/*
#ident	"@(#)smail/src:RELEASE-3_2_0_115:debug.h,v 1.18 2002/08/21 19:11:51 woods Exp"
 */

/*
 *    Copyright (C) 1987, 1988 Ronald S. Karr and Landon Curt Noll
 *    Copyright (C) 1992  Ronald S. Karr
 * 
 * See the file COPYING, distributed with smail, for restriction
 * and warranty information.
 */

/*
 * debug.h:
 *	macros used to generate debugging output.
 */

/*
 * first set up debugging malloc support if desired...
 */

/*
 * SunOS-4 has a /usr/lib/malloc/debug.o which must be included in the list of
 * objects linked with the program under test.
 */
#ifdef USE_SUNOS4_MALLOC_DEBUG
# define MALLOC_DEBUG_OFF		0
# define MALLOC_DEBUG_NORMAL		1
# define MALLOC_DEBUG_FULL		2
# define MALLOC_DEBUG_EXTREME		2 /* not supported on SunOS-4 */
# define MALLOC_DEBUG(level)		malloc_debug(level)
# define MALLOC_VERIFY_NORMAL		0
# define MALLOC_VERIFY_FULLCHECK	0 /* not supported on SunOS-4 */
# define MALLOC_VERIFY(fullcheck)	malloc_verify()
#endif

/*
 * The Moraes Malloc builds with a debugging version that must be linked with
 * '-lmalloc_d' prior to including '-lc'.
 */
#ifdef USE_MORAES_MALLOC_DEBUG
# define MALLOC_DEBUG_OFF		1 /* not supported in -lmalloc_d */
# define MALLOC_DEBUG_NORMAL		1 /* no mal_verify() */
# define MALLOC_DEBUG_FULL		2 /* mal_verify(0) */
# define MALLOC_DEBUG_EXTREME		3 /* mal_verify(1) */
# define MALLOC_DEBUG(level)		mal_debug(level)
# define MALLOC_VERIFY_NORMAL		0
# define MALLOC_VERIFY_FULLCHECK	1
# define MALLOC_VERIFY(fullcheck)	mal_verify(fullcheck)
#endif

/*
 * The Vmalloc package builds with a debugging version that must be linked with
 * '-lvmalloc' prior to including '-lc'.
 *
 * Add '-DVMFL' to enable printing of source filenames and line numbers in
 * trace and debug output.
 *
 * Debugging is turned on by setting the environment variable "VMETHOD=Vmdebug".
 *
 * Debugging can cause an abort() if "VMDEBUG=a" is set.  See vmalloc(3) for
 * more info.
 *
 * Full tracing can be turned on by setting "VMTRACE=/tmp/vmalloc.trace.%p"
 * (where the '%p' is replaced by the process-ID of the running process)
 *
 * Full profiling can be turned on by setting "VMETHOD=Vmprofile" and
 * "VMPROFILE=/tmp/vmalloc.profile.%p" (where the '%p' is replaced by the
 * process-ID of the running process)
 */
#ifdef USE_VMALLOC
# define MALLOC_DEBUG_OFF		0
# define MALLOC_DEBUG_NORMAL		0
# define MALLOC_DEBUG_FULL		0
# define MALLOC_DEBUG_EXTREME		0
# define MALLOC_DEBUG(level)		/*  */
# define MALLOC_VERIFY_NORMAL		0
# define MALLOC_VERIFY_FULLCHECK	0
# define MALLOC_VERIFY(fullcheck)	vmdbcheck(Vmheap)
#endif

/* XXX could also use "ifndef MALLOC_DEBUG_OFF" or some such... */
#if !defined(USE_SUNOS4_MALLOC_DEBUG) && !defined(USE_MORAES_MALLOC_DEBUG) && !defined(USE_VMALLOC)
# define MALLOC_DEBUG_OFF		0
# define MALLOC_DEBUG_NORMAL		0
# define MALLOC_DEBUG_FULL		0
# define MALLOC_DEBUG_EXTREME		0
# define MALLOC_DEBUG(level)		/* No-OP */
# define MALLOC_VERIFY_NORMAL		0
# define MALLOC_VERIFY_FULLCHECK	0
# define MALLOC_VERIFY(fullcheck)	/* No-OP */
#endif

