Alien-libpanda

 view release on metacpan or  search on metacpan

src/panda/log.h  view on Meta::CPAN

#pragma once
#include <string>
#include <memory>
#include <ostream>
#include <string.h>
#include <type_traits>
#include <map>
#include "string_view.h"
#include "string.h"

namespace panda { namespace log {

#ifdef WIN32
#  define __FILENAME__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
#else
#  define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
#endif

#define _panda_log_code_point_ panda::log::CodePoint{__FILENAME__, __LINE__, panda_log_module}

#define panda_should_log(level) panda::log::should_log(level, _panda_log_code_point_)

#define panda_elog_m(module, level, code) do {                                \
    if (panda::log::should_log(level, _panda_log_code_point_, module)) {    \
        std::ostream& log = panda::log::details::_get_os();                 \
        code;                                                               \
        panda::log::details::_do_log(log, _panda_log_code_point_, level);   \
    }                                                                       \
} while (0);

#define panda_log_m(module, level, msg) panda_elog_m(module, level, { log << msg; })

#define panda_elog(level, code) panda_elog_m(*panda_log_module, level, code)
#define panda_log(level, msg)  panda_log_m (*panda_log_module, level, msg)

#define panda_log_verbose_debug(msg)   panda_log(panda::log::VerboseDebug, msg)
#define panda_log_debug(msg)           panda_log(panda::log::Debug, msg)
#define panda_log_info(msg)            panda_log(panda::log::Info, msg)
#define panda_log_notice(msg)          panda_log(panda::log::Notice, msg)
#define panda_log_warn(msg)            panda_log(panda::log::Warning, msg)
#define panda_log_error(msg)           panda_log(panda::log::Error, msg)
#define panda_log_critical(msg)        panda_log(panda::log::Critical, msg)
#define panda_log_alert(msg)           panda_log(panda::log::Alert, msg)
#define panda_log_emergency(msg)       panda_log(panda::log::Emergency, msg)
#define panda_elog_verbose_debug(code) panda_elog(panda::log::VerboseDebug, code)
#define panda_elog_debug(code)         panda_elog(panda::log::Debug, code)
#define panda_elog_info(code)          panda_elog(panda::log::Info, code)
#define panda_elog_notice(code)        panda_elog(panda::log::Notice, code)
#define panda_elog_warn(code)          panda_elog(panda::log::Warning, code)
#define panda_elog_error(code)         panda_elog(panda::log::Error, code)
#define panda_elog_critical(code)      panda_elog(panda::log::Critical, code)
#define panda_elog_alert(code)         panda_elog(panda::log::Alert, code)
#define panda_elog_emergency(code)     panda_elog(panda::log::Emergency, code)

#define panda_debug_v(var) panda_log(panda::log::Debug, #var << " = " << (var))

#define PANDA_ASSERT(var, msg) if(!(auto assert_value = var)) { panda_log_emergency("assert failed: " << #var << " is " << assert_value << msg) }

enum Level {
    VerboseDebug = 0,
    Debug,
    Info,
    Notice,
    Warning,
    Error,
    Critical,
    Alert,
    Emergency
};

struct Module {
    Module* parent;
    Level   level;
    string  name;

    Module(const string& name, Level level = Level::Debug);
    Module(const string& name, Module* parent, Level level = Level::Debug);

    Module(const Module&) = delete;
    Module(Module&&) = delete;
    Module & operator =(const Module&) = delete;

    void set_level(Level level);

    std::map<string, Module*> children;
};

struct CodePoint {
    string_view file;
    uint32_t    line;
    Module*     module;

    std::string to_string () const;
};
std::ostream& operator<< (std::ostream&, const CodePoint&);

struct ILogger {
    virtual bool should_log (Level, const CodePoint&) { return true; }
    virtual void log        (Level, const CodePoint&, const std::string&) = 0;
    virtual ~ILogger() {}
};

namespace details {
    extern Level                    min_level;
    extern std::unique_ptr<ILogger> ilogger;

    std::ostream& _get_os ();
    bool          _do_log (std::ostream&, const CodePoint&, Level);

    template <class Func>
    struct CallbackLogger : ILogger {
        Func f;
        CallbackLogger (const Func& f) : f(f) {}
        void log (Level level, const CodePoint& cp, const std::string& s) override { f(level, cp, s); }
    };



( run in 1.188 second using v1.01-cache-2.11-cpan-02777c243ea )