[an error occurred while processing this directive]

HP OpenVMS Systems Documentation

Content starts here

OpenVMS User's Manual


Previous Contents Index

13.5.3 Step 3: Add Loops

A loop is a group of statements that execute repeatedly until a condition is met. A loop works as follows:

  1. Obtains a value from user input
  2. Processes the command
  3. Repeats the process until the user exits the command procedure

To write a loop, follow this procedure:

Step Action
1 Begin the loop with a label.
2 Test a variable to determine whether you need to execute the commands in the loop.
3 If you do not need to execute the loop, go to the end of the loop.
4 If you need to execute the loop, perform the commands in the body of the loop, then return to the beginning of the loop.
5 End the loop.

The following example shows the usage of loops in the CLEANUP.COM command procedure:


$ GET_COM_LOOP:
$     INQUIRE COMMAND-
$     "Enter command (DELETE, DIRECTORY. EXIT, PRINT, PURGE, TYPE)"
$     IF COMMAND .EQS. "EXIT" THEN GOTO END_LOOP
$!
$! Execute if user entered DELETE
$ DELETE:
$     IF COMMAND .NES. "DELETE" THEN GOTO DIRECTORY
$     WRITE SYS$OUTPUT "This is the DELETE section."
$     GOTO GET_COM_LOOP
   .
   .
   .
$ END_LOOP:
$     WRITE SYS$OUTPUT "Directory ''F$DIRECTORY()' has been cleaned"
$ EXIT

Once a command executes, control is passed back to the GET_COM_LOOP label until a user enters the EXIT command. When an EXIT command is entered, the procedure outputs a message stating that the directory has been cleaned.

13.5.4 Step 4: End the Command Procedure

To end a command procedure, follow this procedure:

Step Action
1 Decide where you might need to exit or quit from the command procedure.
2 Place EXIT or STOP commands as appropriate.

13.5.4.1 Using the EXIT Command

You can put an EXIT command in your command procedure to:

  • Ensure that a procedure does not execute certain lines
  • End procedures that have more than one execution path
  • End a command procedure

The following is an example of using an EXIT command to avoid executing an error handling routine that is located at the end of a procedure:


   .
   .
   .
$ EXIT ! End of normal execution path
$ ERROR_ROUTINE
   .
   .
   .

The following is an example of using the EXIT command to end a procedure that has more than one execution path:


$ START:
$     IF P1 .EQS. "TAPE" .OR. P1 .EQS. "DISK" THEN GOTO 'P1'
$     INQUIRE P1 "Enter device (TAPE or DISK)"
$     GOTO START
$ TAPE: !Process tape files
   .
   .
   .
$     EXIT
$ DISK: ! Process disk files
   .
   .
   .
$     EXIT

The commands following each of the labels (TAPE and DISK) provide different paths though the procedure. The EXIT command before the DISK label ensures that the commands after the DISK label do not execute unless the procedure branches explicitly to the label.

The EXIT command is not required at the end of procedures because the end-of-file of the procedure causes an implicit EXIT command. However, Compaq recommends use of the EXIT command.

13.5.4.2 Using the STOP Command

You can use the STOP command in a command procedure to ensure that the procedure terminates if a severe error occurs. If the STOP command is in a command procedure that is executed interactively, control is returned to the DCL level. If a command procedure is being executed in batch mode, the batch job terminates.

This command line tells the procedure to stop if a severe error occurs:


$ ON SEVERE_ERROR THEN STOP

13.5.5 Step 5: Test and Debug the Program Logic

Once you have written the code using program stubs, you should test the overall logic of the command procedure. You should test all possible paths of execution.

Follow this procedure to test and debug command procedures:

Step Action
1 Test the program logic by entering each valid command in the command procedure.
2 Continue testing the program logic by entering an invalid command.
3 Finish testing the program logic by exiting from the command procedure using the EXIT command.
4 If necessary, debug the program using the SET VERIFY, SET PREFIX, or SHOW SYMBOL commands.

The following example shows how to test the command procedure by entering and executing every possible command, an invalid command, and then exiting:


$ @CLEANUP
  Enter command (DELETE, DIRECTORY, EXIT, PRINT, PURGE, TYPE): DELETE
  This is the DELETE section.
  Enter command (DELETE, DIRECTORY, EXIT, PRINT, PURGE, TYPE): DIRECTORY
  This is the DIRECTORY section.
   .
   .
   .
  Enter command (DELETE, DIRECTORY, EXIT, PRINT, PURGE, TYPE): PRINF
  You have entered an invalid command.
  Enter command (DELETE, DIRECTORY, EXIT, PRINT, PURGE, TYPE): EXIT
