Improve doxygen documentation and remove test stubs when not debugging
[flog.git] / flog.h
blobfb5be1e0a7ab7909f903bb8df206712093078550
1 //! @file flog.h
2 //! @brief Flog - The F logging library
3 //! @author Nabeel Sowan (nabeel.sowan@vibes.se)
4 //!
5 //! Useful as the main logger of a program
7 #ifndef FLOG_H
8 #define FLOG_H
10 /* FLOG_MSG_TYPE_ENUM_API allows switching to an enum API for flog.
11 What this means is that FLOG_MSG_TYPE_T will be defined as an int
12 (instead of unsigned char) In return, enums may yield stronger
13 type checking and therefore easier debugging. */
15 #ifdef FLOG_MSG_TYPE_ENUM_API
17 typedef enum flog_msg_type {
18 FLOG_NONE = 0x00,
19 FLOG_NOTHING = FLOG_NONE,
21 FLOG_CRIT = 0x01,
22 FLOG_CRITICAL = FLOG_CRIT,
24 FLOG_ERR = 0x02,
25 FLOG_ERROR = FLOG_ERR,
27 FLOG_WARN = 0x04,
28 FLOG_WARNING = FLOG_WARN,
29 FLOG_ALERT = FLOG_WARN,
31 FLOG_NOTE = 0x08,
32 FLOG_NOTIFY = FLOG_NOTE,
33 FLOG_IMP = FLOG_NOTE,
34 FLOG_IMPORTANT = FLOG_NOTE,
36 FLOG_INFO = 0x10,
37 FLOG_INFORMATION = FLOG_INFO,
38 FLOG_MSG = FLOG_INFO,
39 FLOG_MESSAGE = FLOG_INFO,
41 FLOG_VINFO = 0x20,
42 FLOG_VERBOSE = FLOG_VINFO,
44 FLOG_DEBUG = 0x40,
46 FLOG_FLOG_DEBUG = 0x80,
48 FLOG_ACCEPT_ONLY_CRITICAL = FLOG_CRIT,
49 FLOG_ACCEPT_ONLY_ERROR = FLOG_CRIT | FLOG_ERR,
50 FLOG_ACCEPT_ERROR_AND_WARNING = FLOG_CRIT | FLOG_ERR | FLOG_WARN,
51 FLOG_ACCEPT_IMPORTANT_NOTES = FLOG_CRIT | FLOG_ERR | FLOG_WARN | FLOG_NOTE,
52 FLOG_ACCEPT_INFO = FLOG_CRIT | FLOG_ERR | FLOG_WARN | FLOG_NOTE | FLOG_INFO,
53 FLOG_ACCEPT_VERBOSE_INFO = FLOG_CRIT | FLOG_ERR | FLOG_WARN | FLOG_NOTE | FLOG_INFO | FLOG_VINFO,
54 FLOG_ACCEPT_ALL = FLOG_CRIT | FLOG_ERR | FLOG_WARN | FLOG_NOTE | FLOG_INFO | FLOG_VINFO | FLOG_DEBUG,
55 FLOG_ACCEPT_FLOG_DEBUG = FLOG_CRIT | FLOG_ERR | FLOG_WARN | FLOG_NOTE | FLOG_INFO | FLOG_VINFO | FLOG_DEBUG | FLOG_FLOG_DEBUG
56 } FLOG_MSG_TYPE_T;
58 #else /* FLOG_MSG_TYPE_ENUM_API */
60 //! @addtogroup FLOG_MSG_TYPE_T
61 //! @brief Types of messages supported by FLOG
62 //! @details Use where ever a @ref FLOG_MSG_TYPE_T is referred
63 //! @{
65 typedef unsigned char FLOG_MSG_TYPE_T;
67 //! Nothing
68 #define FLOG_NONE 0x00
69 #define FLOG_NOTHING FLOG_NONE
71 //! Critical error
72 #define FLOG_CRIT 0x01
73 #define FLOG_CRITICAL FLOG_CRIT
75 //! Error
76 #define FLOG_ERR 0x02
77 #define FLOG_ERROR FLOG_ERR
79 //! Warning
80 #define FLOG_WARN 0x04
81 #define FLOG_WARNING FLOG_WARN
82 #define FLOG_ALERT FLOG_WARN
84 //! Note
85 #define FLOG_NOTE 0x08
86 #define FLOG_NOTIFY FLOG_NOTE
87 #define FLOG_IMP FLOG_NOTE
88 #define FLOG_IMPORTANT FLOG_NOTE
90 //! Info
91 #define FLOG_INFO 0x10
92 #define FLOG_INFORMATION FLOG_INFO
93 #define FLOG_MSG FLOG_INFO
94 #define FLOG_MESSAGE FLOG_INFO
96 //! Info in verbose mode
97 #define FLOG_VINFO 0x20
98 #define FLOG_VERBOSE FLOG_VINFO
100 //! Debug info
101 #define FLOG_DEBUG 0x40
103 //! Debug info for flog itself
104 #define FLOG_FLOG_DEBUG 0x80
106 //! @}
109 //! @addtogroup FLOG_ACCEPT_BITMASKS
110 //! @brief Bitmasks for filtering messages
111 //! @details Set the variable @ref FLOG_T->accepted_message_type
112 //! @{
114 //! Bitmask to accept only critical
115 #define FLOG_ACCEPT_ONLY_CRITICAL FLOG_CRIT
116 //! Bitmask to accept only errors
117 #define FLOG_ACCEPT_ONLY_ERROR FLOG_CRIT | FLOG_ERR
118 //! Bitmask to accept error and warning
119 #define FLOG_ACCEPT_ERROR_AND_WARNING FLOG_CRIT | FLOG_ERR | FLOG_WARN
120 //! Bitmask to accept all important messages
121 #define FLOG_ACCEPT_IMPORTANT_NOTE FLOG_CRIT | FLOG_ERR | FLOG_WARN | FLOG_NOTE
122 //! Bitmask to accept informational messages
123 #define FLOG_ACCEPT_INFO FLOG_CRIT | FLOG_ERR | FLOG_WARN | FLOG_NOTE | FLOG_INFO
124 //! Bitmask to accept verbose messages
125 #define FLOG_ACCEPT_VERBOSE_INFO FLOG_CRIT | FLOG_ERR | FLOG_WARN | FLOG_NOTE | FLOG_INFO | FLOG_VINFO
126 //! Bitmask to accept all messages (except flog internal debug)
127 #define FLOG_ACCEPT_ALL FLOG_CRIT | FLOG_ERR | FLOG_WARN | FLOG_NOTE | FLOG_INFO | FLOG_VINFO | FLOG_DEBUG
128 //! Bitmask to accept all messages
129 #define FLOG_ACCEPT_FLOG_DEBUG FLOG_CRIT | FLOG_ERR | FLOG_WARN | FLOG_NOTE | FLOG_INFO | FLOG_VINFO | FLOG_DEBUG | FLOG_FLOG_DEBUG
131 //! @}
133 #endif /* FLOG_MSG_TYPE_ENUM_API */
135 // Macros to insert source info into print strings
136 // Maybe it is better to use __func__ than __FUNCTION__ ?
138 //! emit an flog message
140 //! use this when you need to emit simple text messages and flog_printf() when formatting is needed
141 //! @param[out] p log to emit message to
142 //! @param[in] type use one of the FLOG_* defines
143 //! @param[in] subsystem which part of the program is outputing this message
144 //! @param[in] text message text
145 //! @retval 0 success
146 //! @see _flog_print(), flog_printf(), flog_dprint()
147 #ifdef FLOG_SRC_INFO
148 #define flog_print(p, type, subsystem, text) _flog_print (p, __FILE__, __LINE__, __FUNCTION__, type, subsystem, text)
149 #else
150 #define flog_print(p, type, subsystem, text) _flog_print (p, type, subsystem, text)
151 #endif
153 //! emit a formatted flog message (calls flog_print())
155 //! use this when you need to emit formatted text messages and flog_print() when no formatting is needed
156 //! @param[out] p log to emit message to
157 //! @param[in] type use one of the FLOG_* defines
158 //! @param[in] subsystem which part of the program is outputing this message
159 //! @param[in] ... formatted message text
160 //! @retval 0 success
161 //! @see _flog_printf(), flog_print(), flog_dprintf()
162 #ifdef FLOG_SRC_INFO
163 #define flog_printf(p, type, subsystem, ...) _flog_printf (p, __FILE__, __LINE__, __FUNCTION__, type, subsystem, __VA_ARGS__)
164 #else
165 #define flog_printf(p, type, subsystem, ...) _flog_printf (p, type, subsystem, __VA_ARGS__)
166 #endif
168 //! Macro for flog assert functionality
170 //! @param[out] p log to emit message to
171 //! @param[in] cond statement to evaluate
172 #define flog_assert(p, cond) ((cond) || flog_printf(p,FLOG_ERROR,"assert","Assertion failed: %s",#cond))
174 // Macros to allow removal of messages from release builds
175 //! Same as flog_print() but only defined if DEBUG is set
177 //! Use this macro to allow removal of messages from release builds
178 //! @see flog_print()
179 #ifdef DEBUG
180 #define flog_dprint(p, type, subsystem, text) flog_print (p, type, subsystem, text)
181 #else
182 #define flog_dprint(p, type, subsystem, text)
183 #endif
185 //! Same as flog_printf() but only defined if DEBUG is set
187 //! Use this macro to allow removal of messages from release builds
188 //! @see flog_printf()
189 #ifdef DEBUG
190 #define flog_dprintf(p, type, subsystem, ...) flog_printf (p, type, subsystem, __VA_ARGS__)
191 #else
192 #define flog_dprintf(p, type, subsystem, ...)
193 #endif
195 #ifdef FLOG_TIMESTAMP
196 typedef int FLOG_TIMESTAMP_T;
197 #endif
199 //! Message structure - Holds all data related to a single message
200 typedef struct {
201 #ifdef FLOG_TIMESTAMP
202 FLOG_TIMESTAMP_T time; //!< timestamp
203 #endif
204 #ifdef FLOG_SRC_INFO
205 char *src_file; //!< source file emitting message
206 int src_line; //!< source line number emitting message
207 char *src_func; //!< source function emitting message
208 #endif
209 FLOG_MSG_TYPE_T type; //!< type of message
210 char *subsystem; //!< subsystem which is outputting the msg
211 char *text; //!< message contents
212 } FLOG_MSG_T;
214 //! Main log structure - typedefined as @ref FLOG_T
216 //! These can be appended to each other in a tree structure (by using flog_append_sublog())
217 //! to form good flow and structure in software.
218 //! Sublogs are created for 3 main purposes: namespacing, multiple outputs and filtering
219 typedef struct flog_t {
220 char *name; //!< name of log
221 FLOG_MSG_TYPE_T accepted_msg_type; //!< bitmask of which messages to accept
222 int (*output_func)(struct flog_t *,const FLOG_MSG_T *); //!< function to output messages to
223 void *output_func_data; //!< data passed to output func
224 int output_error; //!< errors occurred on output
225 int output_stop_on_error; //!< stop outputting messages on error
226 struct flog_t *error_log; //!< error log for flog errors
227 FLOG_MSG_T **msg; //!< array of messages
228 int msg_amount; //!< amount of messages in array
229 int msg_max; //!< maximum amount of buffered messages
230 struct flog_t **sublog; //!< array of sublogs
231 int sublog_amount; //!< amount of sublogs in array
232 } FLOG_T;
234 void init_flog_msg_t(FLOG_MSG_T *p);
235 #ifdef FLOG_SRC_INFO
236 FLOG_MSG_T * create_flog_msg_t(const char *src_file,int src_line,const char *src_func,FLOG_MSG_TYPE_T msg_type,const char *subsystem,const char *text);
237 #else
238 FLOG_MSG_T * create_flog_msg_t(FLOG_MSG_TYPE_T msg_type,const char *subsystem,const char *text);
239 #endif
240 void destroy_flog_msg_t(FLOG_MSG_T *p);
242 void init_flog_t(FLOG_T *p);
243 FLOG_T * create_flog_t(const char *name, FLOG_MSG_TYPE_T accepted_msg_type);
244 void destroy_flog_t(FLOG_T *p);
246 int flog_add_msg(FLOG_T *p,FLOG_MSG_T *msg);
247 void flog_clear_msg_buffer(FLOG_T *p);
248 int flog_append_sublog(FLOG_T *p,FLOG_T *sublog);
250 #ifdef FLOG_SRC_INFO
251 int _flog_print(FLOG_T *p,const char *src_file,int src_line,const char *src_func,FLOG_MSG_TYPE_T type,const char *subsystem,const char *text);
252 int _flog_printf(FLOG_T *p,const char *src_file,int src_line,const char *src_func,FLOG_MSG_TYPE_T type,const char *subsystem,const char *textf, ...);
253 #else
254 int _flog_print(FLOG_T *p,FLOG_MSG_TYPE_T type,const char *subsystem,const char *text);
255 int _flog_printf(FLOG_T *p,FLOG_MSG_TYPE_T type,const char *subsystem,const char *textf, ...);
256 #endif
258 char * flog_msg_t_to_str(const FLOG_MSG_T *p);
259 char * flog_get_msg_type_str(FLOG_MSG_TYPE_T type);
260 void flog_test(FLOG_T *p);
262 #ifdef FLOG_TIMESTAMP
263 const char * get_timestamp(void);
264 #endif
266 #endif