C++ Library containing a lot of needful things: Stack Trace, Command Line Parser, Resource Handling, Configuration Files, Unix Command Execution, Directories, Regular Expressions, Tokenizer, Function Trace, Standard Extensions.
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
192 lines
6.5 KiB
192 lines
6.5 KiB
/** @file |
|
|
|
$Id$ |
|
|
|
$Date$ |
|
$Author$ |
|
|
|
@copy © Marc Wäckerlin |
|
@license LGPL, see file <a href="license.html">COPYING</a> |
|
|
|
$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<T> |
|
- 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 <iostream> |
|
#include <iomanip> |
|
#include <string> |
|
|
|
/** @defgroup SimpleTrace Simple Tracing (for temporary debugging) |
|
@pre #include <mrw/simpletrace.hpp> |
|
|
|
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 |
|
<a href="http://logging.apache.org/log4cxx">log4cxx</a>! |
|
|
|
The trace of the following code: |
|
|
|
@code |
|
#include <mrw/simpletrace.hpp> |
|
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<<std::setw(15)<<_file<<':'<<std::setiosflags(std::ios::left) |
|
<<std::setw(5)<<_line<<std::resetiosflags(std::ios::left)<<' ' |
|
<<std::hex<<std::setw(15)<<_addr<<": "<<std::dec |
|
<<std::setw(2+_level)<<std::setfill(' ')<<"\\ " |
|
<<_name<<std::endl; |
|
++_level; |
|
} |
|
~FnTrace() throw() { |
|
--_level; |
|
if (_off==0) |
|
std::cout<<std::setw(15)<<_file<<':'<<std::setiosflags(std::ios::left) |
|
<<std::setw(5)<<_line<<std::resetiosflags(std::ios::left)<<' ' |
|
<<std::hex<<std::setw(15)<<_addr<<": "<<std::dec |
|
<<std::setw(2+_level)<<std::setfill(' ')<<"/ "<<_name |
|
<<std::endl; |
|
} |
|
void call(const std::string& name, |
|
const std::string& file, unsigned long line) throw() { |
|
if (_off==0) |
|
std::cout<<std::setw(15)<<file<<':'<<std::setiosflags(std::ios::left) |
|
<<std::setw(5)<<line<<std::resetiosflags(std::ios::left)<<' ' |
|
<<std::hex<<std::setw(15)<<_addr<<": "<<std::dec |
|
<<std::setw(4+_level)<<std::setfill(' ')<<" -> "<<name |
|
<<std::endl; |
|
} |
|
void trace(const std::string& text, |
|
const std::string& file, unsigned long line) throw() { |
|
if (_off==0) |
|
std::cout<<std::setw(15)<<file<<':'<<std::setiosflags(std::ios::left) |
|
<<std::setw(5)<<line<<std::resetiosflags(std::ios::left)<<' ' |
|
<<std::hex<<std::setw(15)<<_addr<<": "<<std::dec |
|
<<std::setw(4+_level)<<std::setfill(' ')<<" **** "<<text |
|
<<" **** "<<std::endl; |
|
} |
|
static void off() throw() { |
|
++_off; |
|
} |
|
static void on() throw() { |
|
if (_off>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
|
|
|