Single-line DO inside nested multi-line DOs?

May 20, 2008
11,400
99
Syracuse, NY, USA
The BTM below is contrived to be fast and make a point. It's outer 2 nested DO loops make it count from from 1 to 4. If it's inner (nonsense) DO loop is replaced by a single-line DO, the BTM only counts to 2 (terminating when the outermost DO loop should iterate).

Code:
setlocal
set count=0
do q=1 to 2
do r=1 to 2

::do i=1 to 2 ( set a=a )
do i=1 to 2
    set a=a
enddo

set /a count+=1
echo %count

enddo
enddo
quit
 
May 20, 2008
3,515
4
Elkridge, MD, USA
TCC 14.02.40 Windows XP [Version 5.1.2600]

I tested a the variant below, which differs from the inline version of the original by adding more ECHO statements to monitor progress, and using a progress monitoring ECHO in the inline DO instead of the "nonsense statement set a=a".
Code:
   1 : @echo off
   2 : setlocal
   3 : set count=0
   4 : echo line %_batchline
   5 : do q=1 to 2
   6 : echo line %_batchline
   7 :   do r=1 to 2
   8 :     echo line %_batchline
   9 :       do i=1 to 2 ( echo line %_batchline count=%count q=%q r=%r i=%i )
  10 :     set /a count+=1
  11 :     echo line %_batchline count=%count q=%q r=%r
  12 :   enddo
  13 :   echo line %_batchline count=%count q=%q
  14 : enddo
  15 : echo line %_batchline
  16 : quit


This is the redirected output:
line 4
line 6
line 8
line 9 count=0 q=1 r=1 i=1
line 9 count=0 q=1 r=1 i=2
line 11 count=1 q=1 r=1
line 8
line 9 count=1 q=1 r=2 i=1
line 9 count=1 q=1 r=2 i=2
line 11 count=2 q=1 r=2
line 15



I then replaced the inline DO with a normal DO:
Code:
   1 : @echo off
   2 : setlocal
   3 : set count=0
   4 : echo line %_batchline
   5 : do q=1 to 2
   6 : echo line %_batchline
   7 :   do r=1 to 2
   8 :     echo line %_batchline
   9 :       do i=1 to 2 
  10 :         echo line %_batchline count=%count q=%q r=%r i=%i
  11 :       enddo
  12 :     set /a count+=1
  13 :     echo line %_batchline count=%count q=%q r=%r
  14 :   enddo
  15 :   echo line %_batchline count=%count q=%q
  16 : enddo
  17 : echo line %_batchline
  18 : quit


This is the output of the second version:

line 4
line 6
line 8
line 10 count=0 q=1 r=1 i=1
line 10 count=0 q=1 r=1 i=2
line 13 count=1 q=1 r=1
line 8
line 10 count=1 q=1 r=2 i=1
line 10 count=1 q=1 r=2 i=2
line 13 count=2 q=1 r=2
line 15 count=2 q=1
line 6
line 8
line 10 count=2 q=2 r=1 i=1
line 10 count=2 q=2 r=1 i=2
line 13 count=3 q=2 r=1
line 8
line 10 count=3 q=2 r=2 i=1
line 10 count=3 q=2 r=2 i=2
line 13 count=4 q=2 r=2
line 15 count=4 q=2
line 17


Comparison of the two outputs shows that the inline DO somehow interferes with the outermost loop, and causes it to terminate after the first iteration. I also changed all loop upper limits from 2 to 3, and once again the outermost (DO q) loop terminated short. I also determined that ensuring whitespace between the loop control variable name and the equal sign = and between the sign and the start value has no effect.

