1 /* 2 * Copyright (c) 2000, 2001, 2003 Sendmail, Inc. and its suppliers. 3 * All rights reserved. 4 * 5 * By using this file, you agree to the terms and conditions set 6 * forth in the LICENSE file which can be found at the top level of 7 * the sendmail distribution. 8 * 9 * $Id: debug.h,v 1.16 2003/01/10 00:26:06 ca Exp $ 10 */ 11 12 #pragma ident "%Z%%M% %I% %E% SMI" 13 14 /* 15 ** libsm debugging and tracing 16 ** See libsm/debug.html for documentation. 17 */ 18 19 #ifndef SM_DEBUG_H 20 # define SM_DEBUG_H 21 22 # include <sm/gen.h> 23 # include <sm/io.h> 24 25 /* 26 ** abstractions for printing trace messages 27 */ 28 29 extern SM_FILE_T * 30 sm_debug_file __P((void)); 31 32 extern void 33 sm_debug_setfile __P(( SM_FILE_T *)); 34 35 extern void PRINTFLIKE(1, 2) 36 sm_dprintf __P((char *_fmt, ...)); 37 38 extern void 39 sm_dflush __P((void)); 40 41 extern void 42 sm_debug_close __P((void)); 43 44 /* 45 ** abstractions for setting and testing debug activation levels 46 */ 47 48 extern void 49 sm_debug_addsettings_x __P((const char *)); 50 51 extern void 52 sm_debug_addsetting_x __P((const char *, int)); 53 54 # define SM_DEBUG_UNKNOWN ((SM_ATOMIC_UINT_T)(-1)) 55 56 extern const char SmDebugMagic[]; 57 58 typedef struct sm_debug SM_DEBUG_T; 59 struct sm_debug 60 { 61 const char *sm_magic; /* points to SmDebugMagic */ 62 63 /* 64 ** debug_level is the activation level of this debug 65 ** object. Level 0 means no debug activity. 66 ** It is initialized to SM_DEBUG_UNKNOWN, which indicates 67 ** that the true value is unknown. If debug_level == 68 ** SM_DEBUG_UNKNOWN, then the access functions will look up 69 ** its true value in the internal table of debug settings. 70 */ 71 72 SM_ATOMIC_UINT_T debug_level; 73 74 /* 75 ** debug_name is the name used to reference this SM_DEBUG 76 ** structure via the sendmail -d option. 77 */ 78 79 char *debug_name; 80 81 /* 82 ** debug_desc is a literal character string of the form 83 ** "@(#)$Debug: <name> - <short description> $" 84 */ 85 86 char *debug_desc; 87 88 /* 89 ** We keep a linked list of initialized SM_DEBUG structures 90 ** so that when sm_debug_addsetting is called, we can reset 91 ** them all back to the uninitialized state. 92 */ 93 94 SM_DEBUG_T *debug_next; 95 }; 96 97 # ifndef SM_DEBUG_CHECK 98 # define SM_DEBUG_CHECK 1 99 # endif /* ! SM_DEBUG_CHECK */ 100 101 # if SM_DEBUG_CHECK 102 /* 103 ** This macro is cleverly designed so that if the debug object is below 104 ** the specified level, then the only overhead is a single comparison 105 ** (except for the first time this macro is invoked). 106 */ 107 108 # define sm_debug_active(debug, level) \ 109 ((debug)->debug_level >= (level) && \ 110 ((debug)->debug_level != SM_DEBUG_UNKNOWN || \ 111 sm_debug_loadactive(debug, level))) 112 113 # define sm_debug_level(debug) \ 114 ((debug)->debug_level == SM_DEBUG_UNKNOWN \ 115 ? sm_debug_loadlevel(debug) : (debug)->debug_level) 116 117 # define sm_debug_unknown(debug) ((debug)->debug_level == SM_DEBUG_UNKNOWN) 118 # else /* SM_DEBUG_CHECK */ 119 # define sm_debug_active(debug, level) 0 120 # define sm_debug_level(debug) 0 121 # define sm_debug_unknown(debug) 0 122 # endif /* SM_DEBUG_CHECK */ 123 124 extern bool 125 sm_debug_loadactive __P((SM_DEBUG_T *, int)); 126 127 extern int 128 sm_debug_loadlevel __P((SM_DEBUG_T *)); 129 130 # define SM_DEBUG_INITIALIZER(name, desc) { \ 131 SmDebugMagic, \ 132 SM_DEBUG_UNKNOWN, \ 133 name, \ 134 desc, \ 135 NULL} 136 137 #endif /* ! SM_DEBUG_H */ 138