diff --git a/api/GenApi.py b/api/GenApi.py index 44eccd308eaad0917e03549c3527762988b305f3..f292e8184f2c27a84cb1e16c49d965f730c9e7da 100644 --- a/api/GenApi.py +++ b/api/GenApi.py @@ -487,6 +487,7 @@ def ostring(name, value=None, python_value=None, julia_value=None): a.fortran_types = ["character(len=:), allocatable, intent(out)"] a.fortran_c_api = ["character(kind=c_char), dimension(*)"] a.fortran_c_args = [api_name] + # TODO: Does this need to be C deallocated? return a @@ -1490,6 +1491,8 @@ module gmsh integer, parameter, public :: {2}_API_MAX_STR_LEN = 512 character(len=100), parameter, public :: {2}_API_VERSION = "{4}.{5}.{6}" + public :: gmshFree + type cstr_t character(len=:), allocatable :: s end type cstr_t @@ -1501,6 +1504,22 @@ module gmsh """ fortran_footer = """ + ! ---------------------------------------------------------------------------- + ! GMSH C memory management tools + ! ---------------------------------------------------------------------------- + + !> Callback to C to free any reserved memory + subroutine gmshFree(p) + interface + subroutine C_API(ptr) bind(C, name="gmshFree") + use, intrinsic :: iso_c_binding + type(c_ptr), value :: ptr + end subroutine C_API + end interface + type(c_ptr) :: p + call C_API(p) + end subroutine gmshFree + ! ---------------------------------------------------------------------------- ! Input routines from Fortran to C ! ---------------------------------------------------------------------------- @@ -1598,37 +1617,37 @@ fortran_footer = """ ! ---------------------------------------------------------------------------- function ovectorint_(cptr, n) result(v) - type(c_ptr), intent(in) :: cptr + type(c_ptr), intent(inout) :: cptr integer(c_size_t), intent(in) :: n integer(c_int), allocatable :: v(:) integer(c_int), pointer :: v_(:) call c_f_pointer(cptr, v_, [n]) allocate(v, source=v_) - deallocate(v_) + call gmshFree(cptr) end function ovectorint_ function ovectorsize_(cptr, n) result(v) - type(c_ptr), intent(in) :: cptr + type(c_ptr), intent(inout) :: cptr integer(c_size_t), intent(in) :: n integer(c_size_t), allocatable :: v(:) integer(c_size_t), pointer :: v_(:) call c_f_pointer(cptr, v_, [n]) allocate(v, source=v_) - deallocate(v_) + call gmshFree(cptr) end function ovectorsize_ function ovectordouble_(cptr, n) result(v) - type(c_ptr), intent(in) :: cptr + type(c_ptr), intent(inout) :: cptr integer(c_size_t), intent(in) :: n real(c_double), allocatable :: v(:) real(c_double), pointer :: v_(:) call c_f_pointer(cptr, v_, [n]) allocate(v, source=v_) - deallocate(v_) + call gmshFree(cptr) end function ovectordouble_ function ovectorstring_(cptr, n) result(v) - type(c_ptr), intent(in) :: cptr + type(c_ptr), intent(inout) :: cptr integer(c_size_t), intent(in) :: n character(len=GMSH_API_MAX_STR_LEN), allocatable :: v(:) @@ -1644,20 +1663,21 @@ fortran_footer = """ lenstr = cstrlen(fptr) v(i) = transfer(fptr(1:lenstr), v(i)) end do + call gmshFree(cptr) end function ovectorstring_ function ovectorpair_(cptr, n) result(v) - type(c_ptr), intent(in) :: cptr + type(c_ptr), intent(inout) :: cptr integer(c_size_t), intent(in) :: n integer(c_int), allocatable :: v(:,:) integer(c_int), pointer :: v_(:,:) call c_f_pointer(cptr, v_, [2_c_size_t, n / 2_c_size_t]) allocate(v, source=v_) - deallocate(v_) + call gmshFree(cptr) end function ovectorpair_ subroutine ovectorvectorint_(cptr1, cptr2, n, v, dims) - type(c_ptr), intent(in) :: cptr1, cptr2 + type(c_ptr), intent(inout) :: cptr1, cptr2 integer(c_size_t), intent(in) :: n integer(c_int), allocatable, intent(out) :: v(:) integer(c_size_t), allocatable, intent(out) :: dims(:) @@ -1667,11 +1687,12 @@ fortran_footer = """ call c_f_pointer(cptr1, v_, [sum(dims)]) allocate(dims, source=dims_) allocate(v, source=v_) - deallocate(v_, dims_) + call gmshFree(cptr1) + call gmshFree(cptr2) end subroutine ovectorvectorint_ subroutine ovectorvectorsize_(cptr1, cptr2, n, v, dims) - type(c_ptr), intent(in) :: cptr1, cptr2 + type(c_ptr), intent(inout) :: cptr1, cptr2 integer(c_size_t), intent(in) :: n integer(c_size_t), allocatable, intent(out) :: v(:) integer(c_size_t), allocatable, intent(out) :: dims(:) @@ -1681,11 +1702,12 @@ fortran_footer = """ call c_f_pointer(cptr1, v_, [sum(dims)]) allocate(dims, source=dims_) allocate(v, source=v_) - deallocate(v_, dims_) + call gmshFree(cptr1) + call gmshFree(cptr2) end subroutine ovectorvectorsize_ subroutine ovectorvectordouble_(cptr1, cptr2, n, v, dims) - type(c_ptr), intent(in) :: cptr1, cptr2 + type(c_ptr), intent(inout) :: cptr1, cptr2 integer(c_size_t), intent(in) :: n real(c_double), allocatable, intent(out) :: v(:) integer(c_size_t), allocatable, intent(out) :: dims(:) @@ -1695,11 +1717,12 @@ fortran_footer = """ call c_f_pointer(cptr1, v_, [sum(dims)]) allocate(dims, source=dims_) allocate(v, source=v_) - deallocate(v_, dims_) + call gmshFree(cptr1) + call gmshFree(cptr2) end subroutine ovectorvectordouble_ subroutine ovectorvectorpair_(cptr1, cptr2, n, v, dims) - type(c_ptr), intent(in) :: cptr1, cptr2 + type(c_ptr), intent(inout) :: cptr1, cptr2 integer(c_size_t), intent(in) :: n integer(c_int), allocatable, intent(out) :: v(:,:) integer(c_size_t), allocatable, intent(out) :: dims(:) @@ -1709,7 +1732,8 @@ fortran_footer = """ call c_f_pointer(cptr1, v_, [sum(dims), 2_c_size_t]) allocate(dims, source=dims_) allocate(v, source=v_) - deallocate(v_, dims_) + call gmshFree(cptr1) + call gmshFree(cptr2) end subroutine ovectorvectorpair_ !> Calculates the length of a C string. @@ -2211,6 +2235,8 @@ class API: arg_list = "" for arg in args: for t, a in zip(arg.fortran_types, arg.fortran_args): + # if arg.value: + # t += ", optional" # TODO: add optional to ierr arg_list += f"{indent}{t} :: {a}\n" arg_list += f"{indent}integer(c_int), intent(out) :: ierr\n" return arg_list diff --git a/api/gmsh.f90 b/api/gmsh.f90 index 59124d421e6b61349acca7d6ce321307c6f2149d..1f6b1f49d9cd1c8f1f30ecf54332171176498aae 100644 --- a/api/gmsh.f90 +++ b/api/gmsh.f90 @@ -33,6 +33,8 @@ module gmsh integer, parameter, public :: GMSH_API_MAX_STR_LEN = 512 character(len=100), parameter, public :: GMSH_API_VERSION = "4.10.4" + public :: gmshFree + type cstr_t character(len=:), allocatable :: s end type cstr_t @@ -10202,6 +10204,22 @@ module gmsh ! Post processing end subroutine gmshLoggerGetLastError + ! ---------------------------------------------------------------------------- + ! GMSH C memory management tools + ! ---------------------------------------------------------------------------- + + !> Callback to C to free any reserved memory + subroutine gmshFree(p) + interface + subroutine C_API(ptr) bind(C, name="gmshFree") + use, intrinsic :: iso_c_binding + type(c_ptr), value :: ptr + end subroutine C_API + end interface + type(c_ptr) :: p + call C_API(p) + end subroutine gmshFree + ! ---------------------------------------------------------------------------- ! Input routines from Fortran to C ! ---------------------------------------------------------------------------- @@ -10299,37 +10317,37 @@ module gmsh ! ---------------------------------------------------------------------------- function ovectorint_(cptr, n) result(v) - type(c_ptr), intent(in) :: cptr + type(c_ptr), intent(inout) :: cptr integer(c_size_t), intent(in) :: n integer(c_int), allocatable :: v(:) integer(c_int), pointer :: v_(:) call c_f_pointer(cptr, v_, [n]) allocate(v, source=v_) - deallocate(v_) + call gmshFree(cptr) end function ovectorint_ function ovectorsize_(cptr, n) result(v) - type(c_ptr), intent(in) :: cptr + type(c_ptr), intent(inout) :: cptr integer(c_size_t), intent(in) :: n integer(c_size_t), allocatable :: v(:) integer(c_size_t), pointer :: v_(:) call c_f_pointer(cptr, v_, [n]) allocate(v, source=v_) - deallocate(v_) + call gmshFree(cptr) end function ovectorsize_ function ovectordouble_(cptr, n) result(v) - type(c_ptr), intent(in) :: cptr + type(c_ptr), intent(inout) :: cptr integer(c_size_t), intent(in) :: n real(c_double), allocatable :: v(:) real(c_double), pointer :: v_(:) call c_f_pointer(cptr, v_, [n]) allocate(v, source=v_) - deallocate(v_) + call gmshFree(cptr) end function ovectordouble_ function ovectorstring_(cptr, n) result(v) - type(c_ptr), intent(in) :: cptr + type(c_ptr), intent(inout) :: cptr integer(c_size_t), intent(in) :: n character(len=GMSH_API_MAX_STR_LEN), allocatable :: v(:) @@ -10345,20 +10363,21 @@ module gmsh lenstr = cstrlen(fptr) v(i) = transfer(fptr(1:lenstr), v(i)) end do + call gmshFree(cptr) end function ovectorstring_ function ovectorpair_(cptr, n) result(v) - type(c_ptr), intent(in) :: cptr + type(c_ptr), intent(inout) :: cptr integer(c_size_t), intent(in) :: n integer(c_int), allocatable :: v(:,:) integer(c_int), pointer :: v_(:,:) call c_f_pointer(cptr, v_, [2_c_size_t, n / 2_c_size_t]) allocate(v, source=v_) - deallocate(v_) + call gmshFree(cptr) end function ovectorpair_ subroutine ovectorvectorint_(cptr1, cptr2, n, v, dims) - type(c_ptr), intent(in) :: cptr1, cptr2 + type(c_ptr), intent(inout) :: cptr1, cptr2 integer(c_size_t), intent(in) :: n integer(c_int), allocatable, intent(out) :: v(:) integer(c_size_t), allocatable, intent(out) :: dims(:) @@ -10368,11 +10387,12 @@ module gmsh call c_f_pointer(cptr1, v_, [sum(dims)]) allocate(dims, source=dims_) allocate(v, source=v_) - deallocate(v_, dims_) + call gmshFree(cptr1) + call gmshFree(cptr2) end subroutine ovectorvectorint_ subroutine ovectorvectorsize_(cptr1, cptr2, n, v, dims) - type(c_ptr), intent(in) :: cptr1, cptr2 + type(c_ptr), intent(inout) :: cptr1, cptr2 integer(c_size_t), intent(in) :: n integer(c_size_t), allocatable, intent(out) :: v(:) integer(c_size_t), allocatable, intent(out) :: dims(:) @@ -10382,11 +10402,12 @@ module gmsh call c_f_pointer(cptr1, v_, [sum(dims)]) allocate(dims, source=dims_) allocate(v, source=v_) - deallocate(v_, dims_) + call gmshFree(cptr1) + call gmshFree(cptr2) end subroutine ovectorvectorsize_ subroutine ovectorvectordouble_(cptr1, cptr2, n, v, dims) - type(c_ptr), intent(in) :: cptr1, cptr2 + type(c_ptr), intent(inout) :: cptr1, cptr2 integer(c_size_t), intent(in) :: n real(c_double), allocatable, intent(out) :: v(:) integer(c_size_t), allocatable, intent(out) :: dims(:) @@ -10396,11 +10417,12 @@ module gmsh call c_f_pointer(cptr1, v_, [sum(dims)]) allocate(dims, source=dims_) allocate(v, source=v_) - deallocate(v_, dims_) + call gmshFree(cptr1) + call gmshFree(cptr2) end subroutine ovectorvectordouble_ subroutine ovectorvectorpair_(cptr1, cptr2, n, v, dims) - type(c_ptr), intent(in) :: cptr1, cptr2 + type(c_ptr), intent(inout) :: cptr1, cptr2 integer(c_size_t), intent(in) :: n integer(c_int), allocatable, intent(out) :: v(:,:) integer(c_size_t), allocatable, intent(out) :: dims(:) @@ -10410,7 +10432,8 @@ module gmsh call c_f_pointer(cptr1, v_, [sum(dims), 2_c_size_t]) allocate(dims, source=dims_) allocate(v, source=v_) - deallocate(v_, dims_) + call gmshFree(cptr1) + call gmshFree(cptr2) end subroutine ovectorvectorpair_ !> Calculates the length of a C string.