extern crate regex;
#[cfg(target_os = "freebsd")]
fn main() {
use regex::Regex;
use std::{env, fs::File, io::Write, path::PathBuf};
println!("cargo:rerun-if-env-changed=LLVM_CONFIG_PATH");
println!("cargo:rustc-link-lib=nv");
let autobindings = bindgen::Builder::default()
.header("/usr/include/sys/nv.h")
.allowlist_function("nvlist_.*")
.allowlist_function("FreeBSD_nvlist_.*")
.allowlist_type("nvlist_t")
.allowlist_type("FreeBSD_nvlist_t")
.blocklist_type("size_t")
.blocklist_type("__size_t")
.blocklist_type("__uint64_t")
.opaque_type("FILE")
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
.generate()
.expect("Unable to generate bindings")
.to_string();
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
let mut fixed_bindings = String::new();
let mut prev_index = 0;
let re = Regex::new("pub (fn|type) FreeBSD_([a-zA-Z0-9_]+)").unwrap();
for cap in re.captures_iter(&autobindings) {
let index = cap.get(0).unwrap().start();
fixed_bindings.push_str(&autobindings[prev_index..index]);
let new_fragment = match cap.get(1).unwrap().as_str() {
"fn" => {
let funcname = cap.get(2).unwrap().as_str();
fixed_bindings.push_str(&format!("#[link_name = \"FreeBSD_{}\"]\n", funcname));
format!("pub fn {}", funcname)
},
"type" => {
let typename = cap.get(2).unwrap().as_str();
fixed_bindings
.push_str(&format!("pub type FreeBSD_{} = {};\n", typename, typename));
format!("pub type {}", typename)
},
_ => unreachable!(),
};
fixed_bindings.push_str(&new_fragment);
prev_index = index + new_fragment.len() + "FreeBSD_".len();
}
fixed_bindings.push_str(&autobindings[prev_index..]);
File::create(out_path.join("bindings.rs"))
.unwrap()
.write_all(fixed_bindings.as_bytes())
.expect("Couldn't write bindings!");
}
#[cfg(not(target_os = "freebsd"))]
fn main() {
println!("cargo:rustc-cfg=crossdocs");
}