From cb77cbe9ce4cddad6a460aa190ff70f0c13e4703 Mon Sep 17 00:00:00 2001 From: Steven Le Rouzic Date: Wed, 12 Feb 2025 23:34:47 +0100 Subject: Rename log to logging --- asl/log/BUILD.bazel | 26 ------------ asl/log/log.cpp | 52 ----------------------- asl/log/log.hpp | 98 ------------------------------------------- asl/log/log_tests.cpp | 23 ---------- asl/logging/BUILD.bazel | 26 ++++++++++++ asl/logging/logging.cpp | 52 +++++++++++++++++++++++ asl/logging/logging.hpp | 98 +++++++++++++++++++++++++++++++++++++++++++ asl/logging/logging_tests.cpp | 23 ++++++++++ 8 files changed, 199 insertions(+), 199 deletions(-) delete mode 100644 asl/log/BUILD.bazel delete mode 100644 asl/log/log.cpp delete mode 100644 asl/log/log.hpp delete mode 100644 asl/log/log_tests.cpp create mode 100644 asl/logging/BUILD.bazel create mode 100644 asl/logging/logging.cpp create mode 100644 asl/logging/logging.hpp create mode 100644 asl/logging/logging_tests.cpp (limited to 'asl') diff --git a/asl/log/BUILD.bazel b/asl/log/BUILD.bazel deleted file mode 100644 index 51f41df..0000000 --- a/asl/log/BUILD.bazel +++ /dev/null @@ -1,26 +0,0 @@ -cc_library( - name = "log", - srcs = [ - "log.cpp", - ], - hdrs = [ - "log.hpp", - ], - deps = [ - "//asl", - ], - visibility = ["//visibility:public"], -) - -cc_test( - name = "tests", - srcs = [ - "log_tests.cpp" - ], - deps = [ - ":log", - "//asl/testing", - ], - visibility = ["//visibility:public"], -) - diff --git a/asl/log/log.cpp b/asl/log/log.cpp deleted file mode 100644 index af31a84..0000000 --- a/asl/log/log.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include "asl/log/log.hpp" -#include "asl/print.hpp" -#include "asl/string_builder.hpp" - -// @Todo Don't use internal get_stdout_writer, make console module - -static asl::log::DefaultLogger g_default_logger{asl::print_internals::get_stdout_writer()}; -static asl::log::Logger* g_head = &g_default_logger; - -static constexpr asl::string_view kLevelName[] = { - " DEBUG ", - " INFO ", - " WARNING ", - " ERROR ", -}; - -void asl::log::register_logger(box logger_box) -{ - auto* logger = leak(ASL_MOVE(logger_box)); - logger->m_next = exchange(g_head, logger); -} - -void asl::log::DefaultLoggerBase::log_inner(Writer& writer, const message& msg) -{ - asl::format(&writer, "[{}] {}:{}: {}\n", - kLevelName[msg.level], // NOLINT - msg.location.file, - msg.location.line, - msg.message); -} - -void asl::log::log_inner( - level l, - string_view fmt, span args, - const source_location& sl) -{ - // @Todo Use temporary allocator - StringWriter msg_writer{}; - asl::format_internals::format(&msg_writer, fmt, args); - - message m{ - .level = l, - .message = msg_writer.as_string_view(), - .location = sl, - }; - - for (auto* it = g_head; it != nullptr; it = it->next_logger()) - { - it->log(m); - } -} - diff --git a/asl/log/log.hpp b/asl/log/log.hpp deleted file mode 100644 index 81f10e7..0000000 --- a/asl/log/log.hpp +++ /dev/null @@ -1,98 +0,0 @@ -#pragma once - -#include "asl/format.hpp" -#include "asl/utility.hpp" -#include "asl/box.hpp" - -namespace asl::log -{ - -enum level : uint8_t -{ - kDebug = 0, - kInfo, - kWarning, - kError, -}; - -struct message -{ - level level; - string_view message; - source_location location; -}; - -// @Todo Write and use an intrusive doubly-linked list -class Logger -{ - Logger* m_next{}; - -public: - Logger() = default; - ASL_DEFAULT_COPY_MOVE(Logger); - virtual ~Logger() = default; - - virtual void log(const message&) = 0; - - friend void register_logger(box); - - constexpr Logger* next_logger() const { return m_next; } -}; - -class DefaultLoggerBase : public Logger -{ -protected: - static void log_inner(Writer&, const message&); -}; - -template W> -class DefaultLogger : public DefaultLoggerBase -{ - W m_writer; - -public: - explicit constexpr DefaultLogger(W&& writer) : m_writer{ASL_FWD(writer)} {} - - constexpr void log(const message& m) override - { - log_inner(deref(m_writer), m); - } -}; - -void register_logger(box); - -// @Todo Add a way to remove loggers (including all) - -template -requires constructible_from && convertible_from -void register_logger(Args&&... args) -{ - register_logger(make_box(ASL_FWD(args)...)); -} - -void log_inner(level l, string_view fmt, span args, const source_location& sl); - -template -void log(level l, const source_location& sl, string_view fmt, const Args&... args) -{ - if constexpr (sizeof...(Args) == 0) - { - log_inner(l, fmt, {}, sl); - } - else - { - format_internals::type_erased_arg type_erased_args[] = { - format_internals::type_erased_arg(args)... - }; - log_inner(l, fmt, type_erased_args, sl); - } -} - -} // namespace asl::log - -// @Todo Compile-time configuration of logging - -#define ASL_LOG_DEBUG(...) ::asl::log::log(::asl::log::kDebug, ::asl::source_location{}, __VA_ARGS__) -#define ASL_LOG_INFO(...) ::asl::log::log(::asl::log::kInfo, ::asl::source_location{}, __VA_ARGS__) -#define ASL_LOG_WARNING(...) ::asl::log::log(::asl::log::kWarning, ::asl::source_location{}, __VA_ARGS__) -#define ASL_LOG_ERROR(...) ::asl::log::log(::asl::log::kError, ::asl::source_location{}, __VA_ARGS__) diff --git a/asl/log/log_tests.cpp b/asl/log/log_tests.cpp deleted file mode 100644 index b174fd3..0000000 --- a/asl/log/log_tests.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include "asl/log/log.hpp" -#include "asl/testing/testing.hpp" -#include "asl/string_builder.hpp" - -ASL_TEST(log) -{ - asl::log::log(asl::log::kInfo, asl::source_location{}, "Hello, {}!", "world"_sv); - - ASL_LOG_ERROR("Oh no! {}", 42); -} - -static asl::StringWriter g_string_writer{}; - -ASL_TEST(custom_writer) -{ - asl::log::register_logger&>>(g_string_writer); - - ASL_LOG_INFO("Hello"); - auto sv = g_string_writer.as_string_view(); - - ASL_TEST_EXPECT(sv == "[ INFO ] asl/log/log_tests.cpp:18: Hello\n"); -} - diff --git a/asl/logging/BUILD.bazel b/asl/logging/BUILD.bazel new file mode 100644 index 0000000..396da74 --- /dev/null +++ b/asl/logging/BUILD.bazel @@ -0,0 +1,26 @@ +cc_library( + name = "logging", + srcs = [ + "logging.cpp", + ], + hdrs = [ + "logging.hpp", + ], + deps = [ + "//asl", + ], + visibility = ["//visibility:public"], +) + +cc_test( + name = "tests", + srcs = [ + "logging_tests.cpp" + ], + deps = [ + ":logging", + "//asl/testing", + ], + visibility = ["//visibility:public"], +) + diff --git a/asl/logging/logging.cpp b/asl/logging/logging.cpp new file mode 100644 index 0000000..aa630ac --- /dev/null +++ b/asl/logging/logging.cpp @@ -0,0 +1,52 @@ +#include "asl/logging/logging.hpp" +#include "asl/print.hpp" +#include "asl/string_builder.hpp" + +// @Todo Don't use internal get_stdout_writer, make console module + +static asl::log::DefaultLogger g_default_logger{asl::print_internals::get_stdout_writer()}; +static asl::log::Logger* g_head = &g_default_logger; + +static constexpr asl::string_view kLevelName[] = { + " DEBUG ", + " INFO ", + " WARNING ", + " ERROR ", +}; + +void asl::log::register_logger(box logger_box) +{ + auto* logger = leak(ASL_MOVE(logger_box)); + logger->m_next = exchange(g_head, logger); +} + +void asl::log::DefaultLoggerBase::log_inner(Writer& writer, const message& msg) +{ + asl::format(&writer, "[{}] {}:{}: {}\n", + kLevelName[msg.level], // NOLINT + msg.location.file, + msg.location.line, + msg.message); +} + +void asl::log::log_inner( + level l, + string_view fmt, span args, + const source_location& sl) +{ + // @Todo Use temporary allocator + StringWriter msg_writer{}; + asl::format_internals::format(&msg_writer, fmt, args); + + message m{ + .level = l, + .message = msg_writer.as_string_view(), + .location = sl, + }; + + for (auto* it = g_head; it != nullptr; it = it->next_logger()) + { + it->log(m); + } +} + diff --git a/asl/logging/logging.hpp b/asl/logging/logging.hpp new file mode 100644 index 0000000..81f10e7 --- /dev/null +++ b/asl/logging/logging.hpp @@ -0,0 +1,98 @@ +#pragma once + +#include "asl/format.hpp" +#include "asl/utility.hpp" +#include "asl/box.hpp" + +namespace asl::log +{ + +enum level : uint8_t +{ + kDebug = 0, + kInfo, + kWarning, + kError, +}; + +struct message +{ + level level; + string_view message; + source_location location; +}; + +// @Todo Write and use an intrusive doubly-linked list +class Logger +{ + Logger* m_next{}; + +public: + Logger() = default; + ASL_DEFAULT_COPY_MOVE(Logger); + virtual ~Logger() = default; + + virtual void log(const message&) = 0; + + friend void register_logger(box); + + constexpr Logger* next_logger() const { return m_next; } +}; + +class DefaultLoggerBase : public Logger +{ +protected: + static void log_inner(Writer&, const message&); +}; + +template W> +class DefaultLogger : public DefaultLoggerBase +{ + W m_writer; + +public: + explicit constexpr DefaultLogger(W&& writer) : m_writer{ASL_FWD(writer)} {} + + constexpr void log(const message& m) override + { + log_inner(deref(m_writer), m); + } +}; + +void register_logger(box); + +// @Todo Add a way to remove loggers (including all) + +template +requires constructible_from && convertible_from +void register_logger(Args&&... args) +{ + register_logger(make_box(ASL_FWD(args)...)); +} + +void log_inner(level l, string_view fmt, span args, const source_location& sl); + +template +void log(level l, const source_location& sl, string_view fmt, const Args&... args) +{ + if constexpr (sizeof...(Args) == 0) + { + log_inner(l, fmt, {}, sl); + } + else + { + format_internals::type_erased_arg type_erased_args[] = { + format_internals::type_erased_arg(args)... + }; + log_inner(l, fmt, type_erased_args, sl); + } +} + +} // namespace asl::log + +// @Todo Compile-time configuration of logging + +#define ASL_LOG_DEBUG(...) ::asl::log::log(::asl::log::kDebug, ::asl::source_location{}, __VA_ARGS__) +#define ASL_LOG_INFO(...) ::asl::log::log(::asl::log::kInfo, ::asl::source_location{}, __VA_ARGS__) +#define ASL_LOG_WARNING(...) ::asl::log::log(::asl::log::kWarning, ::asl::source_location{}, __VA_ARGS__) +#define ASL_LOG_ERROR(...) ::asl::log::log(::asl::log::kError, ::asl::source_location{}, __VA_ARGS__) diff --git a/asl/logging/logging_tests.cpp b/asl/logging/logging_tests.cpp new file mode 100644 index 0000000..ebbf800 --- /dev/null +++ b/asl/logging/logging_tests.cpp @@ -0,0 +1,23 @@ +#include "asl/logging/logging.hpp" +#include "asl/testing/testing.hpp" +#include "asl/string_builder.hpp" + +ASL_TEST(log) +{ + asl::log::log(asl::log::kInfo, asl::source_location{}, "Hello, {}!", "world"_sv); + + ASL_LOG_ERROR("Oh no! {}", 42); +} + +static asl::StringWriter g_string_writer{}; + +ASL_TEST(custom_writer) +{ + asl::log::register_logger&>>(g_string_writer); + + ASL_LOG_INFO("Hello"); + auto sv = g_string_writer.as_string_view(); + + ASL_TEST_EXPECT(sv == "[ INFO ] asl/logging/logging_tests.cpp:18: Hello\n"); +} + -- cgit