| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | #pragma once | 
| 2 |  |  |  |  |  |  | #include | 
| 3 |  |  |  |  |  |  | #include | 
| 4 |  |  |  |  |  |  | #include | 
| 5 |  |  |  |  |  |  | #include | 
| 6 |  |  |  |  |  |  | #include | 
| 7 |  |  |  |  |  |  | #include | 
| 8 |  |  |  |  |  |  | #include "string_view.h" | 
| 9 |  |  |  |  |  |  | #include "string.h" | 
| 10 |  |  |  |  |  |  |  | 
| 11 |  |  |  |  |  |  | namespace panda { namespace log { | 
| 12 |  |  |  |  |  |  |  | 
| 13 |  |  |  |  |  |  | #ifdef WIN32 | 
| 14 |  |  |  |  |  |  | #  define __FILENAME__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__) | 
| 15 |  |  |  |  |  |  | #else | 
| 16 |  |  |  |  |  |  | #  define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) | 
| 17 |  |  |  |  |  |  | #endif | 
| 18 |  |  |  |  |  |  |  | 
| 19 |  |  |  |  |  |  | #define _panda_log_code_point_ panda::log::CodePoint{__FILENAME__, __LINE__, panda_log_module} | 
| 20 |  |  |  |  |  |  |  | 
| 21 |  |  |  |  |  |  | #define panda_should_log(level) panda::log::should_log(level, _panda_log_code_point_) | 
| 22 |  |  |  |  |  |  |  | 
| 23 |  |  |  |  |  |  | #define panda_elog_m(module, level, code) do {                                \ | 
| 24 |  |  |  |  |  |  | if (panda::log::should_log(level, _panda_log_code_point_, module)) {    \ | 
| 25 |  |  |  |  |  |  | std::ostream& log = panda::log::details::_get_os();                 \ | 
| 26 |  |  |  |  |  |  | code;                                                               \ | 
| 27 |  |  |  |  |  |  | panda::log::details::_do_log(log, _panda_log_code_point_, level);   \ | 
| 28 |  |  |  |  |  |  | }                                                                       \ | 
| 29 |  |  |  |  |  |  | } while (0); | 
| 30 |  |  |  |  |  |  |  | 
| 31 |  |  |  |  |  |  | #define panda_log_m(module, level, msg) panda_elog_m(module, level, { log << msg; }) | 
| 32 |  |  |  |  |  |  |  | 
| 33 |  |  |  |  |  |  | #define panda_elog(level, code) panda_elog_m(*panda_log_module, level, code) | 
| 34 |  |  |  |  |  |  | #define panda_log(level, msg)  panda_log_m (*panda_log_module, level, msg) | 
| 35 |  |  |  |  |  |  |  | 
| 36 |  |  |  |  |  |  | #define panda_log_verbose_debug(msg)   panda_log(panda::log::VerboseDebug, msg) | 
| 37 |  |  |  |  |  |  | #define panda_log_debug(msg)           panda_log(panda::log::Debug, msg) | 
| 38 |  |  |  |  |  |  | #define panda_log_info(msg)            panda_log(panda::log::Info, msg) | 
| 39 |  |  |  |  |  |  | #define panda_log_notice(msg)          panda_log(panda::log::Notice, msg) | 
| 40 |  |  |  |  |  |  | #define panda_log_warn(msg)            panda_log(panda::log::Warning, msg) | 
| 41 |  |  |  |  |  |  | #define panda_log_error(msg)           panda_log(panda::log::Error, msg) | 
| 42 |  |  |  |  |  |  | #define panda_log_critical(msg)        panda_log(panda::log::Critical, msg) | 
| 43 |  |  |  |  |  |  | #define panda_log_alert(msg)           panda_log(panda::log::Alert, msg) | 
| 44 |  |  |  |  |  |  | #define panda_log_emergency(msg)       panda_log(panda::log::Emergency, msg) | 
| 45 |  |  |  |  |  |  | #define panda_elog_verbose_debug(code) panda_elog(panda::log::VerboseDebug, code) | 
| 46 |  |  |  |  |  |  | #define panda_elog_debug(code)         panda_elog(panda::log::Debug, code) | 
| 47 |  |  |  |  |  |  | #define panda_elog_info(code)          panda_elog(panda::log::Info, code) | 
| 48 |  |  |  |  |  |  | #define panda_elog_notice(code)        panda_elog(panda::log::Notice, code) | 
| 49 |  |  |  |  |  |  | #define panda_elog_warn(code)          panda_elog(panda::log::Warning, code) | 
| 50 |  |  |  |  |  |  | #define panda_elog_error(code)         panda_elog(panda::log::Error, code) | 
| 51 |  |  |  |  |  |  | #define panda_elog_critical(code)      panda_elog(panda::log::Critical, code) | 
| 52 |  |  |  |  |  |  | #define panda_elog_alert(code)         panda_elog(panda::log::Alert, code) | 
| 53 |  |  |  |  |  |  | #define panda_elog_emergency(code)     panda_elog(panda::log::Emergency, code) | 
| 54 |  |  |  |  |  |  |  | 
| 55 |  |  |  |  |  |  | #define panda_debug_v(var) panda_log(panda::log::Debug, #var << " = " << (var)) | 
| 56 |  |  |  |  |  |  |  | 
| 57 |  |  |  |  |  |  | #define PANDA_ASSERT(var, msg) if(!(auto assert_value = var)) { panda_log_emergency("assert failed: " << #var << " is " << assert_value << msg) } | 
| 58 |  |  |  |  |  |  |  | 
| 59 |  |  |  |  |  |  | enum Level { | 
| 60 |  |  |  |  |  |  | VerboseDebug = 0, | 
| 61 |  |  |  |  |  |  | Debug, | 
| 62 |  |  |  |  |  |  | Info, | 
| 63 |  |  |  |  |  |  | Notice, | 
| 64 |  |  |  |  |  |  | Warning, | 
| 65 |  |  |  |  |  |  | Error, | 
| 66 |  |  |  |  |  |  | Critical, | 
| 67 |  |  |  |  |  |  | Alert, | 
| 68 |  |  |  |  |  |  | Emergency | 
| 69 |  |  |  |  |  |  | }; | 
| 70 |  |  |  |  |  |  |  | 
| 71 | 36 |  |  |  |  |  | struct Module { | 
| 72 |  |  |  |  |  |  | Module* parent; | 
| 73 |  |  |  |  |  |  | Level   level; | 
| 74 |  |  |  |  |  |  | string  name; | 
| 75 |  |  |  |  |  |  |  | 
| 76 |  |  |  |  |  |  | Module(const string& name, Level level = Level::Debug); | 
| 77 |  |  |  |  |  |  | Module(const string& name, Module* parent, Level level = Level::Debug); | 
| 78 |  |  |  |  |  |  |  | 
| 79 |  |  |  |  |  |  | Module(const Module&) = delete; | 
| 80 |  |  |  |  |  |  | Module(Module&&) = delete; | 
| 81 |  |  |  |  |  |  | Module & operator =(const Module&) = delete; | 
| 82 |  |  |  |  |  |  |  | 
| 83 |  |  |  |  |  |  | void set_level(Level level); | 
| 84 |  |  |  |  |  |  |  | 
| 85 |  |  |  |  |  |  | std::map children; | 
| 86 |  |  |  |  |  |  | }; | 
| 87 |  |  |  |  |  |  |  | 
| 88 |  |  |  |  |  |  | struct CodePoint { | 
| 89 |  |  |  |  |  |  | string_view file; | 
| 90 |  |  |  |  |  |  | uint32_t    line; | 
| 91 |  |  |  |  |  |  | Module*     module; | 
| 92 |  |  |  |  |  |  |  | 
| 93 |  |  |  |  |  |  | std::string to_string () const; | 
| 94 |  |  |  |  |  |  | }; | 
| 95 |  |  |  |  |  |  | std::ostream& operator<< (std::ostream&, const CodePoint&); | 
| 96 |  |  |  |  |  |  |  | 
| 97 |  |  |  |  |  |  | struct ILogger { | 
| 98 |  |  |  |  |  |  | virtual bool should_log (Level, const CodePoint&) { return true; } | 
| 99 |  |  |  |  |  |  | virtual void log        (Level, const CodePoint&, const std::string&) = 0; | 
| 100 |  |  |  |  |  |  | virtual ~ILogger() {} | 
| 101 |  |  |  |  |  |  | }; | 
| 102 |  |  |  |  |  |  |  | 
| 103 |  |  |  |  |  |  | namespace details { | 
| 104 |  |  |  |  |  |  | extern Level                    min_level; | 
| 105 |  |  |  |  |  |  | extern std::unique_ptr ilogger; | 
| 106 |  |  |  |  |  |  |  | 
| 107 |  |  |  |  |  |  | std::ostream& _get_os (); | 
| 108 |  |  |  |  |  |  | bool          _do_log (std::ostream&, const CodePoint&, Level); | 
| 109 |  |  |  |  |  |  |  | 
| 110 |  |  |  |  |  |  | template | 
| 111 |  |  |  |  |  |  | struct CallbackLogger : ILogger { | 
| 112 |  |  |  |  |  |  | Func f; | 
| 113 |  |  |  |  |  |  | CallbackLogger (const Func& f) : f(f) {} | 
| 114 |  |  |  |  |  |  | void log (Level level, const CodePoint& cp, const std::string& s) override { f(level, cp, s); } | 
| 115 |  |  |  |  |  |  | }; | 
| 116 |  |  |  |  |  |  | } | 
| 117 |  |  |  |  |  |  |  | 
| 118 |  |  |  |  |  |  | void set_level  (Level, const string& name = ""); | 
| 119 |  |  |  |  |  |  | void set_logger (ILogger*); | 
| 120 |  |  |  |  |  |  |  | 
| 121 |  |  |  |  |  |  | template >>::value>> | 
| 122 |  |  |  |  |  |  | void set_logger (const Func& f) { set_logger(new details::CallbackLogger(f)); } | 
| 123 |  |  |  |  |  |  |  | 
| 124 |  |  |  |  |  |  | inline bool should_log (Level level, const CodePoint& cp, const Module& module) { | 
| 125 |  |  |  |  |  |  | return level >= module.level && details::ilogger && details::ilogger->should_log(level, cp); | 
| 126 |  |  |  |  |  |  | } | 
| 127 |  |  |  |  |  |  |  | 
| 128 |  |  |  |  |  |  | struct escaped { | 
| 129 |  |  |  |  |  |  | string_view src; | 
| 130 |  |  |  |  |  |  | }; | 
| 131 |  |  |  |  |  |  | std::ostream& operator<< (std::ostream&, const escaped&); | 
| 132 |  |  |  |  |  |  |  | 
| 133 |  |  |  |  |  |  | } | 
| 134 |  |  |  |  |  |  | } | 
| 135 |  |  |  |  |  |  | extern panda::log::Module* panda_log_module; | 
| 136 |  |  |  |  |  |  |  |