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:

Code: Select all

call if a equ a

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_
Liviu wrote: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


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)