Document revision date: 30 March 2001

## OpenVMS User's Manual

Previous | Contents | Index

## Appendix C
Annotated Command Procedures

This appendix contains complete command procedures for the concepts and techniques discussed in Chapter 15, Chapter 16, and Chapter 17. Each section in this appendix discusses one command procedure and provides the following information:

- The name of the procedure
- A listing of the procedure
- Notes that explain concepts or techniques used by the procedure
- The results of a sample execution of the procedure

## C.1 CONVERT.COM Command Procedure

This command procedure converts an absolute time (for a time in the future) to a delta time and determines the time between the current time and the time that you specify. The procedure illustrates the use of the F$TIME and F$CVTIME lexical functions and the use of assignment statements to perform arithmetic calculations and to concatenate symbol values.

Example: CONVERT.COM

    $ ! Procedure to convert an absolute time to a delta time.
    $ ! The delta time is returned as the global symbol WAIT_TIME.
    $ ! P1 is the time to be converted.
    $ ! P2 is an optional parameter - SHOW - that causes the
    $ ! procedure to display WAIT_TIME before exiting
    $ !
    $ ! Check for inquiry
    $ !
    $ IF P1 .EQS. "?" .OR. P1 .EQS. "" THEN GOTO TELL          (1)
    $ !
    $ ! Verify the parameter:  hours must be less than 24
    $ !                        minutes must be less than 60
    $ !                        time string must contain only hours
    $ !                        and minutes
    $ !
    $ ! Change error and message handling to
    $ ! use message at BADTIME
    $ !
    $ ON WARNING THEN GOTO BADTIME                             (2)
    $ SAVE_MESSAGE = F$ENVIRONMENT("MESSAGE")
    $ SET MESSAGE/NOFACILITY/NOIDENTIFICATION/NOSEVERITY/NOTEXT
    $ TEMP = F$CVTIME(P1)
    $ !
    $ ! Restore default error handling and message format
    $ ON ERROR THEN EXIT
    $ SET MESSAGE'SAVE_MESSAGE'
    $ !
    $ IF F$LENGTH(P1) .NE. 5 .OR. -                            (3)
            F$LOCATE(":",P1) .NE. 2 -
            THEN GOTO BADTIME
    $ !
    $ ! Get the current time
    $ !
    $ TIME = F$TIME()                                          (4)
    $ !
    $ ! Extract the hour and minute fields from both the current time
    $ ! value (TIME) and the future time (P1)
    $ !
    $ MINUTES = F$CVTIME(TIME,"ABSOLUTE","MINUTE")       ! Current minutes (5)
    $ HOURS = F$CVTIME(TIME,"ABSOLUTE","HOUR")           ! Current hours
    $ FUTURE_MINUTES = F$CVTIME(P1,"ABSOLUTE","MINUTE")  ! Minutes in future time
    $ FUTURE_HOURS = F$CVTIME(P1,"ABSOLUTE","HOUR")      ! Hours in future time
    $ !
    $ !
    $ ! Convert both time values to minutes
    $ ! Note the implicit string to integer conversion being performed
    $ !
    $ CURRENT_TIME = HOURS*60 + MINUTES                        (6)
    $ FUTURE_TIME = FUTURE_HOURS*60 + FUTURE_MINUTES
    $ !
    $ ! Compute difference between the future time and the current time
    $ ! (in minutes)
    $ !
    $ !
    $ MINUTES_TO_WAIT = FUTURE_TIME - CURRENT_TIME             (7)
    $ !
    $ ! If the result is less than 0 the specified time is assumed to be
    $ ! for the next day; more calculation is required.
    $ !
    $ IF MINUTES_TO_WAIT .LT. 0 THEN -                         (8)
            MINUTES_TO_WAIT = 24*60 + FUTURE_TIME - CURRENT_TIME
    $ !
    $ ! Start looping to determine the value in hours and minutes from
    $ ! the value expressed all in minutes
    $ !
    $       HOURS_TO_WAIT = 0
    $ HOURS_TO_WAIT_LOOP:                                      (9)
    $       IF MINUTES_TO_WAIT .LT. 60 THEN GOTO FINISH_COMPUTE
    $       MINUTES_TO_WAIT = MINUTES_TO_WAIT - 60
    $       HOURS_TO_WAIT = HOURS_TO_WAIT + 1
    $       GOTO HOURS_TO_WAIT_LOOP
    $ FINISH_COMPUTE:
    $ !
    $ ! Construct the delta time string in the proper format
    $ !
    $ WAIT_TIME == F$STRING(HOURS_TO_WAIT)+ ":" + F$STRING(MINUTES_TO_WAIT)- (10)
      + ":00.00"
    $ !
    $ ! Examine the second parameter
    $ !
    $ IF P2 .EQS.  "SHOW" THEN SHOW SYMBOL WAIT_TIME           (11)
    $ !
    $ ! Normal exit
    $ !
    $ EXIT
    $ !
    $ BADTIME:                                                 (12)
    $ ! Exit taken if first parameter is not formatted correctly
    $ ! EXIT command returns but does not display error status
    $ !
    $ SET MESSAGE'SAVE_MESSAGE'
    $ WRITE SYS$OUTPUT  "Invalid time value: ",P1,", format must be hh:mm"
    $ WRITE SYS$OUTPUT "Hours must be less than 24; minutes must be less than 60"
    $ EXIT %X10000000
    $ !
    $ !
    $ TELL:                                                    (13)
    $ ! Display message and exit if user enters inquiry or enters
    $ ! an illegal parameter
    $ !
    $ TYPE SYS$INPUT
            This procedure converts an absolute time value to
            a delta time value.  The absolute time must be in
            the form hh:mm and must indicate a time in the future.
            On return, the global symbol WAIT_TIME contains the
            converted time value.  If you enter the keyword SHOW
            as the second parameter, the procedure displays the
            resulting value in the output stream. To invoke this
            procedure, use the following syntax:

                           @CONVERT hh:mm [SHOW]
    $ EXIT

