-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathstring_pool.rs
134 lines (114 loc) · 3.8 KB
/
string_pool.rs
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
#[cfg(not(any(target_os = "macos", target_os = "windows")))]
#[distributed_slice]
pub(crate) static STRPLI: [&'static str] = [..];
#[cfg(any(target_os = "macos", target_os = "windows"))]
pub(crate) struct strpool_literal(pub(crate) &'static str);
#[cfg(any(target_os = "macos", target_os = "windows"))]
inventory::collect!(strpool_literal);
static STRPOOL_ITEMS_FROM_256: Lazy<Vec<&'static str>> = Lazy::new(prepare_compiletime_string_pool);
#[cfg(not(any(target_os = "macos", target_os = "windows")))]
fn prepare_compiletime_string_pool() -> Vec<&'static str> {
let mut existing = BTreeSet::new();
let mut result = vec![];
for str in STRPLI.iter().cloned() {
if str.len() == 1 {
continue;
}
if existing.contains(&str) {
continue;
}
result.push(str);
existing.insert(str);
}
result.sort();
result
}
#[cfg(any(target_os = "macos", target_os = "windows"))]
fn prepare_compiletime_string_pool() -> Vec<&'static str> {
let mut existing = BTreeSet::new();
let mut result = vec![];
for strpool_literal(str) in inventory::iter::<strpool_literal> {
let str = *str;
if str.len() == 1 {
continue;
}
if existing.contains(&str) {
continue;
}
result.push(str);
existing.insert(str);
}
result.sort();
result
}
#[cfg(not(any(target_os = "macos", target_os = "windows")))]
pub(crate) macro strpool_str($s:expr) {{
#[::linkme::distributed_slice(crate::string_pool::STRPLI)]
static __: &'static str = $s;
let v = crate::string_pool::string_pool_index($s);
debug_assert!(v <= crate::pascal::char::MAX.0 as _);
crate::section_0038::str_number(crate::pascal::u32_from_m_to_n::new(v as u32))
}}
#[cfg(not(any(target_os = "macos", target_os = "windows")))]
pub(crate) macro submit_strpool_str($s:expr) {
const _: () = {
#[::linkme::distributed_slice(crate::string_pool::STRPLI)]
static __: &'static str = $s;
};
}
#[cfg(any(target_os = "macos", target_os = "windows"))]
pub(crate) macro strpool_str($s:expr) {{
inventory::submit! {
crate::string_pool::strpool_literal($s)
}
let v = crate::string_pool::string_pool_index($s);
debug_assert!(v <= crate::pascal::char::MAX.0 as _);
crate::section_0038::str_number(crate::pascal::u32_from_m_to_n::new(v as u32))
}}
#[cfg(any(target_os = "macos", target_os = "windows"))]
pub(crate) macro submit_strpool_str($s:expr) {
inventory::submit! {
crate::string_pool::strpool_literal($s)
}
}
pub(crate) fn string_pool_index(val: &'static str) -> usize {
if val.len() == 1 {
return val.as_bytes()[0] as usize;
}
for (idx, str) in (256usize..).zip(STRPOOL_ITEMS_FROM_256.iter().cloned()) {
if val == str {
return idx;
}
}
unreachable!(
"Literal `{}` not found in string pool, string pool size is {}.",
val,
256 + STRPOOL_ITEMS_FROM_256.len()
);
}
static POOL_FILE: Lazy<Vec<u8>> = Lazy::new(generate_initial_memory_pool_file);
static CHECKSUM: Lazy<usize> = Lazy::new(generate_checksum);
pub(crate) fn string_pool_checksum() -> usize {
*CHECKSUM
}
pub(crate) fn generate_initial_memory_pool_file() -> Vec<u8> {
let mut cursor = io::Cursor::new(vec![]);
for str in STRPOOL_ITEMS_FROM_256.iter().cloned() {
assert!(str.len() < 256);
write!(cursor, "{:02}{}\n", str.len(), str).unwrap();
}
write!(cursor, "*{:09}", *CHECKSUM).unwrap();
use std::io::Write;
cursor.into_inner()
}
pub(crate) fn generate_checksum() -> usize {
123456789
}
/// TeX string pool data
pub fn pool_file() -> io::Cursor<&'static [u8]> {
io::Cursor::new(&*POOL_FILE)
}
use linkme::distributed_slice;
use once_cell::sync::Lazy;
use std::collections::BTreeSet;
use std::io;