diff --git a/maint/MultiStage2.py b/maint/MultiStage2.py index c56e8dd51..2839b7d08 100755 --- a/maint/MultiStage2.py +++ b/maint/MultiStage2.py @@ -330,20 +330,20 @@ def compress_table(table, block_size): return stage1, stage2 # Print a table -def print_table(table, table_name, block_size = None): +def print_table(out_file, table, table_name, block_size = None): type, size = get_type_size(table) ELEMS_PER_LINE = 16 s = "const %s %s[] = { /* %d bytes" % (type, table_name, size * len(table)) if block_size: s += ", block = %d" % block_size - print(s + " */") + out_file.write(s + " */\n") table = tuple(table) if block_size is None: - fmt = "%3d," * ELEMS_PER_LINE + " /* U+%04X */" + fmt = "%3d," * ELEMS_PER_LINE + " /* U+%04X */\n" mult = MAX_UNICODE / len(table) for i in range(0, len(table), ELEMS_PER_LINE): - print(fmt % (table[i:i+ELEMS_PER_LINE] + + out_file.write(fmt % (table[i:i+ELEMS_PER_LINE] + (int(i * mult),))) else: if block_size > ELEMS_PER_LINE: @@ -354,8 +354,8 @@ def print_table(table, table_name, block_size = None): if block_size > ELEMS_PER_LINE: fmt = fmt * int(block_size / ELEMS_PER_LINE) for i in range(0, len(table), block_size): - print(("/* block %d */\n" + fmt) % ((i / block_size,) + table[i:i+block_size])) - print("};\n") + out_file.write(("/* block %d */\n" + fmt + "\n") % ((i / block_size,) + table[i:i+block_size])) + out_file.write("};\n\n") # Extract the unique combinations of properties into records def combine_tables(*tables): @@ -386,7 +386,7 @@ def get_record_size_struct(records): slice_type, slice_size = get_type_size(record_slice) size = (size + slice_size - 1) & -slice_size - structure += '} ucd_record;\n*/\n' + structure += '} ucd_record;\n*/\n\n' return size, structure def test_record_size(): @@ -405,15 +405,15 @@ def test_record_size(): assert(size == test[1]) #print struct -def print_records(records, record_size): - print('const ucd_record PRIV(ucd_records)[] = { ' + \ - '/* %d bytes, record size %d */' % (len(records) * record_size, record_size)) +def print_records(out_file, records, record_size): + out_file.write('const ucd_record PRIV(ucd_records)[] = { ' + \ + '/* %d bytes, record size %d */\n' % (len(records) * record_size, record_size)) records = list(zip(list(records.keys()), list(records.values()))) records.sort(key = lambda x: x[1]) for i, record in enumerate(records): - print((' {' + '%6d, ' * len(record[0]) + '}, /* %3d */') % (record[0] + (i,))) - print('};\n') + out_file.write((' {' + '%6d, ' * len(record[0]) + '}, /* %3d */\n') % (record[0] + (i,))) + out_file.write('};\n\n') script_names = ['Unknown', 'Arabic', 'Armenian', 'Bengali', 'Bopomofo', 'Braille', 'Buginese', 'Buhid', 'Canadian_Aboriginal', 'Cherokee', 'Common', 'Coptic', 'Cypriot', 'Cyrillic', 'Deseret', 'Devanagari', 'Ethiopic', 'Georgian', @@ -699,90 +699,193 @@ def print_records(records, record_size): min_stage1, min_stage2 = stage1, stage2 min_block_size = block_size -print("/* This module is generated by the maint/MultiStage2.py script.") -print("Do not modify it by hand. Instead modify the script and run it") -print("to regenerate this code.") -print() -print("As well as being part of the PCRE2 library, this module is #included") -print("by the pcre2test program, which redefines the PRIV macro to change") -print("table names from _pcre2_xxx to xxxx, thereby avoiding name clashes") -print("with the library. At present, just one of these tables is actually") -print("needed. */") -print() -print("#ifndef PCRE2_PCRE2TEST") -print() -print("#ifdef HAVE_CONFIG_H") -print("#include \"config.h\"") -print("#endif") -print() -print("#include \"pcre2_internal.h\"") -print() -print("#endif /* PCRE2_PCRE2TEST */") -print() -print("/* Unicode character database. */") -print("/* This file was autogenerated by the MultiStage2.py script. */") -print("/* Total size: %d bytes, block size: %d. */" % (min_size, min_block_size)) -print() -print("/* The tables herein are needed only when UCP support is built,") -print("and in PCRE2 that happens automatically with UTF support.") -print("This module should not be referenced otherwise, so") -print("it should not matter whether it is compiled or not. However") -print("a comment was received about space saving - maybe the guy linked") -print("all the modules rather than using a library - so we include a") -print("condition to cut out the tables when not needed. But don't leave") -print("a totally empty module because some compilers barf at that.") -print("Instead, just supply some small dummy tables. */") -print() -print("#ifndef SUPPORT_UNICODE") -print("const ucd_record PRIV(ucd_records)[] = {{0,0,0,0,0,0,0,0 }};") -print("const uint16_t PRIV(ucd_stage1)[] = {0};") -print("const uint16_t PRIV(ucd_stage2)[] = {0};") -print("const uint32_t PRIV(ucd_caseless_sets)[] = {0};") -print("#else") -print() -print("const char *PRIV(unicode_version) = \"{}\";".format(unicode_version)) -print() -print("/* If the 32-bit library is run in non-32-bit mode, character values") -print("greater than 0x10ffff may be encountered. For these we set up a") -print("special record. */") -print() -print("#if PCRE2_CODE_UNIT_WIDTH == 32") -print("const ucd_record PRIV(dummy_ucd_record)[] = {{") -print(" ucp_Unknown, /* script */") -print(" ucp_Cn, /* type unassigned */") -print(" ucp_gbOther, /* grapheme break property */") -print(" 0, /* case set */") -print(" 0, /* other case */") -print(" ucp_Unknown, /* script extension */") -print(" ucp_bidiL, /* bidi class */") -print(" 0, /* dummy filler */") -print(" }};") -print("#endif") -print() -print(record_struct) +ucd_file = open("pcre2_ucd.c", "w") +ucp_file = open("pcre2_ucp.h", "w") + +for out_file in (ucd_file, ucp_file): + out_file.write("/*************************************************\n") + out_file.write("* Perl-Compatible Regular Expressions *\n") + out_file.write("*************************************************/\n") + out_file.write("\n") + out_file.write("/* PCRE is a library of functions to support regular expressions whose syntax\n") + out_file.write("and semantics are as close as possible to those of the Perl 5 language.\n") + out_file.write("\n") + out_file.write(" Written by Philip Hazel\n") + out_file.write(" Original API code Copyright (c) 1997-2012 University of Cambridge\n") + out_file.write(" New API code Copyright (c) 2016-2021 University of Cambridge\n") + out_file.write("\n") + out_file.write("-----------------------------------------------------------------------------\n") + out_file.write("Redistribution and use in source and binary forms, with or without\n") + out_file.write("modification, are permitted provided that the following conditions are met:\n") + out_file.write("\n") + out_file.write(" * Redistributions of source code must retain the above copyright notice,\n") + out_file.write(" this list of conditions and the following disclaimer.\n") + out_file.write("\n") + out_file.write(" * Redistributions in binary form must reproduce the above copyright\n") + out_file.write(" notice, this list of conditions and the following disclaimer in the\n") + out_file.write(" documentation and/or other materials provided with the distribution.\n") + out_file.write("\n") + out_file.write(" * Neither the name of the University of Cambridge nor the names of its\n") + out_file.write(" contributors may be used to endorse or promote products derived from\n") + out_file.write(" this software without specific prior written permission.\n") + out_file.write("\n") + out_file.write("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n") + out_file.write("AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n") + out_file.write("IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n") + out_file.write("ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n") + out_file.write("LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n") + out_file.write("CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n") + out_file.write("SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n") + out_file.write("INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n") + out_file.write("CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n") + out_file.write("ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n") + out_file.write("POSSIBILITY OF SUCH DAMAGE.\n") + out_file.write("-----------------------------------------------------------------------------\n") + out_file.write("*/\n") + out_file.write("\n") + out_file.write("/* This module is generated by the maint/MultiStage2.py script.\n") + out_file.write("Do not modify it by hand. Instead modify the script and run it\n") + out_file.write("to regenerate this code.\n") + out_file.write("\n") + +ucp_file.write("This file contains definitions of the property values that\n") +ucp_file.write("are returned bythe UCD access macros.\n") +ucp_file.write("\n") +ucp_file.write("IMPORTANT: The specific values of the first two enums are assumed\n") +ucp_file.write("for the table called catposstab in pcre2_compile.c. */\n") +ucp_file.write("\n") +ucp_file.write("\n") +ucp_file.write("#ifndef PCRE2_UCP_H_IDEMPOTENT_GUARD\n") +ucp_file.write("#define PCRE2_UCP_H_IDEMPOTENT_GUARD\n") +ucp_file.write("\n") +ucp_file.write("/* These are the general character categories. */\n") +ucp_file.write("\n") +ucp_file.write("enum {\n") +ucp_file.write(" ucp_C, /* Other */\n") +ucp_file.write(" ucp_L, /* Letter */\n") +ucp_file.write(" ucp_M, /* Mark */\n") +ucp_file.write(" ucp_N, /* Number */\n") +ucp_file.write(" ucp_P, /* Punctuation */\n") +ucp_file.write(" ucp_S, /* Symbol */\n") +ucp_file.write(" ucp_Z /* Separator */\n") +ucp_file.write("};\n") +ucp_file.write("\n") +ucp_file.write("/* These are the particular character categories. */\n") +ucp_file.write("\n") +ucp_file.write("enum {\n") +for i in category_names: + ucp_file.write(" ucp_%s,\n" % i) +ucp_file.write("};\n") +ucp_file.write("\n") +ucp_file.write("/* These are the bidi class values. */\n") +ucp_file.write("\n") +ucp_file.write("enum {\n") +for i in bidiclass_names: + ucp_file.write(" ucp_bidi%s,\n" % i) +ucp_file.write("};\n") +ucp_file.write("\n") +ucp_file.write("/* These are grapheme break properties. The Extended Pictographic property\n") +ucp_file.write("comes from the emoji-data.txt file. */\n") +ucp_file.write("\n") +ucp_file.write("enum {\n") +for i in break_property_names: + ucp_file.write(" ucp_gb%s,\n" % i) +ucp_file.write("};\n") +ucp_file.write("\n") +ucp_file.write("/* These are the script identifications. */\n") +ucp_file.write("\n") +ucp_file.write("enum {\n") +for i in script_names: + ucp_file.write(" ucp_%s,\n" % i) +ucp_file.write("\n") +ucp_file.write(" /* This must be last */\n") +ucp_file.write(" ucp_Script_Count\n") +ucp_file.write("};\n") +ucp_file.write("\n") +ucp_file.write("#endif /* PCRE2_UCP_H_IDEMPOTENT_GUARD */\n") +ucp_file.write("\n") +ucp_file.write("/* End of pcre2_ucp.h */\n") + +ucd_file.write("As well as being part of the PCRE2 library, this module is #included\n") +ucd_file.write("by the pcre2test program, which redefines the PRIV macro to change\n") +ucd_file.write("table names from _pcre2_xxx to xxxx, thereby avoiding name clashes\n") +ucd_file.write("with the library. At present, just one of these tables is actually\n") +ucd_file.write("needed. */\n") +ucd_file.write("\n") +ucd_file.write("#ifndef PCRE2_PCRE2TEST\n") +ucd_file.write("\n") +ucd_file.write("#ifdef HAVE_CONFIG_H\n") +ucd_file.write("#include \"config.h\"\n") +ucd_file.write("#endif\n") +ucd_file.write("\n") +ucd_file.write("#include \"pcre2_internal.h\"\n") +ucd_file.write("\n") +ucd_file.write("#endif /* PCRE2_PCRE2TEST */\n") +ucd_file.write("\n") +ucd_file.write("/* Unicode character database. */\n") +ucd_file.write("/* This file was autogenerated by the MultiStage2.py script. */\n") +ucd_file.write("/* Total size: %d bytes, block size: %d. */\n" % (min_size, min_block_size)) +ucd_file.write("\n") +ucd_file.write("/* The tables herein are needed only when UCP support is built,\n") +ucd_file.write("and in PCRE2 that happens automatically with UTF support.\n") +ucd_file.write("This module should not be referenced otherwise, so\n") +ucd_file.write("it should not matter whether it is compiled or not. However\n") +ucd_file.write("a comment was received about space saving - maybe the guy linked\n") +ucd_file.write("all the modules rather than using a library - so we include a\n") +ucd_file.write("condition to cut out the tables when not needed. But don't leave\n") +ucd_file.write("a totally empty module because some compilers barf at that.\n") +ucd_file.write("Instead, just supply some small dummy tables. */\n") +ucd_file.write("\n") +ucd_file.write("#ifndef SUPPORT_UNICODE\n") +ucd_file.write("const ucd_record PRIV(ucd_records)[] = {{0,0,0,0,0,0,0,0 }};\n") +ucd_file.write("const uint16_t PRIV(ucd_stage1)[] = {0};\n") +ucd_file.write("const uint16_t PRIV(ucd_stage2)[] = {0};\n") +ucd_file.write("const uint32_t PRIV(ucd_caseless_sets)[] = {0};\n") +ucd_file.write("#else\n") +ucd_file.write("\n") +ucd_file.write("const char *PRIV(unicode_version) = \"{}\";\n".format(unicode_version)) +ucd_file.write("\n") +ucd_file.write("/* If the 32-bit library is run in non-32-bit mode, character values\n") +ucd_file.write("greater than 0x10ffff may be encountered. For these we set up a\n") +ucd_file.write("special record. */\n") +ucd_file.write("\n") +ucd_file.write("#if PCRE2_CODE_UNIT_WIDTH == 32\n") +ucd_file.write("const ucd_record PRIV(dummy_ucd_record)[] = {{\n") +ucd_file.write(" ucp_Unknown, /* script */\n") +ucd_file.write(" ucp_Cn, /* type unassigned */\n") +ucd_file.write(" ucp_gbOther, /* grapheme break property */\n") +ucd_file.write(" 0, /* case set */\n") +ucd_file.write(" 0, /* other case */\n") +ucd_file.write(" ucp_Unknown, /* script extension */\n") +ucd_file.write(" ucp_bidiL, /* bidi class */\n") +ucd_file.write(" 0, /* dummy filler */\n") +ucd_file.write(" }};\n") +ucd_file.write("#endif\n") +ucd_file.write("\n") +ucd_file.write(record_struct) # --- Added by PH: output the table of caseless character sets --- -print("/* This table contains lists of characters that are caseless sets of") -print("more than one character. Each list is terminated by NOTACHAR. */\n") +ucd_file.write("/* This table contains lists of characters that are caseless sets of\n") +ucd_file.write("more than one character. Each list is terminated by NOTACHAR. */\n\n") -print("const uint32_t PRIV(ucd_caseless_sets)[] = {") -print(" NOTACHAR,") +ucd_file.write("const uint32_t PRIV(ucd_caseless_sets)[] = {\n") +ucd_file.write(" NOTACHAR,\n") for s in sets: s = sorted(s) for x in s: - print(' 0x%04x,' % x, end=' ') - print(' NOTACHAR,') -print('};') -print() + ucd_file.write(' 0x%04x, ' % x) + ucd_file.write(' NOTACHAR,\n') +ucd_file.write('};\n') +ucd_file.write("\n") # ------ -print("/* When #included in pcre2test, we don't need the table of digit") -print("sets, nor the the large main UCD tables. */") -print() -print("#ifndef PCRE2_PCRE2TEST") -print() +ucd_file.write("/* When #included in pcre2test, we don't need the table of digit\n") +ucd_file.write("sets, nor the the large main UCD tables. */\n") +ucd_file.write("\n") +ucd_file.write("#ifndef PCRE2_PCRE2TEST\n") +ucd_file.write("\n") # --- Added by PH: read Scripts.txt again for the sets of 10 digits. --- @@ -804,24 +907,24 @@ def print_records(records, record_size): file.close() digitsets.sort() -print("/* This table lists the code points for the '9' characters in each") -print("set of decimal digits. It is used to ensure that all the digits in") -print("a script run come from the same set. */\n") -print("const uint32_t PRIV(ucd_digit_sets)[] = {") +ucd_file.write("/* This table lists the code points for the '9' characters in each\n") +ucd_file.write("set of decimal digits. It is used to ensure that all the digits in\n") +ucd_file.write("a script run come from the same set. */\n\n") +ucd_file.write("const uint32_t PRIV(ucd_digit_sets)[] = {\n") -print(" %d, /* Number of subsequent values */" % len(digitsets), end='') +ucd_file.write(" %d, /* Number of subsequent values */" % len(digitsets)) count = 8 for d in digitsets: if count == 8: - print("\n ", end='') + ucd_file.write("\n ") count = 0 - print(" 0x%05x," % d, end='') + ucd_file.write(" 0x%05x," % d) count += 1 -print("\n};\n") +ucd_file.write("\n};\n\n") -print("/* This vector is a list of script bitsets for the Script Extension") -print("property. */\n") -print("const uint32_t PRIV(ucd_script_sets)[] = {") +ucd_file.write("/* This vector is a list of script bitsets for the Script Extension\n") +ucd_file.write("property. */\n\n") +ucd_file.write("const uint32_t PRIV(ucd_script_sets)[] = {\n") bitword_count = len(script_names)/32 + 1 bitwords = [0] * int(bitword_count) @@ -829,12 +932,12 @@ def print_records(records, record_size): for d in script_lists: if d == 0: s = " " - print(" ", end='') + ucd_file.write(" ") for x in bitwords: - print("%s" %s, end='') + ucd_file.write("%s" %s) s = ", " - print("0x%08xu" % x, end='') - print(",\n", end='') + ucd_file.write("0x%08xu" % x) + ucd_file.write(",\n") bitwords = [0] * int(bitword_count) else: @@ -842,26 +945,26 @@ def print_records(records, record_size): y = int(d%32) bitwords[x] = bitwords[x] | (1 << y) -print("};\n") +ucd_file.write("};\n\n") # Output the main UCD tables. -print("/* These are the main two-stage UCD tables. The fields in each record are:") -print("script (8 bits), character type (8 bits), grapheme break property (8 bits),") -print("offset to multichar other cases or zero (8 bits), offset to other case") -print("or zero (32 bits, signed), script extension (16 bits, signed), bidi class") -print("(8 bits), and a dummy 8-bit field to make the whole thing a multiple") -print("of 4 bytes. */\n") - -print_records(records, record_size) -print_table(min_stage1, 'PRIV(ucd_stage1)') -print_table(min_stage2, 'PRIV(ucd_stage2)', min_block_size) -print("#if UCD_BLOCK_SIZE != %d" % min_block_size) -print("#error Please correct UCD_BLOCK_SIZE in pcre2_internal.h") -print("#endif") -print("#endif /* SUPPORT_UNICODE */") -print() -print("#endif /* PCRE2_PCRE2TEST */") +ucd_file.write("/* These are the main two-stage UCD tables. The fields in each record are:\n") +ucd_file.write("script (8 bits), character type (8 bits), grapheme break property (8 bits),\n") +ucd_file.write("offset to multichar other cases or zero (8 bits), offset to other case\n") +ucd_file.write("or zero (32 bits, signed), script extension (16 bits, signed), bidi class\n") +ucd_file.write("(8 bits), and a dummy 8-bit field to make the whole thing a multiple\n") +ucd_file.write("of 4 bytes. */\n\n") + +print_records(ucd_file, records, record_size) +print_table(ucd_file, min_stage1, 'PRIV(ucd_stage1)') +print_table(ucd_file, min_stage2, 'PRIV(ucd_stage2)', min_block_size) +ucd_file.write("#if UCD_BLOCK_SIZE != %d\n" % min_block_size) +ucd_file.write("#error Please correct UCD_BLOCK_SIZE in pcre2_internal.h\n") +ucd_file.write("#endif\n") +ucd_file.write("#endif /* SUPPORT_UNICODE */\n") +ucd_file.write("\n") +ucd_file.write("#endif /* PCRE2_PCRE2TEST */\n") # This code was part of the original contribution, but is commented out as it diff --git a/src/pcre2_extuni.c b/src/pcre2_extuni.c index 5a719e9cb..3f1beecc3 100644 --- a/src/pcre2_extuni.c +++ b/src/pcre2_extuni.c @@ -105,7 +105,7 @@ while (eptr < end_subject) /* Not breaking between Regional Indicators is allowed only if there are an even number of preceding RIs. */ - if (lgb == ucp_gbRegionalIndicator && rgb == ucp_gbRegionalIndicator) + if (lgb == ucp_gbRegional_Indicator && rgb == ucp_gbRegional_Indicator) { int ricount = 0; PCRE2_SPTR bptr = eptr - 1; @@ -123,7 +123,7 @@ while (eptr < end_subject) } else c = *bptr; - if (UCD_GRAPHBREAK(c) != ucp_gbRegionalIndicator) break; + if (UCD_GRAPHBREAK(c) != ucp_gbRegional_Indicator) break; ricount++; } if ((ricount & 1) != 0) break; /* Grapheme break required */ diff --git a/src/pcre2_jit_compile.c b/src/pcre2_jit_compile.c index 2749cc636..0fb226c7c 100644 --- a/src/pcre2_jit_compile.c +++ b/src/pcre2_jit_compile.c @@ -8379,7 +8379,7 @@ do /* Not breaking between Regional Indicators is allowed only if there are an even number of preceding RIs. */ - if (lgb == ucp_gbRegionalIndicator && rgb == ucp_gbRegionalIndicator) + if (lgb == ucp_gbRegional_Indicator && rgb == ucp_gbRegional_Indicator) { ricount = 0; bptr = prevcc; @@ -8391,7 +8391,7 @@ do BACKCHAR(bptr); GETCHAR(c, bptr); - if (UCD_GRAPHBREAK(c) != ucp_gbRegionalIndicator) + if (UCD_GRAPHBREAK(c) != ucp_gbRegional_Indicator) break; ricount++; @@ -8447,7 +8447,7 @@ do /* Not breaking between Regional Indicators is allowed only if there are an even number of preceding RIs. */ - if (lgb == ucp_gbRegionalIndicator && rgb == ucp_gbRegionalIndicator) + if (lgb == ucp_gbRegional_Indicator && rgb == ucp_gbRegional_Indicator) { ricount = 0; bptr = prevcc; @@ -8457,7 +8457,7 @@ do { GETCHARBACK_INVALID(c, bptr, start_subject, break); - if (UCD_GRAPHBREAK(c) != ucp_gbRegionalIndicator) + if (UCD_GRAPHBREAK(c) != ucp_gbRegional_Indicator) break; ricount++; @@ -8515,7 +8515,7 @@ while (cc < end_subject) /* Not breaking between Regional Indicators is allowed only if there are an even number of preceding RIs. */ - if (lgb == ucp_gbRegionalIndicator && rgb == ucp_gbRegionalIndicator) + if (lgb == ucp_gbRegional_Indicator && rgb == ucp_gbRegional_Indicator) { ricount = 0; bptr = cc - 1; @@ -8530,7 +8530,7 @@ while (cc < end_subject) break; #endif /* PCRE2_CODE_UNIT_WIDTH == 32 */ - if (UCD_GRAPHBREAK(c) != ucp_gbRegionalIndicator) break; + if (UCD_GRAPHBREAK(c) != ucp_gbRegional_Indicator) break; ricount++; } diff --git a/src/pcre2_tables.c b/src/pcre2_tables.c index 827e1ea3c..5c23bfd11 100644 --- a/src/pcre2_tables.c +++ b/src/pcre2_tables.c @@ -190,7 +190,7 @@ const uint32_t PRIV(ucp_gbtable)[] = { ESZ|(1u<