//============================================================================= // drt/sys/sdebug.hpp // DRT debugging (tracing) classes. // These classes implement very simple runtime debug tracing functions. // // Usage // DEBUGGING OUTPUT // // All objects of type DrtTrace share a common debugging trace output file // (.s_outf); all debugging output should be written to it. // // If the output file (.s_outf) is null, then the debugging output has not // yet been opened or has been suspended (see the suspend() and resume() // member functions). // This pointer is checked by the DE() macro. // // FUNCTION TRACING // // Constructing an object of type DrtTrace causes the .enter() member // function to be called, which writes an "enter" line to the debugging // output. // Likewise, destructing such an object causes the .leave() member // function to be called, which writes an "exit" line to the debugging // output. // Thus, declaring an auto variable object of this class type results in // the runtime tracing of the entry and exit from a function. // // To trace the entry into and exit out of a member function: // // Type Class::foo() // { // DrtTrace dbg("Class::foo", this); // ...body of function... // } // // To trace the entry and exit of a nonmember function: // // /*static*/ Type Class::bar() // { // DrtTrace dbg("Class::bar"); // ...body of function... // } // // TRACING GROUPS // // Functions can be arranged into debugging groups; each group shares an // DrtTraceGroup object, which contains a name for whole group. // The object should be a static object, either file-static or a private // static class member. // // To define a tracing group object: // // static DrtTraceGroup Foo::s_grp("Name", // __FILE__, __DATE__, __TIME__); // // A tracing group may also belong to a supergroup, which is itself simply // another tracing group object: // // static DrtTraceGroup Foo::s_grp(Bar::s_grp, "Name", // __FILE__, __DATE__, __TIME__); // // To trace the entry and exit of a member function for this group: // // Type Class::foo() // { // public: // DrtTrace dbg(s_grp, "Class::foo", this); // ...body of function... // } // // Tracing a nonmember function is almost the same: // // DrtTrace dbg(s_grp, "Class::bar"); // // If all of the member functions of a class are to be treated as a single // group (i.e., the class is the group), then the function entry/exit // tracing can be simplified somewhat: // // static DrtTraceGroup Class::s_grp("Class", // __FILE__, __DATE__, __TIME__); // // Type Class::foo() // { // DrtTrace dbg(s_grp, "foo", this); // ...body of function... // } // // STATEMENT TRACING // // To execute a statement if and only if the debugging output stream is // open (i.e., if debugging output is enabled): // // DE(expr); // // This is equivalent to: // // #if DEBUG // if (DrtTrace::s_outf != null) // expr; // #endif // // To execute a statement if and only if compile-time debugging is // enabled: // // DS(stmt); // // To execute a group of statements if and only if compile-time debugging // is enabled without using the debugging macros: // // #if DEBUG // stmt; // stmt; // #endif // // TRACING OUTPUT // // To write formatted output (ala printf()) to the debugging output // stream if and only if compile-time and run-time debugging is enabled: // // DE(DrtTrace::print("count=%d\n", count)); // Or: // DE(dbg.print("count=%d\n", count)); // Uses 'dbg' object // Or: // DE(dbg << "count=" << count << dbg.eoln); // // Caveats // These classes (DrtTraceXxx) do not inherit class DrtMagic, as they are // meant to be very primitive class types. // // See also // "kdebug.h" // // History // 0.01, 1998-04-16, David R Tribble. // First cut. // // 0.02, 1998-04-18, David R Tribble. // Added class DrtTraceGroup. // // 0.03, 1998-04-23, David R Tribble. // Added class DrtTraceInfo. // // 0.04, 1998-04-24, David R Tribble. // Renamed from "scdebug.h" to "jdebug.hpp". // // 0.05, 1998-05-30, David R Tribble. // Changed filename prefix from "j" to "s". // // 0.06, 1998-05-30, David R Tribble. // Added members .m_file, .m_cdate, and .m_ctime to class DrtTraceGroup. // // 0.07, 1998-05-30, David R Tribble. // Changed DrtTraceGroup reference args to be pointers instead. // // 0.08, 1998-06-23, David R Tribble. // Changed prototype for DrtTraceGroup::enter(). // // 0.09, 1999-02-27, David R Tribble. // Move to drt/sys/. // // Copyright ©1998-1999, by David R. Tribble, all rights reserved. // See "drt/sys/copyr.txt" for more information. //----------------------------------------------------------------------------- #ifndef drt_sys_sdebug_hpp #define drt_sys_sdebug_hpp 1 // Identification #ifndef NO_H_IDENT static const char drt_sys_sdebug_hpp_id[] = "@(#)drt/sys/sdebug.hpp 0.09"; #endif // System includes #ifndef drt_std_stdio_h #include #define drt_std_stdio_h 1 #endif // Special includes #ifndef drt_sys_sdefs_hpp #include "sdefs.hpp" #endif // Local wrappers #include "slib1.hpp" drt_namespace_begin // Control macro constants #ifndef DEBUG #define DEBUG 0 #elif DEBUG-0 <= 0 #undef DEBUG #define DEBUG 0 #endif // Function macros #if DEBUG #define DE(e) (DrtTrace::s_outf ? (void)(e) : (void)0) #define DS(s) s #define DW() DrtTrace::where(__FILE__, __LINE__) #else #define DE(e) ((void)0) #define DS(s) 0 #define DW() ((void)0) #endif #if DEBUG >= 2 #define DE2(e) DE(e) #else #define DE2(e) ((void)0) #endif #if DEBUG >= 3 #define DE3(e) DE(e) #else #define DE3(e) ((void)0) #endif //----------------------------------------------------------------------------- // Class DrtTraceGroup // Debugging group class. // This class implements very simple runtime debug tracing functions. // // Caveats // This class does not inherit class DrtMagic. // // See also // The notes at the top of this file for more details about how to use // this class. // // History // 100, 1998-04-18, David R Tribble. // First cut. // // 101, 1998-05-30, David R Tribble. // Added .m_magic and .m_vers members. // Added members .m_file, .m_cdate, and .m_ctime. // // 102, 1998-06-23, David R Tribble. // Added .m_enable member. // // 103, 1998-09-25, David R Tribble. // Added .m_sup member. // Replaced .m_enable member with .m_flags. // // 104, 1998-11-04, David R Tribble. // Added .m_color coloring bits member. //----------------------------------------------------------------------------- #define DrtTraceGroup_VS 104 // Class version class DRTEXPORT DrtTraceGroup { public: // Shared constants static const int VS; // Class version static const unsigned int MAGIC; // Class magic number public: // Shared types typedef DrtTraceGroup Type; // This type public: // Constants enum Flags // Control bitflags { F_ENABLE = 0x0001, // Enable group tracing output F_COLOR = 0x0002, // Enable trace coloring F__DFL = 0x0000 // Default settings }; public: // Variables unsigned int m_magic; // Class magic number int m_vers; // Class version number DrtTraceGroup * m_sup; // Parent supergroup const char *const m_name; // Group (e.g., class) name const char *const m_file; // Source filename (__FILE__) const char *const m_cdate; // Compilation date (__DATE__) const char *const m_ctime; // Compilation time (__TIME__) unsigned int m_flags; // Control bitflags public: // Functions /*void*/ ~DrtTraceGroup(); // Destructor /*void*/ DrtTraceGroup(const char *name, const char *file, const char *cdate, const char *ctime); // Constructor /*void*/ DrtTraceGroup(DrtTraceGroup &sup, const char *name, const char *file, const char *cdate, const char *ctime); // Constructor /*void*/ DrtTraceGroup(const char *name); // Constructor, simplified /*void*/ DrtTraceGroup(DrtTraceGroup &sup, const char *name); // Constructor, simplified bool isEnabled() const; // Group output is enabled void setColor(int col); // Set group's tracing color private: // Shared variables static const DrtTraceGroup * s_list; // List of all trace groups private: // Variables const DrtTraceGroup * m_next; // Next group in list unsigned long m_color; // Trace coloring bits private: // Functions // Constructors and destructors not provided /*void*/ DrtTraceGroup(); // Default constructor /*void*/ DrtTraceGroup(const DrtTraceGroup &o); // Copy constructor const DrtTraceGroup & operator =(const DrtTraceGroup &o); // Assignment operator private: // Operators // Operators not provided void * operator new(size_t n); void * operator new[](size_t n); void operator delete(void *o); void operator delete[](void *o); }; // Inline member functions inline /*void*/ DrtTraceGroup::~DrtTraceGroup() { // No members to de-initialize } inline /*void*/ DrtTraceGroup::DrtTraceGroup(const char *name, const char *file, const char *cdate, const char *ctime): m_magic(MAGIC), m_vers(VS), m_sup(null), m_name(name), m_file(file), m_cdate(cdate), m_ctime(ctime), m_flags(F__DFL), m_next(null) { #if DEBUG // Insert this group into the list m_next = s_list; s_list = this; #endif } inline /*void*/ DrtTraceGroup::DrtTraceGroup(DrtTraceGroup &sup, const char *name, const char *file, const char *cdate, const char *ctime): m_magic(MAGIC), m_vers(VS), m_sup(&sup), m_name(name), m_file(file), m_cdate(cdate), m_ctime(ctime), m_flags(F__DFL), m_next(null) { #if DEBUG // Insert this group into the list m_next = s_list; s_list = this; #endif } inline /*void*/ DrtTraceGroup::DrtTraceGroup(const char *name): m_magic(MAGIC), m_vers(VS), m_sup(null), m_name(name), m_file(""), m_cdate(""), m_ctime(""), m_flags(F__DFL), m_next(null) { #if DEBUG // Insert this group into the list m_next = s_list; s_list = this; #endif } inline /*void*/ DrtTraceGroup::DrtTraceGroup(DrtTraceGroup &sup, const char *name): m_magic(MAGIC), m_vers(VS), m_sup(&sup), m_name(name), m_file(""), m_cdate(""), m_ctime(""), m_flags(F__DFL), m_next(null) { #if DEBUG // Insert this group into the list m_next = s_list; s_list = this; #endif } inline bool DrtTraceGroup::isEnabled() const { #if DEBUG // Check that output is enabled for this group return ((m_flags & F_ENABLE) != 0); #else return (false); #endif } //----------------------------------------------------------------------------- // Class DrtTraceInfo // Debugging function entry info. // // Notes // This is a POD class. // // Caveats // This class does not inherit class DrtMagic. // // History // 100, 1998-04-23, David R Tribble. // First cut. // // 101, 1998-05-30, David R Tribble. // Added .m_magic and .m_vers members. //----------------------------------------------------------------------------- #define DrtTraceInfo_VS 101 // Class version class DRTEXPORT DrtTraceInfo { public: // Shared constants static const int VS; // Class version static const unsigned int MAGIC; // Class magic number public: // Shared types typedef DrtTraceInfo Type; // This type public: // Variables unsigned int m_magic; // Class magic number int m_vers; // Class version number const char * m_func; // Func name const void * m_thisp; // Func's object DrtTraceGroup * m_group; // Group info public: // Functions // Constructors and destructors not provided // No destructor // No default constructor // No copy constructor // No assigment operator }; //----------------------------------------------------------------------------- // Class DrtTrace // Debugging (tracing) class. // This class implements very simple runtime debug tracing functions. // // Caveats // This class does not inherit class DrtMagic. // // See also // The notes at the top of this file for more details about how to use // this class. // // History // 100, 1998-04-16, David R Tribble. // First cut. //----------------------------------------------------------------------------- #define DrtTrace_VS 100 // Class version class DRTEXPORT DrtTrace { public: // Shared constants static const int VS; // Class version static const unsigned int MAGIC; // Class magic number enum Constants // Manifest constants { MAX_DEPTH = 200 // Max function nesting depth }; public: // Shared types typedef DrtTrace Type; // This type public: // Shared variables static FILE * s_outf; // Debugging output stream public: // Variables // No members public: // Shared functions static bool open(const char *fn); // Open a debug output stream static void close(); // Close the debug output static void suspend(); // Suspend debug output static void resume(); // Resume debug output static void enterContext(); // Lock the debugging context static void leaveContext(); // Unlock the debugging context static void where(const char *func, int line); // Establish a location static int print(const char *fmt, ...); // Print formatted output static int printHead(); // Print a line heading public: // Formatting insertion functions static int eoln(); // Print an end-of-line static int width(int n); // Format width static int prec(int n); // Format precision static int radix(int n); // Format numeric radix public: // Functions /*void*/ ~DrtTrace(); // Destructor /*void*/ DrtTrace(const char *name, const void *thisp); // Constructor, member func /*void*/ DrtTrace(const char *name); // Constructor, nonmember func /*void*/ DrtTrace(DrtTraceGroup &g, const char *name, const void *thisp); // Constructor, member func /*void*/ DrtTrace(DrtTraceGroup &g, const char *name); // Constructor, nonmember func public: // Operators DrtTrace & operator <<(char x); // Print a char DrtTrace & operator <<(int x); // Print an integer DrtTrace & operator <<(unsigned int x); // Print an integer DrtTrace & operator <<(long x); // Print an integer DrtTrace & operator <<(const char *x); // Print a string DrtTrace & operator <<(const void *x); // Print a pointer DrtTrace & operator <<(int (*x)()); // Insert a formatter DrtTrace & operator <<(int (*x)(int n)); // Insert a formatter private: // Shared variables static FILE * s_savef; // Suspended output stream static int s_depth; // Func nesting depth static DrtTraceInfo * s_stack; // Nested func call info private: // Variables // No members private: // Shared functions static int enter(const char *name, const void *thisp, DrtTraceGroup *g); // Enter a function static void leave(); // Leave a function static void lock(); // Acquire a thread mutex static void unlock(); // Release a thread mutex private: // Functions // Constructors and destructors not provided /*void*/ DrtTrace(); // Default constructor /*void*/ DrtTrace(const DrtTrace &o); // Copy constructor const DrtTrace & operator =(const DrtTrace &o); // Assignment operator private: // Operators // Operators not provided void * operator new(size_t n); void * operator new[](size_t n); void operator delete(void *o); void operator delete[](void *o); }; // Inline member functions inline /*void*/ DrtTrace::~DrtTrace() { #if DEBUG // No members to de-initialize leave(); #endif } inline /*void*/ DrtTrace::DrtTrace() { #if DEBUG // No members to initialize enter("", null, null); #endif } inline /*void*/ DrtTrace::DrtTrace(const char *name) { #if DEBUG // No members to initialize enter(name, null, null); #endif } inline /*void*/ DrtTrace::DrtTrace(const char *name, const void *thisp) { #if DEBUG // No members to initialize enter(name, thisp, null); #endif } inline /*void*/ DrtTrace::DrtTrace(DrtTraceGroup &g, const char *name) { #if DEBUG // No members to initialize enter(name, null, &g); #endif } inline /*void*/ DrtTrace::DrtTrace(DrtTraceGroup &g, const char *name, const void *thisp) { #if DEBUG // No members to initialize enter(name, thisp, &g); #endif } #include "slib2.hpp" drt_namespace_end #endif // drt_sys_sdebug_hpp // End sdebug.hpp