/** @file
$Id$
$Date$
$Author$
@copy © Marc Wäckerlin
@license LGPL, see file COPYING
$Log$
Revision 1.2 2004/08/28 16:21:25 marc
mrw-c++-0.92 (mrw)
- new file: version.cpp
- new file header for all sources
- work around warning in mrw::auto
- possibility to compile without log4cxx
- work around bugs in demangle.h and libiberty.h
- corrections in documentation
- added simple tracing mechanism
- more warnings
- small corrections in Auto<>::Free and a new test for it
- possibility to compile without stack trace
*/
#ifndef __MRW_SIMPLETRACE_HPP__
#define __MRW_SIMPLETRACE_HPP__
#include
#include
#include
/** @defgroup SimpleTrace Simple Tracing (for temporary debugging)
@pre #include
Here is a simple tracing to @c std::cout mechanism for temporary
debugging and simple testing purposes. Might be useful when
experimenting and exploring new C++ language constructs. Please
note that you can only trace in methods and functions that start
with @c METHOD respectively @c FUNCTION.
Please note that you should not use this simple mechanism for real
projects, only for your experiments! For your work, use
log4cxx!
The trace of the following code:
@code
#include
void fn(int i=0) {
FUNCTION; // trace entry and exit
if (!i) TRACE("Hello World, this is a nice text!");
if (i<4) fn(++i);
}
class A {
public:
A() {
NO_TRACE; // don't trace in constructor
method(); // not traced
}
void method() {
METHOD; // trace entry and exit
CALL(fn()); // trace before call
fn();
}
};
int main(int, char**) {
FUNCTION;
CALL(A().method());
A().method();
TRACE("No more trace:");
TRACE_OFF;
A().method();
TRACE_ON;
TRACE("Back again");
return 0;
}
@endcode
Produces this output:
@verbatim
tmp.cpp:20 0: \ main
tmp.cpp:21 0: -> A().method()
tmp.cpp:14 0xbffff10f: \ method
tmp.cpp:15 0xbffff10f: -> fn()
tmp.cpp:3 0: \ fn
tmp.cpp:4 0: **** Hello World, this is a nice text! ****
tmp.cpp:3 0: \ fn
tmp.cpp:3 0: \ fn
tmp.cpp:3 0: \ fn
tmp.cpp:3 0: \ fn
tmp.cpp:3 0: / fn
tmp.cpp:3 0: / fn
tmp.cpp:3 0: / fn
tmp.cpp:3 0: / fn
tmp.cpp:3 0: / fn
tmp.cpp:14 0xbffff10f: / method
tmp.cpp:23 0: **** No more trace: ****
tmp.cpp:27 0: **** Back again ****
tmp.cpp:20 0: / main
@endverbatim
*/
//@{
#ifndef __GNUG__
/// Declare method entrance, place as first line in method.
#define METHOD(name) mrw::FnTrace fnTrace(this, #name, __FILE__, __LINE__)
/// Declare function entrance, place as first line in function.
#define FUNCTION(name) mrw::FnTrace fnTrace(0, #name, __FILE__, __LINE__)
#else
/// Declare method entrance, place as first line in method.
/// GNU g++ knows the method name.
#define METHOD mrw::FnTrace fnTrace(this, __FUNCTION__, __FILE__, __LINE__)
/// Declare function entrance, place as first line in function.
/// GNU g++ knows the method name.
#define FUNCTION mrw::FnTrace fnTrace(0, __FUNCTION__, __FILE__, __LINE__)
#endif
/// Document the call of another method (before you call it).
#define CALL(name) fnTrace.call(#name, __FILE__, __LINE__)
/// Trace an arbitrary text.
#define TRACE(text) fnTrace.trace(text, __FILE__, __LINE__)
/// Turn all tracing off (from here on).
#define TRACE_OFF mrw::FnTrace::off()
/// Turn all tracing off (from here on).
#define TRACE_ON mrw::FnTrace::on()
/// Don't trace in this scope (from here on).
#define NO_TRACE mrw::NoTrace noTrace;
namespace mrw {
class FnTrace {
public:
FnTrace(const void* addr, const std::string& name,
const std::string& file, unsigned long line) throw():
_addr(addr), _name(name), _file(file), _line(line) {
if (_off==0)
std::cout< "<0) --_off;
}
private:
const void* _addr;
const std::string _name;
const std::string _file;
unsigned long _line;
static unsigned int _level;
static unsigned int _off;
};
unsigned int FnTrace::_level(0);
unsigned int FnTrace::_off(0);
class NoTrace {
public:
NoTrace() throw() {TRACE_OFF;}
~NoTrace() throw() {TRACE_ON;}
};
}
//@}
#endif