#ifndef MALLOC_DEBUG_LEVEL
# define MALLOC_DEBUG_LEVEL		MALLOC_DEBUG_NORMAL
#endif

#ifndef MALLOC_VERIFY_LEVEL
# define MALLOC_VERIFY_LEVEL		MALLOC_VERIFY_FULLCHECK
#endif

/*
 * define a macro hook to ease insertion of verifies in every DEBUG*() macro
 */
#ifdef MALLOC_VERIFY_EVERY_DEBUG
# define MALLOC_DEBUG_HOOK(fullcheck)	MALLOC_VERIFY(fullcheck)
#else
# define MALLOC_DEBUG_HOOK(fullcheck)	/* No-OP */
#endif

/*
 * If the current debug level is above d, output the message, otherwise
 * be silent.
 */
#ifndef NODEBUG
# define DEBUG(d,m) \
     {							\
	if ((d) <= debug && errfile) {			\
	    MALLOC_DEBUG_HOOK(MALLOC_VERIFY_LEVEL);	\
	    (void)fputs((m),errfile);			\
	    (void)fflush(errfile);			\
	}						\
     }
# define DEBUG1(d,m,a) \
    {							\
	if ((d) <= debug && errfile) {			\
	    MALLOC_DEBUG_HOOK(MALLOC_VERIFY_LEVEL);	\
	    (void)dprintf(errfile,(m),(a));		\
	    (void)fflush(errfile);			\
	}						\
    }
# define DEBUG2(d,m,a,b) \
    {							\
	if ((d) <= debug && errfile) {			\
	    MALLOC_DEBUG_HOOK(MALLOC_VERIFY_LEVEL); 	\
	    (void)dprintf(errfile,(m),(a),(b));		\
	    (void)fflush(errfile);			\
	}						\
    }
# define DEBUG3(d,m,a,b,c) \
    {							\
	if ((d) <= debug && errfile) {			\
	    MALLOC_DEBUG_HOOK(MALLOC_VERIFY_LEVEL); 	\
	    (void)dprintf(errfile,(m),(a),(b),(c));	\
	    (void)fflush(errfile);			\
	}						\
    }
# define DEBUG4(d,m,a,b,c,e) \
    {							\
	if ((d) <= debug && errfile) {			\
	    MALLOC_DEBUG_HOOK(MALLOC_VERIFY_LEVEL); 	\
	    (void)dprintf(errfile,(m),(a),(b),(c),(e));	\
	    (void)fflush(errfile);			\
	}						\
    }
# define DEBUG5(d,m,a,b,c,e,f) \
    {								\
	if ((d) <= debug && errfile) {				\
	    MALLOC_DEBUG_HOOK(MALLOC_VERIFY_LEVEL); 		\
	    (void)dprintf(errfile,(m),(a),(b),(c),(e),(f));	\
	    (void)fflush(errfile);				\
	}							\
    }
# define DEBUG6(d,m,a,b,c,e,f,g) \
    {								\
	if ((d) <= debug && errfile) {				\
	    MALLOC_DEBUG_HOOK(MALLOC_VERIFY_LEVEL); 		\
	    (void)dprintf(errfile,(m),(a),(b),(c),(e),(f),(g));	\
	    (void)fflush(errfile);				\
	}							\
    }
# define DEBUG7(d,m,a,b,c,e,f,g,h) \
    {								\
	if ((d) <= debug && errfile) {				\
	    MALLOC_DEBUG_HOOK(MALLOC_VERIFY_LEVEL); 		\
	    (void)dprintf(errfile,(m),(a),(b),(c),(e),(f),(g),(h));\
	    (void)fflush(errfile);				\
	}							\
    }
# define DEBUG8(d,m,a,b,c,e,f,g,h,i) \
    {								\
	if ((d) <= debug && errfile) {				\
	    MALLOC_DEBUG_HOOK(MALLOC_VERIFY_LEVEL); 		\
	    (void)dprintf(errfile,(m),(a),(b),(c),(e),(f),(g),(h),(i));\
	    (void)fflush(errfile);				\
	}							\
    }
# define DEBUG9(d,m,a,b,c,e,f,g,h,i,j) \
    {								\
	if ((d) <= debug && errfile) {				\
	    MALLOC_DEBUG_HOOK(MALLOC_VERIFY_LEVEL); 		\
	    (void)dprintf(errfile,(m),(a),(b),(c),(e),(f),(g),(h),(i),(j));\
	    (void)fflush(errfile);				\
	}							\
    }
