diff --git a/CITATION.cff b/CITATION.cff index 4441d4fea83..def24639c31 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -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 @@ -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' diff --git a/src/rinterface_extra.c b/src/rinterface_extra.c index 31db78a46e4..374a990cb64 100644 --- a/src/rinterface_extra.c +++ b/src/rinterface_extra.c @@ -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. */ @@ -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")); @@ -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); } @@ -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); @@ -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); @@ -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; } @@ -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)); } @@ -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); @@ -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; @@ -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