4 use netcdf, only: &
5 & nf90_write, &
6 & nf90_nowrite, &
7 & nf90_noerr, &
8 & nf90_noclobber, &
9 & nf90_clobber, &
10 & nf90_64bit_offset, &
11 & nf90_open, &
12 & nf90_create
13 use dc_message, only: messagenotify
16 use dc_trace, only: beginsub, endsub
17 implicit none
18 integer, intent(out):: fileid
19 character(len = *), intent(in):: filename
20 logical, intent(in), optional:: writable
21
22
23
24
25
26
27 logical, intent(in), optional:: overwrite
28
29
30
31
32
33
34 logical, intent(out), optional:: err
35 integer, intent(out), optional:: stat
36 logical:: writable_required
37 logical:: overwrite_required
38 type(GD_NC_FILE_ID_ENTRY), pointer:: identptr, prev
39 integer:: mystat, mode
40 character(len = 256):: real_filename
41 character(len = STRING):: cause_c
42 character(*), parameter:: subname = "GDNcFileOpen"
43continue
44 fileid = -1
45
46
47
48 writable_required = .false.
49 overwrite_required = .false.
50 if (present(writable)) writable_required = writable
51 if (present(overwrite)) overwrite_required = overwrite
52 call beginsub(subname, 'writable=%y overwrite=%y file=%c', &
53 & l=(/writable_required, overwrite_required/), c1=trim(filename))
54
55
56
59 nullify(prev)
60 do
61 if ((identptr % filename == filename) &
62 & .and. (identptr % writable .or. .not. writable_required)) then
63 fileid = identptr % id
64 identptr % count = identptr % count + 1
65 if (present(err)) err = .false.
66 if (present(stat)) stat = nf90_noerr
67 mystat = nf90_noerr
68 goto 999
69 endif
70 prev => identptr
71 identptr => identptr % next
72 if (.not. associated(identptr)) exit
73 enddo
74 allocate(identptr)
75 prev%next => identptr
76 else
77 nullify(prev)
81 endif
82 nullify(identptr % next)
83 identptr % filename = filename
84 identptr % writable = writable_required
85 identptr % count = 1
86
87
88
89 real_filename = filename
90 if (real_filename(1:8) == 'file:///') then
91 real_filename = real_filename(8: )
92 else if (real_filename(1:5) == 'file:' .AND. real_filename(6:6) /= '/') then
93 real_filename = real_filename(6: )
94 endif
95
96
97
98 mode = nf90_nowrite
99 if (writable_required) mode = ior(mode, nf90_write)
100
101 mystat = nf90_open(real_filename, mode, identptr % id)
102
103
104
105 if (mystat == nf90_noerr) then
106
107 if (writable_required) then
108 if (overwrite_required) then
109
110 mode = nf90_clobber
111 call messagenotify('M', subname, &
112 & '"%c" is overwritten.', c1=trim(filename), rank_mpi = -1)
113 else
114
115 mode = nf90_noclobber
116 call messagenotify('W', subname, &
117 & '"%c" is opened in write-protect mode.', c1=trim(filename), rank_mpi = -1)
118 end if
119 mode = ior(mode,nf90_64bit_offset)
120 mystat = nf90_create(real_filename, mode, identptr % id)
121 if (mystat /= nf90_noerr) then
122 cause_c=filename
123 if (present(stat)) stat = mystat
124 goto 999
125 end if
126 endif
127
128 else
129
130
131
132 if (.not. writable_required) then
133
134
135
136 if (mystat /= nf90_noerr) then
137 cause_c=filename
138 if (present(stat)) stat = mystat
139 goto 999
140 end if
141 else
142
143 mode = nf90_clobber
144
145 mode = ior(mode,nf90_64bit_offset)
146 mystat = nf90_create(real_filename, mode, identptr % id)
147 if (mystat /= nf90_noerr) then
148 cause_c=filename
149 if (present(stat)) stat = mystat
150 goto 999
151 end if
152 endif
153 endif
154
155 fileid = identptr % id
156
157
158 if (mystat /= nf90_noerr) then
159 if (associated(prev)) then
160 prev%next => identptr % next
161 else
164 endif
165 deallocate(identptr)
166 fileid = -1
167 endif
168
169 if (present(stat)) then
170 stat = mystat
171 if (present(err)) err = (stat /= nf90_noerr)
172 else
173 cause_c=filename
174 goto 999
175 endif
176999 continue
177 call storeerror(mystat, subname, err, cause_c)
178 call endsub(subname, 'id=%d stat=%d', i=(/fileid, mystat/))
subroutine, public storeerror(number, where, err, cause_c, cause_i)
integer, parameter, public string
文字列を保持する 文字型変数の種別型パラメタ
type(gd_nc_file_id_entry), pointer, save id_head