144
145
146
147
148
149
150
152 implicit none
153 character(*), intent(out) :: unit
154 character(*), intent(in) :: fmt
155 integer, intent(in), optional :: i(:), n(:)
156 real(SP), intent(in), optional :: r(:)
157 real(DP), intent(in), optional :: d(:)
158 logical, intent(in), optional :: L(:)
159 character(*), intent(in), optional :: c1, c2, c3
160 character(*), intent(in), optional :: ca(:)
161
162
163 integer :: ni, nr, nd, nl, nc, na, nn
164 integer :: ucur
165 integer :: endp
166 integer :: cur
167 integer :: ptr
168 integer :: exp_ptr
169 integer :: minus_ptr
170 integer :: repeat
171 integer :: m
172 integer :: stat
173 character(80) :: cbuf
174 character(80) :: exp_buf
175 character(80) :: ibuf
176 integer :: len_ibuf
177 integer :: figs_ibuf
178 logical :: int_zero_fill
179 integer :: int_figs
180 continue
181 ni = 0; nr = 0; nd = 0; nl = 0; nc = 0; na = 0; nn = 0
182 unit = ""
183 ucur = 0
184 endp = 0
185 int_figs = 0
186 int_zero_fill = .false.
187 mainloop: do
188 cur = endp + 1
189 if (cur > len(fmt)) exit mainloop
190
191
192
193 endp = cur - 1 + scan(fmt(cur: ), '%')
194 if (endp > cur) then
195 call append(unit, ucur, fmt(cur:endp-1), stat)
196 if (stat /= 0) exit mainloop
197 else if (endp == cur - 1) then
198 call append(unit, ucur, fmt(cur: ), stat)
199 exit mainloop
200 endif
201
202
203
204 cur = endp + 1
205 endp = cur - 1 + scan(fmt(cur: ), 'DdOoXxFfRrBbYySsCcAa%')
206 if (endp < cur) then
207 call append(unit, ucur, fmt(cur-1: ), stat)
208 exit mainloop
209 endif
210 cbuf = fmt(cur:endp-1)
211
212
213
214 if (cbuf(1:1) == '*') then
215 nn = nn + 1
216 if (nn > size(n)) then
217 repeat = 1
218 else
219 repeat = n(nn)
220 endif
221 ibuf = cbuf(2:)
222 else
223 repeat = 1
224 ibuf = cbuf
225
226
227
228
229
230
231 endif
232
233
234
235
236
237 if (scan(ibuf(1:1),'1234567890') > 0) then
238 if (ibuf(1:1) == '0') then
239 int_zero_fill = .true.
240 else
241 int_zero_fill = .false.
242 end if
243 read(unit=ibuf, fmt="(i80)") int_figs
244 else
245 int_figs = 0
246 int_zero_fill = .false.
247 endif
248 percentrepeat: do m = 1, repeat
249 if (m > 1) then
250 call append(unit, ucur,
", ", stat)
251 if (stat /= 0) exit mainloop
252 endif
253 select case(fmt(endp:endp))
254 case('d', 'D')
255 if (.not. present(i)) cycle mainloop
256 ni = ni + 1; if (ni > size(i)) cycle mainloop
257 write(ibuf, "(i20)") i(ni)
258 len_ibuf = len(trim(adjustl(ibuf)))
259 figs_ibuf = verify(ibuf, ' ')
260 cbuf = ' '
261 if (int_figs > len_ibuf) then
262 minus_ptr = scan(ibuf, '-')
263 if (int_zero_fill) then
264 if (minus_ptr /= 0) then
265 len_ibuf = len_ibuf - 1
266 figs_ibuf = figs_ibuf + 1
267 cbuf(1:int_figs-len_ibuf) = '-0000000000000000000'
268 else
269 cbuf(1:int_figs-len_ibuf) = '00000000000000000000'
270 end if
271 end if
272 cbuf(int_figs-len_ibuf+1:) = ibuf(figs_ibuf:20)
273 else
274 cbuf = ibuf(figs_ibuf:20)
275 end if
276 call append(unit, ucur, trim(cbuf), stat)
277 if (stat /= 0) exit mainloop
278 case('o', 'O')
279 if (.not. present(i)) cycle mainloop
280 ni = ni + 1; if (ni > size(i)) cycle mainloop
281 write(cbuf, "(o20)") i(ni)
282 call append(unit, ucur, trim(adjustl(cbuf)), stat)
283 if (stat /= 0) exit mainloop
284 case('x', 'X')
285 if (.not. present(i)) cycle mainloop
286 ni = ni + 1; if (ni > size(i)) cycle mainloop
287 write(cbuf, "(z20)") i(ni)
288 call append(unit, ucur, trim(adjustl(cbuf)), stat)
289 if (stat /= 0) exit mainloop
290 case('f', 'F')
291 if (.not. present(d)) cycle mainloop
292 nd = nd + 1; if (nd > size(d)) cycle mainloop
293 write(cbuf, "(f80.40)") d(nd)
294 cbuf = adjustl(cbuf)
295 exp_ptr = verify(cbuf, ' 1234567890-+.', back=.true.)
296 exp_buf = ' '
297 if (exp_ptr > 0) then
298 exp_buf = cbuf(exp_ptr: )
299 cbuf(exp_ptr: ) = " "
300 end if
301 ptr = verify(cbuf, " 0", back=.true.)
302 if (ptr > 0) cbuf(ptr+1: ) = " "
303 cbuf = trim(cbuf) // trim(exp_buf)
304 call append(unit, ucur, trim(adjustl(cbuf)), stat)
305 if (stat /= 0) exit mainloop
306 case('r', 'R')
307 if (.not. present(r)) cycle mainloop
308 nr = nr + 1 ; if (nr > size(r)) cycle mainloop
309 write(cbuf, "(f80.40)") r(nr)
310 cbuf = adjustl(cbuf)
311 exp_ptr = verify(cbuf, ' 1234567890-+.', back=.true.)
312 exp_buf = ' '
313 if (exp_ptr > 0) then
314 exp_buf = cbuf(exp_ptr: )
315 cbuf(exp_ptr: ) = " "
316 end if
317 ptr = verify(cbuf, " 0", back=.true.)
318 if (ptr > 0) cbuf(ptr+1: ) = " "
319 cbuf = trim(cbuf) // trim(exp_buf)
320 call append(unit, ucur, trim(adjustl(cbuf)), stat)
321 if (stat /= 0) exit mainloop
322 case('b', 'B')
323 if (.not. present(l)) cycle mainloop
324 nl = nl + 1; if (nl > size(l)) cycle mainloop
325 write(cbuf, "(L1)") l(nl)
326 call append(unit, ucur, trim(adjustl(cbuf)), stat)
327 if (stat /= 0) exit mainloop
328 case('y', 'Y')
329 if (.not. present(l)) cycle mainloop
330 nl = nl + 1; if (nl > size(l)) cycle mainloop
331 if (l(nl)) then
332 call append(unit, ucur,
"yes", stat)
333 if (stat /= 0) exit mainloop
334 else
335 call append(unit, ucur,
"no", stat)
336 if (stat /= 0) exit mainloop
337 endif
338 case('c', 'C')
339 nc = nc + 1
340 if (nc == 1) then
341 if (.not. present(c1)) cycle percentrepeat
342 call append(unit, ucur, c1, stat)
343 if (stat /= 0) exit mainloop
344 else if (nc == 2) then
345 if (.not. present(c2)) cycle percentrepeat
346 call append(unit, ucur, c2, stat)
347 if (stat /= 0) exit mainloop
348 else if (nc == 3) then
349 if (.not. present(c3)) cycle percentrepeat
350 call append(unit, ucur, c3, stat)
351 if (stat /= 0) exit mainloop
352 endif
353 case('a', 'A')
354 if (.not. present(ca)) cycle mainloop
355 na = na + 1; if (na > size(ca)) cycle mainloop
356 call append(unit, ucur, trim(adjustl(ca(na))), stat)
357 if (stat /= 0) exit mainloop
358 case('%')
359 call append(unit, ucur,
'%', stat)
360 if (stat /= 0) exit mainloop
361 end select
362 enddo percentrepeat
363 enddo mainloop
364 return
365contains
366
367 subroutine append(unitx, ucur, val, stat)
368
369
370
371
372 character(*), intent(inout):: unitx
373 integer, intent(inout):: ucur
374 character(*), intent(in) :: val
375 integer, intent(out) :: stat
376 integer :: wrsz
377 continue
378
379 if (ucur >= len(unitx)) then
380 stat = 2
381
382 else
383
384 wrsz = min(len(val), len(unitx) - ucur)
385 unitx(1+ucur: wrsz+ucur) = val(1: wrsz)
386 ucur = ucur + wrsz
387 stat = 0
388 if (wrsz < len(val)) stat = 1
389 endif
391
subroutine append(unitx, ucur, val, stat)
integer, parameter, public dp
倍精度実数型変数
integer, parameter, public sp
単精度実数型変数