├── NEWS ├── config ├── Makefile.am ├── .cvsignore └── expat.m4 ├── doc ├── .cvsignore ├── Log4C-DevelopersGuide.odt ├── Makefile.am └── old │ └── log4cHowto.html ├── tests ├── Makefile.am ├── log4c │ ├── .cvsignore │ ├── cpp_compile_test.cpp │ ├── test_rc.in │ ├── test_rc.ref │ ├── Makefile.am │ ├── test_rc.c │ ├── test_category.ref │ ├── test_layout_r.c │ └── test_rollingfile_appender.c └── .cvsignore ├── AUTHORS ├── src ├── Makefile.am ├── log4c │ ├── .cvsignore │ ├── version.c │ ├── buffer.h │ ├── layout_type_basic.h │ ├── layout_type_basic_r.h │ ├── config-win32.h │ ├── defs.h │ ├── layout_type_dated.h │ ├── layout_type_dated_r.h │ ├── layout_type_basic.c │ ├── logging_event.c │ ├── version.h.in │ ├── layout_type_basic_r.c │ ├── Makefile.am │ ├── priority.c │ ├── init.h │ ├── rc.h │ ├── appender_type_syslog.h │ ├── appender_type_mmap.h │ ├── priority.h │ ├── appender_type_stream.c │ ├── location_info.h │ ├── appender_type_stream.h │ ├── layout_type_dated_r.c │ ├── layout_type_dated.c │ ├── logging_event.h │ ├── appender_type_syslog.c │ ├── rollingpolicy_type_sizewin.h │ ├── appender_type_mmap.c │ ├── appender_type_stream2.h │ ├── appender_type_rollingfile.h │ ├── layout.h │ ├── appender_type_stream2.c │ └── layout.c ├── sd │ ├── .cvsignore │ ├── error.h │ ├── defs.h │ ├── domnode-xml-parser.h │ ├── malloc.h │ ├── domnode-xml.h │ ├── sync │ ├── sprintf.osf.c │ ├── error.c │ ├── stack.h │ ├── factory.h │ ├── test.h │ ├── sprintf.c │ ├── Makefile.am │ ├── sprintf.h │ ├── domnode.h │ ├── sd_xplatform.c │ ├── domnode-xml-scanner.l │ ├── malloc.c │ ├── sd_xplatform.h │ ├── factory.c │ ├── domnode-xml.c │ ├── domnode-xml-parser.y │ ├── hash.h │ ├── stack.c │ └── list.h ├── .cvsignore └── log4c.h ├── examples ├── .cvsignore ├── helloworld │ ├── Makefile.am │ ├── README │ └── helloworld.c ├── helloworld1 │ ├── Makefile.am │ ├── README │ ├── helloworld1.c │ └── mylog.h ├── Makefile.am ├── application_3.h ├── log4crc.in ├── application_1.c ├── userloc_formatter.c ├── README ├── example_formatters.c ├── application_2.c └── application_3.c ├── macosx ├── English.lproj │ └── InfoPlist.strings ├── version.plist └── Info.plist ├── .cvsignore ├── msvc6 ├── gotest.sh └── log4c │ └── version.h ├── log4crc.sample.in ├── Makefile.am ├── log4c-config.in ├── release ├── log4c.spec.in ├── bootstrap ├── TODO └── README /NEWS: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /config/Makefile.am: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /doc/.cvsignore: -------------------------------------------------------------------------------- 1 | Makefile.in 2 | -------------------------------------------------------------------------------- /tests/Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS = log4c 2 | 3 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bmanojlovic/log4c/HEAD/AUTHORS -------------------------------------------------------------------------------- /src/Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS = sd log4c 2 | 3 | include_HEADERS = \ 4 | log4c.h -------------------------------------------------------------------------------- /examples/.cvsignore: -------------------------------------------------------------------------------- 1 | Makefile.in 2 | Makefile 3 | .deps 4 | .libs 5 | *.lo 6 | *.la 7 | -------------------------------------------------------------------------------- /src/log4c/.cvsignore: -------------------------------------------------------------------------------- 1 | Makefile.in 2 | Makefile 3 | .deps 4 | .libs 5 | *.lo 6 | *.la 7 | -------------------------------------------------------------------------------- /src/sd/.cvsignore: -------------------------------------------------------------------------------- 1 | Makefile.in 2 | Makefile 3 | .deps 4 | .libs 5 | *.lo 6 | *.la 7 | -------------------------------------------------------------------------------- /tests/log4c/.cvsignore: -------------------------------------------------------------------------------- 1 | Makefile.in 2 | Makefile 3 | .deps 4 | .libs 5 | *.lo 6 | *.la 7 | -------------------------------------------------------------------------------- /doc/Log4C-DevelopersGuide.odt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bmanojlovic/log4c/HEAD/doc/Log4C-DevelopersGuide.odt -------------------------------------------------------------------------------- /macosx/English.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bmanojlovic/log4c/HEAD/macosx/English.lproj/InfoPlist.strings -------------------------------------------------------------------------------- /tests/.cvsignore: -------------------------------------------------------------------------------- 1 | .libs 2 | .deps 3 | Makefile 4 | Makefile.in 5 | bench 6 | test_dot 7 | test_rc 8 | test_category 9 | test_hierarchy 10 | -------------------------------------------------------------------------------- /tests/log4c/cpp_compile_test.cpp: -------------------------------------------------------------------------------- 1 | #include "../src/log4c.h" 2 | #include 3 | 4 | int main(int argc, char** argv) 5 | { 6 | exit(0); 7 | } 8 | -------------------------------------------------------------------------------- /.cvsignore: -------------------------------------------------------------------------------- 1 | Makefile 2 | config.status 3 | libtool 4 | config.cache 5 | config.log 6 | configure 7 | Makefile.in 8 | aclocal.m4 9 | autom4te*.cache 10 | -------------------------------------------------------------------------------- /config/.cvsignore: -------------------------------------------------------------------------------- 1 | Makefile 2 | Makefile.in 3 | config.guess 4 | config.sub 5 | ltmain.sh 6 | install-sh 7 | mkinstalldirs 8 | missing 9 | depcomp 10 | -------------------------------------------------------------------------------- /src/.cvsignore: -------------------------------------------------------------------------------- 1 | *.la 2 | *.lo 3 | .libs 4 | .deps 5 | stamp-h 6 | config.h.in 7 | config.h 8 | Makefile 9 | Makefile.in 10 | stamp-h.in 11 | stamp-h1 12 | -------------------------------------------------------------------------------- /msvc6/gotest.sh: -------------------------------------------------------------------------------- 1 | # 2 | # Helper script to run the test programs 3 | # compiled into the log4c/tests directory 4 | # eg ./go_test.sh test_stream2 5 | # 6 | export PATH=log4c/log4c:$PATH 7 | log4c/tests/$1 8 | -------------------------------------------------------------------------------- /examples/helloworld/Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | AM_CPPFLAGS = -I${top_srcdir}/src 3 | 4 | noinst_PROGRAMS = helloworld 5 | 6 | helloworld_SOURCES = helloworld.c 7 | helloworld_LDADD = \ 8 | $(top_builddir)/src/log4c/liblog4c.la 9 | -------------------------------------------------------------------------------- /examples/helloworld1/Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | AM_CPPFLAGS = -I${top_srcdir}/src 3 | 4 | noinst_PROGRAMS = helloworld1 5 | 6 | helloworld1_SOURCES = helloworld1.c mylog.h 7 | helloworld1_LDADD = \ 8 | $(top_builddir)/src/log4c/liblog4c.la 9 | -------------------------------------------------------------------------------- /examples/helloworld/README: -------------------------------------------------------------------------------- 1 | See the developers guide for a detailed description, but to see the output 2 | from this program copy the log4crc file in and add this line: 3 | 4 | 5 | -------------------------------------------------------------------------------- /examples/helloworld1/README: -------------------------------------------------------------------------------- 1 | See the developers guide for a detailed description, but to see the output 2 | from this program copy the log4crc file in and add this line: 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/sd/error.h: -------------------------------------------------------------------------------- 1 | /* $Id$ 2 | * 3 | * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved. 4 | * 5 | * See the COPYING file for the terms of usage and distribution. 6 | */ 7 | 8 | #ifndef __sd_error_h 9 | #define __sd_error_h 10 | 11 | #include 12 | 13 | extern int sd_debug(const char *fmt, ...); 14 | extern int sd_error(const char *fmt, ...); 15 | 16 | #endif /* __sd_error_h */ 17 | -------------------------------------------------------------------------------- /src/sd/defs.h: -------------------------------------------------------------------------------- 1 | /* $Id$ 2 | * 3 | * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved. 4 | * 5 | * See the COPYING file for the terms of usage and distribution. 6 | */ 7 | 8 | #ifndef __sd_defs_h 9 | #define __sd_defs_h 10 | 11 | #ifdef __cplusplus 12 | # define __SD_BEGIN_DECLS extern "C" { 13 | # define __SD_END_DECLS } 14 | #else 15 | # define __SD_BEGIN_DECLS 16 | # define __SD_END_DECLS 17 | #endif 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /src/sd/domnode-xml-parser.h: -------------------------------------------------------------------------------- 1 | #ifndef BISON_DOMNODE_XML_PARSER_H 2 | # define BISON_DOMNODE_XML_PARSER_H 3 | 4 | #ifndef YYSTYPE 5 | typedef union { char *s; } yystype; 6 | # define YYSTYPE yystype 7 | # define YYSTYPE_IS_TRIVIAL 1 8 | #endif 9 | # define ENDDEF 257 10 | # define EQ 258 11 | # define SLASH 259 12 | # define CLOSE 260 13 | # define END 261 14 | # define NAME 262 15 | # define VALUE 263 16 | # define DATA 264 17 | # define COMMENT 265 18 | # define START 266 19 | 20 | 21 | #endif /* not BISON_DOMNODE_XML_PARSER_H */ 22 | -------------------------------------------------------------------------------- /tests/log4c/test_rc.in: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /examples/helloworld1/helloworld1.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define MYLOG_CATEGORY_NAME "log4c.examples.helloworld" 4 | #include "mylog.h" 5 | 6 | int main(int argc, char** argv){ 7 | int rc = 0; 8 | 9 | if (mylog_init()){ 10 | printf("mylog_init() failed"); 11 | rc = 1; 12 | }else{ 13 | 14 | MYLOGMSG(LOG4C_PRIORITY_ERROR, "Hello World!"); 15 | 16 | /* Explicitly call the log4c cleanup routine */ 17 | if ( mylog_fini()){ 18 | printf("mylog_fini() failed"); 19 | } 20 | } 21 | return rc; 22 | } 23 | -------------------------------------------------------------------------------- /src/log4c.h: -------------------------------------------------------------------------------- 1 | /* $Id$ 2 | * 3 | * log4c.h 4 | * 5 | * Copyright 2001-2002, 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_log4c_h 11 | #define log4c_log4c_h 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #endif 23 | 24 | -------------------------------------------------------------------------------- /examples/helloworld/helloworld.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "log4c.h" 4 | 5 | int main(int argc, char** argv){ 6 | int rc = 0; 7 | log4c_category_t* mycat = NULL; 8 | 9 | if (log4c_init()){ 10 | printf("log4c_init() failed"); 11 | rc = 1; 12 | }else{ 13 | mycat = log4c_category_get("log4c.examples.helloworld"); 14 | 15 | log4c_category_log(mycat, LOG4C_PRIORITY_ERROR, "Hello World!"); 16 | 17 | /* Explicitly call the log4c cleanup routine */ 18 | if ( log4c_fini()){ 19 | printf("log4c_fini() failed"); 20 | } 21 | } 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /macosx/version.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildVersion 6 | 317 7 | CFBundleShortVersionString 8 | 1.0 9 | CFBundleVersion 10 | 1.0 11 | ProductBuildVersion 12 | 7K571 13 | ProjectName 14 | CarbonProjectTemplates 15 | SourceVersion 16 | 140000 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/log4c/version.c: -------------------------------------------------------------------------------- 1 | static const char version[] = "$Id$"; 2 | 3 | /* 4 | * version.c 5 | * 6 | * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved. 7 | * 8 | * See the COPYING file for the terms of usage and distribution. 9 | */ 10 | 11 | #ifdef HAVE_CONFIG_H 12 | #include "config.h" 13 | #endif 14 | 15 | #include 16 | 17 | const int log4c_major_version = LOG4C_MAJOR_VERSION; 18 | const int log4c_minor_version = LOG4C_MINOR_VERSION; 19 | const int log4c_micro_version = LOG4C_MICRO_VERSION; 20 | 21 | /*******************************************************************************/ 22 | extern const char* log4c_version(void) 23 | { 24 | return VERSION; 25 | } 26 | -------------------------------------------------------------------------------- /log4crc.sample.in: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 0 8 | 9 | 0 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /macosx/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | log4c 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | org.log4c.framework 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1.2.1 21 | CSResourcesFileMapped 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/log4c/buffer.h: -------------------------------------------------------------------------------- 1 | /* $Id$ 2 | * 3 | * buffer.h 4 | * 5 | * See the COPYING file for the terms of usage and distribution. 6 | */ 7 | 8 | #ifndef __log4c_buffer_h 9 | #define __log4c_buffer_h 10 | 11 | /** 12 | * @file buffer.h 13 | * 14 | * @brief log4c buffer 15 | * 16 | **/ 17 | 18 | #include 19 | #include 20 | 21 | __LOG4C_BEGIN_DECLS 22 | 23 | /** 24 | * @brief buffer object 25 | * 26 | * Attributes description: 27 | * 28 | * @li @c size current size of the buffer 29 | * @li @c maxsize maximum size of the buffer. 0 means no limitation. 30 | * @li @c data raw data 31 | **/ 32 | typedef struct 33 | { 34 | size_t buf_size; 35 | size_t buf_maxsize; 36 | char* buf_data; 37 | 38 | } log4c_buffer_t; 39 | 40 | #define LOG4C_BUFFER_SIZE_DEFAULT 512 41 | 42 | 43 | __LOG4C_END_DECLS 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | if DOC 2 | DOC_SUBDIR = doc 3 | endif 4 | if TEST 5 | TEST_SUBDIR = tests 6 | endif 7 | 8 | SUBDIRS = config src ${DOC_SUBDIR} ${TEST_SUBDIR} examples 9 | 10 | DIST_SUBDIRS = config src doc tests examples 11 | 12 | EXTRA_DIST = \ 13 | log4c.m4 \ 14 | log4c.spec.in \ 15 | log4c.spec 16 | 17 | bin_SCRIPTS = log4c-config 18 | BUILT_SOURCES=log4c-config 19 | 20 | m4datadir = $(datadir)/aclocal 21 | m4data_DATA = log4c.m4 22 | 23 | sysconf_DATA = log4crc.sample 24 | 25 | rpm: dist 26 | mkdir -p $(distdir)/rpmbuild/{BUILD,RPMS,SOURCES,SRPMS,SPECS} 27 | mkdir $(distdir)/rpmbuild/RPMS/i386 28 | # remove the "--clean" here to leave the rpmbuild intermediate file 29 | # for debugging the rpm generation 30 | # The _topdir seems to have to be absolute 31 | rpmbuild -ta --clean --define='_topdir $(CURDIR)/$(distdir)/rpmbuild' ${distdir}.tar.gz 32 | #rpmbuild --clean -ta ${distdir}.tar.gz 33 | -------------------------------------------------------------------------------- /examples/Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | AM_CPPFLAGS = -I${top_srcdir}/src 3 | 4 | SUBDIRS = helloworld helloworld1 5 | 6 | DIST_SUBDIRS = helloworld helloworld1 7 | 8 | EXTRA_DIST=log4crc README 9 | 10 | noinst_LTLIBRARIES = liblog4c_examples.la liblog4c_userloc.la 11 | noinst_PROGRAMS = application_1 application_2 application_3 12 | 13 | liblog4c_examples_la_SOURCES = example_formatters.c example_appenders.c 14 | liblog4c_userloc_la_SOURCES= userloc_formatter.c 15 | 16 | application_1_SOURCES = application_1.c 17 | application_2_SOURCES = application_2.c 18 | application_3_SOURCES = application_3.c application_3.h 19 | 20 | application_1_LDADD = \ 21 | $(top_builddir)/src/log4c/liblog4c.la 22 | application_2_LDADD = \ 23 | liblog4c_examples.la \ 24 | $(top_builddir)/src/log4c/liblog4c.la 25 | application_3_LDADD = \ 26 | liblog4c_userloc.la \ 27 | liblog4c_examples.la \ 28 | $(top_builddir)/src/log4c/liblog4c.la 29 | 30 | -------------------------------------------------------------------------------- /examples/application_3.h: -------------------------------------------------------------------------------- 1 | 2 | typedef struct { 3 | char* hostname; 4 | int pid; 5 | } user_locinfo_t; 6 | 7 | #define log4c_category_log_userinfo(a_category, a_void, a_priority, a_format, args...) \ 8 | helper(a_category, __FILE__, __LINE__, __FUNCTION__, a_void, a_priority, a_format , ## args ); 9 | 10 | static inline void helper( 11 | const log4c_category_t* a_category, 12 | char* file, 13 | int line, 14 | const char* func, 15 | void* user_locinfo, 16 | int a_priority, 17 | const char* a_format, 18 | ...) 19 | { 20 | log4c_location_info_t locinfo; 21 | locinfo.loc_file = file; 22 | locinfo.loc_line = line; 23 | locinfo.loc_function = func; 24 | locinfo.loc_data = user_locinfo; 25 | va_list va; 26 | va_start(va, a_format); 27 | 28 | log4c_category_log_locinfo(a_category, &locinfo, a_priority, a_format,va); 29 | va_end(va); 30 | 31 | } 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/sd/malloc.h: -------------------------------------------------------------------------------- 1 | /* $Id$ 2 | * 3 | * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved. 4 | * 5 | * See the COPYING file for the terms of usage and distribution. 6 | */ 7 | 8 | #ifndef __sd_malloc_h 9 | #define __sd_malloc_h 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | /** 16 | * @file malloc.h 17 | */ 18 | 19 | __SD_BEGIN_DECLS 20 | 21 | typedef void (*sd_malloc_handler_t)(); 22 | 23 | extern sd_malloc_handler_t sd_malloc_set_handler(void (*a_handler)()); 24 | 25 | #ifndef __SD_DEBUG__ 26 | 27 | extern void *sd_malloc(size_t n); 28 | extern void *sd_calloc(size_t n, size_t s); 29 | extern void *sd_realloc(void *p, size_t n); 30 | extern char *sd_strdup (const char *__str); 31 | 32 | #else 33 | 34 | #define sd_malloc malloc 35 | #define sd_calloc calloc 36 | #define sd_realloc realloc 37 | #define sd_strdup strdup 38 | 39 | #endif 40 | 41 | __SD_END_DECLS 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /src/sd/domnode-xml.h: -------------------------------------------------------------------------------- 1 | /* $Id$ 2 | * 3 | * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved. 4 | * See the COPYING file for the terms of usage and distribution. 5 | */ 6 | 7 | #ifndef __sd_domnode_xml_h 8 | #define __sd_domnode_xml_h 9 | 10 | /** 11 | * @file domnode-xml.h @ingroup sd 12 | * 13 | * @brief Private API for XML parsing. 14 | */ 15 | 16 | #include "domnode.h" 17 | #include "stack.h" 18 | 19 | struct __sd_domnode_xml_maker { 20 | void* scanner; 21 | sd_stack_t* elements; 22 | sd_domnode_t* root; 23 | }; 24 | 25 | extern int __sd_domnode_xml_fread(sd_domnode_t** a_node, FILE* a_stream); 26 | extern int __sd_domnode_xml_fwrite(const sd_domnode_t* a_node, FILE* a_stream); 27 | 28 | extern int __sd_domnode_xml_read(sd_domnode_t** a_node, const char* a_buffer, 29 | size_t a_size); 30 | extern int __sd_domnode_xml_write(const sd_domnode_t* a_node, char** a_buffer, 31 | size_t* a_size); 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /src/log4c/layout_type_basic.h: -------------------------------------------------------------------------------- 1 | /* $Id$ 2 | * 3 | * layout_type_basic.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_layout_type_basic_h 11 | #define log4c_layout_type_basic_h 12 | 13 | /** 14 | * @file layout_type_basic.h 15 | * 16 | * @brief Implement a basic layout. 17 | * 18 | * In @c log4j.PatternLayout conventions, the basic layout has the following 19 | * conversion pattern: @c "%P %c - %m\n". 20 | * 21 | * Where 22 | * @li @c "%P" is the priority of the logging event 23 | * @li @c "%c" is the category of the logging event 24 | * @li @c "%m" is the application supplied message associated with the 25 | * logging event 26 | * 27 | **/ 28 | 29 | #include 30 | #include 31 | 32 | __LOG4C_BEGIN_DECLS 33 | 34 | extern const log4c_layout_type_t log4c_layout_type_basic; 35 | 36 | __LOG4C_END_DECLS 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /src/log4c/layout_type_basic_r.h: -------------------------------------------------------------------------------- 1 | /* $Id$ 2 | * 3 | * layout_type_basic_r.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_layout_type_basic_r_h 11 | #define log4c_layout_type_basic_r_h 12 | 13 | /** 14 | * @file layout_type_basic_r.h 15 | * 16 | * @brief Implement a basic_r layout. 17 | * 18 | * In @c log4j.PatternLayout conventions, the basic_r layout has the following 19 | * conversion pattern: @c "%P %c - %m\n". 20 | * 21 | * Where 22 | * @li @c "%P" is the priority of the logging event 23 | * @li @c "%c" is the category of the logging event 24 | * @li @c "%m" is the application supplied message associated with the 25 | * logging event 26 | * 27 | **/ 28 | 29 | #include 30 | #include 31 | 32 | __LOG4C_BEGIN_DECLS 33 | 34 | extern const log4c_layout_type_t log4c_layout_type_basic_r; 35 | 36 | __LOG4C_END_DECLS 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /src/log4c/config-win32.h: -------------------------------------------------------------------------------- 1 | /* $Id$ 2 | * 3 | * See the COPYING file for the terms of usage and distribution. 4 | */ 5 | 6 | /* This file defines some labels as required for 7 | compiling with Microsoft Visual C++ 6 8 | */ 9 | 10 | #ifndef __log4c_config_win32_h 11 | #define __log4c_config_win32_h 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | #undef LOG4C_API 18 | #ifdef LOG4C_EXPORTS 19 | # define LOG4C_API __declspec(dllexport) 20 | #else 21 | # define LOG4C_API extern __declspec(dllimport) 22 | #endif 23 | 24 | #undef LOG4C_DATA 25 | #ifdef LOG4C_EXPORTS 26 | # define LOG4C_DATA __declspec(dllexport) 27 | #else 28 | # define LOG4C_DATA extern __declspec(dllimport) 29 | #endif 30 | 31 | 32 | /* This is defined to be 'inline' by default, 33 | but with msvc6 undef it so that inlined 34 | functions are just normal functions. 35 | */ 36 | #undef LOG4C_INLINE 37 | #define LOG4C_INLINE 38 | 39 | 40 | #endif /* __log4c_config_win32_h */ 41 | -------------------------------------------------------------------------------- /src/log4c/defs.h: -------------------------------------------------------------------------------- 1 | /* $Id$ 2 | * 3 | * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved. 4 | * 5 | * See the COPYING file for the terms of usage and distribution. 6 | */ 7 | 8 | #ifndef __log4c_defs_h 9 | #define __log4c_defs_h 10 | 11 | /** 12 | * @file defs.h 13 | * 14 | * @brief types and declarations enclosures for C++. 15 | * 16 | **/ 17 | 18 | #ifdef __cplusplus 19 | # define __LOG4C_BEGIN_DECLS extern "C" { 20 | # define __LOG4C_END_DECLS } 21 | #else 22 | # define __LOG4C_BEGIN_DECLS 23 | # define __LOG4C_END_DECLS 24 | #endif 25 | 26 | #define LOG4C_INLINE inline 27 | #define LOG4C_API extern 28 | #define LOG4C_DATA extern 29 | 30 | #ifdef __HP_cc 31 | #define inline __inline 32 | #endif 33 | 34 | #ifdef _WIN32 35 | # include 36 | #endif 37 | 38 | #ifndef GCC_VERSION 39 | #define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__) 40 | #endif /* GCC_VERSION */ 41 | 42 | #if GCC_VERSION < 2009 43 | #define OLD_VARIADIC_MACRO 1 44 | #endif 45 | 46 | #endif /* __log4c_defs_h */ 47 | -------------------------------------------------------------------------------- /src/log4c/layout_type_dated.h: -------------------------------------------------------------------------------- 1 | /* $Id$ 2 | * 3 | * layout_type_dated.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_layout_type_dated_h 11 | #define log4c_layout_type_dated_h 12 | 13 | /** 14 | * @file layout_type_dated.h 15 | * 16 | * @brief Implement a dated layout. 17 | * 18 | * In @c log4j.PatternLayout conventions, the dated layout has the following 19 | * conversion pattern: @c "%d %P %c - %m\n". 20 | * 21 | * Where 22 | * @li @c "%d" is the date of the logging event 23 | * @li @c "%P" is the priority of the logging event 24 | * @li @c "%c" is the category of the logging event 25 | * @li @c "%m" is the application supplied message associated with the 26 | * logging event 27 | * 28 | * 29 | * 30 | **/ 31 | 32 | #include 33 | #include 34 | 35 | __LOG4C_BEGIN_DECLS 36 | 37 | extern const log4c_layout_type_t log4c_layout_type_dated; 38 | 39 | __LOG4C_END_DECLS 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /src/log4c/layout_type_dated_r.h: -------------------------------------------------------------------------------- 1 | /* $Id$ 2 | * 3 | * layout_type_dated_r.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_layout_type_dated_r_h 11 | #define log4c_layout_type_dated_r_h 12 | 13 | /** 14 | * @file layout_type_dated_r.h 15 | * 16 | * @brief Implement a dated_r layout. 17 | * 18 | * In @c log4j.PatternLayout conventions, the dated_r layout has the following 19 | * conversion pattern: @c "%d %P %c - %m\n". 20 | * 21 | * Where 22 | * @li @c "%d" is the date of the logging event 23 | * @li @c "%P" is the priority of the logging event 24 | * @li @c "%c" is the category of the logging event 25 | * @li @c "%m" is the application supplied message associated with the 26 | * logging event 27 | * 28 | * 29 | * 30 | **/ 31 | 32 | #include 33 | #include 34 | 35 | __LOG4C_BEGIN_DECLS 36 | 37 | extern const log4c_layout_type_t log4c_layout_type_dated_r; 38 | 39 | __LOG4C_END_DECLS 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /src/log4c/layout_type_basic.c: -------------------------------------------------------------------------------- 1 | static const char version[] = "$Id$"; 2 | 3 | /* 4 | * layout.c 5 | * 6 | * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved. 7 | * 8 | * See the COPYING file for the terms of usage and distribution. 9 | */ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | /*******************************************************************************/ 18 | static const char* basic_format( 19 | const log4c_layout_t* a_layout, 20 | const log4c_logging_event_t* a_event) 21 | { 22 | static char buffer[1024]; 23 | 24 | snprintf(buffer, sizeof(buffer), "%-8s %s - %s\n", 25 | log4c_priority_to_string(a_event->evt_priority), 26 | a_event->evt_category, a_event->evt_msg); 27 | 28 | return buffer; 29 | } 30 | 31 | /*******************************************************************************/ 32 | const log4c_layout_type_t log4c_layout_type_basic = { 33 | "basic", 34 | basic_format, 35 | }; 36 | 37 | -------------------------------------------------------------------------------- /src/sd/sync: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | refdir=../../../sd/src/sd 4 | copy=no 5 | verbose=no 6 | 7 | usage() 8 | { 9 | cat </dev/null 2>&1 46 | fi 47 | 48 | test $? = 1 || continue 49 | 50 | echo "$i needs sync" 51 | 52 | test x$copy = xyes && cp -f ${refdir}/$i $i 53 | done 54 | 55 | 56 | exit 0 57 | -------------------------------------------------------------------------------- /log4c-config.in: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | prefix=@prefix@ 4 | exec_prefix=$prefix 5 | libdir=@libdir@ 6 | libexecdir=@libexecdir@ 7 | includedir=@includedir@ 8 | 9 | usage() 10 | { 11 | cat < 6 | #include 7 | #include 8 | 9 | /******************************************************************************/ 10 | extern int snprintf(char* s, size_t maxlen, const char* fmt, ...) 11 | { 12 | int len; 13 | va_list args; 14 | 15 | va_start(args, fmt); 16 | len = vsnprintf(s, maxlen, fmt, args); 17 | va_end(args); 18 | 19 | return len; 20 | } 21 | 22 | /******************************************************************************/ 23 | extern int vsnprintf(char* s, size_t maxlen, const char* fmt, va_list args) 24 | { 25 | int len; 26 | FILE f; 27 | 28 | if (maxlen == 0) 29 | return 0; 30 | 31 | memset(&f, 0, sizeof(f)); 32 | 33 | f._flag = _IOWRT + _IOSTRG; 34 | 35 | f._bufsiz = f._cnt = maxlen - 1; 36 | f._base = f._ptr = (unsigned char*) s; 37 | f._bufendp = f._base + f._bufsiz; 38 | 39 | len = vfprintf(&f, fmt, args); 40 | *f._ptr = '\0'; 41 | 42 | return len; 43 | } 44 | 45 | -------------------------------------------------------------------------------- /src/sd/error.c: -------------------------------------------------------------------------------- 1 | static const char version[] = "$Id$"; 2 | 3 | /* 4 | * See the COPYING file for the terms of usage and distribution. 5 | */ 6 | 7 | #ifdef HAVE_CONFIG_H 8 | #include "config.h" 9 | #endif 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #ifdef HAVE_STDARG_H 16 | # include 17 | #else 18 | # ifdef HAVE_VARARGS_H 19 | # include 20 | # endif 21 | #endif 22 | 23 | #include 24 | #include 25 | 26 | int sd_debug(const char *fmt, ...) 27 | { 28 | va_list args; 29 | int r; 30 | 31 | if (!getenv("SD_DEBUG")) 32 | return 0; 33 | 34 | r = fprintf(stderr, "[DEBUG] "); 35 | va_start(args, fmt); 36 | r += vfprintf(stderr, fmt, args); 37 | va_end(args); 38 | r += fprintf(stderr, "\n"); 39 | 40 | return r; 41 | } 42 | 43 | int sd_error(const char *fmt, ...) 44 | { 45 | va_list args; 46 | int r; 47 | 48 | if (!getenv("SD_ERROR")) 49 | return 0; 50 | 51 | r = fprintf(stderr, "[ERROR] "); 52 | va_start(args, fmt); 53 | r += vfprintf(stderr, fmt, args); 54 | va_end(args); 55 | r += fprintf(stderr, "\n"); 56 | 57 | return r; 58 | } 59 | -------------------------------------------------------------------------------- /src/sd/stack.h: -------------------------------------------------------------------------------- 1 | /* $Id$ 2 | * 3 | * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved. 4 | * 5 | * See the COPYING file for the terms of usage and distribution. 6 | */ 7 | 8 | #ifndef __sd_stack_h 9 | #define __sd_stack_h 10 | 11 | /** 12 | * @file stack.h @ingroup sd 13 | * 14 | * @brief Generic stack object. 15 | * 16 | * @todo documentation 17 | * @todo API homogeneity with sd_list and sd_hash 18 | */ 19 | 20 | #include 21 | #include 22 | 23 | __SD_BEGIN_DECLS 24 | 25 | typedef struct __sd_stack sd_stack_t; 26 | 27 | extern sd_stack_t* sd_stack_new(size_t max); 28 | extern void sd_stack_delete(sd_stack_t* astack, void (*free_data_fn)(void *)); 29 | extern size_t sd_stack_get_nelem(const sd_stack_t* astack); 30 | 31 | extern void sd_stack_clear(sd_stack_t* astack, void (*free_data_fn)(void *)); 32 | extern int sd_stack_push(sd_stack_t* astack, void *data); 33 | extern void* sd_stack_pop(sd_stack_t* astack); 34 | extern void* sd_stack_begin(sd_stack_t* astack); 35 | extern void* sd_stack_next(sd_stack_t* astack); 36 | extern void* sd_stack_end(sd_stack_t* astack); 37 | extern void* sd_stack_peek(sd_stack_t* astack); 38 | 39 | __SD_END_DECLS 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /src/sd/factory.h: -------------------------------------------------------------------------------- 1 | /* $Id$ 2 | * 3 | * factory.h 4 | * 5 | * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved. 6 | * See the COPYING file for the terms of usage and distribution. 7 | */ 8 | 9 | #ifndef __sd_factory_h 10 | #define __sd_factory_h 11 | 12 | /** 13 | * @file factory.h 14 | */ 15 | 16 | #include 17 | #include 18 | 19 | __SD_BEGIN_DECLS 20 | 21 | struct __sd_factory; 22 | typedef struct __sd_factory sd_factory_t; 23 | 24 | struct __sd_factory_ops 25 | { 26 | void* (*fac_new) (const char*); 27 | void (*fac_delete) (void*); 28 | void (*fac_print) (void*, FILE*); 29 | }; 30 | typedef struct __sd_factory_ops sd_factory_ops_t; 31 | 32 | extern sd_factory_t* sd_factory_new(const char* a_name, 33 | const sd_factory_ops_t* a_ops); 34 | extern void sd_factory_delete(sd_factory_t* a_this); 35 | extern void* sd_factory_get(sd_factory_t* a_this, const char* a_name); 36 | extern void sd_factory_destroy(sd_factory_t* a_this, void* a_pr); 37 | extern void sd_factory_print(const sd_factory_t* a_this, FILE* a_stream); 38 | extern int sd_factory_list(const sd_factory_t* a_this, void** a_items, 39 | int a_nitems); 40 | 41 | __SD_END_DECLS 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /src/log4c/logging_event.c: -------------------------------------------------------------------------------- 1 | static const char version[] = "$Id$"; 2 | 3 | /* 4 | * logging_event.c 5 | * 6 | * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved. 7 | * 8 | * See the COPYING file for the terms of usage and distribution. 9 | */ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | /*******************************************************************************/ 18 | extern log4c_logging_event_t* log4c_logging_event_new( 19 | const char* a_category, 20 | int a_priority, 21 | const char* a_message) 22 | { 23 | log4c_logging_event_t* evt; 24 | 25 | evt = sd_calloc(1, sizeof(log4c_logging_event_t)); 26 | evt->evt_category = a_category; 27 | evt->evt_priority = a_priority; 28 | evt->evt_msg = a_message; 29 | 30 | SD_GETTIMEOFDAY(&evt->evt_timestamp, NULL); 31 | 32 | return evt; 33 | } 34 | 35 | /*******************************************************************************/ 36 | extern void log4c_logging_event_delete(log4c_logging_event_t* this) 37 | { 38 | if (!this) 39 | return; 40 | 41 | free(this); 42 | } 43 | 44 | -------------------------------------------------------------------------------- /src/sd/test.h: -------------------------------------------------------------------------------- 1 | /* $Id$ 2 | * 3 | * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved. 4 | * 5 | * See the COPYING file for the terms of usage and distribution. 6 | */ 7 | 8 | #ifndef __sd_test_h 9 | #define __sd_test_h 10 | 11 | /** 12 | * @file test.h 13 | */ 14 | 15 | #include 16 | #include 17 | 18 | __SD_BEGIN_DECLS 19 | 20 | #define SD_TEST_MAX_NFUNC 100 21 | 22 | struct __sd_test; 23 | 24 | typedef struct __sd_test sd_test_t; 25 | 26 | typedef int (sd_test_func_t)(sd_test_t* a_test, int argc, char* argv[]); 27 | 28 | extern sd_test_t* sd_test_new(int a_argc, char* a_argv[]); 29 | extern void sd_test_delete(sd_test_t* a_this); 30 | 31 | extern const char* sd_test_get_name(const sd_test_t* a_this); 32 | extern int sd_test_get_verbose(const sd_test_t* a_test); 33 | extern int sd_test_set_verbose(sd_test_t* a_this, int a_verbose); 34 | 35 | extern FILE* sd_test_in(sd_test_t* a_this); 36 | extern FILE* sd_test_out(sd_test_t* a_this); 37 | extern FILE* sd_test_err(sd_test_t* a_this); 38 | 39 | extern int sd_test_run(sd_test_t* a_this, int argc, char* argv[]); 40 | extern int sd_test_add(sd_test_t* a_this, sd_test_func_t a_func); 41 | 42 | __SD_END_DECLS 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /msvc6/log4c/version.h: -------------------------------------------------------------------------------- 1 | /* $Id$ 2 | * 3 | * version.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_version_h 11 | #define log4c_version_h 12 | 13 | /** 14 | * @file version.h 15 | * 16 | * @brief log4c version information 17 | **/ 18 | 19 | #include 20 | 21 | __LOG4C_BEGIN_DECLS 22 | 23 | /** 24 | * constant macro holding the major version of log4c 25 | **/ 26 | #define LOG4C_MAJOR_VERSION 1 27 | /** 28 | * constant macro holding the minor version of log4c 29 | **/ 30 | #define LOG4C_MINOR_VERSION 0 31 | /** 32 | * constant macro holding the micro version of log4c 33 | **/ 34 | #define LOG4C_MICRO_VERSION 12 35 | 36 | /** 37 | * constant variable holding the major version of log4c 38 | **/ 39 | extern const int log4c_major_version; 40 | /** 41 | * constant variable holding the minor version of log4c 42 | **/ 43 | extern const int log4c_minor_version; 44 | /** 45 | * constant variable holding the micro version of log4c 46 | **/ 47 | extern const int log4c_micro_version; 48 | 49 | /** 50 | * @return a string containing the full log4c version 51 | **/ 52 | extern const char* log4c_version(void); 53 | 54 | __LOG4C_END_DECLS 55 | 56 | #endif 57 | 58 | -------------------------------------------------------------------------------- /src/log4c/version.h.in: -------------------------------------------------------------------------------- 1 | /* $Id$ 2 | * 3 | * version.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_version_h 11 | #define log4c_version_h 12 | 13 | /** 14 | * @file version.h 15 | * 16 | * @brief log4c version information 17 | **/ 18 | 19 | #include 20 | 21 | __LOG4C_BEGIN_DECLS 22 | 23 | /** 24 | * constant macro holding the major version of log4c 25 | **/ 26 | #define LOG4C_MAJOR_VERSION @LOG4C_MAJOR_VERSION@ 27 | /** 28 | * constant macro holding the minor version of log4c 29 | **/ 30 | #define LOG4C_MINOR_VERSION @LOG4C_MINOR_VERSION@ 31 | /** 32 | * constant macro holding the micro version of log4c 33 | **/ 34 | #define LOG4C_MICRO_VERSION @LOG4C_MICRO_VERSION@ 35 | 36 | /** 37 | * constant variable holding the major version of log4c 38 | **/ 39 | extern const int log4c_major_version; 40 | /** 41 | * constant variable holding the minor version of log4c 42 | **/ 43 | extern const int log4c_minor_version; 44 | /** 45 | * constant variable holding the micro version of log4c 46 | **/ 47 | extern const int log4c_micro_version; 48 | 49 | /** 50 | * @return a string containing the full log4c version 51 | **/ 52 | extern const char* log4c_version(void); 53 | 54 | __LOG4C_END_DECLS 55 | 56 | #endif 57 | 58 | -------------------------------------------------------------------------------- /src/log4c/layout_type_basic_r.c: -------------------------------------------------------------------------------- 1 | static const char version[] = "$Id$"; 2 | 3 | /* 4 | * layout.c 5 | * 6 | * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved. 7 | * 8 | * See the COPYING file for the terms of usage and distribution. 9 | */ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | /*******************************************************************************/ 17 | static const char* basic_r_format( 18 | const log4c_layout_t* a_layout, 19 | const log4c_logging_event_t* a_event) 20 | { 21 | int n, i; 22 | 23 | n = snprintf(a_event->evt_buffer.buf_data, a_event->evt_buffer.buf_size, 24 | "%-8s %s - %s\n", 25 | log4c_priority_to_string(a_event->evt_priority), 26 | a_event->evt_category, a_event->evt_msg); 27 | 28 | if (n >= a_event->evt_buffer.buf_size) { 29 | /* 30 | * append '...' at the end of the message to show it was 31 | * trimmed 32 | */ 33 | for (i = 0; i < 3; i++) 34 | a_event->evt_buffer.buf_data[a_event->evt_buffer.buf_size - 4 + i] = '.'; 35 | } 36 | 37 | return a_event->evt_buffer.buf_data; 38 | } 39 | 40 | /*******************************************************************************/ 41 | const log4c_layout_type_t log4c_layout_type_basic_r = { 42 | "basic_r", 43 | basic_r_format, 44 | }; 45 | 46 | -------------------------------------------------------------------------------- /src/log4c/Makefile.am: -------------------------------------------------------------------------------- 1 | INCLUDES = \ 2 | -I$(top_srcdir)/src \ 3 | -DLOG4C_RCPATH="\"$(sysconfdir)\"" 4 | 5 | lib_LTLIBRARIES = liblog4c.la 6 | 7 | liblog4c_la_SOURCES = \ 8 | rc.c \ 9 | init.c \ 10 | appender_type_stream.c \ 11 | appender_type_stream2.c \ 12 | appender_type_syslog.c \ 13 | appender_type_mmap.c \ 14 | layout_type_basic.c \ 15 | layout_type_dated.c \ 16 | layout_type_basic_r.c \ 17 | layout_type_dated_r.c \ 18 | version.c \ 19 | logging_event.c \ 20 | priority.c \ 21 | appender.c \ 22 | layout.c \ 23 | category.c 24 | 25 | if WITH_ROLLINGFILE 26 | liblog4c_la_SOURCES += appender_type_rollingfile.c \ 27 | rollingpolicy.c rollingpolicy_type_sizewin.c 28 | endif 29 | 30 | liblog4c_la_LDFLAGS = -version-info @LT_VERSION@ 31 | liblog4c_la_LIBADD = ../sd/liblog4c_sd.la 32 | 33 | pkginclude_HEADERS = \ 34 | config-win32.h \ 35 | buffer.h \ 36 | rc.h \ 37 | init.h \ 38 | defs.h \ 39 | version.h \ 40 | location_info.h \ 41 | logging_event.h \ 42 | priority.h \ 43 | layout_type_basic.h \ 44 | layout_type_dated.h \ 45 | layout_type_basic_r.h \ 46 | layout_type_dated_r.h \ 47 | layout.h \ 48 | appender_type_stream.h \ 49 | appender_type_stream2.h \ 50 | appender_type_syslog.h \ 51 | appender_type_mmap.h \ 52 | appender.h \ 53 | category.h \ 54 | appender_type_rollingfile.h \ 55 | rollingpolicy.h \ 56 | rollingpolicy_type_sizewin.h 57 | 58 | -------------------------------------------------------------------------------- /src/log4c/priority.c: -------------------------------------------------------------------------------- 1 | static const char version[] = "$Id$"; 2 | 3 | /* 4 | * priority.c 5 | * 6 | * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved. 7 | * 8 | * See the COPYING file for the terms of usage and distribution. 9 | */ 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | static const char* const priorities[] = { 16 | "FATAL", 17 | "ALERT", 18 | "CRIT", 19 | "ERROR", 20 | "WARN", 21 | "NOTICE", 22 | "INFO", 23 | "DEBUG", 24 | "TRACE", 25 | "NOTSET", 26 | "UNKNOWN" 27 | }; 28 | 29 | static const size_t npriorities = sizeof(priorities) / sizeof(priorities[0]); 30 | 31 | /*******************************************************************************/ 32 | extern const char* log4c_priority_to_string(int a_priority) 33 | { 34 | a_priority /= 100; 35 | if ( (a_priority < 0) || (a_priority > 10) ) 36 | a_priority = 10; 37 | 38 | return priorities[a_priority]; 39 | } 40 | 41 | /*******************************************************************************/ 42 | extern int log4c_priority_to_int(const char* a_priority_name) 43 | { 44 | size_t i; 45 | 46 | if (a_priority_name) { 47 | for (i = 0; i < npriorities; i++) { 48 | if (!strncasecmp(priorities[i], a_priority_name, strlen(priorities[i]))) 49 | return i * 100; 50 | } 51 | } 52 | 53 | return LOG4C_PRIORITY_UNKNOWN; 54 | } 55 | 56 | -------------------------------------------------------------------------------- /src/log4c/init.h: -------------------------------------------------------------------------------- 1 | /* $Id$ 2 | * 3 | * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved. 4 | * 5 | * See the COPYING file for the terms of usage and distribution. 6 | */ 7 | 8 | #ifndef __log4c_init_h 9 | #define __log4c_init_h 10 | 11 | #include 12 | #include 13 | 14 | /** 15 | * @file init.h 16 | * 17 | * @brief log4c constructors and destructors 18 | * 19 | **/ 20 | 21 | /** 22 | * constructor 23 | * 24 | * @returns 0 for success 25 | **/ 26 | LOG4C_API int log4c_init(void); 27 | 28 | /** 29 | * destructor 30 | * 31 | * @returns 0 for success 32 | **/ 33 | LOG4C_API int log4c_fini(void); 34 | 35 | /* 36 | * Dumps all the current appender, layout and rollingpolicy types 37 | * known by log4c. 38 | * @param stream to write to 39 | */ 40 | LOG4C_API void log4c_dump_all_types(FILE *fp); 41 | 42 | /* 43 | * Dumps all the current instances of categories, appenders, layouts 44 | * and rollingpolicy objects. 45 | * An instances of a type consists of the base 46 | * type information (name plus function table) and an instance name and 47 | * configuration. For example one can have an instance of the rollingfile 48 | * appender which logs to /var/tmp and another instance which logs to 49 | * /usr/tmp. They are both of type rollingfile, but are distinct instances of 50 | * it 51 | * @param stream to write t 52 | */ 53 | LOG4C_API void log4c_dump_all_instances(FILE *fp); 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /src/log4c/rc.h: -------------------------------------------------------------------------------- 1 | /* $Id$ 2 | * 3 | * rc.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_rc_h 11 | #define __log4c_rc_h 12 | 13 | /** 14 | * @file rc.h 15 | * 16 | * @brief log4c resource configuration 17 | * 18 | **/ 19 | 20 | #include 21 | 22 | __LOG4C_BEGIN_DECLS 23 | 24 | /** 25 | * @brief resource configuration object 26 | * 27 | * Attributes description: 28 | * 29 | * @li @c nocleanup don't perform memory cleanup in log4c library 30 | * destructor or in log4c_fini() 31 | * @li @c bufsize maximum logging buffer size. 0 for no limits 32 | * @li @c debug activate log4c debugging 33 | **/ 34 | typedef struct 35 | { 36 | struct 37 | { 38 | int nocleanup; 39 | int bufsize; 40 | int debug; 41 | int reread; 42 | } config; 43 | 44 | } log4c_rc_t; 45 | 46 | /** 47 | * default log4c resource configuration object 48 | **/ 49 | LOG4C_API log4c_rc_t * const log4c_rc; 50 | 51 | /** 52 | * load log4c resource configuration file 53 | * 54 | * @param a_filename name of file to load 55 | **/ 56 | LOG4C_API int log4c_load(const char* a_filename); 57 | 58 | /** 59 | * @internal 60 | **/ 61 | LOG4C_API int log4c_rc_load(log4c_rc_t* a_rc, const char* a_filename); 62 | 63 | /* 64 | * Rereads any log4crc files that have changed 65 | */ 66 | LOG4C_API void log4c_reread(void); 67 | 68 | __LOG4C_END_DECLS 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /src/log4c/appender_type_syslog.h: -------------------------------------------------------------------------------- 1 | /* $Id$ 2 | * 3 | * appender_type_syslog.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_appender_type_syslog_h 11 | #define log4c_appender_type_syslog_h 12 | 13 | /** 14 | * @file appender_type_syslog.h 15 | * 16 | * @brief Log4c syslog(3) appender interface. 17 | * 18 | * The syslog appender uses the syslog(3) interface for logging. The log4c 19 | * priorities are mapped to the syslog priorities and the appender name is 20 | * used as a syslog identifier. 1 default syslog appender is defined: @c 21 | * "syslog". 22 | * 23 | * The following examples shows how to define and use syslog appenders. 24 | * 25 | * @code 26 | * 27 | * log4c_appender_t* myappender; 28 | * 29 | * myappender = log4c_appender_get("myappender"); 30 | * log4c_appender_set_type(myappender, &log4c_appender_type_syslog); 31 | * 32 | * @endcode 33 | * 34 | **/ 35 | 36 | #include 37 | #include 38 | 39 | __LOG4C_BEGIN_DECLS 40 | 41 | /** 42 | * Syslog appender type definition. 43 | * 44 | * This should be used as a parameter to the log4c_appender_set_type() 45 | * routine to set the type of the appender. 46 | * 47 | **/ 48 | extern const log4c_appender_type_t log4c_appender_type_syslog; 49 | 50 | extern int log4c_appender_syslog_set_facility(const log4c_appender_t*, int); 51 | 52 | __LOG4C_END_DECLS 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /src/sd/sprintf.c: -------------------------------------------------------------------------------- 1 | static const char version[] = "$Id$"; 2 | 3 | /* 4 | * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved. 5 | * 6 | * See the COPYING file for the terms of usage and distribution. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | /******************************************************************************/ 18 | extern char* sd_sprintf(const char* a_fmt, ...) 19 | { 20 | char* buffer; 21 | va_list args; 22 | 23 | va_start(args, a_fmt); 24 | buffer = sd_vsprintf(a_fmt, args); 25 | va_end(args); 26 | 27 | return buffer; 28 | } 29 | 30 | /******************************************************************************/ 31 | extern char* sd_vsprintf(const char* a_fmt, va_list a_args) 32 | { 33 | int size = 1024; 34 | char* buffer = sd_calloc(size, sizeof(char)); 35 | 36 | while (1) { 37 | int n = vsnprintf(buffer, size, a_fmt, a_args); 38 | 39 | /* If that worked, return */ 40 | if (n > -1 && n < size) 41 | return buffer; 42 | 43 | /* Else try again with more space. */ 44 | if (n > -1) /* ISO/IEC 9899:1999 */ 45 | size = n + 1; 46 | else /* twice the old size */ 47 | size *= 2; 48 | 49 | buffer = sd_realloc(buffer, size); 50 | } 51 | } 52 | 53 | #if defined(__osf__) 54 | # ifndef snprintf 55 | # include "sprintf.osf.c" 56 | # endif 57 | #endif 58 | 59 | -------------------------------------------------------------------------------- /src/log4c/appender_type_mmap.h: -------------------------------------------------------------------------------- 1 | /* $Id$ 2 | * 3 | * appender_type_mmap.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_appender_type_mmap_h 11 | #define log4c_appender_type_mmap_h 12 | 13 | /** 14 | * @file appender_type_mmap.h 15 | * 16 | * @brief Log4c mmap(2) appender interface. 17 | * 18 | * The mmap appender uses a fixed length memory mapped file for 19 | * logging. The appender's name is used as the file name which will be 20 | * opened and mapped to memory at first use. The memory mapped file is then 21 | * used as a rotating buffer in which logging events are written. 22 | * 23 | * The following examples shows how to define and use mmap appenders. 24 | * 25 | * @code 26 | * 27 | * log4c_appender_t* myappender; 28 | * 29 | * myappender = log4c_appender_get("myfile.log"); 30 | * log4c_appender_set_type(myappender, &log4c_appender_type_mmap); 31 | * 32 | * @endcode 33 | * 34 | * @warning the file is not created at first use. It should already exist 35 | * and have a reasonable size, a mutilple of a page size. 36 | * 37 | **/ 38 | #include 39 | #include 40 | 41 | __LOG4C_BEGIN_DECLS 42 | 43 | /** 44 | * Mmap appender type definition. 45 | * 46 | * This should be used as a parameter to the log4c_appender_set_type() 47 | * routine to set the type of the appender. 48 | * 49 | **/ 50 | extern const log4c_appender_type_t log4c_appender_type_mmap; 51 | 52 | __LOG4C_END_DECLS 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /tests/log4c/test_rc.ref: -------------------------------------------------------------------------------- 1 | => test #0 : 2 | factory[log4c_category_factory]: 3 | { name:'root' priority:NOTICE additive:1 appender:'(nil)' parent:'(nil)' } 4 | 5 | factory[log4c_appender_factory]: 6 | { name:'syslog' type:'syslog' layout:'basic' isopen:0 udata:(nil)} 7 | { name:'stderr' type:'stream' layout:'dated' isopen:0 udata:0x42127480} 8 | { name:'stdout' type:'stream' layout:'basic' isopen:0 udata:0x42127320} 9 | 10 | factory[log4c_layout_factory]: 11 | { name:'basic' type:'basic' udata:(nil) } 12 | { name:'dated' type:'dated' udata:(nil) } 13 | 14 | => test #0 : passed 15 | => test #1 : 16 | factory[log4c_category_factory]: 17 | { name:'' priority:UNKNOWN additive:1 appender:'(nil)' parent:'root' } 18 | { name:'a.b' priority:DEBUG additive:1 appender:'afile' parent:'a' } 19 | { name:'root' priority:ERROR additive:1 appender:'stderr' parent:'(nil)' } 20 | { name:'a.b.c' priority:WARN additive:1 appender:'(nil)' parent:'a.b' } 21 | { name:'a.b.c.d' priority:TRACE additive:1 appender:'(nil)' parent:'a.b.c' } 22 | { name:'a' priority:INFO additive:1 appender:'' parent:'root' } 23 | 24 | factory[log4c_appender_factory]: 25 | { name:'' type:'stream' layout:'basic' isopen:0 udata:(nil)} 26 | { name:'syslog' type:'syslog' layout:'basic' isopen:0 udata:(nil)} 27 | { name:'stderr' type:'stream' layout:'dated' isopen:0 udata:0x42127480} 28 | { name:'afile' type:'stream' layout:'toto' isopen:0 udata:(nil)} 29 | { name:'stdout' type:'stream' layout:'basic' isopen:0 udata:0x42127320} 30 | 31 | factory[log4c_layout_factory]: 32 | { name:'toto' type:'basic' udata:(nil) } 33 | { name:'basic' type:'basic' udata:(nil) } 34 | { name:'dated' type:'dated' udata:(nil) } 35 | 36 | => test #1 : passed 37 | -------------------------------------------------------------------------------- /release: -------------------------------------------------------------------------------- 1 | # 2 | # Get log4c version and contruct directory name 3 | # 4 | major=$(grep LOG4C_MAJOR_VERSION= configure.in) 5 | minor=$(grep LOG4C_MINOR_VERSION= configure.in) 6 | micro=$(grep LOG4C_MICRO_VERSION= configure.in) 7 | fname=log4c-${major:20}.${minor:20}.${micro:20} 8 | tagname=log4c_${major:20}_${minor:20}_${micro:20} 9 | 10 | echo "Building dist tarball for release $fname" 11 | echo "CVS tagname $tagname" 12 | 13 | # 14 | # clean up from previous run 15 | # 16 | rm -fr log4c_dist 17 | rm -fr $fname 18 | 19 | 20 | mkdir log4c_dist 21 | pushd log4c_dist 22 | 23 | 24 | 25 | prompt="Do you want a fresh cvs checkout , cvs co -r $tagname (y/n)" 26 | echo -n $prompt 27 | read answer 28 | 29 | if [ "y" == "$answer" ] 30 | then 31 | echo "Pulling from CVS with cvs co -r $tagname" 32 | cvs co -r $tagname log4c 33 | else 34 | echo "Copying from starting working dir" 35 | cp -r ../../log4c . 36 | fi 37 | 38 | # 39 | # make dist 40 | # 41 | 42 | pushd log4c 43 | ./bootstrap 44 | ./configure 45 | make dist 46 | popd 47 | # 48 | # 49 | # 50 | echo "unpacking and testing tarball $fname.tar.gz" 51 | tar -xzvf log4c/$fname.tar.gz 52 | pushd $fname 53 | mkdir build 54 | pushd build 55 | # --enable-debug 56 | ../configure --enable-doc --enable-test --enable-reread --enable-test --prefix=`pwd`/install 57 | make 58 | make install 59 | make check 60 | popd 61 | 62 | popd 63 | 64 | 65 | # 66 | # Resync the docs 67 | # rsync -av --delete log4c-1.2.1/build/doc/html/ your_username@shell.sf.net:/home/groups/l/lo/log4c/htdocs/ 68 | # 69 | 70 | # 71 | # Upload the new file and create the release 72 | # 73 | # https://sourceforge.net/docman/display_doc.php?docid=6445&group_id=1 74 | # 75 | -------------------------------------------------------------------------------- /src/log4c/priority.h: -------------------------------------------------------------------------------- 1 | /* $Id$ 2 | * 3 | * priority.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_priority_h 11 | #define log4c_priority_h 12 | 13 | /** 14 | * @file priority.h 15 | * 16 | * @brief The priority class provides importance levels with which one can 17 | * categorize log messages. 18 | **/ 19 | 20 | #include 21 | 22 | __LOG4C_BEGIN_DECLS 23 | 24 | /** 25 | * Predefined Levels of priorities. These correspond to the priority levels 26 | * used by syslog(3). 27 | **/ 28 | typedef enum { 29 | /** fatal */ LOG4C_PRIORITY_FATAL = 000, 30 | /** alert */ LOG4C_PRIORITY_ALERT = 100, 31 | /** crit */ LOG4C_PRIORITY_CRIT = 200, 32 | /** error */ LOG4C_PRIORITY_ERROR = 300, 33 | /** warn */ LOG4C_PRIORITY_WARN = 400, 34 | /** notice */ LOG4C_PRIORITY_NOTICE = 500, 35 | /** info */ LOG4C_PRIORITY_INFO = 600, 36 | /** debug */ LOG4C_PRIORITY_DEBUG = 700, 37 | /** trace */ LOG4C_PRIORITY_TRACE = 800, 38 | /** notset */ LOG4C_PRIORITY_NOTSET = 900, 39 | /** unknown */ LOG4C_PRIORITY_UNKNOWN = 1000 40 | } log4c_priority_level_t; 41 | 42 | /** 43 | * @param a_priority a numeric value of the priority. 44 | * @returns the given priority string name. 45 | **/ 46 | LOG4C_API const char* log4c_priority_to_string(int a_priority); 47 | 48 | /** 49 | * @param a_priority_name a priority string name. 50 | * @returns the given numeric value of the priority. 51 | **/ 52 | LOG4C_API int log4c_priority_to_int(const char* a_priority_name); 53 | 54 | __LOG4C_END_DECLS 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /doc/Makefile.am: -------------------------------------------------------------------------------- 1 | man3dir = $(mandir)/man3 2 | docdir = $(datadir)/doc/$(PACKAGE)-$(VERSION) 3 | docfiles = \ 4 | $(top_srcdir)/README \ 5 | $(top_srcdir)/AUTHORS \ 6 | $(top_srcdir)/NEWS \ 7 | $(top_srcdir)/COPYING \ 8 | $(top_srcdir)/ChangeLog 9 | 10 | .PHONY: doxygen 11 | 12 | targets = doxygen 13 | 14 | if HAVE_LATEX 15 | targets += $(PACKAGE).pdf 16 | docfiles += $(PACKAGE).pdf 17 | endif 18 | 19 | all-local: $(targets) 20 | 21 | doxygen: Doxyfile main.doc 22 | @DOXYGEN@ 23 | 24 | # 25 | # If you tell Doxygen to generate latex via the GENERATE_LATEX option 26 | # in Doxyfile then it creates a 'latex' subdirectory containing 27 | # a Makefile to generate the stuff. 28 | # 29 | $(PACKAGE).pdf: 30 | $(MAKE) -C ./latex pdf 31 | cp -f ./latex/refman.pdf $(PACKAGE).pdf 32 | 33 | install-data-local: 34 | $(mkinstalldirs) $(DESTDIR)$(man3dir) 35 | @for i in ./man/man3/*.3; do \ 36 | inst=$(PACKAGE)_`basename $$i | sed -e 's/^$(PACKAGE)_//g' `; \ 37 | sed 's,man3/,man3/$(PACKAGE)_,' $$i > $$inst; \ 38 | echo "$(INSTALL_DATA) $$i $(DESTDIR)$(man3dir)/$$inst"; \ 39 | $(INSTALL_DATA) $$inst $(DESTDIR)$(man3dir)/$$inst; \ 40 | rm $$inst; \ 41 | done 42 | $(mkinstalldirs) $(DESTDIR)$(docdir) 43 | @for i in $(docfiles); do \ 44 | echo "$(INSTALL_DATA) $$i $(DESTDIR)$(docdir)"; \ 45 | $(INSTALL_DATA) $$i $(DESTDIR)$(docdir); \ 46 | done 47 | cp -r html $(DESTDIR)$(docdir) 48 | 49 | uninstall-local: 50 | @for i in ./man/man3/*.3; do \ 51 | inst=$(PACKAGE)_`basename $$i | sed -e 's/^$(PACKAGE)_//g' `; \ 52 | echo "rm -f $(DESTDIR)$(man3dir)/$$inst"; \ 53 | rm -f $(DESTDIR)$(man3dir)/$$inst; \ 54 | done 55 | rm -rf $(DESTDIR)$(docdir)/* 56 | 57 | clean-local: 58 | $(RM) -r latex man html $(PACKAGE).pdf doxygen.log 59 | 60 | -------------------------------------------------------------------------------- /src/sd/Makefile.am: -------------------------------------------------------------------------------- 1 | INCLUDES = \ 2 | -I$(top_srcdir)/src \ 3 | $(EXPAT_CFLAGS) 4 | 5 | noinst_LTLIBRARIES = liblog4c_sd.la 6 | 7 | liblog4c_sd_la_SOURCES = \ 8 | error.h \ 9 | defs.h \ 10 | stack.h \ 11 | stack.c \ 12 | list.h \ 13 | list.c \ 14 | malloc.h \ 15 | malloc.c \ 16 | domnode.h \ 17 | factory.h \ 18 | factory.c \ 19 | hash.h \ 20 | hash.c \ 21 | sprintf.h \ 22 | sprintf.c \ 23 | test.h \ 24 | test.c \ 25 | sd_xplatform.h \ 26 | sd_xplatform.c \ 27 | error.c 28 | 29 | liblog4c_sd_la_LDFLAGS = $(EXPAT_LIBS) 30 | 31 | if USE_EXPAT 32 | liblog4c_sd_la_SOURCES += domnode-expat.c 33 | else 34 | liblog4c_sd_la_SOURCES += \ 35 | domnode.c \ 36 | domnode-xml.h \ 37 | domnode-xml.c \ 38 | domnode-xml-parser.h \ 39 | domnode-xml-parser.c \ 40 | domnode-xml-scanner.h \ 41 | domnode-xml-scanner.c 42 | endif 43 | 44 | 45 | EXTRA_liblog4c_sd_la_SOURCES = \ 46 | domnode-xml-parser.y \ 47 | domnode-xml-scanner.l \ 48 | sprintf.osf.c 49 | 50 | # 51 | # requires bison-1.35 as found on redhat-7.3 52 | # 53 | domnode-xml-parser.c domnode-xml-parser.h: 54 | bison $(srcdir)/domnode-xml-parser.y 55 | -mv domnode-xml-parser.[ch] $(srcdir) 2>/dev/null 56 | 57 | # 58 | # requires flex-2.5.27 from http://sourceforge.net/projects/lex/ 59 | # 60 | domnode-xml-scanner.c domnode-xml-scanner.h: 61 | /home/legoater/work/sourceforge/flex-2.5.27/flex $(srcdir)/domnode-xml-scanner.l 62 | -mv domnode-xml-scanner.[ch] $(srcdir) 2>/dev/null 63 | 64 | domnode-xml-parser.lo: domnode-xml-scanner.h 65 | domnode-xml-scanner.lo: domnode-xml-parser.h 66 | domnode-xml.lo: domnode-xml-scanner.c domnode-xml-parser.c 67 | -------------------------------------------------------------------------------- /src/sd/sprintf.h: -------------------------------------------------------------------------------- 1 | /* $Id$ 2 | * 3 | * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved. 4 | * 5 | * See the COPYING file for the terms of usage and distribution. 6 | */ 7 | 8 | #ifndef __sd_sprintf_h 9 | #define __sd_sprintf_h 10 | 11 | /** 12 | * @file sprintf.h 13 | * 14 | * @brief Formatted output conversion 15 | * 16 | * These functions write the output under the control of a format 17 | * string that specifies how subsequent arguments (or arguments 18 | * accessed via the variable-length argument facilities of stdarg(2)) 19 | * are converted for output. 20 | * 21 | * They do not write more than \a size bytes, including the trailing 22 | * \c '\0'. 23 | * 24 | * These functions return the number of characters printed (not 25 | * including the trailing \c `\0' used to end output to strings). They 26 | * return -1 if the output was truncated due to the @a size limit. 27 | * 28 | */ 29 | 30 | #include 31 | #include 32 | #include 33 | 34 | __SD_BEGIN_DECLS 35 | 36 | /** 37 | * Same as fprintf(3) with auto-allocation of the resulting buffer, 38 | * and output directly in a file, not a stream. 39 | */ 40 | extern int sd_fprintf(int fd, const char *fmt, ...); 41 | 42 | /** 43 | * Same as sprintf(3) with auto-allocation of the resulting buffer. 44 | */ 45 | extern char* sd_sprintf(const char* a_fmt, ...); 46 | 47 | /** 48 | * Same as vsprintf(3) with auto-allocation of the resulting buffer. 49 | */ 50 | extern char* sd_vsprintf(const char* a_fmt, va_list a_arg); 51 | 52 | #if defined(__osf__) 53 | extern int snprintf(char* str, size_t size, const char* fmt, ...); 54 | extern int vsnprintf(char* str, size_t size, const char* fmt, va_list arg); 55 | #endif 56 | 57 | __SD_END_DECLS 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /examples/log4crc.in: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 0 8 | 9 | 0 10 | 1 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /src/log4c/appender_type_stream.c: -------------------------------------------------------------------------------- 1 | static const char version[] = "$Id$"; 2 | 3 | /* 4 | * appender_stream.c 5 | * 6 | * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved. 7 | * 8 | * See the COPYING file for the terms of usage and distribution. 9 | */ 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | /*******************************************************************************/ 16 | static int stream_open(log4c_appender_t* this) 17 | { 18 | FILE* fp = log4c_appender_get_udata(this); 19 | 20 | if (fp) 21 | return 0; 22 | 23 | if ( (fp = fopen(log4c_appender_get_name(this), "w+")) == NULL) 24 | fp = stderr; 25 | 26 | /* unbuffered mode */ 27 | setbuf(fp, NULL); 28 | 29 | log4c_appender_set_udata(this, fp); 30 | return 0; 31 | } 32 | 33 | /*******************************************************************************/ 34 | static int stream_append(log4c_appender_t* this, 35 | const log4c_logging_event_t* a_event) 36 | { 37 | FILE* fp = log4c_appender_get_udata(this); 38 | 39 | return fprintf(fp, "[%s] %s", log4c_appender_get_name(this), 40 | a_event->evt_rendered_msg); 41 | } 42 | 43 | /*******************************************************************************/ 44 | static int stream_close(log4c_appender_t* this) 45 | { 46 | FILE* fp = log4c_appender_get_udata(this); 47 | 48 | 49 | if (!fp || fp == stdout || fp == stderr) 50 | return 0; 51 | 52 | return fclose(fp); 53 | } 54 | 55 | /*******************************************************************************/ 56 | const log4c_appender_type_t log4c_appender_type_stream = { 57 | "stream", 58 | stream_open, 59 | stream_append, 60 | stream_close, 61 | }; 62 | 63 | -------------------------------------------------------------------------------- /tests/log4c/Makefile.am: -------------------------------------------------------------------------------- 1 | INCLUDES = \ 2 | -I$(top_srcdir)/src \ 3 | -DSRCDIR="\"$(srcdir)\"" 4 | 5 | noinst_PROGRAMS = test_category test_rc bench bench_fwrite \ 6 | test_stream2 test_layout_r cpp_compile_test 7 | 8 | if WITH_ROLLINGFILE 9 | noinst_PROGRAMS += test_rollingfile_appender test_rollingfile_appender_mt 10 | endif 11 | 12 | cpp_compile_test_SOURCES = cpp_compile_test.cpp 13 | 14 | test_category_SOURCES = test_category.c 15 | test_category_LDADD = $(top_builddir)/src/log4c/liblog4c.la 16 | 17 | test_rc_SOURCES = test_rc.c 18 | test_rc_LDADD = $(top_builddir)/src/log4c/liblog4c.la 19 | 20 | bench_SOURCES = bench.c 21 | bench_LDADD = $(top_builddir)/src/log4c/liblog4c.la 22 | 23 | bench_fwrite_SOURCES = bench_fwrite.c 24 | bench_fwrite_LDADD = $(top_builddir)/src/log4c/liblog4c.la -lpthread 25 | 26 | test_stream2_SOURCES = \ 27 | test_stream2.c 28 | test_stream2_LDADD = $(top_builddir)/src/log4c/liblog4c.la 29 | 30 | test_layout_r_SOURCES = \ 31 | test_layout_r.c 32 | test_layout_r_LDADD = $(top_builddir)/src/log4c/liblog4c.la 33 | 34 | if WITH_ROLLINGFILE 35 | test_rollingfile_appender_SOURCES = test_rollingfile_appender.c 36 | test_rollingfile_appender_LDADD = $(top_builddir)/src/log4c/liblog4c.la 37 | 38 | test_rollingfile_appender_mt_SOURCES = test_rollingfile_appender_mt.c 39 | test_rollingfile_appender_mt_LDADD = $(top_builddir)/src/log4c/liblog4c.la \ 40 | -lpthread 41 | endif 42 | 43 | EXTRA_DIST = \ 44 | test_category.ref \ 45 | test_rc.in \ 46 | test_rc.ref 47 | 48 | bench.mmap: 49 | dd if=/dev/zero of=$@ bs=1k count=64 50 | 51 | all-local: bench.mmap 52 | 53 | check-local: 54 | @for i in test_category test_rc; do \ 55 | ./$$i || exit 1; \ 56 | test -f $(srcdir)/$$i.ref && diff $$i.out $(srcdir)/$$i.ref || exit 1; \ 57 | done 58 | 59 | clean-local: 60 | $(RM) *.out bench.mmap 61 | 62 | -------------------------------------------------------------------------------- /src/log4c/location_info.h: -------------------------------------------------------------------------------- 1 | /* $Id$ 2 | * 3 | * location_info.h 4 | * 5 | * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved. 6 | 7 | 8 | * See the COPYING file for the terms of usage and distribution. 9 | */ 10 | 11 | #ifndef log4c_location_info_h 12 | #define log4c_location_info_h 13 | 14 | /** 15 | * @file location_info.h 16 | * 17 | * @brief The internal representation of caller location information. 18 | * 19 | * When a affirmative logging decision is made a log4c_location_info_t is 20 | * created and is passed around the different log4c components. 21 | **/ 22 | 23 | #include 24 | 25 | __LOG4C_BEGIN_DECLS 26 | 27 | /** 28 | * @brief logging location information 29 | * 30 | * Attributes description: 31 | * 32 | * @li @c loc_file file name 33 | * @li @c loc_line file line 34 | * @li @c loc_function function name 35 | * @li @c loc_data user data 36 | * 37 | * @todo this is not used 38 | **/ 39 | typedef struct 40 | { 41 | const char* loc_file; 42 | int loc_line; 43 | const char* loc_function; 44 | void* loc_data; 45 | 46 | } log4c_location_info_t; 47 | 48 | /** 49 | * log4c_location_info_t initializer 50 | **/ 51 | #ifdef __GNUC__ 52 | # define LOG4C_LOCATION_INFO_INITIALIZER(user_data) { __FILE__, __LINE__, __FUNCTION__, user_data } 53 | #else 54 | # define LOG4C_LOCATION_INFO_INITIALIZER(user_data) { __FILE__, __LINE__, "(nil)", user_data } 55 | #endif 56 | 57 | #define __log4c_str(n) #n 58 | 59 | #ifdef __GNUC__ 60 | # define __log4c_location(n) __FUNCTION__ "() at " __FILE__ ":" __log4c_str(n) 61 | #else 62 | # define __log4c_location(n) __FILE__ ":" __log4c_str(n) 63 | #endif 64 | 65 | /** 66 | * This macro returns the literal representation of a logging event 67 | * location 68 | **/ 69 | #define log4c_location __log4c_location(__LINE__) 70 | 71 | __LOG4C_END_DECLS 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /src/sd/domnode.h: -------------------------------------------------------------------------------- 1 | /* $Id$ 2 | * 3 | * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved. 4 | * See the COPYING file for the terms of usage and distribution. 5 | */ 6 | 7 | #ifndef __sd_domnode_h 8 | #define __sd_domnode_h 9 | 10 | /** 11 | * @file domnode.h @ingroup sd 12 | * 13 | * @brief Generic DOM object. 14 | */ 15 | 16 | #include 17 | #include 18 | 19 | __SD_BEGIN_DECLS 20 | 21 | typedef struct { 22 | const char* name; 23 | const char* value; 24 | sd_list_t* children; 25 | sd_list_t* attrs; 26 | } sd_domnode_t; 27 | 28 | extern sd_domnode_t* sd_domnode_new(const char* a_name, 29 | const char* a_value); 30 | 31 | extern void sd_domnode_delete(sd_domnode_t* this); 32 | 33 | extern int sd_domnode_read(sd_domnode_t* this, 34 | const char* a_buffer, size_t asize); 35 | extern int sd_domnode_write(sd_domnode_t* this, char** a_buffer, 36 | size_t* asize); 37 | 38 | extern int sd_domnode_fread(sd_domnode_t* this, FILE* a_stream); 39 | extern int sd_domnode_fwrite(const sd_domnode_t* this, 40 | FILE* a_stream); 41 | 42 | extern int sd_domnode_load(sd_domnode_t* this, 43 | const char* a_filename); 44 | 45 | extern int sd_domnode_store(const sd_domnode_t* this, 46 | const char* a_filename); 47 | 48 | extern sd_domnode_t* sd_domnode_search(const sd_domnode_t* this, 49 | const char* a_name); 50 | 51 | extern sd_domnode_t* sd_domnode_attrs_put(sd_domnode_t* this, 52 | sd_domnode_t* a_attr); 53 | extern sd_domnode_t* sd_domnode_attrs_get(const sd_domnode_t* this, 54 | const char* a_name); 55 | extern sd_domnode_t* sd_domnode_attrs_remove(sd_domnode_t* this, 56 | const char* a_name); 57 | 58 | /** Creates a new node. */ 59 | extern sd_domnode_t* __sd_domnode_new(const char* name, const char* a_value, 60 | int is_elem); 61 | 62 | __SD_END_DECLS 63 | 64 | #endif 65 | 66 | -------------------------------------------------------------------------------- /src/log4c/appender_type_stream.h: -------------------------------------------------------------------------------- 1 | /* $Id$ 2 | * 3 | * appender_type_stream.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_appender_type_stream_h 11 | #define log4c_appender_type_stream_h 12 | 13 | /** 14 | * @file appender_type_stream.h 15 | * 16 | * @brief Log4c stream appender interface. 17 | * 18 | * The stream appender uses a file handle @c FILE* for logging. The 19 | * appender's name is used as the file name which will be opened at first 20 | * log. An appender can also be associated to an opened file handle using 21 | * the log4c_appender_set_udata() method to update the appender user data 22 | * field. In this last case, the appender name has no meaning. 2 default 23 | * stream appenders are defined: @c "stdout" and @c "stderr". 24 | * 25 | * The following examples shows how to define and use stream appenders. 26 | * 27 | * @li the simple way 28 | * @code 29 | * 30 | * log4c_appender_t* myappender; 31 | * 32 | * myappender = log4c_appender_get("myfile.log"); 33 | * log4c_appender_set_type(myappender, &log4c_appender_type_stream); 34 | * 35 | * @endcode 36 | * 37 | * @li the sophisticated way 38 | * @code 39 | * 40 | * log4c_appender_t* myappender; 41 | * 42 | * myappender = log4c_appender_get("myappender"); 43 | * 44 | * log4c_appender_set_type(myappender, &log4c_appender_type_stream); 45 | * log4c_appender_set_udata(myappender, fopen("myfile.log", "w")); 46 | * 47 | * @endcode 48 | * 49 | **/ 50 | 51 | #include 52 | #include 53 | 54 | __LOG4C_BEGIN_DECLS 55 | 56 | /** 57 | * Stream appender type definition. 58 | * 59 | * This should be used as a parameter to the log4c_appender_set_type() 60 | * routine to set the type of the appender. 61 | * 62 | **/ 63 | extern const log4c_appender_type_t log4c_appender_type_stream; 64 | 65 | __LOG4C_END_DECLS 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /log4c.spec.in: -------------------------------------------------------------------------------- 1 | # $Id$ 2 | 3 | %define RELEASE 1 4 | %define rel %{?CUSTOM_RELEASE} %{!?CUSTOM_RELEASE:%RELEASE} 5 | %define _unpackaged_files_terminate_build 0 6 | 7 | Name: @PACKAGE@ 8 | Version: @VERSION@ 9 | Release: %rel 10 | 11 | Summary: Log for C 12 | License: LGPL 13 | Group: Development/Libraries 14 | Vendor: Cedric Le Goater 15 | Packager: Cedric Le Goater 16 | Url: http://%name.sourceforge.net/ 17 | Source: http://prdownloads.sourceforge.net/%name/%name-%version.tar.gz 18 | BuildRoot: %_topdir/%name-%version-root 19 | BuildRequires: doxygen 20 | Requires: /sbin/ldconfig 21 | 22 | %description 23 | %name is a Logging FrameWork for C, as Log4j or Log4Cpp. 24 | 25 | %package devel 26 | Summary: development tools for %name 27 | Group: Development/Libraries 28 | Requires: %name = %version 29 | 30 | %package doc 31 | Summary: documentation for %name 32 | Group: Development/Libraries 33 | Requires: %name = %version 34 | 35 | %description devel 36 | The %name-devel package contains the static libraries and header files 37 | needed for development with %name. 38 | 39 | %description doc 40 | The %name-doc package contains the %name documentation 41 | 42 | %prep 43 | %setup -q 44 | 45 | %build 46 | %configure --enable-doc 47 | make 48 | 49 | %install 50 | rm -rf %{buildroot} 51 | %makeinstall 52 | 53 | %clean 54 | rm -rf %{buildroot} 55 | 56 | %post -p /sbin/ldconfig 57 | 58 | %postun -p /sbin/ldconfig 59 | 60 | %files 61 | %defattr(-,root,root) 62 | %doc AUTHORS COPYING ChangeLog NEWS README 63 | %{_sysconfdir}/* 64 | %{_libdir}/*.so.* 65 | 66 | %files devel 67 | %defattr(-,root,root) 68 | %{_bindir}/* 69 | %{_includedir}/* 70 | %{_libdir}/*.a 71 | %{_libdir}/*.la 72 | %{_libdir}/*.so 73 | %{_datadir}/aclocal/* 74 | %{_mandir}/* 75 | 76 | %files doc 77 | %defattr(-,root,root) 78 | %doc doc/%{name}.pdf doc/html 79 | 80 | %changelog 81 | * Mon Feb 21 2002 Cedric Le Goater 82 | - Initial RPM release. 83 | 84 | # Local Variables: 85 | # mode:rpm-spec 86 | # End: 87 | -------------------------------------------------------------------------------- /src/log4c/layout_type_dated_r.c: -------------------------------------------------------------------------------- 1 | static const char version[] = "$Id$"; 2 | 3 | /* 4 | * layout.c 5 | * 6 | * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved. 7 | * 8 | * See the COPYING file for the terms of usage and distribution. 9 | */ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | /*******************************************************************************/ 19 | static const char* dated_r_format( 20 | const log4c_layout_t* a_layout, 21 | const log4c_logging_event_t*a_event) 22 | { 23 | int n, i; 24 | struct tm tm; 25 | 26 | #ifndef _WIN32 27 | #ifndef __HP_cc 28 | #warning gmtime() routine should be defined in sd_xplatform 29 | #endif 30 | gmtime_r(&a_event->evt_timestamp.tv_sec, &tm); 31 | #else 32 | /* xxx Need a CreateMutex/ReleaseMutex or something here 33 | */ 34 | { 35 | struct tm *tmp = NULL; 36 | tmp = gmtime(&a_event->evt_timestamp.tv_sec); 37 | tm = *tmp; /* struct copy */ 38 | } 39 | #endif 40 | 41 | n = snprintf(a_event->evt_buffer.buf_data, a_event->evt_buffer.buf_size, 42 | "%04d%02d%02d %02d:%02d:%02d.%03ld %-8s %s - %s\n", 43 | tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, 44 | tm.tm_hour, tm.tm_min, tm.tm_sec, 45 | a_event->evt_timestamp.tv_usec / 1000, 46 | log4c_priority_to_string(a_event->evt_priority), 47 | a_event->evt_category, a_event->evt_msg); 48 | 49 | if (n >= a_event->evt_buffer.buf_size) { 50 | /* 51 | * append '...' at the end of the message to show it was 52 | * trimmed 53 | */ 54 | for (i = 0; i < 3; i++) 55 | a_event->evt_buffer.buf_data[a_event->evt_buffer.buf_size - 4 + i] = '.'; 56 | } 57 | 58 | return a_event->evt_buffer.buf_data; 59 | } 60 | 61 | /*******************************************************************************/ 62 | const log4c_layout_type_t log4c_layout_type_dated_r = { 63 | "dated_r", 64 | dated_r_format, 65 | }; 66 | 67 | -------------------------------------------------------------------------------- /src/log4c/layout_type_dated.c: -------------------------------------------------------------------------------- 1 | static const char version[] = "$Id$"; 2 | 3 | /* 4 | * layout.c 5 | * 6 | * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved. 7 | * 8 | * See the COPYING file for the terms of usage and distribution. 9 | */ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | /*******************************************************************************/ 20 | static const char* dated_format( 21 | const log4c_layout_t* a_layout, 22 | const log4c_logging_event_t*a_event) 23 | { 24 | static char buffer[1024]; 25 | 26 | #ifndef _WIN32 27 | #ifndef __HP_cc 28 | #warning gmtime() routine should be defined in sd_xplatform 29 | #endif 30 | struct tm tm; 31 | gmtime_r(&a_event->evt_timestamp.tv_sec, &tm); 32 | snprintf(buffer, sizeof(buffer), "%04d%02d%02d %02d:%02d:%02d.%03ld %-8s %s- %s\n", 33 | tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, 34 | tm.tm_hour, tm.tm_min, tm.tm_sec, 35 | a_event->evt_timestamp.tv_usec / 1000, 36 | log4c_priority_to_string(a_event->evt_priority), 37 | a_event->evt_category, a_event->evt_msg); 38 | #else 39 | SYSTEMTIME stime; 40 | 41 | if ( FileTimeToSystemTime(&a_event->evt_timestamp, &stime)){ 42 | 43 | snprintf(buffer, sizeof(buffer), "%04d%02d%02d %02d:%02d:%02d.%03ld %-8s %s- %s\n", 44 | stime.wYear, stime.wMonth , stime.wDay, 45 | stime.wHour, stime.wMinute, stime.wSecond, 46 | stime.wMilliseconds, 47 | log4c_priority_to_string(a_event->evt_priority), 48 | a_event->evt_category, a_event->evt_msg); 49 | } 50 | #endif 51 | return buffer; 52 | } 53 | 54 | /*******************************************************************************/ 55 | const log4c_layout_type_t log4c_layout_type_dated = { 56 | "dated", 57 | dated_format, 58 | }; 59 | 60 | -------------------------------------------------------------------------------- /bootstrap: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Run this bootstrap script to 5 | # create the configure script and Makefile.in files etc. 6 | # 7 | # You need to do this if you have just done 'cvs co log4c'. 8 | # 9 | # We require: 10 | # autoconf 2.57+ 11 | # automake 1.7+ (recommended is 1.9+) 12 | # libtool 1.4+ 13 | # m4 1.4+ 14 | # perl 5.8+ 15 | # 16 | # Note that on vanilla RHEL3 you need to build on a local disk-- 17 | # some interaction of 'cp -p' with NFS. Fixed in RHEL4. 18 | # 19 | # Once the configure script is there you 20 | # can do something like "configure --enable-test" 21 | # to create the Makefiles. It is generarelly better if you 22 | # do that outside the source tree...something like this: 23 | # 24 | # cvs co log4c 25 | # cd log4c; ./bootstrap 26 | # cd ..; 27 | # mkdir fc5; cd fc5 28 | # ../log4c/configure --enable-test --enable-debug --enable-doc 29 | # make 30 | # 31 | 32 | # Need at least automake 1.7 33 | am_major=`automake --version | grep automake | cut -d " " -f 4 | cut -d "." -f 1` 34 | am_minor=`automake --version | grep automake | cut -d " " -f 4 | cut -d "." -f 2` 35 | digitver=`expr $am_major \* 10` 36 | digitver=`expr $digitver + $am_minor` 37 | if [ $digitver -lt 17 ]; then 38 | echo "Need at least automake 1.7--found $am_major.$am_minor" 39 | exit 1 40 | fi 41 | 42 | # If it's 1.9 or later take advantage of the force option 43 | ac_major=`aclocal --version | grep aclocal | cut -d " " -f 4 | cut -d "." -f 1` 44 | ac_minor=`aclocal --version | grep aclocal | cut -d " " -f 4 | cut -d "." -f 2` 45 | digitver=`expr $ac_major \* 10` 46 | digitver=`expr $digitver + $ac_minor` 47 | if [ $digitver -ge 19 ]; then 48 | ACLOCAL_FLAGS="$ACLOCAL_FLAGS --force" 49 | fi 50 | 51 | set -x 52 | 53 | if uname -a | egrep -i 'darwin'; then 54 | glibtoolize --force --automake --copy 55 | else 56 | libtoolize --force --automake --copy 57 | fi 58 | 59 | aclocal -I config $ACLOCAL_FLAGS 60 | autoheader --force 61 | automake --add-missing --copy 62 | autoconf --force 63 | # 64 | # "You can run the configure script now to build your Makefiles." 65 | # 66 | 67 | -------------------------------------------------------------------------------- /examples/helloworld1/mylog.h: -------------------------------------------------------------------------------- 1 | 2 | #include "log4c.h" 3 | 4 | #ifndef MYLOG_CATEGORY_NAME 5 | #define MYLOG_CATEGORY_NAME "root" 6 | #endif 7 | 8 | #define MYLOGMSG(priority,msg) mylog_msg(MYLOG_CATEGORY_NAME,priority,msg) 9 | 10 | #ifndef WITHOUT_LOG4C 11 | #define MYLOG_PRIORITY_ERROR LOG4C_PRIORITY_ERROR 12 | #define MYLOG_PRIORITY_WARN LOG4C_PRIORITY_WARN 13 | #define MYLOG_PRIORITY_NOTICE LOG4C_PRIORITY_NOTICE 14 | #define MYLOG_PRIORITY_DEBUG LOG4C_PRIORITY_DEBUG 15 | #define MYLOG_PRIORITY_TRACE LOG4C_PRIORITY_TRACE 16 | #else 17 | #define MYLOG_PRIORITY_ERROR 1 18 | #define MYLOG_PRIORITY_WARN 2 19 | #define MYLOG_PRIORITY_NOTICE 3 20 | #define MYLOG_PRIORITY_DEBUG 4 21 | #define MYLOG_PRIORITY_TRACE 5 22 | #endif 23 | 24 | static LOG4C_INLINE int mylog_init(){ 25 | #ifndef WITHOUT_LOG4C 26 | return(log4c_init()); 27 | #else 28 | return 0; 29 | #endif 30 | } 31 | 32 | static LOG4C_INLINE int mylog_fini(){ 33 | #ifndef WITHOUT_LOG4C 34 | return(log4c_fini()); 35 | #else 36 | return 0; 37 | #endif 38 | } 39 | 40 | static LOG4C_INLINE void mylog_msg(char *catName,int a_priority, char *msg){ 41 | #ifndef WITHOUT_LOG4C 42 | log4c_category_log(log4c_category_get(catName), a_priority, msg); 43 | #else 44 | printf(msg); 45 | #endif 46 | } 47 | 48 | static LOG4C_INLINE int mylog_setappender(char *catName, char *appName){ 49 | #ifndef WITHOUT_LOG4C 50 | log4c_category_set_appender(log4c_category_get(catName) 51 | ,log4c_appender_get(appName)); 52 | return(0); 53 | #else 54 | return(0); 55 | #endif 56 | } 57 | 58 | static LOG4C_INLINE void mylog_log(char *catName,int a_priority, 59 | const char* a_format,...){ 60 | #ifndef WITHOUT_LOG4C 61 | const log4c_category_t* a_category = log4c_category_get(catName); 62 | if (log4c_category_is_priority_enabled(a_category, a_priority)) { 63 | va_list va; 64 | va_start(va, a_format); 65 | log4c_category_vlog(a_category, a_priority, a_format, va); 66 | va_end(va); 67 | } 68 | #else 69 | va_list va; 70 | va_start(va, a_format); 71 | vprintf(a_format, va); 72 | va_end(va); 73 | #endif 74 | } 75 | 76 | -------------------------------------------------------------------------------- /tests/log4c/test_rc.c: -------------------------------------------------------------------------------- 1 | static const char version[] = "$Id$"; 2 | 3 | /* 4 | * test_rc.c 5 | * 6 | * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved. 7 | * 8 | * See the COPYING file for the terms of usage and distribution. 9 | */ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | /******************************************************************************/ 20 | static void log4c_print(FILE* a_fp) 21 | { 22 | extern sd_factory_t* log4c_category_factory; 23 | extern sd_factory_t* log4c_appender_factory; 24 | extern sd_factory_t* log4c_layout_factory; 25 | 26 | sd_factory_print(log4c_category_factory, a_fp); fprintf(a_fp, "\n"); 27 | sd_factory_print(log4c_appender_factory, a_fp); fprintf(a_fp, "\n"); 28 | sd_factory_print(log4c_layout_factory, a_fp); fprintf(a_fp, "\n"); 29 | } 30 | 31 | /******************************************************************************/ 32 | static int test0(sd_test_t* a_test, int argc, char* argv[]) 33 | { 34 | log4c_print(sd_test_out(a_test)); 35 | return 1; 36 | } 37 | 38 | /******************************************************************************/ 39 | static int test1(sd_test_t* a_test, int argc, char* argv[]) 40 | { 41 | log4c_rc_t rc; 42 | 43 | if (log4c_rc_load(&rc, SRCDIR "/test_rc.in") == -1) 44 | return 0; 45 | 46 | log4c_print(sd_test_out(a_test)); 47 | return 1; 48 | } 49 | 50 | /******************************************************************************/ 51 | static int test2(sd_test_t* a_test, int argc, char* argv[]) 52 | { 53 | log4c_rc_t rc; 54 | 55 | if (log4c_rc_load(&rc, SRCDIR "/test_rc.in") == -1) 56 | return 0; 57 | 58 | if (log4c_rc_load(&rc, SRCDIR "/test_rc.in") == -1) 59 | return 0; 60 | 61 | log4c_print(sd_test_out(a_test)); 62 | return 1; 63 | } 64 | 65 | /******************************************************************************/ 66 | int main(int argc, char* argv[]) 67 | { 68 | sd_test_t* t = sd_test_new(argc, argv); 69 | 70 | sd_test_add(t, test0); 71 | sd_test_add(t, test1); 72 | sd_test_add(t, test2); 73 | 74 | return ! sd_test_run(t, argc, argv); 75 | } 76 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | 2 | Last updated: 12 Nov 2006 3 | 4 | - new log4j naming conventions: category -> logger 5 | - multiple appenders per category 6 | - improve errors in configuration file parser 7 | - location_info is broken (need macro ?) 8 | - remove initialization of log4c when library is loaded (compatibility 9 | issues) 10 | . Currently printing some reminder messages in the init and fini sections with gcc. 11 | I guess we ditch those just before the release of 1.2 ? Or always leave em in the 12 | debug version... 13 | - add void* to location_info 14 | - thread safe ? 15 | . see the "Log4C Developers Guide" for a discussion of the issues 16 | and some sugggestions for fixing them. 17 | - expat: 18 | . behavior with autoconf is to use expat if it's there. That's ok but 19 | there needs to be an option so that prevents it being picked up--otherwise 20 | it's hard for release engineers to control what they manufacture with Log4C. 21 | - what is the stauts of the macosx build files--do they work with the latest workspace ? 22 | - improve sd/error.c 23 | . currently the sd_debug are functions...is that costly in the optimized build even if 24 | the body is empty ? 25 | - docs needs an update 26 | . home web page needs to be synced up to 1.1.0, link to latest API doc, 27 | and the draft developers guide. 28 | . Could probably use a "Log4C Internals" doc as well 29 | - rolling file appender: 30 | . take a file lock as well as the mutex. That would protect 31 | the file from other processes that might access it. 32 | - msvc: 33 | . the mapping of pthread to the native Windows thread functrions is done 34 | by macros definined in sd_xplatform.h. This works ok...but the join/cancel macros 35 | are not returning the right values. 36 | . two of the tests in the test_rc program are failing...need to look at that. 37 | . In category.h we make a special case for some of the inline functions on windows. 38 | This is not really required as the __inline (or __forceinline) directoves exist on windows. 39 | So we could just define inline to be __inline in sd_xplatform.h. 40 | - tests: 41 | . write a test program focused on lifecycle management of log4C objects. 42 | For example it can open, append, close in a loop to make sure everything works and 43 | ther eare no memory leaks. What about log4c_init, log4c_fini in a loop...not sure what that 44 | gives...not ethat the base types are not freed by log4c_fini.... 45 | 46 | -------------------------------------------------------------------------------- /examples/application_1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This is one of log4c example programs. 3 | * 4 | * Notice how no relationships between the category and a certain 5 | * priority, appender, or formatter are coded here. These are all left 6 | * to the log4crc config file so they can be chaned without recompiling 7 | * 8 | */ 9 | 10 | #ifdef HAVE_CONFIG_H 11 | #include "config.h" 12 | #endif 13 | 14 | #include 15 | #include 16 | #include 17 | #ifndef _WIN32 18 | #include 19 | #else 20 | #include 21 | #include 22 | #include 23 | #endif 24 | #ifdef HAVE_UNISTD_H 25 | #include 26 | #endif 27 | #include "log4c.h" 28 | 29 | #ifdef _WIN32 30 | int gettimeofday(struct timeval* tp, void* tzp) { 31 | DWORD t; 32 | t = timeGetTime(); 33 | tp->tv_sec = t / 1000; 34 | tp->tv_usec = t % 1000; 35 | /* 0 indicates that the call succeeded. */ 36 | return 0; 37 | } 38 | 39 | int sleep(DWORD t){ 40 | 41 | Sleep(1000*t); 42 | return(0); 43 | } 44 | #endif /* _WIN32 */ 45 | 46 | int main(int argc, char** argv) 47 | { 48 | struct timeval start_time; 49 | struct timeval now_time; 50 | int looptime = 0; 51 | log4c_category_t* mycat = NULL; 52 | int i = 0; 53 | 54 | if (argc < 2) 55 | { 56 | printf("usage: %s loop_time_in_seconds\n",argv[0]); 57 | exit (1); 58 | } 59 | if (sscanf(argv[1],"%d",&looptime) != 1) 60 | { 61 | printf("could not convert %s to number of seconds to loop\n",argv[1]); 62 | exit(1); 63 | } 64 | 65 | /* You could put your category class into a file with a wrapper macro 66 | * to make calling it easier and more consistent 67 | */ 68 | 69 | log4c_init(); 70 | mycat = log4c_category_get("six13log.log.app.application1"); 71 | 72 | gettimeofday(&start_time, NULL); 73 | gettimeofday(&now_time, NULL); 74 | i = 0; 75 | while ( (now_time.tv_sec - start_time.tv_sec) < looptime) 76 | { 77 | log4c_category_log(mycat, LOG4C_PRIORITY_DEBUG, "Debugging app 1 - loop %d", i); 78 | log4c_category_log(mycat, LOG4C_PRIORITY_ERROR, 79 | "some error from app1 at line %d in file %s - loop %d", 80 | __LINE__, __FILE__, i); 81 | 82 | sleep(3); 83 | 84 | gettimeofday(&now_time, NULL); 85 | i++; 86 | } 87 | 88 | /* Explicitly call the log4c cleanup routine */ 89 | if ( log4c_fini()){ 90 | printf("log4c_fini() failed"); 91 | } 92 | 93 | return 0; 94 | } 95 | 96 | -------------------------------------------------------------------------------- /examples/userloc_formatter.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Part of the log4c examples. 4 | * 5 | * Along with example_appenders.c this file is used to create a small 6 | * library of custom appenders and formatters. 7 | * 8 | * This library is excercised using application_3 and a sample log4crc 9 | * config file. 10 | * 11 | *****************************************************************************/ 12 | 13 | #include 14 | #include 15 | #include 16 | #include "application_3.h" 17 | 18 | /********************************************************************** 19 | * 20 | * Formatted to look for extended user location info 21 | * 22 | **********************************************************************/ 23 | static const char* userloc_format( 24 | const log4c_layout_t* a_layout, 25 | const log4c_logging_event_t*a_event) 26 | { 27 | static char buffer[4096]; 28 | user_locinfo_t* uloc = NULL; 29 | 30 | sd_debug("Formatter s13_userloc checking location info for userdata %X",a_event->evt_loc->loc_data); 31 | if (a_event->evt_loc->loc_data != NULL) 32 | { 33 | sd_debug("Formatter s13_userloc getting a valid user location info pointer"); 34 | uloc = (user_locinfo_t*) a_event->evt_loc->loc_data; 35 | sprintf(buffer, "[%s][HOST:%s][PID:%i][FILE:%s][LINE:%i][MSG:%s]", 36 | a_event->evt_category, 37 | uloc->hostname, uloc->pid, a_event->evt_loc->loc_file, 38 | a_event->evt_loc->loc_line,a_event->evt_msg); 39 | 40 | } 41 | else 42 | { 43 | sprintf(buffer, "[%s]::[FILE:%s][LINE:%i][MSG::%s]", 44 | a_event->evt_category, 45 | a_event->evt_loc->loc_file, 46 | a_event->evt_loc->loc_line,a_event->evt_msg); 47 | } 48 | return buffer; 49 | } 50 | 51 | const log4c_layout_type_t log4c_layout_type_userloc = { 52 | "s13_userloc", 53 | userloc_format, 54 | }; 55 | 56 | /*****************************/ 57 | /* 58 | * Here provide an init routine for this lib 59 | * 60 | ******************************/ 61 | static const log4c_layout_type_t * const layout_types[] = { 62 | &log4c_layout_type_userloc, 63 | }; 64 | static int nlayout_types = 65 | (int)(sizeof(layout_types) / sizeof(layout_types[0])); 66 | 67 | 68 | int init_userloc_formatters(){ 69 | 70 | int rc = 0; int i = 0; 71 | 72 | for (i = 0; i < nlayout_types; i++) 73 | log4c_layout_type_set(layout_types[i]); 74 | 75 | return(rc); 76 | 77 | } 78 | 79 | 80 | -------------------------------------------------------------------------------- /examples/README: -------------------------------------------------------------------------------- 1 | 2 | Sample programs using Log4C 3 | =========================== 4 | 5 | Please refer to the developers guide in the doc directory for a fuller 6 | explanation of these examples. 7 | 8 | helloworld -- classic simple program that logs the message "Hello World!" using Log4C. 9 | This example is used in the developers guide to explain some fundamental Log4C 10 | concepts. 11 | 12 | helloworld1 -- again the classic hello world example but demonstrating a technique 13 | for wrapping Log4C API calls to make it easy to remove Log4C from your code and 14 | demonstrating how to use a macro so that you name the category for your file just 15 | once at the start of the file. 16 | 17 | application_1 -- most basic example of using log4c. Notice that you 18 | only have to setup the category. Log4c is more powerful and flexible 19 | if you use the log4crc file to setup the relationship between 20 | category, appender, and formatter. 21 | 22 | application_2 -- example of using log4c with custom written appenders 23 | and formatters. Notice in Makefile.am that the linking for 24 | application_2 includes an additional library. This is an example of 25 | how you as a user of log4c would add in appenders and formatters. 26 | 27 | application_3 -- example of using log4c with extended user information. 28 | You would use this if your logging wanted to add things like which 29 | process_id, which machine, or any other additional location information 30 | you wanted to add to your logging. Notice that you have to write 31 | your own formatter that knows to look for the additional information. 32 | 33 | log4crc -- Notice the specifiers of how the catgories from the two 34 | example applications are wired up to appenders and formatters. Notice 35 | how when specifying a layout and appender, the type= string must match 36 | the name of the appender/formatter given in the code, but that the 37 | name= can be any name you want. Try and alter the priority= settings, 38 | the appender and layout settings in log4crc and rerunning the examples 39 | to see how the config affects which error messages will be printed. 40 | A new category to log to a rollingfile appender has been added 41 | 42 | reread -- If you used the --enable-reread flag during ./configure, you 43 | can test log4crc reread by running application_2 for 30 seconds, and 44 | while it is running edit the log4crc file and change the output level 45 | for application 2 between debug and error using a second window. In 46 | the window running application_2 you should notice the logging 47 | behaviour changes accordingly 48 | 49 | -------------------------------------------------------------------------------- /src/log4c/logging_event.h: -------------------------------------------------------------------------------- 1 | /* $Id$ 2 | * 3 | * logging_event.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_logging_event_h 11 | #define log4c_logging_event_h 12 | 13 | /** 14 | * @file logging_event.h 15 | * 16 | * @brief the internal representation of logging events. 17 | * 18 | * When a affirmative logging decision is made a log4c_logging_event 19 | * instance is created. This instance is passed around the different log4c 20 | * components. 21 | **/ 22 | 23 | #include 24 | #include 25 | #include 26 | #ifndef _WIN32 27 | #include 28 | #endif 29 | 30 | __LOG4C_BEGIN_DECLS 31 | 32 | struct __log4c_category; 33 | 34 | /** 35 | * @brief logging event object 36 | * 37 | * Attributes description: 38 | * 39 | * @li @c evt_category category name. 40 | * @li @c evt_priority priority of logging event. 41 | * @li @c evt_msg The application supplied message of logging event. 42 | * @li @c evt_buffer a pre allocated buffer to be used by layouts to 43 | * format in a multi-thread environment. 44 | * @li @c evt_rendered_msg The application supplied message after layout format. 45 | * @li @c evt_timestamp The number of seconds elapsed since the epoch 46 | * (1/1/1970 00:00:00 UTC) until logging event was created. 47 | * @li @c evt_loc The event's location information 48 | **/ 49 | typedef struct 50 | { 51 | const char* evt_category; 52 | int evt_priority; 53 | const char* evt_msg; 54 | const char* evt_rendered_msg; 55 | log4c_buffer_t evt_buffer; 56 | /* ok, this is probably not a good way to do it--should define a common type here 57 | and have the base acessor function do the mapping 58 | */ 59 | #ifndef _WIN32 60 | struct timeval evt_timestamp; 61 | #else 62 | FILETIME evt_timestamp; 63 | #endif 64 | const log4c_location_info_t* evt_loc; 65 | 66 | } log4c_logging_event_t; 67 | 68 | /** 69 | * Constructor for a logging event. 70 | * 71 | * @param a_category the category name 72 | * @param a_priority the category initial priority 73 | * @param a_message the message of this event 74 | * 75 | * @todo need to handle multi-threading (NDC) 76 | **/ 77 | LOG4C_API log4c_logging_event_t* log4c_logging_event_new( 78 | const char* a_category, 79 | int a_priority, 80 | const char* a_message); 81 | /** 82 | * Destructor for a logging event. 83 | * @param a_event the logging event object 84 | **/ 85 | LOG4C_API void log4c_logging_event_delete(log4c_logging_event_t* a_event); 86 | 87 | __LOG4C_END_DECLS 88 | 89 | #endif 90 | -------------------------------------------------------------------------------- /src/sd/sd_xplatform.c: -------------------------------------------------------------------------------- 1 | static const char version[] = "$Id$"; 2 | 3 | /* 4 | * sd_xplatform.c 5 | * 6 | * See the COPYING file for the terms of usage and distribution. 7 | */ 8 | 9 | #include 10 | #include 11 | #include "log4c/defs.h" 12 | 13 | #include "sd_xplatform.h" 14 | 15 | /****************** getopt *******************************/ 16 | 17 | #define EOF (-1) 18 | 19 | int sd_opterr = 1; 20 | int sd_optind = 1; 21 | int sd_optopt = 0; 22 | char *sd_optarg = NULL; 23 | int _sp = 1; 24 | 25 | #define warn(a,b,c)fprintf(stderr,a,b,c) 26 | 27 | void 28 | getopt_reset(void) 29 | { 30 | sd_opterr = 1; 31 | sd_optind = 1; 32 | sd_optopt = 0; 33 | sd_optarg = NULL; 34 | _sp = 1; 35 | } 36 | 37 | int 38 | sd_getopt(int argc, char *const *argv, const char *opts) 39 | { 40 | char c; 41 | char *cp; 42 | 43 | if (_sp == 1) { 44 | if (sd_optind >= argc || argv[sd_optind][0] != '-' || 45 | argv[sd_optind] == NULL || argv[sd_optind][1] == '\0') 46 | return (EOF); 47 | else if (strcmp(argv[sd_optind], "--") == 0) { 48 | sd_optind++; 49 | return (EOF); 50 | } 51 | } 52 | sd_optopt = c = (unsigned char)argv[sd_optind][_sp]; 53 | if (c == ':' || (cp = strchr(opts, c)) == NULL) { 54 | if (opts[0] != ':') 55 | warn("%s: illegal option -- %c\n", argv[0], c); 56 | if (argv[sd_optind][++_sp] == '\0') { 57 | sd_optind++; 58 | _sp = 1; 59 | } 60 | return ('?'); 61 | } 62 | 63 | if (*(cp + 1) == ':') { 64 | if (argv[sd_optind][_sp+1] != '\0') 65 | sd_optarg = &argv[sd_optind++][_sp+1]; 66 | else if (++sd_optind >= argc) { 67 | if (opts[0] != ':') { 68 | warn("%s: option requires an argument" 69 | " -- %c\n", argv[0], c); 70 | } 71 | _sp = 1; 72 | sd_optarg = NULL; 73 | return (opts[0] == ':' ? ':' : '?'); 74 | } else 75 | sd_optarg = argv[sd_optind++]; 76 | _sp = 1; 77 | } else { 78 | if (argv[sd_optind][++_sp] == '\0') { 79 | _sp = 1; 80 | sd_optind++; 81 | } 82 | sd_optarg = NULL; 83 | } 84 | return (c); 85 | } 86 | 87 | /***************************** gettimeofday *******************/ 88 | 89 | 90 | #ifdef _WIN32 91 | 92 | #if 0 /* also in winsock[2].h */ 93 | #define _TIMEVAL_DEFINED 94 | struct timeval { 95 | long tv_sec; 96 | long tv_usec; 97 | long tv_usec; 98 | }; 99 | #endif /* _TIMEVAL_DEFINED */ 100 | 101 | int sd_gettimeofday(LPFILETIME lpft, void* tzp) { 102 | 103 | if (lpft) { 104 | GetSystemTimeAsFileTime(lpft); 105 | } 106 | /* 0 indicates that the call succeeded. */ 107 | return 0; 108 | } 109 | #endif /* _WIN32 */ 110 | 111 | /* 112 | * Placeholder for WIN32 version to get last changetime of a file 113 | */ 114 | #ifdef WIN32 115 | int sd_stat_ctime(const char* path, time_t* time) 116 | { return -1; } 117 | #else 118 | int sd_stat_ctime(const char* path, time_t* time) 119 | { 120 | struct stat astat; 121 | int statret=stat(path,&astat); 122 | if (0 != statret) 123 | { 124 | return statret; 125 | } 126 | *time=astat.st_ctime; 127 | return statret; 128 | } 129 | #endif 130 | 131 | 132 | -------------------------------------------------------------------------------- /src/log4c/appender_type_syslog.c: -------------------------------------------------------------------------------- 1 | static const char version[] = "$Id$"; 2 | 3 | /* 4 | * appender_syslog.c 5 | * 6 | * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved. 7 | * 8 | * See the COPYING file for the terms of usage and distribution. 9 | */ 10 | 11 | #ifdef HAVE_CONFIG_H 12 | #include 13 | #endif 14 | 15 | #include 16 | #include 17 | 18 | #ifdef HAVE_SYSLOG_H 19 | #include 20 | 21 | /*******************************************************************************/ 22 | static int log4c_to_syslog_priority(int a_priority) 23 | { 24 | static int priorities[] = { 25 | LOG_EMERG, 26 | LOG_ALERT, 27 | LOG_CRIT, 28 | LOG_ERR, 29 | LOG_WARNING, 30 | LOG_NOTICE, 31 | LOG_INFO, 32 | LOG_DEBUG 33 | }; 34 | int result; 35 | 36 | a_priority++; 37 | a_priority /= 100; 38 | 39 | if (a_priority < 0) { 40 | result = LOG_EMERG; 41 | } else if (a_priority > 7) { 42 | result = LOG_DEBUG; 43 | } else { 44 | result = priorities[a_priority]; 45 | } 46 | 47 | return result; 48 | } 49 | 50 | /*******************************************************************************/ 51 | static int syslog_open(log4c_appender_t* this) 52 | { 53 | int facility = (int) log4c_appender_get_udata(this); 54 | 55 | if (!facility) 56 | facility = LOG_USER; 57 | 58 | openlog(log4c_appender_get_name(this), LOG_PID, facility); 59 | return 0; 60 | } 61 | 62 | /*******************************************************************************/ 63 | static int syslog_append(log4c_appender_t* this, 64 | const log4c_logging_event_t* a_event) 65 | { 66 | int facility = (int) log4c_appender_get_udata(this); 67 | 68 | if (!facility) 69 | facility = LOG_USER; 70 | 71 | syslog(log4c_to_syslog_priority(a_event->evt_priority) | facility, 72 | a_event->evt_rendered_msg); 73 | return 0; 74 | } 75 | 76 | /*******************************************************************************/ 77 | static int syslog_close(log4c_appender_t* this) 78 | { 79 | closelog(); 80 | return 0; 81 | } 82 | 83 | #else 84 | 85 | /*******************************************************************************/ 86 | static int syslog_open(log4c_appender_t* this) 87 | { 88 | return 0; 89 | } 90 | 91 | /*******************************************************************************/ 92 | static int syslog_append(log4c_appender_t* this, 93 | const log4c_logging_event_t* a_event) 94 | { 95 | return 0; 96 | } 97 | 98 | /*******************************************************************************/ 99 | static int syslog_close(log4c_appender_t* this) 100 | { 101 | return 0; 102 | } 103 | #endif 104 | 105 | extern int log4c_appender_syslog_set_facility(log4c_appender_t* this, int facility) 106 | { 107 | return (int) log4c_appender_set_udata(this, (void*) facility); 108 | } 109 | 110 | /*******************************************************************************/ 111 | const log4c_appender_type_t log4c_appender_type_syslog = { 112 | "syslog", 113 | syslog_open, 114 | syslog_append, 115 | syslog_close, 116 | }; 117 | 118 | -------------------------------------------------------------------------------- /src/log4c/rollingpolicy_type_sizewin.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * rollingpolicy_type_sizewin.h 4 | * 5 | * See the COPYING file for the terms of usage and distribution. 6 | */ 7 | 8 | #ifndef log4c_policy_type_sizewin_h 9 | #define log4c_policy_type_sizewin_h 10 | 11 | /** 12 | * @file rollingpolicy_type_sizewin.h 13 | * 14 | * @brief Log4c rolling file size-win interface. 15 | * Log4c ships with (and defaults to) the classic size-window rollover policy: 16 | * this triggers rollover when files reach a maximum size. The first file in 17 | * the list is 18 | * always the current file; when a rollover event occurs files are shifted up 19 | * by one position in the list--if the number of files in the list has already 20 | * reached the max then the oldest file is rotated out of the window. 21 | * 22 | * If the max file size is set to zero, this means 'no-limit'. 23 | * 24 | * The default parameters for the size-win policy are 5 files of maximum 25 | * size of 20kilobytes each. These parameters may be changed using the 26 | * appropriate setter functions. 27 | */ 28 | 29 | #include 30 | #include 31 | 32 | __LOG4C_BEGIN_DECLS 33 | 34 | LOG4C_API const log4c_rollingpolicy_type_t log4c_rollingpolicy_type_sizewin; 35 | 36 | /** 37 | * log4c size-win rolling policy type 38 | */ 39 | typedef struct __sizewin_udata rollingpolicy_sizewin_udata_t; 40 | 41 | #define ROLLINGPOLICY_SIZE_DEFAULT_MAX_FILE_SIZE 1024*20 42 | #define ROLLINGPOLICY_SIZE_DEFAULT_MAX_NUM_FILES 5 43 | 44 | /** 45 | * Get a new size-win rolling policy 46 | * @return a new size-win rolling policy, otherwise NULL. 47 | */ 48 | LOG4C_API rollingpolicy_sizewin_udata_t *sizewin_make_udata(void); 49 | 50 | /** 51 | * Set the maximum file size in this rolling policy configuration. 52 | * @param swup the size-win configuration object. 53 | * @param max_size the approximate maximum size any logging file will 54 | * attain. 55 | * If you set zero then it means 'no-limit' and so only one file 56 | * of unlimited size will be used for logging. 57 | * @return zero if successful, non-zero otherwise. 58 | */ 59 | LOG4C_API int sizewin_udata_set_file_maxsize( 60 | rollingpolicy_sizewin_udata_t * swup, 61 | long max_size); 62 | 63 | /** 64 | * Set the maximum number of filesin this rolling policy configuration. 65 | * @param swup the size-win configuration object. 66 | * @param max_num the maximum number of files in the list. 67 | * @return zero if successful, non-zero otherwise. 68 | */ 69 | LOG4C_API int sizewin_udata_set_max_num_files( 70 | rollingpolicy_sizewin_udata_t * swup, 71 | long max_num); 72 | 73 | /** 74 | * Set the rolling file appender in this rolling policy configuration. 75 | * @param swup the size-win configuration object. 76 | * @param app the rolling file appender to set. 77 | * @return zero if successful, non-zero otherwise. 78 | */ 79 | LOG4C_API int sizewin_udata_set_appender( 80 | rollingpolicy_sizewin_udata_t * swup, 81 | log4c_appender_t* app); 82 | 83 | __LOG4C_END_DECLS 84 | 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /examples/example_formatters.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Part of the log4c examples. 4 | * 5 | * Along with example_appenders.c this file is used to create a small 6 | * library of custom appenders and formatters. 7 | * 8 | * This library is excercised using application_2 and a sample log4crc 9 | * config file. 10 | * 11 | *****************************************************************************/ 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | /* Defined in example_appenders.c */ 18 | extern int init_example_appenders(void); 19 | 20 | /********************************************************************** 21 | * 22 | * Formatted to put [category] out at the front of the message 23 | * 24 | **********************************************************************/ 25 | static const char* cat_format( 26 | const log4c_layout_t* a_layout, 27 | const log4c_logging_event_t*a_event) 28 | { 29 | static char buffer[4096]; 30 | 31 | /* 32 | * For this formatter we put the category up front in the log message 33 | */ 34 | sprintf(buffer, "[%s][LINE:%d][FILE:%s] %s", a_event->evt_category, 35 | a_event->evt_loc->loc_line, a_event->evt_loc->loc_file, a_event->evt_msg); 36 | 37 | return buffer; 38 | } 39 | 40 | const log4c_layout_type_t log4c_layout_type_cat = { 41 | "s13_cat", 42 | cat_format, 43 | }; 44 | 45 | 46 | static const char* none_format( 47 | const log4c_layout_t* a_layout, 48 | const log4c_logging_event_t*a_event) 49 | { 50 | static char buffer[4096]; 51 | return buffer; 52 | } 53 | 54 | const log4c_layout_type_t log4c_layout_type_none = { 55 | "s13_none", 56 | none_format, 57 | }; 58 | 59 | 60 | /**********************************************************************/ 61 | /* 62 | * Formatted to mock up an xml format. 63 | * 64 | **********************************************************************/ 65 | static const char* xml_format( 66 | const log4c_layout_t* a_layout, 67 | const log4c_logging_event_t*a_event) 68 | { 69 | static char buffer[4096]; 70 | 71 | /* 72 | * For this formatter we put the category up front in the log message 73 | */ 74 | sprintf(buffer, "%s%s", a_event->evt_category, a_event->evt_msg); 75 | 76 | return buffer; 77 | } 78 | 79 | const log4c_layout_type_t log4c_layout_type_xml = { 80 | "s13_xml", 81 | xml_format, 82 | }; 83 | 84 | 85 | 86 | 87 | /*****************************/ 88 | /* 89 | * Here provide an init routine for this lib 90 | * 91 | ******************************/ 92 | static const log4c_layout_type_t * const layout_types[] = { 93 | &log4c_layout_type_xml, 94 | &log4c_layout_type_none, 95 | &log4c_layout_type_cat 96 | }; 97 | static int nlayout_types = 98 | (int)(sizeof(layout_types) / sizeof(layout_types[0])); 99 | 100 | 101 | int init_example_formatters(){ 102 | 103 | int rc = 0; int i = 0; 104 | 105 | for (i = 0; i < nlayout_types; i++) 106 | log4c_layout_type_set(layout_types[i]); 107 | 108 | return(rc); 109 | 110 | } 111 | 112 | 113 | int init_examples_lib() { 114 | 115 | init_example_formatters(); 116 | init_example_appenders(); 117 | 118 | return(0); 119 | } 120 | 121 | 122 | -------------------------------------------------------------------------------- /src/sd/domnode-xml-scanner.l: -------------------------------------------------------------------------------- 1 | %option nodefault 2 | %option 8bit 3 | %option never-interactive 4 | %option prefix="__sd_domnode_xml_" 5 | %option nounput 6 | %option noyywrap 7 | %option reentrant 8 | %option bison-bridge 9 | %option read 10 | %option fast 11 | %option header-file="domnode-xml-scanner.h" 12 | %option outfile="domnode-xml-scanner.c" 13 | 14 | %{ 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include "error.h" 21 | #include "malloc.h" 22 | #include "domnode-xml.h" 23 | 24 | /* Generated by bison(1) */ 25 | #include "domnode-xml-parser.h" 26 | 27 | #ifdef strdup 28 | # undef strdup 29 | #endif 30 | #define strdup sd_strdup 31 | #ifdef malloc 32 | # undef malloc 33 | #endif 34 | #define malloc sd_malloc 35 | #ifdef calloc 36 | # undef calloc 37 | #endif 38 | #define calloc sd_calloc 39 | #ifdef realloc 40 | # undef realloc 41 | #endif 42 | #define realloc sd_realloc 43 | #ifdef yyerror 44 | # undef yyerror 45 | #endif 46 | #define yyerror sd_error 47 | 48 | /******************************************************************************/ 49 | /* Extract a single word */ 50 | static char* word(const char *s) 51 | { 52 | char *buf; 53 | int i, k; 54 | 55 | for (k = 0; isspace(s[k]) || s[k] == '<'; k++); 56 | for (i = k; s[i] && ! isspace(s[i]); i++); 57 | 58 | buf = malloc((i - k + 1) * sizeof(char)); 59 | strncpy(buf, &s[k], i - k); 60 | buf[i - k] = 0; 61 | 62 | return buf; 63 | } 64 | 65 | /******************************************************************************/ 66 | /* Extract text between " " */ 67 | static char* string(const char* s) 68 | { 69 | char* buf; 70 | int i; 71 | 72 | buf = strdup(s + 1); 73 | for (i = 0; buf[i] != '"'; i++); 74 | buf[i] = 0; 75 | 76 | return buf; 77 | } 78 | 79 | /******************************************************************************/ 80 | /* Extract text between */ 81 | static char* comment(const char* s) 82 | { 83 | char* buf; 84 | int i, k; 85 | 86 | for (k = 4; isspace(s[k]); k++); 87 | for (i = k; strncmp(&s[i], "-->", 3); i++); 88 | 89 | buf = malloc((i - k + 1) * sizeof(char)); 90 | strncpy(buf, &s[k], i - k); 91 | buf[i - k] = 0; 92 | 93 | return buf; 94 | } 95 | 96 | %} 97 | 98 | nl (\r\n|\r|\n) 99 | ws [ \t\r\n]+ 100 | open {ws}*"<" 101 | close ">"{ws}* 102 | namestart [A-Za-z\200-\377_] 103 | namechar [A-Za-z\200-\377_0-9.-] 104 | name {namestart}{namechar}* 105 | data ([^<\n&])+ 106 | comment {open}"!--"([^-]|"-"[^-])+"--"{close} 107 | ignored {open}[!?][^-][^>]*{close} 108 | string \"([^"&])*\"|\'([^'&])*\' 109 | 110 | %s CONTENT 111 | 112 | %% 113 | 114 | {ws} {/* skip */} 115 | "/" { return SLASH; } 116 | "=" { return EQ; } 117 | {close} { BEGIN(CONTENT); return CLOSE; } 118 | {name} { yylvalp->s = strdup(yytext); return NAME; } 119 | {string} { yylvalp->s = string(yytext); return VALUE; } 120 | "?"{close} { return ENDDEF; } 121 | 122 | {open}{ws}?{name} { 123 | BEGIN(INITIAL); 124 | yylvalp->s = word(yytext); 125 | return START; 126 | } 127 | {open}{ws}?"/" {BEGIN(INITIAL); return END;} 128 | {comment} {yylvalp->s = comment(yytext); return COMMENT;} 129 | {ignored} {/* skip */} 130 | 131 | {data} {yylvalp->s = strdup(yytext); return DATA;} 132 | 133 | . { yyerror("wrong XML input '%c'", *yytext); } 134 | {nl} {/* skip, must be an extra one at EOF */} 135 | -------------------------------------------------------------------------------- /src/sd/malloc.c: -------------------------------------------------------------------------------- 1 | /* xmalloc.c -- malloc with out of memory checking 2 | Copyright (C) 1990,91,92,93,94,95,96,97 Free Software Foundation, Inc. 3 | This file is part of the GNU C Library. 4 | 5 | The GNU C Library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | The GNU C Library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with the GNU C Library; if not, write to the Free 17 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 18 | 02111-1307 USA. */ 19 | 20 | #ifdef HAVE_CONFIG_H 21 | #include "config.h" 22 | #endif 23 | #include 24 | 25 | #ifdef HAVE_UNISTD_H 26 | #include 27 | #endif 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | #if defined(__APPLE__) 34 | # include 35 | # include 36 | # define environ (*_NSGetEnviron()) 37 | #endif /* __APPLE__ */ 38 | 39 | typedef void (*sd_malloc_handler_t)(); 40 | 41 | static char* first_break = NULL; 42 | static sd_malloc_handler_t handler = NULL; 43 | 44 | static void * 45 | fixup_null_alloc (n) 46 | size_t n; 47 | { 48 | void* p = 0; 49 | 50 | #ifdef HAVE_SBRK 51 | if (n == 0) 52 | p = malloc ((size_t) 1); 53 | 54 | if (p == 0) { 55 | extern char **environ; 56 | size_t allocated; 57 | 58 | if (first_break != NULL) 59 | allocated = (char *) sbrk (0) - first_break; 60 | else 61 | allocated = (char *) sbrk (0) - (char *) &environ; 62 | sd_error("\nCannot allocate %lu bytes after allocating %lu bytes\n", 63 | (unsigned long) n, (unsigned long) allocated); 64 | 65 | if (handler) 66 | handler(); 67 | else { 68 | sd_error("\n\tMemory exhausted !! Aborting.\n"); 69 | abort(); 70 | } 71 | } 72 | #endif 73 | return p; 74 | } 75 | 76 | sd_malloc_handler_t 77 | sd_malloc_set_handler(a_handler) 78 | sd_malloc_handler_t a_handler; 79 | { 80 | sd_malloc_handler_t previous = handler; 81 | 82 | handler = a_handler; 83 | return previous; 84 | } 85 | 86 | /* Allocate N bytes of memory dynamically, with error checking. */ 87 | 88 | void * 89 | sd_malloc (n) 90 | size_t n; 91 | { 92 | void *p; 93 | 94 | p = malloc (n); 95 | if (p == 0) 96 | p = fixup_null_alloc (n); 97 | return p; 98 | } 99 | 100 | /* Allocate memory for N elements of S bytes, with error checking. */ 101 | 102 | void * 103 | sd_calloc (n, s) 104 | size_t n, s; 105 | { 106 | void *p; 107 | 108 | p = calloc (n, s); 109 | if (p == 0) 110 | p = fixup_null_alloc (n * s); 111 | return p; 112 | } 113 | 114 | /* Change the size of an allocated block of memory P to N bytes, 115 | with error checking. 116 | If P is NULL, run sd_malloc. */ 117 | 118 | void * 119 | sd_realloc (p, n) 120 | void *p; 121 | size_t n; 122 | { 123 | if (p == 0) 124 | return sd_malloc (n); 125 | p = realloc (p, n); 126 | if (p == 0) 127 | p = fixup_null_alloc (n); 128 | return p; 129 | } 130 | 131 | /* Return a newly allocated copy of STRING. */ 132 | 133 | char * 134 | sd_strdup (string) 135 | const char *string; 136 | { 137 | return strcpy (sd_malloc (strlen (string) + 1), string); 138 | } 139 | -------------------------------------------------------------------------------- /examples/application_2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This is one of the log4c example programs. 3 | * 4 | * In this example we link against a shared library that has 5 | * additional formatters and appenders. This shows how easy it is to 6 | * add in more appenders and formatters to the log4c framework. 7 | * 8 | * With gcc this file is in fact exactly the same as application_1.c-- 9 | * only at link time it is linked with a new library. 10 | * With other compilers using explicit initialization, this program needs 11 | * to explicitly tell the custom appender/formatter lib to initialize 12 | * itself and it's appenders and formatters. 13 | * 14 | */ 15 | 16 | #ifdef HAVE_CONFIG_H 17 | #include "config.h" 18 | #endif 19 | 20 | #include 21 | #include 22 | #include 23 | #ifndef _WIN32 24 | #include 25 | #else 26 | #include 27 | #include 28 | #include 29 | #endif 30 | #ifdef HAVE_UNISTD_H 31 | #include 32 | #endif 33 | #include "log4c.h" 34 | 35 | extern int init_examples_lib(void); 36 | 37 | #ifdef _WIN32 38 | int gettimeofday(struct timeval* tp, void* tzp) { 39 | DWORD t; 40 | t = timeGetTime(); 41 | tp->tv_sec = t / 1000; 42 | tp->tv_usec = t % 1000; 43 | /* 0 indicates that the call succeeded. */ 44 | return 0; 45 | } 46 | 47 | int sleep(DWORD t){ 48 | 49 | Sleep(1000*t); 50 | return(0); 51 | } 52 | #endif /* _WIN32 */ 53 | 54 | 55 | int main(int argc, char** argv) 56 | { 57 | struct timeval start_time; 58 | struct timeval now_time; 59 | int looptime = 0; 60 | log4c_category_t* mycat = NULL; 61 | 62 | if (argc < 2) 63 | { 64 | printf("usage: %s loop_time_in_seconds\n",argv[0]); 65 | exit (1); 66 | } 67 | if (sscanf(argv[1],"%d",&looptime) != 1) 68 | { 69 | printf("could not convert %s to number of seconds to loop\n",argv[1]); 70 | exit(1); 71 | } 72 | 73 | /* 74 | * Here, if using explicit initialization (as opposed to implicit via the 75 | * init phase of the library) it's important to initialize the custom appenders 76 | * and layouts before calling log4c_init(). 77 | * This is because when log4c_init() parses the config file it looks for the 78 | * types mentioned in the file to set up the relations between categories, 79 | * appenders and layouts. If it does not find a coresponding type in the 80 | * internal hash tables, it creates one with that type name, but the function 81 | * table is not set up--so that at log time nothing happens. 82 | * 83 | */ 84 | 85 | init_examples_lib(); 86 | 87 | log4c_init(); 88 | 89 | /* 90 | * You could choose to wrap the log4c_category_log with some macro 91 | * that then calls an accessor to get your pre-created category 92 | * mycat and then logs to it. But for now we just focus on the fact 93 | * that we are using log4crc to have this application use the new 94 | * formatters and appenders we wrote as examples 95 | */ 96 | mycat = log4c_category_get("six13log.log.app.application2"); 97 | 98 | gettimeofday(&start_time, NULL); 99 | gettimeofday(&now_time, NULL); 100 | 101 | while ( (now_time.tv_sec - start_time.tv_sec) < looptime) 102 | { 103 | log4c_category_log(mycat, LOG4C_PRIORITY_DEBUG, "Debugging app 2"); 104 | log4c_category_log(mycat, LOG4C_PRIORITY_ERROR, 105 | "some error from app2 at line %d in file %s", 106 | __LINE__, __FILE__); 107 | sleep(3); 108 | 109 | gettimeofday(&now_time, NULL); 110 | } 111 | 112 | /* Explicitly call the log4c cleanup routine */ 113 | if ( log4c_fini()){ 114 | printf("log4c_fini() failed"); 115 | } 116 | 117 | return 0; 118 | } 119 | -------------------------------------------------------------------------------- /src/sd/sd_xplatform.h: -------------------------------------------------------------------------------- 1 | /* $Id$ 2 | * 3 | * sd_xplatform.h 4 | * 5 | * See the COPYING file for the terms of usage and distribution. 6 | */ 7 | 8 | #ifndef __sd_xplatform_h 9 | #define __sd_xplatform_h 10 | 11 | #ifndef _WIN32 12 | #include 13 | #include 14 | #include 15 | #else 16 | #include 17 | #include /* needed for _access */ 18 | #include 19 | #include 20 | #include 21 | #endif 22 | 23 | 24 | #ifdef HAVE_STDINT_H 25 | # include 26 | #define XP_UINT64 uint64_t 27 | #define XP_INT64 int64_t 28 | #else 29 | #ifndef _WIN32 30 | #define XP_UINT64 unsigned long long 31 | #define XP_INT64 long long 32 | #else 33 | #define XP_UINT64 DWORD64 34 | #define XP_INT64 __int64 35 | #endif 36 | #endif 37 | 38 | #include 39 | #include 40 | 41 | 42 | /*extern int sd_optind; */ 43 | LOG4C_DATA int sd_optind; 44 | 45 | extern void getopt_reset(void); 46 | 47 | extern int sd_getopt(int argc, char *const *argv, const char *opts); 48 | 49 | #ifdef _WIN32 50 | #define SD_GETOPT(a,b,c) sd_getopt(a,b,c) 51 | #define SD_OPTIND sd_optind 52 | #else 53 | #define SD_GETOPT(a,b,c) getopt(a,b,c) 54 | #define SD_OPTIND optind 55 | #endif 56 | 57 | 58 | #ifdef _WIN32 59 | #define SD_GETTIMEOFDAY(a,b) sd_gettimeofday(a,b) 60 | extern int sd_gettimeofday(LPFILETIME lpft, void* tzp); 61 | #else 62 | #define SD_GETTIMEOFDAY(a,b) gettimeofday(a,b) 63 | extern int sd_gettimeofday(struct timeval* tp, void* tzp); 64 | #endif 65 | 66 | #ifdef _WIN32 67 | #define FILE_SEP "\\" 68 | #else 69 | #define FILE_SEP "/" 70 | #endif 71 | 72 | #ifdef _WIN32 73 | #define SD_ACCESS_READ(a) _access(a,04) 74 | #else 75 | #define SD_ACCESS_READ(a) access(a,R_OK) 76 | #endif 77 | 78 | int sd_stat_ctime(const char* path, time_t* time); 79 | #define SD_STAT_CTIME(path, time) sd_stat_ctime(path, time) 80 | 81 | #ifndef _WIN32 82 | #define DIFF_CMD "/usr/bin/diff -q" 83 | #else 84 | #define DIFF_CMD "comp.exe" 85 | #endif 86 | 87 | #ifdef _WIN32 88 | #define snprintf _snprintf 89 | #define vsnprintf _vsnprintf 90 | #define alloca _alloca 91 | #define strncasecmp strnicmp 92 | #define strcasecmp stricmp 93 | #define YY_NO_UNISTD_H 94 | #define sleep(x) Sleep(x*1000) 95 | #endif 96 | 97 | 98 | /* Maybe should be using this for to mean 99 | * MS compiler #if defined(_MSC_VER) 100 | */ 101 | #ifdef _WIN32 102 | #define pthread_t HANDLE 103 | #define pthread_mutex_t HANDLE 104 | #define pthread_attr_t DWORD 105 | #define THREAD_FUNCTION DWORD (WINAPI *)(void *) 106 | 107 | /* 108 | * This one not obvious: you would have naturally thought of mapping to 109 | * CreateThread()--turns out that to be safe using CRT functions 110 | * you need to use _begintheadex(). 111 | * cf. http://msdn2.microsoft.com/en-us/library/7t9ha0zh.aspx 112 | * http://groups.google.com/group/comp.os.ms-windows.programmer.win32/browse_thread/thread/86d8624e7ee38c5d/f947ac76cd10f397?lnk=st&q=when+to+use+_beginthreadex&rnum=1#f947ac76cd10f397 113 | * 114 | */ 115 | #define pthread_create(thhandle,attr,thfunc,tharg) \ 116 | (int)((*thhandle=(HANDLE)_beginthreadex(NULL,0,(THREAD_FUNCTION)thfunc,tharg,0,NULL))==NULL) 117 | #define pthread_join(thread, result) \ 118 | ((WaitForSingleObject((thread),INFINITE)!=WAIT_OBJECT_0) || !CloseHandle(thread)) 119 | #define pthread_exit() _endthreadex(0) 120 | #define pthread_cancel(thread) TerminateThread(thread,0) 121 | 122 | #define pthread_mutex_init(pobject,pattr) (*pobject=CreateMutex(NULL,FALSE,NULL)) 123 | #define pthread_mutex_lock(pobject) WaitForSingleObject(*pobject,INFINITE) 124 | #define pthread_mutex_unlock(pobject) ReleaseMutex(*pobject) 125 | 126 | #define pthread_mutex_destroy(pobject) CloseHandle(*pobject) 127 | 128 | #endif 129 | 130 | 131 | #ifdef __HP_cc 132 | #define inline __inline 133 | #endif 134 | 135 | #endif 136 | -------------------------------------------------------------------------------- /tests/log4c/test_category.ref: -------------------------------------------------------------------------------- 1 | => test #0 : 2 | factory[log4c_category_factory]: 3 | { name:'root' priority:NOTICE additive:1 appender:'(nil)' parent:'(nil)' } 4 | { name:'sub1' priority:NOTSET additive:1 appender:'(nil)' parent:'root' } 5 | { name:'sub1.sub2' priority:NOTSET additive:1 appender:'(nil)' parent:'sub1' } 6 | 7 | factory[log4c_appender_factory]: 8 | { name:'syslog' type:'syslog' layout:'basic' isopen:0 udata:(nil)} 9 | { name:'stderr' type:'stream' layout:'dated' isopen:0 udata:0x42127480} 10 | { name:'stdout' type:'stream' layout:'basic' isopen:0 udata:0x42127320} 11 | 12 | factory[log4c_layout_factory]: 13 | { name:'basic' type:'basic' udata:(nil) } 14 | { name:'dated' type:'dated' udata:(nil) } 15 | 16 | => test #0 : passed 17 | => test #1 : 18 | => test #1 : passed 19 | => test #2 : 20 | factory[log4c_category_factory]: 21 | { name:'root' priority:ERROR additive:1 appender:'test_category' parent:'(nil)' } 22 | { name:'a category' priority:NOTSET additive:1 appender:'(nil)' parent:'root' } 23 | { name:'sub1' priority:NOTSET additive:1 appender:'appender1' parent:'root' } 24 | { name:'sub1.sub2' priority:NOTSET additive:1 appender:'appender2' parent:'sub1' } 25 | 26 | factory[log4c_appender_factory]: 27 | { name:'syslog' type:'syslog' layout:'basic' isopen:0 udata:(nil)} 28 | { name:'stderr' type:'stream' layout:'dated' isopen:0 udata:0x42127480} 29 | { name:'stdout' type:'stream' layout:'basic' isopen:0 udata:0x42127320} 30 | { name:'appender1' type:'test' layout:'layout1' isopen:0 udata:0x804dd08} 31 | { name:'test_category' type:'stream' layout:'basic' isopen:0 udata:0x804dd08} 32 | { name:'appender2' type:'test' layout:'layout2' isopen:0 udata:0x804dd08} 33 | 34 | factory[log4c_layout_factory]: 35 | { name:'layout1' type:'test' udata:(nil) } 36 | { name:'layout2' type:'test' udata:(nil) } 37 | { name:'basic' type:'basic' udata:(nil) } 38 | { name:'dated' type:'dated' udata:(nil) } 39 | 40 | => test #2 : passed 41 | => test #3 : 42 | 43 | # root error (priority = ERROR) 44 | [test_category] ERROR root - root error 45 | 46 | # root warn (priority = ERROR) 47 | 48 | # sub1 error (priority = NOTSET) 49 | [appender1] logging 10 bytes. 50 | [test_category] ERROR sub1 - sub1 error 51 | 52 | # sub1 warn (priority = NOTSET) 53 | 54 | # sun1sub2 error (priority = NOTSET) 55 | [appender2] logging 14 bytes. 56 | [appender1] logging 14 bytes. 57 | [test_category] ERROR sub1.sub2 - sun1sub2 error 58 | 59 | # sun1sub2 warn (priority = NOTSET) 60 | => test #3 : passed 61 | => test #4 : 62 | 63 | # root error (priority = ERROR) 64 | [test_category] ERROR root - root error 65 | 66 | # root warn (priority = ERROR) 67 | 68 | # sub1 error (priority = INFO) 69 | [appender1] logging 10 bytes. 70 | [test_category] ERROR sub1 - sub1 error 71 | 72 | # sub1 warn (priority = INFO) 73 | [appender1] logging 9 bytes. 74 | [test_category] WARN sub1 - sub1 warn 75 | 76 | # sun1sub2 error (priority = NOTSET) 77 | [appender2] logging 14 bytes. 78 | [appender1] logging 14 bytes. 79 | [test_category] ERROR sub1.sub2 - sun1sub2 error 80 | 81 | # sun1sub2 warn (priority = NOTSET) 82 | [appender2] logging 13 bytes. 83 | [appender1] logging 13 bytes. 84 | [test_category] WARN sub1.sub2 - sun1sub2 warn 85 | => test #4 : passed 86 | => test #5 : 87 | 88 | # root trace (priority = TRACE) 89 | [test_category] TRACE root - test4() at /home/legoater/cimai/lab/src/log4c/tests/log4c/test_category.c:126 90 | root trace 91 | 92 | # root warn (priority = TRACE) 93 | [test_category] WARN root - root warn 94 | 95 | # sub1 trace (priority = INFO) 96 | 97 | # sub1 warn (priority = INFO) 98 | [appender1] logging 9 bytes. 99 | [test_category] WARN sub1 - sub1 warn 100 | 101 | # sun1sub2 trace (priority = NOTSET) 102 | 103 | # sun1sub2 warn (priority = NOTSET) 104 | [appender2] logging 13 bytes. 105 | [appender1] logging 13 bytes. 106 | [test_category] WARN sub1.sub2 - sun1sub2 warn 107 | => test #5 : passed 108 | -------------------------------------------------------------------------------- /tests/log4c/test_layout_r.c: -------------------------------------------------------------------------------- 1 | static const char version[] = "$Id$"; 2 | 3 | /* 4 | * test_layout.c 5 | * 6 | * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved. 7 | * 8 | * See the COPYING file for the terms of usage and distribution. 9 | * 10 | * 11 | * Note: there's a known issue with this program double closing the 12 | * test file pointer. This is because the test shares the file with 13 | * the log4c stream appender and they both close it on exiting. In 14 | * the context here this error is benign. The stream2 appender 15 | * does not have this issue as it will not close a passed-in 16 | * file pointer on exit. In general you would not share a file pointer like 17 | * this with an appender so that behaviour of the stream appender is not a 18 | * serious issue. 19 | * 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | static log4c_category_t* root = NULL; 33 | static log4c_category_t* sub1 = NULL; 34 | 35 | /******************************************************************************/ 36 | static void log4c_print(FILE* a_fp) 37 | { 38 | extern sd_factory_t* log4c_category_factory; 39 | extern sd_factory_t* log4c_appender_factory; 40 | extern sd_factory_t* log4c_layout_factory; 41 | 42 | sd_factory_print(log4c_category_factory, a_fp); fprintf(a_fp, "\n"); 43 | sd_factory_print(log4c_appender_factory, a_fp); fprintf(a_fp, "\n"); 44 | sd_factory_print(log4c_layout_factory, a_fp); fprintf(a_fp, "\n"); 45 | } 46 | /******************************************************************************/ 47 | static int test0(sd_test_t* a_test, int argc, char* argv[]) 48 | { 49 | log4c_layout_t* layout1 = log4c_layout_get("layout1"); 50 | log4c_appender_t* appender1 = log4c_appender_get("appender1"); 51 | 52 | log4c_layout_set_type(layout1, &log4c_layout_type_basic_r); 53 | 54 | log4c_appender_set_layout(appender1, layout1); 55 | log4c_appender_set_udata(appender1, sd_test_out(a_test)); 56 | 57 | log4c_category_set_appender(sub1, appender1); 58 | log4c_category_set_priority(sub1, LOG4C_PRIORITY_ERROR); 59 | 60 | log4c_print(sd_test_out(a_test)); 61 | return 1; 62 | } 63 | /******************************************************************************/ 64 | static int test1(sd_test_t* a_test, int argc, char* argv[]) 65 | { 66 | log4c_category_error(sub1, "let's log"); 67 | return 1; 68 | } 69 | /******************************************************************************/ 70 | static int test2(sd_test_t* a_test, int argc, char* argv[]) 71 | { 72 | log4c_rc->config.bufsize = 32; 73 | log4c_category_error(sub1, "let's log a very long log that whill surely get trimmed because it is way to long"); 74 | return 1; 75 | } 76 | 77 | /******************************************************************************/ 78 | int main(int argc, char* argv[]) 79 | { 80 | int ret; 81 | sd_test_t* t = sd_test_new(argc, argv); 82 | 83 | /* If we're not using GNU C then initialize our test categories 84 | explicitly 85 | */ 86 | 87 | root = log4c_category_get("root"); 88 | sub1 = log4c_category_get("sub1"); 89 | 90 | log4c_init(); 91 | 92 | fprintf(stderr, 93 | "\nNote: there's a known issue with this program double closing \n" \ 94 | "the test file pointer. This is because the test shares the \n" \ 95 | "file with the log4c stream appender and they both close it on \n" \ 96 | "exiting. In the context here this error is benign. \n" \ 97 | "The stream2 appender does not have this issue as it will not \n" \ 98 | "close a passed-in file pointer on exit.\n\n"); 99 | 100 | sd_test_add(t, test0); 101 | sd_test_add(t, test1); 102 | sd_test_add(t, test2); 103 | 104 | ret = sd_test_run(t, argc, argv); 105 | 106 | sd_test_delete(t); 107 | 108 | log4c_fini(); 109 | 110 | return ! ret; 111 | } 112 | -------------------------------------------------------------------------------- /examples/application_3.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This is one of the log4c example programs. 3 | * 4 | * In this example we link against a shared library that has 5 | * additional formatters and appenders where the formatter is 6 | * augmented to expect the extra user location info that we are sending 7 | * in the void* argument the location_info struct 8 | * 9 | */ 10 | 11 | #ifdef HAVE_CONFIG_H 12 | #include "config.h" 13 | #endif 14 | 15 | #include 16 | #include 17 | #include 18 | #ifndef _WIN32 19 | #include 20 | #else 21 | #include 22 | #include 23 | #include 24 | #endif 25 | #ifdef HAVE_UNISTD_H 26 | #include 27 | #endif 28 | #include "log4c.h" 29 | #include "application_3.h" 30 | 31 | extern int init_examples_lib(void); 32 | extern int init_userloc_formatters(void); 33 | 34 | #ifdef _WIN32 35 | int gettimeofday(struct timeval* tp, void* tzp) { 36 | DWORD t; 37 | t = timeGetTime(); 38 | tp->tv_sec = t / 1000; 39 | tp->tv_usec = t % 1000; 40 | /* 0 indicates that the call succeeded. */ 41 | return 0; 42 | } 43 | 44 | int sleep(DWORD t){ 45 | 46 | Sleep(1000*t); 47 | return(0); 48 | } 49 | #endif /* _WIN32 */ 50 | 51 | 52 | int main(int argc, char** argv) 53 | { 54 | struct timeval start_time; 55 | struct timeval now_time; 56 | user_locinfo_t userloc; 57 | int looptime = 0; 58 | log4c_category_t* mycat = NULL; 59 | 60 | /* setup for the extra user location info */ 61 | char hostname[256]; 62 | int pid = getpid(); 63 | gethostname(hostname,255); 64 | hostname[255] = '\0'; 65 | userloc.hostname = hostname; 66 | userloc.pid = pid; 67 | 68 | if (argc < 2) 69 | { 70 | printf("usage: %s loop_time_in_seconds\n",argv[0]); 71 | exit (1); 72 | } 73 | if (sscanf(argv[1],"%d",&looptime) != 1) 74 | { 75 | printf("could not convert %s to number of seconds to loop\n",argv[1]); 76 | exit(1); 77 | } 78 | 79 | /* 80 | * Here, if using explicit initialization (as opposed to implicit via the 81 | * init phase of the library) it's important to initialize the custom appenders 82 | * and layouts before calling log4c_init(). 83 | * This is because when log4c_init() parses the config file it looks for the 84 | * types mentioned in the file to set up the relations between categories, 85 | * appenders and layouts. If it does not find a coresponding type in the 86 | * internal hash tables, it creates one with that type name, but the function 87 | * table is not set up--so that at log time nothing happens. 88 | * 89 | */ 90 | 91 | init_examples_lib(); 92 | init_userloc_formatters(); 93 | 94 | log4c_init(); 95 | 96 | /* 97 | * Here we add our own userdefined location info, and then pick that up in our formatter 98 | */ 99 | mycat = log4c_category_get("six13log.log.app.application3"); 100 | 101 | gettimeofday(&start_time, NULL); 102 | gettimeofday(&now_time, NULL); 103 | 104 | while ( (now_time.tv_sec - start_time.tv_sec) < looptime) 105 | { 106 | /* LINE and FILE are bad */ 107 | log4c_category_log(mycat, LOG4C_PRIORITY_DEBUG, "Debugging app 3, direct log call"); 108 | 109 | /* using the new API directly */ 110 | const log4c_location_info_t locinfo2 = LOG4C_LOCATION_INFO_INITIALIZER(&userloc); 111 | log4c_category_log_locinfo(mycat, &locinfo2, 112 | LOG4C_PRIORITY_DEBUG, "Debugging application number THREE with extra user location"); 113 | const log4c_location_info_t locinfo3 = LOG4C_LOCATION_INFO_INITIALIZER(NULL); 114 | log4c_category_log_locinfo(mycat, &locinfo3, 115 | LOG4C_PRIORITY_ERROR, 116 | "some error from app at line %d in file %s with NULL for extra user location info", 117 | __LINE__, __FILE__); 118 | 119 | /* using the new API with the define wrapper */ 120 | log4c_category_log_userinfo(mycat, &userloc, LOG4C_PRIORITY_DEBUG, "Debug app3 wrapper define"); 121 | 122 | sleep(3); 123 | 124 | gettimeofday(&now_time, NULL); 125 | } 126 | 127 | /* Explicitly call the log4c cleanup routine */ 128 | if ( log4c_fini()){ 129 | printf("log4c_fini() failed"); 130 | } 131 | 132 | return 0; 133 | } 134 | -------------------------------------------------------------------------------- /src/log4c/appender_type_mmap.c: -------------------------------------------------------------------------------- 1 | static const char version[] = "$Id$"; 2 | 3 | /* 4 | * appender_mmap.c 5 | * 6 | * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved. 7 | * 8 | * See the COPYING file for the terms of usage and distribution. 9 | */ 10 | 11 | #ifdef HAVE_CONFIG_H 12 | #include "config.h" 13 | #endif 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #ifdef HAVE_UNISTD_H 24 | #include 25 | #endif 26 | 27 | /* This could be public */ 28 | struct mmap_info { 29 | const char* name; 30 | int fd; 31 | size_t length; 32 | void* addr; 33 | void* ptr; 34 | struct stat st; 35 | }; 36 | 37 | static int mmap_info_delete(struct mmap_info* a_minfo); 38 | static struct mmap_info* mmap_info_new(const char* a_name); 39 | 40 | /*******************************************************************************/ 41 | static struct mmap_info* mmap_info_new(const char* a_name) 42 | { 43 | struct mmap_info* minfo = NULL; 44 | 45 | minfo = sd_calloc(1, sizeof(*minfo)); 46 | minfo->name = a_name; 47 | 48 | if ( (minfo->fd = open(minfo->name, O_RDWR, 0644)) == -1) { 49 | perror("open"); 50 | mmap_info_delete(minfo); 51 | return NULL; 52 | } 53 | 54 | if (fstat(minfo->fd, &minfo->st) == -1) { 55 | perror("fstat"); 56 | mmap_info_delete(minfo); 57 | return NULL; 58 | } 59 | 60 | minfo->length = minfo->st.st_size; 61 | 62 | if (!minfo->length) { 63 | fprintf(stderr, "file %s is empty", minfo->name); 64 | mmap_info_delete(minfo); 65 | return NULL; 66 | } 67 | 68 | return minfo; 69 | } 70 | /*******************************************************************************/ 71 | static int mmap_info_delete(struct mmap_info* a_minfo) 72 | { 73 | if (!a_minfo) 74 | return -1; 75 | 76 | close(a_minfo->fd); 77 | free(a_minfo); 78 | return 0; 79 | } 80 | 81 | /*******************************************************************************/ 82 | static int mmap_open(log4c_appender_t* this) 83 | { 84 | struct mmap_info* minfo = log4c_appender_get_udata(this); 85 | 86 | if (minfo) 87 | return 0; 88 | 89 | if ( (minfo = mmap_info_new(log4c_appender_get_name(this))) == NULL) 90 | return -1; 91 | 92 | minfo->addr = mmap(NULL, minfo->length, PROT_READ|PROT_WRITE, 93 | MAP_SHARED, minfo->fd, 0); 94 | if (minfo->addr == NULL) { 95 | perror("mmap"); 96 | mmap_info_delete(minfo); 97 | return -1; 98 | } 99 | 100 | minfo->ptr = minfo->addr; 101 | log4c_appender_set_udata(this, minfo); 102 | return 0; 103 | } 104 | 105 | /*******************************************************************************/ 106 | static int mmap_append(log4c_appender_t* this, 107 | const log4c_logging_event_t* a_event) 108 | { 109 | size_t size, available; 110 | struct mmap_info* minfo = log4c_appender_get_udata(this); 111 | 112 | if (!minfo && !minfo->ptr) 113 | return 0; 114 | 115 | size = strlen(a_event->evt_rendered_msg); 116 | available = ((char *)minfo->addr + minfo->length) - (char *)minfo->ptr; 117 | 118 | if (size > available) { 119 | memcpy(minfo->ptr, a_event->evt_rendered_msg, available); 120 | minfo->ptr = minfo->addr; 121 | size -= available; 122 | } 123 | 124 | memcpy(minfo->ptr, a_event->evt_rendered_msg, size); 125 | minfo->ptr = (char *)minfo->ptr + size; 126 | return 0; 127 | } 128 | 129 | /*******************************************************************************/ 130 | static int mmap_close(log4c_appender_t* this) 131 | { 132 | struct mmap_info* minfo = log4c_appender_get_udata(this); 133 | 134 | if (!minfo) 135 | return 0; 136 | 137 | if (munmap(minfo->addr, minfo->length) == -1) 138 | perror("munmap"); 139 | 140 | mmap_info_delete(minfo); 141 | 142 | log4c_appender_set_udata(this, NULL); 143 | return 0; 144 | } 145 | 146 | /*******************************************************************************/ 147 | const log4c_appender_type_t log4c_appender_type_mmap = { 148 | "mmap", 149 | mmap_open, 150 | mmap_append, 151 | mmap_close, 152 | }; 153 | 154 | -------------------------------------------------------------------------------- /src/sd/factory.c: -------------------------------------------------------------------------------- 1 | static const char version[] = "$Id$"; 2 | 3 | /* 4 | * factory.c 5 | * 6 | * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved. 7 | * See the COPYING file for the terms of usage and distribution. 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | struct __sd_factory 18 | { 19 | char* fac_name; 20 | const sd_factory_ops_t* fac_ops; 21 | sd_hash_t* fac_hash; 22 | }; 23 | 24 | /* xxx FIXME: unsafe hand made polymorphism ... 25 | * This is used to access the name field of objects created by 26 | * factories. For example instances of appenders, layouts or 27 | * rollingpolicies. 28 | * So there's a supposition that the name field is always first--this is true 29 | * but should enforce that probably by extending a base 'name' struct. 30 | */ 31 | typedef struct { 32 | char* pr_name; 33 | } sd_factory_product_t; 34 | 35 | /*******************************************************************************/ 36 | extern sd_factory_t* sd_factory_new(const char* a_name, 37 | const sd_factory_ops_t* a_ops) 38 | { 39 | sd_factory_t* this; 40 | 41 | if (!a_name || !a_ops) 42 | return NULL; 43 | 44 | this = sd_calloc(1, sizeof(*this)); 45 | this->fac_name = sd_strdup(a_name); 46 | this->fac_ops = a_ops; 47 | this->fac_hash = sd_hash_new(20, NULL); 48 | return this; 49 | } 50 | 51 | /*******************************************************************************/ 52 | extern void sd_factory_delete(sd_factory_t* this) 53 | { 54 | sd_hash_iter_t* i; 55 | 56 | sd_debug("sd_factory_delete['%s',", 57 | (this && (this->fac_name) ? this->fac_name: "(no name)")); 58 | 59 | if (!this){ 60 | goto sd_factory_delete_exit; 61 | } 62 | 63 | if (this->fac_ops->fac_delete){ 64 | for (i = sd_hash_begin(this->fac_hash); i != sd_hash_end(this->fac_hash); 65 | i = sd_hash_iter_next(i)) { 66 | this->fac_ops->fac_delete(i->data); 67 | } 68 | } 69 | 70 | sd_hash_delete(this->fac_hash); 71 | free(this->fac_name); 72 | free(this); 73 | 74 | sd_factory_delete_exit: 75 | sd_debug("]"); 76 | } 77 | 78 | /*******************************************************************************/ 79 | extern void* sd_factory_get(sd_factory_t* this, const char* a_name) 80 | { 81 | sd_hash_iter_t* i; 82 | sd_factory_product_t* pr; 83 | 84 | if ( (i = sd_hash_lookup(this->fac_hash, a_name)) != NULL) 85 | return i->data; 86 | 87 | if (!this->fac_ops->fac_new) 88 | return NULL; 89 | 90 | if ( (pr = this->fac_ops->fac_new(a_name)) == NULL) 91 | return NULL; 92 | 93 | sd_hash_add(this->fac_hash, pr->pr_name, pr); 94 | return pr; 95 | 96 | } 97 | 98 | /*******************************************************************************/ 99 | extern void sd_factory_destroy(sd_factory_t* this, void* a_pr) 100 | { 101 | sd_factory_product_t* pr = (sd_factory_product_t*) a_pr; 102 | 103 | sd_hash_del(this->fac_hash, pr->pr_name); 104 | if (this->fac_ops->fac_delete) 105 | this->fac_ops->fac_delete(pr); 106 | } 107 | 108 | /*******************************************************************************/ 109 | extern void sd_factory_print(const sd_factory_t* this, FILE* a_stream) 110 | { 111 | sd_hash_iter_t* i; 112 | 113 | if (!this) 114 | return; 115 | 116 | if (!this->fac_ops->fac_print) 117 | return; 118 | 119 | fprintf(a_stream, "factory[%s]:\n", this->fac_name); 120 | for (i = sd_hash_begin(this->fac_hash); i != sd_hash_end(this->fac_hash); 121 | i = sd_hash_iter_next(i)) 122 | { 123 | this->fac_ops->fac_print(i->data, a_stream); 124 | fprintf(a_stream, "\n"); 125 | } 126 | } 127 | 128 | /******************************************************************************/ 129 | extern int sd_factory_list(const sd_factory_t* this, void** a_items, 130 | int a_nitems) 131 | { 132 | sd_hash_iter_t* i; 133 | int j; 134 | 135 | if (!this || !a_items || a_nitems <= 0) 136 | return -1; 137 | 138 | for (i = sd_hash_begin(this->fac_hash), j = 0; 139 | i != sd_hash_end(this->fac_hash); 140 | i = sd_hash_iter_next(i), j++) 141 | { 142 | if (j < a_nitems) 143 | a_items[j] = i->data; 144 | } 145 | 146 | return j; 147 | } 148 | -------------------------------------------------------------------------------- /src/sd/domnode-xml.c: -------------------------------------------------------------------------------- 1 | static const char version[] = "$Id$"; 2 | 3 | /* 4 | * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved. 5 | * 6 | * See the COPYING file for the terms of usage and distribution. 7 | */ 8 | 9 | #include 10 | 11 | #ifdef HAVE_LANGINFO_H 12 | # include 13 | #endif 14 | 15 | #include "domnode-xml.h" 16 | 17 | /* Generated by bison(1) */ 18 | #include "domnode-xml-parser.h" 19 | 20 | /* Generated by flex(1) */ 21 | #define YY_HEADER_NO_UNDEFS 1 22 | #include "domnode-xml-scanner.h" 23 | 24 | extern int __sd_domnode_xml_parse(struct __sd_domnode_xml_maker*); 25 | 26 | /******************************************************************************/ 27 | static int xml_fwrite(const sd_domnode_t* this, FILE* a_stream, int a_indent) 28 | { 29 | sd_list_iter_t* iter; 30 | int i; 31 | 32 | if (!this || !this->name || !a_stream) 33 | return -1; 34 | 35 | for (i = 0; i < a_indent; i++) 36 | fprintf(a_stream, " "); 37 | 38 | if (this->name && strcmp(this->name, "#comment") == 0) { 39 | fprintf(a_stream, "\n", this->value); 40 | return 0; 41 | } 42 | 43 | fprintf(a_stream, "<%s", this->name); 44 | 45 | for (iter = sd_list_begin(this->attrs); iter != sd_list_end(this->attrs); 46 | iter = sd_list_iter_next(iter)) { 47 | sd_domnode_t* node = iter->data; 48 | 49 | fprintf(a_stream, " %s=\"%s\"", node->name, node->value); 50 | } 51 | 52 | if (this->value || sd_list_get_nelem(this->children)) { 53 | fprintf(a_stream, ">\n"); 54 | 55 | if (this->value) { 56 | for (i = 0; i < a_indent + 1; i++) 57 | fprintf(a_stream, " "); 58 | fprintf(a_stream, "%s\n", this->value); 59 | } 60 | 61 | for (iter = sd_list_begin(this->children); 62 | iter != sd_list_end(this->children); 63 | iter = sd_list_iter_next(iter)) { 64 | sd_domnode_t* node = iter->data; 65 | 66 | if (xml_fwrite(node, a_stream, a_indent + 1) == -1) 67 | return -1; 68 | } 69 | 70 | for (i = 0; i < a_indent; i++) 71 | fprintf(a_stream, " "); 72 | fprintf(a_stream, "\n", this->name); 73 | } else { 74 | fprintf(a_stream, "/>\n"); 75 | } 76 | 77 | return 0; 78 | } 79 | 80 | /******************************************************************************/ 81 | extern int __sd_domnode_xml_write(const sd_domnode_t* this, char** a_buffer, 82 | size_t* a_size) 83 | { 84 | /* TODO: to be implemented */ 85 | return -1; 86 | } 87 | 88 | /******************************************************************************/ 89 | extern int __sd_domnode_xml_fwrite(const sd_domnode_t* this, FILE* a_stream) 90 | { 91 | #ifdef HAVE_NL_LANGINFO 92 | fprintf(a_stream, "\n\n", 93 | nl_langinfo(CODESET)); 94 | #else 95 | fprintf(a_stream, "\n\n"); 96 | #endif 97 | 98 | return xml_fwrite(this, a_stream, 0); 99 | } 100 | 101 | /******************************************************************************/ 102 | static int xml_parse(sd_domnode_t** a_node, yyscan_t a_scanner) 103 | { 104 | int r; 105 | struct __sd_domnode_xml_maker maker; 106 | 107 | maker.scanner = a_scanner; 108 | maker.elements = sd_stack_new(0); 109 | maker.root = 0; 110 | 111 | if (! (r = __sd_domnode_xml_parse(&maker))) *a_node = maker.root; 112 | 113 | sd_stack_delete(maker.elements, 0); 114 | 115 | return r; 116 | } 117 | 118 | /******************************************************************************/ 119 | extern int __sd_domnode_xml_fread(sd_domnode_t** a_node, FILE* a_stream) 120 | { 121 | int r; 122 | yyscan_t scanner; 123 | 124 | yylex_init(&scanner); 125 | yyset_in(a_stream, scanner); 126 | 127 | r = xml_parse(a_node, scanner); 128 | 129 | yylex_destroy(scanner); 130 | 131 | return r; 132 | } 133 | 134 | /******************************************************************************/ 135 | extern int __sd_domnode_xml_read(sd_domnode_t** a_node, const char* a_buffer, 136 | size_t a_size) 137 | { 138 | int r; 139 | yyscan_t scanner; 140 | 141 | yylex_init(&scanner); 142 | yy_switch_to_buffer(yy_scan_bytes(a_buffer, a_size, scanner), scanner); 143 | 144 | r = xml_parse(a_node, scanner); 145 | 146 | yylex_destroy(scanner); 147 | 148 | return r; 149 | } 150 | -------------------------------------------------------------------------------- /src/sd/domnode-xml-parser.y: -------------------------------------------------------------------------------- 1 | %{ 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "error.h" 7 | #include "malloc.h" 8 | #include "domnode-xml.h" 9 | 10 | /* Generated by bison(1) */ 11 | #include "domnode-xml-parser.h" 12 | 13 | /* Generated by flex(1) */ 14 | #define YY_HEADER_NO_UNDEFS 1 15 | #include "domnode-xml-scanner.h" 16 | 17 | #define YYPARSE_PARAM __a_maker 18 | #define a_maker ((struct __sd_domnode_xml_maker*) YYPARSE_PARAM) 19 | #define YYLEX_PARAM (a_maker->scanner) 20 | 21 | #ifdef strdup 22 | # undef strdup 23 | #endif 24 | #define strdup sd_strdup 25 | #ifdef malloc 26 | # undef malloc 27 | #endif 28 | #define malloc sd_malloc 29 | #ifdef calloc 30 | # undef calloc 31 | #endif 32 | #define calloc sd_calloc 33 | #ifdef realloc 34 | # undef realloc 35 | #endif 36 | #define realloc sd_realloc 37 | #ifdef yyerror 38 | # undef yyerror 39 | #endif 40 | #define yyerror sd_error 41 | 42 | static void domnode_attribute(struct __sd_domnode_xml_maker*, const char*, 43 | const char*); 44 | %} 45 | 46 | %name-prefix="__sd_domnode_xml_" 47 | %pure_parser 48 | %debug 49 | %defines 50 | %output="domnode-xml-parser.c" 51 | 52 | %union { char *s; } 53 | 54 | %token ENDDEF EQ SLASH CLOSE END 55 | %token NAME VALUE DATA COMMENT START 56 | %type name 57 | 58 | %% 59 | 60 | document 61 | : misc element misc 62 | ; 63 | 64 | misc 65 | : misc comment 66 | | /* empty */ 67 | ; 68 | 69 | comment 70 | : COMMENT 71 | { 72 | sd_domnode_t* node = sd_stack_peek(a_maker->elements); 73 | 74 | if (node) { 75 | sd_debug("COMMENT: add comment '%s' to node '%s'\n", $1, node->name); 76 | sd_list_append(node->children, __sd_domnode_new("#comment", $1, 0)); 77 | /* $1 was obtain with strdup() */ 78 | free($1); 79 | } 80 | } 81 | ; 82 | 83 | element 84 | : START 85 | { 86 | sd_domnode_t* parent = sd_stack_peek(a_maker->elements); 87 | sd_domnode_t* node = __sd_domnode_new($1, 0, 1); 88 | 89 | #ifdef __SD_DEBUG__ 90 | { 91 | static void* __debug = 0; 92 | if (! __debug) { 93 | __debug = getenv("SD_DEBUG"); 94 | if (__debug) 95 | yydebug = 1; 96 | else 97 | __debug = (void*) 0x1; 98 | } 99 | } 100 | #endif 101 | 102 | if (parent) { 103 | sd_debug("START: add child '%s' to node '%s'\n", $1, parent->name); 104 | sd_list_append(parent->children, node); 105 | } else { 106 | sd_debug("START: add root'%s'\n", $1); 107 | a_maker->root = node; 108 | } 109 | 110 | sd_stack_push(a_maker->elements, node); 111 | free($1); 112 | } 113 | attribute_seq_opt 114 | empty_or_content 115 | ; 116 | 117 | empty_or_content 118 | : SLASH CLOSE 119 | { 120 | sd_domnode_t* node = sd_stack_peek(a_maker->elements); 121 | assert(node != 0); 122 | 123 | sd_debug("END: simple node '%s'\n", node->name); 124 | sd_stack_pop(a_maker->elements); 125 | } 126 | | CLOSE content END name CLOSE 127 | { 128 | sd_domnode_t* node = sd_stack_peek(a_maker->elements); 129 | assert(node != 0); 130 | 131 | sd_debug("END: node '%s'\n", $4); 132 | 133 | if (strcmp(node->name, $4)) { 134 | yyerror("got instead of \n", $4, node->name); 135 | YYERROR; 136 | } 137 | 138 | /* $4 was obtain with strdup() */ 139 | free($4); 140 | 141 | sd_stack_pop(a_maker->elements); 142 | } 143 | ; 144 | 145 | content 146 | : content DATA 147 | { 148 | sd_domnode_t* node = sd_stack_peek(a_maker->elements); 149 | assert(node != 0); 150 | 151 | sd_debug("CONTENT: add cvalue '%s' to node '%s'\n", $2, node->name); 152 | 153 | /* $2 was obtain with strdup() */ 154 | node->value = $2; 155 | } 156 | | content element 157 | | content comment 158 | | /*empty*/ 159 | ; 160 | 161 | name 162 | : NAME 163 | { 164 | $$ = $1; 165 | } 166 | ; 167 | 168 | attribute_seq_opt 169 | : attribute_seq_opt attribute 170 | | /*empty*/ 171 | ; 172 | 173 | attribute 174 | : NAME 175 | { 176 | domnode_attribute(a_maker, $1, ""); 177 | /* $1 was obtain with strdup() */ 178 | free($1); 179 | } 180 | | NAME EQ VALUE 181 | { 182 | domnode_attribute(a_maker, $1, $3); 183 | /* $1 was obtain with strdup() */ 184 | free($1); 185 | /* $3 was obtain with strdup() */ 186 | free($3); 187 | } 188 | ; 189 | 190 | %% 191 | #undef a_maker 192 | 193 | /******************************************************************************/ 194 | static void domnode_attribute(struct __sd_domnode_xml_maker* a_maker, 195 | const char* a_name, const char* a_value) 196 | { 197 | sd_domnode_t* node = sd_stack_peek(a_maker->elements); 198 | assert(node != 0); 199 | 200 | sd_debug("ATTR: add atrribute '%s'='%s' to node '%s'\n", a_name, a_value, 201 | node->name); 202 | 203 | sd_list_append(node->attrs, __sd_domnode_new(a_name, a_value, 0)); 204 | } 205 | -------------------------------------------------------------------------------- /src/log4c/appender_type_stream2.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * appender_type_stream.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_appender_type_stream2_h 11 | #define log4c_appender_type_stream2_h 12 | 13 | /** 14 | * @file appender_type_stream2.h 15 | * 16 | * @brief Log4c stream2 appender interface. 17 | * 18 | * The stream2 appender uses a file handle @c FILE* for logging. 19 | * It can be used with @c stdout, @c stderr or a normal file. 20 | * It is pretty primitive as it does not do file rotation, or have a maximum 21 | * configurable file size etc. It improves on the stream appender in a few 22 | * ways that make it a better starting point for new stream based appenders. 23 | * 24 | * It enhances the stream appender by allowing 25 | * the default file pointer to be used in buffered or unbuffered mode. 26 | * Also when you set the file pointer stream2 will not attempt to close 27 | * it on exit which avoids it fighting with the owner of the file pointer. 28 | * stream2 is configured via setter functions--the udata is 29 | * not exposed directly. This means that new options (eg. configure the open 30 | * mode ) could be added to stream2 while maintaining backward compatability. 31 | * 32 | * The appender can be used with default values, for example as follows: 33 | * 34 | * @code 35 | * log4c_appender_t* myappender; 36 | * 37 | * myappender = log4c_appender_get("/var/logs/mylog.log"); 38 | * log4c_appender_set_type(myappender,log4c_appender_type_get("stream2")); 39 | * 40 | * @endcode 41 | * 42 | * In this case the appender will be configured automatically with default 43 | * values: 44 | * @li the filename is the same as the name of the appender, 45 | * @c "/var/logs/mymlog.log" 46 | * @li the file is opened in "w+" mode 47 | * @li the default system buffer is used (cf; @c setbuf() ) in buffered mode 48 | * 49 | * The stream2 appender can be configured by passing it a file pointer 50 | * to use. In this case you manage the file pointer yourself--open, 51 | * option setting, closing. If you set the file pointer log4c will 52 | * not close the file on exiting--you must do this: 53 | * 54 | * @code 55 | * log4c_appender_t* myappender; 56 | * FILE * fp = fopen("myfile.log", "w"); 57 | * 58 | * myappender = log4c_appender_get("myappender"); 59 | * log4c_appender_set_type(myappender, log4c_appender_type_get("stream2")); 60 | * log4c_stream2_set_fp(stream2_appender,myfp); 61 | * 62 | * @endcode 63 | * 64 | * The default file pointer can be configured to use unbuffered mode. 65 | * Buffered mode is typically 25%-50% faster than unbuffered mode but 66 | * unbuffered mode is useful if your preference is for a more synchronized 67 | * log file: 68 | * 69 | * @code log4c_appender_t* myappender; 70 | * 71 | * myappender = log4c_appender_get("/var/logs/mylog.log"); 72 | * log4c_appender_set_type(myappender,log4c_appender_type_get("stream2")); 73 | * log4c_stream2_set_flags(myappender, LOG4C_STREAM2_UNBUFFERED); 74 | * 75 | * @endcode 76 | * 77 | **/ 78 | 79 | #include 80 | #include 81 | 82 | __LOG4C_BEGIN_DECLS 83 | 84 | /** 85 | * Stream2 appender type definition. 86 | * 87 | * This should be used as a parameter to the log4c_appender_set_type() 88 | * routine to set the type of the appender. 89 | * 90 | **/ 91 | LOG4C_API const log4c_appender_type_t log4c_appender_type_stream2; 92 | 93 | /** 94 | * Set the file pointer for this appender. 95 | * @param this a pointer to the appender 96 | * @param fp the file pointer this appender will use. The caller is 97 | * responsible for managing the file pointer (open, option setting, closing). 98 | */ 99 | LOG4C_API void log4c_stream2_set_fp(log4c_appender_t* a_this, FILE *fp); 100 | 101 | /** 102 | * Get the file pointer for this appender. 103 | * @param this a pointer to the appender 104 | * @return the file pointer for this appender. If there's a problem 105 | * returns NULL. 106 | * 107 | */ 108 | LOG4C_API FILE * log4c_stream2_get_fp(log4c_appender_t* a_this); 109 | 110 | 111 | /** 112 | * Set the flags for this appender. 113 | * @param this a pointer to the appender 114 | * @param flags ar teh flags to set. These will overwrite the existing flags. 115 | * Currently supported flags: LOG4C_STREAM2_UNBUFFERED 116 | * 117 | */ 118 | LOG4C_API void log4c_stream2_set_flags(log4c_appender_t* a_this, int flags); 119 | #define LOG4C_STREAM2_UNBUFFERED 0x01 120 | 121 | /** 122 | * Get the flags for this appender. 123 | * @param this a pointer to the appender 124 | * @return the flags for this appender. returns -1 if there was a problem. 125 | */ 126 | LOG4C_API int log4c_stream2_get_flags(log4c_appender_t* a_this); 127 | 128 | __LOG4C_END_DECLS 129 | 130 | #endif 131 | -------------------------------------------------------------------------------- /src/log4c/appender_type_rollingfile.h: -------------------------------------------------------------------------------- 1 | /* $Id: appender_type_rollingfile.h 2 | * 3 | * appender_type_rollingfile.h 4 | * 5 | * 6 | * See the COPYING file for the terms of usage and distribution. 7 | */ 8 | 9 | #ifndef log4c_appender_type_rollingfile_h 10 | #define log4c_appender_type_rollingfile_h 11 | 12 | /** 13 | * @file appender_type_rollingfile.h 14 | * 15 | * @brief Log4c rolling file appender interface. 16 | * 17 | * The rolling file appender implements a logging mechanism of 18 | * a list of files up to a maximum number. 19 | * 20 | * The files are written by default to the current directory with logging 21 | * names folowing the pattern log.1, log.2 etc. These parameters may 22 | * be changed using the appropriate setter functions. 23 | * 24 | * If the appender fails to open logfiles for writing then the 25 | * messages are logged to stderr--it will continue to try to open 26 | * the zero-th file for writing at rollover events so if it succeeds 27 | * at some point to open that file the messages will start to appear therein 28 | * and will no longer be sent to stderr. 29 | * 30 | * Switching from logging from one file 31 | * to the next is referred to as a 'rollover event'. 32 | * 33 | * The policy that determines when a rollover event should happen is 34 | * called a 'rolling policy'. 35 | * 36 | * A mechanism is provided to allow different rolling policies to be defined. 37 | * 38 | * Log4c ships with (and defaults to) the classic size-window rollover policy: 39 | * this triggers rollover when files reach a maximum size. The first file in 40 | * the list is 41 | * always the current file; when a rollover event occurs files are shifted up 42 | * by one position in the list--if the number of files in the list has already 43 | * reached the max then the oldest file is rotated out of the window. 44 | * 45 | * See the documentation in the rollingpolicy_type_sizewin.h file for 46 | * more details on the size-win rollover policy. 47 | * 48 | */ 49 | 50 | #include 51 | #include 52 | #include 53 | 54 | __LOG4C_BEGIN_DECLS 55 | 56 | /** 57 | * rollingfile appender type definition. 58 | * 59 | * This should be used as a parameter to the log4c_appender_set_type() 60 | * routine to set the type of the appender. 61 | * 62 | **/ 63 | LOG4C_API const log4c_appender_type_t log4c_appender_type_rollingfile; 64 | 65 | /** 66 | * Get a new rolling file appender configuration object. 67 | * @return a new rolling file appender configuration object, otherwise NULL. 68 | */ 69 | LOG4C_API rollingfile_udata_t *rollingfile_make_udata(void); 70 | 71 | /** 72 | * Set the logging directory in this rolling file appender configuration. 73 | * @param rfudatap the rolling file appender configuration object. 74 | * @param logdir the logging directory to set. 75 | * @return zero if successful, non-zero otherwise. 76 | */ 77 | LOG4C_API int rollingfile_udata_set_logdir( 78 | rollingfile_udata_t *rfudatap, 79 | const char* logdir); 80 | /** 81 | * Set the prefix string in this rolling file appender configuration. 82 | * @param rfudatap the rolling file appender configuration object. 83 | * @param prefix the logging files prfix to use. 84 | * @return zero if successful, non-zero otherwise. 85 | */ 86 | LOG4C_API int rollingfile_udata_set_files_prefix( 87 | rollingfile_udata_t *rfudatap, 88 | const char * prefix); 89 | /** 90 | * Set the rolling policy in this rolling file appender configuration. 91 | * @param rfudatap the rolling file appender configuration object. 92 | * @param policyp the logging files prfix to use. 93 | * @return zero if successful, non-zero otherwise. 94 | */ 95 | LOG4C_API int rollingfile_udata_set_policy(rollingfile_udata_t* rfudatap, 96 | log4c_rollingpolicy_t* policyp); 97 | /** 98 | * Get the logging directory in this rolling file appender configuration. 99 | * @param rfudatap the rolling file appender configuration object. 100 | * @return the logging directory. 101 | */ 102 | LOG4C_API const char* rollingfile_udata_get_logdir(rollingfile_udata_t* rfudatap); 103 | 104 | /** 105 | * Get the prefix string in this rolling file appender configuration. 106 | * @param rfudatap the rolling file appender configuration object. 107 | * @return the prefix. 108 | */ 109 | LOG4C_API const char* rollingfile_udata_get_files_prefix( 110 | rollingfile_udata_t* rfudatap); 111 | 112 | /** 113 | * Get the prefix string in this rolling file appender configuration. 114 | * @param rfudatap the rolling file appender configuration object. 115 | * @return the current size of the file being logged to. 116 | */ 117 | LOG4C_API long rollingfile_get_current_file_size( rollingfile_udata_t* rfudatap); 118 | 119 | __LOG4C_END_DECLS 120 | 121 | #endif 122 | -------------------------------------------------------------------------------- /src/sd/hash.h: -------------------------------------------------------------------------------- 1 | /* $Id$ 2 | * 3 | * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved. 4 | * Author: Marc Vertes 5 | * See the COPYING file for the terms of usage and distribution. 6 | */ 7 | 8 | #ifndef __sd_hash_h 9 | #define __sd_hash_h 10 | 11 | /** 12 | * @file hash.h 13 | * 14 | * @brief Generic hash table. It is implemented as an array of doubly-linked 15 | * lists of iterators. The index within the array is computed by a efficient 16 | * hash function. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | __SD_BEGIN_DECLS 23 | 24 | struct __sd_hash_ops { 25 | unsigned int (*hash) (const void*); 26 | int (*compare) (const void*, const void*); 27 | void* (*key_dup) (const void*); 28 | void (*key_free) (void*); 29 | void* (*data_dup) (const void*); 30 | void (*data_free) (void*); 31 | }; 32 | 33 | /** 34 | * This structure holds hash table operations. 35 | */ 36 | typedef struct __sd_hash_ops sd_hash_ops_t; 37 | 38 | /** 39 | * This is the hash table. 40 | */ 41 | typedef struct __sd_hash sd_hash_t; 42 | 43 | struct __sd_hash_iter { 44 | void* key; 45 | void* data; 46 | struct __sd_hash* hash; 47 | unsigned int __hkey; 48 | struct __sd_hash_iter* __next; 49 | struct __sd_hash_iter* __prev; 50 | int __foreach; 51 | }; 52 | 53 | /** 54 | * This is the elementary container for storing data into the hash table. 55 | */ 56 | typedef struct __sd_hash_iter sd_hash_iter_t; 57 | 58 | /** 59 | * Signature of a "foreach" function. 60 | */ 61 | typedef unsigned int (*sd_hash_func_t)(void* a_key, void* a_data, 62 | void* a_userdata); 63 | 64 | /** 65 | * Creates a new hash table. One can customize the memory (de)allocation 66 | * policy for keys and data stored in the hash table. 67 | * @param a_size the initial size of the array. 68 | * @param a_ops the hash operations. If NULL, then string keys are assumed and 69 | * no memory (de)allocation is performed for keys and data. 70 | * @return a dynamicaly allocated hash table. 71 | */ 72 | extern sd_hash_t* sd_hash_new(size_t a_size, const sd_hash_ops_t* a_ops); 73 | 74 | /** 75 | * Destroys the hash table. 76 | */ 77 | extern void sd_hash_delete(sd_hash_t* a_this); 78 | 79 | /** 80 | * clears the hash table. 81 | */ 82 | extern void sd_hash_clear(sd_hash_t* a_this); 83 | 84 | /** 85 | * Looks for the iterator associated to the given key in the hash table. 86 | * @param a_key the key associated to the iterator. 87 | * @return a pointer to the found iterator or NULL. 88 | */ 89 | extern sd_hash_iter_t* sd_hash_lookup(sd_hash_t* a_this, const void* a_key); 90 | 91 | /** 92 | * Looks for the iterator associated to the given key in the hash table and 93 | * creates it if doesn't exist. 94 | * @param a_key the key associated to the iterator. 95 | * @return a pointer to the found iterator or NULL. 96 | */ 97 | extern sd_hash_iter_t* sd_hash_lookadd(sd_hash_t* a_this, const void* a_key); 98 | 99 | /** 100 | * Adds data associated with the given key into the hash table. If the 101 | * key already exists, the old iterator is freed according to the memory 102 | * management operations passed to sd_hash_new(). 103 | * @param a_key the key associated to the iterator. 104 | * @return a pointer to the created or found iterator. 105 | */ 106 | extern sd_hash_iter_t* sd_hash_add(sd_hash_t* a_this, const void* a_key, 107 | void* a_data); 108 | 109 | /** 110 | * Removes an iterator from the hash table. 111 | * @param a_key the key associated to the iterator. 112 | */ 113 | extern void sd_hash_del(sd_hash_t* a_this, const void* a_key); 114 | 115 | /** 116 | * Calls \a a_func for each element of the hash table, as long as \a a_func 117 | * returns 0. 118 | * @param a_func the "foreach" function. 119 | * @param a_data the user data passed to \a a_func. 120 | */ 121 | extern void sd_hash_foreach(sd_hash_t* a_this, sd_hash_func_t a_func, 122 | void* a_data); 123 | 124 | /** 125 | * Gets the number of iterators. 126 | */ 127 | extern unsigned int sd_hash_get_nelem(sd_hash_t* a_this); 128 | 129 | /** 130 | * Gets the size of the array. 131 | */ 132 | extern unsigned int sd_hash_get_size(sd_hash_t* a_this); 133 | 134 | /** 135 | * Gets the first iterator. 136 | */ 137 | extern sd_hash_iter_t* sd_hash_begin(sd_hash_t* a_this); 138 | 139 | /** 140 | * Gets the last iterator. 141 | */ 142 | extern sd_hash_iter_t* sd_hash_end(sd_hash_t* a_this); 143 | 144 | /** 145 | * Gets a pointer to the next iterator. 146 | */ 147 | extern sd_hash_iter_t* sd_hash_iter_next(sd_hash_iter_t* a_this); 148 | 149 | /** 150 | * Gets a pointer to the previous iterator. 151 | */ 152 | extern sd_hash_iter_t* sd_hash_iter_prev(sd_hash_iter_t* a_this); 153 | 154 | /** 155 | * Gets a pointer to the previous iterator. 156 | */ 157 | extern void sd_hash_iter_del(sd_hash_iter_t* a_this); 158 | 159 | /** 160 | * Hashes strings. 161 | */ 162 | extern unsigned int sd_hash_hash_string(const char* a_string); 163 | 164 | __SD_END_DECLS 165 | 166 | #endif 167 | -------------------------------------------------------------------------------- /src/sd/stack.c: -------------------------------------------------------------------------------- 1 | /* stack - a dynamically resizing stack 2 | * Copyright (c) 2001 Michael B. Allen 3 | * 4 | * The MIT License 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a 7 | * copy of this software and associated documentation files (the "Software"), 8 | * to deal in the Software without restriction, including without limitation 9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the 11 | * Software is furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included 14 | * in all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | * OTHER DEALINGS IN THE SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include 31 | 32 | #define SD_STACK_INIT_SIZE 32 33 | 34 | struct __sd_stack { 35 | size_t max; 36 | size_t sp; 37 | size_t size; 38 | size_t iter; 39 | void **array; 40 | }; 41 | 42 | /******************************************************************************/ 43 | sd_stack_t* sd_stack_new(size_t max) 44 | { 45 | sd_stack_t* this; 46 | 47 | this = sd_calloc(1, sizeof(sd_stack_t)); 48 | this->max = max == 0 ? INT_MAX : max; 49 | this->size = SD_STACK_INIT_SIZE; 50 | this->sp = 0; 51 | this->array = sd_calloc(this->size, sizeof(*this->array)); 52 | 53 | return this; 54 | } 55 | 56 | /******************************************************************************/ 57 | void sd_stack_delete(sd_stack_t* this, void (*free_data_fn)(void *)) 58 | { 59 | if (!this) 60 | return; 61 | 62 | sd_stack_clear(this, free_data_fn); 63 | 64 | free(this->array); 65 | free(this); 66 | } 67 | 68 | /******************************************************************************/ 69 | size_t sd_stack_get_nelem(const sd_stack_t* this) 70 | { 71 | return this ? this->sp : -1; 72 | } 73 | 74 | /******************************************************************************/ 75 | void sd_stack_clear(sd_stack_t* this, void (*free_data_fn)(void *)) 76 | { 77 | if (!this) 78 | return; 79 | 80 | if (free_data_fn) { 81 | while (this->sp > 0) { 82 | free_data_fn(this->array[--(this->sp)]); 83 | } 84 | } 85 | } 86 | 87 | /******************************************************************************/ 88 | void* sd_stack_begin(sd_stack_t* this) 89 | { 90 | if (!this) 91 | return NULL; 92 | 93 | this->iter = 0; 94 | return this->array[this->iter]; 95 | } 96 | 97 | /******************************************************************************/ 98 | void* sd_stack_next(sd_stack_t* this) 99 | { 100 | if (this && this->iter < this->sp) 101 | return this->array[this->iter++]; 102 | 103 | return NULL; 104 | } 105 | 106 | /******************************************************************************/ 107 | void* sd_stack_end(sd_stack_t* this) 108 | { 109 | return sd_stack_peek(this); 110 | } 111 | 112 | /******************************************************************************/ 113 | void* sd_stack_peek(sd_stack_t* this) 114 | { 115 | if (!this || !this->sp) 116 | return NULL; 117 | 118 | return this->array[this->sp - 1]; 119 | } 120 | 121 | /******************************************************************************/ 122 | int sd_stack_push(sd_stack_t* this, void *data) 123 | { 124 | if (this == NULL) 125 | return -1; 126 | 127 | if (this->sp == this->size) { 128 | size_t new_size; 129 | 130 | if (this->size == this->max) 131 | return -1; 132 | 133 | if (this->size * 2 > this->max) { 134 | new_size = this->max; 135 | } else { 136 | new_size = this->size * 2; 137 | } 138 | 139 | this->size = new_size; 140 | this->array = sd_realloc(this->array, sizeof(*this->array) * this->size); 141 | } 142 | 143 | assert(this->sp <= this->size); 144 | this->array[this->sp++] = data; 145 | return 0; 146 | } 147 | 148 | /******************************************************************************/ 149 | void* sd_stack_pop(sd_stack_t* this) 150 | { 151 | if (this == NULL || this->sp == 0) 152 | return NULL; 153 | 154 | if (this->size >= SD_STACK_INIT_SIZE * 4 && this->sp < this->size / 4) { 155 | size_t new_size = this->size / 2; 156 | 157 | this->size = new_size; 158 | this->array = sd_realloc(this->array, sizeof(*this->array) * this->size); 159 | } 160 | 161 | assert(this->sp > 0 && this->sp <= this->size); 162 | return this->array[--(this->sp)]; 163 | } 164 | 165 | -------------------------------------------------------------------------------- /doc/old/log4cHowto.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Log4C HowTo 5 | 6 | 7 | 8 | 9 | 10 |

