Created
March 11, 2013 15:27
-
-
Save mllg/5135021 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env Rscript | |
### Toggle debug blocks on and off in a fashion of a pre-processor | |
# usage: toggle_debug [uri] [on|off] | |
# | |
# Argument uri can be a single file or directory. | |
# In case of a directory, the script processes all ".[rR]$" files inside and | |
# only writes changes if processing is successful for all files found. | |
# | |
# Debug blocks start with the comment "BDEBUG" and end with "EDEBUG" | |
# Toggled off code is preceded with "#DEBUG# ". | |
# | |
# Note that this script does not work nice with tabs. | |
# If any tabs are found, they are converted to option [tab.width] spaces. | |
# Setting your editor to spaces is highly recommended. | |
### Options | |
# FIXME: maybe allow more options like comment.str | |
tab.width = as.integer(2) | |
tabs2spaces = function(x) { | |
gsub("\t", collapse(rep(" ", tab.width), ""), x) | |
} | |
getIndentInfo = function(x) { | |
indent = tabs2spaces(sub("^([[:blank:]]*).*", "\\1", x)) | |
list(string = indent, count = nchar(indent)) | |
} | |
addComment = function(x, indent, comment.str = "#DEBUG# ") { | |
paste0(indent$string, comment.str, x) | |
} | |
rmComment = function(x, comment.str = "#DEBUG# ") { | |
sub(paste0("^[[:space:]]*", comment.str, "(.*)"), "\\1", x) | |
} | |
is.commented = function(x, comment.str = "#DEBUG# ") { | |
grepl(comment.str, x, fixed = TRUE) | |
} | |
toggle_debug = function(fn, action = "on", dry = FALSE) { | |
src = readLines(fn) | |
fname = basename(fn) | |
in.debug = FALSE | |
last.block = 0L | |
for (ln in seq_along(src)) { | |
line = src[ln] | |
if (grepl("^[[:blank:]]*#+[[:blank:]]*[BE]DEBUG[[:space:]]*$", line)) { | |
if (grepl("BDEBUG", line, fixed = TRUE)) { | |
if (in.debug) | |
stopf("Error in '%s' (%i): Tried to open new debug block before closing previous block starting in line %i", | |
fname, ln, last.block) | |
in.debug = TRUE | |
last.block = ln | |
indent = getIndentInfo(line) | |
} else { | |
if (!in.debug) | |
stopf("Error in '%s' (%i): Tried to close debug block before opening it", | |
fname, ln, last.block) | |
in.debug = FALSE | |
} | |
} else if (in.debug) { | |
if (action == "on") { | |
if (is.commented(line)) | |
stopf("Parts of file '%s' are already commented out, e.g. line %i", fname, ln) | |
src[ln] = addComment(line, indent) | |
} else { | |
if (!is.commented(line)) | |
stopf("Parts of file '%s' are not commented out, e.g. line %i", fname, ln) | |
src[ln] = rmComment(line) | |
} | |
} | |
} | |
if (in.debug) | |
stopf("Error in '%s': EOF reached, debug block starting in line %i not closed", | |
fname, last.block) | |
if (last.block > 0L && !dry) | |
writeLines(src, con = fn) | |
invisible(list(src = src, touched = last.block > 0L)) | |
} | |
library(BBmisc) | |
argv = commandArgs(trailingOnly = TRUE) | |
if (length(argv) != 2L || !(argv[2L] %in% c("on", "off"))) | |
stop("Usage: toggle_debug [uri] [on|off]") | |
uri = argv[1L] | |
action = argv[2L] | |
if (! file.exists(uri)) | |
stopf("Could not open '%s'", uri) | |
if (file_test("-d", uri)) { | |
files = list.files(uri, pattern = "\\.R$", ignore.case = TRUE, full.names = TRUE) | |
src = lapply(files, toggle_debug, action = action, dry = TRUE) | |
ind = extractSubList(src, "touched") | |
res = mapply(writeLines, | |
text = extractSubList(src[ind], "src", simplify = FALSE), | |
con = files[ind]) | |
} else { | |
toggle_debug(uri, action) | |
} | |
invisible(0L) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment