Last active
February 10, 2016 18:04
-
-
Save leppie/2721371adf6bf69fa833 to your computer and use it in GitHub Desktop.
Command line parsing in a batch file (or scripting for the mildly insane)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@echo off | |
setlocal EnableDelayedExpansion | |
:: user settings | |
set VERBOSE=0 | |
set ERRORS=0 | |
:: arg parsing settings | |
set ARGS=verbose debug-mode | |
:: implementation start | |
set $ARGS=%* | |
:: defaults | |
if not defined PREFIX set PREFIX=- | |
if not defined SEPERATOR set SEPERATOR== | |
if not defined SUPPORT_SHORT_FORMS set SUPPORT_SHORT_FORMS=1 | |
if not defined SHOW_ARGS set SHOW_ARGS=0 | |
:: get rid of =, replace with : | |
set X="%$ARGS%" | |
:sep-loop | |
for /f "tokens=1* delims=%SEPERATOR%" %%x in (%X%) do ( | |
if "%%y" NEQ "" ( | |
set $NEW=!$NEW!%%x: | |
set X="%%y" | |
goto sep-loop | |
) else set $NEW=!$NEW!%%x) | |
set $ARGS=%$NEW% | |
call :loop %$ARGS% | |
goto script | |
:loop | |
for %%m in (%ARGS%) do call :slurp %%m %1 | |
if [%1] NEQ [] ( | |
:: try default arg | |
if not defined $HANDLED call :checkdefault %1 | |
:: odd way to restore SEPERATOR | |
set $TMP=%1 | |
call set $TMP=%%$TMP::=%SEPERATOR%%% | |
if not defined $HANDLED call :unhandled !$TMP! 2>nul) | |
set $HANDLED= | |
shift | |
set param=%1 | |
if defined param goto :loop | |
goto :eof | |
:checkdefault | |
set $DEFAULT=%1 | |
if [^%$DEFAULT:~0,1%] NEQ [%PREFIX%] ( | |
call :default %1 2>nul | |
if !ERRORLEVEL! EQU 0 ( | |
set $HANDLED=1 | |
if %SHOW_ARGS% EQU 1 echo %1)) | |
goto :eof | |
:slurp | |
set $SLURP=%1 | |
for /f "tokens=1,2* delims=:" %%b in ("%2") do ( | |
if %SUPPORT_SHORT_FORMS% EQU 1 ( | |
if %%b == %PREFIX%%$SLURP:~0,1% call :dispatch %%b %%c | |
if %%b == %PREFIX%%PREFIX%%$SLURP% call :dispatch %%b %%c | |
) else if %%b == %PREFIX%%$SLURP% call :dispatch %%b %%c) | |
goto :eof | |
:dispatch | |
if %SHOW_ARGS% EQU 1 ( | |
if [%2] EQU [] echo %1 | |
else echo %1%SEPERATOR%%2) | |
call :%$SLURP% %2 2> nul | |
IF %ERRORLEVEL% NEQ 0 echo [Error] Handler not found for "%$SLURP%" | |
set $HANDLED=1 | |
goto :eof | |
:: implementation end | |
:: define arg handlers | |
:unhandled (optional) | |
:: record/log errors, cant bail here, only in :script | |
echo [Error] Unhandled arg: %* | |
set /a ERRORS+=1 | |
goto :eof | |
:default (optional) | |
set DEFAULT=%1 | |
goto :eof | |
:verbose | |
:: set /a VERBOSE+=%1 | |
set VERBOSE=%1 | |
goto :eof | |
:debug-mode | |
set DEBUG=1 | |
goto :eof | |
:: finally what will be run after parsing is complete | |
:script | |
if %ERRORS% GTR 0 endlocal & exit /b 1 | |
echo VERBOSE: %VERBOSE% | |
if defined DEBUG echo DEBUG: SET | |
if defined DEFAULT echo DEFAULT: %DEFAULT% | |
echo Done | |
:: example run with '-v=1 --debug-mode "moo poo"' | |
:: handles balanced quotes | |
endlocal |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment