1 /* $Id: category.h,v 1.12 2013/09/29 17:41:39 valtri Exp $
2  *
3  * category.h
4  *
5  * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved.
6  *
7  * See the COPYING file for the terms of usage and distribution.
8  */
9 
10 #ifndef log4c_category_h
11 #define log4c_category_h
12 
13 /**
14  * @file category.h
15  *
16  * @brief central class in the log4c package.
17  *
18  * One of the distintive features of log4j (and hence log4c) are
19  * hierarchical categories and their evaluation.
20  *
21  **/
22 
23 #include <stdio.h>
24 #include <stdarg.h>
25 #include <log4c/defs.h>
26 #include <log4c/priority.h>
27 #include <log4c/location_info.h>
28 
29 __LOG4C_BEGIN_DECLS
30 
31 struct __log4c_appender;
32 struct __log4c_category;
33 
34 /**
35  * log4c category class
36  **/
37 typedef struct __log4c_category	log4c_category_t;
38 
39 /**
40  * Instantiate a log4c_category_t with name @a name. This method
41  * does not set priority of the category which is by default @c
42  * LOG4C_PRIORITY_NOTSET.
43  *
44  * @param a_name The name of the category to retrieve.
45  **/
46 LOG4C_API log4c_category_t* log4c_category_get(const char* a_name);
47 
48 /**
49  * Fill in an array with the log4c categories.
50  *
51  * @param a_cats array of categories that will be filled
52  * @param a_ncats number of categories in the array
53  *
54  * @returns -1 if it fails or the number of available categories in
55  * log4c.
56  **/
57 LOG4C_API int log4c_category_list(log4c_category_t** a_cats, int a_ncats);
58 
59 /**
60  * Constructor for a log4c_category_t.
61  *
62  * @param a_name the category name
63  * @returns a log4c_category object
64  * @warning this method should not be called directly. You should use the
65  * log4c_category_get() method in order to preserve the categories
66  * hierarchy.
67  **/
68 LOG4C_API log4c_category_t* log4c_category_new(const char* a_name);
69 
70 /**
71  * Destructor for a log4c_category_t.
72  *
73  * @param a_category the log4c_category_t object
74  **/
75 LOG4C_API void log4c_category_delete(log4c_category_t* a_category);
76 
77 /**
78  * Return the category name.
79  * @param a_category the log4c_category_t object
80  * @returns the category name.
81  */
82 LOG4C_API const char* log4c_category_get_name(const log4c_category_t* a_category);
83 
84 /**
85  * Returns the Appender for this log4c_category_t, or NULL if no Appender has
86  * been set.
87  * @param a_category the log4c_category_t object
88  * @returns The Appender.
89  **/
90 LOG4C_API const struct __log4c_appender* log4c_category_get_appender(
91     const log4c_category_t* a_category);
92 
93 /**
94  * Get the additivity flag for this log4c_category_t..
95  *
96  * @param a_category the log4c_category_t object
97  * @return the category additivity
98  **/
99 LOG4C_API int log4c_category_get_additivity(const log4c_category_t* a_category);
100 
101 /**
102  * Returns the assigned Priority, if any, for this log4c_category_t.
103  * @param a_category the log4c_category_t object
104  * @return Priority - the assigned Priority, can be LOG4C_PRIORITY_NOTSET
105  **/
106 LOG4C_API int log4c_category_get_priority(const log4c_category_t* a_category);
107 
108 /**
109  * Starting from this category, search the category hierarchy for a set
110  * priority and return it. Otherwise, return the priority of the root
111  * category.
112  *
113  * @param a_category the log4c_category_t object
114  *
115  * @todo the log4c_category_t is designed so that this method executes as
116  * quickly as possible. It could even be faster if the set priority was
117  * propagated through the children hierarchy of a category.
118  **/
119 LOG4C_API int log4c_category_get_chainedpriority(const log4c_category_t* a_category);
120 
121 /**
122  * Sets a new appender for this category.
123  *
124  * @param a_category the log4c_category_t object
125  * @param a_appender the new category appender
126  * @return the previous category appender
127  **/
128 LOG4C_API const struct __log4c_appender* log4c_category_set_appender(
129     log4c_category_t* a_category,
130     struct __log4c_appender* a_appender);
131 /**
132  * Sets a new priority of this category.
133  *
134  * @param a_category the log4c_category_t object
135  * @param a_priority the new priority to set. Use LOG4C_PRIORITY_NOTSET to
136  * let the category use its parents priority as effective priority.
137  * @return the previous category priority
138  **/
139 LOG4C_API int log4c_category_set_priority(log4c_category_t* a_category,
140                                        int a_priority);
141 
142 /**
143  * Sets a new additivity flag for this category.
144  *
145  * @param a_category the log4c_category_t object
146  * @param a_additivity the new category additivity
147  * @return the previous category additivity
148  **/
149 LOG4C_API int log4c_category_set_additivity(log4c_category_t* a_category,
150                                          int a_additivity);
151 /**
152  * prints the log4c_category_t object on a stream
153  *
154  * @param a_category the log4c_category_t object
155  * @param a_stream The stream
156  **/
157 LOG4C_API void log4c_category_print(const log4c_category_t* a_category, FILE* a_stream);
158 
159 /**
160  * Returns true if the chained priority of the log4c_category_t is equal to
161  * or higher than given priority.
162  * @param a_category the log4c_category_t object
163  * @param a_priority The priority to compare with.
164  * @returns whether logging is enable for this priority.
165  **/
166 #if !defined(_WIN32) && !defined(__HP_cc)
log4c_category_is_priority_enabled(const log4c_category_t * a_category,int a_priority)167 static inline int log4c_category_is_priority_enabled(const log4c_category_t* a_category,
168 						     int a_priority)
169 {
170     return log4c_category_get_chainedpriority(a_category) >= a_priority;
171 }
172 #else
173 #define log4c_category_is_priority_enabled(a,b) \
174   (log4c_category_get_chainedpriority(a) >= b)
175 #endif
176 
177 /**
178  * Return true if the category will log messages with priority @c
179  * LOG4C_PRIORITY_FATAL.
180  *
181  * @param a_category the log4c_category_t object
182  * @returns Whether the category will log.
183  **/
184 #if !defined(_WIN32) && !defined(__HP_cc)
log4c_category_is_fatal_enabled(const log4c_category_t * a_category)185 static inline int log4c_category_is_fatal_enabled(const log4c_category_t* a_category)
186 {
187   return log4c_category_is_priority_enabled(a_category, LOG4C_PRIORITY_FATAL);
188 }
189 #else
190 #define log4c_category_is_fatal_enabled(a)  \
191   (log4c_category_is_priority_enabled(a,LOG4C_PRIORITY_FATAL))
192 #endif
193 
194 /**
195  * Return true if the category will log messages with priority @c
196  * LOG4C_PRIORITY_ALERT.
197  *
198  * @param a_category the log4c_category_t object
199  * @returns Whether the category will log.
200  **/
201 #if !defined(_WIN32) && !defined(__HP_cc)
log4c_category_is_alert_enabled(const log4c_category_t * a_category)202 static inline int log4c_category_is_alert_enabled(const log4c_category_t* a_category)
203 {
204     return log4c_category_is_priority_enabled(a_category, LOG4C_PRIORITY_ALERT);
205 }
206 #else
207 #define log4c_category_is_alert_enabled(a) \
208   (log4c_category_is_priority_enabled(a,LOG4C_PRIORITY_ALERT))
209 #endif
210 
211 /**
212  * Return true if the category will log messages with priority @c
213  * LOG4C_PRIORITY_CRIT.
214  *
215  * @param a_category the log4c_category_t object
216  * @returns Whether the category will log.
217  **/
218 #if !defined(_WIN32) && !defined(__HP_cc)
log4c_category_is_crit_enabled(const log4c_category_t * a_category)219 static inline int log4c_category_is_crit_enabled(const log4c_category_t* a_category)
220 {
221     return log4c_category_is_priority_enabled(a_category, LOG4C_PRIORITY_CRIT);
222 }
223 #else
224 #define log4c_category_is_crit_enabled(a) \
225   (log4c_category_is_priority_enabled(a, LOG4C_PRIORITY_CRIT))
226 #endif
227 
228 /**
229  * Return true if the category will log messages with priority @c
230  * LOG4C_PRIORITY_ERROR.
231  *
232  * @param a_category the log4c_category_t object
233  * @returns Whether the category will log.
234  **/
235 #if !defined(_WIN32) && !defined(__HP_cc)
log4c_category_is_error_enabled(const log4c_category_t * a_category)236 static inline int log4c_category_is_error_enabled(const log4c_category_t* a_category)
237 {
238     return log4c_category_is_priority_enabled(a_category, LOG4C_PRIORITY_ERROR);
239 }
240 #else
241 #define log4c_category_is_error_enabled(a) \
242   (log4c_category_is_priority_enabled(a, LOG4C_PRIORITY_ERROR))
243 #endif
244 
245 /**
246  * Return true if the category will log messages with priority @c
247  * LOG4C_PRIORITY_WARN.
248  *
249  * @param a_category the log4c_category_t object
250  * @returns Whether the category will log.
251  **/
252 #if !defined(_WIN32) && !defined(__HP_cc)
log4c_category_is_warn_enabled(const log4c_category_t * a_category)253 static inline int log4c_category_is_warn_enabled(const log4c_category_t* a_category)
254 {
255     return log4c_category_is_priority_enabled(a_category, LOG4C_PRIORITY_WARN);
256 }
257 #else
258 #define log4c_category_is_warn_enabled(a) \
259   log4c_category_is_warn_enabled(a) \
260     (log4c_category_is_priority_enabled(a, LOG4C_PRIORITY_WARN))
261 #endif
262 
263 /**
264  * Return true if the category will log messages with priority @c
265  * LOG4C_PRIORITY_NOTICE.
266  *
267  * @param a_category the log4c_category_t object
268  * @returns Whether the category will log.
269  **/
270 #if !defined(_WIN32) && !defined(__HP_cc)
log4c_category_is_notice_enabled(const log4c_category_t * a_category)271 static inline int log4c_category_is_notice_enabled(const log4c_category_t* a_category)
272 {
273     return log4c_category_is_priority_enabled(a_category, LOG4C_PRIORITY_NOTICE);
274 }
275 #else
276 #define log4c_category_is_notice_enabled(a) \
277   (log4c_category_is_priority_enabled(a, LOG4C_PRIORITY_NOTICE))
278 #endif
279 
280 /**
281  * Return true if the category will log messages with priority @c
282  * LOG4C_PRIORITY_INFO.
283  *
284  * @param a_category the log4c_category_t object
285  * @returns Whether the category will log.
286  **/
287 #if !defined(_WIN32) && !defined(__HP_cc)
log4c_category_is_info_enabled(const log4c_category_t * a_category)288 static inline int log4c_category_is_info_enabled(const log4c_category_t* a_category)
289 {
290     return log4c_category_is_priority_enabled(a_category, LOG4C_PRIORITY_INFO);
291 }
292 #else
293 #define log4c_category_is_info_enabled(a) \
294   (log4c_category_is_priority_enabled(a, LOG4C_PRIORITY_INFO))
295 #endif
296 
297 /**
298  * Return true if the category will log messages with priority @c
299  * LOG4C_PRIORITY_DEBUG.
300  *
301  * @param a_category the log4c_category_t object
302  * @returns Whether the category will log.
303  **/
304 #if !defined(_WIN32) && !defined(__HP_cc)
log4c_category_is_debug_enabled(const log4c_category_t * a_category)305 static inline int log4c_category_is_debug_enabled(const log4c_category_t* a_category)
306 {
307     return log4c_category_is_priority_enabled(a_category, LOG4C_PRIORITY_DEBUG);
308 }
309 #else
310 #define log4c_category_is_debug_enabled(a) \
311   (log4c_category_is_priority_enabled(a, LOG4C_PRIORITY_DEBUG))
312 #endif
313 
314 /**
315  * Return true if the category will log messages with priority @c
316  * LOG4C_PRIORITY_TRACE.
317  *
318  * @param a_category the log4c_category_t object
319  * @returns Whether the category will log.
320  **/
321 #if !defined(_WIN32) && !defined(__HP_cc)
log4c_category_is_trace_enabled(const log4c_category_t * a_category)322 static inline int log4c_category_is_trace_enabled(const log4c_category_t* a_category)
323 {
324     return log4c_category_is_priority_enabled(a_category, LOG4C_PRIORITY_TRACE);
325 }
326 #else
327 #define log4c_category_is_trace_enabled(a) \
328   (log4c_category_is_priority_enabled(a, LOG4C_PRIORITY_TRACE))
329 #endif
330 
331 /**
332  * @internal
333  **/
334 LOG4C_API void __log4c_category_vlog(const log4c_category_t* a_category,
335 				  const log4c_location_info_t* a_locinfo,
336 				  int a_priority,
337 				  const char* a_format,
338 				  va_list a_args);
339 
340 /**
341  * @internal
342  *
343  * @bug the log4c_location_info_t object is not set correctly. A macro is
344  * needed.
345  **/
346 
347 /* msvc doesn't allow "inline" nor variable args in a macro
348  * so cannot #define these ones.
349  */
350 
log4c_category_vlog(const log4c_category_t * a_category,int a_priority,const char * a_format,va_list a_args)351 static LOG4C_INLINE void log4c_category_vlog(const log4c_category_t* a_category,
352 				       int a_priority,
353 				       const char* a_format,
354 				       va_list a_args)
355 {
356     const log4c_location_info_t locinfo = LOG4C_LOCATION_INFO_INITIALIZER(NULL);
357 
358     __log4c_category_vlog(a_category, &locinfo, a_priority, a_format, a_args);
359 }
360 
361 /**
362  * Log a message with the specified priority.
363  * @param a_category the log4c_category_t object
364  * @param a_priority The priority of this log message.
365  * @param a_format Format specifier for the string to write
366  * in the log file.
367  * @param ... The arguments for a_format
368  **/
369 LOG4C_INLINE LOG4C_ATTRIBUTE((format(printf, 3, 4)))
log4c_category_log(const log4c_category_t * a_category,int a_priority,const char * a_format,...)370 static void log4c_category_log(const log4c_category_t* a_category,
371 				      int a_priority,
372 				      const char* a_format,
373 				      ...)
374 {
375     if (log4c_category_is_priority_enabled(a_category, a_priority)) {
376 	va_list va;
377 	va_start(va, a_format);
378 	log4c_category_vlog(a_category, a_priority, a_format, va);
379 	va_end(va);
380     }
381 }
382 
383 /**
384  * Log a message with the specified priority and a user location info.
385  * @param a_category the log4c_category_t object
386  * @param a_locinfo a user  location info
387  * @param a_priority The priority of this log message.
388  * @param a_format Format specifier for the string to write
389  * in the log file.
390  * @param ... The arguments for a_format
391  **/
392 LOG4C_INLINE LOG4C_ATTRIBUTE((format(printf, 4, 5)))
log4c_category_log_locinfo(const log4c_category_t * a_category,const log4c_location_info_t * a_locinfo,int a_priority,const char * a_format,...)393 static void log4c_category_log_locinfo(
394     const log4c_category_t* a_category,
395     const log4c_location_info_t* a_locinfo,
396     int a_priority,
397     const char* a_format,
398     ...)
399 {
400     if (log4c_category_is_priority_enabled(a_category, a_priority)) {
401 	va_list va;
402 	va_start(va, a_format);
403 	__log4c_category_vlog(a_category, a_locinfo, a_priority, a_format, va);
404 	va_end(va);
405     }
406 }
407 
408 /**
409  * Log a message with fatal priority.
410  * @param a_category the log4c_category_t object
411  * @param a_format Format specifier for the string to write
412  * in the log file.
413  * @param ... The arguments for a_format
414  **/
415 LOG4C_INLINE LOG4C_ATTRIBUTE((format(printf, 2, 3)))
log4c_category_fatal(const log4c_category_t * a_category,const char * a_format,...)416 static void log4c_category_fatal(const log4c_category_t* a_category,
417 					const char* a_format,
418 					...)
419 {
420     if (log4c_category_is_priority_enabled(a_category, LOG4C_PRIORITY_FATAL)) {
421 	va_list va;
422 	va_start(va, a_format);
423 	log4c_category_vlog(a_category, LOG4C_PRIORITY_FATAL, a_format, va);
424 	va_end(va);
425     }
426 }
427 
428 /**
429  * Log a message with alert priority.
430  * @param a_category the log4c_category_t object
431  * @param a_format Format specifier for the string to write
432  * in the log file.
433  * @param ... The arguments for a_format
434  **/
435 LOG4C_INLINE LOG4C_ATTRIBUTE((format(printf, 2, 3)))
log4c_category_alert(const log4c_category_t * a_category,const char * a_format,...)436 static void log4c_category_alert(const log4c_category_t* a_category,
437 					const char* a_format,
438 					...)
439 {
440     if (log4c_category_is_priority_enabled(a_category, LOG4C_PRIORITY_ALERT)) {
441 	va_list va;
442 	va_start(va, a_format);
443 	log4c_category_vlog(a_category, LOG4C_PRIORITY_ALERT, a_format, va);
444 	va_end(va);
445     }
446 }
447 
448 /**
449  * Log a message with crit priority.
450  * @param a_category the log4c_category_t object
451  * @param a_format Format specifier for the string to write
452  * in the log file.
453  * @param ... The arguments for a_format
454  **/
455 LOG4C_INLINE LOG4C_ATTRIBUTE((format(printf, 2, 3)))
log4c_category_crit(const log4c_category_t * a_category,const char * a_format,...)456 static void log4c_category_crit(const log4c_category_t* a_category,
457 				       const char* a_format,
458 				       ...)
459 {
460     if (log4c_category_is_priority_enabled(a_category, LOG4C_PRIORITY_CRIT)) {
461 	va_list va;
462 	va_start(va, a_format);
463 	log4c_category_vlog(a_category, LOG4C_PRIORITY_CRIT, a_format, va);
464 	va_end(va);
465     }
466 }
467 
468 /**
469  * Log a message with error priority.
470  * @param a_category the log4c_category_t object
471  * @param a_format Format specifier for the string to write
472  * in the log file.
473  * @param ... The arguments for a_format
474  **/
475 LOG4C_INLINE LOG4C_ATTRIBUTE((format(printf, 2, 3)))
log4c_category_error(const log4c_category_t * a_category,const char * a_format,...)476 static void log4c_category_error(const log4c_category_t* a_category,
477 					const char* a_format,
478 					...)
479 {
480     if (log4c_category_is_priority_enabled(a_category, LOG4C_PRIORITY_ERROR)) {
481 	va_list va;
482 	va_start(va, a_format);
483 	log4c_category_vlog(a_category, LOG4C_PRIORITY_ERROR, a_format, va);
484 	va_end(va);
485     }
486 }
487 
488 /**
489  * Log a message with warn priority.
490  * @param a_category the log4c_category_t object
491  * @param a_format Format specifier for the string to write
492  * in the log file.
493  * @param ... The arguments for a_format
494  **/
495 LOG4C_INLINE LOG4C_ATTRIBUTE((format(printf, 2, 3)))
log4c_category_warn(const log4c_category_t * a_category,const char * a_format,...)496 static void log4c_category_warn(const log4c_category_t* a_category,
497 				       const char* a_format,
498 				       ...)
499 {
500     if (log4c_category_is_priority_enabled(a_category, LOG4C_PRIORITY_WARN)) {
501 	va_list va;
502 	va_start(va, a_format);
503 	log4c_category_vlog(a_category, LOG4C_PRIORITY_WARN, a_format, va);
504 	va_end(va);
505     }
506 }
507 
508 /**
509  * Log a message with notice priority.
510  * @param a_category the log4c_category_t object
511  * @param a_format Format specifier for the string to write
512  * in the log file.
513  * @param ... The arguments for a_format
514  **/
515 LOG4C_INLINE LOG4C_ATTRIBUTE((format(printf, 2, 3)))
log4c_category_notice(const log4c_category_t * a_category,const char * a_format,...)516 static void log4c_category_notice(const log4c_category_t* a_category,
517 					 const char* a_format,
518 					 ...)
519 {
520     if (log4c_category_is_priority_enabled(a_category, LOG4C_PRIORITY_NOTICE)) {
521 	va_list va;
522 	va_start(va, a_format);
523 	log4c_category_vlog(a_category, LOG4C_PRIORITY_NOTICE, a_format, va);
524 	va_end(va);
525     }
526 }
527 
528 /**
529  * Log a message with info priority.
530  * @param a_category the log4c_category_t object
531  * @param a_format Format specifier for the string to write
532  * in the log file.
533  * @param ... The arguments for a_format
534  **/
535 LOG4C_INLINE LOG4C_ATTRIBUTE((format(printf, 2, 3)))
log4c_category_info(const log4c_category_t * a_category,const char * a_format,...)536 static void log4c_category_info(const log4c_category_t* a_category,
537 				       const char* a_format,
538 				       ...)
539 {
540     if (log4c_category_is_priority_enabled(a_category, LOG4C_PRIORITY_INFO)) {
541 	va_list va;
542 	va_start(va, a_format);
543 	log4c_category_vlog(a_category, LOG4C_PRIORITY_INFO, a_format, va);
544 	va_end(va);
545     }
546 }
547 
548 /**
549  * Log a message with debug priority.
550  * @param a_category the log4c_category_t object
551  * @param a_format Format specifier for the string to write
552  * in the log file.
553  * @param ... The arguments for a_format
554  **/
555 LOG4C_INLINE LOG4C_ATTRIBUTE((format(printf, 2, 3)))
log4c_category_debug(const log4c_category_t * a_category,const char * a_format,...)556 static void log4c_category_debug(const log4c_category_t* a_category,
557 					const char* a_format,
558 					...)
559 {
560     if (log4c_category_is_priority_enabled(a_category, LOG4C_PRIORITY_DEBUG)) {
561 	va_list va;
562 	va_start(va, a_format);
563 	log4c_category_vlog(a_category, LOG4C_PRIORITY_DEBUG, a_format, va);
564 	va_end(va);
565     }
566 }
567 
568 /**
569  * Log a message with trace priority.
570  * @param a_category the log4c_category_t object
571  * @param a_format Format specifier for the string to write
572  * in the log file.
573  * @param ... The arguments for a_format
574  **/
575 LOG4C_INLINE LOG4C_ATTRIBUTE((format(printf, 2, 3)))
__log4c_category_trace(const log4c_category_t * a_category,const char * a_format,...)576 static void __log4c_category_trace(const log4c_category_t* a_category,
577 					  const char* a_format,
578 					  ...)
579 {
580     if (log4c_category_is_priority_enabled(a_category, LOG4C_PRIORITY_TRACE)) {
581 	va_list va;
582 	va_start(va, a_format);
583 	log4c_category_vlog(a_category, LOG4C_PRIORITY_TRACE, a_format, va);
584 	va_end(va);
585     }
586 }
587 
588 #ifdef __GNUC__
589 
590 #ifdef OLD_VARIADIC_MACRO
591 
592 #  define log4c_category_trace(a_category, a_format, args...) \
593     __log4c_category_trace(a_category, log4c_location "\n" a_format, ##args )
594 
595 #else
596 
597 #  define log4c_category_trace(a_category, a_format, ...) \
598     __log4c_category_trace(a_category, log4c_location "\n" a_format, ##__VA_ARGS__ )
599 
600 #endif /* OLD_VARIADIC_MACRO */
601 
602 
603 #else
604 #  define log4c_category_trace __log4c_category_trace
605 #endif  /* __GNUC__ */
606 
607 /**
608  * Helper macro to define static categories.
609  *
610  * @param a_category the log4c_category_t pointer name
611  * @param a_name the category name
612  **/
613 #ifdef __GNUC__
614 #   define log4c_category_define(a_category, a_name) \
615     typedef log4c_category_t log4c_category_define_##a_category __attribute__((deprecated)); \
616     static log4c_category_define_##a_category* a_category  __attribute__ ((unused)) = NULL;
617 #else
618 #   define log4c_category_define(a_category, a_name)
619 #endif
620 
621 /**
622  * @internal
623  **/
624 struct __sd_factory;
625 LOG4C_API struct __sd_factory* log4c_category_factory;
626 
627 __LOG4C_END_DECLS
628 
629 #endif
630