Exclamation point not passed with CALL & delayedexpansion

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
Phylum
Posts: 4
Joined: 07 Nov 2011 06:29

Exclamation point not passed with CALL & delayedexpansion

#1 Post by Phylum » 16 Oct 2014 10:38

I need some help understanding why the exclamation point is not passed on to a 'subroutine' when delayedexpansion is enabled.
When delayedexpansion is not enabled, it works as expected: exclamation point is passed onto the subroutine.

I'm sure I'm missing something simple, but what?
Example code is below with several permutations in an attempt to be thorough.

Code: Select all

@echo off

for /L %%i in (1,1,10) do (
   rem works as expected: exclamation point is present
   call :echo1 "Found1 %%i Cookie!"

   rem exclamation point is present here too
   rem but the below is totally unnecessary
   rem
   rem also, extra carets are added
   rem don't yet understand why though
   rem call :echo1 "Found2 %%i Cookie!!"
   rem call :echo1 "Found3 %%i Cookie^!"
   rem call :echo1 "Found4 %%i Cookie^^!"
   rem call :echo1 "Found5 %%i Cookie^^^!"
   rem call :echo1 "Found6 %%i Cookie^^^^!"
   rem call :echo1 "Found7 %%i Cookie^!!"
   rem call :echo1 "Found8 %%i Cookie^^!!"
   rem call :echo1 "Found9 %%i Cookie^^^!!"
   rem call :echo1 "FoundA %%i Cookie^^^^!!"
   rem call :echo1 "FoundB %%i Cookie^!^!"
   rem call :echo1 "FoundC %%i Cookie^^!^^!"
   rem call :echo1 "FoundD %%i Cookie^^^!^^^!"
   rem call :echo1 "FoundE %%i Cookie^^^^!^^^^!"
   echo.
)


pause


setlocal enabledelayedexpansion



for /L %%i in (1,1,10) do (
   rem these don't work and that's understandable
   rem http://www.dostips.com/%3Ft=Snippets.Escape
   rem replace %3F with a question mark
   call :echo2 "DELAYED Found1 %%i Cookie!"
   call :echo2 "DELAYED Found2 %%i Cookie!!"
   call :echo2 "DELAYED Found3 %%i Cookie^!"

   rem this should work but it doesn't
   call :echo2 "DELAYED Found4 %%i Cookie^^!"

   rem testing other possible combinations
   rem none of which work
   call :echo2 "DELAYED Found5 %%i Cookie^^^!"
   call :echo2 "DELAYED Found6 %%i Cookie^^^^!"
   call :echo2 "DELAYED Found7 %%i Cookie^!!"
   call :echo2 "DELAYED Found8 %%i Cookie^^!!"
   call :echo2 "DELAYED Found9 %%i Cookie^^^!!"
   call :echo2 "DELAYED FoundA %%i Cookie^^^^!!"
   call :echo2 "DELAYED FoundB %%i Cookie^!^!"
   call :echo2 "DELAYED FoundC %%i Cookie^^!^^!"
   call :echo2 "DELAYED FoundD %%i Cookie^^^!^^^!"
   call :echo2 "DELAYED FoundE %%i Cookie^^^^!^^^^!"
   echo.
)

endlocal


pause


goto end

:echo1
echo echo1 is %1
set _Buffer=
set _Buffer=%1
set _Buffer=%_Buffer:"=%
echo %_Buffer%
set _Buffer=
goto:eof


:echo2
echo echo2 is %1
set _Buffer=
set _Buffer=%1
set _Buffer=!_Buffer:"=!
echo !_Buffer!
set _Buffer=
goto:eof


:end

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

Re: Exclamation point not passed with CALL & delayedexpansio

#2 Post by Squashman » 16 Oct 2014 11:44

Do you know that you don't need this code to remove the Quotes.

Code: Select all

set _Buffer=%_Buffer:"=%

Just do this.

Code: Select all

set _Buffer=%~1


You may want to look at passing a variable name as a reference to your subroutine and then expand the variable in the subroutine.

Phylum
Posts: 4
Joined: 07 Nov 2011 06:29

Re: Exclamation point not passed with CALL & delayedexpansio

#3 Post by Phylum » 16 Oct 2014 14:11

Squashman wrote:Do you know that you don't need this code to remove the Quotes.

Code: Select all

set _Buffer=%_Buffer:"=%

Just do this.

Code: Select all

set _Buffer=%~1


Oh, excellent tip. Thank you for that!


Squashman wrote:You may want to look at passing a variable name as a reference to your subroutine and then expand the variable in the subroutine.

I'm not sure I follow.
Do you mean something like this?

Code: Select all

