Delayed expansion fails in some cases

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Message
Author
penpen
Expert
Posts: 1651
Joined: 23 Jun 2013 06:15
Location: Germany

Re: Delayed expansion fails in some cases

#16 Post by penpen » 21 Mar 2017 12:55

dbenham wrote:I am not seeing the point of your subsequent post
jeb wrote:Your results are the expected ones, as delayed expansion is done only once, in the phases of the CALL there isn't any delayed expansion at all.
My posts late in the night are ... suboptimal.... sorry for confusing you:
I'm getting more lazy writing explainations the later it is... especially when i'm unsure.

The point of my last post was to describe a bug (in short) (this is no proof that such a bug exist - it only should show that it may be possible; some kind of "brainstorming reasons"):
If delayed expansion could be switched off (and on again), then it might be, that a programmer has triggered/switched on or off delayed expansion in certain situations (example: calling batch/executing "|" (triggers), and "(...)" (switch on)) instead of simply switching it off (as an explaination of the "perverse beauty in the inverse symmetry").
(The same could be reached with applying an "delayed escaping" one time too many - in case of the first two examples.)

The code with "call call" just should prove that the interpreter may have such a control - i didn't think of referring to the parser rules.


penpen

dbenham
Expert
Posts: 2199
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: Delayed expansion fails in some cases

#17 Post by dbenham » 12 Feb 2019 23:36

jeb wrote:
19 Mar 2017 15:52
penpen wrote:I think i've read before that delayed Expansion "differs" between command and parameter string (although the consequences were different), but i cannot remember where;
if i had to guess, i would say it was a post/code from jeb/dbenham/both - something like this:
Yes, I described somewhere that the delayed expansion is completly independent for the command token and the remaining parameter tokens.

But your comment inspired me to test another case

Code: Select all

@echo off
setlocal EnableDelayedExpansion
set "var=content"
receiver.bat 1--!var!--

versus
set cmd=receiver.bat
!cmd! 2--!var!--
output wrote: REM # 1--!var!-- #
versus
REM # 2--content-- #
Strange :) :?:
jeb
Eureeka :idea: :!:

I just realized that much of this behavior is easier to rationalize if phase 2 has special code to look to see if the command is another batch file. So I did the following two tests.

First I have two identical files, one named xfer.bat, and the other !myFile!.bat

Code: Select all

@echo off
setlocal disableDelayedExpansion
echo %~f0 %*
Now I run the following test1.bat

Code: Select all

@echo off
setlocal enableDelayedExpansion
set "file=xfer"
set "a=myValue"
!file!.bat !a!
-- OUTPUT --

Code: Select all

C:\test\test\xfer.bat myValue
This is basically what jeb reported.

But now I run test2.bat

Code: Select all

@echo off
setlocal enableDelayedExpansion
set "myFile=xfer"
set "a=myValue"
!myFile!.bat !a!
-- OUTPUT --

Code: Select all

C:\test\test\!myFile!.bat !a!
Bingo :!:

Looking back at all the other cases where delayed expansion succeeds, they all have complexities that could prevent phase 2 from recognizing the command as a batch script.

Now the only thing I'm not sure about is whether control is transferred directly from phase 2 to the new batch script? or are subsequent phases executed, but with phase 6 disabled? I tried to probe with delayed expansion, and am leaning towards subsequent phases still executing. But I'm not sure.


Dave Benham

dbenham
Expert
Posts: 2199
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: Delayed expansion fails in some cases

#18 Post by dbenham » 13 Feb 2019 06:51

My previous post postulates that phase 2 checks to see if the first token is a batch script, and then the parser follows some alternate path if it is.

At first I thought "Why the hell would phase 2 do that :?: :? "

But then... of course :) Phase 2 is restarted if there is a CALL, and CALL needs to know whether the first token is a batch script or not :!: So why not let phase 2 do that work.

It feels like I am on to something, but there is still a problem :x

If phase 2 always checks if the first token is a batch script, then there should be a major performance hit every time an internal command is executed, the same as when we try to CALL an internal command. If phase 2 improved the performance by skipping the disk search if the token were an internal command, then CALL ECHO would still execute the internal command, even if ECHO.BAT exists.

Well clearly ECHO is much faster than CALL ECHO, and if ECHO.BAT does exist, then ECHO still executes the internal command, but CALL ECHO executes the script. So I am still stumped :?


Dave Benham

Post Reply