home *** CD-ROM | disk | FTP | other *** search
- Listing 1
-
- #include <stdlib.h>
- #include <signal.h>
- #include "trace.h"
-
- void
- loopChar()
- {
- Trace trace = "::loopChar";
- int c;
-
- trace( "entering loop" );
- while ((c = getchar()) != EOF) {
- putchar(c);
- }
- trace( "exiting loop" );
- }
-
- void
- main( int argc, char *argv[] )
- {
- Trace trace = "::main";
- int c;
- extern int optind;
- extern char *optarg;
-
- trace( info, "The address of trace is %X", &trace );
- trace( info, "The address of c is %X", &c );
- trace( info, "The address of optind is %X", &optind );
- while ( (c = getopt( argc, argv, "d:i" ) ) != -1 ) {
- switch ( c ) {
- case 'd':
- trace( "changing trace mode" );
- trace.setTraceMode( atoi( optarg ) );
- break;
- case 'i':
- trace( "ignoring interrupts" );
- signal( SIGINT, SIG_IGN );
- break;
- case '?':
- trace( error, "aborting due to invalid option" );
- exit( 1 );
- }
- }
- assert( trace, optind == argc );
- loopChar();
- trace( "Good bye" );
- }
- end listing 1
-
-
- Listing 2
- /*
- * Copyright (c) 1989 Marco S. Hyman
- *
- * Permission to copy all or part of this material is granted
- * provided that the original copyright notice and its date
- * appear and notice is given that copying is by permission of
- * the original author.
- *
- */
-
- /*
- Class: Trace
-
- Requires: stdio, stdarg, stdlib
-
- Description:
-
- The Trace class provides trace/debugging code that always
- reside in the program. There is no way (at this time) of
- compiling without the Trace/debug code. Macro wrappers
- could be designed so the class could be conditionally
- included. However, except for a few time critical places,
- most programs can afford the overhead of debugging code
- that can be enabled on the fly.
-
- Debug output is enabled when the DEBUGMODE environment
- variable is defined. The value of the DEBUGMODE variable
- specifies the amount and type of debugging output required.
- Debug output can also be enabled from within the program.
- The expected use of this feature is to enable Trace/debug
- output when a command line switch is parsed. The
- variable/switch value is a bit mask.
-
- 3 2 1 0
- | | | |________ Enable assert output when set
- | | |__________ Enable trace output when set
- | |____________ Enable error output when set
- |______________ Enable info output when set
-
- All trace output is directed to stderr.
-
- Assert output is generated by use of the Assert macro.
- Assert does NOT terminate the program when the assertion
- fails.
-
- Trace output is generated by instantiating an object of
- the trace class and using the function call operator
- without a TraceType.
-
- Error, and info output is generated by using the function
- call operator with a TraceType.
-
- Trace/debug output does NOT use the stream class. C stdio
- library functions are used instead. The reason for this is
- that one of the uses of this class is to develop a clone of
- the version 2.0 stream class. It also ensures that
- Trace/debug output is somewhat independent of the order class
- constructors are called.
-
- Examples of class use:
-
- int Class::function( void )
- {
- Trace trace = "Class::function";
-
- assert( trace, condition );
- ...
- trace( "a simple error message" );
- ...
- trace( error, "format", param, param );
- ...
- trace( info, "format", param, param );
- ...
- }
-
- When the function is entered the constructor Trace::Trace
- is called which prints the passed string, usually the name
- of the function, at an indent level corresponding to the
- nested level of the call. main() is at indent/nest level
- 0. Nothing is printed when the function exits but the
- indent level is restored to its previous value. The error
- and info operations output the passed strings (in printf
- format) at the appropriate indent level. Output from the
- above example will look like the following assuming
- DEBUGMODE is 15 (all trace output enabled).
-
- Trace Class::function
- <filename>(line): assert "condition" failed
- a simple error message
- error: <formated error message>
- info: <formatted info message>
-
- Public Operations:
-
- Trace( void )
- Requires:
- --nothing--
- Effects:
- The static member traceMode is set from the value of
- the environment variable DEBUGMODE. If DEBUGMODE is
- not in the environment traceMode is not modified.
- Comments:
- One instance of trace is defined in trace.cc to force
- this constructor to be called. When called the initial
- value of the trace mode flags is retrieved from the
- environment. It is assumed (but not forced) that no
- other instances of trace will be created using this
- constructor.
-
- Trace( const char *name )
- Requires:
- --nothing--
- Effects:
- The static member indent is incremented.
- Comments:
- This is the standard constructor for instantiating objects
- of class Trace. The usual definition is:
-
- Trace trace = "string";
-
- where string is the name of the entity being traced. The
- string is displayed at the current indent level and then the
- indent level is incremented.
-
- ~Trace( void )
- Requires:
- --nothing--
- Effects:
- The static member indent is decremented.
-
- Trace &operator () ( const char *str )
- Requires:
- --nothing--
- Effects:
- If trace output is enabled str is output to stderr. A
- newline is output after str.
-
- Trace &operator () ( TraceMode traceMode, const char *fmt, ... )
- Requires:
- One parameter of the proper type for each format defined in
- the passed format string.
- Effects:
- If the trace mode specified by traceMode is enabled vprintf
- is used to format and output the passed data to stderr. The
- data is preceded by the type of output (error or info) and
- terminated by a newline.
-
- void doAssert( const char *file, int line, const char *msg )
- Requires:
- --nothing--
- Effects:
- If assert output is enabled a message of the form
- file(line): assert "msg" failed
- is output to stderr.
- Comments:
- doAssert is designed to be called from the assert macro
- defined later in this file. The assert macro is used to
- build a generic condition and make it easier to get the
- file and line number of the assert call instead of the
- file and line number of doAssert's definition.
-
- Trace &setTraceMode( unsigned int traceMode )
- Requires:
- --nothing--
- Effects:
- The data member traceMode is set from the passed value.
- Comments:
- This function is public to allow the default traceMode value
- set from the environment to be modified under program
- control, perhaps as a result of a command line switch.
-
- Private Operations:
- void indent( void )
- Requires:
- --nothing--
- Effects:
- output "level" spaces to stderr.
-
- int assertSet( void )
- Requires:
- --nothing--
- Effects:
- return non-zero if assert output is enabled
-
- int traceSet( void )
- Requires:
- --nothing--
- Effects:
- return non-zero if trace output is enabled
-
- int errorSet( void )
- Requires:
- --nothing--
- Effects:
- return non-zero if error output is enabled
-
- int infoSet( void )
- Requires:
- --nothing--
- Effects:
- return non-zero if info output is enabled
- */
-
- #include <stdio.h>
- #include <stdarg.h>
-
- enum TraceMode {
- error,
- info
- };
-
- class Trace {
- public:
- Trace( );
- Trace( const char *name);
- ~Trace( void );
- Trace &operator () ( const char *str );
- Trace &operator () ( TraceMode traceMode, const char *fmt, ... );
- void doAssert( const char *file, int line, const char *msg );
- Trace &setTraceMode( unsigned int traceMode );
- private:
- void indent( void );
- int assertSet( void );
- int traceSet( void );
- int errorSet( void );
- int infoSet( void );
-
- static unsigned short level; // indent level
- static unsigned int traceMode; // output enable bits
- };
-
- /*
- The macro assert passes calls the doAssert member function only
- when the condition fails.
- */
-
- #define assert( trace, condition ) { \
- if ( !(condition) ) { \
- trace.doAssert( __FILE__, __LINE__, #condition ); \
- } \
- }
-
- static const int incr = 2; // indent level increment
-
- // definitions of bits in DEBUGMODE
-
- enum {
- assertMask = 0x01,
- traceMask = 0x02,
- errorMask = 0x04,
- infoMask = 0x08
- };
-
- /*
- Standard Trace constructor. Output the passed string when trace
- output is enabled. Increase the indent level.
- */
-
- inline
- Trace::Trace( const char *name )
- {
- if ( traceSet() ) {
- indent();
- fputs( name, stderr );
- fputc( '\n', stderr );
- }
- level += incr;
- }
-
- /*
- Decrement the indent level.
- */
-
- inline
- Trace::~Trace( void )
- {
- level -= incr;
- }
-
- /*
- Output the passed string at the current indent level when trace
- output is enabled.
- */
-
- inline Trace&
- Trace::operator () (const char *str)
- {
- if ( traceSet() ) {
- indent();
- fputs( str, stderr );
- fputc( '\n', stderr );
- }
- return *this;
- }
-
- /*
- Output an assert message at the current indent level when assert
- output is enabled.
- */
-
- inline void
- Trace::doAssert( const char *file, int line, const char *msg )
- {
- if ( assertSet() ) {
- indent();
- fprintf( stderr,
- "%s(%d): assert \"%s\" failed\n",
- file,
- line,
- msg );
- }
- }
-
- /*
- Indent to "level" by writing spaces to stderr.
- */
-
- inline void
- Trace::indent( void )
- {
- for ( int i = level; i > 0; --i ) {
- fputc( ' ', stderr );
- }
- }
-
- /*
- Test if assert output is enabled
- */
- inline int
- Trace::assertSet( void )
- {
- return traceMode & assertMask;
- }
-
- /*
- Test if trace output is enabled
- */
-
- inline int
- Trace::traceSet( void )
- {
- return traceMode & traceMask;
- }
-
- /*
- Test if error output is enabled
- */
-
- inline int
- Trace::errorSet( void )
- {
- return traceMode & errorMask;
- }
-
- /*
- Test if info output enabled
- */
-
- inline int
- Trace::infoSet( void )
- {
- return traceMode & infoMask;
- }
-
- end listing 2
-
-
-
- Listing 3
-
- /*
- * Copyright (c) 1989 Marco S. Hyman
- *
- * Permission to copy all or part of this material is granted
- * provided that the original copyright notice and its date
- * appear and notice is given that copying is by permission of
- * the original author.
- *
- */
-
- /*
- This is the implementation of the Trace debugging class. All
- member functions (save the inlines) are defined here. See
- trace.h for the class specification.
- */
-
- #include "trace.h"
- #include <stdlib.h>
-
- /*
- The following static instantiation of Trace causes its
- constructor to be called before main is entered. This should be
- the only instantiation of Trace that uses the Trace() constructor.
- This constructor initializes the traceMode static variables from
- the environment. All other instantiations of the Trace object
- should use the Trace( "string" ) constructor. There is no way to
- ensure that the constructor for initTraceMode is called before the
- constructors for other static objects (that may use Trace!).
- Many linkers will keep the sequence the files were passed to the
- linker in. If trace.o is one of the first files passed to the
- linker initialization may not be a problem.
- */
-
- static Trace initTraceMode;
-
- /*
- The constructor used for initTraceMode. Set traceMode if a
- debugMode is in the environment.
- */
-
- static const char *const debugMode = "DEBUGMODE";
-
- Trace::Trace( )
- {
- char *modeVal = getenv( debugMode );
-
- if (modeVal) {
- setTraceMode( atoi( modeVal ) );
- }
- }
-
- /*
- The arrays id and mask must be initialized such that elements of the
- enumeration TraceMode can be used as indexes into the arrays.
- id contains the string displayed as a prefix for trace messages of
- type TraceMode. mask contains the bit mask for testing if messages
- of type TraceMode are enabled.
-
- Both of the arrays are used by the () operator when the first
- parameter is TraceMode. The operator indents the appropriate
- amount, displays the prefix from id, and then outputs the formated
- string.
- */
-
- static const char *const id[] = {
- "error: ",
- "info: "
- };
-
- static int mask[] = {
- errorMask,
- infoMask,
- };
-
- Trace &
- Trace::operator () ( TraceMode traceMode, const char *fmt, ... )
- {
- if ( this->traceMode & mask[traceMode] ) {
- void *args;
-
- indent();
- fputs( id[traceMode], stderr );
- va_start( args, fmt );
- vfprintf( stderr, fmt, args );
- fputc( '\n', stderr );
- }
- return *this;
- }
-
- /*
- Set the static member traceMode. Can be called by application to
- override the default value set from the environment.
- */
-
- Trace &
- Trace::setTraceMode( unsigned int traceMode )
- {
- this->traceMode = traceMode;
- return *this;
- }
- end listing 3