Release 3-2-0 with tag: REL_mrw-c++-3-2-0

master
Marc Wäckerlin 17 years ago
parent df8e05c180
commit 4ca9363fd0
  1. 17
      ChangeLog
  2. 1
      bootstrap.sh
  3. 37
      configure.in
  4. 28
      makefile.am
  5. 90
      mrw/auto.hpp
  6. 58
      mrw/autofunctiontracelog4cxx.cpp
  7. 140
      mrw/autostacktracelog4cxx.cpp
  8. 75
      mrw/autostacktracestderr.cpp
  9. 6
      mrw/doxyfile.in
  10. 38
      mrw/errno.cpp
  11. 7
      mrw/errno.hpp
  12. 3
      mrw/foot.html
  13. 73
      mrw/functiontrace.hpp
  14. 45
      mrw/functiontrace_test.cpp
  15. 4
      mrw/head.html
  16. BIN
      mrw/hintergrund.png
  17. 135
      mrw/log4cxxconfiguration.cpp
  18. 302
      mrw/makefile.am
  19. 96
      mrw/mrw.hpp.in
  20. 109
      mrw/mrwautofunctiontracelog4cxx_test.cpp
  21. 78
      mrw/stacktrace.cpp
  22. 4
      mrw/stacktrace.hpp
  23. 5
      mrw/stacktrace_test.cpp
  24. 7
      mrw/string.hpp

@ -1,3 +1,20 @@
* Sun Aug 5 2007 Marc Waeckerlin - mrw-c++-3.2.1 (mrw)
- Compatibility to UNICODE log4cxx 0.9.7
* Fri Jul 7 2007 Marc Waeckerlin - mrw-c++-3.2.0 (mrw)
- Partly ported to SVN version of log4cxx
- Added valgrind support with --enable-valgrind
- Checked with valgrind and repaired defects:
- Mismatching delete in StackTrace
* Tue Jun 12 2007 Marc Waeckerlin - mrw-c++-3.1.1 (mrw)
- Don't catch abort() in autostacktraceXXX.cpp
* Thu May 31 2007 Marc Waeckerlin - mrw-c++-3.1.0 (mrw)
- Bug in string.hpp join: Only join with list of strings was possible.
* Fri May 25 2007 Marc Waeckerlin - mrw-c++-3.0.0 (mrw)
- Function- and method-trace have been renamed from FUNCTION and
METHOD to MRW_FUNCTION and MRW_METHOD due to naming conflicts with
Qt-Library. This breaks backward compatibility!
* Sat May 19 2007 Marc Waeckerlin - mrw-c++-2.3.4 (mrw)
- also tracing for signals in autostacktraceXXX (-lmrwexclog4cxx)
* Sat Feb 04 2006 Marc Waeckerlin - mrw-c++-2.3.1 (mrw) * Sat Feb 04 2006 Marc Waeckerlin - mrw-c++-2.3.1 (mrw)
- new rpm package mrw-c++-minimal without debug facilities - new rpm package mrw-c++-minimal without debug facilities
no dependencies to boost, log4cxx and ltdl libraries no dependencies to boost, log4cxx and ltdl libraries

@ -15,5 +15,4 @@
## added file header ## added file header
## ##
test -f makefile && make distclean
aclocal && libtoolize --force && automake -a && autoconf aclocal && libtoolize --force && automake -a && autoconf