$

13.5.5.1 Debugging Command Procedures

You can use the following commands to help debug command procedures:

  • SET VERIFY
    Displays each line before it is executed. When an error occurs with verification set, you see the error and the line that generated the error. You can use keywords with the SET VERIFY command to indicate that only command lines or data lines are to be verified.
    The SET VERIFY command remains in effect until you log out, you enter the SET NOVERIFY command, or you use the F$VERIFY lexical function to change the verification setting. (Chapter 15 contains more information on changing verification settings.)
  • SET PREFIX
    If verification is in effect, you can also use the DCL command SET PREFIX to time-stamp a procedure log file by prefixing each command line with the time it is executed.
  • SHOW SYMBOL
    The SHOW SYMBOL command can be used to determine how symbols in the procedure are defined.

Example: Debugging Using the SET VERIFY Command

In the following example, the label END_LOP is spelled incorrectly. You can see exactly where the error is because verification is turned on:


$ SET VERIFY
$ @CLEAN
$ GET_COM_LOOP:
$    INQUIRE COMMAND -
     "Enter command (DELETE, DIRECTORY, EXIT, PRINT, PURGE, TYPE)"
 Enter command (DELETE, DIRECTORY, EXIT, PRINT, PURGE, TYPE): EXIT
$    IF COMMAND .EQS. "EXIT" THEN GOTO END_LOP
 %DCL-W-USGOTO, target of GOTO not found -
 check spelling and presence of label

To correct the error, change the label to END_LOOP.

Example: Debugging Using the SET PREFIX Command

The following example illustrates the use of time-stamping:


$  SET VERIFY
$  @TEST
$  SET DEFAULT SYS$LOGIN
$  SHOW DEFAULT
   USER$:[SMYTHE]
$  SET PREFIX "(!5%T) "
$  @TEST
 (17:52)  $ SET DEFAULT SYS$LOGIN
 (17:52)  $ SHOW DEFAULT
   USER$:[SMYTHE]

Example: Debugging Using the SHOW SYMBOL Command

The following example shows how the SHOW SYMBOL command is used to determine how the symbol COMMAND is defined:


$ SET VERIFY
$ @CLEAN
$ GET_COM_LOOP:
$    INQUIRE COMMAND -
     "ENTER COMMAND (DELETE, DIRECTORY, EXIT, PRINT, PURGE, TYPE)"
  ENTER COMMAND (DELETE, DIRECTORY, EXIT, PRINT, PURGE, TYPE): EXIT
$ SHOW SYMBOL COMMAND
 COMMAND = "EXIT"
$    IF COMMAND .EQS. "exit" THEN GOTO END_LOOP
   .
   .
   .

The SHOW SYMBOL command reveals that the symbol COMMAND has the value "EXIT". Because the INQUIRE command automatically converts input to uppercase and the IF statement that tests the command uses lowercase characters in the string "exit", DCL determines that the strings are not equal. To correct the error, make sure that the quoted string in the IF statement is written in capital letters. The rest of the string can use either uppercase or lowercase letters.

13.5.5.2 Enabling Verification During Execution

You can also interrupt a command procedure while it is executing to enable verification. As long as the command procedure does not contain the SET VERIFY command or a Ctrl/Y key sequence, you can enable verification by following these steps:

Step Action
1 Press Ctrl/Y to interrupt execution.
2 Enter the SET VERIFY command.
3 Enter the CONTINUE command to continue execution of the command procedure (with verification enabled).

13.5.6 Step 6: Add Cleanup Tasks

In general, execution of a command procedure should not change the user's process state. Therefore, a command procedure should include a set of commands that return the process to its original state. This set of commands is usually part of a subroutine that is labeled "CLEAN_UP". Common cleanup operations include closing files and resetting the default device and directory.

Follow this procedure to add cleanup tasks to your command procedure:

Step Task
1 Begin the cleanup subroutine with a label, such as CLEAN_UP.
2 Test for any open files using the F$GETJPI lexical function.
3 Delete any temporary or extraneous files using the DELETE or PURGE command.
4 If you have changed any defaults (such as the device or directory), restore them to their original state using the SET DEFAULT command.
5 Include an ON CONTROL_Y statement to ensure that the cleanup operations are performed.

