.TITLE VTLOPE - Open Files for Read/Write .IDENT /1.3/ .ENABL LC ;+ ; ; Free software BY ; Project Software & Development, Inc. ; ; This software is furnished for free and may be used and copied as ; desired. This software or any other copies thereof may be provided ; or otherwise made available to any other person. No title to and ; ownership of the software is hereby transferred or allowed. ; ; The information in this software is subject to change without notice ; and should not be construed as a commitment by PROJECT SOFTWARE ; AND DEVELOPMENT, INC. ; ; PROJECT SOFTWARE assumes no responsibility for the use or reliability ; of this software on any equipment whatsoever. ; ; Project Software & Development, Inc. ; 14 Story St. ; Cambridge, Ma. 02138 ; 617-661-1444 ; ; ; Title: VTLOPE ; Author: Robin Miller ; Date: August 9, 1983 ; ; Description: ; ; This module is called to open a file for read or write. It ; does all the neccessary syntax checking using the CSI routines, parsing ; of the file specification, and opening of the file. It presumes the FDB ; is setup with all the required information such as the LUN, the EFN, the ; record attributes, and the access mode. ; ; Modification History: ; ; October 4, 1984 by Robin Miller. Version 1.3 ; Save the radix-50 file name and file type in the default file ; name block when listing multiple file specifications (SETDNB). ; ; August 31, 1984 by Robin Miler. Version 1.2 ; Save the Radix-50 file name and type if doing wildcarding so ; succeeding file lookups can be done. Added SVNAME and RSNAME. ; ; June 7, 1984 by Robin Miller. Version 1.1 ; Globalize CHKCSI and add routine DOCSI2 to use these routines for ; parsing a VMS file specification. This allows mulitiple file ; names to be specified separated by commas (i.e., A.DAT,B.DAT). ; ;- .ENABL AMA ; DEBUG = 0 ; Define for DDT debugging. .MCALL CSI$, CLOSE$, FCSBT$, FDOFF$, NBOFF$ ; Bit and offset definitions: CSI$ ; Define the CSI offsets. .IF NDF DEBUG FCSBT$ ; Define the FCS bits locally. FDOFF$ DEF$L ; Define the FDB offsets locally. NBOFF$ DEF$L ; Define the FNB offsets locally. .IFF FCSBT$ DEF$G ; Define the FCS bits globally. FDOFF$ DEF$G ; Define the FDB offsets globally. NBOFF$ DEF$G ; Define the FNB offsets globally. .ENDC ; .IF NDF DEBUG ; Define offsets for the dataset descriptor block: N.DEVD == 0 ; The device name descriptor. N.DIRD == 4 ; The directory descriptor. N.FILD == 10 ; The file name descriptor. .SBTTL Command String Interpreter (CSI) block. ; ; Scratch storage for wild UIC logic consists of a file name block ; followed by the following extra words. Also defined in PARSE.MAC. ; ; N.WNM1 = S.FNB ; 2 words for RAD50 non wild card ; ; project or programmer name. ; N.WNM2 = N.WNM1+4 ; 6 words of string storage for ; ; ASCII form of current directory name. S.WUIC = S.FNB+16. ; NO. OF BYTES IN SCRATCH AREA NB.SFL = NB.SD1!NB.SD2!NB.SNM!NB.STP!NB.SVR ; All wildcard bits. INCSI1::.BLKB C.SIZE ; CSI buffer for INCSI2::.BLKB C.SIZE ; two input files OUTCSI::.BLKB C.SIZE ; & one output file. INFNB1::.BLKB S.FNB+S.WUIC ; FNB for wildcard UIC's INFNB2::.BLKB S.FNB+S.WUIC ; for two inpur files. INDSD1::.BLKW 6 ; Wildcard dataset descriptor INDSD2::.BLKW 6 ; for two input files. .SBTTL OPEN - Open a file for read or write access. ;+ ; ; OPEN - Open a file for read or write access. ; ; This routine is used to open a single file for either read or write. If ; the file is already open on entry, it will be closed automatically. If ; the file access offset (F.FACC) in the FDB is not setup, it will be filled ; with either shared read (FO.RD!FA.SHA) or write without supercede ; (FO.WRT!FA.NSP). The Command String Interpreter (CSI) routines are used ; to check for syntax errors. If no error is returned from the CSI routines, ; then the file is openned for either read or write. ; ; The error code IE.BNM (bad file name) is returned if errors are encountered ; by the CSI routines. ; ; Inputs: ; R0 = The FDB address. ; R1 = The file specification address. ; R5 = The file entry address. ; ; Outputs: ; C bit clear/set = success/failure. ; All registers are preserved. ; ;- OPENR:: TSTB F.FACC(R0) ; Is the file access setup ? BNE OPEN ; If NE, yes. MOVB #FO.RD!FA.SHR,F.FACC(R0) ; No, setup for shared read. BR OPEN ; Continue ... OPENW:: TSTB F.FACC(R0) ; Is the file access setup ? BNE OPEN ; If NE, yes. MOVB #FO.WRT!FA.NSP,F.FACC(R0) ; No, setup for write/no supercede. .ENABL LSB OPEN: CALL $SAVAL ; Save all registers. CALL CKOPEN ; If the file is open, close it. CALL CLNAME ; Clear the file name from the FNB. CALL CHKCSI ; Check the command syntax. BCS 20$ ; If CS, illegal syntax. ; Parse the file name and open the file for read or write. AOPEN:: ; Alternate open entry point. MOV O.FNB(R5),R1 ; Copy the FNB address. MOV O.CSI(R5),R3 ; Copy the CSI block address. ; When opening files for a read operation, if no wildcards were ; specified we use the normal parsing, otherwise we use the ; wildcard parsing routine. BITB #CS.WLD,C.STAT(R3) ; Any wildcards in file specification ? BEQ 10$ ; If EQ, no (use normal parse). BITB #FO.RD,F.FACC(R0) ; Opening a file for read access ? BNE OPWILD ; If NE, yes (do wildcard parse). SEC ; Presume wildcards or mulitple files. BITB #CS.MOR!CS.WLD,C.STAT(R3) ; Wildcards or multiple files ? BNE 20$ ; If NE, yes (illegal for write). 10$: MOV F.DSPT(R0),R2 ; Address of dataset descriptor. MOV F.DFNB(R0),R3 ; Address of the default FNB. CALL .PARSE ; Parse the file specification. BCS 20$ ; If CS, we had an error. CALL .OPFNB ; Else, open the file for write. 20$: RETURN .DSABL LSB .SBTTL OPWILD - Setup for wildcard parsing. ;+ ; ; OPWILD - Setup for wildcard parsing. ; ; This routine is used to setup for wildcard parsing. The dataset descriptor ; pointed to by the FDB is first copied to the wildcard dataset descriptor. ; This is used when wildcards are specified in the project or programmer ; number (UIC). On subsequent calls to the OPNEXT routine, either the next ; file specification is returned, or the carry bit is set to indicate an FCS ; failure (only error expected is IE.NSF). ; ; Inputs: ; R0 = The FDB address. ; R1 = The FNB address. ; R5 = The file entry address. ; ; Outputs: ; C bit clear/set = success/failure. ; Presumes registers saved by OPEN routine. ; ;- OPWILD: MOV #6,R2 ; Size of the dataset descriptor. MOV F.DSPT(R0),R3 ; Addess of the dataset descriptor. MOV O.WDSD(R5),R4 ; Copy the wildcard dataset address. ; Copy the dataset descriptor to the wildcard descriptor. 10$: MOV (R3)+,(R4)+ ; Copy the dataset descriptor. SOB R2,10$ ; Loop until done. MOV O.WDSD(R5),R4 ; Restore the dataset address. MOV N.DIRD(R4),R2 ; Copy the directory string size. BEQ 30$ ; If EQ, none was specified. MOV N.DIRD+2(R4),R3 ; Copy the directory string address. MOV O.WFNB(R5),-(SP) ; Copy the wildcard FNB address. ADD #N.WNM2,(SP) ; Set address for directory string. MOV (SP),N.DIRD+2(R4) ; Save the new directory string addr. MOV (SP)+,R4 ; Address to store directory string. ; Copy the directory descriptor. 20$: MOVB (R3)+,(R4)+ ; Copy directory string to scratch. SOB R2,20$ ; Loop until done. 30$: MOV F.DSPT(R0),R2 ; Address of the dataset descriptor. MOV F.DFNB(R0),R3 ; Address of the default FNB. MOV O.WFNB(R5),R4 ; Copy the wildcard FNB address. CALL .WPARS ; Do the wildcard file parsing. BCS 40$ ; If CS, failure. CALL SVNAME ; Save the Radix-50 file name. MOV N.FVER(R1),O.WVER(R5) ; Save the original version number. BR OPNEXT ; Now go look up the first file. 40$: RETURN .SBTTL OPNEXT - Open the next wildcard file. ;+ ; ; OPNEXT - Alternate entry to open next file for wildcards. ; ; Inputs: ; R0 = The FDB address. ; R5 = The file entry address. ; ; Outputs: ; C bit clear/set = sucess/failure. ; ;- OPNEXT::CALL $SAVAL ; Save all registers. CALL CKOPEN ; If the file is open, close it. MOV O.FNB(R5),R1 ; Copy the FNB address. MOVB #IE.NSF,F.ERR(R0) ; Presume "No such file" error. BIT #NB.SFL,N.STAT(R1) ; Are there any wildcards ? BEQ 30$ ; If EQ, no (we're all done). CALL RSNAME ; Restore the Radix-50 file name. MOV O.WFNB(R5),R2 ; Copy the wildcard FNB address. MOV N.FVER(R1),N.FID+4(R1) ; Copy the old version number. MOV O.WVER(R5),N.FVER(R1) ; Restore original version number. CALL .FNDNX ; Go find the next file. BCS 20$ ; If CS, we failed. CALL .OPFNB ; Open the file for read access. RETURN ; ; On a "Privilege violation" error, we presume no access to the directory ; file (UFD). We don't clear the wildcard bits to allow a find of the ; next directory. ; 20$: ;*** I hope this doesn't hurt me. *** ;*** ;*** CMPB #IE.PRI,F.ERR(R0) ; Is error "Privilege violation" ? ;*** BEQ 30$ ; If EQ, yes (presume no UFD access). ;*** BIC #NB.SFL,N.STAT(R1) ; Disable all the wildcard bits. 30$: SEC ; Show failure. RETURN .SBTTL OPMORE - Open the next file specification. ;+ ; ; OPMORE - Open the next file specification. ; ; This routine is called when there is another file specification to be ; parsed. If parsed successfully, we open the file(s), otherwise failure ; status is returned. ; ; Inputs: ; R0 = The FDB address. ; R5 = The file entry address. ; ; Outputs: ; C bit set if syntax error from parsing. ; ; All registers are preserved. ; ;- OPMORE::CALL $SAVAL ; Save all registers. CALL SETDNB ; Setup the new default name block. CALL DOCSI2 ; Parse next file specification. BCS 10$ ; If CS, syntax error. JMP AOPEN ; Else, try to open the file(s). 10$: RETURN .SBTTL DOCSI2 - Call command semantic parser. ;+ ; ; DOCSI2 - Call the command semantic parser. ; ; Inputs: ; R0 = The FDB address. ; R5 = The file entry address. ; ; Outputs: ; C bit clear/set = success/failure. ; ; All registers are preserved. ; ;- DOCSI2::JSR R2,$SAVVR ; Save R0 - R2. CLR F.ERR(R0) ; Initialize the FCS error code. BISB #IE.BNM,F.ERR(R0) ; Preset to "Bad file name" error. MOV O.CSI(R5),R0 ; Copy the CSI block address. CALL .CSI2 ; Parse the file specification. RETURN .SBTTL CKOPEN - Check for open file. ;+ ; ; CKOPEN - Check for open file and close it if open. ; ; Inputs: ; R0 = The FDB address. ; ; Outputs: ; All registers are preserved. ; ;- CKOPEN: TST F.BDB(R0) ; Is the file already open ? BEQ 10$ ; If EQ, no. CLOSE$ R0 ; Yes, close it. 10$: RETURN .SBTTL CLNAME - Clear the file name in the FNB. ;+ ; ; CLNAME - Clear the file name in the FNB. ; ; This routine clears the file name (if any) in the FNB so that old file ; name information is not used when constructing an ASCII file name for ; error messages if a syntax error occurs in the CSI routines. ; ; Inputs: ; R0 = The FDB address. ; ; Outputs: ; All registers are preserved. ; ;- CLNAME: JSR R2,$SAVVR ; Save R0 - R2. ADD #F.FNB+N.FNAM,R0 ; Set address of the file name. MOV #5.,R1 ; Set size in words of file name. 10$: CLR (R0)+ ; Clear the file name. SOB R1,10$ ; And loop until done. RETURN .SBTTL CHKCSI - Check file name using CSI routines ;+ ; ; CHKCSI - Use CSI routines to check the filspc syntax. ; ; Inputs: ; R0 = The FDB address. ; R1 = File specification address. (terminated by NULL or ). ; R5 = The file entry address. ; ; Outputs: ; C bit clear/set = success/failure. ; All registers are preserved. ; ;- CHKCSI::CALL $SAVAL ; Save all registers. ;*** CLR F.DSPT(R0) ; Clear the dataset pointer. CLR F.ERR(R0) ; Initialize the FCS error code. BISB #IE.BNM,F.ERR(R0) ; Preset to "Bad file name" error. MOV O.CSI(R5),R3 ; Copy the CSI block address. MOV R3,F.DSPT(R0) ; Setup the dataset ADD #C.DSDS,F.DSPT(R0) ; descriptor address. ; Clear the CSI block so old information isn't used. MOV #C.SIZE/2,R2 ; SET THE CSI SIZE IN WORDS 10$: CLR (R3)+ ; CLEAR THE CSI BLOCK SOB R2,10$ ; BR UNTIL DONE MOV O.CSI(R5),R0 ; Set the CSI block address. MOV R1,C.CMLD+2(R0) ; Save the filspc address. ; Find the end of the file specification (either CR or NULL). 20$: CMPB (R1),#CR ; End of the file name ? BEQ 30$ ; If EQ, yes. TSTB (R1)+ ; End of the file name ? BNE 20$ ; If NE, nope (loop). DEC R1 ; Adjust for the null byte. ; Calculate the length of the file specification. 30$: SUB C.CMLD+2(R0),R1 ; Calculate the byte count. BEQ 50$ ; If EQ, don't do CSI parsing. MOV R1,C.CMLD(R0) ; Now save it. ; Check the syntax of the file specification. CALL .CSI1 ; Check the string syntax. BCS 60$ ; If CS, bad syntax. MOVB #CS.OUT,(R0) ; Set for output file parsing. CALL .CSI2 ; Parse the file specification. BCS 60$ ; If CS, syntax error. 50$: CLC ; Show success. RETURN 60$: SEC ; Show syntax error. RETURN .SBTTL RSNAME - Restore the Radix-50 file name. ;+ ; ; RSNAME - Restore the Radix-50 file name. ; ; Inputs: ; R1 = The FNB address. ; R5 = The file entry address. ; ; Outputs: ; All registers are preserved. ; ;- RSNAME::CALL $SAVAL ; Save all registers. ADD #N.FNAM,R1 ; Point to the file name. ADD #O.RNAM,R5 ; Point to area to save name. MOV #4,R0 ; Set the loop count. 10$: MOV (R5)+,(R1)+ ; Copy the radix-50 name/type. SOB R0,10$ ; Loop until we're done. RETURN .SBTTL SVNAME - Save the Radix-50 file name. ;+ ; ; SVNAME - Save the Radix-50 file name. ; ; This routine is used to save the file name block when doing special ; wildcard lookup (* and/or %). The file name block must be reset before ; doing the next wildcard lookup. ; ; Inputs: ; R1 = The FNB address. ; R5 = The file entry address. ; ; Outputs: ; All registers are preserved. ; ;- SVNAME::CALL $SAVAL ; Save all registers. ADD #N.FNAM,R1 ; Point to the file name. ADD #O.RNAM,R5 ; Point to area to save name. MOV #4,R0 ; Set the loop count. 10$: MOV (R1)+,(R5)+ ; Copy the radix-50 name/type. SOB R0,10$ ; Loop until we're done. RETURN .SBTTL SETDNB - Setup the default name block. ;+ ; ; SETDNB - Setup the default name block. ; ; This routine is used to copy the radix-50 file name and file type ; to the default file name block so that multiple file specifications ; will default properly (i.e., VTL.MAC, VTLNAM). ; ; Inputs: ; R0 = The FDB address. ; R5 = The file entry address. ; ; Outputs: ; All registers are preserved. ; ;- SETDNB: JSR R2,$SAVVR ; Save R0 - R2. MOV O.FNB(R5),R1 ; Copy file name block address. ADD #N.FNAM,R1 ; Point to the file name field. MOV F.DFNB(R0),R2 ; Copy default file name address. ADD #N.FNAM,R2 ; Point to the file name field. MOV #4,R0 ; Set the number of words to copy. 10$: MOV (R1)+,(R2)+ ; Copy the radix-50 name/type. SOB R0,10$ ; Loop until we're done. RETURN .END