VMEC 8.52
3D Equilibrium solver with nested flux surfaces.
Loading...
Searching...
No Matches
safe_open_mod.f
Go to the documentation of this file.
1
3
6!
7! Module for performing a "safe" open of a file for
8! a Fortran read/write operation. Makes sure the requested file
9! unit number is not in use, and increments it until an unused
10! unit is found
11!
12 CONTAINS
13
14 SUBROUTINE safe_open(iunit, istat, filename, filestat, &
15 & fileform, record_in, access_in, delim_in)
16!
17! Module for performing a "safe" open of a file for
18! a Fortran read/write operation. Makes sure the requested file
19! unit number is not in use, and increments it until an unused
20! unit is found
21!
22! Note that:
23! 1) the actual i/o unit number used is returned in the first argument.
24! 2) the status variable from the OPEN command is returned as the second
25! argument.
26
27! Here are some examples of usage:
28!
29! To open an existing namelist input file:
30! CALL safe_open(iou,istat,nli_file_name,'old','formatted')
31!
32! To create a file, in order to write to it:
33! CALL safe_open(iou,istat,my_output_file_name,'replace','formatted')
34!
35! To create an output file, with 'NONE' as delimiter for characters for
36! list-directed output and Namelist output
37! CALL safe_open(iou,istat,my_output_file_name,'replace',
38! & 'formatted',delim_in='none')
39
40! JDH 08-30-2004.
41! Based on Steve Hirshman's original safe_open routine
42! Rearranged comments, continuation lines, some statement ordering.
43! Should be NO change in functionality.
44!
45! JDH 2010-06-09
46! Added coding for DELIM specification
47!
48! SAL 2012-11-29
49! Checked to make sure iunit > 10 so we don't write to screen.
50
51
52 IMPLICIT NONE
53!-----------------------------------------------
54! D u m m y A r g u m e n t s
55!-----------------------------------------------
56 INTEGER, INTENT(inout) :: iunit
57 INTEGER, INTENT(out) :: istat
58 CHARACTER(LEN=*), INTENT(in) :: filename, filestat, fileform
59 INTEGER, INTENT(in), OPTIONAL :: record_in
60 CHARACTER(LEN=*), INTENT(in), OPTIONAL :: access_in
61 CHARACTER(LEN=*), INTENT(in), OPTIONAL :: delim_in
62!-----------------------------------------------
63! L o c a l V a r i a b l e s
64!-----------------------------------------------
65 CHARACTER(LEN=*), PARAMETER :: cdelim = "apostrophe",
66 1 cform="formatted", cunform="unformatted",
67 2 cscratch="scratch", cseq="sequential"
68 CHARACTER(LEN=10) :: acc_type
69 CHARACTER(LEN=10) :: delim_type
70 LOGICAL :: lopen, lexist, linvalid
71!-----------------------------------------------
72! Start of Executable Code
73!-----------------------------------------------
74
75!-----------------------------------------------
76!
77! Check that unit is not already opened
78! Increment iunit until find one that is not in use
79!
80 linvalid = .true.
81 DO WHILE (linvalid)
82 IF (iunit > 10) THEN
83 INQUIRE(iunit, exist=lexist, opened=lopen, iostat=istat)
84 linvalid = (istat.ne.0 .or. .not.lexist) .or. lopen
85 IF (.not.linvalid) EXIT
86 END IF
87 iunit = iunit + 1
88 END DO
89
90! JDH 08-24-2004 This next IF(Present) clause seems to be duplicated below.
91! I think one of the two should be eliminated, for clarity.
92
93 IF (PRESENT(access_in)) THEN
94 acc_type = trim(access_in)
95 ELSE
96 acc_type = cseq
97 END IF
98
99! Why not call this variable lscratch?
100 lexist = (filestat(1:1).eq.'s') .or. (filestat(1:1).eq.'S') !Scratch file
101
102! JDH 08-24-2004 Below is nearly exact duplicate of IF(Present) clause
103! from above
104
105 IF (PRESENT(access_in)) THEN
106 acc_type = trim(access_in)
107 ELSE
108 acc_type = 'SEQUENTIAL'
109 END IF
110
111! JDH 2010-06-09. Coding for DELIM
112 IF (PRESENT(delim_in)) THEN
113 SELECT CASE (delim_in(1:1))
114 CASE ('n', 'N')
115 delim_type = 'none'
116 CASE ('q', 'Q')
117 delim_type = 'quote'
118 CASE DEFAULT
119 delim_type = cdelim
120 END SELECT
121 ELSE
122 delim_type = cdelim
123 ENDIF
124
125! Here are the actual OPEN commands. Eight different cases.
126 SELECT CASE (fileform(1:1))
127 CASE ('u', 'U')
128 IF (PRESENT(record_in)) THEN
129 IF (lexist) THEN ! unformatted, record length specified, scratch
130 OPEN(unit=iunit, form=cunform, status=cscratch, &
131 & recl=record_in, access=acc_type, iostat=istat)
132 ELSE ! unformatted, record length specified, non-scratch
133 OPEN(unit=iunit, file=trim(filename), form=cunform, &
134 & status=trim(filestat), recl=record_in, &
135 & access=acc_type, iostat=istat)
136 END IF
137 ELSE
138 IF (lexist) THEN ! unformatted, record length unspecified, scratch
139 OPEN(unit=iunit, form=cunform, status=cscratch, &
140 & access=acc_type, iostat=istat)
141 ELSE ! unformatted, record length unspecified, non-scratch
142 OPEN(unit=iunit, file=trim(filename), form=cunform, &
143 & status=trim(filestat), access=acc_type,iostat=istat)
144 END IF
145 END IF
146
147 CASE DEFAULT
148 IF (PRESENT(record_in)) THEN
149 IF (lexist) THEN ! formatted, record length specified, scratch
150 OPEN(unit=iunit, form=cform, status=cscratch, &
151 & delim=trim(delim_type), recl=record_in, &
152 & access=acc_type, iostat=istat)
153 ELSE ! formatted, record length specified, non-scratch
154 OPEN(unit=iunit, file=trim(filename), form=cform, &
155 & status=trim(filestat), delim=trim(delim_type), &
156 & recl=record_in, access=acc_type, iostat=istat)
157 END IF
158 ELSE
159 IF (lexist) THEN ! formatted, record length unspecified, scratch
160 OPEN(unit=iunit, form=cform, status=cscratch, &
161 & delim=trim(delim_type), access=acc_type, &
162 & iostat=istat)
163 ELSE ! formatted, record length unspecified, non-scratch
164 OPEN(unit=iunit, file=trim(filename), form=cform, &
165 & status=trim(filestat), delim=trim(delim_type), &
166 & access=acc_type, iostat=istat)
167 END IF
168 END IF
169
170 END SELECT
171
172 END SUBROUTINE safe_open
173
174 END MODULE safe_open_mod
fault-tolerant file opening routines
subroutine safe_open(iunit, istat, filename, filestat, fileform, record_in, access_in, delim_in)