use proc_macro::TokenStream;
#[macro_use]
mod errors;
#[macro_use]
mod logger;
use quote::{ToTokens};
use logger::{rsmemgen_debug_out,rsmemgen_log_get_timestamp};
macro_rules! syn_error_fmt {
($($a:expr),*) => {
let cerr = format!($($a),*);
eprintln!("{}",cerr);
rsmemgen_log_error!("{}",cerr);
return cerr.parse().unwrap();
}
}
#[allow(unused_assignments)]
#[proc_macro_attribute]
pub fn rsmemgen_impl_inline(_args :TokenStream , input :TokenStream) -> TokenStream {
let mut implstruct : syn::ItemImpl ;
match std::env::var("RSMEMCHK_MODE") {
Ok(_v) => {},
Err(_e) => {
rsmemgen_log_trace!("retv\n{}",input.to_string());
return input;
},
}
match syn::parse::<syn::ItemImpl>(input.clone()) {
Ok(v) => {
implstruct = v.clone();
},
Err(_e) => {
syn_error_fmt!("not parse \n{}",input.to_string());
}
}
let mut idx :usize = 0;
while idx < implstruct.items.len() {
let item = implstruct.items[idx].clone();
let mut tk : TokenStream;
let mut newfn :Option<syn::ImplItemFn> = None;
match item {
syn::ImplItem::Fn(fnptr) => {
tk = fnptr.clone().into_token_stream().into();
rsmemgen_log_trace!("fnptr\n{}", tk.to_string());
let mut inlinematch :bool = false;
if fnptr.attrs.len() > 0 {
for a in fnptr.attrs.iter() {
tk = a.into_token_stream().into();
rsmemgen_log_trace!("a\n{}",tk.to_string());
match a.meta.clone() {
syn::Meta::List(l) => {
tk = l.path.into_token_stream().into();
rsmemgen_log_trace!("path\n{}",tk.to_string());
let pname = tk.to_string();
if pname == "inline" {
inlinematch = true;
}
},
_ => {
},
}
}
}
if !inlinematch {
newfn = Some(fnptr.clone());
let c :&mut syn::ImplItemFn = newfn.as_mut().unwrap();
let cp :syn::Attribute = syn::parse_quote! {
#[inline(never)]
};
c.attrs.push(cp.clone());
}
},
_ => {},
}
if newfn.is_some() {
implstruct.items[idx] = syn::ImplItem::Fn(newfn.as_ref().unwrap().clone());
}
idx += 1;
}
let retv :TokenStream = implstruct.into_token_stream().into();
rsmemgen_log_trace!("retv\n{}",retv.to_string());
return retv;
}
#[proc_macro_attribute]
pub fn rsmemgen_func_inline(_args :TokenStream , input :TokenStream) -> TokenStream {
let mut fnstruct : syn::ItemFn ;
match std::env::var("RSMEMCHK_MODE") {
Ok(_v) => {},
Err(_e) => {
rsmemgen_log_trace!("retv\n{}",input.to_string());
return input;
},
}
match syn::parse::<syn::ItemFn>(input.clone()) {
Ok(v) => {
fnstruct = v.clone();
},
Err(_e) => {
syn_error_fmt!("not parse \n{}",input.to_string());
}
}
let mut matched :bool = false;
let mut idx :usize = 0;
while idx < fnstruct.attrs.len() {
let a :syn::Attribute = fnstruct.attrs[idx].clone();
let mut tk : TokenStream;
tk = a.clone().into_token_stream().into();
rsmemgen_log_trace!("a\n{}",tk.to_string());
match a.meta.clone() {
syn::Meta::List(l) => {
tk = l.path.into_token_stream().into();
rsmemgen_log_trace!("path\n{}",tk.to_string());
let pname = tk.to_string();
if pname == "inline" {
matched = true;
break;
}
},
_ => {
},
}
idx += 1;
}
if !matched {
let cp :syn::Attribute = syn::parse_quote! {
#[inline(never)]
};
fnstruct.attrs.push(cp.clone());
}
let retv :TokenStream = fnstruct.into_token_stream().into();
rsmemgen_log_trace!("retv\n{}",retv.to_string());
return retv;
}