From 7a160301d66e0e2aa25d34996519aa043554dca0 Mon Sep 17 00:00:00 2001 From: "Matthew L. Fidler" Date: Thu, 11 Jul 2024 14:40:03 -0500 Subject: [PATCH] Fix sbuf.c --- .gitignore | 1 - inst/tools/workaround.R | 8 -- src/sbuf.c | 246 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 246 insertions(+), 9 deletions(-) create mode 100644 src/sbuf.c diff --git a/.gitignore b/.gitignore index eeb1d6b50..23afcf1af 100644 --- a/.gitignore +++ b/.gitignore @@ -45,5 +45,4 @@ docs/ /Meta/ *.gcda revdep/ -/src/sbuf.c docs diff --git a/inst/tools/workaround.R b/inst/tools/workaround.R index 6af3fe952..8aeb3a606 100644 --- a/inst/tools/workaround.R +++ b/inst/tools/workaround.R @@ -105,11 +105,3 @@ unlink("R/rxode2_md5.R") md5file <- file("R/rxode2_md5.R", "wb") writeLines(sprintf("rxode2.md5 <- \"%s\"\n", md5), md5file) close(md5file) - -l <- readLines(file.path(system.file(package="rxode2parse"), "include", "sbuf.c")) - -sbuf.c <- file("src/sbuf.c", "wb") -.w <- which(regexpr(" *extern +SEXP +_goodFuns; *", l) != -1) -l <- l[-seq(.w, length(l))] -writeLines(l, sbuf.c) -close(sbuf.c) diff --git a/src/sbuf.c b/src/sbuf.c new file mode 100644 index 000000000..98bbe4470 --- /dev/null +++ b/src/sbuf.c @@ -0,0 +1,246 @@ +#define USE_FC_LEN_T +#define STRICT_R_HEADERS +#include "../inst/include/rxode2.h" +#ifdef ENABLE_NLS +#include +#define _(String) dgettext ("rxode2", String) +#endif +/* replace pkg as appropriate */ + +// Taken from dparser and changed to use Calloc +int rc_buf_read(const char *pathname, char **buf, int *len) { + struct stat sb; + int fd; + *buf = 0; + *len = 0; + fd = open(pathname, O_RDONLY); + if (fd <= 0) + return -1; + memset(&sb, 0, sizeof(sb)); + fstat(fd, &sb); + *len = sb.st_size; + *buf = R_Calloc(*len + 3,char); + // MINGW likes to convert cr lf => lf which messes with the size + size_t real_size = read(fd, *buf, *len); + (*buf)[real_size] = 0; + (*buf)[real_size + 1] = 0; + *len = real_size; + close(fd); + return *len; +} + +// Taken from dparser and changed to use Calloc +char * rc_sbuf_read(const char *pathname) { + char *buf; + int len; + if (rc_buf_read(pathname, &buf, &len) < 0) + return NULL; + return buf; +} + + + +void sIniTo(sbuf *sbb, int to) { + if (sbb->s != NULL) R_Free(sbb->s); + sbb->s = R_Calloc(to, char); + sbb->sN = to; + sbb->s[0] = '\0'; + sbb->o = 0; +} + +void sIni(sbuf *sbb) { + sIniTo(sbb, SBUF_MXBUF); +} + +void sFree(sbuf *sbb) { + if (sbb->s != NULL) R_Free(sbb->s); + sNull(sbb); +} + +void sFreeIni(sbuf *sbb) { + sFree(sbb); + sIni(sbb); +} + +void sAppendN(sbuf *sbb, const char *what, int n) { + if (sbb->sN == 0) sIni(sbb); + if (sbb->sN <= 2 + n + sbb->o){ + int mx = sbb->o + 2 + n + SBUF_MXBUF; + sbb->s = R_Realloc(sbb->s, mx, char); + sbb->sN = mx; + } + snprintf(sbb->s+sbb->o, sbb->sN - sbb->o, "%s", what); + sbb->o +=n; +} + +void sAppend(sbuf *sbb, const char *format, ...) { + if (sbb->sN == 0) sIni(sbb); + if (format == NULL) return; + int n = 0; + va_list argptr, copy; + va_start(argptr, format); + va_copy(copy, argptr); +#if defined(_WIN32) || defined(WIN32) + n = vsnprintf(NULL, 0, format, copy) + 1; +#else + char zero[2]; + n = vsnprintf(zero, 0, format, copy) + 1; +#endif + va_end(copy); + if (sbb->sN <= sbb->o + n + 1) { + int mx = sbb->o + n + 1 + SBUF_MXBUF; + sbb->s = R_Realloc(sbb->s, mx, char); + sbb->sN = mx; + } + vsnprintf(sbb->s+ sbb->o, sbb->sN - sbb->o, format, argptr); + va_end(argptr); + sbb->o += n-1; +} + +void sPrint(sbuf *sbb, const char *format, ...) { + if (sbb->sN == 0) sIni(sbb); + sClear(sbb); + if (format == NULL) return; + int n = 0; + va_list argptr, copy; + va_start(argptr, format); + va_copy(copy, argptr); +#if defined(_WIN32) || defined(WIN32) + n = vsnprintf(NULL, 0, format, copy) + 1; +#else + char zero[2]; + n = vsnprintf(zero, 0, format, copy) + 1; +#endif + va_end(copy); + if (sbb->sN <= sbb->o + n + 1){ + int mx = sbb->o + n + 1 + SBUF_MXBUF; + sbb->s = R_Realloc(sbb->s, mx, char); + sbb->sN = mx; + } + vsnprintf(sbb->s+ sbb->o, sbb->sN - sbb->o, format, argptr); + va_end(argptr); + sbb->o += n-1; +} + +void lineIni(vLines *sbb) { + if (sbb->s != NULL) R_Free(sbb->s); + sbb->s = R_Calloc(SBUF_MXBUF, char); + sbb->sN = SBUF_MXBUF; + sbb->s[0]='\0'; + sbb->o = 0; + if (sbb->lProp != NULL) R_Free(sbb->lProp); + if (sbb->line != NULL) R_Free(sbb->line); + if (sbb->lType != NULL) R_Free(sbb->lType); + if (sbb->os != NULL) R_Free(sbb->os); + sbb->lProp = R_Calloc(SBUF_MXLINE, int); + sbb->lType = R_Calloc(SBUF_MXLINE, int); + sbb->line = R_Calloc(SBUF_MXLINE, char*); + sbb->os = R_Calloc(SBUF_MXLINE, int); + sbb->nL=SBUF_MXLINE; + sbb->lProp[0] = -1; + sbb->lType[0] = 0; + sbb->n = 0; +} + +void lineFree(vLines *sbb) { + if (sbb->s != NULL) R_Free(sbb->s); + if (sbb->lProp != NULL) R_Free(sbb->lProp); + if (sbb->line != NULL) R_Free(sbb->line); + if (sbb->lType != NULL) R_Free(sbb->lType); + if (sbb->os != NULL) R_Free(sbb->os); + lineNull(sbb); +} + +void addLine(vLines *sbb, const char *format, ...) { + if (sbb->sN == 0) lineIni(sbb); + if (format == NULL) return; + int n = 0; + va_list argptr, copy; + va_start(argptr, format); + va_copy(copy, argptr); + errno = 0; + // Try first. +#if defined(_WIN32) || defined(WIN32) + n = vsnprintf(NULL, 0, format, copy); +#else + char zero[2]; + n = vsnprintf(zero, 0, format, copy); +#endif + if (n < 0){ + parseFree(0); + Rf_errorcall(R_NilValue, _("encoding error in 'addLine' format: '%s' n: %d; errno: %d"), format, n, errno); + } + va_end(copy); + if (sbb->sN <= sbb->o + n){ + int mx = sbb->sN + n + 2 + SBUF_MXBUF; + sbb->s = R_Realloc(sbb->s, mx, char); + // The sbb->line are not correct any longer because the pointer for sbb->s has been updated; + // Fix them + for (int i = sbb->n; i--;){ + sbb->line[i] = &(sbb->s[sbb->os[i]]); + } + sbb->sN = mx; + } + vsnprintf(sbb->s + sbb->o, sbb->sN - sbb->o, format, argptr); + va_end(argptr); + if (sbb->n + 2 >= sbb->nL){ + int mx = sbb->nL + n + 2 + SBUF_MXLINE; + sbb->lProp = R_Realloc(sbb->lProp, mx, int); + sbb->lType = R_Realloc(sbb->lType, mx, int); + sbb->line = R_Realloc(sbb->line, mx, char*); + sbb->os = R_Realloc(sbb->os, mx, int); + sbb->nL = mx; + } + sbb->line[sbb->n]=&(sbb->s[sbb->o]); + sbb->os[sbb->n]= sbb->o; + sbb->o += n + 1; // n should include the \0 character + sbb->n = sbb->n+1; + sbb->lProp[sbb->n] = -1; + sbb->lType[sbb->n] = 0; + sbb->os[sbb->n]= sbb->o; +} + +void curLineProp(vLines *sbb, int propId){ + sbb->lProp[sbb->n] = propId; +} + +void curLineType(vLines *sbb, int propId) { + sbb->lType[sbb->n] = propId; +} + +extern SEXP _goodFuns; + +void doDot(sbuf *out, char *buf) { + for (int j = Rf_length(_goodFuns); j--;){ + if (!strcmp(CHAR(STRING_ELT(_goodFuns, j)), buf)) { + sAppendN(out, "_rxNotFun_", 10); + break; + } + } + for (int k = 0; k < (int)strlen(buf); k++){ + if (buf[k] == '.'){ + sAppend(out,"_DoT_"); + } else { + sPut(out,buf[k]); + } + } +} + +void doDot2(sbuf *sb, sbuf *sbDt, char *buf) { + for (int j = Rf_length(_goodFuns); j--;){ + if (!strcmp(CHAR(STRING_ELT(_goodFuns, j)), buf)) { + sAppendN(sb, "_rxNotFun_", 10); + sAppendN(sbDt, "_rxNotFun_", 10); + break; + } + } + for (int k = 0; k < (int)strlen(buf); k++) { + if (buf[k] == '.') { + sAppend(sb,"_DoT_"); + sAppend(sbDt,"_DoT_"); + } else { + sPut(sb,buf[k]); + sPut(sbDt,buf[k]); + } + } +}