Skip to content

Commit e72ca2d

Browse files
committed
check function, version prop
doc
1 parent eb4b718 commit e72ca2d

File tree

7 files changed

+78
-133
lines changed

7 files changed

+78
-133
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ It's possible to do these things, if there is user need.
4242
Requirements:
4343

4444
* modern Fortran compiler (this project uses `submodule` and `error stop`). For example, Gfortran ≥ 6.
45-
* HDF5 Fortran library (1.8 or 1.10)
45+
* HDF5 Fortran library (>= 1.8.7, including 1.10.x and 1.12.x)
4646
* Mac / Homebrew: `brew install gcc hdf5`
4747
* Linux: `apt install gfortran libhdf5-dev`
4848
* Windows Subsystem for Linux: `apt install gfortran libhdf5-dev`

src/hdf5_interface.f90

Lines changed: 42 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ module h5fortran
33
use, intrinsic :: iso_c_binding, only : c_ptr, c_loc
44
use, intrinsic :: iso_fortran_env, only : real32, real64, int32, int64, stderr=>error_unit
55
use hdf5, only : HID_T, SIZE_T, HSIZE_T, H5F_ACC_RDONLY_F, H5F_ACC_RDWR_F, H5F_ACC_TRUNC_F, &
6-
h5open_f, h5close_f, h5gcreate_f, h5gclose_f, h5fopen_f, h5fcreate_f, h5fclose_f, h5lexists_f
6+
h5open_f, h5close_f, h5gcreate_f, h5gclose_f, h5fopen_f, h5fcreate_f, h5fclose_f, h5lexists_f, &
7+
h5get_libversion_f, h5eset_auto_f
78

89
use string_utils, only : toLower, strip_trailing_null, truncate_string_null
910

@@ -21,7 +22,8 @@ module h5fortran
2122

2223
integer :: comp_lvl = 0 !< compression level (1-9) 0: disable compression
2324
integer(HSIZE_T) :: chunk_size(7) = [1,1,1,1,1,1,1] !< chunk size per dimension
24-
logical :: verbose=.false.
25+
logical :: verbose=.true.
26+
integer :: libversion(3) !< major, minor, rel
2527

2628
contains
2729
!> initialize HDF5 file
@@ -38,7 +40,7 @@ module h5fortran
3840
hdf_read_4d,hdf_read_5d, hdf_read_6d, hdf_read_7d
3941

4042
!> private methods
41-
procedure,public :: hdf_write_group, &
43+
procedure,private :: hdf_write_group, &
4244
hdf_write_scalar, hdf_write_1d, hdf_write_2d, hdf_write_3d, &
4345
hdf_write_4d, hdf_write_5d, hdf_write_6d, hdf_write_7d, &
4446
hdf_read_scalar, hdf_read_1d, hdf_read_2d, hdf_read_3d, &
@@ -228,13 +230,13 @@ end subroutine writeattr
228230
integer, parameter :: ENOENT = 2, EIO = 5
229231

230232
private
231-
public :: hdf5_file, toLower, hsize_t, strip_trailing_null, truncate_string_null
233+
public :: hdf5_file, toLower, hsize_t, strip_trailing_null, truncate_string_null, check
232234

233235

234236
contains
235237

236238

237-
subroutine hdf_initialize(self,filename,ierr, status,action,comp_lvl,chunk_size)
239+
subroutine hdf_initialize(self,filename,ierr, status,action,comp_lvl,chunk_size,verbose)
238240
!! Opens hdf5 file
239241

240242
class(hdf5_file), intent(inout) :: self
@@ -244,6 +246,7 @@ subroutine hdf_initialize(self,filename,ierr, status,action,comp_lvl,chunk_size)
244246
character(*), intent(in), optional :: action
245247
integer, intent(in), optional :: comp_lvl
246248
integer, intent(in), optional :: chunk_size(:)
249+
logical, intent(in), optional :: verbose
247250

248251
character(:), allocatable :: lstatus, laction
249252
logical :: exists
@@ -254,13 +257,23 @@ subroutine hdf_initialize(self,filename,ierr, status,action,comp_lvl,chunk_size)
254257

255258
if (present(comp_lvl)) self%comp_lvl = comp_lvl
256259
if (present(chunk_size)) self%chunk_size(1:size(chunk_size)) = chunk_size
260+
if (present(verbose)) self%verbose = verbose
257261

