There are a couple of problems with the tracing code shown in the previous section.
if(..) { trace(...); } fragments all over
the place.
We address these problems, we add the following macros
#ifndef TRACE_INT_STACK
#if( NTRACE )
#define TRACE_INT_STACK 0
#else
#define TRACE_INT_STACK 1
#endif
#endif
#if( TRACE_INT_STACK )
#define TRC(_p,_a0) \
((lcl_trace_int_stack != (_p))? ((void)0):\
trace( __FILE__, __LINE__, (_p), (_a0)))
#define TRC1(_p,_a0,_a1) \
((lcl_trace_int_stack != (_p))? ((void)0):\
trace( __FILE__, __LINE__, (_p), (_a0), (_a1)))
#else
#define TRC(_x,_a0) ((void)0)
#define TRC1(_x,_a0,_a1) ((void)0)
#endif
Using these macros the examples are written as:
int_stack
make_int_stack(void)
{
/* ... */
TRC(stack, "make_int_stack");
return stack;
}
void
push_int_stack(
int_stack stack,
int val
)
{
/* ... */
TRC1( stack, "push_int_stack %d", val);
/* ... */
}
Now lets examine the macros.
-D flags; therefore we use #ifndef TRACE_INT_STACK
-DNTRACE=1 to turn tracing off.
TRC() and TRC1() macros are defined to be do-nothings
((void)0) if TRACE_INT_STACK is 0.
TRACE_INT_STACK is 1, the TRC() and TRC1() macros
compare the stack against lcl_trace_int_stack,
and if equal, call trace() with the appropriate parameters.