📄 rvlog.c
字号:
#endif
/* Look for a source with the same name */
curSource = logMgr->source;
for (i = 0; i < logMgr->numSources; i++)
{
if ((curSource->timesConstructed > 0) &&
(curSource->libraryCode == libraryCode) &&
(strcmp(curSource->name, name) == 0))
{
*source = curSource;
return RV_OK;
}
/* Get the next one */
curSource++;
}
/* We can't seem to find this source */
return RvLogErrorCode(RV_ERROR_BADPARAM);
}
#if (RV_LOGMASK_COMPILEMASK != 0)
/********************************************************************************************
* RvLogIsSelected
*
* purpose : Check to see if a specific message type should be sent to the log by a given
* source
* input : source - Source of message to log
* messageType - Type of the message to log
* output : None
* return : RV_TRUE if message should be logged, RV_FALSE otherwise
********************************************************************************************/
RVCOREAPI
RvBool RVCALLCONV RvLogIsSelected(
IN RvLogSource* source,
IN RvLogMessageType messageType)
{
RvInt32 level;
RvBool selected;
#ifdef RV_NULLCHECK
if ((source == NULL) || (*source == NULL))
return RV_FALSE;
#endif
/* First make sure log is not silenced */
level = (*source)->logMgr->level;
if (level == 1)
{
/* Check that the type of message should be logged for this source */
selected = ((RvBool)(((*source)->messageTypes & messageType) != 0));
}
else
selected = (level != 0);
return selected;
}
#endif /* (RV_LOGMASK_COMPILEMASK != 0) */
/********************************************************************************************
* RvLogSetLevel
*
* purpose : Set the level of logging, while leaving the masks of all log sources without a
* change.
* input : logMgr - Log manager
* level - 0 stop logging, 1 log by the masks of the sources, 2 log everything
* output : None
* return : RV_OK on success, other on failure
********************************************************************************************/
RVCOREAPI
RvStatus RVCALLCONV RvLogSetLevel(
IN RvLogMgr* logMgr,
IN RvInt32 level)
{
#ifdef RV_NULLCHECK
if (logMgr == NULL)
return RvLogErrorCode(RV_ERROR_NULLPTR);
#endif
#ifdef RV_RANGECHECK
if ((level < 0) || (level > 2))
return RvLogErrorCode(RV_ERROR_BADPARAM);
#endif
logMgr->level = level;
return RV_OK;
}
/********************************************************************************************
* RvLogSetGlobalMask
*
* purpose : Set the mask of messages to log on all the sources of the log object
* input : logMgr - Log manager
* messageMask - Type of the messages to log
* output : None
* return : RV_OK on success, other on failure
********************************************************************************************/
RVCOREAPI
RvStatus RVCALLCONV RvLogSetGlobalMask(
IN RvLogMgr* logMgr,
IN RvLogMessageType messageMask)
{
int i;
logMgr->defaultMask = messageMask;
for (i = 0; i < logMgr->numSources; i++)
if (logMgr->source[i].timesConstructed > 0)
logMgr->source[i].messageTypes = messageMask;
return RV_OK;
}
/********************************************************************************************
* RvLogSourceSetMask
*
* purpose : Set the mask of messages to log for a specific source
* input : source - Source of messages to set
* messageMask - Type of the messages to log
* output : None
* return : RV_OK on success, other on failure
********************************************************************************************/
RVCOREAPI
RvStatus RVCALLCONV RvLogSourceSetMask(
IN RvLogSource* source,
IN RvLogMessageType messageMask)
{
(*source)->messageTypes = messageMask;
return RV_OK;
}
/********************************************************************************************
* RvLogSourceGetMask
*
* purpose : Get the mask of messages to log for a specific source
* input : source - Source of messages to get
* output : None
* return : Message mask of messages that are logged
********************************************************************************************/
RVCOREAPI
RvLogMessageType RVCALLCONV RvLogSourceGetMask(
IN RvLogSource* source)
{
return ((*source)->messageTypes);
}
/********************************************************************************************
* RvLogSourceGetName
*
* purpose : Get the name for a specific log source
* input : source - Source of messages to get
* output : None
* return : Name of the source on success, NULL on failure
********************************************************************************************/
RVCOREAPI
const RvChar* RVCALLCONV RvLogSourceGetName(
IN RvLogSource* source)
{
return ((*source)->name);
}
/********************************************************************************************
* RvLogTextAny
*
* purpose : Private function used by all RvLogTextXXX functions to format and execute the
* actual listener functions.
* input : source - Source of message to log
* messageType - Type of message to log
* line - Formatted string to log
* varArg - Argument list to log
* output : None
* return : RV_OK on success, other on failure
********************************************************************************************/
#if (RV_LOGMASK_COMPILEMASK != 0)
static RvStatus RvLogTextAny(
IN RvLogSource* source,
IN RvLogMessageType messageType,
IN const RvChar* line,
IN va_list* varArg)
{
RvStatus ret;
RvLogMgr* logMgr;
RvLogRecord logRecord;
RvChar* ptr;
int i;
static RvBool rvLogInsideTextAny = RV_FALSE; /* RV_TRUE if we're currently inside the function RvLogTextAny() */
static RvThreadId rvLogCurId; /* Current thread Id locking this function */
static RvChar rvLogTextStr[RV_LOG_MESSAGE_SIZE + RV_LOG_RESERVED_BYTES]; /* Buffer to use for formatted messages */
if ((rvLogInsideTextAny == RV_TRUE) && (RvThreadIdEqual(RvThreadCurrentId(), rvLogCurId)))
{
/* Make sure we don't enter this function from within this function to avoid an endless
recursion loops of errors */
return RvLogErrorCode(RV_LOG_ERROR_RECURSION);
}
/* Lock it up */
ret = RvLockGet(&rvLogLock);
if (ret != RV_OK)
return ret;
/* Make sure we know we're inside this logging function */
rvLogInsideTextAny = RV_TRUE;
rvLogCurId = RvThreadCurrentId();
/* Skip the reserved bytes - some of the listeners might need it */
ptr = rvLogTextStr + RV_LOG_RESERVED_BYTES;
/* Create the log record we'll be using */
logRecord.timestamp = RvTimestampGet();
logRecord.source = source;
logRecord.messageType = messageType;
logRecord.text = (const RvChar*)ptr;
logRecord.threadInfo = RvThreadCurrent();
/* Format the given line with the arguments */
i = vsprintf((char *)ptr, (char *)line, *varArg);
RvAssert(i < RV_LOG_MESSAGE_SIZE); /* Make sure we didn't junk up the memory */
/* Make sure the one logging this didn't put a darn 'newline' in his message */
if (ptr[i-1] == '\n')
ptr[i-1] = '\0';
logMgr = (*source)->logMgr;
for (i = 0; i < logMgr->numListeners; i++)
{
/* Call the listeners that are waiting for log messages */
logMgr->listener[i](&logRecord, logMgr->listenerUserData[i]);
}
/* Update the status as being outside this function */
rvLogInsideTextAny = RV_FALSE;
RvLockRelease(&rvLogLock);
return ret;
}
#endif /* (RV_LOGMASK_COMPILEMASK != 0) */
/********************************************************************************************
* RvLogTextXXX
*
* purpose : Log a specific message type text message with variable amount of arguments
* input : source - Source of message to log
* line - Formatted string to log
* output : None
* return : RV_OK on success, other on failure
********************************************************************************************/
#if (RV_LOGMASK_COMPILEMASK & RV_LOGLEVEL_EXCEP)
RVCOREAPI
RvStatus RVCALLCONV RvLogTextExcep(
IN RvLogSource* source,
IN const char* line, ...)
{
RvStatus res;
va_list varArg;
va_start(varArg, line);
res = RvLogTextAny(source, RV_LOGLEVEL_EXCEP, line, &varArg);
va_end(varArg);
return res;
}
#endif /* (RV_LOGMASK_COMPILEMASK & RV_LOGLEVEL_EXCEP) */
#if (RV_LOGMASK_COMPILEMASK & RV_LOGLEVEL_ERROR)
RVCOREAPI
RvStatus RVCALLCONV RvLogTextError(
IN RvLogSource* source,
IN const char* line, ...)
{
RvStatus res;
va_list varArg;
va_start(varArg, line);
res = RvLogTextAny(source, RV_LOGLEVEL_ERROR, line, &varArg);
va_end(varArg);
return res;
}
#endif /* (RV_LOGMASK_COMPILEMASK & RV_LOGLEVEL_ERROR) */
#if (RV_LOGMASK_COMPILEMASK & RV_LOGLEVEL_WARNING)
RVCOREAPI
RvStatus RVCALLCONV RvLogTextWarning(
IN RvLogSource* source,
IN const char* line, ...)
{
RvStatus res;
va_list varArg;
va_start(varArg, line);
res = RvLogTextAny(source, RV_LOGLEVEL_WARNING, line, &varArg);
va_end(varArg);
return res;
}
#endif /* (RV_LOGMASK_COMPILEMASK & RV_LOGLEVEL_WARNING) */
#if (RV_LOGMASK_COMPILEMASK & RV_LOGLEVEL_INFO)
RVCOREAPI
RvStatus RVCALLCONV RvLogTextInfo(
IN RvLogSource* source,
IN const char* line, ...)
{
RvStatus res;
va_list varArg;
va_start(varArg, line);
res = RvLogTextAny(source, RV_LOGLEVEL_INFO, line, &varArg);
va_end(varArg);
return res;
}
#endif /* (RV_LOGMASK_COMPILEMASK & RV_LOGLEVEL_INFO) */
#if (RV_LOGMASK_COMPILEMASK & RV_LOGLEVEL_DEBUG)
RVCOREAPI
RvStatus RVCALLCONV RvLogTextDebug(
IN RvLogSource* source,
IN const char* line, ...)
{
RvStatus res;
va_list varArg;
va_start(varArg, line);
res = RvLogTextAny(source, RV_LOGLEVEL_DEBUG, line, &varArg);
va_end(varArg);
return res;
}
#endif /* (RV_LOGMASK_COMPILEMASK & RV_LOGLEVEL_DEBUG) */
#if (RV_LOGMASK_COMPILEMASK & RV_LOGLEVEL_ENTER)
RVCOREAPI
RvStatus RVCALLCONV RvLogTextEnter(
IN RvLogSource* source,
IN const char* line, ...)
{
RvStatus res;
va_list varArg;
va_start(varArg, line);
res = RvLogTextAny(source, RV_LOGLEVEL_ENTER, line, &varArg);
va_end(varArg);
return res;
}
#endif /* (RV_LOGMASK_COMPILEMASK & RV_LOGLEVEL_ENTER) */
#if (RV_LOGMASK_COMPILEMASK & RV_LOGLEVEL_LEAVE)
RVCOREAPI
RvStatus RVCALLCONV RvLogTextLeave(
IN RvLogSource* source,
IN const char* line, ...)
{
RvStatus res;
va_list varArg;
va_start(varArg, line);
res = RvLogTextAny(source, RV_LOGLEVEL_LEAVE, line, &varArg);
va_end(varArg);
return res;
}
#endif /* (RV_LOGMASK_COMPILEMASK & RV_LOGLEVEL_LEAVE) */
#if defined(__cplusplus)
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -