diff --git a/src/monocoque/slog/slog.c b/src/monocoque/slog/slog.c index d67d87d..522b70a 100644 --- a/src/monocoque/slog/slog.c +++ b/src/monocoque/slog/slog.c @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyleft (C) 2015-2020 Sun Dro (f4tb0y@protonmail.com) + * Copyleft (C) 2015-2023 Sun Dro (s.kalatoz@gmail.com) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -27,7 +27,6 @@ #endif #include -#include #include #include #include @@ -37,86 +36,89 @@ #include #include "slog.h" -#if !defined(__APPLE__) && !defined(DARWIN) && !defined(WIN32) +#ifdef __linux__ #include #endif + #include #ifdef WIN32 #include #endif -#ifndef PTHREAD_MUTEX_RECURSIVE +#ifndef PTHREAD_MUTEX_RECURSIVE #define PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP #endif -typedef struct slog -{ - unsigned int nTdSafe:1; +typedef struct slog_file { + uint8_t nCurrDay; + FILE *pHandle; +} slog_file_t; + +typedef struct slog { pthread_mutex_t mutex; slog_config_t config; + slog_file_t logFile; + uint8_t nTdSafe; } slog_t; -typedef struct XLogCtx -{ - const char* pFormat; +typedef struct slog_context { + const char *pFormat; slog_flag_t eFlag; slog_date_t date; - uint8_t nFullColor; uint8_t nNewLine; } slog_context_t; +static volatile int g_nHaveSlogVerShort = 0; +static volatile int g_nHaveSlogVerLong = 0; +static char g_slogVerShort[128]; +static char g_slogVerLong[256]; + static slog_t g_slog; -static void slog_sync_init(slog_t* pSlog) +static void slog_sync_init(slog_t *pSlog) { - if (!pSlog->nTdSafe) - { - return; - } + if (!pSlog->nTdSafe) return; pthread_mutexattr_t mutexAttr; if (pthread_mutexattr_init(&mutexAttr) || - pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_RECURSIVE) || - pthread_mutex_init(&pSlog->mutex, &mutexAttr) || - pthread_mutexattr_destroy(&mutexAttr)) + pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_RECURSIVE) || + pthread_mutex_init(&pSlog->mutex, &mutexAttr) || + pthread_mutexattr_destroy(&mutexAttr)) { - printf("<%s:%d> %s: [ERROR] Can not initialize mutex: %d\n", - __FILE__, __LINE__, __FUNCTION__, errno); + printf("<%s:%d> %s: [ERROR] Can not initialize mutex: %d\n", + __FILE__, __LINE__, __func__, errno); exit(EXIT_FAILURE); } } -static void slog_lock(slog_t* pSlog) +static void slog_lock(slog_t *pSlog) { if (pSlog->nTdSafe && pthread_mutex_lock(&pSlog->mutex)) { - printf("<%s:%d> %s: [ERROR] Can not lock mutex: %d\n", - __FILE__, __LINE__, __FUNCTION__, errno); + printf("<%s:%d> %s: [ERROR] Can not lock mutex: %d\n", + __FILE__, __LINE__, __func__, errno); exit(EXIT_FAILURE); } } -static void slog_unlock(slog_t* pSlog) +static void slog_unlock(slog_t *pSlog) { if (pSlog->nTdSafe && pthread_mutex_unlock(&pSlog->mutex)) { - printf("<%s:%d> %s: [ERROR] Can not unlock mutex: %d\n", - __FILE__, __LINE__, __FUNCTION__, errno); - + printf("<%s:%d> %s: [ERROR] Can not unlock mutex: %d\n", + __FILE__, __LINE__, __func__, errno); + exit(EXIT_FAILURE); } } -static const char* slog_get_indent(slog_flag_t eFlag) +static const char *slog_get_indent(slog_flag_t eFlag) { - slog_config_t* pCfg = &g_slog.config; - if (!pCfg->nIndent) - { - return SLOG_EMPTY; - } + slog_config_t *pCfg = &g_slog.config; + if (!pCfg->nIndent) return SLOG_EMPTY; switch (eFlag) { @@ -125,13 +127,12 @@ static const char* slog_get_indent(slog_flag_t eFlag) case SLOG_NOTE: case SLOG_INFO: case SLOG_WARN: - return SLOG_SPACE; + return SLOG_SPACE; case SLOG_DEBUG: case SLOG_TRACE: case SLOG_FATAL: case SLOG_ERROR: - default: - break; + default: break; } return SLOG_EMPTY; @@ -141,22 +142,14 @@ static const char* slog_get_tag(slog_flag_t eFlag) { switch (eFlag) { - case SLOG_NOTE: - return "note"; - case SLOG_INFO: - return "info"; - case SLOG_WARN: - return "warn"; - case SLOG_DEBUG: - return "debug"; - case SLOG_ERROR: - return "error"; - case SLOG_TRACE: - return "trace"; - case SLOG_FATAL: - return "fatal"; - default: - break; + case SLOG_NOTE: return "note"; + case SLOG_INFO: return "info"; + case SLOG_WARN: return "warn"; + case SLOG_DEBUG: return "debug"; + case SLOG_ERROR: return "error"; + case SLOG_TRACE: return "trace"; + case SLOG_FATAL: return "fatal"; + default: break; } return NULL; @@ -167,38 +160,62 @@ static const char* slog_get_color(slog_flag_t eFlag) switch (eFlag) { case SLOG_NOTAG: - case SLOG_NOTE: - return SLOG_EMPTY; - case SLOG_INFO: - return SLOG_COLOR_GREEN; - case SLOG_WARN: - return SLOG_COLOR_YELLOW; - case SLOG_DEBUG: - return SLOG_COLOR_BLUE; - case SLOG_ERROR: - return SLOG_COLOR_RED; - case SLOG_TRACE: - return SLOG_COLOR_CYAN; - case SLOG_FATAL: - return SLOG_COLOR_MAGENTA; - default: - break; + case SLOG_NOTE: return SLOG_EMPTY; + case SLOG_INFO: return SLOG_COLOR_GREEN; + case SLOG_WARN: return SLOG_COLOR_YELLOW; + case SLOG_DEBUG: return SLOG_COLOR_BLUE; + case SLOG_ERROR: return SLOG_COLOR_RED; + case SLOG_TRACE: return SLOG_COLOR_CYAN; + case SLOG_FATAL: return SLOG_COLOR_MAGENTA; + default: break; } return SLOG_EMPTY; } -uint8_t slog_get_usec() +static void slog_close_file(slog_file_t *pFile) { - struct timeval tv; - if (gettimeofday(&tv, NULL) < 0) + if (pFile->pHandle != NULL) { - return 0; + fclose(pFile->pHandle); + pFile->pHandle = NULL; } - return (uint8_t)(tv.tv_usec / 10000); } -void slog_get_date(slog_date_t* pDate) +static uint8_t slog_open_file(slog_file_t *pFile, const slog_config_t *pCfg, const slog_date_t *pDate) +{ + slog_close_file(pFile); + + char sFilePath[SLOG_PATH_MAX + SLOG_NAME_MAX + SLOG_DATE_MAX]; + snprintf(sFilePath, sizeof(sFilePath), "%s/%s-%04d-%02d-%02d.log", + pCfg->sFilePath, pCfg->sFileName, pDate->nYear, pDate->nMonth, pDate->nDay); + +#ifdef _WIN32 + if (fopen_s(&pFile->pHandle, sFilePath, "a")) pFile->pHandle = NULL; +#else + pFile->pHandle = fopen(sFilePath, "a"); +#endif + + if (pFile->pHandle == NULL) + { + printf("<%s:%d> %s: [ERROR] Failed to open file: %s (%s)\n", + __FILE__, __LINE__, __func__, sFilePath, strerror(errno)); + + return 0; + } + + pFile->nCurrDay = pDate->nDay; + return 1; +} + +uint16_t slog_get_usec() +{ + struct timeval tv; + if (gettimeofday(&tv, NULL) < 0) return 0; + return (uint16_t)(tv.tv_usec / 1000); +} + +void slog_get_date(slog_date_t *pDate) { struct tm timeinfo; time_t rawtime = time(NULL); @@ -217,70 +234,68 @@ void slog_get_date(slog_date_t* pDate) pDate->nUsec = slog_get_usec(); } -static uint32_t slog_get_tid() +static size_t slog_get_tid() { -#if defined(__APPLE__) || defined(DARWIN) || defined(WIN32) - return (uint32_t)pthread_self(); +#ifdef __linux__ + return (size_t)syscall(__NR_gettid); #else - return syscall(__NR_gettid); + return (size_t)pthread_self(); #endif } -static void slog_create_tag(char* pOut, size_t nSize, slog_flag_t eFlag, const char* pColor) +static void slog_create_tag(char *pOut, size_t nSize, slog_flag_t eFlag, const char *pColor) { - slog_config_t* pCfg = &g_slog.config; + slog_config_t *pCfg = &g_slog.config; pOut[0] = SLOG_NUL; - const char* pIndent = slog_get_indent(eFlag); - const char* pTag = slog_get_tag(eFlag); + const char *pIndent = slog_get_indent(eFlag); + const char *pTag = slog_get_tag(eFlag); if (pTag == NULL) { - snprintf(pOut, nSize, pIndent); + snprintf(pOut, nSize, "%s", pIndent); return; } - if (pCfg->eColorFormat != SLOG_COLORING_TAG) - { - snprintf(pOut, nSize, "<%s>%s", pTag, pIndent); - } - else - { - snprintf(pOut, nSize, "%s<%s>%s%s", pColor, pTag, SLOG_COLOR_RESET, pIndent); - } + if (pCfg->eColorFormat != SLOG_COLORING_TAG) snprintf(pOut, nSize, "<%s>%s", pTag, pIndent); + else snprintf(pOut, nSize, "%s<%s>%s%s", pColor, pTag, SLOG_COLOR_RESET, pIndent); } -static void slog_create_tid(char* pOut, int nSize, uint8_t nTraceTid) +static void slog_create_tid(char *pOut, int nSize, uint8_t nTraceTid) { - if (!nTraceTid) - { - pOut[0] = SLOG_NUL; - } - else - { - snprintf(pOut, nSize, "(%u) ", slog_get_tid()); - } + if (!nTraceTid) pOut[0] = SLOG_NUL; + else snprintf(pOut, nSize, "(%zu) ", slog_get_tid()); } -static void slog_display_message(const slog_context_t* pCtx, const char* pInfo, int nInfoLen, const char* pInput) +static void slog_display_message(const slog_context_t *pCtx, const char *pInfo, int nInfoLen, const char *pInput) { - slog_config_t* pCfg = &g_slog.config; + slog_config_t *pCfg = &g_slog.config; + slog_file_t *pFile = &g_slog.logFile; int nCbVal = 1; - const char* pSeparator = nInfoLen > 0 ? pCfg->sSeparator : SLOG_EMPTY; - const char* pReset = pCtx->nFullColor ? SLOG_COLOR_RESET : SLOG_EMPTY; - const char* pNewLine = pCtx->nNewLine ? SLOG_NEWLINE : SLOG_EMPTY; - const char* pMessage = pInput != NULL ? pInput : SLOG_EMPTY; + uint8_t nFullColor = pCfg->eColorFormat == SLOG_COLORING_FULL ? 1 : 0; + const char *pSeparator = nInfoLen > 0 ? pCfg->sSeparator : SLOG_EMPTY; + const char *pNewLine = pCtx->nNewLine ? SLOG_NEWLINE : SLOG_EMPTY; + const char *pMessage = pInput != NULL ? pInput : SLOG_EMPTY; + const char *pReset = nFullColor ? SLOG_COLOR_RESET : SLOG_EMPTY; if (pCfg->logCallback != NULL) { size_t nLength = 0; - char* pLog = NULL; + char *pLog = NULL; + + nLength += asprintf(&pLog, "%s%s%s%s%s", pInfo, + pSeparator, pMessage, pReset, pNewLine); - nLength += asprintf(&pLog, "%s%s%s%s%s", pInfo, pSeparator, pMessage, pReset, pNewLine); if (pLog != NULL) { - nCbVal = pCfg->logCallback(pLog, nLength, pCtx->eFlag, pCfg->pCallbackCtx); + nCbVal = pCfg->logCallback ( + pLog, + nLength, + pCtx->eFlag, + pCfg->pCallbackCtx + ); + free(pLog); } } @@ -288,36 +303,26 @@ static void slog_display_message(const slog_context_t* pCtx, const char* pInfo, if (pCfg->nToScreen && nCbVal > 0) { printf("%s%s%s%s%s", pInfo, pSeparator, pMessage, pReset, pNewLine); - if (pCfg->nFlush) - { - fflush(stdout); - } + if (pCfg->nFlush) fflush(stdout); } - if (!pCfg->nToFile || nCbVal < 0) - { - return; - } - const slog_date_t* pDate = &pCtx->date; + if (!pCfg->nToFile || nCbVal < 0) return; + const slog_date_t *pDate = &pCtx->date; - char sFilePath[SLOG_PATH_MAX + SLOG_NAME_MAX + SLOG_DATE_MAX]; - snprintf(sFilePath, sizeof(sFilePath), "%s/%s-%04d-%02d-%02d.log", - pCfg->sFilePath, pCfg->sFileName, pDate->nYear, pDate->nMonth, pDate->nDay); + if (pFile->nCurrDay != pDate->nDay && pCfg->nRotate) slog_close_file(pFile); + if (pFile->pHandle == NULL && !slog_open_file(pFile, pCfg, pDate)) return; - FILE* pFile = fopen(sFilePath, "a"); - if (pFile == NULL) - { - return; - } + fprintf(pFile->pHandle, "%s%s%s%s%s", pInfo, + pSeparator, pMessage, pReset, pNewLine); - fprintf(pFile, "%s%s%s%s%s", pInfo, pSeparator, pMessage, pReset, pNewLine); - fclose(pFile); + if (pCfg->nFlush) fflush(pFile->pHandle); + if (!pCfg->nKeepOpen) slog_close_file(pFile); } -static int slog_create_info(const slog_context_t* pCtx, char* pOut, size_t nSize) +static int slog_create_info(const slog_context_t *pCtx, char* pOut, size_t nSize) { - slog_config_t* pCfg = &g_slog.config; - const slog_date_t* pDate = &pCtx->date; + slog_config_t *pCfg = &g_slog.config; + const slog_date_t *pDate = &pCtx->date; char sDate[SLOG_DATE_MAX + SLOG_NAME_MAX]; sDate[0] = SLOG_NUL; @@ -325,29 +330,30 @@ static int slog_create_info(const slog_context_t* pCtx, char* pOut, size_t nSize if (pCfg->eDateControl == SLOG_TIME_ONLY) { snprintf(sDate, sizeof(sDate), "%02d:%02d:%02d.%03d ", - pDate->nHour,pDate->nMin, pDate->nSec, pDate->nUsec); + pDate->nHour, pDate->nMin, pDate->nSec, pDate->nUsec); + } + else if (pCfg->eDateControl == SLOG_DATE_FULL) + { + snprintf(sDate, sizeof(sDate), "%04d.%02d.%02d-%02d:%02d:%02d.%03d ", + pDate->nYear, pDate->nMonth, pDate->nDay, pDate->nHour, + pDate->nMin, pDate->nSec, pDate->nUsec); } - else - if (pCfg->eDateControl == SLOG_DATE_FULL) - { - snprintf(sDate, sizeof(sDate), "%04d.%02d.%02d-%02d:%02d:%02d.%03d ", - pDate->nYear, pDate->nMonth, pDate->nDay, pDate->nHour, - pDate->nMin, pDate->nSec, pDate->nUsec); - } char sTid[SLOG_TAG_MAX], sTag[SLOG_TAG_MAX]; - const char* pColorCode = slog_get_color(pCtx->eFlag); - const char* pColor = pCtx->nFullColor ? pColorCode : SLOG_EMPTY; + uint8_t nFullColor = pCfg->eColorFormat == SLOG_COLORING_FULL ? 1 : 0; + + const char *pColorCode = slog_get_color(pCtx->eFlag); + const char *pColor = nFullColor ? pColorCode : SLOG_EMPTY; slog_create_tid(sTid, sizeof(sTid), pCfg->nTraceTid); slog_create_tag(sTag, sizeof(sTag), pCtx->eFlag, pColorCode); return snprintf(pOut, nSize, "%s%s%s%s", pColor, sTid, sDate, sTag); } -static void slog_display_heap(const slog_context_t* pCtx, va_list args) +static void slog_display_heap(const slog_context_t *pCtx, va_list args) { size_t nBytes = 0; - char* pMessage = NULL; + char *pMessage = NULL; char sLogInfo[SLOG_INFO_MAX]; nBytes += vasprintf(&pMessage, pCtx->pFormat, args); @@ -355,21 +361,18 @@ static void slog_display_heap(const slog_context_t* pCtx, va_list args) if (pMessage == NULL) { - printf("<%s:%d> %s%s %s: Can not allocate memory for input: errno(%d)\n", - __FILE__, __LINE__, SLOG_COLOR_RED, SLOG_COLOR_RESET, __FUNCTION__, errno); + printf("<%s:%d> %s%s %s: Can not allocate memory for input: errno(%d)\n", + __FILE__, __LINE__, SLOG_COLOR_RED, SLOG_COLOR_RESET, __func__, errno); return; } int nLength = slog_create_info(pCtx, sLogInfo, sizeof(sLogInfo)); slog_display_message(pCtx, sLogInfo, nLength, pMessage); - if (pMessage != NULL) - { - free(pMessage); - } + if (pMessage != NULL) free(pMessage); } -static void slog_display_stack(const slog_context_t* pCtx, va_list args) +static void slog_display_stack(const slog_context_t *pCtx, va_list args) { char sMessage[SLOG_MESSAGE_MAX]; char sLogInfo[SLOG_INFO_MAX]; @@ -379,13 +382,13 @@ static void slog_display_stack(const slog_context_t* pCtx, va_list args) slog_display_message(pCtx, sLogInfo, nLength, sMessage); } -void slog_display(slog_flag_t eFlag, uint8_t nNewLine, const char* pFormat, ...) +void slog_display(slog_flag_t eFlag, uint8_t nNewLine, char *pFormat, ...) { slog_lock(&g_slog); - slog_config_t* pCfg = &g_slog.config; + slog_config_t *pCfg = &g_slog.config; if ((SLOG_FLAGS_CHECK(g_slog.config.nFlags, eFlag)) && - (g_slog.config.nToScreen || g_slog.config.nToFile)) + (g_slog.config.nToScreen || g_slog.config.nToFile)) { slog_context_t ctx; slog_get_date(&ctx.date); @@ -393,9 +396,8 @@ void slog_display(slog_flag_t eFlag, uint8_t nNewLine, const char* pFormat, ...) ctx.eFlag = eFlag; ctx.pFormat = pFormat; ctx.nNewLine = nNewLine; - ctx.nFullColor = pCfg->eColorFormat == SLOG_COLORING_FULL ? 1 : 0; - void(*slog_display_args)(const slog_context_t* pCtx, va_list args); + void(*slog_display_args)(const slog_context_t *pCtx, va_list args); slog_display_args = pCfg->nUseHeap ? slog_display_heap : slog_display_stack; va_list args; @@ -407,33 +409,50 @@ void slog_display(slog_flag_t eFlag, uint8_t nNewLine, const char* pFormat, ...) slog_unlock(&g_slog); } -size_t slog_version(char* pDest, size_t nSize, uint8_t nMin) +const char* slog_version(uint8_t nShort) { - size_t nLength = 0; + if (nShort) + { + if (!g_nHaveSlogVerShort) + { + snprintf(g_slogVerShort, sizeof(g_slogVerShort), "%d.%d.%d", + SLOG_VERSION_MAJOR, SLOG_VERSION_MINOR, SLOG_BUILD_NUMBER); - /* Version short */ - if (nMin) - nLength = snprintf(pDest, nSize, "%d.%d.%d", - SLOG_VERSION_MAJOR, SLOG_VERSION_MINOR, SLOG_BUILD_NUM); + g_nHaveSlogVerShort = 1; + } - /* Version long */ - else - nLength = snprintf(pDest, nSize, "%d.%d build %d (%s)", - SLOG_VERSION_MAJOR, SLOG_VERSION_MINOR, SLOG_BUILD_NUM, __DATE__); + return g_slogVerShort; + } - return nLength; + if (!g_nHaveSlogVerLong) + { + snprintf(g_slogVerLong, sizeof(g_slogVerLong), "%d.%d build %d (%s)", + SLOG_VERSION_MAJOR, SLOG_VERSION_MINOR, SLOG_BUILD_NUMBER, __DATE__); + + g_nHaveSlogVerLong = 1; + } + + return g_slogVerLong; } -void slog_config_get(slog_config_t* pCfg) +void slog_config_get(slog_config_t *pCfg) { slog_lock(&g_slog); *pCfg = g_slog.config; slog_unlock(&g_slog); } -void slog_config_set(slog_config_t* pCfg) +void slog_config_set(slog_config_t *pCfg) { slog_lock(&g_slog); + slog_config_t *pOldCfg = &g_slog.config; + slog_file_t *pFile = &g_slog.logFile; + + if (!pCfg->nToFile || + strncmp(pOldCfg->sFilePath, pCfg->sFilePath, sizeof(pOldCfg->sFilePath)) || + strncmp(pOldCfg->sFileName, pCfg->sFileName, sizeof(pOldCfg->sFileName))) + slog_close_file(pFile); /* Log function will open it again if required */ + g_slog.config = *pCfg; slog_unlock(&g_slog); } @@ -441,11 +460,11 @@ void slog_config_set(slog_config_t* pCfg) void slog_enable(slog_flag_t eFlag) { slog_lock(&g_slog); + slog_config_t *pCfg = &g_slog.config; - if (!SLOG_FLAGS_CHECK(g_slog.config.nFlags, eFlag)) - { - g_slog.config.nFlags |= eFlag; - } + + if (eFlag == SLOG_FLAGS_ALL) pCfg->nFlags = SLOG_FLAGS_ALL; + else if (!SLOG_FLAGS_CHECK(pCfg->nFlags, eFlag)) pCfg->nFlags |= eFlag; slog_unlock(&g_slog); } @@ -453,19 +472,18 @@ void slog_enable(slog_flag_t eFlag) void slog_disable(slog_flag_t eFlag) { slog_lock(&g_slog); + slog_config_t *pCfg = &g_slog.config; - if (SLOG_FLAGS_CHECK(g_slog.config.nFlags, eFlag)) - { - g_slog.config.nFlags &= ~eFlag; - } + if (eFlag == SLOG_FLAGS_ALL) pCfg->nFlags = 0; + else if (SLOG_FLAGS_CHECK(pCfg->nFlags, eFlag)) pCfg->nFlags &= ~eFlag; slog_unlock(&g_slog); } -void slog_separator_set(const char* pFormat, ...) +void slog_separator_set(const char *pFormat, ...) { slog_lock(&g_slog); - slog_config_t* pCfg = &g_slog.config; + slog_config_t *pCfg = &g_slog.config; va_list args; va_start(args, pFormat); @@ -487,10 +505,10 @@ void slog_indent(uint8_t nEnable) slog_unlock(&g_slog); } -void slog_callback_set(slog_cb_t callback, void* pContext) +void slog_callback_set(slog_cb_t callback, void *pContext) { slog_lock(&g_slog); - slog_config_t* pCfg = &g_slog.config; + slog_config_t *pCfg = &g_slog.config; pCfg->pCallbackCtx = pContext; pCfg->logCallback = callback; slog_unlock(&g_slog); @@ -498,8 +516,10 @@ void slog_callback_set(slog_cb_t callback, void* pContext) void slog_init(const char* pName, uint16_t nFlags, uint8_t nTdSafe) { + slog_config_t *pCfg = &g_slog.config; + slog_file_t *pFile = &g_slog.logFile; + /* Set up default values */ - slog_config_t* pCfg = &g_slog.config; pCfg->eColorFormat = SLOG_COLORING_TAG; pCfg->eDateControl = SLOG_TIME_ONLY; pCfg->pCallbackCtx = NULL; @@ -508,19 +528,24 @@ void slog_init(const char* pName, uint16_t nFlags, uint8_t nTdSafe) pCfg->sSeparator[1] = '\0'; pCfg->sFilePath[0] = '.'; pCfg->sFilePath[1] = '\0'; + pCfg->nKeepOpen = 0; pCfg->nTraceTid = 0; pCfg->nToScreen = 1; pCfg->nUseHeap = 0; pCfg->nToFile = 0; pCfg->nIndent = 0; + pCfg->nRotate = 1; pCfg->nFlush = 0; pCfg->nFlags = nFlags; - const char* pFileName = (pName != NULL) ? pName : SLOG_NAME_DEFAULT; + const char *pFileName = (pName != NULL) ? pName : SLOG_NAME_DEFAULT; snprintf(pCfg->sFileName, sizeof(pCfg->sFileName), "%s", pFileName); + pFile->pHandle = NULL; + pFile->nCurrDay = 0; + #ifdef WIN32 - // Enable color support + /* Enable color support */ HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE); DWORD dwMode = 0; GetConsoleMode(hOutput, &dwMode); @@ -535,8 +560,14 @@ void slog_init(const char* pName, uint16_t nFlags, uint8_t nTdSafe) void slog_destroy() { + slog_lock(&g_slog); + + memset(&g_slog.config, 0, sizeof(g_slog.config)); g_slog.config.pCallbackCtx = NULL; g_slog.config.logCallback = NULL; + slog_close_file(&g_slog.logFile); + + slog_unlock(&g_slog); if (g_slog.nTdSafe) { diff --git a/src/monocoque/slog/slog.h b/src/monocoque/slog/slog.h index bb53e1e..8c7213f 100644 --- a/src/monocoque/slog/slog.h +++ b/src/monocoque/slog/slog.h @@ -31,11 +31,12 @@ extern "C" { #include #include +#include /* SLog version information */ #define SLOG_VERSION_MAJOR 1 #define SLOG_VERSION_MINOR 8 -#define SLOG_BUILD_NUM 26 +#define SLOG_BUILD_NUMBER 37 /* Supported colors */ #define SLOG_COLOR_NORMAL "\x1B[0m" @@ -73,19 +74,18 @@ extern "C" { #define SLOG_EMPTY "" #define SLOG_NUL '\0' -typedef struct SLogDate -{ +typedef struct slog_date { uint16_t nYear; uint8_t nMonth; uint8_t nDay; uint8_t nHour; uint8_t nMin; uint8_t nSec; - uint8_t nUsec; + uint16_t nUsec; } slog_date_t; -uint8_t slog_get_usec(); -void slog_get_date(slog_date_t* pDate); +uint16_t slog_get_usec(); +void slog_get_date(slog_date_t *pDate); /* Log level flags */ typedef enum @@ -100,7 +100,7 @@ typedef enum SLOG_FATAL = (1 << 7) } slog_flag_t; -typedef int(*slog_cb_t)(const char* pLog, size_t nLength, slog_flag_t eFlag, void* pCtx); +typedef int(*slog_cb_t)(const char *pLog, size_t nLength, slog_flag_t eFlag, void *pCtx); /* Output coloring control flags */ typedef enum @@ -117,32 +117,25 @@ typedef enum SLOG_DATE_FULL } slog_date_ctrl_t; -#define slog(...) \ - slog_display(SLOG_NOTAG, 1, __VA_ARGS__) +/* Slog function definitions */ +#define slog(...) slog_display(SLOG_NOTAG, 1, __VA_ARGS__) +#define slog_note(...) slog_display(SLOG_NOTE, 1, __VA_ARGS__) +#define slog_info(...) slog_display(SLOG_INFO, 1, __VA_ARGS__) +#define slog_warn(...) slog_display(SLOG_WARN, 1, __VA_ARGS__) +#define slog_debug(...) slog_display(SLOG_DEBUG, 1, __VA_ARGS__) +#define slog_error(...) slog_display(SLOG_ERROR, 1, __VA_ARGS__) +#define slog_trace(...) slog_display(SLOG_TRACE, 1, SLOG_THROW_LOCATION __VA_ARGS__) +#define slog_fatal(...) slog_display(SLOG_FATAL, 1, SLOG_THROW_LOCATION __VA_ARGS__) -#define slogwn(...) \ - slog_display(SLOG_NOTAG, 0, __VA_ARGS__) - -#define slog_note(...) \ - slog_display(SLOG_NOTE, 1, __VA_ARGS__) - -#define slog_info(...) \ - slog_display(SLOG_INFO, 1, __VA_ARGS__) - -#define slog_warn(...) \ - slog_display(SLOG_WARN, 1, __VA_ARGS__) - -#define slog_debug(...) \ - slog_display(SLOG_DEBUG, 1, __VA_ARGS__) - -#define slog_error(...) \ - slog_display(SLOG_ERROR, 1, __VA_ARGS__) - -#define slog_trace(...) \ - slog_display(SLOG_TRACE, 1, SLOG_THROW_LOCATION __VA_ARGS__) - -#define slog_fatal(...) \ - slog_display(SLOG_FATAL, 1, SLOG_THROW_LOCATION __VA_ARGS__) +/* No new line definitions */ +#define slog_wn(...) slog_display(SLOG_NOTAG, 0, __VA_ARGS__) +#define slog_note_wn(...) slog_display(SLOG_NOTE, 0, __VA_ARGS__) +#define slog_info_wn(...) slog_display(SLOG_INFO, 0, __VA_ARGS__) +#define slog_warn_wn(...) slog_display(SLOG_WARN, 0, __VA_ARGS__) +#define slog_debug_wn(...) slog_display(SLOG_DEBUG, 0, __VA_ARGS__) +#define slog_error_wn(...) slog_display(SLOG_ERROR, 0, __VA_ARGS__) +#define slog_trace_wn(...) slog_display(SLOG_TRACE, 0, SLOG_THROW_LOCATION __VA_ARGS__) +#define slog_fatal_wn(...) slog_display(SLOG_FATAL, 0, SLOG_THROW_LOCATION __VA_ARGS__) /* Short name definitions */ #define slogn(...) slog_note(__VA_ARGS__) @@ -153,40 +146,50 @@ typedef enum #define slogt(...) slog_trace(__VA_ARGS__) #define slogf(...) slog_fatal(__VA_ARGS__) -typedef struct SLogConfig -{ - slog_date_ctrl_t eDateControl; // Display output with date format - slog_coloring_t eColorFormat; // Output color format control - slog_cb_t logCallback; // Log callback to collect logs - void* pCallbackCtx; // Data pointer passed to log callback +/* Short name definitions without new line */ +#define slogn_wn(...) slog_note_wn(__VA_ARGS__) +#define slogi_wn(...) slog_info_wn(__VA_ARGS__) +#define slogw_wn(...) slog_warn_wn(__VA_ARGS__) +#define slogd_wn(...) slog_debug_wn( __VA_ARGS__) +#define sloge_wn(...) slog_error_wn( __VA_ARGS__) +#define slogt_wn(...) slog_trace_wn(__VA_ARGS__) +#define slogf_wn(...) slog_fatal_wn(__VA_ARGS__) - uint8_t nTraceTid; // Trace thread ID and display in output - uint8_t nToScreen; // Enable screen logging - uint8_t nUseHeap; // Use dynamic allocation - uint8_t nToFile; // Enable file logging - uint8_t nIndent; // Enable indentations - uint8_t nFlush; // Flush stdout after screen log - uint16_t nFlags; // Allowed log level flags +typedef struct SLogConfig { + slog_date_ctrl_t eDateControl; // Display output with date format + slog_coloring_t eColorFormat; // Output color format control + slog_cb_t logCallback; // Log callback to collect logs + void* pCallbackCtx; // Data pointer passed to log callback + + uint8_t nKeepOpen; // Keep file handle open for next file writes + uint8_t nTraceTid; // Trace thread ID and display in output + uint8_t nToScreen; // Enable screen logging + uint8_t nUseHeap; // Use dynamic allocation + uint8_t nToFile; // Enable file logging + uint8_t nIndent; // Enable indentations + uint8_t nRotate; // Enable log rotation + uint8_t nFlush; // Flush stdout after screen log + uint16_t nFlags; // Allowed log level flags char sSeparator[SLOG_NAME_MAX]; // Separator between info and log char sFileName[SLOG_NAME_MAX]; // Output file name for logs char sFilePath[SLOG_PATH_MAX]; // Output file path for logs } slog_config_t; -size_t slog_version(char* pDest, size_t nSize, uint8_t nMin); -void slog_config_get(slog_config_t* pCfg); -void slog_config_set(slog_config_t* pCfg); +const char* slog_version(uint8_t nShort); +void slog_config_get(slog_config_t *pCfg); +void slog_config_set(slog_config_t *pCfg); -void slog_separator_set(const char* pFormat, ...); -void slog_callback_set(slog_cb_t callback, void* pContext); +void slog_separator_set(const char *pFormat, ...); +void slog_callback_set(slog_cb_t callback, void *pContext); void slog_indent(uint8_t nEnable); void slog_enable(slog_flag_t eFlag); void slog_disable(slog_flag_t eFlag); void slog_init(const char* pName, uint16_t nFlags, uint8_t nTdSafe); -void slog_display(slog_flag_t eFlag, uint8_t nNewLine, const char* pFormat, ...); -void slog_destroy(); // Needed only if the slog_init() function argument nTdSafe > 0 +void slog_display(slog_flag_t eFlag, uint8_t nNewLine, char *pFormat, ...); +void slog_destroy(); // Required only if (nTdSafe > 0 || nKeepOpen > 0) #ifdef __cplusplus }