module mod_logging use mod_global_variables, only: dp use mod_painting, only: paint_string implicit none private !> exponential format character(8), parameter :: exp_fmt = "(e20.8)" !> shorter float format character(8), parameter :: dp_fmt = "(f20.8)" !> integer format character(4), parameter :: int_fmt = "(i8)" interface str module procedure logical_tostring module procedure integer_tostring module procedure real_tostring module procedure complex_tostring module procedure character_array_tostring module procedure integer_array_tostring end interface str type, private :: logger_t integer, private :: logging_level logical, private :: use_prefix contains procedure, nopass, public :: error procedure, public :: warning procedure, public :: info procedure, public :: debug procedure, public :: initialise procedure, public :: set_logging_level procedure, public :: get_logging_level procedure, public :: enable_prefix procedure, public :: disable_prefix end type logger_t type(logger_t), public :: logger public :: str public :: exp_fmt, dp_fmt, int_fmt contains pure subroutine initialise(this) class(logger_t), intent(inout) :: this this%logging_level = 2 this%use_prefix = .true. end subroutine initialise pure subroutine set_logging_level(this, logging_level) class(logger_t), intent(inout) :: this integer, intent(in) :: logging_level this%logging_level = logging_level end subroutine set_logging_level pure integer function get_logging_level(this) result(logging_level) class(logger_t), intent(in) :: this logging_level = this%logging_level end function get_logging_level pure subroutine enable_prefix(this) class(logger_t), intent(inout) :: this this%use_prefix = .true. end subroutine enable_prefix pure subroutine disable_prefix(this) class(logger_t), intent(inout) :: this this%use_prefix = .false. end subroutine disable_prefix subroutine error(msg) use mod_exceptions, only: raise_exception character(len=*), intent(in) :: msg call raise_exception(msg) end subroutine error subroutine warning(this, msg) class(logger_t), intent(in) :: this character(len=*), intent(in) :: msg character(:), allocatable :: msg_raised if (.not. this%logging_level >= 1) return if (this%use_prefix) then msg_raised = " WARNING | " // msg else msg_raised = " | " // msg end if write(*, *) paint_string(msg_raised, "yellow") end subroutine warning subroutine info(this, msg) ! LCOV_EXCL_START class(logger_t), intent(in) :: this character(len=*), intent(in) :: msg character(:), allocatable :: msg_raised if (.not. this%logging_level >= 2) return if (this%use_prefix) then msg_raised = " INFO | " // msg else msg_raised = " | " // msg end if write(*, *) msg_raised end subroutine info ! LCOV_EXCL_STOP subroutine debug(this, msg) ! LCOV_EXCL_START class(logger_t), intent(in) :: this character(len=*), intent(in) :: msg character(:), allocatable :: msg_raised if (.not. this%logging_level >= 3) return if (this%use_prefix) then msg_raised = " DEBUG | " // msg else msg_raised = " | " // msg end if write(*, *) paint_string(msg_raised, "green") end subroutine debug ! LCOV_EXCL_STOP pure function logical_tostring(boolean) result(string) logical, intent(in) :: boolean character(:), allocatable :: string if (boolean) then string = "True" else string = "False" end if end function logical_tostring pure function integer_tostring(int_value, fmt) result(string) integer, intent(in) :: int_value character(len=*), intent(in), optional :: fmt character(len=20) :: tmp character(:), allocatable :: fmt_string character(:), allocatable :: string if (present(fmt)) then fmt_string = "(" // trim(fmt) // ")" else fmt_string = int_fmt end if write(tmp, fmt_string) int_value string = trim(adjustl(tmp)) end function integer_tostring pure function real_tostring(real_value, fmt) result(string) real(dp), intent(in) :: real_value character(len=*), intent(in), optional :: fmt character(len=20) :: tmp character(:), allocatable :: fmt_string character(:), allocatable :: string if (present(fmt)) then fmt_string = "(" // trim(fmt) // ")" else fmt_string = dp_fmt end if write(tmp, fmt_string) real_value string = trim(adjustl(tmp)) end function real_tostring pure function complex_tostring(complex_value, fmt) result(string) complex(dp), intent(in) :: complex_value character(len=*), intent(in), optional :: fmt character(:), allocatable :: string character(:), allocatable :: fmt_string character(len=20) :: str_real, str_imag if (present(fmt)) then fmt_string = "(" // trim(fmt) // ")" else fmt_string = "(f18.8)" end if write(str_real, fmt_string) real(complex_value) write(str_imag, "(SP," // fmt_string // ",'i')") aimag(complex_value) string = trim(adjustl(str_real)) // trim(adjustl(str_imag)) end function complex_tostring pure function character_array_tostring(array) result(string) !> the array to convert character(len=*), intent(in) :: array(:) !> returned result, trimmed character(:), allocatable :: string integer :: i string = "[" do i = 1, size(array) string = string // trim(array(i)) // ", " end do string = string(:len(string) - 2) // "]" end function character_array_tostring pure function integer_array_tostring(array) result(string) !> the array to convert integer, intent(in) :: array(:) !> returned result, trimmed character(:), allocatable :: string integer :: i string = "[" do i = 1, size(array) string = string // integer_tostring(array(i)) // ", " end do string = string(:len(string) - 2) // "]" end function integer_array_tostring end module mod_logging