Branching

Branching means jumping from one place in a command procedure to another. Labels (described above) provide the destination for a branch.

There are four main ways to branch; GOTO, GOSUB, CALL, and certain other commands that allow branching when they encounter certain conditions. Each is described separately.

GOTO

The GOTO command branches directly to a label and causes execution to resume at that location. GOTO works in either direction, forward or backward, within the command procedure. Its format is as follows:

    $ GOTO label      ! branches directly to a label    $ IF condition THEN $ GOTO label   ! A conditional branch. 

The following example illustrates a label being used as the target of a GOTO command:

    $ !    $ ! This command procedure illustrates the use of GOTO and labels.  Notice    $ ! that when branching to a label, you do not terminate its name with a    $ ! colon.    $ !    $ goto SKIP_SOME_LINES    $ !    $ ! These intervening lines will not be executed due to the GOTO above.    $ ! The GOTO command will work in the reverse direction as well as forward.    $ !    $ show time  ! will not be executed.    $ directory  ! will not be executed.    $ !    $ SKIP_SOME_LINES:  ! execution resumes here.    $ !    $ ! The following lines will be executed:    $ !    $ show logical SYS$LOGIN    $ show device d    $ exit 

GOSUB

The GOSUB command is used in conjunction with RETURN to allow the execution of subroutines within a DCL command procedure. GOSUB transfers control to a label, where execution resumes. Execution continues until a RETURN command is encountered. RETURN causes control to be passed to the line following the most recently executed GOSUB command.

     $ !     $ ! This example shows the control flow of a GOSUB/RETURN pair.     $ !     $ write sys$output "This line is the FIRST one displayed."     $ !     $ gosub DEMO_SUBROUTINE     $ !     $ write sys$output "This line is the THIRD one displayed."     $ !     $ exit  ! This EXIT command is very important...     $ !     $ ! Without the EXIT command above, execution would continue     $ ! into the subroutine below.  DCL would only detect an error upon     $ ! reaching the RETURN command for which there had been no     $ ! corresponding GOSUB command.     $ !     $ DEMO_SUBROUTINE:     $ write sys$output "This line is the SECOND one displayed."     $ return 

CALL

The CALL command provides another method of calling subroutines within your procedures. CALL was added to DCL some years after GOSUB and is a more sophisticated method for calling subroutines. It allows parameters to be passed to the subroutine and allows subroutine output to be directed to a file.

To use CALL, you must declare a subroutine by placing a label into your procedure and marking it as the start of a subroutine. After the label, place the commands that make up the subroutine. Finally, end the subroutine by an EXIT command and then an ENDSUBROUTINE command:

    $ label: SUBROUTINE      .      . (commands)      .    $ EXIT    $ ENDSUBROUTINE 

Your subroutine may be declared before or after the CALL commands that invoke it.

To use the subroutine, use the CALL command, specifying any parameters you may wish to pass to the subroutine.

Within the subroutine, the symbol names P1 through P8 refer to the parameters passed by the CALL statement, not to the overall procedure parameters:

     $ CALL [/output=file] [param1, param2, ... param8] 

The following example illustrates the passing of parameters to a subroutine as well as redirecting subroutine output to a file:

     $ !     $ ! First, declare a subroutine.  It will not actually be executed     $ ! until a CALL statement references it.     $ !     $ SUB1: SUBROUTINE     $ write sys$output "''p1'"     $ EXIT     $ ENDSUBROUTINE     $ !     $ ! Now invoke the subroutine SUB1 twice.     $ ! The first time, its output will be displayed to     $ ! the terminal.  The second time, its output will be     $ ! written to the file SUB_EXAMPLE.TXT     $ !     $ call SUB1 "This is the first call"     $ !     $ call SUB1/output=sub_example.txt "This is the second call"     $ !     $ exit 

When executed, it produces the following output. Note that the second CALL statement directs output to the file SUB_EXAMPLE.TXT:

     $ @CALL     This is the first call     $ TYPE SUB_EXAMPLE.TXT     This is the second call 

