summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDidier Raboud <odyx@debian.org>2019-11-20 20:30:03 +0100
committerDidier Raboud <odyx@debian.org>2019-11-20 20:30:03 +0100
commitb0aeaea912817dd53fda33331a8f6e562b695a50 (patch)
tree4c3eca617f759c0bc9698cc35c599ef3113fa706
parent68b3a623cde64e8dd53f8b1929a7cc9eabf0dadd (diff)
parent052cee686ea886c16b59dcabb5a04b2e6d390ade (diff)
Update to upstream 0.79+dfsg0
[git-debrebase anchor: new upstream 0.79+dfsg0, merge]
-rw-r--r--EastAsianWidth.txt2382
-rw-r--r--Makefile.in150
-rw-r--r--README.utf-827
-rw-r--r--TODO10
-rw-r--r--Tcl_shipped.html1992
-rw-r--r--UnicodeData.txt10121
-rw-r--r--appveyor.yml12
-rw-r--r--auto.def224
-rw-r--r--autosetup/README.autosetup12
-rwxr-xr-xautosetup/autosetup1081
-rwxr-xr-xautosetup/autosetup-config.guess (renamed from autosetup/config.guess)679
-rwxr-xr-xautosetup/autosetup-config.sub (renamed from autosetup/config.sub)304
-rwxr-xr-xautosetup/autosetup-find-tclsh (renamed from autosetup/find-tclsh)9
-rw-r--r--autosetup/autosetup-test-tclsh (renamed from autosetup/test-tclsh)0
-rw-r--r--autosetup/cc-db.tcl4
-rw-r--r--autosetup/cc-lib.tcl148
-rw-r--r--autosetup/cc-shared.tcl17
-rw-r--r--autosetup/cc.tcl146
-rw-r--r--autosetup/jim-misc.auto33
-rw-r--r--autosetup/local.tcl31
-rw-r--r--autosetup/pkg-config.tcl73
-rw-r--r--autosetup/system.tcl296
-rw-r--r--autosetup/tmake.auto33
-rw-r--r--autosetup/tmake.tcl6
-rw-r--r--bootstrap.tcl10
-rw-r--r--build-jim-ext.in132
-rwxr-xr-xconfigure2
-rw-r--r--examples/certificate.pem38
-rw-r--r--examples/jtclsh.tcl2
-rw-r--r--examples/key.pem56
-rw-r--r--examples/ssl.server2
-rw-r--r--examples/tcp.server2
-rwxr-xr-xexamples/tip.tcl192
-rw-r--r--examples/unix.client9
-rw-r--r--examples/unix.dgram.client18
-rw-r--r--examples/unix.dgram.server35
-rw-r--r--examples/unix.server48
-rw-r--r--initjimsh.tcl33
-rw-r--r--jim-aio.c1062
-rw-r--r--jim-array.c16
-rw-r--r--jim-clock.c139
-rw-r--r--jim-eventloop.c96
-rw-r--r--jim-exec.c947
-rw-r--r--jim-file.c190
-rw-r--r--jim-format.c10
-rw-r--r--jim-history.c31
-rw-r--r--jim-interactive.c105
-rw-r--r--jim-interp.c4
-rw-r--r--jim-json.c426
-rw-r--r--jim-namespace.c2
-rw-r--r--jim-nosignal.c28
-rw-r--r--jim-posix.c96
-rw-r--r--jim-regexp.c36
-rw-r--r--jim-signal.c99
-rw-r--r--jim-signal.h8
-rw-r--r--jim-sqlite3.c2
-rw-r--r--jim-subcmd.c44
-rw-r--r--jim-tclprefix.c17
-rw-r--r--jim-tty.c343
-rw-r--r--jim-tty.h30
-rw-r--r--jim-win32.c6
-rw-r--r--jim-win32compat.h6
-rw-r--r--jim-zlib.c13
-rw-r--r--jim.c2384
-rw-r--r--jim.h31
-rw-r--r--jim_tcl.txt904
-rw-r--r--jimiocompat.c214
-rw-r--r--jimiocompat.h80
-rw-r--r--jimregexp.c47
-rw-r--r--jimsh.c18
-rw-r--r--jimtcl.pc.in13
-rw-r--r--jsmn/LICENSE20
-rw-r--r--jsmn/jsmn.c318
-rw-r--r--jsmn/jsmn.h76
-rw-r--r--jsonencode.tcl100
-rw-r--r--linenoise-win32.c375
-rw-r--r--linenoise.c2003
-rw-r--r--linenoise.h84
-rwxr-xr-xmake-bootstrap-jim13
-rwxr-xr-xmake-index4
-rw-r--r--oo.tcl2
-rw-r--r--parse-unidata.tcl96
-rw-r--r--regtest.tcl98
-rwxr-xr-xsqlite3/build-ext2
-rw-r--r--sqlite3/jim-sqlite3.c4
-rw-r--r--stdlib.tcl53
-rw-r--r--tclcompat.tcl42
-rw-r--r--tcltest.tcl41
-rw-r--r--tests/Makefile11
-rw-r--r--tests/Makefile.in13
-rw-r--r--tests/alias.test4
-rw-r--r--tests/array.test46
-rw-r--r--tests/binary.test3
-rw-r--r--tests/clock.test54
-rw-r--r--tests/defer.test237
-rw-r--r--tests/dict2.test3
-rw-r--r--tests/event.test15
-rw-r--r--tests/exec.test34
-rw-r--r--tests/exec2.test56
-rw-r--r--tests/expr-base.test8
-rw-r--r--tests/expr-new.test25
-rw-r--r--tests/expr.test8
-rw-r--r--tests/exprsugar.test5
-rw-r--r--tests/file.test156
-rw-r--r--tests/filejoin.test84
-rw-r--r--tests/format.test4
-rw-r--r--tests/glob2.test28
-rw-r--r--tests/json.test173
-rw-r--r--tests/lock.test13
-rw-r--r--tests/lreplace.test86
-rw-r--r--tests/lsort.test33
-rw-r--r--tests/misc.test15
-rw-r--r--tests/pid.test6
-rw-r--r--tests/prefix.test8
-rw-r--r--tests/regcount.test1
-rw-r--r--tests/regexp.test8
-rw-r--r--tests/regexp2.test9
-rw-r--r--tests/runall.tcl38
-rw-r--r--tests/subst.test7
-rw-r--r--tests/timer.test11
-rw-r--r--tests/tree.test15
-rw-r--r--tests/utftcl.test5
-rw-r--r--tests/zlib.test21
-rw-r--r--tree.tcl24
-rw-r--r--utf8.c95
-rw-r--r--utf8.h24
126 files changed, 24623 insertions, 5910 deletions
diff --git a/EastAsianWidth.txt b/EastAsianWidth.txt
new file mode 100644
index 0000000..0d3129b
--- /dev/null
+++ b/EastAsianWidth.txt
@@ -0,0 +1,2382 @@
+# EastAsianWidth-10.0.0.txt
+# Date: 2017-03-08, 02:00:00 GMT [KW, LI]
+# © 2017 Unicode®, Inc.
+# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
+# For terms of use, see http://www.unicode.org/terms_of_use.html
+#
+# Unicode Character Database
+# For documentation, see http://www.unicode.org/reports/tr44/
+#
+# East_Asian_Width Property
+#
+# This file is an informative contributory data file in the
+# Unicode Character Database.
+#
+# The format is two fields separated by a semicolon.
+# Field 0: Unicode code point value or range of code point values
+# Field 1: East_Asian_Width property, consisting of one of the following values:
+# "A", "F", "H", "N", "Na", "W"
+# - All code points, assigned or unassigned, that are not listed
+# explicitly are given the value "N".
+# - The unassigned code points in the following blocks default to "W":
+# CJK Unified Ideographs Extension A: U+3400..U+4DBF
+# CJK Unified Ideographs: U+4E00..U+9FFF
+# CJK Compatibility Ideographs: U+F900..U+FAFF
+# - All undesignated code points in Planes 2 and 3, whether inside or
+# outside of allocated blocks, default to "W":
+# Plane 2: U+20000..U+2FFFD
+# Plane 3: U+30000..U+3FFFD
+#
+# Character ranges are specified as for other property files in the
+# Unicode Character Database.
+#
+# For legacy reasons, there are no spaces before or after the semicolon
+# which separates the two fields. The comments following the number sign
+# "#" list the General_Category property value or the L& alias of the
+# derived value LC, the Unicode character name or names, and, in lines
+# with ranges of code points, the code point count in square brackets.
+#
+# For more information, see UAX #11: East Asian Width,
+# at http://www.unicode.org/reports/tr11/
+#
+# @missing: 0000..10FFFF; N
+0000..001F;N # Cc [32] <control-0000>..<control-001F>
+0020;Na # Zs SPACE
+0021..0023;Na # Po [3] EXCLAMATION MARK..NUMBER SIGN
+0024;Na # Sc DOLLAR SIGN
+0025..0027;Na # Po [3] PERCENT SIGN..APOSTROPHE
+0028;Na # Ps LEFT PARENTHESIS
+0029;Na # Pe RIGHT PARENTHESIS
+002A;Na # Po ASTERISK
+002B;Na # Sm PLUS SIGN
+002C;Na # Po COMMA
+002D;Na # Pd HYPHEN-MINUS
+002E..002F;Na # Po [2] FULL STOP..SOLIDUS
+0030..0039;Na # Nd [10] DIGIT ZERO..DIGIT NINE
+003A..003B;Na # Po [2] COLON..SEMICOLON
+003C..003E;Na # Sm [3] LESS-THAN SIGN..GREATER-THAN SIGN
+003F..0040;Na # Po [2] QUESTION MARK..COMMERCIAL AT
+0041..005A;Na # Lu [26] LATIN CAPITAL LETTER A..LATIN CAPITAL LETTER Z
+005B;Na # Ps LEFT SQUARE BRACKET
+005C;Na # Po REVERSE SOLIDUS
+005D;Na # Pe RIGHT SQUARE BRACKET
+005E;Na # Sk CIRCUMFLEX ACCENT
+005F;Na # Pc LOW LINE
+0060;Na # Sk GRAVE ACCENT
+0061..007A;Na # Ll [26] LATIN SMALL LETTER A..LATIN SMALL LETTER Z
+007B;Na # Ps LEFT CURLY BRACKET
+007C;Na # Sm VERTICAL LINE
+007D;Na # Pe RIGHT CURLY BRACKET
+007E;Na # Sm TILDE
+007F;N # Cc <control-007F>
+0080..009F;N # Cc [32] <control-0080>..<control-009F>
+00A0;N # Zs NO-BREAK SPACE
+00A1;A # Po INVERTED EXCLAMATION MARK
+00A2..00A3;Na # Sc [2] CENT SIGN..POUND SIGN
+00A4;A # Sc CURRENCY SIGN
+00A5;Na # Sc YEN SIGN
+00A6;Na # So BROKEN BAR
+00A7;A # Po SECTION SIGN
+00A8;A # Sk DIAERESIS
+00A9;N # So COPYRIGHT SIGN
+00AA;A # Lo FEMININE ORDINAL INDICATOR
+00AB;N # Pi LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+00AC;Na # Sm NOT SIGN
+00AD;A # Cf SOFT HYPHEN
+00AE;A # So REGISTERED SIGN
+00AF;Na # Sk MACRON
+00B0;A # So DEGREE SIGN
+00B1;A # Sm PLUS-MINUS SIGN
+00B2..00B3;A # No [2] SUPERSCRIPT TWO..SUPERSCRIPT THREE
+00B4;A # Sk ACUTE ACCENT
+00B5;N # Ll MICRO SIGN
+00B6..00B7;A # Po [2] PILCROW SIGN..MIDDLE DOT
+00B8;A # Sk CEDILLA
+00B9;A # No SUPERSCRIPT ONE
+00BA;A # Lo MASCULINE ORDINAL INDICATOR
+00BB;N # Pf RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+00BC..00BE;A # No [3] VULGAR FRACTION ONE QUARTER..VULGAR FRACTION THREE QUARTERS
+00BF;A # Po INVERTED QUESTION MARK
+00C0..00C5;N # Lu [6] LATIN CAPITAL LETTER A WITH GRAVE..LATIN CAPITAL LETTER A WITH RING ABOVE
+00C6;A # Lu LATIN CAPITAL LETTER AE
+00C7..00CF;N # Lu [9] LATIN CAPITAL LETTER C WITH CEDILLA..LATIN CAPITAL LETTER I WITH DIAERESIS
+00D0;A # Lu LATIN CAPITAL LETTER ETH
+00D1..00D6;N # Lu [6] LATIN CAPITAL LETTER N WITH TILDE..LATIN CAPITAL LETTER O WITH DIAERESIS
+00D7;A # Sm MULTIPLICATION SIGN
+00D8;A # Lu LATIN CAPITAL LETTER O WITH STROKE
+00D9..00DD;N # Lu [5] LATIN CAPITAL LETTER U WITH GRAVE..LATIN CAPITAL LETTER Y WITH ACUTE
+00DE..00E1;A # L& [4] LATIN CAPITAL LETTER THORN..LATIN SMALL LETTER A WITH ACUTE
+00E2..00E5;N # Ll [4] LATIN SMALL LETTER A WITH CIRCUMFLEX..LATIN SMALL LETTER A WITH RING ABOVE
+00E6;A # Ll LATIN SMALL LETTER AE
+00E7;N # Ll LATIN SMALL LETTER C WITH CEDILLA
+00E8..00EA;A # Ll [3] LATIN SMALL LETTER E WITH GRAVE..LATIN SMALL LETTER E WITH CIRCUMFLEX
+00EB;N # Ll LATIN SMALL LETTER E WITH DIAERESIS
+00EC..00ED;A # Ll [2] LATIN SMALL LETTER I WITH GRAVE..LATIN SMALL LETTER I WITH ACUTE
+00EE..00EF;N # Ll [2] LATIN SMALL LETTER I WITH CIRCUMFLEX..LATIN SMALL LETTER I WITH DIAERESIS
+00F0;A # Ll LATIN SMALL LETTER ETH
+00F1;N # Ll LATIN SMALL LETTER N WITH TILDE
+00F2..00F3;A # Ll [2] LATIN SMALL LETTER O WITH GRAVE..LATIN SMALL LETTER O WITH ACUTE
+00F4..00F6;N # Ll [3] LATIN SMALL LETTER O WITH CIRCUMFLEX..LATIN SMALL LETTER O WITH DIAERESIS
+00F7;A # Sm DIVISION SIGN
+00F8..00FA;A # Ll [3] LATIN SMALL LETTER O WITH STROKE..LATIN SMALL LETTER U WITH ACUTE
+00FB;N # Ll LATIN SMALL LETTER U WITH CIRCUMFLEX
+00FC;A # Ll LATIN SMALL LETTER U WITH DIAERESIS
+00FD;N # Ll LATIN SMALL LETTER Y WITH ACUTE
+00FE;A # Ll LATIN SMALL LETTER THORN
+00FF;N # L& LATIN SMALL LETTER Y WITH DIAERESIS
+0100;N # Lu LATIN CAPITAL LETTER A WITH MACRON
+0101;A # Ll LATIN SMALL LETTER A WITH MACRON
+0102..0110;N # L& [15] LATIN CAPITAL LETTER A WITH BREVE..LATIN CAPITAL LETTER D WITH STROKE
+0111;A # Ll LATIN SMALL LETTER D WITH STROKE
+0112;N # Lu LATIN CAPITAL LETTER E WITH MACRON
+0113;A # Ll LATIN SMALL LETTER E WITH MACRON
+0114..011A;N # L& [7] LATIN CAPITAL LETTER E WITH BREVE..LATIN CAPITAL LETTER E WITH CARON
+011B;A # Ll LATIN SMALL LETTER E WITH CARON
+011C..0125;N # L& [10] LATIN CAPITAL LETTER G WITH CIRCUMFLEX..LATIN SMALL LETTER H WITH CIRCUMFLEX
+0126..0127;A # L& [2] LATIN CAPITAL LETTER H WITH STROKE..LATIN SMALL LETTER H WITH STROKE
+0128..012A;N # L& [3] LATIN CAPITAL LETTER I WITH TILDE..LATIN CAPITAL LETTER I WITH MACRON
+012B;A # Ll LATIN SMALL LETTER I WITH MACRON
+012C..0130;N # L& [5] LATIN CAPITAL LETTER I WITH BREVE..LATIN CAPITAL LETTER I WITH DOT ABOVE
+0131..0133;A # L& [3] LATIN SMALL LETTER DOTLESS I..LATIN SMALL LIGATURE IJ
+0134..0137;N # L& [4] LATIN CAPITAL LETTER J WITH CIRCUMFLEX..LATIN SMALL LETTER K WITH CEDILLA
+0138;A # Ll LATIN SMALL LETTER KRA
+0139..013E;N # L& [6] LATIN CAPITAL LETTER L WITH ACUTE..LATIN SMALL LETTER L WITH CARON
+013F..0142;A # L& [4] LATIN CAPITAL LETTER L WITH MIDDLE DOT..LATIN SMALL LETTER L WITH STROKE
+0143;N # Lu LATIN CAPITAL LETTER N WITH ACUTE
+0144;A # Ll LATIN SMALL LETTER N WITH ACUTE
+0145..0147;N # L& [3] LATIN CAPITAL LETTER N WITH CEDILLA..LATIN CAPITAL LETTER N WITH CARON
+0148..014B;A # L& [4] LATIN SMALL LETTER N WITH CARON..LATIN SMALL LETTER ENG
+014C;N # Lu LATIN CAPITAL LETTER O WITH MACRON
+014D;A # Ll LATIN SMALL LETTER O WITH MACRON
+014E..0151;N # L& [4] LATIN CAPITAL LETTER O WITH BREVE..LATIN SMALL LETTER O WITH DOUBLE ACUTE
+0152..0153;A # L& [2] LATIN CAPITAL LIGATURE OE..LATIN SMALL LIGATURE OE
+0154..0165;N # L& [18] LATIN CAPITAL LETTER R WITH ACUTE..LATIN SMALL LETTER T WITH CARON
+0166..0167;A # L& [2] LATIN CAPITAL LETTER T WITH STROKE..LATIN SMALL LETTER T WITH STROKE
+0168..016A;N # L& [3] LATIN CAPITAL LETTER U WITH TILDE..LATIN CAPITAL LETTER U WITH MACRON
+016B;A # Ll LATIN SMALL LETTER U WITH MACRON
+016C..017F;N # L& [20] LATIN CAPITAL LETTER U WITH BREVE..LATIN SMALL LETTER LONG S
+0180..01BA;N # L& [59] LATIN SMALL LETTER B WITH STROKE..LATIN SMALL LETTER EZH WITH TAIL
+01BB;N # Lo LATIN LETTER TWO WITH STROKE
+01BC..01BF;N # L& [4] LATIN CAPITAL LETTER TONE FIVE..LATIN LETTER WYNN
+01C0..01C3;N # Lo [4] LATIN LETTER DENTAL CLICK..LATIN LETTER RETROFLEX CLICK
+01C4..01CD;N # L& [10] LATIN CAPITAL LETTER DZ WITH CARON..LATIN CAPITAL LETTER A WITH CARON
+01CE;A # Ll LATIN SMALL LETTER A WITH CARON
+01CF;N # Lu LATIN CAPITAL LETTER I WITH CARON
+01D0;A # Ll LATIN SMALL LETTER I WITH CARON
+01D1;N # Lu LATIN CAPITAL LETTER O WITH CARON
+01D2;A # Ll LATIN SMALL LETTER O WITH CARON
+01D3;N # Lu LATIN CAPITAL LETTER U WITH CARON
+01D4;A # Ll LATIN SMALL LETTER U WITH CARON
+01D5;N # Lu LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON
+01D6;A # Ll LATIN SMALL LETTER U WITH DIAERESIS AND MACRON
+01D7;N # Lu LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE
+01D8;A # Ll LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE
+01D9;N # Lu LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON
+01DA;A # Ll LATIN SMALL LETTER U WITH DIAERESIS AND CARON
+01DB;N # Lu LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE
+01DC;A # Ll LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE
+01DD..024F;N # L& [115] LATIN SMALL LETTER TURNED E..LATIN SMALL LETTER Y WITH STROKE
+0250;N # Ll LATIN SMALL LETTER TURNED A
+0251;A # Ll LATIN SMALL LETTER ALPHA
+0252..0260;N # Ll [15] LATIN SMALL LETTER TURNED ALPHA..LATIN SMALL LETTER G WITH HOOK
+0261;A # Ll LATIN SMALL LETTER SCRIPT G
+0262..0293;N # Ll [50] LATIN LETTER SMALL CAPITAL G..LATIN SMALL LETTER EZH WITH CURL
+0294;N # Lo LATIN LETTER GLOTTAL STOP
+0295..02AF;N # Ll [27] LATIN LETTER PHARYNGEAL VOICED FRICATIVE..LATIN SMALL LETTER TURNED H WITH FISHHOOK AND TAIL
+02B0..02C1;N # Lm [18] MODIFIER LETTER SMALL H..MODIFIER LETTER REVERSED GLOTTAL STOP
+02C2..02C3;N # Sk [2] MODIFIER LETTER LEFT ARROWHEAD..MODIFIER LETTER RIGHT ARROWHEAD
+02C4;A # Sk MODIFIER LETTER UP ARROWHEAD
+02C5;N # Sk MODIFIER LETTER DOWN ARROWHEAD
+02C6;N # Lm MODIFIER LETTER CIRCUMFLEX ACCENT
+02C7;A # Lm CARON
+02C8;N # Lm MODIFIER LETTER VERTICAL LINE
+02C9..02CB;A # Lm [3] MODIFIER LETTER MACRON..MODIFIER LETTER GRAVE ACCENT
+02CC;N # Lm MODIFIER LETTER LOW VERTICAL LINE
+02CD;A # Lm MODIFIER LETTER LOW MACRON
+02CE..02CF;N # Lm [2] MODIFIER LETTER LOW GRAVE ACCENT..MODIFIER LETTER LOW ACUTE ACCENT
+02D0;A # Lm MODIFIER LETTER TRIANGULAR COLON
+02D1;N # Lm MODIFIER LETTER HALF TRIANGULAR COLON
+02D2..02D7;N # Sk [6] MODIFIER LETTER CENTRED RIGHT HALF RING..MODIFIER LETTER MINUS SIGN
+02D8..02DB;A # Sk [4] BREVE..OGONEK
+02DC;N # Sk SMALL TILDE
+02DD;A # Sk DOUBLE ACUTE ACCENT
+02DE;N # Sk MODIFIER LETTER RHOTIC HOOK
+02DF;A # Sk MODIFIER LETTER CROSS ACCENT
+02E0..02E4;N # Lm [5] MODIFIER LETTER SMALL GAMMA..MODIFIER LETTER SMALL REVERSED GLOTTAL STOP
+02E5..02EB;N # Sk [7] MODIFIER LETTER EXTRA-HIGH TONE BAR..MODIFIER LETTER YANG DEPARTING TONE MARK
+02EC;N # Lm MODIFIER LETTER VOICING
+02ED;N # Sk MODIFIER LETTER UNASPIRATED
+02EE;N # Lm MODIFIER LETTER DOUBLE APOSTROPHE
+02EF..02FF;N # Sk [17] MODIFIER LETTER LOW DOWN ARROWHEAD..MODIFIER LETTER LOW LEFT ARROW
+0300..036F;A # Mn [112] COMBINING GRAVE ACCENT..COMBINING LATIN SMALL LETTER X
+0370..0373;N # L& [4] GREEK CAPITAL LETTER HETA..GREEK SMALL LETTER ARCHAIC SAMPI
+0374;N # Lm GREEK NUMERAL SIGN
+0375;N # Sk GREEK LOWER NUMERAL SIGN
+0376..0377;N # L& [2] GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA..GREEK SMALL LETTER PAMPHYLIAN DIGAMMA
+037A;N # Lm GREEK YPOGEGRAMMENI
+037B..037D;N # Ll [3] GREEK SMALL REVERSED LUNATE SIGMA SYMBOL..GREEK SMALL REVERSED DOTTED LUNATE SIGMA SYMBOL
+037E;N # Po GREEK QUESTION MARK
+037F;N # Lu GREEK CAPITAL LETTER YOT
+0384..0385;N # Sk [2] GREEK TONOS..GREEK DIALYTIKA TONOS
+0386;N # Lu GREEK CAPITAL LETTER ALPHA WITH TONOS
+0387;N # Po GREEK ANO TELEIA
+0388..038A;N # Lu [3] GREEK CAPITAL LETTER EPSILON WITH TONOS..GREEK CAPITAL LETTER IOTA WITH TONOS
+038C;N # Lu GREEK CAPITAL LETTER OMICRON WITH TONOS
+038E..0390;N # L& [3] GREEK CAPITAL LETTER UPSILON WITH TONOS..GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
+0391..03A1;A # Lu [17] GREEK CAPITAL LETTER ALPHA..GREEK CAPITAL LETTER RHO
+03A3..03A9;A # Lu [7] GREEK CAPITAL LETTER SIGMA..GREEK CAPITAL LETTER OMEGA
+03AA..03B0;N # L& [7] GREEK CAPITAL LETTER IOTA WITH DIALYTIKA..GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
+03B1..03C1;A # Ll [17] GREEK SMALL LETTER ALPHA..GREEK SMALL LETTER RHO
+03C2;N # Ll GREEK SMALL LETTER FINAL SIGMA
+03C3..03C9;A # Ll [7] GREEK SMALL LETTER SIGMA..GREEK SMALL LETTER OMEGA
+03CA..03F5;N # L& [44] GREEK SMALL LETTER IOTA WITH DIALYTIKA..GREEK LUNATE EPSILON SYMBOL
+03F6;N # Sm GREEK REVERSED LUNATE EPSILON SYMBOL
+03F7..03FF;N # L& [9] GREEK CAPITAL LETTER SHO..GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL
+0400;N # Lu CYRILLIC CAPITAL LETTER IE WITH GRAVE
+0401;A # Lu CYRILLIC CAPITAL LETTER IO
+0402..040F;N # Lu [14] CYRILLIC CAPITAL LETTER DJE..CYRILLIC CAPITAL LETTER DZHE
+0410..044F;A # L& [64] CYRILLIC CAPITAL LETTER A..CYRILLIC SMALL LETTER YA
+0450;N # Ll CYRILLIC SMALL LETTER IE WITH GRAVE
+0451;A # Ll CYRILLIC SMALL LETTER IO
+0452..0481;N # L& [48] CYRILLIC SMALL LETTER DJE..CYRILLIC SMALL LETTER KOPPA
+0482;N # So CYRILLIC THOUSANDS SIGN
+0483..0487;N # Mn [5] COMBINING CYRILLIC TITLO..COMBINING CYRILLIC POKRYTIE
+0488..0489;N # Me [2] COMBINING CYRILLIC HUNDRED THOUSANDS SIGN..COMBINING CYRILLIC MILLIONS SIGN
+048A..04FF;N # L& [118] CYRILLIC CAPITAL LETTER SHORT I WITH TAIL..CYRILLIC SMALL LETTER HA WITH STROKE
+0500..052F;N # L& [48] CYRILLIC CAPITAL LETTER KOMI DE..CYRILLIC SMALL LETTER EL WITH DESCENDER
+0531..0556;N # Lu [38] ARMENIAN CAPITAL LETTER AYB..ARMENIAN CAPITAL LETTER FEH
+0559;N # Lm ARMENIAN MODIFIER LETTER LEFT HALF RING
+055A..055F;N # Po [6] ARMENIAN APOSTROPHE..ARMENIAN ABBREVIATION MARK
+0561..0587;N # Ll [39] ARMENIAN SMALL LETTER AYB..ARMENIAN SMALL LIGATURE ECH YIWN
+0589;N # Po ARMENIAN FULL STOP
+058A;N # Pd ARMENIAN HYPHEN
+058D..058E;N # So [2] RIGHT-FACING ARMENIAN ETERNITY SIGN..LEFT-FACING ARMENIAN ETERNITY SIGN
+058F;N # Sc ARMENIAN DRAM SIGN
+0591..05BD;N # Mn [45] HEBREW ACCENT ETNAHTA..HEBREW POINT METEG
+05BE;N # Pd HEBREW PUNCTUATION MAQAF
+05BF;N # Mn HEBREW POINT RAFE
+05C0;N # Po HEBREW PUNCTUATION PASEQ
+05C1..05C2;N # Mn [2] HEBREW POINT SHIN DOT..HEBREW POINT SIN DOT
+05C3;N # Po HEBREW PUNCTUATION SOF PASUQ
+05C4..05C5;N # Mn [2] HEBREW MARK UPPER DOT..HEBREW MARK LOWER DOT
+05C6;N # Po HEBREW PUNCTUATION NUN HAFUKHA
+05C7;N # Mn HEBREW POINT QAMATS QATAN
+05D0..05EA;N # Lo [27] HEBREW LETTER ALEF..HEBREW LETTER TAV
+05F0..05F2;N # Lo [3] HEBREW LIGATURE YIDDISH DOUBLE VAV..HEBREW LIGATURE YIDDISH DOUBLE YOD
+05F3..05F4;N # Po [2] HEBREW PUNCTUATION GERESH..HEBREW PUNCTUATION GERSHAYIM
+0600..0605;N # Cf [6] ARABIC NUMBER SIGN..ARABIC NUMBER MARK ABOVE
+0606..0608;N # Sm [3] ARABIC-INDIC CUBE ROOT..ARABIC RAY
+0609..060A;N # Po [2] ARABIC-INDIC PER MILLE SIGN..ARABIC-INDIC PER TEN THOUSAND SIGN
+060B;N # Sc AFGHANI SIGN
+060C..060D;N # Po [2] ARABIC COMMA..ARABIC DATE SEPARATOR
+060E..060F;N # So [2] ARABIC POETIC VERSE SIGN..ARABIC SIGN MISRA
+0610..061A;N # Mn [11] ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM..ARABIC SMALL KASRA
+061B;N # Po ARABIC SEMICOLON
+061C;N # Cf ARABIC LETTER MARK
+061E..061F;N # Po [2] ARABIC TRIPLE DOT PUNCTUATION MARK..ARABIC QUESTION MARK
+0620..063F;N # Lo [32] ARABIC LETTER KASHMIRI YEH..ARABIC LETTER FARSI YEH WITH THREE DOTS ABOVE
+0640;N # Lm ARABIC TATWEEL
+0641..064A;N # Lo [10] ARABIC LETTER FEH..ARABIC LETTER YEH
+064B..065F;N # Mn [21] ARABIC FATHATAN..ARABIC WAVY HAMZA BELOW
+0660..0669;N # Nd [10] ARABIC-INDIC DIGIT ZERO..ARABIC-INDIC DIGIT NINE
+066A..066D;N # Po [4] ARABIC PERCENT SIGN..ARABIC FIVE POINTED STAR
+066E..066F;N # Lo [2] ARABIC LETTER DOTLESS BEH..ARABIC LETTER DOTLESS QAF
+0670;N # Mn ARABIC LETTER SUPERSCRIPT ALEF
+0671..06D3;N # Lo [99] ARABIC LETTER ALEF WASLA..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE
+06D4;N # Po ARABIC FULL STOP
+06D5;N # Lo ARABIC LETTER AE
+06D6..06DC;N # Mn [7] ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA..ARABIC SMALL HIGH SEEN
+06DD;N # Cf ARABIC END OF AYAH
+06DE;N # So ARABIC START OF RUB EL HIZB
+06DF..06E4;N # Mn [6] ARABIC SMALL HIGH ROUNDED ZERO..ARABIC SMALL HIGH MADDA
+06E5..06E6;N # Lm [2] ARABIC SMALL WAW..ARABIC SMALL YEH
+06E7..06E8;N # Mn [2] ARABIC SMALL HIGH YEH..ARABIC SMALL HIGH NOON
+06E9;N # So ARABIC PLACE OF SAJDAH
+06EA..06ED;N # Mn [4] ARABIC EMPTY CENTRE LOW STOP..ARABIC SMALL LOW MEEM
+06EE..06EF;N # Lo [2] ARABIC LETTER DAL WITH INVERTED V..ARABIC LETTER REH WITH INVERTED V
+06F0..06F9;N # Nd [10] EXTENDED ARABIC-INDIC DIGIT ZERO..EXTENDED ARABIC-INDIC DIGIT NINE
+06FA..06FC;N # Lo [3] ARABIC LETTER SHEEN WITH DOT BELOW..ARABIC LETTER GHAIN WITH DOT BELOW
+06FD..06FE;N # So [2] ARABIC SIGN SINDHI AMPERSAND..ARABIC SIGN SINDHI POSTPOSITION MEN
+06FF;N # Lo ARABIC LETTER HEH WITH INVERTED V
+0700..070D;N # Po [14] SYRIAC END OF PARAGRAPH..SYRIAC HARKLEAN ASTERISCUS
+070F;N # Cf SYRIAC ABBREVIATION MARK
+0710;N # Lo SYRIAC LETTER ALAPH
+0711;N # Mn SYRIAC LETTER SUPERSCRIPT ALAPH
+0712..072F;N # Lo [30] SYRIAC LETTER BETH..SYRIAC LETTER PERSIAN DHALATH
+0730..074A;N # Mn [27] SYRIAC PTHAHA ABOVE..SYRIAC BARREKH
+074D..074F;N # Lo [3] SYRIAC LETTER SOGDIAN ZHAIN..SYRIAC LETTER SOGDIAN FE
+0750..077F;N # Lo [48] ARABIC LETTER BEH WITH THREE DOTS HORIZONTALLY BELOW..ARABIC LETTER KAF WITH TWO DOTS ABOVE
+0780..07A5;N # Lo [38] THAANA LETTER HAA..THAANA LETTER WAAVU
+07A6..07B0;N # Mn [11] THAANA ABAFILI..THAANA SUKUN
+07B1;N # Lo THAANA LETTER NAA
+07C0..07C9;N # Nd [10] NKO DIGIT ZERO..NKO DIGIT NINE
+07CA..07EA;N # Lo [33] NKO LETTER A..NKO LETTER JONA RA
+07EB..07F3;N # Mn [9] NKO COMBINING SHORT HIGH TONE..NKO COMBINING DOUBLE DOT ABOVE
+07F4..07F5;N # Lm [2] NKO HIGH TONE APOSTROPHE..NKO LOW TONE APOSTROPHE
+07F6;N # So NKO SYMBOL OO DENNEN
+07F7..07F9;N # Po [3] NKO SYMBOL GBAKURUNEN..NKO EXCLAMATION MARK
+07FA;N # Lm NKO LAJANYALAN
+0800..0815;N # Lo [22] SAMARITAN LETTER ALAF..SAMARITAN LETTER TAAF
+0816..0819;N # Mn [4] SAMARITAN MARK IN..SAMARITAN MARK DAGESH
+081A;N # Lm SAMARITAN MODIFIER LETTER EPENTHETIC YUT
+081B..0823;N # Mn [9] SAMARITAN MARK EPENTHETIC YUT..SAMARITAN VOWEL SIGN A
+0824;N # Lm SAMARITAN MODIFIER LETTER SHORT A
+0825..0827;N # Mn [3] SAMARITAN VOWEL SIGN SHORT A..SAMARITAN VOWEL SIGN U
+0828;N # Lm SAMARITAN MODIFIER LETTER I
+0829..082D;N # Mn [5] SAMARITAN VOWEL SIGN LONG I..SAMARITAN MARK NEQUDAA
+0830..083E;N # Po [15] SAMARITAN PUNCTUATION NEQUDAA..SAMARITAN PUNCTUATION ANNAAU
+0840..0858;N # Lo [25] MANDAIC LETTER HALQA..MANDAIC LETTER AIN
+0859..085B;N # Mn [3] MANDAIC AFFRICATION MARK..MANDAIC GEMINATION MARK
+085E;N # Po MANDAIC PUNCTUATION
+0860..086A;N # Lo [11] SYRIAC LETTER MALAYALAM NGA..SYRIAC LETTER MALAYALAM SSA
+08A0..08B4;N # Lo [21] ARABIC LETTER BEH WITH SMALL V BELOW..ARABIC LETTER KAF WITH DOT BELOW
+08B6..08BD;N # Lo [8] ARABIC LETTER BEH WITH SMALL MEEM ABOVE..ARABIC LETTER AFRICAN NOON
+08D4..08E1;N # Mn [14] ARABIC SMALL HIGH WORD AR-RUB..ARABIC SMALL HIGH SIGN SAFHA
+08E2;N # Cf ARABIC DISPUTED END OF AYAH
+08E3..08FF;N # Mn [29] ARABIC TURNED DAMMA BELOW..ARABIC MARK SIDEWAYS NOON GHUNNA
+0900..0902;N # Mn [3] DEVANAGARI SIGN INVERTED CANDRABINDU..DEVANAGARI SIGN ANUSVARA
+0903;N # Mc DEVANAGARI SIGN VISARGA
+0904..0939;N # Lo [54] DEVANAGARI LETTER SHORT A..DEVANAGARI LETTER HA
+093A;N # Mn DEVANAGARI VOWEL SIGN OE
+093B;N # Mc DEVANAGARI VOWEL SIGN OOE
+093C;N # Mn DEVANAGARI SIGN NUKTA
+093D;N # Lo DEVANAGARI SIGN AVAGRAHA
+093E..0940;N # Mc [3] DEVANAGARI VOWEL SIGN AA..DEVANAGARI VOWEL SIGN II
+0941..0948;N # Mn [8] DEVANAGARI VOWEL SIGN U..DEVANAGARI VOWEL SIGN AI
+0949..094C;N # Mc [4] DEVANAGARI VOWEL SIGN CANDRA O..DEVANAGARI VOWEL SIGN AU
+094D;N # Mn DEVANAGARI SIGN VIRAMA
+094E..094F;N # Mc [2] DEVANAGARI VOWEL SIGN PRISHTHAMATRA E..DEVANAGARI VOWEL SIGN AW
+0950;N # Lo DEVANAGARI OM
+0951..0957;N # Mn [7] DEVANAGARI STRESS SIGN UDATTA..DEVANAGARI VOWEL SIGN UUE
+0958..0961;N # Lo [10] DEVANAGARI LETTER QA..DEVANAGARI LETTER VOCALIC LL
+0962..0963;N # Mn [2] DEVANAGARI VOWEL SIGN VOCALIC L..DEVANAGARI VOWEL SIGN VOCALIC LL
+0964..0965;N # Po [2] DEVANAGARI DANDA..DEVANAGARI DOUBLE DANDA
+0966..096F;N # Nd [10] DEVANAGARI DIGIT ZERO..DEVANAGARI DIGIT NINE
+0970;N # Po DEVANAGARI ABBREVIATION SIGN
+0971;N # Lm DEVANAGARI SIGN HIGH SPACING DOT
+0972..097F;N # Lo [14] DEVANAGARI LETTER CANDRA A..DEVANAGARI LETTER BBA
+0980;N # Lo BENGALI ANJI
+0981;N # Mn BENGALI SIGN CANDRABINDU
+0982..0983;N # Mc [2] BENGALI SIGN ANUSVARA..BENGALI SIGN VISARGA
+0985..098C;N # Lo [8] BENGALI LETTER A..BENGALI LETTER VOCALIC L
+098F..0990;N # Lo [2] BENGALI LETTER E..BENGALI LETTER AI
+0993..09A8;N # Lo [22] BENGALI LETTER O..BENGALI LETTER NA
+09AA..09B0;N # Lo [7] BENGALI LETTER PA..BENGALI LETTER RA
+09B2;N # Lo BENGALI LETTER LA
+09B6..09B9;N # Lo [4] BENGALI LETTER SHA..BENGALI LETTER HA
+09BC;N # Mn BENGALI SIGN NUKTA
+09BD;N # Lo BENGALI SIGN AVAGRAHA
+09BE..09C0;N # Mc [3] BENGALI VOWEL SIGN AA..BENGALI VOWEL SIGN II
+09C1..09C4;N # Mn [4] BENGALI VOWEL SIGN U..BENGALI VOWEL SIGN VOCALIC RR
+09C7..09C8;N # Mc [2] BENGALI VOWEL SIGN E..BENGALI VOWEL SIGN AI
+09CB..09CC;N # Mc [2] BENGALI VOWEL SIGN O..BENGALI VOWEL SIGN AU
+09CD;N # Mn BENGALI SIGN VIRAMA
+09CE;N # Lo BENGALI LETTER KHANDA TA
+09D7;N # Mc BENGALI AU LENGTH MARK
+09DC..09DD;N # Lo [2] BENGALI LETTER RRA..BENGALI LETTER RHA
+09DF..09E1;N # Lo [3] BENGALI LETTER YYA..BENGALI LETTER VOCALIC LL
+09E2..09E3;N # Mn [2] BENGALI VOWEL SIGN VOCALIC L..BENGALI VOWEL SIGN VOCALIC LL
+09E6..09EF;N # Nd [10] BENGALI DIGIT ZERO..BENGALI DIGIT NINE
+09F0..09F1;N # Lo [2] BENGALI LETTER RA WITH MIDDLE DIAGONAL..BENGALI LETTER RA WITH LOWER DIAGONAL
+09F2..09F3;N # Sc [2] BENGALI RUPEE MARK..BENGALI RUPEE SIGN
+09F4..09F9;N # No [6] BENGALI CURRENCY NUMERATOR ONE..BENGALI CURRENCY DENOMINATOR SIXTEEN
+09FA;N # So BENGALI ISSHAR
+09FB;N # Sc BENGALI GANDA MARK
+09FC;N # Lo BENGALI LETTER VEDIC ANUSVARA
+09FD;N # Po BENGALI ABBREVIATION SIGN
+0A01..0A02;N # Mn [2] GURMUKHI SIGN ADAK BINDI..GURMUKHI SIGN BINDI
+0A03;N # Mc GURMUKHI SIGN VISARGA
+0A05..0A0A;N # Lo [6] GURMUKHI LETTER A..GURMUKHI LETTER UU
+0A0F..0A10;N # Lo [2] GURMUKHI LETTER EE..GURMUKHI LETTER AI
+0A13..0A28;N # Lo [22] GURMUKHI LETTER OO..GURMUKHI LETTER NA
+0A2A..0A30;N # Lo [7] GURMUKHI LETTER PA..GURMUKHI LETTER RA
+0A32..0A33;N # Lo [2] GURMUKHI LETTER LA..GURMUKHI LETTER LLA
+0A35..0A36;N # Lo [2] GURMUKHI LETTER VA..GURMUKHI LETTER SHA
+0A38..0A39;N # Lo [2] GURMUKHI LETTER SA..GURMUKHI LETTER HA
+0A3C;N # Mn GURMUKHI SIGN NUKTA
+0A3E..0A40;N # Mc [3] GURMUKHI VOWEL SIGN AA..GURMUKHI VOWEL SIGN II
+0A41..0A42;N # Mn [2] GURMUKHI VOWEL SIGN U..GURMUKHI VOWEL SIGN UU
+0A47..0A48;N # Mn [2] GURMUKHI VOWEL SIGN EE..GURMUKHI VOWEL SIGN AI
+0A4B..0A4D;N # Mn [3] GURMUKHI VOWEL SIGN OO..GURMUKHI SIGN VIRAMA
+0A51;N # Mn GURMUKHI SIGN UDAAT
+0A59..0A5C;N # Lo [4] GURMUKHI LETTER KHHA..GURMUKHI LETTER RRA
+0A5E;N # Lo GURMUKHI LETTER FA
+0A66..0A6F;N # Nd [10] GURMUKHI DIGIT ZERO..GURMUKHI DIGIT NINE
+0A70..0A71;N # Mn [2] GURMUKHI TIPPI..GURMUKHI ADDAK
+0A72..0A74;N # Lo [3] GURMUKHI IRI..GURMUKHI EK ONKAR
+0A75;N # Mn GURMUKHI SIGN YAKASH
+0A81..0A82;N # Mn [2] GUJARATI SIGN CANDRABINDU..GUJARATI SIGN ANUSVARA
+0A83;N # Mc GUJARATI SIGN VISARGA
+0A85..0A8D;N # Lo [9] GUJARATI LETTER A..GUJARATI VOWEL CANDRA E
+0A8F..0A91;N # Lo [3] GUJARATI LETTER E..GUJARATI VOWEL CANDRA O
+0A93..0AA8;N # Lo [22] GUJARATI LETTER O..GUJARATI LETTER NA
+0AAA..0AB0;N # Lo [7] GUJARATI LETTER PA..GUJARATI LETTER RA
+0AB2..0AB3;N # Lo [2] GUJARATI LETTER LA..GUJARATI LETTER LLA
+0AB5..0AB9;N # Lo [5] GUJARATI LETTER VA..GUJARATI LETTER HA
+0ABC;N # Mn GUJARATI SIGN NUKTA
+0ABD;N # Lo GUJARATI SIGN AVAGRAHA
+0ABE..0AC0;N # Mc [3] GUJARATI VOWEL SIGN AA..GUJARATI VOWEL SIGN II
+0AC1..0AC5;N # Mn [5] GUJARATI VOWEL SIGN U..GUJARATI VOWEL SIGN CANDRA E
+0AC7..0AC8;N # Mn [2] GUJARATI VOWEL SIGN E..GUJARATI VOWEL SIGN AI
+0AC9;N # Mc GUJARATI VOWEL SIGN CANDRA O
+0ACB..0ACC;N # Mc [2] GUJARATI VOWEL SIGN O..GUJARATI VOWEL SIGN AU
+0ACD;N # Mn GUJARATI SIGN VIRAMA
+0AD0;N # Lo GUJARATI OM
+0AE0..0AE1;N # Lo [2] GUJARATI LETTER VOCALIC RR..GUJARATI LETTER VOCALIC LL
+0AE2..0AE3;N # Mn [2] GUJARATI VOWEL SIGN VOCALIC L..GUJARATI VOWEL SIGN VOCALIC LL
+0AE6..0AEF;N # Nd [10] GUJARATI DIGIT ZERO..GUJARATI DIGIT NINE
+0AF0;N # Po GUJARATI ABBREVIATION SIGN
+0AF1;N # Sc GUJARATI RUPEE SIGN
+0AF9;N # Lo GUJARATI LETTER ZHA
+0AFA..0AFF;N # Mn [6] GUJARATI SIGN SUKUN..GUJARATI SIGN TWO-CIRCLE NUKTA ABOVE
+0B01;N # Mn ORIYA SIGN CANDRABINDU
+0B02..0B03;N # Mc [2] ORIYA SIGN ANUSVARA..ORIYA SIGN VISARGA
+0B05..0B0C;N # Lo [8] ORIYA LETTER A..ORIYA LETTER VOCALIC L
+0B0F..0B10;N # Lo [2] ORIYA LETTER E..ORIYA LETTER AI
+0B13..0B28;N # Lo [22] ORIYA LETTER O..ORIYA LETTER NA
+0B2A..0B30;N # Lo [7] ORIYA LETTER PA..ORIYA LETTER RA
+0B32..0B33;N # Lo [2] ORIYA LETTER LA..ORIYA LETTER LLA
+0B35..0B39;N # Lo [5] ORIYA LETTER VA..ORIYA LETTER HA
+0B3C;N # Mn ORIYA SIGN NUKTA
+0B3D;N # Lo ORIYA SIGN AVAGRAHA
+0B3E;N # Mc ORIYA VOWEL SIGN AA
+0B3F;N # Mn ORIYA VOWEL SIGN I
+0B40;N # Mc ORIYA VOWEL SIGN II
+0B41..0B44;N # Mn [4] ORIYA VOWEL SIGN U..ORIYA VOWEL SIGN VOCALIC RR
+0B47..0B48;N # Mc [2] ORIYA VOWEL SIGN E..ORIYA VOWEL SIGN AI
+0B4B..0B4C;N # Mc [2] ORIYA VOWEL SIGN O..ORIYA VOWEL SIGN AU
+0B4D;N # Mn ORIYA SIGN VIRAMA
+0B56;N # Mn ORIYA AI LENGTH MARK
+0B57;N # Mc ORIYA AU LENGTH MARK
+0B5C..0B5D;N # Lo [2] ORIYA LETTER RRA..ORIYA LETTER RHA
+0B5F..0B61;N # Lo [3] ORIYA LETTER YYA..ORIYA LETTER VOCALIC LL
+0B62..0B63;N # Mn [2] ORIYA VOWEL SIGN VOCALIC L..ORIYA VOWEL SIGN VOCALIC LL
+0B66..0B6F;N # Nd [10] ORIYA DIGIT ZERO..ORIYA DIGIT NINE
+0B70;N # So ORIYA ISSHAR
+0B71;N # Lo ORIYA LETTER WA
+0B72..0B77;N # No [6] ORIYA FRACTION ONE QUARTER..ORIYA FRACTION THREE SIXTEENTHS
+0B82;N # Mn TAMIL SIGN ANUSVARA
+0B83;N # Lo TAMIL SIGN VISARGA
+0B85..0B8A;N # Lo [6] TAMIL LETTER A..TAMIL LETTER UU
+0B8E..0B90;N # Lo [3] TAMIL LETTER E..TAMIL LETTER AI
+0B92..0B95;N # Lo [4] TAMIL LETTER O..TAMIL LETTER KA
+0B99..0B9A;N # Lo [2] TAMIL LETTER NGA..TAMIL LETTER CA
+0B9C;N # Lo TAMIL LETTER JA
+0B9E..0B9F;N # Lo [2] TAMIL LETTER NYA..TAMIL LETTER TTA
+0BA3..0BA4;N # Lo [2] TAMIL LETTER NNA..TAMIL LETTER TA
+0BA8..0BAA;N # Lo [3] TAMIL LETTER NA..TAMIL LETTER PA
+0BAE..0BB9;N # Lo [12] TAMIL LETTER MA..TAMIL LETTER HA
+0BBE..0BBF;N # Mc [2] TAMIL VOWEL SIGN AA..TAMIL VOWEL SIGN I
+0BC0;N # Mn TAMIL VOWEL SIGN II
+0BC1..0BC2;N # Mc [2] TAMIL VOWEL SIGN U..TAMIL VOWEL SIGN UU
+0BC6..0BC8;N # Mc [3] TAMIL VOWEL SIGN E..TAMIL VOWEL SIGN AI
+0BCA..0BCC;N # Mc [3] TAMIL VOWEL SIGN O..TAMIL VOWEL SIGN AU
+0BCD;N # Mn TAMIL SIGN VIRAMA
+0BD0;N # Lo TAMIL OM
+0BD7;N # Mc TAMIL AU LENGTH MARK
+0BE6..0BEF;N # Nd [10] TAMIL DIGIT ZERO..TAMIL DIGIT NINE
+0BF0..0BF2;N # No [3] TAMIL NUMBER TEN..TAMIL NUMBER ONE THOUSAND
+0BF3..0BF8;N # So [6] TAMIL DAY SIGN..TAMIL AS ABOVE SIGN
+0BF9;N # Sc TAMIL RUPEE SIGN
+0BFA;N # So TAMIL NUMBER SIGN
+0C00;N # Mn TELUGU SIGN COMBINING CANDRABINDU ABOVE
+0C01..0C03;N # Mc [3] TELUGU SIGN CANDRABINDU..TELUGU SIGN VISARGA
+0C05..0C0C;N # Lo [8] TELUGU LETTER A..TELUGU LETTER VOCALIC L
+0C0E..0C10;N # Lo [3] TELUGU LETTER E..TELUGU LETTER AI
+0C12..0C28;N # Lo [23] TELUGU LETTER O..TELUGU LETTER NA
+0C2A..0C39;N # Lo [16] TELUGU LETTER PA..TELUGU LETTER HA
+0C3D;N # Lo TELUGU SIGN AVAGRAHA
+0C3E..0C40;N # Mn [3] TELUGU VOWEL SIGN AA..TELUGU VOWEL SIGN II
+0C41..0C44;N # Mc [4] TELUGU VOWEL SIGN U..TELUGU VOWEL SIGN VOCALIC RR
+0C46..0C48;N # Mn [3] TELUGU VOWEL SIGN E..TELUGU VOWEL SIGN AI
+0C4A..0C4D;N # Mn [4] TELUGU VOWEL SIGN O..TELUGU SIGN VIRAMA
+0C55..0C56;N # Mn [2] TELUGU LENGTH MARK..TELUGU AI LENGTH MARK
+0C58..0C5A;N # Lo [3] TELUGU LETTER TSA..TELUGU LETTER RRRA
+0C60..0C61;N # Lo [2] TELUGU LETTER VOCALIC RR..TELUGU LETTER VOCALIC LL
+0C62..0C63;N # Mn [2] TELUGU VOWEL SIGN VOCALIC L..TELUGU VOWEL SIGN VOCALIC LL
+0C66..0C6F;N # Nd [10] TELUGU DIGIT ZERO..TELUGU DIGIT NINE
+0C78..0C7E;N # No [7] TELUGU FRACTION DIGIT ZERO FOR ODD POWERS OF FOUR..TELUGU FRACTION DIGIT THREE FOR EVEN POWERS OF FOUR
+0C7F;N # So TELUGU SIGN TUUMU
+0C80;N # Lo KANNADA SIGN SPACING CANDRABINDU
+0C81;N # Mn KANNADA SIGN CANDRABINDU
+0C82..0C83;N # Mc [2] KANNADA SIGN ANUSVARA..KANNADA SIGN VISARGA
+0C85..0C8C;N # Lo [8] KANNADA LETTER A..KANNADA LETTER VOCALIC L
+0C8E..0C90;N # Lo [3] KANNADA LETTER E..KANNADA LETTER AI
+0C92..0CA8;N # Lo [23] KANNADA LETTER O..KANNADA LETTER NA
+0CAA..0CB3;N # Lo [10] KANNADA LETTER PA..KANNADA LETTER LLA
+0CB5..0CB9;N # Lo [5] KANNADA LETTER VA..KANNADA LETTER HA
+0CBC;N # Mn KANNADA SIGN NUKTA
+0CBD;N # Lo KANNADA SIGN AVAGRAHA
+0CBE;N # Mc KANNADA VOWEL SIGN AA
+0CBF;N # Mn KANNADA VOWEL SIGN I
+0CC0..0CC4;N # Mc [5] KANNADA VOWEL SIGN II..KANNADA VOWEL SIGN VOCALIC RR
+0CC6;N # Mn KANNADA VOWEL SIGN E
+0CC7..0CC8;N # Mc [2] KANNADA VOWEL SIGN EE..KANNADA VOWEL SIGN AI
+0CCA..0CCB;N # Mc [2] KANNADA VOWEL SIGN O..KANNADA VOWEL SIGN OO
+0CCC..0CCD;N # Mn [2] KANNADA VOWEL SIGN AU..KANNADA SIGN VIRAMA
+0CD5..0CD6;N # Mc [2] KANNADA LENGTH MARK..KANNADA AI LENGTH MARK
+0CDE;N # Lo KANNADA LETTER FA
+0CE0..0CE1;N # Lo [2] KANNADA LETTER VOCALIC RR..KANNADA LETTER VOCALIC LL
+0CE2..0CE3;N # Mn [2] KANNADA VOWEL SIGN VOCALIC L..KANNADA VOWEL SIGN VOCALIC LL
+0CE6..0CEF;N # Nd [10] KANNADA DIGIT ZERO..KANNADA DIGIT NINE
+0CF1..0CF2;N # Lo [2] KANNADA SIGN JIHVAMULIYA..KANNADA SIGN UPADHMANIYA
+0D00..0D01;N # Mn [2] MALAYALAM SIGN COMBINING ANUSVARA ABOVE..MALAYALAM SIGN CANDRABINDU
+0D02..0D03;N # Mc [2] MALAYALAM SIGN ANUSVARA..MALAYALAM SIGN VISARGA
+0D05..0D0C;N # Lo [8] MALAYALAM LETTER A..MALAYALAM LETTER VOCALIC L
+0D0E..0D10;N # Lo [3] MALAYALAM LETTER E..MALAYALAM LETTER AI
+0D12..0D3A;N # Lo [41] MALAYALAM LETTER O..MALAYALAM LETTER TTTA
+0D3B..0D3C;N # Mn [2] MALAYALAM SIGN VERTICAL BAR VIRAMA..MALAYALAM SIGN CIRCULAR VIRAMA
+0D3D;N # Lo MALAYALAM SIGN AVAGRAHA
+0D3E..0D40;N # Mc [3] MALAYALAM VOWEL SIGN AA..MALAYALAM VOWEL SIGN II
+0D41..0D44;N # Mn [4] MALAYALAM VOWEL SIGN U..MALAYALAM VOWEL SIGN VOCALIC RR
+0D46..0D48;N # Mc [3] MALAYALAM VOWEL SIGN E..MALAYALAM VOWEL SIGN AI
+0D4A..0D4C;N # Mc [3] MALAYALAM VOWEL SIGN O..MALAYALAM VOWEL SIGN AU
+0D4D;N # Mn MALAYALAM SIGN VIRAMA
+0D4E;N # Lo MALAYALAM LETTER DOT REPH
+0D4F;N # So MALAYALAM SIGN PARA
+0D54..0D56;N # Lo [3] MALAYALAM LETTER CHILLU M..MALAYALAM LETTER CHILLU LLL
+0D57;N # Mc MALAYALAM AU LENGTH MARK
+0D58..0D5E;N # No [7] MALAYALAM FRACTION ONE ONE-HUNDRED-AND-SIXTIETH..MALAYALAM FRACTION ONE FIFTH
+0D5F..0D61;N # Lo [3] MALAYALAM LETTER ARCHAIC II..MALAYALAM LETTER VOCALIC LL
+0D62..0D63;N # Mn [2] MALAYALAM VOWEL SIGN VOCALIC L..MALAYALAM VOWEL SIGN VOCALIC LL
+0D66..0D6F;N # Nd [10] MALAYALAM DIGIT ZERO..MALAYALAM DIGIT NINE
+0D70..0D78;N # No [9] MALAYALAM NUMBER TEN..MALAYALAM FRACTION THREE SIXTEENTHS
+0D79;N # So MALAYALAM DATE MARK
+0D7A..0D7F;N # Lo [6] MALAYALAM LETTER CHILLU NN..MALAYALAM LETTER CHILLU K
+0D82..0D83;N # Mc [2] SINHALA SIGN ANUSVARAYA..SINHALA SIGN VISARGAYA
+0D85..0D96;N # Lo [18] SINHALA LETTER AYANNA..SINHALA LETTER AUYANNA
+0D9A..0DB1;N # Lo [24] SINHALA LETTER ALPAPRAANA KAYANNA..SINHALA LETTER DANTAJA NAYANNA
+0DB3..0DBB;N # Lo [9] SINHALA LETTER SANYAKA DAYANNA..SINHALA LETTER RAYANNA
+0DBD;N # Lo SINHALA LETTER DANTAJA LAYANNA
+0DC0..0DC6;N # Lo [7] SINHALA LETTER VAYANNA..SINHALA LETTER FAYANNA
+0DCA;N # Mn SINHALA SIGN AL-LAKUNA
+0DCF..0DD1;N # Mc [3] SINHALA VOWEL SIGN AELA-PILLA..SINHALA VOWEL SIGN DIGA AEDA-PILLA
+0DD2..0DD4;N # Mn [3] SINHALA VOWEL SIGN KETTI IS-PILLA..SINHALA VOWEL SIGN KETTI PAA-PILLA
+0DD6;N # Mn SINHALA VOWEL SIGN DIGA PAA-PILLA
+0DD8..0DDF;N # Mc [8] SINHALA VOWEL SIGN GAETTA-PILLA..SINHALA VOWEL SIGN GAYANUKITTA
+0DE6..0DEF;N # Nd [10] SINHALA LITH DIGIT ZERO..SINHALA LITH DIGIT NINE
+0DF2..0DF3;N # Mc [2] SINHALA VOWEL SIGN DIGA GAETTA-PILLA..SINHALA VOWEL SIGN DIGA GAYANUKITTA
+0DF4;N # Po SINHALA PUNCTUATION KUNDDALIYA
+0E01..0E30;N # Lo [48] THAI CHARACTER KO KAI..THAI CHARACTER SARA A
+0E31;N # Mn THAI CHARACTER MAI HAN-AKAT
+0E32..0E33;N # Lo [2] THAI CHARACTER SARA AA..THAI CHARACTER SARA AM
+0E34..0E3A;N # Mn [7] THAI CHARACTER SARA I..THAI CHARACTER PHINTHU
+0E3F;N # Sc THAI CURRENCY SYMBOL BAHT
+0E40..0E45;N # Lo [6] THAI CHARACTER SARA E..THAI CHARACTER LAKKHANGYAO
+0E46;N # Lm THAI CHARACTER MAIYAMOK
+0E47..0E4E;N # Mn [8] THAI CHARACTER MAITAIKHU..THAI CHARACTER YAMAKKAN
+0E4F;N # Po THAI CHARACTER FONGMAN
+0E50..0E59;N # Nd [10] THAI DIGIT ZERO..THAI DIGIT NINE
+0E5A..0E5B;N # Po [2] THAI CHARACTER ANGKHANKHU..THAI CHARACTER KHOMUT
+0E81..0E82;N # Lo [2] LAO LETTER KO..LAO LETTER KHO SUNG
+0E84;N # Lo LAO LETTER KHO TAM
+0E87..0E88;N # Lo [2] LAO LETTER NGO..LAO LETTER CO
+0E8A;N # Lo LAO LETTER SO TAM
+0E8D;N # Lo LAO LETTER NYO
+0E94..0E97;N # Lo [4] LAO LETTER DO..LAO LETTER THO TAM
+0E99..0E9F;N # Lo [7] LAO LETTER NO..LAO LETTER FO SUNG
+0EA1..0EA3;N # Lo [3] LAO LETTER MO..LAO LETTER LO LING
+0EA5;N # Lo LAO LETTER LO LOOT
+0EA7;N # Lo LAO LETTER WO
+0EAA..0EAB;N # Lo [2] LAO LETTER SO SUNG..LAO LETTER HO SUNG
+0EAD..0EB0;N # Lo [4] LAO LETTER O..LAO VOWEL SIGN A
+0EB1;N # Mn LAO VOWEL SIGN MAI KAN
+0EB2..0EB3;N # Lo [2] LAO VOWEL SIGN AA..LAO VOWEL SIGN AM
+0EB4..0EB9;N # Mn [6] LAO VOWEL SIGN I..LAO VOWEL SIGN UU
+0EBB..0EBC;N # Mn [2] LAO VOWEL SIGN MAI KON..LAO SEMIVOWEL SIGN LO
+0EBD;N # Lo LAO SEMIVOWEL SIGN NYO
+0EC0..0EC4;N # Lo [5] LAO VOWEL SIGN E..LAO VOWEL SIGN AI
+0EC6;N # Lm LAO KO LA
+0EC8..0ECD;N # Mn [6] LAO TONE MAI EK..LAO NIGGAHITA
+0ED0..0ED9;N # Nd [10] LAO DIGIT ZERO..LAO DIGIT NINE
+0EDC..0EDF;N # Lo [4] LAO HO NO..LAO LETTER KHMU NYO
+0F00;N # Lo TIBETAN SYLLABLE OM
+0F01..0F03;N # So [3] TIBETAN MARK GTER YIG MGO TRUNCATED A..TIBETAN MARK GTER YIG MGO -UM GTER TSHEG MA
+0F04..0F12;N # Po [15] TIBETAN MARK INITIAL YIG MGO MDUN MA..TIBETAN MARK RGYA GRAM SHAD
+0F13;N # So TIBETAN MARK CARET -DZUD RTAGS ME LONG CAN
+0F14;N # Po TIBETAN MARK GTER TSHEG
+0F15..0F17;N # So [3] TIBETAN LOGOTYPE SIGN CHAD RTAGS..TIBETAN ASTROLOGICAL SIGN SGRA GCAN -CHAR RTAGS
+0F18..0F19;N # Mn [2] TIBETAN ASTROLOGICAL SIGN -KHYUD PA..TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS
+0F1A..0F1F;N # So [6] TIBETAN SIGN RDEL DKAR GCIG..TIBETAN SIGN RDEL DKAR RDEL NAG
+0F20..0F29;N # Nd [10] TIBETAN DIGIT ZERO..TIBETAN DIGIT NINE
+0F2A..0F33;N # No [10] TIBETAN DIGIT HALF ONE..TIBETAN DIGIT HALF ZERO
+0F34;N # So TIBETAN MARK BSDUS RTAGS
+0F35;N # Mn TIBETAN MARK NGAS BZUNG NYI ZLA
+0F36;N # So TIBETAN MARK CARET -DZUD RTAGS BZHI MIG CAN
+0F37;N # Mn TIBETAN MARK NGAS BZUNG SGOR RTAGS
+0F38;N # So TIBETAN MARK CHE MGO
+0F39;N # Mn TIBETAN MARK TSA -PHRU
+0F3A;N # Ps TIBETAN MARK GUG RTAGS GYON
+0F3B;N # Pe TIBETAN MARK GUG RTAGS GYAS
+0F3C;N # Ps TIBETAN MARK ANG KHANG GYON
+0F3D;N # Pe TIBETAN MARK ANG KHANG GYAS
+0F3E..0F3F;N # Mc [2] TIBETAN SIGN YAR TSHES..TIBETAN SIGN MAR TSHES
+0F40..0F47;N # Lo [8] TIBETAN LETTER KA..TIBETAN LETTER JA
+0F49..0F6C;N # Lo [36] TIBETAN LETTER NYA..TIBETAN LETTER RRA
+0F71..0F7E;N # Mn [14] TIBETAN VOWEL SIGN AA..TIBETAN SIGN RJES SU NGA RO
+0F7F;N # Mc TIBETAN SIGN RNAM BCAD
+0F80..0F84;N # Mn [5] TIBETAN VOWEL SIGN REVERSED I..TIBETAN MARK HALANTA
+0F85;N # Po TIBETAN MARK PALUTA
+0F86..0F87;N # Mn [2] TIBETAN SIGN LCI RTAGS..TIBETAN SIGN YANG RTAGS
+0F88..0F8C;N # Lo [5] TIBETAN SIGN LCE TSA CAN..TIBETAN SIGN INVERTED MCHU CAN
+0F8D..0F97;N # Mn [11] TIBETAN SUBJOINED SIGN LCE TSA CAN..TIBETAN SUBJOINED LETTER JA
+0F99..0FBC;N # Mn [36] TIBETAN SUBJOINED LETTER NYA..TIBETAN SUBJOINED LETTER FIXED-FORM RA
+0FBE..0FC5;N # So [8] TIBETAN KU RU KHA..TIBETAN SYMBOL RDO RJE
+0FC6;N # Mn TIBETAN SYMBOL PADMA GDAN
+0FC7..0FCC;N # So [6] TIBETAN SYMBOL RDO RJE RGYA GRAM..TIBETAN SYMBOL NOR BU BZHI -KHYIL
+0FCE..0FCF;N # So [2] TIBETAN SIGN RDEL NAG RDEL DKAR..TIBETAN SIGN RDEL NAG GSUM
+0FD0..0FD4;N # Po [5] TIBETAN MARK BSKA- SHOG GI MGO RGYAN..TIBETAN MARK CLOSING BRDA RNYING YIG MGO SGAB MA
+0FD5..0FD8;N # So [4] RIGHT-FACING SVASTI SIGN..LEFT-FACING SVASTI SIGN WITH DOTS
+0FD9..0FDA;N # Po [2] TIBETAN MARK LEADING MCHAN RTAGS..TIBETAN MARK TRAILING MCHAN RTAGS
+1000..102A;N # Lo [43] MYANMAR LETTER KA..MYANMAR LETTER AU
+102B..102C;N # Mc [2] MYANMAR VOWEL SIGN TALL AA..MYANMAR VOWEL SIGN AA
+102D..1030;N # Mn [4] MYANMAR VOWEL SIGN I..MYANMAR VOWEL SIGN UU
+1031;N # Mc MYANMAR VOWEL SIGN E
+1032..1037;N # Mn [6] MYANMAR VOWEL SIGN AI..MYANMAR SIGN DOT BELOW
+1038;N # Mc MYANMAR SIGN VISARGA
+1039..103A;N # Mn [2] MYANMAR SIGN VIRAMA..MYANMAR SIGN ASAT
+103B..103C;N # Mc [2] MYANMAR CONSONANT SIGN MEDIAL YA..MYANMAR CONSONANT SIGN MEDIAL RA
+103D..103E;N # Mn [2] MYANMAR CONSONANT SIGN MEDIAL WA..MYANMAR CONSONANT SIGN MEDIAL HA
+103F;N # Lo MYANMAR LETTER GREAT SA
+1040..1049;N # Nd [10] MYANMAR DIGIT ZERO..MYANMAR DIGIT NINE
+104A..104F;N # Po [6] MYANMAR SIGN LITTLE SECTION..MYANMAR SYMBOL GENITIVE
+1050..1055;N # Lo [6] MYANMAR LETTER SHA..MYANMAR LETTER VOCALIC LL
+1056..1057;N # Mc [2] MYANMAR VOWEL SIGN VOCALIC R..MYANMAR VOWEL SIGN VOCALIC RR
+1058..1059;N # Mn [2] MYANMAR VOWEL SIGN VOCALIC L..MYANMAR VOWEL SIGN VOCALIC LL
+105A..105D;N # Lo [4] MYANMAR LETTER MON NGA..MYANMAR LETTER MON BBE
+105E..1060;N # Mn [3] MYANMAR CONSONANT SIGN MON MEDIAL NA..MYANMAR CONSONANT SIGN MON MEDIAL LA
+1061;N # Lo MYANMAR LETTER SGAW KAREN SHA
+1062..1064;N # Mc [3] MYANMAR VOWEL SIGN SGAW KAREN EU..MYANMAR TONE MARK SGAW KAREN KE PHO
+1065..1066;N # Lo [2] MYANMAR LETTER WESTERN PWO KAREN THA..MYANMAR LETTER WESTERN PWO KAREN PWA
+1067..106D;N # Mc [7] MYANMAR VOWEL SIGN WESTERN PWO KAREN EU..MYANMAR SIGN WESTERN PWO KAREN TONE-5
+106E..1070;N # Lo [3] MYANMAR LETTER EASTERN PWO KAREN NNA..MYANMAR LETTER EASTERN PWO KAREN GHWA
+1071..1074;N # Mn [4] MYANMAR VOWEL SIGN GEBA KAREN I..MYANMAR VOWEL SIGN KAYAH EE
+1075..1081;N # Lo [13] MYANMAR LETTER SHAN KA..MYANMAR LETTER SHAN HA
+1082;N # Mn MYANMAR CONSONANT SIGN SHAN MEDIAL WA
+1083..1084;N # Mc [2] MYANMAR VOWEL SIGN SHAN AA..MYANMAR VOWEL SIGN SHAN E
+1085..1086;N # Mn [2] MYANMAR VOWEL SIGN SHAN E ABOVE..MYANMAR VOWEL SIGN SHAN FINAL Y
+1087..108C;N # Mc [6] MYANMAR SIGN SHAN TONE-2..MYANMAR SIGN SHAN COUNCIL TONE-3
+108D;N # Mn MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE
+108E;N # Lo MYANMAR LETTER RUMAI PALAUNG FA
+108F;N # Mc MYANMAR SIGN RUMAI PALAUNG TONE-5
+1090..1099;N # Nd [10] MYANMAR SHAN DIGIT ZERO..MYANMAR SHAN DIGIT NINE
+109A..109C;N # Mc [3] MYANMAR SIGN KHAMTI TONE-1..MYANMAR VOWEL SIGN AITON A
+109D;N # Mn MYANMAR VOWEL SIGN AITON AI
+109E..109F;N # So [2] MYANMAR SYMBOL SHAN ONE..MYANMAR SYMBOL SHAN EXCLAMATION
+10A0..10C5;N # Lu [38] GEORGIAN CAPITAL LETTER AN..GEORGIAN CAPITAL LETTER HOE
+10C7;N # Lu GEORGIAN CAPITAL LETTER YN
+10CD;N # Lu GEORGIAN CAPITAL LETTER AEN
+10D0..10FA;N # Lo [43] GEORGIAN LETTER AN..GEORGIAN LETTER AIN
+10FB;N # Po GEORGIAN PARAGRAPH SEPARATOR
+10FC;N # Lm MODIFIER LETTER GEORGIAN NAR
+10FD..10FF;N # Lo [3] GEORGIAN LETTER AEN..GEORGIAN LETTER LABIAL SIGN
+1100..115F;W # Lo [96] HANGUL CHOSEONG KIYEOK..HANGUL CHOSEONG FILLER
+1160..11FF;N # Lo [160] HANGUL JUNGSEONG FILLER..HANGUL JONGSEONG SSANGNIEUN
+1200..1248;N # Lo [73] ETHIOPIC SYLLABLE HA..ETHIOPIC SYLLABLE QWA
+124A..124D;N # Lo [4] ETHIOPIC SYLLABLE QWI..ETHIOPIC SYLLABLE QWE
+1250..1256;N # Lo [7] ETHIOPIC SYLLABLE QHA..ETHIOPIC SYLLABLE QHO
+1258;N # Lo ETHIOPIC SYLLABLE QHWA
+125A..125D;N # Lo [4] ETHIOPIC SYLLABLE QHWI..ETHIOPIC SYLLABLE QHWE
+1260..1288;N # Lo [41] ETHIOPIC SYLLABLE BA..ETHIOPIC SYLLABLE XWA
+128A..128D;N # Lo [4] ETHIOPIC SYLLABLE XWI..ETHIOPIC SYLLABLE XWE
+1290..12B0;N # Lo [33] ETHIOPIC SYLLABLE NA..ETHIOPIC SYLLABLE KWA
+12B2..12B5;N # Lo [4] ETHIOPIC SYLLABLE KWI..ETHIOPIC SYLLABLE KWE
+12B8..12BE;N # Lo [7] ETHIOPIC SYLLABLE KXA..ETHIOPIC SYLLABLE KXO
+12C0;N # Lo ETHIOPIC SYLLABLE KXWA
+12C2..12C5;N # Lo [4] ETHIOPIC SYLLABLE KXWI..ETHIOPIC SYLLABLE KXWE
+12C8..12D6;N # Lo [15] ETHIOPIC SYLLABLE WA..ETHIOPIC SYLLABLE PHARYNGEAL O
+12D8..1310;N # Lo [57] ETHIOPIC SYLLABLE ZA..ETHIOPIC SYLLABLE GWA
+1312..1315;N # Lo [4] ETHIOPIC SYLLABLE GWI..ETHIOPIC SYLLABLE GWE
+1318..135A;N # Lo [67] ETHIOPIC SYLLABLE GGA..ETHIOPIC SYLLABLE FYA
+135D..135F;N # Mn [3] ETHIOPIC COMBINING GEMINATION AND VOWEL LENGTH MARK..ETHIOPIC COMBINING GEMINATION MARK
+1360..1368;N # Po [9] ETHIOPIC SECTION MARK..ETHIOPIC PARAGRAPH SEPARATOR
+1369..137C;N # No [20] ETHIOPIC DIGIT ONE..ETHIOPIC NUMBER TEN THOUSAND
+1380..138F;N # Lo [16] ETHIOPIC SYLLABLE SEBATBEIT MWA..ETHIOPIC SYLLABLE PWE
+1390..1399;N # So [10] ETHIOPIC TONAL MARK YIZET..ETHIOPIC TONAL MARK KURT
+13A0..13F5;N # Lu [86] CHEROKEE LETTER A..CHEROKEE LETTER MV
+13F8..13FD;N # Ll [6] CHEROKEE SMALL LETTER YE..CHEROKEE SMALL LETTER MV
+1400;N # Pd CANADIAN SYLLABICS HYPHEN
+1401..166C;N # Lo [620] CANADIAN SYLLABICS E..CANADIAN SYLLABICS CARRIER TTSA
+166D..166E;N # Po [2] CANADIAN SYLLABICS CHI SIGN..CANADIAN SYLLABICS FULL STOP
+166F..167F;N # Lo [17] CANADIAN SYLLABICS QAI..CANADIAN SYLLABICS BLACKFOOT W
+1680;N # Zs OGHAM SPACE MARK
+1681..169A;N # Lo [26] OGHAM LETTER BEITH..OGHAM LETTER PEITH
+169B;N # Ps OGHAM FEATHER MARK
+169C;N # Pe OGHAM REVERSED FEATHER MARK
+16A0..16EA;N # Lo [75] RUNIC LETTER FEHU FEOH FE F..RUNIC LETTER X
+16EB..16ED;N # Po [3] RUNIC SINGLE PUNCTUATION..RUNIC CROSS PUNCTUATION
+16EE..16F0;N # Nl [3] RUNIC ARLAUG SYMBOL..RUNIC BELGTHOR SYMBOL
+16F1..16F8;N # Lo [8] RUNIC LETTER K..RUNIC LETTER FRANKS CASKET AESC
+1700..170C;N # Lo [13] TAGALOG LETTER A..TAGALOG LETTER YA
+170E..1711;N # Lo [4] TAGALOG LETTER LA..TAGALOG LETTER HA
+1712..1714;N # Mn [3] TAGALOG VOWEL SIGN I..TAGALOG SIGN VIRAMA
+1720..1731;N # Lo [18] HANUNOO LETTER A..HANUNOO LETTER HA
+1732..1734;N # Mn [3] HANUNOO VOWEL SIGN I..HANUNOO SIGN PAMUDPOD
+1735..1736;N # Po [2] PHILIPPINE SINGLE PUNCTUATION..PHILIPPINE DOUBLE PUNCTUATION
+1740..1751;N # Lo [18] BUHID LETTER A..BUHID LETTER HA
+1752..1753;N # Mn [2] BUHID VOWEL SIGN I..BUHID VOWEL SIGN U
+1760..176C;N # Lo [13] TAGBANWA LETTER A..TAGBANWA LETTER YA
+176E..1770;N # Lo [3] TAGBANWA LETTER LA..TAGBANWA LETTER SA
+1772..1773;N # Mn [2] TAGBANWA VOWEL SIGN I..TAGBANWA VOWEL SIGN U
+1780..17B3;N # Lo [52] KHMER LETTER KA..KHMER INDEPENDENT VOWEL QAU
+17B4..17B5;N # Mn [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA
+17B6;N # Mc KHMER VOWEL SIGN AA
+17B7..17BD;N # Mn [7] KHMER VOWEL SIGN I..KHMER VOWEL SIGN UA
+17BE..17C5;N # Mc [8] KHMER VOWEL SIGN OE..KHMER VOWEL SIGN AU
+17C6;N # Mn KHMER SIGN NIKAHIT
+17C7..17C8;N # Mc [2] KHMER SIGN REAHMUK..KHMER SIGN YUUKALEAPINTU
+17C9..17D3;N # Mn [11] KHMER SIGN MUUSIKATOAN..KHMER SIGN BATHAMASAT
+17D4..17D6;N # Po [3] KHMER SIGN KHAN..KHMER SIGN CAMNUC PII KUUH
+17D7;N # Lm KHMER SIGN LEK TOO
+17D8..17DA;N # Po [3] KHMER SIGN BEYYAL..KHMER SIGN KOOMUUT
+17DB;N # Sc KHMER CURRENCY SYMBOL RIEL
+17DC;N # Lo KHMER SIGN AVAKRAHASANYA
+17DD;N # Mn KHMER SIGN ATTHACAN
+17E0..17E9;N # Nd [10] KHMER DIGIT ZERO..KHMER DIGIT NINE
+17F0..17F9;N # No [10] KHMER SYMBOL LEK ATTAK SON..KHMER SYMBOL LEK ATTAK PRAM-BUON
+1800..1805;N # Po [6] MONGOLIAN BIRGA..MONGOLIAN FOUR DOTS
+1806;N # Pd MONGOLIAN TODO SOFT HYPHEN
+1807..180A;N # Po [4] MONGOLIAN SIBE SYLLABLE BOUNDARY MARKER..MONGOLIAN NIRUGU
+180B..180D;N # Mn [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE
+180E;N # Cf MONGOLIAN VOWEL SEPARATOR
+1810..1819;N # Nd [10] MONGOLIAN DIGIT ZERO..MONGOLIAN DIGIT NINE
+1820..1842;N # Lo [35] MONGOLIAN LETTER A..MONGOLIAN LETTER CHI
+1843;N # Lm MONGOLIAN LETTER TODO LONG VOWEL SIGN
+1844..1877;N # Lo [52] MONGOLIAN LETTER TODO E..MONGOLIAN LETTER MANCHU ZHA
+1880..1884;N # Lo [5] MONGOLIAN LETTER ALI GALI ANUSVARA ONE..MONGOLIAN LETTER ALI GALI INVERTED UBADAMA
+1885..1886;N # Mn [2] MONGOLIAN LETTER ALI GALI BALUDA..MONGOLIAN LETTER ALI GALI THREE BALUDA
+1887..18A8;N # Lo [34] MONGOLIAN LETTER ALI GALI A..MONGOLIAN LETTER MANCHU ALI GALI BHA
+18A9;N # Mn MONGOLIAN LETTER ALI GALI DAGALGA
+18AA;N # Lo MONGOLIAN LETTER MANCHU ALI GALI LHA
+18B0..18F5;N # Lo [70] CANADIAN SYLLABICS OY..CANADIAN SYLLABICS CARRIER DENTAL S
+1900..191E;N # Lo [31] LIMBU VOWEL-CARRIER LETTER..LIMBU LETTER TRA
+1920..1922;N # Mn [3] LIMBU VOWEL SIGN A..LIMBU VOWEL SIGN U
+1923..1926;N # Mc [4] LIMBU VOWEL SIGN EE..LIMBU VOWEL SIGN AU
+1927..1928;N # Mn [2] LIMBU VOWEL SIGN E..LIMBU VOWEL SIGN O
+1929..192B;N # Mc [3] LIMBU SUBJOINED LETTER YA..LIMBU SUBJOINED LETTER WA
+1930..1931;N # Mc [2] LIMBU SMALL LETTER KA..LIMBU SMALL LETTER NGA
+1932;N # Mn LIMBU SMALL LETTER ANUSVARA
+1933..1938;N # Mc [6] LIMBU SMALL LETTER TA..LIMBU SMALL LETTER LA
+1939..193B;N # Mn [3] LIMBU SIGN MUKPHRENG..LIMBU SIGN SA-I
+1940;N # So LIMBU SIGN LOO
+1944..1945;N # Po [2] LIMBU EXCLAMATION MARK..LIMBU QUESTION MARK
+1946..194F;N # Nd [10] LIMBU DIGIT ZERO..LIMBU DIGIT NINE
+1950..196D;N # Lo [30] TAI LE LETTER KA..TAI LE LETTER AI
+1970..1974;N # Lo [5] TAI LE LETTER TONE-2..TAI LE LETTER TONE-6
+1980..19AB;N # Lo [44] NEW TAI LUE LETTER HIGH QA..NEW TAI LUE LETTER LOW SUA
+19B0..19C9;N # Lo [26] NEW TAI LUE VOWEL SIGN VOWEL SHORTENER..NEW TAI LUE TONE MARK-2
+19D0..19D9;N # Nd [10] NEW TAI LUE DIGIT ZERO..NEW TAI LUE DIGIT NINE
+19DA;N # No NEW TAI LUE THAM DIGIT ONE
+19DE..19DF;N # So [2] NEW TAI LUE SIGN LAE..NEW TAI LUE SIGN LAEV
+19E0..19FF;N # So [32] KHMER SYMBOL PATHAMASAT..KHMER SYMBOL DAP-PRAM ROC
+1A00..1A16;N # Lo [23] BUGINESE LETTER KA..BUGINESE LETTER HA
+1A17..1A18;N # Mn [2] BUGINESE VOWEL SIGN I..BUGINESE VOWEL SIGN U
+1A19..1A1A;N # Mc [2] BUGINESE VOWEL SIGN E..BUGINESE VOWEL SIGN O
+1A1B;N # Mn BUGINESE VOWEL SIGN AE
+1A1E..1A1F;N # Po [2] BUGINESE PALLAWA..BUGINESE END OF SECTION
+1A20..1A54;N # Lo [53] TAI THAM LETTER HIGH KA..TAI THAM LETTER GREAT SA
+1A55;N # Mc TAI THAM CONSONANT SIGN MEDIAL RA
+1A56;N # Mn TAI THAM CONSONANT SIGN MEDIAL LA
+1A57;N # Mc TAI THAM CONSONANT SIGN LA TANG LAI
+1A58..1A5E;N # Mn [7] TAI THAM SIGN MAI KANG LAI..TAI THAM CONSONANT SIGN SA
+1A60;N # Mn TAI THAM SIGN SAKOT
+1A61;N # Mc TAI THAM VOWEL SIGN A
+1A62;N # Mn TAI THAM VOWEL SIGN MAI SAT
+1A63..1A64;N # Mc [2] TAI THAM VOWEL SIGN AA..TAI THAM VOWEL SIGN TALL AA
+1A65..1A6C;N # Mn [8] TAI THAM VOWEL SIGN I..TAI THAM VOWEL SIGN OA BELOW
+1A6D..1A72;N # Mc [6] TAI THAM VOWEL SIGN OY..TAI THAM VOWEL SIGN THAM AI
+1A73..1A7C;N # Mn [10] TAI THAM VOWEL SIGN OA ABOVE..TAI THAM SIGN KHUEN-LUE KARAN
+1A7F;N # Mn TAI THAM COMBINING CRYPTOGRAMMIC DOT
+1A80..1A89;N # Nd [10] TAI THAM HORA DIGIT ZERO..TAI THAM HORA DIGIT NINE
+1A90..1A99;N # Nd [10] TAI THAM THAM DIGIT ZERO..TAI THAM THAM DIGIT NINE
+1AA0..1AA6;N # Po [7] TAI THAM SIGN WIANG..TAI THAM SIGN REVERSED ROTATED RANA
+1AA7;N # Lm TAI THAM SIGN MAI YAMOK
+1AA8..1AAD;N # Po [6] TAI THAM SIGN KAAN..TAI THAM SIGN CAANG
+1AB0..1ABD;N # Mn [14] COMBINING DOUBLED CIRCUMFLEX ACCENT..COMBINING PARENTHESES BELOW
+1ABE;N # Me COMBINING PARENTHESES OVERLAY
+1B00..1B03;N # Mn [4] BALINESE SIGN ULU RICEM..BALINESE SIGN SURANG
+1B04;N # Mc BALINESE SIGN BISAH
+1B05..1B33;N # Lo [47] BALINESE LETTER AKARA..BALINESE LETTER HA
+1B34;N # Mn BALINESE SIGN REREKAN
+1B35;N # Mc BALINESE VOWEL SIGN TEDUNG
+1B36..1B3A;N # Mn [5] BALINESE VOWEL SIGN ULU..BALINESE VOWEL SIGN RA REPA
+1B3B;N # Mc BALINESE VOWEL SIGN RA REPA TEDUNG
+1B3C;N # Mn BALINESE VOWEL SIGN LA LENGA
+1B3D..1B41;N # Mc [5] BALINESE VOWEL SIGN LA LENGA TEDUNG..BALINESE VOWEL SIGN TALING REPA TEDUNG
+1B42;N # Mn BALINESE VOWEL SIGN PEPET
+1B43..1B44;N # Mc [2] BALINESE VOWEL SIGN PEPET TEDUNG..BALINESE ADEG ADEG
+1B45..1B4B;N # Lo [7] BALINESE LETTER KAF SASAK..BALINESE LETTER ASYURA SASAK
+1B50..1B59;N # Nd [10] BALINESE DIGIT ZERO..BALINESE DIGIT NINE
+1B5A..1B60;N # Po [7] BALINESE PANTI..BALINESE PAMENENG
+1B61..1B6A;N # So [10] BALINESE MUSICAL SYMBOL DONG..BALINESE MUSICAL SYMBOL DANG GEDE
+1B6B..1B73;N # Mn [9] BALINESE MUSICAL SYMBOL COMBINING TEGEH..BALINESE MUSICAL SYMBOL COMBINING GONG
+1B74..1B7C;N # So [9] BALINESE MUSICAL SYMBOL RIGHT-HAND OPEN DUG..BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PING
+1B80..1B81;N # Mn [2] SUNDANESE SIGN PANYECEK..SUNDANESE SIGN PANGLAYAR
+1B82;N # Mc SUNDANESE SIGN PANGWISAD
+1B83..1BA0;N # Lo [30] SUNDANESE LETTER A..SUNDANESE LETTER HA
+1BA1;N # Mc SUNDANESE CONSONANT SIGN PAMINGKAL
+1BA2..1BA5;N # Mn [4] SUNDANESE CONSONANT SIGN PANYAKRA..SUNDANESE VOWEL SIGN PANYUKU
+1BA6..1BA7;N # Mc [2] SUNDANESE VOWEL SIGN PANAELAENG..SUNDANESE VOWEL SIGN PANOLONG
+1BA8..1BA9;N # Mn [2] SUNDANESE VOWEL SIGN PAMEPET..SUNDANESE VOWEL SIGN PANEULEUNG
+1BAA;N # Mc SUNDANESE SIGN PAMAAEH
+1BAB..1BAD;N # Mn [3] SUNDANESE SIGN VIRAMA..SUNDANESE CONSONANT SIGN PASANGAN WA
+1BAE..1BAF;N # Lo [2] SUNDANESE LETTER KHA..SUNDANESE LETTER SYA
+1BB0..1BB9;N # Nd [10] SUNDANESE DIGIT ZERO..SUNDANESE DIGIT NINE
+1BBA..1BBF;N # Lo [6] SUNDANESE AVAGRAHA..SUNDANESE LETTER FINAL M
+1BC0..1BE5;N # Lo [38] BATAK LETTER A..BATAK LETTER U
+1BE6;N # Mn BATAK SIGN TOMPI
+1BE7;N # Mc BATAK VOWEL SIGN E
+1BE8..1BE9;N # Mn [2] BATAK VOWEL SIGN PAKPAK E..BATAK VOWEL SIGN EE
+1BEA..1BEC;N # Mc [3] BATAK VOWEL SIGN I..BATAK VOWEL SIGN O
+1BED;N # Mn BATAK VOWEL SIGN KARO O
+1BEE;N # Mc BATAK VOWEL SIGN U
+1BEF..1BF1;N # Mn [3] BATAK VOWEL SIGN U FOR SIMALUNGUN SA..BATAK CONSONANT SIGN H
+1BF2..1BF3;N # Mc [2] BATAK PANGOLAT..BATAK PANONGONAN
+1BFC..1BFF;N # Po [4] BATAK SYMBOL BINDU NA METEK..BATAK SYMBOL BINDU PANGOLAT
+1C00..1C23;N # Lo [36] LEPCHA LETTER KA..LEPCHA LETTER A
+1C24..1C2B;N # Mc [8] LEPCHA SUBJOINED LETTER YA..LEPCHA VOWEL SIGN UU
+1C2C..1C33;N # Mn [8] LEPCHA VOWEL SIGN E..LEPCHA CONSONANT SIGN T
+1C34..1C35;N # Mc [2] LEPCHA CONSONANT SIGN NYIN-DO..LEPCHA CONSONANT SIGN KANG
+1C36..1C37;N # Mn [2] LEPCHA SIGN RAN..LEPCHA SIGN NUKTA
+1C3B..1C3F;N # Po [5] LEPCHA PUNCTUATION TA-ROL..LEPCHA PUNCTUATION TSHOOK
+1C40..1C49;N # Nd [10] LEPCHA DIGIT ZERO..LEPCHA DIGIT NINE
+1C4D..1C4F;N # Lo [3] LEPCHA LETTER TTA..LEPCHA LETTER DDA
+1C50..1C59;N # Nd [10] OL CHIKI DIGIT ZERO..OL CHIKI DIGIT NINE
+1C5A..1C77;N # Lo [30] OL CHIKI LETTER LA..OL CHIKI LETTER OH
+1C78..1C7D;N # Lm [6] OL CHIKI MU TTUDDAG..OL CHIKI AHAD
+1C7E..1C7F;N # Po [2] OL CHIKI PUNCTUATION MUCAAD..OL CHIKI PUNCTUATION DOUBLE MUCAAD
+1C80..1C88;N # Ll [9] CYRILLIC SMALL LETTER ROUNDED VE..CYRILLIC SMALL LETTER UNBLENDED UK
+1CC0..1CC7;N # Po [8] SUNDANESE PUNCTUATION BINDU SURYA..SUNDANESE PUNCTUATION BINDU BA SATANGA
+1CD0..1CD2;N # Mn [3] VEDIC TONE KARSHANA..VEDIC TONE PRENKHA
+1CD3;N # Po VEDIC SIGN NIHSHVASA
+1CD4..1CE0;N # Mn [13] VEDIC SIGN YAJURVEDIC MIDLINE SVARITA..VEDIC TONE RIGVEDIC KASHMIRI INDEPENDENT SVARITA
+1CE1;N # Mc VEDIC TONE ATHARVAVEDIC INDEPENDENT SVARITA
+1CE2..1CE8;N # Mn [7] VEDIC SIGN VISARGA SVARITA..VEDIC SIGN VISARGA ANUDATTA WITH TAIL
+1CE9..1CEC;N # Lo [4] VEDIC SIGN ANUSVARA ANTARGOMUKHA..VEDIC SIGN ANUSVARA VAMAGOMUKHA WITH TAIL
+1CED;N # Mn VEDIC SIGN TIRYAK
+1CEE..1CF1;N # Lo [4] VEDIC SIGN HEXIFORM LONG ANUSVARA..VEDIC SIGN ANUSVARA UBHAYATO MUKHA
+1CF2..1CF3;N # Mc [2] VEDIC SIGN ARDHAVISARGA..VEDIC SIGN ROTATED ARDHAVISARGA
+1CF4;N # Mn VEDIC TONE CANDRA ABOVE
+1CF5..1CF6;N # Lo [2] VEDIC SIGN JIHVAMULIYA..VEDIC SIGN UPADHMANIYA
+1CF7;N # Mc VEDIC SIGN ATIKRAMA
+1CF8..1CF9;N # Mn [2] VEDIC TONE RING ABOVE..VEDIC TONE DOUBLE RING ABOVE
+1D00..1D2B;N # Ll [44] LATIN LETTER SMALL CAPITAL A..CYRILLIC LETTER SMALL CAPITAL EL
+1D2C..1D6A;N # Lm [63] MODIFIER LETTER CAPITAL A..GREEK SUBSCRIPT SMALL LETTER CHI
+1D6B..1D77;N # Ll [13] LATIN SMALL LETTER UE..LATIN SMALL LETTER TURNED G
+1D78;N # Lm MODIFIER LETTER CYRILLIC EN
+1D79..1D7F;N # Ll [7] LATIN SMALL LETTER INSULAR G..LATIN SMALL LETTER UPSILON WITH STROKE
+1D80..1D9A;N # Ll [27] LATIN SMALL LETTER B WITH PALATAL HOOK..LATIN SMALL LETTER EZH WITH RETROFLEX HOOK
+1D9B..1DBF;N # Lm [37] MODIFIER LETTER SMALL TURNED ALPHA..MODIFIER LETTER SMALL THETA
+1DC0..1DF9;N # Mn [58] COMBINING DOTTED GRAVE ACCENT..COMBINING WIDE INVERTED BRIDGE BELOW
+1DFB..1DFF;N # Mn [5] COMBINING DELETION MARK..COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW
+1E00..1EFF;N # L& [256] LATIN CAPITAL LETTER A WITH RING BELOW..LATIN SMALL LETTER Y WITH LOOP
+1F00..1F15;N # L& [22] GREEK SMALL LETTER ALPHA WITH PSILI..GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA
+1F18..1F1D;N # Lu [6] GREEK CAPITAL LETTER EPSILON WITH PSILI..GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA
+1F20..1F45;N # L& [38] GREEK SMALL LETTER ETA WITH PSILI..GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA
+1F48..1F4D;N # Lu [6] GREEK CAPITAL LETTER OMICRON WITH PSILI..GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA
+1F50..1F57;N # Ll [8] GREEK SMALL LETTER UPSILON WITH PSILI..GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI
+1F59;N # Lu GREEK CAPITAL LETTER UPSILON WITH DASIA
+1F5B;N # Lu GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA
+1F5D;N # Lu GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA
+1F5F..1F7D;N # L& [31] GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI..GREEK SMALL LETTER OMEGA WITH OXIA
+1F80..1FB4;N # L& [53] GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI..GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI
+1FB6..1FBC;N # L& [7] GREEK SMALL LETTER ALPHA WITH PERISPOMENI..GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI
+1FBD;N # Sk GREEK KORONIS
+1FBE;N # Ll GREEK PROSGEGRAMMENI
+1FBF..1FC1;N # Sk [3] GREEK PSILI..GREEK DIALYTIKA AND PERISPOMENI
+1FC2..1FC4;N # Ll [3] GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI..GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI
+1FC6..1FCC;N # L& [7] GREEK SMALL LETTER ETA WITH PERISPOMENI..GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI
+1FCD..1FCF;N # Sk [3] GREEK PSILI AND VARIA..GREEK PSILI AND PERISPOMENI
+1FD0..1FD3;N # Ll [4] GREEK SMALL LETTER IOTA WITH VRACHY..GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA
+1FD6..1FDB;N # L& [6] GREEK SMALL LETTER IOTA WITH PERISPOMENI..GREEK CAPITAL LETTER IOTA WITH OXIA
+1FDD..1FDF;N # Sk [3] GREEK DASIA AND VARIA..GREEK DASIA AND PERISPOMENI
+1FE0..1FEC;N # L& [13] GREEK SMALL LETTER UPSILON WITH VRACHY..GREEK CAPITAL LETTER RHO WITH DASIA
+1FED..1FEF;N # Sk [3] GREEK DIALYTIKA AND VARIA..GREEK VARIA
+1FF2..1FF4;N # Ll [3] GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI..GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI
+1FF6..1FFC;N # L& [7] GREEK SMALL LETTER OMEGA WITH PERISPOMENI..GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI
+1FFD..1FFE;N # Sk [2] GREEK OXIA..GREEK DASIA
+2000..200A;N # Zs [11] EN QUAD..HAIR SPACE
+200B..200F;N # Cf [5] ZERO WIDTH SPACE..RIGHT-TO-LEFT MARK
+2010;A # Pd HYPHEN
+2011..2012;N # Pd [2] NON-BREAKING HYPHEN..FIGURE DASH
+2013..2015;A # Pd [3] EN DASH..HORIZONTAL BAR
+2016;A # Po DOUBLE VERTICAL LINE
+2017;N # Po DOUBLE LOW LINE
+2018;A # Pi LEFT SINGLE QUOTATION MARK
+2019;A # Pf RIGHT SINGLE QUOTATION MARK
+201A;N # Ps SINGLE LOW-9 QUOTATION MARK
+201B;N # Pi SINGLE HIGH-REVERSED-9 QUOTATION MARK
+201C;A # Pi LEFT DOUBLE QUOTATION MARK
+201D;A # Pf RIGHT DOUBLE QUOTATION MARK
+201E;N # Ps DOUBLE LOW-9 QUOTATION MARK
+201F;N # Pi DOUBLE HIGH-REVERSED-9 QUOTATION MARK
+2020..2022;A # Po [3] DAGGER..BULLET
+2023;N # Po TRIANGULAR BULLET
+2024..2027;A # Po [4] ONE DOT LEADER..HYPHENATION POINT
+2028;N # Zl LINE SEPARATOR
+2029;N # Zp PARAGRAPH SEPARATOR
+202A..202E;N # Cf [5] LEFT-TO-RIGHT EMBEDDING..RIGHT-TO-LEFT OVERRIDE
+202F;N # Zs NARROW NO-BREAK SPACE
+2030;A # Po PER MILLE SIGN
+2031;N # Po PER TEN THOUSAND SIGN
+2032..2033;A # Po [2] PRIME..DOUBLE PRIME
+2034;N # Po TRIPLE PRIME
+2035;A # Po REVERSED PRIME
+2036..2038;N # Po [3] REVERSED DOUBLE PRIME..CARET
+2039;N # Pi SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+203A;N # Pf SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+203B;A # Po REFERENCE MARK
+203C..203D;N # Po [2] DOUBLE EXCLAMATION MARK..INTERROBANG
+203E;A # Po OVERLINE
+203F..2040;N # Pc [2] UNDERTIE..CHARACTER TIE
+2041..2043;N # Po [3] CARET INSERTION POINT..HYPHEN BULLET
+2044;N # Sm FRACTION SLASH
+2045;N # Ps LEFT SQUARE BRACKET WITH QUILL
+2046;N # Pe RIGHT SQUARE BRACKET WITH QUILL
+2047..2051;N # Po [11] DOUBLE QUESTION MARK..TWO ASTERISKS ALIGNED VERTICALLY
+2052;N # Sm COMMERCIAL MINUS SIGN
+2053;N # Po SWUNG DASH
+2054;N # Pc INVERTED UNDERTIE
+2055..205E;N # Po [10] FLOWER PUNCTUATION MARK..VERTICAL FOUR DOTS
+205F;N # Zs MEDIUM MATHEMATICAL SPACE
+2060..2064;N # Cf [5] WORD JOINER..INVISIBLE PLUS
+2066..206F;N # Cf [10] LEFT-TO-RIGHT ISOLATE..NOMINAL DIGIT SHAPES
+2070;N # No SUPERSCRIPT ZERO
+2071;N # Lm SUPERSCRIPT LATIN SMALL LETTER I
+2074;A # No SUPERSCRIPT FOUR
+2075..2079;N # No [5] SUPERSCRIPT FIVE..SUPERSCRIPT NINE
+207A..207C;N # Sm [3] SUPERSCRIPT PLUS SIGN..SUPERSCRIPT EQUALS SIGN
+207D;N # Ps SUPERSCRIPT LEFT PARENTHESIS
+207E;N # Pe SUPERSCRIPT RIGHT PARENTHESIS
+207F;A # Lm SUPERSCRIPT LATIN SMALL LETTER N
+2080;N # No SUBSCRIPT ZERO
+2081..2084;A # No [4] SUBSCRIPT ONE..SUBSCRIPT FOUR
+2085..2089;N # No [5] SUBSCRIPT FIVE..SUBSCRIPT NINE
+208A..208C;N # Sm [3] SUBSCRIPT PLUS SIGN..SUBSCRIPT EQUALS SIGN
+208D;N # Ps SUBSCRIPT LEFT PARENTHESIS
+208E;N # Pe SUBSCRIPT RIGHT PARENTHESIS
+2090..209C;N # Lm [13] LATIN SUBSCRIPT SMALL LETTER A..LATIN SUBSCRIPT SMALL LETTER T
+20A0..20A8;N # Sc [9] EURO-CURRENCY SIGN..RUPEE SIGN
+20A9;H # Sc WON SIGN
+20AA..20AB;N # Sc [2] NEW SHEQEL SIGN..DONG SIGN
+20AC;A # Sc EURO SIGN
+20AD..20BF;N # Sc [19] KIP SIGN..BITCOIN SIGN
+20D0..20DC;N # Mn [13] COMBINING LEFT HARPOON ABOVE..COMBINING FOUR DOTS ABOVE
+20DD..20E0;N # Me [4] COMBINING ENCLOSING CIRCLE..COMBINING ENCLOSING CIRCLE BACKSLASH
+20E1;N # Mn COMBINING LEFT RIGHT ARROW ABOVE
+20E2..20E4;N # Me [3] COMBINING ENCLOSING SCREEN..COMBINING ENCLOSING UPWARD POINTING TRIANGLE
+20E5..20F0;N # Mn [12] COMBINING REVERSE SOLIDUS OVERLAY..COMBINING ASTERISK ABOVE
+2100..2101;N # So [2] ACCOUNT OF..ADDRESSED TO THE SUBJECT
+2102;N # Lu DOUBLE-STRUCK CAPITAL C
+2103;A # So DEGREE CELSIUS
+2104;N # So CENTRE LINE SYMBOL
+2105;A # So CARE OF
+2106;N # So CADA UNA
+2107;N # Lu EULER CONSTANT
+2108;N # So SCRUPLE
+2109;A # So DEGREE FAHRENHEIT
+210A..2112;N # L& [9] SCRIPT SMALL G..SCRIPT CAPITAL L
+2113;A # Ll SCRIPT SMALL L
+2114;N # So L B BAR SYMBOL
+2115;N # Lu DOUBLE-STRUCK CAPITAL N
+2116;A # So NUMERO SIGN
+2117;N # So SOUND RECORDING COPYRIGHT
+2118;N # Sm SCRIPT CAPITAL P
+2119..211D;N # Lu [5] DOUBLE-STRUCK CAPITAL P..DOUBLE-STRUCK CAPITAL R
+211E..2120;N # So [3] PRESCRIPTION TAKE..SERVICE MARK
+2121..2122;A # So [2] TELEPHONE SIGN..TRADE MARK SIGN
+2123;N # So VERSICLE
+2124;N # Lu DOUBLE-STRUCK CAPITAL Z
+2125;N # So OUNCE SIGN
+2126;A # Lu OHM SIGN
+2127;N # So INVERTED OHM SIGN
+2128;N # Lu BLACK-LETTER CAPITAL Z
+2129;N # So TURNED GREEK SMALL LETTER IOTA
+212A;N # Lu KELVIN SIGN
+212B;A # Lu ANGSTROM SIGN
+212C..212D;N # Lu [2] SCRIPT CAPITAL B..BLACK-LETTER CAPITAL C
+212E;N # So ESTIMATED SYMBOL
+212F..2134;N # L& [6] SCRIPT SMALL E..SCRIPT SMALL O
+2135..2138;N # Lo [4] ALEF SYMBOL..DALET SYMBOL
+2139;N # Ll INFORMATION SOURCE
+213A..213B;N # So [2] ROTATED CAPITAL Q..FACSIMILE SIGN
+213C..213F;N # L& [4] DOUBLE-STRUCK SMALL PI..DOUBLE-STRUCK CAPITAL PI
+2140..2144;N # Sm [5] DOUBLE-STRUCK N-ARY SUMMATION..TURNED SANS-SERIF CAPITAL Y
+2145..2149;N # L& [5] DOUBLE-STRUCK ITALIC CAPITAL D..DOUBLE-STRUCK ITALIC SMALL J
+214A;N # So PROPERTY LINE
+214B;N # Sm TURNED AMPERSAND
+214C..214D;N # So [2] PER SIGN..AKTIESELSKAB
+214E;N # Ll TURNED SMALL F
+214F;N # So SYMBOL FOR SAMARITAN SOURCE
+2150..2152;N # No [3] VULGAR FRACTION ONE SEVENTH..VULGAR FRACTION ONE TENTH
+2153..2154;A # No [2] VULGAR FRACTION ONE THIRD..VULGAR FRACTION TWO THIRDS
+2155..215A;N # No [6] VULGAR FRACTION ONE FIFTH..VULGAR FRACTION FIVE SIXTHS
+215B..215E;A # No [4] VULGAR FRACTION ONE EIGHTH..VULGAR FRACTION SEVEN EIGHTHS
+215F;N # No FRACTION NUMERATOR ONE
+2160..216B;A # Nl [12] ROMAN NUMERAL ONE..ROMAN NUMERAL TWELVE
+216C..216F;N # Nl [4] ROMAN NUMERAL FIFTY..ROMAN NUMERAL ONE THOUSAND
+2170..2179;A # Nl [10] SMALL ROMAN NUMERAL ONE..SMALL ROMAN NUMERAL TEN
+217A..2182;N # Nl [9] SMALL ROMAN NUMERAL ELEVEN..ROMAN NUMERAL TEN THOUSAND
+2183..2184;N # L& [2] ROMAN NUMERAL REVERSED ONE HUNDRED..LATIN SMALL LETTER REVERSED C
+2185..2188;N # Nl [4] ROMAN NUMERAL SIX LATE FORM..ROMAN NUMERAL ONE HUNDRED THOUSAND
+2189;A # No VULGAR FRACTION ZERO THIRDS
+218A..218B;N # So [2] TURNED DIGIT TWO..TURNED DIGIT THREE
+2190..2194;A # Sm [5] LEFTWARDS ARROW..LEFT RIGHT ARROW
+2195..2199;A # So [5] UP DOWN ARROW..SOUTH WEST ARROW
+219A..219B;N # Sm [2] LEFTWARDS ARROW WITH STROKE..RIGHTWARDS ARROW WITH STROKE
+219C..219F;N # So [4] LEFTWARDS WAVE ARROW..UPWARDS TWO HEADED ARROW
+21A0;N # Sm RIGHTWARDS TWO HEADED ARROW
+21A1..21A2;N # So [2] DOWNWARDS TWO HEADED ARROW..LEFTWARDS ARROW WITH TAIL
+21A3;N # Sm RIGHTWARDS ARROW WITH TAIL
+21A4..21A5;N # So [2] LEFTWARDS ARROW FROM BAR..UPWARDS ARROW FROM BAR
+21A6;N # Sm RIGHTWARDS ARROW FROM BAR
+21A7..21AD;N # So [7] DOWNWARDS ARROW FROM BAR..LEFT RIGHT WAVE ARROW
+21AE;N # Sm LEFT RIGHT ARROW WITH STROKE
+21AF..21B7;N # So [9] DOWNWARDS ZIGZAG ARROW..CLOCKWISE TOP SEMICIRCLE ARROW
+21B8..21B9;A # So [2] NORTH WEST ARROW TO LONG BAR..LEFTWARDS ARROW TO BAR OVER RIGHTWARDS ARROW TO BAR
+21BA..21CD;N # So [20] ANTICLOCKWISE OPEN CIRCLE ARROW..LEFTWARDS DOUBLE ARROW WITH STROKE
+21CE..21CF;N # Sm [2] LEFT RIGHT DOUBLE ARROW WITH STROKE..RIGHTWARDS DOUBLE ARROW WITH STROKE
+21D0..21D1;N # So [2] LEFTWARDS DOUBLE ARROW..UPWARDS DOUBLE ARROW
+21D2;A # Sm RIGHTWARDS DOUBLE ARROW
+21D3;N # So DOWNWARDS DOUBLE ARROW
+21D4;A # Sm LEFT RIGHT DOUBLE ARROW
+21D5..21E6;N # So [18] UP DOWN DOUBLE ARROW..LEFTWARDS WHITE ARROW
+21E7;A # So UPWARDS WHITE ARROW
+21E8..21F3;N # So [12] RIGHTWARDS WHITE ARROW..UP DOWN WHITE ARROW
+21F4..21FF;N # Sm [12] RIGHT ARROW WITH SMALL CIRCLE..LEFT RIGHT OPEN-HEADED ARROW
+2200;A # Sm FOR ALL
+2201;N # Sm COMPLEMENT
+2202..2203;A # Sm [2] PARTIAL DIFFERENTIAL..THERE EXISTS
+2204..2206;N # Sm [3] THERE DOES NOT EXIST..INCREMENT
+2207..2208;A # Sm [2] NABLA..ELEMENT OF
+2209..220A;N # Sm [2] NOT AN ELEMENT OF..SMALL ELEMENT OF
+220B;A # Sm CONTAINS AS MEMBER
+220C..220E;N # Sm [3] DOES NOT CONTAIN AS MEMBER..END OF PROOF
+220F;A # Sm N-ARY PRODUCT
+2210;N # Sm N-ARY COPRODUCT
+2211;A # Sm N-ARY SUMMATION
+2212..2214;N # Sm [3] MINUS SIGN..DOT PLUS
+2215;A # Sm DIVISION SLASH
+2216..2219;N # Sm [4] SET MINUS..BULLET OPERATOR
+221A;A # Sm SQUARE ROOT
+221B..221C;N # Sm [2] CUBE ROOT..FOURTH ROOT
+221D..2220;A # Sm [4] PROPORTIONAL TO..ANGLE
+2221..2222;N # Sm [2] MEASURED ANGLE..SPHERICAL ANGLE
+2223;A # Sm DIVIDES
+2224;N # Sm DOES NOT DIVIDE
+2225;A # Sm PARALLEL TO
+2226;N # Sm NOT PARALLEL TO
+2227..222C;A # Sm [6] LOGICAL AND..DOUBLE INTEGRAL
+222D;N # Sm TRIPLE INTEGRAL
+222E;A # Sm CONTOUR INTEGRAL
+222F..2233;N # Sm [5] SURFACE INTEGRAL..ANTICLOCKWISE CONTOUR INTEGRAL
+2234..2237;A # Sm [4] THEREFORE..PROPORTION
+2238..223B;N # Sm [4] DOT MINUS..HOMOTHETIC
+223C..223D;A # Sm [2] TILDE OPERATOR..REVERSED TILDE
+223E..2247;N # Sm [10] INVERTED LAZY S..NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO
+2248;A # Sm ALMOST EQUAL TO
+2249..224B;N # Sm [3] NOT ALMOST EQUAL TO..TRIPLE TILDE
+224C;A # Sm ALL EQUAL TO
+224D..2251;N # Sm [5] EQUIVALENT TO..GEOMETRICALLY EQUAL TO
+2252;A # Sm APPROXIMATELY EQUAL TO OR THE IMAGE OF
+2253..225F;N # Sm [13] IMAGE OF OR APPROXIMATELY EQUAL TO..QUESTIONED EQUAL TO
+2260..2261;A # Sm [2] NOT EQUAL TO..IDENTICAL TO
+2262..2263;N # Sm [2] NOT IDENTICAL TO..STRICTLY EQUIVALENT TO
+2264..2267;A # Sm [4] LESS-THAN OR EQUAL TO..GREATER-THAN OVER EQUAL TO
+2268..2269;N # Sm [2] LESS-THAN BUT NOT EQUAL TO..GREATER-THAN BUT NOT EQUAL TO
+226A..226B;A # Sm [2] MUCH LESS-THAN..MUCH GREATER-THAN
+226C..226D;N # Sm [2] BETWEEN..NOT EQUIVALENT TO
+226E..226F;A # Sm [2] NOT LESS-THAN..NOT GREATER-THAN
+2270..2281;N # Sm [18] NEITHER LESS-THAN NOR EQUAL TO..DOES NOT SUCCEED
+2282..2283;A # Sm [2] SUBSET OF..SUPERSET OF
+2284..2285;N # Sm [2] NOT A SUBSET OF..NOT A SUPERSET OF
+2286..2287;A # Sm [2] SUBSET OF OR EQUAL TO..SUPERSET OF OR EQUAL TO
+2288..2294;N # Sm [13] NEITHER A SUBSET OF NOR EQUAL TO..SQUARE CUP
+2295;A # Sm CIRCLED PLUS
+2296..2298;N # Sm [3] CIRCLED MINUS..CIRCLED DIVISION SLASH
+2299;A # Sm CIRCLED DOT OPERATOR
+229A..22A4;N # Sm [11] CIRCLED RING OPERATOR..DOWN TACK
+22A5;A # Sm UP TACK
+22A6..22BE;N # Sm [25] ASSERTION..RIGHT ANGLE WITH ARC
+22BF;A # Sm RIGHT TRIANGLE
+22C0..22FF;N # Sm [64] N-ARY LOGICAL AND..Z NOTATION BAG MEMBERSHIP
+2300..2307;N # So [8] DIAMETER SIGN..WAVY LINE
+2308;N # Ps LEFT CEILING
+2309;N # Pe RIGHT CEILING
+230A;N # Ps LEFT FLOOR
+230B;N # Pe RIGHT FLOOR
+230C..2311;N # So [6] BOTTOM RIGHT CROP..SQUARE LOZENGE
+2312;A # So ARC
+2313..2319;N # So [7] SEGMENT..TURNED NOT SIGN
+231A..231B;W # So [2] WATCH..HOURGLASS
+231C..231F;N # So [4] TOP LEFT CORNER..BOTTOM RIGHT CORNER
+2320..2321;N # Sm [2] TOP HALF INTEGRAL..BOTTOM HALF INTEGRAL
+2322..2328;N # So [7] FROWN..KEYBOARD
+2329;W # Ps LEFT-POINTING ANGLE BRACKET
+232A;W # Pe RIGHT-POINTING ANGLE BRACKET
+232B..237B;N # So [81] ERASE TO THE LEFT..NOT CHECK MARK
+237C;N # Sm RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW
+237D..239A;N # So [30] SHOULDERED OPEN BOX..CLEAR SCREEN SYMBOL
+239B..23B3;N # Sm [25] LEFT PARENTHESIS UPPER HOOK..SUMMATION BOTTOM
+23B4..23DB;N # So [40] TOP SQUARE BRACKET..FUSE
+23DC..23E1;N # Sm [6] TOP PARENTHESIS..BOTTOM TORTOISE SHELL BRACKET
+23E2..23E8;N # So [7] WHITE TRAPEZIUM..DECIMAL EXPONENT SYMBOL
+23E9..23EC;W # So [4] BLACK RIGHT-POINTING DOUBLE TRIANGLE..BLACK DOWN-POINTING DOUBLE TRIANGLE
+23ED..23EF;N # So [3] BLACK RIGHT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR..BLACK RIGHT-POINTING TRIANGLE WITH DOUBLE VERTICAL BAR
+23F0;W # So ALARM CLOCK
+23F1..23F2;N # So [2] STOPWATCH..TIMER CLOCK
+23F3;W # So HOURGLASS WITH FLOWING SAND
+23F4..23FF;N # So [12] BLACK MEDIUM LEFT-POINTING TRIANGLE..OBSERVER EYE SYMBOL
+2400..2426;N # So [39] SYMBOL FOR NULL..SYMBOL FOR SUBSTITUTE FORM TWO
+2440..244A;N # So [11] OCR HOOK..OCR DOUBLE BACKSLASH
+2460..249B;A # No [60] CIRCLED DIGIT ONE..NUMBER TWENTY FULL STOP
+249C..24E9;A # So [78] PARENTHESIZED LATIN SMALL LETTER A..CIRCLED LATIN SMALL LETTER Z
+24EA;N # No CIRCLED DIGIT ZERO
+24EB..24FF;A # No [21] NEGATIVE CIRCLED NUMBER ELEVEN..NEGATIVE CIRCLED DIGIT ZERO
+2500..254B;A # So [76] BOX DRAWINGS LIGHT HORIZONTAL..BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL
+254C..254F;N # So [4] BOX DRAWINGS LIGHT DOUBLE DASH HORIZONTAL..BOX DRAWINGS HEAVY DOUBLE DASH VERTICAL
+2550..2573;A # So [36] BOX DRAWINGS DOUBLE HORIZONTAL..BOX DRAWINGS LIGHT DIAGONAL CROSS
+2574..257F;N # So [12] BOX DRAWINGS LIGHT LEFT..BOX DRAWINGS HEAVY UP AND LIGHT DOWN
+2580..258F;A # So [16] UPPER HALF BLOCK..LEFT ONE EIGHTH BLOCK
+2590..2591;N # So [2] RIGHT HALF BLOCK..LIGHT SHADE
+2592..2595;A # So [4] MEDIUM SHADE..RIGHT ONE EIGHTH BLOCK
+2596..259F;N # So [10] QUADRANT LOWER LEFT..QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT
+25A0..25A1;A # So [2] BLACK SQUARE..WHITE SQUARE
+25A2;N # So WHITE SQUARE WITH ROUNDED CORNERS
+25A3..25A9;A # So [7] WHITE SQUARE CONTAINING BLACK SMALL SQUARE..SQUARE WITH DIAGONAL CROSSHATCH FILL
+25AA..25B1;N # So [8] BLACK SMALL SQUARE..WHITE PARALLELOGRAM
+25B2..25B3;A # So [2] BLACK UP-POINTING TRIANGLE..WHITE UP-POINTING TRIANGLE
+25B4..25B5;N # So [2] BLACK UP-POINTING SMALL TRIANGLE..WHITE UP-POINTING SMALL TRIANGLE
+25B6;A # So BLACK RIGHT-POINTING TRIANGLE
+25B7;A # Sm WHITE RIGHT-POINTING TRIANGLE
+25B8..25BB;N # So [4] BLACK RIGHT-POINTING SMALL TRIANGLE..WHITE RIGHT-POINTING POINTER
+25BC..25BD;A # So [2] BLACK DOWN-POINTING TRIANGLE..WHITE DOWN-POINTING TRIANGLE
+25BE..25BF;N # So [2] BLACK DOWN-POINTING SMALL TRIANGLE..WHITE DOWN-POINTING SMALL TRIANGLE
+25C0;A # So BLACK LEFT-POINTING TRIANGLE
+25C1;A # Sm WHITE LEFT-POINTING TRIANGLE
+25C2..25C5;N # So [4] BLACK LEFT-POINTING SMALL TRIANGLE..WHITE LEFT-POINTING POINTER
+25C6..25C8;A # So [3] BLACK DIAMOND..WHITE DIAMOND CONTAINING BLACK SMALL DIAMOND
+25C9..25CA;N # So [2] FISHEYE..LOZENGE
+25CB;A # So WHITE CIRCLE
+25CC..25CD;N # So [2] DOTTED CIRCLE..CIRCLE WITH VERTICAL FILL
+25CE..25D1;A # So [4] BULLSEYE..CIRCLE WITH RIGHT HALF BLACK
+25D2..25E1;N # So [16] CIRCLE WITH LOWER HALF BLACK..LOWER HALF CIRCLE
+25E2..25E5;A # So [4] BLACK LOWER RIGHT TRIANGLE..BLACK UPPER RIGHT TRIANGLE
+25E6..25EE;N # So [9] WHITE BULLET..UP-POINTING TRIANGLE WITH RIGHT HALF BLACK
+25EF;A # So LARGE CIRCLE
+25F0..25F7;N # So [8] WHITE SQUARE WITH UPPER LEFT QUADRANT..WHITE CIRCLE WITH UPPER RIGHT QUADRANT
+25F8..25FC;N # Sm [5] UPPER LEFT TRIANGLE..BLACK MEDIUM SQUARE
+25FD..25FE;W # Sm [2] WHITE MEDIUM SMALL SQUARE..BLACK MEDIUM SMALL SQUARE
+25FF;N # Sm LOWER RIGHT TRIANGLE
+2600..2604;N # So [5] BLACK SUN WITH RAYS..COMET
+2605..2606;A # So [2] BLACK STAR..WHITE STAR
+2607..2608;N # So [2] LIGHTNING..THUNDERSTORM
+2609;A # So SUN
+260A..260D;N # So [4] ASCENDING NODE..OPPOSITION
+260E..260F;A # So [2] BLACK TELEPHONE..WHITE TELEPHONE
+2610..2613;N # So [4] BALLOT BOX..SALTIRE
+2614..2615;W # So [2] UMBRELLA WITH RAIN DROPS..HOT BEVERAGE
+2616..261B;N # So [6] WHITE SHOGI PIECE..BLACK RIGHT POINTING INDEX
+261C;A # So WHITE LEFT POINTING INDEX
+261D;N # So WHITE UP POINTING INDEX
+261E;A # So WHITE RIGHT POINTING INDEX
+261F..263F;N # So [33] WHITE DOWN POINTING INDEX..MERCURY
+2640;A # So FEMALE SIGN
+2641;N # So EARTH
+2642;A # So MALE SIGN
+2643..2647;N # So [5] JUPITER..PLUTO
+2648..2653;W # So [12] ARIES..PISCES
+2654..265F;N # So [12] WHITE CHESS KING..BLACK CHESS PAWN
+2660..2661;A # So [2] BLACK SPADE SUIT..WHITE HEART SUIT
+2662;N # So WHITE DIAMOND SUIT
+2663..2665;A # So [3] BLACK CLUB SUIT..BLACK HEART SUIT
+2666;N # So BLACK DIAMOND SUIT
+2667..266A;A # So [4] WHITE CLUB SUIT..EIGHTH NOTE
+266B;N # So BEAMED EIGHTH NOTES
+266C..266D;A # So [2] BEAMED SIXTEENTH NOTES..MUSIC FLAT SIGN
+266E;N # So MUSIC NATURAL SIGN
+266F;A # Sm MUSIC SHARP SIGN
+2670..267E;N # So [15] WEST SYRIAC CROSS..PERMANENT PAPER SIGN
+267F;W # So WHEELCHAIR SYMBOL
+2680..2692;N # So [19] DIE FACE-1..HAMMER AND PICK
+2693;W # So ANCHOR
+2694..269D;N # So [10] CROSSED SWORDS..OUTLINED WHITE STAR
+269E..269F;A # So [2] THREE LINES CONVERGING RIGHT..THREE LINES CONVERGING LEFT
+26A0;N # So WARNING SIGN
+26A1;W # So HIGH VOLTAGE SIGN
+26A2..26A9;N # So [8] DOUBLED FEMALE SIGN..HORIZONTAL MALE WITH STROKE SIGN
+26AA..26AB;W # So [2] MEDIUM WHITE CIRCLE..MEDIUM BLACK CIRCLE
+26AC..26BC;N # So [17] MEDIUM SMALL WHITE CIRCLE..SESQUIQUADRATE
+26BD..26BE;W # So [2] SOCCER BALL..BASEBALL
+26BF;A # So SQUARED KEY
+26C0..26C3;N # So [4] WHITE DRAUGHTS MAN..BLACK DRAUGHTS KING
+26C4..26C5;W # So [2] SNOWMAN WITHOUT SNOW..SUN BEHIND CLOUD
+26C6..26CD;A # So [8] RAIN..DISABLED CAR
+26CE;W # So OPHIUCHUS
+26CF..26D3;A # So [5] PICK..CHAINS
+26D4;W # So NO ENTRY
+26D5..26E1;A # So [13] ALTERNATE ONE-WAY LEFT WAY TRAFFIC..RESTRICTED LEFT ENTRY-2
+26E2;N # So ASTRONOMICAL SYMBOL FOR URANUS
+26E3;A # So HEAVY CIRCLE WITH STROKE AND TWO DOTS ABOVE
+26E4..26E7;N # So [4] PENTAGRAM..INVERTED PENTAGRAM
+26E8..26E9;A # So [2] BLACK CROSS ON SHIELD..SHINTO SHRINE
+26EA;W # So CHURCH
+26EB..26F1;A # So [7] CASTLE..UMBRELLA ON GROUND
+26F2..26F3;W # So [2] FOUNTAIN..FLAG IN HOLE
+26F4;A # So FERRY
+26F5;W # So SAILBOAT
+26F6..26F9;A # So [4] SQUARE FOUR CORNERS..PERSON WITH BALL
+26FA;W # So TENT
+26FB..26FC;A # So [2] JAPANESE BANK SYMBOL..HEADSTONE GRAVEYARD SYMBOL
+26FD;W # So FUEL PUMP
+26FE..26FF;A # So [2] CUP ON BLACK SQUARE..WHITE FLAG WITH HORIZONTAL MIDDLE BLACK STRIPE
+2700..2704;N # So [5] BLACK SAFETY SCISSORS..WHITE SCISSORS
+2705;W # So WHITE HEAVY CHECK MARK
+2706..2709;N # So [4] TELEPHONE LOCATION SIGN..ENVELOPE
+270A..270B;W # So [2] RAISED FIST..RAISED HAND
+270C..2727;N # So [28] VICTORY HAND..WHITE FOUR POINTED STAR
+2728;W # So SPARKLES
+2729..273C;N # So [20] STRESS OUTLINED WHITE STAR..OPEN CENTRE TEARDROP-SPOKED ASTERISK
+273D;A # So HEAVY TEARDROP-SPOKED ASTERISK
+273E..274B;N # So [14] SIX PETALLED BLACK AND WHITE FLORETTE..HEAVY EIGHT TEARDROP-SPOKED PROPELLER ASTERISK
+274C;W # So CROSS MARK
+274D;N # So SHADOWED WHITE CIRCLE
+274E;W # So NEGATIVE SQUARED CROSS MARK
+274F..2752;N # So [4] LOWER RIGHT DROP-SHADOWED WHITE SQUARE..UPPER RIGHT SHADOWED WHITE SQUARE
+2753..2755;W # So [3] BLACK QUESTION MARK ORNAMENT..WHITE EXCLAMATION MARK ORNAMENT
+2756;N # So BLACK DIAMOND MINUS WHITE X
+2757;W # So HEAVY EXCLAMATION MARK SYMBOL
+2758..2767;N # So [16] LIGHT VERTICAL BAR..ROTATED FLORAL HEART BULLET
+2768;N # Ps MEDIUM LEFT PARENTHESIS ORNAMENT
+2769;N # Pe MEDIUM RIGHT PARENTHESIS ORNAMENT
+276A;N # Ps MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT
+276B;N # Pe MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT
+276C;N # Ps MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT
+276D;N # Pe MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT
+276E;N # Ps HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT
+276F;N # Pe HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT
+2770;N # Ps HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT
+2771;N # Pe HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT
+2772;N # Ps LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT
+2773;N # Pe LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT
+2774;N # Ps MEDIUM LEFT CURLY BRACKET ORNAMENT
+2775;N # Pe MEDIUM RIGHT CURLY BRACKET ORNAMENT
+2776..277F;A # No [10] DINGBAT NEGATIVE CIRCLED DIGIT ONE..DINGBAT NEGATIVE CIRCLED NUMBER TEN
+2780..2793;N # No [20] DINGBAT CIRCLED SANS-SERIF DIGIT ONE..DINGBAT NEGATIVE CIRCLED SANS-SERIF NUMBER TEN
+2794;N # So HEAVY WIDE-HEADED RIGHTWARDS ARROW
+2795..2797;W # So [3] HEAVY PLUS SIGN..HEAVY DIVISION SIGN
+2798..27AF;N # So [24] HEAVY SOUTH EAST ARROW..NOTCHED LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW
+27B0;W # So CURLY LOOP
+27B1..27BE;N # So [14] NOTCHED UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW..OPEN-OUTLINED RIGHTWARDS ARROW
+27BF;W # So DOUBLE CURLY LOOP
+27C0..27C4;N # Sm [5] THREE DIMENSIONAL ANGLE..OPEN SUPERSET
+27C5;N # Ps LEFT S-SHAPED BAG DELIMITER
+27C6;N # Pe RIGHT S-SHAPED BAG DELIMITER
+27C7..27E5;N # Sm [31] OR WITH DOT INSIDE..WHITE SQUARE WITH RIGHTWARDS TICK
+27E6;Na # Ps MATHEMATICAL LEFT WHITE SQUARE BRACKET
+27E7;Na # Pe MATHEMATICAL RIGHT WHITE SQUARE BRACKET
+27E8;Na # Ps MATHEMATICAL LEFT ANGLE BRACKET
+27E9;Na # Pe MATHEMATICAL RIGHT ANGLE BRACKET
+27EA;Na # Ps MATHEMATICAL LEFT DOUBLE ANGLE BRACKET
+27EB;Na # Pe MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET
+27EC;Na # Ps MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET
+27ED;Na # Pe MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET
+27EE;N # Ps MATHEMATICAL LEFT FLATTENED PARENTHESIS
+27EF;N # Pe MATHEMATICAL RIGHT FLATTENED PARENTHESIS
+27F0..27FF;N # Sm [16] UPWARDS QUADRUPLE ARROW..LONG RIGHTWARDS SQUIGGLE ARROW
+2800..28FF;N # So [256] BRAILLE PATTERN BLANK..BRAILLE PATTERN DOTS-12345678
+2900..297F;N # Sm [128] RIGHTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE..DOWN FISH TAIL
+2980..2982;N # Sm [3] TRIPLE VERTICAL BAR DELIMITER..Z NOTATION TYPE COLON
+2983;N # Ps LEFT WHITE CURLY BRACKET
+2984;N # Pe RIGHT WHITE CURLY BRACKET
+2985;Na # Ps LEFT WHITE PARENTHESIS
+2986;Na # Pe RIGHT WHITE PARENTHESIS
+2987;N # Ps Z NOTATION LEFT IMAGE BRACKET
+2988;N # Pe Z NOTATION RIGHT IMAGE BRACKET
+2989;N # Ps Z NOTATION LEFT BINDING BRACKET
+298A;N # Pe Z NOTATION RIGHT BINDING BRACKET
+298B;N # Ps LEFT SQUARE BRACKET WITH UNDERBAR
+298C;N # Pe RIGHT SQUARE BRACKET WITH UNDERBAR
+298D;N # Ps LEFT SQUARE BRACKET WITH TICK IN TOP CORNER
+298E;N # Pe RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER
+298F;N # Ps LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER
+2990;N # Pe RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER
+2991;N # Ps LEFT ANGLE BRACKET WITH DOT
+2992;N # Pe RIGHT ANGLE BRACKET WITH DOT
+2993;N # Ps LEFT ARC LESS-THAN BRACKET
+2994;N # Pe RIGHT ARC GREATER-THAN BRACKET
+2995;N # Ps DOUBLE LEFT ARC GREATER-THAN BRACKET
+2996;N # Pe DOUBLE RIGHT ARC LESS-THAN BRACKET
+2997;N # Ps LEFT BLACK TORTOISE SHELL BRACKET
+2998;N # Pe RIGHT BLACK TORTOISE SHELL BRACKET
+2999..29D7;N # Sm [63] DOTTED FENCE..BLACK HOURGLASS
+29D8;N # Ps LEFT WIGGLY FENCE
+29D9;N # Pe RIGHT WIGGLY FENCE
+29DA;N # Ps LEFT DOUBLE WIGGLY FENCE
+29DB;N # Pe RIGHT DOUBLE WIGGLY FENCE
+29DC..29FB;N # Sm [32] INCOMPLETE INFINITY..TRIPLE PLUS
+29FC;N # Ps LEFT-POINTING CURVED ANGLE BRACKET
+29FD;N # Pe RIGHT-POINTING CURVED ANGLE BRACKET
+29FE..29FF;N # Sm [2] TINY..MINY
+2A00..2AFF;N # Sm [256] N-ARY CIRCLED DOT OPERATOR..N-ARY WHITE VERTICAL BAR
+2B00..2B1A;N # So [27] NORTH EAST WHITE ARROW..DOTTED SQUARE
+2B1B..2B1C;W # So [2] BLACK LARGE SQUARE..WHITE LARGE SQUARE
+2B1D..2B2F;N # So [19] BLACK VERY SMALL SQUARE..WHITE VERTICAL ELLIPSE
+2B30..2B44;N # Sm [21] LEFT ARROW WITH SMALL CIRCLE..RIGHTWARDS ARROW THROUGH SUPERSET
+2B45..2B46;N # So [2] LEFTWARDS QUADRUPLE ARROW..RIGHTWARDS QUADRUPLE ARROW
+2B47..2B4C;N # Sm [6] REVERSE TILDE OPERATOR ABOVE RIGHTWARDS ARROW..RIGHTWARDS ARROW ABOVE REVERSE TILDE OPERATOR
+2B4D..2B4F;N # So [3] DOWNWARDS TRIANGLE-HEADED ZIGZAG ARROW..SHORT BACKSLANTED SOUTH ARROW
+2B50;W # So WHITE MEDIUM STAR
+2B51..2B54;N # So [4] BLACK SMALL STAR..WHITE RIGHT-POINTING PENTAGON
+2B55;W # So HEAVY LARGE CIRCLE
+2B56..2B59;A # So [4] HEAVY OVAL WITH OVAL INSIDE..HEAVY CIRCLED SALTIRE
+2B5A..2B73;N # So [26] SLANTED NORTH ARROW WITH HOOKED HEAD..DOWNWARDS TRIANGLE-HEADED ARROW TO BAR
+2B76..2B95;N # So [32] NORTH WEST TRIANGLE-HEADED ARROW TO BAR..RIGHTWARDS BLACK ARROW
+2B98..2BB9;N # So [34] THREE-D TOP-LIGHTED LEFTWARDS EQUILATERAL ARROWHEAD..UP ARROWHEAD IN A RECTANGLE BOX
+2BBD..2BC8;N # So [12] BALLOT BOX WITH LIGHT X..BLACK MEDIUM RIGHT-POINTING TRIANGLE CENTRED
+2BCA..2BD2;N # So [9] TOP HALF BLACK CIRCLE..GROUP MARK
+2BEC..2BEF;N # So [4] LEFTWARDS TWO-HEADED ARROW WITH TRIANGLE ARROWHEADS..DOWNWARDS TWO-HEADED ARROW WITH TRIANGLE ARROWHEADS
+2C00..2C2E;N # Lu [47] GLAGOLITIC CAPITAL LETTER AZU..GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE
+2C30..2C5E;N # Ll [47] GLAGOLITIC SMALL LETTER AZU..GLAGOLITIC SMALL LETTER LATINATE MYSLITE
+2C60..2C7B;N # L& [28] LATIN CAPITAL LETTER L WITH DOUBLE BAR..LATIN LETTER SMALL CAPITAL TURNED E
+2C7C..2C7D;N # Lm [2] LATIN SUBSCRIPT SMALL LETTER J..MODIFIER LETTER CAPITAL V
+2C7E..2C7F;N # Lu [2] LATIN CAPITAL LETTER S WITH SWASH TAIL..LATIN CAPITAL LETTER Z WITH SWASH TAIL
+2C80..2CE4;N # L& [101] COPTIC CAPITAL LETTER ALFA..COPTIC SYMBOL KAI
+2CE5..2CEA;N # So [6] COPTIC SYMBOL MI RO..COPTIC SYMBOL SHIMA SIMA
+2CEB..2CEE;N # L& [4] COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI..COPTIC SMALL LETTER CRYPTOGRAMMIC GANGIA
+2CEF..2CF1;N # Mn [3] COPTIC COMBINING NI ABOVE..COPTIC COMBINING SPIRITUS LENIS
+2CF2..2CF3;N # L& [2] COPTIC CAPITAL LETTER BOHAIRIC KHEI..COPTIC SMALL LETTER BOHAIRIC KHEI
+2CF9..2CFC;N # Po [4] COPTIC OLD NUBIAN FULL STOP..COPTIC OLD NUBIAN VERSE DIVIDER
+2CFD;N # No COPTIC FRACTION ONE HALF
+2CFE..2CFF;N # Po [2] COPTIC FULL STOP..COPTIC MORPHOLOGICAL DIVIDER
+2D00..2D25;N # Ll [38] GEORGIAN SMALL LETTER AN..GEORGIAN SMALL LETTER HOE
+2D27;N # Ll GEORGIAN SMALL LETTER YN
+2D2D;N # Ll GEORGIAN SMALL LETTER AEN
+2D30..2D67;N # Lo [56] TIFINAGH LETTER YA..TIFINAGH LETTER YO
+2D6F;N # Lm TIFINAGH MODIFIER LETTER LABIALIZATION MARK
+2D70;N # Po TIFINAGH SEPARATOR MARK
+2D7F;N # Mn TIFINAGH CONSONANT JOINER
+2D80..2D96;N # Lo [23] ETHIOPIC SYLLABLE LOA..ETHIOPIC SYLLABLE GGWE
+2DA0..2DA6;N # Lo [7] ETHIOPIC SYLLABLE SSA..ETHIOPIC SYLLABLE SSO
+2DA8..2DAE;N # Lo [7] ETHIOPIC SYLLABLE CCA..ETHIOPIC SYLLABLE CCO
+2DB0..2DB6;N # Lo [7] ETHIOPIC SYLLABLE ZZA..ETHIOPIC SYLLABLE ZZO
+2DB8..2DBE;N # Lo [7] ETHIOPIC SYLLABLE CCHA..ETHIOPIC SYLLABLE CCHO
+2DC0..2DC6;N # Lo [7] ETHIOPIC SYLLABLE QYA..ETHIOPIC SYLLABLE QYO
+2DC8..2DCE;N # Lo [7] ETHIOPIC SYLLABLE KYA..ETHIOPIC SYLLABLE KYO
+2DD0..2DD6;N # Lo [7] ETHIOPIC SYLLABLE XYA..ETHIOPIC SYLLABLE XYO
+2DD8..2DDE;N # Lo [7] ETHIOPIC SYLLABLE GYA..ETHIOPIC SYLLABLE GYO
+2DE0..2DFF;N # Mn [32] COMBINING CYRILLIC LETTER BE..COMBINING CYRILLIC LETTER IOTIFIED BIG YUS
+2E00..2E01;N # Po [2] RIGHT ANGLE SUBSTITUTION MARKER..RIGHT ANGLE DOTTED SUBSTITUTION MARKER
+2E02;N # Pi LEFT SUBSTITUTION BRACKET
+2E03;N # Pf RIGHT SUBSTITUTION BRACKET
+2E04;N # Pi LEFT DOTTED SUBSTITUTION BRACKET
+2E05;N # Pf RIGHT DOTTED SUBSTITUTION BRACKET
+2E06..2E08;N # Po [3] RAISED INTERPOLATION MARKER..DOTTED TRANSPOSITION MARKER
+2E09;N # Pi LEFT TRANSPOSITION BRACKET
+2E0A;N # Pf RIGHT TRANSPOSITION BRACKET
+2E0B;N # Po RAISED SQUARE
+2E0C;N # Pi LEFT RAISED OMISSION BRACKET
+2E0D;N # Pf RIGHT RAISED OMISSION BRACKET
+2E0E..2E16;N # Po [9] EDITORIAL CORONIS..DOTTED RIGHT-POINTING ANGLE
+2E17;N # Pd DOUBLE OBLIQUE HYPHEN
+2E18..2E19;N # Po [2] INVERTED INTERROBANG..PALM BRANCH
+2E1A;N # Pd HYPHEN WITH DIAERESIS
+2E1B;N # Po TILDE WITH RING ABOVE
+2E1C;N # Pi LEFT LOW PARAPHRASE BRACKET
+2E1D;N # Pf RIGHT LOW PARAPHRASE BRACKET
+2E1E..2E1F;N # Po [2] TILDE WITH DOT ABOVE..TILDE WITH DOT BELOW
+2E20;N # Pi LEFT VERTICAL BAR WITH QUILL
+2E21;N # Pf RIGHT VERTICAL BAR WITH QUILL
+2E22;N # Ps TOP LEFT HALF BRACKET
+2E23;N # Pe TOP RIGHT HALF BRACKET
+2E24;N # Ps BOTTOM LEFT HALF BRACKET
+2E25;N # Pe BOTTOM RIGHT HALF BRACKET
+2E26;N # Ps LEFT SIDEWAYS U BRACKET
+2E27;N # Pe RIGHT SIDEWAYS U BRACKET
+2E28;N # Ps LEFT DOUBLE PARENTHESIS
+2E29;N # Pe RIGHT DOUBLE PARENTHESIS
+2E2A..2E2E;N # Po [5] TWO DOTS OVER ONE DOT PUNCTUATION..REVERSED QUESTION MARK
+2E2F;N # Lm VERTICAL TILDE
+2E30..2E39;N # Po [10] RING POINT..TOP HALF SECTION SIGN
+2E3A..2E3B;N # Pd [2] TWO-EM DASH..THREE-EM DASH
+2E3C..2E3F;N # Po [4] STENOGRAPHIC FULL STOP..CAPITULUM
+2E40;N # Pd DOUBLE HYPHEN
+2E41;N # Po REVERSED COMMA
+2E42;N # Ps DOUBLE LOW-REVERSED-9 QUOTATION MARK
+2E43..2E49;N # Po [7] DASH WITH LEFT UPTURN..DOUBLE STACKED COMMA
+2E80..2E99;W # So [26] CJK RADICAL REPEAT..CJK RADICAL RAP
+2E9B..2EF3;W # So [89] CJK RADICAL CHOKE..CJK RADICAL C-SIMPLIFIED TURTLE
+2F00..2FD5;W # So [214] KANGXI RADICAL ONE..KANGXI RADICAL FLUTE
+2FF0..2FFB;W # So [12] IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO RIGHT..IDEOGRAPHIC DESCRIPTION CHARACTER OVERLAID
+3000;F # Zs IDEOGRAPHIC SPACE
+3001..3003;W # Po [3] IDEOGRAPHIC COMMA..DITTO MARK
+3004;W # So JAPANESE INDUSTRIAL STANDARD SYMBOL
+3005;W # Lm IDEOGRAPHIC ITERATION MARK
+3006;W # Lo IDEOGRAPHIC CLOSING MARK
+3007;W # Nl IDEOGRAPHIC NUMBER ZERO
+3008;W # Ps LEFT ANGLE BRACKET
+3009;W # Pe RIGHT ANGLE BRACKET
+300A;W # Ps LEFT DOUBLE ANGLE BRACKET
+300B;W # Pe RIGHT DOUBLE ANGLE BRACKET
+300C;W # Ps LEFT CORNER BRACKET
+300D;W # Pe RIGHT CORNER BRACKET
+300E;W # Ps LEFT WHITE CORNER BRACKET
+300F;W # Pe RIGHT WHITE CORNER BRACKET
+3010;W # Ps LEFT BLACK LENTICULAR BRACKET
+3011;W # Pe RIGHT BLACK LENTICULAR BRACKET
+3012..3013;W # So [2] POSTAL MARK..GETA MARK
+3014;W # Ps LEFT TORTOISE SHELL BRACKET
+3015;W # Pe RIGHT TORTOISE SHELL BRACKET
+3016;W # Ps LEFT WHITE LENTICULAR BRACKET
+3017;W # Pe RIGHT WHITE LENTICULAR BRACKET
+3018;W # Ps LEFT WHITE TORTOISE SHELL BRACKET
+3019;W # Pe RIGHT WHITE TORTOISE SHELL BRACKET
+301A;W # Ps LEFT WHITE SQUARE BRACKET
+301B;W # Pe RIGHT WHITE SQUARE BRACKET
+301C;W # Pd WAVE DASH
+301D;W # Ps REVERSED DOUBLE PRIME QUOTATION MARK
+301E..301F;W # Pe [2] DOUBLE PRIME QUOTATION MARK..LOW DOUBLE PRIME QUOTATION MARK
+3020;W # So POSTAL MARK FACE
+3021..3029;W # Nl [9] HANGZHOU NUMERAL ONE..HANGZHOU NUMERAL NINE
+302A..302D;W # Mn [4] IDEOGRAPHIC LEVEL TONE MARK..IDEOGRAPHIC ENTERING TONE MARK
+302E..302F;W # Mc [2] HANGUL SINGLE DOT TONE MARK..HANGUL DOUBLE DOT TONE MARK
+3030;W # Pd WAVY DASH
+3031..3035;W # Lm [5] VERTICAL KANA REPEAT MARK..VERTICAL KANA REPEAT MARK LOWER HALF
+3036..3037;W # So [2] CIRCLED POSTAL MARK..IDEOGRAPHIC TELEGRAPH LINE FEED SEPARATOR SYMBOL
+3038..303A;W # Nl [3] HANGZHOU NUMERAL TEN..HANGZHOU NUMERAL THIRTY
+303B;W # Lm VERTICAL IDEOGRAPHIC ITERATION MARK
+303C;W # Lo MASU MARK
+303D;W # Po PART ALTERNATION MARK
+303E;W # So IDEOGRAPHIC VARIATION INDICATOR
+303F;N # So IDEOGRAPHIC HALF FILL SPACE
+3041..3096;W # Lo [86] HIRAGANA LETTER SMALL A..HIRAGANA LETTER SMALL KE
+3099..309A;W # Mn [2] COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK..COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
+309B..309C;W # Sk [2] KATAKANA-HIRAGANA VOICED SOUND MARK..KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
+309D..309E;W # Lm [2] HIRAGANA ITERATION MARK..HIRAGANA VOICED ITERATION MARK
+309F;W # Lo HIRAGANA DIGRAPH YORI
+30A0;W # Pd KATAKANA-HIRAGANA DOUBLE HYPHEN
+30A1..30FA;W # Lo [90] KATAKANA LETTER SMALL A..KATAKANA LETTER VO
+30FB;W # Po KATAKANA MIDDLE DOT
+30FC..30FE;W # Lm [3] KATAKANA-HIRAGANA PROLONGED SOUND MARK..KATAKANA VOICED ITERATION MARK
+30FF;W # Lo KATAKANA DIGRAPH KOTO
+3105..312E;W # Lo [42] BOPOMOFO LETTER B..BOPOMOFO LETTER O WITH DOT ABOVE
+3131..318E;W # Lo [94] HANGUL LETTER KIYEOK..HANGUL LETTER ARAEAE
+3190..3191;W # So [2] IDEOGRAPHIC ANNOTATION LINKING MARK..IDEOGRAPHIC ANNOTATION REVERSE MARK
+3192..3195;W # No [4] IDEOGRAPHIC ANNOTATION ONE MARK..IDEOGRAPHIC ANNOTATION FOUR MARK
+3196..319F;W # So [10] IDEOGRAPHIC ANNOTATION TOP MARK..IDEOGRAPHIC ANNOTATION MAN MARK
+31A0..31BA;W # Lo [27] BOPOMOFO LETTER BU..BOPOMOFO LETTER ZY
+31C0..31E3;W # So [36] CJK STROKE T..CJK STROKE Q
+31F0..31FF;W # Lo [16] KATAKANA LETTER SMALL KU..KATAKANA LETTER SMALL RO
+3200..321E;W # So [31] PARENTHESIZED HANGUL KIYEOK..PARENTHESIZED KOREAN CHARACTER O HU
+3220..3229;W # No [10] PARENTHESIZED IDEOGRAPH ONE..PARENTHESIZED IDEOGRAPH TEN
+322A..3247;W # So [30] PARENTHESIZED IDEOGRAPH MOON..CIRCLED IDEOGRAPH KOTO
+3248..324F;A # No [8] CIRCLED NUMBER TEN ON BLACK SQUARE..CIRCLED NUMBER EIGHTY ON BLACK SQUARE
+3250;W # So PARTNERSHIP SIGN
+3251..325F;W # No [15] CIRCLED NUMBER TWENTY ONE..CIRCLED NUMBER THIRTY FIVE
+3260..327F;W # So [32] CIRCLED HANGUL KIYEOK..KOREAN STANDARD SYMBOL
+3280..3289;W # No [10] CIRCLED IDEOGRAPH ONE..CIRCLED IDEOGRAPH TEN
+328A..32B0;W # So [39] CIRCLED IDEOGRAPH MOON..CIRCLED IDEOGRAPH NIGHT
+32B1..32BF;W # No [15] CIRCLED NUMBER THIRTY SIX..CIRCLED NUMBER FIFTY
+32C0..32FE;W # So [63] IDEOGRAPHIC TELEGRAPH SYMBOL FOR JANUARY..CIRCLED KATAKANA WO
+3300..33FF;W # So [256] SQUARE APAATO..SQUARE GAL
+3400..4DB5;W # Lo [6582] CJK UNIFIED IDEOGRAPH-3400..CJK UNIFIED IDEOGRAPH-4DB5
+4DB6..4DBF;W # Cn [10] <reserved-4DB6>..<reserved-4DBF>
+4DC0..4DFF;N # So [64] HEXAGRAM FOR THE CREATIVE HEAVEN..HEXAGRAM FOR BEFORE COMPLETION
+4E00..9FEA;W # Lo [20971] CJK UNIFIED IDEOGRAPH-4E00..CJK UNIFIED IDEOGRAPH-9FEA
+9FEB..9FFF;W # Cn [21] <reserved-9FEB>..<reserved-9FFF>
+A000..A014;W # Lo [21] YI SYLLABLE IT..YI SYLLABLE E
+A015;W # Lm YI SYLLABLE WU
+A016..A48C;W # Lo [1143] YI SYLLABLE BIT..YI SYLLABLE YYR
+A490..A4C6;W # So [55] YI RADICAL QOT..YI RADICAL KE
+A4D0..A4F7;N # Lo [40] LISU LETTER BA..LISU LETTER OE
+A4F8..A4FD;N # Lm [6] LISU LETTER TONE MYA TI..LISU LETTER TONE MYA JEU
+A4FE..A4FF;N # Po [2] LISU PUNCTUATION COMMA..LISU PUNCTUATION FULL STOP
+A500..A60B;N # Lo [268] VAI SYLLABLE EE..VAI SYLLABLE NG
+A60C;N # Lm VAI SYLLABLE LENGTHENER
+A60D..A60F;N # Po [3] VAI COMMA..VAI QUESTION MARK
+A610..A61F;N # Lo [16] VAI SYLLABLE NDOLE FA..VAI SYMBOL JONG
+A620..A629;N # Nd [10] VAI DIGIT ZERO..VAI DIGIT NINE
+A62A..A62B;N # Lo [2] VAI SYLLABLE NDOLE MA..VAI SYLLABLE NDOLE DO
+A640..A66D;N # L& [46] CYRILLIC CAPITAL LETTER ZEMLYA..CYRILLIC SMALL LETTER DOUBLE MONOCULAR O
+A66E;N # Lo CYRILLIC LETTER MULTIOCULAR O
+A66F;N # Mn COMBINING CYRILLIC VZMET
+A670..A672;N # Me [3] COMBINING CYRILLIC TEN MILLIONS SIGN..COMBINING CYRILLIC THOUSAND MILLIONS SIGN
+A673;N # Po SLAVONIC ASTERISK
+A674..A67D;N # Mn [10] COMBINING CYRILLIC LETTER UKRAINIAN IE..COMBINING CYRILLIC PAYEROK
+A67E;N # Po CYRILLIC KAVYKA
+A67F;N # Lm CYRILLIC PAYEROK
+A680..A69B;N # L& [28] CYRILLIC CAPITAL LETTER DWE..CYRILLIC SMALL LETTER CROSSED O
+A69C..A69D;N # Lm [2] MODIFIER LETTER CYRILLIC HARD SIGN..MODIFIER LETTER CYRILLIC SOFT SIGN
+A69E..A69F;N # Mn [2] COMBINING CYRILLIC LETTER EF..COMBINING CYRILLIC LETTER IOTIFIED E
+A6A0..A6E5;N # Lo [70] BAMUM LETTER A..BAMUM LETTER KI
+A6E6..A6EF;N # Nl [10] BAMUM LETTER MO..BAMUM LETTER KOGHOM
+A6F0..A6F1;N # Mn [2] BAMUM COMBINING MARK KOQNDON..BAMUM COMBINING MARK TUKWENTIS
+A6F2..A6F7;N # Po [6] BAMUM NJAEMLI..BAMUM QUESTION MARK
+A700..A716;N # Sk [23] MODIFIER LETTER CHINESE TONE YIN PING..MODIFIER LETTER EXTRA-LOW LEFT-STEM TONE BAR
+A717..A71F;N # Lm [9] MODIFIER LETTER DOT VERTICAL BAR..MODIFIER LETTER LOW INVERTED EXCLAMATION MARK
+A720..A721;N # Sk [2] MODIFIER LETTER STRESS AND HIGH TONE..MODIFIER LETTER STRESS AND LOW TONE
+A722..A76F;N # L& [78] LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF..LATIN SMALL LETTER CON
+A770;N # Lm MODIFIER LETTER US
+A771..A787;N # L& [23] LATIN SMALL LETTER DUM..LATIN SMALL LETTER INSULAR T
+A788;N # Lm MODIFIER LETTER LOW CIRCUMFLEX ACCENT
+A789..A78A;N # Sk [2] MODIFIER LETTER COLON..MODIFIER LETTER SHORT EQUALS SIGN
+A78B..A78E;N # L& [4] LATIN CAPITAL LETTER SALTILLO..LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT
+A78F;N # Lo LATIN LETTER SINOLOGICAL DOT
+A790..A7AE;N # L& [31] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN CAPITAL LETTER SMALL CAPITAL I
+A7B0..A7B7;N # L& [8] LATIN CAPITAL LETTER TURNED K..LATIN SMALL LETTER OMEGA
+A7F7;N # Lo LATIN EPIGRAPHIC LETTER SIDEWAYS I
+A7F8..A7F9;N # Lm [2] MODIFIER LETTER CAPITAL H WITH STROKE..MODIFIER LETTER SMALL LIGATURE OE
+A7FA;N # Ll LATIN LETTER SMALL CAPITAL TURNED M
+A7FB..A7FF;N # Lo [5] LATIN EPIGRAPHIC LETTER REVERSED F..LATIN EPIGRAPHIC LETTER ARCHAIC M
+A800..A801;N # Lo [2] SYLOTI NAGRI LETTER A..SYLOTI NAGRI LETTER I
+A802;N # Mn SYLOTI NAGRI SIGN DVISVARA
+A803..A805;N # Lo [3] SYLOTI NAGRI LETTER U..SYLOTI NAGRI LETTER O
+A806;N # Mn SYLOTI NAGRI SIGN HASANTA
+A807..A80A;N # Lo [4] SYLOTI NAGRI LETTER KO..SYLOTI NAGRI LETTER GHO
+A80B;N # Mn SYLOTI NAGRI SIGN ANUSVARA
+A80C..A822;N # Lo [23] SYLOTI NAGRI LETTER CO..SYLOTI NAGRI LETTER HO
+A823..A824;N # Mc [2] SYLOTI NAGRI VOWEL SIGN A..SYLOTI NAGRI VOWEL SIGN I
+A825..A826;N # Mn [2] SYLOTI NAGRI VOWEL SIGN U..SYLOTI NAGRI VOWEL SIGN E
+A827;N # Mc SYLOTI NAGRI VOWEL SIGN OO
+A828..A82B;N # So [4] SYLOTI NAGRI POETRY MARK-1..SYLOTI NAGRI POETRY MARK-4
+A830..A835;N # No [6] NORTH INDIC FRACTION ONE QUARTER..NORTH INDIC FRACTION THREE SIXTEENTHS
+A836..A837;N # So [2] NORTH INDIC QUARTER MARK..NORTH INDIC PLACEHOLDER MARK
+A838;N # Sc NORTH INDIC RUPEE MARK
+A839;N # So NORTH INDIC QUANTITY MARK
+A840..A873;N # Lo [52] PHAGS-PA LETTER KA..PHAGS-PA LETTER CANDRABINDU
+A874..A877;N # Po [4] PHAGS-PA SINGLE HEAD MARK..PHAGS-PA MARK DOUBLE SHAD
+A880..A881;N # Mc [2] SAURASHTRA SIGN ANUSVARA..SAURASHTRA SIGN VISARGA
+A882..A8B3;N # Lo [50] SAURASHTRA LETTER A..SAURASHTRA LETTER LLA
+A8B4..A8C3;N # Mc [16] SAURASHTRA CONSONANT SIGN HAARU..SAURASHTRA VOWEL SIGN AU
+A8C4..A8C5;N # Mn [2] SAURASHTRA SIGN VIRAMA..SAURASHTRA SIGN CANDRABINDU
+A8CE..A8CF;N # Po [2] SAURASHTRA DANDA..SAURASHTRA DOUBLE DANDA
+A8D0..A8D9;N # Nd [10] SAURASHTRA DIGIT ZERO..SAURASHTRA DIGIT NINE
+A8E0..A8F1;N # Mn [18] COMBINING DEVANAGARI DIGIT ZERO..COMBINING DEVANAGARI SIGN AVAGRAHA
+A8F2..A8F7;N # Lo [6] DEVANAGARI SIGN SPACING CANDRABINDU..DEVANAGARI SIGN CANDRABINDU AVAGRAHA
+A8F8..A8FA;N # Po [3] DEVANAGARI SIGN PUSHPIKA..DEVANAGARI CARET
+A8FB;N # Lo DEVANAGARI HEADSTROKE
+A8FC;N # Po DEVANAGARI SIGN SIDDHAM
+A8FD;N # Lo DEVANAGARI JAIN OM
+A900..A909;N # Nd [10] KAYAH LI DIGIT ZERO..KAYAH LI DIGIT NINE
+A90A..A925;N # Lo [28] KAYAH LI LETTER KA..KAYAH LI LETTER OO
+A926..A92D;N # Mn [8] KAYAH LI VOWEL UE..KAYAH LI TONE CALYA PLOPHU
+A92E..A92F;N # Po [2] KAYAH LI SIGN CWI..KAYAH LI SIGN SHYA
+A930..A946;N # Lo [23] REJANG LETTER KA..REJANG LETTER A
+A947..A951;N # Mn [11] REJANG VOWEL SIGN I..REJANG CONSONANT SIGN R
+A952..A953;N # Mc [2] REJANG CONSONANT SIGN H..REJANG VIRAMA
+A95F;N # Po REJANG SECTION MARK
+A960..A97C;W # Lo [29] HANGUL CHOSEONG TIKEUT-MIEUM..HANGUL CHOSEONG SSANGYEORINHIEUH
+A980..A982;N # Mn [3] JAVANESE SIGN PANYANGGA..JAVANESE SIGN LAYAR
+A983;N # Mc JAVANESE SIGN WIGNYAN
+A984..A9B2;N # Lo [47] JAVANESE LETTER A..JAVANESE LETTER HA
+A9B3;N # Mn JAVANESE SIGN CECAK TELU
+A9B4..A9B5;N # Mc [2] JAVANESE VOWEL SIGN TARUNG..JAVANESE VOWEL SIGN TOLONG
+A9B6..A9B9;N # Mn [4] JAVANESE VOWEL SIGN WULU..JAVANESE VOWEL SIGN SUKU MENDUT
+A9BA..A9BB;N # Mc [2] JAVANESE VOWEL SIGN TALING..JAVANESE VOWEL SIGN DIRGA MURE
+A9BC;N # Mn JAVANESE VOWEL SIGN PEPET
+A9BD..A9C0;N # Mc [4] JAVANESE CONSONANT SIGN KERET..JAVANESE PANGKON
+A9C1..A9CD;N # Po [13] JAVANESE LEFT RERENGGAN..JAVANESE TURNED PADA PISELEH
+A9CF;N # Lm JAVANESE PANGRANGKEP
+A9D0..A9D9;N # Nd [10] JAVANESE DIGIT ZERO..JAVANESE DIGIT NINE
+A9DE..A9DF;N # Po [2] JAVANESE PADA TIRTA TUMETES..JAVANESE PADA ISEN-ISEN
+A9E0..A9E4;N # Lo [5] MYANMAR LETTER SHAN GHA..MYANMAR LETTER SHAN BHA
+A9E5;N # Mn MYANMAR SIGN SHAN SAW
+A9E6;N # Lm MYANMAR MODIFIER LETTER SHAN REDUPLICATION
+A9E7..A9EF;N # Lo [9] MYANMAR LETTER TAI LAING NYA..MYANMAR LETTER TAI LAING NNA
+A9F0..A9F9;N # Nd [10] MYANMAR TAI LAING DIGIT ZERO..MYANMAR TAI LAING DIGIT NINE
+A9FA..A9FE;N # Lo [5] MYANMAR LETTER TAI LAING LLA..MYANMAR LETTER TAI LAING BHA
+AA00..AA28;N # Lo [41] CHAM LETTER A..CHAM LETTER HA
+AA29..AA2E;N # Mn [6] CHAM VOWEL SIGN AA..CHAM VOWEL SIGN OE
+AA2F..AA30;N # Mc [2] CHAM VOWEL SIGN O..CHAM VOWEL SIGN AI
+AA31..AA32;N # Mn [2] CHAM VOWEL SIGN AU..CHAM VOWEL SIGN UE
+AA33..AA34;N # Mc [2] CHAM CONSONANT SIGN YA..CHAM CONSONANT SIGN RA
+AA35..AA36;N # Mn [2] CHAM CONSONANT SIGN LA..CHAM CONSONANT SIGN WA
+AA40..AA42;N # Lo [3] CHAM LETTER FINAL K..CHAM LETTER FINAL NG
+AA43;N # Mn CHAM CONSONANT SIGN FINAL NG
+AA44..AA4B;N # Lo [8] CHAM LETTER FINAL CH..CHAM LETTER FINAL SS
+AA4C;N # Mn CHAM CONSONANT SIGN FINAL M
+AA4D;N # Mc CHAM CONSONANT SIGN FINAL H
+AA50..AA59;N # Nd [10] CHAM DIGIT ZERO..CHAM DIGIT NINE
+AA5C..AA5F;N # Po [4] CHAM PUNCTUATION SPIRAL..CHAM PUNCTUATION TRIPLE DANDA
+AA60..AA6F;N # Lo [16] MYANMAR LETTER KHAMTI GA..MYANMAR LETTER KHAMTI FA
+AA70;N # Lm MYANMAR MODIFIER LETTER KHAMTI REDUPLICATION
+AA71..AA76;N # Lo [6] MYANMAR LETTER KHAMTI XA..MYANMAR LOGOGRAM KHAMTI HM
+AA77..AA79;N # So [3] MYANMAR SYMBOL AITON EXCLAMATION..MYANMAR SYMBOL AITON TWO
+AA7A;N # Lo MYANMAR LETTER AITON RA
+AA7B;N # Mc MYANMAR SIGN PAO KAREN TONE
+AA7C;N # Mn MYANMAR SIGN TAI LAING TONE-2
+AA7D;N # Mc MYANMAR SIGN TAI LAING TONE-5
+AA7E..AA7F;N # Lo [2] MYANMAR LETTER SHWE PALAUNG CHA..MYANMAR LETTER SHWE PALAUNG SHA
+AA80..AAAF;N # Lo [48] TAI VIET LETTER LOW KO..TAI VIET LETTER HIGH O
+AAB0;N # Mn TAI VIET MAI KANG
+AAB1;N # Lo TAI VIET VOWEL AA
+AAB2..AAB4;N # Mn [3] TAI VIET VOWEL I..TAI VIET VOWEL U
+AAB5..AAB6;N # Lo [2] TAI VIET VOWEL E..TAI VIET VOWEL O
+AAB7..AAB8;N # Mn [2] TAI VIET MAI KHIT..TAI VIET VOWEL IA
+AAB9..AABD;N # Lo [5] TAI VIET VOWEL UEA..TAI VIET VOWEL AN
+AABE..AABF;N # Mn [2] TAI VIET VOWEL AM..TAI VIET TONE MAI EK
+AAC0;N # Lo TAI VIET TONE MAI NUENG
+AAC1;N # Mn TAI VIET TONE MAI THO
+AAC2;N # Lo TAI VIET TONE MAI SONG
+AADB..AADC;N # Lo [2] TAI VIET SYMBOL KON..TAI VIET SYMBOL NUENG
+AADD;N # Lm TAI VIET SYMBOL SAM
+AADE..AADF;N # Po [2] TAI VIET SYMBOL HO HOI..TAI VIET SYMBOL KOI KOI
+AAE0..AAEA;N # Lo [11] MEETEI MAYEK LETTER E..MEETEI MAYEK LETTER SSA
+AAEB;N # Mc MEETEI MAYEK VOWEL SIGN II
+AAEC..AAED;N # Mn [2] MEETEI MAYEK VOWEL SIGN UU..MEETEI MAYEK VOWEL SIGN AAI
+AAEE..AAEF;N # Mc [2] MEETEI MAYEK VOWEL SIGN AU..MEETEI MAYEK VOWEL SIGN AAU
+AAF0..AAF1;N # Po [2] MEETEI MAYEK CHEIKHAN..MEETEI MAYEK AHANG KHUDAM
+AAF2;N # Lo MEETEI MAYEK ANJI
+AAF3..AAF4;N # Lm [2] MEETEI MAYEK SYLLABLE REPETITION MARK..MEETEI MAYEK WORD REPETITION MARK
+AAF5;N # Mc MEETEI MAYEK VOWEL SIGN VISARGA
+AAF6;N # Mn MEETEI MAYEK VIRAMA
+AB01..AB06;N # Lo [6] ETHIOPIC SYLLABLE TTHU..ETHIOPIC SYLLABLE TTHO
+AB09..AB0E;N # Lo [6] ETHIOPIC SYLLABLE DDHU..ETHIOPIC SYLLABLE DDHO
+AB11..AB16;N # Lo [6] ETHIOPIC SYLLABLE DZU..ETHIOPIC SYLLABLE DZO
+AB20..AB26;N # Lo [7] ETHIOPIC SYLLABLE CCHHA..ETHIOPIC SYLLABLE CCHHO
+AB28..AB2E;N # Lo [7] ETHIOPIC SYLLABLE BBA..ETHIOPIC SYLLABLE BBO
+AB30..AB5A;N # Ll [43] LATIN SMALL LETTER BARRED ALPHA..LATIN SMALL LETTER Y WITH SHORT RIGHT LEG
+AB5B;N # Sk MODIFIER BREVE WITH INVERTED BREVE
+AB5C..AB5F;N # Lm [4] MODIFIER LETTER SMALL HENG..MODIFIER LETTER SMALL U WITH LEFT HOOK
+AB60..AB65;N # Ll [6] LATIN SMALL LETTER SAKHA YAT..GREEK LETTER SMALL CAPITAL OMEGA
+AB70..ABBF;N # Ll [80] CHEROKEE SMALL LETTER A..CHEROKEE SMALL LETTER YA
+ABC0..ABE2;N # Lo [35] MEETEI MAYEK LETTER KOK..MEETEI MAYEK LETTER I LONSUM
+ABE3..ABE4;N # Mc [2] MEETEI MAYEK VOWEL SIGN ONAP..MEETEI MAYEK VOWEL SIGN INAP
+ABE5;N # Mn MEETEI MAYEK VOWEL SIGN ANAP
+ABE6..ABE7;N # Mc [2] MEETEI MAYEK VOWEL SIGN YENAP..MEETEI MAYEK VOWEL SIGN SOUNAP
+ABE8;N # Mn MEETEI MAYEK VOWEL SIGN UNAP
+ABE9..ABEA;N # Mc [2] MEETEI MAYEK VOWEL SIGN CHEINAP..MEETEI MAYEK VOWEL SIGN NUNG
+ABEB;N # Po MEETEI MAYEK CHEIKHEI
+ABEC;N # Mc MEETEI MAYEK LUM IYEK
+ABED;N # Mn MEETEI MAYEK APUN IYEK
+ABF0..ABF9;N # Nd [10] MEETEI MAYEK DIGIT ZERO..MEETEI MAYEK DIGIT NINE
+AC00..D7A3;W # Lo [11172] HANGUL SYLLABLE GA..HANGUL SYLLABLE HIH
+D7B0..D7C6;N # Lo [23] HANGUL JUNGSEONG O-YEO..HANGUL JUNGSEONG ARAEA-E
+D7CB..D7FB;N # Lo [49] HANGUL JONGSEONG NIEUN-RIEUL..HANGUL JONGSEONG PHIEUPH-THIEUTH
+D800..DB7F;N # Cs [896] <surrogate-D800>..<surrogate-DB7F>
+DB80..DBFF;N # Cs [128] <surrogate-DB80>..<surrogate-DBFF>
+DC00..DFFF;N # Cs [1024] <surrogate-DC00>..<surrogate-DFFF>
+E000..F8FF;A # Co [6400] <private-use-E000>..<private-use-F8FF>
+F900..FA6D;W # Lo [366] CJK COMPATIBILITY IDEOGRAPH-F900..CJK COMPATIBILITY IDEOGRAPH-FA6D
+FA6E..FA6F;W # Cn [2] <reserved-FA6E>..<reserved-FA6F>
+FA70..FAD9;W # Lo [106] CJK COMPATIBILITY IDEOGRAPH-FA70..CJK COMPATIBILITY IDEOGRAPH-FAD9
+FADA..FAFF;W # Cn [38] <reserved-FADA>..<reserved-FAFF>
+FB00..FB06;N # Ll [7] LATIN SMALL LIGATURE FF..LATIN SMALL LIGATURE ST
+FB13..FB17;N # Ll [5] ARMENIAN SMALL LIGATURE MEN NOW..ARMENIAN SMALL LIGATURE MEN XEH
+FB1D;N # Lo HEBREW LETTER YOD WITH HIRIQ
+FB1E;N # Mn HEBREW POINT JUDEO-SPANISH VARIKA
+FB1F..FB28;N # Lo [10] HEBREW LIGATURE YIDDISH YOD YOD PATAH..HEBREW LETTER WIDE TAV
+FB29;N # Sm HEBREW LETTER ALTERNATIVE PLUS SIGN
+FB2A..FB36;N # Lo [13] HEBREW LETTER SHIN WITH SHIN DOT..HEBREW LETTER ZAYIN WITH DAGESH
+FB38..FB3C;N # Lo [5] HEBREW LETTER TET WITH DAGESH..HEBREW LETTER LAMED WITH DAGESH
+FB3E;N # Lo HEBREW LETTER MEM WITH DAGESH
+FB40..FB41;N # Lo [2] HEBREW LETTER NUN WITH DAGESH..HEBREW LETTER SAMEKH WITH DAGESH
+FB43..FB44;N # Lo [2] HEBREW LETTER FINAL PE WITH DAGESH..HEBREW LETTER PE WITH DAGESH
+FB46..FB4F;N # Lo [10] HEBREW LETTER TSADI WITH DAGESH..HEBREW LIGATURE ALEF LAMED
+FB50..FBB1;N # Lo [98] ARABIC LETTER ALEF WASLA ISOLATED FORM..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE FINAL FORM
+FBB2..FBC1;N # Sk [16] ARABIC SYMBOL DOT ABOVE..ARABIC SYMBOL SMALL TAH BELOW
+FBD3..FD3D;N # Lo [363] ARABIC LETTER NG ISOLATED FORM..ARABIC LIGATURE ALEF WITH FATHATAN ISOLATED FORM
+FD3E;N # Pe ORNATE LEFT PARENTHESIS
+FD3F;N # Ps ORNATE RIGHT PARENTHESIS
+FD50..FD8F;N # Lo [64] ARABIC LIGATURE TEH WITH JEEM WITH MEEM INITIAL FORM..ARABIC LIGATURE MEEM WITH KHAH WITH MEEM INITIAL FORM
+FD92..FDC7;N # Lo [54] ARABIC LIGATURE MEEM WITH JEEM WITH KHAH INITIAL FORM..ARABIC LIGATURE NOON WITH JEEM WITH YEH FINAL FORM
+FDF0..FDFB;N # Lo [12] ARABIC LIGATURE SALLA USED AS KORANIC STOP SIGN ISOLATED FORM..ARABIC LIGATURE JALLAJALALOUHOU
+FDFC;N # Sc RIAL SIGN
+FDFD;N # So ARABIC LIGATURE BISMILLAH AR-RAHMAN AR-RAHEEM
+FE00..FE0F;A # Mn [16] VARIATION SELECTOR-1..VARIATION SELECTOR-16
+FE10..FE16;W # Po [7] PRESENTATION FORM FOR VERTICAL COMMA..PRESENTATION FORM FOR VERTICAL QUESTION MARK
+FE17;W # Ps PRESENTATION FORM FOR VERTICAL LEFT WHITE LENTICULAR BRACKET
+FE18;W # Pe PRESENTATION FORM FOR VERTICAL RIGHT WHITE LENTICULAR BRAKCET
+FE19;W # Po PRESENTATION FORM FOR VERTICAL HORIZONTAL ELLIPSIS
+FE20..FE2F;N # Mn [16] COMBINING LIGATURE LEFT HALF..COMBINING CYRILLIC TITLO RIGHT HALF
+FE30;W # Po PRESENTATION FORM FOR VERTICAL TWO DOT LEADER
+FE31..FE32;W # Pd [2] PRESENTATION FORM FOR VERTICAL EM DASH..PRESENTATION FORM FOR VERTICAL EN DASH
+FE33..FE34;W # Pc [2] PRESENTATION FORM FOR VERTICAL LOW LINE..PRESENTATION FORM FOR VERTICAL WAVY LOW LINE
+FE35;W # Ps PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS
+FE36;W # Pe PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS
+FE37;W # Ps PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET
+FE38;W # Pe PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET
+FE39;W # Ps PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET
+FE3A;W # Pe PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET
+FE3B;W # Ps PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET
+FE3C;W # Pe PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET
+FE3D;W # Ps PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET
+FE3E;W # Pe PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET
+FE3F;W # Ps PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET
+FE40;W # Pe PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET
+FE41;W # Ps PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET
+FE42;W # Pe PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET
+FE43;W # Ps PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET
+FE44;W # Pe PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET
+FE45..FE46;W # Po [2] SESAME DOT..WHITE SESAME DOT
+FE47;W # Ps PRESENTATION FORM FOR VERTICAL LEFT SQUARE BRACKET
+FE48;W # Pe PRESENTATION FORM FOR VERTICAL RIGHT SQUARE BRACKET
+FE49..FE4C;W # Po [4] DASHED OVERLINE..DOUBLE WAVY OVERLINE
+FE4D..FE4F;W # Pc [3] DASHED LOW LINE..WAVY LOW LINE
+FE50..FE52;W # Po [3] SMALL COMMA..SMALL FULL STOP
+FE54..FE57;W # Po [4] SMALL SEMICOLON..SMALL EXCLAMATION MARK
+FE58;W # Pd SMALL EM DASH
+FE59;W # Ps SMALL LEFT PARENTHESIS
+FE5A;W # Pe SMALL RIGHT PARENTHESIS
+FE5B;W # Ps SMALL LEFT CURLY BRACKET
+FE5C;W # Pe SMALL RIGHT CURLY BRACKET
+FE5D;W # Ps SMALL LEFT TORTOISE SHELL BRACKET
+FE5E;W # Pe SMALL RIGHT TORTOISE SHELL BRACKET
+FE5F..FE61;W # Po [3] SMALL NUMBER SIGN..SMALL ASTERISK
+FE62;W # Sm SMALL PLUS SIGN
+FE63;W # Pd SMALL HYPHEN-MINUS
+FE64..FE66;W # Sm [3] SMALL LESS-THAN SIGN..SMALL EQUALS SIGN
+FE68;W # Po SMALL REVERSE SOLIDUS
+FE69;W # Sc SMALL DOLLAR SIGN
+FE6A..FE6B;W # Po [2] SMALL PERCENT SIGN..SMALL COMMERCIAL AT
+FE70..FE74;N # Lo [5] ARABIC FATHATAN ISOLATED FORM..ARABIC KASRATAN ISOLATED FORM
+FE76..FEFC;N # Lo [135] ARABIC FATHA ISOLATED FORM..ARABIC LIGATURE LAM WITH ALEF FINAL FORM
+FEFF;N # Cf ZERO WIDTH NO-BREAK SPACE
+FF01..FF03;F # Po [3] FULLWIDTH EXCLAMATION MARK..FULLWIDTH NUMBER SIGN
+FF04;F # Sc FULLWIDTH DOLLAR SIGN
+FF05..FF07;F # Po [3] FULLWIDTH PERCENT SIGN..FULLWIDTH APOSTROPHE
+FF08;F # Ps FULLWIDTH LEFT PARENTHESIS
+FF09;F # Pe FULLWIDTH RIGHT PARENTHESIS
+FF0A;F # Po FULLWIDTH ASTERISK
+FF0B;F # Sm FULLWIDTH PLUS SIGN
+FF0C;F # Po FULLWIDTH COMMA
+FF0D;F # Pd FULLWIDTH HYPHEN-MINUS
+FF0E..FF0F;F # Po [2] FULLWIDTH FULL STOP..FULLWIDTH SOLIDUS
+FF10..FF19;F # Nd [10] FULLWIDTH DIGIT ZERO..FULLWIDTH DIGIT NINE
+FF1A..FF1B;F # Po [2] FULLWIDTH COLON..FULLWIDTH SEMICOLON
+FF1C..FF1E;F # Sm [3] FULLWIDTH LESS-THAN SIGN..FULLWIDTH GREATER-THAN SIGN
+FF1F..FF20;F # Po [2] FULLWIDTH QUESTION MARK..FULLWIDTH COMMERCIAL AT
+FF21..FF3A;F # Lu [26] FULLWIDTH LATIN CAPITAL LETTER A..FULLWIDTH LATIN CAPITAL LETTER Z
+FF3B;F # Ps FULLWIDTH LEFT SQUARE BRACKET
+FF3C;F # Po FULLWIDTH REVERSE SOLIDUS
+FF3D;F # Pe FULLWIDTH RIGHT SQUARE BRACKET
+FF3E;F # Sk FULLWIDTH CIRCUMFLEX ACCENT
+FF3F;F # Pc FULLWIDTH LOW LINE
+FF40;F # Sk FULLWIDTH GRAVE ACCENT
+FF41..FF5A;F # Ll [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH LATIN SMALL LETTER Z
+FF5B;F # Ps FULLWIDTH LEFT CURLY BRACKET
+FF5C;F # Sm FULLWIDTH VERTICAL LINE
+FF5D;F # Pe FULLWIDTH RIGHT CURLY BRACKET
+FF5E;F # Sm FULLWIDTH TILDE
+FF5F;F # Ps FULLWIDTH LEFT WHITE PARENTHESIS
+FF60;F # Pe FULLWIDTH RIGHT WHITE PARENTHESIS
+FF61;H # Po HALFWIDTH IDEOGRAPHIC FULL STOP
+FF62;H # Ps HALFWIDTH LEFT CORNER BRACKET
+FF63;H # Pe HALFWIDTH RIGHT CORNER BRACKET
+FF64..FF65;H # Po [2] HALFWIDTH IDEOGRAPHIC COMMA..HALFWIDTH KATAKANA MIDDLE DOT
+FF66..FF6F;H # Lo [10] HALFWIDTH KATAKANA LETTER WO..HALFWIDTH KATAKANA LETTER SMALL TU
+FF70;H # Lm HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK
+FF71..FF9D;H # Lo [45] HALFWIDTH KATAKANA LETTER A..HALFWIDTH KATAKANA LETTER N
+FF9E..FF9F;H # Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK
+FFA0..FFBE;H # Lo [31] HALFWIDTH HANGUL FILLER..HALFWIDTH HANGUL LETTER HIEUH
+FFC2..FFC7;H # Lo [6] HALFWIDTH HANGUL LETTER A..HALFWIDTH HANGUL LETTER E
+FFCA..FFCF;H # Lo [6] HALFWIDTH HANGUL LETTER YEO..HALFWIDTH HANGUL LETTER OE
+FFD2..FFD7;H # Lo [6] HALFWIDTH HANGUL LETTER YO..HALFWIDTH HANGUL LETTER YU
+FFDA..FFDC;H # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL LETTER I
+FFE0..FFE1;F # Sc [2] FULLWIDTH CENT SIGN..FULLWIDTH POUND SIGN
+FFE2;F # Sm FULLWIDTH NOT SIGN
+FFE3;F # Sk FULLWIDTH MACRON
+FFE4;F # So FULLWIDTH BROKEN BAR
+FFE5..FFE6;F # Sc [2] FULLWIDTH YEN SIGN..FULLWIDTH WON SIGN
+FFE8;H # So HALFWIDTH FORMS LIGHT VERTICAL
+FFE9..FFEC;H # Sm [4] HALFWIDTH LEFTWARDS ARROW..HALFWIDTH DOWNWARDS ARROW
+FFED..FFEE;H # So [2] HALFWIDTH BLACK SQUARE..HALFWIDTH WHITE CIRCLE
+FFF9..FFFB;N # Cf [3] INTERLINEAR ANNOTATION ANCHOR..INTERLINEAR ANNOTATION TERMINATOR
+FFFC;N # So OBJECT REPLACEMENT CHARACTER
+FFFD;A # So REPLACEMENT CHARACTER
+10000..1000B;N # Lo [12] LINEAR B SYLLABLE B008 A..LINEAR B SYLLABLE B046 JE
+1000D..10026;N # Lo [26] LINEAR B SYLLABLE B036 JO..LINEAR B SYLLABLE B032 QO
+10028..1003A;N # Lo [19] LINEAR B SYLLABLE B060 RA..LINEAR B SYLLABLE B042 WO
+1003C..1003D;N # Lo [2] LINEAR B SYLLABLE B017 ZA..LINEAR B SYLLABLE B074 ZE
+1003F..1004D;N # Lo [15] LINEAR B SYLLABLE B020 ZO..LINEAR B SYLLABLE B091 TWO
+10050..1005D;N # Lo [14] LINEAR B SYMBOL B018..LINEAR B SYMBOL B089
+10080..100FA;N # Lo [123] LINEAR B IDEOGRAM B100 MAN..LINEAR B IDEOGRAM VESSEL B305
+10100..10102;N # Po [3] AEGEAN WORD SEPARATOR LINE..AEGEAN CHECK MARK
+10107..10133;N # No [45] AEGEAN NUMBER ONE..AEGEAN NUMBER NINETY THOUSAND
+10137..1013F;N # So [9] AEGEAN WEIGHT BASE UNIT..AEGEAN MEASURE THIRD SUBUNIT
+10140..10174;N # Nl [53] GREEK ACROPHONIC ATTIC ONE QUARTER..GREEK ACROPHONIC STRATIAN FIFTY MNAS
+10175..10178;N # No [4] GREEK ONE HALF SIGN..GREEK THREE QUARTERS SIGN
+10179..10189;N # So [17] GREEK YEAR SIGN..GREEK TRYBLION BASE SIGN
+1018A..1018B;N # No [2] GREEK ZERO SIGN..GREEK ONE QUARTER SIGN
+1018C..1018E;N # So [3] GREEK SINUSOID SIGN..NOMISMA SIGN
+10190..1019B;N # So [12] ROMAN SEXTANS SIGN..ROMAN CENTURIAL SIGN
+101A0;N # So GREEK SYMBOL TAU RHO
+101D0..101FC;N # So [45] PHAISTOS DISC SIGN PEDESTRIAN..PHAISTOS DISC SIGN WAVY BAND
+101FD;N # Mn PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE
+10280..1029C;N # Lo [29] LYCIAN LETTER A..LYCIAN LETTER X
+102A0..102D0;N # Lo [49] CARIAN LETTER A..CARIAN LETTER UUU3
+102E0;N # Mn COPTIC EPACT THOUSANDS MARK
+102E1..102FB;N # No [27] COPTIC EPACT DIGIT ONE..COPTIC EPACT NUMBER NINE HUNDRED
+10300..1031F;N # Lo [32] OLD ITALIC LETTER A..OLD ITALIC LETTER ESS
+10320..10323;N # No [4] OLD ITALIC NUMERAL ONE..OLD ITALIC NUMERAL FIFTY
+1032D..1032F;N # Lo [3] OLD ITALIC LETTER YE..OLD ITALIC LETTER SOUTHERN TSE
+10330..10340;N # Lo [17] GOTHIC LETTER AHSA..GOTHIC LETTER PAIRTHRA
+10341;N # Nl GOTHIC LETTER NINETY
+10342..10349;N # Lo [8] GOTHIC LETTER RAIDA..GOTHIC LETTER OTHAL
+1034A;N # Nl GOTHIC LETTER NINE HUNDRED
+10350..10375;N # Lo [38] OLD PERMIC LETTER AN..OLD PERMIC LETTER IA
+10376..1037A;N # Mn [5] COMBINING OLD PERMIC LETTER AN..COMBINING OLD PERMIC LETTER SII
+10380..1039D;N # Lo [30] UGARITIC LETTER ALPA..UGARITIC LETTER SSU
+1039F;N # Po UGARITIC WORD DIVIDER
+103A0..103C3;N # Lo [36] OLD PERSIAN SIGN A..OLD PERSIAN SIGN HA
+103C8..103CF;N # Lo [8] OLD PERSIAN SIGN AURAMAZDAA..OLD PERSIAN SIGN BUUMISH
+103D0;N # Po OLD PERSIAN WORD DIVIDER
+103D1..103D5;N # Nl [5] OLD PERSIAN NUMBER ONE..OLD PERSIAN NUMBER HUNDRED
+10400..1044F;N # L& [80] DESERET CAPITAL LETTER LONG I..DESERET SMALL LETTER EW
+10450..1047F;N # Lo [48] SHAVIAN LETTER PEEP..SHAVIAN LETTER YEW
+10480..1049D;N # Lo [30] OSMANYA LETTER ALEF..OSMANYA LETTER OO
+104A0..104A9;N # Nd [10] OSMANYA DIGIT ZERO..OSMANYA DIGIT NINE
+104B0..104D3;N # Lu [36] OSAGE CAPITAL LETTER A..OSAGE CAPITAL LETTER ZHA
+104D8..104FB;N # Ll [36] OSAGE SMALL LETTER A..OSAGE SMALL LETTER ZHA
+10500..10527;N # Lo [40] ELBASAN LETTER A..ELBASAN LETTER KHE
+10530..10563;N # Lo [52] CAUCASIAN ALBANIAN LETTER ALT..CAUCASIAN ALBANIAN LETTER KIW
+1056F;N # Po CAUCASIAN ALBANIAN CITATION MARK
+10600..10736;N # Lo [311] LINEAR A SIGN AB001..LINEAR A SIGN A664
+10740..10755;N # Lo [22] LINEAR A SIGN A701 A..LINEAR A SIGN A732 JE
+10760..10767;N # Lo [8] LINEAR A SIGN A800..LINEAR A SIGN A807
+10800..10805;N # Lo [6] CYPRIOT SYLLABLE A..CYPRIOT SYLLABLE JA
+10808;N # Lo CYPRIOT SYLLABLE JO
+1080A..10835;N # Lo [44] CYPRIOT SYLLABLE KA..CYPRIOT SYLLABLE WO
+10837..10838;N # Lo [2] CYPRIOT SYLLABLE XA..CYPRIOT SYLLABLE XE
+1083C;N # Lo CYPRIOT SYLLABLE ZA
+1083F;N # Lo CYPRIOT SYLLABLE ZO
+10840..10855;N # Lo [22] IMPERIAL ARAMAIC LETTER ALEPH..IMPERIAL ARAMAIC LETTER TAW
+10857;N # Po IMPERIAL ARAMAIC SECTION SIGN
+10858..1085F;N # No [8] IMPERIAL ARAMAIC NUMBER ONE..IMPERIAL ARAMAIC NUMBER TEN THOUSAND
+10860..10876;N # Lo [23] PALMYRENE LETTER ALEPH..PALMYRENE LETTER TAW
+10877..10878;N # So [2] PALMYRENE LEFT-POINTING FLEURON..PALMYRENE RIGHT-POINTING FLEURON
+10879..1087F;N # No [7] PALMYRENE NUMBER ONE..PALMYRENE NUMBER TWENTY
+10880..1089E;N # Lo [31] NABATAEAN LETTER FINAL ALEPH..NABATAEAN LETTER TAW
+108A7..108AF;N # No [9] NABATAEAN NUMBER ONE..NABATAEAN NUMBER ONE HUNDRED
+108E0..108F2;N # Lo [19] HATRAN LETTER ALEPH..HATRAN LETTER QOPH
+108F4..108F5;N # Lo [2] HATRAN LETTER SHIN..HATRAN LETTER TAW
+108FB..108FF;N # No [5] HATRAN NUMBER ONE..HATRAN NUMBER ONE HUNDRED
+10900..10915;N # Lo [22] PHOENICIAN LETTER ALF..PHOENICIAN LETTER TAU
+10916..1091B;N # No [6] PHOENICIAN NUMBER ONE..PHOENICIAN NUMBER THREE
+1091F;N # Po PHOENICIAN WORD SEPARATOR
+10920..10939;N # Lo [26] LYDIAN LETTER A..LYDIAN LETTER C
+1093F;N # Po LYDIAN TRIANGULAR MARK
+10980..1099F;N # Lo [32] MEROITIC HIEROGLYPHIC LETTER A..MEROITIC HIEROGLYPHIC SYMBOL VIDJ-2
+109A0..109B7;N # Lo [24] MEROITIC CURSIVE LETTER A..MEROITIC CURSIVE LETTER DA
+109BC..109BD;N # No [2] MEROITIC CURSIVE FRACTION ELEVEN TWELFTHS..MEROITIC CURSIVE FRACTION ONE HALF
+109BE..109BF;N # Lo [2] MEROITIC CURSIVE LOGOGRAM RMT..MEROITIC CURSIVE LOGOGRAM IMN
+109C0..109CF;N # No [16] MEROITIC CURSIVE NUMBER ONE..MEROITIC CURSIVE NUMBER SEVENTY
+109D2..109FF;N # No [46] MEROITIC CURSIVE NUMBER ONE HUNDRED..MEROITIC CURSIVE FRACTION TEN TWELFTHS
+10A00;N # Lo KHAROSHTHI LETTER A
+10A01..10A03;N # Mn [3] KHAROSHTHI VOWEL SIGN I..KHAROSHTHI VOWEL SIGN VOCALIC R
+10A05..10A06;N # Mn [2] KHAROSHTHI VOWEL SIGN E..KHAROSHTHI VOWEL SIGN O
+10A0C..10A0F;N # Mn [4] KHAROSHTHI VOWEL LENGTH MARK..KHAROSHTHI SIGN VISARGA
+10A10..10A13;N # Lo [4] KHAROSHTHI LETTER KA..KHAROSHTHI LETTER GHA
+10A15..10A17;N # Lo [3] KHAROSHTHI LETTER CA..KHAROSHTHI LETTER JA
+10A19..10A33;N # Lo [27] KHAROSHTHI LETTER NYA..KHAROSHTHI LETTER TTTHA
+10A38..10A3A;N # Mn [3] KHAROSHTHI SIGN BAR ABOVE..KHAROSHTHI SIGN DOT BELOW
+10A3F;N # Mn KHAROSHTHI VIRAMA
+10A40..10A47;N # No [8] KHAROSHTHI DIGIT ONE..KHAROSHTHI NUMBER ONE THOUSAND
+10A50..10A58;N # Po [9] KHAROSHTHI PUNCTUATION DOT..KHAROSHTHI PUNCTUATION LINES
+10A60..10A7C;N # Lo [29] OLD SOUTH ARABIAN LETTER HE..OLD SOUTH ARABIAN LETTER THETH
+10A7D..10A7E;N # No [2] OLD SOUTH ARABIAN NUMBER ONE..OLD SOUTH ARABIAN NUMBER FIFTY
+10A7F;N # Po OLD SOUTH ARABIAN NUMERIC INDICATOR
+10A80..10A9C;N # Lo [29] OLD NORTH ARABIAN LETTER HEH..OLD NORTH ARABIAN LETTER ZAH
+10A9D..10A9F;N # No [3] OLD NORTH ARABIAN NUMBER ONE..OLD NORTH ARABIAN NUMBER TWENTY
+10AC0..10AC7;N # Lo [8] MANICHAEAN LETTER ALEPH..MANICHAEAN LETTER WAW
+10AC8;N # So MANICHAEAN SIGN UD
+10AC9..10AE4;N # Lo [28] MANICHAEAN LETTER ZAYIN..MANICHAEAN LETTER TAW
+10AE5..10AE6;N # Mn [2] MANICHAEAN ABBREVIATION MARK ABOVE..MANICHAEAN ABBREVIATION MARK BELOW
+10AEB..10AEF;N # No [5] MANICHAEAN NUMBER ONE..MANICHAEAN NUMBER ONE HUNDRED
+10AF0..10AF6;N # Po [7] MANICHAEAN PUNCTUATION STAR..MANICHAEAN PUNCTUATION LINE FILLER
+10B00..10B35;N # Lo [54] AVESTAN LETTER A..AVESTAN LETTER HE
+10B39..10B3F;N # Po [7] AVESTAN ABBREVIATION MARK..LARGE ONE RING OVER TWO RINGS PUNCTUATION
+10B40..10B55;N # Lo [22] INSCRIPTIONAL PARTHIAN LETTER ALEPH..INSCRIPTIONAL PARTHIAN LETTER TAW
+10B58..10B5F;N # No [8] INSCRIPTIONAL PARTHIAN NUMBER ONE..INSCRIPTIONAL PARTHIAN NUMBER ONE THOUSAND
+10B60..10B72;N # Lo [19] INSCRIPTIONAL PAHLAVI LETTER ALEPH..INSCRIPTIONAL PAHLAVI LETTER TAW
+10B78..10B7F;N # No [8] INSCRIPTIONAL PAHLAVI NUMBER ONE..INSCRIPTIONAL PAHLAVI NUMBER ONE THOUSAND
+10B80..10B91;N # Lo [18] PSALTER PAHLAVI LETTER ALEPH..PSALTER PAHLAVI LETTER TAW
+10B99..10B9C;N # Po [4] PSALTER PAHLAVI SECTION MARK..PSALTER PAHLAVI FOUR DOTS WITH DOT
+10BA9..10BAF;N # No [7] PSALTER PAHLAVI NUMBER ONE..PSALTER PAHLAVI NUMBER ONE HUNDRED
+10C00..10C48;N # Lo [73] OLD TURKIC LETTER ORKHON A..OLD TURKIC LETTER ORKHON BASH
+10C80..10CB2;N # Lu [51] OLD HUNGARIAN CAPITAL LETTER A..OLD HUNGARIAN CAPITAL LETTER US
+10CC0..10CF2;N # Ll [51] OLD HUNGARIAN SMALL LETTER A..OLD HUNGARIAN SMALL LETTER US
+10CFA..10CFF;N # No [6] OLD HUNGARIAN NUMBER ONE..OLD HUNGARIAN NUMBER ONE THOUSAND
+10E60..10E7E;N # No [31] RUMI DIGIT ONE..RUMI FRACTION TWO THIRDS
+11000;N # Mc BRAHMI SIGN CANDRABINDU
+11001;N # Mn BRAHMI SIGN ANUSVARA
+11002;N # Mc BRAHMI SIGN VISARGA
+11003..11037;N # Lo [53] BRAHMI SIGN JIHVAMULIYA..BRAHMI LETTER OLD TAMIL NNNA
+11038..11046;N # Mn [15] BRAHMI VOWEL SIGN AA..BRAHMI VIRAMA
+11047..1104D;N # Po [7] BRAHMI DANDA..BRAHMI PUNCTUATION LOTUS
+11052..11065;N # No [20] BRAHMI NUMBER ONE..BRAHMI NUMBER ONE THOUSAND
+11066..1106F;N # Nd [10] BRAHMI DIGIT ZERO..BRAHMI DIGIT NINE
+1107F;N # Mn BRAHMI NUMBER JOINER
+11080..11081;N # Mn [2] KAITHI SIGN CANDRABINDU..KAITHI SIGN ANUSVARA
+11082;N # Mc KAITHI SIGN VISARGA
+11083..110AF;N # Lo [45] KAITHI LETTER A..KAITHI LETTER HA
+110B0..110B2;N # Mc [3] KAITHI VOWEL SIGN AA..KAITHI VOWEL SIGN II
+110B3..110B6;N # Mn [4] KAITHI VOWEL SIGN U..KAITHI VOWEL SIGN AI
+110B7..110B8;N # Mc [2] KAITHI VOWEL SIGN O..KAITHI VOWEL SIGN AU
+110B9..110BA;N # Mn [2] KAITHI SIGN VIRAMA..KAITHI SIGN NUKTA
+110BB..110BC;N # Po [2] KAITHI ABBREVIATION SIGN..KAITHI ENUMERATION SIGN
+110BD;N # Cf KAITHI NUMBER SIGN
+110BE..110C1;N # Po [4] KAITHI SECTION MARK..KAITHI DOUBLE DANDA
+110D0..110E8;N # Lo [25] SORA SOMPENG LETTER SAH..SORA SOMPENG LETTER MAE
+110F0..110F9;N # Nd [10] SORA SOMPENG DIGIT ZERO..SORA SOMPENG DIGIT NINE
+11100..11102;N # Mn [3] CHAKMA SIGN CANDRABINDU..CHAKMA SIGN VISARGA
+11103..11126;N # Lo [36] CHAKMA LETTER AA..CHAKMA LETTER HAA
+11127..1112B;N # Mn [5] CHAKMA VOWEL SIGN A..CHAKMA VOWEL SIGN UU
+1112C;N # Mc CHAKMA VOWEL SIGN E
+1112D..11134;N # Mn [8] CHAKMA VOWEL SIGN AI..CHAKMA MAAYYAA
+11136..1113F;N # Nd [10] CHAKMA DIGIT ZERO..CHAKMA DIGIT NINE
+11140..11143;N # Po [4] CHAKMA SECTION MARK..CHAKMA QUESTION MARK
+11150..11172;N # Lo [35] MAHAJANI LETTER A..MAHAJANI LETTER RRA
+11173;N # Mn MAHAJANI SIGN NUKTA
+11174..11175;N # Po [2] MAHAJANI ABBREVIATION SIGN..MAHAJANI SECTION MARK
+11176;N # Lo MAHAJANI LIGATURE SHRI
+11180..11181;N # Mn [2] SHARADA SIGN CANDRABINDU..SHARADA SIGN ANUSVARA
+11182;N # Mc SHARADA SIGN VISARGA
+11183..111B2;N # Lo [48] SHARADA LETTER A..SHARADA LETTER HA
+111B3..111B5;N # Mc [3] SHARADA VOWEL SIGN AA..SHARADA VOWEL SIGN II
+111B6..111BE;N # Mn [9] SHARADA VOWEL SIGN U..SHARADA VOWEL SIGN O
+111BF..111C0;N # Mc [2] SHARADA VOWEL SIGN AU..SHARADA SIGN VIRAMA
+111C1..111C4;N # Lo [4] SHARADA SIGN AVAGRAHA..SHARADA OM
+111C5..111C9;N # Po [5] SHARADA DANDA..SHARADA SANDHI MARK
+111CA..111CC;N # Mn [3] SHARADA SIGN NUKTA..SHARADA EXTRA SHORT VOWEL MARK
+111CD;N # Po SHARADA SUTRA MARK
+111D0..111D9;N # Nd [10] SHARADA DIGIT ZERO..SHARADA DIGIT NINE
+111DA;N # Lo SHARADA EKAM
+111DB;N # Po SHARADA SIGN SIDDHAM
+111DC;N # Lo SHARADA HEADSTROKE
+111DD..111DF;N # Po [3] SHARADA CONTINUATION SIGN..SHARADA SECTION MARK-2
+111E1..111F4;N # No [20] SINHALA ARCHAIC DIGIT ONE..SINHALA ARCHAIC NUMBER ONE THOUSAND
+11200..11211;N # Lo [18] KHOJKI LETTER A..KHOJKI LETTER JJA
+11213..1122B;N # Lo [25] KHOJKI LETTER NYA..KHOJKI LETTER LLA
+1122C..1122E;N # Mc [3] KHOJKI VOWEL SIGN AA..KHOJKI VOWEL SIGN II
+1122F..11231;N # Mn [3] KHOJKI VOWEL SIGN U..KHOJKI VOWEL SIGN AI
+11232..11233;N # Mc [2] KHOJKI VOWEL SIGN O..KHOJKI VOWEL SIGN AU
+11234;N # Mn KHOJKI SIGN ANUSVARA
+11235;N # Mc KHOJKI SIGN VIRAMA
+11236..11237;N # Mn [2] KHOJKI SIGN NUKTA..KHOJKI SIGN SHADDA
+11238..1123D;N # Po [6] KHOJKI DANDA..KHOJKI ABBREVIATION SIGN
+1123E;N # Mn KHOJKI SIGN SUKUN
+11280..11286;N # Lo [7] MULTANI LETTER A..MULTANI LETTER GA
+11288;N # Lo MULTANI LETTER GHA
+1128A..1128D;N # Lo [4] MULTANI LETTER CA..MULTANI LETTER JJA
+1128F..1129D;N # Lo [15] MULTANI LETTER NYA..MULTANI LETTER BA
+1129F..112A8;N # Lo [10] MULTANI LETTER BHA..MULTANI LETTER RHA
+112A9;N # Po MULTANI SECTION MARK
+112B0..112DE;N # Lo [47] KHUDAWADI LETTER A..KHUDAWADI LETTER HA
+112DF;N # Mn KHUDAWADI SIGN ANUSVARA
+112E0..112E2;N # Mc [3] KHUDAWADI VOWEL SIGN AA..KHUDAWADI VOWEL SIGN II
+112E3..112EA;N # Mn [8] KHUDAWADI VOWEL SIGN U..KHUDAWADI SIGN VIRAMA
+112F0..112F9;N # Nd [10] KHUDAWADI DIGIT ZERO..KHUDAWADI DIGIT NINE
+11300..11301;N # Mn [2] GRANTHA SIGN COMBINING ANUSVARA ABOVE..GRANTHA SIGN CANDRABINDU
+11302..11303;N # Mc [2] GRANTHA SIGN ANUSVARA..GRANTHA SIGN VISARGA
+11305..1130C;N # Lo [8] GRANTHA LETTER A..GRANTHA LETTER VOCALIC L
+1130F..11310;N # Lo [2] GRANTHA LETTER EE..GRANTHA LETTER AI
+11313..11328;N # Lo [22] GRANTHA LETTER OO..GRANTHA LETTER NA
+1132A..11330;N # Lo [7] GRANTHA LETTER PA..GRANTHA LETTER RA
+11332..11333;N # Lo [2] GRANTHA LETTER LA..GRANTHA LETTER LLA
+11335..11339;N # Lo [5] GRANTHA LETTER VA..GRANTHA LETTER HA
+1133C;N # Mn GRANTHA SIGN NUKTA
+1133D;N # Lo GRANTHA SIGN AVAGRAHA
+1133E..1133F;N # Mc [2] GRANTHA VOWEL SIGN AA..GRANTHA VOWEL SIGN I
+11340;N # Mn GRANTHA VOWEL SIGN II
+11341..11344;N # Mc [4] GRANTHA VOWEL SIGN U..GRANTHA VOWEL SIGN VOCALIC RR
+11347..11348;N # Mc [2] GRANTHA VOWEL SIGN EE..GRANTHA VOWEL SIGN AI
+1134B..1134D;N # Mc [3] GRANTHA VOWEL SIGN OO..GRANTHA SIGN VIRAMA
+11350;N # Lo GRANTHA OM
+11357;N # Mc GRANTHA AU LENGTH MARK
+1135D..11361;N # Lo [5] GRANTHA SIGN PLUTA..GRANTHA LETTER VOCALIC LL
+11362..11363;N # Mc [2] GRANTHA VOWEL SIGN VOCALIC L..GRANTHA VOWEL SIGN VOCALIC LL
+11366..1136C;N # Mn [7] COMBINING GRANTHA DIGIT ZERO..COMBINING GRANTHA DIGIT SIX
+11370..11374;N # Mn [5] COMBINING GRANTHA LETTER A..COMBINING GRANTHA LETTER PA
+11400..11434;N # Lo [53] NEWA LETTER A..NEWA LETTER HA
+11435..11437;N # Mc [3] NEWA VOWEL SIGN AA..NEWA VOWEL SIGN II
+11438..1143F;N # Mn [8] NEWA VOWEL SIGN U..NEWA VOWEL SIGN AI
+11440..11441;N # Mc [2] NEWA VOWEL SIGN O..NEWA VOWEL SIGN AU
+11442..11444;N # Mn [3] NEWA SIGN VIRAMA..NEWA SIGN ANUSVARA
+11445;N # Mc NEWA SIGN VISARGA
+11446;N # Mn NEWA SIGN NUKTA
+11447..1144A;N # Lo [4] NEWA SIGN AVAGRAHA..NEWA SIDDHI
+1144B..1144F;N # Po [5] NEWA DANDA..NEWA ABBREVIATION SIGN
+11450..11459;N # Nd [10] NEWA DIGIT ZERO..NEWA DIGIT NINE
+1145B;N # Po NEWA PLACEHOLDER MARK
+1145D;N # Po NEWA INSERTION SIGN
+11480..114AF;N # Lo [48] TIRHUTA ANJI..TIRHUTA LETTER HA
+114B0..114B2;N # Mc [3] TIRHUTA VOWEL SIGN AA..TIRHUTA VOWEL SIGN II
+114B3..114B8;N # Mn [6] TIRHUTA VOWEL SIGN U..TIRHUTA VOWEL SIGN VOCALIC LL
+114B9;N # Mc TIRHUTA VOWEL SIGN E
+114BA;N # Mn TIRHUTA VOWEL SIGN SHORT E
+114BB..114BE;N # Mc [4] TIRHUTA VOWEL SIGN AI..TIRHUTA VOWEL SIGN AU
+114BF..114C0;N # Mn [2] TIRHUTA SIGN CANDRABINDU..TIRHUTA SIGN ANUSVARA
+114C1;N # Mc TIRHUTA SIGN VISARGA
+114C2..114C3;N # Mn [2] TIRHUTA SIGN VIRAMA..TIRHUTA SIGN NUKTA
+114C4..114C5;N # Lo [2] TIRHUTA SIGN AVAGRAHA..TIRHUTA GVANG
+114C6;N # Po TIRHUTA ABBREVIATION SIGN
+114C7;N # Lo TIRHUTA OM
+114D0..114D9;N # Nd [10] TIRHUTA DIGIT ZERO..TIRHUTA DIGIT NINE
+11580..115AE;N # Lo [47] SIDDHAM LETTER A..SIDDHAM LETTER HA
+115AF..115B1;N # Mc [3] SIDDHAM VOWEL SIGN AA..SIDDHAM VOWEL SIGN II
+115B2..115B5;N # Mn [4] SIDDHAM VOWEL SIGN U..SIDDHAM VOWEL SIGN VOCALIC RR
+115B8..115BB;N # Mc [4] SIDDHAM VOWEL SIGN E..SIDDHAM VOWEL SIGN AU
+115BC..115BD;N # Mn [2] SIDDHAM SIGN CANDRABINDU..SIDDHAM SIGN ANUSVARA
+115BE;N # Mc SIDDHAM SIGN VISARGA
+115BF..115C0;N # Mn [2] SIDDHAM SIGN VIRAMA..SIDDHAM SIGN NUKTA
+115C1..115D7;N # Po [23] SIDDHAM SIGN SIDDHAM..SIDDHAM SECTION MARK WITH CIRCLES AND FOUR ENCLOSURES
+115D8..115DB;N # Lo [4] SIDDHAM LETTER THREE-CIRCLE ALTERNATE I..SIDDHAM LETTER ALTERNATE U
+115DC..115DD;N # Mn [2] SIDDHAM VOWEL SIGN ALTERNATE U..SIDDHAM VOWEL SIGN ALTERNATE UU
+11600..1162F;N # Lo [48] MODI LETTER A..MODI LETTER LLA
+11630..11632;N # Mc [3] MODI VOWEL SIGN AA..MODI VOWEL SIGN II
+11633..1163A;N # Mn [8] MODI VOWEL SIGN U..MODI VOWEL SIGN AI
+1163B..1163C;N # Mc [2] MODI VOWEL SIGN O..MODI VOWEL SIGN AU
+1163D;N # Mn MODI SIGN ANUSVARA
+1163E;N # Mc MODI SIGN VISARGA
+1163F..11640;N # Mn [2] MODI SIGN VIRAMA..MODI SIGN ARDHACANDRA
+11641..11643;N # Po [3] MODI DANDA..MODI ABBREVIATION SIGN
+11644;N # Lo MODI SIGN HUVA
+11650..11659;N # Nd [10] MODI DIGIT ZERO..MODI DIGIT NINE
+11660..1166C;N # Po [13] MONGOLIAN BIRGA WITH ORNAMENT..MONGOLIAN TURNED SWIRL BIRGA WITH DOUBLE ORNAMENT
+11680..116AA;N # Lo [43] TAKRI LETTER A..TAKRI LETTER RRA
+116AB;N # Mn TAKRI SIGN ANUSVARA
+116AC;N # Mc TAKRI SIGN VISARGA
+116AD;N # Mn TAKRI VOWEL SIGN AA
+116AE..116AF;N # Mc [2] TAKRI VOWEL SIGN I..TAKRI VOWEL SIGN II
+116B0..116B5;N # Mn [6] TAKRI VOWEL SIGN U..TAKRI VOWEL SIGN AU
+116B6;N # Mc TAKRI SIGN VIRAMA
+116B7;N # Mn TAKRI SIGN NUKTA
+116C0..116C9;N # Nd [10] TAKRI DIGIT ZERO..TAKRI DIGIT NINE
+11700..11719;N # Lo [26] AHOM LETTER KA..AHOM LETTER JHA
+1171D..1171F;N # Mn [3] AHOM CONSONANT SIGN MEDIAL LA..AHOM CONSONANT SIGN MEDIAL LIGATING RA
+11720..11721;N # Mc [2] AHOM VOWEL SIGN A..AHOM VOWEL SIGN AA
+11722..11725;N # Mn [4] AHOM VOWEL SIGN I..AHOM VOWEL SIGN UU
+11726;N # Mc AHOM VOWEL SIGN E
+11727..1172B;N # Mn [5] AHOM VOWEL SIGN AW..AHOM SIGN KILLER
+11730..11739;N # Nd [10] AHOM DIGIT ZERO..AHOM DIGIT NINE
+1173A..1173B;N # No [2] AHOM NUMBER TEN..AHOM NUMBER TWENTY
+1173C..1173E;N # Po [3] AHOM SIGN SMALL SECTION..AHOM SIGN RULAI
+1173F;N # So AHOM SYMBOL VI
+118A0..118DF;N # L& [64] WARANG CITI CAPITAL LETTER NGAA..WARANG CITI SMALL LETTER VIYO
+118E0..118E9;N # Nd [10] WARANG CITI DIGIT ZERO..WARANG CITI DIGIT NINE
+118EA..118F2;N # No [9] WARANG CITI NUMBER TEN..WARANG CITI NUMBER NINETY
+118FF;N # Lo WARANG CITI OM
+11A00;N # Lo ZANABAZAR SQUARE LETTER A
+11A01..11A06;N # Mn [6] ZANABAZAR SQUARE VOWEL SIGN I..ZANABAZAR SQUARE VOWEL SIGN O
+11A07..11A08;N # Mc [2] ZANABAZAR SQUARE VOWEL SIGN AI..ZANABAZAR SQUARE VOWEL SIGN AU
+11A09..11A0A;N # Mn [2] ZANABAZAR SQUARE VOWEL SIGN REVERSED I..ZANABAZAR SQUARE VOWEL LENGTH MARK
+11A0B..11A32;N # Lo [40] ZANABAZAR SQUARE LETTER KA..ZANABAZAR SQUARE LETTER KSSA
+11A33..11A38;N # Mn [6] ZANABAZAR SQUARE FINAL CONSONANT MARK..ZANABAZAR SQUARE SIGN ANUSVARA
+11A39;N # Mc ZANABAZAR SQUARE SIGN VISARGA
+11A3A;N # Lo ZANABAZAR SQUARE CLUSTER-INITIAL LETTER RA
+11A3B..11A3E;N # Mn [4] ZANABAZAR SQUARE CLUSTER-FINAL LETTER YA..ZANABAZAR SQUARE CLUSTER-FINAL LETTER VA
+11A3F..11A46;N # Po [8] ZANABAZAR SQUARE INITIAL HEAD MARK..ZANABAZAR SQUARE CLOSING DOUBLE-LINED HEAD MARK
+11A47;N # Mn ZANABAZAR SQUARE SUBJOINER
+11A50;N # Lo SOYOMBO LETTER A
+11A51..11A56;N # Mn [6] SOYOMBO VOWEL SIGN I..SOYOMBO VOWEL SIGN OE
+11A57..11A58;N # Mc [2] SOYOMBO VOWEL SIGN AI..SOYOMBO VOWEL SIGN AU
+11A59..11A5B;N # Mn [3] SOYOMBO VOWEL SIGN VOCALIC R..SOYOMBO VOWEL LENGTH MARK
+11A5C..11A83;N # Lo [40] SOYOMBO LETTER KA..SOYOMBO LETTER KSSA
+11A86..11A89;N # Lo [4] SOYOMBO CLUSTER-INITIAL LETTER RA..SOYOMBO CLUSTER-INITIAL LETTER SA
+11A8A..11A96;N # Mn [13] SOYOMBO FINAL CONSONANT SIGN G..SOYOMBO SIGN ANUSVARA
+11A97;N # Mc SOYOMBO SIGN VISARGA
+11A98..11A99;N # Mn [2] SOYOMBO GEMINATION MARK..SOYOMBO SUBJOINER
+11A9A..11A9C;N # Po [3] SOYOMBO MARK TSHEG..SOYOMBO MARK DOUBLE SHAD
+11A9E..11AA2;N # Po [5] SOYOMBO HEAD MARK WITH MOON AND SUN AND TRIPLE FLAME..SOYOMBO TERMINAL MARK-2
+11AC0..11AF8;N # Lo [57] PAU CIN HAU LETTER PA..PAU CIN HAU GLOTTAL STOP FINAL
+11C00..11C08;N # Lo [9] BHAIKSUKI LETTER A..BHAIKSUKI LETTER VOCALIC L
+11C0A..11C2E;N # Lo [37] BHAIKSUKI LETTER E..BHAIKSUKI LETTER HA
+11C2F;N # Mc BHAIKSUKI VOWEL SIGN AA
+11C30..11C36;N # Mn [7] BHAIKSUKI VOWEL SIGN I..BHAIKSUKI VOWEL SIGN VOCALIC L
+11C38..11C3D;N # Mn [6] BHAIKSUKI VOWEL SIGN E..BHAIKSUKI SIGN ANUSVARA
+11C3E;N # Mc BHAIKSUKI SIGN VISARGA
+11C3F;N # Mn BHAIKSUKI SIGN VIRAMA
+11C40;N # Lo BHAIKSUKI SIGN AVAGRAHA
+11C41..11C45;N # Po [5] BHAIKSUKI DANDA..BHAIKSUKI GAP FILLER-2
+11C50..11C59;N # Nd [10] BHAIKSUKI DIGIT ZERO..BHAIKSUKI DIGIT NINE
+11C5A..11C6C;N # No [19] BHAIKSUKI NUMBER ONE..BHAIKSUKI HUNDREDS UNIT MARK
+11C70..11C71;N # Po [2] MARCHEN HEAD MARK..MARCHEN MARK SHAD
+11C72..11C8F;N # Lo [30] MARCHEN LETTER KA..MARCHEN LETTER A
+11C92..11CA7;N # Mn [22] MARCHEN SUBJOINED LETTER KA..MARCHEN SUBJOINED LETTER ZA
+11CA9;N # Mc MARCHEN SUBJOINED LETTER YA
+11CAA..11CB0;N # Mn [7] MARCHEN SUBJOINED LETTER RA..MARCHEN VOWEL SIGN AA
+11CB1;N # Mc MARCHEN VOWEL SIGN I
+11CB2..11CB3;N # Mn [2] MARCHEN VOWEL SIGN U..MARCHEN VOWEL SIGN E
+11CB4;N # Mc MARCHEN VOWEL SIGN O
+11CB5..11CB6;N # Mn [2] MARCHEN SIGN ANUSVARA..MARCHEN SIGN CANDRABINDU
+11D00..11D06;N # Lo [7] MASARAM GONDI LETTER A..MASARAM GONDI LETTER E
+11D08..11D09;N # Lo [2] MASARAM GONDI LETTER AI..MASARAM GONDI LETTER O
+11D0B..11D30;N # Lo [38] MASARAM GONDI LETTER AU..MASARAM GONDI LETTER TRA
+11D31..11D36;N # Mn [6] MASARAM GONDI VOWEL SIGN AA..MASARAM GONDI VOWEL SIGN VOCALIC R
+11D3A;N # Mn MASARAM GONDI VOWEL SIGN E
+11D3C..11D3D;N # Mn [2] MASARAM GONDI VOWEL SIGN AI..MASARAM GONDI VOWEL SIGN O
+11D3F..11D45;N # Mn [7] MASARAM GONDI VOWEL SIGN AU..MASARAM GONDI VIRAMA
+11D46;N # Lo MASARAM GONDI REPHA
+11D47;N # Mn MASARAM GONDI RA-KARA
+11D50..11D59;N # Nd [10] MASARAM GONDI DIGIT ZERO..MASARAM GONDI DIGIT NINE
+12000..12399;N # Lo [922] CUNEIFORM SIGN A..CUNEIFORM SIGN U U
+12400..1246E;N # Nl [111] CUNEIFORM NUMERIC SIGN TWO ASH..CUNEIFORM NUMERIC SIGN NINE U VARIANT FORM
+12470..12474;N # Po [5] CUNEIFORM PUNCTUATION SIGN OLD ASSYRIAN WORD DIVIDER..CUNEIFORM PUNCTUATION SIGN DIAGONAL QUADCOLON
+12480..12543;N # Lo [196] CUNEIFORM SIGN AB TIMES NUN TENU..CUNEIFORM SIGN ZU5 TIMES THREE DISH TENU
+13000..1342E;N # Lo [1071] EGYPTIAN HIEROGLYPH A001..EGYPTIAN HIEROGLYPH AA032
+14400..14646;N # Lo [583] ANATOLIAN HIEROGLYPH A001..ANATOLIAN HIEROGLYPH A530
+16800..16A38;N # Lo [569] BAMUM LETTER PHASE-A NGKUE MFON..BAMUM LETTER PHASE-F VUEQ
+16A40..16A5E;N # Lo [31] MRO LETTER TA..MRO LETTER TEK
+16A60..16A69;N # Nd [10] MRO DIGIT ZERO..MRO DIGIT NINE
+16A6E..16A6F;N # Po [2] MRO DANDA..MRO DOUBLE DANDA
+16AD0..16AED;N # Lo [30] BASSA VAH LETTER ENNI..BASSA VAH LETTER I
+16AF0..16AF4;N # Mn [5] BASSA VAH COMBINING HIGH TONE..BASSA VAH COMBINING HIGH-LOW TONE
+16AF5;N # Po BASSA VAH FULL STOP
+16B00..16B2F;N # Lo [48] PAHAWH HMONG VOWEL KEEB..PAHAWH HMONG CONSONANT CAU
+16B30..16B36;N # Mn [7] PAHAWH HMONG MARK CIM TUB..PAHAWH HMONG MARK CIM TAUM
+16B37..16B3B;N # Po [5] PAHAWH HMONG SIGN VOS THOM..PAHAWH HMONG SIGN VOS FEEM
+16B3C..16B3F;N # So [4] PAHAWH HMONG SIGN XYEEM NTXIV..PAHAWH HMONG SIGN XYEEM FAIB
+16B40..16B43;N # Lm [4] PAHAWH HMONG SIGN VOS SEEV..PAHAWH HMONG SIGN IB YAM
+16B44;N # Po PAHAWH HMONG SIGN XAUS
+16B45;N # So PAHAWH HMONG SIGN CIM TSOV ROG
+16B50..16B59;N # Nd [10] PAHAWH HMONG DIGIT ZERO..PAHAWH HMONG DIGIT NINE
+16B5B..16B61;N # No [7] PAHAWH HMONG NUMBER TENS..PAHAWH HMONG NUMBER TRILLIONS
+16B63..16B77;N # Lo [21] PAHAWH HMONG SIGN VOS LUB..PAHAWH HMONG SIGN CIM NRES TOS
+16B7D..16B8F;N # Lo [19] PAHAWH HMONG CLAN SIGN TSHEEJ..PAHAWH HMONG CLAN SIGN VWJ
+16F00..16F44;N # Lo [69] MIAO LETTER PA..MIAO LETTER HHA
+16F50;N # Lo MIAO LETTER NASALIZATION
+16F51..16F7E;N # Mc [46] MIAO SIGN ASPIRATION..MIAO VOWEL SIGN NG
+16F8F..16F92;N # Mn [4] MIAO TONE RIGHT..MIAO TONE BELOW
+16F93..16F9F;N # Lm [13] MIAO LETTER TONE-2..MIAO LETTER REFORMED TONE-8
+16FE0..16FE1;W # Lm [2] TANGUT ITERATION MARK..NUSHU ITERATION MARK
+17000..187EC;W # Lo [6125] TANGUT IDEOGRAPH-17000..TANGUT IDEOGRAPH-187EC
+18800..18AF2;W # Lo [755] TANGUT COMPONENT-001..TANGUT COMPONENT-755
+1B000..1B0FF;W # Lo [256] KATAKANA LETTER ARCHAIC E..HENTAIGANA LETTER RE-2
+1B100..1B11E;W # Lo [31] HENTAIGANA LETTER RE-3..HENTAIGANA LETTER N-MU-MO-2
+1B170..1B2FB;W # Lo [396] NUSHU CHARACTER-1B170..NUSHU CHARACTER-1B2FB
+1BC00..1BC6A;N # Lo [107] DUPLOYAN LETTER H..DUPLOYAN LETTER VOCALIC M
+1BC70..1BC7C;N # Lo [13] DUPLOYAN AFFIX LEFT HORIZONTAL SECANT..DUPLOYAN AFFIX ATTACHED TANGENT HOOK
+1BC80..1BC88;N # Lo [9] DUPLOYAN AFFIX HIGH ACUTE..DUPLOYAN AFFIX HIGH VERTICAL
+1BC90..1BC99;N # Lo [10] DUPLOYAN AFFIX LOW ACUTE..DUPLOYAN AFFIX LOW ARROW
+1BC9C;N # So DUPLOYAN SIGN O WITH CROSS
+1BC9D..1BC9E;N # Mn [2] DUPLOYAN THICK LETTER SELECTOR..DUPLOYAN DOUBLE MARK
+1BC9F;N # Po DUPLOYAN PUNCTUATION CHINOOK FULL STOP
+1BCA0..1BCA3;N # Cf [4] SHORTHAND FORMAT LETTER OVERLAP..SHORTHAND FORMAT UP STEP
+1D000..1D0F5;N # So [246] BYZANTINE MUSICAL SYMBOL PSILI..BYZANTINE MUSICAL SYMBOL GORGON NEO KATO
+1D100..1D126;N # So [39] MUSICAL SYMBOL SINGLE BARLINE..MUSICAL SYMBOL DRUM CLEF-2
+1D129..1D164;N # So [60] MUSICAL SYMBOL MULTIPLE MEASURE REST..MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH NOTE
+1D165..1D166;N # Mc [2] MUSICAL SYMBOL COMBINING STEM..MUSICAL SYMBOL COMBINING SPRECHGESANG STEM
+1D167..1D169;N # Mn [3] MUSICAL SYMBOL COMBINING TREMOLO-1..MUSICAL SYMBOL COMBINING TREMOLO-3
+1D16A..1D16C;N # So [3] MUSICAL SYMBOL FINGERED TREMOLO-1..MUSICAL SYMBOL FINGERED TREMOLO-3
+1D16D..1D172;N # Mc [6] MUSICAL SYMBOL COMBINING AUGMENTATION DOT..MUSICAL SYMBOL COMBINING FLAG-5
+1D173..1D17A;N # Cf [8] MUSICAL SYMBOL BEGIN BEAM..MUSICAL SYMBOL END PHRASE
+1D17B..1D182;N # Mn [8] MUSICAL SYMBOL COMBINING ACCENT..MUSICAL SYMBOL COMBINING LOURE
+1D183..1D184;N # So [2] MUSICAL SYMBOL ARPEGGIATO UP..MUSICAL SYMBOL ARPEGGIATO DOWN
+1D185..1D18B;N # Mn [7] MUSICAL SYMBOL COMBINING DOIT..MUSICAL SYMBOL COMBINING TRIPLE TONGUE
+1D18C..1D1A9;N # So [30] MUSICAL SYMBOL RINFORZANDO..MUSICAL SYMBOL DEGREE SLASH
+1D1AA..1D1AD;N # Mn [4] MUSICAL SYMBOL COMBINING DOWN BOW..MUSICAL SYMBOL COMBINING SNAP PIZZICATO
+1D1AE..1D1E8;N # So [59] MUSICAL SYMBOL PEDAL MARK..MUSICAL SYMBOL KIEVAN FLAT SIGN
+1D200..1D241;N # So [66] GREEK VOCAL NOTATION SYMBOL-1..GREEK INSTRUMENTAL NOTATION SYMBOL-54
+1D242..1D244;N # Mn [3] COMBINING GREEK MUSICAL TRISEME..COMBINING GREEK MUSICAL PENTASEME
+1D245;N # So GREEK MUSICAL LEIMMA
+1D300..1D356;N # So [87] MONOGRAM FOR EARTH..TETRAGRAM FOR FOSTERING
+1D360..1D371;N # No [18] COUNTING ROD UNIT DIGIT ONE..COUNTING ROD TENS DIGIT NINE
+1D400..1D454;N # L& [85] MATHEMATICAL BOLD CAPITAL A..MATHEMATICAL ITALIC SMALL G
+1D456..1D49C;N # L& [71] MATHEMATICAL ITALIC SMALL I..MATHEMATICAL SCRIPT CAPITAL A
+1D49E..1D49F;N # Lu [2] MATHEMATICAL SCRIPT CAPITAL C..MATHEMATICAL SCRIPT CAPITAL D
+1D4A2;N # Lu MATHEMATICAL SCRIPT CAPITAL G
+1D4A5..1D4A6;N # Lu [2] MATHEMATICAL SCRIPT CAPITAL J..MATHEMATICAL SCRIPT CAPITAL K
+1D4A9..1D4AC;N # Lu [4] MATHEMATICAL SCRIPT CAPITAL N..MATHEMATICAL SCRIPT CAPITAL Q
+1D4AE..1D4B9;N # L& [12] MATHEMATICAL SCRIPT CAPITAL S..MATHEMATICAL SCRIPT SMALL D
+1D4BB;N # Ll MATHEMATICAL SCRIPT SMALL F
+1D4BD..1D4C3;N # Ll [7] MATHEMATICAL SCRIPT SMALL H..MATHEMATICAL SCRIPT SMALL N
+1D4C5..1D505;N # L& [65] MATHEMATICAL SCRIPT SMALL P..MATHEMATICAL FRAKTUR CAPITAL B
+1D507..1D50A;N # Lu [4] MATHEMATICAL FRAKTUR CAPITAL D..MATHEMATICAL FRAKTUR CAPITAL G
+1D50D..1D514;N # Lu [8] MATHEMATICAL FRAKTUR CAPITAL J..MATHEMATICAL FRAKTUR CAPITAL Q
+1D516..1D51C;N # Lu [7] MATHEMATICAL FRAKTUR CAPITAL S..MATHEMATICAL FRAKTUR CAPITAL Y
+1D51E..1D539;N # L& [28] MATHEMATICAL FRAKTUR SMALL A..MATHEMATICAL DOUBLE-STRUCK CAPITAL B
+1D53B..1D53E;N # Lu [4] MATHEMATICAL DOUBLE-STRUCK CAPITAL D..MATHEMATICAL DOUBLE-STRUCK CAPITAL G
+1D540..1D544;N # Lu [5] MATHEMATICAL DOUBLE-STRUCK CAPITAL I..MATHEMATICAL DOUBLE-STRUCK CAPITAL M
+1D546;N # Lu MATHEMATICAL DOUBLE-STRUCK CAPITAL O
+1D54A..1D550;N # Lu [7] MATHEMATICAL DOUBLE-STRUCK CAPITAL S..MATHEMATICAL DOUBLE-STRUCK CAPITAL Y
+1D552..1D6A5;N # L& [340] MATHEMATICAL DOUBLE-STRUCK SMALL A..MATHEMATICAL ITALIC SMALL DOTLESS J
+1D6A8..1D6C0;N # Lu [25] MATHEMATICAL BOLD CAPITAL ALPHA..MATHEMATICAL BOLD CAPITAL OMEGA
+1D6C1;N # Sm MATHEMATICAL BOLD NABLA
+1D6C2..1D6DA;N # Ll [25] MATHEMATICAL BOLD SMALL ALPHA..MATHEMATICAL BOLD SMALL OMEGA
+1D6DB;N # Sm MATHEMATICAL BOLD PARTIAL DIFFERENTIAL
+1D6DC..1D6FA;N # L& [31] MATHEMATICAL BOLD EPSILON SYMBOL..MATHEMATICAL ITALIC CAPITAL OMEGA
+1D6FB;N # Sm MATHEMATICAL ITALIC NABLA
+1D6FC..1D714;N # Ll [25] MATHEMATICAL ITALIC SMALL ALPHA..MATHEMATICAL ITALIC SMALL OMEGA
+1D715;N # Sm MATHEMATICAL ITALIC PARTIAL DIFFERENTIAL
+1D716..1D734;N # L& [31] MATHEMATICAL ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD ITALIC CAPITAL OMEGA
+1D735;N # Sm MATHEMATICAL BOLD ITALIC NABLA
+1D736..1D74E;N # Ll [25] MATHEMATICAL BOLD ITALIC SMALL ALPHA..MATHEMATICAL BOLD ITALIC SMALL OMEGA
+1D74F;N # Sm MATHEMATICAL BOLD ITALIC PARTIAL DIFFERENTIAL
+1D750..1D76E;N # L& [31] MATHEMATICAL BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA
+1D76F;N # Sm MATHEMATICAL SANS-SERIF BOLD NABLA
+1D770..1D788;N # Ll [25] MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA
+1D789;N # Sm MATHEMATICAL SANS-SERIF BOLD PARTIAL DIFFERENTIAL
+1D78A..1D7A8;N # L& [31] MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA
+1D7A9;N # Sm MATHEMATICAL SANS-SERIF BOLD ITALIC NABLA
+1D7AA..1D7C2;N # Ll [25] MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA
+1D7C3;N # Sm MATHEMATICAL SANS-SERIF BOLD ITALIC PARTIAL DIFFERENTIAL
+1D7C4..1D7CB;N # L& [8] MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD SMALL DIGAMMA
+1D7CE..1D7FF;N # Nd [50] MATHEMATICAL BOLD DIGIT ZERO..MATHEMATICAL MONOSPACE DIGIT NINE
+1D800..1D9FF;N # So [512] SIGNWRITING HAND-FIST INDEX..SIGNWRITING HEAD
+1DA00..1DA36;N # Mn [55] SIGNWRITING HEAD RIM..SIGNWRITING AIR SUCKING IN
+1DA37..1DA3A;N # So [4] SIGNWRITING AIR BLOW SMALL ROTATIONS..SIGNWRITING BREATH EXHALE
+1DA3B..1DA6C;N # Mn [50] SIGNWRITING MOUTH CLOSED NEUTRAL..SIGNWRITING EXCITEMENT
+1DA6D..1DA74;N # So [8] SIGNWRITING SHOULDER HIP SPINE..SIGNWRITING TORSO-FLOORPLANE TWISTING
+1DA75;N # Mn SIGNWRITING UPPER BODY TILTING FROM HIP JOINTS
+1DA76..1DA83;N # So [14] SIGNWRITING LIMB COMBINATION..SIGNWRITING LOCATION DEPTH
+1DA84;N # Mn SIGNWRITING LOCATION HEAD NECK
+1DA85..1DA86;N # So [2] SIGNWRITING LOCATION TORSO..SIGNWRITING LOCATION LIMBS DIGITS
+1DA87..1DA8B;N # Po [5] SIGNWRITING COMMA..SIGNWRITING PARENTHESIS
+1DA9B..1DA9F;N # Mn [5] SIGNWRITING FILL MODIFIER-2..SIGNWRITING FILL MODIFIER-6
+1DAA1..1DAAF;N # Mn [15] SIGNWRITING ROTATION MODIFIER-2..SIGNWRITING ROTATION MODIFIER-16
+1E000..1E006;N # Mn [7] COMBINING GLAGOLITIC LETTER AZU..COMBINING GLAGOLITIC LETTER ZHIVETE
+1E008..1E018;N # Mn [17] COMBINING GLAGOLITIC LETTER ZEMLJA..COMBINING GLAGOLITIC LETTER HERU
+1E01B..1E021;N # Mn [7] COMBINING GLAGOLITIC LETTER SHTA..COMBINING GLAGOLITIC LETTER YATI
+1E023..1E024;N # Mn [2] COMBINING GLAGOLITIC LETTER YU..COMBINING GLAGOLITIC LETTER SMALL YUS
+1E026..1E02A;N # Mn [5] COMBINING GLAGOLITIC LETTER YO..COMBINING GLAGOLITIC LETTER FITA
+1E800..1E8C4;N # Lo [197] MENDE KIKAKUI SYLLABLE M001 KI..MENDE KIKAKUI SYLLABLE M060 NYON
+1E8C7..1E8CF;N # No [9] MENDE KIKAKUI DIGIT ONE..MENDE KIKAKUI DIGIT NINE
+1E8D0..1E8D6;N # Mn [7] MENDE KIKAKUI COMBINING NUMBER TEENS..MENDE KIKAKUI COMBINING NUMBER MILLIONS
+1E900..1E943;N # L& [68] ADLAM CAPITAL LETTER ALIF..ADLAM SMALL LETTER SHA
+1E944..1E94A;N # Mn [7] ADLAM ALIF LENGTHENER..ADLAM NUKTA
+1E950..1E959;N # Nd [10] ADLAM DIGIT ZERO..ADLAM DIGIT NINE
+1E95E..1E95F;N # Po [2] ADLAM INITIAL EXCLAMATION MARK..ADLAM INITIAL QUESTION MARK
+1EE00..1EE03;N # Lo [4] ARABIC MATHEMATICAL ALEF..ARABIC MATHEMATICAL DAL
+1EE05..1EE1F;N # Lo [27] ARABIC MATHEMATICAL WAW..ARABIC MATHEMATICAL DOTLESS QAF
+1EE21..1EE22;N # Lo [2] ARABIC MATHEMATICAL INITIAL BEH..ARABIC MATHEMATICAL INITIAL JEEM
+1EE24;N # Lo ARABIC MATHEMATICAL INITIAL HEH
+1EE27;N # Lo ARABIC MATHEMATICAL INITIAL HAH
+1EE29..1EE32;N # Lo [10] ARABIC MATHEMATICAL INITIAL YEH..ARABIC MATHEMATICAL INITIAL QAF
+1EE34..1EE37;N # Lo [4] ARABIC MATHEMATICAL INITIAL SHEEN..ARABIC MATHEMATICAL INITIAL KHAH
+1EE39;N # Lo ARABIC MATHEMATICAL INITIAL DAD
+1EE3B;N # Lo ARABIC MATHEMATICAL INITIAL GHAIN
+1EE42;N # Lo ARABIC MATHEMATICAL TAILED JEEM
+1EE47;N # Lo ARABIC MATHEMATICAL TAILED HAH
+1EE49;N # Lo ARABIC MATHEMATICAL TAILED YEH
+1EE4B;N # Lo ARABIC MATHEMATICAL TAILED LAM
+1EE4D..1EE4F;N # Lo [3] ARABIC MATHEMATICAL TAILED NOON..ARABIC MATHEMATICAL TAILED AIN
+1EE51..1EE52;N # Lo [2] ARABIC MATHEMATICAL TAILED SAD..ARABIC MATHEMATICAL TAILED QAF
+1EE54;N # Lo ARABIC MATHEMATICAL TAILED SHEEN
+1EE57;N # Lo ARABIC MATHEMATICAL TAILED KHAH
+1EE59;N # Lo ARABIC MATHEMATICAL TAILED DAD
+1EE5B;N # Lo ARABIC MATHEMATICAL TAILED GHAIN
+1EE5D;N # Lo ARABIC MATHEMATICAL TAILED DOTLESS NOON
+1EE5F;N # Lo ARABIC MATHEMATICAL TAILED DOTLESS QAF
+1EE61..1EE62;N # Lo [2] ARABIC MATHEMATICAL STRETCHED BEH..ARABIC MATHEMATICAL STRETCHED JEEM
+1EE64;N # Lo ARABIC MATHEMATICAL STRETCHED HEH
+1EE67..1EE6A;N # Lo [4] ARABIC MATHEMATICAL STRETCHED HAH..ARABIC MATHEMATICAL STRETCHED KAF
+1EE6C..1EE72;N # Lo [7] ARABIC MATHEMATICAL STRETCHED MEEM..ARABIC MATHEMATICAL STRETCHED QAF
+1EE74..1EE77;N # Lo [4] ARABIC MATHEMATICAL STRETCHED SHEEN..ARABIC MATHEMATICAL STRETCHED KHAH
+1EE79..1EE7C;N # Lo [4] ARABIC MATHEMATICAL STRETCHED DAD..ARABIC MATHEMATICAL STRETCHED DOTLESS BEH
+1EE7E;N # Lo ARABIC MATHEMATICAL STRETCHED DOTLESS FEH
+1EE80..1EE89;N # Lo [10] ARABIC MATHEMATICAL LOOPED ALEF..ARABIC MATHEMATICAL LOOPED YEH
+1EE8B..1EE9B;N # Lo [17] ARABIC MATHEMATICAL LOOPED LAM..ARABIC MATHEMATICAL LOOPED GHAIN
+1EEA1..1EEA3;N # Lo [3] ARABIC MATHEMATICAL DOUBLE-STRUCK BEH..ARABIC MATHEMATICAL DOUBLE-STRUCK DAL
+1EEA5..1EEA9;N # Lo [5] ARABIC MATHEMATICAL DOUBLE-STRUCK WAW..ARABIC MATHEMATICAL DOUBLE-STRUCK YEH
+1EEAB..1EEBB;N # Lo [17] ARABIC MATHEMATICAL DOUBLE-STRUCK LAM..ARABIC MATHEMATICAL DOUBLE-STRUCK GHAIN
+1EEF0..1EEF1;N # Sm [2] ARABIC MATHEMATICAL OPERATOR MEEM WITH HAH WITH TATWEEL..ARABIC MATHEMATICAL OPERATOR HAH WITH DAL
+1F000..1F003;N # So [4] MAHJONG TILE EAST WIND..MAHJONG TILE NORTH WIND
+1F004;W # So MAHJONG TILE RED DRAGON
+1F005..1F02B;N # So [39] MAHJONG TILE GREEN DRAGON..MAHJONG TILE BACK
+1F030..1F093;N # So [100] DOMINO TILE HORIZONTAL BACK..DOMINO TILE VERTICAL-06-06
+1F0A0..1F0AE;N # So [15] PLAYING CARD BACK..PLAYING CARD KING OF SPADES
+1F0B1..1F0BF;N # So [15] PLAYING CARD ACE OF HEARTS..PLAYING CARD RED JOKER
+1F0C1..1F0CE;N # So [14] PLAYING CARD ACE OF DIAMONDS..PLAYING CARD KING OF DIAMONDS
+1F0CF;W # So PLAYING CARD BLACK JOKER
+1F0D1..1F0F5;N # So [37] PLAYING CARD ACE OF CLUBS..PLAYING CARD TRUMP-21
+1F100..1F10A;A # No [11] DIGIT ZERO FULL STOP..DIGIT NINE COMMA
+1F10B..1F10C;N # No [2] DINGBAT CIRCLED SANS-SERIF DIGIT ZERO..DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ZERO
+1F110..1F12D;A # So [30] PARENTHESIZED LATIN CAPITAL LETTER A..CIRCLED CD
+1F12E;N # So CIRCLED WZ
+1F130..1F169;A # So [58] SQUARED LATIN CAPITAL LETTER A..NEGATIVE CIRCLED LATIN CAPITAL LETTER Z
+1F16A..1F16B;N # So [2] RAISED MC SIGN..RAISED MD SIGN
+1F170..1F18D;A # So [30] NEGATIVE SQUARED LATIN CAPITAL LETTER A..NEGATIVE SQUARED SA
+1F18E;W # So NEGATIVE SQUARED AB
+1F18F..1F190;A # So [2] NEGATIVE SQUARED WC..SQUARE DJ
+1F191..1F19A;W # So [10] SQUARED CL..SQUARED VS
+1F19B..1F1AC;A # So [18] SQUARED THREE D..SQUARED VOD
+1F1E6..1F1FF;N # So [26] REGIONAL INDICATOR SYMBOL LETTER A..REGIONAL INDICATOR SYMBOL LETTER Z
+1F200..1F202;W # So [3] SQUARE HIRAGANA HOKA..SQUARED KATAKANA SA
+1F210..1F23B;W # So [44] SQUARED CJK UNIFIED IDEOGRAPH-624B..SQUARED CJK UNIFIED IDEOGRAPH-914D
+1F240..1F248;W # So [9] TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-672C..TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-6557
+1F250..1F251;W # So [2] CIRCLED IDEOGRAPH ADVANTAGE..CIRCLED IDEOGRAPH ACCEPT
+1F260..1F265;W # So [6] ROUNDED SYMBOL FOR FU..ROUNDED SYMBOL FOR CAI
+1F300..1F320;W # So [33] CYCLONE..SHOOTING STAR
+1F321..1F32C;N # So [12] THERMOMETER..WIND BLOWING FACE
+1F32D..1F335;W # So [9] HOT DOG..CACTUS
+1F336;N # So HOT PEPPER
+1F337..1F37C;W # So [70] TULIP..BABY BOTTLE
+1F37D;N # So FORK AND KNIFE WITH PLATE
+1F37E..1F393;W # So [22] BOTTLE WITH POPPING CORK..GRADUATION CAP
+1F394..1F39F;N # So [12] HEART WITH TIP ON THE LEFT..ADMISSION TICKETS
+1F3A0..1F3CA;W # So [43] CAROUSEL HORSE..SWIMMER
+1F3CB..1F3CE;N # So [4] WEIGHT LIFTER..RACING CAR
+1F3CF..1F3D3;W # So [5] CRICKET BAT AND BALL..TABLE TENNIS PADDLE AND BALL
+1F3D4..1F3DF;N # So [12] SNOW CAPPED MOUNTAIN..STADIUM
+1F3E0..1F3F0;W # So [17] HOUSE BUILDING..EUROPEAN CASTLE
+1F3F1..1F3F3;N # So [3] WHITE PENNANT..WAVING WHITE FLAG
+1F3F4;W # So WAVING BLACK FLAG
+1F3F5..1F3F7;N # So [3] ROSETTE..LABEL
+1F3F8..1F3FA;W # So [3] BADMINTON RACQUET AND SHUTTLECOCK..AMPHORA
+1F3FB..1F3FF;W # Sk [5] EMOJI MODIFIER FITZPATRICK TYPE-1-2..EMOJI MODIFIER FITZPATRICK TYPE-6
+1F400..1F43E;W # So [63] RAT..PAW PRINTS
+1F43F;N # So CHIPMUNK
+1F440;W # So EYES
+1F441;N # So EYE
+1F442..1F4FC;W # So [187] EAR..VIDEOCASSETTE
+1F4FD..1F4FE;N # So [2] FILM PROJECTOR..PORTABLE STEREO
+1F4FF..1F53D;W # So [63] PRAYER BEADS..DOWN-POINTING SMALL RED TRIANGLE
+1F53E..1F54A;N # So [13] LOWER RIGHT SHADOWED WHITE CIRCLE..DOVE OF PEACE
+1F54B..1F54E;W # So [4] KAABA..MENORAH WITH NINE BRANCHES
+1F54F;N # So BOWL OF HYGIEIA
+1F550..1F567;W # So [24] CLOCK FACE ONE OCLOCK..CLOCK FACE TWELVE-THIRTY
+1F568..1F579;N # So [18] RIGHT SPEAKER..JOYSTICK
+1F57A;W # So MAN DANCING
+1F57B..1F594;N # So [26] LEFT HAND TELEPHONE RECEIVER..REVERSED VICTORY HAND
+1F595..1F596;W # So [2] REVERSED HAND WITH MIDDLE FINGER EXTENDED..RAISED HAND WITH PART BETWEEN MIDDLE AND RING FINGERS
+1F597..1F5A3;N # So [13] WHITE DOWN POINTING LEFT HAND INDEX..BLACK DOWN POINTING BACKHAND INDEX
+1F5A4;W # So BLACK HEART
+1F5A5..1F5FA;N # So [86] DESKTOP COMPUTER..WORLD MAP
+1F5FB..1F5FF;W # So [5] MOUNT FUJI..MOYAI
+1F600..1F64F;W # So [80] GRINNING FACE..PERSON WITH FOLDED HANDS
+1F650..1F67F;N # So [48] NORTH WEST POINTING LEAF..REVERSE CHECKER BOARD
+1F680..1F6C5;W # So [70] ROCKET..LEFT LUGGAGE
+1F6C6..1F6CB;N # So [6] TRIANGLE WITH ROUNDED CORNERS..COUCH AND LAMP
+1F6CC;W # So SLEEPING ACCOMMODATION
+1F6CD..1F6CF;N # So [3] SHOPPING BAGS..BED
+1F6D0..1F6D2;W # So [3] PLACE OF WORSHIP..SHOPPING TROLLEY
+1F6D3..1F6D4;N # So [2] STUPA..PAGODA
+1F6E0..1F6EA;N # So [11] HAMMER AND WRENCH..NORTHEAST-POINTING AIRPLANE
+1F6EB..1F6EC;W # So [2] AIRPLANE DEPARTURE..AIRPLANE ARRIVING
+1F6F0..1F6F3;N # So [4] SATELLITE..PASSENGER SHIP
+1F6F4..1F6F8;W # So [5] SCOOTER..FLYING SAUCER
+1F700..1F773;N # So [116] ALCHEMICAL SYMBOL FOR QUINTESSENCE..ALCHEMICAL SYMBOL FOR HALF OUNCE
+1F780..1F7D4;N # So [85] BLACK LEFT-POINTING ISOSCELES RIGHT TRIANGLE..HEAVY TWELVE POINTED PINWHEEL STAR
+1F800..1F80B;N # So [12] LEFTWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD..DOWNWARDS ARROW WITH LARGE TRIANGLE ARROWHEAD
+1F810..1F847;N # So [56] LEFTWARDS ARROW WITH SMALL EQUILATERAL ARROWHEAD..DOWNWARDS HEAVY ARROW
+1F850..1F859;N # So [10] LEFTWARDS SANS-SERIF ARROW..UP DOWN SANS-SERIF ARROW
+1F860..1F887;N # So [40] WIDE-HEADED LEFTWARDS LIGHT BARB ARROW..WIDE-HEADED SOUTH WEST VERY HEAVY BARB ARROW
+1F890..1F8AD;N # So [30] LEFTWARDS TRIANGLE ARROWHEAD..WHITE ARROW SHAFT WIDTH TWO THIRDS
+1F900..1F90B;N # So [12] CIRCLED CROSS FORMEE WITH FOUR DOTS..DOWNWARD FACING NOTCHED HOOK WITH DOT
+1F910..1F93E;W # So [47] ZIPPER-MOUTH FACE..HANDBALL
+1F940..1F94C;W # So [13] WILTED FLOWER..CURLING STONE
+1F950..1F96B;W # So [28] CROISSANT..CANNED FOOD
+1F980..1F997;W # So [24] CRAB..CRICKET
+1F9C0;W # So CHEESE WEDGE
+1F9D0..1F9E6;W # So [23] FACE WITH MONOCLE..SOCKS
+20000..2A6D6;W # Lo [42711] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6D6
+2A6D7..2A6FF;W # Cn [41] <reserved-2A6D7>..<reserved-2A6FF>
+2A700..2B734;W # Lo [4149] CJK UNIFIED IDEOGRAPH-2A700..CJK UNIFIED IDEOGRAPH-2B734
+2B735..2B73F;W # Cn [11] <reserved-2B735>..<reserved-2B73F>
+2B740..2B81D;W # Lo [222] CJK UNIFIED IDEOGRAPH-2B740..CJK UNIFIED IDEOGRAPH-2B81D
+2B81E..2B81F;W # Cn [2] <reserved-2B81E>..<reserved-2B81F>
+2B820..2CEA1;W # Lo [5762] CJK UNIFIED IDEOGRAPH-2B820..CJK UNIFIED IDEOGRAPH-2CEA1
+2CEA2..2CEAF;W # Cn [14] <reserved-2CEA2>..<reserved-2CEAF>
+2CEB0..2EBE0;W # Lo [7473] CJK UNIFIED IDEOGRAPH-2CEB0..CJK UNIFIED IDEOGRAPH-2EBE0
+2EBE1..2F7FF;W # Cn [3103] <reserved-2EBE1>..<reserved-2F7FF>
+2F800..2FA1D;W # Lo [542] CJK COMPATIBILITY IDEOGRAPH-2F800..CJK COMPATIBILITY IDEOGRAPH-2FA1D
+2FA1E..2FFFD;W # Cn [1504] <reserved-2FA1E>..<reserved-2FFFD>
+30000..3FFFD;W # Cn [65534] <reserved-30000>..<reserved-3FFFD>
+E0001;N # Cf LANGUAGE TAG
+E0020..E007F;N # Cf [96] TAG SPACE..CANCEL TAG
+E0100..E01EF;A # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256
+F0000..FFFFD;A # Co [65534] <private-use-F0000>..<private-use-FFFFD>
+100000..10FFFD;A # Co [65534] <private-use-100000>..<private-use-10FFFD>
+
+# EOF
diff --git a/Makefile.in b/Makefile.in
index a803b07..67d503c 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,3 +1,18 @@
+@if NO_SILENT_RULES
+Q :=
+ECHO := @:
+@else
+# make V=1 for verbose make output
+Q := @
+ECHO := @echo
+ifeq ($(V),1)
+ifeq ("$(origin V)", "command line")
+Q :=
+ECHO := @:
+endif
+endif
+@endif
+
# Tools
CC = @CCACHE@ @CC@
CXX = @CCACHE@ @CXX@
@@ -29,7 +44,7 @@ docdir = @docdir@
CC += -Wall $(OPTIM) -I.
CXX += -Wall $(OPTIM) -I.
-@if srcdir != .
+@if [get-define srcdir] ne "."
CFLAGS += -I@srcdir@
CXXFLAGS += -I@srcdir@
VPATH := @srcdir@
@@ -51,7 +66,7 @@ JIMSH_CC := $(CXX) $(CXXFLAGS)
JIMSH_CC := $(CC) $(CFLAGS)
@endif
-OBJS := _load-static-exts.o jim-subcmd.o jim-interactive.o jim-format.o jim.o utf8.o jimregexp.o \
+OBJS := _load-static-exts.o jim-subcmd.o jim-interactive.o jim-format.o jim.o utf8.o jimregexp.o jimiocompat.o \
@EXTRA_OBJS@ @C_EXT_OBJS@ @TCL_EXT_OBJS@
JIMSH := jimsh@EXEEXT@
@@ -67,21 +82,18 @@ all: $(JIMSH) @C_EXT_SHOBJS@
# Create C extensions from pure Tcl extensions
.SUFFIXES: .tcl
.tcl.o:
- @tclsh@ @srcdir@/make-c-ext.tcl $< >_$*.c
- $(CC) $(CFLAGS) -c -o $@ _$*.c
+ $(ECHO) " TCLEXT _$*.c"
+ $(Q)@tclsh@ @srcdir@/make-c-ext.tcl $< >_$*.c
+ $(ECHO) " CC $@"
+ $(Q)$(CC) $(CFLAGS) -c -o $@ _$*.c
-docs: Tcl.html
-
-@if JIM_DOCS
-install-docs: docs
- $(INSTALL_DATA_DIR) $(DESTDIR)$(docdir)
- $(INSTALL_DATA) Tcl.html $(DESTDIR)$(docdir)
-@else
-install-docs:
-@endif
+.c.o:
+ $(ECHO) " CC $@"
+ $(Q)$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
$(JIMSH): $(LIBJIM) jimsh.o initjimsh.o
- $(JIMSH_CC) @SH_LINKFLAGS@ $(LDFLAGS) -o $@ jimsh.o initjimsh.o $(LIBJIM) $(LDLIBS) $(LIBS)
+ $(ECHO) " LINK $@"
+ $(Q)$(JIMSH_CC) @SH_LINKRPATH_FLAGS@ @SH_LINKFLAGS@ $(LDFLAGS) -o $@ jimsh.o initjimsh.o $(LIBJIM) $(LDLIBS) $(LIBS)
@if JIM_INSTALL
install: all @TCL_EXTS@ install-exec install-docs
@@ -95,6 +107,8 @@ install: all @TCL_EXTS@ install-exec install-docs
$(INSTALL_DATA) jim-config.h $(DESTDIR)@includedir@
$(INSTALL_DATA_DIR) $(DESTDIR)@bindir@
$(INSTALL_DATA) build-jim-ext $(DESTDIR)@bindir@
+ $(INSTALL_DATA_DIR) $(DESTDIR)@libdir@/pkgconfig
+ $(INSTALL_DATA) jimtcl.pc $(DESTDIR)@libdir@/pkgconfig
install-exec: all
$(INSTALL_DATA_DIR) $(DESTDIR)@bindir@
@@ -113,103 +127,67 @@ uninstall:
@endif
test check: $(JIMSH)
- cd @srcdir@/tests; $(DEF_LD_PATH) $(MAKE) jimsh=@builddir@/jimsh TOPSRCDIR=@top_srcdir@
+ cd @srcdir@/tests; $(DEF_LD_PATH) $(MAKE) jimsh=@builddir@/jimsh TOPSRCDIR=..
-$(OBJS): Makefile $(wildcard *.h)
+$(OBJS) jimsh.o initjimsh.o: Makefile $(wildcard *.h)
@if JIM_UTF8
# Generate the unicode case mapping
utf8.o: _unicode_mapping.c
_unicode_mapping.c: @srcdir@/UnicodeData.txt @srcdir@/parse-unidata.tcl
- @tclsh@ @srcdir@/parse-unidata.tcl @srcdir@/UnicodeData.txt >$@ || ( rm $@; exit 1)
+ $(ECHO) " UNIDATA $@"
+ $(Q)@tclsh@ @srcdir@/parse-unidata.tcl @PARSE_UNIDATA_FLAGS@ @srcdir@/UnicodeData.txt @srcdir@/EastAsianWidth.txt >$@ || ( rm $@; exit 1)
@endif
_load-static-exts.c: @srcdir@/make-load-static-exts.tcl Makefile
- @tclsh@ @srcdir@/make-load-static-exts.tcl @STATIC_EXTS@ >$@ || ( rm $@; exit 1)
+ $(ECHO) " MKLDEXT $@"
+ $(Q)@tclsh@ @srcdir@/make-load-static-exts.tcl @STATIC_EXTS@ >$@ || ( rm $@; exit 1)
-@if JIM_STATICLIB
$(LIBJIM): $(OBJS)
- $(AR) cr $@ $(OBJS)
- $(RANLIB) $@
+@if JIM_STATICLIB
+ $(ECHO) " AR $@"
+ $(Q)$(AR) cr $@ $(OBJS)
+ $(Q)$(RANLIB) $@
@else
-$(LIBJIM): $(OBJS)
- $(CC) $(CFLAGS) $(LDFLAGS) $(SH_LDFLAGS) -o $@ $(OBJS) $(LDLIBS) $(LIBS)
+ $(ECHO) " LDSO $@"
+ $(Q)$(CC) $(CFLAGS) $(LDFLAGS) $(SH_LDFLAGS) -o $@ $(OBJS) $(LDLIBS) $(LIBS)
@endif
-# Note that $> $^ is for compatibility with both GNU make and BSD make
-readdir.so: jim-readdir.c
- $(CC) $(CFLAGS) $(SHOBJ_CFLAGS) -c -o jim-readdir.o $> $^
- $(CC) $(CFLAGS) $(LDFLAGS) $(SHOBJ_LDFLAGS) -o $@ jim-readdir.o $(SH_LIBJIM)
-
-array.so: jim-array.c
- $(CC) $(CFLAGS) $(SHOBJ_CFLAGS) -c -o jim-array.o $> $^
- $(CC) $(CFLAGS) $(LDFLAGS) $(SHOBJ_LDFLAGS) -o $@ jim-array.o $(SH_LIBJIM)
-
-clock.so: jim-clock.c
- $(CC) $(CFLAGS) $(SHOBJ_CFLAGS) -c -o jim-clock.o $> $^
- $(CC) $(CFLAGS) $(LDFLAGS) $(SHOBJ_LDFLAGS) -o $@ jim-clock.o $(SH_LIBJIM)
-
-file.so: jim-file.c
- $(CC) $(CFLAGS) $(SHOBJ_CFLAGS) -c -o jim-file.o $> $^
- $(CC) $(CFLAGS) $(LDFLAGS) $(SHOBJ_LDFLAGS) -o $@ jim-file.o $(SH_LIBJIM)
-
-interp.so: jim-interp.c
- $(CC) $(CFLAGS) $(SHOBJ_CFLAGS) -c -o jim-interp.o jim-interp.c
- $(CC) $(CFLAGS) $(LDFLAGS) $(SHOBJ_LDFLAGS) -o $@ jim-interp.o $(SH_LIBJIM) @LDLIBS_interp@
-
-posix.so: jim-posix.c
- $(CC) $(CFLAGS) $(SHOBJ_CFLAGS) -c -o jim-posix.o $> $^
- $(CC) $(CFLAGS) $(LDFLAGS) $(SHOBJ_LDFLAGS) -o $@ jim-posix.o $(SH_LIBJIM)
+@BUILD_SHOBJS@
-regexp.so: jim-regexp.c
- $(CC) $(CFLAGS) $(SHOBJ_CFLAGS) -c -o jim-regexp.o $> $^
- $(CC) $(CFLAGS) $(LDFLAGS) $(SHOBJ_LDFLAGS) -o $@ jim-regexp.o $(SH_LIBJIM)
-
-syslog.so: jim-syslog.c
- $(CC) $(CFLAGS) $(SHOBJ_CFLAGS) -c -o jim-syslog.o $> $^
- $(CC) $(CFLAGS) $(LDFLAGS) $(SHOBJ_LDFLAGS) -o $@ jim-syslog.o $(SH_LIBJIM)
-
-readline.so: jim-readline.c
- $(CC) $(CFLAGS) $(SHOBJ_CFLAGS) -c -o jim-readline.o $> $^
- $(CC) $(CFLAGS) $(LDFLAGS) $(SHOBJ_LDFLAGS) -o $@ jim-readline.o $(SH_LIBJIM) @LDLIBS_readline@
-
-pack.so: jim-pack.c
- $(CC) $(CFLAGS) $(SHOBJ_CFLAGS) -c -o jim-pack.o $> $^
- $(CC) $(CFLAGS) $(LDFLAGS) $(SHOBJ_LDFLAGS) -o $@ jim-pack.o $(SH_LIBJIM) @LDLIBS_pack@
-
-tclprefix.so: jim-tclprefix.c
- $(CC) $(CFLAGS) $(SHOBJ_CFLAGS) -c -o jim-tclprefix.o $> $^
- $(CC) $(CFLAGS) $(LDFLAGS) $(SHOBJ_LDFLAGS) -o $@ jim-tclprefix.o $(SH_LIBJIM) @LDLIBS_tclprefix@
-
-sqlite3.so: jim-sqlite3.c
- $(CC) $(CFLAGS) $(SHOBJ_CFLAGS) -c -o jim-sqlite3.o $> $^
- $(CC) $(CFLAGS) $(LDFLAGS) $(SHOBJ_LDFLAGS) -o $@ jim-sqlite3.o $(SH_LIBJIM) @LDLIBS_sqlite3@
-
-win32.so: jim-win32.c
- $(CC) $(CFLAGS) $(SHOBJ_CFLAGS) -c -o jim-win32.o $> $^
- $(CC) $(CFLAGS) $(LDFLAGS) $(SHOBJ_LDFLAGS) -o $@ jim-win32.o $(SH_LIBJIM) @LDLIBS_win32@
+docs: Tcl.html
-mk.so: jim-mk.cpp
- $(CXX) $(CXXFLAGS) $(SHOBJ_CFLAGS) -c -o jim-mk.o $> $^
- $(CXX) $(CXXFLAGS) $(LDFLAGS) $(SHOBJ_LDFLAGS) -o $@ jim-mk.o $(SH_LIBJIM) @LDLIBS_mk@
+@if INSTALL_DOCS eq "nodocs"
+install-docs:
+@endif
-sdl.so: jim-sdl.c
- $(CC) $(CFLAGS) $(SHOBJ_CFLAGS) -c -o jim-sdl.o $> $^
- $(CC) $(CFLAGS) $(LDFLAGS) $(SHOBJ_LDFLAGS) -o $@ jim-sdl.o $(SH_LIBJIM) @LDLIBS_sdl@
+@if INSTALL_DOCS eq "docs"
+install-docs: docs
+ $(INSTALL_DATA_DIR) $(DESTDIR)$(docdir)
+ $(INSTALL_DATA) Tcl.html $(DESTDIR)$(docdir)
+@endif
-zlib.so: jim-zlib.c
- $(CC) $(CFLAGS) $(SHOBJ_CFLAGS) -c -o jim-zlib.o $> $^
- $(CC) $(CFLAGS) $(LDFLAGS) $(SHOBJ_LDFLAGS) -o $@ jim-zlib.o $(SH_LIBJIM) @LDLIBS_zlib@
+@if INSTALL_DOCS eq "shipped"
+install-docs:
+ $(INSTALL_DATA_DIR) $(DESTDIR)$(docdir)
+ @echo "Warning: asciidoc not available - installing Tcl_shipped.html"
+ $(INSTALL_DATA) Tcl_shipped.html $(DESTDIR)$(docdir)/Tcl.html
+@endif
-Tcl.html: jim_tcl.txt
- @tclsh@ @srcdir@/make-index $> $^ | asciidoc -o $@ -d manpage - || cp @srcdir@/Tcl_shipped.html Tcl.html
+Tcl.html: jim_tcl.txt @srcdir@/make-index
+@if HAVE_ASCIIDOC
+ @tclsh@ @srcdir@/make-index $> $^ | @ASCIIDOC@ -d manpage - | @SED@ -e '/^<div.*id="footer-text"/,/<\/div>/d' >$@
+@else
+ @echo "asciidoc is not available"; false
+@endif
clean:
rm -f *.o *.so *.dll *.exe lib*.a $(JIMSH) $(LIBJIM) Tcl.html _*.c
distclean: clean
- rm -f jimautoconf.h jim-config.h Makefile config.log autosetup/jimsh0@EXEEXT@ build-jim-ext
+ rm -f jimautoconf.h jim-config.h Makefile config.log @srcdir@/autosetup/jimsh0@EXEEXT@ build-jim-ext
+ rm -f jimtcl.pc tests/Makefile
ship: Tcl.html
cp $< Tcl_shipped.html
diff --git a/README.utf-8 b/README.utf-8
index 7128d76..4f3cbd5 100644
--- a/README.utf-8
+++ b/README.utf-8
@@ -6,8 +6,8 @@ Date: 2 Nov 2010 10:55:52 EST
OVERVIEW
--------
-Traditionally Jim Tcl has support strings, including binary strings containing
-nulls, however it has had no support for multi-byte character encodings.
+Early versions of Jim Tcl supported strings, including binary strings containing
+nulls, however it had no support for multi-byte character encodings.
In some fields, such as when dealing with the web, or other user-generated content,
support for multi-byte character encodings is necessary.
@@ -16,7 +16,7 @@ as multi-byte character strings rather than simply binary bytes.
Supporting multiple character encodings and translation between those encodings
is beyond the scope of Jim Tcl. Therefore, Jim has been enhanced to add support
-for UTF-8, as probably the most popular general purpose multi-byte encoding.
+for UTF-8, as the most popular general purpose multi-byte encoding.
UTF-8 support is optional. It can be enabled at compile time with:
@@ -31,8 +31,8 @@ It is important to understand that Unicode is an abstract representation
of the concept of a "character", while UTF-8 is an encoding of
Unicode into bytes. Thus the Unicode codepoint U+00B5 is encoded
in UTF-8 with the byte sequence: 0xc2, 0xb5. This is different from
-ASCII which the same name is used interchangeably between a character
-set and an encoding.
+ASCII where the same name is used interchangeably between a character value
+and and its encoding.
Unicode Escapes
---------------
@@ -40,7 +40,10 @@ Even without UTF-8 enabled, it is useful to be able to encode UTF-8 characters
in strings. This can be done with the \uNNNN Unicode escape. This syntax
is compatible with Tcl and is enabled even if UTF-8 is disabled.
-Like Tcl, currently only 16-bit Unicode characters can be encoded.
+Unlike Tcl, Jim Tcl supports Unicode characters up to 21 bits.
+In addition to \uNNNN, Jim Tcl also supports variable length Unicode
+character specifications with \u{NNNNNN} where there may be anywhere between
+1 and 6 hex within the braces. e.g. \u{24B62}
UTF-8 Properties
----------------
@@ -100,16 +103,15 @@ Working with Binary Data and non-UTF-8 encodings
------------------------------------------------
Almost all Jim commands will work identically with binary data and
UTF-8 encoded data, including read, gets, puts and 'string eq'. It
-is only certain string manipulation commands which will operated
-differently. For example, 'string index' will return UTF-8 characters,
-not bytes.
+is only certain string manipulation commands that behave differently.
+For example, 'string index' will return UTF-8 characters, not bytes.
If it is necessary to manipulate strings containing binary, non-ASCII
data (bytes >= 0x80), there are two options.
1. Build Jim without UTF-8 support
-2. Arrange to encode and decode binary data or data in other encodings
- to UTF-8 before manipulation.
+2. Use 'string byterange', 'string bytelength' and 'pack', 'unpack' and
+ 'binary' to operate on strings as bytes rather than characters.
Internal Details
----------------
@@ -120,4 +122,5 @@ terminated (which it always will be).
It is possible to tell if a string is ascii-only because length == bytelength
It is possible to provide optimised versions of various routines for
-the ascii-only case. Currently this is done only for 'string index' and 'string range'.
+the ascii-only case. Both 'string index' and 'string range' currently
+perform such optimisation.
diff --git a/TODO b/TODO
index fc62aef..68e74fe 100644
--- a/TODO
+++ b/TODO
@@ -1,13 +1,10 @@
CORE LANGUAGE FEATURES
-CORE COMMANDS
+- none
-- [onleave] command, executing something as soon as the current procedure
- returns. With no arguments it returns the script set, with one appends
- the onleave script. There should be a way to reset.
+CORE COMMANDS
- Currently we have [local] which can be used to delete procs on proc exit.
- Also try/on/finally. Is [onleave] really needed?
+- none
OTHER COMMANDS NOT IN TCL BUT THAT SHOULD BE IN JIM
@@ -17,7 +14,6 @@ EXTENSIONS
- Cryptography: hash functions, block ciphers, strim ciphers, PRNGs.
- Tuplespace extension (http://wiki.tcl.tk/3947) (using sqlite as backend)
-- Zlib
- Gdlib
- CGI (interface compatible with ncgi, but possibly written in C for speed)
diff --git a/Tcl_shipped.html b/Tcl_shipped.html
index 5e289f8..e27ed2f 100644
--- a/Tcl_shipped.html
+++ b/Tcl_shipped.html
@@ -1,9 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
-<meta name="generator" content="AsciiDoc 8.6.9" />
+<meta name="generator" content="AsciiDoc 8.6.10" />
<title>Jim Tcl(n)</title>
<style type="text/css">
/* Shared CSS for AsciiDoc xhtml11 and html5 backends */
@@ -738,7 +739,7 @@ Jim Tcl(n) Manual Page
</h1>
<h2>NAME</h2>
<div class="sectionbody">
-<p>Jim Tcl v0.77 -
+<p>Jim Tcl v0.79 -
reference manual for the Jim Tcl scripting language
</p>
</div>
@@ -754,9 +755,10 @@ Jim Tcl(n) Manual Page
<div class="paragraph"><p>or</p></div>
<div class="literalblock">
<div class="content">
-<pre><code>jimsh [&lt;scriptfile&gt;]
+<pre><code>jimsh [&lt;scriptfile&gt;|-]
jimsh -e '&lt;immediate-script&gt;'
-jimsh --version</code></pre>
+jimsh --version
+jimsh --help</code></pre>
</div></div>
<div class="ulist"><div class="title">Quick Index</div><ul>
<li>
@@ -823,7 +825,7 @@ Builtin dictionary type (<a href="#_dict"><strong><code>dict</code></strong></a>
</li>
<li>
<p>
-Operating system features: <a href="#cmd_1"><strong><code>os.fork</code></strong></a>, <a href="#cmd_1"><strong><code>os.wait</code></strong></a>, <a href="#cmd_1"><strong><code>os.uptime</code></strong></a>, <a href="#_signal"><strong><code>signal</code></strong></a>, <a href="#_alarm"><strong><code>alarm</code></strong></a>, <a href="#_sleep"><strong><code>sleep</code></strong></a>
+Operating system features: <a href="#cmd_1"><strong><code>os.fork</code></strong></a>, <a href="#cmd_1"><strong><code>os.uptime</code></strong></a>, <a href="#_wait"><strong><code>wait</code></strong></a>, <a href="#_signal"><strong><code>signal</code></strong></a>, <a href="#_alarm"><strong><code>alarm</code></strong></a>, <a href="#_sleep"><strong><code>sleep</code></strong></a>
</p>
</li>
<li>
@@ -878,336 +880,226 @@ Support for UDP, IPv6, Unix-Domain sockets in addition to TCP sockets
<h2 id="_recent_changes">RECENT CHANGES</h2>
<div class="sectionbody">
<div class="sect2">
-<h3 id="_changes_between_0_76_and_0_77">Changes between 0.76 and 0.77</h3>
+<h3 id="_changes_between_0_78_and_0_79">Changes between 0.78 and 0.79</h3>
<div class="olist arabic"><ol class="arabic">
<li>
<p>
-Add support for <a href="#_aio"><strong><code>aio</code></strong></a> <code>sync</code>
+Add <a href="#_file"><strong><code>file</code></strong></a> <code>mtimeus</code> for high resolution file timestamps
</p>
</li>
<li>
<p>
-Add SSL and TLS support in aio
+<a href="#_aio"><strong><code>aio</code></strong></a> now supports datagram Unix-Domain sockets
</p>
</li>
<li>
<p>
-Added <a href="#_zlib"><strong><code>zlib</code></strong></a>
+Add support for <a href="#_aio"><strong><code>aio</code></strong></a> <code>lock -wait</code>
</p>
</li>
<li>
<p>
-Added support for boolean constants in <a href="#_expr"><strong><code>expr</code></strong></a>
+Add <a href="#_signal"><strong><code>signal</code></strong></a> <code>block</code> to prevent delivery of signals
</p>
</li>
<li>
<p>
-<a href="#_string"><strong><code>string</code></strong></a> <code>is</code> now supports <em>boolean</em> class
+Add support for <a href="#_file"><strong><code>file</code></strong></a> <code>split</code>
</p>
</li>
<li>
<p>
-Add support for <a href="#_aio"><strong><code>aio</code></strong></a> <code>lock</code> and <a href="#_aio"><strong><code>aio</code></strong></a> <code>unlock</code>
+Add support for <a href="#_json_encode"><strong><code>json::encode</code></strong></a> and <a href="#_json_decode"><strong><code>json::decode</code></strong></a>
</p>
</li>
<li>
<p>
-Add new <a href="#_interp"><strong><code>interp</code></strong></a> command
+<a href="#_aio"><strong><code>aio</code></strong></a> <code>tty</code> now allows setting <code>echo</code> without full <code>raw</code> mode
</p>
</li>
</ol></div>
</div>
<div class="sect2">
-<h3 id="_changes_between_0_75_and_0_76">Changes between 0.75 and 0.76</h3>
+<h3 id="_changes_between_0_77_and_0_78">Changes between 0.77 and 0.78</h3>
<div class="olist arabic"><ol class="arabic">
<li>
<p>
-<a href="#_glob"><strong><code>glob</code></strong></a> now supports the <code>-tails</code> option
+Add serial/tty support with <a href="#_aio"><strong><code>aio</code></strong></a> <code>tty</code>
</p>
</li>
<li>
<p>
-Add support for <a href="#_string"><strong><code>string</code></strong></a> <code>cat</code>
+Add support for <em>jimsh -</em>
</p>
</li>
<li>
<p>
-Allow <a href="#_info"><strong><code>info</code></strong></a> <code>source</code> to add source info
+Add hidden <em>-commands</em> option to many commands
</p>
</li>
-</ol></div>
-</div>
-<div class="sect2">
-<h3 id="_changes_between_0_74_and_0_75">Changes between 0.74 and 0.75</h3>
-<div class="olist arabic"><ol class="arabic">
<li>
<p>
-<a href="#_binary"><strong><code>binary</code></strong></a>, <a href="#cmd_3"><strong><code>pack</code></strong></a> and <a href="#cmd_3"><strong><code>unpack</code></strong></a> now support floating point
+Add scriptable autocompletion support in interactive mode with <a href="#_tcl_autocomplete"><strong><code>tcl::autocomplete</code></strong></a>
</p>
</li>
<li>
<p>
-<a href="#_file"><strong><code>file</code></strong></a> <code>copy</code> <code>-force</code> handles source and target as the same file
+Add <a href="#_aio"><strong><code>aio</code></strong></a> <code>sockopt</code>
</p>
</li>
<li>
<p>
-<a href="#_format"><strong><code>format</code></strong></a> now supports <code>%b</code> for binary conversion
+Add scriptable autocompletion support with <a href="#_history"><strong><code>history</code></strong></a> <code>completion</code>
</p>
</li>
<li>
<p>
-<a href="#_lsort"><strong><code>lsort</code></strong></a> now supports <code>-unique</code> and <code>-real</code>
+Add support for <a href="#_tree"><strong><code>tree</code></strong></a> <code>delete</code>
</p>
</li>
<li>
<p>
-Add support for half-close with <a href="#_aio"><strong><code>aio</code></strong></a> <code>close</code> <code>?r|w?</code>
+Add support for <a href="#_defer"><strong><code>defer</code></strong></a> and <em>$jim::defer</em>
</p>
</li>
<li>
<p>
-Add <a href="#_socket"><strong><code>socket</code></strong></a> <code>pair</code> for a bidirectional pipe
+Renamed <code>os.wait</code> to <a href="#_wait"><strong><code>wait</code></strong></a>, now more Tcl-compatible and compatible with <a href="#_exec"><strong><code>exec</code></strong></a> <code>... &amp;</code>
</p>
</li>
<li>
<p>
-Add <em>--random-hash</em> to randomise hash tables for greater security
+<a href="#_pipe"><strong><code>pipe</code></strong></a> is now a synonym for <a href="#_socket"><strong><code>socket</code></strong></a> <code>pipe</code>
</p>
</li>
<li>
<p>
-<a href="#_dict"><strong><code>dict</code></strong></a> now supports <em>for</em>, <em>values</em>, <em>incr</em>, <em>append</em>, <em>lappend</em>, <em>update</em>, <em>info</em> and <em>replace</em>
+Closing a pipe open with <a href="#_open"><strong><code>open</code></strong></a> <code>|...</code> now returns Tcl-like status
</p>
</li>
<li>
<p>
-<a href="#_file"><strong><code>file</code></strong></a> <code>stat</code> no longer requires the variable name
+It is now possible to used <a href="#_exec"><strong><code>exec</code></strong></a> redirection with a pipe opened with <a href="#_open"><strong><code>open</code></strong></a> <code>|...</code>
</p>
</li>
<li>
<p>
-Add support for <a href="#_file"><strong><code>file</code></strong></a> <code>link</code>
+Interactive line editing now supports multiline mode if $::history::multiline is set
</p>
</li>
</ol></div>
</div>
<div class="sect2">
-<h3 id="_changes_between_0_73_and_0_74">Changes between 0.73 and 0.74</h3>
-<div class="olist arabic"><ol class="arabic">
-<li>
-<p>
-Numbers with leading zeros are treated as decimal, not octal
-</p>
-</li>
-<li>
-<p>
-Add <a href="#_aio"><strong><code>aio</code></strong></a> <code>isatty</code>
-</p>
-</li>
-<li>
-<p>
-Add LFS (64 bit) support for <a href="#_aio"><strong><code>aio</code></strong></a> <code>seek</code>, <a href="#_aio"><strong><code>aio</code></strong></a> <code>tell</code>, <a href="#_aio"><strong><code>aio</code></strong></a> <code>copyto</code>, <a href="#_file"><strong><code>file</code></strong></a> <code>copy</code>
-</p>
-</li>
-<li>
-<p>
-<a href="#_string"><strong><code>string</code></strong></a> <code>compare</code> and <a href="#_string"><strong><code>string</code></strong></a> <code>equal</code> now support <em>-length</em>
-</p>
-</li>
-<li>
-<p>
-<a href="#_glob"><strong><code>glob</code></strong></a> now supports <em>-directory</em>
-</p>
-</li>
-</ol></div>
-</div>
-<div class="sect2">
-<h3 id="_changes_between_0_72_and_0_73">Changes between 0.72 and 0.73</h3>
+<h3 id="_changes_between_0_76_and_0_77">Changes between 0.76 and 0.77</h3>
<div class="olist arabic"><ol class="arabic">
<li>
<p>
-Built-in regexp now support non-capturing parentheses: (?:&#8230;)
-</p>
-</li>
-<li>
-<p>
-Add <a href="#_string"><strong><code>string</code></strong></a> <code>replace</code>
-</p>
-</li>
-<li>
-<p>
-Add <a href="#_string"><strong><code>string</code></strong></a> <code>totitle</code>
-</p>
-</li>
-<li>
-<p>
-Add <a href="#_info"><strong><code>info</code></strong></a> <code>statics</code>
-</p>
-</li>
-<li>
-<p>
-Add <code>build-jim-ext</code> for easy separate building of loadable modules (extensions)
-</p>
-</li>
-<li>
-<p>
-<a href="#_local"><strong><code>local</code></strong></a> now works with any command, not just procs
-</p>
-</li>
-<li>
-<p>
-Add <a href="#_info"><strong><code>info</code></strong></a> <code>alias</code> to access the target of an alias
+Add support for <a href="#_aio"><strong><code>aio</code></strong></a> <code>sync</code>
</p>
</li>
<li>
<p>
-UTF-8 encoding past the basic multilingual plane (BMP) is supported
+Add SSL and TLS support in aio
</p>
</li>
<li>
<p>
-Add <a href="#_tcl_prefix"><strong><code>tcl::prefix</code></strong></a>
+Added <a href="#_zlib"><strong><code>zlib</code></strong></a>
</p>
</li>
<li>
<p>
-Add <a href="#_history"><strong><code>history</code></strong></a>
+Added support for boolean constants in <a href="#_expr"><strong><code>expr</code></strong></a>
</p>
</li>
<li>
<p>
-Most extensions are now enabled by default
+<a href="#_string"><strong><code>string</code></strong></a> <code>is</code> now supports <em>boolean</em> class
</p>
</li>
<li>
<p>
-Add support for namespaces and the <a href="#_namespace"><strong><code>namespace</code></strong></a> command
+Add support for <a href="#_aio"><strong><code>aio</code></strong></a> <code>lock</code> and <a href="#_aio"><strong><code>aio</code></strong></a> <code>unlock</code>
</p>
</li>
<li>
<p>
-Add <a href="#_apply"><strong><code>apply</code></strong></a>
+Add new <a href="#_interp"><strong><code>interp</code></strong></a> command
</p>
</li>
</ol></div>
</div>
<div class="sect2">
-<h3 id="_changes_between_0_71_and_0_72">Changes between 0.71 and 0.72</h3>
+<h3 id="_changes_between_0_75_and_0_76">Changes between 0.75 and 0.76</h3>
<div class="olist arabic"><ol class="arabic">
<li>
<p>
-procs now allow <em>args</em> and optional parameters in any position
-</p>
-</li>
-<li>
-<p>
-Add Tcl-compatible expr functions, <code>rand()</code>, <code>srand()</code> and <code>pow()</code>
-</p>
-</li>
-<li>
-<p>
-Add support for the <em>-force</em> option to <a href="#_file"><strong><code>file</code></strong></a> <code>delete</code>
-</p>
-</li>
-<li>
-<p>
-Better diagnostics when <a href="#_source"><strong><code>source</code></strong></a> fails to load a script with a missing quote or bracket
-</p>
-</li>
-<li>
-<p>
-New <code>tcl_platform(pathSeparator)</code>
-</p>
-</li>
-<li>
-<p>
-Add support settings the modification time with <a href="#_file"><strong><code>file</code></strong></a> <code>mtime</code>
-</p>
-</li>
-<li>
-<p>
-<a href="#_exec"><strong><code>exec</code></strong></a> is now fully supported on win32 (mingw32)
-</p>
-</li>
-<li>
-<p>
-<a href="#_file"><strong><code>file</code></strong></a> <code>join</code>, <a href="#_pwd"><strong><code>pwd</code></strong></a>, <a href="#_glob"><strong><code>glob</code></strong></a> etc. now work for mingw32
+<a href="#_glob"><strong><code>glob</code></strong></a> now supports the <code>-tails</code> option
</p>
</li>
<li>
<p>
-Line editing is now supported for the win32 console (mingw32)
+Add support for <a href="#_string"><strong><code>string</code></strong></a> <code>cat</code>
</p>
</li>
<li>
<p>
-Add <a href="#_aio"><strong><code>aio</code></strong></a> <code>listen</code> command
+Allow <a href="#_info"><strong><code>info</code></strong></a> <code>source</code> to add source info
</p>
</li>
</ol></div>
</div>
<div class="sect2">
-<h3 id="_changes_between_0_70_and_0_71">Changes between 0.70 and 0.71</h3>
+<h3 id="_changes_between_0_74_and_0_75">Changes between 0.74 and 0.75</h3>
<div class="olist arabic"><ol class="arabic">
<li>
<p>
-Allow <em>args</em> to be renamed in procs
-</p>
-</li>
-<li>
-<p>
-Add <code>$(&#8230;)</code> shorthand syntax for expressions
-</p>
-</li>
-<li>
-<p>
-Add automatic reference variables in procs with <code>&amp;var</code> syntax
+<a href="#_binary"><strong><code>binary</code></strong></a>, <a href="#cmd_3"><strong><code>pack</code></strong></a> and <a href="#cmd_3"><strong><code>unpack</code></strong></a> now support floating point
</p>
</li>
<li>
<p>
-Support <code>jimsh --version</code>
+<a href="#_file"><strong><code>file</code></strong></a> <code>copy</code> <code>-force</code> handles source and target as the same file
</p>
</li>
<li>
<p>
-Additional variables in <code>tcl_platform()</code>
+<a href="#_format"><strong><code>format</code></strong></a> now supports <code>%b</code> for binary conversion
</p>
</li>
<li>
<p>
-<a href="#_local"><strong><code>local</code></strong></a> procs now push existing commands and <a href="#_upcall"><strong><code>upcall</code></strong></a> can call them
+<a href="#_lsort"><strong><code>lsort</code></strong></a> now supports <code>-unique</code> and <code>-real</code>
</p>
</li>
<li>
<p>
-Add <a href="#_loop"><strong><code>loop</code></strong></a> command (TclX compatible)
+Add support for half-close with <a href="#_aio"><strong><code>aio</code></strong></a> <code>close</code> <code>?r|w?</code>
</p>
</li>
<li>
<p>
-Add <a href="#_aio"><strong><code>aio</code></strong></a> <code>buffering</code> command
+Add <a href="#_socket"><strong><code>socket</code></strong></a> <code>pair</code> for a bidirectional pipe
</p>
</li>
<li>
<p>
-<a href="#_info"><strong><code>info</code></strong></a> <code>complete</code> can now return the missing character
+Add <em>--random-hash</em> to randomise hash tables for greater security
</p>
</li>
<li>
<p>
-<a href="#_binary"><strong><code>binary</code></strong></a> <code>format</code> and <a href="#_binary"><strong><code>binary</code></strong></a> <code>scan</code> are now (optionally) supported
+<a href="#_dict"><strong><code>dict</code></strong></a> now supports <em>for</em>, <em>values</em>, <em>incr</em>, <em>append</em>, <em>lappend</em>, <em>update</em>, <em>info</em> and <em>replace</em>
</p>
</li>
<li>
<p>
-Add <a href="#_string"><strong><code>string</code></strong></a> <code>byterange</code>
+<a href="#_file"><strong><code>file</code></strong></a> <code>stat</code> no longer requires the variable name
</p>
</li>
<li>
<p>
-Built-in regexp now support non-greedy repetition (*?, +?, ??)
+Add support for <a href="#_file"><strong><code>file</code></strong></a> <code>link</code>
</p>
</li>
</ol></div>
@@ -1276,6 +1168,11 @@ It may be invoked in interactive mode as:</p></div>
<div class="content">
<pre><code>jimsh filename</code></pre>
</div></div>
+<div class="paragraph"><p>or to process the Tcl script from standard input:</p></div>
+<div class="literalblock">
+<div class="content">
+<pre><code>jimsh -</code></pre>
+</div></div>
<div class="paragraph"><p>It may also be invoked to execute an immediate script with:</p></div>
<div class="literalblock">
<div class="content">
@@ -1363,9 +1260,9 @@ white space (spaces or tabs).
The first field must be the name of a command, and the
additional fields, if any, are arguments that will be passed to
that command. For example, the command:</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>set a 22</code></pre>
+<pre><code> set a 22</code></pre>
</div></div>
<div class="paragraph"><p>has three fields: the first, <a href="#_set"><strong><code>set</code></strong></a>, is the name of a Tcl command, and
the last two, <em>a</em> and <em>22</em>, will be passed as arguments to
@@ -1416,9 +1313,9 @@ terminated by white space (including newlines) or a semi-colon (see below
for information on semi-colons); instead it ends at the next double-quote
character. The double-quotes are not included in the resulting argument.
For example, the command</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>set a "This is a single argument"</code></pre>
+<pre><code> set a "This is a single argument"</code></pre>
</div></div>
<div class="paragraph"><p>will pass two arguments to <a href="#_set"><strong><code>set</code></strong></a>: <em>a</em> and <em>This is a single argument</em>.</p></div>
<div class="paragraph"><p>Within double-quotes, command substitutions, variable substitutions,
@@ -1440,9 +1337,9 @@ can be used to prevent substitutions where they are undesirable.</p></div>
at the matching right brace. Tcl will strip off the outermost layer
of braces and pass the information between the braces to the command
without any further modification. For example, in the command</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>set a {xyz a {b c d}}</code></pre>
+<pre><code> set a {xyz a {b c d}}</code></pre>
</div></div>
<div class="paragraph"><p>the <a href="#_set"><strong><code>set</code></strong></a> command will receive two arguments: <em>a</em>
and <em>xyz a {b c d}</em>.</p></div>
@@ -1452,12 +1349,12 @@ the newline will be included in the argument field along with any other
characters up to the matching brace or quote. For example, the <a href="#_eval"><strong><code>eval</code></strong></a>
command takes one argument, which is a command string; <a href="#_eval"><strong><code>eval</code></strong></a> invokes
the Tcl interpreter to execute the command string. The command</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>eval {
- set a 22
- set b 33
-}</code></pre>
+<pre><code> eval {
+ set a 22
+ set b 33
+ }</code></pre>
</div></div>
<div class="paragraph"><p>will assign the value <em>22</em> to <em>a</em> and <em>33</em> to <em>b</em>.</p></div>
<div class="paragraph"><p>If the first character of a command field is not a left
@@ -1474,42 +1371,42 @@ substitution occurs (except for fields enclosed in braces). All of the
text up to the matching close bracket is treated as a Tcl command and
executed immediately. Then the result of that command is substituted
for the bracketed text. For example, consider the command</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>set a [set b]</code></pre>
+<pre><code> set a [set b]</code></pre>
</div></div>
<div class="paragraph"><p>When the <a href="#_set"><strong><code>set</code></strong></a> command has only a single argument, it is the name of a
variable and <a href="#_set"><strong><code>set</code></strong></a> returns the contents of that variable. In this case,
if variable <em>b</em> has the value <em>foo</em>, then the command above is equivalent
to the command</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>set a foo</code></pre>
+<pre><code> set a foo</code></pre>
</div></div>
<div class="paragraph"><p>Brackets can be used in more complex ways. For example, if the variable
<em>b</em> has the value <em>foo</em> and the variable <em>c</em> has the value <em>gorp</em>,
then the command</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>set a xyz[set b].[set c]</code></pre>
+<pre><code> set a xyz[set b].[set c]</code></pre>
</div></div>
<div class="paragraph"><p>is equivalent to the command</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>set a xyzfoo.gorp</code></pre>
+<pre><code> set a xyzfoo.gorp</code></pre>
</div></div>
<div class="paragraph"><p>A bracketed command may contain multiple commands separated by newlines
or semi-colons in the usual fashion. In this case the value of the last
command is used for substitution. For example, the command</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>set a x[set b 22
-expr $b+2]x</code></pre>
+<pre><code> set a x[set b 22
+ expr $b+2]x</code></pre>
</div></div>
<div class="paragraph"><p>is equivalent to the command</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>set a x24x</code></pre>
+<pre><code> set a x24x</code></pre>
</div></div>
<div class="paragraph"><p>If a field is enclosed in braces then the brackets and the characters
between them are not interpreted specially; they are passed through to
@@ -1526,14 +1423,14 @@ after the <code>$</code>, up to the first character that isn&#8217;t a number, l
or underscore, are taken as a variable name and the string value of that
variable is substituted for the name.</p></div>
<div class="paragraph"><p>For example, if variable <em>foo</em> has the value <em>test</em>, then the command</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>set a $foo.c</code></pre>
+<pre><code> set a $foo.c</code></pre>
</div></div>
<div class="paragraph"><p>is equivalent to the command</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>set a test.c</code></pre>
+<pre><code> set a test.c</code></pre>
</div></div>
<div class="paragraph"><p>There are two special forms for variable substitution. If the next
character after the name of the variable is an open parenthesis, then
@@ -1545,40 +1442,40 @@ used as an index.</p></div>
<div class="paragraph"><p>For example, if the variable <em>x</em> is an array with one element named
<em>first</em> and value <em>87</em> and another element named <em>14</em> and value <em>more</em>,
then the command</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>set a xyz$x(first)zyx</code></pre>
+<pre><code> set a xyz$x(first)zyx</code></pre>
</div></div>
<div class="paragraph"><p>is equivalent to the command</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>set a xyz87zyx</code></pre>
+<pre><code> set a xyz87zyx</code></pre>
</div></div>
<div class="paragraph"><p>If the variable <em>index</em> has the value <em>14</em>, then the command</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>set a xyz$x($index)zyx</code></pre>
+<pre><code> set a xyz$x($index)zyx</code></pre>
</div></div>
<div class="paragraph"><p>is equivalent to the command</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>set a xyzmorezyx</code></pre>
+<pre><code> set a xyzmorezyx</code></pre>
</div></div>
-<div class="paragraph"><p>For more information on arrays, see VARIABLES AND ARRAYS below.</p></div>
+<div class="paragraph"><p>For more information on arrays, see <a href="#_variables_scalars_and_arrays">VARIABLES - SCALARS AND ARRAYS</a> below.</p></div>
<div class="paragraph"><p>The second special form for variables occurs when the dollar sign is
followed by an open curly brace. In this case the variable name consists
of all the characters up to the next curly brace.</p></div>
<div class="paragraph"><p>Array references are not possible in this form: the name between braces
is assumed to refer to a scalar variable. For example, if variable
<em>foo</em> has the value <em>test</em>, then the command</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>set a abc${foo}bar</code></pre>
+<pre><code> set a abc${foo}bar</code></pre>
</div></div>
<div class="paragraph"><p>is equivalent to the command</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>set a abctestbar</code></pre>
+<pre><code> set a abctestbar</code></pre>
</div></div>
<div class="paragraph"><p>Variable substitution does not occur in arguments that are enclosed in
braces: the dollar sign and variable name are passed through to the
@@ -1767,9 +1664,9 @@ sequence is replaced by the given character:</p></div>
</dd>
</dl></div>
<div class="paragraph"><p>For example, in the command</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>set a \{x\[\ yz\141</code></pre>
+<pre><code> set a \{x\[\ yz\141</code></pre>
</div></div>
<div class="paragraph"><p>the second argument to <a href="#_set"><strong><code>set</code></strong></a> will be <code>{x[ yza</code>.</p></div>
<div class="paragraph"><p>If a backslash is followed by something other than one of the options
@@ -1777,9 +1674,9 @@ described above, then the backslash is transmitted to the argument
field without any special processing, and the Tcl scanner continues
normal processing with the next character. For example, in the
command</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>set \*a \\\{foo</code></pre>
+<pre><code> set \*a \\\{foo</code></pre>
</div></div>
<div class="paragraph"><p>The first argument to <a href="#_set"><strong><code>set</code></strong></a> will be <code>\*a</code> and the second
argument will be <code>\{foo</code>.</p></div>
@@ -1792,9 +1689,9 @@ In particular, backslashed braces are not counted in locating the
matching right brace that terminates the argument.
For example, in the
command</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>set a {\{abc}</code></pre>
+<pre><code> set a {\{abc}</code></pre>
</div></div>
<div class="paragraph"><p>the second argument to <a href="#_set"><strong><code>set</code></strong></a> will be <code>\{abc</code>.</p></div>
<div class="paragraph"><p>This backslash mechanism is not sufficient to generate absolutely
@@ -1932,9 +1829,9 @@ same meaning and precedence as the corresponding C operators.
Expressions almost always yield numeric results
(integer or floating-point values).
For example, the expression</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>8.2 + 6</code></pre>
+<pre><code> 8.2 + 6</code></pre>
</div></div>
<div class="paragraph"><p>evaluates to 14.2.</p></div>
<div class="paragraph"><p>Tcl expressions differ from C expressions in the way that
@@ -2018,12 +1915,12 @@ on the contents.</p></div>
the value 3 and the variable <em>b</em> has the value 6. Then the expression
on the left side of each of the lines below will evaluate to the value
on the right side of the line:</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>$a + 3.1 6.1
-2 + "$a.$b" 5.6
-4*[llength "6 2"] 8
-{word one} &lt; "word $a" 0</code></pre>
+<pre><code> $a + 3.1 6.1
+ 2 + "$a.$b" 5.6
+ 4*[llength "6 2"] 8
+ {word one} &lt; "word $a" 0</code></pre>
</div></div>
<div class="paragraph"><p>The valid operators are listed below, grouped in decreasing order
of precedence:</p></div>
@@ -2223,17 +2120,17 @@ of precedence:</p></div>
produced by each operator.
All of the binary operators group left-to-right within the same
precedence level. For example, the expression</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>4*2 &lt; 7</code></pre>
+<pre><code> 4*2 &lt; 7</code></pre>
</div></div>
<div class="paragraph"><p>evaluates to 0.</p></div>
<div class="paragraph"><p>The <code>&amp;&amp;</code>, <code>||</code>, and <code>?:</code> operators have <em>lazy evaluation</em>, just as
in C, which means that operands are not evaluated if they are not
needed to determine the outcome. For example, in</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>$v ? [a] : [b]</code></pre>
+<pre><code> $v ? [a] : [b]</code></pre>
</div></div>
<div class="paragraph"><p>only one of <code>[a]</code> or <code>[b]</code> will actually be evaluated,
depending on the value of <code>$v</code>.</p></div>
@@ -2253,15 +2150,15 @@ string operands is done automatically as needed.
For arithmetic computations, integers are used until some
floating-point number is introduced, after which floating-point is used.
For example,</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>5 / 4</code></pre>
+<pre><code> 5 / 4</code></pre>
</div></div>
<div class="paragraph"><p>yields the result 1, while</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>5 / 4.0
-5 / ( [string length "abcd"] + 0.0 )</code></pre>
+<pre><code> 5 / 4.0
+ 5 / ( [string length "abcd"] + 0.0 )</code></pre>
</div></div>
<div class="paragraph"><p>both yield the result 1.25.</p></div>
<div class="paragraph"><p>String values may be used as operands of the comparison operators,
@@ -2272,10 +2169,10 @@ has a numeric value, the numeric operand is converted back to
a string using the C <em>sprintf</em> format specifier
<em>%d</em> for integers and <em>%g</em> for floating-point values.
For example, the expressions</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>"0x03" &gt; "2"
-"0y" &lt; "0x12"</code></pre>
+<pre><code> "0x03" &gt; "2"
+ "0y" &lt; "0x12"</code></pre>
</div></div>
<div class="paragraph"><p>both evaluate to 1. The first comparison is done using integer
comparison, and the second is done using string comparison after
@@ -2284,9 +2181,9 @@ the second operand is converted to the string <em>18</em>.</p></div>
entering it in a command: otherwise, if the expression contains
any white space then the Tcl interpreter will split it
among several arguments. For example, the command</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>expr $a + $b</code></pre>
+<pre><code> expr $a + $b</code></pre>
</div></div>
<div class="paragraph"><p>results in three arguments being passed to <a href="#_expr"><strong><code>expr</code></strong></a>: <code>$a</code>,
+, and <code>$b</code>. In addition, if the expression isn&#8217;t in braces
@@ -2299,9 +2196,9 @@ decide when to exit a loop). Usually the desired goal is to re-do
the variable or command substitutions each time the expression is
evaluated, rather than once and for all at the beginning. For example,
the command</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>for {set i 1} $i&lt;=10 {incr i} {...} ** WRONG **</code></pre>
+<pre><code> for {set i 1} $i&lt;=10 {incr i} {...} ** WRONG **</code></pre>
</div></div>
<div class="paragraph"><p>is probably intended to iterate over all values of <code>i</code> from 1 to 10.
After each iteration of the body of the loop, <a href="#_for"><strong><code>for</code></strong></a> will pass
@@ -2313,9 +2210,9 @@ command was invoked then the second argument of <a href="#_for"><strong><code>fo
which will always evaluate to 1, even though <code>i</code> eventually
becomes greater than 10. In the above case the loop will never
terminate. Instead, the expression should be placed in braces:</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>for {set i 1} {$i&lt;=10} {incr i} {...} ** RIGHT **</code></pre>
+<pre><code> for {set i 1} {$i&lt;=10} {incr i} {...} ** RIGHT **</code></pre>
</div></div>
<div class="paragraph"><p>This causes the substitution of <em>i</em>
to be delayed; it will be re-done each time the expression is
@@ -2329,9 +2226,9 @@ evaluated, which is the desired result.</p></div>
A list is just a string with a list-like structure
consisting of fields separated by white space. For example, the
string</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>Al Sue Anne John</code></pre>
+<pre><code> Al Sue Anne John</code></pre>
</div></div>
<div class="paragraph"><p>is a list with four elements or fields.
Lists have the same basic structure as command strings, except
@@ -2339,18 +2236,18 @@ that a newline character in a list is treated as a field separator
just like space or tab. Conventions for braces and quotes
and backslashes are the same for lists as for commands. For example,
the string</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>a b\ c {d e {f g h}}</code></pre>
+<pre><code> a b\ c {d e {f g h}}</code></pre>
</div></div>
<div class="paragraph"><p>is a list with three elements: <code>a</code>, <code>b c</code>, and <code>d e {f g h}</code>.</p></div>
<div class="paragraph"><p>Whenever an element is extracted from a list, the same rules about
braces and quotes and backslashes are applied as for commands. Thus in
the example above when the third element is extracted from the list,
the result is</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>d e {f g h}</code></pre>
+<pre><code> d e {f g h}</code></pre>
</div></div>
<div class="paragraph"><p>(when the field was extracted, all that happened was to strip off
the outermost layer of braces). Command substitution and
@@ -2370,17 +2267,17 @@ other list-related functions.</p></div>
<div class="paragraph"><p>A new addition to Tcl 8.5 is the ability to expand a list into separate
arguments. Support for this feature is also available in Jim.</p></div>
<div class="paragraph"><p>Consider the following attempt to exec a list:</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>set cmd {ls -l}
-exec $cmd</code></pre>
+<pre><code> set cmd {ls -l}
+ exec $cmd</code></pre>
</div></div>
<div class="paragraph"><p>This will attempt to exec a command named "ls -l", which will clearly not
work. Typically eval and concat are required to solve this problem, however
it can be solved much more easily with <code>{*}</code>.</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>exec {*}$cmd</code></pre>
+<pre><code> exec {*}$cmd</code></pre>
</div></div>
<div class="paragraph"><p>This will expand the following argument into individual elements and then evaluate
the resulting command.</p></div>
@@ -2657,9 +2554,9 @@ Variable Argument
</li>
</ol></div>
<div class="paragraph"><p>The following example illustrates precedence. Assume a procedure declaration:</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>proc p {{a A} args b {c C} d} {...}</code></pre>
+<pre><code> proc p {{a A} args b {c C} d} {...}</code></pre>
</div></div>
<div class="paragraph"><p>This procedure requires at least two arguments, but can accept an unlimited number.
The following table shows how various numbers of arguments are assigned.
@@ -2740,20 +2637,20 @@ accessed by invoking the <a href="#_global"><strong><code>global</code></strong>
These variables scoped to the procedure and initialised at procedure definition.
Either from the static variable definition, or from the enclosing scope.</p></div>
<div class="paragraph"><p>Consider the following example:</p></div>
-<div class="literalblock">
-<div class="content">
-<pre><code>jim&gt; set a 1
-jim&gt; proc a {} {a {b 2}} {
- set c 1
- puts "$a $b $c"
- incr a
- incr b
- incr c
-}
-jim&gt; a
-1 2 1
-jim&gt; a
-2 3 1</code></pre>
+<div class="listingblock">
+<div class="content">
+<pre><code> . set a 1
+ . proc a {} {a {b 2}} {
+ set c 1
+ puts "$a $b $c"
+ incr a
+ incr b
+ incr c
+ }
+ . a
+ 1 2 1
+ . a
+ 2 3 1</code></pre>
</div></div>
<div class="paragraph"><p>The static variable <code><em>a</em></code> has no initialiser, so it is initialised from
the enclosing scope with the value 1. (Note that it is an error if there
@@ -2762,7 +2659,7 @@ has an initialiser, so it is initialised to 2.</p></div>
<div class="paragraph"><p>Unlike a local variable, the value of a static variable is retained across
invocations of the procedure.</p></div>
<div class="paragraph"><p>See the <a href="#_proc"><strong><code>proc</code></strong></a> command for information on how to define procedures
-and what happens when they are invoked. See also NAMESPACES.</p></div>
+and what happens when they are invoked. See also <a href="#_namespaces">NAMESPACES</a>.</p></div>
</div>
</div>
</div>
@@ -2781,19 +2678,19 @@ its <em>index</em>) and a value.</p></div>
<div class="paragraph"><p>Array indexes may be arbitrary strings; they need not be numeric.
Parentheses are used refer to array elements in Tcl commands.
For example, the command</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>set x(first) 44</code></pre>
+<pre><code> set x(first) 44</code></pre>
</div></div>
<div class="paragraph"><p>will modify the element of <em>x</em> whose index is <em>first</em>
so that its new value is <em>44</em>.</p></div>
<div class="paragraph"><p>Two-dimensional arrays can be simulated in Tcl by using indexes
that contain multiple concatenated values.
For example, the commands</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>set a(2,3) 1
-set a(3,6) 2</code></pre>
+<pre><code> set a(2,3) 1
+ set a(3,6) 2</code></pre>
</div></div>
<div class="paragraph"><p>set the elements of <em>a</em> whose indexes are <em>2,3</em> and <em>3,6</em>.</p></div>
<div class="paragraph"><p>In general, array elements may be used anywhere in Tcl that scalar
@@ -2817,19 +2714,17 @@ a procedure exits. Either <a href="#_global"><strong><code>global</code></stron
that a name refer to a global variable for the duration of the current
procedure (this is somewhat analogous to <em>extern</em> in C), or the variable
may be explicitly scoped with the <code>::</code> prefix. For example</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>set a 1
-set b 2
-proc p {} {
- set c 3
- global a</code></pre>
-</div></div>
-<div class="literalblock">
-<div class="content">
-<pre><code> puts "$a $::b $c"
-}
-p</code></pre>
+<pre><code> . set a 1
+ . set b 2
+ . proc p {} {
+ set c 3
+ global a
+
+ puts "$a $::b $c"
+ }
+ . p</code></pre>
</div></div>
<div class="paragraph"><p>will output:</p></div>
<div class="literalblock">
@@ -2845,29 +2740,29 @@ p</code></pre>
number of elements) and an array value. This is similar to the way Tcl
can convert between a string and a list.</p></div>
<div class="paragraph"><p>For example:</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>set a {1 one 2 two}
-puts $a(2)</code></pre>
+<pre><code> set a {1 one 2 two}
+ puts $a(2)</code></pre>
</div></div>
<div class="paragraph"><p>will output:</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>two</code></pre>
+<pre><code> two</code></pre>
</div></div>
<div class="paragraph"><p>Thus <a href="#_array"><strong><code>array</code></strong></a> <code>set</code> is equivalent to <a href="#_set"><strong><code>set</code></strong></a> when the variable does not
exist or is empty.</p></div>
<div class="paragraph"><p>The reverse is also true where an array will be converted into
a list.</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>set a(1) one; set a(2) two
-puts $a</code></pre>
+<pre><code> set a(1) one; set a(2) two
+ puts $a</code></pre>
</div></div>
<div class="paragraph"><p>will output:</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>1 one 2 two</code></pre>
+<pre><code> 1 one 2 two</code></pre>
</div></div>
</div>
</div>
@@ -2905,18 +2800,18 @@ representations).</p></div>
<div class="paragraph"><p>Note that in Jim, arrays are implemented as dictionaries.
Thus automatic conversion between lists and dictionaries applies
as it does for arrays.</p></div>
-<div class="literalblock">
-<div class="content">
-<pre><code>jim&gt; dict set a 1 one
-1 one
-jim&gt; dict set a 2 two
-1 one 2 two
-jim&gt; puts $a
-1 one 2 two
-jim&gt; puts $a(2)
-two
-jim&gt; dict set a 3 T three
-1 one 2 two 3 {T three}</code></pre>
+<div class="listingblock">
+<div class="content">
+<pre><code> . dict set a 1 one
+ 1 one
+ . dict set a 2 two
+ 1 one 2 two
+ . puts $a
+ 1 one 2 two
+ . puts $a(2)
+ two
+ . dict set a 3 T three
+ 1 one 2 two 3 {T three}</code></pre>
</div></div>
<div class="paragraph"><p>See the <a href="#_dict"><strong><code>dict</code></strong></a> command for more details.</p></div>
</div>
@@ -2944,23 +2839,23 @@ These are described briefly below.</p></div>
<div class="paragraph"><p>A reference can be thought of as holding a value with one level of indirection,
where the value may be garbage collected when unreferenced.
Consider the following example:</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>jim&gt; set r [ref "One String" test]
-&lt;reference.&lt;test___&gt;.00000000000000000000&gt;
-jim&gt; getref $r
-One String</code></pre>
+<pre><code> . set r [ref "One String" test]
+ &lt;reference.&lt;test___&gt;.00000000000000000000&gt;
+ . getref $r
+ One String</code></pre>
</div></div>
<div class="paragraph"><p>The operation <a href="#_ref"><strong><code>ref</code></strong></a> creates a references to the value specified by the
first argument. (The second argument is a "type" used for documentation purposes).</p></div>
<div class="paragraph"><p>The operation <a href="#_getref"><strong><code>getref</code></strong></a> is the dereferencing operation which retrieves the value
stored in the reference.</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>jim&gt; setref $r "New String"
-New String
-jim&gt; getref $r
-New String</code></pre>
+<pre><code> . setref $r "New String"
+ New String
+ . getref $r
+ New String</code></pre>
</div></div>
<div class="paragraph"><p>The operation <a href="#_setref"><strong><code>setref</code></strong></a> replaces the value stored by the reference. If the old value
is no longer accessible by any reference, it will eventually be automatically be garbage
@@ -2975,51 +2870,51 @@ transcend their scope. To support this, case, the Jim system will periodically i
and discard objects which are no longer accessible by any reference.</p></div>
<div class="paragraph"><p>The <a href="#_collect"><strong><code>collect</code></strong></a> command may be used to force garbage collection. Consider a reference created
with a finalizer:</p></div>
-<div class="literalblock">
-<div class="content">
-<pre><code>jim&gt; proc f {ref value} { puts "Finaliser called for $ref,$value" }
-jim&gt; set r [ref "One String" test f]
-&lt;reference.&lt;test___&gt;.00000000000
-jim&gt; collect
-0
-jim&gt; set r ""
-jim&gt; collect
-Finaliser called for &lt;reference.&lt;test___&gt;.00000000000,One String
-1</code></pre>
+<div class="listingblock">
+<div class="content">
+<pre><code> . proc f {ref value} { puts "Finaliser called for $ref,$value" }
+ . set r [ref "One String" test f]
+ &lt;reference.&lt;test___&gt;.00000000000
+ . collect
+ 0
+ . set r ""
+ . collect
+ Finaliser called for &lt;reference.&lt;test___&gt;.00000000000,One String
+ 1</code></pre>
</div></div>
<div class="paragraph"><p>Note that once the reference, <em>r</em>, was modified so that it no longer
contained a reference to the value, the garbage collector discarded
the value (after calling the finalizer).</p></div>
<div class="paragraph"><p>The finalizer for a reference may be examined or changed with the <a href="#_finalize"><strong><code>finalize</code></strong></a> command</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>jim&gt; finalize $r
-f
-jim&gt; finalize $r newf
-newf</code></pre>
+<pre><code> . finalize $r
+ f
+ . finalize $r newf
+ newf</code></pre>
</div></div>
</div>
<div class="sect2">
<h3 id="_lambda_function">Lambda Function</h3>
<div class="paragraph"><p>Jim provides a garbage collected <a href="#_lambda"><strong><code>lambda</code></strong></a> function. This is a procedure
which is able to create an anonymous procedure. Consider:</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>jim&gt; set f [lambda {a} {{x 0}} { incr x $a }]
-jim&gt; $f 1
-1
-jim&gt; $f 2
-3
-jim&gt; set f ""</code></pre>
+<pre><code> . set f [lambda {a} {{x 0}} { incr x $a }]
+ . $f 1
+ 1
+ . $f 2
+ 3
+ . set f ""</code></pre>
</div></div>
<div class="paragraph"><p>This create an anonymous procedure (with the name stored in <em>f</em>), with a static variable
which is incremented by the supplied value and the result returned.</p></div>
<div class="paragraph"><p>Once the procedure name is no longer accessible, it will automatically be deleted
when the garbage collector runs.</p></div>
<div class="paragraph"><p>The procedure may also be delete immediately by renaming it "". e.g.</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>jim&gt; rename $f ""</code></pre>
+<pre><code> . rename $f ""</code></pre>
</div></div>
</div>
</div>
@@ -3044,30 +2939,30 @@ is still available to embed UTF-8 sequences.</p></div>
<h3 id="_string_matching">String Matching</h3>
<div class="paragraph"><p>Commands such as <a href="#_string"><strong><code>string</code></strong></a> <code>match</code>, <a href="#_lsearch"><strong><code>lsearch</code></strong></a> <code>-glob</code>, <a href="#_array"><strong><code>array</code></strong></a> <code>names</code> and others use string
pattern matching rules. These commands support UTF-8. For example:</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>string match a\[\ua0-\ubf\]b "a\u00a3b"</code></pre>
+<pre><code> string match a\[\ua0-\ubf\]b "a\u00a3b"</code></pre>
</div></div>
</div>
<div class="sect2">
<h3 id="_format_and_scan">format and scan</h3>
<div class="paragraph"><p><code>format %c</code> allows a unicode codepoint to be be encoded. For example, the following will return
a string with two bytes and one character. The same as <code>\ub5</code></p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>format %c 0xb5</code></pre>
+<pre><code> format %c 0xb5</code></pre>
</div></div>
<div class="paragraph"><p><a href="#_format"><strong><code>format</code></strong></a> respects widths as character widths, not byte widths. For example, the following will
return a string with three characters, not three bytes.</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>format %.3s \ub5\ub6\ub7\ub8</code></pre>
+<pre><code> format %.3s \ub5\ub6\ub7\ub8</code></pre>
</div></div>
<div class="paragraph"><p>Similarly, <code>scan &#8230; %c</code> allows a UTF-8 to be decoded to a unicode codepoint. The following will set
<code><em>a</em></code> to 181 (0xb5) and <code><em>b</em></code> to 65 (0x41).</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>scan \u00b5A %c%c a b</code></pre>
+<pre><code> scan \u00b5A %c%c a b</code></pre>
</div></div>
<div class="paragraph"><p><a href="#_scan"><strong><code>scan</code></strong></a> <code>%s</code> will also accept a character class, including unicode ranges.</p></div>
</div>
@@ -3075,9 +2970,9 @@ return a string with three characters, not three bytes.</p></div>
<h3 id="_string_classes">String Classes</h3>
<div class="paragraph"><p><a href="#_string"><strong><code>string</code></strong></a> <code>is</code> has <strong>not</strong> been extended to classify UTF-8 characters. Therefore, the following
will return 0, even though the string may be considered to be alphabetic.</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>string is alpha \ub5Test</code></pre>
+<pre><code> string is alpha \ub5Test</code></pre>
</div></div>
<div class="paragraph"><p>This does not affect the string classes <em>ascii</em>, <em>control</em>, <em>digit</em>, <em>double</em>, <em>integer</em> or <em>xdigit</em>.</p></div>
</div>
@@ -3099,16 +2994,16 @@ those which represent character sequences longer than 3 bytes (greater than U+FF
and those which end prematurely, such as a lone <em>0xc2</em>.</p></div>
<div class="paragraph"><p>In these situations, the offending bytes are treated as single characters. For example,
the following returns 2.</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>string bytelength \xff\xff</code></pre>
+<pre><code> string bytelength \xff\xff</code></pre>
</div></div>
</div>
<div class="sect2">
<h3 id="_regular_expressions_2">Regular Expressions</h3>
<div class="paragraph"><p>If UTF-8 support is enabled, the built-in regular expression engine will be
selected which supports UTF-8 strings and patterns.</p></div>
-<div class="paragraph"><p>See REGULAR EXPRESSIONS</p></div>
+<div class="paragraph"><p>See <a href="#_regular_expressions">REGULAR EXPRESSIONS</a></p></div>
</div>
</div>
</div>
@@ -3168,13 +3063,14 @@ cellspacing="0" cellpadding="4">
<td align="left" valign="top"><p class="table"><a href="#_concat"><strong><code>concat</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_continue"><strong><code>continue</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_curry"><strong><code>curry</code></strong></a></p></td>
+<td align="left" valign="top"><p class="table"><a href="#_defer"><strong><code>defer</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_dict"><strong><code>dict</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_env"><strong><code>env</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_eof"><strong><code>eof</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_error"><strong><code>error</code></strong></a></p></td>
-<td align="left" valign="top"><p class="table"><a href="#_eval"><strong><code>eval</code></strong></a></p></td>
</tr>
<tr>
+<td align="left" valign="top"><p class="table"><a href="#_eval"><strong><code>eval</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#cmd_2"><strong><code>eventloop</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_exec"><strong><code>exec</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_exists"><strong><code>exists</code></strong></a></p></td>
@@ -3182,9 +3078,9 @@ cellspacing="0" cellpadding="4">
<td align="left" valign="top"><p class="table"><a href="#_expr"><strong><code>expr</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_fconfigure"><strong><code>fconfigure</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_file"><strong><code>file</code></strong></a></p></td>
-<td align="left" valign="top"><p class="table"><a href="#_finalize"><strong><code>finalize</code></strong></a></p></td>
</tr>
<tr>
+<td align="left" valign="top"><p class="table"><a href="#_finalize"><strong><code>finalize</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_flush"><strong><code>flush</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_for"><strong><code>for</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_foreach"><strong><code>foreach</code></strong></a></p></td>
@@ -3192,117 +3088,116 @@ cellspacing="0" cellpadding="4">
<td align="left" valign="top"><p class="table"><a href="#_getref"><strong><code>getref</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_gets"><strong><code>gets</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_glob"><strong><code>glob</code></strong></a></p></td>
-<td align="left" valign="top"><p class="table"><a href="#_global"><strong><code>global</code></strong></a></p></td>
</tr>
<tr>
+<td align="left" valign="top"><p class="table"><a href="#_global"><strong><code>global</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_history"><strong><code>history</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_if"><strong><code>if</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_incr"><strong><code>incr</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_info"><strong><code>info</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_interp"><strong><code>interp</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_join"><strong><code>join</code></strong></a></p></td>
-<td align="left" valign="top"><p class="table"><a href="#_kill"><strong><code>kill</code></strong></a></p></td>
-<td align="left" valign="top"><p class="table"><a href="#_lambda"><strong><code>lambda</code></strong></a></p></td>
+<td align="left" valign="top"><p class="table"><a href="#_json_decode"><strong><code>json::decode</code></strong></a></p></td>
</tr>
<tr>
+<td align="left" valign="top"><p class="table"><a href="#_json_encode"><strong><code>json::encode</code></strong></a></p></td>
+<td align="left" valign="top"><p class="table"><a href="#_kill"><strong><code>kill</code></strong></a></p></td>
+<td align="left" valign="top"><p class="table"><a href="#_lambda"><strong><code>lambda</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_lappend"><strong><code>lappend</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_lassign"><strong><code>lassign</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_lindex"><strong><code>lindex</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_linsert"><strong><code>linsert</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_list"><strong><code>list</code></strong></a></p></td>
+</tr>
+<tr>
<td align="left" valign="top"><p class="table"><a href="#_llength"><strong><code>llength</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_lmap"><strong><code>lmap</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_load"><strong><code>load</code></strong></a></p></td>
-</tr>
-<tr>
<td align="left" valign="top"><p class="table"><a href="#_local"><strong><code>local</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_loop"><strong><code>loop</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_lrange"><strong><code>lrange</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_lrepeat"><strong><code>lrepeat</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_lreplace"><strong><code>lreplace</code></strong></a></p></td>
+</tr>
+<tr>
<td align="left" valign="top"><p class="table"><a href="#_lreverse"><strong><code>lreverse</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_lsearch"><strong><code>lsearch</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_lset"><strong><code>lset</code></strong></a></p></td>
-</tr>
-<tr>
<td align="left" valign="top"><p class="table"><a href="#_lsort"><strong><code>lsort</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_namespace"><strong><code>namespace</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#cmd_4"><strong><code>oo</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_open"><strong><code>open</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#cmd_1"><strong><code>os.fork</code></strong></a></p></td>
+</tr>
+<tr>
<td align="left" valign="top"><p class="table"><a href="#cmd_1"><strong><code>os.gethostname</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#cmd_1"><strong><code>os.getids</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#cmd_1"><strong><code>os.uptime</code></strong></a></p></td>
-</tr>
-<tr>
-<td align="left" valign="top"><p class="table"><a href="#cmd_1"><strong><code>os.wait</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#cmd_3"><strong><code>pack</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#cmd_3"><strong><code>pack</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_package"><strong><code>package</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_pid"><strong><code>pid</code></strong></a></p></td>
+<td align="left" valign="top"><p class="table"><a href="#_pipe"><strong><code>pipe</code></strong></a></p></td>
+</tr>
+<tr>
<td align="left" valign="top"><p class="table"><a href="#cmd_1"><strong><code>posix</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_proc"><strong><code>proc</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_puts"><strong><code>puts</code></strong></a></p></td>
-</tr>
-<tr>
<td align="left" valign="top"><p class="table"><a href="#_pwd"><strong><code>pwd</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_rand"><strong><code>rand</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_range"><strong><code>range</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_read"><strong><code>read</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_ref"><strong><code>ref</code></strong></a></p></td>
+</tr>
+<tr>
<td align="left" valign="top"><p class="table"><a href="#_regexp"><strong><code>regexp</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_regsub"><strong><code>regsub</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_rename"><strong><code>rename</code></strong></a></p></td>
-</tr>
-<tr>
<td align="left" valign="top"><p class="table"><a href="#_return"><strong><code>return</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_scan"><strong><code>scan</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_seek"><strong><code>seek</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_set"><strong><code>set</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_setref"><strong><code>setref</code></strong></a></p></td>
+</tr>
+<tr>
<td align="left" valign="top"><p class="table"><a href="#_signal"><strong><code>signal</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_sleep"><strong><code>sleep</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_socket"><strong><code>socket</code></strong></a></p></td>
-</tr>
-<tr>
<td align="left" valign="top"><p class="table"><a href="#_source"><strong><code>source</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_split"><strong><code>split</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_stackdump"><strong><code>stackdump</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_stacktrace"><strong><code>stacktrace</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_string"><strong><code>string</code></strong></a></p></td>
+</tr>
+<tr>
<td align="left" valign="top"><p class="table"><a href="#_subst"><strong><code>subst</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#cmd_4"><strong><code>super</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_switch"><strong><code>switch</code></strong></a></p></td>
-</tr>
-<tr>
<td align="left" valign="top"><p class="table"><a href="#_syslog"><strong><code>syslog</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_tailcall"><strong><code>tailcall</code></strong></a></p></td>
+<td align="left" valign="top"><p class="table"><a href="#_tcl_autocomplete"><strong><code>tcl::autocomplete</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_tcl_prefix"><strong><code>tcl::prefix</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_tell"><strong><code>tell</code></strong></a></p></td>
+</tr>
+<tr>
<td align="left" valign="top"><p class="table"><a href="#_throw"><strong><code>throw</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_time"><strong><code>time</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_tree"><strong><code>tree</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_try"><strong><code>try</code></strong></a></p></td>
-</tr>
-<tr>
<td align="left" valign="top"><p class="table"><a href="#_unknown"><strong><code>unknown</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#cmd_3"><strong><code>unpack</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_unset"><strong><code>unset</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_upcall"><strong><code>upcall</code></strong></a></p></td>
+</tr>
+<tr>
<td align="left" valign="top"><p class="table"><a href="#cmd_2"><strong><code>update</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_uplevel"><strong><code>uplevel</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_upvar"><strong><code>upvar</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#cmd_2"><strong><code>vwait</code></strong></a></p></td>
-</tr>
-<tr>
+<td align="left" valign="top"><p class="table"><a href="#_wait"><strong><code>wait</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_while"><strong><code>while</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_zlib"><strong><code>zlib</code></strong></a></p></td>
<td align="left" valign="top"><p class="table"></p></td>
-<td align="left" valign="top"><p class="table"></p></td>
-<td align="left" valign="top"><p class="table"></p></td>
-<td align="left" valign="top"><p class="table"></p></td>
-<td align="left" valign="top"><p class="table"></p></td>
-<td align="left" valign="top"><p class="table"></p></td>
</tr>
</tbody>
</table>
@@ -3323,12 +3218,12 @@ be an integer.</p></div>
<div class="paragraph"><p><code><strong>alias</strong> <em>name args...</em></code></p></div>
<div class="paragraph"><p>Creates a single word alias (command) for one or more words. For example,
the following creates an alias for the command <a href="#_info"><strong><code>info</code></strong></a> <code>exists</code>.</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>alias e info exists
-if {[e var]} {
- ...
-}</code></pre>
+<pre><code> alias e info exists
+ if {[e var]} {
+ ...
+ }</code></pre>
</div></div>
<div class="paragraph"><p><a href="#_alias"><strong><code>alias</code></strong></a> returns <code><em>name</em></code>, allowing it to be used with <a href="#_local"><strong><code>local</code></strong></a>.</p></div>
<div class="paragraph"><p>See also <a href="#_proc"><strong><code>proc</code></strong></a>, <a href="#_curry"><strong><code>curry</code></strong></a>, <a href="#_lambda"><strong><code>lambda</code></strong></a>, <a href="#_local"><strong><code>local</code></strong></a>, <a href="#_info"><strong><code>info</code></strong></a> <code>alias</code>, <a href="#_exists"><strong><code>exists</code></strong></a> <code>-alias</code></p></div>
@@ -3370,8 +3265,7 @@ command. The legal <code><em>options</em></code> (which may be abbreviated) are
<dd>
<p>
Returns 1 if arrayName is an array variable, 0 if there is
- no variable by that name. This command is essentially
- identical to <a href="#_info"><strong><code>info</code></strong></a> <code>exists</code>
+ no variable by that name.
</p>
</dd>
<dt class="hdlist1">
@@ -3455,61 +3349,8 @@ to signal the innermost containing loop command to return immediately.</p></div>
</div>
<div class="sect2">
<h3 id="_case">case</h3>
-<div class="paragraph"><p><code><strong>case</strong> <em>string</em> ?in? <em>patList body ?patList body &#8230;?</em></code></p></div>
-<div class="paragraph"><p><code><strong>case</strong> <em>string</em> ?in? {<em>patList body ?patList body &#8230;?</em>}</code></p></div>
-<div class="paragraph"><p><strong>Note</strong> that the <a href="#_switch"><strong><code>switch</code></strong></a> command should generally be preferred unless compatibility
-with Tcl 6.x is desired.</p></div>
-<div class="paragraph"><p>Match <code><em>string</em></code> against each of the <code><em>patList</em></code> arguments
-in order. If one matches, then evaluate the following <code><em>body</em></code> argument
-by passing it recursively to the Tcl interpreter, and return the result
-of that evaluation. Each <code><em>patList</em></code> argument consists of a single
-pattern or list of patterns. Each pattern may contain any of the wild-cards
-described under <a href="#_string"><strong><code>string</code></strong></a> <code>match</code>.</p></div>
-<div class="paragraph"><p>If a <code><em>patList</em></code> argument is <code>default</code>, the corresponding body will be
-evaluated if no <code><em>patList</em></code> matches <code><em>string</em></code>. If no <code><em>patList</em></code> argument
-matches <code><em>string</em></code> and no default is given, then the <a href="#_case"><strong><code>case</code></strong></a> command returns
-an empty string.</p></div>
-<div class="paragraph"><p>Two syntaxes are provided.</p></div>
-<div class="paragraph"><p>The first uses a separate argument for each of the patterns and commands;
-this form is convenient if substitutions are desired on some of the
-patterns or commands.</p></div>
-<div class="paragraph"><p>The second form places all of the patterns and commands together into
-a single argument; the argument must have proper list structure, with
-the elements of the list being the patterns and commands.</p></div>
-<div class="paragraph"><p>The second form makes it easy to construct multi-line case commands,
-since the braces around the whole list make it unnecessary to include a
-backslash at the end of each line.</p></div>
-<div class="paragraph"><p>Since the <code><em>patList</em></code> arguments are in braces in the second form,
-no command or variable substitutions are performed on them; this makes
-the behaviour of the second form different than the first form in some
-cases.</p></div>
-<div class="paragraph"><p>Below are some examples of <a href="#_case"><strong><code>case</code></strong></a> commands:</p></div>
-<div class="literalblock">
-<div class="content">
-<pre><code>case abc in {a b} {format 1} default {format 2} a* {format 3}</code></pre>
-</div></div>
-<div class="paragraph"><p>will return <em>3</em>,</p></div>
-<div class="literalblock">
-<div class="content">
-<pre><code>case a in {
- {a b} {format 1}
- default {format 2}
- a* {format 3}
-}</code></pre>
-</div></div>
-<div class="paragraph"><p>will return <em>1</em>, and</p></div>
-<div class="literalblock">
-<div class="content">
-<pre><code>case xyz {
- {a b}
- {format 1}
- default
- {format 2}
- a*
- {format 3}
-}</code></pre>
-</div></div>
-<div class="paragraph"><p>will return <em>2</em>.</p></div>
+<div class="paragraph"><p>The obsolete <em><code><strong>case</strong></code></em> command has been removed from Jim Tcl since v0.75.
+Use <a href="#_switch"><strong><code>switch</code></strong></a> instead.</p></div>
</div>
<div class="sect2">
<h3 id="_catch">catch</h3>
@@ -3539,21 +3380,21 @@ the value of the key <code>-errorcode</code> will contain the
same value as the global variable $::errorCode, and the value of
the key <code>-level</code> will be the current return level (see <a href="#_return"><strong><code>return</code></strong></a> <code>-level</code>).
This can be useful to rethrow an error:</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>if {[catch {...} msg opts]} {
- ...maybe do something with the error...
- incr opts(-level)
- return {*}$opts $msg
-}</code></pre>
+<pre><code> if {[catch {...} msg opts]} {
+ ...maybe do something with the error...
+ incr opts(-level)
+ return {*}$opts $msg
+ }</code></pre>
</div></div>
<div class="paragraph"><p>Normally <a href="#_catch"><strong><code>catch</code></strong></a> will <code><em>not</em></code> catch any of the codes <code>JIM_EXIT</code>, <code>JIM_EVAL</code> or <code>JIM_SIGNAL</code>.
The set of codes which will be caught may be modified by specifying the one more codes before
<code><em>command</em></code>.</p></div>
<div class="paragraph"><p>e.g. To catch <code>JIM_EXIT</code> but not <code>JIM_BREAK</code> or <code>JIM_CONTINUE</code></p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>catch -exit -nobreak -nocontinue -- { ... }</code></pre>
+<pre><code> catch -exit -nobreak -nocontinue -- { ... }</code></pre>
</div></div>
<div class="paragraph"><p>The use of <code>--</code> is optional. It signifies that no more return code options follow.</p></div>
<div class="paragraph"><p>Note that if a signal marked as <a href="#_signal"><strong><code>signal</code></strong></a> <code>handle</code> is caught with <a href="#_catch"><strong><code>catch</code></strong></a> <code>-signal</code>, the return value
@@ -3583,7 +3424,7 @@ be removed in some applications.</p></div>
</dt>
<dd>
<p>
- Returns the current time in &#8216;clicks&#8217;.
+ Returns the current time in "clicks", a system-dependent, high-resolution time.
</p>
</dd>
<dt class="hdlist1">
@@ -3603,7 +3444,7 @@ be removed in some applications.</p></div>
</p>
</dd>
<dt class="hdlist1">
-<code><strong>clock format</strong> <em>seconds</em> ?<strong>-format</strong> <em>format?</em></code>
+<code><strong>clock format</strong> <em>seconds</em> ?<strong>-format</strong> <em>format?</em> ?<strong>-gmt</strong> <em>boolean?</em></code>
</dt>
<dd>
<p>
@@ -3613,12 +3454,22 @@ be removed in some applications.</p></div>
</p>
</dd>
<dt class="hdlist1">
-<code><strong>clock scan</strong> <em>str</em> <strong>-format</strong> <em>format</em></code>
+
+</dt>
+<dd>
+<p>
+ If <code><em>boolean</em></code> is true, processing is performed in UTC.
+ If <code><em>boolean</em></code> is false (the default), processing is performeed in the local time zone.
+</p>
+</dd>
+<dt class="hdlist1">
+<code><strong>clock scan</strong> <em>str</em> <strong>-format</strong> <em>format</em> ?<strong>-gmt</strong> <em>boolean?</em></code>
</dt>
<dd>
<p>
Scan the given time string using the given format string.
See strptime(3) for supported formats.
+ See <a href="#_clock"><strong><code>clock</code></strong></a> <code>format</code> for the handling of <em>-gmt</em>.
</p>
</dd>
</dl></div>
@@ -3637,7 +3488,7 @@ used anymore.</p></div>
<div class="paragraph"><p><code><strong>collect</strong></code></p></div>
<div class="paragraph"><p>Normally reference garbage collection is automatically performed periodically.
However it may be run immediately with the <a href="#_collect"><strong><code>collect</code></strong></a> command.</p></div>
-<div class="paragraph"><p>See GARBAGE COLLECTION, REFERENCES, LAMBDA FUNCTION for more detail.</p></div>
+<div class="paragraph"><p>See <a href="#_garbage_collection_references_lambda_function">GARBAGE COLLECTION</a> for more detail.</p></div>
</div>
<div class="sect2">
<h3 id="_concat">concat</h3>
@@ -3645,14 +3496,14 @@ However it may be run immediately with the <a href="#_collect"><strong><code>col
<div class="paragraph"><p>This command treats each argument as a list and concatenates them
into a single list. It permits any number of arguments. For example,
the command</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>concat a b {c d e} {f {g h}}</code></pre>
+<pre><code> concat a b {c d e} {f {g h}}</code></pre>
</div></div>
<div class="paragraph"><p>will return</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>a b c d e f {g h}</code></pre>
+<pre><code> a b c d e f {g h}</code></pre>
</div></div>
<div class="paragraph"><p>as its result.</p></div>
</div>
@@ -3670,12 +3521,12 @@ the loop&#8217;s body but continue with the next iteration of the loop.</p></div
<div class="paragraph"><p>Similar to <a href="#_alias"><strong><code>alias</code></strong></a> except it creates an anonymous procedure (lambda) instead of
a named procedure.</p></div>
<div class="paragraph"><p>the following creates a local, unnamed alias for the command <a href="#_info"><strong><code>info</code></strong></a> <code>exists</code>.</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>set e [local curry info exists]
-if {[$e var]} {
- ...
-}</code></pre>
+<pre><code> set e [local curry info exists]
+ if {[$e var]} {
+ ...
+ }</code></pre>
</div></div>
<div class="paragraph"><p><a href="#_curry"><strong><code>curry</code></strong></a> returns the name of the procedure.</p></div>
<div class="paragraph"><p>See also <a href="#_proc"><strong><code>proc</code></strong></a>, <a href="#_alias"><strong><code>alias</code></strong></a>, <a href="#_lambda"><strong><code>lambda</code></strong></a>, <a href="#_local"><strong><code>local</code></strong></a>.</p></div>
@@ -3850,11 +3701,11 @@ it is used to initialize the stacktrace.</p></div>
if a caught error cannot be handled successfully, <code><em>stacktrace</em></code> can be used
to return a stack trace reflecting the original point of occurrence
of the error:</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>catch {...} errMsg
-...
-error $errMsg [info stacktrace]</code></pre>
+<pre><code> catch {...} errMsg
+ ...
+ error $errMsg [info stacktrace]</code></pre>
</div></div>
<div class="paragraph"><p>See also <code>errorInfo</code>, <a href="#_info"><strong><code>info</code></strong></a> <code>stacktrace</code>, <a href="#_catch"><strong><code>catch</code></strong></a> and <a href="#_return"><strong><code>return</code></strong></a></p></div>
</div>
@@ -3863,12 +3714,12 @@ error $errMsg [info stacktrace]</code></pre>
<div class="paragraph"><p><code><strong>errorInfo</strong> <em>error ?stacktrace?</em></code></p></div>
<div class="paragraph"><p>Returns a human-readable representation of the given error message and stack trace.
Typical usage is:</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>if {[catch {...} error]} {
- puts stderr [errorInfo $error [info stacktrace]]
- exit 1
-}</code></pre>
+<pre><code> if {[catch {...} error]} {
+ puts stderr [errorInfo $error [info stacktrace]]
+ exit 1
+ }</code></pre>
</div></div>
<div class="paragraph"><p>See also <a href="#_error"><strong><code>error</code></strong></a>.</p></div>
</div>
@@ -4112,13 +3963,13 @@ to 0.</p></div>
<h3 id="_expr">expr</h3>
<div class="paragraph"><p><code><strong>expr</strong> <em>arg</em></code></p></div>
<div class="paragraph"><p>Calls the expression processor to evaluate <code><em>arg</em></code>, and returns
-the result as a string. See the section EXPRESSIONS above.</p></div>
+the result as a string. See the section <a href="#_expressions">EXPRESSIONS</a> above.</p></div>
<div class="paragraph"><p>Note that Jim supports a shorthand syntax for <a href="#_expr"><strong><code>expr</code></strong></a> as <code>$(...)</code>
The following two are identical.</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>set x [expr {3 * 2 + 1}]
-set x $(3 * 2 + 1)</code></pre>
+<pre><code> set x [expr {3 * 2 + 1}]
+ set x $(3 * 2 + 1)</code></pre>
</div></div>
</div>
<div class="sect2">
@@ -4280,6 +4131,17 @@ abbreviation for <code><em>option</em></code> is acceptable. The valid options
</p>
</dd>
<dt class="hdlist1">
+<code><strong>file mtimeus</strong> <em>name ?time_us?</em></code>
+</dt>
+<dd>
+<p>
+ As for <a href="#_file"><strong><code>file</code></strong></a> <code>mtime</code> except the time value is in microseconds
+ since the epoch (see also <a href="#_clock"><strong><code>clock</code></strong></a> <code>microseconds</code>).
+ Note that some platforms and some filesystems don&#8217;t support high
+ resolution timestamps for files.
+</p>
+</dd>
+<dt class="hdlist1">
<code><strong>file normalize</strong> <em>name</em></code>
</dt>
<dd>
@@ -4338,13 +4200,14 @@ abbreviation for <code><em>option</em></code> is acceptable. The valid options
</p>
</dd>
<dt class="hdlist1">
-<code><strong>file size</strong> <em>name</em></code>
+<code><strong>file split</strong> <em>name</em></code>
</dt>
<dd>
<p>
- Return a decimal string giving the size of file <code><em>name</em></code> in bytes.
- If the file doesn&#8217;t exist or its size cannot be queried then an
- error is generated.
+ Returns a list whose elements are the path components in <code><em>name</em></code>.
+ The first element of the list will have the same path type as
+ <code><em>name</em></code>. All other elements will be relative. Path separators
+ will be discarded.
</p>
</dd>
<dt class="hdlist1">
@@ -4355,7 +4218,7 @@ abbreviation for <code><em>option</em></code> is acceptable. The valid options
Invoke the <em>stat</em> kernel call on <code><em>name</em></code>, and return the result
as a dictionary with the following keys: <em>atime</em>,
<em>ctime</em>, <em>dev</em>, <em>gid</em>, <em>ino</em>, <em>mode</em>, <em>mtime</em>,
- <em>nlink</em>, <em>size</em>, <em>type</em>, <em>uid</em>.
+ <em>nlink</em>, <em>size</em>, <em>type</em>, <em>uid</em>, <em>mtimeus</em> (if supported - see <a href="#_file"><strong><code>file</code></strong></a> <code>mtimeus</code>)
Each element except <em>type</em> is a decimal string with the value of
the corresponding field from the <em>stat</em> return structure; see the
manual entry for <em>stat</em> for details on the meanings of the values.
@@ -4406,13 +4269,13 @@ abbreviation for <code><em>option</em></code> is acceptable. The valid options
</dl></div>
<div class="paragraph"><p>The <a href="#_file"><strong><code>file</code></strong></a> commands that return 0/1 results are often used in
conditional or looping commands, for example:</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>if {![file exists foo]} {
- error {bad file name}
-} else {
- ...
-}</code></pre>
+<pre><code> if {![file exists foo]} {
+ error {bad file name}
+ } else {
+ ...
+ }</code></pre>
</div></div>
</div>
<div class="sect2">
@@ -4423,7 +4286,7 @@ conditional or looping commands, for example:</p></div>
the empty string to remove the current finalizer.</p></div>
<div class="paragraph"><p>The reference must be a valid reference create with the <a href="#_ref"><strong><code>ref</code></strong></a>
command.</p></div>
-<div class="paragraph"><p>See GARBAGE COLLECTION, REFERENCES, LAMBDA FUNCTION for more detail.</p></div>
+<div class="paragraph"><p>See <a href="#_garbage_collection_references_lambda_function">GARBAGE COLLECTION</a> for more detail.</p></div>
</div>
<div class="sect2">
<h3 id="_flush">flush</h3>
@@ -4505,7 +4368,7 @@ correctly even if the argument is in braces.</p></div>
<div class="paragraph"><p><code><strong>getref</strong> <em>reference</em></code></p></div>
<div class="paragraph"><p>Returns the string associated with <code><em>reference</em></code>. The reference must
be a valid reference create with the <a href="#_ref"><strong><code>ref</code></strong></a> command.</p></div>
-<div class="paragraph"><p>See GARBAGE COLLECTION, REFERENCES, LAMBDA FUNCTION for more detail.</p></div>
+<div class="paragraph"><p>See <a href="#_garbage_collection_references_lambda_function">GARBAGE COLLECTION</a> for more detail.</p></div>
</div>
<div class="sect2">
<h3 id="_gets">gets</h3>
@@ -4903,7 +4766,7 @@ string formed by joining all of the elements of <code><em>list</em></code> toget
<div class="paragraph"><p>The <a href="#_lambda"><strong><code>lambda</code></strong></a> command is identical to <a href="#_proc"><strong><code>proc</code></strong></a>, except rather than
creating a named procedure, it creates an anonymous procedure and returns
the name of the procedure.</p></div>
-<div class="paragraph"><p>See <a href="#_proc"><strong><code>proc</code></strong></a> and GARBAGE COLLECTION, REFERENCES, LAMBDA FUNCTION for more detail.</p></div>
+<div class="paragraph"><p>See <a href="#_proc"><strong><code>proc</code></strong></a> and <a href="#_garbage_collection_references_lambda_function">GARBAGE COLLECTION</a> for more detail.</p></div>
</div>
<div class="sect2">
<h3 id="_lappend">lappend</h3>
@@ -4916,14 +4779,14 @@ by the <code><em>value</em></code> arguments. <a href="#_lappend"><strong><code>
each <code><em>value</em></code> is appended as a list element rather than raw text.</p></div>
<div class="paragraph"><p>This command provides a relatively efficient way to build up large lists.
For example,</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>lappend a $b</code></pre>
+<pre><code> lappend a $b</code></pre>
</div></div>
<div class="paragraph"><p>is much more efficient than</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>set a [concat $a [list $b]]</code></pre>
+<pre><code> set a [concat $a [list $b]]</code></pre>
</div></div>
<div class="paragraph"><p>when <code>$a</code> is long.</p></div>
</div>
@@ -4934,11 +4797,11 @@ For example,</p></div>
the variables given by the <code><em>varName</em></code> arguments in order. If there are more variable names than
list elements, the remaining variables are set to the empty string. If there are more list elements
than variables, a list of unassigned elements is returned.</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>jim&gt; lassign {1 2 3} a b; puts a=$a,b=$b
-3
-a=1,b=2</code></pre>
+<pre><code> . lassign {1 2 3} a b; puts a=$a,b=$b
+ 3
+ a=1,b=2</code></pre>
</div></div>
</div>
<div class="sect2">
@@ -4955,36 +4818,32 @@ via <a href="#_upcall"><strong><code>upcall</code></strong></a>. The previous co
procedure exits. See <a href="#_upcall"><strong><code>upcall</code></strong></a> for more details.</p></div>
<div class="paragraph"><p>In this example, a local procedure is created. Note that the procedure
continues to have global scope while it is active.</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>proc outer {} {
- # proc ... returns "inner" which is marked local
- local proc inner {} {
- # will be deleted when 'outer' exits
- }</code></pre>
-</div></div>
-<div class="literalblock">
-<div class="content">
-<pre><code> inner
- ...
-}</code></pre>
+<pre><code> proc outer {} {
+ # proc ... returns "inner" which is marked local
+ local proc inner {} {
+ # will be deleted when 'outer' exits
+ }
+
+ inner
+ ...
+ }</code></pre>
</div></div>
<div class="paragraph"><p>In this example, the lambda is deleted at the end of the procedure rather
than waiting until garbage collection.</p></div>
-<div class="literalblock">
-<div class="content">
-<pre><code>proc outer {} {
- set x [lambda inner {args} {
- # will be deleted when 'outer' exits
- }]
- # Use 'function' here which simply returns $x
- local function $x</code></pre>
-</div></div>
-<div class="literalblock">
-<div class="content">
-<pre><code> $x ...
- ...
-}</code></pre>
+<div class="listingblock">
+<div class="content">
+<pre><code> proc outer {} {
+ set x [lambda inner {args} {
+ # will be deleted when 'outer' exits
+ }]
+ # Use 'function' here which simply returns $x
+ local function $x
+
+ $x ...
+ ...
+ }</code></pre>
</div></div>
</div>
<div class="sect2">
@@ -4992,9 +4851,9 @@ than waiting until garbage collection.</p></div>
<div class="paragraph"><p><code><strong>loop</strong> <em>var first limit ?incr? body</em></code></p></div>
<div class="paragraph"><p>Similar to <a href="#_for"><strong><code>for</code></strong></a> except simpler and possibly more efficient.
With a positive increment, equivalent to:</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>for {set var $first} {$var &lt; $limit} {incr var $incr} $body</code></pre>
+<pre><code> for {set var $first} {$var &lt; $limit} {incr var $incr} $body</code></pre>
</div></div>
<div class="paragraph"><p>If <code><em>incr</em></code> is not specified, 1 is used.
Note that setting the loop variable inside the loop does not
@@ -5005,7 +4864,7 @@ affect the loop count.</p></div>
<div class="paragraph"><p><code><strong>lindex</strong> <em>list ?index &#8230;?</em></code></p></div>
<div class="paragraph"><p>Treats <code><em>list</em></code> as a Tcl list and returns element <code><em>index</em></code> from it
(0 refers to the first element of the list).
-See STRING AND LIST INDEX SPECIFICATIONS for all allowed forms for <code><em>index</em></code>.</p></div>
+See <a href="#_string_and_list_index_specifications">STRING AND LIST INDEX SPECIFICATIONS</a> for all allowed forms for <code><em>index</em></code>.</p></div>
<div class="paragraph"><p>In extracting the element, <code><em>lindex</em></code> observes the same rules concerning
braces and quotes and backslashes as the Tcl command interpreter; however,
variable substitution and command substitution do not occur.</p></div>
@@ -5027,7 +4886,7 @@ or equal to zero, then the new elements are inserted at the
beginning of the list. If <code><em>index</em></code> is greater than or equal
to the number of elements in the list, then the new elements are
appended to the list.</p></div>
-<div class="paragraph"><p>See STRING AND LIST INDEX SPECIFICATIONS for all allowed forms for <code><em>index</em></code>.</p></div>
+<div class="paragraph"><p>See <a href="#_string_and_list_index_specifications">STRING AND LIST INDEX SPECIFICATIONS</a> for all allowed forms for <code><em>index</em></code>.</p></div>
</div>
<div class="sect2">
<h3 id="_list">list</h3>
@@ -5041,19 +4900,19 @@ its arguments. <a href="#_list"><strong><code>list</code></strong></a> produces
<a href="#_concat"><strong><code>concat</code></strong></a>: <a href="#_concat"><strong><code>concat</code></strong></a> removes one level of grouping before forming
the list, while <a href="#_list"><strong><code>list</code></strong></a> works directly from the original arguments.
For example, the command</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>list a b {c d e} {f {g h}}</code></pre>
+<pre><code> list a b {c d e} {f {g h}}</code></pre>
</div></div>
<div class="paragraph"><p>will return</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>a b {c d e} {f {g h}}</code></pre>
+<pre><code> a b {c d e} {f {g h}}</code></pre>
</div></div>
<div class="paragraph"><p>while <a href="#_concat"><strong><code>concat</code></strong></a> with the same arguments will return</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>a b c d e f {g h}</code></pre>
+<pre><code> a b c d e f {g h}</code></pre>
</div></div>
</div>
<div class="sect2">
@@ -5071,9 +4930,9 @@ as the name of a variable containing a Tcl list. It also accepts
zero or more indices into the list. Finally, it accepts a new value
for an element of varName. If no indices are presented, the command
takes the form:</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>lset varName newValue</code></pre>
+<pre><code> lset varName newValue</code></pre>
</div></div>
<div class="paragraph"><p>In this case, newValue replaces the old value of the variable
varName.</p></div>
@@ -5089,14 +4948,14 @@ stored in the variable varName, and is also the return value from
the <a href="#_lset"><strong><code>lset</code></strong></a> command.</p></div>
<div class="paragraph"><p>If index is negative or greater than or equal to the number of
elements in $varName, then an error occurs.</p></div>
-<div class="paragraph"><p>See STRING AND LIST INDEX SPECIFICATIONS for all allowed forms for <code><em>index</em></code>.</p></div>
+<div class="paragraph"><p>See <a href="#_string_and_list_index_specifications">STRING AND LIST INDEX SPECIFICATIONS</a> for all allowed forms for <code><em>index</em></code>.</p></div>
<div class="paragraph"><p>If additional index arguments are supplied, then each argument is
used in turn to address an element within a sublist designated by
the previous indexing operation, allowing the script to alter
elements in sublists. The command,</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>lset a 1 2 newValue</code></pre>
+<pre><code> lset a 1 2 newValue</code></pre>
</div></div>
<div class="paragraph"><p>replaces element 2 of sublist 1 with <code><em>newValue</em></code>.</p></div>
<div class="paragraph"><p>The integer appearing in each index argument must be greater than
@@ -5111,12 +4970,12 @@ index is outside the permitted range, an error is reported.</p></div>
<div class="paragraph"><p><code><strong>lmap</strong> <em>varList list ?varList2 list2 ...? body</em></code></p></div>
<div class="paragraph"><p><a href="#_lmap"><strong><code>lmap</code></strong></a> is a "collecting" <a href="#_foreach"><strong><code>foreach</code></strong></a> which returns a list of its results.</p></div>
<div class="paragraph"><p>For example:</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>jim&gt; lmap i {1 2 3 4 5} {expr $i*$i}
-1 4 9 16 25
-jim&gt; lmap a {1 2 3} b {A B C} {list $a $b}
-{1 A} {2 B} {3 C}</code></pre>
+<pre><code> . lmap i {1 2 3 4 5} {expr $i*$i}
+ 1 4 9 16 25
+ . lmap a {1 2 3} b {A B C} {list $a $b}
+ {1 A} {2 B} {3 C}</code></pre>
</div></div>
<div class="paragraph"><p>If the body invokes <a href="#_continue"><strong><code>continue</code></strong></a>, no value is added for this iteration.
If the body invokes <a href="#_break"><strong><code>break</code></strong></a>, the loop ends and no more values are added.</p></div>
@@ -5135,7 +4994,7 @@ should not be used directly. Instead it is invoked automatically by <a href="#_p
<div class="paragraph"><p><code><strong>lrange</strong> <em>list first last</em></code></p></div>
<div class="paragraph"><p><code><em>list</em></code> must be a valid Tcl list. This command will return a new
list consisting of elements <code><em>first</em></code> through <code><em>last</em></code>, inclusive.</p></div>
-<div class="paragraph"><p>See STRING AND LIST INDEX SPECIFICATIONS for all allowed forms for <code><em>first</em></code> and <code><em>last</em></code>.</p></div>
+<div class="paragraph"><p>See <a href="#_string_and_list_index_specifications">STRING AND LIST INDEX SPECIFICATIONS</a> for all allowed forms for <code><em>first</em></code> and <code><em>last</em></code>.</p></div>
<div class="paragraph"><p>If <code><em>last</em></code> is greater than or equal to the number of elements
in the list, then it is treated as if it were <code>end</code>.</p></div>
<div class="paragraph"><p>If <code><em>first</em></code> is greater than <code><em>last</em></code> then an empty string
@@ -5157,7 +5016,7 @@ element of <code><em>list</em></code>; the element indicated by <code><em>first
must exist in the list.</p></div>
<div class="paragraph"><p><code><em>last</em></code> gives the index in <code><em>list</em></code> of the last element
to be replaced; it must be greater than or equal to <code><em>first</em></code>.</p></div>
-<div class="paragraph"><p>See STRING AND LIST INDEX SPECIFICATIONS for all allowed forms for <code><em>first</em></code> and <code><em>last</em></code>.</p></div>
+<div class="paragraph"><p>See <a href="#_string_and_list_index_specifications">STRING AND LIST INDEX SPECIFICATIONS</a> for all allowed forms for <code><em>first</em></code> and <code><em>last</em></code>.</p></div>
<div class="paragraph"><p>The <code><em>element</em></code> arguments specify zero or more new arguments to
be added to the list in place of those that were deleted.</p></div>
<div class="paragraph"><p>Each <code><em>element</em></code> argument will become a separate element of
@@ -5170,20 +5029,20 @@ between <code><em>first</em></code> and <code><em>last</em></code> are simply de
<div class="paragraph"><p><code><strong>lrepeat</strong> <em>number element1 ?element2 ...?</em></code></p></div>
<div class="paragraph"><p>Build a list by repeating elements <code><em>number</em></code> times (which must be
a positive integer).</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>jim&gt; lrepeat 3 a b
-a b a b a b</code></pre>
+<pre><code> . lrepeat 3 a b
+ a b a b a b</code></pre>
</div></div>
</div>
<div class="sect2">
<h3 id="_lreverse">lreverse</h3>
<div class="paragraph"><p><code><strong>lreverse</strong> <em>list</em></code></p></div>
<div class="paragraph"><p>Returns the list in reverse order.</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>jim&gt; lreverse {1 2 3}
-3 2 1</code></pre>
+<pre><code> . lreverse {1 2 3}
+ 3 2 1</code></pre>
</div></div>
</div>
<div class="sect2">
@@ -5308,6 +5167,21 @@ the given index is extracted from the list for comparison. The list index may
be any valid list index, such as <code>1</code>, <code>end</code> or <code>end-2</code>.</p></div>
</div>
<div class="sect2">
+<h3 id="_defer">defer</h3>
+<div class="paragraph"><p><code><strong>defer</strong> <em>script</em></code></p></div>
+<div class="paragraph"><p>This command is a simple helper command to add a script to the <em><code>$jim::defer</code></em> variable
+that will run when the current proc or interpreter exits. For example:</p></div>
+<div class="listingblock">
+<div class="content">
+<pre><code> . proc a {} { defer {puts "Leaving a"}; puts "Exit" }
+ . a
+ Exit
+ Leaving a</code></pre>
+</div></div>
+<div class="paragraph"><p>If the <em><code>$jim::defer</code></em> variable exists, it is treated as a list of scripts to run
+when the proc or interpreter exits.</p></div>
+</div>
+<div class="sect2">
<h3 id="_open">open</h3>
<div class="paragraph"><p><code><strong>open</strong> <em>fileName ?access?</em></code></p></div>
<div class="paragraph"><p><code><strong>open</strong> <em>|command-pipeline ?access?</em></code></p></div>
@@ -5428,7 +5302,7 @@ When the new command is invoked, the contents of <code><em>body</em></code> will
Tcl interpreter. <code><em>args</em></code> specifies the formal arguments to the procedure.
If specified, <code><em>statics</em></code>, declares static variables which are bound to the
procedure.</p></div>
-<div class="paragraph"><p>See PROCEDURES for detailed information about Tcl procedures.</p></div>
+<div class="paragraph"><p>See &lt;&lt;_procedures,PROCEDURES&gt; for detailed information about Tcl procedures.</p></div>
<div class="paragraph"><p>The <a href="#_proc"><strong><code>proc</code></strong></a> command returns <code><em>name</em></code> (which is useful with <a href="#_local"><strong><code>local</code></strong></a>).</p></div>
<div class="paragraph"><p>When a procedure is invoked, the procedure&#8217;s return value is the
value specified in a <a href="#_return"><strong><code>return</code></strong></a> command. If the procedure doesn&#8217;t
@@ -5455,6 +5329,20 @@ switch.</p></div>
command may be used to force buffered characters to be output.</p></div>
</div>
<div class="sect2">
+<h3 id="_pipe">pipe</h3>
+<div class="paragraph"><p>Creates a pair of <a href="#_aio"><strong><code>aio</code></strong></a> channels and returns the handles as a list: <code>{read write}</code></p></div>
+<div class="listingblock">
+<div class="content">
+<pre><code> lassign [pipe] r w
+
+ # Must close $w after exec
+ exec ps &gt;@$w &amp;
+ $w close
+
+ $r readable ...</code></pre>
+</div></div>
+</div>
+<div class="sect2">
<h3 id="_pwd">pwd</h3>
<div class="paragraph"><p><code><strong>pwd</strong></code></p></div>
<div class="paragraph"><p>Returns the path name of the current working directory.</p></div>
@@ -5471,16 +5359,16 @@ command may be used to force buffered characters to be output.</p></div>
<div class="paragraph"><p><code><strong>range</strong> <em>?start? end ?step?</em></code></p></div>
<div class="paragraph"><p>Returns a list of integers starting at <code><em>start</em></code> (defaults to 0)
and ranging up to but not including <code><em>end</em></code> in steps of <code><em>step</em></code> defaults to 1).</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>jim&gt; range 5
-0 1 2 3 4
-jim&gt; range 2 5
-2 3 4
-jim&gt; range 2 10 4
-2 6
-jim&gt; range 7 4 -2
-7 5</code></pre>
+<pre><code> . range 5
+ 0 1 2 3 4
+ . range 2 5
+ 2 3 4
+ . range 2 10 4
+ 2 6
+ . range 7 4 -2
+ 7 5</code></pre>
</div></div>
</div>
<div class="sect2">
@@ -5505,7 +5393,7 @@ to <a href="#_open"><strong><code>open</code></strong></a>; it must refer to a f
<div class="paragraph"><p><code><strong>regexp ?-nocase? ?-line? ?-indices? ?-start</strong> <em>offset</em>? <strong>?-all? ?-inline? ?--?</strong> <em>exp string ?matchVar? ?subMatchVar subMatchVar ...?</em></code></p></div>
<div class="paragraph"><p>Determines whether the regular expression <code><em>exp</em></code> matches part or
all of <code><em>string</em></code> and returns 1 if it does, 0 if it doesn&#8217;t.</p></div>
-<div class="paragraph"><p>See REGULAR EXPRESSIONS above for complete information on the
+<div class="paragraph"><p>See <a href="#_regular_expressions">REGULAR EXPRESSIONS</a> above for complete information on the
syntax of <code><em>exp</em></code> and how it is matched against <code><em>string</em></code>.</p></div>
<div class="paragraph"><p>If additional arguments are specified after <code><em>string</em></code> then they
are treated as the names of variables to use to return
@@ -5706,11 +5594,11 @@ If <code><em>finalizer</em></code> is specified, it is a command which will be i
when the a garbage collection cycle runs and this reference is
no longer accessible.</p></div>
<div class="paragraph"><p>The finalizer is invoked as:</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>finalizer reference string</code></pre>
+<pre><code> finalizer reference string</code></pre>
</div></div>
-<div class="paragraph"><p>See GARBAGE COLLECTION, REFERENCES, LAMBDA FUNCTION for more detail.</p></div>
+<div class="paragraph"><p>See <a href="#_garbage_collection_references_lambda_function">GARBAGE COLLECTION</a> for more detail.</p></div>
</div>
<div class="sect2">
<h3 id="_rename">rename</h3>
@@ -5827,7 +5715,7 @@ in the global scope.</p></div>
<div class="paragraph"><p>Store a new string in <code><em>reference</em></code>, replacing the existing string.
The reference must be a valid reference create with the <a href="#_ref"><strong><code>ref</code></strong></a>
command.</p></div>
-<div class="paragraph"><p>See GARBAGE COLLECTION, REFERENCES, LAMBDA FUNCTION for more detail.</p></div>
+<div class="paragraph"><p>See <a href="#_garbage_collection_references_lambda_function">GARBAGE COLLECTION</a> for more detail.</p></div>
</div>
<div class="sect2">
<h3 id="_signal">signal</h3>
@@ -5862,11 +5750,24 @@ command.</p></div>
</p>
</dd>
<dt class="hdlist1">
+<code><strong>signal block</strong> ?<em>signals ...</em>?</code>
+</dt>
+<dd>
+<p>
+ If no signals are given, returns a lists all signals which are currently
+ being blocked.
+ If signals are specified, these are added to the list of signals
+ currently being blocked. These signals are not delivered to the process.
+ This can be useful for signals such as <code>SIGPIPE</code>, especially in conjunction
+ with <a href="#_exec"><strong><code>exec</code></strong></a> as child processes inherit the parent&#8217;s signal disposition.
+</p>
+</dd>
+<dt class="hdlist1">
<code><strong>signal default</strong> ?<em>signals ...</em>?</code>
</dt>
<dd>
<p>
- If no signals are given, returns a lists all signals which are currently have
+ If no signals are given, returns a lists all signals which currently have
the default behaviour.
If signals are specified, these are added to the list of signals which have
the default behaviour.
@@ -5892,41 +5793,43 @@ command.</p></div>
Raises the given signal, which defaults to <code>SIGINT</code> if not specified.
The behaviour is identical to:
</p>
-<div class="literalblock">
-<div class="content">
-<pre><code>kill signal [pid]</code></pre>
-</div></div>
</dd>
</dl></div>
+<div class="listingblock">
+<div class="content">
+<pre><code> kill signal [pid]</code></pre>
+</div></div>
<div class="paragraph"><p>Note that <a href="#_signal"><strong><code>signal</code></strong></a> <code>handle</code> and <a href="#_signal"><strong><code>signal</code></strong></a> <code>ignore</code> represent two forms of signal
handling. <a href="#_signal"><strong><code>signal</code></strong></a> <code>handle</code> is used in conjunction with <a href="#_catch"><strong><code>catch</code></strong></a> <code>-signal</code> or <a href="#_try"><strong><code>try</code></strong></a> <code>-signal</code>
to immediately abort execution when the signal is delivered. Alternatively, <a href="#_signal"><strong><code>signal</code></strong></a> <code>ignore</code>
is used in conjunction with <a href="#_signal"><strong><code>signal</code></strong></a> <code>check</code> to handle signal synchronously. Consider the
two examples below.</p></div>
<div class="paragraph"><p>Prevent a processing from taking too long</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>signal handle SIGALRM
-alarm 20
-try -signal {
- .. possibly long running process ..
- alarm 0
-} on signal {sig} {
- puts stderr "Process took too long"
-}</code></pre>
+<pre><code> signal handle SIGALRM
+ alarm 20
+ try -signal {
+ .. possibly long running process ..
+ alarm 0
+ } on signal {sig} {
+ puts stderr "Process took too long"
+ }</code></pre>
</div></div>
<div class="paragraph"><p>Handle SIGHUP to reconfigure:</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>signal ignore SIGHUP
-while {1} {
- ... handle configuration/reconfiguration ...
- while {[signal check -clear SIGHUP] eq ""} {
- ... do processing ..
- }
- # Received SIGHUP, so reconfigure
-}</code></pre>
+<pre><code> signal ignore SIGHUP
+ while {1} {
+ ... handle configuration/reconfiguration ...
+ while {[signal check -clear SIGHUP] eq ""} {
+ ... do processing ..
+ }
+ # Received SIGHUP, so reconfigure
+ }</code></pre>
</div></div>
+<div class="paragraph"><p>Note: signal handling is currently not supported in child interpreters.
+In these interpreters, the signal command does not exist.</p></div>
</div>
<div class="sect2">
<h3 id="_sleep">sleep</h3>
@@ -5962,14 +5865,14 @@ character of <code><em>string</em></code> is in <code><em>splitChars</em></code>
<code><em>string</em></code> becomes a separate element of the result list.</p></div>
<div class="paragraph"><p><code><em>splitChars</em></code> defaults to the standard white-space characters.
For example,</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>split "comp.unix.misc" .</code></pre>
+<pre><code> split "comp.unix.misc" .</code></pre>
</div></div>
<div class="paragraph"><p>returns <code><em>"comp unix misc"</em></code> and</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>split "Hello world" {}</code></pre>
+<pre><code> split "Hello world" {}</code></pre>
</div></div>
<div class="paragraph"><p>returns <code><em>"H e l l o { } w o r l d"</em></code>.</p></div>
</div>
@@ -6000,7 +5903,7 @@ The legal options (which may be abbreviated) are:</p></div>
Returns the length of the string in bytes. This will return
the same value as <a href="#_string"><strong><code>string</code></strong></a> <code>length</code> if UTF-8 support is not enabled,
or if the string is composed entirely of ASCII characters.
- See UTF-8 AND UNICODE.
+ See <a href="#_utf_8_and_unicode">UTF-8 AND UNICODE</a>.
</p>
</dd>
<dt class="hdlist1">
@@ -6062,7 +5965,7 @@ The legal options (which may be abbreviated) are:</p></div>
</dt>
<dd>
<p>
- See STRING AND LIST INDEX SPECIFICATIONS for all allowed forms for <code><em>firstIndex</em></code>.
+ See <a href="#_string_and_list_index_specifications">STRING AND LIST INDEX SPECIFICATIONS</a> for all allowed forms for <code><em>firstIndex</em></code>.
</p>
</dd>
<dt class="hdlist1">
@@ -6083,7 +5986,7 @@ The legal options (which may be abbreviated) are:</p></div>
</dt>
<dd>
<p>
- See STRING AND LIST INDEX SPECIFICATIONS for all allowed forms for <code><em>charIndex</em></code>.
+ See <a href="#_string_and_list_index_specifications">STRING AND LIST INDEX SPECIFICATIONS</a> for all allowed forms for <code><em>charIndex</em></code>.
</p>
</dd>
<dt class="hdlist1">
@@ -6231,7 +6134,7 @@ Any hexadecimal digit character ([0-9A-Fa-f]).
</dt>
<dd>
<p>
- Note that string classification does <code><em>not</em></code> respect UTF-8. See UTF-8 AND UNICODE
+ Note that string classification does <code><em>not</em></code> respect UTF-8. See <a href="#_utf_8_and_unicode">UTF-8 AND UNICODE</a>.
</p>
</dd>
<dt class="hdlist1">
@@ -6259,7 +6162,7 @@ Any hexadecimal digit character ([0-9A-Fa-f]).
</dt>
<dd>
<p>
- See STRING AND LIST INDEX SPECIFICATIONS for all allowed forms for <code><em>lastIndex</em></code>.
+ See <a href="#_string_and_list_index_specifications">STRING AND LIST INDEX SPECIFICATIONS</a> for all allowed forms for <code><em>lastIndex</em></code>.
</p>
</dd>
<dt class="hdlist1">
@@ -6269,7 +6172,7 @@ Any hexadecimal digit character ([0-9A-Fa-f]).
<p>
Returns a decimal string giving the number of characters in <code><em>string</em></code>.
If UTF-8 support is enabled, this may be different than the number of bytes.
- See UTF-8 AND UNICODE
+ See <a href="#_utf_8_and_unicode">UTF-8 AND UNICODE</a>.
</p>
</dd>
<dt class="hdlist1">
@@ -6287,11 +6190,13 @@ Any hexadecimal digit character ([0-9A-Fa-f]).
only iterated over once, so earlier key replacements will have no affect for
later key matches. For example,
</p>
-<div class="literalblock">
+</dd>
+</dl></div>
+<div class="listingblock">
<div class="content">
-<pre><code>string map {abc 1 ab 2 a 3 1 0} 1abcaababcabababc</code></pre>
+<pre><code> string map {abc 1 ab 2 a 3 1 0} 1abcaababcabababc</code></pre>
</div></div>
-</dd>
+<div class="dlist"><dl>
<dt class="hdlist1">
</dt>
@@ -6308,11 +6213,13 @@ Any hexadecimal digit character ([0-9A-Fa-f]).
Note that if an earlier key is a prefix of a later one, it will completely mask the later
one. So if the previous example is reordered like this,
</p>
-<div class="literalblock">
+</dd>
+</dl></div>
+<div class="listingblock">
<div class="content">
-<pre><code>string map {1 0 ab 2 a 3 abc 1} 1abcaababcabababc</code></pre>
+<pre><code> string map {1 0 ab 2 a 3 abc 1} 1abcaababcabababc</code></pre>
</div></div>
-</dd>
+<div class="dlist"><dl>
<dt class="hdlist1">
</dt>
@@ -6397,7 +6304,7 @@ Any hexadecimal digit character ([0-9A-Fa-f]).
</dt>
<dd>
<p>
- See STRING AND LIST INDEX SPECIFICATIONS for all allowed forms for <code><em>first</em></code> and <code><em>last</em></code>.
+ See <a href="#_string_and_list_index_specifications">STRING AND LIST INDEX SPECIFICATIONS</a> for all allowed forms for <code><em>first</em></code> and <code><em>last</em></code>.
</p>
</dd>
<dt class="hdlist1">
@@ -6528,10 +6435,10 @@ characters with no special interpretation.</p></div>
<div class="paragraph"><p><strong>Note</strong>: when it performs its substitutions, subst does not give any
special treatment to double quotes or curly braces. For example,
the following script returns <code>xyz {44}</code>, not <code>xyz {$a}</code>.</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>set a 44
-subst {xyz {$a}}</code></pre>
+<pre><code> set a 44
+ subst {xyz {$a}}</code></pre>
</div></div>
</div>
<div class="sect2">
@@ -6617,29 +6524,29 @@ next pattern also has a body of <code>-</code> then the body after that is
used, and so on). This feature makes it possible to share a single
body among several patterns.</p></div>
<div class="paragraph"><p>Below are some examples of <a href="#_switch"><strong><code>switch</code></strong></a> commands:</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>switch abc a - b {format 1} abc {format 2} default {format 3}</code></pre>
+<pre><code> switch abc a - b {format 1} abc {format 2} default {format 3}</code></pre>
</div></div>
<div class="paragraph"><p>will return 2,</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>switch -regexp aaab {
- ^a.*b$ -
- b {format 1}
- a* {format 2}
- default {format 3}
-}</code></pre>
+<pre><code> switch -regexp aaab {
+ ^a.*b$ -
+ b {format 1}
+ a* {format 2}
+ default {format 3}
+ }</code></pre>
</div></div>
<div class="paragraph"><p>will return 1, and</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>switch xyz {
- a -
- b {format 1}
- a* {format 2}
- default {format 3}
-}</code></pre>
+<pre><code> switch xyz {
+ a -
+ b {format 1}
+ a* {format 2}
+ default {format 3}
+ }</code></pre>
</div></div>
<div class="paragraph"><p>will return 3.</p></div>
</div>
@@ -6649,22 +6556,22 @@ body among several patterns.</p></div>
<div class="paragraph"><p>The <a href="#_tailcall"><strong><code>tailcall</code></strong></a> command provides an optimised way of invoking a command whilst replacing
the current call frame. This is similar to <em>exec</em> in Bourne Shell.</p></div>
<div class="paragraph"><p>The following are identical except the first immediately replaces the current call frame.</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>tailcall a b c</code></pre>
+<pre><code> tailcall a b c</code></pre>
</div></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>return [uplevel 1 [list a b c]]</code></pre>
+<pre><code> return [uplevel 1 [list a b c]]</code></pre>
</div></div>
<div class="paragraph"><p><a href="#_tailcall"><strong><code>tailcall</code></strong></a> is useful as a dispatch mechanism:</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>proc a {cmd args} {
- tailcall sub_$cmd {*}$args
-}
-proc sub_cmd1 ...
-proc sub_cmd2 ...</code></pre>
+<pre><code> proc a {cmd args} {
+ tailcall sub_$cmd {*}$args
+ }
+ proc sub_cmd1 ...
+ proc sub_cmd2 ...</code></pre>
</div></div>
</div>
<div class="sect2">
@@ -6691,9 +6598,9 @@ The command <code>throw 20 message</code> can be caught with an <code>on 20 ...<
<div class="paragraph"><p>This command will call the Tcl interpreter <code><em>count</em></code>
times to execute <code><em>command</em></code> (or once if <code><em>count</em></code> isn&#8217;t
specified). It will then return a string of the form</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>503 microseconds per iteration</code></pre>
+<pre><code> 503 microseconds per iteration</code></pre>
</div></div>
<div class="paragraph"><p>which indicates the average amount of time required per iteration,
in microseconds.</p></div>
@@ -6718,21 +6625,21 @@ or as integers.</p></div>
<div class="paragraph"><p>If <code><em>resultvar</em></code> and <code><em>optsvar</em></code> are specified, they are set as for <a href="#_catch"><strong><code>catch</code></strong></a> before evaluating
the matching handler.</p></div>
<div class="paragraph"><p>For example:</p></div>
-<div class="literalblock">
-<div class="content">
-<pre><code>set f [open input]
-try -signal {
- process $f
-} on {continue break} {} {
- error "Unexpected break/continue"
-} on error {msg opts} {
- puts "Dealing with error"
- return {*}$opts $msg
-} on signal sig {
- puts "Got signal: $sig"
-} finally {
- $f close
-}</code></pre>
+<div class="listingblock">
+<div class="content">
+<pre><code> set f [open input]
+ try -signal {
+ process $f
+ } on {continue break} {} {
+ error "Unexpected break/continue"
+ } on error {msg opts} {
+ puts "Dealing with error"
+ return {*}$opts $msg
+ } on signal sig {
+ puts "Got signal: $sig"
+ } finally {
+ $f close
+ }</code></pre>
</div></div>
<div class="paragraph"><p>If break, continue or error are raised, they are dealt with by the matching
handler.</p></div>
@@ -6806,17 +6713,17 @@ at top-level (only global variables will be visible).
The <a href="#_uplevel"><strong><code>uplevel</code></strong></a> command causes the invoking procedure to disappear
from the procedure calling stack while the command is being executed.
In the above example, suppose <em>c</em> invokes the command</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>uplevel 1 {set x 43; d}</code></pre>
+<pre><code> uplevel 1 {set x 43; d}</code></pre>
</div></div>
<div class="paragraph"><p>where <em>d</em> is another Tcl procedure. The <a href="#_set"><strong><code>set</code></strong></a> command will
modify the variable <em>x</em> in <em>b&#8217;s context, and 'd</em> will execute
at level 3, as if called from <em>b</em>. If it in turn executes
the command</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>uplevel {set x 42}</code></pre>
+<pre><code> uplevel {set x 42}</code></pre>
</div></div>
<div class="paragraph"><p>then the <a href="#_set"><strong><code>set</code></strong></a> command will modify the same variable <em>x</em> in <em>b&#8217;s
context: the procedure 'c</em> does not appear to be on the call stack
@@ -6849,12 +6756,12 @@ an ordinary variable.</p></div>
procedure calling and also makes it easier to build new control constructs
as Tcl procedures.
For example, consider the following procedure:</p></div>
-<div class="literalblock">
+<div class="listingblock">
<div class="content">
-<pre><code>proc add2 name {
- upvar $name x
- set x [expr $x+2]
-}</code></pre>
+<pre><code> proc add2 name {
+ upvar $name x
+ set x [expr $x+2]
+ }</code></pre>
</div></div>
<div class="paragraph"><p><em>add2</em> is invoked with an argument giving the name of a variable,
and it adds two to the value of that variable.
@@ -6863,6 +6770,25 @@ instead of <a href="#_upvar"><strong><code>upvar</code></strong></a>, <a href="#
to access the variable in the caller&#8217;s procedure frame.</p></div>
</div>
<div class="sect2">
+<h3 id="_wait">wait</h3>
+<div class="paragraph"><p><code><strong>wait</strong></code></p></div>
+<div class="paragraph"><p><code><strong>wait -nohang</strong> <em>pid</em></code></p></div>
+<div class="paragraph"><p>With no arguments, cleans up any processes started by <a href="#_exec"><strong><code>exec</code></strong></a> <code>... &amp;</code> that have completed
+(reaps zombie processes).</p></div>
+<div class="paragraph"><p>With one or two arguments, waits for a process by id, either returned by <a href="#_exec"><strong><code>exec</code></strong></a> <code>... &amp;</code>
+or by <a href="#cmd_1"><strong><code>os.fork</code></strong></a> (if supported).</p></div>
+<div class="paragraph"><p>Waits for the process to complete, unless <code>-nohang</code> is specified, in which case returns
+immediately if the process is still running.</p></div>
+<div class="paragraph"><p>Returns a list of 3 elements.</p></div>
+<div class="paragraph"><p><code>{NONE x x}</code> if the process does not exist or has already been waited for, or
+if -nohang is specified, and the process is still alive.</p></div>
+<div class="paragraph"><p><code>{CHILDSTATUS &lt;pid&gt; &lt;exit-status&gt;}</code> if the process exited normally.</p></div>
+<div class="paragraph"><p><code>{CHILDKILLED &lt;pid&gt; &lt;signal&gt;}</code> if the process terminated on a signal.</p></div>
+<div class="paragraph"><p><code>{CHILDSUSP &lt;pid&gt; none}</code> if the process terminated for some other reason.</p></div>
+<div class="paragraph"><p>Note that on platforms supporting waitpid(2), <code>pid</code> can also be given special values such
+as 0 or -1. See waitpid(2) for more detail.</p></div>
+</div>
+<div class="sect2">
<h3 id="_while">while</h3>
<div class="paragraph"><p><code><strong>while</strong> <em>test body</em></code></p></div>
<div class="paragraph"><p>The <code><em>while</em></code> command evaluates <code><em>test</em></code> as an expression
@@ -6886,7 +6812,7 @@ termination of the <a href="#_while"><strong><code>while</code></strong></a> com
<div class="paragraph"><p>The following extensions may or may not be available depending upon
what options were selected when Jim Tcl was built.</p></div>
<div class="sect2">
-<h3 id="cmd_1">posix: os.fork, os.wait, os.gethostname, os.getids, os.uptime</h3>
+<h3 id="cmd_1">posix: os.fork, os.gethostname, os.getids, os.uptime</h3>
<div class="dlist"><dl>
<dt class="hdlist1">
<code><strong>os.fork</strong></code>
@@ -6897,35 +6823,6 @@ what options were selected when Jim Tcl was built.</p></div>
</p>
</dd>
<dt class="hdlist1">
-<code><strong>os.wait -nohang</strong> <em>pid</em></code>
-</dt>
-<dd>
-<p>
- Invokes waitpid(2), with WNOHANG if <code>-nohang</code> is specified.
- Returns a list of 3 elements.
-</p>
-<div class="literalblock">
-<div class="content">
-<pre><code>{0 none 0} if -nohang is specified, and the process is still alive.</code></pre>
-</div></div>
-<div class="literalblock">
-<div class="content">
-<pre><code>{-1 error &lt;error-description&gt;} if the process does not exist or has already been waited for.</code></pre>
-</div></div>
-<div class="literalblock">
-<div class="content">
-<pre><code>{&lt;pid&gt; exit &lt;exit-status&gt;} if the process exited normally.</code></pre>
-</div></div>
-<div class="literalblock">
-<div class="content">
-<pre><code>{&lt;pid&gt; signal &lt;signal-number&gt;} if the process terminated on a signal.</code></pre>
-</div></div>
-<div class="literalblock">
-<div class="content">
-<pre><code>{&lt;pid&gt; other 0} otherwise (core dump, stopped, continued, etc.)</code></pre>
-</div></div>
-</dd>
-<dt class="hdlist1">
<code><strong>os.gethostname</strong></code>
</dt>
<dd>
@@ -6940,12 +6837,14 @@ what options were selected when Jim Tcl was built.</p></div>
<p>
Returns the various user/group ids for the current process.
</p>
-<div class="literalblock">
+</dd>
+</dl></div>
+<div class="listingblock">
<div class="content">
-<pre><code>jim&gt; os.getids
-uid 1000 euid 1000 gid 100 egid 100</code></pre>
+<pre><code> . os.getids
+ uid 1000 euid 1000 gid 100 egid 100</code></pre>
</div></div>
-</dd>
+<div class="dlist"><dl>
<dt class="hdlist1">
<code><strong>os.uptime</strong></code>
</dt>
@@ -6973,7 +6872,8 @@ uid 1000 euid 1000 gid 100 egid 100</code></pre>
<p>
Server socket only: Accept a connection and return stream.
If <code><em>addrvar</em></code> is specified, the address of the connected client is stored
- in the named variable in the form <em>addr:port</em>. See <a href="#_socket"><strong><code>socket</code></strong></a> for details.
+ in the named variable in the form <em>addr:port</em> for IP sockets or <em>path</em> for Unix domain sockets.
+ See <a href="#_socket"><strong><code>socket</code></strong></a> for details.
</p>
</dd>
<dt class="hdlist1">
@@ -6985,12 +6885,14 @@ uid 1000 euid 1000 gid 100 egid 100</code></pre>
</p>
</dd>
<dt class="hdlist1">
-<code>$handle <strong>close</strong> ?r(ead)|w(rite)?</code>
+<code>$handle <strong>close ?r(ead)|w(rite)|-nodelete?</strong></code>
</dt>
<dd>
<p>
Closes the stream.
- The two-argument form is a "half-close" on a socket. See the <code>shutdown(2)</code> man page.
+ The <code><em>read</em></code> and <code><em>write</em></code> arguments perform a "half-close" on a socket. See the <em>shutdown(2)</em> man page.
+ The <code><em>-nodelete</em></code> option is applicable only for Unix domain sockets. It closes the socket
+ but does not delete the bound path (e.g. after <a href="#cmd_1"><strong><code>os.fork</code></strong></a>).
</p>
</dd>
<dt class="hdlist1">
@@ -7045,12 +6947,13 @@ uid 1000 euid 1000 gid 100 egid 100</code></pre>
</p>
</dd>
<dt class="hdlist1">
-<code>$handle <strong>lock</strong></code>
+<code>$handle <strong>lock ?-wait?</strong></code>
</dt>
<dd>
<p>
Apply a POSIX lock to the open file associated with the handle using
- fcntl(2).
+ <em>fcntl(F_SETLK)</em>, or <em>fcntl(F_SETLKW)</em> to wait for the lock to be available if <code><em>-wait</em></code>
+ is specified.
The handle must be open for write access.
Returns 1 if the lock was successfully obtained, 0 otherwise.
An error occurs if the handle is not suitable for locking (e.g.
@@ -7068,6 +6971,14 @@ uid 1000 euid 1000 gid 100 egid 100</code></pre>
</p>
</dd>
<dt class="hdlist1">
+<code>$handle <strong>peername</strong></code>
+</dt>
+<dd>
+<p>
+ Returns the remote address or path of the connected socket. See <em>getpeername(2)</em>.
+</p>
+</dd>
+<dt class="hdlist1">
<code>$handle <strong>puts ?-nonewline?</strong> <em>str</em></code>
</dt>
<dd>
@@ -7089,9 +7000,9 @@ uid 1000 euid 1000 gid 100 egid 100</code></pre>
<dd>
<p>
Receives a message from the handle via recvfrom(2) and returns it.
- At most <code><em>maxlen</em></code> bytes are read.
- If <code><em>addrvar</em></code> is specified, the sending address of the message is stored in
- the named variable in the form <em>addr:port</em>. See <a href="#_socket"><strong><code>socket</code></strong></a> for details.
+ At most <code><em>maxlen</em></code> bytes are read. If <code><em>addrvar</em></code> is specified, the sending address
+ of the message is stored in the named variable in the form <em>addr:port</em> for IP sockets
+ or <em>path</em> for Unix domain sockets. See <a href="#_socket"><strong><code>socket</code></strong></a> for details.
</p>
</dd>
<dt class="hdlist1">
@@ -7103,23 +7014,43 @@ uid 1000 euid 1000 gid 100 egid 100</code></pre>
</p>
</dd>
<dt class="hdlist1">
-<code>$handle <strong>sendto</strong> <em>str ?addr:?port</em></code>
+<code>$handle <strong>sendto</strong> <em>str ?address</em></code>
</dt>
<dd>
<p>
- Sends the string, <code><em>str</em></code>, to the given address via the socket using sendto(2).
+ Sends the string, <code><em>str</em></code>, to the given address (host:port or path) via the socket using <em>sendto(2)</em>.
This is intended for udp/dgram sockets and may give an error or behave in unintended
ways for other handle types.
Returns the number of bytes written.
</p>
</dd>
<dt class="hdlist1">
+<code>$handle <strong>sockname</strong></code>
+</dt>
+<dd>
+<p>
+ Returns the bound address or path of the socket. See <em>getsockname(2)</em>.
+</p>
+</dd>
+<dt class="hdlist1">
+<code>$handle <strong>sockopt</strong> <em>?name value?</em></code>
+</dt>
+<dd>
+<p>
+ With no arguments, returns a dictionary of socket options currently set for the handle
+ (will be empty for a non-socket). With <code><em>name</em></code> and <code><em>value</em></code>, sets the socket option
+ to the given value. Currently supports the following boolean socket options:
+ <code>broadcast, debug, keepalive, nosigpipe, oobinline, tcp_nodelay</code>, and the following
+ integer socket options: <code>sndbuf, rcvbuf</code>
+</p>
+</dd>
+<dt class="hdlist1">
<code>$handle <strong>sync</strong></code>
</dt>
<dd>
<p>
- Flush the stream, then fsync(2) to commit any changes to storage.
- Only available on platforms that support fsync(2).
+ Flush the stream, then <em>fsync(2)</em> to commit any changes to storage.
+ Only available on platforms that support <em>fsync(2)</em>.
</p>
</dd>
<dt class="hdlist1">
@@ -7131,11 +7062,107 @@ uid 1000 euid 1000 gid 100 egid 100</code></pre>
</p>
</dd>
<dt class="hdlist1">
-<code>$handle <strong>ssl</strong> <strong>?-server cert priv?</strong></code>
+<code>$handle <strong>tty</strong> ?settings?</code>
+</dt>
+<dd>
+<p>
+ If no arguments are given, returns a dictionary containing the tty settings for the stream.
+ If arguments are given, they must either be a dictionary, or <code>setting value ...</code>
+ Abbrevations are supported for both settings and values, so the following is acceptable:
+ <code>$f tty parity e input c out raw</code>.
+ Only available on platforms that support <em>termios(3)</em>. Supported settings are:
+</p>
+<div class="dlist"><dl>
+<dt class="hdlist1">
+<code><strong>baud</strong> <em>rate</em></code>
+</dt>
+<dd>
+<p>
+ Baud rate. e.g. 115200
+</p>
+</dd>
+<dt class="hdlist1">
+<code><strong>data 5|6|7|8</strong></code>
+</dt>
+<dd>
+<p>
+ Number of data bits
+</p>
+</dd>
+<dt class="hdlist1">
+<code><strong>stop 1|2</strong></code>
+</dt>
+<dd>
+<p>
+ Number of stop bits
+</p>
+</dd>
+<dt class="hdlist1">
+<code><strong>parity even|odd|none</strong></code>
+</dt>
+<dd>
+<p>
+ Parity setting
+</p>
+</dd>
+<dt class="hdlist1">
+<code><strong>handshake xonxoff|rtscts|none</strong></code>
+</dt>
+<dd>
+<p>
+ Handshaking type
+</p>
+</dd>
+<dt class="hdlist1">
+<code><strong>input raw|cooked</strong></code>
+</dt>
+<dd>
+<p>
+ Input character processing. In raw mode, the usual key sequences such as ^C do
+ not generate signals.
+</p>
+</dd>
+<dt class="hdlist1">
+<code><strong>output raw|cooked</strong></code>
+</dt>
+<dd>
+<p>
+ Output character processing. Typically CR &#8594; CRNL is disabled in raw mode.
+</p>
+</dd>
+<dt class="hdlist1">
+<code><strong>echo 0|1</strong></code>
+</dt>
+<dd>
+<p>
+ Disable or enable echo on input. Note that this is a set-only value.
+ Setting <code>input</code> to <code>raw</code> or <code>cooked</code> will overwrite this setting.
+</p>
+</dd>
+<dt class="hdlist1">
+<code><strong>vmin</strong> <em>numchars</em></code>
</dt>
<dd>
<p>
- Initiates a SSL/TLS session and returns a new stream
+ Minimum number of characters to read.
+</p>
+</dd>
+<dt class="hdlist1">
+<code><strong>vtime</strong> <em>time</em></code>
+</dt>
+<dd>
+<p>
+ Timeout for noncanonical read (units of 0.1 seconds)
+</p>
+</dd>
+</dl></div>
+</dd>
+<dt class="hdlist1">
+<code>$handle <strong>ssl</strong> ?<strong>-server</strong> <em>cert priv</em>?</code>
+</dt>
+<dd>
+<p>
+ Upgrades the stream to a SSL/TLS session and returns the handle.
</p>
</dd>
<dt class="hdlist1">
@@ -7334,7 +7361,7 @@ to prevent infinite errors. (A time event handler is always removed after execut
</dt>
<dd>
<p>
- A unix domain socket client.
+ A unix domain socket client connected to <em>path</em>
</p>
</dd>
<dt class="hdlist1">
@@ -7342,7 +7369,23 @@ to prevent infinite errors. (A time event handler is always removed after execut
</dt>
<dd>
<p>
- A unix domain socket server.
+ A unix domain socket server listening on <em>path</em>
+</p>
+</dd>
+<dt class="hdlist1">
+<code><strong>socket unix.dgram</strong> <em>?path?</em></code>
+</dt>
+<dd>
+<p>
+ A unix domain socket datagram client, optionally connected to <em>path</em>
+</p>
+</dd>
+<dt class="hdlist1">
+<code><strong>socket unix.dgram.server</strong> <em>path</em></code>
+</dt>
+<dd>
+<p>
+ A unix domain socket datagram server server listening on <em>path</em>
</p>
</dd>
<dt class="hdlist1">
@@ -7384,8 +7427,7 @@ to prevent infinite errors. (A time event handler is always removed after execut
</dt>
<dd>
<p>
- A pipe. Note that unlike all other socket types, this command returns
- a list of two channels: {read write}
+ A synonym for <a href="#_pipe"><strong><code>pipe</code></strong></a>
</p>
</dd>
<dt class="hdlist1">
@@ -7393,7 +7435,7 @@ to prevent infinite errors. (A time event handler is always removed after execut
</dt>
<dd>
<p>
- A socketpair (see socketpair(2)). Like <a href="#_socket"><strong><code>socket</code></strong></a> <code>pipe</code>, this command returns
+ A socketpair (see socketpair(2)). Like <a href="#_pipe"><strong><code>pipe</code></strong></a>, this command returns
a list of two channels: {s1 s2}. These channels are both readable and writable.
</p>
</dd>
@@ -7402,43 +7444,28 @@ to prevent infinite errors. (A time event handler is always removed after execut
address.</p></div>
<div class="paragraph"><p>The returned value is channel and may generally be used with the various file I/O
commands (gets, puts, read, etc.), either as object-based syntax or Tcl-compatible syntax.</p></div>
-<div class="olist arabic"><ol class="arabic">
-<li>
-<p>
-set f [socket stream www.google.com:80]
+<div class="listingblock">
+<div class="content">
+<pre><code> . set f [socket stream www.google.com:80]
aio.sockstream1
-</p>
-</li>
-<li>
-<p>
-$f puts -nonewline "GET / HTTP/1.0\r\n\r\n"
-</p>
-</li>
-<li>
-<p>
-$f gets
+ . $f puts -nonewline "GET / HTTP/1.0\r\n\r\n"
+ . $f gets
HTTP/1.0 302 Found
-</p>
-</li>
-<li>
-<p>
-$f close
-</p>
-</li>
-</ol></div>
+ . $f close</code></pre>
+</div></div>
<div class="paragraph"><p>Server sockets, however support only <em>accept</em>, which is most useful in conjunction with
the EVENTLOOP API.</p></div>
-<div class="literalblock">
-<div class="content">
-<pre><code>set f [socket stream.server 80]
-$f readable {
- set client [$f accept]
- $client gets $buf
- ...
- $client puts -nonewline "HTTP/1.1 404 Not found\r\n"
- $client close
-}
-vwait done</code></pre>
+<div class="listingblock">
+<div class="content">
+<pre><code> set f [socket stream.server 80]
+ $f readable {
+ set client [$f accept]
+ $client gets $buf
+ ...
+ $client puts -nonewline "HTTP/1.1 404 Not found\r\n"
+ $client close
+ }
+ vwait done</code></pre>
</div></div>
<div class="paragraph"><p>The address, <code><em>addr</em></code>, can be given in one of the following forms:</p></div>
<div class="olist arabic"><ol class="arabic">
@@ -7462,21 +7489,11 @@ A hostname
also accept requests via IPv4.</p></div>
<div class="paragraph"><p>Where a hostname is specified, the <code><em>first</em></code> returned address is used
which matches the socket type is used.</p></div>
-<div class="paragraph"><p>The special type <em>pipe</em> isn&#8217;t really a socket.</p></div>
-<div class="literalblock">
-<div class="content">
-<pre><code>lassign [socket pipe] r w</code></pre>
-</div></div>
-<div class="literalblock">
-<div class="content">
-<pre><code># Must close $w after exec
-exec ps &gt;@$w &amp;
-$w close</code></pre>
-</div></div>
-<div class="literalblock">
-<div class="content">
-<pre><code>$r readable ...</code></pre>
-</div></div>
+<div class="paragraph"><p>An unconnected dgram socket (either <em>dgram</em> or <em>unix.dgram</em>) must use
+<code>sendto</code> to specify the destination address.</p></div>
+<div class="paragraph"><p>The path for Unix domain sockets is automatically removed when the socket
+is closed. Use <a href="#_close"><strong><code>close</code></strong></a> <code>-nodelete</code> in the rare case where this behaviour
+should be avoided (e.g. after <a href="#cmd_1"><strong><code>os.fork</code></strong></a>).</p></div>
</div>
<div class="sect2">
<h3 id="_syslog">syslog</h3>
@@ -7618,7 +7635,7 @@ uucp, local0-local7</code></pre>
commands based on the low-level <a href="#cmd_3"><strong><code>pack</code></strong></a> and <a href="#cmd_3"><strong><code>unpack</code></strong></a> commands.</p></div>
<div class="paragraph"><p>See the Tcl documentation at: <a href="http://www.tcl.tk/man/tcl8.5/TclCmd/binary.htm">http://www.tcl.tk/man/tcl8.5/TclCmd/binary.htm</a></p></div>
<div class="paragraph"><p>Note that <em>binary format</em> with f/r/R specifiers (single-precision float) uses the value of Infinity
- in case of overflow.</p></div>
+in case of overflow.</p></div>
</div>
<div class="sect2">
<h3 id="cmd_4">oo: class, super</h3>
@@ -7787,7 +7804,7 @@ and zero or more child nodes (ordered), as well as zero or more attribute/value
</div>
<div class="sect2">
<h3 id="_tcl_prefix">tcl::prefix</h3>
-<div class="paragraph"><p>The optional tclprefix extension provides the Tcl8.6-compatible <em>tcl::prefix</em> command
+<div class="paragraph"><p>The optional tclprefix extension provides the Tcl8.6-compatible <a href="#_tcl_prefix"><strong><code>tcl::prefix</code></strong></a> command
(<a href="http://www.tcl.tk/man/tcl8.6/TclCmd/prefix.htm">http://www.tcl.tk/man/tcl8.6/TclCmd/prefix.htm</a>) for matching strings against a table
of possible values (typically commands or options).</p></div>
<div class="dlist"><dl>
@@ -7841,6 +7858,25 @@ of possible values (typically commands or options).</p></div>
</dl></div>
</div>
<div class="sect2">
+<h3 id="_tcl_autocomplete">tcl::autocomplete</h3>
+<div class="paragraph"><p>Scriptable command line completion is supported in the interactive shell, <em>jimsh</em>, through
+the <a href="#_tcl_autocomplete"><strong><code>tcl::autocomplete</code></strong></a> callback. A simple implementation is provided, however this may
+be replaced with a custom command instead if desired.</p></div>
+<div class="paragraph"><p>In the interactive shell, press &lt;TAB&gt; to activate command line completion.</p></div>
+<div class="dlist"><dl>
+<dt class="hdlist1">
+<code><strong>tcl::autocomplete</strong> <em>commandline</em></code>
+</dt>
+<dd>
+<p>
+ This command is called with the current command line when the user presses &lt;TAB&gt;.
+ The command should return a list of all possible command lines that match the current command line.
+ For example if <code><strong>pr</strong></code> is the current command line, the list <code><strong>{prefix proc}</strong></code> may be returned.
+</p>
+</dd>
+</dl></div>
+</div>
+<div class="sect2">
<h3 id="_history">history</h3>
<div class="paragraph"><p>The optional history extension provides script access to the command line editing
and history support available in <em>jimsh</em>. See <em>examples/jtclsh.tcl</em> for an example.
@@ -7867,6 +7903,15 @@ the remaining subcommands do nothing.</p></div>
</p>
</dd>
<dt class="hdlist1">
+<code><strong>history completion</strong> <em>command</em></code>
+</dt>
+<dd>
+<p>
+ Sets an autocompletion command (see <a href="#_tcl_autocomplete"><strong><code>tcl::autocomplete</code></strong></a>) that is active during <a href="#_history"><strong><code>history</code></strong></a> <code>getline</code>.
+ If the command is empty, autocompletion is disabled.
+</p>
+</dd>
+<dt class="hdlist1">
<code><strong>history add</strong> <em>line</em></code>
</dt>
<dd>
@@ -7992,9 +8037,9 @@ independently (but synchronously) of the main interpreter.</p></div>
<dd>
<p>
Creates and returns a new interpreter object (command).
- The created interpeter contains any built-in commands along with static extensions,
- but does not include any dynamically loaded commands (package require, load).
- These must be reloaded in the child interpreter if required.
+ The created interpeter contains any built-in commands along with static extensions,
+ but does not include any dynamically loaded commands (package require, load).
+ These must be reloaded in the child interpreter if required.
</p>
</dd>
<dt class="hdlist1">
@@ -8010,7 +8055,7 @@ independently (but synchronously) of the main interpreter.</p></div>
</dt>
<dd>
<p>
- Evaluates a script in the context for the child interpreter, in the same way as <em>eval</em>.
+ Evaluates a script in the context for the child interpreter, in the same way as <em>eval</em>.
</p>
</dd>
<dt class="hdlist1">
@@ -8018,12 +8063,155 @@ independently (but synchronously) of the main interpreter.</p></div>
</dt>
<dd>
<p>
- Similar to <em>alias</em>, but creates a command, <code><em>childcmd</em></code>, in the child interpreter that is an
- alias for <code><em>parentcmd</em></code> in the parent interpreter, with the given, fixed arguments.
- The alias may be deleted in the child with <em>rename</em>.
+ Similar to <em>alias</em>, but creates a command, <code><em>childcmd</em></code>, in the child interpreter that is an
+ alias for <code><em>parentcmd</em></code> in the parent interpreter, with the given, fixed arguments.
+ The alias may be deleted in the child with <em>rename</em>.
+</p>
+</dd>
+</dl></div>
+</div>
+<div class="sect2">
+<h3 id="_json_encode">json::encode</h3>
+<div class="paragraph"><p>The Tcl &#8594; JSON encoder is part of the optional <em>json</em> package.</p></div>
+<div class="dlist"><dl>
+<dt class="hdlist1">
+<code><strong>json::encode</strong> <em>value ?schema?</em></code>
+</dt>
+<dd>
+<p>
+Encode a Tcl value as JSON according to the schema (defaults to <code><em>str</em></code>). The following schema types are supported:
+</p>
+<div class="ulist"><ul>
+<li>
+<p>
+<em>str</em> - Tcl string &#8594; JSON string
+</p>
+</li>
+<li>
+<p>
+<em>num</em> - Tcl value &#8594; bare numeric value or null
+</p>
+</li>
+<li>
+<p>
+<em>bool</em> - Tcl boolean value &#8594; true, false
+</p>
+</li>
+<li>
+<p>
+<em>obj ?name subschema &#8230;?</em> - Tcl dict &#8594; JSON object. For each dict key matching <em>name</em>, the corresponding <em>subschema</em>
+is applied. The special name <code><em>*</em></code> matches any keys not otherwise matched, otherwise the default <code><em>str</em></code> is used.
+</p>
+</li>
+<li>
+<p>
+<em>list ?subschema?</em> - Tcl list &#8594; JSON array. The <em>subschema</em> (default <code><em>str</em></code>) is applied for each element of the list/array.
+</p>
+</li>
+<li>
+<p>
+<em>mixed ?subschema &#8230;?</em> = Tcl list &#8594; JSON array. Each <em>subschema</em> is applied for the corresponding element of the list/array.
+</p>
+</li>
+</ul></div>
+</dd>
+<dt class="hdlist1">
+
+</dt>
+<dd>
+<p>
+The following are examples:
</p>
</dd>
</dl></div>
+<div class="listingblock">
+<div class="content">
+<pre><code> . json::encode {1 2 true false null 5.0} list
+ [ "1", "2", "true", "false", "null", "5.0" ]
+ . json::encode {1 2 true false null 5.0} {list num}
+ [ 1, 2, true, false, null, 5.0 ]
+ . json::encode {0 1 2 true false 5.0 off} {list bool}
+ [ false, true, true, true, false, true, false ]
+ . json::encode {a 1 b hello c {3 4}} obj
+ { "a":"1", "b":"hello", "c":"3 4" }
+ . json::encode {a 1 b hello c {3 4}} {obj a num c {list num}}
+ { "a":1, "b":"hello", "c":[ 3, 4 ] }
+ . json::encode {true true {abc def}} {mixed str num obj}
+ [ "true", true, { "abc":"def" } ]
+ . json::encode {a 1 b 3.0 c hello d null} {obj c str * num}
+ { "a":1, "b":3.0, "c":"hello", "d":null }</code></pre>
+</div></div>
+</div>
+<div class="sect2">
+<h3 id="_json_decode">json::decode</h3>
+<div class="paragraph"><p>The JSON &#8594; Tcl decoder is part of the optional <em>json</em> package.</p></div>
+<div class="dlist"><dl>
+<dt class="hdlist1">
+<code><strong>json::decode</strong> ?<strong>-index</strong>? ?<strong>-null</strong> <em>string</em>? ?<strong>-schema</strong>? <em>json-string</em></code>
+</dt>
+<dd>
+<p>
+Decodes the given JSON string (must be array or object) into a Tcl data structure. If <em><code>-index</code></em> is specified,
+decodes JSON arrays as dictionaries with numeric keys. This makes it possible to retrieve data from nested
+arrays and dictionaries with just <em><code>dict get</code></em>. With the option <em><code>-schema</code></em> returns a list of <code><em>{data schema}</em></code>
+where the schema is compatible with <a href="#_json_encode"><strong><code>json::encode</code></strong></a>. Otherwise just returns the data.
+Decoding is as follows (with schema types listed in parentheses):
+</p>
+<div class="ulist"><ul>
+<li>
+<p>
+object &#8594; dict (<em>obj</em>)
+</p>
+</li>
+<li>
+<p>
+array &#8594; list (<em>mixed</em> or <em>list</em>)
+</p>
+</li>
+<li>
+<p>
+number &#8594; as-is (<em>num</em>)
+</p>
+</li>
+<li>
+<p>
+boolean &#8594; as-is (<em>bool</em>)
+</p>
+</li>
+<li>
+<p>
+string &#8594; string (<em>str</em>)
+</p>
+</li>
+<li>
+<p>
+null &#8594; supplied null string or the default <code><em>"null"</em></code> (<em>num</em>)
+</p>
+</li>
+</ul></div>
+</dd>
+<dt class="hdlist1">
+
+</dt>
+<dd>
+<p>
+ Note that an object decoded into a dict will return the keys in the same order as the original string.
+</p>
+</dd>
+</dl></div>
+<div class="listingblock">
+<div class="content">
+<pre><code> . json::decode {[1, 2]}
+ {1 2}
+ . json::decode -schema {[1, 2]}
+ {1 2} {list num}
+ . json::decode -schema {{"a":1, "b":2}}
+ {a 1 b 2} {obj a num b num}
+ . json::decode -schema {[1, 2, {a:"b", c:false}, "hello"]}
+ {1 2 {a b c false} hello} {mixed num num {obj a str c bool} str}
+ . json::decode -index {["foo", "bar"]}
+ {0 foo 1 bar}</code></pre>
+</div></div>
</div>
</div>
</div>
@@ -8108,18 +8296,20 @@ by the Tcl library.</p></div>
about the platform upon which Jim was built. The following is an
example of the contents of this array.
</p>
-<div class="literalblock">
+</dd>
+</dl></div>
+<div class="listingblock">
<div class="content">
-<pre><code>tcl_platform(byteOrder) = littleEndian
-tcl_platform(engine) = Jim
-tcl_platform(os) = Darwin
-tcl_platform(platform) = unix
-tcl_platform(pointerSize) = 8
-tcl_platform(threaded) = 0
-tcl_platform(wordSize) = 8
-tcl_platform(pathSeparator) = :</code></pre>
+<pre><code> tcl_platform(byteOrder) = littleEndian
+ tcl_platform(engine) = Jim
+ tcl_platform(os) = Darwin
+ tcl_platform(platform) = unix
+ tcl_platform(pointerSize) = 8
+ tcl_platform(threaded) = 0
+ tcl_platform(wordSize) = 8
+ tcl_platform(pathSeparator) = :</code></pre>
</div></div>
-</dd>
+<div class="dlist"><dl>
<dt class="hdlist1">
<code><strong>argv0</strong></code>
</dt>
@@ -8156,12 +8346,255 @@ tcl_platform(pathSeparator) = :</code></pre>
</p>
</dd>
</dl></div>
+<div class="paragraph"><p>The following variables have special meaning to Jim Tcl:</p></div>
+<div class="dlist"><dl>
+<dt class="hdlist1">
+<code><strong>jim::defer</strong></code>
+</dt>
+<dd>
+<p>
+ If this variable is set, it is considered to be a list of scripts to evaluate
+ when the current proc exits (local variables), or the interpreter exits (global variable).
+ See <a href="#_defer"><strong><code>defer</code></strong></a>.
+</p>
+</dd>
+<dt class="hdlist1">
+<code><strong>history::multiline</strong></code>
+</dt>
+<dd>
+<p>
+ If this variable is set to "1", interactive line editing operates in multiline mode.
+ That is, long lines will wrap across multiple lines rather than scrolling within a
+ single line.
+</p>
+</dd>
+</dl></div>
</div>
</div>
<div class="sect1">
<h2 id="_changes_in_previous_releases">CHANGES IN PREVIOUS RELEASES</h2>
<div class="sectionbody">
<div class="sect2">
+<h3 id="_in_v0_74">In v0.74</h3>
+<div class="olist arabic"><ol class="arabic">
+<li>
+<p>
+Numbers with leading zeros are treated as decimal, not octal
+</p>
+</li>
+<li>
+<p>
+Add <a href="#_aio"><strong><code>aio</code></strong></a> <code>isatty</code>
+</p>
+</li>
+<li>
+<p>
+Add LFS (64 bit) support for <a href="#_aio"><strong><code>aio</code></strong></a> <code>seek</code>, <a href="#_aio"><strong><code>aio</code></strong></a> <code>tell</code>, <a href="#_aio"><strong><code>aio</code></strong></a> <code>copyto</code>, <a href="#_file"><strong><code>file</code></strong></a> <code>copy</code>
+</p>
+</li>
+<li>
+<p>
+<a href="#_string"><strong><code>string</code></strong></a> <code>compare</code> and <a href="#_string"><strong><code>string</code></strong></a> <code>equal</code> now support <em>-length</em>
+</p>
+</li>
+<li>
+<p>
+<a href="#_glob"><strong><code>glob</code></strong></a> now supports <em>-directory</em>
+</p>
+</li>
+</ol></div>
+</div>
+<div class="sect2">
+<h3 id="_in_v0_73">In v0.73</h3>
+<div class="olist arabic"><ol class="arabic">
+<li>
+<p>
+Built-in regexp now support non-capturing parentheses: (?:&#8230;)
+</p>
+</li>
+<li>
+<p>
+Add <a href="#_string"><strong><code>string</code></strong></a> <code>replace</code>
+</p>
+</li>
+<li>
+<p>
+Add <a href="#_string"><strong><code>string</code></strong></a> <code>totitle</code>
+</p>
+</li>
+<li>
+<p>
+Add <a href="#_info"><strong><code>info</code></strong></a> <code>statics</code>
+</p>
+</li>
+<li>
+<p>
+Add <code>build-jim-ext</code> for easy separate building of loadable modules (extensions)
+</p>
+</li>
+<li>
+<p>
+<a href="#_local"><strong><code>local</code></strong></a> now works with any command, not just procs
+</p>
+</li>
+<li>
+<p>
+Add <a href="#_info"><strong><code>info</code></strong></a> <code>alias</code> to access the target of an alias
+</p>
+</li>
+<li>
+<p>
+UTF-8 encoding past the basic multilingual plane (BMP) is supported
+</p>
+</li>
+<li>
+<p>
+Add <a href="#_tcl_prefix"><strong><code>tcl::prefix</code></strong></a>
+</p>
+</li>
+<li>
+<p>
+Add <a href="#_history"><strong><code>history</code></strong></a>
+</p>
+</li>
+<li>
+<p>
+Most extensions are now enabled by default
+</p>
+</li>
+<li>
+<p>
+Add support for namespaces and the <a href="#_namespace"><strong><code>namespace</code></strong></a> command
+</p>
+</li>
+<li>
+<p>
+Add <a href="#_apply"><strong><code>apply</code></strong></a>
+</p>
+</li>
+</ol></div>
+</div>
+<div class="sect2">
+<h3 id="_in_v0_72">In v0.72</h3>
+<div class="olist arabic"><ol class="arabic">
+<li>
+<p>
+procs now allow <em>args</em> and optional parameters in any position
+</p>
+</li>
+<li>
+<p>
+Add Tcl-compatible expr functions, <code>rand()</code>, <code>srand()</code> and <code>pow()</code>
+</p>
+</li>
+<li>
+<p>
+Add support for the <em>-force</em> option to <a href="#_file"><strong><code>file</code></strong></a> <code>delete</code>
+</p>
+</li>
+<li>
+<p>
+Better diagnostics when <a href="#_source"><strong><code>source</code></strong></a> fails to load a script with a missing quote or bracket
+</p>
+</li>
+<li>
+<p>
+New <code>tcl_platform(pathSeparator)</code>
+</p>
+</li>
+<li>
+<p>
+Add support settings the modification time with <a href="#_file"><strong><code>file</code></strong></a> <code>mtime</code>
+</p>
+</li>
+<li>
+<p>
+<a href="#_exec"><strong><code>exec</code></strong></a> is now fully supported on win32 (mingw32)
+</p>
+</li>
+<li>
+<p>
+<a href="#_file"><strong><code>file</code></strong></a> <code>join</code>, <a href="#_pwd"><strong><code>pwd</code></strong></a>, <a href="#_glob"><strong><code>glob</code></strong></a> etc. now work for mingw32
+</p>
+</li>
+<li>
+<p>
+Line editing is now supported for the win32 console (mingw32)
+</p>
+</li>
+<li>
+<p>
+Add <a href="#_aio"><strong><code>aio</code></strong></a> <code>listen</code> command
+</p>
+</li>
+</ol></div>
+</div>
+<div class="sect2">
+<h3 id="_in_v0_71">In v0.71</h3>
+<div class="olist arabic"><ol class="arabic">
+<li>
+<p>
+Allow <em>args</em> to be renamed in procs
+</p>
+</li>
+<li>
+<p>
+Add <code>$(&#8230;)</code> shorthand syntax for expressions
+</p>
+</li>
+<li>
+<p>
+Add automatic reference variables in procs with <code>&amp;var</code> syntax
+</p>
+</li>
+<li>
+<p>
+Support <code>jimsh --version</code>
+</p>
+</li>
+<li>
+<p>
+Additional variables in <code>tcl_platform()</code>
+</p>
+</li>
+<li>
+<p>
+<a href="#_local"><strong><code>local</code></strong></a> procs now push existing commands and <a href="#_upcall"><strong><code>upcall</code></strong></a> can call them
+</p>
+</li>
+<li>
+<p>
+Add <a href="#_loop"><strong><code>loop</code></strong></a> command (TclX compatible)
+</p>
+</li>
+<li>
+<p>
+Add <a href="#_aio"><strong><code>aio</code></strong></a> <code>buffering</code> command
+</p>
+</li>
+<li>
+<p>
+<a href="#_info"><strong><code>info</code></strong></a> <code>complete</code> can now return the missing character
+</p>
+</li>
+<li>
+<p>
+<a href="#_binary"><strong><code>binary</code></strong></a> <code>format</code> and <a href="#_binary"><strong><code>binary</code></strong></a> <code>scan</code> are now (optionally) supported
+</p>
+</li>
+<li>
+<p>
+Add <a href="#_string"><strong><code>string</code></strong></a> <code>byterange</code>
+</p>
+</li>
+<li>
+<p>
+Built-in regexp now support non-greedy repetition (*?, +?, ??)
+</p>
+</li>
+</ol></div>
+</div>
+<div class="sect2">
<h3 id="_in_v0_70">In v0.70</h3>
<div class="olist arabic"><ol class="arabic">
<li>
@@ -8490,9 +8923,6 @@ official policies, either expressed or implied, of the Jim Tcl Project.</code></
</div>
<div id="footnotes"><hr /></div>
<div id="footer">
-<div id="footer-text">
-Last updated 2016-08-29 16:18:20 AEST
-</div>
</div>
</body>
</html>
diff --git a/UnicodeData.txt b/UnicodeData.txt
index 6b01d90..d89c64f 100644
--- a/UnicodeData.txt
+++ b/UnicodeData.txt
@@ -165,10 +165,10 @@
00A4;CURRENCY SIGN;Sc;0;ET;;;;;N;;;;;
00A5;YEN SIGN;Sc;0;ET;;;;;N;;;;;
00A6;BROKEN BAR;So;0;ON;;;;;N;BROKEN VERTICAL BAR;;;;
-00A7;SECTION SIGN;So;0;ON;;;;;N;;;;;
+00A7;SECTION SIGN;Po;0;ON;;;;;N;;;;;
00A8;DIAERESIS;Sk;0;ON;<compat> 0020 0308;;;;N;SPACING DIAERESIS;;;;
00A9;COPYRIGHT SIGN;So;0;ON;;;;;N;;;;;
-00AA;FEMININE ORDINAL INDICATOR;Ll;0;L;<super> 0061;;;;N;;;;;
+00AA;FEMININE ORDINAL INDICATOR;Lo;0;L;<super> 0061;;;;N;;;;;
00AB;LEFT-POINTING DOUBLE ANGLE QUOTATION MARK;Pi;0;ON;;;;;Y;LEFT POINTING GUILLEMET;;;;
00AC;NOT SIGN;Sm;0;ON;;;;;N;;;;;
00AD;SOFT HYPHEN;Cf;0;BN;;;;;N;;;;;
@@ -180,11 +180,11 @@
00B3;SUPERSCRIPT THREE;No;0;EN;<super> 0033;;3;3;N;SUPERSCRIPT DIGIT THREE;;;;
00B4;ACUTE ACCENT;Sk;0;ON;<compat> 0020 0301;;;;N;SPACING ACUTE;;;;
00B5;MICRO SIGN;Ll;0;L;<compat> 03BC;;;;N;;;039C;;039C
-00B6;PILCROW SIGN;So;0;ON;;;;;N;PARAGRAPH SIGN;;;;
+00B6;PILCROW SIGN;Po;0;ON;;;;;N;PARAGRAPH SIGN;;;;
00B7;MIDDLE DOT;Po;0;ON;;;;;N;;;;;
00B8;CEDILLA;Sk;0;ON;<compat> 0020 0327;;;;N;SPACING CEDILLA;;;;
00B9;SUPERSCRIPT ONE;No;0;EN;<super> 0031;;1;1;N;SUPERSCRIPT DIGIT ONE;;;;
-00BA;MASCULINE ORDINAL INDICATOR;Ll;0;L;<super> 006F;;;;N;;;;;
+00BA;MASCULINE ORDINAL INDICATOR;Lo;0;L;<super> 006F;;;;N;;;;;
00BB;RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK;Pf;0;ON;;;;;Y;RIGHT POINTING GUILLEMET;;;;
00BC;VULGAR FRACTION ONE QUARTER;No;0;ON;<fraction> 0031 2044 0034;;;1/4;N;FRACTION ONE QUARTER;;;;
00BD;VULGAR FRACTION ONE HALF;No;0;ON;<fraction> 0031 2044 0032;;;1/2;N;FRACTION ONE HALF;;;;
@@ -602,23 +602,23 @@
0259;LATIN SMALL LETTER SCHWA;Ll;0;L;;;;;N;;;018F;;018F
025A;LATIN SMALL LETTER SCHWA WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER SCHWA HOOK;;;;
025B;LATIN SMALL LETTER OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER EPSILON;;0190;;0190
-025C;LATIN SMALL LETTER REVERSED OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED EPSILON;;;;
+025C;LATIN SMALL LETTER REVERSED OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED EPSILON;;A7AB;;A7AB
025D;LATIN SMALL LETTER REVERSED OPEN E WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED EPSILON HOOK;;;;
025E;LATIN SMALL LETTER CLOSED REVERSED OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER CLOSED REVERSED EPSILON;;;;
025F;LATIN SMALL LETTER DOTLESS J WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER DOTLESS J BAR;;;;
0260;LATIN SMALL LETTER G WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER G HOOK;;0193;;0193
-0261;LATIN SMALL LETTER SCRIPT G;Ll;0;L;;;;;N;;;;;
+0261;LATIN SMALL LETTER SCRIPT G;Ll;0;L;;;;;N;;;A7AC;;A7AC
0262;LATIN LETTER SMALL CAPITAL G;Ll;0;L;;;;;N;;;;;
0263;LATIN SMALL LETTER GAMMA;Ll;0;L;;;;;N;;;0194;;0194
0264;LATIN SMALL LETTER RAMS HORN;Ll;0;L;;;;;N;LATIN SMALL LETTER BABY GAMMA;;;;
-0265;LATIN SMALL LETTER TURNED H;Ll;0;L;;;;;N;;;;;
-0266;LATIN SMALL LETTER H WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER H HOOK;;;;
+0265;LATIN SMALL LETTER TURNED H;Ll;0;L;;;;;N;;;A78D;;A78D
+0266;LATIN SMALL LETTER H WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER H HOOK;;A7AA;;A7AA
0267;LATIN SMALL LETTER HENG WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER HENG HOOK;;;;
0268;LATIN SMALL LETTER I WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER BARRED I;;0197;;0197
0269;LATIN SMALL LETTER IOTA;Ll;0;L;;;;;N;;;0196;;0196
-026A;LATIN LETTER SMALL CAPITAL I;Ll;0;L;;;;;N;;;;;
+026A;LATIN LETTER SMALL CAPITAL I;Ll;0;L;;;;;N;;;A7AE;;A7AE
026B;LATIN SMALL LETTER L WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;2C62;;2C62
-026C;LATIN SMALL LETTER L WITH BELT;Ll;0;L;;;;;N;LATIN SMALL LETTER L BELT;;;;
+026C;LATIN SMALL LETTER L WITH BELT;Ll;0;L;;;;;N;LATIN SMALL LETTER L BELT;;A7AD;;A7AD
026D;LATIN SMALL LETTER L WITH RETROFLEX HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER L RETROFLEX HOOK;;;;
026E;LATIN SMALL LETTER LEZH;Ll;0;L;;;;;N;LATIN SMALL LETTER L YOGH;;;;
026F;LATIN SMALL LETTER TURNED M;Ll;0;L;;;;;N;;;019C;;019C
@@ -645,7 +645,7 @@
0284;LATIN SMALL LETTER DOTLESS J WITH STROKE AND HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER DOTLESS J BAR HOOK;;;;
0285;LATIN SMALL LETTER SQUAT REVERSED ESH;Ll;0;L;;;;;N;;;;;
0286;LATIN SMALL LETTER ESH WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER ESH CURL;;;;
-0287;LATIN SMALL LETTER TURNED T;Ll;0;L;;;;;N;;;;;
+0287;LATIN SMALL LETTER TURNED T;Ll;0;L;;;;;N;;;A7B1;;A7B1
0288;LATIN SMALL LETTER T WITH RETROFLEX HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER T RETROFLEX HOOK;;01AE;;01AE
0289;LATIN SMALL LETTER U BAR;Ll;0;L;;;;;N;;;0244;;0244
028A;LATIN SMALL LETTER UPSILON;Ll;0;L;;;;;N;;;01B1;;01B1
@@ -667,8 +667,8 @@
029A;LATIN SMALL LETTER CLOSED OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER CLOSED EPSILON;;;;
029B;LATIN LETTER SMALL CAPITAL G WITH HOOK;Ll;0;L;;;;;N;LATIN LETTER SMALL CAPITAL G HOOK;;;;
029C;LATIN LETTER SMALL CAPITAL H;Ll;0;L;;;;;N;;;;;
-029D;LATIN SMALL LETTER J WITH CROSSED-TAIL;Ll;0;L;;;;;N;LATIN SMALL LETTER CROSSED-TAIL J;;;;
-029E;LATIN SMALL LETTER TURNED K;Ll;0;L;;;;;N;;;;;
+029D;LATIN SMALL LETTER J WITH CROSSED-TAIL;Ll;0;L;;;;;N;LATIN SMALL LETTER CROSSED-TAIL J;;A7B2;;A7B2
+029E;LATIN SMALL LETTER TURNED K;Ll;0;L;;;;;N;;;A7B0;;A7B0
029F;LATIN LETTER SMALL CAPITAL L;Ll;0;L;;;;;N;;;;;
02A0;LATIN SMALL LETTER Q WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER Q HOOK;;;;
02A1;LATIN LETTER GLOTTAL STOP WITH STROKE;Ll;0;L;;;;;N;LATIN LETTER GLOTTAL STOP BAR;;;;
@@ -891,6 +891,7 @@
037C;GREEK SMALL DOTTED LUNATE SIGMA SYMBOL;Ll;0;L;;;;;N;;;03FE;;03FE
037D;GREEK SMALL REVERSED DOTTED LUNATE SIGMA SYMBOL;Ll;0;L;;;;;N;;;03FF;;03FF
037E;GREEK QUESTION MARK;Po;0;ON;003B;;;;N;;;;;
+037F;GREEK CAPITAL LETTER YOT;Lu;0;L;;;;;N;;;;03F3;
0384;GREEK TONOS;Sk;0;ON;<compat> 0020 0301;;;;N;GREEK SPACING TONOS;;;;
0385;GREEK DIALYTIKA TONOS;Sk;0;ON;00A8 0301;;;;N;GREEK SPACING DIAERESIS TONOS;;;;
0386;GREEK CAPITAL LETTER ALPHA WITH TONOS;Lu;0;L;0391 0301;;;;N;GREEK CAPITAL LETTER ALPHA TONOS;;;03AC;
@@ -999,7 +1000,7 @@
03F0;GREEK KAPPA SYMBOL;Ll;0;L;<compat> 03BA;;;;N;GREEK SMALL LETTER SCRIPT KAPPA;;039A;;039A
03F1;GREEK RHO SYMBOL;Ll;0;L;<compat> 03C1;;;;N;GREEK SMALL LETTER TAILED RHO;;03A1;;03A1
03F2;GREEK LUNATE SIGMA SYMBOL;Ll;0;L;<compat> 03C2;;;;N;GREEK SMALL LETTER LUNATE SIGMA;;03F9;;03F9
-03F3;GREEK LETTER YOT;Ll;0;L;;;;;N;;;;;
+03F3;GREEK LETTER YOT;Ll;0;L;;;;;N;;;037F;;037F
03F4;GREEK CAPITAL THETA SYMBOL;Lu;0;L;<compat> 0398;;;;N;;;;03B8;
03F5;GREEK LUNATE EPSILON SYMBOL;Ll;0;L;<compat> 03B5;;;;N;;;0395;;0395
03F6;GREEK REVERSED LUNATE EPSILON SYMBOL;Sm;0;ON;;;;;N;;;;;
@@ -1306,6 +1307,16 @@
0523;CYRILLIC SMALL LETTER EN WITH MIDDLE HOOK;Ll;0;L;;;;;N;;;0522;;0522
0524;CYRILLIC CAPITAL LETTER PE WITH DESCENDER;Lu;0;L;;;;;N;;;;0525;
0525;CYRILLIC SMALL LETTER PE WITH DESCENDER;Ll;0;L;;;;;N;;;0524;;0524
+0526;CYRILLIC CAPITAL LETTER SHHA WITH DESCENDER;Lu;0;L;;;;;N;;;;0527;
+0527;CYRILLIC SMALL LETTER SHHA WITH DESCENDER;Ll;0;L;;;;;N;;;0526;;0526
+0528;CYRILLIC CAPITAL LETTER EN WITH LEFT HOOK;Lu;0;L;;;;;N;;;;0529;
+0529;CYRILLIC SMALL LETTER EN WITH LEFT HOOK;Ll;0;L;;;;;N;;;0528;;0528
+052A;CYRILLIC CAPITAL LETTER DZZHE;Lu;0;L;;;;;N;;;;052B;
+052B;CYRILLIC SMALL LETTER DZZHE;Ll;0;L;;;;;N;;;052A;;052A
+052C;CYRILLIC CAPITAL LETTER DCHE;Lu;0;L;;;;;N;;;;052D;
+052D;CYRILLIC SMALL LETTER DCHE;Ll;0;L;;;;;N;;;052C;;052C
+052E;CYRILLIC CAPITAL LETTER EL WITH DESCENDER;Lu;0;L;;;;;N;;;;052F;
+052F;CYRILLIC SMALL LETTER EL WITH DESCENDER;Ll;0;L;;;;;N;;;052E;;052E
0531;ARMENIAN CAPITAL LETTER AYB;Lu;0;L;;;;;N;;;;0561;
0532;ARMENIAN CAPITAL LETTER BEN;Lu;0;L;;;;;N;;;;0562;
0533;ARMENIAN CAPITAL LETTER GIM;Lu;0;L;;;;;N;;;;0563;
@@ -1392,6 +1403,9 @@
0587;ARMENIAN SMALL LIGATURE ECH YIWN;Ll;0;L;<compat> 0565 0582;;;;N;;;;;
0589;ARMENIAN FULL STOP;Po;0;L;;;;;N;ARMENIAN PERIOD;;;;
058A;ARMENIAN HYPHEN;Pd;0;ON;;;;;N;;;;;
+058D;RIGHT-FACING ARMENIAN ETERNITY SIGN;So;0;ON;;;;;N;;;;;
+058E;LEFT-FACING ARMENIAN ETERNITY SIGN;So;0;ON;;;;;N;;;;;
+058F;ARMENIAN DRAM SIGN;Sc;0;ET;;;;;N;;;;;
0591;HEBREW ACCENT ETNAHTA;Mn;220;NSM;;;;;N;;;;;
0592;HEBREW ACCENT SEGOL;Mn;230;NSM;;;;;N;;;;;
0593;HEBREW ACCENT SHALSHELET;Mn;230;NSM;;;;;N;;;;;
@@ -1483,6 +1497,8 @@
0601;ARABIC SIGN SANAH;Cf;0;AN;;;;;N;;;;;
0602;ARABIC FOOTNOTE MARKER;Cf;0;AN;;;;;N;;;;;
0603;ARABIC SIGN SAFHA;Cf;0;AN;;;;;N;;;;;
+0604;ARABIC SIGN SAMVAT;Cf;0;AN;;;;;N;;;;;
+0605;ARABIC NUMBER MARK ABOVE;Cf;0;AN;;;;;N;;;;;
0606;ARABIC-INDIC CUBE ROOT;Sm;0;ON;;;;;N;;;;;
0607;ARABIC-INDIC FOURTH ROOT;Sm;0;ON;;;;;N;;;;;
0608;ARABIC RAY;Sm;0;AL;;;;;N;;;;;
@@ -1505,8 +1521,10 @@
0619;ARABIC SMALL DAMMA;Mn;31;NSM;;;;;N;;;;;
061A;ARABIC SMALL KASRA;Mn;32;NSM;;;;;N;;;;;
061B;ARABIC SEMICOLON;Po;0;AL;;;;;N;;;;;
+061C;ARABIC LETTER MARK;Cf;0;AL;;;;;N;;;;;
061E;ARABIC TRIPLE DOT PUNCTUATION MARK;Po;0;AL;;;;;N;;;;;
061F;ARABIC QUESTION MARK;Po;0;AL;;;;;N;;;;;
+0620;ARABIC LETTER KASHMIRI YEH;Lo;0;AL;;;;;N;;;;;
0621;ARABIC LETTER HAMZA;Lo;0;AL;;;;;N;ARABIC LETTER HAMZAH;;;;
0622;ARABIC LETTER ALEF WITH MADDA ABOVE;Lo;0;AL;0627 0653;;;;N;ARABIC LETTER MADDAH ON ALEF;;;;
0623;ARABIC LETTER ALEF WITH HAMZA ABOVE;Lo;0;AL;0627 0654;;;;N;ARABIC LETTER HAMZAH ON ALEF;;;;
@@ -1569,6 +1587,7 @@
065C;ARABIC VOWEL SIGN DOT BELOW;Mn;220;NSM;;;;;N;;;;;
065D;ARABIC REVERSED DAMMA;Mn;230;NSM;;;;;N;;;;;
065E;ARABIC FATHA WITH TWO DOTS;Mn;230;NSM;;;;;N;;;;;
+065F;ARABIC WAVY HAMZA BELOW;Mn;220;NSM;;;;;N;;;;;
0660;ARABIC-INDIC DIGIT ZERO;Nd;0;AN;;0;0;0;N;;;;;
0661;ARABIC-INDIC DIGIT ONE;Nd;0;AN;;1;1;1;N;;;;;
0662;ARABIC-INDIC DIGIT TWO;Nd;0;AN;;2;2;2;N;;;;;
@@ -1695,7 +1714,7 @@
06DB;ARABIC SMALL HIGH THREE DOTS;Mn;230;NSM;;;;;N;;;;;
06DC;ARABIC SMALL HIGH SEEN;Mn;230;NSM;;;;;N;;;;;
06DD;ARABIC END OF AYAH;Cf;0;AN;;;;;N;;;;;
-06DE;ARABIC START OF RUB EL HIZB;Me;0;NSM;;;;;N;;;;;
+06DE;ARABIC START OF RUB EL HIZB;So;0;ON;;;;;N;;;;;
06DF;ARABIC SMALL HIGH ROUNDED ZERO;Mn;230;NSM;;;;;N;;;;;
06E0;ARABIC SMALL HIGH UPRIGHT RECTANGULAR ZERO;Mn;230;NSM;;;;;N;;;;;
06E1;ARABIC SMALL HIGH DOTLESS HEAD OF KHAH;Mn;230;NSM;;;;;N;;;;;
@@ -1743,7 +1762,7 @@
070B;SYRIAC HARKLEAN OBELUS;Po;0;AL;;;;;N;;;;;
070C;SYRIAC HARKLEAN METOBELUS;Po;0;AL;;;;;N;;;;;
070D;SYRIAC HARKLEAN ASTERISCUS;Po;0;AL;;;;;N;;;;;
-070F;SYRIAC ABBREVIATION MARK;Cf;0;BN;;;;;N;;;;;
+070F;SYRIAC ABBREVIATION MARK;Cf;0;AL;;;;;N;;;;;
0710;SYRIAC LETTER ALAPH;Lo;0;AL;;;;;N;;;;;
0711;SYRIAC LETTER SUPERSCRIPT ALAPH;Mn;36;NSM;;;;;N;;;;;
0712;SYRIAC LETTER BETH;Lo;0;AL;;;;;N;;;;;
@@ -2024,6 +2043,119 @@
083C;SAMARITAN PUNCTUATION ARKAANU;Po;0;R;;;;;N;;;;;
083D;SAMARITAN PUNCTUATION SOF MASHFAAT;Po;0;R;;;;;N;;;;;
083E;SAMARITAN PUNCTUATION ANNAAU;Po;0;R;;;;;N;;;;;
+0840;MANDAIC LETTER HALQA;Lo;0;R;;;;;N;;;;;
+0841;MANDAIC LETTER AB;Lo;0;R;;;;;N;;;;;
+0842;MANDAIC LETTER AG;Lo;0;R;;;;;N;;;;;
+0843;MANDAIC LETTER AD;Lo;0;R;;;;;N;;;;;
+0844;MANDAIC LETTER AH;Lo;0;R;;;;;N;;;;;
+0845;MANDAIC LETTER USHENNA;Lo;0;R;;;;;N;;;;;
+0846;MANDAIC LETTER AZ;Lo;0;R;;;;;N;;;;;
+0847;MANDAIC LETTER IT;Lo;0;R;;;;;N;;;;;
+0848;MANDAIC LETTER ATT;Lo;0;R;;;;;N;;;;;
+0849;MANDAIC LETTER AKSA;Lo;0;R;;;;;N;;;;;
+084A;MANDAIC LETTER AK;Lo;0;R;;;;;N;;;;;
+084B;MANDAIC LETTER AL;Lo;0;R;;;;;N;;;;;
+084C;MANDAIC LETTER AM;Lo;0;R;;;;;N;;;;;
+084D;MANDAIC LETTER AN;Lo;0;R;;;;;N;;;;;
+084E;MANDAIC LETTER AS;Lo;0;R;;;;;N;;;;;
+084F;MANDAIC LETTER IN;Lo;0;R;;;;;N;;;;;
+0850;MANDAIC LETTER AP;Lo;0;R;;;;;N;;;;;
+0851;MANDAIC LETTER ASZ;Lo;0;R;;;;;N;;;;;
+0852;MANDAIC LETTER AQ;Lo;0;R;;;;;N;;;;;
+0853;MANDAIC LETTER AR;Lo;0;R;;;;;N;;;;;
+0854;MANDAIC LETTER ASH;Lo;0;R;;;;;N;;;;;
+0855;MANDAIC LETTER AT;Lo;0;R;;;;;N;;;;;
+0856;MANDAIC LETTER DUSHENNA;Lo;0;R;;;;;N;;;;;
+0857;MANDAIC LETTER KAD;Lo;0;R;;;;;N;;;;;
+0858;MANDAIC LETTER AIN;Lo;0;R;;;;;N;;;;;
+0859;MANDAIC AFFRICATION MARK;Mn;220;NSM;;;;;N;;;;;
+085A;MANDAIC VOCALIZATION MARK;Mn;220;NSM;;;;;N;;;;;
+085B;MANDAIC GEMINATION MARK;Mn;220;NSM;;;;;N;;;;;
+085E;MANDAIC PUNCTUATION;Po;0;R;;;;;N;;;;;
+0860;SYRIAC LETTER MALAYALAM NGA;Lo;0;AL;;;;;N;;;;;
+0861;SYRIAC LETTER MALAYALAM JA;Lo;0;AL;;;;;N;;;;;
+0862;SYRIAC LETTER MALAYALAM NYA;Lo;0;AL;;;;;N;;;;;
+0863;SYRIAC LETTER MALAYALAM TTA;Lo;0;AL;;;;;N;;;;;
+0864;SYRIAC LETTER MALAYALAM NNA;Lo;0;AL;;;;;N;;;;;
+0865;SYRIAC LETTER MALAYALAM NNNA;Lo;0;AL;;;;;N;;;;;
+0866;SYRIAC LETTER MALAYALAM BHA;Lo;0;AL;;;;;N;;;;;
+0867;SYRIAC LETTER MALAYALAM RA;Lo;0;AL;;;;;N;;;;;
+0868;SYRIAC LETTER MALAYALAM LLA;Lo;0;AL;;;;;N;;;;;
+0869;SYRIAC LETTER MALAYALAM LLLA;Lo;0;AL;;;;;N;;;;;
+086A;SYRIAC LETTER MALAYALAM SSA;Lo;0;AL;;;;;N;;;;;
+08A0;ARABIC LETTER BEH WITH SMALL V BELOW;Lo;0;AL;;;;;N;;;;;
+08A1;ARABIC LETTER BEH WITH HAMZA ABOVE;Lo;0;AL;;;;;N;;;;;
+08A2;ARABIC LETTER JEEM WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+08A3;ARABIC LETTER TAH WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+08A4;ARABIC LETTER FEH WITH DOT BELOW AND THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+08A5;ARABIC LETTER QAF WITH DOT BELOW;Lo;0;AL;;;;;N;;;;;
+08A6;ARABIC LETTER LAM WITH DOUBLE BAR;Lo;0;AL;;;;;N;;;;;
+08A7;ARABIC LETTER MEEM WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+08A8;ARABIC LETTER YEH WITH TWO DOTS BELOW AND HAMZA ABOVE;Lo;0;AL;;;;;N;;;;;
+08A9;ARABIC LETTER YEH WITH TWO DOTS BELOW AND DOT ABOVE;Lo;0;AL;;;;;N;;;;;
+08AA;ARABIC LETTER REH WITH LOOP;Lo;0;AL;;;;;N;;;;;
+08AB;ARABIC LETTER WAW WITH DOT WITHIN;Lo;0;AL;;;;;N;;;;;
+08AC;ARABIC LETTER ROHINGYA YEH;Lo;0;AL;;;;;N;;;;;
+08AD;ARABIC LETTER LOW ALEF;Lo;0;AL;;;;;N;;;;;
+08AE;ARABIC LETTER DAL WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;;
+08AF;ARABIC LETTER SAD WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;;
+08B0;ARABIC LETTER GAF WITH INVERTED STROKE;Lo;0;AL;;;;;N;;;;;
+08B1;ARABIC LETTER STRAIGHT WAW;Lo;0;AL;;;;;N;;;;;
+08B2;ARABIC LETTER ZAIN WITH INVERTED V ABOVE;Lo;0;AL;;;;;N;;;;;
+08B3;ARABIC LETTER AIN WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;;
+08B4;ARABIC LETTER KAF WITH DOT BELOW;Lo;0;AL;;;;;N;;;;;
+08B6;ARABIC LETTER BEH WITH SMALL MEEM ABOVE;Lo;0;AL;;;;;N;;;;;
+08B7;ARABIC LETTER PEH WITH SMALL MEEM ABOVE;Lo;0;AL;;;;;N;;;;;
+08B8;ARABIC LETTER TEH WITH SMALL TEH ABOVE;Lo;0;AL;;;;;N;;;;;
+08B9;ARABIC LETTER REH WITH SMALL NOON ABOVE;Lo;0;AL;;;;;N;;;;;
+08BA;ARABIC LETTER YEH WITH TWO DOTS BELOW AND SMALL NOON ABOVE;Lo;0;AL;;;;;N;;;;;
+08BB;ARABIC LETTER AFRICAN FEH;Lo;0;AL;;;;;N;;;;;
+08BC;ARABIC LETTER AFRICAN QAF;Lo;0;AL;;;;;N;;;;;
+08BD;ARABIC LETTER AFRICAN NOON;Lo;0;AL;;;;;N;;;;;
+08D4;ARABIC SMALL HIGH WORD AR-RUB;Mn;230;NSM;;;;;N;;;;;
+08D5;ARABIC SMALL HIGH SAD;Mn;230;NSM;;;;;N;;;;;
+08D6;ARABIC SMALL HIGH AIN;Mn;230;NSM;;;;;N;;;;;
+08D7;ARABIC SMALL HIGH QAF;Mn;230;NSM;;;;;N;;;;;
+08D8;ARABIC SMALL HIGH NOON WITH KASRA;Mn;230;NSM;;;;;N;;;;;
+08D9;ARABIC SMALL LOW NOON WITH KASRA;Mn;230;NSM;;;;;N;;;;;
+08DA;ARABIC SMALL HIGH WORD ATH-THALATHA;Mn;230;NSM;;;;;N;;;;;
+08DB;ARABIC SMALL HIGH WORD AS-SAJDA;Mn;230;NSM;;;;;N;;;;;
+08DC;ARABIC SMALL HIGH WORD AN-NISF;Mn;230;NSM;;;;;N;;;;;
+08DD;ARABIC SMALL HIGH WORD SAKTA;Mn;230;NSM;;;;;N;;;;;
+08DE;ARABIC SMALL HIGH WORD QIF;Mn;230;NSM;;;;;N;;;;;
+08DF;ARABIC SMALL HIGH WORD WAQFA;Mn;230;NSM;;;;;N;;;;;
+08E0;ARABIC SMALL HIGH FOOTNOTE MARKER;Mn;230;NSM;;;;;N;;;;;
+08E1;ARABIC SMALL HIGH SIGN SAFHA;Mn;230;NSM;;;;;N;;;;;
+08E2;ARABIC DISPUTED END OF AYAH;Cf;0;AN;;;;;N;;;;;
+08E3;ARABIC TURNED DAMMA BELOW;Mn;220;NSM;;;;;N;;;;;
+08E4;ARABIC CURLY FATHA;Mn;230;NSM;;;;;N;;;;;
+08E5;ARABIC CURLY DAMMA;Mn;230;NSM;;;;;N;;;;;
+08E6;ARABIC CURLY KASRA;Mn;220;NSM;;;;;N;;;;;
+08E7;ARABIC CURLY FATHATAN;Mn;230;NSM;;;;;N;;;;;
+08E8;ARABIC CURLY DAMMATAN;Mn;230;NSM;;;;;N;;;;;
+08E9;ARABIC CURLY KASRATAN;Mn;220;NSM;;;;;N;;;;;
+08EA;ARABIC TONE ONE DOT ABOVE;Mn;230;NSM;;;;;N;;;;;
+08EB;ARABIC TONE TWO DOTS ABOVE;Mn;230;NSM;;;;;N;;;;;
+08EC;ARABIC TONE LOOP ABOVE;Mn;230;NSM;;;;;N;;;;;
+08ED;ARABIC TONE ONE DOT BELOW;Mn;220;NSM;;;;;N;;;;;
+08EE;ARABIC TONE TWO DOTS BELOW;Mn;220;NSM;;;;;N;;;;;
+08EF;ARABIC TONE LOOP BELOW;Mn;220;NSM;;;;;N;;;;;
+08F0;ARABIC OPEN FATHATAN;Mn;27;NSM;;;;;N;;;;;
+08F1;ARABIC OPEN DAMMATAN;Mn;28;NSM;;;;;N;;;;;
+08F2;ARABIC OPEN KASRATAN;Mn;29;NSM;;;;;N;;;;;
+08F3;ARABIC SMALL HIGH WAW;Mn;230;NSM;;;;;N;;;;;
+08F4;ARABIC FATHA WITH RING;Mn;230;NSM;;;;;N;;;;;
+08F5;ARABIC FATHA WITH DOT ABOVE;Mn;230;NSM;;;;;N;;;;;
+08F6;ARABIC KASRA WITH DOT BELOW;Mn;220;NSM;;;;;N;;;;;
+08F7;ARABIC LEFT ARROWHEAD ABOVE;Mn;230;NSM;;;;;N;;;;;
+08F8;ARABIC RIGHT ARROWHEAD ABOVE;Mn;230;NSM;;;;;N;;;;;
+08F9;ARABIC LEFT ARROWHEAD BELOW;Mn;220;NSM;;;;;N;;;;;
+08FA;ARABIC RIGHT ARROWHEAD BELOW;Mn;220;NSM;;;;;N;;;;;
+08FB;ARABIC DOUBLE RIGHT ARROWHEAD ABOVE;Mn;230;NSM;;;;;N;;;;;
+08FC;ARABIC DOUBLE RIGHT ARROWHEAD ABOVE WITH DOT;Mn;230;NSM;;;;;N;;;;;
+08FD;ARABIC RIGHT ARROWHEAD ABOVE WITH DOT;Mn;230;NSM;;;;;N;;;;;
+08FE;ARABIC DAMMA WITH DOT;Mn;230;NSM;;;;;N;;;;;
+08FF;ARABIC MARK SIDEWAYS NOON GHUNNA;Mn;230;NSM;;;;;N;;;;;
0900;DEVANAGARI SIGN INVERTED CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
0901;DEVANAGARI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
0902;DEVANAGARI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
@@ -2082,6 +2214,8 @@
0937;DEVANAGARI LETTER SSA;Lo;0;L;;;;;N;;;;;
0938;DEVANAGARI LETTER SA;Lo;0;L;;;;;N;;;;;
0939;DEVANAGARI LETTER HA;Lo;0;L;;;;;N;;;;;
+093A;DEVANAGARI VOWEL SIGN OE;Mn;0;NSM;;;;;N;;;;;
+093B;DEVANAGARI VOWEL SIGN OOE;Mc;0;L;;;;;N;;;;;
093C;DEVANAGARI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
093D;DEVANAGARI SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;
093E;DEVANAGARI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
@@ -2101,12 +2235,15 @@
094C;DEVANAGARI VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;
094D;DEVANAGARI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
094E;DEVANAGARI VOWEL SIGN PRISHTHAMATRA E;Mc;0;L;;;;;N;;;;;
+094F;DEVANAGARI VOWEL SIGN AW;Mc;0;L;;;;;N;;;;;
0950;DEVANAGARI OM;Lo;0;L;;;;;N;;;;;
0951;DEVANAGARI STRESS SIGN UDATTA;Mn;230;NSM;;;;;N;;;;;
0952;DEVANAGARI STRESS SIGN ANUDATTA;Mn;220;NSM;;;;;N;;;;;
0953;DEVANAGARI GRAVE ACCENT;Mn;230;NSM;;;;;N;;;;;
0954;DEVANAGARI ACUTE ACCENT;Mn;230;NSM;;;;;N;;;;;
0955;DEVANAGARI VOWEL SIGN CANDRA LONG E;Mn;0;NSM;;;;;N;;;;;
+0956;DEVANAGARI VOWEL SIGN UE;Mn;0;NSM;;;;;N;;;;;
+0957;DEVANAGARI VOWEL SIGN UUE;Mn;0;NSM;;;;;N;;;;;
0958;DEVANAGARI LETTER QA;Lo;0;L;0915 093C;;;;N;;;;;
0959;DEVANAGARI LETTER KHHA;Lo;0;L;0916 093C;;;;N;;;;;
095A;DEVANAGARI LETTER GHHA;Lo;0;L;0917 093C;;;;N;;;;;
@@ -2134,6 +2271,12 @@
0970;DEVANAGARI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;;
0971;DEVANAGARI SIGN HIGH SPACING DOT;Lm;0;L;;;;;N;;;;;
0972;DEVANAGARI LETTER CANDRA A;Lo;0;L;;;;;N;;;;;
+0973;DEVANAGARI LETTER OE;Lo;0;L;;;;;N;;;;;
+0974;DEVANAGARI LETTER OOE;Lo;0;L;;;;;N;;;;;
+0975;DEVANAGARI LETTER AW;Lo;0;L;;;;;N;;;;;
+0976;DEVANAGARI LETTER UE;Lo;0;L;;;;;N;;;;;
+0977;DEVANAGARI LETTER UUE;Lo;0;L;;;;;N;;;;;
+0978;DEVANAGARI LETTER MARWARI DDA;Lo;0;L;;;;;N;;;;;
0979;DEVANAGARI LETTER ZHA;Lo;0;L;;;;;N;;;;;
097A;DEVANAGARI LETTER HEAVY YA;Lo;0;L;;;;;N;;;;;
097B;DEVANAGARI LETTER GGA;Lo;0;L;;;;;N;;;;;
@@ -2141,6 +2284,7 @@
097D;DEVANAGARI LETTER GLOTTAL STOP;Lo;0;L;;;;;N;;;;;
097E;DEVANAGARI LETTER DDDA;Lo;0;L;;;;;N;;;;;
097F;DEVANAGARI LETTER BBA;Lo;0;L;;;;;N;;;;;
+0980;BENGALI ANJI;Lo;0;L;;;;;N;;;;;
0981;BENGALI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
0982;BENGALI SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;
0983;BENGALI SIGN VISARGA;Mc;0;L;;;;;N;;;;;
@@ -2233,6 +2377,8 @@
09F9;BENGALI CURRENCY DENOMINATOR SIXTEEN;No;0;L;;;;16;N;;;;;
09FA;BENGALI ISSHAR;So;0;L;;;;;N;;;;;
09FB;BENGALI GANDA MARK;Sc;0;ET;;;;;N;;;;;
+09FC;BENGALI LETTER VEDIC ANUSVARA;Lo;0;L;;;;;N;;;;;
+09FD;BENGALI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;;
0A01;GURMUKHI SIGN ADAK BINDI;Mn;0;NSM;;;;;N;;;;;
0A02;GURMUKHI SIGN BINDI;Mn;0;NSM;;;;;N;;;;;
0A03;GURMUKHI SIGN VISARGA;Mc;0;L;;;;;N;;;;;
@@ -2394,7 +2540,15 @@
0AED;GUJARATI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
0AEE;GUJARATI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
0AEF;GUJARATI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+0AF0;GUJARATI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;;
0AF1;GUJARATI RUPEE SIGN;Sc;0;ET;;;;;N;;;;;
+0AF9;GUJARATI LETTER ZHA;Lo;0;L;;;;;N;;;;;
+0AFA;GUJARATI SIGN SUKUN;Mn;0;NSM;;;;;N;;;;;
+0AFB;GUJARATI SIGN SHADDA;Mn;0;NSM;;;;;N;;;;;
+0AFC;GUJARATI SIGN MADDAH;Mn;0;NSM;;;;;N;;;;;
+0AFD;GUJARATI SIGN THREE-DOT NUKTA ABOVE;Mn;0;NSM;;;;;N;;;;;
+0AFE;GUJARATI SIGN CIRCLE NUKTA ABOVE;Mn;0;NSM;;;;;N;;;;;
+0AFF;GUJARATI SIGN TWO-CIRCLE NUKTA ABOVE;Mn;0;NSM;;;;;N;;;;;
0B01;ORIYA SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
0B02;ORIYA SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;
0B03;ORIYA SIGN VISARGA;Mc;0;L;;;;;N;;;;;
@@ -2479,6 +2633,12 @@
0B6F;ORIYA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
0B70;ORIYA ISSHAR;So;0;L;;;;;N;;;;;
0B71;ORIYA LETTER WA;Lo;0;L;;;;;N;;;;;
+0B72;ORIYA FRACTION ONE QUARTER;No;0;L;;;;1/4;N;;;;;
+0B73;ORIYA FRACTION ONE HALF;No;0;L;;;;1/2;N;;;;;
+0B74;ORIYA FRACTION THREE QUARTERS;No;0;L;;;;3/4;N;;;;;
+0B75;ORIYA FRACTION ONE SIXTEENTH;No;0;L;;;;1/16;N;;;;;
+0B76;ORIYA FRACTION ONE EIGHTH;No;0;L;;;;1/8;N;;;;;
+0B77;ORIYA FRACTION THREE SIXTEENTHS;No;0;L;;;;3/16;N;;;;;
0B82;TAMIL SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
0B83;TAMIL SIGN VISARGA;Lo;0;L;;;;;N;;;;;
0B85;TAMIL LETTER A;Lo;0;L;;;;;N;;;;;
@@ -2551,6 +2711,7 @@
0BF8;TAMIL AS ABOVE SIGN;So;0;ON;;;;;N;;;;;
0BF9;TAMIL RUPEE SIGN;Sc;0;ET;;;;;N;;;;;
0BFA;TAMIL NUMBER SIGN;So;0;ON;;;;;N;;;;;
+0C00;TELUGU SIGN COMBINING CANDRABINDU ABOVE;Mn;0;NSM;;;;;N;;;;;
0C01;TELUGU SIGN CANDRABINDU;Mc;0;L;;;;;N;;;;;
0C02;TELUGU SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;
0C03;TELUGU SIGN VISARGA;Mc;0;L;;;;;N;;;;;
@@ -2598,6 +2759,7 @@
0C31;TELUGU LETTER RRA;Lo;0;L;;;;;N;;;;;
0C32;TELUGU LETTER LA;Lo;0;L;;;;;N;;;;;
0C33;TELUGU LETTER LLA;Lo;0;L;;;;;N;;;;;
+0C34;TELUGU LETTER LLLA;Lo;0;L;;;;;N;;;;;
0C35;TELUGU LETTER VA;Lo;0;L;;;;;N;;;;;
0C36;TELUGU LETTER SHA;Lo;0;L;;;;;N;;;;;
0C37;TELUGU LETTER SSA;Lo;0;L;;;;;N;;;;;
@@ -2622,6 +2784,7 @@
0C56;TELUGU AI LENGTH MARK;Mn;91;NSM;;;;;N;;;;;
0C58;TELUGU LETTER TSA;Lo;0;L;;;;;N;;;;;
0C59;TELUGU LETTER DZA;Lo;0;L;;;;;N;;;;;
+0C5A;TELUGU LETTER RRRA;Lo;0;L;;;;;N;;;;;
0C60;TELUGU LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
0C61;TELUGU LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
0C62;TELUGU VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
@@ -2644,6 +2807,8 @@
0C7D;TELUGU FRACTION DIGIT TWO FOR EVEN POWERS OF FOUR;No;0;ON;;;;2;N;;;;;
0C7E;TELUGU FRACTION DIGIT THREE FOR EVEN POWERS OF FOUR;No;0;ON;;;;3;N;;;;;
0C7F;TELUGU SIGN TUUMU;So;0;L;;;;;N;;;;;
+0C80;KANNADA SIGN SPACING CANDRABINDU;Lo;0;L;;;;;N;;;;;
+0C81;KANNADA SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
0C82;KANNADA SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;
0C83;KANNADA SIGN VISARGA;Mc;0;L;;;;;N;;;;;
0C85;KANNADA LETTER A;Lo;0;L;;;;;N;;;;;
@@ -2728,8 +2893,10 @@
0CED;KANNADA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
0CEE;KANNADA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
0CEF;KANNADA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
-0CF1;KANNADA SIGN JIHVAMULIYA;So;0;ON;;;;;N;;;;;
-0CF2;KANNADA SIGN UPADHMANIYA;So;0;ON;;;;;N;;;;;
+0CF1;KANNADA SIGN JIHVAMULIYA;Lo;0;L;;;;;N;;;;;
+0CF2;KANNADA SIGN UPADHMANIYA;Lo;0;L;;;;;N;;;;;
+0D00;MALAYALAM SIGN COMBINING ANUSVARA ABOVE;Mn;0;NSM;;;;;N;;;;;
+0D01;MALAYALAM SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
0D02;MALAYALAM SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;
0D03;MALAYALAM SIGN VISARGA;Mc;0;L;;;;;N;;;;;
0D05;MALAYALAM LETTER A;Lo;0;L;;;;;N;;;;;
@@ -2766,6 +2933,7 @@
0D26;MALAYALAM LETTER DA;Lo;0;L;;;;;N;;;;;
0D27;MALAYALAM LETTER DHA;Lo;0;L;;;;;N;;;;;
0D28;MALAYALAM LETTER NA;Lo;0;L;;;;;N;;;;;
+0D29;MALAYALAM LETTER NNNA;Lo;0;L;;;;;N;;;;;
0D2A;MALAYALAM LETTER PA;Lo;0;L;;;;;N;;;;;
0D2B;MALAYALAM LETTER PHA;Lo;0;L;;;;;N;;;;;
0D2C;MALAYALAM LETTER BA;Lo;0;L;;;;;N;;;;;
@@ -2782,6 +2950,9 @@
0D37;MALAYALAM LETTER SSA;Lo;0;L;;;;;N;;;;;
0D38;MALAYALAM LETTER SA;Lo;0;L;;;;;N;;;;;
0D39;MALAYALAM LETTER HA;Lo;0;L;;;;;N;;;;;
+0D3A;MALAYALAM LETTER TTTA;Lo;0;L;;;;;N;;;;;
+0D3B;MALAYALAM SIGN VERTICAL BAR VIRAMA;Mn;9;NSM;;;;;N;;;;;
+0D3C;MALAYALAM SIGN CIRCULAR VIRAMA;Mn;9;NSM;;;;;N;;;;;
0D3D;MALAYALAM SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;
0D3E;MALAYALAM VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
0D3F;MALAYALAM VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
@@ -2797,7 +2968,20 @@
0D4B;MALAYALAM VOWEL SIGN OO;Mc;0;L;0D47 0D3E;;;;N;;;;;
0D4C;MALAYALAM VOWEL SIGN AU;Mc;0;L;0D46 0D57;;;;N;;;;;
0D4D;MALAYALAM SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+0D4E;MALAYALAM LETTER DOT REPH;Lo;0;L;;;;;N;;;;;
+0D4F;MALAYALAM SIGN PARA;So;0;L;;;;;N;;;;;
+0D54;MALAYALAM LETTER CHILLU M;Lo;0;L;;;;;N;;;;;
+0D55;MALAYALAM LETTER CHILLU Y;Lo;0;L;;;;;N;;;;;
+0D56;MALAYALAM LETTER CHILLU LLL;Lo;0;L;;;;;N;;;;;
0D57;MALAYALAM AU LENGTH MARK;Mc;0;L;;;;;N;;;;;
+0D58;MALAYALAM FRACTION ONE ONE-HUNDRED-AND-SIXTIETH;No;0;L;;;;1/160;N;;;;;
+0D59;MALAYALAM FRACTION ONE FORTIETH;No;0;L;;;;1/40;N;;;;;
+0D5A;MALAYALAM FRACTION THREE EIGHTIETHS;No;0;L;;;;3/80;N;;;;;
+0D5B;MALAYALAM FRACTION ONE TWENTIETH;No;0;L;;;;1/20;N;;;;;
+0D5C;MALAYALAM FRACTION ONE TENTH;No;0;L;;;;1/10;N;;;;;
+0D5D;MALAYALAM FRACTION THREE TWENTIETHS;No;0;L;;;;3/20;N;;;;;
+0D5E;MALAYALAM FRACTION ONE FIFTH;No;0;L;;;;1/5;N;;;;;
+0D5F;MALAYALAM LETTER ARCHAIC II;Lo;0;L;;;;;N;;;;;
0D60;MALAYALAM LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
0D61;MALAYALAM LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
0D62;MALAYALAM VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
@@ -2818,6 +3002,9 @@
0D73;MALAYALAM FRACTION ONE QUARTER;No;0;L;;;;1/4;N;;;;;
0D74;MALAYALAM FRACTION ONE HALF;No;0;L;;;;1/2;N;;;;;
0D75;MALAYALAM FRACTION THREE QUARTERS;No;0;L;;;;3/4;N;;;;;
+0D76;MALAYALAM FRACTION ONE SIXTEENTH;No;0;L;;;;1/16;N;;;;;
+0D77;MALAYALAM FRACTION ONE EIGHTH;No;0;L;;;;1/8;N;;;;;
+0D78;MALAYALAM FRACTION THREE SIXTEENTHS;No;0;L;;;;3/16;N;;;;;
0D79;MALAYALAM DATE MARK;So;0;L;;;;;N;;;;;
0D7A;MALAYALAM LETTER CHILLU NN;Lo;0;L;;;;;N;;;;;
0D7B;MALAYALAM LETTER CHILLU N;Lo;0;L;;;;;N;;;;;
@@ -2902,6 +3089,16 @@
0DDD;SINHALA VOWEL SIGN KOMBUVA HAA DIGA AELA-PILLA;Mc;0;L;0DDC 0DCA;;;;N;;;;;
0DDE;SINHALA VOWEL SIGN KOMBUVA HAA GAYANUKITTA;Mc;0;L;0DD9 0DDF;;;;N;;;;;
0DDF;SINHALA VOWEL SIGN GAYANUKITTA;Mc;0;L;;;;;N;;;;;
+0DE6;SINHALA LITH DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+0DE7;SINHALA LITH DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+0DE8;SINHALA LITH DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+0DE9;SINHALA LITH DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+0DEA;SINHALA LITH DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+0DEB;SINHALA LITH DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+0DEC;SINHALA LITH DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+0DED;SINHALA LITH DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+0DEE;SINHALA LITH DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+0DEF;SINHALA LITH DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
0DF2;SINHALA VOWEL SIGN DIGA GAETTA-PILLA;Mc;0;L;;;;;N;;;;;
0DF3;SINHALA VOWEL SIGN DIGA GAYANUKITTA;Mc;0;L;;;;;N;;;;;
0DF4;SINHALA PUNCTUATION KUNDDALIYA;Po;0;L;;;;;N;;;;;
@@ -3057,6 +3254,8 @@
0ED9;LAO DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
0EDC;LAO HO NO;Lo;0;L;<compat> 0EAB 0E99;;;;N;;;;;
0EDD;LAO HO MO;Lo;0;L;<compat> 0EAB 0EA1;;;;N;;;;;
+0EDE;LAO LETTER KHMU GO;Lo;0;L;;;;;N;;;;;
+0EDF;LAO LETTER KHMU NYO;Lo;0;L;;;;;N;;;;;
0F00;TIBETAN SYLLABLE OM;Lo;0;L;;;;;N;;;;;
0F01;TIBETAN MARK GTER YIG MGO TRUNCATED A;So;0;L;;;;;N;;;;;
0F02;TIBETAN MARK GTER YIG MGO -UM RNAM BCAD MA;So;0;L;;;;;N;;;;;
@@ -3077,7 +3276,7 @@
0F11;TIBETAN MARK RIN CHEN SPUNGS SHAD;Po;0;L;;;;;N;TIBETAN RINCHANPHUNGSHAD;;;;
0F12;TIBETAN MARK RGYA GRAM SHAD;Po;0;L;;;;;N;;;;;
0F13;TIBETAN MARK CARET -DZUD RTAGS ME LONG CAN;So;0;L;;;;;N;;;;;
-0F14;TIBETAN MARK GTER TSHEG;So;0;L;;;;;N;TIBETAN COMMA;;;;
+0F14;TIBETAN MARK GTER TSHEG;Po;0;L;;;;;N;TIBETAN COMMA;;;;
0F15;TIBETAN LOGOTYPE SIGN CHAD RTAGS;So;0;L;;;;;N;;;;;
0F16;TIBETAN LOGOTYPE SIGN LHAG RTAGS;So;0;L;;;;;N;;;;;
0F17;TIBETAN ASTROLOGICAL SIGN SGRA GCAN -CHAR RTAGS;So;0;L;;;;;N;;;;;
@@ -3192,6 +3391,10 @@
0F89;TIBETAN SIGN MCHU CAN;Lo;0;L;;;;;N;;;;;
0F8A;TIBETAN SIGN GRU CAN RGYINGS;Lo;0;L;;;;;N;;;;;
0F8B;TIBETAN SIGN GRU MED RGYINGS;Lo;0;L;;;;;N;;;;;
+0F8C;TIBETAN SIGN INVERTED MCHU CAN;Lo;0;L;;;;;N;;;;;
+0F8D;TIBETAN SUBJOINED SIGN LCE TSA CAN;Mn;0;NSM;;;;;N;;;;;
+0F8E;TIBETAN SUBJOINED SIGN MCHU CAN;Mn;0;NSM;;;;;N;;;;;
+0F8F;TIBETAN SUBJOINED SIGN INVERTED MCHU CAN;Mn;0;NSM;;;;;N;;;;;
0F90;TIBETAN SUBJOINED LETTER KA;Mn;0;NSM;;;;;N;;;;;
0F91;TIBETAN SUBJOINED LETTER KHA;Mn;0;NSM;;;;;N;;;;;
0F92;TIBETAN SUBJOINED LETTER GA;Mn;0;NSM;;;;;N;;;;;
@@ -3262,6 +3465,8 @@
0FD6;LEFT-FACING SVASTI SIGN;So;0;L;;;;;N;;;;;
0FD7;RIGHT-FACING SVASTI SIGN WITH DOTS;So;0;L;;;;;N;;;;;
0FD8;LEFT-FACING SVASTI SIGN WITH DOTS;So;0;L;;;;;N;;;;;
+0FD9;TIBETAN MARK LEADING MCHAN RTAGS;Po;0;L;;;;;N;;;;;
+0FDA;TIBETAN MARK TRAILING MCHAN RTAGS;Po;0;L;;;;;N;;;;;
1000;MYANMAR LETTER KA;Lo;0;L;;;;;N;;;;;
1001;MYANMAR LETTER KHA;Lo;0;L;;;;;N;;;;;
1002;MYANMAR LETTER GA;Lo;0;L;;;;;N;;;;;
@@ -3460,6 +3665,8 @@
10C3;GEORGIAN CAPITAL LETTER WE;Lu;0;L;;;;;N;;;;2D23;
10C4;GEORGIAN CAPITAL LETTER HAR;Lu;0;L;;;;;N;;;;2D24;
10C5;GEORGIAN CAPITAL LETTER HOE;Lu;0;L;;;;;N;;;;2D25;
+10C7;GEORGIAN CAPITAL LETTER YN;Lu;0;L;;;;;N;;;;2D27;
+10CD;GEORGIAN CAPITAL LETTER AEN;Lu;0;L;;;;;N;;;;2D2D;
10D0;GEORGIAN LETTER AN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER AN;;;;
10D1;GEORGIAN LETTER BAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER BAN;;;;
10D2;GEORGIAN LETTER GAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER GAN;;;;
@@ -3505,6 +3712,9 @@
10FA;GEORGIAN LETTER AIN;Lo;0;L;;;;;N;;;;;
10FB;GEORGIAN PARAGRAPH SEPARATOR;Po;0;L;;;;;N;;;;;
10FC;MODIFIER LETTER GEORGIAN NAR;Lm;0;L;<super> 10DC;;;;N;;;;;
+10FD;GEORGIAN LETTER AEN;Lo;0;L;;;;;N;;;;;
+10FE;GEORGIAN LETTER HARD SIGN;Lo;0;L;;;;;N;;;;;
+10FF;GEORGIAN LETTER LABIAL SIGN;Lo;0;L;;;;;N;;;;;
1100;HANGUL CHOSEONG KIYEOK;Lo;0;L;;;;;N;;;;;
1101;HANGUL CHOSEONG SSANGKIYEOK;Lo;0;L;;;;;N;;;;;
1102;HANGUL CHOSEONG NIEUN;Lo;0;L;;;;;N;;;;;
@@ -4087,8 +4297,10 @@
1358;ETHIOPIC SYLLABLE RYA;Lo;0;L;;;;;N;;;;;
1359;ETHIOPIC SYLLABLE MYA;Lo;0;L;;;;;N;;;;;
135A;ETHIOPIC SYLLABLE FYA;Lo;0;L;;;;;N;;;;;
+135D;ETHIOPIC COMBINING GEMINATION AND VOWEL LENGTH MARK;Mn;230;NSM;;;;;N;;;;;
+135E;ETHIOPIC COMBINING VOWEL LENGTH MARK;Mn;230;NSM;;;;;N;;;;;
135F;ETHIOPIC COMBINING GEMINATION MARK;Mn;230;NSM;;;;;N;;;;;
-1360;ETHIOPIC SECTION MARK;So;0;L;;;;;N;;;;;
+1360;ETHIOPIC SECTION MARK;Po;0;L;;;;;N;;;;;
1361;ETHIOPIC WORDSPACE;Po;0;L;;;;;N;;;;;
1362;ETHIOPIC FULL STOP;Po;0;L;;;;;N;;;;;
1363;ETHIOPIC COMMA;Po;0;L;;;;;N;;;;;
@@ -4143,91 +4355,98 @@
1397;ETHIOPIC TONAL MARK HIDET;So;0;ON;;;;;N;;;;;
1398;ETHIOPIC TONAL MARK DERET-HIDET;So;0;ON;;;;;N;;;;;
1399;ETHIOPIC TONAL MARK KURT;So;0;ON;;;;;N;;;;;
-13A0;CHEROKEE LETTER A;Lo;0;L;;;;;N;;;;;
-13A1;CHEROKEE LETTER E;Lo;0;L;;;;;N;;;;;
-13A2;CHEROKEE LETTER I;Lo;0;L;;;;;N;;;;;
-13A3;CHEROKEE LETTER O;Lo;0;L;;;;;N;;;;;
-13A4;CHEROKEE LETTER U;Lo;0;L;;;;;N;;;;;
-13A5;CHEROKEE LETTER V;Lo;0;L;;;;;N;;;;;
-13A6;CHEROKEE LETTER GA;Lo;0;L;;;;;N;;;;;
-13A7;CHEROKEE LETTER KA;Lo;0;L;;;;;N;;;;;
-13A8;CHEROKEE LETTER GE;Lo;0;L;;;;;N;;;;;
-13A9;CHEROKEE LETTER GI;Lo;0;L;;;;;N;;;;;
-13AA;CHEROKEE LETTER GO;Lo;0;L;;;;;N;;;;;
-13AB;CHEROKEE LETTER GU;Lo;0;L;;;;;N;;;;;
-13AC;CHEROKEE LETTER GV;Lo;0;L;;;;;N;;;;;
-13AD;CHEROKEE LETTER HA;Lo;0;L;;;;;N;;;;;
-13AE;CHEROKEE LETTER HE;Lo;0;L;;;;;N;;;;;
-13AF;CHEROKEE LETTER HI;Lo;0;L;;;;;N;;;;;
-13B0;CHEROKEE LETTER HO;Lo;0;L;;;;;N;;;;;
-13B1;CHEROKEE LETTER HU;Lo;0;L;;;;;N;;;;;
-13B2;CHEROKEE LETTER HV;Lo;0;L;;;;;N;;;;;
-13B3;CHEROKEE LETTER LA;Lo;0;L;;;;;N;;;;;
-13B4;CHEROKEE LETTER LE;Lo;0;L;;;;;N;;;;;
-13B5;CHEROKEE LETTER LI;Lo;0;L;;;;;N;;;;;
-13B6;CHEROKEE LETTER LO;Lo;0;L;;;;;N;;;;;
-13B7;CHEROKEE LETTER LU;Lo;0;L;;;;;N;;;;;
-13B8;CHEROKEE LETTER LV;Lo;0;L;;;;;N;;;;;
-13B9;CHEROKEE LETTER MA;Lo;0;L;;;;;N;;;;;
-13BA;CHEROKEE LETTER ME;Lo;0;L;;;;;N;;;;;
-13BB;CHEROKEE LETTER MI;Lo;0;L;;;;;N;;;;;
-13BC;CHEROKEE LETTER MO;Lo;0;L;;;;;N;;;;;
-13BD;CHEROKEE LETTER MU;Lo;0;L;;;;;N;;;;;
-13BE;CHEROKEE LETTER NA;Lo;0;L;;;;;N;;;;;
-13BF;CHEROKEE LETTER HNA;Lo;0;L;;;;;N;;;;;
-13C0;CHEROKEE LETTER NAH;Lo;0;L;;;;;N;;;;;
-13C1;CHEROKEE LETTER NE;Lo;0;L;;;;;N;;;;;
-13C2;CHEROKEE LETTER NI;Lo;0;L;;;;;N;;;;;
-13C3;CHEROKEE LETTER NO;Lo;0;L;;;;;N;;;;;
-13C4;CHEROKEE LETTER NU;Lo;0;L;;;;;N;;;;;
-13C5;CHEROKEE LETTER NV;Lo;0;L;;;;;N;;;;;
-13C6;CHEROKEE LETTER QUA;Lo;0;L;;;;;N;;;;;
-13C7;CHEROKEE LETTER QUE;Lo;0;L;;;;;N;;;;;
-13C8;CHEROKEE LETTER QUI;Lo;0;L;;;;;N;;;;;
-13C9;CHEROKEE LETTER QUO;Lo;0;L;;;;;N;;;;;
-13CA;CHEROKEE LETTER QUU;Lo;0;L;;;;;N;;;;;
-13CB;CHEROKEE LETTER QUV;Lo;0;L;;;;;N;;;;;
-13CC;CHEROKEE LETTER SA;Lo;0;L;;;;;N;;;;;
-13CD;CHEROKEE LETTER S;Lo;0;L;;;;;N;;;;;
-13CE;CHEROKEE LETTER SE;Lo;0;L;;;;;N;;;;;
-13CF;CHEROKEE LETTER SI;Lo;0;L;;;;;N;;;;;
-13D0;CHEROKEE LETTER SO;Lo;0;L;;;;;N;;;;;
-13D1;CHEROKEE LETTER SU;Lo;0;L;;;;;N;;;;;
-13D2;CHEROKEE LETTER SV;Lo;0;L;;;;;N;;;;;
-13D3;CHEROKEE LETTER DA;Lo;0;L;;;;;N;;;;;
-13D4;CHEROKEE LETTER TA;Lo;0;L;;;;;N;;;;;
-13D5;CHEROKEE LETTER DE;Lo;0;L;;;;;N;;;;;
-13D6;CHEROKEE LETTER TE;Lo;0;L;;;;;N;;;;;
-13D7;CHEROKEE LETTER DI;Lo;0;L;;;;;N;;;;;
-13D8;CHEROKEE LETTER TI;Lo;0;L;;;;;N;;;;;
-13D9;CHEROKEE LETTER DO;Lo;0;L;;;;;N;;;;;
-13DA;CHEROKEE LETTER DU;Lo;0;L;;;;;N;;;;;
-13DB;CHEROKEE LETTER DV;Lo;0;L;;;;;N;;;;;
-13DC;CHEROKEE LETTER DLA;Lo;0;L;;;;;N;;;;;
-13DD;CHEROKEE LETTER TLA;Lo;0;L;;;;;N;;;;;
-13DE;CHEROKEE LETTER TLE;Lo;0;L;;;;;N;;;;;
-13DF;CHEROKEE LETTER TLI;Lo;0;L;;;;;N;;;;;
-13E0;CHEROKEE LETTER TLO;Lo;0;L;;;;;N;;;;;
-13E1;CHEROKEE LETTER TLU;Lo;0;L;;;;;N;;;;;
-13E2;CHEROKEE LETTER TLV;Lo;0;L;;;;;N;;;;;
-13E3;CHEROKEE LETTER TSA;Lo;0;L;;;;;N;;;;;
-13E4;CHEROKEE LETTER TSE;Lo;0;L;;;;;N;;;;;
-13E5;CHEROKEE LETTER TSI;Lo;0;L;;;;;N;;;;;
-13E6;CHEROKEE LETTER TSO;Lo;0;L;;;;;N;;;;;
-13E7;CHEROKEE LETTER TSU;Lo;0;L;;;;;N;;;;;
-13E8;CHEROKEE LETTER TSV;Lo;0;L;;;;;N;;;;;
-13E9;CHEROKEE LETTER WA;Lo;0;L;;;;;N;;;;;
-13EA;CHEROKEE LETTER WE;Lo;0;L;;;;;N;;;;;
-13EB;CHEROKEE LETTER WI;Lo;0;L;;;;;N;;;;;
-13EC;CHEROKEE LETTER WO;Lo;0;L;;;;;N;;;;;
-13ED;CHEROKEE LETTER WU;Lo;0;L;;;;;N;;;;;
-13EE;CHEROKEE LETTER WV;Lo;0;L;;;;;N;;;;;
-13EF;CHEROKEE LETTER YA;Lo;0;L;;;;;N;;;;;
-13F0;CHEROKEE LETTER YE;Lo;0;L;;;;;N;;;;;
-13F1;CHEROKEE LETTER YI;Lo;0;L;;;;;N;;;;;
-13F2;CHEROKEE LETTER YO;Lo;0;L;;;;;N;;;;;
-13F3;CHEROKEE LETTER YU;Lo;0;L;;;;;N;;;;;
-13F4;CHEROKEE LETTER YV;Lo;0;L;;;;;N;;;;;
+13A0;CHEROKEE LETTER A;Lu;0;L;;;;;N;;;;AB70;
+13A1;CHEROKEE LETTER E;Lu;0;L;;;;;N;;;;AB71;
+13A2;CHEROKEE LETTER I;Lu;0;L;;;;;N;;;;AB72;
+13A3;CHEROKEE LETTER O;Lu;0;L;;;;;N;;;;AB73;
+13A4;CHEROKEE LETTER U;Lu;0;L;;;;;N;;;;AB74;
+13A5;CHEROKEE LETTER V;Lu;0;L;;;;;N;;;;AB75;
+13A6;CHEROKEE LETTER GA;Lu;0;L;;;;;N;;;;AB76;
+13A7;CHEROKEE LETTER KA;Lu;0;L;;;;;N;;;;AB77;
+13A8;CHEROKEE LETTER GE;Lu;0;L;;;;;N;;;;AB78;
+13A9;CHEROKEE LETTER GI;Lu;0;L;;;;;N;;;;AB79;
+13AA;CHEROKEE LETTER GO;Lu;0;L;;;;;N;;;;AB7A;
+13AB;CHEROKEE LETTER GU;Lu;0;L;;;;;N;;;;AB7B;
+13AC;CHEROKEE LETTER GV;Lu;0;L;;;;;N;;;;AB7C;
+13AD;CHEROKEE LETTER HA;Lu;0;L;;;;;N;;;;AB7D;
+13AE;CHEROKEE LETTER HE;Lu;0;L;;;;;N;;;;AB7E;
+13AF;CHEROKEE LETTER HI;Lu;0;L;;;;;N;;;;AB7F;
+13B0;CHEROKEE LETTER HO;Lu;0;L;;;;;N;;;;AB80;
+13B1;CHEROKEE LETTER HU;Lu;0;L;;;;;N;;;;AB81;
+13B2;CHEROKEE LETTER HV;Lu;0;L;;;;;N;;;;AB82;
+13B3;CHEROKEE LETTER LA;Lu;0;L;;;;;N;;;;AB83;
+13B4;CHEROKEE LETTER LE;Lu;0;L;;;;;N;;;;AB84;
+13B5;CHEROKEE LETTER LI;Lu;0;L;;;;;N;;;;AB85;
+13B6;CHEROKEE LETTER LO;Lu;0;L;;;;;N;;;;AB86;
+13B7;CHEROKEE LETTER LU;Lu;0;L;;;;;N;;;;AB87;
+13B8;CHEROKEE LETTER LV;Lu;0;L;;;;;N;;;;AB88;
+13B9;CHEROKEE LETTER MA;Lu;0;L;;;;;N;;;;AB89;
+13BA;CHEROKEE LETTER ME;Lu;0;L;;;;;N;;;;AB8A;
+13BB;CHEROKEE LETTER MI;Lu;0;L;;;;;N;;;;AB8B;
+13BC;CHEROKEE LETTER MO;Lu;0;L;;;;;N;;;;AB8C;
+13BD;CHEROKEE LETTER MU;Lu;0;L;;;;;N;;;;AB8D;
+13BE;CHEROKEE LETTER NA;Lu;0;L;;;;;N;;;;AB8E;
+13BF;CHEROKEE LETTER HNA;Lu;0;L;;;;;N;;;;AB8F;
+13C0;CHEROKEE LETTER NAH;Lu;0;L;;;;;N;;;;AB90;
+13C1;CHEROKEE LETTER NE;Lu;0;L;;;;;N;;;;AB91;
+13C2;CHEROKEE LETTER NI;Lu;0;L;;;;;N;;;;AB92;
+13C3;CHEROKEE LETTER NO;Lu;0;L;;;;;N;;;;AB93;
+13C4;CHEROKEE LETTER NU;Lu;0;L;;;;;N;;;;AB94;
+13C5;CHEROKEE LETTER NV;Lu;0;L;;;;;N;;;;AB95;
+13C6;CHEROKEE LETTER QUA;Lu;0;L;;;;;N;;;;AB96;
+13C7;CHEROKEE LETTER QUE;Lu;0;L;;;;;N;;;;AB97;
+13C8;CHEROKEE LETTER QUI;Lu;0;L;;;;;N;;;;AB98;
+13C9;CHEROKEE LETTER QUO;Lu;0;L;;;;;N;;;;AB99;
+13CA;CHEROKEE LETTER QUU;Lu;0;L;;;;;N;;;;AB9A;
+13CB;CHEROKEE LETTER QUV;Lu;0;L;;;;;N;;;;AB9B;
+13CC;CHEROKEE LETTER SA;Lu;0;L;;;;;N;;;;AB9C;
+13CD;CHEROKEE LETTER S;Lu;0;L;;;;;N;;;;AB9D;
+13CE;CHEROKEE LETTER SE;Lu;0;L;;;;;N;;;;AB9E;
+13CF;CHEROKEE LETTER SI;Lu;0;L;;;;;N;;;;AB9F;
+13D0;CHEROKEE LETTER SO;Lu;0;L;;;;;N;;;;ABA0;
+13D1;CHEROKEE LETTER SU;Lu;0;L;;;;;N;;;;ABA1;
+13D2;CHEROKEE LETTER SV;Lu;0;L;;;;;N;;;;ABA2;
+13D3;CHEROKEE LETTER DA;Lu;0;L;;;;;N;;;;ABA3;
+13D4;CHEROKEE LETTER TA;Lu;0;L;;;;;N;;;;ABA4;
+13D5;CHEROKEE LETTER DE;Lu;0;L;;;;;N;;;;ABA5;
+13D6;CHEROKEE LETTER TE;Lu;0;L;;;;;N;;;;ABA6;
+13D7;CHEROKEE LETTER DI;Lu;0;L;;;;;N;;;;ABA7;
+13D8;CHEROKEE LETTER TI;Lu;0;L;;;;;N;;;;ABA8;
+13D9;CHEROKEE LETTER DO;Lu;0;L;;;;;N;;;;ABA9;
+13DA;CHEROKEE LETTER DU;Lu;0;L;;;;;N;;;;ABAA;
+13DB;CHEROKEE LETTER DV;Lu;0;L;;;;;N;;;;ABAB;
+13DC;CHEROKEE LETTER DLA;Lu;0;L;;;;;N;;;;ABAC;
+13DD;CHEROKEE LETTER TLA;Lu;0;L;;;;;N;;;;ABAD;
+13DE;CHEROKEE LETTER TLE;Lu;0;L;;;;;N;;;;ABAE;
+13DF;CHEROKEE LETTER TLI;Lu;0;L;;;;;N;;;;ABAF;
+13E0;CHEROKEE LETTER TLO;Lu;0;L;;;;;N;;;;ABB0;
+13E1;CHEROKEE LETTER TLU;Lu;0;L;;;;;N;;;;ABB1;
+13E2;CHEROKEE LETTER TLV;Lu;0;L;;;;;N;;;;ABB2;
+13E3;CHEROKEE LETTER TSA;Lu;0;L;;;;;N;;;;ABB3;
+13E4;CHEROKEE LETTER TSE;Lu;0;L;;;;;N;;;;ABB4;
+13E5;CHEROKEE LETTER TSI;Lu;0;L;;;;;N;;;;ABB5;
+13E6;CHEROKEE LETTER TSO;Lu;0;L;;;;;N;;;;ABB6;
+13E7;CHEROKEE LETTER TSU;Lu;0;L;;;;;N;;;;ABB7;
+13E8;CHEROKEE LETTER TSV;Lu;0;L;;;;;N;;;;ABB8;
+13E9;CHEROKEE LETTER WA;Lu;0;L;;;;;N;;;;ABB9;
+13EA;CHEROKEE LETTER WE;Lu;0;L;;;;;N;;;;ABBA;
+13EB;CHEROKEE LETTER WI;Lu;0;L;;;;;N;;;;ABBB;
+13EC;CHEROKEE LETTER WO;Lu;0;L;;;;;N;;;;ABBC;
+13ED;CHEROKEE LETTER WU;Lu;0;L;;;;;N;;;;ABBD;
+13EE;CHEROKEE LETTER WV;Lu;0;L;;;;;N;;;;ABBE;
+13EF;CHEROKEE LETTER YA;Lu;0;L;;;;;N;;;;ABBF;
+13F0;CHEROKEE LETTER YE;Lu;0;L;;;;;N;;;;13F8;
+13F1;CHEROKEE LETTER YI;Lu;0;L;;;;;N;;;;13F9;
+13F2;CHEROKEE LETTER YO;Lu;0;L;;;;;N;;;;13FA;
+13F3;CHEROKEE LETTER YU;Lu;0;L;;;;;N;;;;13FB;
+13F4;CHEROKEE LETTER YV;Lu;0;L;;;;;N;;;;13FC;
+13F5;CHEROKEE LETTER MV;Lu;0;L;;;;;N;;;;13FD;
+13F8;CHEROKEE SMALL LETTER YE;Ll;0;L;;;;;N;;;13F0;;13F0
+13F9;CHEROKEE SMALL LETTER YI;Ll;0;L;;;;;N;;;13F1;;13F1
+13FA;CHEROKEE SMALL LETTER YO;Ll;0;L;;;;;N;;;13F2;;13F2
+13FB;CHEROKEE SMALL LETTER YU;Ll;0;L;;;;;N;;;13F3;;13F3
+13FC;CHEROKEE SMALL LETTER YV;Ll;0;L;;;;;N;;;13F4;;13F4
+13FD;CHEROKEE SMALL LETTER MV;Ll;0;L;;;;;N;;;13F5;;13F5
1400;CANADIAN SYLLABICS HYPHEN;Pd;0;ON;;;;;N;;;;;
1401;CANADIAN SYLLABICS E;Lo;0;L;;;;;N;;;;;
1402;CANADIAN SYLLABICS AAI;Lo;0;L;;;;;N;;;;;
@@ -4978,6 +5197,14 @@
16EE;RUNIC ARLAUG SYMBOL;Nl;0;L;;;;17;N;;;;;
16EF;RUNIC TVIMADUR SYMBOL;Nl;0;L;;;;18;N;;;;;
16F0;RUNIC BELGTHOR SYMBOL;Nl;0;L;;;;19;N;;;;;
+16F1;RUNIC LETTER K;Lo;0;L;;;;;N;;;;;
+16F2;RUNIC LETTER SH;Lo;0;L;;;;;N;;;;;
+16F3;RUNIC LETTER OO;Lo;0;L;;;;;N;;;;;
+16F4;RUNIC LETTER FRANKS CASKET OS;Lo;0;L;;;;;N;;;;;
+16F5;RUNIC LETTER FRANKS CASKET IS;Lo;0;L;;;;;N;;;;;
+16F6;RUNIC LETTER FRANKS CASKET EH;Lo;0;L;;;;;N;;;;;
+16F7;RUNIC LETTER FRANKS CASKET AC;Lo;0;L;;;;;N;;;;;
+16F8;RUNIC LETTER FRANKS CASKET AESC;Lo;0;L;;;;;N;;;;;
1700;TAGALOG LETTER A;Lo;0;L;;;;;N;;;;;
1701;TAGALOG LETTER I;Lo;0;L;;;;;N;;;;;
1702;TAGALOG LETTER U;Lo;0;L;;;;;N;;;;;
@@ -5111,8 +5338,8 @@
17B1;KHMER INDEPENDENT VOWEL QOO TYPE ONE;Lo;0;L;;;;;N;;;;;
17B2;KHMER INDEPENDENT VOWEL QOO TYPE TWO;Lo;0;L;;;;;N;;;;;
17B3;KHMER INDEPENDENT VOWEL QAU;Lo;0;L;;;;;N;;;;;
-17B4;KHMER VOWEL INHERENT AQ;Cf;0;L;;;;;N;;;;;
-17B5;KHMER VOWEL INHERENT AA;Cf;0;L;;;;;N;;;;;
+17B4;KHMER VOWEL INHERENT AQ;Mn;0;NSM;;;;;N;;;;;
+17B5;KHMER VOWEL INHERENT AA;Mn;0;NSM;;;;;N;;;;;
17B6;KHMER VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
17B7;KHMER VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
17B8;KHMER VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;
@@ -5187,7 +5414,7 @@
180B;MONGOLIAN FREE VARIATION SELECTOR ONE;Mn;0;NSM;;;;;N;;;;;
180C;MONGOLIAN FREE VARIATION SELECTOR TWO;Mn;0;NSM;;;;;N;;;;;
180D;MONGOLIAN FREE VARIATION SELECTOR THREE;Mn;0;NSM;;;;;N;;;;;
-180E;MONGOLIAN VOWEL SEPARATOR;Zs;0;WS;;;;;N;;;;;
+180E;MONGOLIAN VOWEL SEPARATOR;Cf;0;BN;;;;;N;;;;;
1810;MONGOLIAN DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
1811;MONGOLIAN DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
1812;MONGOLIAN DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
@@ -5291,8 +5518,8 @@
1882;MONGOLIAN LETTER ALI GALI DAMARU;Lo;0;L;;;;;N;;;;;
1883;MONGOLIAN LETTER ALI GALI UBADAMA;Lo;0;L;;;;;N;;;;;
1884;MONGOLIAN LETTER ALI GALI INVERTED UBADAMA;Lo;0;L;;;;;N;;;;;
-1885;MONGOLIAN LETTER ALI GALI BALUDA;Lo;0;L;;;;;N;;;;;
-1886;MONGOLIAN LETTER ALI GALI THREE BALUDA;Lo;0;L;;;;;N;;;;;
+1885;MONGOLIAN LETTER ALI GALI BALUDA;Mn;0;NSM;;;;;N;;;;;
+1886;MONGOLIAN LETTER ALI GALI THREE BALUDA;Mn;0;NSM;;;;;N;;;;;
1887;MONGOLIAN LETTER ALI GALI A;Lo;0;L;;;;;N;;;;;
1888;MONGOLIAN LETTER ALI GALI I;Lo;0;L;;;;;N;;;;;
1889;MONGOLIAN LETTER ALI GALI KA;Lo;0;L;;;;;N;;;;;
@@ -5428,6 +5655,8 @@
191A;LIMBU LETTER SSA;Lo;0;L;;;;;N;;;;;
191B;LIMBU LETTER SA;Lo;0;L;;;;;N;;;;;
191C;LIMBU LETTER HA;Lo;0;L;;;;;N;;;;;
+191D;LIMBU LETTER GYAN;Lo;0;L;;;;;N;;;;;
+191E;LIMBU LETTER TRA;Lo;0;L;;;;;N;;;;;
1920;LIMBU VOWEL SIGN A;Mn;0;NSM;;;;;N;;;;;
1921;LIMBU VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
1922;LIMBU VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
@@ -5544,23 +5773,23 @@
19A9;NEW TAI LUE LETTER LOW XVA;Lo;0;L;;;;;N;;;;;
19AA;NEW TAI LUE LETTER HIGH SUA;Lo;0;L;;;;;N;;;;;
19AB;NEW TAI LUE LETTER LOW SUA;Lo;0;L;;;;;N;;;;;
-19B0;NEW TAI LUE VOWEL SIGN VOWEL SHORTENER;Mc;0;L;;;;;N;;;;;
-19B1;NEW TAI LUE VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
-19B2;NEW TAI LUE VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
-19B3;NEW TAI LUE VOWEL SIGN U;Mc;0;L;;;;;N;;;;;
-19B4;NEW TAI LUE VOWEL SIGN UU;Mc;0;L;;;;;N;;;;;
-19B5;NEW TAI LUE VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
-19B6;NEW TAI LUE VOWEL SIGN AE;Mc;0;L;;;;;N;;;;;
-19B7;NEW TAI LUE VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
-19B8;NEW TAI LUE VOWEL SIGN OA;Mc;0;L;;;;;N;;;;;
-19B9;NEW TAI LUE VOWEL SIGN UE;Mc;0;L;;;;;N;;;;;
-19BA;NEW TAI LUE VOWEL SIGN AY;Mc;0;L;;;;;N;;;;;
-19BB;NEW TAI LUE VOWEL SIGN AAY;Mc;0;L;;;;;N;;;;;
-19BC;NEW TAI LUE VOWEL SIGN UY;Mc;0;L;;;;;N;;;;;
-19BD;NEW TAI LUE VOWEL SIGN OY;Mc;0;L;;;;;N;;;;;
-19BE;NEW TAI LUE VOWEL SIGN OAY;Mc;0;L;;;;;N;;;;;
-19BF;NEW TAI LUE VOWEL SIGN UEY;Mc;0;L;;;;;N;;;;;
-19C0;NEW TAI LUE VOWEL SIGN IY;Mc;0;L;;;;;N;;;;;
+19B0;NEW TAI LUE VOWEL SIGN VOWEL SHORTENER;Lo;0;L;;;;;N;;;;;
+19B1;NEW TAI LUE VOWEL SIGN AA;Lo;0;L;;;;;N;;;;;
+19B2;NEW TAI LUE VOWEL SIGN II;Lo;0;L;;;;;N;;;;;
+19B3;NEW TAI LUE VOWEL SIGN U;Lo;0;L;;;;;N;;;;;
+19B4;NEW TAI LUE VOWEL SIGN UU;Lo;0;L;;;;;N;;;;;
+19B5;NEW TAI LUE VOWEL SIGN E;Lo;0;L;;;;;N;;;;;
+19B6;NEW TAI LUE VOWEL SIGN AE;Lo;0;L;;;;;N;;;;;
+19B7;NEW TAI LUE VOWEL SIGN O;Lo;0;L;;;;;N;;;;;
+19B8;NEW TAI LUE VOWEL SIGN OA;Lo;0;L;;;;;N;;;;;
+19B9;NEW TAI LUE VOWEL SIGN UE;Lo;0;L;;;;;N;;;;;
+19BA;NEW TAI LUE VOWEL SIGN AY;Lo;0;L;;;;;N;;;;;
+19BB;NEW TAI LUE VOWEL SIGN AAY;Lo;0;L;;;;;N;;;;;
+19BC;NEW TAI LUE VOWEL SIGN UY;Lo;0;L;;;;;N;;;;;
+19BD;NEW TAI LUE VOWEL SIGN OY;Lo;0;L;;;;;N;;;;;
+19BE;NEW TAI LUE VOWEL SIGN OAY;Lo;0;L;;;;;N;;;;;
+19BF;NEW TAI LUE VOWEL SIGN UEY;Lo;0;L;;;;;N;;;;;
+19C0;NEW TAI LUE VOWEL SIGN IY;Lo;0;L;;;;;N;;;;;
19C1;NEW TAI LUE LETTER FINAL V;Lo;0;L;;;;;N;;;;;
19C2;NEW TAI LUE LETTER FINAL NG;Lo;0;L;;;;;N;;;;;
19C3;NEW TAI LUE LETTER FINAL N;Lo;0;L;;;;;N;;;;;
@@ -5568,8 +5797,8 @@
19C5;NEW TAI LUE LETTER FINAL K;Lo;0;L;;;;;N;;;;;
19C6;NEW TAI LUE LETTER FINAL D;Lo;0;L;;;;;N;;;;;
19C7;NEW TAI LUE LETTER FINAL B;Lo;0;L;;;;;N;;;;;
-19C8;NEW TAI LUE TONE MARK-1;Mc;0;L;;;;;N;;;;;
-19C9;NEW TAI LUE TONE MARK-2;Mc;0;L;;;;;N;;;;;
+19C8;NEW TAI LUE TONE MARK-1;Lo;0;L;;;;;N;;;;;
+19C9;NEW TAI LUE TONE MARK-2;Lo;0;L;;;;;N;;;;;
19D0;NEW TAI LUE DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
19D1;NEW TAI LUE DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
19D2;NEW TAI LUE DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
@@ -5580,9 +5809,9 @@
19D7;NEW TAI LUE DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
19D8;NEW TAI LUE DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
19D9;NEW TAI LUE DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
-19DA;NEW TAI LUE THAM DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
-19DE;NEW TAI LUE SIGN LAE;Po;0;ON;;;;;N;;;;;
-19DF;NEW TAI LUE SIGN LAEV;Po;0;ON;;;;;N;;;;;
+19DA;NEW TAI LUE THAM DIGIT ONE;No;0;L;;;1;1;N;;;;;
+19DE;NEW TAI LUE SIGN LAE;So;0;ON;;;;;N;;;;;
+19DF;NEW TAI LUE SIGN LAEV;So;0;ON;;;;;N;;;;;
19E0;KHMER SYMBOL PATHAMASAT;So;0;ON;;;;;N;;;;;
19E1;KHMER SYMBOL MUOY KOET;So;0;ON;;;;;N;;;;;
19E2;KHMER SYMBOL PII KOET;So;0;ON;;;;;N;;;;;
@@ -5642,7 +5871,7 @@
1A18;BUGINESE VOWEL SIGN U;Mn;220;NSM;;;;;N;;;;;
1A19;BUGINESE VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
1A1A;BUGINESE VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
-1A1B;BUGINESE VOWEL SIGN AE;Mc;0;L;;;;;N;;;;;
+1A1B;BUGINESE VOWEL SIGN AE;Mn;0;NSM;;;;;N;;;;;
1A1E;BUGINESE PALLAWA;Po;0;L;;;;;N;;;;;
1A1F;BUGINESE END OF SECTION;Po;0;L;;;;;N;;;;;
1A20;TAI THAM LETTER HIGH KA;Lo;0;L;;;;;N;;;;;
@@ -5772,6 +6001,21 @@
1AAB;TAI THAM SIGN SATKAANKUU;Po;0;L;;;;;N;;;;;
1AAC;TAI THAM SIGN HANG;Po;0;L;;;;;N;;;;;
1AAD;TAI THAM SIGN CAANG;Po;0;L;;;;;N;;;;;
+1AB0;COMBINING DOUBLED CIRCUMFLEX ACCENT;Mn;230;NSM;;;;;N;;;;;
+1AB1;COMBINING DIAERESIS-RING;Mn;230;NSM;;;;;N;;;;;
+1AB2;COMBINING INFINITY;Mn;230;NSM;;;;;N;;;;;
+1AB3;COMBINING DOWNWARDS ARROW;Mn;230;NSM;;;;;N;;;;;
+1AB4;COMBINING TRIPLE DOT;Mn;230;NSM;;;;;N;;;;;
+1AB5;COMBINING X-X BELOW;Mn;220;NSM;;;;;N;;;;;
+1AB6;COMBINING WIGGLY LINE BELOW;Mn;220;NSM;;;;;N;;;;;
+1AB7;COMBINING OPEN MARK BELOW;Mn;220;NSM;;;;;N;;;;;
+1AB8;COMBINING DOUBLE OPEN MARK BELOW;Mn;220;NSM;;;;;N;;;;;
+1AB9;COMBINING LIGHT CENTRALIZATION STROKE BELOW;Mn;220;NSM;;;;;N;;;;;
+1ABA;COMBINING STRONG CENTRALIZATION STROKE BELOW;Mn;220;NSM;;;;;N;;;;;
+1ABB;COMBINING PARENTHESES ABOVE;Mn;230;NSM;;;;;N;;;;;
+1ABC;COMBINING DOUBLE PARENTHESES ABOVE;Mn;230;NSM;;;;;N;;;;;
+1ABD;COMBINING PARENTHESES BELOW;Mn;220;NSM;;;;;N;;;;;
+1ABE;COMBINING PARENTHESES OVERLAY;Me;0;NSM;;;;;N;;;;;
1B00;BALINESE SIGN ULU RICEM;Mn;0;NSM;;;;;N;;;;;
1B01;BALINESE SIGN ULU CANDRA;Mn;0;NSM;;;;;N;;;;;
1B02;BALINESE SIGN CECEK;Mn;0;NSM;;;;;N;;;;;
@@ -5936,6 +6180,9 @@
1BA8;SUNDANESE VOWEL SIGN PAMEPET;Mn;0;NSM;;;;;N;;;;;
1BA9;SUNDANESE VOWEL SIGN PANEULEUNG;Mn;0;NSM;;;;;N;;;;;
1BAA;SUNDANESE SIGN PAMAAEH;Mc;9;L;;;;;N;;;;;
+1BAB;SUNDANESE SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+1BAC;SUNDANESE CONSONANT SIGN PASANGAN MA;Mn;0;NSM;;;;;N;;;;;
+1BAD;SUNDANESE CONSONANT SIGN PASANGAN WA;Mn;0;NSM;;;;;N;;;;;
1BAE;SUNDANESE LETTER KHA;Lo;0;L;;;;;N;;;;;
1BAF;SUNDANESE LETTER SYA;Lo;0;L;;;;;N;;;;;
1BB0;SUNDANESE DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
@@ -5948,6 +6195,68 @@
1BB7;SUNDANESE DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
1BB8;SUNDANESE DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
1BB9;SUNDANESE DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+1BBA;SUNDANESE AVAGRAHA;Lo;0;L;;;;;N;;;;;
+1BBB;SUNDANESE LETTER REU;Lo;0;L;;;;;N;;;;;
+1BBC;SUNDANESE LETTER LEU;Lo;0;L;;;;;N;;;;;
+1BBD;SUNDANESE LETTER BHA;Lo;0;L;;;;;N;;;;;
+1BBE;SUNDANESE LETTER FINAL K;Lo;0;L;;;;;N;;;;;
+1BBF;SUNDANESE LETTER FINAL M;Lo;0;L;;;;;N;;;;;
+1BC0;BATAK LETTER A;Lo;0;L;;;;;N;;;;;
+1BC1;BATAK LETTER SIMALUNGUN A;Lo;0;L;;;;;N;;;;;
+1BC2;BATAK LETTER HA;Lo;0;L;;;;;N;;;;;
+1BC3;BATAK LETTER SIMALUNGUN HA;Lo;0;L;;;;;N;;;;;
+1BC4;BATAK LETTER MANDAILING HA;Lo;0;L;;;;;N;;;;;
+1BC5;BATAK LETTER BA;Lo;0;L;;;;;N;;;;;
+1BC6;BATAK LETTER KARO BA;Lo;0;L;;;;;N;;;;;
+1BC7;BATAK LETTER PA;Lo;0;L;;;;;N;;;;;
+1BC8;BATAK LETTER SIMALUNGUN PA;Lo;0;L;;;;;N;;;;;
+1BC9;BATAK LETTER NA;Lo;0;L;;;;;N;;;;;
+1BCA;BATAK LETTER MANDAILING NA;Lo;0;L;;;;;N;;;;;
+1BCB;BATAK LETTER WA;Lo;0;L;;;;;N;;;;;
+1BCC;BATAK LETTER SIMALUNGUN WA;Lo;0;L;;;;;N;;;;;
+1BCD;BATAK LETTER PAKPAK WA;Lo;0;L;;;;;N;;;;;
+1BCE;BATAK LETTER GA;Lo;0;L;;;;;N;;;;;
+1BCF;BATAK LETTER SIMALUNGUN GA;Lo;0;L;;;;;N;;;;;
+1BD0;BATAK LETTER JA;Lo;0;L;;;;;N;;;;;
+1BD1;BATAK LETTER DA;Lo;0;L;;;;;N;;;;;
+1BD2;BATAK LETTER RA;Lo;0;L;;;;;N;;;;;
+1BD3;BATAK LETTER SIMALUNGUN RA;Lo;0;L;;;;;N;;;;;
+1BD4;BATAK LETTER MA;Lo;0;L;;;;;N;;;;;
+1BD5;BATAK LETTER SIMALUNGUN MA;Lo;0;L;;;;;N;;;;;
+1BD6;BATAK LETTER SOUTHERN TA;Lo;0;L;;;;;N;;;;;
+1BD7;BATAK LETTER NORTHERN TA;Lo;0;L;;;;;N;;;;;
+1BD8;BATAK LETTER SA;Lo;0;L;;;;;N;;;;;
+1BD9;BATAK LETTER SIMALUNGUN SA;Lo;0;L;;;;;N;;;;;
+1BDA;BATAK LETTER MANDAILING SA;Lo;0;L;;;;;N;;;;;
+1BDB;BATAK LETTER YA;Lo;0;L;;;;;N;;;;;
+1BDC;BATAK LETTER SIMALUNGUN YA;Lo;0;L;;;;;N;;;;;
+1BDD;BATAK LETTER NGA;Lo;0;L;;;;;N;;;;;
+1BDE;BATAK LETTER LA;Lo;0;L;;;;;N;;;;;
+1BDF;BATAK LETTER SIMALUNGUN LA;Lo;0;L;;;;;N;;;;;
+1BE0;BATAK LETTER NYA;Lo;0;L;;;;;N;;;;;
+1BE1;BATAK LETTER CA;Lo;0;L;;;;;N;;;;;
+1BE2;BATAK LETTER NDA;Lo;0;L;;;;;N;;;;;
+1BE3;BATAK LETTER MBA;Lo;0;L;;;;;N;;;;;
+1BE4;BATAK LETTER I;Lo;0;L;;;;;N;;;;;
+1BE5;BATAK LETTER U;Lo;0;L;;;;;N;;;;;
+1BE6;BATAK SIGN TOMPI;Mn;7;NSM;;;;;N;;;;;
+1BE7;BATAK VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
+1BE8;BATAK VOWEL SIGN PAKPAK E;Mn;0;NSM;;;;;N;;;;;
+1BE9;BATAK VOWEL SIGN EE;Mn;0;NSM;;;;;N;;;;;
+1BEA;BATAK VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+1BEB;BATAK VOWEL SIGN KARO I;Mc;0;L;;;;;N;;;;;
+1BEC;BATAK VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
+1BED;BATAK VOWEL SIGN KARO O;Mn;0;NSM;;;;;N;;;;;
+1BEE;BATAK VOWEL SIGN U;Mc;0;L;;;;;N;;;;;
+1BEF;BATAK VOWEL SIGN U FOR SIMALUNGUN SA;Mn;0;NSM;;;;;N;;;;;
+1BF0;BATAK CONSONANT SIGN NG;Mn;0;NSM;;;;;N;;;;;
+1BF1;BATAK CONSONANT SIGN H;Mn;0;NSM;;;;;N;;;;;
+1BF2;BATAK PANGOLAT;Mc;9;L;;;;;N;;;;;
+1BF3;BATAK PANONGONAN;Mc;9;L;;;;;N;;;;;
+1BFC;BATAK SYMBOL BINDU NA METEK;Po;0;L;;;;;N;;;;;
+1BFD;BATAK SYMBOL BINDU PINARBORAS;Po;0;L;;;;;N;;;;;
+1BFE;BATAK SYMBOL BINDU JUDUL;Po;0;L;;;;;N;;;;;
+1BFF;BATAK SYMBOL BINDU PANGOLAT;Po;0;L;;;;;N;;;;;
1C00;LEPCHA LETTER KA;Lo;0;L;;;;;N;;;;;
1C01;LEPCHA LETTER KLA;Lo;0;L;;;;;N;;;;;
1C02;LEPCHA LETTER KHA;Lo;0;L;;;;;N;;;;;
@@ -6070,6 +6379,23 @@
1C7D;OL CHIKI AHAD;Lm;0;L;;;;;N;;;;;
1C7E;OL CHIKI PUNCTUATION MUCAAD;Po;0;L;;;;;N;;;;;
1C7F;OL CHIKI PUNCTUATION DOUBLE MUCAAD;Po;0;L;;;;;N;;;;;
+1C80;CYRILLIC SMALL LETTER ROUNDED VE;Ll;0;L;;;;;N;;;0412;;0412
+1C81;CYRILLIC SMALL LETTER LONG-LEGGED DE;Ll;0;L;;;;;N;;;0414;;0414
+1C82;CYRILLIC SMALL LETTER NARROW O;Ll;0;L;;;;;N;;;041E;;041E
+1C83;CYRILLIC SMALL LETTER WIDE ES;Ll;0;L;;;;;N;;;0421;;0421
+1C84;CYRILLIC SMALL LETTER TALL TE;Ll;0;L;;;;;N;;;0422;;0422
+1C85;CYRILLIC SMALL LETTER THREE-LEGGED TE;Ll;0;L;;;;;N;;;0422;;0422
+1C86;CYRILLIC SMALL LETTER TALL HARD SIGN;Ll;0;L;;;;;N;;;042A;;042A
+1C87;CYRILLIC SMALL LETTER TALL YAT;Ll;0;L;;;;;N;;;0462;;0462
+1C88;CYRILLIC SMALL LETTER UNBLENDED UK;Ll;0;L;;;;;N;;;A64A;;A64A
+1CC0;SUNDANESE PUNCTUATION BINDU SURYA;Po;0;L;;;;;N;;;;;
+1CC1;SUNDANESE PUNCTUATION BINDU PANGLONG;Po;0;L;;;;;N;;;;;
+1CC2;SUNDANESE PUNCTUATION BINDU PURNAMA;Po;0;L;;;;;N;;;;;
+1CC3;SUNDANESE PUNCTUATION BINDU CAKRA;Po;0;L;;;;;N;;;;;
+1CC4;SUNDANESE PUNCTUATION BINDU LEU SATANGA;Po;0;L;;;;;N;;;;;
+1CC5;SUNDANESE PUNCTUATION BINDU KA SATANGA;Po;0;L;;;;;N;;;;;
+1CC6;SUNDANESE PUNCTUATION BINDU DA SATANGA;Po;0;L;;;;;N;;;;;
+1CC7;SUNDANESE PUNCTUATION BINDU BA SATANGA;Po;0;L;;;;;N;;;;;
1CD0;VEDIC TONE KARSHANA;Mn;230;NSM;;;;;N;;;;;
1CD1;VEDIC TONE SHARA;Mn;230;NSM;;;;;N;;;;;
1CD2;VEDIC TONE PRENKHA;Mn;230;NSM;;;;;N;;;;;
@@ -6105,6 +6431,13 @@
1CF0;VEDIC SIGN RTHANG LONG ANUSVARA;Lo;0;L;;;;;N;;;;;
1CF1;VEDIC SIGN ANUSVARA UBHAYATO MUKHA;Lo;0;L;;;;;N;;;;;
1CF2;VEDIC SIGN ARDHAVISARGA;Mc;0;L;;;;;N;;;;;
+1CF3;VEDIC SIGN ROTATED ARDHAVISARGA;Mc;0;L;;;;;N;;;;;
+1CF4;VEDIC TONE CANDRA ABOVE;Mn;230;NSM;;;;;N;;;;;
+1CF5;VEDIC SIGN JIHVAMULIYA;Lo;0;L;;;;;N;;;;;
+1CF6;VEDIC SIGN UPADHMANIYA;Lo;0;L;;;;;N;;;;;
+1CF7;VEDIC SIGN ATIKRAMA;Mc;0;L;;;;;N;;;;;
+1CF8;VEDIC TONE RING ABOVE;Mn;230;NSM;;;;;N;;;;;
+1CF9;VEDIC TONE DOUBLE RING ABOVE;Mn;230;NSM;;;;;N;;;;;
1D00;LATIN LETTER SMALL CAPITAL A;Ll;0;L;;;;;N;;;;;
1D01;LATIN LETTER SMALL CAPITAL AE;Ll;0;L;;;;;N;;;;;
1D02;LATIN SMALL LETTER TURNED AE;Ll;0;L;;;;;N;;;;;
@@ -6203,15 +6536,15 @@
1D5F;MODIFIER LETTER SMALL DELTA;Lm;0;L;<super> 03B4;;;;N;;;;;
1D60;MODIFIER LETTER SMALL GREEK PHI;Lm;0;L;<super> 03C6;;;;N;;;;;
1D61;MODIFIER LETTER SMALL CHI;Lm;0;L;<super> 03C7;;;;N;;;;;
-1D62;LATIN SUBSCRIPT SMALL LETTER I;Ll;0;L;<sub> 0069;;;;N;;;;;
-1D63;LATIN SUBSCRIPT SMALL LETTER R;Ll;0;L;<sub> 0072;;;;N;;;;;
-1D64;LATIN SUBSCRIPT SMALL LETTER U;Ll;0;L;<sub> 0075;;;;N;;;;;
-1D65;LATIN SUBSCRIPT SMALL LETTER V;Ll;0;L;<sub> 0076;;;;N;;;;;
-1D66;GREEK SUBSCRIPT SMALL LETTER BETA;Ll;0;L;<sub> 03B2;;;;N;;;;;
-1D67;GREEK SUBSCRIPT SMALL LETTER GAMMA;Ll;0;L;<sub> 03B3;;;;N;;;;;
-1D68;GREEK SUBSCRIPT SMALL LETTER RHO;Ll;0;L;<sub> 03C1;;;;N;;;;;
-1D69;GREEK SUBSCRIPT SMALL LETTER PHI;Ll;0;L;<sub> 03C6;;;;N;;;;;
-1D6A;GREEK SUBSCRIPT SMALL LETTER CHI;Ll;0;L;<sub> 03C7;;;;N;;;;;
+1D62;LATIN SUBSCRIPT SMALL LETTER I;Lm;0;L;<sub> 0069;;;;N;;;;;
+1D63;LATIN SUBSCRIPT SMALL LETTER R;Lm;0;L;<sub> 0072;;;;N;;;;;
+1D64;LATIN SUBSCRIPT SMALL LETTER U;Lm;0;L;<sub> 0075;;;;N;;;;;
+1D65;LATIN SUBSCRIPT SMALL LETTER V;Lm;0;L;<sub> 0076;;;;N;;;;;
+1D66;GREEK SUBSCRIPT SMALL LETTER BETA;Lm;0;L;<sub> 03B2;;;;N;;;;;
+1D67;GREEK SUBSCRIPT SMALL LETTER GAMMA;Lm;0;L;<sub> 03B3;;;;N;;;;;
+1D68;GREEK SUBSCRIPT SMALL LETTER RHO;Lm;0;L;<sub> 03C1;;;;N;;;;;
+1D69;GREEK SUBSCRIPT SMALL LETTER PHI;Lm;0;L;<sub> 03C6;;;;N;;;;;
+1D6A;GREEK SUBSCRIPT SMALL LETTER CHI;Lm;0;L;<sub> 03C7;;;;N;;;;;
1D6B;LATIN SMALL LETTER UE;Ll;0;L;;;;;N;;;;;
1D6C;LATIN SMALL LETTER B WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;;
1D6D;LATIN SMALL LETTER D WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;;
@@ -6336,6 +6669,27 @@
1DE4;COMBINING LATIN SMALL LETTER S;Mn;230;NSM;;;;;N;;;;;
1DE5;COMBINING LATIN SMALL LETTER LONG S;Mn;230;NSM;;;;;N;;;;;
1DE6;COMBINING LATIN SMALL LETTER Z;Mn;230;NSM;;;;;N;;;;;
+1DE7;COMBINING LATIN SMALL LETTER ALPHA;Mn;230;NSM;;;;;N;;;;;
+1DE8;COMBINING LATIN SMALL LETTER B;Mn;230;NSM;;;;;N;;;;;
+1DE9;COMBINING LATIN SMALL LETTER BETA;Mn;230;NSM;;;;;N;;;;;
+1DEA;COMBINING LATIN SMALL LETTER SCHWA;Mn;230;NSM;;;;;N;;;;;
+1DEB;COMBINING LATIN SMALL LETTER F;Mn;230;NSM;;;;;N;;;;;
+1DEC;COMBINING LATIN SMALL LETTER L WITH DOUBLE MIDDLE TILDE;Mn;230;NSM;;;;;N;;;;;
+1DED;COMBINING LATIN SMALL LETTER O WITH LIGHT CENTRALIZATION STROKE;Mn;230;NSM;;;;;N;;;;;
+1DEE;COMBINING LATIN SMALL LETTER P;Mn;230;NSM;;;;;N;;;;;
+1DEF;COMBINING LATIN SMALL LETTER ESH;Mn;230;NSM;;;;;N;;;;;
+1DF0;COMBINING LATIN SMALL LETTER U WITH LIGHT CENTRALIZATION STROKE;Mn;230;NSM;;;;;N;;;;;
+1DF1;COMBINING LATIN SMALL LETTER W;Mn;230;NSM;;;;;N;;;;;
+1DF2;COMBINING LATIN SMALL LETTER A WITH DIAERESIS;Mn;230;NSM;;;;;N;;;;;
+1DF3;COMBINING LATIN SMALL LETTER O WITH DIAERESIS;Mn;230;NSM;;;;;N;;;;;
+1DF4;COMBINING LATIN SMALL LETTER U WITH DIAERESIS;Mn;230;NSM;;;;;N;;;;;
+1DF5;COMBINING UP TACK ABOVE;Mn;230;NSM;;;;;N;;;;;
+1DF6;COMBINING KAVYKA ABOVE RIGHT;Mn;232;NSM;;;;;N;;;;;
+1DF7;COMBINING KAVYKA ABOVE LEFT;Mn;228;NSM;;;;;N;;;;;
+1DF8;COMBINING DOT ABOVE LEFT;Mn;228;NSM;;;;;N;;;;;
+1DF9;COMBINING WIDE INVERTED BRIDGE BELOW;Mn;220;NSM;;;;;N;;;;;
+1DFB;COMBINING DELETION MARK;Mn;230;NSM;;;;;N;;;;;
+1DFC;COMBINING DOUBLE INVERTED BREVE BELOW;Mn;233;NSM;;;;;N;;;;;
1DFD;COMBINING ALMOST EQUAL TO BELOW;Mn;220;NSM;;;;;N;;;;;
1DFE;COMBINING LEFT ARROWHEAD ABOVE;Mn;230;NSM;;;;;N;;;;;
1DFF;COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW;Mn;220;NSM;;;;;N;;;;;
@@ -6929,6 +7283,10 @@
2062;INVISIBLE TIMES;Cf;0;BN;;;;;N;;;;;
2063;INVISIBLE SEPARATOR;Cf;0;BN;;;;;N;;;;;
2064;INVISIBLE PLUS;Cf;0;BN;;;;;N;;;;;
+2066;LEFT-TO-RIGHT ISOLATE;Cf;0;LRI;;;;;N;;;;;
+2067;RIGHT-TO-LEFT ISOLATE;Cf;0;RLI;;;;;N;;;;;
+2068;FIRST STRONG ISOLATE;Cf;0;FSI;;;;;N;;;;;
+2069;POP DIRECTIONAL ISOLATE;Cf;0;PDI;;;;;N;;;;;
206A;INHIBIT SYMMETRIC SWAPPING;Cf;0;BN;;;;;N;;;;;
206B;ACTIVATE SYMMETRIC SWAPPING;Cf;0;BN;;;;;N;;;;;
206C;INHIBIT ARABIC FORM SHAPING;Cf;0;BN;;;;;N;;;;;
@@ -6969,6 +7327,14 @@
2092;LATIN SUBSCRIPT SMALL LETTER O;Lm;0;L;<sub> 006F;;;;N;;;;;
2093;LATIN SUBSCRIPT SMALL LETTER X;Lm;0;L;<sub> 0078;;;;N;;;;;
2094;LATIN SUBSCRIPT SMALL LETTER SCHWA;Lm;0;L;<sub> 0259;;;;N;;;;;
+2095;LATIN SUBSCRIPT SMALL LETTER H;Lm;0;L;<sub> 0068;;;;N;;;;;
+2096;LATIN SUBSCRIPT SMALL LETTER K;Lm;0;L;<sub> 006B;;;;N;;;;;
+2097;LATIN SUBSCRIPT SMALL LETTER L;Lm;0;L;<sub> 006C;;;;N;;;;;
+2098;LATIN SUBSCRIPT SMALL LETTER M;Lm;0;L;<sub> 006D;;;;N;;;;;
+2099;LATIN SUBSCRIPT SMALL LETTER N;Lm;0;L;<sub> 006E;;;;N;;;;;
+209A;LATIN SUBSCRIPT SMALL LETTER P;Lm;0;L;<sub> 0070;;;;N;;;;;
+209B;LATIN SUBSCRIPT SMALL LETTER S;Lm;0;L;<sub> 0073;;;;N;;;;;
+209C;LATIN SUBSCRIPT SMALL LETTER T;Lm;0;L;<sub> 0074;;;;N;;;;;
20A0;EURO-CURRENCY SIGN;Sc;0;ET;;;;;N;;;;;
20A1;COLON SIGN;Sc;0;ET;;;;;N;;;;;
20A2;CRUZEIRO SIGN;Sc;0;ET;;;;;N;;;;;
@@ -6994,6 +7360,13 @@
20B6;LIVRE TOURNOIS SIGN;Sc;0;ET;;;;;N;;;;;
20B7;SPESMILO SIGN;Sc;0;ET;;;;;N;;;;;
20B8;TENGE SIGN;Sc;0;ET;;;;;N;;;;;
+20B9;INDIAN RUPEE SIGN;Sc;0;ET;;;;;N;;;;;
+20BA;TURKISH LIRA SIGN;Sc;0;ET;;;;;N;;;;;
+20BB;NORDIC MARK SIGN;Sc;0;ET;;;;;N;;;;;
+20BC;MANAT SIGN;Sc;0;ET;;;;;N;;;;;
+20BD;RUBLE SIGN;Sc;0;ET;;;;;N;;;;;
+20BE;LARI SIGN;Sc;0;ET;;;;;N;;;;;
+20BF;BITCOIN SIGN;Sc;0;ET;;;;;N;;;;;
20D0;COMBINING LEFT HARPOON ABOVE;Mn;230;NSM;;;;;N;NON-SPACING LEFT HARPOON ABOVE;;;;
20D1;COMBINING RIGHT HARPOON ABOVE;Mn;230;NSM;;;;;N;NON-SPACING RIGHT HARPOON ABOVE;;;;
20D2;COMBINING LONG VERTICAL LINE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING LONG VERTICAL BAR OVERLAY;;;;
@@ -7051,7 +7424,7 @@
2115;DOUBLE-STRUCK CAPITAL N;Lu;0;L;<font> 004E;;;;N;DOUBLE-STRUCK N;;;;
2116;NUMERO SIGN;So;0;ON;<compat> 004E 006F;;;;N;NUMERO;;;;
2117;SOUND RECORDING COPYRIGHT;So;0;ON;;;;;N;;;;;
-2118;SCRIPT CAPITAL P;So;0;ON;;;;;N;SCRIPT P;;;;
+2118;SCRIPT CAPITAL P;Sm;0;ON;;;;;N;SCRIPT P;;;;
2119;DOUBLE-STRUCK CAPITAL P;Lu;0;L;<font> 0050;;;;N;DOUBLE-STRUCK P;;;;
211A;DOUBLE-STRUCK CAPITAL Q;Lu;0;L;<font> 0051;;;;N;DOUBLE-STRUCK Q;;;;
211B;SCRIPT CAPITAL R;Lu;0;L;<font> 0052;;;;N;SCRIPT R;;;;
@@ -7165,6 +7538,8 @@
2187;ROMAN NUMERAL FIFTY THOUSAND;Nl;0;L;;;;50000;N;;;;;
2188;ROMAN NUMERAL ONE HUNDRED THOUSAND;Nl;0;L;;;;100000;N;;;;;
2189;VULGAR FRACTION ZERO THIRDS;No;0;ON;<fraction> 0030 2044 0033;;;0;N;;;;;
+218A;TURNED DIGIT TWO;So;0;ON;;;;;N;;;;;
+218B;TURNED DIGIT THREE;So;0;ON;;;;;N;;;;;
2190;LEFTWARDS ARROW;Sm;0;ON;;;;;N;LEFT ARROW;;;;
2191;UPWARDS ARROW;Sm;0;ON;;;;;N;UP ARROW;;;;
2192;RIGHTWARDS ARROW;Sm;0;ON;;;;;N;RIGHT ARROW;;;;
@@ -7541,10 +7916,10 @@
2305;PROJECTIVE;So;0;ON;;;;;N;;;;;
2306;PERSPECTIVE;So;0;ON;;;;;N;;;;;
2307;WAVY LINE;So;0;ON;;;;;N;;;;;
-2308;LEFT CEILING;Sm;0;ON;;;;;Y;;;;;
-2309;RIGHT CEILING;Sm;0;ON;;;;;Y;;;;;
-230A;LEFT FLOOR;Sm;0;ON;;;;;Y;;;;;
-230B;RIGHT FLOOR;Sm;0;ON;;;;;Y;;;;;
+2308;LEFT CEILING;Ps;0;ON;;;;;Y;;;;;
+2309;RIGHT CEILING;Pe;0;ON;;;;;Y;;;;;
+230A;LEFT FLOOR;Ps;0;ON;;;;;Y;;;;;
+230B;RIGHT FLOOR;Pe;0;ON;;;;;Y;;;;;
230C;BOTTOM RIGHT CROP;So;0;ON;;;;;N;;;;;
230D;BOTTOM LEFT CROP;So;0;ON;;;;;N;;;;;
230E;TOP RIGHT CROP;So;0;ON;;;;;N;;;;;
@@ -7766,6 +8141,29 @@
23E6;AC CURRENT;So;0;ON;;;;;N;;;;;
23E7;ELECTRICAL INTERSECTION;So;0;ON;;;;;N;;;;;
23E8;DECIMAL EXPONENT SYMBOL;So;0;ON;;;;;N;;;;;
+23E9;BLACK RIGHT-POINTING DOUBLE TRIANGLE;So;0;ON;;;;;N;;;;;
+23EA;BLACK LEFT-POINTING DOUBLE TRIANGLE;So;0;ON;;;;;N;;;;;
+23EB;BLACK UP-POINTING DOUBLE TRIANGLE;So;0;ON;;;;;N;;;;;
+23EC;BLACK DOWN-POINTING DOUBLE TRIANGLE;So;0;ON;;;;;N;;;;;
+23ED;BLACK RIGHT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR;So;0;ON;;;;;N;;;;;
+23EE;BLACK LEFT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR;So;0;ON;;;;;N;;;;;
+23EF;BLACK RIGHT-POINTING TRIANGLE WITH DOUBLE VERTICAL BAR;So;0;ON;;;;;N;;;;;
+23F0;ALARM CLOCK;So;0;ON;;;;;N;;;;;
+23F1;STOPWATCH;So;0;ON;;;;;N;;;;;
+23F2;TIMER CLOCK;So;0;ON;;;;;N;;;;;
+23F3;HOURGLASS WITH FLOWING SAND;So;0;ON;;;;;N;;;;;
+23F4;BLACK MEDIUM LEFT-POINTING TRIANGLE;So;0;ON;;;;;N;;;;;
+23F5;BLACK MEDIUM RIGHT-POINTING TRIANGLE;So;0;ON;;;;;N;;;;;
+23F6;BLACK MEDIUM UP-POINTING TRIANGLE;So;0;ON;;;;;N;;;;;
+23F7;BLACK MEDIUM DOWN-POINTING TRIANGLE;So;0;ON;;;;;N;;;;;
+23F8;DOUBLE VERTICAL BAR;So;0;ON;;;;;N;;;;;
+23F9;BLACK SQUARE FOR STOP;So;0;ON;;;;;N;;;;;
+23FA;BLACK CIRCLE FOR RECORD;So;0;ON;;;;;N;;;;;
+23FB;POWER SYMBOL;So;0;ON;;;;;N;;;;;
+23FC;POWER ON-OFF SYMBOL;So;0;ON;;;;;N;;;;;
+23FD;POWER ON SYMBOL;So;0;ON;;;;;N;;;;;
+23FE;POWER SLEEP SYMBOL;So;0;ON;;;;;N;;;;;
+23FF;OBSERVER EYE SYMBOL;So;0;ON;;;;;N;;;;;
2400;SYMBOL FOR NULL;So;0;ON;;;;;N;GRAPHIC FOR NULL;;;;
2401;SYMBOL FOR START OF HEADING;So;0;ON;;;;;N;GRAPHIC FOR START OF HEADING;;;;
2402;SYMBOL FOR START OF TEXT;So;0;ON;;;;;N;GRAPHIC FOR START OF TEXT;;;;
@@ -8438,6 +8836,7 @@
26CB;WHITE DIAMOND IN SQUARE;So;0;ON;;;;;N;;;;;
26CC;CROSSING LANES;So;0;ON;;;;;N;;;;;
26CD;DISABLED CAR;So;0;ON;;;;;N;;;;;
+26CE;OPHIUCHUS;So;0;ON;;;;;N;;;;;
26CF;PICK;So;0;ON;;;;;N;;;;;
26D0;CAR SLIDING;So;0;ON;;;;;N;;;;;
26D1;HELMET WITH WHITE CROSS;So;0;ON;;;;;N;;;;;
@@ -8457,7 +8856,12 @@
26DF;BLACK TRUCK;So;0;ON;;;;;N;;;;;
26E0;RESTRICTED LEFT ENTRY-1;So;0;ON;;;;;N;;;;;
26E1;RESTRICTED LEFT ENTRY-2;So;0;ON;;;;;N;;;;;
+26E2;ASTRONOMICAL SYMBOL FOR URANUS;So;0;ON;;;;;N;;;;;
26E3;HEAVY CIRCLE WITH STROKE AND TWO DOTS ABOVE;So;0;ON;;;;;N;;;;;
+26E4;PENTAGRAM;So;0;ON;;;;;N;;;;;
+26E5;RIGHT-HANDED INTERLACED PENTAGRAM;So;0;ON;;;;;N;;;;;
+26E6;LEFT-HANDED INTERLACED PENTAGRAM;So;0;ON;;;;;N;;;;;
+26E7;INVERTED PENTAGRAM;So;0;ON;;;;;N;;;;;
26E8;BLACK CROSS ON SHIELD;So;0;ON;;;;;N;;;;;
26E9;SHINTO SHRINE;So;0;ON;;;;;N;;;;;
26EA;CHURCH;So;0;ON;;;;;N;;;;;
@@ -8482,14 +8886,18 @@
26FD;FUEL PUMP;So;0;ON;;;;;N;;;;;
26FE;CUP ON BLACK SQUARE;So;0;ON;;;;;N;;;;;
26FF;WHITE FLAG WITH HORIZONTAL MIDDLE BLACK STRIPE;So;0;ON;;;;;N;;;;;
+2700;BLACK SAFETY SCISSORS;So;0;ON;;;;;N;;;;;
2701;UPPER BLADE SCISSORS;So;0;ON;;;;;N;;;;;
2702;BLACK SCISSORS;So;0;ON;;;;;N;;;;;
2703;LOWER BLADE SCISSORS;So;0;ON;;;;;N;;;;;
2704;WHITE SCISSORS;So;0;ON;;;;;N;;;;;
+2705;WHITE HEAVY CHECK MARK;So;0;ON;;;;;N;;;;;
2706;TELEPHONE LOCATION SIGN;So;0;ON;;;;;N;;;;;
2707;TAPE DRIVE;So;0;ON;;;;;N;;;;;
2708;AIRPLANE;So;0;ON;;;;;N;;;;;
2709;ENVELOPE;So;0;ON;;;;;N;;;;;
+270A;RAISED FIST;So;0;ON;;;;;N;;;;;
+270B;RAISED HAND;So;0;ON;;;;;N;;;;;
270C;VICTORY HAND;So;0;ON;;;;;N;;;;;
270D;WRITING HAND;So;0;ON;;;;;N;;;;;
270E;LOWER RIGHT PENCIL;So;0;ON;;;;;N;;;;;
@@ -8518,6 +8926,7 @@
2725;FOUR CLUB-SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
2726;BLACK FOUR POINTED STAR;So;0;ON;;;;;N;;;;;
2727;WHITE FOUR POINTED STAR;So;0;ON;;;;;N;;;;;
+2728;SPARKLES;So;0;ON;;;;;N;;;;;
2729;STRESS OUTLINED WHITE STAR;So;0;ON;;;;;N;;;;;
272A;CIRCLED WHITE STAR;So;0;ON;;;;;N;;;;;
272B;OPEN CENTRE BLACK STAR;So;0;ON;;;;;N;OPEN CENTER BLACK STAR;;;;
@@ -8553,11 +8962,16 @@
2749;BALLOON-SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
274A;EIGHT TEARDROP-SPOKED PROPELLER ASTERISK;So;0;ON;;;;;N;;;;;
274B;HEAVY EIGHT TEARDROP-SPOKED PROPELLER ASTERISK;So;0;ON;;;;;N;;;;;
+274C;CROSS MARK;So;0;ON;;;;;N;;;;;
274D;SHADOWED WHITE CIRCLE;So;0;ON;;;;;N;;;;;
+274E;NEGATIVE SQUARED CROSS MARK;So;0;ON;;;;;N;;;;;
274F;LOWER RIGHT DROP-SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;;
2750;UPPER RIGHT DROP-SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;;
2751;LOWER RIGHT SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;;
2752;UPPER RIGHT SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;;
+2753;BLACK QUESTION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
+2754;WHITE QUESTION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
+2755;WHITE EXCLAMATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
2756;BLACK DIAMOND MINUS WHITE X;So;0;ON;;;;;N;;;;;
2757;HEAVY EXCLAMATION MARK SYMBOL;So;0;ON;;;;;N;;;;;
2758;LIGHT VERTICAL BAR;So;0;ON;;;;;N;;;;;
@@ -8567,6 +8981,8 @@
275C;HEAVY SINGLE COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
275D;HEAVY DOUBLE TURNED COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
275E;HEAVY DOUBLE COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
+275F;HEAVY LOW SINGLE COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
+2760;HEAVY LOW DOUBLE COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
2761;CURVED STEM PARAGRAPH SIGN ORNAMENT;So;0;ON;;;;;N;;;;;
2762;HEAVY EXCLAMATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
2763;HEAVY HEART EXCLAMATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
@@ -8619,6 +9035,9 @@
2792;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT NINE;No;0;ON;;;9;9;N;INVERSE CIRCLED SANS-SERIF DIGIT NINE;;;;
2793;DINGBAT NEGATIVE CIRCLED SANS-SERIF NUMBER TEN;No;0;ON;;;;10;N;INVERSE CIRCLED SANS-SERIF NUMBER TEN;;;;
2794;HEAVY WIDE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY WIDE-HEADED RIGHT ARROW;;;;
+2795;HEAVY PLUS SIGN;So;0;ON;;;;;N;;;;;
+2796;HEAVY MINUS SIGN;So;0;ON;;;;;N;;;;;
+2797;HEAVY DIVISION SIGN;So;0;ON;;;;;N;;;;;
2798;HEAVY SOUTH EAST ARROW;So;0;ON;;;;;N;HEAVY LOWER RIGHT ARROW;;;;
2799;HEAVY RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY RIGHT ARROW;;;;
279A;HEAVY NORTH EAST ARROW;So;0;ON;;;;;N;HEAVY UPPER RIGHT ARROW;;;;
@@ -8643,6 +9062,7 @@
27AD;HEAVY LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY LOWER RIGHT-SHADOWED WHITE RIGHT ARROW;;;;
27AE;HEAVY UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY UPPER RIGHT-SHADOWED WHITE RIGHT ARROW;;;;
27AF;NOTCHED LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;NOTCHED LOWER RIGHT-SHADOWED WHITE RIGHT ARROW;;;;
+27B0;CURLY LOOP;So;0;ON;;;;;N;;;;;
27B1;NOTCHED UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;NOTCHED UPPER RIGHT-SHADOWED WHITE RIGHT ARROW;;;;
27B2;CIRCLED HEAVY WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;CIRCLED HEAVY WHITE RIGHT ARROW;;;;
27B3;WHITE-FEATHERED RIGHTWARDS ARROW;So;0;ON;;;;;N;WHITE-FEATHERED RIGHT ARROW;;;;
@@ -8657,6 +9077,7 @@
27BC;WEDGE-TAILED RIGHTWARDS ARROW;So;0;ON;;;;;N;WEDGE-TAILED RIGHT ARROW;;;;
27BD;HEAVY WEDGE-TAILED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY WEDGE-TAILED RIGHT ARROW;;;;
27BE;OPEN-OUTLINED RIGHTWARDS ARROW;So;0;ON;;;;;N;OPEN-OUTLINED RIGHT ARROW;;;;
+27BF;DOUBLE CURLY LOOP;So;0;ON;;;;;N;;;;;
27C0;THREE DIMENSIONAL ANGLE;Sm;0;ON;;;;;Y;;;;;
27C1;WHITE TRIANGLE CONTAINING SMALL WHITE TRIANGLE;Sm;0;ON;;;;;N;;;;;
27C2;PERPENDICULAR;Sm;0;ON;;;;;N;;;;;
@@ -8668,7 +9089,11 @@
27C8;REVERSE SOLIDUS PRECEDING SUBSET;Sm;0;ON;;;;;Y;;;;;
27C9;SUPERSET PRECEDING SOLIDUS;Sm;0;ON;;;;;Y;;;;;
27CA;VERTICAL BAR WITH HORIZONTAL STROKE;Sm;0;ON;;;;;N;;;;;
+27CB;MATHEMATICAL RISING DIAGONAL;Sm;0;ON;;;;;Y;;;;;
27CC;LONG DIVISION;Sm;0;ON;;;;;Y;;;;;
+27CD;MATHEMATICAL FALLING DIAGONAL;Sm;0;ON;;;;;Y;;;;;
+27CE;SQUARED LOGICAL AND;Sm;0;ON;;;;;N;;;;;
+27CF;SQUARED LOGICAL OR;Sm;0;ON;;;;;N;;;;;
27D0;WHITE DIAMOND WITH CENTRED DOT;Sm;0;ON;;;;;N;;;;;
27D1;AND WITH DOT;Sm;0;ON;;;;;N;;;;;
27D2;ELEMENT OF OPENING UPWARDS;Sm;0;ON;;;;;N;;;;;
@@ -9562,6 +9987,9 @@
2B4A;LEFTWARDS ARROW ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;N;;;;;
2B4B;LEFTWARDS ARROW ABOVE REVERSE TILDE OPERATOR;Sm;0;ON;;;;;N;;;;;
2B4C;RIGHTWARDS ARROW ABOVE REVERSE TILDE OPERATOR;Sm;0;ON;;;;;N;;;;;
+2B4D;DOWNWARDS TRIANGLE-HEADED ZIGZAG ARROW;So;0;ON;;;;;N;;;;;
+2B4E;SHORT SLANTED NORTH ARROW;So;0;ON;;;;;N;;;;;
+2B4F;SHORT BACKSLANTED SOUTH ARROW;So;0;ON;;;;;N;;;;;
2B50;WHITE MEDIUM STAR;So;0;ON;;;;;N;;;;;
2B51;BLACK SMALL STAR;So;0;ON;;;;;N;;;;;
2B52;WHITE SMALL STAR;So;0;ON;;;;;N;;;;;
@@ -9572,6 +10000,123 @@
2B57;HEAVY CIRCLE WITH CIRCLE INSIDE;So;0;ON;;;;;N;;;;;
2B58;HEAVY CIRCLE;So;0;ON;;;;;N;;;;;
2B59;HEAVY CIRCLED SALTIRE;So;0;ON;;;;;N;;;;;
+2B5A;SLANTED NORTH ARROW WITH HOOKED HEAD;So;0;ON;;;;;N;;;;;
+2B5B;BACKSLANTED SOUTH ARROW WITH HOOKED TAIL;So;0;ON;;;;;N;;;;;
+2B5C;SLANTED NORTH ARROW WITH HORIZONTAL TAIL;So;0;ON;;;;;N;;;;;
+2B5D;BACKSLANTED SOUTH ARROW WITH HORIZONTAL TAIL;So;0;ON;;;;;N;;;;;
+2B5E;BENT ARROW POINTING DOWNWARDS THEN NORTH EAST;So;0;ON;;;;;N;;;;;
+2B5F;SHORT BENT ARROW POINTING DOWNWARDS THEN NORTH EAST;So;0;ON;;;;;N;;;;;
+2B60;LEFTWARDS TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;;
+2B61;UPWARDS TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;;
+2B62;RIGHTWARDS TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;;
+2B63;DOWNWARDS TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;;
+2B64;LEFT RIGHT TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;;
+2B65;UP DOWN TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;;
+2B66;NORTH WEST TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;;
+2B67;NORTH EAST TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;;
+2B68;SOUTH EAST TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;;
+2B69;SOUTH WEST TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;;
+2B6A;LEFTWARDS TRIANGLE-HEADED DASHED ARROW;So;0;ON;;;;;N;;;;;
+2B6B;UPWARDS TRIANGLE-HEADED DASHED ARROW;So;0;ON;;;;;N;;;;;
+2B6C;RIGHTWARDS TRIANGLE-HEADED DASHED ARROW;So;0;ON;;;;;N;;;;;
+2B6D;DOWNWARDS TRIANGLE-HEADED DASHED ARROW;So;0;ON;;;;;N;;;;;
+2B6E;CLOCKWISE TRIANGLE-HEADED OPEN CIRCLE ARROW;So;0;ON;;;;;N;;;;;
+2B6F;ANTICLOCKWISE TRIANGLE-HEADED OPEN CIRCLE ARROW;So;0;ON;;;;;N;;;;;
+2B70;LEFTWARDS TRIANGLE-HEADED ARROW TO BAR;So;0;ON;;;;;N;;;;;
+2B71;UPWARDS TRIANGLE-HEADED ARROW TO BAR;So;0;ON;;;;;N;;;;;
+2B72;RIGHTWARDS TRIANGLE-HEADED ARROW TO BAR;So;0;ON;;;;;N;;;;;
+2B73;DOWNWARDS TRIANGLE-HEADED ARROW TO BAR;So;0;ON;;;;;N;;;;;
+2B76;NORTH WEST TRIANGLE-HEADED ARROW TO BAR;So;0;ON;;;;;N;;;;;
+2B77;NORTH EAST TRIANGLE-HEADED ARROW TO BAR;So;0;ON;;;;;N;;;;;
+2B78;SOUTH EAST TRIANGLE-HEADED ARROW TO BAR;So;0;ON;;;;;N;;;;;
+2B79;SOUTH WEST TRIANGLE-HEADED ARROW TO BAR;So;0;ON;;;;;N;;;;;
+2B7A;LEFTWARDS TRIANGLE-HEADED ARROW WITH DOUBLE HORIZONTAL STROKE;So;0;ON;;;;;N;;;;;
+2B7B;UPWARDS TRIANGLE-HEADED ARROW WITH DOUBLE HORIZONTAL STROKE;So;0;ON;;;;;N;;;;;
+2B7C;RIGHTWARDS TRIANGLE-HEADED ARROW WITH DOUBLE HORIZONTAL STROKE;So;0;ON;;;;;N;;;;;
+2B7D;DOWNWARDS TRIANGLE-HEADED ARROW WITH DOUBLE HORIZONTAL STROKE;So;0;ON;;;;;N;;;;;
+2B7E;HORIZONTAL TAB KEY;So;0;ON;;;;;N;;;;;
+2B7F;VERTICAL TAB KEY;So;0;ON;;;;;N;;;;;
+2B80;LEFTWARDS TRIANGLE-HEADED ARROW OVER RIGHTWARDS TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;;
+2B81;UPWARDS TRIANGLE-HEADED ARROW LEFTWARDS OF DOWNWARDS TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;;
+2B82;RIGHTWARDS TRIANGLE-HEADED ARROW OVER LEFTWARDS TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;;
+2B83;DOWNWARDS TRIANGLE-HEADED ARROW LEFTWARDS OF UPWARDS TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;;
+2B84;LEFTWARDS TRIANGLE-HEADED PAIRED ARROWS;So;0;ON;;;;;N;;;;;
+2B85;UPWARDS TRIANGLE-HEADED PAIRED ARROWS;So;0;ON;;;;;N;;;;;
+2B86;RIGHTWARDS TRIANGLE-HEADED PAIRED ARROWS;So;0;ON;;;;;N;;;;;
+2B87;DOWNWARDS TRIANGLE-HEADED PAIRED ARROWS;So;0;ON;;;;;N;;;;;
+2B88;LEFTWARDS BLACK CIRCLED WHITE ARROW;So;0;ON;;;;;N;;;;;
+2B89;UPWARDS BLACK CIRCLED WHITE ARROW;So;0;ON;;;;;N;;;;;
+2B8A;RIGHTWARDS BLACK CIRCLED WHITE ARROW;So;0;ON;;;;;N;;;;;
+2B8B;DOWNWARDS BLACK CIRCLED WHITE ARROW;So;0;ON;;;;;N;;;;;
+2B8C;ANTICLOCKWISE TRIANGLE-HEADED RIGHT U-SHAPED ARROW;So;0;ON;;;;;N;;;;;
+2B8D;ANTICLOCKWISE TRIANGLE-HEADED BOTTOM U-SHAPED ARROW;So;0;ON;;;;;N;;;;;
+2B8E;ANTICLOCKWISE TRIANGLE-HEADED LEFT U-SHAPED ARROW;So;0;ON;;;;;N;;;;;
+2B8F;ANTICLOCKWISE TRIANGLE-HEADED TOP U-SHAPED ARROW;So;0;ON;;;;;N;;;;;
+2B90;RETURN LEFT;So;0;ON;;;;;N;;;;;
+2B91;RETURN RIGHT;So;0;ON;;;;;N;;;;;
+2B92;NEWLINE LEFT;So;0;ON;;;;;N;;;;;
+2B93;NEWLINE RIGHT;So;0;ON;;;;;N;;;;;
+2B94;FOUR CORNER ARROWS CIRCLING ANTICLOCKWISE;So;0;ON;;;;;N;;;;;
+2B95;RIGHTWARDS BLACK ARROW;So;0;ON;;;;;N;;;;;
+2B98;THREE-D TOP-LIGHTED LEFTWARDS EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+2B99;THREE-D RIGHT-LIGHTED UPWARDS EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+2B9A;THREE-D TOP-LIGHTED RIGHTWARDS EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+2B9B;THREE-D LEFT-LIGHTED DOWNWARDS EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+2B9C;BLACK LEFTWARDS EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+2B9D;BLACK UPWARDS EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+2B9E;BLACK RIGHTWARDS EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+2B9F;BLACK DOWNWARDS EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+2BA0;DOWNWARDS TRIANGLE-HEADED ARROW WITH LONG TIP LEFTWARDS;So;0;ON;;;;;N;;;;;
+2BA1;DOWNWARDS TRIANGLE-HEADED ARROW WITH LONG TIP RIGHTWARDS;So;0;ON;;;;;N;;;;;
+2BA2;UPWARDS TRIANGLE-HEADED ARROW WITH LONG TIP LEFTWARDS;So;0;ON;;;;;N;;;;;
+2BA3;UPWARDS TRIANGLE-HEADED ARROW WITH LONG TIP RIGHTWARDS;So;0;ON;;;;;N;;;;;
+2BA4;LEFTWARDS TRIANGLE-HEADED ARROW WITH LONG TIP UPWARDS;So;0;ON;;;;;N;;;;;
+2BA5;RIGHTWARDS TRIANGLE-HEADED ARROW WITH LONG TIP UPWARDS;So;0;ON;;;;;N;;;;;
+2BA6;LEFTWARDS TRIANGLE-HEADED ARROW WITH LONG TIP DOWNWARDS;So;0;ON;;;;;N;;;;;
+2BA7;RIGHTWARDS TRIANGLE-HEADED ARROW WITH LONG TIP DOWNWARDS;So;0;ON;;;;;N;;;;;
+2BA8;BLACK CURVED DOWNWARDS AND LEFTWARDS ARROW;So;0;ON;;;;;N;;;;;
+2BA9;BLACK CURVED DOWNWARDS AND RIGHTWARDS ARROW;So;0;ON;;;;;N;;;;;
+2BAA;BLACK CURVED UPWARDS AND LEFTWARDS ARROW;So;0;ON;;;;;N;;;;;
+2BAB;BLACK CURVED UPWARDS AND RIGHTWARDS ARROW;So;0;ON;;;;;N;;;;;
+2BAC;BLACK CURVED LEFTWARDS AND UPWARDS ARROW;So;0;ON;;;;;N;;;;;
+2BAD;BLACK CURVED RIGHTWARDS AND UPWARDS ARROW;So;0;ON;;;;;N;;;;;
+2BAE;BLACK CURVED LEFTWARDS AND DOWNWARDS ARROW;So;0;ON;;;;;N;;;;;
+2BAF;BLACK CURVED RIGHTWARDS AND DOWNWARDS ARROW;So;0;ON;;;;;N;;;;;
+2BB0;RIBBON ARROW DOWN LEFT;So;0;ON;;;;;N;;;;;
+2BB1;RIBBON ARROW DOWN RIGHT;So;0;ON;;;;;N;;;;;
+2BB2;RIBBON ARROW UP LEFT;So;0;ON;;;;;N;;;;;
+2BB3;RIBBON ARROW UP RIGHT;So;0;ON;;;;;N;;;;;
+2BB4;RIBBON ARROW LEFT UP;So;0;ON;;;;;N;;;;;
+2BB5;RIBBON ARROW RIGHT UP;So;0;ON;;;;;N;;;;;
+2BB6;RIBBON ARROW LEFT DOWN;So;0;ON;;;;;N;;;;;
+2BB7;RIBBON ARROW RIGHT DOWN;So;0;ON;;;;;N;;;;;
+2BB8;UPWARDS WHITE ARROW FROM BAR WITH HORIZONTAL BAR;So;0;ON;;;;;N;;;;;
+2BB9;UP ARROWHEAD IN A RECTANGLE BOX;So;0;ON;;;;;N;;;;;
+2BBD;BALLOT BOX WITH LIGHT X;So;0;ON;;;;;N;;;;;
+2BBE;CIRCLED X;So;0;ON;;;;;N;;;;;
+2BBF;CIRCLED BOLD X;So;0;ON;;;;;N;;;;;
+2BC0;BLACK SQUARE CENTRED;So;0;ON;;;;;N;;;;;
+2BC1;BLACK DIAMOND CENTRED;So;0;ON;;;;;N;;;;;
+2BC2;TURNED BLACK PENTAGON;So;0;ON;;;;;N;;;;;
+2BC3;HORIZONTAL BLACK OCTAGON;So;0;ON;;;;;N;;;;;
+2BC4;BLACK OCTAGON;So;0;ON;;;;;N;;;;;
+2BC5;BLACK MEDIUM UP-POINTING TRIANGLE CENTRED;So;0;ON;;;;;N;;;;;
+2BC6;BLACK MEDIUM DOWN-POINTING TRIANGLE CENTRED;So;0;ON;;;;;N;;;;;
+2BC7;BLACK MEDIUM LEFT-POINTING TRIANGLE CENTRED;So;0;ON;;;;;N;;;;;
+2BC8;BLACK MEDIUM RIGHT-POINTING TRIANGLE CENTRED;So;0;ON;;;;;N;;;;;
+2BCA;TOP HALF BLACK CIRCLE;So;0;ON;;;;;N;;;;;
+2BCB;BOTTOM HALF BLACK CIRCLE;So;0;ON;;;;;N;;;;;
+2BCC;LIGHT FOUR POINTED BLACK CUSP;So;0;ON;;;;;N;;;;;
+2BCD;ROTATED LIGHT FOUR POINTED BLACK CUSP;So;0;ON;;;;;N;;;;;
+2BCE;WHITE FOUR POINTED CUSP;So;0;ON;;;;;N;;;;;
+2BCF;ROTATED WHITE FOUR POINTED CUSP;So;0;ON;;;;;N;;;;;
+2BD0;SQUARE POSITION INDICATOR;So;0;ON;;;;;N;;;;;
+2BD1;UNCERTAINTY SIGN;So;0;ON;;;;;N;;;;;
+2BD2;GROUP MARK;So;0;ON;;;;;N;;;;;
+2BEC;LEFTWARDS TWO-HEADED ARROW WITH TRIANGLE ARROWHEADS;So;0;ON;;;;;N;;;;;
+2BED;UPWARDS TWO-HEADED ARROW WITH TRIANGLE ARROWHEADS;So;0;ON;;;;;N;;;;;
+2BEE;RIGHTWARDS TWO-HEADED ARROW WITH TRIANGLE ARROWHEADS;So;0;ON;;;;;N;;;;;
+2BEF;DOWNWARDS TWO-HEADED ARROW WITH TRIANGLE ARROWHEADS;So;0;ON;;;;;N;;;;;
2C00;GLAGOLITIC CAPITAL LETTER AZU;Lu;0;L;;;;;N;;;;2C30;
2C01;GLAGOLITIC CAPITAL LETTER BUKY;Lu;0;L;;;;;N;;;;2C31;
2C02;GLAGOLITIC CAPITAL LETTER VEDE;Lu;0;L;;;;;N;;;;2C32;
@@ -9694,7 +10239,7 @@
2C79;LATIN SMALL LETTER TURNED R WITH TAIL;Ll;0;L;;;;;N;;;;;
2C7A;LATIN SMALL LETTER O WITH LOW RING INSIDE;Ll;0;L;;;;;N;;;;;
2C7B;LATIN LETTER SMALL CAPITAL TURNED E;Ll;0;L;;;;;N;;;;;
-2C7C;LATIN SUBSCRIPT SMALL LETTER J;Ll;0;L;<sub> 006A;;;;N;;;;;
+2C7C;LATIN SUBSCRIPT SMALL LETTER J;Lm;0;L;<sub> 006A;;;;N;;;;;
2C7D;MODIFIER LETTER CAPITAL V;Lm;0;L;<super> 0056;;;;N;;;;;
2C7E;LATIN CAPITAL LETTER S WITH SWASH TAIL;Lu;0;L;;;;;N;;;;023F;
2C7F;LATIN CAPITAL LETTER Z WITH SWASH TAIL;Lu;0;L;;;;;N;;;;0240;
@@ -9812,6 +10357,8 @@
2CEF;COPTIC COMBINING NI ABOVE;Mn;230;NSM;;;;;N;;;;;
2CF0;COPTIC COMBINING SPIRITUS ASPER;Mn;230;NSM;;;;;N;;;;;
2CF1;COPTIC COMBINING SPIRITUS LENIS;Mn;230;NSM;;;;;N;;;;;
+2CF2;COPTIC CAPITAL LETTER BOHAIRIC KHEI;Lu;0;L;;;;;N;;;;2CF3;
+2CF3;COPTIC SMALL LETTER BOHAIRIC KHEI;Ll;0;L;;;;;N;;;2CF2;;2CF2
2CF9;COPTIC OLD NUBIAN FULL STOP;Po;0;ON;;;;;N;;;;;
2CFA;COPTIC OLD NUBIAN DIRECT QUESTION MARK;Po;0;ON;;;;;N;;;;;
2CFB;COPTIC OLD NUBIAN INDIRECT QUESTION MARK;Po;0;ON;;;;;N;;;;;
@@ -9857,6 +10404,8 @@
2D23;GEORGIAN SMALL LETTER WE;Ll;0;L;;;;;N;;;10C3;;10C3
2D24;GEORGIAN SMALL LETTER HAR;Ll;0;L;;;;;N;;;10C4;;10C4
2D25;GEORGIAN SMALL LETTER HOE;Ll;0;L;;;;;N;;;10C5;;10C5
+2D27;GEORGIAN SMALL LETTER YN;Ll;0;L;;;;;N;;;10C7;;10C7
+2D2D;GEORGIAN SMALL LETTER AEN;Ll;0;L;;;;;N;;;10CD;;10CD
2D30;TIFINAGH LETTER YA;Lo;0;L;;;;;N;;;;;
2D31;TIFINAGH LETTER YAB;Lo;0;L;;;;;N;;;;;
2D32;TIFINAGH LETTER YABH;Lo;0;L;;;;;N;;;;;
@@ -9911,7 +10460,11 @@
2D63;TIFINAGH LETTER YAZ;Lo;0;L;;;;;N;;;;;
2D64;TIFINAGH LETTER TAWELLEMET YAZ;Lo;0;L;;;;;N;;;;;
2D65;TIFINAGH LETTER YAZZ;Lo;0;L;;;;;N;;;;;
+2D66;TIFINAGH LETTER YE;Lo;0;L;;;;;N;;;;;
+2D67;TIFINAGH LETTER YO;Lo;0;L;;;;;N;;;;;
2D6F;TIFINAGH MODIFIER LETTER LABIALIZATION MARK;Lm;0;L;<super> 2D61;;;;N;;;;;
+2D70;TIFINAGH SEPARATOR MARK;Po;0;L;;;;;N;;;;;
+2D7F;TIFINAGH CONSONANT JOINER;Mn;9;NSM;;;;;N;;;;;
2D80;ETHIOPIC SYLLABLE LOA;Lo;0;L;;;;;N;;;;;
2D81;ETHIOPIC SYLLABLE MOA;Lo;0;L;;;;;N;;;;;
2D82;ETHIOPIC SYLLABLE ROA;Lo;0;L;;;;;N;;;;;
@@ -10073,6 +10626,30 @@
2E2F;VERTICAL TILDE;Lm;0;ON;;;;;N;;;;;
2E30;RING POINT;Po;0;ON;;;;;N;;;;;
2E31;WORD SEPARATOR MIDDLE DOT;Po;0;ON;;;;;N;;;;;
+2E32;TURNED COMMA;Po;0;ON;;;;;N;;;;;
+2E33;RAISED DOT;Po;0;ON;;;;;N;;;;;
+2E34;RAISED COMMA;Po;0;ON;;;;;N;;;;;
+2E35;TURNED SEMICOLON;Po;0;ON;;;;;N;;;;;
+2E36;DAGGER WITH LEFT GUARD;Po;0;ON;;;;;N;;;;;
+2E37;DAGGER WITH RIGHT GUARD;Po;0;ON;;;;;N;;;;;
+2E38;TURNED DAGGER;Po;0;ON;;;;;N;;;;;
+2E39;TOP HALF SECTION SIGN;Po;0;ON;;;;;N;;;;;
+2E3A;TWO-EM DASH;Pd;0;ON;;;;;N;;;;;
+2E3B;THREE-EM DASH;Pd;0;ON;;;;;N;;;;;
+2E3C;STENOGRAPHIC FULL STOP;Po;0;ON;;;;;N;;;;;
+2E3D;VERTICAL SIX DOTS;Po;0;ON;;;;;N;;;;;
+2E3E;WIGGLY VERTICAL LINE;Po;0;ON;;;;;N;;;;;
+2E3F;CAPITULUM;Po;0;ON;;;;;N;;;;;
+2E40;DOUBLE HYPHEN;Pd;0;ON;;;;;N;;;;;
+2E41;REVERSED COMMA;Po;0;ON;;;;;N;;;;;
+2E42;DOUBLE LOW-REVERSED-9 QUOTATION MARK;Ps;0;ON;;;;;N;;;;;
+2E43;DASH WITH LEFT UPTURN;Po;0;ON;;;;;N;;;;;
+2E44;DOUBLE SUSPENSION MARK;Po;0;ON;;;;;N;;;;;
+2E45;INVERTED LOW KAVYKA;Po;0;ON;;;;;N;;;;;
+2E46;INVERTED LOW KAVYKA WITH KAVYKA ABOVE;Po;0;ON;;;;;N;;;;;
+2E47;LOW KAVYKA;Po;0;ON;;;;;N;;;;;
+2E48;LOW KAVYKA WITH DOT;Po;0;ON;;;;;N;;;;;
+2E49;DOUBLE STACKED COMMA;Po;0;ON;;;;;N;;;;;
2E80;CJK RADICAL REPEAT;So;0;ON;;;;;N;;;;;
2E81;CJK RADICAL CLIFF;So;0;ON;;;;;N;;;;;
2E82;CJK RADICAL SECOND ONE;So;0;ON;;;;;N;;;;;
@@ -10460,8 +11037,8 @@
302B;IDEOGRAPHIC RISING TONE MARK;Mn;228;NSM;;;;;N;;;;;
302C;IDEOGRAPHIC DEPARTING TONE MARK;Mn;232;NSM;;;;;N;;;;;
302D;IDEOGRAPHIC ENTERING TONE MARK;Mn;222;NSM;;;;;N;;;;;
-302E;HANGUL SINGLE DOT TONE MARK;Mn;224;NSM;;;;;N;;;;;
-302F;HANGUL DOUBLE DOT TONE MARK;Mn;224;NSM;;;;;N;;;;;
+302E;HANGUL SINGLE DOT TONE MARK;Mc;224;L;;;;;N;;;;;
+302F;HANGUL DOUBLE DOT TONE MARK;Mc;224;L;;;;;N;;;;;
3030;WAVY DASH;Pd;0;ON;;;;;N;;;;;
3031;VERTICAL KANA REPEAT MARK;Lm;0;L;;;;;N;;;;;
3032;VERTICAL KANA REPEAT WITH VOICED SOUND MARK;Lm;0;L;;;;;N;;;;;
@@ -10708,6 +11285,7 @@
312B;BOPOMOFO LETTER NG;Lo;0;L;;;;;N;;;;;
312C;BOPOMOFO LETTER GN;Lo;0;L;;;;;N;;;;;
312D;BOPOMOFO LETTER IH;Lo;0;L;;;;;N;;;;;
+312E;BOPOMOFO LETTER O WITH DOT ABOVE;Lo;0;L;;;;;N;;;;;
3131;HANGUL LETTER KIYEOK;Lo;0;L;<compat> 1100;;;;N;HANGUL LETTER GIYEOG;;;;
3132;HANGUL LETTER SSANGKIYEOK;Lo;0;L;<compat> 1101;;;;N;HANGUL LETTER SSANG GIYEOG;;;;
3133;HANGUL LETTER KIYEOK-SIOS;Lo;0;L;<compat> 11AA;;;;N;HANGUL LETTER GIYEOG SIOS;;;;
@@ -10842,6 +11420,9 @@
31B5;BOPOMOFO FINAL LETTER T;Lo;0;L;;;;;N;;;;;
31B6;BOPOMOFO FINAL LETTER K;Lo;0;L;;;;;N;;;;;
31B7;BOPOMOFO FINAL LETTER H;Lo;0;L;;;;;N;;;;;
+31B8;BOPOMOFO LETTER GH;Lo;0;L;;;;;N;;;;;
+31B9;BOPOMOFO LETTER LH;Lo;0;L;;;;;N;;;;;
+31BA;BOPOMOFO LETTER ZY;Lo;0;L;;;;;N;;;;;
31C0;CJK STROKE T;So;0;ON;;;;;N;;;;;
31C1;CJK STROKE WG;So;0;ON;;;;;N;;;;;
31C2;CJK STROKE XG;So;0;ON;;;;;N;;;;;
@@ -10965,14 +11546,14 @@
3245;CIRCLED IDEOGRAPH KINDERGARTEN;So;0;L;<circle> 5E7C;;;;N;;;;;
3246;CIRCLED IDEOGRAPH SCHOOL;So;0;L;<circle> 6587;;;;N;;;;;
3247;CIRCLED IDEOGRAPH KOTO;So;0;L;<circle> 7B8F;;;;N;;;;;
-3248;CIRCLED NUMBER TEN ON BLACK SQUARE;So;0;L;;;;;N;;;;;
-3249;CIRCLED NUMBER TWENTY ON BLACK SQUARE;So;0;L;;;;;N;;;;;
-324A;CIRCLED NUMBER THIRTY ON BLACK SQUARE;So;0;L;;;;;N;;;;;
-324B;CIRCLED NUMBER FORTY ON BLACK SQUARE;So;0;L;;;;;N;;;;;
-324C;CIRCLED NUMBER FIFTY ON BLACK SQUARE;So;0;L;;;;;N;;;;;
-324D;CIRCLED NUMBER SIXTY ON BLACK SQUARE;So;0;L;;;;;N;;;;;
-324E;CIRCLED NUMBER SEVENTY ON BLACK SQUARE;So;0;L;;;;;N;;;;;
-324F;CIRCLED NUMBER EIGHTY ON BLACK SQUARE;So;0;L;;;;;N;;;;;
+3248;CIRCLED NUMBER TEN ON BLACK SQUARE;No;0;L;;;;10;N;;;;;
+3249;CIRCLED NUMBER TWENTY ON BLACK SQUARE;No;0;L;;;;20;N;;;;;
+324A;CIRCLED NUMBER THIRTY ON BLACK SQUARE;No;0;L;;;;30;N;;;;;
+324B;CIRCLED NUMBER FORTY ON BLACK SQUARE;No;0;L;;;;40;N;;;;;
+324C;CIRCLED NUMBER FIFTY ON BLACK SQUARE;No;0;L;;;;50;N;;;;;
+324D;CIRCLED NUMBER SIXTY ON BLACK SQUARE;No;0;L;;;;60;N;;;;;
+324E;CIRCLED NUMBER SEVENTY ON BLACK SQUARE;No;0;L;;;;70;N;;;;;
+324F;CIRCLED NUMBER EIGHTY ON BLACK SQUARE;No;0;L;;;;80;N;;;;;
3250;PARTNERSHIP SIGN;So;0;ON;<square> 0050 0054 0045;;;;N;;;;;
3251;CIRCLED NUMBER TWENTY ONE;No;0;ON;<circle> 0032 0031;;;21;N;;;;;
3252;CIRCLED NUMBER TWENTY TWO;No;0;ON;<circle> 0032 0032;;;22;N;;;;;
@@ -11471,7 +12052,7 @@
4DFE;HEXAGRAM FOR AFTER COMPLETION;So;0;ON;;;;;N;;;;;
4DFF;HEXAGRAM FOR BEFORE COMPLETION;So;0;ON;;;;;N;;;;;
4E00;<CJK Ideograph, First>;Lo;0;L;;;;;N;;;;;
-9FCB;<CJK Ideograph, Last>;Lo;0;L;;;;;N;;;;;
+9FEA;<CJK Ideograph, Last>;Lo;0;L;;;;;N;;;;;
A000;YI SYLLABLE IT;Lo;0;L;;;;;N;;;;;
A001;YI SYLLABLE IX;Lo;0;L;;;;;N;;;;;
A002;YI SYLLABLE I;Lo;0;L;;;;;N;;;;;
@@ -13072,6 +13653,8 @@ A65C;CYRILLIC CAPITAL LETTER IOTIFIED CLOSED LITTLE YUS;Lu;0;L;;;;;N;;;;A65D;
A65D;CYRILLIC SMALL LETTER IOTIFIED CLOSED LITTLE YUS;Ll;0;L;;;;;N;;;A65C;;A65C
A65E;CYRILLIC CAPITAL LETTER YN;Lu;0;L;;;;;N;;;;A65F;
A65F;CYRILLIC SMALL LETTER YN;Ll;0;L;;;;;N;;;A65E;;A65E
+A660;CYRILLIC CAPITAL LETTER REVERSED TSE;Lu;0;L;;;;;N;;;;A661;
+A661;CYRILLIC SMALL LETTER REVERSED TSE;Ll;0;L;;;;;N;;;A660;;A660
A662;CYRILLIC CAPITAL LETTER SOFT DE;Lu;0;L;;;;;N;;;;A663;
A663;CYRILLIC SMALL LETTER SOFT DE;Ll;0;L;;;;;N;;;A662;;A662
A664;CYRILLIC CAPITAL LETTER SOFT EL;Lu;0;L;;;;;N;;;;A665;
@@ -13090,6 +13673,14 @@ A670;COMBINING CYRILLIC TEN MILLIONS SIGN;Me;0;NSM;;;;;N;;;;;
A671;COMBINING CYRILLIC HUNDRED MILLIONS SIGN;Me;0;NSM;;;;;N;;;;;
A672;COMBINING CYRILLIC THOUSAND MILLIONS SIGN;Me;0;NSM;;;;;N;;;;;
A673;SLAVONIC ASTERISK;Po;0;ON;;;;;N;;;;;
+A674;COMBINING CYRILLIC LETTER UKRAINIAN IE;Mn;230;NSM;;;;;N;;;;;
+A675;COMBINING CYRILLIC LETTER I;Mn;230;NSM;;;;;N;;;;;
+A676;COMBINING CYRILLIC LETTER YI;Mn;230;NSM;;;;;N;;;;;
+A677;COMBINING CYRILLIC LETTER U;Mn;230;NSM;;;;;N;;;;;
+A678;COMBINING CYRILLIC LETTER HARD SIGN;Mn;230;NSM;;;;;N;;;;;
+A679;COMBINING CYRILLIC LETTER YERU;Mn;230;NSM;;;;;N;;;;;
+A67A;COMBINING CYRILLIC LETTER SOFT SIGN;Mn;230;NSM;;;;;N;;;;;
+A67B;COMBINING CYRILLIC LETTER OMEGA;Mn;230;NSM;;;;;N;;;;;
A67C;COMBINING CYRILLIC KAVYKA;Mn;230;NSM;;;;;N;;;;;
A67D;COMBINING CYRILLIC PAYEROK;Mn;230;NSM;;;;;N;;;;;
A67E;CYRILLIC KAVYKA;Po;0;ON;;;;;N;;;;;
@@ -13118,6 +13709,14 @@ A694;CYRILLIC CAPITAL LETTER HWE;Lu;0;L;;;;;N;;;;A695;
A695;CYRILLIC SMALL LETTER HWE;Ll;0;L;;;;;N;;;A694;;A694
A696;CYRILLIC CAPITAL LETTER SHWE;Lu;0;L;;;;;N;;;;A697;
A697;CYRILLIC SMALL LETTER SHWE;Ll;0;L;;;;;N;;;A696;;A696
+A698;CYRILLIC CAPITAL LETTER DOUBLE O;Lu;0;L;;;;;N;;;;A699;
+A699;CYRILLIC SMALL LETTER DOUBLE O;Ll;0;L;;;;;N;;;A698;;A698
+A69A;CYRILLIC CAPITAL LETTER CROSSED O;Lu;0;L;;;;;N;;;;A69B;
+A69B;CYRILLIC SMALL LETTER CROSSED O;Ll;0;L;;;;;N;;;A69A;;A69A
+A69C;MODIFIER LETTER CYRILLIC HARD SIGN;Lm;0;L;<super> 044A;;;;N;;;;;
+A69D;MODIFIER LETTER CYRILLIC SOFT SIGN;Lm;0;L;<super> 044C;;;;N;;;;;
+A69E;COMBINING CYRILLIC LETTER EF;Mn;230;NSM;;;;;N;;;;;
+A69F;COMBINING CYRILLIC LETTER IOTIFIED E;Mn;230;NSM;;;;;N;;;;;
A6A0;BAMUM LETTER A;Lo;0;L;;;;;N;;;;;
A6A1;BAMUM LETTER KA;Lo;0;L;;;;;N;;;;;
A6A2;BAMUM LETTER U;Lo;0;L;;;;;N;;;;;
@@ -13347,6 +13946,52 @@ A789;MODIFIER LETTER COLON;Sk;0;L;;;;;N;;;;;
A78A;MODIFIER LETTER SHORT EQUALS SIGN;Sk;0;L;;;;;N;;;;;
A78B;LATIN CAPITAL LETTER SALTILLO;Lu;0;L;;;;;N;;;;A78C;
A78C;LATIN SMALL LETTER SALTILLO;Ll;0;L;;;;;N;;;A78B;;A78B
+A78D;LATIN CAPITAL LETTER TURNED H;Lu;0;L;;;;;N;;;;0265;
+A78E;LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT;Ll;0;L;;;;;N;;;;;
+A78F;LATIN LETTER SINOLOGICAL DOT;Lo;0;L;;;;;N;;;;;
+A790;LATIN CAPITAL LETTER N WITH DESCENDER;Lu;0;L;;;;;N;;;;A791;
+A791;LATIN SMALL LETTER N WITH DESCENDER;Ll;0;L;;;;;N;;;A790;;A790
+A792;LATIN CAPITAL LETTER C WITH BAR;Lu;0;L;;;;;N;;;;A793;
+A793;LATIN SMALL LETTER C WITH BAR;Ll;0;L;;;;;N;;;A792;;A792
+A794;LATIN SMALL LETTER C WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+A795;LATIN SMALL LETTER H WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+A796;LATIN CAPITAL LETTER B WITH FLOURISH;Lu;0;L;;;;;N;;;;A797;
+A797;LATIN SMALL LETTER B WITH FLOURISH;Ll;0;L;;;;;N;;;A796;;A796
+A798;LATIN CAPITAL LETTER F WITH STROKE;Lu;0;L;;;;;N;;;;A799;
+A799;LATIN SMALL LETTER F WITH STROKE;Ll;0;L;;;;;N;;;A798;;A798
+A79A;LATIN CAPITAL LETTER VOLAPUK AE;Lu;0;L;;;;;N;;;;A79B;
+A79B;LATIN SMALL LETTER VOLAPUK AE;Ll;0;L;;;;;N;;;A79A;;A79A
+A79C;LATIN CAPITAL LETTER VOLAPUK OE;Lu;0;L;;;;;N;;;;A79D;
+A79D;LATIN SMALL LETTER VOLAPUK OE;Ll;0;L;;;;;N;;;A79C;;A79C
+A79E;LATIN CAPITAL LETTER VOLAPUK UE;Lu;0;L;;;;;N;;;;A79F;
+A79F;LATIN SMALL LETTER VOLAPUK UE;Ll;0;L;;;;;N;;;A79E;;A79E
+A7A0;LATIN CAPITAL LETTER G WITH OBLIQUE STROKE;Lu;0;L;;;;;N;;;;A7A1;
+A7A1;LATIN SMALL LETTER G WITH OBLIQUE STROKE;Ll;0;L;;;;;N;;;A7A0;;A7A0
+A7A2;LATIN CAPITAL LETTER K WITH OBLIQUE STROKE;Lu;0;L;;;;;N;;;;A7A3;
+A7A3;LATIN SMALL LETTER K WITH OBLIQUE STROKE;Ll;0;L;;;;;N;;;A7A2;;A7A2
+A7A4;LATIN CAPITAL LETTER N WITH OBLIQUE STROKE;Lu;0;L;;;;;N;;;;A7A5;
+A7A5;LATIN SMALL LETTER N WITH OBLIQUE STROKE;Ll;0;L;;;;;N;;;A7A4;;A7A4
+A7A6;LATIN CAPITAL LETTER R WITH OBLIQUE STROKE;Lu;0;L;;;;;N;;;;A7A7;
+A7A7;LATIN SMALL LETTER R WITH OBLIQUE STROKE;Ll;0;L;;;;;N;;;A7A6;;A7A6
+A7A8;LATIN CAPITAL LETTER S WITH OBLIQUE STROKE;Lu;0;L;;;;;N;;;;A7A9;
+A7A9;LATIN SMALL LETTER S WITH OBLIQUE STROKE;Ll;0;L;;;;;N;;;A7A8;;A7A8
+A7AA;LATIN CAPITAL LETTER H WITH HOOK;Lu;0;L;;;;;N;;;;0266;
+A7AB;LATIN CAPITAL LETTER REVERSED OPEN E;Lu;0;L;;;;;N;;;;025C;
+A7AC;LATIN CAPITAL LETTER SCRIPT G;Lu;0;L;;;;;N;;;;0261;
+A7AD;LATIN CAPITAL LETTER L WITH BELT;Lu;0;L;;;;;N;;;;026C;
+A7AE;LATIN CAPITAL LETTER SMALL CAPITAL I;Lu;0;L;;;;;N;;;;026A;
+A7B0;LATIN CAPITAL LETTER TURNED K;Lu;0;L;;;;;N;;;;029E;
+A7B1;LATIN CAPITAL LETTER TURNED T;Lu;0;L;;;;;N;;;;0287;
+A7B2;LATIN CAPITAL LETTER J WITH CROSSED-TAIL;Lu;0;L;;;;;N;;;;029D;
+A7B3;LATIN CAPITAL LETTER CHI;Lu;0;L;;;;;N;;;;AB53;
+A7B4;LATIN CAPITAL LETTER BETA;Lu;0;L;;;;;N;;;;A7B5;
+A7B5;LATIN SMALL LETTER BETA;Ll;0;L;;;;;N;;;A7B4;;A7B4
+A7B6;LATIN CAPITAL LETTER OMEGA;Lu;0;L;;;;;N;;;;A7B7;
+A7B7;LATIN SMALL LETTER OMEGA;Ll;0;L;;;;;N;;;A7B6;;A7B6
+A7F7;LATIN EPIGRAPHIC LETTER SIDEWAYS I;Lo;0;L;;;;;N;;;;;
+A7F8;MODIFIER LETTER CAPITAL H WITH STROKE;Lm;0;L;<super> 0126;;;;N;;;;;
+A7F9;MODIFIER LETTER SMALL LIGATURE OE;Lm;0;L;<super> 0153;;;;N;;;;;
+A7FA;LATIN LETTER SMALL CAPITAL TURNED M;Ll;0;L;;;;;N;;;;;
A7FB;LATIN EPIGRAPHIC LETTER REVERSED F;Lo;0;L;;;;;N;;;;;
A7FC;LATIN EPIGRAPHIC LETTER REVERSED P;Lo;0;L;;;;;N;;;;;
A7FD;LATIN EPIGRAPHIC LETTER INVERTED M;Lo;0;L;;;;;N;;;;;
@@ -13531,6 +14176,7 @@ A8C1;SAURASHTRA VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
A8C2;SAURASHTRA VOWEL SIGN OO;Mc;0;L;;;;;N;;;;;
A8C3;SAURASHTRA VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;
A8C4;SAURASHTRA SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+A8C5;SAURASHTRA SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
A8CE;SAURASHTRA DANDA;Po;0;L;;;;;N;;;;;
A8CF;SAURASHTRA DOUBLE DANDA;Po;0;L;;;;;N;;;;;
A8D0;SAURASHTRA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
@@ -13571,6 +14217,8 @@ A8F8;DEVANAGARI SIGN PUSHPIKA;Po;0;L;;;;;N;;;;;
A8F9;DEVANAGARI GAP FILLER;Po;0;L;;;;;N;;;;;
A8FA;DEVANAGARI CARET;Po;0;L;;;;;N;;;;;
A8FB;DEVANAGARI HEADSTROKE;Lo;0;L;;;;;N;;;;;
+A8FC;DEVANAGARI SIGN SIDDHAM;Po;0;L;;;;;N;;;;;
+A8FD;DEVANAGARI JAIN OM;Lo;0;L;;;;;N;;;;;
A900;KAYAH LI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
A901;KAYAH LI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
A902;KAYAH LI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
@@ -13776,6 +14424,37 @@ A9D8;JAVANESE DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
A9D9;JAVANESE DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
A9DE;JAVANESE PADA TIRTA TUMETES;Po;0;L;;;;;N;;;;;
A9DF;JAVANESE PADA ISEN-ISEN;Po;0;L;;;;;N;;;;;
+A9E0;MYANMAR LETTER SHAN GHA;Lo;0;L;;;;;N;;;;;
+A9E1;MYANMAR LETTER SHAN CHA;Lo;0;L;;;;;N;;;;;
+A9E2;MYANMAR LETTER SHAN JHA;Lo;0;L;;;;;N;;;;;
+A9E3;MYANMAR LETTER SHAN NNA;Lo;0;L;;;;;N;;;;;
+A9E4;MYANMAR LETTER SHAN BHA;Lo;0;L;;;;;N;;;;;
+A9E5;MYANMAR SIGN SHAN SAW;Mn;0;NSM;;;;;N;;;;;
+A9E6;MYANMAR MODIFIER LETTER SHAN REDUPLICATION;Lm;0;L;;;;;N;;;;;
+A9E7;MYANMAR LETTER TAI LAING NYA;Lo;0;L;;;;;N;;;;;
+A9E8;MYANMAR LETTER TAI LAING FA;Lo;0;L;;;;;N;;;;;
+A9E9;MYANMAR LETTER TAI LAING GA;Lo;0;L;;;;;N;;;;;
+A9EA;MYANMAR LETTER TAI LAING GHA;Lo;0;L;;;;;N;;;;;
+A9EB;MYANMAR LETTER TAI LAING JA;Lo;0;L;;;;;N;;;;;
+A9EC;MYANMAR LETTER TAI LAING JHA;Lo;0;L;;;;;N;;;;;
+A9ED;MYANMAR LETTER TAI LAING DDA;Lo;0;L;;;;;N;;;;;
+A9EE;MYANMAR LETTER TAI LAING DDHA;Lo;0;L;;;;;N;;;;;
+A9EF;MYANMAR LETTER TAI LAING NNA;Lo;0;L;;;;;N;;;;;
+A9F0;MYANMAR TAI LAING DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+A9F1;MYANMAR TAI LAING DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+A9F2;MYANMAR TAI LAING DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+A9F3;MYANMAR TAI LAING DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+A9F4;MYANMAR TAI LAING DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+A9F5;MYANMAR TAI LAING DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+A9F6;MYANMAR TAI LAING DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+A9F7;MYANMAR TAI LAING DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+A9F8;MYANMAR TAI LAING DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+A9F9;MYANMAR TAI LAING DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+A9FA;MYANMAR LETTER TAI LAING LLA;Lo;0;L;;;;;N;;;;;
+A9FB;MYANMAR LETTER TAI LAING DA;Lo;0;L;;;;;N;;;;;
+A9FC;MYANMAR LETTER TAI LAING DHA;Lo;0;L;;;;;N;;;;;
+A9FD;MYANMAR LETTER TAI LAING BA;Lo;0;L;;;;;N;;;;;
+A9FE;MYANMAR LETTER TAI LAING BHA;Lo;0;L;;;;;N;;;;;
AA00;CHAM LETTER A;Lo;0;L;;;;;N;;;;;
AA01;CHAM LETTER I;Lo;0;L;;;;;N;;;;;
AA02;CHAM LETTER U;Lo;0;L;;;;;N;;;;;
@@ -13887,6 +14566,10 @@ AA78;MYANMAR SYMBOL AITON ONE;So;0;L;;;;;N;;;;;
AA79;MYANMAR SYMBOL AITON TWO;So;0;L;;;;;N;;;;;
AA7A;MYANMAR LETTER AITON RA;Lo;0;L;;;;;N;;;;;
AA7B;MYANMAR SIGN PAO KAREN TONE;Mc;0;L;;;;;N;;;;;
+AA7C;MYANMAR SIGN TAI LAING TONE-2;Mn;0;NSM;;;;;N;;;;;
+AA7D;MYANMAR SIGN TAI LAING TONE-5;Mc;0;L;;;;;N;;;;;
+AA7E;MYANMAR LETTER SHWE PALAUNG CHA;Lo;0;L;;;;;N;;;;;
+AA7F;MYANMAR LETTER SHWE PALAUNG SHA;Lo;0;L;;;;;N;;;;;
AA80;TAI VIET LETTER LOW KO;Lo;0;L;;;;;N;;;;;
AA81;TAI VIET LETTER HIGH KO;Lo;0;L;;;;;N;;;;;
AA82;TAI VIET LETTER LOW KHO;Lo;0;L;;;;;N;;;;;
@@ -13959,6 +14642,195 @@ AADC;TAI VIET SYMBOL NUENG;Lo;0;L;;;;;N;;;;;
AADD;TAI VIET SYMBOL SAM;Lm;0;L;;;;;N;;;;;
AADE;TAI VIET SYMBOL HO HOI;Po;0;L;;;;;N;;;;;
AADF;TAI VIET SYMBOL KOI KOI;Po;0;L;;;;;N;;;;;
+AAE0;MEETEI MAYEK LETTER E;Lo;0;L;;;;;N;;;;;
+AAE1;MEETEI MAYEK LETTER O;Lo;0;L;;;;;N;;;;;
+AAE2;MEETEI MAYEK LETTER CHA;Lo;0;L;;;;;N;;;;;
+AAE3;MEETEI MAYEK LETTER NYA;Lo;0;L;;;;;N;;;;;
+AAE4;MEETEI MAYEK LETTER TTA;Lo;0;L;;;;;N;;;;;
+AAE5;MEETEI MAYEK LETTER TTHA;Lo;0;L;;;;;N;;;;;
+AAE6;MEETEI MAYEK LETTER DDA;Lo;0;L;;;;;N;;;;;
+AAE7;MEETEI MAYEK LETTER DDHA;Lo;0;L;;;;;N;;;;;
+AAE8;MEETEI MAYEK LETTER NNA;Lo;0;L;;;;;N;;;;;
+AAE9;MEETEI MAYEK LETTER SHA;Lo;0;L;;;;;N;;;;;
+AAEA;MEETEI MAYEK LETTER SSA;Lo;0;L;;;;;N;;;;;
+AAEB;MEETEI MAYEK VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+AAEC;MEETEI MAYEK VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+AAED;MEETEI MAYEK VOWEL SIGN AAI;Mn;0;NSM;;;;;N;;;;;
+AAEE;MEETEI MAYEK VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;
+AAEF;MEETEI MAYEK VOWEL SIGN AAU;Mc;0;L;;;;;N;;;;;
+AAF0;MEETEI MAYEK CHEIKHAN;Po;0;L;;;;;N;;;;;
+AAF1;MEETEI MAYEK AHANG KHUDAM;Po;0;L;;;;;N;;;;;
+AAF2;MEETEI MAYEK ANJI;Lo;0;L;;;;;N;;;;;
+AAF3;MEETEI MAYEK SYLLABLE REPETITION MARK;Lm;0;L;;;;;N;;;;;
+AAF4;MEETEI MAYEK WORD REPETITION MARK;Lm;0;L;;;;;N;;;;;
+AAF5;MEETEI MAYEK VOWEL SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+AAF6;MEETEI MAYEK VIRAMA;Mn;9;NSM;;;;;N;;;;;
+AB01;ETHIOPIC SYLLABLE TTHU;Lo;0;L;;;;;N;;;;;
+AB02;ETHIOPIC SYLLABLE TTHI;Lo;0;L;;;;;N;;;;;
+AB03;ETHIOPIC SYLLABLE TTHAA;Lo;0;L;;;;;N;;;;;
+AB04;ETHIOPIC SYLLABLE TTHEE;Lo;0;L;;;;;N;;;;;
+AB05;ETHIOPIC SYLLABLE TTHE;Lo;0;L;;;;;N;;;;;
+AB06;ETHIOPIC SYLLABLE TTHO;Lo;0;L;;;;;N;;;;;
+AB09;ETHIOPIC SYLLABLE DDHU;Lo;0;L;;;;;N;;;;;
+AB0A;ETHIOPIC SYLLABLE DDHI;Lo;0;L;;;;;N;;;;;
+AB0B;ETHIOPIC SYLLABLE DDHAA;Lo;0;L;;;;;N;;;;;
+AB0C;ETHIOPIC SYLLABLE DDHEE;Lo;0;L;;;;;N;;;;;
+AB0D;ETHIOPIC SYLLABLE DDHE;Lo;0;L;;;;;N;;;;;
+AB0E;ETHIOPIC SYLLABLE DDHO;Lo;0;L;;;;;N;;;;;
+AB11;ETHIOPIC SYLLABLE DZU;Lo;0;L;;;;;N;;;;;
+AB12;ETHIOPIC SYLLABLE DZI;Lo;0;L;;;;;N;;;;;
+AB13;ETHIOPIC SYLLABLE DZAA;Lo;0;L;;;;;N;;;;;
+AB14;ETHIOPIC SYLLABLE DZEE;Lo;0;L;;;;;N;;;;;
+AB15;ETHIOPIC SYLLABLE DZE;Lo;0;L;;;;;N;;;;;
+AB16;ETHIOPIC SYLLABLE DZO;Lo;0;L;;;;;N;;;;;
+AB20;ETHIOPIC SYLLABLE CCHHA;Lo;0;L;;;;;N;;;;;
+AB21;ETHIOPIC SYLLABLE CCHHU;Lo;0;L;;;;;N;;;;;
+AB22;ETHIOPIC SYLLABLE CCHHI;Lo;0;L;;;;;N;;;;;
+AB23;ETHIOPIC SYLLABLE CCHHAA;Lo;0;L;;;;;N;;;;;
+AB24;ETHIOPIC SYLLABLE CCHHEE;Lo;0;L;;;;;N;;;;;
+AB25;ETHIOPIC SYLLABLE CCHHE;Lo;0;L;;;;;N;;;;;
+AB26;ETHIOPIC SYLLABLE CCHHO;Lo;0;L;;;;;N;;;;;
+AB28;ETHIOPIC SYLLABLE BBA;Lo;0;L;;;;;N;;;;;
+AB29;ETHIOPIC SYLLABLE BBU;Lo;0;L;;;;;N;;;;;
+AB2A;ETHIOPIC SYLLABLE BBI;Lo;0;L;;;;;N;;;;;
+AB2B;ETHIOPIC SYLLABLE BBAA;Lo;0;L;;;;;N;;;;;
+AB2C;ETHIOPIC SYLLABLE BBEE;Lo;0;L;;;;;N;;;;;
+AB2D;ETHIOPIC SYLLABLE BBE;Lo;0;L;;;;;N;;;;;
+AB2E;ETHIOPIC SYLLABLE BBO;Lo;0;L;;;;;N;;;;;
+AB30;LATIN SMALL LETTER BARRED ALPHA;Ll;0;L;;;;;N;;;;;
+AB31;LATIN SMALL LETTER A REVERSED-SCHWA;Ll;0;L;;;;;N;;;;;
+AB32;LATIN SMALL LETTER BLACKLETTER E;Ll;0;L;;;;;N;;;;;
+AB33;LATIN SMALL LETTER BARRED E;Ll;0;L;;;;;N;;;;;
+AB34;LATIN SMALL LETTER E WITH FLOURISH;Ll;0;L;;;;;N;;;;;
+AB35;LATIN SMALL LETTER LENIS F;Ll;0;L;;;;;N;;;;;
+AB36;LATIN SMALL LETTER SCRIPT G WITH CROSSED-TAIL;Ll;0;L;;;;;N;;;;;
+AB37;LATIN SMALL LETTER L WITH INVERTED LAZY S;Ll;0;L;;;;;N;;;;;
+AB38;LATIN SMALL LETTER L WITH DOUBLE MIDDLE TILDE;Ll;0;L;;;;;N;;;;;
+AB39;LATIN SMALL LETTER L WITH MIDDLE RING;Ll;0;L;;;;;N;;;;;
+AB3A;LATIN SMALL LETTER M WITH CROSSED-TAIL;Ll;0;L;;;;;N;;;;;
+AB3B;LATIN SMALL LETTER N WITH CROSSED-TAIL;Ll;0;L;;;;;N;;;;;
+AB3C;LATIN SMALL LETTER ENG WITH CROSSED-TAIL;Ll;0;L;;;;;N;;;;;
+AB3D;LATIN SMALL LETTER BLACKLETTER O;Ll;0;L;;;;;N;;;;;
+AB3E;LATIN SMALL LETTER BLACKLETTER O WITH STROKE;Ll;0;L;;;;;N;;;;;
+AB3F;LATIN SMALL LETTER OPEN O WITH STROKE;Ll;0;L;;;;;N;;;;;
+AB40;LATIN SMALL LETTER INVERTED OE;Ll;0;L;;;;;N;;;;;
+AB41;LATIN SMALL LETTER TURNED OE WITH STROKE;Ll;0;L;;;;;N;;;;;
+AB42;LATIN SMALL LETTER TURNED OE WITH HORIZONTAL STROKE;Ll;0;L;;;;;N;;;;;
+AB43;LATIN SMALL LETTER TURNED O OPEN-O;Ll;0;L;;;;;N;;;;;
+AB44;LATIN SMALL LETTER TURNED O OPEN-O WITH STROKE;Ll;0;L;;;;;N;;;;;
+AB45;LATIN SMALL LETTER STIRRUP R;Ll;0;L;;;;;N;;;;;
+AB46;LATIN LETTER SMALL CAPITAL R WITH RIGHT LEG;Ll;0;L;;;;;N;;;;;
+AB47;LATIN SMALL LETTER R WITHOUT HANDLE;Ll;0;L;;;;;N;;;;;
+AB48;LATIN SMALL LETTER DOUBLE R;Ll;0;L;;;;;N;;;;;
+AB49;LATIN SMALL LETTER R WITH CROSSED-TAIL;Ll;0;L;;;;;N;;;;;
+AB4A;LATIN SMALL LETTER DOUBLE R WITH CROSSED-TAIL;Ll;0;L;;;;;N;;;;;
+AB4B;LATIN SMALL LETTER SCRIPT R;Ll;0;L;;;;;N;;;;;
+AB4C;LATIN SMALL LETTER SCRIPT R WITH RING;Ll;0;L;;;;;N;;;;;
+AB4D;LATIN SMALL LETTER BASELINE ESH;Ll;0;L;;;;;N;;;;;
+AB4E;LATIN SMALL LETTER U WITH SHORT RIGHT LEG;Ll;0;L;;;;;N;;;;;
+AB4F;LATIN SMALL LETTER U BAR WITH SHORT RIGHT LEG;Ll;0;L;;;;;N;;;;;
+AB50;LATIN SMALL LETTER UI;Ll;0;L;;;;;N;;;;;
+AB51;LATIN SMALL LETTER TURNED UI;Ll;0;L;;;;;N;;;;;
+AB52;LATIN SMALL LETTER U WITH LEFT HOOK;Ll;0;L;;;;;N;;;;;
+AB53;LATIN SMALL LETTER CHI;Ll;0;L;;;;;N;;;A7B3;;A7B3
+AB54;LATIN SMALL LETTER CHI WITH LOW RIGHT RING;Ll;0;L;;;;;N;;;;;
+AB55;LATIN SMALL LETTER CHI WITH LOW LEFT SERIF;Ll;0;L;;;;;N;;;;;
+AB56;LATIN SMALL LETTER X WITH LOW RIGHT RING;Ll;0;L;;;;;N;;;;;
+AB57;LATIN SMALL LETTER X WITH LONG LEFT LEG;Ll;0;L;;;;;N;;;;;
+AB58;LATIN SMALL LETTER X WITH LONG LEFT LEG AND LOW RIGHT RING;Ll;0;L;;;;;N;;;;;
+AB59;LATIN SMALL LETTER X WITH LONG LEFT LEG WITH SERIF;Ll;0;L;;;;;N;;;;;
+AB5A;LATIN SMALL LETTER Y WITH SHORT RIGHT LEG;Ll;0;L;;;;;N;;;;;
+AB5B;MODIFIER BREVE WITH INVERTED BREVE;Sk;0;L;;;;;N;;;;;
+AB5C;MODIFIER LETTER SMALL HENG;Lm;0;L;<super> A727;;;;N;;;;;
+AB5D;MODIFIER LETTER SMALL L WITH INVERTED LAZY S;Lm;0;L;<super> AB37;;;;N;;;;;
+AB5E;MODIFIER LETTER SMALL L WITH MIDDLE TILDE;Lm;0;L;<super> 026B;;;;N;;;;;
+AB5F;MODIFIER LETTER SMALL U WITH LEFT HOOK;Lm;0;L;<super> AB52;;;;N;;;;;
+AB60;LATIN SMALL LETTER SAKHA YAT;Ll;0;L;;;;;N;;;;;
+AB61;LATIN SMALL LETTER IOTIFIED E;Ll;0;L;;;;;N;;;;;
+AB62;LATIN SMALL LETTER OPEN OE;Ll;0;L;;;;;N;;;;;
+AB63;LATIN SMALL LETTER UO;Ll;0;L;;;;;N;;;;;
+AB64;LATIN SMALL LETTER INVERTED ALPHA;Ll;0;L;;;;;N;;;;;
+AB65;GREEK LETTER SMALL CAPITAL OMEGA;Ll;0;L;;;;;N;;;;;
+AB70;CHEROKEE SMALL LETTER A;Ll;0;L;;;;;N;;;13A0;;13A0
+AB71;CHEROKEE SMALL LETTER E;Ll;0;L;;;;;N;;;13A1;;13A1
+AB72;CHEROKEE SMALL LETTER I;Ll;0;L;;;;;N;;;13A2;;13A2
+AB73;CHEROKEE SMALL LETTER O;Ll;0;L;;;;;N;;;13A3;;13A3
+AB74;CHEROKEE SMALL LETTER U;Ll;0;L;;;;;N;;;13A4;;13A4
+AB75;CHEROKEE SMALL LETTER V;Ll;0;L;;;;;N;;;13A5;;13A5
+AB76;CHEROKEE SMALL LETTER GA;Ll;0;L;;;;;N;;;13A6;;13A6
+AB77;CHEROKEE SMALL LETTER KA;Ll;0;L;;;;;N;;;13A7;;13A7
+AB78;CHEROKEE SMALL LETTER GE;Ll;0;L;;;;;N;;;13A8;;13A8
+AB79;CHEROKEE SMALL LETTER GI;Ll;0;L;;;;;N;;;13A9;;13A9
+AB7A;CHEROKEE SMALL LETTER GO;Ll;0;L;;;;;N;;;13AA;;13AA
+AB7B;CHEROKEE SMALL LETTER GU;Ll;0;L;;;;;N;;;13AB;;13AB
+AB7C;CHEROKEE SMALL LETTER GV;Ll;0;L;;;;;N;;;13AC;;13AC
+AB7D;CHEROKEE SMALL LETTER HA;Ll;0;L;;;;;N;;;13AD;;13AD
+AB7E;CHEROKEE SMALL LETTER HE;Ll;0;L;;;;;N;;;13AE;;13AE
+AB7F;CHEROKEE SMALL LETTER HI;Ll;0;L;;;;;N;;;13AF;;13AF
+AB80;CHEROKEE SMALL LETTER HO;Ll;0;L;;;;;N;;;13B0;;13B0
+AB81;CHEROKEE SMALL LETTER HU;Ll;0;L;;;;;N;;;13B1;;13B1
+AB82;CHEROKEE SMALL LETTER HV;Ll;0;L;;;;;N;;;13B2;;13B2
+AB83;CHEROKEE SMALL LETTER LA;Ll;0;L;;;;;N;;;13B3;;13B3
+AB84;CHEROKEE SMALL LETTER LE;Ll;0;L;;;;;N;;;13B4;;13B4
+AB85;CHEROKEE SMALL LETTER LI;Ll;0;L;;;;;N;;;13B5;;13B5
+AB86;CHEROKEE SMALL LETTER LO;Ll;0;L;;;;;N;;;13B6;;13B6
+AB87;CHEROKEE SMALL LETTER LU;Ll;0;L;;;;;N;;;13B7;;13B7
+AB88;CHEROKEE SMALL LETTER LV;Ll;0;L;;;;;N;;;13B8;;13B8
+AB89;CHEROKEE SMALL LETTER MA;Ll;0;L;;;;;N;;;13B9;;13B9
+AB8A;CHEROKEE SMALL LETTER ME;Ll;0;L;;;;;N;;;13BA;;13BA
+AB8B;CHEROKEE SMALL LETTER MI;Ll;0;L;;;;;N;;;13BB;;13BB
+AB8C;CHEROKEE SMALL LETTER MO;Ll;0;L;;;;;N;;;13BC;;13BC
+AB8D;CHEROKEE SMALL LETTER MU;Ll;0;L;;;;;N;;;13BD;;13BD
+AB8E;CHEROKEE SMALL LETTER NA;Ll;0;L;;;;;N;;;13BE;;13BE
+AB8F;CHEROKEE SMALL LETTER HNA;Ll;0;L;;;;;N;;;13BF;;13BF
+AB90;CHEROKEE SMALL LETTER NAH;Ll;0;L;;;;;N;;;13C0;;13C0
+AB91;CHEROKEE SMALL LETTER NE;Ll;0;L;;;;;N;;;13C1;;13C1
+AB92;CHEROKEE SMALL LETTER NI;Ll;0;L;;;;;N;;;13C2;;13C2
+AB93;CHEROKEE SMALL LETTER NO;Ll;0;L;;;;;N;;;13C3;;13C3
+AB94;CHEROKEE SMALL LETTER NU;Ll;0;L;;;;;N;;;13C4;;13C4
+AB95;CHEROKEE SMALL LETTER NV;Ll;0;L;;;;;N;;;13C5;;13C5
+AB96;CHEROKEE SMALL LETTER QUA;Ll;0;L;;;;;N;;;13C6;;13C6
+AB97;CHEROKEE SMALL LETTER QUE;Ll;0;L;;;;;N;;;13C7;;13C7
+AB98;CHEROKEE SMALL LETTER QUI;Ll;0;L;;;;;N;;;13C8;;13C8
+AB99;CHEROKEE SMALL LETTER QUO;Ll;0;L;;;;;N;;;13C9;;13C9
+AB9A;CHEROKEE SMALL LETTER QUU;Ll;0;L;;;;;N;;;13CA;;13CA
+AB9B;CHEROKEE SMALL LETTER QUV;Ll;0;L;;;;;N;;;13CB;;13CB
+AB9C;CHEROKEE SMALL LETTER SA;Ll;0;L;;;;;N;;;13CC;;13CC
+AB9D;CHEROKEE SMALL LETTER S;Ll;0;L;;;;;N;;;13CD;;13CD
+AB9E;CHEROKEE SMALL LETTER SE;Ll;0;L;;;;;N;;;13CE;;13CE
+AB9F;CHEROKEE SMALL LETTER SI;Ll;0;L;;;;;N;;;13CF;;13CF
+ABA0;CHEROKEE SMALL LETTER SO;Ll;0;L;;;;;N;;;13D0;;13D0
+ABA1;CHEROKEE SMALL LETTER SU;Ll;0;L;;;;;N;;;13D1;;13D1
+ABA2;CHEROKEE SMALL LETTER SV;Ll;0;L;;;;;N;;;13D2;;13D2
+ABA3;CHEROKEE SMALL LETTER DA;Ll;0;L;;;;;N;;;13D3;;13D3
+ABA4;CHEROKEE SMALL LETTER TA;Ll;0;L;;;;;N;;;13D4;;13D4
+ABA5;CHEROKEE SMALL LETTER DE;Ll;0;L;;;;;N;;;13D5;;13D5
+ABA6;CHEROKEE SMALL LETTER TE;Ll;0;L;;;;;N;;;13D6;;13D6
+ABA7;CHEROKEE SMALL LETTER DI;Ll;0;L;;;;;N;;;13D7;;13D7
+ABA8;CHEROKEE SMALL LETTER TI;Ll;0;L;;;;;N;;;13D8;;13D8
+ABA9;CHEROKEE SMALL LETTER DO;Ll;0;L;;;;;N;;;13D9;;13D9
+ABAA;CHEROKEE SMALL LETTER DU;Ll;0;L;;;;;N;;;13DA;;13DA
+ABAB;CHEROKEE SMALL LETTER DV;Ll;0;L;;;;;N;;;13DB;;13DB
+ABAC;CHEROKEE SMALL LETTER DLA;Ll;0;L;;;;;N;;;13DC;;13DC
+ABAD;CHEROKEE SMALL LETTER TLA;Ll;0;L;;;;;N;;;13DD;;13DD
+ABAE;CHEROKEE SMALL LETTER TLE;Ll;0;L;;;;;N;;;13DE;;13DE
+ABAF;CHEROKEE SMALL LETTER TLI;Ll;0;L;;;;;N;;;13DF;;13DF
+ABB0;CHEROKEE SMALL LETTER TLO;Ll;0;L;;;;;N;;;13E0;;13E0
+ABB1;CHEROKEE SMALL LETTER TLU;Ll;0;L;;;;;N;;;13E1;;13E1
+ABB2;CHEROKEE SMALL LETTER TLV;Ll;0;L;;;;;N;;;13E2;;13E2
+ABB3;CHEROKEE SMALL LETTER TSA;Ll;0;L;;;;;N;;;13E3;;13E3
+ABB4;CHEROKEE SMALL LETTER TSE;Ll;0;L;;;;;N;;;13E4;;13E4
+ABB5;CHEROKEE SMALL LETTER TSI;Ll;0;L;;;;;N;;;13E5;;13E5
+ABB6;CHEROKEE SMALL LETTER TSO;Ll;0;L;;;;;N;;;13E6;;13E6
+ABB7;CHEROKEE SMALL LETTER TSU;Ll;0;L;;;;;N;;;13E7;;13E7
+ABB8;CHEROKEE SMALL LETTER TSV;Ll;0;L;;;;;N;;;13E8;;13E8
+ABB9;CHEROKEE SMALL LETTER WA;Ll;0;L;;;;;N;;;13E9;;13E9
+ABBA;CHEROKEE SMALL LETTER WE;Ll;0;L;;;;;N;;;13EA;;13EA
+ABBB;CHEROKEE SMALL LETTER WI;Ll;0;L;;;;;N;;;13EB;;13EB
+ABBC;CHEROKEE SMALL LETTER WO;Ll;0;L;;;;;N;;;13EC;;13EC
+ABBD;CHEROKEE SMALL LETTER WU;Ll;0;L;;;;;N;;;13ED;;13ED
+ABBE;CHEROKEE SMALL LETTER WV;Ll;0;L;;;;;N;;;13EE;;13EE
+ABBF;CHEROKEE SMALL LETTER YA;Ll;0;L;;;;;N;;;13EF;;13EF
ABC0;MEETEI MAYEK LETTER KOK;Lo;0;L;;;;;N;;;;;
ABC1;MEETEI MAYEK LETTER SAM;Lo;0;L;;;;;N;;;;;
ABC2;MEETEI MAYEK LETTER LAI;Lo;0;L;;;;;N;;;;;
@@ -14399,6 +15271,8 @@ FA2A;CJK COMPATIBILITY IDEOGRAPH-FA2A;Lo;0;L;98EF;;;;N;;;;;
FA2B;CJK COMPATIBILITY IDEOGRAPH-FA2B;Lo;0;L;98FC;;;;N;;;;;
FA2C;CJK COMPATIBILITY IDEOGRAPH-FA2C;Lo;0;L;9928;;;;N;;;;;
FA2D;CJK COMPATIBILITY IDEOGRAPH-FA2D;Lo;0;L;9DB4;;;;N;;;;;
+FA2E;CJK COMPATIBILITY IDEOGRAPH-FA2E;Lo;0;L;90DE;;;;N;;;;;
+FA2F;CJK COMPATIBILITY IDEOGRAPH-FA2F;Lo;0;L;96B7;;;;N;;;;;
FA30;CJK COMPATIBILITY IDEOGRAPH-FA30;Lo;0;L;4FAE;;;;N;;;;;
FA31;CJK COMPATIBILITY IDEOGRAPH-FA31;Lo;0;L;50E7;;;;N;;;;;
FA32;CJK COMPATIBILITY IDEOGRAPH-FA32;Lo;0;L;514D;;;;N;;;;;
@@ -14723,6 +15597,22 @@ FBAE;ARABIC LETTER YEH BARREE ISOLATED FORM;Lo;0;AL;<isolated> 06D2;;;;N;;;;;
FBAF;ARABIC LETTER YEH BARREE FINAL FORM;Lo;0;AL;<final> 06D2;;;;N;;;;;
FBB0;ARABIC LETTER YEH BARREE WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 06D3;;;;N;;;;;
FBB1;ARABIC LETTER YEH BARREE WITH HAMZA ABOVE FINAL FORM;Lo;0;AL;<final> 06D3;;;;N;;;;;
+FBB2;ARABIC SYMBOL DOT ABOVE;Sk;0;AL;;;;;N;;;;;
+FBB3;ARABIC SYMBOL DOT BELOW;Sk;0;AL;;;;;N;;;;;
+FBB4;ARABIC SYMBOL TWO DOTS ABOVE;Sk;0;AL;;;;;N;;;;;
+FBB5;ARABIC SYMBOL TWO DOTS BELOW;Sk;0;AL;;;;;N;;;;;
+FBB6;ARABIC SYMBOL THREE DOTS ABOVE;Sk;0;AL;;;;;N;;;;;
+FBB7;ARABIC SYMBOL THREE DOTS BELOW;Sk;0;AL;;;;;N;;;;;
+FBB8;ARABIC SYMBOL THREE DOTS POINTING DOWNWARDS ABOVE;Sk;0;AL;;;;;N;;;;;
+FBB9;ARABIC SYMBOL THREE DOTS POINTING DOWNWARDS BELOW;Sk;0;AL;;;;;N;;;;;
+FBBA;ARABIC SYMBOL FOUR DOTS ABOVE;Sk;0;AL;;;;;N;;;;;
+FBBB;ARABIC SYMBOL FOUR DOTS BELOW;Sk;0;AL;;;;;N;;;;;
+FBBC;ARABIC SYMBOL DOUBLE VERTICAL BAR BELOW;Sk;0;AL;;;;;N;;;;;
+FBBD;ARABIC SYMBOL TWO DOTS VERTICALLY ABOVE;Sk;0;AL;;;;;N;;;;;
+FBBE;ARABIC SYMBOL TWO DOTS VERTICALLY BELOW;Sk;0;AL;;;;;N;;;;;
+FBBF;ARABIC SYMBOL RING;Sk;0;AL;;;;;N;;;;;
+FBC0;ARABIC SYMBOL SMALL TAH ABOVE;Sk;0;AL;;;;;N;;;;;
+FBC1;ARABIC SYMBOL SMALL TAH BELOW;Sk;0;AL;;;;;N;;;;;
FBD3;ARABIC LETTER NG ISOLATED FORM;Lo;0;AL;<isolated> 06AD;;;;N;;;;;
FBD4;ARABIC LETTER NG FINAL FORM;Lo;0;AL;<final> 06AD;;;;N;;;;;
FBD5;ARABIC LETTER NG INITIAL FORM;Lo;0;AL;<initial> 06AD;;;;N;;;;;
@@ -15086,8 +15976,8 @@ FD3A;ARABIC LIGATURE TAH WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0637 0645;;;;N;;
FD3B;ARABIC LIGATURE ZAH WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0638 0645;;;;N;;;;;
FD3C;ARABIC LIGATURE ALEF WITH FATHATAN FINAL FORM;Lo;0;AL;<final> 0627 064B;;;;N;;;;;
FD3D;ARABIC LIGATURE ALEF WITH FATHATAN ISOLATED FORM;Lo;0;AL;<isolated> 0627 064B;;;;N;;;;;
-FD3E;ORNATE LEFT PARENTHESIS;Ps;0;ON;;;;;N;;;;;
-FD3F;ORNATE RIGHT PARENTHESIS;Pe;0;ON;;;;;N;;;;;
+FD3E;ORNATE LEFT PARENTHESIS;Pe;0;ON;;;;;N;;;;;
+FD3F;ORNATE RIGHT PARENTHESIS;Ps;0;ON;;;;;N;;;;;
FD50;ARABIC LIGATURE TEH WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 062A 062C 0645;;;;N;;;;;
FD51;ARABIC LIGATURE TEH WITH HAH WITH JEEM FINAL FORM;Lo;0;AL;<final> 062A 062D 062C;;;;N;;;;;
FD52;ARABIC LIGATURE TEH WITH HAH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 062A 062D 062C;;;;N;;;;;
@@ -15253,6 +16143,15 @@ FE23;COMBINING DOUBLE TILDE RIGHT HALF;Mn;230;NSM;;;;;N;;;;;
FE24;COMBINING MACRON LEFT HALF;Mn;230;NSM;;;;;N;;;;;
FE25;COMBINING MACRON RIGHT HALF;Mn;230;NSM;;;;;N;;;;;
FE26;COMBINING CONJOINING MACRON;Mn;230;NSM;;;;;N;;;;;
+FE27;COMBINING LIGATURE LEFT HALF BELOW;Mn;220;NSM;;;;;N;;;;;
+FE28;COMBINING LIGATURE RIGHT HALF BELOW;Mn;220;NSM;;;;;N;;;;;
+FE29;COMBINING TILDE LEFT HALF BELOW;Mn;220;NSM;;;;;N;;;;;
+FE2A;COMBINING TILDE RIGHT HALF BELOW;Mn;220;NSM;;;;;N;;;;;
+FE2B;COMBINING MACRON LEFT HALF BELOW;Mn;220;NSM;;;;;N;;;;;
+FE2C;COMBINING MACRON RIGHT HALF BELOW;Mn;220;NSM;;;;;N;;;;;
+FE2D;COMBINING CONJOINING MACRON BELOW;Mn;220;NSM;;;;;N;;;;;
+FE2E;COMBINING CYRILLIC TITLO LEFT HALF;Mn;230;NSM;;;;;N;;;;;
+FE2F;COMBINING CYRILLIC TITLO RIGHT HALF;Mn;230;NSM;;;;;N;;;;;
FE30;PRESENTATION FORM FOR VERTICAL TWO DOT LEADER;Po;0;ON;<vertical> 2025;;;;N;GLYPH FOR VERTICAL TWO DOT LEADER;;;;
FE31;PRESENTATION FORM FOR VERTICAL EM DASH;Pd;0;ON;<vertical> 2014;;;;N;GLYPH FOR VERTICAL EM DASH;;;;
FE32;PRESENTATION FORM FOR VERTICAL EN DASH;Pd;0;ON;<vertical> 2013;;;;N;GLYPH FOR VERTICAL EN DASH;;;;
@@ -15895,7 +16794,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
100FA;LINEAR B IDEOGRAM VESSEL B305;Lo;0;L;;;;;N;;;;;
10100;AEGEAN WORD SEPARATOR LINE;Po;0;L;;;;;N;;;;;
10101;AEGEAN WORD SEPARATOR DOT;Po;0;ON;;;;;N;;;;;
-10102;AEGEAN CHECK MARK;So;0;L;;;;;N;;;;;
+10102;AEGEAN CHECK MARK;Po;0;L;;;;;N;;;;;
10107;AEGEAN NUMBER ONE;No;0;L;;;;1;N;;;;;
10108;AEGEAN NUMBER TWO;No;0;L;;;;2;N;;;;;
10109;AEGEAN NUMBER THREE;No;0;L;;;;3;N;;;;;
@@ -16025,6 +16924,10 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
10188;GREEK GRAMMA SIGN;So;0;ON;;;;;N;;;;;
10189;GREEK TRYBLION BASE SIGN;So;0;ON;;;;;N;;;;;
1018A;GREEK ZERO SIGN;No;0;ON;;;;0;N;;;;;
+1018B;GREEK ONE QUARTER SIGN;No;0;ON;;;;1/4;N;;;;;
+1018C;GREEK SINUSOID SIGN;So;0;ON;;;;;N;;;;;
+1018D;GREEK INDICTION SIGN;So;0;L;;;;;N;;;;;
+1018E;NOMISMA SIGN;So;0;L;;;;;N;;;;;
10190;ROMAN SEXTANS SIGN;So;0;ON;;;;;N;;;;;
10191;ROMAN UNCIA SIGN;So;0;ON;;;;;N;;;;;
10192;ROMAN SEMUNCIA SIGN;So;0;ON;;;;;N;;;;;
@@ -16037,6 +16940,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
10199;ROMAN DUPONDIUS SIGN;So;0;ON;;;;;N;;;;;
1019A;ROMAN AS SIGN;So;0;ON;;;;;N;;;;;
1019B;ROMAN CENTURIAL SIGN;So;0;ON;;;;;N;;;;;
+101A0;GREEK SYMBOL TAU RHO;So;0;ON;;;;;N;;;;;
101D0;PHAISTOS DISC SIGN PEDESTRIAN;So;0;L;;;;;N;;;;;
101D1;PHAISTOS DISC SIGN PLUMED HEAD;So;0;L;;;;;N;;;;;
101D2;PHAISTOS DISC SIGN TATTOOED HEAD;So;0;L;;;;;N;;;;;
@@ -16161,6 +17065,34 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
102CE;CARIAN LETTER LD2;Lo;0;L;;;;;N;;;;;
102CF;CARIAN LETTER E2;Lo;0;L;;;;;N;;;;;
102D0;CARIAN LETTER UUU3;Lo;0;L;;;;;N;;;;;
+102E0;COPTIC EPACT THOUSANDS MARK;Mn;220;NSM;;;;;N;;;;;
+102E1;COPTIC EPACT DIGIT ONE;No;0;EN;;;;1;N;;;;;
+102E2;COPTIC EPACT DIGIT TWO;No;0;EN;;;;2;N;;;;;
+102E3;COPTIC EPACT DIGIT THREE;No;0;EN;;;;3;N;;;;;
+102E4;COPTIC EPACT DIGIT FOUR;No;0;EN;;;;4;N;;;;;
+102E5;COPTIC EPACT DIGIT FIVE;No;0;EN;;;;5;N;;;;;
+102E6;COPTIC EPACT DIGIT SIX;No;0;EN;;;;6;N;;;;;
+102E7;COPTIC EPACT DIGIT SEVEN;No;0;EN;;;;7;N;;;;;
+102E8;COPTIC EPACT DIGIT EIGHT;No;0;EN;;;;8;N;;;;;
+102E9;COPTIC EPACT DIGIT NINE;No;0;EN;;;;9;N;;;;;
+102EA;COPTIC EPACT NUMBER TEN;No;0;EN;;;;10;N;;;;;
+102EB;COPTIC EPACT NUMBER TWENTY;No;0;EN;;;;20;N;;;;;
+102EC;COPTIC EPACT NUMBER THIRTY;No;0;EN;;;;30;N;;;;;
+102ED;COPTIC EPACT NUMBER FORTY;No;0;EN;;;;40;N;;;;;
+102EE;COPTIC EPACT NUMBER FIFTY;No;0;EN;;;;50;N;;;;;
+102EF;COPTIC EPACT NUMBER SIXTY;No;0;EN;;;;60;N;;;;;
+102F0;COPTIC EPACT NUMBER SEVENTY;No;0;EN;;;;70;N;;;;;
+102F1;COPTIC EPACT NUMBER EIGHTY;No;0;EN;;;;80;N;;;;;
+102F2;COPTIC EPACT NUMBER NINETY;No;0;EN;;;;90;N;;;;;
+102F3;COPTIC EPACT NUMBER ONE HUNDRED;No;0;EN;;;;100;N;;;;;
+102F4;COPTIC EPACT NUMBER TWO HUNDRED;No;0;EN;;;;200;N;;;;;
+102F5;COPTIC EPACT NUMBER THREE HUNDRED;No;0;EN;;;;300;N;;;;;
+102F6;COPTIC EPACT NUMBER FOUR HUNDRED;No;0;EN;;;;400;N;;;;;
+102F7;COPTIC EPACT NUMBER FIVE HUNDRED;No;0;EN;;;;500;N;;;;;
+102F8;COPTIC EPACT NUMBER SIX HUNDRED;No;0;EN;;;;600;N;;;;;
+102F9;COPTIC EPACT NUMBER SEVEN HUNDRED;No;0;EN;;;;700;N;;;;;
+102FA;COPTIC EPACT NUMBER EIGHT HUNDRED;No;0;EN;;;;800;N;;;;;
+102FB;COPTIC EPACT NUMBER NINE HUNDRED;No;0;EN;;;;900;N;;;;;
10300;OLD ITALIC LETTER A;Lo;0;L;;;;;N;;;;;
10301;OLD ITALIC LETTER BE;Lo;0;L;;;;;N;;;;;
10302;OLD ITALIC LETTER KE;Lo;0;L;;;;;N;;;;;
@@ -16192,10 +17124,14 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1031C;OLD ITALIC LETTER CHE;Lo;0;L;;;;;N;;;;;
1031D;OLD ITALIC LETTER II;Lo;0;L;;;;;N;;;;;
1031E;OLD ITALIC LETTER UU;Lo;0;L;;;;;N;;;;;
+1031F;OLD ITALIC LETTER ESS;Lo;0;L;;;;;N;;;;;
10320;OLD ITALIC NUMERAL ONE;No;0;L;;;;1;N;;;;;
10321;OLD ITALIC NUMERAL FIVE;No;0;L;;;;5;N;;;;;
10322;OLD ITALIC NUMERAL TEN;No;0;L;;;;10;N;;;;;
10323;OLD ITALIC NUMERAL FIFTY;No;0;L;;;;50;N;;;;;
+1032D;OLD ITALIC LETTER YE;Lo;0;L;;;;;N;;;;;
+1032E;OLD ITALIC LETTER NORTHERN TSE;Lo;0;L;;;;;N;;;;;
+1032F;OLD ITALIC LETTER SOUTHERN TSE;Lo;0;L;;;;;N;;;;;
10330;GOTHIC LETTER AHSA;Lo;0;L;;;;;N;;;;;
10331;GOTHIC LETTER BAIRKAN;Lo;0;L;;;;;N;;;;;
10332;GOTHIC LETTER GIBA;Lo;0;L;;;;;N;;;;;
@@ -16223,6 +17159,49 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
10348;GOTHIC LETTER HWAIR;Lo;0;L;;;;;N;;;;;
10349;GOTHIC LETTER OTHAL;Lo;0;L;;;;;N;;;;;
1034A;GOTHIC LETTER NINE HUNDRED;Nl;0;L;;;;900;N;;;;;
+10350;OLD PERMIC LETTER AN;Lo;0;L;;;;;N;;;;;
+10351;OLD PERMIC LETTER BUR;Lo;0;L;;;;;N;;;;;
+10352;OLD PERMIC LETTER GAI;Lo;0;L;;;;;N;;;;;
+10353;OLD PERMIC LETTER DOI;Lo;0;L;;;;;N;;;;;
+10354;OLD PERMIC LETTER E;Lo;0;L;;;;;N;;;;;
+10355;OLD PERMIC LETTER ZHOI;Lo;0;L;;;;;N;;;;;
+10356;OLD PERMIC LETTER DZHOI;Lo;0;L;;;;;N;;;;;
+10357;OLD PERMIC LETTER ZATA;Lo;0;L;;;;;N;;;;;
+10358;OLD PERMIC LETTER DZITA;Lo;0;L;;;;;N;;;;;
+10359;OLD PERMIC LETTER I;Lo;0;L;;;;;N;;;;;
+1035A;OLD PERMIC LETTER KOKE;Lo;0;L;;;;;N;;;;;
+1035B;OLD PERMIC LETTER LEI;Lo;0;L;;;;;N;;;;;
+1035C;OLD PERMIC LETTER MENOE;Lo;0;L;;;;;N;;;;;
+1035D;OLD PERMIC LETTER NENOE;Lo;0;L;;;;;N;;;;;
+1035E;OLD PERMIC LETTER VOOI;Lo;0;L;;;;;N;;;;;
+1035F;OLD PERMIC LETTER PEEI;Lo;0;L;;;;;N;;;;;
+10360;OLD PERMIC LETTER REI;Lo;0;L;;;;;N;;;;;
+10361;OLD PERMIC LETTER SII;Lo;0;L;;;;;N;;;;;
+10362;OLD PERMIC LETTER TAI;Lo;0;L;;;;;N;;;;;
+10363;OLD PERMIC LETTER U;Lo;0;L;;;;;N;;;;;
+10364;OLD PERMIC LETTER CHERY;Lo;0;L;;;;;N;;;;;
+10365;OLD PERMIC LETTER SHOOI;Lo;0;L;;;;;N;;;;;
+10366;OLD PERMIC LETTER SHCHOOI;Lo;0;L;;;;;N;;;;;
+10367;OLD PERMIC LETTER YRY;Lo;0;L;;;;;N;;;;;
+10368;OLD PERMIC LETTER YERU;Lo;0;L;;;;;N;;;;;
+10369;OLD PERMIC LETTER O;Lo;0;L;;;;;N;;;;;
+1036A;OLD PERMIC LETTER OO;Lo;0;L;;;;;N;;;;;
+1036B;OLD PERMIC LETTER EF;Lo;0;L;;;;;N;;;;;
+1036C;OLD PERMIC LETTER HA;Lo;0;L;;;;;N;;;;;
+1036D;OLD PERMIC LETTER TSIU;Lo;0;L;;;;;N;;;;;
+1036E;OLD PERMIC LETTER VER;Lo;0;L;;;;;N;;;;;
+1036F;OLD PERMIC LETTER YER;Lo;0;L;;;;;N;;;;;
+10370;OLD PERMIC LETTER YERI;Lo;0;L;;;;;N;;;;;
+10371;OLD PERMIC LETTER YAT;Lo;0;L;;;;;N;;;;;
+10372;OLD PERMIC LETTER IE;Lo;0;L;;;;;N;;;;;
+10373;OLD PERMIC LETTER YU;Lo;0;L;;;;;N;;;;;
+10374;OLD PERMIC LETTER YA;Lo;0;L;;;;;N;;;;;
+10375;OLD PERMIC LETTER IA;Lo;0;L;;;;;N;;;;;
+10376;COMBINING OLD PERMIC LETTER AN;Mn;230;NSM;;;;;N;;;;;
+10377;COMBINING OLD PERMIC LETTER DOI;Mn;230;NSM;;;;;N;;;;;
+10378;COMBINING OLD PERMIC LETTER ZATA;Mn;230;NSM;;;;;N;;;;;
+10379;COMBINING OLD PERMIC LETTER NENOE;Mn;230;NSM;;;;;N;;;;;
+1037A;COMBINING OLD PERMIC LETTER SII;Mn;230;NSM;;;;;N;;;;;
10380;UGARITIC LETTER ALPA;Lo;0;L;;;;;N;;;;;
10381;UGARITIC LETTER BETA;Lo;0;L;;;;;N;;;;;
10382;UGARITIC LETTER GAMLA;Lo;0;L;;;;;N;;;;;
@@ -16472,6 +17451,512 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
104A7;OSMANYA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
104A8;OSMANYA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
104A9;OSMANYA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+104B0;OSAGE CAPITAL LETTER A;Lu;0;L;;;;;N;;;;104D8;
+104B1;OSAGE CAPITAL LETTER AI;Lu;0;L;;;;;N;;;;104D9;
+104B2;OSAGE CAPITAL LETTER AIN;Lu;0;L;;;;;N;;;;104DA;
+104B3;OSAGE CAPITAL LETTER AH;Lu;0;L;;;;;N;;;;104DB;
+104B4;OSAGE CAPITAL LETTER BRA;Lu;0;L;;;;;N;;;;104DC;
+104B5;OSAGE CAPITAL LETTER CHA;Lu;0;L;;;;;N;;;;104DD;
+104B6;OSAGE CAPITAL LETTER EHCHA;Lu;0;L;;;;;N;;;;104DE;
+104B7;OSAGE CAPITAL LETTER E;Lu;0;L;;;;;N;;;;104DF;
+104B8;OSAGE CAPITAL LETTER EIN;Lu;0;L;;;;;N;;;;104E0;
+104B9;OSAGE CAPITAL LETTER HA;Lu;0;L;;;;;N;;;;104E1;
+104BA;OSAGE CAPITAL LETTER HYA;Lu;0;L;;;;;N;;;;104E2;
+104BB;OSAGE CAPITAL LETTER I;Lu;0;L;;;;;N;;;;104E3;
+104BC;OSAGE CAPITAL LETTER KA;Lu;0;L;;;;;N;;;;104E4;
+104BD;OSAGE CAPITAL LETTER EHKA;Lu;0;L;;;;;N;;;;104E5;
+104BE;OSAGE CAPITAL LETTER KYA;Lu;0;L;;;;;N;;;;104E6;
+104BF;OSAGE CAPITAL LETTER LA;Lu;0;L;;;;;N;;;;104E7;
+104C0;OSAGE CAPITAL LETTER MA;Lu;0;L;;;;;N;;;;104E8;
+104C1;OSAGE CAPITAL LETTER NA;Lu;0;L;;;;;N;;;;104E9;
+104C2;OSAGE CAPITAL LETTER O;Lu;0;L;;;;;N;;;;104EA;
+104C3;OSAGE CAPITAL LETTER OIN;Lu;0;L;;;;;N;;;;104EB;
+104C4;OSAGE CAPITAL LETTER PA;Lu;0;L;;;;;N;;;;104EC;
+104C5;OSAGE CAPITAL LETTER EHPA;Lu;0;L;;;;;N;;;;104ED;
+104C6;OSAGE CAPITAL LETTER SA;Lu;0;L;;;;;N;;;;104EE;
+104C7;OSAGE CAPITAL LETTER SHA;Lu;0;L;;;;;N;;;;104EF;
+104C8;OSAGE CAPITAL LETTER TA;Lu;0;L;;;;;N;;;;104F0;
+104C9;OSAGE CAPITAL LETTER EHTA;Lu;0;L;;;;;N;;;;104F1;
+104CA;OSAGE CAPITAL LETTER TSA;Lu;0;L;;;;;N;;;;104F2;
+104CB;OSAGE CAPITAL LETTER EHTSA;Lu;0;L;;;;;N;;;;104F3;
+104CC;OSAGE CAPITAL LETTER TSHA;Lu;0;L;;;;;N;;;;104F4;
+104CD;OSAGE CAPITAL LETTER DHA;Lu;0;L;;;;;N;;;;104F5;
+104CE;OSAGE CAPITAL LETTER U;Lu;0;L;;;;;N;;;;104F6;
+104CF;OSAGE CAPITAL LETTER WA;Lu;0;L;;;;;N;;;;104F7;
+104D0;OSAGE CAPITAL LETTER KHA;Lu;0;L;;;;;N;;;;104F8;
+104D1;OSAGE CAPITAL LETTER GHA;Lu;0;L;;;;;N;;;;104F9;
+104D2;OSAGE CAPITAL LETTER ZA;Lu;0;L;;;;;N;;;;104FA;
+104D3;OSAGE CAPITAL LETTER ZHA;Lu;0;L;;;;;N;;;;104FB;
+104D8;OSAGE SMALL LETTER A;Ll;0;L;;;;;N;;;104B0;;104B0
+104D9;OSAGE SMALL LETTER AI;Ll;0;L;;;;;N;;;104B1;;104B1
+104DA;OSAGE SMALL LETTER AIN;Ll;0;L;;;;;N;;;104B2;;104B2
+104DB;OSAGE SMALL LETTER AH;Ll;0;L;;;;;N;;;104B3;;104B3
+104DC;OSAGE SMALL LETTER BRA;Ll;0;L;;;;;N;;;104B4;;104B4
+104DD;OSAGE SMALL LETTER CHA;Ll;0;L;;;;;N;;;104B5;;104B5
+104DE;OSAGE SMALL LETTER EHCHA;Ll;0;L;;;;;N;;;104B6;;104B6
+104DF;OSAGE SMALL LETTER E;Ll;0;L;;;;;N;;;104B7;;104B7
+104E0;OSAGE SMALL LETTER EIN;Ll;0;L;;;;;N;;;104B8;;104B8
+104E1;OSAGE SMALL LETTER HA;Ll;0;L;;;;;N;;;104B9;;104B9
+104E2;OSAGE SMALL LETTER HYA;Ll;0;L;;;;;N;;;104BA;;104BA
+104E3;OSAGE SMALL LETTER I;Ll;0;L;;;;;N;;;104BB;;104BB
+104E4;OSAGE SMALL LETTER KA;Ll;0;L;;;;;N;;;104BC;;104BC
+104E5;OSAGE SMALL LETTER EHKA;Ll;0;L;;;;;N;;;104BD;;104BD
+104E6;OSAGE SMALL LETTER KYA;Ll;0;L;;;;;N;;;104BE;;104BE
+104E7;OSAGE SMALL LETTER LA;Ll;0;L;;;;;N;;;104BF;;104BF
+104E8;OSAGE SMALL LETTER MA;Ll;0;L;;;;;N;;;104C0;;104C0
+104E9;OSAGE SMALL LETTER NA;Ll;0;L;;;;;N;;;104C1;;104C1
+104EA;OSAGE SMALL LETTER O;Ll;0;L;;;;;N;;;104C2;;104C2
+104EB;OSAGE SMALL LETTER OIN;Ll;0;L;;;;;N;;;104C3;;104C3
+104EC;OSAGE SMALL LETTER PA;Ll;0;L;;;;;N;;;104C4;;104C4
+104ED;OSAGE SMALL LETTER EHPA;Ll;0;L;;;;;N;;;104C5;;104C5
+104EE;OSAGE SMALL LETTER SA;Ll;0;L;;;;;N;;;104C6;;104C6
+104EF;OSAGE SMALL LETTER SHA;Ll;0;L;;;;;N;;;104C7;;104C7
+104F0;OSAGE SMALL LETTER TA;Ll;0;L;;;;;N;;;104C8;;104C8
+104F1;OSAGE SMALL LETTER EHTA;Ll;0;L;;;;;N;;;104C9;;104C9
+104F2;OSAGE SMALL LETTER TSA;Ll;0;L;;;;;N;;;104CA;;104CA
+104F3;OSAGE SMALL LETTER EHTSA;Ll;0;L;;;;;N;;;104CB;;104CB
+104F4;OSAGE SMALL LETTER TSHA;Ll;0;L;;;;;N;;;104CC;;104CC
+104F5;OSAGE SMALL LETTER DHA;Ll;0;L;;;;;N;;;104CD;;104CD
+104F6;OSAGE SMALL LETTER U;Ll;0;L;;;;;N;;;104CE;;104CE
+104F7;OSAGE SMALL LETTER WA;Ll;0;L;;;;;N;;;104CF;;104CF
+104F8;OSAGE SMALL LETTER KHA;Ll;0;L;;;;;N;;;104D0;;104D0
+104F9;OSAGE SMALL LETTER GHA;Ll;0;L;;;;;N;;;104D1;;104D1
+104FA;OSAGE SMALL LETTER ZA;Ll;0;L;;;;;N;;;104D2;;104D2
+104FB;OSAGE SMALL LETTER ZHA;Ll;0;L;;;;;N;;;104D3;;104D3
+10500;ELBASAN LETTER A;Lo;0;L;;;;;N;;;;;
+10501;ELBASAN LETTER BE;Lo;0;L;;;;;N;;;;;
+10502;ELBASAN LETTER CE;Lo;0;L;;;;;N;;;;;
+10503;ELBASAN LETTER CHE;Lo;0;L;;;;;N;;;;;
+10504;ELBASAN LETTER DE;Lo;0;L;;;;;N;;;;;
+10505;ELBASAN LETTER NDE;Lo;0;L;;;;;N;;;;;
+10506;ELBASAN LETTER DHE;Lo;0;L;;;;;N;;;;;
+10507;ELBASAN LETTER EI;Lo;0;L;;;;;N;;;;;
+10508;ELBASAN LETTER E;Lo;0;L;;;;;N;;;;;
+10509;ELBASAN LETTER FE;Lo;0;L;;;;;N;;;;;
+1050A;ELBASAN LETTER GE;Lo;0;L;;;;;N;;;;;
+1050B;ELBASAN LETTER GJE;Lo;0;L;;;;;N;;;;;
+1050C;ELBASAN LETTER HE;Lo;0;L;;;;;N;;;;;
+1050D;ELBASAN LETTER I;Lo;0;L;;;;;N;;;;;
+1050E;ELBASAN LETTER JE;Lo;0;L;;;;;N;;;;;
+1050F;ELBASAN LETTER KE;Lo;0;L;;;;;N;;;;;
+10510;ELBASAN LETTER LE;Lo;0;L;;;;;N;;;;;
+10511;ELBASAN LETTER LLE;Lo;0;L;;;;;N;;;;;
+10512;ELBASAN LETTER ME;Lo;0;L;;;;;N;;;;;
+10513;ELBASAN LETTER NE;Lo;0;L;;;;;N;;;;;
+10514;ELBASAN LETTER NA;Lo;0;L;;;;;N;;;;;
+10515;ELBASAN LETTER NJE;Lo;0;L;;;;;N;;;;;
+10516;ELBASAN LETTER O;Lo;0;L;;;;;N;;;;;
+10517;ELBASAN LETTER PE;Lo;0;L;;;;;N;;;;;
+10518;ELBASAN LETTER QE;Lo;0;L;;;;;N;;;;;
+10519;ELBASAN LETTER RE;Lo;0;L;;;;;N;;;;;
+1051A;ELBASAN LETTER RRE;Lo;0;L;;;;;N;;;;;
+1051B;ELBASAN LETTER SE;Lo;0;L;;;;;N;;;;;
+1051C;ELBASAN LETTER SHE;Lo;0;L;;;;;N;;;;;
+1051D;ELBASAN LETTER TE;Lo;0;L;;;;;N;;;;;
+1051E;ELBASAN LETTER THE;Lo;0;L;;;;;N;;;;;
+1051F;ELBASAN LETTER U;Lo;0;L;;;;;N;;;;;
+10520;ELBASAN LETTER VE;Lo;0;L;;;;;N;;;;;
+10521;ELBASAN LETTER XE;Lo;0;L;;;;;N;;;;;
+10522;ELBASAN LETTER Y;Lo;0;L;;;;;N;;;;;
+10523;ELBASAN LETTER ZE;Lo;0;L;;;;;N;;;;;
+10524;ELBASAN LETTER ZHE;Lo;0;L;;;;;N;;;;;
+10525;ELBASAN LETTER GHE;Lo;0;L;;;;;N;;;;;
+10526;ELBASAN LETTER GHAMMA;Lo;0;L;;;;;N;;;;;
+10527;ELBASAN LETTER KHE;Lo;0;L;;;;;N;;;;;
+10530;CAUCASIAN ALBANIAN LETTER ALT;Lo;0;L;;;;;N;;;;;
+10531;CAUCASIAN ALBANIAN LETTER BET;Lo;0;L;;;;;N;;;;;
+10532;CAUCASIAN ALBANIAN LETTER GIM;Lo;0;L;;;;;N;;;;;
+10533;CAUCASIAN ALBANIAN LETTER DAT;Lo;0;L;;;;;N;;;;;
+10534;CAUCASIAN ALBANIAN LETTER EB;Lo;0;L;;;;;N;;;;;
+10535;CAUCASIAN ALBANIAN LETTER ZARL;Lo;0;L;;;;;N;;;;;
+10536;CAUCASIAN ALBANIAN LETTER EYN;Lo;0;L;;;;;N;;;;;
+10537;CAUCASIAN ALBANIAN LETTER ZHIL;Lo;0;L;;;;;N;;;;;
+10538;CAUCASIAN ALBANIAN LETTER TAS;Lo;0;L;;;;;N;;;;;
+10539;CAUCASIAN ALBANIAN LETTER CHA;Lo;0;L;;;;;N;;;;;
+1053A;CAUCASIAN ALBANIAN LETTER YOWD;Lo;0;L;;;;;N;;;;;
+1053B;CAUCASIAN ALBANIAN LETTER ZHA;Lo;0;L;;;;;N;;;;;
+1053C;CAUCASIAN ALBANIAN LETTER IRB;Lo;0;L;;;;;N;;;;;
+1053D;CAUCASIAN ALBANIAN LETTER SHA;Lo;0;L;;;;;N;;;;;
+1053E;CAUCASIAN ALBANIAN LETTER LAN;Lo;0;L;;;;;N;;;;;
+1053F;CAUCASIAN ALBANIAN LETTER INYA;Lo;0;L;;;;;N;;;;;
+10540;CAUCASIAN ALBANIAN LETTER XEYN;Lo;0;L;;;;;N;;;;;
+10541;CAUCASIAN ALBANIAN LETTER DYAN;Lo;0;L;;;;;N;;;;;
+10542;CAUCASIAN ALBANIAN LETTER CAR;Lo;0;L;;;;;N;;;;;
+10543;CAUCASIAN ALBANIAN LETTER JHOX;Lo;0;L;;;;;N;;;;;
+10544;CAUCASIAN ALBANIAN LETTER KAR;Lo;0;L;;;;;N;;;;;
+10545;CAUCASIAN ALBANIAN LETTER LYIT;Lo;0;L;;;;;N;;;;;
+10546;CAUCASIAN ALBANIAN LETTER HEYT;Lo;0;L;;;;;N;;;;;
+10547;CAUCASIAN ALBANIAN LETTER QAY;Lo;0;L;;;;;N;;;;;
+10548;CAUCASIAN ALBANIAN LETTER AOR;Lo;0;L;;;;;N;;;;;
+10549;CAUCASIAN ALBANIAN LETTER CHOY;Lo;0;L;;;;;N;;;;;
+1054A;CAUCASIAN ALBANIAN LETTER CHI;Lo;0;L;;;;;N;;;;;
+1054B;CAUCASIAN ALBANIAN LETTER CYAY;Lo;0;L;;;;;N;;;;;
+1054C;CAUCASIAN ALBANIAN LETTER MAQ;Lo;0;L;;;;;N;;;;;
+1054D;CAUCASIAN ALBANIAN LETTER QAR;Lo;0;L;;;;;N;;;;;
+1054E;CAUCASIAN ALBANIAN LETTER NOWC;Lo;0;L;;;;;N;;;;;
+1054F;CAUCASIAN ALBANIAN LETTER DZYAY;Lo;0;L;;;;;N;;;;;
+10550;CAUCASIAN ALBANIAN LETTER SHAK;Lo;0;L;;;;;N;;;;;
+10551;CAUCASIAN ALBANIAN LETTER JAYN;Lo;0;L;;;;;N;;;;;
+10552;CAUCASIAN ALBANIAN LETTER ON;Lo;0;L;;;;;N;;;;;
+10553;CAUCASIAN ALBANIAN LETTER TYAY;Lo;0;L;;;;;N;;;;;
+10554;CAUCASIAN ALBANIAN LETTER FAM;Lo;0;L;;;;;N;;;;;
+10555;CAUCASIAN ALBANIAN LETTER DZAY;Lo;0;L;;;;;N;;;;;
+10556;CAUCASIAN ALBANIAN LETTER CHAT;Lo;0;L;;;;;N;;;;;
+10557;CAUCASIAN ALBANIAN LETTER PEN;Lo;0;L;;;;;N;;;;;
+10558;CAUCASIAN ALBANIAN LETTER GHEYS;Lo;0;L;;;;;N;;;;;
+10559;CAUCASIAN ALBANIAN LETTER RAT;Lo;0;L;;;;;N;;;;;
+1055A;CAUCASIAN ALBANIAN LETTER SEYK;Lo;0;L;;;;;N;;;;;
+1055B;CAUCASIAN ALBANIAN LETTER VEYZ;Lo;0;L;;;;;N;;;;;
+1055C;CAUCASIAN ALBANIAN LETTER TIWR;Lo;0;L;;;;;N;;;;;
+1055D;CAUCASIAN ALBANIAN LETTER SHOY;Lo;0;L;;;;;N;;;;;
+1055E;CAUCASIAN ALBANIAN LETTER IWN;Lo;0;L;;;;;N;;;;;
+1055F;CAUCASIAN ALBANIAN LETTER CYAW;Lo;0;L;;;;;N;;;;;
+10560;CAUCASIAN ALBANIAN LETTER CAYN;Lo;0;L;;;;;N;;;;;
+10561;CAUCASIAN ALBANIAN LETTER YAYD;Lo;0;L;;;;;N;;;;;
+10562;CAUCASIAN ALBANIAN LETTER PIWR;Lo;0;L;;;;;N;;;;;
+10563;CAUCASIAN ALBANIAN LETTER KIW;Lo;0;L;;;;;N;;;;;
+1056F;CAUCASIAN ALBANIAN CITATION MARK;Po;0;L;;;;;N;;;;;
+10600;LINEAR A SIGN AB001;Lo;0;L;;;;;N;;;;;
+10601;LINEAR A SIGN AB002;Lo;0;L;;;;;N;;;;;
+10602;LINEAR A SIGN AB003;Lo;0;L;;;;;N;;;;;
+10603;LINEAR A SIGN AB004;Lo;0;L;;;;;N;;;;;
+10604;LINEAR A SIGN AB005;Lo;0;L;;;;;N;;;;;
+10605;LINEAR A SIGN AB006;Lo;0;L;;;;;N;;;;;
+10606;LINEAR A SIGN AB007;Lo;0;L;;;;;N;;;;;
+10607;LINEAR A SIGN AB008;Lo;0;L;;;;;N;;;;;
+10608;LINEAR A SIGN AB009;Lo;0;L;;;;;N;;;;;
+10609;LINEAR A SIGN AB010;Lo;0;L;;;;;N;;;;;
+1060A;LINEAR A SIGN AB011;Lo;0;L;;;;;N;;;;;
+1060B;LINEAR A SIGN AB013;Lo;0;L;;;;;N;;;;;
+1060C;LINEAR A SIGN AB016;Lo;0;L;;;;;N;;;;;
+1060D;LINEAR A SIGN AB017;Lo;0;L;;;;;N;;;;;
+1060E;LINEAR A SIGN AB020;Lo;0;L;;;;;N;;;;;
+1060F;LINEAR A SIGN AB021;Lo;0;L;;;;;N;;;;;
+10610;LINEAR A SIGN AB021F;Lo;0;L;;;;;N;;;;;
+10611;LINEAR A SIGN AB021M;Lo;0;L;;;;;N;;;;;
+10612;LINEAR A SIGN AB022;Lo;0;L;;;;;N;;;;;
+10613;LINEAR A SIGN AB022F;Lo;0;L;;;;;N;;;;;
+10614;LINEAR A SIGN AB022M;Lo;0;L;;;;;N;;;;;
+10615;LINEAR A SIGN AB023;Lo;0;L;;;;;N;;;;;
+10616;LINEAR A SIGN AB023M;Lo;0;L;;;;;N;;;;;
+10617;LINEAR A SIGN AB024;Lo;0;L;;;;;N;;;;;
+10618;LINEAR A SIGN AB026;Lo;0;L;;;;;N;;;;;
+10619;LINEAR A SIGN AB027;Lo;0;L;;;;;N;;;;;
+1061A;LINEAR A SIGN AB028;Lo;0;L;;;;;N;;;;;
+1061B;LINEAR A SIGN A028B;Lo;0;L;;;;;N;;;;;
+1061C;LINEAR A SIGN AB029;Lo;0;L;;;;;N;;;;;
+1061D;LINEAR A SIGN AB030;Lo;0;L;;;;;N;;;;;
+1061E;LINEAR A SIGN AB031;Lo;0;L;;;;;N;;;;;
+1061F;LINEAR A SIGN AB034;Lo;0;L;;;;;N;;;;;
+10620;LINEAR A SIGN AB037;Lo;0;L;;;;;N;;;;;
+10621;LINEAR A SIGN AB038;Lo;0;L;;;;;N;;;;;
+10622;LINEAR A SIGN AB039;Lo;0;L;;;;;N;;;;;
+10623;LINEAR A SIGN AB040;Lo;0;L;;;;;N;;;;;
+10624;LINEAR A SIGN AB041;Lo;0;L;;;;;N;;;;;
+10625;LINEAR A SIGN AB044;Lo;0;L;;;;;N;;;;;
+10626;LINEAR A SIGN AB045;Lo;0;L;;;;;N;;;;;
+10627;LINEAR A SIGN AB046;Lo;0;L;;;;;N;;;;;
+10628;LINEAR A SIGN AB047;Lo;0;L;;;;;N;;;;;
+10629;LINEAR A SIGN AB048;Lo;0;L;;;;;N;;;;;
+1062A;LINEAR A SIGN AB049;Lo;0;L;;;;;N;;;;;
+1062B;LINEAR A SIGN AB050;Lo;0;L;;;;;N;;;;;
+1062C;LINEAR A SIGN AB051;Lo;0;L;;;;;N;;;;;
+1062D;LINEAR A SIGN AB053;Lo;0;L;;;;;N;;;;;
+1062E;LINEAR A SIGN AB054;Lo;0;L;;;;;N;;;;;
+1062F;LINEAR A SIGN AB055;Lo;0;L;;;;;N;;;;;
+10630;LINEAR A SIGN AB056;Lo;0;L;;;;;N;;;;;
+10631;LINEAR A SIGN AB057;Lo;0;L;;;;;N;;;;;
+10632;LINEAR A SIGN AB058;Lo;0;L;;;;;N;;;;;
+10633;LINEAR A SIGN AB059;Lo;0;L;;;;;N;;;;;
+10634;LINEAR A SIGN AB060;Lo;0;L;;;;;N;;;;;
+10635;LINEAR A SIGN AB061;Lo;0;L;;;;;N;;;;;
+10636;LINEAR A SIGN AB065;Lo;0;L;;;;;N;;;;;
+10637;LINEAR A SIGN AB066;Lo;0;L;;;;;N;;;;;
+10638;LINEAR A SIGN AB067;Lo;0;L;;;;;N;;;;;
+10639;LINEAR A SIGN AB069;Lo;0;L;;;;;N;;;;;
+1063A;LINEAR A SIGN AB070;Lo;0;L;;;;;N;;;;;
+1063B;LINEAR A SIGN AB073;Lo;0;L;;;;;N;;;;;
+1063C;LINEAR A SIGN AB074;Lo;0;L;;;;;N;;;;;
+1063D;LINEAR A SIGN AB076;Lo;0;L;;;;;N;;;;;
+1063E;LINEAR A SIGN AB077;Lo;0;L;;;;;N;;;;;
+1063F;LINEAR A SIGN AB078;Lo;0;L;;;;;N;;;;;
+10640;LINEAR A SIGN AB079;Lo;0;L;;;;;N;;;;;
+10641;LINEAR A SIGN AB080;Lo;0;L;;;;;N;;;;;
+10642;LINEAR A SIGN AB081;Lo;0;L;;;;;N;;;;;
+10643;LINEAR A SIGN AB082;Lo;0;L;;;;;N;;;;;
+10644;LINEAR A SIGN AB085;Lo;0;L;;;;;N;;;;;
+10645;LINEAR A SIGN AB086;Lo;0;L;;;;;N;;;;;
+10646;LINEAR A SIGN AB087;Lo;0;L;;;;;N;;;;;
+10647;LINEAR A SIGN A100-102;Lo;0;L;;;;;N;;;;;
+10648;LINEAR A SIGN AB118;Lo;0;L;;;;;N;;;;;
+10649;LINEAR A SIGN AB120;Lo;0;L;;;;;N;;;;;
+1064A;LINEAR A SIGN A120B;Lo;0;L;;;;;N;;;;;
+1064B;LINEAR A SIGN AB122;Lo;0;L;;;;;N;;;;;
+1064C;LINEAR A SIGN AB123;Lo;0;L;;;;;N;;;;;
+1064D;LINEAR A SIGN AB131A;Lo;0;L;;;;;N;;;;;
+1064E;LINEAR A SIGN AB131B;Lo;0;L;;;;;N;;;;;
+1064F;LINEAR A SIGN A131C;Lo;0;L;;;;;N;;;;;
+10650;LINEAR A SIGN AB164;Lo;0;L;;;;;N;;;;;
+10651;LINEAR A SIGN AB171;Lo;0;L;;;;;N;;;;;
+10652;LINEAR A SIGN AB180;Lo;0;L;;;;;N;;;;;
+10653;LINEAR A SIGN AB188;Lo;0;L;;;;;N;;;;;
+10654;LINEAR A SIGN AB191;Lo;0;L;;;;;N;;;;;
+10655;LINEAR A SIGN A301;Lo;0;L;;;;;N;;;;;
+10656;LINEAR A SIGN A302;Lo;0;L;;;;;N;;;;;
+10657;LINEAR A SIGN A303;Lo;0;L;;;;;N;;;;;
+10658;LINEAR A SIGN A304;Lo;0;L;;;;;N;;;;;
+10659;LINEAR A SIGN A305;Lo;0;L;;;;;N;;;;;
+1065A;LINEAR A SIGN A306;Lo;0;L;;;;;N;;;;;
+1065B;LINEAR A SIGN A307;Lo;0;L;;;;;N;;;;;
+1065C;LINEAR A SIGN A308;Lo;0;L;;;;;N;;;;;
+1065D;LINEAR A SIGN A309A;Lo;0;L;;;;;N;;;;;
+1065E;LINEAR A SIGN A309B;Lo;0;L;;;;;N;;;;;
+1065F;LINEAR A SIGN A309C;Lo;0;L;;;;;N;;;;;
+10660;LINEAR A SIGN A310;Lo;0;L;;;;;N;;;;;
+10661;LINEAR A SIGN A311;Lo;0;L;;;;;N;;;;;
+10662;LINEAR A SIGN A312;Lo;0;L;;;;;N;;;;;
+10663;LINEAR A SIGN A313A;Lo;0;L;;;;;N;;;;;
+10664;LINEAR A SIGN A313B;Lo;0;L;;;;;N;;;;;
+10665;LINEAR A SIGN A313C;Lo;0;L;;;;;N;;;;;
+10666;LINEAR A SIGN A314;Lo;0;L;;;;;N;;;;;
+10667;LINEAR A SIGN A315;Lo;0;L;;;;;N;;;;;
+10668;LINEAR A SIGN A316;Lo;0;L;;;;;N;;;;;
+10669;LINEAR A SIGN A317;Lo;0;L;;;;;N;;;;;
+1066A;LINEAR A SIGN A318;Lo;0;L;;;;;N;;;;;
+1066B;LINEAR A SIGN A319;Lo;0;L;;;;;N;;;;;
+1066C;LINEAR A SIGN A320;Lo;0;L;;;;;N;;;;;
+1066D;LINEAR A SIGN A321;Lo;0;L;;;;;N;;;;;
+1066E;LINEAR A SIGN A322;Lo;0;L;;;;;N;;;;;
+1066F;LINEAR A SIGN A323;Lo;0;L;;;;;N;;;;;
+10670;LINEAR A SIGN A324;Lo;0;L;;;;;N;;;;;
+10671;LINEAR A SIGN A325;Lo;0;L;;;;;N;;;;;
+10672;LINEAR A SIGN A326;Lo;0;L;;;;;N;;;;;
+10673;LINEAR A SIGN A327;Lo;0;L;;;;;N;;;;;
+10674;LINEAR A SIGN A328;Lo;0;L;;;;;N;;;;;
+10675;LINEAR A SIGN A329;Lo;0;L;;;;;N;;;;;
+10676;LINEAR A SIGN A330;Lo;0;L;;;;;N;;;;;
+10677;LINEAR A SIGN A331;Lo;0;L;;;;;N;;;;;
+10678;LINEAR A SIGN A332;Lo;0;L;;;;;N;;;;;
+10679;LINEAR A SIGN A333;Lo;0;L;;;;;N;;;;;
+1067A;LINEAR A SIGN A334;Lo;0;L;;;;;N;;;;;
+1067B;LINEAR A SIGN A335;Lo;0;L;;;;;N;;;;;
+1067C;LINEAR A SIGN A336;Lo;0;L;;;;;N;;;;;
+1067D;LINEAR A SIGN A337;Lo;0;L;;;;;N;;;;;
+1067E;LINEAR A SIGN A338;Lo;0;L;;;;;N;;;;;
+1067F;LINEAR A SIGN A339;Lo;0;L;;;;;N;;;;;
+10680;LINEAR A SIGN A340;Lo;0;L;;;;;N;;;;;
+10681;LINEAR A SIGN A341;Lo;0;L;;;;;N;;;;;
+10682;LINEAR A SIGN A342;Lo;0;L;;;;;N;;;;;
+10683;LINEAR A SIGN A343;Lo;0;L;;;;;N;;;;;
+10684;LINEAR A SIGN A344;Lo;0;L;;;;;N;;;;;
+10685;LINEAR A SIGN A345;Lo;0;L;;;;;N;;;;;
+10686;LINEAR A SIGN A346;Lo;0;L;;;;;N;;;;;
+10687;LINEAR A SIGN A347;Lo;0;L;;;;;N;;;;;
+10688;LINEAR A SIGN A348;Lo;0;L;;;;;N;;;;;
+10689;LINEAR A SIGN A349;Lo;0;L;;;;;N;;;;;
+1068A;LINEAR A SIGN A350;Lo;0;L;;;;;N;;;;;
+1068B;LINEAR A SIGN A351;Lo;0;L;;;;;N;;;;;
+1068C;LINEAR A SIGN A352;Lo;0;L;;;;;N;;;;;
+1068D;LINEAR A SIGN A353;Lo;0;L;;;;;N;;;;;
+1068E;LINEAR A SIGN A354;Lo;0;L;;;;;N;;;;;
+1068F;LINEAR A SIGN A355;Lo;0;L;;;;;N;;;;;
+10690;LINEAR A SIGN A356;Lo;0;L;;;;;N;;;;;
+10691;LINEAR A SIGN A357;Lo;0;L;;;;;N;;;;;
+10692;LINEAR A SIGN A358;Lo;0;L;;;;;N;;;;;
+10693;LINEAR A SIGN A359;Lo;0;L;;;;;N;;;;;
+10694;LINEAR A SIGN A360;Lo;0;L;;;;;N;;;;;
+10695;LINEAR A SIGN A361;Lo;0;L;;;;;N;;;;;
+10696;LINEAR A SIGN A362;Lo;0;L;;;;;N;;;;;
+10697;LINEAR A SIGN A363;Lo;0;L;;;;;N;;;;;
+10698;LINEAR A SIGN A364;Lo;0;L;;;;;N;;;;;
+10699;LINEAR A SIGN A365;Lo;0;L;;;;;N;;;;;
+1069A;LINEAR A SIGN A366;Lo;0;L;;;;;N;;;;;
+1069B;LINEAR A SIGN A367;Lo;0;L;;;;;N;;;;;
+1069C;LINEAR A SIGN A368;Lo;0;L;;;;;N;;;;;
+1069D;LINEAR A SIGN A369;Lo;0;L;;;;;N;;;;;
+1069E;LINEAR A SIGN A370;Lo;0;L;;;;;N;;;;;
+1069F;LINEAR A SIGN A371;Lo;0;L;;;;;N;;;;;
+106A0;LINEAR A SIGN A400-VAS;Lo;0;L;;;;;N;;;;;
+106A1;LINEAR A SIGN A401-VAS;Lo;0;L;;;;;N;;;;;
+106A2;LINEAR A SIGN A402-VAS;Lo;0;L;;;;;N;;;;;
+106A3;LINEAR A SIGN A403-VAS;Lo;0;L;;;;;N;;;;;
+106A4;LINEAR A SIGN A404-VAS;Lo;0;L;;;;;N;;;;;
+106A5;LINEAR A SIGN A405-VAS;Lo;0;L;;;;;N;;;;;
+106A6;LINEAR A SIGN A406-VAS;Lo;0;L;;;;;N;;;;;
+106A7;LINEAR A SIGN A407-VAS;Lo;0;L;;;;;N;;;;;
+106A8;LINEAR A SIGN A408-VAS;Lo;0;L;;;;;N;;;;;
+106A9;LINEAR A SIGN A409-VAS;Lo;0;L;;;;;N;;;;;
+106AA;LINEAR A SIGN A410-VAS;Lo;0;L;;;;;N;;;;;
+106AB;LINEAR A SIGN A411-VAS;Lo;0;L;;;;;N;;;;;
+106AC;LINEAR A SIGN A412-VAS;Lo;0;L;;;;;N;;;;;
+106AD;LINEAR A SIGN A413-VAS;Lo;0;L;;;;;N;;;;;
+106AE;LINEAR A SIGN A414-VAS;Lo;0;L;;;;;N;;;;;
+106AF;LINEAR A SIGN A415-VAS;Lo;0;L;;;;;N;;;;;
+106B0;LINEAR A SIGN A416-VAS;Lo;0;L;;;;;N;;;;;
+106B1;LINEAR A SIGN A417-VAS;Lo;0;L;;;;;N;;;;;
+106B2;LINEAR A SIGN A418-VAS;Lo;0;L;;;;;N;;;;;
+106B3;LINEAR A SIGN A501;Lo;0;L;;;;;N;;;;;
+106B4;LINEAR A SIGN A502;Lo;0;L;;;;;N;;;;;
+106B5;LINEAR A SIGN A503;Lo;0;L;;;;;N;;;;;
+106B6;LINEAR A SIGN A504;Lo;0;L;;;;;N;;;;;
+106B7;LINEAR A SIGN A505;Lo;0;L;;;;;N;;;;;
+106B8;LINEAR A SIGN A506;Lo;0;L;;;;;N;;;;;
+106B9;LINEAR A SIGN A508;Lo;0;L;;;;;N;;;;;
+106BA;LINEAR A SIGN A509;Lo;0;L;;;;;N;;;;;
+106BB;LINEAR A SIGN A510;Lo;0;L;;;;;N;;;;;
+106BC;LINEAR A SIGN A511;Lo;0;L;;;;;N;;;;;
+106BD;LINEAR A SIGN A512;Lo;0;L;;;;;N;;;;;
+106BE;LINEAR A SIGN A513;Lo;0;L;;;;;N;;;;;
+106BF;LINEAR A SIGN A515;Lo;0;L;;;;;N;;;;;
+106C0;LINEAR A SIGN A516;Lo;0;L;;;;;N;;;;;
+106C1;LINEAR A SIGN A520;Lo;0;L;;;;;N;;;;;
+106C2;LINEAR A SIGN A521;Lo;0;L;;;;;N;;;;;
+106C3;LINEAR A SIGN A523;Lo;0;L;;;;;N;;;;;
+106C4;LINEAR A SIGN A524;Lo;0;L;;;;;N;;;;;
+106C5;LINEAR A SIGN A525;Lo;0;L;;;;;N;;;;;
+106C6;LINEAR A SIGN A526;Lo;0;L;;;;;N;;;;;
+106C7;LINEAR A SIGN A527;Lo;0;L;;;;;N;;;;;
+106C8;LINEAR A SIGN A528;Lo;0;L;;;;;N;;;;;
+106C9;LINEAR A SIGN A529;Lo;0;L;;;;;N;;;;;
+106CA;LINEAR A SIGN A530;Lo;0;L;;;;;N;;;;;
+106CB;LINEAR A SIGN A531;Lo;0;L;;;;;N;;;;;
+106CC;LINEAR A SIGN A532;Lo;0;L;;;;;N;;;;;
+106CD;LINEAR A SIGN A534;Lo;0;L;;;;;N;;;;;
+106CE;LINEAR A SIGN A535;Lo;0;L;;;;;N;;;;;
+106CF;LINEAR A SIGN A536;Lo;0;L;;;;;N;;;;;
+106D0;LINEAR A SIGN A537;Lo;0;L;;;;;N;;;;;
+106D1;LINEAR A SIGN A538;Lo;0;L;;;;;N;;;;;
+106D2;LINEAR A SIGN A539;Lo;0;L;;;;;N;;;;;
+106D3;LINEAR A SIGN A540;Lo;0;L;;;;;N;;;;;
+106D4;LINEAR A SIGN A541;Lo;0;L;;;;;N;;;;;
+106D5;LINEAR A SIGN A542;Lo;0;L;;;;;N;;;;;
+106D6;LINEAR A SIGN A545;Lo;0;L;;;;;N;;;;;
+106D7;LINEAR A SIGN A547;Lo;0;L;;;;;N;;;;;
+106D8;LINEAR A SIGN A548;Lo;0;L;;;;;N;;;;;
+106D9;LINEAR A SIGN A549;Lo;0;L;;;;;N;;;;;
+106DA;LINEAR A SIGN A550;Lo;0;L;;;;;N;;;;;
+106DB;LINEAR A SIGN A551;Lo;0;L;;;;;N;;;;;
+106DC;LINEAR A SIGN A552;Lo;0;L;;;;;N;;;;;
+106DD;LINEAR A SIGN A553;Lo;0;L;;;;;N;;;;;
+106DE;LINEAR A SIGN A554;Lo;0;L;;;;;N;;;;;
+106DF;LINEAR A SIGN A555;Lo;0;L;;;;;N;;;;;
+106E0;LINEAR A SIGN A556;Lo;0;L;;;;;N;;;;;
+106E1;LINEAR A SIGN A557;Lo;0;L;;;;;N;;;;;
+106E2;LINEAR A SIGN A559;Lo;0;L;;;;;N;;;;;
+106E3;LINEAR A SIGN A563;Lo;0;L;;;;;N;;;;;
+106E4;LINEAR A SIGN A564;Lo;0;L;;;;;N;;;;;
+106E5;LINEAR A SIGN A565;Lo;0;L;;;;;N;;;;;
+106E6;LINEAR A SIGN A566;Lo;0;L;;;;;N;;;;;
+106E7;LINEAR A SIGN A568;Lo;0;L;;;;;N;;;;;
+106E8;LINEAR A SIGN A569;Lo;0;L;;;;;N;;;;;
+106E9;LINEAR A SIGN A570;Lo;0;L;;;;;N;;;;;
+106EA;LINEAR A SIGN A571;Lo;0;L;;;;;N;;;;;
+106EB;LINEAR A SIGN A572;Lo;0;L;;;;;N;;;;;
+106EC;LINEAR A SIGN A573;Lo;0;L;;;;;N;;;;;
+106ED;LINEAR A SIGN A574;Lo;0;L;;;;;N;;;;;
+106EE;LINEAR A SIGN A575;Lo;0;L;;;;;N;;;;;
+106EF;LINEAR A SIGN A576;Lo;0;L;;;;;N;;;;;
+106F0;LINEAR A SIGN A577;Lo;0;L;;;;;N;;;;;
+106F1;LINEAR A SIGN A578;Lo;0;L;;;;;N;;;;;
+106F2;LINEAR A SIGN A579;Lo;0;L;;;;;N;;;;;
+106F3;LINEAR A SIGN A580;Lo;0;L;;;;;N;;;;;
+106F4;LINEAR A SIGN A581;Lo;0;L;;;;;N;;;;;
+106F5;LINEAR A SIGN A582;Lo;0;L;;;;;N;;;;;
+106F6;LINEAR A SIGN A583;Lo;0;L;;;;;N;;;;;
+106F7;LINEAR A SIGN A584;Lo;0;L;;;;;N;;;;;
+106F8;LINEAR A SIGN A585;Lo;0;L;;;;;N;;;;;
+106F9;LINEAR A SIGN A586;Lo;0;L;;;;;N;;;;;
+106FA;LINEAR A SIGN A587;Lo;0;L;;;;;N;;;;;
+106FB;LINEAR A SIGN A588;Lo;0;L;;;;;N;;;;;
+106FC;LINEAR A SIGN A589;Lo;0;L;;;;;N;;;;;
+106FD;LINEAR A SIGN A591;Lo;0;L;;;;;N;;;;;
+106FE;LINEAR A SIGN A592;Lo;0;L;;;;;N;;;;;
+106FF;LINEAR A SIGN A594;Lo;0;L;;;;;N;;;;;
+10700;LINEAR A SIGN A595;Lo;0;L;;;;;N;;;;;
+10701;LINEAR A SIGN A596;Lo;0;L;;;;;N;;;;;
+10702;LINEAR A SIGN A598;Lo;0;L;;;;;N;;;;;
+10703;LINEAR A SIGN A600;Lo;0;L;;;;;N;;;;;
+10704;LINEAR A SIGN A601;Lo;0;L;;;;;N;;;;;
+10705;LINEAR A SIGN A602;Lo;0;L;;;;;N;;;;;
+10706;LINEAR A SIGN A603;Lo;0;L;;;;;N;;;;;
+10707;LINEAR A SIGN A604;Lo;0;L;;;;;N;;;;;
+10708;LINEAR A SIGN A606;Lo;0;L;;;;;N;;;;;
+10709;LINEAR A SIGN A608;Lo;0;L;;;;;N;;;;;
+1070A;LINEAR A SIGN A609;Lo;0;L;;;;;N;;;;;
+1070B;LINEAR A SIGN A610;Lo;0;L;;;;;N;;;;;
+1070C;LINEAR A SIGN A611;Lo;0;L;;;;;N;;;;;
+1070D;LINEAR A SIGN A612;Lo;0;L;;;;;N;;;;;
+1070E;LINEAR A SIGN A613;Lo;0;L;;;;;N;;;;;
+1070F;LINEAR A SIGN A614;Lo;0;L;;;;;N;;;;;
+10710;LINEAR A SIGN A615;Lo;0;L;;;;;N;;;;;
+10711;LINEAR A SIGN A616;Lo;0;L;;;;;N;;;;;
+10712;LINEAR A SIGN A617;Lo;0;L;;;;;N;;;;;
+10713;LINEAR A SIGN A618;Lo;0;L;;;;;N;;;;;
+10714;LINEAR A SIGN A619;Lo;0;L;;;;;N;;;;;
+10715;LINEAR A SIGN A620;Lo;0;L;;;;;N;;;;;
+10716;LINEAR A SIGN A621;Lo;0;L;;;;;N;;;;;
+10717;LINEAR A SIGN A622;Lo;0;L;;;;;N;;;;;
+10718;LINEAR A SIGN A623;Lo;0;L;;;;;N;;;;;
+10719;LINEAR A SIGN A624;Lo;0;L;;;;;N;;;;;
+1071A;LINEAR A SIGN A626;Lo;0;L;;;;;N;;;;;
+1071B;LINEAR A SIGN A627;Lo;0;L;;;;;N;;;;;
+1071C;LINEAR A SIGN A628;Lo;0;L;;;;;N;;;;;
+1071D;LINEAR A SIGN A629;Lo;0;L;;;;;N;;;;;
+1071E;LINEAR A SIGN A634;Lo;0;L;;;;;N;;;;;
+1071F;LINEAR A SIGN A637;Lo;0;L;;;;;N;;;;;
+10720;LINEAR A SIGN A638;Lo;0;L;;;;;N;;;;;
+10721;LINEAR A SIGN A640;Lo;0;L;;;;;N;;;;;
+10722;LINEAR A SIGN A642;Lo;0;L;;;;;N;;;;;
+10723;LINEAR A SIGN A643;Lo;0;L;;;;;N;;;;;
+10724;LINEAR A SIGN A644;Lo;0;L;;;;;N;;;;;
+10725;LINEAR A SIGN A645;Lo;0;L;;;;;N;;;;;
+10726;LINEAR A SIGN A646;Lo;0;L;;;;;N;;;;;
+10727;LINEAR A SIGN A648;Lo;0;L;;;;;N;;;;;
+10728;LINEAR A SIGN A649;Lo;0;L;;;;;N;;;;;
+10729;LINEAR A SIGN A651;Lo;0;L;;;;;N;;;;;
+1072A;LINEAR A SIGN A652;Lo;0;L;;;;;N;;;;;
+1072B;LINEAR A SIGN A653;Lo;0;L;;;;;N;;;;;
+1072C;LINEAR A SIGN A654;Lo;0;L;;;;;N;;;;;
+1072D;LINEAR A SIGN A655;Lo;0;L;;;;;N;;;;;
+1072E;LINEAR A SIGN A656;Lo;0;L;;;;;N;;;;;
+1072F;LINEAR A SIGN A657;Lo;0;L;;;;;N;;;;;
+10730;LINEAR A SIGN A658;Lo;0;L;;;;;N;;;;;
+10731;LINEAR A SIGN A659;Lo;0;L;;;;;N;;;;;
+10732;LINEAR A SIGN A660;Lo;0;L;;;;;N;;;;;
+10733;LINEAR A SIGN A661;Lo;0;L;;;;;N;;;;;
+10734;LINEAR A SIGN A662;Lo;0;L;;;;;N;;;;;
+10735;LINEAR A SIGN A663;Lo;0;L;;;;;N;;;;;
+10736;LINEAR A SIGN A664;Lo;0;L;;;;;N;;;;;
+10740;LINEAR A SIGN A701 A;Lo;0;L;;;;;N;;;;;
+10741;LINEAR A SIGN A702 B;Lo;0;L;;;;;N;;;;;
+10742;LINEAR A SIGN A703 D;Lo;0;L;;;;;N;;;;;
+10743;LINEAR A SIGN A704 E;Lo;0;L;;;;;N;;;;;
+10744;LINEAR A SIGN A705 F;Lo;0;L;;;;;N;;;;;
+10745;LINEAR A SIGN A706 H;Lo;0;L;;;;;N;;;;;
+10746;LINEAR A SIGN A707 J;Lo;0;L;;;;;N;;;;;
+10747;LINEAR A SIGN A708 K;Lo;0;L;;;;;N;;;;;
+10748;LINEAR A SIGN A709 L;Lo;0;L;;;;;N;;;;;
+10749;LINEAR A SIGN A709-2 L2;Lo;0;L;;;;;N;;;;;
+1074A;LINEAR A SIGN A709-3 L3;Lo;0;L;;;;;N;;;;;
+1074B;LINEAR A SIGN A709-4 L4;Lo;0;L;;;;;N;;;;;
+1074C;LINEAR A SIGN A709-6 L6;Lo;0;L;;;;;N;;;;;
+1074D;LINEAR A SIGN A710 W;Lo;0;L;;;;;N;;;;;
+1074E;LINEAR A SIGN A711 X;Lo;0;L;;;;;N;;;;;
+1074F;LINEAR A SIGN A712 Y;Lo;0;L;;;;;N;;;;;
+10750;LINEAR A SIGN A713 OMEGA;Lo;0;L;;;;;N;;;;;
+10751;LINEAR A SIGN A714 ABB;Lo;0;L;;;;;N;;;;;
+10752;LINEAR A SIGN A715 BB;Lo;0;L;;;;;N;;;;;
+10753;LINEAR A SIGN A717 DD;Lo;0;L;;;;;N;;;;;
+10754;LINEAR A SIGN A726 EYYY;Lo;0;L;;;;;N;;;;;
+10755;LINEAR A SIGN A732 JE;Lo;0;L;;;;;N;;;;;
+10760;LINEAR A SIGN A800;Lo;0;L;;;;;N;;;;;
+10761;LINEAR A SIGN A801;Lo;0;L;;;;;N;;;;;
+10762;LINEAR A SIGN A802;Lo;0;L;;;;;N;;;;;
+10763;LINEAR A SIGN A803;Lo;0;L;;;;;N;;;;;
+10764;LINEAR A SIGN A804;Lo;0;L;;;;;N;;;;;
+10765;LINEAR A SIGN A805;Lo;0;L;;;;;N;;;;;
+10766;LINEAR A SIGN A806;Lo;0;L;;;;;N;;;;;
+10767;LINEAR A SIGN A807;Lo;0;L;;;;;N;;;;;
10800;CYPRIOT SYLLABLE A;Lo;0;R;;;;;N;;;;;
10801;CYPRIOT SYLLABLE E;Lo;0;R;;;;;N;;;;;
10802;CYPRIOT SYLLABLE I;Lo;0;R;;;;;N;;;;;
@@ -16558,6 +18043,104 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1085D;IMPERIAL ARAMAIC NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;;
1085E;IMPERIAL ARAMAIC NUMBER ONE THOUSAND;No;0;R;;;;1000;N;;;;;
1085F;IMPERIAL ARAMAIC NUMBER TEN THOUSAND;No;0;R;;;;10000;N;;;;;
+10860;PALMYRENE LETTER ALEPH;Lo;0;R;;;;;N;;;;;
+10861;PALMYRENE LETTER BETH;Lo;0;R;;;;;N;;;;;
+10862;PALMYRENE LETTER GIMEL;Lo;0;R;;;;;N;;;;;
+10863;PALMYRENE LETTER DALETH;Lo;0;R;;;;;N;;;;;
+10864;PALMYRENE LETTER HE;Lo;0;R;;;;;N;;;;;
+10865;PALMYRENE LETTER WAW;Lo;0;R;;;;;N;;;;;
+10866;PALMYRENE LETTER ZAYIN;Lo;0;R;;;;;N;;;;;
+10867;PALMYRENE LETTER HETH;Lo;0;R;;;;;N;;;;;
+10868;PALMYRENE LETTER TETH;Lo;0;R;;;;;N;;;;;
+10869;PALMYRENE LETTER YODH;Lo;0;R;;;;;N;;;;;
+1086A;PALMYRENE LETTER KAPH;Lo;0;R;;;;;N;;;;;
+1086B;PALMYRENE LETTER LAMEDH;Lo;0;R;;;;;N;;;;;
+1086C;PALMYRENE LETTER MEM;Lo;0;R;;;;;N;;;;;
+1086D;PALMYRENE LETTER FINAL NUN;Lo;0;R;;;;;N;;;;;
+1086E;PALMYRENE LETTER NUN;Lo;0;R;;;;;N;;;;;
+1086F;PALMYRENE LETTER SAMEKH;Lo;0;R;;;;;N;;;;;
+10870;PALMYRENE LETTER AYIN;Lo;0;R;;;;;N;;;;;
+10871;PALMYRENE LETTER PE;Lo;0;R;;;;;N;;;;;
+10872;PALMYRENE LETTER SADHE;Lo;0;R;;;;;N;;;;;
+10873;PALMYRENE LETTER QOPH;Lo;0;R;;;;;N;;;;;
+10874;PALMYRENE LETTER RESH;Lo;0;R;;;;;N;;;;;
+10875;PALMYRENE LETTER SHIN;Lo;0;R;;;;;N;;;;;
+10876;PALMYRENE LETTER TAW;Lo;0;R;;;;;N;;;;;
+10877;PALMYRENE LEFT-POINTING FLEURON;So;0;R;;;;;N;;;;;
+10878;PALMYRENE RIGHT-POINTING FLEURON;So;0;R;;;;;N;;;;;
+10879;PALMYRENE NUMBER ONE;No;0;R;;;;1;N;;;;;
+1087A;PALMYRENE NUMBER TWO;No;0;R;;;;2;N;;;;;
+1087B;PALMYRENE NUMBER THREE;No;0;R;;;;3;N;;;;;
+1087C;PALMYRENE NUMBER FOUR;No;0;R;;;;4;N;;;;;
+1087D;PALMYRENE NUMBER FIVE;No;0;R;;;;5;N;;;;;
+1087E;PALMYRENE NUMBER TEN;No;0;R;;;;10;N;;;;;
+1087F;PALMYRENE NUMBER TWENTY;No;0;R;;;;20;N;;;;;
+10880;NABATAEAN LETTER FINAL ALEPH;Lo;0;R;;;;;N;;;;;
+10881;NABATAEAN LETTER ALEPH;Lo;0;R;;;;;N;;;;;
+10882;NABATAEAN LETTER FINAL BETH;Lo;0;R;;;;;N;;;;;
+10883;NABATAEAN LETTER BETH;Lo;0;R;;;;;N;;;;;
+10884;NABATAEAN LETTER GIMEL;Lo;0;R;;;;;N;;;;;
+10885;NABATAEAN LETTER DALETH;Lo;0;R;;;;;N;;;;;
+10886;NABATAEAN LETTER FINAL HE;Lo;0;R;;;;;N;;;;;
+10887;NABATAEAN LETTER HE;Lo;0;R;;;;;N;;;;;
+10888;NABATAEAN LETTER WAW;Lo;0;R;;;;;N;;;;;
+10889;NABATAEAN LETTER ZAYIN;Lo;0;R;;;;;N;;;;;
+1088A;NABATAEAN LETTER HETH;Lo;0;R;;;;;N;;;;;
+1088B;NABATAEAN LETTER TETH;Lo;0;R;;;;;N;;;;;
+1088C;NABATAEAN LETTER FINAL YODH;Lo;0;R;;;;;N;;;;;
+1088D;NABATAEAN LETTER YODH;Lo;0;R;;;;;N;;;;;
+1088E;NABATAEAN LETTER FINAL KAPH;Lo;0;R;;;;;N;;;;;
+1088F;NABATAEAN LETTER KAPH;Lo;0;R;;;;;N;;;;;
+10890;NABATAEAN LETTER FINAL LAMEDH;Lo;0;R;;;;;N;;;;;
+10891;NABATAEAN LETTER LAMEDH;Lo;0;R;;;;;N;;;;;
+10892;NABATAEAN LETTER FINAL MEM;Lo;0;R;;;;;N;;;;;
+10893;NABATAEAN LETTER MEM;Lo;0;R;;;;;N;;;;;
+10894;NABATAEAN LETTER FINAL NUN;Lo;0;R;;;;;N;;;;;
+10895;NABATAEAN LETTER NUN;Lo;0;R;;;;;N;;;;;
+10896;NABATAEAN LETTER SAMEKH;Lo;0;R;;;;;N;;;;;
+10897;NABATAEAN LETTER AYIN;Lo;0;R;;;;;N;;;;;
+10898;NABATAEAN LETTER PE;Lo;0;R;;;;;N;;;;;
+10899;NABATAEAN LETTER SADHE;Lo;0;R;;;;;N;;;;;
+1089A;NABATAEAN LETTER QOPH;Lo;0;R;;;;;N;;;;;
+1089B;NABATAEAN LETTER RESH;Lo;0;R;;;;;N;;;;;
+1089C;NABATAEAN LETTER FINAL SHIN;Lo;0;R;;;;;N;;;;;
+1089D;NABATAEAN LETTER SHIN;Lo;0;R;;;;;N;;;;;
+1089E;NABATAEAN LETTER TAW;Lo;0;R;;;;;N;;;;;
+108A7;NABATAEAN NUMBER ONE;No;0;R;;;;1;N;;;;;
+108A8;NABATAEAN NUMBER TWO;No;0;R;;;;2;N;;;;;
+108A9;NABATAEAN NUMBER THREE;No;0;R;;;;3;N;;;;;
+108AA;NABATAEAN NUMBER FOUR;No;0;R;;;;4;N;;;;;
+108AB;NABATAEAN CRUCIFORM NUMBER FOUR;No;0;R;;;;4;N;;;;;
+108AC;NABATAEAN NUMBER FIVE;No;0;R;;;;5;N;;;;;
+108AD;NABATAEAN NUMBER TEN;No;0;R;;;;10;N;;;;;
+108AE;NABATAEAN NUMBER TWENTY;No;0;R;;;;20;N;;;;;
+108AF;NABATAEAN NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;;
+108E0;HATRAN LETTER ALEPH;Lo;0;R;;;;;N;;;;;
+108E1;HATRAN LETTER BETH;Lo;0;R;;;;;N;;;;;
+108E2;HATRAN LETTER GIMEL;Lo;0;R;;;;;N;;;;;
+108E3;HATRAN LETTER DALETH-RESH;Lo;0;R;;;;;N;;;;;
+108E4;HATRAN LETTER HE;Lo;0;R;;;;;N;;;;;
+108E5;HATRAN LETTER WAW;Lo;0;R;;;;;N;;;;;
+108E6;HATRAN LETTER ZAYN;Lo;0;R;;;;;N;;;;;
+108E7;HATRAN LETTER HETH;Lo;0;R;;;;;N;;;;;
+108E8;HATRAN LETTER TETH;Lo;0;R;;;;;N;;;;;
+108E9;HATRAN LETTER YODH;Lo;0;R;;;;;N;;;;;
+108EA;HATRAN LETTER KAPH;Lo;0;R;;;;;N;;;;;
+108EB;HATRAN LETTER LAMEDH;Lo;0;R;;;;;N;;;;;
+108EC;HATRAN LETTER MEM;Lo;0;R;;;;;N;;;;;
+108ED;HATRAN LETTER NUN;Lo;0;R;;;;;N;;;;;
+108EE;HATRAN LETTER SAMEKH;Lo;0;R;;;;;N;;;;;
+108EF;HATRAN LETTER AYN;Lo;0;R;;;;;N;;;;;
+108F0;HATRAN LETTER PE;Lo;0;R;;;;;N;;;;;
+108F1;HATRAN LETTER SADHE;Lo;0;R;;;;;N;;;;;
+108F2;HATRAN LETTER QOPH;Lo;0;R;;;;;N;;;;;
+108F4;HATRAN LETTER SHIN;Lo;0;R;;;;;N;;;;;
+108F5;HATRAN LETTER TAW;Lo;0;R;;;;;N;;;;;
+108FB;HATRAN NUMBER ONE;No;0;R;;;;1;N;;;;;
+108FC;HATRAN NUMBER FIVE;No;0;R;;;;5;N;;;;;
+108FD;HATRAN NUMBER TEN;No;0;R;;;;10;N;;;;;
+108FE;HATRAN NUMBER TWENTY;No;0;R;;;;20;N;;;;;
+108FF;HATRAN NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;;
10900;PHOENICIAN LETTER ALF;Lo;0;R;;;;;N;;;;;
10901;PHOENICIAN LETTER BET;Lo;0;R;;;;;N;;;;;
10902;PHOENICIAN LETTER GAML;Lo;0;R;;;;;N;;;;;
@@ -16614,6 +18197,128 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
10938;LYDIAN LETTER NN;Lo;0;R;;;;;N;;;;;
10939;LYDIAN LETTER C;Lo;0;R;;;;;N;;;;;
1093F;LYDIAN TRIANGULAR MARK;Po;0;R;;;;;N;;;;;
+10980;MEROITIC HIEROGLYPHIC LETTER A;Lo;0;R;;;;;N;;;;;
+10981;MEROITIC HIEROGLYPHIC LETTER E;Lo;0;R;;;;;N;;;;;
+10982;MEROITIC HIEROGLYPHIC LETTER I;Lo;0;R;;;;;N;;;;;
+10983;MEROITIC HIEROGLYPHIC LETTER O;Lo;0;R;;;;;N;;;;;
+10984;MEROITIC HIEROGLYPHIC LETTER YA;Lo;0;R;;;;;N;;;;;
+10985;MEROITIC HIEROGLYPHIC LETTER WA;Lo;0;R;;;;;N;;;;;
+10986;MEROITIC HIEROGLYPHIC LETTER BA;Lo;0;R;;;;;N;;;;;
+10987;MEROITIC HIEROGLYPHIC LETTER BA-2;Lo;0;R;;;;;N;;;;;
+10988;MEROITIC HIEROGLYPHIC LETTER PA;Lo;0;R;;;;;N;;;;;
+10989;MEROITIC HIEROGLYPHIC LETTER MA;Lo;0;R;;;;;N;;;;;
+1098A;MEROITIC HIEROGLYPHIC LETTER NA;Lo;0;R;;;;;N;;;;;
+1098B;MEROITIC HIEROGLYPHIC LETTER NA-2;Lo;0;R;;;;;N;;;;;
+1098C;MEROITIC HIEROGLYPHIC LETTER NE;Lo;0;R;;;;;N;;;;;
+1098D;MEROITIC HIEROGLYPHIC LETTER NE-2;Lo;0;R;;;;;N;;;;;
+1098E;MEROITIC HIEROGLYPHIC LETTER RA;Lo;0;R;;;;;N;;;;;
+1098F;MEROITIC HIEROGLYPHIC LETTER RA-2;Lo;0;R;;;;;N;;;;;
+10990;MEROITIC HIEROGLYPHIC LETTER LA;Lo;0;R;;;;;N;;;;;
+10991;MEROITIC HIEROGLYPHIC LETTER KHA;Lo;0;R;;;;;N;;;;;
+10992;MEROITIC HIEROGLYPHIC LETTER HHA;Lo;0;R;;;;;N;;;;;
+10993;MEROITIC HIEROGLYPHIC LETTER SA;Lo;0;R;;;;;N;;;;;
+10994;MEROITIC HIEROGLYPHIC LETTER SA-2;Lo;0;R;;;;;N;;;;;
+10995;MEROITIC HIEROGLYPHIC LETTER SE;Lo;0;R;;;;;N;;;;;
+10996;MEROITIC HIEROGLYPHIC LETTER KA;Lo;0;R;;;;;N;;;;;
+10997;MEROITIC HIEROGLYPHIC LETTER QA;Lo;0;R;;;;;N;;;;;
+10998;MEROITIC HIEROGLYPHIC LETTER TA;Lo;0;R;;;;;N;;;;;
+10999;MEROITIC HIEROGLYPHIC LETTER TA-2;Lo;0;R;;;;;N;;;;;
+1099A;MEROITIC HIEROGLYPHIC LETTER TE;Lo;0;R;;;;;N;;;;;
+1099B;MEROITIC HIEROGLYPHIC LETTER TE-2;Lo;0;R;;;;;N;;;;;
+1099C;MEROITIC HIEROGLYPHIC LETTER TO;Lo;0;R;;;;;N;;;;;
+1099D;MEROITIC HIEROGLYPHIC LETTER DA;Lo;0;R;;;;;N;;;;;
+1099E;MEROITIC HIEROGLYPHIC SYMBOL VIDJ;Lo;0;R;;;;;N;;;;;
+1099F;MEROITIC HIEROGLYPHIC SYMBOL VIDJ-2;Lo;0;R;;;;;N;;;;;
+109A0;MEROITIC CURSIVE LETTER A;Lo;0;R;;;;;N;;;;;
+109A1;MEROITIC CURSIVE LETTER E;Lo;0;R;;;;;N;;;;;
+109A2;MEROITIC CURSIVE LETTER I;Lo;0;R;;;;;N;;;;;
+109A3;MEROITIC CURSIVE LETTER O;Lo;0;R;;;;;N;;;;;
+109A4;MEROITIC CURSIVE LETTER YA;Lo;0;R;;;;;N;;;;;
+109A5;MEROITIC CURSIVE LETTER WA;Lo;0;R;;;;;N;;;;;
+109A6;MEROITIC CURSIVE LETTER BA;Lo;0;R;;;;;N;;;;;
+109A7;MEROITIC CURSIVE LETTER PA;Lo;0;R;;;;;N;;;;;
+109A8;MEROITIC CURSIVE LETTER MA;Lo;0;R;;;;;N;;;;;
+109A9;MEROITIC CURSIVE LETTER NA;Lo;0;R;;;;;N;;;;;
+109AA;MEROITIC CURSIVE LETTER NE;Lo;0;R;;;;;N;;;;;
+109AB;MEROITIC CURSIVE LETTER RA;Lo;0;R;;;;;N;;;;;
+109AC;MEROITIC CURSIVE LETTER LA;Lo;0;R;;;;;N;;;;;
+109AD;MEROITIC CURSIVE LETTER KHA;Lo;0;R;;;;;N;;;;;
+109AE;MEROITIC CURSIVE LETTER HHA;Lo;0;R;;;;;N;;;;;
+109AF;MEROITIC CURSIVE LETTER SA;Lo;0;R;;;;;N;;;;;
+109B0;MEROITIC CURSIVE LETTER ARCHAIC SA;Lo;0;R;;;;;N;;;;;
+109B1;MEROITIC CURSIVE LETTER SE;Lo;0;R;;;;;N;;;;;
+109B2;MEROITIC CURSIVE LETTER KA;Lo;0;R;;;;;N;;;;;
+109B3;MEROITIC CURSIVE LETTER QA;Lo;0;R;;;;;N;;;;;
+109B4;MEROITIC CURSIVE LETTER TA;Lo;0;R;;;;;N;;;;;
+109B5;MEROITIC CURSIVE LETTER TE;Lo;0;R;;;;;N;;;;;
+109B6;MEROITIC CURSIVE LETTER TO;Lo;0;R;;;;;N;;;;;
+109B7;MEROITIC CURSIVE LETTER DA;Lo;0;R;;;;;N;;;;;
+109BC;MEROITIC CURSIVE FRACTION ELEVEN TWELFTHS;No;0;R;;;;11/12;N;;;;;
+109BD;MEROITIC CURSIVE FRACTION ONE HALF;No;0;R;;;;1/2;N;;;;;
+109BE;MEROITIC CURSIVE LOGOGRAM RMT;Lo;0;R;;;;;N;;;;;
+109BF;MEROITIC CURSIVE LOGOGRAM IMN;Lo;0;R;;;;;N;;;;;
+109C0;MEROITIC CURSIVE NUMBER ONE;No;0;R;;;;1;N;;;;;
+109C1;MEROITIC CURSIVE NUMBER TWO;No;0;R;;;;2;N;;;;;
+109C2;MEROITIC CURSIVE NUMBER THREE;No;0;R;;;;3;N;;;;;
+109C3;MEROITIC CURSIVE NUMBER FOUR;No;0;R;;;;4;N;;;;;
+109C4;MEROITIC CURSIVE NUMBER FIVE;No;0;R;;;;5;N;;;;;
+109C5;MEROITIC CURSIVE NUMBER SIX;No;0;R;;;;6;N;;;;;
+109C6;MEROITIC CURSIVE NUMBER SEVEN;No;0;R;;;;7;N;;;;;
+109C7;MEROITIC CURSIVE NUMBER EIGHT;No;0;R;;;;8;N;;;;;
+109C8;MEROITIC CURSIVE NUMBER NINE;No;0;R;;;;9;N;;;;;
+109C9;MEROITIC CURSIVE NUMBER TEN;No;0;R;;;;10;N;;;;;
+109CA;MEROITIC CURSIVE NUMBER TWENTY;No;0;R;;;;20;N;;;;;
+109CB;MEROITIC CURSIVE NUMBER THIRTY;No;0;R;;;;30;N;;;;;
+109CC;MEROITIC CURSIVE NUMBER FORTY;No;0;R;;;;40;N;;;;;
+109CD;MEROITIC CURSIVE NUMBER FIFTY;No;0;R;;;;50;N;;;;;
+109CE;MEROITIC CURSIVE NUMBER SIXTY;No;0;R;;;;60;N;;;;;
+109CF;MEROITIC CURSIVE NUMBER SEVENTY;No;0;R;;;;70;N;;;;;
+109D2;MEROITIC CURSIVE NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;;
+109D3;MEROITIC CURSIVE NUMBER TWO HUNDRED;No;0;R;;;;200;N;;;;;
+109D4;MEROITIC CURSIVE NUMBER THREE HUNDRED;No;0;R;;;;300;N;;;;;
+109D5;MEROITIC CURSIVE NUMBER FOUR HUNDRED;No;0;R;;;;400;N;;;;;
+109D6;MEROITIC CURSIVE NUMBER FIVE HUNDRED;No;0;R;;;;500;N;;;;;
+109D7;MEROITIC CURSIVE NUMBER SIX HUNDRED;No;0;R;;;;600;N;;;;;
+109D8;MEROITIC CURSIVE NUMBER SEVEN HUNDRED;No;0;R;;;;700;N;;;;;
+109D9;MEROITIC CURSIVE NUMBER EIGHT HUNDRED;No;0;R;;;;800;N;;;;;
+109DA;MEROITIC CURSIVE NUMBER NINE HUNDRED;No;0;R;;;;900;N;;;;;
+109DB;MEROITIC CURSIVE NUMBER ONE THOUSAND;No;0;R;;;;1000;N;;;;;
+109DC;MEROITIC CURSIVE NUMBER TWO THOUSAND;No;0;R;;;;2000;N;;;;;
+109DD;MEROITIC CURSIVE NUMBER THREE THOUSAND;No;0;R;;;;3000;N;;;;;
+109DE;MEROITIC CURSIVE NUMBER FOUR THOUSAND;No;0;R;;;;4000;N;;;;;
+109DF;MEROITIC CURSIVE NUMBER FIVE THOUSAND;No;0;R;;;;5000;N;;;;;
+109E0;MEROITIC CURSIVE NUMBER SIX THOUSAND;No;0;R;;;;6000;N;;;;;
+109E1;MEROITIC CURSIVE NUMBER SEVEN THOUSAND;No;0;R;;;;7000;N;;;;;
+109E2;MEROITIC CURSIVE NUMBER EIGHT THOUSAND;No;0;R;;;;8000;N;;;;;
+109E3;MEROITIC CURSIVE NUMBER NINE THOUSAND;No;0;R;;;;9000;N;;;;;
+109E4;MEROITIC CURSIVE NUMBER TEN THOUSAND;No;0;R;;;;10000;N;;;;;
+109E5;MEROITIC CURSIVE NUMBER TWENTY THOUSAND;No;0;R;;;;20000;N;;;;;
+109E6;MEROITIC CURSIVE NUMBER THIRTY THOUSAND;No;0;R;;;;30000;N;;;;;
+109E7;MEROITIC CURSIVE NUMBER FORTY THOUSAND;No;0;R;;;;40000;N;;;;;
+109E8;MEROITIC CURSIVE NUMBER FIFTY THOUSAND;No;0;R;;;;50000;N;;;;;
+109E9;MEROITIC CURSIVE NUMBER SIXTY THOUSAND;No;0;R;;;;60000;N;;;;;
+109EA;MEROITIC CURSIVE NUMBER SEVENTY THOUSAND;No;0;R;;;;70000;N;;;;;
+109EB;MEROITIC CURSIVE NUMBER EIGHTY THOUSAND;No;0;R;;;;80000;N;;;;;
+109EC;MEROITIC CURSIVE NUMBER NINETY THOUSAND;No;0;R;;;;90000;N;;;;;
+109ED;MEROITIC CURSIVE NUMBER ONE HUNDRED THOUSAND;No;0;R;;;;100000;N;;;;;
+109EE;MEROITIC CURSIVE NUMBER TWO HUNDRED THOUSAND;No;0;R;;;;200000;N;;;;;
+109EF;MEROITIC CURSIVE NUMBER THREE HUNDRED THOUSAND;No;0;R;;;;300000;N;;;;;
+109F0;MEROITIC CURSIVE NUMBER FOUR HUNDRED THOUSAND;No;0;R;;;;400000;N;;;;;
+109F1;MEROITIC CURSIVE NUMBER FIVE HUNDRED THOUSAND;No;0;R;;;;500000;N;;;;;
+109F2;MEROITIC CURSIVE NUMBER SIX HUNDRED THOUSAND;No;0;R;;;;600000;N;;;;;
+109F3;MEROITIC CURSIVE NUMBER SEVEN HUNDRED THOUSAND;No;0;R;;;;700000;N;;;;;
+109F4;MEROITIC CURSIVE NUMBER EIGHT HUNDRED THOUSAND;No;0;R;;;;800000;N;;;;;
+109F5;MEROITIC CURSIVE NUMBER NINE HUNDRED THOUSAND;No;0;R;;;;900000;N;;;;;
+109F6;MEROITIC CURSIVE FRACTION ONE TWELFTH;No;0;R;;;;1/12;N;;;;;
+109F7;MEROITIC CURSIVE FRACTION TWO TWELFTHS;No;0;R;;;;2/12;N;;;;;
+109F8;MEROITIC CURSIVE FRACTION THREE TWELFTHS;No;0;R;;;;3/12;N;;;;;
+109F9;MEROITIC CURSIVE FRACTION FOUR TWELFTHS;No;0;R;;;;4/12;N;;;;;
+109FA;MEROITIC CURSIVE FRACTION FIVE TWELFTHS;No;0;R;;;;5/12;N;;;;;
+109FB;MEROITIC CURSIVE FRACTION SIX TWELFTHS;No;0;R;;;;6/12;N;;;;;
+109FC;MEROITIC CURSIVE FRACTION SEVEN TWELFTHS;No;0;R;;;;7/12;N;;;;;
+109FD;MEROITIC CURSIVE FRACTION EIGHT TWELFTHS;No;0;R;;;;8/12;N;;;;;
+109FE;MEROITIC CURSIVE FRACTION NINE TWELFTHS;No;0;R;;;;9/12;N;;;;;
+109FF;MEROITIC CURSIVE FRACTION TEN TWELFTHS;No;0;R;;;;10/12;N;;;;;
10A00;KHAROSHTHI LETTER A;Lo;0;R;;;;;N;;;;;
10A01;KHAROSHTHI VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
10A02;KHAROSHTHI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
@@ -16711,6 +18416,89 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
10A7D;OLD SOUTH ARABIAN NUMBER ONE;No;0;R;;;;1;N;;;;;
10A7E;OLD SOUTH ARABIAN NUMBER FIFTY;No;0;R;;;;50;N;;;;;
10A7F;OLD SOUTH ARABIAN NUMERIC INDICATOR;Po;0;R;;;;;N;;;;;
+10A80;OLD NORTH ARABIAN LETTER HEH;Lo;0;R;;;;;N;;;;;
+10A81;OLD NORTH ARABIAN LETTER LAM;Lo;0;R;;;;;N;;;;;
+10A82;OLD NORTH ARABIAN LETTER HAH;Lo;0;R;;;;;N;;;;;
+10A83;OLD NORTH ARABIAN LETTER MEEM;Lo;0;R;;;;;N;;;;;
+10A84;OLD NORTH ARABIAN LETTER QAF;Lo;0;R;;;;;N;;;;;
+10A85;OLD NORTH ARABIAN LETTER WAW;Lo;0;R;;;;;N;;;;;
+10A86;OLD NORTH ARABIAN LETTER ES-2;Lo;0;R;;;;;N;;;;;
+10A87;OLD NORTH ARABIAN LETTER REH;Lo;0;R;;;;;N;;;;;
+10A88;OLD NORTH ARABIAN LETTER BEH;Lo;0;R;;;;;N;;;;;
+10A89;OLD NORTH ARABIAN LETTER TEH;Lo;0;R;;;;;N;;;;;
+10A8A;OLD NORTH ARABIAN LETTER ES-1;Lo;0;R;;;;;N;;;;;
+10A8B;OLD NORTH ARABIAN LETTER KAF;Lo;0;R;;;;;N;;;;;
+10A8C;OLD NORTH ARABIAN LETTER NOON;Lo;0;R;;;;;N;;;;;
+10A8D;OLD NORTH ARABIAN LETTER KHAH;Lo;0;R;;;;;N;;;;;
+10A8E;OLD NORTH ARABIAN LETTER SAD;Lo;0;R;;;;;N;;;;;
+10A8F;OLD NORTH ARABIAN LETTER ES-3;Lo;0;R;;;;;N;;;;;
+10A90;OLD NORTH ARABIAN LETTER FEH;Lo;0;R;;;;;N;;;;;
+10A91;OLD NORTH ARABIAN LETTER ALEF;Lo;0;R;;;;;N;;;;;
+10A92;OLD NORTH ARABIAN LETTER AIN;Lo;0;R;;;;;N;;;;;
+10A93;OLD NORTH ARABIAN LETTER DAD;Lo;0;R;;;;;N;;;;;
+10A94;OLD NORTH ARABIAN LETTER GEEM;Lo;0;R;;;;;N;;;;;
+10A95;OLD NORTH ARABIAN LETTER DAL;Lo;0;R;;;;;N;;;;;
+10A96;OLD NORTH ARABIAN LETTER GHAIN;Lo;0;R;;;;;N;;;;;
+10A97;OLD NORTH ARABIAN LETTER TAH;Lo;0;R;;;;;N;;;;;
+10A98;OLD NORTH ARABIAN LETTER ZAIN;Lo;0;R;;;;;N;;;;;
+10A99;OLD NORTH ARABIAN LETTER THAL;Lo;0;R;;;;;N;;;;;
+10A9A;OLD NORTH ARABIAN LETTER YEH;Lo;0;R;;;;;N;;;;;
+10A9B;OLD NORTH ARABIAN LETTER THEH;Lo;0;R;;;;;N;;;;;
+10A9C;OLD NORTH ARABIAN LETTER ZAH;Lo;0;R;;;;;N;;;;;
+10A9D;OLD NORTH ARABIAN NUMBER ONE;No;0;R;;;;1;N;;;;;
+10A9E;OLD NORTH ARABIAN NUMBER TEN;No;0;R;;;;10;N;;;;;
+10A9F;OLD NORTH ARABIAN NUMBER TWENTY;No;0;R;;;;20;N;;;;;
+10AC0;MANICHAEAN LETTER ALEPH;Lo;0;R;;;;;N;;;;;
+10AC1;MANICHAEAN LETTER BETH;Lo;0;R;;;;;N;;;;;
+10AC2;MANICHAEAN LETTER BHETH;Lo;0;R;;;;;N;;;;;
+10AC3;MANICHAEAN LETTER GIMEL;Lo;0;R;;;;;N;;;;;
+10AC4;MANICHAEAN LETTER GHIMEL;Lo;0;R;;;;;N;;;;;
+10AC5;MANICHAEAN LETTER DALETH;Lo;0;R;;;;;N;;;;;
+10AC6;MANICHAEAN LETTER HE;Lo;0;R;;;;;N;;;;;
+10AC7;MANICHAEAN LETTER WAW;Lo;0;R;;;;;N;;;;;
+10AC8;MANICHAEAN SIGN UD;So;0;R;;;;;N;;;;;
+10AC9;MANICHAEAN LETTER ZAYIN;Lo;0;R;;;;;N;;;;;
+10ACA;MANICHAEAN LETTER ZHAYIN;Lo;0;R;;;;;N;;;;;
+10ACB;MANICHAEAN LETTER JAYIN;Lo;0;R;;;;;N;;;;;
+10ACC;MANICHAEAN LETTER JHAYIN;Lo;0;R;;;;;N;;;;;
+10ACD;MANICHAEAN LETTER HETH;Lo;0;R;;;;;N;;;;;
+10ACE;MANICHAEAN LETTER TETH;Lo;0;R;;;;;N;;;;;
+10ACF;MANICHAEAN LETTER YODH;Lo;0;R;;;;;N;;;;;
+10AD0;MANICHAEAN LETTER KAPH;Lo;0;R;;;;;N;;;;;
+10AD1;MANICHAEAN LETTER XAPH;Lo;0;R;;;;;N;;;;;
+10AD2;MANICHAEAN LETTER KHAPH;Lo;0;R;;;;;N;;;;;
+10AD3;MANICHAEAN LETTER LAMEDH;Lo;0;R;;;;;N;;;;;
+10AD4;MANICHAEAN LETTER DHAMEDH;Lo;0;R;;;;;N;;;;;
+10AD5;MANICHAEAN LETTER THAMEDH;Lo;0;R;;;;;N;;;;;
+10AD6;MANICHAEAN LETTER MEM;Lo;0;R;;;;;N;;;;;
+10AD7;MANICHAEAN LETTER NUN;Lo;0;R;;;;;N;;;;;
+10AD8;MANICHAEAN LETTER SAMEKH;Lo;0;R;;;;;N;;;;;
+10AD9;MANICHAEAN LETTER AYIN;Lo;0;R;;;;;N;;;;;
+10ADA;MANICHAEAN LETTER AAYIN;Lo;0;R;;;;;N;;;;;
+10ADB;MANICHAEAN LETTER PE;Lo;0;R;;;;;N;;;;;
+10ADC;MANICHAEAN LETTER FE;Lo;0;R;;;;;N;;;;;
+10ADD;MANICHAEAN LETTER SADHE;Lo;0;R;;;;;N;;;;;
+10ADE;MANICHAEAN LETTER QOPH;Lo;0;R;;;;;N;;;;;
+10ADF;MANICHAEAN LETTER XOPH;Lo;0;R;;;;;N;;;;;
+10AE0;MANICHAEAN LETTER QHOPH;Lo;0;R;;;;;N;;;;;
+10AE1;MANICHAEAN LETTER RESH;Lo;0;R;;;;;N;;;;;
+10AE2;MANICHAEAN LETTER SHIN;Lo;0;R;;;;;N;;;;;
+10AE3;MANICHAEAN LETTER SSHIN;Lo;0;R;;;;;N;;;;;
+10AE4;MANICHAEAN LETTER TAW;Lo;0;R;;;;;N;;;;;
+10AE5;MANICHAEAN ABBREVIATION MARK ABOVE;Mn;230;NSM;;;;;N;;;;;
+10AE6;MANICHAEAN ABBREVIATION MARK BELOW;Mn;220;NSM;;;;;N;;;;;
+10AEB;MANICHAEAN NUMBER ONE;No;0;R;;;;1;N;;;;;
+10AEC;MANICHAEAN NUMBER FIVE;No;0;R;;;;5;N;;;;;
+10AED;MANICHAEAN NUMBER TEN;No;0;R;;;;10;N;;;;;
+10AEE;MANICHAEAN NUMBER TWENTY;No;0;R;;;;20;N;;;;;
+10AEF;MANICHAEAN NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;;
+10AF0;MANICHAEAN PUNCTUATION STAR;Po;0;R;;;;;N;;;;;
+10AF1;MANICHAEAN PUNCTUATION FLEURON;Po;0;R;;;;;N;;;;;
+10AF2;MANICHAEAN PUNCTUATION DOUBLE DOT WITHIN DOT;Po;0;R;;;;;N;;;;;
+10AF3;MANICHAEAN PUNCTUATION DOT WITHIN DOT;Po;0;R;;;;;N;;;;;
+10AF4;MANICHAEAN PUNCTUATION DOT;Po;0;R;;;;;N;;;;;
+10AF5;MANICHAEAN PUNCTUATION TWO DOTS;Po;0;R;;;;;N;;;;;
+10AF6;MANICHAEAN PUNCTUATION LINE FILLER;Po;0;R;;;;;N;;;;;
10B00;AVESTAN LETTER A;Lo;0;R;;;;;N;;;;;
10B01;AVESTAN LETTER AA;Lo;0;R;;;;;N;;;;;
10B02;AVESTAN LETTER AO;Lo;0;R;;;;;N;;;;;
@@ -16829,6 +18617,35 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
10B7D;INSCRIPTIONAL PAHLAVI NUMBER TWENTY;No;0;R;;;;20;N;;;;;
10B7E;INSCRIPTIONAL PAHLAVI NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;;
10B7F;INSCRIPTIONAL PAHLAVI NUMBER ONE THOUSAND;No;0;R;;;;1000;N;;;;;
+10B80;PSALTER PAHLAVI LETTER ALEPH;Lo;0;R;;;;;N;;;;;
+10B81;PSALTER PAHLAVI LETTER BETH;Lo;0;R;;;;;N;;;;;
+10B82;PSALTER PAHLAVI LETTER GIMEL;Lo;0;R;;;;;N;;;;;
+10B83;PSALTER PAHLAVI LETTER DALETH;Lo;0;R;;;;;N;;;;;
+10B84;PSALTER PAHLAVI LETTER HE;Lo;0;R;;;;;N;;;;;
+10B85;PSALTER PAHLAVI LETTER WAW-AYIN-RESH;Lo;0;R;;;;;N;;;;;
+10B86;PSALTER PAHLAVI LETTER ZAYIN;Lo;0;R;;;;;N;;;;;
+10B87;PSALTER PAHLAVI LETTER HETH;Lo;0;R;;;;;N;;;;;
+10B88;PSALTER PAHLAVI LETTER YODH;Lo;0;R;;;;;N;;;;;
+10B89;PSALTER PAHLAVI LETTER KAPH;Lo;0;R;;;;;N;;;;;
+10B8A;PSALTER PAHLAVI LETTER LAMEDH;Lo;0;R;;;;;N;;;;;
+10B8B;PSALTER PAHLAVI LETTER MEM-QOPH;Lo;0;R;;;;;N;;;;;
+10B8C;PSALTER PAHLAVI LETTER NUN;Lo;0;R;;;;;N;;;;;
+10B8D;PSALTER PAHLAVI LETTER SAMEKH;Lo;0;R;;;;;N;;;;;
+10B8E;PSALTER PAHLAVI LETTER PE;Lo;0;R;;;;;N;;;;;
+10B8F;PSALTER PAHLAVI LETTER SADHE;Lo;0;R;;;;;N;;;;;
+10B90;PSALTER PAHLAVI LETTER SHIN;Lo;0;R;;;;;N;;;;;
+10B91;PSALTER PAHLAVI LETTER TAW;Lo;0;R;;;;;N;;;;;
+10B99;PSALTER PAHLAVI SECTION MARK;Po;0;R;;;;;N;;;;;
+10B9A;PSALTER PAHLAVI TURNED SECTION MARK;Po;0;R;;;;;N;;;;;
+10B9B;PSALTER PAHLAVI FOUR DOTS WITH CROSS;Po;0;R;;;;;N;;;;;
+10B9C;PSALTER PAHLAVI FOUR DOTS WITH DOT;Po;0;R;;;;;N;;;;;
+10BA9;PSALTER PAHLAVI NUMBER ONE;No;0;R;;;;1;N;;;;;
+10BAA;PSALTER PAHLAVI NUMBER TWO;No;0;R;;;;2;N;;;;;
+10BAB;PSALTER PAHLAVI NUMBER THREE;No;0;R;;;;3;N;;;;;
+10BAC;PSALTER PAHLAVI NUMBER FOUR;No;0;R;;;;4;N;;;;;
+10BAD;PSALTER PAHLAVI NUMBER TEN;No;0;R;;;;10;N;;;;;
+10BAE;PSALTER PAHLAVI NUMBER TWENTY;No;0;R;;;;20;N;;;;;
+10BAF;PSALTER PAHLAVI NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;;
10C00;OLD TURKIC LETTER ORKHON A;Lo;0;R;;;;;N;;;;;
10C01;OLD TURKIC LETTER YENISEI A;Lo;0;R;;;;;N;;;;;
10C02;OLD TURKIC LETTER YENISEI AE;Lo;0;R;;;;;N;;;;;
@@ -16902,6 +18719,114 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
10C46;OLD TURKIC LETTER YENISEI AET;Lo;0;R;;;;;N;;;;;
10C47;OLD TURKIC LETTER ORKHON OT;Lo;0;R;;;;;N;;;;;
10C48;OLD TURKIC LETTER ORKHON BASH;Lo;0;R;;;;;N;;;;;
+10C80;OLD HUNGARIAN CAPITAL LETTER A;Lu;0;R;;;;;N;;;;10CC0;
+10C81;OLD HUNGARIAN CAPITAL LETTER AA;Lu;0;R;;;;;N;;;;10CC1;
+10C82;OLD HUNGARIAN CAPITAL LETTER EB;Lu;0;R;;;;;N;;;;10CC2;
+10C83;OLD HUNGARIAN CAPITAL LETTER AMB;Lu;0;R;;;;;N;;;;10CC3;
+10C84;OLD HUNGARIAN CAPITAL LETTER EC;Lu;0;R;;;;;N;;;;10CC4;
+10C85;OLD HUNGARIAN CAPITAL LETTER ENC;Lu;0;R;;;;;N;;;;10CC5;
+10C86;OLD HUNGARIAN CAPITAL LETTER ECS;Lu;0;R;;;;;N;;;;10CC6;
+10C87;OLD HUNGARIAN CAPITAL LETTER ED;Lu;0;R;;;;;N;;;;10CC7;
+10C88;OLD HUNGARIAN CAPITAL LETTER AND;Lu;0;R;;;;;N;;;;10CC8;
+10C89;OLD HUNGARIAN CAPITAL LETTER E;Lu;0;R;;;;;N;;;;10CC9;
+10C8A;OLD HUNGARIAN CAPITAL LETTER CLOSE E;Lu;0;R;;;;;N;;;;10CCA;
+10C8B;OLD HUNGARIAN CAPITAL LETTER EE;Lu;0;R;;;;;N;;;;10CCB;
+10C8C;OLD HUNGARIAN CAPITAL LETTER EF;Lu;0;R;;;;;N;;;;10CCC;
+10C8D;OLD HUNGARIAN CAPITAL LETTER EG;Lu;0;R;;;;;N;;;;10CCD;
+10C8E;OLD HUNGARIAN CAPITAL LETTER EGY;Lu;0;R;;;;;N;;;;10CCE;
+10C8F;OLD HUNGARIAN CAPITAL LETTER EH;Lu;0;R;;;;;N;;;;10CCF;
+10C90;OLD HUNGARIAN CAPITAL LETTER I;Lu;0;R;;;;;N;;;;10CD0;
+10C91;OLD HUNGARIAN CAPITAL LETTER II;Lu;0;R;;;;;N;;;;10CD1;
+10C92;OLD HUNGARIAN CAPITAL LETTER EJ;Lu;0;R;;;;;N;;;;10CD2;
+10C93;OLD HUNGARIAN CAPITAL LETTER EK;Lu;0;R;;;;;N;;;;10CD3;
+10C94;OLD HUNGARIAN CAPITAL LETTER AK;Lu;0;R;;;;;N;;;;10CD4;
+10C95;OLD HUNGARIAN CAPITAL LETTER UNK;Lu;0;R;;;;;N;;;;10CD5;
+10C96;OLD HUNGARIAN CAPITAL LETTER EL;Lu;0;R;;;;;N;;;;10CD6;
+10C97;OLD HUNGARIAN CAPITAL LETTER ELY;Lu;0;R;;;;;N;;;;10CD7;
+10C98;OLD HUNGARIAN CAPITAL LETTER EM;Lu;0;R;;;;;N;;;;10CD8;
+10C99;OLD HUNGARIAN CAPITAL LETTER EN;Lu;0;R;;;;;N;;;;10CD9;
+10C9A;OLD HUNGARIAN CAPITAL LETTER ENY;Lu;0;R;;;;;N;;;;10CDA;
+10C9B;OLD HUNGARIAN CAPITAL LETTER O;Lu;0;R;;;;;N;;;;10CDB;
+10C9C;OLD HUNGARIAN CAPITAL LETTER OO;Lu;0;R;;;;;N;;;;10CDC;
+10C9D;OLD HUNGARIAN CAPITAL LETTER NIKOLSBURG OE;Lu;0;R;;;;;N;;;;10CDD;
+10C9E;OLD HUNGARIAN CAPITAL LETTER RUDIMENTA OE;Lu;0;R;;;;;N;;;;10CDE;
+10C9F;OLD HUNGARIAN CAPITAL LETTER OEE;Lu;0;R;;;;;N;;;;10CDF;
+10CA0;OLD HUNGARIAN CAPITAL LETTER EP;Lu;0;R;;;;;N;;;;10CE0;
+10CA1;OLD HUNGARIAN CAPITAL LETTER EMP;Lu;0;R;;;;;N;;;;10CE1;
+10CA2;OLD HUNGARIAN CAPITAL LETTER ER;Lu;0;R;;;;;N;;;;10CE2;
+10CA3;OLD HUNGARIAN CAPITAL LETTER SHORT ER;Lu;0;R;;;;;N;;;;10CE3;
+10CA4;OLD HUNGARIAN CAPITAL LETTER ES;Lu;0;R;;;;;N;;;;10CE4;
+10CA5;OLD HUNGARIAN CAPITAL LETTER ESZ;Lu;0;R;;;;;N;;;;10CE5;
+10CA6;OLD HUNGARIAN CAPITAL LETTER ET;Lu;0;R;;;;;N;;;;10CE6;
+10CA7;OLD HUNGARIAN CAPITAL LETTER ENT;Lu;0;R;;;;;N;;;;10CE7;
+10CA8;OLD HUNGARIAN CAPITAL LETTER ETY;Lu;0;R;;;;;N;;;;10CE8;
+10CA9;OLD HUNGARIAN CAPITAL LETTER ECH;Lu;0;R;;;;;N;;;;10CE9;
+10CAA;OLD HUNGARIAN CAPITAL LETTER U;Lu;0;R;;;;;N;;;;10CEA;
+10CAB;OLD HUNGARIAN CAPITAL LETTER UU;Lu;0;R;;;;;N;;;;10CEB;
+10CAC;OLD HUNGARIAN CAPITAL LETTER NIKOLSBURG UE;Lu;0;R;;;;;N;;;;10CEC;
+10CAD;OLD HUNGARIAN CAPITAL LETTER RUDIMENTA UE;Lu;0;R;;;;;N;;;;10CED;
+10CAE;OLD HUNGARIAN CAPITAL LETTER EV;Lu;0;R;;;;;N;;;;10CEE;
+10CAF;OLD HUNGARIAN CAPITAL LETTER EZ;Lu;0;R;;;;;N;;;;10CEF;
+10CB0;OLD HUNGARIAN CAPITAL LETTER EZS;Lu;0;R;;;;;N;;;;10CF0;
+10CB1;OLD HUNGARIAN CAPITAL LETTER ENT-SHAPED SIGN;Lu;0;R;;;;;N;;;;10CF1;
+10CB2;OLD HUNGARIAN CAPITAL LETTER US;Lu;0;R;;;;;N;;;;10CF2;
+10CC0;OLD HUNGARIAN SMALL LETTER A;Ll;0;R;;;;;N;;;10C80;;10C80
+10CC1;OLD HUNGARIAN SMALL LETTER AA;Ll;0;R;;;;;N;;;10C81;;10C81
+10CC2;OLD HUNGARIAN SMALL LETTER EB;Ll;0;R;;;;;N;;;10C82;;10C82
+10CC3;OLD HUNGARIAN SMALL LETTER AMB;Ll;0;R;;;;;N;;;10C83;;10C83
+10CC4;OLD HUNGARIAN SMALL LETTER EC;Ll;0;R;;;;;N;;;10C84;;10C84
+10CC5;OLD HUNGARIAN SMALL LETTER ENC;Ll;0;R;;;;;N;;;10C85;;10C85
+10CC6;OLD HUNGARIAN SMALL LETTER ECS;Ll;0;R;;;;;N;;;10C86;;10C86
+10CC7;OLD HUNGARIAN SMALL LETTER ED;Ll;0;R;;;;;N;;;10C87;;10C87
+10CC8;OLD HUNGARIAN SMALL LETTER AND;Ll;0;R;;;;;N;;;10C88;;10C88
+10CC9;OLD HUNGARIAN SMALL LETTER E;Ll;0;R;;;;;N;;;10C89;;10C89
+10CCA;OLD HUNGARIAN SMALL LETTER CLOSE E;Ll;0;R;;;;;N;;;10C8A;;10C8A
+10CCB;OLD HUNGARIAN SMALL LETTER EE;Ll;0;R;;;;;N;;;10C8B;;10C8B
+10CCC;OLD HUNGARIAN SMALL LETTER EF;Ll;0;R;;;;;N;;;10C8C;;10C8C
+10CCD;OLD HUNGARIAN SMALL LETTER EG;Ll;0;R;;;;;N;;;10C8D;;10C8D
+10CCE;OLD HUNGARIAN SMALL LETTER EGY;Ll;0;R;;;;;N;;;10C8E;;10C8E
+10CCF;OLD HUNGARIAN SMALL LETTER EH;Ll;0;R;;;;;N;;;10C8F;;10C8F
+10CD0;OLD HUNGARIAN SMALL LETTER I;Ll;0;R;;;;;N;;;10C90;;10C90
+10CD1;OLD HUNGARIAN SMALL LETTER II;Ll;0;R;;;;;N;;;10C91;;10C91
+10CD2;OLD HUNGARIAN SMALL LETTER EJ;Ll;0;R;;;;;N;;;10C92;;10C92
+10CD3;OLD HUNGARIAN SMALL LETTER EK;Ll;0;R;;;;;N;;;10C93;;10C93
+10CD4;OLD HUNGARIAN SMALL LETTER AK;Ll;0;R;;;;;N;;;10C94;;10C94
+10CD5;OLD HUNGARIAN SMALL LETTER UNK;Ll;0;R;;;;;N;;;10C95;;10C95
+10CD6;OLD HUNGARIAN SMALL LETTER EL;Ll;0;R;;;;;N;;;10C96;;10C96
+10CD7;OLD HUNGARIAN SMALL LETTER ELY;Ll;0;R;;;;;N;;;10C97;;10C97
+10CD8;OLD HUNGARIAN SMALL LETTER EM;Ll;0;R;;;;;N;;;10C98;;10C98
+10CD9;OLD HUNGARIAN SMALL LETTER EN;Ll;0;R;;;;;N;;;10C99;;10C99
+10CDA;OLD HUNGARIAN SMALL LETTER ENY;Ll;0;R;;;;;N;;;10C9A;;10C9A
+10CDB;OLD HUNGARIAN SMALL LETTER O;Ll;0;R;;;;;N;;;10C9B;;10C9B
+10CDC;OLD HUNGARIAN SMALL LETTER OO;Ll;0;R;;;;;N;;;10C9C;;10C9C
+10CDD;OLD HUNGARIAN SMALL LETTER NIKOLSBURG OE;Ll;0;R;;;;;N;;;10C9D;;10C9D
+10CDE;OLD HUNGARIAN SMALL LETTER RUDIMENTA OE;Ll;0;R;;;;;N;;;10C9E;;10C9E
+10CDF;OLD HUNGARIAN SMALL LETTER OEE;Ll;0;R;;;;;N;;;10C9F;;10C9F
+10CE0;OLD HUNGARIAN SMALL LETTER EP;Ll;0;R;;;;;N;;;10CA0;;10CA0
+10CE1;OLD HUNGARIAN SMALL LETTER EMP;Ll;0;R;;;;;N;;;10CA1;;10CA1
+10CE2;OLD HUNGARIAN SMALL LETTER ER;Ll;0;R;;;;;N;;;10CA2;;10CA2
+10CE3;OLD HUNGARIAN SMALL LETTER SHORT ER;Ll;0;R;;;;;N;;;10CA3;;10CA3
+10CE4;OLD HUNGARIAN SMALL LETTER ES;Ll;0;R;;;;;N;;;10CA4;;10CA4
+10CE5;OLD HUNGARIAN SMALL LETTER ESZ;Ll;0;R;;;;;N;;;10CA5;;10CA5
+10CE6;OLD HUNGARIAN SMALL LETTER ET;Ll;0;R;;;;;N;;;10CA6;;10CA6
+10CE7;OLD HUNGARIAN SMALL LETTER ENT;Ll;0;R;;;;;N;;;10CA7;;10CA7
+10CE8;OLD HUNGARIAN SMALL LETTER ETY;Ll;0;R;;;;;N;;;10CA8;;10CA8
+10CE9;OLD HUNGARIAN SMALL LETTER ECH;Ll;0;R;;;;;N;;;10CA9;;10CA9
+10CEA;OLD HUNGARIAN SMALL LETTER U;Ll;0;R;;;;;N;;;10CAA;;10CAA
+10CEB;OLD HUNGARIAN SMALL LETTER UU;Ll;0;R;;;;;N;;;10CAB;;10CAB
+10CEC;OLD HUNGARIAN SMALL LETTER NIKOLSBURG UE;Ll;0;R;;;;;N;;;10CAC;;10CAC
+10CED;OLD HUNGARIAN SMALL LETTER RUDIMENTA UE;Ll;0;R;;;;;N;;;10CAD;;10CAD
+10CEE;OLD HUNGARIAN SMALL LETTER EV;Ll;0;R;;;;;N;;;10CAE;;10CAE
+10CEF;OLD HUNGARIAN SMALL LETTER EZ;Ll;0;R;;;;;N;;;10CAF;;10CAF
+10CF0;OLD HUNGARIAN SMALL LETTER EZS;Ll;0;R;;;;;N;;;10CB0;;10CB0
+10CF1;OLD HUNGARIAN SMALL LETTER ENT-SHAPED SIGN;Ll;0;R;;;;;N;;;10CB1;;10CB1
+10CF2;OLD HUNGARIAN SMALL LETTER US;Ll;0;R;;;;;N;;;10CB2;;10CB2
+10CFA;OLD HUNGARIAN NUMBER ONE;No;0;R;;;;1;N;;;;;
+10CFB;OLD HUNGARIAN NUMBER FIVE;No;0;R;;;;5;N;;;;;
+10CFC;OLD HUNGARIAN NUMBER TEN;No;0;R;;;;10;N;;;;;
+10CFD;OLD HUNGARIAN NUMBER FIFTY;No;0;R;;;;50;N;;;;;
+10CFE;OLD HUNGARIAN NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;;
+10CFF;OLD HUNGARIAN NUMBER ONE THOUSAND;No;0;R;;;;1000;N;;;;;
10E60;RUMI DIGIT ONE;No;0;AN;;;1;1;N;;;;;
10E61;RUMI DIGIT TWO;No;0;AN;;;2;2;N;;;;;
10E62;RUMI DIGIT THREE;No;0;AN;;;3;3;N;;;;;
@@ -16933,6 +18858,115 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
10E7C;RUMI FRACTION ONE QUARTER;No;0;AN;;;;1/4;N;;;;;
10E7D;RUMI FRACTION ONE THIRD;No;0;AN;;;;1/3;N;;;;;
10E7E;RUMI FRACTION TWO THIRDS;No;0;AN;;;;2/3;N;;;;;
+11000;BRAHMI SIGN CANDRABINDU;Mc;0;L;;;;;N;;;;;
+11001;BRAHMI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+11002;BRAHMI SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+11003;BRAHMI SIGN JIHVAMULIYA;Lo;0;L;;;;;N;;;;;
+11004;BRAHMI SIGN UPADHMANIYA;Lo;0;L;;;;;N;;;;;
+11005;BRAHMI LETTER A;Lo;0;L;;;;;N;;;;;
+11006;BRAHMI LETTER AA;Lo;0;L;;;;;N;;;;;
+11007;BRAHMI LETTER I;Lo;0;L;;;;;N;;;;;
+11008;BRAHMI LETTER II;Lo;0;L;;;;;N;;;;;
+11009;BRAHMI LETTER U;Lo;0;L;;;;;N;;;;;
+1100A;BRAHMI LETTER UU;Lo;0;L;;;;;N;;;;;
+1100B;BRAHMI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+1100C;BRAHMI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+1100D;BRAHMI LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
+1100E;BRAHMI LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
+1100F;BRAHMI LETTER E;Lo;0;L;;;;;N;;;;;
+11010;BRAHMI LETTER AI;Lo;0;L;;;;;N;;;;;
+11011;BRAHMI LETTER O;Lo;0;L;;;;;N;;;;;
+11012;BRAHMI LETTER AU;Lo;0;L;;;;;N;;;;;
+11013;BRAHMI LETTER KA;Lo;0;L;;;;;N;;;;;
+11014;BRAHMI LETTER KHA;Lo;0;L;;;;;N;;;;;
+11015;BRAHMI LETTER GA;Lo;0;L;;;;;N;;;;;
+11016;BRAHMI LETTER GHA;Lo;0;L;;;;;N;;;;;
+11017;BRAHMI LETTER NGA;Lo;0;L;;;;;N;;;;;
+11018;BRAHMI LETTER CA;Lo;0;L;;;;;N;;;;;
+11019;BRAHMI LETTER CHA;Lo;0;L;;;;;N;;;;;
+1101A;BRAHMI LETTER JA;Lo;0;L;;;;;N;;;;;
+1101B;BRAHMI LETTER JHA;Lo;0;L;;;;;N;;;;;
+1101C;BRAHMI LETTER NYA;Lo;0;L;;;;;N;;;;;
+1101D;BRAHMI LETTER TTA;Lo;0;L;;;;;N;;;;;
+1101E;BRAHMI LETTER TTHA;Lo;0;L;;;;;N;;;;;
+1101F;BRAHMI LETTER DDA;Lo;0;L;;;;;N;;;;;
+11020;BRAHMI LETTER DDHA;Lo;0;L;;;;;N;;;;;
+11021;BRAHMI LETTER NNA;Lo;0;L;;;;;N;;;;;
+11022;BRAHMI LETTER TA;Lo;0;L;;;;;N;;;;;
+11023;BRAHMI LETTER THA;Lo;0;L;;;;;N;;;;;
+11024;BRAHMI LETTER DA;Lo;0;L;;;;;N;;;;;
+11025;BRAHMI LETTER DHA;Lo;0;L;;;;;N;;;;;
+11026;BRAHMI LETTER NA;Lo;0;L;;;;;N;;;;;
+11027;BRAHMI LETTER PA;Lo;0;L;;;;;N;;;;;
+11028;BRAHMI LETTER PHA;Lo;0;L;;;;;N;;;;;
+11029;BRAHMI LETTER BA;Lo;0;L;;;;;N;;;;;
+1102A;BRAHMI LETTER BHA;Lo;0;L;;;;;N;;;;;
+1102B;BRAHMI LETTER MA;Lo;0;L;;;;;N;;;;;
+1102C;BRAHMI LETTER YA;Lo;0;L;;;;;N;;;;;
+1102D;BRAHMI LETTER RA;Lo;0;L;;;;;N;;;;;
+1102E;BRAHMI LETTER LA;Lo;0;L;;;;;N;;;;;
+1102F;BRAHMI LETTER VA;Lo;0;L;;;;;N;;;;;
+11030;BRAHMI LETTER SHA;Lo;0;L;;;;;N;;;;;
+11031;BRAHMI LETTER SSA;Lo;0;L;;;;;N;;;;;
+11032;BRAHMI LETTER SA;Lo;0;L;;;;;N;;;;;
+11033;BRAHMI LETTER HA;Lo;0;L;;;;;N;;;;;
+11034;BRAHMI LETTER LLA;Lo;0;L;;;;;N;;;;;
+11035;BRAHMI LETTER OLD TAMIL LLLA;Lo;0;L;;;;;N;;;;;
+11036;BRAHMI LETTER OLD TAMIL RRA;Lo;0;L;;;;;N;;;;;
+11037;BRAHMI LETTER OLD TAMIL NNNA;Lo;0;L;;;;;N;;;;;
+11038;BRAHMI VOWEL SIGN AA;Mn;0;NSM;;;;;N;;;;;
+11039;BRAHMI VOWEL SIGN BHATTIPROLU AA;Mn;0;NSM;;;;;N;;;;;
+1103A;BRAHMI VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+1103B;BRAHMI VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;
+1103C;BRAHMI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+1103D;BRAHMI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+1103E;BRAHMI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
+1103F;BRAHMI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;
+11040;BRAHMI VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
+11041;BRAHMI VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;
+11042;BRAHMI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+11043;BRAHMI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
+11044;BRAHMI VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;
+11045;BRAHMI VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;;
+11046;BRAHMI VIRAMA;Mn;9;NSM;;;;;N;;;;;
+11047;BRAHMI DANDA;Po;0;L;;;;;N;;;;;
+11048;BRAHMI DOUBLE DANDA;Po;0;L;;;;;N;;;;;
+11049;BRAHMI PUNCTUATION DOT;Po;0;L;;;;;N;;;;;
+1104A;BRAHMI PUNCTUATION DOUBLE DOT;Po;0;L;;;;;N;;;;;
+1104B;BRAHMI PUNCTUATION LINE;Po;0;L;;;;;N;;;;;
+1104C;BRAHMI PUNCTUATION CRESCENT BAR;Po;0;L;;;;;N;;;;;
+1104D;BRAHMI PUNCTUATION LOTUS;Po;0;L;;;;;N;;;;;
+11052;BRAHMI NUMBER ONE;No;0;ON;;;1;1;N;;;;;
+11053;BRAHMI NUMBER TWO;No;0;ON;;;2;2;N;;;;;
+11054;BRAHMI NUMBER THREE;No;0;ON;;;3;3;N;;;;;
+11055;BRAHMI NUMBER FOUR;No;0;ON;;;4;4;N;;;;;
+11056;BRAHMI NUMBER FIVE;No;0;ON;;;5;5;N;;;;;
+11057;BRAHMI NUMBER SIX;No;0;ON;;;6;6;N;;;;;
+11058;BRAHMI NUMBER SEVEN;No;0;ON;;;7;7;N;;;;;
+11059;BRAHMI NUMBER EIGHT;No;0;ON;;;8;8;N;;;;;
+1105A;BRAHMI NUMBER NINE;No;0;ON;;;9;9;N;;;;;
+1105B;BRAHMI NUMBER TEN;No;0;ON;;;;10;N;;;;;
+1105C;BRAHMI NUMBER TWENTY;No;0;ON;;;;20;N;;;;;
+1105D;BRAHMI NUMBER THIRTY;No;0;ON;;;;30;N;;;;;
+1105E;BRAHMI NUMBER FORTY;No;0;ON;;;;40;N;;;;;
+1105F;BRAHMI NUMBER FIFTY;No;0;ON;;;;50;N;;;;;
+11060;BRAHMI NUMBER SIXTY;No;0;ON;;;;60;N;;;;;
+11061;BRAHMI NUMBER SEVENTY;No;0;ON;;;;70;N;;;;;
+11062;BRAHMI NUMBER EIGHTY;No;0;ON;;;;80;N;;;;;
+11063;BRAHMI NUMBER NINETY;No;0;ON;;;;90;N;;;;;
+11064;BRAHMI NUMBER ONE HUNDRED;No;0;ON;;;;100;N;;;;;
+11065;BRAHMI NUMBER ONE THOUSAND;No;0;ON;;;;1000;N;;;;;
+11066;BRAHMI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+11067;BRAHMI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+11068;BRAHMI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+11069;BRAHMI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+1106A;BRAHMI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+1106B;BRAHMI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+1106C;BRAHMI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+1106D;BRAHMI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+1106E;BRAHMI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+1106F;BRAHMI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+1107F;BRAHMI NUMBER JOINER;Mn;9;NSM;;;;;N;;;;;
11080;KAITHI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
11081;KAITHI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
11082;KAITHI SIGN VISARGA;Mc;0;L;;;;;N;;;;;
@@ -16999,6 +19033,1529 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
110BF;KAITHI DOUBLE SECTION MARK;Po;0;L;;;;;N;;;;;
110C0;KAITHI DANDA;Po;0;L;;;;;N;;;;;
110C1;KAITHI DOUBLE DANDA;Po;0;L;;;;;N;;;;;
+110D0;SORA SOMPENG LETTER SAH;Lo;0;L;;;;;N;;;;;
+110D1;SORA SOMPENG LETTER TAH;Lo;0;L;;;;;N;;;;;
+110D2;SORA SOMPENG LETTER BAH;Lo;0;L;;;;;N;;;;;
+110D3;SORA SOMPENG LETTER CAH;Lo;0;L;;;;;N;;;;;
+110D4;SORA SOMPENG LETTER DAH;Lo;0;L;;;;;N;;;;;
+110D5;SORA SOMPENG LETTER GAH;Lo;0;L;;;;;N;;;;;
+110D6;SORA SOMPENG LETTER MAH;Lo;0;L;;;;;N;;;;;
+110D7;SORA SOMPENG LETTER NGAH;Lo;0;L;;;;;N;;;;;
+110D8;SORA SOMPENG LETTER LAH;Lo;0;L;;;;;N;;;;;
+110D9;SORA SOMPENG LETTER NAH;Lo;0;L;;;;;N;;;;;
+110DA;SORA SOMPENG LETTER VAH;Lo;0;L;;;;;N;;;;;
+110DB;SORA SOMPENG LETTER PAH;Lo;0;L;;;;;N;;;;;
+110DC;SORA SOMPENG LETTER YAH;Lo;0;L;;;;;N;;;;;
+110DD;SORA SOMPENG LETTER RAH;Lo;0;L;;;;;N;;;;;
+110DE;SORA SOMPENG LETTER HAH;Lo;0;L;;;;;N;;;;;
+110DF;SORA SOMPENG LETTER KAH;Lo;0;L;;;;;N;;;;;
+110E0;SORA SOMPENG LETTER JAH;Lo;0;L;;;;;N;;;;;
+110E1;SORA SOMPENG LETTER NYAH;Lo;0;L;;;;;N;;;;;
+110E2;SORA SOMPENG LETTER AH;Lo;0;L;;;;;N;;;;;
+110E3;SORA SOMPENG LETTER EEH;Lo;0;L;;;;;N;;;;;
+110E4;SORA SOMPENG LETTER IH;Lo;0;L;;;;;N;;;;;
+110E5;SORA SOMPENG LETTER UH;Lo;0;L;;;;;N;;;;;
+110E6;SORA SOMPENG LETTER OH;Lo;0;L;;;;;N;;;;;
+110E7;SORA SOMPENG LETTER EH;Lo;0;L;;;;;N;;;;;
+110E8;SORA SOMPENG LETTER MAE;Lo;0;L;;;;;N;;;;;
+110F0;SORA SOMPENG DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+110F1;SORA SOMPENG DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+110F2;SORA SOMPENG DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+110F3;SORA SOMPENG DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+110F4;SORA SOMPENG DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+110F5;SORA SOMPENG DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+110F6;SORA SOMPENG DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+110F7;SORA SOMPENG DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+110F8;SORA SOMPENG DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+110F9;SORA SOMPENG DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+11100;CHAKMA SIGN CANDRABINDU;Mn;230;NSM;;;;;N;;;;;
+11101;CHAKMA SIGN ANUSVARA;Mn;230;NSM;;;;;N;;;;;
+11102;CHAKMA SIGN VISARGA;Mn;230;NSM;;;;;N;;;;;
+11103;CHAKMA LETTER AA;Lo;0;L;;;;;N;;;;;
+11104;CHAKMA LETTER I;Lo;0;L;;;;;N;;;;;
+11105;CHAKMA LETTER U;Lo;0;L;;;;;N;;;;;
+11106;CHAKMA LETTER E;Lo;0;L;;;;;N;;;;;
+11107;CHAKMA LETTER KAA;Lo;0;L;;;;;N;;;;;
+11108;CHAKMA LETTER KHAA;Lo;0;L;;;;;N;;;;;
+11109;CHAKMA LETTER GAA;Lo;0;L;;;;;N;;;;;
+1110A;CHAKMA LETTER GHAA;Lo;0;L;;;;;N;;;;;
+1110B;CHAKMA LETTER NGAA;Lo;0;L;;;;;N;;;;;
+1110C;CHAKMA LETTER CAA;Lo;0;L;;;;;N;;;;;
+1110D;CHAKMA LETTER CHAA;Lo;0;L;;;;;N;;;;;
+1110E;CHAKMA LETTER JAA;Lo;0;L;;;;;N;;;;;
+1110F;CHAKMA LETTER JHAA;Lo;0;L;;;;;N;;;;;
+11110;CHAKMA LETTER NYAA;Lo;0;L;;;;;N;;;;;
+11111;CHAKMA LETTER TTAA;Lo;0;L;;;;;N;;;;;
+11112;CHAKMA LETTER TTHAA;Lo;0;L;;;;;N;;;;;
+11113;CHAKMA LETTER DDAA;Lo;0;L;;;;;N;;;;;
+11114;CHAKMA LETTER DDHAA;Lo;0;L;;;;;N;;;;;
+11115;CHAKMA LETTER NNAA;Lo;0;L;;;;;N;;;;;
+11116;CHAKMA LETTER TAA;Lo;0;L;;;;;N;;;;;
+11117;CHAKMA LETTER THAA;Lo;0;L;;;;;N;;;;;
+11118;CHAKMA LETTER DAA;Lo;0;L;;;;;N;;;;;
+11119;CHAKMA LETTER DHAA;Lo;0;L;;;;;N;;;;;
+1111A;CHAKMA LETTER NAA;Lo;0;L;;;;;N;;;;;
+1111B;CHAKMA LETTER PAA;Lo;0;L;;;;;N;;;;;
+1111C;CHAKMA LETTER PHAA;Lo;0;L;;;;;N;;;;;
+1111D;CHAKMA LETTER BAA;Lo;0;L;;;;;N;;;;;
+1111E;CHAKMA LETTER BHAA;Lo;0;L;;;;;N;;;;;
+1111F;CHAKMA LETTER MAA;Lo;0;L;;;;;N;;;;;
+11120;CHAKMA LETTER YYAA;Lo;0;L;;;;;N;;;;;
+11121;CHAKMA LETTER YAA;Lo;0;L;;;;;N;;;;;
+11122;CHAKMA LETTER RAA;Lo;0;L;;;;;N;;;;;
+11123;CHAKMA LETTER LAA;Lo;0;L;;;;;N;;;;;
+11124;CHAKMA LETTER WAA;Lo;0;L;;;;;N;;;;;
+11125;CHAKMA LETTER SAA;Lo;0;L;;;;;N;;;;;
+11126;CHAKMA LETTER HAA;Lo;0;L;;;;;N;;;;;
+11127;CHAKMA VOWEL SIGN A;Mn;0;NSM;;;;;N;;;;;
+11128;CHAKMA VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+11129;CHAKMA VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;
+1112A;CHAKMA VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+1112B;CHAKMA VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+1112C;CHAKMA VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
+1112D;CHAKMA VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
+1112E;CHAKMA VOWEL SIGN O;Mn;0;NSM;11131 11127;;;;N;;;;;
+1112F;CHAKMA VOWEL SIGN AU;Mn;0;NSM;11132 11127;;;;N;;;;;
+11130;CHAKMA VOWEL SIGN OI;Mn;0;NSM;;;;;N;;;;;
+11131;CHAKMA O MARK;Mn;0;NSM;;;;;N;;;;;
+11132;CHAKMA AU MARK;Mn;0;NSM;;;;;N;;;;;
+11133;CHAKMA VIRAMA;Mn;9;NSM;;;;;N;;;;;
+11134;CHAKMA MAAYYAA;Mn;9;NSM;;;;;N;;;;;
+11136;CHAKMA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+11137;CHAKMA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+11138;CHAKMA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+11139;CHAKMA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+1113A;CHAKMA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+1113B;CHAKMA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+1113C;CHAKMA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+1113D;CHAKMA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+1113E;CHAKMA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+1113F;CHAKMA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+11140;CHAKMA SECTION MARK;Po;0;L;;;;;N;;;;;
+11141;CHAKMA DANDA;Po;0;L;;;;;N;;;;;
+11142;CHAKMA DOUBLE DANDA;Po;0;L;;;;;N;;;;;
+11143;CHAKMA QUESTION MARK;Po;0;L;;;;;N;;;;;
+11150;MAHAJANI LETTER A;Lo;0;L;;;;;N;;;;;
+11151;MAHAJANI LETTER I;Lo;0;L;;;;;N;;;;;
+11152;MAHAJANI LETTER U;Lo;0;L;;;;;N;;;;;
+11153;MAHAJANI LETTER E;Lo;0;L;;;;;N;;;;;
+11154;MAHAJANI LETTER O;Lo;0;L;;;;;N;;;;;
+11155;MAHAJANI LETTER KA;Lo;0;L;;;;;N;;;;;
+11156;MAHAJANI LETTER KHA;Lo;0;L;;;;;N;;;;;
+11157;MAHAJANI LETTER GA;Lo;0;L;;;;;N;;;;;
+11158;MAHAJANI LETTER GHA;Lo;0;L;;;;;N;;;;;
+11159;MAHAJANI LETTER CA;Lo;0;L;;;;;N;;;;;
+1115A;MAHAJANI LETTER CHA;Lo;0;L;;;;;N;;;;;
+1115B;MAHAJANI LETTER JA;Lo;0;L;;;;;N;;;;;
+1115C;MAHAJANI LETTER JHA;Lo;0;L;;;;;N;;;;;
+1115D;MAHAJANI LETTER NYA;Lo;0;L;;;;;N;;;;;
+1115E;MAHAJANI LETTER TTA;Lo;0;L;;;;;N;;;;;
+1115F;MAHAJANI LETTER TTHA;Lo;0;L;;;;;N;;;;;
+11160;MAHAJANI LETTER DDA;Lo;0;L;;;;;N;;;;;
+11161;MAHAJANI LETTER DDHA;Lo;0;L;;;;;N;;;;;
+11162;MAHAJANI LETTER NNA;Lo;0;L;;;;;N;;;;;
+11163;MAHAJANI LETTER TA;Lo;0;L;;;;;N;;;;;
+11164;MAHAJANI LETTER THA;Lo;0;L;;;;;N;;;;;
+11165;MAHAJANI LETTER DA;Lo;0;L;;;;;N;;;;;
+11166;MAHAJANI LETTER DHA;Lo;0;L;;;;;N;;;;;
+11167;MAHAJANI LETTER NA;Lo;0;L;;;;;N;;;;;
+11168;MAHAJANI LETTER PA;Lo;0;L;;;;;N;;;;;
+11169;MAHAJANI LETTER PHA;Lo;0;L;;;;;N;;;;;
+1116A;MAHAJANI LETTER BA;Lo;0;L;;;;;N;;;;;
+1116B;MAHAJANI LETTER BHA;Lo;0;L;;;;;N;;;;;
+1116C;MAHAJANI LETTER MA;Lo;0;L;;;;;N;;;;;
+1116D;MAHAJANI LETTER RA;Lo;0;L;;;;;N;;;;;
+1116E;MAHAJANI LETTER LA;Lo;0;L;;;;;N;;;;;
+1116F;MAHAJANI LETTER VA;Lo;0;L;;;;;N;;;;;
+11170;MAHAJANI LETTER SA;Lo;0;L;;;;;N;;;;;
+11171;MAHAJANI LETTER HA;Lo;0;L;;;;;N;;;;;
+11172;MAHAJANI LETTER RRA;Lo;0;L;;;;;N;;;;;
+11173;MAHAJANI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
+11174;MAHAJANI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;;
+11175;MAHAJANI SECTION MARK;Po;0;L;;;;;N;;;;;
+11176;MAHAJANI LIGATURE SHRI;Lo;0;L;;;;;N;;;;;
+11180;SHARADA SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
+11181;SHARADA SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+11182;SHARADA SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+11183;SHARADA LETTER A;Lo;0;L;;;;;N;;;;;
+11184;SHARADA LETTER AA;Lo;0;L;;;;;N;;;;;
+11185;SHARADA LETTER I;Lo;0;L;;;;;N;;;;;
+11186;SHARADA LETTER II;Lo;0;L;;;;;N;;;;;
+11187;SHARADA LETTER U;Lo;0;L;;;;;N;;;;;
+11188;SHARADA LETTER UU;Lo;0;L;;;;;N;;;;;
+11189;SHARADA LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+1118A;SHARADA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+1118B;SHARADA LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
+1118C;SHARADA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
+1118D;SHARADA LETTER E;Lo;0;L;;;;;N;;;;;
+1118E;SHARADA LETTER AI;Lo;0;L;;;;;N;;;;;
+1118F;SHARADA LETTER O;Lo;0;L;;;;;N;;;;;
+11190;SHARADA LETTER AU;Lo;0;L;;;;;N;;;;;
+11191;SHARADA LETTER KA;Lo;0;L;;;;;N;;;;;
+11192;SHARADA LETTER KHA;Lo;0;L;;;;;N;;;;;
+11193;SHARADA LETTER GA;Lo;0;L;;;;;N;;;;;
+11194;SHARADA LETTER GHA;Lo;0;L;;;;;N;;;;;
+11195;SHARADA LETTER NGA;Lo;0;L;;;;;N;;;;;
+11196;SHARADA LETTER CA;Lo;0;L;;;;;N;;;;;
+11197;SHARADA LETTER CHA;Lo;0;L;;;;;N;;;;;
+11198;SHARADA LETTER JA;Lo;0;L;;;;;N;;;;;
+11199;SHARADA LETTER JHA;Lo;0;L;;;;;N;;;;;
+1119A;SHARADA LETTER NYA;Lo;0;L;;;;;N;;;;;
+1119B;SHARADA LETTER TTA;Lo;0;L;;;;;N;;;;;
+1119C;SHARADA LETTER TTHA;Lo;0;L;;;;;N;;;;;
+1119D;SHARADA LETTER DDA;Lo;0;L;;;;;N;;;;;
+1119E;SHARADA LETTER DDHA;Lo;0;L;;;;;N;;;;;
+1119F;SHARADA LETTER NNA;Lo;0;L;;;;;N;;;;;
+111A0;SHARADA LETTER TA;Lo;0;L;;;;;N;;;;;
+111A1;SHARADA LETTER THA;Lo;0;L;;;;;N;;;;;
+111A2;SHARADA LETTER DA;Lo;0;L;;;;;N;;;;;
+111A3;SHARADA LETTER DHA;Lo;0;L;;;;;N;;;;;
+111A4;SHARADA LETTER NA;Lo;0;L;;;;;N;;;;;
+111A5;SHARADA LETTER PA;Lo;0;L;;;;;N;;;;;
+111A6;SHARADA LETTER PHA;Lo;0;L;;;;;N;;;;;
+111A7;SHARADA LETTER BA;Lo;0;L;;;;;N;;;;;
+111A8;SHARADA LETTER BHA;Lo;0;L;;;;;N;;;;;
+111A9;SHARADA LETTER MA;Lo;0;L;;;;;N;;;;;
+111AA;SHARADA LETTER YA;Lo;0;L;;;;;N;;;;;
+111AB;SHARADA LETTER RA;Lo;0;L;;;;;N;;;;;
+111AC;SHARADA LETTER LA;Lo;0;L;;;;;N;;;;;
+111AD;SHARADA LETTER LLA;Lo;0;L;;;;;N;;;;;
+111AE;SHARADA LETTER VA;Lo;0;L;;;;;N;;;;;
+111AF;SHARADA LETTER SHA;Lo;0;L;;;;;N;;;;;
+111B0;SHARADA LETTER SSA;Lo;0;L;;;;;N;;;;;
+111B1;SHARADA LETTER SA;Lo;0;L;;;;;N;;;;;
+111B2;SHARADA LETTER HA;Lo;0;L;;;;;N;;;;;
+111B3;SHARADA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+111B4;SHARADA VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+111B5;SHARADA VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+111B6;SHARADA VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+111B7;SHARADA VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+111B8;SHARADA VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
+111B9;SHARADA VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;
+111BA;SHARADA VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
+111BB;SHARADA VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;
+111BC;SHARADA VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+111BD;SHARADA VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
+111BE;SHARADA VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;
+111BF;SHARADA VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;
+111C0;SHARADA SIGN VIRAMA;Mc;9;L;;;;;N;;;;;
+111C1;SHARADA SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;
+111C2;SHARADA SIGN JIHVAMULIYA;Lo;0;L;;;;;N;;;;;
+111C3;SHARADA SIGN UPADHMANIYA;Lo;0;L;;;;;N;;;;;
+111C4;SHARADA OM;Lo;0;L;;;;;N;;;;;
+111C5;SHARADA DANDA;Po;0;L;;;;;N;;;;;
+111C6;SHARADA DOUBLE DANDA;Po;0;L;;;;;N;;;;;
+111C7;SHARADA ABBREVIATION SIGN;Po;0;L;;;;;N;;;;;
+111C8;SHARADA SEPARATOR;Po;0;L;;;;;N;;;;;
+111C9;SHARADA SANDHI MARK;Po;0;L;;;;;N;;;;;
+111CA;SHARADA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
+111CB;SHARADA VOWEL MODIFIER MARK;Mn;0;NSM;;;;;N;;;;;
+111CC;SHARADA EXTRA SHORT VOWEL MARK;Mn;0;NSM;;;;;N;;;;;
+111CD;SHARADA SUTRA MARK;Po;0;L;;;;;N;;;;;
+111D0;SHARADA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+111D1;SHARADA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+111D2;SHARADA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+111D3;SHARADA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+111D4;SHARADA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+111D5;SHARADA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+111D6;SHARADA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+111D7;SHARADA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+111D8;SHARADA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+111D9;SHARADA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+111DA;SHARADA EKAM;Lo;0;L;;;;;N;;;;;
+111DB;SHARADA SIGN SIDDHAM;Po;0;L;;;;;N;;;;;
+111DC;SHARADA HEADSTROKE;Lo;0;L;;;;;N;;;;;
+111DD;SHARADA CONTINUATION SIGN;Po;0;L;;;;;N;;;;;
+111DE;SHARADA SECTION MARK-1;Po;0;L;;;;;N;;;;;
+111DF;SHARADA SECTION MARK-2;Po;0;L;;;;;N;;;;;
+111E1;SINHALA ARCHAIC DIGIT ONE;No;0;L;;;;1;N;;;;;
+111E2;SINHALA ARCHAIC DIGIT TWO;No;0;L;;;;2;N;;;;;
+111E3;SINHALA ARCHAIC DIGIT THREE;No;0;L;;;;3;N;;;;;
+111E4;SINHALA ARCHAIC DIGIT FOUR;No;0;L;;;;4;N;;;;;
+111E5;SINHALA ARCHAIC DIGIT FIVE;No;0;L;;;;5;N;;;;;
+111E6;SINHALA ARCHAIC DIGIT SIX;No;0;L;;;;6;N;;;;;
+111E7;SINHALA ARCHAIC DIGIT SEVEN;No;0;L;;;;7;N;;;;;
+111E8;SINHALA ARCHAIC DIGIT EIGHT;No;0;L;;;;8;N;;;;;
+111E9;SINHALA ARCHAIC DIGIT NINE;No;0;L;;;;9;N;;;;;
+111EA;SINHALA ARCHAIC NUMBER TEN;No;0;L;;;;10;N;;;;;
+111EB;SINHALA ARCHAIC NUMBER TWENTY;No;0;L;;;;20;N;;;;;
+111EC;SINHALA ARCHAIC NUMBER THIRTY;No;0;L;;;;30;N;;;;;
+111ED;SINHALA ARCHAIC NUMBER FORTY;No;0;L;;;;40;N;;;;;
+111EE;SINHALA ARCHAIC NUMBER FIFTY;No;0;L;;;;50;N;;;;;
+111EF;SINHALA ARCHAIC NUMBER SIXTY;No;0;L;;;;60;N;;;;;
+111F0;SINHALA ARCHAIC NUMBER SEVENTY;No;0;L;;;;70;N;;;;;
+111F1;SINHALA ARCHAIC NUMBER EIGHTY;No;0;L;;;;80;N;;;;;
+111F2;SINHALA ARCHAIC NUMBER NINETY;No;0;L;;;;90;N;;;;;
+111F3;SINHALA ARCHAIC NUMBER ONE HUNDRED;No;0;L;;;;100;N;;;;;
+111F4;SINHALA ARCHAIC NUMBER ONE THOUSAND;No;0;L;;;;1000;N;;;;;
+11200;KHOJKI LETTER A;Lo;0;L;;;;;N;;;;;
+11201;KHOJKI LETTER AA;Lo;0;L;;;;;N;;;;;
+11202;KHOJKI LETTER I;Lo;0;L;;;;;N;;;;;
+11203;KHOJKI LETTER U;Lo;0;L;;;;;N;;;;;
+11204;KHOJKI LETTER E;Lo;0;L;;;;;N;;;;;
+11205;KHOJKI LETTER AI;Lo;0;L;;;;;N;;;;;
+11206;KHOJKI LETTER O;Lo;0;L;;;;;N;;;;;
+11207;KHOJKI LETTER AU;Lo;0;L;;;;;N;;;;;
+11208;KHOJKI LETTER KA;Lo;0;L;;;;;N;;;;;
+11209;KHOJKI LETTER KHA;Lo;0;L;;;;;N;;;;;
+1120A;KHOJKI LETTER GA;Lo;0;L;;;;;N;;;;;
+1120B;KHOJKI LETTER GGA;Lo;0;L;;;;;N;;;;;
+1120C;KHOJKI LETTER GHA;Lo;0;L;;;;;N;;;;;
+1120D;KHOJKI LETTER NGA;Lo;0;L;;;;;N;;;;;
+1120E;KHOJKI LETTER CA;Lo;0;L;;;;;N;;;;;
+1120F;KHOJKI LETTER CHA;Lo;0;L;;;;;N;;;;;
+11210;KHOJKI LETTER JA;Lo;0;L;;;;;N;;;;;
+11211;KHOJKI LETTER JJA;Lo;0;L;;;;;N;;;;;
+11213;KHOJKI LETTER NYA;Lo;0;L;;;;;N;;;;;
+11214;KHOJKI LETTER TTA;Lo;0;L;;;;;N;;;;;
+11215;KHOJKI LETTER TTHA;Lo;0;L;;;;;N;;;;;
+11216;KHOJKI LETTER DDA;Lo;0;L;;;;;N;;;;;
+11217;KHOJKI LETTER DDHA;Lo;0;L;;;;;N;;;;;
+11218;KHOJKI LETTER NNA;Lo;0;L;;;;;N;;;;;
+11219;KHOJKI LETTER TA;Lo;0;L;;;;;N;;;;;
+1121A;KHOJKI LETTER THA;Lo;0;L;;;;;N;;;;;
+1121B;KHOJKI LETTER DA;Lo;0;L;;;;;N;;;;;
+1121C;KHOJKI LETTER DDDA;Lo;0;L;;;;;N;;;;;
+1121D;KHOJKI LETTER DHA;Lo;0;L;;;;;N;;;;;
+1121E;KHOJKI LETTER NA;Lo;0;L;;;;;N;;;;;
+1121F;KHOJKI LETTER PA;Lo;0;L;;;;;N;;;;;
+11220;KHOJKI LETTER PHA;Lo;0;L;;;;;N;;;;;
+11221;KHOJKI LETTER BA;Lo;0;L;;;;;N;;;;;
+11222;KHOJKI LETTER BBA;Lo;0;L;;;;;N;;;;;
+11223;KHOJKI LETTER BHA;Lo;0;L;;;;;N;;;;;
+11224;KHOJKI LETTER MA;Lo;0;L;;;;;N;;;;;
+11225;KHOJKI LETTER YA;Lo;0;L;;;;;N;;;;;
+11226;KHOJKI LETTER RA;Lo;0;L;;;;;N;;;;;
+11227;KHOJKI LETTER LA;Lo;0;L;;;;;N;;;;;
+11228;KHOJKI LETTER VA;Lo;0;L;;;;;N;;;;;
+11229;KHOJKI LETTER SA;Lo;0;L;;;;;N;;;;;
+1122A;KHOJKI LETTER HA;Lo;0;L;;;;;N;;;;;
+1122B;KHOJKI LETTER LLA;Lo;0;L;;;;;N;;;;;
+1122C;KHOJKI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+1122D;KHOJKI VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+1122E;KHOJKI VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+1122F;KHOJKI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+11230;KHOJKI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+11231;KHOJKI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
+11232;KHOJKI VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
+11233;KHOJKI VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;
+11234;KHOJKI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+11235;KHOJKI SIGN VIRAMA;Mc;9;L;;;;;N;;;;;
+11236;KHOJKI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
+11237;KHOJKI SIGN SHADDA;Mn;0;NSM;;;;;N;;;;;
+11238;KHOJKI DANDA;Po;0;L;;;;;N;;;;;
+11239;KHOJKI DOUBLE DANDA;Po;0;L;;;;;N;;;;;
+1123A;KHOJKI WORD SEPARATOR;Po;0;L;;;;;N;;;;;
+1123B;KHOJKI SECTION MARK;Po;0;L;;;;;N;;;;;
+1123C;KHOJKI DOUBLE SECTION MARK;Po;0;L;;;;;N;;;;;
+1123D;KHOJKI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;;
+1123E;KHOJKI SIGN SUKUN;Mn;0;NSM;;;;;N;;;;;
+11280;MULTANI LETTER A;Lo;0;L;;;;;N;;;;;
+11281;MULTANI LETTER I;Lo;0;L;;;;;N;;;;;
+11282;MULTANI LETTER U;Lo;0;L;;;;;N;;;;;
+11283;MULTANI LETTER E;Lo;0;L;;;;;N;;;;;
+11284;MULTANI LETTER KA;Lo;0;L;;;;;N;;;;;
+11285;MULTANI LETTER KHA;Lo;0;L;;;;;N;;;;;
+11286;MULTANI LETTER GA;Lo;0;L;;;;;N;;;;;
+11288;MULTANI LETTER GHA;Lo;0;L;;;;;N;;;;;
+1128A;MULTANI LETTER CA;Lo;0;L;;;;;N;;;;;
+1128B;MULTANI LETTER CHA;Lo;0;L;;;;;N;;;;;
+1128C;MULTANI LETTER JA;Lo;0;L;;;;;N;;;;;
+1128D;MULTANI LETTER JJA;Lo;0;L;;;;;N;;;;;
+1128F;MULTANI LETTER NYA;Lo;0;L;;;;;N;;;;;
+11290;MULTANI LETTER TTA;Lo;0;L;;;;;N;;;;;
+11291;MULTANI LETTER TTHA;Lo;0;L;;;;;N;;;;;
+11292;MULTANI LETTER DDA;Lo;0;L;;;;;N;;;;;
+11293;MULTANI LETTER DDDA;Lo;0;L;;;;;N;;;;;
+11294;MULTANI LETTER DDHA;Lo;0;L;;;;;N;;;;;
+11295;MULTANI LETTER NNA;Lo;0;L;;;;;N;;;;;
+11296;MULTANI LETTER TA;Lo;0;L;;;;;N;;;;;
+11297;MULTANI LETTER THA;Lo;0;L;;;;;N;;;;;
+11298;MULTANI LETTER DA;Lo;0;L;;;;;N;;;;;
+11299;MULTANI LETTER DHA;Lo;0;L;;;;;N;;;;;
+1129A;MULTANI LETTER NA;Lo;0;L;;;;;N;;;;;
+1129B;MULTANI LETTER PA;Lo;0;L;;;;;N;;;;;
+1129C;MULTANI LETTER PHA;Lo;0;L;;;;;N;;;;;
+1129D;MULTANI LETTER BA;Lo;0;L;;;;;N;;;;;
+1129F;MULTANI LETTER BHA;Lo;0;L;;;;;N;;;;;
+112A0;MULTANI LETTER MA;Lo;0;L;;;;;N;;;;;
+112A1;MULTANI LETTER YA;Lo;0;L;;;;;N;;;;;
+112A2;MULTANI LETTER RA;Lo;0;L;;;;;N;;;;;
+112A3;MULTANI LETTER LA;Lo;0;L;;;;;N;;;;;
+112A4;MULTANI LETTER VA;Lo;0;L;;;;;N;;;;;
+112A5;MULTANI LETTER SA;Lo;0;L;;;;;N;;;;;
+112A6;MULTANI LETTER HA;Lo;0;L;;;;;N;;;;;
+112A7;MULTANI LETTER RRA;Lo;0;L;;;;;N;;;;;
+112A8;MULTANI LETTER RHA;Lo;0;L;;;;;N;;;;;
+112A9;MULTANI SECTION MARK;Po;0;L;;;;;N;;;;;
+112B0;KHUDAWADI LETTER A;Lo;0;L;;;;;N;;;;;
+112B1;KHUDAWADI LETTER AA;Lo;0;L;;;;;N;;;;;
+112B2;KHUDAWADI LETTER I;Lo;0;L;;;;;N;;;;;
+112B3;KHUDAWADI LETTER II;Lo;0;L;;;;;N;;;;;
+112B4;KHUDAWADI LETTER U;Lo;0;L;;;;;N;;;;;
+112B5;KHUDAWADI LETTER UU;Lo;0;L;;;;;N;;;;;
+112B6;KHUDAWADI LETTER E;Lo;0;L;;;;;N;;;;;
+112B7;KHUDAWADI LETTER AI;Lo;0;L;;;;;N;;;;;
+112B8;KHUDAWADI LETTER O;Lo;0;L;;;;;N;;;;;
+112B9;KHUDAWADI LETTER AU;Lo;0;L;;;;;N;;;;;
+112BA;KHUDAWADI LETTER KA;Lo;0;L;;;;;N;;;;;
+112BB;KHUDAWADI LETTER KHA;Lo;0;L;;;;;N;;;;;
+112BC;KHUDAWADI LETTER GA;Lo;0;L;;;;;N;;;;;
+112BD;KHUDAWADI LETTER GGA;Lo;0;L;;;;;N;;;;;
+112BE;KHUDAWADI LETTER GHA;Lo;0;L;;;;;N;;;;;
+112BF;KHUDAWADI LETTER NGA;Lo;0;L;;;;;N;;;;;
+112C0;KHUDAWADI LETTER CA;Lo;0;L;;;;;N;;;;;
+112C1;KHUDAWADI LETTER CHA;Lo;0;L;;;;;N;;;;;
+112C2;KHUDAWADI LETTER JA;Lo;0;L;;;;;N;;;;;
+112C3;KHUDAWADI LETTER JJA;Lo;0;L;;;;;N;;;;;
+112C4;KHUDAWADI LETTER JHA;Lo;0;L;;;;;N;;;;;
+112C5;KHUDAWADI LETTER NYA;Lo;0;L;;;;;N;;;;;
+112C6;KHUDAWADI LETTER TTA;Lo;0;L;;;;;N;;;;;
+112C7;KHUDAWADI LETTER TTHA;Lo;0;L;;;;;N;;;;;
+112C8;KHUDAWADI LETTER DDA;Lo;0;L;;;;;N;;;;;
+112C9;KHUDAWADI LETTER DDDA;Lo;0;L;;;;;N;;;;;
+112CA;KHUDAWADI LETTER RRA;Lo;0;L;;;;;N;;;;;
+112CB;KHUDAWADI LETTER DDHA;Lo;0;L;;;;;N;;;;;
+112CC;KHUDAWADI LETTER NNA;Lo;0;L;;;;;N;;;;;
+112CD;KHUDAWADI LETTER TA;Lo;0;L;;;;;N;;;;;
+112CE;KHUDAWADI LETTER THA;Lo;0;L;;;;;N;;;;;
+112CF;KHUDAWADI LETTER DA;Lo;0;L;;;;;N;;;;;
+112D0;KHUDAWADI LETTER DHA;Lo;0;L;;;;;N;;;;;
+112D1;KHUDAWADI LETTER NA;Lo;0;L;;;;;N;;;;;
+112D2;KHUDAWADI LETTER PA;Lo;0;L;;;;;N;;;;;
+112D3;KHUDAWADI LETTER PHA;Lo;0;L;;;;;N;;;;;
+112D4;KHUDAWADI LETTER BA;Lo;0;L;;;;;N;;;;;
+112D5;KHUDAWADI LETTER BBA;Lo;0;L;;;;;N;;;;;
+112D6;KHUDAWADI LETTER BHA;Lo;0;L;;;;;N;;;;;
+112D7;KHUDAWADI LETTER MA;Lo;0;L;;;;;N;;;;;
+112D8;KHUDAWADI LETTER YA;Lo;0;L;;;;;N;;;;;
+112D9;KHUDAWADI LETTER RA;Lo;0;L;;;;;N;;;;;
+112DA;KHUDAWADI LETTER LA;Lo;0;L;;;;;N;;;;;
+112DB;KHUDAWADI LETTER VA;Lo;0;L;;;;;N;;;;;
+112DC;KHUDAWADI LETTER SHA;Lo;0;L;;;;;N;;;;;
+112DD;KHUDAWADI LETTER SA;Lo;0;L;;;;;N;;;;;
+112DE;KHUDAWADI LETTER HA;Lo;0;L;;;;;N;;;;;
+112DF;KHUDAWADI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+112E0;KHUDAWADI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+112E1;KHUDAWADI VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+112E2;KHUDAWADI VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+112E3;KHUDAWADI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+112E4;KHUDAWADI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+112E5;KHUDAWADI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+112E6;KHUDAWADI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
+112E7;KHUDAWADI VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;
+112E8;KHUDAWADI VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;;
+112E9;KHUDAWADI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
+112EA;KHUDAWADI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+112F0;KHUDAWADI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+112F1;KHUDAWADI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+112F2;KHUDAWADI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+112F3;KHUDAWADI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+112F4;KHUDAWADI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+112F5;KHUDAWADI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+112F6;KHUDAWADI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+112F7;KHUDAWADI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+112F8;KHUDAWADI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+112F9;KHUDAWADI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+11300;GRANTHA SIGN COMBINING ANUSVARA ABOVE;Mn;0;NSM;;;;;N;;;;;
+11301;GRANTHA SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
+11302;GRANTHA SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;
+11303;GRANTHA SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+11305;GRANTHA LETTER A;Lo;0;L;;;;;N;;;;;
+11306;GRANTHA LETTER AA;Lo;0;L;;;;;N;;;;;
+11307;GRANTHA LETTER I;Lo;0;L;;;;;N;;;;;
+11308;GRANTHA LETTER II;Lo;0;L;;;;;N;;;;;
+11309;GRANTHA LETTER U;Lo;0;L;;;;;N;;;;;
+1130A;GRANTHA LETTER UU;Lo;0;L;;;;;N;;;;;
+1130B;GRANTHA LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+1130C;GRANTHA LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
+1130F;GRANTHA LETTER EE;Lo;0;L;;;;;N;;;;;
+11310;GRANTHA LETTER AI;Lo;0;L;;;;;N;;;;;
+11313;GRANTHA LETTER OO;Lo;0;L;;;;;N;;;;;
+11314;GRANTHA LETTER AU;Lo;0;L;;;;;N;;;;;
+11315;GRANTHA LETTER KA;Lo;0;L;;;;;N;;;;;
+11316;GRANTHA LETTER KHA;Lo;0;L;;;;;N;;;;;
+11317;GRANTHA LETTER GA;Lo;0;L;;;;;N;;;;;
+11318;GRANTHA LETTER GHA;Lo;0;L;;;;;N;;;;;
+11319;GRANTHA LETTER NGA;Lo;0;L;;;;;N;;;;;
+1131A;GRANTHA LETTER CA;Lo;0;L;;;;;N;;;;;
+1131B;GRANTHA LETTER CHA;Lo;0;L;;;;;N;;;;;
+1131C;GRANTHA LETTER JA;Lo;0;L;;;;;N;;;;;
+1131D;GRANTHA LETTER JHA;Lo;0;L;;;;;N;;;;;
+1131E;GRANTHA LETTER NYA;Lo;0;L;;;;;N;;;;;
+1131F;GRANTHA LETTER TTA;Lo;0;L;;;;;N;;;;;
+11320;GRANTHA LETTER TTHA;Lo;0;L;;;;;N;;;;;
+11321;GRANTHA LETTER DDA;Lo;0;L;;;;;N;;;;;
+11322;GRANTHA LETTER DDHA;Lo;0;L;;;;;N;;;;;
+11323;GRANTHA LETTER NNA;Lo;0;L;;;;;N;;;;;
+11324;GRANTHA LETTER TA;Lo;0;L;;;;;N;;;;;
+11325;GRANTHA LETTER THA;Lo;0;L;;;;;N;;;;;
+11326;GRANTHA LETTER DA;Lo;0;L;;;;;N;;;;;
+11327;GRANTHA LETTER DHA;Lo;0;L;;;;;N;;;;;
+11328;GRANTHA LETTER NA;Lo;0;L;;;;;N;;;;;
+1132A;GRANTHA LETTER PA;Lo;0;L;;;;;N;;;;;
+1132B;GRANTHA LETTER PHA;Lo;0;L;;;;;N;;;;;
+1132C;GRANTHA LETTER BA;Lo;0;L;;;;;N;;;;;
+1132D;GRANTHA LETTER BHA;Lo;0;L;;;;;N;;;;;
+1132E;GRANTHA LETTER MA;Lo;0;L;;;;;N;;;;;
+1132F;GRANTHA LETTER YA;Lo;0;L;;;;;N;;;;;
+11330;GRANTHA LETTER RA;Lo;0;L;;;;;N;;;;;
+11332;GRANTHA LETTER LA;Lo;0;L;;;;;N;;;;;
+11333;GRANTHA LETTER LLA;Lo;0;L;;;;;N;;;;;
+11335;GRANTHA LETTER VA;Lo;0;L;;;;;N;;;;;
+11336;GRANTHA LETTER SHA;Lo;0;L;;;;;N;;;;;
+11337;GRANTHA LETTER SSA;Lo;0;L;;;;;N;;;;;
+11338;GRANTHA LETTER SA;Lo;0;L;;;;;N;;;;;
+11339;GRANTHA LETTER HA;Lo;0;L;;;;;N;;;;;
+1133C;GRANTHA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
+1133D;GRANTHA SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;
+1133E;GRANTHA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+1133F;GRANTHA VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+11340;GRANTHA VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;
+11341;GRANTHA VOWEL SIGN U;Mc;0;L;;;;;N;;;;;
+11342;GRANTHA VOWEL SIGN UU;Mc;0;L;;;;;N;;;;;
+11343;GRANTHA VOWEL SIGN VOCALIC R;Mc;0;L;;;;;N;;;;;
+11344;GRANTHA VOWEL SIGN VOCALIC RR;Mc;0;L;;;;;N;;;;;
+11347;GRANTHA VOWEL SIGN EE;Mc;0;L;;;;;N;;;;;
+11348;GRANTHA VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;
+1134B;GRANTHA VOWEL SIGN OO;Mc;0;L;11347 1133E;;;;N;;;;;
+1134C;GRANTHA VOWEL SIGN AU;Mc;0;L;11347 11357;;;;N;;;;;
+1134D;GRANTHA SIGN VIRAMA;Mc;9;L;;;;;N;;;;;
+11350;GRANTHA OM;Lo;0;L;;;;;N;;;;;
+11357;GRANTHA AU LENGTH MARK;Mc;0;L;;;;;N;;;;;
+1135D;GRANTHA SIGN PLUTA;Lo;0;L;;;;;N;;;;;
+1135E;GRANTHA LETTER VEDIC ANUSVARA;Lo;0;L;;;;;N;;;;;
+1135F;GRANTHA LETTER VEDIC DOUBLE ANUSVARA;Lo;0;L;;;;;N;;;;;
+11360;GRANTHA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+11361;GRANTHA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
+11362;GRANTHA VOWEL SIGN VOCALIC L;Mc;0;L;;;;;N;;;;;
+11363;GRANTHA VOWEL SIGN VOCALIC LL;Mc;0;L;;;;;N;;;;;
+11366;COMBINING GRANTHA DIGIT ZERO;Mn;230;NSM;;;;;N;;;;;
+11367;COMBINING GRANTHA DIGIT ONE;Mn;230;NSM;;;;;N;;;;;
+11368;COMBINING GRANTHA DIGIT TWO;Mn;230;NSM;;;;;N;;;;;
+11369;COMBINING GRANTHA DIGIT THREE;Mn;230;NSM;;;;;N;;;;;
+1136A;COMBINING GRANTHA DIGIT FOUR;Mn;230;NSM;;;;;N;;;;;
+1136B;COMBINING GRANTHA DIGIT FIVE;Mn;230;NSM;;;;;N;;;;;
+1136C;COMBINING GRANTHA DIGIT SIX;Mn;230;NSM;;;;;N;;;;;
+11370;COMBINING GRANTHA LETTER A;Mn;230;NSM;;;;;N;;;;;
+11371;COMBINING GRANTHA LETTER KA;Mn;230;NSM;;;;;N;;;;;
+11372;COMBINING GRANTHA LETTER NA;Mn;230;NSM;;;;;N;;;;;
+11373;COMBINING GRANTHA LETTER VI;Mn;230;NSM;;;;;N;;;;;
+11374;COMBINING GRANTHA LETTER PA;Mn;230;NSM;;;;;N;;;;;
+11400;NEWA LETTER A;Lo;0;L;;;;;N;;;;;
+11401;NEWA LETTER AA;Lo;0;L;;;;;N;;;;;
+11402;NEWA LETTER I;Lo;0;L;;;;;N;;;;;
+11403;NEWA LETTER II;Lo;0;L;;;;;N;;;;;
+11404;NEWA LETTER U;Lo;0;L;;;;;N;;;;;
+11405;NEWA LETTER UU;Lo;0;L;;;;;N;;;;;
+11406;NEWA LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+11407;NEWA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+11408;NEWA LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
+11409;NEWA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
+1140A;NEWA LETTER E;Lo;0;L;;;;;N;;;;;
+1140B;NEWA LETTER AI;Lo;0;L;;;;;N;;;;;
+1140C;NEWA LETTER O;Lo;0;L;;;;;N;;;;;
+1140D;NEWA LETTER AU;Lo;0;L;;;;;N;;;;;
+1140E;NEWA LETTER KA;Lo;0;L;;;;;N;;;;;
+1140F;NEWA LETTER KHA;Lo;0;L;;;;;N;;;;;
+11410;NEWA LETTER GA;Lo;0;L;;;;;N;;;;;
+11411;NEWA LETTER GHA;Lo;0;L;;;;;N;;;;;
+11412;NEWA LETTER NGA;Lo;0;L;;;;;N;;;;;
+11413;NEWA LETTER NGHA;Lo;0;L;;;;;N;;;;;
+11414;NEWA LETTER CA;Lo;0;L;;;;;N;;;;;
+11415;NEWA LETTER CHA;Lo;0;L;;;;;N;;;;;
+11416;NEWA LETTER JA;Lo;0;L;;;;;N;;;;;
+11417;NEWA LETTER JHA;Lo;0;L;;;;;N;;;;;
+11418;NEWA LETTER NYA;Lo;0;L;;;;;N;;;;;
+11419;NEWA LETTER NYHA;Lo;0;L;;;;;N;;;;;
+1141A;NEWA LETTER TTA;Lo;0;L;;;;;N;;;;;
+1141B;NEWA LETTER TTHA;Lo;0;L;;;;;N;;;;;
+1141C;NEWA LETTER DDA;Lo;0;L;;;;;N;;;;;
+1141D;NEWA LETTER DDHA;Lo;0;L;;;;;N;;;;;
+1141E;NEWA LETTER NNA;Lo;0;L;;;;;N;;;;;
+1141F;NEWA LETTER TA;Lo;0;L;;;;;N;;;;;
+11420;NEWA LETTER THA;Lo;0;L;;;;;N;;;;;
+11421;NEWA LETTER DA;Lo;0;L;;;;;N;;;;;
+11422;NEWA LETTER DHA;Lo;0;L;;;;;N;;;;;
+11423;NEWA LETTER NA;Lo;0;L;;;;;N;;;;;
+11424;NEWA LETTER NHA;Lo;0;L;;;;;N;;;;;
+11425;NEWA LETTER PA;Lo;0;L;;;;;N;;;;;
+11426;NEWA LETTER PHA;Lo;0;L;;;;;N;;;;;
+11427;NEWA LETTER BA;Lo;0;L;;;;;N;;;;;
+11428;NEWA LETTER BHA;Lo;0;L;;;;;N;;;;;
+11429;NEWA LETTER MA;Lo;0;L;;;;;N;;;;;
+1142A;NEWA LETTER MHA;Lo;0;L;;;;;N;;;;;
+1142B;NEWA LETTER YA;Lo;0;L;;;;;N;;;;;
+1142C;NEWA LETTER RA;Lo;0;L;;;;;N;;;;;
+1142D;NEWA LETTER RHA;Lo;0;L;;;;;N;;;;;
+1142E;NEWA LETTER LA;Lo;0;L;;;;;N;;;;;
+1142F;NEWA LETTER LHA;Lo;0;L;;;;;N;;;;;
+11430;NEWA LETTER WA;Lo;0;L;;;;;N;;;;;
+11431;NEWA LETTER SHA;Lo;0;L;;;;;N;;;;;
+11432;NEWA LETTER SSA;Lo;0;L;;;;;N;;;;;
+11433;NEWA LETTER SA;Lo;0;L;;;;;N;;;;;
+11434;NEWA LETTER HA;Lo;0;L;;;;;N;;;;;
+11435;NEWA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+11436;NEWA VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+11437;NEWA VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+11438;NEWA VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+11439;NEWA VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+1143A;NEWA VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
+1143B;NEWA VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;
+1143C;NEWA VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
+1143D;NEWA VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;
+1143E;NEWA VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+1143F;NEWA VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
+11440;NEWA VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
+11441;NEWA VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;
+11442;NEWA SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+11443;NEWA SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
+11444;NEWA SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+11445;NEWA SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+11446;NEWA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
+11447;NEWA SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;
+11448;NEWA SIGN FINAL ANUSVARA;Lo;0;L;;;;;N;;;;;
+11449;NEWA OM;Lo;0;L;;;;;N;;;;;
+1144A;NEWA SIDDHI;Lo;0;L;;;;;N;;;;;
+1144B;NEWA DANDA;Po;0;L;;;;;N;;;;;
+1144C;NEWA DOUBLE DANDA;Po;0;L;;;;;N;;;;;
+1144D;NEWA COMMA;Po;0;L;;;;;N;;;;;
+1144E;NEWA GAP FILLER;Po;0;L;;;;;N;;;;;
+1144F;NEWA ABBREVIATION SIGN;Po;0;L;;;;;N;;;;;
+11450;NEWA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+11451;NEWA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+11452;NEWA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+11453;NEWA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+11454;NEWA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+11455;NEWA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+11456;NEWA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+11457;NEWA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+11458;NEWA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+11459;NEWA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+1145B;NEWA PLACEHOLDER MARK;Po;0;L;;;;;N;;;;;
+1145D;NEWA INSERTION SIGN;Po;0;L;;;;;N;;;;;
+11480;TIRHUTA ANJI;Lo;0;L;;;;;N;;;;;
+11481;TIRHUTA LETTER A;Lo;0;L;;;;;N;;;;;
+11482;TIRHUTA LETTER AA;Lo;0;L;;;;;N;;;;;
+11483;TIRHUTA LETTER I;Lo;0;L;;;;;N;;;;;
+11484;TIRHUTA LETTER II;Lo;0;L;;;;;N;;;;;
+11485;TIRHUTA LETTER U;Lo;0;L;;;;;N;;;;;
+11486;TIRHUTA LETTER UU;Lo;0;L;;;;;N;;;;;
+11487;TIRHUTA LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+11488;TIRHUTA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+11489;TIRHUTA LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
+1148A;TIRHUTA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
+1148B;TIRHUTA LETTER E;Lo;0;L;;;;;N;;;;;
+1148C;TIRHUTA LETTER AI;Lo;0;L;;;;;N;;;;;
+1148D;TIRHUTA LETTER O;Lo;0;L;;;;;N;;;;;
+1148E;TIRHUTA LETTER AU;Lo;0;L;;;;;N;;;;;
+1148F;TIRHUTA LETTER KA;Lo;0;L;;;;;N;;;;;
+11490;TIRHUTA LETTER KHA;Lo;0;L;;;;;N;;;;;
+11491;TIRHUTA LETTER GA;Lo;0;L;;;;;N;;;;;
+11492;TIRHUTA LETTER GHA;Lo;0;L;;;;;N;;;;;
+11493;TIRHUTA LETTER NGA;Lo;0;L;;;;;N;;;;;
+11494;TIRHUTA LETTER CA;Lo;0;L;;;;;N;;;;;
+11495;TIRHUTA LETTER CHA;Lo;0;L;;;;;N;;;;;
+11496;TIRHUTA LETTER JA;Lo;0;L;;;;;N;;;;;
+11497;TIRHUTA LETTER JHA;Lo;0;L;;;;;N;;;;;
+11498;TIRHUTA LETTER NYA;Lo;0;L;;;;;N;;;;;
+11499;TIRHUTA LETTER TTA;Lo;0;L;;;;;N;;;;;
+1149A;TIRHUTA LETTER TTHA;Lo;0;L;;;;;N;;;;;
+1149B;TIRHUTA LETTER DDA;Lo;0;L;;;;;N;;;;;
+1149C;TIRHUTA LETTER DDHA;Lo;0;L;;;;;N;;;;;
+1149D;TIRHUTA LETTER NNA;Lo;0;L;;;;;N;;;;;
+1149E;TIRHUTA LETTER TA;Lo;0;L;;;;;N;;;;;
+1149F;TIRHUTA LETTER THA;Lo;0;L;;;;;N;;;;;
+114A0;TIRHUTA LETTER DA;Lo;0;L;;;;;N;;;;;
+114A1;TIRHUTA LETTER DHA;Lo;0;L;;;;;N;;;;;
+114A2;TIRHUTA LETTER NA;Lo;0;L;;;;;N;;;;;
+114A3;TIRHUTA LETTER PA;Lo;0;L;;;;;N;;;;;
+114A4;TIRHUTA LETTER PHA;Lo;0;L;;;;;N;;;;;
+114A5;TIRHUTA LETTER BA;Lo;0;L;;;;;N;;;;;
+114A6;TIRHUTA LETTER BHA;Lo;0;L;;;;;N;;;;;
+114A7;TIRHUTA LETTER MA;Lo;0;L;;;;;N;;;;;
+114A8;TIRHUTA LETTER YA;Lo;0;L;;;;;N;;;;;
+114A9;TIRHUTA LETTER RA;Lo;0;L;;;;;N;;;;;
+114AA;TIRHUTA LETTER LA;Lo;0;L;;;;;N;;;;;
+114AB;TIRHUTA LETTER VA;Lo;0;L;;;;;N;;;;;
+114AC;TIRHUTA LETTER SHA;Lo;0;L;;;;;N;;;;;
+114AD;TIRHUTA LETTER SSA;Lo;0;L;;;;;N;;;;;
+114AE;TIRHUTA LETTER SA;Lo;0;L;;;;;N;;;;;
+114AF;TIRHUTA LETTER HA;Lo;0;L;;;;;N;;;;;
+114B0;TIRHUTA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+114B1;TIRHUTA VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+114B2;TIRHUTA VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+114B3;TIRHUTA VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+114B4;TIRHUTA VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+114B5;TIRHUTA VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
+114B6;TIRHUTA VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;
+114B7;TIRHUTA VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
+114B8;TIRHUTA VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;
+114B9;TIRHUTA VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
+114BA;TIRHUTA VOWEL SIGN SHORT E;Mn;0;NSM;;;;;N;;;;;
+114BB;TIRHUTA VOWEL SIGN AI;Mc;0;L;114B9 114BA;;;;N;;;;;
+114BC;TIRHUTA VOWEL SIGN O;Mc;0;L;114B9 114B0;;;;N;;;;;
+114BD;TIRHUTA VOWEL SIGN SHORT O;Mc;0;L;;;;;N;;;;;
+114BE;TIRHUTA VOWEL SIGN AU;Mc;0;L;114B9 114BD;;;;N;;;;;
+114BF;TIRHUTA SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
+114C0;TIRHUTA SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+114C1;TIRHUTA SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+114C2;TIRHUTA SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+114C3;TIRHUTA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
+114C4;TIRHUTA SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;
+114C5;TIRHUTA GVANG;Lo;0;L;;;;;N;;;;;
+114C6;TIRHUTA ABBREVIATION SIGN;Po;0;L;;;;;N;;;;;
+114C7;TIRHUTA OM;Lo;0;L;;;;;N;;;;;
+114D0;TIRHUTA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+114D1;TIRHUTA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+114D2;TIRHUTA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+114D3;TIRHUTA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+114D4;TIRHUTA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+114D5;TIRHUTA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+114D6;TIRHUTA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+114D7;TIRHUTA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+114D8;TIRHUTA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+114D9;TIRHUTA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+11580;SIDDHAM LETTER A;Lo;0;L;;;;;N;;;;;
+11581;SIDDHAM LETTER AA;Lo;0;L;;;;;N;;;;;
+11582;SIDDHAM LETTER I;Lo;0;L;;;;;N;;;;;
+11583;SIDDHAM LETTER II;Lo;0;L;;;;;N;;;;;
+11584;SIDDHAM LETTER U;Lo;0;L;;;;;N;;;;;
+11585;SIDDHAM LETTER UU;Lo;0;L;;;;;N;;;;;
+11586;SIDDHAM LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+11587;SIDDHAM LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+11588;SIDDHAM LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
+11589;SIDDHAM LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
+1158A;SIDDHAM LETTER E;Lo;0;L;;;;;N;;;;;
+1158B;SIDDHAM LETTER AI;Lo;0;L;;;;;N;;;;;
+1158C;SIDDHAM LETTER O;Lo;0;L;;;;;N;;;;;
+1158D;SIDDHAM LETTER AU;Lo;0;L;;;;;N;;;;;
+1158E;SIDDHAM LETTER KA;Lo;0;L;;;;;N;;;;;
+1158F;SIDDHAM LETTER KHA;Lo;0;L;;;;;N;;;;;
+11590;SIDDHAM LETTER GA;Lo;0;L;;;;;N;;;;;
+11591;SIDDHAM LETTER GHA;Lo;0;L;;;;;N;;;;;
+11592;SIDDHAM LETTER NGA;Lo;0;L;;;;;N;;;;;
+11593;SIDDHAM LETTER CA;Lo;0;L;;;;;N;;;;;
+11594;SIDDHAM LETTER CHA;Lo;0;L;;;;;N;;;;;
+11595;SIDDHAM LETTER JA;Lo;0;L;;;;;N;;;;;
+11596;SIDDHAM LETTER JHA;Lo;0;L;;;;;N;;;;;
+11597;SIDDHAM LETTER NYA;Lo;0;L;;;;;N;;;;;
+11598;SIDDHAM LETTER TTA;Lo;0;L;;;;;N;;;;;
+11599;SIDDHAM LETTER TTHA;Lo;0;L;;;;;N;;;;;
+1159A;SIDDHAM LETTER DDA;Lo;0;L;;;;;N;;;;;
+1159B;SIDDHAM LETTER DDHA;Lo;0;L;;;;;N;;;;;
+1159C;SIDDHAM LETTER NNA;Lo;0;L;;;;;N;;;;;
+1159D;SIDDHAM LETTER TA;Lo;0;L;;;;;N;;;;;
+1159E;SIDDHAM LETTER THA;Lo;0;L;;;;;N;;;;;
+1159F;SIDDHAM LETTER DA;Lo;0;L;;;;;N;;;;;
+115A0;SIDDHAM LETTER DHA;Lo;0;L;;;;;N;;;;;
+115A1;SIDDHAM LETTER NA;Lo;0;L;;;;;N;;;;;
+115A2;SIDDHAM LETTER PA;Lo;0;L;;;;;N;;;;;
+115A3;SIDDHAM LETTER PHA;Lo;0;L;;;;;N;;;;;
+115A4;SIDDHAM LETTER BA;Lo;0;L;;;;;N;;;;;
+115A5;SIDDHAM LETTER BHA;Lo;0;L;;;;;N;;;;;
+115A6;SIDDHAM LETTER MA;Lo;0;L;;;;;N;;;;;
+115A7;SIDDHAM LETTER YA;Lo;0;L;;;;;N;;;;;
+115A8;SIDDHAM LETTER RA;Lo;0;L;;;;;N;;;;;
+115A9;SIDDHAM LETTER LA;Lo;0;L;;;;;N;;;;;
+115AA;SIDDHAM LETTER VA;Lo;0;L;;;;;N;;;;;
+115AB;SIDDHAM LETTER SHA;Lo;0;L;;;;;N;;;;;
+115AC;SIDDHAM LETTER SSA;Lo;0;L;;;;;N;;;;;
+115AD;SIDDHAM LETTER SA;Lo;0;L;;;;;N;;;;;
+115AE;SIDDHAM LETTER HA;Lo;0;L;;;;;N;;;;;
+115AF;SIDDHAM VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+115B0;SIDDHAM VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+115B1;SIDDHAM VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+115B2;SIDDHAM VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+115B3;SIDDHAM VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+115B4;SIDDHAM VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
+115B5;SIDDHAM VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;
+115B8;SIDDHAM VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
+115B9;SIDDHAM VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;
+115BA;SIDDHAM VOWEL SIGN O;Mc;0;L;115B8 115AF;;;;N;;;;;
+115BB;SIDDHAM VOWEL SIGN AU;Mc;0;L;115B9 115AF;;;;N;;;;;
+115BC;SIDDHAM SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
+115BD;SIDDHAM SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+115BE;SIDDHAM SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+115BF;SIDDHAM SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+115C0;SIDDHAM SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
+115C1;SIDDHAM SIGN SIDDHAM;Po;0;L;;;;;N;;;;;
+115C2;SIDDHAM DANDA;Po;0;L;;;;;N;;;;;
+115C3;SIDDHAM DOUBLE DANDA;Po;0;L;;;;;N;;;;;
+115C4;SIDDHAM SEPARATOR DOT;Po;0;L;;;;;N;;;;;
+115C5;SIDDHAM SEPARATOR BAR;Po;0;L;;;;;N;;;;;
+115C6;SIDDHAM REPETITION MARK-1;Po;0;L;;;;;N;;;;;
+115C7;SIDDHAM REPETITION MARK-2;Po;0;L;;;;;N;;;;;
+115C8;SIDDHAM REPETITION MARK-3;Po;0;L;;;;;N;;;;;
+115C9;SIDDHAM END OF TEXT MARK;Po;0;L;;;;;N;;;;;
+115CA;SIDDHAM SECTION MARK WITH TRIDENT AND U-SHAPED ORNAMENTS;Po;0;L;;;;;N;;;;;
+115CB;SIDDHAM SECTION MARK WITH TRIDENT AND DOTTED CRESCENTS;Po;0;L;;;;;N;;;;;
+115CC;SIDDHAM SECTION MARK WITH RAYS AND DOTTED CRESCENTS;Po;0;L;;;;;N;;;;;
+115CD;SIDDHAM SECTION MARK WITH RAYS AND DOTTED DOUBLE CRESCENTS;Po;0;L;;;;;N;;;;;
+115CE;SIDDHAM SECTION MARK WITH RAYS AND DOTTED TRIPLE CRESCENTS;Po;0;L;;;;;N;;;;;
+115CF;SIDDHAM SECTION MARK DOUBLE RING;Po;0;L;;;;;N;;;;;
+115D0;SIDDHAM SECTION MARK DOUBLE RING WITH RAYS;Po;0;L;;;;;N;;;;;
+115D1;SIDDHAM SECTION MARK WITH DOUBLE CRESCENTS;Po;0;L;;;;;N;;;;;
+115D2;SIDDHAM SECTION MARK WITH TRIPLE CRESCENTS;Po;0;L;;;;;N;;;;;
+115D3;SIDDHAM SECTION MARK WITH QUADRUPLE CRESCENTS;Po;0;L;;;;;N;;;;;
+115D4;SIDDHAM SECTION MARK WITH SEPTUPLE CRESCENTS;Po;0;L;;;;;N;;;;;
+115D5;SIDDHAM SECTION MARK WITH CIRCLES AND RAYS;Po;0;L;;;;;N;;;;;
+115D6;SIDDHAM SECTION MARK WITH CIRCLES AND TWO ENCLOSURES;Po;0;L;;;;;N;;;;;
+115D7;SIDDHAM SECTION MARK WITH CIRCLES AND FOUR ENCLOSURES;Po;0;L;;;;;N;;;;;
+115D8;SIDDHAM LETTER THREE-CIRCLE ALTERNATE I;Lo;0;L;;;;;N;;;;;
+115D9;SIDDHAM LETTER TWO-CIRCLE ALTERNATE I;Lo;0;L;;;;;N;;;;;
+115DA;SIDDHAM LETTER TWO-CIRCLE ALTERNATE II;Lo;0;L;;;;;N;;;;;
+115DB;SIDDHAM LETTER ALTERNATE U;Lo;0;L;;;;;N;;;;;
+115DC;SIDDHAM VOWEL SIGN ALTERNATE U;Mn;0;NSM;;;;;N;;;;;
+115DD;SIDDHAM VOWEL SIGN ALTERNATE UU;Mn;0;NSM;;;;;N;;;;;
+11600;MODI LETTER A;Lo;0;L;;;;;N;;;;;
+11601;MODI LETTER AA;Lo;0;L;;;;;N;;;;;
+11602;MODI LETTER I;Lo;0;L;;;;;N;;;;;
+11603;MODI LETTER II;Lo;0;L;;;;;N;;;;;
+11604;MODI LETTER U;Lo;0;L;;;;;N;;;;;
+11605;MODI LETTER UU;Lo;0;L;;;;;N;;;;;
+11606;MODI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+11607;MODI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+11608;MODI LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
+11609;MODI LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
+1160A;MODI LETTER E;Lo;0;L;;;;;N;;;;;
+1160B;MODI LETTER AI;Lo;0;L;;;;;N;;;;;
+1160C;MODI LETTER O;Lo;0;L;;;;;N;;;;;
+1160D;MODI LETTER AU;Lo;0;L;;;;;N;;;;;
+1160E;MODI LETTER KA;Lo;0;L;;;;;N;;;;;
+1160F;MODI LETTER KHA;Lo;0;L;;;;;N;;;;;
+11610;MODI LETTER GA;Lo;0;L;;;;;N;;;;;
+11611;MODI LETTER GHA;Lo;0;L;;;;;N;;;;;
+11612;MODI LETTER NGA;Lo;0;L;;;;;N;;;;;
+11613;MODI LETTER CA;Lo;0;L;;;;;N;;;;;
+11614;MODI LETTER CHA;Lo;0;L;;;;;N;;;;;
+11615;MODI LETTER JA;Lo;0;L;;;;;N;;;;;
+11616;MODI LETTER JHA;Lo;0;L;;;;;N;;;;;
+11617;MODI LETTER NYA;Lo;0;L;;;;;N;;;;;
+11618;MODI LETTER TTA;Lo;0;L;;;;;N;;;;;
+11619;MODI LETTER TTHA;Lo;0;L;;;;;N;;;;;
+1161A;MODI LETTER DDA;Lo;0;L;;;;;N;;;;;
+1161B;MODI LETTER DDHA;Lo;0;L;;;;;N;;;;;
+1161C;MODI LETTER NNA;Lo;0;L;;;;;N;;;;;
+1161D;MODI LETTER TA;Lo;0;L;;;;;N;;;;;
+1161E;MODI LETTER THA;Lo;0;L;;;;;N;;;;;
+1161F;MODI LETTER DA;Lo;0;L;;;;;N;;;;;
+11620;MODI LETTER DHA;Lo;0;L;;;;;N;;;;;
+11621;MODI LETTER NA;Lo;0;L;;;;;N;;;;;
+11622;MODI LETTER PA;Lo;0;L;;;;;N;;;;;
+11623;MODI LETTER PHA;Lo;0;L;;;;;N;;;;;
+11624;MODI LETTER BA;Lo;0;L;;;;;N;;;;;
+11625;MODI LETTER BHA;Lo;0;L;;;;;N;;;;;
+11626;MODI LETTER MA;Lo;0;L;;;;;N;;;;;
+11627;MODI LETTER YA;Lo;0;L;;;;;N;;;;;
+11628;MODI LETTER RA;Lo;0;L;;;;;N;;;;;
+11629;MODI LETTER LA;Lo;0;L;;;;;N;;;;;
+1162A;MODI LETTER VA;Lo;0;L;;;;;N;;;;;
+1162B;MODI LETTER SHA;Lo;0;L;;;;;N;;;;;
+1162C;MODI LETTER SSA;Lo;0;L;;;;;N;;;;;
+1162D;MODI LETTER SA;Lo;0;L;;;;;N;;;;;
+1162E;MODI LETTER HA;Lo;0;L;;;;;N;;;;;
+1162F;MODI LETTER LLA;Lo;0;L;;;;;N;;;;;
+11630;MODI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+11631;MODI VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+11632;MODI VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+11633;MODI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+11634;MODI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+11635;MODI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
+11636;MODI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;
+11637;MODI VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
+11638;MODI VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;
+11639;MODI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+1163A;MODI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
+1163B;MODI VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
+1163C;MODI VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;
+1163D;MODI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+1163E;MODI SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+1163F;MODI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+11640;MODI SIGN ARDHACANDRA;Mn;0;NSM;;;;;N;;;;;
+11641;MODI DANDA;Po;0;L;;;;;N;;;;;
+11642;MODI DOUBLE DANDA;Po;0;L;;;;;N;;;;;
+11643;MODI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;;
+11644;MODI SIGN HUVA;Lo;0;L;;;;;N;;;;;
+11650;MODI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+11651;MODI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+11652;MODI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+11653;MODI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+11654;MODI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+11655;MODI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+11656;MODI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+11657;MODI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+11658;MODI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+11659;MODI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+11660;MONGOLIAN BIRGA WITH ORNAMENT;Po;0;ON;;;;;N;;;;;
+11661;MONGOLIAN ROTATED BIRGA;Po;0;ON;;;;;N;;;;;
+11662;MONGOLIAN DOUBLE BIRGA WITH ORNAMENT;Po;0;ON;;;;;N;;;;;
+11663;MONGOLIAN TRIPLE BIRGA WITH ORNAMENT;Po;0;ON;;;;;N;;;;;
+11664;MONGOLIAN BIRGA WITH DOUBLE ORNAMENT;Po;0;ON;;;;;N;;;;;
+11665;MONGOLIAN ROTATED BIRGA WITH ORNAMENT;Po;0;ON;;;;;N;;;;;
+11666;MONGOLIAN ROTATED BIRGA WITH DOUBLE ORNAMENT;Po;0;ON;;;;;N;;;;;
+11667;MONGOLIAN INVERTED BIRGA;Po;0;ON;;;;;N;;;;;
+11668;MONGOLIAN INVERTED BIRGA WITH DOUBLE ORNAMENT;Po;0;ON;;;;;N;;;;;
+11669;MONGOLIAN SWIRL BIRGA;Po;0;ON;;;;;N;;;;;
+1166A;MONGOLIAN SWIRL BIRGA WITH ORNAMENT;Po;0;ON;;;;;N;;;;;
+1166B;MONGOLIAN SWIRL BIRGA WITH DOUBLE ORNAMENT;Po;0;ON;;;;;N;;;;;
+1166C;MONGOLIAN TURNED SWIRL BIRGA WITH DOUBLE ORNAMENT;Po;0;ON;;;;;N;;;;;
+11680;TAKRI LETTER A;Lo;0;L;;;;;N;;;;;
+11681;TAKRI LETTER AA;Lo;0;L;;;;;N;;;;;
+11682;TAKRI LETTER I;Lo;0;L;;;;;N;;;;;
+11683;TAKRI LETTER II;Lo;0;L;;;;;N;;;;;
+11684;TAKRI LETTER U;Lo;0;L;;;;;N;;;;;
+11685;TAKRI LETTER UU;Lo;0;L;;;;;N;;;;;
+11686;TAKRI LETTER E;Lo;0;L;;;;;N;;;;;
+11687;TAKRI LETTER AI;Lo;0;L;;;;;N;;;;;
+11688;TAKRI LETTER O;Lo;0;L;;;;;N;;;;;
+11689;TAKRI LETTER AU;Lo;0;L;;;;;N;;;;;
+1168A;TAKRI LETTER KA;Lo;0;L;;;;;N;;;;;
+1168B;TAKRI LETTER KHA;Lo;0;L;;;;;N;;;;;
+1168C;TAKRI LETTER GA;Lo;0;L;;;;;N;;;;;
+1168D;TAKRI LETTER GHA;Lo;0;L;;;;;N;;;;;
+1168E;TAKRI LETTER NGA;Lo;0;L;;;;;N;;;;;
+1168F;TAKRI LETTER CA;Lo;0;L;;;;;N;;;;;
+11690;TAKRI LETTER CHA;Lo;0;L;;;;;N;;;;;
+11691;TAKRI LETTER JA;Lo;0;L;;;;;N;;;;;
+11692;TAKRI LETTER JHA;Lo;0;L;;;;;N;;;;;
+11693;TAKRI LETTER NYA;Lo;0;L;;;;;N;;;;;
+11694;TAKRI LETTER TTA;Lo;0;L;;;;;N;;;;;
+11695;TAKRI LETTER TTHA;Lo;0;L;;;;;N;;;;;
+11696;TAKRI LETTER DDA;Lo;0;L;;;;;N;;;;;
+11697;TAKRI LETTER DDHA;Lo;0;L;;;;;N;;;;;
+11698;TAKRI LETTER NNA;Lo;0;L;;;;;N;;;;;
+11699;TAKRI LETTER TA;Lo;0;L;;;;;N;;;;;
+1169A;TAKRI LETTER THA;Lo;0;L;;;;;N;;;;;
+1169B;TAKRI LETTER DA;Lo;0;L;;;;;N;;;;;
+1169C;TAKRI LETTER DHA;Lo;0;L;;;;;N;;;;;
+1169D;TAKRI LETTER NA;Lo;0;L;;;;;N;;;;;
+1169E;TAKRI LETTER PA;Lo;0;L;;;;;N;;;;;
+1169F;TAKRI LETTER PHA;Lo;0;L;;;;;N;;;;;
+116A0;TAKRI LETTER BA;Lo;0;L;;;;;N;;;;;
+116A1;TAKRI LETTER BHA;Lo;0;L;;;;;N;;;;;
+116A2;TAKRI LETTER MA;Lo;0;L;;;;;N;;;;;
+116A3;TAKRI LETTER YA;Lo;0;L;;;;;N;;;;;
+116A4;TAKRI LETTER RA;Lo;0;L;;;;;N;;;;;
+116A5;TAKRI LETTER LA;Lo;0;L;;;;;N;;;;;
+116A6;TAKRI LETTER VA;Lo;0;L;;;;;N;;;;;
+116A7;TAKRI LETTER SHA;Lo;0;L;;;;;N;;;;;
+116A8;TAKRI LETTER SA;Lo;0;L;;;;;N;;;;;
+116A9;TAKRI LETTER HA;Lo;0;L;;;;;N;;;;;
+116AA;TAKRI LETTER RRA;Lo;0;L;;;;;N;;;;;
+116AB;TAKRI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+116AC;TAKRI SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+116AD;TAKRI VOWEL SIGN AA;Mn;0;NSM;;;;;N;;;;;
+116AE;TAKRI VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+116AF;TAKRI VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+116B0;TAKRI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+116B1;TAKRI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+116B2;TAKRI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+116B3;TAKRI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
+116B4;TAKRI VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;
+116B5;TAKRI VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;;
+116B6;TAKRI SIGN VIRAMA;Mc;9;L;;;;;N;;;;;
+116B7;TAKRI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
+116C0;TAKRI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+116C1;TAKRI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+116C2;TAKRI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+116C3;TAKRI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+116C4;TAKRI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+116C5;TAKRI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+116C6;TAKRI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+116C7;TAKRI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+116C8;TAKRI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+116C9;TAKRI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+11700;AHOM LETTER KA;Lo;0;L;;;;;N;;;;;
+11701;AHOM LETTER KHA;Lo;0;L;;;;;N;;;;;
+11702;AHOM LETTER NGA;Lo;0;L;;;;;N;;;;;
+11703;AHOM LETTER NA;Lo;0;L;;;;;N;;;;;
+11704;AHOM LETTER TA;Lo;0;L;;;;;N;;;;;
+11705;AHOM LETTER ALTERNATE TA;Lo;0;L;;;;;N;;;;;
+11706;AHOM LETTER PA;Lo;0;L;;;;;N;;;;;
+11707;AHOM LETTER PHA;Lo;0;L;;;;;N;;;;;
+11708;AHOM LETTER BA;Lo;0;L;;;;;N;;;;;
+11709;AHOM LETTER MA;Lo;0;L;;;;;N;;;;;
+1170A;AHOM LETTER JA;Lo;0;L;;;;;N;;;;;
+1170B;AHOM LETTER CHA;Lo;0;L;;;;;N;;;;;
+1170C;AHOM LETTER THA;Lo;0;L;;;;;N;;;;;
+1170D;AHOM LETTER RA;Lo;0;L;;;;;N;;;;;
+1170E;AHOM LETTER LA;Lo;0;L;;;;;N;;;;;
+1170F;AHOM LETTER SA;Lo;0;L;;;;;N;;;;;
+11710;AHOM LETTER NYA;Lo;0;L;;;;;N;;;;;
+11711;AHOM LETTER HA;Lo;0;L;;;;;N;;;;;
+11712;AHOM LETTER A;Lo;0;L;;;;;N;;;;;
+11713;AHOM LETTER DA;Lo;0;L;;;;;N;;;;;
+11714;AHOM LETTER DHA;Lo;0;L;;;;;N;;;;;
+11715;AHOM LETTER GA;Lo;0;L;;;;;N;;;;;
+11716;AHOM LETTER ALTERNATE GA;Lo;0;L;;;;;N;;;;;
+11717;AHOM LETTER GHA;Lo;0;L;;;;;N;;;;;
+11718;AHOM LETTER BHA;Lo;0;L;;;;;N;;;;;
+11719;AHOM LETTER JHA;Lo;0;L;;;;;N;;;;;
+1171D;AHOM CONSONANT SIGN MEDIAL LA;Mn;0;NSM;;;;;N;;;;;
+1171E;AHOM CONSONANT SIGN MEDIAL RA;Mn;0;NSM;;;;;N;;;;;
+1171F;AHOM CONSONANT SIGN MEDIAL LIGATING RA;Mn;0;NSM;;;;;N;;;;;
+11720;AHOM VOWEL SIGN A;Mc;0;L;;;;;N;;;;;
+11721;AHOM VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+11722;AHOM VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+11723;AHOM VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;
+11724;AHOM VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+11725;AHOM VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+11726;AHOM VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
+11727;AHOM VOWEL SIGN AW;Mn;0;NSM;;;;;N;;;;;
+11728;AHOM VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;
+11729;AHOM VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
+1172A;AHOM VOWEL SIGN AM;Mn;0;NSM;;;;;N;;;;;
+1172B;AHOM SIGN KILLER;Mn;9;NSM;;;;;N;;;;;
+11730;AHOM DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+11731;AHOM DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+11732;AHOM DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+11733;AHOM DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+11734;AHOM DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+11735;AHOM DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+11736;AHOM DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+11737;AHOM DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+11738;AHOM DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+11739;AHOM DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+1173A;AHOM NUMBER TEN;No;0;L;;;;10;N;;;;;
+1173B;AHOM NUMBER TWENTY;No;0;L;;;;20;N;;;;;
+1173C;AHOM SIGN SMALL SECTION;Po;0;L;;;;;N;;;;;
+1173D;AHOM SIGN SECTION;Po;0;L;;;;;N;;;;;
+1173E;AHOM SIGN RULAI;Po;0;L;;;;;N;;;;;
+1173F;AHOM SYMBOL VI;So;0;L;;;;;N;;;;;
+118A0;WARANG CITI CAPITAL LETTER NGAA;Lu;0;L;;;;;N;;;;118C0;
+118A1;WARANG CITI CAPITAL LETTER A;Lu;0;L;;;;;N;;;;118C1;
+118A2;WARANG CITI CAPITAL LETTER WI;Lu;0;L;;;;;N;;;;118C2;
+118A3;WARANG CITI CAPITAL LETTER YU;Lu;0;L;;;;;N;;;;118C3;
+118A4;WARANG CITI CAPITAL LETTER YA;Lu;0;L;;;;;N;;;;118C4;
+118A5;WARANG CITI CAPITAL LETTER YO;Lu;0;L;;;;;N;;;;118C5;
+118A6;WARANG CITI CAPITAL LETTER II;Lu;0;L;;;;;N;;;;118C6;
+118A7;WARANG CITI CAPITAL LETTER UU;Lu;0;L;;;;;N;;;;118C7;
+118A8;WARANG CITI CAPITAL LETTER E;Lu;0;L;;;;;N;;;;118C8;
+118A9;WARANG CITI CAPITAL LETTER O;Lu;0;L;;;;;N;;;;118C9;
+118AA;WARANG CITI CAPITAL LETTER ANG;Lu;0;L;;;;;N;;;;118CA;
+118AB;WARANG CITI CAPITAL LETTER GA;Lu;0;L;;;;;N;;;;118CB;
+118AC;WARANG CITI CAPITAL LETTER KO;Lu;0;L;;;;;N;;;;118CC;
+118AD;WARANG CITI CAPITAL LETTER ENY;Lu;0;L;;;;;N;;;;118CD;
+118AE;WARANG CITI CAPITAL LETTER YUJ;Lu;0;L;;;;;N;;;;118CE;
+118AF;WARANG CITI CAPITAL LETTER UC;Lu;0;L;;;;;N;;;;118CF;
+118B0;WARANG CITI CAPITAL LETTER ENN;Lu;0;L;;;;;N;;;;118D0;
+118B1;WARANG CITI CAPITAL LETTER ODD;Lu;0;L;;;;;N;;;;118D1;
+118B2;WARANG CITI CAPITAL LETTER TTE;Lu;0;L;;;;;N;;;;118D2;
+118B3;WARANG CITI CAPITAL LETTER NUNG;Lu;0;L;;;;;N;;;;118D3;
+118B4;WARANG CITI CAPITAL LETTER DA;Lu;0;L;;;;;N;;;;118D4;
+118B5;WARANG CITI CAPITAL LETTER AT;Lu;0;L;;;;;N;;;;118D5;
+118B6;WARANG CITI CAPITAL LETTER AM;Lu;0;L;;;;;N;;;;118D6;
+118B7;WARANG CITI CAPITAL LETTER BU;Lu;0;L;;;;;N;;;;118D7;
+118B8;WARANG CITI CAPITAL LETTER PU;Lu;0;L;;;;;N;;;;118D8;
+118B9;WARANG CITI CAPITAL LETTER HIYO;Lu;0;L;;;;;N;;;;118D9;
+118BA;WARANG CITI CAPITAL LETTER HOLO;Lu;0;L;;;;;N;;;;118DA;
+118BB;WARANG CITI CAPITAL LETTER HORR;Lu;0;L;;;;;N;;;;118DB;
+118BC;WARANG CITI CAPITAL LETTER HAR;Lu;0;L;;;;;N;;;;118DC;
+118BD;WARANG CITI CAPITAL LETTER SSUU;Lu;0;L;;;;;N;;;;118DD;
+118BE;WARANG CITI CAPITAL LETTER SII;Lu;0;L;;;;;N;;;;118DE;
+118BF;WARANG CITI CAPITAL LETTER VIYO;Lu;0;L;;;;;N;;;;118DF;
+118C0;WARANG CITI SMALL LETTER NGAA;Ll;0;L;;;;;N;;;118A0;;118A0
+118C1;WARANG CITI SMALL LETTER A;Ll;0;L;;;;;N;;;118A1;;118A1
+118C2;WARANG CITI SMALL LETTER WI;Ll;0;L;;;;;N;;;118A2;;118A2
+118C3;WARANG CITI SMALL LETTER YU;Ll;0;L;;;;;N;;;118A3;;118A3
+118C4;WARANG CITI SMALL LETTER YA;Ll;0;L;;;;;N;;;118A4;;118A4
+118C5;WARANG CITI SMALL LETTER YO;Ll;0;L;;;;;N;;;118A5;;118A5
+118C6;WARANG CITI SMALL LETTER II;Ll;0;L;;;;;N;;;118A6;;118A6
+118C7;WARANG CITI SMALL LETTER UU;Ll;0;L;;;;;N;;;118A7;;118A7
+118C8;WARANG CITI SMALL LETTER E;Ll;0;L;;;;;N;;;118A8;;118A8
+118C9;WARANG CITI SMALL LETTER O;Ll;0;L;;;;;N;;;118A9;;118A9
+118CA;WARANG CITI SMALL LETTER ANG;Ll;0;L;;;;;N;;;118AA;;118AA
+118CB;WARANG CITI SMALL LETTER GA;Ll;0;L;;;;;N;;;118AB;;118AB
+118CC;WARANG CITI SMALL LETTER KO;Ll;0;L;;;;;N;;;118AC;;118AC
+118CD;WARANG CITI SMALL LETTER ENY;Ll;0;L;;;;;N;;;118AD;;118AD
+118CE;WARANG CITI SMALL LETTER YUJ;Ll;0;L;;;;;N;;;118AE;;118AE
+118CF;WARANG CITI SMALL LETTER UC;Ll;0;L;;;;;N;;;118AF;;118AF
+118D0;WARANG CITI SMALL LETTER ENN;Ll;0;L;;;;;N;;;118B0;;118B0
+118D1;WARANG CITI SMALL LETTER ODD;Ll;0;L;;;;;N;;;118B1;;118B1
+118D2;WARANG CITI SMALL LETTER TTE;Ll;0;L;;;;;N;;;118B2;;118B2
+118D3;WARANG CITI SMALL LETTER NUNG;Ll;0;L;;;;;N;;;118B3;;118B3
+118D4;WARANG CITI SMALL LETTER DA;Ll;0;L;;;;;N;;;118B4;;118B4
+118D5;WARANG CITI SMALL LETTER AT;Ll;0;L;;;;;N;;;118B5;;118B5
+118D6;WARANG CITI SMALL LETTER AM;Ll;0;L;;;;;N;;;118B6;;118B6
+118D7;WARANG CITI SMALL LETTER BU;Ll;0;L;;;;;N;;;118B7;;118B7
+118D8;WARANG CITI SMALL LETTER PU;Ll;0;L;;;;;N;;;118B8;;118B8
+118D9;WARANG CITI SMALL LETTER HIYO;Ll;0;L;;;;;N;;;118B9;;118B9
+118DA;WARANG CITI SMALL LETTER HOLO;Ll;0;L;;;;;N;;;118BA;;118BA
+118DB;WARANG CITI SMALL LETTER HORR;Ll;0;L;;;;;N;;;118BB;;118BB
+118DC;WARANG CITI SMALL LETTER HAR;Ll;0;L;;;;;N;;;118BC;;118BC
+118DD;WARANG CITI SMALL LETTER SSUU;Ll;0;L;;;;;N;;;118BD;;118BD
+118DE;WARANG CITI SMALL LETTER SII;Ll;0;L;;;;;N;;;118BE;;118BE
+118DF;WARANG CITI SMALL LETTER VIYO;Ll;0;L;;;;;N;;;118BF;;118BF
+118E0;WARANG CITI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+118E1;WARANG CITI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+118E2;WARANG CITI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+118E3;WARANG CITI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+118E4;WARANG CITI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+118E5;WARANG CITI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+118E6;WARANG CITI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+118E7;WARANG CITI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+118E8;WARANG CITI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+118E9;WARANG CITI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+118EA;WARANG CITI NUMBER TEN;No;0;L;;;;10;N;;;;;
+118EB;WARANG CITI NUMBER TWENTY;No;0;L;;;;20;N;;;;;
+118EC;WARANG CITI NUMBER THIRTY;No;0;L;;;;30;N;;;;;
+118ED;WARANG CITI NUMBER FORTY;No;0;L;;;;40;N;;;;;
+118EE;WARANG CITI NUMBER FIFTY;No;0;L;;;;50;N;;;;;
+118EF;WARANG CITI NUMBER SIXTY;No;0;L;;;;60;N;;;;;
+118F0;WARANG CITI NUMBER SEVENTY;No;0;L;;;;70;N;;;;;
+118F1;WARANG CITI NUMBER EIGHTY;No;0;L;;;;80;N;;;;;
+118F2;WARANG CITI NUMBER NINETY;No;0;L;;;;90;N;;;;;
+118FF;WARANG CITI OM;Lo;0;L;;;;;N;;;;;
+11A00;ZANABAZAR SQUARE LETTER A;Lo;0;L;;;;;N;;;;;
+11A01;ZANABAZAR SQUARE VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+11A02;ZANABAZAR SQUARE VOWEL SIGN UE;Mn;0;NSM;;;;;N;;;;;
+11A03;ZANABAZAR SQUARE VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+11A04;ZANABAZAR SQUARE VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+11A05;ZANABAZAR SQUARE VOWEL SIGN OE;Mn;0;NSM;;;;;N;;;;;
+11A06;ZANABAZAR SQUARE VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;
+11A07;ZANABAZAR SQUARE VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;
+11A08;ZANABAZAR SQUARE VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;
+11A09;ZANABAZAR SQUARE VOWEL SIGN REVERSED I;Mn;0;NSM;;;;;N;;;;;
+11A0A;ZANABAZAR SQUARE VOWEL LENGTH MARK;Mn;0;NSM;;;;;N;;;;;
+11A0B;ZANABAZAR SQUARE LETTER KA;Lo;0;L;;;;;N;;;;;
+11A0C;ZANABAZAR SQUARE LETTER KHA;Lo;0;L;;;;;N;;;;;
+11A0D;ZANABAZAR SQUARE LETTER GA;Lo;0;L;;;;;N;;;;;
+11A0E;ZANABAZAR SQUARE LETTER GHA;Lo;0;L;;;;;N;;;;;
+11A0F;ZANABAZAR SQUARE LETTER NGA;Lo;0;L;;;;;N;;;;;
+11A10;ZANABAZAR SQUARE LETTER CA;Lo;0;L;;;;;N;;;;;
+11A11;ZANABAZAR SQUARE LETTER CHA;Lo;0;L;;;;;N;;;;;
+11A12;ZANABAZAR SQUARE LETTER JA;Lo;0;L;;;;;N;;;;;
+11A13;ZANABAZAR SQUARE LETTER NYA;Lo;0;L;;;;;N;;;;;
+11A14;ZANABAZAR SQUARE LETTER TTA;Lo;0;L;;;;;N;;;;;
+11A15;ZANABAZAR SQUARE LETTER TTHA;Lo;0;L;;;;;N;;;;;
+11A16;ZANABAZAR SQUARE LETTER DDA;Lo;0;L;;;;;N;;;;;
+11A17;ZANABAZAR SQUARE LETTER DDHA;Lo;0;L;;;;;N;;;;;
+11A18;ZANABAZAR SQUARE LETTER NNA;Lo;0;L;;;;;N;;;;;
+11A19;ZANABAZAR SQUARE LETTER TA;Lo;0;L;;;;;N;;;;;
+11A1A;ZANABAZAR SQUARE LETTER THA;Lo;0;L;;;;;N;;;;;
+11A1B;ZANABAZAR SQUARE LETTER DA;Lo;0;L;;;;;N;;;;;
+11A1C;ZANABAZAR SQUARE LETTER DHA;Lo;0;L;;;;;N;;;;;
+11A1D;ZANABAZAR SQUARE LETTER NA;Lo;0;L;;;;;N;;;;;
+11A1E;ZANABAZAR SQUARE LETTER PA;Lo;0;L;;;;;N;;;;;
+11A1F;ZANABAZAR SQUARE LETTER PHA;Lo;0;L;;;;;N;;;;;
+11A20;ZANABAZAR SQUARE LETTER BA;Lo;0;L;;;;;N;;;;;
+11A21;ZANABAZAR SQUARE LETTER BHA;Lo;0;L;;;;;N;;;;;
+11A22;ZANABAZAR SQUARE LETTER MA;Lo;0;L;;;;;N;;;;;
+11A23;ZANABAZAR SQUARE LETTER TSA;Lo;0;L;;;;;N;;;;;
+11A24;ZANABAZAR SQUARE LETTER TSHA;Lo;0;L;;;;;N;;;;;
+11A25;ZANABAZAR SQUARE LETTER DZA;Lo;0;L;;;;;N;;;;;
+11A26;ZANABAZAR SQUARE LETTER DZHA;Lo;0;L;;;;;N;;;;;
+11A27;ZANABAZAR SQUARE LETTER ZHA;Lo;0;L;;;;;N;;;;;
+11A28;ZANABAZAR SQUARE LETTER ZA;Lo;0;L;;;;;N;;;;;
+11A29;ZANABAZAR SQUARE LETTER -A;Lo;0;L;;;;;N;;;;;
+11A2A;ZANABAZAR SQUARE LETTER YA;Lo;0;L;;;;;N;;;;;
+11A2B;ZANABAZAR SQUARE LETTER RA;Lo;0;L;;;;;N;;;;;
+11A2C;ZANABAZAR SQUARE LETTER LA;Lo;0;L;;;;;N;;;;;
+11A2D;ZANABAZAR SQUARE LETTER VA;Lo;0;L;;;;;N;;;;;
+11A2E;ZANABAZAR SQUARE LETTER SHA;Lo;0;L;;;;;N;;;;;
+11A2F;ZANABAZAR SQUARE LETTER SSA;Lo;0;L;;;;;N;;;;;
+11A30;ZANABAZAR SQUARE LETTER SA;Lo;0;L;;;;;N;;;;;
+11A31;ZANABAZAR SQUARE LETTER HA;Lo;0;L;;;;;N;;;;;
+11A32;ZANABAZAR SQUARE LETTER KSSA;Lo;0;L;;;;;N;;;;;
+11A33;ZANABAZAR SQUARE FINAL CONSONANT MARK;Mn;0;NSM;;;;;N;;;;;
+11A34;ZANABAZAR SQUARE SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+11A35;ZANABAZAR SQUARE SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
+11A36;ZANABAZAR SQUARE SIGN CANDRABINDU WITH ORNAMENT;Mn;0;NSM;;;;;N;;;;;
+11A37;ZANABAZAR SQUARE SIGN CANDRA WITH ORNAMENT;Mn;0;NSM;;;;;N;;;;;
+11A38;ZANABAZAR SQUARE SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+11A39;ZANABAZAR SQUARE SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+11A3A;ZANABAZAR SQUARE CLUSTER-INITIAL LETTER RA;Lo;0;L;;;;;N;;;;;
+11A3B;ZANABAZAR SQUARE CLUSTER-FINAL LETTER YA;Mn;0;NSM;;;;;N;;;;;
+11A3C;ZANABAZAR SQUARE CLUSTER-FINAL LETTER RA;Mn;0;NSM;;;;;N;;;;;
+11A3D;ZANABAZAR SQUARE CLUSTER-FINAL LETTER LA;Mn;0;NSM;;;;;N;;;;;
+11A3E;ZANABAZAR SQUARE CLUSTER-FINAL LETTER VA;Mn;0;NSM;;;;;N;;;;;
+11A3F;ZANABAZAR SQUARE INITIAL HEAD MARK;Po;0;L;;;;;N;;;;;
+11A40;ZANABAZAR SQUARE CLOSING HEAD MARK;Po;0;L;;;;;N;;;;;
+11A41;ZANABAZAR SQUARE MARK TSHEG;Po;0;L;;;;;N;;;;;
+11A42;ZANABAZAR SQUARE MARK SHAD;Po;0;L;;;;;N;;;;;
+11A43;ZANABAZAR SQUARE MARK DOUBLE SHAD;Po;0;L;;;;;N;;;;;
+11A44;ZANABAZAR SQUARE MARK LONG TSHEG;Po;0;L;;;;;N;;;;;
+11A45;ZANABAZAR SQUARE INITIAL DOUBLE-LINED HEAD MARK;Po;0;L;;;;;N;;;;;
+11A46;ZANABAZAR SQUARE CLOSING DOUBLE-LINED HEAD MARK;Po;0;L;;;;;N;;;;;
+11A47;ZANABAZAR SQUARE SUBJOINER;Mn;9;NSM;;;;;N;;;;;
+11A50;SOYOMBO LETTER A;Lo;0;L;;;;;N;;;;;
+11A51;SOYOMBO VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+11A52;SOYOMBO VOWEL SIGN UE;Mn;0;NSM;;;;;N;;;;;
+11A53;SOYOMBO VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+11A54;SOYOMBO VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+11A55;SOYOMBO VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;
+11A56;SOYOMBO VOWEL SIGN OE;Mn;0;NSM;;;;;N;;;;;
+11A57;SOYOMBO VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;
+11A58;SOYOMBO VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;
+11A59;SOYOMBO VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
+11A5A;SOYOMBO VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
+11A5B;SOYOMBO VOWEL LENGTH MARK;Mn;0;NSM;;;;;N;;;;;
+11A5C;SOYOMBO LETTER KA;Lo;0;L;;;;;N;;;;;
+11A5D;SOYOMBO LETTER KHA;Lo;0;L;;;;;N;;;;;
+11A5E;SOYOMBO LETTER GA;Lo;0;L;;;;;N;;;;;
+11A5F;SOYOMBO LETTER GHA;Lo;0;L;;;;;N;;;;;
+11A60;SOYOMBO LETTER NGA;Lo;0;L;;;;;N;;;;;
+11A61;SOYOMBO LETTER CA;Lo;0;L;;;;;N;;;;;
+11A62;SOYOMBO LETTER CHA;Lo;0;L;;;;;N;;;;;
+11A63;SOYOMBO LETTER JA;Lo;0;L;;;;;N;;;;;
+11A64;SOYOMBO LETTER JHA;Lo;0;L;;;;;N;;;;;
+11A65;SOYOMBO LETTER NYA;Lo;0;L;;;;;N;;;;;
+11A66;SOYOMBO LETTER TTA;Lo;0;L;;;;;N;;;;;
+11A67;SOYOMBO LETTER TTHA;Lo;0;L;;;;;N;;;;;
+11A68;SOYOMBO LETTER DDA;Lo;0;L;;;;;N;;;;;
+11A69;SOYOMBO LETTER DDHA;Lo;0;L;;;;;N;;;;;
+11A6A;SOYOMBO LETTER NNA;Lo;0;L;;;;;N;;;;;
+11A6B;SOYOMBO LETTER TA;Lo;0;L;;;;;N;;;;;
+11A6C;SOYOMBO LETTER THA;Lo;0;L;;;;;N;;;;;
+11A6D;SOYOMBO LETTER DA;Lo;0;L;;;;;N;;;;;
+11A6E;SOYOMBO LETTER DHA;Lo;0;L;;;;;N;;;;;
+11A6F;SOYOMBO LETTER NA;Lo;0;L;;;;;N;;;;;
+11A70;SOYOMBO LETTER PA;Lo;0;L;;;;;N;;;;;
+11A71;SOYOMBO LETTER PHA;Lo;0;L;;;;;N;;;;;
+11A72;SOYOMBO LETTER BA;Lo;0;L;;;;;N;;;;;
+11A73;SOYOMBO LETTER BHA;Lo;0;L;;;;;N;;;;;
+11A74;SOYOMBO LETTER MA;Lo;0;L;;;;;N;;;;;
+11A75;SOYOMBO LETTER TSA;Lo;0;L;;;;;N;;;;;
+11A76;SOYOMBO LETTER TSHA;Lo;0;L;;;;;N;;;;;
+11A77;SOYOMBO LETTER DZA;Lo;0;L;;;;;N;;;;;
+11A78;SOYOMBO LETTER ZHA;Lo;0;L;;;;;N;;;;;
+11A79;SOYOMBO LETTER ZA;Lo;0;L;;;;;N;;;;;
+11A7A;SOYOMBO LETTER -A;Lo;0;L;;;;;N;;;;;
+11A7B;SOYOMBO LETTER YA;Lo;0;L;;;;;N;;;;;
+11A7C;SOYOMBO LETTER RA;Lo;0;L;;;;;N;;;;;
+11A7D;SOYOMBO LETTER LA;Lo;0;L;;;;;N;;;;;
+11A7E;SOYOMBO LETTER VA;Lo;0;L;;;;;N;;;;;
+11A7F;SOYOMBO LETTER SHA;Lo;0;L;;;;;N;;;;;
+11A80;SOYOMBO LETTER SSA;Lo;0;L;;;;;N;;;;;
+11A81;SOYOMBO LETTER SA;Lo;0;L;;;;;N;;;;;
+11A82;SOYOMBO LETTER HA;Lo;0;L;;;;;N;;;;;
+11A83;SOYOMBO LETTER KSSA;Lo;0;L;;;;;N;;;;;
+11A86;SOYOMBO CLUSTER-INITIAL LETTER RA;Lo;0;L;;;;;N;;;;;
+11A87;SOYOMBO CLUSTER-INITIAL LETTER LA;Lo;0;L;;;;;N;;;;;
+11A88;SOYOMBO CLUSTER-INITIAL LETTER SHA;Lo;0;L;;;;;N;;;;;
+11A89;SOYOMBO CLUSTER-INITIAL LETTER SA;Lo;0;L;;;;;N;;;;;
+11A8A;SOYOMBO FINAL CONSONANT SIGN G;Mn;0;NSM;;;;;N;;;;;
+11A8B;SOYOMBO FINAL CONSONANT SIGN K;Mn;0;NSM;;;;;N;;;;;
+11A8C;SOYOMBO FINAL CONSONANT SIGN NG;Mn;0;NSM;;;;;N;;;;;
+11A8D;SOYOMBO FINAL CONSONANT SIGN D;Mn;0;NSM;;;;;N;;;;;
+11A8E;SOYOMBO FINAL CONSONANT SIGN N;Mn;0;NSM;;;;;N;;;;;
+11A8F;SOYOMBO FINAL CONSONANT SIGN B;Mn;0;NSM;;;;;N;;;;;
+11A90;SOYOMBO FINAL CONSONANT SIGN M;Mn;0;NSM;;;;;N;;;;;
+11A91;SOYOMBO FINAL CONSONANT SIGN R;Mn;0;NSM;;;;;N;;;;;
+11A92;SOYOMBO FINAL CONSONANT SIGN L;Mn;0;NSM;;;;;N;;;;;
+11A93;SOYOMBO FINAL CONSONANT SIGN SH;Mn;0;NSM;;;;;N;;;;;
+11A94;SOYOMBO FINAL CONSONANT SIGN S;Mn;0;NSM;;;;;N;;;;;
+11A95;SOYOMBO FINAL CONSONANT SIGN -A;Mn;0;NSM;;;;;N;;;;;
+11A96;SOYOMBO SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+11A97;SOYOMBO SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+11A98;SOYOMBO GEMINATION MARK;Mn;0;NSM;;;;;N;;;;;
+11A99;SOYOMBO SUBJOINER;Mn;9;NSM;;;;;N;;;;;
+11A9A;SOYOMBO MARK TSHEG;Po;0;L;;;;;N;;;;;
+11A9B;SOYOMBO MARK SHAD;Po;0;L;;;;;N;;;;;
+11A9C;SOYOMBO MARK DOUBLE SHAD;Po;0;L;;;;;N;;;;;
+11A9E;SOYOMBO HEAD MARK WITH MOON AND SUN AND TRIPLE FLAME;Po;0;L;;;;;N;;;;;
+11A9F;SOYOMBO HEAD MARK WITH MOON AND SUN AND FLAME;Po;0;L;;;;;N;;;;;
+11AA0;SOYOMBO HEAD MARK WITH MOON AND SUN;Po;0;L;;;;;N;;;;;
+11AA1;SOYOMBO TERMINAL MARK-1;Po;0;L;;;;;N;;;;;
+11AA2;SOYOMBO TERMINAL MARK-2;Po;0;L;;;;;N;;;;;
+11AC0;PAU CIN HAU LETTER PA;Lo;0;L;;;;;N;;;;;
+11AC1;PAU CIN HAU LETTER KA;Lo;0;L;;;;;N;;;;;
+11AC2;PAU CIN HAU LETTER LA;Lo;0;L;;;;;N;;;;;
+11AC3;PAU CIN HAU LETTER MA;Lo;0;L;;;;;N;;;;;
+11AC4;PAU CIN HAU LETTER DA;Lo;0;L;;;;;N;;;;;
+11AC5;PAU CIN HAU LETTER ZA;Lo;0;L;;;;;N;;;;;
+11AC6;PAU CIN HAU LETTER VA;Lo;0;L;;;;;N;;;;;
+11AC7;PAU CIN HAU LETTER NGA;Lo;0;L;;;;;N;;;;;
+11AC8;PAU CIN HAU LETTER HA;Lo;0;L;;;;;N;;;;;
+11AC9;PAU CIN HAU LETTER GA;Lo;0;L;;;;;N;;;;;
+11ACA;PAU CIN HAU LETTER KHA;Lo;0;L;;;;;N;;;;;
+11ACB;PAU CIN HAU LETTER SA;Lo;0;L;;;;;N;;;;;
+11ACC;PAU CIN HAU LETTER BA;Lo;0;L;;;;;N;;;;;
+11ACD;PAU CIN HAU LETTER CA;Lo;0;L;;;;;N;;;;;
+11ACE;PAU CIN HAU LETTER TA;Lo;0;L;;;;;N;;;;;
+11ACF;PAU CIN HAU LETTER THA;Lo;0;L;;;;;N;;;;;
+11AD0;PAU CIN HAU LETTER NA;Lo;0;L;;;;;N;;;;;
+11AD1;PAU CIN HAU LETTER PHA;Lo;0;L;;;;;N;;;;;
+11AD2;PAU CIN HAU LETTER RA;Lo;0;L;;;;;N;;;;;
+11AD3;PAU CIN HAU LETTER FA;Lo;0;L;;;;;N;;;;;
+11AD4;PAU CIN HAU LETTER CHA;Lo;0;L;;;;;N;;;;;
+11AD5;PAU CIN HAU LETTER A;Lo;0;L;;;;;N;;;;;
+11AD6;PAU CIN HAU LETTER E;Lo;0;L;;;;;N;;;;;
+11AD7;PAU CIN HAU LETTER I;Lo;0;L;;;;;N;;;;;
+11AD8;PAU CIN HAU LETTER O;Lo;0;L;;;;;N;;;;;
+11AD9;PAU CIN HAU LETTER U;Lo;0;L;;;;;N;;;;;
+11ADA;PAU CIN HAU LETTER UA;Lo;0;L;;;;;N;;;;;
+11ADB;PAU CIN HAU LETTER IA;Lo;0;L;;;;;N;;;;;
+11ADC;PAU CIN HAU LETTER FINAL P;Lo;0;L;;;;;N;;;;;
+11ADD;PAU CIN HAU LETTER FINAL K;Lo;0;L;;;;;N;;;;;
+11ADE;PAU CIN HAU LETTER FINAL T;Lo;0;L;;;;;N;;;;;
+11ADF;PAU CIN HAU LETTER FINAL M;Lo;0;L;;;;;N;;;;;
+11AE0;PAU CIN HAU LETTER FINAL N;Lo;0;L;;;;;N;;;;;
+11AE1;PAU CIN HAU LETTER FINAL L;Lo;0;L;;;;;N;;;;;
+11AE2;PAU CIN HAU LETTER FINAL W;Lo;0;L;;;;;N;;;;;
+11AE3;PAU CIN HAU LETTER FINAL NG;Lo;0;L;;;;;N;;;;;
+11AE4;PAU CIN HAU LETTER FINAL Y;Lo;0;L;;;;;N;;;;;
+11AE5;PAU CIN HAU RISING TONE LONG;Lo;0;L;;;;;N;;;;;
+11AE6;PAU CIN HAU RISING TONE;Lo;0;L;;;;;N;;;;;
+11AE7;PAU CIN HAU SANDHI GLOTTAL STOP;Lo;0;L;;;;;N;;;;;
+11AE8;PAU CIN HAU RISING TONE LONG FINAL;Lo;0;L;;;;;N;;;;;
+11AE9;PAU CIN HAU RISING TONE FINAL;Lo;0;L;;;;;N;;;;;
+11AEA;PAU CIN HAU SANDHI GLOTTAL STOP FINAL;Lo;0;L;;;;;N;;;;;
+11AEB;PAU CIN HAU SANDHI TONE LONG;Lo;0;L;;;;;N;;;;;
+11AEC;PAU CIN HAU SANDHI TONE;Lo;0;L;;;;;N;;;;;
+11AED;PAU CIN HAU SANDHI TONE LONG FINAL;Lo;0;L;;;;;N;;;;;
+11AEE;PAU CIN HAU SANDHI TONE FINAL;Lo;0;L;;;;;N;;;;;
+11AEF;PAU CIN HAU MID-LEVEL TONE;Lo;0;L;;;;;N;;;;;
+11AF0;PAU CIN HAU GLOTTAL STOP VARIANT;Lo;0;L;;;;;N;;;;;
+11AF1;PAU CIN HAU MID-LEVEL TONE LONG FINAL;Lo;0;L;;;;;N;;;;;
+11AF2;PAU CIN HAU MID-LEVEL TONE FINAL;Lo;0;L;;;;;N;;;;;
+11AF3;PAU CIN HAU LOW-FALLING TONE LONG;Lo;0;L;;;;;N;;;;;
+11AF4;PAU CIN HAU LOW-FALLING TONE;Lo;0;L;;;;;N;;;;;
+11AF5;PAU CIN HAU GLOTTAL STOP;Lo;0;L;;;;;N;;;;;
+11AF6;PAU CIN HAU LOW-FALLING TONE LONG FINAL;Lo;0;L;;;;;N;;;;;
+11AF7;PAU CIN HAU LOW-FALLING TONE FINAL;Lo;0;L;;;;;N;;;;;
+11AF8;PAU CIN HAU GLOTTAL STOP FINAL;Lo;0;L;;;;;N;;;;;
+11C00;BHAIKSUKI LETTER A;Lo;0;L;;;;;N;;;;;
+11C01;BHAIKSUKI LETTER AA;Lo;0;L;;;;;N;;;;;
+11C02;BHAIKSUKI LETTER I;Lo;0;L;;;;;N;;;;;
+11C03;BHAIKSUKI LETTER II;Lo;0;L;;;;;N;;;;;
+11C04;BHAIKSUKI LETTER U;Lo;0;L;;;;;N;;;;;
+11C05;BHAIKSUKI LETTER UU;Lo;0;L;;;;;N;;;;;
+11C06;BHAIKSUKI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+11C07;BHAIKSUKI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+11C08;BHAIKSUKI LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
+11C0A;BHAIKSUKI LETTER E;Lo;0;L;;;;;N;;;;;
+11C0B;BHAIKSUKI LETTER AI;Lo;0;L;;;;;N;;;;;
+11C0C;BHAIKSUKI LETTER O;Lo;0;L;;;;;N;;;;;
+11C0D;BHAIKSUKI LETTER AU;Lo;0;L;;;;;N;;;;;
+11C0E;BHAIKSUKI LETTER KA;Lo;0;L;;;;;N;;;;;
+11C0F;BHAIKSUKI LETTER KHA;Lo;0;L;;;;;N;;;;;
+11C10;BHAIKSUKI LETTER GA;Lo;0;L;;;;;N;;;;;
+11C11;BHAIKSUKI LETTER GHA;Lo;0;L;;;;;N;;;;;
+11C12;BHAIKSUKI LETTER NGA;Lo;0;L;;;;;N;;;;;
+11C13;BHAIKSUKI LETTER CA;Lo;0;L;;;;;N;;;;;
+11C14;BHAIKSUKI LETTER CHA;Lo;0;L;;;;;N;;;;;
+11C15;BHAIKSUKI LETTER JA;Lo;0;L;;;;;N;;;;;
+11C16;BHAIKSUKI LETTER JHA;Lo;0;L;;;;;N;;;;;
+11C17;BHAIKSUKI LETTER NYA;Lo;0;L;;;;;N;;;;;
+11C18;BHAIKSUKI LETTER TTA;Lo;0;L;;;;;N;;;;;
+11C19;BHAIKSUKI LETTER TTHA;Lo;0;L;;;;;N;;;;;
+11C1A;BHAIKSUKI LETTER DDA;Lo;0;L;;;;;N;;;;;
+11C1B;BHAIKSUKI LETTER DDHA;Lo;0;L;;;;;N;;;;;
+11C1C;BHAIKSUKI LETTER NNA;Lo;0;L;;;;;N;;;;;
+11C1D;BHAIKSUKI LETTER TA;Lo;0;L;;;;;N;;;;;
+11C1E;BHAIKSUKI LETTER THA;Lo;0;L;;;;;N;;;;;
+11C1F;BHAIKSUKI LETTER DA;Lo;0;L;;;;;N;;;;;
+11C20;BHAIKSUKI LETTER DHA;Lo;0;L;;;;;N;;;;;
+11C21;BHAIKSUKI LETTER NA;Lo;0;L;;;;;N;;;;;
+11C22;BHAIKSUKI LETTER PA;Lo;0;L;;;;;N;;;;;
+11C23;BHAIKSUKI LETTER PHA;Lo;0;L;;;;;N;;;;;
+11C24;BHAIKSUKI LETTER BA;Lo;0;L;;;;;N;;;;;
+11C25;BHAIKSUKI LETTER BHA;Lo;0;L;;;;;N;;;;;
+11C26;BHAIKSUKI LETTER MA;Lo;0;L;;;;;N;;;;;
+11C27;BHAIKSUKI LETTER YA;Lo;0;L;;;;;N;;;;;
+11C28;BHAIKSUKI LETTER RA;Lo;0;L;;;;;N;;;;;
+11C29;BHAIKSUKI LETTER LA;Lo;0;L;;;;;N;;;;;
+11C2A;BHAIKSUKI LETTER VA;Lo;0;L;;;;;N;;;;;
+11C2B;BHAIKSUKI LETTER SHA;Lo;0;L;;;;;N;;;;;
+11C2C;BHAIKSUKI LETTER SSA;Lo;0;L;;;;;N;;;;;
+11C2D;BHAIKSUKI LETTER SA;Lo;0;L;;;;;N;;;;;
+11C2E;BHAIKSUKI LETTER HA;Lo;0;L;;;;;N;;;;;
+11C2F;BHAIKSUKI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+11C30;BHAIKSUKI VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+11C31;BHAIKSUKI VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;
+11C32;BHAIKSUKI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+11C33;BHAIKSUKI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+11C34;BHAIKSUKI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
+11C35;BHAIKSUKI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;
+11C36;BHAIKSUKI VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
+11C38;BHAIKSUKI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+11C39;BHAIKSUKI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
+11C3A;BHAIKSUKI VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;
+11C3B;BHAIKSUKI VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;;
+11C3C;BHAIKSUKI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
+11C3D;BHAIKSUKI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+11C3E;BHAIKSUKI SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+11C3F;BHAIKSUKI SIGN VIRAMA;Mn;9;L;;;;;N;;;;;
+11C40;BHAIKSUKI SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;
+11C41;BHAIKSUKI DANDA;Po;0;L;;;;;N;;;;;
+11C42;BHAIKSUKI DOUBLE DANDA;Po;0;L;;;;;N;;;;;
+11C43;BHAIKSUKI WORD SEPARATOR;Po;0;L;;;;;N;;;;;
+11C44;BHAIKSUKI GAP FILLER-1;Po;0;L;;;;;N;;;;;
+11C45;BHAIKSUKI GAP FILLER-2;Po;0;L;;;;;N;;;;;
+11C50;BHAIKSUKI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+11C51;BHAIKSUKI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+11C52;BHAIKSUKI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+11C53;BHAIKSUKI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+11C54;BHAIKSUKI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+11C55;BHAIKSUKI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+11C56;BHAIKSUKI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+11C57;BHAIKSUKI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+11C58;BHAIKSUKI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+11C59;BHAIKSUKI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+11C5A;BHAIKSUKI NUMBER ONE;No;0;L;;;;1;N;;;;;
+11C5B;BHAIKSUKI NUMBER TWO;No;0;L;;;;2;N;;;;;
+11C5C;BHAIKSUKI NUMBER THREE;No;0;L;;;;3;N;;;;;
+11C5D;BHAIKSUKI NUMBER FOUR;No;0;L;;;;4;N;;;;;
+11C5E;BHAIKSUKI NUMBER FIVE;No;0;L;;;;5;N;;;;;
+11C5F;BHAIKSUKI NUMBER SIX;No;0;L;;;;6;N;;;;;
+11C60;BHAIKSUKI NUMBER SEVEN;No;0;L;;;;7;N;;;;;
+11C61;BHAIKSUKI NUMBER EIGHT;No;0;L;;;;8;N;;;;;
+11C62;BHAIKSUKI NUMBER NINE;No;0;L;;;;9;N;;;;;
+11C63;BHAIKSUKI NUMBER TEN;No;0;L;;;;10;N;;;;;
+11C64;BHAIKSUKI NUMBER TWENTY;No;0;L;;;;20;N;;;;;
+11C65;BHAIKSUKI NUMBER THIRTY;No;0;L;;;;30;N;;;;;
+11C66;BHAIKSUKI NUMBER FORTY;No;0;L;;;;40;N;;;;;
+11C67;BHAIKSUKI NUMBER FIFTY;No;0;L;;;;50;N;;;;;
+11C68;BHAIKSUKI NUMBER SIXTY;No;0;L;;;;60;N;;;;;
+11C69;BHAIKSUKI NUMBER SEVENTY;No;0;L;;;;70;N;;;;;
+11C6A;BHAIKSUKI NUMBER EIGHTY;No;0;L;;;;80;N;;;;;
+11C6B;BHAIKSUKI NUMBER NINETY;No;0;L;;;;90;N;;;;;
+11C6C;BHAIKSUKI HUNDREDS UNIT MARK;No;0;L;;;;100;N;;;;;
+11C70;MARCHEN HEAD MARK;Po;0;L;;;;;N;;;;;
+11C71;MARCHEN MARK SHAD;Po;0;L;;;;;N;;;;;
+11C72;MARCHEN LETTER KA;Lo;0;L;;;;;N;;;;;
+11C73;MARCHEN LETTER KHA;Lo;0;L;;;;;N;;;;;
+11C74;MARCHEN LETTER GA;Lo;0;L;;;;;N;;;;;
+11C75;MARCHEN LETTER NGA;Lo;0;L;;;;;N;;;;;
+11C76;MARCHEN LETTER CA;Lo;0;L;;;;;N;;;;;
+11C77;MARCHEN LETTER CHA;Lo;0;L;;;;;N;;;;;
+11C78;MARCHEN LETTER JA;Lo;0;L;;;;;N;;;;;
+11C79;MARCHEN LETTER NYA;Lo;0;L;;;;;N;;;;;
+11C7A;MARCHEN LETTER TA;Lo;0;L;;;;;N;;;;;
+11C7B;MARCHEN LETTER THA;Lo;0;L;;;;;N;;;;;
+11C7C;MARCHEN LETTER DA;Lo;0;L;;;;;N;;;;;
+11C7D;MARCHEN LETTER NA;Lo;0;L;;;;;N;;;;;
+11C7E;MARCHEN LETTER PA;Lo;0;L;;;;;N;;;;;
+11C7F;MARCHEN LETTER PHA;Lo;0;L;;;;;N;;;;;
+11C80;MARCHEN LETTER BA;Lo;0;L;;;;;N;;;;;
+11C81;MARCHEN LETTER MA;Lo;0;L;;;;;N;;;;;
+11C82;MARCHEN LETTER TSA;Lo;0;L;;;;;N;;;;;
+11C83;MARCHEN LETTER TSHA;Lo;0;L;;;;;N;;;;;
+11C84;MARCHEN LETTER DZA;Lo;0;L;;;;;N;;;;;
+11C85;MARCHEN LETTER WA;Lo;0;L;;;;;N;;;;;
+11C86;MARCHEN LETTER ZHA;Lo;0;L;;;;;N;;;;;
+11C87;MARCHEN LETTER ZA;Lo;0;L;;;;;N;;;;;
+11C88;MARCHEN LETTER -A;Lo;0;L;;;;;N;;;;;
+11C89;MARCHEN LETTER YA;Lo;0;L;;;;;N;;;;;
+11C8A;MARCHEN LETTER RA;Lo;0;L;;;;;N;;;;;
+11C8B;MARCHEN LETTER LA;Lo;0;L;;;;;N;;;;;
+11C8C;MARCHEN LETTER SHA;Lo;0;L;;;;;N;;;;;
+11C8D;MARCHEN LETTER SA;Lo;0;L;;;;;N;;;;;
+11C8E;MARCHEN LETTER HA;Lo;0;L;;;;;N;;;;;
+11C8F;MARCHEN LETTER A;Lo;0;L;;;;;N;;;;;
+11C92;MARCHEN SUBJOINED LETTER KA;Mn;0;NSM;;;;;N;;;;;
+11C93;MARCHEN SUBJOINED LETTER KHA;Mn;0;NSM;;;;;N;;;;;
+11C94;MARCHEN SUBJOINED LETTER GA;Mn;0;NSM;;;;;N;;;;;
+11C95;MARCHEN SUBJOINED LETTER NGA;Mn;0;NSM;;;;;N;;;;;
+11C96;MARCHEN SUBJOINED LETTER CA;Mn;0;NSM;;;;;N;;;;;
+11C97;MARCHEN SUBJOINED LETTER CHA;Mn;0;NSM;;;;;N;;;;;
+11C98;MARCHEN SUBJOINED LETTER JA;Mn;0;NSM;;;;;N;;;;;
+11C99;MARCHEN SUBJOINED LETTER NYA;Mn;0;NSM;;;;;N;;;;;
+11C9A;MARCHEN SUBJOINED LETTER TA;Mn;0;NSM;;;;;N;;;;;
+11C9B;MARCHEN SUBJOINED LETTER THA;Mn;0;NSM;;;;;N;;;;;
+11C9C;MARCHEN SUBJOINED LETTER DA;Mn;0;NSM;;;;;N;;;;;
+11C9D;MARCHEN SUBJOINED LETTER NA;Mn;0;NSM;;;;;N;;;;;
+11C9E;MARCHEN SUBJOINED LETTER PA;Mn;0;NSM;;;;;N;;;;;
+11C9F;MARCHEN SUBJOINED LETTER PHA;Mn;0;NSM;;;;;N;;;;;
+11CA0;MARCHEN SUBJOINED LETTER BA;Mn;0;NSM;;;;;N;;;;;
+11CA1;MARCHEN SUBJOINED LETTER MA;Mn;0;NSM;;;;;N;;;;;
+11CA2;MARCHEN SUBJOINED LETTER TSA;Mn;0;NSM;;;;;N;;;;;
+11CA3;MARCHEN SUBJOINED LETTER TSHA;Mn;0;NSM;;;;;N;;;;;
+11CA4;MARCHEN SUBJOINED LETTER DZA;Mn;0;NSM;;;;;N;;;;;
+11CA5;MARCHEN SUBJOINED LETTER WA;Mn;0;NSM;;;;;N;;;;;
+11CA6;MARCHEN SUBJOINED LETTER ZHA;Mn;0;NSM;;;;;N;;;;;
+11CA7;MARCHEN SUBJOINED LETTER ZA;Mn;0;NSM;;;;;N;;;;;
+11CA9;MARCHEN SUBJOINED LETTER YA;Mc;0;L;;;;;N;;;;;
+11CAA;MARCHEN SUBJOINED LETTER RA;Mn;0;NSM;;;;;N;;;;;
+11CAB;MARCHEN SUBJOINED LETTER LA;Mn;0;NSM;;;;;N;;;;;
+11CAC;MARCHEN SUBJOINED LETTER SHA;Mn;0;NSM;;;;;N;;;;;
+11CAD;MARCHEN SUBJOINED LETTER SA;Mn;0;NSM;;;;;N;;;;;
+11CAE;MARCHEN SUBJOINED LETTER HA;Mn;0;NSM;;;;;N;;;;;
+11CAF;MARCHEN SUBJOINED LETTER A;Mn;0;NSM;;;;;N;;;;;
+11CB0;MARCHEN VOWEL SIGN AA;Mn;0;NSM;;;;;N;;;;;
+11CB1;MARCHEN VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+11CB2;MARCHEN VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+11CB3;MARCHEN VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+11CB4;MARCHEN VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
+11CB5;MARCHEN SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+11CB6;MARCHEN SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
+11D00;MASARAM GONDI LETTER A;Lo;0;L;;;;;N;;;;;
+11D01;MASARAM GONDI LETTER AA;Lo;0;L;;;;;N;;;;;
+11D02;MASARAM GONDI LETTER I;Lo;0;L;;;;;N;;;;;
+11D03;MASARAM GONDI LETTER II;Lo;0;L;;;;;N;;;;;
+11D04;MASARAM GONDI LETTER U;Lo;0;L;;;;;N;;;;;
+11D05;MASARAM GONDI LETTER UU;Lo;0;L;;;;;N;;;;;
+11D06;MASARAM GONDI LETTER E;Lo;0;L;;;;;N;;;;;
+11D08;MASARAM GONDI LETTER AI;Lo;0;L;;;;;N;;;;;
+11D09;MASARAM GONDI LETTER O;Lo;0;L;;;;;N;;;;;
+11D0B;MASARAM GONDI LETTER AU;Lo;0;L;;;;;N;;;;;
+11D0C;MASARAM GONDI LETTER KA;Lo;0;L;;;;;N;;;;;
+11D0D;MASARAM GONDI LETTER KHA;Lo;0;L;;;;;N;;;;;
+11D0E;MASARAM GONDI LETTER GA;Lo;0;L;;;;;N;;;;;
+11D0F;MASARAM GONDI LETTER GHA;Lo;0;L;;;;;N;;;;;
+11D10;MASARAM GONDI LETTER NGA;Lo;0;L;;;;;N;;;;;
+11D11;MASARAM GONDI LETTER CA;Lo;0;L;;;;;N;;;;;
+11D12;MASARAM GONDI LETTER CHA;Lo;0;L;;;;;N;;;;;
+11D13;MASARAM GONDI LETTER JA;Lo;0;L;;;;;N;;;;;
+11D14;MASARAM GONDI LETTER JHA;Lo;0;L;;;;;N;;;;;
+11D15;MASARAM GONDI LETTER NYA;Lo;0;L;;;;;N;;;;;
+11D16;MASARAM GONDI LETTER TTA;Lo;0;L;;;;;N;;;;;
+11D17;MASARAM GONDI LETTER TTHA;Lo;0;L;;;;;N;;;;;
+11D18;MASARAM GONDI LETTER DDA;Lo;0;L;;;;;N;;;;;
+11D19;MASARAM GONDI LETTER DDHA;Lo;0;L;;;;;N;;;;;
+11D1A;MASARAM GONDI LETTER NNA;Lo;0;L;;;;;N;;;;;
+11D1B;MASARAM GONDI LETTER TA;Lo;0;L;;;;;N;;;;;
+11D1C;MASARAM GONDI LETTER THA;Lo;0;L;;;;;N;;;;;
+11D1D;MASARAM GONDI LETTER DA;Lo;0;L;;;;;N;;;;;
+11D1E;MASARAM GONDI LETTER DHA;Lo;0;L;;;;;N;;;;;
+11D1F;MASARAM GONDI LETTER NA;Lo;0;L;;;;;N;;;;;
+11D20;MASARAM GONDI LETTER PA;Lo;0;L;;;;;N;;;;;
+11D21;MASARAM GONDI LETTER PHA;Lo;0;L;;;;;N;;;;;
+11D22;MASARAM GONDI LETTER BA;Lo;0;L;;;;;N;;;;;
+11D23;MASARAM GONDI LETTER BHA;Lo;0;L;;;;;N;;;;;
+11D24;MASARAM GONDI LETTER MA;Lo;0;L;;;;;N;;;;;
+11D25;MASARAM GONDI LETTER YA;Lo;0;L;;;;;N;;;;;
+11D26;MASARAM GONDI LETTER RA;Lo;0;L;;;;;N;;;;;
+11D27;MASARAM GONDI LETTER LA;Lo;0;L;;;;;N;;;;;
+11D28;MASARAM GONDI LETTER VA;Lo;0;L;;;;;N;;;;;
+11D29;MASARAM GONDI LETTER SHA;Lo;0;L;;;;;N;;;;;
+11D2A;MASARAM GONDI LETTER SSA;Lo;0;L;;;;;N;;;;;
+11D2B;MASARAM GONDI LETTER SA;Lo;0;L;;;;;N;;;;;
+11D2C;MASARAM GONDI LETTER HA;Lo;0;L;;;;;N;;;;;
+11D2D;MASARAM GONDI LETTER LLA;Lo;0;L;;;;;N;;;;;
+11D2E;MASARAM GONDI LETTER KSSA;Lo;0;L;;;;;N;;;;;
+11D2F;MASARAM GONDI LETTER JNYA;Lo;0;L;;;;;N;;;;;
+11D30;MASARAM GONDI LETTER TRA;Lo;0;L;;;;;N;;;;;
+11D31;MASARAM GONDI VOWEL SIGN AA;Mn;0;NSM;;;;;N;;;;;
+11D32;MASARAM GONDI VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+11D33;MASARAM GONDI VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;
+11D34;MASARAM GONDI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+11D35;MASARAM GONDI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+11D36;MASARAM GONDI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
+11D3A;MASARAM GONDI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+11D3C;MASARAM GONDI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
+11D3D;MASARAM GONDI VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;
+11D3F;MASARAM GONDI VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;;
+11D40;MASARAM GONDI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+11D41;MASARAM GONDI SIGN VISARGA;Mn;0;NSM;;;;;N;;;;;
+11D42;MASARAM GONDI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
+11D43;MASARAM GONDI SIGN CANDRA;Mn;0;NSM;;;;;N;;;;;
+11D44;MASARAM GONDI SIGN HALANTA;Mn;9;NSM;;;;;N;;;;;
+11D45;MASARAM GONDI VIRAMA;Mn;9;NSM;;;;;N;;;;;
+11D46;MASARAM GONDI REPHA;Lo;0;L;;;;;N;;;;;
+11D47;MASARAM GONDI RA-KARA;Mn;0;NSM;;;;;N;;;;;
+11D50;MASARAM GONDI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+11D51;MASARAM GONDI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+11D52;MASARAM GONDI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+11D53;MASARAM GONDI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+11D54;MASARAM GONDI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+11D55;MASARAM GONDI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+11D56;MASARAM GONDI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+11D57;MASARAM GONDI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+11D58;MASARAM GONDI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+11D59;MASARAM GONDI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
12000;CUNEIFORM SIGN A;Lo;0;L;;;;;N;;;;;
12001;CUNEIFORM SIGN A TIMES A;Lo;0;L;;;;;N;;;;;
12002;CUNEIFORM SIGN A TIMES BAD;Lo;0;L;;;;;N;;;;;
@@ -17878,6 +21435,49 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1236C;CUNEIFORM SIGN ZU5 TIMES A;Lo;0;L;;;;;N;;;;;
1236D;CUNEIFORM SIGN ZUBUR;Lo;0;L;;;;;N;;;;;
1236E;CUNEIFORM SIGN ZUM;Lo;0;L;;;;;N;;;;;
+1236F;CUNEIFORM SIGN KAP ELAMITE;Lo;0;L;;;;;N;;;;;
+12370;CUNEIFORM SIGN AB TIMES NUN;Lo;0;L;;;;;N;;;;;
+12371;CUNEIFORM SIGN AB2 TIMES A;Lo;0;L;;;;;N;;;;;
+12372;CUNEIFORM SIGN AMAR TIMES KUG;Lo;0;L;;;;;N;;;;;
+12373;CUNEIFORM SIGN DAG KISIM5 TIMES U2 PLUS MASH;Lo;0;L;;;;;N;;;;;
+12374;CUNEIFORM SIGN DAG3;Lo;0;L;;;;;N;;;;;
+12375;CUNEIFORM SIGN DISH PLUS SHU;Lo;0;L;;;;;N;;;;;
+12376;CUNEIFORM SIGN DUB TIMES SHE;Lo;0;L;;;;;N;;;;;
+12377;CUNEIFORM SIGN EZEN TIMES GUD;Lo;0;L;;;;;N;;;;;
+12378;CUNEIFORM SIGN EZEN TIMES SHE;Lo;0;L;;;;;N;;;;;
+12379;CUNEIFORM SIGN GA2 TIMES AN PLUS KAK PLUS A;Lo;0;L;;;;;N;;;;;
+1237A;CUNEIFORM SIGN GA2 TIMES ASH2;Lo;0;L;;;;;N;;;;;
+1237B;CUNEIFORM SIGN GE22;Lo;0;L;;;;;N;;;;;
+1237C;CUNEIFORM SIGN GIG;Lo;0;L;;;;;N;;;;;
+1237D;CUNEIFORM SIGN HUSH;Lo;0;L;;;;;N;;;;;
+1237E;CUNEIFORM SIGN KA TIMES ANSHE;Lo;0;L;;;;;N;;;;;
+1237F;CUNEIFORM SIGN KA TIMES ASH3;Lo;0;L;;;;;N;;;;;
+12380;CUNEIFORM SIGN KA TIMES GISH;Lo;0;L;;;;;N;;;;;
+12381;CUNEIFORM SIGN KA TIMES GUD;Lo;0;L;;;;;N;;;;;
+12382;CUNEIFORM SIGN KA TIMES HI TIMES ASH2;Lo;0;L;;;;;N;;;;;
+12383;CUNEIFORM SIGN KA TIMES LUM;Lo;0;L;;;;;N;;;;;
+12384;CUNEIFORM SIGN KA TIMES PA;Lo;0;L;;;;;N;;;;;
+12385;CUNEIFORM SIGN KA TIMES SHUL;Lo;0;L;;;;;N;;;;;
+12386;CUNEIFORM SIGN KA TIMES TU;Lo;0;L;;;;;N;;;;;
+12387;CUNEIFORM SIGN KA TIMES UR2;Lo;0;L;;;;;N;;;;;
+12388;CUNEIFORM SIGN LAGAB TIMES GI;Lo;0;L;;;;;N;;;;;
+12389;CUNEIFORM SIGN LU2 SHESHIG TIMES BAD;Lo;0;L;;;;;N;;;;;
+1238A;CUNEIFORM SIGN LU2 TIMES ESH2 PLUS LAL;Lo;0;L;;;;;N;;;;;
+1238B;CUNEIFORM SIGN LU2 TIMES SHU;Lo;0;L;;;;;N;;;;;
+1238C;CUNEIFORM SIGN MESH;Lo;0;L;;;;;N;;;;;
+1238D;CUNEIFORM SIGN MUSH3 TIMES ZA;Lo;0;L;;;;;N;;;;;
+1238E;CUNEIFORM SIGN NA4;Lo;0;L;;;;;N;;;;;
+1238F;CUNEIFORM SIGN NIN;Lo;0;L;;;;;N;;;;;
+12390;CUNEIFORM SIGN NIN9;Lo;0;L;;;;;N;;;;;
+12391;CUNEIFORM SIGN NINDA2 TIMES BAL;Lo;0;L;;;;;N;;;;;
+12392;CUNEIFORM SIGN NINDA2 TIMES GI;Lo;0;L;;;;;N;;;;;
+12393;CUNEIFORM SIGN NU11 ROTATED NINETY DEGREES;Lo;0;L;;;;;N;;;;;
+12394;CUNEIFORM SIGN PESH2 ASTERISK;Lo;0;L;;;;;N;;;;;
+12395;CUNEIFORM SIGN PIR2;Lo;0;L;;;;;N;;;;;
+12396;CUNEIFORM SIGN SAG TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;
+12397;CUNEIFORM SIGN TI2;Lo;0;L;;;;;N;;;;;
+12398;CUNEIFORM SIGN UM TIMES ME;Lo;0;L;;;;;N;;;;;
+12399;CUNEIFORM SIGN U U;Lo;0;L;;;;;N;;;;;
12400;CUNEIFORM NUMERIC SIGN TWO ASH;Nl;0;L;;;;2;N;;;;;
12401;CUNEIFORM NUMERIC SIGN THREE ASH;Nl;0;L;;;;3;N;;;;;
12402;CUNEIFORM NUMERIC SIGN FOUR ASH;Nl;0;L;;;;4;N;;;;;
@@ -17928,8 +21528,8 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1242F;CUNEIFORM NUMERIC SIGN THREE SHARU VARIANT FORM;Nl;0;L;;;;3;N;;;;;
12430;CUNEIFORM NUMERIC SIGN FOUR SHARU;Nl;0;L;;;;4;N;;;;;
12431;CUNEIFORM NUMERIC SIGN FIVE SHARU;Nl;0;L;;;;5;N;;;;;
-12432;CUNEIFORM NUMERIC SIGN SHAR2 TIMES GAL PLUS DISH;Nl;0;L;;;;;N;;;;;
-12433;CUNEIFORM NUMERIC SIGN SHAR2 TIMES GAL PLUS MIN;Nl;0;L;;;;;N;;;;;
+12432;CUNEIFORM NUMERIC SIGN SHAR2 TIMES GAL PLUS DISH;Nl;0;L;;;;216000;N;;;;;
+12433;CUNEIFORM NUMERIC SIGN SHAR2 TIMES GAL PLUS MIN;Nl;0;L;;;;432000;N;;;;;
12434;CUNEIFORM NUMERIC SIGN ONE BURU;Nl;0;L;;;;1;N;;;;;
12435;CUNEIFORM NUMERIC SIGN TWO BURU;Nl;0;L;;;;2;N;;;;;
12436;CUNEIFORM NUMERIC SIGN THREE BURU;Nl;0;L;;;;3;N;;;;;
@@ -17964,8 +21564,8 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
12453;CUNEIFORM NUMERIC SIGN FOUR BAN2 VARIANT FORM;Nl;0;L;;;;4;N;;;;;
12454;CUNEIFORM NUMERIC SIGN FIVE BAN2;Nl;0;L;;;;5;N;;;;;
12455;CUNEIFORM NUMERIC SIGN FIVE BAN2 VARIANT FORM;Nl;0;L;;;;5;N;;;;;
-12456;CUNEIFORM NUMERIC SIGN NIGIDAMIN;Nl;0;L;;;;;N;;;;;
-12457;CUNEIFORM NUMERIC SIGN NIGIDAESH;Nl;0;L;;;;;N;;;;;
+12456;CUNEIFORM NUMERIC SIGN NIGIDAMIN;Nl;0;L;;;;2;N;;;;;
+12457;CUNEIFORM NUMERIC SIGN NIGIDAESH;Nl;0;L;;;;3;N;;;;;
12458;CUNEIFORM NUMERIC SIGN ONE ESHE3;Nl;0;L;;;;1;N;;;;;
12459;CUNEIFORM NUMERIC SIGN TWO ESHE3;Nl;0;L;;;;2;N;;;;;
1245A;CUNEIFORM NUMERIC SIGN ONE THIRD DISH;Nl;0;L;;;;1/3;N;;;;;
@@ -17977,10 +21577,219 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
12460;CUNEIFORM NUMERIC SIGN ONE QUARTER ASH;Nl;0;L;;;;1/4;N;;;;;
12461;CUNEIFORM NUMERIC SIGN OLD ASSYRIAN ONE SIXTH;Nl;0;L;;;;1/6;N;;;;;
12462;CUNEIFORM NUMERIC SIGN OLD ASSYRIAN ONE QUARTER;Nl;0;L;;;;1/4;N;;;;;
+12463;CUNEIFORM NUMERIC SIGN ONE QUARTER GUR;Nl;0;L;;;;1/4;N;;;;;
+12464;CUNEIFORM NUMERIC SIGN ONE HALF GUR;Nl;0;L;;;;1/2;N;;;;;
+12465;CUNEIFORM NUMERIC SIGN ELAMITE ONE THIRD;Nl;0;L;;;;1/3;N;;;;;
+12466;CUNEIFORM NUMERIC SIGN ELAMITE TWO THIRDS;Nl;0;L;;;;2/3;N;;;;;
+12467;CUNEIFORM NUMERIC SIGN ELAMITE FORTY;Nl;0;L;;;;40;N;;;;;
+12468;CUNEIFORM NUMERIC SIGN ELAMITE FIFTY;Nl;0;L;;;;50;N;;;;;
+12469;CUNEIFORM NUMERIC SIGN FOUR U VARIANT FORM;Nl;0;L;;;;4;N;;;;;
+1246A;CUNEIFORM NUMERIC SIGN FIVE U VARIANT FORM;Nl;0;L;;;;5;N;;;;;
+1246B;CUNEIFORM NUMERIC SIGN SIX U VARIANT FORM;Nl;0;L;;;;6;N;;;;;
+1246C;CUNEIFORM NUMERIC SIGN SEVEN U VARIANT FORM;Nl;0;L;;;;7;N;;;;;
+1246D;CUNEIFORM NUMERIC SIGN EIGHT U VARIANT FORM;Nl;0;L;;;;8;N;;;;;
+1246E;CUNEIFORM NUMERIC SIGN NINE U VARIANT FORM;Nl;0;L;;;;9;N;;;;;
12470;CUNEIFORM PUNCTUATION SIGN OLD ASSYRIAN WORD DIVIDER;Po;0;L;;;;;N;;;;;
12471;CUNEIFORM PUNCTUATION SIGN VERTICAL COLON;Po;0;L;;;;;N;;;;;
12472;CUNEIFORM PUNCTUATION SIGN DIAGONAL COLON;Po;0;L;;;;;N;;;;;
12473;CUNEIFORM PUNCTUATION SIGN DIAGONAL TRICOLON;Po;0;L;;;;;N;;;;;
+12474;CUNEIFORM PUNCTUATION SIGN DIAGONAL QUADCOLON;Po;0;L;;;;;N;;;;;
+12480;CUNEIFORM SIGN AB TIMES NUN TENU;Lo;0;L;;;;;N;;;;;
+12481;CUNEIFORM SIGN AB TIMES SHU2;Lo;0;L;;;;;N;;;;;
+12482;CUNEIFORM SIGN AD TIMES ESH2;Lo;0;L;;;;;N;;;;;
+12483;CUNEIFORM SIGN BAD TIMES DISH TENU;Lo;0;L;;;;;N;;;;;
+12484;CUNEIFORM SIGN BAHAR2 TIMES AB2;Lo;0;L;;;;;N;;;;;
+12485;CUNEIFORM SIGN BAHAR2 TIMES NI;Lo;0;L;;;;;N;;;;;
+12486;CUNEIFORM SIGN BAHAR2 TIMES ZA;Lo;0;L;;;;;N;;;;;
+12487;CUNEIFORM SIGN BU OVER BU TIMES NA2;Lo;0;L;;;;;N;;;;;
+12488;CUNEIFORM SIGN DA TIMES TAK4;Lo;0;L;;;;;N;;;;;
+12489;CUNEIFORM SIGN DAG TIMES KUR;Lo;0;L;;;;;N;;;;;
+1248A;CUNEIFORM SIGN DIM TIMES IGI;Lo;0;L;;;;;N;;;;;
+1248B;CUNEIFORM SIGN DIM TIMES U U U;Lo;0;L;;;;;N;;;;;
+1248C;CUNEIFORM SIGN DIM2 TIMES UD;Lo;0;L;;;;;N;;;;;
+1248D;CUNEIFORM SIGN DUG TIMES ANSHE;Lo;0;L;;;;;N;;;;;
+1248E;CUNEIFORM SIGN DUG TIMES ASH;Lo;0;L;;;;;N;;;;;
+1248F;CUNEIFORM SIGN DUG TIMES ASH AT LEFT;Lo;0;L;;;;;N;;;;;
+12490;CUNEIFORM SIGN DUG TIMES DIN;Lo;0;L;;;;;N;;;;;
+12491;CUNEIFORM SIGN DUG TIMES DUN;Lo;0;L;;;;;N;;;;;
+12492;CUNEIFORM SIGN DUG TIMES ERIN2;Lo;0;L;;;;;N;;;;;
+12493;CUNEIFORM SIGN DUG TIMES GA;Lo;0;L;;;;;N;;;;;
+12494;CUNEIFORM SIGN DUG TIMES GI;Lo;0;L;;;;;N;;;;;
+12495;CUNEIFORM SIGN DUG TIMES GIR2 GUNU;Lo;0;L;;;;;N;;;;;
+12496;CUNEIFORM SIGN DUG TIMES GISH;Lo;0;L;;;;;N;;;;;
+12497;CUNEIFORM SIGN DUG TIMES HA;Lo;0;L;;;;;N;;;;;
+12498;CUNEIFORM SIGN DUG TIMES HI;Lo;0;L;;;;;N;;;;;
+12499;CUNEIFORM SIGN DUG TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;
+1249A;CUNEIFORM SIGN DUG TIMES KASKAL;Lo;0;L;;;;;N;;;;;
+1249B;CUNEIFORM SIGN DUG TIMES KUR;Lo;0;L;;;;;N;;;;;
+1249C;CUNEIFORM SIGN DUG TIMES KUSHU2;Lo;0;L;;;;;N;;;;;
+1249D;CUNEIFORM SIGN DUG TIMES KUSHU2 PLUS KASKAL;Lo;0;L;;;;;N;;;;;
+1249E;CUNEIFORM SIGN DUG TIMES LAK-020;Lo;0;L;;;;;N;;;;;
+1249F;CUNEIFORM SIGN DUG TIMES LAM;Lo;0;L;;;;;N;;;;;
+124A0;CUNEIFORM SIGN DUG TIMES LAM TIMES KUR;Lo;0;L;;;;;N;;;;;
+124A1;CUNEIFORM SIGN DUG TIMES LUH PLUS GISH;Lo;0;L;;;;;N;;;;;
+124A2;CUNEIFORM SIGN DUG TIMES MASH;Lo;0;L;;;;;N;;;;;
+124A3;CUNEIFORM SIGN DUG TIMES MES;Lo;0;L;;;;;N;;;;;
+124A4;CUNEIFORM SIGN DUG TIMES MI;Lo;0;L;;;;;N;;;;;
+124A5;CUNEIFORM SIGN DUG TIMES NI;Lo;0;L;;;;;N;;;;;
+124A6;CUNEIFORM SIGN DUG TIMES PI;Lo;0;L;;;;;N;;;;;
+124A7;CUNEIFORM SIGN DUG TIMES SHE;Lo;0;L;;;;;N;;;;;
+124A8;CUNEIFORM SIGN DUG TIMES SI GUNU;Lo;0;L;;;;;N;;;;;
+124A9;CUNEIFORM SIGN E2 TIMES KUR;Lo;0;L;;;;;N;;;;;
+124AA;CUNEIFORM SIGN E2 TIMES PAP;Lo;0;L;;;;;N;;;;;
+124AB;CUNEIFORM SIGN ERIN2 X;Lo;0;L;;;;;N;;;;;
+124AC;CUNEIFORM SIGN ESH2 CROSSING ESH2;Lo;0;L;;;;;N;;;;;
+124AD;CUNEIFORM SIGN EZEN SHESHIG TIMES ASH;Lo;0;L;;;;;N;;;;;
+124AE;CUNEIFORM SIGN EZEN SHESHIG TIMES HI;Lo;0;L;;;;;N;;;;;
+124AF;CUNEIFORM SIGN EZEN SHESHIG TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;
+124B0;CUNEIFORM SIGN EZEN SHESHIG TIMES LA;Lo;0;L;;;;;N;;;;;
+124B1;CUNEIFORM SIGN EZEN SHESHIG TIMES LAL;Lo;0;L;;;;;N;;;;;
+124B2;CUNEIFORM SIGN EZEN SHESHIG TIMES ME;Lo;0;L;;;;;N;;;;;
+124B3;CUNEIFORM SIGN EZEN SHESHIG TIMES MES;Lo;0;L;;;;;N;;;;;
+124B4;CUNEIFORM SIGN EZEN SHESHIG TIMES SU;Lo;0;L;;;;;N;;;;;
+124B5;CUNEIFORM SIGN EZEN TIMES SU;Lo;0;L;;;;;N;;;;;
+124B6;CUNEIFORM SIGN GA2 TIMES BAHAR2;Lo;0;L;;;;;N;;;;;
+124B7;CUNEIFORM SIGN GA2 TIMES DIM GUNU;Lo;0;L;;;;;N;;;;;
+124B8;CUNEIFORM SIGN GA2 TIMES DUG TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;
+124B9;CUNEIFORM SIGN GA2 TIMES DUG TIMES KASKAL;Lo;0;L;;;;;N;;;;;
+124BA;CUNEIFORM SIGN GA2 TIMES EREN;Lo;0;L;;;;;N;;;;;
+124BB;CUNEIFORM SIGN GA2 TIMES GA;Lo;0;L;;;;;N;;;;;
+124BC;CUNEIFORM SIGN GA2 TIMES GAR PLUS DI;Lo;0;L;;;;;N;;;;;
+124BD;CUNEIFORM SIGN GA2 TIMES GAR PLUS NE;Lo;0;L;;;;;N;;;;;
+124BE;CUNEIFORM SIGN GA2 TIMES HA PLUS A;Lo;0;L;;;;;N;;;;;
+124BF;CUNEIFORM SIGN GA2 TIMES KUSHU2 PLUS KASKAL;Lo;0;L;;;;;N;;;;;
+124C0;CUNEIFORM SIGN GA2 TIMES LAM;Lo;0;L;;;;;N;;;;;
+124C1;CUNEIFORM SIGN GA2 TIMES LAM TIMES KUR;Lo;0;L;;;;;N;;;;;
+124C2;CUNEIFORM SIGN GA2 TIMES LUH;Lo;0;L;;;;;N;;;;;
+124C3;CUNEIFORM SIGN GA2 TIMES MUSH;Lo;0;L;;;;;N;;;;;
+124C4;CUNEIFORM SIGN GA2 TIMES NE;Lo;0;L;;;;;N;;;;;
+124C5;CUNEIFORM SIGN GA2 TIMES NE PLUS E2;Lo;0;L;;;;;N;;;;;
+124C6;CUNEIFORM SIGN GA2 TIMES NE PLUS GI;Lo;0;L;;;;;N;;;;;
+124C7;CUNEIFORM SIGN GA2 TIMES SHIM;Lo;0;L;;;;;N;;;;;
+124C8;CUNEIFORM SIGN GA2 TIMES ZIZ2;Lo;0;L;;;;;N;;;;;
+124C9;CUNEIFORM SIGN GABA ROTATED NINETY DEGREES;Lo;0;L;;;;;N;;;;;
+124CA;CUNEIFORM SIGN GESHTIN TIMES U;Lo;0;L;;;;;N;;;;;
+124CB;CUNEIFORM SIGN GISH TIMES GISH CROSSING GISH;Lo;0;L;;;;;N;;;;;
+124CC;CUNEIFORM SIGN GU2 TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;
+124CD;CUNEIFORM SIGN GUD PLUS GISH TIMES TAK4;Lo;0;L;;;;;N;;;;;
+124CE;CUNEIFORM SIGN HA TENU GUNU;Lo;0;L;;;;;N;;;;;
+124CF;CUNEIFORM SIGN HI TIMES ASH OVER HI TIMES ASH;Lo;0;L;;;;;N;;;;;
+124D0;CUNEIFORM SIGN KA TIMES BU;Lo;0;L;;;;;N;;;;;
+124D1;CUNEIFORM SIGN KA TIMES KA;Lo;0;L;;;;;N;;;;;
+124D2;CUNEIFORM SIGN KA TIMES U U U;Lo;0;L;;;;;N;;;;;
+124D3;CUNEIFORM SIGN KA TIMES UR;Lo;0;L;;;;;N;;;;;
+124D4;CUNEIFORM SIGN LAGAB TIMES ZU OVER ZU;Lo;0;L;;;;;N;;;;;
+124D5;CUNEIFORM SIGN LAK-003;Lo;0;L;;;;;N;;;;;
+124D6;CUNEIFORM SIGN LAK-021;Lo;0;L;;;;;N;;;;;
+124D7;CUNEIFORM SIGN LAK-025;Lo;0;L;;;;;N;;;;;
+124D8;CUNEIFORM SIGN LAK-030;Lo;0;L;;;;;N;;;;;
+124D9;CUNEIFORM SIGN LAK-050;Lo;0;L;;;;;N;;;;;
+124DA;CUNEIFORM SIGN LAK-051;Lo;0;L;;;;;N;;;;;
+124DB;CUNEIFORM SIGN LAK-062;Lo;0;L;;;;;N;;;;;
+124DC;CUNEIFORM SIGN LAK-079 OVER LAK-079 GUNU;Lo;0;L;;;;;N;;;;;
+124DD;CUNEIFORM SIGN LAK-080;Lo;0;L;;;;;N;;;;;
+124DE;CUNEIFORM SIGN LAK-081 OVER LAK-081;Lo;0;L;;;;;N;;;;;
+124DF;CUNEIFORM SIGN LAK-092;Lo;0;L;;;;;N;;;;;
+124E0;CUNEIFORM SIGN LAK-130;Lo;0;L;;;;;N;;;;;
+124E1;CUNEIFORM SIGN LAK-142;Lo;0;L;;;;;N;;;;;
+124E2;CUNEIFORM SIGN LAK-210;Lo;0;L;;;;;N;;;;;
+124E3;CUNEIFORM SIGN LAK-219;Lo;0;L;;;;;N;;;;;
+124E4;CUNEIFORM SIGN LAK-220;Lo;0;L;;;;;N;;;;;
+124E5;CUNEIFORM SIGN LAK-225;Lo;0;L;;;;;N;;;;;
+124E6;CUNEIFORM SIGN LAK-228;Lo;0;L;;;;;N;;;;;
+124E7;CUNEIFORM SIGN LAK-238;Lo;0;L;;;;;N;;;;;
+124E8;CUNEIFORM SIGN LAK-265;Lo;0;L;;;;;N;;;;;
+124E9;CUNEIFORM SIGN LAK-266;Lo;0;L;;;;;N;;;;;
+124EA;CUNEIFORM SIGN LAK-343;Lo;0;L;;;;;N;;;;;
+124EB;CUNEIFORM SIGN LAK-347;Lo;0;L;;;;;N;;;;;
+124EC;CUNEIFORM SIGN LAK-348;Lo;0;L;;;;;N;;;;;
+124ED;CUNEIFORM SIGN LAK-383;Lo;0;L;;;;;N;;;;;
+124EE;CUNEIFORM SIGN LAK-384;Lo;0;L;;;;;N;;;;;
+124EF;CUNEIFORM SIGN LAK-390;Lo;0;L;;;;;N;;;;;
+124F0;CUNEIFORM SIGN LAK-441;Lo;0;L;;;;;N;;;;;
+124F1;CUNEIFORM SIGN LAK-449;Lo;0;L;;;;;N;;;;;
+124F2;CUNEIFORM SIGN LAK-449 TIMES GU;Lo;0;L;;;;;N;;;;;
+124F3;CUNEIFORM SIGN LAK-449 TIMES IGI;Lo;0;L;;;;;N;;;;;
+124F4;CUNEIFORM SIGN LAK-449 TIMES PAP PLUS LU3;Lo;0;L;;;;;N;;;;;
+124F5;CUNEIFORM SIGN LAK-449 TIMES PAP PLUS PAP PLUS LU3;Lo;0;L;;;;;N;;;;;
+124F6;CUNEIFORM SIGN LAK-449 TIMES U2 PLUS BA;Lo;0;L;;;;;N;;;;;
+124F7;CUNEIFORM SIGN LAK-450;Lo;0;L;;;;;N;;;;;
+124F8;CUNEIFORM SIGN LAK-457;Lo;0;L;;;;;N;;;;;
+124F9;CUNEIFORM SIGN LAK-470;Lo;0;L;;;;;N;;;;;
+124FA;CUNEIFORM SIGN LAK-483;Lo;0;L;;;;;N;;;;;
+124FB;CUNEIFORM SIGN LAK-490;Lo;0;L;;;;;N;;;;;
+124FC;CUNEIFORM SIGN LAK-492;Lo;0;L;;;;;N;;;;;
+124FD;CUNEIFORM SIGN LAK-493;Lo;0;L;;;;;N;;;;;
+124FE;CUNEIFORM SIGN LAK-495;Lo;0;L;;;;;N;;;;;
+124FF;CUNEIFORM SIGN LAK-550;Lo;0;L;;;;;N;;;;;
+12500;CUNEIFORM SIGN LAK-608;Lo;0;L;;;;;N;;;;;
+12501;CUNEIFORM SIGN LAK-617;Lo;0;L;;;;;N;;;;;
+12502;CUNEIFORM SIGN LAK-617 TIMES ASH;Lo;0;L;;;;;N;;;;;
+12503;CUNEIFORM SIGN LAK-617 TIMES BAD;Lo;0;L;;;;;N;;;;;
+12504;CUNEIFORM SIGN LAK-617 TIMES DUN3 GUNU GUNU;Lo;0;L;;;;;N;;;;;
+12505;CUNEIFORM SIGN LAK-617 TIMES KU3;Lo;0;L;;;;;N;;;;;
+12506;CUNEIFORM SIGN LAK-617 TIMES LA;Lo;0;L;;;;;N;;;;;
+12507;CUNEIFORM SIGN LAK-617 TIMES TAR;Lo;0;L;;;;;N;;;;;
+12508;CUNEIFORM SIGN LAK-617 TIMES TE;Lo;0;L;;;;;N;;;;;
+12509;CUNEIFORM SIGN LAK-617 TIMES U2;Lo;0;L;;;;;N;;;;;
+1250A;CUNEIFORM SIGN LAK-617 TIMES UD;Lo;0;L;;;;;N;;;;;
+1250B;CUNEIFORM SIGN LAK-617 TIMES URUDA;Lo;0;L;;;;;N;;;;;
+1250C;CUNEIFORM SIGN LAK-636;Lo;0;L;;;;;N;;;;;
+1250D;CUNEIFORM SIGN LAK-648;Lo;0;L;;;;;N;;;;;
+1250E;CUNEIFORM SIGN LAK-648 TIMES DUB;Lo;0;L;;;;;N;;;;;
+1250F;CUNEIFORM SIGN LAK-648 TIMES GA;Lo;0;L;;;;;N;;;;;
+12510;CUNEIFORM SIGN LAK-648 TIMES IGI;Lo;0;L;;;;;N;;;;;
+12511;CUNEIFORM SIGN LAK-648 TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;
+12512;CUNEIFORM SIGN LAK-648 TIMES NI;Lo;0;L;;;;;N;;;;;
+12513;CUNEIFORM SIGN LAK-648 TIMES PAP PLUS PAP PLUS LU3;Lo;0;L;;;;;N;;;;;
+12514;CUNEIFORM SIGN LAK-648 TIMES SHESH PLUS KI;Lo;0;L;;;;;N;;;;;
+12515;CUNEIFORM SIGN LAK-648 TIMES UD;Lo;0;L;;;;;N;;;;;
+12516;CUNEIFORM SIGN LAK-648 TIMES URUDA;Lo;0;L;;;;;N;;;;;
+12517;CUNEIFORM SIGN LAK-724;Lo;0;L;;;;;N;;;;;
+12518;CUNEIFORM SIGN LAK-749;Lo;0;L;;;;;N;;;;;
+12519;CUNEIFORM SIGN LU2 GUNU TIMES ASH;Lo;0;L;;;;;N;;;;;
+1251A;CUNEIFORM SIGN LU2 TIMES DISH;Lo;0;L;;;;;N;;;;;
+1251B;CUNEIFORM SIGN LU2 TIMES HAL;Lo;0;L;;;;;N;;;;;
+1251C;CUNEIFORM SIGN LU2 TIMES PAP;Lo;0;L;;;;;N;;;;;
+1251D;CUNEIFORM SIGN LU2 TIMES PAP PLUS PAP PLUS LU3;Lo;0;L;;;;;N;;;;;
+1251E;CUNEIFORM SIGN LU2 TIMES TAK4;Lo;0;L;;;;;N;;;;;
+1251F;CUNEIFORM SIGN MI PLUS ZA7;Lo;0;L;;;;;N;;;;;
+12520;CUNEIFORM SIGN MUSH OVER MUSH TIMES GA;Lo;0;L;;;;;N;;;;;
+12521;CUNEIFORM SIGN MUSH OVER MUSH TIMES KAK;Lo;0;L;;;;;N;;;;;
+12522;CUNEIFORM SIGN NINDA2 TIMES DIM GUNU;Lo;0;L;;;;;N;;;;;
+12523;CUNEIFORM SIGN NINDA2 TIMES GISH;Lo;0;L;;;;;N;;;;;
+12524;CUNEIFORM SIGN NINDA2 TIMES GUL;Lo;0;L;;;;;N;;;;;
+12525;CUNEIFORM SIGN NINDA2 TIMES HI;Lo;0;L;;;;;N;;;;;
+12526;CUNEIFORM SIGN NINDA2 TIMES KESH2;Lo;0;L;;;;;N;;;;;
+12527;CUNEIFORM SIGN NINDA2 TIMES LAK-050;Lo;0;L;;;;;N;;;;;
+12528;CUNEIFORM SIGN NINDA2 TIMES MASH;Lo;0;L;;;;;N;;;;;
+12529;CUNEIFORM SIGN NINDA2 TIMES PAP PLUS PAP;Lo;0;L;;;;;N;;;;;
+1252A;CUNEIFORM SIGN NINDA2 TIMES U;Lo;0;L;;;;;N;;;;;
+1252B;CUNEIFORM SIGN NINDA2 TIMES U PLUS U;Lo;0;L;;;;;N;;;;;
+1252C;CUNEIFORM SIGN NINDA2 TIMES URUDA;Lo;0;L;;;;;N;;;;;
+1252D;CUNEIFORM SIGN SAG GUNU TIMES HA;Lo;0;L;;;;;N;;;;;
+1252E;CUNEIFORM SIGN SAG TIMES EN;Lo;0;L;;;;;N;;;;;
+1252F;CUNEIFORM SIGN SAG TIMES SHE AT LEFT;Lo;0;L;;;;;N;;;;;
+12530;CUNEIFORM SIGN SAG TIMES TAK4;Lo;0;L;;;;;N;;;;;
+12531;CUNEIFORM SIGN SHA6 TENU;Lo;0;L;;;;;N;;;;;
+12532;CUNEIFORM SIGN SHE OVER SHE;Lo;0;L;;;;;N;;;;;
+12533;CUNEIFORM SIGN SHE PLUS HUB2;Lo;0;L;;;;;N;;;;;
+12534;CUNEIFORM SIGN SHE PLUS NAM2;Lo;0;L;;;;;N;;;;;
+12535;CUNEIFORM SIGN SHE PLUS SAR;Lo;0;L;;;;;N;;;;;
+12536;CUNEIFORM SIGN SHU2 PLUS DUG TIMES NI;Lo;0;L;;;;;N;;;;;
+12537;CUNEIFORM SIGN SHU2 PLUS E2 TIMES AN;Lo;0;L;;;;;N;;;;;
+12538;CUNEIFORM SIGN SI TIMES TAK4;Lo;0;L;;;;;N;;;;;
+12539;CUNEIFORM SIGN TAK4 PLUS SAG;Lo;0;L;;;;;N;;;;;
+1253A;CUNEIFORM SIGN TUM TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;
+1253B;CUNEIFORM SIGN TUM TIMES THREE DISH;Lo;0;L;;;;;N;;;;;
+1253C;CUNEIFORM SIGN UR2 INVERTED;Lo;0;L;;;;;N;;;;;
+1253D;CUNEIFORM SIGN UR2 TIMES UD;Lo;0;L;;;;;N;;;;;
+1253E;CUNEIFORM SIGN URU TIMES DARA3;Lo;0;L;;;;;N;;;;;
+1253F;CUNEIFORM SIGN URU TIMES LAK-668;Lo;0;L;;;;;N;;;;;
+12540;CUNEIFORM SIGN URU TIMES LU3;Lo;0;L;;;;;N;;;;;
+12541;CUNEIFORM SIGN ZA7;Lo;0;L;;;;;N;;;;;
+12542;CUNEIFORM SIGN ZU OVER ZU PLUS SAR;Lo;0;L;;;;;N;;;;;
+12543;CUNEIFORM SIGN ZU5 TIMES THREE DISH TENU;Lo;0;L;;;;;N;;;;;
13000;EGYPTIAN HIEROGLYPH A001;Lo;0;L;;;;;N;;;;;
13001;EGYPTIAN HIEROGLYPH A002;Lo;0;L;;;;;N;;;;;
13002;EGYPTIAN HIEROGLYPH A003;Lo;0;L;;;;;N;;;;;
@@ -19052,6 +22861,3086 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1342C;EGYPTIAN HIEROGLYPH AA030;Lo;0;L;;;;;N;;;;;
1342D;EGYPTIAN HIEROGLYPH AA031;Lo;0;L;;;;;N;;;;;
1342E;EGYPTIAN HIEROGLYPH AA032;Lo;0;L;;;;;N;;;;;
+14400;ANATOLIAN HIEROGLYPH A001;Lo;0;L;;;;;N;;;;;
+14401;ANATOLIAN HIEROGLYPH A002;Lo;0;L;;;;;N;;;;;
+14402;ANATOLIAN HIEROGLYPH A003;Lo;0;L;;;;;N;;;;;
+14403;ANATOLIAN HIEROGLYPH A004;Lo;0;L;;;;;N;;;;;
+14404;ANATOLIAN HIEROGLYPH A005;Lo;0;L;;;;;N;;;;;
+14405;ANATOLIAN HIEROGLYPH A006;Lo;0;L;;;;;N;;;;;
+14406;ANATOLIAN HIEROGLYPH A007;Lo;0;L;;;;;N;;;;;
+14407;ANATOLIAN HIEROGLYPH A008;Lo;0;L;;;;;N;;;;;
+14408;ANATOLIAN HIEROGLYPH A009;Lo;0;L;;;;;N;;;;;
+14409;ANATOLIAN HIEROGLYPH A010;Lo;0;L;;;;;N;;;;;
+1440A;ANATOLIAN HIEROGLYPH A010A;Lo;0;L;;;;;N;;;;;
+1440B;ANATOLIAN HIEROGLYPH A011;Lo;0;L;;;;;N;;;;;
+1440C;ANATOLIAN HIEROGLYPH A012;Lo;0;L;;;;;N;;;;;
+1440D;ANATOLIAN HIEROGLYPH A013;Lo;0;L;;;;;N;;;;;
+1440E;ANATOLIAN HIEROGLYPH A014;Lo;0;L;;;;;N;;;;;
+1440F;ANATOLIAN HIEROGLYPH A015;Lo;0;L;;;;;N;;;;;
+14410;ANATOLIAN HIEROGLYPH A016;Lo;0;L;;;;;N;;;;;
+14411;ANATOLIAN HIEROGLYPH A017;Lo;0;L;;;;;N;;;;;
+14412;ANATOLIAN HIEROGLYPH A018;Lo;0;L;;;;;N;;;;;
+14413;ANATOLIAN HIEROGLYPH A019;Lo;0;L;;;;;N;;;;;
+14414;ANATOLIAN HIEROGLYPH A020;Lo;0;L;;;;;N;;;;;
+14415;ANATOLIAN HIEROGLYPH A021;Lo;0;L;;;;;N;;;;;
+14416;ANATOLIAN HIEROGLYPH A022;Lo;0;L;;;;;N;;;;;
+14417;ANATOLIAN HIEROGLYPH A023;Lo;0;L;;;;;N;;;;;
+14418;ANATOLIAN HIEROGLYPH A024;Lo;0;L;;;;;N;;;;;
+14419;ANATOLIAN HIEROGLYPH A025;Lo;0;L;;;;;N;;;;;
+1441A;ANATOLIAN HIEROGLYPH A026;Lo;0;L;;;;;N;;;;;
+1441B;ANATOLIAN HIEROGLYPH A026A;Lo;0;L;;;;;N;;;;;
+1441C;ANATOLIAN HIEROGLYPH A027;Lo;0;L;;;;;N;;;;;
+1441D;ANATOLIAN HIEROGLYPH A028;Lo;0;L;;;;;N;;;;;
+1441E;ANATOLIAN HIEROGLYPH A029;Lo;0;L;;;;;N;;;;;
+1441F;ANATOLIAN HIEROGLYPH A030;Lo;0;L;;;;;N;;;;;
+14420;ANATOLIAN HIEROGLYPH A031;Lo;0;L;;;;;N;;;;;
+14421;ANATOLIAN HIEROGLYPH A032;Lo;0;L;;;;;N;;;;;
+14422;ANATOLIAN HIEROGLYPH A033;Lo;0;L;;;;;N;;;;;
+14423;ANATOLIAN HIEROGLYPH A034;Lo;0;L;;;;;N;;;;;
+14424;ANATOLIAN HIEROGLYPH A035;Lo;0;L;;;;;N;;;;;
+14425;ANATOLIAN HIEROGLYPH A036;Lo;0;L;;;;;N;;;;;
+14426;ANATOLIAN HIEROGLYPH A037;Lo;0;L;;;;;N;;;;;
+14427;ANATOLIAN HIEROGLYPH A038;Lo;0;L;;;;;N;;;;;
+14428;ANATOLIAN HIEROGLYPH A039;Lo;0;L;;;;;N;;;;;
+14429;ANATOLIAN HIEROGLYPH A039A;Lo;0;L;;;;;N;;;;;
+1442A;ANATOLIAN HIEROGLYPH A040;Lo;0;L;;;;;N;;;;;
+1442B;ANATOLIAN HIEROGLYPH A041;Lo;0;L;;;;;N;;;;;
+1442C;ANATOLIAN HIEROGLYPH A041A;Lo;0;L;;;;;N;;;;;
+1442D;ANATOLIAN HIEROGLYPH A042;Lo;0;L;;;;;N;;;;;
+1442E;ANATOLIAN HIEROGLYPH A043;Lo;0;L;;;;;N;;;;;
+1442F;ANATOLIAN HIEROGLYPH A044;Lo;0;L;;;;;N;;;;;
+14430;ANATOLIAN HIEROGLYPH A045;Lo;0;L;;;;;N;;;;;
+14431;ANATOLIAN HIEROGLYPH A045A;Lo;0;L;;;;;N;;;;;
+14432;ANATOLIAN HIEROGLYPH A046;Lo;0;L;;;;;N;;;;;
+14433;ANATOLIAN HIEROGLYPH A046A;Lo;0;L;;;;;N;;;;;
+14434;ANATOLIAN HIEROGLYPH A046B;Lo;0;L;;;;;N;;;;;
+14435;ANATOLIAN HIEROGLYPH A047;Lo;0;L;;;;;N;;;;;
+14436;ANATOLIAN HIEROGLYPH A048;Lo;0;L;;;;;N;;;;;
+14437;ANATOLIAN HIEROGLYPH A049;Lo;0;L;;;;;N;;;;;
+14438;ANATOLIAN HIEROGLYPH A050;Lo;0;L;;;;;N;;;;;
+14439;ANATOLIAN HIEROGLYPH A051;Lo;0;L;;;;;N;;;;;
+1443A;ANATOLIAN HIEROGLYPH A052;Lo;0;L;;;;;N;;;;;
+1443B;ANATOLIAN HIEROGLYPH A053;Lo;0;L;;;;;N;;;;;
+1443C;ANATOLIAN HIEROGLYPH A054;Lo;0;L;;;;;N;;;;;
+1443D;ANATOLIAN HIEROGLYPH A055;Lo;0;L;;;;;N;;;;;
+1443E;ANATOLIAN HIEROGLYPH A056;Lo;0;L;;;;;N;;;;;
+1443F;ANATOLIAN HIEROGLYPH A057;Lo;0;L;;;;;N;;;;;
+14440;ANATOLIAN HIEROGLYPH A058;Lo;0;L;;;;;N;;;;;
+14441;ANATOLIAN HIEROGLYPH A059;Lo;0;L;;;;;N;;;;;
+14442;ANATOLIAN HIEROGLYPH A060;Lo;0;L;;;;;N;;;;;
+14443;ANATOLIAN HIEROGLYPH A061;Lo;0;L;;;;;N;;;;;
+14444;ANATOLIAN HIEROGLYPH A062;Lo;0;L;;;;;N;;;;;
+14445;ANATOLIAN HIEROGLYPH A063;Lo;0;L;;;;;N;;;;;
+14446;ANATOLIAN HIEROGLYPH A064;Lo;0;L;;;;;N;;;;;
+14447;ANATOLIAN HIEROGLYPH A065;Lo;0;L;;;;;N;;;;;
+14448;ANATOLIAN HIEROGLYPH A066;Lo;0;L;;;;;N;;;;;
+14449;ANATOLIAN HIEROGLYPH A066A;Lo;0;L;;;;;N;;;;;
+1444A;ANATOLIAN HIEROGLYPH A066B;Lo;0;L;;;;;N;;;;;
+1444B;ANATOLIAN HIEROGLYPH A066C;Lo;0;L;;;;;N;;;;;
+1444C;ANATOLIAN HIEROGLYPH A067;Lo;0;L;;;;;N;;;;;
+1444D;ANATOLIAN HIEROGLYPH A068;Lo;0;L;;;;;N;;;;;
+1444E;ANATOLIAN HIEROGLYPH A069;Lo;0;L;;;;;N;;;;;
+1444F;ANATOLIAN HIEROGLYPH A070;Lo;0;L;;;;;N;;;;;
+14450;ANATOLIAN HIEROGLYPH A071;Lo;0;L;;;;;N;;;;;
+14451;ANATOLIAN HIEROGLYPH A072;Lo;0;L;;;;;N;;;;;
+14452;ANATOLIAN HIEROGLYPH A073;Lo;0;L;;;;;N;;;;;
+14453;ANATOLIAN HIEROGLYPH A074;Lo;0;L;;;;;N;;;;;
+14454;ANATOLIAN HIEROGLYPH A075;Lo;0;L;;;;;N;;;;;
+14455;ANATOLIAN HIEROGLYPH A076;Lo;0;L;;;;;N;;;;;
+14456;ANATOLIAN HIEROGLYPH A077;Lo;0;L;;;;;N;;;;;
+14457;ANATOLIAN HIEROGLYPH A078;Lo;0;L;;;;;N;;;;;
+14458;ANATOLIAN HIEROGLYPH A079;Lo;0;L;;;;;N;;;;;
+14459;ANATOLIAN HIEROGLYPH A080;Lo;0;L;;;;;N;;;;;
+1445A;ANATOLIAN HIEROGLYPH A081;Lo;0;L;;;;;N;;;;;
+1445B;ANATOLIAN HIEROGLYPH A082;Lo;0;L;;;;;N;;;;;
+1445C;ANATOLIAN HIEROGLYPH A083;Lo;0;L;;;;;N;;;;;
+1445D;ANATOLIAN HIEROGLYPH A084;Lo;0;L;;;;;N;;;;;
+1445E;ANATOLIAN HIEROGLYPH A085;Lo;0;L;;;;;N;;;;;
+1445F;ANATOLIAN HIEROGLYPH A086;Lo;0;L;;;;;N;;;;;
+14460;ANATOLIAN HIEROGLYPH A087;Lo;0;L;;;;;N;;;;;
+14461;ANATOLIAN HIEROGLYPH A088;Lo;0;L;;;;;N;;;;;
+14462;ANATOLIAN HIEROGLYPH A089;Lo;0;L;;;;;N;;;;;
+14463;ANATOLIAN HIEROGLYPH A090;Lo;0;L;;;;;N;;;;;
+14464;ANATOLIAN HIEROGLYPH A091;Lo;0;L;;;;;N;;;;;
+14465;ANATOLIAN HIEROGLYPH A092;Lo;0;L;;;;;N;;;;;
+14466;ANATOLIAN HIEROGLYPH A093;Lo;0;L;;;;;N;;;;;
+14467;ANATOLIAN HIEROGLYPH A094;Lo;0;L;;;;;N;;;;;
+14468;ANATOLIAN HIEROGLYPH A095;Lo;0;L;;;;;N;;;;;
+14469;ANATOLIAN HIEROGLYPH A096;Lo;0;L;;;;;N;;;;;
+1446A;ANATOLIAN HIEROGLYPH A097;Lo;0;L;;;;;N;;;;;
+1446B;ANATOLIAN HIEROGLYPH A097A;Lo;0;L;;;;;N;;;;;
+1446C;ANATOLIAN HIEROGLYPH A098;Lo;0;L;;;;;N;;;;;
+1446D;ANATOLIAN HIEROGLYPH A098A;Lo;0;L;;;;;N;;;;;
+1446E;ANATOLIAN HIEROGLYPH A099;Lo;0;L;;;;;N;;;;;
+1446F;ANATOLIAN HIEROGLYPH A100;Lo;0;L;;;;;N;;;;;
+14470;ANATOLIAN HIEROGLYPH A100A;Lo;0;L;;;;;N;;;;;
+14471;ANATOLIAN HIEROGLYPH A101;Lo;0;L;;;;;N;;;;;
+14472;ANATOLIAN HIEROGLYPH A101A;Lo;0;L;;;;;N;;;;;
+14473;ANATOLIAN HIEROGLYPH A102;Lo;0;L;;;;;N;;;;;
+14474;ANATOLIAN HIEROGLYPH A102A;Lo;0;L;;;;;N;;;;;
+14475;ANATOLIAN HIEROGLYPH A103;Lo;0;L;;;;;N;;;;;
+14476;ANATOLIAN HIEROGLYPH A104;Lo;0;L;;;;;N;;;;;
+14477;ANATOLIAN HIEROGLYPH A104A;Lo;0;L;;;;;N;;;;;
+14478;ANATOLIAN HIEROGLYPH A104B;Lo;0;L;;;;;N;;;;;
+14479;ANATOLIAN HIEROGLYPH A104C;Lo;0;L;;;;;N;;;;;
+1447A;ANATOLIAN HIEROGLYPH A105;Lo;0;L;;;;;N;;;;;
+1447B;ANATOLIAN HIEROGLYPH A105A;Lo;0;L;;;;;N;;;;;
+1447C;ANATOLIAN HIEROGLYPH A105B;Lo;0;L;;;;;N;;;;;
+1447D;ANATOLIAN HIEROGLYPH A106;Lo;0;L;;;;;N;;;;;
+1447E;ANATOLIAN HIEROGLYPH A107;Lo;0;L;;;;;N;;;;;
+1447F;ANATOLIAN HIEROGLYPH A107A;Lo;0;L;;;;;N;;;;;
+14480;ANATOLIAN HIEROGLYPH A107B;Lo;0;L;;;;;N;;;;;
+14481;ANATOLIAN HIEROGLYPH A107C;Lo;0;L;;;;;N;;;;;
+14482;ANATOLIAN HIEROGLYPH A108;Lo;0;L;;;;;N;;;;;
+14483;ANATOLIAN HIEROGLYPH A109;Lo;0;L;;;;;N;;;;;
+14484;ANATOLIAN HIEROGLYPH A110;Lo;0;L;;;;;N;;;;;
+14485;ANATOLIAN HIEROGLYPH A110A;Lo;0;L;;;;;N;;;;;
+14486;ANATOLIAN HIEROGLYPH A110B;Lo;0;L;;;;;N;;;;;
+14487;ANATOLIAN HIEROGLYPH A111;Lo;0;L;;;;;N;;;;;
+14488;ANATOLIAN HIEROGLYPH A112;Lo;0;L;;;;;N;;;;;
+14489;ANATOLIAN HIEROGLYPH A113;Lo;0;L;;;;;N;;;;;
+1448A;ANATOLIAN HIEROGLYPH A114;Lo;0;L;;;;;N;;;;;
+1448B;ANATOLIAN HIEROGLYPH A115;Lo;0;L;;;;;N;;;;;
+1448C;ANATOLIAN HIEROGLYPH A115A;Lo;0;L;;;;;N;;;;;
+1448D;ANATOLIAN HIEROGLYPH A116;Lo;0;L;;;;;N;;;;;
+1448E;ANATOLIAN HIEROGLYPH A117;Lo;0;L;;;;;N;;;;;
+1448F;ANATOLIAN HIEROGLYPH A118;Lo;0;L;;;;;N;;;;;
+14490;ANATOLIAN HIEROGLYPH A119;Lo;0;L;;;;;N;;;;;
+14491;ANATOLIAN HIEROGLYPH A120;Lo;0;L;;;;;N;;;;;
+14492;ANATOLIAN HIEROGLYPH A121;Lo;0;L;;;;;N;;;;;
+14493;ANATOLIAN HIEROGLYPH A122;Lo;0;L;;;;;N;;;;;
+14494;ANATOLIAN HIEROGLYPH A123;Lo;0;L;;;;;N;;;;;
+14495;ANATOLIAN HIEROGLYPH A124;Lo;0;L;;;;;N;;;;;
+14496;ANATOLIAN HIEROGLYPH A125;Lo;0;L;;;;;N;;;;;
+14497;ANATOLIAN HIEROGLYPH A125A;Lo;0;L;;;;;N;;;;;
+14498;ANATOLIAN HIEROGLYPH A126;Lo;0;L;;;;;N;;;;;
+14499;ANATOLIAN HIEROGLYPH A127;Lo;0;L;;;;;N;;;;;
+1449A;ANATOLIAN HIEROGLYPH A128;Lo;0;L;;;;;N;;;;;
+1449B;ANATOLIAN HIEROGLYPH A129;Lo;0;L;;;;;N;;;;;
+1449C;ANATOLIAN HIEROGLYPH A130;Lo;0;L;;;;;N;;;;;
+1449D;ANATOLIAN HIEROGLYPH A131;Lo;0;L;;;;;N;;;;;
+1449E;ANATOLIAN HIEROGLYPH A132;Lo;0;L;;;;;N;;;;;
+1449F;ANATOLIAN HIEROGLYPH A133;Lo;0;L;;;;;N;;;;;
+144A0;ANATOLIAN HIEROGLYPH A134;Lo;0;L;;;;;N;;;;;
+144A1;ANATOLIAN HIEROGLYPH A135;Lo;0;L;;;;;N;;;;;
+144A2;ANATOLIAN HIEROGLYPH A135A;Lo;0;L;;;;;N;;;;;
+144A3;ANATOLIAN HIEROGLYPH A136;Lo;0;L;;;;;N;;;;;
+144A4;ANATOLIAN HIEROGLYPH A137;Lo;0;L;;;;;N;;;;;
+144A5;ANATOLIAN HIEROGLYPH A138;Lo;0;L;;;;;N;;;;;
+144A6;ANATOLIAN HIEROGLYPH A139;Lo;0;L;;;;;N;;;;;
+144A7;ANATOLIAN HIEROGLYPH A140;Lo;0;L;;;;;N;;;;;
+144A8;ANATOLIAN HIEROGLYPH A141;Lo;0;L;;;;;N;;;;;
+144A9;ANATOLIAN HIEROGLYPH A142;Lo;0;L;;;;;N;;;;;
+144AA;ANATOLIAN HIEROGLYPH A143;Lo;0;L;;;;;N;;;;;
+144AB;ANATOLIAN HIEROGLYPH A144;Lo;0;L;;;;;N;;;;;
+144AC;ANATOLIAN HIEROGLYPH A145;Lo;0;L;;;;;N;;;;;
+144AD;ANATOLIAN HIEROGLYPH A146;Lo;0;L;;;;;N;;;;;
+144AE;ANATOLIAN HIEROGLYPH A147;Lo;0;L;;;;;N;;;;;
+144AF;ANATOLIAN HIEROGLYPH A148;Lo;0;L;;;;;N;;;;;
+144B0;ANATOLIAN HIEROGLYPH A149;Lo;0;L;;;;;N;;;;;
+144B1;ANATOLIAN HIEROGLYPH A150;Lo;0;L;;;;;N;;;;;
+144B2;ANATOLIAN HIEROGLYPH A151;Lo;0;L;;;;;N;;;;;
+144B3;ANATOLIAN HIEROGLYPH A152;Lo;0;L;;;;;N;;;;;
+144B4;ANATOLIAN HIEROGLYPH A153;Lo;0;L;;;;;N;;;;;
+144B5;ANATOLIAN HIEROGLYPH A154;Lo;0;L;;;;;N;;;;;
+144B6;ANATOLIAN HIEROGLYPH A155;Lo;0;L;;;;;N;;;;;
+144B7;ANATOLIAN HIEROGLYPH A156;Lo;0;L;;;;;N;;;;;
+144B8;ANATOLIAN HIEROGLYPH A157;Lo;0;L;;;;;N;;;;;
+144B9;ANATOLIAN HIEROGLYPH A158;Lo;0;L;;;;;N;;;;;
+144BA;ANATOLIAN HIEROGLYPH A159;Lo;0;L;;;;;N;;;;;
+144BB;ANATOLIAN HIEROGLYPH A160;Lo;0;L;;;;;N;;;;;
+144BC;ANATOLIAN HIEROGLYPH A161;Lo;0;L;;;;;N;;;;;
+144BD;ANATOLIAN HIEROGLYPH A162;Lo;0;L;;;;;N;;;;;
+144BE;ANATOLIAN HIEROGLYPH A163;Lo;0;L;;;;;N;;;;;
+144BF;ANATOLIAN HIEROGLYPH A164;Lo;0;L;;;;;N;;;;;
+144C0;ANATOLIAN HIEROGLYPH A165;Lo;0;L;;;;;N;;;;;
+144C1;ANATOLIAN HIEROGLYPH A166;Lo;0;L;;;;;N;;;;;
+144C2;ANATOLIAN HIEROGLYPH A167;Lo;0;L;;;;;N;;;;;
+144C3;ANATOLIAN HIEROGLYPH A168;Lo;0;L;;;;;N;;;;;
+144C4;ANATOLIAN HIEROGLYPH A169;Lo;0;L;;;;;N;;;;;
+144C5;ANATOLIAN HIEROGLYPH A170;Lo;0;L;;;;;N;;;;;
+144C6;ANATOLIAN HIEROGLYPH A171;Lo;0;L;;;;;N;;;;;
+144C7;ANATOLIAN HIEROGLYPH A172;Lo;0;L;;;;;N;;;;;
+144C8;ANATOLIAN HIEROGLYPH A173;Lo;0;L;;;;;N;;;;;
+144C9;ANATOLIAN HIEROGLYPH A174;Lo;0;L;;;;;N;;;;;
+144CA;ANATOLIAN HIEROGLYPH A175;Lo;0;L;;;;;N;;;;;
+144CB;ANATOLIAN HIEROGLYPH A176;Lo;0;L;;;;;N;;;;;
+144CC;ANATOLIAN HIEROGLYPH A177;Lo;0;L;;;;;N;;;;;
+144CD;ANATOLIAN HIEROGLYPH A178;Lo;0;L;;;;;N;;;;;
+144CE;ANATOLIAN HIEROGLYPH A179;Lo;0;L;;;;;N;;;;;
+144CF;ANATOLIAN HIEROGLYPH A180;Lo;0;L;;;;;N;;;;;
+144D0;ANATOLIAN HIEROGLYPH A181;Lo;0;L;;;;;N;;;;;
+144D1;ANATOLIAN HIEROGLYPH A182;Lo;0;L;;;;;N;;;;;
+144D2;ANATOLIAN HIEROGLYPH A183;Lo;0;L;;;;;N;;;;;
+144D3;ANATOLIAN HIEROGLYPH A184;Lo;0;L;;;;;N;;;;;
+144D4;ANATOLIAN HIEROGLYPH A185;Lo;0;L;;;;;N;;;;;
+144D5;ANATOLIAN HIEROGLYPH A186;Lo;0;L;;;;;N;;;;;
+144D6;ANATOLIAN HIEROGLYPH A187;Lo;0;L;;;;;N;;;;;
+144D7;ANATOLIAN HIEROGLYPH A188;Lo;0;L;;;;;N;;;;;
+144D8;ANATOLIAN HIEROGLYPH A189;Lo;0;L;;;;;N;;;;;
+144D9;ANATOLIAN HIEROGLYPH A190;Lo;0;L;;;;;N;;;;;
+144DA;ANATOLIAN HIEROGLYPH A191;Lo;0;L;;;;;N;;;;;
+144DB;ANATOLIAN HIEROGLYPH A192;Lo;0;L;;;;;N;;;;;
+144DC;ANATOLIAN HIEROGLYPH A193;Lo;0;L;;;;;N;;;;;
+144DD;ANATOLIAN HIEROGLYPH A194;Lo;0;L;;;;;N;;;;;
+144DE;ANATOLIAN HIEROGLYPH A195;Lo;0;L;;;;;N;;;;;
+144DF;ANATOLIAN HIEROGLYPH A196;Lo;0;L;;;;;N;;;;;
+144E0;ANATOLIAN HIEROGLYPH A197;Lo;0;L;;;;;N;;;;;
+144E1;ANATOLIAN HIEROGLYPH A198;Lo;0;L;;;;;N;;;;;
+144E2;ANATOLIAN HIEROGLYPH A199;Lo;0;L;;;;;N;;;;;
+144E3;ANATOLIAN HIEROGLYPH A200;Lo;0;L;;;;;N;;;;;
+144E4;ANATOLIAN HIEROGLYPH A201;Lo;0;L;;;;;N;;;;;
+144E5;ANATOLIAN HIEROGLYPH A202;Lo;0;L;;;;;N;;;;;
+144E6;ANATOLIAN HIEROGLYPH A202A;Lo;0;L;;;;;N;;;;;
+144E7;ANATOLIAN HIEROGLYPH A202B;Lo;0;L;;;;;N;;;;;
+144E8;ANATOLIAN HIEROGLYPH A203;Lo;0;L;;;;;N;;;;;
+144E9;ANATOLIAN HIEROGLYPH A204;Lo;0;L;;;;;N;;;;;
+144EA;ANATOLIAN HIEROGLYPH A205;Lo;0;L;;;;;N;;;;;
+144EB;ANATOLIAN HIEROGLYPH A206;Lo;0;L;;;;;N;;;;;
+144EC;ANATOLIAN HIEROGLYPH A207;Lo;0;L;;;;;N;;;;;
+144ED;ANATOLIAN HIEROGLYPH A207A;Lo;0;L;;;;;N;;;;;
+144EE;ANATOLIAN HIEROGLYPH A208;Lo;0;L;;;;;N;;;;;
+144EF;ANATOLIAN HIEROGLYPH A209;Lo;0;L;;;;;N;;;;;
+144F0;ANATOLIAN HIEROGLYPH A209A;Lo;0;L;;;;;N;;;;;
+144F1;ANATOLIAN HIEROGLYPH A210;Lo;0;L;;;;;N;;;;;
+144F2;ANATOLIAN HIEROGLYPH A211;Lo;0;L;;;;;N;;;;;
+144F3;ANATOLIAN HIEROGLYPH A212;Lo;0;L;;;;;N;;;;;
+144F4;ANATOLIAN HIEROGLYPH A213;Lo;0;L;;;;;N;;;;;
+144F5;ANATOLIAN HIEROGLYPH A214;Lo;0;L;;;;;N;;;;;
+144F6;ANATOLIAN HIEROGLYPH A215;Lo;0;L;;;;;N;;;;;
+144F7;ANATOLIAN HIEROGLYPH A215A;Lo;0;L;;;;;N;;;;;
+144F8;ANATOLIAN HIEROGLYPH A216;Lo;0;L;;;;;N;;;;;
+144F9;ANATOLIAN HIEROGLYPH A216A;Lo;0;L;;;;;N;;;;;
+144FA;ANATOLIAN HIEROGLYPH A217;Lo;0;L;;;;;N;;;;;
+144FB;ANATOLIAN HIEROGLYPH A218;Lo;0;L;;;;;N;;;;;
+144FC;ANATOLIAN HIEROGLYPH A219;Lo;0;L;;;;;N;;;;;
+144FD;ANATOLIAN HIEROGLYPH A220;Lo;0;L;;;;;N;;;;;
+144FE;ANATOLIAN HIEROGLYPH A221;Lo;0;L;;;;;N;;;;;
+144FF;ANATOLIAN HIEROGLYPH A222;Lo;0;L;;;;;N;;;;;
+14500;ANATOLIAN HIEROGLYPH A223;Lo;0;L;;;;;N;;;;;
+14501;ANATOLIAN HIEROGLYPH A224;Lo;0;L;;;;;N;;;;;
+14502;ANATOLIAN HIEROGLYPH A225;Lo;0;L;;;;;N;;;;;
+14503;ANATOLIAN HIEROGLYPH A226;Lo;0;L;;;;;N;;;;;
+14504;ANATOLIAN HIEROGLYPH A227;Lo;0;L;;;;;N;;;;;
+14505;ANATOLIAN HIEROGLYPH A227A;Lo;0;L;;;;;N;;;;;
+14506;ANATOLIAN HIEROGLYPH A228;Lo;0;L;;;;;N;;;;;
+14507;ANATOLIAN HIEROGLYPH A229;Lo;0;L;;;;;N;;;;;
+14508;ANATOLIAN HIEROGLYPH A230;Lo;0;L;;;;;N;;;;;
+14509;ANATOLIAN HIEROGLYPH A231;Lo;0;L;;;;;N;;;;;
+1450A;ANATOLIAN HIEROGLYPH A232;Lo;0;L;;;;;N;;;;;
+1450B;ANATOLIAN HIEROGLYPH A233;Lo;0;L;;;;;N;;;;;
+1450C;ANATOLIAN HIEROGLYPH A234;Lo;0;L;;;;;N;;;;;
+1450D;ANATOLIAN HIEROGLYPH A235;Lo;0;L;;;;;N;;;;;
+1450E;ANATOLIAN HIEROGLYPH A236;Lo;0;L;;;;;N;;;;;
+1450F;ANATOLIAN HIEROGLYPH A237;Lo;0;L;;;;;N;;;;;
+14510;ANATOLIAN HIEROGLYPH A238;Lo;0;L;;;;;N;;;;;
+14511;ANATOLIAN HIEROGLYPH A239;Lo;0;L;;;;;N;;;;;
+14512;ANATOLIAN HIEROGLYPH A240;Lo;0;L;;;;;N;;;;;
+14513;ANATOLIAN HIEROGLYPH A241;Lo;0;L;;;;;N;;;;;
+14514;ANATOLIAN HIEROGLYPH A242;Lo;0;L;;;;;N;;;;;
+14515;ANATOLIAN HIEROGLYPH A243;Lo;0;L;;;;;N;;;;;
+14516;ANATOLIAN HIEROGLYPH A244;Lo;0;L;;;;;N;;;;;
+14517;ANATOLIAN HIEROGLYPH A245;Lo;0;L;;;;;N;;;;;
+14518;ANATOLIAN HIEROGLYPH A246;Lo;0;L;;;;;N;;;;;
+14519;ANATOLIAN HIEROGLYPH A247;Lo;0;L;;;;;N;;;;;
+1451A;ANATOLIAN HIEROGLYPH A248;Lo;0;L;;;;;N;;;;;
+1451B;ANATOLIAN HIEROGLYPH A249;Lo;0;L;;;;;N;;;;;
+1451C;ANATOLIAN HIEROGLYPH A250;Lo;0;L;;;;;N;;;;;
+1451D;ANATOLIAN HIEROGLYPH A251;Lo;0;L;;;;;N;;;;;
+1451E;ANATOLIAN HIEROGLYPH A252;Lo;0;L;;;;;N;;;;;
+1451F;ANATOLIAN HIEROGLYPH A253;Lo;0;L;;;;;N;;;;;
+14520;ANATOLIAN HIEROGLYPH A254;Lo;0;L;;;;;N;;;;;
+14521;ANATOLIAN HIEROGLYPH A255;Lo;0;L;;;;;N;;;;;
+14522;ANATOLIAN HIEROGLYPH A256;Lo;0;L;;;;;N;;;;;
+14523;ANATOLIAN HIEROGLYPH A257;Lo;0;L;;;;;N;;;;;
+14524;ANATOLIAN HIEROGLYPH A258;Lo;0;L;;;;;N;;;;;
+14525;ANATOLIAN HIEROGLYPH A259;Lo;0;L;;;;;N;;;;;
+14526;ANATOLIAN HIEROGLYPH A260;Lo;0;L;;;;;N;;;;;
+14527;ANATOLIAN HIEROGLYPH A261;Lo;0;L;;;;;N;;;;;
+14528;ANATOLIAN HIEROGLYPH A262;Lo;0;L;;;;;N;;;;;
+14529;ANATOLIAN HIEROGLYPH A263;Lo;0;L;;;;;N;;;;;
+1452A;ANATOLIAN HIEROGLYPH A264;Lo;0;L;;;;;N;;;;;
+1452B;ANATOLIAN HIEROGLYPH A265;Lo;0;L;;;;;N;;;;;
+1452C;ANATOLIAN HIEROGLYPH A266;Lo;0;L;;;;;N;;;;;
+1452D;ANATOLIAN HIEROGLYPH A267;Lo;0;L;;;;;N;;;;;
+1452E;ANATOLIAN HIEROGLYPH A267A;Lo;0;L;;;;;N;;;;;
+1452F;ANATOLIAN HIEROGLYPH A268;Lo;0;L;;;;;N;;;;;
+14530;ANATOLIAN HIEROGLYPH A269;Lo;0;L;;;;;N;;;;;
+14531;ANATOLIAN HIEROGLYPH A270;Lo;0;L;;;;;N;;;;;
+14532;ANATOLIAN HIEROGLYPH A271;Lo;0;L;;;;;N;;;;;
+14533;ANATOLIAN HIEROGLYPH A272;Lo;0;L;;;;;N;;;;;
+14534;ANATOLIAN HIEROGLYPH A273;Lo;0;L;;;;;N;;;;;
+14535;ANATOLIAN HIEROGLYPH A274;Lo;0;L;;;;;N;;;;;
+14536;ANATOLIAN HIEROGLYPH A275;Lo;0;L;;;;;N;;;;;
+14537;ANATOLIAN HIEROGLYPH A276;Lo;0;L;;;;;N;;;;;
+14538;ANATOLIAN HIEROGLYPH A277;Lo;0;L;;;;;N;;;;;
+14539;ANATOLIAN HIEROGLYPH A278;Lo;0;L;;;;;N;;;;;
+1453A;ANATOLIAN HIEROGLYPH A279;Lo;0;L;;;;;N;;;;;
+1453B;ANATOLIAN HIEROGLYPH A280;Lo;0;L;;;;;N;;;;;
+1453C;ANATOLIAN HIEROGLYPH A281;Lo;0;L;;;;;N;;;;;
+1453D;ANATOLIAN HIEROGLYPH A282;Lo;0;L;;;;;N;;;;;
+1453E;ANATOLIAN HIEROGLYPH A283;Lo;0;L;;;;;N;;;;;
+1453F;ANATOLIAN HIEROGLYPH A284;Lo;0;L;;;;;N;;;;;
+14540;ANATOLIAN HIEROGLYPH A285;Lo;0;L;;;;;N;;;;;
+14541;ANATOLIAN HIEROGLYPH A286;Lo;0;L;;;;;N;;;;;
+14542;ANATOLIAN HIEROGLYPH A287;Lo;0;L;;;;;N;;;;;
+14543;ANATOLIAN HIEROGLYPH A288;Lo;0;L;;;;;N;;;;;
+14544;ANATOLIAN HIEROGLYPH A289;Lo;0;L;;;;;N;;;;;
+14545;ANATOLIAN HIEROGLYPH A289A;Lo;0;L;;;;;N;;;;;
+14546;ANATOLIAN HIEROGLYPH A290;Lo;0;L;;;;;N;;;;;
+14547;ANATOLIAN HIEROGLYPH A291;Lo;0;L;;;;;N;;;;;
+14548;ANATOLIAN HIEROGLYPH A292;Lo;0;L;;;;;N;;;;;
+14549;ANATOLIAN HIEROGLYPH A293;Lo;0;L;;;;;N;;;;;
+1454A;ANATOLIAN HIEROGLYPH A294;Lo;0;L;;;;;N;;;;;
+1454B;ANATOLIAN HIEROGLYPH A294A;Lo;0;L;;;;;N;;;;;
+1454C;ANATOLIAN HIEROGLYPH A295;Lo;0;L;;;;;N;;;;;
+1454D;ANATOLIAN HIEROGLYPH A296;Lo;0;L;;;;;N;;;;;
+1454E;ANATOLIAN HIEROGLYPH A297;Lo;0;L;;;;;N;;;;;
+1454F;ANATOLIAN HIEROGLYPH A298;Lo;0;L;;;;;N;;;;;
+14550;ANATOLIAN HIEROGLYPH A299;Lo;0;L;;;;;N;;;;;
+14551;ANATOLIAN HIEROGLYPH A299A;Lo;0;L;;;;;N;;;;;
+14552;ANATOLIAN HIEROGLYPH A300;Lo;0;L;;;;;N;;;;;
+14553;ANATOLIAN HIEROGLYPH A301;Lo;0;L;;;;;N;;;;;
+14554;ANATOLIAN HIEROGLYPH A302;Lo;0;L;;;;;N;;;;;
+14555;ANATOLIAN HIEROGLYPH A303;Lo;0;L;;;;;N;;;;;
+14556;ANATOLIAN HIEROGLYPH A304;Lo;0;L;;;;;N;;;;;
+14557;ANATOLIAN HIEROGLYPH A305;Lo;0;L;;;;;N;;;;;
+14558;ANATOLIAN HIEROGLYPH A306;Lo;0;L;;;;;N;;;;;
+14559;ANATOLIAN HIEROGLYPH A307;Lo;0;L;;;;;N;;;;;
+1455A;ANATOLIAN HIEROGLYPH A308;Lo;0;L;;;;;N;;;;;
+1455B;ANATOLIAN HIEROGLYPH A309;Lo;0;L;;;;;N;;;;;
+1455C;ANATOLIAN HIEROGLYPH A309A;Lo;0;L;;;;;N;;;;;
+1455D;ANATOLIAN HIEROGLYPH A310;Lo;0;L;;;;;N;;;;;
+1455E;ANATOLIAN HIEROGLYPH A311;Lo;0;L;;;;;N;;;;;
+1455F;ANATOLIAN HIEROGLYPH A312;Lo;0;L;;;;;N;;;;;
+14560;ANATOLIAN HIEROGLYPH A313;Lo;0;L;;;;;N;;;;;
+14561;ANATOLIAN HIEROGLYPH A314;Lo;0;L;;;;;N;;;;;
+14562;ANATOLIAN HIEROGLYPH A315;Lo;0;L;;;;;N;;;;;
+14563;ANATOLIAN HIEROGLYPH A316;Lo;0;L;;;;;N;;;;;
+14564;ANATOLIAN HIEROGLYPH A317;Lo;0;L;;;;;N;;;;;
+14565;ANATOLIAN HIEROGLYPH A318;Lo;0;L;;;;;N;;;;;
+14566;ANATOLIAN HIEROGLYPH A319;Lo;0;L;;;;;N;;;;;
+14567;ANATOLIAN HIEROGLYPH A320;Lo;0;L;;;;;N;;;;;
+14568;ANATOLIAN HIEROGLYPH A321;Lo;0;L;;;;;N;;;;;
+14569;ANATOLIAN HIEROGLYPH A322;Lo;0;L;;;;;N;;;;;
+1456A;ANATOLIAN HIEROGLYPH A323;Lo;0;L;;;;;N;;;;;
+1456B;ANATOLIAN HIEROGLYPH A324;Lo;0;L;;;;;N;;;;;
+1456C;ANATOLIAN HIEROGLYPH A325;Lo;0;L;;;;;N;;;;;
+1456D;ANATOLIAN HIEROGLYPH A326;Lo;0;L;;;;;N;;;;;
+1456E;ANATOLIAN HIEROGLYPH A327;Lo;0;L;;;;;N;;;;;
+1456F;ANATOLIAN HIEROGLYPH A328;Lo;0;L;;;;;N;;;;;
+14570;ANATOLIAN HIEROGLYPH A329;Lo;0;L;;;;;N;;;;;
+14571;ANATOLIAN HIEROGLYPH A329A;Lo;0;L;;;;;N;;;;;
+14572;ANATOLIAN HIEROGLYPH A330;Lo;0;L;;;;;N;;;;;
+14573;ANATOLIAN HIEROGLYPH A331;Lo;0;L;;;;;N;;;;;
+14574;ANATOLIAN HIEROGLYPH A332A;Lo;0;L;;;;;N;;;;;
+14575;ANATOLIAN HIEROGLYPH A332B;Lo;0;L;;;;;N;;;;;
+14576;ANATOLIAN HIEROGLYPH A332C;Lo;0;L;;;;;N;;;;;
+14577;ANATOLIAN HIEROGLYPH A333;Lo;0;L;;;;;N;;;;;
+14578;ANATOLIAN HIEROGLYPH A334;Lo;0;L;;;;;N;;;;;
+14579;ANATOLIAN HIEROGLYPH A335;Lo;0;L;;;;;N;;;;;
+1457A;ANATOLIAN HIEROGLYPH A336;Lo;0;L;;;;;N;;;;;
+1457B;ANATOLIAN HIEROGLYPH A336A;Lo;0;L;;;;;N;;;;;
+1457C;ANATOLIAN HIEROGLYPH A336B;Lo;0;L;;;;;N;;;;;
+1457D;ANATOLIAN HIEROGLYPH A336C;Lo;0;L;;;;;N;;;;;
+1457E;ANATOLIAN HIEROGLYPH A337;Lo;0;L;;;;;N;;;;;
+1457F;ANATOLIAN HIEROGLYPH A338;Lo;0;L;;;;;N;;;;;
+14580;ANATOLIAN HIEROGLYPH A339;Lo;0;L;;;;;N;;;;;
+14581;ANATOLIAN HIEROGLYPH A340;Lo;0;L;;;;;N;;;;;
+14582;ANATOLIAN HIEROGLYPH A341;Lo;0;L;;;;;N;;;;;
+14583;ANATOLIAN HIEROGLYPH A342;Lo;0;L;;;;;N;;;;;
+14584;ANATOLIAN HIEROGLYPH A343;Lo;0;L;;;;;N;;;;;
+14585;ANATOLIAN HIEROGLYPH A344;Lo;0;L;;;;;N;;;;;
+14586;ANATOLIAN HIEROGLYPH A345;Lo;0;L;;;;;N;;;;;
+14587;ANATOLIAN HIEROGLYPH A346;Lo;0;L;;;;;N;;;;;
+14588;ANATOLIAN HIEROGLYPH A347;Lo;0;L;;;;;N;;;;;
+14589;ANATOLIAN HIEROGLYPH A348;Lo;0;L;;;;;N;;;;;
+1458A;ANATOLIAN HIEROGLYPH A349;Lo;0;L;;;;;N;;;;;
+1458B;ANATOLIAN HIEROGLYPH A350;Lo;0;L;;;;;N;;;;;
+1458C;ANATOLIAN HIEROGLYPH A351;Lo;0;L;;;;;N;;;;;
+1458D;ANATOLIAN HIEROGLYPH A352;Lo;0;L;;;;;N;;;;;
+1458E;ANATOLIAN HIEROGLYPH A353;Lo;0;L;;;;;N;;;;;
+1458F;ANATOLIAN HIEROGLYPH A354;Lo;0;L;;;;;N;;;;;
+14590;ANATOLIAN HIEROGLYPH A355;Lo;0;L;;;;;N;;;;;
+14591;ANATOLIAN HIEROGLYPH A356;Lo;0;L;;;;;N;;;;;
+14592;ANATOLIAN HIEROGLYPH A357;Lo;0;L;;;;;N;;;;;
+14593;ANATOLIAN HIEROGLYPH A358;Lo;0;L;;;;;N;;;;;
+14594;ANATOLIAN HIEROGLYPH A359;Lo;0;L;;;;;N;;;;;
+14595;ANATOLIAN HIEROGLYPH A359A;Lo;0;L;;;;;N;;;;;
+14596;ANATOLIAN HIEROGLYPH A360;Lo;0;L;;;;;N;;;;;
+14597;ANATOLIAN HIEROGLYPH A361;Lo;0;L;;;;;N;;;;;
+14598;ANATOLIAN HIEROGLYPH A362;Lo;0;L;;;;;N;;;;;
+14599;ANATOLIAN HIEROGLYPH A363;Lo;0;L;;;;;N;;;;;
+1459A;ANATOLIAN HIEROGLYPH A364;Lo;0;L;;;;;N;;;;;
+1459B;ANATOLIAN HIEROGLYPH A364A;Lo;0;L;;;;;N;;;;;
+1459C;ANATOLIAN HIEROGLYPH A365;Lo;0;L;;;;;N;;;;;
+1459D;ANATOLIAN HIEROGLYPH A366;Lo;0;L;;;;;N;;;;;
+1459E;ANATOLIAN HIEROGLYPH A367;Lo;0;L;;;;;N;;;;;
+1459F;ANATOLIAN HIEROGLYPH A368;Lo;0;L;;;;;N;;;;;
+145A0;ANATOLIAN HIEROGLYPH A368A;Lo;0;L;;;;;N;;;;;
+145A1;ANATOLIAN HIEROGLYPH A369;Lo;0;L;;;;;N;;;;;
+145A2;ANATOLIAN HIEROGLYPH A370;Lo;0;L;;;;;N;;;;;
+145A3;ANATOLIAN HIEROGLYPH A371;Lo;0;L;;;;;N;;;;;
+145A4;ANATOLIAN HIEROGLYPH A371A;Lo;0;L;;;;;N;;;;;
+145A5;ANATOLIAN HIEROGLYPH A372;Lo;0;L;;;;;N;;;;;
+145A6;ANATOLIAN HIEROGLYPH A373;Lo;0;L;;;;;N;;;;;
+145A7;ANATOLIAN HIEROGLYPH A374;Lo;0;L;;;;;N;;;;;
+145A8;ANATOLIAN HIEROGLYPH A375;Lo;0;L;;;;;N;;;;;
+145A9;ANATOLIAN HIEROGLYPH A376;Lo;0;L;;;;;N;;;;;
+145AA;ANATOLIAN HIEROGLYPH A377;Lo;0;L;;;;;N;;;;;
+145AB;ANATOLIAN HIEROGLYPH A378;Lo;0;L;;;;;N;;;;;
+145AC;ANATOLIAN HIEROGLYPH A379;Lo;0;L;;;;;N;;;;;
+145AD;ANATOLIAN HIEROGLYPH A380;Lo;0;L;;;;;N;;;;;
+145AE;ANATOLIAN HIEROGLYPH A381;Lo;0;L;;;;;N;;;;;
+145AF;ANATOLIAN HIEROGLYPH A381A;Lo;0;L;;;;;N;;;;;
+145B0;ANATOLIAN HIEROGLYPH A382;Lo;0;L;;;;;N;;;;;
+145B1;ANATOLIAN HIEROGLYPH A383 RA OR RI;Lo;0;L;;;;;N;;;;;
+145B2;ANATOLIAN HIEROGLYPH A383A;Lo;0;L;;;;;N;;;;;
+145B3;ANATOLIAN HIEROGLYPH A384;Lo;0;L;;;;;N;;;;;
+145B4;ANATOLIAN HIEROGLYPH A385;Lo;0;L;;;;;N;;;;;
+145B5;ANATOLIAN HIEROGLYPH A386;Lo;0;L;;;;;N;;;;;
+145B6;ANATOLIAN HIEROGLYPH A386A;Lo;0;L;;;;;N;;;;;
+145B7;ANATOLIAN HIEROGLYPH A387;Lo;0;L;;;;;N;;;;;
+145B8;ANATOLIAN HIEROGLYPH A388;Lo;0;L;;;;;N;;;;;
+145B9;ANATOLIAN HIEROGLYPH A389;Lo;0;L;;;;;N;;;;;
+145BA;ANATOLIAN HIEROGLYPH A390;Lo;0;L;;;;;N;;;;;
+145BB;ANATOLIAN HIEROGLYPH A391;Lo;0;L;;;;;N;;;;;
+145BC;ANATOLIAN HIEROGLYPH A392;Lo;0;L;;;;;N;;;;;
+145BD;ANATOLIAN HIEROGLYPH A393 EIGHT;Lo;0;L;;;;;N;;;;;
+145BE;ANATOLIAN HIEROGLYPH A394;Lo;0;L;;;;;N;;;;;
+145BF;ANATOLIAN HIEROGLYPH A395;Lo;0;L;;;;;N;;;;;
+145C0;ANATOLIAN HIEROGLYPH A396;Lo;0;L;;;;;N;;;;;
+145C1;ANATOLIAN HIEROGLYPH A397;Lo;0;L;;;;;N;;;;;
+145C2;ANATOLIAN HIEROGLYPH A398;Lo;0;L;;;;;N;;;;;
+145C3;ANATOLIAN HIEROGLYPH A399;Lo;0;L;;;;;N;;;;;
+145C4;ANATOLIAN HIEROGLYPH A400;Lo;0;L;;;;;N;;;;;
+145C5;ANATOLIAN HIEROGLYPH A401;Lo;0;L;;;;;N;;;;;
+145C6;ANATOLIAN HIEROGLYPH A402;Lo;0;L;;;;;N;;;;;
+145C7;ANATOLIAN HIEROGLYPH A403;Lo;0;L;;;;;N;;;;;
+145C8;ANATOLIAN HIEROGLYPH A404;Lo;0;L;;;;;N;;;;;
+145C9;ANATOLIAN HIEROGLYPH A405;Lo;0;L;;;;;N;;;;;
+145CA;ANATOLIAN HIEROGLYPH A406;Lo;0;L;;;;;N;;;;;
+145CB;ANATOLIAN HIEROGLYPH A407;Lo;0;L;;;;;N;;;;;
+145CC;ANATOLIAN HIEROGLYPH A408;Lo;0;L;;;;;N;;;;;
+145CD;ANATOLIAN HIEROGLYPH A409;Lo;0;L;;;;;N;;;;;
+145CE;ANATOLIAN HIEROGLYPH A410 BEGIN LOGOGRAM MARK;Lo;0;L;;;;;N;;;;;
+145CF;ANATOLIAN HIEROGLYPH A410A END LOGOGRAM MARK;Lo;0;L;;;;;N;;;;;
+145D0;ANATOLIAN HIEROGLYPH A411;Lo;0;L;;;;;N;;;;;
+145D1;ANATOLIAN HIEROGLYPH A412;Lo;0;L;;;;;N;;;;;
+145D2;ANATOLIAN HIEROGLYPH A413;Lo;0;L;;;;;N;;;;;
+145D3;ANATOLIAN HIEROGLYPH A414;Lo;0;L;;;;;N;;;;;
+145D4;ANATOLIAN HIEROGLYPH A415;Lo;0;L;;;;;N;;;;;
+145D5;ANATOLIAN HIEROGLYPH A416;Lo;0;L;;;;;N;;;;;
+145D6;ANATOLIAN HIEROGLYPH A417;Lo;0;L;;;;;N;;;;;
+145D7;ANATOLIAN HIEROGLYPH A418;Lo;0;L;;;;;N;;;;;
+145D8;ANATOLIAN HIEROGLYPH A419;Lo;0;L;;;;;N;;;;;
+145D9;ANATOLIAN HIEROGLYPH A420;Lo;0;L;;;;;N;;;;;
+145DA;ANATOLIAN HIEROGLYPH A421;Lo;0;L;;;;;N;;;;;
+145DB;ANATOLIAN HIEROGLYPH A422;Lo;0;L;;;;;N;;;;;
+145DC;ANATOLIAN HIEROGLYPH A423;Lo;0;L;;;;;N;;;;;
+145DD;ANATOLIAN HIEROGLYPH A424;Lo;0;L;;;;;N;;;;;
+145DE;ANATOLIAN HIEROGLYPH A425;Lo;0;L;;;;;N;;;;;
+145DF;ANATOLIAN HIEROGLYPH A426;Lo;0;L;;;;;N;;;;;
+145E0;ANATOLIAN HIEROGLYPH A427;Lo;0;L;;;;;N;;;;;
+145E1;ANATOLIAN HIEROGLYPH A428;Lo;0;L;;;;;N;;;;;
+145E2;ANATOLIAN HIEROGLYPH A429;Lo;0;L;;;;;N;;;;;
+145E3;ANATOLIAN HIEROGLYPH A430;Lo;0;L;;;;;N;;;;;
+145E4;ANATOLIAN HIEROGLYPH A431;Lo;0;L;;;;;N;;;;;
+145E5;ANATOLIAN HIEROGLYPH A432;Lo;0;L;;;;;N;;;;;
+145E6;ANATOLIAN HIEROGLYPH A433;Lo;0;L;;;;;N;;;;;
+145E7;ANATOLIAN HIEROGLYPH A434;Lo;0;L;;;;;N;;;;;
+145E8;ANATOLIAN HIEROGLYPH A435;Lo;0;L;;;;;N;;;;;
+145E9;ANATOLIAN HIEROGLYPH A436;Lo;0;L;;;;;N;;;;;
+145EA;ANATOLIAN HIEROGLYPH A437;Lo;0;L;;;;;N;;;;;
+145EB;ANATOLIAN HIEROGLYPH A438;Lo;0;L;;;;;N;;;;;
+145EC;ANATOLIAN HIEROGLYPH A439;Lo;0;L;;;;;N;;;;;
+145ED;ANATOLIAN HIEROGLYPH A440;Lo;0;L;;;;;N;;;;;
+145EE;ANATOLIAN HIEROGLYPH A441;Lo;0;L;;;;;N;;;;;
+145EF;ANATOLIAN HIEROGLYPH A442;Lo;0;L;;;;;N;;;;;
+145F0;ANATOLIAN HIEROGLYPH A443;Lo;0;L;;;;;N;;;;;
+145F1;ANATOLIAN HIEROGLYPH A444;Lo;0;L;;;;;N;;;;;
+145F2;ANATOLIAN HIEROGLYPH A445;Lo;0;L;;;;;N;;;;;
+145F3;ANATOLIAN HIEROGLYPH A446;Lo;0;L;;;;;N;;;;;
+145F4;ANATOLIAN HIEROGLYPH A447;Lo;0;L;;;;;N;;;;;
+145F5;ANATOLIAN HIEROGLYPH A448;Lo;0;L;;;;;N;;;;;
+145F6;ANATOLIAN HIEROGLYPH A449;Lo;0;L;;;;;N;;;;;
+145F7;ANATOLIAN HIEROGLYPH A450;Lo;0;L;;;;;N;;;;;
+145F8;ANATOLIAN HIEROGLYPH A450A;Lo;0;L;;;;;N;;;;;
+145F9;ANATOLIAN HIEROGLYPH A451;Lo;0;L;;;;;N;;;;;
+145FA;ANATOLIAN HIEROGLYPH A452;Lo;0;L;;;;;N;;;;;
+145FB;ANATOLIAN HIEROGLYPH A453;Lo;0;L;;;;;N;;;;;
+145FC;ANATOLIAN HIEROGLYPH A454;Lo;0;L;;;;;N;;;;;
+145FD;ANATOLIAN HIEROGLYPH A455;Lo;0;L;;;;;N;;;;;
+145FE;ANATOLIAN HIEROGLYPH A456;Lo;0;L;;;;;N;;;;;
+145FF;ANATOLIAN HIEROGLYPH A457;Lo;0;L;;;;;N;;;;;
+14600;ANATOLIAN HIEROGLYPH A457A;Lo;0;L;;;;;N;;;;;
+14601;ANATOLIAN HIEROGLYPH A458;Lo;0;L;;;;;N;;;;;
+14602;ANATOLIAN HIEROGLYPH A459;Lo;0;L;;;;;N;;;;;
+14603;ANATOLIAN HIEROGLYPH A460;Lo;0;L;;;;;N;;;;;
+14604;ANATOLIAN HIEROGLYPH A461;Lo;0;L;;;;;N;;;;;
+14605;ANATOLIAN HIEROGLYPH A462;Lo;0;L;;;;;N;;;;;
+14606;ANATOLIAN HIEROGLYPH A463;Lo;0;L;;;;;N;;;;;
+14607;ANATOLIAN HIEROGLYPH A464;Lo;0;L;;;;;N;;;;;
+14608;ANATOLIAN HIEROGLYPH A465;Lo;0;L;;;;;N;;;;;
+14609;ANATOLIAN HIEROGLYPH A466;Lo;0;L;;;;;N;;;;;
+1460A;ANATOLIAN HIEROGLYPH A467;Lo;0;L;;;;;N;;;;;
+1460B;ANATOLIAN HIEROGLYPH A468;Lo;0;L;;;;;N;;;;;
+1460C;ANATOLIAN HIEROGLYPH A469;Lo;0;L;;;;;N;;;;;
+1460D;ANATOLIAN HIEROGLYPH A470;Lo;0;L;;;;;N;;;;;
+1460E;ANATOLIAN HIEROGLYPH A471;Lo;0;L;;;;;N;;;;;
+1460F;ANATOLIAN HIEROGLYPH A472;Lo;0;L;;;;;N;;;;;
+14610;ANATOLIAN HIEROGLYPH A473;Lo;0;L;;;;;N;;;;;
+14611;ANATOLIAN HIEROGLYPH A474;Lo;0;L;;;;;N;;;;;
+14612;ANATOLIAN HIEROGLYPH A475;Lo;0;L;;;;;N;;;;;
+14613;ANATOLIAN HIEROGLYPH A476;Lo;0;L;;;;;N;;;;;
+14614;ANATOLIAN HIEROGLYPH A477;Lo;0;L;;;;;N;;;;;
+14615;ANATOLIAN HIEROGLYPH A478;Lo;0;L;;;;;N;;;;;
+14616;ANATOLIAN HIEROGLYPH A479;Lo;0;L;;;;;N;;;;;
+14617;ANATOLIAN HIEROGLYPH A480;Lo;0;L;;;;;N;;;;;
+14618;ANATOLIAN HIEROGLYPH A481;Lo;0;L;;;;;N;;;;;
+14619;ANATOLIAN HIEROGLYPH A482;Lo;0;L;;;;;N;;;;;
+1461A;ANATOLIAN HIEROGLYPH A483;Lo;0;L;;;;;N;;;;;
+1461B;ANATOLIAN HIEROGLYPH A484;Lo;0;L;;;;;N;;;;;
+1461C;ANATOLIAN HIEROGLYPH A485;Lo;0;L;;;;;N;;;;;
+1461D;ANATOLIAN HIEROGLYPH A486;Lo;0;L;;;;;N;;;;;
+1461E;ANATOLIAN HIEROGLYPH A487;Lo;0;L;;;;;N;;;;;
+1461F;ANATOLIAN HIEROGLYPH A488;Lo;0;L;;;;;N;;;;;
+14620;ANATOLIAN HIEROGLYPH A489;Lo;0;L;;;;;N;;;;;
+14621;ANATOLIAN HIEROGLYPH A490;Lo;0;L;;;;;N;;;;;
+14622;ANATOLIAN HIEROGLYPH A491;Lo;0;L;;;;;N;;;;;
+14623;ANATOLIAN HIEROGLYPH A492;Lo;0;L;;;;;N;;;;;
+14624;ANATOLIAN HIEROGLYPH A493;Lo;0;L;;;;;N;;;;;
+14625;ANATOLIAN HIEROGLYPH A494;Lo;0;L;;;;;N;;;;;
+14626;ANATOLIAN HIEROGLYPH A495;Lo;0;L;;;;;N;;;;;
+14627;ANATOLIAN HIEROGLYPH A496;Lo;0;L;;;;;N;;;;;
+14628;ANATOLIAN HIEROGLYPH A497;Lo;0;L;;;;;N;;;;;
+14629;ANATOLIAN HIEROGLYPH A501;Lo;0;L;;;;;N;;;;;
+1462A;ANATOLIAN HIEROGLYPH A502;Lo;0;L;;;;;N;;;;;
+1462B;ANATOLIAN HIEROGLYPH A503;Lo;0;L;;;;;N;;;;;
+1462C;ANATOLIAN HIEROGLYPH A504;Lo;0;L;;;;;N;;;;;
+1462D;ANATOLIAN HIEROGLYPH A505;Lo;0;L;;;;;N;;;;;
+1462E;ANATOLIAN HIEROGLYPH A506;Lo;0;L;;;;;N;;;;;
+1462F;ANATOLIAN HIEROGLYPH A507;Lo;0;L;;;;;N;;;;;
+14630;ANATOLIAN HIEROGLYPH A508;Lo;0;L;;;;;N;;;;;
+14631;ANATOLIAN HIEROGLYPH A509;Lo;0;L;;;;;N;;;;;
+14632;ANATOLIAN HIEROGLYPH A510;Lo;0;L;;;;;N;;;;;
+14633;ANATOLIAN HIEROGLYPH A511;Lo;0;L;;;;;N;;;;;
+14634;ANATOLIAN HIEROGLYPH A512;Lo;0;L;;;;;N;;;;;
+14635;ANATOLIAN HIEROGLYPH A513;Lo;0;L;;;;;N;;;;;
+14636;ANATOLIAN HIEROGLYPH A514;Lo;0;L;;;;;N;;;;;
+14637;ANATOLIAN HIEROGLYPH A515;Lo;0;L;;;;;N;;;;;
+14638;ANATOLIAN HIEROGLYPH A516;Lo;0;L;;;;;N;;;;;
+14639;ANATOLIAN HIEROGLYPH A517;Lo;0;L;;;;;N;;;;;
+1463A;ANATOLIAN HIEROGLYPH A518;Lo;0;L;;;;;N;;;;;
+1463B;ANATOLIAN HIEROGLYPH A519;Lo;0;L;;;;;N;;;;;
+1463C;ANATOLIAN HIEROGLYPH A520;Lo;0;L;;;;;N;;;;;
+1463D;ANATOLIAN HIEROGLYPH A521;Lo;0;L;;;;;N;;;;;
+1463E;ANATOLIAN HIEROGLYPH A522;Lo;0;L;;;;;N;;;;;
+1463F;ANATOLIAN HIEROGLYPH A523;Lo;0;L;;;;;N;;;;;
+14640;ANATOLIAN HIEROGLYPH A524;Lo;0;L;;;;;N;;;;;
+14641;ANATOLIAN HIEROGLYPH A525;Lo;0;L;;;;;N;;;;;
+14642;ANATOLIAN HIEROGLYPH A526;Lo;0;L;;;;;N;;;;;
+14643;ANATOLIAN HIEROGLYPH A527;Lo;0;L;;;;;N;;;;;
+14644;ANATOLIAN HIEROGLYPH A528;Lo;0;L;;;;;N;;;;;
+14645;ANATOLIAN HIEROGLYPH A529;Lo;0;L;;;;;N;;;;;
+14646;ANATOLIAN HIEROGLYPH A530;Lo;0;L;;;;;N;;;;;
+16800;BAMUM LETTER PHASE-A NGKUE MFON;Lo;0;L;;;;;N;;;;;
+16801;BAMUM LETTER PHASE-A GBIEE FON;Lo;0;L;;;;;N;;;;;
+16802;BAMUM LETTER PHASE-A PON MFON PIPAEMGBIEE;Lo;0;L;;;;;N;;;;;
+16803;BAMUM LETTER PHASE-A PON MFON PIPAEMBA;Lo;0;L;;;;;N;;;;;
+16804;BAMUM LETTER PHASE-A NAA MFON;Lo;0;L;;;;;N;;;;;
+16805;BAMUM LETTER PHASE-A SHUENSHUET;Lo;0;L;;;;;N;;;;;
+16806;BAMUM LETTER PHASE-A TITA MFON;Lo;0;L;;;;;N;;;;;
+16807;BAMUM LETTER PHASE-A NZA MFON;Lo;0;L;;;;;N;;;;;
+16808;BAMUM LETTER PHASE-A SHINDA PA NJI;Lo;0;L;;;;;N;;;;;
+16809;BAMUM LETTER PHASE-A PON PA NJI PIPAEMGBIEE;Lo;0;L;;;;;N;;;;;
+1680A;BAMUM LETTER PHASE-A PON PA NJI PIPAEMBA;Lo;0;L;;;;;N;;;;;
+1680B;BAMUM LETTER PHASE-A MAEMBGBIEE;Lo;0;L;;;;;N;;;;;
+1680C;BAMUM LETTER PHASE-A TU MAEMBA;Lo;0;L;;;;;N;;;;;
+1680D;BAMUM LETTER PHASE-A NGANGU;Lo;0;L;;;;;N;;;;;
+1680E;BAMUM LETTER PHASE-A MAEMVEUX;Lo;0;L;;;;;N;;;;;
+1680F;BAMUM LETTER PHASE-A MANSUAE;Lo;0;L;;;;;N;;;;;
+16810;BAMUM LETTER PHASE-A MVEUAENGAM;Lo;0;L;;;;;N;;;;;
+16811;BAMUM LETTER PHASE-A SEUNYAM;Lo;0;L;;;;;N;;;;;
+16812;BAMUM LETTER PHASE-A NTOQPEN;Lo;0;L;;;;;N;;;;;
+16813;BAMUM LETTER PHASE-A KEUKEUTNDA;Lo;0;L;;;;;N;;;;;
+16814;BAMUM LETTER PHASE-A NKINDI;Lo;0;L;;;;;N;;;;;
+16815;BAMUM LETTER PHASE-A SUU;Lo;0;L;;;;;N;;;;;
+16816;BAMUM LETTER PHASE-A NGKUENZEUM;Lo;0;L;;;;;N;;;;;
+16817;BAMUM LETTER PHASE-A LAPAQ;Lo;0;L;;;;;N;;;;;
+16818;BAMUM LETTER PHASE-A LET KUT;Lo;0;L;;;;;N;;;;;
+16819;BAMUM LETTER PHASE-A NTAP MFAA;Lo;0;L;;;;;N;;;;;
+1681A;BAMUM LETTER PHASE-A MAEKEUP;Lo;0;L;;;;;N;;;;;
+1681B;BAMUM LETTER PHASE-A PASHAE;Lo;0;L;;;;;N;;;;;
+1681C;BAMUM LETTER PHASE-A GHEUAERAE;Lo;0;L;;;;;N;;;;;
+1681D;BAMUM LETTER PHASE-A PAMSHAE;Lo;0;L;;;;;N;;;;;
+1681E;BAMUM LETTER PHASE-A MON NGGEUAET;Lo;0;L;;;;;N;;;;;
+1681F;BAMUM LETTER PHASE-A NZUN MEUT;Lo;0;L;;;;;N;;;;;
+16820;BAMUM LETTER PHASE-A U YUQ NAE;Lo;0;L;;;;;N;;;;;
+16821;BAMUM LETTER PHASE-A GHEUAEGHEUAE;Lo;0;L;;;;;N;;;;;
+16822;BAMUM LETTER PHASE-A NTAP NTAA;Lo;0;L;;;;;N;;;;;
+16823;BAMUM LETTER PHASE-A SISA;Lo;0;L;;;;;N;;;;;
+16824;BAMUM LETTER PHASE-A MGBASA;Lo;0;L;;;;;N;;;;;
+16825;BAMUM LETTER PHASE-A MEUNJOMNDEUQ;Lo;0;L;;;;;N;;;;;
+16826;BAMUM LETTER PHASE-A MOOMPUQ;Lo;0;L;;;;;N;;;;;
+16827;BAMUM LETTER PHASE-A KAFA;Lo;0;L;;;;;N;;;;;
+16828;BAMUM LETTER PHASE-A PA LEERAEWA;Lo;0;L;;;;;N;;;;;
+16829;BAMUM LETTER PHASE-A NDA LEERAEWA;Lo;0;L;;;;;N;;;;;
+1682A;BAMUM LETTER PHASE-A PET;Lo;0;L;;;;;N;;;;;
+1682B;BAMUM LETTER PHASE-A MAEMKPEN;Lo;0;L;;;;;N;;;;;
+1682C;BAMUM LETTER PHASE-A NIKA;Lo;0;L;;;;;N;;;;;
+1682D;BAMUM LETTER PHASE-A PUP;Lo;0;L;;;;;N;;;;;
+1682E;BAMUM LETTER PHASE-A TUAEP;Lo;0;L;;;;;N;;;;;
+1682F;BAMUM LETTER PHASE-A LUAEP;Lo;0;L;;;;;N;;;;;
+16830;BAMUM LETTER PHASE-A SONJAM;Lo;0;L;;;;;N;;;;;
+16831;BAMUM LETTER PHASE-A TEUTEUWEN;Lo;0;L;;;;;N;;;;;
+16832;BAMUM LETTER PHASE-A MAENYI;Lo;0;L;;;;;N;;;;;
+16833;BAMUM LETTER PHASE-A KET;Lo;0;L;;;;;N;;;;;
+16834;BAMUM LETTER PHASE-A NDAANGGEUAET;Lo;0;L;;;;;N;;;;;
+16835;BAMUM LETTER PHASE-A KUOQ;Lo;0;L;;;;;N;;;;;
+16836;BAMUM LETTER PHASE-A MOOMEUT;Lo;0;L;;;;;N;;;;;
+16837;BAMUM LETTER PHASE-A SHUM;Lo;0;L;;;;;N;;;;;
+16838;BAMUM LETTER PHASE-A LOMMAE;Lo;0;L;;;;;N;;;;;
+16839;BAMUM LETTER PHASE-A FIRI;Lo;0;L;;;;;N;;;;;
+1683A;BAMUM LETTER PHASE-A ROM;Lo;0;L;;;;;N;;;;;
+1683B;BAMUM LETTER PHASE-A KPOQ;Lo;0;L;;;;;N;;;;;
+1683C;BAMUM LETTER PHASE-A SOQ;Lo;0;L;;;;;N;;;;;
+1683D;BAMUM LETTER PHASE-A MAP PIEET;Lo;0;L;;;;;N;;;;;
+1683E;BAMUM LETTER PHASE-A SHIRAE;Lo;0;L;;;;;N;;;;;
+1683F;BAMUM LETTER PHASE-A NTAP;Lo;0;L;;;;;N;;;;;
+16840;BAMUM LETTER PHASE-A SHOQ NSHUT YUM;Lo;0;L;;;;;N;;;;;
+16841;BAMUM LETTER PHASE-A NYIT MONGKEUAEQ;Lo;0;L;;;;;N;;;;;
+16842;BAMUM LETTER PHASE-A PAARAE;Lo;0;L;;;;;N;;;;;
+16843;BAMUM LETTER PHASE-A NKAARAE;Lo;0;L;;;;;N;;;;;
+16844;BAMUM LETTER PHASE-A UNKNOWN;Lo;0;L;;;;;N;;;;;
+16845;BAMUM LETTER PHASE-A NGGEN;Lo;0;L;;;;;N;;;;;
+16846;BAMUM LETTER PHASE-A MAESI;Lo;0;L;;;;;N;;;;;
+16847;BAMUM LETTER PHASE-A NJAM;Lo;0;L;;;;;N;;;;;
+16848;BAMUM LETTER PHASE-A MBANYI;Lo;0;L;;;;;N;;;;;
+16849;BAMUM LETTER PHASE-A NYET;Lo;0;L;;;;;N;;;;;
+1684A;BAMUM LETTER PHASE-A TEUAEN;Lo;0;L;;;;;N;;;;;
+1684B;BAMUM LETTER PHASE-A SOT;Lo;0;L;;;;;N;;;;;
+1684C;BAMUM LETTER PHASE-A PAAM;Lo;0;L;;;;;N;;;;;
+1684D;BAMUM LETTER PHASE-A NSHIEE;Lo;0;L;;;;;N;;;;;
+1684E;BAMUM LETTER PHASE-A MAEM;Lo;0;L;;;;;N;;;;;
+1684F;BAMUM LETTER PHASE-A NYI;Lo;0;L;;;;;N;;;;;
+16850;BAMUM LETTER PHASE-A KAQ;Lo;0;L;;;;;N;;;;;
+16851;BAMUM LETTER PHASE-A NSHA;Lo;0;L;;;;;N;;;;;
+16852;BAMUM LETTER PHASE-A VEE;Lo;0;L;;;;;N;;;;;
+16853;BAMUM LETTER PHASE-A LU;Lo;0;L;;;;;N;;;;;
+16854;BAMUM LETTER PHASE-A NEN;Lo;0;L;;;;;N;;;;;
+16855;BAMUM LETTER PHASE-A NAQ;Lo;0;L;;;;;N;;;;;
+16856;BAMUM LETTER PHASE-A MBAQ;Lo;0;L;;;;;N;;;;;
+16857;BAMUM LETTER PHASE-B NSHUET;Lo;0;L;;;;;N;;;;;
+16858;BAMUM LETTER PHASE-B TU MAEMGBIEE;Lo;0;L;;;;;N;;;;;
+16859;BAMUM LETTER PHASE-B SIEE;Lo;0;L;;;;;N;;;;;
+1685A;BAMUM LETTER PHASE-B SET TU;Lo;0;L;;;;;N;;;;;
+1685B;BAMUM LETTER PHASE-B LOM NTEUM;Lo;0;L;;;;;N;;;;;
+1685C;BAMUM LETTER PHASE-B MBA MAELEE;Lo;0;L;;;;;N;;;;;
+1685D;BAMUM LETTER PHASE-B KIEEM;Lo;0;L;;;;;N;;;;;
+1685E;BAMUM LETTER PHASE-B YEURAE;Lo;0;L;;;;;N;;;;;
+1685F;BAMUM LETTER PHASE-B MBAARAE;Lo;0;L;;;;;N;;;;;
+16860;BAMUM LETTER PHASE-B KAM;Lo;0;L;;;;;N;;;;;
+16861;BAMUM LETTER PHASE-B PEESHI;Lo;0;L;;;;;N;;;;;
+16862;BAMUM LETTER PHASE-B YAFU LEERAEWA;Lo;0;L;;;;;N;;;;;
+16863;BAMUM LETTER PHASE-B LAM NSHUT NYAM;Lo;0;L;;;;;N;;;;;
+16864;BAMUM LETTER PHASE-B NTIEE SHEUOQ;Lo;0;L;;;;;N;;;;;
+16865;BAMUM LETTER PHASE-B NDU NJAA;Lo;0;L;;;;;N;;;;;
+16866;BAMUM LETTER PHASE-B GHEUGHEUAEM;Lo;0;L;;;;;N;;;;;
+16867;BAMUM LETTER PHASE-B PIT;Lo;0;L;;;;;N;;;;;
+16868;BAMUM LETTER PHASE-B TU NSIEE;Lo;0;L;;;;;N;;;;;
+16869;BAMUM LETTER PHASE-B SHET NJAQ;Lo;0;L;;;;;N;;;;;
+1686A;BAMUM LETTER PHASE-B SHEUAEQTU;Lo;0;L;;;;;N;;;;;
+1686B;BAMUM LETTER PHASE-B MFON TEUAEQ;Lo;0;L;;;;;N;;;;;
+1686C;BAMUM LETTER PHASE-B MBIT MBAAKET;Lo;0;L;;;;;N;;;;;
+1686D;BAMUM LETTER PHASE-B NYI NTEUM;Lo;0;L;;;;;N;;;;;
+1686E;BAMUM LETTER PHASE-B KEUPUQ;Lo;0;L;;;;;N;;;;;
+1686F;BAMUM LETTER PHASE-B GHEUGHEN;Lo;0;L;;;;;N;;;;;
+16870;BAMUM LETTER PHASE-B KEUYEUX;Lo;0;L;;;;;N;;;;;
+16871;BAMUM LETTER PHASE-B LAANAE;Lo;0;L;;;;;N;;;;;
+16872;BAMUM LETTER PHASE-B PARUM;Lo;0;L;;;;;N;;;;;
+16873;BAMUM LETTER PHASE-B VEUM;Lo;0;L;;;;;N;;;;;
+16874;BAMUM LETTER PHASE-B NGKINDI MVOP;Lo;0;L;;;;;N;;;;;
+16875;BAMUM LETTER PHASE-B NGGEU MBU;Lo;0;L;;;;;N;;;;;
+16876;BAMUM LETTER PHASE-B WUAET;Lo;0;L;;;;;N;;;;;
+16877;BAMUM LETTER PHASE-B SAKEUAE;Lo;0;L;;;;;N;;;;;
+16878;BAMUM LETTER PHASE-B TAAM;Lo;0;L;;;;;N;;;;;
+16879;BAMUM LETTER PHASE-B MEUQ;Lo;0;L;;;;;N;;;;;
+1687A;BAMUM LETTER PHASE-B NGGUOQ;Lo;0;L;;;;;N;;;;;
+1687B;BAMUM LETTER PHASE-B NGGUOQ LARGE;Lo;0;L;;;;;N;;;;;
+1687C;BAMUM LETTER PHASE-B MFIYAQ;Lo;0;L;;;;;N;;;;;
+1687D;BAMUM LETTER PHASE-B SUE;Lo;0;L;;;;;N;;;;;
+1687E;BAMUM LETTER PHASE-B MBEURI;Lo;0;L;;;;;N;;;;;
+1687F;BAMUM LETTER PHASE-B MONTIEEN;Lo;0;L;;;;;N;;;;;
+16880;BAMUM LETTER PHASE-B NYAEMAE;Lo;0;L;;;;;N;;;;;
+16881;BAMUM LETTER PHASE-B PUNGAAM;Lo;0;L;;;;;N;;;;;
+16882;BAMUM LETTER PHASE-B MEUT NGGEET;Lo;0;L;;;;;N;;;;;
+16883;BAMUM LETTER PHASE-B FEUX;Lo;0;L;;;;;N;;;;;
+16884;BAMUM LETTER PHASE-B MBUOQ;Lo;0;L;;;;;N;;;;;
+16885;BAMUM LETTER PHASE-B FEE;Lo;0;L;;;;;N;;;;;
+16886;BAMUM LETTER PHASE-B KEUAEM;Lo;0;L;;;;;N;;;;;
+16887;BAMUM LETTER PHASE-B MA NJEUAENA;Lo;0;L;;;;;N;;;;;
+16888;BAMUM LETTER PHASE-B MA NJUQA;Lo;0;L;;;;;N;;;;;
+16889;BAMUM LETTER PHASE-B LET;Lo;0;L;;;;;N;;;;;
+1688A;BAMUM LETTER PHASE-B NGGAAM;Lo;0;L;;;;;N;;;;;
+1688B;BAMUM LETTER PHASE-B NSEN;Lo;0;L;;;;;N;;;;;
+1688C;BAMUM LETTER PHASE-B MA;Lo;0;L;;;;;N;;;;;
+1688D;BAMUM LETTER PHASE-B KIQ;Lo;0;L;;;;;N;;;;;
+1688E;BAMUM LETTER PHASE-B NGOM;Lo;0;L;;;;;N;;;;;
+1688F;BAMUM LETTER PHASE-C NGKUE MAEMBA;Lo;0;L;;;;;N;;;;;
+16890;BAMUM LETTER PHASE-C NZA;Lo;0;L;;;;;N;;;;;
+16891;BAMUM LETTER PHASE-C YUM;Lo;0;L;;;;;N;;;;;
+16892;BAMUM LETTER PHASE-C WANGKUOQ;Lo;0;L;;;;;N;;;;;
+16893;BAMUM LETTER PHASE-C NGGEN;Lo;0;L;;;;;N;;;;;
+16894;BAMUM LETTER PHASE-C NDEUAEREE;Lo;0;L;;;;;N;;;;;
+16895;BAMUM LETTER PHASE-C NGKAQ;Lo;0;L;;;;;N;;;;;
+16896;BAMUM LETTER PHASE-C GHARAE;Lo;0;L;;;;;N;;;;;
+16897;BAMUM LETTER PHASE-C MBEEKEET;Lo;0;L;;;;;N;;;;;
+16898;BAMUM LETTER PHASE-C GBAYI;Lo;0;L;;;;;N;;;;;
+16899;BAMUM LETTER PHASE-C NYIR MKPARAQ MEUN;Lo;0;L;;;;;N;;;;;
+1689A;BAMUM LETTER PHASE-C NTU MBIT;Lo;0;L;;;;;N;;;;;
+1689B;BAMUM LETTER PHASE-C MBEUM;Lo;0;L;;;;;N;;;;;
+1689C;BAMUM LETTER PHASE-C PIRIEEN;Lo;0;L;;;;;N;;;;;
+1689D;BAMUM LETTER PHASE-C NDOMBU;Lo;0;L;;;;;N;;;;;
+1689E;BAMUM LETTER PHASE-C MBAA CABBAGE-TREE;Lo;0;L;;;;;N;;;;;
+1689F;BAMUM LETTER PHASE-C KEUSHEUAEP;Lo;0;L;;;;;N;;;;;
+168A0;BAMUM LETTER PHASE-C GHAP;Lo;0;L;;;;;N;;;;;
+168A1;BAMUM LETTER PHASE-C KEUKAQ;Lo;0;L;;;;;N;;;;;
+168A2;BAMUM LETTER PHASE-C YU MUOMAE;Lo;0;L;;;;;N;;;;;
+168A3;BAMUM LETTER PHASE-C NZEUM;Lo;0;L;;;;;N;;;;;
+168A4;BAMUM LETTER PHASE-C MBUE;Lo;0;L;;;;;N;;;;;
+168A5;BAMUM LETTER PHASE-C NSEUAEN;Lo;0;L;;;;;N;;;;;
+168A6;BAMUM LETTER PHASE-C MBIT;Lo;0;L;;;;;N;;;;;
+168A7;BAMUM LETTER PHASE-C YEUQ;Lo;0;L;;;;;N;;;;;
+168A8;BAMUM LETTER PHASE-C KPARAQ;Lo;0;L;;;;;N;;;;;
+168A9;BAMUM LETTER PHASE-C KAA;Lo;0;L;;;;;N;;;;;
+168AA;BAMUM LETTER PHASE-C SEUX;Lo;0;L;;;;;N;;;;;
+168AB;BAMUM LETTER PHASE-C NDIDA;Lo;0;L;;;;;N;;;;;
+168AC;BAMUM LETTER PHASE-C TAASHAE;Lo;0;L;;;;;N;;;;;
+168AD;BAMUM LETTER PHASE-C NJUEQ;Lo;0;L;;;;;N;;;;;
+168AE;BAMUM LETTER PHASE-C TITA YUE;Lo;0;L;;;;;N;;;;;
+168AF;BAMUM LETTER PHASE-C SUAET;Lo;0;L;;;;;N;;;;;
+168B0;BAMUM LETTER PHASE-C NGGUAEN NYAM;Lo;0;L;;;;;N;;;;;
+168B1;BAMUM LETTER PHASE-C VEUX;Lo;0;L;;;;;N;;;;;
+168B2;BAMUM LETTER PHASE-C NANSANAQ;Lo;0;L;;;;;N;;;;;
+168B3;BAMUM LETTER PHASE-C MA KEUAERI;Lo;0;L;;;;;N;;;;;
+168B4;BAMUM LETTER PHASE-C NTAA;Lo;0;L;;;;;N;;;;;
+168B5;BAMUM LETTER PHASE-C NGGUON;Lo;0;L;;;;;N;;;;;
+168B6;BAMUM LETTER PHASE-C LAP;Lo;0;L;;;;;N;;;;;
+168B7;BAMUM LETTER PHASE-C MBIRIEEN;Lo;0;L;;;;;N;;;;;
+168B8;BAMUM LETTER PHASE-C MGBASAQ;Lo;0;L;;;;;N;;;;;
+168B9;BAMUM LETTER PHASE-C NTEUNGBA;Lo;0;L;;;;;N;;;;;
+168BA;BAMUM LETTER PHASE-C TEUTEUX;Lo;0;L;;;;;N;;;;;
+168BB;BAMUM LETTER PHASE-C NGGUM;Lo;0;L;;;;;N;;;;;
+168BC;BAMUM LETTER PHASE-C FUE;Lo;0;L;;;;;N;;;;;
+168BD;BAMUM LETTER PHASE-C NDEUT;Lo;0;L;;;;;N;;;;;
+168BE;BAMUM LETTER PHASE-C NSA;Lo;0;L;;;;;N;;;;;
+168BF;BAMUM LETTER PHASE-C NSHAQ;Lo;0;L;;;;;N;;;;;
+168C0;BAMUM LETTER PHASE-C BUNG;Lo;0;L;;;;;N;;;;;
+168C1;BAMUM LETTER PHASE-C VEUAEPEN;Lo;0;L;;;;;N;;;;;
+168C2;BAMUM LETTER PHASE-C MBERAE;Lo;0;L;;;;;N;;;;;
+168C3;BAMUM LETTER PHASE-C RU;Lo;0;L;;;;;N;;;;;
+168C4;BAMUM LETTER PHASE-C NJAEM;Lo;0;L;;;;;N;;;;;
+168C5;BAMUM LETTER PHASE-C LAM;Lo;0;L;;;;;N;;;;;
+168C6;BAMUM LETTER PHASE-C TITUAEP;Lo;0;L;;;;;N;;;;;
+168C7;BAMUM LETTER PHASE-C NSUOT NGOM;Lo;0;L;;;;;N;;;;;
+168C8;BAMUM LETTER PHASE-C NJEEEE;Lo;0;L;;;;;N;;;;;
+168C9;BAMUM LETTER PHASE-C KET;Lo;0;L;;;;;N;;;;;
+168CA;BAMUM LETTER PHASE-C NGGU;Lo;0;L;;;;;N;;;;;
+168CB;BAMUM LETTER PHASE-C MAESI;Lo;0;L;;;;;N;;;;;
+168CC;BAMUM LETTER PHASE-C MBUAEM;Lo;0;L;;;;;N;;;;;
+168CD;BAMUM LETTER PHASE-C LU;Lo;0;L;;;;;N;;;;;
+168CE;BAMUM LETTER PHASE-C KUT;Lo;0;L;;;;;N;;;;;
+168CF;BAMUM LETTER PHASE-C NJAM;Lo;0;L;;;;;N;;;;;
+168D0;BAMUM LETTER PHASE-C NGOM;Lo;0;L;;;;;N;;;;;
+168D1;BAMUM LETTER PHASE-C WUP;Lo;0;L;;;;;N;;;;;
+168D2;BAMUM LETTER PHASE-C NGGUEET;Lo;0;L;;;;;N;;;;;
+168D3;BAMUM LETTER PHASE-C NSOM;Lo;0;L;;;;;N;;;;;
+168D4;BAMUM LETTER PHASE-C NTEN;Lo;0;L;;;;;N;;;;;
+168D5;BAMUM LETTER PHASE-C KUOP NKAARAE;Lo;0;L;;;;;N;;;;;
+168D6;BAMUM LETTER PHASE-C NSUN;Lo;0;L;;;;;N;;;;;
+168D7;BAMUM LETTER PHASE-C NDAM;Lo;0;L;;;;;N;;;;;
+168D8;BAMUM LETTER PHASE-C MA NSIEE;Lo;0;L;;;;;N;;;;;
+168D9;BAMUM LETTER PHASE-C YAA;Lo;0;L;;;;;N;;;;;
+168DA;BAMUM LETTER PHASE-C NDAP;Lo;0;L;;;;;N;;;;;
+168DB;BAMUM LETTER PHASE-C SHUEQ;Lo;0;L;;;;;N;;;;;
+168DC;BAMUM LETTER PHASE-C SETFON;Lo;0;L;;;;;N;;;;;
+168DD;BAMUM LETTER PHASE-C MBI;Lo;0;L;;;;;N;;;;;
+168DE;BAMUM LETTER PHASE-C MAEMBA;Lo;0;L;;;;;N;;;;;
+168DF;BAMUM LETTER PHASE-C MBANYI;Lo;0;L;;;;;N;;;;;
+168E0;BAMUM LETTER PHASE-C KEUSEUX;Lo;0;L;;;;;N;;;;;
+168E1;BAMUM LETTER PHASE-C MBEUX;Lo;0;L;;;;;N;;;;;
+168E2;BAMUM LETTER PHASE-C KEUM;Lo;0;L;;;;;N;;;;;
+168E3;BAMUM LETTER PHASE-C MBAA PICKET;Lo;0;L;;;;;N;;;;;
+168E4;BAMUM LETTER PHASE-C YUWOQ;Lo;0;L;;;;;N;;;;;
+168E5;BAMUM LETTER PHASE-C NJEUX;Lo;0;L;;;;;N;;;;;
+168E6;BAMUM LETTER PHASE-C MIEE;Lo;0;L;;;;;N;;;;;
+168E7;BAMUM LETTER PHASE-C MUAE;Lo;0;L;;;;;N;;;;;
+168E8;BAMUM LETTER PHASE-C SHIQ;Lo;0;L;;;;;N;;;;;
+168E9;BAMUM LETTER PHASE-C KEN LAW;Lo;0;L;;;;;N;;;;;
+168EA;BAMUM LETTER PHASE-C KEN FATIGUE;Lo;0;L;;;;;N;;;;;
+168EB;BAMUM LETTER PHASE-C NGAQ;Lo;0;L;;;;;N;;;;;
+168EC;BAMUM LETTER PHASE-C NAQ;Lo;0;L;;;;;N;;;;;
+168ED;BAMUM LETTER PHASE-C LIQ;Lo;0;L;;;;;N;;;;;
+168EE;BAMUM LETTER PHASE-C PIN;Lo;0;L;;;;;N;;;;;
+168EF;BAMUM LETTER PHASE-C PEN;Lo;0;L;;;;;N;;;;;
+168F0;BAMUM LETTER PHASE-C TET;Lo;0;L;;;;;N;;;;;
+168F1;BAMUM LETTER PHASE-D MBUO;Lo;0;L;;;;;N;;;;;
+168F2;BAMUM LETTER PHASE-D WAP;Lo;0;L;;;;;N;;;;;
+168F3;BAMUM LETTER PHASE-D NJI;Lo;0;L;;;;;N;;;;;
+168F4;BAMUM LETTER PHASE-D MFON;Lo;0;L;;;;;N;;;;;
+168F5;BAMUM LETTER PHASE-D NJIEE;Lo;0;L;;;;;N;;;;;
+168F6;BAMUM LETTER PHASE-D LIEE;Lo;0;L;;;;;N;;;;;
+168F7;BAMUM LETTER PHASE-D NJEUT;Lo;0;L;;;;;N;;;;;
+168F8;BAMUM LETTER PHASE-D NSHEE;Lo;0;L;;;;;N;;;;;
+168F9;BAMUM LETTER PHASE-D NGGAAMAE;Lo;0;L;;;;;N;;;;;
+168FA;BAMUM LETTER PHASE-D NYAM;Lo;0;L;;;;;N;;;;;
+168FB;BAMUM LETTER PHASE-D WUAEN;Lo;0;L;;;;;N;;;;;
+168FC;BAMUM LETTER PHASE-D NGKUN;Lo;0;L;;;;;N;;;;;
+168FD;BAMUM LETTER PHASE-D SHEE;Lo;0;L;;;;;N;;;;;
+168FE;BAMUM LETTER PHASE-D NGKAP;Lo;0;L;;;;;N;;;;;
+168FF;BAMUM LETTER PHASE-D KEUAETMEUN;Lo;0;L;;;;;N;;;;;
+16900;BAMUM LETTER PHASE-D TEUT;Lo;0;L;;;;;N;;;;;
+16901;BAMUM LETTER PHASE-D SHEUAE;Lo;0;L;;;;;N;;;;;
+16902;BAMUM LETTER PHASE-D NJAP;Lo;0;L;;;;;N;;;;;
+16903;BAMUM LETTER PHASE-D SUE;Lo;0;L;;;;;N;;;;;
+16904;BAMUM LETTER PHASE-D KET;Lo;0;L;;;;;N;;;;;
+16905;BAMUM LETTER PHASE-D YAEMMAE;Lo;0;L;;;;;N;;;;;
+16906;BAMUM LETTER PHASE-D KUOM;Lo;0;L;;;;;N;;;;;
+16907;BAMUM LETTER PHASE-D SAP;Lo;0;L;;;;;N;;;;;
+16908;BAMUM LETTER PHASE-D MFEUT;Lo;0;L;;;;;N;;;;;
+16909;BAMUM LETTER PHASE-D NDEUX;Lo;0;L;;;;;N;;;;;
+1690A;BAMUM LETTER PHASE-D MALEERI;Lo;0;L;;;;;N;;;;;
+1690B;BAMUM LETTER PHASE-D MEUT;Lo;0;L;;;;;N;;;;;
+1690C;BAMUM LETTER PHASE-D SEUAEQ;Lo;0;L;;;;;N;;;;;
+1690D;BAMUM LETTER PHASE-D YEN;Lo;0;L;;;;;N;;;;;
+1690E;BAMUM LETTER PHASE-D NJEUAEM;Lo;0;L;;;;;N;;;;;
+1690F;BAMUM LETTER PHASE-D KEUOT MBUAE;Lo;0;L;;;;;N;;;;;
+16910;BAMUM LETTER PHASE-D NGKEURI;Lo;0;L;;;;;N;;;;;
+16911;BAMUM LETTER PHASE-D TU;Lo;0;L;;;;;N;;;;;
+16912;BAMUM LETTER PHASE-D GHAA;Lo;0;L;;;;;N;;;;;
+16913;BAMUM LETTER PHASE-D NGKYEE;Lo;0;L;;;;;N;;;;;
+16914;BAMUM LETTER PHASE-D FEUFEUAET;Lo;0;L;;;;;N;;;;;
+16915;BAMUM LETTER PHASE-D NDEE;Lo;0;L;;;;;N;;;;;
+16916;BAMUM LETTER PHASE-D MGBOFUM;Lo;0;L;;;;;N;;;;;
+16917;BAMUM LETTER PHASE-D LEUAEP;Lo;0;L;;;;;N;;;;;
+16918;BAMUM LETTER PHASE-D NDON;Lo;0;L;;;;;N;;;;;
+16919;BAMUM LETTER PHASE-D MONI;Lo;0;L;;;;;N;;;;;
+1691A;BAMUM LETTER PHASE-D MGBEUN;Lo;0;L;;;;;N;;;;;
+1691B;BAMUM LETTER PHASE-D PUUT;Lo;0;L;;;;;N;;;;;
+1691C;BAMUM LETTER PHASE-D MGBIEE;Lo;0;L;;;;;N;;;;;
+1691D;BAMUM LETTER PHASE-D MFO;Lo;0;L;;;;;N;;;;;
+1691E;BAMUM LETTER PHASE-D LUM;Lo;0;L;;;;;N;;;;;
+1691F;BAMUM LETTER PHASE-D NSIEEP;Lo;0;L;;;;;N;;;;;
+16920;BAMUM LETTER PHASE-D MBAA;Lo;0;L;;;;;N;;;;;
+16921;BAMUM LETTER PHASE-D KWAET;Lo;0;L;;;;;N;;;;;
+16922;BAMUM LETTER PHASE-D NYET;Lo;0;L;;;;;N;;;;;
+16923;BAMUM LETTER PHASE-D TEUAEN;Lo;0;L;;;;;N;;;;;
+16924;BAMUM LETTER PHASE-D SOT;Lo;0;L;;;;;N;;;;;
+16925;BAMUM LETTER PHASE-D YUWOQ;Lo;0;L;;;;;N;;;;;
+16926;BAMUM LETTER PHASE-D KEUM;Lo;0;L;;;;;N;;;;;
+16927;BAMUM LETTER PHASE-D RAEM;Lo;0;L;;;;;N;;;;;
+16928;BAMUM LETTER PHASE-D TEEEE;Lo;0;L;;;;;N;;;;;
+16929;BAMUM LETTER PHASE-D NGKEUAEQ;Lo;0;L;;;;;N;;;;;
+1692A;BAMUM LETTER PHASE-D MFEUAE;Lo;0;L;;;;;N;;;;;
+1692B;BAMUM LETTER PHASE-D NSIEET;Lo;0;L;;;;;N;;;;;
+1692C;BAMUM LETTER PHASE-D KEUP;Lo;0;L;;;;;N;;;;;
+1692D;BAMUM LETTER PHASE-D PIP;Lo;0;L;;;;;N;;;;;
+1692E;BAMUM LETTER PHASE-D PEUTAE;Lo;0;L;;;;;N;;;;;
+1692F;BAMUM LETTER PHASE-D NYUE;Lo;0;L;;;;;N;;;;;
+16930;BAMUM LETTER PHASE-D LET;Lo;0;L;;;;;N;;;;;
+16931;BAMUM LETTER PHASE-D NGGAAM;Lo;0;L;;;;;N;;;;;
+16932;BAMUM LETTER PHASE-D MFIEE;Lo;0;L;;;;;N;;;;;
+16933;BAMUM LETTER PHASE-D NGGWAEN;Lo;0;L;;;;;N;;;;;
+16934;BAMUM LETTER PHASE-D YUOM;Lo;0;L;;;;;N;;;;;
+16935;BAMUM LETTER PHASE-D PAP;Lo;0;L;;;;;N;;;;;
+16936;BAMUM LETTER PHASE-D YUOP;Lo;0;L;;;;;N;;;;;
+16937;BAMUM LETTER PHASE-D NDAM;Lo;0;L;;;;;N;;;;;
+16938;BAMUM LETTER PHASE-D NTEUM;Lo;0;L;;;;;N;;;;;
+16939;BAMUM LETTER PHASE-D SUAE;Lo;0;L;;;;;N;;;;;
+1693A;BAMUM LETTER PHASE-D KUN;Lo;0;L;;;;;N;;;;;
+1693B;BAMUM LETTER PHASE-D NGGEUX;Lo;0;L;;;;;N;;;;;
+1693C;BAMUM LETTER PHASE-D NGKIEE;Lo;0;L;;;;;N;;;;;
+1693D;BAMUM LETTER PHASE-D TUOT;Lo;0;L;;;;;N;;;;;
+1693E;BAMUM LETTER PHASE-D MEUN;Lo;0;L;;;;;N;;;;;
+1693F;BAMUM LETTER PHASE-D KUQ;Lo;0;L;;;;;N;;;;;
+16940;BAMUM LETTER PHASE-D NSUM;Lo;0;L;;;;;N;;;;;
+16941;BAMUM LETTER PHASE-D TEUN;Lo;0;L;;;;;N;;;;;
+16942;BAMUM LETTER PHASE-D MAENJET;Lo;0;L;;;;;N;;;;;
+16943;BAMUM LETTER PHASE-D NGGAP;Lo;0;L;;;;;N;;;;;
+16944;BAMUM LETTER PHASE-D LEUM;Lo;0;L;;;;;N;;;;;
+16945;BAMUM LETTER PHASE-D NGGUOM;Lo;0;L;;;;;N;;;;;
+16946;BAMUM LETTER PHASE-D NSHUT;Lo;0;L;;;;;N;;;;;
+16947;BAMUM LETTER PHASE-D NJUEQ;Lo;0;L;;;;;N;;;;;
+16948;BAMUM LETTER PHASE-D GHEUAE;Lo;0;L;;;;;N;;;;;
+16949;BAMUM LETTER PHASE-D KU;Lo;0;L;;;;;N;;;;;
+1694A;BAMUM LETTER PHASE-D REN OLD;Lo;0;L;;;;;N;;;;;
+1694B;BAMUM LETTER PHASE-D TAE;Lo;0;L;;;;;N;;;;;
+1694C;BAMUM LETTER PHASE-D TOQ;Lo;0;L;;;;;N;;;;;
+1694D;BAMUM LETTER PHASE-D NYI;Lo;0;L;;;;;N;;;;;
+1694E;BAMUM LETTER PHASE-D RII;Lo;0;L;;;;;N;;;;;
+1694F;BAMUM LETTER PHASE-D LEEEE;Lo;0;L;;;;;N;;;;;
+16950;BAMUM LETTER PHASE-D MEEEE;Lo;0;L;;;;;N;;;;;
+16951;BAMUM LETTER PHASE-D M;Lo;0;L;;;;;N;;;;;
+16952;BAMUM LETTER PHASE-D SUU;Lo;0;L;;;;;N;;;;;
+16953;BAMUM LETTER PHASE-D MU;Lo;0;L;;;;;N;;;;;
+16954;BAMUM LETTER PHASE-D SHII;Lo;0;L;;;;;N;;;;;
+16955;BAMUM LETTER PHASE-D SHEUX;Lo;0;L;;;;;N;;;;;
+16956;BAMUM LETTER PHASE-D KYEE;Lo;0;L;;;;;N;;;;;
+16957;BAMUM LETTER PHASE-D NU;Lo;0;L;;;;;N;;;;;
+16958;BAMUM LETTER PHASE-D SHU;Lo;0;L;;;;;N;;;;;
+16959;BAMUM LETTER PHASE-D NTEE;Lo;0;L;;;;;N;;;;;
+1695A;BAMUM LETTER PHASE-D PEE;Lo;0;L;;;;;N;;;;;
+1695B;BAMUM LETTER PHASE-D NI;Lo;0;L;;;;;N;;;;;
+1695C;BAMUM LETTER PHASE-D SHOQ;Lo;0;L;;;;;N;;;;;
+1695D;BAMUM LETTER PHASE-D PUQ;Lo;0;L;;;;;N;;;;;
+1695E;BAMUM LETTER PHASE-D MVOP;Lo;0;L;;;;;N;;;;;
+1695F;BAMUM LETTER PHASE-D LOQ;Lo;0;L;;;;;N;;;;;
+16960;BAMUM LETTER PHASE-D REN MUCH;Lo;0;L;;;;;N;;;;;
+16961;BAMUM LETTER PHASE-D TI;Lo;0;L;;;;;N;;;;;
+16962;BAMUM LETTER PHASE-D NTUU;Lo;0;L;;;;;N;;;;;
+16963;BAMUM LETTER PHASE-D MBAA SEVEN;Lo;0;L;;;;;N;;;;;
+16964;BAMUM LETTER PHASE-D SAQ;Lo;0;L;;;;;N;;;;;
+16965;BAMUM LETTER PHASE-D FAA;Lo;0;L;;;;;N;;;;;
+16966;BAMUM LETTER PHASE-E NDAP;Lo;0;L;;;;;N;;;;;
+16967;BAMUM LETTER PHASE-E TOON;Lo;0;L;;;;;N;;;;;
+16968;BAMUM LETTER PHASE-E MBEUM;Lo;0;L;;;;;N;;;;;
+16969;BAMUM LETTER PHASE-E LAP;Lo;0;L;;;;;N;;;;;
+1696A;BAMUM LETTER PHASE-E VOM;Lo;0;L;;;;;N;;;;;
+1696B;BAMUM LETTER PHASE-E LOON;Lo;0;L;;;;;N;;;;;
+1696C;BAMUM LETTER PHASE-E PAA;Lo;0;L;;;;;N;;;;;
+1696D;BAMUM LETTER PHASE-E SOM;Lo;0;L;;;;;N;;;;;
+1696E;BAMUM LETTER PHASE-E RAQ;Lo;0;L;;;;;N;;;;;
+1696F;BAMUM LETTER PHASE-E NSHUOP;Lo;0;L;;;;;N;;;;;
+16970;BAMUM LETTER PHASE-E NDUN;Lo;0;L;;;;;N;;;;;
+16971;BAMUM LETTER PHASE-E PUAE;Lo;0;L;;;;;N;;;;;
+16972;BAMUM LETTER PHASE-E TAM;Lo;0;L;;;;;N;;;;;
+16973;BAMUM LETTER PHASE-E NGKA;Lo;0;L;;;;;N;;;;;
+16974;BAMUM LETTER PHASE-E KPEUX;Lo;0;L;;;;;N;;;;;
+16975;BAMUM LETTER PHASE-E WUO;Lo;0;L;;;;;N;;;;;
+16976;BAMUM LETTER PHASE-E SEE;Lo;0;L;;;;;N;;;;;
+16977;BAMUM LETTER PHASE-E NGGEUAET;Lo;0;L;;;;;N;;;;;
+16978;BAMUM LETTER PHASE-E PAAM;Lo;0;L;;;;;N;;;;;
+16979;BAMUM LETTER PHASE-E TOO;Lo;0;L;;;;;N;;;;;
+1697A;BAMUM LETTER PHASE-E KUOP;Lo;0;L;;;;;N;;;;;
+1697B;BAMUM LETTER PHASE-E LOM;Lo;0;L;;;;;N;;;;;
+1697C;BAMUM LETTER PHASE-E NSHIEE;Lo;0;L;;;;;N;;;;;
+1697D;BAMUM LETTER PHASE-E NGOP;Lo;0;L;;;;;N;;;;;
+1697E;BAMUM LETTER PHASE-E MAEM;Lo;0;L;;;;;N;;;;;
+1697F;BAMUM LETTER PHASE-E NGKEUX;Lo;0;L;;;;;N;;;;;
+16980;BAMUM LETTER PHASE-E NGOQ;Lo;0;L;;;;;N;;;;;
+16981;BAMUM LETTER PHASE-E NSHUE;Lo;0;L;;;;;N;;;;;
+16982;BAMUM LETTER PHASE-E RIMGBA;Lo;0;L;;;;;N;;;;;
+16983;BAMUM LETTER PHASE-E NJEUX;Lo;0;L;;;;;N;;;;;
+16984;BAMUM LETTER PHASE-E PEEM;Lo;0;L;;;;;N;;;;;
+16985;BAMUM LETTER PHASE-E SAA;Lo;0;L;;;;;N;;;;;
+16986;BAMUM LETTER PHASE-E NGGURAE;Lo;0;L;;;;;N;;;;;
+16987;BAMUM LETTER PHASE-E MGBA;Lo;0;L;;;;;N;;;;;
+16988;BAMUM LETTER PHASE-E GHEUX;Lo;0;L;;;;;N;;;;;
+16989;BAMUM LETTER PHASE-E NGKEUAEM;Lo;0;L;;;;;N;;;;;
+1698A;BAMUM LETTER PHASE-E NJAEMLI;Lo;0;L;;;;;N;;;;;
+1698B;BAMUM LETTER PHASE-E MAP;Lo;0;L;;;;;N;;;;;
+1698C;BAMUM LETTER PHASE-E LOOT;Lo;0;L;;;;;N;;;;;
+1698D;BAMUM LETTER PHASE-E NGGEEEE;Lo;0;L;;;;;N;;;;;
+1698E;BAMUM LETTER PHASE-E NDIQ;Lo;0;L;;;;;N;;;;;
+1698F;BAMUM LETTER PHASE-E TAEN NTEUM;Lo;0;L;;;;;N;;;;;
+16990;BAMUM LETTER PHASE-E SET;Lo;0;L;;;;;N;;;;;
+16991;BAMUM LETTER PHASE-E PUM;Lo;0;L;;;;;N;;;;;
+16992;BAMUM LETTER PHASE-E NDAA SOFTNESS;Lo;0;L;;;;;N;;;;;
+16993;BAMUM LETTER PHASE-E NGGUAESHAE NYAM;Lo;0;L;;;;;N;;;;;
+16994;BAMUM LETTER PHASE-E YIEE;Lo;0;L;;;;;N;;;;;
+16995;BAMUM LETTER PHASE-E GHEUN;Lo;0;L;;;;;N;;;;;
+16996;BAMUM LETTER PHASE-E TUAE;Lo;0;L;;;;;N;;;;;
+16997;BAMUM LETTER PHASE-E YEUAE;Lo;0;L;;;;;N;;;;;
+16998;BAMUM LETTER PHASE-E PO;Lo;0;L;;;;;N;;;;;
+16999;BAMUM LETTER PHASE-E TUMAE;Lo;0;L;;;;;N;;;;;
+1699A;BAMUM LETTER PHASE-E KEUAE;Lo;0;L;;;;;N;;;;;
+1699B;BAMUM LETTER PHASE-E SUAEN;Lo;0;L;;;;;N;;;;;
+1699C;BAMUM LETTER PHASE-E TEUAEQ;Lo;0;L;;;;;N;;;;;
+1699D;BAMUM LETTER PHASE-E VEUAE;Lo;0;L;;;;;N;;;;;
+1699E;BAMUM LETTER PHASE-E WEUX;Lo;0;L;;;;;N;;;;;
+1699F;BAMUM LETTER PHASE-E LAAM;Lo;0;L;;;;;N;;;;;
+169A0;BAMUM LETTER PHASE-E PU;Lo;0;L;;;;;N;;;;;
+169A1;BAMUM LETTER PHASE-E TAAQ;Lo;0;L;;;;;N;;;;;
+169A2;BAMUM LETTER PHASE-E GHAAMAE;Lo;0;L;;;;;N;;;;;
+169A3;BAMUM LETTER PHASE-E NGEUREUT;Lo;0;L;;;;;N;;;;;
+169A4;BAMUM LETTER PHASE-E SHEUAEQ;Lo;0;L;;;;;N;;;;;
+169A5;BAMUM LETTER PHASE-E MGBEN;Lo;0;L;;;;;N;;;;;
+169A6;BAMUM LETTER PHASE-E MBEE;Lo;0;L;;;;;N;;;;;
+169A7;BAMUM LETTER PHASE-E NZAQ;Lo;0;L;;;;;N;;;;;
+169A8;BAMUM LETTER PHASE-E NKOM;Lo;0;L;;;;;N;;;;;
+169A9;BAMUM LETTER PHASE-E GBET;Lo;0;L;;;;;N;;;;;
+169AA;BAMUM LETTER PHASE-E TUM;Lo;0;L;;;;;N;;;;;
+169AB;BAMUM LETTER PHASE-E KUET;Lo;0;L;;;;;N;;;;;
+169AC;BAMUM LETTER PHASE-E YAP;Lo;0;L;;;;;N;;;;;
+169AD;BAMUM LETTER PHASE-E NYI CLEAVER;Lo;0;L;;;;;N;;;;;
+169AE;BAMUM LETTER PHASE-E YIT;Lo;0;L;;;;;N;;;;;
+169AF;BAMUM LETTER PHASE-E MFEUQ;Lo;0;L;;;;;N;;;;;
+169B0;BAMUM LETTER PHASE-E NDIAQ;Lo;0;L;;;;;N;;;;;
+169B1;BAMUM LETTER PHASE-E PIEEQ;Lo;0;L;;;;;N;;;;;
+169B2;BAMUM LETTER PHASE-E YUEQ;Lo;0;L;;;;;N;;;;;
+169B3;BAMUM LETTER PHASE-E LEUAEM;Lo;0;L;;;;;N;;;;;
+169B4;BAMUM LETTER PHASE-E FUE;Lo;0;L;;;;;N;;;;;
+169B5;BAMUM LETTER PHASE-E GBEUX;Lo;0;L;;;;;N;;;;;
+169B6;BAMUM LETTER PHASE-E NGKUP;Lo;0;L;;;;;N;;;;;
+169B7;BAMUM LETTER PHASE-E KET;Lo;0;L;;;;;N;;;;;
+169B8;BAMUM LETTER PHASE-E MAE;Lo;0;L;;;;;N;;;;;
+169B9;BAMUM LETTER PHASE-E NGKAAMI;Lo;0;L;;;;;N;;;;;
+169BA;BAMUM LETTER PHASE-E GHET;Lo;0;L;;;;;N;;;;;
+169BB;BAMUM LETTER PHASE-E FA;Lo;0;L;;;;;N;;;;;
+169BC;BAMUM LETTER PHASE-E NTUM;Lo;0;L;;;;;N;;;;;
+169BD;BAMUM LETTER PHASE-E PEUT;Lo;0;L;;;;;N;;;;;
+169BE;BAMUM LETTER PHASE-E YEUM;Lo;0;L;;;;;N;;;;;
+169BF;BAMUM LETTER PHASE-E NGGEUAE;Lo;0;L;;;;;N;;;;;
+169C0;BAMUM LETTER PHASE-E NYI BETWEEN;Lo;0;L;;;;;N;;;;;
+169C1;BAMUM LETTER PHASE-E NZUQ;Lo;0;L;;;;;N;;;;;
+169C2;BAMUM LETTER PHASE-E POON;Lo;0;L;;;;;N;;;;;
+169C3;BAMUM LETTER PHASE-E MIEE;Lo;0;L;;;;;N;;;;;
+169C4;BAMUM LETTER PHASE-E FUET;Lo;0;L;;;;;N;;;;;
+169C5;BAMUM LETTER PHASE-E NAE;Lo;0;L;;;;;N;;;;;
+169C6;BAMUM LETTER PHASE-E MUAE;Lo;0;L;;;;;N;;;;;
+169C7;BAMUM LETTER PHASE-E GHEUAE;Lo;0;L;;;;;N;;;;;
+169C8;BAMUM LETTER PHASE-E FU I;Lo;0;L;;;;;N;;;;;
+169C9;BAMUM LETTER PHASE-E MVI;Lo;0;L;;;;;N;;;;;
+169CA;BAMUM LETTER PHASE-E PUAQ;Lo;0;L;;;;;N;;;;;
+169CB;BAMUM LETTER PHASE-E NGKUM;Lo;0;L;;;;;N;;;;;
+169CC;BAMUM LETTER PHASE-E KUT;Lo;0;L;;;;;N;;;;;
+169CD;BAMUM LETTER PHASE-E PIET;Lo;0;L;;;;;N;;;;;
+169CE;BAMUM LETTER PHASE-E NTAP;Lo;0;L;;;;;N;;;;;
+169CF;BAMUM LETTER PHASE-E YEUAET;Lo;0;L;;;;;N;;;;;
+169D0;BAMUM LETTER PHASE-E NGGUP;Lo;0;L;;;;;N;;;;;
+169D1;BAMUM LETTER PHASE-E PA PEOPLE;Lo;0;L;;;;;N;;;;;
+169D2;BAMUM LETTER PHASE-E FU CALL;Lo;0;L;;;;;N;;;;;
+169D3;BAMUM LETTER PHASE-E FOM;Lo;0;L;;;;;N;;;;;
+169D4;BAMUM LETTER PHASE-E NJEE;Lo;0;L;;;;;N;;;;;
+169D5;BAMUM LETTER PHASE-E A;Lo;0;L;;;;;N;;;;;
+169D6;BAMUM LETTER PHASE-E TOQ;Lo;0;L;;;;;N;;;;;
+169D7;BAMUM LETTER PHASE-E O;Lo;0;L;;;;;N;;;;;
+169D8;BAMUM LETTER PHASE-E I;Lo;0;L;;;;;N;;;;;
+169D9;BAMUM LETTER PHASE-E LAQ;Lo;0;L;;;;;N;;;;;
+169DA;BAMUM LETTER PHASE-E PA PLURAL;Lo;0;L;;;;;N;;;;;
+169DB;BAMUM LETTER PHASE-E TAA;Lo;0;L;;;;;N;;;;;
+169DC;BAMUM LETTER PHASE-E TAQ;Lo;0;L;;;;;N;;;;;
+169DD;BAMUM LETTER PHASE-E NDAA MY HOUSE;Lo;0;L;;;;;N;;;;;
+169DE;BAMUM LETTER PHASE-E SHIQ;Lo;0;L;;;;;N;;;;;
+169DF;BAMUM LETTER PHASE-E YEUX;Lo;0;L;;;;;N;;;;;
+169E0;BAMUM LETTER PHASE-E NGUAE;Lo;0;L;;;;;N;;;;;
+169E1;BAMUM LETTER PHASE-E YUAEN;Lo;0;L;;;;;N;;;;;
+169E2;BAMUM LETTER PHASE-E YOQ SWIMMING;Lo;0;L;;;;;N;;;;;
+169E3;BAMUM LETTER PHASE-E YOQ COVER;Lo;0;L;;;;;N;;;;;
+169E4;BAMUM LETTER PHASE-E YUQ;Lo;0;L;;;;;N;;;;;
+169E5;BAMUM LETTER PHASE-E YUN;Lo;0;L;;;;;N;;;;;
+169E6;BAMUM LETTER PHASE-E KEUX;Lo;0;L;;;;;N;;;;;
+169E7;BAMUM LETTER PHASE-E PEUX;Lo;0;L;;;;;N;;;;;
+169E8;BAMUM LETTER PHASE-E NJEE EPOCH;Lo;0;L;;;;;N;;;;;
+169E9;BAMUM LETTER PHASE-E PUE;Lo;0;L;;;;;N;;;;;
+169EA;BAMUM LETTER PHASE-E WUE;Lo;0;L;;;;;N;;;;;
+169EB;BAMUM LETTER PHASE-E FEE;Lo;0;L;;;;;N;;;;;
+169EC;BAMUM LETTER PHASE-E VEE;Lo;0;L;;;;;N;;;;;
+169ED;BAMUM LETTER PHASE-E LU;Lo;0;L;;;;;N;;;;;
+169EE;BAMUM LETTER PHASE-E MI;Lo;0;L;;;;;N;;;;;
+169EF;BAMUM LETTER PHASE-E REUX;Lo;0;L;;;;;N;;;;;
+169F0;BAMUM LETTER PHASE-E RAE;Lo;0;L;;;;;N;;;;;
+169F1;BAMUM LETTER PHASE-E NGUAET;Lo;0;L;;;;;N;;;;;
+169F2;BAMUM LETTER PHASE-E NGA;Lo;0;L;;;;;N;;;;;
+169F3;BAMUM LETTER PHASE-E SHO;Lo;0;L;;;;;N;;;;;
+169F4;BAMUM LETTER PHASE-E SHOQ;Lo;0;L;;;;;N;;;;;
+169F5;BAMUM LETTER PHASE-E FU REMEDY;Lo;0;L;;;;;N;;;;;
+169F6;BAMUM LETTER PHASE-E NA;Lo;0;L;;;;;N;;;;;
+169F7;BAMUM LETTER PHASE-E PI;Lo;0;L;;;;;N;;;;;
+169F8;BAMUM LETTER PHASE-E LOQ;Lo;0;L;;;;;N;;;;;
+169F9;BAMUM LETTER PHASE-E KO;Lo;0;L;;;;;N;;;;;
+169FA;BAMUM LETTER PHASE-E MEN;Lo;0;L;;;;;N;;;;;
+169FB;BAMUM LETTER PHASE-E MA;Lo;0;L;;;;;N;;;;;
+169FC;BAMUM LETTER PHASE-E MAQ;Lo;0;L;;;;;N;;;;;
+169FD;BAMUM LETTER PHASE-E TEU;Lo;0;L;;;;;N;;;;;
+169FE;BAMUM LETTER PHASE-E KI;Lo;0;L;;;;;N;;;;;
+169FF;BAMUM LETTER PHASE-E MON;Lo;0;L;;;;;N;;;;;
+16A00;BAMUM LETTER PHASE-E TEN;Lo;0;L;;;;;N;;;;;
+16A01;BAMUM LETTER PHASE-E FAQ;Lo;0;L;;;;;N;;;;;
+16A02;BAMUM LETTER PHASE-E GHOM;Lo;0;L;;;;;N;;;;;
+16A03;BAMUM LETTER PHASE-F KA;Lo;0;L;;;;;N;;;;;
+16A04;BAMUM LETTER PHASE-F U;Lo;0;L;;;;;N;;;;;
+16A05;BAMUM LETTER PHASE-F KU;Lo;0;L;;;;;N;;;;;
+16A06;BAMUM LETTER PHASE-F EE;Lo;0;L;;;;;N;;;;;
+16A07;BAMUM LETTER PHASE-F REE;Lo;0;L;;;;;N;;;;;
+16A08;BAMUM LETTER PHASE-F TAE;Lo;0;L;;;;;N;;;;;
+16A09;BAMUM LETTER PHASE-F NYI;Lo;0;L;;;;;N;;;;;
+16A0A;BAMUM LETTER PHASE-F LA;Lo;0;L;;;;;N;;;;;
+16A0B;BAMUM LETTER PHASE-F RII;Lo;0;L;;;;;N;;;;;
+16A0C;BAMUM LETTER PHASE-F RIEE;Lo;0;L;;;;;N;;;;;
+16A0D;BAMUM LETTER PHASE-F MEEEE;Lo;0;L;;;;;N;;;;;
+16A0E;BAMUM LETTER PHASE-F TAA;Lo;0;L;;;;;N;;;;;
+16A0F;BAMUM LETTER PHASE-F NDAA;Lo;0;L;;;;;N;;;;;
+16A10;BAMUM LETTER PHASE-F NJAEM;Lo;0;L;;;;;N;;;;;
+16A11;BAMUM LETTER PHASE-F M;Lo;0;L;;;;;N;;;;;
+16A12;BAMUM LETTER PHASE-F SUU;Lo;0;L;;;;;N;;;;;
+16A13;BAMUM LETTER PHASE-F SHII;Lo;0;L;;;;;N;;;;;
+16A14;BAMUM LETTER PHASE-F SI;Lo;0;L;;;;;N;;;;;
+16A15;BAMUM LETTER PHASE-F SEUX;Lo;0;L;;;;;N;;;;;
+16A16;BAMUM LETTER PHASE-F KYEE;Lo;0;L;;;;;N;;;;;
+16A17;BAMUM LETTER PHASE-F KET;Lo;0;L;;;;;N;;;;;
+16A18;BAMUM LETTER PHASE-F NUAE;Lo;0;L;;;;;N;;;;;
+16A19;BAMUM LETTER PHASE-F NU;Lo;0;L;;;;;N;;;;;
+16A1A;BAMUM LETTER PHASE-F NJUAE;Lo;0;L;;;;;N;;;;;
+16A1B;BAMUM LETTER PHASE-F YOQ;Lo;0;L;;;;;N;;;;;
+16A1C;BAMUM LETTER PHASE-F SHU;Lo;0;L;;;;;N;;;;;
+16A1D;BAMUM LETTER PHASE-F YA;Lo;0;L;;;;;N;;;;;
+16A1E;BAMUM LETTER PHASE-F NSHA;Lo;0;L;;;;;N;;;;;
+16A1F;BAMUM LETTER PHASE-F PEUX;Lo;0;L;;;;;N;;;;;
+16A20;BAMUM LETTER PHASE-F NTEE;Lo;0;L;;;;;N;;;;;
+16A21;BAMUM LETTER PHASE-F WUE;Lo;0;L;;;;;N;;;;;
+16A22;BAMUM LETTER PHASE-F PEE;Lo;0;L;;;;;N;;;;;
+16A23;BAMUM LETTER PHASE-F RU;Lo;0;L;;;;;N;;;;;
+16A24;BAMUM LETTER PHASE-F NI;Lo;0;L;;;;;N;;;;;
+16A25;BAMUM LETTER PHASE-F REUX;Lo;0;L;;;;;N;;;;;
+16A26;BAMUM LETTER PHASE-F KEN;Lo;0;L;;;;;N;;;;;
+16A27;BAMUM LETTER PHASE-F NGKWAEN;Lo;0;L;;;;;N;;;;;
+16A28;BAMUM LETTER PHASE-F NGGA;Lo;0;L;;;;;N;;;;;
+16A29;BAMUM LETTER PHASE-F SHO;Lo;0;L;;;;;N;;;;;
+16A2A;BAMUM LETTER PHASE-F PUAE;Lo;0;L;;;;;N;;;;;
+16A2B;BAMUM LETTER PHASE-F FOM;Lo;0;L;;;;;N;;;;;
+16A2C;BAMUM LETTER PHASE-F WA;Lo;0;L;;;;;N;;;;;
+16A2D;BAMUM LETTER PHASE-F LI;Lo;0;L;;;;;N;;;;;
+16A2E;BAMUM LETTER PHASE-F LOQ;Lo;0;L;;;;;N;;;;;
+16A2F;BAMUM LETTER PHASE-F KO;Lo;0;L;;;;;N;;;;;
+16A30;BAMUM LETTER PHASE-F MBEN;Lo;0;L;;;;;N;;;;;
+16A31;BAMUM LETTER PHASE-F REN;Lo;0;L;;;;;N;;;;;
+16A32;BAMUM LETTER PHASE-F MA;Lo;0;L;;;;;N;;;;;
+16A33;BAMUM LETTER PHASE-F MO;Lo;0;L;;;;;N;;;;;
+16A34;BAMUM LETTER PHASE-F MBAA;Lo;0;L;;;;;N;;;;;
+16A35;BAMUM LETTER PHASE-F TET;Lo;0;L;;;;;N;;;;;
+16A36;BAMUM LETTER PHASE-F KPA;Lo;0;L;;;;;N;;;;;
+16A37;BAMUM LETTER PHASE-F SAMBA;Lo;0;L;;;;;N;;;;;
+16A38;BAMUM LETTER PHASE-F VUEQ;Lo;0;L;;;;;N;;;;;
+16A40;MRO LETTER TA;Lo;0;L;;;;;N;;;;;
+16A41;MRO LETTER NGI;Lo;0;L;;;;;N;;;;;
+16A42;MRO LETTER YO;Lo;0;L;;;;;N;;;;;
+16A43;MRO LETTER MIM;Lo;0;L;;;;;N;;;;;
+16A44;MRO LETTER BA;Lo;0;L;;;;;N;;;;;
+16A45;MRO LETTER DA;Lo;0;L;;;;;N;;;;;
+16A46;MRO LETTER A;Lo;0;L;;;;;N;;;;;
+16A47;MRO LETTER PHI;Lo;0;L;;;;;N;;;;;
+16A48;MRO LETTER KHAI;Lo;0;L;;;;;N;;;;;
+16A49;MRO LETTER HAO;Lo;0;L;;;;;N;;;;;
+16A4A;MRO LETTER DAI;Lo;0;L;;;;;N;;;;;
+16A4B;MRO LETTER CHU;Lo;0;L;;;;;N;;;;;
+16A4C;MRO LETTER KEAAE;Lo;0;L;;;;;N;;;;;
+16A4D;MRO LETTER OL;Lo;0;L;;;;;N;;;;;
+16A4E;MRO LETTER MAEM;Lo;0;L;;;;;N;;;;;
+16A4F;MRO LETTER NIN;Lo;0;L;;;;;N;;;;;
+16A50;MRO LETTER PA;Lo;0;L;;;;;N;;;;;
+16A51;MRO LETTER OO;Lo;0;L;;;;;N;;;;;
+16A52;MRO LETTER O;Lo;0;L;;;;;N;;;;;
+16A53;MRO LETTER RO;Lo;0;L;;;;;N;;;;;
+16A54;MRO LETTER SHI;Lo;0;L;;;;;N;;;;;
+16A55;MRO LETTER THEA;Lo;0;L;;;;;N;;;;;
+16A56;MRO LETTER EA;Lo;0;L;;;;;N;;;;;
+16A57;MRO LETTER WA;Lo;0;L;;;;;N;;;;;
+16A58;MRO LETTER E;Lo;0;L;;;;;N;;;;;
+16A59;MRO LETTER KO;Lo;0;L;;;;;N;;;;;
+16A5A;MRO LETTER LAN;Lo;0;L;;;;;N;;;;;
+16A5B;MRO LETTER LA;Lo;0;L;;;;;N;;;;;
+16A5C;MRO LETTER HAI;Lo;0;L;;;;;N;;;;;
+16A5D;MRO LETTER RI;Lo;0;L;;;;;N;;;;;
+16A5E;MRO LETTER TEK;Lo;0;L;;;;;N;;;;;
+16A60;MRO DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+16A61;MRO DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+16A62;MRO DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+16A63;MRO DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+16A64;MRO DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+16A65;MRO DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+16A66;MRO DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+16A67;MRO DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+16A68;MRO DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+16A69;MRO DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+16A6E;MRO DANDA;Po;0;L;;;;;N;;;;;
+16A6F;MRO DOUBLE DANDA;Po;0;L;;;;;N;;;;;
+16AD0;BASSA VAH LETTER ENNI;Lo;0;L;;;;;N;;;;;
+16AD1;BASSA VAH LETTER KA;Lo;0;L;;;;;N;;;;;
+16AD2;BASSA VAH LETTER SE;Lo;0;L;;;;;N;;;;;
+16AD3;BASSA VAH LETTER FA;Lo;0;L;;;;;N;;;;;
+16AD4;BASSA VAH LETTER MBE;Lo;0;L;;;;;N;;;;;
+16AD5;BASSA VAH LETTER YIE;Lo;0;L;;;;;N;;;;;
+16AD6;BASSA VAH LETTER GAH;Lo;0;L;;;;;N;;;;;
+16AD7;BASSA VAH LETTER DHII;Lo;0;L;;;;;N;;;;;
+16AD8;BASSA VAH LETTER KPAH;Lo;0;L;;;;;N;;;;;
+16AD9;BASSA VAH LETTER JO;Lo;0;L;;;;;N;;;;;
+16ADA;BASSA VAH LETTER HWAH;Lo;0;L;;;;;N;;;;;
+16ADB;BASSA VAH LETTER WA;Lo;0;L;;;;;N;;;;;
+16ADC;BASSA VAH LETTER ZO;Lo;0;L;;;;;N;;;;;
+16ADD;BASSA VAH LETTER GBU;Lo;0;L;;;;;N;;;;;
+16ADE;BASSA VAH LETTER DO;Lo;0;L;;;;;N;;;;;
+16ADF;BASSA VAH LETTER CE;Lo;0;L;;;;;N;;;;;
+16AE0;BASSA VAH LETTER UWU;Lo;0;L;;;;;N;;;;;
+16AE1;BASSA VAH LETTER TO;Lo;0;L;;;;;N;;;;;
+16AE2;BASSA VAH LETTER BA;Lo;0;L;;;;;N;;;;;
+16AE3;BASSA VAH LETTER VU;Lo;0;L;;;;;N;;;;;
+16AE4;BASSA VAH LETTER YEIN;Lo;0;L;;;;;N;;;;;
+16AE5;BASSA VAH LETTER PA;Lo;0;L;;;;;N;;;;;
+16AE6;BASSA VAH LETTER WADDA;Lo;0;L;;;;;N;;;;;
+16AE7;BASSA VAH LETTER A;Lo;0;L;;;;;N;;;;;
+16AE8;BASSA VAH LETTER O;Lo;0;L;;;;;N;;;;;
+16AE9;BASSA VAH LETTER OO;Lo;0;L;;;;;N;;;;;
+16AEA;BASSA VAH LETTER U;Lo;0;L;;;;;N;;;;;
+16AEB;BASSA VAH LETTER EE;Lo;0;L;;;;;N;;;;;
+16AEC;BASSA VAH LETTER E;Lo;0;L;;;;;N;;;;;
+16AED;BASSA VAH LETTER I;Lo;0;L;;;;;N;;;;;
+16AF0;BASSA VAH COMBINING HIGH TONE;Mn;1;NSM;;;;;N;;;;;
+16AF1;BASSA VAH COMBINING LOW TONE;Mn;1;NSM;;;;;N;;;;;
+16AF2;BASSA VAH COMBINING MID TONE;Mn;1;NSM;;;;;N;;;;;
+16AF3;BASSA VAH COMBINING LOW-MID TONE;Mn;1;NSM;;;;;N;;;;;
+16AF4;BASSA VAH COMBINING HIGH-LOW TONE;Mn;1;NSM;;;;;N;;;;;
+16AF5;BASSA VAH FULL STOP;Po;0;L;;;;;N;;;;;
+16B00;PAHAWH HMONG VOWEL KEEB;Lo;0;L;;;;;N;;;;;
+16B01;PAHAWH HMONG VOWEL KEEV;Lo;0;L;;;;;N;;;;;
+16B02;PAHAWH HMONG VOWEL KIB;Lo;0;L;;;;;N;;;;;
+16B03;PAHAWH HMONG VOWEL KIV;Lo;0;L;;;;;N;;;;;
+16B04;PAHAWH HMONG VOWEL KAUB;Lo;0;L;;;;;N;;;;;
+16B05;PAHAWH HMONG VOWEL KAUV;Lo;0;L;;;;;N;;;;;
+16B06;PAHAWH HMONG VOWEL KUB;Lo;0;L;;;;;N;;;;;
+16B07;PAHAWH HMONG VOWEL KUV;Lo;0;L;;;;;N;;;;;
+16B08;PAHAWH HMONG VOWEL KEB;Lo;0;L;;;;;N;;;;;
+16B09;PAHAWH HMONG VOWEL KEV;Lo;0;L;;;;;N;;;;;
+16B0A;PAHAWH HMONG VOWEL KAIB;Lo;0;L;;;;;N;;;;;
+16B0B;PAHAWH HMONG VOWEL KAIV;Lo;0;L;;;;;N;;;;;
+16B0C;PAHAWH HMONG VOWEL KOOB;Lo;0;L;;;;;N;;;;;
+16B0D;PAHAWH HMONG VOWEL KOOV;Lo;0;L;;;;;N;;;;;
+16B0E;PAHAWH HMONG VOWEL KAWB;Lo;0;L;;;;;N;;;;;
+16B0F;PAHAWH HMONG VOWEL KAWV;Lo;0;L;;;;;N;;;;;
+16B10;PAHAWH HMONG VOWEL KUAB;Lo;0;L;;;;;N;;;;;
+16B11;PAHAWH HMONG VOWEL KUAV;Lo;0;L;;;;;N;;;;;
+16B12;PAHAWH HMONG VOWEL KOB;Lo;0;L;;;;;N;;;;;
+16B13;PAHAWH HMONG VOWEL KOV;Lo;0;L;;;;;N;;;;;
+16B14;PAHAWH HMONG VOWEL KIAB;Lo;0;L;;;;;N;;;;;
+16B15;PAHAWH HMONG VOWEL KIAV;Lo;0;L;;;;;N;;;;;
+16B16;PAHAWH HMONG VOWEL KAB;Lo;0;L;;;;;N;;;;;
+16B17;PAHAWH HMONG VOWEL KAV;Lo;0;L;;;;;N;;;;;
+16B18;PAHAWH HMONG VOWEL KWB;Lo;0;L;;;;;N;;;;;
+16B19;PAHAWH HMONG VOWEL KWV;Lo;0;L;;;;;N;;;;;
+16B1A;PAHAWH HMONG VOWEL KAAB;Lo;0;L;;;;;N;;;;;
+16B1B;PAHAWH HMONG VOWEL KAAV;Lo;0;L;;;;;N;;;;;
+16B1C;PAHAWH HMONG CONSONANT VAU;Lo;0;L;;;;;N;;;;;
+16B1D;PAHAWH HMONG CONSONANT NTSAU;Lo;0;L;;;;;N;;;;;
+16B1E;PAHAWH HMONG CONSONANT LAU;Lo;0;L;;;;;N;;;;;
+16B1F;PAHAWH HMONG CONSONANT HAU;Lo;0;L;;;;;N;;;;;
+16B20;PAHAWH HMONG CONSONANT NLAU;Lo;0;L;;;;;N;;;;;
+16B21;PAHAWH HMONG CONSONANT RAU;Lo;0;L;;;;;N;;;;;
+16B22;PAHAWH HMONG CONSONANT NKAU;Lo;0;L;;;;;N;;;;;
+16B23;PAHAWH HMONG CONSONANT QHAU;Lo;0;L;;;;;N;;;;;
+16B24;PAHAWH HMONG CONSONANT YAU;Lo;0;L;;;;;N;;;;;
+16B25;PAHAWH HMONG CONSONANT HLAU;Lo;0;L;;;;;N;;;;;
+16B26;PAHAWH HMONG CONSONANT MAU;Lo;0;L;;;;;N;;;;;
+16B27;PAHAWH HMONG CONSONANT CHAU;Lo;0;L;;;;;N;;;;;
+16B28;PAHAWH HMONG CONSONANT NCHAU;Lo;0;L;;;;;N;;;;;
+16B29;PAHAWH HMONG CONSONANT HNAU;Lo;0;L;;;;;N;;;;;
+16B2A;PAHAWH HMONG CONSONANT PLHAU;Lo;0;L;;;;;N;;;;;
+16B2B;PAHAWH HMONG CONSONANT NTHAU;Lo;0;L;;;;;N;;;;;
+16B2C;PAHAWH HMONG CONSONANT NAU;Lo;0;L;;;;;N;;;;;
+16B2D;PAHAWH HMONG CONSONANT AU;Lo;0;L;;;;;N;;;;;
+16B2E;PAHAWH HMONG CONSONANT XAU;Lo;0;L;;;;;N;;;;;
+16B2F;PAHAWH HMONG CONSONANT CAU;Lo;0;L;;;;;N;;;;;
+16B30;PAHAWH HMONG MARK CIM TUB;Mn;230;NSM;;;;;N;;;;;
+16B31;PAHAWH HMONG MARK CIM SO;Mn;230;NSM;;;;;N;;;;;
+16B32;PAHAWH HMONG MARK CIM KES;Mn;230;NSM;;;;;N;;;;;
+16B33;PAHAWH HMONG MARK CIM KHAV;Mn;230;NSM;;;;;N;;;;;
+16B34;PAHAWH HMONG MARK CIM SUAM;Mn;230;NSM;;;;;N;;;;;
+16B35;PAHAWH HMONG MARK CIM HOM;Mn;230;NSM;;;;;N;;;;;
+16B36;PAHAWH HMONG MARK CIM TAUM;Mn;230;NSM;;;;;N;;;;;
+16B37;PAHAWH HMONG SIGN VOS THOM;Po;0;L;;;;;N;;;;;
+16B38;PAHAWH HMONG SIGN VOS TSHAB CEEB;Po;0;L;;;;;N;;;;;
+16B39;PAHAWH HMONG SIGN CIM CHEEM;Po;0;L;;;;;N;;;;;
+16B3A;PAHAWH HMONG SIGN VOS THIAB;Po;0;L;;;;;N;;;;;
+16B3B;PAHAWH HMONG SIGN VOS FEEM;Po;0;L;;;;;N;;;;;
+16B3C;PAHAWH HMONG SIGN XYEEM NTXIV;So;0;L;;;;;N;;;;;
+16B3D;PAHAWH HMONG SIGN XYEEM RHO;So;0;L;;;;;N;;;;;
+16B3E;PAHAWH HMONG SIGN XYEEM TOV;So;0;L;;;;;N;;;;;
+16B3F;PAHAWH HMONG SIGN XYEEM FAIB;So;0;L;;;;;N;;;;;
+16B40;PAHAWH HMONG SIGN VOS SEEV;Lm;0;L;;;;;N;;;;;
+16B41;PAHAWH HMONG SIGN MEEJ SUAB;Lm;0;L;;;;;N;;;;;
+16B42;PAHAWH HMONG SIGN VOS NRUA;Lm;0;L;;;;;N;;;;;
+16B43;PAHAWH HMONG SIGN IB YAM;Lm;0;L;;;;;N;;;;;
+16B44;PAHAWH HMONG SIGN XAUS;Po;0;L;;;;;N;;;;;
+16B45;PAHAWH HMONG SIGN CIM TSOV ROG;So;0;L;;;;;N;;;;;
+16B50;PAHAWH HMONG DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+16B51;PAHAWH HMONG DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+16B52;PAHAWH HMONG DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+16B53;PAHAWH HMONG DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+16B54;PAHAWH HMONG DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+16B55;PAHAWH HMONG DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+16B56;PAHAWH HMONG DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+16B57;PAHAWH HMONG DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+16B58;PAHAWH HMONG DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+16B59;PAHAWH HMONG DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+16B5B;PAHAWH HMONG NUMBER TENS;No;0;L;;;;10;N;;;;;
+16B5C;PAHAWH HMONG NUMBER HUNDREDS;No;0;L;;;;100;N;;;;;
+16B5D;PAHAWH HMONG NUMBER TEN THOUSANDS;No;0;L;;;;10000;N;;;;;
+16B5E;PAHAWH HMONG NUMBER MILLIONS;No;0;L;;;;1000000;N;;;;;
+16B5F;PAHAWH HMONG NUMBER HUNDRED MILLIONS;No;0;L;;;;100000000;N;;;;;
+16B60;PAHAWH HMONG NUMBER TEN BILLIONS;No;0;L;;;;10000000000;N;;;;;
+16B61;PAHAWH HMONG NUMBER TRILLIONS;No;0;L;;;;1000000000000;N;;;;;
+16B63;PAHAWH HMONG SIGN VOS LUB;Lo;0;L;;;;;N;;;;;
+16B64;PAHAWH HMONG SIGN XYOO;Lo;0;L;;;;;N;;;;;
+16B65;PAHAWH HMONG SIGN HLI;Lo;0;L;;;;;N;;;;;
+16B66;PAHAWH HMONG SIGN THIRD-STAGE HLI;Lo;0;L;;;;;N;;;;;
+16B67;PAHAWH HMONG SIGN ZWJ THAJ;Lo;0;L;;;;;N;;;;;
+16B68;PAHAWH HMONG SIGN HNUB;Lo;0;L;;;;;N;;;;;
+16B69;PAHAWH HMONG SIGN NQIG;Lo;0;L;;;;;N;;;;;
+16B6A;PAHAWH HMONG SIGN XIAB;Lo;0;L;;;;;N;;;;;
+16B6B;PAHAWH HMONG SIGN NTUJ;Lo;0;L;;;;;N;;;;;
+16B6C;PAHAWH HMONG SIGN AV;Lo;0;L;;;;;N;;;;;
+16B6D;PAHAWH HMONG SIGN TXHEEJ CEEV;Lo;0;L;;;;;N;;;;;
+16B6E;PAHAWH HMONG SIGN MEEJ TSEEB;Lo;0;L;;;;;N;;;;;
+16B6F;PAHAWH HMONG SIGN TAU;Lo;0;L;;;;;N;;;;;
+16B70;PAHAWH HMONG SIGN LOS;Lo;0;L;;;;;N;;;;;
+16B71;PAHAWH HMONG SIGN MUS;Lo;0;L;;;;;N;;;;;
+16B72;PAHAWH HMONG SIGN CIM HAIS LUS NTOG NTOG;Lo;0;L;;;;;N;;;;;
+16B73;PAHAWH HMONG SIGN CIM CUAM TSHOOJ;Lo;0;L;;;;;N;;;;;
+16B74;PAHAWH HMONG SIGN CIM TXWV;Lo;0;L;;;;;N;;;;;
+16B75;PAHAWH HMONG SIGN CIM TXWV CHWV;Lo;0;L;;;;;N;;;;;
+16B76;PAHAWH HMONG SIGN CIM PUB DAWB;Lo;0;L;;;;;N;;;;;
+16B77;PAHAWH HMONG SIGN CIM NRES TOS;Lo;0;L;;;;;N;;;;;
+16B7D;PAHAWH HMONG CLAN SIGN TSHEEJ;Lo;0;L;;;;;N;;;;;
+16B7E;PAHAWH HMONG CLAN SIGN YEEG;Lo;0;L;;;;;N;;;;;
+16B7F;PAHAWH HMONG CLAN SIGN LIS;Lo;0;L;;;;;N;;;;;
+16B80;PAHAWH HMONG CLAN SIGN LAUJ;Lo;0;L;;;;;N;;;;;
+16B81;PAHAWH HMONG CLAN SIGN XYOOJ;Lo;0;L;;;;;N;;;;;
+16B82;PAHAWH HMONG CLAN SIGN KOO;Lo;0;L;;;;;N;;;;;
+16B83;PAHAWH HMONG CLAN SIGN HAWJ;Lo;0;L;;;;;N;;;;;
+16B84;PAHAWH HMONG CLAN SIGN MUAS;Lo;0;L;;;;;N;;;;;
+16B85;PAHAWH HMONG CLAN SIGN THOJ;Lo;0;L;;;;;N;;;;;
+16B86;PAHAWH HMONG CLAN SIGN TSAB;Lo;0;L;;;;;N;;;;;
+16B87;PAHAWH HMONG CLAN SIGN PHAB;Lo;0;L;;;;;N;;;;;
+16B88;PAHAWH HMONG CLAN SIGN KHAB;Lo;0;L;;;;;N;;;;;
+16B89;PAHAWH HMONG CLAN SIGN HAM;Lo;0;L;;;;;N;;;;;
+16B8A;PAHAWH HMONG CLAN SIGN VAJ;Lo;0;L;;;;;N;;;;;
+16B8B;PAHAWH HMONG CLAN SIGN FAJ;Lo;0;L;;;;;N;;;;;
+16B8C;PAHAWH HMONG CLAN SIGN YAJ;Lo;0;L;;;;;N;;;;;
+16B8D;PAHAWH HMONG CLAN SIGN TSWB;Lo;0;L;;;;;N;;;;;
+16B8E;PAHAWH HMONG CLAN SIGN KWM;Lo;0;L;;;;;N;;;;;
+16B8F;PAHAWH HMONG CLAN SIGN VWJ;Lo;0;L;;;;;N;;;;;
+16F00;MIAO LETTER PA;Lo;0;L;;;;;N;;;;;
+16F01;MIAO LETTER BA;Lo;0;L;;;;;N;;;;;
+16F02;MIAO LETTER YI PA;Lo;0;L;;;;;N;;;;;
+16F03;MIAO LETTER PLA;Lo;0;L;;;;;N;;;;;
+16F04;MIAO LETTER MA;Lo;0;L;;;;;N;;;;;
+16F05;MIAO LETTER MHA;Lo;0;L;;;;;N;;;;;
+16F06;MIAO LETTER ARCHAIC MA;Lo;0;L;;;;;N;;;;;
+16F07;MIAO LETTER FA;Lo;0;L;;;;;N;;;;;
+16F08;MIAO LETTER VA;Lo;0;L;;;;;N;;;;;
+16F09;MIAO LETTER VFA;Lo;0;L;;;;;N;;;;;
+16F0A;MIAO LETTER TA;Lo;0;L;;;;;N;;;;;
+16F0B;MIAO LETTER DA;Lo;0;L;;;;;N;;;;;
+16F0C;MIAO LETTER YI TTA;Lo;0;L;;;;;N;;;;;
+16F0D;MIAO LETTER YI TA;Lo;0;L;;;;;N;;;;;
+16F0E;MIAO LETTER TTA;Lo;0;L;;;;;N;;;;;
+16F0F;MIAO LETTER DDA;Lo;0;L;;;;;N;;;;;
+16F10;MIAO LETTER NA;Lo;0;L;;;;;N;;;;;
+16F11;MIAO LETTER NHA;Lo;0;L;;;;;N;;;;;
+16F12;MIAO LETTER YI NNA;Lo;0;L;;;;;N;;;;;
+16F13;MIAO LETTER ARCHAIC NA;Lo;0;L;;;;;N;;;;;
+16F14;MIAO LETTER NNA;Lo;0;L;;;;;N;;;;;
+16F15;MIAO LETTER NNHA;Lo;0;L;;;;;N;;;;;
+16F16;MIAO LETTER LA;Lo;0;L;;;;;N;;;;;
+16F17;MIAO LETTER LYA;Lo;0;L;;;;;N;;;;;
+16F18;MIAO LETTER LHA;Lo;0;L;;;;;N;;;;;
+16F19;MIAO LETTER LHYA;Lo;0;L;;;;;N;;;;;
+16F1A;MIAO LETTER TLHA;Lo;0;L;;;;;N;;;;;
+16F1B;MIAO LETTER DLHA;Lo;0;L;;;;;N;;;;;
+16F1C;MIAO LETTER TLHYA;Lo;0;L;;;;;N;;;;;
+16F1D;MIAO LETTER DLHYA;Lo;0;L;;;;;N;;;;;
+16F1E;MIAO LETTER KA;Lo;0;L;;;;;N;;;;;
+16F1F;MIAO LETTER GA;Lo;0;L;;;;;N;;;;;
+16F20;MIAO LETTER YI KA;Lo;0;L;;;;;N;;;;;
+16F21;MIAO LETTER QA;Lo;0;L;;;;;N;;;;;
+16F22;MIAO LETTER QGA;Lo;0;L;;;;;N;;;;;
+16F23;MIAO LETTER NGA;Lo;0;L;;;;;N;;;;;
+16F24;MIAO LETTER NGHA;Lo;0;L;;;;;N;;;;;
+16F25;MIAO LETTER ARCHAIC NGA;Lo;0;L;;;;;N;;;;;
+16F26;MIAO LETTER HA;Lo;0;L;;;;;N;;;;;
+16F27;MIAO LETTER XA;Lo;0;L;;;;;N;;;;;
+16F28;MIAO LETTER GHA;Lo;0;L;;;;;N;;;;;
+16F29;MIAO LETTER GHHA;Lo;0;L;;;;;N;;;;;
+16F2A;MIAO LETTER TSSA;Lo;0;L;;;;;N;;;;;
+16F2B;MIAO LETTER DZZA;Lo;0;L;;;;;N;;;;;
+16F2C;MIAO LETTER NYA;Lo;0;L;;;;;N;;;;;
+16F2D;MIAO LETTER NYHA;Lo;0;L;;;;;N;;;;;
+16F2E;MIAO LETTER TSHA;Lo;0;L;;;;;N;;;;;
+16F2F;MIAO LETTER DZHA;Lo;0;L;;;;;N;;;;;
+16F30;MIAO LETTER YI TSHA;Lo;0;L;;;;;N;;;;;
+16F31;MIAO LETTER YI DZHA;Lo;0;L;;;;;N;;;;;
+16F32;MIAO LETTER REFORMED TSHA;Lo;0;L;;;;;N;;;;;
+16F33;MIAO LETTER SHA;Lo;0;L;;;;;N;;;;;
+16F34;MIAO LETTER SSA;Lo;0;L;;;;;N;;;;;
+16F35;MIAO LETTER ZHA;Lo;0;L;;;;;N;;;;;
+16F36;MIAO LETTER ZSHA;Lo;0;L;;;;;N;;;;;
+16F37;MIAO LETTER TSA;Lo;0;L;;;;;N;;;;;
+16F38;MIAO LETTER DZA;Lo;0;L;;;;;N;;;;;
+16F39;MIAO LETTER YI TSA;Lo;0;L;;;;;N;;;;;
+16F3A;MIAO LETTER SA;Lo;0;L;;;;;N;;;;;
+16F3B;MIAO LETTER ZA;Lo;0;L;;;;;N;;;;;
+16F3C;MIAO LETTER ZSA;Lo;0;L;;;;;N;;;;;
+16F3D;MIAO LETTER ZZA;Lo;0;L;;;;;N;;;;;
+16F3E;MIAO LETTER ZZSA;Lo;0;L;;;;;N;;;;;
+16F3F;MIAO LETTER ARCHAIC ZZA;Lo;0;L;;;;;N;;;;;
+16F40;MIAO LETTER ZZYA;Lo;0;L;;;;;N;;;;;
+16F41;MIAO LETTER ZZSYA;Lo;0;L;;;;;N;;;;;
+16F42;MIAO LETTER WA;Lo;0;L;;;;;N;;;;;
+16F43;MIAO LETTER AH;Lo;0;L;;;;;N;;;;;
+16F44;MIAO LETTER HHA;Lo;0;L;;;;;N;;;;;
+16F50;MIAO LETTER NASALIZATION;Lo;0;L;;;;;N;;;;;
+16F51;MIAO SIGN ASPIRATION;Mc;0;L;;;;;N;;;;;
+16F52;MIAO SIGN REFORMED VOICING;Mc;0;L;;;;;N;;;;;
+16F53;MIAO SIGN REFORMED ASPIRATION;Mc;0;L;;;;;N;;;;;
+16F54;MIAO VOWEL SIGN A;Mc;0;L;;;;;N;;;;;
+16F55;MIAO VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+16F56;MIAO VOWEL SIGN AHH;Mc;0;L;;;;;N;;;;;
+16F57;MIAO VOWEL SIGN AN;Mc;0;L;;;;;N;;;;;
+16F58;MIAO VOWEL SIGN ANG;Mc;0;L;;;;;N;;;;;
+16F59;MIAO VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
+16F5A;MIAO VOWEL SIGN OO;Mc;0;L;;;;;N;;;;;
+16F5B;MIAO VOWEL SIGN WO;Mc;0;L;;;;;N;;;;;
+16F5C;MIAO VOWEL SIGN W;Mc;0;L;;;;;N;;;;;
+16F5D;MIAO VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
+16F5E;MIAO VOWEL SIGN EN;Mc;0;L;;;;;N;;;;;
+16F5F;MIAO VOWEL SIGN ENG;Mc;0;L;;;;;N;;;;;
+16F60;MIAO VOWEL SIGN OEY;Mc;0;L;;;;;N;;;;;
+16F61;MIAO VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+16F62;MIAO VOWEL SIGN IA;Mc;0;L;;;;;N;;;;;
+16F63;MIAO VOWEL SIGN IAN;Mc;0;L;;;;;N;;;;;
+16F64;MIAO VOWEL SIGN IANG;Mc;0;L;;;;;N;;;;;
+16F65;MIAO VOWEL SIGN IO;Mc;0;L;;;;;N;;;;;
+16F66;MIAO VOWEL SIGN IE;Mc;0;L;;;;;N;;;;;
+16F67;MIAO VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+16F68;MIAO VOWEL SIGN IU;Mc;0;L;;;;;N;;;;;
+16F69;MIAO VOWEL SIGN ING;Mc;0;L;;;;;N;;;;;
+16F6A;MIAO VOWEL SIGN U;Mc;0;L;;;;;N;;;;;
+16F6B;MIAO VOWEL SIGN UA;Mc;0;L;;;;;N;;;;;
+16F6C;MIAO VOWEL SIGN UAN;Mc;0;L;;;;;N;;;;;
+16F6D;MIAO VOWEL SIGN UANG;Mc;0;L;;;;;N;;;;;
+16F6E;MIAO VOWEL SIGN UU;Mc;0;L;;;;;N;;;;;
+16F6F;MIAO VOWEL SIGN UEI;Mc;0;L;;;;;N;;;;;
+16F70;MIAO VOWEL SIGN UNG;Mc;0;L;;;;;N;;;;;
+16F71;MIAO VOWEL SIGN Y;Mc;0;L;;;;;N;;;;;
+16F72;MIAO VOWEL SIGN YI;Mc;0;L;;;;;N;;;;;
+16F73;MIAO VOWEL SIGN AE;Mc;0;L;;;;;N;;;;;
+16F74;MIAO VOWEL SIGN AEE;Mc;0;L;;;;;N;;;;;
+16F75;MIAO VOWEL SIGN ERR;Mc;0;L;;;;;N;;;;;
+16F76;MIAO VOWEL SIGN ROUNDED ERR;Mc;0;L;;;;;N;;;;;
+16F77;MIAO VOWEL SIGN ER;Mc;0;L;;;;;N;;;;;
+16F78;MIAO VOWEL SIGN ROUNDED ER;Mc;0;L;;;;;N;;;;;
+16F79;MIAO VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;
+16F7A;MIAO VOWEL SIGN EI;Mc;0;L;;;;;N;;;;;
+16F7B;MIAO VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;
+16F7C;MIAO VOWEL SIGN OU;Mc;0;L;;;;;N;;;;;
+16F7D;MIAO VOWEL SIGN N;Mc;0;L;;;;;N;;;;;
+16F7E;MIAO VOWEL SIGN NG;Mc;0;L;;;;;N;;;;;
+16F8F;MIAO TONE RIGHT;Mn;0;NSM;;;;;N;;;;;
+16F90;MIAO TONE TOP RIGHT;Mn;0;NSM;;;;;N;;;;;
+16F91;MIAO TONE ABOVE;Mn;0;NSM;;;;;N;;;;;
+16F92;MIAO TONE BELOW;Mn;0;NSM;;;;;N;;;;;
+16F93;MIAO LETTER TONE-2;Lm;0;L;;;;;N;;;;;
+16F94;MIAO LETTER TONE-3;Lm;0;L;;;;;N;;;;;
+16F95;MIAO LETTER TONE-4;Lm;0;L;;;;;N;;;;;
+16F96;MIAO LETTER TONE-5;Lm;0;L;;;;;N;;;;;
+16F97;MIAO LETTER TONE-6;Lm;0;L;;;;;N;;;;;
+16F98;MIAO LETTER TONE-7;Lm;0;L;;;;;N;;;;;
+16F99;MIAO LETTER TONE-8;Lm;0;L;;;;;N;;;;;
+16F9A;MIAO LETTER REFORMED TONE-1;Lm;0;L;;;;;N;;;;;
+16F9B;MIAO LETTER REFORMED TONE-2;Lm;0;L;;;;;N;;;;;
+16F9C;MIAO LETTER REFORMED TONE-4;Lm;0;L;;;;;N;;;;;
+16F9D;MIAO LETTER REFORMED TONE-5;Lm;0;L;;;;;N;;;;;
+16F9E;MIAO LETTER REFORMED TONE-6;Lm;0;L;;;;;N;;;;;
+16F9F;MIAO LETTER REFORMED TONE-8;Lm;0;L;;;;;N;;;;;
+16FE0;TANGUT ITERATION MARK;Lm;0;L;;;;;N;;;;;
+16FE1;NUSHU ITERATION MARK;Lm;0;L;;;;;N;;;;;
+17000;<Tangut Ideograph, First>;Lo;0;L;;;;;N;;;;;
+187EC;<Tangut Ideograph, Last>;Lo;0;L;;;;;N;;;;;
+18800;TANGUT COMPONENT-001;Lo;0;L;;;;;N;;;;;
+18801;TANGUT COMPONENT-002;Lo;0;L;;;;;N;;;;;
+18802;TANGUT COMPONENT-003;Lo;0;L;;;;;N;;;;;
+18803;TANGUT COMPONENT-004;Lo;0;L;;;;;N;;;;;
+18804;TANGUT COMPONENT-005;Lo;0;L;;;;;N;;;;;
+18805;TANGUT COMPONENT-006;Lo;0;L;;;;;N;;;;;
+18806;TANGUT COMPONENT-007;Lo;0;L;;;;;N;;;;;
+18807;TANGUT COMPONENT-008;Lo;0;L;;;;;N;;;;;
+18808;TANGUT COMPONENT-009;Lo;0;L;;;;;N;;;;;
+18809;TANGUT COMPONENT-010;Lo;0;L;;;;;N;;;;;
+1880A;TANGUT COMPONENT-011;Lo;0;L;;;;;N;;;;;
+1880B;TANGUT COMPONENT-012;Lo;0;L;;;;;N;;;;;
+1880C;TANGUT COMPONENT-013;Lo;0;L;;;;;N;;;;;
+1880D;TANGUT COMPONENT-014;Lo;0;L;;;;;N;;;;;
+1880E;TANGUT COMPONENT-015;Lo;0;L;;;;;N;;;;;
+1880F;TANGUT COMPONENT-016;Lo;0;L;;;;;N;;;;;
+18810;TANGUT COMPONENT-017;Lo;0;L;;;;;N;;;;;
+18811;TANGUT COMPONENT-018;Lo;0;L;;;;;N;;;;;
+18812;TANGUT COMPONENT-019;Lo;0;L;;;;;N;;;;;
+18813;TANGUT COMPONENT-020;Lo;0;L;;;;;N;;;;;
+18814;TANGUT COMPONENT-021;Lo;0;L;;;;;N;;;;;
+18815;TANGUT COMPONENT-022;Lo;0;L;;;;;N;;;;;
+18816;TANGUT COMPONENT-023;Lo;0;L;;;;;N;;;;;
+18817;TANGUT COMPONENT-024;Lo;0;L;;;;;N;;;;;
+18818;TANGUT COMPONENT-025;Lo;0;L;;;;;N;;;;;
+18819;TANGUT COMPONENT-026;Lo;0;L;;;;;N;;;;;
+1881A;TANGUT COMPONENT-027;Lo;0;L;;;;;N;;;;;
+1881B;TANGUT COMPONENT-028;Lo;0;L;;;;;N;;;;;
+1881C;TANGUT COMPONENT-029;Lo;0;L;;;;;N;;;;;
+1881D;TANGUT COMPONENT-030;Lo;0;L;;;;;N;;;;;
+1881E;TANGUT COMPONENT-031;Lo;0;L;;;;;N;;;;;
+1881F;TANGUT COMPONENT-032;Lo;0;L;;;;;N;;;;;
+18820;TANGUT COMPONENT-033;Lo;0;L;;;;;N;;;;;
+18821;TANGUT COMPONENT-034;Lo;0;L;;;;;N;;;;;
+18822;TANGUT COMPONENT-035;Lo;0;L;;;;;N;;;;;
+18823;TANGUT COMPONENT-036;Lo;0;L;;;;;N;;;;;
+18824;TANGUT COMPONENT-037;Lo;0;L;;;;;N;;;;;
+18825;TANGUT COMPONENT-038;Lo;0;L;;;;;N;;;;;
+18826;TANGUT COMPONENT-039;Lo;0;L;;;;;N;;;;;
+18827;TANGUT COMPONENT-040;Lo;0;L;;;;;N;;;;;
+18828;TANGUT COMPONENT-041;Lo;0;L;;;;;N;;;;;
+18829;TANGUT COMPONENT-042;Lo;0;L;;;;;N;;;;;
+1882A;TANGUT COMPONENT-043;Lo;0;L;;;;;N;;;;;
+1882B;TANGUT COMPONENT-044;Lo;0;L;;;;;N;;;;;
+1882C;TANGUT COMPONENT-045;Lo;0;L;;;;;N;;;;;
+1882D;TANGUT COMPONENT-046;Lo;0;L;;;;;N;;;;;
+1882E;TANGUT COMPONENT-047;Lo;0;L;;;;;N;;;;;
+1882F;TANGUT COMPONENT-048;Lo;0;L;;;;;N;;;;;
+18830;TANGUT COMPONENT-049;Lo;0;L;;;;;N;;;;;
+18831;TANGUT COMPONENT-050;Lo;0;L;;;;;N;;;;;
+18832;TANGUT COMPONENT-051;Lo;0;L;;;;;N;;;;;
+18833;TANGUT COMPONENT-052;Lo;0;L;;;;;N;;;;;
+18834;TANGUT COMPONENT-053;Lo;0;L;;;;;N;;;;;
+18835;TANGUT COMPONENT-054;Lo;0;L;;;;;N;;;;;
+18836;TANGUT COMPONENT-055;Lo;0;L;;;;;N;;;;;
+18837;TANGUT COMPONENT-056;Lo;0;L;;;;;N;;;;;
+18838;TANGUT COMPONENT-057;Lo;0;L;;;;;N;;;;;
+18839;TANGUT COMPONENT-058;Lo;0;L;;;;;N;;;;;
+1883A;TANGUT COMPONENT-059;Lo;0;L;;;;;N;;;;;
+1883B;TANGUT COMPONENT-060;Lo;0;L;;;;;N;;;;;
+1883C;TANGUT COMPONENT-061;Lo;0;L;;;;;N;;;;;
+1883D;TANGUT COMPONENT-062;Lo;0;L;;;;;N;;;;;
+1883E;TANGUT COMPONENT-063;Lo;0;L;;;;;N;;;;;
+1883F;TANGUT COMPONENT-064;Lo;0;L;;;;;N;;;;;
+18840;TANGUT COMPONENT-065;Lo;0;L;;;;;N;;;;;
+18841;TANGUT COMPONENT-066;Lo;0;L;;;;;N;;;;;
+18842;TANGUT COMPONENT-067;Lo;0;L;;;;;N;;;;;
+18843;TANGUT COMPONENT-068;Lo;0;L;;;;;N;;;;;
+18844;TANGUT COMPONENT-069;Lo;0;L;;;;;N;;;;;
+18845;TANGUT COMPONENT-070;Lo;0;L;;;;;N;;;;;
+18846;TANGUT COMPONENT-071;Lo;0;L;;;;;N;;;;;
+18847;TANGUT COMPONENT-072;Lo;0;L;;;;;N;;;;;
+18848;TANGUT COMPONENT-073;Lo;0;L;;;;;N;;;;;
+18849;TANGUT COMPONENT-074;Lo;0;L;;;;;N;;;;;
+1884A;TANGUT COMPONENT-075;Lo;0;L;;;;;N;;;;;
+1884B;TANGUT COMPONENT-076;Lo;0;L;;;;;N;;;;;
+1884C;TANGUT COMPONENT-077;Lo;0;L;;;;;N;;;;;
+1884D;TANGUT COMPONENT-078;Lo;0;L;;;;;N;;;;;
+1884E;TANGUT COMPONENT-079;Lo;0;L;;;;;N;;;;;
+1884F;TANGUT COMPONENT-080;Lo;0;L;;;;;N;;;;;
+18850;TANGUT COMPONENT-081;Lo;0;L;;;;;N;;;;;
+18851;TANGUT COMPONENT-082;Lo;0;L;;;;;N;;;;;
+18852;TANGUT COMPONENT-083;Lo;0;L;;;;;N;;;;;
+18853;TANGUT COMPONENT-084;Lo;0;L;;;;;N;;;;;
+18854;TANGUT COMPONENT-085;Lo;0;L;;;;;N;;;;;
+18855;TANGUT COMPONENT-086;Lo;0;L;;;;;N;;;;;
+18856;TANGUT COMPONENT-087;Lo;0;L;;;;;N;;;;;
+18857;TANGUT COMPONENT-088;Lo;0;L;;;;;N;;;;;
+18858;TANGUT COMPONENT-089;Lo;0;L;;;;;N;;;;;
+18859;TANGUT COMPONENT-090;Lo;0;L;;;;;N;;;;;
+1885A;TANGUT COMPONENT-091;Lo;0;L;;;;;N;;;;;
+1885B;TANGUT COMPONENT-092;Lo;0;L;;;;;N;;;;;
+1885C;TANGUT COMPONENT-093;Lo;0;L;;;;;N;;;;;
+1885D;TANGUT COMPONENT-094;Lo;0;L;;;;;N;;;;;
+1885E;TANGUT COMPONENT-095;Lo;0;L;;;;;N;;;;;
+1885F;TANGUT COMPONENT-096;Lo;0;L;;;;;N;;;;;
+18860;TANGUT COMPONENT-097;Lo;0;L;;;;;N;;;;;
+18861;TANGUT COMPONENT-098;Lo;0;L;;;;;N;;;;;
+18862;TANGUT COMPONENT-099;Lo;0;L;;;;;N;;;;;
+18863;TANGUT COMPONENT-100;Lo;0;L;;;;;N;;;;;
+18864;TANGUT COMPONENT-101;Lo;0;L;;;;;N;;;;;
+18865;TANGUT COMPONENT-102;Lo;0;L;;;;;N;;;;;
+18866;TANGUT COMPONENT-103;Lo;0;L;;;;;N;;;;;
+18867;TANGUT COMPONENT-104;Lo;0;L;;;;;N;;;;;
+18868;TANGUT COMPONENT-105;Lo;0;L;;;;;N;;;;;
+18869;TANGUT COMPONENT-106;Lo;0;L;;;;;N;;;;;
+1886A;TANGUT COMPONENT-107;Lo;0;L;;;;;N;;;;;
+1886B;TANGUT COMPONENT-108;Lo;0;L;;;;;N;;;;;
+1886C;TANGUT COMPONENT-109;Lo;0;L;;;;;N;;;;;
+1886D;TANGUT COMPONENT-110;Lo;0;L;;;;;N;;;;;
+1886E;TANGUT COMPONENT-111;Lo;0;L;;;;;N;;;;;
+1886F;TANGUT COMPONENT-112;Lo;0;L;;;;;N;;;;;
+18870;TANGUT COMPONENT-113;Lo;0;L;;;;;N;;;;;
+18871;TANGUT COMPONENT-114;Lo;0;L;;;;;N;;;;;
+18872;TANGUT COMPONENT-115;Lo;0;L;;;;;N;;;;;
+18873;TANGUT COMPONENT-116;Lo;0;L;;;;;N;;;;;
+18874;TANGUT COMPONENT-117;Lo;0;L;;;;;N;;;;;
+18875;TANGUT COMPONENT-118;Lo;0;L;;;;;N;;;;;
+18876;TANGUT COMPONENT-119;Lo;0;L;;;;;N;;;;;
+18877;TANGUT COMPONENT-120;Lo;0;L;;;;;N;;;;;
+18878;TANGUT COMPONENT-121;Lo;0;L;;;;;N;;;;;
+18879;TANGUT COMPONENT-122;Lo;0;L;;;;;N;;;;;
+1887A;TANGUT COMPONENT-123;Lo;0;L;;;;;N;;;;;
+1887B;TANGUT COMPONENT-124;Lo;0;L;;;;;N;;;;;
+1887C;TANGUT COMPONENT-125;Lo;0;L;;;;;N;;;;;
+1887D;TANGUT COMPONENT-126;Lo;0;L;;;;;N;;;;;
+1887E;TANGUT COMPONENT-127;Lo;0;L;;;;;N;;;;;
+1887F;TANGUT COMPONENT-128;Lo;0;L;;;;;N;;;;;
+18880;TANGUT COMPONENT-129;Lo;0;L;;;;;N;;;;;
+18881;TANGUT COMPONENT-130;Lo;0;L;;;;;N;;;;;
+18882;TANGUT COMPONENT-131;Lo;0;L;;;;;N;;;;;
+18883;TANGUT COMPONENT-132;Lo;0;L;;;;;N;;;;;
+18884;TANGUT COMPONENT-133;Lo;0;L;;;;;N;;;;;
+18885;TANGUT COMPONENT-134;Lo;0;L;;;;;N;;;;;
+18886;TANGUT COMPONENT-135;Lo;0;L;;;;;N;;;;;
+18887;TANGUT COMPONENT-136;Lo;0;L;;;;;N;;;;;
+18888;TANGUT COMPONENT-137;Lo;0;L;;;;;N;;;;;
+18889;TANGUT COMPONENT-138;Lo;0;L;;;;;N;;;;;
+1888A;TANGUT COMPONENT-139;Lo;0;L;;;;;N;;;;;
+1888B;TANGUT COMPONENT-140;Lo;0;L;;;;;N;;;;;
+1888C;TANGUT COMPONENT-141;Lo;0;L;;;;;N;;;;;
+1888D;TANGUT COMPONENT-142;Lo;0;L;;;;;N;;;;;
+1888E;TANGUT COMPONENT-143;Lo;0;L;;;;;N;;;;;
+1888F;TANGUT COMPONENT-144;Lo;0;L;;;;;N;;;;;
+18890;TANGUT COMPONENT-145;Lo;0;L;;;;;N;;;;;
+18891;TANGUT COMPONENT-146;Lo;0;L;;;;;N;;;;;
+18892;TANGUT COMPONENT-147;Lo;0;L;;;;;N;;;;;
+18893;TANGUT COMPONENT-148;Lo;0;L;;;;;N;;;;;
+18894;TANGUT COMPONENT-149;Lo;0;L;;;;;N;;;;;
+18895;TANGUT COMPONENT-150;Lo;0;L;;;;;N;;;;;
+18896;TANGUT COMPONENT-151;Lo;0;L;;;;;N;;;;;
+18897;TANGUT COMPONENT-152;Lo;0;L;;;;;N;;;;;
+18898;TANGUT COMPONENT-153;Lo;0;L;;;;;N;;;;;
+18899;TANGUT COMPONENT-154;Lo;0;L;;;;;N;;;;;
+1889A;TANGUT COMPONENT-155;Lo;0;L;;;;;N;;;;;
+1889B;TANGUT COMPONENT-156;Lo;0;L;;;;;N;;;;;
+1889C;TANGUT COMPONENT-157;Lo;0;L;;;;;N;;;;;
+1889D;TANGUT COMPONENT-158;Lo;0;L;;;;;N;;;;;
+1889E;TANGUT COMPONENT-159;Lo;0;L;;;;;N;;;;;
+1889F;TANGUT COMPONENT-160;Lo;0;L;;;;;N;;;;;
+188A0;TANGUT COMPONENT-161;Lo;0;L;;;;;N;;;;;
+188A1;TANGUT COMPONENT-162;Lo;0;L;;;;;N;;;;;
+188A2;TANGUT COMPONENT-163;Lo;0;L;;;;;N;;;;;
+188A3;TANGUT COMPONENT-164;Lo;0;L;;;;;N;;;;;
+188A4;TANGUT COMPONENT-165;Lo;0;L;;;;;N;;;;;
+188A5;TANGUT COMPONENT-166;Lo;0;L;;;;;N;;;;;
+188A6;TANGUT COMPONENT-167;Lo;0;L;;;;;N;;;;;
+188A7;TANGUT COMPONENT-168;Lo;0;L;;;;;N;;;;;
+188A8;TANGUT COMPONENT-169;Lo;0;L;;;;;N;;;;;
+188A9;TANGUT COMPONENT-170;Lo;0;L;;;;;N;;;;;
+188AA;TANGUT COMPONENT-171;Lo;0;L;;;;;N;;;;;
+188AB;TANGUT COMPONENT-172;Lo;0;L;;;;;N;;;;;
+188AC;TANGUT COMPONENT-173;Lo;0;L;;;;;N;;;;;
+188AD;TANGUT COMPONENT-174;Lo;0;L;;;;;N;;;;;
+188AE;TANGUT COMPONENT-175;Lo;0;L;;;;;N;;;;;
+188AF;TANGUT COMPONENT-176;Lo;0;L;;;;;N;;;;;
+188B0;TANGUT COMPONENT-177;Lo;0;L;;;;;N;;;;;
+188B1;TANGUT COMPONENT-178;Lo;0;L;;;;;N;;;;;
+188B2;TANGUT COMPONENT-179;Lo;0;L;;;;;N;;;;;
+188B3;TANGUT COMPONENT-180;Lo;0;L;;;;;N;;;;;
+188B4;TANGUT COMPONENT-181;Lo;0;L;;;;;N;;;;;
+188B5;TANGUT COMPONENT-182;Lo;0;L;;;;;N;;;;;
+188B6;TANGUT COMPONENT-183;Lo;0;L;;;;;N;;;;;
+188B7;TANGUT COMPONENT-184;Lo;0;L;;;;;N;;;;;
+188B8;TANGUT COMPONENT-185;Lo;0;L;;;;;N;;;;;
+188B9;TANGUT COMPONENT-186;Lo;0;L;;;;;N;;;;;
+188BA;TANGUT COMPONENT-187;Lo;0;L;;;;;N;;;;;
+188BB;TANGUT COMPONENT-188;Lo;0;L;;;;;N;;;;;
+188BC;TANGUT COMPONENT-189;Lo;0;L;;;;;N;;;;;
+188BD;TANGUT COMPONENT-190;Lo;0;L;;;;;N;;;;;
+188BE;TANGUT COMPONENT-191;Lo;0;L;;;;;N;;;;;
+188BF;TANGUT COMPONENT-192;Lo;0;L;;;;;N;;;;;
+188C0;TANGUT COMPONENT-193;Lo;0;L;;;;;N;;;;;
+188C1;TANGUT COMPONENT-194;Lo;0;L;;;;;N;;;;;
+188C2;TANGUT COMPONENT-195;Lo;0;L;;;;;N;;;;;
+188C3;TANGUT COMPONENT-196;Lo;0;L;;;;;N;;;;;
+188C4;TANGUT COMPONENT-197;Lo;0;L;;;;;N;;;;;
+188C5;TANGUT COMPONENT-198;Lo;0;L;;;;;N;;;;;
+188C6;TANGUT COMPONENT-199;Lo;0;L;;;;;N;;;;;
+188C7;TANGUT COMPONENT-200;Lo;0;L;;;;;N;;;;;
+188C8;TANGUT COMPONENT-201;Lo;0;L;;;;;N;;;;;
+188C9;TANGUT COMPONENT-202;Lo;0;L;;;;;N;;;;;
+188CA;TANGUT COMPONENT-203;Lo;0;L;;;;;N;;;;;
+188CB;TANGUT COMPONENT-204;Lo;0;L;;;;;N;;;;;
+188CC;TANGUT COMPONENT-205;Lo;0;L;;;;;N;;;;;
+188CD;TANGUT COMPONENT-206;Lo;0;L;;;;;N;;;;;
+188CE;TANGUT COMPONENT-207;Lo;0;L;;;;;N;;;;;
+188CF;TANGUT COMPONENT-208;Lo;0;L;;;;;N;;;;;
+188D0;TANGUT COMPONENT-209;Lo;0;L;;;;;N;;;;;
+188D1;TANGUT COMPONENT-210;Lo;0;L;;;;;N;;;;;
+188D2;TANGUT COMPONENT-211;Lo;0;L;;;;;N;;;;;
+188D3;TANGUT COMPONENT-212;Lo;0;L;;;;;N;;;;;
+188D4;TANGUT COMPONENT-213;Lo;0;L;;;;;N;;;;;
+188D5;TANGUT COMPONENT-214;Lo;0;L;;;;;N;;;;;
+188D6;TANGUT COMPONENT-215;Lo;0;L;;;;;N;;;;;
+188D7;TANGUT COMPONENT-216;Lo;0;L;;;;;N;;;;;
+188D8;TANGUT COMPONENT-217;Lo;0;L;;;;;N;;;;;
+188D9;TANGUT COMPONENT-218;Lo;0;L;;;;;N;;;;;
+188DA;TANGUT COMPONENT-219;Lo;0;L;;;;;N;;;;;
+188DB;TANGUT COMPONENT-220;Lo;0;L;;;;;N;;;;;
+188DC;TANGUT COMPONENT-221;Lo;0;L;;;;;N;;;;;
+188DD;TANGUT COMPONENT-222;Lo;0;L;;;;;N;;;;;
+188DE;TANGUT COMPONENT-223;Lo;0;L;;;;;N;;;;;
+188DF;TANGUT COMPONENT-224;Lo;0;L;;;;;N;;;;;
+188E0;TANGUT COMPONENT-225;Lo;0;L;;;;;N;;;;;
+188E1;TANGUT COMPONENT-226;Lo;0;L;;;;;N;;;;;
+188E2;TANGUT COMPONENT-227;Lo;0;L;;;;;N;;;;;
+188E3;TANGUT COMPONENT-228;Lo;0;L;;;;;N;;;;;
+188E4;TANGUT COMPONENT-229;Lo;0;L;;;;;N;;;;;
+188E5;TANGUT COMPONENT-230;Lo;0;L;;;;;N;;;;;
+188E6;TANGUT COMPONENT-231;Lo;0;L;;;;;N;;;;;
+188E7;TANGUT COMPONENT-232;Lo;0;L;;;;;N;;;;;
+188E8;TANGUT COMPONENT-233;Lo;0;L;;;;;N;;;;;
+188E9;TANGUT COMPONENT-234;Lo;0;L;;;;;N;;;;;
+188EA;TANGUT COMPONENT-235;Lo;0;L;;;;;N;;;;;
+188EB;TANGUT COMPONENT-236;Lo;0;L;;;;;N;;;;;
+188EC;TANGUT COMPONENT-237;Lo;0;L;;;;;N;;;;;
+188ED;TANGUT COMPONENT-238;Lo;0;L;;;;;N;;;;;
+188EE;TANGUT COMPONENT-239;Lo;0;L;;;;;N;;;;;
+188EF;TANGUT COMPONENT-240;Lo;0;L;;;;;N;;;;;
+188F0;TANGUT COMPONENT-241;Lo;0;L;;;;;N;;;;;
+188F1;TANGUT COMPONENT-242;Lo;0;L;;;;;N;;;;;
+188F2;TANGUT COMPONENT-243;Lo;0;L;;;;;N;;;;;
+188F3;TANGUT COMPONENT-244;Lo;0;L;;;;;N;;;;;
+188F4;TANGUT COMPONENT-245;Lo;0;L;;;;;N;;;;;
+188F5;TANGUT COMPONENT-246;Lo;0;L;;;;;N;;;;;
+188F6;TANGUT COMPONENT-247;Lo;0;L;;;;;N;;;;;
+188F7;TANGUT COMPONENT-248;Lo;0;L;;;;;N;;;;;
+188F8;TANGUT COMPONENT-249;Lo;0;L;;;;;N;;;;;
+188F9;TANGUT COMPONENT-250;Lo;0;L;;;;;N;;;;;
+188FA;TANGUT COMPONENT-251;Lo;0;L;;;;;N;;;;;
+188FB;TANGUT COMPONENT-252;Lo;0;L;;;;;N;;;;;
+188FC;TANGUT COMPONENT-253;Lo;0;L;;;;;N;;;;;
+188FD;TANGUT COMPONENT-254;Lo;0;L;;;;;N;;;;;
+188FE;TANGUT COMPONENT-255;Lo;0;L;;;;;N;;;;;
+188FF;TANGUT COMPONENT-256;Lo;0;L;;;;;N;;;;;
+18900;TANGUT COMPONENT-257;Lo;0;L;;;;;N;;;;;
+18901;TANGUT COMPONENT-258;Lo;0;L;;;;;N;;;;;
+18902;TANGUT COMPONENT-259;Lo;0;L;;;;;N;;;;;
+18903;TANGUT COMPONENT-260;Lo;0;L;;;;;N;;;;;
+18904;TANGUT COMPONENT-261;Lo;0;L;;;;;N;;;;;
+18905;TANGUT COMPONENT-262;Lo;0;L;;;;;N;;;;;
+18906;TANGUT COMPONENT-263;Lo;0;L;;;;;N;;;;;
+18907;TANGUT COMPONENT-264;Lo;0;L;;;;;N;;;;;
+18908;TANGUT COMPONENT-265;Lo;0;L;;;;;N;;;;;
+18909;TANGUT COMPONENT-266;Lo;0;L;;;;;N;;;;;
+1890A;TANGUT COMPONENT-267;Lo;0;L;;;;;N;;;;;
+1890B;TANGUT COMPONENT-268;Lo;0;L;;;;;N;;;;;
+1890C;TANGUT COMPONENT-269;Lo;0;L;;;;;N;;;;;
+1890D;TANGUT COMPONENT-270;Lo;0;L;;;;;N;;;;;
+1890E;TANGUT COMPONENT-271;Lo;0;L;;;;;N;;;;;
+1890F;TANGUT COMPONENT-272;Lo;0;L;;;;;N;;;;;
+18910;TANGUT COMPONENT-273;Lo;0;L;;;;;N;;;;;
+18911;TANGUT COMPONENT-274;Lo;0;L;;;;;N;;;;;
+18912;TANGUT COMPONENT-275;Lo;0;L;;;;;N;;;;;
+18913;TANGUT COMPONENT-276;Lo;0;L;;;;;N;;;;;
+18914;TANGUT COMPONENT-277;Lo;0;L;;;;;N;;;;;
+18915;TANGUT COMPONENT-278;Lo;0;L;;;;;N;;;;;
+18916;TANGUT COMPONENT-279;Lo;0;L;;;;;N;;;;;
+18917;TANGUT COMPONENT-280;Lo;0;L;;;;;N;;;;;
+18918;TANGUT COMPONENT-281;Lo;0;L;;;;;N;;;;;
+18919;TANGUT COMPONENT-282;Lo;0;L;;;;;N;;;;;
+1891A;TANGUT COMPONENT-283;Lo;0;L;;;;;N;;;;;
+1891B;TANGUT COMPONENT-284;Lo;0;L;;;;;N;;;;;
+1891C;TANGUT COMPONENT-285;Lo;0;L;;;;;N;;;;;
+1891D;TANGUT COMPONENT-286;Lo;0;L;;;;;N;;;;;
+1891E;TANGUT COMPONENT-287;Lo;0;L;;;;;N;;;;;
+1891F;TANGUT COMPONENT-288;Lo;0;L;;;;;N;;;;;
+18920;TANGUT COMPONENT-289;Lo;0;L;;;;;N;;;;;
+18921;TANGUT COMPONENT-290;Lo;0;L;;;;;N;;;;;
+18922;TANGUT COMPONENT-291;Lo;0;L;;;;;N;;;;;
+18923;TANGUT COMPONENT-292;Lo;0;L;;;;;N;;;;;
+18924;TANGUT COMPONENT-293;Lo;0;L;;;;;N;;;;;
+18925;TANGUT COMPONENT-294;Lo;0;L;;;;;N;;;;;
+18926;TANGUT COMPONENT-295;Lo;0;L;;;;;N;;;;;
+18927;TANGUT COMPONENT-296;Lo;0;L;;;;;N;;;;;
+18928;TANGUT COMPONENT-297;Lo;0;L;;;;;N;;;;;
+18929;TANGUT COMPONENT-298;Lo;0;L;;;;;N;;;;;
+1892A;TANGUT COMPONENT-299;Lo;0;L;;;;;N;;;;;
+1892B;TANGUT COMPONENT-300;Lo;0;L;;;;;N;;;;;
+1892C;TANGUT COMPONENT-301;Lo;0;L;;;;;N;;;;;
+1892D;TANGUT COMPONENT-302;Lo;0;L;;;;;N;;;;;
+1892E;TANGUT COMPONENT-303;Lo;0;L;;;;;N;;;;;
+1892F;TANGUT COMPONENT-304;Lo;0;L;;;;;N;;;;;
+18930;TANGUT COMPONENT-305;Lo;0;L;;;;;N;;;;;
+18931;TANGUT COMPONENT-306;Lo;0;L;;;;;N;;;;;
+18932;TANGUT COMPONENT-307;Lo;0;L;;;;;N;;;;;
+18933;TANGUT COMPONENT-308;Lo;0;L;;;;;N;;;;;
+18934;TANGUT COMPONENT-309;Lo;0;L;;;;;N;;;;;
+18935;TANGUT COMPONENT-310;Lo;0;L;;;;;N;;;;;
+18936;TANGUT COMPONENT-311;Lo;0;L;;;;;N;;;;;
+18937;TANGUT COMPONENT-312;Lo;0;L;;;;;N;;;;;
+18938;TANGUT COMPONENT-313;Lo;0;L;;;;;N;;;;;
+18939;TANGUT COMPONENT-314;Lo;0;L;;;;;N;;;;;
+1893A;TANGUT COMPONENT-315;Lo;0;L;;;;;N;;;;;
+1893B;TANGUT COMPONENT-316;Lo;0;L;;;;;N;;;;;
+1893C;TANGUT COMPONENT-317;Lo;0;L;;;;;N;;;;;
+1893D;TANGUT COMPONENT-318;Lo;0;L;;;;;N;;;;;
+1893E;TANGUT COMPONENT-319;Lo;0;L;;;;;N;;;;;
+1893F;TANGUT COMPONENT-320;Lo;0;L;;;;;N;;;;;
+18940;TANGUT COMPONENT-321;Lo;0;L;;;;;N;;;;;
+18941;TANGUT COMPONENT-322;Lo;0;L;;;;;N;;;;;
+18942;TANGUT COMPONENT-323;Lo;0;L;;;;;N;;;;;
+18943;TANGUT COMPONENT-324;Lo;0;L;;;;;N;;;;;
+18944;TANGUT COMPONENT-325;Lo;0;L;;;;;N;;;;;
+18945;TANGUT COMPONENT-326;Lo;0;L;;;;;N;;;;;
+18946;TANGUT COMPONENT-327;Lo;0;L;;;;;N;;;;;
+18947;TANGUT COMPONENT-328;Lo;0;L;;;;;N;;;;;
+18948;TANGUT COMPONENT-329;Lo;0;L;;;;;N;;;;;
+18949;TANGUT COMPONENT-330;Lo;0;L;;;;;N;;;;;
+1894A;TANGUT COMPONENT-331;Lo;0;L;;;;;N;;;;;
+1894B;TANGUT COMPONENT-332;Lo;0;L;;;;;N;;;;;
+1894C;TANGUT COMPONENT-333;Lo;0;L;;;;;N;;;;;
+1894D;TANGUT COMPONENT-334;Lo;0;L;;;;;N;;;;;
+1894E;TANGUT COMPONENT-335;Lo;0;L;;;;;N;;;;;
+1894F;TANGUT COMPONENT-336;Lo;0;L;;;;;N;;;;;
+18950;TANGUT COMPONENT-337;Lo;0;L;;;;;N;;;;;
+18951;TANGUT COMPONENT-338;Lo;0;L;;;;;N;;;;;
+18952;TANGUT COMPONENT-339;Lo;0;L;;;;;N;;;;;
+18953;TANGUT COMPONENT-340;Lo;0;L;;;;;N;;;;;
+18954;TANGUT COMPONENT-341;Lo;0;L;;;;;N;;;;;
+18955;TANGUT COMPONENT-342;Lo;0;L;;;;;N;;;;;
+18956;TANGUT COMPONENT-343;Lo;0;L;;;;;N;;;;;
+18957;TANGUT COMPONENT-344;Lo;0;L;;;;;N;;;;;
+18958;TANGUT COMPONENT-345;Lo;0;L;;;;;N;;;;;
+18959;TANGUT COMPONENT-346;Lo;0;L;;;;;N;;;;;
+1895A;TANGUT COMPONENT-347;Lo;0;L;;;;;N;;;;;
+1895B;TANGUT COMPONENT-348;Lo;0;L;;;;;N;;;;;
+1895C;TANGUT COMPONENT-349;Lo;0;L;;;;;N;;;;;
+1895D;TANGUT COMPONENT-350;Lo;0;L;;;;;N;;;;;
+1895E;TANGUT COMPONENT-351;Lo;0;L;;;;;N;;;;;
+1895F;TANGUT COMPONENT-352;Lo;0;L;;;;;N;;;;;
+18960;TANGUT COMPONENT-353;Lo;0;L;;;;;N;;;;;
+18961;TANGUT COMPONENT-354;Lo;0;L;;;;;N;;;;;
+18962;TANGUT COMPONENT-355;Lo;0;L;;;;;N;;;;;
+18963;TANGUT COMPONENT-356;Lo;0;L;;;;;N;;;;;
+18964;TANGUT COMPONENT-357;Lo;0;L;;;;;N;;;;;
+18965;TANGUT COMPONENT-358;Lo;0;L;;;;;N;;;;;
+18966;TANGUT COMPONENT-359;Lo;0;L;;;;;N;;;;;
+18967;TANGUT COMPONENT-360;Lo;0;L;;;;;N;;;;;
+18968;TANGUT COMPONENT-361;Lo;0;L;;;;;N;;;;;
+18969;TANGUT COMPONENT-362;Lo;0;L;;;;;N;;;;;
+1896A;TANGUT COMPONENT-363;Lo;0;L;;;;;N;;;;;
+1896B;TANGUT COMPONENT-364;Lo;0;L;;;;;N;;;;;
+1896C;TANGUT COMPONENT-365;Lo;0;L;;;;;N;;;;;
+1896D;TANGUT COMPONENT-366;Lo;0;L;;;;;N;;;;;
+1896E;TANGUT COMPONENT-367;Lo;0;L;;;;;N;;;;;
+1896F;TANGUT COMPONENT-368;Lo;0;L;;;;;N;;;;;
+18970;TANGUT COMPONENT-369;Lo;0;L;;;;;N;;;;;
+18971;TANGUT COMPONENT-370;Lo;0;L;;;;;N;;;;;
+18972;TANGUT COMPONENT-371;Lo;0;L;;;;;N;;;;;
+18973;TANGUT COMPONENT-372;Lo;0;L;;;;;N;;;;;
+18974;TANGUT COMPONENT-373;Lo;0;L;;;;;N;;;;;
+18975;TANGUT COMPONENT-374;Lo;0;L;;;;;N;;;;;
+18976;TANGUT COMPONENT-375;Lo;0;L;;;;;N;;;;;
+18977;TANGUT COMPONENT-376;Lo;0;L;;;;;N;;;;;
+18978;TANGUT COMPONENT-377;Lo;0;L;;;;;N;;;;;
+18979;TANGUT COMPONENT-378;Lo;0;L;;;;;N;;;;;
+1897A;TANGUT COMPONENT-379;Lo;0;L;;;;;N;;;;;
+1897B;TANGUT COMPONENT-380;Lo;0;L;;;;;N;;;;;
+1897C;TANGUT COMPONENT-381;Lo;0;L;;;;;N;;;;;
+1897D;TANGUT COMPONENT-382;Lo;0;L;;;;;N;;;;;
+1897E;TANGUT COMPONENT-383;Lo;0;L;;;;;N;;;;;
+1897F;TANGUT COMPONENT-384;Lo;0;L;;;;;N;;;;;
+18980;TANGUT COMPONENT-385;Lo;0;L;;;;;N;;;;;
+18981;TANGUT COMPONENT-386;Lo;0;L;;;;;N;;;;;
+18982;TANGUT COMPONENT-387;Lo;0;L;;;;;N;;;;;
+18983;TANGUT COMPONENT-388;Lo;0;L;;;;;N;;;;;
+18984;TANGUT COMPONENT-389;Lo;0;L;;;;;N;;;;;
+18985;TANGUT COMPONENT-390;Lo;0;L;;;;;N;;;;;
+18986;TANGUT COMPONENT-391;Lo;0;L;;;;;N;;;;;
+18987;TANGUT COMPONENT-392;Lo;0;L;;;;;N;;;;;
+18988;TANGUT COMPONENT-393;Lo;0;L;;;;;N;;;;;
+18989;TANGUT COMPONENT-394;Lo;0;L;;;;;N;;;;;
+1898A;TANGUT COMPONENT-395;Lo;0;L;;;;;N;;;;;
+1898B;TANGUT COMPONENT-396;Lo;0;L;;;;;N;;;;;
+1898C;TANGUT COMPONENT-397;Lo;0;L;;;;;N;;;;;
+1898D;TANGUT COMPONENT-398;Lo;0;L;;;;;N;;;;;
+1898E;TANGUT COMPONENT-399;Lo;0;L;;;;;N;;;;;
+1898F;TANGUT COMPONENT-400;Lo;0;L;;;;;N;;;;;
+18990;TANGUT COMPONENT-401;Lo;0;L;;;;;N;;;;;
+18991;TANGUT COMPONENT-402;Lo;0;L;;;;;N;;;;;
+18992;TANGUT COMPONENT-403;Lo;0;L;;;;;N;;;;;
+18993;TANGUT COMPONENT-404;Lo;0;L;;;;;N;;;;;
+18994;TANGUT COMPONENT-405;Lo;0;L;;;;;N;;;;;
+18995;TANGUT COMPONENT-406;Lo;0;L;;;;;N;;;;;
+18996;TANGUT COMPONENT-407;Lo;0;L;;;;;N;;;;;
+18997;TANGUT COMPONENT-408;Lo;0;L;;;;;N;;;;;
+18998;TANGUT COMPONENT-409;Lo;0;L;;;;;N;;;;;
+18999;TANGUT COMPONENT-410;Lo;0;L;;;;;N;;;;;
+1899A;TANGUT COMPONENT-411;Lo;0;L;;;;;N;;;;;
+1899B;TANGUT COMPONENT-412;Lo;0;L;;;;;N;;;;;
+1899C;TANGUT COMPONENT-413;Lo;0;L;;;;;N;;;;;
+1899D;TANGUT COMPONENT-414;Lo;0;L;;;;;N;;;;;
+1899E;TANGUT COMPONENT-415;Lo;0;L;;;;;N;;;;;
+1899F;TANGUT COMPONENT-416;Lo;0;L;;;;;N;;;;;
+189A0;TANGUT COMPONENT-417;Lo;0;L;;;;;N;;;;;
+189A1;TANGUT COMPONENT-418;Lo;0;L;;;;;N;;;;;
+189A2;TANGUT COMPONENT-419;Lo;0;L;;;;;N;;;;;
+189A3;TANGUT COMPONENT-420;Lo;0;L;;;;;N;;;;;
+189A4;TANGUT COMPONENT-421;Lo;0;L;;;;;N;;;;;
+189A5;TANGUT COMPONENT-422;Lo;0;L;;;;;N;;;;;
+189A6;TANGUT COMPONENT-423;Lo;0;L;;;;;N;;;;;
+189A7;TANGUT COMPONENT-424;Lo;0;L;;;;;N;;;;;
+189A8;TANGUT COMPONENT-425;Lo;0;L;;;;;N;;;;;
+189A9;TANGUT COMPONENT-426;Lo;0;L;;;;;N;;;;;
+189AA;TANGUT COMPONENT-427;Lo;0;L;;;;;N;;;;;
+189AB;TANGUT COMPONENT-428;Lo;0;L;;;;;N;;;;;
+189AC;TANGUT COMPONENT-429;Lo;0;L;;;;;N;;;;;
+189AD;TANGUT COMPONENT-430;Lo;0;L;;;;;N;;;;;
+189AE;TANGUT COMPONENT-431;Lo;0;L;;;;;N;;;;;
+189AF;TANGUT COMPONENT-432;Lo;0;L;;;;;N;;;;;
+189B0;TANGUT COMPONENT-433;Lo;0;L;;;;;N;;;;;
+189B1;TANGUT COMPONENT-434;Lo;0;L;;;;;N;;;;;
+189B2;TANGUT COMPONENT-435;Lo;0;L;;;;;N;;;;;
+189B3;TANGUT COMPONENT-436;Lo;0;L;;;;;N;;;;;
+189B4;TANGUT COMPONENT-437;Lo;0;L;;;;;N;;;;;
+189B5;TANGUT COMPONENT-438;Lo;0;L;;;;;N;;;;;
+189B6;TANGUT COMPONENT-439;Lo;0;L;;;;;N;;;;;
+189B7;TANGUT COMPONENT-440;Lo;0;L;;;;;N;;;;;
+189B8;TANGUT COMPONENT-441;Lo;0;L;;;;;N;;;;;
+189B9;TANGUT COMPONENT-442;Lo;0;L;;;;;N;;;;;
+189BA;TANGUT COMPONENT-443;Lo;0;L;;;;;N;;;;;
+189BB;TANGUT COMPONENT-444;Lo;0;L;;;;;N;;;;;
+189BC;TANGUT COMPONENT-445;Lo;0;L;;;;;N;;;;;
+189BD;TANGUT COMPONENT-446;Lo;0;L;;;;;N;;;;;
+189BE;TANGUT COMPONENT-447;Lo;0;L;;;;;N;;;;;
+189BF;TANGUT COMPONENT-448;Lo;0;L;;;;;N;;;;;
+189C0;TANGUT COMPONENT-449;Lo;0;L;;;;;N;;;;;
+189C1;TANGUT COMPONENT-450;Lo;0;L;;;;;N;;;;;
+189C2;TANGUT COMPONENT-451;Lo;0;L;;;;;N;;;;;
+189C3;TANGUT COMPONENT-452;Lo;0;L;;;;;N;;;;;
+189C4;TANGUT COMPONENT-453;Lo;0;L;;;;;N;;;;;
+189C5;TANGUT COMPONENT-454;Lo;0;L;;;;;N;;;;;
+189C6;TANGUT COMPONENT-455;Lo;0;L;;;;;N;;;;;
+189C7;TANGUT COMPONENT-456;Lo;0;L;;;;;N;;;;;
+189C8;TANGUT COMPONENT-457;Lo;0;L;;;;;N;;;;;
+189C9;TANGUT COMPONENT-458;Lo;0;L;;;;;N;;;;;
+189CA;TANGUT COMPONENT-459;Lo;0;L;;;;;N;;;;;
+189CB;TANGUT COMPONENT-460;Lo;0;L;;;;;N;;;;;
+189CC;TANGUT COMPONENT-461;Lo;0;L;;;;;N;;;;;
+189CD;TANGUT COMPONENT-462;Lo;0;L;;;;;N;;;;;
+189CE;TANGUT COMPONENT-463;Lo;0;L;;;;;N;;;;;
+189CF;TANGUT COMPONENT-464;Lo;0;L;;;;;N;;;;;
+189D0;TANGUT COMPONENT-465;Lo;0;L;;;;;N;;;;;
+189D1;TANGUT COMPONENT-466;Lo;0;L;;;;;N;;;;;
+189D2;TANGUT COMPONENT-467;Lo;0;L;;;;;N;;;;;
+189D3;TANGUT COMPONENT-468;Lo;0;L;;;;;N;;;;;
+189D4;TANGUT COMPONENT-469;Lo;0;L;;;;;N;;;;;
+189D5;TANGUT COMPONENT-470;Lo;0;L;;;;;N;;;;;
+189D6;TANGUT COMPONENT-471;Lo;0;L;;;;;N;;;;;
+189D7;TANGUT COMPONENT-472;Lo;0;L;;;;;N;;;;;
+189D8;TANGUT COMPONENT-473;Lo;0;L;;;;;N;;;;;
+189D9;TANGUT COMPONENT-474;Lo;0;L;;;;;N;;;;;
+189DA;TANGUT COMPONENT-475;Lo;0;L;;;;;N;;;;;
+189DB;TANGUT COMPONENT-476;Lo;0;L;;;;;N;;;;;
+189DC;TANGUT COMPONENT-477;Lo;0;L;;;;;N;;;;;
+189DD;TANGUT COMPONENT-478;Lo;0;L;;;;;N;;;;;
+189DE;TANGUT COMPONENT-479;Lo;0;L;;;;;N;;;;;
+189DF;TANGUT COMPONENT-480;Lo;0;L;;;;;N;;;;;
+189E0;TANGUT COMPONENT-481;Lo;0;L;;;;;N;;;;;
+189E1;TANGUT COMPONENT-482;Lo;0;L;;;;;N;;;;;
+189E2;TANGUT COMPONENT-483;Lo;0;L;;;;;N;;;;;
+189E3;TANGUT COMPONENT-484;Lo;0;L;;;;;N;;;;;
+189E4;TANGUT COMPONENT-485;Lo;0;L;;;;;N;;;;;
+189E5;TANGUT COMPONENT-486;Lo;0;L;;;;;N;;;;;
+189E6;TANGUT COMPONENT-487;Lo;0;L;;;;;N;;;;;
+189E7;TANGUT COMPONENT-488;Lo;0;L;;;;;N;;;;;
+189E8;TANGUT COMPONENT-489;Lo;0;L;;;;;N;;;;;
+189E9;TANGUT COMPONENT-490;Lo;0;L;;;;;N;;;;;
+189EA;TANGUT COMPONENT-491;Lo;0;L;;;;;N;;;;;
+189EB;TANGUT COMPONENT-492;Lo;0;L;;;;;N;;;;;
+189EC;TANGUT COMPONENT-493;Lo;0;L;;;;;N;;;;;
+189ED;TANGUT COMPONENT-494;Lo;0;L;;;;;N;;;;;
+189EE;TANGUT COMPONENT-495;Lo;0;L;;;;;N;;;;;
+189EF;TANGUT COMPONENT-496;Lo;0;L;;;;;N;;;;;
+189F0;TANGUT COMPONENT-497;Lo;0;L;;;;;N;;;;;
+189F1;TANGUT COMPONENT-498;Lo;0;L;;;;;N;;;;;
+189F2;TANGUT COMPONENT-499;Lo;0;L;;;;;N;;;;;
+189F3;TANGUT COMPONENT-500;Lo;0;L;;;;;N;;;;;
+189F4;TANGUT COMPONENT-501;Lo;0;L;;;;;N;;;;;
+189F5;TANGUT COMPONENT-502;Lo;0;L;;;;;N;;;;;
+189F6;TANGUT COMPONENT-503;Lo;0;L;;;;;N;;;;;
+189F7;TANGUT COMPONENT-504;Lo;0;L;;;;;N;;;;;
+189F8;TANGUT COMPONENT-505;Lo;0;L;;;;;N;;;;;
+189F9;TANGUT COMPONENT-506;Lo;0;L;;;;;N;;;;;
+189FA;TANGUT COMPONENT-507;Lo;0;L;;;;;N;;;;;
+189FB;TANGUT COMPONENT-508;Lo;0;L;;;;;N;;;;;
+189FC;TANGUT COMPONENT-509;Lo;0;L;;;;;N;;;;;
+189FD;TANGUT COMPONENT-510;Lo;0;L;;;;;N;;;;;
+189FE;TANGUT COMPONENT-511;Lo;0;L;;;;;N;;;;;
+189FF;TANGUT COMPONENT-512;Lo;0;L;;;;;N;;;;;
+18A00;TANGUT COMPONENT-513;Lo;0;L;;;;;N;;;;;
+18A01;TANGUT COMPONENT-514;Lo;0;L;;;;;N;;;;;
+18A02;TANGUT COMPONENT-515;Lo;0;L;;;;;N;;;;;
+18A03;TANGUT COMPONENT-516;Lo;0;L;;;;;N;;;;;
+18A04;TANGUT COMPONENT-517;Lo;0;L;;;;;N;;;;;
+18A05;TANGUT COMPONENT-518;Lo;0;L;;;;;N;;;;;
+18A06;TANGUT COMPONENT-519;Lo;0;L;;;;;N;;;;;
+18A07;TANGUT COMPONENT-520;Lo;0;L;;;;;N;;;;;
+18A08;TANGUT COMPONENT-521;Lo;0;L;;;;;N;;;;;
+18A09;TANGUT COMPONENT-522;Lo;0;L;;;;;N;;;;;
+18A0A;TANGUT COMPONENT-523;Lo;0;L;;;;;N;;;;;
+18A0B;TANGUT COMPONENT-524;Lo;0;L;;;;;N;;;;;
+18A0C;TANGUT COMPONENT-525;Lo;0;L;;;;;N;;;;;
+18A0D;TANGUT COMPONENT-526;Lo;0;L;;;;;N;;;;;
+18A0E;TANGUT COMPONENT-527;Lo;0;L;;;;;N;;;;;
+18A0F;TANGUT COMPONENT-528;Lo;0;L;;;;;N;;;;;
+18A10;TANGUT COMPONENT-529;Lo;0;L;;;;;N;;;;;
+18A11;TANGUT COMPONENT-530;Lo;0;L;;;;;N;;;;;
+18A12;TANGUT COMPONENT-531;Lo;0;L;;;;;N;;;;;
+18A13;TANGUT COMPONENT-532;Lo;0;L;;;;;N;;;;;
+18A14;TANGUT COMPONENT-533;Lo;0;L;;;;;N;;;;;
+18A15;TANGUT COMPONENT-534;Lo;0;L;;;;;N;;;;;
+18A16;TANGUT COMPONENT-535;Lo;0;L;;;;;N;;;;;
+18A17;TANGUT COMPONENT-536;Lo;0;L;;;;;N;;;;;
+18A18;TANGUT COMPONENT-537;Lo;0;L;;;;;N;;;;;
+18A19;TANGUT COMPONENT-538;Lo;0;L;;;;;N;;;;;
+18A1A;TANGUT COMPONENT-539;Lo;0;L;;;;;N;;;;;
+18A1B;TANGUT COMPONENT-540;Lo;0;L;;;;;N;;;;;
+18A1C;TANGUT COMPONENT-541;Lo;0;L;;;;;N;;;;;
+18A1D;TANGUT COMPONENT-542;Lo;0;L;;;;;N;;;;;
+18A1E;TANGUT COMPONENT-543;Lo;0;L;;;;;N;;;;;
+18A1F;TANGUT COMPONENT-544;Lo;0;L;;;;;N;;;;;
+18A20;TANGUT COMPONENT-545;Lo;0;L;;;;;N;;;;;
+18A21;TANGUT COMPONENT-546;Lo;0;L;;;;;N;;;;;
+18A22;TANGUT COMPONENT-547;Lo;0;L;;;;;N;;;;;
+18A23;TANGUT COMPONENT-548;Lo;0;L;;;;;N;;;;;
+18A24;TANGUT COMPONENT-549;Lo;0;L;;;;;N;;;;;
+18A25;TANGUT COMPONENT-550;Lo;0;L;;;;;N;;;;;
+18A26;TANGUT COMPONENT-551;Lo;0;L;;;;;N;;;;;
+18A27;TANGUT COMPONENT-552;Lo;0;L;;;;;N;;;;;
+18A28;TANGUT COMPONENT-553;Lo;0;L;;;;;N;;;;;
+18A29;TANGUT COMPONENT-554;Lo;0;L;;;;;N;;;;;
+18A2A;TANGUT COMPONENT-555;Lo;0;L;;;;;N;;;;;
+18A2B;TANGUT COMPONENT-556;Lo;0;L;;;;;N;;;;;
+18A2C;TANGUT COMPONENT-557;Lo;0;L;;;;;N;;;;;
+18A2D;TANGUT COMPONENT-558;Lo;0;L;;;;;N;;;;;
+18A2E;TANGUT COMPONENT-559;Lo;0;L;;;;;N;;;;;
+18A2F;TANGUT COMPONENT-560;Lo;0;L;;;;;N;;;;;
+18A30;TANGUT COMPONENT-561;Lo;0;L;;;;;N;;;;;
+18A31;TANGUT COMPONENT-562;Lo;0;L;;;;;N;;;;;
+18A32;TANGUT COMPONENT-563;Lo;0;L;;;;;N;;;;;
+18A33;TANGUT COMPONENT-564;Lo;0;L;;;;;N;;;;;
+18A34;TANGUT COMPONENT-565;Lo;0;L;;;;;N;;;;;
+18A35;TANGUT COMPONENT-566;Lo;0;L;;;;;N;;;;;
+18A36;TANGUT COMPONENT-567;Lo;0;L;;;;;N;;;;;
+18A37;TANGUT COMPONENT-568;Lo;0;L;;;;;N;;;;;
+18A38;TANGUT COMPONENT-569;Lo;0;L;;;;;N;;;;;
+18A39;TANGUT COMPONENT-570;Lo;0;L;;;;;N;;;;;
+18A3A;TANGUT COMPONENT-571;Lo;0;L;;;;;N;;;;;
+18A3B;TANGUT COMPONENT-572;Lo;0;L;;;;;N;;;;;
+18A3C;TANGUT COMPONENT-573;Lo;0;L;;;;;N;;;;;
+18A3D;TANGUT COMPONENT-574;Lo;0;L;;;;;N;;;;;
+18A3E;TANGUT COMPONENT-575;Lo;0;L;;;;;N;;;;;
+18A3F;TANGUT COMPONENT-576;Lo;0;L;;;;;N;;;;;
+18A40;TANGUT COMPONENT-577;Lo;0;L;;;;;N;;;;;
+18A41;TANGUT COMPONENT-578;Lo;0;L;;;;;N;;;;;
+18A42;TANGUT COMPONENT-579;Lo;0;L;;;;;N;;;;;
+18A43;TANGUT COMPONENT-580;Lo;0;L;;;;;N;;;;;
+18A44;TANGUT COMPONENT-581;Lo;0;L;;;;;N;;;;;
+18A45;TANGUT COMPONENT-582;Lo;0;L;;;;;N;;;;;
+18A46;TANGUT COMPONENT-583;Lo;0;L;;;;;N;;;;;
+18A47;TANGUT COMPONENT-584;Lo;0;L;;;;;N;;;;;
+18A48;TANGUT COMPONENT-585;Lo;0;L;;;;;N;;;;;
+18A49;TANGUT COMPONENT-586;Lo;0;L;;;;;N;;;;;
+18A4A;TANGUT COMPONENT-587;Lo;0;L;;;;;N;;;;;
+18A4B;TANGUT COMPONENT-588;Lo;0;L;;;;;N;;;;;
+18A4C;TANGUT COMPONENT-589;Lo;0;L;;;;;N;;;;;
+18A4D;TANGUT COMPONENT-590;Lo;0;L;;;;;N;;;;;
+18A4E;TANGUT COMPONENT-591;Lo;0;L;;;;;N;;;;;
+18A4F;TANGUT COMPONENT-592;Lo;0;L;;;;;N;;;;;
+18A50;TANGUT COMPONENT-593;Lo;0;L;;;;;N;;;;;
+18A51;TANGUT COMPONENT-594;Lo;0;L;;;;;N;;;;;
+18A52;TANGUT COMPONENT-595;Lo;0;L;;;;;N;;;;;
+18A53;TANGUT COMPONENT-596;Lo;0;L;;;;;N;;;;;
+18A54;TANGUT COMPONENT-597;Lo;0;L;;;;;N;;;;;
+18A55;TANGUT COMPONENT-598;Lo;0;L;;;;;N;;;;;
+18A56;TANGUT COMPONENT-599;Lo;0;L;;;;;N;;;;;
+18A57;TANGUT COMPONENT-600;Lo;0;L;;;;;N;;;;;
+18A58;TANGUT COMPONENT-601;Lo;0;L;;;;;N;;;;;
+18A59;TANGUT COMPONENT-602;Lo;0;L;;;;;N;;;;;
+18A5A;TANGUT COMPONENT-603;Lo;0;L;;;;;N;;;;;
+18A5B;TANGUT COMPONENT-604;Lo;0;L;;;;;N;;;;;
+18A5C;TANGUT COMPONENT-605;Lo;0;L;;;;;N;;;;;
+18A5D;TANGUT COMPONENT-606;Lo;0;L;;;;;N;;;;;
+18A5E;TANGUT COMPONENT-607;Lo;0;L;;;;;N;;;;;
+18A5F;TANGUT COMPONENT-608;Lo;0;L;;;;;N;;;;;
+18A60;TANGUT COMPONENT-609;Lo;0;L;;;;;N;;;;;
+18A61;TANGUT COMPONENT-610;Lo;0;L;;;;;N;;;;;
+18A62;TANGUT COMPONENT-611;Lo;0;L;;;;;N;;;;;
+18A63;TANGUT COMPONENT-612;Lo;0;L;;;;;N;;;;;
+18A64;TANGUT COMPONENT-613;Lo;0;L;;;;;N;;;;;
+18A65;TANGUT COMPONENT-614;Lo;0;L;;;;;N;;;;;
+18A66;TANGUT COMPONENT-615;Lo;0;L;;;;;N;;;;;
+18A67;TANGUT COMPONENT-616;Lo;0;L;;;;;N;;;;;
+18A68;TANGUT COMPONENT-617;Lo;0;L;;;;;N;;;;;
+18A69;TANGUT COMPONENT-618;Lo;0;L;;;;;N;;;;;
+18A6A;TANGUT COMPONENT-619;Lo;0;L;;;;;N;;;;;
+18A6B;TANGUT COMPONENT-620;Lo;0;L;;;;;N;;;;;
+18A6C;TANGUT COMPONENT-621;Lo;0;L;;;;;N;;;;;
+18A6D;TANGUT COMPONENT-622;Lo;0;L;;;;;N;;;;;
+18A6E;TANGUT COMPONENT-623;Lo;0;L;;;;;N;;;;;
+18A6F;TANGUT COMPONENT-624;Lo;0;L;;;;;N;;;;;
+18A70;TANGUT COMPONENT-625;Lo;0;L;;;;;N;;;;;
+18A71;TANGUT COMPONENT-626;Lo;0;L;;;;;N;;;;;
+18A72;TANGUT COMPONENT-627;Lo;0;L;;;;;N;;;;;
+18A73;TANGUT COMPONENT-628;Lo;0;L;;;;;N;;;;;
+18A74;TANGUT COMPONENT-629;Lo;0;L;;;;;N;;;;;
+18A75;TANGUT COMPONENT-630;Lo;0;L;;;;;N;;;;;
+18A76;TANGUT COMPONENT-631;Lo;0;L;;;;;N;;;;;
+18A77;TANGUT COMPONENT-632;Lo;0;L;;;;;N;;;;;
+18A78;TANGUT COMPONENT-633;Lo;0;L;;;;;N;;;;;
+18A79;TANGUT COMPONENT-634;Lo;0;L;;;;;N;;;;;
+18A7A;TANGUT COMPONENT-635;Lo;0;L;;;;;N;;;;;
+18A7B;TANGUT COMPONENT-636;Lo;0;L;;;;;N;;;;;
+18A7C;TANGUT COMPONENT-637;Lo;0;L;;;;;N;;;;;
+18A7D;TANGUT COMPONENT-638;Lo;0;L;;;;;N;;;;;
+18A7E;TANGUT COMPONENT-639;Lo;0;L;;;;;N;;;;;
+18A7F;TANGUT COMPONENT-640;Lo;0;L;;;;;N;;;;;
+18A80;TANGUT COMPONENT-641;Lo;0;L;;;;;N;;;;;
+18A81;TANGUT COMPONENT-642;Lo;0;L;;;;;N;;;;;
+18A82;TANGUT COMPONENT-643;Lo;0;L;;;;;N;;;;;
+18A83;TANGUT COMPONENT-644;Lo;0;L;;;;;N;;;;;
+18A84;TANGUT COMPONENT-645;Lo;0;L;;;;;N;;;;;
+18A85;TANGUT COMPONENT-646;Lo;0;L;;;;;N;;;;;
+18A86;TANGUT COMPONENT-647;Lo;0;L;;;;;N;;;;;
+18A87;TANGUT COMPONENT-648;Lo;0;L;;;;;N;;;;;
+18A88;TANGUT COMPONENT-649;Lo;0;L;;;;;N;;;;;
+18A89;TANGUT COMPONENT-650;Lo;0;L;;;;;N;;;;;
+18A8A;TANGUT COMPONENT-651;Lo;0;L;;;;;N;;;;;
+18A8B;TANGUT COMPONENT-652;Lo;0;L;;;;;N;;;;;
+18A8C;TANGUT COMPONENT-653;Lo;0;L;;;;;N;;;;;
+18A8D;TANGUT COMPONENT-654;Lo;0;L;;;;;N;;;;;
+18A8E;TANGUT COMPONENT-655;Lo;0;L;;;;;N;;;;;
+18A8F;TANGUT COMPONENT-656;Lo;0;L;;;;;N;;;;;
+18A90;TANGUT COMPONENT-657;Lo;0;L;;;;;N;;;;;
+18A91;TANGUT COMPONENT-658;Lo;0;L;;;;;N;;;;;
+18A92;TANGUT COMPONENT-659;Lo;0;L;;;;;N;;;;;
+18A93;TANGUT COMPONENT-660;Lo;0;L;;;;;N;;;;;
+18A94;TANGUT COMPONENT-661;Lo;0;L;;;;;N;;;;;
+18A95;TANGUT COMPONENT-662;Lo;0;L;;;;;N;;;;;
+18A96;TANGUT COMPONENT-663;Lo;0;L;;;;;N;;;;;
+18A97;TANGUT COMPONENT-664;Lo;0;L;;;;;N;;;;;
+18A98;TANGUT COMPONENT-665;Lo;0;L;;;;;N;;;;;
+18A99;TANGUT COMPONENT-666;Lo;0;L;;;;;N;;;;;
+18A9A;TANGUT COMPONENT-667;Lo;0;L;;;;;N;;;;;
+18A9B;TANGUT COMPONENT-668;Lo;0;L;;;;;N;;;;;
+18A9C;TANGUT COMPONENT-669;Lo;0;L;;;;;N;;;;;
+18A9D;TANGUT COMPONENT-670;Lo;0;L;;;;;N;;;;;
+18A9E;TANGUT COMPONENT-671;Lo;0;L;;;;;N;;;;;
+18A9F;TANGUT COMPONENT-672;Lo;0;L;;;;;N;;;;;
+18AA0;TANGUT COMPONENT-673;Lo;0;L;;;;;N;;;;;
+18AA1;TANGUT COMPONENT-674;Lo;0;L;;;;;N;;;;;
+18AA2;TANGUT COMPONENT-675;Lo;0;L;;;;;N;;;;;
+18AA3;TANGUT COMPONENT-676;Lo;0;L;;;;;N;;;;;
+18AA4;TANGUT COMPONENT-677;Lo;0;L;;;;;N;;;;;
+18AA5;TANGUT COMPONENT-678;Lo;0;L;;;;;N;;;;;
+18AA6;TANGUT COMPONENT-679;Lo;0;L;;;;;N;;;;;
+18AA7;TANGUT COMPONENT-680;Lo;0;L;;;;;N;;;;;
+18AA8;TANGUT COMPONENT-681;Lo;0;L;;;;;N;;;;;
+18AA9;TANGUT COMPONENT-682;Lo;0;L;;;;;N;;;;;
+18AAA;TANGUT COMPONENT-683;Lo;0;L;;;;;N;;;;;
+18AAB;TANGUT COMPONENT-684;Lo;0;L;;;;;N;;;;;
+18AAC;TANGUT COMPONENT-685;Lo;0;L;;;;;N;;;;;
+18AAD;TANGUT COMPONENT-686;Lo;0;L;;;;;N;;;;;
+18AAE;TANGUT COMPONENT-687;Lo;0;L;;;;;N;;;;;
+18AAF;TANGUT COMPONENT-688;Lo;0;L;;;;;N;;;;;
+18AB0;TANGUT COMPONENT-689;Lo;0;L;;;;;N;;;;;
+18AB1;TANGUT COMPONENT-690;Lo;0;L;;;;;N;;;;;
+18AB2;TANGUT COMPONENT-691;Lo;0;L;;;;;N;;;;;
+18AB3;TANGUT COMPONENT-692;Lo;0;L;;;;;N;;;;;
+18AB4;TANGUT COMPONENT-693;Lo;0;L;;;;;N;;;;;
+18AB5;TANGUT COMPONENT-694;Lo;0;L;;;;;N;;;;;
+18AB6;TANGUT COMPONENT-695;Lo;0;L;;;;;N;;;;;
+18AB7;TANGUT COMPONENT-696;Lo;0;L;;;;;N;;;;;
+18AB8;TANGUT COMPONENT-697;Lo;0;L;;;;;N;;;;;
+18AB9;TANGUT COMPONENT-698;Lo;0;L;;;;;N;;;;;
+18ABA;TANGUT COMPONENT-699;Lo;0;L;;;;;N;;;;;
+18ABB;TANGUT COMPONENT-700;Lo;0;L;;;;;N;;;;;
+18ABC;TANGUT COMPONENT-701;Lo;0;L;;;;;N;;;;;
+18ABD;TANGUT COMPONENT-702;Lo;0;L;;;;;N;;;;;
+18ABE;TANGUT COMPONENT-703;Lo;0;L;;;;;N;;;;;
+18ABF;TANGUT COMPONENT-704;Lo;0;L;;;;;N;;;;;
+18AC0;TANGUT COMPONENT-705;Lo;0;L;;;;;N;;;;;
+18AC1;TANGUT COMPONENT-706;Lo;0;L;;;;;N;;;;;
+18AC2;TANGUT COMPONENT-707;Lo;0;L;;;;;N;;;;;
+18AC3;TANGUT COMPONENT-708;Lo;0;L;;;;;N;;;;;
+18AC4;TANGUT COMPONENT-709;Lo;0;L;;;;;N;;;;;
+18AC5;TANGUT COMPONENT-710;Lo;0;L;;;;;N;;;;;
+18AC6;TANGUT COMPONENT-711;Lo;0;L;;;;;N;;;;;
+18AC7;TANGUT COMPONENT-712;Lo;0;L;;;;;N;;;;;
+18AC8;TANGUT COMPONENT-713;Lo;0;L;;;;;N;;;;;
+18AC9;TANGUT COMPONENT-714;Lo;0;L;;;;;N;;;;;
+18ACA;TANGUT COMPONENT-715;Lo;0;L;;;;;N;;;;;
+18ACB;TANGUT COMPONENT-716;Lo;0;L;;;;;N;;;;;
+18ACC;TANGUT COMPONENT-717;Lo;0;L;;;;;N;;;;;
+18ACD;TANGUT COMPONENT-718;Lo;0;L;;;;;N;;;;;
+18ACE;TANGUT COMPONENT-719;Lo;0;L;;;;;N;;;;;
+18ACF;TANGUT COMPONENT-720;Lo;0;L;;;;;N;;;;;
+18AD0;TANGUT COMPONENT-721;Lo;0;L;;;;;N;;;;;
+18AD1;TANGUT COMPONENT-722;Lo;0;L;;;;;N;;;;;
+18AD2;TANGUT COMPONENT-723;Lo;0;L;;;;;N;;;;;
+18AD3;TANGUT COMPONENT-724;Lo;0;L;;;;;N;;;;;
+18AD4;TANGUT COMPONENT-725;Lo;0;L;;;;;N;;;;;
+18AD5;TANGUT COMPONENT-726;Lo;0;L;;;;;N;;;;;
+18AD6;TANGUT COMPONENT-727;Lo;0;L;;;;;N;;;;;
+18AD7;TANGUT COMPONENT-728;Lo;0;L;;;;;N;;;;;
+18AD8;TANGUT COMPONENT-729;Lo;0;L;;;;;N;;;;;
+18AD9;TANGUT COMPONENT-730;Lo;0;L;;;;;N;;;;;
+18ADA;TANGUT COMPONENT-731;Lo;0;L;;;;;N;;;;;
+18ADB;TANGUT COMPONENT-732;Lo;0;L;;;;;N;;;;;
+18ADC;TANGUT COMPONENT-733;Lo;0;L;;;;;N;;;;;
+18ADD;TANGUT COMPONENT-734;Lo;0;L;;;;;N;;;;;
+18ADE;TANGUT COMPONENT-735;Lo;0;L;;;;;N;;;;;
+18ADF;TANGUT COMPONENT-736;Lo;0;L;;;;;N;;;;;
+18AE0;TANGUT COMPONENT-737;Lo;0;L;;;;;N;;;;;
+18AE1;TANGUT COMPONENT-738;Lo;0;L;;;;;N;;;;;
+18AE2;TANGUT COMPONENT-739;Lo;0;L;;;;;N;;;;;
+18AE3;TANGUT COMPONENT-740;Lo;0;L;;;;;N;;;;;
+18AE4;TANGUT COMPONENT-741;Lo;0;L;;;;;N;;;;;
+18AE5;TANGUT COMPONENT-742;Lo;0;L;;;;;N;;;;;
+18AE6;TANGUT COMPONENT-743;Lo;0;L;;;;;N;;;;;
+18AE7;TANGUT COMPONENT-744;Lo;0;L;;;;;N;;;;;
+18AE8;TANGUT COMPONENT-745;Lo;0;L;;;;;N;;;;;
+18AE9;TANGUT COMPONENT-746;Lo;0;L;;;;;N;;;;;
+18AEA;TANGUT COMPONENT-747;Lo;0;L;;;;;N;;;;;
+18AEB;TANGUT COMPONENT-748;Lo;0;L;;;;;N;;;;;
+18AEC;TANGUT COMPONENT-749;Lo;0;L;;;;;N;;;;;
+18AED;TANGUT COMPONENT-750;Lo;0;L;;;;;N;;;;;
+18AEE;TANGUT COMPONENT-751;Lo;0;L;;;;;N;;;;;
+18AEF;TANGUT COMPONENT-752;Lo;0;L;;;;;N;;;;;
+18AF0;TANGUT COMPONENT-753;Lo;0;L;;;;;N;;;;;
+18AF1;TANGUT COMPONENT-754;Lo;0;L;;;;;N;;;;;
+18AF2;TANGUT COMPONENT-755;Lo;0;L;;;;;N;;;;;
+1B000;KATAKANA LETTER ARCHAIC E;Lo;0;L;;;;;N;;;;;
+1B001;HIRAGANA LETTER ARCHAIC YE;Lo;0;L;;;;;N;;;;;
+1B002;HENTAIGANA LETTER A-1;Lo;0;L;;;;;N;;;;;
+1B003;HENTAIGANA LETTER A-2;Lo;0;L;;;;;N;;;;;
+1B004;HENTAIGANA LETTER A-3;Lo;0;L;;;;;N;;;;;
+1B005;HENTAIGANA LETTER A-WO;Lo;0;L;;;;;N;;;;;
+1B006;HENTAIGANA LETTER I-1;Lo;0;L;;;;;N;;;;;
+1B007;HENTAIGANA LETTER I-2;Lo;0;L;;;;;N;;;;;
+1B008;HENTAIGANA LETTER I-3;Lo;0;L;;;;;N;;;;;
+1B009;HENTAIGANA LETTER I-4;Lo;0;L;;;;;N;;;;;
+1B00A;HENTAIGANA LETTER U-1;Lo;0;L;;;;;N;;;;;
+1B00B;HENTAIGANA LETTER U-2;Lo;0;L;;;;;N;;;;;
+1B00C;HENTAIGANA LETTER U-3;Lo;0;L;;;;;N;;;;;
+1B00D;HENTAIGANA LETTER U-4;Lo;0;L;;;;;N;;;;;
+1B00E;HENTAIGANA LETTER U-5;Lo;0;L;;;;;N;;;;;
+1B00F;HENTAIGANA LETTER E-2;Lo;0;L;;;;;N;;;;;
+1B010;HENTAIGANA LETTER E-3;Lo;0;L;;;;;N;;;;;
+1B011;HENTAIGANA LETTER E-4;Lo;0;L;;;;;N;;;;;
+1B012;HENTAIGANA LETTER E-5;Lo;0;L;;;;;N;;;;;
+1B013;HENTAIGANA LETTER E-6;Lo;0;L;;;;;N;;;;;
+1B014;HENTAIGANA LETTER O-1;Lo;0;L;;;;;N;;;;;
+1B015;HENTAIGANA LETTER O-2;Lo;0;L;;;;;N;;;;;
+1B016;HENTAIGANA LETTER O-3;Lo;0;L;;;;;N;;;;;
+1B017;HENTAIGANA LETTER KA-1;Lo;0;L;;;;;N;;;;;
+1B018;HENTAIGANA LETTER KA-2;Lo;0;L;;;;;N;;;;;
+1B019;HENTAIGANA LETTER KA-3;Lo;0;L;;;;;N;;;;;
+1B01A;HENTAIGANA LETTER KA-4;Lo;0;L;;;;;N;;;;;
+1B01B;HENTAIGANA LETTER KA-5;Lo;0;L;;;;;N;;;;;
+1B01C;HENTAIGANA LETTER KA-6;Lo;0;L;;;;;N;;;;;
+1B01D;HENTAIGANA LETTER KA-7;Lo;0;L;;;;;N;;;;;
+1B01E;HENTAIGANA LETTER KA-8;Lo;0;L;;;;;N;;;;;
+1B01F;HENTAIGANA LETTER KA-9;Lo;0;L;;;;;N;;;;;
+1B020;HENTAIGANA LETTER KA-10;Lo;0;L;;;;;N;;;;;
+1B021;HENTAIGANA LETTER KA-11;Lo;0;L;;;;;N;;;;;
+1B022;HENTAIGANA LETTER KA-KE;Lo;0;L;;;;;N;;;;;
+1B023;HENTAIGANA LETTER KI-1;Lo;0;L;;;;;N;;;;;
+1B024;HENTAIGANA LETTER KI-2;Lo;0;L;;;;;N;;;;;
+1B025;HENTAIGANA LETTER KI-3;Lo;0;L;;;;;N;;;;;
+1B026;HENTAIGANA LETTER KI-4;Lo;0;L;;;;;N;;;;;
+1B027;HENTAIGANA LETTER KI-5;Lo;0;L;;;;;N;;;;;
+1B028;HENTAIGANA LETTER KI-6;Lo;0;L;;;;;N;;;;;
+1B029;HENTAIGANA LETTER KI-7;Lo;0;L;;;;;N;;;;;
+1B02A;HENTAIGANA LETTER KI-8;Lo;0;L;;;;;N;;;;;
+1B02B;HENTAIGANA LETTER KU-1;Lo;0;L;;;;;N;;;;;
+1B02C;HENTAIGANA LETTER KU-2;Lo;0;L;;;;;N;;;;;
+1B02D;HENTAIGANA LETTER KU-3;Lo;0;L;;;;;N;;;;;
+1B02E;HENTAIGANA LETTER KU-4;Lo;0;L;;;;;N;;;;;
+1B02F;HENTAIGANA LETTER KU-5;Lo;0;L;;;;;N;;;;;
+1B030;HENTAIGANA LETTER KU-6;Lo;0;L;;;;;N;;;;;
+1B031;HENTAIGANA LETTER KU-7;Lo;0;L;;;;;N;;;;;
+1B032;HENTAIGANA LETTER KE-1;Lo;0;L;;;;;N;;;;;
+1B033;HENTAIGANA LETTER KE-2;Lo;0;L;;;;;N;;;;;
+1B034;HENTAIGANA LETTER KE-3;Lo;0;L;;;;;N;;;;;
+1B035;HENTAIGANA LETTER KE-4;Lo;0;L;;;;;N;;;;;
+1B036;HENTAIGANA LETTER KE-5;Lo;0;L;;;;;N;;;;;
+1B037;HENTAIGANA LETTER KE-6;Lo;0;L;;;;;N;;;;;
+1B038;HENTAIGANA LETTER KO-1;Lo;0;L;;;;;N;;;;;
+1B039;HENTAIGANA LETTER KO-2;Lo;0;L;;;;;N;;;;;
+1B03A;HENTAIGANA LETTER KO-3;Lo;0;L;;;;;N;;;;;
+1B03B;HENTAIGANA LETTER KO-KI;Lo;0;L;;;;;N;;;;;
+1B03C;HENTAIGANA LETTER SA-1;Lo;0;L;;;;;N;;;;;
+1B03D;HENTAIGANA LETTER SA-2;Lo;0;L;;;;;N;;;;;
+1B03E;HENTAIGANA LETTER SA-3;Lo;0;L;;;;;N;;;;;
+1B03F;HENTAIGANA LETTER SA-4;Lo;0;L;;;;;N;;;;;
+1B040;HENTAIGANA LETTER SA-5;Lo;0;L;;;;;N;;;;;
+1B041;HENTAIGANA LETTER SA-6;Lo;0;L;;;;;N;;;;;
+1B042;HENTAIGANA LETTER SA-7;Lo;0;L;;;;;N;;;;;
+1B043;HENTAIGANA LETTER SA-8;Lo;0;L;;;;;N;;;;;
+1B044;HENTAIGANA LETTER SI-1;Lo;0;L;;;;;N;;;;;
+1B045;HENTAIGANA LETTER SI-2;Lo;0;L;;;;;N;;;;;
+1B046;HENTAIGANA LETTER SI-3;Lo;0;L;;;;;N;;;;;
+1B047;HENTAIGANA LETTER SI-4;Lo;0;L;;;;;N;;;;;
+1B048;HENTAIGANA LETTER SI-5;Lo;0;L;;;;;N;;;;;
+1B049;HENTAIGANA LETTER SI-6;Lo;0;L;;;;;N;;;;;
+1B04A;HENTAIGANA LETTER SU-1;Lo;0;L;;;;;N;;;;;
+1B04B;HENTAIGANA LETTER SU-2;Lo;0;L;;;;;N;;;;;
+1B04C;HENTAIGANA LETTER SU-3;Lo;0;L;;;;;N;;;;;
+1B04D;HENTAIGANA LETTER SU-4;Lo;0;L;;;;;N;;;;;
+1B04E;HENTAIGANA LETTER SU-5;Lo;0;L;;;;;N;;;;;
+1B04F;HENTAIGANA LETTER SU-6;Lo;0;L;;;;;N;;;;;
+1B050;HENTAIGANA LETTER SU-7;Lo;0;L;;;;;N;;;;;
+1B051;HENTAIGANA LETTER SU-8;Lo;0;L;;;;;N;;;;;
+1B052;HENTAIGANA LETTER SE-1;Lo;0;L;;;;;N;;;;;
+1B053;HENTAIGANA LETTER SE-2;Lo;0;L;;;;;N;;;;;
+1B054;HENTAIGANA LETTER SE-3;Lo;0;L;;;;;N;;;;;
+1B055;HENTAIGANA LETTER SE-4;Lo;0;L;;;;;N;;;;;
+1B056;HENTAIGANA LETTER SE-5;Lo;0;L;;;;;N;;;;;
+1B057;HENTAIGANA LETTER SO-1;Lo;0;L;;;;;N;;;;;
+1B058;HENTAIGANA LETTER SO-2;Lo;0;L;;;;;N;;;;;
+1B059;HENTAIGANA LETTER SO-3;Lo;0;L;;;;;N;;;;;
+1B05A;HENTAIGANA LETTER SO-4;Lo;0;L;;;;;N;;;;;
+1B05B;HENTAIGANA LETTER SO-5;Lo;0;L;;;;;N;;;;;
+1B05C;HENTAIGANA LETTER SO-6;Lo;0;L;;;;;N;;;;;
+1B05D;HENTAIGANA LETTER SO-7;Lo;0;L;;;;;N;;;;;
+1B05E;HENTAIGANA LETTER TA-1;Lo;0;L;;;;;N;;;;;
+1B05F;HENTAIGANA LETTER TA-2;Lo;0;L;;;;;N;;;;;
+1B060;HENTAIGANA LETTER TA-3;Lo;0;L;;;;;N;;;;;
+1B061;HENTAIGANA LETTER TA-4;Lo;0;L;;;;;N;;;;;
+1B062;HENTAIGANA LETTER TI-1;Lo;0;L;;;;;N;;;;;
+1B063;HENTAIGANA LETTER TI-2;Lo;0;L;;;;;N;;;;;
+1B064;HENTAIGANA LETTER TI-3;Lo;0;L;;;;;N;;;;;
+1B065;HENTAIGANA LETTER TI-4;Lo;0;L;;;;;N;;;;;
+1B066;HENTAIGANA LETTER TI-5;Lo;0;L;;;;;N;;;;;
+1B067;HENTAIGANA LETTER TI-6;Lo;0;L;;;;;N;;;;;
+1B068;HENTAIGANA LETTER TI-7;Lo;0;L;;;;;N;;;;;
+1B069;HENTAIGANA LETTER TU-1;Lo;0;L;;;;;N;;;;;
+1B06A;HENTAIGANA LETTER TU-2;Lo;0;L;;;;;N;;;;;
+1B06B;HENTAIGANA LETTER TU-3;Lo;0;L;;;;;N;;;;;
+1B06C;HENTAIGANA LETTER TU-4;Lo;0;L;;;;;N;;;;;
+1B06D;HENTAIGANA LETTER TU-TO;Lo;0;L;;;;;N;;;;;
+1B06E;HENTAIGANA LETTER TE-1;Lo;0;L;;;;;N;;;;;
+1B06F;HENTAIGANA LETTER TE-2;Lo;0;L;;;;;N;;;;;
+1B070;HENTAIGANA LETTER TE-3;Lo;0;L;;;;;N;;;;;
+1B071;HENTAIGANA LETTER TE-4;Lo;0;L;;;;;N;;;;;
+1B072;HENTAIGANA LETTER TE-5;Lo;0;L;;;;;N;;;;;
+1B073;HENTAIGANA LETTER TE-6;Lo;0;L;;;;;N;;;;;
+1B074;HENTAIGANA LETTER TE-7;Lo;0;L;;;;;N;;;;;
+1B075;HENTAIGANA LETTER TE-8;Lo;0;L;;;;;N;;;;;
+1B076;HENTAIGANA LETTER TE-9;Lo;0;L;;;;;N;;;;;
+1B077;HENTAIGANA LETTER TO-1;Lo;0;L;;;;;N;;;;;
+1B078;HENTAIGANA LETTER TO-2;Lo;0;L;;;;;N;;;;;
+1B079;HENTAIGANA LETTER TO-3;Lo;0;L;;;;;N;;;;;
+1B07A;HENTAIGANA LETTER TO-4;Lo;0;L;;;;;N;;;;;
+1B07B;HENTAIGANA LETTER TO-5;Lo;0;L;;;;;N;;;;;
+1B07C;HENTAIGANA LETTER TO-6;Lo;0;L;;;;;N;;;;;
+1B07D;HENTAIGANA LETTER TO-RA;Lo;0;L;;;;;N;;;;;
+1B07E;HENTAIGANA LETTER NA-1;Lo;0;L;;;;;N;;;;;
+1B07F;HENTAIGANA LETTER NA-2;Lo;0;L;;;;;N;;;;;
+1B080;HENTAIGANA LETTER NA-3;Lo;0;L;;;;;N;;;;;
+1B081;HENTAIGANA LETTER NA-4;Lo;0;L;;;;;N;;;;;
+1B082;HENTAIGANA LETTER NA-5;Lo;0;L;;;;;N;;;;;
+1B083;HENTAIGANA LETTER NA-6;Lo;0;L;;;;;N;;;;;
+1B084;HENTAIGANA LETTER NA-7;Lo;0;L;;;;;N;;;;;
+1B085;HENTAIGANA LETTER NA-8;Lo;0;L;;;;;N;;;;;
+1B086;HENTAIGANA LETTER NA-9;Lo;0;L;;;;;N;;;;;
+1B087;HENTAIGANA LETTER NI-1;Lo;0;L;;;;;N;;;;;
+1B088;HENTAIGANA LETTER NI-2;Lo;0;L;;;;;N;;;;;
+1B089;HENTAIGANA LETTER NI-3;Lo;0;L;;;;;N;;;;;
+1B08A;HENTAIGANA LETTER NI-4;Lo;0;L;;;;;N;;;;;
+1B08B;HENTAIGANA LETTER NI-5;Lo;0;L;;;;;N;;;;;
+1B08C;HENTAIGANA LETTER NI-6;Lo;0;L;;;;;N;;;;;
+1B08D;HENTAIGANA LETTER NI-7;Lo;0;L;;;;;N;;;;;
+1B08E;HENTAIGANA LETTER NI-TE;Lo;0;L;;;;;N;;;;;
+1B08F;HENTAIGANA LETTER NU-1;Lo;0;L;;;;;N;;;;;
+1B090;HENTAIGANA LETTER NU-2;Lo;0;L;;;;;N;;;;;
+1B091;HENTAIGANA LETTER NU-3;Lo;0;L;;;;;N;;;;;
+1B092;HENTAIGANA LETTER NE-1;Lo;0;L;;;;;N;;;;;
+1B093;HENTAIGANA LETTER NE-2;Lo;0;L;;;;;N;;;;;
+1B094;HENTAIGANA LETTER NE-3;Lo;0;L;;;;;N;;;;;
+1B095;HENTAIGANA LETTER NE-4;Lo;0;L;;;;;N;;;;;
+1B096;HENTAIGANA LETTER NE-5;Lo;0;L;;;;;N;;;;;
+1B097;HENTAIGANA LETTER NE-6;Lo;0;L;;;;;N;;;;;
+1B098;HENTAIGANA LETTER NE-KO;Lo;0;L;;;;;N;;;;;
+1B099;HENTAIGANA LETTER NO-1;Lo;0;L;;;;;N;;;;;
+1B09A;HENTAIGANA LETTER NO-2;Lo;0;L;;;;;N;;;;;
+1B09B;HENTAIGANA LETTER NO-3;Lo;0;L;;;;;N;;;;;
+1B09C;HENTAIGANA LETTER NO-4;Lo;0;L;;;;;N;;;;;
+1B09D;HENTAIGANA LETTER NO-5;Lo;0;L;;;;;N;;;;;
+1B09E;HENTAIGANA LETTER HA-1;Lo;0;L;;;;;N;;;;;
+1B09F;HENTAIGANA LETTER HA-2;Lo;0;L;;;;;N;;;;;
+1B0A0;HENTAIGANA LETTER HA-3;Lo;0;L;;;;;N;;;;;
+1B0A1;HENTAIGANA LETTER HA-4;Lo;0;L;;;;;N;;;;;
+1B0A2;HENTAIGANA LETTER HA-5;Lo;0;L;;;;;N;;;;;
+1B0A3;HENTAIGANA LETTER HA-6;Lo;0;L;;;;;N;;;;;
+1B0A4;HENTAIGANA LETTER HA-7;Lo;0;L;;;;;N;;;;;
+1B0A5;HENTAIGANA LETTER HA-8;Lo;0;L;;;;;N;;;;;
+1B0A6;HENTAIGANA LETTER HA-9;Lo;0;L;;;;;N;;;;;
+1B0A7;HENTAIGANA LETTER HA-10;Lo;0;L;;;;;N;;;;;
+1B0A8;HENTAIGANA LETTER HA-11;Lo;0;L;;;;;N;;;;;
+1B0A9;HENTAIGANA LETTER HI-1;Lo;0;L;;;;;N;;;;;
+1B0AA;HENTAIGANA LETTER HI-2;Lo;0;L;;;;;N;;;;;
+1B0AB;HENTAIGANA LETTER HI-3;Lo;0;L;;;;;N;;;;;
+1B0AC;HENTAIGANA LETTER HI-4;Lo;0;L;;;;;N;;;;;
+1B0AD;HENTAIGANA LETTER HI-5;Lo;0;L;;;;;N;;;;;
+1B0AE;HENTAIGANA LETTER HI-6;Lo;0;L;;;;;N;;;;;
+1B0AF;HENTAIGANA LETTER HI-7;Lo;0;L;;;;;N;;;;;
+1B0B0;HENTAIGANA LETTER HU-1;Lo;0;L;;;;;N;;;;;
+1B0B1;HENTAIGANA LETTER HU-2;Lo;0;L;;;;;N;;;;;
+1B0B2;HENTAIGANA LETTER HU-3;Lo;0;L;;;;;N;;;;;
+1B0B3;HENTAIGANA LETTER HE-1;Lo;0;L;;;;;N;;;;;
+1B0B4;HENTAIGANA LETTER HE-2;Lo;0;L;;;;;N;;;;;
+1B0B5;HENTAIGANA LETTER HE-3;Lo;0;L;;;;;N;;;;;
+1B0B6;HENTAIGANA LETTER HE-4;Lo;0;L;;;;;N;;;;;
+1B0B7;HENTAIGANA LETTER HE-5;Lo;0;L;;;;;N;;;;;
+1B0B8;HENTAIGANA LETTER HE-6;Lo;0;L;;;;;N;;;;;
+1B0B9;HENTAIGANA LETTER HE-7;Lo;0;L;;;;;N;;;;;
+1B0BA;HENTAIGANA LETTER HO-1;Lo;0;L;;;;;N;;;;;
+1B0BB;HENTAIGANA LETTER HO-2;Lo;0;L;;;;;N;;;;;
+1B0BC;HENTAIGANA LETTER HO-3;Lo;0;L;;;;;N;;;;;
+1B0BD;HENTAIGANA LETTER HO-4;Lo;0;L;;;;;N;;;;;
+1B0BE;HENTAIGANA LETTER HO-5;Lo;0;L;;;;;N;;;;;
+1B0BF;HENTAIGANA LETTER HO-6;Lo;0;L;;;;;N;;;;;
+1B0C0;HENTAIGANA LETTER HO-7;Lo;0;L;;;;;N;;;;;
+1B0C1;HENTAIGANA LETTER HO-8;Lo;0;L;;;;;N;;;;;
+1B0C2;HENTAIGANA LETTER MA-1;Lo;0;L;;;;;N;;;;;
+1B0C3;HENTAIGANA LETTER MA-2;Lo;0;L;;;;;N;;;;;
+1B0C4;HENTAIGANA LETTER MA-3;Lo;0;L;;;;;N;;;;;
+1B0C5;HENTAIGANA LETTER MA-4;Lo;0;L;;;;;N;;;;;
+1B0C6;HENTAIGANA LETTER MA-5;Lo;0;L;;;;;N;;;;;
+1B0C7;HENTAIGANA LETTER MA-6;Lo;0;L;;;;;N;;;;;
+1B0C8;HENTAIGANA LETTER MA-7;Lo;0;L;;;;;N;;;;;
+1B0C9;HENTAIGANA LETTER MI-1;Lo;0;L;;;;;N;;;;;
+1B0CA;HENTAIGANA LETTER MI-2;Lo;0;L;;;;;N;;;;;
+1B0CB;HENTAIGANA LETTER MI-3;Lo;0;L;;;;;N;;;;;
+1B0CC;HENTAIGANA LETTER MI-4;Lo;0;L;;;;;N;;;;;
+1B0CD;HENTAIGANA LETTER MI-5;Lo;0;L;;;;;N;;;;;
+1B0CE;HENTAIGANA LETTER MI-6;Lo;0;L;;;;;N;;;;;
+1B0CF;HENTAIGANA LETTER MI-7;Lo;0;L;;;;;N;;;;;
+1B0D0;HENTAIGANA LETTER MU-1;Lo;0;L;;;;;N;;;;;
+1B0D1;HENTAIGANA LETTER MU-2;Lo;0;L;;;;;N;;;;;
+1B0D2;HENTAIGANA LETTER MU-3;Lo;0;L;;;;;N;;;;;
+1B0D3;HENTAIGANA LETTER MU-4;Lo;0;L;;;;;N;;;;;
+1B0D4;HENTAIGANA LETTER ME-1;Lo;0;L;;;;;N;;;;;
+1B0D5;HENTAIGANA LETTER ME-2;Lo;0;L;;;;;N;;;;;
+1B0D6;HENTAIGANA LETTER ME-MA;Lo;0;L;;;;;N;;;;;
+1B0D7;HENTAIGANA LETTER MO-1;Lo;0;L;;;;;N;;;;;
+1B0D8;HENTAIGANA LETTER MO-2;Lo;0;L;;;;;N;;;;;
+1B0D9;HENTAIGANA LETTER MO-3;Lo;0;L;;;;;N;;;;;
+1B0DA;HENTAIGANA LETTER MO-4;Lo;0;L;;;;;N;;;;;
+1B0DB;HENTAIGANA LETTER MO-5;Lo;0;L;;;;;N;;;;;
+1B0DC;HENTAIGANA LETTER MO-6;Lo;0;L;;;;;N;;;;;
+1B0DD;HENTAIGANA LETTER YA-1;Lo;0;L;;;;;N;;;;;
+1B0DE;HENTAIGANA LETTER YA-2;Lo;0;L;;;;;N;;;;;
+1B0DF;HENTAIGANA LETTER YA-3;Lo;0;L;;;;;N;;;;;
+1B0E0;HENTAIGANA LETTER YA-4;Lo;0;L;;;;;N;;;;;
+1B0E1;HENTAIGANA LETTER YA-5;Lo;0;L;;;;;N;;;;;
+1B0E2;HENTAIGANA LETTER YA-YO;Lo;0;L;;;;;N;;;;;
+1B0E3;HENTAIGANA LETTER YU-1;Lo;0;L;;;;;N;;;;;
+1B0E4;HENTAIGANA LETTER YU-2;Lo;0;L;;;;;N;;;;;
+1B0E5;HENTAIGANA LETTER YU-3;Lo;0;L;;;;;N;;;;;
+1B0E6;HENTAIGANA LETTER YU-4;Lo;0;L;;;;;N;;;;;
+1B0E7;HENTAIGANA LETTER YO-1;Lo;0;L;;;;;N;;;;;
+1B0E8;HENTAIGANA LETTER YO-2;Lo;0;L;;;;;N;;;;;
+1B0E9;HENTAIGANA LETTER YO-3;Lo;0;L;;;;;N;;;;;
+1B0EA;HENTAIGANA LETTER YO-4;Lo;0;L;;;;;N;;;;;
+1B0EB;HENTAIGANA LETTER YO-5;Lo;0;L;;;;;N;;;;;
+1B0EC;HENTAIGANA LETTER YO-6;Lo;0;L;;;;;N;;;;;
+1B0ED;HENTAIGANA LETTER RA-1;Lo;0;L;;;;;N;;;;;
+1B0EE;HENTAIGANA LETTER RA-2;Lo;0;L;;;;;N;;;;;
+1B0EF;HENTAIGANA LETTER RA-3;Lo;0;L;;;;;N;;;;;
+1B0F0;HENTAIGANA LETTER RA-4;Lo;0;L;;;;;N;;;;;
+1B0F1;HENTAIGANA LETTER RI-1;Lo;0;L;;;;;N;;;;;
+1B0F2;HENTAIGANA LETTER RI-2;Lo;0;L;;;;;N;;;;;
+1B0F3;HENTAIGANA LETTER RI-3;Lo;0;L;;;;;N;;;;;
+1B0F4;HENTAIGANA LETTER RI-4;Lo;0;L;;;;;N;;;;;
+1B0F5;HENTAIGANA LETTER RI-5;Lo;0;L;;;;;N;;;;;
+1B0F6;HENTAIGANA LETTER RI-6;Lo;0;L;;;;;N;;;;;
+1B0F7;HENTAIGANA LETTER RI-7;Lo;0;L;;;;;N;;;;;
+1B0F8;HENTAIGANA LETTER RU-1;Lo;0;L;;;;;N;;;;;
+1B0F9;HENTAIGANA LETTER RU-2;Lo;0;L;;;;;N;;;;;
+1B0FA;HENTAIGANA LETTER RU-3;Lo;0;L;;;;;N;;;;;
+1B0FB;HENTAIGANA LETTER RU-4;Lo;0;L;;;;;N;;;;;
+1B0FC;HENTAIGANA LETTER RU-5;Lo;0;L;;;;;N;;;;;
+1B0FD;HENTAIGANA LETTER RU-6;Lo;0;L;;;;;N;;;;;
+1B0FE;HENTAIGANA LETTER RE-1;Lo;0;L;;;;;N;;;;;
+1B0FF;HENTAIGANA LETTER RE-2;Lo;0;L;;;;;N;;;;;
+1B100;HENTAIGANA LETTER RE-3;Lo;0;L;;;;;N;;;;;
+1B101;HENTAIGANA LETTER RE-4;Lo;0;L;;;;;N;;;;;
+1B102;HENTAIGANA LETTER RO-1;Lo;0;L;;;;;N;;;;;
+1B103;HENTAIGANA LETTER RO-2;Lo;0;L;;;;;N;;;;;
+1B104;HENTAIGANA LETTER RO-3;Lo;0;L;;;;;N;;;;;
+1B105;HENTAIGANA LETTER RO-4;Lo;0;L;;;;;N;;;;;
+1B106;HENTAIGANA LETTER RO-5;Lo;0;L;;;;;N;;;;;
+1B107;HENTAIGANA LETTER RO-6;Lo;0;L;;;;;N;;;;;
+1B108;HENTAIGANA LETTER WA-1;Lo;0;L;;;;;N;;;;;
+1B109;HENTAIGANA LETTER WA-2;Lo;0;L;;;;;N;;;;;
+1B10A;HENTAIGANA LETTER WA-3;Lo;0;L;;;;;N;;;;;
+1B10B;HENTAIGANA LETTER WA-4;Lo;0;L;;;;;N;;;;;
+1B10C;HENTAIGANA LETTER WA-5;Lo;0;L;;;;;N;;;;;
+1B10D;HENTAIGANA LETTER WI-1;Lo;0;L;;;;;N;;;;;
+1B10E;HENTAIGANA LETTER WI-2;Lo;0;L;;;;;N;;;;;
+1B10F;HENTAIGANA LETTER WI-3;Lo;0;L;;;;;N;;;;;
+1B110;HENTAIGANA LETTER WI-4;Lo;0;L;;;;;N;;;;;
+1B111;HENTAIGANA LETTER WI-5;Lo;0;L;;;;;N;;;;;
+1B112;HENTAIGANA LETTER WE-1;Lo;0;L;;;;;N;;;;;
+1B113;HENTAIGANA LETTER WE-2;Lo;0;L;;;;;N;;;;;
+1B114;HENTAIGANA LETTER WE-3;Lo;0;L;;;;;N;;;;;
+1B115;HENTAIGANA LETTER WE-4;Lo;0;L;;;;;N;;;;;
+1B116;HENTAIGANA LETTER WO-1;Lo;0;L;;;;;N;;;;;
+1B117;HENTAIGANA LETTER WO-2;Lo;0;L;;;;;N;;;;;
+1B118;HENTAIGANA LETTER WO-3;Lo;0;L;;;;;N;;;;;
+1B119;HENTAIGANA LETTER WO-4;Lo;0;L;;;;;N;;;;;
+1B11A;HENTAIGANA LETTER WO-5;Lo;0;L;;;;;N;;;;;
+1B11B;HENTAIGANA LETTER WO-6;Lo;0;L;;;;;N;;;;;
+1B11C;HENTAIGANA LETTER WO-7;Lo;0;L;;;;;N;;;;;
+1B11D;HENTAIGANA LETTER N-MU-MO-1;Lo;0;L;;;;;N;;;;;
+1B11E;HENTAIGANA LETTER N-MU-MO-2;Lo;0;L;;;;;N;;;;;
+1B170;NUSHU CHARACTER-1B170;Lo;0;L;;;;;N;;;;;
+1B171;NUSHU CHARACTER-1B171;Lo;0;L;;;;;N;;;;;
+1B172;NUSHU CHARACTER-1B172;Lo;0;L;;;;;N;;;;;
+1B173;NUSHU CHARACTER-1B173;Lo;0;L;;;;;N;;;;;
+1B174;NUSHU CHARACTER-1B174;Lo;0;L;;;;;N;;;;;
+1B175;NUSHU CHARACTER-1B175;Lo;0;L;;;;;N;;;;;
+1B176;NUSHU CHARACTER-1B176;Lo;0;L;;;;;N;;;;;
+1B177;NUSHU CHARACTER-1B177;Lo;0;L;;;;;N;;;;;
+1B178;NUSHU CHARACTER-1B178;Lo;0;L;;;;;N;;;;;
+1B179;NUSHU CHARACTER-1B179;Lo;0;L;;;;;N;;;;;
+1B17A;NUSHU CHARACTER-1B17A;Lo;0;L;;;;;N;;;;;
+1B17B;NUSHU CHARACTER-1B17B;Lo;0;L;;;;;N;;;;;
+1B17C;NUSHU CHARACTER-1B17C;Lo;0;L;;;;;N;;;;;
+1B17D;NUSHU CHARACTER-1B17D;Lo;0;L;;;;;N;;;;;
+1B17E;NUSHU CHARACTER-1B17E;Lo;0;L;;;;;N;;;;;
+1B17F;NUSHU CHARACTER-1B17F;Lo;0;L;;;;;N;;;;;
+1B180;NUSHU CHARACTER-1B180;Lo;0;L;;;;;N;;;;;
+1B181;NUSHU CHARACTER-1B181;Lo;0;L;;;;;N;;;;;
+1B182;NUSHU CHARACTER-1B182;Lo;0;L;;;;;N;;;;;
+1B183;NUSHU CHARACTER-1B183;Lo;0;L;;;;;N;;;;;
+1B184;NUSHU CHARACTER-1B184;Lo;0;L;;;;;N;;;;;
+1B185;NUSHU CHARACTER-1B185;Lo;0;L;;;;;N;;;;;
+1B186;NUSHU CHARACTER-1B186;Lo;0;L;;;;;N;;;;;
+1B187;NUSHU CHARACTER-1B187;Lo;0;L;;;;;N;;;;;
+1B188;NUSHU CHARACTER-1B188;Lo;0;L;;;;;N;;;;;
+1B189;NUSHU CHARACTER-1B189;Lo;0;L;;;;;N;;;;;
+1B18A;NUSHU CHARACTER-1B18A;Lo;0;L;;;;;N;;;;;
+1B18B;NUSHU CHARACTER-1B18B;Lo;0;L;;;;;N;;;;;
+1B18C;NUSHU CHARACTER-1B18C;Lo;0;L;;;;;N;;;;;
+1B18D;NUSHU CHARACTER-1B18D;Lo;0;L;;;;;N;;;;;
+1B18E;NUSHU CHARACTER-1B18E;Lo;0;L;;;;;N;;;;;
+1B18F;NUSHU CHARACTER-1B18F;Lo;0;L;;;;;N;;;;;
+1B190;NUSHU CHARACTER-1B190;Lo;0;L;;;;;N;;;;;
+1B191;NUSHU CHARACTER-1B191;Lo;0;L;;;;;N;;;;;
+1B192;NUSHU CHARACTER-1B192;Lo;0;L;;;;;N;;;;;
+1B193;NUSHU CHARACTER-1B193;Lo;0;L;;;;;N;;;;;
+1B194;NUSHU CHARACTER-1B194;Lo;0;L;;;;;N;;;;;
+1B195;NUSHU CHARACTER-1B195;Lo;0;L;;;;;N;;;;;
+1B196;NUSHU CHARACTER-1B196;Lo;0;L;;;;;N;;;;;
+1B197;NUSHU CHARACTER-1B197;Lo;0;L;;;;;N;;;;;
+1B198;NUSHU CHARACTER-1B198;Lo;0;L;;;;;N;;;;;
+1B199;NUSHU CHARACTER-1B199;Lo;0;L;;;;;N;;;;;
+1B19A;NUSHU CHARACTER-1B19A;Lo;0;L;;;;;N;;;;;
+1B19B;NUSHU CHARACTER-1B19B;Lo;0;L;;;;;N;;;;;
+1B19C;NUSHU CHARACTER-1B19C;Lo;0;L;;;;;N;;;;;
+1B19D;NUSHU CHARACTER-1B19D;Lo;0;L;;;;;N;;;;;
+1B19E;NUSHU CHARACTER-1B19E;Lo;0;L;;;;;N;;;;;
+1B19F;NUSHU CHARACTER-1B19F;Lo;0;L;;;;;N;;;;;
+1B1A0;NUSHU CHARACTER-1B1A0;Lo;0;L;;;;;N;;;;;
+1B1A1;NUSHU CHARACTER-1B1A1;Lo;0;L;;;;;N;;;;;
+1B1A2;NUSHU CHARACTER-1B1A2;Lo;0;L;;;;;N;;;;;
+1B1A3;NUSHU CHARACTER-1B1A3;Lo;0;L;;;;;N;;;;;
+1B1A4;NUSHU CHARACTER-1B1A4;Lo;0;L;;;;;N;;;;;
+1B1A5;NUSHU CHARACTER-1B1A5;Lo;0;L;;;;;N;;;;;
+1B1A6;NUSHU CHARACTER-1B1A6;Lo;0;L;;;;;N;;;;;
+1B1A7;NUSHU CHARACTER-1B1A7;Lo;0;L;;;;;N;;;;;
+1B1A8;NUSHU CHARACTER-1B1A8;Lo;0;L;;;;;N;;;;;
+1B1A9;NUSHU CHARACTER-1B1A9;Lo;0;L;;;;;N;;;;;
+1B1AA;NUSHU CHARACTER-1B1AA;Lo;0;L;;;;;N;;;;;
+1B1AB;NUSHU CHARACTER-1B1AB;Lo;0;L;;;;;N;;;;;
+1B1AC;NUSHU CHARACTER-1B1AC;Lo;0;L;;;;;N;;;;;
+1B1AD;NUSHU CHARACTER-1B1AD;Lo;0;L;;;;;N;;;;;
+1B1AE;NUSHU CHARACTER-1B1AE;Lo;0;L;;;;;N;;;;;
+1B1AF;NUSHU CHARACTER-1B1AF;Lo;0;L;;;;;N;;;;;
+1B1B0;NUSHU CHARACTER-1B1B0;Lo;0;L;;;;;N;;;;;
+1B1B1;NUSHU CHARACTER-1B1B1;Lo;0;L;;;;;N;;;;;
+1B1B2;NUSHU CHARACTER-1B1B2;Lo;0;L;;;;;N;;;;;
+1B1B3;NUSHU CHARACTER-1B1B3;Lo;0;L;;;;;N;;;;;
+1B1B4;NUSHU CHARACTER-1B1B4;Lo;0;L;;;;;N;;;;;
+1B1B5;NUSHU CHARACTER-1B1B5;Lo;0;L;;;;;N;;;;;
+1B1B6;NUSHU CHARACTER-1B1B6;Lo;0;L;;;;;N;;;;;
+1B1B7;NUSHU CHARACTER-1B1B7;Lo;0;L;;;;;N;;;;;
+1B1B8;NUSHU CHARACTER-1B1B8;Lo;0;L;;;;;N;;;;;
+1B1B9;NUSHU CHARACTER-1B1B9;Lo;0;L;;;;;N;;;;;
+1B1BA;NUSHU CHARACTER-1B1BA;Lo;0;L;;;;;N;;;;;
+1B1BB;NUSHU CHARACTER-1B1BB;Lo;0;L;;;;;N;;;;;
+1B1BC;NUSHU CHARACTER-1B1BC;Lo;0;L;;;;;N;;;;;
+1B1BD;NUSHU CHARACTER-1B1BD;Lo;0;L;;;;;N;;;;;
+1B1BE;NUSHU CHARACTER-1B1BE;Lo;0;L;;;;;N;;;;;
+1B1BF;NUSHU CHARACTER-1B1BF;Lo;0;L;;;;;N;;;;;
+1B1C0;NUSHU CHARACTER-1B1C0;Lo;0;L;;;;;N;;;;;
+1B1C1;NUSHU CHARACTER-1B1C1;Lo;0;L;;;;;N;;;;;
+1B1C2;NUSHU CHARACTER-1B1C2;Lo;0;L;;;;;N;;;;;
+1B1C3;NUSHU CHARACTER-1B1C3;Lo;0;L;;;;;N;;;;;
+1B1C4;NUSHU CHARACTER-1B1C4;Lo;0;L;;;;;N;;;;;
+1B1C5;NUSHU CHARACTER-1B1C5;Lo;0;L;;;;;N;;;;;
+1B1C6;NUSHU CHARACTER-1B1C6;Lo;0;L;;;;;N;;;;;
+1B1C7;NUSHU CHARACTER-1B1C7;Lo;0;L;;;;;N;;;;;
+1B1C8;NUSHU CHARACTER-1B1C8;Lo;0;L;;;;;N;;;;;
+1B1C9;NUSHU CHARACTER-1B1C9;Lo;0;L;;;;;N;;;;;
+1B1CA;NUSHU CHARACTER-1B1CA;Lo;0;L;;;;;N;;;;;
+1B1CB;NUSHU CHARACTER-1B1CB;Lo;0;L;;;;;N;;;;;
+1B1CC;NUSHU CHARACTER-1B1CC;Lo;0;L;;;;;N;;;;;
+1B1CD;NUSHU CHARACTER-1B1CD;Lo;0;L;;;;;N;;;;;
+1B1CE;NUSHU CHARACTER-1B1CE;Lo;0;L;;;;;N;;;;;
+1B1CF;NUSHU CHARACTER-1B1CF;Lo;0;L;;;;;N;;;;;
+1B1D0;NUSHU CHARACTER-1B1D0;Lo;0;L;;;;;N;;;;;
+1B1D1;NUSHU CHARACTER-1B1D1;Lo;0;L;;;;;N;;;;;
+1B1D2;NUSHU CHARACTER-1B1D2;Lo;0;L;;;;;N;;;;;
+1B1D3;NUSHU CHARACTER-1B1D3;Lo;0;L;;;;;N;;;;;
+1B1D4;NUSHU CHARACTER-1B1D4;Lo;0;L;;;;;N;;;;;
+1B1D5;NUSHU CHARACTER-1B1D5;Lo;0;L;;;;;N;;;;;
+1B1D6;NUSHU CHARACTER-1B1D6;Lo;0;L;;;;;N;;;;;
+1B1D7;NUSHU CHARACTER-1B1D7;Lo;0;L;;;;;N;;;;;
+1B1D8;NUSHU CHARACTER-1B1D8;Lo;0;L;;;;;N;;;;;
+1B1D9;NUSHU CHARACTER-1B1D9;Lo;0;L;;;;;N;;;;;
+1B1DA;NUSHU CHARACTER-1B1DA;Lo;0;L;;;;;N;;;;;
+1B1DB;NUSHU CHARACTER-1B1DB;Lo;0;L;;;;;N;;;;;
+1B1DC;NUSHU CHARACTER-1B1DC;Lo;0;L;;;;;N;;;;;
+1B1DD;NUSHU CHARACTER-1B1DD;Lo;0;L;;;;;N;;;;;
+1B1DE;NUSHU CHARACTER-1B1DE;Lo;0;L;;;;;N;;;;;
+1B1DF;NUSHU CHARACTER-1B1DF;Lo;0;L;;;;;N;;;;;
+1B1E0;NUSHU CHARACTER-1B1E0;Lo;0;L;;;;;N;;;;;
+1B1E1;NUSHU CHARACTER-1B1E1;Lo;0;L;;;;;N;;;;;
+1B1E2;NUSHU CHARACTER-1B1E2;Lo;0;L;;;;;N;;;;;
+1B1E3;NUSHU CHARACTER-1B1E3;Lo;0;L;;;;;N;;;;;
+1B1E4;NUSHU CHARACTER-1B1E4;Lo;0;L;;;;;N;;;;;
+1B1E5;NUSHU CHARACTER-1B1E5;Lo;0;L;;;;;N;;;;;
+1B1E6;NUSHU CHARACTER-1B1E6;Lo;0;L;;;;;N;;;;;
+1B1E7;NUSHU CHARACTER-1B1E7;Lo;0;L;;;;;N;;;;;
+1B1E8;NUSHU CHARACTER-1B1E8;Lo;0;L;;;;;N;;;;;
+1B1E9;NUSHU CHARACTER-1B1E9;Lo;0;L;;;;;N;;;;;
+1B1EA;NUSHU CHARACTER-1B1EA;Lo;0;L;;;;;N;;;;;
+1B1EB;NUSHU CHARACTER-1B1EB;Lo;0;L;;;;;N;;;;;
+1B1EC;NUSHU CHARACTER-1B1EC;Lo;0;L;;;;;N;;;;;
+1B1ED;NUSHU CHARACTER-1B1ED;Lo;0;L;;;;;N;;;;;
+1B1EE;NUSHU CHARACTER-1B1EE;Lo;0;L;;;;;N;;;;;
+1B1EF;NUSHU CHARACTER-1B1EF;Lo;0;L;;;;;N;;;;;
+1B1F0;NUSHU CHARACTER-1B1F0;Lo;0;L;;;;;N;;;;;
+1B1F1;NUSHU CHARACTER-1B1F1;Lo;0;L;;;;;N;;;;;
+1B1F2;NUSHU CHARACTER-1B1F2;Lo;0;L;;;;;N;;;;;
+1B1F3;NUSHU CHARACTER-1B1F3;Lo;0;L;;;;;N;;;;;
+1B1F4;NUSHU CHARACTER-1B1F4;Lo;0;L;;;;;N;;;;;
+1B1F5;NUSHU CHARACTER-1B1F5;Lo;0;L;;;;;N;;;;;
+1B1F6;NUSHU CHARACTER-1B1F6;Lo;0;L;;;;;N;;;;;
+1B1F7;NUSHU CHARACTER-1B1F7;Lo;0;L;;;;;N;;;;;
+1B1F8;NUSHU CHARACTER-1B1F8;Lo;0;L;;;;;N;;;;;
+1B1F9;NUSHU CHARACTER-1B1F9;Lo;0;L;;;;;N;;;;;
+1B1FA;NUSHU CHARACTER-1B1FA;Lo;0;L;;;;;N;;;;;
+1B1FB;NUSHU CHARACTER-1B1FB;Lo;0;L;;;;;N;;;;;
+1B1FC;NUSHU CHARACTER-1B1FC;Lo;0;L;;;;;N;;;;;
+1B1FD;NUSHU CHARACTER-1B1FD;Lo;0;L;;;;;N;;;;;
+1B1FE;NUSHU CHARACTER-1B1FE;Lo;0;L;;;;;N;;;;;
+1B1FF;NUSHU CHARACTER-1B1FF;Lo;0;L;;;;;N;;;;;
+1B200;NUSHU CHARACTER-1B200;Lo;0;L;;;;;N;;;;;
+1B201;NUSHU CHARACTER-1B201;Lo;0;L;;;;;N;;;;;
+1B202;NUSHU CHARACTER-1B202;Lo;0;L;;;;;N;;;;;
+1B203;NUSHU CHARACTER-1B203;Lo;0;L;;;;;N;;;;;
+1B204;NUSHU CHARACTER-1B204;Lo;0;L;;;;;N;;;;;
+1B205;NUSHU CHARACTER-1B205;Lo;0;L;;;;;N;;;;;
+1B206;NUSHU CHARACTER-1B206;Lo;0;L;;;;;N;;;;;
+1B207;NUSHU CHARACTER-1B207;Lo;0;L;;;;;N;;;;;
+1B208;NUSHU CHARACTER-1B208;Lo;0;L;;;;;N;;;;;
+1B209;NUSHU CHARACTER-1B209;Lo;0;L;;;;;N;;;;;
+1B20A;NUSHU CHARACTER-1B20A;Lo;0;L;;;;;N;;;;;
+1B20B;NUSHU CHARACTER-1B20B;Lo;0;L;;;;;N;;;;;
+1B20C;NUSHU CHARACTER-1B20C;Lo;0;L;;;;;N;;;;;
+1B20D;NUSHU CHARACTER-1B20D;Lo;0;L;;;;;N;;;;;
+1B20E;NUSHU CHARACTER-1B20E;Lo;0;L;;;;;N;;;;;
+1B20F;NUSHU CHARACTER-1B20F;Lo;0;L;;;;;N;;;;;
+1B210;NUSHU CHARACTER-1B210;Lo;0;L;;;;;N;;;;;
+1B211;NUSHU CHARACTER-1B211;Lo;0;L;;;;;N;;;;;
+1B212;NUSHU CHARACTER-1B212;Lo;0;L;;;;;N;;;;;
+1B213;NUSHU CHARACTER-1B213;Lo;0;L;;;;;N;;;;;
+1B214;NUSHU CHARACTER-1B214;Lo;0;L;;;;;N;;;;;
+1B215;NUSHU CHARACTER-1B215;Lo;0;L;;;;;N;;;;;
+1B216;NUSHU CHARACTER-1B216;Lo;0;L;;;;;N;;;;;
+1B217;NUSHU CHARACTER-1B217;Lo;0;L;;;;;N;;;;;
+1B218;NUSHU CHARACTER-1B218;Lo;0;L;;;;;N;;;;;
+1B219;NUSHU CHARACTER-1B219;Lo;0;L;;;;;N;;;;;
+1B21A;NUSHU CHARACTER-1B21A;Lo;0;L;;;;;N;;;;;
+1B21B;NUSHU CHARACTER-1B21B;Lo;0;L;;;;;N;;;;;
+1B21C;NUSHU CHARACTER-1B21C;Lo;0;L;;;;;N;;;;;
+1B21D;NUSHU CHARACTER-1B21D;Lo;0;L;;;;;N;;;;;
+1B21E;NUSHU CHARACTER-1B21E;Lo;0;L;;;;;N;;;;;
+1B21F;NUSHU CHARACTER-1B21F;Lo;0;L;;;;;N;;;;;
+1B220;NUSHU CHARACTER-1B220;Lo;0;L;;;;;N;;;;;
+1B221;NUSHU CHARACTER-1B221;Lo;0;L;;;;;N;;;;;
+1B222;NUSHU CHARACTER-1B222;Lo;0;L;;;;;N;;;;;
+1B223;NUSHU CHARACTER-1B223;Lo;0;L;;;;;N;;;;;
+1B224;NUSHU CHARACTER-1B224;Lo;0;L;;;;;N;;;;;
+1B225;NUSHU CHARACTER-1B225;Lo;0;L;;;;;N;;;;;
+1B226;NUSHU CHARACTER-1B226;Lo;0;L;;;;;N;;;;;
+1B227;NUSHU CHARACTER-1B227;Lo;0;L;;;;;N;;;;;
+1B228;NUSHU CHARACTER-1B228;Lo;0;L;;;;;N;;;;;
+1B229;NUSHU CHARACTER-1B229;Lo;0;L;;;;;N;;;;;
+1B22A;NUSHU CHARACTER-1B22A;Lo;0;L;;;;;N;;;;;
+1B22B;NUSHU CHARACTER-1B22B;Lo;0;L;;;;;N;;;;;
+1B22C;NUSHU CHARACTER-1B22C;Lo;0;L;;;;;N;;;;;
+1B22D;NUSHU CHARACTER-1B22D;Lo;0;L;;;;;N;;;;;
+1B22E;NUSHU CHARACTER-1B22E;Lo;0;L;;;;;N;;;;;
+1B22F;NUSHU CHARACTER-1B22F;Lo;0;L;;;;;N;;;;;
+1B230;NUSHU CHARACTER-1B230;Lo;0;L;;;;;N;;;;;
+1B231;NUSHU CHARACTER-1B231;Lo;0;L;;;;;N;;;;;
+1B232;NUSHU CHARACTER-1B232;Lo;0;L;;;;;N;;;;;
+1B233;NUSHU CHARACTER-1B233;Lo;0;L;;;;;N;;;;;
+1B234;NUSHU CHARACTER-1B234;Lo;0;L;;;;;N;;;;;
+1B235;NUSHU CHARACTER-1B235;Lo;0;L;;;;;N;;;;;
+1B236;NUSHU CHARACTER-1B236;Lo;0;L;;;;;N;;;;;
+1B237;NUSHU CHARACTER-1B237;Lo;0;L;;;;;N;;;;;
+1B238;NUSHU CHARACTER-1B238;Lo;0;L;;;;;N;;;;;
+1B239;NUSHU CHARACTER-1B239;Lo;0;L;;;;;N;;;;;
+1B23A;NUSHU CHARACTER-1B23A;Lo;0;L;;;;;N;;;;;
+1B23B;NUSHU CHARACTER-1B23B;Lo;0;L;;;;;N;;;;;
+1B23C;NUSHU CHARACTER-1B23C;Lo;0;L;;;;;N;;;;;
+1B23D;NUSHU CHARACTER-1B23D;Lo;0;L;;;;;N;;;;;
+1B23E;NUSHU CHARACTER-1B23E;Lo;0;L;;;;;N;;;;;
+1B23F;NUSHU CHARACTER-1B23F;Lo;0;L;;;;;N;;;;;
+1B240;NUSHU CHARACTER-1B240;Lo;0;L;;;;;N;;;;;
+1B241;NUSHU CHARACTER-1B241;Lo;0;L;;;;;N;;;;;
+1B242;NUSHU CHARACTER-1B242;Lo;0;L;;;;;N;;;;;
+1B243;NUSHU CHARACTER-1B243;Lo;0;L;;;;;N;;;;;
+1B244;NUSHU CHARACTER-1B244;Lo;0;L;;;;;N;;;;;
+1B245;NUSHU CHARACTER-1B245;Lo;0;L;;;;;N;;;;;
+1B246;NUSHU CHARACTER-1B246;Lo;0;L;;;;;N;;;;;
+1B247;NUSHU CHARACTER-1B247;Lo;0;L;;;;;N;;;;;
+1B248;NUSHU CHARACTER-1B248;Lo;0;L;;;;;N;;;;;
+1B249;NUSHU CHARACTER-1B249;Lo;0;L;;;;;N;;;;;
+1B24A;NUSHU CHARACTER-1B24A;Lo;0;L;;;;;N;;;;;
+1B24B;NUSHU CHARACTER-1B24B;Lo;0;L;;;;;N;;;;;
+1B24C;NUSHU CHARACTER-1B24C;Lo;0;L;;;;;N;;;;;
+1B24D;NUSHU CHARACTER-1B24D;Lo;0;L;;;;;N;;;;;
+1B24E;NUSHU CHARACTER-1B24E;Lo;0;L;;;;;N;;;;;
+1B24F;NUSHU CHARACTER-1B24F;Lo;0;L;;;;;N;;;;;
+1B250;NUSHU CHARACTER-1B250;Lo;0;L;;;;;N;;;;;
+1B251;NUSHU CHARACTER-1B251;Lo;0;L;;;;;N;;;;;
+1B252;NUSHU CHARACTER-1B252;Lo;0;L;;;;;N;;;;;
+1B253;NUSHU CHARACTER-1B253;Lo;0;L;;;;;N;;;;;
+1B254;NUSHU CHARACTER-1B254;Lo;0;L;;;;;N;;;;;
+1B255;NUSHU CHARACTER-1B255;Lo;0;L;;;;;N;;;;;
+1B256;NUSHU CHARACTER-1B256;Lo;0;L;;;;;N;;;;;
+1B257;NUSHU CHARACTER-1B257;Lo;0;L;;;;;N;;;;;
+1B258;NUSHU CHARACTER-1B258;Lo;0;L;;;;;N;;;;;
+1B259;NUSHU CHARACTER-1B259;Lo;0;L;;;;;N;;;;;
+1B25A;NUSHU CHARACTER-1B25A;Lo;0;L;;;;;N;;;;;
+1B25B;NUSHU CHARACTER-1B25B;Lo;0;L;;;;;N;;;;;
+1B25C;NUSHU CHARACTER-1B25C;Lo;0;L;;;;;N;;;;;
+1B25D;NUSHU CHARACTER-1B25D;Lo;0;L;;;;;N;;;;;
+1B25E;NUSHU CHARACTER-1B25E;Lo;0;L;;;;;N;;;;;
+1B25F;NUSHU CHARACTER-1B25F;Lo;0;L;;;;;N;;;;;
+1B260;NUSHU CHARACTER-1B260;Lo;0;L;;;;;N;;;;;
+1B261;NUSHU CHARACTER-1B261;Lo;0;L;;;;;N;;;;;
+1B262;NUSHU CHARACTER-1B262;Lo;0;L;;;;;N;;;;;
+1B263;NUSHU CHARACTER-1B263;Lo;0;L;;;;;N;;;;;
+1B264;NUSHU CHARACTER-1B264;Lo;0;L;;;;;N;;;;;
+1B265;NUSHU CHARACTER-1B265;Lo;0;L;;;;;N;;;;;
+1B266;NUSHU CHARACTER-1B266;Lo;0;L;;;;;N;;;;;
+1B267;NUSHU CHARACTER-1B267;Lo;0;L;;;;;N;;;;;
+1B268;NUSHU CHARACTER-1B268;Lo;0;L;;;;;N;;;;;
+1B269;NUSHU CHARACTER-1B269;Lo;0;L;;;;;N;;;;;
+1B26A;NUSHU CHARACTER-1B26A;Lo;0;L;;;;;N;;;;;
+1B26B;NUSHU CHARACTER-1B26B;Lo;0;L;;;;;N;;;;;
+1B26C;NUSHU CHARACTER-1B26C;Lo;0;L;;;;;N;;;;;
+1B26D;NUSHU CHARACTER-1B26D;Lo;0;L;;;;;N;;;;;
+1B26E;NUSHU CHARACTER-1B26E;Lo;0;L;;;;;N;;;;;
+1B26F;NUSHU CHARACTER-1B26F;Lo;0;L;;;;;N;;;;;
+1B270;NUSHU CHARACTER-1B270;Lo;0;L;;;;;N;;;;;
+1B271;NUSHU CHARACTER-1B271;Lo;0;L;;;;;N;;;;;
+1B272;NUSHU CHARACTER-1B272;Lo;0;L;;;;;N;;;;;
+1B273;NUSHU CHARACTER-1B273;Lo;0;L;;;;;N;;;;;
+1B274;NUSHU CHARACTER-1B274;Lo;0;L;;;;;N;;;;;
+1B275;NUSHU CHARACTER-1B275;Lo;0;L;;;;;N;;;;;
+1B276;NUSHU CHARACTER-1B276;Lo;0;L;;;;;N;;;;;
+1B277;NUSHU CHARACTER-1B277;Lo;0;L;;;;;N;;;;;
+1B278;NUSHU CHARACTER-1B278;Lo;0;L;;;;;N;;;;;
+1B279;NUSHU CHARACTER-1B279;Lo;0;L;;;;;N;;;;;
+1B27A;NUSHU CHARACTER-1B27A;Lo;0;L;;;;;N;;;;;
+1B27B;NUSHU CHARACTER-1B27B;Lo;0;L;;;;;N;;;;;
+1B27C;NUSHU CHARACTER-1B27C;Lo;0;L;;;;;N;;;;;
+1B27D;NUSHU CHARACTER-1B27D;Lo;0;L;;;;;N;;;;;
+1B27E;NUSHU CHARACTER-1B27E;Lo;0;L;;;;;N;;;;;
+1B27F;NUSHU CHARACTER-1B27F;Lo;0;L;;;;;N;;;;;
+1B280;NUSHU CHARACTER-1B280;Lo;0;L;;;;;N;;;;;
+1B281;NUSHU CHARACTER-1B281;Lo;0;L;;;;;N;;;;;
+1B282;NUSHU CHARACTER-1B282;Lo;0;L;;;;;N;;;;;
+1B283;NUSHU CHARACTER-1B283;Lo;0;L;;;;;N;;;;;
+1B284;NUSHU CHARACTER-1B284;Lo;0;L;;;;;N;;;;;
+1B285;NUSHU CHARACTER-1B285;Lo;0;L;;;;;N;;;;;
+1B286;NUSHU CHARACTER-1B286;Lo;0;L;;;;;N;;;;;
+1B287;NUSHU CHARACTER-1B287;Lo;0;L;;;;;N;;;;;
+1B288;NUSHU CHARACTER-1B288;Lo;0;L;;;;;N;;;;;
+1B289;NUSHU CHARACTER-1B289;Lo;0;L;;;;;N;;;;;
+1B28A;NUSHU CHARACTER-1B28A;Lo;0;L;;;;;N;;;;;
+1B28B;NUSHU CHARACTER-1B28B;Lo;0;L;;;;;N;;;;;
+1B28C;NUSHU CHARACTER-1B28C;Lo;0;L;;;;;N;;;;;
+1B28D;NUSHU CHARACTER-1B28D;Lo;0;L;;;;;N;;;;;
+1B28E;NUSHU CHARACTER-1B28E;Lo;0;L;;;;;N;;;;;
+1B28F;NUSHU CHARACTER-1B28F;Lo;0;L;;;;;N;;;;;
+1B290;NUSHU CHARACTER-1B290;Lo;0;L;;;;;N;;;;;
+1B291;NUSHU CHARACTER-1B291;Lo;0;L;;;;;N;;;;;
+1B292;NUSHU CHARACTER-1B292;Lo;0;L;;;;;N;;;;;
+1B293;NUSHU CHARACTER-1B293;Lo;0;L;;;;;N;;;;;
+1B294;NUSHU CHARACTER-1B294;Lo;0;L;;;;;N;;;;;
+1B295;NUSHU CHARACTER-1B295;Lo;0;L;;;;;N;;;;;
+1B296;NUSHU CHARACTER-1B296;Lo;0;L;;;;;N;;;;;
+1B297;NUSHU CHARACTER-1B297;Lo;0;L;;;;;N;;;;;
+1B298;NUSHU CHARACTER-1B298;Lo;0;L;;;;;N;;;;;
+1B299;NUSHU CHARACTER-1B299;Lo;0;L;;;;;N;;;;;
+1B29A;NUSHU CHARACTER-1B29A;Lo;0;L;;;;;N;;;;;
+1B29B;NUSHU CHARACTER-1B29B;Lo;0;L;;;;;N;;;;;
+1B29C;NUSHU CHARACTER-1B29C;Lo;0;L;;;;;N;;;;;
+1B29D;NUSHU CHARACTER-1B29D;Lo;0;L;;;;;N;;;;;
+1B29E;NUSHU CHARACTER-1B29E;Lo;0;L;;;;;N;;;;;
+1B29F;NUSHU CHARACTER-1B29F;Lo;0;L;;;;;N;;;;;
+1B2A0;NUSHU CHARACTER-1B2A0;Lo;0;L;;;;;N;;;;;
+1B2A1;NUSHU CHARACTER-1B2A1;Lo;0;L;;;;;N;;;;;
+1B2A2;NUSHU CHARACTER-1B2A2;Lo;0;L;;;;;N;;;;;
+1B2A3;NUSHU CHARACTER-1B2A3;Lo;0;L;;;;;N;;;;;
+1B2A4;NUSHU CHARACTER-1B2A4;Lo;0;L;;;;;N;;;;;
+1B2A5;NUSHU CHARACTER-1B2A5;Lo;0;L;;;;;N;;;;;
+1B2A6;NUSHU CHARACTER-1B2A6;Lo;0;L;;;;;N;;;;;
+1B2A7;NUSHU CHARACTER-1B2A7;Lo;0;L;;;;;N;;;;;
+1B2A8;NUSHU CHARACTER-1B2A8;Lo;0;L;;;;;N;;;;;
+1B2A9;NUSHU CHARACTER-1B2A9;Lo;0;L;;;;;N;;;;;
+1B2AA;NUSHU CHARACTER-1B2AA;Lo;0;L;;;;;N;;;;;
+1B2AB;NUSHU CHARACTER-1B2AB;Lo;0;L;;;;;N;;;;;
+1B2AC;NUSHU CHARACTER-1B2AC;Lo;0;L;;;;;N;;;;;
+1B2AD;NUSHU CHARACTER-1B2AD;Lo;0;L;;;;;N;;;;;
+1B2AE;NUSHU CHARACTER-1B2AE;Lo;0;L;;;;;N;;;;;
+1B2AF;NUSHU CHARACTER-1B2AF;Lo;0;L;;;;;N;;;;;
+1B2B0;NUSHU CHARACTER-1B2B0;Lo;0;L;;;;;N;;;;;
+1B2B1;NUSHU CHARACTER-1B2B1;Lo;0;L;;;;;N;;;;;
+1B2B2;NUSHU CHARACTER-1B2B2;Lo;0;L;;;;;N;;;;;
+1B2B3;NUSHU CHARACTER-1B2B3;Lo;0;L;;;;;N;;;;;
+1B2B4;NUSHU CHARACTER-1B2B4;Lo;0;L;;;;;N;;;;;
+1B2B5;NUSHU CHARACTER-1B2B5;Lo;0;L;;;;;N;;;;;
+1B2B6;NUSHU CHARACTER-1B2B6;Lo;0;L;;;;;N;;;;;
+1B2B7;NUSHU CHARACTER-1B2B7;Lo;0;L;;;;;N;;;;;
+1B2B8;NUSHU CHARACTER-1B2B8;Lo;0;L;;;;;N;;;;;
+1B2B9;NUSHU CHARACTER-1B2B9;Lo;0;L;;;;;N;;;;;
+1B2BA;NUSHU CHARACTER-1B2BA;Lo;0;L;;;;;N;;;;;
+1B2BB;NUSHU CHARACTER-1B2BB;Lo;0;L;;;;;N;;;;;
+1B2BC;NUSHU CHARACTER-1B2BC;Lo;0;L;;;;;N;;;;;
+1B2BD;NUSHU CHARACTER-1B2BD;Lo;0;L;;;;;N;;;;;
+1B2BE;NUSHU CHARACTER-1B2BE;Lo;0;L;;;;;N;;;;;
+1B2BF;NUSHU CHARACTER-1B2BF;Lo;0;L;;;;;N;;;;;
+1B2C0;NUSHU CHARACTER-1B2C0;Lo;0;L;;;;;N;;;;;
+1B2C1;NUSHU CHARACTER-1B2C1;Lo;0;L;;;;;N;;;;;
+1B2C2;NUSHU CHARACTER-1B2C2;Lo;0;L;;;;;N;;;;;
+1B2C3;NUSHU CHARACTER-1B2C3;Lo;0;L;;;;;N;;;;;
+1B2C4;NUSHU CHARACTER-1B2C4;Lo;0;L;;;;;N;;;;;
+1B2C5;NUSHU CHARACTER-1B2C5;Lo;0;L;;;;;N;;;;;
+1B2C6;NUSHU CHARACTER-1B2C6;Lo;0;L;;;;;N;;;;;
+1B2C7;NUSHU CHARACTER-1B2C7;Lo;0;L;;;;;N;;;;;
+1B2C8;NUSHU CHARACTER-1B2C8;Lo;0;L;;;;;N;;;;;
+1B2C9;NUSHU CHARACTER-1B2C9;Lo;0;L;;;;;N;;;;;
+1B2CA;NUSHU CHARACTER-1B2CA;Lo;0;L;;;;;N;;;;;
+1B2CB;NUSHU CHARACTER-1B2CB;Lo;0;L;;;;;N;;;;;
+1B2CC;NUSHU CHARACTER-1B2CC;Lo;0;L;;;;;N;;;;;
+1B2CD;NUSHU CHARACTER-1B2CD;Lo;0;L;;;;;N;;;;;
+1B2CE;NUSHU CHARACTER-1B2CE;Lo;0;L;;;;;N;;;;;
+1B2CF;NUSHU CHARACTER-1B2CF;Lo;0;L;;;;;N;;;;;
+1B2D0;NUSHU CHARACTER-1B2D0;Lo;0;L;;;;;N;;;;;
+1B2D1;NUSHU CHARACTER-1B2D1;Lo;0;L;;;;;N;;;;;
+1B2D2;NUSHU CHARACTER-1B2D2;Lo;0;L;;;;;N;;;;;
+1B2D3;NUSHU CHARACTER-1B2D3;Lo;0;L;;;;;N;;;;;
+1B2D4;NUSHU CHARACTER-1B2D4;Lo;0;L;;;;;N;;;;;
+1B2D5;NUSHU CHARACTER-1B2D5;Lo;0;L;;;;;N;;;;;
+1B2D6;NUSHU CHARACTER-1B2D6;Lo;0;L;;;;;N;;;;;
+1B2D7;NUSHU CHARACTER-1B2D7;Lo;0;L;;;;;N;;;;;
+1B2D8;NUSHU CHARACTER-1B2D8;Lo;0;L;;;;;N;;;;;
+1B2D9;NUSHU CHARACTER-1B2D9;Lo;0;L;;;;;N;;;;;
+1B2DA;NUSHU CHARACTER-1B2DA;Lo;0;L;;;;;N;;;;;
+1B2DB;NUSHU CHARACTER-1B2DB;Lo;0;L;;;;;N;;;;;
+1B2DC;NUSHU CHARACTER-1B2DC;Lo;0;L;;;;;N;;;;;
+1B2DD;NUSHU CHARACTER-1B2DD;Lo;0;L;;;;;N;;;;;
+1B2DE;NUSHU CHARACTER-1B2DE;Lo;0;L;;;;;N;;;;;
+1B2DF;NUSHU CHARACTER-1B2DF;Lo;0;L;;;;;N;;;;;
+1B2E0;NUSHU CHARACTER-1B2E0;Lo;0;L;;;;;N;;;;;
+1B2E1;NUSHU CHARACTER-1B2E1;Lo;0;L;;;;;N;;;;;
+1B2E2;NUSHU CHARACTER-1B2E2;Lo;0;L;;;;;N;;;;;
+1B2E3;NUSHU CHARACTER-1B2E3;Lo;0;L;;;;;N;;;;;
+1B2E4;NUSHU CHARACTER-1B2E4;Lo;0;L;;;;;N;;;;;
+1B2E5;NUSHU CHARACTER-1B2E5;Lo;0;L;;;;;N;;;;;
+1B2E6;NUSHU CHARACTER-1B2E6;Lo;0;L;;;;;N;;;;;
+1B2E7;NUSHU CHARACTER-1B2E7;Lo;0;L;;;;;N;;;;;
+1B2E8;NUSHU CHARACTER-1B2E8;Lo;0;L;;;;;N;;;;;
+1B2E9;NUSHU CHARACTER-1B2E9;Lo;0;L;;;;;N;;;;;
+1B2EA;NUSHU CHARACTER-1B2EA;Lo;0;L;;;;;N;;;;;
+1B2EB;NUSHU CHARACTER-1B2EB;Lo;0;L;;;;;N;;;;;
+1B2EC;NUSHU CHARACTER-1B2EC;Lo;0;L;;;;;N;;;;;
+1B2ED;NUSHU CHARACTER-1B2ED;Lo;0;L;;;;;N;;;;;
+1B2EE;NUSHU CHARACTER-1B2EE;Lo;0;L;;;;;N;;;;;
+1B2EF;NUSHU CHARACTER-1B2EF;Lo;0;L;;;;;N;;;;;
+1B2F0;NUSHU CHARACTER-1B2F0;Lo;0;L;;;;;N;;;;;
+1B2F1;NUSHU CHARACTER-1B2F1;Lo;0;L;;;;;N;;;;;
+1B2F2;NUSHU CHARACTER-1B2F2;Lo;0;L;;;;;N;;;;;
+1B2F3;NUSHU CHARACTER-1B2F3;Lo;0;L;;;;;N;;;;;
+1B2F4;NUSHU CHARACTER-1B2F4;Lo;0;L;;;;;N;;;;;
+1B2F5;NUSHU CHARACTER-1B2F5;Lo;0;L;;;;;N;;;;;
+1B2F6;NUSHU CHARACTER-1B2F6;Lo;0;L;;;;;N;;;;;
+1B2F7;NUSHU CHARACTER-1B2F7;Lo;0;L;;;;;N;;;;;
+1B2F8;NUSHU CHARACTER-1B2F8;Lo;0;L;;;;;N;;;;;
+1B2F9;NUSHU CHARACTER-1B2F9;Lo;0;L;;;;;N;;;;;
+1B2FA;NUSHU CHARACTER-1B2FA;Lo;0;L;;;;;N;;;;;
+1B2FB;NUSHU CHARACTER-1B2FB;Lo;0;L;;;;;N;;;;;
+1BC00;DUPLOYAN LETTER H;Lo;0;L;;;;;N;;;;;
+1BC01;DUPLOYAN LETTER X;Lo;0;L;;;;;N;;;;;
+1BC02;DUPLOYAN LETTER P;Lo;0;L;;;;;N;;;;;
+1BC03;DUPLOYAN LETTER T;Lo;0;L;;;;;N;;;;;
+1BC04;DUPLOYAN LETTER F;Lo;0;L;;;;;N;;;;;
+1BC05;DUPLOYAN LETTER K;Lo;0;L;;;;;N;;;;;
+1BC06;DUPLOYAN LETTER L;Lo;0;L;;;;;N;;;;;
+1BC07;DUPLOYAN LETTER B;Lo;0;L;;;;;N;;;;;
+1BC08;DUPLOYAN LETTER D;Lo;0;L;;;;;N;;;;;
+1BC09;DUPLOYAN LETTER V;Lo;0;L;;;;;N;;;;;
+1BC0A;DUPLOYAN LETTER G;Lo;0;L;;;;;N;;;;;
+1BC0B;DUPLOYAN LETTER R;Lo;0;L;;;;;N;;;;;
+1BC0C;DUPLOYAN LETTER P N;Lo;0;L;;;;;N;;;;;
+1BC0D;DUPLOYAN LETTER D S;Lo;0;L;;;;;N;;;;;
+1BC0E;DUPLOYAN LETTER F N;Lo;0;L;;;;;N;;;;;
+1BC0F;DUPLOYAN LETTER K M;Lo;0;L;;;;;N;;;;;
+1BC10;DUPLOYAN LETTER R S;Lo;0;L;;;;;N;;;;;
+1BC11;DUPLOYAN LETTER TH;Lo;0;L;;;;;N;;;;;
+1BC12;DUPLOYAN LETTER SLOAN DH;Lo;0;L;;;;;N;;;;;
+1BC13;DUPLOYAN LETTER DH;Lo;0;L;;;;;N;;;;;
+1BC14;DUPLOYAN LETTER KK;Lo;0;L;;;;;N;;;;;
+1BC15;DUPLOYAN LETTER SLOAN J;Lo;0;L;;;;;N;;;;;
+1BC16;DUPLOYAN LETTER HL;Lo;0;L;;;;;N;;;;;
+1BC17;DUPLOYAN LETTER LH;Lo;0;L;;;;;N;;;;;
+1BC18;DUPLOYAN LETTER RH;Lo;0;L;;;;;N;;;;;
+1BC19;DUPLOYAN LETTER M;Lo;0;L;;;;;N;;;;;
+1BC1A;DUPLOYAN LETTER N;Lo;0;L;;;;;N;;;;;
+1BC1B;DUPLOYAN LETTER J;Lo;0;L;;;;;N;;;;;
+1BC1C;DUPLOYAN LETTER S;Lo;0;L;;;;;N;;;;;
+1BC1D;DUPLOYAN LETTER M N;Lo;0;L;;;;;N;;;;;
+1BC1E;DUPLOYAN LETTER N M;Lo;0;L;;;;;N;;;;;
+1BC1F;DUPLOYAN LETTER J M;Lo;0;L;;;;;N;;;;;
+1BC20;DUPLOYAN LETTER S J;Lo;0;L;;;;;N;;;;;
+1BC21;DUPLOYAN LETTER M WITH DOT;Lo;0;L;;;;;N;;;;;
+1BC22;DUPLOYAN LETTER N WITH DOT;Lo;0;L;;;;;N;;;;;
+1BC23;DUPLOYAN LETTER J WITH DOT;Lo;0;L;;;;;N;;;;;
+1BC24;DUPLOYAN LETTER J WITH DOTS INSIDE AND ABOVE;Lo;0;L;;;;;N;;;;;
+1BC25;DUPLOYAN LETTER S WITH DOT;Lo;0;L;;;;;N;;;;;
+1BC26;DUPLOYAN LETTER S WITH DOT BELOW;Lo;0;L;;;;;N;;;;;
+1BC27;DUPLOYAN LETTER M S;Lo;0;L;;;;;N;;;;;
+1BC28;DUPLOYAN LETTER N S;Lo;0;L;;;;;N;;;;;
+1BC29;DUPLOYAN LETTER J S;Lo;0;L;;;;;N;;;;;
+1BC2A;DUPLOYAN LETTER S S;Lo;0;L;;;;;N;;;;;
+1BC2B;DUPLOYAN LETTER M N S;Lo;0;L;;;;;N;;;;;
+1BC2C;DUPLOYAN LETTER N M S;Lo;0;L;;;;;N;;;;;
+1BC2D;DUPLOYAN LETTER J M S;Lo;0;L;;;;;N;;;;;
+1BC2E;DUPLOYAN LETTER S J S;Lo;0;L;;;;;N;;;;;
+1BC2F;DUPLOYAN LETTER J S WITH DOT;Lo;0;L;;;;;N;;;;;
+1BC30;DUPLOYAN LETTER J N;Lo;0;L;;;;;N;;;;;
+1BC31;DUPLOYAN LETTER J N S;Lo;0;L;;;;;N;;;;;
+1BC32;DUPLOYAN LETTER S T;Lo;0;L;;;;;N;;;;;
+1BC33;DUPLOYAN LETTER S T R;Lo;0;L;;;;;N;;;;;
+1BC34;DUPLOYAN LETTER S P;Lo;0;L;;;;;N;;;;;
+1BC35;DUPLOYAN LETTER S P R;Lo;0;L;;;;;N;;;;;
+1BC36;DUPLOYAN LETTER T S;Lo;0;L;;;;;N;;;;;
+1BC37;DUPLOYAN LETTER T R S;Lo;0;L;;;;;N;;;;;
+1BC38;DUPLOYAN LETTER W;Lo;0;L;;;;;N;;;;;
+1BC39;DUPLOYAN LETTER WH;Lo;0;L;;;;;N;;;;;
+1BC3A;DUPLOYAN LETTER W R;Lo;0;L;;;;;N;;;;;
+1BC3B;DUPLOYAN LETTER S N;Lo;0;L;;;;;N;;;;;
+1BC3C;DUPLOYAN LETTER S M;Lo;0;L;;;;;N;;;;;
+1BC3D;DUPLOYAN LETTER K R S;Lo;0;L;;;;;N;;;;;
+1BC3E;DUPLOYAN LETTER G R S;Lo;0;L;;;;;N;;;;;
+1BC3F;DUPLOYAN LETTER S K;Lo;0;L;;;;;N;;;;;
+1BC40;DUPLOYAN LETTER S K R;Lo;0;L;;;;;N;;;;;
+1BC41;DUPLOYAN LETTER A;Lo;0;L;;;;;N;;;;;
+1BC42;DUPLOYAN LETTER SLOAN OW;Lo;0;L;;;;;N;;;;;
+1BC43;DUPLOYAN LETTER OA;Lo;0;L;;;;;N;;;;;
+1BC44;DUPLOYAN LETTER O;Lo;0;L;;;;;N;;;;;
+1BC45;DUPLOYAN LETTER AOU;Lo;0;L;;;;;N;;;;;
+1BC46;DUPLOYAN LETTER I;Lo;0;L;;;;;N;;;;;
+1BC47;DUPLOYAN LETTER E;Lo;0;L;;;;;N;;;;;
+1BC48;DUPLOYAN LETTER IE;Lo;0;L;;;;;N;;;;;
+1BC49;DUPLOYAN LETTER SHORT I;Lo;0;L;;;;;N;;;;;
+1BC4A;DUPLOYAN LETTER UI;Lo;0;L;;;;;N;;;;;
+1BC4B;DUPLOYAN LETTER EE;Lo;0;L;;;;;N;;;;;
+1BC4C;DUPLOYAN LETTER SLOAN EH;Lo;0;L;;;;;N;;;;;
+1BC4D;DUPLOYAN LETTER ROMANIAN I;Lo;0;L;;;;;N;;;;;
+1BC4E;DUPLOYAN LETTER SLOAN EE;Lo;0;L;;;;;N;;;;;
+1BC4F;DUPLOYAN LETTER LONG I;Lo;0;L;;;;;N;;;;;
+1BC50;DUPLOYAN LETTER YE;Lo;0;L;;;;;N;;;;;
+1BC51;DUPLOYAN LETTER U;Lo;0;L;;;;;N;;;;;
+1BC52;DUPLOYAN LETTER EU;Lo;0;L;;;;;N;;;;;
+1BC53;DUPLOYAN LETTER XW;Lo;0;L;;;;;N;;;;;
+1BC54;DUPLOYAN LETTER U N;Lo;0;L;;;;;N;;;;;
+1BC55;DUPLOYAN LETTER LONG U;Lo;0;L;;;;;N;;;;;
+1BC56;DUPLOYAN LETTER ROMANIAN U;Lo;0;L;;;;;N;;;;;
+1BC57;DUPLOYAN LETTER UH;Lo;0;L;;;;;N;;;;;
+1BC58;DUPLOYAN LETTER SLOAN U;Lo;0;L;;;;;N;;;;;
+1BC59;DUPLOYAN LETTER OOH;Lo;0;L;;;;;N;;;;;
+1BC5A;DUPLOYAN LETTER OW;Lo;0;L;;;;;N;;;;;
+1BC5B;DUPLOYAN LETTER OU;Lo;0;L;;;;;N;;;;;
+1BC5C;DUPLOYAN LETTER WA;Lo;0;L;;;;;N;;;;;
+1BC5D;DUPLOYAN LETTER WO;Lo;0;L;;;;;N;;;;;
+1BC5E;DUPLOYAN LETTER WI;Lo;0;L;;;;;N;;;;;
+1BC5F;DUPLOYAN LETTER WEI;Lo;0;L;;;;;N;;;;;
+1BC60;DUPLOYAN LETTER WOW;Lo;0;L;;;;;N;;;;;
+1BC61;DUPLOYAN LETTER NASAL U;Lo;0;L;;;;;N;;;;;
+1BC62;DUPLOYAN LETTER NASAL O;Lo;0;L;;;;;N;;;;;
+1BC63;DUPLOYAN LETTER NASAL I;Lo;0;L;;;;;N;;;;;
+1BC64;DUPLOYAN LETTER NASAL A;Lo;0;L;;;;;N;;;;;
+1BC65;DUPLOYAN LETTER PERNIN AN;Lo;0;L;;;;;N;;;;;
+1BC66;DUPLOYAN LETTER PERNIN AM;Lo;0;L;;;;;N;;;;;
+1BC67;DUPLOYAN LETTER SLOAN EN;Lo;0;L;;;;;N;;;;;
+1BC68;DUPLOYAN LETTER SLOAN AN;Lo;0;L;;;;;N;;;;;
+1BC69;DUPLOYAN LETTER SLOAN ON;Lo;0;L;;;;;N;;;;;
+1BC6A;DUPLOYAN LETTER VOCALIC M;Lo;0;L;;;;;N;;;;;
+1BC70;DUPLOYAN AFFIX LEFT HORIZONTAL SECANT;Lo;0;L;;;;;N;;;;;
+1BC71;DUPLOYAN AFFIX MID HORIZONTAL SECANT;Lo;0;L;;;;;N;;;;;
+1BC72;DUPLOYAN AFFIX RIGHT HORIZONTAL SECANT;Lo;0;L;;;;;N;;;;;
+1BC73;DUPLOYAN AFFIX LOW VERTICAL SECANT;Lo;0;L;;;;;N;;;;;
+1BC74;DUPLOYAN AFFIX MID VERTICAL SECANT;Lo;0;L;;;;;N;;;;;
+1BC75;DUPLOYAN AFFIX HIGH VERTICAL SECANT;Lo;0;L;;;;;N;;;;;
+1BC76;DUPLOYAN AFFIX ATTACHED SECANT;Lo;0;L;;;;;N;;;;;
+1BC77;DUPLOYAN AFFIX ATTACHED LEFT-TO-RIGHT SECANT;Lo;0;L;;;;;N;;;;;
+1BC78;DUPLOYAN AFFIX ATTACHED TANGENT;Lo;0;L;;;;;N;;;;;
+1BC79;DUPLOYAN AFFIX ATTACHED TAIL;Lo;0;L;;;;;N;;;;;
+1BC7A;DUPLOYAN AFFIX ATTACHED E HOOK;Lo;0;L;;;;;N;;;;;
+1BC7B;DUPLOYAN AFFIX ATTACHED I HOOK;Lo;0;L;;;;;N;;;;;
+1BC7C;DUPLOYAN AFFIX ATTACHED TANGENT HOOK;Lo;0;L;;;;;N;;;;;
+1BC80;DUPLOYAN AFFIX HIGH ACUTE;Lo;0;L;;;;;N;;;;;
+1BC81;DUPLOYAN AFFIX HIGH TIGHT ACUTE;Lo;0;L;;;;;N;;;;;
+1BC82;DUPLOYAN AFFIX HIGH GRAVE;Lo;0;L;;;;;N;;;;;
+1BC83;DUPLOYAN AFFIX HIGH LONG GRAVE;Lo;0;L;;;;;N;;;;;
+1BC84;DUPLOYAN AFFIX HIGH DOT;Lo;0;L;;;;;N;;;;;
+1BC85;DUPLOYAN AFFIX HIGH CIRCLE;Lo;0;L;;;;;N;;;;;
+1BC86;DUPLOYAN AFFIX HIGH LINE;Lo;0;L;;;;;N;;;;;
+1BC87;DUPLOYAN AFFIX HIGH WAVE;Lo;0;L;;;;;N;;;;;
+1BC88;DUPLOYAN AFFIX HIGH VERTICAL;Lo;0;L;;;;;N;;;;;
+1BC90;DUPLOYAN AFFIX LOW ACUTE;Lo;0;L;;;;;N;;;;;
+1BC91;DUPLOYAN AFFIX LOW TIGHT ACUTE;Lo;0;L;;;;;N;;;;;
+1BC92;DUPLOYAN AFFIX LOW GRAVE;Lo;0;L;;;;;N;;;;;
+1BC93;DUPLOYAN AFFIX LOW LONG GRAVE;Lo;0;L;;;;;N;;;;;
+1BC94;DUPLOYAN AFFIX LOW DOT;Lo;0;L;;;;;N;;;;;
+1BC95;DUPLOYAN AFFIX LOW CIRCLE;Lo;0;L;;;;;N;;;;;
+1BC96;DUPLOYAN AFFIX LOW LINE;Lo;0;L;;;;;N;;;;;
+1BC97;DUPLOYAN AFFIX LOW WAVE;Lo;0;L;;;;;N;;;;;
+1BC98;DUPLOYAN AFFIX LOW VERTICAL;Lo;0;L;;;;;N;;;;;
+1BC99;DUPLOYAN AFFIX LOW ARROW;Lo;0;L;;;;;N;;;;;
+1BC9C;DUPLOYAN SIGN O WITH CROSS;So;0;L;;;;;N;;;;;
+1BC9D;DUPLOYAN THICK LETTER SELECTOR;Mn;0;NSM;;;;;N;;;;;
+1BC9E;DUPLOYAN DOUBLE MARK;Mn;1;NSM;;;;;N;;;;;
+1BC9F;DUPLOYAN PUNCTUATION CHINOOK FULL STOP;Po;0;L;;;;;N;;;;;
+1BCA0;SHORTHAND FORMAT LETTER OVERLAP;Cf;0;BN;;;;;N;;;;;
+1BCA1;SHORTHAND FORMAT CONTINUING OVERLAP;Cf;0;BN;;;;;N;;;;;
+1BCA2;SHORTHAND FORMAT DOWN STEP;Cf;0;BN;;;;;N;;;;;
+1BCA3;SHORTHAND FORMAT UP STEP;Cf;0;BN;;;;;N;;;;;
1D000;BYZANTINE MUSICAL SYMBOL PSILI;So;0;L;;;;;N;;;;;
1D001;BYZANTINE MUSICAL SYMBOL DASEIA;So;0;L;;;;;N;;;;;
1D002;BYZANTINE MUSICAL SYMBOL PERISPOMENI;So;0;L;;;;;N;;;;;
@@ -19518,6 +26407,17 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1D1DB;MUSICAL SYMBOL SCANDICUS FLEXUS;So;0;L;;;;;N;;;;;
1D1DC;MUSICAL SYMBOL TORCULUS RESUPINUS;So;0;L;;;;;N;;;;;
1D1DD;MUSICAL SYMBOL PES SUBPUNCTIS;So;0;L;;;;;N;;;;;
+1D1DE;MUSICAL SYMBOL KIEVAN C CLEF;So;0;L;;;;;N;;;;;
+1D1DF;MUSICAL SYMBOL KIEVAN END OF PIECE;So;0;L;;;;;N;;;;;
+1D1E0;MUSICAL SYMBOL KIEVAN FINAL NOTE;So;0;L;;;;;N;;;;;
+1D1E1;MUSICAL SYMBOL KIEVAN RECITATIVE MARK;So;0;L;;;;;N;;;;;
+1D1E2;MUSICAL SYMBOL KIEVAN WHOLE NOTE;So;0;L;;;;;N;;;;;
+1D1E3;MUSICAL SYMBOL KIEVAN HALF NOTE;So;0;L;;;;;N;;;;;
+1D1E4;MUSICAL SYMBOL KIEVAN QUARTER NOTE STEM DOWN;So;0;L;;;;;N;;;;;
+1D1E5;MUSICAL SYMBOL KIEVAN QUARTER NOTE STEM UP;So;0;L;;;;;N;;;;;
+1D1E6;MUSICAL SYMBOL KIEVAN EIGHTH NOTE STEM DOWN;So;0;L;;;;;N;;;;;
+1D1E7;MUSICAL SYMBOL KIEVAN EIGHTH NOTE STEM UP;So;0;L;;;;;N;;;;;
+1D1E8;MUSICAL SYMBOL KIEVAN FLAT SIGN;So;0;L;;;;;N;;;;;
1D200;GREEK VOCAL NOTATION SYMBOL-1;So;0;ON;;;;;N;;;;;
1D201;GREEK VOCAL NOTATION SYMBOL-2;So;0;ON;;;;;N;;;;;
1D202;GREEK VOCAL NOTATION SYMBOL-3;So;0;ON;;;;;N;;;;;
@@ -20689,6 +27589,1159 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1D7FD;MATHEMATICAL MONOSPACE DIGIT SEVEN;Nd;0;EN;<font> 0037;7;7;7;N;;;;;
1D7FE;MATHEMATICAL MONOSPACE DIGIT EIGHT;Nd;0;EN;<font> 0038;8;8;8;N;;;;;
1D7FF;MATHEMATICAL MONOSPACE DIGIT NINE;Nd;0;EN;<font> 0039;9;9;9;N;;;;;
+1D800;SIGNWRITING HAND-FIST INDEX;So;0;L;;;;;N;;;;;
+1D801;SIGNWRITING HAND-CIRCLE INDEX;So;0;L;;;;;N;;;;;
+1D802;SIGNWRITING HAND-CUP INDEX;So;0;L;;;;;N;;;;;
+1D803;SIGNWRITING HAND-OVAL INDEX;So;0;L;;;;;N;;;;;
+1D804;SIGNWRITING HAND-HINGE INDEX;So;0;L;;;;;N;;;;;
+1D805;SIGNWRITING HAND-ANGLE INDEX;So;0;L;;;;;N;;;;;
+1D806;SIGNWRITING HAND-FIST INDEX BENT;So;0;L;;;;;N;;;;;
+1D807;SIGNWRITING HAND-CIRCLE INDEX BENT;So;0;L;;;;;N;;;;;
+1D808;SIGNWRITING HAND-FIST THUMB UNDER INDEX BENT;So;0;L;;;;;N;;;;;
+1D809;SIGNWRITING HAND-FIST INDEX RAISED KNUCKLE;So;0;L;;;;;N;;;;;
+1D80A;SIGNWRITING HAND-FIST INDEX CUPPED;So;0;L;;;;;N;;;;;
+1D80B;SIGNWRITING HAND-FIST INDEX HINGED;So;0;L;;;;;N;;;;;
+1D80C;SIGNWRITING HAND-FIST INDEX HINGED LOW;So;0;L;;;;;N;;;;;
+1D80D;SIGNWRITING HAND-CIRCLE INDEX HINGE;So;0;L;;;;;N;;;;;
+1D80E;SIGNWRITING HAND-FIST INDEX MIDDLE;So;0;L;;;;;N;;;;;
+1D80F;SIGNWRITING HAND-CIRCLE INDEX MIDDLE;So;0;L;;;;;N;;;;;
+1D810;SIGNWRITING HAND-FIST INDEX MIDDLE BENT;So;0;L;;;;;N;;;;;
+1D811;SIGNWRITING HAND-FIST INDEX MIDDLE RAISED KNUCKLES;So;0;L;;;;;N;;;;;
+1D812;SIGNWRITING HAND-FIST INDEX MIDDLE HINGED;So;0;L;;;;;N;;;;;
+1D813;SIGNWRITING HAND-FIST INDEX UP MIDDLE HINGED;So;0;L;;;;;N;;;;;
+1D814;SIGNWRITING HAND-FIST INDEX HINGED MIDDLE UP;So;0;L;;;;;N;;;;;
+1D815;SIGNWRITING HAND-FIST INDEX MIDDLE CONJOINED;So;0;L;;;;;N;;;;;
+1D816;SIGNWRITING HAND-FIST INDEX MIDDLE CONJOINED INDEX BENT;So;0;L;;;;;N;;;;;
+1D817;SIGNWRITING HAND-FIST INDEX MIDDLE CONJOINED MIDDLE BENT;So;0;L;;;;;N;;;;;
+1D818;SIGNWRITING HAND-FIST INDEX MIDDLE CONJOINED CUPPED;So;0;L;;;;;N;;;;;
+1D819;SIGNWRITING HAND-FIST INDEX MIDDLE CONJOINED HINGED;So;0;L;;;;;N;;;;;
+1D81A;SIGNWRITING HAND-FIST INDEX MIDDLE CROSSED;So;0;L;;;;;N;;;;;
+1D81B;SIGNWRITING HAND-CIRCLE INDEX MIDDLE CROSSED;So;0;L;;;;;N;;;;;
+1D81C;SIGNWRITING HAND-FIST MIDDLE BENT OVER INDEX;So;0;L;;;;;N;;;;;
+1D81D;SIGNWRITING HAND-FIST INDEX BENT OVER MIDDLE;So;0;L;;;;;N;;;;;
+1D81E;SIGNWRITING HAND-FIST INDEX MIDDLE THUMB;So;0;L;;;;;N;;;;;
+1D81F;SIGNWRITING HAND-CIRCLE INDEX MIDDLE THUMB;So;0;L;;;;;N;;;;;
+1D820;SIGNWRITING HAND-FIST INDEX MIDDLE STRAIGHT THUMB BENT;So;0;L;;;;;N;;;;;
+1D821;SIGNWRITING HAND-FIST INDEX MIDDLE BENT THUMB STRAIGHT;So;0;L;;;;;N;;;;;
+1D822;SIGNWRITING HAND-FIST INDEX MIDDLE THUMB BENT;So;0;L;;;;;N;;;;;
+1D823;SIGNWRITING HAND-FIST INDEX MIDDLE HINGED SPREAD THUMB SIDE;So;0;L;;;;;N;;;;;
+1D824;SIGNWRITING HAND-FIST INDEX UP MIDDLE HINGED THUMB SIDE;So;0;L;;;;;N;;;;;
+1D825;SIGNWRITING HAND-FIST INDEX UP MIDDLE HINGED THUMB CONJOINED;So;0;L;;;;;N;;;;;
+1D826;SIGNWRITING HAND-FIST INDEX HINGED MIDDLE UP THUMB SIDE;So;0;L;;;;;N;;;;;
+1D827;SIGNWRITING HAND-FIST INDEX MIDDLE UP SPREAD THUMB FORWARD;So;0;L;;;;;N;;;;;
+1D828;SIGNWRITING HAND-FIST INDEX MIDDLE THUMB CUPPED;So;0;L;;;;;N;;;;;
+1D829;SIGNWRITING HAND-FIST INDEX MIDDLE THUMB CIRCLED;So;0;L;;;;;N;;;;;
+1D82A;SIGNWRITING HAND-FIST INDEX MIDDLE THUMB HOOKED;So;0;L;;;;;N;;;;;
+1D82B;SIGNWRITING HAND-FIST INDEX MIDDLE THUMB HINGED;So;0;L;;;;;N;;;;;
+1D82C;SIGNWRITING HAND-FIST THUMB BETWEEN INDEX MIDDLE STRAIGHT;So;0;L;;;;;N;;;;;
+1D82D;SIGNWRITING HAND-FIST INDEX MIDDLE CONJOINED THUMB SIDE;So;0;L;;;;;N;;;;;
+1D82E;SIGNWRITING HAND-FIST INDEX MIDDLE CONJOINED THUMB SIDE CONJOINED;So;0;L;;;;;N;;;;;
+1D82F;SIGNWRITING HAND-FIST INDEX MIDDLE CONJOINED THUMB SIDE BENT;So;0;L;;;;;N;;;;;
+1D830;SIGNWRITING HAND-FIST MIDDLE THUMB HOOKED INDEX UP;So;0;L;;;;;N;;;;;
+1D831;SIGNWRITING HAND-FIST INDEX THUMB HOOKED MIDDLE UP;So;0;L;;;;;N;;;;;
+1D832;SIGNWRITING HAND-FIST INDEX MIDDLE CONJOINED HINGED THUMB SIDE;So;0;L;;;;;N;;;;;
+1D833;SIGNWRITING HAND-FIST INDEX MIDDLE CROSSED THUMB SIDE;So;0;L;;;;;N;;;;;
+1D834;SIGNWRITING HAND-FIST INDEX MIDDLE CONJOINED THUMB FORWARD;So;0;L;;;;;N;;;;;
+1D835;SIGNWRITING HAND-FIST INDEX MIDDLE CONJOINED CUPPED THUMB FORWARD;So;0;L;;;;;N;;;;;
+1D836;SIGNWRITING HAND-FIST MIDDLE THUMB CUPPED INDEX UP;So;0;L;;;;;N;;;;;
+1D837;SIGNWRITING HAND-FIST INDEX THUMB CUPPED MIDDLE UP;So;0;L;;;;;N;;;;;
+1D838;SIGNWRITING HAND-FIST MIDDLE THUMB CIRCLED INDEX UP;So;0;L;;;;;N;;;;;
+1D839;SIGNWRITING HAND-FIST MIDDLE THUMB CIRCLED INDEX HINGED;So;0;L;;;;;N;;;;;
+1D83A;SIGNWRITING HAND-FIST INDEX THUMB ANGLED OUT MIDDLE UP;So;0;L;;;;;N;;;;;
+1D83B;SIGNWRITING HAND-FIST INDEX THUMB ANGLED IN MIDDLE UP;So;0;L;;;;;N;;;;;
+1D83C;SIGNWRITING HAND-FIST INDEX THUMB CIRCLED MIDDLE UP;So;0;L;;;;;N;;;;;
+1D83D;SIGNWRITING HAND-FIST INDEX MIDDLE THUMB CONJOINED HINGED;So;0;L;;;;;N;;;;;
+1D83E;SIGNWRITING HAND-FIST INDEX MIDDLE THUMB ANGLED OUT;So;0;L;;;;;N;;;;;
+1D83F;SIGNWRITING HAND-FIST INDEX MIDDLE THUMB ANGLED;So;0;L;;;;;N;;;;;
+1D840;SIGNWRITING HAND-FIST MIDDLE THUMB ANGLED OUT INDEX UP;So;0;L;;;;;N;;;;;
+1D841;SIGNWRITING HAND-FIST MIDDLE THUMB ANGLED OUT INDEX CROSSED;So;0;L;;;;;N;;;;;
+1D842;SIGNWRITING HAND-FIST MIDDLE THUMB ANGLED INDEX UP;So;0;L;;;;;N;;;;;
+1D843;SIGNWRITING HAND-FIST INDEX THUMB HOOKED MIDDLE HINGED;So;0;L;;;;;N;;;;;
+1D844;SIGNWRITING HAND-FLAT FOUR FINGERS;So;0;L;;;;;N;;;;;
+1D845;SIGNWRITING HAND-FLAT FOUR FINGERS BENT;So;0;L;;;;;N;;;;;
+1D846;SIGNWRITING HAND-FLAT FOUR FINGERS HINGED;So;0;L;;;;;N;;;;;
+1D847;SIGNWRITING HAND-FLAT FOUR FINGERS CONJOINED;So;0;L;;;;;N;;;;;
+1D848;SIGNWRITING HAND-FLAT FOUR FINGERS CONJOINED SPLIT;So;0;L;;;;;N;;;;;
+1D849;SIGNWRITING HAND-CLAW FOUR FINGERS CONJOINED;So;0;L;;;;;N;;;;;
+1D84A;SIGNWRITING HAND-FIST FOUR FINGERS CONJOINED BENT;So;0;L;;;;;N;;;;;
+1D84B;SIGNWRITING HAND-HINGE FOUR FINGERS CONJOINED;So;0;L;;;;;N;;;;;
+1D84C;SIGNWRITING HAND-FLAT FIVE FINGERS SPREAD;So;0;L;;;;;N;;;;;
+1D84D;SIGNWRITING HAND-FLAT HEEL FIVE FINGERS SPREAD;So;0;L;;;;;N;;;;;
+1D84E;SIGNWRITING HAND-FLAT FIVE FINGERS SPREAD FOUR BENT;So;0;L;;;;;N;;;;;
+1D84F;SIGNWRITING HAND-FLAT HEEL FIVE FINGERS SPREAD FOUR BENT;So;0;L;;;;;N;;;;;
+1D850;SIGNWRITING HAND-FLAT FIVE FINGERS SPREAD BENT;So;0;L;;;;;N;;;;;
+1D851;SIGNWRITING HAND-FLAT HEEL FIVE FINGERS SPREAD BENT;So;0;L;;;;;N;;;;;
+1D852;SIGNWRITING HAND-FLAT FIVE FINGERS SPREAD THUMB FORWARD;So;0;L;;;;;N;;;;;
+1D853;SIGNWRITING HAND-CUP FIVE FINGERS SPREAD;So;0;L;;;;;N;;;;;
+1D854;SIGNWRITING HAND-CUP FIVE FINGERS SPREAD OPEN;So;0;L;;;;;N;;;;;
+1D855;SIGNWRITING HAND-HINGE FIVE FINGERS SPREAD OPEN;So;0;L;;;;;N;;;;;
+1D856;SIGNWRITING HAND-OVAL FIVE FINGERS SPREAD;So;0;L;;;;;N;;;;;
+1D857;SIGNWRITING HAND-FLAT FIVE FINGERS SPREAD HINGED;So;0;L;;;;;N;;;;;
+1D858;SIGNWRITING HAND-FLAT FIVE FINGERS SPREAD HINGED THUMB SIDE;So;0;L;;;;;N;;;;;
+1D859;SIGNWRITING HAND-FLAT FIVE FINGERS SPREAD HINGED NO THUMB;So;0;L;;;;;N;;;;;
+1D85A;SIGNWRITING HAND-FLAT;So;0;L;;;;;N;;;;;
+1D85B;SIGNWRITING HAND-FLAT BETWEEN PALM FACINGS;So;0;L;;;;;N;;;;;
+1D85C;SIGNWRITING HAND-FLAT HEEL;So;0;L;;;;;N;;;;;
+1D85D;SIGNWRITING HAND-FLAT THUMB SIDE;So;0;L;;;;;N;;;;;
+1D85E;SIGNWRITING HAND-FLAT HEEL THUMB SIDE;So;0;L;;;;;N;;;;;
+1D85F;SIGNWRITING HAND-FLAT THUMB BENT;So;0;L;;;;;N;;;;;
+1D860;SIGNWRITING HAND-FLAT THUMB FORWARD;So;0;L;;;;;N;;;;;
+1D861;SIGNWRITING HAND-FLAT SPLIT INDEX THUMB SIDE;So;0;L;;;;;N;;;;;
+1D862;SIGNWRITING HAND-FLAT SPLIT CENTRE;So;0;L;;;;;N;;;;;
+1D863;SIGNWRITING HAND-FLAT SPLIT CENTRE THUMB SIDE;So;0;L;;;;;N;;;;;
+1D864;SIGNWRITING HAND-FLAT SPLIT CENTRE THUMB SIDE BENT;So;0;L;;;;;N;;;;;
+1D865;SIGNWRITING HAND-FLAT SPLIT LITTLE;So;0;L;;;;;N;;;;;
+1D866;SIGNWRITING HAND-CLAW;So;0;L;;;;;N;;;;;
+1D867;SIGNWRITING HAND-CLAW THUMB SIDE;So;0;L;;;;;N;;;;;
+1D868;SIGNWRITING HAND-CLAW NO THUMB;So;0;L;;;;;N;;;;;
+1D869;SIGNWRITING HAND-CLAW THUMB FORWARD;So;0;L;;;;;N;;;;;
+1D86A;SIGNWRITING HAND-HOOK CURLICUE;So;0;L;;;;;N;;;;;
+1D86B;SIGNWRITING HAND-HOOK;So;0;L;;;;;N;;;;;
+1D86C;SIGNWRITING HAND-CUP OPEN;So;0;L;;;;;N;;;;;
+1D86D;SIGNWRITING HAND-CUP;So;0;L;;;;;N;;;;;
+1D86E;SIGNWRITING HAND-CUP OPEN THUMB SIDE;So;0;L;;;;;N;;;;;
+1D86F;SIGNWRITING HAND-CUP THUMB SIDE;So;0;L;;;;;N;;;;;
+1D870;SIGNWRITING HAND-CUP OPEN NO THUMB;So;0;L;;;;;N;;;;;
+1D871;SIGNWRITING HAND-CUP NO THUMB;So;0;L;;;;;N;;;;;
+1D872;SIGNWRITING HAND-CUP OPEN THUMB FORWARD;So;0;L;;;;;N;;;;;
+1D873;SIGNWRITING HAND-CUP THUMB FORWARD;So;0;L;;;;;N;;;;;
+1D874;SIGNWRITING HAND-CURLICUE OPEN;So;0;L;;;;;N;;;;;
+1D875;SIGNWRITING HAND-CURLICUE;So;0;L;;;;;N;;;;;
+1D876;SIGNWRITING HAND-CIRCLE;So;0;L;;;;;N;;;;;
+1D877;SIGNWRITING HAND-OVAL;So;0;L;;;;;N;;;;;
+1D878;SIGNWRITING HAND-OVAL THUMB SIDE;So;0;L;;;;;N;;;;;
+1D879;SIGNWRITING HAND-OVAL NO THUMB;So;0;L;;;;;N;;;;;
+1D87A;SIGNWRITING HAND-OVAL THUMB FORWARD;So;0;L;;;;;N;;;;;
+1D87B;SIGNWRITING HAND-HINGE OPEN;So;0;L;;;;;N;;;;;
+1D87C;SIGNWRITING HAND-HINGE OPEN THUMB FORWARD;So;0;L;;;;;N;;;;;
+1D87D;SIGNWRITING HAND-HINGE;So;0;L;;;;;N;;;;;
+1D87E;SIGNWRITING HAND-HINGE SMALL;So;0;L;;;;;N;;;;;
+1D87F;SIGNWRITING HAND-HINGE OPEN THUMB SIDE;So;0;L;;;;;N;;;;;
+1D880;SIGNWRITING HAND-HINGE THUMB SIDE;So;0;L;;;;;N;;;;;
+1D881;SIGNWRITING HAND-HINGE OPEN NO THUMB;So;0;L;;;;;N;;;;;
+1D882;SIGNWRITING HAND-HINGE NO THUMB;So;0;L;;;;;N;;;;;
+1D883;SIGNWRITING HAND-HINGE THUMB SIDE TOUCHING INDEX;So;0;L;;;;;N;;;;;
+1D884;SIGNWRITING HAND-HINGE THUMB BETWEEN MIDDLE RING;So;0;L;;;;;N;;;;;
+1D885;SIGNWRITING HAND-ANGLE;So;0;L;;;;;N;;;;;
+1D886;SIGNWRITING HAND-FIST INDEX MIDDLE RING;So;0;L;;;;;N;;;;;
+1D887;SIGNWRITING HAND-CIRCLE INDEX MIDDLE RING;So;0;L;;;;;N;;;;;
+1D888;SIGNWRITING HAND-HINGE INDEX MIDDLE RING;So;0;L;;;;;N;;;;;
+1D889;SIGNWRITING HAND-ANGLE INDEX MIDDLE RING;So;0;L;;;;;N;;;;;
+1D88A;SIGNWRITING HAND-HINGE LITTLE;So;0;L;;;;;N;;;;;
+1D88B;SIGNWRITING HAND-FIST INDEX MIDDLE RING BENT;So;0;L;;;;;N;;;;;
+1D88C;SIGNWRITING HAND-FIST INDEX MIDDLE RING CONJOINED;So;0;L;;;;;N;;;;;
+1D88D;SIGNWRITING HAND-HINGE INDEX MIDDLE RING CONJOINED;So;0;L;;;;;N;;;;;
+1D88E;SIGNWRITING HAND-FIST LITTLE DOWN;So;0;L;;;;;N;;;;;
+1D88F;SIGNWRITING HAND-FIST LITTLE DOWN RIPPLE STRAIGHT;So;0;L;;;;;N;;;;;
+1D890;SIGNWRITING HAND-FIST LITTLE DOWN RIPPLE CURVED;So;0;L;;;;;N;;;;;
+1D891;SIGNWRITING HAND-FIST LITTLE DOWN OTHERS CIRCLED;So;0;L;;;;;N;;;;;
+1D892;SIGNWRITING HAND-FIST LITTLE UP;So;0;L;;;;;N;;;;;
+1D893;SIGNWRITING HAND-FIST THUMB UNDER LITTLE UP;So;0;L;;;;;N;;;;;
+1D894;SIGNWRITING HAND-CIRCLE LITTLE UP;So;0;L;;;;;N;;;;;
+1D895;SIGNWRITING HAND-OVAL LITTLE UP;So;0;L;;;;;N;;;;;
+1D896;SIGNWRITING HAND-ANGLE LITTLE UP;So;0;L;;;;;N;;;;;
+1D897;SIGNWRITING HAND-FIST LITTLE RAISED KNUCKLE;So;0;L;;;;;N;;;;;
+1D898;SIGNWRITING HAND-FIST LITTLE BENT;So;0;L;;;;;N;;;;;
+1D899;SIGNWRITING HAND-FIST LITTLE TOUCHES THUMB;So;0;L;;;;;N;;;;;
+1D89A;SIGNWRITING HAND-FIST LITTLE THUMB;So;0;L;;;;;N;;;;;
+1D89B;SIGNWRITING HAND-HINGE LITTLE THUMB;So;0;L;;;;;N;;;;;
+1D89C;SIGNWRITING HAND-FIST LITTLE INDEX THUMB;So;0;L;;;;;N;;;;;
+1D89D;SIGNWRITING HAND-HINGE LITTLE INDEX THUMB;So;0;L;;;;;N;;;;;
+1D89E;SIGNWRITING HAND-ANGLE LITTLE INDEX THUMB INDEX THUMB OUT;So;0;L;;;;;N;;;;;
+1D89F;SIGNWRITING HAND-ANGLE LITTLE INDEX THUMB INDEX THUMB;So;0;L;;;;;N;;;;;
+1D8A0;SIGNWRITING HAND-FIST LITTLE INDEX;So;0;L;;;;;N;;;;;
+1D8A1;SIGNWRITING HAND-CIRCLE LITTLE INDEX;So;0;L;;;;;N;;;;;
+1D8A2;SIGNWRITING HAND-HINGE LITTLE INDEX;So;0;L;;;;;N;;;;;
+1D8A3;SIGNWRITING HAND-ANGLE LITTLE INDEX;So;0;L;;;;;N;;;;;
+1D8A4;SIGNWRITING HAND-FIST INDEX MIDDLE LITTLE;So;0;L;;;;;N;;;;;
+1D8A5;SIGNWRITING HAND-CIRCLE INDEX MIDDLE LITTLE;So;0;L;;;;;N;;;;;
+1D8A6;SIGNWRITING HAND-HINGE INDEX MIDDLE LITTLE;So;0;L;;;;;N;;;;;
+1D8A7;SIGNWRITING HAND-HINGE RING;So;0;L;;;;;N;;;;;
+1D8A8;SIGNWRITING HAND-ANGLE INDEX MIDDLE LITTLE;So;0;L;;;;;N;;;;;
+1D8A9;SIGNWRITING HAND-FIST INDEX MIDDLE CROSS LITTLE;So;0;L;;;;;N;;;;;
+1D8AA;SIGNWRITING HAND-CIRCLE INDEX MIDDLE CROSS LITTLE;So;0;L;;;;;N;;;;;
+1D8AB;SIGNWRITING HAND-FIST RING DOWN;So;0;L;;;;;N;;;;;
+1D8AC;SIGNWRITING HAND-HINGE RING DOWN INDEX THUMB HOOK MIDDLE;So;0;L;;;;;N;;;;;
+1D8AD;SIGNWRITING HAND-ANGLE RING DOWN MIDDLE THUMB INDEX CROSS;So;0;L;;;;;N;;;;;
+1D8AE;SIGNWRITING HAND-FIST RING UP;So;0;L;;;;;N;;;;;
+1D8AF;SIGNWRITING HAND-FIST RING RAISED KNUCKLE;So;0;L;;;;;N;;;;;
+1D8B0;SIGNWRITING HAND-FIST RING LITTLE;So;0;L;;;;;N;;;;;
+1D8B1;SIGNWRITING HAND-CIRCLE RING LITTLE;So;0;L;;;;;N;;;;;
+1D8B2;SIGNWRITING HAND-OVAL RING LITTLE;So;0;L;;;;;N;;;;;
+1D8B3;SIGNWRITING HAND-ANGLE RING LITTLE;So;0;L;;;;;N;;;;;
+1D8B4;SIGNWRITING HAND-FIST RING MIDDLE;So;0;L;;;;;N;;;;;
+1D8B5;SIGNWRITING HAND-FIST RING MIDDLE CONJOINED;So;0;L;;;;;N;;;;;
+1D8B6;SIGNWRITING HAND-FIST RING MIDDLE RAISED KNUCKLES;So;0;L;;;;;N;;;;;
+1D8B7;SIGNWRITING HAND-FIST RING INDEX;So;0;L;;;;;N;;;;;
+1D8B8;SIGNWRITING HAND-FIST RING THUMB;So;0;L;;;;;N;;;;;
+1D8B9;SIGNWRITING HAND-HOOK RING THUMB;So;0;L;;;;;N;;;;;
+1D8BA;SIGNWRITING HAND-FIST INDEX RING LITTLE;So;0;L;;;;;N;;;;;
+1D8BB;SIGNWRITING HAND-CIRCLE INDEX RING LITTLE;So;0;L;;;;;N;;;;;
+1D8BC;SIGNWRITING HAND-CURLICUE INDEX RING LITTLE ON;So;0;L;;;;;N;;;;;
+1D8BD;SIGNWRITING HAND-HOOK INDEX RING LITTLE OUT;So;0;L;;;;;N;;;;;
+1D8BE;SIGNWRITING HAND-HOOK INDEX RING LITTLE IN;So;0;L;;;;;N;;;;;
+1D8BF;SIGNWRITING HAND-HOOK INDEX RING LITTLE UNDER;So;0;L;;;;;N;;;;;
+1D8C0;SIGNWRITING HAND-CUP INDEX RING LITTLE;So;0;L;;;;;N;;;;;
+1D8C1;SIGNWRITING HAND-HINGE INDEX RING LITTLE;So;0;L;;;;;N;;;;;
+1D8C2;SIGNWRITING HAND-ANGLE INDEX RING LITTLE OUT;So;0;L;;;;;N;;;;;
+1D8C3;SIGNWRITING HAND-ANGLE INDEX RING LITTLE;So;0;L;;;;;N;;;;;
+1D8C4;SIGNWRITING HAND-FIST MIDDLE DOWN;So;0;L;;;;;N;;;;;
+1D8C5;SIGNWRITING HAND-HINGE MIDDLE;So;0;L;;;;;N;;;;;
+1D8C6;SIGNWRITING HAND-FIST MIDDLE UP;So;0;L;;;;;N;;;;;
+1D8C7;SIGNWRITING HAND-CIRCLE MIDDLE UP;So;0;L;;;;;N;;;;;
+1D8C8;SIGNWRITING HAND-FIST MIDDLE RAISED KNUCKLE;So;0;L;;;;;N;;;;;
+1D8C9;SIGNWRITING HAND-FIST MIDDLE UP THUMB SIDE;So;0;L;;;;;N;;;;;
+1D8CA;SIGNWRITING HAND-HOOK MIDDLE THUMB;So;0;L;;;;;N;;;;;
+1D8CB;SIGNWRITING HAND-FIST MIDDLE THUMB LITTLE;So;0;L;;;;;N;;;;;
+1D8CC;SIGNWRITING HAND-FIST MIDDLE LITTLE;So;0;L;;;;;N;;;;;
+1D8CD;SIGNWRITING HAND-FIST MIDDLE RING LITTLE;So;0;L;;;;;N;;;;;
+1D8CE;SIGNWRITING HAND-CIRCLE MIDDLE RING LITTLE;So;0;L;;;;;N;;;;;
+1D8CF;SIGNWRITING HAND-CURLICUE MIDDLE RING LITTLE ON;So;0;L;;;;;N;;;;;
+1D8D0;SIGNWRITING HAND-CUP MIDDLE RING LITTLE;So;0;L;;;;;N;;;;;
+1D8D1;SIGNWRITING HAND-HINGE MIDDLE RING LITTLE;So;0;L;;;;;N;;;;;
+1D8D2;SIGNWRITING HAND-ANGLE MIDDLE RING LITTLE OUT;So;0;L;;;;;N;;;;;
+1D8D3;SIGNWRITING HAND-ANGLE MIDDLE RING LITTLE IN;So;0;L;;;;;N;;;;;
+1D8D4;SIGNWRITING HAND-ANGLE MIDDLE RING LITTLE;So;0;L;;;;;N;;;;;
+1D8D5;SIGNWRITING HAND-CIRCLE MIDDLE RING LITTLE BENT;So;0;L;;;;;N;;;;;
+1D8D6;SIGNWRITING HAND-CLAW MIDDLE RING LITTLE CONJOINED;So;0;L;;;;;N;;;;;
+1D8D7;SIGNWRITING HAND-CLAW MIDDLE RING LITTLE CONJOINED SIDE;So;0;L;;;;;N;;;;;
+1D8D8;SIGNWRITING HAND-HOOK MIDDLE RING LITTLE CONJOINED OUT;So;0;L;;;;;N;;;;;
+1D8D9;SIGNWRITING HAND-HOOK MIDDLE RING LITTLE CONJOINED IN;So;0;L;;;;;N;;;;;
+1D8DA;SIGNWRITING HAND-HOOK MIDDLE RING LITTLE CONJOINED;So;0;L;;;;;N;;;;;
+1D8DB;SIGNWRITING HAND-HINGE INDEX HINGED;So;0;L;;;;;N;;;;;
+1D8DC;SIGNWRITING HAND-FIST INDEX THUMB SIDE;So;0;L;;;;;N;;;;;
+1D8DD;SIGNWRITING HAND-HINGE INDEX THUMB SIDE;So;0;L;;;;;N;;;;;
+1D8DE;SIGNWRITING HAND-FIST INDEX THUMB SIDE THUMB DIAGONAL;So;0;L;;;;;N;;;;;
+1D8DF;SIGNWRITING HAND-FIST INDEX THUMB SIDE THUMB CONJOINED;So;0;L;;;;;N;;;;;
+1D8E0;SIGNWRITING HAND-FIST INDEX THUMB SIDE THUMB BENT;So;0;L;;;;;N;;;;;
+1D8E1;SIGNWRITING HAND-FIST INDEX THUMB SIDE INDEX BENT;So;0;L;;;;;N;;;;;
+1D8E2;SIGNWRITING HAND-FIST INDEX THUMB SIDE BOTH BENT;So;0;L;;;;;N;;;;;
+1D8E3;SIGNWRITING HAND-FIST INDEX THUMB SIDE INDEX HINGE;So;0;L;;;;;N;;;;;
+1D8E4;SIGNWRITING HAND-FIST INDEX THUMB FORWARD INDEX STRAIGHT;So;0;L;;;;;N;;;;;
+1D8E5;SIGNWRITING HAND-FIST INDEX THUMB FORWARD INDEX BENT;So;0;L;;;;;N;;;;;
+1D8E6;SIGNWRITING HAND-FIST INDEX THUMB HOOK;So;0;L;;;;;N;;;;;
+1D8E7;SIGNWRITING HAND-FIST INDEX THUMB CURLICUE;So;0;L;;;;;N;;;;;
+1D8E8;SIGNWRITING HAND-FIST INDEX THUMB CURVE THUMB INSIDE;So;0;L;;;;;N;;;;;
+1D8E9;SIGNWRITING HAND-CLAW INDEX THUMB CURVE THUMB INSIDE;So;0;L;;;;;N;;;;;
+1D8EA;SIGNWRITING HAND-FIST INDEX THUMB CURVE THUMB UNDER;So;0;L;;;;;N;;;;;
+1D8EB;SIGNWRITING HAND-FIST INDEX THUMB CIRCLE;So;0;L;;;;;N;;;;;
+1D8EC;SIGNWRITING HAND-CUP INDEX THUMB;So;0;L;;;;;N;;;;;
+1D8ED;SIGNWRITING HAND-CUP INDEX THUMB OPEN;So;0;L;;;;;N;;;;;
+1D8EE;SIGNWRITING HAND-HINGE INDEX THUMB OPEN;So;0;L;;;;;N;;;;;
+1D8EF;SIGNWRITING HAND-HINGE INDEX THUMB LARGE;So;0;L;;;;;N;;;;;
+1D8F0;SIGNWRITING HAND-HINGE INDEX THUMB;So;0;L;;;;;N;;;;;
+1D8F1;SIGNWRITING HAND-HINGE INDEX THUMB SMALL;So;0;L;;;;;N;;;;;
+1D8F2;SIGNWRITING HAND-ANGLE INDEX THUMB OUT;So;0;L;;;;;N;;;;;
+1D8F3;SIGNWRITING HAND-ANGLE INDEX THUMB IN;So;0;L;;;;;N;;;;;
+1D8F4;SIGNWRITING HAND-ANGLE INDEX THUMB;So;0;L;;;;;N;;;;;
+1D8F5;SIGNWRITING HAND-FIST THUMB;So;0;L;;;;;N;;;;;
+1D8F6;SIGNWRITING HAND-FIST THUMB HEEL;So;0;L;;;;;N;;;;;
+1D8F7;SIGNWRITING HAND-FIST THUMB SIDE DIAGONAL;So;0;L;;;;;N;;;;;
+1D8F8;SIGNWRITING HAND-FIST THUMB SIDE CONJOINED;So;0;L;;;;;N;;;;;
+1D8F9;SIGNWRITING HAND-FIST THUMB SIDE BENT;So;0;L;;;;;N;;;;;
+1D8FA;SIGNWRITING HAND-FIST THUMB FORWARD;So;0;L;;;;;N;;;;;
+1D8FB;SIGNWRITING HAND-FIST THUMB BETWEEN INDEX MIDDLE;So;0;L;;;;;N;;;;;
+1D8FC;SIGNWRITING HAND-FIST THUMB BETWEEN MIDDLE RING;So;0;L;;;;;N;;;;;
+1D8FD;SIGNWRITING HAND-FIST THUMB BETWEEN RING LITTLE;So;0;L;;;;;N;;;;;
+1D8FE;SIGNWRITING HAND-FIST THUMB UNDER TWO FINGERS;So;0;L;;;;;N;;;;;
+1D8FF;SIGNWRITING HAND-FIST THUMB OVER TWO FINGERS;So;0;L;;;;;N;;;;;
+1D900;SIGNWRITING HAND-FIST THUMB UNDER THREE FINGERS;So;0;L;;;;;N;;;;;
+1D901;SIGNWRITING HAND-FIST THUMB UNDER FOUR FINGERS;So;0;L;;;;;N;;;;;
+1D902;SIGNWRITING HAND-FIST THUMB OVER FOUR RAISED KNUCKLES;So;0;L;;;;;N;;;;;
+1D903;SIGNWRITING HAND-FIST;So;0;L;;;;;N;;;;;
+1D904;SIGNWRITING HAND-FIST HEEL;So;0;L;;;;;N;;;;;
+1D905;SIGNWRITING TOUCH SINGLE;So;0;L;;;;;N;;;;;
+1D906;SIGNWRITING TOUCH MULTIPLE;So;0;L;;;;;N;;;;;
+1D907;SIGNWRITING TOUCH BETWEEN;So;0;L;;;;;N;;;;;
+1D908;SIGNWRITING GRASP SINGLE;So;0;L;;;;;N;;;;;
+1D909;SIGNWRITING GRASP MULTIPLE;So;0;L;;;;;N;;;;;
+1D90A;SIGNWRITING GRASP BETWEEN;So;0;L;;;;;N;;;;;
+1D90B;SIGNWRITING STRIKE SINGLE;So;0;L;;;;;N;;;;;
+1D90C;SIGNWRITING STRIKE MULTIPLE;So;0;L;;;;;N;;;;;
+1D90D;SIGNWRITING STRIKE BETWEEN;So;0;L;;;;;N;;;;;
+1D90E;SIGNWRITING BRUSH SINGLE;So;0;L;;;;;N;;;;;
+1D90F;SIGNWRITING BRUSH MULTIPLE;So;0;L;;;;;N;;;;;
+1D910;SIGNWRITING BRUSH BETWEEN;So;0;L;;;;;N;;;;;
+1D911;SIGNWRITING RUB SINGLE;So;0;L;;;;;N;;;;;
+1D912;SIGNWRITING RUB MULTIPLE;So;0;L;;;;;N;;;;;
+1D913;SIGNWRITING RUB BETWEEN;So;0;L;;;;;N;;;;;
+1D914;SIGNWRITING SURFACE SYMBOLS;So;0;L;;;;;N;;;;;
+1D915;SIGNWRITING SURFACE BETWEEN;So;0;L;;;;;N;;;;;
+1D916;SIGNWRITING SQUEEZE LARGE SINGLE;So;0;L;;;;;N;;;;;
+1D917;SIGNWRITING SQUEEZE SMALL SINGLE;So;0;L;;;;;N;;;;;
+1D918;SIGNWRITING SQUEEZE LARGE MULTIPLE;So;0;L;;;;;N;;;;;
+1D919;SIGNWRITING SQUEEZE SMALL MULTIPLE;So;0;L;;;;;N;;;;;
+1D91A;SIGNWRITING SQUEEZE SEQUENTIAL;So;0;L;;;;;N;;;;;
+1D91B;SIGNWRITING FLICK LARGE SINGLE;So;0;L;;;;;N;;;;;
+1D91C;SIGNWRITING FLICK SMALL SINGLE;So;0;L;;;;;N;;;;;
+1D91D;SIGNWRITING FLICK LARGE MULTIPLE;So;0;L;;;;;N;;;;;
+1D91E;SIGNWRITING FLICK SMALL MULTIPLE;So;0;L;;;;;N;;;;;
+1D91F;SIGNWRITING FLICK SEQUENTIAL;So;0;L;;;;;N;;;;;
+1D920;SIGNWRITING SQUEEZE FLICK ALTERNATING;So;0;L;;;;;N;;;;;
+1D921;SIGNWRITING MOVEMENT-HINGE UP DOWN LARGE;So;0;L;;;;;N;;;;;
+1D922;SIGNWRITING MOVEMENT-HINGE UP DOWN SMALL;So;0;L;;;;;N;;;;;
+1D923;SIGNWRITING MOVEMENT-HINGE UP SEQUENTIAL;So;0;L;;;;;N;;;;;
+1D924;SIGNWRITING MOVEMENT-HINGE DOWN SEQUENTIAL;So;0;L;;;;;N;;;;;
+1D925;SIGNWRITING MOVEMENT-HINGE UP DOWN ALTERNATING LARGE;So;0;L;;;;;N;;;;;
+1D926;SIGNWRITING MOVEMENT-HINGE UP DOWN ALTERNATING SMALL;So;0;L;;;;;N;;;;;
+1D927;SIGNWRITING MOVEMENT-HINGE SIDE TO SIDE SCISSORS;So;0;L;;;;;N;;;;;
+1D928;SIGNWRITING MOVEMENT-WALLPLANE FINGER CONTACT;So;0;L;;;;;N;;;;;
+1D929;SIGNWRITING MOVEMENT-FLOORPLANE FINGER CONTACT;So;0;L;;;;;N;;;;;
+1D92A;SIGNWRITING MOVEMENT-WALLPLANE SINGLE STRAIGHT SMALL;So;0;L;;;;;N;;;;;
+1D92B;SIGNWRITING MOVEMENT-WALLPLANE SINGLE STRAIGHT MEDIUM;So;0;L;;;;;N;;;;;
+1D92C;SIGNWRITING MOVEMENT-WALLPLANE SINGLE STRAIGHT LARGE;So;0;L;;;;;N;;;;;
+1D92D;SIGNWRITING MOVEMENT-WALLPLANE SINGLE STRAIGHT LARGEST;So;0;L;;;;;N;;;;;
+1D92E;SIGNWRITING MOVEMENT-WALLPLANE SINGLE WRIST FLEX;So;0;L;;;;;N;;;;;
+1D92F;SIGNWRITING MOVEMENT-WALLPLANE DOUBLE STRAIGHT;So;0;L;;;;;N;;;;;
+1D930;SIGNWRITING MOVEMENT-WALLPLANE DOUBLE WRIST FLEX;So;0;L;;;;;N;;;;;
+1D931;SIGNWRITING MOVEMENT-WALLPLANE DOUBLE ALTERNATING;So;0;L;;;;;N;;;;;
+1D932;SIGNWRITING MOVEMENT-WALLPLANE DOUBLE ALTERNATING WRIST FLEX;So;0;L;;;;;N;;;;;
+1D933;SIGNWRITING MOVEMENT-WALLPLANE CROSS;So;0;L;;;;;N;;;;;
+1D934;SIGNWRITING MOVEMENT-WALLPLANE TRIPLE STRAIGHT MOVEMENT;So;0;L;;;;;N;;;;;
+1D935;SIGNWRITING MOVEMENT-WALLPLANE TRIPLE WRIST FLEX;So;0;L;;;;;N;;;;;
+1D936;SIGNWRITING MOVEMENT-WALLPLANE TRIPLE ALTERNATING;So;0;L;;;;;N;;;;;
+1D937;SIGNWRITING MOVEMENT-WALLPLANE TRIPLE ALTERNATING WRIST FLEX;So;0;L;;;;;N;;;;;
+1D938;SIGNWRITING MOVEMENT-WALLPLANE BEND SMALL;So;0;L;;;;;N;;;;;
+1D939;SIGNWRITING MOVEMENT-WALLPLANE BEND MEDIUM;So;0;L;;;;;N;;;;;
+1D93A;SIGNWRITING MOVEMENT-WALLPLANE BEND LARGE;So;0;L;;;;;N;;;;;
+1D93B;SIGNWRITING MOVEMENT-WALLPLANE CORNER SMALL;So;0;L;;;;;N;;;;;
+1D93C;SIGNWRITING MOVEMENT-WALLPLANE CORNER MEDIUM;So;0;L;;;;;N;;;;;
+1D93D;SIGNWRITING MOVEMENT-WALLPLANE CORNER LARGE;So;0;L;;;;;N;;;;;
+1D93E;SIGNWRITING MOVEMENT-WALLPLANE CORNER ROTATION;So;0;L;;;;;N;;;;;
+1D93F;SIGNWRITING MOVEMENT-WALLPLANE CHECK SMALL;So;0;L;;;;;N;;;;;
+1D940;SIGNWRITING MOVEMENT-WALLPLANE CHECK MEDIUM;So;0;L;;;;;N;;;;;
+1D941;SIGNWRITING MOVEMENT-WALLPLANE CHECK LARGE;So;0;L;;;;;N;;;;;
+1D942;SIGNWRITING MOVEMENT-WALLPLANE BOX SMALL;So;0;L;;;;;N;;;;;
+1D943;SIGNWRITING MOVEMENT-WALLPLANE BOX MEDIUM;So;0;L;;;;;N;;;;;
+1D944;SIGNWRITING MOVEMENT-WALLPLANE BOX LARGE;So;0;L;;;;;N;;;;;
+1D945;SIGNWRITING MOVEMENT-WALLPLANE ZIGZAG SMALL;So;0;L;;;;;N;;;;;
+1D946;SIGNWRITING MOVEMENT-WALLPLANE ZIGZAG MEDIUM;So;0;L;;;;;N;;;;;
+1D947;SIGNWRITING MOVEMENT-WALLPLANE ZIGZAG LARGE;So;0;L;;;;;N;;;;;
+1D948;SIGNWRITING MOVEMENT-WALLPLANE PEAKS SMALL;So;0;L;;;;;N;;;;;
+1D949;SIGNWRITING MOVEMENT-WALLPLANE PEAKS MEDIUM;So;0;L;;;;;N;;;;;
+1D94A;SIGNWRITING MOVEMENT-WALLPLANE PEAKS LARGE;So;0;L;;;;;N;;;;;
+1D94B;SIGNWRITING TRAVEL-WALLPLANE ROTATION-WALLPLANE SINGLE;So;0;L;;;;;N;;;;;
+1D94C;SIGNWRITING TRAVEL-WALLPLANE ROTATION-WALLPLANE DOUBLE;So;0;L;;;;;N;;;;;
+1D94D;SIGNWRITING TRAVEL-WALLPLANE ROTATION-WALLPLANE ALTERNATING;So;0;L;;;;;N;;;;;
+1D94E;SIGNWRITING TRAVEL-WALLPLANE ROTATION-FLOORPLANE SINGLE;So;0;L;;;;;N;;;;;
+1D94F;SIGNWRITING TRAVEL-WALLPLANE ROTATION-FLOORPLANE DOUBLE;So;0;L;;;;;N;;;;;
+1D950;SIGNWRITING TRAVEL-WALLPLANE ROTATION-FLOORPLANE ALTERNATING;So;0;L;;;;;N;;;;;
+1D951;SIGNWRITING TRAVEL-WALLPLANE SHAKING;So;0;L;;;;;N;;;;;
+1D952;SIGNWRITING TRAVEL-WALLPLANE ARM SPIRAL SINGLE;So;0;L;;;;;N;;;;;
+1D953;SIGNWRITING TRAVEL-WALLPLANE ARM SPIRAL DOUBLE;So;0;L;;;;;N;;;;;
+1D954;SIGNWRITING TRAVEL-WALLPLANE ARM SPIRAL TRIPLE;So;0;L;;;;;N;;;;;
+1D955;SIGNWRITING MOVEMENT-DIAGONAL AWAY SMALL;So;0;L;;;;;N;;;;;
+1D956;SIGNWRITING MOVEMENT-DIAGONAL AWAY MEDIUM;So;0;L;;;;;N;;;;;
+1D957;SIGNWRITING MOVEMENT-DIAGONAL AWAY LARGE;So;0;L;;;;;N;;;;;
+1D958;SIGNWRITING MOVEMENT-DIAGONAL AWAY LARGEST;So;0;L;;;;;N;;;;;
+1D959;SIGNWRITING MOVEMENT-DIAGONAL TOWARDS SMALL;So;0;L;;;;;N;;;;;
+1D95A;SIGNWRITING MOVEMENT-DIAGONAL TOWARDS MEDIUM;So;0;L;;;;;N;;;;;
+1D95B;SIGNWRITING MOVEMENT-DIAGONAL TOWARDS LARGE;So;0;L;;;;;N;;;;;
+1D95C;SIGNWRITING MOVEMENT-DIAGONAL TOWARDS LARGEST;So;0;L;;;;;N;;;;;
+1D95D;SIGNWRITING MOVEMENT-DIAGONAL BETWEEN AWAY SMALL;So;0;L;;;;;N;;;;;
+1D95E;SIGNWRITING MOVEMENT-DIAGONAL BETWEEN AWAY MEDIUM;So;0;L;;;;;N;;;;;
+1D95F;SIGNWRITING MOVEMENT-DIAGONAL BETWEEN AWAY LARGE;So;0;L;;;;;N;;;;;
+1D960;SIGNWRITING MOVEMENT-DIAGONAL BETWEEN AWAY LARGEST;So;0;L;;;;;N;;;;;
+1D961;SIGNWRITING MOVEMENT-DIAGONAL BETWEEN TOWARDS SMALL;So;0;L;;;;;N;;;;;
+1D962;SIGNWRITING MOVEMENT-DIAGONAL BETWEEN TOWARDS MEDIUM;So;0;L;;;;;N;;;;;
+1D963;SIGNWRITING MOVEMENT-DIAGONAL BETWEEN TOWARDS LARGE;So;0;L;;;;;N;;;;;
+1D964;SIGNWRITING MOVEMENT-DIAGONAL BETWEEN TOWARDS LARGEST;So;0;L;;;;;N;;;;;
+1D965;SIGNWRITING MOVEMENT-FLOORPLANE SINGLE STRAIGHT SMALL;So;0;L;;;;;N;;;;;
+1D966;SIGNWRITING MOVEMENT-FLOORPLANE SINGLE STRAIGHT MEDIUM;So;0;L;;;;;N;;;;;
+1D967;SIGNWRITING MOVEMENT-FLOORPLANE SINGLE STRAIGHT LARGE;So;0;L;;;;;N;;;;;
+1D968;SIGNWRITING MOVEMENT-FLOORPLANE SINGLE STRAIGHT LARGEST;So;0;L;;;;;N;;;;;
+1D969;SIGNWRITING MOVEMENT-FLOORPLANE SINGLE WRIST FLEX;So;0;L;;;;;N;;;;;
+1D96A;SIGNWRITING MOVEMENT-FLOORPLANE DOUBLE STRAIGHT;So;0;L;;;;;N;;;;;
+1D96B;SIGNWRITING MOVEMENT-FLOORPLANE DOUBLE WRIST FLEX;So;0;L;;;;;N;;;;;
+1D96C;SIGNWRITING MOVEMENT-FLOORPLANE DOUBLE ALTERNATING;So;0;L;;;;;N;;;;;
+1D96D;SIGNWRITING MOVEMENT-FLOORPLANE DOUBLE ALTERNATING WRIST FLEX;So;0;L;;;;;N;;;;;
+1D96E;SIGNWRITING MOVEMENT-FLOORPLANE CROSS;So;0;L;;;;;N;;;;;
+1D96F;SIGNWRITING MOVEMENT-FLOORPLANE TRIPLE STRAIGHT MOVEMENT;So;0;L;;;;;N;;;;;
+1D970;SIGNWRITING MOVEMENT-FLOORPLANE TRIPLE WRIST FLEX;So;0;L;;;;;N;;;;;
+1D971;SIGNWRITING MOVEMENT-FLOORPLANE TRIPLE ALTERNATING MOVEMENT;So;0;L;;;;;N;;;;;
+1D972;SIGNWRITING MOVEMENT-FLOORPLANE TRIPLE ALTERNATING WRIST FLEX;So;0;L;;;;;N;;;;;
+1D973;SIGNWRITING MOVEMENT-FLOORPLANE BEND;So;0;L;;;;;N;;;;;
+1D974;SIGNWRITING MOVEMENT-FLOORPLANE CORNER SMALL;So;0;L;;;;;N;;;;;
+1D975;SIGNWRITING MOVEMENT-FLOORPLANE CORNER MEDIUM;So;0;L;;;;;N;;;;;
+1D976;SIGNWRITING MOVEMENT-FLOORPLANE CORNER LARGE;So;0;L;;;;;N;;;;;
+1D977;SIGNWRITING MOVEMENT-FLOORPLANE CHECK;So;0;L;;;;;N;;;;;
+1D978;SIGNWRITING MOVEMENT-FLOORPLANE BOX SMALL;So;0;L;;;;;N;;;;;
+1D979;SIGNWRITING MOVEMENT-FLOORPLANE BOX MEDIUM;So;0;L;;;;;N;;;;;
+1D97A;SIGNWRITING MOVEMENT-FLOORPLANE BOX LARGE;So;0;L;;;;;N;;;;;
+1D97B;SIGNWRITING MOVEMENT-FLOORPLANE ZIGZAG SMALL;So;0;L;;;;;N;;;;;
+1D97C;SIGNWRITING MOVEMENT-FLOORPLANE ZIGZAG MEDIUM;So;0;L;;;;;N;;;;;
+1D97D;SIGNWRITING MOVEMENT-FLOORPLANE ZIGZAG LARGE;So;0;L;;;;;N;;;;;
+1D97E;SIGNWRITING MOVEMENT-FLOORPLANE PEAKS SMALL;So;0;L;;;;;N;;;;;
+1D97F;SIGNWRITING MOVEMENT-FLOORPLANE PEAKS MEDIUM;So;0;L;;;;;N;;;;;
+1D980;SIGNWRITING MOVEMENT-FLOORPLANE PEAKS LARGE;So;0;L;;;;;N;;;;;
+1D981;SIGNWRITING TRAVEL-FLOORPLANE ROTATION-FLOORPLANE SINGLE;So;0;L;;;;;N;;;;;
+1D982;SIGNWRITING TRAVEL-FLOORPLANE ROTATION-FLOORPLANE DOUBLE;So;0;L;;;;;N;;;;;
+1D983;SIGNWRITING TRAVEL-FLOORPLANE ROTATION-FLOORPLANE ALTERNATING;So;0;L;;;;;N;;;;;
+1D984;SIGNWRITING TRAVEL-FLOORPLANE ROTATION-WALLPLANE SINGLE;So;0;L;;;;;N;;;;;
+1D985;SIGNWRITING TRAVEL-FLOORPLANE ROTATION-WALLPLANE DOUBLE;So;0;L;;;;;N;;;;;
+1D986;SIGNWRITING TRAVEL-FLOORPLANE ROTATION-WALLPLANE ALTERNATING;So;0;L;;;;;N;;;;;
+1D987;SIGNWRITING TRAVEL-FLOORPLANE SHAKING;So;0;L;;;;;N;;;;;
+1D988;SIGNWRITING MOVEMENT-WALLPLANE CURVE QUARTER SMALL;So;0;L;;;;;N;;;;;
+1D989;SIGNWRITING MOVEMENT-WALLPLANE CURVE QUARTER MEDIUM;So;0;L;;;;;N;;;;;
+1D98A;SIGNWRITING MOVEMENT-WALLPLANE CURVE QUARTER LARGE;So;0;L;;;;;N;;;;;
+1D98B;SIGNWRITING MOVEMENT-WALLPLANE CURVE QUARTER LARGEST;So;0;L;;;;;N;;;;;
+1D98C;SIGNWRITING MOVEMENT-WALLPLANE CURVE HALF-CIRCLE SMALL;So;0;L;;;;;N;;;;;
+1D98D;SIGNWRITING MOVEMENT-WALLPLANE CURVE HALF-CIRCLE MEDIUM;So;0;L;;;;;N;;;;;
+1D98E;SIGNWRITING MOVEMENT-WALLPLANE CURVE HALF-CIRCLE LARGE;So;0;L;;;;;N;;;;;
+1D98F;SIGNWRITING MOVEMENT-WALLPLANE CURVE HALF-CIRCLE LARGEST;So;0;L;;;;;N;;;;;
+1D990;SIGNWRITING MOVEMENT-WALLPLANE CURVE THREE-QUARTER CIRCLE SMALL;So;0;L;;;;;N;;;;;
+1D991;SIGNWRITING MOVEMENT-WALLPLANE CURVE THREE-QUARTER CIRCLE MEDIUM;So;0;L;;;;;N;;;;;
+1D992;SIGNWRITING MOVEMENT-WALLPLANE HUMP SMALL;So;0;L;;;;;N;;;;;
+1D993;SIGNWRITING MOVEMENT-WALLPLANE HUMP MEDIUM;So;0;L;;;;;N;;;;;
+1D994;SIGNWRITING MOVEMENT-WALLPLANE HUMP LARGE;So;0;L;;;;;N;;;;;
+1D995;SIGNWRITING MOVEMENT-WALLPLANE LOOP SMALL;So;0;L;;;;;N;;;;;
+1D996;SIGNWRITING MOVEMENT-WALLPLANE LOOP MEDIUM;So;0;L;;;;;N;;;;;
+1D997;SIGNWRITING MOVEMENT-WALLPLANE LOOP LARGE;So;0;L;;;;;N;;;;;
+1D998;SIGNWRITING MOVEMENT-WALLPLANE LOOP SMALL DOUBLE;So;0;L;;;;;N;;;;;
+1D999;SIGNWRITING MOVEMENT-WALLPLANE WAVE CURVE DOUBLE SMALL;So;0;L;;;;;N;;;;;
+1D99A;SIGNWRITING MOVEMENT-WALLPLANE WAVE CURVE DOUBLE MEDIUM;So;0;L;;;;;N;;;;;
+1D99B;SIGNWRITING MOVEMENT-WALLPLANE WAVE CURVE DOUBLE LARGE;So;0;L;;;;;N;;;;;
+1D99C;SIGNWRITING MOVEMENT-WALLPLANE WAVE CURVE TRIPLE SMALL;So;0;L;;;;;N;;;;;
+1D99D;SIGNWRITING MOVEMENT-WALLPLANE WAVE CURVE TRIPLE MEDIUM;So;0;L;;;;;N;;;;;
+1D99E;SIGNWRITING MOVEMENT-WALLPLANE WAVE CURVE TRIPLE LARGE;So;0;L;;;;;N;;;;;
+1D99F;SIGNWRITING MOVEMENT-WALLPLANE CURVE THEN STRAIGHT;So;0;L;;;;;N;;;;;
+1D9A0;SIGNWRITING MOVEMENT-WALLPLANE CURVED CROSS SMALL;So;0;L;;;;;N;;;;;
+1D9A1;SIGNWRITING MOVEMENT-WALLPLANE CURVED CROSS MEDIUM;So;0;L;;;;;N;;;;;
+1D9A2;SIGNWRITING ROTATION-WALLPLANE SINGLE;So;0;L;;;;;N;;;;;
+1D9A3;SIGNWRITING ROTATION-WALLPLANE DOUBLE;So;0;L;;;;;N;;;;;
+1D9A4;SIGNWRITING ROTATION-WALLPLANE ALTERNATE;So;0;L;;;;;N;;;;;
+1D9A5;SIGNWRITING MOVEMENT-WALLPLANE SHAKING;So;0;L;;;;;N;;;;;
+1D9A6;SIGNWRITING MOVEMENT-WALLPLANE CURVE HITTING FRONT WALL;So;0;L;;;;;N;;;;;
+1D9A7;SIGNWRITING MOVEMENT-WALLPLANE HUMP HITTING FRONT WALL;So;0;L;;;;;N;;;;;
+1D9A8;SIGNWRITING MOVEMENT-WALLPLANE LOOP HITTING FRONT WALL;So;0;L;;;;;N;;;;;
+1D9A9;SIGNWRITING MOVEMENT-WALLPLANE WAVE HITTING FRONT WALL;So;0;L;;;;;N;;;;;
+1D9AA;SIGNWRITING ROTATION-WALLPLANE SINGLE HITTING FRONT WALL;So;0;L;;;;;N;;;;;
+1D9AB;SIGNWRITING ROTATION-WALLPLANE DOUBLE HITTING FRONT WALL;So;0;L;;;;;N;;;;;
+1D9AC;SIGNWRITING ROTATION-WALLPLANE ALTERNATING HITTING FRONT WALL;So;0;L;;;;;N;;;;;
+1D9AD;SIGNWRITING MOVEMENT-WALLPLANE CURVE HITTING CHEST;So;0;L;;;;;N;;;;;
+1D9AE;SIGNWRITING MOVEMENT-WALLPLANE HUMP HITTING CHEST;So;0;L;;;;;N;;;;;
+1D9AF;SIGNWRITING MOVEMENT-WALLPLANE LOOP HITTING CHEST;So;0;L;;;;;N;;;;;
+1D9B0;SIGNWRITING MOVEMENT-WALLPLANE WAVE HITTING CHEST;So;0;L;;;;;N;;;;;
+1D9B1;SIGNWRITING ROTATION-WALLPLANE SINGLE HITTING CHEST;So;0;L;;;;;N;;;;;
+1D9B2;SIGNWRITING ROTATION-WALLPLANE DOUBLE HITTING CHEST;So;0;L;;;;;N;;;;;
+1D9B3;SIGNWRITING ROTATION-WALLPLANE ALTERNATING HITTING CHEST;So;0;L;;;;;N;;;;;
+1D9B4;SIGNWRITING MOVEMENT-WALLPLANE WAVE DIAGONAL PATH SMALL;So;0;L;;;;;N;;;;;
+1D9B5;SIGNWRITING MOVEMENT-WALLPLANE WAVE DIAGONAL PATH MEDIUM;So;0;L;;;;;N;;;;;
+1D9B6;SIGNWRITING MOVEMENT-WALLPLANE WAVE DIAGONAL PATH LARGE;So;0;L;;;;;N;;;;;
+1D9B7;SIGNWRITING MOVEMENT-FLOORPLANE CURVE HITTING CEILING SMALL;So;0;L;;;;;N;;;;;
+1D9B8;SIGNWRITING MOVEMENT-FLOORPLANE CURVE HITTING CEILING LARGE;So;0;L;;;;;N;;;;;
+1D9B9;SIGNWRITING MOVEMENT-FLOORPLANE HUMP HITTING CEILING SMALL DOUBLE;So;0;L;;;;;N;;;;;
+1D9BA;SIGNWRITING MOVEMENT-FLOORPLANE HUMP HITTING CEILING LARGE DOUBLE;So;0;L;;;;;N;;;;;
+1D9BB;SIGNWRITING MOVEMENT-FLOORPLANE HUMP HITTING CEILING SMALL TRIPLE;So;0;L;;;;;N;;;;;
+1D9BC;SIGNWRITING MOVEMENT-FLOORPLANE HUMP HITTING CEILING LARGE TRIPLE;So;0;L;;;;;N;;;;;
+1D9BD;SIGNWRITING MOVEMENT-FLOORPLANE LOOP HITTING CEILING SMALL SINGLE;So;0;L;;;;;N;;;;;
+1D9BE;SIGNWRITING MOVEMENT-FLOORPLANE LOOP HITTING CEILING LARGE SINGLE;So;0;L;;;;;N;;;;;
+1D9BF;SIGNWRITING MOVEMENT-FLOORPLANE LOOP HITTING CEILING SMALL DOUBLE;So;0;L;;;;;N;;;;;
+1D9C0;SIGNWRITING MOVEMENT-FLOORPLANE LOOP HITTING CEILING LARGE DOUBLE;So;0;L;;;;;N;;;;;
+1D9C1;SIGNWRITING MOVEMENT-FLOORPLANE WAVE HITTING CEILING SMALL;So;0;L;;;;;N;;;;;
+1D9C2;SIGNWRITING MOVEMENT-FLOORPLANE WAVE HITTING CEILING LARGE;So;0;L;;;;;N;;;;;
+1D9C3;SIGNWRITING ROTATION-FLOORPLANE SINGLE HITTING CEILING;So;0;L;;;;;N;;;;;
+1D9C4;SIGNWRITING ROTATION-FLOORPLANE DOUBLE HITTING CEILING;So;0;L;;;;;N;;;;;
+1D9C5;SIGNWRITING ROTATION-FLOORPLANE ALTERNATING HITTING CEILING;So;0;L;;;;;N;;;;;
+1D9C6;SIGNWRITING MOVEMENT-FLOORPLANE CURVE HITTING FLOOR SMALL;So;0;L;;;;;N;;;;;
+1D9C7;SIGNWRITING MOVEMENT-FLOORPLANE CURVE HITTING FLOOR LARGE;So;0;L;;;;;N;;;;;
+1D9C8;SIGNWRITING MOVEMENT-FLOORPLANE HUMP HITTING FLOOR SMALL DOUBLE;So;0;L;;;;;N;;;;;
+1D9C9;SIGNWRITING MOVEMENT-FLOORPLANE HUMP HITTING FLOOR LARGE DOUBLE;So;0;L;;;;;N;;;;;
+1D9CA;SIGNWRITING MOVEMENT-FLOORPLANE HUMP HITTING FLOOR TRIPLE SMALL TRIPLE;So;0;L;;;;;N;;;;;
+1D9CB;SIGNWRITING MOVEMENT-FLOORPLANE HUMP HITTING FLOOR TRIPLE LARGE TRIPLE;So;0;L;;;;;N;;;;;
+1D9CC;SIGNWRITING MOVEMENT-FLOORPLANE LOOP HITTING FLOOR SMALL SINGLE;So;0;L;;;;;N;;;;;
+1D9CD;SIGNWRITING MOVEMENT-FLOORPLANE LOOP HITTING FLOOR LARGE SINGLE;So;0;L;;;;;N;;;;;
+1D9CE;SIGNWRITING MOVEMENT-FLOORPLANE LOOP HITTING FLOOR SMALL DOUBLE;So;0;L;;;;;N;;;;;
+1D9CF;SIGNWRITING MOVEMENT-FLOORPLANE LOOP HITTING FLOOR LARGE DOUBLE;So;0;L;;;;;N;;;;;
+1D9D0;SIGNWRITING MOVEMENT-FLOORPLANE WAVE HITTING FLOOR SMALL;So;0;L;;;;;N;;;;;
+1D9D1;SIGNWRITING MOVEMENT-FLOORPLANE WAVE HITTING FLOOR LARGE;So;0;L;;;;;N;;;;;
+1D9D2;SIGNWRITING ROTATION-FLOORPLANE SINGLE HITTING FLOOR;So;0;L;;;;;N;;;;;
+1D9D3;SIGNWRITING ROTATION-FLOORPLANE DOUBLE HITTING FLOOR;So;0;L;;;;;N;;;;;
+1D9D4;SIGNWRITING ROTATION-FLOORPLANE ALTERNATING HITTING FLOOR;So;0;L;;;;;N;;;;;
+1D9D5;SIGNWRITING MOVEMENT-FLOORPLANE CURVE SMALL;So;0;L;;;;;N;;;;;
+1D9D6;SIGNWRITING MOVEMENT-FLOORPLANE CURVE MEDIUM;So;0;L;;;;;N;;;;;
+1D9D7;SIGNWRITING MOVEMENT-FLOORPLANE CURVE LARGE;So;0;L;;;;;N;;;;;
+1D9D8;SIGNWRITING MOVEMENT-FLOORPLANE CURVE LARGEST;So;0;L;;;;;N;;;;;
+1D9D9;SIGNWRITING MOVEMENT-FLOORPLANE CURVE COMBINED;So;0;L;;;;;N;;;;;
+1D9DA;SIGNWRITING MOVEMENT-FLOORPLANE HUMP SMALL;So;0;L;;;;;N;;;;;
+1D9DB;SIGNWRITING MOVEMENT-FLOORPLANE LOOP SMALL;So;0;L;;;;;N;;;;;
+1D9DC;SIGNWRITING MOVEMENT-FLOORPLANE WAVE SNAKE;So;0;L;;;;;N;;;;;
+1D9DD;SIGNWRITING MOVEMENT-FLOORPLANE WAVE SMALL;So;0;L;;;;;N;;;;;
+1D9DE;SIGNWRITING MOVEMENT-FLOORPLANE WAVE LARGE;So;0;L;;;;;N;;;;;
+1D9DF;SIGNWRITING ROTATION-FLOORPLANE SINGLE;So;0;L;;;;;N;;;;;
+1D9E0;SIGNWRITING ROTATION-FLOORPLANE DOUBLE;So;0;L;;;;;N;;;;;
+1D9E1;SIGNWRITING ROTATION-FLOORPLANE ALTERNATING;So;0;L;;;;;N;;;;;
+1D9E2;SIGNWRITING MOVEMENT-FLOORPLANE SHAKING PARALLEL;So;0;L;;;;;N;;;;;
+1D9E3;SIGNWRITING MOVEMENT-WALLPLANE ARM CIRCLE SMALL SINGLE;So;0;L;;;;;N;;;;;
+1D9E4;SIGNWRITING MOVEMENT-WALLPLANE ARM CIRCLE MEDIUM SINGLE;So;0;L;;;;;N;;;;;
+1D9E5;SIGNWRITING MOVEMENT-WALLPLANE ARM CIRCLE SMALL DOUBLE;So;0;L;;;;;N;;;;;
+1D9E6;SIGNWRITING MOVEMENT-WALLPLANE ARM CIRCLE MEDIUM DOUBLE;So;0;L;;;;;N;;;;;
+1D9E7;SIGNWRITING MOVEMENT-FLOORPLANE ARM CIRCLE HITTING WALL SMALL SINGLE;So;0;L;;;;;N;;;;;
+1D9E8;SIGNWRITING MOVEMENT-FLOORPLANE ARM CIRCLE HITTING WALL MEDIUM SINGLE;So;0;L;;;;;N;;;;;
+1D9E9;SIGNWRITING MOVEMENT-FLOORPLANE ARM CIRCLE HITTING WALL LARGE SINGLE;So;0;L;;;;;N;;;;;
+1D9EA;SIGNWRITING MOVEMENT-FLOORPLANE ARM CIRCLE HITTING WALL SMALL DOUBLE;So;0;L;;;;;N;;;;;
+1D9EB;SIGNWRITING MOVEMENT-FLOORPLANE ARM CIRCLE HITTING WALL MEDIUM DOUBLE;So;0;L;;;;;N;;;;;
+1D9EC;SIGNWRITING MOVEMENT-FLOORPLANE ARM CIRCLE HITTING WALL LARGE DOUBLE;So;0;L;;;;;N;;;;;
+1D9ED;SIGNWRITING MOVEMENT-WALLPLANE WRIST CIRCLE FRONT SINGLE;So;0;L;;;;;N;;;;;
+1D9EE;SIGNWRITING MOVEMENT-WALLPLANE WRIST CIRCLE FRONT DOUBLE;So;0;L;;;;;N;;;;;
+1D9EF;SIGNWRITING MOVEMENT-FLOORPLANE WRIST CIRCLE HITTING WALL SINGLE;So;0;L;;;;;N;;;;;
+1D9F0;SIGNWRITING MOVEMENT-FLOORPLANE WRIST CIRCLE HITTING WALL DOUBLE;So;0;L;;;;;N;;;;;
+1D9F1;SIGNWRITING MOVEMENT-WALLPLANE FINGER CIRCLES SINGLE;So;0;L;;;;;N;;;;;
+1D9F2;SIGNWRITING MOVEMENT-WALLPLANE FINGER CIRCLES DOUBLE;So;0;L;;;;;N;;;;;
+1D9F3;SIGNWRITING MOVEMENT-FLOORPLANE FINGER CIRCLES HITTING WALL SINGLE;So;0;L;;;;;N;;;;;
+1D9F4;SIGNWRITING MOVEMENT-FLOORPLANE FINGER CIRCLES HITTING WALL DOUBLE;So;0;L;;;;;N;;;;;
+1D9F5;SIGNWRITING DYNAMIC ARROWHEAD SMALL;So;0;L;;;;;N;;;;;
+1D9F6;SIGNWRITING DYNAMIC ARROWHEAD LARGE;So;0;L;;;;;N;;;;;
+1D9F7;SIGNWRITING DYNAMIC FAST;So;0;L;;;;;N;;;;;
+1D9F8;SIGNWRITING DYNAMIC SLOW;So;0;L;;;;;N;;;;;
+1D9F9;SIGNWRITING DYNAMIC TENSE;So;0;L;;;;;N;;;;;
+1D9FA;SIGNWRITING DYNAMIC RELAXED;So;0;L;;;;;N;;;;;
+1D9FB;SIGNWRITING DYNAMIC SIMULTANEOUS;So;0;L;;;;;N;;;;;
+1D9FC;SIGNWRITING DYNAMIC SIMULTANEOUS ALTERNATING;So;0;L;;;;;N;;;;;
+1D9FD;SIGNWRITING DYNAMIC EVERY OTHER TIME;So;0;L;;;;;N;;;;;
+1D9FE;SIGNWRITING DYNAMIC GRADUAL;So;0;L;;;;;N;;;;;
+1D9FF;SIGNWRITING HEAD;So;0;L;;;;;N;;;;;
+1DA00;SIGNWRITING HEAD RIM;Mn;0;NSM;;;;;N;;;;;
+1DA01;SIGNWRITING HEAD MOVEMENT-WALLPLANE STRAIGHT;Mn;0;NSM;;;;;N;;;;;
+1DA02;SIGNWRITING HEAD MOVEMENT-WALLPLANE TILT;Mn;0;NSM;;;;;N;;;;;
+1DA03;SIGNWRITING HEAD MOVEMENT-FLOORPLANE STRAIGHT;Mn;0;NSM;;;;;N;;;;;
+1DA04;SIGNWRITING HEAD MOVEMENT-WALLPLANE CURVE;Mn;0;NSM;;;;;N;;;;;
+1DA05;SIGNWRITING HEAD MOVEMENT-FLOORPLANE CURVE;Mn;0;NSM;;;;;N;;;;;
+1DA06;SIGNWRITING HEAD MOVEMENT CIRCLE;Mn;0;NSM;;;;;N;;;;;
+1DA07;SIGNWRITING FACE DIRECTION POSITION NOSE FORWARD TILTING;Mn;0;NSM;;;;;N;;;;;
+1DA08;SIGNWRITING FACE DIRECTION POSITION NOSE UP OR DOWN;Mn;0;NSM;;;;;N;;;;;
+1DA09;SIGNWRITING FACE DIRECTION POSITION NOSE UP OR DOWN TILTING;Mn;0;NSM;;;;;N;;;;;
+1DA0A;SIGNWRITING EYEBROWS STRAIGHT UP;Mn;0;NSM;;;;;N;;;;;
+1DA0B;SIGNWRITING EYEBROWS STRAIGHT NEUTRAL;Mn;0;NSM;;;;;N;;;;;
+1DA0C;SIGNWRITING EYEBROWS STRAIGHT DOWN;Mn;0;NSM;;;;;N;;;;;
+1DA0D;SIGNWRITING DREAMY EYEBROWS NEUTRAL DOWN;Mn;0;NSM;;;;;N;;;;;
+1DA0E;SIGNWRITING DREAMY EYEBROWS DOWN NEUTRAL;Mn;0;NSM;;;;;N;;;;;
+1DA0F;SIGNWRITING DREAMY EYEBROWS UP NEUTRAL;Mn;0;NSM;;;;;N;;;;;
+1DA10;SIGNWRITING DREAMY EYEBROWS NEUTRAL UP;Mn;0;NSM;;;;;N;;;;;
+1DA11;SIGNWRITING FOREHEAD NEUTRAL;Mn;0;NSM;;;;;N;;;;;
+1DA12;SIGNWRITING FOREHEAD CONTACT;Mn;0;NSM;;;;;N;;;;;
+1DA13;SIGNWRITING FOREHEAD WRINKLED;Mn;0;NSM;;;;;N;;;;;
+1DA14;SIGNWRITING EYES OPEN;Mn;0;NSM;;;;;N;;;;;
+1DA15;SIGNWRITING EYES SQUEEZED;Mn;0;NSM;;;;;N;;;;;
+1DA16;SIGNWRITING EYES CLOSED;Mn;0;NSM;;;;;N;;;;;
+1DA17;SIGNWRITING EYE BLINK SINGLE;Mn;0;NSM;;;;;N;;;;;
+1DA18;SIGNWRITING EYE BLINK MULTIPLE;Mn;0;NSM;;;;;N;;;;;
+1DA19;SIGNWRITING EYES HALF OPEN;Mn;0;NSM;;;;;N;;;;;
+1DA1A;SIGNWRITING EYES WIDE OPEN;Mn;0;NSM;;;;;N;;;;;
+1DA1B;SIGNWRITING EYES HALF CLOSED;Mn;0;NSM;;;;;N;;;;;
+1DA1C;SIGNWRITING EYES WIDENING MOVEMENT;Mn;0;NSM;;;;;N;;;;;
+1DA1D;SIGNWRITING EYE WINK;Mn;0;NSM;;;;;N;;;;;
+1DA1E;SIGNWRITING EYELASHES UP;Mn;0;NSM;;;;;N;;;;;
+1DA1F;SIGNWRITING EYELASHES DOWN;Mn;0;NSM;;;;;N;;;;;
+1DA20;SIGNWRITING EYELASHES FLUTTERING;Mn;0;NSM;;;;;N;;;;;
+1DA21;SIGNWRITING EYEGAZE-WALLPLANE STRAIGHT;Mn;0;NSM;;;;;N;;;;;
+1DA22;SIGNWRITING EYEGAZE-WALLPLANE STRAIGHT DOUBLE;Mn;0;NSM;;;;;N;;;;;
+1DA23;SIGNWRITING EYEGAZE-WALLPLANE STRAIGHT ALTERNATING;Mn;0;NSM;;;;;N;;;;;
+1DA24;SIGNWRITING EYEGAZE-FLOORPLANE STRAIGHT;Mn;0;NSM;;;;;N;;;;;
+1DA25;SIGNWRITING EYEGAZE-FLOORPLANE STRAIGHT DOUBLE;Mn;0;NSM;;;;;N;;;;;
+1DA26;SIGNWRITING EYEGAZE-FLOORPLANE STRAIGHT ALTERNATING;Mn;0;NSM;;;;;N;;;;;
+1DA27;SIGNWRITING EYEGAZE-WALLPLANE CURVED;Mn;0;NSM;;;;;N;;;;;
+1DA28;SIGNWRITING EYEGAZE-FLOORPLANE CURVED;Mn;0;NSM;;;;;N;;;;;
+1DA29;SIGNWRITING EYEGAZE-WALLPLANE CIRCLING;Mn;0;NSM;;;;;N;;;;;
+1DA2A;SIGNWRITING CHEEKS PUFFED;Mn;0;NSM;;;;;N;;;;;
+1DA2B;SIGNWRITING CHEEKS NEUTRAL;Mn;0;NSM;;;;;N;;;;;
+1DA2C;SIGNWRITING CHEEKS SUCKED;Mn;0;NSM;;;;;N;;;;;
+1DA2D;SIGNWRITING TENSE CHEEKS HIGH;Mn;0;NSM;;;;;N;;;;;
+1DA2E;SIGNWRITING TENSE CHEEKS MIDDLE;Mn;0;NSM;;;;;N;;;;;
+1DA2F;SIGNWRITING TENSE CHEEKS LOW;Mn;0;NSM;;;;;N;;;;;
+1DA30;SIGNWRITING EARS;Mn;0;NSM;;;;;N;;;;;
+1DA31;SIGNWRITING NOSE NEUTRAL;Mn;0;NSM;;;;;N;;;;;
+1DA32;SIGNWRITING NOSE CONTACT;Mn;0;NSM;;;;;N;;;;;
+1DA33;SIGNWRITING NOSE WRINKLES;Mn;0;NSM;;;;;N;;;;;
+1DA34;SIGNWRITING NOSE WIGGLES;Mn;0;NSM;;;;;N;;;;;
+1DA35;SIGNWRITING AIR BLOWING OUT;Mn;0;NSM;;;;;N;;;;;
+1DA36;SIGNWRITING AIR SUCKING IN;Mn;0;NSM;;;;;N;;;;;
+1DA37;SIGNWRITING AIR BLOW SMALL ROTATIONS;So;0;L;;;;;N;;;;;
+1DA38;SIGNWRITING AIR SUCK SMALL ROTATIONS;So;0;L;;;;;N;;;;;
+1DA39;SIGNWRITING BREATH INHALE;So;0;L;;;;;N;;;;;
+1DA3A;SIGNWRITING BREATH EXHALE;So;0;L;;;;;N;;;;;
+1DA3B;SIGNWRITING MOUTH CLOSED NEUTRAL;Mn;0;NSM;;;;;N;;;;;
+1DA3C;SIGNWRITING MOUTH CLOSED FORWARD;Mn;0;NSM;;;;;N;;;;;
+1DA3D;SIGNWRITING MOUTH CLOSED CONTACT;Mn;0;NSM;;;;;N;;;;;
+1DA3E;SIGNWRITING MOUTH SMILE;Mn;0;NSM;;;;;N;;;;;
+1DA3F;SIGNWRITING MOUTH SMILE WRINKLED;Mn;0;NSM;;;;;N;;;;;
+1DA40;SIGNWRITING MOUTH SMILE OPEN;Mn;0;NSM;;;;;N;;;;;
+1DA41;SIGNWRITING MOUTH FROWN;Mn;0;NSM;;;;;N;;;;;
+1DA42;SIGNWRITING MOUTH FROWN WRINKLED;Mn;0;NSM;;;;;N;;;;;
+1DA43;SIGNWRITING MOUTH FROWN OPEN;Mn;0;NSM;;;;;N;;;;;
+1DA44;SIGNWRITING MOUTH OPEN CIRCLE;Mn;0;NSM;;;;;N;;;;;
+1DA45;SIGNWRITING MOUTH OPEN FORWARD;Mn;0;NSM;;;;;N;;;;;
+1DA46;SIGNWRITING MOUTH OPEN WRINKLED;Mn;0;NSM;;;;;N;;;;;
+1DA47;SIGNWRITING MOUTH OPEN OVAL;Mn;0;NSM;;;;;N;;;;;
+1DA48;SIGNWRITING MOUTH OPEN OVAL WRINKLED;Mn;0;NSM;;;;;N;;;;;
+1DA49;SIGNWRITING MOUTH OPEN OVAL YAWN;Mn;0;NSM;;;;;N;;;;;
+1DA4A;SIGNWRITING MOUTH OPEN RECTANGLE;Mn;0;NSM;;;;;N;;;;;
+1DA4B;SIGNWRITING MOUTH OPEN RECTANGLE WRINKLED;Mn;0;NSM;;;;;N;;;;;
+1DA4C;SIGNWRITING MOUTH OPEN RECTANGLE YAWN;Mn;0;NSM;;;;;N;;;;;
+1DA4D;SIGNWRITING MOUTH KISS;Mn;0;NSM;;;;;N;;;;;
+1DA4E;SIGNWRITING MOUTH KISS FORWARD;Mn;0;NSM;;;;;N;;;;;
+1DA4F;SIGNWRITING MOUTH KISS WRINKLED;Mn;0;NSM;;;;;N;;;;;
+1DA50;SIGNWRITING MOUTH TENSE;Mn;0;NSM;;;;;N;;;;;
+1DA51;SIGNWRITING MOUTH TENSE FORWARD;Mn;0;NSM;;;;;N;;;;;
+1DA52;SIGNWRITING MOUTH TENSE SUCKED;Mn;0;NSM;;;;;N;;;;;
+1DA53;SIGNWRITING LIPS PRESSED TOGETHER;Mn;0;NSM;;;;;N;;;;;
+1DA54;SIGNWRITING LIP LOWER OVER UPPER;Mn;0;NSM;;;;;N;;;;;
+1DA55;SIGNWRITING LIP UPPER OVER LOWER;Mn;0;NSM;;;;;N;;;;;
+1DA56;SIGNWRITING MOUTH CORNERS;Mn;0;NSM;;;;;N;;;;;
+1DA57;SIGNWRITING MOUTH WRINKLES SINGLE;Mn;0;NSM;;;;;N;;;;;
+1DA58;SIGNWRITING MOUTH WRINKLES DOUBLE;Mn;0;NSM;;;;;N;;;;;
+1DA59;SIGNWRITING TONGUE STICKING OUT FAR;Mn;0;NSM;;;;;N;;;;;
+1DA5A;SIGNWRITING TONGUE LICKING LIPS;Mn;0;NSM;;;;;N;;;;;
+1DA5B;SIGNWRITING TONGUE TIP BETWEEN LIPS;Mn;0;NSM;;;;;N;;;;;
+1DA5C;SIGNWRITING TONGUE TIP TOUCHING INSIDE MOUTH;Mn;0;NSM;;;;;N;;;;;
+1DA5D;SIGNWRITING TONGUE INSIDE MOUTH RELAXED;Mn;0;NSM;;;;;N;;;;;
+1DA5E;SIGNWRITING TONGUE MOVES AGAINST CHEEK;Mn;0;NSM;;;;;N;;;;;
+1DA5F;SIGNWRITING TONGUE CENTRE STICKING OUT;Mn;0;NSM;;;;;N;;;;;
+1DA60;SIGNWRITING TONGUE CENTRE INSIDE MOUTH;Mn;0;NSM;;;;;N;;;;;
+1DA61;SIGNWRITING TEETH;Mn;0;NSM;;;;;N;;;;;
+1DA62;SIGNWRITING TEETH MOVEMENT;Mn;0;NSM;;;;;N;;;;;
+1DA63;SIGNWRITING TEETH ON TONGUE;Mn;0;NSM;;;;;N;;;;;
+1DA64;SIGNWRITING TEETH ON TONGUE MOVEMENT;Mn;0;NSM;;;;;N;;;;;
+1DA65;SIGNWRITING TEETH ON LIPS;Mn;0;NSM;;;;;N;;;;;
+1DA66;SIGNWRITING TEETH ON LIPS MOVEMENT;Mn;0;NSM;;;;;N;;;;;
+1DA67;SIGNWRITING TEETH BITE LIPS;Mn;0;NSM;;;;;N;;;;;
+1DA68;SIGNWRITING MOVEMENT-WALLPLANE JAW;Mn;0;NSM;;;;;N;;;;;
+1DA69;SIGNWRITING MOVEMENT-FLOORPLANE JAW;Mn;0;NSM;;;;;N;;;;;
+1DA6A;SIGNWRITING NECK;Mn;0;NSM;;;;;N;;;;;
+1DA6B;SIGNWRITING HAIR;Mn;0;NSM;;;;;N;;;;;
+1DA6C;SIGNWRITING EXCITEMENT;Mn;0;NSM;;;;;N;;;;;
+1DA6D;SIGNWRITING SHOULDER HIP SPINE;So;0;L;;;;;N;;;;;
+1DA6E;SIGNWRITING SHOULDER HIP POSITIONS;So;0;L;;;;;N;;;;;
+1DA6F;SIGNWRITING WALLPLANE SHOULDER HIP MOVE;So;0;L;;;;;N;;;;;
+1DA70;SIGNWRITING FLOORPLANE SHOULDER HIP MOVE;So;0;L;;;;;N;;;;;
+1DA71;SIGNWRITING SHOULDER TILTING FROM WAIST;So;0;L;;;;;N;;;;;
+1DA72;SIGNWRITING TORSO-WALLPLANE STRAIGHT STRETCH;So;0;L;;;;;N;;;;;
+1DA73;SIGNWRITING TORSO-WALLPLANE CURVED BEND;So;0;L;;;;;N;;;;;
+1DA74;SIGNWRITING TORSO-FLOORPLANE TWISTING;So;0;L;;;;;N;;;;;
+1DA75;SIGNWRITING UPPER BODY TILTING FROM HIP JOINTS;Mn;0;NSM;;;;;N;;;;;
+1DA76;SIGNWRITING LIMB COMBINATION;So;0;L;;;;;N;;;;;
+1DA77;SIGNWRITING LIMB LENGTH-1;So;0;L;;;;;N;;;;;
+1DA78;SIGNWRITING LIMB LENGTH-2;So;0;L;;;;;N;;;;;
+1DA79;SIGNWRITING LIMB LENGTH-3;So;0;L;;;;;N;;;;;
+1DA7A;SIGNWRITING LIMB LENGTH-4;So;0;L;;;;;N;;;;;
+1DA7B;SIGNWRITING LIMB LENGTH-5;So;0;L;;;;;N;;;;;
+1DA7C;SIGNWRITING LIMB LENGTH-6;So;0;L;;;;;N;;;;;
+1DA7D;SIGNWRITING LIMB LENGTH-7;So;0;L;;;;;N;;;;;
+1DA7E;SIGNWRITING FINGER;So;0;L;;;;;N;;;;;
+1DA7F;SIGNWRITING LOCATION-WALLPLANE SPACE;So;0;L;;;;;N;;;;;
+1DA80;SIGNWRITING LOCATION-FLOORPLANE SPACE;So;0;L;;;;;N;;;;;
+1DA81;SIGNWRITING LOCATION HEIGHT;So;0;L;;;;;N;;;;;
+1DA82;SIGNWRITING LOCATION WIDTH;So;0;L;;;;;N;;;;;
+1DA83;SIGNWRITING LOCATION DEPTH;So;0;L;;;;;N;;;;;
+1DA84;SIGNWRITING LOCATION HEAD NECK;Mn;0;NSM;;;;;N;;;;;
+1DA85;SIGNWRITING LOCATION TORSO;So;0;L;;;;;N;;;;;
+1DA86;SIGNWRITING LOCATION LIMBS DIGITS;So;0;L;;;;;N;;;;;
+1DA87;SIGNWRITING COMMA;Po;0;L;;;;;N;;;;;
+1DA88;SIGNWRITING FULL STOP;Po;0;L;;;;;N;;;;;
+1DA89;SIGNWRITING SEMICOLON;Po;0;L;;;;;N;;;;;
+1DA8A;SIGNWRITING COLON;Po;0;L;;;;;N;;;;;
+1DA8B;SIGNWRITING PARENTHESIS;Po;0;L;;;;;N;;;;;
+1DA9B;SIGNWRITING FILL MODIFIER-2;Mn;0;NSM;;;;;N;;;;;
+1DA9C;SIGNWRITING FILL MODIFIER-3;Mn;0;NSM;;;;;N;;;;;
+1DA9D;SIGNWRITING FILL MODIFIER-4;Mn;0;NSM;;;;;N;;;;;
+1DA9E;SIGNWRITING FILL MODIFIER-5;Mn;0;NSM;;;;;N;;;;;
+1DA9F;SIGNWRITING FILL MODIFIER-6;Mn;0;NSM;;;;;N;;;;;
+1DAA1;SIGNWRITING ROTATION MODIFIER-2;Mn;0;NSM;;;;;N;;;;;
+1DAA2;SIGNWRITING ROTATION MODIFIER-3;Mn;0;NSM;;;;;N;;;;;
+1DAA3;SIGNWRITING ROTATION MODIFIER-4;Mn;0;NSM;;;;;N;;;;;
+1DAA4;SIGNWRITING ROTATION MODIFIER-5;Mn;0;NSM;;;;;N;;;;;
+1DAA5;SIGNWRITING ROTATION MODIFIER-6;Mn;0;NSM;;;;;N;;;;;
+1DAA6;SIGNWRITING ROTATION MODIFIER-7;Mn;0;NSM;;;;;N;;;;;
+1DAA7;SIGNWRITING ROTATION MODIFIER-8;Mn;0;NSM;;;;;N;;;;;
+1DAA8;SIGNWRITING ROTATION MODIFIER-9;Mn;0;NSM;;;;;N;;;;;
+1DAA9;SIGNWRITING ROTATION MODIFIER-10;Mn;0;NSM;;;;;N;;;;;
+1DAAA;SIGNWRITING ROTATION MODIFIER-11;Mn;0;NSM;;;;;N;;;;;
+1DAAB;SIGNWRITING ROTATION MODIFIER-12;Mn;0;NSM;;;;;N;;;;;
+1DAAC;SIGNWRITING ROTATION MODIFIER-13;Mn;0;NSM;;;;;N;;;;;
+1DAAD;SIGNWRITING ROTATION MODIFIER-14;Mn;0;NSM;;;;;N;;;;;
+1DAAE;SIGNWRITING ROTATION MODIFIER-15;Mn;0;NSM;;;;;N;;;;;
+1DAAF;SIGNWRITING ROTATION MODIFIER-16;Mn;0;NSM;;;;;N;;;;;
+1E000;COMBINING GLAGOLITIC LETTER AZU;Mn;230;NSM;;;;;N;;;;;
+1E001;COMBINING GLAGOLITIC LETTER BUKY;Mn;230;NSM;;;;;N;;;;;
+1E002;COMBINING GLAGOLITIC LETTER VEDE;Mn;230;NSM;;;;;N;;;;;
+1E003;COMBINING GLAGOLITIC LETTER GLAGOLI;Mn;230;NSM;;;;;N;;;;;
+1E004;COMBINING GLAGOLITIC LETTER DOBRO;Mn;230;NSM;;;;;N;;;;;
+1E005;COMBINING GLAGOLITIC LETTER YESTU;Mn;230;NSM;;;;;N;;;;;
+1E006;COMBINING GLAGOLITIC LETTER ZHIVETE;Mn;230;NSM;;;;;N;;;;;
+1E008;COMBINING GLAGOLITIC LETTER ZEMLJA;Mn;230;NSM;;;;;N;;;;;
+1E009;COMBINING GLAGOLITIC LETTER IZHE;Mn;230;NSM;;;;;N;;;;;
+1E00A;COMBINING GLAGOLITIC LETTER INITIAL IZHE;Mn;230;NSM;;;;;N;;;;;
+1E00B;COMBINING GLAGOLITIC LETTER I;Mn;230;NSM;;;;;N;;;;;
+1E00C;COMBINING GLAGOLITIC LETTER DJERVI;Mn;230;NSM;;;;;N;;;;;
+1E00D;COMBINING GLAGOLITIC LETTER KAKO;Mn;230;NSM;;;;;N;;;;;
+1E00E;COMBINING GLAGOLITIC LETTER LJUDIJE;Mn;230;NSM;;;;;N;;;;;
+1E00F;COMBINING GLAGOLITIC LETTER MYSLITE;Mn;230;NSM;;;;;N;;;;;
+1E010;COMBINING GLAGOLITIC LETTER NASHI;Mn;230;NSM;;;;;N;;;;;
+1E011;COMBINING GLAGOLITIC LETTER ONU;Mn;230;NSM;;;;;N;;;;;
+1E012;COMBINING GLAGOLITIC LETTER POKOJI;Mn;230;NSM;;;;;N;;;;;
+1E013;COMBINING GLAGOLITIC LETTER RITSI;Mn;230;NSM;;;;;N;;;;;
+1E014;COMBINING GLAGOLITIC LETTER SLOVO;Mn;230;NSM;;;;;N;;;;;
+1E015;COMBINING GLAGOLITIC LETTER TVRIDO;Mn;230;NSM;;;;;N;;;;;
+1E016;COMBINING GLAGOLITIC LETTER UKU;Mn;230;NSM;;;;;N;;;;;
+1E017;COMBINING GLAGOLITIC LETTER FRITU;Mn;230;NSM;;;;;N;;;;;
+1E018;COMBINING GLAGOLITIC LETTER HERU;Mn;230;NSM;;;;;N;;;;;
+1E01B;COMBINING GLAGOLITIC LETTER SHTA;Mn;230;NSM;;;;;N;;;;;
+1E01C;COMBINING GLAGOLITIC LETTER TSI;Mn;230;NSM;;;;;N;;;;;
+1E01D;COMBINING GLAGOLITIC LETTER CHRIVI;Mn;230;NSM;;;;;N;;;;;
+1E01E;COMBINING GLAGOLITIC LETTER SHA;Mn;230;NSM;;;;;N;;;;;
+1E01F;COMBINING GLAGOLITIC LETTER YERU;Mn;230;NSM;;;;;N;;;;;
+1E020;COMBINING GLAGOLITIC LETTER YERI;Mn;230;NSM;;;;;N;;;;;
+1E021;COMBINING GLAGOLITIC LETTER YATI;Mn;230;NSM;;;;;N;;;;;
+1E023;COMBINING GLAGOLITIC LETTER YU;Mn;230;NSM;;;;;N;;;;;
+1E024;COMBINING GLAGOLITIC LETTER SMALL YUS;Mn;230;NSM;;;;;N;;;;;
+1E026;COMBINING GLAGOLITIC LETTER YO;Mn;230;NSM;;;;;N;;;;;
+1E027;COMBINING GLAGOLITIC LETTER IOTATED SMALL YUS;Mn;230;NSM;;;;;N;;;;;
+1E028;COMBINING GLAGOLITIC LETTER BIG YUS;Mn;230;NSM;;;;;N;;;;;
+1E029;COMBINING GLAGOLITIC LETTER IOTATED BIG YUS;Mn;230;NSM;;;;;N;;;;;
+1E02A;COMBINING GLAGOLITIC LETTER FITA;Mn;230;NSM;;;;;N;;;;;
+1E800;MENDE KIKAKUI SYLLABLE M001 KI;Lo;0;R;;;;;N;;;;;
+1E801;MENDE KIKAKUI SYLLABLE M002 KA;Lo;0;R;;;;;N;;;;;
+1E802;MENDE KIKAKUI SYLLABLE M003 KU;Lo;0;R;;;;;N;;;;;
+1E803;MENDE KIKAKUI SYLLABLE M065 KEE;Lo;0;R;;;;;N;;;;;
+1E804;MENDE KIKAKUI SYLLABLE M095 KE;Lo;0;R;;;;;N;;;;;
+1E805;MENDE KIKAKUI SYLLABLE M076 KOO;Lo;0;R;;;;;N;;;;;
+1E806;MENDE KIKAKUI SYLLABLE M048 KO;Lo;0;R;;;;;N;;;;;
+1E807;MENDE KIKAKUI SYLLABLE M179 KUA;Lo;0;R;;;;;N;;;;;
+1E808;MENDE KIKAKUI SYLLABLE M004 WI;Lo;0;R;;;;;N;;;;;
+1E809;MENDE KIKAKUI SYLLABLE M005 WA;Lo;0;R;;;;;N;;;;;
+1E80A;MENDE KIKAKUI SYLLABLE M006 WU;Lo;0;R;;;;;N;;;;;
+1E80B;MENDE KIKAKUI SYLLABLE M126 WEE;Lo;0;R;;;;;N;;;;;
+1E80C;MENDE KIKAKUI SYLLABLE M118 WE;Lo;0;R;;;;;N;;;;;
+1E80D;MENDE KIKAKUI SYLLABLE M114 WOO;Lo;0;R;;;;;N;;;;;
+1E80E;MENDE KIKAKUI SYLLABLE M045 WO;Lo;0;R;;;;;N;;;;;
+1E80F;MENDE KIKAKUI SYLLABLE M194 WUI;Lo;0;R;;;;;N;;;;;
+1E810;MENDE KIKAKUI SYLLABLE M143 WEI;Lo;0;R;;;;;N;;;;;
+1E811;MENDE KIKAKUI SYLLABLE M061 WVI;Lo;0;R;;;;;N;;;;;
+1E812;MENDE KIKAKUI SYLLABLE M049 WVA;Lo;0;R;;;;;N;;;;;
+1E813;MENDE KIKAKUI SYLLABLE M139 WVE;Lo;0;R;;;;;N;;;;;
+1E814;MENDE KIKAKUI SYLLABLE M007 MIN;Lo;0;R;;;;;N;;;;;
+1E815;MENDE KIKAKUI SYLLABLE M008 MAN;Lo;0;R;;;;;N;;;;;
+1E816;MENDE KIKAKUI SYLLABLE M009 MUN;Lo;0;R;;;;;N;;;;;
+1E817;MENDE KIKAKUI SYLLABLE M059 MEN;Lo;0;R;;;;;N;;;;;
+1E818;MENDE KIKAKUI SYLLABLE M094 MON;Lo;0;R;;;;;N;;;;;
+1E819;MENDE KIKAKUI SYLLABLE M154 MUAN;Lo;0;R;;;;;N;;;;;
+1E81A;MENDE KIKAKUI SYLLABLE M189 MUEN;Lo;0;R;;;;;N;;;;;
+1E81B;MENDE KIKAKUI SYLLABLE M010 BI;Lo;0;R;;;;;N;;;;;
+1E81C;MENDE KIKAKUI SYLLABLE M011 BA;Lo;0;R;;;;;N;;;;;
+1E81D;MENDE KIKAKUI SYLLABLE M012 BU;Lo;0;R;;;;;N;;;;;
+1E81E;MENDE KIKAKUI SYLLABLE M150 BEE;Lo;0;R;;;;;N;;;;;
+1E81F;MENDE KIKAKUI SYLLABLE M097 BE;Lo;0;R;;;;;N;;;;;
+1E820;MENDE KIKAKUI SYLLABLE M103 BOO;Lo;0;R;;;;;N;;;;;
+1E821;MENDE KIKAKUI SYLLABLE M138 BO;Lo;0;R;;;;;N;;;;;
+1E822;MENDE KIKAKUI SYLLABLE M013 I;Lo;0;R;;;;;N;;;;;
+1E823;MENDE KIKAKUI SYLLABLE M014 A;Lo;0;R;;;;;N;;;;;
+1E824;MENDE KIKAKUI SYLLABLE M015 U;Lo;0;R;;;;;N;;;;;
+1E825;MENDE KIKAKUI SYLLABLE M163 EE;Lo;0;R;;;;;N;;;;;
+1E826;MENDE KIKAKUI SYLLABLE M100 E;Lo;0;R;;;;;N;;;;;
+1E827;MENDE KIKAKUI SYLLABLE M165 OO;Lo;0;R;;;;;N;;;;;
+1E828;MENDE KIKAKUI SYLLABLE M147 O;Lo;0;R;;;;;N;;;;;
+1E829;MENDE KIKAKUI SYLLABLE M137 EI;Lo;0;R;;;;;N;;;;;
+1E82A;MENDE KIKAKUI SYLLABLE M131 IN;Lo;0;R;;;;;N;;;;;
+1E82B;MENDE KIKAKUI SYLLABLE M135 IN;Lo;0;R;;;;;N;;;;;
+1E82C;MENDE KIKAKUI SYLLABLE M195 AN;Lo;0;R;;;;;N;;;;;
+1E82D;MENDE KIKAKUI SYLLABLE M178 EN;Lo;0;R;;;;;N;;;;;
+1E82E;MENDE KIKAKUI SYLLABLE M019 SI;Lo;0;R;;;;;N;;;;;
+1E82F;MENDE KIKAKUI SYLLABLE M020 SA;Lo;0;R;;;;;N;;;;;
+1E830;MENDE KIKAKUI SYLLABLE M021 SU;Lo;0;R;;;;;N;;;;;
+1E831;MENDE KIKAKUI SYLLABLE M162 SEE;Lo;0;R;;;;;N;;;;;
+1E832;MENDE KIKAKUI SYLLABLE M116 SE;Lo;0;R;;;;;N;;;;;
+1E833;MENDE KIKAKUI SYLLABLE M136 SOO;Lo;0;R;;;;;N;;;;;
+1E834;MENDE KIKAKUI SYLLABLE M079 SO;Lo;0;R;;;;;N;;;;;
+1E835;MENDE KIKAKUI SYLLABLE M196 SIA;Lo;0;R;;;;;N;;;;;
+1E836;MENDE KIKAKUI SYLLABLE M025 LI;Lo;0;R;;;;;N;;;;;
+1E837;MENDE KIKAKUI SYLLABLE M026 LA;Lo;0;R;;;;;N;;;;;
+1E838;MENDE KIKAKUI SYLLABLE M027 LU;Lo;0;R;;;;;N;;;;;
+1E839;MENDE KIKAKUI SYLLABLE M084 LEE;Lo;0;R;;;;;N;;;;;
+1E83A;MENDE KIKAKUI SYLLABLE M073 LE;Lo;0;R;;;;;N;;;;;
+1E83B;MENDE KIKAKUI SYLLABLE M054 LOO;Lo;0;R;;;;;N;;;;;
+1E83C;MENDE KIKAKUI SYLLABLE M153 LO;Lo;0;R;;;;;N;;;;;
+1E83D;MENDE KIKAKUI SYLLABLE M110 LONG LE;Lo;0;R;;;;;N;;;;;
+1E83E;MENDE KIKAKUI SYLLABLE M016 DI;Lo;0;R;;;;;N;;;;;
+1E83F;MENDE KIKAKUI SYLLABLE M017 DA;Lo;0;R;;;;;N;;;;;
+1E840;MENDE KIKAKUI SYLLABLE M018 DU;Lo;0;R;;;;;N;;;;;
+1E841;MENDE KIKAKUI SYLLABLE M089 DEE;Lo;0;R;;;;;N;;;;;
+1E842;MENDE KIKAKUI SYLLABLE M180 DOO;Lo;0;R;;;;;N;;;;;
+1E843;MENDE KIKAKUI SYLLABLE M181 DO;Lo;0;R;;;;;N;;;;;
+1E844;MENDE KIKAKUI SYLLABLE M022 TI;Lo;0;R;;;;;N;;;;;
+1E845;MENDE KIKAKUI SYLLABLE M023 TA;Lo;0;R;;;;;N;;;;;
+1E846;MENDE KIKAKUI SYLLABLE M024 TU;Lo;0;R;;;;;N;;;;;
+1E847;MENDE KIKAKUI SYLLABLE M091 TEE;Lo;0;R;;;;;N;;;;;
+1E848;MENDE KIKAKUI SYLLABLE M055 TE;Lo;0;R;;;;;N;;;;;
+1E849;MENDE KIKAKUI SYLLABLE M104 TOO;Lo;0;R;;;;;N;;;;;
+1E84A;MENDE KIKAKUI SYLLABLE M069 TO;Lo;0;R;;;;;N;;;;;
+1E84B;MENDE KIKAKUI SYLLABLE M028 JI;Lo;0;R;;;;;N;;;;;
+1E84C;MENDE KIKAKUI SYLLABLE M029 JA;Lo;0;R;;;;;N;;;;;
+1E84D;MENDE KIKAKUI SYLLABLE M030 JU;Lo;0;R;;;;;N;;;;;
+1E84E;MENDE KIKAKUI SYLLABLE M157 JEE;Lo;0;R;;;;;N;;;;;
+1E84F;MENDE KIKAKUI SYLLABLE M113 JE;Lo;0;R;;;;;N;;;;;
+1E850;MENDE KIKAKUI SYLLABLE M160 JOO;Lo;0;R;;;;;N;;;;;
+1E851;MENDE KIKAKUI SYLLABLE M063 JO;Lo;0;R;;;;;N;;;;;
+1E852;MENDE KIKAKUI SYLLABLE M175 LONG JO;Lo;0;R;;;;;N;;;;;
+1E853;MENDE KIKAKUI SYLLABLE M031 YI;Lo;0;R;;;;;N;;;;;
+1E854;MENDE KIKAKUI SYLLABLE M032 YA;Lo;0;R;;;;;N;;;;;
+1E855;MENDE KIKAKUI SYLLABLE M033 YU;Lo;0;R;;;;;N;;;;;
+1E856;MENDE KIKAKUI SYLLABLE M109 YEE;Lo;0;R;;;;;N;;;;;
+1E857;MENDE KIKAKUI SYLLABLE M080 YE;Lo;0;R;;;;;N;;;;;
+1E858;MENDE KIKAKUI SYLLABLE M141 YOO;Lo;0;R;;;;;N;;;;;
+1E859;MENDE KIKAKUI SYLLABLE M121 YO;Lo;0;R;;;;;N;;;;;
+1E85A;MENDE KIKAKUI SYLLABLE M034 FI;Lo;0;R;;;;;N;;;;;
+1E85B;MENDE KIKAKUI SYLLABLE M035 FA;Lo;0;R;;;;;N;;;;;
+1E85C;MENDE KIKAKUI SYLLABLE M036 FU;Lo;0;R;;;;;N;;;;;
+1E85D;MENDE KIKAKUI SYLLABLE M078 FEE;Lo;0;R;;;;;N;;;;;
+1E85E;MENDE KIKAKUI SYLLABLE M075 FE;Lo;0;R;;;;;N;;;;;
+1E85F;MENDE KIKAKUI SYLLABLE M133 FOO;Lo;0;R;;;;;N;;;;;
+1E860;MENDE KIKAKUI SYLLABLE M088 FO;Lo;0;R;;;;;N;;;;;
+1E861;MENDE KIKAKUI SYLLABLE M197 FUA;Lo;0;R;;;;;N;;;;;
+1E862;MENDE KIKAKUI SYLLABLE M101 FAN;Lo;0;R;;;;;N;;;;;
+1E863;MENDE KIKAKUI SYLLABLE M037 NIN;Lo;0;R;;;;;N;;;;;
+1E864;MENDE KIKAKUI SYLLABLE M038 NAN;Lo;0;R;;;;;N;;;;;
+1E865;MENDE KIKAKUI SYLLABLE M039 NUN;Lo;0;R;;;;;N;;;;;
+1E866;MENDE KIKAKUI SYLLABLE M117 NEN;Lo;0;R;;;;;N;;;;;
+1E867;MENDE KIKAKUI SYLLABLE M169 NON;Lo;0;R;;;;;N;;;;;
+1E868;MENDE KIKAKUI SYLLABLE M176 HI;Lo;0;R;;;;;N;;;;;
+1E869;MENDE KIKAKUI SYLLABLE M041 HA;Lo;0;R;;;;;N;;;;;
+1E86A;MENDE KIKAKUI SYLLABLE M186 HU;Lo;0;R;;;;;N;;;;;
+1E86B;MENDE KIKAKUI SYLLABLE M040 HEE;Lo;0;R;;;;;N;;;;;
+1E86C;MENDE KIKAKUI SYLLABLE M096 HE;Lo;0;R;;;;;N;;;;;
+1E86D;MENDE KIKAKUI SYLLABLE M042 HOO;Lo;0;R;;;;;N;;;;;
+1E86E;MENDE KIKAKUI SYLLABLE M140 HO;Lo;0;R;;;;;N;;;;;
+1E86F;MENDE KIKAKUI SYLLABLE M083 HEEI;Lo;0;R;;;;;N;;;;;
+1E870;MENDE KIKAKUI SYLLABLE M128 HOOU;Lo;0;R;;;;;N;;;;;
+1E871;MENDE KIKAKUI SYLLABLE M053 HIN;Lo;0;R;;;;;N;;;;;
+1E872;MENDE KIKAKUI SYLLABLE M130 HAN;Lo;0;R;;;;;N;;;;;
+1E873;MENDE KIKAKUI SYLLABLE M087 HUN;Lo;0;R;;;;;N;;;;;
+1E874;MENDE KIKAKUI SYLLABLE M052 HEN;Lo;0;R;;;;;N;;;;;
+1E875;MENDE KIKAKUI SYLLABLE M193 HON;Lo;0;R;;;;;N;;;;;
+1E876;MENDE KIKAKUI SYLLABLE M046 HUAN;Lo;0;R;;;;;N;;;;;
+1E877;MENDE KIKAKUI SYLLABLE M090 NGGI;Lo;0;R;;;;;N;;;;;
+1E878;MENDE KIKAKUI SYLLABLE M043 NGGA;Lo;0;R;;;;;N;;;;;
+1E879;MENDE KIKAKUI SYLLABLE M082 NGGU;Lo;0;R;;;;;N;;;;;
+1E87A;MENDE KIKAKUI SYLLABLE M115 NGGEE;Lo;0;R;;;;;N;;;;;
+1E87B;MENDE KIKAKUI SYLLABLE M146 NGGE;Lo;0;R;;;;;N;;;;;
+1E87C;MENDE KIKAKUI SYLLABLE M156 NGGOO;Lo;0;R;;;;;N;;;;;
+1E87D;MENDE KIKAKUI SYLLABLE M120 NGGO;Lo;0;R;;;;;N;;;;;
+1E87E;MENDE KIKAKUI SYLLABLE M159 NGGAA;Lo;0;R;;;;;N;;;;;
+1E87F;MENDE KIKAKUI SYLLABLE M127 NGGUA;Lo;0;R;;;;;N;;;;;
+1E880;MENDE KIKAKUI SYLLABLE M086 LONG NGGE;Lo;0;R;;;;;N;;;;;
+1E881;MENDE KIKAKUI SYLLABLE M106 LONG NGGOO;Lo;0;R;;;;;N;;;;;
+1E882;MENDE KIKAKUI SYLLABLE M183 LONG NGGO;Lo;0;R;;;;;N;;;;;
+1E883;MENDE KIKAKUI SYLLABLE M155 GI;Lo;0;R;;;;;N;;;;;
+1E884;MENDE KIKAKUI SYLLABLE M111 GA;Lo;0;R;;;;;N;;;;;
+1E885;MENDE KIKAKUI SYLLABLE M168 GU;Lo;0;R;;;;;N;;;;;
+1E886;MENDE KIKAKUI SYLLABLE M190 GEE;Lo;0;R;;;;;N;;;;;
+1E887;MENDE KIKAKUI SYLLABLE M166 GUEI;Lo;0;R;;;;;N;;;;;
+1E888;MENDE KIKAKUI SYLLABLE M167 GUAN;Lo;0;R;;;;;N;;;;;
+1E889;MENDE KIKAKUI SYLLABLE M184 NGEN;Lo;0;R;;;;;N;;;;;
+1E88A;MENDE KIKAKUI SYLLABLE M057 NGON;Lo;0;R;;;;;N;;;;;
+1E88B;MENDE KIKAKUI SYLLABLE M177 NGUAN;Lo;0;R;;;;;N;;;;;
+1E88C;MENDE KIKAKUI SYLLABLE M068 PI;Lo;0;R;;;;;N;;;;;
+1E88D;MENDE KIKAKUI SYLLABLE M099 PA;Lo;0;R;;;;;N;;;;;
+1E88E;MENDE KIKAKUI SYLLABLE M050 PU;Lo;0;R;;;;;N;;;;;
+1E88F;MENDE KIKAKUI SYLLABLE M081 PEE;Lo;0;R;;;;;N;;;;;
+1E890;MENDE KIKAKUI SYLLABLE M051 PE;Lo;0;R;;;;;N;;;;;
+1E891;MENDE KIKAKUI SYLLABLE M102 POO;Lo;0;R;;;;;N;;;;;
+1E892;MENDE KIKAKUI SYLLABLE M066 PO;Lo;0;R;;;;;N;;;;;
+1E893;MENDE KIKAKUI SYLLABLE M145 MBI;Lo;0;R;;;;;N;;;;;
+1E894;MENDE KIKAKUI SYLLABLE M062 MBA;Lo;0;R;;;;;N;;;;;
+1E895;MENDE KIKAKUI SYLLABLE M122 MBU;Lo;0;R;;;;;N;;;;;
+1E896;MENDE KIKAKUI SYLLABLE M047 MBEE;Lo;0;R;;;;;N;;;;;
+1E897;MENDE KIKAKUI SYLLABLE M188 MBEE;Lo;0;R;;;;;N;;;;;
+1E898;MENDE KIKAKUI SYLLABLE M072 MBE;Lo;0;R;;;;;N;;;;;
+1E899;MENDE KIKAKUI SYLLABLE M172 MBOO;Lo;0;R;;;;;N;;;;;
+1E89A;MENDE KIKAKUI SYLLABLE M174 MBO;Lo;0;R;;;;;N;;;;;
+1E89B;MENDE KIKAKUI SYLLABLE M187 MBUU;Lo;0;R;;;;;N;;;;;
+1E89C;MENDE KIKAKUI SYLLABLE M161 LONG MBE;Lo;0;R;;;;;N;;;;;
+1E89D;MENDE KIKAKUI SYLLABLE M105 LONG MBOO;Lo;0;R;;;;;N;;;;;
+1E89E;MENDE KIKAKUI SYLLABLE M142 LONG MBO;Lo;0;R;;;;;N;;;;;
+1E89F;MENDE KIKAKUI SYLLABLE M132 KPI;Lo;0;R;;;;;N;;;;;
+1E8A0;MENDE KIKAKUI SYLLABLE M092 KPA;Lo;0;R;;;;;N;;;;;
+1E8A1;MENDE KIKAKUI SYLLABLE M074 KPU;Lo;0;R;;;;;N;;;;;
+1E8A2;MENDE KIKAKUI SYLLABLE M044 KPEE;Lo;0;R;;;;;N;;;;;
+1E8A3;MENDE KIKAKUI SYLLABLE M108 KPE;Lo;0;R;;;;;N;;;;;
+1E8A4;MENDE KIKAKUI SYLLABLE M112 KPOO;Lo;0;R;;;;;N;;;;;
+1E8A5;MENDE KIKAKUI SYLLABLE M158 KPO;Lo;0;R;;;;;N;;;;;
+1E8A6;MENDE KIKAKUI SYLLABLE M124 GBI;Lo;0;R;;;;;N;;;;;
+1E8A7;MENDE KIKAKUI SYLLABLE M056 GBA;Lo;0;R;;;;;N;;;;;
+1E8A8;MENDE KIKAKUI SYLLABLE M148 GBU;Lo;0;R;;;;;N;;;;;
+1E8A9;MENDE KIKAKUI SYLLABLE M093 GBEE;Lo;0;R;;;;;N;;;;;
+1E8AA;MENDE KIKAKUI SYLLABLE M107 GBE;Lo;0;R;;;;;N;;;;;
+1E8AB;MENDE KIKAKUI SYLLABLE M071 GBOO;Lo;0;R;;;;;N;;;;;
+1E8AC;MENDE KIKAKUI SYLLABLE M070 GBO;Lo;0;R;;;;;N;;;;;
+1E8AD;MENDE KIKAKUI SYLLABLE M171 RA;Lo;0;R;;;;;N;;;;;
+1E8AE;MENDE KIKAKUI SYLLABLE M123 NDI;Lo;0;R;;;;;N;;;;;
+1E8AF;MENDE KIKAKUI SYLLABLE M129 NDA;Lo;0;R;;;;;N;;;;;
+1E8B0;MENDE KIKAKUI SYLLABLE M125 NDU;Lo;0;R;;;;;N;;;;;
+1E8B1;MENDE KIKAKUI SYLLABLE M191 NDEE;Lo;0;R;;;;;N;;;;;
+1E8B2;MENDE KIKAKUI SYLLABLE M119 NDE;Lo;0;R;;;;;N;;;;;
+1E8B3;MENDE KIKAKUI SYLLABLE M067 NDOO;Lo;0;R;;;;;N;;;;;
+1E8B4;MENDE KIKAKUI SYLLABLE M064 NDO;Lo;0;R;;;;;N;;;;;
+1E8B5;MENDE KIKAKUI SYLLABLE M152 NJA;Lo;0;R;;;;;N;;;;;
+1E8B6;MENDE KIKAKUI SYLLABLE M192 NJU;Lo;0;R;;;;;N;;;;;
+1E8B7;MENDE KIKAKUI SYLLABLE M149 NJEE;Lo;0;R;;;;;N;;;;;
+1E8B8;MENDE KIKAKUI SYLLABLE M134 NJOO;Lo;0;R;;;;;N;;;;;
+1E8B9;MENDE KIKAKUI SYLLABLE M182 VI;Lo;0;R;;;;;N;;;;;
+1E8BA;MENDE KIKAKUI SYLLABLE M185 VA;Lo;0;R;;;;;N;;;;;
+1E8BB;MENDE KIKAKUI SYLLABLE M151 VU;Lo;0;R;;;;;N;;;;;
+1E8BC;MENDE KIKAKUI SYLLABLE M173 VEE;Lo;0;R;;;;;N;;;;;
+1E8BD;MENDE KIKAKUI SYLLABLE M085 VE;Lo;0;R;;;;;N;;;;;
+1E8BE;MENDE KIKAKUI SYLLABLE M144 VOO;Lo;0;R;;;;;N;;;;;
+1E8BF;MENDE KIKAKUI SYLLABLE M077 VO;Lo;0;R;;;;;N;;;;;
+1E8C0;MENDE KIKAKUI SYLLABLE M164 NYIN;Lo;0;R;;;;;N;;;;;
+1E8C1;MENDE KIKAKUI SYLLABLE M058 NYAN;Lo;0;R;;;;;N;;;;;
+1E8C2;MENDE KIKAKUI SYLLABLE M170 NYUN;Lo;0;R;;;;;N;;;;;
+1E8C3;MENDE KIKAKUI SYLLABLE M098 NYEN;Lo;0;R;;;;;N;;;;;
+1E8C4;MENDE KIKAKUI SYLLABLE M060 NYON;Lo;0;R;;;;;N;;;;;
+1E8C7;MENDE KIKAKUI DIGIT ONE;No;0;R;;;;1;N;;;;;
+1E8C8;MENDE KIKAKUI DIGIT TWO;No;0;R;;;;2;N;;;;;
+1E8C9;MENDE KIKAKUI DIGIT THREE;No;0;R;;;;3;N;;;;;
+1E8CA;MENDE KIKAKUI DIGIT FOUR;No;0;R;;;;4;N;;;;;
+1E8CB;MENDE KIKAKUI DIGIT FIVE;No;0;R;;;;5;N;;;;;
+1E8CC;MENDE KIKAKUI DIGIT SIX;No;0;R;;;;6;N;;;;;
+1E8CD;MENDE KIKAKUI DIGIT SEVEN;No;0;R;;;;7;N;;;;;
+1E8CE;MENDE KIKAKUI DIGIT EIGHT;No;0;R;;;;8;N;;;;;
+1E8CF;MENDE KIKAKUI DIGIT NINE;No;0;R;;;;9;N;;;;;
+1E8D0;MENDE KIKAKUI COMBINING NUMBER TEENS;Mn;220;NSM;;;;;N;;;;;
+1E8D1;MENDE KIKAKUI COMBINING NUMBER TENS;Mn;220;NSM;;;;;N;;;;;
+1E8D2;MENDE KIKAKUI COMBINING NUMBER HUNDREDS;Mn;220;NSM;;;;;N;;;;;
+1E8D3;MENDE KIKAKUI COMBINING NUMBER THOUSANDS;Mn;220;NSM;;;;;N;;;;;
+1E8D4;MENDE KIKAKUI COMBINING NUMBER TEN THOUSANDS;Mn;220;NSM;;;;;N;;;;;
+1E8D5;MENDE KIKAKUI COMBINING NUMBER HUNDRED THOUSANDS;Mn;220;NSM;;;;;N;;;;;
+1E8D6;MENDE KIKAKUI COMBINING NUMBER MILLIONS;Mn;220;NSM;;;;;N;;;;;
+1E900;ADLAM CAPITAL LETTER ALIF;Lu;0;R;;;;;N;;;;1E922;
+1E901;ADLAM CAPITAL LETTER DAALI;Lu;0;R;;;;;N;;;;1E923;
+1E902;ADLAM CAPITAL LETTER LAAM;Lu;0;R;;;;;N;;;;1E924;
+1E903;ADLAM CAPITAL LETTER MIIM;Lu;0;R;;;;;N;;;;1E925;
+1E904;ADLAM CAPITAL LETTER BA;Lu;0;R;;;;;N;;;;1E926;
+1E905;ADLAM CAPITAL LETTER SINNYIIYHE;Lu;0;R;;;;;N;;;;1E927;
+1E906;ADLAM CAPITAL LETTER PE;Lu;0;R;;;;;N;;;;1E928;
+1E907;ADLAM CAPITAL LETTER BHE;Lu;0;R;;;;;N;;;;1E929;
+1E908;ADLAM CAPITAL LETTER RA;Lu;0;R;;;;;N;;;;1E92A;
+1E909;ADLAM CAPITAL LETTER E;Lu;0;R;;;;;N;;;;1E92B;
+1E90A;ADLAM CAPITAL LETTER FA;Lu;0;R;;;;;N;;;;1E92C;
+1E90B;ADLAM CAPITAL LETTER I;Lu;0;R;;;;;N;;;;1E92D;
+1E90C;ADLAM CAPITAL LETTER O;Lu;0;R;;;;;N;;;;1E92E;
+1E90D;ADLAM CAPITAL LETTER DHA;Lu;0;R;;;;;N;;;;1E92F;
+1E90E;ADLAM CAPITAL LETTER YHE;Lu;0;R;;;;;N;;;;1E930;
+1E90F;ADLAM CAPITAL LETTER WAW;Lu;0;R;;;;;N;;;;1E931;
+1E910;ADLAM CAPITAL LETTER NUN;Lu;0;R;;;;;N;;;;1E932;
+1E911;ADLAM CAPITAL LETTER KAF;Lu;0;R;;;;;N;;;;1E933;
+1E912;ADLAM CAPITAL LETTER YA;Lu;0;R;;;;;N;;;;1E934;
+1E913;ADLAM CAPITAL LETTER U;Lu;0;R;;;;;N;;;;1E935;
+1E914;ADLAM CAPITAL LETTER JIIM;Lu;0;R;;;;;N;;;;1E936;
+1E915;ADLAM CAPITAL LETTER CHI;Lu;0;R;;;;;N;;;;1E937;
+1E916;ADLAM CAPITAL LETTER HA;Lu;0;R;;;;;N;;;;1E938;
+1E917;ADLAM CAPITAL LETTER QAAF;Lu;0;R;;;;;N;;;;1E939;
+1E918;ADLAM CAPITAL LETTER GA;Lu;0;R;;;;;N;;;;1E93A;
+1E919;ADLAM CAPITAL LETTER NYA;Lu;0;R;;;;;N;;;;1E93B;
+1E91A;ADLAM CAPITAL LETTER TU;Lu;0;R;;;;;N;;;;1E93C;
+1E91B;ADLAM CAPITAL LETTER NHA;Lu;0;R;;;;;N;;;;1E93D;
+1E91C;ADLAM CAPITAL LETTER VA;Lu;0;R;;;;;N;;;;1E93E;
+1E91D;ADLAM CAPITAL LETTER KHA;Lu;0;R;;;;;N;;;;1E93F;
+1E91E;ADLAM CAPITAL LETTER GBE;Lu;0;R;;;;;N;;;;1E940;
+1E91F;ADLAM CAPITAL LETTER ZAL;Lu;0;R;;;;;N;;;;1E941;
+1E920;ADLAM CAPITAL LETTER KPO;Lu;0;R;;;;;N;;;;1E942;
+1E921;ADLAM CAPITAL LETTER SHA;Lu;0;R;;;;;N;;;;1E943;
+1E922;ADLAM SMALL LETTER ALIF;Ll;0;R;;;;;N;;;1E900;;1E900
+1E923;ADLAM SMALL LETTER DAALI;Ll;0;R;;;;;N;;;1E901;;1E901
+1E924;ADLAM SMALL LETTER LAAM;Ll;0;R;;;;;N;;;1E902;;1E902
+1E925;ADLAM SMALL LETTER MIIM;Ll;0;R;;;;;N;;;1E903;;1E903
+1E926;ADLAM SMALL LETTER BA;Ll;0;R;;;;;N;;;1E904;;1E904
+1E927;ADLAM SMALL LETTER SINNYIIYHE;Ll;0;R;;;;;N;;;1E905;;1E905
+1E928;ADLAM SMALL LETTER PE;Ll;0;R;;;;;N;;;1E906;;1E906
+1E929;ADLAM SMALL LETTER BHE;Ll;0;R;;;;;N;;;1E907;;1E907
+1E92A;ADLAM SMALL LETTER RA;Ll;0;R;;;;;N;;;1E908;;1E908
+1E92B;ADLAM SMALL LETTER E;Ll;0;R;;;;;N;;;1E909;;1E909
+1E92C;ADLAM SMALL LETTER FA;Ll;0;R;;;;;N;;;1E90A;;1E90A
+1E92D;ADLAM SMALL LETTER I;Ll;0;R;;;;;N;;;1E90B;;1E90B
+1E92E;ADLAM SMALL LETTER O;Ll;0;R;;;;;N;;;1E90C;;1E90C
+1E92F;ADLAM SMALL LETTER DHA;Ll;0;R;;;;;N;;;1E90D;;1E90D
+1E930;ADLAM SMALL LETTER YHE;Ll;0;R;;;;;N;;;1E90E;;1E90E
+1E931;ADLAM SMALL LETTER WAW;Ll;0;R;;;;;N;;;1E90F;;1E90F
+1E932;ADLAM SMALL LETTER NUN;Ll;0;R;;;;;N;;;1E910;;1E910
+1E933;ADLAM SMALL LETTER KAF;Ll;0;R;;;;;N;;;1E911;;1E911
+1E934;ADLAM SMALL LETTER YA;Ll;0;R;;;;;N;;;1E912;;1E912
+1E935;ADLAM SMALL LETTER U;Ll;0;R;;;;;N;;;1E913;;1E913
+1E936;ADLAM SMALL LETTER JIIM;Ll;0;R;;;;;N;;;1E914;;1E914
+1E937;ADLAM SMALL LETTER CHI;Ll;0;R;;;;;N;;;1E915;;1E915
+1E938;ADLAM SMALL LETTER HA;Ll;0;R;;;;;N;;;1E916;;1E916
+1E939;ADLAM SMALL LETTER QAAF;Ll;0;R;;;;;N;;;1E917;;1E917
+1E93A;ADLAM SMALL LETTER GA;Ll;0;R;;;;;N;;;1E918;;1E918
+1E93B;ADLAM SMALL LETTER NYA;Ll;0;R;;;;;N;;;1E919;;1E919
+1E93C;ADLAM SMALL LETTER TU;Ll;0;R;;;;;N;;;1E91A;;1E91A
+1E93D;ADLAM SMALL LETTER NHA;Ll;0;R;;;;;N;;;1E91B;;1E91B
+1E93E;ADLAM SMALL LETTER VA;Ll;0;R;;;;;N;;;1E91C;;1E91C
+1E93F;ADLAM SMALL LETTER KHA;Ll;0;R;;;;;N;;;1E91D;;1E91D
+1E940;ADLAM SMALL LETTER GBE;Ll;0;R;;;;;N;;;1E91E;;1E91E
+1E941;ADLAM SMALL LETTER ZAL;Ll;0;R;;;;;N;;;1E91F;;1E91F
+1E942;ADLAM SMALL LETTER KPO;Ll;0;R;;;;;N;;;1E920;;1E920
+1E943;ADLAM SMALL LETTER SHA;Ll;0;R;;;;;N;;;1E921;;1E921
+1E944;ADLAM ALIF LENGTHENER;Mn;230;NSM;;;;;N;;;;;
+1E945;ADLAM VOWEL LENGTHENER;Mn;230;NSM;;;;;N;;;;;
+1E946;ADLAM GEMINATION MARK;Mn;230;NSM;;;;;N;;;;;
+1E947;ADLAM HAMZA;Mn;230;NSM;;;;;N;;;;;
+1E948;ADLAM CONSONANT MODIFIER;Mn;230;NSM;;;;;N;;;;;
+1E949;ADLAM GEMINATE CONSONANT MODIFIER;Mn;230;NSM;;;;;N;;;;;
+1E94A;ADLAM NUKTA;Mn;7;NSM;;;;;N;;;;;
+1E950;ADLAM DIGIT ZERO;Nd;0;R;;0;0;0;N;;;;;
+1E951;ADLAM DIGIT ONE;Nd;0;R;;1;1;1;N;;;;;
+1E952;ADLAM DIGIT TWO;Nd;0;R;;2;2;2;N;;;;;
+1E953;ADLAM DIGIT THREE;Nd;0;R;;3;3;3;N;;;;;
+1E954;ADLAM DIGIT FOUR;Nd;0;R;;4;4;4;N;;;;;
+1E955;ADLAM DIGIT FIVE;Nd;0;R;;5;5;5;N;;;;;
+1E956;ADLAM DIGIT SIX;Nd;0;R;;6;6;6;N;;;;;
+1E957;ADLAM DIGIT SEVEN;Nd;0;R;;7;7;7;N;;;;;
+1E958;ADLAM DIGIT EIGHT;Nd;0;R;;8;8;8;N;;;;;
+1E959;ADLAM DIGIT NINE;Nd;0;R;;9;9;9;N;;;;;
+1E95E;ADLAM INITIAL EXCLAMATION MARK;Po;0;R;;;;;N;;;;;
+1E95F;ADLAM INITIAL QUESTION MARK;Po;0;R;;;;;N;;;;;
+1EE00;ARABIC MATHEMATICAL ALEF;Lo;0;AL;<font> 0627;;;;N;;;;;
+1EE01;ARABIC MATHEMATICAL BEH;Lo;0;AL;<font> 0628;;;;N;;;;;
+1EE02;ARABIC MATHEMATICAL JEEM;Lo;0;AL;<font> 062C;;;;N;;;;;
+1EE03;ARABIC MATHEMATICAL DAL;Lo;0;AL;<font> 062F;;;;N;;;;;
+1EE05;ARABIC MATHEMATICAL WAW;Lo;0;AL;<font> 0648;;;;N;;;;;
+1EE06;ARABIC MATHEMATICAL ZAIN;Lo;0;AL;<font> 0632;;;;N;;;;;
+1EE07;ARABIC MATHEMATICAL HAH;Lo;0;AL;<font> 062D;;;;N;;;;;
+1EE08;ARABIC MATHEMATICAL TAH;Lo;0;AL;<font> 0637;;;;N;;;;;
+1EE09;ARABIC MATHEMATICAL YEH;Lo;0;AL;<font> 064A;;;;N;;;;;
+1EE0A;ARABIC MATHEMATICAL KAF;Lo;0;AL;<font> 0643;;;;N;;;;;
+1EE0B;ARABIC MATHEMATICAL LAM;Lo;0;AL;<font> 0644;;;;N;;;;;
+1EE0C;ARABIC MATHEMATICAL MEEM;Lo;0;AL;<font> 0645;;;;N;;;;;
+1EE0D;ARABIC MATHEMATICAL NOON;Lo;0;AL;<font> 0646;;;;N;;;;;
+1EE0E;ARABIC MATHEMATICAL SEEN;Lo;0;AL;<font> 0633;;;;N;;;;;
+1EE0F;ARABIC MATHEMATICAL AIN;Lo;0;AL;<font> 0639;;;;N;;;;;
+1EE10;ARABIC MATHEMATICAL FEH;Lo;0;AL;<font> 0641;;;;N;;;;;
+1EE11;ARABIC MATHEMATICAL SAD;Lo;0;AL;<font> 0635;;;;N;;;;;
+1EE12;ARABIC MATHEMATICAL QAF;Lo;0;AL;<font> 0642;;;;N;;;;;
+1EE13;ARABIC MATHEMATICAL REH;Lo;0;AL;<font> 0631;;;;N;;;;;
+1EE14;ARABIC MATHEMATICAL SHEEN;Lo;0;AL;<font> 0634;;;;N;;;;;
+1EE15;ARABIC MATHEMATICAL TEH;Lo;0;AL;<font> 062A;;;;N;;;;;
+1EE16;ARABIC MATHEMATICAL THEH;Lo;0;AL;<font> 062B;;;;N;;;;;
+1EE17;ARABIC MATHEMATICAL KHAH;Lo;0;AL;<font> 062E;;;;N;;;;;
+1EE18;ARABIC MATHEMATICAL THAL;Lo;0;AL;<font> 0630;;;;N;;;;;
+1EE19;ARABIC MATHEMATICAL DAD;Lo;0;AL;<font> 0636;;;;N;;;;;
+1EE1A;ARABIC MATHEMATICAL ZAH;Lo;0;AL;<font> 0638;;;;N;;;;;
+1EE1B;ARABIC MATHEMATICAL GHAIN;Lo;0;AL;<font> 063A;;;;N;;;;;
+1EE1C;ARABIC MATHEMATICAL DOTLESS BEH;Lo;0;AL;<font> 066E;;;;N;;;;;
+1EE1D;ARABIC MATHEMATICAL DOTLESS NOON;Lo;0;AL;<font> 06BA;;;;N;;;;;
+1EE1E;ARABIC MATHEMATICAL DOTLESS FEH;Lo;0;AL;<font> 06A1;;;;N;;;;;
+1EE1F;ARABIC MATHEMATICAL DOTLESS QAF;Lo;0;AL;<font> 066F;;;;N;;;;;
+1EE21;ARABIC MATHEMATICAL INITIAL BEH;Lo;0;AL;<font> 0628;;;;N;;;;;
+1EE22;ARABIC MATHEMATICAL INITIAL JEEM;Lo;0;AL;<font> 062C;;;;N;;;;;
+1EE24;ARABIC MATHEMATICAL INITIAL HEH;Lo;0;AL;<font> 0647;;;;N;;;;;
+1EE27;ARABIC MATHEMATICAL INITIAL HAH;Lo;0;AL;<font> 062D;;;;N;;;;;
+1EE29;ARABIC MATHEMATICAL INITIAL YEH;Lo;0;AL;<font> 064A;;;;N;;;;;
+1EE2A;ARABIC MATHEMATICAL INITIAL KAF;Lo;0;AL;<font> 0643;;;;N;;;;;
+1EE2B;ARABIC MATHEMATICAL INITIAL LAM;Lo;0;AL;<font> 0644;;;;N;;;;;
+1EE2C;ARABIC MATHEMATICAL INITIAL MEEM;Lo;0;AL;<font> 0645;;;;N;;;;;
+1EE2D;ARABIC MATHEMATICAL INITIAL NOON;Lo;0;AL;<font> 0646;;;;N;;;;;
+1EE2E;ARABIC MATHEMATICAL INITIAL SEEN;Lo;0;AL;<font> 0633;;;;N;;;;;
+1EE2F;ARABIC MATHEMATICAL INITIAL AIN;Lo;0;AL;<font> 0639;;;;N;;;;;
+1EE30;ARABIC MATHEMATICAL INITIAL FEH;Lo;0;AL;<font> 0641;;;;N;;;;;
+1EE31;ARABIC MATHEMATICAL INITIAL SAD;Lo;0;AL;<font> 0635;;;;N;;;;;
+1EE32;ARABIC MATHEMATICAL INITIAL QAF;Lo;0;AL;<font> 0642;;;;N;;;;;
+1EE34;ARABIC MATHEMATICAL INITIAL SHEEN;Lo;0;AL;<font> 0634;;;;N;;;;;
+1EE35;ARABIC MATHEMATICAL INITIAL TEH;Lo;0;AL;<font> 062A;;;;N;;;;;
+1EE36;ARABIC MATHEMATICAL INITIAL THEH;Lo;0;AL;<font> 062B;;;;N;;;;;
+1EE37;ARABIC MATHEMATICAL INITIAL KHAH;Lo;0;AL;<font> 062E;;;;N;;;;;
+1EE39;ARABIC MATHEMATICAL INITIAL DAD;Lo;0;AL;<font> 0636;;;;N;;;;;
+1EE3B;ARABIC MATHEMATICAL INITIAL GHAIN;Lo;0;AL;<font> 063A;;;;N;;;;;
+1EE42;ARABIC MATHEMATICAL TAILED JEEM;Lo;0;AL;<font> 062C;;;;N;;;;;
+1EE47;ARABIC MATHEMATICAL TAILED HAH;Lo;0;AL;<font> 062D;;;;N;;;;;
+1EE49;ARABIC MATHEMATICAL TAILED YEH;Lo;0;AL;<font> 064A;;;;N;;;;;
+1EE4B;ARABIC MATHEMATICAL TAILED LAM;Lo;0;AL;<font> 0644;;;;N;;;;;
+1EE4D;ARABIC MATHEMATICAL TAILED NOON;Lo;0;AL;<font> 0646;;;;N;;;;;
+1EE4E;ARABIC MATHEMATICAL TAILED SEEN;Lo;0;AL;<font> 0633;;;;N;;;;;
+1EE4F;ARABIC MATHEMATICAL TAILED AIN;Lo;0;AL;<font> 0639;;;;N;;;;;
+1EE51;ARABIC MATHEMATICAL TAILED SAD;Lo;0;AL;<font> 0635;;;;N;;;;;
+1EE52;ARABIC MATHEMATICAL TAILED QAF;Lo;0;AL;<font> 0642;;;;N;;;;;
+1EE54;ARABIC MATHEMATICAL TAILED SHEEN;Lo;0;AL;<font> 0634;;;;N;;;;;
+1EE57;ARABIC MATHEMATICAL TAILED KHAH;Lo;0;AL;<font> 062E;;;;N;;;;;
+1EE59;ARABIC MATHEMATICAL TAILED DAD;Lo;0;AL;<font> 0636;;;;N;;;;;
+1EE5B;ARABIC MATHEMATICAL TAILED GHAIN;Lo;0;AL;<font> 063A;;;;N;;;;;
+1EE5D;ARABIC MATHEMATICAL TAILED DOTLESS NOON;Lo;0;AL;<font> 06BA;;;;N;;;;;
+1EE5F;ARABIC MATHEMATICAL TAILED DOTLESS QAF;Lo;0;AL;<font> 066F;;;;N;;;;;
+1EE61;ARABIC MATHEMATICAL STRETCHED BEH;Lo;0;AL;<font> 0628;;;;N;;;;;
+1EE62;ARABIC MATHEMATICAL STRETCHED JEEM;Lo;0;AL;<font> 062C;;;;N;;;;;
+1EE64;ARABIC MATHEMATICAL STRETCHED HEH;Lo;0;AL;<font> 0647;;;;N;;;;;
+1EE67;ARABIC MATHEMATICAL STRETCHED HAH;Lo;0;AL;<font> 062D;;;;N;;;;;
+1EE68;ARABIC MATHEMATICAL STRETCHED TAH;Lo;0;AL;<font> 0637;;;;N;;;;;
+1EE69;ARABIC MATHEMATICAL STRETCHED YEH;Lo;0;AL;<font> 064A;;;;N;;;;;
+1EE6A;ARABIC MATHEMATICAL STRETCHED KAF;Lo;0;AL;<font> 0643;;;;N;;;;;
+1EE6C;ARABIC MATHEMATICAL STRETCHED MEEM;Lo;0;AL;<font> 0645;;;;N;;;;;
+1EE6D;ARABIC MATHEMATICAL STRETCHED NOON;Lo;0;AL;<font> 0646;;;;N;;;;;
+1EE6E;ARABIC MATHEMATICAL STRETCHED SEEN;Lo;0;AL;<font> 0633;;;;N;;;;;
+1EE6F;ARABIC MATHEMATICAL STRETCHED AIN;Lo;0;AL;<font> 0639;;;;N;;;;;
+1EE70;ARABIC MATHEMATICAL STRETCHED FEH;Lo;0;AL;<font> 0641;;;;N;;;;;
+1EE71;ARABIC MATHEMATICAL STRETCHED SAD;Lo;0;AL;<font> 0635;;;;N;;;;;
+1EE72;ARABIC MATHEMATICAL STRETCHED QAF;Lo;0;AL;<font> 0642;;;;N;;;;;
+1EE74;ARABIC MATHEMATICAL STRETCHED SHEEN;Lo;0;AL;<font> 0634;;;;N;;;;;
+1EE75;ARABIC MATHEMATICAL STRETCHED TEH;Lo;0;AL;<font> 062A;;;;N;;;;;
+1EE76;ARABIC MATHEMATICAL STRETCHED THEH;Lo;0;AL;<font> 062B;;;;N;;;;;
+1EE77;ARABIC MATHEMATICAL STRETCHED KHAH;Lo;0;AL;<font> 062E;;;;N;;;;;
+1EE79;ARABIC MATHEMATICAL STRETCHED DAD;Lo;0;AL;<font> 0636;;;;N;;;;;
+1EE7A;ARABIC MATHEMATICAL STRETCHED ZAH;Lo;0;AL;<font> 0638;;;;N;;;;;
+1EE7B;ARABIC MATHEMATICAL STRETCHED GHAIN;Lo;0;AL;<font> 063A;;;;N;;;;;
+1EE7C;ARABIC MATHEMATICAL STRETCHED DOTLESS BEH;Lo;0;AL;<font> 066E;;;;N;;;;;
+1EE7E;ARABIC MATHEMATICAL STRETCHED DOTLESS FEH;Lo;0;AL;<font> 06A1;;;;N;;;;;
+1EE80;ARABIC MATHEMATICAL LOOPED ALEF;Lo;0;AL;<font> 0627;;;;N;;;;;
+1EE81;ARABIC MATHEMATICAL LOOPED BEH;Lo;0;AL;<font> 0628;;;;N;;;;;
+1EE82;ARABIC MATHEMATICAL LOOPED JEEM;Lo;0;AL;<font> 062C;;;;N;;;;;
+1EE83;ARABIC MATHEMATICAL LOOPED DAL;Lo;0;AL;<font> 062F;;;;N;;;;;
+1EE84;ARABIC MATHEMATICAL LOOPED HEH;Lo;0;AL;<font> 0647;;;;N;;;;;
+1EE85;ARABIC MATHEMATICAL LOOPED WAW;Lo;0;AL;<font> 0648;;;;N;;;;;
+1EE86;ARABIC MATHEMATICAL LOOPED ZAIN;Lo;0;AL;<font> 0632;;;;N;;;;;
+1EE87;ARABIC MATHEMATICAL LOOPED HAH;Lo;0;AL;<font> 062D;;;;N;;;;;
+1EE88;ARABIC MATHEMATICAL LOOPED TAH;Lo;0;AL;<font> 0637;;;;N;;;;;
+1EE89;ARABIC MATHEMATICAL LOOPED YEH;Lo;0;AL;<font> 064A;;;;N;;;;;
+1EE8B;ARABIC MATHEMATICAL LOOPED LAM;Lo;0;AL;<font> 0644;;;;N;;;;;
+1EE8C;ARABIC MATHEMATICAL LOOPED MEEM;Lo;0;AL;<font> 0645;;;;N;;;;;
+1EE8D;ARABIC MATHEMATICAL LOOPED NOON;Lo;0;AL;<font> 0646;;;;N;;;;;
+1EE8E;ARABIC MATHEMATICAL LOOPED SEEN;Lo;0;AL;<font> 0633;;;;N;;;;;
+1EE8F;ARABIC MATHEMATICAL LOOPED AIN;Lo;0;AL;<font> 0639;;;;N;;;;;
+1EE90;ARABIC MATHEMATICAL LOOPED FEH;Lo;0;AL;<font> 0641;;;;N;;;;;
+1EE91;ARABIC MATHEMATICAL LOOPED SAD;Lo;0;AL;<font> 0635;;;;N;;;;;
+1EE92;ARABIC MATHEMATICAL LOOPED QAF;Lo;0;AL;<font> 0642;;;;N;;;;;
+1EE93;ARABIC MATHEMATICAL LOOPED REH;Lo;0;AL;<font> 0631;;;;N;;;;;
+1EE94;ARABIC MATHEMATICAL LOOPED SHEEN;Lo;0;AL;<font> 0634;;;;N;;;;;
+1EE95;ARABIC MATHEMATICAL LOOPED TEH;Lo;0;AL;<font> 062A;;;;N;;;;;
+1EE96;ARABIC MATHEMATICAL LOOPED THEH;Lo;0;AL;<font> 062B;;;;N;;;;;
+1EE97;ARABIC MATHEMATICAL LOOPED KHAH;Lo;0;AL;<font> 062E;;;;N;;;;;
+1EE98;ARABIC MATHEMATICAL LOOPED THAL;Lo;0;AL;<font> 0630;;;;N;;;;;
+1EE99;ARABIC MATHEMATICAL LOOPED DAD;Lo;0;AL;<font> 0636;;;;N;;;;;
+1EE9A;ARABIC MATHEMATICAL LOOPED ZAH;Lo;0;AL;<font> 0638;;;;N;;;;;
+1EE9B;ARABIC MATHEMATICAL LOOPED GHAIN;Lo;0;AL;<font> 063A;;;;N;;;;;
+1EEA1;ARABIC MATHEMATICAL DOUBLE-STRUCK BEH;Lo;0;AL;<font> 0628;;;;N;;;;;
+1EEA2;ARABIC MATHEMATICAL DOUBLE-STRUCK JEEM;Lo;0;AL;<font> 062C;;;;N;;;;;
+1EEA3;ARABIC MATHEMATICAL DOUBLE-STRUCK DAL;Lo;0;AL;<font> 062F;;;;N;;;;;
+1EEA5;ARABIC MATHEMATICAL DOUBLE-STRUCK WAW;Lo;0;AL;<font> 0648;;;;N;;;;;
+1EEA6;ARABIC MATHEMATICAL DOUBLE-STRUCK ZAIN;Lo;0;AL;<font> 0632;;;;N;;;;;
+1EEA7;ARABIC MATHEMATICAL DOUBLE-STRUCK HAH;Lo;0;AL;<font> 062D;;;;N;;;;;
+1EEA8;ARABIC MATHEMATICAL DOUBLE-STRUCK TAH;Lo;0;AL;<font> 0637;;;;N;;;;;
+1EEA9;ARABIC MATHEMATICAL DOUBLE-STRUCK YEH;Lo;0;AL;<font> 064A;;;;N;;;;;
+1EEAB;ARABIC MATHEMATICAL DOUBLE-STRUCK LAM;Lo;0;AL;<font> 0644;;;;N;;;;;
+1EEAC;ARABIC MATHEMATICAL DOUBLE-STRUCK MEEM;Lo;0;AL;<font> 0645;;;;N;;;;;
+1EEAD;ARABIC MATHEMATICAL DOUBLE-STRUCK NOON;Lo;0;AL;<font> 0646;;;;N;;;;;
+1EEAE;ARABIC MATHEMATICAL DOUBLE-STRUCK SEEN;Lo;0;AL;<font> 0633;;;;N;;;;;
+1EEAF;ARABIC MATHEMATICAL DOUBLE-STRUCK AIN;Lo;0;AL;<font> 0639;;;;N;;;;;
+1EEB0;ARABIC MATHEMATICAL DOUBLE-STRUCK FEH;Lo;0;AL;<font> 0641;;;;N;;;;;
+1EEB1;ARABIC MATHEMATICAL DOUBLE-STRUCK SAD;Lo;0;AL;<font> 0635;;;;N;;;;;
+1EEB2;ARABIC MATHEMATICAL DOUBLE-STRUCK QAF;Lo;0;AL;<font> 0642;;;;N;;;;;
+1EEB3;ARABIC MATHEMATICAL DOUBLE-STRUCK REH;Lo;0;AL;<font> 0631;;;;N;;;;;
+1EEB4;ARABIC MATHEMATICAL DOUBLE-STRUCK SHEEN;Lo;0;AL;<font> 0634;;;;N;;;;;
+1EEB5;ARABIC MATHEMATICAL DOUBLE-STRUCK TEH;Lo;0;AL;<font> 062A;;;;N;;;;;
+1EEB6;ARABIC MATHEMATICAL DOUBLE-STRUCK THEH;Lo;0;AL;<font> 062B;;;;N;;;;;
+1EEB7;ARABIC MATHEMATICAL DOUBLE-STRUCK KHAH;Lo;0;AL;<font> 062E;;;;N;;;;;
+1EEB8;ARABIC MATHEMATICAL DOUBLE-STRUCK THAL;Lo;0;AL;<font> 0630;;;;N;;;;;
+1EEB9;ARABIC MATHEMATICAL DOUBLE-STRUCK DAD;Lo;0;AL;<font> 0636;;;;N;;;;;
+1EEBA;ARABIC MATHEMATICAL DOUBLE-STRUCK ZAH;Lo;0;AL;<font> 0638;;;;N;;;;;
+1EEBB;ARABIC MATHEMATICAL DOUBLE-STRUCK GHAIN;Lo;0;AL;<font> 063A;;;;N;;;;;
+1EEF0;ARABIC MATHEMATICAL OPERATOR MEEM WITH HAH WITH TATWEEL;Sm;0;ON;;;;;N;;;;;
+1EEF1;ARABIC MATHEMATICAL OPERATOR HAH WITH DAL;Sm;0;ON;;;;;N;;;;;
1F000;MAHJONG TILE EAST WIND;So;0;ON;;;;;N;;;;;
1F001;MAHJONG TILE SOUTH WIND;So;0;ON;;;;;N;;;;;
1F002;MAHJONG TILE WEST WIND;So;0;ON;;;;;N;;;;;
@@ -20833,6 +28886,88 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1F091;DOMINO TILE VERTICAL-06-04;So;0;ON;;;;;N;;;;;
1F092;DOMINO TILE VERTICAL-06-05;So;0;ON;;;;;N;;;;;
1F093;DOMINO TILE VERTICAL-06-06;So;0;ON;;;;;N;;;;;
+1F0A0;PLAYING CARD BACK;So;0;ON;;;;;N;;;;;
+1F0A1;PLAYING CARD ACE OF SPADES;So;0;ON;;;;;N;;;;;
+1F0A2;PLAYING CARD TWO OF SPADES;So;0;ON;;;;;N;;;;;
+1F0A3;PLAYING CARD THREE OF SPADES;So;0;ON;;;;;N;;;;;
+1F0A4;PLAYING CARD FOUR OF SPADES;So;0;ON;;;;;N;;;;;
+1F0A5;PLAYING CARD FIVE OF SPADES;So;0;ON;;;;;N;;;;;
+1F0A6;PLAYING CARD SIX OF SPADES;So;0;ON;;;;;N;;;;;
+1F0A7;PLAYING CARD SEVEN OF SPADES;So;0;ON;;;;;N;;;;;
+1F0A8;PLAYING CARD EIGHT OF SPADES;So;0;ON;;;;;N;;;;;
+1F0A9;PLAYING CARD NINE OF SPADES;So;0;ON;;;;;N;;;;;
+1F0AA;PLAYING CARD TEN OF SPADES;So;0;ON;;;;;N;;;;;
+1F0AB;PLAYING CARD JACK OF SPADES;So;0;ON;;;;;N;;;;;
+1F0AC;PLAYING CARD KNIGHT OF SPADES;So;0;ON;;;;;N;;;;;
+1F0AD;PLAYING CARD QUEEN OF SPADES;So;0;ON;;;;;N;;;;;
+1F0AE;PLAYING CARD KING OF SPADES;So;0;ON;;;;;N;;;;;
+1F0B1;PLAYING CARD ACE OF HEARTS;So;0;ON;;;;;N;;;;;
+1F0B2;PLAYING CARD TWO OF HEARTS;So;0;ON;;;;;N;;;;;
+1F0B3;PLAYING CARD THREE OF HEARTS;So;0;ON;;;;;N;;;;;
+1F0B4;PLAYING CARD FOUR OF HEARTS;So;0;ON;;;;;N;;;;;
+1F0B5;PLAYING CARD FIVE OF HEARTS;So;0;ON;;;;;N;;;;;
+1F0B6;PLAYING CARD SIX OF HEARTS;So;0;ON;;;;;N;;;;;
+1F0B7;PLAYING CARD SEVEN OF HEARTS;So;0;ON;;;;;N;;;;;
+1F0B8;PLAYING CARD EIGHT OF HEARTS;So;0;ON;;;;;N;;;;;
+1F0B9;PLAYING CARD NINE OF HEARTS;So;0;ON;;;;;N;;;;;
+1F0BA;PLAYING CARD TEN OF HEARTS;So;0;ON;;;;;N;;;;;
+1F0BB;PLAYING CARD JACK OF HEARTS;So;0;ON;;;;;N;;;;;
+1F0BC;PLAYING CARD KNIGHT OF HEARTS;So;0;ON;;;;;N;;;;;
+1F0BD;PLAYING CARD QUEEN OF HEARTS;So;0;ON;;;;;N;;;;;
+1F0BE;PLAYING CARD KING OF HEARTS;So;0;ON;;;;;N;;;;;
+1F0BF;PLAYING CARD RED JOKER;So;0;ON;;;;;N;;;;;
+1F0C1;PLAYING CARD ACE OF DIAMONDS;So;0;ON;;;;;N;;;;;
+1F0C2;PLAYING CARD TWO OF DIAMONDS;So;0;ON;;;;;N;;;;;
+1F0C3;PLAYING CARD THREE OF DIAMONDS;So;0;ON;;;;;N;;;;;
+1F0C4;PLAYING CARD FOUR OF DIAMONDS;So;0;ON;;;;;N;;;;;
+1F0C5;PLAYING CARD FIVE OF DIAMONDS;So;0;ON;;;;;N;;;;;
+1F0C6;PLAYING CARD SIX OF DIAMONDS;So;0;ON;;;;;N;;;;;
+1F0C7;PLAYING CARD SEVEN OF DIAMONDS;So;0;ON;;;;;N;;;;;
+1F0C8;PLAYING CARD EIGHT OF DIAMONDS;So;0;ON;;;;;N;;;;;
+1F0C9;PLAYING CARD NINE OF DIAMONDS;So;0;ON;;;;;N;;;;;
+1F0CA;PLAYING CARD TEN OF DIAMONDS;So;0;ON;;;;;N;;;;;
+1F0CB;PLAYING CARD JACK OF DIAMONDS;So;0;ON;;;;;N;;;;;
+1F0CC;PLAYING CARD KNIGHT OF DIAMONDS;So;0;ON;;;;;N;;;;;
+1F0CD;PLAYING CARD QUEEN OF DIAMONDS;So;0;ON;;;;;N;;;;;
+1F0CE;PLAYING CARD KING OF DIAMONDS;So;0;ON;;;;;N;;;;;
+1F0CF;PLAYING CARD BLACK JOKER;So;0;ON;;;;;N;;;;;
+1F0D1;PLAYING CARD ACE OF CLUBS;So;0;ON;;;;;N;;;;;
+1F0D2;PLAYING CARD TWO OF CLUBS;So;0;ON;;;;;N;;;;;
+1F0D3;PLAYING CARD THREE OF CLUBS;So;0;ON;;;;;N;;;;;
+1F0D4;PLAYING CARD FOUR OF CLUBS;So;0;ON;;;;;N;;;;;
+1F0D5;PLAYING CARD FIVE OF CLUBS;So;0;ON;;;;;N;;;;;
+1F0D6;PLAYING CARD SIX OF CLUBS;So;0;ON;;;;;N;;;;;
+1F0D7;PLAYING CARD SEVEN OF CLUBS;So;0;ON;;;;;N;;;;;
+1F0D8;PLAYING CARD EIGHT OF CLUBS;So;0;ON;;;;;N;;;;;
+1F0D9;PLAYING CARD NINE OF CLUBS;So;0;ON;;;;;N;;;;;
+1F0DA;PLAYING CARD TEN OF CLUBS;So;0;ON;;;;;N;;;;;
+1F0DB;PLAYING CARD JACK OF CLUBS;So;0;ON;;;;;N;;;;;
+1F0DC;PLAYING CARD KNIGHT OF CLUBS;So;0;ON;;;;;N;;;;;
+1F0DD;PLAYING CARD QUEEN OF CLUBS;So;0;ON;;;;;N;;;;;
+1F0DE;PLAYING CARD KING OF CLUBS;So;0;ON;;;;;N;;;;;
+1F0DF;PLAYING CARD WHITE JOKER;So;0;ON;;;;;N;;;;;
+1F0E0;PLAYING CARD FOOL;So;0;ON;;;;;N;;;;;
+1F0E1;PLAYING CARD TRUMP-1;So;0;ON;;;;;N;;;;;
+1F0E2;PLAYING CARD TRUMP-2;So;0;ON;;;;;N;;;;;
+1F0E3;PLAYING CARD TRUMP-3;So;0;ON;;;;;N;;;;;
+1F0E4;PLAYING CARD TRUMP-4;So;0;ON;;;;;N;;;;;
+1F0E5;PLAYING CARD TRUMP-5;So;0;ON;;;;;N;;;;;
+1F0E6;PLAYING CARD TRUMP-6;So;0;ON;;;;;N;;;;;
+1F0E7;PLAYING CARD TRUMP-7;So;0;ON;;;;;N;;;;;
+1F0E8;PLAYING CARD TRUMP-8;So;0;ON;;;;;N;;;;;
+1F0E9;PLAYING CARD TRUMP-9;So;0;ON;;;;;N;;;;;
+1F0EA;PLAYING CARD TRUMP-10;So;0;ON;;;;;N;;;;;
+1F0EB;PLAYING CARD TRUMP-11;So;0;ON;;;;;N;;;;;
+1F0EC;PLAYING CARD TRUMP-12;So;0;ON;;;;;N;;;;;
+1F0ED;PLAYING CARD TRUMP-13;So;0;ON;;;;;N;;;;;
+1F0EE;PLAYING CARD TRUMP-14;So;0;ON;;;;;N;;;;;
+1F0EF;PLAYING CARD TRUMP-15;So;0;ON;;;;;N;;;;;
+1F0F0;PLAYING CARD TRUMP-16;So;0;ON;;;;;N;;;;;
+1F0F1;PLAYING CARD TRUMP-17;So;0;ON;;;;;N;;;;;
+1F0F2;PLAYING CARD TRUMP-18;So;0;ON;;;;;N;;;;;
+1F0F3;PLAYING CARD TRUMP-19;So;0;ON;;;;;N;;;;;
+1F0F4;PLAYING CARD TRUMP-20;So;0;ON;;;;;N;;;;;
+1F0F5;PLAYING CARD TRUMP-21;So;0;ON;;;;;N;;;;;
1F100;DIGIT ZERO FULL STOP;No;0;EN;<compat> 0030 002E;;0;0;N;;;;;
1F101;DIGIT ZERO COMMA;No;0;EN;<compat> 0030 002C;;0;0;N;;;;;
1F102;DIGIT ONE COMMA;No;0;EN;<compat> 0031 002C;;1;1;N;;;;;
@@ -20844,6 +28979,8 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1F108;DIGIT SEVEN COMMA;No;0;EN;<compat> 0037 002C;;7;7;N;;;;;
1F109;DIGIT EIGHT COMMA;No;0;EN;<compat> 0038 002C;;8;8;N;;;;;
1F10A;DIGIT NINE COMMA;No;0;EN;<compat> 0039 002C;;9;9;N;;;;;
+1F10B;DINGBAT CIRCLED SANS-SERIF DIGIT ZERO;No;0;ON;;;;0;N;;;;;
+1F10C;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ZERO;No;0;ON;;;;0;N;;;;;
1F110;PARENTHESIZED LATIN CAPITAL LETTER A;So;0;L;<compat> 0028 0041 0029;;;;N;;;;;
1F111;PARENTHESIZED LATIN CAPITAL LETTER B;So;0;L;<compat> 0028 0042 0029;;;;N;;;;;
1F112;PARENTHESIZED LATIN CAPITAL LETTER C;So;0;L;<compat> 0028 0043 0029;;;;N;;;;;
@@ -20875,28 +29012,156 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1F12C;CIRCLED ITALIC LATIN CAPITAL LETTER R;So;0;L;<circle> 0052;;;;N;;;;;
1F12D;CIRCLED CD;So;0;L;<circle> 0043 0044;;;;N;;;;;
1F12E;CIRCLED WZ;So;0;L;<circle> 0057 005A;;;;N;;;;;
+1F130;SQUARED LATIN CAPITAL LETTER A;So;0;L;<square> 0041;;;;N;;;;;
1F131;SQUARED LATIN CAPITAL LETTER B;So;0;L;<square> 0042;;;;N;;;;;
+1F132;SQUARED LATIN CAPITAL LETTER C;So;0;L;<square> 0043;;;;N;;;;;
+1F133;SQUARED LATIN CAPITAL LETTER D;So;0;L;<square> 0044;;;;N;;;;;
+1F134;SQUARED LATIN CAPITAL LETTER E;So;0;L;<square> 0045;;;;N;;;;;
+1F135;SQUARED LATIN CAPITAL LETTER F;So;0;L;<square> 0046;;;;N;;;;;
+1F136;SQUARED LATIN CAPITAL LETTER G;So;0;L;<square> 0047;;;;N;;;;;
+1F137;SQUARED LATIN CAPITAL LETTER H;So;0;L;<square> 0048;;;;N;;;;;
+1F138;SQUARED LATIN CAPITAL LETTER I;So;0;L;<square> 0049;;;;N;;;;;
+1F139;SQUARED LATIN CAPITAL LETTER J;So;0;L;<square> 004A;;;;N;;;;;
+1F13A;SQUARED LATIN CAPITAL LETTER K;So;0;L;<square> 004B;;;;N;;;;;
+1F13B;SQUARED LATIN CAPITAL LETTER L;So;0;L;<square> 004C;;;;N;;;;;
+1F13C;SQUARED LATIN CAPITAL LETTER M;So;0;L;<square> 004D;;;;N;;;;;
1F13D;SQUARED LATIN CAPITAL LETTER N;So;0;L;<square> 004E;;;;N;;;;;
+1F13E;SQUARED LATIN CAPITAL LETTER O;So;0;L;<square> 004F;;;;N;;;;;
1F13F;SQUARED LATIN CAPITAL LETTER P;So;0;L;<square> 0050;;;;N;;;;;
+1F140;SQUARED LATIN CAPITAL LETTER Q;So;0;L;<square> 0051;;;;N;;;;;
+1F141;SQUARED LATIN CAPITAL LETTER R;So;0;L;<square> 0052;;;;N;;;;;
1F142;SQUARED LATIN CAPITAL LETTER S;So;0;L;<square> 0053;;;;N;;;;;
+1F143;SQUARED LATIN CAPITAL LETTER T;So;0;L;<square> 0054;;;;N;;;;;
+1F144;SQUARED LATIN CAPITAL LETTER U;So;0;L;<square> 0055;;;;N;;;;;
+1F145;SQUARED LATIN CAPITAL LETTER V;So;0;L;<square> 0056;;;;N;;;;;
1F146;SQUARED LATIN CAPITAL LETTER W;So;0;L;<square> 0057;;;;N;;;;;
+1F147;SQUARED LATIN CAPITAL LETTER X;So;0;L;<square> 0058;;;;N;;;;;
+1F148;SQUARED LATIN CAPITAL LETTER Y;So;0;L;<square> 0059;;;;N;;;;;
+1F149;SQUARED LATIN CAPITAL LETTER Z;So;0;L;<square> 005A;;;;N;;;;;
1F14A;SQUARED HV;So;0;L;<square> 0048 0056;;;;N;;;;;
1F14B;SQUARED MV;So;0;L;<square> 004D 0056;;;;N;;;;;
1F14C;SQUARED SD;So;0;L;<square> 0053 0044;;;;N;;;;;
1F14D;SQUARED SS;So;0;L;<square> 0053 0053;;;;N;;;;;
1F14E;SQUARED PPV;So;0;L;<square> 0050 0050 0056;;;;N;;;;;
+1F14F;SQUARED WC;So;0;L;<square> 0057 0043;;;;N;;;;;
+1F150;NEGATIVE CIRCLED LATIN CAPITAL LETTER A;So;0;L;;;;;N;;;;;
+1F151;NEGATIVE CIRCLED LATIN CAPITAL LETTER B;So;0;L;;;;;N;;;;;
+1F152;NEGATIVE CIRCLED LATIN CAPITAL LETTER C;So;0;L;;;;;N;;;;;
+1F153;NEGATIVE CIRCLED LATIN CAPITAL LETTER D;So;0;L;;;;;N;;;;;
+1F154;NEGATIVE CIRCLED LATIN CAPITAL LETTER E;So;0;L;;;;;N;;;;;
+1F155;NEGATIVE CIRCLED LATIN CAPITAL LETTER F;So;0;L;;;;;N;;;;;
+1F156;NEGATIVE CIRCLED LATIN CAPITAL LETTER G;So;0;L;;;;;N;;;;;
1F157;NEGATIVE CIRCLED LATIN CAPITAL LETTER H;So;0;L;;;;;N;;;;;
+1F158;NEGATIVE CIRCLED LATIN CAPITAL LETTER I;So;0;L;;;;;N;;;;;
+1F159;NEGATIVE CIRCLED LATIN CAPITAL LETTER J;So;0;L;;;;;N;;;;;
+1F15A;NEGATIVE CIRCLED LATIN CAPITAL LETTER K;So;0;L;;;;;N;;;;;
+1F15B;NEGATIVE CIRCLED LATIN CAPITAL LETTER L;So;0;L;;;;;N;;;;;
+1F15C;NEGATIVE CIRCLED LATIN CAPITAL LETTER M;So;0;L;;;;;N;;;;;
+1F15D;NEGATIVE CIRCLED LATIN CAPITAL LETTER N;So;0;L;;;;;N;;;;;
+1F15E;NEGATIVE CIRCLED LATIN CAPITAL LETTER O;So;0;L;;;;;N;;;;;
1F15F;NEGATIVE CIRCLED LATIN CAPITAL LETTER P;So;0;L;;;;;N;;;;;
+1F160;NEGATIVE CIRCLED LATIN CAPITAL LETTER Q;So;0;L;;;;;N;;;;;
+1F161;NEGATIVE CIRCLED LATIN CAPITAL LETTER R;So;0;L;;;;;N;;;;;
+1F162;NEGATIVE CIRCLED LATIN CAPITAL LETTER S;So;0;L;;;;;N;;;;;
+1F163;NEGATIVE CIRCLED LATIN CAPITAL LETTER T;So;0;L;;;;;N;;;;;
+1F164;NEGATIVE CIRCLED LATIN CAPITAL LETTER U;So;0;L;;;;;N;;;;;
+1F165;NEGATIVE CIRCLED LATIN CAPITAL LETTER V;So;0;L;;;;;N;;;;;
+1F166;NEGATIVE CIRCLED LATIN CAPITAL LETTER W;So;0;L;;;;;N;;;;;
+1F167;NEGATIVE CIRCLED LATIN CAPITAL LETTER X;So;0;L;;;;;N;;;;;
+1F168;NEGATIVE CIRCLED LATIN CAPITAL LETTER Y;So;0;L;;;;;N;;;;;
+1F169;NEGATIVE CIRCLED LATIN CAPITAL LETTER Z;So;0;L;;;;;N;;;;;
+1F16A;RAISED MC SIGN;So;0;ON;<super> 004D 0043;;;;N;;;;;
+1F16B;RAISED MD SIGN;So;0;ON;<super> 004D 0044;;;;N;;;;;
+1F170;NEGATIVE SQUARED LATIN CAPITAL LETTER A;So;0;L;;;;;N;;;;;
+1F171;NEGATIVE SQUARED LATIN CAPITAL LETTER B;So;0;L;;;;;N;;;;;
+1F172;NEGATIVE SQUARED LATIN CAPITAL LETTER C;So;0;L;;;;;N;;;;;
+1F173;NEGATIVE SQUARED LATIN CAPITAL LETTER D;So;0;L;;;;;N;;;;;
+1F174;NEGATIVE SQUARED LATIN CAPITAL LETTER E;So;0;L;;;;;N;;;;;
+1F175;NEGATIVE SQUARED LATIN CAPITAL LETTER F;So;0;L;;;;;N;;;;;
+1F176;NEGATIVE SQUARED LATIN CAPITAL LETTER G;So;0;L;;;;;N;;;;;
+1F177;NEGATIVE SQUARED LATIN CAPITAL LETTER H;So;0;L;;;;;N;;;;;
+1F178;NEGATIVE SQUARED LATIN CAPITAL LETTER I;So;0;L;;;;;N;;;;;
1F179;NEGATIVE SQUARED LATIN CAPITAL LETTER J;So;0;L;;;;;N;;;;;
+1F17A;NEGATIVE SQUARED LATIN CAPITAL LETTER K;So;0;L;;;;;N;;;;;
1F17B;NEGATIVE SQUARED LATIN CAPITAL LETTER L;So;0;L;;;;;N;;;;;
1F17C;NEGATIVE SQUARED LATIN CAPITAL LETTER M;So;0;L;;;;;N;;;;;
+1F17D;NEGATIVE SQUARED LATIN CAPITAL LETTER N;So;0;L;;;;;N;;;;;
+1F17E;NEGATIVE SQUARED LATIN CAPITAL LETTER O;So;0;L;;;;;N;;;;;
1F17F;NEGATIVE SQUARED LATIN CAPITAL LETTER P;So;0;L;;;;;N;;;;;
+1F180;NEGATIVE SQUARED LATIN CAPITAL LETTER Q;So;0;L;;;;;N;;;;;
+1F181;NEGATIVE SQUARED LATIN CAPITAL LETTER R;So;0;L;;;;;N;;;;;
+1F182;NEGATIVE SQUARED LATIN CAPITAL LETTER S;So;0;L;;;;;N;;;;;
+1F183;NEGATIVE SQUARED LATIN CAPITAL LETTER T;So;0;L;;;;;N;;;;;
+1F184;NEGATIVE SQUARED LATIN CAPITAL LETTER U;So;0;L;;;;;N;;;;;
+1F185;NEGATIVE SQUARED LATIN CAPITAL LETTER V;So;0;L;;;;;N;;;;;
+1F186;NEGATIVE SQUARED LATIN CAPITAL LETTER W;So;0;L;;;;;N;;;;;
+1F187;NEGATIVE SQUARED LATIN CAPITAL LETTER X;So;0;L;;;;;N;;;;;
+1F188;NEGATIVE SQUARED LATIN CAPITAL LETTER Y;So;0;L;;;;;N;;;;;
+1F189;NEGATIVE SQUARED LATIN CAPITAL LETTER Z;So;0;L;;;;;N;;;;;
1F18A;CROSSED NEGATIVE SQUARED LATIN CAPITAL LETTER P;So;0;L;;;;;N;;;;;
1F18B;NEGATIVE SQUARED IC;So;0;L;;;;;N;;;;;
1F18C;NEGATIVE SQUARED PA;So;0;L;;;;;N;;;;;
1F18D;NEGATIVE SQUARED SA;So;0;L;;;;;N;;;;;
+1F18E;NEGATIVE SQUARED AB;So;0;L;;;;;N;;;;;
+1F18F;NEGATIVE SQUARED WC;So;0;L;;;;;N;;;;;
1F190;SQUARE DJ;So;0;L;<square> 0044 004A;;;;N;;;;;
+1F191;SQUARED CL;So;0;L;;;;;N;;;;;
+1F192;SQUARED COOL;So;0;L;;;;;N;;;;;
+1F193;SQUARED FREE;So;0;L;;;;;N;;;;;
+1F194;SQUARED ID;So;0;L;;;;;N;;;;;
+1F195;SQUARED NEW;So;0;L;;;;;N;;;;;
+1F196;SQUARED NG;So;0;L;;;;;N;;;;;
+1F197;SQUARED OK;So;0;L;;;;;N;;;;;
+1F198;SQUARED SOS;So;0;L;;;;;N;;;;;
+1F199;SQUARED UP WITH EXCLAMATION MARK;So;0;L;;;;;N;;;;;
+1F19A;SQUARED VS;So;0;L;;;;;N;;;;;
+1F19B;SQUARED THREE D;So;0;L;;;;;N;;;;;
+1F19C;SQUARED SECOND SCREEN;So;0;L;;;;;N;;;;;
+1F19D;SQUARED TWO K;So;0;L;;;;;N;;;;;
+1F19E;SQUARED FOUR K;So;0;L;;;;;N;;;;;
+1F19F;SQUARED EIGHT K;So;0;L;;;;;N;;;;;
+1F1A0;SQUARED FIVE POINT ONE;So;0;L;;;;;N;;;;;
+1F1A1;SQUARED SEVEN POINT ONE;So;0;L;;;;;N;;;;;
+1F1A2;SQUARED TWENTY-TWO POINT TWO;So;0;L;;;;;N;;;;;
+1F1A3;SQUARED SIXTY P;So;0;L;;;;;N;;;;;
+1F1A4;SQUARED ONE HUNDRED TWENTY P;So;0;L;;;;;N;;;;;
+1F1A5;SQUARED LATIN SMALL LETTER D;So;0;L;;;;;N;;;;;
+1F1A6;SQUARED HC;So;0;L;;;;;N;;;;;
+1F1A7;SQUARED HDR;So;0;L;;;;;N;;;;;
+1F1A8;SQUARED HI-RES;So;0;L;;;;;N;;;;;
+1F1A9;SQUARED LOSSLESS;So;0;L;;;;;N;;;;;
+1F1AA;SQUARED SHV;So;0;L;;;;;N;;;;;
+1F1AB;SQUARED UHD;So;0;L;;;;;N;;;;;
+1F1AC;SQUARED VOD;So;0;L;;;;;N;;;;;
+1F1E6;REGIONAL INDICATOR SYMBOL LETTER A;So;0;L;;;;;N;;;;;
+1F1E7;REGIONAL INDICATOR SYMBOL LETTER B;So;0;L;;;;;N;;;;;
+1F1E8;REGIONAL INDICATOR SYMBOL LETTER C;So;0;L;;;;;N;;;;;
+1F1E9;REGIONAL INDICATOR SYMBOL LETTER D;So;0;L;;;;;N;;;;;
+1F1EA;REGIONAL INDICATOR SYMBOL LETTER E;So;0;L;;;;;N;;;;;
+1F1EB;REGIONAL INDICATOR SYMBOL LETTER F;So;0;L;;;;;N;;;;;
+1F1EC;REGIONAL INDICATOR SYMBOL LETTER G;So;0;L;;;;;N;;;;;
+1F1ED;REGIONAL INDICATOR SYMBOL LETTER H;So;0;L;;;;;N;;;;;
+1F1EE;REGIONAL INDICATOR SYMBOL LETTER I;So;0;L;;;;;N;;;;;
+1F1EF;REGIONAL INDICATOR SYMBOL LETTER J;So;0;L;;;;;N;;;;;
+1F1F0;REGIONAL INDICATOR SYMBOL LETTER K;So;0;L;;;;;N;;;;;
+1F1F1;REGIONAL INDICATOR SYMBOL LETTER L;So;0;L;;;;;N;;;;;
+1F1F2;REGIONAL INDICATOR SYMBOL LETTER M;So;0;L;;;;;N;;;;;
+1F1F3;REGIONAL INDICATOR SYMBOL LETTER N;So;0;L;;;;;N;;;;;
+1F1F4;REGIONAL INDICATOR SYMBOL LETTER O;So;0;L;;;;;N;;;;;
+1F1F5;REGIONAL INDICATOR SYMBOL LETTER P;So;0;L;;;;;N;;;;;
+1F1F6;REGIONAL INDICATOR SYMBOL LETTER Q;So;0;L;;;;;N;;;;;
+1F1F7;REGIONAL INDICATOR SYMBOL LETTER R;So;0;L;;;;;N;;;;;
+1F1F8;REGIONAL INDICATOR SYMBOL LETTER S;So;0;L;;;;;N;;;;;
+1F1F9;REGIONAL INDICATOR SYMBOL LETTER T;So;0;L;;;;;N;;;;;
+1F1FA;REGIONAL INDICATOR SYMBOL LETTER U;So;0;L;;;;;N;;;;;
+1F1FB;REGIONAL INDICATOR SYMBOL LETTER V;So;0;L;;;;;N;;;;;
+1F1FC;REGIONAL INDICATOR SYMBOL LETTER W;So;0;L;;;;;N;;;;;
+1F1FD;REGIONAL INDICATOR SYMBOL LETTER X;So;0;L;;;;;N;;;;;
+1F1FE;REGIONAL INDICATOR SYMBOL LETTER Y;So;0;L;;;;;N;;;;;
+1F1FF;REGIONAL INDICATOR SYMBOL LETTER Z;So;0;L;;;;;N;;;;;
1F200;SQUARE HIRAGANA HOKA;So;0;L;<square> 307B 304B;;;;N;;;;;
+1F201;SQUARED KATAKANA KOKO;So;0;L;<square> 30B3 30B3;;;;N;;;;;
+1F202;SQUARED KATAKANA SA;So;0;L;<square> 30B5;;;;N;;;;;
1F210;SQUARED CJK UNIFIED IDEOGRAPH-624B;So;0;L;<square> 624B;;;;N;;;;;
1F211;SQUARED CJK UNIFIED IDEOGRAPH-5B57;So;0;L;<square> 5B57;;;;N;;;;;
1F212;SQUARED CJK UNIFIED IDEOGRAPH-53CC;So;0;L;<square> 53CC;;;;N;;;;;
@@ -20931,6 +29196,16 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1F22F;SQUARED CJK UNIFIED IDEOGRAPH-6307;So;0;L;<square> 6307;;;;N;;;;;
1F230;SQUARED CJK UNIFIED IDEOGRAPH-8D70;So;0;L;<square> 8D70;;;;N;;;;;
1F231;SQUARED CJK UNIFIED IDEOGRAPH-6253;So;0;L;<square> 6253;;;;N;;;;;
+1F232;SQUARED CJK UNIFIED IDEOGRAPH-7981;So;0;L;<square> 7981;;;;N;;;;;
+1F233;SQUARED CJK UNIFIED IDEOGRAPH-7A7A;So;0;L;<square> 7A7A;;;;N;;;;;
+1F234;SQUARED CJK UNIFIED IDEOGRAPH-5408;So;0;L;<square> 5408;;;;N;;;;;
+1F235;SQUARED CJK UNIFIED IDEOGRAPH-6E80;So;0;L;<square> 6E80;;;;N;;;;;
+1F236;SQUARED CJK UNIFIED IDEOGRAPH-6709;So;0;L;<square> 6709;;;;N;;;;;
+1F237;SQUARED CJK UNIFIED IDEOGRAPH-6708;So;0;L;<square> 6708;;;;N;;;;;
+1F238;SQUARED CJK UNIFIED IDEOGRAPH-7533;So;0;L;<square> 7533;;;;N;;;;;
+1F239;SQUARED CJK UNIFIED IDEOGRAPH-5272;So;0;L;<square> 5272;;;;N;;;;;
+1F23A;SQUARED CJK UNIFIED IDEOGRAPH-55B6;So;0;L;<square> 55B6;;;;N;;;;;
+1F23B;SQUARED CJK UNIFIED IDEOGRAPH-914D;So;0;L;<square> 914D;;;;N;;;;;
1F240;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-672C;So;0;L;<compat> 3014 672C 3015;;;;N;;;;;
1F241;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-4E09;So;0;L;<compat> 3014 4E09 3015;;;;N;;;;;
1F242;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-4E8C;So;0;L;<compat> 3014 4E8C 3015;;;;N;;;;;
@@ -20940,10 +29215,1524 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1F246;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-76D7;So;0;L;<compat> 3014 76D7 3015;;;;N;;;;;
1F247;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-52DD;So;0;L;<compat> 3014 52DD 3015;;;;N;;;;;
1F248;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-6557;So;0;L;<compat> 3014 6557 3015;;;;N;;;;;
+1F250;CIRCLED IDEOGRAPH ADVANTAGE;So;0;L;<circle> 5F97;;;;N;;;;;
+1F251;CIRCLED IDEOGRAPH ACCEPT;So;0;L;<circle> 53EF;;;;N;;;;;
+1F260;ROUNDED SYMBOL FOR FU;So;0;ON;;;;;N;;;;;
+1F261;ROUNDED SYMBOL FOR LU;So;0;ON;;;;;N;;;;;
+1F262;ROUNDED SYMBOL FOR SHOU;So;0;ON;;;;;N;;;;;
+1F263;ROUNDED SYMBOL FOR XI;So;0;ON;;;;;N;;;;;
+1F264;ROUNDED SYMBOL FOR SHUANGXI;So;0;ON;;;;;N;;;;;
+1F265;ROUNDED SYMBOL FOR CAI;So;0;ON;;;;;N;;;;;
+1F300;CYCLONE;So;0;ON;;;;;N;;;;;
+1F301;FOGGY;So;0;ON;;;;;N;;;;;
+1F302;CLOSED UMBRELLA;So;0;ON;;;;;N;;;;;
+1F303;NIGHT WITH STARS;So;0;ON;;;;;N;;;;;
+1F304;SUNRISE OVER MOUNTAINS;So;0;ON;;;;;N;;;;;
+1F305;SUNRISE;So;0;ON;;;;;N;;;;;
+1F306;CITYSCAPE AT DUSK;So;0;ON;;;;;N;;;;;
+1F307;SUNSET OVER BUILDINGS;So;0;ON;;;;;N;;;;;
+1F308;RAINBOW;So;0;ON;;;;;N;;;;;
+1F309;BRIDGE AT NIGHT;So;0;ON;;;;;N;;;;;
+1F30A;WATER WAVE;So;0;ON;;;;;N;;;;;
+1F30B;VOLCANO;So;0;ON;;;;;N;;;;;
+1F30C;MILKY WAY;So;0;ON;;;;;N;;;;;
+1F30D;EARTH GLOBE EUROPE-AFRICA;So;0;ON;;;;;N;;;;;
+1F30E;EARTH GLOBE AMERICAS;So;0;ON;;;;;N;;;;;
+1F30F;EARTH GLOBE ASIA-AUSTRALIA;So;0;ON;;;;;N;;;;;
+1F310;GLOBE WITH MERIDIANS;So;0;ON;;;;;N;;;;;
+1F311;NEW MOON SYMBOL;So;0;ON;;;;;N;;;;;
+1F312;WAXING CRESCENT MOON SYMBOL;So;0;ON;;;;;N;;;;;
+1F313;FIRST QUARTER MOON SYMBOL;So;0;ON;;;;;N;;;;;
+1F314;WAXING GIBBOUS MOON SYMBOL;So;0;ON;;;;;N;;;;;
+1F315;FULL MOON SYMBOL;So;0;ON;;;;;N;;;;;
+1F316;WANING GIBBOUS MOON SYMBOL;So;0;ON;;;;;N;;;;;
+1F317;LAST QUARTER MOON SYMBOL;So;0;ON;;;;;N;;;;;
+1F318;WANING CRESCENT MOON SYMBOL;So;0;ON;;;;;N;;;;;
+1F319;CRESCENT MOON;So;0;ON;;;;;N;;;;;
+1F31A;NEW MOON WITH FACE;So;0;ON;;;;;N;;;;;
+1F31B;FIRST QUARTER MOON WITH FACE;So;0;ON;;;;;N;;;;;
+1F31C;LAST QUARTER MOON WITH FACE;So;0;ON;;;;;N;;;;;
+1F31D;FULL MOON WITH FACE;So;0;ON;;;;;N;;;;;
+1F31E;SUN WITH FACE;So;0;ON;;;;;N;;;;;
+1F31F;GLOWING STAR;So;0;ON;;;;;N;;;;;
+1F320;SHOOTING STAR;So;0;ON;;;;;N;;;;;
+1F321;THERMOMETER;So;0;ON;;;;;N;;;;;
+1F322;BLACK DROPLET;So;0;ON;;;;;N;;;;;
+1F323;WHITE SUN;So;0;ON;;;;;N;;;;;
+1F324;WHITE SUN WITH SMALL CLOUD;So;0;ON;;;;;N;;;;;
+1F325;WHITE SUN BEHIND CLOUD;So;0;ON;;;;;N;;;;;
+1F326;WHITE SUN BEHIND CLOUD WITH RAIN;So;0;ON;;;;;N;;;;;
+1F327;CLOUD WITH RAIN;So;0;ON;;;;;N;;;;;
+1F328;CLOUD WITH SNOW;So;0;ON;;;;;N;;;;;
+1F329;CLOUD WITH LIGHTNING;So;0;ON;;;;;N;;;;;
+1F32A;CLOUD WITH TORNADO;So;0;ON;;;;;N;;;;;
+1F32B;FOG;So;0;ON;;;;;N;;;;;
+1F32C;WIND BLOWING FACE;So;0;ON;;;;;N;;;;;
+1F32D;HOT DOG;So;0;ON;;;;;N;;;;;
+1F32E;TACO;So;0;ON;;;;;N;;;;;
+1F32F;BURRITO;So;0;ON;;;;;N;;;;;
+1F330;CHESTNUT;So;0;ON;;;;;N;;;;;
+1F331;SEEDLING;So;0;ON;;;;;N;;;;;
+1F332;EVERGREEN TREE;So;0;ON;;;;;N;;;;;
+1F333;DECIDUOUS TREE;So;0;ON;;;;;N;;;;;
+1F334;PALM TREE;So;0;ON;;;;;N;;;;;
+1F335;CACTUS;So;0;ON;;;;;N;;;;;
+1F336;HOT PEPPER;So;0;ON;;;;;N;;;;;
+1F337;TULIP;So;0;ON;;;;;N;;;;;
+1F338;CHERRY BLOSSOM;So;0;ON;;;;;N;;;;;
+1F339;ROSE;So;0;ON;;;;;N;;;;;
+1F33A;HIBISCUS;So;0;ON;;;;;N;;;;;
+1F33B;SUNFLOWER;So;0;ON;;;;;N;;;;;
+1F33C;BLOSSOM;So;0;ON;;;;;N;;;;;
+1F33D;EAR OF MAIZE;So;0;ON;;;;;N;;;;;
+1F33E;EAR OF RICE;So;0;ON;;;;;N;;;;;
+1F33F;HERB;So;0;ON;;;;;N;;;;;
+1F340;FOUR LEAF CLOVER;So;0;ON;;;;;N;;;;;
+1F341;MAPLE LEAF;So;0;ON;;;;;N;;;;;
+1F342;FALLEN LEAF;So;0;ON;;;;;N;;;;;
+1F343;LEAF FLUTTERING IN WIND;So;0;ON;;;;;N;;;;;
+1F344;MUSHROOM;So;0;ON;;;;;N;;;;;
+1F345;TOMATO;So;0;ON;;;;;N;;;;;
+1F346;AUBERGINE;So;0;ON;;;;;N;;;;;
+1F347;GRAPES;So;0;ON;;;;;N;;;;;
+1F348;MELON;So;0;ON;;;;;N;;;;;
+1F349;WATERMELON;So;0;ON;;;;;N;;;;;
+1F34A;TANGERINE;So;0;ON;;;;;N;;;;;
+1F34B;LEMON;So;0;ON;;;;;N;;;;;
+1F34C;BANANA;So;0;ON;;;;;N;;;;;
+1F34D;PINEAPPLE;So;0;ON;;;;;N;;;;;
+1F34E;RED APPLE;So;0;ON;;;;;N;;;;;
+1F34F;GREEN APPLE;So;0;ON;;;;;N;;;;;
+1F350;PEAR;So;0;ON;;;;;N;;;;;
+1F351;PEACH;So;0;ON;;;;;N;;;;;
+1F352;CHERRIES;So;0;ON;;;;;N;;;;;
+1F353;STRAWBERRY;So;0;ON;;;;;N;;;;;
+1F354;HAMBURGER;So;0;ON;;;;;N;;;;;
+1F355;SLICE OF PIZZA;So;0;ON;;;;;N;;;;;
+1F356;MEAT ON BONE;So;0;ON;;;;;N;;;;;
+1F357;POULTRY LEG;So;0;ON;;;;;N;;;;;
+1F358;RICE CRACKER;So;0;ON;;;;;N;;;;;
+1F359;RICE BALL;So;0;ON;;;;;N;;;;;
+1F35A;COOKED RICE;So;0;ON;;;;;N;;;;;
+1F35B;CURRY AND RICE;So;0;ON;;;;;N;;;;;
+1F35C;STEAMING BOWL;So;0;ON;;;;;N;;;;;
+1F35D;SPAGHETTI;So;0;ON;;;;;N;;;;;
+1F35E;BREAD;So;0;ON;;;;;N;;;;;
+1F35F;FRENCH FRIES;So;0;ON;;;;;N;;;;;
+1F360;ROASTED SWEET POTATO;So;0;ON;;;;;N;;;;;
+1F361;DANGO;So;0;ON;;;;;N;;;;;
+1F362;ODEN;So;0;ON;;;;;N;;;;;
+1F363;SUSHI;So;0;ON;;;;;N;;;;;
+1F364;FRIED SHRIMP;So;0;ON;;;;;N;;;;;
+1F365;FISH CAKE WITH SWIRL DESIGN;So;0;ON;;;;;N;;;;;
+1F366;SOFT ICE CREAM;So;0;ON;;;;;N;;;;;
+1F367;SHAVED ICE;So;0;ON;;;;;N;;;;;
+1F368;ICE CREAM;So;0;ON;;;;;N;;;;;
+1F369;DOUGHNUT;So;0;ON;;;;;N;;;;;
+1F36A;COOKIE;So;0;ON;;;;;N;;;;;
+1F36B;CHOCOLATE BAR;So;0;ON;;;;;N;;;;;
+1F36C;CANDY;So;0;ON;;;;;N;;;;;
+1F36D;LOLLIPOP;So;0;ON;;;;;N;;;;;
+1F36E;CUSTARD;So;0;ON;;;;;N;;;;;
+1F36F;HONEY POT;So;0;ON;;;;;N;;;;;
+1F370;SHORTCAKE;So;0;ON;;;;;N;;;;;
+1F371;BENTO BOX;So;0;ON;;;;;N;;;;;
+1F372;POT OF FOOD;So;0;ON;;;;;N;;;;;
+1F373;COOKING;So;0;ON;;;;;N;;;;;
+1F374;FORK AND KNIFE;So;0;ON;;;;;N;;;;;
+1F375;TEACUP WITHOUT HANDLE;So;0;ON;;;;;N;;;;;
+1F376;SAKE BOTTLE AND CUP;So;0;ON;;;;;N;;;;;
+1F377;WINE GLASS;So;0;ON;;;;;N;;;;;
+1F378;COCKTAIL GLASS;So;0;ON;;;;;N;;;;;
+1F379;TROPICAL DRINK;So;0;ON;;;;;N;;;;;
+1F37A;BEER MUG;So;0;ON;;;;;N;;;;;
+1F37B;CLINKING BEER MUGS;So;0;ON;;;;;N;;;;;
+1F37C;BABY BOTTLE;So;0;ON;;;;;N;;;;;
+1F37D;FORK AND KNIFE WITH PLATE;So;0;ON;;;;;N;;;;;
+1F37E;BOTTLE WITH POPPING CORK;So;0;ON;;;;;N;;;;;
+1F37F;POPCORN;So;0;ON;;;;;N;;;;;
+1F380;RIBBON;So;0;ON;;;;;N;;;;;
+1F381;WRAPPED PRESENT;So;0;ON;;;;;N;;;;;
+1F382;BIRTHDAY CAKE;So;0;ON;;;;;N;;;;;
+1F383;JACK-O-LANTERN;So;0;ON;;;;;N;;;;;
+1F384;CHRISTMAS TREE;So;0;ON;;;;;N;;;;;
+1F385;FATHER CHRISTMAS;So;0;ON;;;;;N;;;;;
+1F386;FIREWORKS;So;0;ON;;;;;N;;;;;
+1F387;FIREWORK SPARKLER;So;0;ON;;;;;N;;;;;
+1F388;BALLOON;So;0;ON;;;;;N;;;;;
+1F389;PARTY POPPER;So;0;ON;;;;;N;;;;;
+1F38A;CONFETTI BALL;So;0;ON;;;;;N;;;;;
+1F38B;TANABATA TREE;So;0;ON;;;;;N;;;;;
+1F38C;CROSSED FLAGS;So;0;ON;;;;;N;;;;;
+1F38D;PINE DECORATION;So;0;ON;;;;;N;;;;;
+1F38E;JAPANESE DOLLS;So;0;ON;;;;;N;;;;;
+1F38F;CARP STREAMER;So;0;ON;;;;;N;;;;;
+1F390;WIND CHIME;So;0;ON;;;;;N;;;;;
+1F391;MOON VIEWING CEREMONY;So;0;ON;;;;;N;;;;;
+1F392;SCHOOL SATCHEL;So;0;ON;;;;;N;;;;;
+1F393;GRADUATION CAP;So;0;ON;;;;;N;;;;;
+1F394;HEART WITH TIP ON THE LEFT;So;0;ON;;;;;N;;;;;
+1F395;BOUQUET OF FLOWERS;So;0;ON;;;;;N;;;;;
+1F396;MILITARY MEDAL;So;0;ON;;;;;N;;;;;
+1F397;REMINDER RIBBON;So;0;ON;;;;;N;;;;;
+1F398;MUSICAL KEYBOARD WITH JACKS;So;0;ON;;;;;N;;;;;
+1F399;STUDIO MICROPHONE;So;0;ON;;;;;N;;;;;
+1F39A;LEVEL SLIDER;So;0;ON;;;;;N;;;;;
+1F39B;CONTROL KNOBS;So;0;ON;;;;;N;;;;;
+1F39C;BEAMED ASCENDING MUSICAL NOTES;So;0;ON;;;;;N;;;;;
+1F39D;BEAMED DESCENDING MUSICAL NOTES;So;0;ON;;;;;N;;;;;
+1F39E;FILM FRAMES;So;0;ON;;;;;N;;;;;
+1F39F;ADMISSION TICKETS;So;0;ON;;;;;N;;;;;
+1F3A0;CAROUSEL HORSE;So;0;ON;;;;;N;;;;;
+1F3A1;FERRIS WHEEL;So;0;ON;;;;;N;;;;;
+1F3A2;ROLLER COASTER;So;0;ON;;;;;N;;;;;
+1F3A3;FISHING POLE AND FISH;So;0;ON;;;;;N;;;;;
+1F3A4;MICROPHONE;So;0;ON;;;;;N;;;;;
+1F3A5;MOVIE CAMERA;So;0;ON;;;;;N;;;;;
+1F3A6;CINEMA;So;0;ON;;;;;N;;;;;
+1F3A7;HEADPHONE;So;0;ON;;;;;N;;;;;
+1F3A8;ARTIST PALETTE;So;0;ON;;;;;N;;;;;
+1F3A9;TOP HAT;So;0;ON;;;;;N;;;;;
+1F3AA;CIRCUS TENT;So;0;ON;;;;;N;;;;;
+1F3AB;TICKET;So;0;ON;;;;;N;;;;;
+1F3AC;CLAPPER BOARD;So;0;ON;;;;;N;;;;;
+1F3AD;PERFORMING ARTS;So;0;ON;;;;;N;;;;;
+1F3AE;VIDEO GAME;So;0;ON;;;;;N;;;;;
+1F3AF;DIRECT HIT;So;0;ON;;;;;N;;;;;
+1F3B0;SLOT MACHINE;So;0;ON;;;;;N;;;;;
+1F3B1;BILLIARDS;So;0;ON;;;;;N;;;;;
+1F3B2;GAME DIE;So;0;ON;;;;;N;;;;;
+1F3B3;BOWLING;So;0;ON;;;;;N;;;;;
+1F3B4;FLOWER PLAYING CARDS;So;0;ON;;;;;N;;;;;
+1F3B5;MUSICAL NOTE;So;0;ON;;;;;N;;;;;
+1F3B6;MULTIPLE MUSICAL NOTES;So;0;ON;;;;;N;;;;;
+1F3B7;SAXOPHONE;So;0;ON;;;;;N;;;;;
+1F3B8;GUITAR;So;0;ON;;;;;N;;;;;
+1F3B9;MUSICAL KEYBOARD;So;0;ON;;;;;N;;;;;
+1F3BA;TRUMPET;So;0;ON;;;;;N;;;;;
+1F3BB;VIOLIN;So;0;ON;;;;;N;;;;;
+1F3BC;MUSICAL SCORE;So;0;ON;;;;;N;;;;;
+1F3BD;RUNNING SHIRT WITH SASH;So;0;ON;;;;;N;;;;;
+1F3BE;TENNIS RACQUET AND BALL;So;0;ON;;;;;N;;;;;
+1F3BF;SKI AND SKI BOOT;So;0;ON;;;;;N;;;;;
+1F3C0;BASKETBALL AND HOOP;So;0;ON;;;;;N;;;;;
+1F3C1;CHEQUERED FLAG;So;0;ON;;;;;N;;;;;
+1F3C2;SNOWBOARDER;So;0;ON;;;;;N;;;;;
+1F3C3;RUNNER;So;0;ON;;;;;N;;;;;
+1F3C4;SURFER;So;0;ON;;;;;N;;;;;
+1F3C5;SPORTS MEDAL;So;0;ON;;;;;N;;;;;
+1F3C6;TROPHY;So;0;ON;;;;;N;;;;;
+1F3C7;HORSE RACING;So;0;ON;;;;;N;;;;;
+1F3C8;AMERICAN FOOTBALL;So;0;ON;;;;;N;;;;;
+1F3C9;RUGBY FOOTBALL;So;0;ON;;;;;N;;;;;
+1F3CA;SWIMMER;So;0;ON;;;;;N;;;;;
+1F3CB;WEIGHT LIFTER;So;0;ON;;;;;N;;;;;
+1F3CC;GOLFER;So;0;ON;;;;;N;;;;;
+1F3CD;RACING MOTORCYCLE;So;0;ON;;;;;N;;;;;
+1F3CE;RACING CAR;So;0;ON;;;;;N;;;;;
+1F3CF;CRICKET BAT AND BALL;So;0;ON;;;;;N;;;;;
+1F3D0;VOLLEYBALL;So;0;ON;;;;;N;;;;;
+1F3D1;FIELD HOCKEY STICK AND BALL;So;0;ON;;;;;N;;;;;
+1F3D2;ICE HOCKEY STICK AND PUCK;So;0;ON;;;;;N;;;;;
+1F3D3;TABLE TENNIS PADDLE AND BALL;So;0;ON;;;;;N;;;;;
+1F3D4;SNOW CAPPED MOUNTAIN;So;0;ON;;;;;N;;;;;
+1F3D5;CAMPING;So;0;ON;;;;;N;;;;;
+1F3D6;BEACH WITH UMBRELLA;So;0;ON;;;;;N;;;;;
+1F3D7;BUILDING CONSTRUCTION;So;0;ON;;;;;N;;;;;
+1F3D8;HOUSE BUILDINGS;So;0;ON;;;;;N;;;;;
+1F3D9;CITYSCAPE;So;0;ON;;;;;N;;;;;
+1F3DA;DERELICT HOUSE BUILDING;So;0;ON;;;;;N;;;;;
+1F3DB;CLASSICAL BUILDING;So;0;ON;;;;;N;;;;;
+1F3DC;DESERT;So;0;ON;;;;;N;;;;;
+1F3DD;DESERT ISLAND;So;0;ON;;;;;N;;;;;
+1F3DE;NATIONAL PARK;So;0;ON;;;;;N;;;;;
+1F3DF;STADIUM;So;0;ON;;;;;N;;;;;
+1F3E0;HOUSE BUILDING;So;0;ON;;;;;N;;;;;
+1F3E1;HOUSE WITH GARDEN;So;0;ON;;;;;N;;;;;
+1F3E2;OFFICE BUILDING;So;0;ON;;;;;N;;;;;
+1F3E3;JAPANESE POST OFFICE;So;0;ON;;;;;N;;;;;
+1F3E4;EUROPEAN POST OFFICE;So;0;ON;;;;;N;;;;;
+1F3E5;HOSPITAL;So;0;ON;;;;;N;;;;;
+1F3E6;BANK;So;0;ON;;;;;N;;;;;
+1F3E7;AUTOMATED TELLER MACHINE;So;0;ON;;;;;N;;;;;
+1F3E8;HOTEL;So;0;ON;;;;;N;;;;;
+1F3E9;LOVE HOTEL;So;0;ON;;;;;N;;;;;
+1F3EA;CONVENIENCE STORE;So;0;ON;;;;;N;;;;;
+1F3EB;SCHOOL;So;0;ON;;;;;N;;;;;
+1F3EC;DEPARTMENT STORE;So;0;ON;;;;;N;;;;;
+1F3ED;FACTORY;So;0;ON;;;;;N;;;;;
+1F3EE;IZAKAYA LANTERN;So;0;ON;;;;;N;;;;;
+1F3EF;JAPANESE CASTLE;So;0;ON;;;;;N;;;;;
+1F3F0;EUROPEAN CASTLE;So;0;ON;;;;;N;;;;;
+1F3F1;WHITE PENNANT;So;0;ON;;;;;N;;;;;
+1F3F2;BLACK PENNANT;So;0;ON;;;;;N;;;;;
+1F3F3;WAVING WHITE FLAG;So;0;ON;;;;;N;;;;;
+1F3F4;WAVING BLACK FLAG;So;0;ON;;;;;N;;;;;
+1F3F5;ROSETTE;So;0;ON;;;;;N;;;;;
+1F3F6;BLACK ROSETTE;So;0;ON;;;;;N;;;;;
+1F3F7;LABEL;So;0;ON;;;;;N;;;;;
+1F3F8;BADMINTON RACQUET AND SHUTTLECOCK;So;0;ON;;;;;N;;;;;
+1F3F9;BOW AND ARROW;So;0;ON;;;;;N;;;;;
+1F3FA;AMPHORA;So;0;ON;;;;;N;;;;;
+1F3FB;EMOJI MODIFIER FITZPATRICK TYPE-1-2;Sk;0;ON;;;;;N;;;;;
+1F3FC;EMOJI MODIFIER FITZPATRICK TYPE-3;Sk;0;ON;;;;;N;;;;;
+1F3FD;EMOJI MODIFIER FITZPATRICK TYPE-4;Sk;0;ON;;;;;N;;;;;
+1F3FE;EMOJI MODIFIER FITZPATRICK TYPE-5;Sk;0;ON;;;;;N;;;;;
+1F3FF;EMOJI MODIFIER FITZPATRICK TYPE-6;Sk;0;ON;;;;;N;;;;;
+1F400;RAT;So;0;ON;;;;;N;;;;;
+1F401;MOUSE;So;0;ON;;;;;N;;;;;
+1F402;OX;So;0;ON;;;;;N;;;;;
+1F403;WATER BUFFALO;So;0;ON;;;;;N;;;;;
+1F404;COW;So;0;ON;;;;;N;;;;;
+1F405;TIGER;So;0;ON;;;;;N;;;;;
+1F406;LEOPARD;So;0;ON;;;;;N;;;;;
+1F407;RABBIT;So;0;ON;;;;;N;;;;;
+1F408;CAT;So;0;ON;;;;;N;;;;;
+1F409;DRAGON;So;0;ON;;;;;N;;;;;
+1F40A;CROCODILE;So;0;ON;;;;;N;;;;;
+1F40B;WHALE;So;0;ON;;;;;N;;;;;
+1F40C;SNAIL;So;0;ON;;;;;N;;;;;
+1F40D;SNAKE;So;0;ON;;;;;N;;;;;
+1F40E;HORSE;So;0;ON;;;;;N;;;;;
+1F40F;RAM;So;0;ON;;;;;N;;;;;
+1F410;GOAT;So;0;ON;;;;;N;;;;;
+1F411;SHEEP;So;0;ON;;;;;N;;;;;
+1F412;MONKEY;So;0;ON;;;;;N;;;;;
+1F413;ROOSTER;So;0;ON;;;;;N;;;;;
+1F414;CHICKEN;So;0;ON;;;;;N;;;;;
+1F415;DOG;So;0;ON;;;;;N;;;;;
+1F416;PIG;So;0;ON;;;;;N;;;;;
+1F417;BOAR;So;0;ON;;;;;N;;;;;
+1F418;ELEPHANT;So;0;ON;;;;;N;;;;;
+1F419;OCTOPUS;So;0;ON;;;;;N;;;;;
+1F41A;SPIRAL SHELL;So;0;ON;;;;;N;;;;;
+1F41B;BUG;So;0;ON;;;;;N;;;;;
+1F41C;ANT;So;0;ON;;;;;N;;;;;
+1F41D;HONEYBEE;So;0;ON;;;;;N;;;;;
+1F41E;LADY BEETLE;So;0;ON;;;;;N;;;;;
+1F41F;FISH;So;0;ON;;;;;N;;;;;
+1F420;TROPICAL FISH;So;0;ON;;;;;N;;;;;
+1F421;BLOWFISH;So;0;ON;;;;;N;;;;;
+1F422;TURTLE;So;0;ON;;;;;N;;;;;
+1F423;HATCHING CHICK;So;0;ON;;;;;N;;;;;
+1F424;BABY CHICK;So;0;ON;;;;;N;;;;;
+1F425;FRONT-FACING BABY CHICK;So;0;ON;;;;;N;;;;;
+1F426;BIRD;So;0;ON;;;;;N;;;;;
+1F427;PENGUIN;So;0;ON;;;;;N;;;;;
+1F428;KOALA;So;0;ON;;;;;N;;;;;
+1F429;POODLE;So;0;ON;;;;;N;;;;;
+1F42A;DROMEDARY CAMEL;So;0;ON;;;;;N;;;;;
+1F42B;BACTRIAN CAMEL;So;0;ON;;;;;N;;;;;
+1F42C;DOLPHIN;So;0;ON;;;;;N;;;;;
+1F42D;MOUSE FACE;So;0;ON;;;;;N;;;;;
+1F42E;COW FACE;So;0;ON;;;;;N;;;;;
+1F42F;TIGER FACE;So;0;ON;;;;;N;;;;;
+1F430;RABBIT FACE;So;0;ON;;;;;N;;;;;
+1F431;CAT FACE;So;0;ON;;;;;N;;;;;
+1F432;DRAGON FACE;So;0;ON;;;;;N;;;;;
+1F433;SPOUTING WHALE;So;0;ON;;;;;N;;;;;
+1F434;HORSE FACE;So;0;ON;;;;;N;;;;;
+1F435;MONKEY FACE;So;0;ON;;;;;N;;;;;
+1F436;DOG FACE;So;0;ON;;;;;N;;;;;
+1F437;PIG FACE;So;0;ON;;;;;N;;;;;
+1F438;FROG FACE;So;0;ON;;;;;N;;;;;
+1F439;HAMSTER FACE;So;0;ON;;;;;N;;;;;
+1F43A;WOLF FACE;So;0;ON;;;;;N;;;;;
+1F43B;BEAR FACE;So;0;ON;;;;;N;;;;;
+1F43C;PANDA FACE;So;0;ON;;;;;N;;;;;
+1F43D;PIG NOSE;So;0;ON;;;;;N;;;;;
+1F43E;PAW PRINTS;So;0;ON;;;;;N;;;;;
+1F43F;CHIPMUNK;So;0;ON;;;;;N;;;;;
+1F440;EYES;So;0;ON;;;;;N;;;;;
+1F441;EYE;So;0;ON;;;;;N;;;;;
+1F442;EAR;So;0;ON;;;;;N;;;;;
+1F443;NOSE;So;0;ON;;;;;N;;;;;
+1F444;MOUTH;So;0;ON;;;;;N;;;;;
+1F445;TONGUE;So;0;ON;;;;;N;;;;;
+1F446;WHITE UP POINTING BACKHAND INDEX;So;0;ON;;;;;N;;;;;
+1F447;WHITE DOWN POINTING BACKHAND INDEX;So;0;ON;;;;;N;;;;;
+1F448;WHITE LEFT POINTING BACKHAND INDEX;So;0;ON;;;;;N;;;;;
+1F449;WHITE RIGHT POINTING BACKHAND INDEX;So;0;ON;;;;;N;;;;;
+1F44A;FISTED HAND SIGN;So;0;ON;;;;;N;;;;;
+1F44B;WAVING HAND SIGN;So;0;ON;;;;;N;;;;;
+1F44C;OK HAND SIGN;So;0;ON;;;;;N;;;;;
+1F44D;THUMBS UP SIGN;So;0;ON;;;;;N;;;;;
+1F44E;THUMBS DOWN SIGN;So;0;ON;;;;;N;;;;;
+1F44F;CLAPPING HANDS SIGN;So;0;ON;;;;;N;;;;;
+1F450;OPEN HANDS SIGN;So;0;ON;;;;;N;;;;;
+1F451;CROWN;So;0;ON;;;;;N;;;;;
+1F452;WOMANS HAT;So;0;ON;;;;;N;;;;;
+1F453;EYEGLASSES;So;0;ON;;;;;N;;;;;
+1F454;NECKTIE;So;0;ON;;;;;N;;;;;
+1F455;T-SHIRT;So;0;ON;;;;;N;;;;;
+1F456;JEANS;So;0;ON;;;;;N;;;;;
+1F457;DRESS;So;0;ON;;;;;N;;;;;
+1F458;KIMONO;So;0;ON;;;;;N;;;;;
+1F459;BIKINI;So;0;ON;;;;;N;;;;;
+1F45A;WOMANS CLOTHES;So;0;ON;;;;;N;;;;;
+1F45B;PURSE;So;0;ON;;;;;N;;;;;
+1F45C;HANDBAG;So;0;ON;;;;;N;;;;;
+1F45D;POUCH;So;0;ON;;;;;N;;;;;
+1F45E;MANS SHOE;So;0;ON;;;;;N;;;;;
+1F45F;ATHLETIC SHOE;So;0;ON;;;;;N;;;;;
+1F460;HIGH-HEELED SHOE;So;0;ON;;;;;N;;;;;
+1F461;WOMANS SANDAL;So;0;ON;;;;;N;;;;;
+1F462;WOMANS BOOTS;So;0;ON;;;;;N;;;;;
+1F463;FOOTPRINTS;So;0;ON;;;;;N;;;;;
+1F464;BUST IN SILHOUETTE;So;0;ON;;;;;N;;;;;
+1F465;BUSTS IN SILHOUETTE;So;0;ON;;;;;N;;;;;
+1F466;BOY;So;0;ON;;;;;N;;;;;
+1F467;GIRL;So;0;ON;;;;;N;;;;;
+1F468;MAN;So;0;ON;;;;;N;;;;;
+1F469;WOMAN;So;0;ON;;;;;N;;;;;
+1F46A;FAMILY;So;0;ON;;;;;N;;;;;
+1F46B;MAN AND WOMAN HOLDING HANDS;So;0;ON;;;;;N;;;;;
+1F46C;TWO MEN HOLDING HANDS;So;0;ON;;;;;N;;;;;
+1F46D;TWO WOMEN HOLDING HANDS;So;0;ON;;;;;N;;;;;
+1F46E;POLICE OFFICER;So;0;ON;;;;;N;;;;;
+1F46F;WOMAN WITH BUNNY EARS;So;0;ON;;;;;N;;;;;
+1F470;BRIDE WITH VEIL;So;0;ON;;;;;N;;;;;
+1F471;PERSON WITH BLOND HAIR;So;0;ON;;;;;N;;;;;
+1F472;MAN WITH GUA PI MAO;So;0;ON;;;;;N;;;;;
+1F473;MAN WITH TURBAN;So;0;ON;;;;;N;;;;;
+1F474;OLDER MAN;So;0;ON;;;;;N;;;;;
+1F475;OLDER WOMAN;So;0;ON;;;;;N;;;;;
+1F476;BABY;So;0;ON;;;;;N;;;;;
+1F477;CONSTRUCTION WORKER;So;0;ON;;;;;N;;;;;
+1F478;PRINCESS;So;0;ON;;;;;N;;;;;
+1F479;JAPANESE OGRE;So;0;ON;;;;;N;;;;;
+1F47A;JAPANESE GOBLIN;So;0;ON;;;;;N;;;;;
+1F47B;GHOST;So;0;ON;;;;;N;;;;;
+1F47C;BABY ANGEL;So;0;ON;;;;;N;;;;;
+1F47D;EXTRATERRESTRIAL ALIEN;So;0;ON;;;;;N;;;;;
+1F47E;ALIEN MONSTER;So;0;ON;;;;;N;;;;;
+1F47F;IMP;So;0;ON;;;;;N;;;;;
+1F480;SKULL;So;0;ON;;;;;N;;;;;
+1F481;INFORMATION DESK PERSON;So;0;ON;;;;;N;;;;;
+1F482;GUARDSMAN;So;0;ON;;;;;N;;;;;
+1F483;DANCER;So;0;ON;;;;;N;;;;;
+1F484;LIPSTICK;So;0;ON;;;;;N;;;;;
+1F485;NAIL POLISH;So;0;ON;;;;;N;;;;;
+1F486;FACE MASSAGE;So;0;ON;;;;;N;;;;;
+1F487;HAIRCUT;So;0;ON;;;;;N;;;;;
+1F488;BARBER POLE;So;0;ON;;;;;N;;;;;
+1F489;SYRINGE;So;0;ON;;;;;N;;;;;
+1F48A;PILL;So;0;ON;;;;;N;;;;;
+1F48B;KISS MARK;So;0;ON;;;;;N;;;;;
+1F48C;LOVE LETTER;So;0;ON;;;;;N;;;;;
+1F48D;RING;So;0;ON;;;;;N;;;;;
+1F48E;GEM STONE;So;0;ON;;;;;N;;;;;
+1F48F;KISS;So;0;ON;;;;;N;;;;;
+1F490;BOUQUET;So;0;ON;;;;;N;;;;;
+1F491;COUPLE WITH HEART;So;0;ON;;;;;N;;;;;
+1F492;WEDDING;So;0;ON;;;;;N;;;;;
+1F493;BEATING HEART;So;0;ON;;;;;N;;;;;
+1F494;BROKEN HEART;So;0;ON;;;;;N;;;;;
+1F495;TWO HEARTS;So;0;ON;;;;;N;;;;;
+1F496;SPARKLING HEART;So;0;ON;;;;;N;;;;;
+1F497;GROWING HEART;So;0;ON;;;;;N;;;;;
+1F498;HEART WITH ARROW;So;0;ON;;;;;N;;;;;
+1F499;BLUE HEART;So;0;ON;;;;;N;;;;;
+1F49A;GREEN HEART;So;0;ON;;;;;N;;;;;
+1F49B;YELLOW HEART;So;0;ON;;;;;N;;;;;
+1F49C;PURPLE HEART;So;0;ON;;;;;N;;;;;
+1F49D;HEART WITH RIBBON;So;0;ON;;;;;N;;;;;
+1F49E;REVOLVING HEARTS;So;0;ON;;;;;N;;;;;
+1F49F;HEART DECORATION;So;0;ON;;;;;N;;;;;
+1F4A0;DIAMOND SHAPE WITH A DOT INSIDE;So;0;ON;;;;;N;;;;;
+1F4A1;ELECTRIC LIGHT BULB;So;0;ON;;;;;N;;;;;
+1F4A2;ANGER SYMBOL;So;0;ON;;;;;N;;;;;
+1F4A3;BOMB;So;0;ON;;;;;N;;;;;
+1F4A4;SLEEPING SYMBOL;So;0;ON;;;;;N;;;;;
+1F4A5;COLLISION SYMBOL;So;0;ON;;;;;N;;;;;
+1F4A6;SPLASHING SWEAT SYMBOL;So;0;ON;;;;;N;;;;;
+1F4A7;DROPLET;So;0;ON;;;;;N;;;;;
+1F4A8;DASH SYMBOL;So;0;ON;;;;;N;;;;;
+1F4A9;PILE OF POO;So;0;ON;;;;;N;;;;;
+1F4AA;FLEXED BICEPS;So;0;ON;;;;;N;;;;;
+1F4AB;DIZZY SYMBOL;So;0;ON;;;;;N;;;;;
+1F4AC;SPEECH BALLOON;So;0;ON;;;;;N;;;;;
+1F4AD;THOUGHT BALLOON;So;0;ON;;;;;N;;;;;
+1F4AE;WHITE FLOWER;So;0;ON;;;;;N;;;;;
+1F4AF;HUNDRED POINTS SYMBOL;So;0;ON;;;;;N;;;;;
+1F4B0;MONEY BAG;So;0;ON;;;;;N;;;;;
+1F4B1;CURRENCY EXCHANGE;So;0;ON;;;;;N;;;;;
+1F4B2;HEAVY DOLLAR SIGN;So;0;ON;;;;;N;;;;;
+1F4B3;CREDIT CARD;So;0;ON;;;;;N;;;;;
+1F4B4;BANKNOTE WITH YEN SIGN;So;0;ON;;;;;N;;;;;
+1F4B5;BANKNOTE WITH DOLLAR SIGN;So;0;ON;;;;;N;;;;;
+1F4B6;BANKNOTE WITH EURO SIGN;So;0;ON;;;;;N;;;;;
+1F4B7;BANKNOTE WITH POUND SIGN;So;0;ON;;;;;N;;;;;
+1F4B8;MONEY WITH WINGS;So;0;ON;;;;;N;;;;;
+1F4B9;CHART WITH UPWARDS TREND AND YEN SIGN;So;0;ON;;;;;N;;;;;
+1F4BA;SEAT;So;0;ON;;;;;N;;;;;
+1F4BB;PERSONAL COMPUTER;So;0;ON;;;;;N;;;;;
+1F4BC;BRIEFCASE;So;0;ON;;;;;N;;;;;
+1F4BD;MINIDISC;So;0;ON;;;;;N;;;;;
+1F4BE;FLOPPY DISK;So;0;ON;;;;;N;;;;;
+1F4BF;OPTICAL DISC;So;0;ON;;;;;N;;;;;
+1F4C0;DVD;So;0;ON;;;;;N;;;;;
+1F4C1;FILE FOLDER;So;0;ON;;;;;N;;;;;
+1F4C2;OPEN FILE FOLDER;So;0;ON;;;;;N;;;;;
+1F4C3;PAGE WITH CURL;So;0;ON;;;;;N;;;;;
+1F4C4;PAGE FACING UP;So;0;ON;;;;;N;;;;;
+1F4C5;CALENDAR;So;0;ON;;;;;N;;;;;
+1F4C6;TEAR-OFF CALENDAR;So;0;ON;;;;;N;;;;;
+1F4C7;CARD INDEX;So;0;ON;;;;;N;;;;;
+1F4C8;CHART WITH UPWARDS TREND;So;0;ON;;;;;N;;;;;
+1F4C9;CHART WITH DOWNWARDS TREND;So;0;ON;;;;;N;;;;;
+1F4CA;BAR CHART;So;0;ON;;;;;N;;;;;
+1F4CB;CLIPBOARD;So;0;ON;;;;;N;;;;;
+1F4CC;PUSHPIN;So;0;ON;;;;;N;;;;;
+1F4CD;ROUND PUSHPIN;So;0;ON;;;;;N;;;;;
+1F4CE;PAPERCLIP;So;0;ON;;;;;N;;;;;
+1F4CF;STRAIGHT RULER;So;0;ON;;;;;N;;;;;
+1F4D0;TRIANGULAR RULER;So;0;ON;;;;;N;;;;;
+1F4D1;BOOKMARK TABS;So;0;ON;;;;;N;;;;;
+1F4D2;LEDGER;So;0;ON;;;;;N;;;;;
+1F4D3;NOTEBOOK;So;0;ON;;;;;N;;;;;
+1F4D4;NOTEBOOK WITH DECORATIVE COVER;So;0;ON;;;;;N;;;;;
+1F4D5;CLOSED BOOK;So;0;ON;;;;;N;;;;;
+1F4D6;OPEN BOOK;So;0;ON;;;;;N;;;;;
+1F4D7;GREEN BOOK;So;0;ON;;;;;N;;;;;
+1F4D8;BLUE BOOK;So;0;ON;;;;;N;;;;;
+1F4D9;ORANGE BOOK;So;0;ON;;;;;N;;;;;
+1F4DA;BOOKS;So;0;ON;;;;;N;;;;;
+1F4DB;NAME BADGE;So;0;ON;;;;;N;;;;;
+1F4DC;SCROLL;So;0;ON;;;;;N;;;;;
+1F4DD;MEMO;So;0;ON;;;;;N;;;;;
+1F4DE;TELEPHONE RECEIVER;So;0;ON;;;;;N;;;;;
+1F4DF;PAGER;So;0;ON;;;;;N;;;;;
+1F4E0;FAX MACHINE;So;0;ON;;;;;N;;;;;
+1F4E1;SATELLITE ANTENNA;So;0;ON;;;;;N;;;;;
+1F4E2;PUBLIC ADDRESS LOUDSPEAKER;So;0;ON;;;;;N;;;;;
+1F4E3;CHEERING MEGAPHONE;So;0;ON;;;;;N;;;;;
+1F4E4;OUTBOX TRAY;So;0;ON;;;;;N;;;;;
+1F4E5;INBOX TRAY;So;0;ON;;;;;N;;;;;
+1F4E6;PACKAGE;So;0;ON;;;;;N;;;;;
+1F4E7;E-MAIL SYMBOL;So;0;ON;;;;;N;;;;;
+1F4E8;INCOMING ENVELOPE;So;0;ON;;;;;N;;;;;
+1F4E9;ENVELOPE WITH DOWNWARDS ARROW ABOVE;So;0;ON;;;;;N;;;;;
+1F4EA;CLOSED MAILBOX WITH LOWERED FLAG;So;0;ON;;;;;N;;;;;
+1F4EB;CLOSED MAILBOX WITH RAISED FLAG;So;0;ON;;;;;N;;;;;
+1F4EC;OPEN MAILBOX WITH RAISED FLAG;So;0;ON;;;;;N;;;;;
+1F4ED;OPEN MAILBOX WITH LOWERED FLAG;So;0;ON;;;;;N;;;;;
+1F4EE;POSTBOX;So;0;ON;;;;;N;;;;;
+1F4EF;POSTAL HORN;So;0;ON;;;;;N;;;;;
+1F4F0;NEWSPAPER;So;0;ON;;;;;N;;;;;
+1F4F1;MOBILE PHONE;So;0;ON;;;;;N;;;;;
+1F4F2;MOBILE PHONE WITH RIGHTWARDS ARROW AT LEFT;So;0;ON;;;;;N;;;;;
+1F4F3;VIBRATION MODE;So;0;ON;;;;;N;;;;;
+1F4F4;MOBILE PHONE OFF;So;0;ON;;;;;N;;;;;
+1F4F5;NO MOBILE PHONES;So;0;ON;;;;;N;;;;;
+1F4F6;ANTENNA WITH BARS;So;0;ON;;;;;N;;;;;
+1F4F7;CAMERA;So;0;ON;;;;;N;;;;;
+1F4F8;CAMERA WITH FLASH;So;0;ON;;;;;N;;;;;
+1F4F9;VIDEO CAMERA;So;0;ON;;;;;N;;;;;
+1F4FA;TELEVISION;So;0;ON;;;;;N;;;;;
+1F4FB;RADIO;So;0;ON;;;;;N;;;;;
+1F4FC;VIDEOCASSETTE;So;0;ON;;;;;N;;;;;
+1F4FD;FILM PROJECTOR;So;0;ON;;;;;N;;;;;
+1F4FE;PORTABLE STEREO;So;0;ON;;;;;N;;;;;
+1F4FF;PRAYER BEADS;So;0;ON;;;;;N;;;;;
+1F500;TWISTED RIGHTWARDS ARROWS;So;0;ON;;;;;N;;;;;
+1F501;CLOCKWISE RIGHTWARDS AND LEFTWARDS OPEN CIRCLE ARROWS;So;0;ON;;;;;N;;;;;
+1F502;CLOCKWISE RIGHTWARDS AND LEFTWARDS OPEN CIRCLE ARROWS WITH CIRCLED ONE OVERLAY;So;0;ON;;;;;N;;;;;
+1F503;CLOCKWISE DOWNWARDS AND UPWARDS OPEN CIRCLE ARROWS;So;0;ON;;;;;N;;;;;
+1F504;ANTICLOCKWISE DOWNWARDS AND UPWARDS OPEN CIRCLE ARROWS;So;0;ON;;;;;N;;;;;
+1F505;LOW BRIGHTNESS SYMBOL;So;0;ON;;;;;N;;;;;
+1F506;HIGH BRIGHTNESS SYMBOL;So;0;ON;;;;;N;;;;;
+1F507;SPEAKER WITH CANCELLATION STROKE;So;0;ON;;;;;N;;;;;
+1F508;SPEAKER;So;0;ON;;;;;N;;;;;
+1F509;SPEAKER WITH ONE SOUND WAVE;So;0;ON;;;;;N;;;;;
+1F50A;SPEAKER WITH THREE SOUND WAVES;So;0;ON;;;;;N;;;;;
+1F50B;BATTERY;So;0;ON;;;;;N;;;;;
+1F50C;ELECTRIC PLUG;So;0;ON;;;;;N;;;;;
+1F50D;LEFT-POINTING MAGNIFYING GLASS;So;0;ON;;;;;N;;;;;
+1F50E;RIGHT-POINTING MAGNIFYING GLASS;So;0;ON;;;;;N;;;;;
+1F50F;LOCK WITH INK PEN;So;0;ON;;;;;N;;;;;
+1F510;CLOSED LOCK WITH KEY;So;0;ON;;;;;N;;;;;
+1F511;KEY;So;0;ON;;;;;N;;;;;
+1F512;LOCK;So;0;ON;;;;;N;;;;;
+1F513;OPEN LOCK;So;0;ON;;;;;N;;;;;
+1F514;BELL;So;0;ON;;;;;N;;;;;
+1F515;BELL WITH CANCELLATION STROKE;So;0;ON;;;;;N;;;;;
+1F516;BOOKMARK;So;0;ON;;;;;N;;;;;
+1F517;LINK SYMBOL;So;0;ON;;;;;N;;;;;
+1F518;RADIO BUTTON;So;0;ON;;;;;N;;;;;
+1F519;BACK WITH LEFTWARDS ARROW ABOVE;So;0;ON;;;;;N;;;;;
+1F51A;END WITH LEFTWARDS ARROW ABOVE;So;0;ON;;;;;N;;;;;
+1F51B;ON WITH EXCLAMATION MARK WITH LEFT RIGHT ARROW ABOVE;So;0;ON;;;;;N;;;;;
+1F51C;SOON WITH RIGHTWARDS ARROW ABOVE;So;0;ON;;;;;N;;;;;
+1F51D;TOP WITH UPWARDS ARROW ABOVE;So;0;ON;;;;;N;;;;;
+1F51E;NO ONE UNDER EIGHTEEN SYMBOL;So;0;ON;;;;;N;;;;;
+1F51F;KEYCAP TEN;So;0;ON;;;;;N;;;;;
+1F520;INPUT SYMBOL FOR LATIN CAPITAL LETTERS;So;0;ON;;;;;N;;;;;
+1F521;INPUT SYMBOL FOR LATIN SMALL LETTERS;So;0;ON;;;;;N;;;;;
+1F522;INPUT SYMBOL FOR NUMBERS;So;0;ON;;;;;N;;;;;
+1F523;INPUT SYMBOL FOR SYMBOLS;So;0;ON;;;;;N;;;;;
+1F524;INPUT SYMBOL FOR LATIN LETTERS;So;0;ON;;;;;N;;;;;
+1F525;FIRE;So;0;ON;;;;;N;;;;;
+1F526;ELECTRIC TORCH;So;0;ON;;;;;N;;;;;
+1F527;WRENCH;So;0;ON;;;;;N;;;;;
+1F528;HAMMER;So;0;ON;;;;;N;;;;;
+1F529;NUT AND BOLT;So;0;ON;;;;;N;;;;;
+1F52A;HOCHO;So;0;ON;;;;;N;;;;;
+1F52B;PISTOL;So;0;ON;;;;;N;;;;;
+1F52C;MICROSCOPE;So;0;ON;;;;;N;;;;;
+1F52D;TELESCOPE;So;0;ON;;;;;N;;;;;
+1F52E;CRYSTAL BALL;So;0;ON;;;;;N;;;;;
+1F52F;SIX POINTED STAR WITH MIDDLE DOT;So;0;ON;;;;;N;;;;;
+1F530;JAPANESE SYMBOL FOR BEGINNER;So;0;ON;;;;;N;;;;;
+1F531;TRIDENT EMBLEM;So;0;ON;;;;;N;;;;;
+1F532;BLACK SQUARE BUTTON;So;0;ON;;;;;N;;;;;
+1F533;WHITE SQUARE BUTTON;So;0;ON;;;;;N;;;;;
+1F534;LARGE RED CIRCLE;So;0;ON;;;;;N;;;;;
+1F535;LARGE BLUE CIRCLE;So;0;ON;;;;;N;;;;;
+1F536;LARGE ORANGE DIAMOND;So;0;ON;;;;;N;;;;;
+1F537;LARGE BLUE DIAMOND;So;0;ON;;;;;N;;;;;
+1F538;SMALL ORANGE DIAMOND;So;0;ON;;;;;N;;;;;
+1F539;SMALL BLUE DIAMOND;So;0;ON;;;;;N;;;;;
+1F53A;UP-POINTING RED TRIANGLE;So;0;ON;;;;;N;;;;;
+1F53B;DOWN-POINTING RED TRIANGLE;So;0;ON;;;;;N;;;;;
+1F53C;UP-POINTING SMALL RED TRIANGLE;So;0;ON;;;;;N;;;;;
+1F53D;DOWN-POINTING SMALL RED TRIANGLE;So;0;ON;;;;;N;;;;;
+1F53E;LOWER RIGHT SHADOWED WHITE CIRCLE;So;0;ON;;;;;N;;;;;
+1F53F;UPPER RIGHT SHADOWED WHITE CIRCLE;So;0;ON;;;;;N;;;;;
+1F540;CIRCLED CROSS POMMEE;So;0;ON;;;;;N;;;;;
+1F541;CROSS POMMEE WITH HALF-CIRCLE BELOW;So;0;ON;;;;;N;;;;;
+1F542;CROSS POMMEE;So;0;ON;;;;;N;;;;;
+1F543;NOTCHED LEFT SEMICIRCLE WITH THREE DOTS;So;0;ON;;;;;N;;;;;
+1F544;NOTCHED RIGHT SEMICIRCLE WITH THREE DOTS;So;0;ON;;;;;N;;;;;
+1F545;SYMBOL FOR MARKS CHAPTER;So;0;ON;;;;;N;;;;;
+1F546;WHITE LATIN CROSS;So;0;ON;;;;;N;;;;;
+1F547;HEAVY LATIN CROSS;So;0;ON;;;;;N;;;;;
+1F548;CELTIC CROSS;So;0;ON;;;;;N;;;;;
+1F549;OM SYMBOL;So;0;ON;;;;;N;;;;;
+1F54A;DOVE OF PEACE;So;0;ON;;;;;N;;;;;
+1F54B;KAABA;So;0;ON;;;;;N;;;;;
+1F54C;MOSQUE;So;0;ON;;;;;N;;;;;
+1F54D;SYNAGOGUE;So;0;ON;;;;;N;;;;;
+1F54E;MENORAH WITH NINE BRANCHES;So;0;ON;;;;;N;;;;;
+1F54F;BOWL OF HYGIEIA;So;0;ON;;;;;N;;;;;
+1F550;CLOCK FACE ONE OCLOCK;So;0;ON;;;;;N;;;;;
+1F551;CLOCK FACE TWO OCLOCK;So;0;ON;;;;;N;;;;;
+1F552;CLOCK FACE THREE OCLOCK;So;0;ON;;;;;N;;;;;
+1F553;CLOCK FACE FOUR OCLOCK;So;0;ON;;;;;N;;;;;
+1F554;CLOCK FACE FIVE OCLOCK;So;0;ON;;;;;N;;;;;
+1F555;CLOCK FACE SIX OCLOCK;So;0;ON;;;;;N;;;;;
+1F556;CLOCK FACE SEVEN OCLOCK;So;0;ON;;;;;N;;;;;
+1F557;CLOCK FACE EIGHT OCLOCK;So;0;ON;;;;;N;;;;;
+1F558;CLOCK FACE NINE OCLOCK;So;0;ON;;;;;N;;;;;
+1F559;CLOCK FACE TEN OCLOCK;So;0;ON;;;;;N;;;;;
+1F55A;CLOCK FACE ELEVEN OCLOCK;So;0;ON;;;;;N;;;;;
+1F55B;CLOCK FACE TWELVE OCLOCK;So;0;ON;;;;;N;;;;;
+1F55C;CLOCK FACE ONE-THIRTY;So;0;ON;;;;;N;;;;;
+1F55D;CLOCK FACE TWO-THIRTY;So;0;ON;;;;;N;;;;;
+1F55E;CLOCK FACE THREE-THIRTY;So;0;ON;;;;;N;;;;;
+1F55F;CLOCK FACE FOUR-THIRTY;So;0;ON;;;;;N;;;;;
+1F560;CLOCK FACE FIVE-THIRTY;So;0;ON;;;;;N;;;;;
+1F561;CLOCK FACE SIX-THIRTY;So;0;ON;;;;;N;;;;;
+1F562;CLOCK FACE SEVEN-THIRTY;So;0;ON;;;;;N;;;;;
+1F563;CLOCK FACE EIGHT-THIRTY;So;0;ON;;;;;N;;;;;
+1F564;CLOCK FACE NINE-THIRTY;So;0;ON;;;;;N;;;;;
+1F565;CLOCK FACE TEN-THIRTY;So;0;ON;;;;;N;;;;;
+1F566;CLOCK FACE ELEVEN-THIRTY;So;0;ON;;;;;N;;;;;
+1F567;CLOCK FACE TWELVE-THIRTY;So;0;ON;;;;;N;;;;;
+1F568;RIGHT SPEAKER;So;0;ON;;;;;N;;;;;
+1F569;RIGHT SPEAKER WITH ONE SOUND WAVE;So;0;ON;;;;;N;;;;;
+1F56A;RIGHT SPEAKER WITH THREE SOUND WAVES;So;0;ON;;;;;N;;;;;
+1F56B;BULLHORN;So;0;ON;;;;;N;;;;;
+1F56C;BULLHORN WITH SOUND WAVES;So;0;ON;;;;;N;;;;;
+1F56D;RINGING BELL;So;0;ON;;;;;N;;;;;
+1F56E;BOOK;So;0;ON;;;;;N;;;;;
+1F56F;CANDLE;So;0;ON;;;;;N;;;;;
+1F570;MANTELPIECE CLOCK;So;0;ON;;;;;N;;;;;
+1F571;BLACK SKULL AND CROSSBONES;So;0;ON;;;;;N;;;;;
+1F572;NO PIRACY;So;0;ON;;;;;N;;;;;
+1F573;HOLE;So;0;ON;;;;;N;;;;;
+1F574;MAN IN BUSINESS SUIT LEVITATING;So;0;ON;;;;;N;;;;;
+1F575;SLEUTH OR SPY;So;0;ON;;;;;N;;;;;
+1F576;DARK SUNGLASSES;So;0;ON;;;;;N;;;;;
+1F577;SPIDER;So;0;ON;;;;;N;;;;;
+1F578;SPIDER WEB;So;0;ON;;;;;N;;;;;
+1F579;JOYSTICK;So;0;ON;;;;;N;;;;;
+1F57A;MAN DANCING;So;0;ON;;;;;N;;;;;
+1F57B;LEFT HAND TELEPHONE RECEIVER;So;0;ON;;;;;N;;;;;
+1F57C;TELEPHONE RECEIVER WITH PAGE;So;0;ON;;;;;N;;;;;
+1F57D;RIGHT HAND TELEPHONE RECEIVER;So;0;ON;;;;;N;;;;;
+1F57E;WHITE TOUCHTONE TELEPHONE;So;0;ON;;;;;N;;;;;
+1F57F;BLACK TOUCHTONE TELEPHONE;So;0;ON;;;;;N;;;;;
+1F580;TELEPHONE ON TOP OF MODEM;So;0;ON;;;;;N;;;;;
+1F581;CLAMSHELL MOBILE PHONE;So;0;ON;;;;;N;;;;;
+1F582;BACK OF ENVELOPE;So;0;ON;;;;;N;;;;;
+1F583;STAMPED ENVELOPE;So;0;ON;;;;;N;;;;;
+1F584;ENVELOPE WITH LIGHTNING;So;0;ON;;;;;N;;;;;
+1F585;FLYING ENVELOPE;So;0;ON;;;;;N;;;;;
+1F586;PEN OVER STAMPED ENVELOPE;So;0;ON;;;;;N;;;;;
+1F587;LINKED PAPERCLIPS;So;0;ON;;;;;N;;;;;
+1F588;BLACK PUSHPIN;So;0;ON;;;;;N;;;;;
+1F589;LOWER LEFT PENCIL;So;0;ON;;;;;N;;;;;
+1F58A;LOWER LEFT BALLPOINT PEN;So;0;ON;;;;;N;;;;;
+1F58B;LOWER LEFT FOUNTAIN PEN;So;0;ON;;;;;N;;;;;
+1F58C;LOWER LEFT PAINTBRUSH;So;0;ON;;;;;N;;;;;
+1F58D;LOWER LEFT CRAYON;So;0;ON;;;;;N;;;;;
+1F58E;LEFT WRITING HAND;So;0;ON;;;;;N;;;;;
+1F58F;TURNED OK HAND SIGN;So;0;ON;;;;;N;;;;;
+1F590;RAISED HAND WITH FINGERS SPLAYED;So;0;ON;;;;;N;;;;;
+1F591;REVERSED RAISED HAND WITH FINGERS SPLAYED;So;0;ON;;;;;N;;;;;
+1F592;REVERSED THUMBS UP SIGN;So;0;ON;;;;;N;;;;;
+1F593;REVERSED THUMBS DOWN SIGN;So;0;ON;;;;;N;;;;;
+1F594;REVERSED VICTORY HAND;So;0;ON;;;;;N;;;;;
+1F595;REVERSED HAND WITH MIDDLE FINGER EXTENDED;So;0;ON;;;;;N;;;;;
+1F596;RAISED HAND WITH PART BETWEEN MIDDLE AND RING FINGERS;So;0;ON;;;;;N;;;;;
+1F597;WHITE DOWN POINTING LEFT HAND INDEX;So;0;ON;;;;;N;;;;;
+1F598;SIDEWAYS WHITE LEFT POINTING INDEX;So;0;ON;;;;;N;;;;;
+1F599;SIDEWAYS WHITE RIGHT POINTING INDEX;So;0;ON;;;;;N;;;;;
+1F59A;SIDEWAYS BLACK LEFT POINTING INDEX;So;0;ON;;;;;N;;;;;
+1F59B;SIDEWAYS BLACK RIGHT POINTING INDEX;So;0;ON;;;;;N;;;;;
+1F59C;BLACK LEFT POINTING BACKHAND INDEX;So;0;ON;;;;;N;;;;;
+1F59D;BLACK RIGHT POINTING BACKHAND INDEX;So;0;ON;;;;;N;;;;;
+1F59E;SIDEWAYS WHITE UP POINTING INDEX;So;0;ON;;;;;N;;;;;
+1F59F;SIDEWAYS WHITE DOWN POINTING INDEX;So;0;ON;;;;;N;;;;;
+1F5A0;SIDEWAYS BLACK UP POINTING INDEX;So;0;ON;;;;;N;;;;;
+1F5A1;SIDEWAYS BLACK DOWN POINTING INDEX;So;0;ON;;;;;N;;;;;
+1F5A2;BLACK UP POINTING BACKHAND INDEX;So;0;ON;;;;;N;;;;;
+1F5A3;BLACK DOWN POINTING BACKHAND INDEX;So;0;ON;;;;;N;;;;;
+1F5A4;BLACK HEART;So;0;ON;;;;;N;;;;;
+1F5A5;DESKTOP COMPUTER;So;0;ON;;;;;N;;;;;
+1F5A6;KEYBOARD AND MOUSE;So;0;ON;;;;;N;;;;;
+1F5A7;THREE NETWORKED COMPUTERS;So;0;ON;;;;;N;;;;;
+1F5A8;PRINTER;So;0;ON;;;;;N;;;;;
+1F5A9;POCKET CALCULATOR;So;0;ON;;;;;N;;;;;
+1F5AA;BLACK HARD SHELL FLOPPY DISK;So;0;ON;;;;;N;;;;;
+1F5AB;WHITE HARD SHELL FLOPPY DISK;So;0;ON;;;;;N;;;;;
+1F5AC;SOFT SHELL FLOPPY DISK;So;0;ON;;;;;N;;;;;
+1F5AD;TAPE CARTRIDGE;So;0;ON;;;;;N;;;;;
+1F5AE;WIRED KEYBOARD;So;0;ON;;;;;N;;;;;
+1F5AF;ONE BUTTON MOUSE;So;0;ON;;;;;N;;;;;
+1F5B0;TWO BUTTON MOUSE;So;0;ON;;;;;N;;;;;
+1F5B1;THREE BUTTON MOUSE;So;0;ON;;;;;N;;;;;
+1F5B2;TRACKBALL;So;0;ON;;;;;N;;;;;
+1F5B3;OLD PERSONAL COMPUTER;So;0;ON;;;;;N;;;;;
+1F5B4;HARD DISK;So;0;ON;;;;;N;;;;;
+1F5B5;SCREEN;So;0;ON;;;;;N;;;;;
+1F5B6;PRINTER ICON;So;0;ON;;;;;N;;;;;
+1F5B7;FAX ICON;So;0;ON;;;;;N;;;;;
+1F5B8;OPTICAL DISC ICON;So;0;ON;;;;;N;;;;;
+1F5B9;DOCUMENT WITH TEXT;So;0;ON;;;;;N;;;;;
+1F5BA;DOCUMENT WITH TEXT AND PICTURE;So;0;ON;;;;;N;;;;;
+1F5BB;DOCUMENT WITH PICTURE;So;0;ON;;;;;N;;;;;
+1F5BC;FRAME WITH PICTURE;So;0;ON;;;;;N;;;;;
+1F5BD;FRAME WITH TILES;So;0;ON;;;;;N;;;;;
+1F5BE;FRAME WITH AN X;So;0;ON;;;;;N;;;;;
+1F5BF;BLACK FOLDER;So;0;ON;;;;;N;;;;;
+1F5C0;FOLDER;So;0;ON;;;;;N;;;;;
+1F5C1;OPEN FOLDER;So;0;ON;;;;;N;;;;;
+1F5C2;CARD INDEX DIVIDERS;So;0;ON;;;;;N;;;;;
+1F5C3;CARD FILE BOX;So;0;ON;;;;;N;;;;;
+1F5C4;FILE CABINET;So;0;ON;;;;;N;;;;;
+1F5C5;EMPTY NOTE;So;0;ON;;;;;N;;;;;
+1F5C6;EMPTY NOTE PAGE;So;0;ON;;;;;N;;;;;
+1F5C7;EMPTY NOTE PAD;So;0;ON;;;;;N;;;;;
+1F5C8;NOTE;So;0;ON;;;;;N;;;;;
+1F5C9;NOTE PAGE;So;0;ON;;;;;N;;;;;
+1F5CA;NOTE PAD;So;0;ON;;;;;N;;;;;
+1F5CB;EMPTY DOCUMENT;So;0;ON;;;;;N;;;;;
+1F5CC;EMPTY PAGE;So;0;ON;;;;;N;;;;;
+1F5CD;EMPTY PAGES;So;0;ON;;;;;N;;;;;
+1F5CE;DOCUMENT;So;0;ON;;;;;N;;;;;
+1F5CF;PAGE;So;0;ON;;;;;N;;;;;
+1F5D0;PAGES;So;0;ON;;;;;N;;;;;
+1F5D1;WASTEBASKET;So;0;ON;;;;;N;;;;;
+1F5D2;SPIRAL NOTE PAD;So;0;ON;;;;;N;;;;;
+1F5D3;SPIRAL CALENDAR PAD;So;0;ON;;;;;N;;;;;
+1F5D4;DESKTOP WINDOW;So;0;ON;;;;;N;;;;;
+1F5D5;MINIMIZE;So;0;ON;;;;;N;;;;;
+1F5D6;MAXIMIZE;So;0;ON;;;;;N;;;;;
+1F5D7;OVERLAP;So;0;ON;;;;;N;;;;;
+1F5D8;CLOCKWISE RIGHT AND LEFT SEMICIRCLE ARROWS;So;0;ON;;;;;N;;;;;
+1F5D9;CANCELLATION X;So;0;ON;;;;;N;;;;;
+1F5DA;INCREASE FONT SIZE SYMBOL;So;0;ON;;;;;N;;;;;
+1F5DB;DECREASE FONT SIZE SYMBOL;So;0;ON;;;;;N;;;;;
+1F5DC;COMPRESSION;So;0;ON;;;;;N;;;;;
+1F5DD;OLD KEY;So;0;ON;;;;;N;;;;;
+1F5DE;ROLLED-UP NEWSPAPER;So;0;ON;;;;;N;;;;;
+1F5DF;PAGE WITH CIRCLED TEXT;So;0;ON;;;;;N;;;;;
+1F5E0;STOCK CHART;So;0;ON;;;;;N;;;;;
+1F5E1;DAGGER KNIFE;So;0;ON;;;;;N;;;;;
+1F5E2;LIPS;So;0;ON;;;;;N;;;;;
+1F5E3;SPEAKING HEAD IN SILHOUETTE;So;0;ON;;;;;N;;;;;
+1F5E4;THREE RAYS ABOVE;So;0;ON;;;;;N;;;;;
+1F5E5;THREE RAYS BELOW;So;0;ON;;;;;N;;;;;
+1F5E6;THREE RAYS LEFT;So;0;ON;;;;;N;;;;;
+1F5E7;THREE RAYS RIGHT;So;0;ON;;;;;N;;;;;
+1F5E8;LEFT SPEECH BUBBLE;So;0;ON;;;;;N;;;;;
+1F5E9;RIGHT SPEECH BUBBLE;So;0;ON;;;;;N;;;;;
+1F5EA;TWO SPEECH BUBBLES;So;0;ON;;;;;N;;;;;
+1F5EB;THREE SPEECH BUBBLES;So;0;ON;;;;;N;;;;;
+1F5EC;LEFT THOUGHT BUBBLE;So;0;ON;;;;;N;;;;;
+1F5ED;RIGHT THOUGHT BUBBLE;So;0;ON;;;;;N;;;;;
+1F5EE;LEFT ANGER BUBBLE;So;0;ON;;;;;N;;;;;
+1F5EF;RIGHT ANGER BUBBLE;So;0;ON;;;;;N;;;;;
+1F5F0;MOOD BUBBLE;So;0;ON;;;;;N;;;;;
+1F5F1;LIGHTNING MOOD BUBBLE;So;0;ON;;;;;N;;;;;
+1F5F2;LIGHTNING MOOD;So;0;ON;;;;;N;;;;;
+1F5F3;BALLOT BOX WITH BALLOT;So;0;ON;;;;;N;;;;;
+1F5F4;BALLOT SCRIPT X;So;0;ON;;;;;N;;;;;
+1F5F5;BALLOT BOX WITH SCRIPT X;So;0;ON;;;;;N;;;;;
+1F5F6;BALLOT BOLD SCRIPT X;So;0;ON;;;;;N;;;;;
+1F5F7;BALLOT BOX WITH BOLD SCRIPT X;So;0;ON;;;;;N;;;;;
+1F5F8;LIGHT CHECK MARK;So;0;ON;;;;;N;;;;;
+1F5F9;BALLOT BOX WITH BOLD CHECK;So;0;ON;;;;;N;;;;;
+1F5FA;WORLD MAP;So;0;ON;;;;;N;;;;;
+1F5FB;MOUNT FUJI;So;0;ON;;;;;N;;;;;
+1F5FC;TOKYO TOWER;So;0;ON;;;;;N;;;;;
+1F5FD;STATUE OF LIBERTY;So;0;ON;;;;;N;;;;;
+1F5FE;SILHOUETTE OF JAPAN;So;0;ON;;;;;N;;;;;
+1F5FF;MOYAI;So;0;ON;;;;;N;;;;;
+1F600;GRINNING FACE;So;0;ON;;;;;N;;;;;
+1F601;GRINNING FACE WITH SMILING EYES;So;0;ON;;;;;N;;;;;
+1F602;FACE WITH TEARS OF JOY;So;0;ON;;;;;N;;;;;
+1F603;SMILING FACE WITH OPEN MOUTH;So;0;ON;;;;;N;;;;;
+1F604;SMILING FACE WITH OPEN MOUTH AND SMILING EYES;So;0;ON;;;;;N;;;;;
+1F605;SMILING FACE WITH OPEN MOUTH AND COLD SWEAT;So;0;ON;;;;;N;;;;;
+1F606;SMILING FACE WITH OPEN MOUTH AND TIGHTLY-CLOSED EYES;So;0;ON;;;;;N;;;;;
+1F607;SMILING FACE WITH HALO;So;0;ON;;;;;N;;;;;
+1F608;SMILING FACE WITH HORNS;So;0;ON;;;;;N;;;;;
+1F609;WINKING FACE;So;0;ON;;;;;N;;;;;
+1F60A;SMILING FACE WITH SMILING EYES;So;0;ON;;;;;N;;;;;
+1F60B;FACE SAVOURING DELICIOUS FOOD;So;0;ON;;;;;N;;;;;
+1F60C;RELIEVED FACE;So;0;ON;;;;;N;;;;;
+1F60D;SMILING FACE WITH HEART-SHAPED EYES;So;0;ON;;;;;N;;;;;
+1F60E;SMILING FACE WITH SUNGLASSES;So;0;ON;;;;;N;;;;;
+1F60F;SMIRKING FACE;So;0;ON;;;;;N;;;;;
+1F610;NEUTRAL FACE;So;0;ON;;;;;N;;;;;
+1F611;EXPRESSIONLESS FACE;So;0;ON;;;;;N;;;;;
+1F612;UNAMUSED FACE;So;0;ON;;;;;N;;;;;
+1F613;FACE WITH COLD SWEAT;So;0;ON;;;;;N;;;;;
+1F614;PENSIVE FACE;So;0;ON;;;;;N;;;;;
+1F615;CONFUSED FACE;So;0;ON;;;;;N;;;;;
+1F616;CONFOUNDED FACE;So;0;ON;;;;;N;;;;;
+1F617;KISSING FACE;So;0;ON;;;;;N;;;;;
+1F618;FACE THROWING A KISS;So;0;ON;;;;;N;;;;;
+1F619;KISSING FACE WITH SMILING EYES;So;0;ON;;;;;N;;;;;
+1F61A;KISSING FACE WITH CLOSED EYES;So;0;ON;;;;;N;;;;;
+1F61B;FACE WITH STUCK-OUT TONGUE;So;0;ON;;;;;N;;;;;
+1F61C;FACE WITH STUCK-OUT TONGUE AND WINKING EYE;So;0;ON;;;;;N;;;;;
+1F61D;FACE WITH STUCK-OUT TONGUE AND TIGHTLY-CLOSED EYES;So;0;ON;;;;;N;;;;;
+1F61E;DISAPPOINTED FACE;So;0;ON;;;;;N;;;;;
+1F61F;WORRIED FACE;So;0;ON;;;;;N;;;;;
+1F620;ANGRY FACE;So;0;ON;;;;;N;;;;;
+1F621;POUTING FACE;So;0;ON;;;;;N;;;;;
+1F622;CRYING FACE;So;0;ON;;;;;N;;;;;
+1F623;PERSEVERING FACE;So;0;ON;;;;;N;;;;;
+1F624;FACE WITH LOOK OF TRIUMPH;So;0;ON;;;;;N;;;;;
+1F625;DISAPPOINTED BUT RELIEVED FACE;So;0;ON;;;;;N;;;;;
+1F626;FROWNING FACE WITH OPEN MOUTH;So;0;ON;;;;;N;;;;;
+1F627;ANGUISHED FACE;So;0;ON;;;;;N;;;;;
+1F628;FEARFUL FACE;So;0;ON;;;;;N;;;;;
+1F629;WEARY FACE;So;0;ON;;;;;N;;;;;
+1F62A;SLEEPY FACE;So;0;ON;;;;;N;;;;;
+1F62B;TIRED FACE;So;0;ON;;;;;N;;;;;
+1F62C;GRIMACING FACE;So;0;ON;;;;;N;;;;;
+1F62D;LOUDLY CRYING FACE;So;0;ON;;;;;N;;;;;
+1F62E;FACE WITH OPEN MOUTH;So;0;ON;;;;;N;;;;;
+1F62F;HUSHED FACE;So;0;ON;;;;;N;;;;;
+1F630;FACE WITH OPEN MOUTH AND COLD SWEAT;So;0;ON;;;;;N;;;;;
+1F631;FACE SCREAMING IN FEAR;So;0;ON;;;;;N;;;;;
+1F632;ASTONISHED FACE;So;0;ON;;;;;N;;;;;
+1F633;FLUSHED FACE;So;0;ON;;;;;N;;;;;
+1F634;SLEEPING FACE;So;0;ON;;;;;N;;;;;
+1F635;DIZZY FACE;So;0;ON;;;;;N;;;;;
+1F636;FACE WITHOUT MOUTH;So;0;ON;;;;;N;;;;;
+1F637;FACE WITH MEDICAL MASK;So;0;ON;;;;;N;;;;;
+1F638;GRINNING CAT FACE WITH SMILING EYES;So;0;ON;;;;;N;;;;;
+1F639;CAT FACE WITH TEARS OF JOY;So;0;ON;;;;;N;;;;;
+1F63A;SMILING CAT FACE WITH OPEN MOUTH;So;0;ON;;;;;N;;;;;
+1F63B;SMILING CAT FACE WITH HEART-SHAPED EYES;So;0;ON;;;;;N;;;;;
+1F63C;CAT FACE WITH WRY SMILE;So;0;ON;;;;;N;;;;;
+1F63D;KISSING CAT FACE WITH CLOSED EYES;So;0;ON;;;;;N;;;;;
+1F63E;POUTING CAT FACE;So;0;ON;;;;;N;;;;;
+1F63F;CRYING CAT FACE;So;0;ON;;;;;N;;;;;
+1F640;WEARY CAT FACE;So;0;ON;;;;;N;;;;;
+1F641;SLIGHTLY FROWNING FACE;So;0;ON;;;;;N;;;;;
+1F642;SLIGHTLY SMILING FACE;So;0;ON;;;;;N;;;;;
+1F643;UPSIDE-DOWN FACE;So;0;ON;;;;;N;;;;;
+1F644;FACE WITH ROLLING EYES;So;0;ON;;;;;N;;;;;
+1F645;FACE WITH NO GOOD GESTURE;So;0;ON;;;;;N;;;;;
+1F646;FACE WITH OK GESTURE;So;0;ON;;;;;N;;;;;
+1F647;PERSON BOWING DEEPLY;So;0;ON;;;;;N;;;;;
+1F648;SEE-NO-EVIL MONKEY;So;0;ON;;;;;N;;;;;
+1F649;HEAR-NO-EVIL MONKEY;So;0;ON;;;;;N;;;;;
+1F64A;SPEAK-NO-EVIL MONKEY;So;0;ON;;;;;N;;;;;
+1F64B;HAPPY PERSON RAISING ONE HAND;So;0;ON;;;;;N;;;;;
+1F64C;PERSON RAISING BOTH HANDS IN CELEBRATION;So;0;ON;;;;;N;;;;;
+1F64D;PERSON FROWNING;So;0;ON;;;;;N;;;;;
+1F64E;PERSON WITH POUTING FACE;So;0;ON;;;;;N;;;;;
+1F64F;PERSON WITH FOLDED HANDS;So;0;ON;;;;;N;;;;;
+1F650;NORTH WEST POINTING LEAF;So;0;ON;;;;;N;;;;;
+1F651;SOUTH WEST POINTING LEAF;So;0;ON;;;;;N;;;;;
+1F652;NORTH EAST POINTING LEAF;So;0;ON;;;;;N;;;;;
+1F653;SOUTH EAST POINTING LEAF;So;0;ON;;;;;N;;;;;
+1F654;TURNED NORTH WEST POINTING LEAF;So;0;ON;;;;;N;;;;;
+1F655;TURNED SOUTH WEST POINTING LEAF;So;0;ON;;;;;N;;;;;
+1F656;TURNED NORTH EAST POINTING LEAF;So;0;ON;;;;;N;;;;;
+1F657;TURNED SOUTH EAST POINTING LEAF;So;0;ON;;;;;N;;;;;
+1F658;NORTH WEST POINTING VINE LEAF;So;0;ON;;;;;N;;;;;
+1F659;SOUTH WEST POINTING VINE LEAF;So;0;ON;;;;;N;;;;;
+1F65A;NORTH EAST POINTING VINE LEAF;So;0;ON;;;;;N;;;;;
+1F65B;SOUTH EAST POINTING VINE LEAF;So;0;ON;;;;;N;;;;;
+1F65C;HEAVY NORTH WEST POINTING VINE LEAF;So;0;ON;;;;;N;;;;;
+1F65D;HEAVY SOUTH WEST POINTING VINE LEAF;So;0;ON;;;;;N;;;;;
+1F65E;HEAVY NORTH EAST POINTING VINE LEAF;So;0;ON;;;;;N;;;;;
+1F65F;HEAVY SOUTH EAST POINTING VINE LEAF;So;0;ON;;;;;N;;;;;
+1F660;NORTH WEST POINTING BUD;So;0;ON;;;;;N;;;;;
+1F661;SOUTH WEST POINTING BUD;So;0;ON;;;;;N;;;;;
+1F662;NORTH EAST POINTING BUD;So;0;ON;;;;;N;;;;;
+1F663;SOUTH EAST POINTING BUD;So;0;ON;;;;;N;;;;;
+1F664;HEAVY NORTH WEST POINTING BUD;So;0;ON;;;;;N;;;;;
+1F665;HEAVY SOUTH WEST POINTING BUD;So;0;ON;;;;;N;;;;;
+1F666;HEAVY NORTH EAST POINTING BUD;So;0;ON;;;;;N;;;;;
+1F667;HEAVY SOUTH EAST POINTING BUD;So;0;ON;;;;;N;;;;;
+1F668;HOLLOW QUILT SQUARE ORNAMENT;So;0;ON;;;;;N;;;;;
+1F669;HOLLOW QUILT SQUARE ORNAMENT IN BLACK SQUARE;So;0;ON;;;;;N;;;;;
+1F66A;SOLID QUILT SQUARE ORNAMENT;So;0;ON;;;;;N;;;;;
+1F66B;SOLID QUILT SQUARE ORNAMENT IN BLACK SQUARE;So;0;ON;;;;;N;;;;;
+1F66C;LEFTWARDS ROCKET;So;0;ON;;;;;N;;;;;
+1F66D;UPWARDS ROCKET;So;0;ON;;;;;N;;;;;
+1F66E;RIGHTWARDS ROCKET;So;0;ON;;;;;N;;;;;
+1F66F;DOWNWARDS ROCKET;So;0;ON;;;;;N;;;;;
+1F670;SCRIPT LIGATURE ET ORNAMENT;So;0;ON;;;;;N;;;;;
+1F671;HEAVY SCRIPT LIGATURE ET ORNAMENT;So;0;ON;;;;;N;;;;;
+1F672;LIGATURE OPEN ET ORNAMENT;So;0;ON;;;;;N;;;;;
+1F673;HEAVY LIGATURE OPEN ET ORNAMENT;So;0;ON;;;;;N;;;;;
+1F674;HEAVY AMPERSAND ORNAMENT;So;0;ON;;;;;N;;;;;
+1F675;SWASH AMPERSAND ORNAMENT;So;0;ON;;;;;N;;;;;
+1F676;SANS-SERIF HEAVY DOUBLE TURNED COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
+1F677;SANS-SERIF HEAVY DOUBLE COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
+1F678;SANS-SERIF HEAVY LOW DOUBLE COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
+1F679;HEAVY INTERROBANG ORNAMENT;So;0;ON;;;;;N;;;;;
+1F67A;SANS-SERIF INTERROBANG ORNAMENT;So;0;ON;;;;;N;;;;;
+1F67B;HEAVY SANS-SERIF INTERROBANG ORNAMENT;So;0;ON;;;;;N;;;;;
+1F67C;VERY HEAVY SOLIDUS;So;0;ON;;;;;N;;;;;
+1F67D;VERY HEAVY REVERSE SOLIDUS;So;0;ON;;;;;N;;;;;
+1F67E;CHECKER BOARD;So;0;ON;;;;;N;;;;;
+1F67F;REVERSE CHECKER BOARD;So;0;ON;;;;;N;;;;;
+1F680;ROCKET;So;0;ON;;;;;N;;;;;
+1F681;HELICOPTER;So;0;ON;;;;;N;;;;;
+1F682;STEAM LOCOMOTIVE;So;0;ON;;;;;N;;;;;
+1F683;RAILWAY CAR;So;0;ON;;;;;N;;;;;
+1F684;HIGH-SPEED TRAIN;So;0;ON;;;;;N;;;;;
+1F685;HIGH-SPEED TRAIN WITH BULLET NOSE;So;0;ON;;;;;N;;;;;
+1F686;TRAIN;So;0;ON;;;;;N;;;;;
+1F687;METRO;So;0;ON;;;;;N;;;;;
+1F688;LIGHT RAIL;So;0;ON;;;;;N;;;;;
+1F689;STATION;So;0;ON;;;;;N;;;;;
+1F68A;TRAM;So;0;ON;;;;;N;;;;;
+1F68B;TRAM CAR;So;0;ON;;;;;N;;;;;
+1F68C;BUS;So;0;ON;;;;;N;;;;;
+1F68D;ONCOMING BUS;So;0;ON;;;;;N;;;;;
+1F68E;TROLLEYBUS;So;0;ON;;;;;N;;;;;
+1F68F;BUS STOP;So;0;ON;;;;;N;;;;;
+1F690;MINIBUS;So;0;ON;;;;;N;;;;;
+1F691;AMBULANCE;So;0;ON;;;;;N;;;;;
+1F692;FIRE ENGINE;So;0;ON;;;;;N;;;;;
+1F693;POLICE CAR;So;0;ON;;;;;N;;;;;
+1F694;ONCOMING POLICE CAR;So;0;ON;;;;;N;;;;;
+1F695;TAXI;So;0;ON;;;;;N;;;;;
+1F696;ONCOMING TAXI;So;0;ON;;;;;N;;;;;
+1F697;AUTOMOBILE;So;0;ON;;;;;N;;;;;
+1F698;ONCOMING AUTOMOBILE;So;0;ON;;;;;N;;;;;
+1F699;RECREATIONAL VEHICLE;So;0;ON;;;;;N;;;;;
+1F69A;DELIVERY TRUCK;So;0;ON;;;;;N;;;;;
+1F69B;ARTICULATED LORRY;So;0;ON;;;;;N;;;;;
+1F69C;TRACTOR;So;0;ON;;;;;N;;;;;
+1F69D;MONORAIL;So;0;ON;;;;;N;;;;;
+1F69E;MOUNTAIN RAILWAY;So;0;ON;;;;;N;;;;;
+1F69F;SUSPENSION RAILWAY;So;0;ON;;;;;N;;;;;
+1F6A0;MOUNTAIN CABLEWAY;So;0;ON;;;;;N;;;;;
+1F6A1;AERIAL TRAMWAY;So;0;ON;;;;;N;;;;;
+1F6A2;SHIP;So;0;ON;;;;;N;;;;;
+1F6A3;ROWBOAT;So;0;ON;;;;;N;;;;;
+1F6A4;SPEEDBOAT;So;0;ON;;;;;N;;;;;
+1F6A5;HORIZONTAL TRAFFIC LIGHT;So;0;ON;;;;;N;;;;;
+1F6A6;VERTICAL TRAFFIC LIGHT;So;0;ON;;;;;N;;;;;
+1F6A7;CONSTRUCTION SIGN;So;0;ON;;;;;N;;;;;
+1F6A8;POLICE CARS REVOLVING LIGHT;So;0;ON;;;;;N;;;;;
+1F6A9;TRIANGULAR FLAG ON POST;So;0;ON;;;;;N;;;;;
+1F6AA;DOOR;So;0;ON;;;;;N;;;;;
+1F6AB;NO ENTRY SIGN;So;0;ON;;;;;N;;;;;
+1F6AC;SMOKING SYMBOL;So;0;ON;;;;;N;;;;;
+1F6AD;NO SMOKING SYMBOL;So;0;ON;;;;;N;;;;;
+1F6AE;PUT LITTER IN ITS PLACE SYMBOL;So;0;ON;;;;;N;;;;;
+1F6AF;DO NOT LITTER SYMBOL;So;0;ON;;;;;N;;;;;
+1F6B0;POTABLE WATER SYMBOL;So;0;ON;;;;;N;;;;;
+1F6B1;NON-POTABLE WATER SYMBOL;So;0;ON;;;;;N;;;;;
+1F6B2;BICYCLE;So;0;ON;;;;;N;;;;;
+1F6B3;NO BICYCLES;So;0;ON;;;;;N;;;;;
+1F6B4;BICYCLIST;So;0;ON;;;;;N;;;;;
+1F6B5;MOUNTAIN BICYCLIST;So;0;ON;;;;;N;;;;;
+1F6B6;PEDESTRIAN;So;0;ON;;;;;N;;;;;
+1F6B7;NO PEDESTRIANS;So;0;ON;;;;;N;;;;;
+1F6B8;CHILDREN CROSSING;So;0;ON;;;;;N;;;;;
+1F6B9;MENS SYMBOL;So;0;ON;;;;;N;;;;;
+1F6BA;WOMENS SYMBOL;So;0;ON;;;;;N;;;;;
+1F6BB;RESTROOM;So;0;ON;;;;;N;;;;;
+1F6BC;BABY SYMBOL;So;0;ON;;;;;N;;;;;
+1F6BD;TOILET;So;0;ON;;;;;N;;;;;
+1F6BE;WATER CLOSET;So;0;ON;;;;;N;;;;;
+1F6BF;SHOWER;So;0;ON;;;;;N;;;;;
+1F6C0;BATH;So;0;ON;;;;;N;;;;;
+1F6C1;BATHTUB;So;0;ON;;;;;N;;;;;
+1F6C2;PASSPORT CONTROL;So;0;ON;;;;;N;;;;;
+1F6C3;CUSTOMS;So;0;ON;;;;;N;;;;;
+1F6C4;BAGGAGE CLAIM;So;0;ON;;;;;N;;;;;
+1F6C5;LEFT LUGGAGE;So;0;ON;;;;;N;;;;;
+1F6C6;TRIANGLE WITH ROUNDED CORNERS;So;0;ON;;;;;N;;;;;
+1F6C7;PROHIBITED SIGN;So;0;ON;;;;;N;;;;;
+1F6C8;CIRCLED INFORMATION SOURCE;So;0;ON;;;;;N;;;;;
+1F6C9;BOYS SYMBOL;So;0;ON;;;;;N;;;;;
+1F6CA;GIRLS SYMBOL;So;0;ON;;;;;N;;;;;
+1F6CB;COUCH AND LAMP;So;0;ON;;;;;N;;;;;
+1F6CC;SLEEPING ACCOMMODATION;So;0;ON;;;;;N;;;;;
+1F6CD;SHOPPING BAGS;So;0;ON;;;;;N;;;;;
+1F6CE;BELLHOP BELL;So;0;ON;;;;;N;;;;;
+1F6CF;BED;So;0;ON;;;;;N;;;;;
+1F6D0;PLACE OF WORSHIP;So;0;ON;;;;;N;;;;;
+1F6D1;OCTAGONAL SIGN;So;0;ON;;;;;N;;;;;
+1F6D2;SHOPPING TROLLEY;So;0;ON;;;;;N;;;;;
+1F6D3;STUPA;So;0;ON;;;;;N;;;;;
+1F6D4;PAGODA;So;0;ON;;;;;N;;;;;
+1F6E0;HAMMER AND WRENCH;So;0;ON;;;;;N;;;;;
+1F6E1;SHIELD;So;0;ON;;;;;N;;;;;
+1F6E2;OIL DRUM;So;0;ON;;;;;N;;;;;
+1F6E3;MOTORWAY;So;0;ON;;;;;N;;;;;
+1F6E4;RAILWAY TRACK;So;0;ON;;;;;N;;;;;
+1F6E5;MOTOR BOAT;So;0;ON;;;;;N;;;;;
+1F6E6;UP-POINTING MILITARY AIRPLANE;So;0;ON;;;;;N;;;;;
+1F6E7;UP-POINTING AIRPLANE;So;0;ON;;;;;N;;;;;
+1F6E8;UP-POINTING SMALL AIRPLANE;So;0;ON;;;;;N;;;;;
+1F6E9;SMALL AIRPLANE;So;0;ON;;;;;N;;;;;
+1F6EA;NORTHEAST-POINTING AIRPLANE;So;0;ON;;;;;N;;;;;
+1F6EB;AIRPLANE DEPARTURE;So;0;ON;;;;;N;;;;;
+1F6EC;AIRPLANE ARRIVING;So;0;ON;;;;;N;;;;;
+1F6F0;SATELLITE;So;0;ON;;;;;N;;;;;
+1F6F1;ONCOMING FIRE ENGINE;So;0;ON;;;;;N;;;;;
+1F6F2;DIESEL LOCOMOTIVE;So;0;ON;;;;;N;;;;;
+1F6F3;PASSENGER SHIP;So;0;ON;;;;;N;;;;;
+1F6F4;SCOOTER;So;0;ON;;;;;N;;;;;
+1F6F5;MOTOR SCOOTER;So;0;ON;;;;;N;;;;;
+1F6F6;CANOE;So;0;ON;;;;;N;;;;;
+1F6F7;SLED;So;0;ON;;;;;N;;;;;
+1F6F8;FLYING SAUCER;So;0;ON;;;;;N;;;;;
+1F700;ALCHEMICAL SYMBOL FOR QUINTESSENCE;So;0;ON;;;;;N;;;;;
+1F701;ALCHEMICAL SYMBOL FOR AIR;So;0;ON;;;;;N;;;;;
+1F702;ALCHEMICAL SYMBOL FOR FIRE;So;0;ON;;;;;N;;;;;
+1F703;ALCHEMICAL SYMBOL FOR EARTH;So;0;ON;;;;;N;;;;;
+1F704;ALCHEMICAL SYMBOL FOR WATER;So;0;ON;;;;;N;;;;;
+1F705;ALCHEMICAL SYMBOL FOR AQUAFORTIS;So;0;ON;;;;;N;;;;;
+1F706;ALCHEMICAL SYMBOL FOR AQUA REGIA;So;0;ON;;;;;N;;;;;
+1F707;ALCHEMICAL SYMBOL FOR AQUA REGIA-2;So;0;ON;;;;;N;;;;;
+1F708;ALCHEMICAL SYMBOL FOR AQUA VITAE;So;0;ON;;;;;N;;;;;
+1F709;ALCHEMICAL SYMBOL FOR AQUA VITAE-2;So;0;ON;;;;;N;;;;;
+1F70A;ALCHEMICAL SYMBOL FOR VINEGAR;So;0;ON;;;;;N;;;;;
+1F70B;ALCHEMICAL SYMBOL FOR VINEGAR-2;So;0;ON;;;;;N;;;;;
+1F70C;ALCHEMICAL SYMBOL FOR VINEGAR-3;So;0;ON;;;;;N;;;;;
+1F70D;ALCHEMICAL SYMBOL FOR SULFUR;So;0;ON;;;;;N;;;;;
+1F70E;ALCHEMICAL SYMBOL FOR PHILOSOPHERS SULFUR;So;0;ON;;;;;N;;;;;
+1F70F;ALCHEMICAL SYMBOL FOR BLACK SULFUR;So;0;ON;;;;;N;;;;;
+1F710;ALCHEMICAL SYMBOL FOR MERCURY SUBLIMATE;So;0;ON;;;;;N;;;;;
+1F711;ALCHEMICAL SYMBOL FOR MERCURY SUBLIMATE-2;So;0;ON;;;;;N;;;;;
+1F712;ALCHEMICAL SYMBOL FOR MERCURY SUBLIMATE-3;So;0;ON;;;;;N;;;;;
+1F713;ALCHEMICAL SYMBOL FOR CINNABAR;So;0;ON;;;;;N;;;;;
+1F714;ALCHEMICAL SYMBOL FOR SALT;So;0;ON;;;;;N;;;;;
+1F715;ALCHEMICAL SYMBOL FOR NITRE;So;0;ON;;;;;N;;;;;
+1F716;ALCHEMICAL SYMBOL FOR VITRIOL;So;0;ON;;;;;N;;;;;
+1F717;ALCHEMICAL SYMBOL FOR VITRIOL-2;So;0;ON;;;;;N;;;;;
+1F718;ALCHEMICAL SYMBOL FOR ROCK SALT;So;0;ON;;;;;N;;;;;
+1F719;ALCHEMICAL SYMBOL FOR ROCK SALT-2;So;0;ON;;;;;N;;;;;
+1F71A;ALCHEMICAL SYMBOL FOR GOLD;So;0;ON;;;;;N;;;;;
+1F71B;ALCHEMICAL SYMBOL FOR SILVER;So;0;ON;;;;;N;;;;;
+1F71C;ALCHEMICAL SYMBOL FOR IRON ORE;So;0;ON;;;;;N;;;;;
+1F71D;ALCHEMICAL SYMBOL FOR IRON ORE-2;So;0;ON;;;;;N;;;;;
+1F71E;ALCHEMICAL SYMBOL FOR CROCUS OF IRON;So;0;ON;;;;;N;;;;;
+1F71F;ALCHEMICAL SYMBOL FOR REGULUS OF IRON;So;0;ON;;;;;N;;;;;
+1F720;ALCHEMICAL SYMBOL FOR COPPER ORE;So;0;ON;;;;;N;;;;;
+1F721;ALCHEMICAL SYMBOL FOR IRON-COPPER ORE;So;0;ON;;;;;N;;;;;
+1F722;ALCHEMICAL SYMBOL FOR SUBLIMATE OF COPPER;So;0;ON;;;;;N;;;;;
+1F723;ALCHEMICAL SYMBOL FOR CROCUS OF COPPER;So;0;ON;;;;;N;;;;;
+1F724;ALCHEMICAL SYMBOL FOR CROCUS OF COPPER-2;So;0;ON;;;;;N;;;;;
+1F725;ALCHEMICAL SYMBOL FOR COPPER ANTIMONIATE;So;0;ON;;;;;N;;;;;
+1F726;ALCHEMICAL SYMBOL FOR SALT OF COPPER ANTIMONIATE;So;0;ON;;;;;N;;;;;
+1F727;ALCHEMICAL SYMBOL FOR SUBLIMATE OF SALT OF COPPER;So;0;ON;;;;;N;;;;;
+1F728;ALCHEMICAL SYMBOL FOR VERDIGRIS;So;0;ON;;;;;N;;;;;
+1F729;ALCHEMICAL SYMBOL FOR TIN ORE;So;0;ON;;;;;N;;;;;
+1F72A;ALCHEMICAL SYMBOL FOR LEAD ORE;So;0;ON;;;;;N;;;;;
+1F72B;ALCHEMICAL SYMBOL FOR ANTIMONY ORE;So;0;ON;;;;;N;;;;;
+1F72C;ALCHEMICAL SYMBOL FOR SUBLIMATE OF ANTIMONY;So;0;ON;;;;;N;;;;;
+1F72D;ALCHEMICAL SYMBOL FOR SALT OF ANTIMONY;So;0;ON;;;;;N;;;;;
+1F72E;ALCHEMICAL SYMBOL FOR SUBLIMATE OF SALT OF ANTIMONY;So;0;ON;;;;;N;;;;;
+1F72F;ALCHEMICAL SYMBOL FOR VINEGAR OF ANTIMONY;So;0;ON;;;;;N;;;;;
+1F730;ALCHEMICAL SYMBOL FOR REGULUS OF ANTIMONY;So;0;ON;;;;;N;;;;;
+1F731;ALCHEMICAL SYMBOL FOR REGULUS OF ANTIMONY-2;So;0;ON;;;;;N;;;;;
+1F732;ALCHEMICAL SYMBOL FOR REGULUS;So;0;ON;;;;;N;;;;;
+1F733;ALCHEMICAL SYMBOL FOR REGULUS-2;So;0;ON;;;;;N;;;;;
+1F734;ALCHEMICAL SYMBOL FOR REGULUS-3;So;0;ON;;;;;N;;;;;
+1F735;ALCHEMICAL SYMBOL FOR REGULUS-4;So;0;ON;;;;;N;;;;;
+1F736;ALCHEMICAL SYMBOL FOR ALKALI;So;0;ON;;;;;N;;;;;
+1F737;ALCHEMICAL SYMBOL FOR ALKALI-2;So;0;ON;;;;;N;;;;;
+1F738;ALCHEMICAL SYMBOL FOR MARCASITE;So;0;ON;;;;;N;;;;;
+1F739;ALCHEMICAL SYMBOL FOR SAL-AMMONIAC;So;0;ON;;;;;N;;;;;
+1F73A;ALCHEMICAL SYMBOL FOR ARSENIC;So;0;ON;;;;;N;;;;;
+1F73B;ALCHEMICAL SYMBOL FOR REALGAR;So;0;ON;;;;;N;;;;;
+1F73C;ALCHEMICAL SYMBOL FOR REALGAR-2;So;0;ON;;;;;N;;;;;
+1F73D;ALCHEMICAL SYMBOL FOR AURIPIGMENT;So;0;ON;;;;;N;;;;;
+1F73E;ALCHEMICAL SYMBOL FOR BISMUTH ORE;So;0;ON;;;;;N;;;;;
+1F73F;ALCHEMICAL SYMBOL FOR TARTAR;So;0;ON;;;;;N;;;;;
+1F740;ALCHEMICAL SYMBOL FOR TARTAR-2;So;0;ON;;;;;N;;;;;
+1F741;ALCHEMICAL SYMBOL FOR QUICK LIME;So;0;ON;;;;;N;;;;;
+1F742;ALCHEMICAL SYMBOL FOR BORAX;So;0;ON;;;;;N;;;;;
+1F743;ALCHEMICAL SYMBOL FOR BORAX-2;So;0;ON;;;;;N;;;;;
+1F744;ALCHEMICAL SYMBOL FOR BORAX-3;So;0;ON;;;;;N;;;;;
+1F745;ALCHEMICAL SYMBOL FOR ALUM;So;0;ON;;;;;N;;;;;
+1F746;ALCHEMICAL SYMBOL FOR OIL;So;0;ON;;;;;N;;;;;
+1F747;ALCHEMICAL SYMBOL FOR SPIRIT;So;0;ON;;;;;N;;;;;
+1F748;ALCHEMICAL SYMBOL FOR TINCTURE;So;0;ON;;;;;N;;;;;
+1F749;ALCHEMICAL SYMBOL FOR GUM;So;0;ON;;;;;N;;;;;
+1F74A;ALCHEMICAL SYMBOL FOR WAX;So;0;ON;;;;;N;;;;;
+1F74B;ALCHEMICAL SYMBOL FOR POWDER;So;0;ON;;;;;N;;;;;
+1F74C;ALCHEMICAL SYMBOL FOR CALX;So;0;ON;;;;;N;;;;;
+1F74D;ALCHEMICAL SYMBOL FOR TUTTY;So;0;ON;;;;;N;;;;;
+1F74E;ALCHEMICAL SYMBOL FOR CAPUT MORTUUM;So;0;ON;;;;;N;;;;;
+1F74F;ALCHEMICAL SYMBOL FOR SCEPTER OF JOVE;So;0;ON;;;;;N;;;;;
+1F750;ALCHEMICAL SYMBOL FOR CADUCEUS;So;0;ON;;;;;N;;;;;
+1F751;ALCHEMICAL SYMBOL FOR TRIDENT;So;0;ON;;;;;N;;;;;
+1F752;ALCHEMICAL SYMBOL FOR STARRED TRIDENT;So;0;ON;;;;;N;;;;;
+1F753;ALCHEMICAL SYMBOL FOR LODESTONE;So;0;ON;;;;;N;;;;;
+1F754;ALCHEMICAL SYMBOL FOR SOAP;So;0;ON;;;;;N;;;;;
+1F755;ALCHEMICAL SYMBOL FOR URINE;So;0;ON;;;;;N;;;;;
+1F756;ALCHEMICAL SYMBOL FOR HORSE DUNG;So;0;ON;;;;;N;;;;;
+1F757;ALCHEMICAL SYMBOL FOR ASHES;So;0;ON;;;;;N;;;;;
+1F758;ALCHEMICAL SYMBOL FOR POT ASHES;So;0;ON;;;;;N;;;;;
+1F759;ALCHEMICAL SYMBOL FOR BRICK;So;0;ON;;;;;N;;;;;
+1F75A;ALCHEMICAL SYMBOL FOR POWDERED BRICK;So;0;ON;;;;;N;;;;;
+1F75B;ALCHEMICAL SYMBOL FOR AMALGAM;So;0;ON;;;;;N;;;;;
+1F75C;ALCHEMICAL SYMBOL FOR STRATUM SUPER STRATUM;So;0;ON;;;;;N;;;;;
+1F75D;ALCHEMICAL SYMBOL FOR STRATUM SUPER STRATUM-2;So;0;ON;;;;;N;;;;;
+1F75E;ALCHEMICAL SYMBOL FOR SUBLIMATION;So;0;ON;;;;;N;;;;;
+1F75F;ALCHEMICAL SYMBOL FOR PRECIPITATE;So;0;ON;;;;;N;;;;;
+1F760;ALCHEMICAL SYMBOL FOR DISTILL;So;0;ON;;;;;N;;;;;
+1F761;ALCHEMICAL SYMBOL FOR DISSOLVE;So;0;ON;;;;;N;;;;;
+1F762;ALCHEMICAL SYMBOL FOR DISSOLVE-2;So;0;ON;;;;;N;;;;;
+1F763;ALCHEMICAL SYMBOL FOR PURIFY;So;0;ON;;;;;N;;;;;
+1F764;ALCHEMICAL SYMBOL FOR PUTREFACTION;So;0;ON;;;;;N;;;;;
+1F765;ALCHEMICAL SYMBOL FOR CRUCIBLE;So;0;ON;;;;;N;;;;;
+1F766;ALCHEMICAL SYMBOL FOR CRUCIBLE-2;So;0;ON;;;;;N;;;;;
+1F767;ALCHEMICAL SYMBOL FOR CRUCIBLE-3;So;0;ON;;;;;N;;;;;
+1F768;ALCHEMICAL SYMBOL FOR CRUCIBLE-4;So;0;ON;;;;;N;;;;;
+1F769;ALCHEMICAL SYMBOL FOR CRUCIBLE-5;So;0;ON;;;;;N;;;;;
+1F76A;ALCHEMICAL SYMBOL FOR ALEMBIC;So;0;ON;;;;;N;;;;;
+1F76B;ALCHEMICAL SYMBOL FOR BATH OF MARY;So;0;ON;;;;;N;;;;;
+1F76C;ALCHEMICAL SYMBOL FOR BATH OF VAPOURS;So;0;ON;;;;;N;;;;;
+1F76D;ALCHEMICAL SYMBOL FOR RETORT;So;0;ON;;;;;N;;;;;
+1F76E;ALCHEMICAL SYMBOL FOR HOUR;So;0;ON;;;;;N;;;;;
+1F76F;ALCHEMICAL SYMBOL FOR NIGHT;So;0;ON;;;;;N;;;;;
+1F770;ALCHEMICAL SYMBOL FOR DAY-NIGHT;So;0;ON;;;;;N;;;;;
+1F771;ALCHEMICAL SYMBOL FOR MONTH;So;0;ON;;;;;N;;;;;
+1F772;ALCHEMICAL SYMBOL FOR HALF DRAM;So;0;ON;;;;;N;;;;;
+1F773;ALCHEMICAL SYMBOL FOR HALF OUNCE;So;0;ON;;;;;N;;;;;
+1F780;BLACK LEFT-POINTING ISOSCELES RIGHT TRIANGLE;So;0;ON;;;;;N;;;;;
+1F781;BLACK UP-POINTING ISOSCELES RIGHT TRIANGLE;So;0;ON;;;;;N;;;;;
+1F782;BLACK RIGHT-POINTING ISOSCELES RIGHT TRIANGLE;So;0;ON;;;;;N;;;;;
+1F783;BLACK DOWN-POINTING ISOSCELES RIGHT TRIANGLE;So;0;ON;;;;;N;;;;;
+1F784;BLACK SLIGHTLY SMALL CIRCLE;So;0;ON;;;;;N;;;;;
+1F785;MEDIUM BOLD WHITE CIRCLE;So;0;ON;;;;;N;;;;;
+1F786;BOLD WHITE CIRCLE;So;0;ON;;;;;N;;;;;
+1F787;HEAVY WHITE CIRCLE;So;0;ON;;;;;N;;;;;
+1F788;VERY HEAVY WHITE CIRCLE;So;0;ON;;;;;N;;;;;
+1F789;EXTREMELY HEAVY WHITE CIRCLE;So;0;ON;;;;;N;;;;;
+1F78A;WHITE CIRCLE CONTAINING BLACK SMALL CIRCLE;So;0;ON;;;;;N;;;;;
+1F78B;ROUND TARGET;So;0;ON;;;;;N;;;;;
+1F78C;BLACK TINY SQUARE;So;0;ON;;;;;N;;;;;
+1F78D;BLACK SLIGHTLY SMALL SQUARE;So;0;ON;;;;;N;;;;;
+1F78E;LIGHT WHITE SQUARE;So;0;ON;;;;;N;;;;;
+1F78F;MEDIUM WHITE SQUARE;So;0;ON;;;;;N;;;;;
+1F790;BOLD WHITE SQUARE;So;0;ON;;;;;N;;;;;
+1F791;HEAVY WHITE SQUARE;So;0;ON;;;;;N;;;;;
+1F792;VERY HEAVY WHITE SQUARE;So;0;ON;;;;;N;;;;;
+1F793;EXTREMELY HEAVY WHITE SQUARE;So;0;ON;;;;;N;;;;;
+1F794;WHITE SQUARE CONTAINING BLACK VERY SMALL SQUARE;So;0;ON;;;;;N;;;;;
+1F795;WHITE SQUARE CONTAINING BLACK MEDIUM SQUARE;So;0;ON;;;;;N;;;;;
+1F796;SQUARE TARGET;So;0;ON;;;;;N;;;;;
+1F797;BLACK TINY DIAMOND;So;0;ON;;;;;N;;;;;
+1F798;BLACK VERY SMALL DIAMOND;So;0;ON;;;;;N;;;;;
+1F799;BLACK MEDIUM SMALL DIAMOND;So;0;ON;;;;;N;;;;;
+1F79A;WHITE DIAMOND CONTAINING BLACK VERY SMALL DIAMOND;So;0;ON;;;;;N;;;;;
+1F79B;WHITE DIAMOND CONTAINING BLACK MEDIUM DIAMOND;So;0;ON;;;;;N;;;;;
+1F79C;DIAMOND TARGET;So;0;ON;;;;;N;;;;;
+1F79D;BLACK TINY LOZENGE;So;0;ON;;;;;N;;;;;
+1F79E;BLACK VERY SMALL LOZENGE;So;0;ON;;;;;N;;;;;
+1F79F;BLACK MEDIUM SMALL LOZENGE;So;0;ON;;;;;N;;;;;
+1F7A0;WHITE LOZENGE CONTAINING BLACK SMALL LOZENGE;So;0;ON;;;;;N;;;;;
+1F7A1;THIN GREEK CROSS;So;0;ON;;;;;N;;;;;
+1F7A2;LIGHT GREEK CROSS;So;0;ON;;;;;N;;;;;
+1F7A3;MEDIUM GREEK CROSS;So;0;ON;;;;;N;;;;;
+1F7A4;BOLD GREEK CROSS;So;0;ON;;;;;N;;;;;
+1F7A5;VERY BOLD GREEK CROSS;So;0;ON;;;;;N;;;;;
+1F7A6;VERY HEAVY GREEK CROSS;So;0;ON;;;;;N;;;;;
+1F7A7;EXTREMELY HEAVY GREEK CROSS;So;0;ON;;;;;N;;;;;
+1F7A8;THIN SALTIRE;So;0;ON;;;;;N;;;;;
+1F7A9;LIGHT SALTIRE;So;0;ON;;;;;N;;;;;
+1F7AA;MEDIUM SALTIRE;So;0;ON;;;;;N;;;;;
+1F7AB;BOLD SALTIRE;So;0;ON;;;;;N;;;;;
+1F7AC;HEAVY SALTIRE;So;0;ON;;;;;N;;;;;
+1F7AD;VERY HEAVY SALTIRE;So;0;ON;;;;;N;;;;;
+1F7AE;EXTREMELY HEAVY SALTIRE;So;0;ON;;;;;N;;;;;
+1F7AF;LIGHT FIVE SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+1F7B0;MEDIUM FIVE SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+1F7B1;BOLD FIVE SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+1F7B2;HEAVY FIVE SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+1F7B3;VERY HEAVY FIVE SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+1F7B4;EXTREMELY HEAVY FIVE SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+1F7B5;LIGHT SIX SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+1F7B6;MEDIUM SIX SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+1F7B7;BOLD SIX SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+1F7B8;HEAVY SIX SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+1F7B9;VERY HEAVY SIX SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+1F7BA;EXTREMELY HEAVY SIX SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+1F7BB;LIGHT EIGHT SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+1F7BC;MEDIUM EIGHT SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+1F7BD;BOLD EIGHT SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+1F7BE;HEAVY EIGHT SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+1F7BF;VERY HEAVY EIGHT SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+1F7C0;LIGHT THREE POINTED BLACK STAR;So;0;ON;;;;;N;;;;;
+1F7C1;MEDIUM THREE POINTED BLACK STAR;So;0;ON;;;;;N;;;;;
+1F7C2;THREE POINTED BLACK STAR;So;0;ON;;;;;N;;;;;
+1F7C3;MEDIUM THREE POINTED PINWHEEL STAR;So;0;ON;;;;;N;;;;;
+1F7C4;LIGHT FOUR POINTED BLACK STAR;So;0;ON;;;;;N;;;;;
+1F7C5;MEDIUM FOUR POINTED BLACK STAR;So;0;ON;;;;;N;;;;;
+1F7C6;FOUR POINTED BLACK STAR;So;0;ON;;;;;N;;;;;
+1F7C7;MEDIUM FOUR POINTED PINWHEEL STAR;So;0;ON;;;;;N;;;;;
+1F7C8;REVERSE LIGHT FOUR POINTED PINWHEEL STAR;So;0;ON;;;;;N;;;;;
+1F7C9;LIGHT FIVE POINTED BLACK STAR;So;0;ON;;;;;N;;;;;
+1F7CA;HEAVY FIVE POINTED BLACK STAR;So;0;ON;;;;;N;;;;;
+1F7CB;MEDIUM SIX POINTED BLACK STAR;So;0;ON;;;;;N;;;;;
+1F7CC;HEAVY SIX POINTED BLACK STAR;So;0;ON;;;;;N;;;;;
+1F7CD;SIX POINTED PINWHEEL STAR;So;0;ON;;;;;N;;;;;
+1F7CE;MEDIUM EIGHT POINTED BLACK STAR;So;0;ON;;;;;N;;;;;
+1F7CF;HEAVY EIGHT POINTED BLACK STAR;So;0;ON;;;;;N;;;;;
+1F7D0;VERY HEAVY EIGHT POINTED BLACK STAR;So;0;ON;;;;;N;;;;;
+1F7D1;HEAVY EIGHT POINTED PINWHEEL STAR;So;0;ON;;;;;N;;;;;
+1F7D2;LIGHT TWELVE POINTED BLACK STAR;So;0;ON;;;;;N;;;;;
+1F7D3;HEAVY TWELVE POINTED BLACK STAR;So;0;ON;;;;;N;;;;;
+1F7D4;HEAVY TWELVE POINTED PINWHEEL STAR;So;0;ON;;;;;N;;;;;
+1F800;LEFTWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F801;UPWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F802;RIGHTWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F803;DOWNWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F804;LEFTWARDS ARROW WITH MEDIUM TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F805;UPWARDS ARROW WITH MEDIUM TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F806;RIGHTWARDS ARROW WITH MEDIUM TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F807;DOWNWARDS ARROW WITH MEDIUM TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F808;LEFTWARDS ARROW WITH LARGE TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F809;UPWARDS ARROW WITH LARGE TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F80A;RIGHTWARDS ARROW WITH LARGE TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F80B;DOWNWARDS ARROW WITH LARGE TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F810;LEFTWARDS ARROW WITH SMALL EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F811;UPWARDS ARROW WITH SMALL EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F812;RIGHTWARDS ARROW WITH SMALL EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F813;DOWNWARDS ARROW WITH SMALL EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F814;LEFTWARDS ARROW WITH EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F815;UPWARDS ARROW WITH EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F816;RIGHTWARDS ARROW WITH EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F817;DOWNWARDS ARROW WITH EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F818;HEAVY LEFTWARDS ARROW WITH EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F819;HEAVY UPWARDS ARROW WITH EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F81A;HEAVY RIGHTWARDS ARROW WITH EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F81B;HEAVY DOWNWARDS ARROW WITH EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F81C;HEAVY LEFTWARDS ARROW WITH LARGE EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F81D;HEAVY UPWARDS ARROW WITH LARGE EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F81E;HEAVY RIGHTWARDS ARROW WITH LARGE EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F81F;HEAVY DOWNWARDS ARROW WITH LARGE EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F820;LEFTWARDS TRIANGLE-HEADED ARROW WITH NARROW SHAFT;So;0;ON;;;;;N;;;;;
+1F821;UPWARDS TRIANGLE-HEADED ARROW WITH NARROW SHAFT;So;0;ON;;;;;N;;;;;
+1F822;RIGHTWARDS TRIANGLE-HEADED ARROW WITH NARROW SHAFT;So;0;ON;;;;;N;;;;;
+1F823;DOWNWARDS TRIANGLE-HEADED ARROW WITH NARROW SHAFT;So;0;ON;;;;;N;;;;;
+1F824;LEFTWARDS TRIANGLE-HEADED ARROW WITH MEDIUM SHAFT;So;0;ON;;;;;N;;;;;
+1F825;UPWARDS TRIANGLE-HEADED ARROW WITH MEDIUM SHAFT;So;0;ON;;;;;N;;;;;
+1F826;RIGHTWARDS TRIANGLE-HEADED ARROW WITH MEDIUM SHAFT;So;0;ON;;;;;N;;;;;
+1F827;DOWNWARDS TRIANGLE-HEADED ARROW WITH MEDIUM SHAFT;So;0;ON;;;;;N;;;;;
+1F828;LEFTWARDS TRIANGLE-HEADED ARROW WITH BOLD SHAFT;So;0;ON;;;;;N;;;;;
+1F829;UPWARDS TRIANGLE-HEADED ARROW WITH BOLD SHAFT;So;0;ON;;;;;N;;;;;
+1F82A;RIGHTWARDS TRIANGLE-HEADED ARROW WITH BOLD SHAFT;So;0;ON;;;;;N;;;;;
+1F82B;DOWNWARDS TRIANGLE-HEADED ARROW WITH BOLD SHAFT;So;0;ON;;;;;N;;;;;
+1F82C;LEFTWARDS TRIANGLE-HEADED ARROW WITH HEAVY SHAFT;So;0;ON;;;;;N;;;;;
+1F82D;UPWARDS TRIANGLE-HEADED ARROW WITH HEAVY SHAFT;So;0;ON;;;;;N;;;;;
+1F82E;RIGHTWARDS TRIANGLE-HEADED ARROW WITH HEAVY SHAFT;So;0;ON;;;;;N;;;;;
+1F82F;DOWNWARDS TRIANGLE-HEADED ARROW WITH HEAVY SHAFT;So;0;ON;;;;;N;;;;;
+1F830;LEFTWARDS TRIANGLE-HEADED ARROW WITH VERY HEAVY SHAFT;So;0;ON;;;;;N;;;;;
+1F831;UPWARDS TRIANGLE-HEADED ARROW WITH VERY HEAVY SHAFT;So;0;ON;;;;;N;;;;;
+1F832;RIGHTWARDS TRIANGLE-HEADED ARROW WITH VERY HEAVY SHAFT;So;0;ON;;;;;N;;;;;
+1F833;DOWNWARDS TRIANGLE-HEADED ARROW WITH VERY HEAVY SHAFT;So;0;ON;;;;;N;;;;;
+1F834;LEFTWARDS FINGER-POST ARROW;So;0;ON;;;;;N;;;;;
+1F835;UPWARDS FINGER-POST ARROW;So;0;ON;;;;;N;;;;;
+1F836;RIGHTWARDS FINGER-POST ARROW;So;0;ON;;;;;N;;;;;
+1F837;DOWNWARDS FINGER-POST ARROW;So;0;ON;;;;;N;;;;;
+1F838;LEFTWARDS SQUARED ARROW;So;0;ON;;;;;N;;;;;
+1F839;UPWARDS SQUARED ARROW;So;0;ON;;;;;N;;;;;
+1F83A;RIGHTWARDS SQUARED ARROW;So;0;ON;;;;;N;;;;;
+1F83B;DOWNWARDS SQUARED ARROW;So;0;ON;;;;;N;;;;;
+1F83C;LEFTWARDS COMPRESSED ARROW;So;0;ON;;;;;N;;;;;
+1F83D;UPWARDS COMPRESSED ARROW;So;0;ON;;;;;N;;;;;
+1F83E;RIGHTWARDS COMPRESSED ARROW;So;0;ON;;;;;N;;;;;
+1F83F;DOWNWARDS COMPRESSED ARROW;So;0;ON;;;;;N;;;;;
+1F840;LEFTWARDS HEAVY COMPRESSED ARROW;So;0;ON;;;;;N;;;;;
+1F841;UPWARDS HEAVY COMPRESSED ARROW;So;0;ON;;;;;N;;;;;
+1F842;RIGHTWARDS HEAVY COMPRESSED ARROW;So;0;ON;;;;;N;;;;;
+1F843;DOWNWARDS HEAVY COMPRESSED ARROW;So;0;ON;;;;;N;;;;;
+1F844;LEFTWARDS HEAVY ARROW;So;0;ON;;;;;N;;;;;
+1F845;UPWARDS HEAVY ARROW;So;0;ON;;;;;N;;;;;
+1F846;RIGHTWARDS HEAVY ARROW;So;0;ON;;;;;N;;;;;
+1F847;DOWNWARDS HEAVY ARROW;So;0;ON;;;;;N;;;;;
+1F850;LEFTWARDS SANS-SERIF ARROW;So;0;ON;;;;;N;;;;;
+1F851;UPWARDS SANS-SERIF ARROW;So;0;ON;;;;;N;;;;;
+1F852;RIGHTWARDS SANS-SERIF ARROW;So;0;ON;;;;;N;;;;;
+1F853;DOWNWARDS SANS-SERIF ARROW;So;0;ON;;;;;N;;;;;
+1F854;NORTH WEST SANS-SERIF ARROW;So;0;ON;;;;;N;;;;;
+1F855;NORTH EAST SANS-SERIF ARROW;So;0;ON;;;;;N;;;;;
+1F856;SOUTH EAST SANS-SERIF ARROW;So;0;ON;;;;;N;;;;;
+1F857;SOUTH WEST SANS-SERIF ARROW;So;0;ON;;;;;N;;;;;
+1F858;LEFT RIGHT SANS-SERIF ARROW;So;0;ON;;;;;N;;;;;
+1F859;UP DOWN SANS-SERIF ARROW;So;0;ON;;;;;N;;;;;
+1F860;WIDE-HEADED LEFTWARDS LIGHT BARB ARROW;So;0;ON;;;;;N;;;;;
+1F861;WIDE-HEADED UPWARDS LIGHT BARB ARROW;So;0;ON;;;;;N;;;;;
+1F862;WIDE-HEADED RIGHTWARDS LIGHT BARB ARROW;So;0;ON;;;;;N;;;;;
+1F863;WIDE-HEADED DOWNWARDS LIGHT BARB ARROW;So;0;ON;;;;;N;;;;;
+1F864;WIDE-HEADED NORTH WEST LIGHT BARB ARROW;So;0;ON;;;;;N;;;;;
+1F865;WIDE-HEADED NORTH EAST LIGHT BARB ARROW;So;0;ON;;;;;N;;;;;
+1F866;WIDE-HEADED SOUTH EAST LIGHT BARB ARROW;So;0;ON;;;;;N;;;;;
+1F867;WIDE-HEADED SOUTH WEST LIGHT BARB ARROW;So;0;ON;;;;;N;;;;;
+1F868;WIDE-HEADED LEFTWARDS BARB ARROW;So;0;ON;;;;;N;;;;;
+1F869;WIDE-HEADED UPWARDS BARB ARROW;So;0;ON;;;;;N;;;;;
+1F86A;WIDE-HEADED RIGHTWARDS BARB ARROW;So;0;ON;;;;;N;;;;;
+1F86B;WIDE-HEADED DOWNWARDS BARB ARROW;So;0;ON;;;;;N;;;;;
+1F86C;WIDE-HEADED NORTH WEST BARB ARROW;So;0;ON;;;;;N;;;;;
+1F86D;WIDE-HEADED NORTH EAST BARB ARROW;So;0;ON;;;;;N;;;;;
+1F86E;WIDE-HEADED SOUTH EAST BARB ARROW;So;0;ON;;;;;N;;;;;
+1F86F;WIDE-HEADED SOUTH WEST BARB ARROW;So;0;ON;;;;;N;;;;;
+1F870;WIDE-HEADED LEFTWARDS MEDIUM BARB ARROW;So;0;ON;;;;;N;;;;;
+1F871;WIDE-HEADED UPWARDS MEDIUM BARB ARROW;So;0;ON;;;;;N;;;;;
+1F872;WIDE-HEADED RIGHTWARDS MEDIUM BARB ARROW;So;0;ON;;;;;N;;;;;
+1F873;WIDE-HEADED DOWNWARDS MEDIUM BARB ARROW;So;0;ON;;;;;N;;;;;
+1F874;WIDE-HEADED NORTH WEST MEDIUM BARB ARROW;So;0;ON;;;;;N;;;;;
+1F875;WIDE-HEADED NORTH EAST MEDIUM BARB ARROW;So;0;ON;;;;;N;;;;;
+1F876;WIDE-HEADED SOUTH EAST MEDIUM BARB ARROW;So;0;ON;;;;;N;;;;;
+1F877;WIDE-HEADED SOUTH WEST MEDIUM BARB ARROW;So;0;ON;;;;;N;;;;;
+1F878;WIDE-HEADED LEFTWARDS HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;
+1F879;WIDE-HEADED UPWARDS HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;
+1F87A;WIDE-HEADED RIGHTWARDS HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;
+1F87B;WIDE-HEADED DOWNWARDS HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;
+1F87C;WIDE-HEADED NORTH WEST HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;
+1F87D;WIDE-HEADED NORTH EAST HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;
+1F87E;WIDE-HEADED SOUTH EAST HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;
+1F87F;WIDE-HEADED SOUTH WEST HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;
+1F880;WIDE-HEADED LEFTWARDS VERY HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;
+1F881;WIDE-HEADED UPWARDS VERY HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;
+1F882;WIDE-HEADED RIGHTWARDS VERY HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;
+1F883;WIDE-HEADED DOWNWARDS VERY HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;
+1F884;WIDE-HEADED NORTH WEST VERY HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;
+1F885;WIDE-HEADED NORTH EAST VERY HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;
+1F886;WIDE-HEADED SOUTH EAST VERY HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;
+1F887;WIDE-HEADED SOUTH WEST VERY HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;
+1F890;LEFTWARDS TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F891;UPWARDS TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F892;RIGHTWARDS TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F893;DOWNWARDS TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F894;LEFTWARDS WHITE ARROW WITHIN TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F895;UPWARDS WHITE ARROW WITHIN TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F896;RIGHTWARDS WHITE ARROW WITHIN TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F897;DOWNWARDS WHITE ARROW WITHIN TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F898;LEFTWARDS ARROW WITH NOTCHED TAIL;So;0;ON;;;;;N;;;;;
+1F899;UPWARDS ARROW WITH NOTCHED TAIL;So;0;ON;;;;;N;;;;;
+1F89A;RIGHTWARDS ARROW WITH NOTCHED TAIL;So;0;ON;;;;;N;;;;;
+1F89B;DOWNWARDS ARROW WITH NOTCHED TAIL;So;0;ON;;;;;N;;;;;
+1F89C;HEAVY ARROW SHAFT WIDTH ONE;So;0;ON;;;;;N;;;;;
+1F89D;HEAVY ARROW SHAFT WIDTH TWO THIRDS;So;0;ON;;;;;N;;;;;
+1F89E;HEAVY ARROW SHAFT WIDTH ONE HALF;So;0;ON;;;;;N;;;;;
+1F89F;HEAVY ARROW SHAFT WIDTH ONE THIRD;So;0;ON;;;;;N;;;;;
+1F8A0;LEFTWARDS BOTTOM-SHADED WHITE ARROW;So;0;ON;;;;;N;;;;;
+1F8A1;RIGHTWARDS BOTTOM SHADED WHITE ARROW;So;0;ON;;;;;N;;;;;
+1F8A2;LEFTWARDS TOP SHADED WHITE ARROW;So;0;ON;;;;;N;;;;;
+1F8A3;RIGHTWARDS TOP SHADED WHITE ARROW;So;0;ON;;;;;N;;;;;
+1F8A4;LEFTWARDS LEFT-SHADED WHITE ARROW;So;0;ON;;;;;N;;;;;
+1F8A5;RIGHTWARDS RIGHT-SHADED WHITE ARROW;So;0;ON;;;;;N;;;;;
+1F8A6;LEFTWARDS RIGHT-SHADED WHITE ARROW;So;0;ON;;;;;N;;;;;
+1F8A7;RIGHTWARDS LEFT-SHADED WHITE ARROW;So;0;ON;;;;;N;;;;;
+1F8A8;LEFTWARDS BACK-TILTED SHADOWED WHITE ARROW;So;0;ON;;;;;N;;;;;
+1F8A9;RIGHTWARDS BACK-TILTED SHADOWED WHITE ARROW;So;0;ON;;;;;N;;;;;
+1F8AA;LEFTWARDS FRONT-TILTED SHADOWED WHITE ARROW;So;0;ON;;;;;N;;;;;
+1F8AB;RIGHTWARDS FRONT-TILTED SHADOWED WHITE ARROW;So;0;ON;;;;;N;;;;;
+1F8AC;WHITE ARROW SHAFT WIDTH ONE;So;0;ON;;;;;N;;;;;
+1F8AD;WHITE ARROW SHAFT WIDTH TWO THIRDS;So;0;ON;;;;;N;;;;;
+1F900;CIRCLED CROSS FORMEE WITH FOUR DOTS;So;0;ON;;;;;N;;;;;
+1F901;CIRCLED CROSS FORMEE WITH TWO DOTS;So;0;ON;;;;;N;;;;;
+1F902;CIRCLED CROSS FORMEE;So;0;ON;;;;;N;;;;;
+1F903;LEFT HALF CIRCLE WITH FOUR DOTS;So;0;ON;;;;;N;;;;;
+1F904;LEFT HALF CIRCLE WITH THREE DOTS;So;0;ON;;;;;N;;;;;
+1F905;LEFT HALF CIRCLE WITH TWO DOTS;So;0;ON;;;;;N;;;;;
+1F906;LEFT HALF CIRCLE WITH DOT;So;0;ON;;;;;N;;;;;
+1F907;LEFT HALF CIRCLE;So;0;ON;;;;;N;;;;;
+1F908;DOWNWARD FACING HOOK;So;0;ON;;;;;N;;;;;
+1F909;DOWNWARD FACING NOTCHED HOOK;So;0;ON;;;;;N;;;;;
+1F90A;DOWNWARD FACING HOOK WITH DOT;So;0;ON;;;;;N;;;;;
+1F90B;DOWNWARD FACING NOTCHED HOOK WITH DOT;So;0;ON;;;;;N;;;;;
+1F910;ZIPPER-MOUTH FACE;So;0;ON;;;;;N;;;;;
+1F911;MONEY-MOUTH FACE;So;0;ON;;;;;N;;;;;
+1F912;FACE WITH THERMOMETER;So;0;ON;;;;;N;;;;;
+1F913;NERD FACE;So;0;ON;;;;;N;;;;;
+1F914;THINKING FACE;So;0;ON;;;;;N;;;;;
+1F915;FACE WITH HEAD-BANDAGE;So;0;ON;;;;;N;;;;;
+1F916;ROBOT FACE;So;0;ON;;;;;N;;;;;
+1F917;HUGGING FACE;So;0;ON;;;;;N;;;;;
+1F918;SIGN OF THE HORNS;So;0;ON;;;;;N;;;;;
+1F919;CALL ME HAND;So;0;ON;;;;;N;;;;;
+1F91A;RAISED BACK OF HAND;So;0;ON;;;;;N;;;;;
+1F91B;LEFT-FACING FIST;So;0;ON;;;;;N;;;;;
+1F91C;RIGHT-FACING FIST;So;0;ON;;;;;N;;;;;
+1F91D;HANDSHAKE;So;0;ON;;;;;N;;;;;
+1F91E;HAND WITH INDEX AND MIDDLE FINGERS CROSSED;So;0;ON;;;;;N;;;;;
+1F91F;I LOVE YOU HAND SIGN;So;0;ON;;;;;N;;;;;
+1F920;FACE WITH COWBOY HAT;So;0;ON;;;;;N;;;;;
+1F921;CLOWN FACE;So;0;ON;;;;;N;;;;;
+1F922;NAUSEATED FACE;So;0;ON;;;;;N;;;;;
+1F923;ROLLING ON THE FLOOR LAUGHING;So;0;ON;;;;;N;;;;;
+1F924;DROOLING FACE;So;0;ON;;;;;N;;;;;
+1F925;LYING FACE;So;0;ON;;;;;N;;;;;
+1F926;FACE PALM;So;0;ON;;;;;N;;;;;
+1F927;SNEEZING FACE;So;0;ON;;;;;N;;;;;
+1F928;FACE WITH ONE EYEBROW RAISED;So;0;ON;;;;;N;;;;;
+1F929;GRINNING FACE WITH STAR EYES;So;0;ON;;;;;N;;;;;
+1F92A;GRINNING FACE WITH ONE LARGE AND ONE SMALL EYE;So;0;ON;;;;;N;;;;;
+1F92B;FACE WITH FINGER COVERING CLOSED LIPS;So;0;ON;;;;;N;;;;;
+1F92C;SERIOUS FACE WITH SYMBOLS COVERING MOUTH;So;0;ON;;;;;N;;;;;
+1F92D;SMILING FACE WITH SMILING EYES AND HAND COVERING MOUTH;So;0;ON;;;;;N;;;;;
+1F92E;FACE WITH OPEN MOUTH VOMITING;So;0;ON;;;;;N;;;;;
+1F92F;SHOCKED FACE WITH EXPLODING HEAD;So;0;ON;;;;;N;;;;;
+1F930;PREGNANT WOMAN;So;0;ON;;;;;N;;;;;
+1F931;BREAST-FEEDING;So;0;ON;;;;;N;;;;;
+1F932;PALMS UP TOGETHER;So;0;ON;;;;;N;;;;;
+1F933;SELFIE;So;0;ON;;;;;N;;;;;
+1F934;PRINCE;So;0;ON;;;;;N;;;;;
+1F935;MAN IN TUXEDO;So;0;ON;;;;;N;;;;;
+1F936;MOTHER CHRISTMAS;So;0;ON;;;;;N;;;;;
+1F937;SHRUG;So;0;ON;;;;;N;;;;;
+1F938;PERSON DOING CARTWHEEL;So;0;ON;;;;;N;;;;;
+1F939;JUGGLING;So;0;ON;;;;;N;;;;;
+1F93A;FENCER;So;0;ON;;;;;N;;;;;
+1F93B;MODERN PENTATHLON;So;0;ON;;;;;N;;;;;
+1F93C;WRESTLERS;So;0;ON;;;;;N;;;;;
+1F93D;WATER POLO;So;0;ON;;;;;N;;;;;
+1F93E;HANDBALL;So;0;ON;;;;;N;;;;;
+1F940;WILTED FLOWER;So;0;ON;;;;;N;;;;;
+1F941;DRUM WITH DRUMSTICKS;So;0;ON;;;;;N;;;;;
+1F942;CLINKING GLASSES;So;0;ON;;;;;N;;;;;
+1F943;TUMBLER GLASS;So;0;ON;;;;;N;;;;;
+1F944;SPOON;So;0;ON;;;;;N;;;;;
+1F945;GOAL NET;So;0;ON;;;;;N;;;;;
+1F946;RIFLE;So;0;ON;;;;;N;;;;;
+1F947;FIRST PLACE MEDAL;So;0;ON;;;;;N;;;;;
+1F948;SECOND PLACE MEDAL;So;0;ON;;;;;N;;;;;
+1F949;THIRD PLACE MEDAL;So;0;ON;;;;;N;;;;;
+1F94A;BOXING GLOVE;So;0;ON;;;;;N;;;;;
+1F94B;MARTIAL ARTS UNIFORM;So;0;ON;;;;;N;;;;;
+1F94C;CURLING STONE;So;0;ON;;;;;N;;;;;
+1F950;CROISSANT;So;0;ON;;;;;N;;;;;
+1F951;AVOCADO;So;0;ON;;;;;N;;;;;
+1F952;CUCUMBER;So;0;ON;;;;;N;;;;;
+1F953;BACON;So;0;ON;;;;;N;;;;;
+1F954;POTATO;So;0;ON;;;;;N;;;;;
+1F955;CARROT;So;0;ON;;;;;N;;;;;
+1F956;BAGUETTE BREAD;So;0;ON;;;;;N;;;;;
+1F957;GREEN SALAD;So;0;ON;;;;;N;;;;;
+1F958;SHALLOW PAN OF FOOD;So;0;ON;;;;;N;;;;;
+1F959;STUFFED FLATBREAD;So;0;ON;;;;;N;;;;;
+1F95A;EGG;So;0;ON;;;;;N;;;;;
+1F95B;GLASS OF MILK;So;0;ON;;;;;N;;;;;
+1F95C;PEANUTS;So;0;ON;;;;;N;;;;;
+1F95D;KIWIFRUIT;So;0;ON;;;;;N;;;;;
+1F95E;PANCAKES;So;0;ON;;;;;N;;;;;
+1F95F;DUMPLING;So;0;ON;;;;;N;;;;;
+1F960;FORTUNE COOKIE;So;0;ON;;;;;N;;;;;
+1F961;TAKEOUT BOX;So;0;ON;;;;;N;;;;;
+1F962;CHOPSTICKS;So;0;ON;;;;;N;;;;;
+1F963;BOWL WITH SPOON;So;0;ON;;;;;N;;;;;
+1F964;CUP WITH STRAW;So;0;ON;;;;;N;;;;;
+1F965;COCONUT;So;0;ON;;;;;N;;;;;
+1F966;BROCCOLI;So;0;ON;;;;;N;;;;;
+1F967;PIE;So;0;ON;;;;;N;;;;;
+1F968;PRETZEL;So;0;ON;;;;;N;;;;;
+1F969;CUT OF MEAT;So;0;ON;;;;;N;;;;;
+1F96A;SANDWICH;So;0;ON;;;;;N;;;;;
+1F96B;CANNED FOOD;So;0;ON;;;;;N;;;;;
+1F980;CRAB;So;0;ON;;;;;N;;;;;
+1F981;LION FACE;So;0;ON;;;;;N;;;;;
+1F982;SCORPION;So;0;ON;;;;;N;;;;;
+1F983;TURKEY;So;0;ON;;;;;N;;;;;
+1F984;UNICORN FACE;So;0;ON;;;;;N;;;;;
+1F985;EAGLE;So;0;ON;;;;;N;;;;;
+1F986;DUCK;So;0;ON;;;;;N;;;;;
+1F987;BAT;So;0;ON;;;;;N;;;;;
+1F988;SHARK;So;0;ON;;;;;N;;;;;
+1F989;OWL;So;0;ON;;;;;N;;;;;
+1F98A;FOX FACE;So;0;ON;;;;;N;;;;;
+1F98B;BUTTERFLY;So;0;ON;;;;;N;;;;;
+1F98C;DEER;So;0;ON;;;;;N;;;;;
+1F98D;GORILLA;So;0;ON;;;;;N;;;;;
+1F98E;LIZARD;So;0;ON;;;;;N;;;;;
+1F98F;RHINOCEROS;So;0;ON;;;;;N;;;;;
+1F990;SHRIMP;So;0;ON;;;;;N;;;;;
+1F991;SQUID;So;0;ON;;;;;N;;;;;
+1F992;GIRAFFE FACE;So;0;ON;;;;;N;;;;;
+1F993;ZEBRA FACE;So;0;ON;;;;;N;;;;;
+1F994;HEDGEHOG;So;0;ON;;;;;N;;;;;
+1F995;SAUROPOD;So;0;ON;;;;;N;;;;;
+1F996;T-REX;So;0;ON;;;;;N;;;;;
+1F997;CRICKET;So;0;ON;;;;;N;;;;;
+1F9C0;CHEESE WEDGE;So;0;ON;;;;;N;;;;;
+1F9D0;FACE WITH MONOCLE;So;0;ON;;;;;N;;;;;
+1F9D1;ADULT;So;0;ON;;;;;N;;;;;
+1F9D2;CHILD;So;0;ON;;;;;N;;;;;
+1F9D3;OLDER ADULT;So;0;ON;;;;;N;;;;;
+1F9D4;BEARDED PERSON;So;0;ON;;;;;N;;;;;
+1F9D5;PERSON WITH HEADSCARF;So;0;ON;;;;;N;;;;;
+1F9D6;PERSON IN STEAMY ROOM;So;0;ON;;;;;N;;;;;
+1F9D7;PERSON CLIMBING;So;0;ON;;;;;N;;;;;
+1F9D8;PERSON IN LOTUS POSITION;So;0;ON;;;;;N;;;;;
+1F9D9;MAGE;So;0;ON;;;;;N;;;;;
+1F9DA;FAIRY;So;0;ON;;;;;N;;;;;
+1F9DB;VAMPIRE;So;0;ON;;;;;N;;;;;
+1F9DC;MERPERSON;So;0;ON;;;;;N;;;;;
+1F9DD;ELF;So;0;ON;;;;;N;;;;;
+1F9DE;GENIE;So;0;ON;;;;;N;;;;;
+1F9DF;ZOMBIE;So;0;ON;;;;;N;;;;;
+1F9E0;BRAIN;So;0;ON;;;;;N;;;;;
+1F9E1;ORANGE HEART;So;0;ON;;;;;N;;;;;
+1F9E2;BILLED CAP;So;0;ON;;;;;N;;;;;
+1F9E3;SCARF;So;0;ON;;;;;N;;;;;
+1F9E4;GLOVES;So;0;ON;;;;;N;;;;;
+1F9E5;COAT;So;0;ON;;;;;N;;;;;
+1F9E6;SOCKS;So;0;ON;;;;;N;;;;;
20000;<CJK Ideograph Extension B, First>;Lo;0;L;;;;;N;;;;;
2A6D6;<CJK Ideograph Extension B, Last>;Lo;0;L;;;;;N;;;;;
2A700;<CJK Ideograph Extension C, First>;Lo;0;L;;;;;N;;;;;
2B734;<CJK Ideograph Extension C, Last>;Lo;0;L;;;;;N;;;;;
+2B740;<CJK Ideograph Extension D, First>;Lo;0;L;;;;;N;;;;;
+2B81D;<CJK Ideograph Extension D, Last>;Lo;0;L;;;;;N;;;;;
+2B820;<CJK Ideograph Extension E, First>;Lo;0;L;;;;;N;;;;;
+2CEA1;<CJK Ideograph Extension E, Last>;Lo;0;L;;;;;N;;;;;
+2CEB0;<CJK Ideograph Extension F, First>;Lo;0;L;;;;;N;;;;;
+2EBE0;<CJK Ideograph Extension F, Last>;Lo;0;L;;;;;N;;;;;
2F800;CJK COMPATIBILITY IDEOGRAPH-2F800;Lo;0;L;4E3D;;;;N;;;;;
2F801;CJK COMPATIBILITY IDEOGRAPH-2F801;Lo;0;L;4E38;;;;N;;;;;
2F802;CJK COMPATIBILITY IDEOGRAPH-2F802;Lo;0;L;4E41;;;;N;;;;;
diff --git a/appveyor.yml b/appveyor.yml
index d99489e..c0c47f9 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,11 +1,15 @@
-version: "0.76.0.{build}"
+version: "0.78.0.{build}"
install:
- cmd: set MSYSTEM=MINGW32
- - cmd: C:\msys64\usr\bin\bash -lc "pacman --sync --noconfirm make mingw-w64-i686-gcc"
+ - cmd: C:\msys64\usr\bin\bash -lc "pacman --sync --noconfirm make mingw-w64-i686-gcc mingw-w64-i686-sqlite3"
+ - cmd: cd C:\projects & mklink /D %APPVEYOR_PROJECT_NAME% %APPVEYOR_PROJECT_SLUG% & exit 0
build_script:
- - cmd: C:\msys64\usr\bin\bash -lc "cd /c/projects/jimtcl; ./configure --full --with-ext='zlib' --disable-docs"
+ - cmd: C:\msys64\usr\bin\bash -lc "cd /c/projects/jimtcl; ./configure --full --ssl --with-ext='sqlite3 win32 zlib' --disable-docs"
- cmd: C:\msys64\usr\bin\bash -lc "cd /c/projects/jimtcl; make"
test_script:
- cmd: C:\msys64\usr\bin\bash -lc "cd /c/projects/jimtcl; make test"
+after_build:
+ - cmd: copy jimsh.exe jimsh_debug.exe
+ - cmd: C:\msys64\usr\bin\bash -lc "cd /c/projects/jimtcl; strip jimsh.exe; 7z a jimsh.zip jimsh.exe jimsh_debug.exe /c/msys64/mingw32/bin/{libcrypto-1_1.dll,libgcc_s_dw2-1.dll,libsqlite3-0.dll,libssl-1_1.dll,libwinpthread-1.dll,zlib1.dll}"
artifacts:
- - path: jimsh.exe
+ - path: jimsh.zip
diff --git a/auto.def b/auto.def
index fc32b68..fe6e4a2 100644
--- a/auto.def
+++ b/auto.def
@@ -1,10 +1,14 @@
# vim:se syn=tcl:
#
-define JIM_VERSION 77
+define JIM_VERSION 79
+
+options-defaults {
+ silent-rules 1
+}
# Note: modules which support options *must* be included before 'options'
-use cc cc-shared cc-db cc-lib pkg-config
+use cc cc-shared cc-db cc-lib pkg-config util
use local
options {
@@ -21,7 +25,7 @@ options {
docs=1 => "don't build or install the documentation"
docdir:path => "path to install docs (if built)"
random-hash => "randomise hash tables. more secure but hash table results are not predicable"
- with-jim-ext: {with-ext:"ext1 ext2 ..."} => {
+ with-jim-ext: {with-ext:"ext1,ext2,..."} => {
Specify additional jim extensions to include.
These are enabled by default:
@@ -36,7 +40,7 @@ options {
readdir - Required for glob
package - Package management with the package command
load - Load binary extensions at runtime with load or package
- posix - Posix APIs including os.fork, os.wait, pid
+ posix - Posix APIs including os.fork, os.uptime
regexp - Tcl-compatible regexp, regsub commands
signal - Signal handling
stdlib - Built-in commands including lassign, lambda, alias
@@ -44,24 +48,28 @@ options {
tclcompat - Tcl compatible read, gets, puts, parray, case, ...
namespace - Tcl compatible namespace support
- These are disabled by default:
+ These are disabled by default, but enabled by --full:
oo - Jim OO extension
tree - OO tree structure, similar to tcllib ::struct::tree
binary - Tcl-compatible 'binary' command
+ tclprefix - Support for the tcl::prefix command
+ zlib - Interface to zlib
+ json - JSON encode/decode
+
+ These are disabled unless explicitly enabled:
+
readline - Interface to libreadline
rlprompt - Tcl wrapper around the readline extension
mk - Interface to Metakit
- tclprefix - Support for the tcl::prefix command
sqlite3 - Interface to sqlite3
- zlib - Interface to zlib
win32 - Interface to win32
}
- with-out-jim-ext: {without-ext:"default|ext1 ext2 ..."} => {
+ with-out-jim-ext: {without-ext:"default|ext1,ext2,..."} => {
Specify jim extensions to exclude.
If 'default' is given, the default extensions will not be added.
}
- with-jim-extmod: {with-mod:"ext1 ext2 ..."} => {
+ with-jim-extmod: {with-mod:"ext1,ext2,..."} => {
Specify jim extensions to build as separate modules (either C or Tcl).
Note that not all extensions can be built as loadable modules.
}
@@ -73,7 +81,14 @@ options {
# We add detected libs to LDLIBS explicitly
set LIBS [get-define LIBS]
+# In case -Werror is passed in CFLAGS, set -Wno-error when doing checks
+# to prevent warnings from becoming errors
+if {"-Werror" in [get-define CFLAGS] && [cctest -cflags -Wno-error]} {
+ cc-with {-cflags -Wno-error}
+}
+
cc-check-types "long long"
+cc-check-sizeof int
define CCOPTS ""
define CXXOPTS ""
@@ -101,10 +116,15 @@ if {[cc-check-function-in-lib socket socket]} {
}
cc-check-functions ualarm lstat fork vfork system select execvpe
-cc-check-functions backtrace geteuid mkstemp realpath strptime isatty
+cc-check-functions geteuid mkstemp realpath isatty
cc-check-functions regcomp waitpid sigaction sys_signame sys_siglist isascii
cc-check-functions syslog opendir readlink sleep usleep pipe getaddrinfo utimes
-cc-check-functions shutdown socketpair isinf isnan link symlink fsync dup
+cc-check-functions shutdown socketpair isinf isnan link symlink fsync dup umask
+cc-check-functions localtime gmtime strptime clock_gettime
+
+if {[cc-check-function-in-lib backtrace execinfo]} {
+ define-append LDLIBS [get-define lib_backtrace]
+}
if {[cc-check-functions sysinfo]} {
cc-with {-includes sys/sysinfo.h} {
@@ -112,6 +132,11 @@ if {[cc-check-functions sysinfo]} {
}
}
+cc-with {-includes {sys/types.h sys/stat.h}} {
+ cc-check-members "struct stat.st_mtimespec"
+ cc-check-members "struct stat.st_mtim"
+}
+
cc-with {-includes fcntl.h} {
cc-check-types "struct flock"
}
@@ -146,6 +171,29 @@ switch -glob -- $host_os {
cc-check-tools ar ranlib strip
define tclsh [info nameofexecutable]
+# We only support silent-rules for GNU Make
+define NO_SILENT_RULES
+if {[get-define AM_SILENT_RULES 0]} {
+ if {[cc-check-progs [get-define MAKE make]]} {
+ # Are we using GNU make?
+ catch {exec [get-define MAKE] --version} makeversion
+ if {[string match "GNU Make*" $makeversion]} {
+ define NO_SILENT_RULES 0
+ }
+ }
+}
+
+if {[opt-bool docs]} {
+ if {[cc-check-progs asciidoc sed]} {
+ define INSTALL_DOCS docs
+ define HAVE_ASCIIDOC
+ } else {
+ define INSTALL_DOCS shipped
+ }
+} else {
+ define INSTALL_DOCS nodocs
+}
+
if {![cc-check-functions _NSGetEnviron]} {
msg-checking "Checking environ declared in unistd.h..."
if {[cctest -cflags {-D_GNU_SOURCE -D_POSIX_SOURCE} -includes unistd.h -code {char **ep = environ;}]} {
@@ -166,12 +214,35 @@ if {[cctest -includes {sys/types.h sys/stat.h} -code {mkdir("/dummy");}]} {
msg-result no
}
+cc-with {-includes sys/stat.h} {
+ foreach i {S_IXUSR S_IRWXG S_IRWXO} {
+ if {![cc-check-decls $i]} {
+ define $i 0
+ }
+ }
+}
+
set extra_objs {}
set jimregexp 0
-if {[opt-bool utf8 full]} {
+# Returns 1 if either the given option is enabled, or
+# --full is enabled and the option isn't explicitly disabled
+#
+proc opt-bool-or-full {opt} {
+ if {[opt-bool $opt]} {
+ return 1
+ }
+ if {[opt-bool full] && [opt-bool -nodefault $opt] != 0} {
+ return 1
+ }
+ return 0
+}
+
+if {[opt-bool-or-full utf8]} {
msg-result "Enabling UTF-8"
define JIM_UTF8
+ define-append CCOPTS -DUSE_UTF8
+ define PARSE_UNIDATA_FLAGS ""
incr jimregexp
} else {
define JIM_UTF8 0
@@ -180,17 +251,19 @@ if {[opt-bool maintainer]} {
msg-result "Enabling maintainer settings"
define JIM_MAINTAINER
}
-if {[opt-bool math full]} {
+# If --math or --full and not --disable-math
+if {[opt-bool-or-full math]} {
msg-result "Enabling math functions"
define JIM_MATH_FUNCTIONS
cc-check-function-in-lib sin m
define-append LDLIBS [get-define lib_sin]
}
-if {[opt-bool ipv6 full]} {
+if {[opt-bool-or-full ipv6]} {
msg-result "Enabling IPv6"
define JIM_IPV6
}
-if {[opt-bool ssl full]} {
+define-append PKG_CONFIG_REQUIRES ""
+if {[opt-bool-or-full ssl]} {
if {[pkg-config-init 0]} {
foreach pkg {openssl libssl} {
if {[pkg-config $pkg]} {
@@ -199,6 +272,7 @@ if {[opt-bool ssl full]} {
define-append LDFLAGS [pkg-config-get $pkg LDFLAGS]
define-append CCOPTS [pkg-config-get $pkg CFLAGS]
msg-result "Enabling SSL ($pkg)"
+ define-append PKG_CONFIG_REQUIRES $pkg
break
}
}
@@ -212,12 +286,20 @@ if {[opt-bool ssl full]} {
user-error "SSL support requires OpenSSL"
}
}
+ # Later versions deprecate TLSv1_2_method, but older versions don't have TLS_method
+ if {![cc-check-function-in-lib TLS_method ssl]} {
+ define-append CCOPTS -DUSE_TLSv1_2_method
+ }
}
-if {[opt-bool lineedit full]} {
+if {[opt-bool-or-full lineedit]} {
if {([cc-check-includes termios.h] && [have-feature isatty]) || [have-feature winconsole]} {
msg-result "Enabling line editing"
define USE_LINENOISE
+ define-append PARSE_UNIDATA_FLAGS -width
lappend extra_objs linenoise.o
+ if {[cc-check-inline] && [is-defined inline]} {
+ define-append CCOPTS -Dinline=[get-define inline]
+ }
}
}
if {[opt-bool references]} {
@@ -230,26 +312,29 @@ if {[opt-bool shared with-jim-shared]} {
msg-result "Building static library"
define JIM_STATICLIB
}
-define LIBSOEXT [format [get-define SH_SOEXTVER] [format %.2f [expr {[get-define JIM_VERSION] / 100.0}]]]
+define VERSION [format %.2f [expr {[get-define JIM_VERSION] / 100.0}]]
+define LIBSOEXT [format [get-define SH_SOEXTVER] [get-define VERSION]]
+if {[get-define libdir] ni {/lib /usr/lib}} {
+ define SH_LINKRPATH_FLAGS [format [get-define SH_LINKRPATH] [get-define libdir]]
+} else {
+ define SH_LINKRPATH_FLAGS ""
+}
define JIM_INSTALL [opt-bool install-jim]
define JIM_DOCS [opt-bool docs]
define JIM_RANDOMISE_HASH [opt-bool random-hash]
-if {[opt-val docdir] ne ""} {
- define docdir [opt-val docdir]
-} else {
- define docdir {${prefix}/docs/jim}
-}
+define docdir [opt-str docdir o {${prefix}/docs/jim}]
# Attributes of the extensions
# tcl=Pure Tcl extension
# static=Can't be built as a module
-# optional=Not selected by default
+# off=Off unless explicitly enabled
+# optional=Off by default, but selected by --full
# cpp=Is a C++ extension
global extdb
dict set extdb attrs {
aio { static }
array {}
- binary { tcl }
+ binary { tcl optional }
clock {}
eventloop { static }
exec { static }
@@ -257,8 +342,10 @@ dict set extdb attrs {
glob { tcl }
history {}
interp { }
+ json { optional }
+ jsonencode { tcl optional }
load { static }
- mk { cpp optional }
+ mk { cpp off }
namespace { static }
nshelper { tcl optional }
oo { tcl }
@@ -266,19 +353,19 @@ dict set extdb attrs {
package { static }
posix {}
readdir {}
- readline { optional }
+ readline { off }
regexp {}
- rlprompt { tcl optional }
- sdl { optional }
+ rlprompt { tcl off }
+ sdl { off }
signal { static }
- sqlite3 { optional }
+ sqlite3 { off }
zlib { optional }
stdlib { tcl static }
syslog {}
tclcompat { tcl static }
- tclprefix {}
+ tclprefix { optional }
tree { tcl }
- win32 { optional }
+ win32 { off }
}
# Additional information about certain extensions
@@ -292,6 +379,7 @@ dict set extdb info {
load { check {[have-feature dlopen-compat] || [cc-check-function-in-lib dlopen dl]} libdep lib_dlopen }
mk { check {[check-metakit]} libdep lib_mk }
namespace { dep nshelper }
+ json { dep jsonencode extrasrcs jsmn/jsmn.c }
posix { check {[have-feature waitpid]} }
readdir { check {[have-feature opendir]} }
readline { pkg-config readline check {[cc-check-function-in-lib readline readline]} libdep lib_readline}
@@ -300,7 +388,7 @@ dict set extdb info {
sdl { pkg-config SDL_gfx check {[cc-check-function-in-lib SDL_SetVideoMode SDL] && [cc-check-function-in-lib rectangleRGBA SDL_gfx]}
libdep {lib_SDL_SetVideoMode lib_rectangleRGBA}
}
- signal { check {[have-feature sigaction] && [have-feature vfork]} }
+ signal { check {[have-feature sigaction]} }
sqlite3 { pkg-config sqlite3 check {[cc-check-function-in-lib sqlite3_prepare_v2 sqlite3]} libdep lib_sqlite3_prepare_v2 }
zlib { pkg-config zlib check {[cc-check-function-in-lib deflate z]} libdep lib_deflate }
syslog { check {[have-feature syslog]} }
@@ -324,12 +412,24 @@ proc check-metakit {} {
return $found
}
+# Takes a list of module names, separated by spaces or commas
+# and returns them as a single list
+proc join-ext-names {list} {
+ set result {}
+ # Replace comma with space in each list then concatenate the result
+ foreach l $list {
+ lappend result {*}[string map {, " "} $l]
+ }
+ return $result
+}
+
# Set up the withinfo array based on what the user selected
global withinfo
-set withinfo(without) [join [opt-val {without-ext with-out-jim-ext}]]
-set withinfo(ext) [join [opt-val {with-ext with-jim-ext}]]
-set withinfo(mod) [join [opt-val {with-mod with-jim-extmod}]]
+set withinfo(without) [join-ext-names [opt-val {without-ext with-out-jim-ext}]]
+set withinfo(ext) [join-ext-names [opt-val {with-ext with-jim-ext}]]
+set withinfo(mod) [join-ext-names [opt-val {with-mod with-jim-extmod}]]
set withinfo(nodefault) 0
+set withinfo(optional) [opt-bool full]
if {$withinfo(without) eq "default"} {
set withinfo(without) {}
set withinfo(nodefault) 1
@@ -346,6 +446,9 @@ if {[have-feature windows]} {
user-error "cygwin/mingw require --shared for dynamic modules"
}
}
+if {[have-feature termios.h]} {
+ lappend extra_objs jim-tty.o
+}
if {[ext-get-status regexp] in {y m}} {
if {![have-feature regcomp]} {
@@ -365,11 +468,33 @@ if {$jimregexp || [opt-bool jim-regexp]} {
}
}
+foreach mod $extinfo(static-c) {
+ if {[dict exists $extdb info $mod extrasrcs]} {
+ foreach src [dict get $extdb info $mod extrasrcs] {
+ # In case we are building out-of-tree and $src is in a subdir
+ file mkdir [file dirname $src]
+ lappend extra_objs {*}[file rootname $src].o
+ }
+ }
+}
+
+# poor-man's signals
+if {"signal" ni $extinfo(static-c)} {
+ lappend extra_objs jim-nosignal.o
+}
+
if {[ext-get-status load] eq "n"} {
# If we don't have load, no need to support shared objects
define SH_LINKFLAGS ""
}
+# Are we cross compiling?
+if {[get-define host] ne [get-define build]} {
+ define cross_compiling 1
+} else {
+ define cross_compiling 0
+}
+
msg-result "Jim static extensions: [lsort [concat $extinfo(static-tcl) $extinfo(static-c)]]"
if {[llength $extinfo(module-tcl)]} {
msg-result "Jim Tcl extensions: [lsort $extinfo(module-tcl)]"
@@ -388,9 +513,34 @@ define EXTRA_OBJS $extra_objs
# Restore the user-specified LIBS
define LIBS $LIBS
-make-config-header jim-config.h -auto {HAVE_LONG_LONG* JIM_UTF8} -bare JIM_VERSION -none *
-make-config-header jimautoconf.h -auto {jim_ext_* TCL_PLATFORM_* TCL_LIBRARY USE_* JIM_* _FILE_OFFSET*}
+# Now generate the Makefile rules to build the external C shared objects
+# It is easier to do this here rather than listing them out explicitly in Makefile.in
+set lines {}
+foreach mod $extinfo(module-c) {
+ set objs {}
+ set libs [get-define LDLIBS_$mod]
+ set srcs jim-$mod.c
+ if {[dict exists $extdb info $mod extrasrcs]} {
+ lappend srcs {*}[dict get $extdb info $mod extrasrcs]
+ }
+ lappend lines "$mod.so: $srcs"
+ foreach src $srcs {
+ set obj [file rootname $src].o
+ lappend objs $obj
+ lappend lines "\t\$(ECHO)\t\"\tCC\t$obj\""
+ lappend lines "\t\$(Q)\$(CC) \$(CFLAGS) \$(SHOBJ_CFLAGS) -c -o $obj $src"
+ }
+ lappend lines "\t\$(ECHO)\t\"\tLDSO\t\$@\""
+ lappend lines "\t\$(Q)\$(CC) \$(CFLAGS) \$(LDFLAGS) \$(SHOBJ_LDFLAGS) -o \$@ $objs \$(SH_LIBJIM) $libs"
+ lappend lines ""
+}
+define BUILD_SHOBJS [join $lines \n]
+
+make-config-header jim-config.h -auto {HAVE_LONG_LONG* JIM_UTF8 SIZEOF_INT} -bare JIM_VERSION -none *
+make-config-header jimautoconf.h -auto {jim_ext_* TCL_PLATFORM_* TCL_LIBRARY USE_* JIM_* _FILE_OFFSET*} -bare {S_I*}
make-template Makefile.in
+make-template tests/Makefile.in
make-template build-jim-ext.in
+make-template jimtcl.pc.in
catch {exec chmod +x build-jim-ext}
diff --git a/autosetup/README.autosetup b/autosetup/README.autosetup
index c50bd84..a6215e8 100644
--- a/autosetup/README.autosetup
+++ b/autosetup/README.autosetup
@@ -1 +1,11 @@
-This is autosetup v0.6.5. See http://msteveb.github.com/autosetup/
+README.autosetup created by autosetup v0.6.9
+
+This is the autosetup directory for a local install of autosetup.
+It contains autosetup, support files and loadable modules.
+
+*.tcl files in this directory are optional modules which
+can be loaded with the 'use' directive.
+
+*.auto files in this directory are auto-loaded.
+
+For more information, see http://msteveb.github.com/autosetup/
diff --git a/autosetup/autosetup b/autosetup/autosetup
index 84886c2..da3a835 100755
--- a/autosetup/autosetup
+++ b/autosetup/autosetup
@@ -3,12 +3,13 @@
# All rights reserved
# vim:se syntax=tcl:
# \
-dir=`dirname "$0"`; exec "`$dir/find-tclsh`" "$0" "$@"
+dir=`dirname "$0"`; exec "`$dir/autosetup-find-tclsh`" "$0" "$@"
-set autosetup(version) 0.6.5
+# Note that the version has a trailing + on unreleased versions
+set autosetup(version) 0.6.9
# Can be set to 1 to debug early-init problems
-set autosetup(debug) 0
+set autosetup(debug) [expr {"--debug" in $argv}]
##################################################################
#
@@ -61,7 +62,7 @@ proc main {argv} {
set autosetup(srcdir) [pwd]
} else {
# Invoked via the configure wrapper
- set autosetup(srcdir) [file dirname $autosetup(exe)]
+ set autosetup(srcdir) [file-normalize [file dirname $autosetup(exe)]]
}
set autosetup(autodef) [relative-path $autosetup(srcdir)/auto.def]
@@ -70,23 +71,47 @@ proc main {argv} {
set autosetup(argv) $argv
set autosetup(cmdline) {}
+ # options is a list of known options
set autosetup(options) {}
+ # optset is a dictionary of option values set by the user based on getopt
+ set autosetup(optset) {}
+ # optdefault is a dictionary of default values
+ set autosetup(optdefault) {}
+ # options-defaults is a dictionary of overrides for default values for options
+ set autosetup(options-defaults) {}
set autosetup(optionhelp) {}
set autosetup(showhelp) 0
+ use util
+
# Parse options
use getopt
- array set ::useropts [getopt argv]
+ # At the is point we don't know what is a valid option
+ # We simply parse anything that looks like an option
+ set autosetup(getopt) [getopt argv]
#"=Core Options:"
options-add {
help:=local => "display help and options. Optionally specify a module name, such as --help=system"
+ licence license => "display the autosetup license"
version => "display the version of autosetup"
ref:=text manual:=text
reference:=text => "display the autosetup command reference. 'text', 'wiki', 'asciidoc' or 'markdown'"
debug => "display debugging output as autosetup runs"
- install:=. => "install autosetup to the current or given directory (in the 'autosetup/' subdirectory)"
+ install:=. => "install autosetup to the current or given directory"
+ }
+ if {$autosetup(installed)} {
+ # hidden options so we can produce a nice error
+ options-add {
+ sysinstall:path
+ }
+ } else {
+ options-add {
+ sysinstall:path => "install standalone autosetup to the given directory (e.g.: /usr/local)"
+ }
+ }
+ options-add {
force init:=help => "create initial auto.def, etc. Use --init=help for known types"
# Undocumented options
option-checking=1
@@ -96,15 +121,14 @@ proc main {argv} {
conf:
}
- #parray ::useropts
if {[opt-bool version]} {
puts $autosetup(version)
exit 0
}
# autosetup --conf=alternate-auto.def
- if {[opt-val conf] ne ""} {
- set autosetup(autodef) [opt-val conf]
+ if {[opt-str conf o]} {
+ set autosetup(autodef) $o
}
# Debugging output (set this early)
@@ -120,38 +144,47 @@ proc main {argv} {
}
# Now any auto-load modules
- foreach file [glob -nocomplain $autosetup(libdir)/*.auto $autosetup(libdir)/*/*.auto] {
- automf_load source $file
- }
+ autosetup_load_auto_modules
- if {[opt-val help] ne ""} {
+ if {[opt-str help o]} {
incr autosetup(showhelp)
use help
- autosetup_help [opt-val help]
+ autosetup_help $o
}
- if {[opt-val {manual ref reference}] ne ""} {
+ if {[opt-bool licence license]} {
use help
- autosetup_reference [opt-val {manual ref reference}]
+ autosetup_show_license
+ exit 0
+ }
+
+ if {[opt-str {manual ref reference} o]} {
+ use help
+ autosetup_reference $o
}
# Allow combining --install and --init
set earlyexit 0
- if {[opt-val install] ne ""} {
+ if {[opt-str install o]} {
use install
- autosetup_install [opt-val install]
+ autosetup_install $o
incr earlyexit
}
- if {[opt-val init] ne ""} {
+ if {[opt-str init o]} {
use init
- autosetup_init [opt-val init]
+ autosetup_init $o
incr earlyexit
}
if {$earlyexit} {
exit 0
}
+ if {[opt-str sysinstall o]} {
+ use install
+ autosetup_install $o 1
+ exit 0
+ }
if {![file exists $autosetup(autodef)]} {
# Check for invalid option first
@@ -181,6 +214,7 @@ proc main {argv} {
# Log how we were invoked
configlog "Invoked as: [getenv WRAPPER $::argv0] [quote-argv $autosetup(argv)]"
+ configlog "Tclsh: [info nameofexecutable]"
# Note that auto.def is *not* loaded in the global scope
source $autosetup(autodef)
@@ -200,30 +234,134 @@ proc main {argv} {
exit 0
}
-# @opt-bool option ...
+# @opt-bool ?-nodefault? option ...
+#
+# Check each of the named, boolean options and if any have been explicitly enabled
+# or disabled by the user, return 1 or 0 accordingly.
+#
+# If the option was specified more than once, the last value wins.
+# e.g. With '--enable-foo --disable-foo', '[opt-bool foo]' will return 0
#
-# Check each of the named, boolean options and return 1 if any of them have
-# been set by the user.
+# If no value was specified by the user, returns the default value for the
+# first option. If '-nodefault' is given, this behaviour changes and
+# -1 is returned instead.
#
proc opt-bool {args} {
+ set nodefault 0
+ if {[lindex $args 0] eq "-nodefault"} {
+ set nodefault 1
+ set args [lrange $args 1 end]
+ }
option-check-names {*}$args
- opt_bool ::useropts {*}$args
+
+ foreach opt $args {
+ if {[dict exists $::autosetup(optset) $opt]} {
+ return [dict get $::autosetup(optset) $opt]
+ }
+ }
+
+ if {$nodefault} {
+ return -1
+ }
+ # Default value is the default for the first option
+ return [dict get $::autosetup(optdefault) [lindex $args 0]]
}
-# @opt-val option-list ?default=""?
+# @opt-val optionlist ?default=""?
#
-# Returns a list containing all the values given for the non-boolean options in 'option-list'.
+# Returns a list containing all the values given for the non-boolean options in '$optionlist'.
# There will be one entry in the list for each option given by the user, including if the
# same option was used multiple times.
-# If only a single value is required, use something like:
#
-## lindex [opt-val $names] end
+# If no options were set, '$default' is returned (exactly, not as a list).
#
-# If no options were set, $default is returned (exactly, not as a list).
+# Note: For most use cases, 'opt-str' should be preferred.
#
proc opt-val {names {default ""}} {
option-check-names {*}$names
- join [opt_val ::useropts $names $default]
+
+ foreach opt $names {
+ if {[dict exists $::autosetup(optset) $opt]} {
+ lappend result {*}[dict get $::autosetup(optset) $opt]
+ }
+ }
+ if {[info exists result]} {
+ return $result
+ }
+ return $default
+}
+
+# @opt-str optionlist varname ?default?
+#
+# Sets '$varname' in the callers scope to the value for one of the given options.
+#
+# For the list of options given in '$optionlist', if any value is set for any option,
+# the option value is taken to be the *last* value of the last option (in the order given).
+#
+# If no option was given, and a default was specified with 'options-defaults',
+# that value is used.
+#
+# If no 'options-defaults' value was given and '$default' was given, it is used.
+#
+# If none of the above provided a value, no value is set.
+#
+# The return value depends on whether '$default' was specified.
+# If it was, the option value is returned.
+# If it was not, 1 is returns if a value was set, or 0 if not.
+#
+# Typical usage is as follows:
+#
+## if {[opt-str {myopt altname} o]} {
+## do something with $o
+## }
+#
+# Or:
+## define myname [opt-str {myopt altname} o "/usr/local"]
+#
+proc opt-str {names varname args} {
+ global autosetup
+
+ option-check-names {*}$names
+ upvar $varname value
+
+ if {[llength $args]} {
+ # A default was given, so always return the string value of the option
+ set default [lindex $args 0]
+ set retopt 1
+ } else {
+ # No default, so return 0 or 1 to indicate if a value was found
+ set retopt 0
+ }
+
+ foreach opt $names {
+ if {[dict exists $::autosetup(optset) $opt]} {
+ set result [lindex [dict get $::autosetup(optset) $opt] end]
+ }
+ }
+
+ if {![info exists result]} {
+ # No user-specified value. Has options-defaults been set?
+ foreach opt $names {
+ if {[dict exists $::autosetup(options-defaults) $opt]} {
+ set result [dict get $autosetup(options-defaults) $opt]
+ }
+ }
+ }
+
+ if {[info exists result]} {
+ set value $result
+ if {$retopt} {
+ return $value
+ }
+ return 1
+ }
+
+ if {$retopt} {
+ set value $default
+ return $value
+ }
+
+ return 0
}
proc option-check-names {args} {
@@ -235,10 +373,10 @@ proc option-check-names {args} {
}
# Parse the option definition in $opts and update
-# ::useropts() and ::autosetup(optionhelp) appropriately
+# ::autosetup(setoptions) and ::autosetup(optionhelp) appropriately
#
proc options-add {opts {header ""}} {
- global useropts autosetup
+ global autosetup
# First weed out comment lines
set realopts {}
@@ -257,6 +395,7 @@ proc options-add {opts {header ""}} {
set header {}
continue
}
+ unset -nocomplain defaultvalue equal value
#puts "i=$i, opt=$opt"
regexp {^([^:=]*)(:)?(=)?(.*)$} $opt -> name colon equal value
@@ -275,35 +414,101 @@ proc options-add {opts {header ""}} {
# Boolean option
lappend autosetup(options) $name
- if {![info exists useropts($name)]} {
- set useropts($name) $value
+ # Check for override
+ if {[dict exists $autosetup(options-defaults) $name]} {
+ # A default was specified with options-defaults, so use it
+ set value [dict get $autosetup(options-defaults) $name]
}
+
if {$value eq "1"} {
set opthelp "--disable-$name"
} else {
set opthelp "--$name"
}
+
+ # Set the default
+ if {$value eq ""} {
+ set value 0
+ }
+ set defaultvalue $value
+ dict set autosetup(optdefault) $name $defaultvalue
+
+ if {[dict exists $autosetup(getopt) $name]} {
+ # The option was specified by the user. Look at the last value.
+ lassign [lindex [dict get $autosetup(getopt) $name] end] type setvalue
+ if {$type eq "str"} {
+ # Can we convert the value to a boolean?
+ if {$setvalue in {1 enabled yes}} {
+ set setvalue 1
+ } elseif {$setvalue in {0 disabled no}} {
+ set setvalue 0
+ } else {
+ user-error "Boolean option $name given as --$name=$setvalue"
+ }
+ }
+ dict set autosetup(optset) $name $setvalue
+ #puts "Found boolean option --$name=$setvalue"
+ }
} else {
# String option.
lappend autosetup(options) $name
- if {$equal eq "="} {
- if {[info exists useropts($name)]} {
- # If the user specified the option with no value, the value will be "1"
- # Replace with the default
- if {$useropts($name) eq "1"} {
- set useropts($name) $value
- }
+ if {$colon eq ":"} {
+ # Was ":name=default" given?
+ # If so, set $value to the display name and $defaultvalue to the default
+ # (This is the preferred way to set a default value for a string option)
+ if {[regexp {^([^=]+)=(.*)$} $value -> value defaultvalue]} {
+ dict set autosetup(optdefault) $name $defaultvalue
}
+ }
+
+ # Maybe override the default value
+ if {[dict exists $autosetup(options-defaults) $name]} {
+ # A default was specified with options-defaults, so use it
+ set defaultvalue [dict get $autosetup(options-defaults) $name]
+ dict set autosetup(optdefault) $name $defaultvalue
+ } elseif {![info exists defaultvalue]} {
+ # For backward compatibility, if ":name" was given, use name as both
+ # the display text and the default value, but only if the user
+ # specified the option without the value
+ set defaultvalue $value
+ }
+
+ if {$equal eq "="} {
+ # String option with optional value
set opthelp "--$name?=$value?"
} else {
+ # String option with required value
set opthelp "--$name=$value"
}
+
+ # Get the values specified by the user
+ if {[dict exists $autosetup(getopt) $name]} {
+ set listvalue {}
+
+ foreach pair [dict get $autosetup(getopt) $name] {
+ lassign $pair type setvalue
+ if {$type eq "bool" && $setvalue} {
+ if {$equal ne "="} {
+ user-error "Option --$name requires a value"
+ }
+ # If given as a boolean, use the default value
+ set setvalue $defaultvalue
+ }
+ lappend listvalue $setvalue
+ }
+
+ #puts "Found string option --$name=$listvalue"
+ dict set autosetup(optset) $name $listvalue
+ }
}
# Now create the help for this option if appropriate
if {[lindex $opts $i+1] eq "=>"} {
set desc [lindex $opts $i+2]
+ if {[info exists defaultvalue]} {
+ set desc [string map [list @default@ $defaultvalue] $desc]
+ }
#string match \n* $desc
if {$header ne ""} {
lappend autosetup(optionhelp) $header ""
@@ -391,31 +596,35 @@ proc options-show {} {
}
}
-# @options options-spec
+# @options optionspec
#
# Specifies configuration-time options which may be selected by the user
-# and checked with opt-val and opt-bool. The format of options-spec follows.
+# and checked with 'opt-str' and 'opt-bool'. '$optionspec' contains a series
+# of options specifications separated by newlines, as follows:
#
# A boolean option is of the form:
#
## name[=0|1] => "Description of this boolean option"
#
-# The default is name=0, meaning that the option is disabled by default.
-# If name=1 is used to make the option enabled by default, the description should reflect
+# The default is 'name=0', meaning that the option is disabled by default.
+# If 'name=1' is used to make the option enabled by default, the description should reflect
# that with text like "Disable support for ...".
#
# An argument option (one which takes a parameter) is of the form:
#
## name:[=]value => "Description of this option"
#
-# If the name:value form is used, the value must be provided with the option (as --name=myvalue).
-# If the name:=value form is used, the value is optional and the given value is used as the default
+# If the 'name:value' form is used, the value must be provided with the option (as '--name=myvalue').
+# If the 'name:=value' form is used, the value is optional and the given value is used as the default
# if it is not provided.
#
-# Undocumented options are also supported by omitting the "=> description.
-# These options are not displayed with --help and can be useful for internal options or as aliases.
+# The description may contain '@default@', in which case it will be replaced with the default
+# value for the option (taking into account defaults specified with 'options-defaults'.
+#
+# Undocumented options are also supported by omitting the '=> description'.
+# These options are not displayed with '--help' and can be useful for internal options or as aliases.
#
-# For example, --disable-lfs is an alias for --disable=largefile:
+# For example, '--disable-lfs' is an alias for '--disable=largefile':
#
## lfs=1 largefile=1 => "Disable large file support"
#
@@ -430,7 +639,7 @@ proc options {optlist} {
# Check for invalid options
if {[opt-bool option-checking]} {
- foreach o [array names ::useropts] {
+ foreach o [dict keys $::autosetup(getopt)] {
if {$o ni $::autosetup(options)} {
user-error "Unknown option --$o"
}
@@ -438,22 +647,32 @@ proc options {optlist} {
}
}
+# @options-defaults dictionary
+#
+# Specifies a dictionary of options and a new default value for each of those options.
+# Use before any 'use' statements in 'auto.def' to change the defaults for
+# subsequently included modules.
+proc options-defaults {dict} {
+ foreach {n v} $dict {
+ dict set ::autosetup(options-defaults) $n $v
+ }
+}
+
proc config_guess {} {
- if {[file-isexec $::autosetup(dir)/config.guess]} {
- exec-with-stderr sh $::autosetup(dir)/config.guess
- if {[catch {exec-with-stderr sh $::autosetup(dir)/config.guess} alias]} {
+ if {[file-isexec $::autosetup(dir)/autosetup-config.guess]} {
+ if {[catch {exec-with-stderr sh $::autosetup(dir)/autosetup-config.guess} alias]} {
user-error $alias
}
return $alias
} else {
- configlog "No config.guess, so using uname"
+ configlog "No autosetup-config.guess, so using uname"
string tolower [exec uname -p]-unknown-[exec uname -s][exec uname -r]
}
}
proc config_sub {alias} {
- if {[file-isexec $::autosetup(dir)/config.sub]} {
- if {[catch {exec-with-stderr sh $::autosetup(dir)/config.sub $alias} alias]} {
+ if {[file-isexec $::autosetup(dir)/autosetup-config.sub]} {
+ if {[catch {exec-with-stderr sh $::autosetup(dir)/autosetup-config.sub $alias} alias]} {
user-error $alias
}
}
@@ -464,7 +683,7 @@ proc config_sub {alias} {
#
# Defines the named variable to the given value.
# These (name, value) pairs represent the results of the configuration check
-# and are available to be checked, modified and substituted.
+# and are available to be subsequently checked, modified and substituted.
#
proc define {name {value 1}} {
set ::define($name) $value
@@ -473,7 +692,7 @@ proc define {name {value 1}} {
# @undefine name
#
-# Undefine the named variable
+# Undefine the named variable.
#
proc undefine {name} {
unset -nocomplain ::define($name)
@@ -482,17 +701,26 @@ proc undefine {name} {
# @define-append name value ...
#
-# Appends the given value(s) to the given 'defined' variable.
-# If the variable is not defined or empty, it is set to $value.
+# Appends the given value(s) to the given "defined" variable.
+# If the variable is not defined or empty, it is set to '$value'.
# Otherwise the value is appended, separated by a space.
# Any extra values are similarly appended.
# If any value is already contained in the variable (as a substring) it is omitted.
#
proc define-append {name args} {
if {[get-define $name ""] ne ""} {
- # Make a token attempt to avoid duplicates
+ # Avoid duplicates
foreach arg $args {
- if {[string first $arg $::define($name)] == -1} {
+ if {$arg eq ""} {
+ continue
+ }
+ set found 0
+ foreach str [split $::define($name) " "] {
+ if {$str eq $arg} {
+ incr found
+ }
+ }
+ if {!$found} {
append ::define($name) " " $arg
}
}
@@ -504,7 +732,7 @@ proc define-append {name args} {
# @get-define name ?default=0?
#
-# Returns the current value of the 'defined' variable, or $default
+# Returns the current value of the "defined" variable, or '$default'
# if not set.
#
proc get-define {name {default 0}} {
@@ -524,9 +752,21 @@ proc is-defined {name} {
info exists ::define($name)
}
+# @is-define-set name
+#
+# Returns 1 if the given variable is defined and is set
+# to a value other than "" or 0
+#
+proc is-define-set {name} {
+ if {[get-define $name] in {0 ""}} {
+ return 0
+ }
+ return 1
+}
+
# @all-defines
#
-# Returns a dictionary (name value list) of all defined variables.
+# Returns a dictionary (name, value list) of all defined variables.
#
# This is suitable for use with 'dict', 'array set' or 'foreach'
# and allows for arbitrary processing of the defined variables.
@@ -538,9 +778,9 @@ proc all-defines {} {
# @get-env name default
#
-# If $name was specified on the command line, return it.
-# If $name was set in the environment, return it.
-# Otherwise return $default.
+# If '$name' was specified on the command line, return it.
+# Otherwise if '$name' was set in the environment, return it.
+# Otherwise return '$default'.
#
proc get-env {name default} {
if {[dict exists $::autosetup(cmdline) $name]} {
@@ -551,7 +791,7 @@ proc get-env {name default} {
# @env-is-set name
#
-# Returns 1 if the $name was specified on the command line or in the environment.
+# Returns 1 if '$name' was specified on the command line or in the environment.
# Note that an empty environment variable is not considered to be set.
#
proc env-is-set {name} {
@@ -567,7 +807,7 @@ proc env-is-set {name} {
# @readfile filename ?default=""?
#
# Return the contents of the file, without the trailing newline.
-# If the file doesn't exist or can't be read, returns $default.
+# If the file doesn't exist or can't be read, returns '$default'.
#
proc readfile {filename {default_value ""}} {
set result $default_value
@@ -581,7 +821,7 @@ proc readfile {filename {default_value ""}} {
# @writefile filename value
#
-# Creates the given file containing $value.
+# Creates the given file containing '$value'.
# Does not add an extra newline.
#
proc writefile {filename value} {
@@ -605,59 +845,56 @@ proc quote-argv {argv} {
join $args
}
-# @suffix suf list
+# @list-non-empty list
#
-# Takes a list and returns a new list with $suf appended
-# to each element
-#
-## suffix .c {a b c} => {a.c b.c c.c}
-#
-proc suffix {suf list} {
+# Returns a copy of the given list with empty elements removed
+proc list-non-empty {list} {
set result {}
foreach p $list {
- lappend result $p$suf
+ if {$p ne ""} {
+ lappend result $p
+ }
}
return $result
}
-# @prefix pre list
+# @find-executable-path name
#
-# Takes a list and returns a new list with $pre prepended
-# to each element
-#
-## prefix jim- {a.c b.c} => {jim-a.c jim-b.c}
+# Searches the path for an executable with the given name.
+# Note that the name may include some parameters, e.g. 'cc -mbig-endian',
+# in which case the parameters are ignored.
+# The full path to the executable if found, or "" if not found.
+# Returns 1 if found, or 0 if not.
#
-proc prefix {pre list} {
- set result {}
- foreach p $list {
- lappend result $pre$p
+proc find-executable-path {name} {
+ # Ignore any parameters
+ set name [lindex $name 0]
+ # The empty string is never a valid executable
+ if {$name ne ""} {
+ foreach p [split-path] {
+ dputs "Looking for $name in $p"
+ set exec [file join $p $name]
+ if {[file-isexec $exec]} {
+ dputs "Found $name -> $exec"
+ return $exec
+ }
+ }
}
- return $result
+ return {}
}
# @find-executable name
#
# Searches the path for an executable with the given name.
-# Note that the name may include some parameters, e.g. "cc -mbig-endian",
+# Note that the name may include some parameters, e.g. 'cc -mbig-endian',
# in which case the parameters are ignored.
# Returns 1 if found, or 0 if not.
#
proc find-executable {name} {
- # Ignore any parameters
- set name [lindex $name 0]
- if {$name eq ""} {
- # The empty string is never a valid executable
+ if {[find-executable-path $name] eq {}} {
return 0
}
- foreach p [split-path] {
- dputs "Looking for $name in $p"
- set exec [file join $p $name]
- if {[file-isexec $exec]} {
- dputs "Found $name -> $exec"
- return 1
- }
- }
- return 0
+ return 1
}
# @find-an-executable ?-required? name ...
@@ -692,7 +929,7 @@ proc find-an-executable {args} {
# @configlog msg
#
-# Writes the given message to the configuration log, config.log
+# Writes the given message to the configuration log, 'config.log'.
#
proc configlog {msg} {
if {![info exists ::autosetup(logfh)]} {
@@ -728,8 +965,8 @@ proc msg-result {msg} {
# @msg-quiet command ...
#
-# msg-quiet evaluates it's arguments as a command with output
-# from msg-checking and msg-result suppressed.
+# 'msg-quiet' evaluates it's arguments as a command with output
+# from 'msg-checking' and 'msg-result' suppressed.
#
# This is useful if a check needs to run a subcheck which isn't
# of interest to the user.
@@ -769,7 +1006,7 @@ proc dputs {msg} {
#
# Indicate incorrect usage to the user, including if required components
# or features are not found.
-# autosetup exits with a non-zero return code.
+# 'autosetup' exits with a non-zero return code.
#
proc user-error {msg} {
show-notices
@@ -816,6 +1053,17 @@ proc maybe-show-timestamp {} {
}
}
+# @autosetup-require-version required
+#
+# Checks the current version of 'autosetup' against '$required'.
+# A fatal error is generated if the current version is less than that required.
+#
+proc autosetup-require-version {required} {
+ if {[compare-versions $::autosetup(version) $required] < 0} {
+ user-error "autosetup version $required is required, but this is $::autosetup(version)"
+ }
+}
+
proc autosetup_version {} {
return "autosetup v$::autosetup(version)"
}
@@ -914,19 +1162,31 @@ proc autosetup_add_dep {filename} {
# when it is loaded.
#
proc use {args} {
+ global autosetup libmodule modsource
+
+ set dirs [list $autosetup(libdir)]
+ if {[info exists autosetup(srcdir)]} {
+ lappend dirs $autosetup(srcdir)/autosetup
+ }
foreach m $args {
- if {[info exists ::libmodule($m)]} {
+ if {[info exists libmodule($m)]} {
continue
}
- set ::libmodule($m) 1
- if {[info exists ::modsource($m)]} {
- automf_load eval $::modsource($m)
+ set libmodule($m) 1
+ if {[info exists modsource(${m}.tcl)]} {
+ automf_load eval $modsource(${m}.tcl)
} else {
- set sources [list $::autosetup(libdir)/${m}.tcl $::autosetup(libdir)/${m}/init.tcl]
+ set locs [list ${m}.tcl ${m}/init.tcl]
set found 0
- foreach source $sources {
- if {[file exists $source]} {
- incr found
+ foreach dir $dirs {
+ foreach loc $locs {
+ set source $dir/$loc
+ if {[file exists $source]} {
+ incr found
+ break
+ }
+ }
+ if {$found} {
break
}
}
@@ -943,6 +1203,18 @@ proc use {args} {
}
}
+proc autosetup_load_auto_modules {} {
+ global autosetup modsource
+ # First load any embedded auto modules
+ foreach mod [array names modsource *.auto] {
+ automf_load eval $modsource($mod)
+ }
+ # Now any external auto modules
+ foreach file [glob -nocomplain $autosetup(libdir)/*.auto $autosetup(libdir)/*/*.auto] {
+ automf_load source $file
+ }
+}
+
# Load module source in the global scope by executing the given command
proc automf_load {args} {
if {[catch [list uplevel #0 $args] msg opts] ni {0 2 3}} {
@@ -955,14 +1227,17 @@ set autosetup(exe) $::argv0
set autosetup(istcl) 1
set autosetup(start) [clock millis]
set autosetup(installed) 0
+set autosetup(sysinstall) 0
set autosetup(msg-checking) 0
set autosetup(msg-quiet) 0
+set autosetup(inittypes) {}
# Embedded modules are inserted below here
set autosetup(installed) 1
-# ----- module asciidoc-formatting -----
+set autosetup(sysinstall) 0
+# ----- @module asciidoc-formatting.tcl -----
-set modsource(asciidoc-formatting) {
+set modsource(asciidoc-formatting.tcl) {
# Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/
# All rights reserved
@@ -1030,15 +1305,15 @@ proc defn {first args} {
}
}
-# ----- module formatting -----
+# ----- @module formatting.tcl -----
-set modsource(formatting) {
+set modsource(formatting.tcl) {
# Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/
# All rights reserved
# Module which provides common text formatting
-# This is designed for documenation which looks like:
+# This is designed for documentation which looks like:
# code {...}
# or
# code {
@@ -1087,21 +1362,28 @@ proc parse_code_block {text} {
}
}
-# ----- module getopt -----
+# ----- @module getopt.tcl -----
-set modsource(getopt) {
+set modsource(getopt.tcl) {
# Copyright (c) 2006 WorkWare Systems http://www.workware.net.au/
# All rights reserved
# Simple getopt module
# Parse everything out of the argv list which looks like an option
-# Knows about --enable-thing and --disable-thing as alternatives for --thing=0 or --thing=1
# Everything which doesn't look like an option, or is after --, is left unchanged
+# Understands --enable-xxx as a synonym for --xxx to enable the boolean option xxx.
+# Understands --disable-xxx to disable the boolean option xxx.
+#
+# The returned value is a dictionary keyed by option name
+# Each value is a list of {type value} ... where type is "bool" or "str".
+# The value for a boolean option is 0 or 1. The value of a string option is the value given.
proc getopt {argvname} {
upvar $argvname argv
set nargv {}
+ set opts {}
+
for {set i 0} {$i < [llength $argv]} {incr i} {
set arg [lindex $argv $i]
@@ -1115,65 +1397,33 @@ proc getopt {argvname} {
}
if {[regexp {^--([^=][^=]+)=(.*)$} $arg -> name value]} {
- lappend opts($name) $value
+ # --name=value
+ dict lappend opts $name [list str $value]
} elseif {[regexp {^--(enable-|disable-)?([^=]*)$} $arg -> prefix name]} {
- if {$prefix eq "disable-"} {
- set value 0
- } else {
+ if {$prefix in {enable- ""}} {
set value 1
+ } else {
+ set value 0
}
- lappend opts($name) $value
+ dict lappend opts $name [list bool $value]
} else {
lappend nargv $arg
}
}
#puts "getopt: argv=[join $argv] => [join $nargv]"
- #parray opts
+ #array set getopt $opts
+ #parray getopt
set argv $nargv
- return [array get opts]
+ return $opts
}
-
-proc opt_val {optarrayname options {default {}}} {
- upvar $optarrayname opts
-
- set result {}
-
- foreach o $options {
- if {[info exists opts($o)]} {
- lappend result {*}$opts($o)
- }
- }
- if {[llength $result] == 0} {
- return $default
- }
- return $result
}
-proc opt_bool {optarrayname args} {
- upvar $optarrayname opts
-
- # Support the args being passed as a list
- if {[llength $args] == 1} {
- set args [lindex $args 0]
- }
+# ----- @module help.tcl -----
- foreach o $args {
- if {[info exists opts($o)]} {
- if {"1" in $opts($o) || "yes" in $opts($o)} {
- return 1
- }
- }
- }
- return 0
-}
-}
-
-# ----- module help -----
-
-set modsource(help) {
+set modsource(help.tcl) {
# Copyright (c) 2010 WorkWare Systems http://workware.net.au/
# All rights reserved
@@ -1205,6 +1455,24 @@ proc autosetup_help {what} {
exit 0
}
+proc autosetup_show_license {} {
+ global modsource autosetup
+ use_pager
+
+ if {[info exists modsource(LICENSE)]} {
+ puts $modsource(LICENSE)
+ return
+ }
+ foreach dir [list $autosetup(libdir) $autosetup(srcdir)] {
+ set path [file join $dir LICENSE]
+ if {[file exists $path]} {
+ puts [readfile $path]
+ return
+ }
+ }
+ puts "LICENSE not found"
+}
+
# If not already paged and stdout is a tty, pipe the output through the pager
# This is done by reinvoking autosetup with --nopager added
proc use_pager {} {
@@ -1257,6 +1525,12 @@ proc autosetup_reference {{type text}} {
proc autosetup_output_block {type lines} {
if {[llength $lines]} {
switch $type {
+ section {
+ section $lines
+ }
+ subsection {
+ subsection $lines
+ }
code {
codelines $lines
}
@@ -1278,16 +1552,30 @@ proc automf_command_reference {} {
lappend files $::autosetup(prog)
lappend files {*}[lsort [glob -nocomplain $::autosetup(libdir)/*.tcl]]
- section "Core Commands"
- set type p
- set lines {}
- set cmd {}
+ # We want to process all non-module files before module files
+ # and then modules in alphabetical order.
+ # So examine all files and extract docs into doc($modulename) and doc(_core_)
+ #
+ # Each entry is a list of {type data} where $type is one of: section, subsection, code, list, p
+ # and $data is a string for section, subsection or a list of text lines for other types.
+
+ # XXX: Should commands be in alphabetical order too? Currently they are in file order.
+
+ set doc(_core_) {}
+ lappend doc(_core_) [list section "Core Commands"]
foreach file $files {
+ set modulename [file rootname [file tail $file]]
+ set current _core_
set f [open $file]
while {![eof $f]} {
set line [gets $f]
+ # Find embedded module names
+ if {[regexp {^#.*@module ([^ ]*)} $line -> modulename]} {
+ continue
+ }
+
# Find lines starting with "# @*" and continuing through the remaining comment lines
if {![regexp {^# @(.*)} $line -> cmd]} {
continue
@@ -1295,9 +1583,10 @@ proc automf_command_reference {} {
# Synopsis or command?
if {$cmd eq "synopsis:"} {
- section "Module: [file rootname [file tail $file]]"
+ set current $modulename
+ lappend doc($current) [list section "Module: $modulename"]
} else {
- subsection $cmd
+ lappend doc($current) [list subsection $cmd]
}
set lines {}
@@ -1322,7 +1611,7 @@ proc automf_command_reference {} {
if {$t ne $type || $cmd eq ""} {
# Finish the current block
- autosetup_output_block $type $lines
+ lappend doc($current) [list $type $lines]
set lines {}
set type $t
}
@@ -1331,16 +1620,25 @@ proc automf_command_reference {} {
}
}
- autosetup_output_block $type $lines
+ lappend doc($current) [list $type $lines]
}
close $f
}
+
+ # Now format and output the results
+
+ # _core_ will sort first
+ foreach module [lsort [array names doc]] {
+ foreach item $doc($module) {
+ autosetup_output_block {*}$item
+ }
+ }
}
}
-# ----- module init -----
+# ----- @module init.tcl -----
-set modsource(init) {
+set modsource(init.tcl) {
# Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/
# All rights reserved
@@ -1397,25 +1695,63 @@ proc autosetup_check_create {filename contents} {
}
}
-# ----- module install -----
+# ----- @module install.tcl -----
-set modsource(install) {
+set modsource(install.tcl) {
# Copyright (c) 2006-2010 WorkWare Systems http://www.workware.net.au/
# All rights reserved
# Module which can install autosetup
-proc autosetup_install {dir} {
- if {[catch {
+# autosetup(installed)=1 means that autosetup is not running from source
+# autosetup(sysinstall)=1 means that autosetup is running from a sysinstall version
+# shared=1 means that we are trying to do a sysinstall. This is only possible from the development source.
+
+proc autosetup_install {dir {shared 0}} {
+ global autosetup
+ if {$shared} {
+ if {$autosetup(installed) || $autosetup(sysinstall)} {
+ user-error "Can only --sysinstall from development sources"
+ }
+ } elseif {$autosetup(installed) && !$autosetup(sysinstall)} {
+ user-error "Can't --install from project install"
+ }
+
+ if {$autosetup(sysinstall)} {
+ # This is the sysinstall version, so install just uses references
cd $dir
+
+ puts "[autosetup_version] creating configure to use system-installed autosetup"
+ autosetup_create_configure 1
+ puts "Creating autosetup/README.autosetup"
file mkdir autosetup
+ autosetup_install_readme autosetup/README.autosetup 1
+ return
+ }
- set f [open autosetup/autosetup w]
+ if {[catch {
+ if {$shared} {
+ set target $dir/bin/autosetup
+ set installedas $target
+ } else {
+ if {$dir eq "."} {
+ set installedas autosetup
+ } else {
+ set installedas $dir/autosetup
+ }
+ cd $dir
+ file mkdir autosetup
+ set target autosetup/autosetup
+ }
+ set targetdir [file dirname $target]
+ file mkdir $targetdir
+
+ set f [open $target w]
- set publicmodules [glob $::autosetup(libdir)/*.auto]
+ set publicmodules {}
# First the main script, but only up until "CUT HERE"
- set in [open $::autosetup(dir)/autosetup]
+ set in [open $autosetup(dir)/autosetup]
while {[gets $in buf] >= 0} {
if {$buf ne "##-- CUT HERE --##"} {
puts $f $buf
@@ -1424,48 +1760,88 @@ proc autosetup_install {dir} {
# Insert the static modules here
# i.e. those which don't contain @synopsis:
+ # All modules are inserted if $shared is set
puts $f "set autosetup(installed) 1"
- foreach file [lsort [glob $::autosetup(libdir)/*.tcl]] {
+ puts $f "set autosetup(sysinstall) $shared"
+ foreach file [lsort [glob $autosetup(libdir)/*.{tcl,auto}]] {
+ set modname [file tail $file]
+ set ext [file ext $modname]
set buf [readfile $file]
- if {[string match "*\n# @synopsis:*" $buf]} {
- lappend publicmodules $file
- continue
+ if {!$shared} {
+ if {$ext eq ".auto" || [string match "*\n# @synopsis:*" $buf]} {
+ lappend publicmodules $file
+ continue
+ }
}
- set modname [file rootname [file tail $file]]
- puts $f "# ----- module $modname -----"
+ dputs "install: importing lib/[file tail $file]"
+ puts $f "# ----- @module $modname -----"
puts $f "\nset modsource($modname) \{"
puts $f $buf
puts $f "\}\n"
}
+ if {$shared} {
+ foreach {srcname destname} [list $autosetup(libdir)/README.autosetup-lib README.autosetup \
+ $autosetup(srcdir)/LICENSE LICENSE] {
+ dputs "install: importing $srcname as $destname"
+ puts $f "\nset modsource($destname) \\\n[list [readfile $srcname]\n]\n"
+ }
+ }
}
close $in
close $f
- exec chmod 755 autosetup/autosetup
+ catch {exec chmod 755 $target}
+
+ set installfiles {autosetup-config.guess autosetup-config.sub autosetup-test-tclsh}
+ set removefiles {}
+
+ if {!$shared} {
+ autosetup_install_readme $targetdir/README.autosetup 0
- # Install public modules
- foreach file $publicmodules {
- autosetup_install_file $file autosetup
+ # Install public modules
+ foreach file $publicmodules {
+ set tail [file tail $file]
+ autosetup_install_file $file $targetdir/$tail
+ }
+ lappend installfiles jimsh0.c autosetup-find-tclsh LICENSE
+ lappend removefiles config.guess config.sub test-tclsh find-tclsh
+ } else {
+ lappend installfiles {sys-find-tclsh autosetup-find-tclsh}
}
# Install support files
- foreach file {config.guess config.sub jimsh0.c find-tclsh test-tclsh LICENSE} {
- autosetup_install_file $::autosetup(dir)/$file autosetup
+ foreach fileinfo $installfiles {
+ if {[llength $fileinfo] == 2} {
+ lassign $fileinfo source dest
+ } else {
+ lassign $fileinfo source
+ set dest $source
+ }
+ autosetup_install_file $autosetup(dir)/$source $targetdir/$dest
}
- exec chmod 755 autosetup/config.sub autosetup/config.guess autosetup/find-tclsh
-
- writefile autosetup/README.autosetup \
- "This is [autosetup_version]. See http://msteveb.github.com/autosetup/\n"
+ # Remove obsolete files
+ foreach file $removefiles {
+ if {[file exists $targetdir/$file]} {
+ file delete $targetdir/$file
+ }
+ }
} error]} {
user-error "Failed to install autosetup: $error"
}
- puts "Installed [autosetup_version] to autosetup/"
+ if {$shared} {
+ set type "system"
+ } else {
+ set type "local"
+ }
+ puts "Installed $type [autosetup_version] to $installedas"
- # Now create 'configure' if necessary
- autosetup_create_configure
+ if {!$shared} {
+ # Now create 'configure' if necessary
+ autosetup_create_configure 0
+ }
}
-proc autosetup_create_configure {} {
+proc autosetup_create_configure {shared} {
if {[file exists configure]} {
if {!$::autosetup(force)} {
# Could this be an autosetup configure?
@@ -1480,36 +1856,71 @@ proc autosetup_create_configure {} {
} else {
puts "I don't see configure, so I will create it."
}
- writefile configure \
+ if {$shared} {
+ writefile configure \
+{#!/bin/sh
+WRAPPER="$0"; export WRAPPER; "autosetup" "$@"
+}
+ } else {
+ writefile configure \
{#!/bin/sh
dir="`dirname "$0"`/autosetup"
-WRAPPER="$0"; export WRAPPER; exec "`$dir/find-tclsh`" "$dir/autosetup" "$@"
+WRAPPER="$0"; export WRAPPER; exec "`"$dir/autosetup-find-tclsh"`" "$dir/autosetup" "$@"
}
+ }
catch {exec chmod 755 configure}
}
# Append the contents of $file to filehandle $f
proc autosetup_install_append {f file} {
+ dputs "install: include $file"
set in [open $file]
puts $f [read $in]
close $in
}
-proc autosetup_install_file {file dir} {
- if {![file exists $file]} {
- error "Missing installation file '$file'"
+proc autosetup_install_file {source target} {
+ dputs "install: $source => $target"
+ if {![file exists $source]} {
+ error "Missing installation file '$source'"
}
- writefile [file join $dir [file tail $file]] [readfile $file]\n
+ writefile $target [readfile $source]\n
+ # If possible, copy the file mode
+ file stat $source stat
+ set mode [format %o [expr {$stat(mode) & 0x1ff}]]
+ catch {exec chmod $mode $target}
+}
+
+proc autosetup_install_readme {target sysinstall} {
+ set readme "README.autosetup created by [autosetup_version]\n\n"
+ if {$sysinstall} {
+ append readme \
+{This is the autosetup directory for a system install of autosetup.
+Loadable modules can be added here.
+}
+ } else {
+ append readme \
+{This is the autosetup directory for a local install of autosetup.
+It contains autosetup, support files and loadable modules.
}
+}
+
+ append readme {
+*.tcl files in this directory are optional modules which
+can be loaded with the 'use' directive.
+
+*.auto files in this directory are auto-loaded.
-if {$::autosetup(installed)} {
- user-error "autosetup can only be installed from development source, not from installed copy"
+For more information, see http://msteveb.github.com/autosetup/
+}
+ dputs "install: autosetup/README.autosetup"
+ writefile $target $readme
}
}
-# ----- module markdown-formatting -----
+# ----- @module markdown-formatting.tcl -----
-set modsource(markdown-formatting) {
+set modsource(markdown-formatting.tcl) {
# Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/
# All rights reserved
@@ -1580,9 +1991,9 @@ proc defn {first args} {
}
}
-# ----- module misc -----
+# ----- @module misc.tcl -----
-set modsource(misc) {
+set modsource(misc.tcl) {
# Copyright (c) 2007-2010 WorkWare Systems http://www.workware.net.au/
# All rights reserved
@@ -1758,9 +2169,9 @@ proc error-dump {msg opts fulltrace} {
}
}
-# ----- module text-formatting -----
+# ----- @module text-formatting.tcl -----
-set modsource(text-formatting) {
+set modsource(text-formatting.tcl) {
# Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/
# All rights reserved
@@ -1769,91 +2180,203 @@ set modsource(text-formatting) {
use formatting
proc wordwrap {text length {firstprefix ""} {nextprefix ""}} {
- set len 0
- set space $firstprefix
- foreach word [split $text] {
- set word [string trim $word]
- if {$word == ""} {
- continue
- }
- if {$len && [string length $space$word] + $len >= $length} {
- puts ""
- set len 0
- set space $nextprefix
- }
- incr len [string length $space$word]
-
- # Use man-page conventions for highlighting 'quoted' and *quoted*
- # single words.
- # Use x^Hx for *bold* and _^Hx for 'underline'.
- #
- # less and more will both understand this.
- # Pipe through 'col -b' to remove them.
- if {[regexp {^'(.*)'([^a-zA-Z0-9_]*)$} $word -> bareword dot]} {
- regsub -all . $bareword "_\b&" word
- append word $dot
- } elseif {[regexp {^[*](.*)[*]([^a-zA-Z0-9_]*)$} $word -> bareword dot]} {
- regsub -all . $bareword "&\b&" word
- append word $dot
- }
- puts -nonewline $space$word
- set space " "
- }
- if {$len} {
- puts ""
- }
+ set len 0
+ set space $firstprefix
+
+ foreach word [split $text] {
+ set word [string trim $word]
+ if {$word eq ""} {
+ continue
+ }
+ if {[info exists partial]} {
+ append partial " " $word
+ if {[string first $quote $word] < 0} {
+ # Haven't found end of quoted word
+ continue
+ }
+ # Finished quoted word
+ set word $partial
+ unset partial
+ unset quote
+ } else {
+ set quote [string index $word 0]
+ if {$quote in {' *}} {
+ if {[string first $quote $word 1] < 0} {
+ # Haven't found end of quoted word
+ # Not a whole word.
+ set first [string index $word 0]
+ # Start of quoted word
+ set partial $word
+ continue
+ }
+ }
+ }
+
+ if {$len && [string length $space$word] + $len >= $length} {
+ puts ""
+ set len 0
+ set space $nextprefix
+ }
+ incr len [string length $space$word]
+
+ # Use man-page conventions for highlighting 'quoted' and *quoted*
+ # single words.
+ # Use x^Hx for *bold* and _^Hx for 'underline'.
+ #
+ # less and more will both understand this.
+ # Pipe through 'col -b' to remove them.
+ if {[regexp {^'(.*)'(.*)} $word -> quoted after]} {
+ set quoted [string map {~ " "} $quoted]
+ regsub -all . $quoted "&\b&" quoted
+ set word $quoted$after
+ } elseif {[regexp {^[*](.*)[*](.*)} $word -> quoted after]} {
+ set quoted [string map {~ " "} $quoted]
+ regsub -all . $quoted "_\b&" quoted
+ set word $quoted$after
+ }
+ puts -nonewline $space$word
+ set space " "
+ }
+ if {[info exists partial]} {
+ # Missing end of quote
+ puts -nonewline $space$partial
+ }
+ if {$len} {
+ puts ""
+ }
}
proc title {text} {
- underline [string trim $text] =
- nl
+ underline [string trim $text] =
+ nl
}
proc p {text} {
- wordwrap $text 80
- nl
+ wordwrap $text 80
+ nl
}
proc codelines {lines} {
- foreach line $lines {
- puts " $line"
- }
- nl
+ foreach line $lines {
+ puts " $line"
+ }
+ nl
}
proc nl {} {
- puts ""
+ puts ""
}
proc underline {text char} {
- regexp "^(\[ \t\]*)(.*)" $text -> indent words
- puts $text
- puts $indent[string repeat $char [string length $words]]
+ regexp "^(\[ \t\]*)(.*)" $text -> indent words
+ puts $text
+ puts $indent[string repeat $char [string length $words]]
}
proc section {text} {
- underline "[string trim $text]" -
- nl
+ underline "[string trim $text]" -
+ nl
}
proc subsection {text} {
- underline "$text" ~
- nl
+ underline "$text" ~
+ nl
}
proc bullet {text} {
- wordwrap $text 76 " * " " "
+ wordwrap $text 76 " * " " "
}
proc indent {text} {
- wordwrap $text 76 " " " "
+ wordwrap $text 76 " " " "
}
proc defn {first args} {
- if {$first ne ""} {
- underline " $first" ~
- }
- foreach p $args {
- if {$p ne ""} {
- indent $p
- }
- }
+ if {$first ne ""} {
+ underline " $first" ~
+ }
+ foreach p $args {
+ if {$p ne ""} {
+ indent $p
+ }
+ }
+}
+}
+
+# ----- @module util.tcl -----
+
+set modsource(util.tcl) {
+# Copyright (c) 2012 WorkWare Systems http://www.workware.net.au/
+# All rights reserved
+
+# Module which contains miscellaneous utility functions
+
+# @compare-versions version1 version2
+#
+# Versions are of the form 'a.b.c' (may be any number of numeric components)
+#
+# Compares the two versions and returns:
+## -1 if v1 < v2
+## 0 if v1 == v2
+## 1 if v1 > v2
+#
+# If one version has fewer components than the other, 0 is substituted to the right. e.g.
+## 0.2 < 0.3
+## 0.2.5 > 0.2
+## 1.1 == 1.1.0
+#
+proc compare-versions {v1 v2} {
+ foreach c1 [split $v1 .] c2 [split $v2 .] {
+ if {$c1 eq ""} {
+ set c1 0
+ }
+ if {$c2 eq ""} {
+ set c2 0
+ }
+ if {$c1 < $c2} {
+ return -1
+ }
+ if {$c1 > $c2} {
+ return 1
+ }
+ }
+ return 0
+}
+
+# @suffix suf list
+#
+# Takes a list and returns a new list with '$suf' appended
+# to each element
+#
+## suffix .c {a b c} => {a.c b.c c.c}
+#
+proc suffix {suf list} {
+ set result {}
+ foreach p $list {
+ lappend result $p$suf
+ }
+ return $result
+}
+
+# @prefix pre list
+#
+# Takes a list and returns a new list with '$pre' prepended
+# to each element
+#
+## prefix jim- {a.c b.c} => {jim-a.c jim-b.c}
+#
+proc prefix {pre list} {
+ set result {}
+ foreach p $list {
+ lappend result $pre$p
+ }
+ return $result
+}
+
+# @lpop list
+#
+# Removes the last entry from the given list and returns it.
+proc lpop {listname} {
+ upvar $listname list
+ set val [lindex $list end]
+ set list [lrange $list 0 end-1]
+ return $val
}
}
-# ----- module wiki-formatting -----
+# ----- @module wiki-formatting.tcl -----
-set modsource(wiki-formatting) {
+set modsource(wiki-formatting.tcl) {
# Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/
# All rights reserved
@@ -1928,7 +2451,7 @@ if {$autosetup(debug)} {
}
if {[catch {main $argv} msg opts] == 1} {
show-notices
- autosetup-full-error [error-dump $msg $opts $::autosetup(debug)]
+ autosetup-full-error [error-dump $msg $opts $autosetup(debug)]
if {!$autosetup(debug)} {
puts stderr "Try: '[file tail $autosetup(exe)] --debug' for a full stack trace"
}
diff --git a/autosetup/config.guess b/autosetup/autosetup-config.guess
index 6c32c86..256083a 100755
--- a/autosetup/config.guess
+++ b/autosetup/autosetup-config.guess
@@ -1,8 +1,8 @@
#! /bin/sh
# Attempt to guess a canonical system name.
-# Copyright 1992-2014 Free Software Foundation, Inc.
+# Copyright 1992-2018 Free Software Foundation, Inc.
-timestamp='2014-11-04'
+timestamp='2018-03-08'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -15,7 +15,7 @@ timestamp='2014-11-04'
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program; if not, see <http://www.gnu.org/licenses/>.
+# along with this program; if not, see <https://www.gnu.org/licenses/>.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@@ -27,7 +27,7 @@ timestamp='2014-11-04'
# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
#
# You can get the latest version of this script from:
-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
#
# Please send patches to <config-patches@gnu.org>.
@@ -39,7 +39,7 @@ Usage: $0 [OPTION]
Output the configuration name of the system \`$me' is run on.
-Operation modes:
+Options:
-h, --help print this help, then exit
-t, --time-stamp print date of last modification, then exit
-v, --version print version number, then exit
@@ -50,7 +50,7 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
-Copyright 1992-2014 Free Software Foundation, Inc.
+Copyright 1992-2018 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."
@@ -107,9 +107,9 @@ trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
dummy=$tmp/dummy ;
tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
case $CC_FOR_BUILD,$HOST_CC,$CC in
- ,,) echo "int x;" > $dummy.c ;
+ ,,) echo "int x;" > "$dummy.c" ;
for c in cc gcc c89 c99 ; do
- if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+ if ($c -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then
CC_FOR_BUILD="$c"; break ;
fi ;
done ;
@@ -132,14 +132,14 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
-case "${UNAME_SYSTEM}" in
+case "$UNAME_SYSTEM" in
Linux|GNU|GNU/*)
# If the system lacks a compiler, then just pick glibc.
# We could probably try harder.
LIBC=gnu
- eval $set_cc_for_build
- cat <<-EOF > $dummy.c
+ eval "$set_cc_for_build"
+ cat <<-EOF > "$dummy.c"
#include <features.h>
#if defined(__UCLIBC__)
LIBC=uclibc
@@ -149,13 +149,20 @@ Linux|GNU|GNU/*)
LIBC=gnu
#endif
EOF
- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
+ eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`"
+
+ # If ldd exists, use it to detect musl libc.
+ if command -v ldd >/dev/null && \
+ ldd --version 2>&1 | grep -q ^musl
+ then
+ LIBC=musl
+ fi
;;
esac
# Note: order is significant - the case branches are not exclusive.
-case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
*:NetBSD:*:*)
# NetBSD (nbsd) targets should (where applicable) match one or
# more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
@@ -168,21 +175,31 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# Note: NetBSD doesn't particularly care about the vendor
# portion of the name. We always set it to "unknown".
sysctl="sysctl -n hw.machine_arch"
- UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
- /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
- case "${UNAME_MACHINE_ARCH}" in
+ UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
+ "/sbin/$sysctl" 2>/dev/null || \
+ "/usr/sbin/$sysctl" 2>/dev/null || \
+ echo unknown)`
+ case "$UNAME_MACHINE_ARCH" in
armeb) machine=armeb-unknown ;;
arm*) machine=arm-unknown ;;
sh3el) machine=shl-unknown ;;
sh3eb) machine=sh-unknown ;;
sh5el) machine=sh5le-unknown ;;
- *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+ earmv*)
+ arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
+ endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'`
+ machine="${arch}${endian}"-unknown
+ ;;
+ *) machine="$UNAME_MACHINE_ARCH"-unknown ;;
esac
# The Operating System including object format, if it has switched
- # to ELF recently, or will in the future.
- case "${UNAME_MACHINE_ARCH}" in
+ # to ELF recently (or will in the future) and ABI.
+ case "$UNAME_MACHINE_ARCH" in
+ earm*)
+ os=netbsdelf
+ ;;
arm*|i386|m68k|ns32k|sh3*|sparc|vax)
- eval $set_cc_for_build
+ eval "$set_cc_for_build"
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ELF__
then
@@ -197,44 +214,67 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
os=netbsd
;;
esac
+ # Determine ABI tags.
+ case "$UNAME_MACHINE_ARCH" in
+ earm*)
+ expr='s/^earmv[0-9]/-eabi/;s/eb$//'
+ abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"`
+ ;;
+ esac
# The OS release
# Debian GNU/NetBSD machines have a different userland, and
# thus, need a distinct triplet. However, they do not need
# kernel version information, so it can be replaced with a
# suitable tag, in the style of linux-gnu.
- case "${UNAME_VERSION}" in
+ case "$UNAME_VERSION" in
Debian*)
release='-gnu'
;;
*)
- release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2`
;;
esac
# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
# contains redundant information, the shorter form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
- echo "${machine}-${os}${release}"
+ echo "$machine-${os}${release}${abi}"
exit ;;
*:Bitrig:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
- echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
+ echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE"
exit ;;
*:OpenBSD:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
- echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+ echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE"
+ exit ;;
+ *:LibertyBSD:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'`
+ echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE"
+ exit ;;
+ *:MidnightBSD:*:*)
+ echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE"
exit ;;
*:ekkoBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+ echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE"
exit ;;
*:SolidBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+ echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE"
exit ;;
macppc:MirBSD:*:*)
- echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+ echo powerpc-unknown-mirbsd"$UNAME_RELEASE"
exit ;;
*:MirBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+ echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE"
exit ;;
+ *:Sortix:*:*)
+ echo "$UNAME_MACHINE"-unknown-sortix
+ exit ;;
+ *:Redox:*:*)
+ echo "$UNAME_MACHINE"-unknown-redox
+ exit ;;
+ mips:OSF1:*.*)
+ echo mips-dec-osf1
+ exit ;;
alpha:OSF1:*:*)
case $UNAME_RELEASE in
*4.0)
@@ -251,63 +291,54 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
case "$ALPHA_CPU_TYPE" in
"EV4 (21064)")
- UNAME_MACHINE="alpha" ;;
+ UNAME_MACHINE=alpha ;;
"EV4.5 (21064)")
- UNAME_MACHINE="alpha" ;;
+ UNAME_MACHINE=alpha ;;
"LCA4 (21066/21068)")
- UNAME_MACHINE="alpha" ;;
+ UNAME_MACHINE=alpha ;;
"EV5 (21164)")
- UNAME_MACHINE="alphaev5" ;;
+ UNAME_MACHINE=alphaev5 ;;
"EV5.6 (21164A)")
- UNAME_MACHINE="alphaev56" ;;
+ UNAME_MACHINE=alphaev56 ;;
"EV5.6 (21164PC)")
- UNAME_MACHINE="alphapca56" ;;
+ UNAME_MACHINE=alphapca56 ;;
"EV5.7 (21164PC)")
- UNAME_MACHINE="alphapca57" ;;
+ UNAME_MACHINE=alphapca57 ;;
"EV6 (21264)")
- UNAME_MACHINE="alphaev6" ;;
+ UNAME_MACHINE=alphaev6 ;;
"EV6.7 (21264A)")
- UNAME_MACHINE="alphaev67" ;;
+ UNAME_MACHINE=alphaev67 ;;
"EV6.8CB (21264C)")
- UNAME_MACHINE="alphaev68" ;;
+ UNAME_MACHINE=alphaev68 ;;
"EV6.8AL (21264B)")
- UNAME_MACHINE="alphaev68" ;;
+ UNAME_MACHINE=alphaev68 ;;
"EV6.8CX (21264D)")
- UNAME_MACHINE="alphaev68" ;;
+ UNAME_MACHINE=alphaev68 ;;
"EV6.9A (21264/EV69A)")
- UNAME_MACHINE="alphaev69" ;;
+ UNAME_MACHINE=alphaev69 ;;
"EV7 (21364)")
- UNAME_MACHINE="alphaev7" ;;
+ UNAME_MACHINE=alphaev7 ;;
"EV7.9 (21364A)")
- UNAME_MACHINE="alphaev79" ;;
+ UNAME_MACHINE=alphaev79 ;;
esac
# A Pn.n version is a patched version.
# A Vn.n version is a released version.
# A Tn.n version is a released field test version.
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
- echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`"
# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
exitcode=$?
trap '' 0
exit $exitcode ;;
- Alpha\ *:Windows_NT*:*)
- # How do we know it's Interix rather than the generic POSIX subsystem?
- # Should we change UNAME_MACHINE based on the output of uname instead
- # of the specific Alpha model?
- echo alpha-pc-interix
- exit ;;
- 21064:Windows_NT:50:3)
- echo alpha-dec-winnt3.5
- exit ;;
Amiga*:UNIX_System_V:4.0:*)
echo m68k-unknown-sysv4
exit ;;
*:[Aa]miga[Oo][Ss]:*:*)
- echo ${UNAME_MACHINE}-unknown-amigaos
+ echo "$UNAME_MACHINE"-unknown-amigaos
exit ;;
*:[Mm]orph[Oo][Ss]:*:*)
- echo ${UNAME_MACHINE}-unknown-morphos
+ echo "$UNAME_MACHINE"-unknown-morphos
exit ;;
*:OS/390:*:*)
echo i370-ibm-openedition
@@ -319,7 +350,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
echo powerpc-ibm-os400
exit ;;
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
- echo arm-acorn-riscix${UNAME_RELEASE}
+ echo arm-acorn-riscix"$UNAME_RELEASE"
exit ;;
arm*:riscos:*:*|arm*:RISCOS:*:*)
echo arm-unknown-riscos
@@ -346,38 +377,38 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
sparc) echo sparc-icl-nx7; exit ;;
esac ;;
s390x:SunOS:*:*)
- echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`"
exit ;;
sun4H:SunOS:5.*:*)
- echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
exit ;;
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
- echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`"
exit ;;
i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
- echo i386-pc-auroraux${UNAME_RELEASE}
+ echo i386-pc-auroraux"$UNAME_RELEASE"
exit ;;
i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
- eval $set_cc_for_build
- SUN_ARCH="i386"
+ eval "$set_cc_for_build"
+ SUN_ARCH=i386
# If there is a compiler, see if it is configured for 64-bit objects.
# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
# This test works for both compilers.
- if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
- (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
grep IS_64BIT_ARCH >/dev/null
then
- SUN_ARCH="x86_64"
+ SUN_ARCH=x86_64
fi
fi
- echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
exit ;;
sun4*:SunOS:6*:*)
# According to config.sub, this is the proper way to canonicalize
# SunOS6. Hard to guess exactly what SunOS6 will be like, but
# it's likely to be more like Solaris than SunOS4.
- echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ echo sparc-sun-solaris3"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
exit ;;
sun4*:SunOS:*:*)
case "`/usr/bin/arch -k`" in
@@ -386,25 +417,25 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
;;
esac
# Japanese Language versions have a version number like `4.1.3-JL'.
- echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+ echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`"
exit ;;
sun3*:SunOS:*:*)
- echo m68k-sun-sunos${UNAME_RELEASE}
+ echo m68k-sun-sunos"$UNAME_RELEASE"
exit ;;
sun*:*:4.2BSD:*)
UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
- test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+ test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3
case "`/bin/arch`" in
sun3)
- echo m68k-sun-sunos${UNAME_RELEASE}
+ echo m68k-sun-sunos"$UNAME_RELEASE"
;;
sun4)
- echo sparc-sun-sunos${UNAME_RELEASE}
+ echo sparc-sun-sunos"$UNAME_RELEASE"
;;
esac
exit ;;
aushp:SunOS:*:*)
- echo sparc-auspex-sunos${UNAME_RELEASE}
+ echo sparc-auspex-sunos"$UNAME_RELEASE"
exit ;;
# The situation for MiNT is a little confusing. The machine name
# can be virtually everything (everything which is not
@@ -415,44 +446,44 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# MiNT. But MiNT is downward compatible to TOS, so this should
# be no problem.
atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
+ echo m68k-atari-mint"$UNAME_RELEASE"
exit ;;
atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
+ echo m68k-atari-mint"$UNAME_RELEASE"
exit ;;
*falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
+ echo m68k-atari-mint"$UNAME_RELEASE"
exit ;;
milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
- echo m68k-milan-mint${UNAME_RELEASE}
+ echo m68k-milan-mint"$UNAME_RELEASE"
exit ;;
hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
- echo m68k-hades-mint${UNAME_RELEASE}
+ echo m68k-hades-mint"$UNAME_RELEASE"
exit ;;
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
- echo m68k-unknown-mint${UNAME_RELEASE}
+ echo m68k-unknown-mint"$UNAME_RELEASE"
exit ;;
m68k:machten:*:*)
- echo m68k-apple-machten${UNAME_RELEASE}
+ echo m68k-apple-machten"$UNAME_RELEASE"
exit ;;
powerpc:machten:*:*)
- echo powerpc-apple-machten${UNAME_RELEASE}
+ echo powerpc-apple-machten"$UNAME_RELEASE"
exit ;;
RISC*:Mach:*:*)
echo mips-dec-mach_bsd4.3
exit ;;
RISC*:ULTRIX:*:*)
- echo mips-dec-ultrix${UNAME_RELEASE}
+ echo mips-dec-ultrix"$UNAME_RELEASE"
exit ;;
VAX*:ULTRIX*:*:*)
- echo vax-dec-ultrix${UNAME_RELEASE}
+ echo vax-dec-ultrix"$UNAME_RELEASE"
exit ;;
2020:CLIX:*:* | 2430:CLIX:*:*)
- echo clipper-intergraph-clix${UNAME_RELEASE}
+ echo clipper-intergraph-clix"$UNAME_RELEASE"
exit ;;
mips:*:*:UMIPS | mips:*:*:RISCos)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
+ eval "$set_cc_for_build"
+ sed 's/^ //' << EOF > "$dummy.c"
#ifdef __cplusplus
#include <stdio.h> /* for printf() prototype */
int main (int argc, char *argv[]) {
@@ -461,23 +492,23 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
#endif
#if defined (host_mips) && defined (MIPSEB)
#if defined (SYSTYPE_SYSV)
- printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0);
#endif
#if defined (SYSTYPE_SVR4)
- printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0);
#endif
#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
- printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0);
#endif
#endif
exit (-1);
}
EOF
- $CC_FOR_BUILD -o $dummy $dummy.c &&
- dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
- SYSTEM_NAME=`$dummy $dummyarg` &&
+ $CC_FOR_BUILD -o "$dummy" "$dummy.c" &&
+ dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+ SYSTEM_NAME=`"$dummy" "$dummyarg"` &&
{ echo "$SYSTEM_NAME"; exit; }
- echo mips-mips-riscos${UNAME_RELEASE}
+ echo mips-mips-riscos"$UNAME_RELEASE"
exit ;;
Motorola:PowerMAX_OS:*:*)
echo powerpc-motorola-powermax
@@ -503,17 +534,17 @@ EOF
AViiON:dgux:*:*)
# DG/UX returns AViiON for all architectures
UNAME_PROCESSOR=`/usr/bin/uname -p`
- if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+ if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ]
then
- if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
- [ ${TARGET_BINARY_INTERFACE}x = x ]
+ if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \
+ [ "$TARGET_BINARY_INTERFACE"x = x ]
then
- echo m88k-dg-dgux${UNAME_RELEASE}
+ echo m88k-dg-dgux"$UNAME_RELEASE"
else
- echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ echo m88k-dg-dguxbcs"$UNAME_RELEASE"
fi
else
- echo i586-dg-dgux${UNAME_RELEASE}
+ echo i586-dg-dgux"$UNAME_RELEASE"
fi
exit ;;
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
@@ -530,7 +561,7 @@ EOF
echo m68k-tektronix-bsd
exit ;;
*:IRIX*:*:*)
- echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`"
exit ;;
????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
@@ -542,14 +573,14 @@ EOF
if [ -x /usr/bin/oslevel ] ; then
IBM_REV=`/usr/bin/oslevel`
else
- IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"
fi
- echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+ echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV"
exit ;;
*:AIX:2:3)
if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
+ eval "$set_cc_for_build"
+ sed 's/^ //' << EOF > "$dummy.c"
#include <sys/systemcfg.h>
main()
@@ -560,7 +591,7 @@ EOF
exit(0);
}
EOF
- if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+ if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"`
then
echo "$SYSTEM_NAME"
else
@@ -574,7 +605,7 @@ EOF
exit ;;
*:AIX:*:[4567])
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
- if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+ if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then
IBM_ARCH=rs6000
else
IBM_ARCH=powerpc
@@ -583,18 +614,18 @@ EOF
IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
else
- IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"
fi
- echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+ echo "$IBM_ARCH"-ibm-aix"$IBM_REV"
exit ;;
*:AIX:*:*)
echo rs6000-ibm-aix
exit ;;
- ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*)
echo romp-ibm-bsd4.4
exit ;;
ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
- echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ echo romp-ibm-bsd"$UNAME_RELEASE" # 4.3 with uname added to
exit ;; # report: romp-ibm BSD 4.3
*:BOSX:*:*)
echo rs6000-bull-bosx
@@ -609,28 +640,28 @@ EOF
echo m68k-hp-bsd4.4
exit ;;
9000/[34678]??:HP-UX:*:*)
- HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
- case "${UNAME_MACHINE}" in
- 9000/31? ) HP_ARCH=m68000 ;;
- 9000/[34]?? ) HP_ARCH=m68k ;;
+ HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'`
+ case "$UNAME_MACHINE" in
+ 9000/31?) HP_ARCH=m68000 ;;
+ 9000/[34]??) HP_ARCH=m68k ;;
9000/[678][0-9][0-9])
if [ -x /usr/bin/getconf ]; then
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
- case "${sc_cpu_version}" in
- 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
- 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+ case "$sc_cpu_version" in
+ 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0
+ 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1
532) # CPU_PA_RISC2_0
- case "${sc_kernel_bits}" in
- 32) HP_ARCH="hppa2.0n" ;;
- 64) HP_ARCH="hppa2.0w" ;;
- '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
+ case "$sc_kernel_bits" in
+ 32) HP_ARCH=hppa2.0n ;;
+ 64) HP_ARCH=hppa2.0w ;;
+ '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20
esac ;;
esac
fi
- if [ "${HP_ARCH}" = "" ]; then
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
+ if [ "$HP_ARCH" = "" ]; then
+ eval "$set_cc_for_build"
+ sed 's/^ //' << EOF > "$dummy.c"
#define _HPUX_SOURCE
#include <stdlib.h>
@@ -663,13 +694,13 @@ EOF
exit (0);
}
EOF
- (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+ (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"`
test -z "$HP_ARCH" && HP_ARCH=hppa
fi ;;
esac
- if [ ${HP_ARCH} = "hppa2.0w" ]
+ if [ "$HP_ARCH" = hppa2.0w ]
then
- eval $set_cc_for_build
+ eval "$set_cc_for_build"
# hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
# 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
@@ -680,23 +711,23 @@ EOF
# $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
# => hppa64-hp-hpux11.23
- if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+ if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) |
grep -q __LP64__
then
- HP_ARCH="hppa2.0w"
+ HP_ARCH=hppa2.0w
else
- HP_ARCH="hppa64"
+ HP_ARCH=hppa64
fi
fi
- echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ echo "$HP_ARCH"-hp-hpux"$HPUX_REV"
exit ;;
ia64:HP-UX:*:*)
- HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
- echo ia64-hp-hpux${HPUX_REV}
+ HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'`
+ echo ia64-hp-hpux"$HPUX_REV"
exit ;;
3050*:HI-UX:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
+ eval "$set_cc_for_build"
+ sed 's/^ //' << EOF > "$dummy.c"
#include <unistd.h>
int
main ()
@@ -721,11 +752,11 @@ EOF
exit (0);
}
EOF
- $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+ $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` &&
{ echo "$SYSTEM_NAME"; exit; }
echo unknown-hitachi-hiuxwe2
exit ;;
- 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*)
echo hppa1.1-hp-bsd
exit ;;
9000/8??:4.3bsd:*:*)
@@ -734,7 +765,7 @@ EOF
*9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
echo hppa1.0-hp-mpeix
exit ;;
- hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*)
echo hppa1.1-hp-osf
exit ;;
hp8??:OSF1:*:*)
@@ -742,9 +773,9 @@ EOF
exit ;;
i*86:OSF1:*:*)
if [ -x /usr/sbin/sysversion ] ; then
- echo ${UNAME_MACHINE}-unknown-osf1mk
+ echo "$UNAME_MACHINE"-unknown-osf1mk
else
- echo ${UNAME_MACHINE}-unknown-osf1
+ echo "$UNAME_MACHINE"-unknown-osf1
fi
exit ;;
parisc*:Lites*:*:*)
@@ -769,127 +800,109 @@ EOF
echo c4-convex-bsd
exit ;;
CRAY*Y-MP:*:*:*)
- echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
exit ;;
CRAY*[A-Z]90:*:*:*)
- echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \
| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
-e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
-e 's/\.[^.]*$/.X/'
exit ;;
CRAY*TS:*:*:*)
- echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
exit ;;
CRAY*T3E:*:*:*)
- echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
exit ;;
CRAY*SV1:*:*:*)
- echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
exit ;;
*:UNICOS/mp:*:*)
- echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
exit ;;
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
- FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
- FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
+ FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
+ FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'`
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;;
5000:UNIX_System_V:4.*:*)
- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
- FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+ FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
+ FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'`
echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;;
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
- echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE"
exit ;;
sparc*:BSD/OS:*:*)
- echo sparc-unknown-bsdi${UNAME_RELEASE}
+ echo sparc-unknown-bsdi"$UNAME_RELEASE"
exit ;;
*:BSD/OS:*:*)
- echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE"
exit ;;
*:FreeBSD:*:*)
UNAME_PROCESSOR=`/usr/bin/uname -p`
- case ${UNAME_PROCESSOR} in
+ case "$UNAME_PROCESSOR" in
amd64)
- echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
- *)
- echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ UNAME_PROCESSOR=x86_64 ;;
+ i386)
+ UNAME_PROCESSOR=i586 ;;
esac
+ echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`"
exit ;;
i*:CYGWIN*:*)
- echo ${UNAME_MACHINE}-pc-cygwin
+ echo "$UNAME_MACHINE"-pc-cygwin
exit ;;
*:MINGW64*:*)
- echo ${UNAME_MACHINE}-pc-mingw64
+ echo "$UNAME_MACHINE"-pc-mingw64
exit ;;
*:MINGW*:*)
- echo ${UNAME_MACHINE}-pc-mingw32
+ echo "$UNAME_MACHINE"-pc-mingw32
exit ;;
*:MSYS*:*)
- echo ${UNAME_MACHINE}-pc-msys
- exit ;;
- i*:windows32*:*)
- # uname -m includes "-pc" on this system.
- echo ${UNAME_MACHINE}-mingw32
+ echo "$UNAME_MACHINE"-pc-msys
exit ;;
i*:PW*:*)
- echo ${UNAME_MACHINE}-pc-pw32
+ echo "$UNAME_MACHINE"-pc-pw32
exit ;;
*:Interix*:*)
- case ${UNAME_MACHINE} in
+ case "$UNAME_MACHINE" in
x86)
- echo i586-pc-interix${UNAME_RELEASE}
+ echo i586-pc-interix"$UNAME_RELEASE"
exit ;;
authenticamd | genuineintel | EM64T)
- echo x86_64-unknown-interix${UNAME_RELEASE}
+ echo x86_64-unknown-interix"$UNAME_RELEASE"
exit ;;
IA64)
- echo ia64-unknown-interix${UNAME_RELEASE}
+ echo ia64-unknown-interix"$UNAME_RELEASE"
exit ;;
esac ;;
- [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
- echo i${UNAME_MACHINE}-pc-mks
- exit ;;
- 8664:Windows_NT:*)
- echo x86_64-pc-mks
- exit ;;
- i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
- # How do we know it's Interix rather than the generic POSIX subsystem?
- # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
- # UNAME_MACHINE based on the output of uname instead of i386?
- echo i586-pc-interix
- exit ;;
i*:UWIN*:*)
- echo ${UNAME_MACHINE}-pc-uwin
+ echo "$UNAME_MACHINE"-pc-uwin
exit ;;
amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
echo x86_64-unknown-cygwin
exit ;;
- p*:CYGWIN*:*)
- echo powerpcle-unknown-cygwin
- exit ;;
prep*:SunOS:5.*:*)
- echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
exit ;;
*:GNU:*:*)
# the GNU system
- echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`"
exit ;;
*:GNU/*:*:*)
# other systems with GNU libc and userland
- echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
+ echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC"
exit ;;
i*86:Minix:*:*)
- echo ${UNAME_MACHINE}-pc-minix
+ echo "$UNAME_MACHINE"-pc-minix
exit ;;
aarch64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
aarch64_be:Linux:*:*)
UNAME_MACHINE=aarch64_be
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
alpha:Linux:*:*)
case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
@@ -902,58 +915,64 @@ EOF
EV68*) UNAME_MACHINE=alphaev68 ;;
esac
objdump --private-headers /bin/sh | grep -q ld.so.1
- if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ if test "$?" = 0 ; then LIBC=gnulibc1 ; fi
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
arc:Linux:*:* | arceb:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
arm*:Linux:*:*)
- eval $set_cc_for_build
+ eval "$set_cc_for_build"
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_EABI__
then
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
else
if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_PCS_VFP
then
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi
else
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf
fi
fi
exit ;;
avr32*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
cris:Linux:*:*)
- echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ echo "$UNAME_MACHINE"-axis-linux-"$LIBC"
exit ;;
crisv32:Linux:*:*)
- echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ echo "$UNAME_MACHINE"-axis-linux-"$LIBC"
+ exit ;;
+ e2k:Linux:*:*)
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
frv:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
hexagon:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
i*86:Linux:*:*)
- echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+ echo "$UNAME_MACHINE"-pc-linux-"$LIBC"
exit ;;
ia64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+ exit ;;
+ k1om:Linux:*:*)
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
m32r*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
m68*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
mips:Linux:*:* | mips64:Linux:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
+ eval "$set_cc_for_build"
+ sed 's/^ //' << EOF > "$dummy.c"
#undef CPU
#undef ${UNAME_MACHINE}
#undef ${UNAME_MACHINE}el
@@ -967,64 +986,70 @@ EOF
#endif
#endif
EOF
- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
+ eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU'`"
+ test "x$CPU" != x && { echo "$CPU-unknown-linux-$LIBC"; exit; }
;;
+ mips64el:Linux:*:*)
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+ exit ;;
openrisc*:Linux:*:*)
- echo or1k-unknown-linux-${LIBC}
+ echo or1k-unknown-linux-"$LIBC"
exit ;;
or32:Linux:*:* | or1k*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
padre:Linux:*:*)
- echo sparc-unknown-linux-${LIBC}
+ echo sparc-unknown-linux-"$LIBC"
exit ;;
parisc64:Linux:*:* | hppa64:Linux:*:*)
- echo hppa64-unknown-linux-${LIBC}
+ echo hppa64-unknown-linux-"$LIBC"
exit ;;
parisc:Linux:*:* | hppa:Linux:*:*)
# Look for CPU level
case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
- PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
- PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
- *) echo hppa-unknown-linux-${LIBC} ;;
+ PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;;
+ PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;;
+ *) echo hppa-unknown-linux-"$LIBC" ;;
esac
exit ;;
ppc64:Linux:*:*)
- echo powerpc64-unknown-linux-${LIBC}
+ echo powerpc64-unknown-linux-"$LIBC"
exit ;;
ppc:Linux:*:*)
- echo powerpc-unknown-linux-${LIBC}
+ echo powerpc-unknown-linux-"$LIBC"
exit ;;
ppc64le:Linux:*:*)
- echo powerpc64le-unknown-linux-${LIBC}
+ echo powerpc64le-unknown-linux-"$LIBC"
exit ;;
ppcle:Linux:*:*)
- echo powerpcle-unknown-linux-${LIBC}
+ echo powerpcle-unknown-linux-"$LIBC"
+ exit ;;
+ riscv32:Linux:*:* | riscv64:Linux:*:*)
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
s390:Linux:*:* | s390x:Linux:*:*)
- echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
+ echo "$UNAME_MACHINE"-ibm-linux-"$LIBC"
exit ;;
sh64*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
sh*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
sparc:Linux:*:* | sparc64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
tile*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
vax:Linux:*:*)
- echo ${UNAME_MACHINE}-dec-linux-${LIBC}
+ echo "$UNAME_MACHINE"-dec-linux-"$LIBC"
exit ;;
x86_64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-pc-linux-"$LIBC"
exit ;;
xtensa*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
i*86:DYNIX/ptx:4*:*)
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
@@ -1038,34 +1063,34 @@ EOF
# I am not positive that other SVR4 systems won't match this,
# I just have to hope. -- rms.
# Use sysv4.2uw... so that sysv4* matches it.
- echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION"
exit ;;
i*86:OS/2:*:*)
# If we were able to find `uname', then EMX Unix compatibility
# is probably installed.
- echo ${UNAME_MACHINE}-pc-os2-emx
+ echo "$UNAME_MACHINE"-pc-os2-emx
exit ;;
i*86:XTS-300:*:STOP)
- echo ${UNAME_MACHINE}-unknown-stop
+ echo "$UNAME_MACHINE"-unknown-stop
exit ;;
i*86:atheos:*:*)
- echo ${UNAME_MACHINE}-unknown-atheos
+ echo "$UNAME_MACHINE"-unknown-atheos
exit ;;
i*86:syllable:*:*)
- echo ${UNAME_MACHINE}-pc-syllable
+ echo "$UNAME_MACHINE"-pc-syllable
exit ;;
i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
- echo i386-unknown-lynxos${UNAME_RELEASE}
+ echo i386-unknown-lynxos"$UNAME_RELEASE"
exit ;;
i*86:*DOS:*:*)
- echo ${UNAME_MACHINE}-pc-msdosdjgpp
+ echo "$UNAME_MACHINE"-pc-msdosdjgpp
exit ;;
- i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
- UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+ i*86:*:4.*:*)
+ UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'`
if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
- echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+ echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL"
else
- echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+ echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL"
fi
exit ;;
i*86:*:5:[678]*)
@@ -1075,12 +1100,12 @@ EOF
*Pentium) UNAME_MACHINE=i586 ;;
*Pent*|*Celeron) UNAME_MACHINE=i686 ;;
esac
- echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+ echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}{$UNAME_VERSION}"
exit ;;
i*86:*:3.2:*)
if test -f /usr/options/cb.name; then
UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
- echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ echo "$UNAME_MACHINE"-pc-isc"$UNAME_REL"
elif /bin/uname -X 2>/dev/null >/dev/null ; then
UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
@@ -1090,9 +1115,9 @@ EOF
&& UNAME_MACHINE=i686
(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
&& UNAME_MACHINE=i686
- echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL"
else
- echo ${UNAME_MACHINE}-pc-sysv32
+ echo "$UNAME_MACHINE"-pc-sysv32
fi
exit ;;
pc:*:*:*)
@@ -1100,7 +1125,7 @@ EOF
# uname -m prints for DJGPP always 'pc', but it prints nothing about
# the processor, so we play safe by assuming i586.
# Note: whatever this is, it MUST be the same as what config.sub
- # prints for the "djgpp" host, or else GDB configury will decide that
+ # prints for the "djgpp" host, or else GDB configure will decide that
# this is a cross-build.
echo i586-pc-msdosdjgpp
exit ;;
@@ -1112,9 +1137,9 @@ EOF
exit ;;
i860:*:4.*:*) # i860-SVR4
if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
- echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4
else # Add other i860-SVR4 vendors below as they are discovered.
- echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ echo i860-unknown-sysv"$UNAME_RELEASE" # Unknown i860-SVR4
fi
exit ;;
mini*:CTIX:SYS*5:*)
@@ -1134,9 +1159,9 @@ EOF
test -r /etc/.relid \
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; }
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
- && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;;
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4; exit; } ;;
@@ -1145,28 +1170,28 @@ EOF
test -r /etc/.relid \
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; }
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
- && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; }
/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
- && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;;
m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
- echo m68k-unknown-lynxos${UNAME_RELEASE}
+ echo m68k-unknown-lynxos"$UNAME_RELEASE"
exit ;;
mc68030:UNIX_System_V:4.*:*)
echo m68k-atari-sysv4
exit ;;
TSUNAMI:LynxOS:2.*:*)
- echo sparc-unknown-lynxos${UNAME_RELEASE}
+ echo sparc-unknown-lynxos"$UNAME_RELEASE"
exit ;;
rs6000:LynxOS:2.*:*)
- echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ echo rs6000-unknown-lynxos"$UNAME_RELEASE"
exit ;;
PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
- echo powerpc-unknown-lynxos${UNAME_RELEASE}
+ echo powerpc-unknown-lynxos"$UNAME_RELEASE"
exit ;;
SM[BE]S:UNIX_SV:*:*)
- echo mips-dde-sysv${UNAME_RELEASE}
+ echo mips-dde-sysv"$UNAME_RELEASE"
exit ;;
RM*:ReliantUNIX-*:*:*)
echo mips-sni-sysv4
@@ -1177,7 +1202,7 @@ EOF
*:SINIX-*:*:*)
if uname -p 2>/dev/null >/dev/null ; then
UNAME_MACHINE=`(uname -p) 2>/dev/null`
- echo ${UNAME_MACHINE}-sni-sysv4
+ echo "$UNAME_MACHINE"-sni-sysv4
else
echo ns32k-sni-sysv
fi
@@ -1197,23 +1222,23 @@ EOF
exit ;;
i*86:VOS:*:*)
# From Paul.Green@stratus.com.
- echo ${UNAME_MACHINE}-stratus-vos
+ echo "$UNAME_MACHINE"-stratus-vos
exit ;;
*:VOS:*:*)
# From Paul.Green@stratus.com.
echo hppa1.1-stratus-vos
exit ;;
mc68*:A/UX:*:*)
- echo m68k-apple-aux${UNAME_RELEASE}
+ echo m68k-apple-aux"$UNAME_RELEASE"
exit ;;
news*:NEWS-OS:6*:*)
echo mips-sony-newsos6
exit ;;
R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
if [ -d /usr/nec ]; then
- echo mips-nec-sysv${UNAME_RELEASE}
+ echo mips-nec-sysv"$UNAME_RELEASE"
else
- echo mips-unknown-sysv${UNAME_RELEASE}
+ echo mips-unknown-sysv"$UNAME_RELEASE"
fi
exit ;;
BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
@@ -1232,46 +1257,56 @@ EOF
echo x86_64-unknown-haiku
exit ;;
SX-4:SUPER-UX:*:*)
- echo sx4-nec-superux${UNAME_RELEASE}
+ echo sx4-nec-superux"$UNAME_RELEASE"
exit ;;
SX-5:SUPER-UX:*:*)
- echo sx5-nec-superux${UNAME_RELEASE}
+ echo sx5-nec-superux"$UNAME_RELEASE"
exit ;;
SX-6:SUPER-UX:*:*)
- echo sx6-nec-superux${UNAME_RELEASE}
+ echo sx6-nec-superux"$UNAME_RELEASE"
exit ;;
SX-7:SUPER-UX:*:*)
- echo sx7-nec-superux${UNAME_RELEASE}
+ echo sx7-nec-superux"$UNAME_RELEASE"
exit ;;
SX-8:SUPER-UX:*:*)
- echo sx8-nec-superux${UNAME_RELEASE}
+ echo sx8-nec-superux"$UNAME_RELEASE"
exit ;;
SX-8R:SUPER-UX:*:*)
- echo sx8r-nec-superux${UNAME_RELEASE}
+ echo sx8r-nec-superux"$UNAME_RELEASE"
+ exit ;;
+ SX-ACE:SUPER-UX:*:*)
+ echo sxace-nec-superux"$UNAME_RELEASE"
exit ;;
Power*:Rhapsody:*:*)
- echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ echo powerpc-apple-rhapsody"$UNAME_RELEASE"
exit ;;
*:Rhapsody:*:*)
- echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+ echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE"
exit ;;
*:Darwin:*:*)
UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
- eval $set_cc_for_build
+ eval "$set_cc_for_build"
if test "$UNAME_PROCESSOR" = unknown ; then
UNAME_PROCESSOR=powerpc
fi
- if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
- if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if test "`echo "$UNAME_RELEASE" | sed -e 's/\..*//'`" -le 10 ; then
+ if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
- (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
- grep IS_64BIT_ARCH >/dev/null
+ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
then
case $UNAME_PROCESSOR in
i386) UNAME_PROCESSOR=x86_64 ;;
powerpc) UNAME_PROCESSOR=powerpc64 ;;
esac
fi
+ # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc
+ if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \
+ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_PPC >/dev/null
+ then
+ UNAME_PROCESSOR=powerpc
+ fi
fi
elif test "$UNAME_PROCESSOR" = i386 ; then
# Avoid executing cc on OS X 10.9, as it ships with a stub
@@ -1282,27 +1317,33 @@ EOF
# that Apple uses in portable devices.
UNAME_PROCESSOR=x86_64
fi
- echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+ echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE"
exit ;;
*:procnto*:*:* | *:QNX:[0123456789]*:*)
UNAME_PROCESSOR=`uname -p`
- if test "$UNAME_PROCESSOR" = "x86"; then
+ if test "$UNAME_PROCESSOR" = x86; then
UNAME_PROCESSOR=i386
UNAME_MACHINE=pc
fi
- echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+ echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE"
exit ;;
*:QNX:*:4*)
echo i386-pc-qnx
exit ;;
- NEO-?:NONSTOP_KERNEL:*:*)
- echo neo-tandem-nsk${UNAME_RELEASE}
+ NEO-*:NONSTOP_KERNEL:*:*)
+ echo neo-tandem-nsk"$UNAME_RELEASE"
exit ;;
NSE-*:NONSTOP_KERNEL:*:*)
- echo nse-tandem-nsk${UNAME_RELEASE}
+ echo nse-tandem-nsk"$UNAME_RELEASE"
+ exit ;;
+ NSR-*:NONSTOP_KERNEL:*:*)
+ echo nsr-tandem-nsk"$UNAME_RELEASE"
exit ;;
- NSR-?:NONSTOP_KERNEL:*:*)
- echo nsr-tandem-nsk${UNAME_RELEASE}
+ NSV-*:NONSTOP_KERNEL:*:*)
+ echo nsv-tandem-nsk"$UNAME_RELEASE"
+ exit ;;
+ NSX-*:NONSTOP_KERNEL:*:*)
+ echo nsx-tandem-nsk"$UNAME_RELEASE"
exit ;;
*:NonStop-UX:*:*)
echo mips-compaq-nonstopux
@@ -1311,18 +1352,18 @@ EOF
echo bs2000-siemens-sysv
exit ;;
DS/*:UNIX_System_V:*:*)
- echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+ echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE"
exit ;;
*:Plan9:*:*)
# "uname -m" is not consistent, so use $cputype instead. 386
# is converted to i386 for consistency with other x86
# operating systems.
- if test "$cputype" = "386"; then
+ if test "$cputype" = 386; then
UNAME_MACHINE=i386
else
UNAME_MACHINE="$cputype"
fi
- echo ${UNAME_MACHINE}-unknown-plan9
+ echo "$UNAME_MACHINE"-unknown-plan9
exit ;;
*:TOPS-10:*:*)
echo pdp10-unknown-tops10
@@ -1343,14 +1384,14 @@ EOF
echo pdp10-unknown-its
exit ;;
SEI:*:*:SEIUX)
- echo mips-sei-seiux${UNAME_RELEASE}
+ echo mips-sei-seiux"$UNAME_RELEASE"
exit ;;
*:DragonFly:*:*)
- echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`"
exit ;;
*:*VMS:*:*)
UNAME_MACHINE=`(uname -p) 2>/dev/null`
- case "${UNAME_MACHINE}" in
+ case "$UNAME_MACHINE" in
A*) echo alpha-dec-vms ; exit ;;
I*) echo ia64-dec-vms ; exit ;;
V*) echo vax-dec-vms ; exit ;;
@@ -1359,34 +1400,48 @@ EOF
echo i386-pc-xenix
exit ;;
i*86:skyos:*:*)
- echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+ echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`"
exit ;;
i*86:rdos:*:*)
- echo ${UNAME_MACHINE}-pc-rdos
+ echo "$UNAME_MACHINE"-pc-rdos
exit ;;
i*86:AROS:*:*)
- echo ${UNAME_MACHINE}-pc-aros
+ echo "$UNAME_MACHINE"-pc-aros
exit ;;
x86_64:VMkernel:*:*)
- echo ${UNAME_MACHINE}-unknown-esx
+ echo "$UNAME_MACHINE"-unknown-esx
+ exit ;;
+ amd64:Isilon\ OneFS:*:*)
+ echo x86_64-unknown-onefs
exit ;;
esac
+echo "$0: unable to guess system type" >&2
+
+case "$UNAME_MACHINE:$UNAME_SYSTEM" in
+ mips:Linux | mips64:Linux)
+ # If we got here on MIPS GNU/Linux, output extra information.
+ cat >&2 <<EOF
+
+NOTE: MIPS GNU/Linux systems require a C compiler to fully recognize
+the system type. Please install a C compiler and try again.
+EOF
+ ;;
+esac
+
cat >&2 <<EOF
-$0: unable to guess system type
-This script, last modified $timestamp, has failed to recognize
-the operating system you are using. It is advised that you
-download the most up to date version of the config scripts from
+This script (version $timestamp), has failed to recognize the
+operating system you are using. If your script is old, overwrite *all*
+copies of config.guess and config.sub with the latest versions from:
- http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+ https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
and
- http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+ https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
-If the version you run ($0) is already up to date, please
-send the following data and any information you think might be
-pertinent to <config-patches@gnu.org> in order to provide the needed
-information to handle your system.
+If $0 has already been updated, send the following data and any
+information you think might be pertinent to config-patches@gnu.org to
+provide the necessary information to handle your system.
config.guess timestamp = $timestamp
@@ -1405,16 +1460,16 @@ hostinfo = `(hostinfo) 2>/dev/null`
/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
-UNAME_MACHINE = ${UNAME_MACHINE}
-UNAME_RELEASE = ${UNAME_RELEASE}
-UNAME_SYSTEM = ${UNAME_SYSTEM}
-UNAME_VERSION = ${UNAME_VERSION}
+UNAME_MACHINE = "$UNAME_MACHINE"
+UNAME_RELEASE = "$UNAME_RELEASE"
+UNAME_SYSTEM = "$UNAME_SYSTEM"
+UNAME_VERSION = "$UNAME_VERSION"
EOF
exit 1
# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "timestamp='"
# time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'"
diff --git a/autosetup/config.sub b/autosetup/autosetup-config.sub
index 7ffe373..9ccf09a 100755
--- a/autosetup/config.sub
+++ b/autosetup/autosetup-config.sub
@@ -1,8 +1,8 @@
#! /bin/sh
# Configuration validation subroutine script.
-# Copyright 1992-2014 Free Software Foundation, Inc.
+# Copyright 1992-2018 Free Software Foundation, Inc.
-timestamp='2014-12-03'
+timestamp='2018-03-08'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -15,7 +15,7 @@ timestamp='2014-12-03'
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program; if not, see <http://www.gnu.org/licenses/>.
+# along with this program; if not, see <https://www.gnu.org/licenses/>.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@@ -33,7 +33,7 @@ timestamp='2014-12-03'
# Otherwise, we print the canonical config type on stdout and succeed.
# You can get the latest version of this script from:
-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
# This file is supposed to be the same for all GNU packages
# and recognize all the CPU types, system types and aliases
@@ -53,12 +53,11 @@ timestamp='2014-12-03'
me=`echo "$0" | sed -e 's,.*/,,'`
usage="\
-Usage: $0 [OPTION] CPU-MFR-OPSYS
- $0 [OPTION] ALIAS
+Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS
Canonicalize a configuration name.
-Operation modes:
+Options:
-h, --help print this help, then exit
-t, --time-stamp print date of last modification, then exit
-v, --version print version number, then exit
@@ -68,7 +67,7 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
-Copyright 1992-2014 Free Software Foundation, Inc.
+Copyright 1992-2018 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."
@@ -95,7 +94,7 @@ while test $# -gt 0 ; do
*local*)
# First pass through any local machine types.
- echo $1
+ echo "$1"
exit ;;
* )
@@ -113,24 +112,24 @@ esac
# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
# Here we must recognize all the valid KERNEL-OS combinations.
-maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+maybe_os=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
- knetbsd*-gnu* | netbsd*-gnu* | \
- kopensolaris*-gnu* | \
+ knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
+ kopensolaris*-gnu* | cloudabi*-eabi* | \
storm-chaos* | os2-emx* | rtmk-nova*)
os=-$maybe_os
- basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
android-linux)
os=-linux-android
- basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
+ basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
;;
*)
- basic_machine=`echo $1 | sed 's/-[^-]*$//'`
- if [ $basic_machine != $1 ]
- then os=`echo $1 | sed 's/.*-/-/'`
+ basic_machine=`echo "$1" | sed 's/-[^-]*$//'`
+ if [ "$basic_machine" != "$1" ]
+ then os=`echo "$1" | sed 's/.*-/-/'`
else os=; fi
;;
esac
@@ -179,44 +178,44 @@ case $os in
;;
-sco6)
os=-sco5v6
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
;;
-sco5)
os=-sco3.2v5
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
;;
-sco4)
os=-sco3.2v4
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
;;
-sco3.2.[4-9]*)
os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
;;
-sco3.2v[4-9]*)
# Don't forget version if it is 3.2v4 or newer.
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
;;
-sco5v6*)
# Don't forget version if it is 3.2v4 or newer.
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
;;
-sco*)
os=-sco3.2v2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
;;
-udk*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
;;
-isc)
os=-isc2.2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
;;
-clix*)
basic_machine=clipper-intergraph
;;
-isc*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
;;
-lynx*178)
os=-lynxos178
@@ -228,10 +227,7 @@ case $os in
os=-lynxos
;;
-ptx*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
- ;;
- -windowsnt*)
- os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ basic_machine=`echo "$1" | sed -e 's/86-.*/86-sequent/'`
;;
-psos*)
os=-psos
@@ -255,15 +251,16 @@ case $basic_machine in
| arc | arceb \
| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
| avr | avr32 \
+ | ba \
| be32 | be64 \
| bfin \
| c4x | c8051 | clipper \
| d10v | d30v | dlx | dsp16xx \
- | epiphany \
- | fido | fr30 | frv \
+ | e2k | epiphany \
+ | fido | fr30 | frv | ft32 \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| hexagon \
- | i370 | i860 | i960 | ia64 \
+ | i370 | i860 | i960 | ia16 | ia64 \
| ip2k | iq2000 \
| k1om \
| le32 | le64 \
@@ -299,13 +296,14 @@ case $basic_machine in
| nios | nios2 | nios2eb | nios2el \
| ns16k | ns32k \
| open8 | or1k | or1knd | or32 \
- | pdp10 | pdp11 | pj | pjl \
+ | pdp10 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle \
+ | pru \
| pyramid \
| riscv32 | riscv64 \
| rl78 | rx \
| score \
- | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
| sh64 | sh64le \
| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
@@ -314,7 +312,7 @@ case $basic_machine in
| ubicom32 \
| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
| visium \
- | we32k \
+ | wasm32 \
| x86 | xc16x | xstormy16 | xtensa \
| z8k | z80)
basic_machine=$basic_machine-unknown
@@ -335,7 +333,7 @@ case $basic_machine in
basic_machine=$basic_machine-unknown
os=-none
;;
- m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65)
;;
ms1)
basic_machine=mt-unknown
@@ -364,7 +362,7 @@ case $basic_machine in
;;
# Object if more than one company name word.
*-*-*)
- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2
exit 1
;;
# Recognize the basic CPU types with company name.
@@ -376,17 +374,18 @@ case $basic_machine in
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
| avr-* | avr32-* \
+ | ba-* \
| be32-* | be64-* \
| bfin-* | bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* \
| c8051-* | clipper-* | craynv-* | cydra-* \
| d10v-* | d30v-* | dlx-* \
- | elxsi-* \
+ | e2k-* | elxsi-* \
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| hexagon-* \
- | i*86-* | i860-* | i960-* | ia64-* \
+ | i*86-* | i860-* | i960-* | ia16-* | ia64-* \
| ip2k-* | iq2000-* \
| k1om-* \
| le32-* | le64-* \
@@ -427,13 +426,15 @@ case $basic_machine in
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+ | pru-* \
| pyramid-* \
+ | riscv32-* | riscv64-* \
| rl78-* | romp-* | rs6000-* | rx-* \
| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
| sparclite-* \
- | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
+ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \
| tahoe-* \
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
| tile*-* \
@@ -442,6 +443,7 @@ case $basic_machine in
| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
| vax-* \
| visium-* \
+ | wasm32-* \
| we32k-* \
| x86-* | x86_64-* | xc16x-* | xps100-* \
| xstormy16-* | xtensa*-* \
@@ -455,7 +457,7 @@ case $basic_machine in
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
386bsd)
- basic_machine=i386-unknown
+ basic_machine=i386-pc
os=-bsd
;;
3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
@@ -489,7 +491,7 @@ case $basic_machine in
basic_machine=x86_64-pc
;;
amd64-*)
- basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ basic_machine=x86_64-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;;
amdahl)
basic_machine=580-amdahl
@@ -518,6 +520,9 @@ case $basic_machine in
basic_machine=i386-pc
os=-aros
;;
+ asmjs)
+ basic_machine=asmjs-unknown
+ ;;
aux)
basic_machine=m68k-apple
os=-aux
@@ -531,7 +536,7 @@ case $basic_machine in
os=-linux
;;
blackfin-*)
- basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+ basic_machine=bfin-`echo "$basic_machine" | sed 's/^[^-]*-//'`
os=-linux
;;
bluegene*)
@@ -539,13 +544,13 @@ case $basic_machine in
os=-cnk
;;
c54x-*)
- basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ basic_machine=tic54x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;;
c55x-*)
- basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ basic_machine=tic55x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;;
c6x-*)
- basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ basic_machine=tic6x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;;
c90)
basic_machine=c90-cray
@@ -634,10 +639,18 @@ case $basic_machine in
basic_machine=rs6000-bull
os=-bosx
;;
- dpx2* | dpx2*-bull)
+ dpx2*)
basic_machine=m68k-bull
os=-sysv3
;;
+ e500v[12])
+ basic_machine=powerpc-unknown
+ os=$os"spe"
+ ;;
+ e500v[12]-*)
+ basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ os=$os"spe"
+ ;;
ebmon29k)
basic_machine=a29k-amd
os=-ebmon
@@ -727,9 +740,6 @@ case $basic_machine in
hp9k8[0-9][0-9] | hp8[0-9][0-9])
basic_machine=hppa1.0-hp
;;
- hppa-next)
- os=-nextstep3
- ;;
hppaosf)
basic_machine=hppa1.1-hp
os=-osf
@@ -742,26 +752,26 @@ case $basic_machine in
basic_machine=i370-ibm
;;
i*86v32)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
os=-sysv32
;;
i*86v4*)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
os=-sysv4
;;
i*86v)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
os=-sysv
;;
i*86sol2)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
os=-solaris2
;;
i386mach)
basic_machine=i386-mach
os=-mach
;;
- i386-vsta | vsta)
+ vsta)
basic_machine=i386-unknown
os=-vsta
;;
@@ -780,19 +790,16 @@ case $basic_machine in
os=-sysv
;;
leon-*|leon[3-9]-*)
- basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
+ basic_machine=sparc-`echo "$basic_machine" | sed 's/-.*//'`
;;
m68knommu)
basic_machine=m68k-unknown
os=-linux
;;
m68knommu-*)
- basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+ basic_machine=m68k-`echo "$basic_machine" | sed 's/^[^-]*-//'`
os=-linux
;;
- m88k-omron*)
- basic_machine=m88k-omron
- ;;
magnum | m3230)
basic_machine=mips-mips
os=-sysv
@@ -824,10 +831,10 @@ case $basic_machine in
os=-mint
;;
mips3*-*)
- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+ basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`
;;
mips3*)
- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+ basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`-unknown
;;
monitor)
basic_machine=m68k-rom68k
@@ -846,7 +853,7 @@ case $basic_machine in
os=-msdos
;;
ms1-*)
- basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+ basic_machine=`echo "$basic_machine" | sed -e 's/ms1-/mt-/'`
;;
msys)
basic_machine=i686-pc
@@ -888,7 +895,7 @@ case $basic_machine in
basic_machine=v70-nec
os=-sysv
;;
- next | m*-next )
+ next | m*-next)
basic_machine=m68k-next
case $os in
-nextstep* )
@@ -933,6 +940,12 @@ case $basic_machine in
nsr-tandem)
basic_machine=nsr-tandem
;;
+ nsv-tandem)
+ basic_machine=nsv-tandem
+ ;;
+ nsx-tandem)
+ basic_machine=nsx-tandem
+ ;;
op50n-* | op60c-*)
basic_machine=hppa1.1-oki
os=-proelf
@@ -965,7 +978,7 @@ case $basic_machine in
os=-linux
;;
parisc-*)
- basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+ basic_machine=hppa-`echo "$basic_machine" | sed 's/^[^-]*-//'`
os=-linux
;;
pbd)
@@ -981,7 +994,7 @@ case $basic_machine in
basic_machine=i386-pc
;;
pc98-*)
- basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+ basic_machine=i386-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;;
pentium | p5 | k5 | k6 | nexgen | viac3)
basic_machine=i586-pc
@@ -996,16 +1009,16 @@ case $basic_machine in
basic_machine=i786-pc
;;
pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
- basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+ basic_machine=i586-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;;
pentiumpro-* | p6-* | 6x86-* | athlon-*)
- basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;;
pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
- basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;;
pentium4-*)
- basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+ basic_machine=i786-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;;
pn)
basic_machine=pn-gould
@@ -1015,23 +1028,23 @@ case $basic_machine in
ppc | ppcbe) basic_machine=powerpc-unknown
;;
ppc-* | ppcbe-*)
- basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;;
- ppcle | powerpclittle | ppc-le | powerpc-little)
+ ppcle | powerpclittle)
basic_machine=powerpcle-unknown
;;
ppcle-* | powerpclittle-*)
- basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ basic_machine=powerpcle-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;;
ppc64) basic_machine=powerpc64-unknown
;;
- ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ppc64-*) basic_machine=powerpc64-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;;
- ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+ ppc64le | powerpc64little)
basic_machine=powerpc64le-unknown
;;
ppc64le-* | powerpc64little-*)
- basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+ basic_machine=powerpc64le-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;;
ps2)
basic_machine=i386-ibm
@@ -1085,17 +1098,10 @@ case $basic_machine in
sequent)
basic_machine=i386-sequent
;;
- sh)
- basic_machine=sh-hitachi
- os=-hms
- ;;
sh5el)
basic_machine=sh5le-unknown
;;
- sh64)
- basic_machine=sh64-unknown
- ;;
- sparclite-wrs | simso-wrs)
+ simso-wrs)
basic_machine=sparclite-wrs
os=-vxworks
;;
@@ -1114,7 +1120,7 @@ case $basic_machine in
os=-sysv4
;;
strongarm-* | thumb-*)
- basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+ basic_machine=arm-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;;
sun2)
basic_machine=m68000-sun
@@ -1236,6 +1242,9 @@ case $basic_machine in
basic_machine=hppa1.1-winbond
os=-proelf
;;
+ x64)
+ basic_machine=x86_64-pc
+ ;;
xbox)
basic_machine=i686-pc
os=-mingw32
@@ -1244,20 +1253,12 @@ case $basic_machine in
basic_machine=xps100-honeywell
;;
xscale-* | xscalee[bl]-*)
- basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+ basic_machine=`echo "$basic_machine" | sed 's/^xscale/arm/'`
;;
ymp)
basic_machine=ymp-cray
os=-unicos
;;
- z8k-*-coff)
- basic_machine=z8k-unknown
- os=-sim
- ;;
- z80-*-coff)
- basic_machine=z80-unknown
- os=-sim
- ;;
none)
basic_machine=none-none
os=-none
@@ -1286,10 +1287,6 @@ case $basic_machine in
vax)
basic_machine=vax-dec
;;
- pdp10)
- # there are many clones, so DEC is not a safe bet
- basic_machine=pdp10-unknown
- ;;
pdp11)
basic_machine=pdp11-dec
;;
@@ -1299,9 +1296,6 @@ case $basic_machine in
sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
basic_machine=sh-unknown
;;
- sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
- basic_machine=sparc-sun
- ;;
cydra)
basic_machine=cydra-cydrome
;;
@@ -1321,7 +1315,7 @@ case $basic_machine in
# Make sure to match an already-canonicalized machine name.
;;
*)
- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2
exit 1
;;
esac
@@ -1329,10 +1323,10 @@ esac
# Here we canonicalize certain aliases for manufacturers.
case $basic_machine in
*-digital*)
- basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+ basic_machine=`echo "$basic_machine" | sed 's/digital.*/dec/'`
;;
*-commodore*)
- basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+ basic_machine=`echo "$basic_machine" | sed 's/commodore.*/cbm/'`
;;
*)
;;
@@ -1343,8 +1337,8 @@ esac
if [ x"$os" != x"" ]
then
case $os in
- # First match some system type aliases
- # that might get confused with valid system types.
+ # First match some system type aliases that might get confused
+ # with valid system types.
# -solaris* is a basic system type, with this one exception.
-auroraux)
os=-auroraux
@@ -1355,45 +1349,48 @@ case $os in
-solaris)
os=-solaris2
;;
- -svr4*)
- os=-sysv4
- ;;
-unixware*)
os=-sysv4.2uw
;;
-gnu/linux*)
os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
;;
- # First accept the basic system types.
+ # es1800 is here to avoid being matched by es* (a different OS)
+ -es1800*)
+ os=-ose
+ ;;
+ # Now accept the basic system types.
# The portable systems comes first.
- # Each alternative MUST END IN A *, to match a version number.
+ # Each alternative MUST end in a * to match a version number.
# -sysv* is not here because it comes later, after sysvr4.
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
| -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
| -sym* | -kopensolaris* | -plan9* \
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
- | -aos* | -aros* \
+ | -aos* | -aros* | -cloudabi* | -sortix* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
- | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
- | -bitrig* | -openbsd* | -solidbsd* \
+ | -hiux* | -knetbsd* | -mirbsd* | -netbsd* \
+ | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
- | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
- | -chorusos* | -chorusrdb* | -cegcc* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* | -hcos* \
+ | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \
| -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
- | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
+ | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
| -linux-newlib* | -linux-musl* | -linux-uclibc* \
| -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
- | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
- | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+ | -morphos* | -superux* | -rtmk* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
- | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*)
+ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
+ | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox* | -bme* \
+ | -midnightbsd*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
@@ -1410,12 +1407,12 @@ case $os in
-nto*)
os=`echo $os | sed -e 's|nto|nto-qnx|'`
;;
- -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
- | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+ -sim | -xray | -os68k* | -v88r* \
+ | -windows* | -osx | -abug | -netware* | -os9* \
| -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
;;
-mac*)
- os=`echo $os | sed -e 's|mac|macos|'`
+ os=`echo "$os" | sed -e 's|mac|macos|'`
;;
-linux-dietlibc)
os=-linux-dietlibc
@@ -1424,10 +1421,10 @@ case $os in
os=`echo $os | sed -e 's|linux|linux-gnu|'`
;;
-sunos5*)
- os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ os=`echo "$os" | sed -e 's|sunos5|solaris2|'`
;;
-sunos6*)
- os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ os=`echo "$os" | sed -e 's|sunos6|solaris3|'`
;;
-opened*)
os=-openedition
@@ -1438,12 +1435,6 @@ case $os in
-wince*)
os=-wince
;;
- -osfrose*)
- os=-osfrose
- ;;
- -osf*)
- os=-osf
- ;;
-utek*)
os=-bsd
;;
@@ -1468,7 +1459,7 @@ case $os in
-nova*)
os=-rtmk-nova
;;
- -ns2 )
+ -ns2)
os=-nextstep2
;;
-nsk*)
@@ -1490,7 +1481,7 @@ case $os in
-oss*)
os=-sysv3
;;
- -svr4)
+ -svr4*)
os=-sysv4
;;
-svr3)
@@ -1505,32 +1496,38 @@ case $os in
-ose*)
os=-ose
;;
- -es1800*)
- os=-ose
- ;;
- -xenix)
- os=-xenix
- ;;
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
os=-mint
;;
- -aros*)
- os=-aros
- ;;
-zvmoe)
os=-zvmoe
;;
-dicos*)
os=-dicos
;;
+ -pikeos*)
+ # Until real need of OS specific support for
+ # particular features comes up, bare metal
+ # configurations are quite functional.
+ case $basic_machine in
+ arm*)
+ os=-eabi
+ ;;
+ *)
+ os=-elf
+ ;;
+ esac
+ ;;
-nacl*)
;;
+ -ios)
+ ;;
-none)
;;
*)
# Get rid of the `-' at the beginning of $os.
os=`echo $os | sed 's/[^-]*-//'`
- echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ echo Invalid configuration \`"$1"\': system \`"$os"\' not recognized 1>&2
exit 1
;;
esac
@@ -1620,12 +1617,12 @@ case $basic_machine in
sparc-* | *-sun)
os=-sunos4.1.1
;;
+ pru-*)
+ os=-elf
+ ;;
*-be)
os=-beos
;;
- *-haiku)
- os=-haiku
- ;;
*-ibm)
os=-aix
;;
@@ -1665,7 +1662,7 @@ case $basic_machine in
m88k-omron*)
os=-luna
;;
- *-next )
+ *-next)
os=-nextstep
;;
*-sequent)
@@ -1680,9 +1677,6 @@ case $basic_machine in
i370-*)
os=-mvs
;;
- *-next)
- os=-nextstep3
- ;;
*-gould)
os=-sysv
;;
@@ -1792,15 +1786,15 @@ case $basic_machine in
vendor=stratus
;;
esac
- basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ basic_machine=`echo "$basic_machine" | sed "s/unknown/$vendor/"`
;;
esac
-echo $basic_machine$os
+echo "$basic_machine$os"
exit
# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "timestamp='"
# time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'"
diff --git a/autosetup/find-tclsh b/autosetup/autosetup-find-tclsh
index be7cf3d..dfe70f8 100755
--- a/autosetup/find-tclsh
+++ b/autosetup/autosetup-find-tclsh
@@ -1,16 +1,17 @@
#!/bin/sh
# Looks for a suitable tclsh or jimsh in the PATH
# If not found, builds a bootstrap jimsh from source
+# Prefer $autosetup_tclsh if is set in the environment
d=`dirname "$0"`
-{ "$d/jimsh0" "$d/test-tclsh"; } 2>/dev/null && exit 0
+{ "$d/jimsh0" "$d/autosetup-test-tclsh"; } 2>/dev/null && exit 0
PATH="$PATH:$d"; export PATH
-for tclsh in jimsh tclsh tclsh8.5 tclsh8.6; do
- { $tclsh "$d/test-tclsh"; } 2>/dev/null && exit 0
+for tclsh in $autosetup_tclsh jimsh tclsh tclsh8.5 tclsh8.6; do
+ { $tclsh "$d/autosetup-test-tclsh"; } 2>/dev/null && exit 0
done
echo 1>&2 "No installed jimsh or tclsh, building local bootstrap jimsh0"
for cc in ${CC_FOR_BUILD:-cc} gcc; do
{ $cc -o "$d/jimsh0" "$d/jimsh0.c"; } 2>/dev/null || continue
- "$d/jimsh0" "$d/test-tclsh" && exit 0
+ "$d/jimsh0" "$d/autosetup-test-tclsh" && exit 0
done
echo 1>&2 "No working C compiler found. Tried ${CC_FOR_BUILD:-cc} and gcc."
echo false
diff --git a/autosetup/test-tclsh b/autosetup/autosetup-test-tclsh
index 75126d2..75126d2 100644
--- a/autosetup/test-tclsh
+++ b/autosetup/autosetup-test-tclsh
diff --git a/autosetup/cc-db.tcl b/autosetup/cc-db.tcl
index c67fc6e..5dadbaf 100644
--- a/autosetup/cc-db.tcl
+++ b/autosetup/cc-db.tcl
@@ -3,8 +3,8 @@
# @synopsis:
#
-# The 'cc-db' module provides a knowledge based of system idiosyncrasies
-# In general, this module can always be included
+# The 'cc-db' module provides a knowledge-base of system idiosyncrasies.
+# In general, this module can always be included.
use cc
diff --git a/autosetup/cc-lib.tcl b/autosetup/cc-lib.tcl
index 4df5130..80ee078 100644
--- a/autosetup/cc-lib.tcl
+++ b/autosetup/cc-lib.tcl
@@ -11,8 +11,8 @@ module-options {}
# @cc-check-lfs
#
-# The equivalent of the AC_SYS_LARGEFILE macro
-#
+# The equivalent of the 'AC_SYS_LARGEFILE' macro.
+#
# defines 'HAVE_LFS' if LFS is available,
# and defines '_FILE_OFFSET_BITS=64' if necessary
#
@@ -37,8 +37,8 @@ proc cc-check-lfs {} {
# @cc-check-endian
#
-# The equivalent of the AC_C_BIGENDIAN macro
-#
+# The equivalent of the 'AC_C_BIGENDIAN' macro.
+#
# defines 'HAVE_BIG_ENDIAN' if endian is known to be big,
# or 'HAVE_LITTLE_ENDIAN' if endian is known to be little.
#
@@ -82,34 +82,34 @@ proc cc-check-endian {} {
# names prefixed with 'HAVE_CFLAG' and 'HAVE_CXXFLAG' respectively, and
# appends working flags to '-cflags' and 'CFLAGS' or 'CXXFLAGS'.
proc cc-check-flags {args} {
- set result 1
- array set opts [cc-get-settings]
- switch -exact -- $opts(-lang) {
- c++ {
- set lang C++
- set prefix CXXFLAG
- }
- c {
- set lang C
- set prefix CFLAG
- }
- default {
- autosetup-error "cc-check-flags failed with unknown language: $opts(-lang)"
- }
- }
- foreach flag $args {
- msg-checking "Checking whether the $lang compiler accepts $flag..."
- if {[cctest -cflags $flag]} {
- msg-result yes
- define-feature $prefix$flag
- cc-with [list -cflags [list $flag]]
- define-append ${prefix}S $flag
- } else {
- msg-result no
- set result 0
- }
- }
- return $result
+ set result 1
+ array set opts [cc-get-settings]
+ switch -exact -- $opts(-lang) {
+ c++ {
+ set lang C++
+ set prefix CXXFLAG
+ }
+ c {
+ set lang C
+ set prefix CFLAG
+ }
+ default {
+ autosetup-error "cc-check-flags failed with unknown language: $opts(-lang)"
+ }
+ }
+ foreach flag $args {
+ msg-checking "Checking whether the $lang compiler accepts $flag..."
+ if {[cctest -cflags $flag]} {
+ msg-result yes
+ define-feature $prefix$flag
+ cc-with [list -cflags [list $flag]]
+ define-append ${prefix}S $flag
+ } else {
+ msg-result no
+ set result 0
+ }
+ }
+ return $result
}
# @cc-check-standards ver ?...?
@@ -118,26 +118,24 @@ proc cc-check-flags {args} {
# options, and appends the first working one to '-cflags' and 'CFLAGS' or
# 'CXXFLAGS'.
proc cc-check-standards {args} {
- array set opts [cc-get-settings]
- foreach std $args {
- if {[cc-check-flags -std=$std]} {
- return $std
- }
- }
- return ""
+ array set opts [cc-get-settings]
+ foreach std $args {
+ if {[cc-check-flags -std=$std]} {
+ return $std
+ }
+ }
+ return ""
}
# Checks whether $keyword is usable as alignof
proc cctest_alignof {keyword} {
- msg-checking "Checking for $keyword..."
- if {[cctest -code [subst -nobackslashes {
- printf("minimum alignment is %d == %d\n", ${keyword}(char), ${keyword}('x'));
- }]]} then {
- msg-result ok
- define-feature $keyword
- } else {
- msg-result "not found"
- }
+ msg-checking "Checking for $keyword..."
+ if {[cctest -code "int x = ${keyword}(char), y = ${keyword}('x');"]} then {
+ msg-result ok
+ define-feature $keyword
+ } else {
+ msg-result "not found"
+ }
}
# @cc-check-c11
@@ -145,17 +143,47 @@ proc cctest_alignof {keyword} {
# Checks for several C11/C++11 extensions and their alternatives. Currently
# checks for '_Static_assert', '_Alignof', '__alignof__', '__alignof'.
proc cc-check-c11 {} {
- msg-checking "Checking for _Static_assert..."
- if {[cctest -code {
- _Static_assert(1, "static assertions are available");
- }]} then {
- msg-result ok
- define-feature _Static_assert
- } else {
- msg-result "not found"
- }
+ msg-checking "Checking for _Static_assert..."
+ if {[cctest -code {
+ _Static_assert(1, "static assertions are available");
+ }]} then {
+ msg-result ok
+ define-feature _Static_assert
+ } else {
+ msg-result "not found"
+ }
+
+ cctest_alignof _Alignof
+ cctest_alignof __alignof__
+ cctest_alignof __alignof
+}
- cctest_alignof _Alignof
- cctest_alignof __alignof__
- cctest_alignof __alignof
+# @cc-check-alloca
+#
+# The equivalent of the 'AC_FUNC_ALLOCA' macro.
+#
+# Checks for the existence of 'alloca'
+# defines 'HAVE_ALLOCA' and returns 1 if it exists.
+proc cc-check-alloca {} {
+ cc-check-some-feature alloca {
+ cctest -includes alloca.h -code { alloca (2 * sizeof (int)); }
+ }
+}
+
+# @cc-signal-return-type
+#
+# The equivalent of the 'AC_TYPE_SIGNAL' macro.
+#
+# defines 'RETSIGTYPE' to 'int' or 'void'.
+proc cc-signal-return-type {} {
+ msg-checking "Checking return type of signal handlers..."
+ cc-with {-includes {sys/types.h signal.h}} {
+ if {[cctest -code {return *(signal (0, 0)) (0) == 1;}]} {
+ set type int
+ } else {
+ set type void
+ }
+ define RETSIGTYPE $type
+ msg-result $type
+ }
}
diff --git a/autosetup/cc-shared.tcl b/autosetup/cc-shared.tcl
index 86e169c..0d6d522 100644
--- a/autosetup/cc-shared.tcl
+++ b/autosetup/cc-shared.tcl
@@ -9,11 +9,13 @@
## SH_CFLAGS Flags to use compiling sources destined for a shared library
## SH_LDFLAGS Flags to use linking (creating) a shared library
## SH_SOPREFIX Prefix to use to set the soname when creating a shared library
+## SH_SOFULLPATH Set to 1 if the shared library soname should include the full install path
## SH_SOEXT Extension for shared libs
## SH_SOEXTVER Format for versioned shared libs - %s = version
## SHOBJ_CFLAGS Flags to use compiling sources destined for a shared object
## SHOBJ_LDFLAGS Flags to use linking a shared object, undefined symbols allowed
## SHOBJ_LDFLAGS_R - as above, but all symbols must be resolved
+## SH_LINKRPATH Format for setting the rpath when linking an executable, %s = path
## SH_LINKFLAGS Flags to use linking an executable which will load shared objects
## LD_LIBRARY_PATH Environment variable which specifies path to shared libraries
## STRIPLIBFLAGS Arguments to strip a dynamic library
@@ -21,11 +23,12 @@
module-options {}
# Defaults: gcc on unix
-define SHOBJ_CFLAGS -fpic
+define SHOBJ_CFLAGS -fPIC
define SHOBJ_LDFLAGS -shared
-define SH_CFLAGS -fpic
+define SH_CFLAGS -fPIC
define SH_LDFLAGS -shared
define SH_LINKFLAGS -rdynamic
+define SH_LINKRPATH "-Wl,-rpath -Wl,%s"
define SH_SOEXT .so
define SH_SOEXTVER .so.%s
define SH_SOPREFIX -Wl,-soname,
@@ -46,6 +49,7 @@ switch -glob -- [get-define host] {
define SH_SOEXT .dylib
define SH_SOEXTVER .%s.dylib
define SH_SOPREFIX -Wl,-install_name,
+ define SH_SOFULLPATH
define LD_LIBRARY_PATH DYLD_LIBRARY_PATH
define STRIPLIBFLAGS -x
}
@@ -54,6 +58,7 @@ switch -glob -- [get-define host] {
define SHOBJ_LDFLAGS -shared
define SH_CFLAGS ""
define SH_LDFLAGS -shared
+ define SH_LINKRPATH ""
define SH_LINKFLAGS ""
define SH_SOEXT .dll
define SH_SOEXTVER .dll
@@ -64,23 +69,19 @@ switch -glob -- [get-define host] {
if {[msg-quiet cc-check-decls __SUNPRO_C]} {
msg-result "Found sun stdio compiler"
# sun stdio compiler
- # XXX: These haven't been fully tested.
+ # XXX: These haven't been fully tested.
define SHOBJ_CFLAGS -KPIC
define SHOBJ_LDFLAGS "-G"
define SH_CFLAGS -KPIC
define SH_LINKFLAGS -Wl,-export-dynamic
define SH_SOPREFIX -Wl,-h,
- } else {
- # sparc has a very small GOT table limit, so use -fPIC
- define SH_CFLAGS -fPIC
- define SHOBJ_CFLAGS -fPIC
}
}
*-*-solaris* {
if {[msg-quiet cc-check-decls __SUNPRO_C]} {
msg-result "Found sun stdio compiler"
# sun stdio compiler
- # XXX: These haven't been fully tested.
+ # XXX: These haven't been fully tested.
define SHOBJ_CFLAGS -KPIC
define SHOBJ_LDFLAGS "-G"
define SH_CFLAGS -KPIC
diff --git a/autosetup/cc.tcl b/autosetup/cc.tcl
index ebd9789..585d259 100644
--- a/autosetup/cc.tcl
+++ b/autosetup/cc.tcl
@@ -4,13 +4,14 @@
# @synopsis:
#
# The 'cc' module supports checking various 'features' of the C or C++
-# compiler/linker environment. Common commands are cc-check-includes,
-# cc-check-types, cc-check-functions, cc-with, make-autoconf-h and make-template.
+# compiler/linker environment. Common commands are 'cc-check-includes',
+# 'cc-check-types', 'cc-check-functions', 'cc-with', 'make-config-header' and 'make-template'.
#
# The following environment variables are used if set:
#
## CC - C compiler
## CXX - C++ compiler
+## CPP - C preprocessor
## CCACHE - Set to "none" to disable automatic use of ccache
## CFLAGS - Additional C compiler flags
## CXXFLAGS - Additional C++ compiler flags
@@ -30,11 +31,6 @@ use system
module-options {}
-# Note that the return code is not meaningful
-proc cc-check-something {name code} {
- uplevel 1 $code
-}
-
# Checks for the existence of the given function by linking
#
proc cctest_function {function} {
@@ -49,7 +45,8 @@ proc cctest_type {type} {
# Checks for the existence of the given type/structure member.
# e.g. "struct stat.st_mtime"
proc cctest_member {struct_member} {
- lassign [split $struct_member .] struct member
+ # split at the first dot
+ regexp {^([^.]+)[.](.*)$} $struct_member -> struct member
cctest -code "static $struct _s; return sizeof(_s.$member);"
}
@@ -69,8 +66,8 @@ proc cctest_decl {name} {
# @cc-check-sizeof type ...
#
# Checks the size of the given types (between 1 and 32, inclusive).
-# Defines a variable with the size determined, or "unknown" otherwise.
-# e.g. for type 'long long', defines SIZEOF_LONG_LONG.
+# Defines a variable with the size determined, or 'unknown' otherwise.
+# e.g. for type 'long long', defines 'SIZEOF_LONG_LONG'.
# Returns the size of the last type.
#
proc cc-check-sizeof {args} {
@@ -110,7 +107,7 @@ proc cc-check-some-feature {list script} {
# @cc-check-includes includes ...
#
-# Checks that the given include files can be used
+# Checks that the given include files can be used.
proc cc-check-includes {args} {
cc-check-some-feature $args {
set with {}
@@ -135,8 +132,8 @@ proc cc-check-includes {args} {
# @cc-include-needs include required ...
#
-# Ensures that when checking for 'include', a check is first
-# made for each 'required' file, and if found, it is #included
+# Ensures that when checking for '$include', a check is first
+# made for each '$required' file, and if found, it is included with '#include'.
proc cc-include-needs {file args} {
foreach depfile $args {
dict set ::autosetup(cc-include-deps) $file $depfile 1
@@ -154,7 +151,7 @@ proc cc-check-types {args} {
# @cc-check-defines define ...
#
-# Checks that the given preprocessor symbol is defined
+# Checks that the given preprocessor symbols are defined.
proc cc-check-defines {args} {
cc-check-some-feature $args {
cctest_define $each
@@ -164,8 +161,8 @@ proc cc-check-defines {args} {
# @cc-check-decls name ...
#
# Checks that each given name is either a preprocessor symbol or rvalue
-# such as an enum. Note that the define used is HAVE_DECL_xxx
-# rather than HAVE_xxx
+# such as an enum. Note that the define used is 'HAVE_DECL_xxx'
+# rather than 'HAVE_xxx'.
proc cc-check-decls {args} {
set ret 1
foreach name $args {
@@ -184,7 +181,7 @@ proc cc-check-decls {args} {
# @cc-check-functions function ...
#
-# Checks that the given functions exist (can be linked)
+# Checks that the given functions exist (can be linked).
proc cc-check-functions {args} {
cc-check-some-feature $args {
cctest_function $each
@@ -194,7 +191,7 @@ proc cc-check-functions {args} {
# @cc-check-members type.member ...
#
# Checks that the given type/structure members exist.
-# A structure member is of the form "struct stat.st_mtime"
+# A structure member is of the form 'struct stat.st_mtime'.
proc cc-check-members {args} {
cc-check-some-feature $args {
cctest_member $each
@@ -208,16 +205,16 @@ proc cc-check-members {args} {
# First checks for no library required, then checks each of the libraries
# in turn.
#
-# If the function is found, the feature is defined and lib_$function is defined
-# to -l$lib where the function was found, or "" if no library required.
-# In addition, -l$lib is added to the LIBS define.
+# If the function is found, the feature is defined and 'lib_$function' is defined
+# to '-l$lib' where the function was found, or "" if no library required.
+# In addition, '-l$lib' is prepended to the 'LIBS' define.
#
# If additional libraries may be needed for linking, they should be specified
-# as $extralibs as "-lotherlib1 -lotherlib2".
-# These libraries are not automatically added to LIBS.
+# with '$extralibs' as '-lotherlib1 -lotherlib2'.
+# These libraries are not automatically added to 'LIBS'.
#
# Returns 1 if found or 0 if not.
-#
+#
proc cc-check-function-in-lib {function libs {otherlibs {}}} {
msg-checking "Checking libs for $function..."
set found 0
@@ -232,7 +229,8 @@ proc cc-check-function-in-lib {function libs {otherlibs {}}} {
if {[cctest_function $function]} {
msg-result -l$lib
define lib_$function -l$lib
- define-append LIBS -l$lib
+ # prepend to LIBS
+ define LIBS "-l$lib [get-define LIBS]"
incr found
break
}
@@ -240,9 +238,8 @@ proc cc-check-function-in-lib {function libs {otherlibs {}}} {
}
}
}
- if {$found} {
- define [feature-define-name $function]
- } else {
+ define-feature $function $found
+ if {!$found} {
msg-result "no"
}
return $found
@@ -253,12 +250,12 @@ proc cc-check-function-in-lib {function libs {otherlibs {}}} {
# Checks for existence of the given compiler tools, taking
# into account any cross compilation prefix.
#
-# For example, when checking for "ar", first AR is checked on the command
-# line and then in the environment. If not found, "${host}-ar" or
-# simply "ar" is assumed depending upon whether cross compiling.
-# The path is searched for this executable, and if found AR is defined
+# For example, when checking for 'ar', first 'AR' is checked on the command
+# line and then in the environment. If not found, '${host}-ar' or
+# simply 'ar' is assumed depending upon whether cross compiling.
+# The path is searched for this executable, and if found 'AR' is defined
# to the executable name.
-# Note that even when cross compiling, the simple "ar" is used as a fallback,
+# Note that even when cross compiling, the simple 'ar' is used as a fallback,
# but a warning is generated. This is necessary for some toolchains.
#
# It is an error if the executable is not found.
@@ -284,10 +281,10 @@ proc cc-check-tools {args} {
#
# Checks for existence of the given executables on the path.
#
-# For example, when checking for "grep", the path is searched for
-# the executable, 'grep', and if found GREP is defined as "grep".
+# For example, when checking for 'grep', the path is searched for
+# the executable, 'grep', and if found 'GREP' is defined as 'grep'.
#
-# If the executable is not found, the variable is defined as false.
+# If the executable is not found, the variable is defined as 'false'.
# Returns 1 if all programs were found, or 0 otherwise.
#
proc cc-check-progs {args} {
@@ -307,6 +304,29 @@ proc cc-check-progs {args} {
expr {!$failed}
}
+# @cc-path-progs prog ...
+#
+# Like cc-check-progs, but sets the define to the full path rather
+# than just the program name.
+#
+proc cc-path-progs {args} {
+ set failed 0
+ foreach prog $args {
+ set PROG [string toupper $prog]
+ msg-checking "Checking for $prog..."
+ set path [find-executable-path $prog]
+ if {$path eq ""} {
+ msg-result no
+ define $PROG false
+ incr failed
+ } else {
+ msg-result $path
+ define $PROG $path
+ }
+ }
+ expr {!$failed}
+}
+
# Adds the given settings to $::autosetup(ccsettings) and
# returns the old settings.
#
@@ -326,14 +346,14 @@ proc cc-add-settings {settings} {
switch -exact -- $name {
-cflags - -includes {
# These are given as lists
- lappend new($name) {*}$value
+ lappend new($name) {*}[list-non-empty $value]
}
-declare {
lappend new($name) $value
}
-libs {
# Note that new libraries are added before previous libraries
- set new($name) [list {*}$value {*}$new($name)]
+ set new($name) [list {*}[list-non-empty $value] {*}$new($name)]
}
-link - -lang - -nooutput {
set new($name) $value
@@ -373,12 +393,12 @@ proc cc-update-settings {args} {
# @cc-with settings ?{ script }?
#
-# Sets the given 'cctest' settings and then runs the tests in 'script'.
-# Note that settings such as -lang replace the current setting, while
-# those such as -includes are appended to the existing setting.
+# Sets the given 'cctest' settings and then runs the tests in '$script'.
+# Note that settings such as '-lang' replace the current setting, while
+# those such as '-includes' are appended to the existing setting.
#
# If no script is given, the settings become the default for the remainder
-# of the auto.def file.
+# of the 'auto.def' file.
#
## cc-with {-lang c++} {
## # This will check with the C++ compiler
@@ -390,7 +410,7 @@ proc cc-update-settings {args} {
## # back to just the C++ compiler
## }
#
-# The -libs setting is special in that newer values are added *before* earlier ones.
+# The '-libs' setting is special in that newer values are added *before* earlier ones.
#
## cc-with {-libs {-lc -lm}} {
## cc-with {-libs -ldl} {
@@ -415,8 +435,8 @@ proc cc-with {settings args} {
}
# @cctest ?settings?
-#
-# Low level C compiler checker. Compiles and or links a small C program
+#
+# Low level C/C++ compiler checker. Compiles and or links a small C program
# according to the arguments and returns 1 if OK, or 0 if not.
#
# Supported settings are:
@@ -432,7 +452,7 @@ proc cc-with {settings args} {
## -sourcefile file Shorthand for -source [readfile [get-define srcdir]/$file]
## -nooutput 1 Treat any compiler output (e.g. a warning) as an error
#
-# Unless -source or -sourcefile is specified, the C program looks like:
+# Unless '-source' or '-sourcefile' is specified, the C program looks like:
#
## #include <firstinclude> /* same for remaining includes in the list */
##
@@ -446,7 +466,6 @@ proc cc-with {settings args} {
# Any failures are recorded in 'config.log'
#
proc cctest {args} {
- set src conftest__.c
set tmp conftest__
# Easiest way to merge in the settings
@@ -488,9 +507,11 @@ proc cctest {args} {
lappend cmdline {*}[get-define CCACHE]
switch -exact -- $opts(-lang) {
c++ {
+ set src conftest__.cpp
lappend cmdline {*}[get-define CXX] {*}[get-define CXXFLAGS]
}
c {
+ set src conftest__.c
lappend cmdline {*}[get-define CC] {*}[get-define CFLAGS]
}
default {
@@ -498,13 +519,17 @@ proc cctest {args} {
}
}
- if {!$opts(-link)} {
+ if {$opts(-link)} {
+ lappend cmdline {*}[get-define LDFLAGS]
+ } else {
set tmp conftest__.o
lappend cmdline -c
}
lappend cmdline {*}$opts(-cflags) {*}[get-define cc-default-debug ""]
-
lappend cmdline $src -o $tmp {*}$opts(-libs)
+ if {$opts(-link)} {
+ lappend cmdline {*}[get-define LIBS]
+ }
# At this point we have the complete command line and the
# complete source to be compiled. Get the result from cache if
@@ -550,7 +575,7 @@ proc cctest {args} {
# @make-autoconf-h outfile ?auto-patterns=HAVE_*? ?bare-patterns=SIZEOF_*?
#
-# Deprecated - see make-config-header
+# Deprecated - see 'make-config-header'
proc make-autoconf-h {file {autopatterns {HAVE_*}} {barepatterns {SIZEOF_* HAVE_DECL_*}}} {
user-notice "*** make-autoconf-h is deprecated -- use make-config-header instead"
make-config-header $file -auto $autopatterns -bare $barepatterns
@@ -559,19 +584,19 @@ proc make-autoconf-h {file {autopatterns {HAVE_*}} {barepatterns {SIZEOF_* HAVE_
# @make-config-header outfile ?-auto patternlist? ?-bare patternlist? ?-none patternlist? ?-str patternlist? ...
#
# Examines all defined variables which match the given patterns
-# and writes an include file, $file, which defines each of these.
+# and writes an include file, '$file', which defines each of these.
# Variables which match '-auto' are output as follows:
-# - defines which have the value "0" are ignored.
+# - defines which have the value '0' are ignored.
# - defines which have integer values are defined as the integer value.
-# - any other value is defined as a string, e.g. "value"
+# - any other value is defined as a string, e.g. '"value"'
# Variables which match '-bare' are defined as-is.
-# Variables which match '-str' are defined as a string, e.g. "value"
+# Variables which match '-str' are defined as a string, e.g. '"value"'
# Variables which match '-none' are omitted.
#
-# Note that order is important. The first pattern which matches is selected
+# Note that order is important. The first pattern that matches is selected.
# Default behaviour is:
#
-# -bare {SIZEOF_* HAVE_DECL_*} -auto HAVE_* -none *
+## -bare {SIZEOF_* HAVE_DECL_*} -auto HAVE_* -none *
#
# If the file would be unchanged, it is not written.
proc make-config-header {file args} {
@@ -674,6 +699,15 @@ if {[get-define CC] eq ""} {
define CCACHE [find-an-executable [get-env CCACHE ccache]]
+# If any of these are set in the environment, propagate them to the AUTOREMAKE commandline
+foreach i {CC CXX CCACHE CPP CFLAGS CXXFLAGS CXXFLAGS LDFLAGS LIBS CROSS CPPFLAGS LINKFLAGS CC_FOR_BUILD LD} {
+ if {[env-is-set $i]} {
+ # Note: If the variable is set on the command line, get-env will return that value
+ # so the command line will continue to override the environment
+ define-append AUTOREMAKE [quote-if-needed $i=[get-env $i ""]]
+ }
+}
+
# Initial cctest settings
cc-store-settings {-cflags {} -includes {} -declare {} -link 0 -lang c -libs {} -code {} -nooutput 0}
set autosetup(cc-include-deps) {}
diff --git a/autosetup/jim-misc.auto b/autosetup/jim-misc.auto
new file mode 100644
index 0000000..cf13592
--- /dev/null
+++ b/autosetup/jim-misc.auto
@@ -0,0 +1,33 @@
+# @cc-check-inline
+#
+# The equivalent of the 'AC_C_INLINE' macro.
+#
+# defines 'HAVE_INLINE' if inline is available,
+# and defines 'inline' to be __inline__ or __inline if necessary
+# or to "" if not available.
+#
+# Returns 1 if 'inline' is available or 0 otherwise
+#
+proc cc-check-inline {} {
+ msg-checking "Checking for inline support..."
+ set ok 0
+ foreach i {inline __inline__ __inline} {
+ if {[cctest -declare "#ifndef __cplusplus\nstatic $i void testfunc__(void);\n#endif"]} {
+ incr ok
+ break
+ }
+ }
+ if {$ok} {
+ if {$i eq "inline"} {
+ msg-result yes
+ } else {
+ msg-result $i
+ define inline $i
+ }
+ } else {
+ define inline ""
+ msg-result no
+ }
+ define-feature inline $ok
+ return $ok
+}
diff --git a/autosetup/local.tcl b/autosetup/local.tcl
index bf86c5c..ba2bb3d 100644
--- a/autosetup/local.tcl
+++ b/autosetup/local.tcl
@@ -32,7 +32,7 @@ proc ext-get-status {ext} {
return ?
}
-proc check-extension-status {ext required} {
+proc check-extension-status {ext required {asmodule 0}} {
global withinfo
set status [ext-get-status $ext]
@@ -79,7 +79,13 @@ proc check-extension-status {ext required} {
}
}
- if {$ext in $withinfo(mod)} {
+ # asmodule=1 means that the parent is a module so
+ # any automatically selected dependencies should also be modules
+ if {$asmodule == 0 && $ext in $withinfo(mod)} {
+ set asmodule 1
+ }
+
+ if {$asmodule} {
# This is a module, so ignore LIBS
# LDLIBS_$ext will contain the appropriate libs for this module
define LIBS $LIBS
@@ -88,7 +94,7 @@ proc check-extension-status {ext required} {
if {$depinfo(n) == 0} {
# Now extension dependencies
foreach i [ext-get $ext dep] {
- set status [check-extension-status $i $required]
+ set status [check-extension-status $i $required $asmodule]
#puts "$ext: dep $i $required => $status"
incr depinfo($status)
if {$depinfo(n)} {
@@ -108,8 +114,8 @@ proc check-extension-status {ext required} {
return [ext-set-status $ext n]
}
- # Selected as a module?
- if {$ext in $withinfo(mod)} {
+ # Selected as a module directly or because of a parent dependency?
+ if {$asmodule} {
if {[ext-has $ext tcl]} {
# Easy, a Tcl module
msg-result "Extension $ext...tcl"
@@ -121,6 +127,7 @@ proc check-extension-status {ext required} {
define-append LDLIBS_$ext [pkg-config-get $pkg LIBS]
define-append LDFLAGS [pkg-config-get $pkg LDFLAGS]
define-append CCOPTS [pkg-config-get $pkg CFLAGS]
+ define-append PKG_CONFIG_REQUIRES $pkg
} else {
foreach i [ext-get $ext libdep] {
define-append LDLIBS_$ext [get-define $i ""]
@@ -145,6 +152,7 @@ proc check-extension-status {ext required} {
define-append LDLIBS [pkg-config-get $pkg LIBS]
define-append LDFLAGS [pkg-config-get $pkg LDFLAGS]
define-append CCOPTS [pkg-config-get $pkg CFLAGS]
+ define-append PKG_CONFIG_REQUIRES $pkg
} else {
foreach i [ext-get $ext libdep] {
define-append LDLIBS [get-define $i ""]
@@ -178,15 +186,20 @@ proc check-extensions {} {
set withinfo(maybe) {}
# Now work out the default status. We have.
- # normal case, include !optional if possible
- # --without=default, don't include optional
+ # normal case, include !off, !optional if possible
+ # --full, include !off if possible
+ # --without=default, don't include optional or off
if {$withinfo(nodefault)} {
lappend withinfo(maybe) stdlib
} else {
foreach i $extlist {
- if {![ext-has $i optional]} {
- lappend withinfo(maybe) $i
+ if {[ext-has $i off]} {
+ continue
+ }
+ if {[ext-has $i optional] && !$withinfo(optional)} {
+ continue
}
+ lappend withinfo(maybe) $i
}
}
diff --git a/autosetup/pkg-config.tcl b/autosetup/pkg-config.tcl
index c2e2bbf..0883e4c 100644
--- a/autosetup/pkg-config.tcl
+++ b/autosetup/pkg-config.tcl
@@ -3,15 +3,15 @@
# @synopsis:
#
-# The 'pkg-config' module allows package information to be found via pkg-config
+# The 'pkg-config' module allows package information to be found via 'pkg-config'.
#
# If not cross-compiling, the package path should be determined automatically
-# by pkg-config.
+# by 'pkg-config'.
# If cross-compiling, the default package path is the compiler sysroot.
-# If the C compiler doesn't support -print-sysroot, the path can be supplied
-# by the --sysroot option or by defining SYSROOT.
+# If the C compiler doesn't support '-print-sysroot', the path can be supplied
+# by the '--sysroot' option or by defining 'SYSROOT'.
#
-# PKG_CONFIG may be set to use an alternative to pkg-config
+# 'PKG_CONFIG' may be set to use an alternative to 'pkg-config'.
use cc
@@ -21,12 +21,13 @@ module-options {
# @pkg-config-init ?required?
#
-# Initialises the pkg-config system. Unless required is set to 0,
-# it is a fatal error if the pkg-config
+# Initialises the 'pkg-config' system. Unless '$required' is set to 0,
+# it is a fatal error if a usable 'pkg-config' is not found .
+#
# This command will normally be called automatically as required,
-# but it may be invoked explicitly if lack of pkg-config is acceptable.
+# but it may be invoked explicitly if lack of 'pkg-config' is acceptable.
#
-# Returns 1 if ok, or 0 if pkg-config not found/usable (only if required=0)
+# Returns 1 if ok, or 0 if 'pkg-config' not found/usable (only if '$required' is 0).
#
proc pkg-config-init {{required 1}} {
if {[is-defined HAVE_PKG_CONFIG]} {
@@ -37,15 +38,19 @@ proc pkg-config-init {{required 1}} {
define PKG_CONFIG [get-env PKG_CONFIG pkg-config]
msg-checking "Checking for pkg-config..."
- try {
- set version [exec [get-define PKG_CONFIG] --version]
+ if {[catch {exec [get-define PKG_CONFIG] --version} version]} {
+ msg-result "[get-define PKG_CONFIG] (not found)"
+ if {$required} {
+ user-error "No usable pkg-config"
+ }
+ } else {
msg-result $version
define PKG_CONFIG_VERSION $version
set found 1
- if {[opt-val sysroot] ne ""} {
- define SYSROOT [file-normalize [opt-val sysroot]]
+ if {[opt-str sysroot o]} {
+ define SYSROOT [file-normalize $o]
msg-result "Using specified sysroot [get-define SYSROOT]"
} elseif {[get-define build] ne [get-define host]} {
if {[catch {exec-with-stderr [get-define CC] -print-sysroot} result errinfo] == 0} {
@@ -72,12 +77,6 @@ proc pkg-config-init {{required 1}} {
set env(PKG_CONFIG_LIBDIR) $sysroot/usr/lib/pkgconfig:$sysroot/usr/share/pkgconfig
set env(PKG_CONFIG_SYSROOT_DIR) $sysroot
}
-
- } on error msg {
- msg-result "[get-define PKG_CONFIG] (not found)"
- if {$required} {
- user-error "No usable pkg-config"
- }
}
define HAVE_PKG_CONFIG $found
return $found
@@ -85,17 +84,17 @@ proc pkg-config-init {{required 1}} {
# @pkg-config module ?requirements?
#
-# Use pkg-config to find the given module meeting the given requirements.
+# Use 'pkg-config' to find the given module meeting the given requirements.
# e.g.
#
## pkg-config pango >= 1.37.0
#
-# If found, returns 1 and sets HAVE_PKG_PANGO to 1 along with:
+# If found, returns 1 and sets 'HAVE_PKG_PANGO' to 1 along with:
#
## PKG_PANGO_VERSION to the found version
-## PKG_PANGO_LIBS to the required libs (--libs-only-l)
+## PKG_PANGO_LIBS to the required libs (--libs-only-l)
## PKG_PANGO_LDFLAGS to the required linker flags (--libs-only-L)
-## PKG_PANGO_CFLAGS to the required compiler flags (--cflags)
+## PKG_PANGO_CFLAGS to the required compiler flags (--cflags)
#
# If not found, returns 0.
#
@@ -109,29 +108,27 @@ proc pkg-config {module args} {
return 0
}
- try {
- set version [exec [get-define PKG_CONFIG] --modversion "$module $args"]
- msg-result $version
- set prefix [feature-define-name $module PKG_]
- define HAVE_${prefix}
- define ${prefix}_VERSION $version
- define ${prefix}_LIBS [exec pkg-config --libs-only-l $module]
- define ${prefix}_LDFLAGS [exec pkg-config --libs-only-L $module]
- define ${prefix}_CFLAGS [exec pkg-config --cflags $module]
- return 1
- } on error msg {
+ if {[catch {exec [get-define PKG_CONFIG] --modversion "$module $args"} version]} {
msg-result "not found"
- configlog "pkg-config --modversion $module $args: $msg"
+ configlog "pkg-config --modversion $module $args: $version"
return 0
}
+ msg-result $version
+ set prefix [feature-define-name $module PKG_]
+ define HAVE_${prefix}
+ define ${prefix}_VERSION $version
+ define ${prefix}_LIBS [exec pkg-config --libs-only-l $module]
+ define ${prefix}_LDFLAGS [exec pkg-config --libs-only-L $module]
+ define ${prefix}_CFLAGS [exec pkg-config --cflags $module]
+ return 1
}
# @pkg-config-get module setting
#
-# Convenience access to the results of pkg-config
+# Convenience access to the results of 'pkg-config'.
#
-# For example, [pkg-config-get pango CFLAGS] returns
-# the value of PKG_PANGO_CFLAGS, or "" if not defined.
+# For example, '[pkg-config-get pango CFLAGS]' returns
+# the value of 'PKG_PANGO_CFLAGS', or '""' if not defined.
proc pkg-config-get {module name} {
set prefix [feature-define-name $module PKG_]
get-define ${prefix}_${name} ""
diff --git a/autosetup/system.tcl b/autosetup/system.tcl
index 9d9cb39..b98b5c0 100644
--- a/autosetup/system.tcl
+++ b/autosetup/system.tcl
@@ -4,18 +4,36 @@
# @synopsis:
#
# This module supports common system interrogation and options
-# such as --host, --build, --prefix, and setting srcdir, builddir, and EXEEXT
+# such as '--host', '--build', '--prefix', and setting 'srcdir', 'builddir', and 'EXEEXT'.
#
-# It also support the 'feature' naming convention, where searching
-# for a feature such as sys/type.h defines HAVE_SYS_TYPES_H
+# It also support the "feature" naming convention, where searching
+# for a feature such as 'sys/type.h' defines 'HAVE_SYS_TYPES_H'.
#
-module-options {
+# It defines the following variables, based on '--prefix' unless overridden by the user:
+#
+## datadir
+## sysconfdir
+## sharedstatedir
+## localstatedir
+## infodir
+## mandir
+## includedir
+#
+# If '--prefix' is not supplied, it defaults to '/usr/local' unless 'defaultprefix' is defined *before*
+# including the 'system' module.
+
+if {[is-defined defaultprefix]} {
+ user-notice "Note: defaultprefix is deprecated. Use options-defaults to set default options"
+ options-defaults [list prefix [get-define defaultprefix]]
+}
+
+module-options [subst -noc -nob {
host:host-alias => {a complete or partial cpu-vendor-opsys for the system where
the application will run (defaults to the same value as --build)}
build:build-alias => {a complete or partial cpu-vendor-opsys for the system
where the application will be built (defaults to the
result of running config.guess)}
- prefix:dir => {the target directory for the build (defaults to /usr/local)}
+ prefix:dir=/usr/local => {the target directory for the build (default: '@default@')}
# These (hidden) options are supported for autoconf/automake compatibility
exec-prefix:
@@ -30,12 +48,22 @@ module-options {
sysconfdir:
sharedstatedir:
localstatedir:
+ runstatedir:
maintainer-mode=0
dependency-tracking=0
-}
+ silent-rules=0
+}]
-# Returns 1 if exists, or 0 if not
+# @check-feature name { script }
+#
+# defines feature '$name' to the return value of '$script',
+# which should be 1 if found or 0 if not found.
+#
+# e.g. the following will define 'HAVE_CONST' to 0 or 1.
#
+## check-feature const {
+## cctest -code {const int _x = 0;}
+## }
proc check-feature {name code} {
msg-checking "Checking for $name..."
set r [uplevel 1 $code]
@@ -50,9 +78,10 @@ proc check-feature {name code} {
# @have-feature name ?default=0?
#
-# Returns the value of the feature if defined, or $default if not.
-# See 'feature-define-name' for how the feature name
-# is translated into the define name.
+# Returns the value of feature '$name' if defined, or '$default' if not.
+#
+# See 'feature-define-name' for how the "feature" name
+# is translated into the "define" name.
#
proc have-feature {name {default 0}} {
get-define [feature-define-name $name] $default
@@ -60,9 +89,10 @@ proc have-feature {name {default 0}} {
# @define-feature name ?value=1?
#
-# Sets the feature 'define' to the given value.
-# See 'feature-define-name' for how the feature name
-# is translated into the define name.
+# Sets the feature 'define' to '$value'.
+#
+# See 'feature-define-name' for how the "feature" name
+# is translated into the "define" name.
#
proc define-feature {name {value 1}} {
define [feature-define-name $name] $value
@@ -70,7 +100,7 @@ proc define-feature {name {value 1}} {
# @feature-checked name
#
-# Returns 1 if the feature has been checked, whether true or not
+# Returns 1 if feature '$name' has been checked, whether true or not.
#
proc feature-checked {name} {
is-defined [feature-define-name $name]
@@ -78,17 +108,20 @@ proc feature-checked {name} {
# @feature-define-name name ?prefix=HAVE_?
#
-# Converts a name to the corresponding define,
-# e.g. sys/stat.h becomes HAVE_SYS_STAT_H.
+# Converts a "feature" name to the corresponding "define",
+# e.g. 'sys/stat.h' becomes 'HAVE_SYS_STAT_H'.
#
-# Converts * to P and all non-alphanumeric to underscore.
+# Converts '*' to 'P' and all non-alphanumeric to underscore.
#
proc feature-define-name {name {prefix HAVE_}} {
string toupper $prefix[regsub -all {[^a-zA-Z0-9]} [regsub -all {[*]} $name p] _]
}
-# If $file doesn't exist, or it's contents are different than $buf,
-# the file is written and $script is executed.
+# @write-if-changed filename contents ?script?
+#
+# If '$filename' doesn't exist, or it's contents are different to '$contents',
+# the file is written and '$script' is evaluated.
+#
# Otherwise a "file is unchanged" message is displayed.
proc write-if-changed {file buf {script {}}} {
set old [readfile $file ""]
@@ -100,37 +133,137 @@ proc write-if-changed {file buf {script {}}} {
}
}
+
+# @include-file infile mapping
+#
+# The core of make-template, called recursively for each @include
+# directive found within that template so that this proc's result
+# is the fully-expanded template.
+#
+# The mapping parameter is how we expand @varname@ within the template.
+# We do that inline within this step only for @include directives which
+# can have variables in the filename arg. A separate substitution pass
+# happens when this recursive function returns, expanding the rest of
+# the variables.
+#
+proc include-file {infile mapping} {
+ # A stack of true/false conditions, one for each nested conditional
+ # starting with "true"
+ set condstack {1}
+ set result {}
+ set linenum 0
+ foreach line [split [readfile $infile] \n] {
+ incr linenum
+ if {[regexp {^@(if|else|endif)(\s*)(.*)} $line -> condtype condspace condargs]} {
+ if {$condtype eq "if"} {
+ if {[string length $condspace] == 0} {
+ autosetup-error "$infile:$linenum: Invalid expression: $line"
+ }
+ if {[llength $condargs] == 1} {
+ # ABC => [get-define ABC] ni {0 ""}
+ # !ABC => [get-define ABC] in {0 ""}
+ lassign $condargs condvar
+ if {[regexp {^!(.*)} $condvar -> condvar]} {
+ set op in
+ } else {
+ set op ni
+ }
+ set condexpr "\[[list get-define $condvar]\] $op {0 {}}"
+ } else {
+ # Translate alphanumeric ABC into [get-define ABC] and leave the
+ # rest of the expression untouched
+ regsub -all {([A-Z][[:alnum:]_]*)} $condargs {[get-define \1]} condexpr
+ }
+ if {[catch [list expr $condexpr] condval]} {
+ dputs $condval
+ autosetup-error "$infile:$linenum: Invalid expression: $line"
+ }
+ dputs "@$condtype: $condexpr => $condval"
+ }
+ if {$condtype ne "if"} {
+ if {[llength $condstack] <= 1} {
+ autosetup-error "$infile:$linenum: Error: @$condtype missing @if"
+ } elseif {[string length $condargs] && [string index $condargs 0] ne "#"} {
+ autosetup-error "$infile:$linenum: Error: Extra arguments after @$condtype"
+ }
+ }
+ switch -exact $condtype {
+ if {
+ # push condval
+ lappend condstack $condval
+ }
+ else {
+ # Toggle the last entry
+ set condval [lpop condstack]
+ set condval [expr {!$condval}]
+ lappend condstack $condval
+ }
+ endif {
+ if {[llength $condstack] == 0} {
+ user-notice "$infile:$linenum: Error: @endif missing @if"
+ }
+ lpop condstack
+ }
+ }
+ continue
+ } elseif {[regexp {^@include\s+(.*)} $line -> filearg]} {
+ set incfile [string map $mapping $filearg]
+ if {[file exists $incfile]} {
+ lappend ::autosetup(deps) [file-normalize $incfile]
+ lappend result {*}[include-file $incfile $mapping]
+ } else {
+ user-error "$infile:$linenum: Include file $incfile is missing"
+ }
+ continue
+ } elseif {[regexp {^@define\s+(\w+)\s+(.*)} $line -> var val]} {
+ define $var $val
+ continue
+ }
+ # Only output this line if the stack contains all "true"
+ if {"0" in $condstack} {
+ continue
+ }
+ lappend result $line
+ }
+ return $result
+}
+
+
# @make-template template ?outfile?
#
-# Reads the input file <srcdir>/$template and writes the output file $outfile.
-# If $outfile is blank/omitted, $template should end with ".in" which
+# Reads the input file '<srcdir>/$template' and writes the output file '$outfile'
+# (unless unchanged).
+# If '$outfile' is blank/omitted, '$template' should end with '.in' which
# is removed to create the output file name.
#
-# Each pattern of the form @define@ is replaced with the corresponding
-# define, if it exists, or left unchanged if not.
-#
-# The special value @srcdir@ is substituted with the relative
+# Each pattern of the form '@define@' is replaced with the corresponding
+# "define", if it exists, or left unchanged if not.
+#
+# The special value '@srcdir@' is substituted with the relative
# path to the source directory from the directory where the output
-# file is created, while the special value @top_srcdir@ is substituted
+# file is created, while the special value '@top_srcdir@' is substituted
# with the relative path to the top level source directory.
#
# Conditional sections may be specified as follows:
-## @if name == value
+## @if NAME eq "value"
## lines
## @else
## lines
## @endif
#
-# Where 'name' is a defined variable name and @else is optional.
+# Where 'NAME' is a defined variable name and '@else' is optional.
+# Note that variables names *must* start with an uppercase letter.
# If the expression does not match, all lines through '@endif' are ignored.
#
# The alternative forms may also be used:
-## @if name
-## @if name != value
+## @if NAME (true if the variable is defined, but not empty and not "0")
+## @if !NAME (opposite of the form above)
+## @if <general-tcl-expression>
#
-# Where the first form is true if the variable is defined, but not empty or 0
+# In the general Tcl expression, any words beginning with an uppercase letter
+# are translated into [get-define NAME]
#
-# Currently these expressions can't be nested.
+# Expressions may be nested
#
proc make-template {template {out {}}} {
set infile [file join $::autosetup(srcdir) $template]
@@ -158,49 +291,30 @@ proc make-template {template {out {}}} {
define srcdir [relative-path [file join $::autosetup(srcdir) $outdir] $outdir]
define top_srcdir [relative-path $::autosetup(srcdir) $outdir]
- set mapping {}
- foreach {n v} [array get ::define] {
- lappend mapping @$n@ $v
- }
- set result {}
- foreach line [split [readfile $infile] \n] {
- if {[info exists cond]} {
- set l [string trimright $line]
- if {$l eq "@endif"} {
- unset cond
- continue
- }
- if {$l eq "@else"} {
- set cond [expr {!$cond}]
- continue
- }
- if {$cond} {
- lappend result $line
- }
- continue
- }
- if {[regexp {^@if\s+(\w+)(.*)} $line -> name expression]} {
- lassign $expression equal value
- set varval [get-define $name ""]
- if {$equal eq ""} {
- set cond [expr {$varval ni {"" 0}}]
- } else {
- set cond [expr {$varval eq $value}]
- if {$equal ne "=="} {
- set cond [expr {!$cond}]
- }
- }
- continue
+ # Build map from global defines to their values so they can be
+ # substituted into @include file names.
+ proc build-define-mapping {} {
+ set mapping {}
+ foreach {n v} [array get ::define] {
+ lappend mapping @$n@ $v
}
- lappend result $line
+ return $mapping
}
- writefile $out [string map $mapping [join $result \n]]\n
+ set mapping [build-define-mapping]
+
+ set result [include-file $infile $mapping]
- msg-result "Created [relative-path $out] from [relative-path $template]"
+ # Rebuild the define mapping in case we ran across @define
+ # directives in the template or a file it @included, then
+ # apply that mapping to the expanded template.
+ set mapping [build-define-mapping]
+ write-if-changed $out [string map $mapping [join $result \n]] {
+ msg-result "Created [relative-path $out] from [relative-path $template]"
+ }
}
# build/host tuples and cross-compilation prefix
-set build [opt-val build]
+opt-str build build ""
define build_alias $build
if {$build eq ""} {
define build [config_guess]
@@ -208,7 +322,7 @@ if {$build eq ""} {
define build [config_sub $build]
}
-set host [opt-val host]
+opt-str host host ""
define host_alias $host
if {$host eq ""} {
define host [get-define build]
@@ -219,42 +333,64 @@ if {$host eq ""} {
}
define cross [get-env CROSS $cross]
-# Do "define defaultprefix myvalue" to set the default prefix *before* the first "use"
-set prefix [opt-val prefix [get-define defaultprefix /usr/local]]
+# build/host _cpu, _vendor and _os
+foreach type {build host} {
+ set v [get-define $type]
+ if {![regexp {^([^-]+)-([^-]+)-(.*)$} $v -> cpu vendor os]} {
+ user-error "Invalid canonical $type: $v"
+ }
+ define ${type}_cpu $cpu
+ define ${type}_vendor $vendor
+ define ${type}_os $os
+}
+
+opt-str prefix prefix /usr/local
# These are for compatibility with autoconf
define target [get-define host]
define prefix $prefix
define builddir $autosetup(builddir)
define srcdir $autosetup(srcdir)
-# Allow this to come from the environment
-define top_srcdir [get-env top_srcdir [get-define srcdir]]
+define top_srcdir $autosetup(srcdir)
+define abs_top_srcdir [file-normalize $autosetup(srcdir)]
+define abs_top_builddir [file-normalize $autosetup(builddir)]
# autoconf supports all of these
-set exec_prefix [opt-val exec-prefix $prefix]
-define exec_prefix $exec_prefix
+define exec_prefix [opt-str exec-prefix exec_prefix $prefix]
foreach {name defpath} {
bindir /bin
sbindir /sbin
libexecdir /libexec
libdir /lib
} {
- define $name [opt-val $name $exec_prefix$defpath]
+ define $name [opt-str $name o $exec_prefix$defpath]
}
foreach {name defpath} {
datadir /share
- sysconfdir /etc
sharedstatedir /com
- localstatedir /var
infodir /share/info
mandir /share/man
includedir /include
} {
- define $name [opt-val $name $prefix$defpath]
+ define $name [opt-str $name o $prefix$defpath]
}
+if {$prefix ne {/usr}} {
+ opt-str sysconfdir sysconfdir $prefix/etc
+} else {
+ opt-str sysconfdir sysconfdir /etc
+}
+define sysconfdir $sysconfdir
+
+define localstatedir [opt-str localstatedir o /var]
+define runstatedir [opt-str runstatedir o /run]
define SHELL [get-env SHELL [find-an-executable sh bash ksh]]
+# These could be used to generate Makefiles following some automake conventions
+define AM_SILENT_RULES [opt-bool silent-rules]
+define AM_MAINTAINER_MODE [opt-bool maintainer-mode]
+define AM_DEPENDENCY_TRACKING [opt-bool dependency-tracking]
+
# Windows vs. non-Windows
switch -glob -- [get-define host] {
*-*-ming* - *-*-cygwin - *-*-msys {
diff --git a/autosetup/tmake.auto b/autosetup/tmake.auto
index 75813c3..64a5712 100644
--- a/autosetup/tmake.auto
+++ b/autosetup/tmake.auto
@@ -23,41 +23,30 @@ cc-check-tools ar ranlib
set objdir [get-env BUILDDIR objdir]
make-config-header $objdir/include/autoconf.h
-make-tmake-settings $objdir/settings.conf {[A-Z]*}
+make-tmake-settings $objdir/settings.conf {[A-Z]*} *dir lib_*
}
autosetup_check_create project.spec \
{# Initial project.spec created by 'autosetup --init=tmake'
+tmake-require-version 0.7.3
+
# vim:set syntax=tcl:
define? DESTDIR _install
# XXX If configure creates additional/different files than include/autoconf.h
# that should be reflected here
+Autosetup include/autoconf.h
-# We use [set AUTOREMAKE] here to avoid rebuilding settings.conf
-# if the AUTOREMAKE command changes
-Depends {settings.conf include/autoconf.h} auto.def -msg {note Configuring...} -do {
- run [set AUTOREMAKE] >$build/config.out
-} -onerror {puts [readfile $build/config.out]} -fatal
-Clean config.out
-DistClean --source config.log
-DistClean settings.conf include/autoconf.h
-
-# If not configured, configure with default options
-# Note that it is expected that configure will normally be run
-# separately. This is just a convenience for a host build
-define? AUTOREMAKE configure TOPBUILDDIR=$TOPBUILDDIR --conf=auto.def
-
-Load settings.conf
-
-# e.g. for up autoconf.h
+# e.g. for autoconf.h
IncludePaths include
-ifconfig CONFIGURED
-
-# Hmmm, but should we turn off AutoSubDirs?
-#AutoSubDirs off
+ifconfig !CONFIGURED {
+ # Not configured, so don't process subdirs
+ AutoSubDirs off
+ # And don't process this file any further
+ ifconfig false
+}
}
if {![file exists build.spec]} {
diff --git a/autosetup/tmake.tcl b/autosetup/tmake.tcl
index b946362..a9d7219 100644
--- a/autosetup/tmake.tcl
+++ b/autosetup/tmake.tcl
@@ -17,9 +17,9 @@ define CONFIGURED
# @make-tmake-settings outfile patterns ...
#
-# Examines all defined variables which match the given patterns (defaults to "*")
+# Examines all defined variables which match the given patterns (defaults to '*')
# and writes a tmake-compatible .conf file defining those variables.
-# For example, if ABC is "3 monkeys" and ABC matches a pattern, then the file will include:
+# For example, if 'ABC' is '"3 monkeys"' and 'ABC' matches a pattern, then the file will include:
#
## define ABC {3 monkeys}
#
@@ -27,7 +27,7 @@ define CONFIGURED
#
# Typical usage is:
#
-# make-tmake-settings [get-env BUILDDIR objdir]/settings.conf {[A-Z]*}
+## make-tmake-settings [get-env BUILDDIR objdir]/settings.conf {[A-Z]*}
proc make-tmake-settings {file args} {
file mkdir [file dirname $file]
set lines {}
diff --git a/bootstrap.tcl b/bootstrap.tcl
index f6c404f..c93ec9f 100644
--- a/bootstrap.tcl
+++ b/bootstrap.tcl
@@ -1,10 +1,14 @@
# Minimal support for package require
# No error on failure since C extensions aren't handled
-proc package {cmd pkg} {
+proc package {cmd pkg args} {
if {$cmd eq "require"} {
foreach path $::auto_path {
- if {[file exists $path/$pkg.tcl]} {
- uplevel #0 [list source $path/$pkg.tcl]
+ set pkgpath $path/$pkg.tcl
+ if {$path eq "."} {
+ set pkgpath $pkg.tcl
+ }
+ if {[file exists $pkgpath]} {
+ uplevel #0 [list source $pkgpath]
return
}
}
diff --git a/build-jim-ext.in b/build-jim-ext.in
index 087ec23..ce9ddf6 100644
--- a/build-jim-ext.in
+++ b/build-jim-ext.in
@@ -5,25 +5,16 @@ set opts {}
set sources {}
proc usage {{msg {}}} {
- puts stderr "Usage: build-jim-ext ?--notest? ?--install? ?--static? ?cc-options? ?-o modname? sources..."
+ puts stderr "Usage: build-jim-ext ?--notest? ?--cross? ?--install? ?--static? ?cc-options? ?-o modname? sources..."
if {$msg ne ""} {
puts stderr \n$msg
}
exit 1
}
-proc readfile {filename {default_value ""}} {
- set result $default_value
- catch {
- set f [open $filename]
- set result [$f read -nonewline]
- $f close
- }
- return $result
-}
-
set linker "@CC@"
set testmod 1
+set cross @cross_compiling@
set install 0
set static 0
set verbose 0
@@ -42,18 +33,26 @@ for {set i 0} {$i < [llength $argv]} {incr i} {
set linker "@CXX@"
}
--notest {
+ # Don't test to see if the module can be loaded
set testmod 0
}
+ --cross {
+ # Don't use standard include/lib paths if cross compiling
+ set cross 1
+ }
--install {
+ # Install to $DESTDIR/@prefix@/lib/jim
set install 1
}
--static {
+ # Build a static extension that can be linked
set static 1
}
--verbose {
set verbose 1
}
--keep {
+ # Don't remove intermediate files
set keep 1
}
--help {
@@ -106,8 +105,39 @@ if {$static} {
}
puts "Building $target from $sources\n"
-# Now add the standard location after any user include paths
-lappend includepaths -I@prefix@/include
+if {!$cross} {
+ # If not cross compiling, add the standard location after any user include paths
+ lappend includepaths -I@prefix@/include
+}
+
+# Work around Tcl's strange behaviour of exec failing if stderr is produced
+#
+proc exec-catch {verbose cmdlist} {
+ if {$verbose} {
+ puts [join $cmdlist]
+ }
+ flush stdout
+ set rc [catch {
+ exec {*}$cmdlist
+ } msg errinfo]
+
+ # Handle failed case.
+ # Note that Tcl returns rc=1 if there is any stderr,
+ # even if the exit code is 0
+ if {$rc} {
+ if {[dict get $errinfo -errorcode] ne "NONE"} {
+ if {!$verbose} {
+ puts stderr [join $cmdlist]
+ }
+ puts stderr $msg
+ return 1
+ }
+ }
+ if {$msg ne ""} {
+ puts stderr $msg
+ }
+ return 0
+}
set CPPFLAGS "-D_GNU_SOURCE"
@@ -137,31 +167,11 @@ foreach source $sources {
set compile "$compiler @CFLAGS@ $CPPFLAGS $shobj_cflags $includepaths $opts -c -o $obj $source"
puts "Compile: $obj"
lappend objs $obj
- flush stdout
- set rc [catch {
- if {$verbose} {
- puts $compile
- }
- exec 2>jimerr.out {*}$compile
- } msg]
-
- set errmsg [readfile jimerr.out]
- file delete jimerr.out
+ set rc [exec-catch $verbose $compile]
if {$rc} {
- if {!$verbose} {
- puts stderr $compile
- }
- puts stderr $msg
- if {$errmsg ne ""} {
- puts stderr $errmsg
- }
file delete {*}$objs
- exit 1
- } else {
- if {$errmsg ne ""} {
- puts $errmsg
- }
+ exit $rc
}
}
@@ -170,65 +180,39 @@ if {$static} {
set ranlib "@RANLIB@ $target"
puts "Ar: $target"
- set rc [catch {
- file delete $target
- exec {*}$ar
- exec {*}$ranlib
- if {$verbose} {
- puts stderr $ar
- }
- } msg]
-
+ set rc [exec-catch $verbose $ar]
+ if {rc == 0} {
+ set rc [exec-catch $verbose $ranlib]
+ }
file delete {*}$objs
-
if {$rc} {
- puts stderr $ar
- puts stderr $ranlib
- puts stderr $msg
file delete $target
- exit 1
+ exit $rc
}
} else {
- # Add the standard location after any user lib paths
- lappend libpaths -L@prefix@/lib
+ if {!$cross} {
+ # If not cross compiling, add the standard location after any user lib paths
+ lappend libpaths -L@prefix@/lib
+ }
set link "$linker @CFLAGS@ @LDFLAGS@ $shobj_ldflags $libpaths $opts -o $target $objs $ljim @LIBS@ $libs"
puts "Link: $target"
- set rc [catch {
- if {$verbose} {
- puts stderr $link
- }
- exec 2>jimerr.out {*}$link
- } msg]
-
- set errmsg [readfile jimerr.out]
- file delete jimerr.out
-
+ set rc [exec-catch $verbose $link]
if {!$keep} {
file delete {*}$objs
}
-
if {$rc} {
file delete $target
- puts stderr $link
- puts stderr $msg
- if {$errmsg ne ""} {
- puts stderr $errmsg
- }
- exit 1
- }
- if {$errmsg ne ""} {
- puts $errmsg
+ exit $rc
}
- if {$testmod} {
+ if {$testmod && !$cross} {
# Now, is testing even possible?
# We must be running a compatible jimsh with the load command at least
set testmod 0
set rc [catch {
# This will avoid attempting on Tcl and on jimsh without load
- # How to tell if we are cross compiling?
if {[info version] > 0.73 && [exists -command load]} {
set testmod 1
}
@@ -236,7 +220,7 @@ if {$static} {
}
set rc [catch {
- if {$testmod} {
+ if {$testmod && !$cross} {
puts "Test: load $target"
load ./$target
}
diff --git a/configure b/configure
index 8367bd8..adac37c 100755
--- a/configure
+++ b/configure
@@ -1,3 +1,3 @@
#!/bin/sh
dir="`dirname "$0"`/autosetup"
-WRAPPER="$0"; export WRAPPER; exec "`$dir/find-tclsh`" "$dir/autosetup" "$@"
+WRAPPER="$0"; export WRAPPER; exec "`"$dir/autosetup-find-tclsh"`" "$dir/autosetup" "$@"
diff --git a/examples/certificate.pem b/examples/certificate.pem
index 9d7ac23..2c49fd9 100644
--- a/examples/certificate.pem
+++ b/examples/certificate.pem
@@ -1,14 +1,28 @@
-----BEGIN CERTIFICATE-----
-MIICLDCCAdYCAQAwDQYJKoZIhvcNAQEEBQAwgaAxCzAJBgNVBAYTAlBUMRMwEQYD
-VQQIEwpRdWVlbnNsYW5kMQ8wDQYDVQQHEwZMaXNib2ExFzAVBgNVBAoTDk5ldXJv
-bmlvLCBMZGEuMRgwFgYDVQQLEw9EZXNlbnZvbHZpbWVudG8xGzAZBgNVBAMTEmJy
-dXR1cy5uZXVyb25pby5wdDEbMBkGCSqGSIb3DQEJARYMc2FtcG9AaWtpLmZpMB4X
-DTk2MDkwNTAzNDI0M1oXDTk2MTAwNTAzNDI0M1owgaAxCzAJBgNVBAYTAlBUMRMw
-EQYDVQQIEwpRdWVlbnNsYW5kMQ8wDQYDVQQHEwZMaXNib2ExFzAVBgNVBAoTDk5l
-dXJvbmlvLCBMZGEuMRgwFgYDVQQLEw9EZXNlbnZvbHZpbWVudG8xGzAZBgNVBAMT
-EmJydXR1cy5uZXVyb25pby5wdDEbMBkGCSqGSIb3DQEJARYMc2FtcG9AaWtpLmZp
-MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAL7+aty3S1iBA/+yxjxv4q1MUTd1kjNw
-L4lYKbpzzlmC5beaQXeQ2RmGMTXU+mDvuqItjVHOK3DvPK7lTcSGftUCAwEAATAN
-BgkqhkiG9w0BAQQFAANBAFqPEKFjk6T6CKTHvaQeEAsX0/8YHPHqH/9AnhSjrwuX
-9EBc0n6bVGhN7XaXd6sJ7dym9sbsWxb+pJdurnkxjx4=
+MIIEwDCCAqgCCQCFOs3gH4RsKTANBgkqhkiG9w0BAQUFADAiMQswCQYDVQQGEwJh
+dTETMBEGA1UEAwwKamltLnRjbC50azAeFw0xOTA5MjQyMzQ2NDFaFw00NzAyMDgy
+MzQ2NDFaMCIxCzAJBgNVBAYTAmF1MRMwEQYDVQQDDApqaW0udGNsLnRrMIICIjAN
+BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0T9HMb5b2WZDIAF7+7KZzwAEiXC5
+misVrY1gmlwvLlSVx1pXKx5KrFpwkBMfDs1Zsi03/D46N+kViOmSJY/h5nxpiTdb
+s1Gld2b1RqFbnXcLmx7eWVXXouLDcmzoJM1Y7vh26e9j3Uy4Bsew7zfxgnWmbfOA
+9Sg/rHamQFfJ+Ov9NglkAoGPwdIiDWc4+hkKD6HL3B72m3VyD4crDSuTm2vFqUDh
+Xk+Jw3clNQYXHQrOSpDKst1qPQtEDTQbrmKhSN6jMBRwcwfo39lCZLN02jEfOC2b
+wHPe+VgcyfCzWgfKHtPlhqqanSIndDSAc6aF5hzI1vlT2dZNmSWDZ6QBrwharh25
+QXcnQhDr/9DyHIjgvojROsOiSaT4pVvJRBsVm7N/7kVQKvNdbwB8itz+ubLlb5SY
+ahlZNBMpE9RqgchwAwe0SpjILMBHI90/H89SrZPZ4rMitZiIq5/3mBFEy/7Xio/G
+5jw/Gp3cHa6SMf/6cqhll7binB8s8Yd5c8RvdNunczCobKmbnTMDRdsnjnvWFmia
+PJZUdcOtftxUCxYP2tEjapQL8kjC+K4MjCGkde/5lrd8+yRY6GK6zixxfYb1jka/
+NFdXBaws4gm8amrsFstkY3K2GqrVh44/sG7BNqsl4hxkqyHryay7B413+KUrkiET
+4PqwSHgtJHPayAMCAwEAATANBgkqhkiG9w0BAQUFAAOCAgEAlieZi6YNBCKkCLVP
+bIEtB/Ky28YTZ8Blv9dyOG557nfIze0NgsFJLOvLCFqKh8TKJRxGWkBeDh72ozjd
+R0twQ9w/uWv/RIvBvX+O67ByN8/u3E+H8TqsnRq6FxnHLKh4MbUuNya6/dskVAtB
+5JthL5EPU0z+6MqIissmx4V7d/MA3bEWF+etAnI9maxdJ2KXlqiBy0K09RCydZzi
+JHSVqpY/UrwYjWxgJgMFq5ZLrMwLv2SVqFa5FnMsP2Qc1Ojgq0Jz8vbYFd9CCyyc
+mZUb1fAoxKRjBOBbbgW3fYsS4MkJ1PGeUh+60beDsKZhuTe5g5KCiB0QdB53Juth
+UizaqM+u2PECDV5TmhVIDCyHhGbbfzIFppsrpCZfXwtie4qqj50l55I7KoX6Twhu
+7uadSWRiU60aOD7m99SUkqqkODXy2BvQixKZ6QOruTMqgbbpxpVMOUxFPkkmB5Jk
+LQ+3uIjBbVKQxGzniVwYwIRCTgg1x/nTlHEr5DhEs/8MiFrw3UafX9B6m9Jo1oJh
+HAs01bC9yMqNhaTXZRrGR4hEM3cmS0Sa6VYiZ+dhDwucvBwz0ClSiTT3iFjGcTMZ
+r9m5x0V15qZSvj1GWp6hSWIG/NwS+4gvv75Jlx83cr+bTlHgDl8h4seEmj8HhPq1
+j9ZXBr9P2ETiD8OVyZAT3hhSwOg=
-----END CERTIFICATE-----
diff --git a/examples/jtclsh.tcl b/examples/jtclsh.tcl
index b384717..772b327 100644
--- a/examples/jtclsh.tcl
+++ b/examples/jtclsh.tcl
@@ -8,6 +8,8 @@ package require history
set histfile [env HOME]/.jtclsh
history load $histfile
+# Use the standard Tcl autocompletion
+history completion tcl::autocomplete
set prefix ""
while {1} {
# Read a complete line (script)
diff --git a/examples/key.pem b/examples/key.pem
index 239ad66..67ca6c6 100644
--- a/examples/key.pem
+++ b/examples/key.pem
@@ -1,9 +1,51 @@
-----BEGIN RSA PRIVATE KEY-----
-MIIBPAIBAAJBAL7+aty3S1iBA/+yxjxv4q1MUTd1kjNwL4lYKbpzzlmC5beaQXeQ
-2RmGMTXU+mDvuqItjVHOK3DvPK7lTcSGftUCAwEAAQJBALjkK+jc2+iihI98riEF
-oudmkNziSRTYjnwjx8mCoAjPWviB3c742eO3FG4/soi1jD9A5alihEOXfUzloenr
-8IECIQD3B5+0l+68BA/6d76iUNqAAV8djGTzvxnCxycnxPQydQIhAMXt4trUI3nc
-a+U8YL2HPFA3gmhBsSICbq2OptOCnM7hAiEA6Xi3JIQECob8YwkRj29DU3/4WYD7
-WLPgsQpwo1GuSpECICGsnWH5oaeD9t9jbFoSfhJvv0IZmxdcLpRcpslpeWBBAiEA
-6/5B8J0GHdJq89FHwEG/H2eVVUYu5y/aD6sgcm+0Avg=
+MIIJKgIBAAKCAgEA0T9HMb5b2WZDIAF7+7KZzwAEiXC5misVrY1gmlwvLlSVx1pX
+Kx5KrFpwkBMfDs1Zsi03/D46N+kViOmSJY/h5nxpiTdbs1Gld2b1RqFbnXcLmx7e
+WVXXouLDcmzoJM1Y7vh26e9j3Uy4Bsew7zfxgnWmbfOA9Sg/rHamQFfJ+Ov9Nglk
+AoGPwdIiDWc4+hkKD6HL3B72m3VyD4crDSuTm2vFqUDhXk+Jw3clNQYXHQrOSpDK
+st1qPQtEDTQbrmKhSN6jMBRwcwfo39lCZLN02jEfOC2bwHPe+VgcyfCzWgfKHtPl
+hqqanSIndDSAc6aF5hzI1vlT2dZNmSWDZ6QBrwharh25QXcnQhDr/9DyHIjgvojR
+OsOiSaT4pVvJRBsVm7N/7kVQKvNdbwB8itz+ubLlb5SYahlZNBMpE9RqgchwAwe0
+SpjILMBHI90/H89SrZPZ4rMitZiIq5/3mBFEy/7Xio/G5jw/Gp3cHa6SMf/6cqhl
+l7binB8s8Yd5c8RvdNunczCobKmbnTMDRdsnjnvWFmiaPJZUdcOtftxUCxYP2tEj
+apQL8kjC+K4MjCGkde/5lrd8+yRY6GK6zixxfYb1jka/NFdXBaws4gm8amrsFstk
+Y3K2GqrVh44/sG7BNqsl4hxkqyHryay7B413+KUrkiET4PqwSHgtJHPayAMCAwEA
+AQKCAgEApOLjPCyP/jkaLg9dXtK3ZynRaWh9qSHIXFFqzVhVCYI34Last9qP508B
+IlcfAzAIPWJqmoeCouo2QQQlWRoPXeut0iXgSebNp9Bm+ThPlD7p01u4xNbjLITa
+lMGDEPUL3ovGUMOGgy1gWl9jaq4/zpjdBAl9FjKYMlPw4AUNr+xuRPWTbHIiEQ6A
+LOWpPVMb3YOWvCdeFtSug9P0tdUf5LpBMQViUkoE+hVaKXVaI1WPh6yfPeFCRUYq
+Yukr4vfvthdSqqGAlvSlqjdunSHYs9M/kapG8JmeHAg171+QRSKcQDyjwsGPQsFW
+K7jve7K+Er2d+eDRFXhM/6BS8wmHFLP5BtHY/XCCZdjcJShIrGWK/Arepzh5TPpe
+lIriZBzFBdtLNDaVs0Fj7C+r5ERYulgrF8gwEfPXxFen4vp4gjP3fRnApXgLfEGu
+2Cj7SR62nZrRWKBuOYhaoVGt1zdoP7mmcL32/Kg78ItteaNXG07ICogXBoTl0Tj0
+N0wPpFG280amcJLB2tSwYyiIF53XyNazKxhgpBHnt1/y+peQfZadncQ/nImmM0f6
+GTql3ToEMKj9V3nrYUQhRVEmltCrfJA8pVjFJkp0AjlyZOf/FgcSFNvWbdn0t6vE
+EOPU6RklpK0X0Go7B3ywOEqAu51oxo0QgUdRe6v2nzv7Xeuh9FkCggEBAPUV6JTg
+uqjWxq7XNA3RljCy8NPzTsT7AS7XwLBD/+JcICXjQQ2SVqMzx7SftGucGw6/8GKx
+HRXwp67k73iifiiQ7f1xOsXXgVs7aDg1MT7UE9KOVuY0r74P3No13nSfNYzOMBjh
+a+FqKO5v8yjZjNwT5ghtHluJqXPQPMeKYzR3ngNlFRzW9cfDQspiHdTSpu9gFE02
+iSug9SNxMjRDiWsqBC14qu3S3ynaU5UuKhqw5CVSRj/Y7pN94b01tVXe4Szcf/U0
+HXzg33jlf1QshwsdcBXcGpkB5ijtp6koQuAKRHjxeqcpMKIPpxzratlWBPeynvX7
+xO+bDultW4z8tr0CggEBANqQy30ZMM64v39bo04cQNrIMJd2ez1c/lqysneQwIuK
+1ALfRJbN74/Zy+vlx9VH6tKT2i5o1FP1Nd5BKiRGLd3bTLE+UlweUWrZoJbyz7ns
+IuLqGhw9Qy9SaqCfSyGu9Lmn8blCMVDPf1AggB4fuFHhiT+aBK1AidzDM/Usar2H
+D2HwfWP3tKARcyzBnWExiDncUau8oRFdfsYL72kb2P3RvtDtsMRLSFHOdd88o1Us
+LSQ+T36U3A2UKCteBndBguN+N7zyUNk7DVpfXILKmFj9nDmoYOFsnctG+TYbRmfr
+7G/wKDcEtrmK0tpSOLF5QvowO3qDYaYYYGdK5EPbxb8CggEACDRtjt5fIVvfVucZ
+dQT5NDQpX88bafjFN149syjzng5bfSk4ek3V3KzVGLToA1o8hafjUkp/oMZntrEv
+WyiFdLI1ZXCu+QSX7gf1Gzyco2/SIhBl1FsbLw+04xE+m0ThNA+LCKozRF6bdDAH
+QezWjF+WKd4NUB8xrxDfmAaH/6+peI+fv1Fq9P8Sc1gJi6BpukXLKDKVMQK4cjFN
+7vX72byUWzlY75FJq0sF1U6wVihp2t4AQA7xHbrvHbh4k6FchHX1Sq4t9opIsPFt
+69F5y+N2ZyTxNwIbRG+AV2djpcByPmJHKuV0HVjMzWkMMK5yiCBQtgdxtlvIigQB
+Np0XOQKCAQEAw6yYEUJpONmbz/iJppeS1IwfPKq9QL2tliOftX2pdARxNLUQYfay
+v9WcRHBuTJrbN3VZAu2lEhlZBcbPZLRTwejgq1oBQCmAeKmnpRxzLp+iyAYQJDIQ
+oSAnB/A0wk4xGLmrplEFd7Sc5W6DZPS+/sdtKbzI7Rb3leZI8Pm4AkAVXHiCuen9
+EsUsmOgp7ub6b9q4X4k7piFPKx1qVG6zAOIz9DaoZ8SCVYMCcj6Gd+1Z6LXEU64P
+qDR5FgJSxZeoB+VrH0TNbv34QW1YlFuusxUyNUhym76zMlczK+aVTNqhzcFzL3aP
+5GLNzNmJmhHXDcf6p/9Rf/MY88DPxZTPXwKCAQEAt2cxXMiEWfFwWHufqpahl3Aq
+C4yf0EFMhBsOmnDYZ4RDYikFGJog7XY+BOEX0NZ2z2ZghwjmQW/Gm14ISQnww97d
+uo/MDuUZvf6aAeh6gRmkiejhIXMwuvxRAwm90TFUiJ4yn8LKp2c1XxX8DMHujlzS
+cdUKcFO3OL+eLQazM5M+3qxQuAFDTlBf41d3OJjCOuQ9soBy0Gy9yMhtjFVVmKDw
+eArA0lZgskLVcI9JH6bPhv7+5+n26OqMlFjtmbNMwqi/lOoyGwst5b2d9oAMkWQi
+QW5pi51MaAwVV8q8NdfUv1twD8lpRV8Rwb2k8rmG5FqSwhOsibSwpu8gf4WYow==
-----END RSA PRIVATE KEY-----
diff --git a/examples/ssl.server b/examples/ssl.server
index 7ccb101..bf36646 100644
--- a/examples/ssl.server
+++ b/examples/ssl.server
@@ -5,7 +5,7 @@ set s [socket stream.server 20000]
$s readable {
# Clean up children
- os.wait -nohang 0
+ wait -nohang 0
set sock [[$s accept addr] ssl -server certificate.pem key.pem]
puts "Client address: $addr"
diff --git a/examples/tcp.server b/examples/tcp.server
index a86cd63..c62cd7a 100644
--- a/examples/tcp.server
+++ b/examples/tcp.server
@@ -5,7 +5,7 @@ set s [socket stream.server 20000]
$s readable {
# Clean up children
- os.wait -nohang 0
+ wait -nohang 0
set sock [$s accept addr]
puts "Client address: $addr"
diff --git a/examples/tip.tcl b/examples/tip.tcl
new file mode 100755
index 0000000..ff8b2fc
--- /dev/null
+++ b/examples/tip.tcl
@@ -0,0 +1,192 @@
+#!/usr/bin/env jimsh
+
+# tip.tcl is like a simple version of cu, written in pure Jim Tcl
+# It makes use of the new aio tty support
+
+# Note: On Mac OS X, be sure to open /dev/cu.* devices, not /dev/tty.* devices
+
+set USAGE \
+{Usage: tip ?settings? device
+ or tip help
+
+Where settings are as follows:
+1|2 stop bits (default 1)
+5|6|7|8 data bits (default 8)
+even|odd parity (default none)
+xonxoff|rtscts handshaking (default none)
+<number> baud rate (default 115200)
+
+e.g. tip 9600 8 1 rtscts /dev/ttyUSB0}
+
+set settings {
+ baud 115200
+ stop 1
+ data 8
+ parity none
+ handshake none
+ input raw
+ output raw
+ vmin 1
+ vtime 1
+}
+
+set showhelp 0
+
+foreach i $argv {
+ if {[string match -h* $i] || [string match help* $i]} {
+ puts $USAGE
+ return 0
+ }
+ if {$i in {even odd}} {
+ set settings(parity) $i
+ continue
+ }
+ if {$i in {ixonixoff rtscts}} {
+ set settings(handshake) $i
+ continue
+ }
+ if {$i in {1 2}} {
+ set settings(stop) $i
+ continue
+ }
+ if {$i in {5 6 7 8}} {
+ set settings(data) $i
+ continue
+ }
+ if {[string is integer -strict $i]} {
+ set settings(baud) $i
+ continue
+ }
+ if {[file exists $i]} {
+ set device $i
+ continue
+ }
+ puts "Warning: unrecognised setting $i"
+}
+
+if {![exists device]} {
+ puts $USAGE
+ exit 1
+}
+
+# save stdin and stdout tty settings
+# note that stdin and stdout are probably the same file descriptor,
+# but it doesn't hurt to treat them independently
+set stdin_save [stdin tty]
+set stdout_save [stdout tty]
+
+try {
+ set f [open $device r+]
+} on error msg {
+ puts "Failed to open $device"
+ return 1
+}
+
+if {[$f lock] == 0} {
+ puts "Device is in use: $device"
+ return 1
+}
+
+try {
+ $f tty {*}$settings
+} on error msg {
+ puts "$device: $msg"
+ return 1
+}
+
+puts "\[$device\] Use ~. to exit"
+
+$f ndelay 1
+$f buffering none
+
+stdin tty input raw
+stdin ndelay 1
+
+stdout tty output raw
+stdout buffering none
+
+set status ""
+set tilde 0
+set tosend {}
+
+# To avoid sending too much data and blocking,
+# this sends str in chunks of 1000 bytes via writable
+proc output-on-writable {fh str} {
+ # Add it to the buffer to send
+ append ::tosend($fh) $str
+
+ if {[string length [$fh writable]] == 0} {
+ # Start the writable event handler
+ $fh writable [list output-is-writable $fh]
+ }
+}
+
+# This is the writable callback
+proc output-is-writable {fh} {
+ global tosend
+ set buf $tosend($fh)
+ if {[string bytelength $buf] >= 1000} {
+ set tosend($fh) [string byterange $buf 1000 end]
+ set buf [string byterange $buf 0 999]
+ } else {
+ set tosend($fh) {}
+ # All sent, so cancel the writable event handler
+ $fh writable {}
+ }
+ $fh puts -nonewline $buf
+}
+
+proc bgerror {args} {
+ set status $args
+ incr ::done
+}
+
+# I/O loop
+
+$f readable {
+ set c [$f read]
+ if {[$f eof]} {
+ set status "$device: disconnected"
+ incr done
+ break
+ }
+ output-on-writable stdout $c
+}
+
+proc tilde_timeout {} {
+ global tilde f
+ if {$tilde} {
+ output-on-writable $f ~
+ set tilde 0
+ }
+}
+
+stdin readable {
+ set c [stdin read]
+ # may receive more than one char here, but only need to consider
+ # ~. processing if we receive them as separate chars
+ if {$tilde == 0 && $c eq "~"} {
+ incr tilde
+ # Need ~. within 1 second of each other
+ after 1000 tilde_timeout
+ } else {
+ if {$tilde} {
+ after cancel tilde_timeout
+ set tilde 0
+ if {$c eq "."} {
+ incr done
+ return
+ }
+ output-on-writable $f ~
+ }
+ output-on-writable $f $c
+ }
+}
+
+vwait done
+
+# restore previous settings
+stdin tty {*}$stdin_save
+stdout tty {*}$stdout_save
+
+puts $status
diff --git a/examples/unix.client b/examples/unix.client
new file mode 100644
index 0000000..12a5bf8
--- /dev/null
+++ b/examples/unix.client
@@ -0,0 +1,9 @@
+# Example of sending via a connected tcp socket
+
+set s [socket unix unix.tmp]
+
+foreach i [range 1 20] {
+ $s puts "expr {1 << $i}"
+
+ puts [$s gets]
+}
diff --git a/examples/unix.dgram.client b/examples/unix.dgram.client
new file mode 100644
index 0000000..d9dd8ca
--- /dev/null
+++ b/examples/unix.dgram.client
@@ -0,0 +1,18 @@
+# Example of sending from an unconnected socket
+
+# Now sending via a connected udp socket
+
+set s [socket unix.dgram unix.sock]
+$s buffering none
+
+puts "dgram socket [$s sockname] connected to [$s peername]"
+
+foreach i [range 5 10] {
+ # Socket is connected, so can just use puts here
+ # No need to flush because we set 'buffering none' above.
+ $s puts -nonewline "$i * $i"
+ #$s flush
+
+ # Receive the response - max length of 100
+ puts [$s recvfrom 100]
+}
diff --git a/examples/unix.dgram.server b/examples/unix.dgram.server
new file mode 100644
index 0000000..43ada19
--- /dev/null
+++ b/examples/unix.dgram.server
@@ -0,0 +1,35 @@
+# Example of a udp server which sends a response
+
+# Listen on port 20000. No host specified means 0.0.0.0
+file delete unix.sock
+set s [socket unix.dgram.server unix.sock]
+
+puts "Listening on dgram socket [$s sockname]"
+
+set count 0
+
+# For each request...
+$s readable {
+ # Get the request (max 80 chars) - need the source address
+ set buf [$s recvfrom 80 addr]
+
+ puts -nonewline "read '$buf' from client $addr"
+
+ try {
+ set result "$buf = [expr $buf]"
+ } on error {msg} {
+ set result "Error: $buf => $msg"
+ }
+
+ puts ", sending '$result' to client $addr"
+
+ # Send the result back to where it came from
+ $s sendto $result $addr
+}
+
+# Handle signals so the socket is removed on exit
+signal handle SIGINT SIGTERM
+
+catch -signal {
+ vwait done
+}
diff --git a/examples/unix.server b/examples/unix.server
new file mode 100644
index 0000000..fa52992
--- /dev/null
+++ b/examples/unix.server
@@ -0,0 +1,48 @@
+# Example of a unix domain stream server which sends a response
+
+file delete unix.tmp
+set s [socket unix.server unix.tmp]
+
+puts "Listening on [$s sockname]"
+
+$s readable {
+ # Clean up children
+ wait -nohang 0
+ set sock [$s accept]
+
+ # Make this server forking so we can accept multiple
+ # simultaneous connections
+ if {[os.fork] == 0} {
+ # We don't want the unix domain path to be deleted here
+ $s close -nodelete
+
+ $sock buffering line
+
+ # Get the requests, one line at a time an evaluate
+ while {[$sock gets buf] >= 0} {
+ set buf [string trim $buf]
+ if {$buf in {? help}} {
+ set result "Enter any Tcl command to run in the server"
+ } else {
+ try {
+ set result [eval $buf]
+ set result [string map [list \\ \\\\ \n \\n \r \\r] $result]
+ } on error {msg} {
+ set result "Error: $buf => $msg"
+ }
+ }
+
+ # Send the result back to where it came from
+ $sock puts $result
+ }
+ }
+
+ $sock close
+}
+
+# Handle signals so the socket is removed on exit
+signal handle SIGINT SIGTERM
+
+catch -signal {
+ vwait done
+}
diff --git a/initjimsh.tcl b/initjimsh.tcl
index f929a27..1aab707 100644
--- a/initjimsh.tcl
+++ b/initjimsh.tcl
@@ -43,4 +43,37 @@ if {$tcl_platform(platform) eq "windows"} {
set jim::argv0 [string map {\\ /} $jim::argv0]
}
+# Set a global variable here so that custom commands can be added post hoc
+set tcl::autocomplete_commands {info tcl::prefix socket namespace array clock file package string dict signal history}
+
+# Simple interactive command line completion callback
+# Explicitly knows about some commands that support "-commands"
+proc tcl::autocomplete {prefix} {
+ if {[set space [string first " " $prefix]] != -1} {
+ set cmd [string range $prefix 0 $space-1]
+ if {$cmd in $::tcl::autocomplete_commands || [info channel $cmd] ne ""} {
+ set arg [string range $prefix $space+1 end]
+ # Add any results from -commands
+ return [lmap p [$cmd -commands] {
+ if {![string match "${arg}*" $p]} continue
+ function "$cmd $p"
+ }]
+ }
+ }
+ # Find matching files.
+ if {[string match "source *" $prefix]} {
+ set path [string range $prefix 7 end]
+ return [lmap p [glob -nocomplain "${path}*"] {
+ function "source $p"
+ }]
+ }
+ # Find matching commands, omitting results containing spaces
+ return [lmap p [lsort [info commands $prefix*]] {
+ if {[string match "* *" $p]} {
+ continue
+ }
+ function $p
+ }]
+}
+
_jimsh_init
diff --git a/jim-aio.c b/jim-aio.c
index fb8577f..ddfc486 100644
--- a/jim-aio.c
+++ b/jim-aio.c
@@ -39,26 +39,34 @@
#include "jimautoconf.h"
+#ifndef _GNU_SOURCE
#define _GNU_SOURCE
+#endif
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
+#include <assert.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#include <sys/stat.h>
#endif
#include "jim.h"
+#include "jimiocompat.h"
#if defined(HAVE_SYS_SOCKET_H) && defined(HAVE_SELECT) && defined(HAVE_NETINET_IN_H) && defined(HAVE_NETDB_H) && defined(HAVE_ARPA_INET_H)
#include <sys/socket.h>
#include <netinet/in.h>
+#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <netdb.h>
#ifdef HAVE_SYS_UN_H
#include <sys/un.h>
#endif
+#define HAVE_SOCKETS
+#elif defined (__MINGW32__)
+/* currently mingw32 doesn't support sockets, but has pipe, fdopen */
#else
#define JIM_ANSIC
#endif
@@ -68,6 +76,10 @@
#include <openssl/err.h>
#endif
+#ifdef HAVE_TERMIOS_H
+#include <jim-tty.h>
+#endif
+
#include "jim-eventloop.h"
#include "jim-subcmd.h"
@@ -82,6 +94,7 @@
#endif
#define AIO_KEEPOPEN 1
+#define AIO_NODELETE 2
#if defined(JIM_IPV6)
#define IPV6 1
@@ -91,16 +104,29 @@
#define PF_INET6 0
#endif
#endif
+#if defined(HAVE_SYS_UN_H) && defined(PF_UNIX)
+#define UNIX_SOCKETS 1
+#else
+#define UNIX_SOCKETS 0
+#endif
-#define JimCheckStreamError(interp, af) af->fops->error(af)
+#ifdef JIM_ANSIC
+/* no fdopen() with ANSIC, so can't support these */
+#undef HAVE_PIPE
+#undef HAVE_SOCKETPAIR
+#endif
-#if !defined(JIM_ANSIC) && !defined(JIM_BOOTSTRAP)
+#if defined(HAVE_SOCKETS) && !defined(JIM_BOOTSTRAP)
+/* Avoid type punned pointers */
union sockaddr_any {
struct sockaddr sa;
struct sockaddr_in sin;
#if IPV6
struct sockaddr_in6 sin6;
#endif
+#if UNIX_SOCKETS
+ struct sockaddr_un sun;
+#endif
};
#ifndef HAVE_INET_NTOP
@@ -172,7 +198,7 @@ static int stdio_error(const AioFile *af)
}
#endif
#ifdef ECONNABORTED
- if (errno != ECONNABORTED) {
+ if (errno == ECONNABORTED) {
return JIM_OK;
}
#endif
@@ -209,7 +235,7 @@ static int ssl_reader(struct AioFile *af, char *buf, int len)
static const char *ssl_getline(struct AioFile *af, char *buf, int len)
{
- int i;
+ size_t i;
for (i = 0; i < len + 1; i++) {
if (SSL_read(af->ssl, &buf[i], 1) != 1) {
if (i == 0) {
@@ -241,9 +267,9 @@ static const char *ssl_strerror(struct AioFile *af)
if (err) {
return ERR_error_string(err, NULL);
}
-
- /* should not happen */
- return "unknown SSL error";
+ else {
+ return stdio_strerror(af);
+ }
}
static int ssl_verify(struct AioFile *af)
@@ -275,10 +301,73 @@ static const JimAioFopsType ssl_fops = {
static int JimAioSubCmdProc(Jim_Interp *interp, int argc, Jim_Obj *const *argv);
static AioFile *JimMakeChannel(Jim_Interp *interp, FILE *fh, int fd, Jim_Obj *filename,
- const char *hdlfmt, int family, const char *mode);
+ const char *hdlfmt, int family, const char *mode, int flags);
+
+#if defined(HAVE_SOCKETS) && !defined(JIM_BOOTSTRAP)
+#ifndef HAVE_GETADDRINFO
+/*
+ * Poor man's getaddrinfo().
+ * hints->ai_family must be set and must be PF_INET or PF_INET6
+ * Only returns the first matching result.
+ * servname must be numeric.
+ */
+struct addrinfo {
+ int ai_family;
+ socklen_t ai_addrlen;
+ struct sockaddr *ai_addr; /* simply points to ai_storage */
+ union sockaddr_any ai_storage;
+};
-#if !defined(JIM_ANSIC) && !defined(JIM_BOOTSTRAP)
-static int JimParseIPv6Address(Jim_Interp *interp, const char *hostport, union sockaddr_any *sa, int *salen)
+static int getaddrinfo(const char *hostname, const char *servname,
+ const struct addrinfo *hints, struct addrinfo **res)
+{
+ struct hostent *he;
+ char *end;
+ unsigned long port = strtoul(servname, &end, 10);
+ if (port == 0 || port > 65536 || *end) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if ((he = gethostbyname(hostname)) != NULL) {
+ int i;
+ for (i = 0; he->h_addr_list[i]; i++) {
+ if (he->h_addrtype == hints->ai_family) {
+ struct addrinfo *ai = malloc(sizeof(*ai));
+ memset(ai, 0, sizeof(*ai));
+ ai->ai_family = he->h_addrtype;
+ ai->ai_addr = &ai->ai_storage.sa;
+ if (ai->ai_family == PF_INET) {
+ ai->ai_addrlen = sizeof(ai->ai_storage.sin);
+ ai->ai_storage.sin.sin_family = he->h_addrtype;
+ assert(sizeof(ai->ai_storage.sin.sin_addr) == he->h_length);
+ memcpy(&ai->ai_storage.sin.sin_addr, he->h_addr_list[i], he->h_length);
+ ai->ai_storage.sin.sin_port = htons(port);
+ }
+#if IPV6
+ else {
+ ai->ai_addrlen = sizeof(ai->ai_storage.sin6);
+ ai->ai_storage.sin6.sin6_family = he->h_addrtype;
+ assert(sizeof(ai->ai_storage.sin6.sin6_addr) == he->h_length);
+ memcpy(&ai->ai_storage.sin6.sin6_addr, he->h_addr_list[i], he->h_length);
+ ai->ai_storage.sin6.sin6_port = htons(port);
+ }
+#endif
+ *res = ai;
+ return 0;
+ }
+ }
+ }
+ return ENOENT;
+}
+
+static void freeaddrinfo(struct addrinfo *ai)
+{
+ free(ai);
+}
+#endif
+
+static int JimParseIPv6Address(Jim_Interp *interp, const char *hostport, union sockaddr_any *sa, socklen_t *salen)
{
#if IPV6
/*
@@ -323,16 +412,13 @@ static int JimParseIPv6Address(Jim_Interp *interp, const char *hostport, union s
memset(&req, '\0', sizeof(req));
req.ai_family = PF_INET6;
- if (getaddrinfo(sthost, NULL, &req, &ai)) {
+ if (getaddrinfo(sthost, stport, &req, &ai)) {
Jim_SetResultFormatted(interp, "Not a valid address: %s", hostport);
ret = JIM_ERR;
}
else {
- memcpy(&sa->sin, ai->ai_addr, ai->ai_addrlen);
+ memcpy(&sa->sin6, ai->ai_addr, ai->ai_addrlen);
*salen = ai->ai_addrlen;
-
- sa->sin.sin_port = htons(atoi(stport));
-
freeaddrinfo(ai);
}
Jim_Free(sthost);
@@ -344,7 +430,7 @@ static int JimParseIPv6Address(Jim_Interp *interp, const char *hostport, union s
#endif
}
-static int JimParseIpAddress(Jim_Interp *interp, const char *hostport, union sockaddr_any *sa, int *salen)
+static int JimParseIpAddress(Jim_Interp *interp, const char *hostport, union sockaddr_any *sa, socklen_t *salen)
{
/* An IPv4 addr/port looks like:
* 192.168.1.5
@@ -357,6 +443,8 @@ static int JimParseIpAddress(Jim_Interp *interp, const char *hostport, union soc
char *sthost = NULL;
const char *stport;
int ret = JIM_OK;
+ struct addrinfo req;
+ struct addrinfo *ai;
stport = strrchr(hostport, ':');
if (!stport) {
@@ -369,37 +457,16 @@ static int JimParseIpAddress(Jim_Interp *interp, const char *hostport, union soc
stport++;
}
- {
-#ifdef HAVE_GETADDRINFO
- struct addrinfo req;
- struct addrinfo *ai;
- memset(&req, '\0', sizeof(req));
- req.ai_family = PF_INET;
-
- if (getaddrinfo(sthost, NULL, &req, &ai)) {
- ret = JIM_ERR;
- }
- else {
- memcpy(&sa->sin, ai->ai_addr, ai->ai_addrlen);
- *salen = ai->ai_addrlen;
- freeaddrinfo(ai);
- }
-#else
- struct hostent *he;
+ memset(&req, '\0', sizeof(req));
+ req.ai_family = PF_INET;
+ if (getaddrinfo(sthost, stport, &req, &ai)) {
ret = JIM_ERR;
-
- if ((he = gethostbyname(sthost)) != NULL) {
- if (he->h_length == sizeof(sa->sin.sin_addr)) {
- *salen = sizeof(sa->sin);
- sa->sin.sin_family= he->h_addrtype;
- memcpy(&sa->sin.sin_addr, he->h_addr, he->h_length); /* set address */
- ret = JIM_OK;
- }
- }
-#endif
-
- sa->sin.sin_port = htons(atoi(stport));
+ }
+ else {
+ memcpy(&sa->sin, ai->ai_addr, ai->ai_addrlen);
+ *salen = ai->ai_addrlen;
+ freeaddrinfo(ai);
}
Jim_Free(sthost);
@@ -410,46 +477,97 @@ static int JimParseIpAddress(Jim_Interp *interp, const char *hostport, union soc
return ret;
}
-#ifdef HAVE_SYS_UN_H
-static int JimParseDomainAddress(Jim_Interp *interp, const char *path, struct sockaddr_un *sa)
+#if UNIX_SOCKETS
+static int JimParseDomainAddress(Jim_Interp *interp, const char *path, union sockaddr_any *sa, socklen_t *salen)
{
- sa->sun_family = PF_UNIX;
- snprintf(sa->sun_path, sizeof(sa->sun_path), "%s", path);
+ sa->sun.sun_family = PF_UNIX;
+ snprintf(sa->sun.sun_path, sizeof(sa->sun.sun_path), "%s", path);
+ *salen = strlen(sa->sun.sun_path) + 1 + sizeof(sa->sun.sun_family);
return JIM_OK;
}
#endif
+static int JimParseSocketAddress(Jim_Interp *interp, int family, const char *addr, union sockaddr_any *sa, socklen_t *salen)
+{
+ switch (family) {
+#if UNIX_SOCKETS
+ case PF_UNIX:
+ return JimParseDomainAddress(interp, addr, sa, salen);
+#endif
+ case PF_INET6:
+ return JimParseIPv6Address(interp, addr, sa, salen);
+ case PF_INET:
+ return JimParseIpAddress(interp, addr, sa, salen);
+ }
+ return JIM_ERR;
+}
+
/**
- * Format that address in 'sa' as a string and store in variable 'varObjPtr'
+ * Format that address in 'sa' as a string and return it as a zero-refcount object.
+ *
*/
-static int JimFormatIpAddress(Jim_Interp *interp, Jim_Obj *varObjPtr, const union sockaddr_any *sa)
+static Jim_Obj *JimFormatSocketAddress(Jim_Interp *interp, const union sockaddr_any *sa, socklen_t salen)
{
/* INET6_ADDRSTRLEN is 46. Add some for [] and port */
char addrbuf[60];
-
+ const char *addr = addrbuf;
+ int addrlen = -1;
+
+ switch (sa->sa.sa_family) {
+#if UNIX_SOCKETS
+ case PF_UNIX:
+ addr = sa->sun.sun_path;
+ addrlen = salen - 1 - sizeof(sa->sun.sun_family);
+ if (addrlen < 0) {
+ addrlen = 0;
+ }
+ break;
+#endif
#if IPV6
- if (sa->sa.sa_family == PF_INET6) {
- addrbuf[0] = '[';
- /* Allow 9 for []:65535\0 */
- inet_ntop(sa->sa.sa_family, &sa->sin6.sin6_addr, addrbuf + 1, sizeof(addrbuf) - 9);
- snprintf(addrbuf + strlen(addrbuf), 8, "]:%d", ntohs(sa->sin.sin_port));
- }
- else
+ case PF_INET6:
+ addrbuf[0] = '[';
+ /* Allow 9 for []:65535\0 */
+ inet_ntop(sa->sa.sa_family, &sa->sin6.sin6_addr, addrbuf + 1, sizeof(addrbuf) - 9);
+ snprintf(addrbuf + strlen(addrbuf), 8, "]:%d", ntohs(sa->sin6.sin6_port));
+ break;
#endif
- if (sa->sa.sa_family == PF_INET) {
- /* Allow 7 for :65535\0 */
- inet_ntop(sa->sa.sa_family, &sa->sin.sin_addr, addrbuf, sizeof(addrbuf) - 7);
- snprintf(addrbuf + strlen(addrbuf), 7, ":%d", ntohs(sa->sin.sin_port));
- }
- else {
- /* recvfrom still works on unix domain sockets, etc */
- addrbuf[0] = 0;
+ case PF_INET:
+ /* Allow 7 for :65535\0 */
+ inet_ntop(sa->sa.sa_family, &sa->sin.sin_addr, addrbuf, sizeof(addrbuf) - 7);
+ snprintf(addrbuf + strlen(addrbuf), 7, ":%d", ntohs(sa->sin.sin_port));
+ break;
+
+ default:
+ /* Otherwise just an empty address */
+ addr = "";
+ fprintf(stderr, "%s:%d", __FILE__, __LINE__);
+ break;
}
- return Jim_SetVariable(interp, varObjPtr, Jim_NewStringObj(interp, addrbuf, -1));
+ return Jim_NewStringObj(interp, addr, addrlen);
+}
+
+static int JimSetVariableSocketAddress(Jim_Interp *interp, Jim_Obj *varObjPtr, const union sockaddr_any *sa, socklen_t salen)
+{
+ int ret;
+ Jim_Obj *objPtr = JimFormatSocketAddress(interp, sa, salen);
+ Jim_IncrRefCount(objPtr);
+ ret = Jim_SetVariable(interp, varObjPtr, objPtr);
+ Jim_DecrRefCount(interp, objPtr);
+ return ret;
}
+static Jim_Obj *aio_sockname(Jim_Interp *interp, AioFile *af)
+{
+ union sockaddr_any sa;
+ socklen_t salen = sizeof(sa);
+
+ if (getsockname(af->fd, &sa.sa, &salen) < 0) {
+ return NULL;
+ }
+ return JimFormatSocketAddress(interp, &sa, salen);
+}
#endif /* JIM_BOOTSTRAP */
static const char *JimAioErrorString(AioFile *af)
@@ -472,12 +590,34 @@ static void JimAioSetError(Jim_Interp *interp, Jim_Obj *name)
}
}
+static int JimCheckStreamError(Jim_Interp *interp, AioFile *af)
+{
+ int ret = af->fops->error(af);
+ if (ret) {
+ JimAioSetError(interp, af->filename);
+ }
+ return ret;
+}
+
static void JimAioDelProc(Jim_Interp *interp, void *privData)
{
AioFile *af = privData;
JIM_NOTUSED(interp);
+#if UNIX_SOCKETS
+ if (af->addr_family == PF_UNIX && (af->openFlags & AIO_NODELETE) == 0) {
+ /* If this is bound, delete the socket file now */
+ Jim_Obj *filenameObj = aio_sockname(interp, af);
+ if (filenameObj) {
+ if (Jim_Length(filenameObj)) {
+ remove(Jim_String(filenameObj));
+ }
+ Jim_FreeNewObj(interp, filenameObj);
+ }
+ }
+#endif
+
Jim_DecrRefCount(interp, af->filename);
#ifdef jim_ext_eventloop
@@ -490,7 +630,6 @@ static void JimAioDelProc(Jim_Interp *interp, void *privData)
SSL_free(af->ssl);
}
#endif
-
if (!(af->openFlags & AIO_KEEPOPEN)) {
fclose(af->fp);
}
@@ -585,6 +724,16 @@ FILE *Jim_AioFilehandle(Jim_Interp *interp, Jim_Obj *command)
return af->fp;
}
+static int aio_cmd_getfd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ AioFile *af = Jim_CmdPrivData(interp);
+
+ fflush(af->fp);
+ Jim_SetResultInt(interp, fileno(af->fp));
+
+ return JIM_OK;
+}
+
static int aio_cmd_copy(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
AioFile *af = Jim_CmdPrivData(interp);
@@ -603,15 +752,21 @@ static int aio_cmd_copy(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
}
while (count < maxlen) {
- char ch;
+ /* A reasonable compromise between stack size and speed */
+ char buf[AIO_BUF_LEN];
+ jim_wide len = maxlen - count;
+ if (len > sizeof(buf)) {
+ len = sizeof(buf);
+ }
- if (af->fops->reader(af, &ch, 1) != 1) {
+ len = af->fops->reader(af, buf, len);
+ if (len <= 0) {
break;
}
- if (outf->fops->writer(outf, &ch, 1) != 1) {
+ if (outf->fops->writer(outf, buf, len) != len) {
break;
}
- count++;
+ count += len;
}
if (JimCheckStreamError(interp, af) || JimCheckStreamError(interp, outf)) {
@@ -720,7 +875,7 @@ static int aio_cmd_isatty(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
return JIM_OK;
}
-#if !defined(JIM_ANSIC) && !defined(JIM_BOOTSTRAP)
+#if defined(HAVE_SOCKETS) && !defined(JIM_BOOTSTRAP)
static int aio_cmd_recvfrom(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
AioFile *af = Jim_CmdPrivData(interp);
@@ -746,7 +901,7 @@ static int aio_cmd_recvfrom(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, buf, rlen));
if (argc > 1) {
- return JimFormatIpAddress(interp, argv[1], &sa);
+ return JimSetVariableSocketAddress(interp, argv[1], &sa, salen);
}
return JIM_OK;
@@ -761,14 +916,9 @@ static int aio_cmd_sendto(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
const char *wdata;
union sockaddr_any sa;
const char *addr = Jim_String(argv[1]);
- int salen;
+ socklen_t salen;
- if (IPV6 && af->addr_family == PF_INET6) {
- if (JimParseIPv6Address(interp, addr, &sa, &salen) != JIM_OK) {
- return JIM_ERR;
- }
- }
- else if (JimParseIpAddress(interp, addr, &sa, &salen) != JIM_OK) {
+ if (JimParseSocketAddress(interp, af->addr_family, addr, &sa, &salen) != JIM_OK) {
return JIM_ERR;
}
wdata = Jim_GetString(argv[0], &wlen);
@@ -788,23 +938,50 @@ static int aio_cmd_accept(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
AioFile *af = Jim_CmdPrivData(interp);
int sock;
union sockaddr_any sa;
- socklen_t addrlen = sizeof(sa);
+ socklen_t salen = sizeof(sa);
- sock = accept(af->fd, &sa.sa, &addrlen);
+ sock = accept(af->fd, &sa.sa, &salen);
if (sock < 0) {
JimAioSetError(interp, NULL);
return JIM_ERR;
}
if (argc > 0) {
- if (JimFormatIpAddress(interp, argv[0], &sa) != JIM_OK) {
+ if (JimSetVariableSocketAddress(interp, argv[0], &sa, salen) != JIM_OK) {
return JIM_ERR;
}
}
/* Create the file command */
return JimMakeChannel(interp, NULL, sock, Jim_NewStringObj(interp, "accept", -1),
- "aio.sockstream%ld", af->addr_family, "r+") ? JIM_OK : JIM_ERR;
+ "aio.sockstream%ld", af->addr_family, "r+", AIO_NODELETE) ? JIM_OK : JIM_ERR;
+}
+
+static int aio_cmd_sockname(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ AioFile *af = Jim_CmdPrivData(interp);
+ Jim_Obj *objPtr = aio_sockname(interp, af);
+
+ if (objPtr == NULL) {
+ JimAioSetError(interp, NULL);
+ return JIM_ERR;
+ }
+ Jim_SetResult(interp, objPtr);
+ return JIM_OK;
+}
+
+static int aio_cmd_peername(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ AioFile *af = Jim_CmdPrivData(interp);
+ union sockaddr_any sa;
+ socklen_t salen = sizeof(sa);
+
+ if (getpeername(af->fd, &sa.sa, &salen) < 0) {
+ JimAioSetError(interp, NULL);
+ return JIM_ERR;
+ }
+ Jim_SetResult(interp, JimFormatSocketAddress(interp, &sa, salen));
+ return JIM_OK;
}
static int aio_cmd_listen(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
@@ -847,23 +1024,38 @@ static int aio_cmd_eof(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
static int aio_cmd_close(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
if (argc == 3) {
-#if !defined(JIM_ANSIC) && defined(HAVE_SHUTDOWN)
- static const char * const options[] = { "r", "w", NULL };
- enum { OPT_R, OPT_W, };
- int option;
+ int option = -1;
+#if defined(HAVE_SOCKETS)
+ static const char * const options[] = { "r", "w", "-nodelete", NULL };
+ enum { OPT_R, OPT_W, OPT_NODELETE };
AioFile *af = Jim_CmdPrivData(interp);
if (Jim_GetEnum(interp, argv[2], options, &option, NULL, JIM_ERRMSG) != JIM_OK) {
return JIM_ERR;
}
- if (shutdown(af->fd, option == OPT_R ? SHUT_RD : SHUT_WR) == 0) {
- return JIM_OK;
- }
- JimAioSetError(interp, NULL);
-#else
- Jim_SetResultString(interp, "async close not supported", -1);
#endif
- return JIM_ERR;
+ switch (option) {
+#if defined(HAVE_SHUTDOWN)
+ case OPT_R:
+ case OPT_W:
+ if (shutdown(af->fd, option == OPT_R ? SHUT_RD : SHUT_WR) == 0) {
+ return JIM_OK;
+ }
+ JimAioSetError(interp, NULL);
+ return JIM_ERR;
+#endif
+#if UNIX_SOCKETS
+ case OPT_NODELETE:
+ if (af->addr_family == PF_UNIX) {
+ af->openFlags |= AIO_NODELETE;
+ break;
+ }
+ /* fall through */
+#endif
+ default:
+ Jim_SetResultString(interp, "not supported", -1);
+ return JIM_ERR;
+ }
}
return Jim_DeleteCommand(interp, Jim_String(argv[0]));
@@ -938,6 +1130,107 @@ static int aio_cmd_ndelay(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
}
#endif
+#if defined(HAVE_SOCKETS) && !defined(JIM_BOOTSTRAP)
+#define SOCKOPT_BOOL 0
+#define SOCKOPT_INT 1
+#define SOCKOPT_TIMEVAL 2 /* not currently supported */
+
+static const struct sockopt_def {
+ const char *name;
+ int level;
+ int opt;
+ int type; /* SOCKOPT_xxx */
+} sockopts[] = {
+#ifdef SOL_SOCKET
+#ifdef SO_BROADCAST
+ { "broadcast", SOL_SOCKET, SO_BROADCAST },
+#endif
+#ifdef SO_DEBUG
+ { "debug", SOL_SOCKET, SO_DEBUG },
+#endif
+#ifdef SO_KEEPALIVE
+ { "keepalive", SOL_SOCKET, SO_KEEPALIVE },
+#endif
+#ifdef SO_NOSIGPIPE
+ { "nosigpipe", SOL_SOCKET, SO_NOSIGPIPE },
+#endif
+#ifdef SO_OOBINLINE
+ { "oobinline", SOL_SOCKET, SO_OOBINLINE },
+#endif
+#ifdef SO_SNDBUF
+ { "sndbuf", SOL_SOCKET, SO_SNDBUF, SOCKOPT_INT },
+#endif
+#ifdef SO_RCVBUF
+ { "rcvbuf", SOL_SOCKET, SO_RCVBUF, SOCKOPT_INT },
+#endif
+#if 0 && defined(SO_SNDTIMEO)
+ { "sndtimeo", SOL_SOCKET, SO_SNDTIMEO, SOCKOPT_TIMEVAL },
+#endif
+#if 0 && defined(SO_RCVTIMEO)
+ { "rcvtimeo", SOL_SOCKET, SO_RCVTIMEO, SOCKOPT_TIMEVAL },
+#endif
+#endif
+#ifdef IPPROTO_TCP
+#ifdef TCP_NODELAY
+ { "tcp_nodelay", IPPROTO_TCP, TCP_NODELAY },
+#endif
+#endif
+};
+
+static int aio_cmd_sockopt(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ AioFile *af = Jim_CmdPrivData(interp);
+ size_t i;
+
+ if (argc == 0) {
+ Jim_Obj *dictObjPtr = Jim_NewListObj(interp, NULL, 0);
+ for (i = 0; i < sizeof(sockopts) / sizeof(*sockopts); i++) {
+ int value = 0;
+ socklen_t len = sizeof(value);
+ if (getsockopt(af->fd, sockopts[i].level, sockopts[i].opt, (void *)&value, &len) == 0) {
+ if (sockopts[i].type == SOCKOPT_BOOL) {
+ value = !!value;
+ }
+ Jim_ListAppendElement(interp, dictObjPtr, Jim_NewStringObj(interp, sockopts[i].name, -1));
+ Jim_ListAppendElement(interp, dictObjPtr, Jim_NewIntObj(interp, value));
+ }
+ }
+ Jim_SetResult(interp, dictObjPtr);
+ return JIM_OK;
+ }
+ if (argc == 1) {
+ return -1;
+ }
+
+ /* Set an option */
+ for (i = 0; i < sizeof(sockopts) / sizeof(*sockopts); i++) {
+ if (strcmp(Jim_String(argv[0]), sockopts[i].name) == 0) {
+ int on;
+ if (sockopts[i].type == SOCKOPT_BOOL) {
+ if (Jim_GetBoolean(interp, argv[1], &on) != JIM_OK) {
+ return JIM_ERR;
+ }
+ }
+ else {
+ long longval;
+ if (Jim_GetLong(interp, argv[1], &longval) != JIM_OK) {
+ return JIM_ERR;
+ }
+ on = longval;
+ }
+ if (setsockopt(af->fd, sockopts[i].level, sockopts[i].opt, (void *)&on, sizeof(on)) < 0) {
+ Jim_SetResultFormatted(interp, "Failed to set %#s: %s", argv[0], strerror(errno));
+ return JIM_ERR;
+ }
+ return JIM_OK;
+ }
+ }
+ /* Not found */
+ Jim_SetResultFormatted(interp, "Unknown sockopt %#s", argv[0]);
+ return JIM_ERR;
+}
+#endif /* JIM_BOOTSTRAP */
+
#ifdef HAVE_FSYNC
static int aio_cmd_sync(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
@@ -1060,7 +1353,7 @@ static int aio_cmd_ssl(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
AioFile *af = Jim_CmdPrivData(interp);
SSL *ssl;
SSL_CTX *ssl_ctx;
- int fd, server = 0;
+ int server = 0;
if (argc == 5) {
if (!Jim_CompareStringImmediate(interp, argv[2], "-server")) {
@@ -1069,17 +1362,14 @@ static int aio_cmd_ssl(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
server = 1;
}
else if (argc != 2) {
- Jim_WrongNumArgs(interp, 2, argv, "?-server cert priv?");
- return JIM_ERR;
+ return -1;
}
- fd = fileno(af->fp);
-#if defined(HAVE_DUP)
- fd = dup(fd);
- if (fd < 0) {
+ if (af->ssl) {
+ Jim_SetResultFormatted(interp, "%#s: stream is already ssl", argv[0]);
return JIM_ERR;
}
-#endif
+
ssl_ctx = JimAioSslCtx(interp);
if (ssl_ctx == NULL) {
return JIM_ERR;
@@ -1087,11 +1377,7 @@ static int aio_cmd_ssl(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
ssl = SSL_new(ssl_ctx);
if (ssl == NULL) {
-#if defined(HAVE_DUP)
- close(fd);
-#endif
- Jim_SetResultString(interp, ERR_error_string(ERR_get_error(), NULL), -1);
- return JIM_ERR;
+ goto out;
}
SSL_set_cipher_list(ssl, "ALL");
@@ -1119,21 +1405,18 @@ static int aio_cmd_ssl(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
}
}
- af = JimMakeChannel(interp, NULL, fd, NULL, "aio.sslstream%ld", af->addr_family, "r+");
- if (af == NULL) {
- goto out;
- }
-
af->ssl = ssl;
af->fops = &ssl_fops;
+ /* Set the command name as the result */
+ Jim_SetResult(interp, argv[0]);
+
return JIM_OK;
out:
-#if defined(HAVE_DUP)
- close(fd);
-#endif
- SSL_free(ssl);
+ if (ssl) {
+ SSL_free(ssl);
+ }
Jim_SetResultString(interp, ERR_error_string(ERR_get_error(), NULL), -1);
return JIM_ERR;
}
@@ -1149,9 +1432,7 @@ static int aio_cmd_verify(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
ret = af->fops->verify(af);
if (ret != JIM_OK) {
- if (JimCheckStreamError(interp, af)) {
- JimAioSetError(interp, af->filename);
- } else {
+ if (JimCheckStreamError(interp, af) == JIM_OK) {
Jim_SetResultString(interp, "failed to verify the connection authenticity", -1);
}
}
@@ -1164,13 +1445,21 @@ static int aio_cmd_lock(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
AioFile *af = Jim_CmdPrivData(interp);
struct flock fl;
+ int lockmode = F_SETLK;
+
+ if (argc == 1) {
+ if (!Jim_CompareStringImmediate(interp, argv[0], "-wait")) {
+ return -1;
+ }
+ lockmode = F_SETLKW;
+ }
fl.l_start = 0;
fl.l_len = 0;
fl.l_type = F_WRLCK;
fl.l_whence = SEEK_SET;
- switch (fcntl(af->fd, F_SETLK, &fl))
+ switch (fcntl(af->fd, lockmode, &fl))
{
case 0:
Jim_SetResultInt(interp, 1);
@@ -1207,6 +1496,51 @@ static int aio_cmd_unlock(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
}
#endif /* JIM_BOOTSTRAP */
+#if defined(HAVE_TERMIOS_H) && !defined(JIM_BOOTSTRAP)
+static int aio_cmd_tty(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ AioFile *af = Jim_CmdPrivData(interp);
+ Jim_Obj *dictObjPtr;
+ int ret;
+
+ if (argc == 0) {
+ /* get the current settings as a dictionary */
+ dictObjPtr = Jim_GetTtySettings(interp, af->fd);
+ if (dictObjPtr == NULL) {
+ JimAioSetError(interp, NULL);
+ return JIM_ERR;
+ }
+ Jim_SetResult(interp, dictObjPtr);
+ return JIM_OK;
+ }
+
+ if (argc > 1) {
+ /* Convert name value arguments to a dictionary */
+ dictObjPtr = Jim_NewListObj(interp, argv, argc);
+ }
+ else {
+ /* The settings are already given as a list */
+ dictObjPtr = argv[0];
+ }
+ Jim_IncrRefCount(dictObjPtr);
+
+ if (Jim_ListLength(interp, dictObjPtr) % 2) {
+ /* Must be a valid dictionary */
+ Jim_DecrRefCount(interp, dictObjPtr);
+ return -1;
+ }
+
+ ret = Jim_SetTtySettings(interp, af->fd, dictObjPtr);
+ if (ret < 0) {
+ JimAioSetError(interp, NULL);
+ ret = JIM_ERR;
+ }
+ Jim_DecrRefCount(interp, dictObjPtr);
+
+ return ret;
+}
+#endif /* JIM_BOOTSTRAP */
+
static const jim_subcmd_type aio_command_table[] = {
{ "read",
"?-nonewline? ?len?",
@@ -1222,6 +1556,13 @@ static const jim_subcmd_type aio_command_table[] = {
2,
/* Description: Copy up to 'size' bytes to the given filehandle, or to eof if no size. */
},
+ { "getfd",
+ NULL,
+ aio_cmd_getfd,
+ 0,
+ 0,
+ /* Description: Internal command to return the underlying file descriptor. */
+ },
{ "gets",
"?var?",
aio_cmd_gets,
@@ -1243,7 +1584,7 @@ static const jim_subcmd_type aio_command_table[] = {
0,
/* Description: Is the file descriptor a tty? */
},
-#if !defined(JIM_ANSIC) && !defined(JIM_BOOTSTRAP)
+#if defined(HAVE_SOCKETS) && !defined(JIM_BOOTSTRAP)
{ "recvfrom",
"len ?addrvar?",
aio_cmd_recvfrom,
@@ -1272,6 +1613,27 @@ static const jim_subcmd_type aio_command_table[] = {
1,
/* Description: Set the listen backlog for server socket */
},
+ { "sockopt",
+ "?opt 0|1?",
+ aio_cmd_sockopt,
+ 0,
+ 2,
+ /* Description: Return a dictionary of sockopts, or set the value of a sockopt */
+ },
+ { "sockname",
+ NULL,
+ aio_cmd_sockname,
+ 0,
+ 0,
+ /* Description: Returns the local address of the socket, if any */
+ },
+ { "peername",
+ NULL,
+ aio_cmd_peername,
+ 0,
+ 0,
+ /* Description: Returns the remote address of the socket, if any */
+ },
#endif /* JIM_BOOTSTRAP */
{ "flush",
NULL,
@@ -1364,7 +1726,8 @@ static const jim_subcmd_type aio_command_table[] = {
/* Description: Returns script, or invoke exception-script when oob data, {} to remove */
},
#endif
-#if defined(JIM_SSL) && !defined(JIM_BOOTSTRAP)
+#if !defined(JIM_BOOTSTRAP)
+#if defined(JIM_SSL)
{ "ssl",
"?-server cert priv?",
aio_cmd_ssl,
@@ -1380,14 +1743,14 @@ static const jim_subcmd_type aio_command_table[] = {
0,
/* Description: Verifies the certificate of a SSL/TLS channel */
},
-#endif /* JIM_BOOTSTRAP */
-#if defined(HAVE_STRUCT_FLOCK) && !defined(JIM_BOOTSTRAP)
- { "lock",
+#endif
+#if defined(HAVE_STRUCT_FLOCK)
+ { "lock ?-wait?",
NULL,
aio_cmd_lock,
0,
- 0,
- /* Description: Attempt to get a lock. */
+ 1,
+ /* Description: Attempt to get a lock, possibly waiting */
},
{ "unlock",
NULL,
@@ -1396,6 +1759,16 @@ static const jim_subcmd_type aio_command_table[] = {
0,
/* Description: Relase a lock. */
},
+#endif
+#if defined(HAVE_TERMIOS_H)
+ { "tty",
+ "?baud rate? ?data bits? ?stop bits? ?parity even|odd|none? ?handshake xonxoff|rtscts|none? ?input raw|cooked? ?output raw|cooked? ?echo 0|1? ?vmin n? ?vtime n?",
+ aio_cmd_tty,
+ 0,
+ -1,
+ /* Description: Get or set tty settings - valid only on a tty */
+ },
+#endif
#endif /* JIM_BOOTSTRAP */
{ NULL }
};
@@ -1433,7 +1806,7 @@ static int JimAioOpenCommand(Jim_Interp *interp, int argc,
}
}
#endif
- return JimMakeChannel(interp, NULL, -1, argv[1], "aio.handle%ld", 0, mode) ? JIM_OK : JIM_ERR;
+ return JimMakeChannel(interp, NULL, -1, argv[1], "aio.handle%ld", 0, mode, 0) ? JIM_OK : JIM_ERR;
}
#if defined(JIM_SSL) && !defined(JIM_BOOTSTRAP)
@@ -1443,13 +1816,17 @@ static void JimAioSslContextDelProc(struct Jim_Interp *interp, void *privData)
ERR_free_strings();
}
+#ifdef USE_TLSv1_2_method
+#define TLS_method TLSv1_2_method
+#endif
+
static SSL_CTX *JimAioSslCtx(Jim_Interp *interp)
{
SSL_CTX *ssl_ctx = (SSL_CTX *)Jim_GetAssocData(interp, "ssl_ctx");
if (ssl_ctx == NULL) {
SSL_load_error_strings();
SSL_library_init();
- ssl_ctx = SSL_CTX_new(TLSv1_2_method());
+ ssl_ctx = SSL_CTX_new(TLS_method());
if (ssl_ctx && SSL_CTX_set_default_verify_paths(ssl_ctx)) {
SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_NONE, NULL);
Jim_SetAssocData(interp, "ssl_ctx", JimAioSslContextDelProc, ssl_ctx);
@@ -1475,17 +1852,10 @@ static SSL_CTX *JimAioSslCtx(Jim_Interp *interp)
* Returns the AioFile pointer on sucess or NULL on failure.
*/
static AioFile *JimMakeChannel(Jim_Interp *interp, FILE *fh, int fd, Jim_Obj *filename,
- const char *hdlfmt, int family, const char *mode)
+ const char *hdlfmt, int family, const char *mode, int flags)
{
AioFile *af;
char buf[AIO_CMD_LEN];
- int openFlags = 0;
-
- snprintf(buf, sizeof(buf), hdlfmt, Jim_GetId(interp));
-
- if (fh) {
- openFlags = AIO_KEEPOPEN;
- }
snprintf(buf, sizeof(buf), hdlfmt, Jim_GetId(interp));
if (!filename) {
@@ -1495,17 +1865,17 @@ static AioFile *JimMakeChannel(Jim_Interp *interp, FILE *fh, int fd, Jim_Obj *fi
Jim_IncrRefCount(filename);
if (fh == NULL) {
-#if !defined(JIM_ANSIC)
if (fd >= 0) {
+#ifndef JIM_ANSIC
fh = fdopen(fd, mode);
+#endif
}
else
-#endif
fh = fopen(Jim_String(filename), mode);
if (fh == NULL) {
JimAioSetError(interp, filename);
-#if !defined(JIM_ANSIC)
+#ifndef JIM_ANSIC
if (fd >= 0) {
close(fd);
}
@@ -1519,14 +1889,16 @@ static AioFile *JimMakeChannel(Jim_Interp *interp, FILE *fh, int fd, Jim_Obj *fi
af = Jim_Alloc(sizeof(*af));
memset(af, 0, sizeof(*af));
af->fp = fh;
- af->fd = fileno(fh);
af->filename = filename;
+ af->openFlags = flags;
+#ifndef JIM_ANSIC
+ af->fd = fileno(fh);
#ifdef FD_CLOEXEC
- if ((openFlags & AIO_KEEPOPEN) == 0) {
+ if ((flags & AIO_KEEPOPEN) == 0) {
(void)fcntl(af->fd, F_SETFD, FD_CLOEXEC);
}
#endif
- af->openFlags = openFlags;
+#endif
af->addr_family = family;
af->fops = &stdio_fops;
af->ssl = NULL;
@@ -1541,18 +1913,17 @@ static AioFile *JimMakeChannel(Jim_Interp *interp, FILE *fh, int fd, Jim_Obj *fi
return af;
}
-#if defined(HAVE_PIPE) || (defined(HAVE_SOCKETPAIR) && defined(HAVE_SYS_UN_H))
+#if defined(HAVE_PIPE) || (defined(HAVE_SOCKETPAIR) && UNIX_SOCKETS)
/**
* Create a pair of channels. e.g. from pipe() or socketpair()
*/
static int JimMakeChannelPair(Jim_Interp *interp, int p[2], Jim_Obj *filename,
- const char *hdlfmt, int family, const char *mode[2])
+ const char *hdlfmt, int family, const char * const mode[2])
{
- if (JimMakeChannel(interp, NULL, p[0], filename, hdlfmt, family, mode[0])) {
+ if (JimMakeChannel(interp, NULL, p[0], filename, hdlfmt, family, mode[0], 0)) {
Jim_Obj *objPtr = Jim_NewListObj(interp, NULL, 0);
Jim_ListAppendElement(interp, objPtr, Jim_GetResult(interp));
-
- if (JimMakeChannel(interp, NULL, p[1], filename, hdlfmt, family, mode[1])) {
+ if (JimMakeChannel(interp, NULL, p[1], filename, hdlfmt, family, mode[1], 0)) {
Jim_ListAppendElement(interp, objPtr, Jim_GetResult(interp));
Jim_SetResult(interp, objPtr);
return JIM_OK;
@@ -1567,14 +1938,35 @@ static int JimMakeChannelPair(Jim_Interp *interp, int p[2], Jim_Obj *filename,
}
#endif
-#if !defined(JIM_ANSIC) && !defined(JIM_BOOTSTRAP)
+#ifdef HAVE_PIPE
+static int JimAioPipeCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ int p[2];
+ static const char * const mode[2] = { "r", "w" };
+
+ if (argc != 1) {
+ Jim_WrongNumArgs(interp, 1, argv, "");
+ return JIM_ERR;
+ }
+
+ if (pipe(p) != 0) {
+ JimAioSetError(interp, NULL);
+ return JIM_ERR;
+ }
+
+ return JimMakeChannelPair(interp, p, argv[0], "aio.pipe%ld", 0, mode);
+}
+#endif
+
+#if defined(HAVE_SOCKETS) && !defined(JIM_BOOTSTRAP)
static int JimAioSockCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
- const char *hdlfmt = "aio.unknown%ld";
const char *socktypes[] = {
"unix",
"unix.server",
+ "unix.dgram",
+ "unix.dgram.server",
"dgram",
"dgram.server",
"stream",
@@ -1587,6 +1979,8 @@ static int JimAioSockCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
SOCK_UNIX,
SOCK_UNIX_SERVER,
+ SOCK_UNIX_DGRAM,
+ SOCK_UNIX_DGRAM_SERVER,
SOCK_DGRAM_CLIENT,
SOCK_DGRAM_SERVER,
SOCK_STREAM_CLIENT,
@@ -1596,11 +1990,16 @@ static int JimAioSockCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
};
int socktype;
int sock;
- const char *hostportarg = NULL;
- int res;
+ const char *addr = NULL;
+ const char *bind_addr = NULL;
+ const char *connect_addr = NULL;
+ union sockaddr_any sa;
+ socklen_t salen;
int on = 1;
- const char *mode = "r+";
+ int reuse = 0;
+ int do_listen = 0;
int family = PF_INET;
+ int type = SOCK_STREAM;
Jim_Obj *argv0 = argv[0];
int ipv6 = 0;
@@ -1622,208 +2021,116 @@ static int JimAioSockCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
}
if (Jim_GetEnum(interp, argv[1], socktypes, &socktype, "socket type", JIM_ERRMSG) != JIM_OK)
- return JIM_ERR;
+ return Jim_CheckShowCommands(interp, argv[1], socktypes);
Jim_SetEmptyResult(interp);
- hdlfmt = "aio.sock%ld";
-
if (argc > 2) {
- hostportarg = Jim_String(argv[2]);
+ addr = Jim_String(argv[2]);
}
+#if defined(HAVE_SOCKETPAIR) && UNIX_SOCKETS
+ if (socktype == SOCK_STREAM_SOCKETPAIR) {
+ int p[2];
+ static const char * const mode[2] = { "r+", "r+" };
+
+ if (addr || ipv6) {
+ goto wrongargs;
+ }
+
+ if (socketpair(PF_UNIX, SOCK_STREAM, 0, p) < 0) {
+ JimAioSetError(interp, NULL);
+ return JIM_ERR;
+ }
+ return JimMakeChannelPair(interp, p, argv[1], "aio.sockpair%ld", PF_UNIX, mode);
+ }
+#endif
+
+#if defined(HAVE_PIPE)
+ if (socktype == SOCK_STREAM_PIPE) {
+ if (addr || ipv6) {
+ goto wrongargs;
+ }
+ return JimAioPipeCommand(interp, 1, &argv[1]);
+ }
+#endif
+
+ /* Now all these socket types are very similar */
switch (socktype) {
case SOCK_DGRAM_CLIENT:
- if (argc == 2) {
- /* No address, so an unconnected dgram socket */
- sock = socket(family, SOCK_DGRAM, 0);
- if (sock < 0) {
- JimAioSetError(interp, NULL);
- return JIM_ERR;
- }
- break;
- }
- /* fall through */
- case SOCK_STREAM_CLIENT:
- {
- union sockaddr_any sa;
- int salen;
-
- if (argc != 3) {
- goto wrongargs;
- }
+ connect_addr = addr;
+ type = SOCK_DGRAM;
+ break;
- if (ipv6) {
- if (JimParseIPv6Address(interp, hostportarg, &sa, &salen) != JIM_OK) {
- return JIM_ERR;
- }
- }
- else if (JimParseIpAddress(interp, hostportarg, &sa, &salen) != JIM_OK) {
- return JIM_ERR;
- }
- sock = socket(family, (socktype == SOCK_DGRAM_CLIENT) ? SOCK_DGRAM : SOCK_STREAM, 0);
- if (sock < 0) {
- JimAioSetError(interp, NULL);
- return JIM_ERR;
- }
- res = connect(sock, &sa.sa, salen);
- if (res) {
- JimAioSetError(interp, argv[2]);
- close(sock);
- return JIM_ERR;
- }
+ case SOCK_STREAM_CLIENT:
+ if (addr == NULL) {
+ goto wrongargs;
}
+ connect_addr = addr;
break;
case SOCK_STREAM_SERVER:
- case SOCK_DGRAM_SERVER:
- {
- union sockaddr_any sa;
- int salen;
-
- if (argc != 3) {
- goto wrongargs;
- }
-
- if (ipv6) {
- if (JimParseIPv6Address(interp, hostportarg, &sa, &salen) != JIM_OK) {
- return JIM_ERR;
- }
- }
- else if (JimParseIpAddress(interp, hostportarg, &sa, &salen) != JIM_OK) {
- return JIM_ERR;
- }
- sock = socket(family, (socktype == SOCK_DGRAM_SERVER) ? SOCK_DGRAM : SOCK_STREAM, 0);
- if (sock < 0) {
- JimAioSetError(interp, NULL);
- return JIM_ERR;
- }
-
- /* Enable address reuse */
- setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on));
+ if (addr == NULL) {
+ goto wrongargs;
+ }
+ bind_addr = addr;
+ reuse = 1;
+ do_listen = 1;
+ break;
- res = bind(sock, &sa.sa, salen);
- if (res) {
- JimAioSetError(interp, argv[2]);
- close(sock);
- return JIM_ERR;
- }
- if (socktype == SOCK_STREAM_SERVER) {
- res = listen(sock, 5);
- if (res) {
- JimAioSetError(interp, NULL);
- close(sock);
- return JIM_ERR;
- }
- }
- hdlfmt = "aio.socksrv%ld";
+ case SOCK_DGRAM_SERVER:
+ if (addr == NULL) {
+ goto wrongargs;
}
+ bind_addr = addr;
+ type = SOCK_DGRAM;
+ reuse = 1;
break;
-#ifdef HAVE_SYS_UN_H
+#if UNIX_SOCKETS
case SOCK_UNIX:
- {
- struct sockaddr_un sa;
- socklen_t len;
-
- if (argc != 3 || ipv6) {
- goto wrongargs;
- }
-
- if (JimParseDomainAddress(interp, hostportarg, &sa) != JIM_OK) {
- JimAioSetError(interp, argv[2]);
- return JIM_ERR;
- }
- family = PF_UNIX;
- sock = socket(PF_UNIX, SOCK_STREAM, 0);
- if (sock < 0) {
- JimAioSetError(interp, NULL);
- return JIM_ERR;
- }
- len = strlen(sa.sun_path) + 1 + sizeof(sa.sun_family);
- res = connect(sock, (struct sockaddr *)&sa, len);
- if (res) {
- JimAioSetError(interp, argv[2]);
- close(sock);
- return JIM_ERR;
- }
- hdlfmt = "aio.sockunix%ld";
- break;
+ if (addr == NULL) {
+ goto wrongargs;
}
+ connect_addr = addr;
+ family = PF_UNIX;
+ break;
- case SOCK_UNIX_SERVER:
- {
- struct sockaddr_un sa;
- socklen_t len;
-
- if (argc != 3 || ipv6) {
- goto wrongargs;
- }
-
- if (JimParseDomainAddress(interp, hostportarg, &sa) != JIM_OK) {
- JimAioSetError(interp, argv[2]);
- return JIM_ERR;
- }
- family = PF_UNIX;
- sock = socket(PF_UNIX, SOCK_STREAM, 0);
- if (sock < 0) {
- JimAioSetError(interp, NULL);
- return JIM_ERR;
- }
- len = strlen(sa.sun_path) + 1 + sizeof(sa.sun_family);
- res = bind(sock, (struct sockaddr *)&sa, len);
- if (res) {
- JimAioSetError(interp, argv[2]);
- close(sock);
+ case SOCK_UNIX_DGRAM:
+ connect_addr = addr;
+ type = SOCK_DGRAM;
+ family = PF_UNIX;
+ /* A dgram unix domain socket client needs to bind
+ * to a temporary address to allow the server to
+ * send responses
+ */
+ {
+ int tmpfd = Jim_MakeTempFile(interp, NULL, 1);
+ if (tmpfd < 0) {
return JIM_ERR;
}
- res = listen(sock, 5);
- if (res) {
- JimAioSetError(interp, NULL);
- close(sock);
- return JIM_ERR;
- }
- hdlfmt = "aio.sockunixsrv%ld";
- break;
+ close(tmpfd);
+ /* This will be valid until a result is next set, which is long enough here */
+ bind_addr = Jim_String(Jim_GetResult(interp));
}
-#endif
-
-#if defined(HAVE_SOCKETPAIR) && defined(HAVE_SYS_UN_H)
- case SOCK_STREAM_SOCKETPAIR:
- {
- int p[2];
- static const char *mode[2] = { "r+", "r+" };
-
- if (argc != 2 || ipv6) {
- goto wrongargs;
- }
+ break;
- if (socketpair(PF_UNIX, SOCK_STREAM, 0, p) < 0) {
- JimAioSetError(interp, NULL);
- return JIM_ERR;
- }
- return JimMakeChannelPair(interp, p, argv[1], "aio.sockpair%ld", PF_UNIX, mode);
+ case SOCK_UNIX_SERVER:
+ if (addr == NULL) {
+ goto wrongargs;
}
+ bind_addr = addr;
+ family = PF_UNIX;
+ do_listen = 1;
break;
-#endif
-
-#if defined(HAVE_PIPE)
- case SOCK_STREAM_PIPE:
- {
- int p[2];
- static const char *mode[2] = { "r", "w" };
- if (argc != 2 || ipv6) {
- goto wrongargs;
- }
-
- if (pipe(p) < 0) {
- JimAioSetError(interp, NULL);
- return JIM_ERR;
- }
-
- return JimMakeChannelPair(interp, p, argv[1], "aio.pipe%ld", 0, mode);
+ case SOCK_UNIX_DGRAM_SERVER:
+ if (addr == NULL) {
+ goto wrongargs;
}
+ bind_addr = addr;
+ type = SOCK_DGRAM;
+ family = PF_UNIX;
break;
#endif
@@ -1832,62 +2139,48 @@ static int JimAioSockCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
return JIM_ERR;
}
- return JimMakeChannel(interp, NULL, sock, argv[1], hdlfmt, family, mode) ? JIM_OK : JIM_ERR;
-}
-#endif /* JIM_BOOTSTRAP */
-
-/**
- * Returns the file descriptor of a writable, newly created temp file
- * or -1 on error.
- *
- * On success, leaves the filename in the interpreter result, otherwise
- * leaves an error message.
- */
-int Jim_MakeTempFile(Jim_Interp *interp, const char *template)
-{
-#ifdef HAVE_MKSTEMP
- int fd;
- mode_t mask;
- Jim_Obj *filenameObj;
-
- if (template == NULL) {
- const char *tmpdir = getenv("TMPDIR");
- if (tmpdir == NULL || *tmpdir == '\0' || access(tmpdir, W_OK) != 0) {
- tmpdir = "/tmp/";
+ /* Now do all the steps necessary for the given socket type */
+ sock = socket(family, type, 0);
+ if (sock < 0) {
+ JimAioSetError(interp, NULL);
+ return JIM_ERR;
+ }
+ if (bind_addr) {
+ if (JimParseSocketAddress(interp, family, bind_addr, &sa, &salen) != JIM_OK) {
+ close(sock);
+ return JIM_ERR;
}
- filenameObj = Jim_NewStringObj(interp, tmpdir, -1);
- if (tmpdir[0] && tmpdir[strlen(tmpdir) - 1] != '/') {
- Jim_AppendString(interp, filenameObj, "/", 1);
+ if (reuse) {
+ setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on));
+ }
+ if (bind(sock, &sa.sa, salen)) {
+ Jim_SetResultFormatted(interp, "%s: bind: %s", bind_addr, strerror(errno));
+ close(sock);
+ return JIM_ERR;
}
- Jim_AppendString(interp, filenameObj, "tcl.tmp.XXXXXX", -1);
}
- else {
- filenameObj = Jim_NewStringObj(interp, template, -1);
+ if (connect_addr) {
+ if (JimParseSocketAddress(interp, family, connect_addr, &sa, &salen) != JIM_OK) {
+ close(sock);
+ return JIM_ERR;
+ }
+ if (connect(sock, &sa.sa, salen)) {
+ Jim_SetResultFormatted(interp, "%s: connect: %s", connect_addr, strerror(errno));
+ close(sock);
+ return JIM_ERR;
+ }
}
-
-#if defined(S_IRWXG) && defined(S_IRWXO)
- mask = umask(S_IXUSR | S_IRWXG | S_IRWXO);
-#else
- /* MinGW does not have group/owner permissions */
- mask = umask(S_IXUSR);
-#endif
-
- /* Update the template name directly with the filename */
- fd = mkstemp(filenameObj->bytes);
- umask(mask);
- if (fd < 0) {
- JimAioSetError(interp, filenameObj);
- Jim_FreeNewObj(interp, filenameObj);
- return -1;
+ if (do_listen) {
+ if (listen(sock, 5)) {
+ Jim_SetResultFormatted(interp, "listen: %s", strerror(errno));
+ close(sock);
+ return JIM_ERR;
+ }
}
- Jim_SetResult(interp, filenameObj);
- return fd;
-#else
- Jim_SetResultString(interp, "platform has no tempfile support", -1);
- return -1;
-#endif
+ return JimMakeChannel(interp, NULL, sock, argv[1], "aio.sock%ld", family, "r+", 0) ? JIM_OK : JIM_ERR;
}
+#endif /* JIM_BOOTSTRAP */
#if defined(JIM_SSL) && !defined(JIM_BOOTSTRAP)
static int JimAioLoadSSLCertsCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
@@ -1921,14 +2214,17 @@ int Jim_aioInit(Jim_Interp *interp)
#endif
Jim_CreateCommand(interp, "open", JimAioOpenCommand, NULL, NULL);
-#ifndef JIM_ANSIC
+#ifdef HAVE_SOCKETS
Jim_CreateCommand(interp, "socket", JimAioSockCommand, NULL, NULL);
#endif
+#ifdef HAVE_PIPE
+ Jim_CreateCommand(interp, "pipe", JimAioPipeCommand, NULL, NULL);
+#endif
/* Create filehandles for stdin, stdout and stderr */
- JimMakeChannel(interp, stdin, -1, NULL, "stdin", 0, "r");
- JimMakeChannel(interp, stdout, -1, NULL, "stdout", 0, "w");
- JimMakeChannel(interp, stderr, -1, NULL, "stderr", 0, "w");
+ JimMakeChannel(interp, stdin, -1, NULL, "stdin", 0, "r", AIO_KEEPOPEN);
+ JimMakeChannel(interp, stdout, -1, NULL, "stdout", 0, "w", AIO_KEEPOPEN);
+ JimMakeChannel(interp, stderr, -1, NULL, "stderr", 0, "w", AIO_KEEPOPEN);
return JIM_OK;
}
diff --git a/jim-array.c b/jim-array.c
index 39cd168..4213bc3 100644
--- a/jim-array.c
+++ b/jim-array.c
@@ -54,7 +54,8 @@
static int array_cmd_exists(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
/* Just a regular [info exists] */
- Jim_SetResultInt(interp, Jim_GetVariable(interp, argv[0], 0) != 0);
+ Jim_Obj *dictObj = Jim_GetVariable(interp, argv[0], JIM_UNSHARED);
+ Jim_SetResultInt(interp, dictObj && Jim_DictSize(interp, dictObj) != -1);
return JIM_OK;
}
@@ -78,8 +79,7 @@ static int array_cmd_get(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
}
}
- /* Return a list of keys and values where the keys match the pattern */
- return Jim_DictValues(interp, objPtr, patternObj);
+ return Jim_DictMatchTypes(interp, objPtr, patternObj, JIM_DICTMATCH_KEYS, JIM_DICTMATCH_KEYS | JIM_DICTMATCH_VALUES);
}
static int array_cmd_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
@@ -90,7 +90,7 @@ static int array_cmd_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
return JIM_OK;
}
- return Jim_DictKeys(interp, objPtr, argc == 1 ? NULL : argv[1]);
+ return Jim_DictMatchTypes(interp, objPtr, argc == 1 ? NULL : argv[1], JIM_DICTMATCH_KEYS, JIM_DICTMATCH_KEYS);
}
static int array_cmd_unset(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
@@ -115,7 +115,9 @@ static int array_cmd_unset(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
}
if (Jim_DictPairs(interp, objPtr, &dictValuesObj, &len) != JIM_OK) {
- return JIM_ERR;
+ /* Variable is not an array - tclsh ignores this and returns nothing - be compatible */
+ Jim_SetResultString(interp, "", -1);
+ return JIM_OK;
}
/* Create a new object with the values which don't match */
@@ -142,7 +144,9 @@ static int array_cmd_size(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
if (objPtr) {
len = Jim_DictSize(interp, objPtr);
if (len < 0) {
- return JIM_ERR;
+ /* Variable is not an array - tclsh ignores this and returns 0 - be compatible */
+ Jim_SetResultInt(interp, 0);
+ return JIM_OK;
}
}
diff --git a/jim-clock.c b/jim-clock.c
index 69fb966..cc24319 100644
--- a/jim-clock.c
+++ b/jim-clock.c
@@ -4,47 +4,91 @@
* Implements the clock command
*/
-/* For strptime() */
+#include "jimautoconf.h"
+
+/* For strptime() - currently nothing sets this */
+#ifdef STRPTIME_NEEDS_XOPEN_SOURCE
#ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE 500
#endif
+#endif
+
+/* For timegm() */
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
-#include "jimautoconf.h"
#include <jim-subcmd.h>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
+struct clock_options {
+ int gmt;
+ const char *format;
+};
+
+/* Parses the options ?-format string? ?-gmt boolean? and fills in *opts.
+ * Any options not present are not set.
+ * argc must be even.
+ *
+ * Returns JIM_OK or JIM_ERR and sets an error result.
+ */
+static int parse_clock_options(Jim_Interp *interp, int argc, Jim_Obj *const *argv, struct clock_options *opts)
+{
+ static const char * const options[] = { "-gmt", "-format", NULL };
+ enum { OPT_GMT, OPT_FORMAT, };
+ int i;
+
+ for (i = 0; i < argc; i += 2) {
+ int option;
+ if (Jim_GetEnum(interp, argv[i], options, &option, NULL, JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) {
+ return JIM_ERR;
+ }
+ switch (option) {
+ case OPT_GMT:
+ if (Jim_GetBoolean(interp, argv[i + 1], &opts->gmt) != JIM_OK) {
+ return JIM_ERR;
+ }
+ break;
+ case OPT_FORMAT:
+ opts->format = Jim_String(argv[i + 1]);
+ break;
+ }
+ }
+ return JIM_OK;
+}
+
static int clock_cmd_format(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
/* How big is big enough? */
char buf[100];
time_t t;
- long seconds;
+ jim_wide seconds;
+ struct clock_options options = { 0, "%a %b %d %H:%M:%S %Z %Y" };
+ struct tm *tm;
- const char *format = "%a %b %d %H:%M:%S %Z %Y";
-
- if (argc == 2 || (argc == 3 && !Jim_CompareStringImmediate(interp, argv[1], "-format"))) {
- return -1;
+ if (Jim_GetWide(interp, argv[0], &seconds) != JIM_OK) {
+ return JIM_ERR;
}
-
- if (argc == 3) {
- format = Jim_String(argv[2]);
+ if (argc % 2 == 0) {
+ return -1;
}
-
- if (Jim_GetLong(interp, argv[0], &seconds) != JIM_OK) {
+ if (parse_clock_options(interp, argc - 1, argv + 1, &options) == JIM_ERR) {
return JIM_ERR;
}
+
t = seconds;
+ tm = options.gmt ? gmtime(&t) : localtime(&t);
- if (strftime(buf, sizeof(buf), format, localtime(&t)) == 0) {
- Jim_SetResultString(interp, "format string too long", -1);
+ if (tm == NULL || strftime(buf, sizeof(buf), options.format, tm) == 0) {
+ Jim_SetResultString(interp, "format string too long or invalid time", -1);
return JIM_ERR;
}
@@ -54,27 +98,52 @@ static int clock_cmd_format(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
}
#ifdef HAVE_STRPTIME
+/* Implement timegm() that doesn't require messing with timezone
+ * Based on: http://howardhinnant.github.io/date_algorithms.html#days_from_civil
+ */
+static time_t jim_timegm(const struct tm *tm)
+{
+ int m = tm->tm_mon + 1;
+ int y = 1900 + tm->tm_year - (m <= 2);
+ int era = (y >= 0 ? y : y - 399) / 400;
+ unsigned yoe = (unsigned)(y - era * 400);
+ unsigned doy = (153 * (m + (m > 2 ? -3 : 9)) + 2) / 5 + tm->tm_mday - 1;
+ unsigned doe = yoe * 365 + yoe / 4 - yoe / 100 + doy;
+ long days = (era * 146097 + (int)doe - 719468);
+ int secs = tm->tm_hour * 3600 + tm->tm_min * 60 + tm->tm_sec;
+
+ return days * 24 * 60 * 60 + secs;
+}
+
static int clock_cmd_scan(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
char *pt;
struct tm tm;
- time_t now = time(0);
+ time_t now = time(NULL);
+ /* No default format */
+ struct clock_options options = { 0, NULL };
- if (!Jim_CompareStringImmediate(interp, argv[1], "-format")) {
+ if (argc % 2 == 0) {
+ return -1;
+ }
+
+ if (parse_clock_options(interp, argc - 1, argv + 1, &options) == JIM_ERR) {
+ return JIM_ERR;
+ }
+ if (options.format == NULL) {
return -1;
}
- /* Initialise with the current date/time */
localtime_r(&now, &tm);
- pt = strptime(Jim_String(argv[0]), Jim_String(argv[2]), &tm);
+ pt = strptime(Jim_String(argv[0]), options.format, &tm);
if (pt == 0 || *pt != 0) {
Jim_SetResultString(interp, "Failed to parse time according to format", -1);
return JIM_ERR;
}
/* Now convert into a time_t */
- Jim_SetResultInt(interp, mktime(&tm));
+ Jim_SetResultInt(interp, options.gmt ? jim_timegm(&tm) : mktime(&tm));
return JIM_OK;
}
@@ -110,13 +179,6 @@ static int clock_cmd_millis(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
}
static const jim_subcmd_type clock_command_table[] = {
- { "seconds",
- NULL,
- clock_cmd_seconds,
- 0,
- 0,
- /* Description: Returns the current time as seconds since the epoch */
- },
{ "clicks",
NULL,
clock_cmd_micros,
@@ -124,6 +186,13 @@ static const jim_subcmd_type clock_command_table[] = {
0,
/* Description: Returns the current time in 'clicks' */
},
+ { "format",
+ "seconds ?-format string? ?-gmt boolean?",
+ clock_cmd_format,
+ 1,
+ 5,
+ /* Description: Format the given time */
+ },
{ "microseconds",
NULL,
clock_cmd_micros,
@@ -138,22 +207,22 @@ static const jim_subcmd_type clock_command_table[] = {
0,
/* Description: Returns the current time in milliseconds */
},
- { "format",
- "seconds ?-format format?",
- clock_cmd_format,
- 1,
- 3,
- /* Description: Format the given time */
- },
#ifdef HAVE_STRPTIME
{ "scan",
- "str -format format",
+ "str -format format ?-gmt boolean?",
clock_cmd_scan,
3,
- 3,
+ 5,
/* Description: Determine the time according to the given format */
},
#endif
+ { "seconds",
+ NULL,
+ clock_cmd_seconds,
+ 0,
+ 0,
+ /* Description: Returns the current time as seconds since the epoch */
+ },
{ NULL }
};
diff --git a/jim-eventloop.c b/jim-eventloop.c
index 1bbd171..78aae12 100644
--- a/jim-eventloop.c
+++ b/jim-eventloop.c
@@ -41,29 +41,34 @@
#include <jim.h>
#include <jim-eventloop.h>
-/* POSIX includes */
-#include <sys/time.h>
-#include <sys/types.h>
+#include <time.h>
#include <string.h>
-#include <unistd.h>
#include <errno.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
#if defined(__MINGW32__)
#include <windows.h>
#include <winsock.h>
-#define msleep Sleep
+#ifndef HAVE_USLEEP
+#define usleep(US) Sleep((US) / 1000)
+#define HAVE_USLEEP
+#endif
#else
+#include <sys/types.h>
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
+#endif
#ifndef HAVE_USLEEP
/* XXX: Implement this in terms of select() or nanosleep() */
-#define msleep(MS) sleep((MS) / 1000)
+#define usleep(US) sleep((US) / 1000000)
#warning "sub-second sleep not supported"
-#else
-#define msleep(MS) sleep((MS) / 1000); usleep(((MS) % 1000) * 1000);
-#endif
#endif
/* --- */
@@ -83,8 +88,8 @@ typedef struct Jim_FileEvent
typedef struct Jim_TimeEvent
{
jim_wide id; /* time event identifier. */
- long initialms; /* initial relative timer value */
- jim_wide when; /* milliseconds */
+ jim_wide initialus; /* initial relative timer value in microseconds */
+ jim_wide when; /* microseconds */
Jim_TimeProc *timeProc;
Jim_EventFinalizerProc *finalizerProc;
void *clientData;
@@ -115,7 +120,7 @@ int Jim_EvalObjBackground(Jim_Interp *interp, Jim_Obj *scriptObjPtr)
retval = Jim_EvalObj(interp, scriptObjPtr);
interp->framePtr = savedFramePtr;
/* Try to report the error (if any) via the bgerror proc */
- if (retval != JIM_OK && !eventLoop->suppress_bgerror) {
+ if (retval != JIM_OK && retval != JIM_RETURN && !eventLoop->suppress_bgerror) {
Jim_Obj *objv[2];
int rc = JIM_ERR;
@@ -185,18 +190,31 @@ void Jim_DeleteFileHandler(Jim_Interp *interp, int fd, int mask)
}
/**
- * Returns the time since interp creation in milliseconds.
+ * Returns the time since interp creation in microseconds.
*/
-static jim_wide JimGetTime(Jim_EventLoop *eventLoop)
+static jim_wide JimGetTimeUsec(Jim_EventLoop *eventLoop)
{
+ long long now;
struct timeval tv;
- gettimeofday(&tv, NULL);
+#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC_RAW)
+ struct timespec ts;
- return (jim_wide)(tv.tv_sec - eventLoop->timeBase) * 1000 + tv.tv_usec / 1000;
+ if (clock_gettime(CLOCK_MONOTONIC_RAW, &ts) == 0) {
+ now = ts.tv_sec * 1000000LL + ts.tv_nsec / 1000;
+ }
+ else
+#endif
+ {
+ gettimeofday(&tv, NULL);
+
+ now = tv.tv_sec * 1000000LL + tv.tv_usec;
+ }
+
+ return now - eventLoop->timeBase;
}
-jim_wide Jim_CreateTimeHandler(Jim_Interp *interp, jim_wide milliseconds,
+jim_wide Jim_CreateTimeHandler(Jim_Interp *interp, jim_wide us,
Jim_TimeProc * proc, void *clientData, Jim_EventFinalizerProc * finalizerProc)
{
Jim_EventLoop *eventLoop = Jim_GetAssocData(interp, "eventloop");
@@ -205,8 +223,8 @@ jim_wide Jim_CreateTimeHandler(Jim_Interp *interp, jim_wide milliseconds,
te = Jim_Alloc(sizeof(*te));
te->id = id;
- te->initialms = milliseconds;
- te->when = JimGetTime(eventLoop) + milliseconds;
+ te->initialus = us;
+ te->when = JimGetTimeUsec(eventLoop) + us;
te->timeProc = proc;
te->finalizerProc = finalizerProc;
te->clientData = clientData;
@@ -307,7 +325,7 @@ jim_wide Jim_DeleteTimeHandler(Jim_Interp *interp, jim_wide id)
if (te) {
jim_wide remain;
- remain = te->when - JimGetTime(eventLoop);
+ remain = te->when - JimGetTimeUsec(eventLoop);
remain = (remain < 0) ? 0 : remain;
Jim_FreeTimeHandler(interp, te);
@@ -334,7 +352,7 @@ jim_wide Jim_DeleteTimeHandler(Jim_Interp *interp, jim_wide id)
*/
int Jim_ProcessEvents(Jim_Interp *interp, int flags)
{
- jim_wide sleep_ms = -1;
+ jim_wide sleep_us = -1;
int processed = 0;
Jim_EventLoop *eventLoop = Jim_GetAssocData(interp, "eventloop");
Jim_FileEvent *fe = eventLoop->fileEventHead;
@@ -356,7 +374,7 @@ int Jim_ProcessEvents(Jim_Interp *interp, int flags)
if (flags & JIM_DONT_WAIT) {
/* Wait no time */
- sleep_ms = 0;
+ sleep_us = 0;
}
else if (flags & JIM_TIME_EVENTS) {
/* The nearest timer is always at the head of the list */
@@ -365,14 +383,14 @@ int Jim_ProcessEvents(Jim_Interp *interp, int flags)
/* Calculate the time missing for the nearest
* timer to fire. */
- sleep_ms = shortest->when - JimGetTime(eventLoop);
- if (sleep_ms < 0) {
- sleep_ms = 0;
+ sleep_us = shortest->when - JimGetTimeUsec(eventLoop);
+ if (sleep_us < 0) {
+ sleep_us = 0;
}
}
else {
/* Wait forever */
- sleep_ms = -1;
+ sleep_us = -1;
}
}
@@ -400,10 +418,10 @@ int Jim_ProcessEvents(Jim_Interp *interp, int flags)
fe = fe->next;
}
- if (sleep_ms >= 0) {
+ if (sleep_us >= 0) {
tvp = &tv;
- tvp->tv_sec = sleep_ms / 1000;
- tvp->tv_usec = 1000 * (sleep_ms % 1000);
+ tvp->tv_sec = sleep_us / 1000000;
+ tvp->tv_usec = sleep_us % 1000000;
}
retval = select(maxfd + 1, &rfds, &wfds, &efds, tvp);
@@ -429,7 +447,8 @@ int Jim_ProcessEvents(Jim_Interp *interp, int flags)
mask |= JIM_EVENT_EXCEPTION;
if (mask) {
- if (fe->fileProc(interp, fe->clientData, mask) != JIM_OK) {
+ int ret = fe->fileProc(interp, fe->clientData, mask);
+ if (ret != JIM_OK && ret != JIM_RETURN) {
/* Remove the element on handler error */
Jim_DeleteFileHandler(interp, fd, mask);
/* At this point fe is no longer valid - it will be assigned below */
@@ -451,8 +470,8 @@ int Jim_ProcessEvents(Jim_Interp *interp, int flags)
}
}
#else
- if (sleep_ms > 0) {
- msleep(sleep_ms);
+ if (sleep_us > 0) {
+ usleep(sleep_us);
}
#endif
@@ -466,7 +485,7 @@ int Jim_ProcessEvents(Jim_Interp *interp, int flags)
te = te->next;
continue;
}
- if (JimGetTime(eventLoop) >= te->when) {
+ if (JimGetTimeUsec(eventLoop) >= te->when) {
id = te->id;
/* Remove from the list before executing */
Jim_RemoveTimeHandler(eventLoop, id);
@@ -611,7 +630,8 @@ static void JimAfterTimeEventFinalizer(Jim_Interp *interp, void *clientData)
static int JimELAfterCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
Jim_EventLoop *eventLoop = Jim_CmdPrivData(interp);
- jim_wide ms = 0, id;
+ double ms = 0;
+ jim_wide id;
Jim_Obj *objPtr, *idObjPtr;
static const char * const options[] = {
"cancel", "info", "idle", NULL
@@ -624,7 +644,7 @@ static int JimELAfterCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
Jim_WrongNumArgs(interp, 1, argv, "option ?arg ...?");
return JIM_ERR;
}
- if (Jim_GetWide(interp, argv[1], &ms) != JIM_OK) {
+ if (Jim_GetDouble(interp, argv[1], &ms) != JIM_OK) {
if (Jim_GetEnum(interp, argv[1], options, &option, "argument", JIM_ERRMSG) != JIM_OK) {
return JIM_ERR;
}
@@ -632,7 +652,7 @@ static int JimELAfterCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
}
else if (argc == 2) {
/* Simply a sleep */
- msleep(ms);
+ usleep(ms * 1000);
return JIM_OK;
}
@@ -646,7 +666,7 @@ static int JimELAfterCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
case AFTER_CREATE: {
Jim_Obj *scriptObj = Jim_ConcatObj(interp, argc - 2, argv + 2);
Jim_IncrRefCount(scriptObj);
- id = Jim_CreateTimeHandler(interp, ms, JimAfterTimeHandler, scriptObj,
+ id = Jim_CreateTimeHandler(interp, (jim_wide)(ms * 1000), JimAfterTimeHandler, scriptObj,
JimAfterTimeEventFinalizer);
objPtr = Jim_NewStringObj(interp, NULL, 0);
Jim_AppendString(interp, objPtr, "after#", -1);
@@ -704,7 +724,7 @@ static int JimELAfterCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
if (e && e->timeProc == JimAfterTimeHandler) {
Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0);
Jim_ListAppendElement(interp, listObj, e->clientData);
- Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, e->initialms ? "timer" : "idle", -1));
+ Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, e->initialus ? "timer" : "idle", -1));
Jim_SetResult(interp, listObj);
return JIM_OK;
}
diff --git a/jim-exec.c b/jim-exec.c
index c8dc832..67d2f18 100644
--- a/jim-exec.c
+++ b/jim-exec.c
@@ -20,7 +20,9 @@
* express or implied warranty.
*/
+#ifndef _GNU_SOURCE
#define _GNU_SOURCE
+#endif
#include <string.h>
#include <ctype.h>
@@ -91,83 +93,24 @@ int Jim_execInit(Jim_Interp *interp)
#include <errno.h>
#include <signal.h>
+#include "jim-signal.h"
+#include "jimiocompat.h"
+#include <sys/stat.h>
-#if defined(__MINGW32__)
- /* XXX: Should we use this implementation for cygwin too? msvc? */
- #ifndef STRICT
- #define STRICT
- #endif
- #define WIN32_LEAN_AND_MEAN
- #include <windows.h>
- #include <fcntl.h>
-
- typedef HANDLE fdtype;
- typedef HANDLE pidtype;
- #define JIM_BAD_FD INVALID_HANDLE_VALUE
- #define JIM_BAD_PID INVALID_HANDLE_VALUE
- #define JimCloseFd CloseHandle
-
- #define WIFEXITED(STATUS) 1
- #define WEXITSTATUS(STATUS) (STATUS)
- #define WIFSIGNALED(STATUS) 0
- #define WTERMSIG(STATUS) 0
- #define WNOHANG 1
-
- static fdtype JimFileno(FILE *fh);
- static pidtype JimWaitPid(pidtype pid, int *status, int nohang);
- static fdtype JimDupFd(fdtype infd);
- static fdtype JimOpenForRead(const char *filename);
- static FILE *JimFdOpenForRead(fdtype fd);
- static int JimPipe(fdtype pipefd[2]);
- static pidtype JimStartWinProcess(Jim_Interp *interp, char **argv, char *env,
- fdtype inputId, fdtype outputId, fdtype errorId);
- static int JimErrno(void);
-#else
- #include "jim-signal.h"
- #include <unistd.h>
- #include <fcntl.h>
- #include <sys/wait.h>
- #include <sys/stat.h>
-
- typedef int fdtype;
- typedef int pidtype;
- #define JimPipe pipe
- #define JimErrno() errno
- #define JIM_BAD_FD -1
- #define JIM_BAD_PID -1
- #define JimFileno fileno
- #define JimReadFd read
- #define JimCloseFd close
- #define JimWaitPid waitpid
- #define JimDupFd dup
- #define JimFdOpenForRead(FD) fdopen((FD), "r")
- #define JimOpenForRead(NAME) open((NAME), O_RDONLY, 0)
-
- #ifndef HAVE_EXECVPE
- #define execvpe(ARG0, ARGV, ENV) execvp(ARG0, ARGV)
- #endif
-#endif
+struct WaitInfoTable;
-static const char *JimStrError(void);
+static char **JimOriginalEnviron(void);
static char **JimSaveEnv(char **env);
static void JimRestoreEnv(char **env);
static int JimCreatePipeline(Jim_Interp *interp, int argc, Jim_Obj *const *argv,
- pidtype **pidArrayPtr, fdtype *inPipePtr, fdtype *outPipePtr, fdtype *errFilePtr);
-static void JimDetachPids(Jim_Interp *interp, int numPids, const pidtype *pidPtr);
+ pidtype **pidArrayPtr, int *inPipePtr, int *outPipePtr, int *errFilePtr);
+static void JimDetachPids(struct WaitInfoTable *table, int numPids, const pidtype *pidPtr);
static int JimCleanupChildren(Jim_Interp *interp, int numPids, pidtype *pidPtr, Jim_Obj *errStrObj);
-static fdtype JimCreateTemp(Jim_Interp *interp, const char *contents, int len);
-static fdtype JimOpenForWrite(const char *filename, int append);
-static int JimRewindFd(fdtype fd);
-
-static void Jim_SetResultErrno(Jim_Interp *interp, const char *msg)
-{
- Jim_SetResultFormatted(interp, "%s: %s", msg, JimStrError());
-}
+static int Jim_WaitCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv);
-static const char *JimStrError(void)
-{
- return strerror(JimErrno());
-}
+#if defined(__MINGW32__)
+static pidtype JimStartWinProcess(Jim_Interp *interp, char **argv, char **env, int inputId, int outputId, int errorId);
+#endif
/*
* If the last character of 'objPtr' is a newline, then remove
@@ -188,10 +131,10 @@ static void Jim_RemoveTrailingNewline(Jim_Obj *objPtr)
* Read from 'fd', append the data to strObj and close 'fd'.
* Returns 1 if data was added, 0 if not, or -1 on error.
*/
-static int JimAppendStreamToString(Jim_Interp *interp, fdtype fd, Jim_Obj *strObj)
+static int JimAppendStreamToString(Jim_Interp *interp, int fd, Jim_Obj *strObj)
{
char buf[256];
- FILE *fh = JimFdOpenForRead(fd);
+ FILE *fh = fdopen(fd, "r");
int ret = 0;
if (fh == NULL) {
@@ -233,7 +176,7 @@ static char **JimBuildEnv(Jim_Interp *interp)
Jim_Obj *objPtr = Jim_GetGlobalVariableStr(interp, "env", JIM_NONE);
if (!objPtr) {
- return Jim_GetEnviron();
+ return JimOriginalEnviron();
}
/* We build the array as a single block consisting of the pointers followed by
@@ -289,40 +232,16 @@ static void JimFreeEnv(char **env, char **original_environ)
}
}
-#ifndef jim_ext_signal
-/* Implement trivial Jim_SignalId() and Jim_SignalName(), just good enough for JimCheckWaitStatus() */
-const char *Jim_SignalId(int sig)
-{
- static char buf[10];
- snprintf(buf, sizeof(buf), "%d", sig);
- return buf;
-}
-
-const char *Jim_SignalName(int sig)
-{
- return Jim_SignalId(sig);
-}
-#endif
-
-/*
- * Create and store an appropriate value for the global variable $::errorCode
- * Based on pid and waitStatus.
- *
- * Returns JIM_OK for a normal exit with code 0, otherwise returns JIM_ERR.
- *
- * Note that $::errorCode is left unchanged for a normal exit.
- * Details of any abnormal exit is appended to the errStrObj, unless it is NULL.
- */
-static int JimCheckWaitStatus(Jim_Interp *interp, pidtype pid, int waitStatus, Jim_Obj *errStrObj)
+static Jim_Obj *JimMakeErrorCode(Jim_Interp *interp, pidtype pid, int waitStatus, Jim_Obj *errStrObj)
{
- Jim_Obj *errorCode;
+ Jim_Obj *errorCode = Jim_NewListObj(interp, NULL, 0);
- if (WIFEXITED(waitStatus) && WEXITSTATUS(waitStatus) == 0) {
- return JIM_OK;
+ if (pid == JIM_BAD_PID || pid == JIM_NO_PID) {
+ Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, "NONE", -1));
+ Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, (long)pid));
+ Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, -1));
}
- errorCode = Jim_NewListObj(interp, NULL, 0);
-
- if (WIFEXITED(waitStatus)) {
+ else if (WIFEXITED(waitStatus)) {
Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, "CHILDSTATUS", -1));
Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, (long)pid));
Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, WEXITSTATUS(waitStatus)));
@@ -330,14 +249,17 @@ static int JimCheckWaitStatus(Jim_Interp *interp, pidtype pid, int waitStatus, J
else {
const char *type;
const char *action;
+ const char *signame;
if (WIFSIGNALED(waitStatus)) {
type = "CHILDKILLED";
action = "killed";
+ signame = Jim_SignalId(WTERMSIG(waitStatus));
}
else {
type = "CHILDSUSP";
action = "suspended";
+ signame = "none";
}
Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, type, -1));
@@ -350,17 +272,33 @@ static int JimCheckWaitStatus(Jim_Interp *interp, pidtype pid, int waitStatus, J
}
Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, (long)pid));
- Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, Jim_SignalId(WTERMSIG(waitStatus)), -1));
- Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, Jim_SignalName(WTERMSIG(waitStatus)), -1));
+ Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, signame, -1));
+ }
+ return errorCode;
+}
+
+/*
+ * Create and store an appropriate value for the global variable $::errorCode
+ * Based on pid and waitStatus.
+ *
+ * Returns JIM_OK for a normal exit with code 0, otherwise returns JIM_ERR.
+ *
+ * Note that $::errorCode is left unchanged for a normal exit.
+ * Details of any abnormal exit is appended to the errStrObj, unless it is NULL.
+ */
+static int JimCheckWaitStatus(Jim_Interp *interp, pidtype pid, int waitStatus, Jim_Obj *errStrObj)
+{
+ if (WIFEXITED(waitStatus) && WEXITSTATUS(waitStatus) == 0) {
+ return JIM_OK;
}
- Jim_SetGlobalVariableStr(interp, "errorCode", errorCode);
+ Jim_SetGlobalVariableStr(interp, "errorCode", JimMakeErrorCode(interp, pid, waitStatus, errStrObj));
return JIM_ERR;
}
/*
- * Data structures of the following type are used by JimFork and
- * JimWaitPids to keep track of child processes.
+ * Data structures of the following type are used by exec and
+ * wait to keep track of child processes.
*/
struct WaitInfo
@@ -370,10 +308,12 @@ struct WaitInfo
int flags; /* Various flag bits; see below for definitions. */
};
+/* This table is shared by exec and wait */
struct WaitInfoTable {
struct WaitInfo *info; /* Table of outstanding processes */
int size; /* Size of the allocated table */
int used; /* Number of entries in use */
+ int refcount; /* Free the table once the refcount drops to 0 */
};
/*
@@ -392,8 +332,10 @@ static void JimFreeWaitInfoTable(struct Jim_Interp *interp, void *privData)
{
struct WaitInfoTable *table = privData;
- Jim_Free(table->info);
- Jim_Free(table);
+ if (--table->refcount == 0) {
+ Jim_Free(table->info);
+ Jim_Free(table);
+ }
}
static struct WaitInfoTable *JimAllocWaitInfoTable(void)
@@ -401,22 +343,46 @@ static struct WaitInfoTable *JimAllocWaitInfoTable(void)
struct WaitInfoTable *table = Jim_Alloc(sizeof(*table));
table->info = NULL;
table->size = table->used = 0;
+ table->refcount = 1;
return table;
}
+/**
+ * Removes the given pid from the wait table.
+ *
+ * Returns 0 if OK or -1 if not found.
+ */
+static int JimWaitRemove(struct WaitInfoTable *table, pidtype pid)
+{
+ int i;
+
+ /* Find it in the table */
+ for (i = 0; i < table->used; i++) {
+ if (pid == table->info[i].pid) {
+ if (i != table->used - 1) {
+ table->info[i] = table->info[table->used - 1];
+ }
+ table->used--;
+ return 0;
+ }
+ }
+ return -1;
+}
+
/*
* The main [exec] command
*/
static int Jim_ExecCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
- fdtype outputId; /* File id for output pipe. -1 means command overrode. */
- fdtype errorId; /* File id for temporary file containing error output. */
+ int outputId; /* File id for output pipe. -1 means command overrode. */
+ int errorId; /* File id for temporary file containing error output. */
pidtype *pidPtr;
int numPids, result;
int child_siginfo = 1;
Jim_Obj *childErrObj;
Jim_Obj *errStrObj;
+ struct WaitInfoTable *table = Jim_CmdPrivData(interp);
/*
* See if the command is to be run in the background; if so, create
@@ -437,7 +403,7 @@ static int Jim_ExecCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
Jim_ListAppendElement(interp, listObj, Jim_NewIntObj(interp, (long)pidPtr[i]));
}
Jim_SetResult(interp, listObj);
- JimDetachPids(interp, numPids, pidPtr);
+ JimDetachPids(table, numPids, pidPtr);
Jim_Free(pidPtr);
return JIM_OK;
}
@@ -457,7 +423,7 @@ static int Jim_ExecCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
errStrObj = Jim_NewStringObj(interp, "", 0);
/* Read from the output pipe until EOF */
- if (outputId != JIM_BAD_FD) {
+ if (outputId != -1) {
if (JimAppendStreamToString(interp, outputId, errStrObj) < 0) {
result = JIM_ERR;
Jim_SetResultErrno(interp, "error reading from output pipe");
@@ -478,9 +444,9 @@ static int Jim_ExecCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
* Note that unlike Tcl, the presence of stderr output does not cause
* exec to return an error.
*/
- if (errorId != JIM_BAD_FD) {
+ if (errorId != -1) {
int ret;
- JimRewindFd(errorId);
+ lseek(errorId, 0, SEEK_SET);
ret = JimAppendStreamToString(interp, errorId, errStrObj);
if (ret < 0) {
Jim_SetResultErrno(interp, "error reading from error pipe");
@@ -507,6 +473,65 @@ static int Jim_ExecCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
return result;
}
+/**
+ * Does waitpid() on the given pid, and then removes the
+ * entry from the wait table.
+ *
+ * Returns the pid if OK and updates *statusPtr with the status,
+ * or JIM_BAD_PID if the pid was not in the table.
+ */
+static pidtype JimWaitForProcess(struct WaitInfoTable *table, pidtype pid, int *statusPtr)
+{
+ if (JimWaitRemove(table, pid) == 0) {
+ /* wait for it */
+ waitpid(pid, statusPtr, 0);
+ return pid;
+ }
+
+ /* Not found */
+ return JIM_BAD_PID;
+}
+
+/**
+ * Indicates that one or more child processes have been placed in
+ * background and are no longer cared about.
+ * These children can be cleaned up with JimReapDetachedPids().
+ */
+static void JimDetachPids(struct WaitInfoTable *table, int numPids, const pidtype *pidPtr)
+{
+ int j;
+
+ for (j = 0; j < numPids; j++) {
+ /* Find it in the table */
+ int i;
+ for (i = 0; i < table->used; i++) {
+ if (pidPtr[j] == table->info[i].pid) {
+ table->info[i].flags |= WI_DETACHED;
+ break;
+ }
+ }
+ }
+}
+
+/* Use 'name getfd' to get the file descriptor associated with channel 'name'
+ * Returns the file descriptor or -1 on error
+ */
+static int JimGetChannelFd(Jim_Interp *interp, const char *name)
+{
+ Jim_Obj *objv[2];
+
+ objv[0] = Jim_NewStringObj(interp, name, -1);
+ objv[1] = Jim_NewStringObj(interp, "getfd", -1);
+
+ if (Jim_EvalObjVector(interp, 2, objv) == JIM_OK) {
+ jim_wide fd;
+ if (Jim_GetWide(interp, Jim_GetResult(interp), &fd) == JIM_OK) {
+ return fd;
+ }
+ }
+ return -1;
+}
+
static void JimReapDetachedPids(struct WaitInfoTable *table)
{
struct WaitInfo *waitPtr;
@@ -522,7 +547,7 @@ static void JimReapDetachedPids(struct WaitInfoTable *table)
for (count = table->used; count > 0; waitPtr++, count--) {
if (waitPtr->flags & WI_DETACHED) {
int status;
- pidtype pid = JimWaitPid(waitPtr->pid, &status, WNOHANG);
+ pidtype pid = waitpid(waitPtr->pid, &status, WNOHANG);
if (pid == waitPtr->pid) {
/* Process has exited, so remove it from the table */
table->used--;
@@ -536,69 +561,78 @@ static void JimReapDetachedPids(struct WaitInfoTable *table)
}
}
-/**
- * Does waitpid() on the given pid, and then removes the
- * entry from the wait table.
+/*
+ * wait ?-nohang? ?pid?
*
- * Returns the pid if OK and updates *statusPtr with the status,
- * or JIM_BAD_PID if the pid was not in the table.
+ * An interface to waitpid(2)
+ *
+ * Returns a 3 element list.
+ *
+ * If the process has not exited or doesn't exist, returns:
+ *
+ * {NONE x x}
+ *
+ * If the process exited normally, returns:
+ *
+ * {CHILDSTATUS <pid> <exit-status>}
+ *
+ * If the process terminated on a signal, returns:
+ *
+ * {CHILDKILLED <pid> <signal>}
+ *
+ * Otherwise (core dump, stopped, continued, ...), returns:
+ *
+ * {CHILDSUSP <pid> none}
+ *
+ * With no arguments, reaps any finished background processes started by exec ... &
*/
-static pidtype JimWaitForProcess(struct WaitInfoTable *table, pidtype pid, int *statusPtr)
+static int Jim_WaitCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
- int i;
+ struct WaitInfoTable *table = Jim_CmdPrivData(interp);
+ int nohang = 0;
+ pidtype pid;
+ long pidarg;
+ int status;
+ Jim_Obj *errCodeObj;
- /* Find it in the table */
- for (i = 0; i < table->used; i++) {
- if (pid == table->info[i].pid) {
- /* wait for it */
- JimWaitPid(pid, statusPtr, 0);
+ /* With no arguments, reap detached children */
+ if (argc == 1) {
+ JimReapDetachedPids(table);
+ return JIM_OK;
+ }
- /* Remove it from the table */
- if (i != table->used - 1) {
- table->info[i] = table->info[table->used - 1];
- }
- table->used--;
- return pid;
- }
+ if (argc > 1 && Jim_CompareStringImmediate(interp, argv[1], "-nohang")) {
+ nohang = 1;
+ }
+ if (argc != nohang + 2) {
+ Jim_WrongNumArgs(interp, 1, argv, "?-nohang? ?pid?");
+ return JIM_ERR;
+ }
+ if (Jim_GetLong(interp, argv[nohang + 1], &pidarg) != JIM_OK) {
+ return JIM_ERR;
}
- /* Not found */
- return JIM_BAD_PID;
-}
+ pid = waitpid((pidtype)pidarg, &status, nohang ? WNOHANG : 0);
-/**
- * Indicates that one or more child processes have been placed in
- * background and are no longer cared about.
- * These children can be cleaned up with JimReapDetachedPids().
- */
-static void JimDetachPids(Jim_Interp *interp, int numPids, const pidtype *pidPtr)
-{
- int j;
- struct WaitInfoTable *table = Jim_CmdPrivData(interp);
+ errCodeObj = JimMakeErrorCode(interp, pid, status, NULL);
- for (j = 0; j < numPids; j++) {
- /* Find it in the table */
- int i;
- for (i = 0; i < table->used; i++) {
- if (pidPtr[j] == table->info[i].pid) {
- table->info[i].flags |= WI_DETACHED;
- break;
- }
- }
+ if (pid != JIM_BAD_PID && (WIFEXITED(status) || WIFSIGNALED(status))) {
+ /* The process has finished. Remove it from the wait table if it exists there */
+ JimWaitRemove(table, pid);
}
+ Jim_SetResult(interp, errCodeObj);
+ return JIM_OK;
}
-static FILE *JimGetAioFilehandle(Jim_Interp *interp, const char *name)
+static int Jim_PidCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
- FILE *fh;
- Jim_Obj *fhObj;
-
- fhObj = Jim_NewStringObj(interp, name, -1);
- Jim_IncrRefCount(fhObj);
- fh = Jim_AioFilehandle(interp, fhObj);
- Jim_DecrRefCount(interp, fhObj);
+ if (argc != 1) {
+ Jim_WrongNumArgs(interp, 1, argv, "");
+ return JIM_ERR;
+ }
- return fh;
+ Jim_SetResultInt(interp, (jim_wide)getpid());
+ return JIM_OK;
}
/*
@@ -631,7 +665,7 @@ static FILE *JimGetAioFilehandle(Jim_Interp *interp, const char *name)
*/
static int
JimCreatePipeline(Jim_Interp *interp, int argc, Jim_Obj *const *argv, pidtype **pidArrayPtr,
- fdtype *inPipePtr, fdtype *outPipePtr, fdtype *errFilePtr)
+ int *inPipePtr, int *outPipePtr, int *errFilePtr)
{
pidtype *pidPtr = NULL; /* Points to malloc-ed array holding all
* the pids of child processes. */
@@ -668,47 +702,48 @@ JimCreatePipeline(Jim_Interp *interp, int argc, Jim_Obj *const *argv, pidtype **
* or NULL if output goes to stdout/pipe. */
const char *error = NULL; /* Holds name of stderr file to pipe to,
* or NULL if stderr goes to stderr/pipe. */
- fdtype inputId = JIM_BAD_FD;
+ int inputId = -1;
/* Readable file id input to current command in
- * pipeline (could be file or pipe). JIM_BAD_FD
+ * pipeline (could be file or pipe). -1
* means use stdin. */
- fdtype outputId = JIM_BAD_FD;
+ int outputId = -1;
/* Writable file id for output from current
* command in pipeline (could be file or pipe).
- * JIM_BAD_FD means use stdout. */
- fdtype errorId = JIM_BAD_FD;
+ * -1 means use stdout. */
+ int errorId = -1;
/* Writable file id for all standard error
- * output from all commands in pipeline. JIM_BAD_FD
+ * output from all commands in pipeline. -1
* means use stderr. */
- fdtype lastOutputId = JIM_BAD_FD;
+ int lastOutputId = -1;
/* Write file id for output from last command
* in pipeline (could be file or pipe).
* -1 means use stdout. */
- fdtype pipeIds[2]; /* File ids for pipe that's being created. */
+ int pipeIds[2]; /* File ids for pipe that's being created. */
int firstArg, lastArg; /* Indexes of first and last arguments in
* current command. */
int lastBar;
int i;
pidtype pid;
char **save_environ;
+#ifndef __MINGW32__
+ char **child_environ;
+#endif
struct WaitInfoTable *table = Jim_CmdPrivData(interp);
/* Holds the args which will be used to exec */
char **arg_array = Jim_Alloc(sizeof(*arg_array) * (argc + 1));
int arg_count = 0;
- JimReapDetachedPids(table);
-
if (inPipePtr != NULL) {
- *inPipePtr = JIM_BAD_FD;
+ *inPipePtr = -1;
}
if (outPipePtr != NULL) {
- *outPipePtr = JIM_BAD_FD;
+ *outPipePtr = -1;
}
if (errFilePtr != NULL) {
- *errFilePtr = JIM_BAD_FD;
+ *errFilePtr = -1;
}
- pipeIds[0] = pipeIds[1] = JIM_BAD_FD;
+ pipeIds[0] = pipeIds[1] = -1;
/*
* First, scan through all the arguments to figure out the structure
@@ -822,39 +857,44 @@ badargs:
* Immediate data in command. Create temporary file and
* put data into file.
*/
- inputId = JimCreateTemp(interp, input, input_len);
- if (inputId == JIM_BAD_FD) {
+ inputId = Jim_MakeTempFile(interp, NULL, 1);
+ if (inputId == -1) {
+ goto error;
+ }
+ if (write(inputId, input, input_len) != input_len) {
+ Jim_SetResultErrno(interp, "couldn't write temp file");
+ close(inputId);
goto error;
}
+ lseek(inputId, 0L, SEEK_SET);
}
else if (inputFile == FILE_HANDLE) {
- /* Should be a file descriptor */
- FILE *fh = JimGetAioFilehandle(interp, input);
+ int fd = JimGetChannelFd(interp, input);
- if (fh == NULL) {
+ if (fd < 0) {
goto error;
}
- inputId = JimDupFd(JimFileno(fh));
+ inputId = dup(fd);
}
else {
/*
* File redirection. Just open the file.
*/
- inputId = JimOpenForRead(input);
- if (inputId == JIM_BAD_FD) {
- Jim_SetResultFormatted(interp, "couldn't read file \"%s\": %s", input, JimStrError());
+ inputId = Jim_OpenForRead(input);
+ if (inputId == -1) {
+ Jim_SetResultFormatted(interp, "couldn't read file \"%s\": %s", input, strerror(Jim_Errno()));
goto error;
}
}
}
else if (inPipePtr != NULL) {
- if (JimPipe(pipeIds) != 0) {
+ if (pipe(pipeIds) != 0) {
Jim_SetResultErrno(interp, "couldn't create input pipe for command");
goto error;
}
inputId = pipeIds[0];
*inPipePtr = pipeIds[1];
- pipeIds[0] = pipeIds[1] = JIM_BAD_FD;
+ pipeIds[0] = pipeIds[1] = -1;
}
/*
@@ -863,20 +903,19 @@ badargs:
*/
if (output != NULL) {
if (outputFile == FILE_HANDLE) {
- FILE *fh = JimGetAioFilehandle(interp, output);
- if (fh == NULL) {
+ int fd = JimGetChannelFd(interp, output);
+ if (fd < 0) {
goto error;
}
- fflush(fh);
- lastOutputId = JimDupFd(JimFileno(fh));
+ lastOutputId = dup(fd);
}
else {
/*
* Output is to go to a file.
*/
- lastOutputId = JimOpenForWrite(output, outputFile == FILE_APPEND);
- if (lastOutputId == JIM_BAD_FD) {
- Jim_SetResultFormatted(interp, "couldn't write file \"%s\": %s", output, JimStrError());
+ lastOutputId = Jim_OpenForWrite(output, outputFile == FILE_APPEND);
+ if (lastOutputId == -1) {
+ Jim_SetResultFormatted(interp, "couldn't write file \"%s\": %s", output, strerror(Jim_Errno()));
goto error;
}
}
@@ -885,43 +924,42 @@ badargs:
/*
* Output is to go to a pipe.
*/
- if (JimPipe(pipeIds) != 0) {
+ if (pipe(pipeIds) != 0) {
Jim_SetResultErrno(interp, "couldn't create output pipe");
goto error;
}
lastOutputId = pipeIds[1];
*outPipePtr = pipeIds[0];
- pipeIds[0] = pipeIds[1] = JIM_BAD_FD;
+ pipeIds[0] = pipeIds[1] = -1;
}
/* If we are redirecting stderr with 2>filename or 2>@fileId, then we ignore errFilePtr */
if (error != NULL) {
if (errorFile == FILE_HANDLE) {
if (strcmp(error, "1") == 0) {
/* Special 2>@1 */
- if (lastOutputId != JIM_BAD_FD) {
- errorId = JimDupFd(lastOutputId);
+ if (lastOutputId != -1) {
+ errorId = dup(lastOutputId);
}
else {
/* No redirection of stdout, so just use 2>@stdout */
error = "stdout";
}
}
- if (errorId == JIM_BAD_FD) {
- FILE *fh = JimGetAioFilehandle(interp, error);
- if (fh == NULL) {
+ if (errorId == -1) {
+ int fd = JimGetChannelFd(interp, error);
+ if (fd < 0) {
goto error;
}
- fflush(fh);
- errorId = JimDupFd(JimFileno(fh));
+ errorId = dup(fd);
}
}
else {
/*
* Output is to go to a file.
*/
- errorId = JimOpenForWrite(error, errorFile == FILE_APPEND);
- if (errorId == JIM_BAD_FD) {
- Jim_SetResultFormatted(interp, "couldn't write file \"%s\": %s", error, JimStrError());
+ errorId = Jim_OpenForWrite(error, errorFile == FILE_APPEND);
+ if (errorId == -1) {
+ Jim_SetResultFormatted(interp, "couldn't write file \"%s\": %s", error, strerror(Jim_Errno()));
goto error;
}
}
@@ -935,11 +973,11 @@ badargs:
* to complete before reading stderr, and processes couldn't complete
* because stderr was backed up.
*/
- errorId = JimCreateTemp(interp, NULL, 0);
- if (errorId == JIM_BAD_FD) {
+ errorId = Jim_MakeTempFile(interp, NULL, 1);
+ if (errorId == -1) {
goto error;
}
- *errFilePtr = JimDupFd(errorId);
+ *errFilePtr = dup(errorId);
}
/*
@@ -953,30 +991,38 @@ badargs:
}
for (firstArg = 0; firstArg < arg_count; numPids++, firstArg = lastArg + 1) {
int pipe_dup_err = 0;
- fdtype origErrorId = errorId;
+ int origErrorId = errorId;
for (lastArg = firstArg; lastArg < arg_count; lastArg++) {
- if (arg_array[lastArg][0] == '|') {
- if (arg_array[lastArg][1] == '&') {
- pipe_dup_err = 1;
- }
+ if (strcmp(arg_array[lastArg], "|") == 0) {
+ break;
+ }
+ if (strcmp(arg_array[lastArg], "|&") == 0) {
+ pipe_dup_err = 1;
break;
}
}
+
+ if (lastArg == firstArg) {
+ Jim_SetResultString(interp, "missing command to exec", -1);
+ goto error;
+ }
+
/* Replace | with NULL for execv() */
arg_array[lastArg] = NULL;
if (lastArg == arg_count) {
outputId = lastOutputId;
+ lastOutputId = -1;
}
else {
- if (JimPipe(pipeIds) != 0) {
+ if (pipe(pipeIds) != 0) {
Jim_SetResultErrno(interp, "couldn't create pipe");
goto error;
}
outputId = pipeIds[1];
}
- /* Need to do this befor vfork() */
+ /* Need to do this before vfork() */
if (pipe_dup_err) {
errorId = outputId;
}
@@ -984,14 +1030,17 @@ badargs:
/* Now fork the child */
#ifdef __MINGW32__
- pid = JimStartWinProcess(interp, &arg_array[firstArg], save_environ ? save_environ[0] : NULL, inputId, outputId, errorId);
+ pid = JimStartWinProcess(interp, &arg_array[firstArg], save_environ, inputId, outputId, errorId);
if (pid == JIM_BAD_PID) {
Jim_SetResultFormatted(interp, "couldn't exec \"%s\"", arg_array[firstArg]);
goto error;
}
#else
+ i = strlen(arg_array[firstArg]);
+
+ child_environ = Jim_GetEnviron();
/*
- * Make a new process and enter it into the table if the fork
+ * Make a new process and enter it into the table if the vfork
* is successful.
*/
pid = vfork();
@@ -1001,22 +1050,49 @@ badargs:
}
if (pid == 0) {
/* Child */
-
- if (inputId != -1) dup2(inputId, 0);
- if (outputId != -1) dup2(outputId, 1);
- if (errorId != -1) dup2(errorId, 2);
-
- for (i = 3; (i <= outputId) || (i <= inputId) || (i <= errorId); i++) {
- close(i);
+ /* Set up stdin, stdout, stderr */
+ if (inputId != -1) {
+ dup2(inputId, fileno(stdin));
+ close(inputId);
+ }
+ if (outputId != -1) {
+ dup2(outputId, fileno(stdout));
+ if (outputId != errorId) {
+ close(outputId);
+ }
+ }
+ if (errorId != -1) {
+ dup2(errorId, fileno(stderr));
+ close(errorId);
+ }
+ /* Close parent-only file descriptors */
+ if (outPipePtr) {
+ close(*outPipePtr);
+ }
+ if (errFilePtr) {
+ close(*errFilePtr);
+ }
+ if (pipeIds[0] != -1) {
+ close(pipeIds[0]);
+ }
+ if (lastOutputId != -1) {
+ close(lastOutputId);
}
- /* Restore SIGPIPE behaviour */
- (void)signal(SIGPIPE, SIG_DFL);
-
- execvpe(arg_array[firstArg], &arg_array[firstArg], Jim_GetEnviron());
+ execvpe(arg_array[firstArg], &arg_array[firstArg], child_environ);
- /* Need to prep an error message before vfork(), just in case */
- fprintf(stderr, "couldn't exec \"%s\"\n", arg_array[firstArg]);
+ if (write(fileno(stderr), "couldn't exec \"", 15) &&
+ write(fileno(stderr), arg_array[firstArg], i) &&
+ write(fileno(stderr), "\"\n", 2)) {
+ /* nothing */
+ }
+#ifdef JIM_MAINTAINER
+ {
+ /* Keep valgrind happy */
+ static char *const false_argv[2] = {"false", NULL};
+ execvp(false_argv[0],false_argv);
+ }
+#endif
_exit(127);
}
#endif
@@ -1046,14 +1122,14 @@ badargs:
* this child, then set up the input for the next child.
*/
- if (inputId != JIM_BAD_FD) {
- JimCloseFd(inputId);
+ if (inputId != -1) {
+ close(inputId);
}
- if (outputId != JIM_BAD_FD) {
- JimCloseFd(outputId);
+ if (outputId != -1) {
+ close(outputId);
}
inputId = pipeIds[0];
- pipeIds[0] = pipeIds[1] = JIM_BAD_FD;
+ pipeIds[0] = pipeIds[1] = -1;
}
*pidArrayPtr = pidPtr;
@@ -1062,14 +1138,14 @@ badargs:
*/
cleanup:
- if (inputId != JIM_BAD_FD) {
- JimCloseFd(inputId);
+ if (inputId != -1) {
+ close(inputId);
}
- if (lastOutputId != JIM_BAD_FD) {
- JimCloseFd(lastOutputId);
+ if (lastOutputId != -1) {
+ close(lastOutputId);
}
- if (errorId != JIM_BAD_FD) {
- JimCloseFd(errorId);
+ if (errorId != -1) {
+ close(errorId);
}
Jim_Free(arg_array);
@@ -1084,28 +1160,28 @@ badargs:
*/
error:
- if ((inPipePtr != NULL) && (*inPipePtr != JIM_BAD_FD)) {
- JimCloseFd(*inPipePtr);
- *inPipePtr = JIM_BAD_FD;
+ if ((inPipePtr != NULL) && (*inPipePtr != -1)) {
+ close(*inPipePtr);
+ *inPipePtr = -1;
}
- if ((outPipePtr != NULL) && (*outPipePtr != JIM_BAD_FD)) {
- JimCloseFd(*outPipePtr);
- *outPipePtr = JIM_BAD_FD;
+ if ((outPipePtr != NULL) && (*outPipePtr != -1)) {
+ close(*outPipePtr);
+ *outPipePtr = -1;
}
- if ((errFilePtr != NULL) && (*errFilePtr != JIM_BAD_FD)) {
- JimCloseFd(*errFilePtr);
- *errFilePtr = JIM_BAD_FD;
+ if ((errFilePtr != NULL) && (*errFilePtr != -1)) {
+ close(*errFilePtr);
+ *errFilePtr = -1;
}
- if (pipeIds[0] != JIM_BAD_FD) {
- JimCloseFd(pipeIds[0]);
+ if (pipeIds[0] != -1) {
+ close(pipeIds[0]);
}
- if (pipeIds[1] != JIM_BAD_FD) {
- JimCloseFd(pipeIds[1]);
+ if (pipeIds[1] != -1) {
+ close(pipeIds[1]);
}
if (pidPtr != NULL) {
for (i = 0; i < numPids; i++) {
if (pidPtr[i] != JIM_BAD_PID) {
- JimDetachPids(interp, 1, &pidPtr[i]);
+ JimDetachPids(table, 1, &pidPtr[i]);
}
}
Jim_Free(pidPtr);
@@ -1156,244 +1232,22 @@ static int JimCleanupChildren(Jim_Interp *interp, int numPids, pidtype *pidPtr,
int Jim_execInit(Jim_Interp *interp)
{
+ struct WaitInfoTable *waitinfo;
if (Jim_PackageProvide(interp, "exec", "1.0", JIM_ERRMSG))
return JIM_ERR;
-#ifdef SIGPIPE
- /*
- * Disable SIGPIPE signals: if they were allowed, this process
- * might go away unexpectedly if children misbehave. This code
- * can potentially interfere with other application code that
- * expects to handle SIGPIPEs.
- *
- * By doing this in the init function, applications can override
- * this later. Note that child processes have SIGPIPE restored
- * to the default after vfork().
- */
- (void)signal(SIGPIPE, SIG_IGN);
-#endif
+ waitinfo = JimAllocWaitInfoTable();
+ Jim_CreateCommand(interp, "exec", Jim_ExecCmd, waitinfo, JimFreeWaitInfoTable);
+ waitinfo->refcount++;
+ Jim_CreateCommand(interp, "wait", Jim_WaitCommand, waitinfo, JimFreeWaitInfoTable);
+ Jim_CreateCommand(interp, "pid", Jim_PidCommand, 0, 0);
- Jim_CreateCommand(interp, "exec", Jim_ExecCmd, JimAllocWaitInfoTable(), JimFreeWaitInfoTable);
return JIM_OK;
}
#if defined(__MINGW32__)
/* Windows-specific (mingw) implementation */
-static SECURITY_ATTRIBUTES *JimStdSecAttrs(void)
-{
- static SECURITY_ATTRIBUTES secAtts;
-
- secAtts.nLength = sizeof(SECURITY_ATTRIBUTES);
- secAtts.lpSecurityDescriptor = NULL;
- secAtts.bInheritHandle = TRUE;
- return &secAtts;
-}
-
-static int JimErrno(void)
-{
- switch (GetLastError()) {
- case ERROR_FILE_NOT_FOUND: return ENOENT;
- case ERROR_PATH_NOT_FOUND: return ENOENT;
- case ERROR_TOO_MANY_OPEN_FILES: return EMFILE;
- case ERROR_ACCESS_DENIED: return EACCES;
- case ERROR_INVALID_HANDLE: return EBADF;
- case ERROR_BAD_ENVIRONMENT: return E2BIG;
- case ERROR_BAD_FORMAT: return ENOEXEC;
- case ERROR_INVALID_ACCESS: return EACCES;
- case ERROR_INVALID_DRIVE: return ENOENT;
- case ERROR_CURRENT_DIRECTORY: return EACCES;
- case ERROR_NOT_SAME_DEVICE: return EXDEV;
- case ERROR_NO_MORE_FILES: return ENOENT;
- case ERROR_WRITE_PROTECT: return EROFS;
- case ERROR_BAD_UNIT: return ENXIO;
- case ERROR_NOT_READY: return EBUSY;
- case ERROR_BAD_COMMAND: return EIO;
- case ERROR_CRC: return EIO;
- case ERROR_BAD_LENGTH: return EIO;
- case ERROR_SEEK: return EIO;
- case ERROR_WRITE_FAULT: return EIO;
- case ERROR_READ_FAULT: return EIO;
- case ERROR_GEN_FAILURE: return EIO;
- case ERROR_SHARING_VIOLATION: return EACCES;
- case ERROR_LOCK_VIOLATION: return EACCES;
- case ERROR_SHARING_BUFFER_EXCEEDED: return ENFILE;
- case ERROR_HANDLE_DISK_FULL: return ENOSPC;
- case ERROR_NOT_SUPPORTED: return ENODEV;
- case ERROR_REM_NOT_LIST: return EBUSY;
- case ERROR_DUP_NAME: return EEXIST;
- case ERROR_BAD_NETPATH: return ENOENT;
- case ERROR_NETWORK_BUSY: return EBUSY;
- case ERROR_DEV_NOT_EXIST: return ENODEV;
- case ERROR_TOO_MANY_CMDS: return EAGAIN;
- case ERROR_ADAP_HDW_ERR: return EIO;
- case ERROR_BAD_NET_RESP: return EIO;
- case ERROR_UNEXP_NET_ERR: return EIO;
- case ERROR_NETNAME_DELETED: return ENOENT;
- case ERROR_NETWORK_ACCESS_DENIED: return EACCES;
- case ERROR_BAD_DEV_TYPE: return ENODEV;
- case ERROR_BAD_NET_NAME: return ENOENT;
- case ERROR_TOO_MANY_NAMES: return ENFILE;
- case ERROR_TOO_MANY_SESS: return EIO;
- case ERROR_SHARING_PAUSED: return EAGAIN;
- case ERROR_REDIR_PAUSED: return EAGAIN;
- case ERROR_FILE_EXISTS: return EEXIST;
- case ERROR_CANNOT_MAKE: return ENOSPC;
- case ERROR_OUT_OF_STRUCTURES: return ENFILE;
- case ERROR_ALREADY_ASSIGNED: return EEXIST;
- case ERROR_INVALID_PASSWORD: return EPERM;
- case ERROR_NET_WRITE_FAULT: return EIO;
- case ERROR_NO_PROC_SLOTS: return EAGAIN;
- case ERROR_DISK_CHANGE: return EXDEV;
- case ERROR_BROKEN_PIPE: return EPIPE;
- case ERROR_OPEN_FAILED: return ENOENT;
- case ERROR_DISK_FULL: return ENOSPC;
- case ERROR_NO_MORE_SEARCH_HANDLES: return EMFILE;
- case ERROR_INVALID_TARGET_HANDLE: return EBADF;
- case ERROR_INVALID_NAME: return ENOENT;
- case ERROR_PROC_NOT_FOUND: return ESRCH;
- case ERROR_WAIT_NO_CHILDREN: return ECHILD;
- case ERROR_CHILD_NOT_COMPLETE: return ECHILD;
- case ERROR_DIRECT_ACCESS_HANDLE: return EBADF;
- case ERROR_SEEK_ON_DEVICE: return ESPIPE;
- case ERROR_BUSY_DRIVE: return EAGAIN;
- case ERROR_DIR_NOT_EMPTY: return EEXIST;
- case ERROR_NOT_LOCKED: return EACCES;
- case ERROR_BAD_PATHNAME: return ENOENT;
- case ERROR_LOCK_FAILED: return EACCES;
- case ERROR_ALREADY_EXISTS: return EEXIST;
- case ERROR_FILENAME_EXCED_RANGE: return ENAMETOOLONG;
- case ERROR_BAD_PIPE: return EPIPE;
- case ERROR_PIPE_BUSY: return EAGAIN;
- case ERROR_PIPE_NOT_CONNECTED: return EPIPE;
- case ERROR_DIRECTORY: return ENOTDIR;
- }
- return EINVAL;
-}
-
-static int JimPipe(fdtype pipefd[2])
-{
- if (CreatePipe(&pipefd[0], &pipefd[1], NULL, 0)) {
- return 0;
- }
- return -1;
-}
-
-static fdtype JimDupFd(fdtype infd)
-{
- fdtype dupfd;
- pidtype pid = GetCurrentProcess();
-
- if (DuplicateHandle(pid, infd, pid, &dupfd, 0, TRUE, DUPLICATE_SAME_ACCESS)) {
- return dupfd;
- }
- return JIM_BAD_FD;
-}
-
-static int JimRewindFd(fdtype fd)
-{
- return SetFilePointer(fd, 0, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER ? -1 : 0;
-}
-
-#if 0
-static int JimReadFd(fdtype fd, char *buffer, size_t len)
-{
- DWORD num;
-
- if (ReadFile(fd, buffer, len, &num, NULL)) {
- return num;
- }
- if (GetLastError() == ERROR_HANDLE_EOF || GetLastError() == ERROR_BROKEN_PIPE) {
- return 0;
- }
- return -1;
-}
-#endif
-
-static FILE *JimFdOpenForRead(fdtype fd)
-{
- return _fdopen(_open_osfhandle((int)fd, _O_RDONLY | _O_TEXT), "r");
-}
-
-static fdtype JimFileno(FILE *fh)
-{
- return (fdtype)_get_osfhandle(_fileno(fh));
-}
-
-static fdtype JimOpenForRead(const char *filename)
-{
- return CreateFile(filename, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
- JimStdSecAttrs(), OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
-}
-
-static fdtype JimOpenForWrite(const char *filename, int append)
-{
- fdtype fd = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
- JimStdSecAttrs(), append ? OPEN_ALWAYS : CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, (HANDLE) NULL);
- if (append && fd != JIM_BAD_FD) {
- SetFilePointer(fd, 0, NULL, FILE_END);
- }
- return fd;
-}
-
-static FILE *JimFdOpenForWrite(fdtype fd)
-{
- return _fdopen(_open_osfhandle((int)fd, _O_TEXT), "w");
-}
-
-static pidtype JimWaitPid(pidtype pid, int *status, int nohang)
-{
- DWORD ret = WaitForSingleObject(pid, nohang ? 0 : INFINITE);
- if (ret == WAIT_TIMEOUT || ret == WAIT_FAILED) {
- /* WAIT_TIMEOUT can only happend with WNOHANG */
- return JIM_BAD_PID;
- }
- GetExitCodeProcess(pid, &ret);
- *status = ret;
- CloseHandle(pid);
- return pid;
-}
-
-static HANDLE JimCreateTemp(Jim_Interp *interp, const char *contents, int len)
-{
- char name[MAX_PATH];
- HANDLE handle;
-
- if (!GetTempPath(MAX_PATH, name) || !GetTempFileName(name, "JIM", 0, name)) {
- return JIM_BAD_FD;
- }
-
- handle = CreateFile(name, GENERIC_READ | GENERIC_WRITE, 0, JimStdSecAttrs(),
- CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE,
- NULL);
-
- if (handle == INVALID_HANDLE_VALUE) {
- goto error;
- }
-
- if (contents != NULL) {
- /* Use fdopen() to get automatic text-mode translation */
- FILE *fh = JimFdOpenForWrite(JimDupFd(handle));
- if (fh == NULL) {
- goto error;
- }
-
- if (fwrite(contents, len, 1, fh) != 1) {
- fclose(fh);
- goto error;
- }
- fseek(fh, 0, SEEK_SET);
- fclose(fh);
- }
- return handle;
-
- error:
- Jim_SetResultErrno(interp, "failed to create temp file");
- CloseHandle(handle);
- DeleteFile(name);
- return JIM_BAD_FD;
-}
-
static int
JimWinFindExecutable(const char *originalName, char fullPath[MAX_PATH])
{
@@ -1425,6 +1279,11 @@ static void JimRestoreEnv(char **env)
JimFreeEnv(env, Jim_GetEnviron());
}
+static char **JimOriginalEnviron(void)
+{
+ return NULL;
+}
+
static Jim_Obj *
JimWinBuildCommandLine(Jim_Interp *interp, char **argv)
{
@@ -1501,15 +1360,19 @@ JimWinBuildCommandLine(Jim_Interp *interp, char **argv)
return strObj;
}
+/**
+ * Note that inputId, etc. are osf_handles.
+ */
static pidtype
-JimStartWinProcess(Jim_Interp *interp, char **argv, char *env, fdtype inputId, fdtype outputId, fdtype errorId)
+JimStartWinProcess(Jim_Interp *interp, char **argv, char **env, int inputId, int outputId, int errorId)
{
STARTUPINFO startInfo;
PROCESS_INFORMATION procInfo;
- HANDLE hProcess, h;
+ HANDLE hProcess;
char execPath[MAX_PATH];
pidtype pid = JIM_BAD_PID;
Jim_Obj *cmdLineObj;
+ char *winenv;
if (JimWinFindExecutable(argv[0], execPath) < 0) {
return JIM_BAD_PID;
@@ -1537,47 +1400,57 @@ JimStartWinProcess(Jim_Interp *interp, char **argv, char *env, fdtype inputId, f
* and stderr of the child process. The duplicate handles are set to
* be inheritable, so the child process can use them.
*/
- if (inputId == JIM_BAD_FD) {
- if (CreatePipe(&startInfo.hStdInput, &h, JimStdSecAttrs(), 0) != FALSE) {
- CloseHandle(h);
- }
- } else {
- DuplicateHandle(hProcess, inputId, hProcess, &startInfo.hStdInput,
- 0, TRUE, DUPLICATE_SAME_ACCESS);
+ /*
+ * If stdin was not redirected, input should come from the parent's stdin
+ */
+ if (inputId == -1) {
+ inputId = _fileno(stdin);
}
- if (startInfo.hStdInput == JIM_BAD_FD) {
+ DuplicateHandle(hProcess, (HANDLE)_get_osfhandle(inputId), hProcess, &startInfo.hStdInput,
+ 0, TRUE, DUPLICATE_SAME_ACCESS);
+ if (startInfo.hStdInput == INVALID_HANDLE_VALUE) {
goto end;
}
- if (outputId == JIM_BAD_FD) {
- startInfo.hStdOutput = CreateFile("NUL:", GENERIC_WRITE, 0,
- JimStdSecAttrs(), OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- } else {
- DuplicateHandle(hProcess, outputId, hProcess, &startInfo.hStdOutput,
- 0, TRUE, DUPLICATE_SAME_ACCESS);
+ /*
+ * If stdout was not redirected, output should go to the parent's stdout
+ */
+ if (outputId == -1) {
+ outputId = _fileno(stdout);
}
- if (startInfo.hStdOutput == JIM_BAD_FD) {
+ DuplicateHandle(hProcess, (HANDLE)_get_osfhandle(outputId), hProcess, &startInfo.hStdOutput,
+ 0, TRUE, DUPLICATE_SAME_ACCESS);
+ if (startInfo.hStdOutput == INVALID_HANDLE_VALUE) {
goto end;
}
- if (errorId == JIM_BAD_FD) {
- /*
- * If handle was not set, errors should be sent to an infinitely
- * deep sink.
- */
-
- startInfo.hStdError = CreateFile("NUL:", GENERIC_WRITE, 0,
- JimStdSecAttrs(), OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
- } else {
- DuplicateHandle(hProcess, errorId, hProcess, &startInfo.hStdError,
- 0, TRUE, DUPLICATE_SAME_ACCESS);
+ /* Ditto stderr */
+ if (errorId == -1) {
+ errorId = _fileno(stderr);
}
- if (startInfo.hStdError == JIM_BAD_FD) {
+ DuplicateHandle(hProcess, (HANDLE)_get_osfhandle(errorId), hProcess, &startInfo.hStdError,
+ 0, TRUE, DUPLICATE_SAME_ACCESS);
+ if (startInfo.hStdError == INVALID_HANDLE_VALUE) {
goto end;
}
+ /* If env is NULL, use the original environment.
+ * If env[0] is NULL, use an empty environment.
+ * Otherwise use the environment starting at env[0]
+ */
+ if (env == NULL) {
+ /* Use the original environment */
+ winenv = NULL;
+ }
+ else if (env[0] == NULL) {
+ winenv = (char *)"\0";
+ }
+ else {
+ winenv = env[0];
+ }
+
if (!CreateProcess(NULL, (char *)Jim_String(cmdLineObj), NULL, NULL, TRUE,
- 0, env, NULL, &startInfo, &procInfo)) {
+ 0, winenv, NULL, &startInfo, &procInfo)) {
goto end;
}
@@ -1597,45 +1470,23 @@ JimStartWinProcess(Jim_Interp *interp, char **argv, char *env, fdtype inputId, f
end:
Jim_FreeNewObj(interp, cmdLineObj);
- if (startInfo.hStdInput != JIM_BAD_FD) {
+ if (startInfo.hStdInput != INVALID_HANDLE_VALUE) {
CloseHandle(startInfo.hStdInput);
}
- if (startInfo.hStdOutput != JIM_BAD_FD) {
+ if (startInfo.hStdOutput != INVALID_HANDLE_VALUE) {
CloseHandle(startInfo.hStdOutput);
}
- if (startInfo.hStdError != JIM_BAD_FD) {
+ if (startInfo.hStdError != INVALID_HANDLE_VALUE) {
CloseHandle(startInfo.hStdError);
}
return pid;
}
-#else
-/* Unix-specific implementation */
-static int JimOpenForWrite(const char *filename, int append)
-{
- return open(filename, O_WRONLY | O_CREAT | (append ? O_APPEND : O_TRUNC), 0666);
-}
-static int JimRewindFd(int fd)
-{
- return lseek(fd, 0L, SEEK_SET);
-}
+#else
-static int JimCreateTemp(Jim_Interp *interp, const char *contents, int len)
+static char **JimOriginalEnviron(void)
{
- int fd = Jim_MakeTempFile(interp, NULL);
-
- if (fd != JIM_BAD_FD) {
- unlink(Jim_String(Jim_GetResult(interp)));
- if (contents) {
- if (write(fd, contents, len) != len) {
- Jim_SetResultErrno(interp, "couldn't write temp file");
- close(fd);
- return -1;
- }
- lseek(fd, 0L, SEEK_SET);
- }
- }
- return fd;
+ return Jim_GetEnviron();
}
static char **JimSaveEnv(char **env)
diff --git a/jim-file.c b/jim-file.c
index 065ff2c..24f39e5 100644
--- a/jim-file.c
+++ b/jim-file.c
@@ -71,12 +71,19 @@
# define MAXPATHLEN JIM_PATH_LEN
# endif
-#if defined(__MINGW32__) || defined(_MSC_VER)
+#if defined(__MINGW32__) || defined(__MSYS__) || defined(_MSC_VER)
#define ISWINDOWS 1
#else
#define ISWINDOWS 0
#endif
+/* extract nanosecond resolution mtime from struct stat */
+#if defined(HAVE_STRUCT_STAT_ST_MTIMESPEC)
+ #define STAT_MTIME_US(STAT) ((STAT).st_mtimespec.tv_sec * 1000000ll + (STAT).st_mtimespec.tv_nsec / 1000)
+#elif defined(HAVE_STRUCT_STAT_ST_MTIM)
+ #define STAT_MTIME_US(STAT) ((STAT).st_mtim.tv_sec * 1000000ll + (STAT).st_mtim.tv_nsec / 1000)
+#endif
+
/*
*----------------------------------------------------------------------
*
@@ -169,26 +176,31 @@ static int StoreStatData(Jim_Interp *interp, Jim_Obj *varName, const struct stat
AppendStatElement(interp, listObj, "atime", sb->st_atime);
AppendStatElement(interp, listObj, "mtime", sb->st_mtime);
AppendStatElement(interp, listObj, "ctime", sb->st_ctime);
+#ifdef STAT_MTIME_US
+ AppendStatElement(interp, listObj, "mtimeus", STAT_MTIME_US(*sb));
+#endif
Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, "type", -1));
Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, JimGetFileType((int)sb->st_mode), -1));
/* Was a variable specified? */
if (varName) {
- Jim_Obj *objPtr = Jim_GetVariable(interp, varName, JIM_NONE);
+ Jim_Obj *objPtr;
+ objPtr = Jim_GetVariable(interp, varName, JIM_NONE);
+
if (objPtr) {
- if (Jim_DictSize(interp, objPtr) < 0) {
+ Jim_Obj *objv[2];
+
+ objv[0] = objPtr;
+ objv[1] = listObj;
+
+ objPtr = Jim_DictMerge(interp, 2, objv);
+ if (objPtr == NULL) {
/* This message matches the one from Tcl */
Jim_SetResultFormatted(interp, "can't set \"%#s(dev)\": variable isn't array", varName);
Jim_FreeNewObj(interp, listObj);
return JIM_ERR;
}
- if (Jim_IsShared(objPtr))
- objPtr = Jim_DuplicateObj(interp, objPtr);
-
- /* Just cheat here and append as a list and convert to a dict */
- Jim_ListAppendList(interp, objPtr, listObj);
- Jim_DictSize(interp, objPtr);
Jim_InvalidateStringRep(objPtr);
Jim_FreeNewObj(interp, listObj);
@@ -203,9 +215,43 @@ static int StoreStatData(Jim_Interp *interp, Jim_Obj *varName, const struct stat
return JIM_OK;
}
+/**
+ * Give a path of length 'len', returns the length of the path
+ * with any trailing slashes removed.
+ */
+static int JimPathLenNoTrailingSlashes(const char *path, int len)
+{
+ int i;
+ for (i = len; i > 1 && path[i - 1] == '/'; i--) {
+ /* Trailing slash, so remove it */
+ if (ISWINDOWS && path[i - 2] == ':') {
+ /* But on windows, we won't remove the trailing slash from c:/ */
+ break;
+ }
+ }
+ return i;
+}
+
+/**
+ * Give a path in objPtr, returns a new path with any trailing slash removed.
+ * Use Jim_DecrRefCount() on the returned object (which may be identical to objPtr).
+ */
+static Jim_Obj *JimStripTrailingSlashes(Jim_Interp *interp, Jim_Obj *objPtr)
+{
+ int len = Jim_Length(objPtr);
+ const char *path = Jim_String(objPtr);
+ int i = JimPathLenNoTrailingSlashes(path, len);
+ if (i != len) {
+ objPtr = Jim_NewStringObj(interp, path, i);
+ }
+ Jim_IncrRefCount(objPtr);
+ return objPtr;
+}
+
static int file_cmd_dirname(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
- const char *path = Jim_String(argv[0]);
+ Jim_Obj *objPtr = JimStripTrailingSlashes(interp, argv[0]);
+ const char *path = Jim_String(objPtr);
const char *p = strrchr(path, '/');
if (!p && path[0] == '.' && path[1] == '.' && path[2] == '\0') {
@@ -221,29 +267,64 @@ static int file_cmd_dirname(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
Jim_SetResultString(interp, path, p - path + 1);
}
else {
- Jim_SetResultString(interp, path, p - path);
+ /* Strip any trailing slashes from the result */
+ int len = JimPathLenNoTrailingSlashes(path, p - path);
+ Jim_SetResultString(interp, path, len);
}
+ Jim_DecrRefCount(interp, objPtr);
return JIM_OK;
}
-static int file_cmd_rootname(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+static int file_cmd_split(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
+ Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0);
const char *path = Jim_String(argv[0]);
+
+ if (*path == '/') {
+ Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, "/", 1));
+ }
+
+ while (1) {
+ /* Remove leading slashes */
+ while (*path == '/') {
+ path++;
+ }
+ if (*path) {
+ const char *pt = strchr(path, '/');
+ if (pt) {
+ Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, path, pt - path));
+ path = pt;
+ continue;
+ }
+ Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, path, -1));
+ }
+ break;
+ }
+ Jim_SetResult(interp, listObj);
+ return JIM_OK;
+}
+
+static int file_cmd_rootname(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ Jim_Obj *objPtr = JimStripTrailingSlashes(interp, argv[0]);
+ const char *path = Jim_String(objPtr);
const char *lastSlash = strrchr(path, '/');
const char *p = strrchr(path, '.');
if (p == NULL || (lastSlash != NULL && lastSlash > p)) {
- Jim_SetResult(interp, argv[0]);
+ Jim_SetResult(interp, objPtr);
}
else {
Jim_SetResultString(interp, path, p - path);
}
+ Jim_DecrRefCount(interp, objPtr);
return JIM_OK;
}
static int file_cmd_extension(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
- const char *path = Jim_String(argv[0]);
+ Jim_Obj *objPtr = JimStripTrailingSlashes(interp, argv[0]);
+ const char *path = Jim_String(objPtr);
const char *lastSlash = strrchr(path, '/');
const char *p = strrchr(path, '.');
@@ -251,20 +332,23 @@ static int file_cmd_extension(Jim_Interp *interp, int argc, Jim_Obj *const *argv
p = "";
}
Jim_SetResultString(interp, p, -1);
+ Jim_DecrRefCount(interp, objPtr);
return JIM_OK;
}
static int file_cmd_tail(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
- const char *path = Jim_String(argv[0]);
+ Jim_Obj *objPtr = JimStripTrailingSlashes(interp, argv[0]);
+ const char *path = Jim_String(objPtr);
const char *lastSlash = strrchr(path, '/');
if (lastSlash) {
Jim_SetResultString(interp, lastSlash + 1, -1);
}
else {
- Jim_SetResult(interp, argv[0]);
+ Jim_SetResult(interp, objPtr);
}
+ Jim_DecrRefCount(interp, objPtr);
return JIM_OK;
}
@@ -490,7 +574,7 @@ static int file_cmd_mkdir(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
static int file_cmd_tempfile(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
- int fd = Jim_MakeTempFile(interp, (argc >= 1) ? Jim_String(argv[0]) : NULL);
+ int fd = Jim_MakeTempFile(interp, (argc >= 1) ? Jim_String(argv[0]) : NULL, 0);
if (fd < 0) {
return JIM_ERR;
@@ -608,37 +692,65 @@ static int file_cmd_atime(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
return JIM_OK;
}
+/**
+ * Set file atime/mtime to the given time in microseconds since the epoch.
+ */
+static int JimSetFileTimes(Jim_Interp *interp, const char *filename, jim_wide us)
+{
+#ifdef HAVE_UTIMES
+ struct timeval times[2];
+
+ times[1].tv_sec = times[0].tv_sec = us / 1000000;
+ times[1].tv_usec = times[0].tv_usec = us % 1000000;
+
+ if (utimes(filename, times) != 0) {
+ Jim_SetResultFormatted(interp, "can't set time on \"%s\": %s", filename, strerror(errno));
+ return JIM_ERR;
+ }
+ return JIM_OK;
+#else
+ Jim_SetResultString(interp, "Not implemented", -1);
+ return JIM_ERR;
+#endif
+}
+
static int file_cmd_mtime(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
struct stat sb;
if (argc == 2) {
-#ifdef HAVE_UTIMES
- jim_wide newtime;
- struct timeval times[2];
-
- if (Jim_GetWide(interp, argv[1], &newtime) != JIM_OK) {
+ jim_wide secs;
+ if (Jim_GetWide(interp, argv[1], &secs) != JIM_OK) {
return JIM_ERR;
}
+ return JimSetFileTimes(interp, Jim_String(argv[0]), secs * 1000000);
+ }
+ if (file_stat(interp, argv[0], &sb) != JIM_OK) {
+ return JIM_ERR;
+ }
+ Jim_SetResultInt(interp, sb.st_mtime);
+ return JIM_OK;
+}
- times[1].tv_sec = times[0].tv_sec = newtime;
- times[1].tv_usec = times[0].tv_usec = 0;
+#ifdef STAT_MTIME_US
+static int file_cmd_mtimeus(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ struct stat sb;
- if (utimes(Jim_String(argv[0]), times) != 0) {
- Jim_SetResultFormatted(interp, "can't set time on \"%#s\": %s", argv[0], strerror(errno));
+ if (argc == 2) {
+ jim_wide us;
+ if (Jim_GetWide(interp, argv[1], &us) != JIM_OK) {
return JIM_ERR;
}
-#else
- Jim_SetResultString(interp, "Not implemented", -1);
- return JIM_ERR;
-#endif
+ return JimSetFileTimes(interp, Jim_String(argv[0]), us);
}
if (file_stat(interp, argv[0], &sb) != JIM_OK) {
return JIM_ERR;
}
- Jim_SetResultInt(interp, sb.st_mtime);
+ Jim_SetResultInt(interp, STAT_MTIME_US(sb));
return JIM_OK;
}
+#endif
static int file_cmd_copy(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
@@ -763,6 +875,15 @@ static const jim_subcmd_type file_command_table[] = {
2,
/* Description: Get or set last modification time */
},
+#ifdef STAT_MTIME_US
+ { "mtimeus",
+ "name ?time?",
+ file_cmd_mtimeus,
+ 1,
+ 2,
+ /* Description: Get or set last modification time in microseconds */
+ },
+#endif
{ "copy",
"?-force? source dest",
file_cmd_copy,
@@ -798,6 +919,13 @@ static const jim_subcmd_type file_command_table[] = {
1,
/* Description: Last component of the name */
},
+ { "split",
+ "name",
+ file_cmd_split,
+ 1,
+ 1,
+ /* Description: Split path into components as a list */
+ },
{ "normalize",
"name",
file_cmd_normalize,
diff --git a/jim-format.c b/jim-format.c
index dc6f8ae..e9b1d5c 100644
--- a/jim-format.c
+++ b/jim-format.c
@@ -177,7 +177,8 @@ Jim_Obj *Jim_FormatString(Jim_Interp *interp, Jim_Obj *fmtObjPtr, int objc, Jim_
*p++ = ch;
format += step;
step = utf8_tounicode(format, &ch);
- } while (sawFlag);
+ /* Only allow one of each flag, so if we have more than 5 flags, stop */
+ } while (sawFlag && (p - spec <= 5));
/*
* Step 3. Minimum field width.
@@ -398,6 +399,13 @@ Jim_Obj *Jim_FormatString(Jim_Interp *interp, Jim_Obj *fmtObjPtr, int objc, Jim_
*p++ = (char) ch;
*p = '\0';
+ /* Put some reasonable limits on the field size */
+ if (width > 10000 || length > 10000 || precision > 10000) {
+ Jim_SetResultString(interp, "format too long", -1);
+ goto error;
+ }
+
+
/* Adjust length for width and precision */
if (width > length) {
length = width;
diff --git a/jim-history.c b/jim-history.c
index 9a56e04..1ae63d7 100644
--- a/jim-history.c
+++ b/jim-history.c
@@ -9,7 +9,7 @@
static int history_cmd_getline(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
Jim_Obj *objPtr;
- char *line = Jim_HistoryGetline(Jim_String(argv[0]));
+ char *line = Jim_HistoryGetline(interp, Jim_String(argv[0]));
/* On EOF returns -1 if varName was specified; otherwise the empty string. */
if (line == NULL) {
@@ -35,6 +35,12 @@ static int history_cmd_getline(Jim_Interp *interp, int argc, Jim_Obj *const *arg
return JIM_OK;
}
+static int history_cmd_setcompletion(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ Jim_HistorySetCompletion(interp, Jim_Length(argv[0]) ? argv[0] : NULL);
+ return JIM_OK;
+}
+
static int history_cmd_load(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
Jim_HistoryLoad(Jim_String(argv[0]));
@@ -67,6 +73,13 @@ static const jim_subcmd_type history_command_table[] = {
2,
/* Description: Reads one line from the user. Similar to gets. */
},
+ { "completion",
+ "command",
+ history_cmd_setcompletion,
+ 1,
+ 1,
+ /* Description: Sets an autocompletion callback command, or none if "" */
+ },
{ "load",
"filename",
history_cmd_load,
@@ -98,25 +111,11 @@ static const jim_subcmd_type history_command_table[] = {
{ NULL }
};
-static int JimHistorySubCmdProc(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
-{
- return Jim_CallSubCmd(interp, Jim_ParseSubCmd(interp, history_command_table, argc, argv), argc, argv);
-}
-
-static void JimHistoryDelProc(Jim_Interp *interp, void *privData)
-{
- Jim_Free(privData);
-}
-
int Jim_historyInit(Jim_Interp *interp)
{
- void **history;
if (Jim_PackageProvide(interp, "history", "1.0", JIM_ERRMSG))
return JIM_ERR;
- history = Jim_Alloc(sizeof(*history));
- *history = NULL;
-
- Jim_CreateCommand(interp, "history", JimHistorySubCmdProc, history, JimHistoryDelProc);
+ Jim_CreateCommand(interp, "history", Jim_SubCmdProc, (void *)history_command_table, NULL);
return JIM_OK;
}
diff --git a/jim-interactive.c b/jim-interactive.c
index 78f5470..baad909 100644
--- a/jim-interactive.c
+++ b/jim-interactive.c
@@ -8,18 +8,44 @@
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
+#ifdef HAVE_SYS_STAT_H
+ #include <sys/stat.h>
+#endif
#include "linenoise.h"
#else
#define MAX_LINE_LEN 512
#endif
+#ifdef USE_LINENOISE
+static void JimCompletionCallback(const char *prefix, linenoiseCompletions *comp, void *userdata);
+static const char completion_callback_assoc_key[] = "interactive-completion";
+#endif
+
/**
* Returns an allocated line, or NULL if EOF.
*/
-char *Jim_HistoryGetline(const char *prompt)
+char *Jim_HistoryGetline(Jim_Interp *interp, const char *prompt)
{
#ifdef USE_LINENOISE
- return linenoise(prompt);
+ struct JimCompletionInfo *compinfo = Jim_GetAssocData(interp, completion_callback_assoc_key);
+ char *result;
+ Jim_Obj *objPtr;
+ long mlmode = 0;
+ /* Set any completion callback just during the call to linenoise()
+ * to allow for per-interp settings
+ */
+ if (compinfo) {
+ linenoiseSetCompletionCallback(JimCompletionCallback, compinfo);
+ }
+ objPtr = Jim_GetVariableStr(interp, "history::multiline", JIM_NONE);
+ if (objPtr && Jim_GetLong(interp, objPtr, &mlmode) == JIM_NONE) {
+ linenoiseSetMultiLine(mlmode);
+ }
+
+ result = linenoise(prompt);
+ /* unset the callback */
+ linenoiseSetCompletionCallback(NULL, NULL);
+ return result;
#else
int len;
char *line = malloc(MAX_LINE_LEN);
@@ -56,7 +82,15 @@ void Jim_HistoryAdd(const char *line)
void Jim_HistorySave(const char *filename)
{
#ifdef USE_LINENOISE
+#ifdef HAVE_UMASK
+ mode_t mask;
+ /* Just u=rw, but note that this is only effective for newly created files */
+ mask = umask(S_IXUSR | S_IRWXG | S_IRWXO);
+#endif
linenoiseHistorySave(filename);
+#ifdef HAVE_UMASK
+ umask(mask);
+#endif
#endif
}
@@ -73,6 +107,68 @@ void Jim_HistoryShow(void)
#endif
}
+#ifdef USE_LINENOISE
+struct JimCompletionInfo {
+ Jim_Interp *interp;
+ Jim_Obj *command;
+};
+
+static void JimCompletionCallback(const char *prefix, linenoiseCompletions *comp, void *userdata)
+{
+ struct JimCompletionInfo *info = (struct JimCompletionInfo *)userdata;
+ Jim_Obj *objv[2];
+ int ret;
+
+ objv[0] = info->command;
+ objv[1] = Jim_NewStringObj(info->interp, prefix, -1);
+
+ ret = Jim_EvalObjVector(info->interp, 2, objv);
+
+ /* XXX: Consider how best to handle errors here. bgerror? */
+ if (ret == JIM_OK) {
+ int i;
+ Jim_Obj *listObj = Jim_GetResult(info->interp);
+ int len = Jim_ListLength(info->interp, listObj);
+ for (i = 0; i < len; i++) {
+ linenoiseAddCompletion(comp, Jim_String(Jim_ListGetIndex(info->interp, listObj, i)));
+ }
+ }
+}
+
+static void JimHistoryFreeCompletion(Jim_Interp *interp, void *data)
+{
+ struct JimCompletionInfo *compinfo = data;
+
+ Jim_DecrRefCount(interp, compinfo->command);
+
+ Jim_Free(compinfo);
+}
+#endif
+
+/**
+ * Sets a completion command to be used with Jim_HistoryGetline()
+ * If commandObj is NULL, deletes any existing completion command.
+ */
+void Jim_HistorySetCompletion(Jim_Interp *interp, Jim_Obj *commandObj)
+{
+#ifdef USE_LINENOISE
+ if (commandObj) {
+ /* Increment now in case the existing object is the same */
+ Jim_IncrRefCount(commandObj);
+ }
+
+ Jim_DeleteAssocData(interp, completion_callback_assoc_key);
+
+ if (commandObj) {
+ struct JimCompletionInfo *compinfo = Jim_Alloc(sizeof(*compinfo));
+ compinfo->interp = interp;
+ compinfo->command = commandObj;
+
+ Jim_SetAssocData(interp, completion_callback_assoc_key, JimHistoryFreeCompletion, compinfo);
+ }
+#endif
+}
+
int Jim_InteractivePrompt(Jim_Interp *interp)
{
int retcode = JIM_OK;
@@ -87,6 +183,8 @@ int Jim_InteractivePrompt(Jim_Interp *interp)
snprintf(history_file, history_len, "%s/.jim_history", home);
Jim_HistoryLoad(history_file);
}
+
+ Jim_HistorySetCompletion(interp, Jim_NewStringObj(interp, "tcl::autocomplete", -1));
#endif
printf("Welcome to Jim version %d.%d\n",
@@ -119,7 +217,7 @@ int Jim_InteractivePrompt(Jim_Interp *interp)
char state;
char *line;
- line = Jim_HistoryGetline(prompt);
+ line = Jim_HistoryGetline(interp, prompt);
if (line == NULL) {
if (errno == EINTR) {
continue;
@@ -168,5 +266,6 @@ int Jim_InteractivePrompt(Jim_Interp *interp)
}
out:
Jim_Free(history_file);
+
return retcode;
}
diff --git a/jim-interp.c b/jim-interp.c
index dd80479..dc45720 100644
--- a/jim-interp.c
+++ b/jim-interp.c
@@ -139,7 +139,7 @@ static void JimInterpCopyVariable(Jim_Interp *target, Jim_Interp *source, const
static int JimInterpCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
Jim_Interp *child;
- char buf[32];
+ char buf[34];
if (argc != 1) {
Jim_WrongNumArgs(interp, 1, argv, "");
@@ -163,7 +163,7 @@ static int JimInterpCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
snprintf(buf, sizeof(buf), "interp.handle%ld", Jim_GetId(interp));
Jim_CreateCommand(interp, buf, JimInterpSubCmdProc, child, JimInterpDelProc);
- Jim_SetResultString(interp, buf, -1);
+ Jim_SetResult(interp, Jim_MakeGlobalNamespaceName(interp, Jim_NewStringObj(interp, buf, -1)));
return JIM_OK;
}
diff --git a/jim-json.c b/jim-json.c
new file mode 100644
index 0000000..1b3869c
--- /dev/null
+++ b/jim-json.c
@@ -0,0 +1,426 @@
+/*
+ * Copyright (c) 2015 - 2016 Svyatoslav Mishyn <juef@openmailbox.org>
+ * Copyright (c) 2019 Steve Bennett <steveb@workware.net.au>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <jim.h>
+
+#include "jsmn/jsmn.h"
+
+/* These are all the schema types we support */
+typedef enum {
+ JSON_BOOL,
+ JSON_OBJ,
+ JSON_LIST,
+ JSON_MIXED,
+ JSON_STR,
+ JSON_NUM,
+ JSON_MAX_TYPE,
+} json_schema_t;
+
+struct json_state {
+ Jim_Obj *nullObj;
+ const char *json;
+ jsmntok_t *tok;
+ int need_subst;
+ /* The following are used for -schema */
+ int enable_schema;
+ int enable_index;
+ Jim_Obj *schemaObj;
+ Jim_Obj *schemaTypeObj[JSON_MAX_TYPE];
+};
+
+static void json_decode_dump_value(Jim_Interp *interp, struct json_state *state, Jim_Obj *list);
+
+/**
+ * Start a new subschema. Returns the previous schemaObj.
+ * Does nothing and returns NULL if -schema is not enabled.
+ */
+static Jim_Obj *json_decode_schema_push(Jim_Interp *interp, struct json_state *state)
+{
+ Jim_Obj *prevSchemaObj = NULL;
+ if (state->enable_schema) {
+ prevSchemaObj = state->schemaObj;
+ state->schemaObj = Jim_NewListObj(interp, NULL, 0);
+ Jim_IncrRefCount(state->schemaObj);
+ }
+ return prevSchemaObj;
+}
+
+/**
+ * Combines the current schema with the previous schema, prevSchemaObj
+ * returned by json_decode_schema_push().
+ * Does nothing if -schema is not enabled.
+ */
+static void json_decode_schema_pop(Jim_Interp *interp, struct json_state *state, Jim_Obj *prevSchemaObj)
+{
+ if (state->enable_schema) {
+ Jim_ListAppendElement(interp, prevSchemaObj, state->schemaObj);
+ Jim_DecrRefCount(interp, state->schemaObj);
+ state->schemaObj = prevSchemaObj;
+ }
+}
+
+/**
+ * Appends the schema type to state->schemaObj based on 'type'
+ */
+static void json_decode_add_schema_type(Jim_Interp *interp, struct json_state *state, json_schema_t type)
+{
+ static const char * const schema_names[] = {
+ "bool",
+ "obj",
+ "list",
+ "mixed",
+ "str",
+ "num",
+ };
+ assert(type >= 0 && type < JSON_MAX_TYPE);
+ /* Share multiple instances of the same type */
+ if (state->schemaTypeObj[type] == NULL) {
+ state->schemaTypeObj[type] = Jim_NewStringObj(interp, schema_names[type], -1);
+ }
+ Jim_ListAppendElement(interp, state->schemaObj, state->schemaTypeObj[type]);
+}
+
+/**
+ * Returns the schema type for the given token.
+ * There is a one-to-one correspondence except for JSMN_PRIMITIVE
+ * which will return JSON_BOOL for true, false and JSON_NUM otherise.
+ */
+static json_schema_t json_decode_get_type(const jsmntok_t *tok, const char *json)
+{
+ switch (tok->type) {
+ case JSMN_PRIMITIVE:
+ assert(json);
+ if (json[tok->start] == 't' || json[tok->start] == 'f') {
+ return JSON_BOOL;
+ }
+ return JSON_NUM;
+ case JSMN_OBJECT:
+ return JSON_OBJ;
+ case JSMN_ARRAY:
+ /* Return mixed by default - need other checks to select list instead */
+ return JSON_MIXED;
+ case JSMN_STRING:
+ default:
+ return JSON_STR;
+ }
+}
+
+/**
+ * Returns the current object (state->tok) as a Tcl list.
+ *
+ * state->tok is incremented to just past the object that was dumped.
+ */
+static Jim_Obj *
+json_decode_dump_container(Jim_Interp *interp, struct json_state *state)
+{
+ int i;
+ Jim_Obj *list = Jim_NewListObj(interp, NULL, 0);
+ int size = state->tok->size;
+ int type = state->tok->type;
+ json_schema_t container_type = JSON_OBJ; /* JSON_LIST, JSON_MIXED or JSON_OBJ */
+
+ if (state->schemaObj) {
+ json_schema_t list_type;
+ /* Figure out the type to use for the container */
+ if (type == JSMN_ARRAY) {
+ /* If every element of the array is of the same primitive schema type (str, bool or num),
+ * we can use "list", otherwise need to use "mixed"
+ */
+ container_type = JSON_LIST;
+ if (size) {
+ list_type = json_decode_get_type(&state->tok[1], state->json);
+
+ if (list_type == JSON_BOOL || list_type == JSON_STR || list_type == JSON_NUM) {
+ for (i = 2; i <= size; i++) {
+ if (json_decode_get_type(state->tok + i, state->json) != list_type) {
+ /* Can't use list */
+ container_type = JSON_MIXED;
+ break;
+ }
+ }
+ }
+ else {
+ container_type = JSON_MIXED;
+ }
+ }
+ }
+ json_decode_add_schema_type(interp, state, container_type);
+ if (container_type == JSON_LIST && size) {
+ json_decode_add_schema_type(interp, state, list_type);
+ }
+ }
+
+ state->tok++;
+
+ for (i = 0; i < size; i++) {
+ if (type == JSMN_OBJECT) {
+ /* Dump the object key */
+ if (state->enable_schema) {
+ const char *p = state->json + state->tok->start;
+ int len = state->tok->end - state->tok->start;
+ Jim_ListAppendElement(interp, state->schemaObj, Jim_NewStringObj(interp, p, len));
+ }
+ json_decode_dump_value(interp, state, list);
+ }
+
+ if (state->enable_index && type == JSMN_ARRAY) {
+ Jim_ListAppendElement(interp, list, Jim_NewIntObj(interp, i));
+ }
+
+ if (state->schemaObj && container_type != JSON_LIST) {
+ if (state->tok->type == JSMN_STRING || state->tok->type == JSMN_PRIMITIVE) {
+ json_decode_add_schema_type(interp, state, json_decode_get_type(state->tok, state->json));
+ }
+ }
+
+ /* Dump the array or object value */
+ json_decode_dump_value(interp, state, list);
+ }
+
+ return list;
+}
+
+/**
+ * Appends the value at state->tok to 'list' and increments state->tok to just
+ * past that token.
+ *
+ * Also appends to the schema if state->enable_schema is set.
+ */
+static void
+json_decode_dump_value(Jim_Interp *interp, struct json_state *state, Jim_Obj *list)
+{
+ const jsmntok_t *t = state->tok;
+
+ if (t->type == JSMN_STRING || t->type == JSMN_PRIMITIVE) {
+ Jim_Obj *elem;
+ int len = t->end - t->start;
+ const char *p = state->json + t->start;
+ if (t->type == JSMN_STRING) {
+ /* Do we need to process backslash escapes? */
+ if (state->need_subst == 0 && memchr(p, '\\', len) != NULL) {
+ state->need_subst = 1;
+ }
+ elem = Jim_NewStringObj(interp, p, len);
+ } else if (p[0] == 'n') { /* null */
+ elem = state->nullObj;
+ } else if (p[0] == 'I') {
+ elem = Jim_NewStringObj(interp, "Inf", -1);
+ } else if (p[0] == '-' && p[1] == 'I') {
+ elem = Jim_NewStringObj(interp, "-Inf", -1);
+ } else { /* number, true or false */
+ elem = Jim_NewStringObj(interp, p, len);
+ }
+
+ Jim_ListAppendElement(interp, list, elem);
+ state->tok++;
+ }
+ else {
+ Jim_Obj *prevSchemaObj = json_decode_schema_push(interp, state);
+ Jim_Obj *newList = json_decode_dump_container(interp, state);
+ Jim_ListAppendElement(interp, list, newList);
+ json_decode_schema_pop(interp, state, prevSchemaObj);
+ }
+}
+
+/* Parses the options ?-null string? ?-schema? *state.
+ * Any options not present are not set.
+ *
+ * Returns JIM_OK or JIM_ERR and sets an error result.
+ */
+static int parse_json_decode_options(Jim_Interp *interp, int argc, Jim_Obj *const argv[], struct json_state *state)
+{
+ static const char * const options[] = { "-index", "-null", "-schema", NULL };
+ enum { OPT_INDEX, OPT_NULL, OPT_SCHEMA, };
+ int i;
+
+ for (i = 1; i < argc - 1; i++) {
+ int option;
+ if (Jim_GetEnum(interp, argv[i], options, &option, NULL, JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) {
+ return JIM_ERR;
+ }
+ switch (option) {
+ case OPT_INDEX:
+ state->enable_index = 1;
+ break;
+
+ case OPT_NULL:
+ i++;
+ Jim_IncrRefCount(argv[i]);
+ Jim_DecrRefCount(interp, state->nullObj);
+ state->nullObj = argv[i];
+ break;
+
+ case OPT_SCHEMA:
+ state->enable_schema = 1;
+ break;
+ }
+ }
+
+ if (i != argc - 1) {
+ Jim_WrongNumArgs(interp, 1, argv,
+ "?-index? ?-null nullvalue? ?-schema? json");
+ return JIM_ERR;
+ }
+
+ return JIM_OK;
+}
+
+/**
+ * Use jsmn to tokenise the JSON string 'json' of length 'len'
+ *
+ * Returns an allocated array of tokens or NULL on error (and sets an error result)
+ */
+static jsmntok_t *
+json_decode_tokenize(Jim_Interp *interp, const char *json, size_t len)
+{
+ jsmntok_t *t;
+ jsmn_parser parser;
+ int n;
+
+ /* Parse once just to find the number of tokens */
+ jsmn_init(&parser);
+ n = jsmn_parse(&parser, json, len, NULL, 0);
+
+error:
+ switch (n) {
+ case JSMN_ERROR_INVAL:
+ Jim_SetResultString(interp, "invalid JSON string", -1);
+ return NULL;
+
+ case JSMN_ERROR_PART:
+ Jim_SetResultString(interp, "truncated JSON string", -1);
+ return NULL;
+
+ case 0:
+ Jim_SetResultString(interp, "root element must be an object or an array", -1);
+ return NULL;
+
+ default:
+ break;
+ }
+
+ if (n < 0) {
+ return NULL;
+ }
+
+ t = Jim_Alloc(n * sizeof(*t));
+
+ jsmn_init(&parser);
+ n = jsmn_parse(&parser, json, len, t, n);
+ if (t->type != JSMN_OBJECT && t->type != JSMN_ARRAY) {
+ n = 0;
+ }
+ if (n <= 0) {
+ Jim_Free(t);
+ goto error;
+ }
+
+ return t;
+}
+
+/**
+ * json::decode returns the decoded data structure.
+ *
+ * If -schema is specified, returns a list of {data schema}
+ */
+static int
+json_decode(Jim_Interp *interp, int argc, Jim_Obj *const argv[])
+{
+ Jim_Obj *list;
+ jsmntok_t *tokens;
+ int len;
+ int ret = JIM_ERR;
+ struct json_state state;
+
+ memset(&state, 0, sizeof(state));
+
+ state.nullObj = Jim_NewStringObj(interp, "null", -1);
+ Jim_IncrRefCount(state.nullObj);
+
+ if (parse_json_decode_options(interp, argc, argv, &state) != JIM_OK) {
+ goto done;
+ }
+
+ state.json = Jim_GetString(argv[argc - 1], &len);
+
+ if (!len) {
+ Jim_SetResultString(interp, "empty JSON string", -1);
+ goto done;
+ }
+ if ((tokens = json_decode_tokenize(interp, state.json, len)) == NULL) {
+ goto done;
+ }
+ state.tok = tokens;
+ json_decode_schema_push(interp, &state);
+
+ list = json_decode_dump_container(interp, &state);
+ Jim_Free(tokens);
+ ret = JIM_OK;
+
+ /* Make sure the refcount doesn't go to 0 during Jim_SubstObj() */
+ Jim_IncrRefCount(list);
+
+ if (state.need_subst) {
+ /* Subsitute backslashes in the returned dictionary.
+ * Need to be careful of refcounts.
+ * Note that Jim_SubstObj() supports a few more escapes than
+ * JSON requires, but should give the same result for all legal escapes.
+ */
+ Jim_Obj *newList;
+ Jim_SubstObj(interp, list, &newList, JIM_SUBST_FLAG | JIM_SUBST_NOCMD | JIM_SUBST_NOVAR);
+ Jim_IncrRefCount(newList);
+ Jim_DecrRefCount(interp, list);
+ list = newList;
+ }
+
+ if (state.schemaObj) {
+ Jim_Obj *resultObj = Jim_NewListObj(interp, NULL, 0);
+ Jim_ListAppendElement(interp, resultObj, list);
+ Jim_ListAppendElement(interp, resultObj, state.schemaObj);
+ Jim_SetResult(interp, resultObj);
+ Jim_DecrRefCount(interp, state.schemaObj);
+ }
+ else {
+ Jim_SetResult(interp, list);
+ }
+ Jim_DecrRefCount(interp, list);
+
+done:
+ Jim_DecrRefCount(interp, state.nullObj);
+
+ return ret;
+}
+
+int
+Jim_jsonInit(Jim_Interp *interp)
+{
+ if (Jim_PackageProvide(interp, "json", "1.0", JIM_ERRMSG) != JIM_OK) {
+ return JIM_ERR;
+ }
+
+ Jim_CreateCommand(interp, "json::decode", json_decode, NULL, NULL);
+ /* Load the Tcl implementation of the json encoder if possible */
+ Jim_PackageRequire(interp, "jsonencode", 0);
+ return JIM_OK;
+}
diff --git a/jim-namespace.c b/jim-namespace.c
index bcc7259..9920488 100644
--- a/jim-namespace.c
+++ b/jim-namespace.c
@@ -217,7 +217,7 @@ static int JimNamespaceCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
}
if (Jim_GetEnum(interp, argv[1], options, &option, "subcommand", JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) {
- return JIM_ERR;
+ return Jim_CheckShowCommands(interp, argv[1], options);
}
switch (option) {
diff --git a/jim-nosignal.c b/jim-nosignal.c
new file mode 100644
index 0000000..bc39712
--- /dev/null
+++ b/jim-nosignal.c
@@ -0,0 +1,28 @@
+#include <stdio.h>
+#include <signal.h>
+
+#include <jim-signal.h>
+#include <jim.h>
+
+/* Implement trivial Jim_SignalId() just good enough for JimMakeErrorCode() in [exec] */
+
+
+/* This works for mingw, but is not really portable */
+#ifndef SIGPIPE
+#define SIGPIPE 13
+#endif
+#ifndef SIGINT
+#define SIGINT 2
+#endif
+
+const char *Jim_SignalId(int sig)
+{
+ static char buf[10];
+ switch (sig) {
+ case SIGINT: return "SIGINT";
+ case SIGPIPE: return "SIGPIPE";
+
+ }
+ snprintf(buf, sizeof(buf), "%d", sig);
+ return buf;
+}
diff --git a/jim-posix.c b/jim-posix.c
index af8c0f1..a4ba61e 100644
--- a/jim-posix.c
+++ b/jim-posix.c
@@ -37,7 +37,6 @@
#include <sys/wait.h>
#include <unistd.h>
#include <string.h>
-#include <signal.h>
#include <errno.h>
#include "jimautoconf.h"
@@ -72,88 +71,6 @@ static int Jim_PosixForkCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar
}
#endif
-/*
- * os.wait ?-nohang? pid
- *
- * An interface to waitpid(2)
- *
- * Returns a 3 element list.
- *
- * If -nohang is specified, and the process is still alive, returns
- *
- * {0 none 0}
- *
- * If the process does not exist or has already been waited for, returns:
- *
- * {-1 error <error-description>}
- *
- * If the process exited normally, returns:
- *
- * {<pid> exit <exit-status>}
- *
- * If the process terminated on a signal, returns:
- *
- * {<pid> signal <signal-number>}
- *
- * Otherwise (core dump, stopped, continued, ...), returns:
- *
- * {<pid> other 0}
- */
-static int Jim_PosixWaitCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
-{
- int nohang = 0;
- long pid;
- int status;
- Jim_Obj *listObj;
- const char *type;
- int value;
-
- if (argc > 1 && Jim_CompareStringImmediate(interp, argv[1], "-nohang")) {
- nohang = 1;
- }
- if (argc != nohang + 2) {
- Jim_WrongNumArgs(interp, 1, argv, "?-nohang? pid");
- return JIM_ERR;
- }
- if (Jim_GetLong(interp, argv[nohang + 1], &pid) != JIM_OK) {
- return JIM_ERR;
- }
-
- pid = waitpid(pid, &status, nohang ? WNOHANG : 0);
- listObj = Jim_NewListObj(interp, NULL, 0);
- Jim_ListAppendElement(interp, listObj, Jim_NewIntObj(interp, pid));
- if (pid < 0) {
- type = "error";
- value = errno;
- }
- else if (pid == 0) {
- type = "none";
- value = 0;
- }
- else if (WIFEXITED(status)) {
- type = "exit";
- value = WEXITSTATUS(status);
- }
- else if (WIFSIGNALED(status)) {
- type = "signal";
- value = WTERMSIG(status);
- }
- else {
- type = "other";
- value = 0;
- }
-
- Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, type, -1));
- if (pid < 0) {
- Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, strerror(value), -1));
- }
- else {
- Jim_ListAppendElement(interp, listObj, Jim_NewIntObj(interp, value));
- }
- Jim_SetResult(interp, listObj);
- return JIM_OK;
-}
-
static int Jim_PosixGetidsCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
Jim_Obj *objv[8];
@@ -218,17 +135,6 @@ static int Jim_PosixUptimeCommand(Jim_Interp *interp, int argc, Jim_Obj *const *
return JIM_OK;
}
-static int Jim_PosixPidCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
-{
- if (argc != 1) {
- Jim_WrongNumArgs(interp, 1, argv, "");
- return JIM_ERR;
- }
-
- Jim_SetResultInt(interp, getpid());
- return JIM_OK;
-}
-
int Jim_posixInit(Jim_Interp *interp)
{
if (Jim_PackageProvide(interp, "posix", "1.0", JIM_ERRMSG))
@@ -237,10 +143,8 @@ int Jim_posixInit(Jim_Interp *interp)
#ifdef HAVE_FORK
Jim_CreateCommand(interp, "os.fork", Jim_PosixForkCommand, NULL, NULL);
#endif
- Jim_CreateCommand(interp, "os.wait", Jim_PosixWaitCommand, NULL, NULL);
Jim_CreateCommand(interp, "os.getids", Jim_PosixGetidsCommand, NULL, NULL);
Jim_CreateCommand(interp, "os.gethostname", Jim_PosixGethostnameCommand, NULL, NULL);
Jim_CreateCommand(interp, "os.uptime", Jim_PosixUptimeCommand, NULL, NULL);
- Jim_CreateCommand(interp, "pid", Jim_PosixPidCommand, NULL, NULL);
return JIM_OK;
}
diff --git a/jim-regexp.c b/jim-regexp.c
index 8eb457d..b0411f8 100644
--- a/jim-regexp.c
+++ b/jim-regexp.c
@@ -55,13 +55,18 @@
#include <regex.h>
#endif
#include "jim.h"
+#include "utf8.h"
static void FreeRegexpInternalRep(Jim_Interp *interp, Jim_Obj *objPtr)
{
- regfree(objPtr->internalRep.regexpValue.compre);
- Jim_Free(objPtr->internalRep.regexpValue.compre);
+ regfree(objPtr->internalRep.ptrIntValue.ptr);
+ Jim_Free(objPtr->internalRep.ptrIntValue.ptr);
}
+/* internal rep is stored in ptrIntvalue
+ * ptr = compiled regex
+ * int1 = flags
+ */
static const Jim_ObjType regexpObjType = {
"regexp",
FreeRegexpInternalRep,
@@ -78,9 +83,9 @@ static regex_t *SetRegexpFromAny(Jim_Interp *interp, Jim_Obj *objPtr, unsigned f
/* Check if the object is already an uptodate variable */
if (objPtr->typePtr == &regexpObjType &&
- objPtr->internalRep.regexpValue.compre && objPtr->internalRep.regexpValue.flags == flags) {
+ objPtr->internalRep.ptrIntValue.ptr && objPtr->internalRep.ptrIntValue.int1 == flags) {
/* nothing to do */
- return objPtr->internalRep.regexpValue.compre;
+ return objPtr->internalRep.ptrIntValue.ptr;
}
/* Not a regexp or the flags do not match */
@@ -102,8 +107,8 @@ static regex_t *SetRegexpFromAny(Jim_Interp *interp, Jim_Obj *objPtr, unsigned f
Jim_FreeIntRep(interp, objPtr);
objPtr->typePtr = &regexpObjType;
- objPtr->internalRep.regexpValue.flags = flags;
- objPtr->internalRep.regexpValue.compre = compre;
+ objPtr->internalRep.ptrIntValue.int1 = flags;
+ objPtr->internalRep.ptrIntValue.ptr = compre;
return compre;
}
@@ -222,7 +227,7 @@ int Jim_RegexpCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
source_str += source_len;
}
else if (offset > 0) {
- source_str += offset;
+ source_str += utf8_index(source_str, offset);
}
eflags |= REG_NOTBOL;
}
@@ -276,16 +281,15 @@ int Jim_RegexpCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
}
}
else {
- int len = pmatch[j].rm_eo - pmatch[j].rm_so;
-
if (opt_indices) {
- Jim_ListAppendElement(interp, resultObj, Jim_NewIntObj(interp,
- offset + pmatch[j].rm_so));
- Jim_ListAppendElement(interp, resultObj, Jim_NewIntObj(interp,
- offset + pmatch[j].rm_so + len - 1));
+ /* rm_so and rm_eo are byte offsets. We need char offsets */
+ int so = utf8_strlen(source_str, pmatch[j].rm_so);
+ int eo = utf8_strlen(source_str, pmatch[j].rm_eo);
+ Jim_ListAppendElement(interp, resultObj, Jim_NewIntObj(interp, offset + so));
+ Jim_ListAppendElement(interp, resultObj, Jim_NewIntObj(interp, offset + eo - 1));
}
else {
- Jim_AppendString(interp, resultObj, source_str + pmatch[j].rm_so, len);
+ Jim_AppendString(interp, resultObj, source_str + pmatch[j].rm_so, pmatch[j].rm_eo - pmatch[j].rm_so);
}
}
@@ -306,7 +310,7 @@ int Jim_RegexpCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
try_next_match:
if (opt_all && (pattern[0] != '^' || (regcomp_flags & REG_NEWLINE)) && *source_str) {
if (pmatch[0].rm_eo) {
- offset += pmatch[0].rm_eo;
+ offset += utf8_strlen(source_str, pmatch[0].rm_eo);
source_str += pmatch[0].rm_eo;
}
else {
@@ -437,6 +441,8 @@ int Jim_RegsubCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
offset = 0;
}
}
+ /* Convert from character offset to byte offset */
+ offset = utf8_index(source_str, offset);
/* Copy the part before -start */
Jim_AppendString(interp, resultObj, source_str, offset);
diff --git a/jim-signal.c b/jim-signal.c
index b760ede..7d02e68 100644
--- a/jim-signal.c
+++ b/jim-signal.c
@@ -16,13 +16,13 @@
#define MAX_SIGNALS_WIDE (sizeof(jim_wide) * 8)
#if defined(NSIG)
- #define MAX_SIGNALS ((NSIG < MAX_SIGNALS_WIDE) ? NSIG : MAX_SIGNALS_WIDE)
+ #define MAX_SIGNALS (int)((NSIG < MAX_SIGNALS_WIDE) ? NSIG : MAX_SIGNALS_WIDE)
#else
- #define MAX_SIGNALS MAX_SIGNALS_WIDE
+ #define MAX_SIGNALS (int)MAX_SIGNALS_WIDE
#endif
static jim_wide *sigloc;
-static jim_wide sigsblocked;
+static jim_wide sigsignored;
static struct sigaction *sa_old;
static struct {
int status;
@@ -34,16 +34,16 @@ static struct {
static void signal_handler(int sig)
{
- /* We just remember which signals occurred. Jim_Eval() will
- * notice this as soon as it can and throw an error
+ /* Remember which signals occurred and store in *sigloc.
+ * Jim_Eval() will notice this as soon as it can and throw an error
*/
*sigloc |= sig_to_bit(sig);
}
static void signal_ignorer(int sig)
{
- /* We just remember which signals occurred */
- sigsblocked |= sig_to_bit(sig);
+ /* Remember which signals occurred for access by 'signal check' */
+ sigsignored |= sig_to_bit(sig);
}
static void signal_init_names(void)
@@ -128,16 +128,6 @@ const char *Jim_SignalId(int sig)
return "unknown signal";
}
-const char *Jim_SignalName(int sig)
-{
-#ifdef HAVE_SYS_SIGLIST
- if (sig >= 0 && sig < NSIG) {
- return sys_siglist[sig];
- }
-#endif
- return Jim_SignalId(sig);
-}
-
/**
* Given the name of a signal, returns the signal value if found,
* or returns -1 (and sets an error) if not found.
@@ -179,6 +169,7 @@ static int find_signal_by_name(Jim_Interp *interp, const char *name)
#define SIGNAL_ACTION_HANDLE 1
#define SIGNAL_ACTION_IGNORE -1
+#define SIGNAL_ACTION_BLOCK -2
#define SIGNAL_ACTION_DEFAULT 0
static int do_signal_cmd(Jim_Interp *interp, int action, int argc, Jim_Obj *const *argv)
@@ -204,9 +195,13 @@ static int do_signal_cmd(Jim_Interp *interp, int action, int argc, Jim_Obj *cons
if (action == SIGNAL_ACTION_HANDLE) {
sa.sa_handler = signal_handler;
}
- else {
+ else if (action == SIGNAL_ACTION_IGNORE) {
sa.sa_handler = signal_ignorer;
}
+ else {
+ /* SIGNAL_ACTION_BLOCK */
+ sa.sa_handler = SIG_IGN;
+ }
}
/* Iterate through the provided signals */
@@ -219,6 +214,7 @@ static int do_signal_cmd(Jim_Interp *interp, int action, int argc, Jim_Obj *cons
if (action != siginfo[sig].status) {
/* Need to change the action for this signal */
switch (action) {
+ case SIGNAL_ACTION_BLOCK:
case SIGNAL_ACTION_HANDLE:
case SIGNAL_ACTION_IGNORE:
if (siginfo[sig].status == SIGNAL_ACTION_DEFAULT) {
@@ -256,6 +252,11 @@ static int signal_cmd_ignore(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
return do_signal_cmd(interp, SIGNAL_ACTION_IGNORE, argc, argv);
}
+static int signal_cmd_block(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ return do_signal_cmd(interp, SIGNAL_ACTION_BLOCK, argc, argv);
+}
+
static int signal_cmd_default(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
return do_signal_cmd(interp, SIGNAL_ACTION_DEFAULT, argc, argv);
@@ -279,7 +280,7 @@ static int signal_cmd_check(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
int clear = 0;
jim_wide mask = 0;
- jim_wide blocked;
+ jim_wide ignored;
if (argc > 0 && Jim_CompareStringImmediate(interp, argv[0], "-clear")) {
clear++;
@@ -302,17 +303,13 @@ static int signal_cmd_check(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
mask = ~mask;
}
- if ((sigsblocked & mask) == 0) {
- /* No matching signals, so empty result and nothing to do */
- return JIM_OK;
- }
/* Be careful we don't have a race condition where signals are cleared but not returned */
- blocked = sigsblocked & mask;
+ ignored = sigsignored & mask;
if (clear) {
- sigsblocked &= ~blocked;
+ sigsignored &= ~ignored;
}
/* Set the result */
- signal_set_sigmask_result(interp, blocked);
+ signal_set_sigmask_result(interp, ignored);
return JIM_OK;
}
@@ -326,9 +323,9 @@ static int signal_cmd_throw(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
}
}
- /* If the signal is ignored (blocked) ... */
+ /* If the signal is ignored ... */
if (siginfo[sig].status == SIGNAL_ACTION_IGNORE) {
- sigsblocked |= sig_to_bit(sig);
+ sigsignored |= sig_to_bit(sig);
return JIM_OK;
}
@@ -380,6 +377,13 @@ static const jim_subcmd_type signal_command_table[] = {
-1,
/* Description: Lists ignored signals, or adds to ignored signals */
},
+ { "block",
+ "?signals ...?",
+ signal_cmd_block,
+ 0,
+ -1,
+ /* Description: Lists blocked signals, or adds to blocked signals */
+ },
{ "default",
"?signals ...?",
signal_cmd_default,
@@ -404,6 +408,25 @@ static const jim_subcmd_type signal_command_table[] = {
{ NULL }
};
+/**
+ * Restore default signal handling.
+ */
+static void JimSignalCmdDelete(Jim_Interp *interp, void *privData)
+{
+ int i;
+ if (sa_old) {
+ for (i = 1; i < MAX_SIGNALS; i++) {
+ if (siginfo[i].status != SIGNAL_ACTION_DEFAULT) {
+ sigaction(i, &sa_old[i], 0);
+ siginfo[i].status = SIGNAL_ACTION_DEFAULT;
+ }
+ }
+ }
+ Jim_Free(sa_old);
+ sa_old = NULL;
+ sigloc = NULL;
+}
+
static int Jim_AlarmCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
int ret;
@@ -510,19 +533,23 @@ int Jim_signalInit(Jim_Interp *interp)
if (Jim_PackageProvide(interp, "signal", "1.0", JIM_ERRMSG))
return JIM_ERR;
- signal_init_names();
+ Jim_CreateCommand(interp, "alarm", Jim_AlarmCmd, 0, 0);
+ Jim_CreateCommand(interp, "kill", Jim_KillCmd, 0, 0);
+ /* Sleep is slightly dubious here */
+ Jim_CreateCommand(interp, "sleep", Jim_SleepCmd, 0, 0);
/* Teach the jim core how to set a result from a sigmask */
interp->signal_set_result = signal_set_sigmask_result;
- /* Make sure we know where to store the signals which occur */
- sigloc = &interp->sigmask;
+ /* Currently only the top level interp supports signals */
+ if (!sigloc) {
+ signal_init_names();
- Jim_CreateCommand(interp, "signal", Jim_SubCmdProc, (void *)signal_command_table, NULL);
- Jim_CreateCommand(interp, "alarm", Jim_AlarmCmd, 0, 0);
- Jim_CreateCommand(interp, "kill", Jim_KillCmd, 0, 0);
+ /* Make sure we know where to store the signals which occur */
+ sigloc = &interp->sigmask;
+
+ Jim_CreateCommand(interp, "signal", Jim_SubCmdProc, (void *)signal_command_table, JimSignalCmdDelete);
+ }
- /* Sleep is slightly dubious here */
- Jim_CreateCommand(interp, "sleep", Jim_SleepCmd, 0, 0);
return JIM_OK;
}
diff --git a/jim-signal.h b/jim-signal.h
index 84dcd8b..09f688a 100644
--- a/jim-signal.h
+++ b/jim-signal.h
@@ -11,14 +11,6 @@ extern "C" {
*/
const char *Jim_SignalId(int sig);
-/**
- * If available, returns a short description of the given signal.
- * e.g. "Terminated", "Interrupted"
- *
- * Otherwise returns the same as Jim_SignalId()
- */
-const char *Jim_SignalName(int sig);
-
#ifdef __cplusplus
}
#endif
diff --git a/jim-sqlite3.c b/jim-sqlite3.c
index e5fa304..67bb83d 100644
--- a/jim-sqlite3.c
+++ b/jim-sqlite3.c
@@ -177,7 +177,7 @@ static int JimSqliteHandlerCommand(Jim_Interp *interp, int argc, Jim_Obj *const
}
Jim_IncrRefCount(nullStrObj);
if (argc < 3) {
- Jim_WrongNumArgs(interp, 2, argv, "query ?args?");
+ Jim_WrongNumArgs(interp, 2, argv, "?args?");
goto err;
}
objPtr = JimSqliteFormatQuery(interp, argv[2], argc - 3, argv + 3);
diff --git a/jim-subcmd.c b/jim-subcmd.c
index c522830..1a090d5 100644
--- a/jim-subcmd.c
+++ b/jim-subcmd.c
@@ -41,18 +41,14 @@ static void add_commands(Jim_Interp *interp, const jim_subcmd_type * ct, const c
static void bad_subcmd(Jim_Interp *interp, const jim_subcmd_type * command_table, const char *type,
Jim_Obj *cmd, Jim_Obj *subcmd)
{
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp), Jim_String(cmd), ", ", type,
- " command \"", Jim_String(subcmd), "\": should be ", NULL);
+ Jim_SetResultFormatted(interp, "%#s, %s command \"%#s\": should be ", cmd, type, subcmd);
add_commands(interp, command_table, ", ");
}
static void show_cmd_usage(Jim_Interp *interp, const jim_subcmd_type * command_table, int argc,
Jim_Obj *const *argv)
{
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp), "Usage: \"", Jim_String(argv[0]),
- " command ... \", where command is one of: ", NULL);
+ Jim_SetResultFormatted(interp, "Usage: \"%#s command ... \", where command is one of: ", argv[0]);
add_commands(interp, command_table, ", ");
}
@@ -74,6 +70,18 @@ static void set_wrong_args(Jim_Interp *interp, const jim_subcmd_type * command_t
Jim_AppendStrings(interp, Jim_GetResult(interp), "\"", NULL);
}
+/* internal rep is stored in ptrIntvalue
+ * ptr = command_table
+ * int1 = index
+ */
+static const Jim_ObjType subcmdLookupObjType = {
+ "subcmd-lookup",
+ NULL,
+ NULL,
+ NULL,
+ JIM_TYPE_REFERENCES
+};
+
const jim_subcmd_type *Jim_ParseSubCmd(Jim_Interp *interp, const jim_subcmd_type * command_table,
int argc, Jim_Obj *const *argv)
{
@@ -82,21 +90,24 @@ const jim_subcmd_type *Jim_ParseSubCmd(Jim_Interp *interp, const jim_subcmd_type
int cmdlen;
Jim_Obj *cmd;
const char *cmdstr;
- const char *cmdname;
int help = 0;
- cmdname = Jim_String(argv[0]);
-
if (argc < 2) {
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp), "wrong # args: should be \"", cmdname,
- " command ...\"\n", NULL);
- Jim_AppendStrings(interp, Jim_GetResult(interp), "Use \"", cmdname, " -help ?command?\" for help", NULL);
+ Jim_SetResultFormatted(interp, "wrong # args: should be \"%#s command ...\"\n"
+ "Use \"%#s -help ?command?\" for help", argv[0], argv[0]);
return 0;
}
cmd = argv[1];
+ /* Use cached lookup if possible */
+ if (cmd->typePtr == &subcmdLookupObjType) {
+ if (cmd->internalRep.ptrIntValue.ptr == command_table) {
+ ct = command_table + cmd->internalRep.ptrIntValue.int1;
+ goto found;
+ }
+ }
+
/* Check for the help command */
if (Jim_CompareStringImmediate(interp, cmd, "-help")) {
if (argc == 2) {
@@ -164,6 +175,13 @@ const jim_subcmd_type *Jim_ParseSubCmd(Jim_Interp *interp, const jim_subcmd_type
return &dummy_subcmd;
}
+ /* Cache the result for a successful non-help lookup */
+ Jim_FreeIntRep(interp, cmd);
+ cmd->typePtr = &subcmdLookupObjType;
+ cmd->internalRep.ptrIntValue.ptr = (void *)command_table;
+ cmd->internalRep.ptrIntValue.int1 = ct - command_table;
+
+found:
/* Check the number of args */
if (argc - 2 < ct->minargs || (ct->maxargs >= 0 && argc - 2 > ct->maxargs)) {
Jim_SetResultString(interp, "wrong # args: should be \"", -1);
diff --git a/jim-tclprefix.c b/jim-tclprefix.c
index e041cc6..dcffd4d 100644
--- a/jim-tclprefix.c
+++ b/jim-tclprefix.c
@@ -43,7 +43,7 @@ static int Jim_TclPrefixCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const
return JIM_ERR;
}
if (Jim_GetEnum(interp, argv[1], options, &option, NULL, JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK)
- return JIM_ERR;
+ return Jim_CheckShowCommands(interp, argv[1], options);
switch (option) {
case OPT_MATCH:{
@@ -53,7 +53,7 @@ static int Jim_TclPrefixCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const
const char **table;
Jim_Obj *tableObj;
Jim_Obj *errorObj = NULL;
- Jim_Obj *messageObj = NULL;
+ const char *message = "option";
static const char * const matchoptions[] = { "-error", "-exact", "-message", NULL };
enum { OPT_MATCH_ERROR, OPT_MATCH_EXACT, OPT_MATCH_MESSAGE };
int flags = JIM_ERRMSG | JIM_ENUM_ABBREV;
@@ -91,7 +91,7 @@ static int Jim_TclPrefixCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const
Jim_SetResultString(interp, "missing message", -1);
return JIM_ERR;
}
- messageObj = argv[i];
+ message = Jim_String(argv[i]);
break;
}
}
@@ -104,7 +104,7 @@ static int Jim_TclPrefixCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const
}
table[i] = NULL;
- ret = Jim_GetEnum(interp, stringObj, table, &i, messageObj ? Jim_String(messageObj) : NULL, flags);
+ ret = Jim_GetEnum(interp, stringObj, table, &i, message, flags);
Jim_Free(table);
if (ret == JIM_OK) {
Jim_ListIndex(interp, tableObj, i, &objPtr, JIM_NONE);
@@ -112,7 +112,7 @@ static int Jim_TclPrefixCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const
return JIM_OK;
}
if (tablesize == 0) {
- Jim_SetResultFormatted(interp, "bad option \"%#s\": no valid options", stringObj);
+ Jim_SetResultFormatted(interp, "bad %s \"%#s\": no valid options", message, stringObj);
return JIM_ERR;
}
if (errorObj) {
@@ -128,7 +128,6 @@ static int Jim_TclPrefixCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const
}
return JIM_ERR;
}
- break;
case OPT_ALL:
if (argc != 4) {
@@ -157,11 +156,11 @@ static int Jim_TclPrefixCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const
else if (Jim_ListLength(interp, argv[2])) {
const char *longeststr = NULL;
int longestlen = 0;
+ int i;
+ int listlen = Jim_ListLength(interp, argv[2]);
stringObj = argv[3];
- int i;
- int listlen = Jim_ListLength(interp, argv[2]);
for (i = 0; i < listlen; i++) {
Jim_Obj *valObj = Jim_ListGetIndex(interp, argv[2], i);
@@ -184,7 +183,7 @@ static int Jim_TclPrefixCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const
return JIM_OK;
}
}
- return JIM_ERR;
+ return JIM_ERR; /* Cannot ever get here */
}
int Jim_tclprefixInit(Jim_Interp *interp)
diff --git a/jim-tty.c b/jim-tty.c
new file mode 100644
index 0000000..5d9cee7
--- /dev/null
+++ b/jim-tty.c
@@ -0,0 +1,343 @@
+/*
+ * Support for tty settings using termios
+ *
+ * (c) 2016 Steve Bennett <steveb@workware.net.au>
+ *
+ */
+
+/* termios support is required */
+
+#include <jim-tty.h>
+#include <termios.h>
+
+static const struct {
+ unsigned baud;
+ speed_t speed;
+} baudtable[] = {
+ { 0, B0 },
+ { 50, B50 },
+ { 75, B75 },
+ { 110, B110 },
+ { 134, B134 },
+ { 150, B150 },
+ { 200, B200 },
+ { 300, B300 },
+ { 600, B600 },
+ { 1200, B1200 },
+ { 1800, B1800 },
+ { 2400, B2400 },
+ { 4800, B4800 },
+ { 9600, B9600 },
+ { 19200, B19200 },
+ { 38400, B38400 },
+ { 57600, B57600 },
+ { 115200, B115200 },
+#ifdef B230400
+ { 230400, B230400 },
+#endif
+#ifdef B460800
+ { 460800, B460800 }
+#endif
+};
+
+struct flag_name_map {
+ const char *name;
+ unsigned value;
+};
+
+static const struct flag_name_map parity_map[] = {
+ { "none", 0 },
+ { "even", PARENB },
+ { "odd", PARENB | PARODD },
+};
+static const struct flag_name_map data_size_map[] = {
+ { "5", CS5 },
+ { "6", CS6 },
+ { "7", CS7 },
+ { "8", CS8 },
+};
+static const struct flag_name_map stop_size_map[] = {
+ { "1", 0 },
+ { "2", CSTOPB },
+};
+static const struct flag_name_map input_map[] = {
+ { "raw", 0 },
+ { "cooked", ICANON },
+};
+static const struct flag_name_map output_map[] = {
+ { "raw", 0 },
+ { "cooked", OPOST },
+};
+
+static const char * const tty_settings_names[] = {
+ "baud",
+ "data",
+ "handshake",
+ "input",
+ "output",
+ "parity",
+ "stop",
+ "vmin",
+ "vtime",
+ "echo",
+ NULL
+};
+
+enum {
+ OPT_BAUD,
+ OPT_DATA,
+ OPT_HANDSHAKE,
+ OPT_INPUT,
+ OPT_OUTPUT,
+ OPT_PARITY,
+ OPT_STOP,
+ OPT_VMIN,
+ OPT_VTIME,
+ OPT_ECHO
+};
+
+
+#define ARRAYSIZE(A) (sizeof(A)/sizeof(*(A)))
+
+/**
+ * Search the flag/name map for an entry with the given name.
+ * (Actually, just matching the first char)
+ * Returns a pointer to the entry if found, or NULL if not.
+ */
+static const struct flag_name_map *flag_name_to_value(const struct flag_name_map *map, int len, const char *name)
+{
+ int i;
+
+ for (i = 0; i < len; i++) {
+ /* Only need to compare the first character since all names are unique in the first char */
+ if (*name == *map[i].name) {
+ return &map[i];
+ }
+ }
+ return NULL;
+}
+
+/**
+ * Search the flag/name map for an entry with the matching value.
+ * Returns the corresponding name if found, or NULL if no match.
+ */
+static const char *flag_value_to_name(const struct flag_name_map *map, int len, unsigned value)
+{
+ int i;
+
+ for (i = 0; i < len; i++) {
+ if (value == map[i].value) {
+ return map[i].name;
+ }
+ }
+ return NULL;
+}
+
+/**
+ * If 'str2' is not NULL, appends 'str1' and 'str2' to the list.
+ * Otherwise does nothing.
+ */
+static void JimListAddPair(Jim_Interp *interp, Jim_Obj *listObjPtr, const char *str1, const char *str2)
+{
+ if (str2) {
+ Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, str1, -1));
+ Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, str2, -1));
+ }
+}
+
+Jim_Obj *Jim_GetTtySettings(Jim_Interp *interp, int fd)
+{
+ struct termios tio;
+ size_t i;
+ const char *p;
+ Jim_Obj *listObjPtr;
+ speed_t speed;
+ int baud;
+
+ if (tcgetattr(fd, &tio) < 0) {
+ return NULL;
+ }
+
+ listObjPtr = Jim_NewListObj(interp, NULL, 0);
+
+ p = flag_value_to_name(parity_map, ARRAYSIZE(parity_map), tio.c_cflag & (PARENB | PARODD));
+ JimListAddPair(interp, listObjPtr, "parity", p);
+ p = flag_value_to_name(data_size_map, ARRAYSIZE(data_size_map), tio.c_cflag & CSIZE);
+ JimListAddPair(interp, listObjPtr, "data", p);
+ p = flag_value_to_name(stop_size_map, ARRAYSIZE(stop_size_map), tio.c_cflag & CSTOPB);
+ JimListAddPair(interp, listObjPtr, "stop", p);
+ if (tio.c_iflag & (IXON | IXOFF)) {
+ p = "xonxoff";
+ }
+ else if (tio.c_cflag & CRTSCTS) {
+ p = "rtscts";
+ }
+ else {
+ p = "none";
+ }
+ JimListAddPair(interp, listObjPtr, "handshake", p);
+ p = flag_value_to_name(input_map, ARRAYSIZE(input_map), tio.c_lflag & ICANON);
+ JimListAddPair(interp, listObjPtr, "input", p);
+ p = flag_value_to_name(output_map, ARRAYSIZE(output_map), tio.c_oflag & OPOST);
+ JimListAddPair(interp, listObjPtr, "output", p);
+
+ Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, "vmin", -1));
+ Jim_ListAppendElement(interp, listObjPtr, Jim_NewIntObj(interp, tio.c_cc[VMIN]));
+ Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, "vtime", -1));
+ Jim_ListAppendElement(interp, listObjPtr, Jim_NewIntObj(interp, tio.c_cc[VTIME]));
+
+ speed = cfgetispeed(&tio);
+ baud = 0;
+ for (i = 0; i < sizeof(baudtable) / sizeof(*baudtable); i++) {
+ if (baudtable[i].speed == speed) {
+ baud = baudtable[i].baud;
+ break;
+ }
+ }
+ Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, "baud", -1));
+ Jim_ListAppendElement(interp, listObjPtr, Jim_NewIntObj(interp, baud));
+
+ return listObjPtr;
+}
+
+int Jim_SetTtySettings(Jim_Interp *interp, int fd, Jim_Obj *dictObjPtr)
+{
+ int len = Jim_ListLength(interp, dictObjPtr);
+ int i;
+
+ struct termios tio;
+
+ if (tcgetattr(fd, &tio) < 0) {
+ return -1;
+ }
+
+ for (i = 0; i < len; i += 2) {
+ Jim_Obj *nameObj = Jim_ListGetIndex(interp, dictObjPtr, i);
+ Jim_Obj *valueObj = Jim_ListGetIndex(interp, dictObjPtr, i + 1);
+ int opt;
+ const struct flag_name_map *p;
+ long l;
+ size_t j;
+
+ if (Jim_GetEnum(interp, nameObj, tty_settings_names, &opt, "setting", JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) {
+ return JIM_ERR;
+ }
+
+ switch (opt) {
+ case OPT_BAUD:
+ if (Jim_GetLong(interp, valueObj, &l) != JIM_OK) {
+ goto badvalue;
+ }
+ for (j = 0; j < ARRAYSIZE(baudtable); j++) {
+ if (baudtable[j].baud == l) {
+ break;
+ }
+ }
+ if (j == ARRAYSIZE(baudtable)) {
+ goto badvalue;
+ }
+ cfsetospeed(&tio, baudtable[j].speed);
+ cfsetispeed(&tio, baudtable[j].speed);
+ break;
+
+ case OPT_PARITY:
+ p = flag_name_to_value(parity_map, ARRAYSIZE(parity_map), Jim_String(valueObj));
+ if (p == NULL) {
+badvalue:
+ Jim_SetResultFormatted(interp, "bad value for %#s: %#s", nameObj, valueObj);
+ return JIM_ERR;
+ }
+ tio.c_cflag &= ~(PARENB | PARODD);
+ tio.c_cflag |= p->value;
+ break;
+
+ case OPT_STOP:
+ p = flag_name_to_value(stop_size_map, ARRAYSIZE(stop_size_map), Jim_String(valueObj));
+ if (p == NULL) {
+ goto badvalue;
+ }
+ tio.c_cflag &= ~CSTOPB;
+ tio.c_cflag |= p->value;
+ break;
+
+ case OPT_DATA:
+ p = flag_name_to_value(data_size_map, ARRAYSIZE(data_size_map), Jim_String(valueObj));
+ if (p == NULL) {
+ goto badvalue;
+ }
+ tio.c_cflag &= ~CSIZE;
+ tio.c_cflag |= p->value;
+ break;
+
+ case OPT_HANDSHAKE:
+ tio.c_iflag &= ~(IXON | IXOFF);
+ tio.c_cflag &= ~(CRTSCTS);
+ if (Jim_CompareStringImmediate(interp, valueObj, "xonxoff")) {
+ tio.c_iflag |= (IXON | IXOFF);
+ }
+ else if (Jim_CompareStringImmediate(interp, valueObj, "rtscts")) {
+ tio.c_cflag |= CRTSCTS;
+ }
+ else if (!Jim_CompareStringImmediate(interp, valueObj, "none")) {
+ goto badvalue;
+ }
+ break;
+
+ case OPT_VMIN:
+ if (Jim_GetLong(interp, valueObj, &l) != JIM_OK) {
+ goto badvalue;
+ }
+ tio.c_cc[VMIN] = l;
+ break;
+
+ case OPT_VTIME:
+ if (Jim_GetLong(interp, valueObj, &l) != JIM_OK) {
+ goto badvalue;
+ }
+ tio.c_cc[VTIME] = l;
+ break;
+
+ case OPT_OUTPUT:
+ p = flag_name_to_value(output_map, ARRAYSIZE(output_map), Jim_String(valueObj));
+ if (p == NULL) {
+ goto badvalue;
+ }
+ tio.c_oflag &= ~OPOST;
+ tio.c_oflag |= p->value;
+ break;
+
+ case OPT_INPUT:
+ p = flag_name_to_value(input_map, ARRAYSIZE(input_map), Jim_String(valueObj));
+ if (p == NULL) {
+ goto badvalue;
+ }
+ if (p->value) {
+ tio.c_lflag |= (ECHO | ECHOE | ECHOK | ECHONL | ICANON | IEXTEN | ISIG | NOFLSH | TOSTOP);
+ tio.c_iflag |= ICRNL;
+ }
+ else {
+ tio.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL | ICANON | IEXTEN | ISIG | NOFLSH | TOSTOP);
+ tio.c_iflag &= ~ICRNL;
+ }
+ break;
+
+ case OPT_ECHO:
+ if (Jim_GetLong(interp, valueObj, &l) != JIM_OK) {
+ goto badvalue;
+ }
+ if (l) {
+ tio.c_lflag |= ECHO;
+ }
+ else {
+ tio.c_lflag &= ~ECHO;
+ }
+ break;
+
+ }
+ }
+
+ if (tcsetattr(fd, TCSAFLUSH, &tio) < 0) {
+ return -1;
+ }
+ return 0;
+}
diff --git a/jim-tty.h b/jim-tty.h
new file mode 100644
index 0000000..d052d73
--- /dev/null
+++ b/jim-tty.h
@@ -0,0 +1,30 @@
+#ifndef JIM_TTY_H
+#define JIM_TTY_H
+
+#include <jim.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Return the tty settings for the given file descriptor as a dictionary
+ * with a zero reference count.
+ *
+ * Returns NULL and sets errno file descriptor is not a valid tty.
+ */
+Jim_Obj *Jim_GetTtySettings(Jim_Interp *interp, int fd);
+
+/**
+ * Sets the tty settings given in 'dictObjPtr'
+ *
+ * Returns JIM_OK if OK, JIM_ERR if any settings are invalid,
+ * or -1 (and sets errno) if the file descriptor is not a valid tty.
+ */
+int Jim_SetTtySettings(Jim_Interp *interp, int fd, Jim_Obj *dictObjPtr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/jim-win32.c b/jim-win32.c
index 3218edc..33e7117 100644
--- a/jim-win32.c
+++ b/jim-win32.c
@@ -92,7 +92,7 @@ Win32ErrorObj(Jim_Interp *interp, const char * szPrefix, DWORD dwError)
static int
Win32_ShellExecute(Jim_Interp *interp, int objc, Jim_Obj * const *objv)
{
- int r;
+ ptrdiff_t r;
const char *verb, *file, *parm = NULL;
char cwd[MAX_PATH + 1];
@@ -105,7 +105,7 @@ Win32_ShellExecute(Jim_Interp *interp, int objc, Jim_Obj * const *objv)
GetCurrentDirectoryA(MAX_PATH + 1, cwd);
if (objc == 4)
parm = Jim_String(objv[3]);
- r = (int)ShellExecuteA(NULL, verb, file, parm, cwd, SW_SHOWNORMAL);
+ r = (ptrdiff_t)ShellExecuteA(NULL, verb, file, parm, cwd, SW_SHOWNORMAL);
if (r < 33)
Jim_SetResult(interp,
Win32ErrorObj(interp, "ShellExecute", GetLastError()));
@@ -163,7 +163,7 @@ Win32_CloseWindow(Jim_Interp *interp, int objc, Jim_Obj * const *objv)
static int
Win32_GetActiveWindow(Jim_Interp *interp, int objc, Jim_Obj * const *objv)
{
- Jim_SetResult(interp, Jim_NewIntObj(interp, (DWORD)GetActiveWindow()));
+ Jim_SetResult(interp, Jim_NewIntObj(interp, (ptrdiff_t)GetActiveWindow()));
return JIM_OK;
}
diff --git a/jim-win32compat.h b/jim-win32compat.h
index edd29c3..16133b5 100644
--- a/jim-win32compat.h
+++ b/jim-win32compat.h
@@ -41,7 +41,6 @@ char *dlerror(void);
#define JIM_WIDE_MODIFIER "I64d"
#define strcasecmp _stricmp
#define strtoull _strtoui64
-#define snprintf _snprintf
#include <io.h>
@@ -68,11 +67,6 @@ DIR *opendir(const char *name);
int closedir(DIR *dir);
struct dirent *readdir(DIR *dir);
-#elif defined(__MINGW32__)
-
-#include <stdlib.h>
-#define strtod __strtod
-
#endif
#endif /* WIN32 */
diff --git a/jim-zlib.c b/jim-zlib.c
index 4bf88a4..bb91913 100644
--- a/jim-zlib.c
+++ b/jim-zlib.c
@@ -44,8 +44,7 @@
static int JimZlibCheckBufSize(Jim_Interp *interp, jim_wide bufsiz)
{
if ((bufsiz <= 0) || (bufsiz > INT_MAX)) {
- Jim_SetResultString(interp, "buffer size must be 0 to ", -1);
- Jim_AppendObj(interp, Jim_GetResult(interp), Jim_NewIntObj(interp, INT_MAX));
+ Jim_SetResultFormatted(interp, "buffer size must be 0 to %#s", Jim_NewIntObj(interp, INT_MAX));
return JIM_ERR;
}
return JIM_OK;
@@ -86,6 +85,10 @@ static int Jim_Compress(Jim_Interp *interp, const char *in, int len, long level,
}
strm.avail_out = deflateBound(&strm, (uLong)len);
+
+ /* Some compression methods may need a little more space */
+ strm.avail_out += 100;
+
if (strm.avail_out > INT_MAX) {
deflateEnd(&strm);
return JIM_ERR;
@@ -99,15 +102,17 @@ static int Jim_Compress(Jim_Interp *interp, const char *in, int len, long level,
* decompressed data anyway, so there's no reason to do chunked
* decompression */
if (deflate(&strm, Z_FINISH) != Z_STREAM_END) {
- Jim_Free(strm.next_out);
+ Jim_Free(buf);
deflateEnd(&strm);
+ Jim_SetResultString(interp, "not enough output space", -1);
return JIM_ERR;
}
deflateEnd(&strm);
if (strm.total_out > INT_MAX) {
- Jim_Free(strm.next_out);
+ Jim_Free(buf);
+ Jim_SetResultString(interp, "too much output", -1);
return JIM_ERR;
}
diff --git a/jim.c b/jim.c
index bb32f09..499fa69 100644
--- a/jim.c
+++ b/jim.c
@@ -41,7 +41,9 @@
* official policies, either expressed or implied, of the Jim Tcl Project.
**/
#define JIM_OPTIMIZATION /* comment to avoid optimizations and reduce size */
+#ifndef _GNU_SOURCE
#define _GNU_SOURCE /* Mostly just for environ */
+#endif
#include <stdio.h>
#include <stdlib.h>
@@ -222,7 +224,7 @@ first:
pattern += utf8_tounicode_case(pattern, &start, nocase);
if (pattern[0] == '-' && pattern[1]) {
/* skip '-' */
- pattern += utf8_tounicode(pattern, &pchar);
+ pattern++;
pattern += utf8_tounicode_case(pattern, &end, nocase);
/* Handle reversed range too */
@@ -366,9 +368,12 @@ static int JimStringCompareLen(const char *s1, const char *s2, int maxchars, int
return 0;
}
-/* Search 's1' inside 's2', starting to search from char 'index' of 's2'.
+/* Search for 's1' inside 's2', starting to search from char 'index' of 's2'.
* The index of the first occurrence of s1 in s2 is returned.
- * If s1 is not found inside s2, -1 is returned. */
+ * If s1 is not found inside s2, -1 is returned.
+ *
+ * Note: Lengths and return value are in bytes, not chars.
+ */
static int JimStringFirst(const char *s1, int l1, const char *s2, int l2, int idx)
{
int i;
@@ -393,7 +398,10 @@ static int JimStringFirst(const char *s1, int l1, const char *s2, int l2, int id
return -1;
}
-/**
+/* Search for the last occurrence 's1' inside 's2', starting to search from char 'index' of 's2'.
+ * The index of the last occurrence of s1 in s2 is returned.
+ * If s1 is not found inside s2, -1 is returned.
+ *
* Note: Lengths and return value are in bytes, not chars.
*/
static int JimStringLast(const char *s1, int l1, const char *s2, int l2)
@@ -414,7 +422,7 @@ static int JimStringLast(const char *s1, int l1, const char *s2, int l2)
#ifdef JIM_UTF8
/**
- * Note: Lengths and return value are in chars.
+ * Per JimStringLast but lengths and return value are in chars, not bytes.
*/
static int JimStringLastUtf8(const char *s1, int l1, const char *s2, int l2)
{
@@ -450,7 +458,7 @@ static int JimCheckConversion(const char *str, const char *endptr)
return JIM_OK;
}
-/* Parses the front of a number to determine it's sign and base
+/* Parses the front of a number to determine its sign and base.
* Returns the index to start parsing according to the given base
*/
static int JimNumberBase(const char *str, int *base, int *sign)
@@ -719,7 +727,13 @@ unsigned int Jim_GenHashFunction(const unsigned char *buf, int len)
/* ----------------------------- API implementation ------------------------- */
-/* reset a hashtable already initialized */
+/*
+ * Reset a hashtable already initialized.
+ * The table data should already have been freed.
+ *
+ * Note that type and privdata are not initialised
+ * to allow the now-empty hashtable to be reused
+ */
static void JimResetHashTable(Jim_HashTable *ht)
{
ht->table = NULL;
@@ -754,17 +768,6 @@ int Jim_InitHashTable(Jim_HashTable *ht, const Jim_HashTableType *type, void *pr
return JIM_OK;
}
-/* Resize the table to the minimal size that contains all the elements,
- * but with the invariant of a USER/BUCKETS ration near to <= 1 */
-void Jim_ResizeHashTable(Jim_HashTable *ht)
-{
- int minimal = ht->used;
-
- if (minimal < JIM_HT_INITIAL_SIZE)
- minimal = JIM_HT_INITIAL_SIZE;
- Jim_ExpandHashTable(ht, minimal);
-}
-
/* Expand or create the hashtable */
void Jim_ExpandHashTable(Jim_HashTable *ht, unsigned int size)
{
@@ -902,7 +905,9 @@ int Jim_DeleteHashEntry(Jim_HashTable *ht, const void *key)
return JIM_ERR; /* not found */
}
-/* Destroy an entire hash table and leave it ready for reuse */
+/* Remove all entries from the hash table
+ * and leave it empty for reuse
+ */
int Jim_FreeHashTable(Jim_HashTable *ht)
{
unsigned int i;
@@ -981,7 +986,7 @@ Jim_HashEntry *Jim_NextHashEntry(Jim_HashTableIterator *iter)
static void JimExpandHashTableIfNeeded(Jim_HashTable *ht)
{
/* If the hash table is empty expand it to the intial size,
- * if the table is "full" dobule its size. */
+ * if the table is "full" double its size. */
if (ht->size == 0)
Jim_ExpandHashTable(ht, JIM_HT_INITIAL_SIZE);
if (ht->size == ht->used)
@@ -1186,12 +1191,12 @@ void Jim_FreeStackElements(Jim_Stack *stack, void (*freeFunc) (void *ptr))
* Results of missing quotes, braces, etc. from parsing.
*/
struct JimParseMissing {
- int ch; /* At end of parse, ' ' if complete or '{', '[', '"', '\\' , '{' if incomplete */
+ int ch; /* At end of parse, ' ' if complete or '{', '[', '"', '\\', '}' if incomplete */
int line; /* Line number starting the missing token */
};
-/* Parser context structure. The same context is used both to parse
- * Tcl scripts and lists. */
+/* Parser context structure. The same context is used to parse
+ * Tcl scripts, expressions and lists. */
struct JimParserCtx
{
const char *p; /* Pointer to the point of the program we are parsing */
@@ -1337,17 +1342,17 @@ static int JimParseEol(struct JimParserCtx *pc)
** Here are the rules for parsing:
** {braced expression}
** - Count open and closing braces
-** - Backslash escapes meaning of braces
+** - Backslash escapes meaning of braces but doesn't remove the backslash
**
** "quoted expression"
-** - First double quote at start of word terminates the expression
-** - Backslash escapes quote and bracket
+** - Unescaped double quote terminates the expression
+** - Backslash escapes next char
** - [commands brackets] are counted/nested
-** - command rules apply within [brackets], not quoting rules (i.e. quotes have their own rules)
+** - command rules apply within [brackets], not quoting rules (i.e. brackets have their own rules)
**
** [command expression]
** - Count open and closing brackets
-** - Backslash escapes quote, bracket and brace
+** - Backslash escapes next char
** - [commands brackets] are counted/nested
** - "quoted expressions" are parsed according to quoting rules
** - {braced expressions} are parsed according to brace rules
@@ -1810,8 +1815,8 @@ static int odigitval(int c)
/* Perform Tcl escape substitution of 's', storing the result
* string into 'dest'. The escaped string is guaranteed to
- * be the same length or shorted than the source string.
- * Slen is the length of the string at 's'.
+ * be the same length or shorter than the source string.
+ * slen is the length of the string at 's'.
*
* The function returns the length of the resulting string. */
static int JimEscape(char *dest, const char *s, int slen)
@@ -2002,23 +2007,19 @@ static Jim_Obj *JimParserGetTokenObj(Jim_Interp *interp, struct JimParserCtx *pc
start = pc->tstart;
end = pc->tend;
- if (start > end) {
+ len = (end - start) + 1;
+ if (len < 0) {
len = 0;
- token = Jim_Alloc(1);
- token[0] = '\0';
+ }
+ token = Jim_Alloc(len + 1);
+ if (pc->tt != JIM_TT_ESC) {
+ /* No escape conversion needed? Just copy it. */
+ memcpy(token, start, len);
+ token[len] = '\0';
}
else {
- len = (end - start) + 1;
- token = Jim_Alloc(len + 1);
- if (pc->tt != JIM_TT_ESC) {
- /* No escape conversion needed? Just copy it. */
- memcpy(token, start, len);
- token[len] = '\0';
- }
- else {
- /* Else convert the escape chars. */
- len = JimEscape(token, start, len);
- }
+ /* Else convert the escape chars. */
+ len = JimEscape(token, start, len);
}
return Jim_NewStringObjNoAlloc(interp, token, len);
@@ -2158,10 +2159,10 @@ Jim_Obj *Jim_NewObj(Jim_Interp *interp)
}
/* Object is returned with refCount of 0. Every
- * kind of GC implemented should take care to don't try
- * to scan objects with refCount == 0. */
+ * kind of GC implemented should take care to avoid
+ * scanning objects with refCount == 0. */
objPtr->refCount = 0;
- /* All the other fields are left not initialized to save time.
+ /* All the other fields are left uninitialized to save time.
* The caller will probably want to set them to the right
* value anyway. */
@@ -2232,7 +2233,9 @@ Jim_Obj *Jim_DuplicateObj(Jim_Interp *interp, Jim_Obj *objPtr)
dupPtr->bytes = NULL;
}
else if (objPtr->length == 0) {
- /* Zero length, so don't even bother with the type-specific dup, since all zero length objects look the same */
+ /* Zero length, so don't even bother with the type-specific dup,
+ * since all zero length objects look the same
+ */
dupPtr->bytes = JimEmptyStringRep;
dupPtr->length = 0;
dupPtr->typePtr = NULL;
@@ -2275,13 +2278,12 @@ const char *Jim_GetString(Jim_Obj *objPtr, int *lenPtr)
return objPtr->bytes;
}
-/* Just returns the length of the object's string rep */
+/* Just returns the length (in bytes) of the object's string rep */
int Jim_Length(Jim_Obj *objPtr)
{
if (objPtr->bytes == NULL) {
/* Invalid string repr. Generate it. */
- JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name));
- objPtr->typePtr->updateStringProc(objPtr);
+ Jim_GetString(objPtr, NULL);
}
return objPtr->length;
}
@@ -2291,9 +2293,7 @@ const char *Jim_String(Jim_Obj *objPtr)
{
if (objPtr->bytes == NULL) {
/* Invalid string repr. Generate it. */
- JimPanic((objPtr->typePtr == NULL, "UpdateStringProc called against typeless value."));
- JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name));
- objPtr->typePtr->updateStringProc(objPtr);
+ Jim_GetString(objPtr, NULL);
}
return objPtr->bytes;
}
@@ -2315,19 +2315,30 @@ static const Jim_ObjType dictSubstObjType = {
JIM_TYPE_NONE,
};
-static void FreeInterpolatedInternalRep(Jim_Interp *interp, Jim_Obj *objPtr)
-{
- Jim_DecrRefCount(interp, objPtr->internalRep.dictSubstValue.indexObjPtr);
-}
+static void FreeInterpolatedInternalRep(Jim_Interp *interp, Jim_Obj *objPtr);
+static void DupInterpolatedInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr);
static const Jim_ObjType interpolatedObjType = {
"interpolated",
FreeInterpolatedInternalRep,
- NULL,
+ DupInterpolatedInternalRep,
NULL,
JIM_TYPE_NONE,
};
+static void FreeInterpolatedInternalRep(Jim_Interp *interp, Jim_Obj *objPtr)
+{
+ Jim_DecrRefCount(interp, objPtr->internalRep.dictSubstValue.indexObjPtr);
+}
+
+static void DupInterpolatedInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr)
+{
+ /* Copy the interal rep */
+ dupPtr->internalRep = srcPtr->internalRep;
+ /* Need to increment the key ref count */
+ Jim_IncrRefCount(dupPtr->internalRep.dictSubstValue.indexObjPtr);
+}
+
/* -----------------------------------------------------------------------------
* String Object
* ---------------------------------------------------------------------------*/
@@ -2407,9 +2418,7 @@ Jim_Obj *Jim_NewStringObj(Jim_Interp *interp, const char *s, int len)
objPtr->bytes = JimEmptyStringRep;
}
else {
- objPtr->bytes = Jim_Alloc(len + 1);
- memcpy(objPtr->bytes, s, len);
- objPtr->bytes[len] = '\0';
+ objPtr->bytes = Jim_StrDupLen(s, len);
}
objPtr->length = len;
@@ -2732,8 +2741,6 @@ static Jim_Obj *JimStringToLower(Jim_Interp *interp, Jim_Obj *strObjPtr)
int len;
const char *str;
- SetStringFromAny(interp, strObjPtr);
-
str = Jim_GetString(strObjPtr, &len);
#ifdef JIM_UTF8
@@ -2756,10 +2763,6 @@ static Jim_Obj *JimStringToUpper(Jim_Interp *interp, Jim_Obj *strObjPtr)
const char *str;
int len;
- if (strObjPtr->typePtr != &stringObjType) {
- SetStringFromAny(interp, strObjPtr);
- }
-
str = Jim_GetString(strObjPtr, &len);
#ifdef JIM_UTF8
@@ -2784,9 +2787,7 @@ static Jim_Obj *JimStringToTitle(Jim_Interp *interp, Jim_Obj *strObjPtr)
const char *str;
str = Jim_GetString(strObjPtr, &len);
- if (len == 0) {
- return strObjPtr;
- }
+
#ifdef JIM_UTF8
/* Case mapping can change the utf-8 length of the string.
* But at worst it will be by one extra byte per char
@@ -3032,7 +3033,7 @@ static int JimStringIs(Jim_Interp *interp, Jim_Obj *strObjPtr, Jim_Obj *strClass
}
for (i = 0; i < len; i++) {
- if (!isclassfunc(str[i])) {
+ if (!isclassfunc(UCHAR(str[i]))) {
Jim_SetResultBool(interp, 0);
return JIM_OK;
}
@@ -3075,9 +3076,7 @@ int Jim_CompareStringImmediate(Jim_Interp *interp, Jim_Obj *objPtr, const char *
return 1;
}
else {
- const char *objStr = Jim_String(objPtr);
-
- if (strcmp(str, objStr) != 0)
+ if (strcmp(str, Jim_String(objPtr)) != 0)
return 0;
if (objPtr->typePtr != &comparedStringObjType) {
@@ -3399,7 +3398,7 @@ static void ScriptAddToken(ParseTokenList *tokenlist, const char *token, int len
* operator (in which case the count doesn't include
* that token).
*/
-static int JimCountWordTokens(ParseToken *t)
+static int JimCountWordTokens(struct ScriptObj *script, ParseToken *t)
{
int expand = 1;
int count = 0;
@@ -3411,6 +3410,13 @@ static int JimCountWordTokens(ParseToken *t)
expand = -1;
t++;
}
+ else {
+ if (script->missing == ' ') {
+ /* This is a "extra characters after close-brace" error. Report the first error */
+ script->missing = '}';
+ script->linenr = t[1].line;
+ }
+ }
}
/* Now count non-separator words */
@@ -3497,7 +3503,7 @@ static void ScriptObjAddTokens(Jim_Interp *interp, struct ScriptObj *script,
i++;
}
- wordtokens = JimCountWordTokens(tokenlist->list + i);
+ wordtokens = JimCountWordTokens(script, tokenlist->list + i);
if (wordtokens == 0) {
/* None, so at end of line */
@@ -3578,6 +3584,10 @@ static void ScriptObjAddTokens(Jim_Interp *interp, struct ScriptObj *script,
* '\\' on scripts with a trailing backslash.
*
* If the script is complete, 1 is returned, otherwise 0.
+ *
+ * If the script has extra characters after a close brace, this still returns 1,
+ * but sets *stateCharPtr to '}'
+ * Evaluating the script will give the error "extra characters after close-brace".
*/
int Jim_ScriptIsComplete(Jim_Interp *interp, Jim_Obj *scriptObj, char *stateCharPtr)
{
@@ -3585,7 +3595,7 @@ int Jim_ScriptIsComplete(Jim_Interp *interp, Jim_Obj *scriptObj, char *stateChar
if (stateCharPtr) {
*stateCharPtr = script->missing;
}
- return (script->missing == ' ');
+ return script->missing == ' ' || script->missing == '}';
}
/**
@@ -3610,6 +3620,9 @@ static int JimParseCheckMissing(Jim_Interp *interp, int ch)
case '{':
msg = "missing close-brace";
break;
+ case '}':
+ msg = "extra characters after close-brace";
+ break;
case '"':
default:
msg = "missing quote";
@@ -3777,10 +3790,6 @@ static void JimDecrCmdRefCount(Jim_Interp *interp, Jim_Cmd *cmdPtr)
*
* Keys are dynamically allocated strings, Values are Jim_Var structures.
*/
-
-/* Variables HashTable Type.
- *
- * Keys are dynamic allocated strings, Values are Jim_Var structures. */
static void JimVariablesHTValDestructor(void *interp, void *val)
{
Jim_DecrRefCount(interp, ((Jim_Var *)val)->objPtr);
@@ -3839,6 +3848,11 @@ static Jim_Obj *JimQualifyNameObj(Jim_Interp *interp, Jim_Obj *nsObj)
return nsObj;
}
+/**
+ * If nameObjPtr starts with "::", returns it.
+ * Otherwise returns a new object with nameObjPtr prefixed with "::".
+ * In this case, decrements the ref count of nameObjPtr.
+ */
Jim_Obj *Jim_MakeGlobalNamespaceName(Jim_Interp *interp, Jim_Obj *nameObjPtr)
{
Jim_Obj *resultObj;
@@ -4010,6 +4024,10 @@ static int JimCreateProcedureStatics(Jim_Interp *interp, Jim_Cmd *cmdPtr, Jim_Ob
return JIM_OK;
}
+/**
+ * If the command is a proc, sets/updates the cached namespace (nsObj)
+ * based on the command name.
+ */
static void JimUpdateProcNamespace(Jim_Interp *interp, Jim_Cmd *cmdPtr, const char *cmdname)
{
#ifdef jim_ext_namespace
@@ -4022,7 +4040,7 @@ static void JimUpdateProcNamespace(Jim_Interp *interp, Jim_Cmd *cmdPtr, const ch
Jim_IncrRefCount(cmdPtr->u.proc.nsObj);
if (Jim_FindHashEntry(&interp->commands, pt + 1)) {
- /* This commands shadows a global command, so a proc epoch update is required */
+ /* This command shadows a global command, so a proc epoch update is required */
Jim_InterpIncrProcEpoch(interp);
}
}
@@ -4207,12 +4225,12 @@ static const Jim_ObjType commandObjType = {
};
/* This function returns the command structure for the command name
- * stored in objPtr. It tries to specialize the objPtr to contain
- * a cached info instead to perform the lookup into the hash table
- * every time. The information cached may not be uptodate, in such
- * a case the lookup is performed and the cache updated.
+ * stored in objPtr. It specializes the objPtr to contain
+ * cached info instead of performing the lookup into the hash table
+ * every time. The information cached may not be up-to-date, in this
+ * case the lookup is performed and the cache updated.
*
- * Respects the 'upcall' setting
+ * Respects the 'upcall' setting.
*/
Jim_Cmd *Jim_GetCommand(Jim_Interp *interp, Jim_Obj *objPtr, int flags)
{
@@ -4263,7 +4281,7 @@ found:
#endif
cmd = Jim_GetHashEntryVal(he);
- /* Free the old internal repr and set the new one. */
+ /* Free the old internal rep and set the new one. */
Jim_FreeIntRep(interp, objPtr);
objPtr->typePtr = &commandObjType;
objPtr->internalRep.cmdValue.procEpoch = interp->procEpoch;
@@ -4437,6 +4455,9 @@ static Jim_Var *JimCreateVariable(Jim_Interp *interp, Jim_Obj *nameObjPtr, Jim_O
* All the caching should also have an 'epoch' mechanism similar
* to the one used by Tcl for procedures lookup caching. */
+/**
+ * Set the variable nameObjPtr to value valObjptr.
+ */
int Jim_SetVariable(Jim_Interp *interp, Jim_Obj *nameObjPtr, Jim_Obj *valObjPtr)
{
int err;
@@ -4500,15 +4521,12 @@ int Jim_SetGlobalVariableStr(Jim_Interp *interp, const char *name, Jim_Obj *objP
int Jim_SetVariableStrWithStr(Jim_Interp *interp, const char *name, const char *val)
{
- Jim_Obj *nameObjPtr, *valObjPtr;
+ Jim_Obj *valObjPtr;
int result;
- nameObjPtr = Jim_NewStringObj(interp, name, -1);
valObjPtr = Jim_NewStringObj(interp, val, -1);
- Jim_IncrRefCount(nameObjPtr);
Jim_IncrRefCount(valObjPtr);
- result = Jim_SetVariable(interp, nameObjPtr, valObjPtr);
- Jim_DecrRefCount(interp, nameObjPtr);
+ result = Jim_SetVariableStr(interp, name, valObjPtr);
Jim_DecrRefCount(interp, valObjPtr);
return result;
}
@@ -4684,8 +4702,9 @@ Jim_Obj *Jim_GetGlobalVariableStr(Jim_Interp *interp, const char *name, int flag
}
/* Unset a variable.
- * Note: On success unset invalidates all the variable objects created
- * in the current call frame incrementing. */
+ * Note: On success unset invalidates all the (cached) variable objects
+ * by incrementing callFrameEpoch
+ */
int Jim_UnsetVariable(Jim_Interp *interp, Jim_Obj *nameObjPtr, int flags)
{
Jim_Var *varPtr;
@@ -4849,14 +4868,13 @@ void FreeDictSubstInternalRep(Jim_Interp *interp, Jim_Obj *objPtr)
Jim_DecrRefCount(interp, objPtr->internalRep.dictSubstValue.indexObjPtr);
}
-void DupDictSubstInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr)
+static void DupDictSubstInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr)
{
- JIM_NOTUSED(interp);
-
- dupPtr->internalRep.dictSubstValue.varNameObjPtr =
- srcPtr->internalRep.dictSubstValue.varNameObjPtr;
- dupPtr->internalRep.dictSubstValue.indexObjPtr = srcPtr->internalRep.dictSubstValue.indexObjPtr;
- dupPtr->typePtr = &dictSubstObjType;
+ /* Copy the internal rep */
+ dupPtr->internalRep = srcPtr->internalRep;
+ /* Need to increment the ref counts */
+ Jim_IncrRefCount(dupPtr->internalRep.dictSubstValue.varNameObjPtr);
+ Jim_IncrRefCount(dupPtr->internalRep.dictSubstValue.indexObjPtr);
}
/* Note: The object *must* be in dict-sugar format */
@@ -4912,18 +4930,6 @@ static Jim_Obj *JimExpandDictSugar(Jim_Interp *interp, Jim_Obj *objPtr)
return resObjPtr;
}
-static Jim_Obj *JimExpandExprSugar(Jim_Interp *interp, Jim_Obj *objPtr)
-{
- Jim_Obj *resultObjPtr;
-
- if (Jim_EvalExpression(interp, objPtr, &resultObjPtr) == JIM_OK) {
- /* Note that the result has a ref count of 1, but we need a ref count of 0 */
- resultObjPtr->refCount--;
- return resultObjPtr;
- }
- return NULL;
-}
-
/* -----------------------------------------------------------------------------
* CallFrame
* ---------------------------------------------------------------------------*/
@@ -4991,8 +4997,8 @@ static int JimDeleteLocalProcs(Jim_Interp *interp, Jim_Stack *localCommands)
}
else {
Jim_DeleteHashEntry(ht, fqname);
- Jim_InterpIncrProcEpoch(interp);
}
+ Jim_InterpIncrProcEpoch(interp);
}
Jim_DecrRefCount(interp, cmdNameObj);
JimFreeQualifiedName(interp, fqObjName);
@@ -5003,6 +5009,62 @@ static int JimDeleteLocalProcs(Jim_Interp *interp, Jim_Stack *localCommands)
return JIM_OK;
}
+/**
+ * Run any $jim::defer scripts for the current call frame.
+ *
+ * retcode is the return code from the current proc.
+ *
+ * Returns the new return code.
+ */
+static int JimInvokeDefer(Jim_Interp *interp, int retcode)
+{
+ Jim_Obj *objPtr;
+
+ /* Fast check for the likely case that the variable doesn't exist */
+ if (Jim_FindHashEntry(&interp->framePtr->vars, "jim::defer") == NULL) {
+ return retcode;
+ }
+
+ objPtr = Jim_GetVariableStr(interp, "jim::defer", JIM_NONE);
+
+ if (objPtr) {
+ int ret = JIM_OK;
+ int i;
+ int listLen = Jim_ListLength(interp, objPtr);
+ Jim_Obj *resultObjPtr;
+
+ Jim_IncrRefCount(objPtr);
+
+ /* Need to save away the current interp result and
+ * restore it if appropriate
+ */
+ resultObjPtr = Jim_GetResult(interp);
+ Jim_IncrRefCount(resultObjPtr);
+ Jim_SetEmptyResult(interp);
+
+ /* Invoke in reverse order */
+ for (i = listLen; i > 0; i--) {
+ /* If a defer script returns an error, don't evaluate remaining scripts */
+ Jim_Obj *scriptObjPtr = Jim_ListGetIndex(interp, objPtr, i - 1);
+ ret = Jim_EvalObj(interp, scriptObjPtr);
+ if (ret != JIM_OK) {
+ break;
+ }
+ }
+
+ if (ret == JIM_OK || retcode == JIM_ERR) {
+ /* defer script had no error, or proc had an error so restore proc result */
+ Jim_SetResult(interp, resultObjPtr);
+ }
+ else {
+ retcode = ret;
+ }
+
+ Jim_DecrRefCount(interp, resultObjPtr);
+ Jim_DecrRefCount(interp, objPtr);
+ }
+ return retcode;
+}
#define JIM_FCF_FULL 0 /* Always free the vars hash table */
#define JIM_FCF_REUSE 1 /* Reuse the vars hash table if possible */
@@ -5308,11 +5370,11 @@ int Jim_Collect(Jim_Interp *interp)
Jim_Obj *objPtr;
/* Avoid recursive calls */
- if (interp->lastCollectId == -1) {
+ if (interp->lastCollectId == (unsigned long)~0) {
/* Jim_Collect() already running. Return just now. */
return 0;
}
- interp->lastCollectId = -1;
+ interp->lastCollectId = ~0;
/* Mark all the references found into the 'mark' hash table.
* The references are searched in every live object that
@@ -5523,6 +5585,8 @@ void Jim_FreeInterp(Jim_Interp *i)
/* Free the active call frames list - must be done before i->commands is destroyed */
for (cf = i->framePtr; cf; cf = cfx) {
+ /* Note that we ignore any errors */
+ JimInvokeDefer(i, JIM_OK);
cfx = cf->parent;
JimFreeCallFrame(i, cf, JIM_FCF_FULL);
}
@@ -5555,6 +5619,7 @@ void Jim_FreeInterp(Jim_Interp *i)
printf("Objects still in the free list:\n");
while (objPtr) {
const char *type = objPtr->typePtr ? objPtr->typePtr->name : "string";
+ Jim_String(objPtr);
if (objPtr->bytes && strlen(objPtr->bytes) > 20) {
printf("%p (%d) %-10s: '%.20s...'\n",
@@ -6011,11 +6076,6 @@ static int SetDoubleFromAny(Jim_Interp *interp, Jim_Obj *objPtr)
jim_wide wideValue;
const char *str;
- /* Preserve the string representation.
- * Needed so we can convert back to int without loss
- */
- str = Jim_String(objPtr);
-
#ifdef HAVE_LONG_LONG
/* Assume a 53 bit mantissa */
#define MIN_INT_IN_DOUBLE -(1LL << 53)
@@ -6029,8 +6089,12 @@ static int SetDoubleFromAny(Jim_Interp *interp, Jim_Obj *objPtr)
objPtr->typePtr = &coercedDoubleObjType;
return JIM_OK;
}
- else
#endif
+ /* Preserve the string representation.
+ * Needed so we can convert back to int without loss
+ */
+ str = Jim_String(objPtr);
+
if (Jim_StringToWide(str, &wideValue, 10) == JIM_OK) {
/* Managed to convert to an int, so we can use this as a cooerced double */
Jim_FreeIntRep(interp, objPtr);
@@ -6657,8 +6721,12 @@ static void ListRemoveDuplicates(Jim_Obj *listObjPtr, int (*comp)(Jim_Obj **lhs,
}
ele[dst] = ele[src];
}
- /* At end of list, keep the final element */
- ele[++dst] = ele[src];
+
+ /* At end of list, keep the final element unless all elements were kept */
+ dst++;
+ if (dst < listObjPtr->internalRep.listValue.len) {
+ ele[dst] = ele[src];
+ }
/* Set the new length */
listObjPtr->internalRep.listValue.len = dst;
@@ -7247,8 +7315,10 @@ int Jim_DictKey(Jim_Interp *interp, Jim_Obj *dictPtr, Jim_Obj *keyPtr,
}
return JIM_ERR;
}
- *objPtrPtr = he->u.val;
- return JIM_OK;
+ else {
+ *objPtrPtr = Jim_GetHashEntryVal(he);
+ return JIM_OK;
+ }
}
/* Return an allocated array of key/value pairs for the dictionary. Stores the length in *len */
@@ -7509,7 +7579,7 @@ static const char * const jimReturnCodes[] = {
NULL
};
-#define jimReturnCodesSize (sizeof(jimReturnCodes)/sizeof(*jimReturnCodes))
+#define jimReturnCodesSize (sizeof(jimReturnCodes)/sizeof(*jimReturnCodes) - 1)
static const Jim_ObjType returnCodeObjType = {
"return-code",
@@ -7567,13 +7637,12 @@ static int JimParseExprNumber(struct JimParserCtx *pc);
static int JimParseExprIrrational(struct JimParserCtx *pc);
static int JimParseExprBoolean(struct JimParserCtx *pc);
-/* Exrp's Stack machine operators opcodes. */
-
-/* Binary operators (numbers) */
+/* expr operator opcodes. */
enum
{
/* Continues on from the JIM_TT_ space */
- /* Operations */
+
+ /* Binary operators (numbers) */
JIM_EXPROP_MUL = JIM_TT_EXPR_OP, /* 20 */
JIM_EXPROP_DIV,
JIM_EXPROP_MOD,
@@ -7592,45 +7661,26 @@ enum
JIM_EXPROP_BITAND, /* 35 */
JIM_EXPROP_BITXOR,
JIM_EXPROP_BITOR,
-
- /* Note must keep these together */
JIM_EXPROP_LOGICAND, /* 38 */
- JIM_EXPROP_LOGICAND_LEFT,
- JIM_EXPROP_LOGICAND_RIGHT,
-
- /* and these */
- JIM_EXPROP_LOGICOR, /* 41 */
- JIM_EXPROP_LOGICOR_LEFT,
- JIM_EXPROP_LOGICOR_RIGHT,
-
- /* and these */
- /* Ternary operators */
- JIM_EXPROP_TERNARY, /* 44 */
- JIM_EXPROP_TERNARY_LEFT,
- JIM_EXPROP_TERNARY_RIGHT,
+ JIM_EXPROP_LOGICOR, /* 39 */
+ JIM_EXPROP_TERNARY, /* 40 */
+ JIM_EXPROP_COLON, /* 41 */
+ JIM_EXPROP_POW, /* 42 */
- /* and these */
- JIM_EXPROP_COLON, /* 47 */
- JIM_EXPROP_COLON_LEFT,
- JIM_EXPROP_COLON_RIGHT,
-
- JIM_EXPROP_POW, /* 50 */
-
-/* Binary operators (strings) */
- JIM_EXPROP_STREQ, /* 51 */
+ /* Binary operators (strings) */
+ JIM_EXPROP_STREQ, /* 43 */
JIM_EXPROP_STRNE,
JIM_EXPROP_STRIN,
JIM_EXPROP_STRNI,
-/* Unary operators (numbers) */
- JIM_EXPROP_NOT, /* 55 */
+ /* Unary operators (numbers) */
+ JIM_EXPROP_NOT, /* 47 */
JIM_EXPROP_BITNOT,
JIM_EXPROP_UNARYMINUS,
JIM_EXPROP_UNARYPLUS,
/* Functions */
- JIM_EXPROP_FUNC_FIRST, /* 59 */
- JIM_EXPROP_FUNC_INT = JIM_EXPROP_FUNC_FIRST,
+ JIM_EXPROP_FUNC_INT, /* 51 */
JIM_EXPROP_FUNC_WIDE,
JIM_EXPROP_FUNC_ABS,
JIM_EXPROP_FUNC_DOUBLE,
@@ -7660,46 +7710,47 @@ enum
JIM_EXPROP_FUNC_FMOD,
};
-struct JimExprState
-{
- Jim_Obj **stack;
- int stacklen;
- int opcode;
- int skip;
+/* A expression node is either a term or an operator
+ * If a node is an operator, 'op' points to the details of the operator and it's terms.
+ */
+struct JimExprNode {
+ int type; /* JIM_TT_xxx */
+ struct Jim_Obj *objPtr; /* The object for a term, or NULL for an operator */
+
+ struct JimExprNode *left; /* For all operators */
+ struct JimExprNode *right; /* For binary operators */
+ struct JimExprNode *ternary; /* For ternary operator only */
};
/* Operators table */
typedef struct Jim_ExprOperator
{
const char *name;
- int (*funcop) (Jim_Interp *interp, struct JimExprState * e);
+ int (*funcop) (Jim_Interp *interp, struct JimExprNode *opnode);
unsigned char precedence;
unsigned char arity;
- unsigned char lazy;
+ unsigned char attr;
unsigned char namelen;
} Jim_ExprOperator;
-static void ExprPush(struct JimExprState *e, Jim_Obj *obj)
-{
- Jim_IncrRefCount(obj);
- e->stack[e->stacklen++] = obj;
-}
-
-static Jim_Obj *ExprPop(struct JimExprState *e)
-{
- return e->stack[--e->stacklen];
-}
+static int JimExprGetTerm(Jim_Interp *interp, struct JimExprNode *node, Jim_Obj **objPtrPtr);
+static int JimExprGetTermBoolean(Jim_Interp *interp, struct JimExprNode *node);
+static int JimExprEvalTermNode(Jim_Interp *interp, struct JimExprNode *node);
-static int JimExprOpNumUnary(Jim_Interp *interp, struct JimExprState *e)
+static int JimExprOpNumUnary(Jim_Interp *interp, struct JimExprNode *node)
{
int intresult = 1;
- int rc = JIM_OK;
- Jim_Obj *A = ExprPop(e);
+ int rc;
double dA, dC = 0;
jim_wide wA, wC = 0;
+ Jim_Obj *A;
+
+ if ((rc = JimExprGetTerm(interp, node->left, &A)) != JIM_OK) {
+ return rc;
+ }
if ((A->typePtr != &doubleObjType || A->bytes) && JimGetWideNoErr(interp, A, &wA) == JIM_OK) {
- switch (e->opcode) {
+ switch (node->type) {
case JIM_EXPROP_FUNC_INT:
case JIM_EXPROP_FUNC_WIDE:
case JIM_EXPROP_FUNC_ROUND:
@@ -7724,7 +7775,7 @@ static int JimExprOpNumUnary(Jim_Interp *interp, struct JimExprState *e)
}
}
else if ((rc = Jim_GetDouble(interp, A, &dA)) == JIM_OK) {
- switch (e->opcode) {
+ switch (node->type) {
case JIM_EXPROP_FUNC_INT:
case JIM_EXPROP_FUNC_WIDE:
wC = dA;
@@ -7759,10 +7810,10 @@ static int JimExprOpNumUnary(Jim_Interp *interp, struct JimExprState *e)
if (rc == JIM_OK) {
if (intresult) {
- ExprPush(e, Jim_NewIntObj(interp, wC));
+ Jim_SetResultInt(interp, wC);
}
else {
- ExprPush(e, Jim_NewDoubleObj(interp, dC));
+ Jim_SetResult(interp, Jim_NewDoubleObj(interp, dC));
}
}
@@ -7779,20 +7830,25 @@ static double JimRandDouble(Jim_Interp *interp)
return (double)x / (unsigned long)~0;
}
-static int JimExprOpIntUnary(Jim_Interp *interp, struct JimExprState *e)
+static int JimExprOpIntUnary(Jim_Interp *interp, struct JimExprNode *node)
{
- Jim_Obj *A = ExprPop(e);
jim_wide wA;
+ Jim_Obj *A;
+ int rc;
+
+ if ((rc = JimExprGetTerm(interp, node->left, &A)) != JIM_OK) {
+ return rc;
+ }
- int rc = Jim_GetWide(interp, A, &wA);
+ rc = Jim_GetWide(interp, A, &wA);
if (rc == JIM_OK) {
- switch (e->opcode) {
+ switch (node->type) {
case JIM_EXPROP_BITNOT:
- ExprPush(e, Jim_NewIntObj(interp, ~wA));
+ Jim_SetResultInt(interp, ~wA);
break;
case JIM_EXPROP_FUNC_SRAND:
JimPrngSeed(interp, (unsigned char *)&wA, sizeof(wA));
- ExprPush(e, Jim_NewDoubleObj(interp, JimRandDouble(interp)));
+ Jim_SetResult(interp, Jim_NewDoubleObj(interp, JimRandDouble(interp)));
break;
default:
abort();
@@ -7804,25 +7860,29 @@ static int JimExprOpIntUnary(Jim_Interp *interp, struct JimExprState *e)
return rc;
}
-static int JimExprOpNone(Jim_Interp *interp, struct JimExprState *e)
+static int JimExprOpNone(Jim_Interp *interp, struct JimExprNode *node)
{
- JimPanic((e->opcode != JIM_EXPROP_FUNC_RAND, "JimExprOpNone only support rand()"));
+ JimPanic((node->type != JIM_EXPROP_FUNC_RAND, "JimExprOpNone only support rand()"));
- ExprPush(e, Jim_NewDoubleObj(interp, JimRandDouble(interp)));
+ Jim_SetResult(interp, Jim_NewDoubleObj(interp, JimRandDouble(interp)));
return JIM_OK;
}
#ifdef JIM_MATH_FUNCTIONS
-static int JimExprOpDoubleUnary(Jim_Interp *interp, struct JimExprState *e)
+static int JimExprOpDoubleUnary(Jim_Interp *interp, struct JimExprNode *node)
{
int rc;
- Jim_Obj *A = ExprPop(e);
double dA, dC;
+ Jim_Obj *A;
+
+ if ((rc = JimExprGetTerm(interp, node->left, &A)) != JIM_OK) {
+ return rc;
+ }
rc = Jim_GetDouble(interp, A, &dA);
if (rc == JIM_OK) {
- switch (e->opcode) {
+ switch (node->type) {
case JIM_EXPROP_FUNC_SIN:
dC = sin(dA);
break;
@@ -7871,7 +7931,7 @@ static int JimExprOpDoubleUnary(Jim_Interp *interp, struct JimExprState *e)
default:
abort();
}
- ExprPush(e, Jim_NewDoubleObj(interp, dC));
+ Jim_SetResult(interp, Jim_NewDoubleObj(interp, dC));
}
Jim_DecrRefCount(interp, A);
@@ -7881,19 +7941,28 @@ static int JimExprOpDoubleUnary(Jim_Interp *interp, struct JimExprState *e)
#endif
/* A binary operation on two ints */
-static int JimExprOpIntBin(Jim_Interp *interp, struct JimExprState *e)
+static int JimExprOpIntBin(Jim_Interp *interp, struct JimExprNode *node)
{
- Jim_Obj *B = ExprPop(e);
- Jim_Obj *A = ExprPop(e);
jim_wide wA, wB;
- int rc = JIM_ERR;
+ int rc;
+ Jim_Obj *A, *B;
+
+ if ((rc = JimExprGetTerm(interp, node->left, &A)) != JIM_OK) {
+ return rc;
+ }
+ if ((rc = JimExprGetTerm(interp, node->right, &B)) != JIM_OK) {
+ Jim_DecrRefCount(interp, A);
+ return rc;
+ }
+
+ rc = JIM_ERR;
if (Jim_GetWide(interp, A, &wA) == JIM_OK && Jim_GetWide(interp, B, &wB) == JIM_OK) {
jim_wide wC;
rc = JIM_OK;
- switch (e->opcode) {
+ switch (node->type) {
case JIM_EXPROP_LSHIFT:
wC = wA << wB;
break;
@@ -7950,7 +8019,7 @@ static int JimExprOpIntBin(Jim_Interp *interp, struct JimExprState *e)
/* Shift left by the word size or more is undefined. */
uB %= S;
- if (e->opcode == JIM_EXPROP_ROTR) {
+ if (node->type == JIM_EXPROP_ROTR) {
uB = S - uB;
}
wC = (unsigned long)(uA << uB) | (uA >> (S - uB));
@@ -7959,8 +8028,7 @@ static int JimExprOpIntBin(Jim_Interp *interp, struct JimExprState *e)
default:
abort();
}
- ExprPush(e, Jim_NewIntObj(interp, wC));
-
+ Jim_SetResultInt(interp, wC);
}
Jim_DecrRefCount(interp, A);
@@ -7971,14 +8039,20 @@ static int JimExprOpIntBin(Jim_Interp *interp, struct JimExprState *e)
/* A binary operation on two ints or two doubles (or two strings for some ops) */
-static int JimExprOpBin(Jim_Interp *interp, struct JimExprState *e)
+static int JimExprOpBin(Jim_Interp *interp, struct JimExprNode *node)
{
int rc = JIM_OK;
double dA, dB, dC = 0;
jim_wide wA, wB, wC = 0;
+ Jim_Obj *A, *B;
- Jim_Obj *B = ExprPop(e);
- Jim_Obj *A = ExprPop(e);
+ if ((rc = JimExprGetTerm(interp, node->left, &A)) != JIM_OK) {
+ return rc;
+ }
+ if ((rc = JimExprGetTerm(interp, node->right, &B)) != JIM_OK) {
+ Jim_DecrRefCount(interp, A);
+ return rc;
+ }
if ((A->typePtr != &doubleObjType || A->bytes) &&
(B->typePtr != &doubleObjType || B->bytes) &&
@@ -7986,7 +8060,7 @@ static int JimExprOpBin(Jim_Interp *interp, struct JimExprState *e)
/* Both are ints */
- switch (e->opcode) {
+ switch (node->type) {
case JIM_EXPROP_POW:
case JIM_EXPROP_FUNC_POW:
if (wA == 0 && wB < 0) {
@@ -8051,7 +8125,7 @@ static int JimExprOpBin(Jim_Interp *interp, struct JimExprState *e)
}
}
if (Jim_GetDouble(interp, A, &dA) == JIM_OK && Jim_GetDouble(interp, B, &dB) == JIM_OK) {
- switch (e->opcode) {
+ switch (node->type) {
#ifndef JIM_MATH_FUNCTIONS
case JIM_EXPROP_POW:
case JIM_EXPROP_FUNC_POW:
@@ -8123,7 +8197,7 @@ static int JimExprOpBin(Jim_Interp *interp, struct JimExprState *e)
/* XXX: Could optimise the eq/ne case by checking lengths */
int i = Jim_StringCompareObj(interp, A, B, 0);
- switch (e->opcode) {
+ switch (node->type) {
case JIM_EXPROP_LT:
wC = i < 0;
goto intresult;
@@ -8151,10 +8225,10 @@ done:
Jim_DecrRefCount(interp, B);
return rc;
intresult:
- ExprPush(e, Jim_NewIntObj(interp, wC));
+ Jim_SetResultInt(interp, wC);
goto done;
doubleresult:
- ExprPush(e, Jim_NewDoubleObj(interp, dC));
+ Jim_SetResult(interp, Jim_NewDoubleObj(interp, dC));
goto done;
}
@@ -8172,18 +8246,27 @@ static int JimSearchList(Jim_Interp *interp, Jim_Obj *listObjPtr, Jim_Obj *valOb
return 0;
}
-static int JimExprOpStrBin(Jim_Interp *interp, struct JimExprState *e)
-{
- Jim_Obj *B = ExprPop(e);
- Jim_Obj *A = ExprPop(e);
+
+static int JimExprOpStrBin(Jim_Interp *interp, struct JimExprNode *node)
+{
+ Jim_Obj *A, *B;
jim_wide wC;
+ int rc;
+
+ if ((rc = JimExprGetTerm(interp, node->left, &A)) != JIM_OK) {
+ return rc;
+ }
+ if ((rc = JimExprGetTerm(interp, node->right, &B)) != JIM_OK) {
+ Jim_DecrRefCount(interp, A);
+ return rc;
+ }
- switch (e->opcode) {
+ switch (node->type) {
case JIM_EXPROP_STREQ:
case JIM_EXPROP_STRNE:
wC = Jim_StringEqObj(A, B);
- if (e->opcode == JIM_EXPROP_STRNE) {
+ if (node->type == JIM_EXPROP_STRNE) {
wC = !wC;
}
break;
@@ -8196,12 +8279,12 @@ static int JimExprOpStrBin(Jim_Interp *interp, struct JimExprState *e)
default:
abort();
}
- ExprPush(e, Jim_NewIntObj(interp, wC));
+ Jim_SetResultInt(interp, wC);
Jim_DecrRefCount(interp, A);
Jim_DecrRefCount(interp, B);
- return JIM_OK;
+ return rc;
}
static int ExprBool(Jim_Interp *interp, Jim_Obj *obj)
@@ -8209,162 +8292,78 @@ static int ExprBool(Jim_Interp *interp, Jim_Obj *obj)
long l;
double d;
int b;
+ int ret = -1;
+
+ /* In case the object is interp->result with refcount 1*/
+ Jim_IncrRefCount(obj);
if (Jim_GetLong(interp, obj, &l) == JIM_OK) {
- return l != 0;
- }
- if (Jim_GetDouble(interp, obj, &d) == JIM_OK) {
- return d != 0;
+ ret = (l != 0);
}
- if (Jim_GetBoolean(interp, obj, &b) == JIM_OK) {
- return b != 0;
+ else if (Jim_GetDouble(interp, obj, &d) == JIM_OK) {
+ ret = (d != 0);
}
- return -1;
-}
-
-static int JimExprOpAndLeft(Jim_Interp *interp, struct JimExprState *e)
-{
- Jim_Obj *skip = ExprPop(e);
- Jim_Obj *A = ExprPop(e);
- int rc = JIM_OK;
-
- switch (ExprBool(interp, A)) {
- case 0:
- /* false, so skip RHS opcodes with a 0 result */
- e->skip = JimWideValue(skip);
- ExprPush(e, Jim_NewIntObj(interp, 0));
- break;
-
- case 1:
- /* true so continue */
- break;
-
- case -1:
- /* Invalid */
- rc = JIM_ERR;
+ else if (Jim_GetBoolean(interp, obj, &b) == JIM_OK) {
+ ret = (b != 0);
}
- Jim_DecrRefCount(interp, A);
- Jim_DecrRefCount(interp, skip);
- return rc;
+ Jim_DecrRefCount(interp, obj);
+ return ret;
}
-static int JimExprOpOrLeft(Jim_Interp *interp, struct JimExprState *e)
+static int JimExprOpAnd(Jim_Interp *interp, struct JimExprNode *node)
{
- Jim_Obj *skip = ExprPop(e);
- Jim_Obj *A = ExprPop(e);
- int rc = JIM_OK;
-
- switch (ExprBool(interp, A)) {
- case 0:
- /* false, so do nothing */
- break;
+ /* evaluate left */
+ int result = JimExprGetTermBoolean(interp, node->left);
- case 1:
- /* true so skip RHS opcodes with a 1 result */
- e->skip = JimWideValue(skip);
- ExprPush(e, Jim_NewIntObj(interp, 1));
- break;
-
- case -1:
- /* Invalid */
- rc = JIM_ERR;
- break;
+ if (result == 1) {
+ /* true so evaluate right */
+ result = JimExprGetTermBoolean(interp, node->right);
}
- Jim_DecrRefCount(interp, A);
- Jim_DecrRefCount(interp, skip);
-
- return rc;
-}
-
-static int JimExprOpAndOrRight(Jim_Interp *interp, struct JimExprState *e)
-{
- Jim_Obj *A = ExprPop(e);
- int rc = JIM_OK;
-
- switch (ExprBool(interp, A)) {
- case 0:
- ExprPush(e, Jim_NewIntObj(interp, 0));
- break;
-
- case 1:
- ExprPush(e, Jim_NewIntObj(interp, 1));
- break;
-
- case -1:
- /* Invalid */
- rc = JIM_ERR;
- break;
+ if (result == -1) {
+ return JIM_ERR;
}
- Jim_DecrRefCount(interp, A);
-
- return rc;
+ Jim_SetResultInt(interp, result);
+ return JIM_OK;
}
-static int JimExprOpTernaryLeft(Jim_Interp *interp, struct JimExprState *e)
+static int JimExprOpOr(Jim_Interp *interp, struct JimExprNode *node)
{
- Jim_Obj *skip = ExprPop(e);
- Jim_Obj *A = ExprPop(e);
- int rc = JIM_OK;
-
- /* Repush A */
- ExprPush(e, A);
-
- switch (ExprBool(interp, A)) {
- case 0:
- /* false, skip RHS opcodes */
- e->skip = JimWideValue(skip);
- /* Push a dummy value */
- ExprPush(e, Jim_NewIntObj(interp, 0));
- break;
+ /* evaluate left */
+ int result = JimExprGetTermBoolean(interp, node->left);
- case 1:
- /* true so do nothing */
- break;
-
- case -1:
- /* Invalid */
- rc = JIM_ERR;
- break;
+ if (result == 0) {
+ /* false so evaluate right */
+ result = JimExprGetTermBoolean(interp, node->right);
}
- Jim_DecrRefCount(interp, A);
- Jim_DecrRefCount(interp, skip);
-
- return rc;
-}
-
-static int JimExprOpColonLeft(Jim_Interp *interp, struct JimExprState *e)
-{
- Jim_Obj *skip = ExprPop(e);
- Jim_Obj *B = ExprPop(e);
- Jim_Obj *A = ExprPop(e);
-
- /* No need to check for A as non-boolean */
- if (ExprBool(interp, A)) {
- /* true, so skip RHS opcodes */
- e->skip = JimWideValue(skip);
- /* Repush B as the answer */
- ExprPush(e, B);
+ if (result == -1) {
+ return JIM_ERR;
}
-
- Jim_DecrRefCount(interp, skip);
- Jim_DecrRefCount(interp, A);
- Jim_DecrRefCount(interp, B);
+ Jim_SetResultInt(interp, result);
return JIM_OK;
}
-static int JimExprOpNull(Jim_Interp *interp, struct JimExprState *e)
+static int JimExprOpTernary(Jim_Interp *interp, struct JimExprNode *node)
{
- return JIM_OK;
+ /* evaluate left */
+ int result = JimExprGetTermBoolean(interp, node->left);
+
+ if (result == 1) {
+ /* true so select right */
+ return JimExprEvalTermNode(interp, node->right);
+ }
+ else if (result == 0) {
+ /* false so select ternary */
+ return JimExprEvalTermNode(interp, node->ternary);
+ }
+ /* error */
+ return JIM_ERR;
}
enum
{
- LAZY_NONE,
- LAZY_OP,
- LAZY_LEFT,
- LAZY_RIGHT,
- RIGHT_ASSOC, /* reuse this field for right associativity too */
+ OP_FUNC = 0x0001, /* function syntax */
+ OP_RIGHT_ASSOC = 0x0002, /* right associative */
};
/* name - precedence - arity - opcode
@@ -8374,7 +8373,7 @@ enum
* The following macros pre-compute the string length at compile time.
*/
#define OPRINIT_ATTR(N, P, ARITY, F, ATTR) {N, F, P, ARITY, ATTR, sizeof(N) - 1}
-#define OPRINIT(N, P, ARITY, F) OPRINIT_ATTR(N, P, ARITY, F, LAZY_NONE)
+#define OPRINIT(N, P, ARITY, F) OPRINIT_ATTR(N, P, ARITY, F, 0)
static const struct Jim_ExprOperator Jim_ExprOperators[] = {
OPRINIT("*", 110, 2, JimExprOpBin),
@@ -8402,24 +8401,13 @@ static const struct Jim_ExprOperator Jim_ExprOperators[] = {
OPRINIT("^", 49, 2, JimExprOpIntBin),
OPRINIT("|", 48, 2, JimExprOpIntBin),
- OPRINIT_ATTR("&&", 10, 2, NULL, LAZY_OP),
- OPRINIT_ATTR(NULL, 10, 2, JimExprOpAndLeft, LAZY_LEFT),
- OPRINIT_ATTR(NULL, 10, 2, JimExprOpAndOrRight, LAZY_RIGHT),
-
- OPRINIT_ATTR("||", 9, 2, NULL, LAZY_OP),
- OPRINIT_ATTR(NULL, 9, 2, JimExprOpOrLeft, LAZY_LEFT),
- OPRINIT_ATTR(NULL, 9, 2, JimExprOpAndOrRight, LAZY_RIGHT),
-
- OPRINIT_ATTR("?", 5, 2, JimExprOpNull, LAZY_OP),
- OPRINIT_ATTR(NULL, 5, 2, JimExprOpTernaryLeft, LAZY_LEFT),
- OPRINIT_ATTR(NULL, 5, 2, JimExprOpNull, LAZY_RIGHT),
-
- OPRINIT_ATTR(":", 5, 2, JimExprOpNull, LAZY_OP),
- OPRINIT_ATTR(NULL, 5, 2, JimExprOpColonLeft, LAZY_LEFT),
- OPRINIT_ATTR(NULL, 5, 2, JimExprOpNull, LAZY_RIGHT),
+ OPRINIT("&&", 10, 2, JimExprOpAnd),
+ OPRINIT("||", 9, 2, JimExprOpOr),
+ OPRINIT_ATTR("?", 5, 3, JimExprOpTernary, OP_RIGHT_ASSOC),
+ OPRINIT_ATTR(":", 5, 3, NULL, OP_RIGHT_ASSOC),
/* Precedence is higher than * and / but lower than ! and ~, and right-associative */
- OPRINIT_ATTR("**", 120, 2, JimExprOpBin, RIGHT_ASSOC),
+ OPRINIT_ATTR("**", 120, 2, JimExprOpBin, OP_RIGHT_ASSOC),
OPRINIT("eq", 60, 2, JimExprOpStrBin),
OPRINIT("ne", 60, 2, JimExprOpStrBin),
@@ -8427,45 +8415,45 @@ static const struct Jim_ExprOperator Jim_ExprOperators[] = {
OPRINIT("in", 55, 2, JimExprOpStrBin),
OPRINIT("ni", 55, 2, JimExprOpStrBin),
- OPRINIT("!", 150, 1, JimExprOpNumUnary),
- OPRINIT("~", 150, 1, JimExprOpIntUnary),
- OPRINIT(NULL, 150, 1, JimExprOpNumUnary),
- OPRINIT(NULL, 150, 1, JimExprOpNumUnary),
+ OPRINIT_ATTR("!", 150, 1, JimExprOpNumUnary, OP_RIGHT_ASSOC),
+ OPRINIT_ATTR("~", 150, 1, JimExprOpIntUnary, OP_RIGHT_ASSOC),
+ OPRINIT_ATTR(" -", 150, 1, JimExprOpNumUnary, OP_RIGHT_ASSOC),
+ OPRINIT_ATTR(" +", 150, 1, JimExprOpNumUnary, OP_RIGHT_ASSOC),
- OPRINIT("int", 200, 1, JimExprOpNumUnary),
- OPRINIT("wide", 200, 1, JimExprOpNumUnary),
- OPRINIT("abs", 200, 1, JimExprOpNumUnary),
- OPRINIT("double", 200, 1, JimExprOpNumUnary),
- OPRINIT("round", 200, 1, JimExprOpNumUnary),
- OPRINIT("rand", 200, 0, JimExprOpNone),
- OPRINIT("srand", 200, 1, JimExprOpIntUnary),
+ OPRINIT_ATTR("int", 200, 1, JimExprOpNumUnary, OP_FUNC),
+ OPRINIT_ATTR("wide", 200, 1, JimExprOpNumUnary, OP_FUNC),
+ OPRINIT_ATTR("abs", 200, 1, JimExprOpNumUnary, OP_FUNC),
+ OPRINIT_ATTR("double", 200, 1, JimExprOpNumUnary, OP_FUNC),
+ OPRINIT_ATTR("round", 200, 1, JimExprOpNumUnary, OP_FUNC),
+ OPRINIT_ATTR("rand", 200, 0, JimExprOpNone, OP_FUNC),
+ OPRINIT_ATTR("srand", 200, 1, JimExprOpIntUnary, OP_FUNC),
#ifdef JIM_MATH_FUNCTIONS
- OPRINIT("sin", 200, 1, JimExprOpDoubleUnary),
- OPRINIT("cos", 200, 1, JimExprOpDoubleUnary),
- OPRINIT("tan", 200, 1, JimExprOpDoubleUnary),
- OPRINIT("asin", 200, 1, JimExprOpDoubleUnary),
- OPRINIT("acos", 200, 1, JimExprOpDoubleUnary),
- OPRINIT("atan", 200, 1, JimExprOpDoubleUnary),
- OPRINIT("atan2", 200, 2, JimExprOpBin),
- OPRINIT("sinh", 200, 1, JimExprOpDoubleUnary),
- OPRINIT("cosh", 200, 1, JimExprOpDoubleUnary),
- OPRINIT("tanh", 200, 1, JimExprOpDoubleUnary),
- OPRINIT("ceil", 200, 1, JimExprOpDoubleUnary),
- OPRINIT("floor", 200, 1, JimExprOpDoubleUnary),
- OPRINIT("exp", 200, 1, JimExprOpDoubleUnary),
- OPRINIT("log", 200, 1, JimExprOpDoubleUnary),
- OPRINIT("log10", 200, 1, JimExprOpDoubleUnary),
- OPRINIT("sqrt", 200, 1, JimExprOpDoubleUnary),
- OPRINIT("pow", 200, 2, JimExprOpBin),
- OPRINIT("hypot", 200, 2, JimExprOpBin),
- OPRINIT("fmod", 200, 2, JimExprOpBin),
+ OPRINIT_ATTR("sin", 200, 1, JimExprOpDoubleUnary, OP_FUNC),
+ OPRINIT_ATTR("cos", 200, 1, JimExprOpDoubleUnary, OP_FUNC),
+ OPRINIT_ATTR("tan", 200, 1, JimExprOpDoubleUnary, OP_FUNC),
+ OPRINIT_ATTR("asin", 200, 1, JimExprOpDoubleUnary, OP_FUNC),
+ OPRINIT_ATTR("acos", 200, 1, JimExprOpDoubleUnary, OP_FUNC),
+ OPRINIT_ATTR("atan", 200, 1, JimExprOpDoubleUnary, OP_FUNC),
+ OPRINIT_ATTR("atan2", 200, 2, JimExprOpBin, OP_FUNC),
+ OPRINIT_ATTR("sinh", 200, 1, JimExprOpDoubleUnary, OP_FUNC),
+ OPRINIT_ATTR("cosh", 200, 1, JimExprOpDoubleUnary, OP_FUNC),
+ OPRINIT_ATTR("tanh", 200, 1, JimExprOpDoubleUnary, OP_FUNC),
+ OPRINIT_ATTR("ceil", 200, 1, JimExprOpDoubleUnary, OP_FUNC),
+ OPRINIT_ATTR("floor", 200, 1, JimExprOpDoubleUnary, OP_FUNC),
+ OPRINIT_ATTR("exp", 200, 1, JimExprOpDoubleUnary, OP_FUNC),
+ OPRINIT_ATTR("log", 200, 1, JimExprOpDoubleUnary, OP_FUNC),
+ OPRINIT_ATTR("log10", 200, 1, JimExprOpDoubleUnary, OP_FUNC),
+ OPRINIT_ATTR("sqrt", 200, 1, JimExprOpDoubleUnary, OP_FUNC),
+ OPRINIT_ATTR("pow", 200, 2, JimExprOpBin, OP_FUNC),
+ OPRINIT_ATTR("hypot", 200, 2, JimExprOpBin, OP_FUNC),
+ OPRINIT_ATTR("fmod", 200, 2, JimExprOpBin, OP_FUNC),
#endif
};
#undef OPRINIT
-#undef OPRINIT_LAZY
+#undef OPRINIT_ATTR
#define JIM_EXPR_OPERATORS_NUM \
(sizeof(Jim_ExprOperators)/sizeof(struct Jim_ExprOperator))
@@ -8624,31 +8612,40 @@ static int JimParseExprBoolean(struct JimParserCtx *pc)
return JIM_ERR;
}
+static const struct Jim_ExprOperator *JimExprOperatorInfoByOpcode(int opcode)
+{
+ static Jim_ExprOperator dummy_op;
+ if (opcode < JIM_TT_EXPR_OP) {
+ return &dummy_op;
+ }
+ return &Jim_ExprOperators[opcode - JIM_TT_EXPR_OP];
+}
+
static int JimParseExprOperator(struct JimParserCtx *pc)
{
int i;
- int bestIdx = -1, bestLen = 0;
+ const struct Jim_ExprOperator *bestOp = NULL;
+ int bestLen = 0;
/* Try to get the longest match. */
for (i = 0; i < (signed)JIM_EXPR_OPERATORS_NUM; i++) {
- const char * const opname = Jim_ExprOperators[i].name;
- const int oplen = Jim_ExprOperators[i].namelen;
+ const struct Jim_ExprOperator *op = &Jim_ExprOperators[i];
- if (opname == NULL || opname[0] != pc->p[0]) {
+ if (op->name[0] != pc->p[0]) {
continue;
}
- if (oplen > bestLen && strncmp(opname, pc->p, oplen) == 0) {
- bestIdx = i + JIM_TT_EXPR_OP;
- bestLen = oplen;
+ if (op->namelen > bestLen && strncmp(op->name, pc->p, op->namelen) == 0) {
+ bestOp = op;
+ bestLen = op->namelen;
}
}
- if (bestIdx == -1) {
+ if (bestOp == NULL) {
return JIM_ERR;
}
/* Validate paretheses around function arguments */
- if (bestIdx >= JIM_EXPROP_FUNC_FIRST) {
+ if (bestOp->attr & OP_FUNC) {
const char *p = pc->p + bestLen;
int len = pc->len - bestLen;
@@ -8664,19 +8661,10 @@ static int JimParseExprOperator(struct JimParserCtx *pc)
pc->p += bestLen;
pc->len -= bestLen;
- pc->tt = bestIdx;
+ pc->tt = (bestOp - Jim_ExprOperators) + JIM_TT_EXPR_OP;
return JIM_OK;
}
-static const struct Jim_ExprOperator *JimExprOperatorInfoByOpcode(int opcode)
-{
- static Jim_ExprOperator dummy_op;
- if (opcode < JIM_TT_EXPR_OP) {
- return &dummy_op;
- }
- return &Jim_ExprOperators[opcode - JIM_TT_EXPR_OP];
-}
-
const char *jim_tt_name(int type)
{
static const char * const tt_names[JIM_TT_EXPR_OP] =
@@ -8718,35 +8706,42 @@ static const Jim_ObjType exprObjType = {
JIM_TYPE_REFERENCES,
};
-/* Expr bytecode structure */
-typedef struct ExprByteCode
+/* expr tree structure */
+struct ExprTree
{
- ScriptToken *token; /* Tokens array. */
- int len; /* Length as number of tokens. */
+ struct JimExprNode *expr; /* The first operator or term */
+ struct JimExprNode *nodes; /* Storage of all nodes in the tree */
+ int len; /* Number of nodes in use */
int inUse; /* Used for sharing. */
-} ExprByteCode;
+};
-static void ExprFreeByteCode(Jim_Interp *interp, ExprByteCode * expr)
+static void ExprTreeFreeNodes(Jim_Interp *interp, struct JimExprNode *nodes, int num)
{
int i;
-
- for (i = 0; i < expr->len; i++) {
- Jim_DecrRefCount(interp, expr->token[i].objPtr);
+ for (i = 0; i < num; i++) {
+ if (nodes[i].objPtr) {
+ Jim_DecrRefCount(interp, nodes[i].objPtr);
+ }
}
- Jim_Free(expr->token);
+ Jim_Free(nodes);
+}
+
+static void ExprTreeFree(Jim_Interp *interp, struct ExprTree *expr)
+{
+ ExprTreeFreeNodes(interp, expr->nodes, expr->len);
Jim_Free(expr);
}
static void FreeExprInternalRep(Jim_Interp *interp, Jim_Obj *objPtr)
{
- ExprByteCode *expr = (void *)objPtr->internalRep.ptr;
+ struct ExprTree *expr = (void *)objPtr->internalRep.ptr;
if (expr) {
if (--expr->inUse != 0) {
return;
}
- ExprFreeByteCode(interp, expr);
+ ExprTreeFree(interp, expr);
}
}
@@ -8759,376 +8754,156 @@ static void DupExprInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dup
dupPtr->typePtr = NULL;
}
-/* Check if an expr program looks correct
- * Sets an error result on invalid
- */
-static int ExprCheckCorrectness(Jim_Interp *interp, Jim_Obj *exprObjPtr, ExprByteCode * expr)
+struct ExprBuilder {
+ int parencount; /* count of outstanding parentheses */
+ int level; /* recursion depth */
+ ParseToken *token; /* The current token */
+ ParseToken *first_token; /* The first token */
+ Jim_Stack stack; /* stack of pending terms */
+ Jim_Obj *exprObjPtr; /* the original expression */
+ Jim_Obj *fileNameObj; /* filename of the original expression */
+ struct JimExprNode *nodes; /* storage for all nodes */
+ struct JimExprNode *next; /* storage for the next node */
+};
+
+#ifdef DEBUG_SHOW_EXPR
+static void JimShowExprNode(struct JimExprNode *node, int level)
{
int i;
- int stacklen = 0;
- int ternary = 0;
- int lasttt = JIM_TT_NONE;
- const char *errmsg;
-
- /* Try to check if there are stack underflows,
- * and make sure at the end of the program there is
- * a single result on the stack. */
- for (i = 0; i < expr->len; i++) {
- ScriptToken *t = &expr->token[i];
- const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(t->type);
- lasttt = t->type;
-
- stacklen -= op->arity;
-
- if (stacklen < 0) {
- break;
- }
- if (t->type == JIM_EXPROP_TERNARY || t->type == JIM_EXPROP_TERNARY_LEFT) {
- ternary++;
- }
- else if (t->type == JIM_EXPROP_COLON || t->type == JIM_EXPROP_COLON_LEFT) {
- ternary--;
- }
-
- /* All operations and operands add one to the stack */
- stacklen++;
- }
- if (stacklen == 1 && ternary == 0) {
- return JIM_OK;
+ for (i = 0; i < level; i++) {
+ printf(" ");
}
-
- if (stacklen <= 0) {
- /* Too few args */
- if (lasttt >= JIM_EXPROP_FUNC_FIRST) {
- errmsg = "too few arguments for math function";
- Jim_SetResultString(interp, "too few arguments for math function", -1);
- } else {
- errmsg = "premature end of expression";
+ if (TOKEN_IS_EXPR_OP(node->type)) {
+ printf("%s\n", jim_tt_name(node->type));
+ if (node->left) {
+ JimShowExprNode(node->left, level + 1);
}
- }
- else if (stacklen > 1) {
- if (lasttt >= JIM_EXPROP_FUNC_FIRST) {
- errmsg = "too many arguments for math function";
- } else {
- errmsg = "extra tokens at end of expression";
+ if (node->right) {
+ JimShowExprNode(node->right, level + 1);
+ }
+ if (node->ternary) {
+ JimShowExprNode(node->ternary, level + 1);
}
}
else {
- errmsg = "invalid ternary expression";
+ printf("[%s] %s\n", jim_tt_name(node->type), Jim_String(node->objPtr));
}
- Jim_SetResultFormatted(interp, "syntax error in expression \"%#s\": %s", exprObjPtr, errmsg);
- return JIM_ERR;
}
+#endif
-/* This procedure converts every occurrence of || and && opereators
- * in lazy unary versions.
- *
- * a b || is converted into:
- *
- * a <offset> |L b |R
- *
- * a b && is converted into:
+#define EXPR_UNTIL_CLOSE 0x0001
+#define EXPR_FUNC_ARGS 0x0002
+#define EXPR_TERNARY 0x0004
+
+/**
+ * Parse the subexpression at builder->token and return with the node on the stack.
+ * builder->token is advanced to the next unconsumed token.
+ * Returns JIM_OK if OK or JIM_ERR on error and leaves a message in the interpreter result.
*
- * a <offset> &L b &R
+ * 'precedence' is the precedence of the current operator. Tokens are consumed until an operator
+ * with an equal or lower precedence is reached (or strictly lower if right associative).
*
- * "|L" checks if 'a' is true:
- * 1) if it is true pushes 1 and skips <offset> instructions to reach
- * the opcode just after |R.
- * 2) if it is false does nothing.
- * "|R" checks if 'b' is true:
- * 1) if it is true pushes 1, otherwise pushes 0.
+ * If EXPR_UNTIL_CLOSE is set, the subexpression extends up to and including the next close parenthesis.
+ * If EXPR_FUNC_ARGS is set, multiple subexpressions (terms) are expected separated by comma
+ * If EXPR_TERNARY is set, two subexpressions (terms) are expected separated by colon
*
- * "&L" checks if 'a' is true:
- * 1) if it is true does nothing.
- * 2) If it is false pushes 0 and skips <offset> instructions to reach
- * the opcode just after &R
- * "&R" checks if 'a' is true:
- * if it is true pushes 1, otherwise pushes 0.
+ * 'exp_numterms' indicates how many terms are expected. Normally this is 1, but may be more for EXPR_FUNC_ARGS and EXPR_TERNARY.
*/
-static int ExprAddLazyOperator(Jim_Interp *interp, ExprByteCode * expr, ParseToken *t)
-{
- int i;
-
- int leftindex, arity, offset;
-
- /* Search for the end of the first operator */
- leftindex = expr->len - 1;
-
- arity = 1;
- while (arity) {
- ScriptToken *tt = &expr->token[leftindex];
-
- if (tt->type >= JIM_TT_EXPR_OP) {
- arity += JimExprOperatorInfoByOpcode(tt->type)->arity;
- }
- arity--;
- if (--leftindex < 0) {
- return JIM_ERR;
- }
- }
- leftindex++;
-
- /* Move them up */
- memmove(&expr->token[leftindex + 2], &expr->token[leftindex],
- sizeof(*expr->token) * (expr->len - leftindex));
- expr->len += 2;
- offset = (expr->len - leftindex) - 1;
-
- /* Now we rely on the fact that the left and right version have opcodes
- * 1 and 2 after the main opcode respectively
- */
- expr->token[leftindex + 1].type = t->type + 1;
- expr->token[leftindex + 1].objPtr = interp->emptyObj;
-
- expr->token[leftindex].type = JIM_TT_EXPR_INT;
- expr->token[leftindex].objPtr = Jim_NewIntObj(interp, offset);
-
- /* Now add the 'R' operator */
- expr->token[expr->len].objPtr = interp->emptyObj;
- expr->token[expr->len].type = t->type + 2;
- expr->len++;
-
- /* Do we need to adjust the skip count for any &L, |L, ?L or :L in the left operand? */
- for (i = leftindex - 1; i > 0; i--) {
- const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(expr->token[i].type);
- if (op->lazy == LAZY_LEFT) {
- if (JimWideValue(expr->token[i - 1].objPtr) + i - 1 >= leftindex) {
- JimWideValue(expr->token[i - 1].objPtr) += 2;
- }
- }
- }
- return JIM_OK;
-}
-
-static int ExprAddOperator(Jim_Interp *interp, ExprByteCode * expr, ParseToken *t)
+static int ExprTreeBuildTree(Jim_Interp *interp, struct ExprBuilder *builder, int precedence, int flags, int exp_numterms)
{
- struct ScriptToken *token = &expr->token[expr->len];
- const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(t->type);
+ int rc;
+ struct JimExprNode *node;
+ /* Calculate the stack length expected after pushing the number of expected terms */
+ int exp_stacklen = builder->stack.len + exp_numterms;
- if (op->lazy == LAZY_OP) {
- if (ExprAddLazyOperator(interp, expr, t) != JIM_OK) {
- Jim_SetResultFormatted(interp, "Expression has bad operands to %s", op->name);
- return JIM_ERR;
- }
- }
- else {
- token->objPtr = interp->emptyObj;
- token->type = t->type;
- expr->len++;
+ if (builder->level++ > 200) {
+ Jim_SetResultString(interp, "Expression too complex", -1);
+ return JIM_ERR;
}
- return JIM_OK;
-}
-/**
- * Returns the index of the COLON_LEFT to the left of 'right_index'
- * taking into account nesting.
- *
- * The expression *must* be well formed, thus a COLON_LEFT will always be found.
- */
-static int ExprTernaryGetColonLeftIndex(ExprByteCode *expr, int right_index)
-{
- int ternary_count = 1;
+ while (builder->token->type != JIM_TT_EOL) {
+ ParseToken *t = builder->token++;
+ int prevtt;
- right_index--;
-
- while (right_index > 1) {
- if (expr->token[right_index].type == JIM_EXPROP_TERNARY_LEFT) {
- ternary_count--;
- }
- else if (expr->token[right_index].type == JIM_EXPROP_COLON_RIGHT) {
- ternary_count++;
+ if (t == builder->first_token) {
+ prevtt = JIM_TT_NONE;
}
- else if (expr->token[right_index].type == JIM_EXPROP_COLON_LEFT && ternary_count == 1) {
- return right_index;
+ else {
+ prevtt = t[-1].type;
}
- right_index--;
- }
-
- /*notreached*/
- return -1;
-}
-
-/**
- * Find the left/right indices for the ternary expression to the left of 'right_index'.
- *
- * Returns 1 if found, and fills in *prev_right_index and *prev_left_index.
- * Otherwise returns 0.
- */
-static int ExprTernaryGetMoveIndices(ExprByteCode *expr, int right_index, int *prev_right_index, int *prev_left_index)
-{
- int i = right_index - 1;
- int ternary_count = 1;
- while (i > 1) {
- if (expr->token[i].type == JIM_EXPROP_TERNARY_LEFT) {
- if (--ternary_count == 0 && expr->token[i - 2].type == JIM_EXPROP_COLON_RIGHT) {
- *prev_right_index = i - 2;
- *prev_left_index = ExprTernaryGetColonLeftIndex(expr, *prev_right_index);
- return 1;
+ if (t->type == JIM_TT_SUBEXPR_START) {
+ if (builder->stack.len == exp_stacklen) {
+ Jim_SetResultFormatted(interp, "unexpected open parenthesis in expression: \"%#s\"", builder->exprObjPtr);
+ return JIM_ERR;
}
- }
- else if (expr->token[i].type == JIM_EXPROP_COLON_RIGHT) {
- if (ternary_count == 0) {
- return 0;
+ builder->parencount++;
+ rc = ExprTreeBuildTree(interp, builder, 0, EXPR_UNTIL_CLOSE, 1);
+ if (rc != JIM_OK) {
+ return rc;
}
- ternary_count++;
- }
- i--;
- }
- return 0;
-}
-
-/*
-* ExprTernaryReorderExpression description
-* ========================================
-*
-* ?: is right-to-left associative which doesn't work with the stack-based
-* expression engine. The fix is to reorder the bytecode.
-*
-* The expression:
-*
-* expr 1?2:0?3:4
-*
-* Has initial bytecode:
-*
-* '1' '2' (40=TERNARY_LEFT) '2' (41=TERNARY_RIGHT) '2' (43=COLON_LEFT) '0' (44=COLON_RIGHT)
-* '2' (40=TERNARY_LEFT) '3' (41=TERNARY_RIGHT) '2' (43=COLON_LEFT) '4' (44=COLON_RIGHT)
-*
-* The fix involves simulating this expression instead:
-*
-* expr 1?2:(0?3:4)
-*
-* With the following bytecode:
-*
-* '1' '2' (40=TERNARY_LEFT) '2' (41=TERNARY_RIGHT) '10' (43=COLON_LEFT) '0' '2' (40=TERNARY_LEFT)
-* '3' (41=TERNARY_RIGHT) '2' (43=COLON_LEFT) '4' (44=COLON_RIGHT) (44=COLON_RIGHT)
-*
-* i.e. The token COLON_RIGHT at index 8 is moved towards the end of the stack, all tokens above 8
-* are shifted down and the skip count of the token JIM_EXPROP_COLON_LEFT at index 5 is
-* incremented by the amount tokens shifted down. The token JIM_EXPROP_COLON_RIGHT that is moved
-* is identified as immediately preceeding a token JIM_EXPROP_TERNARY_LEFT
-*
-* ExprTernaryReorderExpression works thus as follows :
-* - start from the end of the stack
-* - while walking towards the beginning of the stack
-* if token=JIM_EXPROP_COLON_RIGHT then
-* find the associated token JIM_EXPROP_TERNARY_LEFT, which allows to
-* find the associated token previous(JIM_EXPROP_COLON_RIGHT)
-* find the associated token previous(JIM_EXPROP_LEFT_RIGHT)
-* if all found then
-* perform the rotation
-* update the skip count of the token previous(JIM_EXPROP_LEFT_RIGHT)
-* end if
-* end if
-*
-* Note: care has to be taken for nested ternary constructs!!!
-*/
-static void ExprTernaryReorderExpression(Jim_Interp *interp, ExprByteCode *expr)
-{
- int i;
-
- for (i = expr->len - 1; i > 1; i--) {
- int prev_right_index;
- int prev_left_index;
- int j;
- ScriptToken tmp;
-
- if (expr->token[i].type != JIM_EXPROP_COLON_RIGHT) {
- continue;
+ /* A complete subexpression is on the stack */
}
-
- /* COLON_RIGHT found: get the indexes needed to move the tokens in the stack (if any) */
- if (ExprTernaryGetMoveIndices(expr, i, &prev_right_index, &prev_left_index) == 0) {
- continue;
+ else if (t->type == JIM_TT_SUBEXPR_END) {
+ if (!(flags & EXPR_UNTIL_CLOSE)) {
+ if (builder->stack.len == exp_stacklen && builder->level > 1) {
+ builder->token--;
+ builder->level--;
+ return JIM_OK;
+ }
+ Jim_SetResultFormatted(interp, "unexpected closing parenthesis in expression: \"%#s\"", builder->exprObjPtr);
+ return JIM_ERR;
+ }
+ builder->parencount--;
+ if (builder->stack.len == exp_stacklen) {
+ /* Return with the expected number of subexpressions on the stack */
+ break;
+ }
}
-
- /*
- ** rotate tokens down
- **
- ** +-> [i] : JIM_EXPROP_COLON_RIGHT
- ** | | |
- ** | V V
- ** | [...] : ...
- ** | | |
- ** | V V
- ** | [...] : ...
- ** | | |
- ** | V V
- ** +- [prev_right_index] : JIM_EXPROP_COLON_RIGHT
- */
- tmp = expr->token[prev_right_index];
- for (j = prev_right_index; j < i; j++) {
- expr->token[j] = expr->token[j + 1];
- }
- expr->token[i] = tmp;
-
- /* Increment the 'skip' count associated to the previous JIM_EXPROP_COLON_LEFT token
- *
- * This is 'colon left increment' = i - prev_right_index
- *
- * [prev_left_index] : JIM_EXPROP_LEFT_RIGHT
- * [prev_left_index-1] : skip_count
- *
- */
- JimWideValue(expr->token[prev_left_index-1].objPtr) += (i - prev_right_index);
-
- /* Adjust for i-- in the loop */
- i++;
- }
-}
-
-static ExprByteCode *ExprCreateByteCode(Jim_Interp *interp, const ParseTokenList *tokenlist, Jim_Obj *exprObjPtr, Jim_Obj *fileNameObj)
-{
- Jim_Stack stack;
- ExprByteCode *expr;
- int ok = 1;
- int i;
- int prevtt = JIM_TT_NONE;
- int have_ternary = 0;
-
- /* -1 for EOL */
- int count = tokenlist->count - 1;
-
- expr = Jim_Alloc(sizeof(*expr));
- expr->inUse = 1;
- expr->len = 0;
-
- Jim_InitStack(&stack);
-
- /* Need extra bytecodes for lazy operators.
- * Also check for the ternary operator
- */
- for (i = 0; i < tokenlist->count; i++) {
- ParseToken *t = &tokenlist->list[i];
- const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(t->type);
-
- if (op->lazy == LAZY_OP) {
- count += 2;
- /* Ternary is a lazy op but also needs reordering */
- if (t->type == JIM_EXPROP_TERNARY) {
- have_ternary = 1;
+ else if (t->type == JIM_TT_SUBEXPR_COMMA) {
+ if (!(flags & EXPR_FUNC_ARGS)) {
+ if (builder->stack.len == exp_stacklen) {
+ /* handle the comma back at the parent level */
+ builder->token--;
+ builder->level--;
+ return JIM_OK;
+ }
+ Jim_SetResultFormatted(interp, "unexpected comma in expression: \"%#s\"", builder->exprObjPtr);
+ return JIM_ERR;
+ }
+ else {
+ /* If we see more terms than expected, it is an error */
+ if (builder->stack.len > exp_stacklen) {
+ Jim_SetResultFormatted(interp, "too many arguments to math function");
+ return JIM_ERR;
+ }
}
+ /* just go onto the next arg */
}
- }
-
- expr->token = Jim_Alloc(sizeof(ScriptToken) * count);
-
- for (i = 0; i < tokenlist->count && ok; i++) {
- ParseToken *t = &tokenlist->list[i];
-
- /* Next token will be stored here */
- struct ScriptToken *token = &expr->token[expr->len];
-
- if (t->type == JIM_TT_EOL) {
- break;
+ else if (t->type == JIM_EXPROP_COLON) {
+ if (!(flags & EXPR_TERNARY)) {
+ if (builder->level != 1) {
+ /* handle the comma back at the parent level */
+ builder->token--;
+ builder->level--;
+ return JIM_OK;
+ }
+ Jim_SetResultFormatted(interp, ": without ? in expression: \"%#s\"", builder->exprObjPtr);
+ return JIM_ERR;
+ }
+ if (builder->stack.len == exp_stacklen) {
+ /* handle the comma back at the parent level */
+ builder->token--;
+ builder->level--;
+ return JIM_OK;
+ }
+ /* just go onto the next term */
}
-
- if (TOKEN_IS_EXPR_OP(t->type)) {
+ else if (TOKEN_IS_EXPR_OP(t->type)) {
const struct Jim_ExprOperator *op;
- ParseToken *tt;
/* Convert -/+ to unary minus or unary plus if necessary */
- if (prevtt == JIM_TT_NONE || prevtt == JIM_TT_SUBEXPR_START || prevtt == JIM_TT_SUBEXPR_COMMA || prevtt >= JIM_TT_EXPR_OP) {
+ if (TOKEN_IS_EXPR_OP(prevtt) || TOKEN_IS_EXPR_START(prevtt)) {
if (t->type == JIM_EXPROP_SUB) {
t->type = JIM_EXPROP_UNARYMINUS;
}
@@ -9139,68 +8914,85 @@ static ExprByteCode *ExprCreateByteCode(Jim_Interp *interp, const ParseTokenList
op = JimExprOperatorInfoByOpcode(t->type);
- /* Handle precedence */
- while ((tt = Jim_StackPeek(&stack)) != NULL) {
- const struct Jim_ExprOperator *tt_op =
- JimExprOperatorInfoByOpcode(tt->type);
-
- /* Note that right-to-left associativity of ?: operator is handled later.
- */
+ if (op->precedence < precedence || (!(op->attr & OP_RIGHT_ASSOC) && op->precedence == precedence)) {
+ /* next op is lower precedence, or equal and left associative, so done here */
+ builder->token--;
+ break;
+ }
- if (op->arity != 1 && tt_op->precedence >= op->precedence) {
- /* Don't reduce if right associative with equal precedence? */
- if (tt_op->precedence == op->precedence && tt_op->lazy == RIGHT_ASSOC) {
- break;
- }
- if (ExprAddOperator(interp, expr, tt) != JIM_OK) {
- ok = 0;
- goto err;
- }
- Jim_StackPop(&stack);
+ if (op->attr & OP_FUNC) {
+ if (builder->token->type != JIM_TT_SUBEXPR_START) {
+ Jim_SetResultString(interp, "missing arguments for math function", -1);
+ return JIM_ERR;
}
- else {
- break;
+ builder->token++;
+ if (op->arity == 0) {
+ if (builder->token->type != JIM_TT_SUBEXPR_END) {
+ Jim_SetResultString(interp, "too many arguments for math function", -1);
+ return JIM_ERR;
+ }
+ builder->token++;
+ goto noargs;
}
+ builder->parencount++;
+
+ /* This will push left and return right */
+ rc = ExprTreeBuildTree(interp, builder, 0, EXPR_FUNC_ARGS | EXPR_UNTIL_CLOSE, op->arity);
+ }
+ else if (t->type == JIM_EXPROP_TERNARY) {
+ /* Collect the two arguments to the ternary operator */
+ rc = ExprTreeBuildTree(interp, builder, op->precedence, EXPR_TERNARY, 2);
+ }
+ else {
+ /* Recursively handle everything on the right until we see a precendence <= op->precedence or == and right associative
+ * and push that on the term stack
+ */
+ rc = ExprTreeBuildTree(interp, builder, op->precedence, 0, 1);
}
- Jim_StackPush(&stack, t);
- }
- else if (t->type == JIM_TT_SUBEXPR_START) {
- Jim_StackPush(&stack, t);
- }
- else if (t->type == JIM_TT_SUBEXPR_END || t->type == JIM_TT_SUBEXPR_COMMA) {
- /* Reduce the expression back to the previous ( or , */
- ok = 0;
- while (Jim_StackLen(&stack)) {
- ParseToken *tt = Jim_StackPop(&stack);
- if (tt->type == JIM_TT_SUBEXPR_START || tt->type == JIM_TT_SUBEXPR_COMMA) {
- if (t->type == JIM_TT_SUBEXPR_COMMA) {
- /* Need to push back the previous START or COMMA in the case of comma */
- Jim_StackPush(&stack, tt);
- }
- ok = 1;
- break;
+ if (rc != JIM_OK) {
+ return rc;
+ }
+
+noargs:
+ node = builder->next++;
+ node->type = t->type;
+
+ if (op->arity >= 3) {
+ node->ternary = Jim_StackPop(&builder->stack);
+ if (node->ternary == NULL) {
+ goto missingoperand;
}
- if (ExprAddOperator(interp, expr, tt) != JIM_OK) {
- goto err;
+ }
+ if (op->arity >= 2) {
+ node->right = Jim_StackPop(&builder->stack);
+ if (node->right == NULL) {
+ goto missingoperand;
}
}
- if (!ok) {
- Jim_SetResultFormatted(interp, "Unexpected close parenthesis in expression: \"%#s\"", exprObjPtr);
- goto err;
+ if (op->arity >= 1) {
+ node->left = Jim_StackPop(&builder->stack);
+ if (node->left == NULL) {
+missingoperand:
+ Jim_SetResultFormatted(interp, "missing operand to %s in expression: \"%#s\"", op->name, builder->exprObjPtr);
+ builder->next--;
+ return JIM_ERR;
+
+ }
}
+
+ /* Now push the node */
+ Jim_StackPush(&builder->stack, node);
}
else {
Jim_Obj *objPtr = NULL;
/* This is a simple non-operator term, so create and push the appropriate object */
- token->type = t->type;
/* Two consecutive terms without an operator is invalid */
if (!TOKEN_IS_EXPR_START(prevtt) && !TOKEN_IS_EXPR_OP(prevtt)) {
- Jim_SetResultFormatted(interp, "missing operator in expression: \"%#s\"", exprObjPtr);
- ok = 0;
- goto err;
+ Jim_SetResultFormatted(interp, "missing operator in expression: \"%#s\"", builder->exprObjPtr);
+ return JIM_ERR;
}
/* Immediately create a double or int object? */
@@ -9219,66 +9011,105 @@ static ExprByteCode *ExprCreateByteCode(Jim_Interp *interp, const ParseTokenList
}
}
- if (objPtr) {
- token->objPtr = objPtr;
- }
- else {
+ if (!objPtr) {
/* Everything else is stored a simple string term */
- token->objPtr = Jim_NewStringObj(interp, t->token, t->len);
+ objPtr = Jim_NewStringObj(interp, t->token, t->len);
if (t->type == JIM_TT_CMD) {
/* Only commands need source info */
- JimSetSourceInfo(interp, token->objPtr, fileNameObj, t->line);
+ JimSetSourceInfo(interp, objPtr, builder->fileNameObj, t->line);
}
}
- expr->len++;
+
+ /* Now push a term node */
+ node = builder->next++;
+ node->objPtr = objPtr;
+ Jim_IncrRefCount(node->objPtr);
+ node->type = t->type;
+ Jim_StackPush(&builder->stack, node);
}
- prevtt = t->type;
}
- /* Reduce any remaining subexpr */
- while (Jim_StackLen(&stack)) {
- ParseToken *tt = Jim_StackPop(&stack);
+ if (builder->stack.len == exp_stacklen) {
+ builder->level--;
+ return JIM_OK;
+ }
- if (tt->type == JIM_TT_SUBEXPR_START) {
- ok = 0;
- Jim_SetResultString(interp, "Missing close parenthesis", -1);
- goto err;
+ if ((flags & EXPR_FUNC_ARGS)) {
+ Jim_SetResultFormatted(interp, "too %s arguments for math function", (builder->stack.len < exp_stacklen) ? "few" : "many");
+ }
+ else {
+ if (builder->stack.len < exp_stacklen) {
+ if (builder->level == 0) {
+ Jim_SetResultFormatted(interp, "empty expression");
+ }
+ else {
+ Jim_SetResultFormatted(interp, "syntax error in expression \"%#s\": premature end of expression", builder->exprObjPtr);
+ }
}
- if (ExprAddOperator(interp, expr, tt) != JIM_OK) {
- ok = 0;
- goto err;
+ else {
+ Jim_SetResultFormatted(interp, "extra terms after expression");
}
}
- if (have_ternary) {
- ExprTernaryReorderExpression(interp, expr);
- }
+ return JIM_ERR;
+}
- err:
- /* Free the stack used for the compilation. */
- Jim_FreeStack(&stack);
+static struct ExprTree *ExprTreeCreateTree(Jim_Interp *interp, const ParseTokenList *tokenlist, Jim_Obj *exprObjPtr, Jim_Obj *fileNameObj)
+{
+ struct ExprTree *expr;
+ struct ExprBuilder builder;
+ int rc;
+ struct JimExprNode *top = NULL;
+
+ builder.parencount = 0;
+ builder.level = 0;
+ builder.token = builder.first_token = tokenlist->list;
+ builder.exprObjPtr = exprObjPtr;
+ builder.fileNameObj = fileNameObj;
+ /* The bytecode will never produce more nodes than there are tokens - 1 (for EOL)*/
+ builder.nodes = malloc(sizeof(struct JimExprNode) * (tokenlist->count - 1));
+ memset(builder.nodes, 0, sizeof(struct JimExprNode) * (tokenlist->count - 1));
+ builder.next = builder.nodes;
+ Jim_InitStack(&builder.stack);
- for (i = 0; i < expr->len; i++) {
- Jim_IncrRefCount(expr->token[i].objPtr);
+ rc = ExprTreeBuildTree(interp, &builder, 0, 0, 1);
+
+ if (rc == JIM_OK) {
+ top = Jim_StackPop(&builder.stack);
+
+ if (builder.parencount) {
+ Jim_SetResultString(interp, "missing close parenthesis", -1);
+ rc = JIM_ERR;
+ }
}
- if (!ok) {
- ExprFreeByteCode(interp, expr);
+ /* Free the stack used for the compilation. */
+ Jim_FreeStack(&builder.stack);
+
+ if (rc != JIM_OK) {
+ ExprTreeFreeNodes(interp, builder.nodes, builder.next - builder.nodes);
return NULL;
}
+ expr = Jim_Alloc(sizeof(*expr));
+ expr->inUse = 1;
+ expr->expr = top;
+ expr->nodes = builder.nodes;
+ expr->len = builder.next - builder.nodes;
+
+ assert(expr->len <= tokenlist->count - 1);
+
return expr;
}
-
/* This method takes the string representation of an expression
- * and generates a program for the Expr's stack-based VM. */
+ * and generates a program for the expr engine */
static int SetExprFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr)
{
int exprTextLen;
const char *exprText;
struct JimParserCtx parser;
- struct ExprByteCode *expr;
+ struct ExprTree *expr;
ParseTokenList tokenlist;
int line;
Jim_Obj *fileNameObj;
@@ -9331,7 +9162,7 @@ static int SetExprFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr)
}
/* Now create the expression bytecode from the tokenlist */
- expr = ExprCreateByteCode(interp, &tokenlist, objPtr, fileNameObj);
+ expr = ExprTreeCreateTree(interp, &tokenlist, objPtr, fileNameObj);
/* No longer need the token list */
ScriptTokenListFree(&tokenlist);
@@ -9341,26 +9172,10 @@ static int SetExprFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr)
}
#ifdef DEBUG_SHOW_EXPR
- {
- int i;
-
- printf("==== Expr ====\n");
- for (i = 0; i < expr->len; i++) {
- ScriptToken *t = &expr->token[i];
-
- printf("[%2d] %s '%s'\n", i, jim_tt_name(t->type), Jim_String(t->objPtr));
- }
- }
+ printf("==== Expr ====\n");
+ JimShowExprNode(expr->expr, 0);
#endif
- /* Check program correctness. */
- if (ExprCheckCorrectness(interp, objPtr, expr) != JIM_OK) {
- /* ExprCheckCorrectness set an error in this case */
- ExprFreeByteCode(interp, expr);
- expr = NULL;
- goto err;
- }
-
rc = JIM_OK;
err:
@@ -9372,25 +9187,25 @@ static int SetExprFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr)
return rc;
}
-static ExprByteCode *JimGetExpression(Jim_Interp *interp, Jim_Obj *objPtr)
+static struct ExprTree *JimGetExpression(Jim_Interp *interp, Jim_Obj *objPtr)
{
if (objPtr->typePtr != &exprObjType) {
if (SetExprFromAny(interp, objPtr) != JIM_OK) {
return NULL;
}
}
- return (ExprByteCode *) Jim_GetIntRepPtr(objPtr);
+ return (struct ExprTree *) Jim_GetIntRepPtr(objPtr);
}
#ifdef JIM_OPTIMIZATION
-static Jim_Obj *JimExprIntValOrVar(Jim_Interp *interp, const ScriptToken *token)
-{
- if (token->type == JIM_TT_EXPR_INT)
- return token->objPtr;
- else if (token->type == JIM_TT_VAR)
- return Jim_GetVariable(interp, token->objPtr, JIM_NONE);
- else if (token->type == JIM_TT_DICTSUGAR)
- return JimExpandDictSugar(interp, token->objPtr);
+static Jim_Obj *JimExprIntValOrVar(Jim_Interp *interp, struct JimExprNode *node)
+{
+ if (node->type == JIM_TT_EXPR_INT)
+ return node->objPtr;
+ else if (node->type == JIM_TT_VAR)
+ return Jim_GetVariable(interp, node->objPtr, JIM_NONE);
+ else if (node->type == JIM_TT_DICTSUGAR)
+ return JimExpandDictSugar(interp, node->objPtr);
else
return NULL;
}
@@ -9398,11 +9213,11 @@ static Jim_Obj *JimExprIntValOrVar(Jim_Interp *interp, const ScriptToken *token)
/* -----------------------------------------------------------------------------
* Expressions evaluation.
- * Jim uses a specialized stack-based virtual machine for expressions,
+ * Jim uses a recursive evaluation engine for expressions,
* that takes advantage of the fact that expr's operators
* can't be redefined.
*
- * Jim_EvalExpression() uses the bytecode compiled by
+ * Jim_EvalExpression() uses the expression tree compiled by
* SetExprFromAny() method of the "expression" object.
*
* On success a Tcl Object containing the result of the evaluation
@@ -9411,15 +9226,80 @@ static Jim_Obj *JimExprIntValOrVar(Jim_Interp *interp, const ScriptToken *token)
* On error the function returns a retcode != to JIM_OK and set a suitable
* error on the interp.
* ---------------------------------------------------------------------------*/
-#define JIM_EE_STATICSTACK_LEN 10
-int Jim_EvalExpression(Jim_Interp *interp, Jim_Obj *exprObjPtr, Jim_Obj **exprResultPtrPtr)
+static int JimExprEvalTermNode(Jim_Interp *interp, struct JimExprNode *node)
{
- ExprByteCode *expr;
- Jim_Obj *staticStack[JIM_EE_STATICSTACK_LEN];
- int i;
+ if (TOKEN_IS_EXPR_OP(node->type)) {
+ const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(node->type);
+ return op->funcop(interp, node);
+ }
+ else {
+ Jim_Obj *objPtr;
+
+ /* A term */
+ switch (node->type) {
+ case JIM_TT_EXPR_INT:
+ case JIM_TT_EXPR_DOUBLE:
+ case JIM_TT_EXPR_BOOLEAN:
+ case JIM_TT_STR:
+ Jim_SetResult(interp, node->objPtr);
+ return JIM_OK;
+
+ case JIM_TT_VAR:
+ objPtr = Jim_GetVariable(interp, node->objPtr, JIM_ERRMSG);
+ if (objPtr) {
+ Jim_SetResult(interp, objPtr);
+ return JIM_OK;
+ }
+ return JIM_ERR;
+
+ case JIM_TT_DICTSUGAR:
+ objPtr = JimExpandDictSugar(interp, node->objPtr);
+ if (objPtr) {
+ Jim_SetResult(interp, objPtr);
+ return JIM_OK;
+ }
+ return JIM_ERR;
+
+ case JIM_TT_ESC:
+ if (Jim_SubstObj(interp, node->objPtr, &objPtr, JIM_NONE) == JIM_OK) {
+ Jim_SetResult(interp, objPtr);
+ return JIM_OK;
+ }
+ return JIM_ERR;
+
+ case JIM_TT_CMD:
+ return Jim_EvalObj(interp, node->objPtr);
+
+ default:
+ /* Should never get here */
+ return JIM_ERR;
+ }
+ }
+}
+
+static int JimExprGetTerm(Jim_Interp *interp, struct JimExprNode *node, Jim_Obj **objPtrPtr)
+{
+ int rc = JimExprEvalTermNode(interp, node);
+ if (rc == JIM_OK) {
+ *objPtrPtr = Jim_GetResult(interp);
+ Jim_IncrRefCount(*objPtrPtr);
+ }
+ return rc;
+}
+
+static int JimExprGetTermBoolean(Jim_Interp *interp, struct JimExprNode *node)
+{
+ if (JimExprEvalTermNode(interp, node) == JIM_OK) {
+ return ExprBool(interp, Jim_GetResult(interp));
+ }
+ return -1;
+}
+
+int Jim_EvalExpression(Jim_Interp *interp, Jim_Obj *exprObjPtr)
+{
+ struct ExprTree *expr;
int retcode = JIM_OK;
- struct JimExprState e;
expr = JimGetExpression(interp, exprObjPtr);
if (!expr) {
@@ -9447,35 +9327,33 @@ int Jim_EvalExpression(Jim_Interp *interp, Jim_Obj *exprObjPtr, Jim_Obj **exprRe
switch (expr->len) {
case 1:
- objPtr = JimExprIntValOrVar(interp, &expr->token[0]);
+ objPtr = JimExprIntValOrVar(interp, expr->expr);
if (objPtr) {
- Jim_IncrRefCount(objPtr);
- *exprResultPtrPtr = objPtr;
+ Jim_SetResult(interp, objPtr);
return JIM_OK;
}
break;
case 2:
- if (expr->token[1].type == JIM_EXPROP_NOT) {
- objPtr = JimExprIntValOrVar(interp, &expr->token[0]);
+ if (expr->expr->type == JIM_EXPROP_NOT) {
+ objPtr = JimExprIntValOrVar(interp, expr->expr->left);
if (objPtr && JimIsWide(objPtr)) {
- *exprResultPtrPtr = JimWideValue(objPtr) ? interp->falseObj : interp->trueObj;
- Jim_IncrRefCount(*exprResultPtrPtr);
+ Jim_SetResult(interp, JimWideValue(objPtr) ? interp->falseObj : interp->trueObj);
return JIM_OK;
}
}
break;
case 3:
- objPtr = JimExprIntValOrVar(interp, &expr->token[0]);
+ objPtr = JimExprIntValOrVar(interp, expr->expr->left);
if (objPtr && JimIsWide(objPtr)) {
- Jim_Obj *objPtr2 = JimExprIntValOrVar(interp, &expr->token[1]);
+ Jim_Obj *objPtr2 = JimExprIntValOrVar(interp, expr->expr->right);
if (objPtr2 && JimIsWide(objPtr2)) {
jim_wide wideValueA = JimWideValue(objPtr);
jim_wide wideValueB = JimWideValue(objPtr2);
int cmpRes;
- switch (expr->token[2].type) {
+ switch (expr->expr->type) {
case JIM_EXPROP_LT:
cmpRes = wideValueA < wideValueB;
break;
@@ -9497,8 +9375,7 @@ int Jim_EvalExpression(Jim_Interp *interp, Jim_Obj *exprObjPtr, Jim_Obj **exprRe
default:
goto noopt;
}
- *exprResultPtrPtr = cmpRes ? interp->trueObj : interp->falseObj;
- Jim_IncrRefCount(*exprResultPtrPtr);
+ Jim_SetResult(interp, cmpRes ? interp->trueObj : interp->falseObj);
return JIM_OK;
}
}
@@ -9508,131 +9385,39 @@ int Jim_EvalExpression(Jim_Interp *interp, Jim_Obj *exprObjPtr, Jim_Obj **exprRe
noopt:
#endif
- /* In order to avoid that the internal repr gets freed due to
+ /* In order to avoid the internal repr being freed due to
* shimmering of the exprObjPtr's object, we make the internal rep
* shared. */
expr->inUse++;
- /* The stack-based expr VM itself */
-
- /* Stack allocation. Expr programs have the feature that
- * a program of length N can't require a stack longer than
- * N. */
- if (expr->len > JIM_EE_STATICSTACK_LEN)
- e.stack = Jim_Alloc(sizeof(Jim_Obj *) * expr->len);
- else
- e.stack = staticStack;
-
- e.stacklen = 0;
-
- /* Execute every instruction */
- for (i = 0; i < expr->len && retcode == JIM_OK; i++) {
- Jim_Obj *objPtr;
-
- switch (expr->token[i].type) {
- case JIM_TT_EXPR_INT:
- case JIM_TT_EXPR_DOUBLE:
- case JIM_TT_EXPR_BOOLEAN:
- case JIM_TT_STR:
- ExprPush(&e, expr->token[i].objPtr);
- break;
-
- case JIM_TT_VAR:
- objPtr = Jim_GetVariable(interp, expr->token[i].objPtr, JIM_ERRMSG);
- if (objPtr) {
- ExprPush(&e, objPtr);
- }
- else {
- retcode = JIM_ERR;
- }
- break;
-
- case JIM_TT_DICTSUGAR:
- objPtr = JimExpandDictSugar(interp, expr->token[i].objPtr);
- if (objPtr) {
- ExprPush(&e, objPtr);
- }
- else {
- retcode = JIM_ERR;
- }
- break;
-
- case JIM_TT_ESC:
- retcode = Jim_SubstObj(interp, expr->token[i].objPtr, &objPtr, JIM_NONE);
- if (retcode == JIM_OK) {
- ExprPush(&e, objPtr);
- }
- break;
-
- case JIM_TT_CMD:
- retcode = Jim_EvalObj(interp, expr->token[i].objPtr);
- if (retcode == JIM_OK) {
- ExprPush(&e, Jim_GetResult(interp));
- }
- break;
-
- default:{
- /* Find and execute the operation */
- e.skip = 0;
- e.opcode = expr->token[i].type;
-
- retcode = JimExprOperatorInfoByOpcode(e.opcode)->funcop(interp, &e);
- /* Skip some opcodes if necessary */
- i += e.skip;
- continue;
- }
- }
- }
+ /* Evaluate with the recursive expr engine */
+ retcode = JimExprEvalTermNode(interp, expr->expr);
expr->inUse--;
- if (retcode == JIM_OK) {
- *exprResultPtrPtr = ExprPop(&e);
- }
- else {
- for (i = 0; i < e.stacklen; i++) {
- Jim_DecrRefCount(interp, e.stack[i]);
- }
- }
- if (e.stack != staticStack) {
- Jim_Free(e.stack);
- }
return retcode;
}
int Jim_GetBoolFromExpr(Jim_Interp *interp, Jim_Obj *exprObjPtr, int *boolPtr)
{
- int retcode;
- jim_wide wideValue;
- double doubleValue;
- int booleanValue;
- Jim_Obj *exprResultPtr;
+ int retcode = Jim_EvalExpression(interp, exprObjPtr);
- retcode = Jim_EvalExpression(interp, exprObjPtr, &exprResultPtr);
- if (retcode != JIM_OK)
- return retcode;
+ if (retcode == JIM_OK) {
+ switch (ExprBool(interp, Jim_GetResult(interp))) {
+ case 0:
+ *boolPtr = 0;
+ break;
- if (JimGetWideNoErr(interp, exprResultPtr, &wideValue) != JIM_OK) {
- if (Jim_GetDouble(interp, exprResultPtr, &doubleValue) != JIM_OK) {
- if (Jim_GetBoolean(interp, exprResultPtr, &booleanValue) != JIM_OK) {
- Jim_DecrRefCount(interp, exprResultPtr);
- return JIM_ERR;
- } else {
- Jim_DecrRefCount(interp, exprResultPtr);
- *boolPtr = booleanValue;
- return JIM_OK;
- }
- }
- else {
- Jim_DecrRefCount(interp, exprResultPtr);
- *boolPtr = doubleValue != 0;
- return JIM_OK;
+ case 1:
+ *boolPtr = 1;
+ break;
+
+ case -1:
+ retcode = JIM_ERR;
+ break;
}
}
- *boolPtr = wideValue != 0;
-
- Jim_DecrRefCount(interp, exprResultPtr);
- return JIM_OK;
+ return retcode;
}
/* -----------------------------------------------------------------------------
@@ -9651,8 +9436,8 @@ int Jim_GetBoolFromExpr(Jim_Interp *interp, Jim_Obj *exprObjPtr, int *boolPtr)
typedef struct ScanFmtPartDescr
{
- char *arg; /* Specification of a CHARSET conversion */
- char *prefix; /* Prefix to be scanned literally before conversion */
+ const char *arg; /* Specification of a CHARSET conversion */
+ const char *prefix; /* Prefix to be scanned literally before conversion */
size_t width; /* Maximal width of input to be converted */
int pos; /* -1 - no assign, 0 - natural pos, >0 - XPG3 pos */
char type; /* Type of conversion (e.g. c, d, f) */
@@ -9736,8 +9521,8 @@ static int SetScanFmtFromAny(Jim_Interp *interp, Jim_Obj *objPtr)
ScanFmtStringObj *fmtObj;
char *buffer;
int maxCount, i, approxSize, lastPos = -1;
- const char *fmt = objPtr->bytes;
- int maxFmtLen = objPtr->length;
+ const char *fmt = Jim_String(objPtr);
+ int maxFmtLen = Jim_Length(objPtr);
const char *fmtEnd = fmt + maxFmtLen;
int curr;
@@ -9822,6 +9607,11 @@ static int SetScanFmtFromAny(Jim_Interp *interp, Jim_Obj *objPtr)
return JIM_ERR;
}
}
+ if (descr->pos < 0) {
+ fmtObj->error =
+ "\"%n$\" conversion specifier is negative";
+ return JIM_ERR;
+ }
/* Try to find a width after the XPG3 specifier */
if (sscanf(fmt, "%d%n", &width, &skip) == 1) {
descr->width = width;
@@ -9873,9 +9663,14 @@ static int SetScanFmtFromAny(Jim_Interp *interp, Jim_Obj *objPtr)
}
else {
/* Remember any valid modifier if given */
- if (strchr("hlL", *fmt) != 0)
+ if (fmt < fmtEnd && strchr("hlL", *fmt))
descr->modifier = tolower((int)*fmt++);
+ if (fmt >= fmtEnd) {
+ fmtObj->error = "missing scan conversion character";
+ return JIM_ERR;
+ }
+
descr->type = *fmt;
if (strchr("efgcsndoxui", *fmt) == 0) {
fmtObj->error = "bad scan conversion character";
@@ -10324,6 +10119,7 @@ static int JimInvokeCommand(Jim_Interp *interp, int objc, Jim_Obj *const *objv)
{
int retcode;
Jim_Cmd *cmdPtr;
+ void *prevPrivData;
#if 0
printf("invoke");
@@ -10353,6 +10149,7 @@ static int JimInvokeCommand(Jim_Interp *interp, int objc, Jim_Obj *const *objv)
goto out;
}
interp->evalDepth++;
+ prevPrivData = interp->cmdPrivData;
/* Call it -- Make sure result is an empty object. */
Jim_SetEmptyResult(interp);
@@ -10363,6 +10160,7 @@ static int JimInvokeCommand(Jim_Interp *interp, int objc, Jim_Obj *const *objv)
interp->cmdPrivData = cmdPtr->u.native.privData;
retcode = cmdPtr->u.native.cmdProc(interp, objc, objv);
}
+ interp->cmdPrivData = prevPrivData;
interp->evalDepth--;
out:
@@ -10450,6 +10248,7 @@ static void JimAddErrorToStack(Jim_Interp *interp, ScriptObj *script)
static int JimSubstOneToken(Jim_Interp *interp, const ScriptToken *token, Jim_Obj **objPtrPtr)
{
Jim_Obj *objPtr;
+ int ret = JIM_ERR;
switch (token->type) {
case JIM_TT_STR:
@@ -10463,22 +10262,21 @@ static int JimSubstOneToken(Jim_Interp *interp, const ScriptToken *token, Jim_Ob
objPtr = JimExpandDictSugar(interp, token->objPtr);
break;
case JIM_TT_EXPRSUGAR:
- objPtr = JimExpandExprSugar(interp, token->objPtr);
+ ret = Jim_EvalExpression(interp, token->objPtr);
+ if (ret == JIM_OK) {
+ objPtr = Jim_GetResult(interp);
+ }
+ else {
+ objPtr = NULL;
+ }
break;
case JIM_TT_CMD:
- switch (Jim_EvalObj(interp, token->objPtr)) {
- case JIM_OK:
- case JIM_RETURN:
- objPtr = interp->result;
- break;
- case JIM_BREAK:
- /* Stop substituting */
- return JIM_BREAK;
- case JIM_CONTINUE:
- /* just skip this one */
- return JIM_CONTINUE;
- default:
- return JIM_ERR;
+ ret = Jim_EvalObj(interp, token->objPtr);
+ if (ret == JIM_OK || ret == JIM_RETURN) {
+ objPtr = interp->result;
+ } else {
+ /* includes JIM_BREAK, JIM_CONTINUE */
+ objPtr = NULL;
}
break;
default:
@@ -10491,7 +10289,7 @@ static int JimSubstOneToken(Jim_Interp *interp, const ScriptToken *token, Jim_Ob
*objPtrPtr = objPtr;
return JIM_OK;
}
- return JIM_ERR;
+ return ret;
}
/* Interpolate the given tokens into a unique Jim_Obj returned by reference
@@ -10549,7 +10347,8 @@ static Jim_Obj *JimInterpolateTokens(Jim_Interp *interp, const ScriptToken * tok
/* Fast path return for a single token */
if (tokens == 1 && intv[0] && intv == sintv) {
- Jim_DecrRefCount(interp, intv[0]);
+ /* Reverse the Jim_IncrRefCount() above, but don't free the object */
+ intv[0]->refCount--;
return intv[0];
}
@@ -10738,7 +10537,13 @@ int Jim_EvalObj(Jim_Interp *interp, Jim_Obj *scriptObjPtr)
wordObjPtr = Jim_GetVariable(interp, token[i].objPtr, JIM_ERRMSG);
break;
case JIM_TT_EXPRSUGAR:
- wordObjPtr = JimExpandExprSugar(interp, token[i].objPtr);
+ retcode = Jim_EvalExpression(interp, token[i].objPtr);
+ if (retcode == JIM_OK) {
+ wordObjPtr = Jim_GetResult(interp);
+ }
+ else {
+ wordObjPtr = NULL;
+ }
break;
case JIM_TT_DICTSUGAR:
wordObjPtr = JimExpandDictSugar(interp, token[i].objPtr);
@@ -10922,7 +10727,6 @@ static void JimSetProcWrongArgs(Jim_Interp *interp, Jim_Obj *procNameObj, Jim_Cm
}
}
Jim_SetResultFormatted(interp, "wrong # args: should be \"%#s%#s\"", procNameObj, argmsg);
- Jim_FreeNewObj(interp, argmsg);
}
#ifdef jim_ext_namespace
@@ -11060,7 +10864,8 @@ static int JimCallProcedure(Jim_Interp *interp, Jim_Cmd *cmd, int argc, Jim_Obj
badargset:
- /* Free the callframe */
+ /* Invoke $jim::defer then destroy the callframe */
+ retcode = JimInvokeDefer(interp, retcode);
interp->framePtr = interp->framePtr->parent;
JimFreeCallFrame(interp, callFramePtr, JIM_FCF_REUSE);
@@ -11342,7 +11147,11 @@ static ScriptObj *Jim_GetSubst(Jim_Interp *interp, Jim_Obj *objPtr, int flags)
* resObjPtrPtr. */
int Jim_SubstObj(Jim_Interp *interp, Jim_Obj *substObjPtr, Jim_Obj **resObjPtrPtr, int flags)
{
- ScriptObj *script = Jim_GetSubst(interp, substObjPtr, flags);
+ ScriptObj *script;
+
+ JimPanic((substObjPtr->refCount == 0, "Jim_SubstObj() called with zero refcount object"));
+
+ script = Jim_GetSubst(interp, substObjPtr, flags);
Jim_IncrRefCount(substObjPtr); /* Make sure it's shared. */
/* In order to preserve the internal rep, we increment the
@@ -11371,16 +11180,14 @@ void Jim_WrongNumArgs(Jim_Interp *interp, int argc, Jim_Obj *const *argv, const
listObjPtr = Jim_NewListObj(interp, argv, argc);
- if (*msg) {
+ if (msg && *msg) {
Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, msg, -1));
}
Jim_IncrRefCount(listObjPtr);
objPtr = Jim_ListJoin(interp, listObjPtr, " ", 1);
Jim_DecrRefCount(interp, listObjPtr);
- Jim_IncrRefCount(objPtr);
Jim_SetResultFormatted(interp, "wrong # args: should be \"%#s\"", objPtr);
- Jim_DecrRefCount(interp, objPtr);
}
/**
@@ -11634,8 +11441,13 @@ static int JimSubDivHelper(Jim_Interp *interp, int argc, Jim_Obj *const *argv, i
}
if (op == JIM_EXPROP_SUB)
res -= wideValue;
- else
+ else {
+ if (wideValue == 0) {
+ Jim_SetResultString(interp, "Division by zero", -1);
+ return JIM_ERR;
+ }
res /= wideValue;
+ }
}
Jim_SetResultInt(interp, res);
return JIM_OK;
@@ -11805,7 +11617,7 @@ static int Jim_ForCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv
*/
if (retval == JIM_OK && boolean) {
ScriptObj *incrScript;
- ExprByteCode *expr;
+ struct ExprTree *expr;
jim_wide stop, currentVal;
Jim_Obj *objPtr;
int cmpOffset;
@@ -11819,47 +11631,53 @@ static int Jim_ForCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv
goto evalstart;
}
/* Ensure proper token types. */
- if (incrScript->token[1].type != JIM_TT_ESC ||
- expr->token[0].type != JIM_TT_VAR ||
- (expr->token[1].type != JIM_TT_EXPR_INT && expr->token[1].type != JIM_TT_VAR)) {
+ if (incrScript->token[1].type != JIM_TT_ESC) {
goto evalstart;
}
- if (expr->token[2].type == JIM_EXPROP_LT) {
+ if (expr->expr->type == JIM_EXPROP_LT) {
cmpOffset = 0;
}
- else if (expr->token[2].type == JIM_EXPROP_LTE) {
+ else if (expr->expr->type == JIM_EXPROP_LTE) {
cmpOffset = 1;
}
else {
goto evalstart;
}
+ if (expr->expr->left->type != JIM_TT_VAR) {
+ goto evalstart;
+ }
+
+ if (expr->expr->right->type != JIM_TT_VAR && expr->expr->right->type != JIM_TT_EXPR_INT) {
+ goto evalstart;
+ }
+
/* Update command must be incr */
if (!Jim_CompareStringImmediate(interp, incrScript->token[1].objPtr, "incr")) {
goto evalstart;
}
/* incr, expression must be about the same variable */
- if (!Jim_StringEqObj(incrScript->token[2].objPtr, expr->token[0].objPtr)) {
+ if (!Jim_StringEqObj(incrScript->token[2].objPtr, expr->expr->left->objPtr)) {
goto evalstart;
}
/* Get the stop condition (must be a variable or integer) */
- if (expr->token[1].type == JIM_TT_EXPR_INT) {
- if (Jim_GetWide(interp, expr->token[1].objPtr, &stop) == JIM_ERR) {
+ if (expr->expr->right->type == JIM_TT_EXPR_INT) {
+ if (Jim_GetWide(interp, expr->expr->right->objPtr, &stop) == JIM_ERR) {
goto evalstart;
}
}
else {
- stopVarNamePtr = expr->token[1].objPtr;
+ stopVarNamePtr = expr->expr->right->objPtr;
Jim_IncrRefCount(stopVarNamePtr);
/* Keep the compiler happy */
stop = 0;
}
/* Initialization */
- varNamePtr = expr->token[0].objPtr;
+ varNamePtr = expr->expr->left->objPtr;
Jim_IncrRefCount(varNamePtr);
objPtr = Jim_GetVariable(interp, varNamePtr, JIM_NONE);
@@ -12080,7 +11898,7 @@ static int JimForeachMapHelper(Jim_Interp *interp, int argc, Jim_Obj *const *arg
}
if (result != JIM_OK) {
Jim_SetResultString(interp, "foreach varlist is empty", -1);
- return result;
+ goto empty_varlist;
}
if (doMap) {
@@ -12143,6 +11961,7 @@ static int JimForeachMapHelper(Jim_Interp *interp, int argc, Jim_Obj *const *arg
Jim_SetResult(interp, resultObj);
err:
Jim_DecrRefCount(interp, resultObj);
+ empty_varlist:
if (numargs > 2) {
Jim_Free(iters);
}
@@ -12271,15 +12090,13 @@ int Jim_CommandMatchObj(Jim_Interp *interp, Jim_Obj *commandObj, Jim_Obj *patter
return eq;
}
-enum
-{ SWITCH_EXACT, SWITCH_GLOB, SWITCH_RE, SWITCH_CMD };
-
/* [switch] */
static int Jim_SwitchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
+ enum { SWITCH_EXACT, SWITCH_GLOB, SWITCH_RE, SWITCH_CMD };
int matchOpt = SWITCH_EXACT, opt = 1, patCount, i;
- Jim_Obj *command = 0, *const *caseList = 0, *strObj;
- Jim_Obj *script = 0;
+ Jim_Obj *command = NULL, *scriptObj = NULL, *strObj;
+ Jim_Obj **caseList;
if (argc < 3) {
wrongnumargs:
@@ -12320,16 +12137,13 @@ static int Jim_SwitchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a
strObj = argv[opt++];
patCount = argc - opt;
if (patCount == 1) {
- Jim_Obj **vector;
-
- JimListGetElements(interp, argv[opt], &patCount, &vector);
- caseList = vector;
+ JimListGetElements(interp, argv[opt], &patCount, &caseList);
}
else
- caseList = &argv[opt];
+ caseList = (Jim_Obj **)&argv[opt];
if (patCount == 0 || patCount % 2 != 0)
goto wrongnumargs;
- for (i = 0; script == 0 && i < patCount; i += 2) {
+ for (i = 0; scriptObj == NULL && i < patCount; i += 2) {
Jim_Obj *patObj = caseList[i];
if (!Jim_CompareStringImmediate(interp, patObj, "default")
@@ -12337,11 +12151,11 @@ static int Jim_SwitchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a
switch (matchOpt) {
case SWITCH_EXACT:
if (Jim_StringEqObj(strObj, patObj))
- script = caseList[i + 1];
+ scriptObj = caseList[i + 1];
break;
case SWITCH_GLOB:
if (Jim_StringMatchObj(interp, patObj, strObj, 0))
- script = caseList[i + 1];
+ scriptObj = caseList[i + 1];
break;
case SWITCH_RE:
command = Jim_NewStringObj(interp, "regexp", -1);
@@ -12353,34 +12167,31 @@ static int Jim_SwitchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a
* make sure to reconvert the object into a list
* again. Only for the single-list style [switch]. */
if (argc - opt == 1) {
- Jim_Obj **vector;
-
- JimListGetElements(interp, argv[opt], &patCount, &vector);
- caseList = vector;
+ JimListGetElements(interp, argv[opt], &patCount, &caseList);
}
/* command is here already decref'd */
if (rc < 0) {
return -rc;
}
if (rc)
- script = caseList[i + 1];
+ scriptObj = caseList[i + 1];
break;
}
}
}
else {
- script = caseList[i + 1];
+ scriptObj = caseList[i + 1];
}
}
- for (; i < patCount && Jim_CompareStringImmediate(interp, script, "-"); i += 2)
- script = caseList[i + 1];
- if (script && Jim_CompareStringImmediate(interp, script, "-")) {
+ for (; i < patCount && Jim_CompareStringImmediate(interp, scriptObj, "-"); i += 2)
+ scriptObj = caseList[i + 1];
+ if (scriptObj && Jim_CompareStringImmediate(interp, scriptObj, "-")) {
Jim_SetResultFormatted(interp, "no body specified for pattern \"%#s\"", caseList[i - 2]);
return JIM_ERR;
}
Jim_SetEmptyResult(interp);
- if (script) {
- return Jim_EvalObj(interp, script);
+ if (scriptObj) {
+ return Jim_EvalObj(interp, scriptObj);
}
return JIM_OK;
}
@@ -12684,18 +12495,11 @@ static int Jim_LreplaceCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const
* <elements before first> <supplied elements> <elements after last>
*/
- /* Check to see if trying to replace past the end of the list */
- if (first < len) {
- /* OK. Not past the end */
- }
- else if (len == 0) {
- /* Special for empty list, adjust first to 0 */
- first = 0;
- }
- else {
- Jim_SetResultString(interp, "list doesn't contain element ", -1);
- Jim_AppendObj(interp, Jim_GetResult(interp), argv[2]);
- return JIM_ERR;
+ /* Trying to replace past the end of the list means end of list
+ * See TIP #505
+ */
+ if (first > len) {
+ first = len;
}
/* Add the first set of elements */
@@ -12739,6 +12543,7 @@ static int Jim_LsortCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const arg
Jim_Obj *resObj;
int i;
int retCode;
+ int shared;
struct lsort_info info;
@@ -12804,12 +12609,14 @@ static int Jim_LsortCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const arg
break;
}
}
- resObj = Jim_DuplicateObj(interp, argv[argc - 1]);
+ resObj = argv[argc - 1];
+ if ((shared = Jim_IsShared(resObj)))
+ resObj = Jim_DuplicateObj(interp, resObj);
retCode = ListSortElements(interp, resObj, &info);
if (retCode == JIM_OK) {
Jim_SetResult(interp, resObj);
}
- else {
+ else if (shared) {
Jim_FreeNewObj(interp, resObj);
}
return retCode;
@@ -12856,6 +12663,33 @@ static int Jim_AppendCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a
return JIM_OK;
}
+#if defined(JIM_DEBUG_COMMAND) && !defined(JIM_BOOTSTRAP)
+/**
+ * Returns a zero-refcount list describing the expression at 'node'
+ */
+static Jim_Obj *JimGetExprAsList(Jim_Interp *interp, struct JimExprNode *node)
+{
+ Jim_Obj *listObjPtr = Jim_NewListObj(interp, NULL, 0);
+
+ Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, jim_tt_name(node->type), -1));
+ if (TOKEN_IS_EXPR_OP(node->type)) {
+ if (node->left) {
+ Jim_ListAppendElement(interp, listObjPtr, JimGetExprAsList(interp, node->left));
+ }
+ if (node->right) {
+ Jim_ListAppendElement(interp, listObjPtr, JimGetExprAsList(interp, node->right));
+ }
+ if (node->ternary) {
+ Jim_ListAppendElement(interp, listObjPtr, JimGetExprAsList(interp, node->ternary));
+ }
+ }
+ else {
+ Jim_ListAppendElement(interp, listObjPtr, node->objPtr);
+ }
+ return listObjPtr;
+}
+#endif /* JIM_DEBUG_COMMAND && !JIM_BOOTSTRAP */
+
/* [debug] */
static int Jim_DebugCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
@@ -12877,7 +12711,7 @@ static int Jim_DebugCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar
return JIM_ERR;
}
if (Jim_GetEnum(interp, argv[1], options, &option, "subcommand", JIM_ERRMSG) != JIM_OK)
- return JIM_ERR;
+ return Jim_CheckShowCommands(interp, argv[1], options);
if (option == OPT_REFCOUNT) {
if (argc != 3) {
Jim_WrongNumArgs(interp, 2, argv, "object");
@@ -12984,7 +12818,7 @@ static int Jim_DebugCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar
return JIM_OK;
}
else if (option == OPT_EXPRLEN) {
- ExprByteCode *expr;
+ struct ExprTree *expr;
if (argc != 3) {
Jim_WrongNumArgs(interp, 2, argv, "expression");
@@ -12997,9 +12831,7 @@ static int Jim_DebugCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar
return JIM_OK;
}
else if (option == OPT_EXPRBC) {
- Jim_Obj *objPtr;
- ExprByteCode *expr;
- int i;
+ struct ExprTree *expr;
if (argc != 3) {
Jim_WrongNumArgs(interp, 2, argv, "expression");
@@ -13008,55 +12840,7 @@ static int Jim_DebugCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar
expr = JimGetExpression(interp, argv[2]);
if (expr == NULL)
return JIM_ERR;
- objPtr = Jim_NewListObj(interp, NULL, 0);
- for (i = 0; i < expr->len; i++) {
- const char *type;
- const Jim_ExprOperator *op;
- Jim_Obj *obj = expr->token[i].objPtr;
-
- switch (expr->token[i].type) {
- case JIM_TT_EXPR_INT:
- type = "int";
- break;
- case JIM_TT_EXPR_DOUBLE:
- type = "double";
- break;
- case JIM_TT_EXPR_BOOLEAN:
- type = "boolean";
- break;
- case JIM_TT_CMD:
- type = "command";
- break;
- case JIM_TT_VAR:
- type = "variable";
- break;
- case JIM_TT_DICTSUGAR:
- type = "dictsugar";
- break;
- case JIM_TT_EXPRSUGAR:
- type = "exprsugar";
- break;
- case JIM_TT_ESC:
- type = "subst";
- break;
- case JIM_TT_STR:
- type = "string";
- break;
- default:
- op = JimExprOperatorInfoByOpcode(expr->token[i].type);
- if (op == NULL) {
- type = "private";
- }
- else {
- type = "operator";
- }
- obj = Jim_NewStringObj(interp, op ? op->name : "", -1);
- break;
- }
- Jim_ListAppendElement(interp, objPtr, Jim_NewStringObj(interp, type, -1));
- Jim_ListAppendElement(interp, objPtr, obj);
- }
- Jim_SetResult(interp, objPtr);
+ Jim_SetResult(interp, JimGetExprAsList(interp, expr->expr));
return JIM_OK;
}
else {
@@ -13144,18 +12928,17 @@ static int Jim_UplevelCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *
/* [expr] */
static int Jim_ExprCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
- Jim_Obj *exprResultPtr;
int retcode;
if (argc == 2) {
- retcode = Jim_EvalExpression(interp, argv[1], &exprResultPtr);
+ retcode = Jim_EvalExpression(interp, argv[1]);
}
else if (argc > 2) {
Jim_Obj *objPtr;
objPtr = Jim_ConcatObj(interp, argc - 1, argv + 1);
Jim_IncrRefCount(objPtr);
- retcode = Jim_EvalExpression(interp, objPtr, &exprResultPtr);
+ retcode = Jim_EvalExpression(interp, objPtr);
Jim_DecrRefCount(interp, objPtr);
}
else {
@@ -13164,8 +12947,6 @@ static int Jim_ExprCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg
}
if (retcode != JIM_OK)
return retcode;
- Jim_SetResult(interp, exprResultPtr);
- Jim_DecrRefCount(interp, exprResultPtr);
return JIM_OK;
}
@@ -13629,7 +13410,7 @@ static int Jim_StringCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a
}
if (Jim_GetEnum(interp, argv[1], options, &option, NULL,
JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK)
- return JIM_ERR;
+ return Jim_CheckShowCommands(interp, argv[1], options);
switch (option) {
case OPT_LENGTH:
@@ -14269,55 +14050,43 @@ static int Jim_RenameCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a
return Jim_RenameCommand(interp, Jim_String(argv[1]), Jim_String(argv[2]));
}
-#define JIM_DICTMATCH_VALUES 0x0001
-
-typedef void JimDictMatchCallbackType(Jim_Interp *interp, Jim_Obj *listObjPtr, Jim_HashEntry *he, int type);
-
-static void JimDictMatchKeys(Jim_Interp *interp, Jim_Obj *listObjPtr, Jim_HashEntry *he, int type)
-{
- Jim_ListAppendElement(interp, listObjPtr, (Jim_Obj *)he->key);
- if (type & JIM_DICTMATCH_VALUES) {
- Jim_ListAppendElement(interp, listObjPtr, Jim_GetHashEntryVal(he));
- }
-}
+#define JIM_DICTMATCH_KEYS 0x0001
+#define JIM_DICTMATCH_VALUES 0x002
/**
- * Like JimHashtablePatternMatch, but for dictionaries.
+ * match_type must be one of JIM_DICTMATCH_KEYS or JIM_DICTMATCH_VALUES
+ * return_types should be either or both
*/
-static Jim_Obj *JimDictPatternMatch(Jim_Interp *interp, Jim_HashTable *ht, Jim_Obj *patternObjPtr,
- JimDictMatchCallbackType *callback, int type)
+int Jim_DictMatchTypes(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *patternObj, int match_type, int return_types)
{
Jim_HashEntry *he;
- Jim_Obj *listObjPtr = Jim_NewListObj(interp, NULL, 0);
-
- /* Check for the non-pattern case. We can do this much more efficiently. */
+ Jim_Obj *listObjPtr;
Jim_HashTableIterator htiter;
- JimInitHashTableIterator(ht, &htiter);
- while ((he = Jim_NextHashEntry(&htiter)) != NULL) {
- if (patternObjPtr == NULL || JimGlobMatch(Jim_String(patternObjPtr), Jim_String((Jim_Obj *)he->key), 0)) {
- callback(interp, listObjPtr, he, type);
- }
- }
-
- return listObjPtr;
-}
-
-int Jim_DictKeys(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *patternObjPtr)
-{
if (SetDictFromAny(interp, objPtr) != JIM_OK) {
return JIM_ERR;
}
- Jim_SetResult(interp, JimDictPatternMatch(interp, objPtr->internalRep.ptr, patternObjPtr, JimDictMatchKeys, 0));
- return JIM_OK;
-}
-int Jim_DictValues(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *patternObjPtr)
-{
- if (SetDictFromAny(interp, objPtr) != JIM_OK) {
- return JIM_ERR;
+ listObjPtr = Jim_NewListObj(interp, NULL, 0);
+
+ JimInitHashTableIterator(objPtr->internalRep.ptr, &htiter);
+ while ((he = Jim_NextHashEntry(&htiter)) != NULL) {
+ if (patternObj) {
+ Jim_Obj *matchObj = (match_type == JIM_DICTMATCH_KEYS) ? (Jim_Obj *)he->key : Jim_GetHashEntryVal(he);
+ if (!JimGlobMatch(Jim_String(patternObj), Jim_String(matchObj), 0)) {
+ /* no match */
+ continue;
+ }
+ }
+ if (return_types & JIM_DICTMATCH_KEYS) {
+ Jim_ListAppendElement(interp, listObjPtr, (Jim_Obj *)he->key);
+ }
+ if (return_types & JIM_DICTMATCH_VALUES) {
+ Jim_ListAppendElement(interp, listObjPtr, Jim_GetHashEntryVal(he));
+ }
}
- Jim_SetResult(interp, JimDictPatternMatch(interp, objPtr->internalRep.ptr, patternObjPtr, JimDictMatchKeys, JIM_DICTMATCH_VALUES));
+
+ Jim_SetResult(interp, listObjPtr);
return JIM_OK;
}
@@ -14329,10 +14098,46 @@ int Jim_DictSize(Jim_Interp *interp, Jim_Obj *objPtr)
return ((Jim_HashTable *)objPtr->internalRep.ptr)->used;
}
+/**
+ * Must be called with at least one object.
+ * Returns the new dictionary, or NULL on error.
+ */
+Jim_Obj *Jim_DictMerge(Jim_Interp *interp, int objc, Jim_Obj *const *objv)
+{
+ Jim_Obj *objPtr = Jim_NewDictObj(interp, NULL, 0);
+ int i;
+
+ JimPanic((objc == 0, "Jim_DictMerge called with objc=0"));
+
+ /* Note that we don't optimise the trivial case of a single argument */
+
+ for (i = 0; i < objc; i++) {
+ Jim_HashTable *ht;
+ Jim_HashTableIterator htiter;
+ Jim_HashEntry *he;
+
+ if (SetDictFromAny(interp, objv[i]) != JIM_OK) {
+ Jim_FreeNewObj(interp, objPtr);
+ return NULL;
+ }
+ ht = objv[i]->internalRep.ptr;
+ JimInitHashTableIterator(ht, &htiter);
+ while ((he = Jim_NextHashEntry(&htiter)) != NULL) {
+ Jim_ReplaceHashEntry(objPtr->internalRep.ptr, Jim_GetHashEntryKey(he), Jim_GetHashEntryVal(he));
+ }
+ }
+ return objPtr;
+}
+
int Jim_DictInfo(Jim_Interp *interp, Jim_Obj *objPtr)
{
Jim_HashTable *ht;
unsigned int i;
+ char buffer[100];
+ int sum = 0;
+ int nonzero_count = 0;
+ Jim_Obj *output;
+ int bucket_counts[11] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
if (SetDictFromAny(interp, objPtr) != JIM_OK) {
return JIM_ERR;
@@ -14341,21 +14146,36 @@ int Jim_DictInfo(Jim_Interp *interp, Jim_Obj *objPtr)
ht = (Jim_HashTable *)objPtr->internalRep.ptr;
/* Note that this uses internal knowledge of the hash table */
- printf("%d entries in table, %d buckets\n", ht->used, ht->size);
+ snprintf(buffer, sizeof(buffer), "%d entries in table, %d buckets\n", ht->used, ht->size);
+ output = Jim_NewStringObj(interp, buffer, -1);
for (i = 0; i < ht->size; i++) {
Jim_HashEntry *he = ht->table[i];
-
- if (he) {
- printf("%d: ", i);
-
- while (he) {
- printf(" %s", Jim_String(he->key));
- he = he->next;
- }
- printf("\n");
+ int entries = 0;
+ while (he) {
+ entries++;
+ he = he->next;
+ }
+ if (entries > 9) {
+ bucket_counts[10]++;
+ }
+ else {
+ bucket_counts[entries]++;
+ }
+ if (entries) {
+ sum += entries;
+ nonzero_count++;
}
}
+ for (i = 0; i < 10; i++) {
+ snprintf(buffer, sizeof(buffer), "number of buckets with %d entries: %d\n", i, bucket_counts[i]);
+ Jim_AppendString(interp, output, buffer, -1);
+ }
+ snprintf(buffer, sizeof(buffer), "number of buckets with 10 or more entries: %d\n", bucket_counts[10]);
+ Jim_AppendString(interp, output, buffer, -1);
+ snprintf(buffer, sizeof(buffer), "average search distance for entry: %.1f", nonzero_count ? (double)sum / nonzero_count : 0.0);
+ Jim_AppendString(interp, output, buffer, -1);
+ Jim_SetResult(interp, output);
return JIM_OK;
}
@@ -14369,10 +14189,66 @@ static int Jim_EvalEnsemble(Jim_Interp *interp, const char *basecmd, const char
return Jim_EvalObjPrefix(interp, prefixObj, argc, argv);
}
+/**
+ * Implements the [dict with] command
+ */
+static int JimDictWith(Jim_Interp *interp, Jim_Obj *dictVarName, Jim_Obj *const *keyv, int keyc, Jim_Obj *scriptObj)
+{
+ int i;
+ Jim_Obj *objPtr;
+ Jim_Obj *dictObj;
+ Jim_Obj **dictValues;
+ int len;
+ int ret = JIM_OK;
+
+ /* Open up the appropriate level of the dictionary */
+ dictObj = Jim_GetVariable(interp, dictVarName, JIM_ERRMSG);
+ if (dictObj == NULL || Jim_DictKeysVector(interp, dictObj, keyv, keyc, &objPtr, JIM_ERRMSG) != JIM_OK) {
+ return JIM_ERR;
+ }
+ /* Set the local variables */
+ if (Jim_DictPairs(interp, objPtr, &dictValues, &len) == JIM_ERR) {
+ return JIM_ERR;
+ }
+ for (i = 0; i < len; i += 2) {
+ if (Jim_SetVariable(interp, dictValues[i], dictValues[i + 1]) == JIM_ERR) {
+ Jim_Free(dictValues);
+ return JIM_ERR;
+ }
+ }
+
+ /* As an optimisation, if the script is empty, no need to evaluate it or update the dict */
+ if (Jim_Length(scriptObj)) {
+ ret = Jim_EvalObj(interp, scriptObj);
+
+ /* Now if the dictionary still exists, update it based on the local variables */
+ if (ret == JIM_OK && Jim_GetVariable(interp, dictVarName, 0) != NULL) {
+ /* We need a copy of keyv with one extra element at the end for Jim_SetDictKeysVector() */
+ Jim_Obj **newkeyv = Jim_Alloc(sizeof(*newkeyv) * (keyc + 1));
+ for (i = 0; i < keyc; i++) {
+ newkeyv[i] = keyv[i];
+ }
+
+ for (i = 0; i < len; i += 2) {
+ /* This will be NULL if the variable no longer exists, thus deleting the variable */
+ objPtr = Jim_GetVariable(interp, dictValues[i], 0);
+ newkeyv[keyc] = dictValues[i];
+ Jim_SetDictKeysVector(interp, dictVarName, newkeyv, keyc + 1, objPtr, 0);
+ }
+ Jim_Free(newkeyv);
+ }
+ }
+
+ Jim_Free(dictValues);
+
+ return ret;
+}
+
/* [dict] */
static int Jim_DictCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
Jim_Obj *objPtr;
+ int types = JIM_DICTMATCH_KEYS;
int option;
static const char * const options[] = {
"create", "get", "set", "unset", "exists", "keys", "size", "info",
@@ -14392,7 +14268,7 @@ static int Jim_DictCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg
}
if (Jim_GetEnum(interp, argv[1], options, &option, "subcommand", JIM_ERRMSG) != JIM_OK) {
- return JIM_ERR;
+ return Jim_CheckShowCommands(interp, argv[1], options);
}
switch (option) {
@@ -14439,12 +14315,15 @@ static int Jim_DictCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg
}
return JIM_OK;
+ case OPT_VALUES:
+ types = JIM_DICTMATCH_VALUES;
+ /* fallthru */
case OPT_KEYS:
if (argc != 3 && argc != 4) {
Jim_WrongNumArgs(interp, 2, argv, "dictionary ?pattern?");
return JIM_ERR;
}
- return Jim_DictKeys(interp, argv[2], argc == 4 ? argv[3] : NULL);
+ return Jim_DictMatchTypes(interp, argv[2], argc == 4 ? argv[3] : NULL, types, types);
case OPT_SIZE:
if (argc != 3) {
@@ -14461,11 +14340,12 @@ static int Jim_DictCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg
if (argc == 2) {
return JIM_OK;
}
- if (Jim_DictSize(interp, argv[2]) < 0) {
+ objPtr = Jim_DictMerge(interp, argc - 2, argv + 2);
+ if (objPtr == NULL) {
return JIM_ERR;
}
- /* Handle as ensemble */
- break;
+ Jim_SetResult(interp, objPtr);
+ return JIM_OK;
case OPT_UPDATE:
if (argc < 6 || argc % 2) {
@@ -14489,6 +14369,13 @@ static int Jim_DictCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg
return JIM_ERR;
}
return Jim_DictInfo(interp, argv[2]);
+
+ case OPT_WITH:
+ if (argc < 4) {
+ Jim_WrongNumArgs(interp, 2, argv, "dictVar ?key ...? script");
+ return JIM_ERR;
+ }
+ return JimDictWith(interp, argv[2], argv + 3, argc - 4, argv[argc - 1]);
}
/* Handle command as an ensemble */
return Jim_EvalEnsemble(interp, "dict", options[option], argc - 2, argv + 2);
@@ -14571,9 +14458,8 @@ static int Jim_InfoCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg
Jim_WrongNumArgs(interp, 1, argv, "subcommand ?args ...?");
return JIM_ERR;
}
- if (Jim_GetEnum(interp, argv[1], commands, &cmd, "subcommand", JIM_ERRMSG | JIM_ENUM_ABBREV)
- != JIM_OK) {
- return JIM_ERR;
+ if (Jim_GetEnum(interp, argv[1], commands, &cmd, "subcommand", JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) {
+ return Jim_CheckShowCommands(interp, argv[1], commands);
}
/* Test for the most common commands first, just in case it makes a difference */
@@ -15448,36 +15334,87 @@ void Jim_MakeErrorMessage(Jim_Interp *interp)
Jim_EvalObjVector(interp, 2, argv);
}
-static void JimSetFailedEnumResult(Jim_Interp *interp, const char *arg, const char *badtype,
- const char *prefix, const char *const *tablePtr, const char *name)
+/*
+ * Given a null terminated array of strings, returns an allocated, sorted
+ * copy of the array.
+ */
+static char **JimSortStringTable(const char *const *tablePtr)
{
int count;
char **tablePtrSorted;
- int i;
+ /* Find the size of the table */
for (count = 0; tablePtr[count]; count++) {
}
+ /* Allocate one extra for the terminating NULL pointer */
+ tablePtrSorted = Jim_Alloc(sizeof(char *) * (count + 1));
+ memcpy(tablePtrSorted, tablePtr, sizeof(char *) * count);
+ qsort(tablePtrSorted, count, sizeof(char *), qsortCompareStringPointers);
+ tablePtrSorted[count] = NULL;
+
+ return tablePtrSorted;
+}
+
+static void JimSetFailedEnumResult(Jim_Interp *interp, const char *arg, const char *badtype,
+ const char *prefix, const char *const *tablePtr, const char *name)
+{
+ char **tablePtrSorted;
+ int i;
+
if (name == NULL) {
name = "option";
}
Jim_SetResultFormatted(interp, "%s%s \"%s\": must be ", badtype, name, arg);
- tablePtrSorted = Jim_Alloc(sizeof(char *) * count);
- memcpy(tablePtrSorted, tablePtr, sizeof(char *) * count);
- qsort(tablePtrSorted, count, sizeof(char *), qsortCompareStringPointers);
- for (i = 0; i < count; i++) {
- if (i + 1 == count && count > 1) {
+ tablePtrSorted = JimSortStringTable(tablePtr);
+ for (i = 0; tablePtrSorted[i]; i++) {
+ if (tablePtrSorted[i + 1] == NULL && i > 0) {
Jim_AppendString(interp, Jim_GetResult(interp), "or ", -1);
}
Jim_AppendStrings(interp, Jim_GetResult(interp), prefix, tablePtrSorted[i], NULL);
- if (i + 1 != count) {
+ if (tablePtrSorted[i + 1]) {
Jim_AppendString(interp, Jim_GetResult(interp), ", ", -1);
}
}
Jim_Free(tablePtrSorted);
}
+
+/*
+ * If objPtr is "-commands" sets the Jim result as a sorted list of options in the table
+ * and returns JIM_OK.
+ *
+ * Otherwise returns JIM_ERR.
+ */
+int Jim_CheckShowCommands(Jim_Interp *interp, Jim_Obj *objPtr, const char *const *tablePtr)
+{
+ if (Jim_CompareStringImmediate(interp, objPtr, "-commands")) {
+ int i;
+ char **tablePtrSorted = JimSortStringTable(tablePtr);
+ Jim_SetResult(interp, Jim_NewListObj(interp, NULL, 0));
+ for (i = 0; tablePtrSorted[i]; i++) {
+ Jim_ListAppendElement(interp, Jim_GetResult(interp), Jim_NewStringObj(interp, tablePtrSorted[i], -1));
+ }
+ Jim_Free(tablePtrSorted);
+ return JIM_OK;
+ }
+ return JIM_ERR;
+}
+
+/* internal rep is stored in ptrIntvalue
+ * ptr = tablePtr
+ * int1 = flags
+ * int2 = index
+ */
+static const Jim_ObjType getEnumObjType = {
+ "get-enum",
+ NULL,
+ NULL,
+ NULL,
+ JIM_TYPE_REFERENCES
+};
+
int Jim_GetEnum(Jim_Interp *interp, Jim_Obj *objPtr,
const char *const *tablePtr, int *indexPtr, const char *name, int flags)
{
@@ -15486,15 +15423,24 @@ int Jim_GetEnum(Jim_Interp *interp, Jim_Obj *objPtr,
int i;
int match = -1;
int arglen;
- const char *arg = Jim_GetString(objPtr, &arglen);
+ const char *arg;
+
+ if (objPtr->typePtr == &getEnumObjType) {
+ if (objPtr->internalRep.ptrIntValue.ptr == tablePtr && objPtr->internalRep.ptrIntValue.int1 == flags) {
+ *indexPtr = objPtr->internalRep.ptrIntValue.int2;
+ return JIM_OK;
+ }
+ }
+
+ arg = Jim_GetString(objPtr, &arglen);
*indexPtr = -1;
for (entryPtr = tablePtr, i = 0; *entryPtr != NULL; entryPtr++, i++) {
if (Jim_CompareStringImmediate(interp, objPtr, *entryPtr)) {
/* Found an exact match */
- *indexPtr = i;
- return JIM_OK;
+ match = i;
+ goto found;
}
if (flags & JIM_ENUM_ABBREV) {
/* Accept an unambiguous abbreviation.
@@ -15515,6 +15461,14 @@ int Jim_GetEnum(Jim_Interp *interp, Jim_Obj *objPtr,
/* If we had an unambiguous partial match */
if (match >= 0) {
+ found:
+ /* Record the match in the object */
+ Jim_FreeIntRep(interp, objPtr);
+ objPtr->typePtr = &getEnumObjType;
+ objPtr->internalRep.ptrIntValue.ptr = (void *)tablePtr;
+ objPtr->internalRep.ptrIntValue.int1 = flags;
+ objPtr->internalRep.ptrIntValue.int2 = match;
+ /* Return the result */
*indexPtr = match;
return JIM_OK;
}
@@ -15561,6 +15515,8 @@ int Jim_IsList(Jim_Obj *objPtr)
* e.g. Jim_SetResultFormatted(interp, "Bad option \"%#s\" in proc \"%#s\"", optionObjPtr, procNamePtr);
*
* Note: We take advantage of the fact that printf has the same behaviour for both %s and %#s
+ *
+ * Note that any Jim_Obj parameters with zero ref count will be freed as a result of this call.
*/
void Jim_SetResultFormatted(Jim_Interp *interp, const char *format, ...)
{
@@ -15569,6 +15525,8 @@ void Jim_SetResultFormatted(Jim_Interp *interp, const char *format, ...)
int extra = 0;
int n = 0;
const char *params[5];
+ int nobjparam = 0;
+ Jim_Obj *objparam[5];
char *buf;
va_list args;
int i;
@@ -15587,6 +15545,8 @@ void Jim_SetResultFormatted(Jim_Interp *interp, const char *format, ...)
Jim_Obj *objPtr = va_arg(args, Jim_Obj *);
params[n] = Jim_GetString(objPtr, &l);
+ objparam[nobjparam++] = objPtr;
+ Jim_IncrRefCount(objPtr);
}
else {
if (format[i] == '%') {
@@ -15605,6 +15565,10 @@ void Jim_SetResultFormatted(Jim_Interp *interp, const char *format, ...)
va_end(args);
Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, buf, len));
+
+ for (i = 0; i < nobjparam; i++) {
+ Jim_DecrRefCount(interp, objparam[i]);
+ }
}
/* stubs */
diff --git a/jim.h b/jim.h
index dd2b9ab..bbef251 100644
--- a/jim.h
+++ b/jim.h
@@ -293,6 +293,12 @@ typedef struct Jim_Obj {
void *ptr1;
void *ptr2;
} twoPtrValue;
+ /* Generic pointer, int, int value */
+ struct {
+ void *ptr;
+ int int1;
+ int int2;
+ } ptrIntValue;
/* Variable object */
struct {
struct Jim_Var *varPtr;
@@ -331,11 +337,6 @@ typedef struct Jim_Obj {
struct Jim_Obj *varNameObjPtr;
struct Jim_Obj *indexObjPtr;
} dictSubstValue;
- /* Regular expression pattern */
- struct {
- void *compre; /* really an allocated (regex_t *) */
- unsigned flags;
- } regexpValue;
struct {
int line;
int argc;
@@ -534,7 +535,7 @@ typedef struct Jim_Interp {
unsigned long referenceNextId; /* Next id for reference. */
struct Jim_HashTable references; /* References hash table. */
unsigned long lastCollectId; /* reference max Id of the last GC
- execution. It's set to -1 while the collection
+ execution. It's set to ~0 while the collection
is running as sentinel to avoid to recursive
calls via the [collect] command inside
finalizers. */
@@ -608,7 +609,7 @@ JIM_EXPORT char *Jim_StrDupLen(const char *s, int l);
/* environment */
JIM_EXPORT char **Jim_GetEnviron(void);
JIM_EXPORT void Jim_SetEnviron(char **env);
-JIM_EXPORT int Jim_MakeTempFile(Jim_Interp *interp, const char *template);
+JIM_EXPORT int Jim_MakeTempFile(Jim_Interp *interp, const char *filename_template, int unlink_file);
/* evaluation */
JIM_EXPORT int Jim_Eval(Jim_Interp *interp, const char *script);
@@ -655,7 +656,6 @@ JIM_EXPORT int Jim_DeleteHashEntry (Jim_HashTable *ht,
JIM_EXPORT int Jim_FreeHashTable (Jim_HashTable *ht);
JIM_EXPORT Jim_HashEntry * Jim_FindHashEntry (Jim_HashTable *ht,
const void *key);
-JIM_EXPORT void Jim_ResizeHashTable (Jim_HashTable *ht);
JIM_EXPORT Jim_HashTableIterator *Jim_GetHashTableIterator
(Jim_HashTable *ht);
JIM_EXPORT Jim_HashEntry * Jim_NextHashEntry
@@ -801,10 +801,14 @@ JIM_EXPORT int Jim_DictPairs(Jim_Interp *interp,
Jim_Obj *dictPtr, Jim_Obj ***objPtrPtr, int *len);
JIM_EXPORT int Jim_DictAddElement(Jim_Interp *interp, Jim_Obj *objPtr,
Jim_Obj *keyObjPtr, Jim_Obj *valueObjPtr);
-JIM_EXPORT int Jim_DictKeys(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *patternObj);
-JIM_EXPORT int Jim_DictValues(Jim_Interp *interp, Jim_Obj *dictObjPtr, Jim_Obj *patternObjPtr);
+
+#define JIM_DICTMATCH_KEYS 0x0001
+#define JIM_DICTMATCH_VALUES 0x002
+
+JIM_EXPORT int Jim_DictMatchTypes(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *patternObj, int match_type, int return_types);
JIM_EXPORT int Jim_DictSize(Jim_Interp *interp, Jim_Obj *objPtr);
JIM_EXPORT int Jim_DictInfo(Jim_Interp *interp, Jim_Obj *objPtr);
+JIM_EXPORT Jim_Obj *Jim_DictMerge(Jim_Interp *interp, int objc, Jim_Obj *const *objv);
/* return code object */
JIM_EXPORT int Jim_GetReturnCode (Jim_Interp *interp, Jim_Obj *objPtr,
@@ -812,7 +816,7 @@ JIM_EXPORT int Jim_GetReturnCode (Jim_Interp *interp, Jim_Obj *objPtr,
/* expression object */
JIM_EXPORT int Jim_EvalExpression (Jim_Interp *interp,
- Jim_Obj *exprObjPtr, Jim_Obj **exprResultPtrPtr);
+ Jim_Obj *exprObjPtr);
JIM_EXPORT int Jim_GetBoolFromExpr (Jim_Interp *interp,
Jim_Obj *exprObjPtr, int *boolPtr);
@@ -841,6 +845,8 @@ JIM_EXPORT void Jim_WrongNumArgs (Jim_Interp *interp, int argc,
Jim_Obj *const *argv, const char *msg);
JIM_EXPORT int Jim_GetEnum (Jim_Interp *interp, Jim_Obj *objPtr,
const char * const *tablePtr, int *indexPtr, const char *name, int flags);
+JIM_EXPORT int Jim_CheckShowCommands(Jim_Interp *interp, Jim_Obj *objPtr,
+ const char *const *tablePtr);
JIM_EXPORT int Jim_ScriptIsComplete(Jim_Interp *interp,
Jim_Obj *scriptObj, char *stateCharPtr);
@@ -874,7 +880,8 @@ JIM_EXPORT void Jim_MakeErrorMessage (Jim_Interp *interp);
JIM_EXPORT int Jim_InteractivePrompt (Jim_Interp *interp);
JIM_EXPORT void Jim_HistoryLoad(const char *filename);
JIM_EXPORT void Jim_HistorySave(const char *filename);
-JIM_EXPORT char *Jim_HistoryGetline(const char *prompt);
+JIM_EXPORT char *Jim_HistoryGetline(Jim_Interp *interp, const char *prompt);
+JIM_EXPORT void Jim_HistorySetCompletion(Jim_Interp *interp, Jim_Obj *commandObj);
JIM_EXPORT void Jim_HistoryAdd(const char *line);
JIM_EXPORT void Jim_HistoryShow(void);
diff --git a/jim_tcl.txt b/jim_tcl.txt
index 7d8cd64..c342ad1 100644
--- a/jim_tcl.txt
+++ b/jim_tcl.txt
@@ -3,7 +3,7 @@ Jim Tcl(n)
NAME
----
-Jim Tcl v0.77 - reference manual for the Jim Tcl scripting language
+Jim Tcl v0.79 - reference manual for the Jim Tcl scripting language
SYNOPSIS
--------
@@ -12,9 +12,10 @@ SYNOPSIS
or
- jimsh [<scriptfile>]
+ jimsh [<scriptfile>|-]
jimsh -e '<immediate-script>'
jimsh --version
+ jimsh --help
.Quick Index
@@ -38,7 +39,7 @@ Some notable differences with Tcl 8.5/8.6 are:
4. Support for references (`ref`/`getref`/`setref`) and garbage collection
5. Builtin dictionary type (`dict`) with some limitations compared to Tcl 8.6
6. `env` command to access environment variables
-7. Operating system features: `os.fork`, `os.wait`, `os.uptime`, `signal`, `alarm`, `sleep`
+7. Operating system features: `os.fork`, `os.uptime`, `wait`, `signal`, `alarm`, `sleep`
8. Much better error reporting. `info stacktrace` as a replacement for '$errorInfo', '$errorCode'
9. Support for "static" variables in procedures
10. Threads and coroutines are not supported
@@ -51,6 +52,32 @@ Some notable differences with Tcl 8.5/8.6 are:
RECENT CHANGES
--------------
+Changes between 0.78 and 0.79
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+1. Add `file mtimeus` for high resolution file timestamps
+2. `aio` now supports datagram Unix-Domain sockets
+3. Add support for `aio lock -wait`
+4. Add `signal block` to prevent delivery of signals
+5. Add support for `file split`
+6. Add support for `json::encode` and `json::decode`
+7. `aio tty` now allows setting +echo+ without full +raw+ mode
+
+Changes between 0.77 and 0.78
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+1. Add serial/tty support with `aio tty`
+2. Add support for 'jimsh -'
+3. Add hidden '-commands' option to many commands
+4. Add scriptable autocompletion support in interactive mode with `tcl::autocomplete`
+5. Add `aio sockopt`
+6. Add scriptable autocompletion support with `history completion`
+7. Add support for `tree delete`
+8. Add support for `defer` and '$jim::defer'
+9. Renamed `os.wait` to `wait`, now more Tcl-compatible and compatible with `exec ... &`
+10. `pipe` is now a synonym for `socket pipe`
+11. Closing a pipe open with `open |...` now returns Tcl-like status
+12. It is now possible to used `exec` redirection with a pipe opened with `open |...`
+13. Interactive line editing now supports multiline mode if $::history::multiline is set
+
Changes between 0.76 and 0.77
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1. Add support for `aio sync`
@@ -80,58 +107,6 @@ Changes between 0.74 and 0.75
9. `file stat` no longer requires the variable name
10. Add support for `file link`
-Changes between 0.73 and 0.74
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-1. Numbers with leading zeros are treated as decimal, not octal
-2. Add `aio isatty`
-3. Add LFS (64 bit) support for `aio seek`, `aio tell`, `aio copyto`, `file copy`
-4. `string compare` and `string equal` now support '-length'
-5. `glob` now supports '-directory'
-
-Changes between 0.72 and 0.73
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-1. Built-in regexp now support non-capturing parentheses: (?:...)
-2. Add `string replace`
-3. Add `string totitle`
-4. Add `info statics`
-5. Add +build-jim-ext+ for easy separate building of loadable modules (extensions)
-6. `local` now works with any command, not just procs
-7. Add `info alias` to access the target of an alias
-8. UTF-8 encoding past the basic multilingual plane (BMP) is supported
-9. Add `tcl::prefix`
-10. Add `history`
-11. Most extensions are now enabled by default
-12. Add support for namespaces and the `namespace` command
-13. Add `apply`
-
-Changes between 0.71 and 0.72
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-1. procs now allow 'args' and optional parameters in any position
-2. Add Tcl-compatible expr functions, `rand()`, `srand()` and `pow()`
-3. Add support for the '-force' option to `file delete`
-4. Better diagnostics when `source` fails to load a script with a missing quote or bracket
-5. New +tcl_platform(pathSeparator)+
-6. Add support settings the modification time with `file mtime`
-7. `exec` is now fully supported on win32 (mingw32)
-8. `file join`, `pwd`, `glob` etc. now work for mingw32
-9. Line editing is now supported for the win32 console (mingw32)
-10. Add `aio listen` command
-
-Changes between 0.70 and 0.71
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-1. Allow 'args' to be renamed in procs
-2. Add +$(...)+ shorthand syntax for expressions
-3. Add automatic reference variables in procs with +&var+ syntax
-4. Support +jimsh --version+
-5. Additional variables in +tcl_platform()+
-6. `local` procs now push existing commands and `upcall` can call them
-7. Add `loop` command (TclX compatible)
-8. Add `aio buffering` command
-9. `info complete` can now return the missing character
-10. `binary format` and `binary scan` are now (optionally) supported
-11. Add `string byterange`
-12. Built-in regexp now support non-greedy repetition (*?, +?, ??)
-
TCL INTRODUCTION
-----------------
Tcl stands for 'tool command language' and is pronounced
@@ -196,6 +171,10 @@ or to process the Tcl script in a file with:
jimsh filename
+or to process the Tcl script from standard input:
+
+ jimsh -
+
It may also be invoked to execute an immediate script with:
jimsh -e "script"
@@ -280,7 +259,9 @@ The first field must be the name of a command, and the
additional fields, if any, are arguments that will be passed to
that command. For example, the command:
+----
set a 22
+----
has three fields: the first, `set`, is the name of a Tcl command, and
the last two, 'a' and '22', will be passed as arguments to
@@ -333,7 +314,9 @@ for information on semi-colons); instead it ends at the next double-quote
character. The double-quotes are not included in the resulting argument.
For example, the command
+----
set a "This is a single argument"
+----
will pass two arguments to `set`: 'a' and 'This is a single argument'.
@@ -356,7 +339,9 @@ at the matching right brace. Tcl will strip off the outermost layer
of braces and pass the information between the braces to the command
without any further modification. For example, in the command
+----
set a {xyz a {b c d}}
+----
the `set` command will receive two arguments: 'a'
and 'xyz a {b c d}'.
@@ -368,10 +353,12 @@ characters up to the matching brace or quote. For example, the `eval`
command takes one argument, which is a command string; `eval` invokes
the Tcl interpreter to execute the command string. The command
+----
eval {
set a 22
set b 33
}
+----
will assign the value '22' to 'a' and '33' to 'b'.
@@ -388,37 +375,47 @@ text up to the matching close bracket is treated as a Tcl command and
executed immediately. Then the result of that command is substituted
for the bracketed text. For example, consider the command
+----
set a [set b]
+----
When the `set` command has only a single argument, it is the name of a
variable and `set` returns the contents of that variable. In this case,
if variable 'b' has the value 'foo', then the command above is equivalent
to the command
+----
set a foo
+----
Brackets can be used in more complex ways. For example, if the variable
'b' has the value 'foo' and the variable 'c' has the value 'gorp',
then the command
+----
set a xyz[set b].[set c]
+----
is equivalent to the command
+----
set a xyzfoo.gorp
-
+----
A bracketed command may contain multiple commands separated by newlines
or semi-colons in the usual fashion. In this case the value of the last
command is used for substitution. For example, the command
+----
set a x[set b 22
expr $b+2]x
+----
is equivalent to the command
+----
set a x24x
-
+----
If a field is enclosed in braces then the brackets and the characters
between them are not interpreted specially; they are passed through to
@@ -435,11 +432,15 @@ variable is substituted for the name.
For example, if variable 'foo' has the value 'test', then the command
+----
set a $foo.c
+----
is equivalent to the command
+----
set a test.c
+----
There are two special forms for variable substitution. If the next
character after the name of the variable is an open parenthesis, then
@@ -453,21 +454,29 @@ For example, if the variable 'x' is an array with one element named
'first' and value '87' and another element named '14' and value 'more',
then the command
+----
set a xyz$x(first)zyx
+----
is equivalent to the command
+----
set a xyz87zyx
+----
If the variable 'index' has the value '14', then the command
+----
set a xyz$x($index)zyx
+----
is equivalent to the command
+----
set a xyzmorezyx
+----
-For more information on arrays, see VARIABLES AND ARRAYS below.
+For more information on arrays, see <<_variables_scalars_and_arrays,VARIABLES - SCALARS AND ARRAYS>> below.
The second special form for variables occurs when the dollar sign is
followed by an open curly brace. In this case the variable name consists
@@ -477,11 +486,15 @@ Array references are not possible in this form: the name between braces
is assumed to refer to a scalar variable. For example, if variable
'foo' has the value 'test', then the command
+----
set a abc${foo}bar
+----
is equivalent to the command
+----
set a abctestbar
+----
Variable substitution does not occur in arguments that are enclosed in
@@ -575,7 +588,9 @@ sequence is replaced by the given character:
For example, in the command
+----
set a \{x\[\ yz\141
+----
the second argument to `set` will be +{x[ yza+.
@@ -585,7 +600,9 @@ field without any special processing, and the Tcl scanner continues
normal processing with the next character. For example, in the
command
+----
set \*a \\\{foo
+----
The first argument to `set` will be +{backslash}*a+ and the second
argument will be +{backslash}{foo+.
@@ -600,7 +617,9 @@ matching right brace that terminates the argument.
For example, in the
command
+----
set a {\{abc}
+----
the second argument to `set` will be +{backslash}{abc+.
@@ -679,7 +698,9 @@ Expressions almost always yield numeric results
(integer or floating-point values).
For example, the expression
+----
8.2 + 6
+----
evaluates to 14.2.
@@ -751,10 +772,12 @@ the value 3 and the variable 'b' has the value 6. Then the expression
on the left side of each of the lines below will evaluate to the value
on the right side of the line:
+----
$a + 3.1 6.1
2 + "$a.$b" 5.6
4*[llength "6 2"] 8
{word one} < "word $a" 0
+----
The valid operators are listed below, grouped in decreasing order
of precedence:
@@ -843,7 +866,9 @@ produced by each operator.
All of the binary operators group left-to-right within the same
precedence level. For example, the expression
+----
4*2 < 7
+----
evaluates to 0.
@@ -851,7 +876,9 @@ The +&&+, +||+, and +?:+ operators have 'lazy evaluation', just as
in C, which means that operands are not evaluated if they are not
needed to determine the outcome. For example, in
+----
$v ? [a] : [b]
+----
only one of +[a]+ or +[b]+ will actually be evaluated,
depending on the value of +$v+.
@@ -875,12 +902,16 @@ For arithmetic computations, integers are used until some
floating-point number is introduced, after which floating-point is used.
For example,
+----
5 / 4
+----
yields the result 1, while
+----
5 / 4.0
5 / ( [string length "abcd"] + 0.0 )
+----
both yield the result 1.25.
@@ -893,8 +924,10 @@ a string using the C 'sprintf' format specifier
'%d' for integers and '%g' for floating-point values.
For example, the expressions
+----
"0x03" > "2"
"0y" < "0x12"
+----
both evaluate to 1. The first comparison is done using integer
comparison, and the second is done using string comparison after
@@ -905,7 +938,9 @@ entering it in a command: otherwise, if the expression contains
any white space then the Tcl interpreter will split it
among several arguments. For example, the command
+----
expr $a + $b
+----
results in three arguments being passed to `expr`: +$a+,
\+, and +$b+. In addition, if the expression isn't in braces
@@ -919,7 +954,9 @@ the variable or command substitutions each time the expression is
evaluated, rather than once and for all at the beginning. For example,
the command
+----
for {set i 1} $i<=10 {incr i} {...} ** WRONG **
+----
is probably intended to iterate over all values of +i+ from 1 to 10.
After each iteration of the body of the loop, `for` will pass
@@ -932,7 +969,9 @@ which will always evaluate to 1, even though +i+ eventually
becomes greater than 10. In the above case the loop will never
terminate. Instead, the expression should be placed in braces:
+----
for {set i 1} {$i<=10} {incr i} {...} ** RIGHT **
+----
This causes the substitution of 'i'
to be delayed; it will be re-done each time the expression is
@@ -945,7 +984,9 @@ A list is just a string with a list-like structure
consisting of fields separated by white space. For example, the
string
+----
Al Sue Anne John
+----
is a list with four elements or fields.
Lists have the same basic structure as command strings, except
@@ -954,7 +995,9 @@ just like space or tab. Conventions for braces and quotes
and backslashes are the same for lists as for commands. For example,
the string
+----
a b\ c {d e {f g h}}
+----
is a list with three elements: +a+, +b c+, and +d e {f g h}+.
@@ -963,7 +1006,9 @@ braces and quotes and backslashes are applied as for commands. Thus in
the example above when the third element is extracted from the list,
the result is
+----
d e {f g h}
+----
(when the field was extracted, all that happened was to strip off
the outermost layer of braces). Command substitution and
@@ -986,14 +1031,18 @@ arguments. Support for this feature is also available in Jim.
Consider the following attempt to exec a list:
+----
set cmd {ls -l}
exec $cmd
+----
This will attempt to exec a command named "ls -l", which will clearly not
work. Typically eval and concat are required to solve this problem, however
it can be solved much more easily with +\{*\}+.
+----
exec {*}$cmd
+----
This will expand the following argument into individual elements and then evaluate
the resulting command.
@@ -1169,7 +1218,9 @@ order with the following precedence.
The following example illustrates precedence. Assume a procedure declaration:
+----
proc p {{a A} args b {c C} d} {...}
+----
This procedure requires at least two arguments, but can accept an unlimited number.
The following table shows how various numbers of arguments are assigned.
@@ -1199,18 +1250,20 @@ Either from the static variable definition, or from the enclosing scope.
Consider the following example:
- jim> set a 1
- jim> proc a {} {a {b 2}} {
+----
+ . set a 1
+ . proc a {} {a {b 2}} {
set c 1
puts "$a $b $c"
incr a
incr b
incr c
}
- jim> a
+ . a
1 2 1
- jim> a
+ . a
2 3 1
+----
The static variable +'a'+ has no initialiser, so it is initialised from
the enclosing scope with the value 1. (Note that it is an error if there
@@ -1221,7 +1274,7 @@ Unlike a local variable, the value of a static variable is retained across
invocations of the procedure.
See the `proc` command for information on how to define procedures
-and what happens when they are invoked. See also NAMESPACES.
+and what happens when they are invoked. See also <<_namespaces,NAMESPACES>>.
VARIABLES - SCALARS AND ARRAYS
------------------------------
@@ -1241,7 +1294,9 @@ Array indexes may be arbitrary strings; they need not be numeric.
Parentheses are used refer to array elements in Tcl commands.
For example, the command
+----
set x(first) 44
+----
will modify the element of 'x' whose index is 'first'
so that its new value is '44'.
@@ -1250,8 +1305,10 @@ Two-dimensional arrays can be simulated in Tcl by using indexes
that contain multiple concatenated values.
For example, the commands
+----
set a(2,3) 1
set a(3,6) 2
+----
set the elements of 'a' whose indexes are '2,3' and '3,6'.
@@ -1282,15 +1339,17 @@ that a name refer to a global variable for the duration of the current
procedure (this is somewhat analogous to 'extern' in C), or the variable
may be explicitly scoped with the +::+ prefix. For example
- set a 1
- set b 2
- proc p {} {
+----
+ . set a 1
+ . set b 2
+ . proc p {} {
set c 3
global a
puts "$a $::b $c"
}
- p
+ . p
+----
will output:
@@ -1304,12 +1363,16 @@ can convert between a string and a list.
For example:
+----
set a {1 one 2 two}
puts $a(2)
+----
will output:
+----
two
+----
Thus `array set` is equivalent to `set` when the variable does not
exist or is empty.
@@ -1317,12 +1380,16 @@ exist or is empty.
The reverse is also true where an array will be converted into
a list.
+----
set a(1) one; set a(2) two
puts $a
+----
will output:
+----
1 one 2 two
+----
DICTIONARY VALUES
-----------------
@@ -1361,16 +1428,18 @@ Note that in Jim, arrays are implemented as dictionaries.
Thus automatic conversion between lists and dictionaries applies
as it does for arrays.
- jim> dict set a 1 one
+----
+ . dict set a 1 one
1 one
- jim> dict set a 2 two
+ . dict set a 2 two
1 one 2 two
- jim> puts $a
+ . puts $a
1 one 2 two
- jim> puts $a(2)
+ . puts $a(2)
two
- jim> dict set a 3 T three
+ . dict set a 3 T three
1 one 2 two 3 {T three}
+----
See the `dict` command for more details.
@@ -1398,10 +1467,12 @@ A reference can be thought of as holding a value with one level of indirection,
where the value may be garbage collected when unreferenced.
Consider the following example:
- jim> set r [ref "One String" test]
+----
+ . set r [ref "One String" test]
<reference.<test___>.00000000000000000000>
- jim> getref $r
+ . getref $r
One String
+----
The operation `ref` creates a references to the value specified by the
first argument. (The second argument is a "type" used for documentation purposes).
@@ -1409,10 +1480,12 @@ first argument. (The second argument is a "type" used for documentation purposes
The operation `getref` is the dereferencing operation which retrieves the value
stored in the reference.
- jim> setref $r "New String"
+----
+ . setref $r "New String"
New String
- jim> getref $r
+ . getref $r
New String
+----
The operation `setref` replaces the value stored by the reference. If the old value
is no longer accessible by any reference, it will eventually be automatically be garbage
@@ -1430,15 +1503,17 @@ and discard objects which are no longer accessible by any reference.
The `collect` command may be used to force garbage collection. Consider a reference created
with a finalizer:
- jim> proc f {ref value} { puts "Finaliser called for $ref,$value" }
- jim> set r [ref "One String" test f]
+----
+ . proc f {ref value} { puts "Finaliser called for $ref,$value" }
+ . set r [ref "One String" test f]
<reference.<test___>.00000000000
- jim> collect
+ . collect
0
- jim> set r ""
- jim> collect
+ . set r ""
+ . collect
Finaliser called for <reference.<test___>.00000000000,One String
1
+----
Note that once the reference, 'r', was modified so that it no longer
contained a reference to the value, the garbage collector discarded
@@ -1446,22 +1521,26 @@ the value (after calling the finalizer).
The finalizer for a reference may be examined or changed with the `finalize` command
- jim> finalize $r
+----
+ . finalize $r
f
- jim> finalize $r newf
+ . finalize $r newf
newf
+----
Lambda Function
~~~~~~~~~~~~~~~
Jim provides a garbage collected `lambda` function. This is a procedure
which is able to create an anonymous procedure. Consider:
- jim> set f [lambda {a} {{x 0}} { incr x $a }]
- jim> $f 1
+----
+ . set f [lambda {a} {{x 0}} { incr x $a }]
+ . $f 1
1
- jim> $f 2
+ . $f 2
3
- jim> set f ""
+ . set f ""
+----
This create an anonymous procedure (with the name stored in 'f'), with a static variable
which is incremented by the supplied value and the result returned.
@@ -1471,7 +1550,9 @@ when the garbage collector runs.
The procedure may also be delete immediately by renaming it "". e.g.
- jim> rename $f ""
+----
+ . rename $f ""
+----
UTF-8 AND UNICODE
-----------------
@@ -1498,24 +1579,32 @@ String Matching
Commands such as `string match`, `lsearch -glob`, `array names` and others use string
pattern matching rules. These commands support UTF-8. For example:
+----
string match a\[\ua0-\ubf\]b "a\u00a3b"
+----
format and scan
~~~~~~~~~~~~~~~
+format %c+ allows a unicode codepoint to be be encoded. For example, the following will return
a string with two bytes and one character. The same as +{backslash}ub5+
+----
format %c 0xb5
+----
`format` respects widths as character widths, not byte widths. For example, the following will
return a string with three characters, not three bytes.
+----
format %.3s \ub5\ub6\ub7\ub8
+----
Similarly, +scan ... %c+ allows a UTF-8 to be decoded to a unicode codepoint. The following will set
+'a'+ to 181 (0xb5) and +'b'+ to 65 (0x41).
+----
scan \u00b5A %c%c a b
+----
`scan %s` will also accept a character class, including unicode ranges.
@@ -1524,7 +1613,9 @@ String Classes
`string is` has *not* been extended to classify UTF-8 characters. Therefore, the following
will return 0, even though the string may be considered to be alphabetic.
+----
string is alpha \ub5Test
+----
This does not affect the string classes 'ascii', 'control', 'digit', 'double', 'integer' or 'xdigit'.
@@ -1550,14 +1641,16 @@ and those which end prematurely, such as a lone '0xc2'.
In these situations, the offending bytes are treated as single characters. For example,
the following returns 2.
+----
string bytelength \xff\xff
+----
Regular Expressions
~~~~~~~~~~~~~~~~~~~
If UTF-8 support is enabled, the built-in regular expression engine will be
selected which supports UTF-8 strings and patterns.
-See REGULAR EXPRESSIONS
+See <<_regular_expressions,REGULAR EXPRESSIONS>>
BUILT-IN COMMANDS
-----------------
@@ -1603,10 +1696,12 @@ alias
Creates a single word alias (command) for one or more words. For example,
the following creates an alias for the command `info exists`.
+----
alias e info exists
if {[e var]} {
...
}
+----
`alias` returns +'name'+, allowing it to be used with `local`.
@@ -1652,8 +1747,7 @@ command. The legal +'options'+ (which may be abbreviated) are:
+*array exists* 'arrayName'+::
Returns 1 if arrayName is an array variable, 0 if there is
- no variable by that name. This command is essentially
- identical to `info exists`
+ no variable by that name.
+*array get* 'arrayName ?pattern?'+::
Returns a list containing pairs of elements. The first
@@ -1710,68 +1804,8 @@ to signal the innermost containing loop command to return immediately.
case
~~~~
-+*case* 'string' ?in? 'patList body ?patList body ...?'+
-
-+*case* 'string' ?in? {'patList body ?patList body ...?'}+
-
-*Note* that the `switch` command should generally be preferred unless compatibility
-with Tcl 6.x is desired.
-
-Match +'string'+ against each of the +'patList'+ arguments
-in order. If one matches, then evaluate the following +'body'+ argument
-by passing it recursively to the Tcl interpreter, and return the result
-of that evaluation. Each +'patList'+ argument consists of a single
-pattern or list of patterns. Each pattern may contain any of the wild-cards
-described under `string match`.
-
-If a +'patList'+ argument is +default+, the corresponding body will be
-evaluated if no +'patList'+ matches +'string'+. If no +'patList'+ argument
-matches +'string'+ and no default is given, then the `case` command returns
-an empty string.
-
-Two syntaxes are provided.
-
-The first uses a separate argument for each of the patterns and commands;
-this form is convenient if substitutions are desired on some of the
-patterns or commands.
-
-The second form places all of the patterns and commands together into
-a single argument; the argument must have proper list structure, with
-the elements of the list being the patterns and commands.
-
-The second form makes it easy to construct multi-line case commands,
-since the braces around the whole list make it unnecessary to include a
-backslash at the end of each line.
-
-Since the +'patList'+ arguments are in braces in the second form,
-no command or variable substitutions are performed on them; this makes
-the behaviour of the second form different than the first form in some
-cases.
-
-Below are some examples of `case` commands:
-
- case abc in {a b} {format 1} default {format 2} a* {format 3}
-
-will return '3',
-
- case a in {
- {a b} {format 1}
- default {format 2}
- a* {format 3}
- }
-
-will return '1', and
-
- case xyz {
- {a b}
- {format 1}
- default
- {format 2}
- a*
- {format 3}
- }
-
-will return '2'.
+The obsolete '+*case*+' command has been removed from Jim Tcl since v0.75.
+Use `switch` instead.
catch
~~~~~
@@ -1806,11 +1840,13 @@ same value as the global variable $::errorCode, and the value of
the key +-level+ will be the current return level (see `return -level`).
This can be useful to rethrow an error:
+----
if {[catch {...} msg opts]} {
...maybe do something with the error...
incr opts(-level)
return {*}$opts $msg
}
+----
Normally `catch` will +'not'+ catch any of the codes +JIM_EXIT+, +JIM_EVAL+ or +JIM_SIGNAL+.
The set of codes which will be caught may be modified by specifying the one more codes before
@@ -1818,7 +1854,9 @@ The set of codes which will be caught may be modified by specifying the one more
e.g. To catch +JIM_EXIT+ but not +JIM_BREAK+ or +JIM_CONTINUE+
+----
catch -exit -nobreak -nocontinue -- { ... }
+----
The use of +--+ is optional. It signifies that no more return code options follow.
@@ -1842,7 +1880,7 @@ clock
Returns the current time as seconds since the epoch.
+*clock clicks*+::
- Returns the current time in `clicks'.
+ Returns the current time in "clicks", a system-dependent, high-resolution time.
+*clock microseconds*+::
Returns the current time in microseconds.
@@ -1850,14 +1888,18 @@ clock
+*clock milliseconds*+::
Returns the current time in milliseconds.
-+*clock format* 'seconds' ?*-format* 'format?'+::
++*clock format* 'seconds' ?*-format* 'format?' ?*-gmt* 'boolean?'+::
Format the given time (seconds since the epoch) according to the given
format. See strftime(3) for supported formats.
If no format is supplied, "%c" is used.
+ ::
+ If +'boolean'+ is true, processing is performed in UTC.
+ If +'boolean'+ is false (the default), processing is performeed in the local time zone.
-+*clock scan* 'str' *-format* 'format'+::
++*clock scan* 'str' *-format* 'format' ?*-gmt* 'boolean?'+::
Scan the given time string using the given format string.
See strptime(3) for supported formats.
+ See `clock format` for the handling of '-gmt'.
close
~~~~~
@@ -1877,7 +1919,7 @@ collect
Normally reference garbage collection is automatically performed periodically.
However it may be run immediately with the `collect` command.
-See GARBAGE COLLECTION, REFERENCES, LAMBDA FUNCTION for more detail.
+See <<_garbage_collection_references_lambda_function,GARBAGE COLLECTION>> for more detail.
concat
~~~~~~
@@ -1887,11 +1929,15 @@ This command treats each argument as a list and concatenates them
into a single list. It permits any number of arguments. For example,
the command
+----
concat a b {c d e} {f {g h}}
+----
will return
+----
a b c d e f {g h}
+----
as its result.
@@ -1913,10 +1959,12 @@ a named procedure.
the following creates a local, unnamed alias for the command `info exists`.
+----
set e [local curry info exists]
if {[$e var]} {
...
}
+----
`curry` returns the name of the procedure.
@@ -2052,9 +2100,11 @@ if a caught error cannot be handled successfully, +'stacktrace'+ can be used
to return a stack trace reflecting the original point of occurrence
of the error:
+----
catch {...} errMsg
...
error $errMsg [info stacktrace]
+----
See also `errorInfo`, `info stacktrace`, `catch` and `return`
@@ -2065,10 +2115,12 @@ errorInfo
Returns a human-readable representation of the given error message and stack trace.
Typical usage is:
+----
if {[catch {...} error]} {
puts stderr [errorInfo $error [info stacktrace]]
exit 1
}
+----
See also `error`.
@@ -2255,13 +2307,15 @@ expr
+*expr* 'arg'+
Calls the expression processor to evaluate +'arg'+, and returns
-the result as a string. See the section EXPRESSIONS above.
+the result as a string. See the section <<_expressions,EXPRESSIONS>> above.
Note that Jim supports a shorthand syntax for `expr` as +$(\...)+
The following two are identical.
+----
set x [expr {3 * 2 + 1}]
set x $(3 * 2 + 1)
+----
file
~~~~
@@ -2353,6 +2407,12 @@ abbreviation for +'option'+ is acceptable. The valid options are:
error is generated. If +'time'+ is given, sets the modification time
of the file to the given value.
++*file mtimeus* 'name ?time_us?'+::
+ As for `file mtime` except the time value is in microseconds
+ since the epoch (see also `clock microseconds`).
+ Note that some platforms and some filesystems don't support high
+ resolution timestamps for files.
+
+*file normalize* 'name'+::
Return the normalized path of +'name'+. See 'realpath(3)'.
@@ -2381,16 +2441,17 @@ abbreviation for +'option'+ is acceptable. The valid options are:
the last '.' character in the name. If +'name'+ doesn't contain
a dot, then return +'name'+.
-+*file size* 'name'+::
- Return a decimal string giving the size of file +'name'+ in bytes.
- If the file doesn't exist or its size cannot be queried then an
- error is generated.
++*file split* 'name'+::
+ Returns a list whose elements are the path components in +'name'+.
+ The first element of the list will have the same path type as
+ +'name'+. All other elements will be relative. Path separators
+ will be discarded.
+*file stat* 'name ?varName?'+::
Invoke the 'stat' kernel call on +'name'+, and return the result
as a dictionary with the following keys: 'atime',
'ctime', 'dev', 'gid', 'ino', 'mode', 'mtime',
- 'nlink', 'size', 'type', 'uid'.
+ 'nlink', 'size', 'type', 'uid', 'mtimeus' (if supported - see `file mtimeus`)
Each element except 'type' is a decimal string with the value of
the corresponding field from the 'stat' return structure; see the
manual entry for 'stat' for details on the meanings of the values.
@@ -2420,11 +2481,13 @@ abbreviation for +'option'+ is acceptable. The valid options are:
The `file` commands that return 0/1 results are often used in
conditional or looping commands, for example:
+----
if {![file exists foo]} {
error {bad file name}
} else {
...
}
+----
finalize
~~~~~~~~
@@ -2438,7 +2501,7 @@ the empty string to remove the current finalizer.
The reference must be a valid reference create with the `ref`
command.
-See GARBAGE COLLECTION, REFERENCES, LAMBDA FUNCTION for more detail.
+See <<_garbage_collection_references_lambda_function,GARBAGE COLLECTION>> for more detail.
flush
~~~~~
@@ -2544,7 +2607,7 @@ getref
Returns the string associated with +'reference'+. The reference must
be a valid reference create with the `ref` command.
-See GARBAGE COLLECTION, REFERENCES, LAMBDA FUNCTION for more detail.
+See <<_garbage_collection_references_lambda_function,GARBAGE COLLECTION>> for more detail.
gets
~~~~
@@ -2840,7 +2903,7 @@ The `lambda` command is identical to `proc`, except rather than
creating a named procedure, it creates an anonymous procedure and returns
the name of the procedure.
-See `proc` and GARBAGE COLLECTION, REFERENCES, LAMBDA FUNCTION for more detail.
+See `proc` and <<_garbage_collection_references_lambda_function,GARBAGE COLLECTION>> for more detail.
lappend
~~~~~~~
@@ -2857,11 +2920,15 @@ each +'value'+ is appended as a list element rather than raw text.
This command provides a relatively efficient way to build up large lists.
For example,
+----
lappend a $b
+----
is much more efficient than
+----
set a [concat $a [list $b]]
+----
when +$a+ is long.
@@ -2874,9 +2941,11 @@ the variables given by the +'varName'+ arguments in order. If there are more var
list elements, the remaining variables are set to the empty string. If there are more list elements
than variables, a list of unassigned elements is returned.
- jim> lassign {1 2 3} a b; puts a=$a,b=$b
+----
+ . lassign {1 2 3} a b; puts a=$a,b=$b
3
a=1,b=2
+----
local
~~~~~
@@ -2896,6 +2965,7 @@ procedure exits. See `upcall` for more details.
In this example, a local procedure is created. Note that the procedure
continues to have global scope while it is active.
+----
proc outer {} {
# proc ... returns "inner" which is marked local
local proc inner {} {
@@ -2905,10 +2975,12 @@ continues to have global scope while it is active.
inner
...
}
+----
In this example, the lambda is deleted at the end of the procedure rather
than waiting until garbage collection.
+----
proc outer {} {
set x [lambda inner {args} {
# will be deleted when 'outer' exits
@@ -2919,6 +2991,7 @@ than waiting until garbage collection.
$x ...
...
}
+----
loop
~~~~
@@ -2927,7 +3000,9 @@ loop
Similar to `for` except simpler and possibly more efficient.
With a positive increment, equivalent to:
- for {set var $first} {$var < $limit} {incr var $incr} $body
+----
+ for {set var $first} {$var < $limit} {incr var $incr} $body
+----
If +'incr'+ is not specified, 1 is used.
Note that setting the loop variable inside the loop does not
@@ -2939,7 +3014,7 @@ lindex
Treats +'list'+ as a Tcl list and returns element +'index'+ from it
(0 refers to the first element of the list).
-See STRING AND LIST INDEX SPECIFICATIONS for all allowed forms for +'index'+.
+See <<_string_and_list_index_specifications,STRING AND LIST INDEX SPECIFICATIONS>> for all allowed forms for +'index'+.
In extracting the element, +'lindex'+ observes the same rules concerning
braces and quotes and backslashes as the Tcl command interpreter; however,
@@ -2967,7 +3042,7 @@ beginning of the list. If +'index'+ is greater than or equal
to the number of elements in the list, then the new elements are
appended to the list.
-See STRING AND LIST INDEX SPECIFICATIONS for all allowed forms for +'index'+.
+See <<_string_and_list_index_specifications,STRING AND LIST INDEX SPECIFICATIONS>> for all allowed forms for +'index'+.
list
~~~~
@@ -2984,15 +3059,21 @@ its arguments. `list` produces slightly different results than
the list, while `list` works directly from the original arguments.
For example, the command
+----
list a b {c d e} {f {g h}}
+----
will return
+----
a b {c d e} {f {g h}}
+----
while `concat` with the same arguments will return
+----
a b c d e f {g h}
+----
llength
~~~~~~~
@@ -3013,7 +3094,9 @@ zero or more indices into the list. Finally, it accepts a new value
for an element of varName. If no indices are presented, the command
takes the form:
+----
lset varName newValue
+----
In this case, newValue replaces the old value of the variable
varName.
@@ -3032,14 +3115,16 @@ the `lset` command.
If index is negative or greater than or equal to the number of
elements in $varName, then an error occurs.
-See STRING AND LIST INDEX SPECIFICATIONS for all allowed forms for +'index'+.
+See <<_string_and_list_index_specifications,STRING AND LIST INDEX SPECIFICATIONS>> for all allowed forms for +'index'+.
If additional index arguments are supplied, then each argument is
used in turn to address an element within a sublist designated by
the previous indexing operation, allowing the script to alter
elements in sublists. The command,
+----
lset a 1 2 newValue
+----
replaces element 2 of sublist 1 with +'newValue'+.
@@ -3060,10 +3145,12 @@ lmap
For example:
- jim> lmap i {1 2 3 4 5} {expr $i*$i}
+----
+ . lmap i {1 2 3 4 5} {expr $i*$i}
1 4 9 16 25
- jim> lmap a {1 2 3} b {A B C} {list $a $b}
+ . lmap a {1 2 3} b {A B C} {list $a $b}
{1 A} {2 B} {3 C}
+----
If the body invokes `continue`, no value is added for this iteration.
If the body invokes `break`, the loop ends and no more values are added.
@@ -3085,7 +3172,7 @@ lrange
+'list'+ must be a valid Tcl list. This command will return a new
list consisting of elements +'first'+ through +'last'+, inclusive.
-See STRING AND LIST INDEX SPECIFICATIONS for all allowed forms for +'first'+ and +'last'+.
+See <<_string_and_list_index_specifications,STRING AND LIST INDEX SPECIFICATIONS>> for all allowed forms for +'first'+ and +'last'+.
If +'last'+ is greater than or equal to the number of elements
in the list, then it is treated as if it were +end+.
@@ -3116,7 +3203,7 @@ must exist in the list.
+'last'+ gives the index in +'list'+ of the last element
to be replaced; it must be greater than or equal to +'first'+.
-See STRING AND LIST INDEX SPECIFICATIONS for all allowed forms for +'first'+ and +'last'+.
+See <<_string_and_list_index_specifications,STRING AND LIST INDEX SPECIFICATIONS>> for all allowed forms for +'first'+ and +'last'+.
The +'element'+ arguments specify zero or more new arguments to
be added to the list in place of those that were deleted.
@@ -3134,8 +3221,10 @@ lrepeat
Build a list by repeating elements +'number'+ times (which must be
a positive integer).
- jim> lrepeat 3 a b
+----
+ . lrepeat 3 a b
a b a b a b
+----
lreverse
~~~~~~~~
@@ -3143,8 +3232,10 @@ lreverse
Returns the list in reverse order.
- jim> lreverse {1 2 3}
+----
+ . lreverse {1 2 3}
3 2 1
+----
lsearch
~~~~~~~
@@ -3230,6 +3321,23 @@ If +-index 'listindex'+ is specified, each element of the list is treated as a l
the given index is extracted from the list for comparison. The list index may
be any valid list index, such as +1+, +end+ or +end-2+.
+defer
+~~~~~
++*defer* 'script'+
+
+This command is a simple helper command to add a script to the '+$jim::defer+' variable
+that will run when the current proc or interpreter exits. For example:
+
+----
+ . proc a {} { defer {puts "Leaving a"}; puts "Exit" }
+ . a
+ Exit
+ Leaving a
+----
+
+If the '+$jim::defer+' variable exists, it is treated as a list of scripts to run
+when the proc or interpreter exits.
+
open
~~~~
+*open* 'fileName ?access?'+
@@ -3340,7 +3448,7 @@ Tcl interpreter. +'args'+ specifies the formal arguments to the procedure.
If specified, +'statics'+, declares static variables which are bound to the
procedure.
-See PROCEDURES for detailed information about Tcl procedures.
+See <<_procedures,PROCEDURES> for detailed information about Tcl procedures.
The `proc` command returns +'name'+ (which is useful with `local`).
@@ -3373,6 +3481,20 @@ switch.
Output to files is buffered internally by Tcl; the `flush`
command may be used to force buffered characters to be output.
+pipe
+~~~~
+Creates a pair of `aio` channels and returns the handles as a list: +{read write}+
+
+----
+ lassign [pipe] r w
+
+ # Must close $w after exec
+ exec ps >@$w &
+ $w close
+
+ $r readable ...
+----
+
pwd
~~~
+*pwd*+
@@ -3395,14 +3517,16 @@ range
Returns a list of integers starting at +'start'+ (defaults to 0)
and ranging up to but not including +'end'+ in steps of +'step'+ defaults to 1).
- jim> range 5
+----
+ . range 5
0 1 2 3 4
- jim> range 2 5
+ . range 2 5
2 3 4
- jim> range 2 10 4
+ . range 2 10 4
2 6
- jim> range 7 4 -2
+ . range 7 4 -2
7 5
+----
read
~~~~
@@ -3414,7 +3538,6 @@ read
+'fileId' *read* 'numBytes'+
-
In the first form, all of the remaining bytes are read from the file
given by +'fileId'+; they are returned as the result of the command.
If the +-nonewline+ switch is specified then the last
@@ -3435,7 +3558,7 @@ regexp
Determines whether the regular expression +'exp'+ matches part or
all of +'string'+ and returns 1 if it does, 0 if it doesn't.
-See REGULAR EXPRESSIONS above for complete information on the
+See <<_regular_expressions,REGULAR EXPRESSIONS>> above for complete information on the
syntax of +'exp'+ and how it is matched against +'string'+.
If additional arguments are specified after +'string'+ then they
@@ -3586,9 +3709,11 @@ no longer accessible.
The finalizer is invoked as:
- finalizer reference string
+----
+ finalizer reference string
+----
-See GARBAGE COLLECTION, REFERENCES, LAMBDA FUNCTION for more detail.
+See <<_garbage_collection_references_lambda_function,GARBAGE COLLECTION>> for more detail.
rename
~~~~~~
@@ -3709,7 +3834,7 @@ Store a new string in +'reference'+, replacing the existing string.
The reference must be a valid reference create with the `ref`
command.
-See GARBAGE COLLECTION, REFERENCES, LAMBDA FUNCTION for more detail.
+See <<_garbage_collection_references_lambda_function,GARBAGE COLLECTION>> for more detail.
signal
~~~~~~
@@ -3735,8 +3860,16 @@ Commands which return a list of signal names do so using the canonical form:
`signal check` to determine which signals have occurred but
been ignored.
++*signal block* ?'signals \...'?+::
+ If no signals are given, returns a lists all signals which are currently
+ being blocked.
+ If signals are specified, these are added to the list of signals
+ currently being blocked. These signals are not delivered to the process.
+ This can be useful for signals such as +SIGPIPE+, especially in conjunction
+ with `exec` as child processes inherit the parent's signal disposition.
+
+*signal default* ?'signals \...'?+::
- If no signals are given, returns a lists all signals which are currently have
+ If no signals are given, returns a lists all signals which currently have
the default behaviour.
If signals are specified, these are added to the list of signals which have
the default behaviour.
@@ -3752,7 +3885,9 @@ Commands which return a list of signal names do so using the canonical form:
Raises the given signal, which defaults to +SIGINT+ if not specified.
The behaviour is identical to:
- kill signal [pid]
+----
+ kill signal [pid]
+----
Note that `signal handle` and `signal ignore` represent two forms of signal
handling. `signal handle` is used in conjunction with `catch -signal` or `try -signal`
@@ -3762,6 +3897,7 @@ two examples below.
Prevent a processing from taking too long
+----
signal handle SIGALRM
alarm 20
try -signal {
@@ -3770,9 +3906,11 @@ Prevent a processing from taking too long
} on signal {sig} {
puts stderr "Process took too long"
}
+----
Handle SIGHUP to reconfigure:
+----
signal ignore SIGHUP
while {1} {
... handle configuration/reconfiguration ...
@@ -3781,6 +3919,10 @@ Handle SIGHUP to reconfigure:
}
# Received SIGHUP, so reconfigure
}
+----
+
+Note: signal handling is currently not supported in child interpreters.
+In these interpreters, the signal command does not exist.
sleep
~~~~~
@@ -3825,11 +3967,15 @@ If +'splitChars'+ is an empty string then each character of
+'splitChars'+ defaults to the standard white-space characters.
For example,
+----
split "comp.unix.misc" .
+----
returns +'"comp unix misc"'+ and
+----
split "Hello world" {}
+----
returns +'"H e l l o { } w o r l d"'+.
@@ -3863,7 +4009,7 @@ The legal options (which may be abbreviated) are:
Returns the length of the string in bytes. This will return
the same value as `string length` if UTF-8 support is not enabled,
or if the string is composed entirely of ASCII characters.
- See UTF-8 AND UNICODE.
+ See <<_utf_8_and_unicode,UTF-8 AND UNICODE>>.
+*string byterange* 'string first last'+::
Like `string range` except works on bytes rather than characters.
@@ -3894,7 +4040,7 @@ The legal options (which may be abbreviated) are:
found, return -1. If +'firstIndex'+ is specified, matching will start
from +'firstIndex'+ of +'string1'+.
::
- See STRING AND LIST INDEX SPECIFICATIONS for all allowed forms for +'firstIndex'+.
+ See <<_string_and_list_index_specifications,STRING AND LIST INDEX SPECIFICATIONS>> for all allowed forms for +'firstIndex'+.
+*string index* 'string charIndex'+::
Returns the +'charIndex'+'th character of the +'string'+
@@ -3904,7 +4050,7 @@ The legal options (which may be abbreviated) are:
or equal to the length of the string then an empty string is
returned.
::
- See STRING AND LIST INDEX SPECIFICATIONS for all allowed forms for +'charIndex'+.
+ See <<_string_and_list_index_specifications,STRING AND LIST INDEX SPECIFICATIONS>> for all allowed forms for +'charIndex'+.
+*string is* 'class' ?*-strict*? 'string'+::
Returns 1 if +'string'+ is a valid member of the specified character
@@ -3930,7 +4076,7 @@ The legal options (which may be abbreviated) are:
+upper+;; Any upper case alphabet character.
+xdigit+;; Any hexadecimal digit character ([0-9A-Fa-f]).
::
- Note that string classification does +'not'+ respect UTF-8. See UTF-8 AND UNICODE
+ Note that string classification does +'not'+ respect UTF-8. See <<_utf_8_and_unicode,UTF-8 AND UNICODE>>.
::
Note that only +'lowercase'+ boolean values are recognized (Tcl accepts any case).
@@ -3941,12 +4087,12 @@ The legal options (which may be abbreviated) are:
is no match, then return -1. If +'lastIndex'+ is specified, only characters
up to +'lastIndex'+ of +'string2'+ will be considered in the match.
::
- See STRING AND LIST INDEX SPECIFICATIONS for all allowed forms for +'lastIndex'+.
+ See <<_string_and_list_index_specifications,STRING AND LIST INDEX SPECIFICATIONS>> for all allowed forms for +'lastIndex'+.
+*string length* 'string'+::
Returns a decimal string giving the number of characters in +'string'+.
If UTF-8 support is enabled, this may be different than the number of bytes.
- See UTF-8 AND UNICODE
+ See <<_utf_8_and_unicode,UTF-8 AND UNICODE>>.
+*string map ?-nocase?* 'mapping string'+::
Replaces substrings in +'string'+ based on the key-value pairs in
@@ -3959,7 +4105,9 @@ The legal options (which may be abbreviated) are:
only iterated over once, so earlier key replacements will have no affect for
later key matches. For example,
+----
string map {abc 1 ab 2 a 3 1 0} 1abcaababcabababc
+----
::
will return the string +01321221+.
@@ -3967,7 +4115,9 @@ The legal options (which may be abbreviated) are:
Note that if an earlier key is a prefix of a later one, it will completely mask the later
one. So if the previous example is reordered like this,
+----
string map {1 0 ab 2 a 3 abc 1} 1abcaababcabababc
+----
::
it will return the string +02c322c222c+.
@@ -4005,7 +4155,7 @@ The legal options (which may be abbreviated) are:
character whose index is +'last'+. An index of 0 refers to the
first character of the string.
::
- See STRING AND LIST INDEX SPECIFICATIONS for all allowed forms for +'first'+ and +'last'+.
+ See <<_string_and_list_index_specifications,STRING AND LIST INDEX SPECIFICATIONS>> for all allowed forms for +'first'+ and +'last'+.
::
If +'first'+ is less than zero then it is treated as if it were zero, and
if +'last'+ is greater than or equal to the length of the string then
@@ -4086,8 +4236,10 @@ characters with no special interpretation.
special treatment to double quotes or curly braces. For example,
the following script returns +xyz \{44\}+, not +xyz \{$a\}+.
+----
set a 44
subst {xyz {$a}}
+----
switch
@@ -4152,25 +4304,31 @@ body among several patterns.
Below are some examples of `switch` commands:
+----
switch abc a - b {format 1} abc {format 2} default {format 3}
+----
will return 2,
+----
switch -regexp aaab {
^a.*b$ -
b {format 1}
a* {format 2}
default {format 3}
}
+----
will return 1, and
+----
switch xyz {
a -
b {format 1}
a* {format 2}
default {format 3}
}
+----
will return 3.
@@ -4183,17 +4341,23 @@ the current call frame. This is similar to 'exec' in Bourne Shell.
The following are identical except the first immediately replaces the current call frame.
+----
tailcall a b c
+----
+----
return [uplevel 1 [list a b c]]
+----
`tailcall` is useful as a dispatch mechanism:
+----
proc a {cmd args} {
tailcall sub_$cmd {*}$args
}
proc sub_cmd1 ...
proc sub_cmd2 ...
+----
tell
~~~~
@@ -4226,7 +4390,9 @@ This command will call the Tcl interpreter +'count'+
times to execute +'command'+ (or once if +'count'+ isn't
specified). It will then return a string of the form
+----
503 microseconds per iteration
+----
which indicates the average amount of time required per iteration,
in microseconds.
@@ -4261,6 +4427,7 @@ the matching handler.
For example:
+----
set f [open input]
try -signal {
process $f
@@ -4274,6 +4441,7 @@ For example:
} finally {
$f close
}
+----
If break, continue or error are raised, they are dealt with by the matching
handler.
@@ -4366,14 +4534,18 @@ The `uplevel` command causes the invoking procedure to disappear
from the procedure calling stack while the command is being executed.
In the above example, suppose 'c' invokes the command
+----
uplevel 1 {set x 43; d}
+----
where 'd' is another Tcl procedure. The `set` command will
modify the variable 'x' in 'b's context, and 'd' will execute
at level 3, as if called from 'b'. If it in turn executes
the command
+----
uplevel {set x 42}
+----
then the `set` command will modify the same variable 'x' in 'b's
context: the procedure 'c' does not appear to be on the call stack
@@ -4415,10 +4587,12 @@ procedure calling and also makes it easier to build new control constructs
as Tcl procedures.
For example, consider the following procedure:
+----
proc add2 name {
upvar $name x
set x [expr $x+2]
}
+----
'add2' is invoked with an argument giving the name of a variable,
and it adds two to the value of that variable.
@@ -4426,6 +4600,35 @@ Although 'add2' could have been implemented using `uplevel`
instead of `upvar`, `upvar` makes it simpler for 'add2'
to access the variable in the caller's procedure frame.
+wait
+~~~~
++*wait*+
+
++*wait -nohang* 'pid'+
+
+With no arguments, cleans up any processes started by `exec ... &` that have completed
+(reaps zombie processes).
+
+With one or two arguments, waits for a process by id, either returned by `exec ... &`
+or by `os.fork` (if supported).
+
+Waits for the process to complete, unless +-nohang+ is specified, in which case returns
+immediately if the process is still running.
+
+Returns a list of 3 elements.
+
++{NONE x x}+ if the process does not exist or has already been waited for, or
+if -nohang is specified, and the process is still alive.
+
++{CHILDSTATUS <pid> <exit-status>}+ if the process exited normally.
+
++{CHILDKILLED <pid> <signal>}+ if the process terminated on a signal.
+
++{CHILDSUSP <pid> none}+ if the process terminated for some other reason.
+
+Note that on platforms supporting waitpid(2), +pid+ can also be given special values such
+as 0 or -1. See waitpid(2) for more detail.
+
while
~~~~~
+*while* 'test body'+
@@ -4451,34 +4654,23 @@ OPTIONAL-EXTENSIONS
The following extensions may or may not be available depending upon
what options were selected when Jim Tcl was built.
+
[[cmd_1]]
-posix: os.fork, os.wait, os.gethostname, os.getids, os.uptime
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+posix: os.fork, os.gethostname, os.getids, os.uptime
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+*os.fork*+::
Invokes 'fork(2)' and returns the result.
-+*os.wait -nohang* 'pid'+::
- Invokes waitpid(2), with WNOHANG if +-nohang+ is specified.
- Returns a list of 3 elements.
-
- {0 none 0} if -nohang is specified, and the process is still alive.
-
- {-1 error <error-description>} if the process does not exist or has already been waited for.
-
- {<pid> exit <exit-status>} if the process exited normally.
-
- {<pid> signal <signal-number>} if the process terminated on a signal.
-
- {<pid> other 0} otherwise (core dump, stopped, continued, etc.)
-
+*os.gethostname*+::
Invokes 'gethostname(3)' and returns the result.
+*os.getids*+::
Returns the various user/group ids for the current process.
- jim> os.getids
+----
+ . os.getids
uid 1000 euid 1000 gid 100 egid 100
+----
+*os.uptime*+::
Returns the number of seconds since system boot. See description of 'uptime' in 'sysinfo(2)'.
@@ -4494,14 +4686,18 @@ aio
+$handle *accept* ?addrvar?+::
Server socket only: Accept a connection and return stream.
If +'addrvar'+ is specified, the address of the connected client is stored
- in the named variable in the form 'addr:port'. See `socket` for details.
+ in the named variable in the form 'addr:port' for IP sockets or 'path' for Unix domain sockets.
+ See `socket` for details.
+$handle *buffering none|line|full*+::
Sets the buffering mode of the stream.
-+$handle *close* ?r(ead)|w(rite)?+::
++$handle *close ?r(ead)|w(rite)|-nodelete?*+::
Closes the stream.
- The two-argument form is a "half-close" on a socket. See the +shutdown(2)+ man page.
+ The +'read'+ and +'write'+ arguments perform a "half-close" on a socket. See the 'shutdown(2)' man page.
+ The +'-nodelete'+ option is applicable only for Unix domain sockets. It closes the socket
+ but does not delete the bound path (e.g. after `os.fork`).
+
+$handle *copyto* 'tofd ?size?'+::
Copy bytes to the file descriptor +'tofd'+. If +'size'+ is specified, at most
@@ -4524,9 +4720,10 @@ aio
+$handle *isatty*+::
Returns 1 if the stream is a tty device.
-+$handle *lock*+::
++$handle *lock ?-wait?*+::
Apply a POSIX lock to the open file associated with the handle using
- fcntl(2).
+ 'fcntl(F_SETLK)', or 'fcntl(F_SETLKW)' to wait for the lock to be available if +'-wait'+
+ is specified.
The handle must be open for write access.
Returns 1 if the lock was successfully obtained, 0 otherwise.
An error occurs if the handle is not suitable for locking (e.g.
@@ -4537,6 +4734,9 @@ aio
Note that in general ANSI I/O interacts badly with non-blocking I/O.
Use with care.
++$handle *peername*+::
+ Returns the remote address or path of the connected socket. See 'getpeername(2)'.
+
+$handle *puts ?-nonewline?* 'str'+::
Write the string, with newline unless -nonewline
@@ -4545,28 +4745,77 @@ aio
+$handle *recvfrom* 'maxlen ?addrvar?'+::
Receives a message from the handle via recvfrom(2) and returns it.
- At most +'maxlen'+ bytes are read.
- If +'addrvar'+ is specified, the sending address of the message is stored in
- the named variable in the form 'addr:port'. See `socket` for details.
+ At most +'maxlen'+ bytes are read. If +'addrvar'+ is specified, the sending address
+ of the message is stored in the named variable in the form 'addr:port' for IP sockets
+ or 'path' for Unix domain sockets. See `socket` for details.
+$handle *seek* 'offset' *?start|current|end?*+::
Seeks in the stream (default 'current')
-+$handle *sendto* 'str ?addr:?port'+::
- Sends the string, +'str'+, to the given address via the socket using sendto(2).
++$handle *sendto* 'str ?address'+::
+ Sends the string, +'str'+, to the given address (host:port or path) via the socket using 'sendto(2)'.
This is intended for udp/dgram sockets and may give an error or behave in unintended
ways for other handle types.
Returns the number of bytes written.
++$handle *sockname*+::
+ Returns the bound address or path of the socket. See 'getsockname(2)'.
+
++$handle *sockopt* '?name value?'+::
+ With no arguments, returns a dictionary of socket options currently set for the handle
+ (will be empty for a non-socket). With +'name'+ and +'value'+, sets the socket option
+ to the given value. Currently supports the following boolean socket options:
+ +broadcast, debug, keepalive, nosigpipe, oobinline, tcp_nodelay+, and the following
+ integer socket options: +sndbuf, rcvbuf+
+
+$handle *sync*+::
- Flush the stream, then fsync(2) to commit any changes to storage.
- Only available on platforms that support fsync(2).
+ Flush the stream, then 'fsync(2)' to commit any changes to storage.
+ Only available on platforms that support 'fsync(2)'.
+$handle *tell*+::
Returns the current seek position
-+$handle *ssl* *?-server cert priv?*+::
- Initiates a SSL/TLS session and returns a new stream
++$handle *tty* ?settings?+::
+ If no arguments are given, returns a dictionary containing the tty settings for the stream.
+ If arguments are given, they must either be a dictionary, or +setting value \...+
+ Abbrevations are supported for both settings and values, so the following is acceptable:
+ +$f tty parity e input c out raw+.
+ Only available on platforms that support 'termios(3)'. Supported settings are:
+
+ +*baud* 'rate'+;;
+ Baud rate. e.g. 115200
+
+ +*data 5|6|7|8*+;;
+ Number of data bits
+
+ +*stop 1|2*+;;
+ Number of stop bits
+
+ +*parity even|odd|none*+;;
+ Parity setting
+
+ +*handshake xonxoff|rtscts|none*+;;
+ Handshaking type
+
+ +*input raw|cooked*+;;
+ Input character processing. In raw mode, the usual key sequences such as ^C do
+ not generate signals.
+
+ +*output raw|cooked*+;;
+ Output character processing. Typically CR -> CRNL is disabled in raw mode.
+
+ +*echo 0|1*+;;
+ Disable or enable echo on input. Note that this is a set-only value.
+ Setting +input+ to +raw+ or +cooked+ will overwrite this setting.
+
+ +*vmin* 'numchars'+;;
+ Minimum number of characters to read.
+
+ +*vtime* 'time'+;;
+ Timeout for noncanonical read (units of 0.1 seconds)
+
++$handle *ssl* ?*-server* 'cert priv'?+::
+ Upgrades the stream to a SSL/TLS session and returns the handle.
+$handle *unlock*+::
Release a POSIX lock previously acquired by `aio lock`.
@@ -4664,10 +4913,16 @@ socket
Various socket types may be created.
+*socket unix* 'path'+::
- A unix domain socket client.
+ A unix domain socket client connected to 'path'
+*socket unix.server* 'path'+::
- A unix domain socket server.
+ A unix domain socket server listening on 'path'
+
++*socket unix.dgram* '?path?'+::
+ A unix domain socket datagram client, optionally connected to 'path'
+
++*socket unix.dgram.server* 'path'+::
+ A unix domain socket datagram server server listening on 'path'
+*socket ?-ipv6? stream* 'addr:port'+::
A TCP socket client. (See the forms for +'addr'+ below)
@@ -4684,11 +4939,10 @@ Various socket types may be created.
A UDP socket server.
+*socket pipe*+::
- A pipe. Note that unlike all other socket types, this command returns
- a list of two channels: {read write}
+ A synonym for `pipe`
+*socket pair*+::
- A socketpair (see socketpair(2)). Like `socket pipe`, this command returns
+ A socketpair (see socketpair(2)). Like `pipe`, this command returns
a list of two channels: {s1 s2}. These channels are both readable and writable.
This command creates a socket connected (client) or bound (server) to the given
@@ -4697,16 +4951,19 @@ address.
The returned value is channel and may generally be used with the various file I/O
commands (gets, puts, read, etc.), either as object-based syntax or Tcl-compatible syntax.
+----
. set f [socket stream www.google.com:80]
aio.sockstream1
. $f puts -nonewline "GET / HTTP/1.0\r\n\r\n"
. $f gets
HTTP/1.0 302 Found
. $f close
+----
Server sockets, however support only 'accept', which is most useful in conjunction with
the EVENTLOOP API.
+----
set f [socket stream.server 80]
$f readable {
set client [$f accept]
@@ -4716,6 +4973,7 @@ the EVENTLOOP API.
$client close
}
vwait done
+----
The address, +'addr'+, can be given in one of the following forms:
@@ -4729,15 +4987,12 @@ also accept requests via IPv4.
Where a hostname is specified, the +'first'+ returned address is used
which matches the socket type is used.
-The special type 'pipe' isn't really a socket.
-
- lassign [socket pipe] r w
+An unconnected dgram socket (either 'dgram' or 'unix.dgram') must use
+`sendto` to specify the destination address.
- # Must close $w after exec
- exec ps >@$w &
- $w close
-
- $r readable ...
+The path for Unix domain sockets is automatically removed when the socket
+is closed. Use `close -nodelete` in the rare case where this behaviour
+should be avoided (e.g. after `os.fork`).
syslog
~~~~~~
@@ -4824,7 +5079,7 @@ commands based on the low-level `pack` and `unpack` commands.
See the Tcl documentation at: http://www.tcl.tk/man/tcl8.5/TclCmd/binary.htm
Note that 'binary format' with f/r/R specifiers (single-precision float) uses the value of Infinity
- in case of overflow.
+in case of overflow.
oo: class, super
~~~~~~~~~~~~~~~~
@@ -4906,7 +5161,7 @@ and zero or more child nodes (ordered), as well as zero or more attribute/value
tcl::prefix
~~~~~~~~~~~
-The optional tclprefix extension provides the Tcl8.6-compatible 'tcl::prefix' command
+The optional tclprefix extension provides the Tcl8.6-compatible `tcl::prefix` command
(http://www.tcl.tk/man/tcl8.6/TclCmd/prefix.htm) for matching strings against a table
of possible values (typically commands or options).
@@ -4929,6 +5184,19 @@ of possible values (typically commands or options).
generating the error message. The default corresponds to
setting +-level 0+.
+tcl::autocomplete
+~~~~~~~~~~~~~~~~~
+Scriptable command line completion is supported in the interactive shell, 'jimsh', through
+the `tcl::autocomplete` callback. A simple implementation is provided, however this may
+be replaced with a custom command instead if desired.
+
+In the interactive shell, press <TAB> to activate command line completion.
+
++*tcl::autocomplete* 'commandline'+::
+ This command is called with the current command line when the user presses <TAB>.
+ The command should return a list of all possible command lines that match the current command line.
+ For example if +*pr*+ is the current command line, the list +*{prefix proc}*+ may be returned.
+
history
~~~~~~~
The optional history extension provides script access to the command line editing
@@ -4945,6 +5213,10 @@ the remaining subcommands do nothing.
if +'varname'+ is given, it receives the line and the length of the line is returned,
or -1 on EOF. If +'varname'+ is not given, the line is returned directly.
++*history completion* 'command'+::
+ Sets an autocompletion command (see `tcl::autocomplete`) that is active during `history getline`.
+ If the command is empty, autocompletion is disabled.
+
+*history add* 'line'+::
Adds the given line to the history buffer.
@@ -4998,20 +5270,87 @@ independently (but synchronously) of the main interpreter.
+*interp*+::
Creates and returns a new interpreter object (command).
- The created interpeter contains any built-in commands along with static extensions,
- but does not include any dynamically loaded commands (package require, load).
- These must be reloaded in the child interpreter if required.
+ The created interpeter contains any built-in commands along with static extensions,
+ but does not include any dynamically loaded commands (package require, load).
+ These must be reloaded in the child interpreter if required.
+*$interp delete*+::
Deletes the interpeter object.
+*$interp eval* 'script' ...+::
- Evaluates a script in the context for the child interpreter, in the same way as 'eval'.
+ Evaluates a script in the context for the child interpreter, in the same way as 'eval'.
+*$interp alias* 'alias childcmd parentcmd ?arg ...?'+::
- Similar to 'alias', but creates a command, +'childcmd'+, in the child interpreter that is an
- alias for +'parentcmd'+ in the parent interpreter, with the given, fixed arguments.
- The alias may be deleted in the child with 'rename'.
+ Similar to 'alias', but creates a command, +'childcmd'+, in the child interpreter that is an
+ alias for +'parentcmd'+ in the parent interpreter, with the given, fixed arguments.
+ The alias may be deleted in the child with 'rename'.
+
+json::encode
+~~~~~~~~~~~~
+
+The Tcl -> JSON encoder is part of the optional 'json' package.
+
++*json::encode* 'value ?schema?'+::
+
+Encode a Tcl value as JSON according to the schema (defaults to +'str'+). The following schema types are supported:
+* 'str' - Tcl string -> JSON string
+* 'num' - Tcl value -> bare numeric value or null
+* 'bool' - Tcl boolean value -> true, false
+* 'obj ?name subschema ...?' - Tcl dict -> JSON object. For each dict key matching 'name', the corresponding 'subschema'
+is applied. The special name +'*'+ matches any keys not otherwise matched, otherwise the default +'str'+ is used.
+* 'list ?subschema?' - Tcl list -> JSON array. The 'subschema' (default +'str'+) is applied for each element of the list/array.
+* 'mixed ?subschema ...?' = Tcl list -> JSON array. Each 'subschema' is applied for the corresponding element of the list/array.
+ ::
+The following are examples:
+----
+ . json::encode {1 2 true false null 5.0} list
+ [ "1", "2", "true", "false", "null", "5.0" ]
+ . json::encode {1 2 true false null 5.0} {list num}
+ [ 1, 2, true, false, null, 5.0 ]
+ . json::encode {0 1 2 true false 5.0 off} {list bool}
+ [ false, true, true, true, false, true, false ]
+ . json::encode {a 1 b hello c {3 4}} obj
+ { "a":"1", "b":"hello", "c":"3 4" }
+ . json::encode {a 1 b hello c {3 4}} {obj a num c {list num}}
+ { "a":1, "b":"hello", "c":[ 3, 4 ] }
+ . json::encode {true true {abc def}} {mixed str num obj}
+ [ "true", true, { "abc":"def" } ]
+ . json::encode {a 1 b 3.0 c hello d null} {obj c str * num}
+ { "a":1, "b":3.0, "c":"hello", "d":null }
+----
+
+json::decode
+~~~~~~~~~~~~
+
+The JSON -> Tcl decoder is part of the optional 'json' package.
+
++*json::decode* ?*-index*? ?*-null* 'string'? ?*-schema*? 'json-string'+::
+
+Decodes the given JSON string (must be array or object) into a Tcl data structure. If '+-index+' is specified,
+decodes JSON arrays as dictionaries with numeric keys. This makes it possible to retrieve data from nested
+arrays and dictionaries with just '+dict get+'. With the option '+-schema+' returns a list of +'{data schema}'+
+where the schema is compatible with `json::encode`. Otherwise just returns the data.
+Decoding is as follows (with schema types listed in parentheses):
+* object -> dict ('obj')
+* array -> list ('mixed' or 'list')
+* number -> as-is ('num')
+* boolean -> as-is ('bool')
+* string -> string ('str')
+* null -> supplied null string or the default +'"null"'+ ('num')
+ ::
+ Note that an object decoded into a dict will return the keys in the same order as the original string.
+----
+ . json::decode {[1, 2]}
+ {1 2}
+ . json::decode -schema {[1, 2]}
+ {1 2} {list num}
+ . json::decode -schema {{"a":1, "b":2}}
+ {a 1 b 2} {obj a num b num}
+ . json::decode -schema {[1, 2, {a:"b", c:false}, "hello"]}
+ {1 2 {a b c false} hello} {mixed num num {obj a str c bool} str}
+ . json::decode -index {["foo", "bar"]}
+ {0 foo 1 bar}
+----
[[BuiltinVariables]]
BUILT-IN VARIABLES
@@ -5065,6 +5404,7 @@ The following global variables are set by jimsh.
about the platform upon which Jim was built. The following is an
example of the contents of this array.
+----
tcl_platform(byteOrder) = littleEndian
tcl_platform(engine) = Jim
tcl_platform(os) = Darwin
@@ -5073,6 +5413,7 @@ The following global variables are set by jimsh.
tcl_platform(threaded) = 0
tcl_platform(wordSize) = 8
tcl_platform(pathSeparator) = :
+----
+*argv0*+::
If jimsh is invoked to run a script, this variable contains the name
@@ -5089,9 +5430,74 @@ The following global variables are set by jimsh.
+*jim::argv0*+::
The value of argv[0] when jimsh was invoked.
+The following variables have special meaning to Jim Tcl:
+
++*jim::defer*+::
+ If this variable is set, it is considered to be a list of scripts to evaluate
+ when the current proc exits (local variables), or the interpreter exits (global variable).
+ See `defer`.
+
++*history::multiline*+::
+ If this variable is set to "1", interactive line editing operates in multiline mode.
+ That is, long lines will wrap across multiple lines rather than scrolling within a
+ single line.
+
CHANGES IN PREVIOUS RELEASES
----------------------------
+=== In v0.74 ===
+
+1. Numbers with leading zeros are treated as decimal, not octal
+2. Add `aio isatty`
+3. Add LFS (64 bit) support for `aio seek`, `aio tell`, `aio copyto`, `file copy`
+4. `string compare` and `string equal` now support '-length'
+5. `glob` now supports '-directory'
+
+=== In v0.73 ===
+
+1. Built-in regexp now support non-capturing parentheses: (?:...)
+2. Add `string replace`
+3. Add `string totitle`
+4. Add `info statics`
+5. Add +build-jim-ext+ for easy separate building of loadable modules (extensions)
+6. `local` now works with any command, not just procs
+7. Add `info alias` to access the target of an alias
+8. UTF-8 encoding past the basic multilingual plane (BMP) is supported
+9. Add `tcl::prefix`
+10. Add `history`
+11. Most extensions are now enabled by default
+12. Add support for namespaces and the `namespace` command
+13. Add `apply`
+
+=== In v0.72 ===
+
+1. procs now allow 'args' and optional parameters in any position
+2. Add Tcl-compatible expr functions, `rand()`, `srand()` and `pow()`
+3. Add support for the '-force' option to `file delete`
+4. Better diagnostics when `source` fails to load a script with a missing quote or bracket
+5. New +tcl_platform(pathSeparator)+
+6. Add support settings the modification time with `file mtime`
+7. `exec` is now fully supported on win32 (mingw32)
+8. `file join`, `pwd`, `glob` etc. now work for mingw32
+9. Line editing is now supported for the win32 console (mingw32)
+10. Add `aio listen` command
+
+=== In v0.71 ===
+
+1. Allow 'args' to be renamed in procs
+2. Add +$(...)+ shorthand syntax for expressions
+3. Add automatic reference variables in procs with +&var+ syntax
+4. Support +jimsh --version+
+5. Additional variables in +tcl_platform()+
+6. `local` procs now push existing commands and `upcall` can call them
+7. Add `loop` command (TclX compatible)
+8. Add `aio buffering` command
+9. `info complete` can now return the missing character
+10. `binary format` and `binary scan` are now (optionally) supported
+11. Add `string byterange`
+12. Built-in regexp now support non-greedy repetition (*?, +?, ??)
+
+
=== In v0.70 ===
1. +platform_tcl()+ settings are now automatically determined
diff --git a/jimiocompat.c b/jimiocompat.c
new file mode 100644
index 0000000..c8c3f86
--- /dev/null
+++ b/jimiocompat.c
@@ -0,0 +1,214 @@
+#include <string.h>
+#include "jimiocompat.h"
+
+void Jim_SetResultErrno(Jim_Interp *interp, const char *msg)
+{
+ Jim_SetResultFormatted(interp, "%s: %s", msg, strerror(Jim_Errno()));
+}
+
+#if defined(__MINGW32__)
+#include <sys/stat.h>
+
+int Jim_Errno(void)
+{
+ switch (GetLastError()) {
+ case ERROR_FILE_NOT_FOUND: return ENOENT;
+ case ERROR_PATH_NOT_FOUND: return ENOENT;
+ case ERROR_TOO_MANY_OPEN_FILES: return EMFILE;
+ case ERROR_ACCESS_DENIED: return EACCES;
+ case ERROR_INVALID_HANDLE: return EBADF;
+ case ERROR_BAD_ENVIRONMENT: return E2BIG;
+ case ERROR_BAD_FORMAT: return ENOEXEC;
+ case ERROR_INVALID_ACCESS: return EACCES;
+ case ERROR_INVALID_DRIVE: return ENOENT;
+ case ERROR_CURRENT_DIRECTORY: return EACCES;
+ case ERROR_NOT_SAME_DEVICE: return EXDEV;
+ case ERROR_NO_MORE_FILES: return ENOENT;
+ case ERROR_WRITE_PROTECT: return EROFS;
+ case ERROR_BAD_UNIT: return ENXIO;
+ case ERROR_NOT_READY: return EBUSY;
+ case ERROR_BAD_COMMAND: return EIO;
+ case ERROR_CRC: return EIO;
+ case ERROR_BAD_LENGTH: return EIO;
+ case ERROR_SEEK: return EIO;
+ case ERROR_WRITE_FAULT: return EIO;
+ case ERROR_READ_FAULT: return EIO;
+ case ERROR_GEN_FAILURE: return EIO;
+ case ERROR_SHARING_VIOLATION: return EACCES;
+ case ERROR_LOCK_VIOLATION: return EACCES;
+ case ERROR_SHARING_BUFFER_EXCEEDED: return ENFILE;
+ case ERROR_HANDLE_DISK_FULL: return ENOSPC;
+ case ERROR_NOT_SUPPORTED: return ENODEV;
+ case ERROR_REM_NOT_LIST: return EBUSY;
+ case ERROR_DUP_NAME: return EEXIST;
+ case ERROR_BAD_NETPATH: return ENOENT;
+ case ERROR_NETWORK_BUSY: return EBUSY;
+ case ERROR_DEV_NOT_EXIST: return ENODEV;
+ case ERROR_TOO_MANY_CMDS: return EAGAIN;
+ case ERROR_ADAP_HDW_ERR: return EIO;
+ case ERROR_BAD_NET_RESP: return EIO;
+ case ERROR_UNEXP_NET_ERR: return EIO;
+ case ERROR_NETNAME_DELETED: return ENOENT;
+ case ERROR_NETWORK_ACCESS_DENIED: return EACCES;
+ case ERROR_BAD_DEV_TYPE: return ENODEV;
+ case ERROR_BAD_NET_NAME: return ENOENT;
+ case ERROR_TOO_MANY_NAMES: return ENFILE;
+ case ERROR_TOO_MANY_SESS: return EIO;
+ case ERROR_SHARING_PAUSED: return EAGAIN;
+ case ERROR_REDIR_PAUSED: return EAGAIN;
+ case ERROR_FILE_EXISTS: return EEXIST;
+ case ERROR_CANNOT_MAKE: return ENOSPC;
+ case ERROR_OUT_OF_STRUCTURES: return ENFILE;
+ case ERROR_ALREADY_ASSIGNED: return EEXIST;
+ case ERROR_INVALID_PASSWORD: return EPERM;
+ case ERROR_NET_WRITE_FAULT: return EIO;
+ case ERROR_NO_PROC_SLOTS: return EAGAIN;
+ case ERROR_DISK_CHANGE: return EXDEV;
+ case ERROR_BROKEN_PIPE: return EPIPE;
+ case ERROR_OPEN_FAILED: return ENOENT;
+ case ERROR_DISK_FULL: return ENOSPC;
+ case ERROR_NO_MORE_SEARCH_HANDLES: return EMFILE;
+ case ERROR_INVALID_TARGET_HANDLE: return EBADF;
+ case ERROR_INVALID_NAME: return ENOENT;
+ case ERROR_PROC_NOT_FOUND: return ESRCH;
+ case ERROR_WAIT_NO_CHILDREN: return ECHILD;
+ case ERROR_CHILD_NOT_COMPLETE: return ECHILD;
+ case ERROR_DIRECT_ACCESS_HANDLE: return EBADF;
+ case ERROR_SEEK_ON_DEVICE: return ESPIPE;
+ case ERROR_BUSY_DRIVE: return EAGAIN;
+ case ERROR_DIR_NOT_EMPTY: return EEXIST;
+ case ERROR_NOT_LOCKED: return EACCES;
+ case ERROR_BAD_PATHNAME: return ENOENT;
+ case ERROR_LOCK_FAILED: return EACCES;
+ case ERROR_ALREADY_EXISTS: return EEXIST;
+ case ERROR_FILENAME_EXCED_RANGE: return ENAMETOOLONG;
+ case ERROR_BAD_PIPE: return EPIPE;
+ case ERROR_PIPE_BUSY: return EAGAIN;
+ case ERROR_PIPE_NOT_CONNECTED: return EPIPE;
+ case ERROR_DIRECTORY: return ENOTDIR;
+ }
+ return EINVAL;
+}
+
+pidtype waitpid(pidtype pid, int *status, int nohang)
+{
+ DWORD ret = WaitForSingleObject(pid, nohang ? 0 : INFINITE);
+ if (ret == WAIT_TIMEOUT || ret == WAIT_FAILED) {
+ /* WAIT_TIMEOUT can only happend with WNOHANG */
+ return JIM_BAD_PID;
+ }
+ GetExitCodeProcess(pid, &ret);
+ *status = ret;
+ CloseHandle(pid);
+ return pid;
+}
+
+int Jim_MakeTempFile(Jim_Interp *interp, const char *filename_template, int unlink_file)
+{
+ char name[MAX_PATH];
+ HANDLE handle;
+
+ if (!GetTempPath(MAX_PATH, name) || !GetTempFileName(name, filename_template ? filename_template : "JIM", 0, name)) {
+ return -1;
+ }
+
+ handle = CreateFile(name, GENERIC_READ | GENERIC_WRITE, 0, NULL,
+ CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY | (unlink_file ? FILE_FLAG_DELETE_ON_CLOSE : 0),
+ NULL);
+
+ if (handle == INVALID_HANDLE_VALUE) {
+ goto error;
+ }
+
+ Jim_SetResultString(interp, name, -1);
+ return _open_osfhandle((int)handle, _O_RDWR | _O_TEXT);
+
+ error:
+ Jim_SetResultErrno(interp, name);
+ DeleteFile(name);
+ return -1;
+}
+
+int Jim_OpenForWrite(const char *filename, int append)
+{
+ if (strcmp(filename, "/dev/null") == 0) {
+ filename = "nul:";
+ }
+ int fd = _open(filename, _O_WRONLY | _O_CREAT | _O_TEXT | (append ? _O_APPEND : _O_TRUNC), _S_IREAD | _S_IWRITE);
+ if (fd >= 0 && append) {
+ /* Note that _O_APPEND doesn't actually work. need to do it manually */
+ _lseek(fd, 0L, SEEK_END);
+ }
+ return fd;
+}
+
+int Jim_OpenForRead(const char *filename)
+{
+ if (strcmp(filename, "/dev/null") == 0) {
+ filename = "nul:";
+ }
+ return _open(filename, _O_RDONLY | _O_TEXT, 0);
+}
+
+#elif defined(HAVE_UNISTD_H)
+
+/* Unix-specific implementation */
+
+int Jim_MakeTempFile(Jim_Interp *interp, const char *filename_template, int unlink_file)
+{
+ int fd;
+ mode_t mask;
+ Jim_Obj *filenameObj;
+
+ if (filename_template == NULL) {
+ const char *tmpdir = getenv("TMPDIR");
+ if (tmpdir == NULL || *tmpdir == '\0' || access(tmpdir, W_OK) != 0) {
+ tmpdir = "/tmp/";
+ }
+ filenameObj = Jim_NewStringObj(interp, tmpdir, -1);
+ if (tmpdir[0] && tmpdir[strlen(tmpdir) - 1] != '/') {
+ Jim_AppendString(interp, filenameObj, "/", 1);
+ }
+ Jim_AppendString(interp, filenameObj, "tcl.tmp.XXXXXX", -1);
+ }
+ else {
+ filenameObj = Jim_NewStringObj(interp, filename_template, -1);
+ }
+
+ /* Update the template name directly with the filename */
+ mask = umask(S_IXUSR | S_IRWXG | S_IRWXO);
+#ifdef HAVE_MKSTEMP
+ fd = mkstemp(filenameObj->bytes);
+#else
+ if (mktemp(filenameObj->bytes) == NULL) {
+ fd = -1;
+ }
+ else {
+ fd = open(filenameObj->bytes, O_RDWR | O_CREAT | O_TRUNC);
+ }
+#endif
+ umask(mask);
+ if (fd < 0) {
+ Jim_SetResultErrno(interp, Jim_String(filenameObj));
+ Jim_FreeNewObj(interp, filenameObj);
+ return -1;
+ }
+ if (unlink_file) {
+ remove(Jim_String(filenameObj));
+ }
+
+ Jim_SetResult(interp, filenameObj);
+ return fd;
+}
+
+int Jim_OpenForWrite(const char *filename, int append)
+{
+ return open(filename, O_WRONLY | O_CREAT | (append ? O_APPEND : O_TRUNC), 0666);
+}
+
+int Jim_OpenForRead(const char *filename)
+{
+ return open(filename, O_RDONLY, 0);
+}
+
+#endif
diff --git a/jimiocompat.h b/jimiocompat.h
new file mode 100644
index 0000000..2cbb578
--- /dev/null
+++ b/jimiocompat.h
@@ -0,0 +1,80 @@
+#ifndef JIMIOCOMPAT_H
+#define JIMIOCOMPAT_H
+
+/*
+ * Cross-platform compatibility functions and types for I/O.
+ * Currently used by jim-aio.c and jim-exec.c
+ */
+
+#include <stdio.h>
+#include <errno.h>
+
+#include "jimautoconf.h"
+#include <jim.h>
+#include <jim-win32compat.h>
+
+/**
+ * Set an error result based on errno and the given message.
+ */
+void Jim_SetResultErrno(Jim_Interp *interp, const char *msg);
+
+/**
+ * Opens the file for writing (and appending if append is true).
+ * Returns the file descriptor, or -1 on failure.
+ */
+int Jim_OpenForWrite(const char *filename, int append);
+
+/**
+ * Opens the file for reading.
+ * Returns the file descriptor, or -1 on failure.
+ */
+int Jim_OpenForRead(const char *filename);
+
+#if defined(__MINGW32__)
+ #ifndef STRICT
+ #define STRICT
+ #endif
+ #define WIN32_LEAN_AND_MEAN
+ #include <windows.h>
+ #include <fcntl.h>
+ #include <io.h>
+ #include <process.h>
+
+ typedef HANDLE pidtype;
+ #define JIM_BAD_PID INVALID_HANDLE_VALUE
+ /* Note that this isn't a separate value on Windows since we don't have os.fork */
+ #define JIM_NO_PID INVALID_HANDLE_VALUE
+
+ /* These seem to accord with the conventions used by msys/mingw32 */
+ #define WIFEXITED(STATUS) (((STATUS) & 0xff00) == 0)
+ #define WEXITSTATUS(STATUS) ((STATUS) & 0x00ff)
+ #define WIFSIGNALED(STATUS) (((STATUS) & 0xff00) != 0)
+ #define WTERMSIG(STATUS) (((STATUS) >> 8) & 0xff)
+ #define WNOHANG 1
+
+ /**
+ * Unix-compatible errno
+ */
+ int Jim_Errno(void);
+ pidtype waitpid(pidtype pid, int *status, int nohang);
+
+ #define HAVE_PIPE
+ #define pipe(P) _pipe((P), 0, O_NOINHERIT)
+
+#elif defined(HAVE_UNISTD_H)
+ #include <unistd.h>
+ #include <fcntl.h>
+ #include <sys/wait.h>
+ #include <sys/stat.h>
+
+ typedef int pidtype;
+ #define Jim_Errno() errno
+ #define JIM_BAD_PID -1
+ #define JIM_NO_PID 0
+
+ #ifndef HAVE_EXECVPE
+ #define execvpe(ARG0, ARGV, ENV) execvp(ARG0, ARGV)
+ #endif
+#endif
+
+#endif
diff --git a/jimregexp.c b/jimregexp.c
index b256e76..5b2d60c 100644
--- a/jimregexp.c
+++ b/jimregexp.c
@@ -477,6 +477,10 @@ static int regpiece(regex_t *preg, int *flagp)
if (*end == '}') {
max = min;
}
+ else if (*end == '\0') {
+ preg->err = REG_ERR_UNMATCHED_BRACES;
+ return 0;
+ }
else {
preg->regparse = end;
max = strtoul(preg->regparse + 1, &end, 10);
@@ -720,8 +724,31 @@ static int regatom(regex_t *preg, int *flagp)
int start;
int end;
+ enum {
+ CC_ALPHA, CC_ALNUM, CC_SPACE, CC_BLANK, CC_UPPER, CC_LOWER,
+ CC_DIGIT, CC_XDIGIT, CC_CNTRL, CC_GRAPH, CC_PRINT, CC_PUNCT,
+ CC_NUM
+ };
+ int cc;
+
pattern += reg_utf8_tounicode_case(pattern, &start, nocase);
if (start == '\\') {
+ /* First check for class shorthand escapes */
+ switch (*pattern) {
+ case 's':
+ pattern++;
+ cc = CC_SPACE;
+ goto cc_switch;
+ case 'd':
+ pattern++;
+ cc = CC_DIGIT;
+ goto cc_switch;
+ case 'w':
+ pattern++;
+ reg_addrange(preg, '_', '_');
+ cc = CC_ALNUM;
+ goto cc_switch;
+ }
pattern += reg_decode_escape(pattern, &start);
if (start == 0) {
preg->err = REG_ERR_NULL_CHAR;
@@ -748,23 +775,18 @@ static int regatom(regex_t *preg, int *flagp)
":alpha:", ":alnum:", ":space:", ":blank:", ":upper:", ":lower:",
":digit:", ":xdigit:", ":cntrl:", ":graph:", ":print:", ":punct:",
};
- enum {
- CC_ALPHA, CC_ALNUM, CC_SPACE, CC_BLANK, CC_UPPER, CC_LOWER,
- CC_DIGIT, CC_XDIGIT, CC_CNTRL, CC_GRAPH, CC_PRINT, CC_PUNCT,
- CC_NUM
- };
- int i;
- for (i = 0; i < CC_NUM; i++) {
- n = strlen(character_class[i]);
- if (strncmp(pattern, character_class[i], n) == 0) {
+ for (cc = 0; cc < CC_NUM; cc++) {
+ n = strlen(character_class[cc]);
+ if (strncmp(pattern, character_class[cc], n) == 0) {
/* Found a character class */
pattern += n + 1;
break;
}
}
- if (i != CC_NUM) {
- switch (i) {
+ if (cc != CC_NUM) {
+cc_switch:
+ switch (cc) {
case CC_ALNUM:
reg_addrange(preg, '0', '9');
/* Fall through */
@@ -1590,10 +1612,9 @@ static int regrepeat(regex_t *preg, int p, int max)
opnd = OPERAND(p);
switch (OP(preg, p)) {
case ANY:
- /* No need to handle utf8 specially here */
while (!reg_iseol(preg, *scan) && count < max) {
count++;
- scan++;
+ scan += utf8_charlen(*scan);
}
break;
case EXACTLY:
diff --git a/jimsh.c b/jimsh.c
index afcd7dd..1a334a2 100644
--- a/jimsh.c
+++ b/jimsh.c
@@ -74,12 +74,12 @@ void usage(const char* executable_name)
printf("Without options: Interactive mode\n");
printf("\n");
printf("Options:\n");
- printf(" --version : prints the version string\n");
- printf(" --help : prints this text\n");
- printf(" -e CMD : executes command CMD\n");
- printf(" NOTE: all subsequent options will be passed as arguments to the command\n");
- printf(" [filename] : executes the script contained in the named file\n");
- printf(" NOTE: all subsequent options will be passed to the script\n\n");
+ printf(" --version : prints the version string\n");
+ printf(" --help : prints this text\n");
+ printf(" -e CMD : executes command CMD\n");
+ printf(" NOTE: all subsequent options will be passed as arguments to the command\n");
+ printf(" [filename|-] : executes the script contained in the named file, or from stdin if \"-\"\n");
+ printf(" NOTE: all subsequent options will be passed to the script\n\n");
}
int main(int argc, char *const argv[])
@@ -134,7 +134,11 @@ int main(int argc, char *const argv[])
else {
Jim_SetVariableStr(interp, "argv0", Jim_NewStringObj(interp, argv[1], -1));
JimSetArgv(interp, argc - 2, argv + 2);
- retcode = Jim_EvalFile(interp, argv[1]);
+ if (strcmp(argv[1], "-") == 0) {
+ retcode = Jim_Eval(interp, "eval [info source [stdin read] stdin 1]");
+ } else {
+ retcode = Jim_EvalFile(interp, argv[1]);
+ }
}
if (retcode == JIM_ERR) {
JimPrintErrorMessage(interp);
diff --git a/jimtcl.pc.in b/jimtcl.pc.in
new file mode 100644
index 0000000..a7e3c03
--- /dev/null
+++ b/jimtcl.pc.in
@@ -0,0 +1,13 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: jimtcl
+URL: http://jim.tcl.tk/
+Description: The Jim Interpreter - A small-footprint implementation of the Tcl programming language.
+Version: @VERSION@
+Requires: @PKG_CONFIG_REQUIRES@
+Libs: -L${libdir} -ljim
+Libs.private: @LDLIBS@
+Cflags: -I${includedir}
diff --git a/jsmn/LICENSE b/jsmn/LICENSE
new file mode 100644
index 0000000..c84fb2e
--- /dev/null
+++ b/jsmn/LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2010 Serge A. Zaitsev
+
+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.
+
diff --git a/jsmn/jsmn.c b/jsmn/jsmn.c
new file mode 100644
index 0000000..2de5ec2
--- /dev/null
+++ b/jsmn/jsmn.c
@@ -0,0 +1,318 @@
+#include "jsmn.h"
+
+/**
+ * Allocates a fresh unused token from the token pool.
+ */
+static jsmntok_t *jsmn_alloc_token(jsmn_parser *parser,
+ jsmntok_t *tokens, size_t num_tokens) {
+ jsmntok_t *tok;
+ if (parser->toknext >= num_tokens) {
+ return NULL;
+ }
+ tok = &tokens[parser->toknext++];
+ tok->start = tok->end = -1;
+ tok->size = 0;
+#ifdef JSMN_PARENT_LINKS
+ tok->parent = -1;
+#endif
+ return tok;
+}
+
+/**
+ * Fills token type and boundaries.
+ */
+static void jsmn_fill_token(jsmntok_t *token, jsmntype_t type,
+ int start, int end) {
+ token->type = type;
+ token->start = start;
+ token->end = end;
+ token->size = 0;
+}
+
+/**
+ * Fills next available token with JSON primitive.
+ */
+static int jsmn_parse_primitive(jsmn_parser *parser, const char *js,
+ size_t len, jsmntok_t *tokens, size_t num_tokens) {
+ jsmntok_t *token;
+ int start;
+
+ start = parser->pos;
+
+ for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) {
+ switch (js[parser->pos]) {
+#ifndef JSMN_STRICT
+ /* In strict mode primitive must be followed by "," or "}" or "]" */
+ case ':':
+#endif
+ case '\t' : case '\r' : case '\n' : case ' ' :
+ case ',' : case ']' : case '}' :
+ goto found;
+ }
+ if (js[parser->pos] < 32 || js[parser->pos] >= 127) {
+ parser->pos = start;
+ return JSMN_ERROR_INVAL;
+ }
+ }
+#ifdef JSMN_STRICT
+ /* In strict mode primitive must be followed by a comma/object/array */
+ parser->pos = start;
+ return JSMN_ERROR_PART;
+#endif
+
+found:
+ if (tokens == NULL) {
+ parser->pos--;
+ return 0;
+ }
+ token = jsmn_alloc_token(parser, tokens, num_tokens);
+ if (token == NULL) {
+ parser->pos = start;
+ return JSMN_ERROR_NOMEM;
+ }
+ jsmn_fill_token(token, JSMN_PRIMITIVE, start, parser->pos);
+#ifdef JSMN_PARENT_LINKS
+ token->parent = parser->toksuper;
+#endif
+ parser->pos--;
+ return 0;
+}
+
+/**
+ * Fills next token with JSON string.
+ */
+static int jsmn_parse_string(jsmn_parser *parser, const char *js,
+ size_t len, jsmntok_t *tokens, size_t num_tokens) {
+ jsmntok_t *token;
+
+ int start = parser->pos;
+
+ parser->pos++;
+
+ /* Skip starting quote */
+ for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) {
+ char c = js[parser->pos];
+
+ /* Quote: end of string */
+ if (c == '\"') {
+ if (tokens == NULL) {
+ return 0;
+ }
+ token = jsmn_alloc_token(parser, tokens, num_tokens);
+ if (token == NULL) {
+ parser->pos = start;
+ return JSMN_ERROR_NOMEM;
+ }
+ jsmn_fill_token(token, JSMN_STRING, start+1, parser->pos);
+#ifdef JSMN_PARENT_LINKS
+ token->parent = parser->toksuper;
+#endif
+ return 0;
+ }
+
+ /* Backslash: Quoted symbol expected */
+ if (c == '\\' && parser->pos + 1 < len) {
+ int i;
+ parser->pos++;
+ switch (js[parser->pos]) {
+ /* Allowed escaped symbols */
+ case '\"': case '/' : case '\\' : case 'b' :
+ case 'f' : case 'r' : case 'n' : case 't' :
+ break;
+ /* Allows escaped symbol \uXXXX */
+ case 'u':
+ parser->pos++;
+ for(i = 0; i < 4 && parser->pos < len && js[parser->pos] != '\0'; i++) {
+ /* If it isn't a hex character we have an error */
+ if(!((js[parser->pos] >= 48 && js[parser->pos] <= 57) || /* 0-9 */
+ (js[parser->pos] >= 65 && js[parser->pos] <= 70) || /* A-F */
+ (js[parser->pos] >= 97 && js[parser->pos] <= 102))) { /* a-f */
+ parser->pos = start;
+ return JSMN_ERROR_INVAL;
+ }
+ parser->pos++;
+ }
+ parser->pos--;
+ break;
+ /* Unexpected symbol */
+ default:
+ parser->pos = start;
+ return JSMN_ERROR_INVAL;
+ }
+ }
+ }
+ parser->pos = start;
+ return JSMN_ERROR_PART;
+}
+
+/**
+ * Parse JSON string and fill tokens.
+ */
+int jsmn_parse(jsmn_parser *parser, const char *js, size_t len,
+ jsmntok_t *tokens, unsigned int num_tokens) {
+ int r;
+ int i;
+ jsmntok_t *token;
+ int count = parser->toknext;
+
+ for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) {
+ char c;
+ jsmntype_t type;
+
+ c = js[parser->pos];
+ switch (c) {
+ case '{': case '[':
+ count++;
+ if (tokens == NULL) {
+ break;
+ }
+ token = jsmn_alloc_token(parser, tokens, num_tokens);
+ if (token == NULL)
+ return JSMN_ERROR_NOMEM;
+ if (parser->toksuper != -1) {
+ if (tokens[parser->toksuper].type == JSMN_OBJECT) {
+ /* Object keys must be strings, not objects or arrays */
+ return JSMN_ERROR_INVAL;
+ }
+ tokens[parser->toksuper].size++;
+#ifdef JSMN_PARENT_LINKS
+ token->parent = parser->toksuper;
+#endif
+ }
+ token->type = (c == '{' ? JSMN_OBJECT : JSMN_ARRAY);
+ token->start = parser->pos;
+ parser->toksuper = parser->toknext - 1;
+ break;
+ case '}': case ']':
+ if (tokens == NULL)
+ break;
+ type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY);
+#ifdef JSMN_PARENT_LINKS
+ if (parser->toknext < 1) {
+ return JSMN_ERROR_INVAL;
+ }
+ token = &tokens[parser->toknext - 1];
+ for (;;) {
+ if (token->start != -1 && token->end == -1) {
+ if (token->type != type) {
+ return JSMN_ERROR_INVAL;
+ }
+ token->end = parser->pos + 1;
+ parser->toksuper = token->parent;
+ break;
+ }
+ if (token->parent == -1) {
+ if(token->type != type || parser->toksuper == -1) {
+ return JSMN_ERROR_INVAL;
+ }
+ break;
+ }
+ token = &tokens[token->parent];
+ }
+#else
+ for (i = parser->toknext - 1; i >= 0; i--) {
+ token = &tokens[i];
+ if (token->start != -1 && token->end == -1) {
+ if (token->type != type) {
+ return JSMN_ERROR_INVAL;
+ }
+ parser->toksuper = -1;
+ token->end = parser->pos + 1;
+ break;
+ }
+ }
+ /* Error if unmatched closing bracket */
+ if (i == -1) return JSMN_ERROR_INVAL;
+ for (; i >= 0; i--) {
+ token = &tokens[i];
+ if (token->start != -1 && token->end == -1) {
+ parser->toksuper = i;
+ break;
+ }
+ }
+#endif
+ break;
+ case '\"':
+ r = jsmn_parse_string(parser, js, len, tokens, num_tokens);
+ if (r < 0) return r;
+ count++;
+ if (parser->toksuper != -1 && tokens != NULL)
+ tokens[parser->toksuper].size++;
+ break;
+ case '\t' : case '\r' : case '\n' : case ' ':
+ break;
+ case ':':
+ parser->toksuper = parser->toknext - 1;
+ break;
+ case ',':
+ if (tokens != NULL && parser->toksuper != -1 &&
+ tokens[parser->toksuper].type != JSMN_ARRAY &&
+ tokens[parser->toksuper].type != JSMN_OBJECT) {
+#ifdef JSMN_PARENT_LINKS
+ parser->toksuper = tokens[parser->toksuper].parent;
+#else
+ for (i = parser->toknext - 1; i >= 0; i--) {
+ if (tokens[i].type == JSMN_ARRAY || tokens[i].type == JSMN_OBJECT) {
+ if (tokens[i].start != -1 && tokens[i].end == -1) {
+ parser->toksuper = i;
+ break;
+ }
+ }
+ }
+#endif
+ }
+ break;
+#ifdef JSMN_STRICT
+ /* In strict mode primitives are: numbers and booleans */
+ case '-': case '0': case '1' : case '2': case '3' : case '4':
+ case '5': case '6': case '7' : case '8': case '9':
+ case 't': case 'f': case 'n' :
+ /* And they must not be keys of the object */
+ if (tokens != NULL && parser->toksuper != -1) {
+ jsmntok_t *t = &tokens[parser->toksuper];
+ if (t->type == JSMN_OBJECT ||
+ (t->type == JSMN_STRING && t->size != 0)) {
+ return JSMN_ERROR_INVAL;
+ }
+ }
+#else
+ /* In non-strict mode every unquoted value is a primitive */
+ default:
+#endif
+ r = jsmn_parse_primitive(parser, js, len, tokens, num_tokens);
+ if (r < 0) return r;
+ count++;
+ if (parser->toksuper != -1 && tokens != NULL)
+ tokens[parser->toksuper].size++;
+ break;
+
+#ifdef JSMN_STRICT
+ /* Unexpected char in strict mode */
+ default:
+ return JSMN_ERROR_INVAL;
+#endif
+ }
+ }
+
+ if (tokens != NULL) {
+ for (i = parser->toknext - 1; i >= 0; i--) {
+ /* Unmatched opened object or array */
+ if (tokens[i].start != -1 && tokens[i].end == -1) {
+ return JSMN_ERROR_PART;
+ }
+ }
+ }
+
+ return count;
+}
+
+/**
+ * Creates a new parser based over a given buffer with an array of tokens
+ * available.
+ */
+void jsmn_init(jsmn_parser *parser) {
+ parser->pos = 0;
+ parser->toknext = 0;
+ parser->toksuper = -1;
+}
+
diff --git a/jsmn/jsmn.h b/jsmn/jsmn.h
new file mode 100644
index 0000000..01ca99c
--- /dev/null
+++ b/jsmn/jsmn.h
@@ -0,0 +1,76 @@
+#ifndef __JSMN_H_
+#define __JSMN_H_
+
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * JSON type identifier. Basic types are:
+ * o Object
+ * o Array
+ * o String
+ * o Other primitive: number, boolean (true/false) or null
+ */
+typedef enum {
+ JSMN_UNDEFINED = 0,
+ JSMN_OBJECT = 1,
+ JSMN_ARRAY = 2,
+ JSMN_STRING = 3,
+ JSMN_PRIMITIVE = 4
+} jsmntype_t;
+
+enum jsmnerr {
+ /* Not enough tokens were provided */
+ JSMN_ERROR_NOMEM = -1,
+ /* Invalid character inside JSON string */
+ JSMN_ERROR_INVAL = -2,
+ /* The string is not a full JSON packet, more bytes expected */
+ JSMN_ERROR_PART = -3
+};
+
+/**
+ * JSON token description.
+ * @param type type (object, array, string etc.)
+ * @param start start position in JSON data string
+ * @param end end position in JSON data string
+ */
+typedef struct {
+ jsmntype_t type;
+ int start;
+ int end;
+ int size;
+#ifdef JSMN_PARENT_LINKS
+ int parent;
+#endif
+} jsmntok_t;
+
+/**
+ * JSON parser. Contains an array of token blocks available. Also stores
+ * the string being parsed now and current position in that string
+ */
+typedef struct {
+ unsigned int pos; /* offset in the JSON string */
+ unsigned int toknext; /* next token to allocate */
+ int toksuper; /* superior token node, e.g parent object or array */
+} jsmn_parser;
+
+/**
+ * Create JSON parser over an array of tokens
+ */
+void jsmn_init(jsmn_parser *parser);
+
+/**
+ * Run JSON parser. It parses a JSON data string into and array of tokens, each describing
+ * a single JSON object.
+ */
+int jsmn_parse(jsmn_parser *parser, const char *js, size_t len,
+ jsmntok_t *tokens, unsigned int num_tokens);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __JSMN_H_ */
diff --git a/jsonencode.tcl b/jsonencode.tcl
new file mode 100644
index 0000000..107ab1a
--- /dev/null
+++ b/jsonencode.tcl
@@ -0,0 +1,100 @@
+# Implements 'json::encode'
+#
+# (c) 2019 Steve Bennett <steveb@workware.net.au>
+#
+# See LICENCE in this directory for licensing.
+
+# Encode Tcl objects as JSON
+# dict -> object
+# list -> array
+# numeric -> number
+# string -> string
+#
+# The schema provides the type information for the value.
+# str = string
+# num = numeric (or null)
+# bool = boolean
+# obj ... = object. parameters are 'name' 'subschema' where the name matches the dict.
+# list ... = array. parameters are 'subschema' for the elements of the list/array.
+# mixed ... = array of mixed types. parameters are types for each element of the list/array.
+
+# Top level JSON encoder which encodes the given
+# value based on the schema
+proc json::encode {value {schema str}} {
+ json::encode.[lindex $schema 0] $value [lrange $schema 1 end]
+}
+
+# Encode a string
+proc json::encode.str {value {dummy {}}} {
+ # Strictly we should be converting \x00 through \x1F to unicode escapes
+ # And anything outside the BMP to a UTF-16 surrogate pair
+ return \"[string map [list \\ \\\\ \" \\" \f \\f \n \\n / \\/ \b \\b \r \\r \t \\t] $value]\"
+}
+
+# If no type is given, also encode as a string
+proc json::encode. {args} {
+ tailcall json::encode.str {*}$args
+}
+
+# Encode a number
+proc json::encode.num {value {dummy {}}} {
+ if {$value in {Inf -Inf}} {
+ append value inity
+ }
+ return $value
+}
+
+# Encode a boolean
+proc json::encode.bool {value {dummy {}}} {
+ if {$value} {
+ return true
+ }
+ return false
+}
+
+# Encode an object (dictionary)
+proc json::encode.obj {obj {schema {}}} {
+ set result "\{"
+ set sep " "
+ foreach k [lsort [dict keys $obj]] {
+ if {[dict exists $schema $k]} {
+ set type [dict get $schema $k]
+ } elseif {[dict exists $schema *]} {
+ set type [dict get $schema *]
+ } else {
+ set type str
+ }
+ append result $sep\"$k\":
+
+ append result [json::encode.[lindex $type 0] [dict get $obj $k] [lrange $type 1 end]]
+ set sep ", "
+ }
+ append result " \}"
+}
+
+# Encode an array (list)
+proc json::encode.list {list {type str}} {
+ set result "\["
+ set sep " "
+ foreach l $list {
+ append result $sep
+ append result [json::encode.[lindex $type 0] $l [lrange $type 1 end]]
+ set sep ", "
+ }
+ append result " \]"
+}
+
+# Encode a mixed-type array (list)
+# Must be as many types as there are elements of the list
+proc json::encode.mixed {list types} {
+ set result "\["
+ set sep " "
+ foreach l $list type $types {
+ append result $sep
+ append result [json::encode.[lindex $type 0] $l [lrange $type 1 end]]
+ set sep ", "
+ }
+ append result " \]"
+}
+
+# vim: se ts=4:
diff --git a/linenoise-win32.c b/linenoise-win32.c
new file mode 100644
index 0000000..dd15b94
--- /dev/null
+++ b/linenoise-win32.c
@@ -0,0 +1,375 @@
+
+/* this code is not standalone
+ * it is included into linenoise.c
+ * for windows.
+ * It is deliberately kept separate so that
+ * applications that have no need for windows
+ * support can omit this
+ */
+static DWORD orig_consolemode = 0;
+
+static int flushOutput(struct current *current);
+static void outputNewline(struct current *current);
+
+static void refreshStart(struct current *current)
+{
+}
+
+static void refreshEnd(struct current *current)
+{
+}
+
+static void refreshStartChars(struct current *current)
+{
+ assert(current->output == NULL);
+ /* We accumulate all output here */
+ current->output = sb_alloc();
+#ifdef USE_UTF8
+ current->ubuflen = 0;
+#endif
+}
+
+static void refreshNewline(struct current *current)
+{
+ DRL("<nl>");
+ outputNewline(current);
+}
+
+static void refreshEndChars(struct current *current)
+{
+ assert(current->output);
+ flushOutput(current);
+ sb_free(current->output);
+ current->output = NULL;
+}
+
+static int enableRawMode(struct current *current) {
+ DWORD n;
+ INPUT_RECORD irec;
+
+ current->outh = GetStdHandle(STD_OUTPUT_HANDLE);
+ current->inh = GetStdHandle(STD_INPUT_HANDLE);
+
+ if (!PeekConsoleInput(current->inh, &irec, 1, &n)) {
+ return -1;
+ }
+ if (getWindowSize(current) != 0) {
+ return -1;
+ }
+ if (GetConsoleMode(current->inh, &orig_consolemode)) {
+ SetConsoleMode(current->inh, ENABLE_PROCESSED_INPUT);
+ }
+#ifdef USE_UTF8
+ /* XXX is this the right thing to do? */
+ SetConsoleCP(65001);
+#endif
+ return 0;
+}
+
+static void disableRawMode(struct current *current)
+{
+ SetConsoleMode(current->inh, orig_consolemode);
+}
+
+void linenoiseClearScreen(void)
+{
+ /* XXX: This is ugly. Should just have the caller pass a handle */
+ struct current current;
+
+ current.outh = GetStdHandle(STD_OUTPUT_HANDLE);
+
+ if (getWindowSize(&current) == 0) {
+ COORD topleft = { 0, 0 };
+ DWORD n;
+
+ FillConsoleOutputCharacter(current.outh, ' ',
+ current.cols * current.rows, topleft, &n);
+ FillConsoleOutputAttribute(current.outh,
+ FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN,
+ current.cols * current.rows, topleft, &n);
+ SetConsoleCursorPosition(current.outh, topleft);
+ }
+}
+
+static void cursorToLeft(struct current *current)
+{
+ COORD pos;
+ DWORD n;
+
+ pos.X = 0;
+ pos.Y = (SHORT)current->y;
+
+ FillConsoleOutputAttribute(current->outh,
+ FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN, current->cols, pos, &n);
+ current->x = 0;
+}
+
+#ifdef USE_UTF8
+static void flush_ubuf(struct current *current)
+{
+ COORD pos;
+ DWORD nwritten;
+ pos.Y = (SHORT)current->y;
+ pos.X = (SHORT)current->x;
+ SetConsoleCursorPosition(current->outh, pos);
+ WriteConsoleW(current->outh, current->ubuf, current->ubuflen, &nwritten, 0);
+ current->x += current->ubufcols;
+ current->ubuflen = 0;
+ current->ubufcols = 0;
+}
+
+static void add_ubuf(struct current *current, int ch)
+{
+ /* This code originally by: Author: Mark E. Davis, 1994. */
+ static const int halfShift = 10; /* used for shifting by 10 bits */
+
+ static const DWORD halfBase = 0x0010000UL;
+ static const DWORD halfMask = 0x3FFUL;
+
+ #define UNI_SUR_HIGH_START 0xD800
+ #define UNI_SUR_HIGH_END 0xDBFF
+ #define UNI_SUR_LOW_START 0xDC00
+ #define UNI_SUR_LOW_END 0xDFFF
+
+ #define UNI_MAX_BMP 0x0000FFFF
+
+ if (ch > UNI_MAX_BMP) {
+ /* convert from unicode to utf16 surrogate pairs
+ * There is always space for one extra word in ubuf
+ */
+ ch -= halfBase;
+ current->ubuf[current->ubuflen++] = (WORD)((ch >> halfShift) + UNI_SUR_HIGH_START);
+ current->ubuf[current->ubuflen++] = (WORD)((ch & halfMask) + UNI_SUR_LOW_START);
+ }
+ else {
+ current->ubuf[current->ubuflen++] = ch;
+ }
+ current->ubufcols += utf8_width(ch);
+ if (current->ubuflen >= UBUF_MAX_CHARS) {
+ flush_ubuf(current);
+ }
+}
+#endif
+
+static int flushOutput(struct current *current)
+{
+ const char *pt = sb_str(current->output);
+ int len = sb_len(current->output);
+
+#ifdef USE_UTF8
+ /* convert utf8 in current->output into utf16 in current->ubuf
+ */
+ while (len) {
+ int ch;
+ int n = utf8_tounicode(pt, &ch);
+
+ pt += n;
+ len -= n;
+
+ add_ubuf(current, ch);
+ }
+ flush_ubuf(current);
+#else
+ DWORD nwritten;
+ COORD pos;
+
+ pos.Y = (SHORT)current->y;
+ pos.X = (SHORT)current->x;
+
+ SetConsoleCursorPosition(current->outh, pos);
+ WriteConsoleA(current->outh, pt, len, &nwritten, 0);
+
+ current->x += len;
+#endif
+
+ sb_clear(current->output);
+
+ return 0;
+}
+
+static int outputChars(struct current *current, const char *buf, int len)
+{
+ if (len < 0) {
+ len = strlen(buf);
+ }
+ assert(current->output);
+
+ sb_append_len(current->output, buf, len);
+
+ return 0;
+}
+
+static void outputNewline(struct current *current)
+{
+ /* On the last row output a newline to force a scroll */
+ if (current->y + 1 == current->rows) {
+ outputChars(current, "\n", 1);
+ }
+ flushOutput(current);
+ current->x = 0;
+ current->y++;
+}
+
+static void setOutputHighlight(struct current *current, const int *props, int nprops)
+{
+ int colour = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN;
+ int bold = 0;
+ int reverse = 0;
+ int i;
+
+ for (i = 0; i < nprops; i++) {
+ switch (props[i]) {
+ case 0:
+ colour = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN;
+ bold = 0;
+ reverse = 0;
+ break;
+ case 1:
+ bold = FOREGROUND_INTENSITY;
+ break;
+ case 7:
+ reverse = 1;
+ break;
+ case 30:
+ colour = 0;
+ break;
+ case 31:
+ colour = FOREGROUND_RED;
+ break;
+ case 32:
+ colour = FOREGROUND_GREEN;
+ break;
+ case 33:
+ colour = FOREGROUND_RED | FOREGROUND_GREEN;
+ break;
+ case 34:
+ colour = FOREGROUND_BLUE;
+ break;
+ case 35:
+ colour = FOREGROUND_RED | FOREGROUND_BLUE;
+ break;
+ case 36:
+ colour = FOREGROUND_BLUE | FOREGROUND_GREEN;
+ break;
+ case 37:
+ colour = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN;
+ break;
+ }
+ }
+
+ flushOutput(current);
+
+ if (reverse) {
+ SetConsoleTextAttribute(current->outh, BACKGROUND_INTENSITY);
+ }
+ else {
+ SetConsoleTextAttribute(current->outh, colour | bold);
+ }
+}
+
+static void eraseEol(struct current *current)
+{
+ COORD pos;
+ DWORD n;
+
+ pos.X = (SHORT) current->x;
+ pos.Y = (SHORT) current->y;
+
+ FillConsoleOutputCharacter(current->outh, ' ', current->cols - current->x, pos, &n);
+}
+
+static void setCursorXY(struct current *current)
+{
+ COORD pos;
+
+ pos.X = (SHORT) current->x;
+ pos.Y = (SHORT) current->y;
+
+ SetConsoleCursorPosition(current->outh, pos);
+}
+
+
+static void setCursorPos(struct current *current, int x)
+{
+ current->x = x;
+ setCursorXY(current);
+}
+
+static void cursorUp(struct current *current, int n)
+{
+ current->y -= n;
+ setCursorXY(current);
+}
+
+static void cursorDown(struct current *current, int n)
+{
+ current->y += n;
+ setCursorXY(current);
+}
+
+static int fd_read(struct current *current)
+{
+ while (1) {
+ INPUT_RECORD irec;
+ DWORD n;
+ if (WaitForSingleObject(current->inh, INFINITE) != WAIT_OBJECT_0) {
+ break;
+ }
+ if (!ReadConsoleInputW(current->inh, &irec, 1, &n)) {
+ break;
+ }
+ if (irec.EventType == KEY_EVENT) {
+ KEY_EVENT_RECORD *k = &irec.Event.KeyEvent;
+ if (k->bKeyDown || k->wVirtualKeyCode == VK_MENU) {
+ if (k->dwControlKeyState & ENHANCED_KEY) {
+ switch (k->wVirtualKeyCode) {
+ case VK_LEFT:
+ return SPECIAL_LEFT;
+ case VK_RIGHT:
+ return SPECIAL_RIGHT;
+ case VK_UP:
+ return SPECIAL_UP;
+ case VK_DOWN:
+ return SPECIAL_DOWN;
+ case VK_INSERT:
+ return SPECIAL_INSERT;
+ case VK_DELETE:
+ return SPECIAL_DELETE;
+ case VK_HOME:
+ return SPECIAL_HOME;
+ case VK_END:
+ return SPECIAL_END;
+ case VK_PRIOR:
+ return SPECIAL_PAGE_UP;
+ case VK_NEXT:
+ return SPECIAL_PAGE_DOWN;
+ }
+ }
+ /* Note that control characters are already translated in AsciiChar */
+ else if (k->wVirtualKeyCode == VK_CONTROL)
+ continue;
+ else {
+ return k->uChar.UnicodeChar;
+ }
+ }
+ }
+ }
+ return -1;
+}
+
+static int getWindowSize(struct current *current)
+{
+ CONSOLE_SCREEN_BUFFER_INFO info;
+ if (!GetConsoleScreenBufferInfo(current->outh, &info)) {
+ return -1;
+ }
+ current->cols = info.dwSize.X;
+ current->rows = info.dwSize.Y;
+ if (current->cols <= 0 || current->rows <= 0) {
+ current->cols = 80;
+ return -1;
+ }
+ current->y = info.dwCursorPosition.Y;
+ current->x = info.dwCursorPosition.X;
+ return 0;
+}
diff --git a/linenoise.c b/linenoise.c
index e805356..1c01853 100644
--- a/linenoise.c
+++ b/linenoise.c
@@ -1,3 +1,300 @@
+#ifndef STRINGBUF_H
+#define STRINGBUF_H
+
+/* (c) 2017 Workware Systems Pty Ltd -- All Rights Reserved */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @file
+ * A stringbuf is a resizing, null terminated string buffer.
+ *
+ * The buffer is reallocated as necessary.
+ *
+ * In general it is *not* OK to call these functions with a NULL pointer
+ * unless stated otherwise.
+ *
+ * If USE_UTF8 is defined, supports utf8.
+ */
+
+/**
+ * The stringbuf structure should not be accessed directly.
+ * Use the functions below.
+ */
+typedef struct {
+ int remaining; /**< Allocated, but unused space */
+ int last; /**< Index of the null terminator (and thus the length of the string) */
+#ifdef USE_UTF8
+ int chars; /**< Count of characters */
+#endif
+ char *data; /**< Allocated memory containing the string or NULL for empty */
+} stringbuf;
+
+/**
+ * Allocates and returns a new stringbuf with no elements.
+ */
+stringbuf *sb_alloc(void);
+
+/**
+ * Frees a stringbuf.
+ * It is OK to call this with NULL.
+ */
+void sb_free(stringbuf *sb);
+
+/**
+ * Returns an allocated copy of the stringbuf
+ */
+stringbuf *sb_copy(stringbuf *sb);
+
+/**
+ * Returns the length of the buffer.
+ *
+ * Returns 0 for both a NULL buffer and an empty buffer.
+ */
+static inline int sb_len(stringbuf *sb) {
+ return sb->last;
+}
+
+/**
+ * Returns the utf8 character length of the buffer.
+ *
+ * Returns 0 for both a NULL buffer and an empty buffer.
+ */
+static inline int sb_chars(stringbuf *sb) {
+#ifdef USE_UTF8
+ return sb->chars;
+#else
+ return sb->last;
+#endif
+}
+
+/**
+ * Appends a null terminated string to the stringbuf
+ */
+void sb_append(stringbuf *sb, const char *str);
+
+/**
+ * Like sb_append() except does not require a null terminated string.
+ * The length of 'str' is given as 'len'
+ *
+ * Note that in utf8 mode, characters will *not* be counted correctly
+ * if a partial utf8 sequence is added with sb_append_len()
+ */
+void sb_append_len(stringbuf *sb, const char *str, int len);
+
+/**
+ * Returns a pointer to the null terminated string in the buffer.
+ *
+ * Note this pointer only remains valid until the next modification to the
+ * string buffer.
+ *
+ * The returned pointer can be used to update the buffer in-place
+ * as long as care is taken to not overwrite the end of the buffer.
+ */
+static inline char *sb_str(const stringbuf *sb)
+{
+ return sb->data;
+}
+
+/**
+ * Inserts the given string *before* (zero-based) 'index' in the stringbuf.
+ * If index is past the end of the buffer, the string is appended,
+ * just like sb_append()
+ */
+void sb_insert(stringbuf *sb, int index, const char *str);
+
+/**
+ * Delete 'len' bytes in the string at the given index.
+ *
+ * Any bytes past the end of the buffer are ignored.
+ * The buffer remains null terminated.
+ *
+ * If len is -1, deletes to the end of the buffer.
+ */
+void sb_delete(stringbuf *sb, int index, int len);
+
+/**
+ * Clear to an empty buffer.
+ */
+void sb_clear(stringbuf *sb);
+
+/**
+ * Return an allocated copy of buffer and frees 'sb'.
+ *
+ * If 'sb' is empty, returns an allocated copy of "".
+ */
+char *sb_to_string(stringbuf *sb);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <assert.h>
+
+#ifndef STRINGBUF_H
+#include "stringbuf.h"
+#endif
+#ifdef USE_UTF8
+#include "utf8.h"
+#endif
+
+#define SB_INCREMENT 200
+
+stringbuf *sb_alloc(void)
+{
+ stringbuf *sb = (stringbuf *)malloc(sizeof(*sb));
+ sb->remaining = 0;
+ sb->last = 0;
+#ifdef USE_UTF8
+ sb->chars = 0;
+#endif
+ sb->data = NULL;
+
+ return(sb);
+}
+
+void sb_free(stringbuf *sb)
+{
+ if (sb) {
+ free(sb->data);
+ }
+ free(sb);
+}
+
+void sb_realloc(stringbuf *sb, int newlen)
+{
+ sb->data = (char *)realloc(sb->data, newlen);
+ sb->remaining = newlen - sb->last;
+}
+
+void sb_append(stringbuf *sb, const char *str)
+{
+ sb_append_len(sb, str, strlen(str));
+}
+
+void sb_append_len(stringbuf *sb, const char *str, int len)
+{
+ if (sb->remaining < len + 1) {
+ sb_realloc(sb, sb->last + len + 1 + SB_INCREMENT);
+ }
+ memcpy(sb->data + sb->last, str, len);
+ sb->data[sb->last + len] = 0;
+
+ sb->last += len;
+ sb->remaining -= len;
+#ifdef USE_UTF8
+ sb->chars += utf8_strlen(str, len);
+#endif
+}
+
+char *sb_to_string(stringbuf *sb)
+{
+ if (sb->data == NULL) {
+ /* Return an allocated empty string, not null */
+ return strdup("");
+ }
+ else {
+ /* Just return the data and free the stringbuf structure */
+ char *pt = sb->data;
+ free(sb);
+ return pt;
+ }
+}
+
+/* Insert and delete operations */
+
+/* Moves up all the data at position 'pos' and beyond by 'len' bytes
+ * to make room for new data
+ *
+ * Note: Does *not* update sb->chars
+ */
+static void sb_insert_space(stringbuf *sb, int pos, int len)
+{
+ assert(pos <= sb->last);
+
+ /* Make sure there is enough space */
+ if (sb->remaining < len) {
+ sb_realloc(sb, sb->last + len + SB_INCREMENT);
+ }
+ /* Now move it up */
+ memmove(sb->data + pos + len, sb->data + pos, sb->last - pos);
+ sb->last += len;
+ sb->remaining -= len;
+ /* And null terminate */
+ sb->data[sb->last] = 0;
+}
+
+/**
+ * Move down all the data from pos + len, effectively
+ * deleting the data at position 'pos' of length 'len'
+ */
+static void sb_delete_space(stringbuf *sb, int pos, int len)
+{
+ assert(pos < sb->last);
+ assert(pos + len <= sb->last);
+
+#ifdef USE_UTF8
+ sb->chars -= utf8_strlen(sb->data + pos, len);
+#endif
+
+ /* Now move it up */
+ memmove(sb->data + pos, sb->data + pos + len, sb->last - pos - len);
+ sb->last -= len;
+ sb->remaining += len;
+ /* And null terminate */
+ sb->data[sb->last] = 0;
+}
+
+void sb_insert(stringbuf *sb, int index, const char *str)
+{
+ if (index >= sb->last) {
+ /* Inserting after the end of the list appends. */
+ sb_append(sb, str);
+ }
+ else {
+ int len = strlen(str);
+
+ sb_insert_space(sb, index, len);
+ memcpy(sb->data + index, str, len);
+#ifdef USE_UTF8
+ sb->chars += utf8_strlen(str, len);
+#endif
+ }
+}
+
+/**
+ * Delete the bytes at index 'index' for length 'len'
+ * Has no effect if the index is past the end of the list.
+ */
+void sb_delete(stringbuf *sb, int index, int len)
+{
+ if (index < sb->last) {
+ char *pos = sb->data + index;
+ if (len < 0) {
+ len = sb->last;
+ }
+
+ sb_delete_space(sb, pos - sb->data, len);
+ }
+}
+
+void sb_clear(stringbuf *sb)
+{
+ if (sb->data) {
+ /* Null terminate */
+ sb->data[0] = 0;
+ sb->last = 0;
+#ifdef USE_UTF8
+ sb->chars = 0;
+#endif
+ }
+}
/* linenoise.c -- guerrilla line editing library against the idea that a
* line editing lib needs to be 20,000 lines of C code.
*
@@ -57,14 +354,12 @@
* the more compatible.
*
* EL (Erase Line)
- * Sequence: ESC [ n K
- * Effect: if n is 0 or missing, clear from cursor to end of line
- * Effect: if n is 1, clear from beginning of line to cursor
- * Effect: if n is 2, clear entire line
+ * Sequence: ESC [ 0 K
+ * Effect: clear from cursor to end of line
*
* CUF (CUrsor Forward)
* Sequence: ESC [ n C
- * Effect: moves cursor forward of n chars
+ * Effect: moves cursor forward n chars
*
* CR (Carriage Return)
* Sequence: \r
@@ -95,6 +390,15 @@
* Sequence: ESC [ 6 n
* Effect: reports current cursor position as ESC [ NNN ; MMM R
*
+ * == Only used in multiline mode ==
+ * CUU (Cursor Up)
+ * Sequence: ESC [ n A
+ * Effect: moves cursor up n chars.
+ *
+ * CUD (Cursor Down)
+ * Sequence: ESC [ n B
+ * Effect: moves cursor down n chars.
+ *
* win32/console
* -------------
* If __MINGW32__ is defined, the win32 console API is used.
@@ -116,7 +420,7 @@
#else
#include <termios.h>
#include <sys/ioctl.h>
-#include <sys/poll.h>
+#include <poll.h>
#define USE_TERMIOS
#define HAVE_UNISTD_H
#endif
@@ -127,27 +431,27 @@
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
+#include <assert.h>
#include <errno.h>
#include <string.h>
+#include <signal.h>
#include <stdlib.h>
#include <sys/types.h>
#include "linenoise.h"
-
-#include "jim-config.h"
-#ifdef JIM_UTF8
-#define USE_UTF8
+#ifndef STRINGBUF_H
+#include "stringbuf.h"
#endif
#include "utf8.h"
#define LINENOISE_DEFAULT_HISTORY_MAX_LEN 100
-#define LINENOISE_MAX_LINE 4096
#define ctrl(C) ((C) - '@')
/* Use -ve numbers here to co-exist with normal unicode chars */
enum {
SPECIAL_NONE,
+ /* don't use -1 here since that indicates error */
SPECIAL_UP = -20,
SPECIAL_DOWN = -21,
SPECIAL_LEFT = -22,
@@ -157,7 +461,11 @@ enum {
SPECIAL_END = -26,
SPECIAL_INSERT = -27,
SPECIAL_PAGE_UP = -28,
- SPECIAL_PAGE_DOWN = -29
+ SPECIAL_PAGE_DOWN = -29,
+
+ /* Some handy names for other special keycodes */
+ CHAR_ESCAPE = 27,
+ CHAR_DELETE = 127,
};
static int history_max_len = LINENOISE_DEFAULT_HISTORY_MAX_LEN;
@@ -166,14 +474,16 @@ static char **history = NULL;
/* Structure to contain the status of the current (being edited) line */
struct current {
- char *buf; /* Current buffer. Always null terminated */
- int bufmax; /* Size of the buffer, including space for the null termination */
- int len; /* Number of bytes in 'buf' */
- int chars; /* Number of chars in 'buf' (utf-8 chars) */
+ stringbuf *buf; /* Current buffer. Always null terminated */
int pos; /* Cursor position, measured in chars */
int cols; /* Size of the window, in chars */
+ int nrows; /* How many rows are being used in multiline mode (>= 1) */
+ int rpos; /* The current row containing the cursor - multiline mode only */
+ int colsright; /* refreshLine() cached cols for insert_char() optimisation */
+ int colsleft; /* refreshLine() cached cols for remove_char() optimisation */
const char *prompt;
- char *capture; /* Allocated capture buffer, or NULL for none. Always null terminated */
+ stringbuf *capture; /* capture buffer, or NULL for none. Always null terminated */
+ stringbuf *output; /* used only during refreshLine() - output accumulator */
#if defined(USE_TERMIOS)
int fd; /* Terminal fd */
#elif defined(USE_WINCONSOLE)
@@ -182,11 +492,25 @@ struct current {
int rows; /* Screen rows */
int x; /* Current column during output */
int y; /* Current row */
+#ifdef USE_UTF8
+ #define UBUF_MAX_CHARS 132
+ WORD ubuf[UBUF_MAX_CHARS + 1]; /* Accumulates utf16 output - one extra for final surrogate pairs */
+ int ubuflen; /* length used in ubuf */
+ int ubufcols; /* how many columns are represented by the chars in ubuf? */
+#endif
#endif
};
static int fd_read(struct current *current);
static int getWindowSize(struct current *current);
+static void cursorDown(struct current *current, int n);
+static void cursorUp(struct current *current, int n);
+static void eraseEol(struct current *current);
+static void refreshLine(struct current *current);
+static void refreshLineAlt(struct current *current, const char *prompt, const char *buf, int cursor_pos);
+static void setCursorPos(struct current *current, int x);
+static void setOutputHighlight(struct current *current, const int *props, int nprops);
+static void set_current(struct current *current, const char *str);
void linenoiseHistoryFree(void) {
if (history) {
@@ -200,13 +524,137 @@ void linenoiseHistoryFree(void) {
}
}
+struct esc_parser {
+ enum {
+ EP_START, /* looking for ESC */
+ EP_ESC, /* looking for [ */
+ EP_DIGITS, /* parsing digits */
+ EP_PROPS, /* parsing digits or semicolons */
+ EP_END, /* ok */
+ EP_ERROR, /* error */
+ } state;
+ int props[5]; /* properties are stored here */
+ int maxprops; /* size of the props[] array */
+ int numprops; /* number of properties found */
+ int termchar; /* terminator char, or 0 for any alpha */
+ int current; /* current (partial) property value */
+};
+
+/**
+ * Initialise the escape sequence parser at *parser.
+ *
+ * If termchar is 0 any alpha char terminates ok. Otherwise only the given
+ * char terminates successfully.
+ * Run the parser state machine with calls to parseEscapeSequence() for each char.
+ */
+static void initParseEscapeSeq(struct esc_parser *parser, int termchar)
+{
+ parser->state = EP_START;
+ parser->maxprops = sizeof(parser->props) / sizeof(*parser->props);
+ parser->numprops = 0;
+ parser->current = 0;
+ parser->termchar = termchar;
+}
+
+/**
+ * Pass character 'ch' into the state machine to parse:
+ * 'ESC' '[' <digits> (';' <digits>)* <termchar>
+ *
+ * The first character must be ESC.
+ * Returns the current state. The state machine is done when it returns either EP_END
+ * or EP_ERROR.
+ *
+ * On EP_END, the "property/attribute" values can be read from parser->props[]
+ * of length parser->numprops.
+ */
+static int parseEscapeSequence(struct esc_parser *parser, int ch)
+{
+ switch (parser->state) {
+ case EP_START:
+ parser->state = (ch == '\x1b') ? EP_ESC : EP_ERROR;
+ break;
+ case EP_ESC:
+ parser->state = (ch == '[') ? EP_DIGITS : EP_ERROR;
+ break;
+ case EP_PROPS:
+ if (ch == ';') {
+ parser->state = EP_DIGITS;
+donedigits:
+ if (parser->numprops + 1 < parser->maxprops) {
+ parser->props[parser->numprops++] = parser->current;
+ parser->current = 0;
+ }
+ break;
+ }
+ /* fall through */
+ case EP_DIGITS:
+ if (ch >= '0' && ch <= '9') {
+ parser->current = parser->current * 10 + (ch - '0');
+ parser->state = EP_PROPS;
+ break;
+ }
+ /* must be terminator */
+ if (parser->termchar != ch) {
+ if (parser->termchar != 0 || !((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'))) {
+ parser->state = EP_ERROR;
+ break;
+ }
+ }
+ parser->state = EP_END;
+ goto donedigits;
+ case EP_END:
+ parser->state = EP_ERROR;
+ break;
+ case EP_ERROR:
+ break;
+ }
+ return parser->state;
+}
+
+/*#define DEBUG_REFRESHLINE*/
+
+#ifdef DEBUG_REFRESHLINE
+#define DRL(ARGS...) fprintf(dfh, ARGS)
+static FILE *dfh;
+
+static void DRL_CHAR(int ch)
+{
+ if (ch < ' ') {
+ DRL("^%c", ch + '@');
+ }
+ else if (ch > 127) {
+ DRL("\\u%04x", ch);
+ }
+ else {
+ DRL("%c", ch);
+ }
+}
+static void DRL_STR(const char *str)
+{
+ while (*str) {
+ int ch;
+ int n = utf8_tounicode(str, &ch);
+ str += n;
+ DRL_CHAR(ch);
+ }
+}
+#else
+#define DRL(ARGS...)
+#define DRL_CHAR(ch)
+#define DRL_STR(str)
+#endif
+
+#if defined(USE_WINCONSOLE)
+#include "linenoise-win32.c"
+#endif
+
#if defined(USE_TERMIOS)
static void linenoiseAtExit(void);
static struct termios orig_termios; /* in order to restore at exit */
static int rawmode = 0; /* for atexit() function to check if restore is needed*/
static int atexit_registered = 0; /* register atexit just 1 time */
-static const char *unsupported_term[] = {"dumb","cons25",NULL};
+static const char *unsupported_term[] = {"dumb","cons25","emacs",NULL};
static int isUnsupportedTerm(void) {
char *term = getenv("TERM");
@@ -226,6 +674,7 @@ static int enableRawMode(struct current *current) {
struct termios raw;
current->fd = STDIN_FILENO;
+ current->cols = 0;
if (!isatty(current->fd) || isUnsupportedTerm() ||
tcgetattr(current->fd, &orig_termios) == -1) {
@@ -243,8 +692,8 @@ fatal:
/* input modes: no break, no CR to NL, no parity check, no strip char,
* no start/stop output control. */
raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
- /* output modes - disable post processing */
- raw.c_oflag &= ~(OPOST);
+ /* output modes - actually, no need to disable post processing */
+ /*raw.c_oflag &= ~(OPOST);*/
/* control modes - set 8 bit chars */
raw.c_cflag |= (CS8);
/* local modes - choing off, canonical off, no extended functions,
@@ -259,8 +708,6 @@ fatal:
goto fatal;
}
rawmode = 1;
-
- current->cols = 0;
return 0;
}
@@ -284,10 +731,25 @@ static void linenoiseAtExit(void) {
*/
#define IGNORE_RC(EXPR) if (EXPR) {}
-/* This is fdprintf() on some systems, but use a different
- * name to avoid conflicts
+/**
+ * Output bytes directly, or accumulate output (if current->output is set)
+ */
+static void outputChars(struct current *current, const char *buf, int len)
+{
+ if (len < 0) {
+ len = strlen(buf);
+ }
+ if (current->output) {
+ sb_append_len(current->output, buf, len);
+ }
+ else {
+ IGNORE_RC(write(current->fd, buf, len));
+ }
+}
+
+/* Like outputChars, but using printf-style formatting
*/
-static void fd_printf(int fd, const char *format, ...)
+static void outputFormatted(struct current *current, const char *format, ...)
{
va_list args;
char buf[64];
@@ -295,38 +757,58 @@ static void fd_printf(int fd, const char *format, ...)
va_start(args, format);
n = vsnprintf(buf, sizeof(buf), format, args);
+ /* This will never happen because we are sure to use outputFormatted() only for short sequences */
+ assert(n < (int)sizeof(buf));
va_end(args);
- IGNORE_RC(write(fd, buf, n));
+ outputChars(current, buf, n);
}
-static void clearScreen(struct current *current)
+static void cursorToLeft(struct current *current)
{
- fd_printf(current->fd, "\x1b[H\x1b[2J");
+ outputChars(current, "\r", -1);
}
-static void cursorToLeft(struct current *current)
+static void setOutputHighlight(struct current *current, const int *props, int nprops)
{
- fd_printf(current->fd, "\r");
+ outputChars(current, "\x1b[", -1);
+ while (nprops--) {
+ outputFormatted(current, "%d%c", *props, (nprops == 0) ? 'm' : ';');
+ props++;
+ }
}
-static int outputChars(struct current *current, const char *buf, int len)
+static void eraseEol(struct current *current)
{
- return write(current->fd, buf, len);
+ outputChars(current, "\x1b[0K", -1);
}
-static void outputControlChar(struct current *current, char ch)
+static void setCursorPos(struct current *current, int x)
{
- fd_printf(current->fd, "\x1b[7m^%c\x1b[0m", ch);
+ if (x == 0) {
+ cursorToLeft(current);
+ }
+ else {
+ outputFormatted(current, "\r\x1b[%dC", x);
+ }
}
-static void eraseEol(struct current *current)
+static void cursorUp(struct current *current, int n)
{
- fd_printf(current->fd, "\x1b[0K");
+ if (n) {
+ outputFormatted(current, "\x1b[%dA", n);
+ }
}
-static void setCursorPos(struct current *current, int x)
+static void cursorDown(struct current *current, int n)
+{
+ if (n) {
+ outputFormatted(current, "\x1b[%dB", n);
+ }
+}
+
+void linenoiseClearScreen(void)
{
- fd_printf(current->fd, "\r\x1b[%dC", x);
+ IGNORE_RC(write(STDOUT_FILENO, "\x1b[H\x1b[2J", 7));
}
/**
@@ -361,7 +843,7 @@ static int fd_read_char(int fd, int timeout)
static int fd_read(struct current *current)
{
#ifdef USE_UTF8
- char buf[4];
+ char buf[MAX_UTF8_LEN];
int n;
int i;
int c;
@@ -370,7 +852,7 @@ static int fd_read(struct current *current)
return -1;
}
n = utf8_charlen(buf[0]);
- if (n < 1 || n > 3) {
+ if (n < 1) {
return -1;
}
for (i = 1; i < n; i++) {
@@ -378,7 +860,6 @@ static int fd_read(struct current *current)
return -1;
}
}
- buf[n] = 0;
/* decode and return the character */
utf8_tounicode(buf, &c);
return c;
@@ -387,58 +868,46 @@ static int fd_read(struct current *current)
#endif
}
-static int countColorControlChars(const char* prompt)
+
+/**
+ * Stores the current cursor column in '*cols'.
+ * Returns 1 if OK, or 0 if failed to determine cursor pos.
+ */
+static int queryCursor(struct current *current, int* cols)
{
- /* ANSI color control sequences have the form:
- * "\x1b" "[" [0-9;]* "m"
- * We parse them with a simple state machine.
- */
+ struct esc_parser parser;
+ int ch;
- enum {
- search_esc,
- expect_bracket,
- expect_trail
- } state = search_esc;
- int len = 0, found = 0;
- char ch;
-
- /* XXX: Strictly we should be checking utf8 chars rather than
- * bytes in case of the extremely unlikely scenario where
- * an ANSI sequence is part of a utf8 sequence.
- */
- while ((ch = *prompt++) != 0) {
- switch (state) {
- case search_esc:
- if (ch == '\x1b') {
- state = expect_bracket;
- }
- break;
- case expect_bracket:
- if (ch == '[') {
- state = expect_trail;
- /* 3 for "\e[ ... m" */
- len = 3;
+ /* Should not be buffering this output, it needs to go immediately */
+ assert(current->output == NULL);
+
+ /* control sequence - report cursor location */
+ outputChars(current, "\x1b[6n", -1);
+
+ /* Parse the response: ESC [ rows ; cols R */
+ initParseEscapeSeq(&parser, 'R');
+ while ((ch = fd_read_char(current->fd, 100)) > 0) {
+ switch (parseEscapeSequence(&parser, ch)) {
+ default:
+ continue;
+ case EP_END:
+ if (parser.numprops == 2 && parser.props[1] < 1000) {
+ *cols = parser.props[1];
+ return 1;
+ }
break;
- }
- state = search_esc;
- break;
- case expect_trail:
- if ((ch == ';') || ((ch >= '0' && ch <= '9'))) {
- /* 0-9, or semicolon */
- len++;
+ case EP_ERROR:
break;
- }
- if (ch == 'm') {
- found += len;
- }
- state = search_esc;
- break;
}
+ /* failed */
+ break;
}
-
- return found;
+ return 0;
}
+/**
+ * Updates current->cols with the current window size (width)
+ */
static int getWindowSize(struct current *current)
{
struct winsize ws;
@@ -453,49 +922,51 @@ static int getWindowSize(struct current *current)
* and reading back the cursor position.
* Note that this is only done once per call to linenoise rather than
* every time the line is refreshed for efficiency reasons.
+ *
+ * In more detail, we:
+ * (a) request current cursor position,
+ * (b) move cursor far right,
+ * (c) request cursor position again,
+ * (d) at last move back to the old position.
+ * This gives us the width without messing with the externally
+ * visible cursor position.
*/
+
if (current->cols == 0) {
+ int here;
+
+ /* If anything fails => default 80 */
current->cols = 80;
- /* Move cursor far right and report cursor position, then back to the left */
- fd_printf(current->fd, "\x1b[999C" "\x1b[6n");
-
- /* Parse the response: ESC [ rows ; cols R */
- if (fd_read_char(current->fd, 100) == 0x1b && fd_read_char(current->fd, 100) == '[') {
- int n = 0;
- while (1) {
- int ch = fd_read_char(current->fd, 100);
- if (ch == ';') {
- /* Ignore rows */
- n = 0;
- }
- else if (ch == 'R') {
- /* Got cols */
- if (n != 0 && n < 1000) {
- current->cols = n;
- }
- break;
- }
- else if (ch >= 0 && ch <= '9') {
- n = n * 10 + ch - '0';
- }
- else {
- break;
+ /* (a) */
+ if (queryCursor (current, &here)) {
+ /* (b) */
+ setCursorPos(current, 999);
+
+ /* (c). Note: If (a) succeeded, then (c) should as well.
+ * For paranoia we still check and have a fallback action
+ * for (d) in case of failure..
+ */
+ if (queryCursor (current, &current->cols)) {
+ /* (d) Reset the cursor back to the original location. */
+ if (current->cols > here) {
+ setCursorPos(current, here);
}
}
}
}
+
return 0;
}
/**
- * If escape (27) was received, reads subsequent
+ * If CHAR_ESCAPE was received, reads subsequent
* chars to determine if this is a known special key.
*
* Returns SPECIAL_NONE if unrecognised, or -1 if EOF.
*
* If no additional char is received within a short time,
- * 27 is returned.
+ * CHAR_ESCAPE is returned.
*/
static int check_special(int fd)
{
@@ -503,7 +974,7 @@ static int check_special(int fd)
int c2;
if (c < 0) {
- return 27;
+ return CHAR_ESCAPE;
}
c2 = fd_read_char(fd, 50);
@@ -554,295 +1025,543 @@ static int check_special(int fd)
return SPECIAL_NONE;
}
-#elif defined(USE_WINCONSOLE)
+#endif
-static DWORD orig_consolemode = 0;
+static void clearOutputHighlight(struct current *current)
+{
+ int nohighlight = 0;
+ setOutputHighlight(current, &nohighlight, 1);
+}
-static int enableRawMode(struct current *current) {
- DWORD n;
- INPUT_RECORD irec;
+static void outputControlChar(struct current *current, char ch)
+{
+ int reverse = 7;
+ setOutputHighlight(current, &reverse, 1);
+ outputChars(current, "^", 1);
+ outputChars(current, &ch, 1);
+ clearOutputHighlight(current);
+}
- current->outh = GetStdHandle(STD_OUTPUT_HANDLE);
- current->inh = GetStdHandle(STD_INPUT_HANDLE);
+#ifndef utf8_getchars
+static int utf8_getchars(char *buf, int c)
+{
+#ifdef USE_UTF8
+ return utf8_fromunicode(buf, c);
+#else
+ *buf = c;
+ return 1;
+#endif
+}
+#endif
- if (!PeekConsoleInput(current->inh, &irec, 1, &n)) {
- return -1;
- }
- if (getWindowSize(current) != 0) {
- return -1;
- }
- if (GetConsoleMode(current->inh, &orig_consolemode)) {
- SetConsoleMode(current->inh, ENABLE_PROCESSED_INPUT);
+/**
+ * Returns the unicode character at the given offset,
+ * or -1 if none.
+ */
+static int get_char(struct current *current, int pos)
+{
+ if (pos >= 0 && pos < sb_chars(current->buf)) {
+ int c;
+ int i = utf8_index(sb_str(current->buf), pos);
+ (void)utf8_tounicode(sb_str(current->buf) + i, &c);
+ return c;
}
- return 0;
+ return -1;
}
-static void disableRawMode(struct current *current)
+static int char_display_width(int ch)
{
- SetConsoleMode(current->inh, orig_consolemode);
+ if (ch < ' ') {
+ /* control chars take two positions */
+ return 2;
+ }
+ else {
+ return utf8_width(ch);
+ }
}
-static void clearScreen(struct current *current)
-{
- COORD topleft = { 0, 0 };
- DWORD n;
+#ifndef NO_COMPLETION
+static linenoiseCompletionCallback *completionCallback = NULL;
+static void *completionUserdata = NULL;
+static int showhints = 1;
+static linenoiseHintsCallback *hintsCallback = NULL;
+static linenoiseFreeHintsCallback *freeHintsCallback = NULL;
+static void *hintsUserdata = NULL;
- FillConsoleOutputCharacter(current->outh, ' ',
- current->cols * current->rows, topleft, &n);
- FillConsoleOutputAttribute(current->outh,
- FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN,
- current->cols * current->rows, topleft, &n);
- SetConsoleCursorPosition(current->outh, topleft);
+static void beep() {
+#ifdef USE_TERMIOS
+ fprintf(stderr, "\x7");
+ fflush(stderr);
+#endif
}
-static void cursorToLeft(struct current *current)
-{
- COORD pos = { 0, (SHORT)current->y };
- DWORD n;
-
- FillConsoleOutputAttribute(current->outh,
- FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN, current->cols, pos, &n);
- current->x = 0;
+static void freeCompletions(linenoiseCompletions *lc) {
+ size_t i;
+ for (i = 0; i < lc->len; i++)
+ free(lc->cvec[i]);
+ free(lc->cvec);
}
-static int outputChars(struct current *current, const char *buf, int len)
-{
- COORD pos = { (SHORT)current->x, (SHORT)current->y };
- DWORD n;
+static int completeLine(struct current *current) {
+ linenoiseCompletions lc = { 0, NULL };
+ int c = 0;
- WriteConsoleOutputCharacter(current->outh, buf, len, pos, &n);
- current->x += len;
- return 0;
-}
+ completionCallback(sb_str(current->buf),&lc,completionUserdata);
+ if (lc.len == 0) {
+ beep();
+ } else {
+ size_t stop = 0, i = 0;
-static void outputControlChar(struct current *current, char ch)
-{
- COORD pos = { (SHORT)current->x, (SHORT)current->y };
- DWORD n;
+ while(!stop) {
+ /* Show completion or original buffer */
+ if (i < lc.len) {
+ int chars = utf8_strlen(lc.cvec[i], -1);
+ refreshLineAlt(current, current->prompt, lc.cvec[i], chars);
+ } else {
+ refreshLine(current);
+ }
- FillConsoleOutputAttribute(current->outh, BACKGROUND_INTENSITY, 2, pos, &n);
- outputChars(current, "^", 1);
- outputChars(current, &ch, 1);
+ c = fd_read(current);
+ if (c == -1) {
+ break;
+ }
+
+ switch(c) {
+ case '\t': /* tab */
+ i = (i+1) % (lc.len+1);
+ if (i == lc.len) beep();
+ break;
+ case CHAR_ESCAPE: /* escape */
+ /* Re-show original buffer */
+ if (i < lc.len) {
+ refreshLine(current);
+ }
+ stop = 1;
+ break;
+ default:
+ /* Update buffer and return */
+ if (i < lc.len) {
+ set_current(current,lc.cvec[i]);
+ }
+ stop = 1;
+ break;
+ }
+ }
+ }
+
+ freeCompletions(&lc);
+ return c; /* Return last read character */
}
-static void eraseEol(struct current *current)
-{
- COORD pos = { (SHORT)current->x, (SHORT)current->y };
- DWORD n;
+/* Register a callback function to be called for tab-completion.
+ Returns the prior callback so that the caller may (if needed)
+ restore it when done. */
+linenoiseCompletionCallback * linenoiseSetCompletionCallback(linenoiseCompletionCallback *fn, void *userdata) {
+ linenoiseCompletionCallback * old = completionCallback;
+ completionCallback = fn;
+ completionUserdata = userdata;
+ return old;
+}
- FillConsoleOutputCharacter(current->outh, ' ', current->cols - current->x, pos, &n);
+void linenoiseAddCompletion(linenoiseCompletions *lc, const char *str) {
+ lc->cvec = (char **)realloc(lc->cvec,sizeof(char*)*(lc->len+1));
+ lc->cvec[lc->len++] = strdup(str);
}
-static void setCursorPos(struct current *current, int x)
+void linenoiseSetHintsCallback(linenoiseHintsCallback *callback, void *userdata)
{
- COORD pos = { (SHORT)x, (SHORT)current->y };
+ hintsCallback = callback;
+ hintsUserdata = userdata;
+}
- SetConsoleCursorPosition(current->outh, pos);
- current->x = x;
+void linenoiseSetFreeHintsCallback(linenoiseFreeHintsCallback *callback)
+{
+ freeHintsCallback = callback;
}
-static int fd_read(struct current *current)
+#endif
+
+
+static const char *reduceSingleBuf(const char *buf, int availcols, int *cursor_pos)
{
- while (1) {
- INPUT_RECORD irec;
- DWORD n;
- if (WaitForSingleObject(current->inh, INFINITE) != WAIT_OBJECT_0) {
- break;
+ /* We have availcols columns available.
+ * If necessary, strip chars off the front of buf until *cursor_pos
+ * fits within availcols
+ */
+ int needcols = 0;
+ int pos = 0;
+ int new_cursor_pos = *cursor_pos;
+ const char *pt = buf;
+
+ DRL("reduceSingleBuf: availcols=%d, cursor_pos=%d\n", availcols, *cursor_pos);
+
+ while (*pt) {
+ int ch;
+ int n = utf8_tounicode(pt, &ch);
+ pt += n;
+
+ needcols += char_display_width(ch);
+
+ /* If we need too many cols, strip
+ * chars off the front of buf to make it fit.
+ * We keep 3 extra cols to the right of the cursor.
+ * 2 for possible wide chars, 1 for the last column that
+ * can't be used.
+ */
+ while (needcols >= availcols - 3) {
+ n = utf8_tounicode(buf, &ch);
+ buf += n;
+ needcols -= char_display_width(ch);
+ DRL_CHAR(ch);
+
+ /* and adjust the apparent cursor position */
+ new_cursor_pos--;
+
+ if (buf == pt) {
+ /* can't remove more than this */
+ break;
+ }
}
- if (!ReadConsoleInput (current->inh, &irec, 1, &n)) {
+
+ if (pos++ == *cursor_pos) {
break;
}
- if (irec.EventType == KEY_EVENT && irec.Event.KeyEvent.bKeyDown) {
- KEY_EVENT_RECORD *k = &irec.Event.KeyEvent;
- if (k->dwControlKeyState & ENHANCED_KEY) {
- switch (k->wVirtualKeyCode) {
- case VK_LEFT:
- return SPECIAL_LEFT;
- case VK_RIGHT:
- return SPECIAL_RIGHT;
- case VK_UP:
- return SPECIAL_UP;
- case VK_DOWN:
- return SPECIAL_DOWN;
- case VK_INSERT:
- return SPECIAL_INSERT;
- case VK_DELETE:
- return SPECIAL_DELETE;
- case VK_HOME:
- return SPECIAL_HOME;
- case VK_END:
- return SPECIAL_END;
- case VK_PRIOR:
- return SPECIAL_PAGE_UP;
- case VK_NEXT:
- return SPECIAL_PAGE_DOWN;
+
+ }
+ DRL("<snip>");
+ DRL_STR(buf);
+ DRL("\nafter reduce, needcols=%d, new_cursor_pos=%d\n", needcols, new_cursor_pos);
+
+ /* Done, now new_cursor_pos contains the adjusted cursor position
+ * and buf points to he adjusted start
+ */
+ *cursor_pos = new_cursor_pos;
+ return buf;
+}
+
+static int mlmode = 0;
+
+void linenoiseSetMultiLine(int enableml)
+{
+ mlmode = enableml;
+}
+
+/* Helper of refreshSingleLine() and refreshMultiLine() to show hints
+ * to the right of the prompt.
+ * Returns 1 if a hint was shown, or 0 if not
+ * If 'display' is 0, does no output. Just returns the appropriate return code.
+ */
+static int refreshShowHints(struct current *current, const char *buf, int availcols, int display)
+{
+ int rc = 0;
+ if (showhints && hintsCallback && availcols > 0) {
+ int bold = 0;
+ int color = -1;
+ char *hint = hintsCallback(buf, &color, &bold, hintsUserdata);
+ if (hint) {
+ rc = 1;
+ if (display) {
+ const char *pt;
+ if (bold == 1 && color == -1) color = 37;
+ if (bold || color > 0) {
+ int props[3] = { bold, color, 49 }; /* bold, color, fgnormal */
+ setOutputHighlight(current, props, 3);
}
- }
- /* Note that control characters are already translated in AsciiChar */
- else {
-#ifdef USE_UTF8
- return k->uChar.UnicodeChar;
-#else
- return k->uChar.AsciiChar;
-#endif
+ DRL("<hint bold=%d,color=%d>", bold, color);
+ pt = hint;
+ while (*pt) {
+ int ch;
+ int n = utf8_tounicode(pt, &ch);
+ int width = char_display_width(ch);
+
+ if (width >= availcols) {
+ DRL("<hinteol>");
+ break;
+ }
+ DRL_CHAR(ch);
+
+ availcols -= width;
+ outputChars(current, pt, n);
+ pt += n;
+ }
+ if (bold || color > 0) {
+ clearOutputHighlight(current);
+ }
+ /* Call the function to free the hint returned. */
+ if (freeHintsCallback) freeHintsCallback(hint, hintsUserdata);
}
}
}
- return -1;
+ return rc;
}
-static int countColorControlChars(const char* prompt)
+#ifdef USE_TERMIOS
+static void refreshStart(struct current *current)
{
- /* For windows we assume that there are no embedded ansi color
- * control sequences.
- */
- return 0;
+ /* We accumulate all output here */
+ assert(current->output == NULL);
+ current->output = sb_alloc();
}
-static int getWindowSize(struct current *current)
+static void refreshEnd(struct current *current)
{
- CONSOLE_SCREEN_BUFFER_INFO info;
- if (!GetConsoleScreenBufferInfo(current->outh, &info)) {
- return -1;
- }
- current->cols = info.dwSize.X;
- current->rows = info.dwSize.Y;
- if (current->cols <= 0 || current->rows <= 0) {
- current->cols = 80;
- return -1;
- }
- current->y = info.dwCursorPosition.Y;
- current->x = info.dwCursorPosition.X;
- return 0;
+ /* Output everything at once */
+ IGNORE_RC(write(current->fd, sb_str(current->output), sb_len(current->output)));
+ sb_free(current->output);
+ current->output = NULL;
}
-#endif
-/**
- * Returns the unicode character at the given offset,
- * or -1 if none.
- */
-static int get_char(struct current *current, int pos)
+static void refreshStartChars(struct current *current)
+{
+}
+
+static void refreshNewline(struct current *current)
+{
+ DRL("<nl>");
+ outputChars(current, "\n", 1);
+}
+
+static void refreshEndChars(struct current *current)
{
- if (pos >= 0 && pos < current->chars) {
- int c;
- int i = utf8_index(current->buf, pos);
- (void)utf8_tounicode(current->buf + i, &c);
- return c;
- }
- return -1;
}
+#endif
-static void refreshLine(const char *prompt, struct current *current)
+static void refreshLineAlt(struct current *current, const char *prompt, const char *buf, int cursor_pos)
{
- int plen;
- int pchars;
- int backup = 0;
int i;
- const char *buf = current->buf;
- int chars = current->chars;
- int pos = current->pos;
- int b;
- int ch;
- int n;
+ const char *pt;
+ int displaycol;
+ int displayrow;
+ int visible;
+ int currentpos;
+ int notecursor;
+ int cursorcol = 0;
+ int cursorrow = 0;
+ int hint;
+ struct esc_parser parser;
+
+#ifdef DEBUG_REFRESHLINE
+ dfh = fopen("linenoise.debuglog", "a");
+#endif
/* Should intercept SIGWINCH. For now, just get the size every time */
getWindowSize(current);
- plen = strlen(prompt);
- pchars = utf8_strlen(prompt, plen);
+ refreshStart(current);
- /* Scan the prompt for embedded ansi color control sequences and
- * discount them as characters/columns.
- */
- pchars -= countColorControlChars(prompt);
+ DRL("wincols=%d, cursor_pos=%d, nrows=%d, rpos=%d\n", current->cols, cursor_pos, current->nrows, current->rpos);
- /* Account for a line which is too long to fit in the window.
- * Note that control chars require an extra column
+ /* Here is the plan:
+ * (a) move the the bottom row, going down the appropriate number of lines
+ * (b) move to beginning of line and erase the current line
+ * (c) go up one line and do the same, until we have erased up to the first row
+ * (d) output the prompt, counting cols and rows, taking into account escape sequences
+ * (e) output the buffer, counting cols and rows
+ * (e') when we hit the current pos, save the cursor position
+ * (f) move the cursor to the saved cursor position
+ * (g) save the current cursor row and number of rows
*/
- /* How many cols are required to the left of 'pos'?
- * The prompt, plus one extra for each control char
- */
- n = pchars + utf8_strlen(buf, current->len);
- b = 0;
- for (i = 0; i < pos; i++) {
- b += utf8_tounicode(buf + b, &ch);
- if (ch < ' ') {
- n++;
+ /* (a) - The cursor is currently at row rpos */
+ cursorDown(current, current->nrows - current->rpos - 1);
+ DRL("<cud=%d>", current->nrows - current->rpos - 1);
+
+ /* (b), (c) - Erase lines upwards until we get to the first row */
+ for (i = 0; i < current->nrows; i++) {
+ if (i) {
+ DRL("<cup>");
+ cursorUp(current, 1);
}
+ DRL("<clearline>");
+ cursorToLeft(current);
+ eraseEol(current);
}
+ DRL("\n");
- /* If too many are needed, strip chars off the front of 'buf'
- * until it fits. Note that if the current char is a control character,
- * we need one extra col.
- */
- if (current->pos < current->chars && get_char(current, current->pos) < ' ') {
- n++;
- }
+ /* (d) First output the prompt. control sequences don't take up display space */
+ pt = prompt;
+ displaycol = 0; /* current display column */
+ displayrow = 0; /* current display row */
+ visible = 1;
- while (n >= current->cols && pos > 0) {
- b = utf8_tounicode(buf, &ch);
- if (ch < ' ') {
- n--;
+ refreshStartChars(current);
+
+ while (*pt) {
+ int width;
+ int ch;
+ int n = utf8_tounicode(pt, &ch);
+
+ if (visible && ch == CHAR_ESCAPE) {
+ /* The start of an escape sequence, so not visible */
+ visible = 0;
+ initParseEscapeSeq(&parser, 'm');
+ DRL("<esc-seq-start>");
+ }
+
+ if (ch == '\n' || ch == '\r') {
+ /* treat both CR and NL the same and force wrap */
+ refreshNewline(current);
+ displaycol = 0;
+ displayrow++;
+ }
+ else {
+ width = visible * utf8_width(ch);
+
+ displaycol += width;
+ if (displaycol >= current->cols) {
+ /* need to wrap to the next line because of newline or if it doesn't fit
+ * XXX this is a problem in single line mode
+ */
+ refreshNewline(current);
+ displaycol = width;
+ displayrow++;
+ }
+
+ DRL_CHAR(ch);
+#ifdef USE_WINCONSOLE
+ if (visible) {
+ outputChars(current, pt, n);
+ }
+#else
+ outputChars(current, pt, n);
+#endif
+ }
+ pt += n;
+
+ if (!visible) {
+ switch (parseEscapeSequence(&parser, ch)) {
+ case EP_END:
+ visible = 1;
+ setOutputHighlight(current, parser.props, parser.numprops);
+ DRL("<esc-seq-end,numprops=%d>", parser.numprops);
+ break;
+ case EP_ERROR:
+ DRL("<esc-seq-err>");
+ visible = 1;
+ break;
+ }
}
- n--;
- buf += b;
- pos--;
- chars--;
}
- /* Cursor to left edge, then the prompt */
- cursorToLeft(current);
- outputChars(current, prompt, plen);
+ /* Now we are at the first line with all lines erased */
+ DRL("\nafter prompt: displaycol=%d, displayrow=%d\n", displaycol, displayrow);
- /* Now the current buffer content */
- /* Need special handling for control characters.
- * If we hit 'cols', stop.
- */
- b = 0; /* unwritted bytes */
- n = 0; /* How many control chars were written */
- for (i = 0; i < chars; i++) {
+ /* (e) output the buffer, counting cols and rows */
+ if (mlmode == 0) {
+ /* In this mode we may need to trim chars from the start of the buffer until the
+ * cursor fits in the window.
+ */
+ pt = reduceSingleBuf(buf, current->cols - displaycol, &cursor_pos);
+ }
+ else {
+ pt = buf;
+ }
+
+ currentpos = 0;
+ notecursor = -1;
+
+ while (*pt) {
int ch;
- int w = utf8_tounicode(buf + b, &ch);
- if (ch < ' ') {
- n++;
+ int n = utf8_tounicode(pt, &ch);
+ int width = char_display_width(ch);
+
+ if (currentpos == cursor_pos) {
+ /* (e') wherever we output this character is where we want the cursor */
+ notecursor = 1;
}
- if (pchars + i + n >= current->cols) {
- break;
+
+ if (displaycol + width >= current->cols) {
+ if (mlmode == 0) {
+ /* In single line mode stop once we print as much as we can on one line */
+ DRL("<slmode>");
+ break;
+ }
+ /* need to wrap to the next line since it doesn't fit */
+ refreshNewline(current);
+ displaycol = 0;
+ displayrow++;
+ }
+
+ if (notecursor == 1) {
+ /* (e') Save this position as the current cursor position */
+ cursorcol = displaycol;
+ cursorrow = displayrow;
+ notecursor = 0;
+ DRL("<cursor>");
}
+
+ displaycol += width;
+
if (ch < ' ') {
- /* A control character, so write the buffer so far */
- outputChars(current, buf, b);
- buf += b + w;
- b = 0;
outputControlChar(current, ch + '@');
- if (i < pos) {
- backup++;
- }
}
else {
- b += w;
+ outputChars(current, pt, n);
+ }
+ DRL_CHAR(ch);
+ if (width != 1) {
+ DRL("<w=%d>", width);
}
+
+ pt += n;
+ currentpos++;
+ }
+
+ /* If we didn't see the cursor, it is at the current location */
+ if (notecursor) {
+ DRL("<cursor>");
+ cursorcol = displaycol;
+ cursorrow = displayrow;
+ }
+
+ DRL("\nafter buf: displaycol=%d, displayrow=%d, cursorcol=%d, cursorrow=%d\n", displaycol, displayrow, cursorcol, cursorrow);
+
+ /* (f) show hints */
+ hint = refreshShowHints(current, buf, current->cols - displaycol, 1);
+
+ /* Remember how many many cols are available for insert optimisation */
+ if (prompt == current->prompt && hint == 0) {
+ current->colsright = current->cols - displaycol;
+ current->colsleft = displaycol;
+ }
+ else {
+ /* Can't optimise */
+ current->colsright = 0;
+ current->colsleft = 0;
}
- outputChars(current, buf, b);
+ DRL("\nafter hints: colsleft=%d, colsright=%d\n\n", current->colsleft, current->colsright);
+
+ refreshEndChars(current);
+
+ /* (g) move the cursor to the correct place */
+ cursorUp(current, displayrow - cursorrow);
+ setCursorPos(current, cursorcol);
- /* Erase to right, move cursor to original position */
- eraseEol(current);
- setCursorPos(current, pos + pchars + backup);
+ /* (h) Update the number of rows if larger, but never reduce this */
+ if (displayrow >= current->nrows) {
+ current->nrows = displayrow + 1;
+ }
+ /* And remember the row that the cursor is on */
+ current->rpos = cursorrow;
+
+ refreshEnd(current);
+
+#ifdef DEBUG_REFRESHLINE
+ fclose(dfh);
+#endif
}
-static void set_current(struct current *current, const char *str)
+static void refreshLine(struct current *current)
{
- strncpy(current->buf, str, current->bufmax);
- current->buf[current->bufmax - 1] = 0;
- current->len = strlen(current->buf);
- current->pos = current->chars = utf8_strlen(current->buf, current->len);
+ refreshLineAlt(current, current->prompt, sb_str(current->buf), current->pos);
}
-static int has_room(struct current *current, int bytes)
+static void set_current(struct current *current, const char *str)
{
- return current->len + bytes < current->bufmax - 1;
+ sb_clear(current->buf);
+ sb_append(current->buf, str);
+ current->pos = sb_chars(current->buf);
}
/**
@@ -853,31 +1572,52 @@ static int has_room(struct current *current, int bytes)
*/
static int remove_char(struct current *current, int pos)
{
- if (pos >= 0 && pos < current->chars) {
- int p1, p2;
- int ret = 1;
- p1 = utf8_index(current->buf, pos);
- p2 = p1 + utf8_index(current->buf + p1, 1);
-
-#ifdef USE_TERMIOS
- /* optimise remove char in the case of removing the last char */
- if (current->pos == pos + 1 && current->pos == current->chars) {
- if (current->buf[pos] >= ' ' && utf8_strlen(current->prompt, -1) + utf8_strlen(current->buf, current->len) < current->cols - 1) {
- ret = 2;
- fd_printf(current->fd, "\b \b");
+ if (pos >= 0 && pos < sb_chars(current->buf)) {
+ int offset = utf8_index(sb_str(current->buf), pos);
+ int nbytes = utf8_index(sb_str(current->buf) + offset, 1);
+ int rc = 1;
+
+ /* Now we try to optimise in the simple but very common case that:
+ * - outputChars() can be used directly (not win32)
+ * - we are removing the char at EOL
+ * - the buffer is not empty
+ * - there are columns available to the left
+ * - the char being deleted is not a wide or utf-8 character
+ * - no hints are being shown
+ */
+ if (current->output && current->pos == pos + 1 && current->pos == sb_chars(current->buf) && pos > 0) {
+#ifdef USE_UTF8
+ /* Could implement utf8_prev_len() but simplest just to not optimise this case */
+ char last = sb_str(current->buf)[offset];
+#else
+ char last = 0;
+#endif
+ if (current->colsleft > 0 && (last & 0x80) == 0) {
+ /* Have cols on the left and not a UTF-8 char or continuation */
+ /* Yes, can optimise */
+ current->colsleft--;
+ current->colsright++;
+ rc = 2;
}
}
-#endif
- /* Move the null char too */
- memmove(current->buf + p1, current->buf + p2, current->len - p2 + 1);
- current->len -= (p2 - p1);
- current->chars--;
+ sb_delete(current->buf, offset, nbytes);
if (current->pos > pos) {
current->pos--;
}
- return ret;
+ if (rc == 2) {
+ if (refreshShowHints(current, sb_str(current->buf), current->colsright, 0)) {
+ /* A hint needs to be shown, so can't optimise after all */
+ rc = 1;
+ }
+ else {
+ /* optimised output */
+ outputChars(current, "\b \b", 3);
+ }
+ }
+ return rc;
+ return 1;
}
return 0;
}
@@ -890,34 +1630,45 @@ static int remove_char(struct current *current, int pos)
*/
static int insert_char(struct current *current, int pos, int ch)
{
- char buf[3];
- int n = utf8_getchars(buf, ch);
-
- if (has_room(current, n) && pos >= 0 && pos <= current->chars) {
- int p1, p2;
- int ret = 1;
- p1 = utf8_index(current->buf, pos);
- p2 = p1 + n;
-
-#ifdef USE_TERMIOS
- /* optimise the case where adding a single char to the end and no scrolling is needed */
- if (current->pos == pos && current->chars == pos) {
- if (ch >= ' ' && utf8_strlen(current->prompt, -1) + utf8_strlen(current->buf, current->len) < current->cols - 1) {
- IGNORE_RC(write(current->fd, buf, n));
- ret = 2;
+ if (pos >= 0 && pos <= sb_chars(current->buf)) {
+ char buf[MAX_UTF8_LEN + 1];
+ int offset = utf8_index(sb_str(current->buf), pos);
+ int n = utf8_getchars(buf, ch);
+ int rc = 1;
+
+ /* null terminate since sb_insert() requires it */
+ buf[n] = 0;
+
+ /* Now we try to optimise in the simple but very common case that:
+ * - outputChars() can be used directly (not win32)
+ * - we are inserting at EOL
+ * - there are enough columns available
+ * - no hints are being shown
+ */
+ if (current->output && pos == current->pos && pos == sb_chars(current->buf)) {
+ int width = char_display_width(ch);
+ if (current->colsright > width) {
+ /* Yes, can optimise */
+ current->colsright -= width;
+ current->colsleft -= width;
+ rc = 2;
}
}
-#endif
-
- memmove(current->buf + p2, current->buf + p1, current->len - p1);
- memcpy(current->buf + p1, buf, n);
- current->len += n;
-
- current->chars++;
+ sb_insert(current->buf, offset, buf);
if (current->pos >= pos) {
current->pos++;
}
- return ret;
+ if (rc == 2) {
+ if (refreshShowHints(current, sb_str(current->buf), current->colsright, 0)) {
+ /* A hint needs to be shown, so can't optimise after all */
+ rc = 1;
+ }
+ else {
+ /* optimised output */
+ outputChars(current, buf, n);
+ }
+ }
+ return rc;
}
return 0;
}
@@ -927,18 +1678,20 @@ static int insert_char(struct current *current, int pos, int ch)
*
* This replaces any existing characters in the cut buffer.
*/
-static void capture_chars(struct current *current, int pos, int n)
+static void capture_chars(struct current *current, int pos, int nchars)
{
- if (pos >= 0 && (pos + n - 1) < current->chars) {
- int p1 = utf8_index(current->buf, pos);
- int nbytes = utf8_index(current->buf + p1, n);
-
- if (nbytes) {
- free(current->capture);
- /* Include space for the null terminator */
- current->capture = (char *)malloc(nbytes + 1);
- memcpy(current->capture, current->buf + p1, nbytes);
- current->capture[nbytes] = '\0';
+ if (pos >= 0 && (pos + nchars - 1) < sb_chars(current->buf)) {
+ int offset = utf8_index(sb_str(current->buf), pos);
+ int nbytes = utf8_index(sb_str(current->buf) + offset, nchars);
+
+ if (nbytes > 0) {
+ if (current->capture) {
+ sb_clear(current->capture);
+ }
+ else {
+ current->capture = sb_alloc();
+ }
+ sb_append_len(current->capture, sb_str(current->buf) + offset, nbytes);
}
}
}
@@ -982,89 +1735,113 @@ static int insert_chars(struct current *current, int pos, const char *chars)
return inserted;
}
-#ifndef NO_COMPLETION
-static linenoiseCompletionCallback *completionCallback = NULL;
+/**
+ * Returns the keycode to process, or 0 if none.
+ */
+static int reverseIncrementalSearch(struct current *current)
+{
+ /* Display the reverse-i-search prompt and process chars */
+ char rbuf[50];
+ char rprompt[80];
+ int rchars = 0;
+ int rlen = 0;
+ int searchpos = history_len - 1;
+ int c;
-static void beep() {
+ rbuf[0] = 0;
+ while (1) {
+ int n = 0;
+ const char *p = NULL;
+ int skipsame = 0;
+ int searchdir = -1;
+
+ snprintf(rprompt, sizeof(rprompt), "(reverse-i-search)'%s': ", rbuf);
+ refreshLineAlt(current, rprompt, sb_str(current->buf), current->pos);
+ c = fd_read(current);
+ if (c == ctrl('H') || c == CHAR_DELETE) {
+ if (rchars) {
+ int p = utf8_index(rbuf, --rchars);
+ rbuf[p] = 0;
+ rlen = strlen(rbuf);
+ }
+ continue;
+ }
#ifdef USE_TERMIOS
- fprintf(stderr, "\x7");
- fflush(stderr);
+ if (c == CHAR_ESCAPE) {
+ c = check_special(current->fd);
+ }
#endif
-}
-
-static void freeCompletions(linenoiseCompletions *lc) {
- size_t i;
- for (i = 0; i < lc->len; i++)
- free(lc->cvec[i]);
- free(lc->cvec);
-}
-
-static int completeLine(struct current *current) {
- linenoiseCompletions lc = { 0, NULL };
- int c = 0;
+ if (c == ctrl('P') || c == SPECIAL_UP) {
+ /* Search for the previous (earlier) match */
+ if (searchpos > 0) {
+ searchpos--;
+ }
+ skipsame = 1;
+ }
+ else if (c == ctrl('N') || c == SPECIAL_DOWN) {
+ /* Search for the next (later) match */
+ if (searchpos < history_len) {
+ searchpos++;
+ }
+ searchdir = 1;
+ skipsame = 1;
+ }
+ else if (c >= ' ') {
+ /* >= here to allow for null terminator */
+ if (rlen >= (int)sizeof(rbuf) - MAX_UTF8_LEN) {
+ continue;
+ }
- completionCallback(current->buf,&lc);
- if (lc.len == 0) {
- beep();
- } else {
- size_t stop = 0, i = 0;
+ n = utf8_getchars(rbuf + rlen, c);
+ rlen += n;
+ rchars++;
+ rbuf[rlen] = 0;
- while(!stop) {
- /* Show completion or original buffer */
- if (i < lc.len) {
- struct current tmp = *current;
- tmp.buf = lc.cvec[i];
- tmp.pos = tmp.len = strlen(tmp.buf);
- tmp.chars = utf8_strlen(tmp.buf, tmp.len);
- refreshLine(current->prompt, &tmp);
- } else {
- refreshLine(current->prompt, current);
- }
+ /* Adding a new char resets the search location */
+ searchpos = history_len - 1;
+ }
+ else {
+ /* Exit from incremental search mode */
+ break;
+ }
- c = fd_read(current);
- if (c == -1) {
+ /* Now search through the history for a match */
+ for (; searchpos >= 0 && searchpos < history_len; searchpos += searchdir) {
+ p = strstr(history[searchpos], rbuf);
+ if (p) {
+ /* Found a match */
+ if (skipsame && strcmp(history[searchpos], sb_str(current->buf)) == 0) {
+ /* But it is identical, so skip it */
+ continue;
+ }
+ /* Copy the matching line and set the cursor position */
+ set_current(current,history[searchpos]);
+ current->pos = utf8_strlen(history[searchpos], p - history[searchpos]);
break;
}
-
- switch(c) {
- case '\t': /* tab */
- i = (i+1) % (lc.len+1);
- if (i == lc.len) beep();
- break;
- case 27: /* escape */
- /* Re-show original buffer */
- if (i < lc.len) {
- refreshLine(current->prompt, current);
- }
- stop = 1;
- break;
- default:
- /* Update buffer and return */
- if (i < lc.len) {
- set_current(current,lc.cvec[i]);
- }
- stop = 1;
- break;
- }
+ }
+ if (!p && n) {
+ /* No match, so don't add it */
+ rchars--;
+ rlen -= n;
+ rbuf[rlen] = 0;
}
}
+ if (c == ctrl('G') || c == ctrl('C')) {
+ /* ctrl-g terminates the search with no effect */
+ set_current(current, "");
+ c = 0;
+ }
+ else if (c == ctrl('J')) {
+ /* ctrl-j terminates the search leaving the buffer in place */
+ c = 0;
+ }
- freeCompletions(&lc);
- return c; /* Return last read character */
-}
-
-/* Register a callback function to be called for tab-completion. */
-void linenoiseSetCompletionCallback(linenoiseCompletionCallback *fn) {
- completionCallback = fn;
-}
-
-void linenoiseAddCompletion(linenoiseCompletions *lc, const char *str) {
- lc->cvec = (char **)realloc(lc->cvec,sizeof(char*)*(lc->len+1));
- lc->cvec[lc->len++] = strdup(str);
+ /* Go process the char normally */
+ refreshLine(current);
+ return c;
}
-#endif
-
static int linenoiseEdit(struct current *current) {
int history_index = 0;
@@ -1073,7 +1850,7 @@ static int linenoiseEdit(struct current *current) {
linenoiseHistoryAdd("");
set_current(current, "");
- refreshLine(current->prompt, current);
+ refreshLine(current);
while(1) {
int dir = -1;
@@ -1083,38 +1860,61 @@ static int linenoiseEdit(struct current *current) {
/* Only autocomplete when the callback is set. It returns < 0 when
* there was an error reading from fd. Otherwise it will return the
* character that should be handled next. */
- if (c == '\t' && current->pos == current->chars && completionCallback != NULL) {
+ if (c == '\t' && current->pos == sb_chars(current->buf) && completionCallback != NULL) {
c = completeLine(current);
- /* Return on errors */
- if (c < 0) return current->len;
- /* Read next character when 0 */
- if (c == 0) continue;
}
#endif
+ if (c == ctrl('R')) {
+ /* reverse incremental search will provide an alternative keycode or 0 for none */
+ c = reverseIncrementalSearch(current);
+ /* go on to process the returned char normally */
+ }
-process_char:
- if (c == -1) return current->len;
#ifdef USE_TERMIOS
- if (c == 27) { /* escape sequence */
+ if (c == CHAR_ESCAPE) { /* escape sequence */
c = check_special(current->fd);
}
#endif
+ if (c == -1) {
+ /* Return on errors */
+ return sb_len(current->buf);
+ }
+
switch(c) {
- case '\r': /* enter */
+ case SPECIAL_NONE:
+ break;
+ case '\r': /* enter/CR */
+ case '\n': /* LF */
history_len--;
free(history[history_len]);
- return current->len;
+ current->pos = sb_chars(current->buf);
+ if (mlmode || hintsCallback) {
+ showhints = 0;
+ refreshLine(current);
+ showhints = 1;
+ }
+ return sb_len(current->buf);
case ctrl('C'): /* ctrl-c */
errno = EAGAIN;
return -1;
- case 127: /* backspace */
+ case ctrl('Z'): /* ctrl-z */
+#ifdef SIGTSTP
+ /* send ourselves SIGSUSP */
+ disableRawMode(current);
+ raise(SIGTSTP);
+ /* and resume */
+ enableRawMode(current);
+ refreshLine(current);
+#endif
+ continue;
+ case CHAR_DELETE: /* backspace */
case ctrl('H'):
if (remove_char(current, current->pos - 1) == 1) {
- refreshLine(current->prompt, current);
+ refreshLine(current);
}
break;
case ctrl('D'): /* ctrl-d */
- if (current->len == 0) {
+ if (sb_len(current->buf) == 0) {
/* Empty line, so EOF */
history_len--;
free(history[history_len]);
@@ -1123,7 +1923,7 @@ process_char:
/* Otherwise fall through to delete char to right of cursor */
case SPECIAL_DELETE:
if (remove_char(current, current->pos) == 1) {
- refreshLine(current->prompt, current);
+ refreshLine(current);
}
break;
case SPECIAL_INSERT:
@@ -1145,151 +1945,48 @@ process_char:
}
if (remove_chars(current, pos, current->pos - pos)) {
- refreshLine(current->prompt, current);
- }
- }
- break;
- case ctrl('R'): /* ctrl-r */
- {
- /* Display the reverse-i-search prompt and process chars */
- char rbuf[50];
- char rprompt[80];
- int rchars = 0;
- int rlen = 0;
- int searchpos = history_len - 1;
-
- rbuf[0] = 0;
- while (1) {
- int n = 0;
- const char *p = NULL;
- int skipsame = 0;
- int searchdir = -1;
-
- snprintf(rprompt, sizeof(rprompt), "(reverse-i-search)'%s': ", rbuf);
- refreshLine(rprompt, current);
- c = fd_read(current);
- if (c == ctrl('H') || c == 127) {
- if (rchars) {
- int p = utf8_index(rbuf, --rchars);
- rbuf[p] = 0;
- rlen = strlen(rbuf);
- }
- continue;
- }
-#ifdef USE_TERMIOS
- if (c == 27) {
- c = check_special(current->fd);
- }
-#endif
- if (c == ctrl('P') || c == SPECIAL_UP) {
- /* Search for the previous (earlier) match */
- if (searchpos > 0) {
- searchpos--;
- }
- skipsame = 1;
- }
- else if (c == ctrl('N') || c == SPECIAL_DOWN) {
- /* Search for the next (later) match */
- if (searchpos < history_len) {
- searchpos++;
- }
- searchdir = 1;
- skipsame = 1;
- }
- else if (c >= ' ') {
- if (rlen >= (int)sizeof(rbuf) + 3) {
- continue;
- }
-
- n = utf8_getchars(rbuf + rlen, c);
- rlen += n;
- rchars++;
- rbuf[rlen] = 0;
-
- /* Adding a new char resets the search location */
- searchpos = history_len - 1;
- }
- else {
- /* Exit from incremental search mode */
- break;
- }
-
- /* Now search through the history for a match */
- for (; searchpos >= 0 && searchpos < history_len; searchpos += searchdir) {
- p = strstr(history[searchpos], rbuf);
- if (p) {
- /* Found a match */
- if (skipsame && strcmp(history[searchpos], current->buf) == 0) {
- /* But it is identical, so skip it */
- continue;
- }
- /* Copy the matching line and set the cursor position */
- set_current(current,history[searchpos]);
- current->pos = utf8_strlen(history[searchpos], p - history[searchpos]);
- break;
- }
- }
- if (!p && n) {
- /* No match, so don't add it */
- rchars--;
- rlen -= n;
- rbuf[rlen] = 0;
- }
- }
- if (c == ctrl('G') || c == ctrl('C')) {
- /* ctrl-g terminates the search with no effect */
- set_current(current, "");
- c = 0;
+ refreshLine(current);
}
- else if (c == ctrl('J')) {
- /* ctrl-j terminates the search leaving the buffer in place */
- c = 0;
- }
- /* Go process the char normally */
- refreshLine(current->prompt, current);
- goto process_char;
}
break;
case ctrl('T'): /* ctrl-t */
- if (current->pos > 0 && current->pos <= current->chars) {
+ if (current->pos > 0 && current->pos <= sb_chars(current->buf)) {
/* If cursor is at end, transpose the previous two chars */
- int fixer = (current->pos == current->chars);
+ int fixer = (current->pos == sb_chars(current->buf));
c = get_char(current, current->pos - fixer);
remove_char(current, current->pos - fixer);
insert_char(current, current->pos - 1, c);
- refreshLine(current->prompt, current);
+ refreshLine(current);
}
break;
case ctrl('V'): /* ctrl-v */
- if (has_room(current, 3)) {
- /* Insert the ^V first */
- if (insert_char(current, current->pos, c)) {
- refreshLine(current->prompt, current);
- /* Now wait for the next char. Can insert anything except \0 */
- c = fd_read(current);
-
- /* Remove the ^V first */
- remove_char(current, current->pos - 1);
- if (c != -1) {
- /* Insert the actual char */
- insert_char(current, current->pos, c);
- }
- refreshLine(current->prompt, current);
+ /* Insert the ^V first */
+ if (insert_char(current, current->pos, c)) {
+ refreshLine(current);
+ /* Now wait for the next char. Can insert anything except \0 */
+ c = fd_read(current);
+
+ /* Remove the ^V first */
+ remove_char(current, current->pos - 1);
+ if (c > 0) {
+ /* Insert the actual char, can't be error or null */
+ insert_char(current, current->pos, c);
}
+ refreshLine(current);
}
break;
case ctrl('B'):
case SPECIAL_LEFT:
if (current->pos > 0) {
current->pos--;
- refreshLine(current->prompt, current);
+ refreshLine(current);
}
break;
case ctrl('F'):
case SPECIAL_RIGHT:
- if (current->pos < current->chars) {
+ if (current->pos < sb_chars(current->buf)) {
current->pos++;
- refreshLine(current->prompt, current);
+ refreshLine(current);
}
break;
case SPECIAL_PAGE_UP:
@@ -1309,7 +2006,7 @@ history_navigation:
/* Update the current history entry before to
* overwrite it with tne next one. */
free(history[history_len - 1 - history_index]);
- history[history_len - 1 - history_index] = strdup(current->buf);
+ history[history_len - 1 - history_index] = strdup(sb_str(current->buf));
/* Show the new entry */
history_index += dir;
if (history_index < 0) {
@@ -1320,131 +2017,164 @@ history_navigation:
break;
}
set_current(current, history[history_len - 1 - history_index]);
- refreshLine(current->prompt, current);
+ refreshLine(current);
}
break;
case ctrl('A'): /* Ctrl+a, go to the start of the line */
case SPECIAL_HOME:
current->pos = 0;
- refreshLine(current->prompt, current);
+ refreshLine(current);
break;
case ctrl('E'): /* ctrl+e, go to the end of the line */
case SPECIAL_END:
- current->pos = current->chars;
- refreshLine(current->prompt, current);
+ current->pos = sb_chars(current->buf);
+ refreshLine(current);
break;
case ctrl('U'): /* Ctrl+u, delete to beginning of line, save deleted chars. */
if (remove_chars(current, 0, current->pos)) {
- refreshLine(current->prompt, current);
+ refreshLine(current);
}
break;
case ctrl('K'): /* Ctrl+k, delete from current to end of line, save deleted chars. */
- if (remove_chars(current, current->pos, current->chars - current->pos)) {
- refreshLine(current->prompt, current);
+ if (remove_chars(current, current->pos, sb_chars(current->buf) - current->pos)) {
+ refreshLine(current);
}
break;
case ctrl('Y'): /* Ctrl+y, insert saved chars at current position */
- if (current->capture && insert_chars(current, current->pos, current->capture)) {
- refreshLine(current->prompt, current);
+ if (current->capture && insert_chars(current, current->pos, sb_str(current->capture))) {
+ refreshLine(current);
}
break;
case ctrl('L'): /* Ctrl+L, clear screen */
- clearScreen(current);
+ linenoiseClearScreen();
/* Force recalc of window size for serial terminals */
current->cols = 0;
- refreshLine(current->prompt, current);
+ current->rpos = 0;
+ refreshLine(current);
break;
default:
/* Only tab is allowed without ^V */
if (c == '\t' || c >= ' ') {
if (insert_char(current, current->pos, c) == 1) {
- refreshLine(current->prompt, current);
+ refreshLine(current);
}
}
break;
}
}
- return current->len;
+ return sb_len(current->buf);
}
int linenoiseColumns(void)
{
struct current current;
+ current.output = NULL;
enableRawMode (&current);
getWindowSize (&current);
disableRawMode (&current);
return current.cols;
}
+/**
+ * Reads a line from the file handle (without the trailing NL or CRNL)
+ * and returns it in a stringbuf.
+ * Returns NULL if no characters are read before EOF or error.
+ *
+ * Note that the character count will *not* be correct for lines containing
+ * utf8 sequences. Do not rely on the character count.
+ */
+static stringbuf *sb_getline(FILE *fh)
+{
+ stringbuf *sb = sb_alloc();
+ int c;
+ int n = 0;
+
+ while ((c = getc(fh)) != EOF) {
+ char ch;
+ n++;
+ if (c == '\r') {
+ /* CRLF -> LF */
+ continue;
+ }
+ if (c == '\n' || c == '\r') {
+ break;
+ }
+ ch = c;
+ /* ignore the effect of character count for partial utf8 sequences */
+ sb_append_len(sb, &ch, 1);
+ }
+ if (n == 0) {
+ sb_free(sb);
+ return NULL;
+ }
+ return sb;
+}
+
char *linenoise(const char *prompt)
{
int count;
struct current current;
- char buf[LINENOISE_MAX_LINE];
+ stringbuf *sb;
+
+ memset(&current, 0, sizeof(current));
if (enableRawMode(&current) == -1) {
printf("%s", prompt);
fflush(stdout);
- if (fgets(buf, sizeof(buf), stdin) == NULL) {
- return NULL;
- }
- count = strlen(buf);
- if (count && buf[count-1] == '\n') {
- count--;
- buf[count] = '\0';
- }
+ sb = sb_getline(stdin);
}
- else
- {
- current.buf = buf;
- current.bufmax = sizeof(buf);
- current.len = 0;
- current.chars = 0;
+ else {
+ current.buf = sb_alloc();
current.pos = 0;
+ current.nrows = 1;
current.prompt = prompt;
- current.capture = NULL;
count = linenoiseEdit(&current);
disableRawMode(&current);
printf("\n");
- free(current.capture);
+ sb_free(current.capture);
if (count == -1) {
+ sb_free(current.buf);
return NULL;
}
+ sb = current.buf;
}
- return strdup(buf);
+ return sb ? sb_to_string(sb) : NULL;
}
/* Using a circular buffer is smarter, but a bit more complex to handle. */
-int linenoiseHistoryAdd(const char *line) {
- char *linecopy;
+int linenoiseHistoryAddAllocated(char *line) {
- if (history_max_len == 0) return 0;
+ if (history_max_len == 0) {
+notinserted:
+ free(line);
+ return 0;
+ }
if (history == NULL) {
- history = (char **)malloc(sizeof(char*)*history_max_len);
- if (history == NULL) return 0;
- memset(history,0,(sizeof(char*)*history_max_len));
+ history = (char **)calloc(sizeof(char*), history_max_len);
}
/* do not insert duplicate lines into history */
if (history_len > 0 && strcmp(line, history[history_len - 1]) == 0) {
- return 0;
+ goto notinserted;
}
- linecopy = strdup(line);
- if (!linecopy) return 0;
if (history_len == history_max_len) {
free(history[0]);
memmove(history,history+1,sizeof(char*)*(history_max_len-1));
history_len--;
}
- history[history_len] = linecopy;
+ history[history_len] = line;
history_len++;
return 1;
}
+int linenoiseHistoryAdd(const char *line) {
+ return linenoiseHistoryAddAllocated(strdup(line));
+}
+
int linenoiseHistoryGetMaxLen(void) {
return history_max_len;
}
@@ -1456,8 +2186,7 @@ int linenoiseHistorySetMaxLen(int len) {
if (history) {
int tocopy = history_len;
- newHistory = (char **)malloc(sizeof(char*)*len);
- if (newHistory == NULL) return 0;
+ newHistory = (char **)calloc(sizeof(char*), len);
/* If we can't copy everything, free the elements we'll not use. */
if (len < tocopy) {
@@ -1466,7 +2195,6 @@ int linenoiseHistorySetMaxLen(int len) {
for (j = 0; j < tocopy-len; j++) free(history[j]);
tocopy = len;
}
- memset(newHistory,0,sizeof(char*)*len);
memcpy(newHistory,history+(history_len-tocopy), sizeof(char*)*tocopy);
free(history);
history = newHistory;
@@ -1509,22 +2237,25 @@ int linenoiseHistorySave(const char *filename) {
return 0;
}
-/* Load the history from the specified file. If the file does not exist
- * zero is returned and no operation is performed.
+/* Load the history from the specified file.
*
- * If the file exists and the operation succeeded 0 is returned, otherwise
- * on error -1 is returned. */
+ * If the file does not exist or can't be opened, no operation is performed
+ * and -1 is returned.
+ * Otherwise 0 is returned.
+ */
int linenoiseHistoryLoad(const char *filename) {
FILE *fp = fopen(filename,"r");
- char buf[LINENOISE_MAX_LINE];
+ stringbuf *sb;
if (fp == NULL) return -1;
- while (fgets(buf,LINENOISE_MAX_LINE,fp) != NULL) {
- char *src, *dest;
+ while ((sb = sb_getline(fp)) != NULL) {
+ /* Take the stringbuf and decode backslash escaped values */
+ char *buf = sb_to_string(sb);
+ char *dest = buf;
+ const char *src;
- /* Decode backslash escaped values */
- for (src = dest = buf; *src; src++) {
+ for (src = buf; *src; src++) {
char ch = *src;
if (ch == '\\') {
@@ -1540,13 +2271,9 @@ int linenoiseHistoryLoad(const char *filename) {
}
*dest++ = ch;
}
- /* Remove trailing newline */
- if (dest != buf && (dest[-1] == '\n' || dest[-1] == '\r')) {
- dest--;
- }
*dest = 0;
- linenoiseHistoryAdd(buf);
+ linenoiseHistoryAddAllocated(buf);
}
fclose(fp);
return 0;
diff --git a/linenoise.h b/linenoise.h
index cf8f16f..9f36dbf 100644
--- a/linenoise.h
+++ b/linenoise.h
@@ -37,28 +37,100 @@
#ifndef __LINENOISE_H
#define __LINENOISE_H
-/* Currently never enable completion */
-#define NO_COMPLETION
-
#ifndef NO_COMPLETION
typedef struct linenoiseCompletions {
size_t len;
char **cvec;
} linenoiseCompletions;
-typedef void(linenoiseCompletionCallback)(const char *, linenoiseCompletions *);
-void linenoiseSetCompletionCallback(linenoiseCompletionCallback *);
-void linenoiseAddCompletion(linenoiseCompletions *, const char *);
+/*
+ * The callback type for tab completion handlers.
+ */
+typedef void(linenoiseCompletionCallback)(const char *prefix, linenoiseCompletions *comp, void *userdata);
+
+/*
+ * Sets the current tab completion handler and returns the previous one, or NULL
+ * if no prior one has been set.
+ */
+linenoiseCompletionCallback * linenoiseSetCompletionCallback(linenoiseCompletionCallback *comp, void *userdata);
+
+/*
+ * Adds a copy of the given string to the given completion list. The copy is owned
+ * by the linenoiseCompletions object.
+ */
+void linenoiseAddCompletion(linenoiseCompletions *comp, const char *str);
+
+typedef char*(linenoiseHintsCallback)(const char *, int *color, int *bold, void *userdata);
+typedef void(linenoiseFreeHintsCallback)(void *hint, void *userdata);
+void linenoiseSetHintsCallback(linenoiseHintsCallback *callback, void *userdata);
+void linenoiseSetFreeHintsCallback(linenoiseFreeHintsCallback *callback);
+
#endif
+/*
+ * Prompts for input using the given string as the input
+ * prompt. Returns when the user has tapped ENTER or (on an empty
+ * line) EOF (Ctrl-D on Unix, Ctrl-Z on Windows). Returns either
+ * a copy of the entered string (for ENTER) or NULL (on EOF). The
+ * caller owns the returned string and must eventually free() it.
+ */
char *linenoise(const char *prompt);
+
+/**
+ * Clear the screen.
+ */
+void linenoiseClearScreen(void);
+
+/*
+ * Adds a copy of the given line of the command history.
+ */
int linenoiseHistoryAdd(const char *line);
+
+/*
+ * Sets the maximum length of the command history, in lines.
+ * If the history is currently longer, it will be trimmed,
+ * retaining only the most recent entries. If len is 0 or less
+ * then this function does nothing.
+ */
int linenoiseHistorySetMaxLen(int len);
+
+/*
+ * Returns the current maximum length of the history, in lines.
+ */
int linenoiseHistoryGetMaxLen(void);
+
+/*
+ * Saves the current contents of the history to the given file.
+ * Returns 0 on success.
+ */
int linenoiseHistorySave(const char *filename);
+
+/*
+ * Replaces the current history with the contents
+ * of the given file. Returns 0 on success.
+ */
int linenoiseHistoryLoad(const char *filename);
+
+/*
+ * Frees all history entries, clearing the history.
+ */
void linenoiseHistoryFree(void);
+
+/*
+ * Returns a pointer to the list of history entries, writing its
+ * length to *len if len is not NULL. The memory is owned by linenoise
+ * and must not be freed.
+ */
char **linenoiseHistory(int *len);
+
+/*
+ * Returns the number of display columns in the current terminal.
+ */
int linenoiseColumns(void);
+/**
+ * Enable or disable multiline mode (disabled by default)
+ */
+void linenoiseSetMultiLine(int enableml);
+
#endif /* __LINENOISE_H */
diff --git a/make-bootstrap-jim b/make-bootstrap-jim
index c1754f7..7484b11 100755
--- a/make-bootstrap-jim
+++ b/make-bootstrap-jim
@@ -74,6 +74,14 @@ cat <<EOF
#define HAVE_SYS_TIME_H
#define HAVE_DIRENT_H
#define HAVE_UNISTD_H
+#define HAVE_UMASK
+#include <sys/stat.h>
+#ifndef S_IRWXG
+#define S_IRWXG 0
+#endif
+#ifndef S_IRWXO
+#define S_IRWXO 0
+#endif
#else
#define TCL_PLATFORM_OS "unknown"
#define TCL_PLATFORM_PLATFORM "unix"
@@ -92,6 +100,7 @@ cat <<EOF
#define HAVE_SYS_TIME_H
#define HAVE_DIRENT_H
#define HAVE_UNISTD_H
+#define HAVE_UMASK
#endif
EOF
@@ -106,7 +115,7 @@ outputsource()
}
# Now output header files, removing references to jim header files
-for i in jim-win32compat.h utf8.h jim.h jim-subcmd.h jimregexp.h ; do
+for i in jim-win32compat.h utf8.h jim.h jim-subcmd.h jimregexp.h jim-signal.h jimiocompat.h; do
outputsource $i
done
@@ -120,7 +129,7 @@ done
makeloadexts $allexts
# And finally the core source code
-for i in jim.c jim-subcmd.c utf8.c jim-format.c jimregexp.c jim-win32compat.c; do
+for i in jim.c jim-subcmd.c utf8.c jim-format.c jimregexp.c jimiocompat.c jim-win32compat.c jim-nosignal.c; do
outputsource $i
done
echo "#ifndef JIM_BOOTSTRAP_LIB_ONLY"
diff --git a/make-index b/make-index
index 1908d00..5071d88 100755
--- a/make-index
+++ b/make-index
@@ -16,13 +16,13 @@ while {[gets $f buf] >= 0} {
incr c
set target cmd_$c
set lines [linsert $lines end-1 "\[\[$target\]\]"]
- set prevlist [split $prev ":, "]
+ set prevlist [split $prev ", "]
} else {
set target _[string map {:: _} $prev]
set prevlist [list $prev]
}
foreach cmd $prevlist {
- set cmd [string trim $cmd]
+ set cmd [string trim $cmd :]
if {[regexp {^[a-z.:]+$} $cmd]} {
lappend commands [list $cmd $target]
set cdict($cmd) $target
diff --git a/oo.tcl b/oo.tcl
index a05aa01..b6ad4a9 100644
--- a/oo.tcl
+++ b/oo.tcl
@@ -78,7 +78,7 @@ proc class {classname {baseclasses {}} classvars} {
proc "$classname classvars" {} classvars { return $classvars }
proc "$classname classname" {} classname { return $classname }
proc "$classname methods" {} classname {
- lsort [lmap p [info procs "$classname *"] {
+ lsort [lmap p [info commands "$classname *"] {
lindex [split $p " "] 1
}]
}
diff --git a/parse-unidata.tcl b/parse-unidata.tcl
index 348a114..2bf6547 100644
--- a/parse-unidata.tcl
+++ b/parse-unidata.tcl
@@ -8,18 +8,45 @@
#/
# Parse the unicode data from: http://unicode.org/Public/UNIDATA/UnicodeData.txt
-# to generate case mapping tables
+# and http://unicode.org/Public/UNIDATA/EastAsianWidth.txt
+# to generate case mapping and display width tables
set map(lower) {}
set map(upper) {}
set map(title) {}
+set map(combining) {}
+set map(wide) {}
-set f [open [lindex $argv 0]]
+set USAGE "Usage: parse-unidata.tcl \[-width\] UnicodeData.txt \[EastAsianWidth.txt\]"
+set do_width 0
+
+if {[lindex $argv 0] eq "-width"} {
+ set do_width 1
+ set argv [lrange $argv 1 end]
+}
+
+if {[llength $argv] ni {1 2}} {
+ puts stderr $USAGE
+ exit 1
+}
+
+lassign $argv unicodefile widthfile
+
+set f [open $unicodefile]
while {[gets $f buf] >= 0} {
set title ""
set lower ""
set upper ""
- foreach {code name class x x x x x x x x x upper lower title} [split $buf ";"] break
+ lassign [split $buf ";"] code name class x x x x x x x x x upper lower title
set codex [string tolower 0x$code]
+ if {[string match M* $class]} {
+ if {![info exists combining]} {
+ set combining $codex
+ }
+ continue
+ } elseif {[info exists combining]} {
+ lappend map(combining) $combining $codex
+ unset combining
+ }
if {$codex <= 0x7f} {
continue
}
@@ -44,10 +71,69 @@ while {[gets $f buf] >= 0} {
}
close $f
+proc output-int-pairs {list} {
+ set n 0
+ foreach {v1 v2} $list {
+ puts -nonewline "\t{ $v1, $v2 },"
+ if {[incr n] % 4 == 0} {
+ puts ""
+ }
+ }
+ if {$n % 4} {
+ puts ""
+ }
+}
+
+# Merges adjacent ranges in a list of ranges (lower upper lower upper ...)
+proc combine-adjacent-ranges {list} {
+ set newlist {}
+ foreach {lower upper} $list {
+ if {[info exists prev_upper]} {
+ if {$lower == $prev_upper + 1} {
+ # combine these
+ set prev_upper $upper
+ continue
+ } else {
+ # can't combine
+ lappend newlist $prev_lower $prev_upper
+ }
+ }
+ set prev_lower $lower
+ set prev_upper $upper
+ }
+ # Now add the last range
+ lappend newlist $prev_lower $prev_upper
+ return $newlist
+}
+
foreach type {upper lower title} {
puts "static const struct casemap unicode_case_mapping_$type\[\] = \{"
- foreach {code alt} $map($type) {
- puts "\t{ $code, $alt },"
+ output-int-pairs $map($type)
+ puts "\};\n"
+}
+
+if {$do_width} {
+ set f [open $widthfile]
+ while {[gets $f buf] >= 0} {
+ if {[regexp {^([0-9A-Fa-f.]+);W} $buf -> range]} {
+ set range [string tolower $range]
+ lassign [split $range .] lower - upper
+ if {$upper eq ""} {
+ set upper $lower
+ }
+ lappend map(wide) 0x$lower 0x$upper
+ }
+ }
+ close $f
+}
+
+foreach type {combining wide} {
+ puts "static const struct utf8range unicode_range_$type\[\] = \{"
+ if {$do_width} {
+ output-int-pairs [combine-adjacent-ranges $map($type)]
+ } else {
+ # Just produce empty width tables in this case
+ output-int-pairs {}
}
puts "\};\n"
}
diff --git a/regtest.tcl b/regtest.tcl
index 28bd43d..a46b849 100644
--- a/regtest.tcl
+++ b/regtest.tcl
@@ -252,6 +252,104 @@ $f writable {incr y}
$f close
puts "TEST 34 PASSED"
+# REGTEST 35
+# caching of command resolution after local proc deleted
+set result {}
+proc x {} { }
+proc p {n} {
+ if {$n in {2 3}} {
+ local proc x {} { }
+ }
+ x
+}
+foreach i {1 2 3 4} {
+ p $i
+}
+puts "TEST 35 PASSED"
+
+# REGTEST 36
+# divide integer by integer zero
+catch {/ 1 0}
+puts "TEST 36 PASSED"
+
+# REGTEST 37
+# ternary operator order
+catch {expr {1 : 2 ? 3}}
+puts "TEST 37 PASSED"
+
+# REGTEST 38
+# refcount with interpolation and expr
+set b(-1) 5
+set a $b($(-1))
+puts "TEST 38 PASSED"
+
+# REGTEST 39
+# invalid ternary expr
+catch {set a $(5?6,7?8:?9:10%11:12)}
+puts "TEST 39 PASSED"
+
+# REGTEST 40
+# ref count problem - double free
+set d [dict create a b]
+lsort r($d)
+catch {dict remove r($d) m}
+puts "TEST 40 PASSED"
+
+# REGTEST 41
+# access invalid memory on no scan conversion char
+catch {scan x %3}
+puts "TEST 41 PASSED"
+
+# REGTEST 42
+# | and |& are not acceptable as prefixes
+catch {exec dummy |x second}
+puts "TEST 42 PASSED"
+
+# REGTEST 43
+# too many flags to format
+catch {format %----------------------------------------d 1}
+puts "TEST 43 PASSED"
+
+# REGTEST 44
+# lsort -unique with no duplicate - invalid memory write
+lsort -unique {a b c d}
+puts "TEST 44 PASSED"
+
+# REGTEST 45
+# regexp with missing close brace for count
+catch [list regexp "u{0" x]
+puts "TEST 45 PASSED"
+
+# REGTEST 46
+# scan with no stringrep
+catch {scan $(1) $(1)}
+puts "TEST 46 PASSED"
+
+# REGTEST 47
+# Invalid ternary expression
+catch {set a $(99?9,99?9:*9:999)?9)}
+puts "TEST 47 PASSED"
+
+# REGTEST 48
+# scan: -ve XPG3 specifier
+catch {scan a {%-9999999$c}}
+puts "TEST 48 PASSED"
+
+# REGTEST 49
+# format: precision too large
+catch {format %1.9999999999f 1.0}
+puts "TEST 49 PASSED"
+
+# REGTEST 50
+# expr missing operand
+catch {expr {>>-$x}}
+puts "TEST 50 PASSED"
+
+# REGTEST 51
+# expr convert invalid value to boolean
+catch {expr {2 && "abc$"}}
+puts "TEST 51 PASSED"
+
# TAKE THE FOLLOWING puts AS LAST LINE
puts "--- ALL TESTS PASSED ---"
diff --git a/sqlite3/build-ext b/sqlite3/build-ext
index a6fa5c3..c370687 100755
--- a/sqlite3/build-ext
+++ b/sqlite3/build-ext
@@ -7,4 +7,4 @@
# Prefer jimsh in .. if it exists
PATH=..:$PATH; export PATH
asdir="`dirname "$0"`/../autosetup"
-exec "`$asdir/find-tclsh`" ../build-jim-ext "$@"
+exec "`$asdir/autosetup-find-tclsh`" ../build-jim-ext "$@"
diff --git a/sqlite3/jim-sqlite3.c b/sqlite3/jim-sqlite3.c
index 7b09a9a..260f1ee 100644
--- a/sqlite3/jim-sqlite3.c
+++ b/sqlite3/jim-sqlite3.c
@@ -903,7 +903,7 @@ static char *local_getline(char *zPrompt, FILE *in){
while( !eol ){
if( n+100>nLine ){
nLine = nLine*2 + 100;
- zLine = realloc(zLine, nLine);
+ zLine = Jim_Realloc(zLine, nLine);
if( zLine==0 ) return 0;
}
if( fgets(&zLine[n], nLine - n, in)==0 ){
@@ -922,7 +922,7 @@ static char *local_getline(char *zPrompt, FILE *in){
eol = 1;
}
}
- zLine = realloc( zLine, n+1 );
+ zLine = Jim_Realloc( zLine, n+1 );
return zLine;
}
diff --git a/stdlib.tcl b/stdlib.tcl
index 08cb217..37a8007 100644
--- a/stdlib.tcl
+++ b/stdlib.tcl
@@ -1,5 +1,12 @@
# Implements script-based standard commands for Jim Tcl
+if {![exists -command ref]} {
+ # No support for references, so create a poor-man's reference just good enough for lambda
+ proc ref {args} {{count 0}} {
+ format %08x [incr count]
+ }
+}
+
# Creates an anonymous procedure
proc lambda {arglist args} {
tailcall proc [ref {} function lambda.finalizer] $arglist {*}$args
@@ -59,6 +66,13 @@ proc stackdump {stacktrace} {
join $lines \n
}
+# Add the given script to $jim::defer, to be evaluated when the current
+# procedure exits
+proc defer {script} {
+ upvar jim::defer v
+ lappend v $script
+}
+
# Sort of replacement for $::errorInfo
# Usage: errorInfo error ?stacktrace?
proc errorInfo {msg {stacktrace ""}} {
@@ -87,27 +101,6 @@ proc {info nameofexecutable} {} {
}
}
-# Script-based implementation of 'dict with'
-proc {dict with} {&dictVar {args key} script} {
- set keys {}
- foreach {n v} [dict get $dictVar {*}$key] {
- upvar $n var_$n
- set var_$n $v
- lappend keys $n
- }
- catch {uplevel 1 $script} msg opts
- if {[info exists dictVar] && ([llength $key] == 0 || [dict exists $dictVar {*}$key])} {
- foreach n $keys {
- if {[info exists var_$n]} {
- dict set dictVar {*}$key $n [set var_$n]
- } else {
- dict unset dictVar {*}$key $n
- }
- }
- }
- return {*}$opts $msg
-}
-
# Script-based implementation of 'dict update'
proc {dict update} {&varName args script} {
set keys {}
@@ -130,19 +123,6 @@ proc {dict update} {&varName args script} {
return {*}$opts $msg
}
-# Script-based implementation of 'dict merge'
-# This won't get called in the trivial case of no args
-proc {dict merge} {dict args} {
- foreach d $args {
- # Check for a valid dict
- dict size $d
- foreach {k v} $d {
- dict set dict $k $v
- }
- }
- return $dict
-}
-
proc {dict replace} {dictionary {args {key value}}} {
if {[llength ${key value}] % 2} {
tailcall {dict replace}
@@ -188,11 +168,6 @@ proc {dict remove} {dictionary {args key}} {
return $dictionary
}
-# Script-based implementation of 'dict values'
-proc {dict values} {dictionary {pattern *}} {
- dict keys [lreverse $dictionary] $pattern
-}
-
# Script-based implementation of 'dict for'
proc {dict for} {vars dictionary script} {
if {[llength $vars] != 2} {
diff --git a/tclcompat.tcl b/tclcompat.tcl
index d1516b3..432c744 100644
--- a/tclcompat.tcl
+++ b/tclcompat.tcl
@@ -1,5 +1,5 @@
# Loads some Tcl-compatible features.
-# I/O commands, case, lassign, parray, errorInfo, ::tcl_platform, ::env
+# I/O commands, parray, open |..., errorInfo, ::env
# try, throw, file copy, file delete -force
#
# (c) 2008 Steve Bennett <steveb@workware.net.au>
@@ -63,9 +63,8 @@ proc fileevent {args} {
tailcall {*}$args
}
-# Second, option argument is a glob pattern
+# Second, optional argument is a glob pattern
# Third, optional argument is a "putter" function
-#
proc parray {arrayname {pattern *} {puts puts}} {
upvar $arrayname a
@@ -119,9 +118,9 @@ proc {file copy} {{force {}} source target} {
}
# 'open "|..." ?mode?" will invoke this wrapper around exec/pipe
-# Note that we return a lambda which also provides the 'pid' command
+# Note that we return a lambda that also provides the 'pid' command
proc popen {cmd {mode r}} {
- lassign [socket pipe] r w
+ lassign [pipe] r w
try {
if {[string match "w*" $mode]} {
lappend cmd <@$r &
@@ -138,11 +137,26 @@ proc popen {cmd {mode r}} {
if {$cmd eq "pid"} {
return $pids
}
+ if {$cmd eq "getfd"} {
+ $f getfd
+ }
if {$cmd eq "close"} {
$f close
# And wait for the child processes to complete
- foreach p $pids { os.wait $p }
- return
+ set retopts {}
+ foreach p $pids {
+ lassign [wait $p] status - rc
+ if {$status eq "CHILDSTATUS"} {
+ if {$rc == 0} {
+ continue
+ }
+ set msg "child process exited abnormally"
+ } else {
+ set msg "child killed: received signal"
+ }
+ set retopts [list -code error -errorcode [list $status $p $rc] $msg]
+ }
+ return {*}$retopts
}
tailcall $f $cmd {*}$args
}
@@ -153,7 +167,7 @@ proc popen {cmd {mode r}} {
}
}
-# A wrapper around 'pid' which can return the pids for 'popen'
+# A wrapper around 'pid' that can return the pids for 'popen'
local proc pid {{channelId {}}} {
if {$channelId eq ""} {
tailcall upcall pid
@@ -172,14 +186,10 @@ local proc pid {{channelId {}}} {
# Usage: try ?catchopts? script ?onclause ...? ?finallyclause?
#
# Where:
-# onclause is: on codes {?resultvar? ?optsvar?} script
-#
-# codes is: a list of return codes (ok, error, etc. or integers), or * for any
-#
-# finallyclause is: finally script
-#
-#
-# Where onclause is: on codes {?resultvar? ?optsvar?}
+# catchopts is: options for catch such as -nobreak, -signal
+# onclause is: on codes {?resultvar? ?optsvar?} script
+# codes is: a list of return codes (ok, error, etc. or integers), or * for any
+# finallyclause is: finally script
proc try {args} {
set catchopts {}
while {[string match -* [lindex $args 0]]} {
diff --git a/tcltest.tcl b/tcltest.tcl
index 1542d85..5b0198a 100644
--- a/tcltest.tcl
+++ b/tcltest.tcl
@@ -44,6 +44,12 @@ proc needs {type what {packages {}}} {
}
skiptest " (command $what)"
}
+ if {$type eq "package"} {
+ if {[catch {package require $what}]} {
+ skiptest " (package $what)"
+ }
+ return
+ }
error "Unknown needs type: $type"
}
@@ -95,14 +101,20 @@ proc makeDirectory {name} {
return $name
}
-proc temporaryDirectory {} {
- set name [format "%s/tcltmp-%04x" [env TMPDIR /tmp] [rand 65536]]
- file mkdir $name
- return $name
+proc temporaryDirectory {} {{dir {}}} {
+ if {$dir eq ""} {
+ set dir [file join [env TMPDIR /tmp] [format "tcltmp-%04x" [rand 65536]]]
+ file mkdir $dir
+ }
+ return $dir
}
-proc removeFile {name} {
- file delete $name
+proc removeFile {args} {
+ file delete -force {*}$args
+}
+
+proc removeDirectory {name} {
+ file delete -force $name
}
# In case tclcompat is not selected
@@ -160,7 +172,7 @@ proc testConstraint {constraint {bool {}}} {
}
testConstraint {utf8} [expr {[string length "\xc2\xb5"] == 1}]
-testConstraint {references} [expr {[info commands ref] ne ""}]
+testConstraint {references} [expr {[info commands getref] ne ""}]
testConstraint {jim} 1
testConstraint {tcl} 0
@@ -193,15 +205,23 @@ proc test {id descr args} {
if {![testConstraint $c]} {
incr ::testinfo(numskip)
if {$::testinfo(verbose)} {
- puts "SKIP"
+ puts "SKIP $descr"
}
return
}
}
- catch {uplevel 1 $a(-setup)}
+ if {[catch {uplevel 1 $a(-setup)} msg]} {
+ if {$::testinfo(verbose)} {
+ puts "-setup failed: $msg"
+ }
+ }
set rc [catch {uplevel 1 $a(-body)} result opts]
- catch {uplevel 1 $a(-cleanup)}
+ if {[catch {uplevel 1 $a(-cleanup)} msg]} {
+ if {$::testinfo(verbose)} {
+ puts "-cleanup failed: $msg"
+ }
+ }
if {[info return $rc] ni $a(-returnCodes) && $rc ni $a(-returnCodes)} {
set ok 0
@@ -248,6 +268,7 @@ proc test {id descr args} {
}
proc ::tcltest::cleanupTests {} {
+ file delete [temporaryDirectory]
tailcall testreport
}
diff --git a/tests/Makefile b/tests/Makefile
deleted file mode 100644
index 979d081..0000000
--- a/tests/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-jimsh ?= ../jimsh
-tclsh ?= tclsh
-
-test:
- @LD_LIBRARY_PATH=..:$(LD_LIBRARY_PATH) $(jimsh) runall.tcl
-
-tcl:
- @rc=0; for i in *.test; do LD_LIBRARY_PATH=..:$(LD_LIBRARY_PATH) $(tclsh) -encoding utf-8 $$i || rc=$?; done; exit $$rc
-
-clean:
- rm -f gorp.file2 gorp.file sleepx test1 exec.tmp1
diff --git a/tests/Makefile.in b/tests/Makefile.in
new file mode 100644
index 0000000..0567ff0
--- /dev/null
+++ b/tests/Makefile.in
@@ -0,0 +1,13 @@
+jimsh ?= ../jimsh
+tclsh ?= tclsh
+
+DEF_LD_PATH := @LD_LIBRARY_PATH@="@builddir@:$(@LD_LIBRARY_PATH@)"
+
+test:
+ @$(DEF_LD_PATH) $(jimsh) runall.tcl
+
+tcl:
+ @rc=0; for i in *.test; do $(tclsh) -encoding utf-8 $$i || rc=$?; done; exit $$rc
+
+clean:
+ rm -f gorp.file2 gorp.file sleepx test1 exec.tmp1
diff --git a/tests/alias.test b/tests/alias.test
index c539920..4f6e553 100644
--- a/tests/alias.test
+++ b/tests/alias.test
@@ -62,8 +62,8 @@ test curry-1.4 "Two word curry" {
list [$two x] [$two y]
} {1 0}
-collect
-test curry-1.5 "Delete curry" {
+test curry-1.5 "Delete curry" references {
+ collect
unset one two
collect
} {2}
diff --git a/tests/array.test b/tests/array.test
index ba88147..423276b 100644
--- a/tests/array.test
+++ b/tests/array.test
@@ -85,4 +85,50 @@ test array-1.14 "access array via unset var" -body {
expr {$a($b) + 4}
} -returnCodes error -result {can't read "b": no such variable}
+test array-1.15 "array unset non-variable" -body {
+ array unset nonvariable 4
+} -result {}
+
+test array-1.16 "array names non-variable" -body {
+ array names nonvariable
+} -result {}
+
+test array-1.17 "array get non-variable" -body {
+ array get nonvariable
+} -result {}
+
+# This seems like incorrect behaviour, but it matches tclsh
+test array-1.18 "array size non-array" -body {
+ set x 1
+ array size x
+} -result {0}
+
+# This seems like incorrect behaviour, but it matches tclsh
+test array-1.19 "array unset non-array" -body {
+ set x 6
+ array unset x 4
+} -result {}
+
+test array-1.20 "array stat" -body {
+ set output [array stat a]
+ regexp "1 entries in table.*number of buckets with 1 entries: 1" $output
+} -result {1}
+
+test array-1.21 "array stat non-array" -body {
+ array stat badvariable
+} -returnCodes error -result {"badvariable" isn't an array}
+
+test array-1.22 "array set non-even args" -body {
+ array set x {
+ 1 one
+ 2 two
+ 3
+}
+} -returnCodes error -result {list must have an even number of elements}
+
+test array-1.23 "array exists non-array" -body {
+ set x 4
+ array exists x
+} -result {0}
+
testreport
diff --git a/tests/binary.test b/tests/binary.test
index 3ba1970..8eb93f9 100644
--- a/tests/binary.test
+++ b/tests/binary.test
@@ -13,6 +13,9 @@
source [file dirname [info script]]/testing.tcl
needs cmd binary
+if {[testConstraint jim]} {
+ needs cmd pack
+}
testConstraint bigEndian [expr {$tcl_platform(byteOrder) eq "bigEndian"}]
testConstraint littleEndian [expr {$tcl_platform(byteOrder) eq "littleEndian"}]
testConstraint maxCompatibility 0
diff --git a/tests/clock.test b/tests/clock.test
new file mode 100644
index 0000000..4e32df4
--- /dev/null
+++ b/tests/clock.test
@@ -0,0 +1,54 @@
+source [file dirname [info script]]/testing.tcl
+
+needs cmd clock
+
+if {[catch {clock scan 2000 -format %Y}]} {
+ testConstraint clockscan 0
+} else {
+ testConstraint clockscan 1
+}
+
+test clock-1.1 {clock usage} -body {
+ clock
+} -returnCodes error -match glob -result {wrong # args: should be "clock command ..."*}
+
+test clock-1.2 {clock usage} -body {
+ clock blah
+} -returnCodes error -match glob -result {clock, unknown command "blah": should be clicks, format, microseconds, milliseconds, *seconds}
+
+# clock format
+test clock-3.1 {clock format tests} {
+ set clockval 657687766
+ clock format $clockval -format {%a %b %d %I:%M:%S %p %Y} -gmt true
+} {Sun Nov 04 03:02:46 AM 1990}
+
+test clock-3.5 {clock format tests} -body {
+ clock format
+} -returnCodes error -result {wrong # args: should be "clock format seconds ?-format string? ?-gmt boolean?"}
+
+test clock-3.6 {clock format tests} -body {
+ clock format foo
+} -returnCodes error -result {expected integer but got "foo"}
+
+test clock-3.8 {clock format tests} -body {
+ clock format a b c d e g
+} -returnCodes error -result {wrong # args: should be "clock format seconds ?-format string? ?-gmt boolean?"}
+
+test clock-3.9 {clock format tests} {
+ set clockval 0
+ clock format $clockval -format "%a %b %d %I:%M:%S %p %Y" -gmt true
+} "Thu Jan 01 12:00:00 AM 1970"
+
+test clock-3.10 {clock format tests} -body {
+ clock format 123 -bad arg
+} -returnCodes error -result {bad option "-bad": must be -format, or -gmt}
+
+test clock-3.11 {clock format tests} {
+ clock format 123 -format "x"
+} x
+
+test clock-4.1 {clock scan tests} clockscan {
+ clock scan {Sun Nov 04 03:02:46 AM 1990} -format {%a %b %d %I:%M:%S %p %Y} -gmt true
+} 657687766
+
+testreport
diff --git a/tests/defer.test b/tests/defer.test
new file mode 100644
index 0000000..c714656
--- /dev/null
+++ b/tests/defer.test
@@ -0,0 +1,237 @@
+# vim:se syntax=tcl:
+
+source [file dirname [info script]]/testing.tcl
+
+needs cmd defer
+needs cmd interp
+
+test defer-1.1 {defer in proc} {
+ set x -
+ proc a {} {
+ set x +
+ # This does nothing since it increments a local variable
+ defer {append x L}
+ # This increments the global variable
+ defer {append ::x G}
+ # Will return "-", not "-L" since return happens before defer triggers
+ return $x
+ }
+ list [a] $x
+} {+ -G}
+
+test defer-1.2 {set $defer directly} {
+ set x -
+ proc a {} {
+ lappend jim::defer {append ::x a}
+ lappend jim::defer {append ::x b}
+ return $jim::defer
+ }
+ list [a] $x
+} {{{append ::x a} {append ::x b}} -ba}
+
+
+test defer-1.3 {unset $defer} {
+ set x -
+ proc a {} {
+ defer {append ::x a}
+ # unset, to remove all defer actions
+ unset jim::defer
+ }
+ a
+ set x
+} {-}
+
+test defer-1.4 {error in defer - error} {
+ set x -
+ proc a {} {
+ # First defer script will not happen because of error in next defer script
+ defer {append ::x a}
+ # Error ignored because of error from proc
+ defer {blah}
+ # Last defer script will happen
+ defer {append ::x b}
+ # This error will take precedence over the error from defer
+ error "from a"
+ }
+ set rc [catch {a} msg]
+ list [info ret $rc] $msg $x
+} {error {from a} -b}
+
+test defer-1.5 {error in defer - return} {
+ set x -
+ proc a {} {
+ # First defer script will not happen
+ defer {append ::x a}
+ defer {blah}
+ # Last defer script will happen
+ defer {append ::x b}
+ return 3
+ }
+ set rc [catch {a} msg]
+ list [info ret $rc] $msg $x
+} {error {invalid command name "blah"} -b}
+
+test defer-1.6 {error in defer - ok} {
+ set x -
+ proc a {} {
+ # First defer script will not happen
+ defer {append ::x a}
+ # Error ignored because of error from proc
+ defer {blah}
+ # Last defer script will happen
+ defer {append ::x b}
+ }
+ set rc [catch {a} msg]
+ list [info ret $rc] $msg $x
+} {error {invalid command name "blah"} -b}
+
+test defer-1.7 {error in defer - break} {
+ set x -
+ proc a {} {
+ # First defer script will not happen
+ defer {append ::x a}
+ # This non-zero return code will take precedence over the proc return
+ defer {return -code 30 ret30}
+ # Last defer script will happen
+ defer {append ::x b}
+
+ return -code 20 ret20
+ }
+ set rc [catch {a} msg]
+ list [info ret $rc] $msg $x
+} {30 ret30 -b}
+
+test defer-1.8 {error in defer - tailcall} {
+ set x -
+ proc a {} {
+ # This will prevent tailcall from happening
+ defer {blah}
+
+ # Tailcall will not happen because of error in defer
+ tailcall append ::x a
+ }
+ set rc [catch {a} msg]
+ list [info ret $rc] $msg $x
+} {error {invalid command name "blah"} -}
+
+test defer-1.9 {Add to defer in defer body} {
+ set x -
+ proc a {} {
+ defer {
+ # Add to defer in defer
+ defer {
+ # This will do nothing
+ error here
+ }
+ }
+ defer {append ::x a}
+ }
+ a
+ set x
+} {-a}
+
+test defer-1.10 {Unset defer in defer body} {
+ set x -
+ proc a {} {
+ defer {
+ # This will do nothing
+ unset -nocomplain jim::defer
+ }
+ defer {append ::x a}
+ }
+ a
+ set x
+} {-a}
+
+test defer-1.11 {defer through tailcall} {
+ set x {}
+ proc a {} {
+ defer {append ::x a}
+ b
+ }
+ proc b {} {
+ defer {append ::x b}
+ # c will be invoked as through called from a but this
+ # won't make any difference for defer
+ tailcall c
+ }
+ proc c {} {
+ defer {append ::x c}
+ }
+ a
+ set x
+} {bca}
+
+test defer-1.12 {defer in recursive call} {
+ set x {}
+ proc a {n} {
+ # defer happens just before the return, so after the recursive call to a
+ defer {lappend ::x $n}
+ if {$n > 0} {
+ a $($n - 1)
+ }
+ }
+ a 3
+ set x
+} {0 1 2 3}
+
+test defer-1.13 {defer in recursive tailcall} {
+ set x {}
+ proc a {n} {
+ # defer happens just before the return, so before the tailcall to a
+ defer {lappend ::x $n}
+ if {$n > 0} {
+ tailcall a $($n - 1)
+ }
+ }
+ a 3
+ set x
+} {3 2 1 0}
+
+test defer-1.14 {defer capture variables} {
+ set x {}
+ proc a {} {
+ set y 1
+ # A normal defer will evaluate at the end of the proc, so $y may change
+ defer {lappend ::x $y}
+ incr y
+
+ # What if we want to capture the value of y here? list will work
+ defer [list lappend ::x $y]
+ incr y
+
+ # But with multiple statements, list doesn't work, so use a lambda
+ # to capture the value instead
+ defer [lambda {} {y} {
+ # multi-line script
+ lappend ::x $y
+ }]
+ incr y
+
+ return $y
+ }
+ list [a] $x
+} {4 {3 2 4}}
+
+test defer-2.1 {defer from interp} -body {
+ set i [interp]
+ # defer needs to have some effect to detect on exit,
+ # so write to a file
+ file delete defer.tmp
+ $i eval {
+ defer {
+ [open defer.tmp w] puts "leaving child"
+ }
+ }
+ set a [file exists defer.tmp]
+ $i delete
+ # Now the file should exist
+ set f [open defer.tmp]
+ $f gets b
+ $f close
+ list $a $b
+} -result {0 {leaving child}} -cleanup {
+ file delete defer.tmp
+}
+
+testreport
diff --git a/tests/dict2.test b/tests/dict2.test
index 2e9bcd4..54d4d0d 100644
--- a/tests/dict2.test
+++ b/tests/dict2.test
@@ -126,7 +126,7 @@ test dict-3.18 {array set non-dict get command} -constraints jim -returnCodes er
} -result {missing value to go with key}
test dict-4.1 {dict replace command} {
- dict replace {a b c d}
+ dict-sort [dict replace {a b c d}]
} {a b c d}
test dict-4.2 {dict replace command} {
dict-sort [dict replace {a b c d} e f]
@@ -197,6 +197,7 @@ test dict-7.9 {dict values command} -returnCodes error -body {
test dict-7.10 {dict values command} -returnCodes error -body {
dict values a
} -result {missing value to go with key}
+test dict-7.11 {dict values with duplicate values} {dict values {a b c b} b} {b b}
test dict-8.1 {dict size command} {dict size {}} 0
test dict-8.2 {dict size command} {dict size {a b}} 1
diff --git a/tests/event.test b/tests/event.test
index 096f21b..123b17c 100644
--- a/tests/event.test
+++ b/tests/event.test
@@ -15,8 +15,19 @@ needs cmd after eventloop
testConstraint socket [expr {[info commands socket] ne ""}]
testConstraint exec [expr {[info commands exec] ne ""}]
testConstraint signal [expr {[info commands signal] ne ""}]
-catch {[socket -ipv6 stream ::1:5000]} ipv6res
-testConstraint ipv6 [expr {$ipv6res ne "ipv6 not supported"}]
+catch {[socket -ipv6 stream ::1:5000]} res
+set ipv6 1
+if {[string match "*not supported" $res]} {
+ set ipv6 0
+} else {
+ # Also, if we can't bind an IPv6 socket, don't run IPv6 tests
+ if {[catch {
+ [socket -ipv6 stream.server ::1:5000] close
+ } msg opts]} {
+ set ipv6 0
+ }
+}
+testConstraint ipv6 $ipv6
test event-5.1 {Tcl_BackgroundError, HandleBgErrors procedures} jim {
catch {rename bgerror {}}
diff --git a/tests/exec.test b/tests/exec.test
index 8df1aa8..0eb218a 100644
--- a/tests/exec.test
+++ b/tests/exec.test
@@ -17,26 +17,23 @@ source [file dirname [info script]]/testing.tcl
needs cmd exec
needs cmd flush
-needs cmd after eventloop
testConstraint unix [expr {$tcl_platform(platform) eq {unix}}]
# Sleep which supports fractions of a second
if {[info commands sleep] eq {}} {
proc sleep {n} {
- after [expr {int($n * 1000)}]
+ exec {*}$::sleepx $n
}
}
set f [open sleepx w]
-puts $f "#![info nameofexecutable]"
puts $f {
- set seconds [lindex $argv 0]
- after [expr {int($seconds * 1000)}]
+ sleep "$@"
}
close $f
#catch {exec chmod +x sleepx}
-set sleepx [list [info nameofexecutable] sleepx]
+set sleepx [list sh sleepx]
# Basic operations.
@@ -349,7 +346,7 @@ test exec-12.1 {reaping background processes} -constraints unix -body {
exec echo foo > exec.tmp1 &
}
exec {*}$sleepx 0.1
- catch {exec ps | fgrep "echo foo" | fgrep -v fgrep | wc} msg
+ catch {exec ps | fgrep "echo foo" | fgrep -v grep | wc} msg
lindex $msg 0
} -cleanup {
file delete exec.tmp1
@@ -416,6 +413,29 @@ test exec-16.1 {flush output before exec} -body {
Second line
Third line}
+test exec-17.1 {redirecting from command pipeline} -setup {
+ makeFile "abc\nghi\njkl" gorp.file
+} -body {
+ set f [open "|cat gorp.file | wc -l" r]
+ set result [lindex [exec cat <@$f] 0]
+ close $f
+ set result
+} -cleanup {
+ file delete gorp.file
+} -result {3}
+
+test exec-17.2 {redirecting to command pipeline} -setup {
+ makeFile "abc\nghi\njkl" gorp.file
+} -body {
+ set f [open "|wc -l >gorp2.file" w]
+ exec cat gorp.file >@$f
+ flush $f
+ close $f
+ lindex [exec cat gorp2.file] 0
+} -cleanup {
+ file delete gorp.file gorp2.file
+} -result {3}
+
file delete sleepx
testreport
diff --git a/tests/exec2.test b/tests/exec2.test
index e43bba0..b4b42cc 100644
--- a/tests/exec2.test
+++ b/tests/exec2.test
@@ -5,6 +5,16 @@
source [file dirname [info script]]/testing.tcl
needs cmd exec
+foreach i {pipe signal wait} {
+ testConstraint $i [expr {[info commands $i] ne ""}]
+}
+# Some Windows platforms (e.g. AppVeyor) produce ENOSPC rather than killing
+# the child with SIGPIPE). So turn off this test for that platform
+if {[info exists env(MSYSTEM)] && $env(MSYSTEM) eq "MINGW32"} {
+ testConstraint nomingw32 0
+} else {
+ testConstraint nomingw32 1
+}
set d \"
set s '
@@ -44,4 +54,50 @@ test exec2-2.4 "Remove all env var" {
array set env [array get saveenv]
+test exec2-3.1 "close pipeline return value" {
+ set f [open |false]
+ set rc [catch {close $f} msg opts]
+ lassign [dict get $opts -errorcode] status pid exitcode
+ list $rc $msg $status $exitcode
+} {1 {child process exited abnormally} CHILDSTATUS 1}
+
+test exec2-3.2 "close pipeline return value" -constraints {pipe nomingw32} -body {
+ # Create a pipe and immediately close the read end
+ lassign [pipe] r w
+ close $r
+ # Write more than 64KB which is maximum size of the pipe buffers
+ # on all systems we have seen
+ set bigstring [string repeat a 100000]
+ set f [open [list |cat << $bigstring >$@w]]
+ set rc [catch {close $f} msg opts]
+ lassign [dict get $opts -errorcode] status pid exitcode
+ list $rc $msg $status $exitcode
+} -match glob -result {1 {child killed*} CHILDKILLED SIGPIPE}
+
+test exec2-3.3 "close pipeline with SIGPIPE blocked" -constraints {pipe signal nomingw32} -body {
+ # Create a pipe and immediately close the read end
+ lassign [pipe] r w
+ close $r
+ signal block SIGPIPE
+ # Write more than 64KB which is maximum size of the pipe buffers
+ # on all systems we have seen
+ set bigstring [string repeat a 100000]
+ set f [open [list |cat << $bigstring >$@w 2>/dev/null]]
+ set rc [catch {close $f} msg opts]
+ lassign [dict get $opts -errorcode] status pid exitcode
+ list $rc $msg $status $exitcode
+} -match glob -result {1 {child process exited*} CHILDSTATUS 1} -cleanup {
+ signal default SIGPIPE
+}
+
+test exec2-3.4 "wait for background task" -constraints wait -body {
+ set pid [exec sleep 0.1 &]
+ lassign [wait $pid] status newpid exitcode
+ if {$pid != $newpid} {
+ error "Got wrong pid from wait"
+ } else {
+ list $status $exitcode
+ }
+} -result {CHILDSTATUS 0}
+
testreport
diff --git a/tests/expr-base.test b/tests/expr-base.test
index 5c9e1da..27d583e 100644
--- a/tests/expr-base.test
+++ b/tests/expr-base.test
@@ -7,7 +7,6 @@ set good_testcases {
8 8
00 0
07 7
- 08 8
0x5 5
0x0 0
0x00 0
@@ -23,6 +22,11 @@ foreach {str exp} $good_testcases {
test expr-base-1.[incr i] "expr conversion" [list expr [list $str]] $exp
}
+# JimTCL specifically does not adhere to the octal default for numbers starting with zero
+test expr-base-2.1 {expr conversion jim specific} -constraints jim -body {
+ expr [list "08"]
+} -result {8}
+
set bad_testcases {
{0x + 1}
x
@@ -34,6 +38,6 @@ set bad_testcases {
set i 0
foreach str $bad_testcases {
- test expr-base-2.[incr i] "expr conversion failure" -returnCodes error -body [list expr $str] -match glob -result "*"
+ test expr-base-3.[incr i] "expr conversion failure" -returnCodes error -body [list expr $str] -match glob -result "*"
}
testreport
diff --git a/tests/expr-new.test b/tests/expr-new.test
index 86e776b..c04da05 100644
--- a/tests/expr-new.test
+++ b/tests/expr-new.test
@@ -294,7 +294,12 @@ test expr-9.10 {CompileRelationalExpr: error compiling relational arm} {
test expr-10.1 {CompileShiftExpr: just add expr} {expr 4+-2} 2
test expr-10.2 {CompileShiftExpr: just add expr} {expr 0xff-2} 253
test expr-10.3 {CompileShiftExpr: just add expr} {expr -1--2} 1
-test expr-10.4 {CompileShiftExpr: just add expr} {expr 1-0123} -122
+
+# JimTCL specifically does not adhere to the octal default for numbers starting with zero
+test expr-10.4 {CompileShiftExpr: just add expr} -constraints jim -body {
+ expr 1-0123
+} -result {-122}
+
test expr-10.5 {CompileShiftExpr: error in add expr} {
catch {expr x+3} msg
} {1}
@@ -316,7 +321,11 @@ test expr-10.11 {CompileShiftExpr: runtime error} {
test expr-11.1 {CompileAddExpr: just multiply expr} {expr 4*-2} -8
test expr-11.2 {CompileAddExpr: just multiply expr} {expr 0xff%2} 1
test expr-11.3 {CompileAddExpr: just multiply expr} {expr -1/2} -1
-test expr-11.4 {CompileAddExpr: just multiply expr} {expr 7891%0123} 19
+# JimTCL specifically does not adhere to the octal default for numbers starting with zero
+test expr-11.4 {CompileAddExpr: just multiply expr} -constraints jim -body {
+ expr 7891%0123
+} -result {19}
+
test expr-11.5 {CompileAddExpr: error in multiply expr} {
catch {expr x*3} msg
} {1}
@@ -367,7 +376,11 @@ test expr-12.11 {CompileMultiplyExpr: runtime error} {
} {1}
test expr-13.1 {CompileUnaryExpr: unary exprs} {expr -0xff} -255
-test expr-13.2 {CompileUnaryExpr: unary exprs} {expr +000123} 123
+# JimTCL specifically does not adhere to the octal default for numbers starting with zero
+test expr-13.2 {CompileUnaryExpr: unary exprs} -constraints jim -body {
+ expr +000123
+} -result {123}
+
test expr-13.3 {CompileUnaryExpr: unary exprs} {expr +--++36} 36
test expr-13.4 {CompileUnaryExpr: unary exprs} {expr !2} 0
test expr-13.5 {CompileUnaryExpr: unary exprs} {expr +--+-62.0} -62.0
@@ -400,7 +413,11 @@ test expr-13.16 {CompileUnaryExpr: error in primary expr} {
test expr-14.1 {CompilePrimaryExpr: literal primary} {expr 1} 1
test expr-14.2 {CompilePrimaryExpr: literal primary} {expr 123} 123
test expr-14.3 {CompilePrimaryExpr: literal primary} {expr 0xff} 255
-test expr-14.4 {CompilePrimaryExpr: literal primary} {expr 00010} 10
+# JimTCL specifically does not adhere to the octal default for numbers starting with zero
+test expr-14.4 {CompilePrimaryExpr: literal primary} -constraints jim -body {
+ expr 00010
+} -result {10}
+
test expr-14.5 {CompilePrimaryExpr: literal primary} {expr 62.0} 62.0
test expr-14.6 {CompilePrimaryExpr: literal primary} {
expr 3.1400000
diff --git a/tests/expr.test b/tests/expr.test
index dbe84f5..b195d4a 100644
--- a/tests/expr.test
+++ b/tests/expr.test
@@ -99,6 +99,14 @@ test expr-2.4 "Ternary operator - missing question" -body {
expr {1 : 2}
} -returnCodes error -match glob -result *
+test expr-2.5 "Ternary operator with -ve values" {
+ expr {-1?-2:-3}
+} -2
+
+test expr-2.6 "Ternary operator with -ve values" {
+ expr {0?-2:-3}
+} -3
+
test expr-3.1 "in, ni operators" {
set l {a b c d}
set c C
diff --git a/tests/exprsugar.test b/tests/exprsugar.test
index 9579203..943945a 100644
--- a/tests/exprsugar.test
+++ b/tests/exprsugar.test
@@ -48,5 +48,10 @@ test exprsugar-1.11 {Simple operations} {
test exprsugar-1.12 {Simple operations} {
set x $((2 + 4))
} 6
+# This necessary to ensure that things like exit will pass through expr-sugar
+test exprsugar-1.13 {Non-error return inside expr-sugar} -body {
+ proc a {} { break }
+ set x $([a])
+} -returnCodes break
testreport
diff --git a/tests/file.test b/tests/file.test
new file mode 100644
index 0000000..fb5a555
--- /dev/null
+++ b/tests/file.test
@@ -0,0 +1,156 @@
+source [file dirname [info script]]/testing.tcl
+
+needs cmd file
+
+test join-1.1 "One name" {
+ file join abc
+} {abc}
+
+test join-1.2 "One name with trailing slash" {
+ file join abc/
+} {abc}
+
+test join-1.3 "One name with leading slash" {
+ file join /abc
+} {/abc}
+
+test join-1.4 "One name with leading and trailing slash" {
+ file join /abc/
+} {/abc}
+
+test join-1.5 "Two names" {
+ file join abc def
+} {abc/def}
+
+test join-1.6 "Two names with dir trailing slash" {
+ file join abc/ def
+} {abc/def}
+
+test join-1.7 "Two names with dir leading slash" {
+ file join /abc def
+} {/abc/def}
+
+test join-1.8 "Two names with dir leading and trailing slash" {
+ file join /abc/ def
+} {/abc/def}
+
+test join-1.9 "Two names with file trailing slash" {
+ file join abc def/
+} {abc/def}
+
+test join-1.10 "Two names with file leading slash" {
+ file join abc /def
+} {/def}
+
+test join-1.11 "Two names with file leading and trailing slash" {
+ file join abc /def/
+} {/def}
+
+test join-1.12 "Two names with double slashes" {
+ file join abc/ /def
+} {/def}
+
+test join-1.13 "Join to root" {
+ file join / abc
+} {/abc}
+
+test join-1.14 "Join to root" {
+ set dir [file join / .]
+ # Either / or /. is OK here
+ expr {$dir in {/ /.}}
+} 1
+
+test join-1.15 "Join to root" {
+ file join / /
+} {/}
+
+test join-1.16 "Join to root" {
+ file join /abc /
+} {/}
+
+test join-1.17 "With trailing slash" {
+ file join /abc/def/ ghi/jkl
+} {/abc/def/ghi/jkl}
+
+test join-2.1 "Dir is empty string" {
+ file join "" def
+} {def}
+
+test join-2.2 "File is empty string" {
+ file join abc ""
+} {abc}
+
+test join-2.3 "Path too long" jim {
+ set components [string repeat {abcdefghi } 500]
+ list [catch [concat file join $components] msg] $msg
+} {1 {Path too long}}
+
+test tail-1.1 "One component" {
+ file tail abc
+} {abc}
+
+test tail-1.2 "Two components" {
+ file tail abc/def
+} {def}
+
+test tail-1.3 "Absolute one component" {
+ file tail /abc
+} {abc}
+
+test tail-1.4 "Trailing slash" {
+ file tail abc/
+} {abc}
+
+test dirname-1.1 "One component" {
+ file dirname abc
+} {.}
+
+test dirname-1.2 "Two components" {
+ file dirname abc/def
+} {abc}
+
+test dirname-1.3 "Absolute one component" {
+ file dirname /abc
+} {/}
+
+test dirname-1.4 "Trailing slash" {
+ file dirname abc/
+} {.}
+
+# These tests are courtesy of picol
+
+test file.12.1 "picol test" {file dirname /foo/bar/grill.txt} /foo/bar
+test file.12.2 "picol test" {file dirname /foo/bar/baz/} /foo/bar
+test file.12.3 "picol test" {file dirname /foo/bar/baz///} /foo/bar
+test file.12.4 "picol test" {file dirname /foo/bar/baz///qux} /foo/bar/baz
+test file.12.5 "picol test" {file dirname foo/bar/grill.txt} foo/bar
+test file.12.6 "picol test" {file dirname foo/bar/baz/} foo/bar
+test file.12.7 "picol test" {file dirname {}} .
+test file.12.8 "picol test" {file dirname /} /
+test file.12.9 "picol test" {file dirname ///} /
+
+test file.13.1 "picol test" {file tail /foo/bar/grill.txt} grill.txt
+test file.13.2 "picol test" {file tail /foo/bar/baz/} baz
+test file.13.3 "picol test" {file tail /foo/bar/baz///} baz
+test file.13.4 "picol test" {file dirname /foo/bar/baz///qux} /foo/bar/baz
+test file.13.5 "picol test" {file tail foo/bar/grill.txt} grill.txt
+test file.13.6 "picol test" {file tail foo/bar/baz/} baz
+test file.13.7 "picol test" {file tail {}} {}
+test file.13.8 "picol test" {file tail /} {}
+test file.13.9 "picol test" {file tail ///} {}
+
+test file.14 "picol test" {file join foo} foo
+test file.15 "picol test" {file join foo bar} foo/bar
+test file.16 "picol test" {file join foo /bar} /bar
+
+if {$tcl_platform(platform) eq {windows}} {
+ test file.17 "picol test" {file join foo C:/bar grill} C:/bar/grill
+}
+
+test file.18 "picol test" {file split {/foo/space station/bar}} {/ foo {space station} bar}
+test file.19 "picol test" {file split {/foo/space station/bar/}} {/ foo {space station} bar}
+test file.20 "picol test" {file split {foo/space station/bar}} {foo {space station} bar}
+test file.21 "picol test" {file split foo///bar} {foo bar}
+test file.22 "picol test" {file split foo} foo
+
+testreport
diff --git a/tests/filejoin.test b/tests/filejoin.test
deleted file mode 100644
index 7245938..0000000
--- a/tests/filejoin.test
+++ /dev/null
@@ -1,84 +0,0 @@
-source [file dirname [info script]]/testing.tcl
-
-needs cmd file
-
-test join-1.1 "One name" {
- file join abc
-} {abc}
-
-test join-1.2 "One name with trailing slash" {
- file join abc/
-} {abc}
-
-test join-1.3 "One name with leading slash" {
- file join /abc
-} {/abc}
-
-test join-1.4 "One name with leading and trailing slash" {
- file join /abc/
-} {/abc}
-
-test join-1.5 "Two names" {
- file join abc def
-} {abc/def}
-
-test join-1.6 "Two names with dir trailing slash" {
- file join abc/ def
-} {abc/def}
-
-test join-1.7 "Two names with dir leading slash" {
- file join /abc def
-} {/abc/def}
-
-test join-1.8 "Two names with dir leading and trailing slash" {
- file join /abc/ def
-} {/abc/def}
-
-test join-1.9 "Two names with file trailing slash" {
- file join abc def/
-} {abc/def}
-
-test join-1.10 "Two names with file leading slash" {
- file join abc /def
-} {/def}
-
-test join-1.11 "Two names with file leading and trailing slash" {
- file join abc /def/
-} {/def}
-
-test join-1.12 "Two names with double slashes" {
- file join abc/ /def
-} {/def}
-
-test join-1.13 "Join to root" {
- file join / abc
-} {/abc}
-
-test join-1.14 "Join to root" {
- set dir [file join / .]
- # Either / or /. is OK here
- expr {$dir in {/ /.}}
-} 1
-
-test join-1.15 "Join to root" {
- file join / /
-} {/}
-
-test join-1.16 "Join to root" {
- file join /abc /
-} {/}
-
-test join-2.1 "Dir is empty string" {
- file join "" def
-} {def}
-
-test join-2.2 "File is empty string" {
- file join abc ""
-} {abc}
-
-test join-2.3 "Path too long" jim {
- set components [string repeat {abcdefghi } 500]
- list [catch [concat file join $components] msg] $msg
-} {1 {Path too long}}
-
-testreport
diff --git a/tests/format.test b/tests/format.test
index 6a9ce85..bc3e461 100644
--- a/tests/format.test
+++ b/tests/format.test
@@ -508,6 +508,10 @@ test format-16.4 {format %b} {
format %b 1234567
} {100101101011010000111}
+test format-16.5 {format %b} {
+ list [catch {format %b badvalue} msg] $msg
+} {1 {expected integer but got "badvalue"}}
+
# cleanup
catch {unset a}
catch {unset b}
diff --git a/tests/glob2.test b/tests/glob2.test
index 5e4be31..80fdd12 100644
--- a/tests/glob2.test
+++ b/tests/glob2.test
@@ -236,34 +236,6 @@ test fileName-20.1 {Bug 1750300} -setup {
removeFile TAGS $d
removeDirectory foo
} -result 1
-test fileName-20.6 {Bug 2837800} -setup {
- # Recall that we have $env(HOME) set so that references
- # to ~ point to [temporaryDirectory]
- makeFile {} test ~
- set dd [makeDirectory isolate]
- set d [makeDirectory ./~ $dd]
- set savewd [pwd]
- cd $dd
-} -body {
- glob -nocomplain */test
-} -cleanup {
- cd $savewd
- removeDirectory ./~ $dd
- removeDirectory isolate
- removeFile test ~
-} -result {}
-test fileName-20.7 {Bug 2806250} -setup {
- set savewd [pwd]
- cd [temporaryDirectory]
- set d [makeDirectory isolate]
- makeFile {} ./~test $d
-} -body {
- file exists [lindex [glob -nocomplain isolate/*] 0]
-} -cleanup {
- removeFile ./~test $d
- removeDirectory isolate
- cd $savewd
-} -result 1
# cleanup
catch {file delete -force C:/globTest}
diff --git a/tests/json.test b/tests/json.test
new file mode 100644
index 0000000..ed73401
--- /dev/null
+++ b/tests/json.test
@@ -0,0 +1,173 @@
+source [file dirname [info script]]/testing.tcl
+
+needs cmd json::decode json
+needs cmd json::encode json
+
+set json {
+{
+ "fossil":"9c65b5432e4aeecf3556e5550c338ce93fd861cc",
+ "timestamp":1435827337,
+ "command":"timeline/checkin",
+ "procTimeUs":3333,
+ "procTimeMs":3,
+ "homepage":null,
+ "payload":{
+ "limit":1,
+ "timeline":[{
+ "type":"checkin",
+ "uuid":"f8b17edee7ff4f16517601c40eb713602aed7a52",
+ "isLeaf":true,
+ "timestamp":1435318826,
+ "user":"juef",
+ "comment":"adwaita-icon-theme: update to 3.17.3",
+ "parents":["de628be645cc62429d630f9234c56d1fddfdc2a3"],
+ "tags":["trunk"]
+ }]
+ }
+}}
+
+test json-decode-001 {top level keys} {
+ lsort [dict keys [json::decode $json]]
+} {command fossil homepage payload procTimeMs procTimeUs timestamp}
+
+# Note that the decode will return the keys/values in order
+test json-decode-002 {object value} {
+ dict get [json::decode $json] payload
+} {limit 1 timeline {{type checkin uuid f8b17edee7ff4f16517601c40eb713602aed7a52 isLeaf true timestamp 1435318826 user juef comment {adwaita-icon-theme: update to 3.17.3} parents de628be645cc62429d630f9234c56d1fddfdc2a3 tags trunk}}}
+
+test json-decode-003 {object nested value} {
+ dict get [json::decode $json] payload timeline
+} {{type checkin uuid f8b17edee7ff4f16517601c40eb713602aed7a52 isLeaf true timestamp 1435318826 user juef comment {adwaita-icon-theme: update to 3.17.3} parents de628be645cc62429d630f9234c56d1fddfdc2a3 tags trunk}}
+
+test json-decode-004 {array entry from nested value} {
+ lindex [dict get [json::decode $json] payload timeline] 0
+} {type checkin uuid f8b17edee7ff4f16517601c40eb713602aed7a52 isLeaf true timestamp 1435318826 user juef comment {adwaita-icon-theme: update to 3.17.3} parents de628be645cc62429d630f9234c56d1fddfdc2a3 tags trunk}
+
+test json-decode-005 {object value from child array entry} {
+ dict get [lindex [dict get [json::decode $json] payload timeline] 0] comment
+} {adwaita-icon-theme: update to 3.17.3}
+
+test json-decode-006 {unicode escape} {
+ dict get [json::decode {{"key":"\u2022"}}] key
+} \u2022
+
+test json-decode-011 {null subsitution} {
+ dict get [json::decode -null NULL $json] homepage
+} {NULL}
+
+test json-decode-012 {default null value} {
+ dict get [json::decode $json] homepage
+} {null}
+
+test json-decode-1.1 {Number forms} {
+ json::decode {[ 1, 2, 3.0, 4, Infinity, NaN, -Infinity, -0.0, 1e5, -1e-5 ]}
+} {1 2 3.0 4 Inf NaN -Inf -0.0 1e5 -1e-5}
+
+test json-2.1 {schema tests} {
+ lindex [json::decode -schema {[]}] 1
+} {list}
+
+test json-2.2 {schema tests} {
+ lindex [json::decode -schema {[1, 2]}] 1
+} {list num}
+
+test json-2.3 {schema tests} {
+ lindex [json::decode -schema {[1, 2, [3, 4], 4, 6]}] 1
+} {mixed num num {list num} num num}
+
+test json-2.4 {schema tests} {
+ lindex [json::decode -schema {{"a":1, "b":2}}] 1
+} {obj a num b num}
+
+test json-2.5 {schema tests} {
+ lindex [json::decode -schema {[1, 2, {a:"b", c:false}, "hello"]}] 1
+} {mixed num num {obj a str c bool} str}
+
+test json-2.6 {schema tests} {
+ lindex [json::decode -schema {[1, 2, {a:["b", 1, true, Infinity]}]}] 1
+} {mixed num num {obj a {mixed str num bool num}}}
+
+test json-2.7 {schema tests} {
+ lindex [json::decode -schema {[1, 2, {a:["b", 1, true, ["d", "e", "f"]]}]}] 1
+} {mixed num num {obj a {mixed str num bool {list str}}}}
+
+test json-2.8 {schema tests} {
+ lindex [json::decode -schema {[1, 2, true, false]}] 1
+} {mixed num num bool bool}
+
+test json-2.9 {schema tests} {
+ lindex [json::decode -schema {[{a:1},{b:2}]}] 1
+} {mixed {obj a num} {obj b num}}
+
+
+test json-3.1 {-index array} {
+ json::decode -index \
+ {[null, 1, 2, true, false, "hello"]}
+} {0 null 1 1 2 2 3 true 4 false 5 hello}
+
+test json-3.2 {-index array and object} {
+ json::decode -index \
+ {{"outer": [{"key": "value"}, {"key2": "value2"}]}}
+} {outer {0 {key value} 1 {key2 value2}}}
+
+test json-3.3 {-index array with -schema} {
+ json::decode -index -schema \
+ {[null, 1, 2, true, false, "hello"]}
+} "{0 null 1 1 2 2 3 true 4 false 5 hello}\
+ {mixed num num num bool bool str}"
+
+test json-3.4 {-index array with -schema 2} {
+ json::decode -index -schema \
+ {{"outer": [{"key": "value"}, {"key2": "value2"}]}}
+} "{outer {0 {key value} 1 {key2 value2}}}\
+ {obj outer {mixed {obj key str} {obj key2 str}}}"
+
+
+unset -nocomplain json
+
+test json-encode-1.1 {String with backslashes} {
+ json::encode {A "quoted string containing \backslashes\"}
+} {"A \"quoted string containing \\backslashes\\\""}
+
+test json-encode-1.2 {String with special chars} {
+ json::encode "Various \n special \b characters \t and /slash/ \r too"
+} {"Various \n special \b characters \t and \/slash\/ \r too"}
+
+test json-encode-1.3 {Array of numbers} {
+ json::encode {1 2 3.0 4 Inf NaN -Inf -0.0 1e5 -1e-5} {list num}
+} {[ 1, 2, 3.0, 4, Infinity, NaN, -Infinity, -0.0, 1e5, -1e-5 ]}
+
+test json-encode-1.4 {Array of strings} {
+ json::encode {1 2 3.0 4} list
+} {[ "1", "2", "3.0", "4" ]}
+
+test json-encode-1.5 {Array of objects} {
+ json::encode {{state NY city {New York} postalCode 10021 streetAddress {21 2nd Street}} {state CA city {Los Angeles} postalCode 10345 streetAddress {15 Hale St}}} {list obj postalCode num}
+} {[ { "city":"New York", "postalCode":10021, "state":"NY", "streetAddress":"21 2nd Street" }, { "city":"Los Angeles", "postalCode":10345, "state":"CA", "streetAddress":"15 Hale St" } ]}
+
+test json-encode-1.6 {Simple typeless object} {
+ json::encode {home {212 555-1234} fax {646 555-4567}} obj
+} {{ "fax":"646 555-4567", "home":"212 555-1234" }}
+
+test json-encode-1.7 {Primitives as num} {
+ json::encode {a false b null c true} {obj a num b num c num}
+} {{ "a":false, "b":null, "c":true }}
+
+test json-encode-1.8 {Complex schema} {
+ json::encode {Person {firstName John age 25 lastName Smith years {1972 1980 1995 2002} PhoneNumbers {home {212 555-1234} fax {646 555-4567}} Address {state NY city {New York} postalCode 10021 streetAddress {21 2nd Street}}}} {obj Person {obj age num Address {obj postalCode num} PhoneNumbers obj years {list num}}}
+} {{ "Person":{ "Address":{ "city":"New York", "postalCode":10021, "state":"NY", "streetAddress":"21 2nd Street" }, "PhoneNumbers":{ "fax":"646 555-4567", "home":"212 555-1234" }, "age":25, "firstName":"John", "lastName":"Smith", "years":[ 1972, 1980, 1995, 2002 ] } }}
+
+test json-encode-1.9 {Array of mixed types} {
+ json::encode {{a b c d} 44} {mixed list num}
+} {[ [ "a", "b", "c", "d" ], 44 ]}
+
+test json-encode-1.10 {Array of objects} {
+ json::encode {{state NY city {New York} postalCode 10021 streetAddress {21 2nd Street}} {state CA city {Los Angeles} postalCode 10345 streetAddress {15 Hale St}}} {list obj postalCode num}
+} {[ { "city":"New York", "postalCode":10021, "state":"NY", "streetAddress":"21 2nd Street" }, { "city":"Los Angeles", "postalCode":10345, "state":"CA", "streetAddress":"15 Hale St" } ]}
+
+test json-encode-1.11 {Forms of boolean} {
+ json::encode {-5 4 1 0 yes no true false} {list bool}
+} {[ true, true, true, false, true, false, true, false ]}
+
+
+testreport
diff --git a/tests/lock.test b/tests/lock.test
index 3672d6a..e7b0b2d 100644
--- a/tests/lock.test
+++ b/tests/lock.test
@@ -42,6 +42,19 @@ test lock-1.5 {grab lock from sub-process} {
set stat
} 0
+test lock-1.6 {wait for lock} {
+ # Run a child process that grabs the lock for 0.5 seconds
+ set pid [exec [info nameofexecutable] -e {set fh [open locktest.file r+]; $fh lock; sleep 0.5} >/dev/null &]
+ # And wait to acquire the lock in the parent. Should take ~500ms
+ set start [clock millis]
+ sleep 0.1
+ $fh lock -wait
+ set delta [expr {[clock millis] - $start}]
+ if {$delta < 100} {
+ error "Lock acquired after ${delta}ms"
+ }
+} {}
+
$fh close
file delete locktest.file
diff --git a/tests/lreplace.test b/tests/lreplace.test
index ba77505..32a2111 100644
--- a/tests/lreplace.test
+++ b/tests/lreplace.test
@@ -95,7 +95,18 @@ test lreplace-1.26 {lreplace command} {
[set foo [lreplace $foo end end]] \
[set foo [lreplace $foo end end]]
} {a {} {}}
-
+test lreplace-1.27 {lreplace command} -body {
+ lreplace x 1 1
+} -result x
+test lreplace-1.28 {lreplace command} -body {
+ lreplace x 1 1 y
+} -result {x y}
+test lreplace-1.29 {lreplace command} -body {
+ lreplace x 1 1 [error foo]
+} -returnCodes 1 -result {foo}
+test lreplace-1.30 {lreplace command} -body {
+ lreplace {not {}alist} 0 0 [error foo]
+} -returnCodes 1 -result {foo}
test lreplace-2.1 {lreplace errors} {
list [catch lreplace msg] $msg
@@ -114,10 +125,10 @@ test lreplace-2.5 {lreplace errors} {
} {1 {bad index "1x": must be integer?[+-]integer? or end?[+-]integer?}}
test lreplace-2.6 {lreplace errors} {
list [catch {lreplace x 3 2} msg] $msg
-} {1 {list doesn't contain element 3}}
+} {0 x}
test lreplace-2.7 {lreplace errors} {
list [catch {lreplace x 1 1} msg] $msg
-} {1 {list doesn't contain element 1}}
+} {0 x}
test lreplace-3.1 {lreplace won't modify shared argument objects} {
proc p {} {
@@ -127,6 +138,75 @@ test lreplace-3.1 {lreplace won't modify shared argument objects} {
p
} "a b c"
+test lreplace-4.1 {Bug ccc2c2cc98: lreplace edge case} {
+ lreplace {} 1 1
+} {}
+test lreplace-4.2 {Bug ccc2c2cc98: lreplace edge case} {
+ lreplace { } 1 1
+} {}
+test lreplace-4.3 {lreplace edge case} {
+ lreplace {1 2 3} 2 0
+} {1 2 3}
+test lreplace-4.4 {lreplace edge case} {
+ lreplace {1 2 3 4 5} 3 1
+} {1 2 3 4 5}
+test lreplace-4.5 {lreplace edge case} {
+ lreplace {1 2 3 4 5} 3 0 _
+} {1 2 3 _ 4 5}
+test lreplace-4.6 {lreplace end-x: bug a4cb3f06c4} {
+ lreplace {0 1 2 3 4} 0 end-2
+} {3 4}
+test lreplace-4.6.1 {lreplace end-x: bug a4cb3f06c4} {
+ lreplace {0 1 2 3 4} 0 end-2 a b c
+} {a b c 3 4}
+test lreplace-4.7 {lreplace with two end-indexes: increasing} {
+ lreplace {0 1 2 3 4} end-2 end-1
+} {0 1 4}
+test lreplace-4.7.1 {lreplace with two end-indexes: increasing} {
+ lreplace {0 1 2 3 4} end-2 end-1 a b c
+} {0 1 a b c 4}
+test lreplace-4.8 {lreplace with two end-indexes: equal} {
+ lreplace {0 1 2 3 4} end-2 end-2
+} {0 1 3 4}
+test lreplace-4.8.1 {lreplace with two end-indexes: equal} {
+ lreplace {0 1 2 3 4} end-2 end-2 a b c
+} {0 1 a b c 3 4}
+test lreplace-4.9 {lreplace with two end-indexes: decreasing} {
+ lreplace {0 1 2 3 4} end-2 end-3
+} {0 1 2 3 4}
+test lreplace-4.9.1 {lreplace with two end-indexes: decreasing} {
+ lreplace {0 1 2 3 4} end-2 end-3 a b c
+} {0 1 a b c 2 3 4}
+test lreplace-4.10 {lreplace with two equal indexes} {
+ lreplace {0 1 2 3 4} 2 2
+} {0 1 3 4}
+test lreplace-4.10.1 {lreplace with two equal indexes} {
+ lreplace {0 1 2 3 4} 2 2 a b c
+} {0 1 a b c 3 4}
+test lreplace-4.11 {lreplace end index first} {
+ lreplace {0 1 2 3 4} end-2 1 a b c
+} {0 1 a b c 2 3 4}
+test lreplace-4.12 {lreplace end index first} {
+ lreplace {0 1 2 3 4} end-2 2 a b c
+} {0 1 a b c 3 4}
+test lreplace-4.13 {lreplace empty list} {
+ lreplace {} 1 1 1
+} 1
+test lreplace-4.14 {lreplace empty list} {
+ lreplace {} 2 2 2
+} 2
+
+test lreplace-5.1 {compiled lreplace: Bug 47ac84309b} {
+ apply {x {
+ lreplace $x end 0
+ }} {a b c}
+} {a b c}
+test lreplace-5.2 {compiled lreplace: Bug 47ac84309b} {
+ apply {x {
+ lreplace $x end 0 A
+ }} {a b c}
+} {a b A c}
+
# cleanup
catch {unset foo}
::tcltest::cleanupTests
diff --git a/tests/lsort.test b/tests/lsort.test
index ca2fc49..5808b89 100644
--- a/tests/lsort.test
+++ b/tests/lsort.test
@@ -149,9 +149,12 @@ test lsort-3.9 {SortCompare procedure, -integer option} {
test lsort-3.10 {SortCompare procedure, -integer option} {
list [catch {lsort -integer {3 q}} msg] $msg
} {1 {expected integer but got "q"}}
-test lsort-3.11 {SortCompare procedure, -integer option} {
+# JimTCL specifically does not adhere to the octal default for numbers starting with zero
+test lsort-3.11 {SortCompare procedure, -integer option} -constraints jim -body {
lsort -integer {35 21 0x20 30 023 100 8}
-} {8 21 023 30 0x20 35 100}
+} -result {8 21 023 30 0x20 35 100}
+
+
test lsort-3.15 {SortCompare procedure, -command option} {
proc cmp {a b} {
error "comparison error"
@@ -176,9 +179,11 @@ test lsort-3.18 {SortCompare procedure, -command option} {
}
lsort -command cmp {48 6 18 22 21 35 36}
} {48 36 35 22 21 18 6}
-test lsort-3.19 {SortCompare procedure, -decreasing option} {
+# JimTCL specifically does not adhere to the octal default for numbers starting with zero
+test lsort-3.19 {SortCompare procedure, -decreasing optio} -constraints jim -body {
lsort -decreasing -integer {35 21 0x20 30 023 100 8}
-} {100 35 0x20 30 023 21 8}
+} -result {100 35 0x20 30 023 21 8}
+
test lsort-3.20 {SortCompare procedure, -real option} -body {
lsort -real {6...4 3}
} -returnCodes error -result {expected floating-point number but got "6...4"}
@@ -198,24 +203,8 @@ test lsort-3.22 {lsort, unique sort with index} {
} {0 4 5}
test lsort-4.26 {DefaultCompare procedure, signed characters} utf8 {
- set l [lsort [list "abc\u80" "abc"]]
- set viewlist {}
- foreach s $l {
- set viewelem ""
- set len [string length $s]
- for {set i 0} {$i < $len} {incr i} {
- set c [string index $s $i]
- scan $c %c d
- if {$d > 0 && $d < 128} {
- append viewelem $c
- } else {
- append viewelem "\\[format %03o [expr {$d & 0xff}]]"
- }
- }
- lappend viewlist $viewelem
- }
- set viewlist
-} [list "abc" "abc\\200"]
+ lsort [list "abc\u80" "abc"]
+} [list "abc" "abc\u80"]
test lsort-5.1 "Sort case insensitive" {
lsort -nocase {ba aB aa ce}
diff --git a/tests/misc.test b/tests/misc.test
index 60dcf78..0ff2a7a 100644
--- a/tests/misc.test
+++ b/tests/misc.test
@@ -475,6 +475,19 @@ test jimexpr-2.5 "double ** operator" {
expr {$result in {unsupported 8.0}}
} 1
+test jimexpr-2.6 "exit in expression" {
+ # The inner 'exit 0' should propagate through the if to
+ # the outer catch
+ catch -exit {
+ set x 1
+ if {[catch {exit 0}] == 1} {
+ set x 2
+ } else {
+ set x 3
+ }
+ }
+} 6
+
# This one is for test coverage of an unusual case
test jimobj-1.1 "duplicate obj with no dupIntRepProc" {
proc "x x" {} { return 2 }
@@ -550,7 +563,7 @@ test lmap-1.1 {lmap} {
test exprerr-1.1 {Error message with bad expr} {
catch {expr {5 ||}} msg
set msg
-} {Expression has bad operands to ||}
+} {syntax error in expression "5 ||": premature end of expression}
test eval-list-1.1 {Lost string rep with list} {
set x {set y 1; incr y}
diff --git a/tests/pid.test b/tests/pid.test
index 6a534a5..56ffcf8 100644
--- a/tests/pid.test
+++ b/tests/pid.test
@@ -19,7 +19,7 @@ needs cmd pid posix
needs cmd exec
catch {package require regexp}
testConstraint regexp [expr {[info commands regexp] ne {}}]
-testConstraint socket [expr {[info commands socket] ne {}}]
+testConstraint pipe [expr {[info commands pipe] ne {}}]
testConstraint getpid [expr {[catch pid] == 0}]
# This is a proxy for tcl || tclcompat
testConstraint pidchan [expr {[info commands fconfigure] ne {}}]
@@ -29,7 +29,7 @@ file delete test1
test pid-1.1 {pid command} {regexp getpid} {
regexp {(^[0-9]+$)|(^0x[0-9a-fA-F]+$)} [pid]
} 1
-test pid-1.2 {pid command} {regexp socket pidchan} {
+test pid-1.2 {pid command} {regexp pipe pidchan} {
set f [open {| echo foo | cat >test1} w]
set pids [pid $f]
close $f
@@ -38,7 +38,7 @@ test pid-1.2 {pid command} {regexp socket pidchan} {
[regexp {^[0-9]+$} [lindex $pids 1]] \
[expr {[lindex $pids 0] == [lindex $pids 1]}]
} {2 1 1 0}
-test pid-1.3 {pid command} {socket pidchan} {
+test pid-1.3 {pid command} {pipe pidchan} {
set f [open test1 w]
set pids [pid $f]
close $f
diff --git a/tests/prefix.test b/tests/prefix.test
index 1540f75..e81d429 100644
--- a/tests/prefix.test
+++ b/tests/prefix.test
@@ -14,12 +14,15 @@
source [file dirname [info script]]/testing.tcl
-needs cmd tcl::prefix prefix
+needs cmd tcl::prefix tclprefix
testConstraint namespace [expr {[info commands namespace] ne ""}]
test string-26.1 {tcl::prefix, too few args} -body {
tcl::prefix match a
} -returnCodes 1 -match glob -result {wrong # args: should be "tcl::prefix match ?options*? table string"}
+test string-26.1.1 {tcl::prefix, too few args} -body {
+ tcl::prefix
+} -returnCodes 1 -match glob -result {wrong # args: should be "tcl::prefix subcommand ?arg ...?"}
test string-26.2 {tcl::prefix, bad args} -body {
tcl::prefix match a b c
} -returnCodes 1 -result {bad option "a": must be -error, -exact, or -message}
@@ -27,6 +30,9 @@ test string-26.2.1 {tcl::prefix, empty table} -body {
tcl::prefix match {} foo
} -returnCodes 1 -result {bad option "foo": no valid options}
+test string-26.2.2 {tcl::prefix, bad args} -body {
+ tcl::prefix badoption
+} -returnCodes 1 -result {bad option "badoption": must be all, longest, or match}
test string-26.3.1 {tcl::prefix, bad args} -body {
diff --git a/tests/regcount.test b/tests/regcount.test
index 96f4ddd..5c1469e 100644
--- a/tests/regcount.test
+++ b/tests/regcount.test
@@ -84,6 +84,7 @@ foreach {pat str exp} {
(a|y){5,6}? baaaad {}
{[[:alpha:]]+} _bcd56_ef bcd
{[[:alnum:]]+} _bcd56_ef bcd56
+ {[\w]+} :_bcd56_ef _bcd56_ef
{[[:space:]]+} "_bc \t\r\n\f\v_" "{ \t\r\n\f\v}"
{[\x41-\x43]+} "_ABCD_" ABC
{\m.+\M} "#A test#" "{A test}"
diff --git a/tests/regexp.test b/tests/regexp.test
index 94107eb..2e9b13e 100644
--- a/tests/regexp.test
+++ b/tests/regexp.test
@@ -222,6 +222,10 @@ test regexp-6.8 {regexp errors} jim {
test regexp-6.9 {regexp errors, -start bad int check} {
list [catch {regexp -start bogus {^$} {}} msg] $msg
} {1 {bad index "bogus": must be integer?[+-]integer? or end?[+-]integer?}}
+test regexp-6.10 {regexp errors, -start too few args} {
+ list [catch {regexp -all -start} msg] $msg
+} {1 {wrong # args: should be "regexp ?-switch ...? exp string ?matchVar? ?subMatchVar ...?"}}
+
test regexp-7.1 {basic regsub operation} {
list [regsub aa+ xaxaaaxaa 111&222 foo] $foo
@@ -388,6 +392,10 @@ test regexp-11.11 {regsub without final variable name returns value} {
test regexp-11.12 {regsub without final variable name returns value} {
regsub -all b(\[^d\]*)d abcdeabcfde {,&,\1,}
} {a,bcd,c,ea,bcfd,cf,e}
+test regexp-11.13 {regsub errors, -start too few args} {
+ list [catch {regsub -all -nocase -nocase -start} msg] $msg
+} {1 {wrong # args: should be "regsub ?-switch ...? exp string subSpec ?varName?"}}
+
# This test crashes on the Mac unless you increase the Stack Space to about 1
# Meg. This is probably bigger than most users want...
diff --git a/tests/regexp2.test b/tests/regexp2.test
index f7cf516..1aee8cd 100644
--- a/tests/regexp2.test
+++ b/tests/regexp2.test
@@ -627,6 +627,12 @@ test regexpComp-16.3 {regsub -start} {
# lappend out [regsub -start 0 -all {\A(\w)} {abcde} {/\1} x] $x
# lappend out [regsub -start 2 -all {\A(\w)} {abcde} {/\1} x] $x
#} {5 /a/b/c/d/e 3 ab/c/d/e}
+test regexpComp-16.5 {regexp -start with utf8} utf8 {
+ regexp -inline -start 1 . \u0442\u0435\u0441\u0442
+} \u0435
+test regexpComp-16.6 {regexp -start with utf8} utf8 {
+ regsub -start 1 . \u0442\u0435\u0441\u0442 x
+} \u0442x\u0441\u0442
test regexpComp-17.1 {regexp -inline} {
regexp -inline b ababa
@@ -649,6 +655,9 @@ test regexpComp-17.6 {regexp -inline no matches} {
test regexpComp-17.7 {regexp -inline, no matchvars allowed} {
list [catch {regexp -inline b abc match} msg] $msg
} {1 {regexp match variables not allowed when using -inline}}
+test regexpComp-17.8 {regexp -indices utf8} utf8 {
+ regexp -all -inline -start 1 -indices . \u0442\u0435\u0441\u0442
+} {{1 1} {2 2} {3 3}}
test regexpComp-18.1 {regexp -all} {
regexp -all b bbbbb
diff --git a/tests/runall.tcl b/tests/runall.tcl
index 5b5d220..2b1c15a 100644
--- a/tests/runall.tcl
+++ b/tests/runall.tcl
@@ -24,25 +24,35 @@ if {[info commands interp] eq ""} {
foreach script [lsort [glob *.test]] {
set ::argv0 $script
- set i [interp]
+ if {$script eq "signal.test"} {
+ # special case, can't run this in a child interpeter
+ catch -exit {
+ source $script
+ }
+ foreach var {pass fail skip tests} {
+ incr total($var) $testinfo(num$var)
+ }
+ } else {
+ set i [interp]
- foreach var {argv0 auto_path} {
- $i eval [list set $var [set ::$var]]
- }
+ foreach var {argv0 auto_path} {
+ $i eval [list set $var [set ::$var]]
+ }
- # Run the test
- catch -exit {$i eval source $script} msg opts
- if {[info returncode $opts(-code)] eq "error"} {
- puts [format "%16s: --- error ($msg)" $script]
- incr total(fail)
- }
+ # Run the test
+ catch -exit {$i eval source $script} msg opts
+ if {[info returncode $opts(-code)] eq "error"} {
+ puts [format "%16s: --- error ($msg)" $script]
+ incr total(fail)
+ }
- # Extract the counts
- foreach var {pass fail skip tests} {
- incr total($var) [$i eval "set testinfo(num$var)"]
+ # Extract the counts
+ foreach var {pass fail skip tests} {
+ incr total($var) [$i eval "set testinfo(num$var)"]
+ }
+ $i delete
}
- $i delete
stdout flush
}
puts [string repeat = 73]
diff --git a/tests/subst.test b/tests/subst.test
index 353af5f..5128a99 100644
--- a/tests/subst.test
+++ b/tests/subst.test
@@ -142,10 +142,13 @@ test subst-10.2 {break in a subst} {
test subst-10.3 {break in a subst} {
subst {foo [if 1 { break; bogus code}] bar}
} {foo }
-test subst-10.4 {break in a subst, parse error} {
+
+# Note that unlike Tcl, Jim throws an error for these two before
+# evaluating
+test subst-10.4 {break in a subst, parse error} tcl {
subst {foo [break ; set a {}{} ; stuff] bar}
} {foo }
-test subst-10.5 {break in a subst, parse error} {
+test subst-10.5 {break in a subst, parse error} tcl {
subst {foo [break ;set bar baz ;set a {}{} ; stuff] bar}
} {foo }
diff --git a/tests/timer.test b/tests/timer.test
index 26ffa0a..a493004 100644
--- a/tests/timer.test
+++ b/tests/timer.test
@@ -189,16 +189,7 @@ test timer-6.4 {Tcl_AfterCmd procedure, ms argument} {
update
list $y $x
} {before after}
-test timer-6.5 {Tcl_AfterCmd procedure, ms argument} {
- set x before
- after 60 {set x after}
- after 40
- update
- set y $x
- after 40
- update
- list $y $x
-} {before after}
+
test timer-6.6 {Tcl_AfterCmd procedure, cancel option} {
list [catch {after cancel} msg] $msg
} {1 {wrong # args: should be "after cancel id|command"}}
diff --git a/tests/tree.test b/tests/tree.test
index 5a7cf74..22a16f5 100644
--- a/tests/tree.test
+++ b/tests/tree.test
@@ -110,6 +110,21 @@ test tree-2.3 "walk bfs" {
set result
} {rootnode childnode1 root.c2 root.c3 childnode2 n.c4 n.c5 n.c5.c6}
+test tree-3.1 "delete nodes" {
+ $pt delete node6
+ set result {}
+ $pt walk root bfs {action n} {
+ if {$action == "enter"} {
+ lappend result [$pt get $n name]
+ }
+ }
+ set result
+} {rootnode childnode1 root.c2 root.c3 childnode2 n.c4}
+
+test tree-3.2 "can't delete root node" -body {
+ $pt delete root
+} -returnCodes error -result {can't delete root node}
+
$pt destroy
testreport
diff --git a/tests/utftcl.test b/tests/utftcl.test
index 33b8933..fac14ce 100644
--- a/tests/utftcl.test
+++ b/tests/utftcl.test
@@ -74,7 +74,8 @@ test utf-4.2 {Tcl_NumUtfChars: length 1} {
test utf-4.3 {Tcl_NumUtfChars: long string} {
testnumutfchars [bytestring "abc\xC2\xA2\xe4\xb9\x8e\uA2\u4e4e"]
} {7}
-test utf-4.4 {Tcl_NumUtfChars: #u0000} {
+# This is an invalid utf-8 sequence. Not minimal, so should return 2
+test utf-4.4 {Tcl_NumUtfChars: #u0000} tcl {
testnumutfchars [bytestring "\xC0\x80"]
} {1}
test utf-4.5 {Tcl_NumUtfChars: zero length, calc len} {
@@ -86,7 +87,7 @@ test utf-4.6 {Tcl_NumUtfChars: length 1, calc len} {
test utf-4.7 {Tcl_NumUtfChars: long string, calc len} {
testnumutfchars [bytestring "abc\xC2\xA2\xe4\xb9\x8e\uA2\u4e4e"] 1
} {7}
-test utf-4.8 {Tcl_NumUtfChars: #u0000, calc len} {
+test utf-4.8 {Tcl_NumUtfChars: #u0000, calc len} tcl {
testnumutfchars [bytestring "\xC0\x80"] 1
} {1}
diff --git a/tests/zlib.test b/tests/zlib.test
index f2b4a36..7f56ab2 100644
--- a/tests/zlib.test
+++ b/tests/zlib.test
@@ -103,6 +103,10 @@ test zlib-3.11 {zlib gzip usage 4} -returnCodes error -body {
zlib gzip -level 9 a
} -result {wrong # args: should be "zlib gzip data ?-level level?"}
+test zlib-3.7 {zlib gunzip bad option} -returnCodes error -body {
+ zlib gunzip aaa -badoption
+} -result {wrong # args: should be "zlib gunzip data ?-buffersize size?"}
+
test zlib-4.1 {zlib gzip/gunzip} {
zlib gunzip [zlib gzip abcdefghijklm]
} abcdefghijklm
@@ -111,6 +115,18 @@ test zlib-4.2 {zlib gzip/gunzip level and chunk size} {
zlib gunzip [zlib gzip abcdefghijklm -level 9] -buffersize 128
} abcdefghijklm
+test zlib-4.3 {zlib gzip/gunzip bad level } -body {
+ zlib gzip abcdefghijklm -level -5
+} -returnCodes error -result {level must be 0 to 9}
+
+test zlib-4.4 {zlib gzip/gunzip bad level } -body {
+ zlib gzip abcdefghijklm -level 10
+} -returnCodes error -result {level must be 0 to 9}
+
+test zlib-4.5 {zlib gzip/gunzip non-int level } -body {
+ zlib gzip abcdefghijklm -level "abc"
+} -returnCodes error -result {wrong # args: should be "zlib gzip data ?-level level?"}
+
test zlib-5.1 {zlib crc32} {
format %x [expr {[zlib crc32 abcdeabcdeabcdeabcdeabcdeabcde] & 0xffffffff}]
} 6f73e901
@@ -119,4 +135,9 @@ test zlib-5.2 {zlib crc32} {
format %x [expr {[zlib crc32 abcdeabcdeabcdeabcdeabcdeabcde 42] & 0xffffffff}]
} ce1c4914
+test zlib-5.3 {zlib crc32 non-int arg} -body {
+ zlib crc32 abcdeabcdeabcdeabcdeabcdeabcde "abc"
+} -returnCodes error -result {expected integer but got "abc"}
+
+
testreport
diff --git a/tree.tcl b/tree.tcl
index d897c51..38a0a94 100644
--- a/tree.tcl
+++ b/tree.tcl
@@ -60,6 +60,10 @@ package require oo
# THe default index is "end"
# Returns the name of the newly added node
#
+# $pt delete <nodename>
+#
+# Delete the given node and all it's children.
+#
# $pt walk <nodename> dfs|bfs {actionvar nodevar} <code>
#
# Walks the tree starting from the given node, either breadth first (bfs)
@@ -155,6 +159,26 @@ tree method insert {node {index end}} {
return $childname
}
+tree method delete {node} {
+ if {$node eq "root"} {
+ return -code error "can't delete root node"
+ }
+ $self walk $node dfs {action subnode} {
+ if {$action eq "exit"} {
+ # Remove the node
+ dict unset tree $subnode
+ # And remove as a child of our parent
+ set parent [$self parent $subnode]
+ if {$parent ne ""} {
+ set siblings [dict get $children $parent]
+ set i [lsearch $siblings $subnode]
+ dict set children $parent [lreplace $siblings $i $i]
+ }
+ }
+ }
+}
+
+
tree method lappend {node key args} {
if {[dict exists $tree $node $key]} {
set result [dict get $tree $node $key]
diff --git a/utf8.c b/utf8.c
index 603e8ac..405c20d 100644
--- a/utf8.c
+++ b/utf8.c
@@ -1,7 +1,7 @@
/**
* UTF-8 utility functions
*
- * (c) 2010 Steve Bennett <steveb@workware.net.au>
+ * (c) 2010-2016 Steve Bennett <steveb@workware.net.au>
*
* See LICENCE for licence details.
*/
@@ -41,7 +41,7 @@ int utf8_fromunicode(char *p, unsigned uc)
}
}
-#if defined(JIM_UTF8) && !defined(JIM_BOOTSTRAP)
+#if defined(USE_UTF8) && !defined(JIM_BOOTSTRAP)
int utf8_charlen(int c)
{
if ((c & 0x80) == 0) {
@@ -56,8 +56,8 @@ int utf8_charlen(int c)
if ((c & 0xf8) == 0xf0) {
return 4;
}
- /* Invalid sequence */
- return -1;
+ /* Invalid sequence, so treat it as a single byte */
+ return 1;
}
int utf8_strlen(const char *str, int bytelen)
@@ -66,7 +66,7 @@ int utf8_strlen(const char *str, int bytelen)
if (bytelen < 0) {
bytelen = strlen(str);
}
- while (bytelen) {
+ while (bytelen > 0) {
int c;
int l = utf8_tounicode(str, &c);
charlen++;
@@ -76,12 +76,24 @@ int utf8_strlen(const char *str, int bytelen)
return charlen;
}
+int utf8_strwidth(const char *str, int charlen)
+{
+ int width = 0;
+ while (charlen) {
+ int c;
+ int l = utf8_tounicode(str, &c);
+ width += utf8_width(c);
+ str += l;
+ charlen--;
+ }
+ return width;
+}
+
int utf8_index(const char *str, int index)
{
const char *s = str;
while (index--) {
- int c;
- s += utf8_tounicode(s, &c);
+ s += utf8_charlen(*s);
}
return s - str;
}
@@ -118,19 +130,28 @@ int utf8_tounicode(const char *str, int *uc)
if (s[0] < 0xe0) {
if ((s[1] & 0xc0) == 0x80) {
*uc = ((s[0] & ~0xc0) << 6) | (s[1] & ~0x80);
- return 2;
+ if (*uc >= 0x80) {
+ return 2;
+ }
+ /* Otherwise this is an invalid sequence */
}
}
else if (s[0] < 0xf0) {
if (((str[1] & 0xc0) == 0x80) && ((str[2] & 0xc0) == 0x80)) {
*uc = ((s[0] & ~0xe0) << 12) | ((s[1] & ~0x80) << 6) | (s[2] & ~0x80);
- return 3;
+ if (*uc >= 0x800) {
+ return 3;
+ }
+ /* Otherwise this is an invalid sequence */
}
}
else if (s[0] < 0xf8) {
if (((str[1] & 0xc0) == 0x80) && ((str[2] & 0xc0) == 0x80) && ((str[3] & 0xc0) == 0x80)) {
*uc = ((s[0] & ~0xf0) << 18) | ((s[1] & ~0x80) << 12) | ((s[2] & ~0x80) << 6) | (s[3] & ~0x80);
- return 4;
+ if (*uc >= 0x10000) {
+ return 4;
+ }
+ /* Otherwise this is an invalid sequence */
}
}
@@ -144,6 +165,12 @@ struct casemap {
unsigned short altcode; /* alternate case code point */
};
+struct utf8range {
+ unsigned lower; /* lower inclusive */
+ unsigned upper; /* upper exclusive */
+};
+
+
/* Generated mapping tables */
#include "_unicode_mapping.c"
@@ -168,10 +195,29 @@ static int utf8_map_case(const struct casemap *mapping, int num, int ch)
return ch;
}
-/* Some platforms don't have isascii */
-#ifndef isascii
-#define isascii(C) (!((C) & ~0x7f))
-#endif
+static int cmp_range(const void *key, const void *cm)
+{
+ const struct utf8range *range = (const struct utf8range *)cm;
+ unsigned ch = *(unsigned *)key;
+ if (ch < range->lower) {
+ return -1;
+ }
+ if (ch >= range->upper) {
+ return 1;
+ }
+ return 0;
+}
+
+static int utf8_in_range(const struct utf8range *range, int num, int ch)
+{
+ const struct utf8range *r =
+ bsearch(&ch, range, num, sizeof(*range), cmp_range);
+
+ if (r) {
+ return 1;
+ }
+ return 0;
+}
int utf8_upper(int ch)
{
@@ -191,11 +237,26 @@ int utf8_lower(int ch)
int utf8_title(int ch)
{
- int newch = utf8_map_case(unicode_case_mapping_title, ARRAYSIZE(unicode_case_mapping_title), ch);
- if (newch != ch) {
- return newch ? newch : ch;
+ if (!isascii(ch)) {
+ int newch = utf8_map_case(unicode_case_mapping_title, ARRAYSIZE(unicode_case_mapping_title), ch);
+ if (newch != ch) {
+ return newch ? newch : ch;
+ }
}
return utf8_upper(ch);
}
+int utf8_width(int ch)
+{
+ if (!isascii(ch)) {
+ if (utf8_in_range(unicode_range_combining, ARRAYSIZE(unicode_range_combining), ch)) {
+ return 0;
+ }
+ if (utf8_in_range(unicode_range_wide, ARRAYSIZE(unicode_range_wide), ch)) {
+ return 2;
+ }
+ }
+ return 1;
+}
+
#endif /* JIM_BOOTSTRAP */
diff --git a/utf8.h b/utf8.h
index 7288113..9970683 100644
--- a/utf8.h
+++ b/utf8.h
@@ -8,7 +8,7 @@ extern "C" {
/**
* UTF-8 utility functions
*
- * (c) 2010 Steve Bennett <steveb@workware.net.au>
+ * (c) 2010-2016 Steve Bennett <steveb@workware.net.au>
*
* See LICENCE for licence details.
*/
@@ -29,7 +29,8 @@ int utf8_fromunicode(char *p, unsigned uc);
#include <ctype.h>
/* No utf-8 support. 1 byte = 1 char */
-#define utf8_strlen(S, B) ((B) < 0 ? strlen(S) : (B))
+#define utf8_strlen(S, B) ((B) < 0 ? (int)strlen(S) : (B))
+#define utf8_strwidth(S, B) utf8_strlen((S), (B))
#define utf8_tounicode(S, CP) (*(CP) = (unsigned char)*(S), 1)
#define utf8_getchars(CP, C) (*(CP) = (C), 1)
#define utf8_upper(C) toupper(C)
@@ -38,6 +39,7 @@ int utf8_fromunicode(char *p, unsigned uc);
#define utf8_index(C, I) (I)
#define utf8_charlen(C) 1
#define utf8_prev_len(S, L) 1
+#define utf8_width(C) 1
#else
#if !defined(JIM_BOOTSTRAP)
@@ -47,9 +49,8 @@ int utf8_fromunicode(char *p, unsigned uc);
/**
* Returns the length of the utf-8 sequence starting with 'c'.
*
- * Returns 1-4, or -1 if this is not a valid start byte.
- *
- * Note that charlen=4 is not supported by the rest of the API.
+ * Returns 1-4.
+ * If 'c' is not a valid start byte, returns 1.
*/
int utf8_charlen(int c);
@@ -67,6 +68,12 @@ int utf8_charlen(int c);
int utf8_strlen(const char *str, int bytelen);
/**
+ * Calculates the display width of the first 'charlen' characters in 'str'.
+ * See utf8_width()
+ */
+int utf8_strwidth(const char *str, int charlen);
+
+/**
* Returns the byte index of the given character in the utf-8 string.
*
* The string *must* be null terminated.
@@ -125,6 +132,13 @@ int utf8_title(int uc);
* Unicode code points > \uffff are returned unchanged.
*/
int utf8_lower(int uc);
+
+/**
+ * Returns the width (in characters) of the given unicode codepoint.
+ * This is 1 for normal letters and 0 for combining characters and 2 for wide characters.
+ */
+int utf8_width(int ch);
+
#endif /* JIM_BOOTSTRAP */
#endif