Notes for CONVERT.COM Command Procedure

1. The procedure checks whether the parameter was omitted or whether the value entered for a parameter is the question mark (?) character. In either case, the procedure branches to the label TELL.
2. The procedure uses the F$CVTIME function to verify that the time value is a valid 24-hour clock time; the F$CVTIME returns a warning message if the input time is not valid. If the F$CVTIME function returns an error, the procedure changes the default ON action to direct control to the label BADTIME.
   The procedure uses the F$ENVIRONMENT function to save the current message setting. It then sets the message format so that no warning or error messages are displayed. After checking the time values, the procedure restores the default ON condition and message format.
3. The procedure checks the format of the parameter. It must be a time value in the following format:

   `hh:mm`

   The IF command checks (1) that the length of the entered value is 5 characters and (2) that the third character (offset of 2) is a colon. The IF command contains the logical OR operator: if either expression is true (that is, if the length is not 5 or if there is not a colon in the third character position), the procedure branches to the label BADTIME.

4. The F$TIME lexical function places the current time value in the symbol TIME.
5. The F$CVTIME function extracts the "minute" and "hour" fields from the current time (saved in the symbol TIME). Then the F$CVTIME function extracts the "minute" and "hour") fields from the time you want to convert.
6. These assignment statements convert the current and future times to minutes. When you use the symbols MINUTES, HOURS, FUTURE_HOURS, and FUTURE_MINUTES in the assignment statements, the system automatically converts these values to integers.
7. The procedure then subtracts the current time (in minutes) from the future time (in minutes).
8. If the result is less than 0, the future time is interpreted as being on the next day. In this case, the procedure adds 24 hours to the future time and then subtracts the current time.
9. The procedure enters a loop in which it calculates, from the value of MINUTES_TO_WAIT, the number of hours. Each time through the loop, it checks whether MINUTES_TO_WAIT is greater than 60. If it is, the procedure subtracts 60 from MINUTES_TO_WAIT and adds 1 to the accumulator for the number of hours (HOURS_TO_WAIT).
10. When the procedure exits from the loop, it concatenates the hours and minutes values into a time string. The symbols HOURS_TO_WAIT and MINUTES_TO_WAIT are replaced by their character string equivalents and separated with an intervening colon. The resulting string is assigned to the symbol WAIT_TIME, which holds the delta time value for the future time. WAIT_TIME is defined as a global symbol so that it is not deleted when the procedure CONVERT.COM exits.
11. If a second parameter, SHOW, was entered, the procedure displays the resulting time value. Otherwise, it exits.
12. At the label BADTIME, the procedure displays an error message that shows the incorrect value entered as well as the format it requires. After issuing the error message, CONVERT.COM exits. The EXIT command returns an error status in which the high-order digit is set to 1. This suppresses the display of an error message.
    The procedure explicitly specifies an error status with the EXIT command, so you can execute CONVERT.COM from within another procedure. When CONVERT.COM completes, the calling procedure can determine whether a time was successfully translated.
13. At the label TELL, the procedure displays information about what the procedure does. The TYPE command displays the lines listed in SYS$INPUT, the input data stream.

