diff --git a/.dev/CRAN_Release.cmd b/.dev/CRAN_Release.cmd index e629ee980b..ab215750d6 100644 --- a/.dev/CRAN_Release.cmd +++ b/.dev/CRAN_Release.cmd @@ -153,6 +153,14 @@ grep -nE "(llu|lld|zd|zu)" src/*.[hc] grep -P "\t" ./R/*.R grep -P "\t" ./src/*.c +# all error branches should be on a new line to be properly included in codecov; exceptions: +# (1) in a comment (pattern: after // or after \s*[*] +# (2) in '} else error(' pattern (if else is covered, so is the error) +# (3) in #define macros +for type in error warning STOP DTWARN Error; do + grep -Enr "\b$type[(]" src --include=*.c | grep -Ev "^src\/[a-zA-Z-]+[.]c:[0-9]+:\s*(?:(?:[}]?\s*else\s*)?$type|#define|[*]|.*\/\/.*$type)" +done + # No T or F symbols in tests.Rraw. 24 valid F (quoted, column name or in data) and 1 valid T at the time of writing grep -n "[^A-Za-z0-9]T[^A-Za-z0-9]" ./inst/tests/tests.Rraw grep -n "[^A-Za-z0-9]F[^A-Za-z0-9]" ./inst/tests/tests.Rraw diff --git a/inst/tests/tests.Rraw b/inst/tests/tests.Rraw index 7cc6819e8f..1fd32e6784 100644 --- a/inst/tests/tests.Rraw +++ b/inst/tests/tests.Rraw @@ -54,6 +54,7 @@ if (exists("test.data.table", .GlobalEnv, inherits=FALSE)) { test = data.table:::test uniqlengths = data.table:::uniqlengths uniqlist = data.table:::uniqlist + vecseq = data.table:::vecseq which_ = data.table:::which_ which.first = data.table:::which.first which.last = data.table:::which.last @@ -6312,15 +6313,13 @@ options(datatable.optimize = Inf) # fread dec=',' e.g. France test(1439, fread("A;B\n1;2,34\n", dec="12"), error="nchar(dec) == 1L is not TRUE") -test(1440, fread("A;B\n8;2,34\n", dec="1"), data.table(A=8L, B="2,34")) test(1441, fread("A;B\n8;2,34\n", dec=","), data.table(A=8L, B=2.34)) test(1442, fread("A;B\n1;2,34\n", sep=".", dec="."), error="sep == dec ('.') is not allowed") test(1443, fread("A;B\n1;2,34\n", dec=",", sep=","), error="sep == dec (',') is not allowed") # sep=".", issue #502 input = paste( paste("192.168.4.", 1:10, sep=""), collapse="\n") -test(1444.1, fread(input, sep=".", dec="*"), ans<-data.table(V1=192L,V2=168L,V3=4L,V4=1:10)) -test(1444.2, fread(input, sep=".", dec=","), ans) +test(1444.2, fread(input, sep=".", dec=","), ans<-data.table(V1=192L,V2=168L,V3=4L,V4=1:10)) test(1444.3, fread(paste(paste("192. 168. 4. ", 1:10, sep = ""), collapse="\n"), sep=".", dec=","), ans) test(1444.4, fread(paste(paste("Hz.BB.GHG.", 1:10, sep = ""), collapse="\n"), sep=".", dec=","), data.table(V1="Hz",V2="BB",V3="GHG",V4=1:10)) @@ -16846,3 +16845,87 @@ A = data.table(A=c(complex(real = 1:3, imaginary=c(0, -1, 1)), NaN)) test(2138.3, rbind(A,B), data.table(A=c(as.character(A$A), B$A))) A = data.table(A=as.complex(rep(NA, 5))) test(2138.4, rbind(A,B), data.table(A=c(as.character(A$A), B$A))) + +# tests caught by introducing newlines in #4301 +test(2139.01, getDTthreads(8L), error="'verbose' must be TRUE or FALSE") +test(2139.02, setDTthreads(1:2), error='threads= must be either NULL.*length 2') +test(2139.03, setDTthreads(1+0i), error='threads= must be either NULL.*type integer/numeric') +DT = data.table(1L) +invisible(alloc.col(DT, 10010L)) +test(2139.04, alloc.col(DT), DT, warning='greater than 10,000 items over-allocated') +test(2139.05, alloc.col(DT, verbose = 1L), error="verbose must be TRUE or FALSE") +test(2139.06, set(data.table(NULL), NULL, 1L, 1L), error="Input data.table has no columns") +test(2139.07, set(1L, NULL, 1L, 1L), error="object passed to assign isn't type VECSXP") +names(DT) = NULL +test(2139.08, set(DT, NULL, 1L, 2L), error="data.table passed to assign has no names") +test(2139.09, alloc.col(NULL), error="object passed to alloccol is NULL") +test(2139.10, alloc.col(1L), error="object passed to alloccol isn't type VECSXP") +test(2139.11, set(NULL, NULL, 1L, 1L), error="object passed to assign is NULL") +setDF(DT) +names(DT) = 'V1' +test(2139.12, set(DT, NULL, 'V2', 2L), error="set() on a data.frame is for changing existing columns") +setDT(DT) +invisible(alloc.col(DT, 10010L)) +test(2139.13, set(DT, NULL, 'V2', 2L), DT, warning="greater than 10,000 items over-allocated") + +txt = 'a,b\n1,2' +test(2139.14, fread(txt, sep=',', quote=','), error="sep == quote (',') is not allowed") +test(2139.15, fread(txt, dec='&'), error="dec='&' not allowed") +test(2139.16, fread(txt, quote='.', dec='.'), error="quote == dec ('.') is not allowed") +test(2139.17, fread(txt, integer64=letters), error="'integer64' must be a single character string") +test(2139.18, fread(txt, select = c(1, 1)), error="Column number 1 ('a') has been selected twice by select=") + +test(2139.19, setNumericRounding(1:2), error="Rounding level must be a length-1 integer or numeric vector") +test(2139.20, setNumericRounding(-1), error="Rounding level must be 2, 1 or 0") + +DT = data.table(1L) +names(DT) = NULL +test(2139.21, setcolorder(DT, 1L), error="data.table passed to setcolorder has no names") + +# uniqueNlogical +test(2139.22, uniqueN(NA, na.rm=1), error="na.rm must be TRUE or FALSE") +test(2139.23, rleid(1, 1:2), error="All elements of input list must be of same length") +test(2139.24, uniqlengths(1L, 1:3), error="Input argument 'n' to 'uniqlengths' must be an integer vector of length 1") + +old = options(datatable.optimize = 2L) +DT = data.table(a = 1:2, b = 1, f = factor(1), l = list(1)) +test(2139.25, DT[ , sum(b, na.rm=1), by=a], error="na.rm must be TRUE or FALSE") +test(2139.26, DT[ , sum(f), by=a], error="sum is not meaningful for factors") +test(2139.27, DT[ , mean(b, na.rm=1), by=a], error="na.rm must be TRUE or FALSE") +test(2139.28, DT[ , mean(l), by=a], error="GForce mean can only be applied to columns, not .SD or similar") +test(2139.29, DT[ , mean(f), by=a], error="mean is not meaningful for factors") +test(2139.30, DT[ , min(b, na.rm=1), by=a], error="na.rm must be TRUE or FALSE") +test(2139.31, DT[ , min(l), by=a], error="GForce min can only be applied to columns, not .SD or similar") +test(2139.32, DT[ , min(f), by=a], error="min is not meaningful for factors") +test(2139.33, DT[ , max(b, na.rm=1), by=a], error="na.rm must be TRUE or FALSE") +test(2139.34, DT[ , max(l), by=a], error="GForce max can only be applied to columns, not .SD or similar") +test(2139.35, DT[ , max(f), by=a], error="max is not meaningful for factors") +test(2139.36, DT[ , median(b, na.rm=1), by=a], error="na.rm must be TRUE or FALSE") +test(2139.37, DT[ , median(l), by=a], error="GForce median can only be applied to columns, not .SD or similar") +test(2139.38, DT[ , median(f), by=a], error="median is not meaningful for factors") +test(2139.39, DT[ , var(b, na.rm=1), by=a], error="na.rm must be TRUE or FALSE") +test(2139.40, DT[ , var(l), by=a], error="GForce var/sd can only be applied to columns, not .SD or similar") +test(2139.41, DT[ , var(f), by=a], error="var/sd is not meaningful for factors") +test(2139.42, DT[ , prod(b, na.rm=1), by=a], error="na.rm must be TRUE or FALSE") +test(2139.43, DT[ , prod(l), by=a], error="GForce prod can only be applied to columns, not .SD or similar") +test(2139.44, DT[ , prod(f), by=a], error="prod is not meaningful for factors") +options(old) + +test(2139.45, vecseq(NA, NA, NA), error="x must be an integer vector") +test(2139.46, vecseq(1L, NA, NA), error="len must be an integer vector") +test(2139.47, vecseq(1L, 1:2, NA), error="x and len must be the same length") +test(2139.48, vecseq(1L, 1L, 's'), error="clamp must be a double vector length 1") +test(2139.49, vecseq(1L, 1L, -1), error="clamp must be positive") + +test(2139.50, which_(1L, FALSE), error="Argument to 'which' must be logical") + +test(2139.51, melt(data.table(1), variable.name=1), error="Argument 'variable.name' must be a character vector") +test(2139.52, melt(data.table(1), value.name=1), error="Argument 'value.name' must be a character vector") + +DT1 = data.table(a=1) +DT2 = data.table(a=2) +test(2139.53, bmerge(DT1, DT2, 1, 1, roll = 'a', rollends = TRUE, verbose = TRUE, ops = NULL, nomatch = NULL, mult = 'all'), error="roll is character but not 'nearest'") + +test(2139.54, fsort(-1), error="Cannot yet handle negatives") + +test(2139.55, binary('a'), error="x must be type 'double'") diff --git a/src/assign.c b/src/assign.c index 1392079e72..4f57c383b7 100644 --- a/src/assign.c +++ b/src/assign.c @@ -4,12 +4,15 @@ static void finalizer(SEXP p) { SEXP x; R_len_t n, l, tl; - if(!R_ExternalPtrAddr(p)) error(_("Internal error: finalizer hasn't received an ExternalPtr")); // # nocov + if(!R_ExternalPtrAddr(p)) + error(_("Internal error: finalizer hasn't received an ExternalPtr")); // # nocov p = R_ExternalPtrTag(p); - if (!isString(p)) error(_("Internal error: finalizer's ExternalPtr doesn't see names in tag")); // # nocov + if (!isString(p)) + error(_("Internal error: finalizer's ExternalPtr doesn't see names in tag")); // # nocov l = LENGTH(p); tl = TRUELENGTH(p); - if (l<0 || tl0 but 0 but l) ? n : l); // e.g. test 848 and 851 in R > 3.0.2 // added (n>l) ? ... for #970, see test 1481. @@ -212,9 +221,12 @@ SEXP alloccol(SEXP dt, R_len_t n, Rboolean verbose) tl = TRUELENGTH(dt); // R <= 2.13.2 and we didn't catch uninitialized tl somehow - if (tl<0) error(_("Internal error, tl of class is marked but tl<0.")); // # nocov - if (tl>0 && tll+10000) warning(_("tl (%d) is greater than 10,000 items over-allocated (l = %d). If you didn't set the datatable.alloccol option to be very large, please report to data.table issue tracker including the result of sessionInfo()."),tl,l); + if (tl<0) + error(_("Internal error, tl of class is marked but tl<0.")); // # nocov + if (tl>0 && tll+10000) + warning(_("tl (%d) is greater than 10,000 items over-allocated (l = %d). If you didn't set the datatable.alloccol option to be very large, please report to data.table issue tracker including the result of sessionInfo()."),tl,l); if (n>tl) return(shallow(dt,R_NilValue,n)); // usual case (increasing alloc) if (n0) { - if (!isDataTable) error(_("set() on a data.frame is for changing existing columns, not adding new ones. Please use a data.table for that. data.table's are over-allocated and don't shallow copy.")); + if (!isDataTable) + error(_("set() on a data.frame is for changing existing columns, not adding new ones. Please use a data.table for that. data.table's are over-allocated and don't shallow copy.")); newcolnames = PROTECT(allocVector(STRSXP, k)); protecti++; for (i=0; i1; // initial value; may be revised below if (verbose) Rprintf(_("RHS_list_of_columns == %s\n"), RHS_list_of_columns ? "true" : "false"); if (TYPEOF(values)==VECSXP && length(cols)==1 && length(values)==1) { @@ -400,13 +419,21 @@ SEXP assign(SEXP dt, SEXP rows, SEXP cols, SEXP newcolnames, SEXP values) for (i=0; ioldncol+length(newcolnames)) { - if (!isDataTable) error(_("Item %d of column numbers in j is %d which is outside range [1,ncol=%d]. set() on a data.frame is for changing existing columns, not adding new ones. Please use a data.table for that."), i+1, coln, oldncol); - else error(_("Item %d of column numbers in j is %d which is outside range [1,ncol=%d]. Use column names instead in j to add new columns."), i+1, coln, oldncol); + if (!isDataTable) + error(_("Item %d of column numbers in j is %d which is outside range [1,ncol=%d]. set() on a data.frame is for changing existing columns, not adding new ones. Please use a data.table for that."), i+1, coln, oldncol); + else { + if (oldncol >= 1) { + error(_("Item %d of column numbers in j is %d which is outside range [1,ncol=%d]. Use column names instead in j to add new columns."), i+1, coln, oldncol); + } else { + error(_("Input data.table has no columns. Use column names in j instead to add new columns.")); + } + } } coln--; SEXP thisvalue = RHS_list_of_columns ? VECTOR_ELT(values, i) : values; vlen = length(thisvalue); - if (isNull(thisvalue) && !isNull(rows)) error(_("When deleting columns, i should not be provided")); // #1082, #3089 + if (isNull(thisvalue) && !isNull(rows)) + error(_("When deleting columns, i should not be provided")); // #1082, #3089 if (coln+1 <= oldncol) colnam = STRING_ELT(names,coln); else colnam = STRING_ELT(newcolnames,coln-length(names)); if (coln+1 <= oldncol && isNull(thisvalue)) continue; // delete existing column(s) afterwards, near end of this function @@ -444,10 +471,12 @@ SEXP assign(SEXP dt, SEXP rows, SEXP cols, SEXP newcolnames, SEXP values) oldtncol = TRUELENGTH(dt); // TO DO: oldtncol can be just called tl now, as we won't realloc here any more. if (oldtncololdncol+10000L) warning(_("truelength (%d) is greater than 10,000 items over-allocated (length = %d). See ?truelength. If you didn't set the datatable.alloccol option very large, please report to data.table issue tracker including the result of sessionInfo()."),oldtncol, oldncol); + if (oldtncol>oldncol+10000L) + warning(_("truelength (%d) is greater than 10,000 items over-allocated (length = %d). See ?truelength. If you didn't set the datatable.alloccol option very large, please report to data.table issue tracker including the result of sessionInfo()."),oldtncol, oldncol); if (oldtncol < oldncol+LENGTH(newcolnames)) error(_("Internal error: DT passed to assign has not been allocated enough column slots. l=%d, tl=%d, adding %d"), oldncol, oldtncol, LENGTH(newcolnames)); // # nocov if (!selfrefnamesok(dt,verbose)) @@ -466,7 +495,8 @@ SEXP assign(SEXP dt, SEXP rows, SEXP cols, SEXP newcolnames, SEXP values) coln = INTEGER(cols)[i]-1; SEXP thisvalue = RHS_list_of_columns ? VECTOR_ELT(values, i) : values; if (TYPEOF(thisvalue)==NILSXP) { - if (!isNull(rows)) error(_("Internal error: earlier error 'When deleting columns, i should not be provided' did not happen.")); // # nocov + if (!isNull(rows)) + error(_("Internal error: earlier error 'When deleting columns, i should not be provided' did not happen.")); // # nocov ndelete++; continue; // delete column(s) afterwards, below this loop } @@ -503,7 +533,8 @@ SEXP assign(SEXP dt, SEXP rows, SEXP cols, SEXP newcolnames, SEXP values) targetcol = VECTOR_ELT(dt,coln); } const char *ret = memrecycle(targetcol, rows, 0, targetlen, thisvalue, 0, -1, coln+1, CHAR(STRING_ELT(names, coln))); - if (ret) warning(ret); + if (ret) + warning(ret); } *_Last_updated = numToDo; // the updates have taken place with no error, so update .Last.updated now @@ -559,7 +590,8 @@ SEXP assign(SEXP dt, SEXP rows, SEXP cols, SEXP newcolnames, SEXP values) continue; // with next index } tc1 += 2; // tc1 always marks the start of a key column - if (!*tc1) error(_("Internal error: index name ends with trailing __")); // # nocov + if (!*tc1) + error(_("Internal error: index name ends with trailing __")); // # nocov // check the position of the first appearance of an assigned column in the index. // the new index will be truncated to this position. char *s4 = (char*) malloc(strlen(c1) + 3); @@ -810,7 +842,8 @@ const char *memrecycle(const SEXP target, const SEXP where, const int start, con SEXP s = sourceLevelsD[k]; int tl = TRUELENGTH(s); if (tl) { // tl negative here - if (tl != -nTargetLevels-thisAdd-1) error(_("Internal error: extra level check sum failed")); // # nocov + if (tl != -nTargetLevels-thisAdd-1) + error(_("Internal error: extra level check sum failed")); // # nocov temp[thisAdd++] = s; SET_TRUELENGTH(s,0); } @@ -1201,16 +1234,25 @@ void savetl_end() { nsaved = nalloc = 0; } +// Not exposed to users and only called from: +// [.data.table->.massageSD +// setnames SEXP setcharvec(SEXP x, SEXP which, SEXP newx) { - int w; - if (!isString(x)) error(_("x must be a character vector")); - if (!isInteger(which)) error(_("'which' must be an integer vector")); - if (!isString(newx)) error(_("'new' must be a character vector")); - if (LENGTH(newx)!=LENGTH(which)) error(_("'new' is length %d. Should be the same as length of 'which' (%d)"),LENGTH(newx),LENGTH(which)); + if (!isString(x)) + error(_("Internal error: x must be a character vector in setcharvec")); // # nocov + if (!isInteger(which)) + error(_("Internal error: 'which' must be an integer vector in setcharvec")); // # nocov + if (!isString(newx)) + error(_("Internal error: 'new' must be a character vector in setcharvec")); // # nocov + if (LENGTH(newx)!=LENGTH(which)) + error(_("Internal error: 'new' is length %d. Should be the same as length of 'which' (%d) in setcharvec"),LENGTH(newx),LENGTH(which)); // # nocov + int *wp = INTEGER(which); + int n = LENGTH(x); for (int i=0; iLENGTH(x)) error(_("Item %d of 'which' is %d which is outside range of the length %d character vector"), i+1,w,LENGTH(x)); + int w = wp[i]; + if (w==NA_INTEGER || w<1 || w>n) + error(_("Internal error: Item %d of 'which' is %d which is outside range of the length %d character vector in setcharvec"), i+1,w,LENGTH(x)); // # nocov SET_STRING_ELT(x, w-1, STRING_ELT(newx, i)); } return R_NilValue; diff --git a/src/bmerge.c b/src/bmerge.c index 15d7d6f4f7..6f07012561 100644 --- a/src/bmerge.c +++ b/src/bmerge.c @@ -45,33 +45,44 @@ SEXP bmerge(SEXP iArg, SEXP xArg, SEXP icolsArg, SEXP xcolsArg, SEXP isorted, SE // iArg, xArg, icolsArg and xcolsArg i = iArg; x = xArg; // set globals so bmerge_r can see them. - if (!isInteger(icolsArg)) error(_("Internal error: icols is not integer vector")); // # nocov - if (!isInteger(xcolsArg)) error(_("Internal error: xcols is not integer vector")); // # nocov - if (LENGTH(icolsArg) > LENGTH(xcolsArg)) error(_("Internal error: length(icols) [%d] > length(xcols) [%d]"), LENGTH(icolsArg), LENGTH(xcolsArg)); // # nocov + if (!isInteger(icolsArg)) + error(_("Internal error: icols is not integer vector")); // # nocov + if (!isInteger(xcolsArg)) + error(_("Internal error: xcols is not integer vector")); // # nocov + if (LENGTH(icolsArg) > LENGTH(xcolsArg)) + error(_("Internal error: length(icols) [%d] > length(xcols) [%d]"), LENGTH(icolsArg), LENGTH(xcolsArg)); // # nocov icols = INTEGER(icolsArg); xcols = INTEGER(xcolsArg); xN = LENGTH(x) ? LENGTH(VECTOR_ELT(x,0)) : 0; iN = ilen = anslen = LENGTH(i) ? LENGTH(VECTOR_ELT(i,0)) : 0; ncol = LENGTH(icolsArg); // there may be more sorted columns in x than involved in the join for(int col=0; colLENGTH(i) || icols[col]<1) error(_("icols[%d]=%d outside range [1,length(i)=%d]"), col, icols[col], LENGTH(i)); - if (xcols[col]>LENGTH(x) || xcols[col]<1) error(_("xcols[%d]=%d outside range [1,length(x)=%d]"), col, xcols[col], LENGTH(x)); + if (icols[col]==NA_INTEGER) + error(_("Internal error. icols[%d] is NA"), col); // # nocov + if (xcols[col]==NA_INTEGER) + error(_("Internal error. xcols[%d] is NA"), col); // # nocov + if (icols[col]>LENGTH(i) || icols[col]<1) + error(_("Internal error: icols[%d]=%d outside range [1,length(i)=%d]"), col, icols[col], LENGTH(i)); // # nocov + if (xcols[col]>LENGTH(x) || xcols[col]<1) + error(_("Internal error: xcols[%d]=%d outside range [1,length(x)=%d]"), col, xcols[col], LENGTH(x)); // # nocov int it = TYPEOF(VECTOR_ELT(i, icols[col]-1)); int xt = TYPEOF(VECTOR_ELT(x, xcols[col]-1)); - if (iN && it!=xt) error(_("typeof x.%s (%s) != typeof i.%s (%s)"), CHAR(STRING_ELT(getAttrib(x,R_NamesSymbol),xcols[col]-1)), type2char(xt), CHAR(STRING_ELT(getAttrib(i,R_NamesSymbol),icols[col]-1)), type2char(it)); + if (iN && it!=xt) + error(_("Internal error: typeof x.%s (%s) != typeof i.%s (%s)"), CHAR(STRING_ELT(getAttrib(x, R_NamesSymbol), xcols[col]-1)), type2char(xt), CHAR(STRING_ELT(getAttrib(i, R_NamesSymbol), icols[col]-1)), type2char(it)); // # nocov } // raise(SIGINT); // rollArg, rollendsArg roll = 0.0; rollToNearest = FALSE; if (isString(rollarg)) { - if (strcmp(CHAR(STRING_ELT(rollarg,0)),"nearest") != 0) error(_("roll is character but not 'nearest'")); - if (TYPEOF(VECTOR_ELT(i, icols[ncol-1]-1))==STRSXP) error(_("roll='nearest' can't be applied to a character column, yet.")); + if (strcmp(CHAR(STRING_ELT(rollarg,0)),"nearest") != 0) + error(_("roll is character but not 'nearest'")); + if (TYPEOF(VECTOR_ELT(i, icols[ncol-1]-1))==STRSXP) + error(_("roll='nearest' can't be applied to a character column, yet.")); roll=1.0; rollToNearest=TRUE; // the 1.0 here is just any non-0.0, so roll!=0.0 can be used later } else { - if (!isReal(rollarg)) error(_("Internal error: roll is not character or double")); // # nocov + if (!isReal(rollarg)) + error(_("Internal error: roll is not character or double")); // # nocov roll = REAL(rollarg)[0]; // more common case (rolling forwards or backwards) or no roll when 0.0 } rollabs = fabs(roll); @@ -99,7 +110,7 @@ SEXP bmerge(SEXP iArg, SEXP xArg, SEXP icolsArg, SEXP xcolsArg, SEXP isorted, SE // nqmaxgrpArg if (!isInteger(nqmaxgrpArg) || length(nqmaxgrpArg) != 1 || INTEGER(nqmaxgrpArg)[0] <= 0) - error(_("Intrnal error: nqmaxgrpArg is not a positive length-1 integer vector")); // # nocov + error(_("Internal error: nqmaxgrpArg is not a positive length-1 integer vector")); // # nocov nqmaxgrp = INTEGER(nqmaxgrpArg)[0]; if (nqmaxgrp>1 && mult == ALL) { // non-equi case with mult=ALL, may need reallocation @@ -153,7 +164,8 @@ SEXP bmerge(SEXP iArg, SEXP xArg, SEXP icolsArg, SEXP xcolsArg, SEXP isorted, SE // xo arg xo = NULL; if (length(xoArg)) { - if (!isInteger(xoArg)) error(_("Internal error: xoArg is not an integer vector")); // # nocov + if (!isInteger(xoArg)) + error(_("Internal error: xoArg is not an integer vector")); // # nocov xo = INTEGER(xoArg); } @@ -268,7 +280,8 @@ void bmerge_r(int xlowIn, int xuppIn, int ilowIn, int iuppIn, int col, int thisg case LT : xupp = xlow + 1; xlow = xlowIn; break; case GE : if (ival.i != NA_INTEGER) xupp = xuppIn; break; case GT : xlow = xupp - 1; if (ival.i != NA_INTEGER) xupp = xuppIn; break; - default : error(_("Internal error in bmerge_r for '%s' column. Unrecognized value op[col]=%d"), type2char(TYPEOF(xc)), op[col]); // #nocov + default : + error(_("Internal error in bmerge_r for '%s' column. Unrecognized value op[col]=%d"), type2char(TYPEOF(xc)), op[col]); // #nocov } // for LE/LT cases, we need to ensure xlow excludes NA indices, != EQ is checked above already if (op[col] <= 3 && xlowxuppIn) error(_("Internal error: xlow!=xupp-1 || xlowxuppIn")); // # nocov + if (xlow != xupp-1 || xlowxuppIn) + error(_("Internal error: xlow!=xupp-1 || xlowxuppIn")); // # nocov if (rollToNearest) { // value of roll ignored currently when nearest if ( (!lowmax || xlow>xlowIn) && (!uppmax || xupp