> # test.dots.R
> 
> source("test.prolog.R")
> 
> cat0("=== test dotindex\n")
=== test dotindex
> 
> test.dotindex <- function(expected, ARGNAME, ..., EX=FALSE)
+ {
+     dotindex <- plotmo:::dotindex(ARGNAME=ARGNAME, EX=EX, ...)
+     stopifnot(all.equal(dotindex, expected))
+ }
> test.dotindex(NA, "x") # empty dots
> test.dotindex(NA, "x",  a=10, b=20)
> test.dotindex(1,  "a",  a=10, b=20)
> test.dotindex(2,  "b",  a=10, b=20)
> test.dotindex(1,  "a1", a=10, b=20)
> test.dotindex(NA, "a",  a1=10, a2=20)
> expect.err(try(test.dotindex(1, nonesuch, a=10, a=20)), "object 'nonesuch' not found")
Error : object 'nonesuch' not found
Got expected error from try(test.dotindex(1, nonesuch, a = 10, a = 20))
> expect.err(try(test.dotindex(1, "a1", a=10, a=20)), "argument 'a' for test.dotindex() is duplicated")
Error : argument 'a' for test.dotindex() is duplicated
Got expected error from try(test.dotindex(1, "a1", a = 10, a = 20))
> expect.err(try(test.dotindex(1, "aa1", a=10, aa=20)), "arguments 'a' and 'aa' both match 'aa1' in test.dotindex")
Error : arguments 'a' and 'aa' both match 'aa1' in test.dotindex
Got expected error from try(test.dotindex(1, "aa1", a = 10, aa = 20))
> stopifnot(is.na(plotmo:::dotindex("a", EX=1, a1=10, a2=20)))
> stopifnot(plotmo:::dotindex("a2", EX=1, a1=10, a2=20) == 2)
> 
> # multiple argnames
> test.dotindex(NA, c("a", "b")) # empty dots
> test.dotindex(1,  c("a", "b"), a=2, c=3)
> test.dotindex(1,  c("a", "b"), a=5, b=6)
> test.dotindex(2,  c("a", "b"), x=1, a=5, b=6)
> test.dotindex(3,  c("b,a"), x=1, a=5, b=6)
> test.dotindex(1,  c("a b"), b=3, c=4)
> test.dotindex(2,  c(" a b "), c=3, b=4)
> test.dotindex(NA, c("a", "b"), c=3)
> stopifnot(plotmo:::dotindex(c("x", "a1"), EX=1, a1=10, a2=20) == 1)
> 
> test.dota <- function(expected, ARGNAME, ..., DEF=NA, EX=FALSE)
+ {
+     if(is.na(DEF))
+         dot <- plotmo:::dota(ARGNAME, EX=EX, ...)
+     else
+         dot <- plotmo:::dota(ARGNAME, EX=EX, DEF=DEF, ...)
+     stopifnot(all.equal(dot, expected))
+ }
> cat0("=== test dot\n")
=== test dot
> test.dota(NA, "x") # empty dots
> test.dota(NA, "x",  a=10, b=20)
> test.dota(10, "a",  a=10, b=20)
> test.dota(20, "b",  a=10, b=20)
> test.dota(99, DEF=99, "nonesuch", a=10, b=20)
> test.dota(NA, "a", a1=10, a2=20)
> expect.err(try(test.dota(1, "a1", a=10, a=20)), "argument 'a' for test.dota() is duplicated")
Error : argument 'a' for test.dota() is duplicated
Got expected error from try(test.dota(1, "a1", a = 10, a = 20))
> expect.err(try(test.dota(1, 99, a=10, a=20)), "is.character(argname) is not TRUE")
Error in process.argname(ARGNAME) : is.character(argname) is not TRUE
Got expected error from try(test.dota(1, 99, a = 10, a = 20))
> expect.err(try(test.dota(1, test.dota, a=10, a=20)), "is.character(argname) is not TRUE")
Error in process.argname(ARGNAME) : is.character(argname) is not TRUE
Got expected error from try(test.dota(1, test.dota, a = 10, a = 20))
> expect.err(try(test.dota(1, "", a=10, a=20)), "empty string in ARGNAME")
Error : empty string in ARGNAME
Got expected error from try(test.dota(1, "", a = 10, a = 20))
> expect.err(try(test.dota(1, "x^x", a=10, a=20)), "illegal character \"^\" in ARGNAME")
Error : illegal character "^" in ARGNAME = "x^x"
Got expected error from try(test.dota(1, "x^x", a = 10, a = 20))
> 
> test.dota(10, "abc", EX=T, abc=10)
> test.dota(NA, "a",   EX=T, a1=10, a2=20)
> expect.err(try(test.dota(1, "a1", a1=10, a1=20)), "argument 'a1' for test.dota() is duplicated")
Error : argument 'a1' for test.dota() is duplicated
Got expected error from try(test.dota(1, "a1", a1 = 10, a1 = 20))
> 
> stopifnot(is.na(plotmo:::dota("a", EX=1, a1=1, a2=2)))
> stopifnot(plotmo:::dota("a2", EX=1, a1=10, a2=20, a3=30) == 20)
> 
> foo <- function(func, x) func(x)
> foo(mean, 33)
[1] 33
> foo(function(...) plotmo:::dota("x", ...), 33)
[1] NA
> foo(function(...) plotmo:::dota("x99", ...), 33)
[1] NA
> foo(function(...) { plotmo:::dota("nonesuch", ...) }, 33)
[1] NA
> 
> test.dota(1,  "a", EX=T, a=1)
> test.dota(2,  "b", EX=T, a=1, b=2, c=3)
> test.dota(NA, "x", EX=T, a=1, b=2, c=3)
> test.dota(2,  "a", EX=T, ab=1, a=2)
> test.dota(2,  "a", EX=T, aa=1, a=2)
> test.dota(NA, "a", EX=T, aa=1, ab=2)
> expect.err(try(test.dota(2, "a", EX=T, aa=1, a=2, a=3)), "argument 'a' for test.dota() is duplicated")
Error : argument 'a' for test.dota() is duplicated
Got expected error from try(test.dota(2, "a", EX = T, aa = 1, a = 2, a = 3))
> 
> expect.err(try(test.dota(2, "a", EX=T, a=none.such)), "cannot evaluate 'a'")
Error : object 'none.such' not found
Error : cannot evaluate 'a'
Got expected error from try(test.dota(2, "a", EX = T, a = none.such))
> 
> # multiple argnames
> test.dota(2,  c("a", "b"), a=2, c=3)
> test.dota(5,  c("a", "b"), a=5, b=6)
> test.dota(5,  c("a", "b"), x=1, a=5, b=6)
> test.dota(3,  c("a", "b"), b=3, c=4)
> test.dota(4,  c("a", "b"), c=3, b=4)
> test.dota(NA, c("a", "b"), c=3)
> expect.err(try(test.dota(1, c("b", "aa1"), a=10, aa=20)), "arguments 'a' and 'aa' both match 'aa1' in test.dota")
Error : arguments 'a' and 'aa' both match 'aa1' in test.dota
Got expected error from try(test.dota(1, c("b", "aa1"), a = 10, aa = 20))
> expect.err(try(test.dota(1, c("x", ""), a=10, b=20)), "empty string in ARGNAME")
Error : empty string in ARGNAME
Got expected error from try(test.dota(1, c("x", ""), a = 10, b = 20))
> stopifnot(plotmo:::dota(c("x", "a2", "y"), EX=1, a1=10, a2=20, a3=30) == 20)
> 
> test.dota(NA, c("a", "b"), aa=2, cc=3, EX=T)
> test.dota(2,  c("aa", "b"), aa=2, cc=3, EX=T)
> test.dota(3,  c("bb", "b"), bb=3, cc=4, EX=T)
> test.dota(NA, c("a", "b"), c=3, EX=T)
> 
> foo.x <- function(...) { plotmo:::dota("x", ..., DEF="default", EX=FALSE) }
> stopifnot(foo.x(x=3) == 3)
> stopifnot(foo.x(y=3) == "default")
> 
> foo2 <- function(funcarg, ...) funcarg(...)
> stopifnot(is.na(foo2(function(...) plotmo:::dota("x", ...), 3))) # 3 is unnamed
> stopifnot(foo2(function(...) plotmo:::dota("x", EX=0, ...), x=3) == 3)
> stopifnot(foo2(function(...) plotmo:::dota("x99", EX=0, ...), x=3) == 3)
> stopifnot(foo2(function(...) { plotmo:::dota("x", DEF="default", EX=FALSE, ...) }, x=3) == 3)
> stopifnot(foo2(function(...) { plotmo:::dota("y", DEF="default", EX=FALSE, ...) }, x=3) == "default")
> # expect.err(try(foo2(function(...) { plotmo:::dota("y", DEF="default", EX=FALSE, ...) }, 3)), "unnamed arguments in ... are not allowed for funcarg()")
> 
> stopifnot(foo2(foo.x, x=3) == 3)
> stopifnot(foo2(foo.x, y=3) == "default")
> 
> test.is.dot <- function(expected, ARGNAME, ...)
+ {
+     present <- plotmo:::is.dot(ARGNAME, ...)
+     stopifnot(all.equal(present, expected))
+ }
> cat0("=== test is.dot\n")
=== test is.dot
> test.is.dot(FALSE, "x") # empty dots
> test.is.dot(FALSE, "x",  EX=0, a=10, b=20)
> test.is.dot(TRUE,  "a",  EX=0, a=10, b=20)
> test.is.dot(TRUE,  "b",  EX=0, a=10, b=20)
> test.is.dot(TRUE,  "a1", EX=0, a=10, b=20)
> test.is.dot(FALSE, "a",  EX=0, a1=10, a2=20)
> expect.err(try(test.is.dot(TRUE, "a1", EX=0, a=10, a=20)), "argument 'a' for test.is.dot() is duplicated")
Error : argument 'a' for test.is.dot() is duplicated
Got expected error from try(test.is.dot(TRUE, "a1", EX = 0, a = 10, a = 20))
> expect.err(try(test.is.dot(TRUE, "a", EX=0, a=10, a=20)), "argument 'a' for test.is.dot() is duplicated")
Error : argument 'a' for test.is.dot() is duplicated
Got expected error from try(test.is.dot(TRUE, "a", EX = 0, a = 10, a = 20))
> stopifnot(plotmo:::is.dot("a",  EX=1, a1=10, a2=20, a3=30) == FALSE)
> stopifnot(plotmo:::is.dot("x",  EX=1, a1=10, a2=20, a3=30) == FALSE)
> stopifnot(plotmo:::is.dot("a3", EX=1, a1=10, a2=20, a3=30) == TRUE)
> 
> # multiple argnames
> test.is.dot(TRUE,  EX=0, c("a1", "b1"), a=2, c=3)
> test.is.dot(TRUE,  EX=0, c("a1", "b1"), b=3, c=4)
> test.is.dot(TRUE,  EX=0, c("a1", "b1"), c=3, b=4)
> test.is.dot(FALSE, EX=0, c("a1", "b1"), c=3)
> expect.err(try(test.is.dot(FALSE, c("aa1", "b"), EX=0, a=10, aa=20)), "arguments 'a' and 'aa' both match 'aa1' in test.is.dot")
Error : arguments 'a' and 'aa' both match 'aa1' in test.is.dot
Got expected error from try(test.is.dot(FALSE, c("aa1", "b"), EX = 0, a = 10, aa = 20))
> stopifnot(plotmo:::is.dot(c("x", "a", "y"), EX=1, a1=10, a2=20, a3=30) == FALSE)
> stopifnot(plotmo:::is.dot(c("x", "a2", "y"), EX=1, a1=10, a2=20, a3=30) == TRUE)
> 
> cat0("=== test expand.drop\n")
=== test expand.drop
> 
> # nchar is used an example func, it has formals "x", "type", "allowNA"
> 
> stopifnot(is.null(plotmo:::expand.drop(NULL, prefix="prefix.", func=nchar)))
> 
> stopifnot(plotmo:::expand.drop("a", prefix="prefix.", func=nchar) == ">PREFIX|>EXPLICIT|^a")
> 
> stopifnot(plotmo:::expand.drop("a", prefix="prefix.", func=nchar, include.standard.prefixes=TRUE) == ">STANDARDPREFIXES|^force\\.|^def\\.|^drop\\.|>PREFIX|^prefix\\.|>EXPLICIT|^a")
> 
> stopifnot(plotmo:::expand.drop("FORMALS", prefix="prefix.", func=base::nchar) == ">FORMALS|^x|^type|^allowNA|^keepNA|>PREFIX|>EXPLICIT")
> 
> stopifnot(plotmo:::expand.drop("FORMALS", prefix="prefix.", func=base::nchar, include.standard.prefixes=TRUE) == ">FORMALS|^x|^type|^allowNA|^keepNA|>STANDARDPREFIXES|^force\\.|^def\\.|^drop\\.|>PREFIX|^prefix\\.|>EXPLICIT")
> 
> expect.err(try(plotmo:::expand.drop("FORMALS", prefix="prefix.", func=NULL)), "\"FORMALS\" specified in DROP, but FUNC is NULL")
Error : "FORMALS" specified in DROP, but FUNC is NULL
Got expected error from try(plotmo:::expand.drop("FORMALS", prefix = "prefix.", func = NULL))
> 
> expect.err(try(plotmo:::expand.drop("FORMALS", prefix="prefix.", func=base::c)), "\"FORMALS\" specified but formals(FUNC) returned no formal arguments")
Error : "FORMALS" specified but formals(FUNC) returned no formal arguments
Got expected error from try(plotmo:::expand.drop("FORMALS", prefix = "prefix.", func = base::c))
> 
> foo99 <- function(...) NULL
> expect.err(try(plotmo:::expand.drop("FORMALS", prefix="prefix.", func=foo99)), "\"FORMALS\" specified but formals(FUNC) returned only \"...\"")
Error : "FORMALS" specified but formals(FUNC) returned only "..."
Got expected error from try(plotmo:::expand.drop("FORMALS", prefix = "prefix.", func = foo99))
> 
> stopifnot(plotmo:::expand.drop("a,FORMALS", prefix="prefix.", func=base::nchar) == ">FORMALS|^x|^type|^allowNA|^keepNA|>PREFIX|>EXPLICIT|^a")
> 
> stopifnot(plotmo:::expand.drop("a,FORMALS", prefix="prefix.", func=base::nchar, include.standard.prefixes=TRUE) == ">FORMALS|^x|^type|^allowNA|^keepNA|>STANDARDPREFIXES|^force\\.|^def\\.|^drop\\.|>PREFIX|^prefix\\.|>EXPLICIT|^a")
> 
> expect.err(try(plotmo:::expand.drop("", prefix="prefix.", func=base::nchar)), "DROP is an empty string")
Error : DROP is an empty string
Got expected error from try(plotmo:::expand.drop("", prefix = "prefix.", func = base::nchar))
> 
> stopifnot(plotmo:::expand.drop("a", prefix="lines.", func=base::nchar) == ">PREFIX|>EXPLICIT|^a")
> 
> stopifnot(plotmo:::expand.drop("a", "lines.a", prefix="lines.", func=base::nchar, include.standard.prefixes=TRUE) == ">STANDARDPREFIXES|^force\\.|^def\\.|^drop\\.|>PREFIX|^lines\\.|>EXPLICIT|^a")
> 
> stopifnot(plotmo:::expand.drop("a*", prefix="lines.", func=base::nchar) == ">PREFIX|>EXPLICIT|^a.*")
> 
> stopifnot(plotmo:::expand.drop("a.*", prefix="lines.", func=base::nchar) == ">PREFIX|>EXPLICIT|^a\\..*")
> 
> stopifnot(plotmo:::expand.drop("a$", prefix="lines.", func=base::nchar) == ">PREFIX|>EXPLICIT|^a$")
> 
> stopifnot(plotmo:::expand.drop("a$,b*,c*$", prefix="lines.", func=base::nchar) == ">PREFIX|>EXPLICIT|^a$|^b.*|^c.*$")
> 
> stopifnot(plotmo:::expand.drop(c("a", "b,c", " d e$ f ", "g h$, i"), prefix="lines.", func=base::nchar) ==
+ ">PREFIX|>EXPLICIT|^a|^b|^c|^d|^e$|^f|^g|^h$|^i")
> 
> stopifnot(plotmo:::expand.drop("PLOT.ARGS", prefix="lines.", func=base::nchar) ==
+ ">PREFIX|>EXPLICIT|>PLOT_ARGS|^add$|^adj$|^bty$|^cex$|^cex\\.axis$|^cex\\.lab$|^cex\\.main$|^cex\\.sub$|^col$|^col\\.axis$|^col\\.lab$|^col\\.main$|^col\\.sub$|^crt$|^family$|^font$|^font$|^font\\.axis$|^font\\.lab$|^font\\.main$|^font\\.sub$|^lend$|^ljoin$|^lmitre$|^lty$|^lwd$|^main$|^pch$|^srt$|^xaxp$|^xaxs$|^xaxt$|^xlab$|^xlim$|^xlog$|^xpd$|^yaxp$|^yaxs$|^yaxt$|^ylab$|^ylim$|^ylog$")
> 
> stopifnot(plotmo:::expand.drop("abc,PLOT.ARGS", prefix="lines.", func=base::nchar) ==
+ ">PREFIX|>EXPLICIT|^abc|>PLOT_ARGS|^add$|^adj$|^bty$|^cex$|^cex\\.axis$|^cex\\.lab$|^cex\\.main$|^cex\\.sub$|^col$|^col\\.axis$|^col\\.lab$|^col\\.main$|^col\\.sub$|^crt$|^family$|^font$|^font$|^font\\.axis$|^font\\.lab$|^font\\.main$|^font\\.sub$|^lend$|^ljoin$|^lmitre$|^lty$|^lwd$|^main$|^pch$|^srt$|^xaxp$|^xaxs$|^xaxt$|^xlab$|^xlim$|^xlog$|^xpd$|^yaxp$|^yaxs$|^yaxt$|^ylab$|^ylim$|^ylog$")
> 
> stopifnot(plotmo:::expand.drop("abc,FORMALS,PLOT.ARGS", prefix="lines.", func=base::nchar) ==
+ ">FORMALS|^x|^type|^allowNA|^keepNA|>PREFIX|>EXPLICIT|^abc|>PLOT_ARGS|^add$|^adj$|^bty$|^cex$|^cex\\.axis$|^cex\\.lab$|^cex\\.main$|^cex\\.sub$|^col$|^col\\.axis$|^col\\.lab$|^col\\.main$|^col\\.sub$|^crt$|^family$|^font$|^font$|^font\\.axis$|^font\\.lab$|^font\\.main$|^font\\.sub$|^lend$|^ljoin$|^lmitre$|^lty$|^lwd$|^main$|^pch$|^srt$|^xaxp$|^xaxs$|^xaxt$|^xlab$|^xlim$|^xlog$|^xpd$|^yaxp$|^yaxs$|^yaxt$|^ylab$|^ylim$|^ylog$")
> 
> stopifnot(plotmo:::expand.drop("abc,FORMALS,PAR.ARGS", prefix="lines.", func=base::nchar) ==
+ ">FORMALS|^x|^type|^allowNA|^keepNA|>PREFIX|>EXPLICIT|^abc|>PAR_ARGS|^adj$|^ann$|^ask$|^bg$|^bty$|^cex$|^cex\\.axis$|^cex\\.lab$|^cex\\.main$|^cex\\.sub$|^col\\.axis$|^col\\.lab$|^col\\.main$|^col\\.sub$|^crt$|^err$|^family$|^fg$|^fig$|^fin$|^font$|^font\\.axis$|^font\\.lab$|^font\\.main$|^font\\.sub$|^lab$|^las$|^lend$|^lheight$|^ljoin$|^lmitre$|^lty$|^mai$|^mar$|^mex$|^mfcol$|^mfg$|^mfrow$|^mgp$|^mkh$|^new$|^oma$|^omd$|^omi$|^pch$|^pin$|^plt$|^ps$|^pty$|^srt$|^tck$|^tcl$|^usr$|^xaxp$|^xaxs$|^xaxt$|^xlog$|^xpd$|^yaxp$|^yaxs$|^yaxt$|^ylbias$|^ylog$")
> 
> stopifnot(plotmo:::expand.drop("abc,FORMALS,PLOTMO.ARGS", prefix="lines.", func=base::nchar) ==
+ ">FORMALS|^x|^type|^allowNA|^keepNA|>PREFIX|>EXPLICIT|^abc|>PLOTMO_ARGS|^caption\\.|^cex\\.|^col\\.|^contour\\.|^cum\\.|^degree1\\.|^degree2\\.|^density\\.|^filled\\.contour\\.|^font\\.|^func\\.|^grid\\.|^heatmap\\.|^image\\.|^jitter\\.|^legend\\.|^label\\.|^level\\.|^line\\.|^lines\\.|^lty\\.|^lty\\.|^lwd\\.|^main\\.|^mtext\\.|^nresiduals|^par\\.|^pch\\.|^persp\\.|^plot\\.|^plotmath\\.|^prednames\\.|^qq\\.|^qqline\\.|^pt\\.|^response\\.|^rug\\.|^smooth\\.|^text\\.|^title\\.|^vfont\\.")
> 
> test.deprefix <- function(expected, ..., FNAME="test.deprefix", KEEP=NULL)
+ {
+     args <- plotmo:::deprefix(..., FNAME=FNAME, KEEP=KEEP, CALLARGS="")
+     # can't use all.equal because it complains about names
+     # cat("args:\n")
+     # print(args)
+     # cat("expected:\n")
+     # print(expected)
+     stopifnot(length(args) == length(expected))
+     for(i in seq_len(length(expected))) {
+         stopifnot(names(args)[i] == names(expected)[i])
+         stopifnot(args[[i]] == expected[[i]])
+     }
+ }
> cat0("=== test deprefix\n")
=== test deprefix
> 
> test.deprefix(
+     expected=list(a=1, b=2), DROP="*",
+     PREFIX="predict.", def.a=1, predict.b=2, c=3)
> 
> test.deprefix(TRACE=2,
+     expected=list(b="predict.b", d="def.d", c="predict.c", e="predict.e"),
+     PREFIX="predict.", DROP="*",
+     a="a", b="b", c="c", w1.xlab="xlab",
+     def.b="def.b", def.d="def.d",
+     predict.b="predict.b", predict.c="predict.c", predict.e="predict.e")
TRACE higher.caller.to.deprefix called higher.caller.to.deprefix(test.deprefix,
                         FNAME="test.deprefix", a="a", b="b", c="c",
                         w1.xlab="xlab", def.b="def.b", def.d="def.d",
                         predict.b="predict.b", predict.c="predict.c",
                         predict.e="predict.e")