13.5.6.1 Closing Files

If you have any open files, make sure that they are closed before the procedure exits. You can use the lexical function F$GETJPI to examine the remaining open file quota (FILCNT) for the process. If FILCNT is the same at the beginning and end of the command procedure, you know that no files have been left open.

These are the commands that you would use to warn a user that a file has been left open:


$ FIL_COUNT = F$GETJPI ("","FILCNT")
   .
   .
   .
$ IF FILCNT .NE. F$GETJPI ("", "FILCNT") THEN-
  WRITE SYS$OUTPUT "WARNING -- file left open)

13.5.6.2 Deleting Temporary or Extraneous Files

If you have created temporary files, delete them. In general, if you have updated any files, you should purge them to delete the previous copies. Before you delete files you have not created, make sure you want to delete them. For example, if you have updated a file that contains crucial data, you might want to make the purging operation optional.

If you change the default device, the directory, or both, reset the original defaults before the command procedure exits. To save the name of the original default directory, use the DEFAULT keyword of the F$ENVIRONMENT lexical function. At the end of the command procedure, include a SET DEFAULT command that restores the saved device and directory.

The command lines shown in this example save and restore the device and directory defaults:


$ SAV_DEFAULT = F$ENVIRONMENT ("DEFAULT")
   .
   .
   .
$ SET DEFAULT 'SAV_DEFAULT'

13.5.6.3 Commonly Changed Process Characteristics

The following table lists other commonly changed process characteristics, the lexical functions used to save them, and the lexical function or command used to restore them:

Characteristic Lexical Function
Used to Save
Lexical Function
Used to Restore
DCL prompt F$ENVIRONMENT SET PROMPT
Default protection F$ENVIRONMENT SET PROTECTION/DEFAULT
Privileges F$SETPRV F$SETPRV or SET PROCESS/PRIVILEGES
Control characters F$ENVIRONMENT SET CONTROL
Verification F$VERIFY F$VERIFY
Message format F$ENVIRONMENT SET MESSAGE
Key state F$ENVIRONMENT SET KEY

For complete descriptions of these lexical functions, refer to the OpenVMS DCL Dictionary.

13.5.6.4 Ensuring Cleanup Operations Are Performed

To ensure that cleanup operations are performed even if the command procedure is aborted, begin each command level in the command procedure with the following statement:


$ ON CONTROL_Y THEN GOTO CLEANUP

For additional information on using the ON CONTROL_Y command, see Chapter 14.

13.5.7 Step 7: Complete the Command Procedure

When your general design works correctly, follow these steps to complete your command procedure:

Step Task
1 Substitute commands for the first program stub in the command procedure.
2 Test the command procedure to make sure that the new commands work properly.
3 Debug the command procedure, if necessary.
4 When the first program stub works, move to the next one, and so on, until all program stubs have been replaced.

Example: Replacing a Program Stub with Commands

The following example shows the code for the TYPE section of CLEANUP.COM:


$! Execute if user entered TYPE
$! TYPE:
$      IF COMMAND .NES. "TYPE THEN GOTO ERROR
$      INQUIRE FILE "File to type"
$      TYPE 'FILE'
$      GOTO GET_COM_LOOP

This would replace the existing code:


$ WRITE SYS$OUTPUT "This is the TYPE section."

Example: CLEANUP.COM Command Procedure

Following is an example of the completed CLEANUP.COM command procedure:


$ GET_COM_LOOP:
$    INQUIRE COMMAND -
     "Enter command (DELETE, DIRECTORY, EXIT, PRINT, PURGE, TYPE)"
$    IF COMMAND .EQS. "EXIT" THEN GOTO END_LOOP
$!
$!Execute if user entered DELETE
$ DELETE:
$       IF COMMAND .NES. "DELETE" THEN GOTO DIRECTORY
$       INQUIRE FILE "File to delete? "
$       DELETE 'FILE'
$       GOTO GET_COM_LOOP
$!
$!Execute if user entered DIRECTORY
$ DIRECTORY:
$       IF COMMAND .NES. "DIRECTORY" THEN GOTO PRINT
$       DIRECTORY
$       GOTO GET_COM_LOOP
$!
$!Execute if user entered PRINT
$ PRINT:
$       IF COMMAND .NES. "PRINT" THEN GOTO PURGE
$       INQUIRE FILE "File to print? "
$       PRINT SYS$OUTPUT 'FILE'
$       GOTO GET_COM_LOOP
$!
$!Execute if user entered PURGE
$ PURGE:
$       IF COMMAND .NES. "PURGE" THEN GOTO TYPE
$       PURGE
$       GOTO GET_COM_LOOP
$!
$!Execute if user entered TYPE
$ TYPE:
$       IF COMMAND .NES. "TYPE" THEN GOTO ERROR
$       INQUIRE FILE "File to type"
$       TYPE 'FILE'
$       GOTO GET_COM_LOOP
$!
$ ERROR:
$       WRITE SYS$OUTPUT "You entered an invalid command."
$       GOTO GET_COM_LOOP
$!
$ END_LOOP:
$ WRITE SYS$OUTPUT "Directory ''F$DIRECTORY()' has been cleaned."
$
$ EXIT