Sample Execution for CONVERT.COM Command Procedure

    $ SHOW TIME
    10-JUN-1999 10:38:26
    $ @CONVERT 12:00 SHOW
       WAIT_TIME = "1:22:00.00"

The SHOW TIME command displays the current date and time. CONVERT.COM is executed with the parameters 12:00 and SHOW. The procedure converts the absolute time 12:00 to a delta time value and displays it on the terminal.

## C.2 REMINDER.COM Command Procedure

This command procedure displays a reminder message on your terminal at a specified time. The procedure prompts for the time you want the message to be displayed and for the text of the message. The procedure uses CONVERT.COM to convert the time to a delta time. The procedure then spawns a subprocess that waits until the specified time and displays your reminder message. The procedure illustrates the use of the F$ENVIRONMENT, F$VERIFY, and F$GETDVI functions.

Example: REMINDER.COM

    $ ! Procedure to obtain a reminder message and display this
    $ ! message on your terminal at the time you specify.
    $ !
    $ ! Save current states for procedure and image verification
    $ ! Turn verification off for duration of procedure
    $
    $ SAVE_VERIFY_IMAGE = F$ENVIRONMENT("VERIFY_IMAGE")               (1)
    $ SAVE_VERIFY_PROC = F$VERIFY(0)
    $ !
    $ ! Places the current process in a wait state until a specified
    $ ! absolute time.  Then, it rings the bell on the terminal and
    $ ! displays a message.
    $ !
    $ ! Prompt for absolute time
    $ !
    $
    $ GET_TIME:
    $ INQUIRE REMINDER_TIME  "Enter time to send reminder (hh:mm)"    (2)
    $ INQUIRE MESSAGE_TEXT "Enter message"
    $ !
    $ ! Call the CONVERT.COM procedure to convert the absolute time
    $ ! to a delta time
    $ !
    $ @DISK2:[JONES.TOOLS]CONVERT 'REMINDER_TIME'                     (3)
    $ IF .NOT. $STATUS THEN GOTO BADTIME
    $ !
    $ !
    $ ! Create a command file that will be executed
    $ ! in a subprocess.  The subprocess will wait until
    $ ! the specified time and then display your message
    $ ! at the terminal.  If you are working at a DEC_CRT
    $ ! terminal, the message has double size blinking
    $ ! characters. Otherwise, the message has normal letters.
    $ ! In either case, the terminal bell rings when the
    $ ! message is displayed.
    $
    $ CREATE WAKEUP.COM                                        (4)
    $ DECK                            ! Lines starting with $ are data lines
    $ WAIT 'WAIT_TIME'                                         (5)
    $ BELL[0,7] = %X07                ! Create symbol to ring the bell
    $ IF F$GETDVI("SYS$OUTPUT","TT_DECCRT") .NES. "TRUE" THEN GOTO OTHER_TERM
    $ !
    $ DEC_CRT_ONLY:
    $ ! Create symbols to set special graphics (for DEC_CRT terminals only)
    $ !
    $     SET_FLASH = "<ESC>[1;5m"    ! Turn on blinking characters
    $     SET_NOFLASH = "<ESC>[0m"    ! Turn off blinking characters
    $     TOP = "<ESC>#3"             ! Double size characters (top portion)
    $     BOT = "<ESC>#4"             ! Double size characters (bottom portion)
    $ !
    $ ! Write double size, blinking message to the terminal and ring the bell
    $ !
    $     WRITE SYS$OUTPUT BELL, SET_FLASH, TOP, MESSAGE_TEXT
    $     WRITE SYS$OUTPUT BELL, BOT, MESSAGE_TEXT
    $     WRITE SYS$OUTPUT F$TIME(), SET_NOFLASH
    $     GOTO CLEAN_UP
    $ !
    $ OTHER_TERM:
    $      WRITE SYS$OUTPUT BELL,MESSAGE_TEXT
    $      WRITE SYS$OUTPUT F$TIME()
    $ !
    $ CLEAN_UP:
    $      DELETE WAKEUP.COM;*
    $ EOD
    $ !
    $ ! Now continue executing commands.
    $ !
    $ SPAWN/NOWAIT/INPUT=WAKEUP.COM                            (6)
    $ END:                                                     (7)
    $ !   Restore verification
    $     SAVE_VERIFY_PROC = F$VERIFY(SAVE_VERIFY_PROC, SAVE_VERIFY_IMAGE)
    $     EXIT
    $ !
    $ BADTIME:
    $    WRITE SYS$OUTPUT "Time must be entered as hh:mm"
    $    GOTO GET_TIME

Notes for REMINDER.COM Command Procedure

