At some point I'd like to get a single comprehensive post that describes all the ins and outs of :label parsing and CALL and GOTO behavior.
I see a couple things that don't look correct in jeb's first post:
jeb wrote:
Now the label names.
They also use STOP characters, but not the same, I only know two :!:
When scanning the file for the label name, I see that there are 5 (maybe 6) stop characters for the label name instead of two: <+>, <:>, <space>, <tab>, <LF>, and possibly <CR>. The other token delimiters are not stop characters
jeb wrote:
So these labels are equivalent
That last :one^ looks incorrect to me - I can never manage to CALL or GOTO that label. I suppose that may be what you were driving at in
This post
I also cannot find a way to call any of the following labels:
Code: Select all
:one^<space>
:one^<tab>
:one;
:one,
:one=
:one^+
:one^:
It appears to me that the label scanner does escape label stop characters, such that they are included in the label name. But the GOTO and CALL label parsers do not escape any of the stop characters, even though the escaped characters are included within the token. I think that would explain why the above labels are inaccessible.
One thing that appears to be missing from this discussion is details as to how the batch parser recognizes labels so that they are never executed. I've attempted to partially describe that in a
modified Phase 2 in jeb's SO post. The label detection happens late in phase 2, so there can be some surprising lines that are interpreted as un-executable labels.
One consequence of those rules is redirection can exist prior to the label, and the label will still prevent the line from ever being executed. The redirection will also prevent the label from ever being CALLed (or GOTOed - sorry about the grammer). Note that the redirection never actually takes place.
Code: Select all
@echo off
>test.txt :label this inaccessible label can never be executed or CALLed
This behavior has been used before. It is critical to the
WSF hybrid scripting technique
More trivial is the fact that any number of expansion terms can exist prior to the label and still make it unexecutable and inaccessible as long as they expand to nothing or token delimiters.
Code: Select all
@echo off
set local enableDelayedExpansion
%= undefined =% :Cannot be executed or accessed
!= undefined =% :Cannot be executed or accessed
Something that I have never seen demonstrated before, the unexecutable and inaccessible label can appear on the same line as a valid command, after command concatenation. This also is explained by my modifed Phase 2 rules.
Code: Select all
@echo off
echo This is printed & :The remainder of the line is ignored & echo So this command is never executed
One thing that is not explained by my modifed Phase 2 rules: Introduction of redirection prior to the label enables subsequent command concatenation after the inline label. Also, the redirection now takes place.
Code: Select all
@echo off
>test.txt :This is ignored except redirection takes place - the file is overwritten and made empty & echo This is printed
echo Part 1 is printed & >test2.txt :This is ignored but redirection takes place & echo Part 2 is printed
This all can have some interesting effects on labels / comments within parenthesized blocks. But I am too tired to write these out (I may have the flu - not a good New Year's Eve).
But I do have one quick point to make about comment labels within blocks.
You can use :; instead of :: as a comment. The inaccessible label is legal / never treated as a path. So you can safely use symmetric :; label comments as long as they are paired
Code: Select all
(
:;This is a safe comment
:;And so is this because they are paired
)
Dave Benham