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.