Document revision date: 15 July 2002 | |
Previous | Contents | Index |
The file name and file specification services, Parse and Search, are used for relatively complex operations such as processing wildcard characters.
Before you can perform operations on a file, you must establish a path to the file. You do this by specifying the file specification string address and size (FAB$L_FNA and FAB$B_FNS) fields (and possibly the default file specification string address and size fields) of the FAB to describe an ASCII string within the program. In this ASCII string, you can have a concatenation of the network node name; a logical or device name; the directory name; and the file name, type, and version number.
If a logical name is used, RMS translates the logical name into its equivalent file specification before it applies defaults to any missing components of the file specification. If the logical name is a search list logical name, RMS translates each element of the search list into an equivalent file specification before it applies defaults to that element. When using the Search service, a file specification that may contain a search list logical name must be handled as if wildcard characters were present in the file specification.
The Parse service is required prior to the Search service in order to examine the file specification for wildcard characters or a search list. If the file is found, the Parse service sets a NAM or NAML block bit that RMS uses internally and sets an appropriate value in the wildcard character context that is used as input by the Search service. The Parse service is invoked once, then the Search service is repetitively invoked as many times as there are files that match the original file specification.
If a wildcard is present, the Search service attempts to find all files that match the file specification. If an asterisk (*) is in the directory field, all directories on the specified device are searched for files that match the remaining file specification components. As with the use of wildcard characters, when a search list logical name is present, a single Parse service and multiple Search services return all files that match the file specification. With search lists, however, all list elements are searched for matching file specifications in the specified order without regard to uniqueness between the resulting file specifications. Search lists can be used in place of (or in addition to) wildcard characters to specify a more efficient search order, which can mean different combinations for the device, directory, file name, file type, and version number parts of a file specification. Search lists can also contain wildcard characters, if needed.
In summary, the Parse and Search services use a search list logical name very much like a wildcard. Unlike the case of opening a file, in which the first instance where the file is found successfully ends the use of additional search list file specifications, the Parse and Search services use all search list file specifications.
Example B-4 shows how the $PARSE and $SEARCH macros can be used in wildcard processing.
Example B-4 Wildcard Processing Using Parse and Search Services |
---|
.TITLE WILD ; ; Program to accept wildcard characters in input (partial) file ; specification and display full file specification. ; $NAMDEF ; NAM block definitions .PSECT DATA,NOEXE,WRT NAM_BLK: $NAM RSA=RES_STR,- ; Result buffer address RSS=NAM$C_MAXRSS,- ; Result buffer size ESA=EXP_STR,- ; Expanded buffer address ESS=NAM$C_MAXRSS ; Expanded buffer size FAB_BLK: $FAB FOP=NAM,- ; Use NAM block option NAM=NAM_BLK,- ; Pointer to NAM block FNA=INP_STR ; Addr of file name string EXP_STR: ; Expanded string buffer .BLKB NAM$C_MAXRSS RES_STR: ; Resultant string buffer .BLKB NAM$C_MAXRSS RES_STR_D: ; Resultant string descriptor .BLKL 1 .LONG RES_STR INP_STR: ; Input string buffer .BLKB NAM$C_MAXRSS INP_STR_D: ; Input string descriptor .LONG NAM$C_MAXRSS .LONG INP_STR INP_STR_LEN: ; Input string length .BLKL 1 PROMPT_D: ; User prompt string .ASCID /Please enter the file specification: / .PSECT CODE,EXE,NOWRT .ENTRY WILD,^M<> PUSHAB INP_STR_LEN ; Address for string length PUSHAB PROMPT_D ; Prompt string descriptor PUSHAB INP_STR_D ; String buffer descriptor CALLS #3,G^LIB$GET_INPUT ; Get input string value BLBC R0,EXIT ; Quit on error ; ; Store user input string and perform initial parse to ; set up RMS context for subsequent search. ; MOVB INP_STR_LEN, - ; Set string size FAB_BLK+FAB$B_FNS $PARSE FAB=FAB_BLK ; Parse the file spec BLBC R0,F_ERR ; Quit and signal on error ; ; Search until all possibilities are exhausted. ; SEARCH_LOOP: $SEARCH FAB=FAB_BLK ; Find next file BLBC R0,SRCHERR ; Any more? ; ; Print out the resultant string from the search operation ; MOVZBL NAM_BLK+NAM$B_RSL, - RES_STR_D ; Set string length PUSHAB RES_STR_D ; String descriptor CALLS #1,G^LIB$PUT_OUTPUT ; Output the result BLBC R0,EXIT ; Quit on error BRB SEARCH_LOOP ; Go for more SRCHERR: ; If error is "No more files", CMPL R0,#RMS$_NMF ; this is normal completion BEQL S_EXIT ; of the search loop. F_ERR: PUSHL FAB_BLK+FAB$L_STV ; Push STV and STS on stack PUSHL FAB_BLK+FAB$L_STS ; in reverse order CALLS #2, G^LIB$SIGNAL ; Signal error S_EXIT: MOVL #1,R0 ; Suppress "No More Files" EXIT: RET .END WILD |
This program is designed to locate all files corresponding to a partial file specification input. The program prompts the user for an input string, which can consist of a partial file specification, using the wildcard characters and/or any type of logical name, including a search list logical name. In many respects, this program emulates the DCL command DIRECTORY, which is discussed in the OpenVMS DCL Dictionary.
The program illustrates the use of the $PARSE and $SEARCH file name processing macros. Here is the program statement that invokes the Parse service for parsing the file name string:
$PARSE FAB=FAB_BLK |
Before invoking the Parse service ($PARSE macro), the program moves the input string length to the file name string (FAB$B_FNS) field. If the Parse service returns an error completion status, the program branches to the F_ERR error routine.
Assuming no error, the program searches the disk directories specified by the expanded string area address field in the NAM block (NAM$L_ESA) until all possible files conforming to the partial file specification input are found. Here is the program line that invokes the Search service:
$SEARCH FAB=FAB_BLK |
A status test is performed immediately after the $SEARCH macro. If an error is detected, the program branches to the SRCHERR label. If a no-more-files condition is detected, RMS returns the RMS$_NMF message to indicate that all files that match the specification have been found. (This error, however, is not signaled.)
This program contains two run-time library routines: LIB$GET_INPUT and
LIB$PUT_OUTPUT. The LIB$GET_INPUT routine inputs a record from the
current controlling input device, specified by SYS$INPUT, using the Get
service. The LIB$PUT_OUTPUT routine outputs a record (line) to the
current controlling output device, specified by SYS$OUTPUT, using the
Put service. Both routines are discussed in greater detail in the
OpenVMS RTL Library (LIB$) Manual.
B.3.5 Connecting and Disconnecting Record Streams
To associate or disassociate a file with one or more record streams, RMS provides the Connect and Disconnect services, which are invoked using the $CONNECT and $DISCONNECT macros.
Before reading and writing file records, the program must open (or create) the input and output files and then connect the files to the appropriate record streams by executing the $OPEN (or $CREATE) macro followed by the $CONNECT macro.
Closing a file implicitly disconnects the record stream. Use the Disconnect service to explicitly disconnect a record stream that is not to be used immediately. This keeps the file open but releases various data structures for use by other processes until your program needs the record stream.
Example B-5 shows a program in which a user-entered reply determines which key path is selected to access the indexed file created in Example B-3. The user-entered value determines the value specified for the RAB$B_KRF field. The RAB$B_KRF value is set before the connect operation occurs because this field is input to the Connect service.
Example B-5 Use of the Connect Service and Multiple Keys |
---|
.TITLE MULTIKEY ; REC_SIZE=128 .PSECT DATA NOEXE,LONG ; ** RMS DATA ** MODFAB: $FAB FNM=<DATA_OUTPUT.DAT>,- ; FAB file spec. FAC=<GET>,- ; Get access needed SHR=<GET, UPD, PUT>,- ; Allow Get, Update, Put MRS=REC_SIZE ; Specify record size MODRAB: $RAB FAB=MODFAB,- ; RAB; indicate FAB MBF=3,- ; Use 3 buffers UBF=REC_MODBUF,- ; Specify buffer USZ=REC_SIZE,- KRF=0 ; Primary is default key REC_START: .LONG REC_SIZE ; Record buffer .ADDRESS REC_MODBUF REC_MODBUF: .BLKB REC_SIZE ; TERMINAL I/O DATA ** MPRO0: .ASCID / / MPRO1: .ASCID /Enter list order: 1-by name, 2-by city, 3-by state, 9-end :/ ENTRYERR: .ASCID /* * Value entered must be 1, 2, 3, or 9. * */ ; REGANS: .LONG 1 .ADDRESS REGBUF REGBUF: .BLKB 1 ; DONE: .ASCID /Press RETURN to continue/ ; .PSECT CODE START: .WORD ^M<> INPUT: PUSHAL MPRO0 ; Get input PUSHAL MPRO1 ; Display prompt PUSHAL REGANS CALLS #3, G^LIB$GET_INPUT BLBC R0,FINIBR CMPB #^A/1/,REGBUF ; Test value of menu answer BEQLU PRIM ; 1 means primary CMPB #^A/2/,REGBUF ; Continue testing BEQLU ALT1 ; 2 means first alternate CMPB #^A/3/,REGBUF ; Continue testing BEQLU ALT2 ; 3 means second alternate CMPB #^A/9/,REGBUF ; Continue testing BEQLU FINIBR ; 9 means end program BADANS: PUSHAL ENTRYERR ; otherwise, display error message CALLS #1, G^LIB$PUT_OUTPUT BLBC R0,FINIBR BRB INPUT ; Entry error; retry FINIBR: BRW FINI ; branch extender PRIM: MOVB #0,MODRAB+RAB$B_KRF ; Set key of reference in RAB BRB OPEN ALT1: MOVB #1,MODRAB+RAB$B_KRF ; Set key of reference in RAB BRB OPEN ALT2: MOVB #2,MODRAB+RAB$B_KRF ; Set key of reference in RAB OPEN: $OPEN FAB=MODFAB ; Open file BLBS R0,CONN BRW ERROR_OPEN CONN: $CONNECT RAB=MODRAB ; Connect record stream BLBS R0,NEXT BRW ERROR NEXT: $GET RAB=MODRAB ; Get record CMPL #RMS$_EOF,R0 ; Test if EOF BEQLU CLEAN BLBC R0,ERROR MOVZWL RAB$W_USZ+MODRAB,REC_START ; Set ASCII descriptor length PUSHAL REC_START ; Display each record CALLS #1, G^LIB$PUT_OUTPUT BLBS R0,NEXT BRB FINI ; Repeat until EOF CLEAN: $CLOSE FAB=MODFAB ; Close file BLBC R0,ERROR_OPEN PUSHAL MPRO0 CALLS #1, G^LIB$PUT_OUTPUT BLBC R0,FINI PUSHAL DONE PUSHAL REGANS CALLS #2, G^LIB$GET_INPUT BLBC R0,FINI BRW INPUT ; ERROR_OPEN: PUSHL MODFAB+FAB$L_STV ; Error opening PUSHL MODFAB+FAB$L_STS ; file. Signal error CALLS #2, G^LIB$SIGNAL ; using LIB$SIGNAL. BRB FINI ; End program ERROR: PUSHL MODRAB+RAB$L_STV ; Record-related error PUSHL MODRAB+RAB$L_STS CALLS #2, G^LIB$SIGNAL ; Signal error, then $CLOSE FAB=MODFAB ; close file FINI: RET .END START |
Here the SHR argument limits access to processes that perform the Get service, Put service, and Update service. If you anticipate no file modifications as your program accesses the file, you can improve performance by having the SHR argument limit access to processes that use the Get service (SHR=GET).
Errors are signaled according to the recommended practice of using the
FAB$L_STS and FAB$L_STV fields for file errors and RAB$L_STS and
RAB$L_STV fields for record errors.
B.3.6 Other File-Processing Operations
Other file services include the Display, Erase, Extend, Remove, and Rename services, which can be invoked using the $DISPLAY, $ERASE, $EXTEND, $REMOVE, and $RENAME macros, respectively.
Example B-6 illustrates the use of the Rename service to rename a file from directory [USER] named NAMES.DAT to directory [USER.HISTORY] named OLD_NAMES.DAT.
Example B-6 Use of the Rename Service |
---|
.TITLE RENAME ; ; Program that renames a file into a different directory and ; displays the resultant string. ; .PSECT DATA,NOEXE,WRT ; ; Define old FAB, old NAM, new FAB, new NAM, and buffers ; OLD_FAB: ; Define old file FAB $FAB FNM=<[USER]NAMES.DAT>,- NAM=OLD_NAM ; Pointer to NAM block OLD_NAM: ; Define old file NAM $NAM ESA=EXP_OLD,- ; Equivalence string ESS=NAM$C_MAXRSS,- ; address and size RSA=RES_OLD,- ; Resultant string RSS=NAM$C_MAXRSS ; address and size NEW_FAB: ; Define new file FAB $FAB FNM=<[USER.HISTORY]OLD_NAMES.DAT>,- NAM=NEW_NAM ; Pointer to NAM block NEW_NAM: $NAM ESA=EXP_NEW,- ; Equivalence string ESS=NAM$C_MAXRSS,- ; address and size RSA=RES_NEW,- ; Resultant string RSS=NAM$C_MAXRSS ; address and size EXP_OLD: ; Old file equivalence .BLKB NAM$C_MAXRSS ; string buffer EXP_NEW: ; New file equivalence .BLKB NAM$C_MAXRSS ; string buffer RES_OLD: ; Old file resultant .BLKB NAM$C_MAXRSS ; string buffer RES_OLD_D: ; String descriptor .BLKL 1 .LONG RES_OLD RES_NEW: ; New file resultant .BLKB NAM$C_MAXRSS ; string buffer RES_NEW_D: ; String descriptor .BLKL 1 .LONG RES_NEW ; MESS: .ASCID /has been successfully relocated to / ; .PSECT CODE,EXE,NOWRT .ENTRY RENAME,^M<> ; Rename file ; $RENAME OLDFAB=OLD_FAB, NEWFAB=NEW_FAB BLBC R0,ERROR ; Set up descriptors ; MOVZBL OLD_NAM+NAM$B_RSL,RES_OLD_D MOVZBL NEW_NAM+NAM$B_RSL,RES_NEW_D ; PUSHAL RES_OLD_D ; Push resultant name, CALLS #1,G^LIB$PUT_OUTPUT ; display old file spec. BLBC R0,TERM_ERROR ; Branch on error PUSHAL MESS ; Push message on stack, CALLS #1,G^LIB$PUT_OUTPUT ; display message BLBC R0,TERM_ERROR ; Branch on error PUSHAL RES_NEW_D ; Push resultant name, CALLS #1,G^LIB$PUT_OUTPUT ; display new file spec. BLBS R0,DONE ; Branch on success TERM_ERROR: PUSHL R0 ; Signal output error CALLS #1,G^LIB$SIGNAL ; from R0 BRB DONE ERROR: PUSHL OLD_FAB+FAB$L_STV ; Push STV and STS on PUSHL OLD_FAB+FAB$L_STS ; stack (reverse order) CALLS #2,G^LIB$SIGNAL ; Signal error DONE: RET .END RENAME |
This program uses the Rename service to change both the directory and
the name of the object file, which is being replaced by a new file
(created by a separate program). If the Rename service executes
correctly, the resultant
file specification of the old file, the message defined by the ASCII
descriptor following the label MESS, and the resultant file
specification of the new file are displayed as verification that the
Rename service successfully completed.
B.3.7 Retrieving and Inserting Records
The record-processing services provided by RMS insert records into a file and retrieve records from a file. These services are the Find, Get, and Put services, which can be invoked by the $FIND, $GET, and $PUT macros, respectively.
Example B-7 illustrates the use of the $GET and $PUT macros. It connects the input and output record streams, reads a record from an indexed file, and writes the record to a relative file. The program illustrates the use of the key string buffer, the key string descriptor, and the key string length when reading indexed records, and it includes the use of a user prompt string.
Example B-7 Use of the Get and Put Services |
---|
.TITLE LOOKUP ; ; This program looks up records in the input file and ; writes the records to the output file. .PSECT DATA,WRT,NOEXE INFAB: $FAB FNM = <INFILE:>,- ; Input file logical name SHR = <GET,PUT,UPD,DEL> ; Allow read/write sharing INRAB: $RAB FAB = INFAB,- ; Pointer to FAB KBF = INP_STR,- ; Key buffer KRF = 0,- ; Primary key RAC = KEY,- ; Keyed access ROP = WAT,- ; Wait for record UBF = REC_BUFF,- ; Record buffer USZ = REC_SIZE ; and size OUTFAB: $FAB FNM = <OUTFILE:>,- ; Output file logical name BKS = 3,- ; 3 blocks per bucket MRS = REC_SIZE,- ; Maximum record size ORG = REL,- ; Relative file RAT = CR ; Implied carriage control OUTRAB: $RAB FAB = OUTFAB,- ; Pointer to FAB RBF = REC_BUFF ; Output uses same buffer ; as input REC_SIZE = 132 ; Maximum size records REC_BUFF: .BLKB REC_SIZE ; Record buffer INP_STR: ; Key string buffer .BLKB REC_SIZE INP_STR_D: ; Key string descriptor .LONG REC_SIZE .LONG INP_STR INP_STR_LEN: ; Key string length .BLKL 1 PROMPT_D: ; User prompt string .ASCID /Please input key value: / .PSECT CODE,NOWRT,EXE ; ; Initialization - Open input and output files and connect streams ; .ENTRY LOOKUP,^M<> ; No registers to save $OPEN FAB=INFAB ; Open input file BLBC R0,EXIT1 ; Quit on error $CONNECT RAB=INRAB ; Connect to input BLBC R0,EXIT2 ; Quit on error $CREATE FAB=OUTFAB ; Create output file BLBC R0,EXIT3 ; Quit on error $CONNECT RAB=OUTRAB ; Connect to output BLBC R0,EXIT4 ; Quit on error BRB READ ; Skip error branching EXIT1: MOVAL INFAB, R6 ; Keep INFAB address BRW F_ERR ; Signal FAB error EXIT2: MOVAL INRAB, R6 ; Keep INRAB address BRW R_ERR ; Signal RAB error EXIT3: MOVAL OUTFAB, R6 ; Keep OUTFAB address BRB F_ERR ; Signal FAB error EXIT4: MOVAL OUTRAB, R6 ; Keep OUTRAB address BRB R_ERR ; Signal RAB error ; ; Loop to copy records ; READ: PUSHAB INP_STR_LEN ; Address for string length PUSHAB PROMPT_D ; Prompt string descriptor PUSHAB INP_STR_D ; String buffer descriptor CALLS #3,G^LIB$GET_INPUT ; Get input string value BLBS R0,GET ; Quit on error or end-of-file CMPL R0,#RMS$_EOF ; Was error end-of-file? BEQL DONE ; Successful completion BRB EXIT ; Error otherwise GET: MOVB INP_STR_LEN, - ; Set key size INRAB+RAB$B_KSZ $GET RAB=INRAB ; Get a record BLBS R0,PUT ; Put if successful CMPL R0,#RMS$_RNF ; No such record? BEQL READ ; Try again BRB EXIT2 ; Error otherwise PUT: MOVW INRAB+RAB$W_RSZ, - ; Set the record size OUTRAB+RAB$W_RSZ ; for output $PUT RAB=OUTRAB ; Write the record BLBC R0,EXIT4 ; Quit on error BRB READ ; Go back for more ; ; Close files and exit ; F_ERR: PUSHL FAB$L_STV(R6) ; Push STV and STS on PUSHL FAB$L_STS(R6) ; stack in reverse order CALLS #2, G^LIB$SIGNAL ; Signal message BRB EXIT R_ERR: PUSHL RAB$L_STV(R6) ; Push STV and STS on PUSHL RAB$L_STS(R6) ; stack in reverse order CALLS #2, G^LIB$SIGNAL ; Signal message DONE: $CLOSE FAB=INFAB ; Close input $CLOSE FAB=OUTFAB ; and output EXIT: RET ; Return with status in R0 .END LOOKUP |
This program writes records from an existing indexed input file into a newly created relative output file.
The program configures the file-sharing field (FAB$B_SHR) in the input FAB to permit sharing of the file by processes that use the Get, Put, Update, and Delete services.
The output FAB sets the bucket size field (FAB$B_BKS) at 3 blocks per bucket, limits the record size in the output file to 132 bytes, specifies the relative file organization, and specifies an implicit carriage control when the file output is directed to a terminal.
The RAB for the input file establishes the key data, sets the WAIT record option, and defines the record buffer. The output RAB locates the record buffer. The rest of the first program section assigns values and allocates space to various program variables. After the program opens and creates the two files and connects the record streams, it executes a series of instructions at label READ that input the required key values and the user prompt. Then the program uses the $GET and $PUT macros to invoke the respective services for retrieving and inserting the records. The $GET macro uses the INRAB and the $PUT macro uses the OUTRAB, as shown in the following program statements:
$GET RAB=INRAB $PUT RAB=OUTRAB |
Each time the program reads or writes a record, it performs a status check. If the status check is successful, the program branches back to the READ label for the next record. If any of the status checks indicate an error, the program branches to the appropriate error handler before exiting.
When the program completes the record transfers, it branches to the DONE label to close the record and exit.
Previous | Next | Contents | Index |
privacy and legal statement | ||
4523PRO_041.HTML |