• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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