HP OpenVMS Systems Documentation
OpenVMS User's Manual
14.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.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:
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.
14.7.4 Redirecting Error Messages
The following sections describe how to redirect error messages.
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:
126.96.36.199 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:
14.8 Reading and Writing Files (File I/O)
The basic steps in reading and writing files from command procedures are:
The following sections describe:
14.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:
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:
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 that is 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:
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:
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:
14.10 Writing to Files
To write to files, use the following procedure:
The following command procedure writes data to the new file STATS.DAT. If a file of that name exists, a new version is created.
14.10.1 Creating Files with Unique File Names
To create a file with a unique name, use the F$SEARCH lexical function to see if the name is already in the directory. (Refer to the lexical function descriptions in the OpenVMS DCL Dictionary for more information about F$SEARCH.)
This command procedure prompts the user for a file name, then uses the F$SEARCH lexical function to search the default directory for the name. If a file with that name already exists, control is passed to ERROR_1, the procedure prints the message "The file already exists" and control returns to the label GET_NAME. The procedure then prompts for another file name as shown in the following example:
When you specify data for the WRITE command, follow the rules for character string expressions described in Chapter 12. You can specify data in the following ways:
As you examine the example, note the following:
14.11.2 Using the /SYMBOL Qualifier
When the WRITE command writes a record, it positions the record pointer after the record just written. The WRITE command can write a record that is up to 2,048 bytes long.
Use the /SYMBOL qualifier to write a record if either of the following conditions exist:
Refer to the description of the WRITE command in the OpenVMS DCL Dictionary for
more information on writing long records.
You can use the WRITE command with the /UPDATE qualifier to change a
record rather than insert a new one. To use the /UPDATE qualifier, you
must open the file for both reading and writing.
Use the READ command to read a record and assign its contents to a symbol. You can use the READ command to read records that are less than or equal to 1,024 characters in length. To read data from a file, use the following procedure:
The following command procedure reads and processes each record in the file STATS.DAT. The procedure executes the READ command repeatedly until the end-of-file status is returned. Then, the procedure branches to the line labeled END_READ.
When you specify a symbol name for the READ command, the command
interpreter places the symbol name in the local symbol table for the
current command level. If you use the same symbol name for more than
one READ command, each READ command redefines the value of the symbol
name. For example, in the preceding example, the READ command reads a
new record from the input file (STATS.DAT) each time through the loop.
It then uses this record to redefine the value of the symbol RECORD.
When you read from files, you generally read and process each record until you reach the end of the file. By using the /END_OF_FILE qualifier with the READ command, you can construct a loop to read records from a file, process the records, and exit from the loop when you have finished reading all the records.
Note that the labels you specify for /END_OF_FILE qualifiers are subject to the same rules as labels specified for a GOTO command. (See Chapter 13 for more information on using the GOTO command.)
You should always use the /END_OF_FILE qualifier when you use the READ command in a loop. Otherwise, when the error condition indicating the end-of-file is returned by the OpenVMS Record Management Services (OpenVMS RMS), the command interpreter performs the error action specified by the current ON command. For example, OpenVMS RMS returns the error status %RMS-E-EOF. This causes a command procedure to exit unless the procedure has established its own error handling.