Skip to content

Commit 5537ba7

Browse files
committed
Postpone the problem.
1 parent 96e89fa commit 5537ba7

File tree

12 files changed

+217
-130
lines changed

12 files changed

+217
-130
lines changed

src/R_Defn.h

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
#include <R.h>
2+
#include <Rinternals.h>
3+
4+
// NOTE: All of this is copied from Defn.h: https://github.com/wch/r-source/blob/28de75af0541f93832c5899139b969d290bf422e/src/include/Defn.h
5+
// We intend to gradually remove the need for this header file
6+
7+
// Writable vector/string pointer
8+
#define SEXPPTR(x) ((SEXP *)DATAPTR(x))
9+
10+
#ifndef NAMED_BITS
11+
# define NAMED_BITS 16
12+
#endif
13+
14+
#ifndef SEXPREC_HEADER
15+
16+
// https://github.com/wch/r-source/blob/2640a203d13473f95c9c7508eb2976fefb5c931c/src/include/Defn.h#L123
17+
struct sxpinfo_struct {
18+
SEXPTYPE type : TYPE_BITS;
19+
/* ==> (FUNSXP == 99) %% 2^5 == 3 == CLOSXP
20+
* -> warning: `type' is narrower than values
21+
* of its type
22+
* when SEXPTYPE was an enum */
23+
unsigned int scalar: 1;
24+
unsigned int obj : 1;
25+
unsigned int alt : 1;
26+
unsigned int gp : 16;
27+
unsigned int mark : 1;
28+
unsigned int debug : 1;
29+
unsigned int trace : 1; /* functions and memory tracing */
30+
unsigned int spare : 1; /* used on closures and when REFCNT is defined */
31+
unsigned int gcgen : 1; /* old generation number */
32+
unsigned int gccls : 3; /* node class */
33+
unsigned int named : NAMED_BITS;
34+
unsigned int extra : 32 - NAMED_BITS; /* used for immediate bindings */
35+
}; /* Tot: 64 */
36+
37+
// https://github.com/wch/r-source/blob/2640a203d13473f95c9c7508eb2976fefb5c931c/src/include/Defn.h#L190
38+
#define SEXPREC_HEADER \
39+
struct sxpinfo_struct sxpinfo; \
40+
struct SEXPREC *attrib; \
41+
struct SEXPREC *gengc_next_node, *gengc_prev_node
42+
43+
// https://github.com/wch/r-source/blob/2640a203d13473f95c9c7508eb2976fefb5c931c/src/include/Defn.h#L143
44+
struct vecsxp_struct {
45+
R_xlen_t length;
46+
R_xlen_t truelength;
47+
};
48+
49+
// https://github.com/wch/r-source/blob/2640a203d13473f95c9c7508eb2976fefb5c931c/src/include/Defn.h#L214
50+
typedef struct VECTOR_SEXPREC {
51+
SEXPREC_HEADER;
52+
struct vecsxp_struct vecsxp;
53+
} VECTOR_SEXPREC, *VECSEXP;
54+
55+
#endif
56+
57+
// https://github.com/wch/r-source/blob/2640a203d13473f95c9c7508eb2976fefb5c931c/src/include/Defn.h#L197
58+
typedef struct {
59+
SEXPREC_HEADER;
60+
} SEXPREC_partial;
61+
62+
// (SET_)TRULENGTH: https://github.com/wch/r-source/blob/2640a203d13473f95c9c7508eb2976fefb5c931c/src/include/Defn.h#L386
63+
#define STDVEC_TRUELENGTH(x) (((VECSEXP) (x))->vecsxp.truelength)
64+
// No method to set ALTREP_TRUELENGTH (gives error): https://github.com/wch/r-source/blob/2640a203d13473f95c9c7508eb2976fefb5c931c/src/include/Defn.h#L388
65+
#define SET_TRULEN(x, v) (STDVEC_TRUELENGTH(x)=(v))
66+
// ALTREP_TRUELENGTH is 0: https://github.com/wch/r-source/blob/48f06c1071fea6a6e7e365ad3d745217268e2175/src/main/altrep.c#L345
67+
#define TRULEN(x) (ALTREP(x) ? 0 : STDVEC_TRUELENGTH(x))
68+
69+
// SETLENGTH: https://github.com/wch/r-source/blob/05bb18266d49e87f2477120ecb0ab1440f4e9b40/src/include/Defn.h#L385
70+
#define STDVEC_LENGTH(x) (((VECSEXP) (x))->vecsxp.length)
71+
#define SETSCAL(x, v) ((((SEXPREC_partial *)(x))->sxpinfo.scalar) = (v))
72+
#define SET_STDVEC_LENGTH(x,v) do { \
73+
SEXP __x__ = (x); \
74+
R_xlen_t __v__ = (v); \
75+
STDVEC_LENGTH(__x__) = __v__; \
76+
SETSCAL(__x__, __v__ == 1 ? 1 : 0); \
77+
} while (0)
78+
// https://github.com/wch/r-source/blob/05bb18266d49e87f2477120ecb0ab1440f4e9b40/src/main/memory.c#L4072
79+
#define SET_LEN(x, v) SET_STDVEC_LENGTH((x), (v))
80+
81+
// LEVELS: https://github.com/wch/r-source/blob/2640a203d13473f95c9c7508eb2976fefb5c931c/src/include/Defn.h#L228
82+
#define LEVLS(x) (((SEXPREC_partial *)(x))->sxpinfo.gp)
83+
84+
// SET_GROWABLE_BIT: https://github.com/wch/r-source/blob/2640a203d13473f95c9c7508eb2976fefb5c931c/src/include/Defn.h#L374
85+
#define GROWBLE_MASK ((unsigned short)(1<<5))
86+
#define SET_GROWBLE_BIT(x) (LEVLS(x) |= GROWBLE_MASK)

