#if defined HAVE_CONFIG_H
#include "config.h"
#endif

!!@LICENSE

module gridxc_sys

  ! This module contains interfaces to handler routines
  ! They can be provided by the user of the library
  ! through calls to associate the respective pointers
  ! Note that the alloc-related handlers are defined
  ! in the alloc module
  
  interface
    subroutine die_interf(str)
      character(len=*), intent(in)  :: str
    end subroutine die_interf
  end interface
  interface
    subroutine gridxc_timer_start_interf(str)
      character(len=*), intent(in)  :: str
    end subroutine gridxc_timer_start_interf
  end interface
  interface
    subroutine gridxc_timer_stop_interf(str)
      character(len=*), intent(in)  :: str
    end subroutine gridxc_timer_stop_interf
  end interface

 procedure(die_interf),pointer :: die => simple_die_routine
 procedure(gridxc_timer_start_interf),pointer :: gridxc_timer_start => dummy_timer_start
 procedure(gridxc_timer_stop_interf),pointer :: gridxc_timer_stop => dummy_timer_stop

CONTAINS

  subroutine set_die_routine(func)
    procedure(die_interf) :: func
    die => func
  end subroutine set_die_routine

! auxiliary routine to provide a non-zero exit code
  subroutine exit(code)
    use iso_c_binding, only: C_INT

    integer(C_INT), intent(in) :: code

    interface
       subroutine c_exit(code) bind(C,name="exit")
         use iso_c_binding, only: c_int
         integer(c_int), intent(in) :: code
       end subroutine c_exit
    end interface

    call c_exit(code)
  end subroutine exit

  subroutine simple_die_routine(str)
    character(len=*), intent(in)   :: str
    write(0,'(a,a)') "[libgridxc default error handler]: " // trim(str)
    write(6,'(a,a)') "[libgridxc default error handler]: " // trim(str)
    write(6,'(a)') "Use gridxc_set_error_handler(custom_handler) to configure"
    !
    call exit(1)
    ! alternatively
    ! stop
    ! In F2018:
    ! error stop 1
  end subroutine simple_die_routine
! --------------------------------
  subroutine set_timer_start_routine(func)
    procedure(gridxc_timer_start_interf) :: func
    gridxc_timer_start => func
  end subroutine set_timer_start_routine

  subroutine set_timer_stop_routine(func)
    procedure(gridxc_timer_stop_interf) :: func
    gridxc_timer_stop => func
  end subroutine set_timer_stop_routine

  subroutine dummy_timer_start(str)
    character(len=*), intent(in)   :: str
  end subroutine dummy_timer_start

  subroutine dummy_timer_stop(str)
    character(len=*), intent(in)   :: str
  end subroutine dummy_timer_stop
! --------------------------------

end module gridxc_sys