13.6 Executing Command Procedures

To make a command procedure run, you must execute it. You can execute command procedures:

  • From within another command procedure
  • On remote nodes
  • As parameters or qualifiers to DCL commands
  • Interactively
  • As batch jobs
  • On disk and tape volumes

The following sections describe each of these methods.

13.6.1 Executing Command Procedures from Within Other Command Procedures

You can execute another command procedure from within a command procedure by including an execute procedure (@) command .

The following command procedure, WRITEDATE.COM, invokes the command procedure GETDATE.COM:


$! WRITEDATE.COM
$!
$ INQUIRE TIME "What is the current time in hh:mm format?"
$ @GETDATE [JONES.COM]GETDATE.COM

13.6.2 Executing Command Procedures on Remote Nodes

You can use the TYPE command to execute command procedures in the top-level directory of another account on a remote node. You can execute command procedures that:

  • Display the status of services in the local OpenVMS Cluster system that are not provided clusterwide
  • List the users logged in to the remote node

Enter the TYPE command followed by an access control string. Use the following format:


$ TYPE nodename"username password"::"TASK=command_procedure"

The variables username and password are the user name and password for the account on the remote node.

This command procedure displays the users logged in to the remote node on which the command procedure resides:


$!SHOWUSERS.COM
$!
$ IF F$MODE() .EQS. "NETWORK" THEN DEFINE/USER SYS$OUTPUT SYS$NET
$ SHOW USERS

In the following example, SHOWUSERS.COM is located in the top-level directory of BIRD's account on node ORIOLE, and the password is BOULDER. SHOWUSERS.COM executes the DCL command SHOW USERS on the remote node ORIOLE. The TYPE command displays the output from SHOWUSERS.COM on the local node; that is, on the terminal from which you enter the type command:


$ TYPE ORIOLE"BIRD BOULDER"::"TASK=SHOWUSERS"

             OpenVMS User Processes at 11-DEC-1999 17:20:13.30
    Total number of users = 4, number of processes = 4

 Username     Node           Interactive  Subprocess   Batch
 FLICKER      AUTOMA                 2         1
 ROBIN        FABLES                 1         2        1
 DOVE         MURMUR                 1
 DUCK         FABLES                 1         1

13.6.2.1 Security Note

Your password will be visible on your terminal when you use the TYPE command with an access control string. Take the appropriate security precautions as described in Chapter 18.

13.6.3 Executing Command Procedures with DCL Qualifiers or Parameters

You can create a command procedure that specifies DCL command parameters or qualifiers. This type of command procedure is useful when there is a set of parameters or qualifiers that you use frequently with one or more commands.

Enter the execute procedure command (@) in a command line where you would normally specify qualifiers or parameters.

This command procedure can be used to enter a set of qualifiers to the LINK command:


$! This command procedure contains command
$! qualifiers for the LINK command.
$!
/DEBUG/SYMBOL_TABLE/MAP/FULL/CROSS_REFERENCE

This command line links an object named SYNAPSE.OBJ, using the qualifiers specified in DEFLINK.COM:


$ LINK SYNAPSE@DEFLINK

This command procedure can be used to enter the parameters CHAP1.TXT, CHAP2.TXT, and CHAP3.TXT with a DCL command:


$! PARAM.COM
$! This command procedure contains a list of
$! parameters that can be used with commands.
$!
CHAP1, CHAP2, CHAP3

This command line specifies the command procedure PARAM in place of a list of parameters. In the following example, the parameters are the file names listed in PARAM.COM:


$ DIRECTORY/SIZE @PARAM

Note

When using the execute procedure command (@), the entire specified file is treated as command input by DCL.


Previous Next Contents Index