diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 34137207d1ac52d9ffdbaff1fc37816cb465fb4b..9ffa2bbb31a0e99a095b7054486ef281a856c284 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -26,6 +26,18 @@ "problemMatcher": [ "$rustc" ] + }, + { + "label": "cargo run --example trustall", + "type": "shell", + "command": "cargo run --example trustall", + "group": { + "kind": "build", + "isDefault": true + }, + "problemMatcher": [ + "$rustc" + ] } ] } \ No newline at end of file diff --git a/examples/trustall.rs b/examples/trustall.rs new file mode 100644 index 0000000000000000000000000000000000000000..7ffb750864c52b59ee14c9fd0c261be202bbe23e --- /dev/null +++ b/examples/trustall.rs @@ -0,0 +1,34 @@ +use proc_collect::*; +trustall! { + + fn hello() { + println!("in trust hello"); + ext_hello(); + } + + #[entry] + #[inline(always)] + fn entry() { + hello(); + } + + #[interrupt] + fn i1() { + println!("i1"); + } + + #[interrupt] + fn i2() { + println!("i2"); + } + + #[exception] + fn exception() { + println!("exc"); + } + +} + +fn ext_hello() { + println!("ext_hello"); +} diff --git a/src/lib.rs b/src/lib.rs index e3c3c4f1d65b9b32222380049c9f4ee1649ac2f0..ef39a2e5a3e1a71d3b073ec62e9fdcf82649ddb1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -103,3 +103,64 @@ pub fn trust(_args: TokenStream, input: TokenStream) -> TokenStream { }) .into() } + +#[derive(Debug)] +struct TrustMod2 { + items: Vec<Item>, + entries: Vec<Entry>, +} + +impl Parse for TrustMod2 { + fn parse(input: ParseStream) -> Result<Self> { + let mut items = vec![]; + while let Ok(i) = input.parse() { + items.push(i); + } + let mut e = vec![]; + + for i in &items { + match i { + Item::Fn(ref item_fn) => { + for a in &item_fn.attrs { + for s in &a.path.segments { + match s.ident.to_string().as_str() { + "entry" => e.push(Entry::Entry(item_fn.sig.ident.clone())), + "interrupt" => e.push(Entry::Interrupt(item_fn.sig.ident.clone())), + "exception" => e.push(Entry::Exception(item_fn.sig.ident.clone())), + _ => (), + } + } + } + } + _ => (), + } + } + Ok(TrustMod2 { items, entries: e }) + } +} + +#[proc_macro] +pub fn trustall(input: TokenStream) -> TokenStream { + let i = input.clone(); + let trust = parse_macro_input!(i as TrustMod2); + + let mut calls = vec![]; + for e in trust.entries { + let id = match e { + Entry::Entry(id) => id, + Entry::Interrupt(id) => id, + Entry::Exception(id) => id, + }; + calls.push(quote! { let _ = #id(); }); + } + + let items = trust.items; + + (quote! { + #(#items)* + fn main() { + #(#calls)* + } + }) + .into() +}