Windows batch (cmd.exe) command line parameters and string manipulation

Lumi picture Lumi · Jan 30, 2012 · Viewed 10.4k times · Source

Let's consider this FOR loop in a Windows batch script:

D:\MiLu\Dev\C++\temp :: type string.bat
@ECHO OFF
FOR %%a IN (%*) DO ECHO %%a

It echoess all the arguments, one by one. Really?

D:\MiLu\Dev\C++\temp :: string.bat foo.obj bar.obj CPPFLAGS=/EHsc
foo.obj
bar.obj
CPPFLAGS
/EHsc

It splits command-line arguments not only on spaces (good), but also on = (not good). How can I prevent this from happening?

What I want to achieve is simple: A wrapper around NMAKE.exe that specifies /nologo to nmake and also - and this is the problem - to the compiler via the environment variables CFLAGS and CPPFLAGS while at the same time including any settings for CFLAGS and CPPFLAGS supplied on the command line.

In other words, I want to have the script add /nologo to the command line input for CFLAGS and CPPFLAGS even when there is none. Always /nologo! Don't annoy me with your logo, comrade compiler!

Update

Here's what I've come up with based on Mike's answer:

@ECHO OFF
SETLOCAL
SETLOCAL ENABLEDELAYEDEXPANSION

FOR %%a IN (%*) DO (
    SET var1=%%a
    ECHO %%a - !var1! - !var1:~0,1!
    IF "!var1:~0,1!" EQU "/" (
        ECHO gefunden: %%a !var1!
    )
)

Going to continue tomorrow ...

Update 2

Okay, given that tomorrow is already here I might just as well continue ... so here's a working solution, proudly presented. Feel free to comment on how to improve it.

@ECHO OFF
SETLOCAL
SETLOCAL ENABLEDELAYEDEXPANSION

SET files=
SET   CFLAGS=/nologo %CFLAGS%
SET CPPFLAGS=/nologo %CPPFLAGS%

SET state=normal
FOR %%a IN (%*) DO (
    SET curarg=%%a
    REM ECHO %%a - !curarg! - !curarg:~0,1!
    IF /I "%%a" EQU "CFLAGS" (
        SET state=expecting_cflags
    ) ELSE IF /I "%%a" EQU "CPPFLAGS" (
        SET state=expecting_cppflags
    ) ELSE (
        IF "!curarg:~0,1!" EQU "/" (
            REM ECHO gefunden: %%a !curarg!
            IF "!state!" EQU "expecting_cflags" (
                REM ECHO expecting_cflags
                SET CFLAGS=!CFLAGS! !curarg!
            ) ELSE IF "!state!" EQU "expecting_cppflags" (
                REM ECHO expecting_cppflags
                SET CPPFLAGS=!CPPFLAGS! !curarg!
            ) ELSE (
                ECHO Logikfehler >&2
            )
        ) ELSE (
            SET files=!files! !curarg!
        )
        SET state=normal
    )
)
ECHO Dateien:  !files! >&2
ECHO CFLAGS:   !CFLAGS! >&2
ECHO CPPFLAGS: !CPPFLAGS! >&2
:: ECHO ON
nmake /nologo %files% CFLAGS="%CFLAGS%" CPPFLAGS="%CPPFLAGS%"
ENDLOCAL

Answer

Dawood picture Dawood · Jan 30, 2012

Have you tried the following?

string.bat foo.obj bar.obj "CPPFLAGS=/EHsc"

If you're appending the CPPFLAGS argument yourself, try enclosing it in quotes.

Reference: http://www.robvanderwoude.com/parameters.php