recursive subroutine ESMF_LogWrite(msg, logmsgFlag, &
logmsgList, & ! DEPRECATED ARGUMENT
keywordEnforcer, line, file, method, log, rc)
!
!
! !ARGUMENTS:
character(len=*), intent(in) :: msg
type(ESMF_LogMsg_Flag),intent(in),optional :: logmsgFlag
type(ESMF_LogMsg_Flag),intent(in),optional::logmsgList ! DEPRECATED ARG
type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below
integer, intent(in), optional :: line
character(len=*), intent(in), optional :: file
character(len=*), intent(in), optional :: method
type(ESMF_Log), intent(inout),optional :: log
integer, intent(out), optional :: rc
!
! !STATUS:
! \begin{itemize}
! \item\apiStatusCompatibleVersion{5.2.0r}
! \item\apiStatusModifiedSinceVersion{5.2.0r}
! \begin{description}
! \item[5.2.0rp1] Added argument {\tt logmsgFlag}.
! Started to deprecate argument {\tt logmsgList}.
! This corrects inconsistent use of the {\tt List} suffix on
! the argument name. In ESMF this suffix indicates
! one--dimensional array arguments.
! \end{description}
! \end{itemize}
!
! !DESCRIPTION:
! This subroutine writes to the file associated with an {\tt ESMF\_Log}.
! A message is passed in along with the {\tt logmsgFlag}, {\tt line},
! {\tt file} and {\tt method}. If the write to the {\tt ESMF\_Log}
! is successful, the function will return a logical {\tt true}. This
! function is the base function used by all the other {\tt ESMF\_Log}
! writing methods.
!
! The arguments are:
! \begin{description}
!
! \item [msg]
! User-provided message string.
! \item [{[logmsgFlag]}]
! The type of message. See Section~\ref{const:logmsgflag} for
! possible values. If not specified, the default is {\tt ESMF\_LOGMSG\_INFO}.
! \item [{[logmsgList]}]
! \apiDeprecatedArgWithReplacement{logmsgFlag}
! \item [{[line]}]
! Integer source line number. Expected to be set by
! using the preprocessor macro {\tt \_\_LINE\_\_} macro.
! \item [{[file]}]
! User-provided source file name.
! \item [{[method]}]
! User-provided method string.
! \item [{[log]}]
! An optional {\tt ESMF\_Log} object that can be used instead
! of the default Log.
! \item [{[rc]}]
! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
! \end{description}
!
!EOP
interface
subroutine f_ESMF_VMAbort(rc)
integer, intent(out), optional :: rc
end subroutine f_ESMF_VMAbort
end interface
integer :: argcase
type(ESMF_LogMsg_Flag) :: local_logmsgflag
character(len=10) :: t
character(len=8) :: d
integer :: timevals(8)
!character(len=7) :: lt
character(len=32) :: tmethod
character(len=ESMF_MAXPATHLEN) :: tfile
integer :: tline
integer :: i
integer :: localrc
integer :: memstat
integer :: rc2, index, lenTotal, indentCount
type(ESMF_LogPrivate), pointer :: alog
ESMF_INIT_CHECK_SET_SHALLOW(ESMF_LogGetInit,ESMF_LogInit,log)
! Initialize return code; assume routine not implemented
if (present(rc)) then
rc=ESMF_RC_NOT_IMPL
endif
nullify(alog) ! ensure that the association status is well defined
localrc = ESMF_SUCCESS
if (present(log)) then
if (log%logTableIndex > 0) then
alog => ESMF_LogTable(log%logTableIndex)
else
localrc = ESMF_RC_OBJ_INIT
endif
else
if (ESMF_LogDefault%logTableIndex > 0) then
alog => ESMF_LogTable(ESMF_LogDefault%logTableIndex)
else
localrc = ESMF_RC_OBJ_INIT
end if
endif
! Check argument sanity
argcase = 0
argcase = argcase + merge (1, 0, present (logmsgFlag))
argcase = argcase + merge (2, 0, present (logmsgList))
select case (argcase)
case (0)
local_logmsgflag = ESMF_LOGMSG_INFO
case (1)
local_logmsgflag = logmsgFlag
case (2)
write (ESMF_UtilIOStderr,*) ESMF_METHOD, &
": Deprecated: Use logmsgFlag instead of logmsgList."
call ESMF_UtilIOUnitFlush(ESMF_UtilIOStderr, rc=rc)
local_logmsgflag = logmsgList
case (3)
write (ESMF_UtilIOStderr,*) ESMF_METHOD, &
": Do not specify both logmsgFlag and logmsgList. Use logmsgFlag."
call ESMF_UtilIOUnitFlush(ESMF_UtilIOStderr, rc=rc)
if (present(rc)) then
rc=ESMF_RC_ARG_INCOMP
end if
return
end select
if (associated(alog)) then
! Open the log file if necessary
if (alog%logkindflag /= ESMF_LOGKIND_NONE) then
if (alog%deferredOpenFlag) then
if (local_logmsgflag == ESMF_LOGMSG_ERROR) then
call ESMF_LogOpenFile (alog, rc=localrc)
if (localrc /= ESMF_SUCCESS) then
if (present (rc)) then
rc = localrc
end if
return
end if
alog%deferredOpenFlag = .false.
else
if (present (rc)) then
rc = ESMF_SUCCESS
end if
return
end if
end if
if (alog%FileIsOpen /= ESMF_TRUE) then
write (ESMF_UtilIOStderr,*) ESMF_METHOD, &
": ESMF_Log not open -- cannot ESMF_LogWrite(). Log message = ", trim (msg)
call ESMF_UtilIOUnitFlush(ESMF_UtilIOStderr, rc=rc)
if (present(rc)) rc=ESMF_FAILURE
return
endif
if (associated (alog%logmsgList)) then
do, i=1, size (alog%logmsgList)
if (local_logmsgflag == alog%logmsgList(i)) then
exit
end if
end do
if (i > size (alog%logmsgList)) then
if (present (rc)) rc=ESMF_SUCCESS
return
end if
end if
! Add the message to the message queue awaiting flushing
index = alog%fIndex
alog%dirty = ESMF_TRUE
call DATE_AND_TIME(date=d, time=t, values=timevals)
if (alog%highResTimestampFlag) then
call c_ESMC_VMWtime (alog%LOG_ENTRY(index)%highResTimestamp, localrc)
if (localrc /= ESMF_SUCCESS) then
if (present (rc)) rc = localrc
return
end if
end if
alog%LOG_ENTRY(index)%noPrefix = alog%noPrefix
alog%LOG_ENTRY(index)%highResTimestampFlag = alog%highResTimestampFlag
alog%LOG_ENTRY(index)%indentCount = alog%indentCount
alog%LOG_ENTRY(index)%methodflag = .FALSE.
alog%LOG_ENTRY(index)%lineflag = .FALSE.
alog%LOG_ENTRY(index)%fileflag = .FALSE.
if (present(method)) then
tmethod=adjustl(method)
alog%LOG_ENTRY(index)%methodflag=.TRUE.
alog%LOG_ENTRY(index)%method = tmethod
endif
if (present(line)) then
tline=line
alog%LOG_ENTRY(index)%lineflag = .TRUE.
alog%LOG_ENTRY(index)%line = tline
endif
if (present(file)) then
tfile=adjustl(file)
alog%LOG_ENTRY(index)%fileflag = .TRUE.
alog%LOG_ENTRY(index)%file = tfile
endif
select case (local_logmsgflag%mtype)
case (:0, size (ESMF_LogMsgString)+1:)
alog%LOG_ENTRY(index)%lt="INTERNAL ERROR"
case default
alog%LOG_ENTRY(index)%lt= ESMF_LogMsgString(local_logmsgflag%mtype)
end select
alog%LOG_ENTRY(alog%fIndex)%d = d
alog%LOG_ENTRY(alog%fIndex)%h = timevals(5)
alog%LOG_ENTRY(alog%fIndex)%m = timevals(6)
alog%LOG_ENTRY(alog%fIndex)%s = timevals(7)
alog%LOG_ENTRY(alog%fIndex)%ms = timevals(8)
indentCount = alog%LOG_ENTRY(index)%indentCount
lenTotal = len_trim(msg) + indentCount
allocate (alog%LOG_ENTRY(alog%fIndex)%msg(lenTotal), stat=memstat)
if (indentCount > 0) then
! insert leading white spaces
alog%LOG_ENTRY(alog%fIndex)%msg(1:indentCount) = " "
endif
alog%LOG_ENTRY(alog%fIndex)%msg(1+indentCount:) = &
ESMF_UtilString2Array(trim(msg))
alog%flushed = ESMF_FALSE
if (associated (alog%logmsgAbort)) then
do, i=1, size (alog%logmsgAbort)
if (local_logmsgflag%mtype == alog%logmsgAbort(i)%mtype) then
alog%stopprogram=.true.
alog%fIndex = alog%fIndex + 1
call ESMF_LogFlush(log,rc=rc2)
call ESMF_LogClose(ESMF_LogDefault, rc=rc2)
exit
end if
end do
end if
if (alog%fIndex == alog%maxElements .or. &
alog%flushImmediately == ESMF_TRUE .or. &
local_logmsgflag == ESMF_LOGMSG_ERROR) then
alog%fIndex = alog%fIndex + 1
call ESMF_LogFlush(log,rc=rc2)
alog%fIndex = 1
else
alog%fIndex = alog%fIndex + 1
endif
endif
! if requested, halt the program right now.
if (alog%stopprogram) call f_ESMF_VMAbort()
if (present(rc)) then
rc=ESMF_SUCCESS
endif
else
write (ESMF_UtilIOStderr,*) ESMF_METHOD, &
": ESMF_Log not open -- cannot ESMF_LogWrite(). Log message = ", trim (msg)
call ESMF_UtilIOUnitFlush(ESMF_UtilIOStderr, rc=rc)
if (present (rc)) then
rc = localrc
end if
endif
end subroutine ESMF_LogWrite