Well, today was a fun exercise in a language I have not used in a while… MS-DOS batch files.

We author batch files that our Build Managers can use to compile all of our binaries, but I recently ran into a issue where I wanted to give them an option of providing some, or all, of the arguments needed to run the batch file.  If some were left out, then I would use some kind of default values.

Because of this, I wanted to use the command line pattern of -arg1=value1 -arg2=value2, which is not natively supported in a simple batch file.  Furthermore, I didn’t want to force a set sequence, so they could also use -arg2=value2 -arg1=value1.

It took some creative license (i.e. hacks) to get this to work correctly, but now I can use a standard command line argument pattern when creating these batch files.

Here’s the complete solution.

************************
UPDATE: I also added in the ability to provide option flags in addition to name/value pairs.

Syntax:  BATCH -project=MyProject -target=compile -sdkpath=C:\Flex\sdk -e -o
************************

ECHO OFF
CLS

REM =============================================================================
REM  Set default (empty) values for the variables that will be used to hold the
REM  values specified in the command line arguments.
REM =============================================================================
SET PROJECT=
SET TARGET=
SET SDKPATH=
SET EMAILLOG=
SET REMOTE=false

:PARSEARGUMENTS

REM =============================================================================
REM  Concatenate arguments 1 and 2 with an equals sign unless it is an option
REM  flag which we determine by looking at %2 and seeing if it starts with -
REM =============================================================================
SET ARGUMENT2=%2
if "%ARGUMENT2:~0,1%" == "-" (
    SET commandline=%1=
    SET ARGUMENTTYPE=single
) else (
    SET commandline=%1=%2
    SET ARGUMENTTYPE=double
)

REM =============================================================================
REM  If the first argument is just an equals sign, we've parsed all the arguments
REM =============================================================================
IF "commandline%" == "=" GOTO DONEPARSING

REM =============================================================================
REM  Clear out the values for the switch and the value
REM =============================================================================
SET SWITCH=
SET VALUE=

REM =============================================================================
REM  Using the equals sign as the delimiter, set the SWITCH variable to the
REM  argument name, and the VALUE variable to the argument value
REM =============================================================================
FOR /f "tokens=1,2 delims==" %%a IN ("%commandline%") DO SET SWITCH=%%a&SET VALUE=%%b

REM =============================================================================
REM  Put an IF condition for each command line argument that you are expecting
REM  on the command line, and set the corresponding variable to what's contained
REM  in the VALUE variable.
REM
REM  Then use the SHIFT command twice to move to the next name/value pair.
REM =============================================================================
IF "%SWITCH%" == "-sdkpath" (
    SET SDKPATH=%VALUE%
    GOTO SHIFTER
) 

IF "%SWITCH%" == "-target" (
    SET TARGET=%VALUE%
    GOTO SHIFTER
)

IF "%SWITCH%" == "-project" (
    SET PROJECT=%VALUE%
    GOTO SHIFTER
)

IF "%SWITCH%" == "-e" (
    SET EMAILLOG=yes
    GOTO SHIFTER
)

:SHIFTER
IF "%ARGUMENTTYPE%" == "single" (
    SHIFT
) ELSE (
    SHIFT
    SHIFT
)

REM =============================================================================
REM  Start the parsing process all over again.
REM =============================================================================
GOTO PARSEARGUMENTS

:DONEPARSING