Skip to content

Commit

Permalink
prevent global sinks initializing before the sink list
Browse files Browse the repository at this point in the history
  • Loading branch information
SizzinSeal committed Jan 1, 2025
1 parent 4f81dd2 commit 05da319
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 8 deletions.
4 changes: 3 additions & 1 deletion include/lemlog/logger/logger.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,10 @@ class Helper {
/**
* @brief Send a message to all sinks
*
* Sends a message to all sinks
*
* @param level the logging level of the message
* @param format the message to be sent
* @param format the format of the message to be sent
* @param args the arguments to be formatted into the message
*
* @b Example:
Expand Down
109 changes: 102 additions & 7 deletions src/lemlog/logger/logger.cpp
Original file line number Diff line number Diff line change
@@ -1,20 +1,115 @@
#include "lemlog/logger/logger.hpp"
#include <list>

namespace logger {

template <typename T>
class Node;

/**
* @brief Doubly linked list
*
* The linked list in the standard library cannot be initialized at compile
* time. If we were to use the stdlib implementation, we wouldn't be able to
* create sinks during static initialization, as the sinks may initialize before
* the list of sinks do
*
* @tparam T the element to store
*/
template <typename T>
class List {
public:
void push_back(T value) {
if (exists(value)) return;
Node<T>* const last = getLast();
if (last == nullptr) {
m_first = new Node<T>(value);
} else {
last->next = new Node<T>(value);
}
}

Node<T>* getLast() {
if (m_first == nullptr) {
return nullptr;
} else {
Node<T>* res = m_first;
while (res->next != nullptr) {
res = res->next;
}
return res;
}
}

bool exists(T element) {
Node<T>* ptr = m_first;
while (ptr != nullptr) {
if (ptr->value == element) return true;
}
return false;
}

void erase(T element) {
Node<T>* ptr = m_first;
while (ptr != nullptr) {
if (ptr->value == element) delete ptr;
}
}

// Access operator
T& operator[](size_t index) const {
Node<T>* last = m_first;
for (int i = 0; i < index; ++i) {
last = last->next;
}
return last->value;
}

// Size getter
size_t size() const {
Node<T>* last = m_first;
size_t s = 0;
while (last != nullptr) {
last = last->next;
++s;
}
return s;
}

const T* begin() const { return &m_first->value; }

const T* end() const { return &(*this)[size()]; }
private:
Node<T>* m_first = nullptr;
};

template <typename T>
class Node {
friend List<T>;
public:
Node<T>(T value)
: value(value) {}
private:
~Node<T>() {
if (prev != nullptr) prev->next = this->next;
}

T value;
Node<T>* prev = nullptr;
Node<T>* next = nullptr;
};

// doubly linked list of all sinks
static std::list<Sink*> sinks;
static std::list<std::string> whitelist;
static std::list<std::string> blacklist;
static constinit List<Sink*> sinks;
static constinit List<std::string> whitelist;
static constinit List<std::string> blacklist;

void addWhitelist(std::string s) { whitelist.push_back(s); }

void removeWhitelist(std::string s) { whitelist.remove(s); }
void removeWhitelist(std::string s) { whitelist.erase(s); }

void addBlacklist(std::string s) { blacklist.push_back(s); }

void removeBlacklist(std::string s) { blacklist.remove(s); }
void removeBlacklist(std::string s) { blacklist.erase(s); }

void log(Level level, std::string topic, std::string message) {
// is the message a debug message?
Expand Down Expand Up @@ -45,5 +140,5 @@ Helper::Helper(std::string topic)

Sink::Sink() { sinks.push_back(this); }

Sink::~Sink() { sinks.remove(this); }
Sink::~Sink() { sinks.erase(this); }
} // namespace logger
1 change: 1 addition & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ void initialize() {
logger::Helper test("test-topic");

test.log(logger::Level::INFO, "The value is {}", 42);
test.log(logger::Level::INFO, "hello!");
}

/**
Expand Down

0 comments on commit 05da319

Please sign in to comment.