@@ -10,15 +10,16 @@ module m_error_v_manager
1010 private
1111
1212 type (ErrorV), dimension (:), allocatable :: instance_array
13+ ! MZ : Do we really need instance_available?
1314 logical , dimension (:), allocatable :: instance_available
1415
1516 ! TODO: think about ordering here, alphabetical probably easiest
16- public :: build_instance, finalise_instance, get_available_instance_index, get_instance, set_instance_index_to , &
17- ensure_instance_array_size_is_at_least
17+ public :: build_instance, finalise_instance, get_available_instance_index, get_instance, get_error_message , &
18+ set_instance_index_to, ensure_array_capacity_for_instances,deallocate_instance_arrays
1819
1920contains
2021
21- function build_instance (code , message ) result(instance_index)
22+ function build_instance (code , message , cause ) result(instance_index)
2223 ! ! Build an instance
2324
2425 integer , intent (in ) :: code
@@ -27,12 +28,14 @@ function build_instance(code, message) result(instance_index)
2728 character (len=* ), optional , intent (in ) :: message
2829 ! ! Error message
2930
31+ integer , optional , intent (in ) :: cause
32+
3033 integer :: instance_index
3134 ! ! Index of the built instance
3235
33- call ensure_instance_array_size_is_at_least (1 )
36+ call ensure_array_capacity_for_instances (1 )
3437 call get_available_instance_index(instance_index)
35- call instance_array(instance_index) % build(code= code, message= message)
38+ call instance_array(instance_index) % build(code= code, message= message, cause = cause )
3639
3740 end function build_instance
3841
@@ -82,7 +85,7 @@ subroutine get_available_instance_index(available_instance_index)
8285
8386 ! TODO: switch to returning a Result type with an error set
8487 ! res = ResultInt(ErrorV(code=1, message="No available instances"))
85- print * , " print"
88+ print * , " print dioooo "
8689 error stop 1
8790
8891 end subroutine get_available_instance_index
@@ -97,6 +100,8 @@ function get_instance(instance_index) result(err_inst)
97100 ! ! Instance at `instance_array(instance_index)`
98101
99102 type (ErrorV) :: err_check_index_claimed
103+
104+ integer :: cause
100105 character (len= 20 ) :: idx_str
101106 character (len= :), allocatable :: msg
102107
@@ -107,39 +112,46 @@ function get_instance(instance_index) result(err_inst)
107112 err_inst = instance_array(instance_index)
108113
109114 else
115+
110116 write (idx_str, " (I0)" ) instance_index
111117 msg = " Error at get_instance -> " // trim (adjustl (idx_str))
112118
113- err_inst = ErrorV( &
119+ cause = build_instance(code= err_check_index_claimed % code, message= err_check_index_claimed % message)
120+
121+ call err_inst % build( &
114122 code= err_check_index_claimed% code,&
115123 message = msg, &
116- cause = err_check_index_claimed &
124+ cause = cause &
117125 )
118126 end if
119127
120128 end function get_instance
121129
122- function set_instance_index_to (instance_index , val ) result(err )
130+ function set_instance_index_to (instance_index , val ) result(err_inst )
123131
124132 integer , intent (in ) :: instance_index
125133 ! ! Index in `instance_array` of which to set the value equal to `val`
126134
127135 type (ErrorV), intent (in ) :: val
128- type (ErrorV) :: err
136+ type (ErrorV) :: err_inst
129137
130138 type (ErrorV) :: err_check_index_claimed
139+ integer :: cause
131140 character (len= :), allocatable :: msg
132141
133142 err_check_index_claimed = check_index_claimed(instance_index)
134143
135- if (err_check_index_claimed% code /= NO_ERROR_CODE) then
144+ if (err_check_index_claimed% code /= NO_ERROR_CODE) then
136145 ! MZ: here we do not set if the index has not been claimed.
137146 ! Must be harmonised with Results type
138147 msg = " Setting Instance Error: "
139- err = ErrorV ( &
140- code = err_check_index_claimed% code, &
148+
149+ cause = build_instance(code= err_check_index_claimed % code, message= err_check_index_claimed % message)
150+
151+ call err_inst % build( &
152+ code= err_check_index_claimed% code,&
141153 message = msg, &
142- cause = err_check_index_claimed &
154+ cause = cause &
143155 )
144156
145157 else
@@ -153,7 +165,7 @@ function set_instance_index_to(instance_index, val) result(err)
153165 ! Reassigning the slot
154166 call instance_array(instance_index)% build(code= val% code, message= val% message, cause= val% cause)
155167
156- err = ErrorV (code= NO_ERROR_CODE)
168+ call err_inst % build (code= NO_ERROR_CODE)
157169
158170 end if
159171
@@ -192,8 +204,7 @@ function check_index_claimed(instance_index) result(err_check_index_claimed)
192204 ! print *, "Index ", instance_index, " has not been claimed"
193205 ! error stop 1
194206 msg = " Index " // trim (adjustl (idx_str)) // " has not been claimed"
195-
196- err_check_index_claimed = ErrorV(code= 1 , message= msg)
207+ call err_check_index_claimed % build(code= 1 , message= msg)
197208
198209 return
199210 end if
@@ -209,41 +220,123 @@ function check_index_claimed(instance_index) result(err_check_index_claimed)
209220 ! print *, "Requested index is ", instance_index, " which is less than 1"
210221 ! error stop 1
211222 msg = " Requested index is: " // trim (adjustl (idx_str)) // " ==> out of boundary"
212- err_check_index_claimed = ErrorV (code= 2 , message= msg)
223+ call err_check_index_claimed % build (code= 2 , message= msg)
213224
214225 return
215226 end if
216227
217- err_check_index_claimed = ErrorV (code= NO_ERROR_CODE)
228+ call err_check_index_claimed % build (code= NO_ERROR_CODE)
218229
219230 end function check_index_claimed
220231
221- subroutine ensure_instance_array_size_is_at_least (n )
222- ! ! Ensure that `instance_array` and `instance_available` have at least `n` slots
232+ ! subroutine ensure_instance_array_size_is_at_least(n)
233+ ! !! Ensure that `instance_array` and `instance_available` have at least `n` slots
234+ !
235+ ! integer, intent(in) :: n
236+ !
237+ ! type(ErrorV), dimension(:), allocatable :: tmp_instances
238+ ! logical, dimension(:), allocatable :: tmp_available
239+ !
240+ ! if (.not. allocated(instance_array)) then
241+ ! allocate (instance_array(n))
242+ !
243+ ! allocate (instance_available(n))
244+ ! ! Race conditions ?
245+ ! instance_available = .true.
246+ !
247+ ! else if (size(instance_available) < n) then
248+ ! allocate (tmp_instances(n))
249+ ! tmp_instances(1:size(instance_array)) = instance_array
250+ ! call move_alloc(tmp_instances, instance_array)
251+ !
252+ ! allocate (tmp_available(n))
253+ ! tmp_available(1:size(instance_available)) = instance_available
254+ ! tmp_available(size(instance_available) + 1:size(tmp_available)) = .true.
255+ ! call move_alloc(tmp_available, instance_available)
256+ !
257+ ! end if
258+ ! end subroutine ensure_instance_array_size_is_at_least
259+
260+ subroutine ensure_array_capacity_for_instances (n )
261+ ! ! Ensure that `instance_array` has at least `n` slots
262+
263+ integer , intent (in ) :: n
264+ type (ErrorV), dimension (:), allocatable :: tmp_instances
265+ logical , dimension (:), allocatable :: tmp_available
266+
267+ integer :: free_count
268+
269+ if (.not. allocated (instance_array)) then
270+
271+ allocate (instance_array(n),instance_available(n))
272+ ! Race conditions ?
273+ instance_available = .true.
274+
275+ else if (size (instance_array) < n) then
276+ ! MZ: in this case we just add n spaces on top
223277
224- integer , intent (in ) :: n
278+ allocate (tmp_instances(n+ size (instance_array)), &
279+ tmp_available(n+ size (instance_available)) &
280+ )
225281
226- type (ErrorV), dimension (:), allocatable :: tmp_instances
227- logical , dimension (:), allocatable :: tmp_available
282+ tmp_instances(1 :size (instance_array)) = instance_array
283+ tmp_available = .true.
284+ tmp_available(1 :size (instance_available)) = instance_available
228285
229- if ( .not. allocated ( instance_array)) then
230- allocate (instance_array(n) )
286+ call move_alloc(tmp_instances, instance_array)
287+ call move_alloc(tmp_available, instance_available )
231288
232- allocate (instance_available(n))
233- ! Race conditions ?
234- instance_available = .true.
289+ else
235290
236- else if (size (instance_available) < n) then
237- allocate (tmp_instances(n))
238- tmp_instances(1 :size (instance_array)) = instance_array
239- call move_alloc(tmp_instances, instance_array)
291+ free_count = count (instance_available)
240292
241- allocate (tmp_available(n))
242- tmp_available(1 :size (instance_available)) = instance_available
243- tmp_available(size (instance_available) + 1 :size (tmp_available)) = .true.
244- call move_alloc(tmp_available, instance_available)
293+ if (free_count < n) then
294+ ! MZ: doubling the size might be more efficient in the long run??
295+ allocate (tmp_instances(size (instance_array)* 2 ),&
296+ tmp_available(size (instance_available)* 2 ) &
297+ )
245298
299+ tmp_instances(1 :size (instance_array)) = instance_array
300+ tmp_available = .true.
301+ tmp_available(1 :size (instance_available)) = instance_available
302+
303+ call move_alloc(tmp_instances, instance_array)
304+ call move_alloc(tmp_available, instance_available)
305+
306+ end if
307+
308+ end if
309+
310+ end subroutine ensure_array_capacity_for_instances
311+
312+ pure recursive function get_error_message(err) result(full_msg)
313+
314+ type (ErrorV), intent (in ) :: err
315+
316+ character (len= :), allocatable :: full_msg
317+ character (len= :), allocatable :: cause_msg
318+
319+ full_msg = err% message
320+
321+ if (err% cause/= 0 ) then
322+ ! MZ : free slot while passing by?
323+ cause_msg = get_error_message(instance_array(err% cause))
324+ full_msg = trim (full_msg) // NEW_LINE(" A" ) // " Previous error --> " // trim (cause_msg)
246325 end if
247- end subroutine ensure_instance_array_size_is_at_least
326+
327+ end function get_error_message
328+
329+ subroutine deallocate_instance_arrays ()
330+ ! ! Finalise an instance
331+
332+ if (allocated (instance_available).and. allocated (instance_array)) then
333+ deallocate (instance_available,instance_array)
334+ else if (allocated (instance_available))then
335+ deallocate (instance_available)
336+ else if (allocated (instance_array)) then
337+ deallocate (instance_array)
338+ end if
339+
340+ end subroutine deallocate_instance_arrays
248341
249342end module m_error_v_manager
0 commit comments