Skip to content

Commit a773f9c

Browse files
committed
Advancements and bubble-up working (message only)
1 parent 2c1f383 commit a773f9c

14 files changed

Lines changed: 623 additions & 156 deletions

Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ test: ## run the tests (re-installs the package every time so you might want to
5252
uv run --no-sync python scripts/inject-srcs-into-meson-build.py
5353
uv run --no-sync python -c 'from pathlib import Path; import example_fgen_basic' || ( echo "Run make virtual-environment first" && false )
5454
COV_DIR=$$(uv run --no-sync python -c 'from pathlib import Path; import example_fgen_basic; print(Path(example_fgen_basic.__file__).parent)'); \
55-
uv run --no-editable --reinstall-package example-fgen-basic pytest -r a -v tests src --doctest-modules --doctest-report ndiff --cov=$$COV_DIR
55+
# uv run --no-editable --reinstall-package example-fgen-basic pytest -s -r a -v tests/unit/test_result_dp.py --doctest-modules --doctest-report ndiff --cov=$$COV_DIR
56+
uv run --no-editable --reinstall-package example-fgen-basic pytest -s -r a -v tests/unit/test_result_dp.py src --doctest-modules --doctest-report ndiff --cov=$$COV_DIR
5657

5758
# Note on code coverage and testing:
5859
# You must specify cov=src.

src/example_fgen_basic/error_v/creation_wrapper.f90

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ function create_error(inv) result(res_instance_index)
3939
! This is the major trick for wrapping.
4040
! We return instance indexes (integers) to Python rather than the instance itself.
4141

42-
type(ErrorV) :: res
42+
type(ErrorV) :: res, err
4343

4444
! Do the Fortran call
4545
res = o_create_error(inv)
@@ -51,7 +51,8 @@ function create_error(inv) result(res_instance_index)
5151

5252
! Set the derived type value in the manager's array,
5353
! ready for its attributes to be retrieved from Python.
54-
call error_v_manager_set_instance_index_to(res_instance_index, res)
54+
err = error_v_manager_set_instance_index_to(res_instance_index, res)
55+
!MZ: check for errors ?
5556

5657
end function create_error
5758

@@ -72,7 +73,7 @@ function create_errors(invs, n) result(res_instance_indexes)
7273
!
7374
! This is the major trick for wrapping.
7475
! We return instance indexes (integers) to Python rather than the instance itself.
75-
76+
type(ErrorV) :: err
7677
type(ErrorV), dimension(n) :: res
7778

7879
integer :: i, tmp
@@ -91,7 +92,8 @@ function create_errors(invs, n) result(res_instance_indexes)
9192
call error_v_manager_get_available_instance_index(tmp)
9293
! Set the derived type value in the manager's array,
9394
! ready for its attributes to be retrieved from Python.
94-
call error_v_manager_set_instance_index_to(tmp, res(i))
95+
err = error_v_manager_set_instance_index_to(tmp, res(i))
96+
!MZ: check for errors ?
9597
! Set the result in the output array
9698
res_instance_indexes(i) = tmp
9799

src/example_fgen_basic/error_v/error_v.f90

Lines changed: 74 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,53 +16,96 @@ module m_error_v
1616
!! Code that indicates no error
1717

1818
type, public :: ErrorV
19-
!! Error value
19+
!! Error value
2020

2121
integer :: code = 1
2222
!! Error code
2323

24-
character(len=128) :: message = ""
24+
character(len=:), allocatable :: message
2525
!! Error message
2626
! TODO: think about making the message allocatable to handle long messages
2727

2828
! TODO: think about adding idea of critical
2929
! (means you can stop but also unwind errors and traceback along the way)
3030

3131
! TODO: think about adding trace (might be simpler than compiling with traceback)
32-
! type(ErrorV), allocatable, dimension(:) :: causes
32+
! class(ErrorV), allocatable :: cause
33+
type(ErrorV), pointer :: cause => null()
3334

3435
contains
3536

3637
private
3738