PREFIX predict.
DROP .*
KEEP ^force.|^def.|^predict.
input dotnames       a b c w1.xlab def.b def.d predict.b predict.c predict.e
after DROP and KEEP  def.b def.d predict.b predict.c predict.e
return dotnames      b d c e

> 
> test.deprefix(TRACE=2,
+     expected=list(b="predict.b", d="def.d", a="a", c="predict.c", e="predict.e"),
+     KEEP=NULL, PREFIX="predict.", DROP="w1.",
+     a="a", b="b", c="c", w1.xlab="xlab",
+     def.b="def.b", def.d="def.d",
+     predict.b="predict.b", predict.c="predict.c", predict.e="predict.e")
TRACE higher.caller.to.deprefix called higher.caller.to.deprefix(test.deprefix,
                         FNAME="test.deprefix", a="a", b="b", c="c",
                         w1.xlab="xlab", def.b="def.b", def.d="def.d",
                         predict.b="predict.b", predict.c="predict.c",
                         predict.e="predict.e")
PREFIX predict.
DROP >PREFIX
     >EXPLICIT|^w1\.
KEEP ^force.|^def.|^predict.
input dotnames       a b c w1.xlab def.b def.d predict.b predict.c predict.e
after DROP and KEEP  a b c def.b def.d predict.b predict.c predict.e
return dotnames      b d a c e

