static const char version[] = "$Id$"; /* * layout.c * * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved. * * See the COPYING file for the terms of usage and distribution. */ #include #include #include #include #include #include #include #include #include #include #include #include struct __log4c_layout { char* lo_name; const log4c_layout_type_t* lo_type; void* lo_udata; }; sd_factory_t* log4c_layout_factory = NULL; ////////////////////////////////////////////////////////////////////////// ///以下为jesse修改的代码,将原有代码用#if 0...#endif注释掉 // 为解决log4c_layout_types中内存泄漏而将静态局部变量提升为全局局部变量 [9/8/2008 jesse] static sd_hash_t* layout_c_gs_types = NULL; static sd_hash_t* log4c_layout_types(void) { ///static sd_hash_t* types = NULL; if (!layout_c_gs_types) layout_c_gs_types = sd_hash_new(20, NULL); return layout_c_gs_types; } /** 删除本layout.c文件中定义的全局和静态的指针指向的内存,防止内存泄漏 如: 1.layout_c_gs_types. 2. @return void. 作者:jesse 日期:2008.09.08 */ extern void log4c_layout_delete_global() { if (NULL != layout_c_gs_types) { sd_hash_delete(layout_c_gs_types); layout_c_gs_types = NULL; } } ////////////////////////////////////////////////////////////////////////// #if 0 /** * @bug log4c_appender_type hash is not freed in destructor */ /*******************************************************************************/ static sd_hash_t* log4c_layout_types(void) { static sd_hash_t* types = NULL; if (!types) types = sd_hash_new(20, NULL); return types; } #endif extern void log4c_layout_types_print(FILE *fp) { sd_hash_iter_t* i; fprintf(fp, "layout types:"); for (i = sd_hash_begin(log4c_layout_types()); i != sd_hash_end(log4c_layout_types()); i = sd_hash_iter_next(i) ) { fprintf(fp, "'%s' ",((log4c_layout_type_t *)(i->data))->name ); } fprintf(fp, "\n"); } /*******************************************************************************/ extern const log4c_layout_type_t* log4c_layout_type_get(const char* a_name) { sd_hash_iter_t* i; if (!a_name) return NULL; if ( (i = (sd_hash_iter_t*)sd_hash_lookup(log4c_layout_types(), a_name)) != NULL) return (log4c_layout_type_t*)i->data; return NULL; } /*******************************************************************************/ extern const log4c_layout_type_t* log4c_layout_type_set( const log4c_layout_type_t* a_type) { sd_hash_iter_t* i = NULL; void* previous = NULL; if (!a_type) return NULL; if ( (i = sd_hash_lookadd(log4c_layout_types(), a_type->name)) == NULL) return NULL; previous = i->data; i->data = (void*) a_type; return (log4c_layout_type_t*)previous; } /*******************************************************************************/ extern log4c_layout_t* log4c_layout_get(const char* a_name) { static const sd_factory_ops_t log4c_layout_factory_ops = { /*(void*) log4c_layout_new, (void*) log4c_layout_delete, (void*) log4c_layout_print,*/ (void *( *)(const char *))log4c_layout_new, (void ( *)(void *))log4c_layout_delete, (void ( *)(void *,FILE *))log4c_layout_print }; if (!log4c_layout_factory) { log4c_layout_factory = sd_factory_new("log4c_layout_factory", &log4c_layout_factory_ops); /* build default layouts */ log4c_layout_set_type(log4c_layout_get("dated"), &log4c_layout_type_dated); log4c_layout_set_type(log4c_layout_get("basic"), &log4c_layout_type_basic); // 添加新的layouts [7/21/2010 jesse] log4c_layout_set_type(log4c_layout_get("dated_r"), &log4c_layout_type_dated_r); log4c_layout_set_type(log4c_layout_get("dated_threadid"), &log4c_layout_type_dated_threadid); } return (log4c_layout_t *)sd_factory_get(log4c_layout_factory, a_name); } /*******************************************************************************/ extern log4c_layout_t* log4c_layout_new(const char* a_name) { log4c_layout_t* ptrThis; if (!a_name) return NULL; ptrThis = (log4c_layout_t*)sd_calloc(1, sizeof(log4c_layout_t)); ptrThis->lo_name = sd_strdup(a_name); ptrThis->lo_type = &log4c_layout_type_basic; ptrThis->lo_udata = NULL; return ptrThis; } /*******************************************************************************/ extern void log4c_layout_delete(log4c_layout_t* ptrThis) { if (!ptrThis) return; free(ptrThis->lo_name); free(ptrThis); } /*******************************************************************************/ extern const char* log4c_layout_get_name(const log4c_layout_t* ptrThis) { return (ptrThis ? ptrThis->lo_name : NULL); } /*******************************************************************************/ extern const log4c_layout_type_t* log4c_layout_get_type(const log4c_layout_t* ptrThis) { return (ptrThis ? ptrThis->lo_type : NULL); } /*******************************************************************************/ extern const log4c_layout_type_t* log4c_layout_set_type( log4c_layout_t* ptrThis, const log4c_layout_type_t* a_type) { const log4c_layout_type_t* previous; if (!ptrThis) return NULL; previous = ptrThis->lo_type; ptrThis->lo_type = a_type; return previous; } /*******************************************************************************/ extern void* log4c_layout_get_udata(const log4c_layout_t* ptrThis) { return (ptrThis ? ptrThis->lo_udata : NULL); } /*******************************************************************************/ extern void* log4c_layout_set_udata(log4c_layout_t* ptrThis, void* a_udata) { void* previous; if (!ptrThis) return NULL; previous = ptrThis->lo_udata; ptrThis->lo_udata = a_udata; return previous; } /*******************************************************************************/ extern const char* log4c_layout_format( const log4c_layout_t* ptrThis, const log4c_logging_event_t*a_event) { if (!ptrThis) return NULL; if (!ptrThis->lo_type) return NULL; if (!ptrThis->lo_type->format) return NULL; return ptrThis->lo_type->format(ptrThis, a_event); } /*******************************************************************************/ extern void log4c_layout_print(const log4c_layout_t* ptrThis, FILE* a_stream) { if (!ptrThis) return; fprintf(a_stream, "{ name:'%s' type:'%s' udata:%p }", ptrThis->lo_name, ptrThis->lo_type ? ptrThis->lo_type->name : "(no set)", ptrThis->lo_udata); }