1*758e9fbaSOystein Eftevaag #ifndef LOG_H 2*758e9fbaSOystein Eftevaag #define LOG_H 3*758e9fbaSOystein Eftevaag 4*758e9fbaSOystein Eftevaag #include <stdint.h> 5*758e9fbaSOystein Eftevaag #include <stddef.h> 6*758e9fbaSOystein Eftevaag 7*758e9fbaSOystein Eftevaag #ifndef LOGMODULE 8*758e9fbaSOystein Eftevaag #error "LOGMODULE must be set before including log/log.h" 9*758e9fbaSOystein Eftevaag #endif 10*758e9fbaSOystein Eftevaag 11*758e9fbaSOystein Eftevaag #ifndef LOGDEFAULT 12*758e9fbaSOystein Eftevaag #define LOGDEFAULT LOGLEVEL_WARNING 13*758e9fbaSOystein Eftevaag #endif 14*758e9fbaSOystein Eftevaag 15*758e9fbaSOystein Eftevaag #if defined (__GNUC__) 16*758e9fbaSOystein Eftevaag #define COMPILER_ATTR(...) __attribute__((__VA_ARGS__)) 17*758e9fbaSOystein Eftevaag #else 18*758e9fbaSOystein Eftevaag #define COMPILER_ATTR(...) 19*758e9fbaSOystein Eftevaag #endif 20*758e9fbaSOystein Eftevaag 21*758e9fbaSOystein Eftevaag #define LOGL_NONE 0 22*758e9fbaSOystein Eftevaag #define LOGL_ERROR 2 23*758e9fbaSOystein Eftevaag #define LOGL_WARNING 3 24*758e9fbaSOystein Eftevaag #define LOGL_INFO 4 25*758e9fbaSOystein Eftevaag #define LOGL_DEBUG 5 26*758e9fbaSOystein Eftevaag #define LOGL_TRACE 6 27*758e9fbaSOystein Eftevaag #define LOGL_UNDEF 0xFF 28*758e9fbaSOystein Eftevaag 29*758e9fbaSOystein Eftevaag typedef enum { 30*758e9fbaSOystein Eftevaag LOGLEVEL_NONE = LOGL_NONE, 31*758e9fbaSOystein Eftevaag LOGLEVEL_ERROR = LOGL_ERROR, 32*758e9fbaSOystein Eftevaag LOGLEVEL_WARNING = LOGL_WARNING, 33*758e9fbaSOystein Eftevaag LOGLEVEL_INFO = LOGL_INFO, 34*758e9fbaSOystein Eftevaag LOGLEVEL_DEBUG = LOGL_DEBUG, 35*758e9fbaSOystein Eftevaag LOGLEVEL_TRACE = LOGL_TRACE, 36*758e9fbaSOystein Eftevaag LOGLEVEL_UNDEFINED = LOGL_UNDEF 37*758e9fbaSOystein Eftevaag } log_level; 38*758e9fbaSOystein Eftevaag 39*758e9fbaSOystein Eftevaag static const char *log_strings[] COMPILER_ATTR(unused) = { 40*758e9fbaSOystein Eftevaag "none", 41*758e9fbaSOystein Eftevaag "(unused)", 42*758e9fbaSOystein Eftevaag "ERROR", 43*758e9fbaSOystein Eftevaag "WARNING", 44*758e9fbaSOystein Eftevaag "info", 45*758e9fbaSOystein Eftevaag "debug", 46*758e9fbaSOystein Eftevaag "trace" 47*758e9fbaSOystein Eftevaag }; 48*758e9fbaSOystein Eftevaag 49*758e9fbaSOystein Eftevaag #define xstr(s) str(s) 50*758e9fbaSOystein Eftevaag #define str(s) #s 51*758e9fbaSOystein Eftevaag 52*758e9fbaSOystein Eftevaag static log_level LOGMODULE_status COMPILER_ATTR(unused) = LOGLEVEL_UNDEFINED; 53*758e9fbaSOystein Eftevaag 54*758e9fbaSOystein Eftevaag #ifndef MAXLOGLEVEL 55*758e9fbaSOystein Eftevaag #error "MAXLOGLEVEL undefined" 56*758e9fbaSOystein Eftevaag #endif 57*758e9fbaSOystein Eftevaag 58*758e9fbaSOystein Eftevaag #if MAXLOGLEVEL > LOGL_TRACE || MAXLOGLEVEL < LOGL_ERROR 59*758e9fbaSOystein Eftevaag #if MAXLOGLEVEL != LOGL_NONE 60*758e9fbaSOystein Eftevaag #error "Unknown MAXLOGLEVEL" 61*758e9fbaSOystein Eftevaag #endif 62*758e9fbaSOystein Eftevaag #endif 63*758e9fbaSOystein Eftevaag 64*758e9fbaSOystein Eftevaag /* MAXLOGLEVEL is Error or "higher" */ 65*758e9fbaSOystein Eftevaag #if MAXLOGLEVEL >= LOGL_ERROR 66*758e9fbaSOystein Eftevaag #define LOG_ERROR(FORMAT, ...) doLog(LOGLEVEL_ERROR, \ 67*758e9fbaSOystein Eftevaag xstr(LOGMODULE), LOGDEFAULT, \ 68*758e9fbaSOystein Eftevaag &LOGMODULE_status, \ 69*758e9fbaSOystein Eftevaag __FILE__, __func__, __LINE__, \ 70*758e9fbaSOystein Eftevaag FORMAT, ## __VA_ARGS__) 71*758e9fbaSOystein Eftevaag #define LOGBLOB_ERROR(BUFFER, SIZE, FORMAT, ...) doLogBlob(LOGLEVEL_ERROR, \ 72*758e9fbaSOystein Eftevaag xstr(LOGMODULE), LOGDEFAULT, \ 73*758e9fbaSOystein Eftevaag &LOGMODULE_status, \ 74*758e9fbaSOystein Eftevaag __FILE__, __func__, __LINE__, \ 75*758e9fbaSOystein Eftevaag BUFFER, SIZE, \ 76*758e9fbaSOystein Eftevaag FORMAT, ## __VA_ARGS__) 77*758e9fbaSOystein Eftevaag #else /* MAXLOGLEVEL is not Error or "higher" */ 78*758e9fbaSOystein Eftevaag #define LOG_ERROR(FORMAT, ...) {} 79*758e9fbaSOystein Eftevaag #define LOGBLOB_ERROR(FORMAT, ...) {} 80*758e9fbaSOystein Eftevaag #endif 81*758e9fbaSOystein Eftevaag 82*758e9fbaSOystein Eftevaag /* MAXLOGLEVEL is Warning or "higher" */ 83*758e9fbaSOystein Eftevaag #if MAXLOGLEVEL >= LOGL_WARNING 84*758e9fbaSOystein Eftevaag #define LOG_WARNING(FORMAT, ...) doLog(LOGLEVEL_WARNING, \ 85*758e9fbaSOystein Eftevaag xstr(LOGMODULE), LOGDEFAULT, \ 86*758e9fbaSOystein Eftevaag &LOGMODULE_status, \ 87*758e9fbaSOystein Eftevaag __FILE__, __func__, __LINE__, \ 88*758e9fbaSOystein Eftevaag FORMAT, ## __VA_ARGS__) 89*758e9fbaSOystein Eftevaag #define LOGBLOB_WARNING(BUFFER, SIZE, FORMAT, ...) doLogBlob(LOGLEVEL_WARNING, \ 90*758e9fbaSOystein Eftevaag xstr(LOGMODULE), LOGDEFAULT, \ 91*758e9fbaSOystein Eftevaag &LOGMODULE_status, \ 92*758e9fbaSOystein Eftevaag __FILE__, __func__, __LINE__, \ 93*758e9fbaSOystein Eftevaag BUFFER, SIZE, \ 94*758e9fbaSOystein Eftevaag FORMAT, ## __VA_ARGS__) 95*758e9fbaSOystein Eftevaag #else /* MAXLOGLEVEL is not Warning or "higher" */ 96*758e9fbaSOystein Eftevaag #define LOG_WARNING(FORMAT, ...) {} 97*758e9fbaSOystein Eftevaag #define LOGBLOB_WARNING(FORMAT, ...) {} 98*758e9fbaSOystein Eftevaag #endif 99*758e9fbaSOystein Eftevaag 100*758e9fbaSOystein Eftevaag /* MAXLOGLEVEL is Info or "higher" */ 101*758e9fbaSOystein Eftevaag #if MAXLOGLEVEL >= LOGL_INFO 102*758e9fbaSOystein Eftevaag #define LOG_INFO(FORMAT, ...) doLog(LOGLEVEL_INFO, \ 103*758e9fbaSOystein Eftevaag xstr(LOGMODULE), LOGDEFAULT, \ 104*758e9fbaSOystein Eftevaag &LOGMODULE_status, \ 105*758e9fbaSOystein Eftevaag __FILE__, __func__, __LINE__, \ 106*758e9fbaSOystein Eftevaag FORMAT, ## __VA_ARGS__) 107*758e9fbaSOystein Eftevaag #define LOGBLOB_INFO(BUFFER, SIZE, FORMAT, ...) doLogBlob(LOGLEVEL_INFO, \ 108*758e9fbaSOystein Eftevaag xstr(LOGMODULE), LOGDEFAULT, \ 109*758e9fbaSOystein Eftevaag &LOGMODULE_status, \ 110*758e9fbaSOystein Eftevaag __FILE__, __func__, __LINE__, \ 111*758e9fbaSOystein Eftevaag BUFFER, SIZE, \ 112*758e9fbaSOystein Eftevaag FORMAT, ## __VA_ARGS__) 113*758e9fbaSOystein Eftevaag #else /* MAXLOGLEVEL is not Info or "higher" */ 114*758e9fbaSOystein Eftevaag #define LOG_INFO(FORMAT, ...) {} 115*758e9fbaSOystein Eftevaag #define LOGBLOB_INFO(FORMAT, ...) {} 116*758e9fbaSOystein Eftevaag #endif 117*758e9fbaSOystein Eftevaag 118*758e9fbaSOystein Eftevaag /* MAXLOGLEVEL is Debug or "higher" */ 119*758e9fbaSOystein Eftevaag #if MAXLOGLEVEL >= LOGL_DEBUG 120*758e9fbaSOystein Eftevaag #define LOG_DEBUG(FORMAT, ...) doLog(LOGLEVEL_DEBUG, \ 121*758e9fbaSOystein Eftevaag xstr(LOGMODULE), LOGDEFAULT, \ 122*758e9fbaSOystein Eftevaag &LOGMODULE_status, \ 123*758e9fbaSOystein Eftevaag __FILE__, __func__, __LINE__, \ 124*758e9fbaSOystein Eftevaag FORMAT, ## __VA_ARGS__) 125*758e9fbaSOystein Eftevaag #define LOGBLOB_DEBUG(BUFFER, SIZE, FORMAT, ...) doLogBlob(LOGLEVEL_DEBUG, \ 126*758e9fbaSOystein Eftevaag xstr(LOGMODULE), LOGDEFAULT, \ 127*758e9fbaSOystein Eftevaag &LOGMODULE_status, \ 128*758e9fbaSOystein Eftevaag __FILE__, __func__, __LINE__, \ 129*758e9fbaSOystein Eftevaag BUFFER, SIZE, \ 130*758e9fbaSOystein Eftevaag FORMAT, ## __VA_ARGS__) 131*758e9fbaSOystein Eftevaag #else /* MAXLOGLEVEL is not Debug or "higher" */ 132*758e9fbaSOystein Eftevaag #define LOG_DEBUG(FORMAT, ...) {} 133*758e9fbaSOystein Eftevaag #define LOGBLOB_DEBUG(FORMAT, ...) {} 134*758e9fbaSOystein Eftevaag #endif 135*758e9fbaSOystein Eftevaag 136*758e9fbaSOystein Eftevaag /* MAXLOGLEVEL is Trace */ 137*758e9fbaSOystein Eftevaag #if MAXLOGLEVEL >= LOGL_TRACE 138*758e9fbaSOystein Eftevaag #define LOG_TRACE(FORMAT, ...) doLog(LOGLEVEL_TRACE, \ 139*758e9fbaSOystein Eftevaag xstr(LOGMODULE), LOGDEFAULT, \ 140*758e9fbaSOystein Eftevaag &LOGMODULE_status, \ 141*758e9fbaSOystein Eftevaag __FILE__, __func__, __LINE__, \ 142*758e9fbaSOystein Eftevaag FORMAT, ## __VA_ARGS__) 143*758e9fbaSOystein Eftevaag #define LOGBLOB_TRACE(BUFFER, SIZE, FORMAT, ...) doLogBlob(LOGLEVEL_TRACE, \ 144*758e9fbaSOystein Eftevaag xstr(LOGMODULE), LOGDEFAULT, \ 145*758e9fbaSOystein Eftevaag &LOGMODULE_status, \ 146*758e9fbaSOystein Eftevaag __FILE__, __func__, __LINE__, \ 147*758e9fbaSOystein Eftevaag BUFFER, SIZE, \ 148*758e9fbaSOystein Eftevaag FORMAT, ## __VA_ARGS__) 149*758e9fbaSOystein Eftevaag #else /* MAXLOGLEVEL is not Trace */ 150*758e9fbaSOystein Eftevaag #define LOG_TRACE(FORMAT, ...) {} 151*758e9fbaSOystein Eftevaag #define LOGBLOB_TRACE(FORMAT, ...) {} 152*758e9fbaSOystein Eftevaag #endif 153*758e9fbaSOystein Eftevaag 154*758e9fbaSOystein Eftevaag #ifdef __cplusplus 155*758e9fbaSOystein Eftevaag extern "C" { 156*758e9fbaSOystein Eftevaag #endif 157*758e9fbaSOystein Eftevaag 158*758e9fbaSOystein Eftevaag void 159*758e9fbaSOystein Eftevaag doLog(log_level loglevel, const char *module, log_level logdefault, 160*758e9fbaSOystein Eftevaag log_level *status, 161*758e9fbaSOystein Eftevaag const char *file, const char *func, int line, 162*758e9fbaSOystein Eftevaag const char *msg, ...) 163*758e9fbaSOystein Eftevaag COMPILER_ATTR(unused, format (printf, 8, 9)); 164*758e9fbaSOystein Eftevaag 165*758e9fbaSOystein Eftevaag void 166*758e9fbaSOystein Eftevaag doLogBlob(log_level loglevel, const char *module, log_level logdefault, 167*758e9fbaSOystein Eftevaag log_level *status, 168*758e9fbaSOystein Eftevaag const char *file, const char *func, int line, 169*758e9fbaSOystein Eftevaag const uint8_t *buffer, size_t size, const char *msg, ...) 170*758e9fbaSOystein Eftevaag COMPILER_ATTR(unused, format (printf, 10, 11)); 171*758e9fbaSOystein Eftevaag 172*758e9fbaSOystein Eftevaag #ifdef __cplusplus 173*758e9fbaSOystein Eftevaag } // extern "C" 174*758e9fbaSOystein Eftevaag #endif 175*758e9fbaSOystein Eftevaag 176*758e9fbaSOystein Eftevaag #endif /* LOG_H */ 177