Usage

11 |

12 | You sprinkle log statements throughout your C code, and can turn them on/off via the config file. 13 |

14 | Finer control of the log statements is achieved by logging to categories, like URLDecodeStep?, or MyBug67Fix?. Each category can be turned on/off via the config file. So, you could turn off all the log messages except for those concerning URL-decoding, without recompiling. 15 |

16 | Categories are hierachical. If you have a category whose name is "root", then a category whose name is "root.dhcp" is a child of root. In the config file, all the properties of a category are inherited by its children unless they override it. 17 |

18 | Yet finer control is achieved by assigning a priority to each message (each call of log()). If the config file specifies a priority for a category, then a message won't be logged unless the log() call gives an equal/higher priority. Some constants are predefined for you. So, for example, you could limit logging to FATAL for some category, and TRACE for some other category. You can think of priority as "severity". 19 |

20 | NB There seem to be bugs in log4c's XML parser: comments terminate the parsing, thus ignoring further definitions. 21 |

22 | The output looks like this (depending on the appender you choose):

 23 | [stdout] WARN     root.bob - bob
 24 | [stderr] 20040209 17:17:58.013 ERROR    root.jane - jane
 25 | 
26 |

27 | Steps 28 |

29 |

    30 |
  1. Edit your code 31 |
      32 |
    1. Add a log() call to your code. 33 |
        34 |
      • log4c_category_xxx(catxx,"message you want, as a sprintf string %d",99) 35 |
      • 36 |
      37 |
    2. 38 |
    3. Decide on the category (e.g. what feature, function, purpose), and priority/severity. 39 |
    4. 40 |
    41 |
  2. 42 |