Remember, using CALL results in a higher-numbered command level for the duration of the subroutine. Local symbols already in existence can be seen, but if you modify them, they will revert back to their original values at the end of the subroutine. Use global symbols if you must modify symbols from within subroutines.

Other DCL Commands That Branch

Certain DCL commands (e.g., OPEN, READ, WRITE, and CLOSE) have the ability to branch when they detect a certain condition. For example, OPEN can branch to a label if it is not able to open the requested file. READ can branch on reaching the end of the input file or on an error reading the record:

     $ !     $ ! This example shows the branching ability of certain DCL commands     $ !     $ records_read = 0     $ !     $ open/read infile payroll.txt /error=CANT_OPEN     $ READLOOP:     $   read infile inrecord /end=NO_MORE_DATA  ! reads the next record     $   records_read = records_read + 1         ! keep track of records read     $ goto READLOOP                             ! goes back for the next record     $ !     $ ! The following label will only be reached when the READ instruction     $ ! detects the end of the input file.     $ !     $ NO_MORE_DATA:     $ write sys$output "End of file reached. Records read: ''records_read'"     $ close infile     $ exit     $ !     $ ! The following label will only be reached if the file cannot be opened;     $ ! perhaps the file does not exist, or you have insufficient permissions     $ ! to open it.     $ !     $ CANT_OPEN:     $ !     $ ! Save the value of the OpenVMS reserved symbol $STATUS.  This contains     $ ! the reason for the failure.  See the section "handling errors," later,     $ ! for details.     $ !     $ savestat = $status     $ if (savestat .gt. %x10000000) then $ savestat = savestat - %x10000000     $ write sys$output "Cannot open input file, status: ''savestat':"     $ !     $ ! Use SAVESTAT with the exit command. This will generate an error message     $ ! appropriate to the exact error that occurred. The status code will     $ ! also be passed to the next higher command level.     $ !     $ exit savestat 

When executed, this procedure produces output like the following:

     $ @COUNT_RECORDS     End of file reached. Records read: 329 

Should an error occur, the error-handling capabilities built into the procedure will show you the cause of the problem:

     $ @COUNT_RECORDS     Cannot open input file, status: 98962:     %RMS-E-FNF, file not found 

The section entitled "Handling Errors" (discussed later) contains information about additional methods to detect errors and take appropriate action.

More Advanced IF Commands

The simple form of the IF command was introduced in Chapter 6, "The Digital Command Language." Within command procedures, more complex IF commands are available.

Command procedures allow blocks of multiple conditional commands by the use of IF, THEN, ELSE, and ENDIF. The following example illustrates several ways to execute lines of code based on the results of comparisons:

     $ !     $ ! To execute a single command if a condition     $ ! is true (at the DCL prompt or within a command     $ ! procedure):     $ !     $ IF expression THEN $ command     $ !     $ ! To branch to another location if a condition     $ ! is true (within command procedures only):     $ !     $ IF expression THEN $ GOTO label  ! See "Branching"     $ IF expression THEN $ GOSUB label ! See "Branching"     $ IF expression THEN $ CALL label  ! See "Branching"     $ !     $ ! To execute multiple commands if a condition     $ ! is true (available in command procedures only).     $ ! Indentation is optional, but shown for clarity:     $ !     $ IF expression     $ THEN     $   one or more commands...     $ ENDIF     $ !     $ ! To execute one set of commands if a condition     $ ! is true, and another if it is false (in command     $ ! procedures only):     $ !     $ IF expression     $ THEN     $   one or more commands...     $ ELSE     $   one or more commands...     $ ENDIF     $ ! 



Getting Started with OpenVMS(c) A Guide for New Users
Getting Started with OpenVMS: A Guide for New Users (HP Technologies)
ISBN: 1555582796
EAN: 2147483647
Year: 2005
Pages: 215

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net