1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#![feature(proc_macro)]
extern crate proc_macro;
extern crate syn;
#[macro_use]
extern crate quote;
use std::env;
use syn::{Ident, ItemKind};
use proc_macro::TokenStream;
#[proc_macro_attribute]
pub fn init(_: TokenStream, target: TokenStream) -> TokenStream {
let s = target.to_string();
let package_name = env::var("CARGO_PKG_NAME").unwrap().replace('-', "_");
let package_version = env::var("CARGO_PKG_VERSION").unwrap().replace('.', "_");
let abi_name = Ident::new(format!("_rust_init_{}_{}", package_name, package_version));
let item = syn::parse_item(&s).unwrap();
match item.node {
ItemKind::Fn(..) => {
let item_name = &item.ident;
let gen = quote! {
#[inline(always)]
#item
#[no_mangle]
pub extern "C" fn #abi_name() {
#item_name();
}
};
gen.parse().unwrap()
}
_ => {
target
}
}
}