Skip to content

Commit 376756e

Browse files
committed
poly_function more tests and status
1 parent 9f450ad commit 376756e

4 files changed

Lines changed: 91 additions & 7 deletions

File tree

src/poly_function/c_interface_poly.f90

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ module c_interface_poly
1212
integer(c_int), parameter :: STATUS_ZERO_DIMS = 3_c_int
1313
integer(c_int), parameter :: STATUS_ALLOC_FAIL = 4_c_int
1414
integer(c_int), parameter :: STATUS_BAD_OBJECT_PTR = 5_c_int
15+
integer(c_int), parameter :: STATUS_FORTDATA_PTR = 6_c_int
16+
integer(c_int), parameter :: STATUS_SET_DATA_DEALLOC_FAIL = 7_c_int
17+
integer(c_int), parameter :: STATUS_SET_DATA_ALLOC_FAIL = 8_c_int
18+
integer(c_int), parameter :: STATUS_DESTRUCT_DEALLOC_FAIL = 9_c_int
1519

1620
contains
1721

@@ -27,6 +31,7 @@ integer(c_int) function objconstruct_C(objtype,cptr_f90obj,cptr_indata,lx,ly) bi
2731
type(data2), pointer :: tmpobj2 !< ditto
2832
real(c_float), dimension(:,:), pointer :: fortdata
2933
integer :: alloc_status
34+
integer(c_int) :: data_status
3035

3136
!> nullify for sake of clarity and good practice
3237
nullify(tmpobj1, tmpobj2)
@@ -69,7 +74,25 @@ integer(c_int) function objconstruct_C(objtype,cptr_f90obj,cptr_indata,lx,ly) bi
6974
!> initialize some test data, and call methods to print
7075
print*, 'Initializing test data...'
7176
call c_f_pointer(cptr_indata,fortdata,shape=[lx,ly])
72-
call obj%set_data(fortdata)
77+
if (.not. associated(fortdata)) then
78+
objconstruct_C = STATUS_FORTDATA_PTR
79+
return
80+
end if
81+
82+
data_status = obj%set_data(fortdata)
83+
select case (data_status)
84+
case (0_c_int)
85+
continue
86+
case (1_c_int)
87+
objconstruct_C = STATUS_SET_DATA_DEALLOC_FAIL
88+
return
89+
case (2_c_int)
90+
objconstruct_C = STATUS_SET_DATA_ALLOC_FAIL
91+
return
92+
case default
93+
objconstruct_C = STATUS_SET_DATA_ALLOC_FAIL
94+
return
95+
end select
7396

7497
!! note lack of deallocate and nullify here; we need memory allocated to persist past the return.
7598
end function objconstruct_C
@@ -139,6 +162,7 @@ integer(c_int) function destruct_C(objtype, objC) bind(C, name='destruct_C')
139162

140163
class(dataobj_poly),pointer :: obj
141164
integer(c_int) :: status
165+
integer :: dealloc_status
142166

143167
destruct_C = STATUS_SUCCESS
144168
if (.not. c_associated(objC)) return
@@ -149,8 +173,20 @@ integer(c_int) function destruct_C(objtype, objC) bind(C, name='destruct_C')
149173
return
150174
end if
151175

152-
if (associated(obj%dataval)) deallocate(obj%dataval)
153-
deallocate(obj)
176+
if (associated(obj%dataval)) then
177+
deallocate(obj%dataval, stat=dealloc_status)
178+
if (dealloc_status /= 0) then
179+
destruct_C = STATUS_DESTRUCT_DEALLOC_FAIL
180+
return
181+
end if
182+
end if
183+
184+
deallocate(obj, stat=dealloc_status)
185+
if (dealloc_status /= 0) then
186+
destruct_C = STATUS_DESTRUCT_DEALLOC_FAIL
187+
return
188+
end if
189+
154190
objC = c_null_ptr
155191

156192
end function destruct_C

