Expand description
XML character-class validation (upstream chvalid.c / parserInternals.c).
The exported xmlIs* family and xmlCharInRange use the generated
character-class tables from unicode_tables.rs (extracted verbatim from
upstream codegen/ranges.inc; see
tools/archaeology/gen_chvalid_tables.py).
§UPSTREAM-PARITY
The semantics mirror upstream chvalid.h macros exactly:
xmlIsBaseCharQ:(c < 0x100) ? xmlIsBaseChar_ch(c) : xmlCharInRange(c, &xmlIsBaseCharGroup)xmlIsBlankQ:(c < 0x100) ? (c==0x20 || 0x9<=c<=0xa || c==0xd) : 0xmlIsCharQ:(c < 0x100) ? (0x9<=c<=0xa || c==0xd || 0x20<=c) : (0x100<=c<=0xd7ff || 0xe000<=c<=0xfffd || 0x10000<=c<=0x10ffff)xmlIsCombiningQ:(c < 0x100) ? 0 : xmlCharInRange(c, &xmlIsCombiningGroup)xmlIsDigitQ:(c < 0x100) ? (0x30<=c<=0x39) : xmlCharInRange(c, &xmlIsDigitGroup)xmlIsExtenderQ:(c < 0x100) ? (c==0xb7) : xmlCharInRange(c, &xmlIsExtenderGroup)xmlIsIdeographicQ:(c < 0x100) ? 0 : (0x4e00<=c<=0x9fa5 || c==0x3007 || 0x3021<=c<=0x3029)xmlIsPubidCharQ:(c < 0x100) ? xmlIsPubidChar_tab[c] : 0xmlIsLetter:xmlIsBaseCharQ(c) || xmlIsIdeographicQ(c)(parserInternals.c)xmlIsBlankNode: tree.c — text/CDATA node whose content is empty or all blank.
§Courts
CHVALID-* differential tests compare against the oracle DSO for the whole BMP + representative supplementary-plane code points.
§Upstream contract
Mirrors upstream chvalid.c / xmlunicode.c / chvalid.h
(SRC-LIBXML2-2.15.0-CHVALID-C et al., parity target libxml2 2.15.3
oracle): xmlCharInRange, the exported xmlIs* predicates and the
xmlIsPubidChar_tab data table.
§Conceptual behavior
Implements the upstream Q-macro semantics verbatim (each xmlIs*Q
expansion is listed above): sub-0x100 code points are answered from
tables/linear tests, larger code points from the generated range
groups via binary search. xmlIsLetter (parserInternals.c) and
xmlIsBlankNode (tree.c) complete the surface.
§Ownership & safety invariants
The tables are immutable static data (extracted from upstream
codegen/ranges.inc); xmlCharInRange only reads its group argument
(SAFETY: NULL group returns 0, valid group must cover
nbShortRange/nbLongRange entries). Nothing here allocates.
§Historical quirks & epochs
R-000135: the seven char-class tables were extracted verbatim from
upstream ranges.inc by tools/archaeology/gen_chvalid_tables.py
(sha256-bound, oracle sha256 e7575963…) and the DATA-GLOBALS-001 court
fingerprints FNV-1a hashes of all nine xmlIs* functions over the BMP
— the tables are stable across the 2.7.8 → 2.15.3 oracle span.
§Deliberate oddities
xmlIsPubidChar only accepts < 0x100 (per the Q-macro); the Latin-1
linear cases in xmlIsBaseChar etc. are kept exactly as upstream
encodes them rather than merged into the range groups.
§Proving courts
DATA-GLOBALS-001 (tools/abi/data_globals_probe.py + committed C probe) compiles the probe against the system libxml2 and the candidate DSO and requires byte-identical output; CHVALID-* differential tests cover the whole BMP; cargo test runs the unit assertions.
§Tempting simplifications that would break parity
Do not regenerate the tables from Unicode data files: upstream tables
carry historical drift (e.g. ideographs bounded at 0x9fa5, the
pubid table) that byte-parity requires. Do not replace the binary
search with a hash set: the group ranges are what the C ABI exposes
through xmlChRangeGroup.
Functions§
- xmlChar
InRange ⚠ - Binary search over the short/long range tables (upstream
xmlCharInRange, chvalid.c — the tables are sorted, so the search is exact). - xmlIs
Base ⚠Char xmlIsBaseChar(unsigned int ch)— XML 1.0 BaseChar production.- xmlIs
Blank ⚠ xmlIsBlank(unsigned int ch)— space, tab, LF, CR.- xmlIs
Blank ⚠Node xmlIsBlankNode(const xmlNode *node)— text/CDATA node with empty or whitespace-only content (tree.c 2.15).- xmlIs
Char ⚠ xmlIsChar(unsigned int ch)— XML 1.0 Char production.- xmlIs
Combining ⚠ xmlIsCombining(unsigned int ch)— XML 1.0 CombiningChar production.- xmlIs
Digit ⚠ xmlIsDigit(unsigned int ch)— XML 1.0 Digit production.- xmlIs
Extender ⚠ xmlIsExtender(unsigned int ch)— XML 1.0 Extender production.- xmlIs
Ideographic ⚠ xmlIsIdeographic(unsigned int ch)— XML 1.0 Ideographic production.- xmlIs
Letter ⚠ xmlIsLetter(int c)— BaseChar or Ideographic (parserInternals.c).- xmlIs
Pubid ⚠Char xmlIsPubidChar(unsigned int ch)— PubidChar production (ASCII table).