Page 1 of 1
CALL it only IF it is FOR no reason
Posted: 22 Apr 2014 13:23
by npocmaka_
Here many many ...many moons ago I've wondered why I can't CALL FOR and IF command. But it turned out that this was yet another case when I've underestimated the cmd.exe . It is possible to call IF and FOR:
Code: Select all
@echo off
rem :: this will produce an error
rem if a equ a
rem :: And this too
rem call if a equ a rem
rem :: But this will not!!!
call if a equ a
rem :: This will not too ((\but in command prompt single % is enough)
call for %%%%a in (.) do
rem :: And this
call if a equ a for %%%%a in (.) do if 1 equ 1 for %%%%a in (.) do if c==c
rem :: And this
call if a equ a for %%%%a in (.) do if 1 equ 1 for %%%%a in (.) do if c==c ( rem rem rem echo something
Though it's not useful at all as it does not work if there is finished statement/command after if/for block. But it is an insane bug

and shows that the FOR and IF parsers should have something in common.
Re: CALL it only IF it is FOR no reason
Posted: 22 Apr 2014 20:27
by Liviu
Nice topic title

npocmaka_ wrote:It is possible to call IF and FOR:
Don't think that "a equ a" is actually relevant, "call if ???" also "works" i.e. does nothing. More examples in the thread at
http://www.dostips.com/forum/viewtopic.php?p=32829#p32829 with some curious findings, but no real resolution.
Liviu
Re: CALL it only IF it is FOR no reason
Posted: 23 Apr 2014 02:19
by npocmaka_
Almost every time I think I find something new it's not new

. Should search more careful next time.
At least the open bracket behavior and composition of for/if seem to be something new (but at the same degree useless)
My picture of the cmd source code is more like a bowl of spaghetti
Do you have decompiled cmd? My attempts with opensource decompilers failed...
Re: CALL it only IF it is FOR no reason
Posted: 23 Apr 2014 07:49
by Squashman
npocmaka_ wrote:Do you have decompiled cmd? My attempts with opensource decompilers failed...
I believe someone who posts on this forum did it last year. Trying to find the thread.
Re: CALL it only IF it is FOR no reason
Posted: 23 Apr 2014 15:39
by jeb
Liviu wrote:Don't think that "a equ a" is actually relevant, "call if ???" also "works" i.e. does nothing.
I assume, that CALL suppress some sorts of parser errors.
So the samples don't work, they only don't show an error message.
Code: Select all
@echo off
set "var1=echo Test1 X & echo Y"
set "var2=echo Test2 X ^& echo Y"
call %%var1%%
call %%var2%%
Output wrote:Test2 X & echo Y
jeb
Re: CALL it only IF it is FOR no reason
Posted: 23 Apr 2014 23:30
by Liviu
npocmaka_ wrote: My picture of the cmd source code is more like a bowl of spaghetti
Do you have decompiled cmd? My attempts with opensource decompilers failed...
No, that would kill all fun of trying to second guess it

Besides, my take on decompilers is along the line of (paraphrased) "can't bring a cow back from hamburgers".
jeb wrote:I assume, that CALL suppress some sorts of parser errors.
So the samples don't work, they only don't show an error message.
Right. Now that you mentioned it, there even appears to be an errorlevel returned.
Code: Select all
C:\tmp>(call if ???) && (echo OK) || (echo failed)
failed
Liviu
Re: CALL it only IF it is FOR no reason
Posted: 24 Jun 2014 05:54
by npocmaka_
One more thing that started to bother me with CALL.If you call something in in brackets it wont be executed:
Code: Select all
call (echo "I just call to say I love you")
Even non-existent commands wont produce an error:
Code: Select all
call ( gibberish) && echo successful execution
the only things that annoys CALL are some parsing errors:
Code: Select all
call ( if a=
call ( :%~ gives an error only from a batch file )
call (^)
Re: CALL it only IF it is FOR no reason
Posted: 26 Jun 2014 12:30
by npocmaka_
Call parser is pretty buggy . Here are more strange cases for CALL with brackets:
Code: Select all
>call ((echo TEST)
>call (( echo TEST ))
'1' is not recognized as an internal or external command,
operable program or batch file.
>call ( @echo TEST )
'9' is not recognized as an internal or external command,
operable program or batch file.
>echo @echo echo from 1.bat >1.bat
>echo @echo echo from 9.bat >9.bat
>call (( echo TEST ))
echo from 1.bat
>echo (@echo TEST)
(@echo TEST)
>call (echo /?)
....call help...
When CALL is used with an expression with more than one pair of brackets it searches (at least on my machine) for "1" program/script
(and if exists it will be executed)
If something that looks like
(@ whatever ) it will search for "9" program command and if exist will be executed.
If there somewhere /? string (but not in quotes) in the argument passed to the CALL it will print the CALL help without appeal .
E.G CALL CMD /? will print CALL help .
Also it's with higher priority than calling a label (same with GOTO)