LEAVE appears to affect command-line arguments

May 23, 2010
60
1
Seattle
LEAVE inside an argument-acquisition loop seems to make a subsequent test for empty argument fail, as well as cause a spurious error message:
Code:
[C:\batch]type foo.btm
@ echo off
  do until (%1) == ()
    iff (%1) == (trap) then
      shift
      leave
    endiff
    shift
  enddo

:PASTEND
  iff (%1) ne () then
    echo (%1):  too many parms!
  endiff

[C:\batch]foo a b c trap x
(x):  too many parms!

[C:\batch]foo a b c trap
():  too many parms!
TCC: C:\batch\foo.btm [13]  Unknown command "endiff"
If I replace the LEAVE with a GOTO PASTEND, both these cases seem to work as intended. Am I using the LEAVE incorrectly?
 
May 20, 2008
11,810
118
Syracuse, NY, USA
Two observations.

1. It doesn't seem to have anything to do with the IFF/ENDIFF inside the DO loop
2. After the DO loop a simple IF gets it right (and a subsequent IFF gets it wrong (plus error message)).

Code:
v:\> type foo.btm
do until (%1) == ()
    if (%1) == (trap) (shift & leave) else (shift)
enddo

if (%1) ne () echo (%1):  too many parms! (1)

iff (%1) ne () then
    echo (%1):  too many parms! (2)
endiff

v:\> foo.btm a b trap
():  too many parms! (2)
TCC: V:\foo.btm [9]  Unknown command "endiff"
 
May 20, 2008
11,810
118
Syracuse, NY, USA
The batch args seem OK. It's as though the IFF is skipped (but ECHO ON says it's being read).

Code:
v:\> type foo.btm
do until (%1) == ()
    if (%1) == (trap) (shift & leave) else (shift)
enddo

if foo eq bar echo This message shouldn't be seen! (1)

iff foo eq bar then
    echo This message shouldn't be seen! (2)
endiff


v:\> foo.btm a b c d e f g h trap
This message shouldn't be seen! (2)
TCC: V:\foo.btm [9]  Unknown command "endiff"
 
May 20, 2008
11,810
118
Syracuse, NY, USA
A wild speculation. Using LEAVE in a DO UNTIL loop leaves a "dangling" contitional (that was supposed to be evaluated after the loop). That dangling conditional is the one evaluated by the subsequent IFF. Compare these two.

Code:
v:\> type foo.btm
do until foo ne foo
    leave
enddo

iff foo eq bar then
    echo This message shouldn't be seen! (2)
endiff


v:\> foo.btm

v:\>

Code:
v:\> type foo.btm
do until foo eq foo
    leave
enddo

iff foo eq bar then
    echo This message shouldn't be seen! (2)
endiff


v:\> foo.btm
This message shouldn't be seen! (2)
TCC: V:\foo.btm [7]  Unknown command "endiff"

v:\>
 

rconn

Administrator
Staff member
May 14, 2008
12,425
153
Both DO and IFF set flags that are evaluated on the following lines (looking for ELSE, ELSEIFF, ENDIFF, ENDDO, LEAVE, or ITERATE).

The problem here is that the parser has never supported doing a LEAVE from an IFF inside a DO. This is decidedly non-trivial (particularly since both DO and IFF can be nested multiple levels) but I've added experimental support for it in the next build (28.02.17).
 
May 20, 2008
11,810
118
Syracuse, NY, USA
This wasn't working (failed as above) and it's working now in build 28. [I thought I had mentioned it but I couldn't find it.]

Code:
do until %_datetime LT 20220101010101
        leave
enddo
iff foo == bar then
        echo foo == foo
endiff