From b25d8835d37fee30d6156be2d33bee1f2b6f8ccb Mon Sep 17 00:00:00 2001
From: Per Lindgren <per.lindgren@ltu.se>
Date: Fri, 14 Feb 2020 09:15:07 +0100
Subject: [PATCH] trustall

---
 .vscode/tasks.json   | 12 +++++++++
 examples/trustall.rs | 34 ++++++++++++++++++++++++
 src/lib.rs           | 61 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 107 insertions(+)
 create mode 100644 examples/trustall.rs

diff --git a/.vscode/tasks.json b/.vscode/tasks.json
index 3413720..9ffa2bb 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 0000000..7ffb750
--- /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 e3c3c4f..ef39a2e 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()
+}
-- 
GitLab