...
for /L %%i in (1,1,10) do (
   rem those that are rem'd out don't work
   rem or don't produce desired result

   rem set _ToBeEchod=DELAYED Found1 %%i Cookie!
   rem call :echo3 _ToBeEchod

   rem set _ToBeEchod=DELAYED Found2 %%i Cookie!!
   rem call :echo3 _ToBeEchod

   rem set _ToBeEchod=DELAYED Found3 %%i Cookie^!
   rem call :echo3 _ToBeEchod

   set _ToBeEchod=DELAYED Found4 %%i Cookie^^!
   call :echo3 _ToBeEchod

   rem set _ToBeEchod=DELAYED Found5 %%i Cookie^^^!
   rem call :echo3 _ToBeEchod

   rem set _ToBeEchod=DELAYED Found6 %%i Cookie^^^^!
   rem call :echo3 _ToBeEchod

   rem set _ToBeEchod=DELAYED Found7 %%i Cookie^!!
   rem call :echo3 _ToBeEchod

   rem set _ToBeEchod=DELAYED Found8 %%i Cookie^^!!
   rem call :echo3 _ToBeEchod

   rem set _ToBeEchod=DELAYED Found9 %%i Cookie^^^!!
   rem call :echo3 _ToBeEchod

   rem set _ToBeEchod=DELAYED FoundA %%i Cookie^^^^!!
   rem call :echo3 _ToBeEchod

   rem set _ToBeEchod=DELAYED FoundB %%i Cookie^!^!
   rem call :echo3 _ToBeEchod

   set _ToBeEchod=DELAYED FoundC %%i Cookie^^!^^!
   call :echo3 _ToBeEchod

   rem set _ToBeEchod=DELAYED FoundD %%i Cookie^^^!^^^!
   rem call :echo3 _ToBeEchod

   rem set _ToBeEchod=DELAYED FoundE %%i Cookie^^^^!^^^^!
   rem call :echo3 _ToBeEchod
   echo.
)

:echo3
echo echo3 is !%1!
echo !%1!
@echo !%1! >>%temp%\trash.log
goto:eof

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

Re: Exclamation point not passed with CALL & delayedexpansio

#4 Post by Squashman » 16 Oct 2014 14:35

Notice how the QUOTES in the 2nd SET command makes a difference.

Code: Select all

@echo off
for /L %%i in (1,1,10) do (
    set _ToBeEchod=DELAYED Found %%i Cookie^^!
   call :echo3 _ToBeEchod

   set "_ToBeEchod=DELAYED Found %%i Cookie^^!"
   call :echo3 _ToBeEchod
)
pause

:echo3
setlocal enabledelayedexpansion
echo echo3 is !%1!
endlocal
goto:eof

output

Code: Select all

echo3 is DELAYED Found 1 Cookie^!
echo3 is DELAYED Found 1 Cookie^^!
echo3 is DELAYED Found 2 Cookie^!
echo3 is DELAYED Found 2 Cookie^^!
echo3 is DELAYED Found 3 Cookie^!
echo3 is DELAYED Found 3 Cookie^^!
echo3 is DELAYED Found 4 Cookie^!
echo3 is DELAYED Found 4 Cookie^^!
echo3 is DELAYED Found 5 Cookie^!
echo3 is DELAYED Found 5 Cookie^^!
echo3 is DELAYED Found 6 Cookie^!
echo3 is DELAYED Found 6 Cookie^^!
echo3 is DELAYED Found 7 Cookie^!
echo3 is DELAYED Found 7 Cookie^^!
echo3 is DELAYED Found 8 Cookie^!
echo3 is DELAYED Found 8 Cookie^^!
echo3 is DELAYED Found 9 Cookie^!
echo3 is DELAYED Found 9 Cookie^^!
echo3 is DELAYED Found 10 Cookie^!
echo3 is DELAYED Found 10 Cookie^^!

Yury
Posts: 115
Joined: 28 Dec 2013 07:54

Re: Exclamation point not passed with CALL & delayedexpansio

#5 Post by Yury » 16 Oct 2014 14:53

Phylum, take a look here. It will be interesting for you:



Code: Select all

@echo off

setlocal enabledelayedexpansion

call :echo3 "Found1 Cookie!"
call :echo3 "Found2 Cookie!!"
call :echo3 "Found3 Cookie^!"
call :echo3 "Found4 Cookie^^!"
call :echo3 "Found5 Cookie^^^!"
call :echo3 "Found6 Cookie^^^^!"
call :echo3 "Found7 Cookie^!!"
call :echo3 "Found8 Cookie^^!!"
call :echo3 "Found9 Cookie^^^!!"
call :echo3 "FoundA Cookie^^^^!!"
call :echo3 "FoundB Cookie^!^!"
call :echo3 "FoundC Cookie^^!^^!"
call :echo3 "FoundD Cookie^^^!^^^!"
call :echo3 "FoundE Cookie^^^^!^^^^!"

endlocal

pause>nul
exit /b


:echo3

   setlocal disabledelayedexpansion

   echo %1
   call echo %1
   echo %~1
   call echo %~1
   echo.
   cmd /v:on /c echo %1
   cmd /v:on /c call echo %1
   cmd /v:on /c echo %~1
   cmd /v:on /c call echo %~1
   echo.
   set _Buffer=%1
   echo %_Buffer%
   call echo %_Buffer%
   cmd /v:on /c echo !_Buffer!
   cmd /v:on /c "set _Buffer=%1& echo !_Buffer!"
   cmd /v:on /c "set _Buffer=%1& call echo %%_Buffer%%"
   echo.
   set _Buffer=%~1
   echo %_Buffer%
   call echo %_Buffer%
   cmd /v:on /c echo !_Buffer!
   cmd /v:on /c "set _Buffer=%~1& echo !_Buffer!"
   cmd /v:on /c "set _Buffer=%~1& call echo %%_Buffer%%"
   echo.
   echo.

   endlocal

   exit /b




.

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

Re: Exclamation point not passed with CALL & delayedexpansio

#6 Post by jeb » 20 Oct 2014 01:26

Thanks to Yury and Squashman for showing these examples.

But without any explanation it's unclear why it happens this way.
And what are the rules behind the behaviour?

Post Reply