This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
regen/mk_invlists.pl: Collapse unused boundary values
authorKarl Williamson <khw@cpan.org>
Sat, 21 Jul 2018 20:09:24 +0000 (14:09 -0600)
committerKarl Williamson <khw@cpan.org>
Sat, 21 Jul 2018 21:26:48 +0000 (15:26 -0600)
Each Unicode property that specifies a boundary conditions, like
Word_Break, partitions all the Unicode code points into equivalence
classes.  So, for example, combining marks are placed into the Extend
class, because they are usually used to extend the previous character
and don't stand on their own.  mk_invlists.pl creates a boolean table of
all pairwise combinations of these classes, so that it knows by simple
lookup if the first character is class X and the next character is class
Y, if a break is permitted between these.

However, in some cases the answer isn't as simple as this, and other
means such as the characters in the vicinity of X and Y must be used to
disambiguate.  In these cases the table value in the cell (X,Y) isn't a
boolean, but is some other number indicating some specially crafted code
section to execute to resolve the issue.

Over the years, Unicode has tended to subdivide partitions into smaller
ones, as they've refined their algorithms.  But with Unicode 11, they
used another method and actually removed partitions.  Rather, they
retain the partitions, but no code point actually takes on the value of
an obsolete partition.

In order to not have to change the algorithm unnecessarily between
Unicode releases (who knows, they might change their minds, and
unobsolete these next time), mk_invlists has just kept the tables
around, but those cells won't ever get accessed because no code point in
the current release evaluates to them.

But that makes the tables unnecessarily large.  We can achieve the same
thing by mapping each unused equivalence class to the same value, which
we call 'unused'.  The algorithms that refer to the obsolete partitions
go through the data assigning values to the cells, but now the cells
overlap, since all obsolete classes map to the same row or column.  Thus
the data is total garbage.  But that doesn't matter, since that row or
column is never read by the data in the Unicode release the table is
constructed for.

mk_invlists also can compile older Unicode releases, and this makes
those tables smaller than before, with all unused classes in a
given release collapsed into a single row and single column of (unused)
garbage.

charclass_invlists.h
regen/mk_invlists.pl
uni_keywords.h

