// c++11
template<enum Log>
constexpr string_view logGetColor() {
return "\e[m";
}
template<>
constexpr string_view logGetColor<Log::General>() {
return "\e[m";
}
template<>
constexpr string_view logGetColor<Log::Warning>() {
return "\e[33m";
}
template<>
constexpr string_view logGetColor<Log::Error>() {
return "\e[31m";
}
template<>
constexpr string_view logGetColor<Log::Alert>() {
return "\e[41m";
}
template<>
constexpr string_view logGetColor<Log::Debug>() {
return "\e[2m";
}
constexpr std::size_t strlen_iter(const char *filename, size_t size) {
return filename[size] == '\0'? size : strlen_iter(filename, size + 1);
}
constexpr std::size_t strlen(const char *filename) {
return strlen_iter(filename, 0);
}
constexpr std::size_t trimFilePath_loop(const char *filename, std::size_t size) {
return ((size > 0) && (filename[size] != '/')) ?
trimFilePath_loop(filename, size - 1)
: size;
}
constexpr string_view trimFilePath2(const char *filename, size_t length) {
return (!length)? filename + length :
filename + length + 1;
}
constexpr string_view trimFilePath1(const char *filename, size_t length) {
return (!length)?
filename + length
: filename[length - 1] == '.'?
filename + length + 1
: trimFilePath2(filename, trimFilePath_loop(filename, length - 1));
}
constexpr string_view trimFilePath(const char *filename, size_t length) {
return trimFilePath1(filename, trimFilePath_loop(filename, length));
}
constexpr string_view trimFilePath(const char *filename) {
return trimFilePath(filename, strlen(filename));
}
#define DETAIL_WRITE_LOG_SUM3(a, b, out, COUNTER) static constexpr auto A##COUNTER = (a); static constexpr auto B##COUNTER = (b); static constexpr auto out = A##COUNTER + B##COUNTER;
#define DETAIL_WRITE_LOG_SUM2(a, b, out, COUNTER) DETAIL_WRITE_LOG_SUM3(a, b, out, COUNTER)
#define DETAIL_WRITE_LOG_SUM(a, b, out) DETAIL_WRITE_LOG_SUM2(a, b, out, __COUNTER__)
#define DETAIL_WRITE_LOG(_filename, _line, _type, s_type, _fmt, ...) do {\
static constexpr string_view view_filename = detail::trimFilePath(_filename);\
static constexpr auto view_size = view_filename.size(); \
static constexpr auto color = logGetColor<_type>(); \
static constexpr auto color_size = color.size(); \
DETAIL_WRITE_LOG_SUM(make_constexpr_string<color_size>(color.data()), make_constexpr_string("%s "), part1); \
DETAIL_WRITE_LOG_SUM(part1, make_constexpr_string(s_type), part2); \
DETAIL_WRITE_LOG_SUM(part2, make_constexpr_string(": "), part3); \
DETAIL_WRITE_LOG_SUM(part3, make_constexpr_string<view_size>(view_filename.data()), part4); \
DETAIL_WRITE_LOG_SUM(part4, make_constexpr_string(": "), part5); \
DETAIL_WRITE_LOG_SUM(part5, make_constexpr_string(_line), part6); \
DETAIL_WRITE_LOG_SUM(part6, make_constexpr_string(": "), part7); \
DETAIL_WRITE_LOG_SUM(part7, make_constexpr_string(_fmt), part8); \
DETAIL_WRITE_LOG_SUM(part8, make_constexpr_string("\e[m\n"), part9); \
static constexpr auto fmt_ = part9; \
time_t t;\
tm now;\
char time_str[40];\
std::time(&t);\
localtime_r(&t, &now);\
std::strftime(time_str, sizeof(time_str), "%Y-%m-%dT%H:%M:%S", &now);\
printf(fmt_.data(), time_str,##__VA_ARGS__); \
} while(0)
//c++14
namespace detail {
constexpr string_view logGetColor(Log type) {
switch (type) {
case Log::General: return "\e[m";
case Log::Warning: return "\e[33m";
case Log::Error: return "\e[31m";
case Log::Alert: return "\e[41m";
case Log::Debug: return "\e[2m";
}
return "\e[m";
}
constexpr string_view trimFilePath(const char *filename) {
size_t length = 0;
for (; *filename; ++length, ++filename) {}
for (; length > 0 && *filename != '/'; --length, --filename) {}
if (!length) {
return filename;
}
if (*(filename-1) == '.') {
return filename + 1;
}
for (--filename, --length; length > 0 && *filename != '/'; --length, --filename) {}
return (!length)? filename : filename + 1;
}
}
#define DETAIL_WRITE_LOG(_filename, _line, _type, s_type, _fmt, ...) do {\
static constexpr string_view view_filename = detail::trimFilePath(_filename);\
static constexpr auto color = detail::logGetColor(_type); \
static constexpr auto color_size = color.size(); \
static constexpr auto fmt_ = make_constexpr_string<color_size>(color.data()) + "HOST: %s " + make_constexpr_string(s_type) + ": " + make_constexpr_string<view_filename.size()>(view_filename.data()) + ":" + _line + ": " + _fmt + "\e[m" "\n"; \
time_t t;\
tm now;\
char time_str[256];\
std::time(&t);\
localtime_r(&t, &now);\
std::strftime(time_str, sizeof(time_str), "%Y-%m-%dT%H:%M:%S", &now);\
printf(fmt_.data(), time_str ,##__VA_ARGS__); \
} while(0)