savvy_ffi/
lib.rs

1#![allow(non_upper_case_globals)]
2#![allow(non_camel_case_types)]
3#![allow(non_snake_case)]
4
5#[cfg(feature = "altrep")]
6pub mod altrep;
7
8// internal types
9
10pub type R_xlen_t = isize;
11
12pub const Rboolean_FALSE: Rboolean = 0;
13pub const Rboolean_TRUE: Rboolean = 1;
14pub type Rboolean = ::std::os::raw::c_int;
15
16#[cfg(feature = "complex")]
17pub use num_complex::Complex64;
18
19// SEXP
20pub type SEXP = *mut ::std::os::raw::c_void;
21
22// SEXPTYPE
23
24pub type SEXPTYPE = ::std::os::raw::c_uint;
25
26pub const NILSXP: SEXPTYPE = 0;
27pub const SYMSXP: SEXPTYPE = 1;
28pub const LISTSXP: SEXPTYPE = 2;
29pub const CLOSXP: SEXPTYPE = 3;
30pub const ENVSXP: SEXPTYPE = 4;
31pub const PROMSXP: SEXPTYPE = 5;
32pub const LANGSXP: SEXPTYPE = 6;
33pub const SPECIALSXP: SEXPTYPE = 7;
34pub const BUILTINSXP: SEXPTYPE = 8;
35pub const CHARSXP: SEXPTYPE = 9;
36pub const LGLSXP: SEXPTYPE = 10;
37pub const INTSXP: SEXPTYPE = 13;
38pub const REALSXP: SEXPTYPE = 14;
39pub const CPLXSXP: SEXPTYPE = 15;
40pub const STRSXP: SEXPTYPE = 16;
41pub const DOTSXP: SEXPTYPE = 17;
42pub const ANYSXP: SEXPTYPE = 18;
43pub const VECSXP: SEXPTYPE = 19;
44pub const EXPRSXP: SEXPTYPE = 20;
45pub const BCODESXP: SEXPTYPE = 21;
46pub const EXTPTRSXP: SEXPTYPE = 22;
47pub const WEAKREFSXP: SEXPTYPE = 23;
48pub const RAWSXP: SEXPTYPE = 24;
49pub const OBJSXP: SEXPTYPE = 25;
50
51// pre-defined symbols
52extern "C" {
53    pub static mut R_NamesSymbol: SEXP;
54    pub static mut R_ClassSymbol: SEXP;
55    pub static mut R_DimSymbol: SEXP;
56}
57
58// NULL
59extern "C" {
60    pub static mut R_NilValue: SEXP;
61}
62
63// NA
64extern "C" {
65    pub static mut R_NaInt: ::std::os::raw::c_int;
66    pub static mut R_NaReal: f64;
67    pub static mut R_NaString: SEXP;
68
69    pub fn R_IsNA(arg1: f64) -> ::std::os::raw::c_int;
70}
71
72// Allocation and attributes
73extern "C" {
74    pub fn Rf_xlength(arg1: SEXP) -> R_xlen_t;
75    pub fn Rf_allocVector(arg1: SEXPTYPE, arg2: R_xlen_t) -> SEXP;
76    pub fn Rf_getAttrib(arg1: SEXP, arg2: SEXP) -> SEXP;
77    pub fn Rf_setAttrib(arg1: SEXP, arg2: SEXP, arg3: SEXP) -> SEXP;
78}
79
80// Symbol
81extern "C" {
82    pub fn Rf_install(arg1: *const ::std::os::raw::c_char) -> SEXP;
83    pub fn PRINTNAME(x: SEXP) -> SEXP;
84}
85
86// Integer
87extern "C" {
88    pub fn INTEGER(x: SEXP) -> *mut ::std::os::raw::c_int;
89    pub fn INTEGER_RO(x: SEXP) -> *const ::std::os::raw::c_int;
90    pub fn INTEGER_ELT(x: SEXP, i: R_xlen_t) -> ::std::os::raw::c_int;
91    pub fn SET_INTEGER_ELT(x: SEXP, i: R_xlen_t, v: ::std::os::raw::c_int);
92    pub fn Rf_ScalarInteger(arg1: ::std::os::raw::c_int) -> SEXP;
93    pub fn Rf_isInteger(arg1: SEXP) -> Rboolean;
94}
95
96// Real
97extern "C" {
98    pub fn REAL(x: SEXP) -> *mut f64;
99    pub fn REAL_RO(x: SEXP) -> *const f64;
100    pub fn REAL_ELT(x: SEXP, i: R_xlen_t) -> f64;
101    pub fn SET_REAL_ELT(x: SEXP, i: R_xlen_t, v: f64);
102    pub fn Rf_ScalarReal(arg1: f64) -> SEXP;
103    pub fn Rf_isReal(s: SEXP) -> Rboolean;
104}
105
106// Raw
107//
108// According to the doc[1], c_uchar is simply u8 unlike the complexity of
109// c_char.
110//
111// [1]: https://doc.rust-lang.org/stable/core/ffi/type.c_uchar.html
112extern "C" {
113    pub fn RAW(x: SEXP) -> *mut u8;
114    pub fn RAW_RO(x: SEXP) -> *const u8;
115    pub fn RAW_ELT(x: SEXP, i: R_xlen_t) -> u8;
116    pub fn SET_RAW_ELT(x: SEXP, i: R_xlen_t, v: u8);
117    pub fn Rf_ScalarRaw(arg1: u8) -> SEXP;
118
119    // There's no `Rf_isRaw`.`
120}
121
122// Numeric
123extern "C" {
124    pub fn Rf_isNumeric(arg1: SEXP) -> Rboolean;
125}
126
127// Complex
128//
129// Since the representation of Rcomplex matches num_complex's Compplex64, use it
130// directly. Note that num-complex's docment warns as following and this seems
131// the case of passing as a value.
132//
133//     Note that `Complex<F>` where `F` is a floating point type is **only**
134//     memory layout compatible with C’s complex types, **not** necessarily
135//     calling convention compatible. This means that for FFI you can only pass
136//     `Complex<F>` behind a pointer, not as a value.
137//     (https://docs.rs/num-complex/latest/num_complex/struct.Complex.html#representation-and-foreign-function-interface-compatibility)
138//
139// While it's true it's not guaranteed to be safe, in actual, no problem has
140// benn found so far, and it's a common attitude to ignore the unsafety.
141//
142// cf. https://gitlab.com/petsc/petsc-rs/-/issues/1
143#[cfg(feature = "complex")]
144extern "C" {
145    pub fn COMPLEX(x: SEXP) -> *mut num_complex::Complex64;
146    pub fn COMPLEX_RO(x: SEXP) -> *mut num_complex::Complex64;
147    pub fn COMPLEX_ELT(x: SEXP, i: R_xlen_t) -> num_complex::Complex64;
148    pub fn SET_COMPLEX_ELT(x: SEXP, i: R_xlen_t, v: num_complex::Complex64);
149    pub fn Rf_ScalarComplex(arg1: num_complex::Complex64) -> SEXP;
150    pub fn Rf_isComplex(s: SEXP) -> Rboolean;
151}
152
153// Logical
154extern "C" {
155    pub fn LOGICAL(x: SEXP) -> *mut ::std::os::raw::c_int;
156    pub fn LOGICAL_RO(x: SEXP) -> *const ::std::os::raw::c_int;
157    pub fn LOGICAL_ELT(x: SEXP, i: R_xlen_t) -> ::std::os::raw::c_int;
158    pub fn SET_LOGICAL_ELT(x: SEXP, i: R_xlen_t, v: ::std::os::raw::c_int);
159    pub fn Rf_ScalarLogical(arg1: ::std::os::raw::c_int) -> SEXP;
160    pub fn Rf_isLogical(s: SEXP) -> Rboolean;
161}
162
163// String and character
164
165pub const cetype_t_CE_NATIVE: cetype_t = 0;
166pub const cetype_t_CE_UTF8: cetype_t = 1;
167pub const cetype_t_CE_LATIN1: cetype_t = 2;
168pub const cetype_t_CE_BYTES: cetype_t = 3;
169pub const cetype_t_CE_SYMBOL: cetype_t = 5;
170pub const cetype_t_CE_ANY: cetype_t = 99;
171pub type cetype_t = ::std::os::raw::c_int;
172
173extern "C" {
174    pub fn STRING_PTR_RO(x: SEXP) -> *const SEXP;
175    pub fn STRING_ELT(x: SEXP, i: R_xlen_t) -> SEXP;
176    pub fn SET_STRING_ELT(x: SEXP, i: R_xlen_t, v: SEXP);
177    pub fn Rf_ScalarString(arg1: SEXP) -> SEXP;
178    pub fn Rf_isString(s: SEXP) -> Rboolean;
179
180    pub fn R_CHAR(x: SEXP) -> *const ::std::os::raw::c_char;
181    pub fn Rf_mkCharLenCE(
182        arg1: *const ::std::os::raw::c_char,
183        arg2: ::std::os::raw::c_int,
184        arg3: cetype_t,
185    ) -> SEXP;
186}
187
188// List
189extern "C" {
190    pub fn DATAPTR_RO(x: SEXP) -> *const ::std::os::raw::c_void; // TODO: replace this to VECTOR_PTR_RO()
191    pub fn VECTOR_ELT(x: SEXP, i: R_xlen_t) -> SEXP;
192    pub fn SET_VECTOR_ELT(x: SEXP, i: R_xlen_t, v: SEXP) -> SEXP;
193}
194
195// External pointer
196
197pub type R_CFinalizer_t = Option<unsafe extern "C" fn(arg1: SEXP)>;
198extern "C" {
199    pub fn R_MakeExternalPtr(p: *mut ::std::os::raw::c_void, tag: SEXP, prot: SEXP) -> SEXP;
200    pub fn R_ExternalPtrAddr(s: SEXP) -> *mut ::std::os::raw::c_void;
201    pub fn R_ClearExternalPtr(s: SEXP);
202
203    pub fn R_RegisterCFinalizerEx(s: SEXP, fun: R_CFinalizer_t, onexit: Rboolean);
204}
205
206// Pairlist
207extern "C" {
208    pub fn Rf_cons(arg1: SEXP, arg2: SEXP) -> SEXP;
209    pub fn Rf_lcons(arg1: SEXP, arg2: SEXP) -> SEXP;
210    pub fn CAR(e: SEXP) -> SEXP;
211    pub fn CDR(e: SEXP) -> SEXP;
212    pub fn CADR(e: SEXP) -> SEXP;
213    pub fn SETCAR(x: SEXP, y: SEXP) -> SEXP;
214    pub fn SETCDR(x: SEXP, y: SEXP) -> SEXP;
215    pub fn SET_TAG(x: SEXP, y: SEXP);
216    pub fn ATTRIB(x: SEXP) -> SEXP;
217}
218
219// Function and environment
220extern "C" {
221    pub fn Rf_isFunction(arg1: SEXP) -> Rboolean;
222    pub fn Rf_isEnvironment(arg1: SEXP) -> Rboolean;
223    pub fn Rf_eval(arg1: SEXP, arg2: SEXP) -> SEXP;
224    pub fn Rf_defineVar(arg1: SEXP, arg2: SEXP, arg3: SEXP);
225    pub fn R_existsVarInFrame(arg1: SEXP, arg2: SEXP) -> Rboolean;
226
227    pub static mut R_GlobalEnv: SEXP;
228    pub static mut R_UnboundValue: SEXP;
229}
230
231// Parse
232extern "C" {
233    pub fn R_ParseEvalString(arg1: *const ::std::os::raw::c_char, arg2: SEXP) -> SEXP;
234    pub fn R_compute_identical(arg1: SEXP, arg2: SEXP, arg3: ::std::os::raw::c_int) -> Rboolean;
235}
236
237// Protection
238extern "C" {
239    pub fn Rf_protect(arg1: SEXP) -> SEXP;
240    pub fn Rf_unprotect(arg1: ::std::os::raw::c_int);
241    pub fn R_PreserveObject(arg1: SEXP);
242}
243
244// Type
245extern "C" {
246    // Note: For some reason, the return type of TYPEOF() is defined as int in
247    // RInternals.h and memory.c. However, the actual implementation is
248    //
249    // In memory.c:
250    //
251    //     int (TYPEOF)(SEXP x) { return TYPEOF(CHK(x)); }
252    //
253    // In Defn.h:
254    //
255    //     #define TYPEOF(x)    ((x)->sxpinfo.type)
256    //
257    // and the definition of the `type` field of `sxpinfo_struct` is `SEXPTYPE`,
258    // so the actual return type should be `SEXPTYPE`, while I'm not 100% sure...
259    pub fn TYPEOF(x: SEXP) -> SEXPTYPE;
260    pub fn Rf_type2char(arg1: SEXPTYPE) -> *const ::std::os::raw::c_char;
261}
262
263// Error
264extern "C" {
265    pub fn Rf_errorcall(arg1: SEXP, arg2: *const ::std::os::raw::c_char, ...) -> !;
266    pub fn Rf_warningcall(arg1: SEXP, arg2: *const ::std::os::raw::c_char, ...);
267}
268
269// I/O
270extern "C" {
271    pub fn Rprintf(arg1: *const ::std::os::raw::c_char, ...);
272    pub fn REprintf(arg1: *const ::std::os::raw::c_char, ...);
273}
274
275// misc
276pub type DllInfo = *mut ::std::os::raw::c_void;
277extern "C" {
278    pub fn Rf_coerceVector(arg1: SEXP, arg2: SEXPTYPE) -> SEXP;
279    pub fn Rf_duplicate(arg1: SEXP) -> SEXP;
280}