-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuild.rs
More file actions
63 lines (52 loc) · 1.63 KB
/
Copy pathbuild.rs
File metadata and controls
63 lines (52 loc) · 1.63 KB
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
use std::{
env,
error::Error,
fmt,
fs::File,
io::{BufWriter, Write},
path::Path,
};
const RUSTC_MAX_ALIGN_EXP: u16 = 29;
fn main() -> Result<(), Box<dyn Error>> {
println!("cargo::rerun-if-changed=build.rs");
let ptr_width: u16 = env::var("CARGO_CFG_TARGET_POINTER_WIDTH")?
.parse::<u64>()?
.try_into()?;
// -2 because align must be less than isize::MAX,
// and pow(2, ptr_width - 1) = isize::MAX + 1.
let max_align_exp = (ptr_width - 2).min(RUSTC_MAX_ALIGN_EXP);
let out_dir = env::var_os("OUT_DIR").ok_or(env::VarError::NotPresent)?;
let out_dir = Path::new(&out_dir);
let mut f = BufWriter::new(File::create(out_dir.join("for_each_align.rs"))?);
write_for_each_align_macro(&mut f, max_align_exp)?;
Ok(())
}
fn write_for_each_align_macro(f: &mut impl Write, max_align_exp: u16) -> std::io::Result<()> {
write!(f, "macro_rules! for_each_align {{")?;
write!(f, "{}($($mac:tt)*) => {{", IndentLn(1))?;
write!(f, "{}$($mac)*! {{", IndentLn(2))?;
let ln = IndentLn(3);
// yield all pow(2, i) for i in 0..=max_align_exp
for i in 0..=max_align_exp {
// pow(2, i) = 0b10...0 in binary, with i zeros
write!(f, "{ln}0b1")?;
for _ in 0..i {
write!(f, "0")?;
}
}
for i in (0..=2).rev() {
write!(f, "{}", IndentLn(i))?;
write!(f, "}}")?;
}
Ok(())
}
struct IndentLn(u8);
impl std::fmt::Display for IndentLn {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
writeln!(f)?;
for _ in 0..self.0 {
write!(f, " ")?;
}
Ok(())
}
}