mirror of
https://github.com/AlexandreRouma/SDRPlusPlus.git
synced 2025-07-09 02:25:24 +02:00
Switched to a custom logging lib instead of that spdlog junk
This commit is contained in:
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <utils/flog.h>
|
||||
|
||||
template <class T>
|
||||
struct EventHandler {
|
||||
@ -32,7 +32,7 @@ public:
|
||||
|
||||
void unbindHandler(EventHandler<T>* handler) {
|
||||
if (std::find(handlers.begin(), handlers.end(), handler) == handlers.end()) {
|
||||
spdlog::error("Tried to remove a non-existent event handler");
|
||||
flog::error("Tried to remove a non-existent event handler");
|
||||
return;
|
||||
}
|
||||
handlers.erase(std::remove(handlers.begin(), handlers.end(), handler), handlers.end());
|
||||
|
259
core/src/utils/flog.cpp
Normal file
259
core/src/utils/flog.cpp
Normal file
@ -0,0 +1,259 @@
|
||||
#include "flog.h"
|
||||
#include <mutex>
|
||||
#include <chrono>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include <log.h>
|
||||
#ifndef FLOG_ANDROID_TAG
|
||||
#define FLOG_ANDROID_TAG "flog"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#define FORMAT_BUF_SIZE 16
|
||||
#define ESCAPE_CHAR '\\'
|
||||
|
||||
namespace flog {
|
||||
std::mutex outMtx;
|
||||
|
||||
const char* TYPE_STR[_TYPE_COUNT] = {
|
||||
"DEBUG",
|
||||
"INFO",
|
||||
"WARN",
|
||||
"ERROR"
|
||||
};
|
||||
|
||||
#ifdef _WIN32
|
||||
#define COLOR_WHITE (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE)
|
||||
const WORD TYPE_COLORS[_TYPE_COUNT] = {
|
||||
FOREGROUND_GREEN | FOREGROUND_BLUE,
|
||||
FOREGROUND_GREEN,
|
||||
FOREGROUND_RED | FOREGROUND_GREEN,
|
||||
FOREGROUND_RED
|
||||
};
|
||||
#else
|
||||
#define COLOR_WHITE "\x1B[0m"
|
||||
const char* TYPE_COLORS[_TYPE_COUNT] = {
|
||||
"\x1B[36m",
|
||||
"\x1B[32m",
|
||||
"\x1B[33m",
|
||||
"\x1B[31m",
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef __ANDROID__
|
||||
const android_LogPriority TYPE_PRIORITIES[_TYPE_COUNT] = {
|
||||
ANDROID_LOG_DEBUG,
|
||||
ANDROID_LOG_INFO,
|
||||
ANDROID_LOG_WARN,
|
||||
ANDROID_LOG_ERROR
|
||||
};
|
||||
#endif
|
||||
|
||||
void __log__(Type type, const char* fmt, const std::vector<std::string>& args) {
|
||||
// Reserve a buffer for the final output
|
||||
int argCount = args.size();
|
||||
int fmtLen = strlen(fmt) + 1;
|
||||
int totSize = fmtLen;
|
||||
for (const auto& a : args) { totSize += a.size(); }
|
||||
std::string out;
|
||||
out.reserve(totSize);
|
||||
|
||||
// Get output stream depending on type
|
||||
FILE* outStream = (type == TYPE_ERROR) ? stderr : stdout;
|
||||
|
||||
// Parse format string
|
||||
bool escaped = false;
|
||||
int formatCounter = 0;
|
||||
bool inFormat = false;
|
||||
int formatLen = 0;
|
||||
char formatBuf[FORMAT_BUF_SIZE+1];
|
||||
for (int i = 0; i < fmtLen; i++) {
|
||||
// Get char
|
||||
const char c = fmt[i];
|
||||
|
||||
// If this character is escaped, don't try to parse it
|
||||
if (escaped) {
|
||||
escaped = false;
|
||||
out += c;
|
||||
continue;
|
||||
}
|
||||
|
||||
// State machine
|
||||
if (!inFormat && c != '{') {
|
||||
// Write to formatted output if not escape character
|
||||
if (c == ESCAPE_CHAR) {
|
||||
escaped = true;
|
||||
}
|
||||
else {
|
||||
out += c;
|
||||
}
|
||||
}
|
||||
else if (!inFormat) {
|
||||
// Start format mode
|
||||
inFormat = true;
|
||||
}
|
||||
else if (c == '}') {
|
||||
// Stop format mode
|
||||
inFormat = false;
|
||||
|
||||
// Insert string value or error
|
||||
if (!formatLen) {
|
||||
// Use format counter as ID if available or print wrong format string
|
||||
if (formatCounter < argCount) {
|
||||
out += args[formatCounter++];
|
||||
}
|
||||
else {
|
||||
out += "{}";
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Parse number
|
||||
formatBuf[formatLen] = 0;
|
||||
formatCounter = std::atoi(formatBuf);
|
||||
|
||||
// Use ID if available or print wrong format string
|
||||
if (formatCounter < argCount) {
|
||||
out += args[formatCounter];
|
||||
}
|
||||
else {
|
||||
out += '{';
|
||||
out += formatBuf;
|
||||
out += '}';
|
||||
}
|
||||
|
||||
// Increment format counter
|
||||
formatCounter++;
|
||||
}
|
||||
|
||||
// Reset format counter
|
||||
formatLen = 0;
|
||||
}
|
||||
else {
|
||||
// Add to format buffer
|
||||
if (formatLen < FORMAT_BUF_SIZE) { formatBuf[formatLen++] = c; }
|
||||
}
|
||||
}
|
||||
|
||||
// Get time
|
||||
auto now = std::chrono::system_clock::now();
|
||||
auto nowt = std::chrono::system_clock::to_time_t(now);
|
||||
auto nowc = std::localtime(&nowt); // TODO: This is not threadsafe
|
||||
|
||||
// Write to output
|
||||
{
|
||||
std::lock_guard<std::mutex> lck(outMtx);
|
||||
#if defined(_WIN32)
|
||||
// Get output handle and return if invalid
|
||||
int wOutStream = (type == TYPE_ERROR) ? STD_ERROR_HANDLE : STD_OUTPUT_HANDLE;
|
||||
HANDLE conHndl = GetStdHandle(wOutStream);
|
||||
if (!conHndl || conHndl == INVALID_HANDLE_VALUE) { return; }
|
||||
|
||||
// Print beginning of log line
|
||||
SetConsoleTextAttribute(conHndl, COLOR_WHITE);
|
||||
fprintf(outStream, "[%02d/%02d/%02d %02d:%02d:%02d.%03d] [", nowc->tm_mday, nowc->tm_mon + 1, nowc->tm_year + 1900, nowc->tm_hour, nowc->tm_min, nowc->tm_sec, 0);
|
||||
|
||||
// Switch color to the log color, print log type and
|
||||
SetConsoleTextAttribute(conHndl, TYPE_COLORS[type]);
|
||||
fputs(TYPE_STR[type], outStream);
|
||||
|
||||
|
||||
// Switch back to default color and print rest of log string
|
||||
SetConsoleTextAttribute(conHndl, COLOR_WHITE);
|
||||
fprintf(outStream, "] %s\n", out.c_str());
|
||||
#elif defined(__ANDROID__)
|
||||
// Print format string
|
||||
__android_log_buf_print(LOG_ID_DEFAULT, TYPE_PRIORITIES[type], FLOG_ANDROID_TAG, COLOR_WHITE "[%02d/%02d/%02d %02d:%02d:%02d.%03d] [%s%s" COLOR_WHITE "] %s\n",
|
||||
nowc->tm_mday, nowc->tm_mon + 1, nowc->tm_year + 1900, nowc->tm_hour, nowc->tm_min, nowc->tm_sec, 0, TYPE_COLORS[type], TYPE_STR[type], out.c_str());
|
||||
#else
|
||||
// Print format string
|
||||
fprintf(outStream, COLOR_WHITE "[%02d/%02d/%02d %02d:%02d:%02d.%03d] [%s%s" COLOR_WHITE "] %s\n",
|
||||
nowc->tm_mday, nowc->tm_mon + 1, nowc->tm_year + 1900, nowc->tm_hour, nowc->tm_min, nowc->tm_sec, 0, TYPE_COLORS[type], TYPE_STR[type], out.c_str());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
std::string __toString__(bool value) {
|
||||
return value ? "true" : "false";
|
||||
}
|
||||
|
||||
std::string __toString__(char value) {
|
||||
return std::string("")+value;
|
||||
}
|
||||
|
||||
std::string __toString__(int8_t value) {
|
||||
char buf[8];
|
||||
sprintf(buf, "%" PRId8, value);
|
||||
return buf;
|
||||
}
|
||||
|
||||
std::string __toString__(uint8_t value) {
|
||||
char buf[8];
|
||||
sprintf(buf, "%" PRIu8, value);
|
||||
return buf;
|
||||
}
|
||||
|
||||
std::string __toString__(int16_t value) {
|
||||
char buf[16];
|
||||
sprintf(buf, "%" PRId16, value);
|
||||
return buf;
|
||||
}
|
||||
|
||||
std::string __toString__(uint16_t value) {
|
||||
char buf[16];
|
||||
sprintf(buf, "%" PRIu16, value);
|
||||
return buf;
|
||||
}
|
||||
|
||||
std::string __toString__(int32_t value) {
|
||||
char buf[32];
|
||||
sprintf(buf, "%" PRId32, value);
|
||||
return buf;
|
||||
}
|
||||
|
||||
std::string __toString__(uint32_t value) {
|
||||
char buf[32];
|
||||
sprintf(buf, "%" PRIu32, value);
|
||||
return buf;
|
||||
}
|
||||
|
||||
std::string __toString__(int64_t value) {
|
||||
char buf[64];
|
||||
sprintf(buf, "%" PRId64, value);
|
||||
return buf;
|
||||
}
|
||||
|
||||
std::string __toString__(uint64_t value) {
|
||||
char buf[64];
|
||||
sprintf(buf, "%" PRIu64, value);
|
||||
return buf;
|
||||
}
|
||||
|
||||
std::string __toString__(float value) {
|
||||
char buf[256];
|
||||
sprintf(buf, "%f", value);
|
||||
return buf;
|
||||
}
|
||||
|
||||
std::string __toString__(double value) {
|
||||
char buf[256];
|
||||
sprintf(buf, "%lf", value);
|
||||
return buf;
|
||||
}
|
||||
|
||||
std::string __toString__(const char* value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
std::string __toString__(const void* value) {
|
||||
char buf[32];
|
||||
sprintf(buf, "0x%p", value);
|
||||
return buf;
|
||||
}
|
||||
}
|
77
core/src/utils/flog.h
Normal file
77
core/src/utils/flog.h
Normal file
@ -0,0 +1,77 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace flog {
|
||||
enum Type {
|
||||
TYPE_DEBUG,
|
||||
TYPE_INFO,
|
||||
TYPE_WARNING,
|
||||
TYPE_ERROR,
|
||||
_TYPE_COUNT
|
||||
};
|
||||
|
||||
// IO functions
|
||||
void __log__(Type type, const char* fmt, const std::vector<std::string>& args);
|
||||
|
||||
// Conversion functions
|
||||
std::string __toString__(bool value);
|
||||
std::string __toString__(char value);
|
||||
std::string __toString__(int8_t value);
|
||||
std::string __toString__(uint8_t value);
|
||||
std::string __toString__(int16_t value);
|
||||
std::string __toString__(uint16_t value);
|
||||
std::string __toString__(int32_t value);
|
||||
std::string __toString__(uint32_t value);
|
||||
std::string __toString__(int64_t value);
|
||||
std::string __toString__(uint64_t value);
|
||||
std::string __toString__(float value);
|
||||
std::string __toString__(double value);
|
||||
std::string __toString__(const char* value);
|
||||
std::string __toString__(const void* value);
|
||||
template <class T>
|
||||
std::string __toString__(const T& value) {
|
||||
return (std::string)value;
|
||||
}
|
||||
|
||||
// Utility to generate a list from arguments
|
||||
inline void __genArgList__(std::vector<std::string>& args) {}
|
||||
template <typename First, typename... Others>
|
||||
inline void __genArgList__(std::vector<std::string>& args, First first, Others... others) {
|
||||
// Add argument
|
||||
args.push_back(__toString__(first));
|
||||
|
||||
// Recursive call that will be unrolled since the function is inline
|
||||
__genArgList__(args, others...);
|
||||
}
|
||||
|
||||
// Logging functions
|
||||
template <typename... Args>
|
||||
void log(Type type, const char* fmt, Args... args) {
|
||||
std::vector<std::string> _args;
|
||||
_args.reserve(sizeof...(args));
|
||||
__genArgList__(_args, args...);
|
||||
__log__(type, fmt, _args);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void debug(const char* fmt, Args... args) {
|
||||
log(TYPE_DEBUG, fmt, args...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void info(const char* fmt, Args... args) {
|
||||
log(TYPE_INFO, fmt, args...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void warn(const char* fmt, Args... args) {
|
||||
log(TYPE_WARNING, fmt, args...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void error(const char* fmt, Args... args) {
|
||||
log(TYPE_ERROR, fmt, args...);
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
#include <utils/networking.h>
|
||||
#include <assert.h>
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <utils/flog.h>
|
||||
|
||||
namespace net {
|
||||
|
||||
|
Reference in New Issue
Block a user