!-*-f90-*- ! ! API: Error treatment ! FIXME: introduction of own error handler requires ! !> \page "Comments on error handling" !> Please go to api/error.finc for the API documentation. !> !> The error handling subroutines are available from Fortran, with !> exception of the macros GSL_ERROR and GSL_ERROR_VAL. !> A user-defined error handler can be defined either in C or using a !> Fortran function with the bind(c) attribute. Here is the !> description of the required interface: !>
!> subroutine errhand(reason, file, line, errno) bind(c)
!>    type(c_ptr), value :: reason, file
!>    integer(c_int), value :: line, errno
!> end subroutine errhand
!> 
!> An object of type fgsl_error_handler_t is returned by the !> constructor fgsl_error_handler_init(errhand), which takes !> a subroutine with the interface described above as its argument. !> The subroutine fgsl_error(reason, file, line, errno) works !> in an analogous manner as the C version. If the Fortran preprocessor is !> supported, it should be possible to use the macros __FILE__ !> and __LINE__ in the above call. Once not needed any more, the !> error handler object can be deallocated by calling the subroutine !> fgsl_error_handler_free with itself as its only argument. !> Note that the function fgsl_strerror returns a string !> of length fgsl_strmax. function fgsl_set_error_handler(new_handler) type(fgsl_error_handler_t), intent(in) :: new_handler type(fgsl_error_handler_t) :: fgsl_set_error_handler fgsl_set_error_handler%gsl_error_handler_t = & gsl_set_error_handler(new_handler%gsl_error_handler_t) end function fgsl_set_error_handler function fgsl_set_error_handler_off() type(fgsl_error_handler_t) :: fgsl_set_error_handler_off fgsl_set_error_handler_off%gsl_error_handler_t = & gsl_set_error_handler_off() end function fgsl_set_error_handler_off function fgsl_strerror(errno) integer(fgsl_int), intent(in) :: errno character(kind=fgsl_char,len=fgsl_strmax) :: fgsl_strerror ! type(c_ptr) :: name ! ! write(6, *) 'Error is ',errno name = gsl_strerror(errno) fgsl_strerror = fgsl_name(name) end function fgsl_strerror subroutine fgsl_error(reason, file, line, errno) character(kind=fgsl_char,len=*), intent(in) :: & reason, file integer(fgsl_int), intent(in) :: line, errno character(kind=fgsl_char,len=fgsl_strmax), target :: reason_null, file_null if (len(trim(reason)) < fgsl_strmax .and. & len(trim(file)) < fgsl_strmax) then reason_null = trim(reason) // c_null_char file_null = trim(file) // c_null_char call gsl_error(c_loc(reason_null), c_loc(file_null), line, errno) end if end subroutine fgsl_error function fgsl_error_handler_status(error_handler_t) type(fgsl_error_handler_t), intent(in) :: error_handler_t logical :: fgsl_error_handler_status fgsl_error_handler_status = .true. if (.not. c_associated(error_handler_t%gsl_error_handler_t)) & fgsl_error_handler_status = .false. end function fgsl_error_handler_status ! ! initialize own error handler ! function fgsl_error_handler_init(handler_sr) interface subroutine handler_sr(reason, file, line, errno) bind(c) import :: c_ptr, c_int type(c_ptr), value :: reason, file integer(c_int), value :: line, errno end subroutine handler_sr end interface type(fgsl_error_handler_t) :: fgsl_error_handler_init ! type(c_funptr) :: fptr fptr = c_funloc(handler_sr) fgsl_error_handler_init%gsl_error_handler_t = fptr end function fgsl_error_handler_init