2 #include <stdarg.h> // va-args
3 #include <stdlib.h> // malloc/free
4 #include <string.h> // strdup
5 #include "pnd_logger.h"
7 char *log_pretext = NULL;
8 unsigned char log_filterlevel = 0;
21 pnd_log_callback_f callback;
26 static pnd_log_target_t log_targets [ PND_LOG_MAX ]; // implicitly nil
28 static int pnd_log_empty_slot ( void ) {
31 for ( i = 0; i < PND_LOG_MAX; i++ ) {
32 if ( log_targets [ i ].type == pndl_nil ) {
40 unsigned char pnd_log_set_filter ( unsigned char newlevel ) {
41 unsigned char foo = log_filterlevel;
42 log_filterlevel = newlevel;
46 unsigned char pnd_log_get_filter ( void ) {
47 return ( log_filterlevel );
50 void pnd_log_set_pretext ( char *pre ) {
58 log_pretext = strdup ( pre );
64 void pnd_log_to_nil ( void ) {
65 memset ( log_targets, '\0', sizeof(pnd_log_target_t) * PND_LOG_MAX );
69 unsigned char pnd_log_to_stream ( FILE *f ) {
70 int i = pnd_log_empty_slot();
73 return ( 0 ); // fail!
76 log_targets [ i ].type = pndl_stream;
77 log_targets [ i ].stream = f;
82 unsigned char pnd_log_to_syslog ( char *facility ) {
86 unsigned char pnd_log_to_callback ( pnd_log_callback_f f, void *userdata ) {
90 unsigned char pnd_log_to_stdout ( void ) {
91 return ( pnd_log_to_stream ( stdout ) );
94 unsigned char pnd_log_to_stderr ( void ) {
95 return ( pnd_log_to_stream ( stderr ) );
98 unsigned char pnd_log_max_targets ( void ) {
99 return ( PND_LOG_MAX );
102 void pnd_log_emit ( char *message ) {
105 // iterate across targets and attempt to emit
106 for ( i = 0; i < PND_LOG_MAX; i++ ) {
108 switch ( log_targets [ i ].type ) {
116 fprintf ( log_targets [ i ].stream, "%s\t", log_pretext );
119 fprintf ( log_targets [ i ].stream, "%s", message );
120 if ( strchr ( message, '\n' ) == NULL ) {
121 fprintf ( log_targets [ i ].stream, "\n" );
141 unsigned char pnd_log ( unsigned char level, char *fmt, ... ) {
143 if ( level == PND_LOG_FORCE ) {
145 } else if ( level < log_filterlevel ) {
146 return ( 0 ); // too low level
149 // format the actual log string
154 if ( ( p = malloc ( size ) ) == NULL ) {
155 return ( 0 ); // fail!
160 /* Try to print in the allocated space. */
161 va_start ( ap, fmt );
162 n = vsnprintf ( p, size, fmt, ap );
165 /* If that worked, return the string. */
166 if ( n > -1 && n < size ) {
171 /* Else try again with more space. */
172 if ( n > -1 ) /* glibc 2.1 */
173 size = n + 1; /* precisely what is needed */
175 size *= 2; /* twice the old size */
176 if ( ( np = realloc ( p, size ) ) == NULL ) {
178 return ( 0 ); // fail!