+ lineOffset <- charOffset <- colOffset <- NULL
+ for(pos in position) {
+ switch(as.character(pos[[1]]),
+ `:position` = {charOffset <- pos[[2]]},
+ `:line` = {lineOffset <- pos[[2]]; colOffset <- pos[[3]]},
+ warning("unknown content in pos", pos))
+ }
+ frob <- function(refs) {
+ lapply(refs,
+ function(x)
+ srcref(attr(x,"srcfile"),
+ c(x[1]+lineOffset-1, ifelse(x[1]==1, x[2]+colOffset-1, x[2]),
+ x[3]+lineOffset-1, ifelse(x[3]==1, x[4]+colOffset-1, x[4]),
+ ifelse(x[1]==1, x[5]+colOffset-1, x[5]),
+ ifelse(x[3]==1, x[6]+colOffset-1, x[6]))))
+ }
+ transformSrcrefs <- function(s) {
+ ## horrendous KLUDGE: we need to short-circuit here for "name"
+ ## objects, rather than having a nice uniform behaviour, because
+ ## for expressions of the form x[y,] there is an empty "name"
+ ## which ends up becoming a `missing' object when passed through
+ ## the switch; why, I do not know, but it is then impossible to
+ ## return it, because returning it attempts to evaluate it and
+ ## evaluating it is an error. Fortunately it appears that names
+ ## don't have srcrefs attached.
+ if(mode(s) == "name") {
+ return(s)
+ }
+ if(is(s, "srcref")) {
+ ## more monumental KLUDGE: parsing (in 2.14, at least) appears
+ ## to put srcrefs directly in `length 2' objects, which we need
+ ## to frob directly.
+ return(frob(list(s))[[1]])
+ }
+ srcrefs <- attr(s, "srcref")
+ attribs <- attributes(s)
+ new <-
+ switch(mode(s),
+ "call"=as.call(lapply(s, transformSrcrefs)),
+ "expression"=as.expression(lapply(s, transformSrcrefs)),
+ s)
+ attributes(new) <- attribs
+ if(!is.null(attr(s, "srcref"))) {
+ attr(new, "srcref") <- frob(srcrefs)
+ }
+ if(!is.null(attr(s, "wholeSrcref"))) {
+ attr(new, "wholeSrcref") <- frob(list(attr(s, "wholeSrcref")))[[1]]
+ }
+ new
+ }
+ withRestarts({
+ times <- system.time({
+ exprs <- parse(text=string, srcfile=srcfile(filename))
+ eval(transformSrcrefs(exprs), envir = globalenv()) })},