43 |
One of:
 44 |   LOG4C_PRIORITY_FATAL = 000,
 45 |   LOG4C_PRIORITY_ALERT = 100,
 46 |   LOG4C_PRIORITY_CRIT = 200,
 47 |   LOG4C_PRIORITY_ERROR = 300,
 48 |   LOG4C_PRIORITY_WARN = 400,
 49 |   LOG4C_PRIORITY_NOTICE = 500,
 50 |   LOG4C_PRIORITY_INFO = 600,
 51 |   LOG4C_PRIORITY_DEBUG = 700,
 52 |   LOG4C_PRIORITY_TRACE = 800,
 53 |   LOG4C_PRIORITY_NOTSET = 900,
 54 |   LOG4C_PRIORITY_UNKNOWN = 1000
55 |
56 |
    57 |
  • 58 |
      59 |
    • 60 |
        61 |
      • log4c_category_trace(cat_urlDecodeStep,"message you want, as a sprintf string %d",99) 62 |
      • 63 |
      64 |
    • 65 |
    66 |
      67 |
    1. Setup the category variable as a global or local 68 |
        69 |
      • log4c_category_t* cat_urlDecodeStep = log4c_category_get("NameFromConfigFile"); 70 |
      • 71 |
      72 |
    2. 73 |
    3. #include <log4c/category.h> 74 |
    4. 75 |
    76 |
  • 77 |