src/assign.c

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ static void finalizer(SEXP p)
88
p = R_ExternalPtrTag(p);
99
if (!isString(p)) internal_error(__func__, "ExternalPtr doesn't see names in tag"); // # nocov
1010
l = LENGTH(p);
11-
tl = TRUELENGTH(p);
11+
tl = TRULEN(p);
1212
if (l<0 || tl<l) internal_error(__func__, "l=%d, tl=%d", l, tl); // # nocov
1313
n = tl-l;
1414
if (n==0) {
@@ -18,7 +18,7 @@ static void finalizer(SEXP p)
1818
}
1919
x = PROTECT(allocVector(INTSXP, 50)); // 50 so it's big enough to be on LargeVector heap. See NodeClassSize in memory.c:allocVector
2020
// INTSXP rather than VECSXP so that GC doesn't inspect contents after LENGTH (thanks to Karl Miller, Jul 2015)
21-
SETLENGTH(x,50+n*2*sizeof(void *)/4); // 1*n for the names, 1*n for the VECSXP itself (both are over allocated).
21+
SET_LEN(x,50+n*2*sizeof(void *)/4); // 1*n for the names, 1*n for the VECSXP itself (both are over allocated).
2222
UNPROTECT(1);
2323
return;
2424
}
@@ -86,8 +86,8 @@ closest I got to getting it to pass all tests :
8686
UNPROTECT(2);
8787
8888
Then in finalizer:
89-
SETLENGTH(names, tl)
90-
SETLENGTH(dt, tl)
89+
SET_LEN(names, tl)
90+
SET_LEN(dt, tl)
9191
9292
and that finalizer indeed now happens before the GC releases memory (thanks to the env wrapper).
9393
@@ -127,14 +127,14 @@ static int _selfrefok(SEXP x, Rboolean checkNames, Rboolean verbose) {
127127
if (!(isNull(tag) || isString(tag))) internal_error(__func__, ".internal.selfref tag is neither NULL nor a character vector"); // # nocov
128128
names = getAttrib(x, R_NamesSymbol);
129129
if (names!=tag && isString(names) && !ALTREP(names)) // !ALTREP for #4734
130-
SET_TRUELENGTH(names, LENGTH(names));
130+
SET_TRULEN(names, LENGTH(names));
131131
// R copied this vector not data.table; it's not actually over-allocated. It looks over-allocated
132132
// because R copies the original vector's tl over despite allocating length.
133133
prot = R_ExternalPtrProtected(v);
134134
if (TYPEOF(prot) != EXTPTRSXP) // Very rare. Was error(_(".internal.selfref prot is not itself an extptr")).
135135
return 0; // # nocov ; see http://stackoverflow.com/questions/15342227/getting-a-random-internal-selfref-error-in-data-table-for-r
136136
if (x!=R_ExternalPtrAddr(prot) && !ALTREP(x))
137-
SET_TRUELENGTH(x, LENGTH(x)); // R copied this vector not data.table, it's not actually over-allocated
137+
SET_TRULEN(x, LENGTH(x)); // R copied this vector not data.table, it's not actually over-allocated
138138
return checkNames ? names==tag : x==R_ExternalPtrAddr(prot);
139139
}
140140

@@ -189,10 +189,10 @@ static SEXP shallow(SEXP dt, SEXP cols, R_len_t n)
189189
setAttrib(newdt, R_NamesSymbol, newnames);
190190
// setAttrib appears to change length and truelength, so need to do that first _then_ SET next,
191191
// otherwise (if the SET were were first) the 100 tl is assigned to length.
192-
SETLENGTH(newnames,l);
193-
SET_TRUELENGTH(newnames,n);
194-
SETLENGTH(newdt,l);
195-
SET_TRUELENGTH(newdt,n);
192+
SET_LEN(newnames,l);
193+
SET_TRULEN(newnames,n);
194+
SET_LEN(newdt,l);
195+
SET_TRULEN(newdt,n);
196196
setselfref(newdt);
197197
UNPROTECT(protecti);
198198
return(newdt);
@@ -260,10 +260,10 @@ SEXP alloccol(SEXP dt, R_len_t n, Rboolean verbose)
260260
return shallow(dt,R_NilValue,(n>l) ? n : l); // e.g. test 848 and 851 in R > 3.0.2
261261
// added (n>l) ? ... for #970, see test 1481.
262262
// TO DO: test realloc names if selfrefnamesok (users can setattr(x,"name") themselves for example.
263-
// if (TRUELENGTH(getAttrib(dt,R_NamesSymbol))!=tl)
264-
// internal_error(__func__, "tl of dt passes checks, but tl of names (%d) != tl of dt (%d)", tl, TRUELENGTH(getAttrib(dt,R_NamesSymbol))); // # nocov
263+
// if (TRULEN(getAttrib(dt,R_NamesSymbol))!=tl)
264+
// internal_error(__func__, "tl of dt passes checks, but tl of names (%d) != tl of dt (%d)", tl, TRULEN(getAttrib(dt,R_NamesSymbol))); // # nocov
265265

266-
tl = TRUELENGTH(dt);
266+
tl = TRULEN(dt);
267267
// R <= 2.13.2 and we didn't catch uninitialized tl somehow
268268
if (tl<0) internal_error(__func__, "tl of class is marked but tl<0"); // # nocov
269269
if (tl>0 && tl<l) internal_error(__func__, "tl (%d) < l (%d) but tl of class is marked", tl, l); // # nocov
@@ -313,11 +313,11 @@ SEXP shallowwrapper(SEXP dt, SEXP cols) {
313313
if (!selfrefok(dt, FALSE)) {
314314
int n = isNull(cols) ? length(dt) : length(cols);
315315
return(shallow(dt, cols, n));
316-
} else return(shallow(dt, cols, TRUELENGTH(dt)));
316+
} else return(shallow(dt, cols, TRULEN(dt)));
317317
}
318318

319319
SEXP truelength(SEXP x) {
320-
return ScalarInteger(isNull(x) ? 0 : TRUELENGTH(x));
320+
return ScalarInteger(isNull(x) ? 0 : TRULEN(x));
321321
}
322322

