aboutsummaryrefslogtreecommitdiff
path: root/build.rs
diff options
context:
space:
mode:
authorJorge Aparicio <japaricious@gmail.com>2017-04-09 22:42:17 -0500
committerJorge Aparicio <japaricious@gmail.com>2017-04-09 22:42:17 -0500
commit595404c5ffc37ce95ffb2b6999ab85e6818bfa50 (patch)
tree43688c0818f2af6fdb37ce2e3f29dd7f0ccb898b /build.rs
parent6ac2625a75fc73b5cb846cd3d60422976f8946fc (diff)
compile time verified ceilings
Diffstat (limited to 'build.rs')
-rw-r--r--build.rs103
1 files changed, 100 insertions, 3 deletions
diff --git a/build.rs b/build.rs
index 46bdb71..19625e5 100644
--- a/build.rs
+++ b/build.rs
@@ -1,9 +1,106 @@
+#[macro_use]
+extern crate quote;
+extern crate syn;
+
use std::env;
+use std::fs::File;
+use std::io::Write;
+use std::path::PathBuf;
+
+use syn::{Ident, IntTy, Lit};
fn main() {
- let target = env::var("TARGET").unwrap();
+ let bits = if env::var_os("CARGO_FEATURE_P2").is_some() {
+ 2
+ } else if env::var_os("CARGO_FEATURE_P3").is_some() {
+ 3
+ } else if env::var_os("CARGO_FEATURE_P4").is_some() {
+ 4
+ } else if env::var_os("CARGO_FEATURE_P5").is_some() {
+ 5
+ } else {
+ panic!(
+ "Specify the number of priority bits through one of these Cargo \
+ features: P2, P3, P4 or P5"
+ );
+ };
+
+ let n = Lit::Int(bits, IntTy::Unsuffixed);
+ let mut tokens = vec![];
+ tokens.push(
+ quote! {
+ const PRIORITY_BITS: u8 = #n;
+ },
+ );
+
+ // Ceilings
+ for i in 1..(1 << bits) + 1 {
+ let c = Ident::new(format!("C{}", i));
+ let u = Ident::new(format!("U{}", i));
+
+ tokens.push(
+ quote! {
+ /// Ceiling
+ pub type #c = C<::typenum::#u>;
+
+ unsafe impl Ceiling for #c {}
+ },
+ );
+ }
+
+ // Priorities
+ for i in 1..(1 << bits) + 1 {
+ let p = Ident::new(format!("P{}", i));
+ let u = Ident::new(format!("U{}", i));
+
+ tokens.push(
+ quote! {
+ /// Priority
+ pub type #p = P<::typenum::#u>;
+
+ unsafe impl Priority for #p {}
- if target == "thumbv6m-none-eabi" {
- println!("cargo:rustc-cfg=thumbv6m");
+ unsafe impl Level for ::typenum::#u {
+ fn hw() -> u8 {
+ logical2hw(::typenum::#u::to_u8())
+ }
+ }
+ },
+ );
}
+
+ // GreaterThanOrEqual
+ for i in 1..(1 << bits) + 1 {
+ for j in 1..(i + 1) {
+ let i = Ident::new(format!("U{}", i));
+ let j = Ident::new(format!("U{}", j));
+
+ tokens.push(
+ quote! {
+ unsafe impl GreaterThanOrEqual<::typenum::#j> for
+ ::typenum::#i {}
+ },
+ );
+ }
+ }
+
+ let u = Ident::new(format!("U{}", (1 << bits)));
+ tokens.push(quote! {
+ #[doc(hidden)]
+ pub type CMAX = C<::typenum::#u>;
+
+ /// Maximum priority level
+ pub type UMAX = ::typenum::#u;
+ });
+
+ let tokens = quote! {
+ #(#tokens)*
+ };
+
+ let out_dir = env::var("OUT_DIR").unwrap();
+ let mut out = File::create(PathBuf::from(out_dir).join("prio.rs")).unwrap();
+
+ out.write_all(tokens.as_str().as_bytes()).unwrap();
+
+ println!("cargo:rerun-if-changed=build.rs");
}