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