FULLSCREEN CONTENTS Project Home Page
.EXAMPLE.....: 41 Delete files more than X days old (use a batch-file subroutine)
.ALIAS.......: 41
.CATEGORY....: examples 
.CODE........:

See the COMMENTARY that follows the text of the batch file.


@echo off
if (%1)==(SUBROUTINE) goto %2
cls

goto EndDoc
----------------------------------------------------------------------
OLDFILES.BAT
This batch file shows how to do work on files that are older than
%NumDays%.  The PROCESS! subroutine can be modified to do any kind of
work you want.
----------------------------------------------------------------------

:EndDoc

:: set the number of days in the past.   if this value is not passed
:: in via parameter %1, it defaults to 3 days
set NumDays=%1
if (%NumDays%)==() SET NumDays=3


echo ------------------------------------------------------------------
echo           PROCESSING FILES CREATED MORE THAN %NumDays% DAYS AGO
echo ------------------------------------------------------------------
for %%v in (*.*) do  CALL %0 SUBROUTINE PROCESS! %%v
echo ------------------------------------------------------------------
echo           END OF PROCESSING
echo ------------------------------------------------------------------

:: CLEANUP
set NumDays=
set DaysOld=
set Comparison=
GOTO ENDIT



:PROCESS!
shift
shift

:: get difference in days between filedate and today.
:: Note that /B parm (which is omitted) defaults to today's date.
fdate /fdif   /A%1        /IF          /VDaysOld

:: compare DaysOld to NumDays
fdate /f#comp /A%DaysOld% /B%NumDays%  /Vcomparison

:: the following line will DISPLAY THE NAME AND AGE OF
:: any file for which %DaysOld% is greater than %NumDays%
:: --------------------------------------------------------------
if (%comparison%)==(GT) echo %1 is %DaysOld% days old.

:: EXAMPLE (to activate this routine, remove the REM from column 1)
:: the following line will COPY TO AN ARCHIVE SUBDIRECTORY
:: any file for which %DaysOld% is greater than %NumDays%
:: -----------------------------------------------
:: if (%comparison%)==(GT) COPY %1 C:\ARCHIVE\*.*

:: EXAMPLE (to activate this routine, remove the REM from column 1)
:: the following line will DELETE
:: any file for which %DaysOld% is greater than %NumDays%
:: -----------------------------------------------
:: if (%comparison%)==(GT) DEL %1

:: fall through to endit


:endit

 ===============================================================
                        COMMENTARY BEGIN
 ===============================================================
 This batch file uses a crude, but effective, technique for giving a
 batch file the ability to call subroutines.  If you've never seen
 something like this before, it is sort of mind-blowing.  Here's some
 commentary on the more important lines involved in the technique.
 ===============================================================

 if (%1)==(SUBROUTINE) goto %2

    COMMENTARY:
    If the first parameter, %1, is "SUBROUTINE", then the batch file
    recognizes that it is being called for the purpose of executing
    one of its own subroutines.  In such a case, it does a GOTO to the
    start of the requested subroutine.  That is, it goes to the label
    whose name is in the second parameter.

    Explicitly specifying the name of the desired subroutine permits
    permits us to have multiple subroutines in the batch file,
    each with its own name.  (As it happens, in this batch file
    we have only one subroutine, named "PROCESS!")

    If the first parameter is not "SUBROUTINE", then we fall through
    and begin executing the main routine of the batch file.  In such a
    case, the first parameter (%1) may contain a number, indicating
    the number of days to use in determining which files to delete.

    Note that this technique will make the batch file malfunction
    if the user himself ever executes the batch file from the
    DOS command line with the word "SUBROUTINE" as the first
    parameter, the word "PROCESS!" as the second parameter, and a
    third parameter that is missing or not a valid filename.
    This is so unlikely, however, that it is reasonable
    to assume that it will never happen.

 ===============================================================

 for %%v in (*.*) do  CALL %0 SUBROUTINE PROCESS! %%v

    COMMENTARY:
    In a batch file, %0 contains the name by which the batch file was
    invoked.  We use this fact to allow a batch file to call itself,
    regardless of what name the user has given to it.

    The first parameter passed, when the batch file calls
    itself, is the string "SUBROUTINE".  This string allows the batch
    file to recognize when it is being called for the purpose of
    executing one of its own subroutines.

    The second parameter is the name of the subroutine that we want
    to call: in this case, "PROCESS!".

    The third parameter is what we would normally think of as the first
    parameter to the subroutine.  In this case, when the
    FOR statement is executed, and the substitution for %%v takes
    place, it will contain the name of the file to be processed.
    Note that we could, if we wished, pass additional parameters to
    the subroutine.  Note also that we can control the files that
    we process.  We do so via the filemask in the FOR statement.
    It we used, for example, "*.EXE", then we would process only
    executable files.

 ===============================================================

 GOTO ENDIT

   COMMENTARY:
   When the mainline of the batch file is finished executing, we
   goto the end of the batch file.  We MUST do this GOTO in order
   to avoid falling through into, and starting to execute, the first
   of the batch file's subroutines.

 ===============================================================

 :PROCESS!
 shift
 shift

   COMMENTARY:
   Note that when the batch file is called as a subroutine, and the
   batch file goes to the PROCESS! label, the values of the parms are:
           %0 = [the name of the batch file]
           %1 = SUBROUTINE
           %2 = PROCESS!
           %3 = [name of the file to be processed]

    We shift all the parameters to the left twice, to move the
    parameter(s) into what we think of as the
    proper places for parameters to the subroutine.

    After the first SHIFT command:
           %0 = SUBROUTINE
           %1 = PROCESS!
           %2 = [name of the file to be processed]

    After the second SHIFT command:
           %0 = PROCESS!
           %1 = [name of the file to be processed]

    Now %1 contains what we think of as the proper parameter(s)
    to the subroutine.  In this case, %1 contains the filename that
    we want the subroutine to process.

    At the end of every subroutine, there should be a GOTO ENDIT,
    which causes the batch file to go to its own end, and then
    end and return control to the statement in the program which called
    it.  (This is, of course, the CALL statement embedded in the
    FOR statement.)

    We can optimize the batch file a little by omitting the "goto endit"
    at the end of the last subroutine.  Instead, we simply allow the
    last subroutine to fall through to the end of the batch file.

 ===============================================================
                         COMMENTARY END
 ===============================================================