From 82587dc1ccc203fe3f65e4e133eb66f5fbd917d4 Mon Sep 17 00:00:00 2001 From: "Pavel N. Krivitsky" Date: Tue, 10 Sep 2024 10:14:03 +1000 Subject: [PATCH] No longer use the non-API call SET_TYPEOF(); allocLang() (with a workaround for older R) is used instead. fixes statnet/ergm#575 --- src/etamap.c | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/src/etamap.c b/src/etamap.c index 000cb82dc..61eb7e003 100644 --- a/src/etamap.c +++ b/src/etamap.c @@ -8,6 +8,7 @@ * Copyright 2003-2023 Statnet Commons */ #include "ergm_etamap.h" +#include #define SETUP_CALL(fun) \ SEXP cm = VECTOR_ELT(curved, i); \ @@ -28,6 +29,23 @@ SETCAR(pos, cov); +/* + A local implementation of allocLang(), recommended by Writing R + Extensions. + + TODO: Delete in mid 2026. +*/ +#if R_VERSION < R_Version(4, 4, 1) +static inline SEXP allocLang(int n) +{ + if (n > 0) + return LCONS(R_NilValue, allocList(n - 1)); + else + return R_NilValue; +} +#endif +/* End local implementation of allocLang(). */ + SEXP ergm_eta_wrapper(SEXP thetaR, SEXP etamap){ unsigned int neta = asInteger(getListElement(etamap, "etalength")); SEXP etaR = PROTECT(allocVector(REALSXP, neta)); @@ -56,9 +74,8 @@ void ergm_eta(double *theta, SEXP etamap, double *eta){ unsigned int ncurved = length(curved); if(ncurved){ - SEXP call = PROTECT(allocList(4)); - SET_TYPEOF(call, LANGSXP); - + SEXP call = PROTECT(allocLang(3)); + for(unsigned int i = 0; i < ncurved; i++){ SETUP_CALL(map); memcpy(eta1+to, REAL(eval(call, R_EmptyEnv)), nto*sizeof(double)); @@ -100,9 +117,8 @@ void ergm_etagrad(double *theta, SEXP etamap, double *etagrad){ unsigned int ncurved = length(curved); if(ncurved){ - SEXP call = PROTECT(allocList(4)); - SET_TYPEOF(call, LANGSXP); - + SEXP call = PROTECT(allocLang(3)); + for(unsigned int i = 0; i < ncurved; i++){ SETUP_CALL(gradient); double *g = REAL(eval(call, R_EmptyEnv)); @@ -158,9 +174,8 @@ void ergm_etagradmult(double *theta, double *v, unsigned int nv, SEXP etamap, do unsigned int ncurved = length(curved); if(ncurved){ - SEXP call = PROTECT(allocList(4)); - SET_TYPEOF(call, LANGSXP); - + SEXP call = PROTECT(allocLang(3)); + for(unsigned int i = 0; i < ncurved; i++){ SETUP_CALL(gradient); double *g = REAL(eval(call, R_EmptyEnv));