libcwd: The C++ Debugging Support Library - Tutorial
Author: Carlo Wood

| The C++ Debugging Support Library By Carlo Wood, ©1999 - 2003.

## Tutorial 2: Creating your own Debug Channels

You can easily create your own debug channels. In the example below we create a debug channel `dc::ghost` that will use the string "GHOST" as label.

Create a file `"sys.h"` that is part of your application and put in it:

    #ifdef HAVE_CONFIG_H		// This is just an example of what you could do
    #include "config.h"		//   when using autoconf for your project.
    #endif
    #ifdef CWDEBUG			// This is needed so that others can compile
    				//   your application without having libcwd installed.
    #ifndef _GNU_SOURCE		// Already defined by g++ 3.0 and higher.
    #define _GNU_SOURCE		// Needed for libpthread extensions.
    #endif
    #include <libcwd/sys.h>
    #endif

Create a file `"debug.h"` that is part of your application and put in it:

    #ifndef DEBUG_H
    #define DEBUG_H

    #ifndef CWDEBUG

    #define AllocTag1(p)
    #define AllocTag2(p, desc)
    #define AllocTag_dynamic_description(p, x)
    #define AllocTag(p, x)
    #define Debug(x)
    #define Dout(a, b)
    #define DoutFatal(a, b) LibcwDoutFatal(::std, , a, b)
    #define ForAllDebugChannels(STATEMENT)
    #define ForAllDebugObjects(STATEMENT)
    #define LibcwDebug(dc_namespace, x)
    #define LibcwDout(a, b, c, d)
    #define LibcwDoutFatal(a, b, c, d) do { ::std::cerr << d << ::std::endl; ::std::exit(254); } while(1)
    #define NEW(x) new x

    #else // CWDEBUG

    #ifndef DEBUGCHANNELS
    // This must be defined before <libcwd/debug.h> is included and must be the
    // name of the namespace containing your `dc' namespace (see below).
    // You can use any namespace(s) you like, except existing namespaces
    // (like ::, ::std and ::libcwd).
    #define DEBUGCHANNELS ::myproject::debug::channels
    #endif
    #include <libcwd/debug.h>

    namespace myproject {
      namespace debug {
        namespace channels {
          namespace dc {
    	using namespace ::libcwd::channels::dc;

    	// Add the declaration of new debug channels here
    	// and their definition in a custom debug.cc file.
    	extern ::libcwd::channel_ct custom;

          } // namespace dc
        } // namespace DEBUGCHANNELS
      }
    }

    #endif // CWDEBUG
    #endif // DEBUG_H

Finally write the program:

[download]

    #include "sys.h"
    #include "debug.h"

    // Actual definition of `ghost'
    namespace debug_channels {	// Actually, you will need a series of
    				// "namespace xyz {" here, to match whatever
    				// DEBUGCHANNELS is.
      namespace dc {
        libcwd::channel_ct ghost("GHOST");
      }
    }

    int main(void)
    {
      Debug( dc::ghost.on() );			// Remember: don't forget to turn
      Debug( libcw_do.on() );			//   the debug Channel and Object on!

      for (int i = 0; i < 4; ++i)
        Dout(dc::ghost, "i = " << i);		// We can write more than just
    						// "Hello World" to the ostream :)
      return 0;
    }

This program outputs:

    GHOST   : i = 0
    GHOST   : i = 1
    GHOST   : i = 2
    GHOST   : i = 3

Note that when writing a library you are highly advised to follow the namespace guideline as set forth in the Reference Manual.

#### FAQ

- What is the maximum length of a label?
- Why do I have to use the `dc::` prefix?
- Why does it print spaces between the label and the colon? How is the field width of the label determined?