78 |
    79 |
  1. Edit the config file 80 |
      81 |
    1. Create your config file (./log4crc, or ~/.log4crc, or ${LOG4C_RCPATH}/log4rc) 82 |
    2. 83 |
    3. Setup the skeleton log4crc file... 84 | 6 Add your category, the priority is the cutoff point for messages (log() calls of lower priority won't print). 85 |
        86 |
      • <category name="TheCategoryNameToUseIn_category_get" priority="notice" appender="stdout"/> 87 |
      • 88 |
      89 |
    4. 90 |
    5. Decide on the "appender", it controls where the message goes, and it's format. Apparently "stdout", "stderr", and "syslog" are provided. Each formats the message a little differently. 91 |
    6. 92 |
    93 |
  2. 94 |
  3. Make your code: don't forget to add the -l log4c switch to gcc to link in log4c. 95 |
  4. 96 |
  5. Edit the config file to turn on/off messages. 97 |
  6. 98 |
99 |

100 |

101 | In log4crc
102 | define a category
103 |    <category name="SCSIOp" priority="trace" appender="stdout">
104 |    where:
105 |      Your C program will log messages in the category NAME,
106 |      If the attempt to log has a lower priority, the message is ignored,
107 |      The message will be output in a format and to a location defined by the APPENDER.
108 | 
109 | someRoutine
110 | {
111 |     // get the "category" 
112 |     log4c_category_t*   cat = log4c_category_get("a category");
113 | 
114 |     ...
115 | 
116 |     // "print" to it
117 |     log4c_category_log(cat,priority,sprintfFmt,args...)
118 | // where priority is equiv to routine _error, _warn, _trace, etc:
119 |   LOG4C_PRIORITY_FATAL = 000,
120 |   LOG4C_PRIORITY_ALERT = 100,
121 |   LOG4C_PRIORITY_CRIT = 200,
122 |   LOG4C_PRIORITY_ERROR = 300,
123 |   LOG4C_PRIORITY_WARN = 400,
124 |   LOG4C_PRIORITY_NOTICE = 500,
125 |   LOG4C_PRIORITY_INFO = 600,
126 |   LOG4C_PRIORITY_DEBUG = 700,
127 |   LOG4C_PRIORITY_TRACE = 800,
128 |   LOG4C_PRIORITY_NOTSET = 900,
129 |   LOG4C_PRIORITY_UNKNOWN = 1000 
130 | 
131 | }
132 | 
133 | 134 | 135 | 136 | -------------------------------------------------------------------------------- /tests/log4c/test_rollingfile_appender.c: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * test_rollingfile_appender.c 4 | * 5 | * This file demonstrates how to programatically use the rolling 6 | * file appender. See also the API documentation for the 7 | * appender_type_rollingfile.h file. 8 | * 9 | * It is possible to be more terse here if you accept the default values, 10 | * but we spell it out explicitly. 11 | * 12 | * See the COPYING file for the terms of usage and distribution. 13 | */ 14 | 15 | #ifdef HAVE_CONFIG_H 16 | #include "config.h" 17 | #endif 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | /*********************** Parameters ********************************** 26 | * 27 | * params could be taken from the command line to facillitate testing 28 | * 29 | */ 30 | 31 | /* 32 | * rolling file specific params 33 | */ 34 | #ifdef _WIN32 35 | #define FILE_SEP "\\" 36 | #else 37 | #define FILE_SEP "/" 38 | #endif 39 | char *param_log_dir = ROLLINGFILE_DEFAULT_LOG_DIR; 40 | char* param_log_prefix = ROLLINGFILE_DEFAULT_LOG_PREFIX"rf"; 41 | long param_max_file_size = 1666; 42 | long param_max_num_files = 6; 43 | 44 | /* 45 | * Other Logging params 46 | * xxx Problem with dated layout on windows: assert failure 47 | * in gmtime call. 48 | */ 49 | char *param_layout_to_use = "dated"; /* could also be "basic" */ 50 | 51 | /******************************************************************* 52 | * 53 | * Globals 54 | * 55 | */ 56 | log4c_category_t* root = NULL; 57 | log4c_appender_t* file_appender = NULL; 58 | /******************************************************************************/ 59 | 60 | /* 61 | * Init log4c and configure a rolling file appender 62 | * 63 | */ 64 | static void init_log4c_with_rollingfile_appender(){ 65 | int rc = 2; 66 | rollingfile_udata_t *rfup = NULL; 67 | log4c_rollingpolicy_t *policyp = NULL; 68 | rollingpolicy_sizewin_udata_t *sizewin_udatap = NULL; 69 | 70 | printf("using the rolling file appender " 71 | "to write test log files\n" 72 | "to log directory '%s', log file prefix is '%s'" 73 | ", max file size is '%ld'\n" 74 | "max num files is '%ld'\n", 75 | param_log_dir, param_log_prefix, param_max_file_size, 76 | param_max_num_files); 77 | 78 | if ( (rc = log4c_init()) == 0 ) { 79 | printf("log4c init success\n"); 80 | } else { 81 | printf("log4c init failed--error %d\n", rc); 82 | return; 83 | } 84 | 85 | /* 86 | * Get a reference to the root category 87 | */ 88 | root = log4c_category_get("root"); 89 | log4c_category_set_priority(root, 90 | LOG4C_PRIORITY_WARN); 91 | 92 | /* 93 | * Get a file appender and set the type to rollingfile 94 | */ 95 | file_appender = log4c_appender_get("aname"); 96 | log4c_appender_set_type(file_appender, 97 | log4c_appender_type_get("rollingfile")); 98 | 99 | /* 100 | * Make a rolling file udata object and set the basic parameters 101 | */ 102 | rfup = rollingfile_make_udata(); 103 | rollingfile_udata_set_logdir(rfup, param_log_dir); 104 | rollingfile_udata_set_files_prefix(rfup, param_log_prefix); 105 | 106 | /* 107 | * Get a new rollingpolicy 108 | * type defaults to "sizewin" but set the type explicitly here 109 | * to show how to do it. 110 | */ 111 | policyp = log4c_rollingpolicy_get("a_policy_name"); 112 | log4c_rollingpolicy_set_type(policyp, 113 | log4c_rollingpolicy_type_get("sizewin")); 114 | 115 | /* 116 | * Get a new sizewin policy type and configure it. 117 | * Then attach it to the policy object. 118 | */ 119 | sizewin_udatap = sizewin_make_udata(); 120 | sizewin_udata_set_file_maxsize(sizewin_udatap, param_max_file_size); 121 | sizewin_udata_set_max_num_files(sizewin_udatap, param_max_num_files); 122 | log4c_rollingpolicy_set_udata(policyp,sizewin_udatap); 123 | 124 | /* 125 | * Now set that policy in our rolling file appender udata. 126 | */ 127 | 128 | rollingfile_udata_set_policy(rfup, policyp); 129 | log4c_appender_set_udata(file_appender, rfup); 130 | 131 | /* 132 | * Allow the rolling policy to initialize itself: 133 | * it needs to know the rollingfile udata it is associated with--it 134 | * picks up some parameters in there 135 | */ 136 | log4c_rollingpolicy_init(policyp, rfup); 137 | 138 | /* 139 | * Configure a layout for the rolling file appender 140 | */ 141 | log4c_appender_set_layout(file_appender, 142 | log4c_layout_get(param_layout_to_use) ); 143 | 144 | /* 145 | * Configure the root category with our rolling file appender... 146 | * and we can then start logging to it. 147 | * 148 | */ 149 | log4c_category_set_appender(root,file_appender ); 150 | 151 | log4c_dump_all_instances(stderr); 152 | 153 | 154 | } 155 | 156 | static int test0(int argc, char* argv[]) 157 | { 158 | int i = 0; 159 | init_log4c_with_rollingfile_appender(); 160 | 161 | for (i = 0; i<200; i++){ 162 | 163 | log4c_category_fatal(root, 164 | "%d%d%d%d%d%d%d%d%d%d%d%d%d\n",i,i,i,i,i,i,i,i,i,i,i,i,i); 165 | 166 | } 167 | 168 | /* Explicitly call the log4c cleanup routine */ 169 | if ( log4c_fini()){ 170 | printf("log4c_fini() failed"); 171 | } 172 | 173 | return 1; 174 | } 175 | 176 | /******************************************************************************/ 177 | int main(int argc, char* argv[]) 178 | { 179 | 180 | test0(argc,argv); 181 | 182 | return(0); 183 | } 184 | -------------------------------------------------------------------------------- /src/log4c/layout.h: -------------------------------------------------------------------------------- 1 | /* $Id$ 2 | * 3 | * layout.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_layout_h 11 | #define log4c_layout_h 12 | 13 | /** 14 | * @file layout.h 15 | * 16 | * @brief Interface for user specific layout format of log4c_logging_event 17 | * events. 18 | * 19 | * @todo the layout interface needs a better configuration system 20 | * depending on the layout type. The udata field is a just a trick. 21 | * 22 | * @todo a pattern layout would be welcomed !! 23 | **/ 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | __LOG4C_BEGIN_DECLS 30 | 31 | struct __log4c_layout; 32 | 33 | /** 34 | * log4c layout class 35 | **/ 36 | typedef struct __log4c_layout log4c_layout_t; 37 | 38 | /** 39 | * @brief log4c layout type class 40 | * 41 | * Attributes description: 42 | * 43 | * @li @c name layout type name 44 | * @li @c format 45 | **/ 46 | typedef struct log4c_layout_type { 47 | const char* name; 48 | const char* (*format) (const log4c_layout_t*, const log4c_logging_event_t*); 49 | } log4c_layout_type_t; 50 | 51 | /** 52 | * Get a pointer to an existing layout type. 53 | * 54 | * @param a_name the name of the layout type to return. 55 | * @returns a pointer to an existing layout type, or NULL if no layout 56 | * type with the specified name exists. 57 | **/ 58 | LOG4C_API const log4c_layout_type_t* log4c_layout_type_get(const char* a_name); 59 | 60 | /** 61 | * Use this function to register a layout type with log4c. 62 | * Once this is done you may refer to this type by name both 63 | * programatically and in the log4c configuration file. 64 | * 65 | * @param a_type a pointer to the new layout type to set. 66 | * @returns a pointer to the previous layout type of same name. 67 | * 68 | * Example code fragment: 69 | * @code 70 | * 71 | * const log4c_layout_type_t log4c_layout_type_xml = { 72 | * "s13_xml", 73 | * xml_format, 74 | * }; 75 | * 76 | * log4c_layout_type_set(&log4c_layout_type_xml); 77 | * 78 | * @endcode 79 | **/ 80 | LOG4C_API const log4c_layout_type_t* log4c_layout_type_set( 81 | const log4c_layout_type_t* a_type); 82 | 83 | /** 84 | * Get a pointer to an existing layout. 85 | * 86 | * @param a_name the name of the layout to return. 87 | * @returns a pointer to an existing layout, or NULL if no layout 88 | * with the specfied name exists. 89 | **/ 90 | LOG4C_API log4c_layout_t* log4c_layout_get(const char* a_name); 91 | 92 | /** 93 | * Constructor for layout. 94 | **/ 95 | LOG4C_API log4c_layout_t* log4c_layout_new(const char* a_name); 96 | 97 | /** 98 | * Destructor for layout. 99 | **/ 100 | LOG4C_API void log4c_layout_delete(log4c_layout_t* a_layout); 101 | 102 | /** 103 | * @param a_layout the log4c_layout_t object 104 | * @return the layout name 105 | **/ 106 | LOG4C_API const char* log4c_layout_get_name(const log4c_layout_t* a_layout); 107 | 108 | /** 109 | * @param a_layout the log4c_layout_t object 110 | * @return a log4c_layout_type_t object 111 | **/ 112 | LOG4C_API const log4c_layout_type_t* log4c_layout_get_type( 113 | const log4c_layout_t* a_layout); 114 | 115 | /** 116 | * sets the layout type 117 | * 118 | * @param a_layout the log4c_layout_t object 119 | * @param a_type the new layout type 120 | * @return the previous layout type 121 | * 122 | **/ 123 | LOG4C_API const log4c_layout_type_t* log4c_layout_set_type( 124 | log4c_layout_t* a_layout, 125 | const log4c_layout_type_t* a_type); 126 | 127 | /** 128 | * @param a_layout the log4c_layout_t object 129 | * @return the layout user data 130 | **/ 131 | LOG4C_API void* log4c_layout_get_udata(const log4c_layout_t* a_layout); 132 | 133 | /** 134 | * sets the layout user data 135 | * 136 | * @param a_layout the log4c_layout_t object 137 | * @param a_udata the new layout user data 138 | * @return the previous layout user data 139 | **/ 140 | LOG4C_API void* log4c_layout_set_udata(log4c_layout_t* a_layout, 141 | void* a_udata); 142 | /** 143 | * format a log4c_logging_event events to a string. 144 | * 145 | * @param a_layout the log4c_layout_t object 146 | * @param a_event a logging_event_t object 147 | * @returns an appendable string. 148 | **/ 149 | LOG4C_API const char* log4c_layout_format( 150 | const log4c_layout_t* a_layout, 151 | const log4c_logging_event_t* a_event); 152 | 153 | /** 154 | * prints the layout on a stream 155 | * @param a_layout the log4c_layout_t object 156 | * @param a_stream the stream 157 | **/ 158 | LOG4C_API void log4c_layout_print( 159 | const log4c_layout_t* a_layout, FILE* a_stream); 160 | 161 | /** 162 | * prints all the current registered layout types on a stream 163 | * 164 | * @param fp the stream 165 | **/ 166 | LOG4C_API void log4c_layout_types_print(FILE *fp); 167 | 168 | /** 169 | * Helper macro to define static layout types. 170 | * 171 | * @param a_type the log4c_layout_type_t object to define 172 | * @warning needs GCC support: otherwise this macro does nothing 173 | * @deprecated This macro, and the static initialialization 174 | * of layouts in general, is deprecated. Use rather 175 | * the log4c_layout_type_set() function to initialize your appenders 176 | * before calling log4c_init() 177 | **/ 178 | #ifdef __GNUC__ 179 | # define log4c_layout_type_define(a_type) \ 180 | typedef int log4c_layout_type_define_##a_type __attribute__((deprecated)); \ 181 | static log4c_layout_type_define_##a_type __unsused_var __attribute__((unused)); 182 | #else 183 | # define log4c_layout_type_define(a_type) 184 | #endif 185 | 186 | /** 187 | * @internal 188 | **/ 189 | struct __sd_factory; 190 | LOG4C_API struct __sd_factory* log4c_layout_factory; 191 | 192 | __LOG4C_END_DECLS 193 | 194 | #endif 195 | -------------------------------------------------------------------------------- /src/sd/list.h: -------------------------------------------------------------------------------- 1 | /* $Id$ 2 | * 3 | * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved. 4 | * 5 | * See the COPYING file for the terms of usage and distribution. 6 | */ 7 | 8 | #ifndef __sd_list_h 9 | #define __sd_list_h 10 | 11 | /** 12 | * @file list.h @ingroup sd 13 | * 14 | * @brief Generic list object. It is implemented as an array of doubly-linked 15 | * lists of iterators. The index within the array is computed by a efficient 16 | * list function. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | __SD_BEGIN_DECLS 23 | 24 | /** 25 | * This is the list object. 26 | */ 27 | typedef struct __sd_list sd_list_t; 28 | 29 | struct __sd_list_iter { 30 | void* data; 31 | struct __sd_list* list; 32 | struct __sd_list_iter* __next; 33 | struct __sd_list_iter* __prev; 34 | int __foreach; 35 | }; 36 | 37 | /** 38 | * This is the elementary container for storing data into the list object. 39 | */ 40 | typedef struct __sd_list_iter sd_list_iter_t; 41 | 42 | /** 43 | * Signature of a "foreach" function. 44 | */ 45 | typedef unsigned int (*sd_list_func_t)(void* a_data, void* a_userdata); 46 | 47 | /** 48 | * Creates a list. 49 | * @param a_capacity initial number of preallocated iterators 50 | * @return the list object. 51 | */ 52 | extern sd_list_t* sd_list_new(size_t a_capacity); 53 | 54 | /** 55 | * Destroys the list object. 56 | * @todo need a function parameter to destroy list elements. 57 | */ 58 | extern void sd_list_delete(sd_list_t* a_this); 59 | 60 | /** 61 | * Adds the given_data at the head of the list. 62 | */ 63 | extern sd_list_iter_t* sd_list_prepend(sd_list_t* a_this, void* a_data); 64 | 65 | /** 66 | * Adds the given data at the tail of the list. 67 | */ 68 | extern sd_list_iter_t* sd_list_append(sd_list_t* a_this, void* a_data); 69 | 70 | /** 71 | * Looks for the iterator associated to the given data in the list object. 72 | * @param a_data the data to find 73 | * @return a pointer to the found iterator or NULL. 74 | */ 75 | extern sd_list_iter_t* sd_list_lookup(sd_list_t* a_this, void* a_data); 76 | 77 | /** 78 | * Looks for the iterator associated to the given data in the list object and 79 | * creates it if doesn't exist, using @c sd_list_add(). 80 | * @param a_data the data to find/add 81 | * @return a pointer to the found iterator or NULL. 82 | */ 83 | extern sd_list_iter_t* sd_list_lookadd(sd_list_t* a_this, void* a_data); 84 | 85 | /** 86 | * Adds the given data into the list object. If the data already exists, 87 | * the associated iterator is returned. 88 | * @warning the element is added at the begining of the list. 89 | * @param a_data the data to add 90 | * @return a pointer to the created or found iterator. 91 | */ 92 | extern sd_list_iter_t* sd_list_add(sd_list_t* a_this, void* a_data); 93 | 94 | /** 95 | * Applies the given function to all list elements, starting from the 96 | * first one. As soon as the function returns a non-null value, the 97 | * given data is inserted in the list (before the element). 98 | * @param a_func the "sort" function. 99 | * @param a_data the data to add 100 | * @return a pointer to the created iterator. 101 | */ 102 | extern sd_list_iter_t* sd_list_sortadd(sd_list_t* a_this, 103 | sd_list_func_t a_func, 104 | void* a_data); 105 | 106 | /** 107 | * Removes an iterator from the list object. 108 | * @param a_data the data associated to the iterator. 109 | */ 110 | extern int sd_list_del(sd_list_t* a_this, void* a_data); 111 | 112 | /** 113 | * clears the list object. 114 | */ 115 | extern void sd_list_clear(sd_list_t* a_this); 116 | 117 | /** 118 | * Calls \a a_func for each element of the list object, as long as \a a_func 119 | * returns 0. 120 | * @param a_func the "foreach" function. 121 | * @param a_data the user data passed to \a a_func. 122 | */ 123 | extern void sd_list_foreach(sd_list_t* a_this, sd_list_func_t a_func, 124 | void* a_userdata); 125 | 126 | /** 127 | * Calls \a a_func for each element of the list object, as long as \a a_func 128 | * returns 0. 129 | * Same as sd_list_foreach but from tail to head of list. 130 | * @param a_func the "foreach" function. 131 | * @param a_data the user data passed to \a a_func. 132 | */ 133 | extern void sd_list_rforeach(sd_list_t* a_this, sd_list_func_t a_func, 134 | void* a_userdata); 135 | 136 | /** 137 | * Gets the number of iterators. 138 | */ 139 | extern size_t sd_list_get_nelem(sd_list_t* a_this); 140 | 141 | /** 142 | * Gets the iterator pointing to the first element of the list. 143 | */ 144 | extern sd_list_iter_t* sd_list_begin(sd_list_t* a_this); 145 | 146 | /** 147 | * Gets the past-the-last-element iterator of the list. 148 | */ 149 | extern sd_list_iter_t* sd_list_end(sd_list_t* a_this); 150 | 151 | /** 152 | * Gets the iterator pointing to the last element of the list. 153 | */ 154 | extern sd_list_iter_t* sd_list_rbegin(sd_list_t* a_this); 155 | 156 | /** 157 | * Gets the before-the-first-element iterator of the list. 158 | */ 159 | extern sd_list_iter_t* sd_list_rend(sd_list_t* a_this); 160 | 161 | /** 162 | * Gets a pointer to the next iterator. 163 | */ 164 | extern sd_list_iter_t* sd_list_iter_next(sd_list_iter_t* a_this); 165 | 166 | /** 167 | * Gets a pointer to the previous iterator. 168 | */ 169 | extern sd_list_iter_t* sd_list_iter_prev(sd_list_iter_t* a_this); 170 | 171 | /** 172 | * Deletes the iterator from the list. 173 | */ 174 | extern void sd_list_iter_del(sd_list_iter_t* a_this); 175 | 176 | /** 177 | * Deletes the iterator from the list. 178 | */ 179 | extern void sd_list_iter_del(sd_list_iter_t* a_this); 180 | 181 | /** 182 | * Creates a new iterator and inserts it before @a a_this. 183 | * @param a_data the data associated to the iterator. 184 | */ 185 | extern sd_list_iter_t* sd_list_iter_insert(sd_list_iter_t* a_this, 186 | void* a_data); 187 | 188 | __SD_END_DECLS 189 | 190 | #endif 191 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | This version of Log4C is clone/fork of original version located 2 | at sf.net/projects/log4c to fix building on AIX and new Linux versions 3 | 4 | -------------------------------------------------------------------- 5 | 6 | This is the distribution of Log4C (last updated 13 Nov 2006) 7 | 8 | * What is Log4C 9 | 10 | Log4C is a C library for flexible logging to files, syslog and other 11 | destinations. It is modeled after the Log for Java library 12 | (http://jakarta.apache.org/log4j/), staying as close to their API as is 13 | reasonable. 14 | 15 | As well as the "doc" directory in the Log4C repository, see also here for 16 | more documentation on Log4c: 17 | 18 | http://log4c.sourceforge.net/ 19 | http://sourceforge.net/docman/?group_id=38627 20 | http://en.wikipedia.org/wiki/Log4C 21 | 22 | * Licensing 23 | 24 | Log4C libraries are released under the terms of the GNU Lesser 25 | General Public License (GNU LGPL). 26 | 27 | You can find copies of the license in the file COPYING 28 | 29 | * What you will need to compile Log4C on Unix systems 30 | 31 | perl 5.8+ (used by the automake tools) 32 | 33 | GNU make tools: automake 1.7+, autoconf 2.57+, m4 1.4+ and libtool 1.4+ 34 | 35 | A Compiler, among those tested are: 36 | . gcc3 (on Red Hat Enterprise Linux 3 and 4) 37 | . gcc4 (on HP-UX 11.11i, on Fedora Core 5) 38 | . Sun cc (versions 5.3 and 5.7 on Solaris 8 and higher, sparc and i386) 39 | . HPUX ansi C compiler (on HPUX v11.11i, pa-risc) 40 | . AIX xlc compiler 41 | 42 | If you request at compile time that the expat library be used to help parse 43 | the configuration file, then you will need the expat library available 44 | on the system. If you do not use expat then pre-generated files from 45 | obsolete versions of flex and bison are used to do the parsing--this code 46 | is still supported for the moment but it is recommended to use expat. 47 | 48 | For information on compiling on Microsoft Windows see the README in the msvc6 49 | directory. 50 | 51 | * Where to find ... 52 | 53 | GNU automake tools: 54 | http://gcc.gnu.org 55 | http://www.sunfreeware.com/ for pre-built Solaris packages 56 | http://hpux.connect.org.uk/ for re-built HP-UX depots 57 | 58 | gcc3 or gcc4 59 | http://gcc.gnu.org 60 | http://www.sunfreeware.com for pre-built Solaris packages 61 | http://hpux.connect.org.uk/ for re-built HP-UX depots 62 | 63 | Log4C 64 | http://log4c.sf.net/ This SourceForge site is now the main log4c site. 65 | 66 | expat 67 | http://expat.sourceforge.net/ 68 | 69 | * How to for library users who download a released tarball (eg. 70 | log4c-1.2.0.tar.gz): 71 | 72 | The Log4C package uses the GNU autotools compilation and installation 73 | framework. 74 | 75 | We recommend that you do not build in the source directories themselves; 76 | rather make a build directory into which the configure script will generate 77 | the Makefiles and build the library and binaries in there. This is better 78 | because it allows you to seperate the source from the binaries and also to 79 | mantain a compiled version of Log4C for different platforms--make a build 80 | directory for each of the platforms you support and run configure on each of 81 | your build machines. 82 | 83 | So, for example, you might create directories called build-fc5, build-rh3, 84 | build-Solaris10x86, build-hpuxi11 and so on for your various builds. These 85 | example commands below should compile Log4C on each of the supported 86 | platforms: 87 | 88 | $ tar -zxvf log4c-1.2.0.tar.gz 89 | $ mkdir build; cd build 90 | $ ../log4c-1.2.0/configure --prefix=/path/of/installation 91 | $ make 92 | $ make install 93 | 94 | To build the binary, source, developer and debuginfo RPMs for Linux: 95 | $ make rpm 96 | 97 | To enable compilation of the test programs for the library you would do this: 98 | $ ../log4c-1.2.0/configure --prefix=/path/of/installation --enable-test 99 | 100 | To enable the dcumentation generation 101 | $ ../log4c-1.2.0/configure --prefix=/path/of/installation --enable-doc 102 | 103 | To specify a compiler other than gcc at configure time you would do something 104 | like this: 105 | $ ../log4c-1.2.0/configure --prefix=/path/of/installation --enable-test \ 106 | CC=/usr/SUNWspro/bin/cc 107 | 108 | To get started with the examples see the README in the examples source code 109 | directory and run them from the build directory as follows: 110 | $ cd examples 111 | $ ./application_1 112 | $ ./application_2 113 | 114 | * How to for library developers ... 115 | 116 | When you check out Log4C from CVS (as opposed to downloading a released 117 | tarball) you will need to generate the configure script and so on. To do this 118 | run the bootstrap script. This script must be run in the source directories 119 | themselves: 120 | 121 | $ cvs -d:pserver:anonymous@log4c.cvs.sourceforge.net:/cvsroot/log4c login 122 | $ cvs -z3 -d:pserver:anonymous@log4c.cvs.sourceforge.net:/cvsroot/log4c co -P log4c 123 | $ cd log4c 124 | $ ./bootstrap 125 | 126 | To compile in extra tracing and messages and compile the doc you would do 127 | this from your build directory: 128 | $ ../log4c/configure --prefix=/path/of/installation --enable-test \ 129 | --enable-debug --enable-doc 130 | 131 | This will define the __SD_DEBUG__ variable at compile time. Note that you 132 | still need to define the SD_ERROR and SD_DEBUG envronment variables at run 133 | time to actually see the error/debug output. 134 | 135 | Type '../log4c/configure --help' for a list of all the configure 136 | options. Some of the options are generic autoconf options, while the Log4C 137 | specific options are prefixed with "LOG4C" in the help text. 138 | 139 | 140 | Have Fun !! 141 | -------------------------------------------------------------------------------- /src/log4c/appender_type_stream2.c: -------------------------------------------------------------------------------- 1 | static const char version[] = "$Id$"; 2 | 3 | /* 4 | * appender_stream2.c 5 | * 6 | * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved. 7 | * 8 | * See the COPYING file for the terms of usage and distribution. 9 | */ 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | #include 16 | #include 17 | 18 | typedef struct stream2_udata { 19 | FILE * s2u_fp; 20 | int s2u_flags; 21 | #define STREAM2_MY_FP 0x01 22 | int s2u_state; 23 | } log4c_stream2_udata_t; 24 | 25 | /* xxx would be nice to run-time check the type here */ 26 | #define stream2_get_udata(this) \ 27 | (log4c_stream2_udata_t *)log4c_appender_get_udata(this) 28 | 29 | /*******************************************************************************/ 30 | static log4c_stream2_udata_t* stream2_make_udata(void); 31 | static void stream2_free_udata(log4c_stream2_udata_t* s2up); 32 | static log4c_stream2_udata_t * stream2_get_or_make_udata(log4c_appender_t* this); 33 | static int stream2_init(log4c_appender_t* this); 34 | 35 | /*******************************************************************************/ 36 | static int stream2_init(log4c_appender_t* this){ 37 | log4c_stream2_udata_t *s2up = stream2_make_udata(); 38 | 39 | log4c_appender_set_udata(this, s2up); 40 | 41 | return(0); 42 | } 43 | 44 | /*******************************************************************************/ 45 | static int stream2_open(log4c_appender_t* this) 46 | { 47 | log4c_stream2_udata_t *s2up = NULL; 48 | FILE * fp = NULL; 49 | int flags = 0; 50 | 51 | if ( !this){ 52 | return(-1); 53 | } 54 | s2up = stream2_get_or_make_udata(this); 55 | //s2up = stream2_get_udata(this); 56 | 57 | fp = s2up->s2u_fp; 58 | flags = s2up->s2u_flags; 59 | 60 | if ( !fp ) { 61 | if ( (fp = fopen(log4c_appender_get_name(this), "w+")) == NULL){ 62 | fp = stderr; 63 | } else { 64 | s2up->s2u_state |= STREAM2_MY_FP; 65 | } 66 | s2up->s2u_fp = fp; 67 | } 68 | 69 | if ( flags & LOG4C_STREAM2_UNBUFFERED){/* unbuffered mode by default */ 70 | setbuf(fp, NULL); 71 | } 72 | 73 | return 0; 74 | } 75 | 76 | /*******************************************************************************/ 77 | static int stream2_append(log4c_appender_t* this, 78 | const log4c_logging_event_t* a_event) 79 | { 80 | log4c_stream2_udata_t *s2up = log4c_appender_get_udata(this); 81 | 82 | if ( !s2up ) { 83 | return(-1); 84 | } 85 | 86 | return fprintf(s2up->s2u_fp, "[%s] %s", log4c_appender_get_name(this), 87 | a_event->evt_rendered_msg); 88 | } 89 | 90 | /*******************************************************************************/ 91 | static int stream2_close(log4c_appender_t* this) 92 | { 93 | log4c_stream2_udata_t *s2up = log4c_appender_get_udata(this); 94 | int rc = -1; 95 | 96 | if ( !this){ 97 | return rc; 98 | } 99 | s2up = stream2_get_udata(this); 100 | if ( !s2up){ 101 | return(rc); 102 | } 103 | 104 | if ( s2up->s2u_fp && (s2up->s2u_state & STREAM2_MY_FP) ){ 105 | rc = fclose(s2up->s2u_fp); 106 | } else { 107 | rc = 0; 108 | } 109 | /* Free up and reset any data associated with this stream2 appender */ 110 | stream2_free_udata(s2up); 111 | log4c_appender_set_udata(this, NULL); 112 | 113 | return (rc); 114 | } 115 | 116 | /*******************************************************************************/ 117 | 118 | static log4c_stream2_udata_t* stream2_make_udata(){ 119 | 120 | log4c_stream2_udata_t* s2up = 121 | (log4c_stream2_udata_t*) sd_calloc(1, sizeof(log4c_stream2_udata_t)); 122 | return(s2up); 123 | } 124 | 125 | /*******************************************************************************/ 126 | 127 | static void stream2_free_udata(log4c_stream2_udata_t* s2up){ 128 | 129 | free(s2up); 130 | } 131 | 132 | /*******************************************************************************/ 133 | 134 | static log4c_stream2_udata_t * stream2_get_or_make_udata(log4c_appender_t* this){ 135 | log4c_stream2_udata_t *s2up; 136 | int rc = 0; 137 | 138 | s2up = log4c_appender_get_udata(this); 139 | 140 | if ( !s2up) { 141 | rc = stream2_init(this); 142 | } 143 | 144 | return(stream2_get_udata(this)); 145 | } 146 | 147 | /*******************************************************************************/ 148 | extern void log4c_stream2_set_fp(log4c_appender_t* this, FILE *fp){ 149 | log4c_stream2_udata_t *s2up; 150 | 151 | if ( !this){ 152 | return; 153 | } 154 | s2up = stream2_get_or_make_udata(this); 155 | 156 | s2up->s2u_fp = fp; 157 | s2up->s2u_state &= !(STREAM2_MY_FP); 158 | } 159 | /*******************************************************************************/ 160 | extern FILE* log4c_stream2_get_fp(log4c_appender_t* this){ 161 | log4c_stream2_udata_t *s2up; 162 | 163 | if ( !this){ 164 | return NULL; 165 | } 166 | s2up = stream2_get_udata(this); 167 | if ( s2up){ 168 | return s2up->s2u_fp; 169 | } else { 170 | return NULL; 171 | } 172 | } 173 | /*******************************************************************************/ 174 | extern int log4c_stream2_get_flags(log4c_appender_t* this){ 175 | log4c_stream2_udata_t *s2up; 176 | 177 | if ( !this){ 178 | return -1; 179 | } 180 | s2up = stream2_get_udata(this); 181 | if ( s2up){ 182 | return s2up->s2u_flags; 183 | } else { 184 | return -1; 185 | } 186 | } 187 | /*******************************************************************************/ 188 | extern void log4c_stream2_set_flags(log4c_appender_t* this, int flags){ 189 | log4c_stream2_udata_t *s2up; 190 | 191 | if ( !this){ 192 | return; 193 | } 194 | s2up = stream2_get_or_make_udata(this); 195 | if ( !s2up){ 196 | return; 197 | } 198 | s2up->s2u_flags = flags; 199 | } 200 | 201 | /*******************************************************************************/ 202 | const log4c_appender_type_t log4c_appender_type_stream2 = { 203 | "stream2", 204 | stream2_open, 205 | stream2_append, 206 | stream2_close, 207 | }; 208 | 209 | -------------------------------------------------------------------------------- /src/log4c/layout.c: -------------------------------------------------------------------------------- 1 | static const char version[] = "$Id$"; 2 | 3 | /* 4 | * layout.c 5 | * 6 | * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved. 7 | * 8 | * See the COPYING file for the terms of usage and distribution. 9 | */ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | struct __log4c_layout 23 | { 24 | char* lo_name; 25 | const log4c_layout_type_t* lo_type; 26 | void* lo_udata; 27 | }; 28 | 29 | sd_factory_t* log4c_layout_factory = NULL; 30 | 31 | /** 32 | * @bug log4c_appender_type hash is not freed in destructor 33 | */ 34 | 35 | /*******************************************************************************/ 36 | static sd_hash_t* log4c_layout_types(void) 37 | { 38 | static sd_hash_t* types = NULL; 39 | 40 | if (!types) 41 | types = sd_hash_new(20, NULL); 42 | 43 | return types; 44 | } 45 | 46 | 47 | extern void log4c_layout_types_print(FILE *fp) 48 | { 49 | sd_hash_iter_t* i; 50 | 51 | fprintf(fp, "layout types:"); 52 | for (i = sd_hash_begin(log4c_layout_types()); 53 | i != sd_hash_end(log4c_layout_types()); 54 | i = sd_hash_iter_next(i) ) 55 | { 56 | fprintf(fp, "'%s' ",((log4c_layout_type_t *)(i->data))->name ); 57 | } 58 | fprintf(fp, "\n"); 59 | } 60 | 61 | /*******************************************************************************/ 62 | extern const log4c_layout_type_t* log4c_layout_type_get(const char* a_name) 63 | { 64 | sd_hash_iter_t* i; 65 | 66 | if (!a_name) 67 | return NULL; 68 | 69 | if ( (i = sd_hash_lookup(log4c_layout_types(), a_name)) != NULL) 70 | return i->data; 71 | 72 | return NULL; 73 | } 74 | 75 | /*******************************************************************************/ 76 | extern const log4c_layout_type_t* log4c_layout_type_set( 77 | const log4c_layout_type_t* a_type) 78 | { 79 | sd_hash_iter_t* i = NULL; 80 | void* previous = NULL; 81 | 82 | if (!a_type) 83 | return NULL; 84 | 85 | if ( (i = sd_hash_lookadd(log4c_layout_types(), a_type->name)) == NULL) 86 | return NULL; 87 | 88 | previous = i->data; 89 | i->data = (void*) a_type; 90 | 91 | return previous; 92 | } 93 | /*******************************************************************************/ 94 | extern log4c_layout_t* log4c_layout_get(const char* a_name) 95 | { 96 | static const sd_factory_ops_t log4c_layout_factory_ops = { 97 | (void*) log4c_layout_new, 98 | (void*) log4c_layout_delete, 99 | (void*) log4c_layout_print, 100 | }; 101 | 102 | if (!log4c_layout_factory) { 103 | log4c_layout_factory = sd_factory_new("log4c_layout_factory", 104 | &log4c_layout_factory_ops); 105 | /* build default layouts */ 106 | log4c_layout_set_type(log4c_layout_get("dated"), &log4c_layout_type_dated); 107 | log4c_layout_set_type(log4c_layout_get("basic"), &log4c_layout_type_basic); 108 | } 109 | 110 | return sd_factory_get(log4c_layout_factory, a_name); 111 | } 112 | 113 | /*******************************************************************************/ 114 | extern log4c_layout_t* log4c_layout_new(const char* a_name) 115 | { 116 | log4c_layout_t* this; 117 | 118 | if (!a_name) 119 | return NULL; 120 | 121 | this = sd_calloc(1, sizeof(log4c_layout_t)); 122 | this->lo_name = sd_strdup(a_name); 123 | this->lo_type = &log4c_layout_type_basic; 124 | this->lo_udata = NULL; 125 | 126 | return this; 127 | } 128 | 129 | /*******************************************************************************/ 130 | extern void log4c_layout_delete(log4c_layout_t* this) 131 | { 132 | if (!this) 133 | return; 134 | 135 | free(this->lo_name); 136 | free(this); 137 | } 138 | 139 | /*******************************************************************************/ 140 | extern const char* log4c_layout_get_name(const log4c_layout_t* this) 141 | { 142 | return (this ? this->lo_name : NULL); 143 | } 144 | 145 | /*******************************************************************************/ 146 | extern const log4c_layout_type_t* log4c_layout_get_type(const log4c_layout_t* this) 147 | { 148 | return (this ? this->lo_type : NULL); 149 | } 150 | 151 | /*******************************************************************************/ 152 | extern const log4c_layout_type_t* log4c_layout_set_type( 153 | log4c_layout_t* this, 154 | const log4c_layout_type_t* a_type) 155 | { 156 | const log4c_layout_type_t* previous; 157 | 158 | if (!this) 159 | return NULL; 160 | 161 | previous = this->lo_type; 162 | this->lo_type = a_type; 163 | return previous; 164 | } 165 | 166 | /*******************************************************************************/ 167 | extern void* log4c_layout_get_udata(const log4c_layout_t* this) 168 | { 169 | return (this ? this->lo_udata : NULL); 170 | } 171 | 172 | /*******************************************************************************/ 173 | extern void* log4c_layout_set_udata(log4c_layout_t* this, void* a_udata) 174 | { 175 | void* previous; 176 | 177 | if (!this) 178 | return NULL; 179 | 180 | previous = this->lo_udata; 181 | this->lo_udata = a_udata; 182 | return previous; 183 | } 184 | 185 | /*******************************************************************************/ 186 | extern const char* log4c_layout_format( 187 | const log4c_layout_t* this, 188 | const log4c_logging_event_t*a_event) 189 | { 190 | if (!this) 191 | return NULL; 192 | 193 | if (!this->lo_type) 194 | return NULL; 195 | 196 | if (!this->lo_type->format) 197 | return NULL; 198 | 199 | return this->lo_type->format(this, a_event); 200 | } 201 | 202 | /*******************************************************************************/ 203 | extern void log4c_layout_print(const log4c_layout_t* this, FILE* a_stream) 204 | { 205 | if (!this) 206 | return; 207 | 208 | fprintf(a_stream, "{ name:'%s' type:'%s' udata:%p }", 209 | this->lo_name, 210 | this->lo_type ? this->lo_type->name : "(no set)", 211 | this->lo_udata); 212 | } 213 | -------------------------------------------------------------------------------- /config/expat.m4: -------------------------------------------------------------------------------- 1 | # Configure paths for EXPAT 2 | # Owen Taylor 97-11-3 3 | 4 | dnl AM_PATH_EXPAT([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) 5 | dnl Test for EXPAT, and define EXPAT_CFLAGS and EXPAT_LIBS 6 | dnl 7 | AC_DEFUN([AM_PATH_EXPAT], 8 | [dnl 9 | dnl Get the cflags and libraries from the expat-config script 10 | dnl 11 | 12 | AC_ARG_WITH(expat-prefix, 13 | AC_HELP_STRING([--with-expat-prefix=PFX], 14 | [LOG4C: Prefix where EXPAT is installed (defaults to just 15 | looking in the standard library locations). If 16 | --without-expat is set to yes then this option has 17 | no effect)])) 18 | 19 | AC_ARG_ENABLE(expattest, 20 | AC_HELP_STRING([--disable-expattest], 21 | [LOG4C: Do not try to compile and run a test EXPAT program. 22 | (default is no). If without-expat is set to yes this 23 | option has no effect.]), 24 | , enable_expattest=yes) 25 | 26 | if test x$with_expat_prefix != x ; then 27 | EXPAT_CFLAGS="-I$with_expat_prefix/include" 28 | EXPAT_LIBS="-L$with_expat_prefix/lib" 29 | fi 30 | 31 | min_expat_version=ifelse([$1], ,1.95.1, $1) 32 | dnl AC_MSG_NOTICE([value of with_expat_prefix=$with_expat_prefix \ 33 | dnl value of with_expat=$with_expat]) 34 | AC_MSG_CHECKING(for EXPAT - version >= $min_expat_version) 35 | 36 | 37 | EXPAT_CFLAGS="$EXPAT_CFLAGS" 38 | EXPAT_LIBS="$EXPAT_LIBS -lexpat" 39 | 40 | if test "x$enable_expattest" = "xyes" ; then 41 | ac_save_CFLAGS="$CFLAGS" 42 | ac_save_LIBS="$LIBS" 43 | CFLAGS="$CFLAGS $EXPAT_CFLAGS" 44 | LIBS="$EXPAT_LIBS $LIBS" 45 | dnl 46 | dnl Now check if the installed EXPAT is sufficiently new. (Also sanity 47 | dnl checks the results of expat-config to some extent 48 | dnl 49 | rm -f conf.expattest 50 | AC_TRY_RUN([ 51 | #include 52 | #include 53 | #include 54 | #include 55 | 56 | int 57 | main () 58 | { 59 | int expat_major, expat_minor, expat_micro; 60 | int major, minor, micro; 61 | char *tmp_expat_version; 62 | char *tmp_version; 63 | 64 | system ("touch conf.expattest"); 65 | 66 | /* HP/UX 9 (%@#!) writes to sscanf strings */ 67 | tmp_expat_version = strdup(XML_ExpatVersion()); 68 | if (sscanf(tmp_expat_version, "expat_%d.%d.%d", &expat_major, &expat_minor, &expat_micro) != 3) { 69 | printf("%s, bad expat version string\n", XML_ExpatVersion()); 70 | exit(1); 71 | } 72 | 73 | /* HP/UX 9 (%@#!) writes to sscanf strings */ 74 | tmp_version = strdup("$min_expat_version"); 75 | if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { 76 | printf("%s, bad version string\n", "$min_expat_version"); 77 | exit(1); 78 | } 79 | 80 | if ((expat_major > major) || 81 | ((expat_major == major) && (expat_minor > minor)) || 82 | ((expat_major == major) && (expat_minor == minor) && (expat_micro >= micro))) 83 | { 84 | return 0; 85 | } 86 | else 87 | { 88 | printf("\n*** An old version of EXPAT (%d.%d.%d) was found.\n", 89 | expat_major, expat_minor, expat_micro); 90 | printf("*** You need a version of EXPAT newer than %d.%d.%d. The latest version of\n", 91 | major, minor, micro); 92 | printf("***\n"); 93 | printf("*** If you have already installed a sufficiently new version, this error\n"); 94 | printf("*** probably means that the wrong copy of the expat-config shell script is\n"); 95 | printf("*** being found. The easiest way to fix this is to remove the old version\n"); 96 | printf("*** of EXPAT, but you can also set the EXPAT_CONFIG environment to point to the\n"); 97 | printf("*** correct copy of expat-config. (In this case, you will have to\n"); 98 | printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n"); 99 | printf("*** so that the correct libraries are found at run-time))\n"); 100 | } 101 | return 1; 102 | } 103 | ],, no_expat=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) 104 | CFLAGS="$ac_save_CFLAGS" 105 | LIBS="$ac_save_LIBS" 106 | fi 107 | 108 | if test "x$no_expat" = x ; then 109 | AC_MSG_RESULT(yes) 110 | use_expat=yes 111 | ifelse([$2], , :, [$2]) 112 | else 113 | AC_MSG_RESULT(no) 114 | use_expat=no 115 | if test -f conf.expattest ; then 116 | : 117 | else 118 | echo "*** Could not run EXPAT test program, checking why..." 119 | CFLAGS="$CFLAGS $EXPAT_CFLAGS" 120 | LIBS="$LIBS $EXPAT_LIBS" 121 | AC_TRY_LINK([ 122 | #include 123 | #include 124 | ], [ return (XML_ExpatVersion()); ], 125 | [ echo "*** The test program compiled, but did not run. This usually means" 126 | echo "*** that the run-time linker is not finding EXPAT or finding the wrong" 127 | echo "*** version of EXPAT. If it is not finding EXPAT you can specify" 128 | echo "*** an install location using --with-expat-prefix option to" 129 | echo "*** configure. You can also set the " 130 | echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" 131 | echo "*** to the installed location Also, make sure you have run ldconfig if that" 132 | echo "*** is required on your system" 133 | echo "***" 134 | echo "*** If you have an old version installed, it is best to remove it, although" 135 | echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH" 136 | echo "***" 137 | echo "*** Log4C will still run without EXPAT--it uses some bundled" 138 | echo "*** lex/yacc code to parse the configuration file"], 139 | [ echo "*** The test program failed to compile or link. See the file config.log for the" 140 | echo "*** exact error that occured. This usually means EXPAT was incorrectly installed" 141 | echo "*** or that you have moved EXPAT since it was installed. In the latter case, you" 142 | echo "*** may want to edit the expat-config script: '$EXPAT_CONFIG'" 143 | echo "*** Log4C will still run without EXPAT--it uses some bundled" 144 | echo "*** lex/yacc code to parse the configuration file"]) 145 | CFLAGS="$ac_save_CFLAGS" 146 | LIBS="$ac_save_LIBS" 147 | fi 148 | EXPAT_CFLAGS="" 149 | EXPAT_LIBS="" 150 | ifelse([$3], , :, [$3]) 151 | fi 152 | AC_SUBST(EXPAT_CFLAGS) 153 | AC_SUBST(EXPAT_LIBS) 154 | rm -f conf.expattest 155 | ]) 156 | --------------------------------------------------------------------------------