3839
procedure, public :: build
3940
procedure, public :: finalise
41+
! procedure, public :: get_error_message
4042
final :: finalise_auto
4143
! get_res sort of not needed (?)
4244
! get_err sort of not needed (?)
4345

4446
end type ErrorV
4547

4648
interface ErrorV
47-
!! Constructor interface - see build (TODO: figure out cross-ref syntax) for details
49+
!! Constructor interface - see build (TODO: figure out cross-ref syntax) for details
4850
module procedure :: constructor
4951
end interface ErrorV
5052

5153
contains
5254

53-
function constructor(code, message) result(self)
55+
! pure recursive function get_error_message(self) result(full_msg)
56+
!
57+
! class(ErrorV), target, intent(in) :: self
58+
!
59+
! character(len=:), allocatable :: full_msg
60+
! character(len=:), allocatable :: cause_msg
61+
!
62+
! full_msg = self%message
63+
! if (associated(self%cause)) then
64+
! cause_msg = self%cause%get_error_message()
65+
! full_msg = trim(full_msg) // ' Previous error: ' // trim(cause_msg)
66+
! end if
67+
!
68+
! end function
69+
! function get_error_message(self) result(full_msg)
70+
!
71+
! class(ErrorV), target, intent(in) :: self
72+
! class(ErrorV), pointer :: p_errorv
73+
!
74+
! character(len=:), allocatable :: full_msg
75+
!
76+
! full_msg = ""
77+
!
78+
! if (allocated(self%message)) full_msg = trim(self%message)
79+
! p_errorv => self
80+
!
81+
! do while (associated(p_errorv))
82+
!
83+
! if(len(full_msg)>0)then
84+
! full_msg = trim(full_msg) // " --> Cause: " // p_errorv % message
85+
! else
86+
! full_msg = p_errorv % message
87+
! end if
88+
!
89+
! p_errorv => p_errorv % cause
90+
!
91+
! end do
92+
!
93+
! end function
94+
95+
function constructor(code, message, cause) result(self)
5496
!! Constructor - see build (TODO: figure out cross-ref syntax) for details
5597

5698
integer, intent(in) :: code
5799
character(len=*), optional, intent(in) :: message
100+
type(ErrorV), target, optional, intent(in) :: cause
58101

59102
type(ErrorV) :: self
60103

61-
call self % build(code, message)
104+
call self % build(code, message, cause)
62105

63106
end function constructor
64107

65-
subroutine build(self, code, message)
108+
subroutine build(self, code, message, cause)
66109
!! Build instance
67110

68111
class(ErrorV), intent(inout) :: self
@@ -75,10 +118,25 @@ subroutine build(self, code, message)
75118

76119
character(len=*), optional, intent(in) :: message
77120
!! Error message
121+
type(ErrorV), target, optional, intent(in) :: cause
78122

79123
self % code = code
80-
if (present(message)) then
81-
self % message = message
124+
125+
if (present(cause)) then
126+
! self % cause => cause
127+
! allocate(self % cause)
128+
! call self%cause%build(cause%code, cause%message, cause%cause)
129+
! self%cause = cause
130+
if (present(message)) then
131+
self % message = trim(message) // " --> Cause: " // cause % message
132+
else
133+
self % message = " --> Cause: " // cause % message
134+
end if
135+
136+
else
137+
if (present(message)) then
138+
self % message = trim(message)
139+
end if
82140
end if
83141

84142
end subroutine build
@@ -91,7 +149,13 @@ subroutine finalise(self)
91149

92150
! If we make message allocatable, deallocate here
93151
self % code = 1
94-
self % message = ""
152+
if (allocated(self%message)) deallocate(self%message)
153+
! MZ when the object is finalized or goes out of scope, its pointer components are destroyed.
154+
! Hopefully no shared ownership??
155+
if (associated(self%cause))then
156+
deallocate(self%cause)
157+
nullify(self%cause)
158+
end if
95159

96160
end subroutine finalise
97161

0 commit comments

Comments
 (0)