From 98023003024a72ce81efdc17cdae62710df2c041 Mon Sep 17 00:00:00 2001
From: varkor <github@varkor.com>
Date: Thu, 12 Apr 2018 11:46:52 +0100
Subject: [PATCH 01/13] Update .gitignore for libstd_unicode

---
 .gitignore | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/.gitignore b/.gitignore
index efbbf22ffe57b..2f65ee3e777a3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -74,13 +74,13 @@ __pycache__/
 /obj/
 /rt/
 /rustllvm/
-/src/libstd_unicode/DerivedCoreProperties.txt
-/src/libstd_unicode/DerivedNormalizationProps.txt
-/src/libstd_unicode/PropList.txt
-/src/libstd_unicode/ReadMe.txt
-/src/libstd_unicode/Scripts.txt
-/src/libstd_unicode/SpecialCasing.txt
-/src/libstd_unicode/UnicodeData.txt
+/src/libcore/unicode/DerivedCoreProperties.txt
+/src/libcore/unicode/DerivedNormalizationProps.txt
+/src/libcore/unicode/PropList.txt
+/src/libcore/unicode/ReadMe.txt
+/src/libcore/unicode/Scripts.txt
+/src/libcore/unicode/SpecialCasing.txt
+/src/libcore/unicode/UnicodeData.txt
 /stage[0-9]+/
 /target
 target/

From f53022f88d1820a1a8b2991f661e4373329d317f Mon Sep 17 00:00:00 2001
From: varkor <github@varkor.com>
Date: Thu, 12 Apr 2018 11:57:49 +0100
Subject: [PATCH 02/13] Update unicode/tables.rs with Mn

---
 src/libcore/unicode/tables.rs  | 120 +++++++++++++++++++++++++++++++++
 src/libcore/unicode/unicode.py |   2 +-
 2 files changed, 121 insertions(+), 1 deletion(-)

diff --git a/src/libcore/unicode/tables.rs b/src/libcore/unicode/tables.rs
index 3fbbc011bc41d..1d553fe5538c3 100644
--- a/src/libcore/unicode/tables.rs
+++ b/src/libcore/unicode/tables.rs
@@ -38,6 +38,126 @@ pub mod general_category {
         Cc_table.lookup(c)
     }
 