> 
> test.deprefix(
+     expected=list(a="predict.a"),
+     KEEP=NULL, PREFIX="predict.", DROP="w1.",
+     a="plain.a", predict.a="predict.a")
> 
> test.deprefix(expected=list(a="aa1"),
+     KEEP=NULL, PREFIX="predict.", a="aa1")
> 
> test.deprefix(expected=list(a="aa2"),
+     KEEP=NULL, PREFIX="predict.", def.a="aa2")
> 
> test.deprefix(expected=list(a="aa3", b="bb3"),
+     KEEP=NULL, PREFIX="predict.", def.a="aa3", b="bb3")
> 
> test.deprefix(expected=list(10, 20), TRACE=2,
+                 KEEP=NULL, DROP="w1.,persp.,xlab.",
+                 PREFIX="predict.",
+                 force.anon2=20, force.anon1=10)
TRACE higher.caller.to.deprefix called higher.caller.to.deprefix(test.deprefix,
                         FNAME="test.deprefix", force.anon2=20, force.anon1=10)
PREFIX predict.
DROP >PREFIX
     >EXPLICIT|^w1\.|^persp\.|^xlab\.
KEEP ^force.|^def.|^predict.
input dotnames       force.anon2 force.anon1
after DROP and KEEP  force.anon2 force.anon1
return dotnames      anon1 anon2 

> 
> test.deprefix(expected=list(10, 20, a=3), TRACE=2,
+                 KEEP=NULL, DROP="w1.,persp.,xlab.",
+                 PREFIX="predict.",
+                 force.anon2=20, force.anon1=10,
+                 a=3)
TRACE higher.caller.to.deprefix called higher.caller.to.deprefix(test.deprefix,
                         FNAME="test.deprefix", force.anon2=20, force.anon1=10,
                         a=3)
PREFIX predict.
DROP >PREFIX
     >EXPLICIT|^w1\.|^persp\.|^xlab\.
KEEP ^force.|^def.|^predict.
input dotnames       force.anon2 force.anon1 a
after DROP and KEEP  force.anon2 force.anon1 a
return dotnames      anon1 anon2  a

