diff options
Diffstat (limited to 'navit/log.c')
-rw-r--r-- | navit/log.c | 534 |
1 files changed, 258 insertions, 276 deletions
diff --git a/navit/log.c b/navit/log.c index 5daca2eeb..ab2726523 100644 --- a/navit/log.c +++ b/navit/log.c @@ -16,10 +16,10 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ - + /** @file log.c * @brief The log object. - * + * * This file implements everything needed for logging: the log object and its functions. * * @author Navit Team @@ -49,34 +49,34 @@ #include "log.h" struct log_data { - int len; - int max_len; - char *data; + int len; + int max_len; + char *data; }; struct log { - NAVIT_OBJECT - FILE *f; - int overwrite; - int empty; - int lazy; - int mkdir; - int flush_size; - int flush_time; - struct event_timeout *timer; - struct callback *timer_callback; + NAVIT_OBJECT + FILE *f; + int overwrite; + int empty; + int lazy; + int mkdir; + int flush_size; + int flush_time; + struct event_timeout *timer; + struct callback *timer_callback; #ifdef HAVE_SYS_TIME_H - struct timeval last_flush; + struct timeval last_flush; #endif - char *filename; - char *filename_ex1; - char *filename_ex2; - struct log_data header; - struct log_data data; - struct log_data trailer; + char *filename; + char *filename_ex1; + char *filename_ex2; + struct log_data header; + struct log_data data; + struct log_data trailer; }; -/** +/** * @brief Stores formatted time to a string. * * This function obtains local system time, formats it as specified in {@code fmt} and stores it in buffer. @@ -88,51 +88,49 @@ struct log { * @return Nothing */ static void -strftime_localtime(char *buffer, int size, char *fmt) -{ - time_t t; - struct tm *tm; - - t=time(NULL); - tm=localtime(&t); - strftime(buffer, size - 1, fmt, tm); +strftime_localtime(char *buffer, int size, char *fmt) { + time_t t; + struct tm *tm; + + t=time(NULL); + tm=localtime(&t); + strftime(buffer, size - 1, fmt, tm); } -/** +/** * @brief Expands placeholders in a filename * * This function examines the {@code log->filename} and replaces any placeholders * found in it with date, time or an incremental number. If an incremental number is specified, the function * will ensure the filename is unique. The expanded filename will be stored {@code log->filename_ex2}. * The function uses {@code log->filename_ex1} to store the partly-expanded filename. - * + * * @param this_ The log object. */ static void -expand_filenames(struct log *this_) -{ - char *pos,buffer[4096]; - int i; - - strftime_localtime(buffer, 4096, this_->filename); - this_->filename_ex1=g_strdup(buffer); - if ((pos=strstr(this_->filename_ex1,"%i"))) { +expand_filenames(struct log *this_) { + char *pos,buffer[4096]; + int i; + + strftime_localtime(buffer, 4096, this_->filename); + this_->filename_ex1=g_strdup(buffer); + if ((pos=strstr(this_->filename_ex1,"%i"))) { #ifdef HAVE_API_ANDROID - pos[1]='d'; + pos[1]='d'; #endif - i=0; - do { - g_free(this_->filename_ex2); - this_->filename_ex2=g_strdup_printf(this_->filename_ex1,i++); - } while (file_exists(this_->filename_ex2)); + i=0; + do { + g_free(this_->filename_ex2); + this_->filename_ex2=g_strdup_printf(this_->filename_ex1,i++); + } while (file_exists(this_->filename_ex2)); #ifdef HAVE_API_ANDROID - pos[1]='i'; + pos[1]='i'; #endif - } else - this_->filename_ex2=g_strdup(this_->filename_ex1); + } else + this_->filename_ex2=g_strdup(this_->filename_ex1); } -/** +/** * @brief Sets the time at which the log buffer was last flushed. * * This function sets {@code log->last_flush} to current time. @@ -140,14 +138,13 @@ expand_filenames(struct log *this_) * @param this_ The log object. */ static void -log_set_last_flush(struct log *this_) -{ +log_set_last_flush(struct log *this_) { #ifdef HAVE_SYS_TIME_H - gettimeofday(&this_->last_flush, NULL); + gettimeofday(&this_->last_flush, NULL); #endif } -/** +/** * @brief Opens a log file. * * This function opens the log file for {@code log}. @@ -166,27 +163,26 @@ log_set_last_flush(struct log *this_) * @param this_ The log object. */ static void -log_open(struct log *this_) -{ - char *mode; - if (this_->overwrite) - mode="w"; - else - mode="r+"; - if (this_->mkdir) - file_mkdir(this_->filename_ex2, 2); - this_->f=fopen(this_->filename_ex2, mode); - if (! this_->f) - this_->f=fopen(this_->filename_ex2, "w"); - if (! this_->f) - return; - if (!this_->overwrite) - fseek(this_->f, 0, SEEK_END); - this_->empty = !ftell(this_->f); - log_set_last_flush(this_); +log_open(struct log *this_) { + char *mode; + if (this_->overwrite) + mode="w"; + else + mode="r+"; + if (this_->mkdir) + file_mkdir(this_->filename_ex2, 2); + this_->f=fopen(this_->filename_ex2, mode); + if (! this_->f) + this_->f=fopen(this_->filename_ex2, "w"); + if (! this_->f) + return; + if (!this_->overwrite) + fseek(this_->f, 0, SEEK_END); + this_->empty = !ftell(this_->f); + log_set_last_flush(this_); } -/** +/** * @brief Closes a log file. * * This function writes the trailer to a log file, flushes it and closes the log file for {@code log}. @@ -194,18 +190,17 @@ log_open(struct log *this_) * @param this_ The log object. */ static void -log_close(struct log *this_) -{ - if (! this_->f) - return; - if (this_->trailer.len) - fwrite(this_->trailer.data, 1, this_->trailer.len, this_->f); - fflush(this_->f); - fclose(this_->f); - this_->f=NULL; +log_close(struct log *this_) { + if (! this_->f) + return; + if (this_->trailer.len) + fwrite(this_->trailer.data, 1, this_->trailer.len, this_->f); + fflush(this_->f); + fclose(this_->f); + this_->f=NULL; } -/** +/** * @brief Flushes the buffer of a log. * * This function writes buffered log data to the log file associated with {@code log} @@ -231,48 +226,47 @@ log_close(struct log *this_) * {@code log_flag_truncate}: truncates the log file at the current position. On the Win32 Base API, this flag has no effect. */ static void -log_flush(struct log *this_, enum log_flags flags) -{ - long pos; - if (this_->lazy && !this_->f) { - if (!this_->data.len) - return; - log_open(this_); - } - if (! this_->f) - return; - if (this_->empty) { - if (this_->header.len) - fwrite(this_->header.data, 1, this_->header.len, this_->f); - if (this_->header.len || this_->data.len) - this_->empty=0; - } - fwrite(this_->data.data, 1, this_->data.len, this_->f); +log_flush(struct log *this_, enum log_flags flags) { + long pos; + if (this_->lazy && !this_->f) { + if (!this_->data.len) + return; + log_open(this_); + } + if (! this_->f) + return; + if (this_->empty) { + if (this_->header.len) + fwrite(this_->header.data, 1, this_->header.len, this_->f); + if (this_->header.len || this_->data.len) + this_->empty=0; + } + fwrite(this_->data.data, 1, this_->data.len, this_->f); #ifndef HAVE_API_WIN32_BASE - if (flags & log_flag_truncate) { - pos=ftell(this_->f); - ftruncate(fileno(this_->f), pos); - } + if (flags & log_flag_truncate) { + pos=ftell(this_->f); + ftruncate(fileno(this_->f), pos); + } #endif - if (this_->trailer.len) { - pos=ftell(this_->f); - if (pos > 0) { - fwrite(this_->trailer.data, 1, this_->trailer.len, this_->f); - fseek(this_->f, pos, SEEK_SET); - } - } - if (flags & log_flag_keep_pointer) - fseek(this_->f, -this_->data.len, SEEK_CUR); - fflush(this_->f); - if (!(flags & log_flag_keep_buffer)) { - g_free(this_->data.data); - this_->data.data=NULL; - this_->data.max_len=this_->data.len=0; - } - log_set_last_flush(this_); + if (this_->trailer.len) { + pos=ftell(this_->f); + if (pos > 0) { + fwrite(this_->trailer.data, 1, this_->trailer.len, this_->f); + fseek(this_->f, pos, SEEK_SET); + } + } + if (flags & log_flag_keep_pointer) + fseek(this_->f, -this_->data.len, SEEK_CUR); + fflush(this_->f); + if (!(flags & log_flag_keep_buffer)) { + g_free(this_->data.data); + this_->data.data=NULL; + this_->data.max_len=this_->data.len=0; + } + log_set_last_flush(this_); } -/** +/** * @brief Determines if the maximum buffer size of a log has been exceeded. * * This function examines the size of the data buffer to determine if it exceeds @@ -282,12 +276,11 @@ log_flush(struct log *this_, enum log_flags flags) * @return True if the cache needs to be flushed, false otherwise. */ static int -log_flush_required(struct log *this_) -{ - return this_->data.len > this_->flush_size; +log_flush_required(struct log *this_) { + return this_->data.len > this_->flush_size; } -/** +/** * @brief Rotates a log file. * * This function rotates a log by stopping and immediately restarting it. @@ -306,16 +299,15 @@ log_flush_required(struct log *this_) * @param this_ The log object. */ static void -log_change(struct log *this_) -{ - log_flush(this_,0); - log_close(this_); - expand_filenames(this_); - if (! this_->lazy) - log_open(this_); +log_change(struct log *this_) { + log_flush(this_,0); + log_close(this_); + expand_filenames(this_); + if (! this_->lazy) + log_open(this_); } -/** +/** * @brief Determines if the log must be rotated. * * This function expands the date and time placeholders in {@code log->filename} @@ -325,15 +317,14 @@ log_change(struct log *this_) * @return True if the date/time-dependent part of the filename has changed, false otherwise. */ static int -log_change_required(struct log *this_) -{ - char buffer[4096]; +log_change_required(struct log *this_) { + char buffer[4096]; - strftime_localtime(buffer, 4096, this_->filename); - return (strcmp(this_->filename_ex1, buffer) != 0); + strftime_localtime(buffer, 4096, this_->filename); + return (strcmp(this_->filename_ex1, buffer) != 0); } -/** +/** * @brief Determines if the flush interval of a log has elapsed and flushes the buffer if needed. * * This function calculates the difference between current time and {@code log->last_flush}. @@ -342,20 +333,19 @@ log_change_required(struct log *this_) * @param this_ The log object. */ static void -log_timer(struct log *this_) -{ +log_timer(struct log *this_) { #ifdef HAVE_SYS_TIME_H - struct timeval tv; - int delta; - gettimeofday(&tv, NULL); - delta=(tv.tv_sec-this_->last_flush.tv_sec)*1000+(tv.tv_usec-this_->last_flush.tv_usec)/1000; - dbg(lvl_debug,"delta=%d flush_time=%d", delta, this_->flush_time); - if (this_->flush_time && delta >= this_->flush_time*1000) - log_flush(this_,0); + struct timeval tv; + int delta; + gettimeofday(&tv, NULL); + delta=(tv.tv_sec-this_->last_flush.tv_sec)*1000+(tv.tv_usec-this_->last_flush.tv_usec)/1000; + dbg(lvl_debug,"delta=%d flush_time=%d", delta, this_->flush_time); + if (this_->flush_time && delta >= this_->flush_time*1000) + log_flush(this_,0); #endif } -/** +/** * @brief Gets an attribute * * @param this_ The log object. @@ -365,13 +355,12 @@ log_timer(struct log *this_) * @return True for success, false for failure */ int -log_get_attr(struct log *this_, enum attr_type type, struct attr *attr, struct attr_iter *iter) -{ - return attr_generic_get_attr(this_->attrs, NULL, type, attr, iter); +log_get_attr(struct log *this_, enum attr_type type, struct attr *attr, struct attr_iter *iter) { + return attr_generic_get_attr(this_->attrs, NULL, type, attr, iter); } -/** +/** * @brief Creates and initializes a new log object. * * @param parent The parent object. @@ -379,59 +368,58 @@ log_get_attr(struct log *this_, enum attr_type type, struct attr *attr, struct a * @return The new log object, or NULL if creation fails. */ struct log * -log_new(struct attr * parent,struct attr **attrs) -{ - struct log *ret=g_new0(struct log, 1); - struct attr *data,*overwrite,*lazy,*mkdir,*flush_size,*flush_time; - struct file_wordexp *wexp; - char *filename, **wexp_data; - - dbg(lvl_debug,"enter"); - ret->func=&log_func; - navit_object_ref((struct navit_object *)ret); - data=attr_search(attrs, NULL, attr_data); - if (! data) - return NULL; - filename=data->u.str; - wexp=file_wordexp_new(filename); - if (wexp && file_wordexp_get_count(wexp) > 0) { - wexp_data=file_wordexp_get_array(wexp); - filename=wexp_data[0]; - } - if (filename) - ret->filename=g_strdup(filename); - if (wexp) - file_wordexp_destroy(wexp); - overwrite=attr_search(attrs, NULL, attr_overwrite); - if (overwrite) - ret->overwrite=overwrite->u.num; - lazy=attr_search(attrs, NULL, attr_lazy); - if (lazy) - ret->lazy=lazy->u.num; - mkdir=attr_search(attrs, NULL, attr_mkdir); - if (mkdir) - ret->mkdir=mkdir->u.num; - flush_size=attr_search(attrs, NULL, attr_flush_size); - if (flush_size) - ret->flush_size=flush_size->u.num; - flush_time=attr_search(attrs, NULL, attr_flush_time); - if (flush_time) - ret->flush_time=flush_time->u.num; - if (ret->flush_time) { - dbg(lvl_debug,"interval %d", ret->flush_time*1000); - ret->timer_callback=callback_new_1(callback_cast(log_timer), ret); - ret->timer=event_add_timeout(ret->flush_time*1000, 1, ret->timer_callback); - } - expand_filenames(ret); - if (ret->lazy) - log_set_last_flush(ret); - else - log_open(ret); - ret->attrs=attr_list_dup(attrs); - return ret; +log_new(struct attr * parent,struct attr **attrs) { + struct log *ret=g_new0(struct log, 1); + struct attr *data,*overwrite,*lazy,*mkdir,*flush_size,*flush_time; + struct file_wordexp *wexp; + char *filename, **wexp_data; + + dbg(lvl_debug,"enter"); + ret->func=&log_func; + navit_object_ref((struct navit_object *)ret); + data=attr_search(attrs, NULL, attr_data); + if (! data) + return NULL; + filename=data->u.str; + wexp=file_wordexp_new(filename); + if (wexp && file_wordexp_get_count(wexp) > 0) { + wexp_data=file_wordexp_get_array(wexp); + filename=wexp_data[0]; + } + if (filename) + ret->filename=g_strdup(filename); + if (wexp) + file_wordexp_destroy(wexp); + overwrite=attr_search(attrs, NULL, attr_overwrite); + if (overwrite) + ret->overwrite=overwrite->u.num; + lazy=attr_search(attrs, NULL, attr_lazy); + if (lazy) + ret->lazy=lazy->u.num; + mkdir=attr_search(attrs, NULL, attr_mkdir); + if (mkdir) + ret->mkdir=mkdir->u.num; + flush_size=attr_search(attrs, NULL, attr_flush_size); + if (flush_size) + ret->flush_size=flush_size->u.num; + flush_time=attr_search(attrs, NULL, attr_flush_time); + if (flush_time) + ret->flush_time=flush_time->u.num; + if (ret->flush_time) { + dbg(lvl_debug,"interval %d", ret->flush_time*1000); + ret->timer_callback=callback_new_1(callback_cast(log_timer), ret); + ret->timer=event_add_timeout(ret->flush_time*1000, 1, ret->timer_callback); + } + expand_filenames(ret); + if (ret->lazy) + log_set_last_flush(ret); + else + log_open(ret); + ret->attrs=attr_list_dup(attrs); + return ret; } -/** +/** * @brief Sets the header for a log file. * * This function sets the header, which is to be inserted into any log file before @@ -442,14 +430,13 @@ log_new(struct attr * parent,struct attr **attrs) * @param len Size of the header data to be copied, in bytes. */ void -log_set_header(struct log *this_, char *data, int len) -{ - this_->header.data=g_malloc(len); - this_->header.max_len=this_->header.len=len; - memcpy(this_->header.data, data, len); +log_set_header(struct log *this_, char *data, int len) { + this_->header.data=g_malloc(len); + this_->header.max_len=this_->header.len=len; + memcpy(this_->header.data, data, len); } -/** +/** * @brief Sets the trailer for a log file. * * This function sets the trailer, which is to be added to any log file after @@ -460,17 +447,16 @@ log_set_header(struct log *this_, char *data, int len) * @param len Size of the trailer data to be copied, in bytes. */ void -log_set_trailer(struct log *this_, char *data, int len) -{ - this_->trailer.data=g_malloc(len); - this_->trailer.max_len=this_->trailer.len=len; - memcpy(this_->trailer.data, data, len); +log_set_trailer(struct log *this_, char *data, int len) { + this_->trailer.data=g_malloc(len); + this_->trailer.max_len=this_->trailer.len=len; + memcpy(this_->trailer.data, data, len); } -/** +/** * @brief Writes to a log. * - * This function appends data to a log. It rotates the log, if needed, before + * This function appends data to a log. It rotates the log, if needed, before * adding the new data. After adding, the log is flushed if the buffer exceeds * its maximum size or if the {@code log_flag_force_flush} flag is set. * @@ -490,27 +476,26 @@ log_set_trailer(struct log *this_, char *data, int len) * {@code log_flag_truncate}: ignored */ void -log_write(struct log *this_, char *data, int len, enum log_flags flags) -{ - dbg(lvl_debug,"enter"); - if (log_change_required(this_)) { - dbg(lvl_debug,"log_change"); - log_change(this_); - } - if (flags & log_flag_replace_buffer) - this_->data.len=0; - if (this_->data.len + len > this_->data.max_len) { - dbg(lvl_info,"overflow"); - this_->data.max_len+=16384; // FIXME: what if len exceeds this->data.max_len by more than 16384 bytes? - this_->data.data=g_realloc(this_->data.data,this_->data.max_len); - } - memcpy(this_->data.data+this_->data.len, data, len); - this_->data.len+=len; - if (log_flush_required(this_) || (flags & log_flag_force_flush)) - log_flush(this_, flags); +log_write(struct log *this_, char *data, int len, enum log_flags flags) { + dbg(lvl_debug,"enter"); + if (log_change_required(this_)) { + dbg(lvl_debug,"log_change"); + log_change(this_); + } + if (flags & log_flag_replace_buffer) + this_->data.len=0; + if (this_->data.len + len > this_->data.max_len) { + dbg(lvl_info,"overflow"); + this_->data.max_len+=16384; // FIXME: what if len exceeds this->data.max_len by more than 16384 bytes? + this_->data.data=g_realloc(this_->data.data,this_->data.max_len); + } + memcpy(this_->data.data+this_->data.len, data, len); + this_->data.len+=len; + if (log_flush_required(this_) || (flags & log_flag_force_flush)) + log_flush(this_, flags); } -/** +/** * @brief Returns the data buffer of a log object and its length. * * @param this_ The log object. @@ -519,15 +504,14 @@ log_write(struct log *this_, char *data, int len, enum log_flags flags) * @return Pointer to the data buffer. */ void * -log_get_buffer(struct log *this_, int *len) -{ - if (len) - *len=this_->data.len; - return this_->data.data; +log_get_buffer(struct log *this_, int *len) { + if (len) + *len=this_->data.len; + return this_->data.data; } -/** +/** * @brief Writes a formatted string to a log. * * This function formats a string in a fashion similar to {@code printf()} and related functions @@ -538,51 +522,49 @@ log_get_buffer(struct log *this_, int *len) * @param ... Additional arguments must be specified for each placeholder in the format string. */ void -log_printf(struct log *this_, char *fmt, ...) -{ - char buffer[LOG_BUFFER_SIZE]; - int size; - va_list ap; +log_printf(struct log *this_, char *fmt, ...) { + char buffer[LOG_BUFFER_SIZE]; + int size; + va_list ap; - va_start(ap, fmt); + va_start(ap, fmt); - // Format the string and write it to the log - size = g_vsnprintf(buffer, LOG_BUFFER_SIZE, fmt, ap); - log_write(this_, buffer, size, 0); + // Format the string and write it to the log + size = g_vsnprintf(buffer, LOG_BUFFER_SIZE, fmt, ap); + log_write(this_, buffer, size, 0); - va_end(ap); + va_end(ap); } -/** +/** * @brief Destroys a log object and frees up its memory. * * @param this_ The log object. */ void -log_destroy(struct log *this_) -{ - dbg(lvl_debug,"enter"); - attr_list_free(this_->attrs); - callback_destroy(this_->timer_callback); - event_remove_timeout(this_->timer); - log_flush(this_,0); - log_close(this_); - g_free(this_); +log_destroy(struct log *this_) { + dbg(lvl_debug,"enter"); + attr_list_free(this_->attrs); + callback_destroy(this_->timer_callback); + event_remove_timeout(this_->timer); + log_flush(this_,0); + log_close(this_); + g_free(this_); } struct object_func log_func = { - attr_log, - (object_func_new)log_new, - (object_func_get_attr)navit_object_get_attr, - (object_func_iter_new)navit_object_attr_iter_new, - (object_func_iter_destroy)navit_object_attr_iter_destroy, - (object_func_set_attr)navit_object_set_attr, - (object_func_add_attr)navit_object_add_attr, - (object_func_remove_attr)navit_object_remove_attr, - (object_func_init)NULL, - (object_func_destroy)log_destroy, - (object_func_dup)NULL, - (object_func_ref)navit_object_ref, - (object_func_unref)navit_object_unref, + attr_log, + (object_func_new)log_new, + (object_func_get_attr)navit_object_get_attr, + (object_func_iter_new)navit_object_attr_iter_new, + (object_func_iter_destroy)navit_object_attr_iter_destroy, + (object_func_set_attr)navit_object_set_attr, + (object_func_add_attr)navit_object_add_attr, + (object_func_remove_attr)navit_object_remove_attr, + (object_func_init)NULL, + (object_func_destroy)log_destroy, + (object_func_dup)NULL, + (object_func_ref)navit_object_ref, + (object_func_unref)navit_object_unref, }; |