PureXML/Sources/Regex/Unicode32Assigned.swift
Mihaela Mihaljevic be8a39394d fix(schema): advance XSTS valid-instances-rejected to 4 (#146)
Consolidates the in-progress #146 work; valid-instances-rejected reaches 4
on the 2006-11-06 XSTS archive (buckets now 1/262/4/147).

Regex: match Unicode scalars rather than grapheme clusters; the empty
pattern matches only the empty string; pin the category repertoire to
Unicode 3.2, the version the corpus is consistent at, so code points added
in 3.2 (Tagalog, Cyrillic Komi) are word characters while later additions
(the Tamil digit zero) stay unassigned and match \D. New XSDCategory and a
3.2 assignment table derived from DerivedAge, replacing the old Unicode31
files.

Content model: assess each child against the particle the content automaton
matched, not a by-name lookup (#180). Two same-named particles keep their
own fixed values, and an element matching a skip wildcard is no longer
validated against its global declaration. Selection is made reproducible
when an ambiguous schema slips past the UPA check.

XSTS runner: compile and merge every schemaDocument in a schemaTest, not
just the first; this also surfaced one previously-masked invalid-instance
acceptance (recorded in the baselines).

Also folds in attribute-group anyAttribute inheritance, extension wildcard
union, namespace-qualified type tables for multi-document
xsi:schemaLocation, per-container elementFormDefault, strict and lax
attribute wildcard validation, built-in type resolution, and xs:redefine
simpleType overrides.
2026-06-16 22:22:05 +02:00

98 lines
7.8 KiB
Swift

extension PureXML.Regex.XSDCategory {
/// Inclusive `[lo, hi]` code-point bounds of every range assigned by Unicode
/// 3.2. XSD 1.0 regular expressions are normatively defined against Unicode
/// 3.1, but the W3C conformance corpus is internally consistent only at 3.2:
/// it expects code points added in 3.2 (Tagalog, Cyrillic Komi, and others)
/// to be word characters, yet code points added in 4.0 (such as the Tamil
/// digit zero U+0BE6) to be unassigned and so match `\D`. Derived clean-room
/// from the Unicode Character Database `DerivedAge` property (ages <= 3.2),
/// stored sorted and non-overlapping so membership is a binary search.
private static let assignedRanges: [UInt32] = [
0x0, 0x220, 0x222, 0x233, 0x250, 0x2AD, 0x2B0, 0x2EE, 0x300, 0x34F, 0x360, 0x36F,
0x374, 0x375, 0x37A, 0x37A, 0x37E, 0x37E, 0x384, 0x38A, 0x38C, 0x38C, 0x38E, 0x3A1,
0x3A3, 0x3CE, 0x3D0, 0x3F6, 0x400, 0x486, 0x488, 0x4CE, 0x4D0, 0x4F5, 0x4F8, 0x4F9,
0x500, 0x50F, 0x531, 0x556, 0x559, 0x55F, 0x561, 0x587, 0x589, 0x58A, 0x591, 0x5A1,
0x5A3, 0x5B9, 0x5BB, 0x5C4, 0x5D0, 0x5EA, 0x5F0, 0x5F4, 0x60C, 0x60C, 0x61B, 0x61B,
0x61F, 0x61F, 0x621, 0x63A, 0x640, 0x655, 0x660, 0x6ED, 0x6F0, 0x6FE, 0x700, 0x70D,
0x70F, 0x72C, 0x730, 0x74A, 0x780, 0x7B1, 0x901, 0x903, 0x905, 0x939, 0x93C, 0x94D,
0x950, 0x954, 0x958, 0x970, 0x981, 0x983, 0x985, 0x98C, 0x98F, 0x990, 0x993, 0x9A8,
0x9AA, 0x9B0, 0x9B2, 0x9B2, 0x9B6, 0x9B9, 0x9BC, 0x9BC, 0x9BE, 0x9C4, 0x9C7, 0x9C8,
0x9CB, 0x9CD, 0x9D7, 0x9D7, 0x9DC, 0x9DD, 0x9DF, 0x9E3, 0x9E6, 0x9FA, 0xA02, 0xA02,
0xA05, 0xA0A, 0xA0F, 0xA10, 0xA13, 0xA28, 0xA2A, 0xA30, 0xA32, 0xA33, 0xA35, 0xA36,
0xA38, 0xA39, 0xA3C, 0xA3C, 0xA3E, 0xA42, 0xA47, 0xA48, 0xA4B, 0xA4D, 0xA59, 0xA5C,
0xA5E, 0xA5E, 0xA66, 0xA74, 0xA81, 0xA83, 0xA85, 0xA8B, 0xA8D, 0xA8D, 0xA8F, 0xA91,
0xA93, 0xAA8, 0xAAA, 0xAB0, 0xAB2, 0xAB3, 0xAB5, 0xAB9, 0xABC, 0xAC5, 0xAC7, 0xAC9,
0xACB, 0xACD, 0xAD0, 0xAD0, 0xAE0, 0xAE0, 0xAE6, 0xAEF, 0xB01, 0xB03, 0xB05, 0xB0C,
0xB0F, 0xB10, 0xB13, 0xB28, 0xB2A, 0xB30, 0xB32, 0xB33, 0xB36, 0xB39, 0xB3C, 0xB43,
0xB47, 0xB48, 0xB4B, 0xB4D, 0xB56, 0xB57, 0xB5C, 0xB5D, 0xB5F, 0xB61, 0xB66, 0xB70,
0xB82, 0xB83, 0xB85, 0xB8A, 0xB8E, 0xB90, 0xB92, 0xB95, 0xB99, 0xB9A, 0xB9C, 0xB9C,
0xB9E, 0xB9F, 0xBA3, 0xBA4, 0xBA8, 0xBAA, 0xBAE, 0xBB5, 0xBB7, 0xBB9, 0xBBE, 0xBC2,
0xBC6, 0xBC8, 0xBCA, 0xBCD, 0xBD7, 0xBD7, 0xBE7, 0xBF2, 0xC01, 0xC03, 0xC05, 0xC0C,
0xC0E, 0xC10, 0xC12, 0xC28, 0xC2A, 0xC33, 0xC35, 0xC39, 0xC3E, 0xC44, 0xC46, 0xC48,
0xC4A, 0xC4D, 0xC55, 0xC56, 0xC60, 0xC61, 0xC66, 0xC6F, 0xC82, 0xC83, 0xC85, 0xC8C,
0xC8E, 0xC90, 0xC92, 0xCA8, 0xCAA, 0xCB3, 0xCB5, 0xCB9, 0xCBE, 0xCC4, 0xCC6, 0xCC8,
0xCCA, 0xCCD, 0xCD5, 0xCD6, 0xCDE, 0xCDE, 0xCE0, 0xCE1, 0xCE6, 0xCEF, 0xD02, 0xD03,
0xD05, 0xD0C, 0xD0E, 0xD10, 0xD12, 0xD28, 0xD2A, 0xD39, 0xD3E, 0xD43, 0xD46, 0xD48,
0xD4A, 0xD4D, 0xD57, 0xD57, 0xD60, 0xD61, 0xD66, 0xD6F, 0xD82, 0xD83, 0xD85, 0xD96,
0xD9A, 0xDB1, 0xDB3, 0xDBB, 0xDBD, 0xDBD, 0xDC0, 0xDC6, 0xDCA, 0xDCA, 0xDCF, 0xDD4,
0xDD6, 0xDD6, 0xDD8, 0xDDF, 0xDF2, 0xDF4, 0xE01, 0xE3A, 0xE3F, 0xE5B, 0xE81, 0xE82,
0xE84, 0xE84, 0xE87, 0xE88, 0xE8A, 0xE8A, 0xE8D, 0xE8D, 0xE94, 0xE97, 0xE99, 0xE9F,
0xEA1, 0xEA3, 0xEA5, 0xEA5, 0xEA7, 0xEA7, 0xEAA, 0xEAB, 0xEAD, 0xEB9, 0xEBB, 0xEBD,
0xEC0, 0xEC4, 0xEC6, 0xEC6, 0xEC8, 0xECD, 0xED0, 0xED9, 0xEDC, 0xEDD, 0xF00, 0xF47,
0xF49, 0xF6A, 0xF71, 0xF8B, 0xF90, 0xF97, 0xF99, 0xFBC, 0xFBE, 0xFCC, 0xFCF, 0xFCF,
0x1000, 0x1021, 0x1023, 0x1027, 0x1029, 0x102A, 0x102C, 0x1032, 0x1036, 0x1039, 0x1040, 0x1059,
0x10A0, 0x10C5, 0x10D0, 0x10F8, 0x10FB, 0x10FB, 0x1100, 0x1159, 0x115F, 0x11A2, 0x11A8, 0x11F9,
0x1200, 0x1206, 0x1208, 0x1246, 0x1248, 0x1248, 0x124A, 0x124D, 0x1250, 0x1256, 0x1258, 0x1258,
0x125A, 0x125D, 0x1260, 0x1286, 0x1288, 0x1288, 0x128A, 0x128D, 0x1290, 0x12AE, 0x12B0, 0x12B0,
0x12B2, 0x12B5, 0x12B8, 0x12BE, 0x12C0, 0x12C0, 0x12C2, 0x12C5, 0x12C8, 0x12CE, 0x12D0, 0x12D6,
0x12D8, 0x12EE, 0x12F0, 0x130E, 0x1310, 0x1310, 0x1312, 0x1315, 0x1318, 0x131E, 0x1320, 0x1346,
0x1348, 0x135A, 0x1361, 0x137C, 0x13A0, 0x13F4, 0x1401, 0x1676, 0x1680, 0x169C, 0x16A0, 0x16F0,
0x1700, 0x170C, 0x170E, 0x1714, 0x1720, 0x1736, 0x1740, 0x1753, 0x1760, 0x176C, 0x176E, 0x1770,
0x1772, 0x1773, 0x1780, 0x17DC, 0x17E0, 0x17E9, 0x1800, 0x180E, 0x1810, 0x1819, 0x1820, 0x1877,
0x1880, 0x18A9, 0x1E00, 0x1E9B, 0x1EA0, 0x1EF9, 0x1F00, 0x1F15, 0x1F18, 0x1F1D, 0x1F20, 0x1F45,
0x1F48, 0x1F4D, 0x1F50, 0x1F57, 0x1F59, 0x1F59, 0x1F5B, 0x1F5B, 0x1F5D, 0x1F5D, 0x1F5F, 0x1F7D,
0x1F80, 0x1FB4, 0x1FB6, 0x1FC4, 0x1FC6, 0x1FD3, 0x1FD6, 0x1FDB, 0x1FDD, 0x1FEF, 0x1FF2, 0x1FF4,
0x1FF6, 0x1FFE, 0x2000, 0x2052, 0x2057, 0x2057, 0x205F, 0x2063, 0x206A, 0x2071, 0x2074, 0x208E,
0x20A0, 0x20B1, 0x20D0, 0x20EA, 0x2100, 0x213A, 0x213D, 0x214B, 0x2153, 0x2183, 0x2190, 0x23CE,
0x2400, 0x2426, 0x2440, 0x244A, 0x2460, 0x24FE, 0x2500, 0x2613, 0x2616, 0x2617, 0x2619, 0x267D,
0x2680, 0x2689, 0x2701, 0x2704, 0x2706, 0x2709, 0x270C, 0x2727, 0x2729, 0x274B, 0x274D, 0x274D,
0x274F, 0x2752, 0x2756, 0x2756, 0x2758, 0x275E, 0x2761, 0x2794, 0x2798, 0x27AF, 0x27B1, 0x27BE,
0x27D0, 0x27EB, 0x27F0, 0x2AFF, 0x2E80, 0x2E99, 0x2E9B, 0x2EF3, 0x2F00, 0x2FD5, 0x2FF0, 0x2FFB,
0x3000, 0x303F, 0x3041, 0x3096, 0x3099, 0x30FF, 0x3105, 0x312C, 0x3131, 0x318E, 0x3190, 0x31B7,
0x31F0, 0x321C, 0x3220, 0x3243, 0x3251, 0x327B, 0x327F, 0x32CB, 0x32D0, 0x32FE, 0x3300, 0x3376,
0x337B, 0x33DD, 0x33E0, 0x33FE, 0x3400, 0x4DB5, 0x4E00, 0x9FA5, 0xA000, 0xA48C, 0xA490, 0xA4C6,
0xAC00, 0xD7A3, 0xD800, 0xFA2D, 0xFA30, 0xFA6A, 0xFB00, 0xFB06, 0xFB13, 0xFB17, 0xFB1D, 0xFB36,
0xFB38, 0xFB3C, 0xFB3E, 0xFB3E, 0xFB40, 0xFB41, 0xFB43, 0xFB44, 0xFB46, 0xFBB1, 0xFBD3, 0xFD3F,
0xFD50, 0xFD8F, 0xFD92, 0xFDC7, 0xFDD0, 0xFDFC, 0xFE00, 0xFE0F, 0xFE20, 0xFE23, 0xFE30, 0xFE46,
0xFE49, 0xFE52, 0xFE54, 0xFE66, 0xFE68, 0xFE6B, 0xFE70, 0xFE74, 0xFE76, 0xFEFC, 0xFEFF, 0xFEFF,
0xFF01, 0xFFBE, 0xFFC2, 0xFFC7, 0xFFCA, 0xFFCF, 0xFFD2, 0xFFD7, 0xFFDA, 0xFFDC, 0xFFE0, 0xFFE6,
0xFFE8, 0xFFEE, 0xFFF9, 0xFFFF, 0x10300, 0x1031E, 0x10320, 0x10323, 0x10330, 0x1034A, 0x10400, 0x10425,
0x10428, 0x1044D, 0x1D000, 0x1D0F5, 0x1D100, 0x1D126, 0x1D12A, 0x1D1DD, 0x1D400, 0x1D454, 0x1D456, 0x1D49C,
0x1D49E, 0x1D49F, 0x1D4A2, 0x1D4A2, 0x1D4A5, 0x1D4A6, 0x1D4A9, 0x1D4AC, 0x1D4AE, 0x1D4B9, 0x1D4BB, 0x1D4BB,
0x1D4BD, 0x1D4C0, 0x1D4C2, 0x1D4C3, 0x1D4C5, 0x1D505, 0x1D507, 0x1D50A, 0x1D50D, 0x1D514, 0x1D516, 0x1D51C,
0x1D51E, 0x1D539, 0x1D53B, 0x1D53E, 0x1D540, 0x1D544, 0x1D546, 0x1D546, 0x1D54A, 0x1D550, 0x1D552, 0x1D6A3,
0x1D6A8, 0x1D7C9, 0x1D7CE, 0x1D7FF, 0x1FFFE, 0x2A6D6, 0x2F800, 0x2FA1D, 0x2FFFE, 0x2FFFF, 0x3FFFE, 0x3FFFF,
0x4FFFE, 0x4FFFF, 0x5FFFE, 0x5FFFF, 0x6FFFE, 0x6FFFF, 0x7FFFE, 0x7FFFF, 0x8FFFE, 0x8FFFF, 0x9FFFE, 0x9FFFF,
0xAFFFE, 0xAFFFF, 0xBFFFE, 0xBFFFF, 0xCFFFE, 0xCFFFF, 0xDFFFE, 0xDFFFF, 0xE0001, 0xE0001, 0xE0020, 0xE007F,
0xEFFFE, 0x10FFFF,
]
/// Whether `value` was an assigned code point as of Unicode 3.2. Binary
/// search over ``assignedRanges``; each step compares one range's bounds.
static func assignedInUnicode32(_ value: UInt32) -> Bool {
var low = 0
var high = assignedRanges.count / 2
while low < high {
let mid = (low + high) / 2
if value < assignedRanges[mid * 2] {
high = mid
} else if value > assignedRanges[mid * 2 + 1] {
low = mid + 1
} else {
return true
}
}
return false
}
}