WAVEWATCH III  beta 0.0.1
mod_fileio.f90
Go to the documentation of this file.
1 
6 
7 !-----------------------------------------------------------------------------!
16 
17 module m_fileio
18 !-----------------------------------------------------------------------------!
19 !
20 ! +-------+ ALKYON Hydraulic Consultancy & Research
21 ! | | Gerbrant van Vledder
22 ! | +---+
23 ! | | +---+ Last update: 8 Feb. 2003
24 ! +---+ | |
25 ! +---+
26 !
27 ! Module for storing file i/o related variables
28 !
29 ! The values for the parameter i_log, i_prt and iw_tst must be set
30 ! in one of the routines of the host program or in subroutine sys_init
31 !
32 ! Version 1.1 29 May 2000 Initial version
33 ! 1.2 21 Sep. 2001 Form=binary added (B)
34 ! 1.3 5 Oct. 2001 Form=direct access, unformatted, fixed record (R)
35 ! 1.4 24 Aug. 2002 Bug fixed and restructure of test output
36 ! 1.5 8 Feb. 2003 Error check included when incorrect path (Z_FILEIO)
37 !
38 !-----------------------------------------------------------------------------!
39 ! The following two parameters must be set by the user
40 ! They define the overall test level and the output channel
41 !
42 integer,parameter :: i_print=0
44 !
45 integer,parameter :: i_out=6
48 !------------------------------------------------------------------------------
49 !
50 ! Standard switches to activate Logging, Test and Print ouput
51 !
52 integer i_log
53 integer i_prt
54 integer i_tst
55 !
56 !
57 ! Standard unit numbers of input & output files
58 !
59 integer lu_err
60 integer lu_inp
61 integer lu_log
62 integer lu_prt
63 integer lu_tst
64 !
65 contains
66 
67 !-----------------------------------------------------------------------------!
82 
83 subroutine z_fileio(filename,qual,iufind,iunit,iostat) !
84 !-----------------------------------------------------------------------------!
85 !
86 ! +-------+ ALKYON Hydraulic Consultancy & Research
87 ! | | Gerbrant van Vledder
88 ! | +---+
89 ! | | +---+
90 ! +---+ | |
91 ! +---+
92 !
93 USE constants, ONLY: file_endian
94 implicit none
95 !
96 ! 0. Update history
97 !
98 ! 24/07/1999 First version
99 ! 28/09/1999 Module name changed from FILEOPEN -> Z_FILEIO
100 ! 27/10/1999 Option to delete an existing file added
101 ! 18/11/1999 Argument IUNIT used to control use of Z_FLUNIT
102 ! 22/11/1999 Parameter iunit not changed unless by z_flunit
103 ! 28/12/1999 Interface with Z_FLUNIT updated and
104 ! input parameter iufind added
105 ! 14/04/2000 Module m_fileio included in this routine
106 ! 25/05/2000 Module m_fileio excluded, if an already opened file is
107 ! found, the corresponding unit number is assigned to output
108 ! 21/09/2001 Form=binary added, extension to Fortran 95 standard
109 ! 5/10/2001 Form=fixed Record length, as specified in input argument
110 ! 17/06/2002 Initialisation of IUNIT=-1 included
111 ! 24/08/2002 Bug fixed when routine called with IUFIND=0
112 ! 08/02/2003 Bug fixed when file could not be created due to invalid path
113 !
114 ! 1. Purpose
115 !
116 ! Open file with name FILENAME and determine unit number IUNIT
117 ! With file type determined in QUAL
118 !
119 ! Depending on the value of IUFIND a search is performed for a
120 ! free unit number
121 !
122 ! 2. Method
123 !
124 ! If file exists then
125 ! if QUAL = 'D'
126 ! delete file
127 ! Else
128 ! inquire if file opened
129 ! If opened
130 ! determine unit number
131 ! Else
132 ! If iunit >= 10 Find free unit number
133 ! Open file with unit number and file qualifier
134 ! End if
135 ! End if
136 ! Else
137 ! If QUAL='SNU'
138 ! If iunit >= 10 find free unit number
139 ! Open new file with unit number and qualifier
140 ! Else
141 ! Iunit = -1 File does not exist
142 ! End if
143 ! End if
144 !
145 !
146 ! 3. Parameter list
147 !
148 !Type I/O Name Description
149 !----------------------------------------------------
150 character(len=*), intent(in) :: filename
151 character(len=2), intent(in) :: qual
152 integer, intent(in) :: iufind
153 integer, intent(inout) :: iunit
154 integer, intent(out) :: iostat
155 !
156 ! 4. Subroutines used
157 !
158 ! Z_FLUNIT
159 !
160 ! 5. Error messages
161 !
162 ! IUNIT > 0 File exists, is (already) connected to unit number IUNIT, or is
163 ! created and connected to unit number
164 ! IUNIT == 0 File has been deleted or does not exist
165 ! < 0 An error occurred, no file or unit number found
166 !
167 ! IOSTAT = 0 No errors detected
168 ! -1 Incorrect file qualifier
169 ! -2 Unit number does not exist
170 ! -3 Attempt to open non-existing file with status=OLD
171 ! -4 Attempt to open existing file with wrong FORMATTING
172 ! -5 Incorrect value for IUFIND: not in range [0,1]
173 ! -6 File could not be created due to,e.g. incorrect path
174 !
175 ! 6. Remarks
176 !
177 ! 1) Use of file qualifier:
178 !
179 ! 1st char: O(ld),R(eplace),S(cratch),
180 ! U(nknown),(D)elete
181 ! 2nd char: F(ormatted),U(nformatted),B(inary)
182 !
183 ! 2) Use of IUFIND
184 !
185 ! if IUFIND==0, No search is performed for a free unit number
186 ! ==1, A search is performed in routine Z_FLUNIT
187 !
188 ! 3) This routine is based on routine FOR from
189 ! SWAN version 40.00 of Delft University of Technology
190 !
191 !------------------------------------------------------------------------------
192 ! Local variables
193 !
194 character(len=7) :: cstat
195 character(len=11) :: cform
196 integer junit
197 logical lexist
198 logical lopen
199 integer iuerr
200 !-------------------------------------------------------------------------------------
201 ! initialisations
202 !-------------------------------------------------------------------------------------
203 iostat = 0
204 if(iufind==1) iunit = -1
205 !
206 !
207 ! Check value of IUFIND
208 !
209 if(iufind/=0 .and. iufind/=1) then
210  if(i_print >0) write(i_out,*) 'Z_FILEIO: Incorrect value for IUFIND:',iufind
211  iostat = -5
212  goto 9999
213 end if
214 !
215 !
216 ! check input argument QUAL
217 !
218 if(i_print>=1) write(i_out,*) 'Z_FILEIO/A:',trim(filename),' ',qual,iunit,iostat
219 !
220 if (index('ORSUD',qual(1:1)) ==0 .or. index('FUB',qual(2:2)) ==0) then
221  if(i_print > 0) write(i_out,*) 'Incorrect file qualifier'
222  iostat = -1
223 else
224  if(qual(1:1) == 'O') cstat = 'old'
225  if(qual(1:1) == 'R') cstat = 'replace'
226  if(qual(1:1) == 'S') cstat = 'scratch'
227  if(qual(1:1) == 'U') cstat = 'unknown'
228  if(qual(1:1) == 'D') cstat = 'delete'
229 !
230  if(qual(2:2) == 'F') cform = 'formatted'
231  if(qual(2:2) == 'U') cform = 'unformatted'
232  if(qual(2:2) == 'B') cform = 'binary'
233  if(qual(2:2) == 'R') cform = 'unformatted'
234 !
235 ! Check if file exists
236 !
237  inquire(file=filename,exist=lexist)
238  if(i_print >=2) write(i_out,*) 'Z_FILEIO file exists?:',trim(filename),':',lexist
239 !
240 ! delete file if it exists and qual == 'D'
241 !
242  if(lexist .and. qual(1:1)=='D') then
243  inquire(file=filename,opened=lopen)
244  if(lopen) then
245  inquire(file=filename,number=junit)
246  else
247  if(iufind == 1) call z_flunit(iunit,iuerr)
248  junit = iunit
249  if(junit > 0) then
250  if( cform == 'unformatted') then
251  open(file=filename,unit=junit,form=cform,convert=file_endian,iostat=iostat)
252  else
253  open(file=filename,unit=junit,form=cform,iostat=iostat)
254  end if
255  if(iostat/=0) then
256  iostat = -4
257  goto 9999
258  end if
259  end if
260  end if
261  close(junit,status=cstat)
262  goto 9999
263  end if
264 !
265 ! if the file exists, check if it is opened
266 !
267  if(lexist) then
268  if(i_print >=2) write(i_out,*) 'Z_FILEIO: File exists:',trim(filename)
269  inquire(file=filename,opened=lopen)
270  if(lopen) then
271  if(i_print >=2) write(i_out,*) 'Z_FILEIO: File is opened:',trim(filename)
272 !
273 ! determine unit number to which this file is connected
274 ! and assign it to the output number
275 !
276  inquire(file=filename,number=junit)
277  if(i_print >=2) write(i_out,*) 'Z_FILEIO: File is connected to unit:', junit
278  iunit = junit
279  else
280 !
281 ! if the file exists and not connected to a unit number, search a free unit number
282 !
283  if(i_print >=2) write(i_out,*) 'Z_FILEIO: File is not connected to a unit number'
284  if(iufind==0) then
285  if(i_print >=2) write(i_out,*) 'Z_FILEIO: Assign user defined unit number:',iunit
286  elseif(iufind==1) then
287  call z_flunit(iunit,iuerr)
288  if(i_print >=2) write(i_out,*) 'Z_FILEIO: New unit number IUNIT:',iunit
289  end if
290  junit = iunit
291 !
292  if(junit > 0) then
293  if( cform == 'unformatted') then
294  open(file=filename,unit=junit,form=cform,convert=file_endian,status=cstat)
295  else
296  open(file=filename,unit=junit,form=cform,status=cstat)
297  end if
298  else
299  iostat = -2
300  end if
301  end if
302 !
303 ! the file does not exist, so open it and find a free unit number
304 !
305  else
306 !
307  if(i_print>=2) then
308  write(i_out,*) 'Z_FILEIO: File does not exist !'
309  write(i_out,*) 'Z_FILEIO: Qual:',qual(1:1)
310  end if
311 !
312  if(index('SRU',qual(1:1)) > 0) then
313  if(iufind==1) then
314  call z_flunit(iunit,iuerr)
315  if(i_print >=1) write(i_out,*) 'Z_FILEIO: New unit number IUNIT:',iunit
316  end if
317  junit = iunit
318 !
319 ! open file to IUNIT, if possible
320 !
321  if(junit > 0) then
322  if( cform == 'unformatted') then
323  open(file=filename,unit=junit,form=cform,convert=file_endian,iostat=iuerr)
324  else
325  open(file=filename,unit=junit,form=cform,iostat=iuerr)
326  end if
327 !
328 ! check added 8/2/2003
329 !
330  if(iuerr/=0) then
331  iunit = -1
332  iostat = -6
333  end if
334  else
335  iostat = -2
336  end if
337 !
338 ! file cannot be opened because it does not exist
339 !
340  elseif('O'==qual(1:1)) then ! File should exist
341  if(i_print>=2) write(i_out,*) 'Z_FILEIO: File cannot be opened because it does not exist'
342  iostat = -3
343  end if
344  end if
345 end if
346 !
347 9999 continue
348 !
349 if(i_print>=1) write(i_out,*) 'Z_FILEIO/Z:',trim(filename),' ',qual,iunit,iostat
350 !
351 return
352 end subroutine
353 !
354 !-----------------------------------------------------------------------------!
362 
363 subroutine z_fclose(iunit) !
364 !-----------------------------------------------------------------------------!
365 !
366 ! +-------+ ALKYON Hydraulic Consultancy & Research
367 ! | | Gerbrant van Vledder
368 ! | +---+
369 ! | | +---+
370 ! +---+ | |
371 ! +---+
372 !
373 implicit none
374 !
375 ! 0. Update history
376 !
377 ! 0.01 24/08/2000 First version
378 !
379 ! 1. Purpose
380 !
381 ! Close file with unit number IUNIT, and set IUNIT=-1
382 !
383 ! 2. Method
384 !
385 !
386 ! 3. Parameter list
387 !
388 !Type I/O Name Description
389 !-----------------------------------------------------------------------------
390 integer, intent(inout) :: iunit
391 !-----------------------------------------------------------------------------
392 close(iunit)
393 iunit = -1
394 !
395 return
396 end subroutine
397 !
398 !-----------------------------------------------------------------------------!
416 
417 subroutine z_flunit(iunit,ierr) !
418 !-----------------------------------------------------------------------------!
419 !
420 ! +-------+ ALKYON Hydraulic Consultancy & Research
421 ! | | Gerbrant van Vledder
422 ! | +---+
423 ! | | +---+
424 ! +---+ | |
425 ! +---+
426 !
427 implicit none
428 !
429 ! 0. Update history
430 !
431 ! Version Date Modification
432 !
433 ! 0.01 24/07/1999 Initial version
434 ! 0.02 01/10/1999 Extra check added to ensure maximum unit number
435 ! 0.03 07/10/1999 Check of existence of uni number deleted,
436 ! since this test produces different answer
437 ! on Lahey compiler
438 ! 0.04 25/11/1999 Intent added
439 ! 0.05 24/12/1999 Module M_GENVAR added for information about range of unit numbers
440 ! 0.06 27/12/1999 Module M_GENVAR replaced by M_FILEIO
441 ! Check added for forbidden unit numbers
442 ! 0.07 28/12/1999 Internal checks added and IERR added to parameter list
443 ! 0.08 08/02/2000 User of lu_min & lu_max deleted
444 ! 0.09 14/04/2000 Module m_fileio included in this routine
445 !
446 ! 1. Purpose
447 !
448 ! Find a free unit number
449 !
450 ! 2. Method
451 !
452 ! Starting at LU_MIN till LU_MAX are investigated until
453 ! a free (i.e. not connected to a file) is found.
454 ! Use is made of the standard fortran INQUIRE function.
455 ! The values of LU_MIN and LU_MAX should be specified
456 ! in an initialisation routine
457 !
458 ! 3. Parameter list
459 !
460 !Type I/O Name Description
461 !----------------------------------------------------------
462 integer, intent(out) :: iunit
463 integer, intent(out) :: ierr
464 !
465 ! 4. Subroutines used
466 !
467 ! None
468 !
469 ! 5. Error messages
470 !
471 ! ierr=0 No errors encountered
472 ! 1 Invalud combination lu_low >= lu_high
473 ! 2 Invalid value for lu_low
474 ! 3 Invalid value for lu_high
475 ! 4 No free unit number could be found
476 !
477 ! 6. Remarks
478 !
479 ! If no free unit number if found in the range
480 ! lu_min - lu_high, then the function returns IUNIT = -1
481 !
482 ! The switch i_print can be used to generate test output
483 !
484 !----------------------------------------------------------------------------------
485 ! local parameters
486 !
487 integer junit
488 logical lopen
489 logical lnot
490 integer i_not
491 !
492 !---------------------------------------------------------------------------------
493 ! range of unit numbers to search
494 !
495 integer, parameter :: lu_min=60
496 integer, parameter :: lu_max=200
497 !
498 ! specification of forbidden unit numbers
499 !
500 integer, parameter :: lu_nr=3
501 integer lu_not(lu_nr)
502 !----------------------------------------------------------------------------------
503 lu_not(1) = 100
504 lu_not(2) = 101
505 lu_not(3) = 102
506 !-----------------------------------------------------------------------------------
507 !
508 ierr = 0
509 !
510 if(i_print >= 2) then
511  write(i_out,*) 'Z_FLUNIT: forbidden :',lu_not
512  write(i_out,*) 'Z_FLUNIT: lu_min lu_max :',lu_min,lu_max
513 end if
514 !
515 ! check data specified in Module Z_FILEIO
516 !
517 if(lu_min >= lu_max) then
518  ierr = 1
519  write(i_out,*) 'Z_FLUNIT: Incorrect boundaries for LU_MIN & LU_MAX:',&
520 & lu_min,lu_max
521 end if
522 !
523 junit = lu_min
524 !
525 iunit = -1
526 !
527 do while (iunit ==-1)
528 !
529 ! Check if unit number is free, i.e. not in use by an opened file
530 !
531  inquire(unit=junit,opened=lopen)
532 !
533 ! check if unit number is not a forbidden unit number
534 !
535  lnot = .false.
536  do i_not=1,lu_nr
537  if(lu_not(i_not)==junit) then
538  lnot = .true.
539  if(i_print >= 1) write(i_out,*) 'Z_FLUNIT: a forbidden unit number was encountered:',junit
540  end if
541  end do
542 !
543  if(lopen.or.lnot) then
544  junit = junit + 1
545  else
546  iunit = junit
547  end if
548  if(junit > lu_max) exit
549 end do
550 !
551 if(iunit < 0) then
552  write(i_out,*) 'ERROR in Z_FLUNIT: No free unit number could be found'
553 end if
554 !
555 return
556 end subroutine
557 !
558 end module
m_fileio::i_out
integer, parameter i_out
Output channel to screen ==1 screen output for Unix/Linux systems ==6 screen output for Windows.
Definition: mod_fileio.f90:45
m_fileio::z_fclose
subroutine z_fclose(iunit)
Close file with unit number IUNIT, and set IUNIT=-1.
Definition: mod_fileio.f90:364
m_fileio::i_log
integer i_log
(0/1) Logging off/on
Definition: mod_fileio.f90:52
m_fileio::lu_inp
integer lu_inp
standard input file
Definition: mod_fileio.f90:60
m_fileio::lu_prt
integer lu_prt
standard print output
Definition: mod_fileio.f90:62
m_fileio::i_prt
integer i_prt
(0/1) Printing off/on
Definition: mod_fileio.f90:53
m_fileio::lu_log
integer lu_log
standard logging
Definition: mod_fileio.f90:61
file
file(STRINGS ${CMAKE_BINARY_DIR}/switch switch_strings) separate_arguments(switches UNIX_COMMAND $
Definition: CMakeLists.txt:3
m_fileio::i_tst
integer i_tst
(0,1,2...) Test level off/on
Definition: mod_fileio.f90:54
m_fileio::lu_tst
integer lu_tst
standard test output
Definition: mod_fileio.f90:63
constants
Define some much-used constants for global use (all defined as PARAMETER).
Definition: constants.F90:20
m_fileio::z_flunit
subroutine z_flunit(iunit, ierr)
Find a free unit number.
Definition: mod_fileio.f90:418
constants::file_endian
character(*), parameter file_endian
FILE_ENDIAN Filled by preprocessor with 'big_endian', 'little_endian', or 'native'.
Definition: constants.F90:86
m_fileio::lu_err
integer lu_err
standard error file
Definition: mod_fileio.f90:59
m_fileio::i_print
integer, parameter i_print
(0/1/2) Test output printing off/on Output channel defined by i_out
Definition: mod_fileio.f90:42
m_fileio::z_fileio
subroutine z_fileio(filename, qual, iufind, iunit, iostat)
Open file with name FILENAME and determine unit number IUNIT.
Definition: mod_fileio.f90:84
m_fileio
Module for storing file i/o related variables.
Definition: mod_fileio.f90:17