:ForIF Function, evaluates arguments like a IF inside a for (but there's strange behaviour ?)
Posted: 24 Sep 2023 17:37
Hi,
I needed to evaluate an IF inside a for loop.
I didn't want to go into delayedexpansion and out again.
So instead, I created the function :ForIF
This function works as expected.
does return
Great !
I have tested several more permutations, works as you would expect.
It even works byref too
it returns as expected
I also ran multiple permutation and it runs as expected.
But when I went to operate as expected inside a for loop, suddenly it breaks !
Suppose this simple for loop
You would expect it to print numbers 1 through 9
but it only outputs
So I created a debug version of :ForIF
This will print the input parameters before dereferencing
This will directly print the result of the evaluation
Here is the full code
And here is the output of all that
I don't get it !!!
"19" LSS "10" evaluates to false !?
How is that possible ?
Here is my complete DEMO file with every test permutation
I needed to evaluate an IF inside a for loop.
I didn't want to go into delayedexpansion and out again.
So instead, I created the function :ForIF
Code: Select all
::Usage Call :ForIF FirstTerm Operator SecondTerm
:ForIF
set "_ForIF_first_term=%~1"
set "_ForIF_operator=%~2"
set "_ForIF_second_term=%~3"
if defined %_ForIF_first_term% call set "_ForIF_first_term=%%%_ForIF_first_term%%%"
if defined %_ForIF_second_term% call set "_ForIF_second_term=%%%_ForIF_second_term%%%"
if "%_ForIF_first_term%" %_ForIF_operator% "%_ForIF_second_term%" ( set "_ForIF_first_term=" & set "_ForIF_operator=" & set "_ForIF_second_term=" & exit /b 0 ) else (
set "_ForIF_first_term=" & set "_ForIF_operator=" & set "_ForIF_second_term=" & exit /b 1 )
Code: Select all
call :forif 1 GTR 5 && echo 1 is greater than 5 || echo 1 is not greater than 5
Code: Select all
1 is not greater than 5
I have tested several more permutations, works as you would expect.
It even works byref too
Code: Select all
set _myfirstterm=6748
set _mysecondterm=2983
call :forif _myfirstterm EQU _mysecondterm && echo %_myfirstterm% is equal to %_mysecondterm% || echo %_myfirstterm% is not equal to %_mysecondterm%
Code: Select all
6748 is not equal to 2983
But when I went to operate as expected inside a for loop, suddenly it breaks !
Suppose this simple for loop
Code: Select all
for /l %%a in (1,1,20) do (
set /a _myloop+=1
call :ForIF _myloop LSS 10 && echo %%a
)
You would expect it to print numbers 1 through 9
but it only outputs
Code: Select all
1
Code: Select all
::Usage Call :ForIFdebug FirstTerm Operator SecondTerm
:ForIFdebug
set "_ForIF_first_term=%~1"
set "_ForIF_operator=%~2"
set "_ForIF_second_term=%~3"
echo 00%_ForIF_first_term% %_ForIF_operator% %_ForIF_second_term%
if defined %_ForIF_first_term% call set "_ForIF_first_term=%%%_ForIF_first_term%%%"
if defined %_ForIF_second_term% call set "_ForIF_second_term=%%%_ForIF_second_term%%%"
if "%_ForIF_first_term%" %_ForIF_operator% "%_ForIF_second_term%" ( echo 11yes "%_ForIF_first_term%" %_ForIF_operator% "%_ForIF_second_term%" ) else ( echo 11no "%_ForIF_first_term%" %_ForIF_operator% "%_ForIF_second_term%" )
if "%_ForIF_first_term%" %_ForIF_operator% "%_ForIF_second_term%" ( set "_ForIF_first_term=" & set "_ForIF_operator=" & set "_ForIF_second_term=" & exit /b 0 ) else (
set "_ForIF_first_term=" & set "_ForIF_operator=" & set "_ForIF_second_term=" & exit /b 1 )
Code: Select all
echo 00%_ForIF_first_term% %_ForIF_operator% %_ForIF_second_term%
Code: Select all
if "%_ForIF_first_term%" %_ForIF_operator% "%_ForIF_second_term%" ( echo 11yes "%_ForIF_first_term%" %_ForIF_operator% "%_ForIF_second_term%" ) else ( echo 11no "%_ForIF_first_term%" %_ForIF_operator% "%_ForIF_second_term%" )
Code: Select all
@echo off
:setup
:main
echo.&echo Calling :ForIF-broken-mini-DEMO debug version
call :ForIF-debug-broken-mini-DEMO
GoTo :EOF
:ForIF-debug-broken-mini-DEMO
echo.&echo This should print numbers from 1 to 9, this calls the ForIF debug version
set "_myloop="
for /l %%a in (1,1,20) do (
set /a _myloop+=1
call :ForIFdebug _myloop LSS 10 && echo debug%%a
)
GoTo :EOF
::Usage Call :ForIFdebug FirstTerm Operator SecondTerm
:ForIFdebug
set "_ForIF_first_term=%~1"
set "_ForIF_operator=%~2"
set "_ForIF_second_term=%~3"
echo 00%_ForIF_first_term% %_ForIF_operator% %_ForIF_second_term%
if defined %_ForIF_first_term% call set "_ForIF_first_term=%%%_ForIF_first_term%%%"
if defined %_ForIF_second_term% call set "_ForIF_second_term=%%%_ForIF_second_term%%%"
if "%_ForIF_first_term%" %_ForIF_operator% "%_ForIF_second_term%" ( echo 11yes "%_ForIF_first_term%" %_ForIF_operator% "%_ForIF_second_term%" ) else ( echo 11no "%_ForIF_first_term%" %_ForIF_operator% "%_ForIF_second_term%" )
if "%_ForIF_first_term%" %_ForIF_operator% "%_ForIF_second_term%" ( set "_ForIF_first_term=" & set "_ForIF_operator=" & set "_ForIF_second_term=" & exit /b 0 ) else (
set "_ForIF_first_term=" & set "_ForIF_operator=" & set "_ForIF_second_term=" & exit /b 1 )
And here is the output of all that
Code: Select all
ForIF-DEMO.bat
Calling :ForIF-broken-mini-DEMO debug version
This should print numbers from 1 to 9, this calls the ForIF debug version
00_myloop LSS 10
11yes "1" LSS "10"
debug1
00_myloop LSS 10
11no "2" LSS "10"
00_myloop LSS 10
11no "3" LSS "10"
00_myloop LSS 10
11no "4" LSS "10"
00_myloop LSS 10
11no "5" LSS "10"
00_myloop LSS 10
11no "6" LSS "10"
00_myloop LSS 10
11no "7" LSS "10"
00_myloop LSS 10
11no "8" LSS "10"
00_myloop LSS 10
11no "9" LSS "10"
00_myloop LSS 10
11no "10" LSS "10"
00_myloop LSS 10
11no "11" LSS "10"
00_myloop LSS 10
11no "12" LSS "10"
00_myloop LSS 10
11no "13" LSS "10"
00_myloop LSS 10
11no "14" LSS "10"
00_myloop LSS 10
11no "15" LSS "10"
00_myloop LSS 10
11no "16" LSS "10"
00_myloop LSS 10
11no "17" LSS "10"
00_myloop LSS 10
11no "18" LSS "10"
00_myloop LSS 10
11no "19" LSS "10"
00_myloop LSS 10
11no "20" LSS "10"
I don't get it !!!
"19" LSS "10" evaluates to false !?
How is that possible ?
Here is my complete DEMO file with every test permutation