1N/A/*
1N/A * Copyright (c) 2000, 2001, 2003 Sendmail, Inc. and its suppliers.
1N/A * All rights reserved.
1N/A *
1N/A * By using this file, you agree to the terms and conditions set
1N/A * forth in the LICENSE file which can be found at the top level of
1N/A * the sendmail distribution.
1N/A *
1N/A * $Id: debug.h,v 1.16 2003/01/10 00:26:06 ca Exp $
1N/A */
1N/A
1N/A#pragma ident "%Z%%M% %I% %E% SMI"
1N/A
1N/A/*
1N/A** libsm debugging and tracing
1N/A** See libsm/debug.html for documentation.
1N/A*/
1N/A
1N/A#ifndef SM_DEBUG_H
1N/A# define SM_DEBUG_H
1N/A
1N/A# include <sm/gen.h>
1N/A# include <sm/io.h>
1N/A
1N/A/*
1N/A** abstractions for printing trace messages
1N/A*/
1N/A
1N/Aextern SM_FILE_T *
1N/Asm_debug_file __P((void));
1N/A
1N/Aextern void
1N/Asm_debug_setfile __P(( SM_FILE_T *));
1N/A
1N/Aextern void PRINTFLIKE(1, 2)
1N/Asm_dprintf __P((char *_fmt, ...));
1N/A
1N/Aextern void
1N/Asm_dflush __P((void));
1N/A
1N/Aextern void
1N/Asm_debug_close __P((void));
1N/A
1N/A/*
1N/A** abstractions for setting and testing debug activation levels
1N/A*/
1N/A
1N/Aextern void
1N/Asm_debug_addsettings_x __P((const char *));
1N/A
1N/Aextern void
1N/Asm_debug_addsetting_x __P((const char *, int));
1N/A
1N/A# define SM_DEBUG_UNKNOWN ((SM_ATOMIC_UINT_T)(-1))
1N/A
1N/Aextern const char SmDebugMagic[];
1N/A
1N/Atypedef struct sm_debug SM_DEBUG_T;
1N/Astruct sm_debug
1N/A{
1N/A const char *sm_magic; /* points to SmDebugMagic */
1N/A
1N/A /*
1N/A ** debug_level is the activation level of this debug
1N/A ** object. Level 0 means no debug activity.
1N/A ** It is initialized to SM_DEBUG_UNKNOWN, which indicates
1N/A ** that the true value is unknown. If debug_level ==
1N/A ** SM_DEBUG_UNKNOWN, then the access functions will look up
1N/A ** its true value in the internal table of debug settings.
1N/A */
1N/A
1N/A SM_ATOMIC_UINT_T debug_level;
1N/A
1N/A /*
1N/A ** debug_name is the name used to reference this SM_DEBUG
1N/A ** structure via the sendmail -d option.
1N/A */
1N/A
1N/A char *debug_name;
1N/A
1N/A /*
1N/A ** debug_desc is a literal character string of the form
1N/A ** "@(#)$Debug: <name> - <short description> $"
1N/A */
1N/A
1N/A char *debug_desc;
1N/A
1N/A /*
1N/A ** We keep a linked list of initialized SM_DEBUG structures
1N/A ** so that when sm_debug_addsetting is called, we can reset
1N/A ** them all back to the uninitialized state.
1N/A */
1N/A
1N/A SM_DEBUG_T *debug_next;
1N/A};
1N/A
1N/A# ifndef SM_DEBUG_CHECK
1N/A# define SM_DEBUG_CHECK 1
1N/A# endif /* ! SM_DEBUG_CHECK */
1N/A
1N/A# if SM_DEBUG_CHECK
1N/A/*
1N/A** This macro is cleverly designed so that if the debug object is below
1N/A** the specified level, then the only overhead is a single comparison
1N/A** (except for the first time this macro is invoked).
1N/A*/
1N/A
1N/A# define sm_debug_active(debug, level) \
1N/A ((debug)->debug_level >= (level) && \
1N/A ((debug)->debug_level != SM_DEBUG_UNKNOWN || \
1N/A sm_debug_loadactive(debug, level)))
1N/A
1N/A# define sm_debug_level(debug) \
1N/A ((debug)->debug_level == SM_DEBUG_UNKNOWN \
1N/A ? sm_debug_loadlevel(debug) : (debug)->debug_level)
1N/A
1N/A# define sm_debug_unknown(debug) ((debug)->debug_level == SM_DEBUG_UNKNOWN)
1N/A# else /* SM_DEBUG_CHECK */
1N/A# define sm_debug_active(debug, level) 0
1N/A# define sm_debug_level(debug) 0
1N/A# define sm_debug_unknown(debug) 0
1N/A# endif /* SM_DEBUG_CHECK */
1N/A
1N/Aextern bool
1N/Asm_debug_loadactive __P((SM_DEBUG_T *, int));
1N/A
1N/Aextern int
1N/Asm_debug_loadlevel __P((SM_DEBUG_T *));
1N/A
1N/A# define SM_DEBUG_INITIALIZER(name, desc) { \
1N/A SmDebugMagic, \
1N/A SM_DEBUG_UNKNOWN, \
1N/A name, \
1N/A desc, \
1N/A NULL}
1N/A
1N/A#endif /* ! SM_DEBUG_H */