Skip to content

Commit

Permalink
reimplement identifying files with a trailing return as having a newl…
Browse files Browse the repository at this point in the history
…ine (#78)
  • Loading branch information
cjyetman authored Feb 2, 2024
1 parent de388a7 commit c089e73
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 27 deletions.
37 changes: 11 additions & 26 deletions R/has_newline_at_end.R
Original file line number Diff line number Diff line change
Expand Up @@ -9,36 +9,21 @@ file_has_newline_at_end <- function(filepath) {
if (!is_file_accessible(filepath) || !is_text_file(filepath)) {
return(NA)
}
if (.Platform$OS.type == "unix") {
newlines_in_final_char <- system(
command = paste(
"tail -c1 ", filepath, # tail -c1 returns last 1 byte
" | ", # pipe to next command
"wc -l" # wc -l returns number of newline characters in input
),
intern = TRUE
)
has_trailing_newline <- as.logical(as.integer(newlines_in_final_char))
} else {
# Windows does not have a POSIX compliant `tail` command
# so we use builtin R functionality, which is slower
con <- file(filepath, "rb")
on.exit(close(con))

not_at_end <- TRUE
chars <- ""
while (not_at_end) {
prev_chars <- chars
chars <- readChar(con, nchars = 2048L, useBytes = TRUE)
if (length(chars) == 0L) {
not_at_end <- FALSE
}
con <- file(filepath, "rb")
on.exit(close(con))

not_at_end <- TRUE
chars <- ""
while (not_at_end) {
prev_chars <- chars
chars <- readChar(con, nchars = 2048L, useBytes = TRUE)
if (length(chars) == 0L) {
not_at_end <- FALSE
}

has_trailing_newline <- grepl(
# using [\n] instead of [\n\r] because modern systems use either \n or
# \r\n as newline, both of which match \n as last character.
"[\n]$", iconv(prev_chars, to = "UTF-8", sub = "")
"[\n\r]$", iconv(prev_chars, to = "UTF-8", sub = "")
)

}
Expand Down
2 changes: 1 addition & 1 deletion tests/testthat/test-has_newline_at_end.R
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ test_that("has_newline_at_end identifies trailing return", {
trailing_return <- withr::local_tempfile()
writeChar("A,B\r1,2\r", trailing_return, eos = NULL)
expect_true(tail(readBin(trailing_return, what = "raw", n = 10), n = 1) == charToRaw("\r"))
expect_false(has_newline_at_end(trailing_return))
expect_true(has_newline_at_end(trailing_return))
})

test_that("has_newline_at_end identifies trailing return and newline", {
Expand Down

0 comments on commit c089e73

Please sign in to comment.