1. The procedure uses the F$ENVIRONMENT function to save the image verification setting in the symbol SAVE_VERIFY_IMAGE. Next, the procedure uses the F$VERIFY function to save the procedure verification setting in the symbol SAVE_VERIFY_PROC. The F$VERIFY function also turns off both types of verification.
2. The procedure uses the INQUIRE command to prompt for the time when the reminder message should be sent. This value is used as input to the procedure CONVERT.COM. The procedure also prompts for the text of the message.
3. The procedure executes a nested procedure, CONVERT.COM. Be sure to specify the disk and directory as part of the file specification; this ensures that the system can locate CONVERT.COM regardless of the directory from which you execute REMINDER.COM.
   CONVERT.COM converts your reminder to a delta time, and returns this time in the global symbol WAIT_TIME. This delta time indicates the time interval from the current time until the time when the message should be sent. If CONVERT.COM returns an error, the procedure branches to the label BADTIME.
4. The procedure uses the CREATE command to create a new procedure, WAKEUP.COM. This procedure is executed from within a subprocess. To allow the CREATE command to read lines that begin with dollar signs, use the DECK and EOD commands to surround the input for the CREATE command. Therefore, all lines between the DECK and EOD commands are written to WAKEUP.COM.
5. WAKEUP.COM performs the following tasks:
   - It waits until the time indicated by the symbol WAIT_TIME.
   - It creates the symbol BELL to ring the terminal bell.
   - It determines whether the terminal is a DEC_CRT terminal and can accept escape sequences to display double-size, blinking characters. (To see whether you have a DEC_CRT terminal, enter the SHOW TERMINAL command and see whether this characteristic is listed.)
   - If the terminal is a DEC_CRT terminal, then the procedure defines the symbols SET_FLASH, TOP, and BOT. These symbols cause the terminal to use flashing, double-size characters. The procedure also defines the symbol SET_NOFLASH to return the terminal to its normal state. To enter the escape character (<ESC>) when you create these definitions using the EDT editor, press the ESC key twice.
     After defining these symbols, the procedure writes three lines to the terminal. The first line rings the bell, turns on flashing characters, and displays (using double-size characters) the top half of your message. The second line rings the bell again and displays the bottom half of your message. The third line writes the current time and then turns off the flash characteristic to return your terminal to normal.
     If you do not have a DEC_CRT terminal, then the procedure rings your terminal bell, and displays your message and the time.
   - The DELETE command causes the procedure WAKEUP.COM to delete itself after it executes.
6. After creating WAKEUP.COM, the procedure spawns a subprocess and directs the subprocess to use WAKEUP.COM as the input command file. The /NOWAIT qualifier allows you to continue working at your terminal while the subprocess executes commands from WAKEUP.COM. At the specified time, WAKEUP.COM displays your message on your terminal.
   Note that, by default, the SPAWN command passes global and local symbols to a subprocess. Therefore, although you provide values for the symbols WAIT_TIME and MESSAGE_TEXT in REMINDER.COM, WAKEUP.COM can also access these symbols.
7. The procedure restores the original verification settings before it exits.

Sample Execution for REMINDER.COM Command Procedure

    $ @REMINDER
    Enter time to send reminder (hh:mm): 12:00
    Enter message: TIME FOR LUNCH
    %DCL-S-SPAWNED, process BLUTO_1 spawned
    $
       .
       .
       .
    TIME FOR LUNCH
    11-DEC-1999 12:00:56.99

The procedure prompts for a time value and for your message. Then the procedure spawns a subprocess that displays your message. You can continue working at your terminal; at the specified time, the subprocess rings the terminal bell, displays your message, and displays the time.

## C.3 DIR.COM Command Procedure

This command procedure imitates the DCL command DIRECTORY/SIZE=ALL/DATE, displaying the block size (used and allocated) and creation date of the specified files. It illustrates use of the F$PARSE, F$SEARCH, F$FILE_ATTRIBUTES, and F$FAO lexical functions.

