CALL it only IF it is FOR no reason

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
npocmaka_
Posts: 513
Joined: 24 Jun 2013 17:10
Location: Bulgaria
Contact:

CALL it only IF it is FOR no reason

#1 Post by npocmaka_ » 22 Apr 2014 13:23

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.

Liviu
Expert
Posts: 470
Joined: 13 Jan 2012 21:24

Re: CALL it only IF it is FOR no reason

#2 Post by Liviu » 22 Apr 2014 20:27

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

npocmaka_
Posts: 513
Joined: 24 Jun 2013 17:10
Location: Bulgaria
Contact:

Re: CALL it only IF it is FOR no reason

#3 Post by npocmaka_ » 23 Apr 2014 02:19

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...

Squashman
Expert
Posts: 4473
Joined: 23 Dec 2011 13:59

Re: CALL it only IF it is FOR no reason

#4 Post by Squashman » 23 Apr 2014 07:49

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.

jeb
Expert
Posts: 1043
Joined: 30 Aug 2007 08:05
Location: Germany, Bochum

Re: CALL it only IF it is FOR no reason

#5 Post by jeb » 23 Apr 2014 15:39

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

Liviu
Expert
Posts: 470
Joined: 13 Jan 2012 21:24

Re: CALL it only IF it is FOR no reason

#6 Post by Liviu » 23 Apr 2014 23:30

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

npocmaka_
Posts: 513
Joined: 24 Jun 2013 17:10
Location: Bulgaria
Contact:

Re: CALL it only IF it is FOR no reason

#7 Post by npocmaka_ » 24 Jun 2014 05:54

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 (^)

npocmaka_
Posts: 513
Joined: 24 Jun 2013 17:10
Location: Bulgaria
Contact:

Re: CALL it only IF it is FOR no reason

#8 Post by npocmaka_ » 26 Jun 2014 12:30

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)

Post Reply