X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fgen-uni-tables.c;h=0a1731751608707dc7c9d18e698907c40b974fb9;hb=665a8a0fca396d67dfed85580a48178df8b4a60e;hp=b949a5bf2f98250714b1bb9141317425ab1aa5a2;hpb=7ef2788bd0cfc453fab33250a85881863640dd7c;p=gnulib.git diff --git a/lib/gen-uni-tables.c b/lib/gen-uni-tables.c index b949a5bf2..0a1731751 100644 --- a/lib/gen-uni-tables.c +++ b/lib/gen-uni-tables.c @@ -1,5 +1,6 @@ /* Generate Unicode conforming character classification tables and - Line Break Properties tables from a UnicodeData file. + line break properties tables and word break property tables and + case mapping tables from a UnicodeData file. Copyright (C) 2000-2002, 2004, 2007-2009 Free Software Foundation, Inc. Written by Bruno Haible , 2000-2002. @@ -737,7 +738,7 @@ output_predicate (const char *filename, bool (*predicate) (unsigned int), const if (offset == 0) fprintf (stream, " %5d", -1); else - fprintf (stream, " %5zd * sizeof (int) / sizeof (short) + %5zd", + fprintf (stream, " %5zu * sizeof (int) / sizeof (short) + %5zu", 1 + t.level1_size, (offset - level2_offset) / sizeof (uint32_t)); if (i+1 < t.level1_size) fprintf (stream, ","); @@ -757,7 +758,7 @@ output_predicate (const char *filename, bool (*predicate) (unsigned int), const if (offset == 0) fprintf (stream, " %5d", -1); else - fprintf (stream, " %5zd + %5zd * sizeof (short) / sizeof (int) + %5zd", + fprintf (stream, " %5zu + %5zu * sizeof (short) / sizeof (int) + %5zu", 1 + t.level1_size, t.level2_size << t.q, (offset - level3_offset) / sizeof (uint32_t)); if (i+1 < t.level2_size << t.q) fprintf (stream, ","); @@ -1055,7 +1056,7 @@ output_category (const char *filename, const char *version) if (offset == 0) fprintf (stream, " %5d", -1); else - fprintf (stream, " %5zd", + fprintf (stream, " %5zu", (offset - level2_offset) / sizeof (uint32_t)); if (i+1 < t.level1_size) fprintf (stream, ","); @@ -1075,7 +1076,7 @@ output_category (const char *filename, const char *version) if (offset == 0) fprintf (stream, " %5d", -1); else - fprintf (stream, " %5zd", + fprintf (stream, " %5zu", (offset - level3_offset) / sizeof (uint8_t)); if (i+1 < t.level2_size << t.q) fprintf (stream, ","); @@ -1206,7 +1207,7 @@ output_combclass (const char *filename, const char *version) if (offset == 0) fprintf (stream, " %5d", -1); else - fprintf (stream, " %5zd", + fprintf (stream, " %5zu", (offset - level2_offset) / sizeof (uint32_t)); if (i+1 < t.level1_size) fprintf (stream, ","); @@ -1226,7 +1227,7 @@ output_combclass (const char *filename, const char *version) if (offset == 0) fprintf (stream, " %5d", -1); else - fprintf (stream, " %5zd", + fprintf (stream, " %5zu", (offset - level3_offset) / sizeof (uint8_t)); if (i+1 < t.level2_size << t.q) fprintf (stream, ","); @@ -1545,7 +1546,7 @@ output_bidi_category (const char *filename, const char *version) if (offset == 0) fprintf (stream, " %5d", -1); else - fprintf (stream, " %5zd", + fprintf (stream, " %5zu", (offset - level2_offset) / sizeof (uint32_t)); if (i+1 < t.level1_size) fprintf (stream, ","); @@ -1565,7 +1566,7 @@ output_bidi_category (const char *filename, const char *version) if (offset == 0) fprintf (stream, " %5d", -1); else - fprintf (stream, " %5zd", + fprintf (stream, " %5zu", (offset - level3_offset) / sizeof (uint8_t)); if (i+1 < t.level2_size << t.q) fprintf (stream, ","); @@ -1752,7 +1753,7 @@ output_decimal_digit (const char *filename, const char *version) if (offset == 0) fprintf (stream, " %5d", -1); else - fprintf (stream, " %5zd", + fprintf (stream, " %5zu", (offset - level2_offset) / sizeof (uint32_t)); if (i+1 < t.level1_size) fprintf (stream, ","); @@ -1772,7 +1773,7 @@ output_decimal_digit (const char *filename, const char *version) if (offset == 0) fprintf (stream, " %5d", -1); else - fprintf (stream, " %5zd", + fprintf (stream, " %5zu", (offset - level3_offset) / sizeof (uint8_t)); if (i+1 < t.level2_size << t.q) fprintf (stream, ","); @@ -1939,7 +1940,7 @@ output_digit (const char *filename, const char *version) if (offset == 0) fprintf (stream, " %5d", -1); else - fprintf (stream, " %5zd", + fprintf (stream, " %5zu", (offset - level2_offset) / sizeof (uint32_t)); if (i+1 < t.level1_size) fprintf (stream, ","); @@ -1959,7 +1960,7 @@ output_digit (const char *filename, const char *version) if (offset == 0) fprintf (stream, " %5d", -1); else - fprintf (stream, " %5zd", + fprintf (stream, " %5zu", (offset - level3_offset) / sizeof (uint8_t)); if (i+1 < t.level2_size << t.q) fprintf (stream, ","); @@ -2195,7 +2196,7 @@ output_numeric (const char *filename, const char *version) if (offset == 0) fprintf (stream, " %5d", -1); else - fprintf (stream, " %5zd", + fprintf (stream, " %5zu", (offset - level2_offset) / sizeof (uint32_t)); if (i+1 < t.level1_size) fprintf (stream, ","); @@ -2215,7 +2216,7 @@ output_numeric (const char *filename, const char *version) if (offset == 0) fprintf (stream, " %5d", -1); else - fprintf (stream, " %5zd", + fprintf (stream, " %5zu", (offset - level3_offset) / sizeof (uint8_t)); if (i+1 < t.level2_size << t.q) fprintf (stream, ","); @@ -2433,7 +2434,7 @@ output_mirror (const char *filename, const char *version) if (offset == 0) fprintf (stream, " %5d", -1); else - fprintf (stream, " %5zd", + fprintf (stream, " %5zu", (offset - level2_offset) / sizeof (uint32_t)); if (i+1 < t.level1_size) fprintf (stream, ","); @@ -2453,7 +2454,7 @@ output_mirror (const char *filename, const char *version) if (offset == 0) fprintf (stream, " %5d", -1); else - fprintf (stream, " %5zd", + fprintf (stream, " %5zu", (offset - level3_offset) / sizeof (int32_t)); if (i+1 < t.level2_size << t.q) fprintf (stream, ","); @@ -3753,7 +3754,7 @@ output_scripts (const char *version) if (offset == 0) fprintf (stream, " %5d", -1); else - fprintf (stream, " %5zd", + fprintf (stream, " %5zu", (offset - level2_offset) / sizeof (uint32_t)); if (i+1 < t.level1_size) fprintf (stream, ","); @@ -3773,7 +3774,7 @@ output_scripts (const char *version) if (offset == 0) fprintf (stream, " %5d", -1); else - fprintf (stream, " %5zd", + fprintf (stream, " %5zu", (offset - level3_offset) / sizeof (uint8_t)); if (i+1 < t.level2_size << t.q) fprintf (stream, ","); @@ -4429,7 +4430,7 @@ output_ident_category (const char *filename, int (*predicate) (unsigned int), co if (offset == 0) fprintf (stream, " %5d", -1); else - fprintf (stream, " %5zd", + fprintf (stream, " %5zu", (offset - level2_offset) / sizeof (uint32_t)); if (i+1 < t.level1_size) fprintf (stream, ","); @@ -4449,7 +4450,7 @@ output_ident_category (const char *filename, int (*predicate) (unsigned int), co if (offset == 0) fprintf (stream, " %5d", -1); else - fprintf (stream, " %5zd", + fprintf (stream, " %5zu", (offset - level3_offset) / sizeof (uint8_t)); if (i+1 < t.level2_size << t.q) fprintf (stream, ","); @@ -6109,9 +6110,13 @@ output_lbp (FILE *stream1, FILE *stream2) if (i > 0 && (i % 8) == 0) fprintf (stream2, "\n "); offset = ((uint32_t *) (t.result + level1_offset))[i]; - fprintf (stream2, " %5zd%s", - offset == 0 ? -1 : (offset - level2_offset) / sizeof (uint32_t), - (i+1 < t.level1_size ? "," : "")); + if (offset == 0) + fprintf (stream2, " %5d", -1); + else + fprintf (stream2, " %5zu", + (offset - level2_offset) / sizeof (uint32_t)); + if (i+1 < t.level1_size) + fprintf (stream2, ","); } if (t.level1_size > 8) fprintf (stream2, "\n "); @@ -6125,9 +6130,13 @@ output_lbp (FILE *stream1, FILE *stream2) if (i > 0 && (i % 8) == 0) fprintf (stream2, "\n "); offset = ((uint32_t *) (t.result + level2_offset))[i]; - fprintf (stream2, " %5zd%s", - offset == 0 ? -1 : (offset - level3_offset) / sizeof (uint8_t), - (i+1 < t.level2_size << t.q ? "," : "")); + if (offset == 0) + fprintf (stream2, " %5d", -1); + else + fprintf (stream2, " %5zu", + (offset - level3_offset) / sizeof (unsigned char)); + if (i+1 < t.level2_size << t.q) + fprintf (stream2, ","); } if (t.level2_size << t.q > 8) fprintf (stream2, "\n "); @@ -6614,9 +6623,13 @@ output_wbp (FILE *stream) if (i > 0 && (i % 8) == 0) fprintf (stream, "\n "); offset = ((uint32_t *) (t.result + level1_offset))[i]; - fprintf (stream, " %5zd%s", - offset == 0 ? -1 : (offset - level2_offset) / sizeof (uint32_t), - (i+1 < t.level1_size ? "," : "")); + if (offset == 0) + fprintf (stream, " %5d", -1); + else + fprintf (stream, " %5zu", + (offset - level2_offset) / sizeof (uint32_t)); + if (i+1 < t.level1_size) + fprintf (stream, ","); } if (t.level1_size > 8) fprintf (stream, "\n "); @@ -6630,9 +6643,13 @@ output_wbp (FILE *stream) if (i > 0 && (i % 8) == 0) fprintf (stream, "\n "); offset = ((uint32_t *) (t.result + level2_offset))[i]; - fprintf (stream, " %5zd%s", - offset == 0 ? -1 : (offset - level3_offset) / sizeof (uint8_t), - (i+1 < t.level2_size << t.q ? "," : "")); + if (offset == 0) + fprintf (stream, " %5d", -1); + else + fprintf (stream, " %5zu", + (offset - level3_offset) / sizeof (unsigned char)); + if (i+1 < t.level2_size << t.q) + fprintf (stream, ","); } if (t.level2_size << t.q > 8) fprintf (stream, "\n "); @@ -6723,6 +6740,208 @@ output_wbrk_tables (const char *filename, const char *version) /* ========================================================================= */ +/* Output the test for a simple character mapping table to the given file. */ + +static void +output_simple_mapping_test (const char *filename, + const char *function_name, + unsigned int (*func) (unsigned int), + const char *version) +{ + FILE *stream; + bool need_comma; + unsigned int ch; + + stream = fopen (filename, "w"); + if (stream == NULL) + { + fprintf (stderr, "cannot open '%s' for writing\n", filename); + exit (1); + } + + fprintf (stream, "/* DO NOT EDIT! GENERATED AUTOMATICALLY! */\n"); + fprintf (stream, "/* Test the Unicode character mapping functions.\n"); + fprintf (stream, " Copyright (C) 2009 Free Software Foundation, Inc.\n"); + fprintf (stream, "\n"); + fprintf (stream, " This program is free software: you can redistribute it and/or modify\n"); + fprintf (stream, " it under the terms of the GNU General Public License as published by\n"); + fprintf (stream, " the Free Software Foundation; either version 3 of the License, or\n"); + fprintf (stream, " (at your option) any later version.\n"); + fprintf (stream, "\n"); + fprintf (stream, " This program is distributed in the hope that it will be useful,\n"); + fprintf (stream, " but WITHOUT ANY WARRANTY; without even the implied warranty of\n"); + fprintf (stream, " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"); + fprintf (stream, " GNU General Public License for more details.\n"); + fprintf (stream, "\n"); + fprintf (stream, " You should have received a copy of the GNU General Public License\n"); + fprintf (stream, " along with this program. If not, see . */\n"); + fprintf (stream, "\n"); + fprintf (stream, "/* Generated automatically by gen-case.c for Unicode %s. */\n", + version); + fprintf (stream, "\n"); + fprintf (stream, "#include \"test-mapping-part1.h\"\n"); + fprintf (stream, "\n"); + + need_comma = false; + for (ch = 0; ch < 0x110000; ch++) + { + unsigned int value = func (ch); + + if (value != ch) + { + if (need_comma) + fprintf (stream, ",\n"); + fprintf (stream, " { 0x%04X, 0x%04X }", ch, value); + need_comma = true; + } + } + if (need_comma) + fprintf (stream, "\n"); + + fprintf (stream, "\n"); + fprintf (stream, "#define MAP(c) %s (c)\n", function_name); + fprintf (stream, "#include \"test-mapping-part2.h\"\n"); + + if (ferror (stream) || fclose (stream)) + { + fprintf (stderr, "error writing to '%s'\n", filename); + exit (1); + } +} + +/* Construction of sparse 3-level tables. */ +#define TABLE mapping_table +#define ELEMENT int32_t +#define DEFAULT 0 +#define xmalloc malloc +#define xrealloc realloc +#include "3level.h" + +/* Output a simple character mapping table to the given file. */ + +static void +output_simple_mapping (const char *filename, + unsigned int (*func) (unsigned int), + const char *version) +{ + FILE *stream; + unsigned int ch, i; + struct mapping_table t; + unsigned int level1_offset, level2_offset, level3_offset; + + stream = fopen (filename, "w"); + if (stream == NULL) + { + fprintf (stderr, "cannot open '%s' for writing\n", filename); + exit (1); + } + + fprintf (stream, "/* DO NOT EDIT! GENERATED AUTOMATICALLY! */\n"); + fprintf (stream, "/* Simple character mapping of Unicode characters. */\n"); + fprintf (stream, "/* Generated automatically by gen-case.c for Unicode %s. */\n", + version); + + t.p = 7; + t.q = 9; + mapping_table_init (&t); + + for (ch = 0; ch < 0x110000; ch++) + { + int value = (int) func (ch) - (int) ch; + + mapping_table_add (&t, ch, value); + } + + mapping_table_finalize (&t); + + /* Offsets in t.result, in memory of this process. */ + level1_offset = + 5 * sizeof (uint32_t); + level2_offset = + 5 * sizeof (uint32_t) + + t.level1_size * sizeof (uint32_t); + level3_offset = + 5 * sizeof (uint32_t) + + t.level1_size * sizeof (uint32_t) + + (t.level2_size << t.q) * sizeof (uint32_t); + + for (i = 0; i < 5; i++) + fprintf (stream, "#define mapping_header_%d %d\n", i, + ((uint32_t *) t.result)[i]); + fprintf (stream, "static const\n"); + fprintf (stream, "struct\n"); + fprintf (stream, " {\n"); + fprintf (stream, " int level1[%zu];\n", t.level1_size); + fprintf (stream, " short level2[%zu << %d];\n", t.level2_size, t.q); + fprintf (stream, " int level3[%zu << %d];\n", t.level3_size, t.p); + fprintf (stream, " }\n"); + fprintf (stream, "u_mapping =\n"); + fprintf (stream, "{\n"); + fprintf (stream, " {"); + if (t.level1_size > 8) + fprintf (stream, "\n "); + for (i = 0; i < t.level1_size; i++) + { + uint32_t offset; + if (i > 0 && (i % 8) == 0) + fprintf (stream, "\n "); + offset = ((uint32_t *) (t.result + level1_offset))[i]; + if (offset == 0) + fprintf (stream, " %5d", -1); + else + fprintf (stream, " %5zu", + (offset - level2_offset) / sizeof (uint32_t)); + if (i+1 < t.level1_size) + fprintf (stream, ","); + } + if (t.level1_size > 8) + fprintf (stream, "\n "); + fprintf (stream, " },\n"); + fprintf (stream, " {"); + if (t.level2_size << t.q > 8) + fprintf (stream, "\n "); + for (i = 0; i < t.level2_size << t.q; i++) + { + uint32_t offset; + if (i > 0 && (i % 8) == 0) + fprintf (stream, "\n "); + offset = ((uint32_t *) (t.result + level2_offset))[i]; + if (offset == 0) + fprintf (stream, " %5d", -1); + else + fprintf (stream, " %5zu", + (offset - level3_offset) / sizeof (int32_t)); + if (i+1 < t.level2_size << t.q) + fprintf (stream, ","); + } + if (t.level2_size << t.q > 8) + fprintf (stream, "\n "); + fprintf (stream, " },\n"); + fprintf (stream, " {"); + if (t.level3_size << t.p > 8) + fprintf (stream, "\n "); + for (i = 0; i < t.level3_size << t.p; i++) + { + if (i > 0 && (i % 8) == 0) + fprintf (stream, "\n "); + fprintf (stream, " %5d", ((int32_t *) (t.result + level3_offset))[i]); + if (i+1 < t.level3_size << t.p) + fprintf (stream, ","); + } + if (t.level3_size << t.p > 8) + fprintf (stream, "\n "); + fprintf (stream, " }\n"); + fprintf (stream, "};\n"); + + if (ferror (stream) || fclose (stream)) + { + fprintf (stderr, "error writing to '%s'\n", filename); + exit (1); + } +} + +/* ========================================================================= */ + int main (int argc, char * argv[]) { @@ -6792,6 +7011,13 @@ main (int argc, char * argv[]) debug_output_org_wbrk_tables ("uniwbrk/wbrkprop_org.txt"); output_wbrk_tables ("uniwbrk/wbrkprop.h", version); + output_simple_mapping_test ("../tests/unicase/test-uc_toupper.c", "uc_toupper", to_upper, version); + output_simple_mapping_test ("../tests/unicase/test-uc_tolower.c", "uc_tolower", to_lower, version); + output_simple_mapping_test ("../tests/unicase/test-uc_totitle.c", "uc_totitle", to_title, version); + output_simple_mapping ("unicase/toupper.h", to_upper, version); + output_simple_mapping ("unicase/tolower.h", to_lower, version); + output_simple_mapping ("unicase/totitle.h", to_title, version); + return 0; }