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!
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 ...
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
One way to work around the problem would be to specify "CPPFLAGS=/EHsc" and then in the loop use %%~a to get rid of the double quotes.
Another way to work around the problem would be to check the first character of %%a, and if it is a /
then prepend a =
to it. In order to achieve this you will need to setlocal enabledelayedexpansion
, assign %%a to a variable, and then use the %variable:~1,1% notation to extract the first character so you can compare it against /
. For more information about this notation, type help set
.
Update (after OP's update)
The following fragment appears to work, it is a bit simpler than the corresponding fragment in your solution, and it does not contain any hard-coded names of the arguments, so it is more general-purpose:
SET allargs=
FOR %%a IN (%*) DO (
SET curarg=%%a
IF "!curarg:~0,1!" EQU "/" (
SET allargs=!allargs!=!curarg!
) ELSE (
SET allargs=!allargs! !curarg!
)
)
ECHO !allargs!