I have some scripts which define macros within FOR loops and these macros are called using FOR loops.
I have some other scripts which call these scripts within FOR loops.
When doing so, i noticed that FOR variables within macro definitions are overridden.
I have a work-around, but i would like to know:
Q: Is this behavior to be expected?
Q: Is there a way to call scripts within FOR loops AND to keep %%A empty when defining macros within FOR loops?
Note: delayed expansion is not acceptable as part of the solution.
The actual used code in my project imho does not serve the topic.
I created some example scripts which reproduce the situation as described.
Script which defines macros within FOR loops using FOR loops, i named it callee.cmd:
Code: Select all
@echo off
REM @SITUATION: FOR variable %%A gets overridden when script is called by other script within FOR loop.
REM @NOTE: %%A doesn't stay empty as expected while defining the macro,
REM instead it expands to the FOR variable of the caller script.
REM @TODO: find a way to call script within FOR loop AND to keep %%A empty
REM when defining the macros.
REM @FIX: no fix yet, work-around is to call script directly,
REM NOT within FOR loop context.
REM Define macro to call macros:
set __call=for %%A in
for %%g in (__macro) do (
REM Define sample macro in FOR loop:
REM @NOTE: here, the variable "%%~A" gets overridden when this script is called by other script within FOR loop:
set "%%~g= do (if /i "%%~A" equ "_some value" (echo("some value" detected) else (echo(incorrect value detected))"
)
REM Display contents of macros:
set __call
set __macro
REM Call macro with argument:
%__call%("_%*") %__macro%
exit /b
This will give expected results:
__call=for %A in
__macro= do (if /i "%~A" equ "_some value" (echo("some value" detected) else (echo(incorrect value detected))
"some value" detected
An other script, which i named caller_directly.cmd, demonstrates correct results when callee.cmd is called via this script:
Code: Select all
@echo off
REM @NOTE: calling script.
call callee.cmd %*
exit /b
This will also give expected results:
__call=for %A in
__macro= do (if /i "%~A" equ "_some value" (echo("some value" detected) else (echo(incorrect value detected))
"some value" detected
The last script, which i named caller_FOR.cmd, invokes and reproduces the issue:
Code: Select all
@echo off
for %%A in (whatever) do (
REM @NOTE: calling script within FOR loop context.
call callee.cmd %*
)
exit /b
This will give the following results:
__call=for %A in
__macro= do (if /i "whatever" equ "_some value" (echo("some value" detected) else (echo(incorrect value detected))
incorrect value detected
Notice the "whatever" part has overridden the "%%~A" part in the macro definition.
If this behavior is to be expected, and no solution is available, i'll stick to the work-around of NOT calling such scripts within FOR loop context but always call these scripts directly.
Edit: using %%a instead of %%A doesn't really solve the issue. %%A here is just an example.