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