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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
use std::{
os, panic,
collections::HashMap,
sync::{Mutex, atomic::AtomicBool},
};
use lazy_static::lazy_static;
use crate::{Env, Value, Result};
#[deprecated(since = "0.11.0", note = "Please use `#[emacs::module]` instead")]
#[macro_export]
macro_rules! module_init {
($($inner:tt)*) => {
$crate::__module_init!($($inner)*);
};
}
#[deprecated(since = "0.7.0", note = "Please use `#[emacs::module]` instead")]
#[doc(hidden)]
#[macro_export]
macro_rules! emacs_module_init {
($($inner:tt)*) => {
$crate::__module_init!($($inner)*);
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __module_init {
($init:ident) => {
#[no_mangle]
pub unsafe extern "C" fn emacs_module_init(
runtime: *mut $crate::raw::emacs_runtime,
) -> ::std::os::raw::c_int {
$crate::init::initialize(&$crate::Env::from_runtime(runtime), $init)
}
#[no_mangle]
pub unsafe extern "C" fn emacs_rs_module_init(
raw: *mut $crate::raw::emacs_env,
) -> ::std::os::raw::c_int {
$crate::init::initialize(&$crate::Env::new(raw), $init)
}
};
}
type InitFn = dyn Fn(&Env) -> Result<()> + Send + 'static;
type FnMap = HashMap<String, Box<InitFn>>;
lazy_static! {
pub static ref __INIT_FNS__: Mutex<FnMap> = Mutex::new(HashMap::new());
pub static ref __PREFIX__: Mutex<[String; 2]> = Mutex::new(["".to_owned(), "-".to_owned()]);
pub static ref __MOD_IN_NAME__: AtomicBool = AtomicBool::new(true);
}
#[inline]
pub fn initialize<F>(env: &Env, f: F) -> os::raw::c_int
where
F: Fn(&Env) -> Result<Value<'_>> + panic::RefUnwindSafe,
{
let env = panic::AssertUnwindSafe(env);
let result = panic::catch_unwind(|| match env.define_errors().and_then(|_| f(&env)) {
Ok(_) => 0,
Err(e) => {
env.message(format!("Error during initialization: {:#?}", e))
.expect("Fail to message Emacs about error");
1
}
});
match result {
Ok(v) => v,
Err(e) => {
env.message(format!("Panic during initialization: {:#?}", e))
.expect("Fail to message Emacs about panic");
2
}
}
}
fn lisp_name(s: &str) -> String {
s.replace("_", "-")
}
pub fn lisp_pkg(module_path: &str) -> String {
let crate_name = module_path.split("::").nth(0).expect("module_path is empty!");
lisp_name(&crate_name)
}
pub fn lisp_path(module_path: &str) -> String {
let split = module_path.split("::");
let mut path =
__PREFIX__.try_lock().expect("Failed to acquire read lock of module prefix").join("");
for segment in split.skip(1) {
path.push_str(segment);
path.push('-');
}
lisp_name(&path)
}