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
|
use std::error::Error;
use std::path::Path;
use bindgen::callbacks::ParseCallbacks;
use bindgen::{CodegenConfig, MacroTypeVariation};
pub fn generate_bindings(dest_file: &Path) -> Result<(), Box<dyn Error>>
{
println!("cargo:rerun-if-changed=gl.h");
let bindings = bindgen::Builder::default()
.header("gl.h")
.default_macro_constant_type(MacroTypeVariation::Signed)
.with_codegen_config(CodegenConfig::all() & !CodegenConfig::FUNCTIONS)
.allowlist_type("GL.*")
.allowlist_type("_cl_.*")
.allowlist_var("GL_.*")
.blocklist_item("GL_Z4.*")
.blocklist_item("GL_Z6.*")
.parse_callbacks(Box::new(Callbacks))
.generate()?;
bindings.write_to_file(dest_file)?;
Ok(())
}
#[derive(Debug)]
struct Callbacks;
impl ParseCallbacks for Callbacks
{
fn item_name(&self, original_item_name: &str) -> Option<String>
{
let stripped = original_item_name.strip_prefix("GL_")?;
if stripped.starts_with(|character: char| character.is_ascii_digit()) {
let digit_cnt = stripped
.chars()
.filter(|character| character.is_ascii_digit())
.count();
let digits = stripped
.chars()
.take_while(|character| character.is_ascii_digit())
.map(|character| match character {
'0' => "zero",
'1' => "one",
'2' => "two",
'3' => "three",
'4' => "four",
'5' => "five",
'6' => "six",
'7' => "seven",
'8' => "eight",
'9' => "nine",
_ => unreachable!(),
});
return Some(
digits
.map(|digit| digit.chars())
.flatten()
.map(|character| character.to_ascii_uppercase())
.chain(stripped.chars().skip(digit_cnt))
.collect::<String>(),
);
}
Some(stripped.to_string())
}
}
|