C+ C NAME: C iOpenFile C PURPOSE: C Open statemenst for direct/sequential, formatted/unformatted files C (internal use only; called by bOpenFile) C CALLING SEQUENCE: function iOpenFile(iAct,cFile,nRecl) C INPUTS: (passed from bOpenFile) C iAct integer code passed from bOpenFile C cFile character*(*) fully qualified file name C nRecl integer record length in 4-byte longwords C (not always used; see PROCEDURE) C OUTPUTS: C iOpenFile integer logical unit number assigned by iGetLun C (=FIL__NOUNIT is open was unsuccessful) C nRecl integer on success, record length in longwords C on failure, input value is retained C INCLUDE: include 'dirspec.h' include 'openfile.h' C CALLS: C Say, bGetLun, iFreeLun, HOSInquire C PROCEDURE: C Isolates the Fortran open statements needed by bOpenFile. C C If a file is opened for direct access on an Intel PC, then the record length C must be explicitly added to the open statement. This is not needed on a VMS C computer. If an 'inquire by filename' is done on VMS then the record length C is returned in bytes. On Intel either 0 (MS-Fortran) is returned, or the C record length is not filled at all (i.e. the input value is retained; Absoft C Fortran). C C For the HELIOS files it is possible to determine the record length from the C file content (done by HOSInquire). C C On VMS the record length is determined by an 'inquire by file name' C For HELIOS files the record length is determined by HOSInquire C C VMS: C In the open command the record length should be specified in bytes for C formatted access and in words for unformatted access. C WARNING: C Do not add a call to iSearch to this function to check for the existence C of cFile. This may interfere with a wildcard search using iSearch in progress C in the calling procedure. C MODIFICATION HISTORY: C DEC-1995, Paul Hick (UCSD) C- integer iAct character cFile*(*) integer nRecl character cSay*9 /'iOpenFile'/ character cStatus*3 character cInt2Str*14 logical bRead logical bSeq logical bDir logical bFmt logical bUnfmt logical bNew logical bScratch logical bApp logical bGetLun logical bHOS logical bGetRecl logical bReclB logical bReturn if (cOpSys .ne. OS__DOS) call Say(cSay,'E','version','for wrong OS') if (.not. bGetLun(iOpenFile,cFile)) return ! No unit number available bNew = iand(iAct,OPN__NEW) .ne. 0 bScratch= iand(iAct,OPN__SCRATCH) .ne. 0 bRead = iand(iAct,OPN__READONLY) .ne. 0 bHOS = iand(iAct,OPN__HOS) .ne. 0 bReclB = iand(iAct,OPN__RECLBYTE) .ne. 0 !------- ! If bGetRecl is true just before returning, then an attempt is made to determine ! the record length by an inquire by logical unit on the succesfully opened file. bGetRecl= iand(iAct,OPN__RECLINQ) .ne. 0 cStatus = 'OLD' if (bNew ) cStatus = 'NEW' if (bScratch) cStatus = 'SCRATCH' !------- ! If any ways can be devised to obtain the record length from an existing file ! these can be inserted here. ! DOS: ! For a HELIOS file (set bHOS) the HOSInquire function may work. !------- ! iRecl will be used in the open statements to set the record length iRecl = 0 if (cStatus .eq. 'OLD') then if (bHOS) then call HOSInquire(cFile,iRecl) ! Determine record length for existing file if (bReclB) iRecl = 4*iRecl end if end if !------- ! If at this point still iRecl=0 then a positive input value of nRecl is assumed to be the ! record length in 4-byte longwords. If nRecl<=0 then iRecl remains zero !!!: this allows only ! open statements which do not require an explicit recordlength. if (iRecl .eq. 0 .and. nRecl .gt. 0) iRecl = nRecl ! Pick up input value !------- ! Record lengths on Windows are specified in bytes. Convert iRecl from longword to byte. if (.not. bReclB) iRecl = 4*iRecl bSeq = iand(iAct,OPN__SEQUENTIAL) .ne. 0 bApp = iand(iAct,OPN__APPEND ) .ne. 0 bDir = (iand(iAct,OPN__SEQUENTIAL) .eq. 0 .and. & iand(iAct,OPN__APPEND ) .eq. 0) .and. iRecl .gt. 0 bFmt = iand(iAct,OPN__FORMATTED ) .ne. 0 bUnfmt = iand(iAct,OPN__FORMATTED ) .eq. 0 ! Sanity checks if (bApp) then if (bNew .or. bScratch .or. bRead) then ! Append does not make much sense here bSeq = .TRUE. ! .. (for scratch files not even possible, I think) bApp = .FALSE. else bSeq = .FALSE. ! In case both OPN__SEQUENTIAL and OPN__APPEND are set end if end if bReturn = .FALSE. I = -1 ! Assume open error iU = iOpenFile if (bRead) then ! Open 'readonly', only happens if cStatus='OLD' !------- ! The keyword "readonly" works in VAX and Absoft Fortran ! The keyword "mode='READ'" should work in MS-Fortran ! Neither works in G77 Fortran. Don't know what does. if (bSeq) then if (bFmt) then ! Sequential access, formatted open (iU,iostat=I,file=cFile,status=cStatus,readonly) !open (iU,iostat=I,file=cFile,status=cStatus,mode='READ') else if (bUnfmt) then ! Sequential access unformatted open (iU,iostat=I,file=cFile,status=cStatus,readonly,form='UNFORMATTED') !open (iU,iostat=I,file=cFile,status=cStatus,mode='READ',form='UNFORMATTED') end if else if (bDir) then ! Implies iRecl > 0 if (bFmt) then ! Direct access, formatted open (iU,iostat=I,file=cFile,status=cStatus,readonly,access='DIRECT',recl=iRecl,form='FORMATTED') !open (iU,iostat=I,file=cFile,status=cStatus,mode='READ',access='DIRECT',recl=iRecl,form='FORMATTED') bReturn = .TRUE. else if (bUnfmt) then ! Direct access, unformatted open (iU,iostat=I,file=cFile,status=cStatus,readonly,access='DIRECT',recl=iRecl) !open (iU,iostat=I,file=cFile,status=cStatus,mode='READ',access='DIRECT',recl=iRecl) bReturn = .TRUE. end if end if else if (bNew .or. bScratch) then ! cStatus='NEW' or cStatus='SCRATCH' if (bSeq) then ! Absoft does NOT allow recl keyword for sequential files if (bFmt) then open (iU,iostat=I,file=cFile,status=cStatus) else if (bUnfmt) then open (iU,iostat=I,file=cFile,status=cStatus,form='UNFORMATTED') end if else if (bDir) then ! Absoft REQUIRES recl keyword for direct access files if (bFmt) then open (iU,iostat=I,file=cFile,status=cStatus,access='DIRECT',recl=iRecl,form='FORMATTED') bReturn = .TRUE. else if (bUnfmt) then ! DOS/UNIX require bytes open (iU,iostat=I,file=cFile,status=cStatus,access='DIRECT',recl=iRecl) bReturn = .TRUE. end if end if else ! cStatus='OLD' (but not readonly) if (bSeq) then ! Absoft does NOT allow recl keyword for sequential files if (bFmt) then open (iU,iostat=I,file=cFile,status=cStatus) else if (bUnfmt) then open (iU,iostat=I,file=cFile,status=cStatus,access='SEQUENTIAL',form='UNFORMATTED') end if else if (bApp) then ! Absoft does NOT allow recl keyword for append access files if (bFmt) then open (iU,iostat=I,file=cFile,status=cStatus,access='APPEND') else if (bUnfmt) then open (iU,iostat=I,file=cFile,status=cStatus,access='APPEND',form='UNFORMATTED') end if else if (bDir) then ! Absoft REQUIRES recl keyword for direct access files if (bFmt) then open (iU,iostat=I,file=cFile,status=cStatus,access='DIRECT',recl=iRecl,form='FORMATTED') bReturn = .TRUE. else if (bUnfmt) then ! DOS/UNIX require bytes open (iU,iostat=I,file=cFile,status=cStatus,access='DIRECT',recl=iRecl) bReturn = .TRUE. end if end if end if if (I .ne. 0) then iOpenFile = iFreeLun(iOpenFile) ! Sets iOpenFile=FIL__NOUNIT call Say(cSay,'W',cFile,'error status '//cInt2Str(I)) nRecl = 0 else if (bGetRecl) then inquire (iOpenFile,recl=nRecl) nRecl = nRecl/4 ! Bytes -> words else if (bReturn) then nRecl = iRecl/4 ! Bytes -> words end if ! iRecl was used to open the file return end