gtool5 Fortran 90/95 ライブラリ 1.0.0-rc5
English
Loading...
Searching...
No Matches
dc_iounit.f90
Go to the documentation of this file.
1!-----------------------------------------------------------------------
2! Copyright (c) 2000-2026 Gtool Development Group. All rights reserved.
3!-----------------------------------------------------------------------
4!>
5!> @author Youhei SASAKI, Yasuhiro MORIKAWA
6!> @copyright Copyright (C) GFD Dennou Club, 2007-2026. All rights reserved. <br/>
7!> License is BSD-2-Clause. see [COPYRIGHT](@ref COPYRIGHT) in detail
8!> @en
9!> @brief Unit number handling at file open
10!> @details
11!> Unit number is handled when a file is opened.
12!> Subroutine "FileOpen" receives filename and open mode firstly, and
13!> searches an available unit number internally, and
14!> opens the file according to the open mode internally, and
15!> returns the unit number finally.
16!> This module simplifies source codes for unit number management or
17!> readable/writable check.
18!>
19!> @section iounit_procedures Procedures List
20!>
21!> | Procedure | Description |
22!> |------------|--------------------------------------------------------|
23!> | FileOpen | A file is opened and unit number is returned with a filename and mode |
24!>
25!> @section iounit_usage Usage
26!>
27!> Give filename and open mode to subroutine "FileOpen" provided by
28!> this module. Then the file is opened and unit number is returned
29!> to an argument `unit`. Using the unit number, read the contents
30!> of the file or write in the file. Use Fortran built-in READ,
31!> WRITE, and CLOSE statements for read/write and close.
32!>
33!> @section iounit_example Example
34!>
35!> @code{.f90}
36!> program dc_iounit_sample
37!> use dc_types, only: TOKEN
38!> use dc_iounit, only: FileOpen
39!> implicit none
40!> integer:: unit00, unit01
41!> character(TOKEN):: char
42!> character(TOKEN):: filename = 'dc_iounit_sample.nml'
43!> integer:: int
44!> namelist /dc_iounit_sample_nml/ char, int
45!> continue
46!>
47!> call FileOpen(unit00, file = filename, mode = 'w')
48!> write(unit00, *) '&dc_iounit_sample_nml'
49!> write(unit00, *) ' char = "hogehoge",'
50!> write(unit00, *) ' int = 123'
51!> write(unit00, *) '/'
52!> close(unit00)
53!>
54!> call FileOpen(unit01, file = filename, mode = 'r')
55!> read(unit01, nml = dc_iounit_sample_nml)
56!> close(unit01)
57!> write(0, nml = dc_iounit_sample_nml)
58!>
59!> end program dc_iounit_sample
60!> @endcode
61!>
62!> @enden
63!>
64!> @ja
65!> @brief ファイルオープン時の装置番号処理
66!> @details
67!> ファイルをオープンする際に使用する装置番号の処理を行います.
68!> サブルーチン FileOpen にファイル名とオープン時のモードを与えることで,
69!> 利用可能な装置番号を内部で探査し,
70!> 内部でファイルをモードに合わせてオープンしてから, 装置番号を返します.
71!> このモジュールは, 装置番号の管理やファイルの読み取り/書き込み可能
72!> などの確認作業のためのソースコードを簡素化します.
73!>
74!> @section iounit_procedures_ja 手続一覧
75!>
76!> | 手続名 | 説明 |
77!> |------------|--------------------------------------------------------|
78!> | FileOpen | ファイル名とモードを与えることでファイルをオープンし, 装置番号を返します |
79!>
80!> @section iounit_usage_ja 使用方法
81!>
82!> このモジュールで提供されるサブルーチン FileOpen に
83!> ファイル名とオープン時のモードを与えてください.
84!> するとファイルがオープンされ, 引数 `unit` に装置番号が返ります.
85!> その装置番号を用い, ファイルの内容の読み込みや
86!> ファイルへの書き込みを行ってください. 読み込みや書き込みやクローズには
87!> Fortran 組み込みの READ 文や WRITE 文, CLOSE 文を用いてください.
88!>
89!> @section iounit_example_ja 使用例
90!>
91!> @code{.f90}
92!> program dc_iounit_sample
93!> use dc_types, only: TOKEN
94!> use dc_iounit, only: FileOpen
95!> implicit none
96!> integer:: unit00, unit01
97!> character(TOKEN):: char
98!> character(TOKEN):: filename = 'dc_iounit_sample.nml'
99!> integer:: int
100!> namelist /dc_iounit_sample_nml/ char, int
101!> continue
102!>
103!> call FileOpen(unit00, file = filename, mode = 'w')
104!> write(unit00, *) '&dc_iounit_sample_nml'
105!> write(unit00, *) ' char = "hogehoge",'
106!> write(unit00, *) ' int = 123'
107!> write(unit00, *) '/'
108!> close(unit00)
109!>
110!> call FileOpen(unit01, file = filename, mode = 'r')
111!> read(unit01, nml = dc_iounit_sample_nml)
112!> close(unit01)
113!> write(0, nml = dc_iounit_sample_nml)
114!>
115!> end program dc_iounit_sample
116!> @endcode
117!>
118!> @endja
119!>
120
122 implicit none
123 private
124
125 public:: fileopen
126
127 character(*), parameter:: version = &
128 & '$Name: $' // &
129 & '$Id: dc_iounit.f90,v 1.1 2009-03-20 09:09:53 morikawa Exp $'
130
131 interface fileopen
132 module procedure fileopen
133 end interface
134
135contains
136
137 !> @en
138 !> @brief Open a file and return unit number
139 !> @details
140 !> Filename is given to `file`, and open mode is given to `mode`,
141 !> then the file is opened and unit number is returned.
142 !>
143 !> | Mode | Description |
144 !> |------|-----------------------------------------------------------------|
145 !> | "r" | A file is opened with read-only mode |
146 !> | "w" | A file is opened with writable mode. If a file is exist already, the content of the file is emptied. |
147 !> | "a" | A file is opened with writable mode. Output is appended at the end of the file. |
148 !> | "rw" | A file is opened with read/write mode. If a file is exist already, the content of the file is emptied. |
149 !> | "ra" | A file is opened with read/write mode. If a file is exist already, a position of read/write is set at the end of the file. |
150 !>
151 !> If the file can not be opened with the mode, the program aborts.
152 !> If this `err` argument is given, `.true.` is substituted to `err` and
153 !> -1 is substituted to `unit` and the program does not abort.
154 !>
155 !> @param[out] unit Unit number assigned to the opened file
156 !> @param[in] file Filename to open
157 !> @param[in] mode Open mode ("r", "w", "a", "rw", "ra"). Default is "r".
158 !> @param[out] err Exception handling flag
159 !> @enden
160 !>
161 !> @ja
162 !> @brief ファイルをオープンし、装置番号を返します
163 !> @details
164 !> ファイル名を `file` へ, オープンする際のモードを `mode` へと
165 !> 与えることで, ファイルをオープンし, 装置番号を `unit` に返します.
166 !> `mode` には以下の文字列を指定します. 省略時は "r" が指定されたもの
167 !> とみなします.
168 !>
169 !> | モード | 説明 |
170 !> |--------|----------------------------------------------------------------|
171 !> | "r" | ファイルを読み込みモードでオープンします. |
172 !> | "w" | ファイルを書き込みモードでオープンします. オープン時にファイルがすでに存在していればその内容を空にします. |
173 !> | "a" | ファイルを書き込みモードでオープンします. 出力はファイルの末尾に追加されます. |
174 !> | "rw" | ファイルを読み書き両用モードでオープンします. オープン時にファイルがすでに存在していればその内容を空にします. |
175 !> | "ra" | ファイルを読み書き両用モードでオープンします. オープン時にファイルがすでに存在していれば読み書き位置がファイルの末尾にセットされます. |
176 !>
177 !> ファイルが `mode` で指定されるモードで開けない場合, プログラムは
178 !> 強制終了します. 引数 `err` が与えられる場合, プログラムは強制終了せず,
179 !> 代わりに `err` に `.true.` が, `unit` に -1 が代入されます.
180 !>
181 !> @param[out] unit オープンされたファイルに割り当てられた装置番号
182 !> @param[in] file オープンするファイル名
183 !> @param[in] mode オープンモード ("r", "w", "a", "rw", "ra"). デフォルトは "r".
184 !> @param[out] err 例外処理用フラグ
185 !> @endja
186 subroutine fileopen( &
187 & unit, file, mode, &
188 & err )
189 use dc_types, only: string, token
190 use dc_trace, only: beginsub, endsub
191 use dc_error, only: storeerror, dc_noerr, &
195 use dc_string, only: tochar, tolower
196 implicit none
197 integer, intent(out):: unit
198 character(*), intent(in):: file
199 character(*), intent(in), optional:: mode
200 logical, intent(out), optional:: err
201
202 !-----------------------------------
203 ! 作業変数
204 ! Work variables
205 integer, parameter:: max_unit = 99
206 ! NAMELIST ファイルをオープンするための
207 ! 装置番号の最大値. Fortran で使用可能な
208 ! 範囲 (0〜99) のうち,
209 ! 最大値が設定されている.
210 !
211 ! Maximum unit number for open of
212 ! NAMELIST file. An maximum
213 ! value within the bounds of available number
214 ! in Fortran (0 - 99) is specified.
215 integer, parameter:: min_unit = 0
216 ! NAMELIST ファイルをオープンするための
217 ! 装置番号の最小値. Fortran で使用可能な
218 ! 範囲 (0〜99) のうち,
219 ! 最小値が設定されている.
220 !
221 ! Minimum unit number for open of
222 ! NAMELIST file. An minimum
223 ! value within the bounds of available number
224 ! in Fortran (0 - 99) is specified.
225 character(TOKEN):: open_mode
226 integer:: unit_work
227 logical:: unit_exist_flag, unit_opend_flag
228 logical:: file_exist_flag
229 integer:: iostat
230 integer:: stat
231 character(STRING):: cause_c
232 character(*), parameter:: subname = 'FileOpen'
233 continue
234 call beginsub(subname, version)
235 stat = dc_noerr
236 cause_c = ''
237 unit = -1
238
239 !-----------------------------------------------------------------
240 ! オプショナル引数のチェック
241 ! Check optional arguments
242 !-----------------------------------------------------------------
243 if (present_and_not_empty(mode)) then
244 open_mode = mode
245 else
246 open_mode = 'r'
247 end if
248 call tolower(open_mode)
249
250 !-----------------------------------------------------------------
251 ! 引数の正当性のチェック
252 ! Validation of arguments
253 !-----------------------------------------------------------------
254 if ( trim(file) == '' ) then
255 stat = dc_efilenameempty
256 goto 999
257 end if
258
259 !----------------------------------------------------------------
260 ! 使用可能な装置番号の探査
261 ! Search available unit number
262 !----------------------------------------------------------------
263 unit_work = max_unit
264 do
265 inquire(unit=unit_work, exist=unit_exist_flag, opened=unit_opend_flag)
266 if (unit_exist_flag .and. .not. unit_opend_flag) then
267 exit
268 endif
269 unit_work = unit_work - 1
270 if (unit_work < min_unit) then
271 cause_c = tochar(min_unit) // ' - ' // tochar(max_unit)
272 stat = dc_enounitnum
273 goto 999
274 end if
275 enddo
276
277 !----------------------------------------------------------------
278 ! モードの書式のチェック
279 ! Check form of mode
280 !----------------------------------------------------------------
281 select case( trim(open_mode) )
282 case ('r', 'w', 'rw', 'a', 'ra')
283 case default
284 cause_c = open_mode
285 stat = dc_ebadfileopmode
286 goto 999
287 end select
288
289 !----------------------------------------------------------------
290 ! ファイルの存在のチェック
291 ! Check existance of a file
292 !----------------------------------------------------------------
293 select case( trim(open_mode) )
294 case ('r')
295 inquire(file=file, exist=file_exist_flag)
296 if (.not. file_exist_flag) then
297 cause_c = file
298 stat = dc_enofileexist
299 goto 999
300 end if
301 end select
302
303 !----------------------------------------------------------------
304 ! ファイルの読み込み可能のチェック
305 ! Check readable of a file
306 !----------------------------------------------------------------
307 select case( trim(open_mode) )
308 case ('r')
309 open(unit=unit_work, iostat=iostat, &
310 & file=file, status='OLD', action='READ')
311 if (.not. iostat == 0) then
312 cause_c = file
313 stat = dc_enofileread
314 goto 999
315 end if
316 close(unit=unit_work)
317 end select
318
319 !----------------------------------------------------------------
320 ! ファイルの書き込み可能のチェック
321 ! Check writable of a file
322 !----------------------------------------------------------------
323 select case( trim(open_mode) )
324 case ('w', 'a', 'rw', 'ra')
325 open(unit=unit_work, iostat=iostat, &
326 & file=file, status='UNKNOWN', action='WRITE')
327 if (.not. iostat == 0) then
328 cause_c = file
329 stat = dc_enofilewrite
330 goto 999
331 end if
332 close(unit=unit_work)
333 end select
334
335 !----------------------------------------------------------------
336 ! ファイルオープン
337 ! Open a file
338 !----------------------------------------------------------------
339 select case( trim(open_mode) )
340 case ('r')
341 open(unit=unit_work, file=file, &
342 & status='OLD', action='READ')
343
344 case ('w')
345 open(unit=unit_work, file=file, &
346 & status='REPLACE', action='WRITE')
347
348 case ('rw')
349 open(unit=unit_work, file=file, &
350 & status='REPLACE', action='READWRITE')
351
352 case ('a')
353 open(unit=unit_work, file=file, &
354 & status='UNKNOWN', position='APPEND', action='WRITE')
355
356 case ('ra')
357 open(unit=unit_work, file=file, &
358 & status='UNKNOWN', position='APPEND', action='READWRITE')
359
360 end select
361
362 unit = unit_work
363
364999 continue
365 call storeerror(stat, subname, err, cause_c)
366 call endsub(subname)
367 end subroutine fileopen
368
369 !> @namespace dc_iounit
370end module dc_iounit
エラー処理用モジュール
Definition dc_error.f90:454
subroutine, public storeerror(number, where, err, cause_c, cause_i)
Definition dc_error.f90:891
integer, parameter, public dc_ebadfileopmode
Definition dc_error.f90:540
integer, parameter, public dc_noerr
エラー等を保持
Definition dc_error.f90:468
integer, parameter, public dc_enofileread
Definition dc_error.f90:543
integer, parameter, public dc_efilenameempty
Definition dc_error.f90:539
integer, parameter, public dc_enofilewrite
Definition dc_error.f90:544
integer, parameter, public dc_enofileexist
Definition dc_error.f90:542
integer, parameter, public dc_enounitnum
Definition dc_error.f90:541
ファイルオープン時の装置番号処理
省略可能な制御パラメータの判定
logical function, public present_and_not_empty(arg)
文字型変数の操作
Definition dc_string.f90:83
デバッグ時の追跡用モジュール
Definition dc_trace.f90:150
subroutine, public beginsub(name, fmt, i, r, d, l, n, c1, c2, c3, ca, version)
Definition dc_trace.f90:476
subroutine, public endsub(name, fmt, i, r, d, l, n, c1, c2, c3, ca)
Definition dc_trace.f90:599
種別型パラメタを提供します。
Definition dc_types.f90:55
integer, parameter, public token
単語やキーワードを保持する文字型変数の種別型パラメタ
Definition dc_types.f90:128
integer, parameter, public string
文字列を保持する 文字型変数の種別型パラメタ
Definition dc_types.f90:137