MODULE logging ! see also use_logging.h ! macro LOGBUF accumulates log output into logging_buffer IMPLICIT NONE SAVE PRIVATE INTERFACE ! Explicit interfaces for plugins ! Plugin that typically prints all lines in the loggin buffer 'buf' and prepends tags (log level, timestamp, ...) SUBROUTINE plugin(lev, tag, buf) INTEGER, INTENT(IN) :: lev CHARACTER(*), INTENT(IN) :: tag, buf(:) END SUBROUTINE plugin ! Plugin that writes into string 'line' information about the gridpoint of index 'index' SUBROUTINE plugin_log_gridpoint(index, line) INTEGER, INTENT(IN) :: index ! index of gridpoint CHARACTER(*), INTENT(OUT) :: line END SUBROUTINE plugin_log_gridpoint END INTERFACE #ifdef XCODEML ! XCodeML cannot parse procedure pointers #define default_flush_plugin flush_plugin #define default_log_gridpoint log_gridpoint_plugin #else ! This module provides a default implementation of flush_plugin but the top-level driver is welcome to override it. PROCEDURE(plugin), POINTER :: flush_plugin => default_flush_plugin ! The top-level driver MUST provide an implementation for log_gridpoint_plugin PROCEDURE(plugin_log_gridpoint), POINTER :: log_gridpoint_plugin => NULL() #endif INTEGER, PARAMETER :: linesize=10000, logging_bufsize=100 CHARACTER(linesize) :: logging_buf(logging_bufsize) INTEGER :: logging_lineno=0 ! messages with a log level > max_log_level are not printed INTEGER, PARAMETER, PUBLIC :: log_level_fatal=1, log_level_error=2, log_level_warn=3, log_level_info=4, log_level_dbg=5 INTEGER, PUBLIC :: max_log_level = log_level_info PUBLIC :: logging_buf, logging_bufsize, logging_lineno, flush_log, log_gridpoint, & flush_plugin, log_gridpoint_plugin CONTAINS SUBROUTINE flush_log(lev,tag) INTEGER, INTENT(IN) :: lev CHARACTER(*), INTENT(IN) :: tag IF(logging_lineno>0 .AND. lev<=max_log_level) CALL flush_plugin(lev, TRIM(tag), logging_buf(1:logging_lineno)) logging_lineno=0 END SUBROUTINE flush_log SUBROUTINE default_flush_plugin(lev, tag, buf) INTEGER, INTENT(IN) :: lev CHARACTER(*), INTENT(IN) :: tag, buf(:) CHARACTER(3), DIMENSION(log_level_dbg) :: dbtag = (/ 'FAT', 'ERR', 'WRN', 'INF', 'DBG' /) CHARACTER(100) :: prefix INTEGER :: i WRITE(prefix,*) '[', dbtag(lev), ' ', tag, ']' DO i=1, SIZE(buf) PRINT *, TRIM(prefix), TRIM(buf(i)) END DO END SUBROUTINE default_flush_plugin SUBROUTINE log_gridpoint(index) INTEGER, INTENT(IN) :: index logging_lineno = logging_lineno+1 CALL log_gridpoint_plugin(index, logging_buf(logging_lineno)) END SUBROUTINE log_gridpoint SUBROUTINE default_log_gridpoint(index, line) INTEGER, INTENT(IN) :: index ! index of gridpoint CHARACTER(*), INTENT(OUT) :: line line='' END SUBROUTINE default_log_gridpoint END MODULE logging