fsfw-example-common/example/test/testFmt.h

163 lines
5.6 KiB
C
Raw Normal View History

2022-05-08 02:06:29 +02:00
#ifndef FSFW_EXAMPLE_HOSTED_TESTFMT_H
#define FSFW_EXAMPLE_HOSTED_TESTFMT_H
#include <fmt/chrono.h>
#include <fmt/color.h>
2022-05-08 17:11:43 +02:00
#include <fmt/compile.h>
2022-05-08 02:06:29 +02:00
#include <fmt/core.h>
#include <array>
#include <cstdint>
#include "fsfw/ipc/MutexFactory.h"
#include "fsfw/ipc/MutexGuard.h"
#include "fsfw/ipc/MutexIF.h"
#include "fsfw/timemanager/Clock.h"
2022-05-22 15:30:08 +02:00
#define __FILENAME_REL__ (((const char *)__FILE__ + SOURCE_PATH_SIZE))
2022-08-08 12:32:06 +02:00
#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
2022-05-08 17:11:43 +02:00
2022-05-08 02:06:29 +02:00
void fmtTests();
namespace sif {
2022-05-08 17:11:43 +02:00
static std::array<char, 524> PRINT_BUF = {};
static const char INFO_PREFIX[] = "INFO";
static const char DEBUG_PREFIX[] = "DEBUG";
static const char WARNING_PREFIX[] = "WARNING";
static const char ERROR_PREFIX[] = "ERROR";
2022-08-08 12:32:06 +02:00
enum class LogLevel : unsigned int { DEBUG = 0, INFO = 1, WARNING = 2, ERROR = 3 };
2022-05-08 17:11:43 +02:00
2022-08-08 12:32:06 +02:00
static const char *PREFIX_ARR[4] = {DEBUG_PREFIX, INFO_PREFIX, WARNING_PREFIX, ERROR_PREFIX};
2022-05-08 17:11:43 +02:00
static const std::array<fmt::color, 4> LOG_COLOR_ARR = {
2022-08-08 12:32:06 +02:00
fmt::color::deep_sky_blue, fmt::color::forest_green, fmt::color::orange_red, fmt::color::red};
2022-05-08 17:11:43 +02:00
2022-05-22 15:30:08 +02:00
static MutexIF *PRINT_MUTEX = MutexFactory::instance()->createMutex();
2022-05-08 02:06:29 +02:00
2022-05-08 17:11:43 +02:00
static size_t writeTypePrefix(LogLevel level) {
auto idx = static_cast<unsigned int>(level);
2022-08-08 12:32:06 +02:00
const auto result =
fmt::format_to_n(PRINT_BUF.begin(), PRINT_BUF.size() - 1,
fmt::runtime(fmt::format(fg(LOG_COLOR_ARR[idx]), PREFIX_ARR[idx])));
2022-05-08 17:11:43 +02:00
return result.size;
}
2022-05-08 02:06:29 +02:00
template <typename... T>
2022-08-08 12:32:06 +02:00
size_t logTraced(LogLevel level, const char *file, unsigned int line, bool timed,
fmt::format_string<T...> fmt, T &&...args) noexcept {
2022-05-08 17:11:43 +02:00
try {
MutexGuard mg(PRINT_MUTEX);
size_t bufPos = writeTypePrefix(level);
auto currentIter = PRINT_BUF.begin() + bufPos;
if (timed) {
Clock::TimeOfDay_t logTime;
Clock::getDateAndTime(&logTime);
2022-08-08 12:32:06 +02:00
const auto result = fmt::format_to_n(currentIter, PRINT_BUF.size() - 1 - bufPos,
" | {}[l.{}] | {:02}:{:02}:{:02}.{:03} | {}", file, line,
logTime.hour, logTime.minute, logTime.second,
logTime.usecond / 1000, fmt::format(fmt, args...));
2022-05-08 17:11:43 +02:00
*result.out = '\0';
bufPos += result.size;
} else {
2022-08-08 12:32:06 +02:00
const auto result =
fmt::format_to_n(currentIter, PRINT_BUF.size() - 1 - bufPos, " | {}[l.{}] | {}", file,
line, fmt::format(fmt, args...));
2022-05-08 17:11:43 +02:00
*result.out = '\0';
bufPos += result.size;
}
fmt::print(fmt::runtime(PRINT_BUF.data()));
return bufPos;
2022-05-22 15:30:08 +02:00
} catch (const fmt::v8::format_error &e) {
2022-05-08 17:11:43 +02:00
fmt::print("Printing failed with error: {}\n", e.what());
return 0;
}
2022-05-08 02:06:29 +02:00
}
template <typename... T>
2022-08-08 12:32:06 +02:00
size_t log(LogLevel level, bool timed, fmt::format_string<T...> fmt, T &&...args) noexcept {
2022-05-08 17:11:43 +02:00
try {
MutexGuard mg(PRINT_MUTEX);
size_t bufPos = writeTypePrefix(level);
auto currentIter = PRINT_BUF.begin() + bufPos;
if (timed) {
Clock::TimeOfDay_t logTime;
Clock::getDateAndTime(&logTime);
const auto result = fmt::format_to_n(
2022-08-08 12:32:06 +02:00
currentIter, PRINT_BUF.size() - bufPos, " | {:02}:{:02}:{:02}.{:03} | {}", logTime.hour,
logTime.minute, logTime.second, logTime.usecond / 1000, fmt::format(fmt, args...));
2022-05-08 17:11:43 +02:00
bufPos += result.size;
}
fmt::print(fmt::runtime(PRINT_BUF.data()));
return bufPos;
2022-05-22 15:30:08 +02:00
} catch (const fmt::v8::format_error &e) {
2022-05-08 17:11:43 +02:00
fmt::print("Printing failed with error: {}\n", e.what());
return 0;
}
2022-05-08 02:06:29 +02:00
}
template <typename... T>
2022-05-22 15:30:08 +02:00
void fdebug(const char *file, unsigned int line, fmt::format_string<T...> fmt,
T &&...args) noexcept {
2022-05-08 17:11:43 +02:00
logTraced(LogLevel::DEBUG, file, line, false, fmt, args...);
2022-05-08 02:06:29 +02:00
}
template <typename... T>
2022-05-22 15:30:08 +02:00
void fdebug_t(const char *file, unsigned int line, fmt::format_string<T...> fmt,
T &&...args) noexcept {
2022-05-08 17:11:43 +02:00
logTraced(LogLevel::DEBUG, file, line, true, fmt, args...);
2022-05-08 02:06:29 +02:00
}
template <typename... T>
2022-05-22 15:30:08 +02:00
void finfo_t(fmt::format_string<T...> fmt, T &&...args) {
2022-05-08 17:11:43 +02:00
log(LogLevel::INFO, true, fmt, args...);
2022-05-08 02:06:29 +02:00
}
2022-08-08 12:32:06 +02:00
template <typename... T>
void finfo(fmt::format_string<T...> fmt, T &&...args) {
2022-05-08 17:11:43 +02:00
log(LogLevel::INFO, false, fmt, args...);
2022-05-08 02:06:29 +02:00
}
template <typename... T>
2022-08-08 12:32:06 +02:00
void fwarning(const char *file, unsigned int line, fmt::format_string<T...> fmt, T &&...args) {
2022-05-08 17:11:43 +02:00
logTraced(LogLevel::WARNING, file, line, false, fmt, args...);
2022-05-08 02:06:29 +02:00
}
template <typename... T>
2022-08-08 12:32:06 +02:00
void fwarning_t(const char *file, unsigned int line, fmt::format_string<T...> fmt, T &&...args) {
2022-05-08 17:11:43 +02:00
logTraced(LogLevel::WARNING, file, line, true, fmt, args...);
2022-05-08 02:06:29 +02:00
}
template <typename... T>
2022-08-08 12:32:06 +02:00
void ferror(const char *file, unsigned int line, fmt::format_string<T...> fmt, T &&...args) {
2022-05-08 17:11:43 +02:00
logTraced(LogLevel::ERROR, file, line, false, fmt, args...);
2022-05-08 02:06:29 +02:00
}
template <typename... T>
2022-08-08 12:32:06 +02:00
void ferror_t(const char *file, unsigned int line, fmt::format_string<T...> fmt, T &&...args) {
2022-05-08 17:11:43 +02:00
logTraced(LogLevel::ERROR, file, line, true, fmt, args...);
2022-05-08 02:06:29 +02:00
}
2022-08-08 12:32:06 +02:00
} // namespace sif
2022-05-08 17:11:43 +02:00
#define FSFW_LOGI(format, ...) finfo(FMT_STRING(format), __VA_ARGS__)
#define FSFW_LOGIT(format, ...) finfo_t(FMT_STRING(format), __VA_ARGS__)
2022-08-08 12:32:06 +02:00
#define FSFW_LOGD(format, ...) sif::fdebug(__FILENAME__, __LINE__, FMT_STRING(format), __VA_ARGS__)
2022-05-08 17:11:43 +02:00
2022-08-08 12:32:06 +02:00
#define FSFW_LOGDT(format, ...) fdebug_t(__FILENAME__, __LINE__, FMT_STRING(format), __VA_ARGS__)
2022-05-08 17:11:43 +02:00
2022-08-08 12:32:06 +02:00
#define FSFW_LOGW(format, ...) fdebug(__FILENAME__, __LINE__, FMT_STRING(format), __VA_ARGS__)
2022-05-08 17:11:43 +02:00
2022-08-08 12:32:06 +02:00
#define FSFW_LOGWT(format, ...) fdebug_t(__FILENAME__, __LINE__, FMT_STRING(format), __VA_ARGS__)
2022-05-08 17:11:43 +02:00
2022-08-08 12:32:06 +02:00
#define FSFW_LOGE(format, ...) fdebug(__FILENAME__, __LINE__, FMT_STRING(format), __VA_ARGS__)
2022-05-08 17:11:43 +02:00
2022-08-08 12:32:06 +02:00
#define FSFW_LOGET(format, ...) fdebug_t(__FILENAME__, __LINE__, FMT_STRING(format), __VA_ARGS__)
2022-05-08 02:06:29 +02:00
2022-08-08 12:32:06 +02:00
#endif // FSFW_EXAMPLE_HOSTED_TESTFMT_H