323323
SEXP selfrefokwrapper(SEXP x, SEXP verbose) {
@@ -514,7 +514,7 @@ SEXP assign(SEXP dt, SEXP rows, SEXP cols, SEXP newcolnames, SEXP values)
514514
// modify DT by reference. Other than if new columns are being added and the allocVec() fails with
515515
// out-of-memory. In that case the user will receive hard halt and know to rerun.
516516
if (length(newcolnames)) {
517-
oldtncol = TRUELENGTH(dt); // TO DO: oldtncol can be just called tl now, as we won't realloc here any more.
517+
oldtncol = TRULEN(dt); // TO DO: oldtncol can be just called tl now, as we won't realloc here any more.
518518

519519
if (oldtncol<oldncol) {
520520
if (oldtncol==0) error(_("This data.table has either been loaded from disk (e.g. using readRDS()/load()) or constructed manually (e.g. using structure()). Please run setDT() or setalloccol() on it first (to pre-allocate space for new columns) before assigning by reference to it.")); // #2996
@@ -527,13 +527,13 @@ SEXP assign(SEXP dt, SEXP rows, SEXP cols, SEXP newcolnames, SEXP values)
527527
error(_("It appears that at some earlier point, names of this data.table have been reassigned. Please ensure to use setnames() rather than names<- or colnames<-. Otherwise, please report to data.table issue tracker.")); // # nocov
528528
// Can growVector at this point easily enough, but it shouldn't happen in first place so leave it as
529529
// strong error message for now.
530-
else if (TRUELENGTH(names) != oldtncol)
530+
else if (TRULEN(names) != oldtncol)
531531
// Use (long long) to cast R_xlen_t to a fixed type to robustly avoid -Wformat compiler warnings, see #5768, PRId64 didn't work
532-
internal_error(__func__, "selfrefnames is ok but tl names [%lld] != tl [%d]", (long long)TRUELENGTH(names), oldtncol); // # nocov
532+
internal_error(__func__, "selfrefnames is ok but tl names [%lld] != tl [%d]", (long long)TRULEN(names), oldtncol); // # nocov
533533
if (!selfrefok(dt, verbose)) // #6410 setDT(dt) and subsequent attr<- can lead to invalid selfref
534534
error(_("It appears that at some earlier point, attributes of this data.table have been reassigned. Please use setattr(DT, name, value) rather than attr(DT, name) <- value. If that doesn't apply to you, please report your case to the data.table issue tracker."));
535-
SETLENGTH(dt, oldncol+LENGTH(newcolnames));
536-
SETLENGTH(names, oldncol+LENGTH(newcolnames));
535+
SET_LEN(dt, oldncol+LENGTH(newcolnames));
536+
SET_LEN(names, oldncol+LENGTH(newcolnames));
537537
for (int i=0; i<LENGTH(newcolnames); ++i)
538538
SET_STRING_ELT(names,oldncol+i,STRING_ELT(newcolnames,i));
539539
// truelengths of both already set by alloccol
@@ -730,8 +730,8 @@ SEXP assign(SEXP dt, SEXP rows, SEXP cols, SEXP newcolnames, SEXP values)
730730
SET_VECTOR_ELT(dt, i, R_NilValue);
731731
SET_STRING_ELT(names, i, NA_STRING); // release reference to the CHARSXP
732732
}
733-
SETLENGTH(dt, ndt-ndelete);
734-
SETLENGTH(names, ndt-ndelete);
733+
SET_LEN(dt, ndt-ndelete);
734+
SET_LEN(names, ndt-ndelete);
735735
if (LENGTH(names)==0) {
736736
// That was last column deleted, leaving NULL data.table, so we need to reset .row_names, so that it really is the NULL data.table.
737737
PROTECT(nullint=allocVector(INTSXP, 0)); protecti++;
@@ -830,26 +830,26 @@ const char *memrecycle(const SEXP target, const SEXP where, const int start, con
830830
savetl_init();
831831
for (int k=0; k<nTargetLevels; ++k) {
832832
const SEXP s = targetLevelsD[k];
833-
const int tl = TRUELENGTH(s);
833+
const int tl = TRULEN(s);
834834
if (tl>0) {
835835
savetl(s);
836836
} else if (tl<0) {
837837
// # nocov start
838-
for (int j=0; j<k; ++j) SET_TRUELENGTH(s, 0); // wipe our negative usage and restore 0
838+
for (int j=0; j<k; ++j) SET_TRULEN(s, 0); // wipe our negative usage and restore 0
839839
savetl_end(); // then restore R's own usage (if any)
840840
internal_error(__func__, "levels of target are either not unique or have truelength<0"); // # nocov
841841
// # nocov end
842842
}
843-
SET_TRUELENGTH(s, -k-1);
843+
SET_TRULEN(s, -k-1);
844844
}
845845
int nAdd = 0;
846846
for (int k=0; k<nSourceLevels; ++k) {
847847
const SEXP s = sourceLevelsD[k];
848-
const int tl = TRUELENGTH(s);
848+
const int tl = TRULEN(s);
849849
if (tl>=0) {
850850
if (!sourceIsFactor && s==NA_STRING) continue; // don't create NA factor level when assigning character to factor; test 2117
851851
if (tl>0) savetl(s);
852-
SET_TRUELENGTH(s, -nTargetLevels-(++nAdd));
852+
SET_TRULEN(s, -nTargetLevels-(++nAdd));
853853
} // else, when sourceIsString, it's normal for there to be duplicates here
854854
}
855855
const int nSource = length(source);
@@ -858,34 +858,34 @@ const char *memrecycle(const SEXP target, const SEXP where, const int start, con
858858
const int *sourceD = INTEGER(source);
859859
for (int i=0; i<nSource; ++i) { // convert source integers to refer to target levels
860860
const int val = sourceD[i];
861-
newSourceD[i] = val==NA_INTEGER ? NA_INTEGER : -TRUELENGTH(sourceLevelsD[val-1]); // retains NA factor levels here via TL(NA_STRING); e.g. ordered factor
861+
newSourceD[i] = val==NA_INTEGER ? NA_INTEGER : -TRULEN(sourceLevelsD[val-1]); // retains NA factor levels here via TL(NA_STRING); e.g. ordered factor
862862
}
863863
} else {
864864
const SEXP *sourceD = STRING_PTR_RO(source);
865865
for (int i=0; i<nSource; ++i) { // convert source integers to refer to target levels
866866
const SEXP val = sourceD[i];
867-
newSourceD[i] = val==NA_STRING ? NA_INTEGER : -TRUELENGTH(val);
867+
newSourceD[i] = val==NA_STRING ? NA_INTEGER : -TRULEN(val);
868868
}
869869
}
870870
source = newSource;
871-
for (int k=0; k<nTargetLevels; ++k) SET_TRUELENGTH(targetLevelsD[k], 0); // don't need those anymore
871+
for (int k=0; k<nTargetLevels; ++k) SET_TRULEN(targetLevelsD[k], 0); // don't need those anymore
872872
if (nAdd) {
873873
// cannot grow the levels yet as that would be R call which could fail to alloc and we have no hook to clear up
874874
SEXP *temp = (SEXP *)malloc(nAdd * sizeof(SEXP *));
875875
if (!temp) {
876876
// # nocov start
877-
for (int k=0; k<nSourceLevels; ++k) SET_TRUELENGTH(sourceLevelsD[k], 0);
877+
for (int k=0; k<nSourceLevels; ++k) SET_TRULEN(sourceLevelsD[k], 0);
878878
savetl_end();
879879
error(_("Unable to allocate working memory of %zu bytes to combine factor levels"), nAdd*sizeof(SEXP *));
880880
// # nocov end
881881
}
882882
for (int k=0, thisAdd=0; thisAdd<nAdd; ++k) { // thisAdd<nAdd to stop early when the added ones are all reached
883883
SEXP s = sourceLevelsD[k];
884-
int tl = TRUELENGTH(s);
884+
int tl = TRULEN(s);
885885
if (tl) { // tl negative here
886886
if (tl != -nTargetLevels-thisAdd-1) internal_error(__func__, "extra level check sum failed"); // # nocov
887887
temp[thisAdd++] = s;
888-
SET_TRUELENGTH(s,0);
888+
SET_TRULEN(s,0);
889889
}
890890
}
891891
savetl_end();
@@ -1312,14 +1312,14 @@ void savetl(SEXP s)
13121312
savedtl = (R_len_t *)tmp;
13131313
}
13141314
saveds[nsaved] = s;
1315-
savedtl[nsaved] = TRUELENGTH(s);
1315+
savedtl[nsaved] = TRULEN(s);
13161316
nsaved++;
13171317
}
13181318

13191319
void savetl_end(void) {
13201320
// Can get called if nothing has been saved yet (nsaved==0), or even if _init() hasn't been called yet (pointers NULL). Such
13211321
// as to clear up before error. Also, it might be that nothing needed to be saved anyway.
1322-
for (int i=0; i<nsaved; i++) SET_TRUELENGTH(saveds[i],savedtl[i]);
1322+
for (int i=0; i<nsaved; i++) SET_TRULEN(saveds[i],savedtl[i]);
13231323
free(saveds); // possible free(NULL) which is safe no-op
13241324
saveds = NULL;
13251325
free(savedtl);

src/chmatch.c

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,10 @@ static SEXP chmatchMain(SEXP x, SEXP table, int nomatch, bool chin, bool chmatch
5858
savetl_init();
5959
for (int i=0; i<xlen; i++) {
6060
SEXP s = xd[i];
61-
const int tl = TRUELENGTH(s);
61+
const int tl = TRULEN(s);
6262
if (tl>0) {
6363
savetl(s); // R's internal hash (which is positive); save it
64-
SET_TRUELENGTH(s,0);
64+
SET_TRULEN(s,0);
6565
} else if (tl<0) {
6666
// R 2.14.0+ initializes truelength to 0 (before that it was uninitialized/random).
6767
// Now that data.table depends on R 3.1.0+, that is after 2.14.0 too.
@@ -75,13 +75,13 @@ static SEXP chmatchMain(SEXP x, SEXP table, int nomatch, bool chin, bool chmatch
7575
int nuniq=0;
7676
for (int i=0; i<tablelen; ++i) {
7777
const SEXP s = td[i];
78-
int tl = TRUELENGTH(s);
78+
int tl = TRULEN(s);
7979
if (tl>0) { savetl(s); tl=0; }
80-
if (tl==0) SET_TRUELENGTH(s, chmatchdup ? -(++nuniq) : -i-1); // first time seen this string in table
80+
if (tl==0) SET_TRULEN(s, chmatchdup ? -(++nuniq) : -i-1); // first time seen this string in table
8181
}
8282
// in future if we need NAs in x not to be matched to NAs in table ...
83-
// if (!matchNAtoNA && TRUELENGTH(NA_STRING)<0)
84-
// SET_TRUELENGTH(NA_STRING, 0);
83+
// if (!matchNAtoNA && TRULEN(NA_STRING)<0)
84+
// SET_TRULEN(NA_STRING, 0);
8585
if (chmatchdup) {
8686
// chmatchdup() is basically base::pmatch() but without the partial matching part. For example :
8787
// chmatchdup(c("a", "a"), c("a", "a")) # 1,2 - the second 'a' in 'x' has a 2nd match in 'table'
@@ -100,21 +100,21 @@ static SEXP chmatchMain(SEXP x, SEXP table, int nomatch, bool chin, bool chmatch
100100
if (!counts || !map) {
101101
// # nocov start
102102
free(counts); free(map);
103-
for (int i=0; i<tablelen; i++) SET_TRUELENGTH(td[i], 0);
103+
for (int i=0; i<tablelen; i++) SET_TRULEN(td[i], 0);
104104
savetl_end();
105105
error(_("Failed to allocate %"PRIu64" bytes working memory in chmatchdup: length(table)=%d length(unique(table))=%d"), ((uint64_t)tablelen*2+nuniq)*sizeof(int), tablelen, nuniq);
106106
// # nocov end
107107
}
108-
for (int i=0; i<tablelen; ++i) counts[-TRUELENGTH(td[i])-1]++;
108+
for (int i=0; i<tablelen; ++i) counts[-TRULEN(td[i])-1]++;
109109
for (int i=0, sum=0; i<nuniq; ++i) { int tt=counts[i]; counts[i]=sum; sum+=tt+1; }
110-
for (int i=0; i<tablelen; ++i) map[counts[-TRUELENGTH(td[i])-1]++] = i+1; // 0 is left ending each group thanks to the calloc
110+
for (int i=0; i<tablelen; ++i) map[counts[-TRULEN(td[i])-1]++] = i+1; // 0 is left ending each group thanks to the calloc
111111
for (int i=0, last=0; i<nuniq; ++i) {int tt=counts[i]+1; counts[i]=last; last=tt;} // rewind counts to the beginning of each group
112112
for (int i=0; i<xlen; ++i) {
113-
int u = TRUELENGTH(xd[i]);
113+
int u = TRULEN(xd[i]);
114114
if (u<0) {
115115
const int w = counts[-u-1]++;
116116
if (map[w]) { ansd[i]=map[w]; continue; }
117-
SET_TRUELENGTH(xd[i],0); // w falls on ending 0 marker: dups used up; any more dups should return nomatch
117+
SET_TRULEN(xd[i],0); // w falls on ending 0 marker: dups used up; any more dups should return nomatch
118118
// we still need the 0-setting loop at the end of this function because often there will be some values in table that are not matched to at all.
119119
}
120120
ansd[i] = nomatch;
@@ -123,16 +123,16 @@ static SEXP chmatchMain(SEXP x, SEXP table, int nomatch, bool chin, bool chmatch
123123
free(map);
124124
} else if (chin) {
125125
for (int i=0; i<xlen; i++) {
126-
ansd[i] = TRUELENGTH(xd[i])<0;
126+
ansd[i] = TRULEN(xd[i])<0;
127127
}
128128
} else {
129129
for (int i=0; i<xlen; i++) {
130-
const int m = TRUELENGTH(xd[i]);
130+
const int m = TRULEN(xd[i]);
131131
ansd[i] = (m<0) ? -m : nomatch;
132132
}
133133
}
134134
for (int i=0; i<tablelen; i++)
135-
SET_TRUELENGTH(td[i], 0); // reinstate 0 rather than leave the -i-1
135+
SET_TRULEN(td[i], 0); // reinstate 0 rather than leave the -i-1
136136
savetl_end();
137137
UNPROTECT(nprotect); // ans, xd, td
138138
return ans;

0 commit comments

Comments
 (0)