Page 1 of 1

Call a label as a variable

Posted: 25 May 2011 13:53
by Cleptography
Pretty sure this can't be done using something like...

Code: Select all

set label=LABEL
call :%label%
goto :eof
:%label%
echo.HERE

...but I do not understand how or what is happening here...

Code: Select all

@echo off&&setlocal
 setlocal enabledelayedexpansion

set label=^^!LABEL^^!
call :%label%
goto :eof
:!LABEL!
echo.HERE

...why the above works but if I change it to...

Code: Select all

@echo off&&setlocal
 setlocal enabledelayedexpansion

set label=^^!ONE^^!
call :%label%
goto :eof
:!ONE!
echo.HERE

...it does not work, is it because I am redefining label as label again...?
I am confused. It would appear in the second example due to the escape chars, all that is happening is that
it is looking for !LABEL! as the label which exist so it calls it, but then why doesn't !ONE! respond the same way? Further more this test baffles me completely...

Code: Select all

@echo off&&setlocal

set label=^^%label^^%
call :%label%
goto :eof
:goto
echo.HERE

...why is label now being declared as goto...
Does it really matter, no probably not, just curiousness.

Re: Call a label as a variable

Posted: 25 May 2011 16:31
by dbenham
Cleptography wrote:...but I do not understand how or what is happening here...

Code: Select all

@echo off&&setlocal
setlocal enabledelayedexpansion

set label=^^!LABEL^^!
call :%label%
goto :eof
:!LABEL!
echo.HERE
...why the above works but if I change it to...

Code: Select all

@echo off&&setlocal
setlocal enabledelayedexpansion

set label=^^!ONE^^!
call :%label%
goto :eof
:!ONE!
echo.HERE
...it does not work, is it because I am redefining label as label again...?

Example 1: %label% expands to !LABEL!, which in turn expands to !LABEL!, so the call is looking for :!LABEL! and works.

Example 2: %label% expands to !ONE!, which is undefined so expands to nothing, and the call fails. This code will work if you define one=!ONE! (with appropriate escaping of course)

Cleptography wrote:Further more this test baffles me completely...

Code: Select all

@echo off&&setlocal

set label=^^%label^^%
call :%label%
goto :eof
:goto
echo.HERE
...why is label now being declared as goto...

The label definition is not processed like you expect. During the definition it is trying to expand the undefined variable named label^, which becomes nothing. So that makes the definition of label = to a single caret (the line continuation character!) So the call becomes call :goto :eof

The following modified code shows what is happening:

Code: Select all

@echo off&&setlocal

set label=^^%label^^%
set label
call :%label%
goto :eof
echo above goto is skipped
:goto
echo.HERE %1

Output:

Code: Select all

label=^
HERE :eof
above goto is skipped
HERE


It's all very simple and logical, yes? :wink:

Dave Benham

Re: Call a label as a variable

Posted: 25 May 2011 16:59
by Cleptography
Ahh thank you very much sir, that makes sense, and is very easy to understand. Now I feel like a dumb ass. :oops:

Re: Call a label as a variable

Posted: 25 May 2011 17:35
by dbenham
Cleptography wrote:Now I feel like a dumb ass.

Far from it. You are posing interesting puzzles.

Dave

Re: Call a label as a variable

Posted: 26 May 2011 15:24
by jeb
Labels/Call/goto are also a bit complex in batch.
Somewhere I post something about it, but I can't find it anymore :(

A label itself will never be expanded or affected by carets.
A label can be prefixed with ANY character but only one of them, and multiple characters of "=,;<space>"
Sample:

Code: Select all

X;=;;=  ;==,,,:legalLabel

The label name ends at the lineend or at the first character "+:<space>&|<>"

But in the call/goto statement there are the normal expansion rules.
Labels ends here with other characters "=+,;:<space>"

call/goto to a label searches the file from the current postion to the end, and then begin from the beginning.
The next executed line is the line directly after the label, important if the end of the label line is a caret (multiline).

After calling a label you can access the name of the label with %0.


Now this should be obvious :wink:

Code: Select all

@echo off
cls
call :#;#
%:#+~%,=*
>=,;=;,,=,;:%%+,=;echo\=%01>&2&call=;:%%%%%%%%;%*
echo *%*


jeb

Re: Call a label as a variable

Posted: 26 May 2011 22:42
by Cleptography
Thank you jeb, your insight is very much respected and appreciated.