#else	/* NODEBUG */
# define DEBUG(d,m)
# define DEBUG1(d,m,a)
# define DEBUG2(d,m,a,b)
# define DEBUG3(d,m,a,b,c)
# define DEBUG4(d,m,a,b,c,e)
# define DEBUG5(d,m,a,b,c,e,f)
# define DEBUG6(d,m,a,b,c,e,f,g)
# define DEBUG7(d,m,a,b,c,e,f,g,h)
# define DEBUG8(d,m,a,b,c,e,f,g,h,i)
# define DEBUG9(d,m,a,b,c,e,f,g,h,i,j)
#endif	/* NODEBUG */

/*
 * put various debug levels here so that we can change this file and
 * recompile, rather than changing the DEBUG statements themselves to
 * concentrate on a particular routine
 */

/* debug levels for functions in field.c */
#define DBG_FIELD_HI	50
#define DBG_FIELD_MID	9
#define DBG_FIELD_LO	6

/* debug levels for functions in addr.c */
#define DBG_ADDR_HI	50
#define DBG_ADDR_MID	9
#define DBG_ADDR_LO	6

/* debug levels for functions in log.c */
#define DBG_LOG_HI	50
#define DBG_LOG_MID	5
#define DBG_LOG_LO	1

/* debug levels for functions in queue.c */
#define DBG_QUEUE_HI	50
#define DBG_QUEUE_MID	5
#define DBG_QUEUE_LO	1

/* debug levels for functions in retry.c */
#define DBG_RETRY_HI	50
#define DBG_RETRY_MID	5
#define DBG_RETRY_LO	1

/* debug levels for functions in spool.c */
#define DBG_SPOOL_HI	50
#define DBG_SPOOL_MID	5
#define DBG_SPOOL_LO	1

/* debug levels for functions in header.c */
#define DBG_HEADER_HI	50
#define DBG_HEADER_MID	9
#define DBG_HEADER_LO	6

/* debug levels for directing code in direct.c */
#define DBG_DIRECT_HI	50
#define DBG_DIRECT_MID	8
#define DBG_DIRECT_LO	1

/* debug levels for routing code in route.c */
#define DBG_ROUTE_HI	50
#define DBG_ROUTE_MID	8
#define DBG_ROUTE_LO	1

/* debug levels for main code in main.c */
#define DBG_MAIN_HI	50
#define DBG_MAIN_MID	8
#define DBG_MAIN_LO	1

/* debug levels for notification code in notify.c */
#define DBG_NOTIFY_HI	50
#define DBG_NOTIFY_MID	5
#define DBG_NOTIFY_LO	1

/* debug levels for drivers */
#define DBG_DRIVER_HI	20
#define DBG_DRIVER_MID	2
#define DBG_DRIVER_LO	1

/* debug levels for resolving code in resolve.c */
#define DBG_RESOLVE_HI	50
#define DBG_RESOLVE_MID	8
#define DBG_RESOLVE_LO	1

/* debug levels for remote delivery code in remote.c */
#define DBG_REMOTE_HI	50
#define DBG_REMOTE_MID	5
#define DBG_REMOTE_LO	1

/* debug levels for aliasing code in alias.c */
#define DBG_ALIAS_HI	50
#define DBG_ALIAS_MID	8
#define DBG_ALIAS_LO	1

/* debug levels for hasing code in hash.c */
#define DBG_HASH_VHI   120
#define DBG_HASH_HI	90
#define DBG_HASH_MID	60
#define DBG_HASH_LO	30

/* debug levels for startup file processing code in startup.c */
#define DBG_STARTUP_HI	50
#define DBG_STARTUP_MID	25
#define DBG_STARTUP_LO	10

/* debug levels for startup file generation code in smailconf.c */
#define DBG_CONF_HI	50
#define DBG_CONF_MID	11
#define DBG_CONF_LO	1

/*
 * variables exported by main.c but used primarily only by debug.h
 */
extern int debug;			/* debugging level, 0 is off */
extern FILE *errfile;			/* file to write debug messages to */

/*
 * external functions defined in string.c but used primarily only by debug.h
 */
extern int dprintf __P((FILE *, char *, ...));
