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