1use ::rdll::*;
5use ::std::ffi::*;
6
7use ::protect::stackp::*;
8use traits::ToSEXP;
9
10pub unsafe extern "C" fn check_interrupt_fn(_ptr: *mut ::std::os::raw::c_void ) {
11 R_CheckUserInterrupt();
12}
13
14#[macro_export]
17macro_rules! cstring {
18 ($x:expr) => (
19 ::std::ffi::CString::new($x).unwrap().as_ptr()
20 )
21 }
22
23pub unsafe fn cstr_sym(x: &str) -> SEXP {
24 Rf_install(c_str(x).as_ptr())
25}
26
27#[inline]
28pub fn cstring_user<T: Into<Vec<u8>>>(string: T) -> Result<CString, NulError> {
29
30 ::std::ffi::CString::new(string)
31
32}
33
34pub fn check_user_interrupt() -> bool {
35 unsafe { R_ToplevelExec(Some(check_interrupt_fn), ::std::ptr::null_mut()) != Rboolean::TRUE }
36}
37
38#[inline]
39pub fn c_str(x: &str) -> CString {
40 match CString::new(x) {
41 Ok(some) => some,
42 Err(err) => {
43 unsafe {
44 Rf_warning(cstring!(format!("{:?} from string '{:?}': safe string \
45 transformation failed, use unknown",
46 err,
47 x)));
48 }
49 CString::new("unknown").unwrap()
50 }
51 }
52}
53
54
55#[inline]
56pub fn c_str2(x: &str, unknown: &str) -> CString {
57 CString::new(x).unwrap_or({
58 unsafe {
59 Rf_warning(cstring!("safe string transformation failed, use unknown"));
60 }
61 CString::new(unknown).unwrap()
62 })
63}
64
65#[inline]
66pub fn derives_from(cl: SEXP, clazz: CString) -> bool {
67 unsafe {
68 if cl == R_NilValue {
69 return false;
70 }
71 let sstring = clazz;
72 if sstring == CStr::from_ptr(R_CHAR(STRING_ELT(cl, 0))).to_owned() {
74 return true;
75 }
76 let contains_sym = cstr_sym("contains");
77 let contains = Shield::new(R_do_slot(R_getClassDef(R_CHAR(Rf_asChar(cl))), contains_sym));
78 let res = Rf_getAttrib(contains.s(), R_NamesSymbol);
79 if res == R_NilValue {
80 return false;
81 }
82 for ii in 0..Rf_xlength(res) + 1 {
83
84 if CStr::from_ptr(R_CHAR(*VECTOR_PTR(res).offset(ii as isize))).to_owned() == sstring {
85 return true;
86 }
87 }
88 }
89 false
90}
91
92pub fn rprint<T: ToSEXP>(s: T) {
93 unsafe {
94 Rf_PrintValue(s.s());
95 }
96
97}