diff --git a/R/engine_batch.R b/R/engine_batch.R index e1845b7..18afd6f 100644 --- a/R/engine_batch.R +++ b/R/engine_batch.R @@ -448,15 +448,18 @@ rta_parse_write_table <- function(tok) { c <- tail_next_char(t) if (c != ",") stop_batch(", expected; not a ", c) + # Multiple options form one series token (legacy writeTableBatch): + # the token is chomped in 2-letter code + sign chunks until empty. options <- character(0) - repeat { - hs <- toupper(tail_next_token(t)) - if (hs == "") break - if (nchar(hs) < 3L) stop_batch("Unknown option (", hs, ")") + hs <- toupper(tail_next_token(t)) + while (nzchar(hs)) { + if (nchar(hs) < 2L) stop_batch("Unknown option (", hs, ")") opt <- substring(hs, 1L, 2L) - sign <- substring(hs, 3L, 3L) + hs <- trimws(substring(hs, 3L)) + sign <- substring(hs, 1L, 1L) if (!(sign %in% c("+", "-"))) stop_batch("+ or - expected; not a ", sign) + hs <- trimws(substring(hs, 2L)) options <- c(options, paste0(sign, opt)) } diff --git a/tests/testthat/test_engine_parse.R b/tests/testthat/test_engine_parse.R index cadd011..68db46e 100644 --- a/tests/testthat/test_engine_parse.R +++ b/tests/testthat/test_engine_parse.R @@ -142,6 +142,26 @@ test_that("WRITETABLE grammar: options, empty-options form and type bounds", { expect_error(rtauargus.native:::parse_batch(p3), class = "BatchError") }) +test_that("WRITETABLE option series: multiple options in one token", { + # Legacy writeTableBatch (batch.java) reads one option token and + # chomps it in 2-letter code + sign chunks, so AS+AR+ is a series of + # two options. The port must keep every option, not silently drop + # all but the first. + p <- local_arb(c(' (1, 5, AS+AR+, "out.tab")')) + cmd <- rtauargus.native:::parse_batch(p)[[1]] + expect_equal(cmd$options, c("+AS", "+AR")) + expect_equal(cmd$file, "out.tab") + + p2 <- local_arb(c(' (1, 5, AS+AR+SO-, "out.tab")')) + cmd2 <- rtauargus.native:::parse_batch(p2)[[1]] + expect_equal(cmd2$options, c("+AS", "+AR", "-SO")) + expect_equal(cmd2$file, "out.tab") + + # a sign-less tail of the series is an error, not a silent drop + p3 <- local_arb(c(' (1, 5, AS+AR, "out.tab")')) + expect_error(rtauargus.native:::parse_batch(p3), class = "BatchError") +}) + test_that("READTABLE flags are parsed", { # READTABLE is only allowed in table-input position (after the data, # metadata and table specification)