/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.TYPE		Header
.NAME		trace.h
.LANGUAGE	C
.AUTHOR		Francois Ochsenbein [ESO], Alan Richmond [ST-ECF].
.CATEGORY 	General Definitions
.COMMENTS	Definition of tracing routines and macros.
		Note that TRACING equated to zero disables the tracing.
.ENVIRONMENT

.VERSION 1.0	01-Aug-1986: creation
		(Excerpt from original STESODEF file)
.VERSION 1.1	27-Jan-1987: Added confidentiality macros
		to avoid logging sensible data in the log file
.VERSION 1.2	25-Jun-1987: Minimal SW_level
.VERSION 1.3	01-Feb-1988: For Midas usage
.VERSION 1.4	08-May-1989: Added GetLevel() to retrieve max trace level.
			     M. Albrecht [ESIS] (see `#ifdef ESIS')
.VERSION 1.5	20-Jun-1989: Use NOTRACING option 
.VERSION 1.5	06-Oct-1989: pm_lfile / GetLog added.
------------------------------------------------------------*/

#ifndef TRACE_DEF
#define TRACE_DEF	0

#ifdef  NOTRACING
#define TRACING		0
#endif

#ifdef __STDC__
#define _ARGS(A)        A /* ANSI */
#else
#define _ARGS(A)        ()  /* non-ansi */
#endif

#ifndef TRACING
#  ifdef PM_LEVEL
#    define TRACING	1
#  else
#    define TRACING	0
#  endif
#endif


#define MONITOR(module)		static  int  status= 0

/*===========================================================================
 *             Levels of Components
 *===========================================================================*/

#define LEVEL_STR	31	/* Level for string-handling functions	*/
#define LEVEL_OS	30	/* OS-dependant routines		*/
#define LEVEL_OO	30	/* Object-Oriented routines		*/
#define LEVEL_FI	29	/* File interfaces			*/
#define LEVEL_TU	28	/* TermCap interfaces			*/
#define LEVEL_TV	27	/* Terminal Handling with TermCap	*/
#define LEVEL_TW	26	/* TermWindows functions		*/
#define LEVEL_TX	25	/* TermDisplay				*/
#define LEVEL_TH	24	/* TermHelp				*/
#define LEVEL_TA	24	/* TermHelp				*/
#define LEVEL_TF	23	/* Forms				*/

#define LEVEL_FITS	 6	/* IHAP tranformations			*/
#define LEVEL_IHAP	 5	/* IHAP tranformations			*/
#define LEVEL_X25	 5	/* X25 communications			*/
#define LEVEL_SW	 6	/* Software parsing			*/

/*===========================================================================
 *		Function Templates
 *===========================================================================*/
int 	 pm_get_depth 	_ARGS((void));		/* Current depth	*/
int 	 pm_sensible 	_ARGS((int true_false));
int 	 pm_set_depth 	_ARGS((int max_tracing_depth));	
int 	 pm_fetch 	_ARGS((char *function, int max_tracing_depth));
int 	 pm_unfetch 	_ARGS((char *function));
int 	 pm_open 	_ARGS((char *filename, char *title));
int 	 pm_close 	_ARGS((void));
int 	 pm_level	_ARGS((int tracing_level));
int 	 pm_stop	_ARGS((int tracing_level));
int 	 pm_enter 	_ARGS((int level, char *function));
int 	 pm_iexit 	_ARGS((int level, int status));
long  	 pm_lexit 	_ARGS((int level,long status));
char   	*pm_pexit 	_ARGS((int level,char *status));
int 	 pm_history 	_ARGS((void));
int 	 pm_trace 	_ARGS((int level, char *text));
int 	 pm_tr2 	_ARGS((int level, char *text, int text_length));
int 	 pm_ed_trace  	_ARGS((int level, char *text, char *string));
int 	 pm_ed_tr2 	_ARGS((int level, char *text, char *string,int string_length));
int 	 pm_ed_i 	_ARGS((int level, char *text, int value));
int 	 pm_log 	_ARGS((char *string));
int 	 pm_comment 	_ARGS((char *string));
int 	 pm_get_level	_ARGS((void));
int 	 pm_lfile	_ARGS((void));
int 	 pm_islev	_ARGS((int level_to_check));

/*===========================================================================
 *			Tracing Definitions
 *===========================================================================*/

#define OpenLog(filename,title)	pm_open(filename,title)
#define GetLog()		pm_lfile()
#define CloseLog()		pm_close()
#define Confidential(x)		pm_sensible(x)
#define ConfidentialOn()	pm_sensible(1)
#define ConfidentialOff()	pm_sensible(0)

#define TraceOn(level)		pm_level(level)
#define TraceOff(level)		pm_stop(level)
#define TraceUntil(depth)	pm_set_depth(depth)
#define LogLevel		TraceOn
#define LogHistory()		pm_history()

#define TraceRoutine(f)		pm_fetch(f,0)
#define TraceRoutineUntil(f,d)	pm_fetch(f,d)
#define UntraceRoutine(f)	pm_unfetch(f)

#define GetDepth()		pm_get_depth()
#define GetLevel()		pm_get_level()
#define CheckTracing(lev)	pm_islev(lev)

/*===========================================================================
 *		TRACING Macros always valid
 *===========================================================================*/

#define ENTER_			ENTER
#define EXIT			EXITi
#define _EXIT			EXIT_PTR
#define TRACE			TRACE_STRING

#if TRACING
/*===========================================================================
 *		Tracing Definitions if Tracing is ON
 *===========================================================================*/

#define ENTER(fct)		pm_enter(PM_LEVEL,fct)	 		\
		/* Pass the function name 		*/
#define EXITi(code)		return( pm_iexit (PM_LEVEL,code))	\
		/* Pass the completion code 		*/
#define EXITl(code)		return(pm_lexit(PM_LEVEL,code))		\
		/* Pass the completion code 		*/
#define EXITp(code)		return( pm_pexit (PM_LEVEL,code))	\
		/* Pass the completion code 		*/
#define EXIT_PTR(t,code)	return((t *)pm_pexit(PM_LEVEL,(char *)code))\
		/* Pass the completion code 		*/
#define EXIT_CAST(t,code)	return((t)pm_pexit(PM_LEVEL,(char *)code))\
		/* Pass the completion code 		*/
#define TRACE_STR2(text,l)	pm_tr2(PM_LEVEL,text,l)            	\
		/* Trace a string of length l		*/
#define TRACE_TEXT(text)	pm_tr2(PM_LEVEL,text,sizeof(text)-1)	\
		/* Trace a constant string text		*/
#define TRACE_STRING(text)	pm_trace(PM_LEVEL,text) 		\
		/* Trace an EOS-terminated string 	*/
#define TRACE_ED_TEXT(t,s)	pm_ed_str2(PM_LEVEL,t,s,sizeof(s)-1)	\
		/* Trace a text followed by a string  	*/
#define TRACE_ED_STRING(t,s)	pm_ed_trace(PM_LEVEL,t,s)		\
		/* Trace a text followed by a string  	*/
#define TRACE_ED_STR2(t,s,l)	pm_ed_tr2(PM_LEVEL,t,s,l)		\
		/* Trace a text followed by a string  	*/
#define TRACE_ED_I(t,i)		pm_ed_i   (PM_LEVEL,t,i)		\
		/* Trace a text followed by a number  	*/

#define LOG(string)		pm_log (string) 			 \
		/* Log a string				*/
#define LOG_COMMENT(string)	pm_comment (string)			 \
		/* Log a comment string			*/
#define LOG_ED_TEXT(t,s)	pm_ed_str2(-1,t,s,sizeof(s)-1)	\
		/* Log a text followed by a string  	*/
#define LOG_ED_STRING(t,s)	pm_ed_trace(-1,t,s)		\
		/* Log a text followed by a string  	*/
#define LOG_ED_STR2(t,s,l)	pm_ed_tr2(-1,t,s,l)		\
		/* Log a text followed by a string  	*/
#define LOG_ED_I(t,i)		pm_ed_i   (-1,t,i)		\
		/* Log a text followed by a number  	*/

#else		/* Suppress Tracing			*/
/*===========================================================================
 *		Tracing Definitions if Tracing is OFF
 *===========================================================================*/
#include <stdio.h>

#define ENTER(fct)
#define EXITi(code)		return(code)
#define EXITl(code)		return(code)
#define EXITp(code)		return(code)
#define EXIT_PTR(t,code)	return((t *)code)
#define EXIT_CAST(t,code)	return((t)code)
#define TRACE_STR2(text,l)
#define TRACE_TEXT(text)
#define TRACE_STRING(text)
#define TRACE_ED_TEXT(t,s)
#define TRACE_ED_STRING(t,s)
#define TRACE_ED_STR2(t,s,l)
#define TRACE_ED_I(t,i)

#define LOG(string)		fprintf(stderr, "%s\n", string)
#define LOG_COMMENT(string)	fprintf(stderr, "!s\n", string)
#define LOG_ED_TEXT(t,s)	fprintf(stderr, "%s: ", t), \
				fwrite(s,1,sizeof(s)-1,stderr), \
				fputc('\n',stderr)
#define LOG_ED_STRING(t,s)	fprintf(stderr,"%s: %s\n", t,s)
#define LOG_ED_STR2(t,s,l)	fprintf(stderr, "%s: ", t), \
				fwrite(s,1,l,,stderr), fputc('\n',stderr)
#define LOG_ED_I(t,i)		fprintf(stderr,"%s: %d\n", t, i)
#endif

#endif