258262
!> Initialize FORTRAN interface.
259263
call h5open_f(ierr)
260-
if (ierr /= 0) then
261-
write(stderr,*) 'ERROR: HDF5 library initialize'
262-
return
264+
if (check(ierr, 'ERROR: HDF5 library initialize')) return
265+
266+
!> get library version
267+
call h5get_libversion_f(self%libversion(1), self%libversion(2), self%libversion(3), ierr)
268+
! if (self%verbose) print '(A,3I3)', 'HDF5 version: ',self%libversion
269+
if (check(ierr, 'ERROR: HDF5 library get version')) return
270+
271+
if(self%verbose) then
272+
call h5eset_auto_f(1, ierr)
273+
else
274+
call h5eset_auto_f(0, ierr)
263275
endif
276+
if (check(ierr, 'ERROR: HDF5 library set traceback')) return
264277

265278
lstatus = 'old'
266279
if(present(status)) lstatus = toLower(status)
@@ -277,34 +290,24 @@ subroutine hdf_initialize(self,filename,ierr, status,action,comp_lvl,chunk_size)
277290
if (.not.exists) then
278291
write(stderr,*) 'ERROR: ' // filename // ' does not exist.'
279292
ierr = ENOENT
280-
return
281293
endif
282294
call h5fopen_f(filename,H5F_ACC_RDONLY_F,self%lid,ierr)
283295
case('write','readwrite','w','rw', 'r+', 'append', 'a')
284296
call h5fopen_f(filename,H5F_ACC_RDWR_F,self%lid,ierr)
285-
if (ierr /= 0) then
286-
write(stderr,*) 'ERROR: ' // filename // ' could not be opened'
287-
ierr = EIO
288-
return
289-
endif
297+
if (check(ierr, 'ERROR: ' // filename // ' could not be opened')) return
290298
case default
291299
write(stderr,*) 'Unsupported action -> ' // laction
292300
ierr = 128
293-
return
294301
endselect
295302
case('new','replace')
296303
call h5fcreate_f(filename, H5F_ACC_TRUNC_F, self%lid, ierr)
297-
if (ierr /= 0) then
298-
write(stderr,*) 'ERROR: ' // filename // ' could not be created'
299-
ierr = EIO
300-
return
301-
endif
304+
if (check(ierr, 'ERROR: ' // filename // ' could not be created')) return
302305
case default
303306
write(stderr,*) 'Unsupported status -> '// lstatus
304307
ierr = 128
305-
return
306308
endselect
307309

310+
308311
end subroutine hdf_initialize
309312

310313

@@ -314,14 +317,11 @@ subroutine hdf_finalize(self, ierr)
314317

315318
!> close hdf5 file
316319
call h5fclose_f(self%lid, ierr)
317-
if (ierr /= 0) then
318-
write(stderr,*) 'ERROR: HDF5 file close: ' // self%filename
319-
return
320-
endif
320+
if (check(ierr, 'ERROR: HDF5 file close: ' // self%filename)) return
321321

322322
!> Close Fortran interface.
323323
call h5close_f(ierr)
324-
if (ierr /= 0) write(stderr,*) 'ERROR: HDF5 library close'
324+
if (check(ierr, 'ERROR: HDF5 library close')) return
325325

326326
end subroutine hdf_finalize
327327

@@ -351,26 +351,30 @@ subroutine hdf_write_group(self, gname, ierr)
351351
! check subgroup exists
352352
sp = sp + ep
353353
call h5lexists_f(self%lid, gname(1:sp-1), gexist, ierr)
354-
if (ierr /= 0) then
355-
write(stderr,*) 'ERROR: did not find group ' // gname // ' in ' // self%filename
356-
return
357-
endif
354+
if (check(ierr, 'ERROR: did not find group ' // gname // ' in ' // self%filename)) return
358355

359356
if(.not.gexist) then
360357
call h5gcreate_f(self%lid, gname(1:sp-1), gid, ierr)
361-
if (ierr /= 0) then
362-
write(stderr,*) 'ERROR: creating group ' // gname // ' in ' // self%filename
363-
return
364-
endif
358+
if (check(ierr, 'ERROR: creating group ' // gname // ' in ' // self%filename)) return
365359

366360
call h5gclose_f(gid, ierr)
367-
if (ierr /= 0) then
368-
write(stderr,*) 'ERROR: closing group ' // gname // ' in ' // self%filename
369-
return
370-
endif
361+
if (check(ierr, 'ERROR: closing group ' // gname // ' in ' // self%filename)) return
371362
endif
372363
end do
373364

374365
end subroutine hdf_write_group
375366

367+
368+
logical function check(ierr, msg)
369+
integer, intent(in) :: ierr
370+
character(*), intent(in) :: msg
371+
372+
check = ierr /= 0
373+
if (.not.check) return
374+
375+
write(stderr, *) msg
376+
377+
end function check
378+
379+
376380
end module h5fortran

src/read.f90

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
endif
3030

3131
call h5ltget_dataset_info_f(self%lid, dname, dims, dtype, dsize, ierr)
32-
if (ierr /= 0) write(stderr,*) 'ERROR: open ' // dname // ' read ' // self%filename
32+
if (check(ierr, 'ERROR: open ' // dname // ' read ' // self%filename)) return
3333

3434
end procedure hdf_setup_read
3535

@@ -48,14 +48,11 @@
4848
endif
4949

5050
call h5ltget_dataset_ndims_f(self%lid, dname, drank, ierr)
51-
if (ierr /= 0) then
52-
write(stderr,*) 'ERROR: '// dname // ' rank ' // self%filename
53-
return
54-
endif
51+
if (check(ierr, 'ERROR: '// dname // ' rank ' // self%filename)) return
5552

5653
allocate(dims(drank))
5754
call h5ltget_dataset_info_f(self%lid, dname, dims, dtype, dsize, ierr)
58-
if (ierr /= 0) write(stderr,*) 'ERROR: ' // dname // ' info ' // self%filename
55+
if (check(ierr, 'ERROR: ' // dname // ' info ' // self%filename)) return
5956

6057
end procedure hdf_get_shape
6158

src/tests/test_error.f90

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ subroutine test_nonexist_old_file(path)
3939
character(*), intent(in) :: path
4040
integer :: ierr
4141

42-
call h5f%initialize(path//'/not-exist', ierr, status='old', action='read')
42+
call h5f%initialize(path//'/not-exist', ierr, status='old', action='read', verbose=.false.)
4343
if (ierr==0) error stop 'should have had ierr/=0 on non-existing old file'
4444
end subroutine test_nonexist_old_file
4545

@@ -48,7 +48,7 @@ subroutine test_nonexist_unknown_file(path)
4848
character(*), intent(in) :: path
4949
integer :: ierr
5050

51-
call h5f%initialize(path//'/not-exist', ierr, status='unknown', action='read')
51+
call h5f%initialize(path//'/not-exist', ierr, status='unknown', action='read', verbose=.false.)
5252
if (ierr==0) error stop 'should have had ierr/=0 on non-existing unknown read file'
5353
end subroutine test_nonexist_unknown_file
5454

@@ -75,7 +75,7 @@ subroutine test_nonexist_variable(path)
7575
character(:), allocatable :: filename
7676

7777
filename = path // '/junk.h5'
78-
call h5f%initialize(filename, ierr, status='replace', action='readwrite')
78+
call h5f%initialize(filename, ierr, status='replace', action='readwrite', verbose=.false.)
7979
if(ierr/=0) error stop 'test_nonexist_variable: opening file'
8080
call h5f%read('/not-exist', u, ierr)
8181
if(ierr==0) error stop 'test_nonexist_variable: should have ierr/=0 on non-exist variable'
@@ -90,14 +90,14 @@ subroutine test_wrong_type(path)
9090
character(:), allocatable :: filename
9191

9292
filename = path // '/junk.h5'
93-
call h5f%initialize(filename, ierr, status='replace', action='write')
93+
call h5f%initialize(filename, ierr, status='replace', action='write', verbose=.false.)
9494
if(ierr/=0) error stop 'test_wrong_type: creating file'
9595
call h5f%write('/real32', 42., ierr)
9696
if(ierr/=0) error stop 'test_wrong_type: writing test variable'
9797
call h5f%finalize(ierr)
9898
if (ierr/=0) error stop 'test_nonexist_variable: finalizing'
9999

100-
call h5f%initialize(filename, ierr, status='old', action='read')
100+
call h5f%initialize(filename, ierr, status='old', action='read', verbose=.false.)
101101
if(ierr/=0) error stop 'test_wrong_type: opening file'
102102
call h5f%read('/real32', u, ierr)
103103
if(ierr/=0) then
@@ -119,7 +119,7 @@ subroutine test_unknown_write(path)
119119
x = (1, -1)
120120

121121
filename = path // '/junk.h5'
122-
call h5f%initialize(filename, ierr, status='replace', action='write')
122+
call h5f%initialize(filename, ierr, status='replace', action='write', verbose=.false.)
123123
if(ierr/=0) error stop 'test_unknown_write: creating file'
124124
call h5f%write('/complex', x, ierr)
125125
if(ierr==0) error stop 'test_unknown_write: writing unknown type variable'
@@ -135,7 +135,7 @@ subroutine test_unknown_read(path)
135135
x = (1, -1)
136136

137137
filename = path // '/junk.h5'
138-
call h5f%initialize(filename, ierr, status='unknown', action='readwrite')
138+
call h5f%initialize(filename, ierr, status='unknown', action='readwrite', verbose=.false.)
139139
if(ierr/=0) error stop 'test_unknown_read: opening file'
140140
call h5f%read('/complex', x, ierr)
141141
if(ierr==0) error stop 'test_unknown_read: reading unknown type variable'

0 commit comments

Comments
 (0)