Add generating code for bidirectional character mirror mappings Signed-off-by: Laslo Hunhold <dev@frign.de>
diff --git a/gen/bidirectional.c b/gen/bidirectional.c index 469b9cf..3dd034e 100644 --- a/gen/bidirectional.c +++ b/gen/bidirectional.c
@@ -402,9 +402,43 @@ } } +static struct properties *prop_mirror = NULL; + +static int +mirror_callback(const char *file, char **field, size_t nfields, char *comment, + void *payload) +{ + uint_least32_t cp, cp_mirror; + + (void)file; + (void)comment; + (void)payload; + + hextocp(field[0], strlen(field[0]), &cp); + + cp_mirror = cp; + + if (nfields >= 2 && strlen(field[1]) > 0 && + hextocp(field[1], strlen(field[1]), &cp_mirror)) { + return 1; + } + + prop_mirror[cp].property = (int_least32_t)cp_mirror - (int_least32_t)cp; + + return 0; +} + +static int_least64_t +get_value(const struct properties *prop, size_t offset) +{ + return prop[offset].property; +} + int main(int argc, char *argv[]) { + struct properties_compressed comp_mirror; + struct properties_major_minor mm_mirror; size_t i; (void)argc; @@ -438,5 +472,32 @@ } printf("};\n"); + /* + * allocate property buffer for all 0x110000 codepoints + * + * the buffers contain the offset from the "base" character + * to the respective mirrored character. By callocing we set all + * fields to zero, which is also the Unicode "default" in the sense + * that the coe point is its mirror (unless we fill it in) + */ + if (!(prop_mirror = calloc(UINT32_C(0x110000), sizeof(*prop_mirror)))) { + fprintf(stderr, "calloc: %s\n", strerror(errno)); + exit(1); + } + parse_file_with_callback(FILE_BIDI_MIRRORING, mirror_callback, NULL); + + /* compress properties */ + properties_compress(prop_mirror, &comp_mirror); + + fprintf(stderr, "%s: mirror-LUT compression-ratio: %.2f%%\n", argv[0], + properties_get_major_minor(&comp_mirror, &mm_mirror)); + + /* print tables */ + properties_print_lookup_table("mirror_major", mm_mirror.major, 0x1100); + printf("\n"); + properties_print_derived_lookup_table("mirror_minor", mm_mirror.minor, + mm_mirror.minorlen, get_value, + comp_mirror.data); + return 0; }