CACK_OOPS_!@#$%^&*()*&^%$#@!_SPOO_KCAC IOPEN.FOR 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 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 cSeq*7 character cDir*7 character cFmt*7 character cUnfmt*7 character cStatus*3 character cInt2Str*14 character cSay*9 /'iOpenFile'/ logical bRead logical bSeq logical bDir logical bFmt logical bUnfmt logical bNew logical bScratch logical bApp logical bGetLun logical bHOS logical bGetRecl if (cOpSys .ne. OS__VMS) 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 cStatus = 'OLD' if (bNew ) cStatus = 'NEW' if (bScratch) cStatus = 'SCRATCH' cSeq = 'YES' cDir = 'YES' cFmt = 'YES' cUnfmt = 'YES' !------- ! If any ways can be devised to obtain the record length from an existing file ! these can be inserted here. ! VMS: ! For binary files an inquire by name can be used ! The inquire call is triggered by setting bHOS (Helios files), or by ! explicitly setting nRecl to a negative number. !------- ! iRecl will be used in the open statements to set the record length iRecl = 0 if (cStatus .eq. 'OLD') then if (bHOS .or. nRecl .lt. 0) then ! Open existing file on VMS inquire (file=cFile, ! MS and Absoft FORTRAN return UNKNOWN & sequential = cSeq, direct = cDir, & formatted = cFmt, unformatted = cUnfmt, & recl = iRecl) ! Record length in bytes (VMS only) iRecl = iRecl/4 ! Convert to longword nRecl = 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 bSeq = iand(iAct,OPN__SEQUENTIAL) .ne. 0 .and. cSeq .eq. 'YES' bApp = iand(iAct,OPN__APPEND ) .ne. 0 .and. cSeq .eq. 'YES' bDir = (iand(iAct,OPN__SEQUENTIAL) .eq. 0 .and. & iand(iAct,OPN__APPEND ) .eq. 0) .and. cDir .eq. 'YES' .and. iRecl .gt. 0 bFmt = iand(iAct,OPN__FORMATTED ) .ne. 0 .and. cFmt .eq. 'YES' bUnfmt = iand(iAct,OPN__FORMATTED ) .eq. 0 .and. cUnfmt .eq. 'YES' ! 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 !------- ! 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. ! This can be suppressed by setting bGetRecl=.FALSE. here, or later. bGetRecl = .TRUE. I = -1 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) else if (bUnfmt) then ! Sequential access unformatted open (iU,iostat=I,file=cFile,status=cStatus,readonly,form='UNFORMATTED') end if else if (bDir) then if (bFmt) then ! Direct access, formatted open (iU,iostat=I,file=cFile,status=cStatus,readonly,access='DIRECT',form='FORMATTED',recl=4*iRecl) else if (bUnfmt) then ! Direct access, unformatted open (iU,iostat=I,file=cFile,status=cStatus,readonly,access='DIRECT',recl=iRecl) end if end if else if (bNew .or. bScratch) then ! cStatus='NEW' or cStatus='SCRATCH' if (bSeq) then if (bFmt) then ! Formatted: recl in bytes open (iU,iostat=I,file=cFile,status=cStatus,carriagecontrol='LIST',recl=4*iRecl) else if (bUnfmt) then ! Unformatted: recl in longwords !open (iU,iostat=I,file=cFile,status=cStatus,form='UNFORMATTED',recordtype='FIXED',recl=iRecl) open (iU,iostat=I,file=cFile,status=cStatus,form='UNFORMATTED',recl=iRecl) end if else if (bDir) then if (bFmt) then open (iU,iostat=I,file=cFile,status=cStatus,access='DIRECT',form='FORMATTED',recl=4*iRecl) else if (bUnfmt) then open (iU,iostat=I,file=cFile,status=cStatus,access='DIRECT',recl=iRecl) end if end if else ! cStatus='OLD' (but not readonly) if (bSeq) then 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')!,recl=iRecl) end if else if (bApp) then 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')!,recl=iRecl) end if else if (bDir) then if (bFmt) then open (iU,iostat=I,file=cFile,status=cStatus,access='DIRECT',form='FORMATTED')!,recl=4*iRecl) else if (bUnfmt) then open (iU,iostat=I,file=cFile,status=cStatus,access='DIRECT')!,recl=iRecl) 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)) else if (bGetRecl) then inquire (iOpenFile,recl=nRecl) if (bFmt) nRecl = nRecl/4 ! Bytes -> words end if return end