+    pub const Mn_table: &super::BoolTrie = &super::BoolTrie {
+        r1: [
+            0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
+            0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
+            0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
+            0xffffffffffffffff, 0x0000ffffffffffff, 0x0000000000000000, 0x0000000000000000,
+            0x0000000000000000, 0x0000000000000000, 0x00000000000000f8, 0x0000000000000000,
+            0x0000000000000000, 0x0000000000000000, 0xbffffffffffe0000, 0x00000000000000b6,
+            0x0000000007ff0000, 0x00010000fffff800, 0x0000000000000000, 0x00003d9f9fc00000,
+            0xffff000000020000, 0x00000000000007ff, 0x0001ffc000000000, 0x000ff80000000000
+        ],
+        r2: [
+            0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 10, 11, 12, 13, 14, 15, 16, 11, 17, 18, 7, 2, 19, 20,
+            21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 31, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 32, 33, 34, 35, 36, 2, 37, 2, 38, 2, 2, 2, 39, 40, 41, 2, 42,
+            43, 44, 45, 46, 2, 2, 47, 2, 2, 2, 48, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 49, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 50, 2, 51, 2, 52, 2, 2, 2, 2, 2, 2, 2, 2, 53,
+            2, 54, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 55, 56, 57, 2, 2, 2, 2, 58, 2, 2, 59, 60, 61, 62, 63, 64, 65,
+            66, 67, 2, 2, 2, 68, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 69, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 70, 2, 2, 2, 2, 2, 2, 2
+        ],
+        r3: &[
+            0x00003eeffbc00000, 0x000000000e000000, 0x0000000000000000, 0xfffffffbfff00000,
+            0x1400000000000007, 0x0000000c00fe21fe, 0x1000000000000002, 0x0000000c0000201e,
+            0x1000000000000006, 0x0023000000023986, 0xfc00000c000021be, 0x9000000000000002,
+            0x0000000c0040201e, 0x0000000000000004, 0x0000000000002001, 0xc000000000000001,
+            0x0000000c00603dc1, 0x0000000c00003040, 0x1800000000000003, 0x00000000005c0400,
+            0x07f2000000000000, 0x0000000000007f80, 0x1bf2000000000000, 0x0000000000003f00,
+            0x02a0000003000000, 0x7ffe000000000000, 0x1ffffffffeffe0df, 0x0000000000000040,
+            0x66fde00000000000, 0x001e0001c3000000, 0x0000000020002064, 0x00000000e0000000,
+            0x001c0000001c0000, 0x000c0000000c0000, 0x3fb0000000000000, 0x00000000200ffe40,
+            0x0000000000003800, 0x0000020000000060, 0x0e04018700000000, 0x0000000009800000,
+            0x9ff81fe57f400000, 0x3fff000000000000, 0x17d000000000000f, 0x000ff80000000004,
+            0x00003b3c00000003, 0x0003a34000000000, 0x00cff00000000000, 0x031021fdfff70000,
+            0xfbffffffffffffff, 0x0001ffe21fff0000, 0x0003800000000000, 0x8000000000000000,
+            0xffffffff00000000, 0x00003c0000000000, 0x0000000006000000, 0x3ff0800000000000,
+            0x00000000c0000000, 0x0003000000000000, 0x0000006000000844, 0x0003ffff00000030,
+            0x00003fc000000000, 0x000000000003ff80, 0x13c8000000000007, 0x0000002000000000,
+            0x00667e0000000000, 0x1000000000001008, 0xc19d000000000000, 0x0040300000000002,
+            0x0000212000000000, 0x0000000040000000, 0x0000ffff0000ffff
+        ],
+        r4: [
+            0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 4, 2, 5, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
+        ],
+        r5: &[
+            0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 6, 7, 8, 0, 9, 10, 11, 12, 13, 0, 0, 14, 15, 16, 0, 0, 17, 18, 19, 20,
+            0, 0, 21, 22, 23, 24, 25, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 28, 29, 0, 0, 0,
+            0, 0, 30, 0, 31, 0, 32, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 39, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 42, 43, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 46, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47,
+            47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+        ],
+        r6: &[
+            0x0000000000000000, 0x2000000000000000, 0x0000000100000000, 0x07c0000000000000,
+            0x870000000000f06e, 0x0000006000000000, 0xff00000000000002, 0x800000000000007f,
+            0x0678000000000003, 0x001fef8000000007, 0x0008000000000000, 0x7fc0000000000003,
+            0x0000000000001c00, 0x40d3800000000000, 0x000007f880000000, 0x1000000000000003,
+            0x001f1fc000000001, 0xff00000000000000, 0x000000000000005c, 0x85f8000000000000,
+            0x000000000000000d, 0xb03c000000000000, 0x0000000030000001, 0xa7f8000000000000,
+            0x0000000000000001, 0x00bf280000000000, 0x00000fbce0000000, 0x79f800000000067e,
+            0x000000000e7e0080, 0x00000000037ffc00, 0xbf7f000000000000, 0x006dfcfffffc0000,
+            0xb47e000000000000, 0x00000000000000bf, 0x001f000000000000, 0x007f000000000000,
+            0x0000000000078000, 0x0000000060000000, 0xf800038000000000, 0x00003c0000000fe7,
+            0x000000000000001c, 0xf87fffffffffffff, 0x00201fffffffffff, 0x0000fffef8000010,
+            0x000007dbf9ffff7f, 0x00000000007f0000, 0x00000000000007f0, 0xffffffffffffffff,
+            0x0000ffffffffffff
+        ],
+    };
+
+    pub fn Mn(c: char) -> bool {
+        Mn_table.lookup(c)
+    }
+
     pub const N_table: &super::BoolTrie = &super::BoolTrie {
         r1: [
             0x03ff000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
diff --git a/src/libcore/unicode/unicode.py b/src/libcore/unicode/unicode.py
index 75ec01944bfb9..260251b96dcb2 100755
--- a/src/libcore/unicode/unicode.py
+++ b/src/libcore/unicode/unicode.py
@@ -21,7 +21,7 @@
 # - UnicodeData.txt
 #
 # Since this should not require frequent updates, we just store this
-# out-of-line and check the unicode.rs file into git.
+# out-of-line and check the unicode.py file into git.
 
 import fileinput, re, os, sys, operator, math
 

From a0b5d3813e5793caed9a6cf973851d40b75bf7b9 Mon Sep 17 00:00:00 2001
From: varkor <github@varkor.com>
Date: Thu, 12 Apr 2018 12:09:47 +0100
Subject: [PATCH 03/13] Download unicode data files in directory of unicode.py

---
 src/libcore/unicode/unicode.py | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/src/libcore/unicode/unicode.py b/src/libcore/unicode/unicode.py
index 260251b96dcb2..2527c1c103e9d 100755
--- a/src/libcore/unicode/unicode.py
+++ b/src/libcore/unicode/unicode.py
@@ -25,6 +25,9 @@
 
 import fileinput, re, os, sys, operator, math
 
+# The directory in which this file resides.
+fdir = os.path.dirname(os.path.realpath(__file__)) + "/"
+
 preamble = '''// Copyright 2012-2016 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
@@ -61,11 +64,12 @@
 surrogate_codepoints = (0xd800, 0xdfff)
 
 def fetch(f):
-    if not os.path.exists(os.path.basename(f)):
+    path = fdir + os.path.basename(f)
+    if not os.path.exists(path):
         os.system("curl -O http://www.unicode.org/Public/UNIDATA/%s"
                   % f)
 
-    if not os.path.exists(os.path.basename(f)):
+    if not os.path.exists(path):
         sys.stderr.write("cannot load %s" % f)
         exit(1)
 
@@ -84,7 +88,7 @@ def load_unicode_data(f):
 
     udict = {}
     range_start = -1
-    for line in fileinput.input(f):
+    for line in fileinput.input(fdir + f):
         data = line.split(';')
         if len(data) != 15:
             continue
@@ -156,7 +160,7 @@ def load_unicode_data(f):
 
 def load_special_casing(f, to_upper, to_lower, to_title):
     fetch(f)
-    for line in fileinput.input(f):
+    for line in fileinput.input(fdir + f):
         data = line.split('#')[0].split(';')
         if len(data) == 5:
             code, lower, title, upper, _comment = data
@@ -243,7 +247,7 @@ def load_properties(f, interestingprops):
     re1 = re.compile("^ *([0-9A-F]+) *; *(\w+)")
     re2 = re.compile("^ *([0-9A-F]+)\.\.([0-9A-F]+) *; *(\w+)")
 
-    for line in fileinput.input(os.path.basename(f)):
+    for line in fileinput.input(fdir + os.path.basename(f)):
         prop = None
         d_lo = 0
         d_hi = 0
@@ -456,7 +460,7 @@ def emit_norm_module(f, canon, compat, combine, norm_props):
     canon_comp_keys = sorted(canon_comp.keys())
 
 if __name__ == "__main__":
-    r = "tables.rs"
+    r = fdir + "tables.rs"
     if os.path.exists(r):
         os.remove(r)
     with open(r, "w") as rf:
@@ -465,7 +469,7 @@ def emit_norm_module(f, canon, compat, combine, norm_props):
 
         # download and parse all the data
         fetch("ReadMe.txt")
-        with open("ReadMe.txt") as readme:
+        with open(fdir + "ReadMe.txt") as readme:
             pattern = "for Version (\d+)\.(\d+)\.(\d+) of the Unicode"
             unicode_version = re.search(pattern, readme.read()).groups()
         rf.write("""

From b72faf5795681352b5fba83dce91ee24c22e71c8 Mon Sep 17 00:00:00 2001
From: varkor <github@varkor.com>
Date: Thu, 12 Apr 2018 12:24:08 +0100
Subject: [PATCH 04/13] Keep tables.rs copyright notice up to date

---
 src/libcore/unicode/tables.rs  | 2 +-
 src/libcore/unicode/unicode.py | 8 ++++----
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/libcore/unicode/tables.rs b/src/libcore/unicode/tables.rs
index 1d553fe5538c3..1fdd92cd47d3f 100644
--- a/src/libcore/unicode/tables.rs
+++ b/src/libcore/unicode/tables.rs
@@ -1,4 +1,4 @@
-// Copyright 2012-2016 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2018 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
diff --git a/src/libcore/unicode/unicode.py b/src/libcore/unicode/unicode.py
index 2527c1c103e9d..d24b4eb4ce4e3 100755
--- a/src/libcore/unicode/unicode.py
+++ b/src/libcore/unicode/unicode.py
@@ -23,12 +23,12 @@
 # Since this should not require frequent updates, we just store this
 # out-of-line and check the unicode.py file into git.
 
-import fileinput, re, os, sys, operator, math
+import fileinput, re, os, sys, operator, math, datetime
 
 # The directory in which this file resides.
 fdir = os.path.dirname(os.path.realpath(__file__)) + "/"
 
-preamble = '''// Copyright 2012-2016 The Rust Project Developers. See the COPYRIGHT
+preamble = '''// Copyright 2012-{year} The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -43,8 +43,8 @@
 #![allow(missing_docs, non_upper_case_globals, non_snake_case)]
 
 use unicode::version::UnicodeVersion;
-use unicode::bool_trie::{BoolTrie, SmallBoolTrie};
-'''
+use unicode::bool_trie::{{BoolTrie, SmallBoolTrie}};
+'''.format(year = datetime.datetime.now().year)
 
 # Mapping taken from Table 12 from:
 # http://www.unicode.org/reports/tr44/#General_Category_Values

From 4694d20170e1a67f8a801c1f6dda11473d6fef77 Mon Sep 17 00:00:00 2001
From: varkor <github@varkor.com>
Date: Thu, 12 Apr 2018 11:39:18 +0100
Subject: [PATCH 05/13] Escape combining characters in escape_debug

---
 src/libcore/char/methods.rs    | 26 ++++++++++++++++++++++++--
 src/libcore/fmt/mod.rs         | 10 ++++++++--
 src/libcore/unicode/unicode.py |  2 +-
 3 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/src/libcore/char/methods.rs b/src/libcore/char/methods.rs
index 374adafef647d..c170e0c1ba1c9 100644
--- a/src/libcore/char/methods.rs
+++ b/src/libcore/char/methods.rs
@@ -229,8 +229,8 @@ impl char {
             '\r' => EscapeDefaultState::Backslash('r'),
             '\n' => EscapeDefaultState::Backslash('n'),
             '\\' | '\'' | '"' => EscapeDefaultState::Backslash(self),
-            c if is_printable(c) => EscapeDefaultState::Char(c),
-            c => EscapeDefaultState::Unicode(c.escape_unicode()),
+            _ if is_printable(self) => EscapeDefaultState::Char(self),
+            _ => EscapeDefaultState::Unicode(self.escape_unicode()),
         };
         EscapeDebug(EscapeDefault { state: init_state })
     }
@@ -692,6 +692,28 @@ impl char {
         general_category::Cc(self)
     }
 
+    /// Returns true if this `char` is a nonspacing mark code point, and false otherwise.
+    ///
+    /// 'Nonspacing mark code point' is defined in terms of the Unicode General
+    /// Category `Mn`.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// // U+0301, COMBINING ACUTE ACCENT
+    /// assert!('\u{301}'.is_nonspacing_mark());
+    /// assert!(!'e'.is_nonspacing_mark());
+    /// ```
+    #[unstable(feature = "rustc_private",
+               reason = "mainly needed for compiler internals",
+               issue = "27812")]
+    #[inline]
+    pub fn is_nonspacing_mark(self) -> bool {
+        general_category::Mn(self)
+    }
+
     /// Returns true if this `char` is numeric, and false otherwise.
     ///
     /// 'Numeric'-ness is defined in terms of the Unicode General Categories
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index 5820fe58932c6..1cfde5131026a 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -1844,8 +1844,14 @@ impl Display for str {
 impl Debug for char {
     fn fmt(&self, f: &mut Formatter) -> Result {
         f.write_char('\'')?;
-        for c in self.escape_debug() {
-            f.write_char(c)?
+        if self.is_nonspacing_mark() {
+            for c in self.escape_unicode() {
+                f.write_char(c)?
+            }
+        } else {
+            for c in self.escape_debug() {
+                f.write_char(c)?
+            }
         }
         f.write_char('\'')
     }
diff --git a/src/libcore/unicode/unicode.py b/src/libcore/unicode/unicode.py
index d24b4eb4ce4e3..5b3c181ea9bb3 100755
--- a/src/libcore/unicode/unicode.py
+++ b/src/libcore/unicode/unicode.py
@@ -496,7 +496,7 @@ def emit_norm_module(f, canon, compat, combine, norm_props):
                      ["Full_Composition_Exclusion"])
 
         # category tables
-        for (name, cat, pfuns) in ("general_category", gencats, ["N", "Cc"]), \
+        for (name, cat, pfuns) in ("general_category", gencats, ["N", "Cc", "Mn"]), \
                                   ("derived_property", derived, want_derived), \
                                   ("property", props, ["White_Space", "Pattern_White_Space"]):
             emit_property_module(rf, name, cat, pfuns)

From 699a2b5c7ee900c1ff99b70f9b6402ded78d3b3b Mon Sep 17 00:00:00 2001
From: varkor <github@varkor.com>
Date: Thu, 12 Apr 2018 22:19:02 +0100
Subject: [PATCH 06/13] Add test for Debug formatting of char

---
 src/libcore/tests/char.rs | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/src/libcore/tests/char.rs b/src/libcore/tests/char.rs
index ab90763abf8d5..76f28d493ab94 100644
--- a/src/libcore/tests/char.rs
+++ b/src/libcore/tests/char.rs
@@ -186,6 +186,14 @@ fn test_escape_debug() {
     assert_eq!(string('\u{100000}'), "\\u{100000}"); // private use 2
 }
 
+#[test]
+fn test_debug() {
+    assert_eq!(format!("{:?}", 'a'), "'a'");                // ASCII character
+    assert_eq!(format!("{:?}", 'é'), "'é'");                // printable character
+    assert_eq!(format!("{:?}", '\u{301}'), "'\\u{301}'");   // combining character
+    assert_eq!(format!("{:?}", '\u{e000}'), "'\\u{e000}'"); // private use 1
+}
+
 #[test]
 fn test_escape_default() {
     fn string(c: char) -> String {

From 68c4fb8f2f556aca74394e07cbfb457d216e75b9 Mon Sep 17 00:00:00 2001
From: varkor <github@varkor.com>
Date: Sat, 14 Apr 2018 00:21:25 +0100
Subject: [PATCH 07/13] Remove example in test for is_nonspacing_mark because
 it's currently private

---
 src/libcore/char/methods.rs | 10 ----------
 1 file changed, 10 deletions(-)

diff --git a/src/libcore/char/methods.rs b/src/libcore/char/methods.rs
index c170e0c1ba1c9..bffbba1a72351 100644
--- a/src/libcore/char/methods.rs
+++ b/src/libcore/char/methods.rs
@@ -696,16 +696,6 @@ impl char {
     ///
     /// 'Nonspacing mark code point' is defined in terms of the Unicode General
     /// Category `Mn`.
-    ///
-    /// # Examples
-    ///
-    /// Basic usage:
-    ///
-    /// ```
-    /// // U+0301, COMBINING ACUTE ACCENT
-    /// assert!('\u{301}'.is_nonspacing_mark());
-    /// assert!(!'e'.is_nonspacing_mark());
-    /// ```
     #[unstable(feature = "rustc_private",
                reason = "mainly needed for compiler internals",
                issue = "27812")]

From d3c257b0aed1f6c0d541659539f27aca5c5bc25a Mon Sep 17 00:00:00 2001
From: varkor <github@varkor.com>
Date: Wed, 16 May 2018 23:08:19 +0100
Subject: [PATCH 08/13] Use the correct output directory for downloading
 Unicode files

---
 src/libcore/unicode/unicode.py | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/libcore/unicode/unicode.py b/src/libcore/unicode/unicode.py
index 5b3c181ea9bb3..ce22c6f226a44 100755
--- a/src/libcore/unicode/unicode.py
+++ b/src/libcore/unicode/unicode.py
@@ -66,8 +66,7 @@
 def fetch(f):
     path = fdir + os.path.basename(f)
     if not os.path.exists(path):
-        os.system("curl -O http://www.unicode.org/Public/UNIDATA/%s"
-                  % f)
+        os.system("curl -o {0}{1} http://www.unicode.org/Public/UNIDATA/{1}".format(fdir, f))
 
     if not os.path.exists(path):
         sys.stderr.write("cannot load %s" % f)

From d7aa35eb1bdc61db0842ab81f6c96f24897e61ad Mon Sep 17 00:00:00 2001
From: varkor <github@varkor.com>
Date: Wed, 16 May 2018 23:19:58 +0100
Subject: [PATCH 09/13] Use Grapheme_Extend instead of Mn

---
 src/libcore/char/methods.rs    |  16 +-
 src/libcore/unicode/tables.rs  | 290 ++++++++++++++-------------------
 src/libcore/unicode/unicode.py |   5 +-
 3 files changed, 137 insertions(+), 174 deletions(-)

diff --git a/src/libcore/char/methods.rs b/src/libcore/char/methods.rs
index bffbba1a72351..bf7772492e5bc 100644
--- a/src/libcore/char/methods.rs
+++ b/src/libcore/char/methods.rs
@@ -229,6 +229,9 @@ impl char {
             '\r' => EscapeDefaultState::Backslash('r'),
             '\n' => EscapeDefaultState::Backslash('n'),
             '\\' | '\'' | '"' => EscapeDefaultState::Backslash(self),
+            _ if self.is_grapheme_extended() => {
+                EscapeDefaultState::Unicode(self.escape_unicode())
+            }
             _ if is_printable(self) => EscapeDefaultState::Char(self),
             _ => EscapeDefaultState::Unicode(self.escape_unicode()),
         };
@@ -692,16 +695,13 @@ impl char {
         general_category::Cc(self)
     }
 
-    /// Returns true if this `char` is a nonspacing mark code point, and false otherwise.
+    /// Returns true if this `char` is an extended grapheme character, and false otherwise.
     ///
-    /// 'Nonspacing mark code point' is defined in terms of the Unicode General
-    /// Category `Mn`.
-    #[unstable(feature = "rustc_private",
-               reason = "mainly needed for compiler internals",
-               issue = "27812")]
+    /// 'Extended grapheme character' is defined in terms of the Unicode Shaping and Rendering
+    /// Category `Grapheme_Extend`.
     #[inline]
-    pub fn is_nonspacing_mark(self) -> bool {
-        general_category::Mn(self)
+    pub(crate) fn is_grapheme_extended(self) -> bool {
+        derived_property::Grapheme_Extend(self)
     }
 
     /// Returns true if this `char` is numeric, and false otherwise.
diff --git a/src/libcore/unicode/tables.rs b/src/libcore/unicode/tables.rs
index 1fdd92cd47d3f..7f9c52e3aa562 100644
--- a/src/libcore/unicode/tables.rs
+++ b/src/libcore/unicode/tables.rs
@@ -38,126 +38,6 @@ pub mod general_category {
         Cc_table.lookup(c)
     }
 
-    pub const Mn_table: &super::BoolTrie = &super::BoolTrie {
-        r1: [
-            0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
-            0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
-            0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
-            0xffffffffffffffff, 0x0000ffffffffffff, 0x0000000000000000, 0x0000000000000000,
-            0x0000000000000000, 0x0000000000000000, 0x00000000000000f8, 0x0000000000000000,
-            0x0000000000000000, 0x0000000000000000, 0xbffffffffffe0000, 0x00000000000000b6,
-            0x0000000007ff0000, 0x00010000fffff800, 0x0000000000000000, 0x00003d9f9fc00000,
-            0xffff000000020000, 0x00000000000007ff, 0x0001ffc000000000, 0x000ff80000000000
-        ],
-        r2: [
-            0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 10, 11, 12, 13, 14, 15, 16, 11, 17, 18, 7, 2, 19, 20,
-            21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 31, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 32, 33, 34, 35, 36, 2, 37, 2, 38, 2, 2, 2, 39, 40, 41, 2, 42,
-            43, 44, 45, 46, 2, 2, 47, 2, 2, 2, 48, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 49, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 50, 2, 51, 2, 52, 2, 2, 2, 2, 2, 2, 2, 2, 53,
-            2, 54, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 55, 56, 57, 2, 2, 2, 2, 58, 2, 2, 59, 60, 61, 62, 63, 64, 65,
-            66, 67, 2, 2, 2, 68, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 69, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 70, 2, 2, 2, 2, 2, 2, 2
-        ],
-        r3: &[
-            0x00003eeffbc00000, 0x000000000e000000, 0x0000000000000000, 0xfffffffbfff00000,
-            0x1400000000000007, 0x0000000c00fe21fe, 0x1000000000000002, 0x0000000c0000201e,
-            0x1000000000000006, 0x0023000000023986, 0xfc00000c000021be, 0x9000000000000002,
-            0x0000000c0040201e, 0x0000000000000004, 0x0000000000002001, 0xc000000000000001,
-            0x0000000c00603dc1, 0x0000000c00003040, 0x1800000000000003, 0x00000000005c0400,
-            0x07f2000000000000, 0x0000000000007f80, 0x1bf2000000000000, 0x0000000000003f00,
-            0x02a0000003000000, 0x7ffe000000000000, 0x1ffffffffeffe0df, 0x0000000000000040,
-            0x66fde00000000000, 0x001e0001c3000000, 0x0000000020002064, 0x00000000e0000000,
-            0x001c0000001c0000, 0x000c0000000c0000, 0x3fb0000000000000, 0x00000000200ffe40,
-            0x0000000000003800, 0x0000020000000060, 0x0e04018700000000, 0x0000000009800000,
-            0x9ff81fe57f400000, 0x3fff000000000000, 0x17d000000000000f, 0x000ff80000000004,
-            0x00003b3c00000003, 0x0003a34000000000, 0x00cff00000000000, 0x031021fdfff70000,
-            0xfbffffffffffffff, 0x0001ffe21fff0000, 0x0003800000000000, 0x8000000000000000,
-            0xffffffff00000000, 0x00003c0000000000, 0x0000000006000000, 0x3ff0800000000000,
-            0x00000000c0000000, 0x0003000000000000, 0x0000006000000844, 0x0003ffff00000030,
-            0x00003fc000000000, 0x000000000003ff80, 0x13c8000000000007, 0x0000002000000000,
-            0x00667e0000000000, 0x1000000000001008, 0xc19d000000000000, 0x0040300000000002,
-            0x0000212000000000, 0x0000000040000000, 0x0000ffff0000ffff
-        ],
-        r4: [
-            0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 4, 2, 5, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
-        ],
-        r5: &[
-            0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 6, 7, 8, 0, 9, 10, 11, 12, 13, 0, 0, 14, 15, 16, 0, 0, 17, 18, 19, 20,
-            0, 0, 21, 22, 23, 24, 25, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 28, 29, 0, 0, 0,
-            0, 0, 30, 0, 31, 0, 32, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 39, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 42, 43, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 46, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47,
-            47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-        ],
-        r6: &[
-            0x0000000000000000, 0x2000000000000000, 0x0000000100000000, 0x07c0000000000000,
-            0x870000000000f06e, 0x0000006000000000, 0xff00000000000002, 0x800000000000007f,
-            0x0678000000000003, 0x001fef8000000007, 0x0008000000000000, 0x7fc0000000000003,
-            0x0000000000001c00, 0x40d3800000000000, 0x000007f880000000, 0x1000000000000003,
-            0x001f1fc000000001, 0xff00000000000000, 0x000000000000005c, 0x85f8000000000000,
-            0x000000000000000d, 0xb03c000000000000, 0x0000000030000001, 0xa7f8000000000000,
-            0x0000000000000001, 0x00bf280000000000, 0x00000fbce0000000, 0x79f800000000067e,
-            0x000000000e7e0080, 0x00000000037ffc00, 0xbf7f000000000000, 0x006dfcfffffc0000,
-            0xb47e000000000000, 0x00000000000000bf, 0x001f000000000000, 0x007f000000000000,
-            0x0000000000078000, 0x0000000060000000, 0xf800038000000000, 0x00003c0000000fe7,
-            0x000000000000001c, 0xf87fffffffffffff, 0x00201fffffffffff, 0x0000fffef8000010,
-            0x000007dbf9ffff7f, 0x00000000007f0000, 0x00000000000007f0, 0xffffffffffffffff,
-            0x0000ffffffffffff
-        ],
-    };
-
-    pub fn Mn(c: char) -> bool {
-        Mn_table.lookup(c)
-    }
-
     pub const N_table: &super::BoolTrie = &super::BoolTrie {
         r1: [
             0x03ff000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
@@ -213,7 +93,7 @@ pub mod general_category {
             0x03ff000003ff0000
         ],
         r4: [
-            0, 1, 2, 3, 3, 3, 4, 3, 3, 3, 3, 3, 3, 5, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+            0, 1, 2, 3, 3, 3, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
             3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
             3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
             3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
@@ -235,17 +115,12 @@ pub mod general_category {
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+            0
         ],
         r6: &[
             0x0000000000000000, 0x001fffffffffffff, 0x0000000000000402, 0x00000000003e0000,
             0x000003ff00000000, 0x0000ffc000000000, 0x03ff000000000000, 0xffc0000000000000,
-            0x0000000003ff0000, 0x00000000000003ff, 0xffffffffffffffff, 0x00007fffffffffff,
-            0xffffffffffffc000
+            0x0000000003ff0000, 0x00000000000003ff, 0xffffffffffffffff, 0x00007fffffffffff
         ],
     };
 
@@ -669,6 +544,127 @@ pub mod derived_property {
         Cased_table.lookup(c)
     }
 
+    pub const Grapheme_Extend_table: &super::BoolTrie = &super::BoolTrie {
+        r1: [
+            0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
+            0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
+            0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
+            0xffffffffffffffff, 0x0000ffffffffffff, 0x0000000000000000, 0x0000000000000000,
+            0x0000000000000000, 0x0000000000000000, 0x00000000000003f8, 0x0000000000000000,
+            0x0000000000000000, 0x0000000000000000, 0xbffffffffffe0000, 0x00000000000000b6,
+            0x0000000007ff0000, 0x00010000fffff800, 0x0000000000000000, 0x00003d9f9fc00000,
+            0xffff000000020000, 0x00000000000007ff, 0x0001ffc000000000, 0x000ff80000000000
+        ],
+        r2: [
+            0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 7, 2, 20, 21,
+            22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 32, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 33, 34, 35, 36, 37, 2, 38, 2, 39, 2, 2, 2, 40, 41, 42, 2, 43,
+            44, 45, 46, 47, 2, 2, 48, 2, 2, 2, 49, 2, 2, 2, 2, 2, 2, 2, 2, 50, 2, 2, 51, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 52, 2, 53, 2, 54, 2, 2, 2, 2, 2, 2, 2, 2, 55,
+            2, 56, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 57, 58, 59, 2, 2, 2, 2, 60, 2, 2, 61, 62, 63, 64, 65, 66, 67,
+            68, 69, 2, 2, 2, 70, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 71, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 72, 2, 2, 2, 2, 2, 58, 2
+        ],
+        r3: &[
+            0x00003eeffbc00000, 0x000000000e000000, 0x0000000000000000, 0xfffffffbfff00000,
+            0x1400000000000007, 0x0000000c00fe21fe, 0x5000000000000002, 0x0000000c0080201e,
+            0x1000000000000006, 0x0023000000023986, 0xfc00000c000021be, 0xd000000000000002,
+            0x0000000c00c0201e, 0x4000000000000004, 0x0000000000802001, 0xc000000000000001,
+            0x0000000c00603dc1, 0x9000000000000002, 0x0000000c00603044, 0x5800000000000003,
+            0x00000000805c8400, 0x07f2000000000000, 0x0000000000007f80, 0x1bf2000000000000,
+            0x0000000000003f00, 0x02a0000003000000, 0x7ffe000000000000, 0x1ffffffffeffe0df,
+            0x0000000000000040, 0x66fde00000000000, 0x001e0001c3000000, 0x0000000020002064,
+            0x00000000e0000000, 0x001c0000001c0000, 0x000c0000000c0000, 0x3fb0000000000000,
+            0x00000000200ffe40, 0x0000000000003800, 0x0000020000000060, 0x0e04018700000000,
+            0x0000000009800000, 0x9ff81fe57f400000, 0x7fff000000000000, 0x17d000000000000f,
+            0x000ff80000000004, 0x00003b3c00000003, 0x0003a34000000000, 0x00cff00000000000,
+            0x031021fdfff70000, 0xfbffffffffffffff, 0x0000000000001000, 0x0001ffffffff0000,
+            0x0003800000000000, 0x8000000000000000, 0xffffffff00000000, 0x0000fc0000000000,
+            0x0000000006000000, 0x3ff7800000000000, 0x00000000c0000000, 0x0003000000000000,
+            0x0000006000000844, 0x0003ffff00000030, 0x00003fc000000000, 0x000000000003ff80,
+            0x13c8000000000007, 0x0000002000000000, 0x00667e0000000000, 0x1000000000001008,
+            0xc19d000000000000, 0x0040300000000002, 0x0000212000000000, 0x0000000040000000,
+            0x0000ffff0000ffff
+        ],
+        r4: [
+            0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 4, 2, 5, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
+        ],
+        r5: &[
+            0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 6, 7, 8, 0, 9, 10, 11, 12, 13, 0, 0, 14, 15, 16, 0, 0, 17, 18, 19, 20,
+            0, 0, 21, 22, 23, 24, 25, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 28, 29, 0, 0, 0,
+            0, 0, 30, 0, 31, 0, 32, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 39, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 42, 43, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 46, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 48, 0, 0, 48, 48,
+            48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+        ],
+        r6: &[
+            0x0000000000000000, 0x2000000000000000, 0x0000000100000000, 0x07c0000000000000,
+            0x870000000000f06e, 0x0000006000000000, 0xff00000000000002, 0x800000000000007f,
+            0x0678000000000003, 0x001fef8000000007, 0x0008000000000000, 0x7fc0000000000003,
+            0x0000000000001c00, 0x40d3800000000000, 0x000007f880000000, 0x5000000000000003,
+            0x001f1fc000800001, 0xff00000000000000, 0x000000000000005c, 0xa5f9000000000000,
+            0x000000000000000d, 0xb03c800000000000, 0x0000000030000001, 0xa7f8000000000000,
+            0x0000000000000001, 0x00bf280000000000, 0x00000fbce0000000, 0x79f800000000067e,
+            0x000000000e7e0080, 0x00000000037ffc00, 0xbf7f000000000000, 0x006dfcfffffc0000,
+            0xb47e000000000000, 0x00000000000000bf, 0x001f000000000000, 0x007f000000000000,
+            0x0000000000078000, 0x0000000060000000, 0xf807c3a000000000, 0x00003c0000000fe7,
+            0x000000000000001c, 0xf87fffffffffffff, 0x00201fffffffffff, 0x0000fffef8000010,
+            0x000007dbf9ffff7f, 0x00000000007f0000, 0x00000000000007f0, 0xffffffff00000000,
+            0xffffffffffffffff, 0x0000ffffffffffff
+        ],
+    };
+
+    pub fn Grapheme_Extend(c: char) -> bool {
+        Grapheme_Extend_table.lookup(c)
+    }
+
     pub const Lowercase_table: &super::BoolTrie = &super::BoolTrie {
         r1: [
             0x0000000000000000, 0x07fffffe00000000, 0x0420040000000000, 0xff7fffff80000000,
@@ -1841,24 +1837,7 @@ pub mod conversions {
         ('\u{118b8}', ['\u{118d8}', '\0', '\0']), ('\u{118b9}', ['\u{118d9}', '\0', '\0']),
         ('\u{118ba}', ['\u{118da}', '\0', '\0']), ('\u{118bb}', ['\u{118db}', '\0', '\0']),
         ('\u{118bc}', ['\u{118dc}', '\0', '\0']), ('\u{118bd}', ['\u{118dd}', '\0', '\0']),
-        ('\u{118be}', ['\u{118de}', '\0', '\0']), ('\u{118bf}', ['\u{118df}', '\0', '\0']),
-        ('\u{1e900}', ['\u{1e922}', '\0', '\0']), ('\u{1e901}', ['\u{1e923}', '\0', '\0']),
-        ('\u{1e902}', ['\u{1e924}', '\0', '\0']), ('\u{1e903}', ['\u{1e925}', '\0', '\0']),
-        ('\u{1e904}', ['\u{1e926}', '\0', '\0']), ('\u{1e905}', ['\u{1e927}', '\0', '\0']),
-        ('\u{1e906}', ['\u{1e928}', '\0', '\0']), ('\u{1e907}', ['\u{1e929}', '\0', '\0']),
-        ('\u{1e908}', ['\u{1e92a}', '\0', '\0']), ('\u{1e909}', ['\u{1e92b}', '\0', '\0']),
-        ('\u{1e90a}', ['\u{1e92c}', '\0', '\0']), ('\u{1e90b}', ['\u{1e92d}', '\0', '\0']),
-        ('\u{1e90c}', ['\u{1e92e}', '\0', '\0']), ('\u{1e90d}', ['\u{1e92f}', '\0', '\0']),
-        ('\u{1e90e}', ['\u{1e930}', '\0', '\0']), ('\u{1e90f}', ['\u{1e931}', '\0', '\0']),
-        ('\u{1e910}', ['\u{1e932}', '\0', '\0']), ('\u{1e911}', ['\u{1e933}', '\0', '\0']),
-        ('\u{1e912}', ['\u{1e934}', '\0', '\0']), ('\u{1e913}', ['\u{1e935}', '\0', '\0']),
-        ('\u{1e914}', ['\u{1e936}', '\0', '\0']), ('\u{1e915}', ['\u{1e937}', '\0', '\0']),
-        ('\u{1e916}', ['\u{1e938}', '\0', '\0']), ('\u{1e917}', ['\u{1e939}', '\0', '\0']),
-        ('\u{1e918}', ['\u{1e93a}', '\0', '\0']), ('\u{1e919}', ['\u{1e93b}', '\0', '\0']),
-        ('\u{1e91a}', ['\u{1e93c}', '\0', '\0']), ('\u{1e91b}', ['\u{1e93d}', '\0', '\0']),
-        ('\u{1e91c}', ['\u{1e93e}', '\0', '\0']), ('\u{1e91d}', ['\u{1e93f}', '\0', '\0']),
-        ('\u{1e91e}', ['\u{1e940}', '\0', '\0']), ('\u{1e91f}', ['\u{1e941}', '\0', '\0']),
-        ('\u{1e920}', ['\u{1e942}', '\0', '\0']), ('\u{1e921}', ['\u{1e943}', '\0', '\0'])
+        ('\u{118be}', ['\u{118de}', '\0', '\0']), ('\u{118bf}', ['\u{118df}', '\0', '\0'])
     ];
 
     const to_uppercase_table: &[(char, [char; 3])] = &[
@@ -2472,24 +2451,7 @@ pub mod conversions {
         ('\u{118d8}', ['\u{118b8}', '\0', '\0']), ('\u{118d9}', ['\u{118b9}', '\0', '\0']),
         ('\u{118da}', ['\u{118ba}', '\0', '\0']), ('\u{118db}', ['\u{118bb}', '\0', '\0']),
         ('\u{118dc}', ['\u{118bc}', '\0', '\0']), ('\u{118dd}', ['\u{118bd}', '\0', '\0']),
-        ('\u{118de}', ['\u{118be}', '\0', '\0']), ('\u{118df}', ['\u{118bf}', '\0', '\0']),
-        ('\u{1e922}', ['\u{1e900}', '\0', '\0']), ('\u{1e923}', ['\u{1e901}', '\0', '\0']),
-        ('\u{1e924}', ['\u{1e902}', '\0', '\0']), ('\u{1e925}', ['\u{1e903}', '\0', '\0']),
-        ('\u{1e926}', ['\u{1e904}', '\0', '\0']), ('\u{1e927}', ['\u{1e905}', '\0', '\0']),
-        ('\u{1e928}', ['\u{1e906}', '\0', '\0']), ('\u{1e929}', ['\u{1e907}', '\0', '\0']),
-        ('\u{1e92a}', ['\u{1e908}', '\0', '\0']), ('\u{1e92b}', ['\u{1e909}', '\0', '\0']),
-        ('\u{1e92c}', ['\u{1e90a}', '\0', '\0']), ('\u{1e92d}', ['\u{1e90b}', '\0', '\0']),
-        ('\u{1e92e}', ['\u{1e90c}', '\0', '\0']), ('\u{1e92f}', ['\u{1e90d}', '\0', '\0']),
-        ('\u{1e930}', ['\u{1e90e}', '\0', '\0']), ('\u{1e931}', ['\u{1e90f}', '\0', '\0']),
-        ('\u{1e932}', ['\u{1e910}', '\0', '\0']), ('\u{1e933}', ['\u{1e911}', '\0', '\0']),
-        ('\u{1e934}', ['\u{1e912}', '\0', '\0']), ('\u{1e935}', ['\u{1e913}', '\0', '\0']),
-        ('\u{1e936}', ['\u{1e914}', '\0', '\0']), ('\u{1e937}', ['\u{1e915}', '\0', '\0']),
-        ('\u{1e938}', ['\u{1e916}', '\0', '\0']), ('\u{1e939}', ['\u{1e917}', '\0', '\0']),
-        ('\u{1e93a}', ['\u{1e918}', '\0', '\0']), ('\u{1e93b}', ['\u{1e919}', '\0', '\0']),
-        ('\u{1e93c}', ['\u{1e91a}', '\0', '\0']), ('\u{1e93d}', ['\u{1e91b}', '\0', '\0']),
-        ('\u{1e93e}', ['\u{1e91c}', '\0', '\0']), ('\u{1e93f}', ['\u{1e91d}', '\0', '\0']),
-        ('\u{1e940}', ['\u{1e91e}', '\0', '\0']), ('\u{1e941}', ['\u{1e91f}', '\0', '\0']),
-        ('\u{1e942}', ['\u{1e920}', '\0', '\0']), ('\u{1e943}', ['\u{1e921}', '\0', '\0'])
+        ('\u{118de}', ['\u{118be}', '\0', '\0']), ('\u{118df}', ['\u{118bf}', '\0', '\0'])
     ];
 
 }
diff --git a/src/libcore/unicode/unicode.py b/src/libcore/unicode/unicode.py
index ce22c6f226a44..1da5878c4c6d3 100755
--- a/src/libcore/unicode/unicode.py
+++ b/src/libcore/unicode/unicode.py
@@ -486,7 +486,7 @@ def emit_norm_module(f, canon, compat, combine, norm_props):
                 to_upper, to_lower, to_title) = load_unicode_data("UnicodeData.txt")
         load_special_casing("SpecialCasing.txt", to_upper, to_lower, to_title)
         want_derived = ["XID_Start", "XID_Continue", "Alphabetic", "Lowercase", "Uppercase",
-                        "Cased", "Case_Ignorable"]
+                        "Cased", "Case_Ignorable", "Grapheme_Extend"]
         derived = load_properties("DerivedCoreProperties.txt", want_derived)
         scripts = load_properties("Scripts.txt", [])
         props = load_properties("PropList.txt",
@@ -495,7 +495,7 @@ def emit_norm_module(f, canon, compat, combine, norm_props):
                      ["Full_Composition_Exclusion"])
 
         # category tables
-        for (name, cat, pfuns) in ("general_category", gencats, ["N", "Cc", "Mn"]), \
+        for (name, cat, pfuns) in ("general_category", gencats, ["N", "Cc"]), \
                                   ("derived_property", derived, want_derived), \
                                   ("property", props, ["White_Space", "Pattern_White_Space"]):
             emit_property_module(rf, name, cat, pfuns)
@@ -503,3 +503,4 @@ def emit_norm_module(f, canon, compat, combine, norm_props):
         # normalizations and conversions module
         emit_norm_module(rf, canon_decomp, compat_decomp, combines, norm_props)
         emit_conversions_module(rf, to_upper, to_lower, to_title)
+    print("Regenerated tables.rs.")

From 8c89e7f3d58ff110aa4de64aef8ef29f78ebf456 Mon Sep 17 00:00:00 2001
From: varkor <github@varkor.com>
Date: Wed, 16 May 2018 23:20:22 +0100
Subject: [PATCH 10/13] Make {char, str}::escape_debug and impl Debug for
 {char, str} consistent

---
 src/liballoc/tests/str.rs |  1 +
 src/libcore/fmt/mod.rs    | 10 ++--------
 src/libcore/tests/char.rs |  9 +--------
 3 files changed, 4 insertions(+), 16 deletions(-)

diff --git a/src/liballoc/tests/str.rs b/src/liballoc/tests/str.rs
index 1a47e5433ea90..2f38c8b3ae21e 100644
--- a/src/liballoc/tests/str.rs
+++ b/src/liballoc/tests/str.rs
@@ -999,6 +999,7 @@ fn test_escape_debug() {
     assert_eq!("\u{10000}\u{10ffff}".escape_debug(), "\u{10000}\\u{10ffff}");
     assert_eq!("ab\u{200b}".escape_debug(), "ab\\u{200b}");
     assert_eq!("\u{10d4ea}\r".escape_debug(), "\\u{10d4ea}\\r");
+    assert_eq!("\u{301}a\u{301}bé\u{e000}".escape_debug(), "\\u{301}a\\u{301}bé\\u{e000}");
 }
 
 #[test]
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index 1cfde5131026a..5820fe58932c6 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -1844,14 +1844,8 @@ impl Display for str {
 impl Debug for char {
     fn fmt(&self, f: &mut Formatter) -> Result {
         f.write_char('\'')?;
-        if self.is_nonspacing_mark() {
-            for c in self.escape_unicode() {
-                f.write_char(c)?
-            }
-        } else {
-            for c in self.escape_debug() {
-                f.write_char(c)?
-            }
+        for c in self.escape_debug() {
+            f.write_char(c)?
         }
         f.write_char('\'')
     }
diff --git a/src/libcore/tests/char.rs b/src/libcore/tests/char.rs
index 76f28d493ab94..d19e3b527696f 100644
--- a/src/libcore/tests/char.rs
+++ b/src/libcore/tests/char.rs
@@ -181,19 +181,12 @@ fn test_escape_debug() {
     assert_eq!(string('\u{ff}'), "\u{ff}");
     assert_eq!(string('\u{11b}'), "\u{11b}");
     assert_eq!(string('\u{1d4b6}'), "\u{1d4b6}");
+    assert_eq!(string('\u{301}'), "'\\u{301}'");     // combining character
     assert_eq!(string('\u{200b}'),"\\u{200b}");      // zero width space
     assert_eq!(string('\u{e000}'), "\\u{e000}");     // private use 1
     assert_eq!(string('\u{100000}'), "\\u{100000}"); // private use 2
 }
 
-#[test]
-fn test_debug() {
-    assert_eq!(format!("{:?}", 'a'), "'a'");                // ASCII character
-    assert_eq!(format!("{:?}", 'é'), "'é'");                // printable character
-    assert_eq!(format!("{:?}", '\u{301}'), "'\\u{301}'");   // combining character
-    assert_eq!(format!("{:?}", '\u{e000}'), "'\\u{e000}'"); // private use 1
-}
-
 #[test]
 fn test_escape_default() {
     fn string(c: char) -> String {

From c51f00280205d476651ff9f9a46cff6645b411a2 Mon Sep 17 00:00:00 2001
From: varkor <github@varkor.com>
Date: Thu, 17 May 2018 10:45:34 +0100
Subject: [PATCH 11/13] Only escape extended grapheme characters in the first
 position

---
 src/liballoc/str.rs         |  5 ++++-
 src/liballoc/tests/str.rs   |  2 +-
 src/libcore/char/methods.rs | 34 ++++++++++++++++++++++------------
 src/libcore/tests/char.rs   |  2 +-
 4 files changed, 28 insertions(+), 15 deletions(-)

diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs
index c10c0a6943392..8af14d3c698d2 100644
--- a/src/liballoc/str.rs
+++ b/src/liballoc/str.rs
@@ -372,12 +372,15 @@ impl str {
 
     /// Escapes each char in `s` with [`char::escape_debug`].
     ///
+    /// Note: only extended grapheme codepoints that begin the string will be
+    /// escaped.
+    ///
     /// [`char::escape_debug`]: primitive.char.html#method.escape_debug
     #[unstable(feature = "str_escape",
                reason = "return type may change to be an iterator",
                issue = "27791")]
     pub fn escape_debug(&self) -> String {
-        self.chars().flat_map(|c| c.escape_debug()).collect()
+        self.chars().enumerate().flat_map(|(i, c)| c.escape_debug_ext(i == 0)).collect()
     }
 
     /// Escapes each char in `s` with [`char::escape_default`].
diff --git a/src/liballoc/tests/str.rs b/src/liballoc/tests/str.rs
index 2f38c8b3ae21e..84c97abcbc28f 100644
--- a/src/liballoc/tests/str.rs
+++ b/src/liballoc/tests/str.rs
@@ -999,7 +999,7 @@ fn test_escape_debug() {
     assert_eq!("\u{10000}\u{10ffff}".escape_debug(), "\u{10000}\\u{10ffff}");
     assert_eq!("ab\u{200b}".escape_debug(), "ab\\u{200b}");
     assert_eq!("\u{10d4ea}\r".escape_debug(), "\\u{10d4ea}\\r");
-    assert_eq!("\u{301}a\u{301}bé\u{e000}".escape_debug(), "\\u{301}a\\u{301}bé\\u{e000}");
+    assert_eq!("\u{301}a\u{301}bé\u{e000}".escape_debug(), "\\u{301}a\u{301}bé\\u{e000}");
 }
 
 #[test]
diff --git a/src/libcore/char/methods.rs b/src/libcore/char/methods.rs
index bf7772492e5bc..f6b201fe06dea 100644
--- a/src/libcore/char/methods.rs
+++ b/src/libcore/char/methods.rs
@@ -187,6 +187,27 @@ impl char {
         }
     }
 
+    /// An extended version of `escape_debug` that optionally permits escaping
+    /// Extended Grapheme codepoints. This allows us to format characters like
+    /// nonspacing marks better when they're at the start of a string.
+    #[doc(hidden)]
+    #[unstable(feature = "str_internals", issue = "0")]
+    #[inline]
+    pub fn escape_debug_ext(self, escape_grapheme_extended: bool) -> EscapeDebug {
+        let init_state = match self {
+            '\t' => EscapeDefaultState::Backslash('t'),
+            '\r' => EscapeDefaultState::Backslash('r'),
+            '\n' => EscapeDefaultState::Backslash('n'),
+            '\\' | '\'' | '"' => EscapeDefaultState::Backslash(self),
+            _ if escape_grapheme_extended && self.is_grapheme_extended() => {
+                EscapeDefaultState::Unicode(self.escape_unicode())
+            }
+            _ if is_printable(self) => EscapeDefaultState::Char(self),
+            _ => EscapeDefaultState::Unicode(self.escape_unicode()),
+        };
+        EscapeDebug(EscapeDefault { state: init_state })
+    }
+
     /// Returns an iterator that yields the literal escape code of a character
     /// as `char`s.
     ///
@@ -224,18 +245,7 @@ impl char {
     #[stable(feature = "char_escape_debug", since = "1.20.0")]
     #[inline]
     pub fn escape_debug(self) -> EscapeDebug {
-        let init_state = match self {
-            '\t' => EscapeDefaultState::Backslash('t'),
-            '\r' => EscapeDefaultState::Backslash('r'),
-            '\n' => EscapeDefaultState::Backslash('n'),
-            '\\' | '\'' | '"' => EscapeDefaultState::Backslash(self),
-            _ if self.is_grapheme_extended() => {
-                EscapeDefaultState::Unicode(self.escape_unicode())
-            }
-            _ if is_printable(self) => EscapeDefaultState::Char(self),
-            _ => EscapeDefaultState::Unicode(self.escape_unicode()),
-        };
-        EscapeDebug(EscapeDefault { state: init_state })
+        self.escape_debug_ext(true)
     }
 
     /// Returns an iterator that yields the literal escape code of a character
diff --git a/src/libcore/tests/char.rs b/src/libcore/tests/char.rs
index d19e3b527696f..d2a9ed75be658 100644
--- a/src/libcore/tests/char.rs
+++ b/src/libcore/tests/char.rs
@@ -181,7 +181,7 @@ fn test_escape_debug() {
     assert_eq!(string('\u{ff}'), "\u{ff}");
     assert_eq!(string('\u{11b}'), "\u{11b}");
     assert_eq!(string('\u{1d4b6}'), "\u{1d4b6}");
-    assert_eq!(string('\u{301}'), "'\\u{301}'");     // combining character
+    assert_eq!(string('\u{301}'), "\\u{301}");     // combining character
     assert_eq!(string('\u{200b}'),"\\u{200b}");      // zero width space
     assert_eq!(string('\u{e000}'), "\\u{e000}");     // private use 1
     assert_eq!(string('\u{100000}'), "\\u{100000}"); // private use 2

From 2fa22effb6e1dd3b3e2e587ec5fcabefe2eb3443 Mon Sep 17 00:00:00 2001
From: varkor <github@varkor.com>
Date: Mon, 21 May 2018 18:57:49 +0100
Subject: [PATCH 12/13] Avoid counting characters and add explanatory comment
 to test

---
 src/liballoc/str.rs            | 8 +++++++-
 src/liballoc/tests/str.rs      | 6 ++++++
 src/libcore/unicode/unicode.py | 2 +-
 3 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs
index 8af14d3c698d2..823e56b64e398 100644
--- a/src/liballoc/str.rs
+++ b/src/liballoc/str.rs
@@ -380,7 +380,13 @@ impl str {
                reason = "return type may change to be an iterator",
                issue = "27791")]
     pub fn escape_debug(&self) -> String {
-        self.chars().enumerate().flat_map(|(i, c)| c.escape_debug_ext(i == 0)).collect()
+        let mut string = String::with_capacity(self.len());
+        let mut chars = self.chars();
+        if let Some(first) = chars.next() {
+            string.extend(first.escape_debug_ext(true))
+        }
+        string.extend(chars.flat_map(|c| c.escape_debug_ext(false)));
+        string
     }
 
     /// Escapes each char in `s` with [`char::escape_default`].
diff --git a/src/liballoc/tests/str.rs b/src/liballoc/tests/str.rs
index 84c97abcbc28f..d11bf5dc3e9a6 100644
--- a/src/liballoc/tests/str.rs
+++ b/src/liballoc/tests/str.rs
@@ -989,6 +989,12 @@ fn test_escape_unicode() {
 
 #[test]
 fn test_escape_debug() {
+    // Note that there are subtleties with the number of backslashes
+    // on the left- and right-hand sides. In particular, Unicode code points
+    // are usually escaped with two backslashes on the right-hand side, as
+    // they are escaped. However, when the character is unescaped (e.g. for
+    // printable characters), only a single backslash appears (as the character
+    // itself appears in the debug string).
     assert_eq!("abc".escape_debug(), "abc");
     assert_eq!("a c".escape_debug(), "a c");
     assert_eq!("éèê".escape_debug(), "éèê");
diff --git a/src/libcore/unicode/unicode.py b/src/libcore/unicode/unicode.py
index 1da5878c4c6d3..07f873b13c0c4 100755
--- a/src/libcore/unicode/unicode.py
+++ b/src/libcore/unicode/unicode.py
@@ -21,7 +21,7 @@
 # - UnicodeData.txt
 #
 # Since this should not require frequent updates, we just store this
-# out-of-line and check the unicode.py file into git.
+# out-of-line and check the tables.rs file into git.
 
 import fileinput, re, os, sys, operator, math, datetime
 

From b6539372e9d4dddb1c9f8c894f23bd4c3e8d9489 Mon Sep 17 00:00:00 2001
From: varkor <github@varkor.com>
Date: Mon, 21 May 2018 19:12:36 +0100
Subject: [PATCH 13/13] Fix tables.rs

---
 src/libcore/unicode/tables.rs  | 49 ++++++++++++++++++++++++++++++----
 src/libcore/unicode/unicode.py |  2 +-
 2 files changed, 45 insertions(+), 6 deletions(-)

diff --git a/src/libcore/unicode/tables.rs b/src/libcore/unicode/tables.rs
index 7f9c52e3aa562..e3d27474b9a71 100644
--- a/src/libcore/unicode/tables.rs
+++ b/src/libcore/unicode/tables.rs
@@ -93,7 +93,7 @@ pub mod general_category {
             0x03ff000003ff0000
         ],
         r4: [
-            0, 1, 2, 3, 3, 3, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+            0, 1, 2, 3, 3, 3, 4, 3, 3, 3, 3, 3, 3, 5, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
             3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
             3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
             3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
@@ -115,12 +115,17 @@ pub mod general_category {
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
         ],
         r6: &[
             0x0000000000000000, 0x001fffffffffffff, 0x0000000000000402, 0x00000000003e0000,
             0x000003ff00000000, 0x0000ffc000000000, 0x03ff000000000000, 0xffc0000000000000,
-            0x0000000003ff0000, 0x00000000000003ff, 0xffffffffffffffff, 0x00007fffffffffff
+            0x0000000003ff0000, 0x00000000000003ff, 0xffffffffffffffff, 0x00007fffffffffff,
+            0xffffffffffffc000
         ],
     };
 
@@ -1837,7 +1842,24 @@ pub mod conversions {
         ('\u{118b8}', ['\u{118d8}', '\0', '\0']), ('\u{118b9}', ['\u{118d9}', '\0', '\0']),
         ('\u{118ba}', ['\u{118da}', '\0', '\0']), ('\u{118bb}', ['\u{118db}', '\0', '\0']),
         ('\u{118bc}', ['\u{118dc}', '\0', '\0']), ('\u{118bd}', ['\u{118dd}', '\0', '\0']),
-        ('\u{118be}', ['\u{118de}', '\0', '\0']), ('\u{118bf}', ['\u{118df}', '\0', '\0'])
+        ('\u{118be}', ['\u{118de}', '\0', '\0']), ('\u{118bf}', ['\u{118df}', '\0', '\0']),
+        ('\u{1e900}', ['\u{1e922}', '\0', '\0']), ('\u{1e901}', ['\u{1e923}', '\0', '\0']),
+        ('\u{1e902}', ['\u{1e924}', '\0', '\0']), ('\u{1e903}', ['\u{1e925}', '\0', '\0']),
+        ('\u{1e904}', ['\u{1e926}', '\0', '\0']), ('\u{1e905}', ['\u{1e927}', '\0', '\0']),
+        ('\u{1e906}', ['\u{1e928}', '\0', '\0']), ('\u{1e907}', ['\u{1e929}', '\0', '\0']),
+        ('\u{1e908}', ['\u{1e92a}', '\0', '\0']), ('\u{1e909}', ['\u{1e92b}', '\0', '\0']),
+        ('\u{1e90a}', ['\u{1e92c}', '\0', '\0']), ('\u{1e90b}', ['\u{1e92d}', '\0', '\0']),
+        ('\u{1e90c}', ['\u{1e92e}', '\0', '\0']), ('\u{1e90d}', ['\u{1e92f}', '\0', '\0']),
+        ('\u{1e90e}', ['\u{1e930}', '\0', '\0']), ('\u{1e90f}', ['\u{1e931}', '\0', '\0']),
+        ('\u{1e910}', ['\u{1e932}', '\0', '\0']), ('\u{1e911}', ['\u{1e933}', '\0', '\0']),
+        ('\u{1e912}', ['\u{1e934}', '\0', '\0']), ('\u{1e913}', ['\u{1e935}', '\0', '\0']),
+        ('\u{1e914}', ['\u{1e936}', '\0', '\0']), ('\u{1e915}', ['\u{1e937}', '\0', '\0']),
+        ('\u{1e916}', ['\u{1e938}', '\0', '\0']), ('\u{1e917}', ['\u{1e939}', '\0', '\0']),
+        ('\u{1e918}', ['\u{1e93a}', '\0', '\0']), ('\u{1e919}', ['\u{1e93b}', '\0', '\0']),
+        ('\u{1e91a}', ['\u{1e93c}', '\0', '\0']), ('\u{1e91b}', ['\u{1e93d}', '\0', '\0']),
+        ('\u{1e91c}', ['\u{1e93e}', '\0', '\0']), ('\u{1e91d}', ['\u{1e93f}', '\0', '\0']),
+        ('\u{1e91e}', ['\u{1e940}', '\0', '\0']), ('\u{1e91f}', ['\u{1e941}', '\0', '\0']),
+        ('\u{1e920}', ['\u{1e942}', '\0', '\0']), ('\u{1e921}', ['\u{1e943}', '\0', '\0'])
     ];
 
     const to_uppercase_table: &[(char, [char; 3])] = &[
@@ -2451,7 +2473,24 @@ pub mod conversions {
         ('\u{118d8}', ['\u{118b8}', '\0', '\0']), ('\u{118d9}', ['\u{118b9}', '\0', '\0']),
         ('\u{118da}', ['\u{118ba}', '\0', '\0']), ('\u{118db}', ['\u{118bb}', '\0', '\0']),
         ('\u{118dc}', ['\u{118bc}', '\0', '\0']), ('\u{118dd}', ['\u{118bd}', '\0', '\0']),
-        ('\u{118de}', ['\u{118be}', '\0', '\0']), ('\u{118df}', ['\u{118bf}', '\0', '\0'])
+        ('\u{118de}', ['\u{118be}', '\0', '\0']), ('\u{118df}', ['\u{118bf}', '\0', '\0']),
+        ('\u{1e922}', ['\u{1e900}', '\0', '\0']), ('\u{1e923}', ['\u{1e901}', '\0', '\0']),
+        ('\u{1e924}', ['\u{1e902}', '\0', '\0']), ('\u{1e925}', ['\u{1e903}', '\0', '\0']),
+        ('\u{1e926}', ['\u{1e904}', '\0', '\0']), ('\u{1e927}', ['\u{1e905}', '\0', '\0']),
+        ('\u{1e928}', ['\u{1e906}', '\0', '\0']), ('\u{1e929}', ['\u{1e907}', '\0', '\0']),
+        ('\u{1e92a}', ['\u{1e908}', '\0', '\0']), ('\u{1e92b}', ['\u{1e909}', '\0', '\0']),
+        ('\u{1e92c}', ['\u{1e90a}', '\0', '\0']), ('\u{1e92d}', ['\u{1e90b}', '\0', '\0']),
+        ('\u{1e92e}', ['\u{1e90c}', '\0', '\0']), ('\u{1e92f}', ['\u{1e90d}', '\0', '\0']),
+        ('\u{1e930}', ['\u{1e90e}', '\0', '\0']), ('\u{1e931}', ['\u{1e90f}', '\0', '\0']),
+        ('\u{1e932}', ['\u{1e910}', '\0', '\0']), ('\u{1e933}', ['\u{1e911}', '\0', '\0']),
+        ('\u{1e934}', ['\u{1e912}', '\0', '\0']), ('\u{1e935}', ['\u{1e913}', '\0', '\0']),
+        ('\u{1e936}', ['\u{1e914}', '\0', '\0']), ('\u{1e937}', ['\u{1e915}', '\0', '\0']),
+        ('\u{1e938}', ['\u{1e916}', '\0', '\0']), ('\u{1e939}', ['\u{1e917}', '\0', '\0']),
+        ('\u{1e93a}', ['\u{1e918}', '\0', '\0']), ('\u{1e93b}', ['\u{1e919}', '\0', '\0']),
+        ('\u{1e93c}', ['\u{1e91a}', '\0', '\0']), ('\u{1e93d}', ['\u{1e91b}', '\0', '\0']),
+        ('\u{1e93e}', ['\u{1e91c}', '\0', '\0']), ('\u{1e93f}', ['\u{1e91d}', '\0', '\0']),
+        ('\u{1e940}', ['\u{1e91e}', '\0', '\0']), ('\u{1e941}', ['\u{1e91f}', '\0', '\0']),
+        ('\u{1e942}', ['\u{1e920}', '\0', '\0']), ('\u{1e943}', ['\u{1e921}', '\0', '\0'])
     ];
 
 }
diff --git a/src/libcore/unicode/unicode.py b/src/libcore/unicode/unicode.py
index 07f873b13c0c4..be0970b544406 100755
--- a/src/libcore/unicode/unicode.py
+++ b/src/libcore/unicode/unicode.py
@@ -66,7 +66,7 @@
 def fetch(f):
     path = fdir + os.path.basename(f)
     if not os.path.exists(path):
-        os.system("curl -o {0}{1} http://www.unicode.org/Public/UNIDATA/{1}".format(fdir, f))
+        os.system("curl -o {0}{1} ftp://ftp.unicode.org/Public/UNIDATA/{1}".format(fdir, f))
 
     if not os.path.exists(path):
         sys.stderr.write("cannot load %s" % f)