scala/scala — pull request #3065 by retronym (2013-10-21 07:34:50+00:00)
Title: SI-7295 Fix windows batch file with args containing parentheses

In command scripts, substitution of `FOO` in `if cond ( %FOO% )` happens
*before* the condition is evaluated. One can use delayed expansion with
`if cond (!FOO!)` to get a saner behaviour. Or, as I ended up doing here, use
a goto in the body of the if rather than referring directly to variables
there.

Here's a cut down version to demonstrate the old problem:

C:\Users\IEUser>type test.cmd
@echo off

setlocal enableextensions enabledelayedexpansion

if [%~1]==[-toolcp] (
set CP=%~2
shift
shift
)
echo -toolcp %CP%
echo %~1 %~2

C:\Users\IEUser>test.cmd a b
-toolcp
a b

C:\Users\IEUser>test.cmd -toolcp "c:\program files" a b
-toolcp c:\program files
a b

C:\Users\IEUser>test.cmd -toolcp "c:\program files" "a()b" "c()d"
-toolcp c:\program files
a()b c()d

C:\Users\IEUser>test.cmd "a()b" "c()d"
d was unexpected at this time.

I don't understand exactly why the parentheses only mess things up in this
situation. But regardless, lets find another way.

My first attempt to fix this was based on the suggestion in the ticket. But,
as shown below, this fails to capture the -toolcp.

C:\Users\IEUser>type test.cmd
@echo off

setlocal enableextensions enabledelayedexpansion

if [%~1]==[-toolcp] (
set CP=!2!
shift
shift
)
echo -toolcp %CP%
echo %~1 %~2
C:\Users\IEUser>test.cmd "a()b" "c()d"
-toolcp
a()b c()d

C:\Users\IEUser>test.cmd -toolcp "c:\program files" "a()b" "c()d"
-toolcp
a()b c()d

Last stop was the goto you'll find in this patch.

With this patch applied, I tested on Windows 8 with the following:

C:\Users\IEUser>type Desktop\temp.cmd
::#!
@echo off
call scala %0 %*
goto :eof
::!#
println("hello, world")
println(argv.toList)

C:\Users\IEUser>scala Desktop\temp.cmd "foo(bar)baz"
"java" -Xmx256M -Xms32M -Dscala.home="C:\PROGRA~3\scala\bin\.."
-Denv.emacs="" -Dscala.usejavacp=true -cp "..."
scala.tools.nsc.MainGenericRunner Desktop\temp.cmd "foo(bar)baz"

hello, world
List(foo(bar)baz)

C:\Users\IEUser>scala -toolcp "c:\program files" Desktop\temp.cmd
"foo(bar)baz"
"java" -Xmx256M -Xms32M -Dscala.home="C:\PROGRA~3\scala\bin\.."
-Denv.emacs="" -Dscala.usejavacp=true -cp "...;c:\program files"
scala.tools.nsc.MainGenericRunner -toolcp "c:\program files"
Desktop\temp.cmd "foo(bar)baz"

hello, world
List(foo(bar)baz)