Document revision date: 30 March 2001

## OpenVMS User's Manual

Previous | Contents | Index

## C.9 LISTER.COM Command Procedure

Prompts for input data, formats the data in columns, and sorts it into an output file. This procedure illustrates the READ and WRITE commands, as well as the character substring overlay format of an assignment statement.

Example: LISTER.COM

    $ ! Procedure to accumulate programmer names and document file names.
    $ ! After all programmer names and file names are entered, they are
    $ ! sorted in alphabetic order by programmer name and printed on
    $ ! the system printer.
    $ !
    $ SAVE_VERIFY_IMAGE = F$ENVIRONMENT("VERIFY_IMAGE")        (1)
    $ SAVE_VERIFY_PROCEDURE = F$VERIFY(0)
    $ !
    $ OPEN/WRITE OUTFILE DATA.TMP         ! Create output file (2)
    $ !
    $ ! Loop to obtain programmers' last names and file names,
    $ ! and write this data to DATA.TMP.
    $ !
    $ LOOP:                                                    (3)
    $        INQUIRE NAME "Programmer (press Return to quit)"
    $        IF NAME .EQS. "" THEN GOTO FINISHED
    $        INQUIRE FILE "Document file name"
    $        RECORD[0,20]:='NAME'                              (4)
    $        RECORD[21,20]:='FILE'
    $        WRITE OUTFILE RECORD
    $        GOTO LOOP
    $ FINISHED:
    $        CLOSE OUTFILE
    $ !
    $ DEFINE/USER_MODE SYS$OUTPUT: NL:   ! Suppress sort output
    $ SORT/KEY=(POSITION:1,SIZE=20) DATA.TMP DOC.SRT           (5)
    $ !
    $ OPEN/WRITE OUTFILE DOCUMENT.DAT                          (6)
    $ WRITE OUTFILE "Programmer Files as of ",F$TIME()
    $ WRITE OUTFILE ""
    $ RECORD[0,20]:="Programmer Name"
    $ RECORD[21,20]:="File Name"
    $ WRITE OUTFILE RECORD
    $ WRITE OUTFILE ""
    $ !
    $ CLOSE OUTFILE                                            (7)
    $ APPEND DOC.SRT DOCUMENT.DAT
    $ PRINT DOCUMENT.DAT
    $ !
    $ INQUIRE CLEAN_UP "Delete temporary files [Y,N]"          (8)
    $ IF CLEAN_UP THEN DELETE DATA.TMP;*,DOC.SRT;*
    $ SAVE_VERIFY_PROCEDURE = F$VERIFY(SAVE_VERIFY_PROCEDURE,SAVE_VERIFY_IMAGE)
    $ EXIT

Notes for LISTER.COM Command Procedure

1. LISTER.COM saves the current verification setting and turns off verification.
2. The OPEN command creates a temporary file for writing.
3. INQUIRE commands prompt for a programmer name and for a file name. If a null line, signaled by pressing Return, is entered in response to the INQUIRE command prompt, the procedure assumes that no more data is to be entered and branches to the label FINISHED.
4. After assigning values to the symbols NAME and FILE, the procedure uses the character string overlay format of an assignment statement to construct a value for the symbol RECORD. In columns 1 to 21 of RECORD, the current value of NAME is written. The command interpreter pads the value of NAME with spaces to fill the 20-character length specified.
   Similarly, the next 20 columns of RECORD are filled with the value of FILE. Then, the value of RECORD is written to the output file.
5. After the file has been closed, the procedure sorts the output file DATA.TMP. The DEFINE command directs the SORT command output to the null file NL. Otherwise, these statistics would be displayed on the terminal:
   The sort is performed on the first 20 columns; that is, by programmer name.
   The sorted output file has the name DOC.SRT.
6. The procedure creates the final output file, DOCUMENT.DAT, with the OPEN command. The first lines written to the file are header lines, giving a title, the date and time of day, and headings for the columns.
7. The procedure closes the file DOCUMENT.DAT and appends the sorted output file, DOC.SRT, to it. Then, the output file is queued to the system printer.
8. The procedure prompts to determine whether to delete the intermediate files. If a true response (T, t, Y, or y) is entered at the INQUIRE command prompt, the files DATA.TMP and DOC.SRT are deleted. Otherwise, they are retained.

Sample Execution for LISTER.COM Command Procedure

    $ @LISTER
    Programmer: WATERS
    Document file name: CRYSTAL.CAV
    Programmer: JENKINS
    Document file name: MARIGOLD.DAT
    Programmer: MASON
    Document file name: SYSTEM.SRC
    Programmer: ANDERSON
    Document file name: JUNK.J
    Programmer: [Return]
    Delete temporary files [Y,N]:y

The output file resulting from this execution of the procedure contains the following:

    Programmer Files as of 31-DEC-1999 16:18:58.79

    Programmer Name      File Name

    ANDERSON             JUNK.J
    JENKINS              MARIGOLD.DAT
    MASON                SYSTEM.SRC
    WATERS               CRYSTAL.CAV

## C.10 CALC.COM Command Procedure

Performs arithmetic calculations and converts the resulting value to hexadecimal and decimal values.

Example: CALC.COM

    $ ! Procedure to calculate expressions.  If you enter an
    $ ! assignment statement, then CALC.COM evaluates the expression
    $ ! and assigns the result to the symbol you specify.  In the next
    $ ! iteration, you can use either your symbol or the symbol Q to
    $ ! represent the current result.
    $ !
    $ ! If you enter an expression, then CALC.COM evaluates the
    $ ! expression and assigns the result to the symbol Q.  In
    $ ! the next iteration, you can use the symbol Q to represent
    $ ! the current result.
    $ !
    $ SAVE_VERIFY_IMAGE = F$ENVIRONMENT("VERIFY_IMAGE")
    $ SAVE_VERIFY_PROCEDURE = F$VERIFY(0)
    $ START:
    $     ON WARNING THEN GOTO START                           (1)
    $     INQUIRE STRING "Calc"                                (2)
    $     IF STRING .EQS. "" THEN GOTO CLEAN_UP
    $     IF F$LOCATE("=",STRING) .EQ. F$LENGTH(STRING) THEN GOTO EXPRESSION
    $ !
    $ ! Execute if string is in the form symbol = expression
    $ STATEMENT:                                               (3)
    $     'STRING' ! Execute assignment statements
    $     SYMBOL = F$EXTRACT(0,F$LOCATE("=",STRING)-1,STRING) ! get symbol name
    $     Q = 'SYMBOL'        ! Set up q for future iterations
    $     LINE = F$FAO("Decimal = !SL       Hex = !-!XL      Octal = !-!OL",Q)
    $     WRITE SYS$OUTPUT LINE
    $     GOTO START
    $ !
    $ !
    $ ! Execute if string is an expression
    $ EXPRESSION:                                              (4)
    $     Q = F$INTEGER('STRING')         ! Can use Q in next iteration
    $     LINE = F$FAO("Decimal = !SL       Hex = !-!XL      Octal = !-!OL",Q)
    $     WRITE SYS$OUTPUT LINE
    $     GOTO START
    $ !
    $ CLEAN_UP:
    $ SAVE_VERIFY_PROCEDURE = F$VERIFY(SAVE_VERIFY_PROCEDURE,SAVE_VERIFY_IMAGE)
    $ EXIT

Notes for CALC.COM Command Procedure

1. The procedure establishes an error-handling condition that restarts the procedure. If a warning or an error of greater severity occurs, the procedure will branch to the beginning where it resets the ON condition.
   This technique ensures that the procedure will not exit if the user enters an expression incorrectly.
2. The INQUIRE command prompts for an arithmetic expression. The procedure accepts expressions in either of the following formats:

   `name = expression`

   `expression`

   If you press Return, the procedure assumes the end of a CALC session and exits.
   If you enter input in the format "name = expression" then the procedure continues executing at the label STATEMENT. Otherwise, the procedure branches to the label EXPRESSION.

3. The procedure executes the assignment statement and assigns the result of the expression to the symbol. Then the procedure extracts the symbol name, and assigns the value of the symbol to Q. This allows you to use either Q or your symbol during the next iteration of the procedure. Next, the procedure displays the result and then branches back to the label START.
4. The procedure evaluates the expression and assigns the result to the symbol Q. This allows you to use Q during the next iteration of the procedure. Next, the procedure displays the result and then branches back to the label START.

Sample Execution for CALC.COM Command Procedure

    $ @CALC
    Calc: 2 * 30
    Decimal = 60        Hex = 0000003C  Octal = 00000000074
    Calc: Q + 3
    Decimal = 63        Hex = 0000003F  Octal = 00000000077
    Calc: TOTAL = Q + 4
    Decimal = 67        Hex = 00000043  Octal = 00000000103
    Calc: 5 + 7
    Decimal = 12    Hex = 0000000C  Octal = 00000000014
    Calc:[Return]
    $

After each prompt from the procedure, the user enters an arithmetic expression. The procedure displays the results in decimal, hexadecimal, and octal. A null line, signaled by pressing Return on a line with no data, concludes the CALC session.

## C.11 BATCH.COM Command Procedure

Accepts a command string, a command procedure, or a list of commands and then executes these commands as a batch job.

Example: BATCH.COM

    $ VERIFY_IMAGE = F$ENVIRONMENT("VERIFY_IMAGE")
    $ VERIFY_PROCEDURE = F$VERIFY(0)
    $!
    $! Turn off verification and save current settings.
    $! (This comment must appear after you turn verification
    $! off; otherwise it will appear in the batch job log file.)
    $!
    $!
    $! If this is being executed as a batch job,
    $! (from the SUBMIT section below) go to the EXECUTE_BATCH_JOB section
    $! Otherwise, get the information you need to prepare to execute the
    $! batch job.
    $!
    $ IF F$MODE() .EQS. "BATCH" THEN GOTO EXECUTE_BATCH_JOB    (1)
    $!
    $!
    $! Prepare to submit a command (or a command procedure) as a batch job.
    $! First, determine a mnemonic process name for the batch job.  Use the
    $! following rules:
    $!
    $! 1) If the user is executing a single command, then use the verb name.
    $!    Strip off any qualifiers that were included with the command.
    $! 2) If the user is executing a command procedure, then use the file name.
    $! 3) Otherwise, use BATCH.
    $!
    $ JOB_NAME = P1         (2)
    $ IF JOB_NAME .EQS. "" THEN JOB_NAME = "BATCH"
    $ IF F$EXTRACT(0,1,JOB_NAME) .EQS. "@" THEN JOB_NAME = F$EXTRACT(1,999,JOB_NAME)
    $ JOB_NAME = F$EXTRACT(0,F$LOCATE("/",JOB_NAME),JOB_NAME)
    $ JOB_NAME = F$PARSE(JOB_NAME,,,"NAME","SYNTAX_ONLY")
    $ IF JOB_NAME .EQS. "" THEN JOB_NAME = "BATCH"
    $!
    $!
    $! Get the current default device and directory.
    $!
    $ ORIGDIR = F$ENVIRONMENT("DEFAULT")
    $!
    $!
    $! Concatenate the parameters to form the command string to be executed.
    $! If the user did not enter a command string, the symbol COMMAND will have
    $! a null value.
    $!
    $ COMMAND = P1 + " " + P2 + " " + P3 + " " + P4 + " " + -  (3)
                P5 + " " + P6 + " " + P7 + " " + P8
    $!
    $!
    $! If the user is executing a single command and if both the command and the
    $! original directory specification are small enough to be passed as
    $! parameters to the SUBMIT command, then submit the batch job now.
    $!
    $ IF (P1 .NES. "") .AND. (F$LENGTH(COMMAND) .LE. 255) .AND. -    (4)
            (F$LENGTH(ORIGDIR) .LE. 255) THEN GOTO SUBMIT
    $!
    $!
    $! If the single command to be executed in the batch job is very large, or
    $! if you have to prompt for commands to execute in the batch job, then
    $! create a temporary command procedure to hold those commands and get the
    $! fully expanded name of the command procedure.
    $!
    $ CREATE_TEMP_FILE:
    $   ON CONTROL_Y THEN GOTO CONTROL_Y_HANDLER               (5)
    $   OPEN/WRITE/ERROR=FILE_OPEN_ERROR TEMPFILE SYS$SCRATCH:'JOB_NAME'.TMP (6)
    $   FILESPEC = F$SEARCH("SYS$SCRATCH:" + JOB_NAME + ".TMP")
    $!
    $!  By default, have the batch job continue if it encounters any errors.
    $!
    $   WRITE TEMPFILE "$ SET NOON"
    $!
    $!  Either write the single large command to the file, or prompt for
    $!  multiple commands and write them to the file.
    $!
    $   IF COMMAND .NES. "       " THEN GOTO WRITE_LARGE_COMMAND
    $
    $   LOOP:
    $       READ /END_OF_FILE=CLOSE_FILE /PROMPT="Command: " SYS$COMMAND COMMAND
    $       IF COMMAND .EQS. "" THEN GOTO CLOSE_FILE
    $       WRITE TEMPFILE "$ ",COMMAND
    $       GOTO LOOP
    $
    $ WRITE_LARGE_COMMAND:
    $   WRITE TEMPFILE "$ ",COMMAND
    $
    $!
    $! Finish the temporary file by defining a symbol so that you will know
    $! the name of the command procedure to delete and then close the file.
    $! Define the symbol COMMAND to mean "execute the command procedure
    $! you have just created."  Then submit the batch job and execute
    $! this command procedure in the batch job.
    $!
    $ CLOSE_FILE:                                              (7)
    $   WRITE TEMPFILE "$ BATCH$DELETE_FILESPEC == """,FILESPEC,""""
    $   CLOSE TEMPFILE
    $   ON CONTROL_Y THEN EXIT
    $   COMMAND = "@" + FILESPEC
    $!
    $!
    $! Submit BATCH.COM as a batch job, and pass it two parameters.
    $! P1 is the command (or name of the command procedure) to execute.
    $! P2 is the directory from which to execute the command.
    $!
    $ SUBMIT:                                                  (8)
    $   SUBMIT/NOTIFY/NOPRINT 'F$ENVIRONMENT("PROCEDURE")' /NAME='JOB_NAME' -
              /PARAMETERS=("''COMMAND'","''ORIGDIR'")
    $   GOTO EXIT
    $!
    $!
    $! The user pressed Ctrl/Y while the temporary command procedure was open.
    $! Close the command procedure, delete it if it exists, and exit.
    $!
    $ CONTROL_Y_HANDLER:                                       (9)
    $   CLOSE TEMPFILE
    $   IF F$TYPE(FILESPEC) .NES. "" THEN DELETE/NOLOG 'FILESPEC'
    $   WRITE SYS$OUTPUT "Ctrl/Y caused the command procedure to abort."
    $   GOTO EXIT
    $!
    $!
    $! The temporary command procedure could not be created.
    $! Notify the user and exit.
    $!
    $ FILE_OPEN_ERROR:                                         (10)
    $   WRITE SYS$OUTPUT "Could not create sys$scratch:",job_name,".tmp"
    $   WRITE SYS$OUTPUT "Please correct the situation and try again."
    $!
    $!
    $! Restore the verification states and exit.
    $!
    $ EXIT:                                                    (11)
    $  VERIFY_PROCEDURE = F$VERIFY(VERIFY_PROCEDURE,VERIFY_IMAGE)
    $  EXIT
    $!
    $!
    $! BATCH.COM was invoked as a batch job.  P1 contains the command
    $! to execute and P2 the default directory specification.
    $! Return a status code that indicates the termination status of P1.
    $!
    $ EXECUTE_BATCH_JOB:                                      (12)
    $    SET NOON
    $    VERIFY_PROCEDURE = F$VERIFY(VERIFY_PROCEDURE,VERIFY_IMAGE)
    $    SET DEFAULT 'P2'
    $    'P1'
    $    IF F$TYPE(BATCH$DELETE_FILESPEC) .EQS. "" THEN EXIT $STATUS
    $    STATUS = $STATUS
    $    DELETE /NOLOG 'BATCH$DELETE_FILESPEC'
    $    EXIT STATUS

Notes for BATCH.COM Command Procedure

1. This IF statement tests whether BATCH.COM is executing in batch mode. When you invoke BATCH.COM interactively, you provide (as parameters) a command string or a command procedure that is to be executed as a batch job. If you do not supply any parameters, then BATCH.COM prompts you for commands, writes these commands to a file, and then executes this command procedure as a batch job. After BATCH.COM prepares your commands for execution from a batch job, it uses the SUBMIT command to submit itself as a batch job and executes your commands from this job. (See Note 8.) When you invoke BATCH.COM as a batch job, the procedure branches to the label EXECUTE_BATCH_JOB. Note that you must specify the command or command procedure to execute as P1 and the default directory as P2 if you execute BATCH.COM in batch mode.
2. These commands prepare the batch job for execution. First, the procedure constructs a name for the batch job. If a command string was passed, then BATCH.COM uses the verb name as the job name. If a command procedure was passed, then BATCH.COM uses the file name. If no input was passed, then BATCH.COM names the job BATCH.
3. The parameters are concatenated to form the command string to be executed. The command string is assigned to the symbol COMMAND.
4. The SUBMIT command cannot pass a parameter that is greater than 255 characters. Therefore, the procedure tests that the command string and directory name are less than 255 characters long. If both strings are less than 255 characters (and if the user did, in fact, pass a command string), then the procedure branches to the label SUBMIT.
5. The procedure establishes a Ctrl/Y handler, so cleanup operations are performed if the user presses Ctrl/Y during this section of the command procedure.
6. The procedure creates a temporary file to contain the commands to be executed. If the user supplies a long command string, the procedure branches to WRITE_LARGE_COMMAND and writes this command to the temporary file. Otherwise, the procedure prompts for the commands to be executed. Each command is written to the temporary file.
7. Before you close the temporary file, write a symbol assignment statement to the file. This statement assigns the file name for the temporary file to the symbol BATCH$DELETE_FILESPEC. After closing the temporary file, the procedure resets the default Ctrl/Y handler. Then the procedure defines the symbol COMMAND so that, when executed, the symbol COMMAND invokes the temporary command file.
8. The procedure submits itself as a batch job, using the defined job name. (See Note 2.) The procedure also passes two parameters: the command or command procedure to be executed, and the directory from which the command should be executed. Then the procedure branches to the label EXIT. (See Note 11.)
9. This section performs cleanup operations if the user enters Ctrl/Y while the temporary file is being created.
10. This section writes an error message if the temporary file cannot be created.
11. The procedure resets the original verification settings and then exits.
12. These commands are executed when BATCH.COM runs in batch mode. First, ON error handling is disabled and the user's default verification settings are set. Then the default is set to the directory indicated by P2, and the command or command procedure indicated by P1 is executed. If a temporary file was created, this file is deleted. The completion status for P1 is saved before deleting BATCH$DELETE_FILESPEC. This completion status is returned by the EXIT command.

Sample Execution for BATCH.COM Command Procedure

    $ @BATCH RUN MYPROG
    Job RUN (queue SYS$BATCH, entry 1715) started on SYS$BATCH

The example uses BATCH.COM to run a program from within a batch job.

## C.12 COMPILE_FILE.COM Command Procedure

Compiles, links, and runs a file written in Pascal or FORTRAN. It prompts for a file to process and determines if the file type is .PAS or .FOR. If the file type is not .PAS or .FOR, or if the file does not exist in the current default directory, the command procedure outputs appropriate error messages. This procedure illustrates the use of the IF-THEN-ELSE language construct.

Example: COMPILE_FILE.COM

    $! This command procedure compiles, links, and runs a file written in Pascal
    $! or FORTRAN.
    $!
    $ ON CONTROL_Y THEN EXIT
    $!
    $ TOP:
    $   INQUIRE FILE "File to process"
    $   IF F$SEARCH(FILE) .NES. ""                             (1)
    $ THEN
    $   FILE_TYPE = F$PARSE(FILE,,,"TYPE") (2)             ! determine file type
    $   FILE_TYPE = F$EXTRACT(1,F$LENGTH('FILE_TYPE'),FILE_TYPE) ! remove period
    $! Remove type from file specification
    $   PERIOD_LOC = F$LOCATE(".",FILE)
    $   FILE = F$EXTRACT(0,PERIOD_LOC,FILE)
    $   ON WARNING THEN GOTO OTHER
    $   GOTO 'FILE_TYPE'
    $ ELSE                                                     (3)
    $   WRITE SYS$OUTPUT FILE, "does not exist"
    $ ENDIF                                                    (4)
    $!
    $ GOTO END
    $!
    $!
    $!
    $ FOR:                                                      (5)
    $ ON ERROR THEN GOTO PRINT
    $ FORTRAN/LIST 'FILE'
    $ GOTO LINK

    $!
    $ PAS:
    $   ON ERROR THEN GOTO PRINT
    $   PASCAL/LIST 'FILE'
    $   GOTO LINK
    $!
    $ OTHER:
    $   WRITE SYS$OUTPUT "Can't handle files of type .''FILE_TYPE'"
    $   GOTO END
    $!
    $ LINK:                                                    (6)
    $   ON ERROR THEN GOTO END
    $   WRITE SYS$OUTPUT "Successful compilation ...."
    $   LINK 'FILE'
    $   DEFINE/USER_MODE SYS$INPUT SYS$COMMAND
    $   RUN 'FILE'
    $   GOTO CLEANUP
    $!
    $ PRINT:                                                   (7)
    $   WRITE SYS$OUTPUT "Unsuccessful compilation, printing listing file ...."
    $   PRINT 'FILE'
    $!
    $ CLEANUP:
    $   DELETE 'FILE'.OBJ;
    $   DELETE 'FILE'.LIS;
    $!
    $ END:
    $   INQUIRE/NOPUNCTUATION ANS "Process another file (Y or N)?  "
    $   IF ANS THEN GOTO TOP
    $ EXIT

Notes for COMPILE_FILE.COM Command Procedure

1. The IF command uses the F$SEARCH lexical function to search the directory and determine if the file exists.
2. The command block following the THEN command:
   - Uses the F$LENGTH lexical function to determine the length of the file type
   - Determines the file type
   - Removes the period from the file type
   - Removes the file type from the file specification to determine the file name
   - Removes the period from the file name
   - Defines an action to perform if an error occurs
   - Branches to the label defined by the symbol FILE_TYPE
3. If the file you entered at the "File to process:" prompt does not exist in the directory, the command following the ELSE command executes.
4. The ENDIF command ends the IF-THEN-ELSE command language construct.
5. The procedure compiles the FORTRAN program and branches to the LINK label. If an error occurs during the compilation, the procedure branches to the PRINT label.
6. The procedure displays that the program compiled correctly, links and runs the program, and branches to the CLEANUP label. The program branches to the END label if an error occurs.
7. The procedure enters the listing file of the program in the default print queue.

Sample Execution for COMPILE_FILE.COM Command Procedure

    $ @COMPILE_FILE
    File to process: RAND.PAS
    Successful compilation
    %DELETE-I-FILDEL,WORK:[DESCH]RAND.OBJ;1 deleted (3 blocks)
    %DELETE-I-FILDEL,WORK:[DESCH]RAND.LIS;1 deleted (9 blocks)
    Process another file (Y or N)? N [Return]

Previous | Next | Contents | Index

| privacy and legal statement |
6489PRO_058.HTML