> 
> expect.err(try(test.deprefix(expected=list(10, 20, a=4),
+                 KEEP=NULL, DROP="w1.,persp.,xlab.",
+                 PREFIX="predict.",
+                 force.anon=10, force.anon=20,
+                 a=3, predict.a=4)),
+                 "argument 'force.anon' for test.deprefix() is duplicated")
Error : argument 'force.anon' for test.deprefix() is duplicated
Got expected error from try(test.deprefix(expected = list(10, 20, a = 4), KEEP = NULL,     DROP = "w1.,persp.,xlab.", PREFIX = "predict.", force.anon = 10,     force.anon = 20, a = 3, predict.a = 4))
> 
> expect.err(try(test.deprefix(expected=list(10, 20, a=4),
+                 KEEP=NULL, DROP="w1.,persp.,xlab.",
+                 PREFIX="predict.", FNAME="foobar",
+                 force.anon=10, force.anon=20,
+                 a=3, predict.a=4)),
+                 "argument 'force.anon' for foobar() is duplicated")
Error : argument 'force.anon' for foobar() is duplicated
Got expected error from try(test.deprefix(expected = list(10, 20, a = 4), KEEP = NULL,     DROP = "w1.,persp.,xlab.", PREFIX = "predict.", FNAME = "foobar",     force.anon = 10, force.anon = 20, a = 3, predict.a = 4))
> 
> test.deprefix(expected=list(10, 20, a=4),
+                 KEEP=NULL, DROP="w1.,persp.,xlab.",
+                 PREFIX="predict.",
+                 force.anon1=10, force.anon2=20,
+                 a=3, predict.a=4)
> 
> test.deprefix(expected=list(10, 20, b=3, a=4),
+                 KEEP=NULL, DROP="w1.,persp.,xlab.",
+                 PREFIX="predict.",
+                 force.anon1=10, force.anon2=20, def.b=3,
+                 a=3, predict.a=4)
> 
> test.deprefix(expected=list(10, 20, b=5, a=3),
+                 KEEP=NULL, DROP="w1.,persp.,xlab.",
+                 PREFIX="predict.",
+                 force.anon1=10, force.anon2=20, def.b=3,
+                 a=3, predict.b=5)
> 
> test.deprefix(expected=list(10, 20, b=6, a=3),
+                 KEEP=NULL, DROP="w1.,persp.,xlab.",
+                 PREFIX="predict.",
+                 force.anon1=10, force.anon2=20, def.b=3,
+                 a=3, b=6)
> 
> expect.err(try(test.deprefix(expected=NULL, KEEP=NULL, PREFIX="predict.", DROP="w1\\.")), "illegal character \"\\\" in DROP = \"w1\\.\"")
Error : illegal character "\" in DROP = "w1\."
Got expected error from try(test.deprefix(expected = NULL, KEEP = NULL, PREFIX = "predict.",     DROP = "w1\\."))
> 
> test.deprefix(expected=list(b="predict.b", d="def.d", a="a", c="predict.c", w1.xl="xlab2", e="predict.e"),
+     PREFIX="predict.", DROP="w1.xlab$",
+     a="a", b="b", c="c",
+     w1.xlab="xlab1", # will be dropped (exact match)
+     w1.xl="xlab2",   # will be kept (not an exact match)
+     def.b="def.b", def.d="def.d",
+     predict.b="predict.b", predict.c="predict.c", predict.e="predict.e")
> 
> # expect.err(try(plotmo:::deprefix(FNAME="test.deprefix", PREFIX="predict.", UPPER.CASE123=99,
> #   def.a=1, predict.b=2, c=3)),
> #   "uppercase argument names like \"UPPER.CASE123\" are not allowed for test.deprefix()")
> 
> test.expand.dotnames <- function(expected, PREFIX, FUNC=NULL,
+                                  FNAME="test.expand.dotnames", FORMALS=NULL, ...)
+ {
+     dots <- as.list(match.call(expand.dots=FALSE)$...)
+     args <- plotmo:::expand.dotnames(dots, PREFIX, FUNC, FNAME, FORMALS)
+     # can't use all.equal because it complains about named list versus unnamed list
+     stopifnot(length(args) == length(expected))
+     for(i in seq_len(length(expected))) {
+         stopifnot(names(args)[i] == names(expected)[i])
+         stopifnot(eval(args[[i]]) == expected[[i]])
+     }
+ }
> cat0("=== test expand.dotnames\n")
=== test expand.dotnames
> 
> test.expand.dotnames(expected=list(x=9, persp.shade=3),
+     "persp.", graphics:::persp.default, "persp.default", x=9, persp.sh=3)
> 
> test.expand.dotnames(expected=list(x=9, persp.shade=3, persp.nonesuch=4),
+     "persp.", graphics:::persp.default, "persp.default", x=9, persp.sh=3, persp.nonesuch=4)
> 
> test.expand.dotnames(expected=list(x=9, persp.col=3),
+     "persp.", graphics:::persp.default, "persp.default", x=9, persp.c=3)
> 
> # TODO not sure why this works as it does
> test.expand.dotnames(expected=list(x=9, persp.x=3),
+     "persp.", graphics:::persp.default, "persp.default", x=9, persp.x=3)
> 
> expect.err(try(test.expand.dotnames(expected=NULL,
+     "persp.", graphics:::persp.default, "persp.default", x=9, persp.l=3)),
+     "'l' matches both the 'ltheta' and 'lphi' arguments of persp.default()")
Error : 'l' matches both the 'ltheta' and 'lphi' arguments of persp.default()
Got expected error from try(test.expand.dotnames(expected = NULL, "persp.", graphics:::persp.default,     "persp.default", x = 9, persp.l = 3))
> 
> test.expand.dotnames(expected=list(x=9, plot.foo=3, plot.xlim=c(1,2)),
+     "plot.", graphics:::plot.default, "plot.default", x=9, plot.foo=3, plot.xlim=c(1,2))
> 
> test.expand.dotnames(expected=list(x=9, plot.foo=3, plot.xlim=c(1,2)),
+     "plot.", graphics:::plot.default, "plot.default", x=9, plot.foo=3, plot.xli=c(1,2))
> 
> expect.err(try(test.expand.dotnames(expected=NULL,
+     "plot.", graphics:::plot.default, "plot.default", x=9, plot.foo=3, plot.xl=c(1,2))),
+     "'xl' matches both the 'xlim' and 'xlab' arguments of plot.default()")
Error : 'xl' matches both the 'xlim' and 'xlab' arguments of plot.default()
Got expected error from try(test.expand.dotnames(expected = NULL, "plot.", graphics:::plot.default,     "plot.default", x = 9, plot.foo = 3, plot.xl = c(1, 2)))
> 
> foo3 <- function(aaa=1, aa=2, bb=3, bba=4, cca=5, ccb=6, def=7)
+     cat0("foo3: aaa=", aaa, " aa=", aa, ", bb=", bb, " bba=", bba,
+          " cca=", cca, " ccb=", ccb, " def=", def, "\n")
> 
> # --- above tests again but using formals ---
> 
> # formal args for graphics:::persp.default (R version 3.2.0)
> formals <- c( "x", "y", "z", "xlim", "zlim", "xlab", "ylab", "zlab",
+     "main", "sub", "theta", "phi", "r", "d", "scale", "expand", "col",
+     "border", "ltheta", "lphi", "shade", "box", "axes", "nticks",
+     "ticktype")
> 
> test.expand.dotnames(expected=list(x=9, persp.shade=3),
+     "persp.", graphics:::persp, "persp", FORMALS=formals, x=9, persp.sh=3)
> 
> test.expand.dotnames(expected=list(x=9, persp.shade=3, persp.nonesuch=4),
+     "persp.", graphics:::persp, "persp", FORMALS=formals, x=9, persp.sh=3, persp.nonesuch=4)
> 
> test.expand.dotnames(expected=list(x=9, persp.col=3),
+     "persp.", graphics:::persp, "persp", FORMALS=formals, x=9, persp.c=3)
> 
> # TODO not sure why this works as it does
> test.expand.dotnames(expected=list(x=9, persp.x=3),
+     "persp.", graphics:::persp, "persp", FORMALS=formals, x=9, persp.x=3)
> 
> expect.err(try(test.expand.dotnames(expected=NULL,
+     "persp.", graphics:::persp, "persp", FORMALS=formals, x=9, persp.l=3)),
+     "'l' matches both the 'ltheta' and 'lphi' arguments of persp()")
Error : 'l' matches both the 'ltheta' and 'lphi' arguments of persp()
Got expected error from try(test.expand.dotnames(expected = NULL, "persp.", graphics:::persp,     "persp", FORMALS = formals, x = 9, persp.l = 3))
> 
> # done formals tests
> 
> test.expand.dotnames(expected=list(x=9, plot.foo=3, plot.xlim=c(1,2)),
+     "plot.", graphics:::plot.default, "plot.default", x=9, plot.foo=3, plot.xlim=c(1,2))
> 
> test.expand.dotnames(expected=list(x=9, plot.foo=3, plot.xlim=c(1,2)),
+     "plot.", graphics:::plot.default, "plot.default", x=9, plot.foo=3, plot.xli=c(1,2))
> 
> expect.err(try(test.expand.dotnames(expected=NULL,
+     "plot.", graphics:::plot.default, "plot.default", x=9, plot.foo=3, plot.xl=c(1,2))),
+     "'xl' matches both the 'xlim' and 'xlab' arguments of plot.default()")
Error : 'xl' matches both the 'xlim' and 'xlab' arguments of plot.default()
Got expected error from try(test.expand.dotnames(expected = NULL, "plot.", graphics:::plot.default,     "plot.default", x = 9, plot.foo = 3, plot.xl = c(1, 2)))
> 
> test.expand.dotnames(expected=list(foo3.aa=99),
+     "foo3.", foo3, "foo3", foo3.aa=99)
> expect.err(try(plotmo:::call.plot(foo3, "foo3.", foo3.aa=99)), "Unnamed arguments are not allowed here\n       The argument's value is \"foo3.\"")
Error : Unnamed arguments are not allowed here
       The argument's value is "foo3."
       plotmo:::call.plot via try called call.dots(FUNC=foo3, PREFIX=PREFIX, ...,
          DROP="*", KEEP="PREFIX,PLOT.ARGS", TRACE=TRACE, FNAME=fname,
          FORMALS=FORMALS, SCALAR=SCALAR, CALLARGS=function.object,
          CALLER=caller, foo3.aa=99)

Got expected error from try(plotmo:::call.plot(foo3, "foo3.", foo3.aa = 99))
> expect.err(try(plotmo:::call.plot(foo3, foo, foo3.aa=99)),
+ "Unnamed arguments are not allowed here\n       The argument's value is function.object")
Error : Unnamed arguments are not allowed here
       The argument's value is function.object
       plotmo:::call.plot via try called call.dots(FUNC=foo3, PREFIX=PREFIX, ...,
          DROP="*", KEEP="PREFIX,PLOT.ARGS", TRACE=TRACE, FNAME=fname,
          FORMALS=FORMALS, SCALAR=SCALAR, CALLARGS=function.object,
          CALLER=caller, foo3.aa=99)

Got expected error from try(plotmo:::call.plot(foo3, foo, foo3.aa = 99))
> expect.err(try(plotmo:::call.plot(foo3, NULL, foo3.aa=99)), "Unnamed arguments are not allowed here\n       The argument's value is NULL")
Error : Unnamed arguments are not allowed here
       The argument's value is NULL
       plotmo:::call.plot via try called call.dots(FUNC=foo3, PREFIX=PREFIX, ...,
          DROP="*", KEEP="PREFIX,PLOT.ARGS", TRACE=TRACE, FNAME=fname,
          FORMALS=FORMALS, SCALAR=SCALAR, CALLARGS=function.object,
          CALLER=caller, foo3.aa=99)

