Henrik Bengtsson
2013-Jan-07 02:00 UTC
[Rd] aspell(..., dictionaries) incorrectly passes double-quoted arguments via shell() [and a patch]
Hi, I think I found a bug in aspell() on Windows. Specifying argument 'dictionaries' for aspell() does not work on Windows, which I believe is because it tries to pass a quoted command line option via shell(). THIS WORKS: # Create a text file to be spell checked> writeLines(c("Hello", "world", "ANOVA"), con="text.txt")# Check it (word 'babaa' is unknown)> aspell("text.txt")ANOVA text.txt:3:1 THIS DOES NOT WORK: # Get a dictionary> url <- "http://svn.r-project.org/R/trunk/share/dictionaries/en_stats.rds" > download.file(url, "en_stats.rds", mode="wb")# Check it> aspell("text.txt", dictionaries="./en_stats.rds")Error in aspell("text.txt", dictionaries = "./en_stats.rds") : Running aspell failed with diagnostics: The filename, directory name, or volume label syntax is incorrect. In addition: Warning message: In shell(sprintf("%s > %s 2> %s", command, outfile, errfile), input = input, : '"C:\PROGRA~2\Aspell\bin\aspell.exe" -a -p "C:\Users\hb\AppData\Local\Temp\RtmpueSaQa\aspell_personal1d1c378e3241" < C:\Users\hb\AppData\Local\Temp\RtmpueSaQa\aspell1d1c64e663c9 > C:\Users\hb\AppData\Local\Temp\RtmpueSaQa\xshell1d1c724c140 2> C:\Users\hb\AppData\Local\Temp\RtmpueSaQa\xshell1d1c731063f3' execution failed with error code 1 (You get a similar error with 'R CMD check' and system environment flag '_R_CHECK_CRAN_INCOMING_USE_ASPELL_' set). TROUBLESHOOTING: I rather sure that the above error occurs because the value for command line argument '-p' is quoted, i.e. -p "C:\Users\hb\AppData\Local\Temp\RtmpueSaQa\aspell_personal1d1c378e3241" and then passed to shell(). The shell() expands to a system("cmd /c ...") call on Windows, and the handling of quotation marks by "cmd /c" is rather peculiar (for details see the paragraph starting with "If /C or /K is specified, then [...] the following logic is used to process quote (") characters [...]" in 'cmd /?'). Example: % cmd /c R --slave -e "print(1:3)" [1] 1 2 3 % cmd /c "R" --slave -e "print(1:3)" 'R" --slave -e "print' is not recognized as an internal or external command, operable program or batch file. x:\calmate,R-forge>cmd /c "R" --slave -e print(1:3) [1] 1 2 3 x:\calmate,R-forge>cmd /c "R" --slave -e 'print(1:3)' [1] "print(1:3)" PATCH: Because the the personal dictionary used by aspell() is passed via tempfile("aspell_personal", tmpdir=tempdir()) it does not need to be quoted on Windows, because such a temporary pathname will never contain spaces, cf. "If the path to the directory contains a space in any of the components, the path returned will use the shortnames version of the path" from help("tempdir"). A patch is therefore: --- aspell.R 2012-10-16 20:17:38.126736100 -0700 +++ aspell,patch.R 2013-01-06 17:45:44.092499300 -0800 @@ -111,7 +111,8 @@ aspell_write_personal_dictionary_file(words, personal, program = program) ## </FIXME> - control <- c(control, "-p", shQuote(personal)) + if (.Platform$OS.type != "windows") personal <- shQuote(personal) + control <- c(control, "-p", personal) } } /Henrik> sessionInfo()R Under development (unstable) (2013-01-05 r61554) Platform: x86_64-w64-mingw32/x64 (64-bit) locale: [1] LC_COLLATE=English_United States.1252 [2] LC_CTYPE=English_United States.1252 [3] LC_MONETARY=English_United States.1252 [4] LC_NUMERIC=C [5] LC_TIME=English_United States.1252 attached base packages: [1] stats graphics grDevices utils datasets methods base loaded via a namespace (and not attached): [1] tools_3.0.0