
                                  BATLOOP.COM
             A Program to Implement Batch file Looping Capability
                                  version 1.0
                                 Rod L. Renner
                                 July 10, 1989

Program History:
     07/10/89 - Initial release of v1.0


Those of you who write Batch files in DOS are aware that there is no easy way 
to provide program loop control within a BAT file.  In programming languages, 
such as BASIC, it is easy to set up a loop to repeat a set of statements, say 
15 times, with the ability to jump out of the loop should some condition 
occur.  The statements might look like this: 

             5  I=15
            10    <statement 1>
                   ...
            20    IF <condition> THEN 50
                   ...
            30  I=I-1
            35  IF I>=1 GOTO 10
            40  PRINT "LOOP Terminated Normally"
            45  GOTO 60
            50  PRINT "Condition occurred while in LOOP"
            60  END

The equivalent loop in a Batch file usually involves long repetition.  Other 
loops are possible, but usually require clever programming and involve 
combinations of DOS commands such as IF ERRORLEVEL, FOR-DO, SHIFT, CALL or 
GOTO.  In particular, the key feature missing in DOS is the easy ability to 
initialize a loop variable and to change it during each pass through the loop.  

The program BATLOOP provides this missing key.  Thus, the above loop in DOS 
might look like this: 

             BATLOOP 15
             :LOOP
             <statement 1>
              ...
             IF <condition> GOTO OUT
             BATLOOP
             IF ERRORLEVEL 1 GOTO LOOP
             ECHO  LOOP Terminated Normally
             GOTO EXIT
             :OUT
             ECHO  Condition occurred while in LOOP
             :EXIT 

The program BATLOOP simulates the missing loop features for DOS.  When called 
with a numeric parameter between 1 and 255, BATLOOP creates a loop variable 
(actually creates a 0-byte file called BATLOOP$ in the default directory) and 
sets it to this numeric value (uses the file's time field for storage).  When 
called with no arguments, it decrements the current value of the loop variable 
by 1.  When the value reaches 0, the loop variable BATLOOP$ is deleted.  In 
all cases, BATLOOP sets the return code to the value of the loop variable (0 
to 255) each time it's executed.  This return code can be tested immediately 
after execution using the DOS IF ERRORLEVEL command to determine when the 
return code is 0 and the loop is completed (ie., the loop is terminated when 
the DOS test IF ERRORLEVEL 1 is False).  

A practical example for this looping capability is in running a multi-node BBS 
under a LAN, such as PCBoard with LANtastic, to prevent an infinite loop when 
the workstation is unable to connect to the file server.  If we assume that 
critical files, such as the USERS file are located on the work station, that 
file directories are located on the LAN, but substitutions can be made by 
local mapping if the file server is not available, then the following segment 
shows use of BATLOOP: 

  ...
  BATLOOP 15                       <=try up to 15 times
  :LOOP                            <=start of body of the loop
  NET LOGOUT \\SERVER              <=do this in case already on
  NET LOGIN \\SERVER id pwd        <=attempt to logon the server
  IF NOT ERRORLEVEL 1 GOTO LOGD    <=goto LOGD if successful logon
  BATLOOP                          <=decrement the loop counter
  IF ERRORLEVEL 1 GOTO LOOP        <=loop back if not done 15 times
  SUBST G: C:\PCB\ALTDIR           <=failure to logon; substitute local for G:
  GOTO CONTINUE                    <=continue with BAT file
  :LOGD                            <=come here if logon is successful
  NET USE G: \\SERVER\C:\PCB\DIR   <=attach server directory as G:
  DEL BATLOOP$                     <=get rid of loop variable (optional)
  :CONTINUE                        <=G: is now defined (local or network)

As mentioned above, BATLOOP.COM simulates the loop variable by creating a 0-
byte length file in the default directory called BATLOOP$ and uses its time 
field to keep track of the current value of the loop variable.  If you use 
BATLOOP, then the following must be kept in mind: 

  o  There must be room in the default directory for BATLOOP$; otherwise, 
     BATLOOP returns an ERRORLEVEL value of 0.  Note that the file uses no 
     sectors for storage, only a directory entry, so the default drive can be 
     filled and still work as long as there is space in the directory.  

  o  The default directory in effect when the initializing "BATLOOP n" is 
     called should be the same one when subsequent BATLOOP calls are made in 
     order to work as expected.  Note that by changing default directories, a 
     clever user can create nested loops.  

  o  Whenever BATLOOP detects a loop value of 0 (at initialization, or before 
     or after decrementing), it will attempt to delete BATLOOP$.  The 
     existence of BATLOOP$ can also be a test for termination of the loop, but 
     using the IF ERRORLEVEL test is the surest means, as BATLOOP sets this to 
     zero whenever it encounters an error.  

   o Jumping out of a BATLOOP loop before termination will result in BATLOOP$ 
     remaining in the directory.  This is not considered a problem, as the 
     user can either reset the loop value by using "BATLOOP n", resume 
     countdown with the current loop value using "BATLOOP" with no arguments, 
     or delete BATLOOP$ with a "DEL BATLOOP$" command.  

   o Entering "BATLOOP 0" will cause BATLOOP to delete BATLOOP$ and return an 
     ERRORLEVEL code of 0.  Entering "BATLOOP n" where n is greater than 255 
     will cause unpredictable results.  Entering "BATLOOP" with no arguments 
     and no previous initialization (ie., no existing BATLOOP$) will cause 
     BATLOOP to return an ERRORLEVEL code of 0.  Typing "BATLOOP x" where x 
     does not start with a number is equivalent to typing "BATLOOP" without an 
     argument.  

The usual construct for a simple repetitive loop is the following: 

       ...                              <=previous statements, if any
     BATLOOP n                          <=initialize BATLOOP$ to loop n times
     IF NOT ERRORLEVEL 1 GOTO DONE      <=skip loop if n=0 (optional)
     :LOOPTOP                           <=start of body of the loop
       ...                              <=statements to be repeated n times
     BATLOOP                            <=decrement the BATLOOP$ loop counter
     IF ERRORLEVEL 1 GOTO LOOPTOP       <=loop back if loop counter >=1
     :DONE                              <=end of loop

I hereby place BATLOOP.COM in the public domain.  It comes AS IS with no 
warranties or guarantees of any kind.  Use it completely at your own risk and 
expense.  There is no source code as BATLOOP.COM was written in DEBUG 
assembler.


                                Rod L. Renner
                                SYSOP, SALEMDUG BBS
                                Washington, DC
                                202-646-3528
