I am still struggling to properly understand the behaviour of Disable/EnableDelayedExpansion...
I want to parse input arguments when calling something like command -a -b -c file such to finally have options=-a -b -c and filename=file.
To do so I use the FOR /f loop:
set "count=0"
set "opts="
set "fl="
set tmpv=
:argloop
for /f tokens^=1^,^*^ delims^= %%a in ("%1") do (
echo.
echo Chosen option is %1
set /a count+=1
echo.
echo Reading %count% is %%a..
set "tmpv=%%a"
rem setlocal enabledelayedexpansion
echo Tmp is %tmpv% after set equal %%variable.
rem endlocal
rem setlocal disabledelayedexpansion
set "tmpv=%tmpv:-=%"
rem setlocal enabledelayedexpansion
echo After removing it writes !tmpv!
rem endlocal
rem setlocal disabledelayedexpansion
if "%tmpv%"=="%%a" (
echo Input does not contain "-"
set "fl=%tmpv%"
echo %fl%
) else (
echo/Options before are %opts%
echo.
if "%opts%"=="" (
echo Options are empty.
set opts=%%a
) else (
set "opts=%opts% %%a"
)
)
if not "%2"=="" (shift & goto:argloop)
)
echo.
echo Finally options are %opts%
set opts=%opts:-=/%
echo Finally options are %opts%
echo File name %fl%
set tmpv=
set count=
goto:end
Output writes:
Chosen option is -a
Reading 1 is -a..
Tmp is after set equal %variable.
After removing it writes
Options before are
Options are empty.
Chosen option is -b
Reading 2 is -b..
Tmp is -= after set equal %variable.
After removing it writes -=
Options before are -a
Chosen option is -c
Reading 3 is -c..
Tmp is = after set equal %variable.
After removing it writes =
Options before are -a -b
Chosen option is flfl
Reading 4 is flfl..
Tmp is = after set equal %variable.
After removing it writes =
Options before are -a -b -c
Finally options are -a -b -c flfl
Finally options are /a /b /c flfl
File name
I had made it working with EnableDelayedExpansion, but not capable of storing final %fl% variable.
But why does it not work this way (without using delayed expansions)??
I will sincerely appreciate whom will try to clarify it in all extents.
The rules really aren't too hard.
You are aware that
%var%is resolved to the value ofvar.When a loop is parsed, every
%var%within that loop is replaced by the THEN-current value ofvar. This includes pseudovariables like %cd%, %errorlevel% and %random%.If
delayedexpansionis in effect (and it is "in effect" from thesetlocal enabledelayedexpansioninstruction [start-of-setlocal-bracket] until anendlocalorend-of-file[end-of-setlocal-bracket] is reached) then!var!is resolved to the contents ofvarat the time that particular instruction (set,echo, etc) is executed.If
delayedexpansionis NOT in effect then!var!is simply that - the literal string!var!.And one small kink. Any change made to the environment (addition, deletion or variation of variable values) is discarded when a
setlocalbracket ends.So, in all probability, you could display the difference by
echoing%var%alongside!var!%%x(ametavariable) is always resolved to its current value, regardless ofsetlocalstatus.[After responses]
Since all
setlocal enabledelayedexpansion/endlocalbrackets areremmed-out in the published code, I'm not surprised at the results.However, running the published code does not yield the published results - for me, the response was "Reading 0"..."Reading 3".
So, looking at the
forloop, I believe it's equivalent towhich in turn is the same as
since there are no delimiters, an this is effectively the same as
which does nothing beyond assigning
%1to%%aand making the entire loop oneblock statement.So therefore, this code should do the same job - without the kinkiness afforded by
setlocal...I've assumed that a proper batch-debug environment has been established; hence
goto :eofto terminate the batch and an inintialsetlocalto preserve the original environment.When you use the point-click-and-giggle method of executing a batch, the batch window will often close if a syntax-error is found. You should instead open a 'command prompt' and run your batch from there so that the window remains open and any error message will be displayed.
--- BUT ---
In testing, I tried this:
Which didn't do what I expected it to do - that is, report
Instead, it reported
Which I find puzzling as the
!var!is outside thesetlocal enabledelayedexpansion/endlocalcommand-bracket and hence should not have been replaced, in my view.Seems like an @jeb problem to me... so I'll see whether he's got an explanation...