104
106 implicit none
107 character(*), intent(out) :: unit
108 character(*), intent(in) :: fmt
109 integer, intent(in), optional :: i(:), n(:)
110 real(SP), intent(in), optional :: r(:)
111 real(DP), intent(in), optional :: d(:)
112 logical, intent(in), optional :: L(:)
113 character(*), intent(in), optional :: c1, c2, c3
114 character(*), intent(in), optional :: ca(:)
115
116
117 integer :: ni, nr, nd, nl, nc, na, nn
118 integer :: ucur
119 integer :: endp
120 integer :: cur
121 integer :: ptr
122 integer :: exp_ptr
123 integer :: minus_ptr
124 integer :: repeat
125 integer :: m
126 integer :: stat
127 character(80) :: cbuf
128 character(80) :: exp_buf
129 character(80) :: ibuf
130 integer :: len_ibuf
131 integer :: figs_ibuf
132 logical :: int_zero_fill
133 integer :: int_figs
134 continue
135 ni = 0; nr = 0; nd = 0; nl = 0; nc = 0; na = 0; nn = 0
136 unit = ""
137 ucur = 0
138 endp = 0
139 int_figs = 0
140 int_zero_fill = .false.
141 mainloop: do
142 cur = endp + 1
143 if (cur > len(fmt)) exit mainloop
144
145
146
147 endp = cur - 1 + scan(fmt(cur: ), '%')
148 if (endp > cur) then
149 call append(unit, ucur, fmt(cur:endp-1), stat)
150 if (stat /= 0) exit mainloop
151 else if (endp == cur - 1) then
152 call append(unit, ucur, fmt(cur: ), stat)
153 exit mainloop
154 endif
155
156
157
158 cur = endp + 1
159 endp = cur - 1 + scan(fmt(cur: ), 'DdOoXxFfRrBbYySsCcAa%')
160 if (endp < cur) then
161 call append(unit, ucur, fmt(cur-1: ), stat)
162 exit mainloop
163 endif
164 cbuf = fmt(cur:endp-1)
165
166
167
168 if (cbuf(1:1) == '*') then
169 nn = nn + 1
170 if (nn > size(n)) then
171 repeat = 1
172 else
173 repeat = n(nn)
174 endif
175 ibuf = cbuf(2:)
176 else
177 repeat = 1
178 ibuf = cbuf
179
180
181
182
183
184
185 endif
186
187
188
189
190
191 if (scan(ibuf(1:1),'1234567890') > 0) then
192 if (ibuf(1:1) == '0') then
193 int_zero_fill = .true.
194 else
195 int_zero_fill = .false.
196 end if
197 read(unit=ibuf, fmt="(i80)") int_figs
198 else
199 int_figs = 0
200 int_zero_fill = .false.
201 endif
202 percentrepeat: do m = 1, repeat
203 if (m > 1) then
204 call append(unit, ucur,
", ", stat)
205 if (stat /= 0) exit mainloop
206 endif
207 select case(fmt(endp:endp))
208 case('d', 'D')
209 if (.not. present(i)) cycle mainloop
210 ni = ni + 1; if (ni > size(i)) cycle mainloop
211 write(ibuf, "(i20)") i(ni)
212 len_ibuf = len(trim(adjustl(ibuf)))
213 figs_ibuf = verify(ibuf, ' ')
214 cbuf = ' '
215 if (int_figs > len_ibuf) then
216 minus_ptr = scan(ibuf, '-')
217 if (int_zero_fill) then
218 if (minus_ptr /= 0) then
219 len_ibuf = len_ibuf - 1
220 figs_ibuf = figs_ibuf + 1
221 cbuf(1:int_figs-len_ibuf) = '-0000000000000000000'
222 else
223 cbuf(1:int_figs-len_ibuf) = '00000000000000000000'
224 end if
225 end if
226 cbuf(int_figs-len_ibuf+1:) = ibuf(figs_ibuf:20)
227 else
228 cbuf = ibuf(figs_ibuf:20)
229 end if
230 call append(unit, ucur, trim(cbuf), stat)
231 if (stat /= 0) exit mainloop
232 case('o', 'O')
233 if (.not. present(i)) cycle mainloop
234 ni = ni + 1; if (ni > size(i)) cycle mainloop
235 write(cbuf, "(o20)") i(ni)
236 call append(unit, ucur, trim(adjustl(cbuf)), stat)
237 if (stat /= 0) exit mainloop
238 case('x', 'X')
239 if (.not. present(i)) cycle mainloop
240 ni = ni + 1; if (ni > size(i)) cycle mainloop
241 write(cbuf, "(z20)") i(ni)
242 call append(unit, ucur, trim(adjustl(cbuf)), stat)
243 if (stat /= 0) exit mainloop
244 case('f', 'F')
245 if (.not. present(d)) cycle mainloop
246 nd = nd + 1; if (nd > size(d)) cycle mainloop
247 write(cbuf, "(f80.40)") d(nd)
248 cbuf = adjustl(cbuf)
249 exp_ptr = verify(cbuf, ' 1234567890-+.', back=.true.)
250 exp_buf = ' '
251 if (exp_ptr > 0) then
252 exp_buf = cbuf(exp_ptr: )
253 cbuf(exp_ptr: ) = " "
254 end if
255 ptr = verify(cbuf, " 0", back=.true.)
256 if (ptr > 0) cbuf(ptr+1: ) = " "
257 cbuf = trim(cbuf) // trim(exp_buf)
258 call append(unit, ucur, trim(adjustl(cbuf)), stat)
259 if (stat /= 0) exit mainloop
260 case('r', 'R')
261 if (.not. present(r)) cycle mainloop
262 nr = nr + 1 ; if (nr > size(r)) cycle mainloop
263 write(cbuf, "(f80.40)") r(nr)
264 cbuf = adjustl(cbuf)
265 exp_ptr = verify(cbuf, ' 1234567890-+.', back=.true.)
266 exp_buf = ' '
267 if (exp_ptr > 0) then
268 exp_buf = cbuf(exp_ptr: )
269 cbuf(exp_ptr: ) = " "
270 end if
271 ptr = verify(cbuf, " 0", back=.true.)
272 if (ptr > 0) cbuf(ptr+1: ) = " "
273 cbuf = trim(cbuf) // trim(exp_buf)
274 call append(unit, ucur, trim(adjustl(cbuf)), stat)
275 if (stat /= 0) exit mainloop
276 case('b', 'B')
277 if (.not. present(l)) cycle mainloop
278 nl = nl + 1; if (nl > size(l)) cycle mainloop
279 write(cbuf, "(L1)") l(nl)
280 call append(unit, ucur, trim(adjustl(cbuf)), stat)
281 if (stat /= 0) exit mainloop
282 case('y', 'Y')
283 if (.not. present(l)) cycle mainloop
284 nl = nl + 1; if (nl > size(l)) cycle mainloop
285 if (l(nl)) then
286 call append(unit, ucur,
"yes", stat)
287 if (stat /= 0) exit mainloop
288 else
289 call append(unit, ucur,
"no", stat)
290 if (stat /= 0) exit mainloop
291 endif
292 case('c', 'C')
293 nc = nc + 1
294 if (nc == 1) then
295 if (.not. present(c1)) cycle percentrepeat
296 call append(unit, ucur, c1, stat)
297 if (stat /= 0) exit mainloop
298 else if (nc == 2) then
299 if (.not. present(c2)) cycle percentrepeat
300 call append(unit, ucur, c2, stat)
301 if (stat /= 0) exit mainloop
302 else if (nc == 3) then
303 if (.not. present(c3)) cycle percentrepeat
304 call append(unit, ucur, c3, stat)
305 if (stat /= 0) exit mainloop
306 endif
307 case('a', 'A')
308 if (.not. present(ca)) cycle mainloop
309 na = na + 1; if (na > size(ca)) cycle mainloop
310 call append(unit, ucur, trim(adjustl(ca(na))), stat)
311 if (stat /= 0) exit mainloop
312 case('%')
313 call append(unit, ucur,
'%', stat)
314 if (stat /= 0) exit mainloop
315 end select
316 enddo percentrepeat
317 enddo mainloop
318 return
319contains
320
335 subroutine append(unitx, ucur, val, stat)
336 character(*), intent(inout):: unitx
337 integer, intent(inout):: ucur
338 character(*), intent(in) :: val
339 integer, intent(out) :: stat
340 integer :: wrsz
341 continue
342
343 if (ucur >= len(unitx)) then
344 stat = 2
345
346 else
347
348 wrsz = min(len(val), len(unitx) - ucur)
349 unitx(1+ucur: wrsz+ucur) = val(1: wrsz)
350 ucur = ucur + wrsz
351 stat = 0
352 if (wrsz < len(val)) stat = 1
353 endif
355
subroutine append(unitx, ucur, val, stat)
integer, parameter, public sp
単精度実数型変数
integer, parameter, public dp
倍精度実数型変数