Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/JAVA/Openclaw/src/media-understanding/   (Openclaw AI Version 22©)  Datei vom 26.3.2026 mit Größe 54 B image not shown  

Quelle  gen-ucd-table.py   Sprache: Python

 

#!/usr/bin/env python3

"""usage: ./gen-ucd-table [--rust] ucd.nounihan.grouped.xml [/path/to/hb-script-list.h]

Input file:
* https://unicode.org/Public/UCD/latest/ucdxml/ucd.nounihan.grouped.zip
"""

# https://github.com/harfbuzz/packtab
import packTab
import packTab.ucdxml

import sys, re
import logging

logging.basicConfig(format="%(levelname)s: %(message)s", level=logging.INFO)

if len(sys.argv) > 1 and sys.argv[1] == "--rust":
    del sys.argv[1]
    logging.info("Generating Rust code...")
    language = "rust"
else:
    logging.info("Generating C code...")
    language = "c"
language = packTab.languages[language]

if len(sys.argv) not in (2, 3):
    sys.exit(__doc__)

logging.info("Loading UCDXML...")
ucdxml = packTab.ucdxml.load_ucdxml(sys.argv[1])
ucd = packTab.ucdxml.ucdxml_get_repertoire(ucdxml)

hb_script_list_h = "hb-script-list.h" if len(sys.argv) < 3 else sys.argv[2]

logging.info("Preparing data tables...")


# This is how the data is encoded:
#
# General_Category (gc), Canonical_Combining_Class (ccc),
# and Script (sc) are encoded as integers.
#
# Mirroring character (bmg) is encoded as difference from
# the original character.
#
# Composition & Decomposition (dm) are encoded elaborately,
# as discussed below.

gc = [u["gc"] for u in ucd]
ccc = [int(u["ccc"]) for u in ucd]
bmg = [int(v, 16) - int(u) if v else 0 for u, v in enumerate(u["bmg"] for u in ucd)]
sc = [u["sc"] for u in ucd]


# Prepare Compose / Decompose data
#
# This code is very dense.  See hb_ucd_compose() / hb_ucd_decompose() for the logic.

dm = {
    i: tuple(int(v, 16) for v in u["dm"].split())
    for i, u in enumerate(ucd)
    if u["dm"] != "#" and u["dt"] == "can" and not (0xAC00 <= i < 0xAC00 + 11172)
}
ce = {i for i, u in enumerate(ucd) if u["Comp_Ex"] == "Y"}

assert not any(v for v in dm.values() if len(v) not in (1, 2))
dm1 = sorted(set(v for v in dm.values() if len(v) == 1))
assert all((v[0] >> 16) in (0, 2) for v in dm1)
dm1_p0_array = ["0x%04X" % (v[0] & 0xFFFF) for v in dm1 if (v[0] >> 16) == 0]
dm1_p2_array = ["0x%04X" % (v[0] & 0xFFFF) for v in dm1 if (v[0] >> 16) == 2]
dm1_order = {v: i + 1 for i, v in enumerate(dm1)}

dm2 = sorted(
    (v + (i if i not in ce and not ccc[i] else 0,), v)
    for i, v in dm.items()
    if len(v) == 2
)

filt = lambda v: (
    (v[0] & 0xFFFFF800) == 0x0000
    and (v[1] & 0xFFFFFF80) == 0x0300
    and (v[2] & 0xFFF0C000) == 0x0000
)
dm2_u32_array = [v for v in dm2 if filt(v[0])]
dm2_u64_array = [v for v in dm2 if not filt(v[0])]
assert dm2_u32_array + dm2_u64_array == dm2
dm2_u32_array = [
    "HB_CODEPOINT_ENCODE3_11_7_14 (0x%04X, 0x%04X, 0x%04X)" % v[0]
    for v in dm2_u32_array
]
dm2_u64_array = [
    "HB_CODEPOINT_ENCODE3 (0x%04X, 0x%04X, 0x%04X)" % v[0] for v in dm2_u64_array
]

l = 1 + len(dm1_p0_array) + len(dm1_p2_array)
dm2_order = {v[1]: i + l for i, v in enumerate(dm2)}

dm_order = {None: 0}
dm_order.update(dm1_order)
dm_order.update(dm2_order)


# Prepare General_Category / Script mapping arrays

gc_order = dict()
for i, v in enumerate(
    (
        "Cc",
        "Cf",
        "Cn",
        "Co",
        "Cs",
        "Ll",
        "Lm",
        "Lo",
        "Lt",
        "Lu",
        "Mc",
        "Me",
        "Mn",
        "Nd",
        "Nl",
        "No",
        "Pc",
        "Pd",
        "Pe",
        "Pf",
        "Pi",
        "Po",
        "Ps",
        "Sc",
        "Sk",
        "Sm",
        "So",
        "Zl",
        "Zp",
        "Zs",
    )
):
    gc_order[i] = v
    gc_order[v] = i

