libcwd: The C++ Debugging Support Library - Reference Manual
Author: Carlo Wood
Description: C++ debugging support library with ostream debug output
Keywords: libcwd, debug output, debug facility, debug channel, object orientation, OO, C++, nested debug output, ostream, memory allocation, debugging, source file and line number

Main Page Reference Manual Namespace List Compound List Namespace Members Compound Members File Members

# libcwd/class_debug.h

Go to the documentation of this file.

    00001 // $Header$
    00002 //
    00003 // Copyright (C) 2000 - 2004, by
    00004 //
    00005 // Carlo Wood, Run on IRC <carlo@alinoe.com>
    00006 // RSA-1024 0x624ACAD5 1997-01-26                    Sign & Encrypt
    00007 // Fingerprint16 = 32 EC A7 B6 AC DB 65 A6  F6 F6 55 DD 1C DC FF 61
    00008 //
    00009 // This file may be distributed under the terms of the Q Public License
    00010 // version 1.0 as appearing in the file LICENSE.QPL included in the
    00011 // packaging of this file.
    00012 //
    00013
    00018 #ifndef LIBCWD_CLASS_DEBUG_H
    00019 #define LIBCWD_CLASS_DEBUG_H
    00020
    00021 #ifndef LIBCWD_CONFIG_H
    00022 #include <libcwd/config.h>
    00023 #endif
    00024 #ifndef LIBCWD_CLASS_CHANNEL_SET_H
    00025 #include <libcwd/class_channel_set.h>
    00026 #endif
    00027 #ifndef LIBCWD_PRIVATE_STRUCT_TSD_H
    00028 #include <libcwd/private_struct_TSD.h>
    00029 #endif
    00030 #ifndef LIBCWD_STRUCT_DEBUG_TSD_H
    00031 #include <libcwd/struct_debug_tsd.h>
    00032 #endif
    00033 #ifndef LIBCWD_PRIVATE_LOCK_INTERFACE_H
    00034 #include <libcwd/private_lock_interface.h>
    00035 #endif
    00036 #ifndef LIBCW_IOSFWD
    00037 #define LIBCW_IOSFWD
    00038 #include <iosfwd>
    00039 #endif
    00040
    00041 namespace libcwd {
    00042
    00043 class buffer_ct;
    00044
    00045 #if CWDEBUG_ALLOC
    00046 namespace _private_ {
    00047
    00048 struct debug_message_st {
    00049   struct debug_message_st* next;
    00050   struct debug_message_st* prev;
    00051   int curlen;
    00052   char buf[sizeof(int)];
    00053 };
    00054
    00055 } // namespace _private_
    00056 #endif
    00057
    00058 //===================================================================================================
    00059 // class debug_ct
    00060 //
    00061 // Note: Debug output is printed already *before* this object is constructed,
    00062 // and is still printed when this object is already destructed.
    00063 // This is why initialization is done with method init() *before* construction
    00064 // and debug is turned off when this object is destructed.
    00065 // I hope that this is no problem because libcwd::libcw_do is a global object.
    00066 // It means however that this object can not contain any attributes that have
    00067 // a constructor of their own!
    00068
    00077 class debug_ct {
    00078   friend void debug_tsd_st::start(debug_ct&, channel_set_data_st& LIBCWD_COMMA_TSD_PARAM);
    00079   friend void debug_tsd_st::finish(debug_ct &, channel_set_data_st& LIBCWD_COMMA_TSD_PARAM);
    00080 #ifdef LIBCWD_DOXYGEN
    00081 protected:
    00082 #else
    00083 public: // Only public because macro LibcwDout needs acces, don't access this directly.
    00084 #endif
    00085 #if LIBCWD_THREAD_SAFE
    00086   int WNS_index;
    00087   static int S_index_count;
    00088 #else
    00089   //-------------------------------------------------------------------------------------------------
    00090   // Put the otherwise Thread Specific Data of this debug object
    00091   // directly into the object when we don't use threads.
    00092   //
    00093
    00094   debug_tsd_st tsd;
    00095 #endif
    00096
    00097 protected:
    00098   //-------------------------------------------------------------------------------------------------
    00099   // Protected attributes.
    00100   //
    00101
    00102   std::ostream* real_os;
    00103     // The original output ostream (as set with set_ostream()).
    00104     //
    00105 #if LIBCWD_THREAD_SAFE
    00106   friend class libcwd::buffer_ct;               // buffer_ct::writeto() needs access.
    00107   _private_::lock_interface_base_ct* M_mutex;
    00108     // Pointer to the mutex that should be used for `real_os' or NULL when no lock is used.
    00109     // A value of NULL is only allowed prior to creating a second thread.
    00110
    00111   buffer_ct* unfinished_oss;
    00112   void const* newlineless_tsd;
    00113 #endif
    00114
    00115 private:
    00116   //-------------------------------------------------------------------------------------------------
    00117   // Private attributes:
    00118   //
    00119
    00120   bool WNS_initialized;
    00121     // Set to true when this object is initialized (by a call to NS_init()).
    00122
    00123   bool NS_being_initialized;
    00124     // Set to true when this object is being initialized (by a call to NS_init()).
    00125
    00126 #if CWDEBUG_DEBUG
    00127   long init_magic;
    00128     // Used to check if the trick with `WNS_initialized' really works.
    00129 #endif
    00130
    00131   bool interactive;
    00132     // Set true if the last or current debug output is to cerr
    00133
    00134 #if CWDEBUG_ALLOC
    00135 public:
    00136   _private_::debug_message_st* queue;
    00137   _private_::debug_message_st* queue_top;
    00138     // Queue of messages written inside malloc/realloc/calloc/free/new/delete.
    00139     // Locked by mutex provided through set_ostream.
    00140 #endif
    00141
    00142 public:
    00155   debug_string_ct& margin(void);
    00156   debug_string_ct const& margin(void) const;
    00157
    00167   debug_string_ct& marker(void);
    00168   debug_string_ct const& marker(void) const;
    00169
    00172 public:
    00173   //-------------------------------------------------------------------------------------------------
    00174   // Manipulators and accessors for the "format" attributes:
    00175   //
    00176
    00177   void set_indent(unsigned short indentation);
    00178   void inc_indent(unsigned short indentation);
    00179   void dec_indent(unsigned short indentation);
    00180   unsigned short get_indent(void) const;
    00181
    00182   void push_margin(void);
    00183   void pop_margin(void);
    00184   void push_marker(void);
    00185   void pop_marker(void);
    00186
    00187   //-------------------------------------------------------------------------------------------------
    00188   // Other accessors
    00189   //
    00190
    00191   std::ostream* get_ostream(void) const;                // The original ostream set with set_ostream.
    00192
    00193 private:
    00194   //-------------------------------------------------------------------------------------------------
    00195   // Initialization function.
    00196   //
    00197
    00198   friend class channel_ct;
    00199   friend class fatal_channel_ct;
    00200   friend void ST_initialize_globals(LIBCWD_TSD_PARAM);
    00201 #if CWDEBUG_LOCATION
    00202   friend bool cwbfd::ST_init(LIBCWD_TSD_PARAM);
    00203 #endif
    00204   bool NS_init(LIBCWD_TSD_PARAM);
    00205     // Initialize this object, needed because debug output can be written
    00206     // from the constructors of (other) global objects, and from the malloc()
    00207     // family when CWDEBUG_ALLOC is set to 1.
    00208     // This will return false when it is called recursively which can happen
    00209     // as part of initialization of libcwd via a call to malloc while creating
    00210     // laf_ct -> buffer_ct --> basic_stringbuf.  In that case the initialization
    00211     // failed thus.  On success, it returns true.
    00212
    00213 public:
    00214   //-------------------------------------------------------------------------------------------------
    00215   // Constructors and destructors.
    00216   //
    00217
    00218   debug_ct(void);
    00219
    00220 private:
    00221   void private_set_ostream(std::ostream* os);
    00222
    00223 public:
    00224   //-------------------------------------------------------------------------------------------------
    00225   // Manipulators:
    00226   //
    00227
    00228   void set_ostream(std::ostream* os);
    00229 #if LIBCWD_THREAD_SAFE || defined(LIBCWD_DOXYGEN)
    00230   template<class T>
    00231     void set_ostream(std::ostream* os, T* mutex);
    00232 #ifdef LIBCWD_DOXYGEN
    00233   // Specialization.
    00234   template<>
    00235     void set_ostream(std::ostream* os, pthread_mutex_t* mutex);
    00236 #endif
    00237 #endif
    00238   void off(void);
    00239   void on(void);
    00240
    00241   struct OnOffState {
    00242     int _off;
    00243 #if CWDEBUG_DEBUGOUTPUT
    00244     bool first_time;
    00245 #endif
    00246   };
    00247
    00248   void force_on(OnOffState& state);
    00249   void restore(OnOffState const& state);
    00250 };
    00251
    00252 #if LIBCWD_THREAD_SAFE && !defined(LIBCWD_DOXYGEN)
    00253 // Specialization.
    00254 template<>
    00255   void debug_ct::set_ostream(std::ostream* os, pthread_mutex_t* mutex);
    00256 #endif
    00257
    00258 }  // namespace libcwd
    00259
    00260 #ifndef LIBCWD_SET_OSTREAM_INL
    00261 #include <libcwd/set_ostream.inl>
    00262 #endif
    00263
    00264 #endif // LIBCWD_CLASS_DEBUG_H
    00265