Example: DIR.COM

    $ !
    $ ! Command procedure implementation of DIRECTORY/SIZE=ALL/DATE
    $ ! command
    $ !
    $ SAVE_VERIFY_IMAGE = F$ENVIRONMENT("VERIFY_IMAGE")
    $ SAVE_VERIFY_PROCEDURE = F$VERIFY(0)
    $ !
    $ ! Replace any blank field of the P1 file specification with
    $ ! a wildcard character
    $ !
    $ P1 = F$PARSE(P1,"*.*;*")                                 (1)
    $ !
    $ ! Define initial values for symbols
    $ !
    $ FIRST_TIME = "TRUE"
    $ FILE_COUNT = 0
    $ TOTAL_ALLOC = 0
    $ TOTAL_USED = 0
    $
    $ LOOP:                                                    (2)
    $       FILESPEC = F$SEARCH(P1)
    $ ! Find next file in directory
    $       IF FILESPEC .EQS. "" THEN GOTO DONE
    $ ! If no more files, then done
    $       IF .NOT. FIRST_TIME THEN GOTO SHOW_FILE
    $ ! Print header only once
    $ !
    $ ! Construct and output the header line
    $ !
    $       FIRST_TIME =  "FALSE"                              (3)
    $       DIRSPEC = F$PARSE(FILESPEC,,, "DEVICE") -
                    +F$PARSE(FILESPEC,,, "DIRECTORY")
    $       WRITE SYS$OUTPUT ""
    $       WRITE SYS$OUTPUT  "Directory ",DIRSPEC
    $       WRITE SYS$OUTPUT ""
    $       LASTDIR = DIRSPEC
    $
    $ !
    $ ! Put the file name together, get some of the file attributes, and
    $ ! type the information out
    $ !
    $SHOW_FILE:
    $       FILE_COUNT = FILE_COUNT + 1
    $       FILENAME = F$PARSE(FILESPEC,,, "NAME") -           (4)
                     + F$PARSE(FILESPEC,,, "TYPE") -
                     + F$PARSE(FILESPEC,,, "VERSION")
    $      ALLOC = F$FILE_ATTRIBUTES(FILESPEC, "ALQ")
    $      USED = F$FILE_ATTRIBUTES(FILESPEC, "EOF")
    $      TOTAL_ALLOC = TOTAL_ALLOC + ALLOC
    $      TOTAL_USED = TOTAL_USED + USED
    $      REVISED = F$FILE_ATTRIBUTES(FILESPEC,"RDT")
    $      LINE = F$FAO("!19AS !5UL/!5<!UL!> !17AS",FILENAME,-
                   USED, ALLOC, REVISED)
    $      WRITE SYS$OUTPUT LINE
    $      GOTO LOOP
    $
    $ !
    $ ! Output summary information, reset verification, and exit
    $ !
    $ DONE:                                                    (5)
    $      WRITE SYS$OUTPUT ""
    $      WRITE SYS$OUTPUT "Total of ''FILE_COUNT' files, " + -
                            "''TOTAL_USED'/''TOTAL_ALLOC' blocks."
    $      SAVE_VERIFY_PROCEDURE = F$VERIFY(SAVE_VERIFY_PROCEDURE,SAVE_VERIFY_IMAGE)
    $      EXIT

Notes for DIR.COM Command Procedure

1. This procedure uses the F$PARSE function to place asterisks in blank fields in P1, the user-supplied file specification. If you do not specify a parameter when you execute DIR.COM, then the F$PARSE function assigns the value "*.*;*" to P1. This causes DIR.COM to display all files in the current default directory.
2. The F$SEARCH lexical function searches the directory for the file (or files) indicated by P1. If P1 contains any wildcards (asterisks), the F$SEARCH function returns all matching file specifications. After the last file specification has been returned, the procedure branches to the label DONE.
3. The first time through the loop, the procedure writes a header for the directory display. This header includes the device and directory names. To obtain these names, the procedure uses the F$PARSE function.
4. The procedure uses the F$PARSE lexical function to extract the file name from each file specification in the directory. The F$FILE_ATTRIBUTES lexical function then obtains blocks used, blocks allocated, and creation date information about each file. Finally, the F$FAO function formats a single display line for each file in the directory. The F$FAO function uses the file name and file attribute information as arguments.
5. When F$SEARCH returns a null string, the procedure branches to the label DONE and displays summary information showing the total number of files, the total number of blocks used, and the total number of blocks allocated in the directory.

Sample Execution for DIR.COM Command Procedure

    $ @DIR [VERN]*.COM

    Directory DISK4:[VERN]

    BATCH.COM;1             1/3     11-DEC-1999 11:43
    CALC.COM;3              1/3     11-DEC-1999 11:30
    CONVERT.COM;1           5/6     11-DEC-1999 15:23
       .
       .
       .
    LOGIN.COM;34            2/3     11-DEC-1999 13:17
    PID.COM;7               1/3     11-DEC-1999 09:49
    SCRATCH.COM;6           1/3     11-DEC-1999 11:29)

    Total of 15 files, 22/48 blocks.

The procedure returns information on all .COM files in the directory [VERN].

Previous | Next | Contents | Index

| privacy and legal statement |
6489PRO_056.HTML