1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
|
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2021 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
import GenUtils
func getCompExclusions(from data: String) -> [ClosedRange<UInt32>] {
var result: [ClosedRange<UInt32>] = []
for line in data.split(separator: "\n") {
// Skip comments
guard !line.hasPrefix("#") else {
continue
}
let info = line.split(separator: "#")
let components = info[0].split(separator: ";")
// Get the property first because we only care about Full_Composition_Exclusion
let filteredProperty = components[1].filter { !$0.isWhitespace }
guard filteredProperty == "Full_Composition_Exclusion" else {
continue
}
let scalars: ClosedRange<UInt32>
let filteredScalars = components[0].filter { !$0.isWhitespace }
// If we have . appear, it means we have a legitimate range. Otherwise,
// it's a singular scalar.
if filteredScalars.contains(".") {
let range = filteredScalars.split(separator: ".")
scalars = UInt32(range[0], radix: 16)! ... UInt32(range[1], radix: 16)!
} else {
let scalar = UInt32(filteredScalars, radix: 16)!
scalars = scalar ... scalar
}
result.append(scalars)
}
return result
}
func emitComp(_ mph: Mph, _ data: [(UInt32, [UInt32])], into result: inout String) {
emitMph(
mph,
name: "_swift_stdlib_nfc_comp",
defineLabel: "NFC_COMP",
into: &result
)
emitCompComps(mph, data, into: &result)
}
func emitCompComps(
_ mph: Mph,
_ data: [(UInt32, [UInt32])],
into result: inout String
) {
let uniqueKeys = Set(data.map { $0.1[1] })
var sortedData: [[(UInt32, UInt32)]] = .init(
repeating: [],
count: uniqueKeys.count
)
for (scalar, comp) in data {
let idx = mph.index(for: UInt64(comp[1]))
if sortedData[idx].isEmpty {
sortedData[idx].append((comp[1], .max))
}
sortedData[idx].append((comp[0], scalar))
}
// Go back and sort each array as well as putting the size information of each
// in the first element (who contains the original y scalar that was hashed).
for i in sortedData.indices {
sortedData[i][1...].sort { $0.0 < $1.0 }
sortedData[i][0].0 = sortedData[i][0].0 | UInt32(sortedData[i].count << 21)
}
for i in sortedData.indices {
result += """
static const __swift_uint32_t _swift_stdlib_nfc_comp\(i)[\(sortedData[i].count)] = {
"""
formatCollection(sortedData[i], into: &result) { (comp, scalar) in
// This only occurs for the first element who stores the original y scalar
// in the composition and the size of the array.
if scalar == .max {
return "0x\(String(comp, radix: 16, uppercase: true))"
}
// Make sure that these scalars don't exceed past 17 bits. We need the other
// 15 bits to store the range to the final composition. Although Unicode
// scalars can go up to 21 bits, none of the compositions with this scalar
// go that high.
assert(comp <= 0x1FFFF)
var value = comp
// Calculate the distance from our current composition scalar to our final
// composed scalar.
let distance = Int(scalar) - Int(comp)
// Make sure that our distance doesn't exceed 14 bits. Although the above
// assertion gives us 15 bits, we use the last bit to indicate negative
// or not.
assert(distance <= 0x3FFF)
value |= UInt32(distance.magnitude) << 17
if distance < 0 {
value |= 1 << 31
}
return "0x\(String(value, radix: 16, uppercase: true))"
}
result += "\n};\n\n"
}
result += """
static const __swift_uint32_t * const _swift_stdlib_nfc_comp_indices[\(sortedData.count)] = {
"""
formatCollection(sortedData.indices, into: &result) { i in
return "_swift_stdlib_nfc_comp\(i)"
}
result += "\n};\n\n"
}
|