index 4f5c4dd..701ce95 100644 (file)
@@ -19927,11 +19927,11 @@ typedef enum {
        GCB_V = 12,
        GCB_XPG_XX = 13,
        GCB_ZWJ = 14,
-       GCB_E_Base = 15,
+       GCB_EDGE = 15,
+       GCB_E_Base = 16,
        GCB_E_Base_GAZ = 16,
-       GCB_E_Modifier = 17,
-       GCB_Glue_After_Zwj = 18,
-       GCB_EDGE = 19
+       GCB_E_Modifier = 16,
+       GCB_Glue_After_Zwj = 16
 } GCB_enum;
 
 static const GCB_enum _Perl_GCB_invmap[] = { /* for ASCII/Latin1 */
@@ -23517,11 +23517,11 @@ typedef enum {
        GCB_V = 12,
        GCB_XPG_XX = 13,
        GCB_ZWJ = 14,
-       GCB_E_Base = 15,
+       GCB_EDGE = 15,
+       GCB_E_Base = 16,
        GCB_E_Base_GAZ = 16,
-       GCB_E_Modifier = 17,
-       GCB_Glue_After_Zwj = 18,
-       GCB_EDGE = 19
+       GCB_E_Modifier = 16,
+       GCB_Glue_After_Zwj = 16
 } GCB_enum;
 
 static const GCB_enum _Perl_GCB_invmap[] = { /* for EBCDIC 1047 */
@@ -27108,11 +27108,11 @@ typedef enum {
        GCB_V = 12,
        GCB_XPG_XX = 13,
        GCB_ZWJ = 14,
-       GCB_E_Base = 15,
+       GCB_EDGE = 15,
+       GCB_E_Base = 16,
        GCB_E_Base_GAZ = 16,
-       GCB_E_Modifier = 17,
-       GCB_Glue_After_Zwj = 18,
-       GCB_EDGE = 19
+       GCB_E_Modifier = 16,
+       GCB_Glue_After_Zwj = 16
 } GCB_enum;
 
 static const GCB_enum _Perl_GCB_invmap[] = { /* for EBCDIC 037 */
@@ -84785,12 +84785,12 @@ typedef enum {
        WB_XPG_LE = 18,
        WB_XPG_XX = 19,
        WB_ZWJ = 20,
-       WB_E_Base = 21,
+       WB_EDGE = 21,
+       WB_E_Base = 22,
        WB_E_Base_GAZ = 22,
-       WB_E_Modifier = 23,
-       WB_Glue_After_Zwj = 24,
-       WB_EDGE = 25,
-       WB_UNKNOWN = 26
+       WB_E_Modifier = 22,
+       WB_Glue_After_Zwj = 22,
+       WB_UNKNOWN = 22
 } WB_enum;
 
 static const WB_enum _Perl_WB_invmap[] = { /* for ASCII/Latin1 */
@@ -88494,12 +88494,12 @@ typedef enum {
        WB_XPG_LE = 18,
        WB_XPG_XX = 19,
        WB_ZWJ = 20,
-       WB_E_Base = 21,
+       WB_EDGE = 21,
+       WB_E_Base = 22,
        WB_E_Base_GAZ = 22,
-       WB_E_Modifier = 23,
-       WB_Glue_After_Zwj = 24,
-       WB_EDGE = 25,
-       WB_UNKNOWN = 26
+       WB_E_Modifier = 22,
+       WB_Glue_After_Zwj = 22,
+       WB_UNKNOWN = 22
 } WB_enum;
 
 static const WB_enum _Perl_WB_invmap[] = { /* for EBCDIC 1047 */
@@ -92222,12 +92222,12 @@ typedef enum {
        WB_XPG_LE = 18,
        WB_XPG_XX = 19,
        WB_ZWJ = 20,
-       WB_E_Base = 21,
+       WB_EDGE = 21,
+       WB_E_Base = 22,
        WB_E_Base_GAZ = 22,
-       WB_E_Modifier = 23,
-       WB_Glue_After_Zwj = 24,
-       WB_EDGE = 25,
-       WB_UNKNOWN = 26
+       WB_E_Modifier = 22,
+       WB_Glue_After_Zwj = 22,
+       WB_UNKNOWN = 22
 } WB_enum;
 
 static const WB_enum _Perl_WB_invmap[] = { /* for EBCDIC 037 */
@@ -382972,29 +382972,28 @@ static const UV * const PL_uni_prop_ptrs[] = {
 #define GCB_EX_then_EM             3
 #define GCB_Maybe_Emoji_NonBreak   4
 
-static const U8 GCB_table[20][20] = {
-   /* 'XPG' stands for 'XPG_XX'; 'edg' stands for 'EDGE' */
-/*        XX CR CN EX  L LF LV LVT PP RI SM  T  V XPG ZWJ EB EBG EM GAZ edg */
-/* XX */ { 1, 1, 1, 0, 1, 1, 1,  1, 1, 1, 0, 1, 1,  1,  0, 1,  1, 1,  1,  1 },
-/* CR */ { 1, 1, 1, 1, 1, 0, 1,  1, 1, 1, 1, 1, 1,  1,  1, 1,  1, 1,  1,  1 },
-/* CN */ { 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1,  1,  1, 1,  1, 1,  1,  1 },
-/* EX */ { 1, 1, 1, 0, 1, 1, 1,  1, 1, 1, 0, 1, 1,  1,  0, 1,  1, 3,  1,  1 },
-/* L  */ { 1, 1, 1, 0, 0, 1, 0,  0, 1, 1, 0, 1, 0,  1,  0, 1,  1, 1,  1,  1 },
-/* LF */ { 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1,  1,  1, 1,  1, 1,  1,  1 },
-/* LV */ { 1, 1, 1, 0, 1, 1, 1,  1, 1, 1, 0, 0, 0,  1,  0, 1,  1, 1,  1,  1 },
-/* LVT*/ { 1, 1, 1, 0, 1, 1, 1,  1, 1, 1, 0, 0, 1,  1,  0, 1,  1, 1,  1,  1 },
-/* PP */ { 0, 1, 1, 0, 0, 1, 0,  0, 0, 0, 0, 0, 0,  0,  0, 0,  0, 0,  0,  1 },
-/* RI */ { 1, 1, 1, 0, 1, 1, 1,  1, 1, 2, 0, 1, 1,  1,  0, 1,  1, 1,  1,  1 },
-/* SM */ { 1, 1, 1, 0, 1, 1, 1,  1, 1, 1, 0, 1, 1,  1,  0, 1,  1, 1,  1,  1 },
-/* T  */ { 1, 1, 1, 0, 1, 1, 1,  1, 1, 1, 0, 0, 1,  1,  0, 1,  1, 1,  1,  1 },
-/* V  */ { 1, 1, 1, 0, 1, 1, 1,  1, 1, 1, 0, 0, 0,  1,  0, 1,  1, 1,  1,  1 },
-/* XPG*/ { 1, 1, 1, 0, 1, 1, 1,  1, 1, 1, 0, 1, 1,  1,  0, 1,  1, 1,  1,  1 },
-/* ZWJ*/ { 1, 1, 1, 0, 1, 1, 1,  1, 1, 1, 0, 1, 1,  4,  0, 1,  0, 1,  0,  1 },
-/* EB */ { 1, 1, 1, 0, 1, 1, 1,  1, 1, 1, 0, 1, 1,  1,  0, 1,  1, 0,  1,  1 },
-/* EBG*/ { 1, 1, 1, 0, 1, 1, 1,  1, 1, 1, 0, 1, 1,  1,  0, 1,  1, 0,  1,  1 },
-/* EM */ { 1, 1, 1, 0, 1, 1, 1,  1, 1, 1, 0, 1, 1,  1,  0, 1,  1, 1,  1,  1 },
-/* GAZ*/ { 1, 1, 1, 0, 1, 1, 1,  1, 1, 1, 0, 1, 1,  1,  0, 1,  1, 1,  1,  1 },
-/* edg*/ { 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1,  1,  1, 1,  1, 1,  1,  0 }
+static const U8 GCB_table[17][17] = {
+   /* 'XPG' stands for 'XPG_XX'; 'edg' stands for 'EDGE'; u stands
+    * for 'unused in this Unicode release (and the data in the row
+    * or column are garbage) */
+/*        XX CR CN EX  L LF LV LVT PP RI SM  T  V XPG ZWJ edg  u */
+/* XX */ { 1, 1, 1, 0, 1, 1, 1,  1, 1, 1, 0, 1, 1,  1,  0,  1, 1 },
+/* CR */ { 1, 1, 1, 1, 1, 0, 1,  1, 1, 1, 1, 1, 1,  1,  1,  1, 1 },
+/* CN */ { 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1,  1,  1,  1, 1 },
+/* EX */ { 1, 1, 1, 0, 1, 1, 1,  1, 1, 1, 0, 1, 1,  1,  0,  1, 3 },
+/* L  */ { 1, 1, 1, 0, 0, 1, 0,  0, 1, 1, 0, 1, 0,  1,  0,  1, 1 },
+/* LF */ { 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1,  1,  1,  1, 1 },
+/* LV */ { 1, 1, 1, 0, 1, 1, 1,  1, 1, 1, 0, 0, 0,  1,  0,  1, 1 },
+/* LVT*/ { 1, 1, 1, 0, 1, 1, 1,  1, 1, 1, 0, 0, 1,  1,  0,  1, 1 },
+/* PP */ { 0, 1, 1, 0, 0, 1, 0,  0, 0, 0, 0, 0, 0,  0,  0,  1, 0 },
+/* RI */ { 1, 1, 1, 0, 1, 1, 1,  1, 1, 2, 0, 1, 1,  1,  0,  1, 1 },
+/* SM */ { 1, 1, 1, 0, 1, 1, 1,  1, 1, 1, 0, 1, 1,  1,  0,  1, 1 },
+/* T  */ { 1, 1, 1, 0, 1, 1, 1,  1, 1, 1, 0, 0, 1,  1,  0,  1, 1 },
+/* V  */ { 1, 1, 1, 0, 1, 1, 1,  1, 1, 1, 0, 0, 0,  1,  0,  1, 1 },
+/* XPG*/ { 1, 1, 1, 0, 1, 1, 1,  1, 1, 1, 0, 1, 1,  1,  0,  1, 1 },
+/* ZWJ*/ { 1, 1, 1, 0, 1, 1, 1,  1, 1, 1, 0, 1, 1,  4,  0,  1, 0 },
+/* edg*/ { 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1,  1,  1,  0, 1 },
+/* u  */ { 1, 1, 1, 0, 1, 1, 1,  1, 1, 1, 0, 1, 1,  1,  0,  1, 0 }
 };
 
 #define LB_NOBREAK                        0
@@ -383064,36 +383063,35 @@ static const U8 LB_table[39][39] = {
 #define WB_NU_then_MB_or_MN_or_SQ        14
 #define WB_RI_then_RI                    16
 
-static const U8 WB_table[26][26] = {
-   /* 'Ext' stands for 'Extend'; 'XPG' stands for 'XPG_LE'; 'XPH' stands for 'XPG_XX'; 'edg'
-    * stands for 'EDGE'; 'hs' stands for 'Perl_Tailored_HSpace'; 'unk' stands for 'UNKNOWN' */
-/*        XX LE CR DQ Ext EX FO HL KA LF ML MN MB NL NU hs RI SQ XPG XPH ZWJ EB EBG EM GAZ edg */
-/* XX */ { 1, 1, 1, 1,  0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1,  1,  0, 1,  1, 1,  1,  1 },
-/* LE */ { 1, 0, 1, 1,  0, 0, 0, 0, 1, 1, 9, 1, 9, 1, 0, 1, 1, 9,  1,  1,  0, 1,  1, 1,  1,  1 },
-/* CR */ { 1, 1, 0, 1,  1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1,  1,  1,  1, 1,  1, 1,  1,  1 },
-/* DQ */ { 1, 1, 1, 1,  0, 1, 0, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1,  1,  0, 1,  1, 1,  1,  1 },
-/* Ext*/ { 3, 3, 1, 3,  0, 3, 0, 3, 3, 1, 3, 3, 3, 1, 3, 1, 3, 3,  3,  3,  0, 3,  3, 3,  3,  1 },
-/* EX */ { 1, 0, 1, 1,  0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1,  0,  1,  0, 1,  1, 1,  1,  1 },
-/* FO */ { 3, 3, 1, 3,  0, 3, 0, 3, 3, 1, 3, 3, 3, 1, 3, 1, 3, 3,  3,  3,  0, 3,  3, 3,  3,  1 },
-/* HL */ { 1, 0, 1, 7,  0, 0, 0, 0, 1, 1, 9, 1, 9, 1, 0, 1, 1, 8,  0,  1,  0, 1,  1, 1,  1,  1 },
-/* KA */ { 1, 1, 1, 1,  0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1,  1,  0, 1,  1, 1,  1,  1 },
-/* LF */ { 1, 1, 0, 1,  1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1,  1,  1,  1, 1,  1, 1,  1,  1 },
-/* ML */ { 1,11, 1, 1,  0, 1, 0,11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 11,  1,  0, 1,  1, 1,  1,  1 },
-/* MN */ { 1, 1, 1, 1,  0, 1, 0, 1, 1, 1, 1, 1, 1, 1,13, 1, 1, 1,  1,  1,  0, 1,  1, 1,  1,  1 },
-/* MB */ { 1,11, 1, 1,  0, 1, 0,11, 1, 1, 1, 1, 1, 1,13, 1, 1, 1, 11,  1,  0, 1,  1, 1,  1,  1 },
-/* NL */ { 1, 1, 0, 1,  1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1,  1,  1,  1, 1,  1, 1,  1,  1 },
-/* NU */ { 1, 0, 1, 1,  0, 0, 0, 0, 1, 1, 1,15,15, 1, 0, 1, 1,15,  0,  1,  0, 1,  1, 1,  1,  1 },
-/* hs */ { 1, 1, 0, 1,  0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 2, 1, 1,  1,  1,  0, 1,  1, 1,  1,  1 },
-/* RI */ { 1, 1, 1, 1,  0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,16, 1,  1,  1,  0, 1,  1, 1,  1,  1 },
-/* SQ */ { 1,11, 1, 1,  0, 1, 0,11, 1, 1, 1, 1, 1, 1,13, 1, 1, 1, 11,  1,  0, 1,  1, 1,  1,  1 },
-/* XPG*/ { 1, 0, 1, 1,  0, 0, 0, 0, 1, 1, 9, 1, 9, 1, 0, 1, 1, 9,  0,  1,  0, 1,  1, 1,  1,  1 },
-/* XPH*/ { 1, 1, 1, 1,  0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1,  1,  0, 1,  1, 1,  1,  1 },
-/* ZWJ*/ { 3, 3, 1, 3,  0, 3, 0, 3, 3, 1, 3, 3, 3, 1, 3, 1, 3, 3,  0,  0,  0, 3,  0, 3,  0,  1 },
-/* EB */ { 1, 1, 1, 1,  0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1,  1,  0, 1,  1, 0,  1,  1 },
-/* EBG*/ { 1, 1, 1, 1,  0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1,  1,  0, 1,  1, 0,  1,  1 },
-/* EM */ { 1, 1, 1, 1,  0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1,  1,  0, 1,  1, 1,  1,  1 },
-/* GAZ*/ { 1, 1, 1, 1,  0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1,  1,  0, 1,  1, 1,  1,  1 },
-/* edg*/ { 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1,  1,  1, 1,  1, 1,  1,  0 }
+static const U8 WB_table[23][23] = {
+   /* 'Ext' stands for 'Extend'; 'XPG' stands for 'XPG_LE'; 'XPH' stands for 'XPG_XX';
+    * 'edg' stands for 'EDGE'; 'hs' stands for 'Perl_Tailored_HSpace'; u stands for
+    * 'unused in this Unicode release (and the data in the row or column are garbage)
+    * */
+/*        XX LE CR DQ Ext EX FO HL KA LF ML MN MB NL NU hs RI SQ XPG XPH ZWJ edg  u */
+/* XX */ { 1, 1, 1, 1,  0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1,  1,  0,  1, 1 },
+/* LE */ { 1, 0, 1, 1,  0, 0, 0, 0, 1, 1, 9, 1, 9, 1, 0, 1, 1, 9,  1,  1,  0,  1, 1 },
+/* CR */ { 1, 1, 0, 1,  1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1,  1,  1,  1,  1, 1 },
+/* DQ */ { 1, 1, 1, 1,  0, 1, 0, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1,  1,  0,  1, 1 },
+/* Ext*/ { 3, 3, 1, 3,  0, 3, 0, 3, 3, 1, 3, 3, 3, 1, 3, 1, 3, 3,  3,  3,  0,  1, 3 },
+/* EX */ { 1, 0, 1, 1,  0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1,  0,  1,  0,  1, 1 },
+/* FO */ { 3, 3, 1, 3,  0, 3, 0, 3, 3, 1, 3, 3, 3, 1, 3, 1, 3, 3,  3,  3,  0,  1, 3 },
+/* HL */ { 1, 0, 1, 7,  0, 0, 0, 0, 1, 1, 9, 1, 9, 1, 0, 1, 1, 8,  0,  1,  0,  1, 1 },
+/* KA */ { 1, 1, 1, 1,  0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1,  1,  0,  1, 1 },
+/* LF */ { 1, 1, 0, 1,  1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1,  1,  1,  1,  1, 1 },
+/* ML */ { 1,11, 1, 1,  0, 1, 0,11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 11,  1,  0,  1, 1 },
+/* MN */ { 1, 1, 1, 1,  0, 1, 0, 1, 1, 1, 1, 1, 1, 1,13, 1, 1, 1,  1,  1,  0,  1, 1 },
+/* MB */ { 1,11, 1, 1,  0, 1, 0,11, 1, 1, 1, 1, 1, 1,13, 1, 1, 1, 11,  1,  0,  1, 1 },
+/* NL */ { 1, 1, 0, 1,  1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1,  1,  1,  1,  1, 1 },
+/* NU */ { 1, 0, 1, 1,  0, 0, 0, 0, 1, 1, 1,15,15, 1, 0, 1, 1,15,  0,  1,  0,  1, 1 },
+/* hs */ { 1, 1, 0, 1,  0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 2, 1, 1,  1,  1,  0,  1, 1 },
+/* RI */ { 1, 1, 1, 1,  0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,16, 1,  1,  1,  0,  1, 1 },
+/* SQ */ { 1,11, 1, 1,  0, 1, 0,11, 1, 1, 1, 1, 1, 1,13, 1, 1, 1, 11,  1,  0,  1, 1 },
+/* XPG*/ { 1, 0, 1, 1,  0, 0, 0, 0, 1, 1, 9, 1, 9, 1, 0, 1, 1, 9,  0,  1,  0,  1, 1 },
+/* XPH*/ { 1, 1, 1, 1,  0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1,  1,  0,  1, 1 },
+/* ZWJ*/ { 3, 3, 1, 3,  0, 3, 0, 3, 3, 1, 3, 3, 3, 1, 3, 1, 3, 3,  0,  0,  0,  1, 0 },
+/* edg*/ { 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1,  1,  1,  0, 1 },
+/* u  */ { 1, 1, 1, 1,  0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1,  1,  0,  1, 0 }
 };
 
 #endif /* defined(PERL_IN_REGEXEC_C) */
@@ -383149,5 +383147,5 @@ static const U8 WB_table[26][26] = {
  * 7bd6bcbe3813e0cd55e0998053d182b7bc8c97dcfd0b85028e9f7f55af4ad61b lib/unicore/version
  * 4bb677187a1a64e39d48f2e341b5ecb6c99857e49d7a79cf503bd8a3c709999b regen/charset_translations.pl
  * 03e51b0f07beebd5da62ab943899aa4934eee1f792fa27c1fb638c33bf4ac6ea regen/mk_PL_charclass.pl
- * a232f3394a90476c4c315c1d067d92243d0d0e38ed4e4bc8d4bb46978c45eaeb regen/mk_invlists.pl
+ * 97779934175e3b7dc8c302762e8e9f342bb828583dd7f862ed85be5906aa939c regen/mk_invlists.pl
  * ex: set ro: */
index 72d939f..663ef12 100644 (file)
@@ -141,6 +141,8 @@ my %keep_together = (
                     );
 my %perl_tags;  # So can find synonyms of the above properties
 
+my $unused_table_hdr = 'u';     # Heading for row or column for unused values
+
 sub uniques {
     # Returns non-duplicated input values.  From "Perl Best Practices:
     # Encapsulated Cleverness".  p. 455 in first edition.
@@ -306,17 +308,47 @@ sub output_invmap ($$$$$$$) {
         }
 
         # The internal enums come last, and in the order specified.
+        #
+        # The internal one named EDGE is also used a marker.  Any ones that
+        # come after it are used in the algorithms below, and so must be
+        # defined, even if the release of Unicode this is being compiled for
+        # doesn't use them.   But since no code points are assigned to them in
+        # such a release, those values will never be accessed.  We collapse
+        # all of them into a single placholder row and a column.  The
+        # algorithms below will fill in those cells with essentially garbage,
+        # but they are never read, so it doesn't matter.  This allows the
+        # algorithm to remain the same from release to release.
+        #
+        # In one case, regexec.c also uses a placeholder which must be defined
+        # here, and we put it in the unused row and column as its value is
+        # never read.
+        #
         my @enums = @input_enums;
         my @extras;
+        my @unused_enums;
+        my $unused_enum_value = @enums;
         if ($extra_enums ne "") {
             @extras = split /,/, $extra_enums;
+            my $seen_EDGE = 0;
 
             # Don't add if already there.
             foreach my $this_extra (@extras) {
                 next if grep { $_ eq $this_extra } @enums;
-
-                push @enums, $this_extra;
+                if ($this_extra eq 'EDGE') {
+                    push @enums, $this_extra;
+                    $seen_EDGE = 1;
+                }
+                elsif ($seen_EDGE) {
+                    push @unused_enums, $this_extra;
+                }
+                else {
+                    push @enums, $this_extra;
+                }
             }
+
+            @unused_enums = sort @unused_enums;
+            $unused_enum_value = @enums;    # All unused have the same value,
+                                            # one beyond the final used one
         }
 
         # Assign a value to each element of the enum type we are creating.
@@ -341,8 +373,6 @@ sub output_invmap ($$$$$$$) {
             # all the tables
             my $type = lc $prop_name;
 
-            my $placeholder = "a";
-
             # Skip if we've already done this code, which populated
             # this hash
             if (eval "! \%${type}_enums") {
@@ -373,22 +403,17 @@ sub output_invmap ($$$$$$$) {
                             #
                             # First are those enums that are not part of the
                             # property, but are defined by this code.  By
-                            # convention these have all-caps names of at least
-                            # 4 characters.  We use the lowercased name for
-                            # thse.
+                            # convention these have all-caps names.  We use
+                            # the lowercased name for these.
                             #
-                            # Second are enums that are needed to get
-                            # regexec.c to compile, but don't exist in all
-                            # Unicode releases.  To get here, we must be
-                            # compiling an earlier Unicode release that
-                            # doesn't have that enum, so just use a unique
-                            # anonymous name for it.
+                            # Second are enums that are needed to get the
+                            # algorithms below to work and/or to get regexec.c
+                            # to compile, but don't exist in all Unicode
+                            # releases.  These are handled outside this loop
+                            # as 'unused_enums'
                             if (grep { $_ eq $enum } @input_enums) {
                                 $short = $enum
                             }
-                            elsif ($enum !~ / ^ [A-Z]{4,} $ /x) {
-                                $short = $placeholder++;
-                            }
                             else {
                                 $short = lc $enum;
                             }
@@ -436,6 +461,18 @@ sub output_invmap ($$$$$$$) {
                     eval "\$${type}_short_enums[$value] = '$short'";
                     die $@ if $@;
                 }
+
+                # Each unused enum has the same value.  They all are collapsed
+                # into one row and one column, named $unused_table_hdr.
+                if (@unused_enums) {
+                    eval "\$${type}_short_enums['$unused_enum_value'] = '$unused_table_hdr'";
+                    die $@ if $@;
+
+                    foreach my $enum (@unused_enums) {
+                        eval "\$${type}_enums{$enum} = $unused_enum_value";
+                        die $@ if $@;
+                    }
+                }
             }
         }
 
@@ -457,6 +494,12 @@ sub output_invmap ($$$$$$$) {
             my $name = $enum_list[$i];
             push @enum_definition, "\t${name_prefix}$name = $i";
         }
+        if (@unused_enums) {
+            foreach my $unused (@unused_enums) {
+                push @enum_definition,
+                            ",\n\t${name_prefix}$unused = $unused_enum_value";
+            }
+        }
 
         # For an 'l' property, we need extra enums, because some of the
         # elements are lists.  Each such distinct list is placed in its own
@@ -1029,17 +1072,11 @@ sub output_table_common {
     # nor run into an adjacent column
     my @spacers;
 
-    # If we are being compiled on a Unicode version earlier than that which
-    # this file was designed for, it may be that some of the property values
-    # aren't in the current release, and so would be undefined if we didn't
-    # define them ourselves.  Earlier code has done this, making them
-    # lowercase characters of length one.  We look to see if any exist, so
-    # that we can add an annotation to the output table
-    my $has_placeholder = 0;
+    # Is there a row and column for unused values in this release?
+    my $has_unused = $names_ref->[$size-1] eq $unused_table_hdr;
 
     for my $i (0 .. $size - 1) {
         no warnings 'numeric';
-        $has_placeholder = 1 if $names_ref->[$i] =~ / ^ [[:lower:]] $ /x;
         $spacers[$i] = " " x (length($names_ref->[$i]) - $column_width);
     }
 
@@ -1061,18 +1098,15 @@ sub output_table_common {
     $header_line .= " */\n";
 
     # If we have annotations, output it now.
-    if ($has_placeholder || scalar %$abbreviations_ref) {
+    if ($has_unused || scalar %$abbreviations_ref) {
         my $text = "";
         foreach my $abbr (sort keys %$abbreviations_ref) {
             $text .= "; " if $text;
             $text .= "'$abbr' stands for '$abbreviations_ref->{$abbr}'";
         }
-        if ($has_placeholder) {
-            $text .= "; other " if $text;
-            $text .= "lowercase names are placeholders for"
-                  .  " property values not defined until a later Unicode"
-                  .  " release, so are irrelevant in this one, as they are"
-                  .  " not assigned to any code points";
+        if ($has_unused) {
+            $text .= "; $unused_table_hdr stands for 'unused in this Unicode"
+                   . " release (and the data in the row or column are garbage)"
         }
 
         my $indent = " " x 3;
@@ -1896,8 +1930,7 @@ sub output_WB_table() {
     # algorithm stops at the earliest matching rule
 
     my @wb_table;
-    my $table_size = @wb_short_enums - 1;   # -1 because we don't use UNKNOWN
-    die "UNKNOWN must be final WB enum" unless $wb_short_enums[-1] =~ /unk/i;
+    my $table_size = @wb_short_enums;
 
     # Otherwise, break everywhere (including around ideographs).
     # WB99  Any  รท  Any
@@ -2209,10 +2242,10 @@ my @props;
 push @props, sort { prop_name_for_cmp($a) cmp prop_name_for_cmp($b) } qw(
                     &NonL1_Perl_Non_Final_Folds
                     &UpperLatin1
-                    _Perl_GCB,E_Base,E_Base_GAZ,E_Modifier,Glue_After_Zwj,LV,Prepend,Regional_Indicator,SpacingMark,ZWJ,XPG_XX,EDGE
-                    _Perl_LB,Close_Parenthesis,Hebrew_Letter,Next_Line,Regional_Indicator,ZWJ,Contingent_Break,E_Base,E_Modifier,H2,H3,JL,JT,JV,Word_Joiner,EDGE
-                    _Perl_SB,SContinue,CR,Extend,LF,EDGE
-                    _Perl_WB,CR,Double_Quote,E_Base,E_Base_GAZ,E_Modifier,Extend,Glue_After_Zwj,Hebrew_Letter,LF,MidNumLet,Newline,Regional_Indicator,Single_Quote,ZWJ,XPG_XX,XPG_LE,Perl_Tailored_HSpace,EDGE,UNKNOWN
+                    _Perl_GCB,EDGE,E_Base,E_Base_GAZ,E_Modifier,Glue_After_Zwj,LV,Prepend,Regional_Indicator,SpacingMark,ZWJ,XPG_XX
+                    _Perl_LB,EDGE,Close_Parenthesis,Hebrew_Letter,Next_Line,Regional_Indicator,ZWJ,Contingent_Break,E_Base,E_Modifier,H2,H3,JL,JT,JV,Word_Joiner
+                    _Perl_SB,EDGE,SContinue,CR,Extend,LF
+                    _Perl_WB,Perl_Tailored_HSpace,EDGE,UNKNOWN,CR,Double_Quote,E_Base,E_Base_GAZ,E_Modifier,Extend,Glue_After_Zwj,Hebrew_Letter,LF,MidNumLet,Newline,Regional_Indicator,Single_Quote,ZWJ,XPG_XX,XPG_LE
                     _Perl_SCX,Latin,Inherited,Unknown,Kore,Jpan,Hanb,INVALID
                     Lowercase_Mapping
                     Titlecase_Mapping
index f71cd5c..590c158 100644 (file)
@@ -6994,6 +6994,6 @@ MPH_VALt match_uniprop( const unsigned char * const key, const U16 key_len ) {
  * 7bd6bcbe3813e0cd55e0998053d182b7bc8c97dcfd0b85028e9f7f55af4ad61b lib/unicore/version
  * 4bb677187a1a64e39d48f2e341b5ecb6c99857e49d7a79cf503bd8a3c709999b regen/charset_translations.pl
  * 03e51b0f07beebd5da62ab943899aa4934eee1f792fa27c1fb638c33bf4ac6ea regen/mk_PL_charclass.pl
- * a232f3394a90476c4c315c1d067d92243d0d0e38ed4e4bc8d4bb46978c45eaeb regen/mk_invlists.pl
+ * 97779934175e3b7dc8c302762e8e9f342bb828583dd7f862ed85be5906aa939c regen/mk_invlists.pl
  * c42c035b18a0426443184e9f889aa2b16bef5a9add9805cd853c4e2a783712ff regen/mph.pl
  * ex: set ro: */