Rex, I suggest the documentation of the single line DO should have a subtitle, and the grouping parentheses be referred to as "left parenthesis (" etc. for clarity. Not all screens display the boldness of ( distinctively.
 

rconn

Administrator
Staff member
May 14, 2008
12,345
150
The BTM below is contrived to be fast and make a point. It's outer 2 nested DO loops make it count from from 1 to 4. If it's inner (nonsense) DO loop is replaced by a single-line DO, the BTM only counts to 2 (terminating when the outermost DO loop should iterate).

I will change the help to make it clearer that single-line DO's are not supported in batch files, and that they cannot be nested. (I would have banned them entirely in batch files, but I was worried about people defining them in aliases and then referencing the alias in a batch file.)
 

rconn

Administrator
Staff member
May 14, 2008
12,345
150
A brief test showed that the problem isn't with the single-line do nested in non-single-line DO's, but with the (unnecessary) QUIT combined with the single-line DO nested in multiple non-single-line DO's.

Since this isn't a supported use, and it provides no benefit (and several drawbacks), and since the workaround is to use the documented format, I'm inclined to think it's not worth tearing the parser apart (and breaking other things) to try to support it.
 
May 20, 2008
11,400
99
Syracuse, NY, USA
A brief test showed that the problem isn't with the single-line do nested in non-single-line DO's, but with the (unnecessary) QUIT combined with the single-line DO nested in multiple non-single-line DO's.

Since this isn't a supported use, and it provides no benefit (and several drawbacks), and since the workaround is to use the documented format, I'm inclined to think it's not worth tearing the parser apart (and breaking other things) to try to support it.
It may not be worth tearing the parser apart but it does provide the benefit of speed, especially when doing small things many, many times.
Code:
v:\> type docompare.btm
timer
do i=1 to 100000 ( set a=0 )
timer
 
timer
do i=1 to 100000
        set a=0
enddo
timer
 
v:\> docompare.btm
Timer 1 on: 10:53:58
Timer 1 off: 10:54:08  Elapsed: 0:00:09.80
Timer 1 on: 10:54:08
Timer 1 off: 10:54:25  Elapsed: 0:00:16.83
 
May 20, 2008
11,400
99
Syracuse, NY, USA
I will change the help to make it clearer that single-line DO's are not supported in batch files, and that they cannot be nested. (I would have banned them entirely in batch files, but I was worried about people defining them in aliases and then referencing the alias in a batch file.)
In a simple test outside a batch file, nesting seems OK.

Code:
v:\> do i=0 to 1 ( do j=0 to 1 ( do k=0 to 1 ( echo %i %j %k ) ) )
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1
 
May 20, 2008
3,515
4
Elkridge, MD, USA
I don't understand how a QUIT command, which is past the outermost ENDDO Replacing QUIT with EXIT (which may be necessary) in the last line the output was identical.

I tried another version, no QUIT command, no aliases, one more loop, updating COUNT inside single line DO :
Code:
   1 : @echo off
   2 : setlocal
   3 : unalias *
   4 : unset *
   5 : set count=0
   6 : echo line %_batchline count=%count
   7 : do q = 1 to 3
   8 : echo line %_batchline
   9 :   do r = 1 to 3
  10 :     echo line %_batchline
  11 :     do s = 1 to 3
  12 :       echo line %_batchline
  13 :         do i = 1 to 3 ( set /a count+=1 %+ echo line %_batchline count=%count q=%q r=%r s=%s i=%i )
  14 :       echo line %_batchline count=%count q=%q r=%r s=%s
  15 :     enddo
  16 :     echo line %_batchline count=%count q=%q r=%r
  17 :   enddo
  18 :   echo line %_batchline count=%count q=%q
  19 : enddo
  20 : echo line %_batchline count=%count

Surprise!!! the ECHO in line 16 is never reported! But line 20 reported 3 times... Seems that using a single-line DO in a batch file mixes up the parser, it executes a command outside of an enclosing DO instead of inside.

It seems to me that the single line DO confuses the part of the parser which keeps track of loop ends of the already parsed batch file, possibly by searching for ENDDO. As fas as I am concerned, prohibiting "single line DO" in batch files, and reporting them as errors if used is OK.
 

rconn

Administrator
Staff member
May 14, 2008
12,345
150
It may not be worth tearing the parser apart but it does provide the benefit of speed, especially when doing small things many, many times.

Not really; running your test here shows:

Code:
Timer 1 on: 12:23:00
Timer 1 off: 12:23:05  Elapsed: 0:00:04.57
Timer 1 on: 12:23:05
Timer 1 off: 12:23:12  Elapsed: 0:00:06.20

The parser changes necessary would eat up most of that difference (and also make *all* DO's significantly slower). Plus the inability to debug single-line DO's means the time you spend trying to debug anything other than the most trivial DO will probably be several orders of magnitude greater than the time savings in running the batch file for the rest of your life.
 
Similar threads
Thread starter Title Forum Replies Date
Peter Murschall Single-line Do-CMD is a bit uncooperative. Support 6
rfaquino How to? Display filename being copied on a single line Support 2
E Scrolling output to single, non-scrolling line Support 13
M Backquoted parameters used in GoSub don't pass string as a single parameter Support 2
A License Question for Single User Support 5
fpefpe How to? Single installer? Support 5
Emilio III Registering TCMD in VM with single license? Support 2
S How to? Installing TCMD for a single language Support 5
C Single Instance not honored? Support 2
S How to? Install single-language version Support 22
E Single instance/TCMD Here problem Support 7
T VIEW only works from command line Support 14
vefatica `Back quotes` - command line vs. batch file Support 5
Phileosophos Is there any way to open the Take Command options dialog from the command line? Support 8
Phileosophos Command-line Editing Shortkeys That Fail Support 6
D How to use multi-line DO to loop through first level directory names Support 5
D Open Windows 10 Photos app from command line Support 11
Jesse Heines Strange Line Wrapping Behavior Support 14
fpefpe How to? command echo in title line/bar Support 2
vefatica Command line DO with no closing parenthesis? Support 9
R Long commands retrieved from command history have blank line when wrapped Support 20
M No line wraps if last line of the screen buffer is reached Support 5
Joe Caverly No blank line in TEXT...ENDTEXT in a LIBRARY function Support 8
R CMDebug, dark theme, current line Support 7
vefatica IDE - when breakpoint is on a blank line? Support 3
D Double Quote in TC Tool Bar Button Command line Support 3
Joe Caverly Expand all aliases on the command line Support 2
vefatica How do I do this with a multiple-line DO? Support 7
Jay Sage Cannot Postion Cursor in Command Line Using Mouse Support 7
vefatica Windows 10 and line wrapping selection? Support 6
vefatica IDE.EXE's command line? Support 19
x13 TPIPE /REPLACE - Remove line (including EOL) Support 3
D btm file command line augments comparing for string or math. Support 12
D Grabbing html text with @line Support 3
Chen Touboul Overtyping issue - i press the Insert key, help till press enter for new line in TCC Support 2
vefatica FFIND and multi-line regular expressions Support 4
P Escape key no longer clears command line in v24 Support 21
J File explorer handling from command line? Support 2
M Ctrl-C when using command line history does nothing Support 2
M Command line parsing differences between cmd.exe and TCC Support 6
C Replace 1st argument on command line Support 4
vefatica Library functions and line continuations? Support 4
Joe Caverly Works in debugger, not from cmd line Support 1
P No linefeed on last line of console window Support 2
K Command Line Selection Not Working Support 12
J Error running Python at command line Support 9
Joe Caverly PSHELL Blank Line Display Support 2
rps How to? Alias/Command line use of *log on/off Support 2
x13 //directive ignored on TCC command-line Support 4
Joe Caverly Unicode, Codepage 437, and line characters Support 3

Similar threads