# package to manage breakpoints with trace(), browser() # breaks will be a list, indexed by quoted the names of the functions being # debugged; breaks[["f"]] is then a vector of current breakpoints of # f(); note that these are "step numbers" in R terminology, differing # from line numbers within the function in that comments don't count and # blocks count as just one step breaks <- list() # set a breakpoint using trace() # note: quotedftnname must be a quoted string! setbp <- function(quotedftnname,stepnums) trace(quotedftnname,browser,at=stepnums) # bk() changes the current breakpoint set of the function quotedftnname, # adding breakpoints at the steps specfied by toadd, and deleting those # specfied by todel; if wipe is TRUE, then all breakpoints for this # function are deleted, overriding toadd and todel, and calling # untrace() on the function; example: # bk("g",c(5,8),12) # will add breakpoints at steps 5 and 8 of g() while deleting the one at 12 bk <- function(quotedftnname,toadd=NULL,todel=NULL,wipe=F) { if (wipe) { breaks[[quotedftnname]] <<- NULL untrace(quotedftnname) return() } # since each call to trace() nullifies previous such actions, we must # update our breakpoint list, then call trace() with the new list if (!is.null(toadd)) breaks[[quotedftnname]] <<- c(breaks[[quotedftnname]],toadd) if (!is.null(todel)) breaks[[quotedftnname]] <<- setdiff(breaks[[quotedftnname]],todel) setbp(quotedftnname,breaks[[quotedftnname]]) } # list step numbers (for use as "at" in trace()) lssns <- function(ftnname) as.list(body(ftnname))