FV3 Bundle
File_Utility.f90
Go to the documentation of this file.
1 !
2 ! File_Utility
3 !
4 ! Module containing generic file utility routines
5 !
6 !
7 ! Written by: Paul van Delst, CIMSS/SSEC 12-Jul-2000
8 ! paul.vandelst@ssec.wisc.edu
9 !
10 ! Copyright (C) 2000, 2006 Paul van Delst
11 !
12 ! This program is free software; you can redistribute it and/or
13 ! modify it under the terms of the GNU General Public License
14 ! as published by the Free Software Foundation; either version 2
15 ! of the License, or (at your option) any later version.
16 !
17 ! This program is distributed in the hope that it will be useful,
18 ! but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 ! GNU General Public License for more details.
21 !
22 ! You should have received a copy of the GNU General Public License
23 ! along with this program; if not, write to the Free Software
24 ! Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 
27 
28 
29  ! ---------------------------
30  ! Disable all implicit typing
31  ! ---------------------------
32 
33  IMPLICIT NONE
34 
35 
36  ! ------------
37  ! Visibilities
38  ! ------------
39 
40  PRIVATE
41  PUBLIC :: get_lun
42  PUBLIC :: file_exists
43  PUBLIC :: file_open
44  PUBLIC :: count_lines_in_file
45 
46 
47  ! --------------------
48  ! Function overloading
49  ! --------------------
50 
51  INTERFACE file_exists
52  MODULE PROCEDURE file_unit_exists
53  MODULE PROCEDURE file_name_exists
54  END INTERFACE file_exists
55 
56  INTERFACE file_open
57  MODULE PROCEDURE file_open_by_unit
58  MODULE PROCEDURE file_open_by_name
59  END INTERFACE file_open
60 
61 
62 CONTAINS
63 
64 
65 !
66 ! Get_Lun
67 !
68 ! Function to obtain a free logical unit number for file access
69 !
70 ! CALLING SEQUENCE:
71 ! Lun = Get_Lun()
72 !
73 ! FUNCTION RESULT:
74 ! Lun: Logical unit number that may be used for file access.
75 ! If Lun > 0 it can be used as a logical unit number to open
76 ! and access a file.
77 ! Lun < 0 a non-existant logical unit number was reached
78 ! during the search.
79 ! UNITS: N/A
80 ! TYPE: INTEGER
81 ! DIMENSION: Scalar
82 !
83 
84  FUNCTION get_lun() RESULT( Lun )
85  INTEGER :: lun
86 
87  ! Initialise logical unit number
88  lun = 9
89 
90  ! Start open loop for Lun Search
91  lun_search: DO
92  lun = lun + 1
93  IF ( .NOT. file_exists( lun ) ) THEN
94  lun = -1
95  EXIT lun_search
96  END IF
97  IF ( .NOT. file_open( lun ) ) EXIT lun_search
98  END DO lun_search
99 
100  END FUNCTION get_lun
101 
102 
103 
104 !
105 ! File_Exists
106 !
107 ! Function to determine if a file unit or a file exists.
108 !
109 ! CALLING SEQUENCE:
110 ! Result = File_Exists( FileID/Filename )
111 !
112 ! INPUT ARGUMENTS:
113 ! Specify one of:
114 !
115 ! FileID: The logical unit number for which the existence
116 ! is to be determined.
117 ! UNITS: N/A
118 ! TYPE: INTEGER
119 ! DIMENSION: Scalar
120 ! ATTRIBUTES: INTENT( IN )
121 ! or
122 !
123 ! Filename: Name of the file the existence of which is to
124 ! be determined.
125 ! UNITS: N/A
126 ! TYPE: CHARACTER( * )
127 ! DIMENSION: Scalar
128 ! ATTRIBUTES: INTENT( IN )
129 !
130 ! FUNCTION RESULT:
131 ! Result: The return value is a logical result.
132 ! If .TRUE. the file unit/file exists.
133 ! .FALSE. the file unit/file does not exist.
134 ! UNITS: N/A
135 ! TYPE: LOGICAL
136 ! DIMENSION: Scalar
137 !
138 
139  FUNCTION file_unit_exists( FileID ) RESULT ( Existence )
140  INTEGER, INTENT( IN ) :: fileid
141  LOGICAL :: existence
142  INQUIRE( unit = fileid, exist = existence )
143  END FUNCTION file_unit_exists
144 
145 
146  FUNCTION file_name_exists( Filename ) RESULT ( Existence )
147  CHARACTER( * ), INTENT( IN ) :: filename
148  LOGICAL :: existence
149  INQUIRE( file = filename, exist = existence )
150  END FUNCTION file_name_exists
151 
152 
153 
154 !
155 ! File_Open
156 !
157 ! Function to determine if a file is open for I/O.
158 !
159 ! CALLING SEQUENCE:
160 ! Result = File_Open( FileID/Filename )
161 !
162 ! INPUT ARGUMENTS:
163 ! Specify one of:
164 !
165 ! FileID: The logical unit number of the file.
166 ! UNITS: N/A
167 ! TYPE: INTEGER
168 ! DIMENSION: Scalar
169 ! ATTRIBUTES: INTENT( IN )
170 ! or
171 !
172 ! Filename: The name of the file.
173 ! UNITS: N/A
174 ! TYPE: CHARACTER( * )
175 ! DIMENSION: Scalar
176 ! ATTRIBUTES: INTENT( IN )
177 !
178 ! FUNCTION RESULT:
179 ! Result: The return value is a logical result.
180 ! If .TRUE. the file is open.
181 ! .FALSE. the file is not open
182 ! UNITS: N/A
183 ! TYPE: LOGICAL
184 ! DIMENSION: Scalar
185 !
186 ! RESTRICTIONS:
187 ! It is assumed the file unit or name exists.
188 !
189 
190  FUNCTION file_open_by_unit( FileID ) RESULT ( Is_Open )
191  INTEGER, INTENT( IN ) :: fileid
192  LOGICAL :: is_open
193  INQUIRE( unit = fileid, opened = is_open )
194  END FUNCTION file_open_by_unit
195 
196 
197  FUNCTION file_open_by_name( Filename ) RESULT ( Is_Open )
198  CHARACTER( * ), INTENT( IN ) :: filename
199  LOGICAL :: is_open
200  INQUIRE( file = filename, opened = is_open )
201  END FUNCTION file_open_by_name
202 
203 
204 
205 !
206 ! Count_Lines_in_File
207 !
208 ! Function to count the number of lines in an ASCII file
209 !
210 ! CALLING SEQUENCE:
211 ! nLines = Count_Lines_in_File( Filename, &
212 ! NoComment=NoComment, &
213 ! NoBlank=NoBlank )
214 !
215 ! INPUT ARGUMENTS:
216 ! Filename: Character string specifying the name of the
217 ! ASCII file
218 ! UNITS: N/A
219 ! TYPE: CHARACTER(*)
220 ! DIMENSION: Scalar
221 ! ATTRIBUTES: INTENT(IN)
222 !
223 ! OPTIONAL INPUT ARGUMENTS:
224 ! NoComment: Set this argument to a single character used to
225 ! specify a comment line in the input file when the
226 ! character is encountered in the first column.
227 ! If specified, comment lines are NOT included
228 ! in the line count.
229 ! Default action to count ALL lines.
230 ! ASCII file
231 ! UNITS: N/A
232 ! TYPE: CHARACTER(*)
233 ! DIMENSION: Scalar
234 ! ATTRIBUTES: INTENT(IN)
235 !
236 ! NoBlank: Set this argument to a non-zero value to skip
237 ! blank lines in the line count.
238 ! If == 0, blank lines are counted [DEFAULT]
239 ! /= 0, blank lines are NOT counted.
240 ! Default action to count ALL lines.
241 ! UNITS: N/A
242 ! TYPE: CHARACTER(*)
243 ! DIMENSION: Scalar
244 ! ATTRIBUTES: INTENT(IN)
245 !
246 ! FUNCTION RESULT:
247 ! nLines: The number of lines in the file. If it equals
248 ! zero, then the file line count could not be
249 ! determined.
250 ! UNITS: N/A
251 ! TYPE: INTEGER
252 ! DIMENSION: Scalar
253 !
254 
255  FUNCTION count_lines_in_file( Filename, NoComment, NoBlank ) RESULT ( nLines )
257  ! Arguments
258  CHARACTER(*), INTENT(IN) :: filename
259  CHARACTER(*), OPTIONAL, INTENT(IN) :: nocomment
260  INTEGER, OPTIONAL, INTENT(IN) :: noblank
261 
262  ! Function result
263  INTEGER :: nlines
264 
265  ! Local variables
266  CHARACTER(1) :: cchar
267  LOGICAL :: skipcomment
268  LOGICAL :: skipblank
269  CHARACTER(5000) :: buffer
270  INTEGER :: io_status
271  INTEGER :: fileid
272  INTEGER :: n
273 
274  ! Set default return value
275  nlines = 0
276 
277  ! Check arguments
278  IF ( .NOT. file_exists( filename ) ) RETURN
279 
280  skipcomment = .false.
281  IF ( PRESENT(nocomment) ) THEN
282  IF ( len(nocomment) > 0 ) THEN
283  cchar = nocomment(1:1)
284  skipcomment = .true.
285  END IF
286  END IF
287 
288  skipblank = .false.
289  IF ( PRESENT(noblank) ) THEN
290  IF ( noblank /= 0 ) skipblank = .true.
291  END IF
292 
293  ! Open the file for reading only
294  fileid = get_lun()
295  IF ( fileid < 0 ) RETURN
296  OPEN( fileid, file = filename, &
297  status = 'OLD', &
298  access = 'SEQUENTIAL', &
299  form = 'FORMATTED', &
300  action = 'READ', &
301  iostat = io_status )
302  IF ( io_status /= 0 ) RETURN
303 
304  ! Initialise line counter
305  n = 0
306 
307  ! Begin open loop
308  count_loop: DO
309 
310  ! Read a line of the file
311  READ( fileid, fmt = '( a )', &
312  iostat = io_status ) buffer
313 
314  ! Check for an error
315  IF ( io_status > 0 ) THEN
316  CLOSE( fileid )
317  RETURN
318  END IF
319 
320  ! Check for end-of-file
321  IF ( io_status < 0 ) THEN
322  CLOSE( fileid )
323  EXIT count_loop
324  END IF
325 
326  ! Check for comment
327  IF ( skipcomment ) THEN
328  IF ( buffer(1:1) == cchar ) cycle count_loop
329  END IF
330 
331  ! Check for blank line
332  IF ( skipblank ) THEN
333  IF ( len_trim(buffer) == 0 ) cycle count_loop
334  END IF
335 
336  ! Update line count
337  n = n + 1
338 
339  END DO count_loop
340 
341  ! Assign the final count
342  nlines = n
343 
344  END FUNCTION count_lines_in_file
345 
346 END MODULE file_utility
347 
348 
349 !-------------------------------------------------------------------------------
350 ! -- MODIFICATION HISTORY --
351 !-------------------------------------------------------------------------------
352 !
353 ! $Id: File_Utility.f90 60152 2015-08-13 19:19:13Z paul.vandelst@noaa.gov $
354 !
355 ! $Date: 2006/03/17 21:05:12 $
356 !
357 ! $Revision: 60152 $
358 !
359 ! $Name: $
360 !
361 ! $State: Exp $
362 !
363 ! $Log: File_Utility.f90,v $
364 ! Revision 1.15 2006/03/17 21:05:12 paulv
365 ! - Stripped out the mod block.
366 ! - Simplified header documentation.
367 ! - Modified Count_Lines_in_File() function to handle comment and blank
368 ! lines if required.
369 !
370 ! Revision 1.14 2006/02/15 22:53:55 paulv
371 ! - Added ASCII file line count function.
372 !
373 ! Revision 1.13 2005/04/01 15:20:51 paulv
374 ! - Uncommented END INTERFACE names.
375 !
376 ! Revision 1.12 2004/08/11 20:34:41 paulv
377 ! - Updated.
378 !
379 ! Revision 1.11 2002/05/15 17:59:54 paulv
380 ! - Overloaded FILE_EXISTS() functions from FILE_UNITS_EXISTS() and FILE_NAME_EXISTS()
381 ! functions.
382 ! - Added test for file unit existence to the GET_LUN() function.
383 !
384 ! Revision 1.10 2001/10/24 17:36:18 paulv
385 ! - Changed the way in which module subprograms are declared PUBLIC or PRIVATE
386 ! so code would compile using pgf90 3.2-4a. The compiler has a bug, dammit.
387 !
388 ! Revision 1.9 2001/09/28 19:33:36 paulv
389 ! - Updated FILE_OPEN subprogram header documentation.
390 !
391 ! Revision 1.8 2001/09/24 02:54:21 paulv
392 ! - Overloaded FILE_OPEN function to allow inquiry by unit or file name.
393 !
394 ! Revision 1.7 2001/09/23 19:49:54 paulv
395 ! - Removed file_open logical variable from GET_LUN function. Argh.
396 !
397 ! Revision 1.6 2001/09/23 19:38:17 paulv
398 ! - Added CVS "Name" to modification history keyword list.
399 !
400 ! Revision 1.5 2001/09/23 19:29:14 paulv
401 ! - Corrected bug in FILE_OPEN argument type specification
402 ! - Use FILE_OPEN() function in GET_LUN()
403 ! - Updated header documentation
404 !
405 ! Revision 1.4 2001/09/17 20:11:09 paulv
406 ! - Module now resides in the UTILITY module directory.
407 ! - Added FILE_OPEN function.
408 !
409 ! Revision 1.3 2000/08/31 19:36:32 paulv
410 ! - Added documentation delimiters.
411 ! - Updated documentation headers.
412 !
413 ! Revision 1.2 2000/08/24 15:33:42 paulv
414 ! - In the GET_LUN subprogram, the loop to search for a free unit number
415 ! was changed from:
416 !
417 ! DO WHILE ( file_open )
418 ! ...search
419 ! END DO
420 !
421 ! to
422 !
423 ! lun_search: DO
424 ! ...search
425 ! IF ( .NOT. file_open ) EXIT lun_search
426 ! END DO lun_search
427 !
428 ! The earlier version is a deprecated use of the DO with WHILE.
429 !
430 ! - The subprogram FILE_EXISTS was added. Note that the INQUIRE statement
431 ! required the FILE = keyword to work. Simply using the file name in
432 ! the INQUIRE returned an error (compiler assumed it was an inquire by
433 ! unit number?)
434 ! - Updated module and subprogram documentation.
435 !
436 ! Revision 1.1 2000/07/12 16:08:10 paulv
437 ! Initial checked in version
438 !
439 !
440 !
441 
logical function file_open_by_unit(FileID)
logical function file_name_exists(Filename)
integer function, public get_lun()
logical function file_unit_exists(FileID)
integer function, public count_lines_in_file(Filename, NoComment, NoBlank)
logical function file_open_by_name(Filename)