|
8 | 8 | h5fget_obj_count_f, h5fget_obj_ids_f, h5fget_name_f, &
|
9 | 9 | h5sselect_hyperslab_f, h5screate_simple_f, &
|
10 | 10 | H5Sget_simple_extent_ndims_f, H5Sget_simple_extent_dims_f, H5Sget_simple_extent_npoints_f, &
|
11 |
| -H5F_ACC_RDONLY_F, H5F_ACC_RDWR_F, H5F_ACC_TRUNC_F, & |
| 11 | +H5F_ACC_RDONLY_F, H5F_ACC_RDWR_F, H5F_ACC_TRUNC_F, H5F_ACC_EXCL_F, & |
12 | 12 | H5F_OBJ_FILE_F, H5F_OBJ_GROUP_F, H5F_OBJ_DATASET_F, H5F_OBJ_DATATYPE_F, H5F_OBJ_ALL_F, &
|
13 | 13 | H5D_CONTIGUOUS_F, H5D_CHUNKED_F, H5D_COMPACT_F, &
|
14 | 14 | H5I_FILE_F, &
|
|
35 | 35 |
|
36 | 36 | module procedure h5open
|
37 | 37 |
|
38 |
| -character(2) :: laction |
39 | 38 | integer :: ier
|
40 | 39 | integer(HID_T) :: fapl !< file access property list
|
41 |
| -integer :: file_mode |
42 | 40 |
|
43 | 41 | if(present(ok)) ok = .true.
|
44 | 42 |
|
| 43 | +if(present(debug)) self%debug = debug |
| 44 | + |
45 | 45 | if(self%is_open()) then
|
46 | 46 | write(stderr, '(a)') 'NOTICE:h5fortran:open: file handle already open: '//self%filename
|
47 | 47 | return
|
48 | 48 | endif
|
49 | 49 |
|
50 |
| -laction = 'r' |
51 |
| -if (present(action)) laction = action |
| 50 | +!> Initialize FORTRAN interface |
| 51 | +!! HDF5 1.14.0 introduced bug that if H5open_f is called more than once, |
| 52 | +!! it will error. |
| 53 | +if (.not. hdf5_is_initialized()) then |
| 54 | + if(self%debug) print '(a)', 'TRACE:h5fortran:h5open: initializing HDF5 library' |
| 55 | + call H5open_f(ier) |
| 56 | + call estop(ier, 'h5open:H5open HDF5 library initialize', self%filename, ok=ok) |
| 57 | + if (present(ok)) then |
| 58 | + if (.not. ok) return |
| 59 | + endif |
| 60 | +endif |
52 | 61 |
|
53 |
| -self%filename = filename |
| 62 | +!! these enums will all be 0 if h5open_f isn't called first |
| 63 | +! print *, "TRACE: self%file_mode = ", self%file_mode, " filename = ", filename |
| 64 | +! print *, "TRACE: H5F_ACC_RDONLY_F = ", H5F_ACC_RDONLY_F |
| 65 | +! print *, "TRACE: H5F_ACC_RDWR_F = ", H5F_ACC_RDWR_F |
| 66 | +! print *, "TRACE: H5F_ACC_TRUNC_F = ", H5F_ACC_TRUNC_F |
54 | 67 |
|
55 |
| -if(present(debug)) self%debug = debug |
| 68 | +if (present(action)) then |
| 69 | + select case(action) |
| 70 | + case('r') |
| 71 | + self%file_mode = H5F_ACC_RDONLY_F |
| 72 | + case('r+') |
| 73 | + self%file_mode = H5F_ACC_RDWR_F |
| 74 | + case('rw', 'a') |
| 75 | + if(is_hdf5(filename)) then |
| 76 | + self%file_mode = H5F_ACC_RDWR_F |
| 77 | + else |
| 78 | + self%file_mode = H5F_ACC_TRUNC_F |
| 79 | + endif |
| 80 | + case ('w') |
| 81 | + self%file_mode = H5F_ACC_TRUNC_F |
| 82 | + case default |
| 83 | + call estop(ier, 'ERROR:h5fortran:open Unsupported action=' // action, filename, ok=ok) |
| 84 | + if (present(ok)) then |
| 85 | + if(.not. ok) return |
| 86 | + endif |
| 87 | + end select |
| 88 | +elseif (self%filename == filename .and. any(self%file_mode == [H5F_ACC_RDONLY_F, H5F_ACC_RDWR_F])) then |
| 89 | + if(self%debug) print '(3a,i0)', 'NOTICE:h5fortran:open: ', filename, ' reusing file mode ', self%file_mode |
| 90 | +else |
| 91 | + self%file_mode = H5F_ACC_RDONLY_F |
| 92 | + if(self%debug) print '(a)', 'NOTICE:h5fortran:open: no action specified, defaulting to read-only mode' |
| 93 | +endif |
| 94 | + |
| 95 | +self%filename = filename |
| 96 | +!! do this AFTER the action= switch |
56 | 97 |
|
57 | 98 | !> compression parameter
|
58 |
| -if(present(comp_lvl) .and. laction /= "r") self%comp_lvl = comp_lvl |
| 99 | +if(present(comp_lvl) .and. self%file_mode /= H5F_ACC_RDONLY_F) self%comp_lvl = comp_lvl |
| 100 | + |
59 | 101 | if(self%comp_lvl > 0) then
|
60 | 102 | self%shuffle = .true.
|
61 | 103 | self%fletcher32 = .true.
|
|
72 | 114 | self%comp_lvl = 9
|
73 | 115 | endif
|
74 | 116 |
|
75 |
| -!> Initialize FORTRAN interface |
76 |
| -!! HDF5 1.14.0 introduced bug that if H5open_f is called more than once, |
77 |
| -!! it will error. |
78 |
| -if (.not. hdf5_is_initialized()) then |
79 |
| - if(self%debug) print '(a)', 'TRACE:h5fortran:h5open: initializing HDF5 library' |
80 |
| - call H5open_f(ier) |
81 |
| - call estop(ier, 'h5open:H5open HDF5 library initialize', filename, ok=ok) |
82 |
| - if (present(ok)) then |
83 |
| - if (.not. ok) return |
84 |
| - endif |
85 |
| -endif |
86 |
| - |
87 | 117 | if(self%debug) then
|
88 | 118 | call H5Eset_auto_f(1, ier)
|
89 | 119 | else
|
90 | 120 | call H5Eset_auto_f(0, ier)
|
91 | 121 | endif
|
92 |
| -call estop(ier, 'h5open:H5Eset_auto: HDF5 library set traceback', filename, ok=ok) |
| 122 | +call estop(ier, 'h5open:H5Eset_auto: HDF5 library set traceback', self%filename, ok=ok) |
93 | 123 | if (present(ok)) then
|
94 | 124 | if(.not. ok) return
|
95 | 125 | endif
|
96 | 126 |
|
97 |
| -select case(laction) |
98 |
| -case('r') |
99 |
| - file_mode = H5F_ACC_RDONLY_F |
100 |
| -case('r+') |
101 |
| - file_mode = H5F_ACC_RDWR_F |
102 |
| -case('rw', 'a') |
103 |
| - if(is_hdf5(filename)) then |
104 |
| - file_mode = H5F_ACC_RDWR_F |
105 |
| - else |
106 |
| - file_mode = H5F_ACC_TRUNC_F |
107 |
| - endif |
108 |
| -case ('w') |
109 |
| - file_mode = H5F_ACC_TRUNC_F |
110 |
| -case default |
111 |
| - call estop(ier, 'ERROR:h5fortran:open Unsupported action ' // laction, filename, ok=ok) |
112 |
| - if (present(ok)) then |
113 |
| - if(.not. ok) return |
114 |
| - endif |
115 |
| - |
116 |
| -end select |
117 |
| - |
118 | 127 | fapl = H5P_DEFAULT_F
|
119 | 128 |
|
120 |
| -!! these enums will all be 0 if h5open_f isn't called first |
121 |
| -! print *, "TRACE: file_mode = ", file_mode, " filename = ", filename |
122 |
| -! print *, "TRACE: H5F_ACC_RDONLY_F = ", H5F_ACC_RDONLY_F |
123 |
| -! print *, "TRACE: H5F_ACC_RDWR_F = ", H5F_ACC_RDWR_F |
124 |
| -! print *, "TRACE: H5F_ACC_TRUNC_F = ", H5F_ACC_TRUNC_F |
125 |
| - |
126 |
| - |
127 |
| -if (file_mode == H5F_ACC_RDONLY_F .or. file_mode == H5F_ACC_RDWR_F) then |
| 129 | +if (any(self%file_mode == [H5F_ACC_RDONLY_F, H5F_ACC_RDWR_F])) then |
128 | 130 | if(.not. is_hdf5(filename)) then
|
129 |
| - error stop "ERROR:h5fortran:open: action=" // laction // " not an HDF5 file: " // filename |
| 131 | + write(stderr, '(a,i0)') "ERROR:h5fortran:open: is not an HDF5 file: " // self%filename // " file mode ", self%file_mode |
| 132 | + if (present(ok)) then |
| 133 | + ok = .false. |
| 134 | + return |
| 135 | + else |
| 136 | + error stop |
| 137 | + endif |
130 | 138 | endif
|
131 |
| - call H5Fopen_f(filename, file_mode, self%file_id, ier, access_prp=fapl) |
132 |
| - call estop(ier, "h5open:H5Fopen", filename, ok=ok) |
| 139 | + call H5Fopen_f(self%filename, self%file_mode, self%file_id, ier, access_prp=fapl) |
| 140 | + call estop(ier, "h5open:H5Fopen", self%filename, ok=ok) |
133 | 141 | if (present(ok)) then
|
134 | 142 | if(.not. ok) return
|
135 | 143 | endif
|
136 |
| -elseif(file_mode == H5F_ACC_TRUNC_F) then |
137 |
| - call H5Fcreate_f(filename, file_mode, self%file_id, ier, access_prp=fapl) |
138 |
| - call estop(ier, "h5open:H5Fcreate", filename, ok=ok) |
| 144 | +elseif(self%file_mode == H5F_ACC_TRUNC_F) then |
| 145 | + call H5Fcreate_f(self%filename, self%file_mode, self%file_id, ier, access_prp=fapl) |
| 146 | + call estop(ier, "h5open:H5Fcreate", self%filename, ok=ok) |
139 | 147 | if (present(ok)) then
|
140 | 148 | if(.not. ok) return
|
141 | 149 | endif
|
142 | 150 | else
|
143 |
| - error stop "ERROR:h5fortran:open: Unsupported file mode: " // filename |
| 151 | + error stop "ERROR:h5fortran:open: Unsupported file mode: " // self%filename |
144 | 152 | endif
|
145 | 153 |
|
146 | 154 | end procedure h5open
|
|
0 commit comments