Got expected error from try(plotmo:::call.plot(foo3, NULL, foo3.aa = 99))
> expect.err(try(plotmo:::call.plot(foo3, stop("stop was called"), foo3.aa=99)), "Unnamed arguments are not allowed here (argument ..1 is unnamed)")
Error : Unnamed arguments are not allowed here (argument ..1 is unnamed)
       plotmo:::call.plot via try called call.dots(FUNC=foo3, PREFIX=PREFIX, ...,
          DROP="*", KEEP="PREFIX,PLOT.ARGS", TRACE=TRACE, FNAME=fname,
          FORMALS=FORMALS, SCALAR=SCALAR, CALLARGS=function.object,
          CALLER=caller, foo3.aa=99)

Got expected error from try(plotmo:::call.plot(foo3, stop("stop was called"), foo3.aa = 99))
> expect.err(try(plotmo:::call.plot(foo3, cat("side effect\n"), foo3.aa=99)), "Unnamed arguments are not allowed here\n       The argument's value is NULL")
side effect
Error : Unnamed arguments are not allowed here
       The argument's value is NULL
       plotmo:::call.plot via try called call.dots(FUNC=foo3, PREFIX=PREFIX, ...,
          DROP="*", KEEP="PREFIX,PLOT.ARGS", TRACE=TRACE, FNAME=fname,
          FORMALS=FORMALS, SCALAR=SCALAR, CALLARGS=function.object,
          CALLER=caller, foo3.aa=99)

Got expected error from try(plotmo:::call.plot(foo3, cat("side effect\n"), foo3.aa = 99))
> expect.err(try(plotmo:::call.plot(foo3, nonesuch1=1, nonesuch2, foo3.aa=99)), "Unnamed arguments are not allowed here (argument ..2 is unnamed)")
Error : Unnamed arguments are not allowed here (argument ..2 is unnamed)
       plotmo:::call.plot via try called call.dots(FUNC=foo3, PREFIX=PREFIX, ...,
          DROP="*", KEEP="PREFIX,PLOT.ARGS", TRACE=TRACE, FNAME=fname,
          FORMALS=FORMALS, SCALAR=SCALAR, CALLARGS=function.object,
          CALLER=caller, nonesuch1=1, foo3.aa=99)

Got expected error from try(plotmo:::call.plot(foo3, nonesuch1 = 1, nonesuch2, foo3.aa = 99))
> plotmo:::call.plot(foo3, PREFIX="foo3.", foo3.aa=99)
foo3: aaa=1 aa=99, bb=3 bba=4 cca=5 ccb=6 def=7
> 
> test.expand.dotnames(expected=list(foo3.aaa=99),
+     "foo3.", foo3, "foo3", foo3.aaa=99)
> plotmo:::call.plot(foo3, foo3.aaa=99)
foo3: aaa=99 aa=2, bb=3 bba=4 cca=5 ccb=6 def=7
> 
> expect.err(try(test.expand.dotnames(expected=list(foo3.aaa=99),
+     "foo3.", foo3, "foo3", foo3.aa=88, foo3.aa=99)),
+     "'foo3.aa' for foo3() is duplicated")
Error : argument 'foo3.aa' for foo3() is duplicated
Got expected error from try(test.expand.dotnames(expected = list(foo3.aaa = 99), "foo3.",     foo3, "foo3", foo3.aa = 88, foo3.aa = 99))
> 
> expect.err(try(test.expand.dotnames(expected=list(foo3.aaa=99),
+     "foo3.", foo3, "foo3", foo3.a=88, foo3.aa=99)),
+     "'a' matches both the 'aaa' and 'aa' arguments of foo3()")
Error : 'a' matches both the 'aaa' and 'aa' arguments of foo3()
Got expected error from try(test.expand.dotnames(expected = list(foo3.aaa = 99), "foo3.",     foo3, "foo3", foo3.a = 88, foo3.aa = 99))
> 
> expect.err(try(test.expand.dotnames(expected=list(foo3.aaa=99),
+     "foo3.", foo3, "foo3", foo3.aaa=88, foo3.aaa=99)),
+     "'foo3.aaa' for foo3() is duplicated")
Error : argument 'foo3.aaa' for foo3() is duplicated
Got expected error from try(test.expand.dotnames(expected = list(foo3.aaa = 99), "foo3.",     foo3, "foo3", foo3.aaa = 88, foo3.aaa = 99))
> 
> test.expand.dotnames(expected=list(foo3.bbb=88, foo3.bba=99),
+      "foo3.", foo3, "foo3", foo3.bbb=88, foo3.bba=99)
> expect.err(try(plotmo:::call.plot(foo3, foo3.bbb=88, foo3.bba=99)),
+      "unused argument (bbb = 88)")

foo3(bbb=88, bba=99)

