HP OpenVMS Systems Documentation
Guide to OpenVMS File Applications
Example 5-2 also shows the proper way to signal errors. The RAB$L_STS (completion status) field and the RAB$L_STV (additional status values) field of the FAB or RAB are used so that secondary completion information is displayed, if appropriate, by the LIB$SIGNAL or LIB$STOP routines.
The VAX MACRO program shown in Example 5-3 invokes the Parse service, determines whether a wildcard character or search list is present, and conditionally branches to a sequence of instructions that invoke the Search service followed by the Open service. The resultant string is displayed after the file is opened.
For more information about the LIB$ routines, see the OpenVMS RTL Library (LIB$) Manual.
The next example program uses the $PARSE and $SEARCH functions, demonstrates the use of C language's fopen function, and shows how you can mix RMS calls and C I/O calls.
Example 5-3 uses cc$rms_fab and cc$rms_nam to define the $FAB and $NAM control blocks and specify the arguments for the Parse, and Search services.
The program shows how to preprocess a file specification using the Parse and Search services. First, the program prompts the user for an input file specification that may contain wildcard characters. The program then searches each file that matches the file specification for the specified text string.
An application may also need to process either one file or many files,
depending on the file specification that the terminal user enters or
the logical name that is provided (if the program uses a logical name
in its file specification). Each of these cases is discussed in the
When only a single file needs to be processed, but more than one location for the file may need to be searched, you can usually find the file by specifying a file specification that contains a search list.
For example, consider the case of a directory that contains the file PAY.DAT and a backup copy of the file named PAY_BUP.DAT. You could specify a file name of PAY*.DAT in the file specification and invoke the Parse service once and the Search service once to locate either of the two files; this method will locate PAY.DAT before PAY_BUP.DAT.
A potential problem arises if the file PAY.DAT has been deleted or renamed. In this case, unless the program determines that the file specification is one of several that are acceptable, any file named PAY that has the file type .DAT could be accessed: for example, PAY_ACC.DAT. You can avoid such problems by defining a search list logical name that specifies a search for PAY.DAT and PAY_BUP.DAT. A search list named SEARCH could be defined as follows for the directory [SMITH]:
To locate the file, specify SEARCH as the primary file specification.
When the file locations to be searched reside in different directories of a directory tree, you can use the ellipsis wildcard character in the directory field to search all subdirectories. Alternatively, you could define a search list that searches for the file PAY.DAT in one directory, the same file name in a subdirectory, and PAY_BUP.DAT in any directory in the directory tree by using the following DEFINE command:
You use the file specification SEARCH:.DAT to locate the desired file. In this example, note that one of the search list file specifications contains wildcard characters. Wildcard characters can be used in a search list if they are needed, just as with any other logical names and file specifications. However, the Parse and Search services must be used to locate the correct file.
When you need to locate files in different directory trees (or top-level directories), include complete directory specifications in your search list definition. For example, to locate the file TEST_DATA.DAT in the device/directory combinations of DISK1:[SMITH], DISK2:[STATS], or DISK2:[SMITH] you could use the following command to define the search list TST:
You can also use search lists to locate files on different devices. To locate this file, you specify TST:TEST_DATA.DAT.
To find the same directory and the same file name on different devices, you could use the following command to define TST:
When you define the search list TST in this manner, you can locate the
file by using the search list to specify the device name. In this way,
you can use a single search list to locate files that would otherwise
require multiple file specifications, even if wildcard characters were
To process many files using a single file specification, you always need to use the Parse and Search services to locate the files.
The application requirements and the directory location of the files generally determine whether one or more search lists, wildcard characters, or search lists containing wildcard characters are used in the file specification. When files must be accessed in nonalphabetical order, use a search list.
To process multiple files using a single file specification, invoke the Parse service (or its equivalent) once to interpret the file specification and to create the file specification pattern to be searched. After the file specification is parsed, you can invoke the Search service to locate each file that matches the original file specification. In some cases, you can examine (or display) the resultant file specification string returned by the Search service to determine if you (or the interactive user) want to process (open) the file.
If you want to list all file specifications that match a particular file specification and let the terminal user choose each file to be processed, wildcard characters can be used safely, possibly in a search list that contains wildcard characters in one or more of its file specifications. To reduce the number of files that the user might choose to process, use a search list without wildcard characters or rely less on wildcard characters. For example, to locate all files in a directory tree on different devices with a file type of .DAT, you could define the search list TREE as follows:
The primary file specification that would be used for the Parse service would be TREE:*.DAT. A great number of files might match this.
For applications that will need to locate certain files, search lists with limited use of wildcard characters might be needed. Consider a file that contains a prefix of RESULTS followed by the date for which the data applies. You could use the file name RESULTS*JUN*.DAT to locate a record that was entered in the month of June by executing a Search service followed by an Open service for each file, reading all records until the correct one is found, and invoking the Close service after processing each file.
A search list should be used when a predefined group of files is
processed by a program that is not intended to be interactive. Using a
search list is particularly desirable if the files have unrelated file
names or if they are located on different directories or devices. A
search list also minimizes processing time by searching for a definite
group of files.
For general-purpose applications, when the user enters a file specification that may indicate one file or many files, there is a means of testing whether one file or many files are to be processed, or to explicitly disallow the use of wildcard characters for applications where only a single file should be processed. To test for wildcard characters or search lists, or both, invoke the Parse service and test the appropriate bits in the NAM$L_FNB or NAML$L_FNB field.
The presence of a wildcard character usually indicates that many files should be processed, depending on program conventions. If a search list is present, it may or may not indicate that only one file should be processed and a convention is needed for users of that program. Thus, by testing whether a wildcard is present, the program can either invoke the Parse service once and the Search service repeatedly for each file to be opened, or it can disallow wildcard characters and request that the file specification be reentered. In some cases, the program may need to disallow the use of a search list or allow one or many files to be accessed, depending upon application conventions.
If you want to disallow wildcard characters, invoke the Open service. The Open service fails when it encounters a wildcard character.
|Primary||If the device field is a logical name, RMS translates the logical device name to its component parts. The resulting device name may be a physical device name, a process-permanent file name, or another logical name.|
|Default||If the device field is a logical name, RMS translates it before defaults are applied. If any of the fields in the file specification from the previous step are missing, they are supplied from the corresponding fields in the translated default file specification, where applicable.|
|Related||If the device field is a logical name, RMS translates it and applies the default values before it uses the related file specification to add missing component fields. If fields contain wildcard characters, the wildcard characters remain in the fields. When RMS uses the related file specification to complete an output file specification, the file name field and the file type field are replaced by the corresponding related file specification fields, where applicable. For more information, including the use of multiple related file specifications, see Section 6.2.3.|
|If the device name is omitted, the device field and, optionally, the directory field accept the system logical name SYS$DISK. If RMS cannot translate the logical name SYS$DISK to a physical device name, an error occurs. If the directory field does not accept the logical name SYS$DISK, it accepts the name of the current process default directory.|
Primary, default, and related file specifications can use logical names. RMS translates the primary file specification before it applies defaults and missing components. RMS also translates the default file specification before using the default values. Finally, RMS translates the related file specification before it uses missing components supplied by the related file specification. If the file specification is still missing the device or directory name components, the process executing the program supplies default device and directory values.
The algorithm used in determining the appropriate translation is as follows:
if node name present then translate node name else if device name present then translate device name else if only file name present then translate file name
Table 6-2 shows the sequence in which defaults are applied to a file specification (primary file specification string) and the resulting file specification (resultant string). In Table 6-2, the program specifies the primary file specification string FILE, omitting all other components of the file specification. The default file specification string .DAT provides the file type component. The related file specification string does not provide any component strings, but the default device string (logically SYS$DISK) provides the device string DISK1: and the directory string, [INV_C], is provided by the default directory string. Finally, because the resultant string is used to specify a new file, RMS applies the version number 1 to complete the new file specification.
|String Name||String Applied||Expanded String|
|Primary file specification||FILE||FILE|
|Default file specification||.DAT||FILE.DAT;|
|Related file specification||None.||FILE.DAT;|
|Default device (SYS$DISK)||DISK1:||DISK1:FILE.DAT;|
RMS appends the version number to the expanded string to convert it into the resultant string. The resultant string is the resultant file specification that RMS uses to locate the file.
When coding the file specification information in a program, you can use the language keyword for the OPEN (or CREATE) statement. Then you use the FDL Editor to enter the file specification characteristics. Finally, you call the FDL$CREATE routine to create a file, or you call the FDL$PARSE routine and the FDL$RELEASE routine to open a file.
Consider a program that does not explicitly specify the device and directory in any of the file specifications and does not have a related file specification. RMS adds the current process default device and the current process default directory to the expanded string after it applies components provided by the default file specification. However, if the program looks for a data file that is not in the current process default device and directory, it does not find the file. In this case, the solution is to specify the data file's device and directory either in the primary file specification, the default file specification, or the related file specification.
The program-supplied file specifications can be specified using the methods summarized in the following chart:
|How You Can Specify It|
|Primary||Use the FDL attribute FILE_NAME; use the file name or the name following the FILE, FILE_ID, or FILENAME keywords in the OPEN statement in some high-level languages; or use the string pointed to by the FAB field FAB$L_FNA.|
|Default||Use the FDL attribute FILE DEFAULT_NAME; use the default file specification or the name following the DEFAULTNAME or DEFAULT_FILE_ID keyword in the OPEN statement in some high-level languages; or use the string pointed to by the FAB field FAB$L_DNA.|
|Related||Use the name block (NAM) pointed to by the NAM$L_RLF field; the related name block must specify the location of a file specification, which must be pointed to by the NAM field NAM$L_RSA.|
See the appropriate languages documentation for information about
language statements and their keywords. Consult the OpenVMS Record Management Utilities Reference Manual for
information about the FDL Editor, and refer to the OpenVMS Utility Routines Manual for
information about the FDL$PARSE and FDL$RELEASE routines. For detailed
information about RMS control blocks and services, see the
OpenVMS Record Management Services Reference Manual.
6.2 Understanding RMS Parsing
In the following text, the term expanded string buffer refers to the user-allocated buffer that is pointed to by the NAM block expanded string address field (NAM$L_ESA), by the NAML block short expanded string address field (NAML$L_ESA), or by the NAML block long expanded string address field (NAML$L_LONG_EXPAND).
As it processes each program-supplied file specification, RMS identifies each specification's component parts. Components present in the primary, default, or related, and process-default file specifications are used to form the expanded file specification. The expanded file specification can then be used to locate one or more files. If a name block (NAM or NAML) is present, and the address and size of the expanded string buffer are specified, the file specification is copied into the expanded string buffer.
Note that the Parse service operates differently from other services with regard to the expanded string. With the Parse service, the expanded string contains all wildcard characters present in the file specification. RMS does not generate the resultant string until the program invokes a related service, such as SYS$SEARCH, which uses the expanded string from the Parse service as input.
When you use a search list, the expanded string contains the first location to be searched. RMS stores internally the information that specifies the remaining search list equivalence strings. Note that the equivalence string from a $PARSE is not guaranteed to point to an actual file. As different file locations are examined, RMS updates the expanded string to reflect the current location, and the resultant string contains the actual file specification of the file.
With the Create, Display, Erase, Open, and Search services, defaults are applied to the expanded string to select the actual file used. The resultant string can be used by the program to indicate which file was located. When the file is located, the version number found (or created) is appended to the resultant file specification string (not the expanded file specification string). When a search list is used, the resultant string contains the file specification where the file was actually found.