@ -13,11 +13,11 @@
# init # init
AC_INIT([mrw/mrw.hpp.in]) AC_INIT([mrw/mrw.hpp.in])
AC_CANONICAL_SYSTEM
PACKAGENAME=mrw-c++ PACKAGENAME=mrw-c++
m4_define(x_major, 2) m4_define(x_major, 3)
m4_define(x_minor, 3) m4_define(x_minor, 2)
m4_define(x_least, 1) m4_define(x_least, 1)
AM_INIT_AUTOMAKE(@PACKAGENAME@, @MAJOR@.@MINOR@.@LEAST@, [marc@waeckerlin.org])
# copy M4 to shell # copy M4 to shell
MAJOR=x_major MAJOR=x_major
@ -27,6 +27,8 @@ AC_SUBST(MAJOR)
AC_SUBST(MINOR) AC_SUBST(MINOR)
AC_SUBST(LEAST) AC_SUBST(LEAST)
AM_INIT_AUTOMAKE($PACKAGENAME, $MAJOR.$MINOR.$LEAST, [marc@waeckerlin.org])
# libtool versioning # libtool versioning
LIB_MAJOR=m4_eval(x_major+x_minor) LIB_MAJOR=m4_eval(x_major+x_minor)
LIB_MINOR=x_least LIB_MINOR=x_least
@ -62,9 +64,17 @@ AC_CHECK_HEADER(sys/old_procfs.h, [AM_CPPFLAGS=-D__solaris__])
# libraries # libraries
AC_CHECK_HEADER(log4cxx/logger.h, [have_log4cxx=yes]) AC_CHECK_HEADER(log4cxx/logger.h, [have_log4cxx=yes])
AC_CHECK_HEADER(ltdl.h, [have_ltdl=yes]) AC_CHECK_HEADER(ltdl.h, [have_ltdl=yes])
AC_CHECK_HEADER(regex.h, [have_regex=yes])
AC_CHECK_HEADERS(unistd.h fcntl.h, [have_exec=yes])
AC_CHECK_HEADER(dirent.h, [have_dir=yes])
# Arguments # Arguments
AM_MAINTAINER_MODE AM_MAINTAINER_MODE
AC_ARG_ENABLE(valgrind,
AS_HELP_STRING([--enable-valgrind],
[runs all checks with valgrind enabled]),
[have_valgrind="$enableval"], [have_valgrind="no"])
AM_CONDITIONAL(HAVE_VALGRIND, test "$have_valgrind" = "yes")
AC_ARG_ENABLE(threads, AC_ARG_ENABLE(threads,
[ --disable-threads disable multithreading], [ --disable-threads disable multithreading],
[with_threads="$enableval"], [with_threads="yes"]) [with_threads="$enableval"], [with_threads="yes"])
@ -85,6 +95,18 @@ AC_ARG_ENABLE(dot,
[ --disable-dot disable dot graphic tools for documentation], [ --disable-dot disable dot graphic tools for documentation],
[have_dot="$enableval"]) [have_dot="$enableval"])
test "$enableval" = "yes" && HAVE_DOT="YES" || HAVE_DOT="NO"; test "$enableval" = "yes" && HAVE_DOT="YES" || HAVE_DOT="NO";
AC_ARG_ENABLE(dir,
[ --disable-dir disable POSIX directory access],
[have_dir="$enableval"])
AM_CONDITIONAL(HAVE_DIR, test "$have_dir" = "yes")
AC_ARG_ENABLE(exec,
[ --disable-exec disable UNIX fork and execute with pipes],
[have_exec="$enableval"])
AM_CONDITIONAL(HAVE_EXEC, test "$have_exec" = "yes")
AC_ARG_ENABLE(regexp,
[ --disable-regexp disable use of regular expressions],
[have_regex="$enableval"])
AM_CONDITIONAL(HAVE_REGEXP, test "$have_regex" = "yes")
AC_ARG_ENABLE(log4cxx, AC_ARG_ENABLE(log4cxx,
[ --disable-log4cxx disable use of log4cxx library in automated [ --disable-log4cxx disable use of log4cxx library in automated
stack trace], stack trace],
@ -197,6 +219,15 @@ if test "$with_threads" = "no"; then
AC_MSG_WARN([Multithreading support is disabled! AC_MSG_WARN([Multithreading support is disabled!
- use --enable-threads to enable it - use --enable-threads to enable it
- actually, there's only support for automated function trace]); fi - actually, there's only support for automated function trace]); fi
if test "$have_dir" != "yes"; then
AC_MSG_WARN([POSIX directory access is disabled!
- you need a UNIX/Posix environment if you want to use it]); fi
if test "$have_exec" != "yes"; then
AC_MSG_WARN([UNIX fork/exec with pipes will not be used!
- you need a UNIX/Posix environment if you want to use it]); fi
if test "$have_regex" != "yes"; then
AC_MSG_WARN([GNU regular expression library will not be used!
- if you want it, install it]); fi
if test "$have_log4cxx" != "yes"; then if test "$have_log4cxx" != "yes"; then
AC_MSG_WARN([Library log4cxx will not be used! AC_MSG_WARN([Library log4cxx will not be used!
- if you want it, download it from: - if you want it, download it from:

@ -54,17 +54,25 @@ rpm: dist
rpmbuild -ba --clean @PACKAGENAME@.spec rpmbuild -ba --clean @PACKAGENAME@.spec
rpmbuild -bb --clean @PACKAGENAME@-minimal.spec rpmbuild -bb --clean @PACKAGENAME@-minimal.spec
webserver: rpm webserver: check distcheck rpm webserver.en webserver.de webserver.zh
ssh root@waeckerlin.org bash -c \ - rm -rf ~/www/marc/data/doxygen/mrw-cpp
'"rm -r /home/marc/mrw-c++; mkdir -p /home/marc/mrw-c++"' mkdir -p ~/www/marc/data/doxygen/mrw-cpp
scp doc/html/* \ cp doc/html/*.html ~/www/marc/data/doxygen/mrw-cpp/
doc/latex/@PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@.pdf \ cp doc/latex/@PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@.pdf \
@PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@.tar.gz \ @PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@.tar.gz \
${RPMS} \ ${RPMS} \
log4cxx*.rpm \ log4cxx*.rpm \
root@waeckerlin.org:/home/marc/mrw-c++/ ~/www/marc/downloads/
date +'%s 127.0.0.1 :computer:c_:mrw-c_:index mrw @PACKAGENAME@ version @MAJOR@.@MINOR@.@LEAST@' >> ~/www/marc/data/changes.log
maintainerclean-local: webserver.%:
- rm -rf ~/www/marc/data/media/$(@:webserver.%=%)/computer/c_/mrw-c_
mkdir -p ~/www/marc/data/media/$(@:webserver.%=%)/computer/c_/mrw-c_
cp doc/html/*.png \
doc/html/*.gif \
~/www/marc/data/media/$(@:webserver.%=%)/computer/c_/mrw-c_/
maintainer-clean-local:
- find . -name '*~' | xargs rm - find . -name '*~' | xargs rm
- rm -r doc - rm -r doc
- rm -r autom4te.cache - rm -r autom4te.cache

@ -255,6 +255,96 @@ namespace mrw {
T* _res; ///< the resource to be managed T* _res; ///< the resource to be managed
}; };
/** @brief Automatically deletes an array pointer when destructed.
@pre \#include <mrw/auto.hpp>
mrw::AutoPtrAry is a replacement for std::auto_ptr. Other than
mrw::AutoPtr it is for arrays, that means, it calls @c delete[]
instead of @c delete to free the memory. The problem with
standard std::auto_ptr is, that it cannot be stored in a
std::map and it does not call @c delete[].
@warning Use this class with prudence! Should I ever find out,
how to work around the std::auto_ptr&nbsp;/ std::map problem,
then this class may become deprecated.
@param T type of the pointer to manage
*/
template <typename T>
class AutoPtrAry {
public:
/// @brief Construct from an allocated resource.
/// The resource is freed if necessary.
/// AutoPtrAry takes over ownership of the resource.
explicit AutoPtrAry(T* res = 0)
throw(std::bad_exception): _res(res) {
res = 0;
}
/// @brief Takeover ownership from another AutoPtrAry.
AutoPtrAry(AutoPtrAry& o) throw(std::bad_exception):
_res(o.release()) {
}
//! @brief Do not use this method!
//! This method had to be introduced for the @c std::map, where
//! @c operator[] first creates an empty element, then assigns it
//! the real value. Because that empty element is temporary, gcc can
//! not use @c AutoResource(AutoResource&) since release 4.0.
AutoPtrAry(const AutoPtrAry& o) throw(std::bad_exception): _res(0) {
assert(o._res==0);
if (o._res!=0)
_res = const_cast<AutoPtrAry&>(o).release();
}
/// @brief Free resource. Calls @c reset().
~AutoPtrAry() throw(std::bad_exception) {reset();}
/// @brief Assign new resource. Calls @c reset().
/// The resource is freed if necessary.
AutoPtrAry& operator=(T* res) throw(std::bad_exception) {
return reset(res);
}
/// @brief Takeover ownership from another AutoResource.
/// Calls @c reset() from @c this and @c release() from @c other.
AutoPtrAry& operator=(AutoPtrAry& other) throw(std::bad_exception) {
return reset(other.release());
}
/// @brief Get the resource.
operator T* const() const throw(std::bad_exception) {
return _res;
}
/// @brief find out, if a value is set
/// @return @c true: resource is valid
operator bool() const throw(std::bad_exception) {
return _res!=0;
}
/// @brief Access the AutoPtrAry like a normal pointer.
T*const operator->() {return _res;}
/// @brief Dereference the AutoPtrAry like a normal pointer.
T& operator*() {return *_res;}
/// @brief get the resetted resource for resetting it.
/// Calls @c reset and returns the cleaned resource.
/// The intention is, that you can safely assign it a new value
/// (e.g. in an expression).
T* getClean() throw(std::bad_exception) {
reset();
return _res;
}
/// @brief Give away ownership of the resource.
/// @return old resource
T* release() throw(std::bad_exception) {
T* res(_res); _res=0;
return res;
}
/// @brief Assign a new resource.
/// The old resource of @c this is freed if necessary.
AutoPtrAry& reset(T* res = 0)
throw(std::bad_exception) {
delete[] _res;
_res = res;
return *this;
}
private:
T* _res; ///< the resource to be managed
};
/** @brief Automatically closes a file when destructed. /** @brief Automatically closes a file when destructed.
@pre \#include <mrw/auto.hpp> @pre \#include <mrw/auto.hpp>

@ -31,6 +31,26 @@
extern "C" void __cyg_profile_func_enter (void *, void *) __attribute__((no_instrument_function)); extern "C" void __cyg_profile_func_enter (void *, void *) __attribute__((no_instrument_function));
extern "C" void __cyg_profile_func_exit (void *, void *) __attribute__((no_instrument_function)); extern "C" void __cyg_profile_func_exit (void *, void *) __attribute__((no_instrument_function));
// support for log4cxx 0.9.7 and for new CVS version
#ifndef LOG4CXX_LOCATION
# define MRW_LOG4CXX_LOCATION pos.file.c_str(), pos.line
#define MRW_LEVEL_DEBUG ::log4cxx::Level::DEBUG
#define MRW_LEVEL_INFO ::log4cxx::Level::INFO
#define MRW_LEVEL_WARN ::log4cxx::Level::WARN
#define MRW_LEVEL_ERROR ::log4cxx::Level::ERROR
#define MRW_LEVEL_FATAL ::log4cxx::Level::FATAL
#else
# define LOG4CXX_CVS
# define MRW_LOG4CXX_LOCATION \
::log4cxx::spi::LocationInfo(pos.file.c_str(), pos.function.c_str(), pos.line)
#define MRW_LEVEL_DEBUG ::log4cxx::Level::getDebug()
#define MRW_LEVEL_INFO ::log4cxx::Level::getInfo()
#define MRW_LEVEL_WARN ::log4cxx::Level::getWarn()
#define MRW_LEVEL_ERROR ::log4cxx::Level::getError()
#define MRW_LEVEL_FATAL ::log4cxx::Level::getFatal()
#endif
namespace mrw { namespace mrw {
struct ThreadInfo { struct ThreadInfo {
@ -176,14 +196,20 @@ extern "C" void __cyg_profile_func_enter(void *this_fn, void*) {
(hierarchy.rfind(' ', std::min(hierarchy.find('<'), (hierarchy.rfind(' ', std::min(hierarchy.find('<'),
hierarchy.find("operator")))); hierarchy.find("operator"))));
if (p!=std::string::npos) hierarchy.erase(0, p+1); if (p!=std::string::npos) hierarchy.erase(0, p+1);
// hierarchy.erase
// (hierarchy.find_first_not_of
// ("qwertzuiopasdfghjklyxcvbnmQWERTZUIOPASDFGHJKLYXCVBNM1234567890_."));
if (hierarchy=="") hierarchy = "global";
std::string name("mrw.fn."+hierarchy);
log4cxx::Logger* logger log4cxx::Logger* logger
(log4cxx::Logger::getLogger(_T("mrw.fn.")+hierarchy)); (log4cxx::Logger::getLogger(log4cxx::String(name.begin(), name.end())));
if (logger->isDebugEnabled()) { if (logger->isDebugEnabled()) {
std::ostringstream ss; std::basic_ostringstream<log4cxx::String::value_type> ss;
ss<<std::setw(2+mrw::info.level++)<<std::setfill(' ') ss<<std::setw(2+mrw::info.level++)
<<"\\ "<<pos.function; <<std::setfill(log4cxx::String::value_type(' '))
logger->forcedLog(::log4cxx::Level::DEBUG, ss.str(), <<"\\ "<<log4cxx::String(pos.function.begin(), pos.function.end());
pos.file.c_str(), pos.line); logger->forcedLog(MRW_LEVEL_DEBUG, ss.str(),
MRW_LOG4CXX_LOCATION);
} }
} }
} catch (...) {} } catch (...) {}
@ -206,19 +232,25 @@ extern "C" void __cyg_profile_func_exit(void *this_fn, void*) {
for (std::string::size_type p(0); for (std::string::size_type p(0);
(p=hierarchy.find("::", p))!=std::string::npos; (p=hierarchy.find("::", p))!=std::string::npos;
hierarchy.replace(p, 2, ".")); hierarchy.replace(p, 2, "."));
hierarchy.erase(hierarchy.find('(')); hierarchy.erase(hierarchy.rfind('('));
std::string::size_type p std::string::size_type p
(hierarchy.rfind(' ', std::min(hierarchy.find('<'), (hierarchy.rfind(' ', std::min(hierarchy.find('<'),
hierarchy.find("operator")))); hierarchy.find("operator"))));
if (p!=std::string::npos) hierarchy.erase(0, p+1); if (p!=std::string::npos) hierarchy.erase(0, p+1);
// hierarchy.erase
// (hierarchy.find_first_not_of
// ("qwertzuiopasdfghjklyxcvbnmQWERTZUIOPASDFGHJKLYXCVBNM1234567890_."));
if (hierarchy=="") hierarchy = "global";
std::string name("mrw.fn."+hierarchy);
log4cxx::Logger* logger log4cxx::Logger* logger
(log4cxx::Logger::getLogger(_T("mrw.fn.")+hierarchy)); (log4cxx::Logger::getLogger(log4cxx::String(name.begin(), name.end())));
if (logger->isDebugEnabled()) { if (logger->isDebugEnabled()) {
std::ostringstream ss; std::basic_ostringstream<log4cxx::String::value_type> ss;
ss<<std::setw(2+--mrw::info.level)<<std::setfill(' ') ss<<std::setw(2+--mrw::info.level)
<<"/ "<<pos.function; <<std::setfill(log4cxx::String::value_type(' '))
logger->forcedLog(::log4cxx::Level::DEBUG, ss.str(), <<"/ "<<log4cxx::String(pos.function.begin(), pos.function.end());
pos.file.c_str(), pos.line); logger->forcedLog(MRW_LEVEL_DEBUG, ss.str(),
MRW_LOG4CXX_LOCATION);
} }
} }
} catch (...) {} } catch (...) {}

@ -11,11 +11,28 @@
*/ */
#include <mrw/stacktrace.hpp> #include <mrw/stacktrace.hpp>
#include <mrw/exception.hpp> #include <mrw/exception.hpp>
#include <csignal>
#include <exception> #include <exception>
#include <log4cxx/logger.h> #include <log4cxx/logger.h>
#ifndef _T
#define _T // support for log4cxx 0.9.7 and for new CVS version
#ifndef LOG4CXX_LOCATION
# define MRW_LOG4CXX_LOCATION __FILE__, __LINE__
#define MRW_LEVEL_DEBUG ::log4cxx::Level::DEBUG
#define MRW_LEVEL_INFO ::log4cxx::Level::INFO
#define MRW_LEVEL_WARN ::log4cxx::Level::WARN
#define MRW_LEVEL_ERROR ::log4cxx::Level::ERROR
#define MRW_LEVEL_FATAL ::log4cxx::Level::FATAL
#else
# define LOG4CXX_CVS
# define MRW_LOG4CXX_LOCATION \
::log4cxx::spi::LocationInfo(__FILE__, __FUNCTION__, __LINE__)
#define MRW_LEVEL_DEBUG ::log4cxx::Level::getDebug()
#define MRW_LEVEL_INFO ::log4cxx::Level::getInfo()
#define MRW_LEVEL_WARN ::log4cxx::Level::getWarn()
#define MRW_LEVEL_ERROR ::log4cxx::Level::getError()
#define MRW_LEVEL_FATAL ::log4cxx::Level::getFatal()
#endif #endif
namespace mrw { namespace mrw {
@ -27,8 +44,10 @@ namespace mrw {
If you link to the library @c libmrwexclog4cxx using a linker If you link to the library @c libmrwexclog4cxx using a linker
option such as: @c -lmrwexclog4cxx, then an unexpected and a option such as: @c -lmrwexclog4cxx, then an unexpected and a
terminate handler are registered, that trace a fatal error using terminate handler are registered, that trace a fatal error using
the log4cxx library. You don't need to change a single line in the log4cxx library. Also for all know signals there's a signal
your code! handler to trace the stack before termination (except in case of
a @c SIGTRAP, wehere the program is not terminated). You don't
need to change a single line in your code!
The log4cxx library is located at: The log4cxx library is located at:
- http://logging.apache.org/log4cxx - http://logging.apache.org/log4cxx
@ -49,7 +68,7 @@ namespace mrw {
@code @code
void unexpected_log4cxx() { void unexpected_log4cxx() {
log4cxx::LoggerPtr logger(log4cxx::Logger::getLogger(_T("mrw.stacktrace"))); log4cxx::LoggerPtr logger(log4cxx::Logger::getLogger("mrw.stacktrace"));
logger->fatal("Unexpected Exception", __FILE__, __LINE__); logger->fatal("Unexpected Exception", __FILE__, __LINE__);
StackTrace::createSymtable(); StackTrace::createSymtable();
std::string st((std::string)StackTrace()); std::string st((std::string)StackTrace());
@ -71,21 +90,27 @@ namespace mrw {
*/ */
void unexpected_log4cxx() { void unexpected_log4cxx() {
log4cxx::LoggerPtr logger(log4cxx::Logger::getLogger(_T("mrw.stacktrace"))); static const std::string name("mrw.stacktrace");
logger->fatal("Unexpected Exception", __FILE__, __LINE__); log4cxx::LoggerPtr logger
(log4cxx::Logger::getLogger(log4cxx::String(name.begin(), name.end())));
static const std::string txt("Unexpected Exception");
logger->fatal(log4cxx::String(txt.begin(), txt.end()), MRW_LOG4CXX_LOCATION);
StackTrace::createSymtable(); StackTrace::createSymtable();
std::string st((std::string)StackTrace()); std::string st((std::string)StackTrace());
try { try {
throw; throw;
} catch (const mrw::exception& x) { } catch (const mrw::exception& x) {
logger->fatal(std::string("Reason:\n")+x.what() std::string txt(std::string("Reason:\n")+x.what()
+"\nStack:\n"+x.stacktrace()); +"\nStack:\n"+x.stacktrace());
logger->fatal(log4cxx::String(txt.begin(), txt.end()));
} catch (const std::exception& x) { } catch (const std::exception& x) {
logger->fatal(std::string("Reason:\n")+x.what() std::string txt(std::string("Reason:\n")+x.what()
+"\nStack:\n"+st); +"\nStack:\n"+st);
logger->fatal(log4cxx::String(txt.begin(), txt.end()));
} catch (...) { } catch (...) {
logger->fatal(std::string("Reason: **** not available ****") std::string txt(std::string("Reason: **** not available ****")
+"\nStack:\n"+st); +"\nStack:\n"+st);
logger->fatal(log4cxx::String(txt.begin(), txt.end()));
} }
throw std::bad_exception(); throw std::bad_exception();
} }
@ -98,7 +123,7 @@ namespace mrw {
@code @code
void terminate_log4cxx() { void terminate_log4cxx() {
log4cxx::LoggerPtr logger(log4cxx::Logger::getLogger(_T("mrw.stacktrace"))); log4cxx::LoggerPtr logger(log4cxx::Logger::getLogger("mrw.stacktrace"));
logger->fatal("Uncaught Exception", __FILE__, __LINE__); logger->fatal("Uncaught Exception", __FILE__, __LINE__);
StackTrace::createSymtable(); StackTrace::createSymtable();
std::string st((std::string)StackTrace()); std::string st((std::string)StackTrace());
@ -121,35 +146,104 @@ namespace mrw {
*/ */
void terminate_log4cxx() { void terminate_log4cxx() {
log4cxx::LoggerPtr logger(log4cxx::Logger::getLogger(_T("mrw.stacktrace"))); static const std::string name("mrw.stacktrace");
logger->fatal("Uncaught Exception", __FILE__, __LINE__); log4cxx::LoggerPtr logger
(log4cxx::Logger::getLogger(log4cxx::String(name.begin(), name.end())));
static const std::string txt("Uncaught Exception");
logger->fatal(log4cxx::String(txt.begin(), txt.end()), MRW_LOG4CXX_LOCATION);
StackTrace::createSymtable(); StackTrace::createSymtable();
std::string st((std::string)StackTrace()); std::string st((std::string)StackTrace());
try { try {
throw; throw;
} catch (const mrw::exception& x) { } catch (const mrw::exception& x) {
logger->fatal(std::string("Reason:\n")+x.what() std::string txt(std::string("Reason:\n")+x.what()
+"\nStack:\n"+x.stacktrace()); +"\nStack:\n"+x.stacktrace());
logger->fatal(log4cxx::String(txt.begin(), txt.end()));
} catch (const std::exception& x) { } catch (const std::exception& x) {
logger->fatal(std::string("Reason:\n")+x.what() std::string txt(std::string("Reason:\n")+x.what()
+"\nStack:\n"+st); +"\nStack:\n"+st);
logger->fatal(log4cxx::String(txt.begin(), txt.end()));
} catch (...) { } catch (...) {
logger->fatal(std::string("Reason: **** not available ****") std::string txt(std::string("Reason: **** not available ****")
+"\nStack:\n"+st); +"\nStack:\n"+st);
logger->fatal(log4cxx::String(txt.begin(), txt.end()));
} }
exit(1); exit(1);
} }
/** @brief segmentation-fault handler, that traces using log4cxx
//@} The segmentation-fault handler is installed automatically when you link
to @c -lmrwexclog4cxx. The implementation of this handler is as follows:
@code
void signal_log4cxx(int sig) {
std::string txt;
bool abort(true);
switch sig {
case SIGFPE: txt="SIGFPE: Arithmetic error."; break;
case SIGILL: txt="SIGILL: Illegal instruction."; break;
case SIGSEGV: txt="SIGSEGV: Segmentation fault"
" (invalid access to valid memory)."; break;
case SIGBUS: txt="SIGBUS: Invalid pointer dereference"
" (access to an invalid memory address)."; break;
case SIGABRT: txt="SIGABRT: Funktion 'abort' was called."; break;
case SIGIOT: txt="SIGIOT: PDP-11 'iot' instruction"; break;
case SIGTRAP: txt="SIGTRAP: Breakpoint instruction."; abort=false; break;
case SIGEMT: txt="SIGEMT: Emulator trap."; break;
case SIGSYS: txt="SIGSYS: Bad system call."; break;
default: txt="Unknown Signal Nr. "+sig; break;
}
StackTrace::createSymtable();
std::string st((std::string)StackTrace());
log4cxx::LoggerPtr logger(log4cxx::Logger::getLogger("mrw.stacktrace"));
logger->fatal("Aborted by signal: "+txt+"\nStack:\n"+st);
if (abort) exit(1);
}
@endcode
*/
void signal_log4cxx(int sig) {
std::string txt;
bool abort(true);
switch (sig) {
case SIGFPE: txt="SIGFPE: Arithmetic error."; break;
case SIGILL: txt="SIGILL: Illegal instruction."; break;
case SIGSEGV: txt="SIGSEGV: Segmentation fault"
" (invalid access to valid memory)."; break;
case SIGBUS: txt="SIGBUS: Invalid pointer dereference"
" (access to an invalid memory address)."; break;
case SIGABRT: txt="SIGABRT: Funktion 'abort' was called."; break;
case SIGTRAP: txt="SIGTRAP: Breakpoint instruction."; abort=false; break;
case SIGSYS: txt="SIGSYS: Bad system call."; break;
default: txt="Unknown Signal Nr. "+sig; break;
}
StackTrace::createSymtable();
std::string st((std::string)StackTrace());
static const std::string name("mrw.stacktrace");
log4cxx::LoggerPtr logger
(log4cxx::Logger::getLogger(log4cxx::String(name.begin(), name.end())));
std::string errtxt("Aborted by signal: "+txt+"\nStack:\n"+st);
logger->fatal(log4cxx::String(errtxt.begin(), errtxt.end()));
if (abort) exit(1);
}
class AutoStackTrace { class AutoStackTrace {
public: public:
AutoStackTrace() { AutoStackTrace() {
std::set_unexpected(&mrw::unexpected_log4cxx); std::set_unexpected(&mrw::unexpected_log4cxx);
std::set_terminate(&mrw::terminate_log4cxx); std::set_terminate(&mrw::terminate_log4cxx);
std::signal(SIGFPE, &mrw::signal_log4cxx);
std::signal(SIGILL, &mrw::signal_log4cxx);
std::signal(SIGSEGV, &mrw::signal_log4cxx);
std::signal(SIGBUS, &mrw::signal_log4cxx);
std::signal(SIGTRAP, &mrw::signal_log4cxx);
std::signal(SIGSYS, &mrw::signal_log4cxx);
} }
}; };
//@}
// initialize stack traces (load symbols) // initialize stack traces (load symbols)
static AutoStackTrace _autoStackTrace; static AutoStackTrace _autoStackTrace;

@ -11,6 +11,7 @@
*/ */
#include <mrw/stacktrace.hpp> #include <mrw/stacktrace.hpp>
#include <mrw/exception.hpp> #include <mrw/exception.hpp>
#include <csignal>
#include <exception> #include <exception>
#include <iostream> #include <iostream>
@ -48,8 +49,10 @@ namespace mrw {
If you link to the library @c libmrwexcstderr using a linker If you link to the library @c libmrwexcstderr using a linker
option such as: @c -lmrwexcstderr, then an unexpected and a option such as: @c -lmrwexcstderr, then an unexpected and a
terminate handler are registered, that trace to the standard terminate handler are registered, that trace to the standard
error stream @c std::cerr. You don't need to change a single error stream @c std::cerr. Also for all know signals there's a
line in your code! signal handler to trace the stack before termination (except in
case of a @c SIGTRAP, wehere the program is not terminated). You
don't need to change a single line in your code!
*/ */
//@{ //@{
@ -163,6 +166,67 @@ namespace mrw {
exit(1); exit(1);
} }
/** @brief segmentation-fault handler, that traces using stderr
The segmentation-fault handler is installed automatically when you link
to @c -lmrwexcstderr. The implementation of this handler is as follows:
@code
void signal_stderr(int sig) {
std::cerr<<"SIGNAL RECEIVED: -------------------------------"<<std::endl;
std::string txt;
bool abort(true);
switch (sig) {
case SIGFPE: txt="SIGFPE: Arithmetic error."; break;
case SIGILL: txt="SIGILL: Illegal instruction."; break;
case SIGSEGV: txt="SIGSEGV: Segmentation fault"
" (invalid access to valid memory)."; break;
case SIGBUS: txt="SIGBUS: Invalid pointer dereference"
" (access to an invalid memory address)."; break;
case SIGABRT: txt="SIGABRT: Funktion 'abort' was called."; break;
case SIGTRAP: txt="SIGTRAP: Breakpoint instruction."; abort=false; break;
case SIGSYS: txt="SIGSYS: Bad system call."; break;
default: txt="Unknown Signal Nr. "+sig; break;
}
StackTrace::createSymtable();
std::string st((std::string)StackTrace());
stderr::LoggerPtr logger(stderr::Logger::getLogger(_T("mrw.stacktrace")));
std::cerr<<"---------- Reason:"<<std::endl
<<"Aborted by signal: "<<txt<<std::endl
<<"---------- Stack:"<<std::endl
<<st<<std::endl
<<"-------------------------------------------------"<<std::endl;
if (abort) exit(1);
}
@endcode
*/
void signal_stderr(int sig) {
std::cerr<<"SIGNAL RECEIVED: -------------------------------"<<std::endl;
std::string txt;
bool abort(true);
switch (sig) {
case SIGFPE: txt="SIGFPE: Arithmetic error."; break;
case SIGILL: txt="SIGILL: Illegal instruction."; break;
case SIGSEGV: txt="SIGSEGV: Segmentation fault"
" (invalid access to valid memory)."; break;
case SIGBUS: txt="SIGBUS: Invalid pointer dereference"
" (access to an invalid memory address)."; break;
case SIGABRT: txt="SIGABRT: Funktion 'abort' was called."; break;
case SIGTRAP: txt="SIGTRAP: Breakpoint instruction."; abort=false; break;
case SIGSYS: txt="SIGSYS: Bad system call."; break;
default: txt="Unknown Signal Nr. "+sig; break;
}
StackTrace::createSymtable();
std::string st((std::string)StackTrace());
std::cerr<<"---------- Reason:"<<std::endl
<<"Aborted by signal: "<<txt<<std::endl
<<"---------- Stack:"<<std::endl
<<st<<std::endl
<<"-------------------------------------------------"<<std::endl;
if (abort) exit(1);
}
//@} //@}
//@} //@}
@ -171,6 +235,13 @@ namespace mrw {
AutoStackTrace() { AutoStackTrace() {
std::set_unexpected(&mrw::unexpected_stderr); std::set_unexpected(&mrw::unexpected_stderr);
std::set_terminate(&mrw::terminate_stderr); std::set_terminate(&mrw::terminate_stderr);
std::signal(SIGFPE, &mrw::signal_stderr);
std::signal(SIGILL, &mrw::signal_stderr);
std::signal(SIGSEGV, &mrw::signal_stderr);
std::signal(SIGBUS, &mrw::signal_stderr);
std::signal(SIGIOT, &mrw::signal_stderr);
std::signal(SIGTRAP, &mrw::signal_stderr);
std::signal(SIGSYS, &mrw::signal_stderr);
} }
}; };

@ -87,7 +87,7 @@ PROJECT_NUMBER = "Version @MAJOR@.@MINOR@.@LEAST@"
# If a relative path is entered, it will be relative to the location # If a relative path is entered, it will be relative to the location
# where doxygen was started. If left blank the current directory will be used. # where doxygen was started. If left blank the current directory will be used.
OUTPUT_DIRECTORY = @top_builddir@doc OUTPUT_DIRECTORY = @top_builddir@/doc
# The OUTPUT_LANGUAGE tag is used to specify the language in which all # The OUTPUT_LANGUAGE tag is used to specify the language in which all
# documentation generated by doxygen is written. Doxygen will use this # documentation generated by doxygen is written. Doxygen will use this
@ -537,7 +537,7 @@ ALPHABETICAL_INDEX = YES
# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
# in which this list will be split (can be a number in the range [1..20]) # in which this list will be split (can be a number in the range [1..20])
COLS_IN_ALPHA_INDEX = 5 COLS_IN_ALPHA_INDEX = 3
# In case all classes in a project start with a common prefix, all # In case all classes in a project start with a common prefix, all
# classes will be put under the same header in the alphabetical index. # classes will be put under the same header in the alphabetical index.
@ -590,7 +590,7 @@ HTML_STYLESHEET = @srcdir@/style.css
# files or namespaces will be aligned in HTML using tables. If set to # files or namespaces will be aligned in HTML using tables. If set to
# NO a bullet list will be used. # NO a bullet list will be used.
HTML_ALIGN_MEMBERS = YES HTML_ALIGN_MEMBERS = NO
# If the GENERATE_HTMLHELP tag is set to YES, additional index files # If the GENERATE_HTMLHELP tag is set to YES, additional index files
# will be generated that can be used as input for tools like the # will be generated that can be used as input for tools like the

@ -24,30 +24,38 @@
#include <mrw/errno.hpp> #include <mrw/errno.hpp>
#include <mrw/string.hpp> #include <mrw/string.hpp>
#include <mrw/stdext.hpp>
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#ifndef __GLIBC__
#include <mrw/stdext.hpp>
#endif
mrw::Errno::Errno() throw(): _errno(errno) {} mrw::Errno::Errno() throw(): _errnoxxx(errno) {}
mrw::Errno::operator std::string() const throw(std::bad_exception) { mrw::Errno::operator std::string() const throw(std::bad_exception) {
#ifdef __GLIBC__ return *this;
char error[1024];
return !strerror_r(_errno, error, 1024) ?
error : std::string("errno=")+_errno;
#else
return mrw::ifelse(strerror(_errno), (std::string("errno=")+_errno).c_str());
#endif
} }
std::string mrw::Errno::string() const throw(std::bad_exception) { std::string mrw::Errno::string() const throw(std::bad_exception) {
#ifdef __GLIBC__ char* pos(0);
char error[1024]; char error[1024];
return !strerror_r(_errno, error, 1024) ? #ifdef __GLIBC__
error : std::string("errno=")+_errno; # if defined __USE_XOPEN2K && !defined __USE_GNU
return strerror_r(errno=_errnoxxx, error, 1024)!=-1
? error+std::string(" errno=")+_errnoxxx
: std::string("errno=")+_errnoxxx;
# else
return (pos=strerror_r(errno=_errnoxxx, error, 1024))
? pos+std::string(" errno=")+_errnoxxx
: std::string("errno=")+_errnoxxx;
# endif
#else #else
return mrw::ifelse(strerror(_errno), (std::string("errno=")+_errno).c_str()); # if defined __USE_XOPEN2K && !defined __USE_GNU
return strerror_r(errno=_errnoxxx, error, 1024)!=-1
? error+std::string(" errno=")+_errnoxxx
: std::string("errno=")+_errnoxxx;
# else
return (pos=strerror(errno=_errnoxxx))
? error+std::string(" errno=")+_errnoxxx
: std::string("errno=")+_errnoxxx;
# endif
#endif #endif
} }

@ -60,18 +60,19 @@ namespace mrw {
/// returns the @c errno stored in the constructor /// returns the @c errno stored in the constructor
operator int() const throw() { operator int() const throw() {
return _errno; return _errnoxxx;
} }
/// returns the @c errno stored in the constructor /// returns the @c errno stored in the constructor
int numerical() const throw() { int numerical() const throw() {
return _errno; return _errnoxxx;
} }
//.............................................................. variables //.............................................................. variables
private: private:
int _errno; int _errnoxxx; // "xxx" for MinGW-compatibility (there's a
// function named _errno)
}; };

@ -1,5 +1,4 @@
<div class="status">Last Change: $date</div> <div class="status">Last Build: $date</div>
<div class="feedback"></div>
<div class="author"><a href="http://marc.waeckerlin.org">The autor's page: http://marc.waeckerlin.org</a></div> <div class="author"><a href="http://marc.waeckerlin.org">The autor's page: http://marc.waeckerlin.org</a></div>
</body> </body>
</html> </html>

@ -34,10 +34,20 @@
// support for log4cxx 0.9.7 and for new CVS version // support for log4cxx 0.9.7 and for new CVS version
#ifndef LOG4CXX_LOCATION #ifndef LOG4CXX_LOCATION
# define MRW_LOG4CXX_LOCATION _file.c_str(), _line # define MRW_LOG4CXX_LOCATION _file.c_str(), _line
#define MRW_LEVEL_DEBUG ::log4cxx::Level::DEBUG
#define MRW_LEVEL_INFO ::log4cxx::Level::INFO
#define MRW_LEVEL_WARN ::log4cxx::Level::WARN
#define MRW_LEVEL_ERROR ::log4cxx::Level::ERROR
#define MRW_LEVEL_FATAL ::log4cxx::Level::FATAL
#else #else
# define LOG4CXX_CVS # define LOG4CXX_CVS
# define MRW_LOG4CXX_LOCATION \ # define MRW_LOG4CXX_LOCATION \
::log4cxx::spi::LocationInfo(_name.c_str(), _file.c_str(), _line) ::log4cxx::spi::LocationInfo(_file.c_str(), _name.c_str(), _line)
#define MRW_LEVEL_DEBUG ::log4cxx::Level::getDebug()
#define MRW_LEVEL_INFO ::log4cxx::Level::getInfo()
#define MRW_LEVEL_WARN ::log4cxx::Level::getWarn()
#define MRW_LEVEL_ERROR ::log4cxx::Level::getError()
#define MRW_LEVEL_FATAL ::log4cxx::Level::getFatal()
#endif #endif
namespace mrw { namespace mrw {
@ -48,11 +58,11 @@ namespace mrw {
/** @defgroup FunctionTrace Function Tracing (using log4cxx) /** @defgroup FunctionTrace Function Tracing (using log4cxx)
@pre \#include <mrw/functiontrace.hpp> @pre \#include <mrw/functiontrace.hpp>
Place the macro @ref METHOD as first line of all methods you want to Place the macro @ref MRW_METHOD as first line of all methods you want to
trace, and macro @ref FUNCTION as first line of all functions to be trace, and macro @ref MRW_FUNCTION as first line of all functions to be
traced. traced.
There are alternative macros @ref METHOD2 and @ref FUNCTION2, There are alternative macros @ref MRW_METHOD2 and @ref MRW_FUNCTION2,
that allow you to also specify the logging hierarchy. The that allow you to also specify the logging hierarchy. The
default for the hierarchy string is @c "mrw.fntrace". The default for the hierarchy string is @c "mrw.fntrace". The
logging level is always @c DEBUG and cannot be changed. logging level is always @c DEBUG and cannot be changed.
@ -71,7 +81,7 @@ namespace mrw {
\#include <mrw/functiontrace.hpp> \#include <mrw/functiontrace.hpp>
\#include <log4cxx/basicconfigurator.h> \#include <log4cxx/basicconfigurator.h>
void fn(int i=0) { void fn(int i=0) {
FUNCTION("fn(int)"); // trace entry and exit MRW_FUNCTION("fn(int)"); // trace entry and exit
if (i<4) fn(++i); if (i<4) fn(++i);
} }
class A { class A {
@ -80,13 +90,13 @@ namespace mrw {
method(); method();
} }
void method() { void method() {
METHOD("A::method()"); // trace entry and exit MRW_METHOD("A::method()"); // trace entry and exit
fn(); fn();
} }
}; };
int main(int, char**) { int main(int, char**) {
log4cxx::BasicConfigurator::configure(); log4cxx::BasicConfigurator::configure();
FUNCTION("main(int, char**)"); MRW_FUNCTION("main(int, char**)");
A().method(); A().method();
return 0; return 0;
} }
@ -144,7 +154,7 @@ namespace mrw {
namespace yyy { namespace yyy {
class Zzz { class Zzz {
public: void doIt(int, char) { public: void doIt(int, char) {
METHOD("xxx::yyy::Zzz::doIt(int, char)"); MRW_METHOD("xxx::yyy::Zzz::doIt(int, char)");
[...] [...]
} }
}; };
@ -155,7 +165,7 @@ namespace mrw {
@param name the full name of the method, including namespaces @param name the full name of the method, including namespaces
and class name and class name
*/ */
#define METHOD(name) mrw::FnTrace fnTrace(this, name, __FILE__, __LINE__) #define MRW_METHOD(name) mrw::FnTrace fnTrace(this, name, __FILE__, __LINE__)
/** @brief Declare function entrance, place as first line in functions. /** @brief Declare function entrance, place as first line in functions.
@ -168,7 +178,7 @@ namespace mrw {
namespace xxx { namespace xxx {
namespace yyy { namespace yyy {
void doIt(int, char) { void doIt(int, char) {
FUNCTION("xxx::yyy::doIt(int, char)"); MRW_FUNCTION("xxx::yyy::doIt(int, char)");
[...] [...]
} }
} }
@ -177,7 +187,7 @@ namespace mrw {
@param name the full name of the function, including namespaces @param name the full name of the function, including namespaces
*/ */
#define FUNCTION(name) mrw::FnTrace fnTrace(name, __FILE__, __LINE__) #define MRW_FUNCTION(name) mrw::FnTrace fnTrace(name, __FILE__, __LINE__)
/** @brief Declare method entrance, place as first line in method. /** @brief Declare method entrance, place as first line in method.
@ -193,7 +203,7 @@ namespace mrw {
namespace yyy { namespace yyy {
class Zzz { class Zzz {
public: void doIt(int, char) { public: void doIt(int, char) {
METHOD2("xxx::yyy::Zzz::doIt(int, char)", "fn.xxx.yyy.Zzz"); MRW_METHOD2("xxx::yyy::Zzz::doIt(int, char)", "fn.xxx.yyy.Zzz");
[...] [...]
} }
}; };
@ -205,7 +215,7 @@ namespace mrw {
and class name and class name
@param tracer the tracer hierarchy @param tracer the tracer hierarchy
*/ */
#define METHOD2(name, tracer) \ #define MRW_METHOD2(name, tracer) \
mrw::FnTrace fnTrace(this, name, __FILE__, __LINE__, tracer) mrw::FnTrace fnTrace(this, name, __FILE__, __LINE__, tracer)
/** @brief Declare function entrance, place as first line in functions. /** @brief Declare function entrance, place as first line in functions.
@ -221,7 +231,7 @@ namespace mrw {
namespace xxx { namespace xxx {
namespace yyy { namespace yyy {
void doIt(int, char) { void doIt(int, char) {
FUNCTION2("xxx::yyy::doIt(int, char)", "fn.xxx.yyy"); MRW_FUNCTION2("xxx::yyy::doIt(int, char)", "fn.xxx.yyy");
[...] [...]
} }
} }
@ -231,7 +241,7 @@ namespace mrw {
@param name the full name of the function, including namespaces @param name the full name of the function, including namespaces
@param tracer the tracer hierarchy @param tracer the tracer hierarchy
*/ */
#define FUNCTION2(name, tracer) \ #define MRW_FUNCTION2(name, tracer) \
mrw::FnTrace fnTrace(name, __FILE__, __LINE__, tracer) mrw::FnTrace fnTrace(name, __FILE__, __LINE__, tracer)
class FnTrace { class FnTrace {
@ -239,13 +249,15 @@ namespace mrw {
FnTrace(const void* addr, const std::string& name, FnTrace(const void* addr, const std::string& name,
const std::string& file, unsigned long line, const std::string& file, unsigned long line,
const std::string& tracer = "mrw.fntrace") throw(): const std::string& tracer = "mrw.fntrace") throw():
_addr(addr), _name(name), _file(file), _line(line), _tracer(tracer) { _addr(addr), _name(name.begin(), name.end()), _file(file), _line(line),
_tracer(tracer.begin(), tracer.end()) {
log4cxx::Logger* logger(log4cxx::Logger::getLogger(_tracer)); log4cxx::Logger* logger(log4cxx::Logger::getLogger(_tracer));
if (logger->isDebugEnabled()) { if (logger->isDebugEnabled()) {
std::stringstream oss; std::basic_stringstream<log4cxx::String::value_type> oss;
oss<<std::hex<<std::setw(15)<<_addr<<": "<<std::dec oss<<std::hex<<std::setw(15)<<_addr<<": "
<<std::setw(2+_level)<<std::setfill(' ')<<"\\ "<<_name; <<std::dec<<std::setw(2+_level)
logger->forcedLog(log4cxx::Level::DEBUG, oss.str(), <<std::setfill(log4cxx::String::value_type(' '))<<"\\ "<<_name;
logger->forcedLog(MRW_LEVEL_DEBUG, oss.str(),
MRW_LOG4CXX_LOCATION); MRW_LOG4CXX_LOCATION);
++_level; ++_level;
} }
@ -253,13 +265,15 @@ namespace mrw {
FnTrace(const std::string& name, FnTrace(const std::string& name,
const std::string& file, unsigned long line, const std::string& file, unsigned long line,
const std::string& tracer = "mrw.fntrace") throw(): const std::string& tracer = "mrw.fntrace") throw():
_addr(0), _name(name), _file(file), _line(line), _tracer(tracer) { _addr(0), _name(name.begin(), name.end()), _file(file), _line(line),
_tracer(tracer.begin(), tracer.end()) {
log4cxx::Logger* logger(log4cxx::Logger::getLogger(_tracer)); log4cxx::Logger* logger(log4cxx::Logger::getLogger(_tracer));
if (logger->isDebugEnabled()) { if (logger->isDebugEnabled()) {
std::stringstream oss; std::basic_stringstream<log4cxx::String::value_type> oss;
oss<<std::setw(17)<<' ' oss<<std::setw(17)<<' '
<<std::setw(2+_level)<<std::setfill(' ')<<"\\ "<<_name; <<std::setw(2+_level)<<std::setfill(log4cxx::String::value_type(' '))
logger->forcedLog(log4cxx::Level::DEBUG, oss.str(), <<"\\ "<<_name;
logger->forcedLog(MRW_LEVEL_DEBUG, oss.str(),
MRW_LOG4CXX_LOCATION); MRW_LOG4CXX_LOCATION);
++_level; ++_level;
} }
@ -268,22 +282,23 @@ namespace mrw {
log4cxx::Logger* logger(log4cxx::Logger::getLogger(_tracer)); log4cxx::Logger* logger(log4cxx::Logger::getLogger(_tracer));
if (logger->isDebugEnabled()) { if (logger->isDebugEnabled()) {
--_level; --_level;
std::stringstream oss; std::basic_stringstream<log4cxx::String::value_type> oss;
if (_addr) if (_addr)
oss<<std::hex<<std::setw(15)<<_addr<<": "<<std::dec; oss<<std::hex<<std::setw(15)<<_addr<<": "<<std::dec;
else else
oss<<std::setw(17)<<' '; oss<<std::setw(17)<<' ';
oss<<std::setw(2+_level)<<std::setfill(' ')<<"/ "<<_name; oss<<std::setw(2+_level)<<std::setfill(log4cxx::String::value_type(' '))
logger->forcedLog(log4cxx::Level::DEBUG, oss.str(), <<"/ "<<_name;
logger->forcedLog(MRW_LEVEL_DEBUG, oss.str(),
MRW_LOG4CXX_LOCATION); MRW_LOG4CXX_LOCATION);
} }
} }
private: private:
const void* _addr; const void* _addr;
const std::string _name; const log4cxx::String _name;
const std::string _file; const std::string _file;
unsigned long _line; unsigned long _line;
const std::string _tracer; const log4cxx::String _tracer;
/** @todo for multithreading, use thread specific storage */ /** @todo for multithreading, use thread specific storage */
static unsigned int _level; static unsigned int _level;
}; };

@ -36,32 +36,32 @@
class A { class A {
public: public:
A() { A() {
METHOD("A::A()"); MRW_METHOD("A::A()");
} }
~A() { ~A() {
METHOD("A::~A()"); MRW_METHOD("A::~A()");
} }
void fn1() { void fn1() {
METHOD("A::fn1()"); MRW_METHOD("A::fn1()");
fn2(); fn2();
} }
void fn2() { void fn2() {
METHOD("A::fn2()"); MRW_METHOD("A::fn2()");
fn3(); fn3();
fn4(); fn4();
} }
void fn3() { void fn3() {
METHOD("A::fn3()"); MRW_METHOD("A::fn3()");
fn4(); fn4();
} }
void fn4(bool flag=true) { void fn4(bool flag=true) {
METHOD("A::fn4()"); MRW_METHOD("A::fn4()");
if (flag) fn4(false); if (flag) fn4(false);
} }
}; };
void fn(A a) { void fn(A a) {
FUNCTION("fn(A)"); MRW_FUNCTION("fn(A)");
a.fn1(); a.fn1();
} }
@ -70,16 +70,27 @@ class FunctionTraceTest: public CppUnit::TestFixture {
void Init() { void Init() {
try {mrw::File::remove("functiontrace_test.log");} catch (...) {} try {mrw::File::remove("functiontrace_test.log");} catch (...) {}
log4cxx::helpers::Properties properties; log4cxx::helpers::Properties properties;
properties.setProperty("log4j.rootLogger", std::string name, cont;
"DEBUG, A1"); properties.setProperty((name="log4j.rootLogger",
properties.setProperty("log4j.appender.A1", log4cxx::String(name.begin(), name.end())),
"org.apache.log4j.FileAppender"); (cont="DEBUG, A1",
properties.setProperty("log4j.appender.A1.layout", log4cxx::String(cont.begin(), cont.end())));
"org.apache.log4j.PatternLayout"); properties.setProperty((name="log4j.appender.A1",
properties.setProperty("log4j.appender.A1.layout.ConversionPattern", log4cxx::String(name.begin(), name.end())),
"%F:%L - %m%n"); (cont="org.apache.log4j.FileAppender",
properties.setProperty("log4j.appender.A1.filename", log4cxx::String(cont.begin(), cont.end())));
"functiontrace_test.log"); properties.setProperty((name="log4j.appender.A1.layout",
log4cxx::String(name.begin(), name.end())),
(cont="org.apache.log4j.PatternLayout",
log4cxx::String(cont.begin(), cont.end())));
properties.setProperty((name="log4j.appender.A1.layout.ConversionPattern",
log4cxx::String(name.begin(), name.end())),
(cont="%F:%L - %m%n",
log4cxx::String(cont.begin(), cont.end())));
properties.setProperty((name="log4j.appender.A1.filename",
log4cxx::String(name.begin(), name.end())),
(cont="functiontrace_test.log",
log4cxx::String(cont.begin(), cont.end())));
log4cxx::PropertyConfigurator::configure(properties); log4cxx::PropertyConfigurator::configure(properties);
} }
void Calls() { void Calls() {

@ -14,7 +14,3 @@
</head> </head>
<body xml:lang="en-gb" <body xml:lang="en-gb"
lang="en-gb"> lang="en-gb">
<div class="kontakt" xml:lang="de-ch" lang="de:de-ch"><a class="target" name="top"></a><a href="&#109;&#97;&#105;&#108;&#116;&#111;:&#109;&#97;&#114;&#99;@&#119;&#97;&#101;&#99;&#107;&#101;&#114;&#108;&#105;&#110;&#46;&#111;&#114;&#103;&#10;">&#109;&#97;&#114;&#99;@&#119;&#97;&#101;&#99;&#107;&#101;&#114;&#108;&#105;&#110;&#46;&#111;&#114;&#103;&#10;</a></div>
<h1 class="main"><a href="http://marc.waeckerlin.org">$title</a></h1>

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

@ -64,8 +64,9 @@ namespace mrw {
-# <code>/etc/mrwlog4cxx</code> (global configuration) -# <code>/etc/mrwlog4cxx</code> (global configuration)
-# if no configuration file is found, use default configuration: -# if no configuration file is found, use default configuration:
@verbatim @verbatim
log4j.rootLogger = DEBUG, A1 log4j.rootLogger = WARN, A1
log4j.logger.mrw.fn = DEBUG log4j.logger.mrw.fntrace = OFF
log4j.logger.mrw.fn = OFF
log4j.logger.mrw.fn.log4cxx = OFF log4j.logger.mrw.fn.log4cxx = OFF
log4j.logger.mrw.fn.boost = OFF log4j.logger.mrw.fn.boost = OFF
log4j.logger.mrw.fn.Thread = OFF log4j.logger.mrw.fn.Thread = OFF
@ -84,17 +85,17 @@ log4j.appender.A1.layout = org.apache.log4j.PatternLayout
@endverbatim @endverbatim
and for multi threaded programs in addition: and for multi threaded programs in addition:
@verbatim @verbatim
log4j.appender.A1.layout.ConversionPattern = t-%-60c%m%n log4j.appender.A1.layout.ConversionPattern = \%t-\%-40l - \%m\%n
@endverbatim @endverbatim
on the other hand, single threaded programs are formatted as: on the other hand, single threaded programs are formatted as:
@verbatim @verbatim
log4j.appender.A1.layout.ConversionPattern = 60c%m%n log4j.appender.A1.layout.ConversionPattern = \%-40l - \%m\%n
@endverbatim @endverbatim
This results in the following behaviour: This results in the following behaviour:
- trace to console - trace to console
- format as... - format as...
- @c "%t-%-60c%m%n" if threaded - @c "\%t-\%-40l - \%m\%n" if threaded
- @c "%-60c%m%n" if not threaded - @c "\%-40l - \%m\%n" if not threaded
- enable all tracing to @c DEBUG - enable all tracing to @c DEBUG
- enable tracing of @ref AutoFunctionTrace - enable tracing of @ref AutoFunctionTrace
- disable function trace for @c log4cxx - disable function trace for @c log4cxx
@ -122,50 +123,94 @@ log4j.appender.A1.layout.ConversionPattern = 60c%m%n
else if (std::ifstream("/etc/mrwlog4cxx")) else if (std::ifstream("/etc/mrwlog4cxx"))
logconfigfile = "/etc/mrwlog4cxx"; logconfigfile = "/etc/mrwlog4cxx";
if (logconfigfile.size()) { if (logconfigfile.size()) {
log4cxx::PropertyConfigurator::configure(logconfigfile); log4cxx::PropertyConfigurator::configure
(log4cxx::String(logconfigfile.begin(), logconfigfile.end()));
return; return;
} }
log4cxx::helpers::Properties properties; log4cxx::helpers::Properties properties;
properties.setProperty("log4j.rootLogger", std::string name, cont;
"DEBUG, A1"); properties.setProperty((name="log4j.rootLogger",
properties.setProperty("log4j.logger.mrw.fn", log4cxx::String(name.begin(), name.end())),
"DEBUG"); (cont="WARN, A1",
properties.setProperty("log4j.logger.mrw.fn.log4cxx", log4cxx::String(cont.begin(), cont.end())));
"OFF"); properties.setProperty((name="log4j.logger.mrw.fntracea",
properties.setProperty("log4j.logger.mrw.fn.boost", log4cxx::String(name.begin(), name.end())),
"OFF"); (cont="OFF",
properties.setProperty("log4j.logger.mrw.fn.Thread", log4cxx::String(cont.begin(), cont.end())));
"OFF"); properties.setProperty((name="log4j.logger.mrw.fn",
properties.setProperty("log4j.logger.mrw.fn.QString", log4cxx::String(name.begin(), name.end())),
"OFF"); (cont="OFF",
properties.setProperty("log4j.logger.mrw.fn.QShared", log4cxx::String(cont.begin(), cont.end())));
"OFF"); properties.setProperty((name="log4j.logger.mrw.fn.log4cxx",
properties.setProperty("log4j.logger.mrw.fn.QWidget", log4cxx::String(name.begin(), name.end())),
"OFF"); (cont="OFF",
properties.setProperty("log4j.logger.mrw.fn.QRect", log4cxx::String(cont.begin(), cont.end())));
"OFF"); properties.setProperty((name="log4j.logger.mrw.fn.boost",
properties.setProperty("log4j.logger.mrw.fn.qstrcmp", log4cxx::String(name.begin(), name.end())),
"OFF"); (cont="OFF",
properties.setProperty("log4j.logger.mrw.fn.*.qt_cast", log4cxx::String(cont.begin(), cont.end())));
"OFF"); properties.setProperty((name="log4j.logger.mrw.fn.Thread",
properties.setProperty("log4j.logger.mrw.fn.mrw", log4cxx::String(name.begin(), name.end())),
"OFF"); (cont="OFF",
properties.setProperty("log4j.logger.mrw.fn.std", log4cxx::String(cont.begin(), cont.end())));
"OFF"); properties.setProperty((name="log4j.logger.mrw.fn.QString",
properties.setProperty("log4j.logger.mrw.fn.CppUnit", log4cxx::String(name.begin(), name.end())),
"OFF"); (cont="OFF",
properties.setProperty("log4j.logger.mrw.fn.__gnu_cxx", log4cxx::String(cont.begin(), cont.end())));
"OFF"); properties.setProperty((name="log4j.logger.mrw.fn.QShared",
properties.setProperty("log4j.appender.A1", log4cxx::String(name.begin(), name.end())),
"org.apache.log4j.ConsoleAppender"); (cont="OFF",
properties.setProperty("log4j.appender.A1.layout", log4cxx::String(cont.begin(), cont.end())));
"org.apache.log4j.PatternLayout"); properties.setProperty((name="log4j.logger.mrw.fn.QWidget",
log4cxx::String(name.begin(), name.end())),
(cont="OFF",
log4cxx::String(cont.begin(), cont.end())));
properties.setProperty((name="log4j.logger.mrw.fn.QRect",
log4cxx::String(name.begin(), name.end())),
(cont="OFF",
log4cxx::String(cont.begin(), cont.end())));
properties.setProperty((name="log4j.logger.mrw.fn.qstrcmp",
log4cxx::String(name.begin(), name.end())),
(cont="OFF",
log4cxx::String(cont.begin(), cont.end())));
properties.setProperty((name="log4j.logger.mrw.fn.*.qt_cast",
log4cxx::String(name.begin(), name.end())),
(cont="OFF",
log4cxx::String(cont.begin(), cont.end())));
properties.setProperty((name="log4j.logger.mrw.fn.mrw",
log4cxx::String(name.begin(), name.end())),
(cont="OFF",
log4cxx::String(cont.begin(), cont.end())));
properties.setProperty((name="log4j.logger.mrw.fn.std",
log4cxx::String(name.begin(), name.end())),
(cont="OFF",
log4cxx::String(cont.begin(), cont.end())));
properties.setProperty((name="log4j.logger.mrw.fn.CppUnit",
log4cxx::String(name.begin(), name.end())),
(cont="OFF",
log4cxx::String(cont.begin(), cont.end())));
properties.setProperty((name="log4j.logger.mrw.fn.__gnu_cxx",
log4cxx::String(name.begin(), name.end())),
(cont="OFF",
log4cxx::String(cont.begin(), cont.end())));
properties.setProperty((name="log4j.appender.A1",
log4cxx::String(name.begin(), name.end())),
(cont="org.apache.log4j.ConsoleAppender",
log4cxx::String(cont.begin(), cont.end())));
properties.setProperty((name="log4j.appender.A1.layout",
log4cxx::String(name.begin(), name.end())),
(cont="org.apache.log4j.PatternLayout",
log4cxx::String(cont.begin(), cont.end())));
#ifdef _MT #ifdef _MT
properties.setProperty("log4j.appender.A1.layout.ConversionPattern", properties.setProperty((name="log4j.appender.A1.layout.ConversionPattern",
"%t-%-60c%m%n"); log4cxx::String(name.begin(), name.end())),
(cont="%t-%-40l - %m%n",
log4cxx::String(cont.begin(), cont.end())));
#else #else
properties.setProperty("log4j.appender.A1.layout.ConversionPattern", properties.setProperty((name="log4j.appender.A1.layout.ConversionPattern",
"%-60c%m%n"); log4cxx::String(name.begin(), name.end())),
(cont="%-40l - %m%n",
log4cxx::String(cont.begin(), cont.end())));
#endif #endif
log4cxx::PropertyConfigurator::configure(properties); log4cxx::PropertyConfigurator::configure(properties);
} }

@ -9,7 +9,7 @@
## @license LGPL, see file <a href="license.html">COPYING</a> ## @license LGPL, see file <a href="license.html">COPYING</a>
## ##
AM_CPPFLAGS += -I${top_srcdir} AM_CPPFLAGS += -I$(top_srcdir)
if HAVE_STACKTRACE if HAVE_STACKTRACE
AM_CPPFLAGS += -DHAVE_STACKTRACE AM_CPPFLAGS += -DHAVE_STACKTRACE
@ -17,13 +17,14 @@ endif
CLEANFILES = doxygen.errors functiontrace_test.log \ CLEANFILES = doxygen.errors functiontrace_test.log \
mrwautofunctiontracelog4cxx_test.log \ mrwautofunctiontracelog4cxx_test.log \
mrwautofunctiontracelog4cxx_test-mt.log mrwautofunctiontracelog4cxx_test-mt.log \
examplesdir = ${pkgdatadir}/examples $(VALTESTS) valgrind.log
dist_examples_DATA = ${top_srcdir}/mrw/examples/* examplesdir = $(pkgdatadir)/examples
htmldir = ${pkgdatadir}/doc/html dist_examples_DATA = $(top_srcdir)/mrw/examples/*
html_DATA = ${top_builddir}/doc/html/index.html htmldir = $(pkgdatadir)/doc/html
pdfdir = ${pkgdatadir}/doc/pdf html_DATA = $(top_builddir)/doc/html/index.html
dist_pdf_DATA = ${top_builddir}/doc/latex/@PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@.pdf pdfdir = $(pkgdatadir)/doc/pdf
dist_pdf_DATA = $(top_builddir)/doc/latex/@PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@.pdf
lib_LTLIBRARIES = libmrw.la lib_LTLIBRARIES = libmrw.la
if HAVE_BOOST_THREAD if HAVE_BOOST_THREAD
@ -45,14 +46,10 @@ endif
endif endif
endif endif
if HAVE_LOG4CXX if HAVE_LOG4CXX
lib_LTLIBRARIES += libmrwexclog4cxx.la \ lib_LTLIBRARIES += libmrwexclog4cxx.la
libmrwlog4cxxconfiguration.la
if HAVE_THREADS
lib_LTLIBRARIES += libmrwlog4cxxconfiguration-mt.la
if HAVE_BOOST_THREAD if HAVE_BOOST_THREAD
lib_LTLIBRARIES += libmrwexclog4cxx-mt.la lib_LTLIBRARIES += libmrwexclog4cxx-mt.la
endif endif
endif
if AUTOFNTRACE if AUTOFNTRACE
lib_LTLIBRARIES += libmrwautofunctiontracelog4cxx.la lib_LTLIBRARIES += libmrwautofunctiontracelog4cxx.la
if HAVE_THREADS if HAVE_THREADS
@ -63,18 +60,33 @@ endif
endif endif
endif endif
endif endif
if HAVE_LOG4CXX
lib_LTLIBRARIES += libmrwlog4cxxconfiguration.la
if HAVE_THREADS
lib_LTLIBRARIES += libmrwlog4cxxconfiguration-mt.la
endif
endif
libmrw_la_SOURCES = \ libmrw_la_SOURCES = \
mrw.hpp version.cpp \ mrw.hpp version.cpp \
arg.cpp arg.hpp auto.hpp deque.hpp \ arg.cpp arg.hpp auto.hpp deque.hpp \
exception.cpp exception.hpp \ exception.cpp exception.hpp \
exec.cpp exec.hpp list.hpp \ list.hpp \
map.hpp multimap.hpp multiset.hpp \ map.hpp multimap.hpp multiset.hpp \
set.hpp \ set.hpp \
smartpointer.hpp stdext.cpp stdext.hpp \ smartpointer.hpp stdext.cpp stdext.hpp \
string.hpp unistd.hpp vector.hpp regexp.hpp regexp.cpp \ string.hpp unistd.hpp vector.hpp \
tokenizer.hpp configfile.hpp configfile.cpp file.hpp \ tokenizer.hpp \
errno.hpp errno.cpp errno.hpp errno.cpp
if HAVE_DIR
libmrw_la_SOURCES += file.hpp configfile.hpp configfile.cpp
endif
if HAVE_REGEXP
libmrw_la_SOURCES += regexp.hpp regexp.cpp
endif
if HAVE_EXEC
libmrw_la_SOURCES += exec.cpp exec.hpp
endif
if HAVE_LTDL if HAVE_LTDL
libmrw_la_SOURCES += dynamiclibrary.hpp libmrw_la_SOURCES += dynamiclibrary.hpp
endif endif
@ -93,33 +105,32 @@ endif
if HAVE_THREADS if HAVE_THREADS
if HAVE_BOOST_THREAD if HAVE_BOOST_THREAD
libmrw_mt_la_SOURCES = ${libmrw_la_SOURCES} libmrw_mt_la_SOURCES = $(libmrw_la_SOURCES)
libmrw_mt_la_CXXFLAGS = @THREADS@ libmrw_mt_la_CXXFLAGS = @THREADS@
libmrw_mt_la_LDFLAGS = ${libmrw_la_LDFLAGS} -version-info @LIB_VERSION@ \ libmrw_mt_la_LDFLAGS = $(libmrw_la_LDFLAGS) -version-info @LIB_VERSION@ \
@THREADS@ @THREADS@
libmrw_mt_la_LIBADD = ${libmrw_la_LIBADD} @BOOST_THREAD_LIB@ libmrw_mt_la_LIBADD = $(libmrw_la_LIBADD) @BOOST_THREAD_LIB@
endif endif
endif endif
if HAVE_STACKTRACE if HAVE_STACKTRACE
libmrwexcstderr_la_SOURCES = autostacktracestderr.cpp version.cpp libmrwexcstderr_la_SOURCES = autostacktracestderr.cpp version.cpp
libmrwexcstderr_la_LDFLAGS = -version-info @LIB_VERSION@ libmrwexcstderr_la_LDFLAGS = -version-info @LIB_VERSION@
libmrwexcstderr_la_LIBADD = ${top_builddir}/mrw/libmrw.la libmrwexcstderr_la_LIBADD = $(top_builddir)/mrw/libmrw.la
if HAVE_THREADS if HAVE_THREADS
if HAVE_BOOST_THREAD if HAVE_BOOST_THREAD
libmrwexcstderr_mt_la_SOURCES = autostacktracestderr.cpp version.cpp libmrwexcstderr_mt_la_SOURCES = autostacktracestderr.cpp version.cpp
libmrwexcstderr_mt_la_CXXFLAGS = @THREADS@ libmrwexcstderr_mt_la_CXXFLAGS = @THREADS@
libmrwexcstderr_mt_la_LDFLAGS = -version-info @LIB_VERSION@ @THREADS@ libmrwexcstderr_mt_la_LDFLAGS = -version-info @LIB_VERSION@ @THREADS@
libmrwexcstderr_mt_la_LIBADD = ${top_builddir}/mrw/libmrw-mt.la libmrwexcstderr_mt_la_LIBADD = $(top_builddir)/mrw/libmrw-mt.la
endif endif
endif endif
if AUTOFNTRACE if AUTOFNTRACE
libmrwautofunctiontracestdlog_la_SOURCES = autofunctiontracestdlog.cpp \ libmrwautofunctiontracestdlog_la_SOURCES = autofunctiontracestdlog.cpp \
version.cpp version.cpp
libmrwautofunctiontracestdlog_la_CXXFLAGS = -w libmrwautofunctiontracestdlog_la_CXXFLAGS = -w
libmrwautofunctiontracestdlog_la_LDFLAGS = -version-info @LIB_VERSION@ libmrwautofunctiontracestdlog_la_LDFLAGS = -version-info @LIB_VERSION@
libmrwautofunctiontracestdlog_la_LIBADD = ${top_builddir}/mrw/libmrw.la libmrwautofunctiontracestdlog_la_LIBADD = $(top_builddir)/mrw/libmrw.la
if HAVE_THREADS if HAVE_THREADS
if HAVE_BOOST_THREAD if HAVE_BOOST_THREAD
libmrwautofunctiontracestdlog_mt_la_SOURCES = \ libmrwautofunctiontracestdlog_mt_la_SOURCES = \
@ -128,38 +139,28 @@ if HAVE_BOOST_THREAD
libmrwautofunctiontracestdlog_mt_la_LDFLAGS = \ libmrwautofunctiontracestdlog_mt_la_LDFLAGS = \
-version-info @LIB_VERSION@ @THREADS@ -version-info @LIB_VERSION@ @THREADS@
libmrwautofunctiontracestdlog_mt_la_LIBADD = \ libmrwautofunctiontracestdlog_mt_la_LIBADD = \
${top_builddir}/mrw/libmrw-mt.la $(top_builddir)/mrw/libmrw-mt.la
endif endif
endif endif
endif endif
if HAVE_LOG4CXX if HAVE_LOG4CXX
libmrwexclog4cxx_la_SOURCES = autostacktracelog4cxx.cpp version.cpp libmrwexclog4cxx_la_SOURCES = autostacktracelog4cxx.cpp version.cpp
libmrwexclog4cxx_la_LDFLAGS = -version-info @LIB_VERSION@ libmrwexclog4cxx_la_LDFLAGS = -version-info @LIB_VERSION@
libmrwexclog4cxx_la_LIBADD = ${top_builddir}/mrw/libmrw.la -llog4cxx libmrwexclog4cxx_la_LIBADD = $(top_builddir)/mrw/libmrw.la -llog4cxx
libmrwlog4cxxconfiguration_la_SOURCES = log4cxxconfiguration.cpp version.cpp
libmrwlog4cxxconfiguration_la_LDFLAGS = -version-info @LIB_VERSION@
libmrwlog4cxxconfiguration_la_LIBADD = -llog4cxx
if HAVE_THREADS if HAVE_THREADS
if HAVE_BOOST_THREAD if HAVE_BOOST_THREAD
libmrwexclog4cxx_mt_la_SOURCES = autostacktracelog4cxx.cpp version.cpp libmrwexclog4cxx_mt_la_SOURCES = autostacktracelog4cxx.cpp version.cpp
libmrwexclog4cxx_mt_la_CXXFLAGS = @THREADS@ libmrwexclog4cxx_mt_la_CXXFLAGS = @THREADS@
libmrwexclog4cxx_mt_la_LDFLAGS = -version-info @LIB_VERSION@ @THREADS@ libmrwexclog4cxx_mt_la_LDFLAGS = -version-info @LIB_VERSION@ @THREADS@
libmrwexclog4cxx_mt_la_LIBADD = ${top_builddir}/mrw/libmrw-mt.la -llog4cxx libmrwexclog4cxx_mt_la_LIBADD = $(top_builddir)/mrw/libmrw-mt.la -llog4cxx
libmrwlog4cxxconfiguration_mt_la_SOURCES = log4cxxconfiguration.cpp \
version.cpp
libmrwlog4cxxconfiguration_mt_la_CXXFLAGS = @THREADS@
libmrwlog4cxxconfiguration_mt_la_LDFLAGS = -version-info @LIB_VERSION@ \
@THREADS@
libmrwlog4cxxconfiguration_mt_la_LIBADD = -llog4cxx
endif endif
endif endif
if AUTOFNTRACE if AUTOFNTRACE
libmrwautofunctiontracelog4cxx_la_SOURCES = autofunctiontracelog4cxx.cpp \ libmrwautofunctiontracelog4cxx_la_SOURCES = autofunctiontracelog4cxx.cpp \
version.cpp version.cpp
libmrwautofunctiontracelog4cxx_la_CXXFLAGS = -w libmrwautofunctiontracelog4cxx_la_CXXFLAGS = -w
libmrwautofunctiontracelog4cxx_la_LDFLAGS = -version-info @LIB_VERSION@ libmrwautofunctiontracelog4cxx_la_LDFLAGS = -version-info @LIB_VERSION@
libmrwautofunctiontracelog4cxx_la_LIBADD = ${top_builddir}/mrw/libmrw.la -llog4cxx libmrwautofunctiontracelog4cxx_la_LIBADD = $(top_builddir)/mrw/libmrw.la -llog4cxx
if HAVE_THREADS if HAVE_THREADS
if HAVE_BOOST_THREAD if HAVE_BOOST_THREAD
libmrwautofunctiontracelog4cxx_mt_la_SOURCES = \ libmrwautofunctiontracelog4cxx_mt_la_SOURCES = \
@ -168,159 +169,190 @@ if HAVE_BOOST_THREAD
libmrwautofunctiontracelog4cxx_mt_la_LDFLAGS = \ libmrwautofunctiontracelog4cxx_mt_la_LDFLAGS = \
-version-info @LIB_VERSION@ @THREADS@ -version-info @LIB_VERSION@ @THREADS@
libmrwautofunctiontracelog4cxx_mt_la_LIBADD = \ libmrwautofunctiontracelog4cxx_mt_la_LIBADD = \
${top_builddir}/mrw/libmrw-mt.la -llog4cxx $(top_builddir)/mrw/libmrw-mt.la -llog4cxx
endif endif
endif endif
endif endif
endif endif
endif endif
if HAVE_LOG4CXX
libmrwlog4cxxconfiguration_la_SOURCES = log4cxxconfiguration.cpp version.cpp
libmrwlog4cxxconfiguration_la_LDFLAGS = -version-info @LIB_VERSION@
libmrwlog4cxxconfiguration_la_LIBADD = -llog4cxx
if HAVE_THREADS
libmrwlog4cxxconfiguration_mt_la_SOURCES = log4cxxconfiguration.cpp \
version.cpp
libmrwlog4cxxconfiguration_mt_la_CXXFLAGS = @THREADS@
libmrwlog4cxxconfiguration_mt_la_LDFLAGS = -version-info @LIB_VERSION@ \
@THREADS@
libmrwlog4cxxconfiguration_mt_la_LIBADD = -llog4cxx
endif
endif
check_PROGRAMS = auto_test smartpointer_test exec_test stdext_test regexp_test \ VALGRIND_CHECKS = auto_test smartpointer_test stdext_test \
tokenizer_test configfile_test string_test tokenizer_test string_test
NO_VALGRIND_CHECKS =
if HAVE_DIR
VALGRIND_CHECKS += configfile_test
dist_check_SCRIPTS = configfile_check.sh
endif
if HAVE_REGEXP
VALGRIND_CHECKS += regexp_test
endif
if HAVE_EXEC
VALGRIND_CHECKS += exec_test
endif
if HAVE_LTDL if HAVE_LTDL
check_PROGRAMS += dynamiclibrary_test VALGRIND_CHECKS += dynamiclibrary_test
endif endif
if HAVE_LOG4CXX if HAVE_LOG4CXX
check_PROGRAMS += functiontrace_test VALGRIND_CHECKS += functiontrace_test
endif endif
dist_check_SCRIPTS = configfile_check.sh
if HAVE_STACKTRACE if HAVE_STACKTRACE
check_PROGRAMS += stacktrace_test mrwexcstderr_test NO_VALGRIND_CHECKS += stacktrace_test
VALGRIND_CHECKS += mrwexcstderr_test
if HAVE_LOG4CXX if HAVE_LOG4CXX
check_PROGRAMS += mrwexclog4cxx_test VALGRIND_CHECKS += mrwexclog4cxx_test
if AUTOFNTRACE if AUTOFNTRACE
check_PROGRAMS += mrwautofunctiontracelog4cxx_test NO_VALGRIND_CHECKS += mrwautofunctiontracelog4cxx_test
if HAVE_THREADS if HAVE_THREADS
if HAVE_BOOST_THREAD if HAVE_BOOST_THREAD
check_PROGRAMS += mrwautofunctiontracelog4cxx_test-mt NO_VALGRIND_CHECKS += mrwautofunctiontracelog4cxx_test-mt
endif endif
endif endif
endif endif
endif endif
endif endif
auto_test_SOURCES = auto_test.cpp version.cpp auto_test_SOURCES = auto_test.cpp version.cpp
auto_test_CPPFLAGS = -I${top_srcdir} @CPPUNIT_CFLAGS@ -g3 -O0 auto_test_CPPFLAGS = -I$(top_srcdir) @CPPUNIT_CFLAGS@ -g3 -O0
auto_test_CXXFLAGS = -g3 -O0 auto_test_CXXFLAGS = -g3 -O0
auto_test_LDFLAGS = @CPPUNIT_LIBS@ auto_test_LDFLAGS = @CPPUNIT_LIBS@ -L.libs
auto_test_LDADD = ${top_builddir}/mrw/libmrw.la auto_test_LDADD = $(top_builddir)/mrw/libmrw.la
if HAVE_STACKTRACE if HAVE_STACKTRACE
auto_test_LDADD += ${top_builddir}/mrw/libmrwexcstderr.la auto_test_LDADD += $(top_builddir)/mrw/libmrwexcstderr.la
endif endif
smartpointer_test_SOURCES = smartpointer_test.cpp version.cpp smartpointer_test_SOURCES = smartpointer_test.cpp version.cpp
smartpointer_test_CPPFLAGS = -I${top_srcdir} @CPPUNIT_CFLAGS@ -g3 -O0 smartpointer_test_CPPFLAGS = -I$(top_srcdir) @CPPUNIT_CFLAGS@ -g3 -O0
smartpointer_test_CXXFLAGS = -g3 -O0 smartpointer_test_CXXFLAGS = -g3 -O0
smartpointer_test_LDFLAGS = @CPPUNIT_LIBS@ smartpointer_test_LDFLAGS = @CPPUNIT_LIBS@ -L.libs
smartpointer_test_LDADD = ${top_builddir}/mrw/libmrw.la smartpointer_test_LDADD = $(top_builddir)/mrw/libmrw.la
if HAVE_STACKTRACE if HAVE_STACKTRACE
smartpointer_test_LDADD += ${top_builddir}/mrw/libmrwexcstderr.la smartpointer_test_LDADD += $(top_builddir)/mrw/libmrwexcstderr.la
endif endif
if HAVE_EXEC
exec_test_SOURCES = exec_test.cpp version.cpp exec_test_SOURCES = exec_test.cpp version.cpp
exec_test_CPPFLAGS = -I${top_srcdir} @CPPUNIT_CFLAGS@ -g3 -O0 exec_test_CPPFLAGS = -I$(top_srcdir) @CPPUNIT_CFLAGS@ -g3 -O0
exec_test_CXXFLAGS = -g3 -O0 exec_test_CXXFLAGS = -g3 -O0
exec_test_LDFLAGS = @CPPUNIT_LIBS@ exec_test_LDFLAGS = @CPPUNIT_LIBS@ -L.libs
exec_test_LDADD = ${top_builddir}/mrw/libmrw.la exec_test_LDADD = $(top_builddir)/mrw/libmrw.la
if HAVE_STACKTRACE if HAVE_STACKTRACE
exec_test_LDADD += ${top_builddir}/mrw/libmrwexcstderr.la exec_test_LDADD += $(top_builddir)/mrw/libmrwexcstderr.la
endif
endif endif
stdext_test_SOURCES = stdext_test.cpp version.cpp stdext_test_SOURCES = stdext_test.cpp version.cpp
stdext_test_CPPFLAGS = -I${top_srcdir} @CPPUNIT_CFLAGS@ -g3 -O0 stdext_test_CPPFLAGS = -I$(top_srcdir) @CPPUNIT_CFLAGS@ -g3 -O0
stdext_test_CXXFLAGS = -g3 -O0 stdext_test_CXXFLAGS = -g3 -O0
stdext_test_LDFLAGS = @CPPUNIT_LIBS@ stdext_test_LDFLAGS = @CPPUNIT_LIBS@ -L.libs
stdext_test_LDADD = ${top_builddir}/mrw/libmrw.la stdext_test_LDADD = $(top_builddir)/mrw/libmrw.la
if HAVE_STACKTRACE if HAVE_STACKTRACE
stdext_test_LDADD += ${top_builddir}/mrw/libmrwexcstderr.la stdext_test_LDADD += $(top_builddir)/mrw/libmrwexcstderr.la
endif endif
string_test_SOURCES = string_test.cpp version.cpp string_test_SOURCES = string_test.cpp version.cpp
string_test_CPPFLAGS = -I${top_srcdir} @CPPUNIT_CFLAGS@ -g3 -O0 string_test_CPPFLAGS = -I$(top_srcdir) @CPPUNIT_CFLAGS@ -g3 -O0
string_test_CXXFLAGS = -g3 -O0 string_test_CXXFLAGS = -g3 -O0
string_test_LDFLAGS = @CPPUNIT_LIBS@ string_test_LDFLAGS = @CPPUNIT_LIBS@ -L.libs
string_test_LDADD = ${top_builddir}/mrw/libmrw.la string_test_LDADD = $(top_builddir)/mrw/libmrw.la
if HAVE_STACKTRACE if HAVE_STACKTRACE
string_test_LDADD += ${top_builddir}/mrw/libmrwexcstderr.la string_test_LDADD += $(top_builddir)/mrw/libmrwexcstderr.la
endif endif
regexp_test_SOURCES = regexp_test.cpp version.cpp if HAVE_REGEXP
regexp_test_CPPFLAGS = -I${top_srcdir} @CPPUNIT_CFLAGS@ -g3 -O0 regexp_test_SOURCES = regexp_test.cpp version.cpp
regexp_test_CXXFLAGS = -g3 -O0 regexp_test_CPPFLAGS = -I$(top_srcdir) @CPPUNIT_CFLAGS@ -g3 -O0
regexp_test_LDFLAGS = @CPPUNIT_LIBS@ regexp_test_CXXFLAGS = -g3 -O0
regexp_test_LDADD = ${top_builddir}/mrw/libmrw.la regexp_test_LDFLAGS = @CPPUNIT_LIBS@ -L.libs
regexp_test_LDADD = $(top_builddir)/mrw/libmrw.la
if HAVE_STACKTRACE if HAVE_STACKTRACE
regexp_test_LDADD += ${top_builddir}/mrw/libmrwexcstderr.la regexp_test_LDADD += $(top_builddir)/mrw/libmrwexcstderr.la
endif
endif endif
tokenizer_test_SOURCES = tokenizer_test.cpp version.cpp tokenizer_test_SOURCES = tokenizer_test.cpp version.cpp
tokenizer_test_CPPFLAGS = -I${top_srcdir} @CPPUNIT_CFLAGS@ -g3 -O0 tokenizer_test_CPPFLAGS = -I$(top_srcdir) @CPPUNIT_CFLAGS@ -g3 -O0
tokenizer_test_CXXFLAGS = -g3 -O0 tokenizer_test_CXXFLAGS = -g3 -O0
tokenizer_test_LDFLAGS = @CPPUNIT_LIBS@ tokenizer_test_LDFLAGS = @CPPUNIT_LIBS@ -L.libs
tokenizer_test_LDADD = ${top_builddir}/mrw/libmrw.la tokenizer_test_LDADD = $(top_builddir)/mrw/libmrw.la
if HAVE_STACKTRACE if HAVE_STACKTRACE
tokenizer_test_LDADD += ${top_builddir}/mrw/libmrwexcstderr.la tokenizer_test_LDADD += $(top_builddir)/mrw/libmrwexcstderr.la
endif endif
configfile_test_SOURCES = configfile_test.cpp version.cpp if HAVE_DIR
configfile_test_CPPFLAGS = -I${top_srcdir} @CPPUNIT_CFLAGS@ -g3 -O0 configfile_test_SOURCES = configfile_test.cpp version.cpp
configfile_test_CXXFLAGS = -g3 -O0 configfile_test_CPPFLAGS = -I$(top_srcdir) @CPPUNIT_CFLAGS@ -g3 -O0
configfile_test_LDFLAGS = @CPPUNIT_LIBS@ configfile_test_CXXFLAGS = -g3 -O0
configfile_test_LDADD = ${top_builddir}/mrw/libmrw.la configfile_test_LDFLAGS = @CPPUNIT_LIBS@ -L.libs
configfile_test_LDADD = $(top_builddir)/mrw/libmrw.la
if HAVE_STACKTRACE if HAVE_STACKTRACE
configfile_test_LDADD += ${top_builddir}/mrw/libmrwexcstderr.la configfile_test_LDADD += $(top_builddir)/mrw/libmrwexcstderr.la
endif
endif endif
if HAVE_LTDL if HAVE_LTDL
check_LTLIBRARIES = libdynamiclibrary_testlib.la check_LTLIBRARIES = libdynamiclibrary_testlib.la
libdynamiclibrary_testlib_la_SOURCES = dynamiclibrary_testlib.cpp libdynamiclibrary_testlib_la_SOURCES = dynamiclibrary_testlib.cpp
libdynamiclibrary_testlib_la_LDFLAGS = -module -rpath /bullshit libdynamiclibrary_testlib_la_LDFLAGS = -module -rpath /bullshit
dynamiclibrary_test_SOURCES = dynamiclibrary_test.cpp version.cpp dynamiclibrary_test_SOURCES = dynamiclibrary_test.cpp version.cpp
dynamiclibrary_test_CPPFLAGS = -I${top_srcdir} @CPPUNIT_CFLAGS@ -g3 -O0 dynamiclibrary_test_CPPFLAGS = -I$(top_srcdir) @CPPUNIT_CFLAGS@ -g3 -O0
dynamiclibrary_test_CXXFLAGS = -g3 -O0 dynamiclibrary_test_CXXFLAGS = -g3 -O0
dynamiclibrary_test_LDFLAGS = @CPPUNIT_LIBS@ dynamiclibrary_test_LDFLAGS = @CPPUNIT_LIBS@ -L.libs
dynamiclibrary_test_LDADD = ${top_builddir}/mrw/libmrw.la -lltdl dynamiclibrary_test_LDADD = $(top_builddir)/mrw/libmrw.la -lltdl
endif endif
if HAVE_LOG4CXX if HAVE_LOG4CXX
functiontrace_test_SOURCES = functiontrace_test.cpp version.cpp functiontrace_test_SOURCES = functiontrace_test.cpp version.cpp
functiontrace_test_CPPFLAGS = -I${top_srcdir} @CPPUNIT_CFLAGS@ -g3 -O0 functiontrace_test_CPPFLAGS = -I$(top_srcdir) @CPPUNIT_CFLAGS@ -g3 -O0
functiontrace_test_CXXFLAGS = -g3 -O0 functiontrace_test_CXXFLAGS = -g3 -O0
functiontrace_test_LDFLAGS = @CPPUNIT_LIBS@ functiontrace_test_LDFLAGS = @CPPUNIT_LIBS@ -L.libs
functiontrace_test_LDADD = ${top_builddir}/mrw/libmrw.la -llog4cxx functiontrace_test_LDADD = $(top_builddir)/mrw/libmrw.la -llog4cxx
if HAVE_STACKTRACE if HAVE_STACKTRACE
functiontrace_test_LDADD += ${top_builddir}/mrw/libmrwexcstderr.la functiontrace_test_LDADD += $(top_builddir)/mrw/libmrwexcstderr.la
endif endif
endif endif
if HAVE_STACKTRACE if HAVE_STACKTRACE
stacktrace_test_SOURCES = stacktrace_test.cpp version.cpp stacktrace_test_SOURCES = stacktrace_test.cpp version.cpp
stacktrace_test_CPPFLAGS = -I${top_srcdir} @CPPUNIT_CFLAGS@ -g3 -O0 stacktrace_test_CPPFLAGS = -I$(top_srcdir) @CPPUNIT_CFLAGS@ -g3 -O0
stacktrace_test_CXXFLAGS = -g3 -O0 stacktrace_test_CXXFLAGS = -g3 -O0
stacktrace_test_LDFLAGS = @CPPUNIT_LIBS@ stacktrace_test_LDFLAGS = @CPPUNIT_LIBS@ -L.libs
stacktrace_test_LDADD = ${top_builddir}/mrw/libmrw.la ${top_builddir}/mrw/libmrwexcstderr.la stacktrace_test_LDADD = $(top_builddir)/mrw/libmrw.la $(top_builddir)/mrw/libmrwexcstderr.la
mrwexcstderr_test_SOURCES = mrwexcstderr_test.cpp version.cpp mrwexcstderr_test_SOURCES = mrwexcstderr_test.cpp version.cpp
mrwexcstderr_test_CPPFLAGS = -I${top_srcdir} @CPPUNIT_CFLAGS@ -g3 -O0 mrwexcstderr_test_CPPFLAGS = -I$(top_srcdir) @CPPUNIT_CFLAGS@ -g3 -O0
mrwexcstderr_test_CXXFLAGS = -g3 -O0 mrwexcstderr_test_CXXFLAGS = -g3 -O0
mrwexcstderr_test_LDFLAGS = @CPPUNIT_LIBS@ mrwexcstderr_test_LDFLAGS = @CPPUNIT_LIBS@ -L.libs
mrwexcstderr_test_LDADD = ${top_builddir}/mrw/libmrwexcstderr.la mrwexcstderr_test_LDADD = $(top_builddir)/mrw/libmrwexcstderr.la
if HAVE_LOG4CXX if HAVE_LOG4CXX
mrwexclog4cxx_test_SOURCES = mrwexclog4cxx_test.cpp version.cpp mrwexclog4cxx_test_SOURCES = mrwexclog4cxx_test.cpp version.cpp
mrwexclog4cxx_test_CPPFLAGS = -I${top_srcdir} @CPPUNIT_CFLAGS@ -g3 -O0 mrwexclog4cxx_test_CPPFLAGS = -I$(top_srcdir) @CPPUNIT_CFLAGS@ -g3 -O0
mrwexclog4cxx_test_CXXFLAGS = -g3 -O0 mrwexclog4cxx_test_CXXFLAGS = -g3 -O0
mrwexclog4cxx_test_LDFLAGS = @CPPUNIT_LIBS@ mrwexclog4cxx_test_LDFLAGS = @CPPUNIT_LIBS@ -L.libs
mrwexclog4cxx_test_LDADD = ${top_builddir}/mrw/libmrwexclog4cxx.la -llog4cxx mrwexclog4cxx_test_LDADD = $(top_builddir)/mrw/libmrwexclog4cxx.la -llog4cxx
if AUTOFNTRACE if AUTOFNTRACE
mrwautofunctiontracelog4cxx_test_SOURCES = \ mrwautofunctiontracelog4cxx_test_SOURCES = \
mrwautofunctiontracelog4cxx_test.cpp version.cpp mrwautofunctiontracelog4cxx_test.cpp version.cpp
mrwautofunctiontracelog4cxx_test_CPPFLAGS = \ mrwautofunctiontracelog4cxx_test_CPPFLAGS = \
-I${top_srcdir} @CPPUNIT_CFLAGS@ -finstrument-functions -g3 -O0 -I$(top_srcdir) @CPPUNIT_CFLAGS@ -finstrument-functions -g3 -O0
mrwautofunctiontracelog4cxx_test_CXXFLAGS = -g3 -O0 -finstrument-functions mrwautofunctiontracelog4cxx_test_CXXFLAGS = -g3 -O0 -finstrument-functions
mrwautofunctiontracelog4cxx_test_LDFLAGS = \ mrwautofunctiontracelog4cxx_test_LDFLAGS = \
@CPPUNIT_LIBS@ -finstrument-functions @CPPUNIT_LIBS@ -L.libs -finstrument-functions
mrwautofunctiontracelog4cxx_test_LDADD = \ mrwautofunctiontracelog4cxx_test_LDADD = \
-llog4cxx ${top_builddir}/mrw/libmrwautofunctiontracelog4cxx.la -llog4cxx $(top_builddir)/mrw/libmrwautofunctiontracelog4cxx.la
if HAVE_THREADS if HAVE_THREADS
if HAVE_BOOST_THREAD if HAVE_BOOST_THREAD
mrwautofunctiontracelog4cxx_test_mt_SOURCES = \ mrwautofunctiontracelog4cxx_test_mt_SOURCES = \
mrwautofunctiontracelog4cxx_test.cpp version.cpp mrwautofunctiontracelog4cxx_test.cpp version.cpp
mrwautofunctiontracelog4cxx_test_mt_CPPFLAGS = \ mrwautofunctiontracelog4cxx_test_mt_CPPFLAGS = \
-I${top_srcdir} @CPPUNIT_CFLAGS@ -finstrument-functions -g3 -O0 -I$(top_srcdir) @CPPUNIT_CFLAGS@ -finstrument-functions -g3 -O0
mrwautofunctiontracelog4cxx_test_mt_CXXFLAGS = -g3 -O0 \ mrwautofunctiontracelog4cxx_test_mt_CXXFLAGS = -g3 -O0 \
-finstrument-functions @THREADS@ -finstrument-functions @THREADS@
mrwautofunctiontracelog4cxx_test_mt_LDFLAGS = \ mrwautofunctiontracelog4cxx_test_mt_LDFLAGS = \
@CPPUNIT_LIBS@ @THREADS@ -finstrument-functions @CPPUNIT_LIBS@ -L.libs @THREADS@ -finstrument-functions
mrwautofunctiontracelog4cxx_test_mt_LDADD = \ mrwautofunctiontracelog4cxx_test_mt_LDADD = \
-llog4cxx ${top_builddir}/mrw/libmrwautofunctiontracelog4cxx-mt.la @BOOST_THREAD_LIB@ -llog4cxx $(top_builddir)/mrw/libmrwautofunctiontracelog4cxx-mt.la @BOOST_THREAD_LIB@
endif endif
endif endif
endif endif
@ -328,51 +360,59 @@ endif
endif endif
dist_check_DATA = test.dat configfile.ini configfile.ini.result dist_check_DATA = test.dat configfile.ini configfile.ini.result
EXTRA_DIST = head.html foot.html style.css EXTRA_DIST = head.html foot.html style.css hintergrund.png
TESTS = ${check_PROGRAMS} ${dist_check_SCRIPTS} if HAVE_VALGRIND
VALTESTS=$(VALGRIND_CHECKS:%=valcheck_%)
TESTS = $(VALTESTS) $(NO_VALGRIND_CHECKS) $(dist_check_SCRIPTS)
valcheck_%: %
echo "LD_LIBRARY_PATH=.libs $(top_srcdir)/valcheck.sh .libs/$<" > $@
chmod ugo+x $@
else
TESTS = $(check_PROGRAMS) $(dist_check_SCRIPTS)
endif
check_PROGRAMS = $(VALGRIND_CHECKS) $(NO_VALGRIND_CHECKS)
.PHONY: doc clean-local distclean-local dist-hool install-data-hook \ .PHONY: doc clean-local distclean-local dist-hool install-data-hook \
uninstall-hook uninstall-hook
deps = ${top_srcdir}/COPYING ${top_srcdir}/README ${top_srcdir}/INSTALL ${top_srcdir}/NEWS ${top_srcdir}/ChangeLog deps = $(top_srcdir)/COPYING $(top_srcdir)/README $(top_srcdir)/INSTALL $(top_srcdir)/NEWS $(top_srcdir)/ChangeLog
doc: ${top_builddir}/doc/html/index.html ${top_builddir}/doc/latex/@PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@.pdf doc: $(top_builddir)/doc/html/index.html $(top_builddir)/doc/latex/@PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@.pdf
${html_DATA}: doxyfile *.[ch]pp ${deps} style.css head.html foot.html $(html_DATA): doxyfile *.[ch]pp $(deps) style.css head.html foot.html
test -d ${top_builddir}/doc/latex || mkdir -p ${top_builddir}/doc/latex test -d $(top_builddir)/doc/latex || mkdir -p $(top_builddir)/doc/latex
test -d ${top_builddir}/doc/html || mkdir -p ${top_builddir}/doc/html test -d $(top_builddir)/doc/html || mkdir -p $(top_builddir)/doc/html
@test -f ${top_builddir}/doc/html/hintergrund.png || \ @test -f $(top_builddir)/doc/html/hintergrund.png || \
cp ~/www/marc/linux/hintergrund.png \ cp $(srcdir)/hintergrund.png \
${top_builddir}/doc/html || \ $(top_builddir)/doc/html
( \
echo "**** sorry, you are missing the html background image"; \
echo " (after distclean doc/html/hintergrund.png is deleted)" \
)
doxygen doxyfile doxygen doxyfile
if PEDANTIC if PEDANTIC
test \! -s doxygen.errors test \! -s doxygen.errors
endif endif
${top_builddir}/doc/latex/@PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@.pdf: doxyfile *.[ch]pp ${deps} ${html_DATA} $(top_builddir)/doc/latex/@PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@.pdf: doxyfile *.[ch]pp $(deps) $(html_DATA)
cd ${top_builddir}/doc/latex && make && \ cd $(top_builddir)/doc/latex && make && \
mv refman.pdf @PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@.pdf mv refman.pdf @PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@.pdf
clean-local: clean-local:
- rm doxygen.err libmrw.doxytag - rm doxygen.err libmrw.doxytag
distclean-local: distclean-local:
- rm -r ${top_builddir}/doc/html/* ${top_builddir}/doc/latex/* - rm -r $(top_builddir)/doc/html/* $(top_builddir)/doc/latex/*
- rm makefile makefile.in doxygen.err libmrw.doxytag - rm makefile makefile.in doxygen.err libmrw.doxytag
dist-hook: dist-hook:
test -d ${distdir}/doc/html || \ test -d $(distdir)/doc/html || \
mkdir -p ${distdir}/doc/html mkdir -p $(distdir)/doc/html
cp ${top_builddir}/doc/html/* ${distdir}/doc/html/. cp $(top_builddir)/doc/html/* $(distdir)/doc/html/.
install-data-hook: install-data-hook:
chmod -R u+w ${pkgdatadir}/doc env | grep -i tmp
cp -rf ${top_builddir}/doc/html ${pkgdatadir}/doc/ test -d "$(DESTDIR)$(pkgdatadir)/doc" || \
mkdir -p "$(DESTDIR)$(pkgdatadir)/doc"
chmod -R u+w "$(DESTDIR)$(pkgdatadir)/doc"
cp -rf $(top_builddir)/doc/html "$(DESTDIR)$(pkgdatadir)/doc/"
uninstall-hook: uninstall-hook:
chmod -R u+w ${pkgdatadir}/doc chmod -R u+w "$(DESTDIR)$(pkgdatadir)/doc"
rm -rf ${pkgdatadir}/doc/html rm -rf "$(DESTDIR)$(pkgdatadir)/doc/html"

@ -1,7 +1,15 @@
/** @mainpage /** @mainpage
The official homepage is on: The official homepage is on:
- http://marc.waeckerlin.org/@PACKAGENAME@/index.html - http://marc.waeckerlin.org/computer/c_/mrw-c_/index
The minimal runtime package (for use with VideoreKorder):
Minimalpaket (f&uuml;r den VideoreKorder):
- <a href="/downloads/@PACKAGENAME@-minimal-@MAJOR@.@MINOR@.@LEAST@-1.i586.rpm">@PACKAGENAME@-minimal-@MAJOR@.@MINOR@.@LEAST@-1.i586.rpm</a>
More downloads see @ref downloads.
All features are listed on the <a All features are listed on the <a
href="modules.html">"Modules"</a> page. href="modules.html">"Modules"</a> page.
@ -39,8 +47,8 @@
See the <a href="pages.html">"Related Pages"</a>. See the <a href="pages.html">"Related Pages"</a>.
- @ref downloads
- @ref readme - @ref readme
- @ref download
- @ref usage - @ref usage
- @ref threads - @ref threads
- @ref libversion - @ref libversion
@ -50,63 +58,53 @@
- @ref changes - @ref changes
*/ */
/** @page download Download and Installation /** @page downloads Download and Installation of the MRW-C++ Library
Download this documentation in PDF:
- <a href="/downloads/@PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@.pdf">@PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@.pdf</a>
Download this version from here: Download this version from here:
- Requirements:
- Boost thread library for multi threading:
http://boost.org
- log4cxx for automated tracing and function traces:
- http://logging.apache.org/log4cxx
- RPM: http://marc.waeckerlin.org/mrw-c++/log4cxx-0.9.7-3.i386.rpm
- @ref mrw::StackTrace requires:
- the GNU Binutils
- either GNU Compiler gcc or GNU C library glibc
- runs better on: either Linux or Solaris
- Binary
- Binary RPM Packages (built on i586/SuSE):
- http://marc.waeckerlin.org/@PACKAGENAME@/@PACKAGENAME@-minimal-@MAJOR@.@MINOR@.@LEAST@-1.i586.rpm
- Minimal runtime package without debugging support.
Does not depend on boost and log4cxx and ltdl.
To be used
e.g. with http://marc.waeckerlin.org/videorekorder
- Installation:<br />
<code>rpm -Uvh @PACKAGENAME@-minimal-@MAJOR@.@MINOR@.@LEAST@-1.i586.rpm</code>
- http://marc.waeckerlin.org/@PACKAGENAME@/@PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@-1.i586.rpm
- Full runtime library, no multithreading.
- Installation:<br />
<code>rpm -Uvh @PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@-1.i586.rpm</code>
- http://marc.waeckerlin.org/@PACKAGENAME@/@PACKAGENAME@-mt-@MAJOR@.@MINOR@.@LEAST@-1.i586.rpm
- Full runtime library, with multithreading support.
- Installation:<br />
<code>rpm -Uvh @PACKAGENAME@-mt-@MAJOR@.@MINOR@.@LEAST@-1.i586.rpm</code>
- http://marc.waeckerlin.org/@PACKAGENAME@/@PACKAGENAME@-devel-@MAJOR@.@MINOR@.@LEAST@-1.i586.rpm
- The package for developers.
- Installation:<br />
<code>rpm -Uvh @PACKAGENAME@-devel-@MAJOR@.@MINOR@.@LEAST@-1.i586.rpm</code>
- Source - Source
- Source TAR-Ball:
- <a href="/downloads/@PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@.tar.gz">@PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@.tar.gz</a>
- Installation:
-# <code>tar xzf @PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@.tar.gz</code>
-# <code>cd @PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@</code>
-# <code>./configure && make all install</code>
- Source RPM Packages:
- <a href="/downloads/@PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@-1.src.rpm">@PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@-1.src.rpm</a>
- Installation:<br /><code>sudo rpmbuild --rebuild @PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@-1.src.rpm</code>
- Requirements to build from source: - Requirements to build from source:
- boost: http://boost.org - boost: http://boost.org
- cppunit: http://cppunit.sf.net - cppunit: http://cppunit.sf.net
- log4cxx: http://logging.apache.org/log4cxx - log4cxx: http://logging.apache.org/log4cxx
- doxygen: http://doxygen.org - doxygen: http://doxygen.org
- graphviz: http://www.research.att.com/sw/tools/graphviz - graphviz: http://www.research.att.com/sw/tools/graphviz
- GNU binutils (you also need the development package, if it is - GNU binutils (you also need the development package, if it is separete (e.g. in Debian))
separete (e.g. in Debian))
- GNU g++, GNU make, GNU autotools: http://gnu.org - GNU g++, GNU make, GNU autotools: http://gnu.org
- Source TAR-Ball: - Binary
- http://marc.waeckerlin.org/@PACKAGENAME@/@PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@.tar.gz - Binary RPM Packages (built on i586/SuSE):
- Installation: - <a href="/downloads/@PACKAGENAME@-minimal-@MAJOR@.@MINOR@.@LEAST@-1.i586.rpm">@PACKAGENAME@-minimal-@MAJOR@.@MINOR@.@LEAST@-1.i586.rpm</a>
-# <code>tar xzf @PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@.tar.gz</code> - Minimal runtime package without debugging support.<br />Does not depend on boost and log4cxx and ltdl.<br />To be used e.g. with [[:Computer:Linux:Programme:Videorekorder]]
-# <code>cd @PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@</code> - Installation:<br /><code>rpm -Uvh @PACKAGENAME@-minimal-@MAJOR@.@MINOR@.@LEAST@-1.i586.rpm</code>
-# <code>./configure && make all install</code> - <a href="/downloads/@PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@-1.i586.rpm">@PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@-1.i586.rpm</a>
- Source RPM Packages: - Full runtime library, no multithreading.
- http://marc.waeckerlin.org/@PACKAGENAME@/@PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@-1.src.rpm - Installation:<br /><code>rpm -Uvh @PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@-1.i586.rpm</code>
- Installation:<br /> - <a href="/downloads/@PACKAGENAME@-mt-@MAJOR@.@MINOR@.@LEAST@-1.i586.rpm">@PACKAGENAME@-mt-@MAJOR@.@MINOR@.@LEAST@-1.i586.rpm</a>
<code>sudo rpmbuild --rebuild @PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@-1.src.rpm</code> - Full runtime library, with multithreading support.
- Installation:<br /><code>rpm -Uvh @PACKAGENAME@-mt-@MAJOR@.@MINOR@.@LEAST@-1.i586.rpm</code>
Download this documentation in PDF: - <a href="/downloads/@PACKAGENAME@-devel-@MAJOR@.@MINOR@.@LEAST@-1.i586.rpm">@PACKAGENAME@-devel-@MAJOR@.@MINOR@.@LEAST@-1.i586.rpm</a>
- http://marc.waeckerlin.org/@PACKAGENAME@/@PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@.pdf - The package for developers.
- Installation:<br /><code>rpm -Uvh @PACKAGENAME@-devel-@MAJOR@.@MINOR@.@LEAST@-1.i586.rpm</code>
- Requirements:
- Boost thread library for multi threading:<br />http://boost.org
- log4cxx for automated tracing and function traces:
- http://logging.apache.org/log4cxx
- RPM: <a href="/downloads/log4cxx-0.9.7-3.i386.rpm">log4cxx-0.9.7-3.i386.rpm</a>
- mrw::StackTrace requires:
- the GNU Binutils
- either GNU Compiler gcc or GNU C library glibc
- runs better on: either Linux or Solaris
*/ */
/** @page usage Usage of the Library: Include and Link /** @page usage Usage of the Library: Include and Link

@ -86,40 +86,85 @@ namespace mrw {
#endif #endif
catch (...) {} catch (...) {}
log4cxx::helpers::Properties properties; log4cxx::helpers::Properties properties;
properties.setProperty("log4j.rootLogger", std::string name, cont;
"OFF, A1"); properties.setProperty((name="log4j.rootLogger",
properties.setProperty("log4j.logger.mrw.fn", log4cxx::String(name.begin(), name.end())),
"DEBUG"); (cont="OFF, A1",
properties.setProperty("log4j.logger.mrw.fn.log4cxx", log4cxx::String(cont.begin(), cont.end())));
"OFF"); properties.setProperty((name="log4j.logger.mrw.fn",
properties.setProperty("log4j.logger.mrw.fn.boost", log4cxx::String(name.begin(), name.end())),
"OFF"); (cont="DEBUG",
properties.setProperty("log4j.logger.mrw.fn.Thread", log4cxx::String(cont.begin(), cont.end())));
"OFF"); properties.setProperty((name="log4j.logger.mrw.fn.global",
properties.setProperty("log4j.logger.mrw.fn.mrw", log4cxx::String(name.begin(), name.end())),
"OFF"); (cont="OFF",
properties.setProperty("log4j.logger.mrw.fn.std", log4cxx::String(cont.begin(), cont.end())));
"OFF"); properties.setProperty((name="log4j.logger.mrw.fn.allocator",
properties.setProperty("log4j.logger.mrw.fn.new", log4cxx::String(name.begin(), name.end())),
"OFF"); (cont="OFF",
properties.setProperty("log4j.logger.mrw.fn.CppUnit", log4cxx::String(cont.begin(), cont.end())));
"OFF"); properties.setProperty((name="log4j.logger.mrw.fn.std.*",
properties.setProperty("log4j.logger.mrw.fn.__gnu_cxx", log4cxx::String(name.begin(), name.end())),
"OFF"); (cont="OFF",
properties.setProperty("log4j.appender.A1", log4cxx::String(cont.begin(), cont.end())));
"org.apache.log4j.FileAppender"); properties.setProperty((name="log4j.logger.mrw.fn.log4cxx",
properties.setProperty("log4j.appender.A1.layout", log4cxx::String(name.begin(), name.end())),
"org.apache.log4j.PatternLayout"); (cont="OFF",
log4cxx::String(cont.begin(), cont.end())));
properties.setProperty((name="log4j.logger.mrw.fn.boost",
log4cxx::String(name.begin(), name.end())),
(cont="OFF",
log4cxx::String(cont.begin(), cont.end())));
properties.setProperty((name="log4j.logger.mrw.fn.Thread",
log4cxx::String(name.begin(), name.end())),
(cont="OFF",
log4cxx::String(cont.begin(), cont.end())));
properties.setProperty((name="log4j.logger.mrw.fn.mrw",
log4cxx::String(name.begin(), name.end())),
(cont="OFF",
log4cxx::String(cont.begin(), cont.end())));
properties.setProperty((name="log4j.logger.mrw.fn.std",
log4cxx::String(name.begin(), name.end())),
(cont="OFF",
log4cxx::String(cont.begin(), cont.end())));
properties.setProperty((name="log4j.logger.mrw.fn.new",
log4cxx::String(name.begin(), name.end())),
(cont="OFF",
log4cxx::String(cont.begin(), cont.end())));
properties.setProperty((name="log4j.logger.mrw.fn.CppUnit",
log4cxx::String(name.begin(), name.end())),
(cont="OFF",
log4cxx::String(cont.begin(), cont.end())));
properties.setProperty((name="log4j.logger.mrw.fn.__gnu_cxx",
log4cxx::String(name.begin(), name.end())),
(cont="OFF",
log4cxx::String(cont.begin(), cont.end())));
properties.setProperty((name="log4j.appender.A1",
log4cxx::String(name.begin(), name.end())),
(cont="org.apache.log4j.FileAppender",
log4cxx::String(cont.begin(), cont.end())));
properties.setProperty((name="log4j.appender.A1.layout",
log4cxx::String(name.begin(), name.end())),
(cont="org.apache.log4j.PatternLayout",
log4cxx::String(cont.begin(), cont.end())));
#ifdef _MT #ifdef _MT
properties.setProperty("log4j.appender.A1.layout.ConversionPattern", properties.setProperty((name="log4j.appender.A1.layout.ConversionPattern",
"%t-%-27c%m%n"); log4cxx::String(name.begin(), name.end())),
properties.setProperty("log4j.appender.A1.filename", (cont="%t-%-27c%m%n",
"mrwautofunctiontracelog4cxx_test-mt.log"); log4cxx::String(cont.begin(), cont.end())));
properties.setProperty((name="log4j.appender.A1.filename",
log4cxx::String(name.begin(), name.end())),
(cont="mrwautofunctiontracelog4cxx_test-mt.log",
log4cxx::String(cont.begin(), cont.end())));
#else #else
properties.setProperty("log4j.appender.A1.layout.ConversionPattern", properties.setProperty((name="log4j.appender.A1.layout.ConversionPattern",
"%-27c%m%n"); log4cxx::String(name.begin(), name.end())),
properties.setProperty("log4j.appender.A1.filename", (cont="%-27c%m%n",
"mrwautofunctiontracelog4cxx_test.log"); log4cxx::String(cont.begin(), cont.end())));
properties.setProperty((name="log4j.appender.A1.filename",
log4cxx::String(name.begin(), name.end())),
(cont="mrwautofunctiontracelog4cxx_test.log",
log4cxx::String(cont.begin(), cont.end())));
#endif #endif
log4cxx::PropertyConfigurator::configure(properties); log4cxx::PropertyConfigurator::configure(properties);
#ifdef _MT #ifdef _MT

@ -87,34 +87,74 @@ namespace mrw {
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
mrw::StackTrace::StackTrace() throw(std::bad_exception) { mrw::StackTrace::StackTrace() throw(std::bad_exception) {
// maximum trace level is limited here to 50, see below why // maximum trace level is limited here to 50, see below why
# if defined(__GLIBC__) # if defined(__GNUG__)
{
# define PUSH(i) \
(__builtin_frame_address(i)!=0 ? \
(_trace.push_back(__builtin_return_address(i)), true) : false)
PUSH(0) && PUSH(1) && PUSH(2) && PUSH(3) && PUSH(4) && PUSH(5) &&
PUSH(6) && PUSH(7) && PUSH(8) && PUSH(9) && PUSH(10) && PUSH(11) &&
PUSH(12) && PUSH(13) && PUSH(14) && PUSH(15) && PUSH(16) && PUSH(17)
&& PUSH(18) && PUSH(19) && PUSH(20) && PUSH(21) && PUSH(22) &&
PUSH(23) && PUSH(24) && PUSH(25) && PUSH(26) && PUSH(27) && PUSH(28)
&& PUSH(29) && PUSH(30) && PUSH(31) && PUSH(32) && PUSH(33) &&
PUSH(34) && PUSH(35) && PUSH(36) && PUSH(37) && PUSH(38) && PUSH(39)
&& PUSH(40) && PUSH(41) && PUSH(42) && PUSH(43) && PUSH(44) &&
PUSH(45) && PUSH(46) && PUSH(47) && PUSH(48) && PUSH(49);
# undef PUSH
}
# elif defined(__GLIBC__)
{ {
const int TRACE_LEVEL(50); const int TRACE_LEVEL(50);
void* ba[TRACE_LEVEL]; void* ba[TRACE_LEVEL];
for (int n(backtrace(ba, TRACE_LEVEL)), i(0); i<n; ++i) for (int n(backtrace(ba, TRACE_LEVEL)), i(0); i<n; ++i)
_trace.push_back(ba[i]); _trace.push_back(ba[i]);
} }
# elif defined(__GNUG__)
{
# define push(i) \
(__builtin_return_address(i) ? \
(_trace.push_back(__builtin_return_address(i)), true) : false)
push(0) && push(1) && push(2) && push(3) && push(4) && push(5) &&
push(6) && push(7) && push(8) && push(9) && push(10) && push(11) &&
push(12) && push(13) && push(14) && push(15) && push(16) && push(17)
&& push(18) && push(19) && push(20) && push(21) && push(22) &&
push(23) && push(24) && push(25) && push(26) && push(27) && push(28)
&& push(29) && push(30) && push(31) && push(32) && push(33) &&
push(34) && push(35) && push(36) && push(37) && push(38) && push(39)
&& push(40) && push(41) && push(42) && push(43) && push(44) &&
push(45) && push(46) && push(47) && push(48) && push(49);
# undef push
}
# else # else
# warning "You need GNU gcc or GNU glibc to be able to use mrw::StackTrace" # warning "You need GNU gcc or GNU glibc to be able to use mrw::StackTrace"
# endif # endif
} }
mrw::StackTrace::~StackTrace() throw() {
// maximum trace level is limited here to 50, see below why
# if !defined(__GNUG__) && defined(__GLIBC__)
/* GLIBC backtrace seems to leak memory, but I don't see why, so
GNUG part is prefered. According to the man-page, backtrace does
not allocate memory, so what happens here? Valgrind message:
==19829== 28 bytes in 1 blocks are still reachable in loss record 1 of 1
==19829== at 0x40233F0: malloc (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==19829== by 0x400CE43: _dl_map_object_deps (in /lib/ld-2.5.so)
==19829== by 0x4011E34: dl_open_worker (in /lib/ld-2.5.so)
==19829== by 0x400E025: _dl_catch_error (in /lib/ld-2.5.so)
==19829== by 0x4011928: _dl_open (in /lib/ld-2.5.so)
==19829== by 0x44AFF01: do_dlopen (in /lib/libc-2.5.so)
==19829== by 0x400E025: _dl_catch_error (in /lib/ld-2.5.so)
==19829== by 0x44B0000: dlerror_run (in /lib/libc-2.5.so)
==19829== by 0x44B012A: __libc_dlopen_mode (in /lib/libc-2.5.so)
==19829== by 0x448E2A8: init (in /lib/libc-2.5.so)
==19829== by 0x448E452: backtrace (in /lib/libc-2.5.so)
==19829== by 0x40E7E53: mrw::StackTrace::StackTrace() (in libmrw.so.3.2.0)
{
<insert a suppression name here>
Memcheck:Leak
fun:_vgrZU_libcZdsoZa_malloc
fun:_dl_map_object_deps
fun:dl_open_worker
fun:_dl_catch_error
fun:_dl_open
fun:do_dlopen
fun:_dl_catch_error
fun:dlerror_run
fun:__libc_dlopen_mode
fun:init
fun:backtrace
fun:_ZN3mrw10StackTraceC1Ev
}
*/
# endif
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
mrw::StackTrace::operator std::string() const throw(std::bad_exception) { mrw::StackTrace::operator std::string() const throw(std::bad_exception) {
std::stringstream s; std::stringstream s;
@ -220,7 +260,7 @@ bool mrw::StackTrace::createSymtable(const std::string& fname, void* offs)
"for file: \""+fname+'"'; "for file: \""+fname+'"';
return false; return false;
} }
mrw::AutoPtr<asymbol*> syms(new asymbol*[memsz]); mrw::AutoPtrAry<asymbol*> syms(new asymbol*[memsz]);
if (bfd_canonicalize_symtab(const_cast<bfd*>(static_cast<const bfd*>(abfd)), if (bfd_canonicalize_symtab(const_cast<bfd*>(static_cast<const bfd*>(abfd)),
syms)<0) { syms)<0) {
_error = "cannot map bfd symbols - 'bfd_canonicalize_symtab' failed" _error = "cannot map bfd symbols - 'bfd_canonicalize_symtab' failed"
@ -339,7 +379,7 @@ std::map<std::string, mrw::StackTrace::Translator> mrw::StackTrace::_dic;
std::map<mrw::StackTrace::Translator::key_type, std::string> std::map<mrw::StackTrace::Translator::key_type, std::string>
mrw::StackTrace::_addrs; mrw::StackTrace::_addrs;
std::map<std::string, mrw::StackTrace::AutoBfd> mrw::StackTrace::_bfd; std::map<std::string, mrw::StackTrace::AutoBfd> mrw::StackTrace::_bfd;
std::map<std::string, mrw::AutoPtr<asymbol*> > mrw::StackTrace::_syms; std::map<std::string, mrw::AutoPtrAry<asymbol*> > mrw::StackTrace::_syms;
#ifdef _MT #ifdef _MT
boost::recursive_mutex mrw::StackTrace::_mutex; boost::recursive_mutex mrw::StackTrace::_mutex;
#endif #endif

@ -157,6 +157,8 @@ namespace mrw {
//................................................................ methods //................................................................ methods
/// the constructor stores the actual stack trace /// the constructor stores the actual stack trace
StackTrace() throw(std::bad_exception); StackTrace() throw(std::bad_exception);
/// depending on how we got the stack trace, we may have to free memory
~StackTrace() throw();
/// evaluates the symbol table and returns the formatted stack trace /// evaluates the symbol table and returns the formatted stack trace
operator std::string() const throw(std::bad_exception); operator std::string() const throw(std::bad_exception);
/** @return list of raw stack addresses */ /** @return list of raw stack addresses */
@ -262,7 +264,7 @@ namespace mrw {
static std::map<std::string, Translator> _dic; static std::map<std::string, Translator> _dic;
static std::map<Translator::key_type, std::string> _addrs; static std::map<Translator::key_type, std::string> _addrs;
static std::map<std::string, AutoBfd> _bfd; static std::map<std::string, AutoBfd> _bfd;
static std::map<std::string, mrw::AutoPtr<asymbol*> > _syms; static std::map<std::string, mrw::AutoPtrAry<asymbol*> > _syms;
#ifdef _MT #ifdef _MT
static boost::recursive_mutex _mutex; static boost::recursive_mutex _mutex;
#endif #endif

@ -26,7 +26,10 @@ namespace mrw {
bool init(mrw::StackTrace::createSymtable()); bool init(mrw::StackTrace::createSymtable());
CPPUNIT_ASSERT_MESSAGE("createSymtable() failed! ERROR=" CPPUNIT_ASSERT_MESSAGE("createSymtable() failed! ERROR="
+mrw::StackTrace::error(), +mrw::StackTrace::error(),
init); init
||
mrw::StackTrace::error().find("/valgrind/")
!=std::string::npos);
mrw::StackTrace s; int l(__LINE__); std::string f(__FILE__); mrw::StackTrace s; int l(__LINE__); std::string f(__FILE__);
std::stringstream ss; std::stringstream ss;
ss<<f<<':'<<l; ss<<f<<':'<<l;

@ -231,12 +231,13 @@ namespace mrw {
@param l the list of strings to join @param l the list of strings to join
@param delimiter the delimiter between the joined strings @param delimiter the delimiter between the joined strings
*/ */
template<template<class STRING> class LIST> template<template<class CONTENTS_TPL> class LIST,
std::string join(const LIST<std::string>& l, typename CONTENTS>
std::string join(const LIST<CONTENTS>& l,
const std::string& delimiter=" ") const std::string& delimiter=" ")
throw(std::bad_exception) { throw(std::bad_exception) {
std::string result; std::string result;
for (typename LIST<std::string>::const_iterator it(l.begin()); for (typename LIST<CONTENTS>::const_iterator it(l.begin());
it!=l.end(); ++it) it!=l.end(); ++it)
result+=(result.size()?delimiter:"")+mrw::string(*it); result+=(result.size()?delimiter:"")+mrw::string(*it);
return result; return result;

Loading…
Cancel
Save