Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -642,7 +642,7 @@ references:
title: graph
abstract: 'graph: graph: A package to handle graph data structures'
notes: Enhances
repository: https://bioconductor.org/
repository: https://bioc-release.r-universe.dev
authors:
- family-names: Gentleman
given-names: R
Expand All @@ -657,7 +657,6 @@ references:
- family-names: Shannon
given-names: Paul
year: '2026'
doi: 10.18129/B9.bioc.graph
- type: software
title: cpp11
abstract: 'cpp11: A C++11 Interface for R''s C Interface'
Expand Down
153 changes: 55 additions & 98 deletions src/rinterface_extra.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,22 @@ enum igraph_versions {

#define R_IGRAPH_VERSION_VAR ".__igraph_version__."

#if R_VERSION >= R_Version(4, 5, 0)
# define IGRAPH_R_GET_VAR(sym, env, inherits) \
R_getVar((sym), (env), (inherits))
# define IGRAPH_R_GET_VAR_EX(sym, env, inherits, ifnotfound) \
R_getVarEx((sym), (env), (inherits), (ifnotfound))
#else
static inline SEXP IGRAPH_R_GET_VAR(SEXP sym, SEXP env, Rboolean inherits) {
return inherits ? Rf_findVar(sym, env) : Rf_findVarInFrame(env, sym);
}

static inline SEXP IGRAPH_R_GET_VAR_EX(SEXP sym, SEXP env, Rboolean inherits, SEXP ifnotfound) {
SEXP val = IGRAPH_R_GET_VAR(sym, env, inherits);
return val == R_UnboundValue ? ifnotfound : val;
}
#endif

/* The following three R_check_... functions must only be called from top-level C code,
* i.e. in contexts where igraph_error() does NOT return. */

Expand Down Expand Up @@ -238,14 +254,7 @@ Rx_igraph_safe_eval_result_t Rx_igraph_safe_eval_classify_result(SEXP result) {
SEXP Rx_igraph_safe_eval_in_env(SEXP expr_call, SEXP rho, Rx_igraph_safe_eval_result_t* result) {
/* find `identity` function used to capture errors */
SEXP identity = PROTECT(Rf_install("identity"));
#if R_VERSION >= R_Version(4, 6, 0)
SEXP identity_func = PROTECT(R_getVar(identity, R_BaseNamespace, TRUE));
#else
SEXP identity_func = PROTECT(Rf_findFun(identity, R_BaseNamespace));
if (identity_func == R_UnboundValue) {
Rf_error("Failed to find 'base::identity()'");
}
#endif

/* define the call -- enclose with `tryCatch` so we can record errors */
SEXP try_catch = PROTECT(Rf_install("tryCatch"));
Expand Down Expand Up @@ -2415,55 +2424,39 @@ igraph_error_t Rx_igraph_progress_handler(const char *message, double percent,
void * data) {
SEXP ec;
int ecint;
int px = 0;
SEXP rho;
#if R_VERSION >= R_Version(4, 6, 0)
rho = R_getRegisteredNamespace("igraph");
#else
SEXP l1 = PROTECT(Rf_install("getNamespace")); px++;
SEXP l2 = PROTECT(Rf_ScalarString(PROTECT(Rf_mkChar("igraph")))); px += 2;
SEXP l3 = PROTECT(Rf_lang2(l1, l2)); px++;
rho = PROTECT(Rf_eval(l3, R_BaseEnv)); px++;
#endif
SEXP l1 = PROTECT(Rf_install("getNamespace"));
SEXP l2 = PROTECT(Rf_ScalarString(PROTECT(Rf_mkChar("igraph"))));
SEXP l3 = PROTECT(Rf_lang2(l1, l2));
SEXP rho = PROTECT(Rf_eval(l3, R_BaseEnv));

SEXP l4 = PROTECT(Rf_install(".igraph.progress")); px++;
SEXP l5 = PROTECT(Rf_ScalarReal(percent)); px++;
SEXP l6 = PROTECT(Rf_ScalarString(PROTECT(Rf_mkChar(message)))); px += 2;
SEXP l7 = PROTECT(Rf_lang3(l4, l5, l6)); px++;
PROTECT(ec=Rf_eval(l7, rho)); px++;
SEXP l4 = PROTECT(Rf_install(".igraph.progress"));
SEXP l5 = PROTECT(Rf_ScalarReal(percent));
SEXP l6 = PROTECT(Rf_ScalarString(PROTECT(Rf_mkChar(message))));
SEXP l7 = PROTECT(Rf_lang3(l4, l5, l6));
PROTECT(ec=Rf_eval(l7, rho));

ecint=INTEGER(ec)[0];
UNPROTECT(px);
UNPROTECT(11);
return ecint;
}

igraph_error_t Rx_igraph_status_handler(const char *message, void *data) {
int px = 0;
SEXP rho;
#if R_VERSION >= R_Version(4, 6, 0)
rho = R_getRegisteredNamespace("igraph");
#else
SEXP l1 = PROTECT(Rf_install("getNamespace")); px++;
SEXP l2 = PROTECT(Rf_ScalarString(PROTECT(Rf_mkChar("igraph")))); px += 2;
SEXP l3 = PROTECT(Rf_lang2(l1, l2)); px++;
rho = PROTECT(Rf_eval(l3, R_BaseEnv)); px++;
#endif
SEXP l1 = PROTECT(Rf_install("getNamespace"));
SEXP l2 = PROTECT(Rf_ScalarString(PROTECT(Rf_mkChar("igraph"))));
SEXP l3 = PROTECT(Rf_lang2(l1, l2));
SEXP rho = PROTECT(Rf_eval(l3, R_BaseEnv));

SEXP l4 = PROTECT(Rf_install(".igraph.status")); px++;
SEXP l5 = PROTECT(Rf_ScalarString(PROTECT(Rf_mkChar(message)))); px += 2;
SEXP l6 = PROTECT(Rf_lang2(l4, l5)); px++;
PROTECT(Rf_eval(l6, rho)); px++;
SEXP l4 = PROTECT(Rf_install(".igraph.status"));
SEXP l5 = PROTECT(Rf_ScalarString(PROTECT(Rf_mkChar(message))));
SEXP l6 = PROTECT(Rf_lang2(l4, l5));
PROTECT(Rf_eval(l6, rho));

UNPROTECT(px);
UNPROTECT(10);
return 0;
}

static R_xlen_t Rx_igraph_altrep_length(SEXP vec) {
#if R_VERSION >= R_Version(4, 6, 0)
SEXP xp=R_getVar(Rf_install("igraph"), R_altrep_data1(vec), TRUE);
#else
SEXP xp=Rf_findVar(Rf_install("igraph"), R_altrep_data1(vec));
#endif
SEXP xp=IGRAPH_R_GET_VAR(Rf_install("igraph"), R_altrep_data1(vec), TRUE);
igraph_t *g=(igraph_t*)(R_ExternalPtrAddr(xp));
return igraph_ecount(g);
}
Expand All @@ -2472,11 +2465,7 @@ static void *Rx_igraph_altrep_from(SEXP vec, Rboolean writeable) {
SEXP data=R_altrep_data2(vec);
if (data == R_NilValue) {
Rx_igraph_status_handler("Materializing 'from' vector.\n", NULL);
#if R_VERSION >= R_Version(4, 6, 0)
SEXP xp=R_getVar(Rf_install("igraph"), R_altrep_data1(vec), TRUE);
#else
SEXP xp=Rf_findVar(Rf_install("igraph"), R_altrep_data1(vec));
#endif
SEXP xp=IGRAPH_R_GET_VAR(Rf_install("igraph"), R_altrep_data1(vec), TRUE);
igraph_t *g=(igraph_t*)(R_ExternalPtrAddr(xp));

data=Ry_igraph_vector_int_to_SEXP(&g->from);
Expand All @@ -2491,11 +2480,7 @@ static void *Rx_igraph_altrep_to(SEXP vec, Rboolean writeable) {
if (data == R_NilValue) {
Rx_igraph_status_handler("Materializing 'to' vector.\n", NULL);

#if R_VERSION >= R_Version(4, 6, 0)
SEXP xp=R_getVar(Rf_install("igraph"), R_altrep_data1(vec), TRUE);
#else
SEXP xp=Rf_findVar(Rf_install("igraph"), R_altrep_data1(vec));
#endif
SEXP xp=IGRAPH_R_GET_VAR(Rf_install("igraph"), R_altrep_data1(vec), TRUE);
igraph_t *g=(igraph_t*)(R_ExternalPtrAddr(xp));

data=Ry_igraph_vector_int_to_SEXP(&g->to);
Expand Down Expand Up @@ -2542,24 +2527,18 @@ SEXP Rx_igraph_set_verbose(SEXP verbose) {

SEXP R_igraph_finalizer(void) {
IGRAPH_FINALLY_FREE();
int px = 0;
SEXP rho;
#if R_VERSION >= R_Version(4, 6, 0)
rho = R_getRegisteredNamespace("igraph");
#else
SEXP l1 = PROTECT(Rf_install("getNamespace")); px++;
SEXP l2 = PROTECT(Rf_ScalarString(PROTECT(Rf_mkChar("igraph")))); px += 2;
SEXP l3 = PROTECT(Rf_lang2(l1, l2)); px++;
rho = PROTECT(Rf_eval(l3, R_BaseEnv)); px++;
#endif

SEXP l4 = PROTECT(Rf_install(".igraph.progress")); px++;
SEXP l5 = PROTECT(Rf_ScalarReal(0.0)); px++;
SEXP l6 = PROTECT(Rf_ScalarString(PROTECT(Rf_mkChar("")))); px += 2;
SEXP l7 = PROTECT(Rf_ScalarLogical(1)); px++;
SEXP l8 = PROTECT(Rf_lang4(l4, l5, l6, l7)); px++;
SEXP l1 = PROTECT(Rf_install("getNamespace"));
SEXP l2 = PROTECT(Rf_ScalarString(PROTECT(Rf_mkChar("igraph"))));
SEXP l3 = PROTECT(Rf_lang2(l1, l2));
SEXP rho = PROTECT(Rf_eval(l3, R_BaseEnv));

SEXP l4 = PROTECT(Rf_install(".igraph.progress"));
SEXP l5 = PROTECT(Rf_ScalarReal(0.0));
SEXP l6 = PROTECT(Rf_ScalarString(PROTECT(Rf_mkChar(""))));
SEXP l7 = PROTECT(Rf_ScalarLogical(1));
SEXP l8 = PROTECT(Rf_lang4(l4, l5, l6, l7));
Rf_eval(l8, rho);
UNPROTECT(px);
UNPROTECT(11);
return R_NilValue;
}

Expand Down Expand Up @@ -2907,29 +2886,17 @@ igraph_t *Rx_igraph_get_pointer(SEXP graph) {
Rf_error("This graph was created by a now unsupported old igraph version.\n Call upgrade_graph() before using igraph functions on that object.");
}

#if R_VERSION >= R_Version(4, 6, 0)
SEXP xp=R_getVarEx(Rf_install("igraph"), Rx_igraph_graph_env(graph), TRUE, R_NilValue);
SEXP xp=IGRAPH_R_GET_VAR_EX(Rf_install("igraph"), Rx_igraph_graph_env(graph), TRUE, R_NilValue);
if (xp == R_NilValue) {
Rx_igraph_restore_pointer(graph);
xp=R_getVarEx(Rf_install("igraph"), Rx_igraph_graph_env(graph), TRUE, R_NilValue);
}
#else
SEXP xp=Rf_findVar(Rf_install("igraph"), Rx_igraph_graph_env(graph));
if (xp == R_UnboundValue || xp == R_NilValue) {
Rx_igraph_restore_pointer(graph);
xp=Rf_findVar(Rf_install("igraph"), Rx_igraph_graph_env(graph));
xp=IGRAPH_R_GET_VAR_EX(Rf_install("igraph"), Rx_igraph_graph_env(graph), TRUE, R_NilValue);
}
#endif

igraph_t *pgraph=(igraph_t*)(R_ExternalPtrAddr(xp));

if (!pgraph) {
Rx_igraph_restore_pointer(graph);
#if R_VERSION >= R_Version(4, 6, 0)
xp=R_getVarEx(Rf_install("igraph"), Rx_igraph_graph_env(graph), TRUE, R_NilValue);
#else
xp=Rf_findVar(Rf_install("igraph"), Rx_igraph_graph_env(graph));
#endif
xp=IGRAPH_R_GET_VAR_EX(Rf_install("igraph"), Rx_igraph_graph_env(graph), TRUE, R_NilValue);
pgraph=(igraph_t*)(R_ExternalPtrAddr(xp));
}

Expand Down Expand Up @@ -7753,17 +7720,10 @@ SEXP Rx_igraph_graph_version(SEXP graph) {
return Rf_ScalarInteger(ver_0_4);
}

#if R_VERSION >= R_Version(4, 6, 0)
SEXP ver = R_getVarEx(Rf_install(R_IGRAPH_VERSION_VAR), Rx_igraph_graph_env(graph), TRUE, R_NilValue);
SEXP ver = IGRAPH_R_GET_VAR_EX(Rf_install(R_IGRAPH_VERSION_VAR), Rx_igraph_graph_env(graph), TRUE, R_NilValue);
if (ver == R_NilValue) {
return Rf_ScalarInteger(ver_0_7_999);
}
#else
SEXP ver = Rf_findVar(Rf_install(R_IGRAPH_VERSION_VAR), Rx_igraph_graph_env(graph));
if (ver == R_UnboundValue) {
return Rf_ScalarInteger(ver_0_7_999);
}
#endif

if (TYPEOF(ver) == STRSXP) {
return Rf_ScalarInteger(ver_0_8);
Expand Down Expand Up @@ -7797,6 +7757,7 @@ SEXP Rx_igraph_add_version_to_env(SEXP graph) {

SEXP Rx_igraph_add_env(SEXP graph) {
SEXP result = graph;
R_xlen_t i;
uuid_t my_id;
char my_id_chr[40];
int px = 0;
Expand Down Expand Up @@ -7831,11 +7792,7 @@ SEXP Rx_igraph_add_env(SEXP graph) {
}

SEXP Rx_igraph_get_graph_id(SEXP graph) {
#if R_VERSION >= R_Version(4, 6, 0)
return R_getVar(Rf_install("myid"), Rx_igraph_graph_env(graph), TRUE);
#else
return Rf_findVar(Rf_install("myid"), Rx_igraph_graph_env(graph));
#endif
return IGRAPH_R_GET_VAR(Rf_install("myid"), Rx_igraph_graph_env(graph), TRUE);
}

// Wrapper functions for functions not in aaa-auto.R
Expand Down
Loading