Skip to main content

rsmemgen/
lib.rs

1use proc_macro::TokenStream;
2
3#[macro_use]
4mod errors;
5#[macro_use]
6mod logger;
7
8use quote::{ToTokens};
9
10use logger::{rsmemgen_debug_out,rsmemgen_log_get_timestamp};
11
12
13macro_rules! syn_error_fmt {
14    ($($a:expr),*) => {
15        let cerr = format!($($a),*);
16        eprintln!("{}",cerr);
17        rsmemgen_log_error!("{}",cerr);
18        return cerr.parse().unwrap();
19        //return syn::Error::new(
20        //            Span::call_site(),
21        //            $cerr,
22        //        ).to_compile_error().to_string().parse().unwrap();
23    }
24}
25
26
27#[allow(unused_assignments)]
28#[proc_macro_attribute]
29pub fn rsmemgen_impl_inline(_args :TokenStream , input :TokenStream) -> TokenStream {
30    let mut implstruct : syn::ItemImpl ;
31
32    match std::env::var("RSMEMCHK_MODE") {
33        Ok(_v) => {},
34        Err(_e) => {
35            /*we do not set this handle*/
36            rsmemgen_log_trace!("retv\n{}",input.to_string());
37            return input;
38        },
39    }
40
41
42    match syn::parse::<syn::ItemImpl>(input.clone()) {
43        Ok(v) => {
44            implstruct = v.clone();
45        },
46        Err(_e) => {
47            syn_error_fmt!("not parse \n{}",input.to_string());
48        }
49    }
50
51    let mut idx :usize = 0;
52    while idx < implstruct.items.len() {
53        let item = implstruct.items[idx].clone();
54        let mut tk : TokenStream;
55        let mut newfn :Option<syn::ImplItemFn> = None;
56
57        match item {
58            syn::ImplItem::Fn(fnptr) => {                
59                tk = fnptr.clone().into_token_stream().into();
60                rsmemgen_log_trace!("fnptr\n{}", tk.to_string());
61                let mut inlinematch :bool = false;
62
63                if fnptr.attrs.len() > 0 {
64                    for a in fnptr.attrs.iter() {
65                        tk = a.into_token_stream().into();
66                        rsmemgen_log_trace!("a\n{}",tk.to_string());
67                        match a.meta.clone() {
68                            syn::Meta::List(l) => {
69                                //tk = l.into_token_stream().into();
70                                //rsmemgen_log_trace!("l\n{}",tk.to_string());
71                                tk = l.path.into_token_stream().into();
72                                rsmemgen_log_trace!("path\n{}",tk.to_string());
73                                let pname = tk.to_string();
74                                if pname == "inline" {
75                                    inlinematch = true;
76                                }
77                            },
78                            _ => {
79                            },
80                        }
81                    }
82                }
83                if !inlinematch {
84                    newfn = Some(fnptr.clone());
85                    let  c :&mut syn::ImplItemFn = newfn.as_mut().unwrap();
86                    let cp :syn::Attribute = syn::parse_quote! {
87                         #[inline(never)]
88                    };
89                    c.attrs.push(cp.clone());
90                }
91            },
92            _ => {},
93
94        }
95
96        if newfn.is_some() {
97            implstruct.items[idx] = syn::ImplItem::Fn(newfn.as_ref().unwrap().clone());
98        }
99        idx += 1;
100    }
101
102    let retv :TokenStream = implstruct.into_token_stream().into();
103    rsmemgen_log_trace!("retv\n{}",retv.to_string());
104
105    return retv;
106}
107
108#[proc_macro_attribute]
109pub fn rsmemgen_func_inline(_args :TokenStream , input :TokenStream) -> TokenStream {
110    let mut fnstruct : syn::ItemFn ;
111
112    match std::env::var("RSMEMCHK_MODE") {
113        Ok(_v) => {},
114        Err(_e) => {
115            /*we do not set this handle*/
116            rsmemgen_log_trace!("retv\n{}",input.to_string());
117            return input;
118        },
119    }
120
121
122    match syn::parse::<syn::ItemFn>(input.clone()) {
123        Ok(v) => {
124            fnstruct = v.clone();
125        },
126        Err(_e) => {
127            syn_error_fmt!("not parse \n{}",input.to_string());
128        }
129    }
130
131    let mut matched :bool = false;
132    let mut idx :usize = 0;
133    while idx < fnstruct.attrs.len() {
134        let a :syn::Attribute = fnstruct.attrs[idx].clone();
135        let mut tk : TokenStream;
136        tk = a.clone().into_token_stream().into();
137        rsmemgen_log_trace!("a\n{}",tk.to_string());
138        match a.meta.clone() {
139            syn::Meta::List(l) => {
140                //tk = l.into_token_stream().into();
141                //rsmemgen_log_trace!("l\n{}",tk.to_string());
142                tk = l.path.into_token_stream().into();
143                rsmemgen_log_trace!("path\n{}",tk.to_string());
144                let pname = tk.to_string();
145                if pname == "inline" {
146                    matched = true;
147                    break;
148                }
149            },
150            _ => {
151            },
152        }
153        idx += 1;
154    }
155
156    if !matched {
157        let cp :syn::Attribute = syn::parse_quote! {
158            #[inline(never)]
159        };
160        fnstruct.attrs.push(cp.clone());
161    }
162
163
164    let retv :TokenStream = fnstruct.into_token_stream().into();
165    rsmemgen_log_trace!("retv\n{}",retv.to_string());
166    return retv;
167}