diff --git a/bin/spack.bat b/bin/spack.bat index 310b59506c..2c2947ac0f 100644 --- a/bin/spack.bat +++ b/bin/spack.bat @@ -50,24 +50,69 @@ setlocal enabledelayedexpansion :: flags will always start with '-', e.g. --help or -V :: subcommands will never start with '-' :: everything after the subcommand is an arg -for %%x in (%*) do ( - set t="%%~x" + +:: we cannot allow batch "for" loop to directly process CL args +:: a number of batch reserved characters are commonly passed to +:: spack and allowing batch's "for" method to process the raw inputs +:: results in a large number of formatting issues +:: instead, treat the entire CLI as one string +:: and split by space manually +:: capture cl args in variable named cl_args +set cl_args=%* +:process_cl_args +:: tokens=1* returns the first processed token produced +:: by tokenizing the input string cl_args on spaces into +:: the named variable %%g +:: While this make look like a for loop, it only +:: executes a single time for each of the cl args +:: the actual iterative loop is performed by the +:: goto process_cl_args stanza +:: we are simply leveraging the "for" method's string +:: tokenization +for /f "tokens=1*" %%g in ("%cl_args%") do ( + set t=%%~g + :: remainder of string is composed into %%h + :: these are the cl args yet to be processed + :: assign cl_args var to only the args to be processed + :: effectively discarding the current arg %%g + :: this will be nul when we have no further tokens to process + set cl_args=%%h + :: process the first space delineated cl arg + :: of this iteration if "!t:~0,1!" == "-" ( if defined _sp_subcommand ( :: We already have a subcommand, processing args now - set "_sp_args=!_sp_args! !t!" + if not defined _sp_args ( + set "_sp_args=!t!" + ) else ( + set "_sp_args=!_sp_args! !t!" + ) ) else ( - set "_sp_flags=!_sp_flags! !t!" - shift + if not defined _sp_flags ( + set "_sp_flags=!t!" + shift + ) else ( + set "_sp_flags=!_sp_flags! !t!" + shift + ) ) ) else if not defined _sp_subcommand ( set "_sp_subcommand=!t!" shift ) else ( - set "_sp_args=!_sp_args! !t!" - shift + if not defined _sp_args ( + set "_sp_args=!t!" + shift + ) else ( + set "_sp_args=!_sp_args! !t!" + shift + ) ) ) +:: if this is not nil, we have more tokens to process +:: start above process again with remaining unprocessed cl args +if defined cl_args goto :process_cl_args + :: --help, -h and -V flags don't require further output parsing. :: If we encounter, execute and exit @@ -95,31 +140,21 @@ if not defined _sp_subcommand ( :: pass parsed variables outside of local scope. Need to do :: this because delayedexpansion can only be set by setlocal -echo %_sp_flags%>flags -echo %_sp_args%>args -echo %_sp_subcommand%>subcmd -endlocal -set /p _sp_subcommand=