-
Notifications
You must be signed in to change notification settings - Fork 1k
Replace ATTRIB, SET_ATTRIB
#7487
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
0a6e0e7
2e0c389
58d586b
402f0d5
0f47f29
ff280b5
e4f1788
3c66757
2c10c37
e1fa0a6
09b1f7e
1a408bf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,6 +3,8 @@ | |
| #include <fcntl.h> | ||
| #include <time.h> | ||
|
|
||
| static SEXP attribWalker(SEXP key, SEXP val, void *ctx); | ||
|
|
||
| static bool anySpecialStatic(SEXP x, hashtab * specials) { | ||
| // Special refers to special symbols .BY, .I, .N, and .GRP; see special-symbols.Rd | ||
| // Static because these are like C static arrays which are the same memory for each group; e.g., dogroups | ||
|
|
@@ -54,20 +56,23 @@ static bool anySpecialStatic(SEXP x, hashtab * specials) { | |
| list_el = VECTOR_ELT(x,i); | ||
| if (anySpecialStatic(list_el, specials)) | ||
| return true; | ||
| for(attribs = ATTRIB(list_el); attribs != R_NilValue; attribs = CDR(attribs)) { | ||
| if (anySpecialStatic(CAR(attribs), specials)) | ||
| return true; // #4936 | ||
| } | ||
| if (R_mapAttrib(list_el, attribWalker, specials)) | ||
| return true; // #4936 | ||
| } | ||
| } | ||
| return false; | ||
| } | ||
|
|
||
| static SEXP attribWalker(SEXP key, SEXP val, void *specials) { | ||
| (void)key; | ||
| return anySpecialStatic(val, specials) ? R_NilValue : NULL; | ||
| } | ||
|
|
||
| SEXP dogroups(SEXP dt, SEXP dtcols, SEXP groups, SEXP grpcols, SEXP jiscols, SEXP xjiscols, SEXP grporder, SEXP order, SEXP starts, SEXP lens, SEXP jexp, SEXP env, SEXP lhs, SEXP newnames, SEXP on, SEXP verboseArg, SEXP showProgressArg) | ||
| { | ||
| R_len_t ngrp, nrowgroups, njval=0, ngrpcols, ansloc=0, maxn, estn=-1, thisansloc, grpn, thislen, igrp; | ||
| int nprotect=0; | ||
| SEXP ans=NULL, jval, thiscol, BY, N, I, GRP, iSD, xSD, rownames, s, RHS, target, source; | ||
| SEXP ans=NULL, jval, thiscol, BY, N, I, GRP, iSD, xSD, s, RHS, target, source; | ||
| Rboolean wasvector, firstalloc=FALSE, NullWarnDone=FALSE; | ||
| const bool verbose = LOGICAL(verboseArg)[0]==1; | ||
| double tstart=0, tblock[10]={0}; int nblock[10]={0}; // For verbose printing, tstart is updated each block | ||
|
|
@@ -130,12 +135,15 @@ SEXP dogroups(SEXP dt, SEXP dtcols, SEXP groups, SEXP grpcols, SEXP jiscols, SEX | |
| R_LockBinding(install(".I"), env); | ||
|
|
||
| SEXP dtnames = PROTECT(getAttrib(dt, R_NamesSymbol)); nprotect++; // added here to fix #91 - `:=` did not issue recycling warning during "by" | ||
| // fetch rownames of .SD. rownames[1] is set to -thislen for each group, in case .SD is passed to | ||
|
|
||
| // override rownames of .SD. rownames[1] is set to -thislen for each group, in case .SD is passed to | ||
| // non data.table aware package that uses rownames | ||
| for (s = ATTRIB(SD); s != R_NilValue && TAG(s)!=R_RowNamesSymbol; s = CDR(s)); // getAttrib0 basically but that's hidden in attrib.c; #loop_counter_not_local_scope_ok | ||
| if (s==R_NilValue) error(_("row.names attribute of .SD not found")); | ||
| rownames = CAR(s); | ||
| if (!isInteger(rownames) || LENGTH(rownames)!=2 || INTEGER(rownames)[0]!=NA_INTEGER) error(_("row.names of .SD isn't integer length 2 with NA as first item; i.e., .set_row_names(). [%s %d %d]"),type2char(TYPEOF(rownames)),LENGTH(rownames),INTEGER(rownames)[0]); | ||
| SEXP rownames; | ||
| PROTECT_INDEX rownamesi; | ||
| PROTECT_WITH_INDEX(rownames = allocVector(INTSXP, 2), &rownamesi); nprotect++; | ||
| INTEGER(rownames)[0] = NA_INTEGER; | ||
| INTEGER(rownames)[1] = -maxGrpSize; | ||
| REPROTECT(rownames = setAttrib(SD, R_RowNamesSymbol, rownames), rownamesi); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this is wrong; check the return value of setAttrib
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider R_mapAttrib for this.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. R is somewhat inconsistent about this. |
||
|
|
||
| // fetch names of .SD and prepare symbols. In case they are copied-on-write by user assigning to those variables | ||
| // using <- in j (which is valid, useful and tested), they are repointed to the .SD cols for each group. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -625,7 +625,7 @@ SEXP frev(SEXP x, SEXP copyArg) { | |
| SEXP levels = PROTECT(getAttrib(x, R_LevelsSymbol)); | ||
| nprotect += 2; | ||
| // swipe attributes from x | ||
| SET_ATTRIB(x, R_NilValue); | ||
| CLEAR_ATTRIB(x); | ||
| setAttrib(x, R_NamesSymbol, names); | ||
| setAttrib(x, R_ClassSymbol, klass); | ||
| setAttrib(x, R_LevelsSymbol, levels); | ||
|
|
@@ -672,3 +672,20 @@ void R_resizeVector_(SEXP x, R_xlen_t newlen) { | |
| SETLENGTH(x, newlen); | ||
| } | ||
| #endif | ||
|
|
||
| #ifdef BACKPORT_MAP_ATTRIB | ||
| SEXP R_mapAttrib_(SEXP x, SEXP (*fun)(SEXP key, SEXP val, void *ctx), void *ctx) { | ||
| PROTECT_INDEX i; | ||
| SEXP a = ATTRIB(x); | ||
| PROTECT_WITH_INDEX(a, &i); | ||
|
|
||
| SEXP ret = NULL; | ||
| for (; !isNull(a); REPROTECT(a = CDR(a), i)) { | ||
| ret = fun(TAG(a), CAR(a), ctx); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not blocking, but if time permits consider R's structure more closely with protection of the TAG(a) and CAR(a) in teh callback.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. AFAIK while |
||
| if (ret) break; | ||
| } | ||
|
|
||
| UNPROTECT(1); | ||
| return ret; | ||
| } | ||
| #endif | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is
SEXPthe intended return type?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that's following the
R_mapAttribinterface. I have to return(SEXP)NULLto continue iteration.