Error in (function (aaa = 1, aa = 2, bb = 3, bba = 4, cca = 5, ccb = 6,  : 
  unused argument (bbb = 88)
Got expected error from try(plotmo:::call.plot(foo3, foo3.bbb = 88, foo3.bba = 99))
> 
> # same as above but with TRACE (so don't use try in call.dots)
> expect.err(try(plotmo:::call.plot(foo3, foo3.bbb=88, foo3.bba=99, TRACE=T)),
+      "unused argument (bbb = 88)")
foo3(bbb=88, bba=99)
Error in (function (aaa = 1, aa = 2, bb = 3, bba = 4, cca = 5, ccb = 6,  : 
  unused argument (bbb = 88)
Got expected error from try(plotmo:::call.plot(foo3, foo3.bbb = 88, foo3.bba = 99, TRACE = T))
> 
> test.expand.dotnames(expected=list(foo3.bb=88),
+      "foo3.", foo3, "foo3", foo3.bb=88)
> plotmo:::call.plot(foo3, foo3.bb=88)
foo3: aaa=1 aa=2, bb=88 bba=4 cca=5 ccb=6 def=7
> 
> # test with FUNC=NULL
> 
> test.expand.dotnames(expected=list(foo3.aa=99),
+     "foo3.", NULL, "foo3", foo3.aa=99)
> plotmo:::call.plot(foo3, foo3.aa=99)
foo3: aaa=1 aa=99, bb=3 bba=4 cca=5 ccb=6 def=7
> 
> test.expand.dotnames(expected=list(foo3.aaa=99),
+     "foo3.", NULL, "foo3", foo3.aaa=99)
> plotmo:::call.plot(foo3, foo3.aaa=99)
foo3: aaa=99 aa=2, bb=3 bba=4 cca=5 ccb=6 def=7
> 
> expect.err(try(test.expand.dotnames(expected=list(foo3.aaa=99),
+     "foo3.", NULL, "foo3", foo3.aa=88, foo3.aa=99)),
+     "argument 'foo3.aa' for foo3() is duplicated")
Error : argument 'foo3.aa' for foo3() is duplicated
Got expected error from try(test.expand.dotnames(expected = list(foo3.aaa = 99), "foo3.",     NULL, "foo3", foo3.aa = 88, foo3.aa = 99))
> 
> test.expand.dotnames(expected=list(foo3.a=88, foo3.aa=99),
+      "foo3.", NULL, "foo3", foo3.a=88, foo3.aa=99)
> expect.err(try(plotmo:::call.plot(foo3, foo3.a=88, foo3.aa=99)),
+      "'a' matches both the 'aaa' and 'aa' arguments of foo3()")
Error : 'a' matches both the 'aaa' and 'aa' arguments of foo3()
Got expected error from try(plotmo:::call.plot(foo3, foo3.a = 88, foo3.aa = 99))
> 
> expect.err(try(test.expand.dotnames(expected=list(foo3.aaa=99),
+      "foo3.", NULL, "foo3", foo3.aaa=88, foo3.aaa=99)),
+      "argument 'foo3.aaa' for foo3() is duplicated")
Error : argument 'foo3.aaa' for foo3() is duplicated
Got expected error from try(test.expand.dotnames(expected = list(foo3.aaa = 99), "foo3.",     NULL, "foo3", foo3.aaa = 88, foo3.aaa = 99))
> 
> test.expand.dotnames(expected=list(foo3.bbb=88, foo3.bba=99),
+       "foo3.", NULL, "foo3", foo3.bbb=88, foo3.bba=99)
> expect.err(try(plotmo:::call.plot(foo3, PREFIX="foo3.", foo3.bbb=88, foo3.bba=99)),
+       "unused argument (bbb = 88)")

foo3(bbb=88, bba=99)

Error in (function (aaa = 1, aa = 2, bb = 3, bba = 4, cca = 5, ccb = 6,  : 
  unused argument (bbb = 88)
Got expected error from try(plotmo:::call.plot(foo3, PREFIX = "foo3.", foo3.bbb = 88,     foo3.bba = 99))
> 
> test.expand.dotnames(expected=list(foo3.bb=88),
+       "foo3.", NULL, "foo3", foo3.bb=88)
> plotmo:::call.plot(foo3, foo3.bb=88)
foo3: aaa=1 aa=2, bb=88 bba=4 cca=5 ccb=6 def=7
> 
> test.expand.dotnames(expected=list(foo3.bbx=88),
+       "foo3.", NULL, "foo3", foo3.bbx=88)
> expect.err(try(plotmo:::call.plot(foo3, foo3.bbx=88)),
+       "unused argument (bbx = 88)")

foo3(bbx=88)

Error in (function (aaa = 1, aa = 2, bb = 3, bba = 4, cca = 5, ccb = 6,  : 
  unused argument (bbx = 88)
Got expected error from try(plotmo:::call.plot(foo3, foo3.bbx = 88))
> 
> test.expand.dotnames(expected=list(foo3.cc=77),
+       "foo3.", NULL, "foo3", foo3.cc=77)
> expect.err(try(plotmo:::call.plot(foo3, foo3.cc=77)),
+       "'cc' matches both the 'cca' and 'ccb' arguments of foo3()")
Error : 'cc' matches both the 'cca' and 'ccb' arguments of foo3()
Got expected error from try(plotmo:::call.plot(foo3, foo3.cc = 77))
> 
> # following two directly compare FUNC=NULL to FUNC=foo3
> test.expand.dotnames(expected=list(foo3.cc=77),
+            "foo3.", FUNC=NULL, "foo3", foo3.cc=77)
> expect.err(try(test.expand.dotnames(expected=NULL,
+            "foo3.", FUNC=foo3, "foo3", foo3.cc=77)),
+            "'cc' matches both the 'cca' and 'ccb' arguments of foo3()")
Error : 'cc' matches both the 'cca' and 'ccb' arguments of foo3()
Got expected error from try(test.expand.dotnames(expected = NULL, "foo3.", FUNC = foo3,     "foo3", foo3.cc = 77))
> 
> test.expand.dotnames(expected=list(), "foo3.", foo3, "foo3", d=88, de=99)
> 
> expect.err(try(plotmo:::call.plot(graphics::plot, x=1:3, y=1:3, 99)),
+ "Unnamed arguments are not allowed here\n       The argument's value is 99\n       plotmo:::call.plot via try called call.dots(FUNC=plot, PREFIX=PREFIX, ...")
Error : Unnamed arguments are not allowed here
       The argument's value is 99
       plotmo:::call.plot via try called call.dots(FUNC=plot, PREFIX=PREFIX, ...,
          DROP="*", KEEP="PREFIX,PLOT.ARGS", TRACE=TRACE, FNAME=fname,
          FORMALS=FORMALS, SCALAR=SCALAR, CALLARGS=function.object,
          CALLER=caller, x=c(1,2,3), y=c(1,2,3))

Got expected error from try(plotmo:::call.plot(graphics::plot, x = 1:3, y = 1:3, 99))
> 
> # test TRACE
> print(plotmo:::deprefix(FUNC=nchar, PREFIX="foo3.", TRACE=TRUE, FNAME="nchar", allowN=1, b=2, foo3.c=3))
$allowNA
[1] 1

$b
[1] 2

$c
[1] 3

> print(plotmo:::deprefix(FUNC=nchar, PREFIX="foo3.", TRACE=2,    allowN=1, b=2, foo3.c=3))
TRACE higher.caller.to.deprefix called higher.caller.to.deprefix(nchar,
                         FNAME="nchar", allowN=1, b=2, foo3.c=3)
PREFIX foo3.
DROP NULL
KEEP ^force.|^def.|^foo3.
input dotnames       allowN b foo3.c
after DROP and KEEP  allowN b foo3.c
return dotnames      allowNA b c

$allowNA
[1] 1

$b
[1] 2

$c
[1] 3

> print(plotmo:::deprefix(FUNC=nchar, PREFIX="foo3.", TRACE=3,    allowN=1, b=2, foo3.c=3))
TRACE higher.caller.to.deprefix called higher.caller.to.deprefix(nchar,
                         FNAME="nchar", allowN=1, b=2, foo3.c=3)
PREFIX foo3.
DROP NULL
KEEP ^force.|^def.|^foo3.
input dotnames       allowN b foo3.c
after DROP and KEEP  allowN b foo3.c
return dotnames      allowNA b c

$allowNA
[1] 1

$b
[1] 2

$c
[1] 3

> 
> expect.err(try(plotmo:::call.plot(foo3, foo3.d=88, foo3.de=99)),
+         "'foo3.d' and 'foo3.de' both match the 'def' argument of foo3()")
Error : 'foo3.d' and 'foo3.de' both match the 'def' argument of foo3()
Got expected error from try(plotmo:::call.plot(foo3, foo3.d = 88, foo3.de = 99))
> 
> cat0("=== test stop.if.dots\n")
=== test stop.if.dots
> 
> foo3 <- function(x=1, ...)  plotmo:::stop.if.dots(...)
> foo3(1) # ok
> expect.err(try(foo3(10, y=2)), "foo3: unrecognized argument 'y'")
Error : foo3: unrecognized argument 'y'
Got expected error from try(foo3(10, y = 2))
> expect.err(try(foo3(10, 99)), "foo3: unrecognized unnamed argument\n       The call was foo3(x=10, 99)")
Error : foo3: unrecognized unnamed argument
       The call was foo3(x=10, 99)
Got expected error from try(foo3(10, 99))
> expect.err(try(foo3(10, y=plot)), "foo3: unrecognized argument 'y'")
Error : foo3: unrecognized argument 'y'
Got expected error from try(foo3(10, y = plot))
> expect.err(try(foo3(10, plot)),
+ "foo3: unrecognized unnamed argument\n       The call was foo3(x=10, plot)")
Error : foo3: unrecognized unnamed argument
       The call was foo3(x=10, plot)
Got expected error from try(foo3(10, plot))
> 
> expect.err(try(foo3(20, c(1,2,3), plot)),
+ "foo3: unrecognized unnamed argument\n       The call was foo3(x=20, c(1,2,3), plot)")
Error : foo3: unrecognized unnamed argument
       The call was foo3(x=20, c(1,2,3), plot)
Got expected error from try(foo3(20, c(1, 2, 3), plot))
> 
> expect.err(try(foo3(20, c(1,2,3,4,5,6,7,8,9,10,11,12), plot)),
+ "foo3: unrecognized unnamed argument\n       The call was foo3(x=20, c(1,2,3,4,5,6,7,8,9,10,11,12), plot)")
Error : foo3: unrecognized unnamed argument
       The call was foo3(x=20, c(1,2,3,4,5,6,7,8,9,10,11,12), plot)
Got expected error from try(foo3(20, c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12), plot))
> 
> # test that we don't crash because we eval the argument
> expect.err(try(foo3(20, y=stop("stop was called"))), "foo3: unrecognized argument 'y'")
Error : foo3: unrecognized argument 'y'
Got expected error from try(foo3(20, y = stop("stop was called")))
> expect.err(try(foo3(20, stop("stop was called"))), "foo3: unrecognized unnamed argument")
Error : foo3: unrecognized unnamed argument
       The call was foo3(x=20, stop("stopwascalled"))
Got expected error from try(foo3(20, stop("stop was called")))
> expect.err(try(foo3(20, cat("side effect\n"))),
+ "foo3: unrecognized unnamed argument\n       The call was foo3(x=20, cat(")
Error : foo3: unrecognized unnamed argument
       The call was foo3(x=20, cat("sideeffect\n"))
Got expected error from try(foo3(20, cat("side effect\n")))
> foo2 <- function(...)  plotmo:::stop.if.dots(...)
> foo2() # ok
> expect.err(try(foo2(y=2)), "foo2: unrecognized argument 'y'")
Error : foo2: unrecognized argument 'y'
Got expected error from try(foo2(y = 2))
> expect.err(try(foo2(2)), "foo2: unrecognized unnamed argument\n       The call was foo2(2)")
Error : foo2: unrecognized unnamed argument
       The call was foo2(2)
Got expected error from try(foo2(2))
> expect.err(try(foo2(y=plot)), "foo2: unrecognized argument 'y'")
Error : foo2: unrecognized argument 'y'
Got expected error from try(foo2(y = plot))
> expect.err(try(foo2(plot)),
+ "foo2: unrecognized unnamed argument\n       The call was foo2(plot)")
Error : foo2: unrecognized unnamed argument
       The call was foo2(plot)
Got expected error from try(foo2(plot))
> 
> foo2a <- function(funcarg, ...) funcarg(...)
> expect.err(try(foo2a(function(x=1, ...) plotmo:::stop.if.dots(...), x=1, y=2)), "funcarg: unrecognized argument 'y'")
Error : funcarg: unrecognized argument 'y'
Got expected error from try(foo2a(function(x = 1, ...) plotmo:::stop.if.dots(...), x = 1,     y = 2))
> 
> cat0("=== test warn.if.dots\n")
=== test warn.if.dots
> 
> options(warn=2) # treat warnings as errors
> 
> foo3 <- function(x=1, ...)  plotmo:::warn.if.dots(...)
> foo3(1) # ok
> expect.err(try(foo3(1, y=2)), "foo3 ignored argument 'y'")
Error : (converted from warning) foo3 ignored argument 'y'
Got expected error from try(foo3(1, y = 2))
> expect.err(try(foo3(1, 2)), "foo3 ignored unnamed argument\n       The call was foo3(x=1, 2)")
Error : (converted from warning) foo3 ignored unnamed argument
       The call was foo3(x=1, 2)
Got expected error from try(foo3(1, 2))
> expect.err(try(foo3(1, y=plot)), "foo3 ignored argument 'y'")
Error : (converted from warning) foo3 ignored argument 'y'
Got expected error from try(foo3(1, y = plot))
> # TODO would like to improve this error messsage
> expect.err(try(foo3(1, plot)),
+ "(converted from warning) foo3 ignored unnamed argument\n       The call was foo3(x=1, plot)")
Error : (converted from warning) foo3 ignored unnamed argument
       The call was foo3(x=1, plot)
Got expected error from try(foo3(1, plot))
> foo4 <- function(...)  plotmo:::warn.if.dots(...)
> foo4() # ok
> expect.err(try(foo4(y=2)), "foo4 ignored argument 'y'")
Error : (converted from warning) foo4 ignored argument 'y'
Got expected error from try(foo4(y = 2))
> expect.err(try(foo4(2)), "foo4 ignored unnamed argument\n       The call was foo4(2)")
Error : (converted from warning) foo4 ignored unnamed argument
       The call was foo4(2)
Got expected error from try(foo4(2))
> expect.err(try(foo4(y=plot)), "foo4 ignored argument 'y'")
Error : (converted from warning) foo4 ignored argument 'y'
Got expected error from try(foo4(y = plot))
> expect.err(try(foo4(plot)),
+ "(converted from warning) foo4 ignored unnamed argument\n       The call was foo4(plot)")
Error : (converted from warning) foo4 ignored unnamed argument
       The call was foo4(plot)
Got expected error from try(foo4(plot))
> 
> options(warn=1)
> 
> foo3(1, nonesuch=12, nonesuch2=12, 999) # expect three warnings
Warning: foo3 ignored argument 'nonesuch'
Warning: foo3 ignored argument 'nonesuch2'
Warning: foo3 ignored unnamed argument
       The call was foo3(x=1, nonesuch=12, nonesuch2=12, 999)
> 
> cat0("=== test using sample functions that invoke call.dots\n")
=== test using sample functions that invoke call.dots
> 
> x <- 1:10
> y <- x * x
> lmfit <- lm(y~x)
> par(mfrow=c(3, 2))
> par(oma=c(0, 0, 3, 0))
> 
> # plot1: simple example
> # we choose to use predict() here rather than fitted() because nearly all
> # models have a fitted() method, but many don't have a fitted() method.
> 
> plot1 <- function(object, ...)
+ {
+     residuals <- residuals(object, ...)
+ 
+     fitted <- predict(object, ...)
+ 
+     plot(fitted, residuals, ...)
+ }
> plot1(lmfit)
> mtext("example plot functions using prefixed dots", outer=TRUE, font=2, line=1, cex=1)
> 
> # Following causes error in predict.lm().  The type argument meant for
> # residuals() is also sent to predict.lm(), where it is rejected.
> 
> expect.err(try(plot1(lmfit, type="pearson")), "'arg' should be one of \"response\", \"terms\"")
Error in match.arg(type) : 'arg' should be one of "response", "terms"
Got expected error from try(plot1(lmfit, type = "pearson"))
> 
> # plot2: use prefixed args
> 
> plot2 <- function(object, ..., TRACE=2)
+ {
+     resids <- plotmo:::call.dots(residuals, object=object, ..., TRACE=TRACE)
+ 
+     fitted <- plotmo:::call.dots(predict, object=object, ..., TRACE=TRACE)
+ 
+     plotmo:::call.plot(plot, x=fitted, y=resids, ..., TRACE=TRACE)
+ }
> # we can now direct args using the prefixes "residuals.", "predict.", or "plot.")
> 
> plot2(lmfit, residuals.type="pearson")
plot2 invoked call.dots
TRACE plotmo:::call.dots called deprefix(FUNC=residuals, PREFIX=PREFIX, ...,
                         DROP=DROP, KEEP=KEEP, TRACE=TRACE, FNAME="residuals",
                         FORMALS=FORMALS, SCALAR=SCALAR, CALLARGS=CALLARGS,
                         object=lm.object, residuals.type="pearson")
PREFIX residuals.
DROP .*
KEEP >STANDARDPREFIXES|^force\.|^def\.|^drop\.
     >PREFIX|^residuals\.
     >CALLARGS|^object$
     >EXPLICIT
input dotnames       object residuals.type
after DROP and KEEP  object residuals.type
return dotnames      object type

residuals(object=lm.object, type="pearson")
plot2 invoked call.dots
TRACE plotmo:::call.dots called deprefix(FUNC=predict, PREFIX=PREFIX, ...,
                         DROP=DROP, KEEP=KEEP, TRACE=TRACE, FNAME="predict",
                         FORMALS=FORMALS, SCALAR=SCALAR, CALLARGS=CALLARGS,
                         object=lm.object, residuals.type="pearson")
PREFIX predict.
DROP .*
KEEP >STANDARDPREFIXES|^force\.|^def\.|^drop\.
     >PREFIX|^predict\.
     >CALLARGS|^object$
     >EXPLICIT
input dotnames       object residuals.type
after DROP and KEEP  object
return dotnames      object

predict(object=lm.object)
plot2 invoked call.dots
TRACE plotmo:::call.plot called call.dots(FUNC=plot, PREFIX=PREFIX, ...,
                         DROP="*", KEEP="PREFIX,PLOT.ARGS", TRACE=TRACE,
                         FNAME=fname, FORMALS=FORMALS, SCALAR=SCALAR,
                         CALLARGS=function.object, CALLER=caller,
                         x=c(-11,0,11,22,3...), y=c(12,4,-2,-6,-8...),
                         residuals.type="pearson")
PREFIX plot.
DROP .*
KEEP >STANDARDPREFIXES|^force\.|^def\.|^drop\.
     >PREFIX|^plot\.
     >CALLARGS|^x$|^y$
     >EXPLICIT
     >PLOT_ARGS|^add$|^adj$|^bty$|^cex$|^cex\.axis$|^cex\.lab$|^cex\.main$|^cex\.sub$|^col$|^col\.axis$|^col\.lab$|^col\.main$|^col\.sub$|^crt$|^family$|^font$|^font$|^font\.axis$|^font\.lab$|^font\.main$|^font\.sub$|^lend$|^ljoin$|^lmitre$|^lty$|^lwd$|^main$|^pch$|^srt$|^xaxp$|^xaxs$|^xaxt$|^xlab$|^xlim$|^xlog$|^xpd$|^yaxp$|^yaxs$|^yaxt$|^ylab$|^ylim$|^ylog$
input dotnames       x y residuals.type
after DROP and KEEP  x y
return dotnames      x y

plot(x=c(-11,0,11,22,3...), y=c(12,4,-2,-6,-8...))
> 
> # We can also use the usual plot arguments like ylab: call.dots drops
> # them; call.plot recognizes them and passes them to lines().
> 
> plot2(lmfit, residuals.type="pearson", ylab="pearson residuals", main="plot2")
plot2 invoked call.dots
TRACE plotmo:::call.dots called deprefix(FUNC=residuals, PREFIX=PREFIX, ...,
                         DROP=DROP, KEEP=KEEP, TRACE=TRACE, FNAME="residuals",
                         FORMALS=FORMALS, SCALAR=SCALAR, CALLARGS=CALLARGS,
                         object=lm.object, residuals.type="pearson",
                         ylab="pearson residuals", main="plot2")
PREFIX residuals.
DROP .*
KEEP >STANDARDPREFIXES|^force\.|^def\.|^drop\.
     >PREFIX|^residuals\.
     >CALLARGS|^object$
     >EXPLICIT
input dotnames       object residuals.type ylab main
after DROP and KEEP  object residuals.type
return dotnames      object type

residuals(object=lm.object, type="pearson")
plot2 invoked call.dots
TRACE plotmo:::call.dots called deprefix(FUNC=predict, PREFIX=PREFIX, ...,
                         DROP=DROP, KEEP=KEEP, TRACE=TRACE, FNAME="predict",
                         FORMALS=FORMALS, SCALAR=SCALAR, CALLARGS=CALLARGS,
                         object=lm.object, residuals.type="pearson",
                         ylab="pearson residuals", main="plot2")
PREFIX predict.
DROP .*
KEEP >STANDARDPREFIXES|^force\.|^def\.|^drop\.
     >PREFIX|^predict\.
     >CALLARGS|^object$
     >EXPLICIT
input dotnames       object residuals.type ylab main
after DROP and KEEP  object
return dotnames      object

predict(object=lm.object)
plot2 invoked call.dots
TRACE plotmo:::call.plot called call.dots(FUNC=plot, PREFIX=PREFIX, ...,
                         DROP="*", KEEP="PREFIX,PLOT.ARGS", TRACE=TRACE,
                         FNAME=fname, FORMALS=FORMALS, SCALAR=SCALAR,
                         CALLARGS=function.object, CALLER=caller,
                         x=c(-11,0,11,22,3...), y=c(12,4,-2,-6,-8...),
                         residuals.type="pearson", ylab="pearson residuals",
                         main="plot2")
PREFIX plot.
DROP .*
KEEP >STANDARDPREFIXES|^force\.|^def\.|^drop\.
     >PREFIX|^plot\.
     >CALLARGS|^x$|^y$
     >EXPLICIT
     >PLOT_ARGS|^add$|^adj$|^bty$|^cex$|^cex\.axis$|^cex\.lab$|^cex\.main$|^cex\.sub$|^col$|^col\.axis$|^col\.lab$|^col\.main$|^col\.sub$|^crt$|^family$|^font$|^font$|^font\.axis$|^font\.lab$|^font\.main$|^font\.sub$|^lend$|^ljoin$|^lmitre$|^lty$|^lwd$|^main$|^pch$|^srt$|^xaxp$|^xaxs$|^xaxt$|^xlab$|^xlim$|^xlog$|^xpd$|^yaxp$|^yaxs$|^yaxt$|^ylab$|^ylim$|^ylog$
input dotnames       x y residuals.type ylab main
after DROP and KEEP  x y ylab main
return dotnames      x y main ylab

plot(x=c(-11,0,11,22,3...), y=c(12,4,-2,-6,-8...), main="plot2", ylab="pearson
     residuals")
> 
> # plot3: further refinements
> #   o namespace added to FUNC arg
> #   o full name for plot.default
> #   o force. and def. prefixes
> #   o explicit xlab and ylab for call.plot
> #   o unprefixed args are passed to residuals()
> 
> plot3 <- function(object, ..., TRACE=2)
+ {
+     resids <- plotmo:::call.dots(stats::residuals,
+                                  DROP="plotmo:::PLOTARGS,predict.,plot.",
+                                  TRACE=TRACE, force.object=object, ...)
+ 
+     fitted <- plotmo:::call.dots(stats::predict,
+                                  force.object=object, TRACE=TRACE, ...)
+ 
+     plotmo:::call.plot(graphics::plot.default, force.x=fitted, force.y=resids,
+                        def.xlab="fitted", def.ylab="residuals",
+                        TRACE=TRACE, ...)
+ }
> plot3(lmfit, type="pearson", main="plot3a") # type goes only to pearson, no prefix needed
plot3 invoked call.dots
TRACE plotmo:::call.dots called deprefix(FUNC=residuals, PREFIX=PREFIX, ...,
                         DROP=DROP, KEEP=KEEP, TRACE=TRACE, FNAME="residuals",
                         FORMALS=FORMALS, SCALAR=SCALAR, CALLARGS=CALLARGS,
                         force.object=lm.object, type="pearson", main="plot3a")
PREFIX residuals.
DROP >PREFIX
     >EXPLICIT|^plotmo:::PLOTARGS|^predict\.|^plot\.
KEEP >STANDARDPREFIXES|^force\.|^def\.|^drop\.
     >PREFIX|^residuals\.
     >CALLARGS|^force\.object$
     >EXPLICIT
input dotnames       force.object type main
after DROP and KEEP  force.object type main
return dotnames      object type main

stats::residuals(object=lm.object, type="pearson", main="plot3a")
plot3 invoked call.dots
TRACE plotmo:::call.dots called deprefix(FUNC=predict, PREFIX=PREFIX, ...,
                         DROP=DROP, KEEP=KEEP, TRACE=TRACE, FNAME="predict",
                         FORMALS=FORMALS, SCALAR=SCALAR, CALLARGS=CALLARGS,
                         force.object=lm.object, type="pearson", main="plot3a")
PREFIX predict.
DROP .*
KEEP >STANDARDPREFIXES|^force\.|^def\.|^drop\.
     >PREFIX|^predict\.
     >CALLARGS|^force\.object$
     >EXPLICIT
input dotnames       force.object type main
after DROP and KEEP  force.object
return dotnames      object

stats::predict(object=lm.object)
plot3 invoked call.dots
TRACE plotmo:::call.plot called call.dots(FUNC=plot.default, PREFIX=PREFIX,
                         ..., DROP="*", KEEP="PREFIX,PLOT.ARGS", TRACE=TRACE,
                         FNAME=fname, FORMALS=FORMALS, SCALAR=SCALAR,
                         CALLARGS=function.object, CALLER=caller,
                         force.x=c(-11,0,11,22,3...),
                         force.y=c(12,4,-2,-6,-8...), def.xlab="fitted",
                         def.ylab="residuals", type="pearson", main="plot3a")
PREFIX plot.
DROP .*
KEEP >STANDARDPREFIXES|^force\.|^def\.|^drop\.
     >PREFIX|^plot\.
     >CALLARGS|^force\.x$|^force\.y$|^def\.xlab$|^def\.ylab$
     >EXPLICIT
     >PLOT_ARGS|^add$|^adj$|^bty$|^cex$|^cex\.axis$|^cex\.lab$|^cex\.main$|^cex\.sub$|^col$|^col\.axis$|^col\.lab$|^col\.main$|^col\.sub$|^crt$|^family$|^font$|^font$|^font\.axis$|^font\.lab$|^font\.main$|^font\.sub$|^lend$|^ljoin$|^lmitre$|^lty$|^lwd$|^main$|^pch$|^srt$|^xaxp$|^xaxs$|^xaxt$|^xlab$|^xlim$|^xlog$|^xpd$|^yaxp$|^yaxs$|^yaxt$|^ylab$|^ylim$|^ylog$
input dotnames       force.x force.y def.xlab def.ylab type main
after DROP and KEEP  force.x force.y def.xlab def.ylab main
return dotnames      x y main xlab ylab

graphics::plot.default(x=c(-11,0,11,22,3...), y=c(12,4,-2,-6,-8...),
                       main="plot3a", xlab="fitted", ylab="residuals")
> plot3(lmfit, type="pearson", predict.type="response", main="plot3b")
plot3 invoked call.dots
TRACE plotmo:::call.dots called deprefix(FUNC=residuals, PREFIX=PREFIX, ...,
                         DROP=DROP, KEEP=KEEP, TRACE=TRACE, FNAME="residuals",
                         FORMALS=FORMALS, SCALAR=SCALAR, CALLARGS=CALLARGS,
                         force.object=lm.object, type="pearson",
                         predict.type="response", main="plot3b")
PREFIX residuals.
DROP >PREFIX
     >EXPLICIT|^plotmo:::PLOTARGS|^predict\.|^plot\.
KEEP >STANDARDPREFIXES|^force\.|^def\.|^drop\.
     >PREFIX|^residuals\.
     >CALLARGS|^force\.object$
     >EXPLICIT
input dotnames       force.object type predict.type main
after DROP and KEEP  force.object type main
return dotnames      object type main

stats::residuals(object=lm.object, type="pearson", main="plot3b")
plot3 invoked call.dots
TRACE plotmo:::call.dots called deprefix(FUNC=predict, PREFIX=PREFIX, ...,
                         DROP=DROP, KEEP=KEEP, TRACE=TRACE, FNAME="predict",
                         FORMALS=FORMALS, SCALAR=SCALAR, CALLARGS=CALLARGS,
                         force.object=lm.object, type="pearson",
                         predict.type="response", main="plot3b")
PREFIX predict.
DROP .*
KEEP >STANDARDPREFIXES|^force\.|^def\.|^drop\.
     >PREFIX|^predict\.
     >CALLARGS|^force\.object$
     >EXPLICIT
input dotnames       force.object type predict.type main
after DROP and KEEP  force.object predict.type
return dotnames      object type

stats::predict(object=lm.object, type="response")
plot3 invoked call.dots
TRACE plotmo:::call.plot called call.dots(FUNC=plot.default, PREFIX=PREFIX,
                         ..., DROP="*", KEEP="PREFIX,PLOT.ARGS", TRACE=TRACE,
                         FNAME=fname, FORMALS=FORMALS, SCALAR=SCALAR,
                         CALLARGS=function.object, CALLER=caller,
                         force.x=c(-11,0,11,22,3...),
                         force.y=c(12,4,-2,-6,-8...), def.xlab="fitted",
                         def.ylab="residuals", type="pearson",
                         predict.type="response", main="plot3b")
PREFIX plot.
DROP .*
KEEP >STANDARDPREFIXES|^force\.|^def\.|^drop\.
     >PREFIX|^plot\.
     >CALLARGS|^force\.x$|^force\.y$|^def\.xlab$|^def\.ylab$
     >EXPLICIT
     >PLOT_ARGS|^add$|^adj$|^bty$|^cex$|^cex\.axis$|^cex\.lab$|^cex\.main$|^cex\.sub$|^col$|^col\.axis$|^col\.lab$|^col\.main$|^col\.sub$|^crt$|^family$|^font$|^font$|^font\.axis$|^font\.lab$|^font\.main$|^font\.sub$|^lend$|^ljoin$|^lmitre$|^lty$|^lwd$|^main$|^pch$|^srt$|^xaxp$|^xaxs$|^xaxt$|^xlab$|^xlim$|^xlog$|^xpd$|^yaxp$|^yaxs$|^yaxt$|^ylab$|^ylim$|^ylog$
input dotnames       force.x force.y def.xlab def.ylab type predict.type main
after DROP and KEEP  force.x force.y def.xlab def.ylab main
return dotnames      x y main xlab ylab

graphics::plot.default(x=c(-11,0,11,22,3...), y=c(12,4,-2,-6,-8...),
                       main="plot3b", xlab="fitted", ylab="residuals")
> 
> cat0("=== test callers.name\n")
=== test callers.name
> 
> test.callers.name <- function(x) {
+     caller0  <- plotmo:::callers.name(0)  # test.callers.name
+     caller1  <- plotmo:::callers.name(1)  # caller of test.callers.name
+     caller99 <- plotmo:::callers.name(99) # sys.call(-n) : not that many frames on the stack
+     s <- sprint("0 %s 1 %s 99 %s", caller0, caller1, caller99)
+     cat(s, "\n", sep="")
+     s
+ }
> print(plotmo:::callers.name()) # "eval"
[1] "NULL"
> myfunc <- function(func) func()
> stopifnot(myfunc(function(x) test.callers.name(99)) == "0 test.callers.name 1 func 99 unknown")
0 test.callers.name 1 func 99 unknown
> stopifnot(test.callers.name() == "0 test.callers.name 1 stopifnot 99 unknown")
0 test.callers.name 1 stopifnot 99 unknown
> 
> source("test.epilog.R")
