diff options
| author | Jorge Aparicio <japaricious@gmail.com> | 2017-04-09 22:42:17 -0500 |
|---|---|---|
| committer | Jorge Aparicio <japaricious@gmail.com> | 2017-04-09 22:42:17 -0500 |
| commit | 595404c5ffc37ce95ffb2b6999ab85e6818bfa50 (patch) | |
| tree | 43688c0818f2af6fdb37ce2e3f29dd7f0ccb898b /build.rs | |
| parent | 6ac2625a75fc73b5cb846cd3d60422976f8946fc (diff) | |
compile time verified ceilings
Diffstat (limited to 'build.rs')
| -rw-r--r-- | build.rs | 103 |
1 files changed, 100 insertions, 3 deletions
@@ -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"); } |
