diff options
-rw-r--r-- | bin/spack.bat | 107 |
1 files changed, 71 insertions, 36 deletions
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=<subcmd -set /p _sp_flags=<flags -set /p _sp_args=<args -if "%_sp_subcommand%"=="ECHO is off." (set "_sp_subcommand=") -if "%_sp_subcommand%"=="ECHO is on." (set "_sp_subcommand=") -if "%_sp_flags%"=="ECHO is off." (set "_sp_flags=") -if "%_sp_flags%"=="ECHO is on." (set "_sp_flags=") -if "%_sp_args%"=="ECHO is off." (set "_sp_args=") -if "%_sp_args%"=="ECHO is on." (set "_sp_args=") -del subcmd -del flags -del args +endlocal & ( + set "_sp_flags=%_sp_flags%" + set "_sp_args=%_sp_args%" + set "_sp_subcommand=%_sp_subcommand%" +) + :: Filter out some commands. For any others, just run the command. -if %_sp_subcommand% == "cd" ( +if "%_sp_subcommand%" == "cd" ( goto :case_cd -) else if %_sp_subcommand% == "env" ( +) else if "%_sp_subcommand%" == "env" ( goto :case_env -) else if %_sp_subcommand% == "load" ( +) else if "%_sp_subcommand%" == "load" ( goto :case_load -) else if %_sp_subcommand% == "unload" ( +) else if "%_sp_subcommand%" == "unload" ( goto :case_load ) else ( goto :default_case @@ -154,20 +189,20 @@ goto :end_switch if NOT defined _sp_args ( goto :default_case ) -set args_no_quote=%_sp_args:"=% -if NOT "%args_no_quote%"=="%args_no_quote:--help=%" ( + +if NOT "%_sp_args%"=="%_sp_args:--help=%" ( goto :default_case -) else if NOT "%args_no_quote%"=="%args_no_quote: -h=%" ( +) else if NOT "%_sp_args%"=="%_sp_args: -h=%" ( goto :default_case -) else if NOT "%args_no_quote%"=="%args_no_quote:--bat=%" ( +) else if NOT "%_sp_args%"=="%_sp_args:--bat=%" ( goto :default_case -) else if NOT "%args_no_quote%"=="%args_no_quote:deactivate=%" ( +) else if NOT "%_sp_args%"=="%_sp_args:deactivate=%" ( for /f "tokens=* USEBACKQ" %%I in ( - `call python %spack% %_sp_flags% env deactivate --bat %args_no_quote:deactivate=%` + `call python %spack% %_sp_flags% env deactivate --bat %_sp_args:deactivate=%` ) do %%I -) else if NOT "%args_no_quote%"=="%args_no_quote:activate=%" ( +) else if NOT "%_sp_args%"=="%_sp_args:activate=%" ( for /f "tokens=* USEBACKQ" %%I in ( - `python %spack% %_sp_flags% env activate --bat %args_no_quote:activate=%` + `python %spack% %_sp_flags% env activate --bat %_sp_args:activate=%` ) do %%I ) else ( goto :default_case @@ -188,7 +223,7 @@ if defined _sp_args ( for /f "tokens=* USEBACKQ" %%I in ( `python "%spack%" %_sp_flags% %_sp_subcommand% --bat %_sp_args%`) do %%I -) + goto :end_switch :case_unload |