sc_order = dict()
sc_array = []
sc_re = re.compile(r"\b(HB_SCRIPT_[_A-Z]*).*HB_TAG [(]'(.)','(.)','(.)','(.)'[)]")
for line in open(hb_script_list_h):
    m = sc_re.search(line)
    if not m:
        continue
    name = m.group(1)
    tag = "".join(m.group(i) for i in range(2, 6))
    i = len(sc_array)
    sc_order[tag] = i
    sc_order[i] = tag
    if language.name == "rust":
        name = name.replace("HB_SCRIPT_", "script::")
    sc_array.append(name)


# Write out main data

DEFAULT = "DEFAULT"
COMPACT = "COMPACT"
SLOPPY = "SLOPPY"

compression_level = {
    DEFAULT: 3,
    COMPACT: 9,
    SLOPPY: 9,
}

logging.info("Generating output...")
print("/* == Start of generated table == */")
print("/*")
print(" * The following table is generated by running:")
print(" *")
print(
    " *   ./gen-ucd-table.py %sucd.nounihan.grouped.xml hb-script-list.h"
    % (("--%s " % language.name) if language.name != "c" else "")
)
print(" *")
print(" * on file with this description:", ucdxml.description)
print(" */")
print()
if language.name == "c":
    print("#ifndef HB_UCD_TABLE_HH")
    print("#define HB_UCD_TABLE_HH")
    print()
    print('#include "hb.hh"')
    print()
elif language.name == "rust":
    print("pub(crate) mod ucd {")
    print()
    print("#![allow(unused_parens)]")
    print("#![allow(clippy::unnecessary_cast, clippy::unreadable_literal, clippy::double_parens)]")
    print()
    print("use crate::hb::algs::{HB_CODEPOINT_ENCODE3, HB_CODEPOINT_ENCODE3_11_7_14};")
    print("use crate::hb::common::script;")
    print("use crate::hb::common::Script as hb_script_t;")
    print()
else:
    assert False, "Unknown language: %s" % language.name

# Write mapping data

uint16_t = language.type_name("u16")
uint32_t = language.type_name("u32")
uint64_t = language.type_name("u64")

if language.name == "c":
    private = True
elif language.name == "rust":
    private = False
else:
    assert False, "Unknown language: %s" % language.name

code = packTab.Code("_hb_ucd")
sc_array, _ = code.addArray("hb_script_t", "sc_map", sc_array)
dm1_p0_array, _ = code.addArray(uint16_t, "dm1_p0_map", dm1_p0_array)
dm1_p2_array, _ = code.addArray(uint16_t, "dm1_p2_map", dm1_p2_array)
dm2_u32_array, _ = code.addArray(uint32_t, "dm2_u32_map", dm2_u32_array)
dm2_u64_array, _ = code.addArray(uint64_t, "dm2_u64_map", dm2_u64_array)
code.print_code(language=language, private=private)

datasets = [
    ("gc", gc, "Cn", gc_order),
    ("ccc", ccc, 0, None),
    ("bmg", bmg, 0, None),
    ("sc", sc, "Zzzz", sc_order),
    ("dm", dm, None, dm_order),
]


# Write main data

modes = {}
if language.name == "c":
    modes[DEFAULT] = "#ifndef HB_OPTIMIZE_SIZE"
    modes[COMPACT] = "#elif !defined(HB_NO_UCD_UNASSIGNED)"
    modes[SLOPPY] = "#else"
    modes[None] = "#endif"
else:
    modes[DEFAULT] = ""

for step, text in modes.items():
    print()
    if text:
        print(text)
        print()
    if step is None:
        continue

    compression = compression_level[step]
    logging.info("  Compression=%d:" % compression)

    if step == SLOPPY:
        for i in range(len(gc)):
            if (i % 128) and gc[i] == "Cn":
                gc[i] = gc[i - 1]
        for i in range(len(gc) - 2, -1, -1):
            if ((i + 1) % 128) and gc[i] == "Cn":
                gc[i] = gc[i + 1]
        for i in range(len(sc)):
            if (i % 128) and sc[i] == "Zzzz":
                sc[i] = sc[i - 1]
        for i in range(len(sc) - 2, -1, -1):
            if ((i + 1) % 128) and sc[i] == "Zzzz":
                sc[i] = sc[i + 1]

    code = packTab.Code("_hb_ucd")

    for name, data, default, mapping in datasets:
        sol = packTab.pack_table(
            data, default, mapping=mapping, compression=compression
        )
        logging.info("      Dataset=%-8s FullCost=%d" % (name, sol.fullCost))
        sol.genCode(code, name, private=private, language=language)

    code.print_code(language=language)

    print()

if language.name == "c":
    print("#endif /* HB_UCD_TABLE_HH */")
elif language.name == "rust":
    print("}")
else:
    assert False, "Unknown language: %s" % language.name
print()
print("/* == End of generated table == */")
logging.info("Done.")

Messung V0.5 in Prozent
C=90 H=60 G=76

¤ Dauer der Verarbeitung: 0.12 Sekunden  (vorverarbeitet am  2026-09-30) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.