1 /* $Id: log.h,v 1.2 2009/08/30 13:23:39 fredette Exp $ */ 2 3 /* tme/log.h - public header file for logging: */ 4 5 /* 6 * Copyright (c) 2003 Matt Fredette 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed by Matt Fredette. 20 * 4. The name of the author may not be used to endorse or promote products 21 * derived from this software without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 27 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 31 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 32 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36 #ifndef _TME_LOG_H 37 #define _TME_LOG_H 38 39 #include <tme/common.h> 40 _TME_RCSID("$Id: log.h,v 1.2 2009/08/30 13:23:39 fredette Exp $"); 41 42 /* includes: */ 43 44 /* macros: */ 45 46 /* if TME_NO_LOG has been specified, shut down all logging except for 47 level zero: */ 48 #ifdef TME_NO_LOG 49 #undef TME_LOG_LEVEL_MAX 50 #define TME_LOG_LEVEL_MAX (0) 51 #endif /* TME_NO_LOG */ 52 53 /* non-ancient GCCs can check the arguments to our printf-like 54 functions: */ 55 #if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5)) 56 #define __tme_printf_attribute __attribute__ ((format (printf, 2, 3))) 57 #else 58 #define __tme_printf_attribute 59 #endif 60 61 /* log modes: */ 62 #define TME_LOG_MODE_TEXT (0) 63 #define TME_LOG_MODE_BINARY (1) 64 65 /* maximum message sizes: */ 66 #define TME_LOG_MESSAGE_SIZE_MAX_BINARY (1024) 67 68 /* a logging handle: */ 69 struct tme_log_handle { 70 71 /* the maximum log level output: */ 72 unsigned long tme_log_handle_level_max; 73 74 /* the log level of this message: */ 75 unsigned long tme_log_handle_level; 76 77 /* the log message: */ 78 char *tme_log_handle_message; 79 unsigned long tme_log_handle_message_size; 80 81 /* any errno with this message: */ 82 int tme_log_handle_errno; 83 84 /* the interface's private data: */ 85 void *tme_log_handle_private; 86 87 /* the interface's log output function: */ 88 void (*tme_log_handle_output) _TME_P((struct tme_log_handle *)); 89 90 /* the mode of this handle: */ 91 unsigned int tme_log_handle_mode; 92 93 /* a format hash: */ 94 struct _tme_hash *tme_log_handle_hash_format; 95 }; 96 97 /* prototypes and macros: */ 98 99 /* this starts logging a message: */ 100 #ifdef TME_LOG_LEVEL_MAX 101 #define _tme_log_start(handle, level) \ 102 ((level) <= TME_LOG_LEVEL_MAX \ 103 && (level) <= (handle)->tme_log_handle_level_max) 104 #else /* !TME_LOG_LEVEL_MAX */ 105 #define _tme_log_start(handle, level) \ 106 ((level) <= (handle)->tme_log_handle_level_max) 107 #endif /* !TME_LOG_LEVEL_MAX */ 108 #define tme_log_start(handle, level, rc) \ 109 do { \ 110 if (_tme_log_start(handle, level)) { \ 111 (handle)->tme_log_handle_level = (level); \ 112 (handle)->tme_log_handle_errno = (rc); \ 113 do 114 115 /* this logs (part of) the body of a message: */ 116 void tme_log_part _TME_P((struct tme_log_handle *, _tme_const char *, ...)) __tme_printf_attribute; 117 118 /* this finishes logging a message: */ 119 #define tme_log_finish(handle) \ 120 while (/* CONSTCOND */ 0); \ 121 (*(handle)->tme_log_handle_output)(handle); \ 122 } \ 123 } while (/* CONSTCOND */ 0) 124 125 /* this handles all of the logging of a message: */ 126 #define tme_log(handle, level, rc, x) \ 127 do { \ 128 tme_log_start(handle, level, rc) { \ 129 tme_log_part x; \ 130 } tme_log_finish(handle); \ 131 } while (/* CONSTCOND */ 0) 132 133 /* these collect output: */ 134 void tme_output_append_raw _TME_P((char **, const char *, unsigned int)); 135 void tme_output_prepend_raw _TME_P((char **, const char *, unsigned int)); 136 void tme_output_append _TME_P((char **, const char *, ...)) __tme_printf_attribute; 137 void tme_output_prepend _TME_P((char **, const char *, ...)) __tme_printf_attribute; 138 void tme_output_append_error _TME_P((char **, const char *, ...)) __tme_printf_attribute; 139 void tme_output_prepend_error _TME_P((char **, const char *, ...)) __tme_printf_attribute; 140 141 #endif /* !_TME_LOG_H */ 142