Skip to content

Commit

Permalink
fix: use new Rboolean enum instead
Browse files Browse the repository at this point in the history
  • Loading branch information
CGMossa committed Jan 28, 2024
1 parent 5ad76a9 commit c9a4cd6
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 70 deletions.
10 changes: 7 additions & 3 deletions extendr-api/src/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,10 +209,14 @@ pub fn blank_scalar_string() -> Robj {
pub fn parse(code: &str) -> Result<Expressions> {
single_threaded(|| unsafe {
use libR_sys::*;
let mut status = 0_u32;
let status_ptr = &mut status as _;
let mut status = ParseStatus_PARSE_NULL;
let codeobj: Robj = code.into();
let parsed = Robj::from_sexp(R_ParseVector(codeobj.get(), -1, status_ptr, R_NilValue));
let parsed = Robj::from_sexp(R_ParseVector(
codeobj.get(),
-1,
&mut status as *mut _,
R_NilValue,
));
match status {
1 => parsed.try_into(),
_ => Err(Error::ParseError(code.into())),
Expand Down
22 changes: 11 additions & 11 deletions extendr-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -482,17 +482,17 @@ pub unsafe fn register_call_methods(info: *mut libR_sys::DllInfo, metadata: Meta
});

single_threaded(|| {
libR_sys::R_registerRoutines(
info,
std::ptr::null(),
rmethods.as_ptr(),
std::ptr::null(),
std::ptr::null(),
);

// This seems to allow both symbols and strings,
libR_sys::R_useDynamicSymbols(info, 0);
libR_sys::R_forceSymbols(info, 0);
libR_sys::R_registerRoutines(
info,
std::ptr::null(),
rmethods.as_ptr(),
std::ptr::null(),
std::ptr::null(),
);

// This seems to allow both symbols and strings,
libR_sys::R_useDynamicSymbols(info, Rboolean::FALSE);
libR_sys::R_forceSymbols(info, Rboolean::FALSE);
})
}

Expand Down
2 changes: 1 addition & 1 deletion extendr-api/src/robj/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1068,7 +1068,7 @@ impl PartialEq<Robj> for Robj {
}

// see https://github.com/hadley/r-internals/blob/master/misc.md
R_compute_identical(self.get(), rhs.get(), 16) != 0
R_compute_identical(self.get(), rhs.get(), 16) != Rboolean::FALSE
}
}
}
Expand Down
70 changes: 37 additions & 33 deletions extendr-api/src/robj/rinternals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,37 +7,37 @@ use std::os::raw;
pub trait Rinternals: Types + Conversions {
/// Return true if this is the null object.
fn is_null(&self) -> bool {
unsafe { Rf_isNull(self.get()) == Rboolean_TRUE }
unsafe { Rf_isNull(self.get()) == Rboolean::TRUE }
}

/// Return `true` if this is a symbol.
fn is_symbol(&self) -> bool {
unsafe { Rf_isSymbol(self.get()) == Rboolean_TRUE }
unsafe { Rf_isSymbol(self.get()) == Rboolean::TRUE }
}

/// Return `true` if this is a boolean (`logical`) vector
fn is_logical(&self) -> bool {
unsafe { Rf_isLogical(self.get()) == Rboolean_TRUE }
unsafe { Rf_isLogical(self.get()) == Rboolean::TRUE }
}

/// Return `true` if this is a real (`f64`) vector.
fn is_real(&self) -> bool {
unsafe { Rf_isReal(self.get()) == Rboolean_TRUE }
unsafe { Rf_isReal(self.get()) == Rboolean::TRUE }
}

/// Return `true` if this is a complex vector.
fn is_complex(&self) -> bool {
unsafe { Rf_isComplex(self.get()) == Rboolean_TRUE }
unsafe { Rf_isComplex(self.get()) == Rboolean::TRUE }
}

/// Return `true` if this is an expression.
fn is_expressions(&self) -> bool {
unsafe { Rf_isExpression(self.get()) == Rboolean_TRUE }
unsafe { Rf_isExpression(self.get()) == Rboolean::TRUE }
}

/// Return `true` if this is an environment.
fn is_environment(&self) -> bool {
unsafe { Rf_isEnvironment(self.get()) == Rboolean_TRUE }
unsafe { Rf_isEnvironment(self.get()) == Rboolean::TRUE }
}

/// Return `true` if this is an environment.
Expand All @@ -47,17 +47,21 @@ pub trait Rinternals: Types + Conversions {

/// Return `true` if this is a string.
fn is_string(&self) -> bool {
unsafe { Rf_isString(self.get()) == Rboolean_TRUE }
unsafe { Rf_isString(self.get()) == Rboolean::TRUE }
}

/// Return `true` if this is an object (ie. has a class attribute).
fn is_object(&self) -> bool {
unsafe { Rf_isObject(self.get()) == Rboolean_TRUE }
unsafe { Rf_isObject(self.get()) == Rboolean::TRUE }
}

/// Return `true` if this is a S4 object.
fn is_s4(&self) -> bool {
unsafe { Rf_isS4(self.get()) == Rboolean_TRUE }
unsafe {
// calls IS_S4_OBJECT, returns 16 instead of 1..
Rf_isS4(self.get()) != Rboolean::FALSE
// unsafe { Rf_isS4(self.get()) == Rboolean_TRUE }
}
}

/// Return `true` if this is an expression.
Expand Down Expand Up @@ -274,7 +278,7 @@ pub trait Rinternals: Types + Conversions {
unsafe fn register_c_finalizer(&self, func: R_CFinalizer_t) {
// Use R_RegisterCFinalizerEx() and set onexit to 1 (TRUE) to invoke the
// finalizer on a shutdown of the R session as well.
single_threaded(|| R_RegisterCFinalizerEx(self.get(), func, 1));
single_threaded(|| R_RegisterCFinalizerEx(self.get(), func, Rboolean::TRUE));
}

/// Copy a vector and resize it.
Expand All @@ -298,102 +302,102 @@ pub trait Rinternals: Types + Conversions {

/// Return `true` if two arrays have identical dims.
fn conformable(a: &Robj, b: &Robj) -> bool {
single_threaded(|| unsafe { Rf_conformable(a.get(), b.get()) == Rboolean_TRUE })
single_threaded(|| unsafe { Rf_conformable(a.get(), b.get()) == Rboolean::TRUE })
}

/// Return `true` if this is an array.
fn is_array(&self) -> bool {
unsafe { Rf_isArray(self.get()) == Rboolean_TRUE }
unsafe { Rf_isArray(self.get()) == Rboolean::TRUE }
}

/// Return `true` if this is factor.
fn is_factor(&self) -> bool {
unsafe { Rf_isFactor(self.get()) == Rboolean_TRUE }
unsafe { Rf_isFactor(self.get()) == Rboolean::TRUE }
}

/// Return `true` if this is a data frame.
fn is_frame(&self) -> bool {
unsafe { Rf_isFrame(self.get()) == Rboolean_TRUE }
unsafe { Rf_isFrame(self.get()) == Rboolean::TRUE }
}

/// Return `true` if this is a function or a primitive (`CLOSXP`, `BUILTINSXP` or `SPECIALSXP`)
fn is_function(&self) -> bool {
unsafe { Rf_isFunction(self.get()) == Rboolean_TRUE }
unsafe { Rf_isFunction(self.get()) == Rboolean::TRUE }
}

/// Return `true` if this is an integer vector (`INTSXP`) but not a factor.
fn is_integer(&self) -> bool {
unsafe { Rf_isInteger(self.get()) == Rboolean_TRUE }
unsafe { Rf_isInteger(self.get()) == Rboolean::TRUE }
}

/// Return `true` if this is a language object (`LANGSXP`).
fn is_language(&self) -> bool {
unsafe { Rf_isLanguage(self.get()) == Rboolean_TRUE }
unsafe { Rf_isLanguage(self.get()) == Rboolean::TRUE }
}

/// Return `true` if this is `NILSXP` or `LISTSXP`.
fn is_pairlist(&self) -> bool {
unsafe { Rf_isList(self.get()) == Rboolean_TRUE }
unsafe { Rf_isList(self.get()) == Rboolean::TRUE }
}

/// Return `true` if this is a matrix.
fn is_matrix(&self) -> bool {
unsafe { Rf_isMatrix(self.get()) == Rboolean_TRUE }
unsafe { Rf_isMatrix(self.get()) == Rboolean::TRUE }
}

/// Return `true` if this is `NILSXP` or `VECSXP`.
fn is_list(&self) -> bool {
unsafe { Rf_isNewList(self.get()) == Rboolean_TRUE }
unsafe { Rf_isNewList(self.get()) == Rboolean::TRUE }
}

/// Return `true` if this is `INTSXP`, `LGLSXP` or `REALSXP` but not a factor.
fn is_number(&self) -> bool {
unsafe { Rf_isNumber(self.get()) == Rboolean_TRUE }
unsafe { Rf_isNumber(self.get()) == Rboolean::TRUE }
}

/// Return `true` if this is a primitive function `BUILTINSXP`, `SPECIALSXP`.
fn is_primitive(&self) -> bool {
unsafe { Rf_isPrimitive(self.get()) == Rboolean_TRUE }
unsafe { Rf_isPrimitive(self.get()) == Rboolean::TRUE }
}

/// Return `true` if this is a time series vector (see tsp).
fn is_ts(&self) -> bool {
unsafe { Rf_isTs(self.get()) == Rboolean_TRUE }
unsafe { Rf_isTs(self.get()) == Rboolean::TRUE }
}

/// Return `true` if this is a user defined binop.
fn is_user_binop(&self) -> bool {
unsafe { Rf_isUserBinop(self.get()) == Rboolean_TRUE }
unsafe { Rf_isUserBinop(self.get()) == Rboolean::TRUE }
}

/// Return `true` if this is a valid string.
fn is_valid_string(&self) -> bool {
unsafe { Rf_isValidString(self.get()) == Rboolean_TRUE }
unsafe { Rf_isValidString(self.get()) == Rboolean::TRUE }
}

/// Return `true` if this is a valid string.
fn is_valid_string_f(&self) -> bool {
unsafe { Rf_isValidStringF(self.get()) == Rboolean_TRUE }
unsafe { Rf_isValidStringF(self.get()) == Rboolean::TRUE }
}

/// Return `true` if this is a vector.
fn is_vector(&self) -> bool {
unsafe { Rf_isVector(self.get()) == Rboolean_TRUE }
unsafe { Rf_isVector(self.get()) == Rboolean::TRUE }
}

/// Return `true` if this is an atomic vector.
fn is_vector_atomic(&self) -> bool {
unsafe { Rf_isVectorAtomic(self.get()) == Rboolean_TRUE }
unsafe { Rf_isVectorAtomic(self.get()) == Rboolean::TRUE }
}

/// Return `true` if this is a vector list.
fn is_vector_list(&self) -> bool {
unsafe { Rf_isVectorList(self.get()) == Rboolean_TRUE }
unsafe { Rf_isVectorList(self.get()) == Rboolean::TRUE }
}

/// Return `true` if this is can be made into a vector.
fn is_vectorizable(&self) -> bool {
unsafe { Rf_isVectorizable(self.get()) == Rboolean_TRUE }
unsafe { Rf_isVectorizable(self.get()) == Rboolean::TRUE }
}

/// Return `true` if this is RAWSXP.
Expand Down Expand Up @@ -428,15 +432,15 @@ pub trait Rinternals: Types + Conversions {
}

fn is_package_env(&self) -> bool {
unsafe { R_IsPackageEnv(self.get()) == Rboolean_TRUE }
unsafe { R_IsPackageEnv(self.get()) == Rboolean::TRUE }
}

fn package_env_name(&self) -> Robj {
unsafe { Robj::from_sexp(R_PackageEnvName(self.get())) }
}

fn is_namespace_env(&self) -> bool {
unsafe { R_IsNamespaceEnv(self.get()) == Rboolean_TRUE }
unsafe { R_IsNamespaceEnv(self.get()) == Rboolean::TRUE }
}

fn namespace_env_spec(&self) -> Robj {
Expand Down
4 changes: 2 additions & 2 deletions extendr-api/src/thread_safety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ pub fn throw_r_error<S: AsRef<str>>(s: S) -> ! {
let s = s.as_ref();
unsafe {
R_ERROR_BUF = Some(std::ffi::CString::new(s).unwrap());
libR_sys::Rf_error(R_ERROR_BUF.as_ref().unwrap().as_ptr());
libR_sys::Rf_error(R_ERROR_BUF.as_ref().unwrap().as_ptr())
};
}

Expand Down Expand Up @@ -78,7 +78,7 @@ where
}

unsafe extern "C" fn do_cleanup(_: *mut raw::c_void, jump: Rboolean) {
if jump != 0 {
if jump != Rboolean::FALSE {
panic!("R has thrown an error.");
}
}
Expand Down
Loading

0 comments on commit c9a4cd6

Please sign in to comment.