diff options
Diffstat (limited to '3rdparty/log')
-rw-r--r-- | 3rdparty/log/log.c | 383 | ||||
-rw-r--r-- | 3rdparty/log/log.h | 110 |
2 files changed, 493 insertions, 0 deletions
diff --git a/3rdparty/log/log.c b/3rdparty/log/log.c new file mode 100644 index 0000000..a1cdf2c --- /dev/null +++ b/3rdparty/log/log.c @@ -0,0 +1,383 @@ +/* ******************************************** */ +/* File Name: log.c */ +/* Author: (C) 2007-2009 - Juan José Ponteprino */ +/* Description: Loggin API */ +/* License: This code is licenced as LGPL */ +/* ******************************************** */ + +#include <stdlib.h> +#include <stdio.h> +#if WIN32 +#define vsnprintf _vsnprintf +#endif +#include <stdarg.h> +#include <string.h> + +#include <log.h> + +/* ---------------------------------------------------- */ + +static char * log_str_priority[] = +{ + "EMERG" , + "ALERT" , + "CRIT" , + "ERR" , + "WARN" , + "NOTICE" , + "INFO" , + "DEBUG" , + "N/D" +}; + +static int log_level = -1; + +/* ---------------------------------------------------- */ +/* ---------------------------------------------------- */ +/* ---------------------------------------------------- */ +/* Default Backend */ +/* ---------------------------------------------------- */ +/* ---------------------------------------------------- */ +/* ---------------------------------------------------- */ + +static FILE * __log_file_roll( log_be_file_t * _privData ) +{ + time_t Moment = time( NULL ); + char MomentStr[ 18 ]; + struct tm Now ; + + FILE * filelog; + char * nfilename = malloc( strlen( _privData->fullpathname ) + 16 ); + +#if WIN32 + struct tm * _Now = localtime( &Moment ); + Now = * _Now; +#else + localtime_r( &Moment, &Now ); +#endif + + fclose( _privData->handle ); + + strftime( MomentStr, sizeof( MomentStr ), "%y%m%d%H%M%S", &Now ); + + sprintf( nfilename, "%s.%s", _privData->fullpathname, MomentStr ); + + rename( _privData->fullpathname, nfilename ); + free( nfilename ); + + filelog = _privData->handle = fopen( _privData->fullpathname, "a" ); + if ( !filelog ) + { + filelog = stdout; + } + + return filelog; +} + +/* ---------------------------------------------------- */ + +log_t * log_file_be_create() +{ + log_t * lt = malloc( sizeof( log_t ) ); + + if ( !lt ) + { + return NULL; + } + + lt->log_open = log_file_open; + lt->log_close = log_file_close; + lt->log_write = log_file_write; + lt->log_control = log_file_control; + + return lt; +} + +/* ---------------------------------------------------- */ + +void * log_file_open( char * name, int flags ) +{ + char * p; + + log_be_file_t * privData = ( log_be_file_t * ) malloc( sizeof( log_be_file_t ) ); + if ( !privData ) + { + return NULL; + } + + privData->flags = flags; + + privData->fullpathname = strdup( name ); + if ( !privData->fullpathname ) + { + free( privData ); + return NULL; + } + + privData->filename = strrchr( privData->fullpathname, '/' ); + if (!privData->filename) + { + privData->filename = strrchr( privData->fullpathname, '\\' ); + } + if ( !privData->filename ) + privData->filename = privData->fullpathname; + else + privData->filename++; + + privData->handle = fopen( name, "a" ); + if ( !privData->handle ) + { + free( privData->fullpathname ); + free( privData ); + return NULL; + } + + return privData; +} + +/* ---------------------------------------------------- */ + +void log_file_close( void * privData ) +{ + if ( privData && (( log_be_file_t * ) privData )->handle ) + { + free((( log_be_file_t * ) privData )->fullpathname ); + fclose((( log_be_file_t * ) privData )->handle ); + free( privData ); + } +} + +/* ---------------------------------------------------- */ + +void log_file_write( void * privData, int priority, char * message ) +{ + int doroll = 0; + + time_t Moment = time( NULL ); + char MomentStr[ 18 ]; + struct tm Now ; + + log_be_file_t * _privData = privData; + FILE * filelog = _privData->handle; + +#if WIN32 + struct tm * _Now = localtime( &Moment ); + Now = * _Now; +#else + localtime_r( &Moment, &Now ); +#endif + + if ( !filelog ) + { + filelog = stdout; + } + + if ( _privData->flags & LOG_FILE_ROLL_SIZE_MASK ) + { + long pos = ftell( filelog ); + + if ( pos / 1024 >= ( _privData->flags & LOG_FILE_ROLL_SIZE_MASK ) ) + { + doroll = 1; + } + } + + if ( _privData->flags & LOG_FILE_ROLL_DAY ) + { + /* If day of year is different of last log, then roll it + (tm_mday is used only for check valid date in internal structs) + */ + if ( Now.tm_yday != _privData->lastTime.tm_yday && _privData->lastTime.tm_mday != 0 ) + { + doroll = 1; + } + } + + if ( doroll ) + { + filelog = __log_file_roll( _privData ); + } + + if ( priority >= LOG_PRIO_MAX ) + { + priority = LOG_PRIO_NODEF ; + } + + if ( message && * message != '\0' ) + { + strftime( MomentStr, sizeof( MomentStr ), "%y/%m/%d-%H:%M:%S", &Now ); + + if ( _privData->flags & LOG_FILE_DISPLAY_FNAME ) + fprintf( filelog, "%s:%s %7.4f %s %s\n", _privData->filename, MomentStr, clock() / 1000.00, log_str_priority[ priority ], message ); + else + fprintf( filelog, "%s %7.4f %s %s\n", MomentStr, clock() / 1000.00, log_str_priority[ priority ], message ); + + if ( !( _privData->flags & LOG_FILE_DONT_FLUSH ) ) fflush( filelog ); + } + + _privData->lastTime = Now; +} + +/* ---------------------------------------------------- */ + +void log_file_control( void * privData, long kid, char * args ) +{ + switch ( kid ) + { + case LOG_FILE_ROLL_NOW: + __log_file_roll(( log_be_file_t * ) privData ); + break; + + case LOG_FILE_GET_FD: + ( ( FILE ** ) args )[0] = ( FILE * )( ( ( log_be_file_t * ) privData )->handle ); + break; + } +} + +/* ---------------------------------------------------- */ +/* ---------------------------------------------------- */ +/* ---------------------------------------------------- */ +/* Log core functions */ +/* ---------------------------------------------------- */ +/* ---------------------------------------------------- */ +/* ---------------------------------------------------- */ + +int log_open( log_t * backend, char * name, int flags ) +{ + if ( !backend || !backend->log_open ) + { + return 0; + } + + backend->internalBuffer = malloc( LOG_INIT_INTERNAL_BUFFER_SIZE ); + if ( !backend->internalBuffer ) + { + return 0; + } + + backend->privData = backend->log_open( name, flags ); + if ( !backend->privData ) + { + free( backend->internalBuffer ) ; + return 0; + } + + return 1; /* OK */ +} + +/* ---------------------------------------------------- */ + +void log_close( log_t * backend ) +{ + if ( backend && backend->privData && backend->log_close ) + { + backend->log_close( backend->privData ); + if ( backend->internalBuffer ) + { + free( backend->internalBuffer ) ; + } + } +} + +/* ---------------------------------------------------- */ + +void log_write( log_t * backend, int priority, char * format, ... ) +{ + /* Suponemos que no necesitamos más de 100 bytes. */ + int n; + va_list ap; + + if ( !backend || !backend->privData || !backend->internalBuffer || !backend->log_write ) + { + return; + } + + if ( log_level != -1 && priority > log_level ) return; + + /* Intenta imprimir en el espacio reservado. */ + va_start( ap, format ); + n = vsnprintf( backend->internalBuffer, LOG_INIT_INTERNAL_BUFFER_SIZE, format, ap ); + va_end( ap ); + + if ( n <= -1 || n > LOG_INIT_INTERNAL_BUFFER_SIZE ) + { + int size = LOG_INIT_INTERNAL_BUFFER_SIZE * 2; + char * p, * p1; + if (( p = malloc( size ) ) == NULL ) + { + return; + } + + while ( 1 ) + { + /* Intenta imprimir en el espacio reservado. */ + va_start( ap, format ); + n = vsnprintf( p, size, format, ap ); + va_end( ap ); + + /* Si ha funcionado, devuelve la cadena. */ + if ( n > -1 && n < size ) + { + break ; + } + + /* Si no, inténtalo de nuevo con más espacio. */ + if ( n > -1 ) /* glibc 2.1 */ + { + size = n + 1; /* exactamente lo que se necesita */ + } + else /* glibc 2.0 */ + { + size *= 2; /* el doble del tamaño anterior*/ + } + + if (( p1 = realloc( p, size ) ) == NULL ) + { + free( p ); + return; + } + p = p1; + } + + backend->log_write( backend->privData, priority, p ); + free( p ); + } + else + { + backend->log_write( backend->privData, priority, backend->internalBuffer ); + } +} + +/* ---------------------------------------------------- */ + +void log_control( log_t * backend, long kid, char * args ) +{ + if ( !backend || !backend->privData || !backend->log_control ) + { + return; + } + + if ( ( kid & LOG_SYSTEM_CTRL ) == LOG_SYSTEM_CTRL ) + { + switch ( kid ) + { + case LOG_LEVEL: + log_level = ( int ) args; + break; + } + return; + } + + backend->log_control(( void * )( backend->privData ), kid, args ); +} + +/* ---------------------------------------------------- */ + +FILE * log_get_handle( log_t * backend ) +{ + log_be_file_t * _privData; + _privData = ( log_be_file_t * ) backend->privData; + return ( FILE *) _privData->handle; +} + +/* ---------------------------------------------------- */ diff --git a/3rdparty/log/log.h b/3rdparty/log/log.h new file mode 100644 index 0000000..046c345 --- /dev/null +++ b/3rdparty/log/log.h @@ -0,0 +1,110 @@ +/* ******************************************** */ +/* File Name: log.h */ +/* Author: (C) 2007-2009 - Juan José Ponteprino */ +/* Description: Loggin API Headers */ +/* License: This code is licenced as LGPL */ +/* ******************************************** */ + +#ifndef _LOG_H +#define _LOG_H + +#include <time.h> + +/* ---------------------------------------------------- */ +/* ---------------------------------------------------- */ +/* ---------------------------------------------------- */ +/* Core */ +/* ---------------------------------------------------- */ +/* ---------------------------------------------------- */ +/* ---------------------------------------------------- */ + +#define LOG_INIT_INTERNAL_BUFFER_SIZE 16384 + +enum { + LOG_PRIO_EMERGENCY = 0 , /* el sistema está inutilizable */ + LOG_PRIO_ALERT , /* debe tomarse una acción correctora inmediatamente */ + LOG_PRIO_CRITICAL , /* condiciones críticas */ + LOG_PRIO_ERROR , /* condiciones de error */ + LOG_PRIO_WARNNING , /* condiciones de advertencia */ + LOG_PRIO_NOTICE , /* condición normal, pero significativa */ + LOG_PRIO_INFO , /* mensaje informativo */ + LOG_PRIO_DEBUG , /* mensaje del nivel de depuración */ + LOG_PRIO_NODEF , /* No definido */ + LOG_PRIO_MAX = LOG_PRIO_NODEF /* valor maximo permitido ( - 1 ) */ +}; + +typedef struct +{ + void * privData; /* Internal Use */ + + char * internalBuffer; + + void * ( * log_open )( char * name, int flags ); + void ( * log_close )( void * privData ); + void ( * log_write )( void * privData, int priority, char * message ); + void ( * log_control )( void * privData, long kid, char * args ); +} log_t; + +/* ---------------------------------------------------- */ +/* Control format */ +/* -------------- */ +/* 0xBBUUUUUU */ +/* BB = Internal backend id ( 0xff - core control ) */ +/* UUUUUU = User data */ +/* ---------------------------------------------------- */ + +#define LOG_SYSTEM_CTRL 0xFF000000 + +#define LOG_LEVEL 0xFF000001 + +/* ---------------------------------------------------- */ + +int log_open( log_t * backend, char * name, int flags ); +void log_close( log_t * backend ); +void log_write( log_t * backend, int priority, char * format, ... ); +void log_control( log_t * backend, long kid, char * args ); +FILE * log_get_handle( log_t * backend ); + +/* ---------------------------------------------------- */ +/* ---------------------------------------------------- */ +/* ---------------------------------------------------- */ +/* Default backend */ +/* ---------------------------------------------------- */ +/* ---------------------------------------------------- */ +/* ---------------------------------------------------- */ + +/* controls keyword id for file backend */ + +#define LOG_FILE_ROLL_NOW 0x00000001 +#define LOG_FILE_GET_FD 0x00000002 + +/* flags for file backend */ + +#define LOG_FILE_ROLL_SIZE_MASK 0x000007FF /* Max is 2047MB, 0 is disable size roll */ +#define LOG_FILE_ROLL_DAY 0x00001000 +#define LOG_FILE_DONT_FLUSH 0x00002000 + +#define LOG_FILE_DISPLAY_FNAME 0x00010000 + +/* file backend internal struct */ + +typedef struct +{ + char * fullpathname; + char * filename; + FILE * handle; + int flags; + struct tm lastTime; +} log_be_file_t; + +/* file backend functions */ + +log_t * log_file_be_create(); +void * log_file_open( char * name, int flags ); +void log_file_close( void * privData ); +void log_file_write( void * privData, int priority, char * message ); +void log_file_control( void * privData, long kid, char * args ); + +/* ---------------------------------------------------- */ + +#endif |