Document revision date: 19 July 1999
[Compaq] [Go to the documentation home page] [How to order documentation] [Help on this site] [How to contact us]
[OpenVMS documentation]

OpenVMS User's Manual


Previous Contents Index

16.4 Using Parameters to Pass Data to Nested Command Procedures

You can pass up to eight parameters to nested command procedures. The local symbols P1 to P8 in the nested procedure are not related to the local symbols P1 to P8 in the invoking procedure.

In the following example, DATA.COM invokes the nested command procedure NAME.COM:


$ ! DATA.COM 
$ @NAME 'P1' Joe Cooper 

If P1 in DATA.COM is the string Paul Cramer, which contains no quotation marks, it is passed to NAME.COM as two parameters. In NAME.COM, P1 to P8 are defined as follows:

If P1 in DATA.COM is "Paul Cramer" (quotation marks included), you can pass the value to NAME.COM as one parameter by enclosing P1 in three sets of quotation marks, as follows:


$ ! DATA.COM 
$ QUOTE = """ 
$ P1 = QUOTE + P1 + QUOTE 
$ @NAME 'P1' "Joe Cooper" 

In this example, P1 is Paul Cramer and P2 is Joe Cooper in the command procedure NAME.COM.

16.5 Prompting for Data

You can use the INQUIRE command (as described in Chapter 15) or the READ command to obtain data for command procedures interactively. Both commands prompt for input and assign the response to a symbol.

The READ command is different from the INQUIRE command in the following ways:
The INQUIRE command... The READ command...
Prompts for a value Prompts for a value
Reads the value from the terminal Reads the value from the source specified by the first parameter
Assigns the value to a symbol Assigns the value to the symbol named as the second parameter

The READ command accepts all characters typed on the terminal in response to the prompt, as an exact character string value (case, spaces, and tabs are preserved). If you omit the /PROMPT qualifier, the READ command displays Data: as the default prompt.

You can also write command procedures that can either accept parameters or prompt for user input if the required parameters are not specified.

In the following example, the command issues the prompt Filename: to the terminal, reads the response from the source specified by the logical name SYS$COMMAND (by default, the terminal), and assigns the response to the symbol FILE:


$ READ/PROMPT="Filename: "  SYS$COMMAND  FILE 

In the following example, if a file name is not specified when the procedure is invoked, the user is prompted for a file name:


$ ! Prompt for a file name if name 
$ ! is not passed as a parameter 
$ IF P1 .EQS. "" THEN INQUIRE P1 "Filename" 
$ COPY 'P1' DISK5:[RESERVED]*.* 
$ EXIT 

Note

If you submit a command procedure for execution as a batch job, DCL reads the value for a symbol specified in an INQUIRE command from the data line following the INQUIRE command. If you do not include a data line, the symbol is assigned a null value.

16.6 Using the SYS$INPUT Logical Name to Obtain Data

Commands, utilities, and other system images get their input from the source specified by the logical name SYS$INPUT, which is the default input stream. In a command procedure, SYS$INPUT is defined as the command procedure file; commands or images that require data look for data lines in the file. However, by redefining SYS$INPUT, you can provide data from your terminal or from a separate input file.

16.6.1 Redefining SYS$INPUT as Your Terminal

You can redefine SYS$INPUT to be your terminal. This enables images called from command procedures to obtain input interactively, rather than from data lines in command procedures.

Note that you must redefine SYS$INPUT to be your terminal if you want to use a DCL command or utility that requires interactive input in command procedures.

In the following example, the command procedure allows you to provide input interactively to the image CENSUS.EXE:


$ ! Execute CENSUS getting data from the terminal 
$ DEFINE/USER_MODE SYS$INPUT SYS$COMMAND 
$ RUN CENSUS 
$ EXIT 

The DEFINE/USER_MODE command temporarily redefines SYS$INPUT while CENSUS.EXE is running, so CENSUS.EXE obtains its input from the terminal. After CENSUS.EXE completes, SYS$INPUT reverts to its original definition (the command procedure file).

In the following example, the command procedure uses EVE as the text editor:


$ ! Obtain a list of your files 
$ DIRECTORY 
$ ! 
$ ! Get file name and invoke the EVE editor 
$ EDIT_LOOP: 
$      INQUIRE FILE "File to edit (Press Return to end)" 
$      IF FILE .EQS. "" THEN EXIT 
$      DEFINE/USER_MODE SYS$INPUT SYS$COMMAND 
$      EDIT/TPU 'FILE' 
$      GOTO EDIT_LOOP 

The command procedure prompts for file names until you terminate the loop by pressing the Return key. When you enter a file name, the procedure automatically invokes EVE to edit the file. While the editor is running, SYS$INPUT is defined as the terminal so you can enter your edits interactively.

16.6.2 Defining SYS$INPUT as a Separate File

A command procedure can also get input from a file by defining SYS$INPUT as a file. Note that DCL does not process data lines; command procedures pass text on data lines directly to commands or images. If you include DCL symbols or expressions on data lines, DCL will not substitute values for the symbols or evaluate the expressions. If you use an exclamation point (!) in a data line, the image to which you pass the data processes the exclamation point.

You can also place programs in the command procedure file by specifying the name of the data file as SYS$INPUT. This causes the compiler to read the program from the command procedure rather than from another file.

The following example shows a command procedure that contains a FORTRAN command followed by the program's statements:


$ FORTRAN/OBJECT=TESTER/LIST=TESTER SYS$INPUT 
C  THIS IS A TEST PROGRAM 
   A = 1 
   B = 2 
   STOP 
   END 
$ PRINT TESTER.LIS 
$ EXIT 

The FORTRAN command uses the logical name SYS$INPUT to identify the file to be compiled. Because SYS$INPUT equates to the command procedure, the FORTRAN compiler compiles the statements following the FORTRAN command (up to the next line that begins with a dollar sign). When the compilation completes, two output files are created: TESTER.OBJ and TESTER.LIS. The PRINT command then prints the file.

16.7 Performing Command Procedure Output

Output from command procedures such as data, error messages, and verification of command lines can be directed to either terminals or other files. The following methods of directing output are covered in this section:

16.7.1 Writing Data to Terminals

Use the TYPE command to display text that is several lines long and does not require symbol substitution. The TYPE command writes data from the file you specify to SYS$OUTPUT.

In the following example, SYS$INPUT is specified as the data file. The TYPE command reads data from the data lines that follow and displays the lines on the terminal:


$ ! Using TYPE to display lines 
$ TYPE SYS$INPUT 
REPORT BY MARY JONES 
PREPARED APRIL 15, 1995 
SUBJECT: Analysis of Tax Deductions for 1995 
   .
   .
   .
$ EXIT 

Use the WRITE command to write data that contains symbols or lexical functions. Unless you enclose the data in quotation marks (" "), the WRITE command performs symbol substitution automatically.

To use the WRITE command to display a character string as literal text, enclose the string in quotation marks (" "). For example:


$ WRITE SYS$OUTPUT "Two files are written." 
Two files are written. 

To include quotation marks in character strings, use two sets of quotation marks ("" ""). For example:


$ WRITE SYS$OUTPUT "Summary of ""Q & A"" Session" 
Summary of "Q & A" Session 

To continue a line of text on more than one line, concatenate the two strings with a plus sign (+) and a hyphen (-). For example:


$ WRITE SYS$OUTPUT "Report by Mary Jones" + - 
" Prepared April 15, 1996" 
Report by Mary Jones Prepared April 15, 1996 

The WRITE command performs symbol substitutions automatically and displays the values of symbols. To force symbol substitutions within character strings, enclose the symbol in apostrophes. For example:


$ AFILE = "STAT1.DAT" 
$ BFILE = "STAT2.DAT" 
$ WRITE SYS$OUTPUT "''AFILE' and ''BFILE' ready." 
STAT1.DAT and STAT2.DAT ready. 

In this example, STAT1.DAT is the translation of the symbol AFILE; STAT2.DAT is the translation of the symbol BFILE.

16.7.2 Redirecting Output from Commands and Images

Commands, utilities, and other system images write their output to the source specified by the logical name SYS$OUTPUT. By default, SYS$OUTPUT equates to the terminal. However, you can redirect the output in one of the following ways:

In the following example, the command procedure redirects the output from the SHOW USERS command to a file. The new definition for SYS$OUTPUT is in effect only for the execution of the SHOW USERS command:


$ DEFINE/USER_MODE SYS$OUTPUT SHOW_USER.DAT 
$ SHOW USERS 
$ ! 
$ ! Process the information in SHOW_USER.DAT 
$ OPEN/READ INFILE SHOW_USER.DAT 
$ READ INFILE RECORD 
   .
   .
   .
$ CLOSE INFILE 
$ EXIT 

In the following example, SYS$OUTPUT is defined as a null device (NL:).


$ DEFINE/USER_MODE SYS$OUTPUT NL: 
$ APPEND NEW_DATA.DAT STATS.DAT 
   .
   .
   .

The /USER_MODE qualifier is used to create a temporary logical name assignment that is in effect only until the next image completes. After the command executes, SYS$OUTPUT reverts to the default definition (usually the terminal).

You cannot use the DEFINE/USER_MODE command to redirect output from DCL commands that are executed within the command interpreter. Instead, use the DEFINE command to redefine SYS$OUTPUT and use the DEASSIGN command to delete the definition when you are through with it.

The following is a complete list of DCL commands that are performed within the command interpreter:
= ALLOCATE ASSIGN
ATTACH CALL CANCEL
CLOSE CONNECT CONTINUE
CREATE/LOGICAL_NAME_TABLE DEALLOCATE DEASSIGN
DEBUG DECK DEFINE
DEFINE/KEY DELETE/SYMBOL DISCONNECT
ELSE ENDIF ENDSUBROUTINE
EOD EXAMINE EXIT
GOSUB GOTO IF
INQUIRE ON OPEN
READ RECALL RETURN
SET CONTROL SET DEFAULT SET KEY
SET ON SET OUTPUT_RATE SET PROMPT
SET PROTECTION/DEFAULT SET SYMBOL/SCOPE SET UIC
SET VERIFY SHOW DEFAULT SHOW KEY
SHOW PROTECTION SHOW QUOTA SHOW STATUS
SHOW SYMBOL SHOW TIME SHOW TRANSLATION
SPAWN STOP SUBROUTINE
THEN WAIT WRITE

The following example shows the commands that would be used to redirect output from the SHOW TIME command to the file TIME.DAT. After you deassign SYS$OUTPUT, it reverts to the default definition (the terminal):


$ DEFINE SYS$OUTPUT TIME.DAT 
$ SHOW TIME 
$ DEASSIGN SYS$OUTPUT 

16.7.3 Returning Data from Command Procedures

Global symbols and logical names return data from a command procedure to a calling procedure or to DCL command level. You can read a global symbol or a logical name at any command level. Logical names can return data from a nested command procedure to the calling procedure.

The following example shows how a command procedure passes a value with a global symbol created with a global assignment statement:


$ @DATA "Paul Cramer" 
 
$ ! DATA.COM 
$ ! 
$ ! P1 is a full name. 
$ ! NAME.COM returns the last name in the 
$ ! global symbol LAST_NAME. 
$ ! 
$ @NAME 'P1' 
       $ ! NAME.COM 
       $ ! P1 is a first name 
       $ ! P2 is a last name 
       $ ! return P2 in the global symbol LAST_NAME 
       $ LAST_NAME == P2 
       $ EXIT 
$ ! write LAST_NAME to the terminal 
$ WRITE SYS$OUTPUT "LAST_NAME = ''LAST_NAME'" 
 
LAST_NAME = CRAMER 

DATA.COM invokes the command procedure NAME.COM, passing NAME.COM a full name. NAME.COM places the last name in the global symbol LAST_NAME. When NAME.COM completes, DCL continues executing DATA.COM, which reads the last name by specifying the global symbol LAST_NAME. The command procedure NAME.COM would be in a separate file. It is shown indented in this example for clarity.

In this command procedure, REPORT.COM obtains the file name for a report, equates the file name to the logical name REPORT_FILE, and executes a program that writes a report to REPORT_FILE:


$! Obtain the name of a file and then run 
$! REPORT.EXE to write a report to the file 
$! 
$ INQUIRE FILE "Name of report file" 
$ DEFINE/NOLOG REPORT_FILE 'FILE' 
$ RUN REPORT 
$ EXIT 

In the following example, the command procedure REPORT.COM is invoked from another procedure. The calling procedure uses the logical name REPORT_FILE to refer to the report file:


$! Command procedure that updates data files 
$! and optionally prepares reports 
$! 
$ UPDATE: 
   .
   .
   .
$   INQUIRE REPORT "Prepare a report [Y or N]" 
$   IF REPORT THEN GOTO REPORT_SEC 
$   EXIT 
$! 
$ REPORT_SEC: 
$   @REPORT 
$   WRITE SYS$OUTPUT "Report written to ", F$TRNLNM("REPORT_FILE") 
$   EXIT 

16.7.4 Redirecting Error Messages

The following sections describe how to redirect error messages.

16.7.4.1 Redefining SYS$ERROR

By default, command procedures send system error messages to the file indicated by SYS$ERROR. You can redefine SYS$ERROR to direct system error messages to a specified file. However, if you redefine SYS$ERROR to be different from SYS$OUTPUT (or if you redefine SYS$OUTPUT without also redefining SYS$ERROR), DCL commands and images that use standard system error display mechanisms send system error level and system severe level error messages to both SYS$ERROR and SYS$OUTPUT. Therefore, you receive these messages twice---once in the file indicated by the definition of SYS$ERROR and once in the file indicated by SYS$OUTPUT. Success, informational, and warning level messages are sent only to the file indicated by SYS$OUTPUT. If you want to suppress system error messages from a DCL command, be sure that neither SYS$ERROR nor SYS$OUTPUT is equated to the terminal.

If you run one of your own images from a command procedure and the image references SYS$ERROR, the image sends system error messages only to the file indicated by SYS$ERROR --- even if SYS$ERROR is different from SYS$OUTPUT. Only DCL commands and images that use standard system error display mechanisms send messages to both SYS$ERROR and SYS$OUTPUT when these files are different.

This command procedure accepts a directory name as a parameter, sets the default to that directory, and purges files in the directory. To suppress system error messages, the procedure temporarily defines SYS$ERROR and SYS$OUTPUT as the null device:


$ ! Purge files in a directory and suppress messages 
$ ! 
$ SET DEFAULT 'P1' 
$ ! Suppress messages 
$ ! 
$ DEFINE/USER_MODE SYS$ERROR NL: 
$ DEFINE/USER_MODE SYS$OUTPUT NL: 
$ PURGE 
$ EXIT 

16.7.4.2 Suppressing System Error Messages

You can also use the SET MESSAGE command to suppress system messages. By using the qualifiers /NOFACILITY, /NOIDENTIFICATION, /NOSEVERITY, or /NOTEXT, you can suppress the facility name, message identification, severity level, or the message text.

In the following example, the facility, identification, severity, and text messages are temporarily suppressed, until the second SET MESSAGE command is issued:


$ ! Purge files in a directory and suppress system messages 
$ ! 
$ SET DEFAULT 'P1' 
$ ! Suppress system messages 
$ ! 
$ SET MESSAGE/NOFACILITY - 
             /NOIDENTIFICATION - 
             /NOSEVERITY - 
             /NOTEXT 
$ PURGE 
$ SET MESSAGE/FACILITY - 
             /IDENTIFICATION - 
             /SEVERITY 
             /TEXT 
$ EXIT 

16.8 Reading and Writing Files (File I/O)

The basic steps in reading and writing files from command procedures are:
Step Action
1 Use the OPEN command to open files.

This assigns a logical name to the file and specifies whether the file is to be read, written, or both read and written. Subsequent READ, WRITE, and CLOSE commands use this logical name to refer to the file.

2 Use the READ or WRITE commands to read or write records to files.

Input and output to files is usually accomplished by designing a loop to read a record, process the record, and write the modified record to either the same file or to another file.

3 Use the CLOSE command to close files.

If you do not include the CLOSE command, files remain open until you log out.

Note

You do not have to open process-permanent files such as SYS$INPUT, SYS$OUTPUT, SYS$COMMAND, and SYS$ERROR explicitly to read or write to them because the system opens these files for you when you log in.

The following sections describe:

16.9 Using the OPEN Command

The OPEN command opens sequential, relative, or indexed sequential files. The files are opened as process-permanent; they remain open for the duration of your process unless you explicitly close them (with the CLOSE command). While the files are open, they are subject to OpenVMS RMS restrictions on using process-permanent files.

When you open a file, the OPEN command assigns a logical name (specified as the first parameter) to the file (specified as the second parameter) and places the name in the process logical name table. Subsequent READ, WRITE, and CLOSE commands use this logical name to refer to the file.

In the following example, the OPEN command assigns the logical name INFILE to the file DISK4:[MURPHY]STATS.DAT:


$ OPEN/READ INFILE DISK4:[MURPHY]STATS.DAT 

Note

The logical name in the OPEN command must be unique. If the OPEN command does not work and your commands seem correct, change the logical name in the OPEN command. To display a list of logical name definitions, use the SHOW LOGICAL command.

To ensure that the command procedure can access the correct files, use complete file specifications (for example, DISK4:[MURPHY]STATS.DAT) or use the SET DEFAULT command to specify the proper device and directory before you open a file.

You can also specify shareable files. The /SHARE qualifier enables other opened files. In addition, users can access shareable files with the DCL commands TYPE and SEARCH.

The OPEN/READ command opens the files, assigns logical names to the files, and places record pointers at the beginning of the files. When you open files for reading, you can read but not write records. Each time you read a record, the pointer moves to the next record.

The OPEN/READ command in this command procedure opens the file STATS.DAT and assigns the logical name INFILE to the file:


$   OPEN/READ INFILE DISK4:[MURPHY]STATS.DAT 
$ READ_FILE: 
$   READ/END_OF_FILE=DONE INFILE DATA 
$   GOTO READ_FILE 
$ DONE: 
$   CLOSE INFILE 
$   EXIT 

Use the OPEN/WRITE command when you want to write to a new file. The OPEN/WRITE command creates a sequential file in print file format. The record format for the file is variable with fixed control (VFC), with a 2-byte record header. The /WRITE qualifier cannot be used with the /APPEND qualifier.

If you specify a file that already exists, the OPEN/WRITE command opens a new file with a version number one greater than the existing file.

The command procedure in the following example creates a new file (NAMES.DAT) that can be used for writing:


$   OPEN/WRITE OUTFILE DISK4:[MURPHY]NAMES.DAT 
$ UPDATE: 
$   INQUIRE NEW_RECORD "Enter name" 
$   WRITE OUTFILE NEW_RECORD 
$   IF NEW_RECORD .EQS. "" THEN GOTO EXIT_CODE 
$   GOTO UPDATE 
$ EXIT_CODE: 
$   CLOSE OUTFILE 
$   EXIT 

The OPEN/APPEND command appends records to the end of an existing file. If you attempt to open a file that does not exist, an error occurs and the file is not opened. The /APPEND qualifier cannot be used with the /WRITE qualifier.

In the following example, records are appended to the end of an existing file, NAMES.DAT:


$ OPEN/APPEND OUTFILE DISK4:[MURPHY]NAMES.DAT 
$ INQUIRE NEW_RECORD "Enter name" 
$ WRITE OUTFILE NEW_RECORD 
   .
   .
   .
$ CLOSE OUTFILE 

The OPEN/READ/WRITE command places the record pointer at the beginning of a file so you can read the first record. When you use this method to open a file, you can replace only the record you have read most recently; you cannot write new records to the end of the file. In addition, a revised record must be exactly the same size as the record being replaced.

In the following example, the record pointer is placed at the beginning of the file STATS.DAT so the first record can be read:


$ OPEN/READ/WRITE FILE DISK4:[MURPHY]STATS.DAT 


Previous Next Contents Index

  [Go to the documentation home page] [How to order documentation] [Help on this site] [How to contact us]  
  privacy and legal statement  
6489PRO_041.HTML