src/poly_function/datamod_poly.f90

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,14 @@ module datamod_poly
3333
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
3434
!! type-bound procedures
3535
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
36-
subroutine set_data(self,array)
36+
integer(c_int) function set_data(self,array)
3737
class(dataobj_poly), intent(inout) :: self
3838
real(c_float), dimension(:,:), intent(in) :: array
3939
integer(c_int) :: nx, ny
4040
integer(c_int) :: dealloc_status, alloc_status
4141

42+
set_data = 0_c_int
43+
4244
nx = size(array,1)
4345
ny = size(array,2)
4446

@@ -51,16 +53,22 @@ subroutine set_data(self,array)
5153
return
5254
end if
5355
deallocate(self%dataval, stat=dealloc_status)
54-
if (dealloc_status /= 0) return
56+
if (dealloc_status /= 0) then
57+
set_data = 1_c_int
58+
return
59+
end if
5560
end if
5661

5762
allocate(self%dataval(nx,ny), stat=alloc_status)
58-
if (alloc_status /= 0) return
63+
if (alloc_status /= 0) then
64+
set_data = 2_c_int
65+
return
66+
end if
5967

6068
self%lx = nx
6169
self%ly = ny
6270
self%dataval(:,:)=array(:,:)
63-
end subroutine set_data
71+
end function set_data
6472

6573

6674
subroutine print_data(self)

src/poly_function/my_polyfcn.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
#include <stddef.h>
22

3+
enum {
4+
POLY_STATUS_SUCCESS = 0,
5+
POLY_STATUS_INVALID_TYPE = 1,
6+
POLY_STATUS_NULL_PTR = 2,
7+
POLY_STATUS_ZERO_DIMS = 3,
8+
POLY_STATUS_ALLOC_FAIL = 4,
9+
POLY_STATUS_BAD_OBJECT_PTR = 5,
10+
POLY_STATUS_FORTDATA_PTR = 6,
11+
POLY_STATUS_SET_DATA_DEALLOC_FAIL = 7,
12+
POLY_STATUS_SET_DATA_ALLOC_FAIL = 8,
13+
POLY_STATUS_DESTRUCT_DEALLOC_FAIL = 9
14+
};
15+
316
#ifdef __cplusplus
417
extern "C" {
518
#endif

test/poly_function/main.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
// 3: zero dimensions in constructor
88
// 4: allocation failure
99
// 5: invalid/stale object pointer
10+
// 6: invalid C->Fortran input data pointer mapping
11+
// 7: set_data deallocation failure
12+
// 8: set_data allocation failure
13+
// 9: destruct deallocation failure
1014
#include <array>
1115
#include <iostream>
1216
#include <cstdlib>
@@ -156,5 +160,28 @@ if (status != 0) {
156160
return EXIT_FAILURE;
157161
}
158162

163+
// Invalid-type destroy should return invalid type status when handle is non-null.
164+
void* invalid_type_obj = nullptr;
165+
objtype = 1;
166+
status = objconstruct_C(&objtype, &invalid_type_obj, &arrptr, &lx1, &ly1);
167+
if (status != 0) {
168+
std::cerr << "Failed to construct invalid_type_obj with status " << status << "\n";
169+
return EXIT_FAILURE;
170+
}
171+
172+
objtype = 999;
173+
status = destruct_C(&objtype, &invalid_type_obj);
174+
if (status != 1) {
175+
std::cerr << "Expected invalid objtype status 1 from destruct_C, got " << status << "\n";
176+
return EXIT_FAILURE;
177+
}
178+
179+
objtype = 1;
180+
status = destruct_C(&objtype, &invalid_type_obj);
181+
if (status != 0) {
182+
std::cerr << "Cleanup destruct_C failed for invalid_type_obj with status " << status << "\n";
183+
return EXIT_FAILURE;
184+
}
185+
159186
return EXIT_SUCCESS;
160187
}

0 commit comments

Comments
 (0)