diff --git a/ChangeLog b/ChangeLog index 8ec7657..c1c3638 100644 --- a/ChangeLog +++ b/ChangeLog @@ -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) - new rpm package mrw-c++-minimal without debug facilities no dependencies to boost, log4cxx and ltdl libraries diff --git a/bootstrap.sh b/bootstrap.sh index 2d637db..91e94a9 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -15,5 +15,4 @@ ## added file header ## -test -f makefile && make distclean aclocal && libtoolize --force && automake -a && autoconf diff --git a/configure.in b/configure.in index 7cc988c..580c9ae 100644 --- a/configure.in +++ b/configure.in @@ -13,11 +13,11 @@ # init AC_INIT([mrw/mrw.hpp.in]) +AC_CANONICAL_SYSTEM PACKAGENAME=mrw-c++ -m4_define(x_major, 2) -m4_define(x_minor, 3) +m4_define(x_major, 3) +m4_define(x_minor, 2) m4_define(x_least, 1) -AM_INIT_AUTOMAKE(@PACKAGENAME@, @MAJOR@.@MINOR@.@LEAST@, [marc@waeckerlin.org]) # copy M4 to shell MAJOR=x_major @@ -27,6 +27,8 @@ AC_SUBST(MAJOR) AC_SUBST(MINOR) AC_SUBST(LEAST) +AM_INIT_AUTOMAKE($PACKAGENAME, $MAJOR.$MINOR.$LEAST, [marc@waeckerlin.org]) + # libtool versioning LIB_MAJOR=m4_eval(x_major+x_minor) LIB_MINOR=x_least @@ -62,9 +64,17 @@ AC_CHECK_HEADER(sys/old_procfs.h, [AM_CPPFLAGS=-D__solaris__]) # libraries AC_CHECK_HEADER(log4cxx/logger.h, [have_log4cxx=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 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, [ --disable-threads disable multithreading], [with_threads="$enableval"], [with_threads="yes"]) @@ -85,6 +95,18 @@ AC_ARG_ENABLE(dot, [ --disable-dot disable dot graphic tools for documentation], [have_dot="$enableval"]) 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, [ --disable-log4cxx disable use of log4cxx library in automated stack trace], @@ -197,6 +219,15 @@ if test "$with_threads" = "no"; then AC_MSG_WARN([Multithreading support is disabled! - use --enable-threads to enable it - 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 AC_MSG_WARN([Library log4cxx will not be used! - if you want it, download it from: diff --git a/makefile.am b/makefile.am index 5bb41de..cda41b4 100644 --- a/makefile.am +++ b/makefile.am @@ -54,17 +54,25 @@ rpm: dist rpmbuild -ba --clean @PACKAGENAME@.spec rpmbuild -bb --clean @PACKAGENAME@-minimal.spec -webserver: rpm - ssh root@waeckerlin.org bash -c \ - '"rm -r /home/marc/mrw-c++; mkdir -p /home/marc/mrw-c++"' - scp doc/html/* \ - doc/latex/@PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@.pdf \ - @PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@.tar.gz \ - ${RPMS} \ - log4cxx*.rpm \ - root@waeckerlin.org:/home/marc/mrw-c++/ +webserver: check distcheck rpm webserver.en webserver.de webserver.zh + - rm -rf ~/www/marc/data/doxygen/mrw-cpp + mkdir -p ~/www/marc/data/doxygen/mrw-cpp + cp doc/html/*.html ~/www/marc/data/doxygen/mrw-cpp/ + cp doc/latex/@PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@.pdf \ + @PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@.tar.gz \ + ${RPMS} \ + log4cxx*.rpm \ + ~/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 - rm -r doc - rm -r autom4te.cache diff --git a/mrw/auto.hpp b/mrw/auto.hpp index c1eb014..f894e60 100644 --- a/mrw/auto.hpp +++ b/mrw/auto.hpp @@ -255,6 +255,96 @@ namespace mrw { T* _res; ///< the resource to be managed }; + /** @brief Automatically deletes an array pointer when destructed. + @pre \#include + + 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 / std::map problem, + then this class may become deprecated. + + @param T type of the pointer to manage + */ + template + 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(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. @pre \#include diff --git a/mrw/autofunctiontracelog4cxx.cpp b/mrw/autofunctiontracelog4cxx.cpp index db5568f..3f68437 100644 --- a/mrw/autofunctiontracelog4cxx.cpp +++ b/mrw/autofunctiontracelog4cxx.cpp @@ -31,6 +31,26 @@ 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)); + +// 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 { struct ThreadInfo { @@ -176,14 +196,20 @@ extern "C" void __cyg_profile_func_enter(void *this_fn, void*) { (hierarchy.rfind(' ', std::min(hierarchy.find('<'), hierarchy.find("operator")))); 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::getLogger(_T("mrw.fn.")+hierarchy)); + (log4cxx::Logger::getLogger(log4cxx::String(name.begin(), name.end()))); if (logger->isDebugEnabled()) { - std::ostringstream ss; - ss<forcedLog(::log4cxx::Level::DEBUG, ss.str(), - pos.file.c_str(), pos.line); + std::basic_ostringstream ss; + ss<forcedLog(MRW_LEVEL_DEBUG, ss.str(), + MRW_LOG4CXX_LOCATION); } } } catch (...) {} @@ -206,19 +232,25 @@ extern "C" void __cyg_profile_func_exit(void *this_fn, void*) { for (std::string::size_type p(0); (p=hierarchy.find("::", p))!=std::string::npos; hierarchy.replace(p, 2, ".")); - hierarchy.erase(hierarchy.find('(')); + hierarchy.erase(hierarchy.rfind('(')); std::string::size_type p (hierarchy.rfind(' ', std::min(hierarchy.find('<'), hierarchy.find("operator")))); 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::getLogger(_T("mrw.fn.")+hierarchy)); + (log4cxx::Logger::getLogger(log4cxx::String(name.begin(), name.end()))); if (logger->isDebugEnabled()) { - std::ostringstream ss; - ss<forcedLog(::log4cxx::Level::DEBUG, ss.str(), - pos.file.c_str(), pos.line); + std::basic_ostringstream ss; + ss<forcedLog(MRW_LEVEL_DEBUG, ss.str(), + MRW_LOG4CXX_LOCATION); } } } catch (...) {} diff --git a/mrw/autostacktracelog4cxx.cpp b/mrw/autostacktracelog4cxx.cpp index 916f281..81ed123 100644 --- a/mrw/autostacktracelog4cxx.cpp +++ b/mrw/autostacktracelog4cxx.cpp @@ -11,11 +11,28 @@ */ #include #include +#include #include #include -#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 namespace mrw { @@ -27,8 +44,10 @@ namespace mrw { If you link to the library @c libmrwexclog4cxx using a linker option such as: @c -lmrwexclog4cxx, then an unexpected and a terminate handler are registered, that trace a fatal error using - the log4cxx library. You don't need to change a single line in - your code! + the log4cxx library. Also for all know signals there's a 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! The log4cxx library is located at: - http://logging.apache.org/log4cxx @@ -49,7 +68,7 @@ namespace mrw { @code 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__); StackTrace::createSymtable(); std::string st((std::string)StackTrace()); @@ -71,21 +90,27 @@ namespace mrw { */ void unexpected_log4cxx() { - log4cxx::LoggerPtr logger(log4cxx::Logger::getLogger(_T("mrw.stacktrace"))); - logger->fatal("Unexpected Exception", __FILE__, __LINE__); + static const std::string name("mrw.stacktrace"); + 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(); std::string st((std::string)StackTrace()); try { throw; } catch (const mrw::exception& x) { - logger->fatal(std::string("Reason:\n")+x.what() - +"\nStack:\n"+x.stacktrace()); + std::string txt(std::string("Reason:\n")+x.what() + +"\nStack:\n"+x.stacktrace()); + logger->fatal(log4cxx::String(txt.begin(), txt.end())); } catch (const std::exception& x) { - logger->fatal(std::string("Reason:\n")+x.what() - +"\nStack:\n"+st); + std::string txt(std::string("Reason:\n")+x.what() + +"\nStack:\n"+st); + logger->fatal(log4cxx::String(txt.begin(), txt.end())); } catch (...) { - logger->fatal(std::string("Reason: **** not available ****") - +"\nStack:\n"+st); + std::string txt(std::string("Reason: **** not available ****") + +"\nStack:\n"+st); + logger->fatal(log4cxx::String(txt.begin(), txt.end())); } throw std::bad_exception(); } @@ -98,7 +123,7 @@ namespace mrw { @code 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__); StackTrace::createSymtable(); std::string st((std::string)StackTrace()); @@ -121,35 +146,104 @@ namespace mrw { */ void terminate_log4cxx() { - log4cxx::LoggerPtr logger(log4cxx::Logger::getLogger(_T("mrw.stacktrace"))); - logger->fatal("Uncaught Exception", __FILE__, __LINE__); + static const std::string name("mrw.stacktrace"); + 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(); std::string st((std::string)StackTrace()); try { throw; } catch (const mrw::exception& x) { - logger->fatal(std::string("Reason:\n")+x.what() - +"\nStack:\n"+x.stacktrace()); + std::string txt(std::string("Reason:\n")+x.what() + +"\nStack:\n"+x.stacktrace()); + logger->fatal(log4cxx::String(txt.begin(), txt.end())); } catch (const std::exception& x) { - logger->fatal(std::string("Reason:\n")+x.what() - +"\nStack:\n"+st); + std::string txt(std::string("Reason:\n")+x.what() + +"\nStack:\n"+st); + logger->fatal(log4cxx::String(txt.begin(), txt.end())); } catch (...) { - logger->fatal(std::string("Reason: **** not available ****") - +"\nStack:\n"+st); + std::string txt(std::string("Reason: **** not available ****") + +"\nStack:\n"+st); + logger->fatal(log4cxx::String(txt.begin(), txt.end())); } 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 { public: AutoStackTrace() { std::set_unexpected(&mrw::unexpected_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) static AutoStackTrace _autoStackTrace; diff --git a/mrw/autostacktracestderr.cpp b/mrw/autostacktracestderr.cpp index c41bcff..938a4e5 100644 --- a/mrw/autostacktracestderr.cpp +++ b/mrw/autostacktracestderr.cpp @@ -11,6 +11,7 @@ */ #include #include +#include #include #include @@ -48,8 +49,10 @@ namespace mrw { If you link to the library @c libmrwexcstderr using a linker option such as: @c -lmrwexcstderr, then an unexpected and a terminate handler are registered, that trace to the standard - error stream @c std::cerr. You don't need to change a single - line in your code! + error stream @c std::cerr. Also for all know signals there's a + 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); } + /** @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: -------------------------------"< #include +#include #include #include -#ifndef __GLIBC__ -#include -#endif -mrw::Errno::Errno() throw(): _errno(errno) {} +mrw::Errno::Errno() throw(): _errnoxxx(errno) {} mrw::Errno::operator std::string() const throw(std::bad_exception) { -#ifdef __GLIBC__ - 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 + return *this; } std::string mrw::Errno::string() const throw(std::bad_exception) { -#ifdef __GLIBC__ + char* pos(0); char error[1024]; - return !strerror_r(_errno, error, 1024) ? - error : std::string("errno=")+_errno; +#ifdef __GLIBC__ +# 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 - 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 } diff --git a/mrw/errno.hpp b/mrw/errno.hpp index 12ab30e..23c1cb4 100644 --- a/mrw/errno.hpp +++ b/mrw/errno.hpp @@ -60,18 +60,19 @@ namespace mrw { /// returns the @c errno stored in the constructor operator int() const throw() { - return _errno; + return _errnoxxx; } /// returns the @c errno stored in the constructor int numerical() const throw() { - return _errno; + return _errnoxxx; } //.............................................................. variables private: - int _errno; + int _errnoxxx; // "xxx" for MinGW-compatibility (there's a + // function named _errno) }; diff --git a/mrw/foot.html b/mrw/foot.html index 67ab645..3f3b985 100644 --- a/mrw/foot.html +++ b/mrw/foot.html @@ -1,5 +1,4 @@ -
Last Change: $date
- +
Last Build: $date
diff --git a/mrw/functiontrace.hpp b/mrw/functiontrace.hpp index dac9cd7..aa8a612 100644 --- a/mrw/functiontrace.hpp +++ b/mrw/functiontrace.hpp @@ -34,10 +34,20 @@ // support for log4cxx 0.9.7 and for new CVS version #ifndef LOG4CXX_LOCATION # 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 # define LOG4CXX_CVS # 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 namespace mrw { @@ -48,11 +58,11 @@ namespace mrw { /** @defgroup FunctionTrace Function Tracing (using log4cxx) @pre \#include - Place the macro @ref METHOD as first line of all methods you want to - trace, and macro @ref FUNCTION as first line of all functions to be + Place the macro @ref MRW_METHOD as first line of all methods you want to + trace, and macro @ref MRW_FUNCTION as first line of all functions to be 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 default for the hierarchy string is @c "mrw.fntrace". The logging level is always @c DEBUG and cannot be changed. @@ -71,7 +81,7 @@ namespace mrw { \#include \#include 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); } class A { @@ -80,13 +90,13 @@ namespace mrw { method(); } void method() { - METHOD("A::method()"); // trace entry and exit + MRW_METHOD("A::method()"); // trace entry and exit fn(); } }; int main(int, char**) { log4cxx::BasicConfigurator::configure(); - FUNCTION("main(int, char**)"); + MRW_FUNCTION("main(int, char**)"); A().method(); return 0; } @@ -144,7 +154,7 @@ namespace mrw { namespace yyy { class Zzz { 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 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. @@ -168,7 +178,7 @@ namespace mrw { namespace xxx { namespace yyy { 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 */ -#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. @@ -193,7 +203,7 @@ namespace mrw { namespace yyy { class Zzz { 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 @param tracer the tracer hierarchy */ -#define METHOD2(name, tracer) \ +#define MRW_METHOD2(name, tracer) \ mrw::FnTrace fnTrace(this, name, __FILE__, __LINE__, tracer) /** @brief Declare function entrance, place as first line in functions. @@ -221,7 +231,7 @@ namespace mrw { namespace xxx { namespace yyy { 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 tracer the tracer hierarchy */ -#define FUNCTION2(name, tracer) \ +#define MRW_FUNCTION2(name, tracer) \ mrw::FnTrace fnTrace(name, __FILE__, __LINE__, tracer) class FnTrace { @@ -239,13 +249,15 @@ namespace mrw { FnTrace(const void* addr, const std::string& name, const std::string& file, unsigned long line, 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)); if (logger->isDebugEnabled()) { - std::stringstream oss; - oss<forcedLog(log4cxx::Level::DEBUG, oss.str(), + std::basic_stringstream oss; + oss<forcedLog(MRW_LEVEL_DEBUG, oss.str(), MRW_LOG4CXX_LOCATION); ++_level; } @@ -253,13 +265,15 @@ namespace mrw { FnTrace(const std::string& name, const std::string& file, unsigned long line, 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)); if (logger->isDebugEnabled()) { - std::stringstream oss; + std::basic_stringstream oss; oss<forcedLog(log4cxx::Level::DEBUG, oss.str(), + <forcedLog(MRW_LEVEL_DEBUG, oss.str(), MRW_LOG4CXX_LOCATION); ++_level; } @@ -268,22 +282,23 @@ namespace mrw { log4cxx::Logger* logger(log4cxx::Logger::getLogger(_tracer)); if (logger->isDebugEnabled()) { --_level; - std::stringstream oss; + std::basic_stringstream oss; if (_addr) oss<forcedLog(log4cxx::Level::DEBUG, oss.str(), + oss<forcedLog(MRW_LEVEL_DEBUG, oss.str(), MRW_LOG4CXX_LOCATION); } } private: const void* _addr; - const std::string _name; + const log4cxx::String _name; const std::string _file; unsigned long _line; - const std::string _tracer; + const log4cxx::String _tracer; /** @todo for multithreading, use thread specific storage */ static unsigned int _level; }; diff --git a/mrw/functiontrace_test.cpp b/mrw/functiontrace_test.cpp index a274306..646cc37 100644 --- a/mrw/functiontrace_test.cpp +++ b/mrw/functiontrace_test.cpp @@ -36,32 +36,32 @@ class A { public: A() { - METHOD("A::A()"); + MRW_METHOD("A::A()"); } ~A() { - METHOD("A::~A()"); + MRW_METHOD("A::~A()"); } void fn1() { - METHOD("A::fn1()"); + MRW_METHOD("A::fn1()"); fn2(); } void fn2() { - METHOD("A::fn2()"); + MRW_METHOD("A::fn2()"); fn3(); fn4(); } void fn3() { - METHOD("A::fn3()"); + MRW_METHOD("A::fn3()"); fn4(); } void fn4(bool flag=true) { - METHOD("A::fn4()"); + MRW_METHOD("A::fn4()"); if (flag) fn4(false); } }; void fn(A a) { - FUNCTION("fn(A)"); + MRW_FUNCTION("fn(A)"); a.fn1(); } @@ -70,16 +70,27 @@ class FunctionTraceTest: public CppUnit::TestFixture { void Init() { try {mrw::File::remove("functiontrace_test.log");} catch (...) {} log4cxx::helpers::Properties properties; - properties.setProperty("log4j.rootLogger", - "DEBUG, A1"); - properties.setProperty("log4j.appender.A1", - "org.apache.log4j.FileAppender"); - properties.setProperty("log4j.appender.A1.layout", - "org.apache.log4j.PatternLayout"); - properties.setProperty("log4j.appender.A1.layout.ConversionPattern", - "%F:%L - %m%n"); - properties.setProperty("log4j.appender.A1.filename", - "functiontrace_test.log"); + std::string name, cont; + properties.setProperty((name="log4j.rootLogger", + log4cxx::String(name.begin(), name.end())), + (cont="DEBUG, A1", + 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()))); + 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); } void Calls() { diff --git a/mrw/head.html b/mrw/head.html index 8ed296a..fc627cb 100644 --- a/mrw/head.html +++ b/mrw/head.html @@ -14,7 +14,3 @@ - - - -

$title

diff --git a/mrw/hintergrund.png b/mrw/hintergrund.png new file mode 100644 index 0000000..17f0abc Binary files /dev/null and b/mrw/hintergrund.png differ diff --git a/mrw/log4cxxconfiguration.cpp b/mrw/log4cxxconfiguration.cpp index 8dcd8a2..b7cf589 100644 --- a/mrw/log4cxxconfiguration.cpp +++ b/mrw/log4cxxconfiguration.cpp @@ -64,8 +64,9 @@ namespace mrw { -# /etc/mrwlog4cxx (global configuration) -# if no configuration file is found, use default configuration: @verbatim -log4j.rootLogger = DEBUG, A1 -log4j.logger.mrw.fn = DEBUG +log4j.rootLogger = WARN, A1 +log4j.logger.mrw.fntrace = OFF +log4j.logger.mrw.fn = OFF log4j.logger.mrw.fn.log4cxx = OFF log4j.logger.mrw.fn.boost = OFF log4j.logger.mrw.fn.Thread = OFF @@ -84,17 +85,17 @@ log4j.appender.A1.layout = org.apache.log4j.PatternLayout @endverbatim and for multi threaded programs in addition: @verbatim -log4j.appender.A1.layout.ConversionPattern = t-%-60c%m%n +log4j.appender.A1.layout.ConversionPattern = \%t-\%-40l - \%m\%n @endverbatim on the other hand, single threaded programs are formatted as: @verbatim -log4j.appender.A1.layout.ConversionPattern = 60c%m%n +log4j.appender.A1.layout.ConversionPattern = \%-40l - \%m\%n @endverbatim This results in the following behaviour: - trace to console - format as... - - @c "%t-%-60c%m%n" if threaded - - @c "%-60c%m%n" if not threaded + - @c "\%t-\%-40l - \%m\%n" if threaded + - @c "\%-40l - \%m\%n" if not threaded - enable all tracing to @c DEBUG - enable tracing of @ref AutoFunctionTrace - disable function trace for @c log4cxx @@ -122,50 +123,94 @@ log4j.appender.A1.layout.ConversionPattern = 60c%m%n else if (std::ifstream("/etc/mrwlog4cxx")) logconfigfile = "/etc/mrwlog4cxx"; if (logconfigfile.size()) { - log4cxx::PropertyConfigurator::configure(logconfigfile); + log4cxx::PropertyConfigurator::configure + (log4cxx::String(logconfigfile.begin(), logconfigfile.end())); return; } log4cxx::helpers::Properties properties; - properties.setProperty("log4j.rootLogger", - "DEBUG, A1"); - properties.setProperty("log4j.logger.mrw.fn", - "DEBUG"); - properties.setProperty("log4j.logger.mrw.fn.log4cxx", - "OFF"); - properties.setProperty("log4j.logger.mrw.fn.boost", - "OFF"); - properties.setProperty("log4j.logger.mrw.fn.Thread", - "OFF"); - properties.setProperty("log4j.logger.mrw.fn.QString", - "OFF"); - properties.setProperty("log4j.logger.mrw.fn.QShared", - "OFF"); - properties.setProperty("log4j.logger.mrw.fn.QWidget", - "OFF"); - properties.setProperty("log4j.logger.mrw.fn.QRect", - "OFF"); - properties.setProperty("log4j.logger.mrw.fn.qstrcmp", - "OFF"); - properties.setProperty("log4j.logger.mrw.fn.*.qt_cast", - "OFF"); - properties.setProperty("log4j.logger.mrw.fn.mrw", - "OFF"); - properties.setProperty("log4j.logger.mrw.fn.std", - "OFF"); - properties.setProperty("log4j.logger.mrw.fn.CppUnit", - "OFF"); - properties.setProperty("log4j.logger.mrw.fn.__gnu_cxx", - "OFF"); - properties.setProperty("log4j.appender.A1", - "org.apache.log4j.ConsoleAppender"); - properties.setProperty("log4j.appender.A1.layout", - "org.apache.log4j.PatternLayout"); + std::string name, cont; + properties.setProperty((name="log4j.rootLogger", + log4cxx::String(name.begin(), name.end())), + (cont="WARN, A1", + log4cxx::String(cont.begin(), cont.end()))); + properties.setProperty((name="log4j.logger.mrw.fntracea", + log4cxx::String(name.begin(), name.end())), + (cont="OFF", + log4cxx::String(cont.begin(), cont.end()))); + properties.setProperty((name="log4j.logger.mrw.fn", + log4cxx::String(name.begin(), name.end())), + (cont="OFF", + log4cxx::String(cont.begin(), cont.end()))); + properties.setProperty((name="log4j.logger.mrw.fn.log4cxx", + log4cxx::String(name.begin(), name.end())), + (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.QString", + log4cxx::String(name.begin(), name.end())), + (cont="OFF", + log4cxx::String(cont.begin(), cont.end()))); + properties.setProperty((name="log4j.logger.mrw.fn.QShared", + log4cxx::String(name.begin(), name.end())), + (cont="OFF", + log4cxx::String(cont.begin(), cont.end()))); + 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 - properties.setProperty("log4j.appender.A1.layout.ConversionPattern", - "%t-%-60c%m%n"); + properties.setProperty((name="log4j.appender.A1.layout.ConversionPattern", + log4cxx::String(name.begin(), name.end())), + (cont="%t-%-40l - %m%n", + log4cxx::String(cont.begin(), cont.end()))); #else - properties.setProperty("log4j.appender.A1.layout.ConversionPattern", - "%-60c%m%n"); + properties.setProperty((name="log4j.appender.A1.layout.ConversionPattern", + log4cxx::String(name.begin(), name.end())), + (cont="%-40l - %m%n", + log4cxx::String(cont.begin(), cont.end()))); #endif log4cxx::PropertyConfigurator::configure(properties); } diff --git a/mrw/makefile.am b/mrw/makefile.am index 78de50e..dd4ace4 100644 --- a/mrw/makefile.am +++ b/mrw/makefile.am @@ -9,7 +9,7 @@ ## @license LGPL, see file COPYING ## -AM_CPPFLAGS += -I${top_srcdir} +AM_CPPFLAGS += -I$(top_srcdir) if HAVE_STACKTRACE AM_CPPFLAGS += -DHAVE_STACKTRACE @@ -17,13 +17,14 @@ endif CLEANFILES = doxygen.errors functiontrace_test.log \ mrwautofunctiontracelog4cxx_test.log \ - mrwautofunctiontracelog4cxx_test-mt.log -examplesdir = ${pkgdatadir}/examples -dist_examples_DATA = ${top_srcdir}/mrw/examples/* -htmldir = ${pkgdatadir}/doc/html -html_DATA = ${top_builddir}/doc/html/index.html -pdfdir = ${pkgdatadir}/doc/pdf -dist_pdf_DATA = ${top_builddir}/doc/latex/@PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@.pdf + mrwautofunctiontracelog4cxx_test-mt.log \ + $(VALTESTS) valgrind.log +examplesdir = $(pkgdatadir)/examples +dist_examples_DATA = $(top_srcdir)/mrw/examples/* +htmldir = $(pkgdatadir)/doc/html +html_DATA = $(top_builddir)/doc/html/index.html +pdfdir = $(pkgdatadir)/doc/pdf +dist_pdf_DATA = $(top_builddir)/doc/latex/@PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@.pdf lib_LTLIBRARIES = libmrw.la if HAVE_BOOST_THREAD @@ -45,14 +46,10 @@ endif endif endif if HAVE_LOG4CXX - lib_LTLIBRARIES += libmrwexclog4cxx.la \ - libmrwlog4cxxconfiguration.la -if HAVE_THREADS - lib_LTLIBRARIES += libmrwlog4cxxconfiguration-mt.la + lib_LTLIBRARIES += libmrwexclog4cxx.la if HAVE_BOOST_THREAD lib_LTLIBRARIES += libmrwexclog4cxx-mt.la endif -endif if AUTOFNTRACE lib_LTLIBRARIES += libmrwautofunctiontracelog4cxx.la if HAVE_THREADS @@ -63,18 +60,33 @@ endif endif endif endif +if HAVE_LOG4CXX + lib_LTLIBRARIES += libmrwlog4cxxconfiguration.la +if HAVE_THREADS + lib_LTLIBRARIES += libmrwlog4cxxconfiguration-mt.la +endif +endif libmrw_la_SOURCES = \ mrw.hpp version.cpp \ arg.cpp arg.hpp auto.hpp deque.hpp \ exception.cpp exception.hpp \ - exec.cpp exec.hpp list.hpp \ + list.hpp \ map.hpp multimap.hpp multiset.hpp \ set.hpp \ smartpointer.hpp stdext.cpp stdext.hpp \ - string.hpp unistd.hpp vector.hpp regexp.hpp regexp.cpp \ - tokenizer.hpp configfile.hpp configfile.cpp file.hpp \ + string.hpp unistd.hpp vector.hpp \ + tokenizer.hpp \ 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 libmrw_la_SOURCES += dynamiclibrary.hpp endif @@ -93,33 +105,32 @@ endif if HAVE_THREADS 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_LDFLAGS = ${libmrw_la_LDFLAGS} -version-info @LIB_VERSION@ \ + libmrw_mt_la_LDFLAGS = $(libmrw_la_LDFLAGS) -version-info @LIB_VERSION@ \ @THREADS@ - libmrw_mt_la_LIBADD = ${libmrw_la_LIBADD} @BOOST_THREAD_LIB@ + libmrw_mt_la_LIBADD = $(libmrw_la_LIBADD) @BOOST_THREAD_LIB@ endif endif if HAVE_STACKTRACE libmrwexcstderr_la_SOURCES = autostacktracestderr.cpp version.cpp 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_BOOST_THREAD libmrwexcstderr_mt_la_SOURCES = autostacktracestderr.cpp version.cpp libmrwexcstderr_mt_la_CXXFLAGS = @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 - if AUTOFNTRACE libmrwautofunctiontracestdlog_la_SOURCES = autofunctiontracestdlog.cpp \ version.cpp libmrwautofunctiontracestdlog_la_CXXFLAGS = -w 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_BOOST_THREAD libmrwautofunctiontracestdlog_mt_la_SOURCES = \ @@ -128,38 +139,28 @@ if HAVE_BOOST_THREAD libmrwautofunctiontracestdlog_mt_la_LDFLAGS = \ -version-info @LIB_VERSION@ @THREADS@ libmrwautofunctiontracestdlog_mt_la_LIBADD = \ - ${top_builddir}/mrw/libmrw-mt.la + $(top_builddir)/mrw/libmrw-mt.la endif endif endif if HAVE_LOG4CXX libmrwexclog4cxx_la_SOURCES = autostacktracelog4cxx.cpp version.cpp libmrwexclog4cxx_la_LDFLAGS = -version-info @LIB_VERSION@ - 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 + libmrwexclog4cxx_la_LIBADD = $(top_builddir)/mrw/libmrw.la -llog4cxx if HAVE_THREADS if HAVE_BOOST_THREAD libmrwexclog4cxx_mt_la_SOURCES = autostacktracelog4cxx.cpp version.cpp libmrwexclog4cxx_mt_la_CXXFLAGS = @THREADS@ libmrwexclog4cxx_mt_la_LDFLAGS = -version-info @LIB_VERSION@ @THREADS@ - 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 + libmrwexclog4cxx_mt_la_LIBADD = $(top_builddir)/mrw/libmrw-mt.la -llog4cxx endif endif - if AUTOFNTRACE libmrwautofunctiontracelog4cxx_la_SOURCES = autofunctiontracelog4cxx.cpp \ version.cpp libmrwautofunctiontracelog4cxx_la_CXXFLAGS = -w 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_BOOST_THREAD libmrwautofunctiontracelog4cxx_mt_la_SOURCES = \ @@ -168,159 +169,190 @@ if HAVE_BOOST_THREAD libmrwautofunctiontracelog4cxx_mt_la_LDFLAGS = \ -version-info @LIB_VERSION@ @THREADS@ libmrwautofunctiontracelog4cxx_mt_la_LIBADD = \ - ${top_builddir}/mrw/libmrw-mt.la -llog4cxx + $(top_builddir)/mrw/libmrw-mt.la -llog4cxx 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 \ - tokenizer_test configfile_test string_test +VALGRIND_CHECKS = auto_test smartpointer_test stdext_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 -check_PROGRAMS += dynamiclibrary_test + VALGRIND_CHECKS += dynamiclibrary_test endif if HAVE_LOG4CXX - check_PROGRAMS += functiontrace_test + VALGRIND_CHECKS += functiontrace_test endif -dist_check_SCRIPTS = configfile_check.sh if HAVE_STACKTRACE - check_PROGRAMS += stacktrace_test mrwexcstderr_test + NO_VALGRIND_CHECKS += stacktrace_test + VALGRIND_CHECKS += mrwexcstderr_test if HAVE_LOG4CXX - check_PROGRAMS += mrwexclog4cxx_test + VALGRIND_CHECKS += mrwexclog4cxx_test if AUTOFNTRACE - check_PROGRAMS += mrwautofunctiontracelog4cxx_test + NO_VALGRIND_CHECKS += mrwautofunctiontracelog4cxx_test if HAVE_THREADS if HAVE_BOOST_THREAD - check_PROGRAMS += mrwautofunctiontracelog4cxx_test-mt + NO_VALGRIND_CHECKS += mrwautofunctiontracelog4cxx_test-mt endif endif endif endif endif + 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_LDFLAGS = @CPPUNIT_LIBS@ -auto_test_LDADD = ${top_builddir}/mrw/libmrw.la +auto_test_LDFLAGS = @CPPUNIT_LIBS@ -L.libs +auto_test_LDADD = $(top_builddir)/mrw/libmrw.la if HAVE_STACKTRACE - auto_test_LDADD += ${top_builddir}/mrw/libmrwexcstderr.la + auto_test_LDADD += $(top_builddir)/mrw/libmrwexcstderr.la endif 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_LDFLAGS = @CPPUNIT_LIBS@ -smartpointer_test_LDADD = ${top_builddir}/mrw/libmrw.la +smartpointer_test_LDFLAGS = @CPPUNIT_LIBS@ -L.libs +smartpointer_test_LDADD = $(top_builddir)/mrw/libmrw.la if HAVE_STACKTRACE - smartpointer_test_LDADD += ${top_builddir}/mrw/libmrwexcstderr.la + smartpointer_test_LDADD += $(top_builddir)/mrw/libmrwexcstderr.la endif +if HAVE_EXEC 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_LDFLAGS = @CPPUNIT_LIBS@ -exec_test_LDADD = ${top_builddir}/mrw/libmrw.la +exec_test_LDFLAGS = @CPPUNIT_LIBS@ -L.libs +exec_test_LDADD = $(top_builddir)/mrw/libmrw.la if HAVE_STACKTRACE - exec_test_LDADD += ${top_builddir}/mrw/libmrwexcstderr.la + exec_test_LDADD += $(top_builddir)/mrw/libmrwexcstderr.la +endif endif 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_LDFLAGS = @CPPUNIT_LIBS@ -stdext_test_LDADD = ${top_builddir}/mrw/libmrw.la +stdext_test_LDFLAGS = @CPPUNIT_LIBS@ -L.libs +stdext_test_LDADD = $(top_builddir)/mrw/libmrw.la if HAVE_STACKTRACE - stdext_test_LDADD += ${top_builddir}/mrw/libmrwexcstderr.la + stdext_test_LDADD += $(top_builddir)/mrw/libmrwexcstderr.la endif 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_LDFLAGS = @CPPUNIT_LIBS@ -string_test_LDADD = ${top_builddir}/mrw/libmrw.la +string_test_LDFLAGS = @CPPUNIT_LIBS@ -L.libs +string_test_LDADD = $(top_builddir)/mrw/libmrw.la if HAVE_STACKTRACE - string_test_LDADD += ${top_builddir}/mrw/libmrwexcstderr.la -endif -regexp_test_SOURCES = regexp_test.cpp version.cpp -regexp_test_CPPFLAGS = -I${top_srcdir} @CPPUNIT_CFLAGS@ -g3 -O0 -regexp_test_CXXFLAGS = -g3 -O0 -regexp_test_LDFLAGS = @CPPUNIT_LIBS@ -regexp_test_LDADD = ${top_builddir}/mrw/libmrw.la + string_test_LDADD += $(top_builddir)/mrw/libmrwexcstderr.la +endif +if HAVE_REGEXP + regexp_test_SOURCES = regexp_test.cpp version.cpp + regexp_test_CPPFLAGS = -I$(top_srcdir) @CPPUNIT_CFLAGS@ -g3 -O0 + regexp_test_CXXFLAGS = -g3 -O0 + regexp_test_LDFLAGS = @CPPUNIT_LIBS@ -L.libs + regexp_test_LDADD = $(top_builddir)/mrw/libmrw.la if HAVE_STACKTRACE - regexp_test_LDADD += ${top_builddir}/mrw/libmrwexcstderr.la + regexp_test_LDADD += $(top_builddir)/mrw/libmrwexcstderr.la +endif endif 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_LDFLAGS = @CPPUNIT_LIBS@ -tokenizer_test_LDADD = ${top_builddir}/mrw/libmrw.la +tokenizer_test_LDFLAGS = @CPPUNIT_LIBS@ -L.libs +tokenizer_test_LDADD = $(top_builddir)/mrw/libmrw.la if HAVE_STACKTRACE - tokenizer_test_LDADD += ${top_builddir}/mrw/libmrwexcstderr.la -endif -configfile_test_SOURCES = configfile_test.cpp version.cpp -configfile_test_CPPFLAGS = -I${top_srcdir} @CPPUNIT_CFLAGS@ -g3 -O0 -configfile_test_CXXFLAGS = -g3 -O0 -configfile_test_LDFLAGS = @CPPUNIT_LIBS@ -configfile_test_LDADD = ${top_builddir}/mrw/libmrw.la + tokenizer_test_LDADD += $(top_builddir)/mrw/libmrwexcstderr.la +endif +if HAVE_DIR + configfile_test_SOURCES = configfile_test.cpp version.cpp + configfile_test_CPPFLAGS = -I$(top_srcdir) @CPPUNIT_CFLAGS@ -g3 -O0 + configfile_test_CXXFLAGS = -g3 -O0 + configfile_test_LDFLAGS = @CPPUNIT_LIBS@ -L.libs + configfile_test_LDADD = $(top_builddir)/mrw/libmrw.la if HAVE_STACKTRACE - configfile_test_LDADD += ${top_builddir}/mrw/libmrwexcstderr.la + configfile_test_LDADD += $(top_builddir)/mrw/libmrwexcstderr.la +endif endif if HAVE_LTDL check_LTLIBRARIES = libdynamiclibrary_testlib.la libdynamiclibrary_testlib_la_SOURCES = dynamiclibrary_testlib.cpp libdynamiclibrary_testlib_la_LDFLAGS = -module -rpath /bullshit 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_LDFLAGS = @CPPUNIT_LIBS@ - dynamiclibrary_test_LDADD = ${top_builddir}/mrw/libmrw.la -lltdl + dynamiclibrary_test_LDFLAGS = @CPPUNIT_LIBS@ -L.libs + dynamiclibrary_test_LDADD = $(top_builddir)/mrw/libmrw.la -lltdl endif if HAVE_LOG4CXX 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_LDFLAGS = @CPPUNIT_LIBS@ - functiontrace_test_LDADD = ${top_builddir}/mrw/libmrw.la -llog4cxx + functiontrace_test_LDFLAGS = @CPPUNIT_LIBS@ -L.libs + functiontrace_test_LDADD = $(top_builddir)/mrw/libmrw.la -llog4cxx if HAVE_STACKTRACE - functiontrace_test_LDADD += ${top_builddir}/mrw/libmrwexcstderr.la + functiontrace_test_LDADD += $(top_builddir)/mrw/libmrwexcstderr.la endif endif if HAVE_STACKTRACE 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_LDFLAGS = @CPPUNIT_LIBS@ - stacktrace_test_LDADD = ${top_builddir}/mrw/libmrw.la ${top_builddir}/mrw/libmrwexcstderr.la + stacktrace_test_LDFLAGS = @CPPUNIT_LIBS@ -L.libs + stacktrace_test_LDADD = $(top_builddir)/mrw/libmrw.la $(top_builddir)/mrw/libmrwexcstderr.la 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_LDFLAGS = @CPPUNIT_LIBS@ - mrwexcstderr_test_LDADD = ${top_builddir}/mrw/libmrwexcstderr.la + mrwexcstderr_test_LDFLAGS = @CPPUNIT_LIBS@ -L.libs + mrwexcstderr_test_LDADD = $(top_builddir)/mrw/libmrwexcstderr.la if HAVE_LOG4CXX 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_LDFLAGS = @CPPUNIT_LIBS@ - mrwexclog4cxx_test_LDADD = ${top_builddir}/mrw/libmrwexclog4cxx.la -llog4cxx + mrwexclog4cxx_test_LDFLAGS = @CPPUNIT_LIBS@ -L.libs + mrwexclog4cxx_test_LDADD = $(top_builddir)/mrw/libmrwexclog4cxx.la -llog4cxx if AUTOFNTRACE mrwautofunctiontracelog4cxx_test_SOURCES = \ mrwautofunctiontracelog4cxx_test.cpp version.cpp 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_LDFLAGS = \ - @CPPUNIT_LIBS@ -finstrument-functions + @CPPUNIT_LIBS@ -L.libs -finstrument-functions mrwautofunctiontracelog4cxx_test_LDADD = \ - -llog4cxx ${top_builddir}/mrw/libmrwautofunctiontracelog4cxx.la + -llog4cxx $(top_builddir)/mrw/libmrwautofunctiontracelog4cxx.la if HAVE_THREADS if HAVE_BOOST_THREAD mrwautofunctiontracelog4cxx_test_mt_SOURCES = \ mrwautofunctiontracelog4cxx_test.cpp version.cpp 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 \ -finstrument-functions @THREADS@ mrwautofunctiontracelog4cxx_test_mt_LDFLAGS = \ - @CPPUNIT_LIBS@ @THREADS@ -finstrument-functions + @CPPUNIT_LIBS@ -L.libs @THREADS@ -finstrument-functions 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 @@ -328,51 +360,59 @@ endif endif dist_check_DATA = test.dat configfile.ini configfile.ini.result -EXTRA_DIST = head.html foot.html style.css -TESTS = ${check_PROGRAMS} ${dist_check_SCRIPTS} +EXTRA_DIST = head.html foot.html style.css hintergrund.png +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 \ 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 - 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 -f ${top_builddir}/doc/html/hintergrund.png || \ - cp ~/www/marc/linux/hintergrund.png \ - ${top_builddir}/doc/html || \ - ( \ - echo "**** sorry, you are missing the html background image"; \ - echo " (after distclean doc/html/hintergrund.png is deleted)" \ - ) +$(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/html || mkdir -p $(top_builddir)/doc/html + @test -f $(top_builddir)/doc/html/hintergrund.png || \ + cp $(srcdir)/hintergrund.png \ + $(top_builddir)/doc/html doxygen doxyfile if PEDANTIC test \! -s doxygen.errors endif -${top_builddir}/doc/latex/@PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@.pdf: doxyfile *.[ch]pp ${deps} ${html_DATA} - cd ${top_builddir}/doc/latex && make && \ +$(top_builddir)/doc/latex/@PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@.pdf: doxyfile *.[ch]pp $(deps) $(html_DATA) + cd $(top_builddir)/doc/latex && make && \ mv refman.pdf @PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@.pdf clean-local: - rm doxygen.err libmrw.doxytag 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 dist-hook: - test -d ${distdir}/doc/html || \ - mkdir -p ${distdir}/doc/html - cp ${top_builddir}/doc/html/* ${distdir}/doc/html/. + test -d $(distdir)/doc/html || \ + mkdir -p $(distdir)/doc/html + cp $(top_builddir)/doc/html/* $(distdir)/doc/html/. install-data-hook: - chmod -R u+w ${pkgdatadir}/doc - cp -rf ${top_builddir}/doc/html ${pkgdatadir}/doc/ + env | grep -i tmp + 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: - chmod -R u+w ${pkgdatadir}/doc - rm -rf ${pkgdatadir}/doc/html + chmod -R u+w "$(DESTDIR)$(pkgdatadir)/doc" + rm -rf "$(DESTDIR)$(pkgdatadir)/doc/html" diff --git a/mrw/mrw.hpp.in b/mrw/mrw.hpp.in index ea16e57..40c7e81 100644 --- a/mrw/mrw.hpp.in +++ b/mrw/mrw.hpp.in @@ -1,7 +1,15 @@ /** @mainpage 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ür den VideoreKorder): + + - @PACKAGENAME@-minimal-@MAJOR@.@MINOR@.@LEAST@-1.i586.rpm + + More downloads see @ref downloads. All features are listed on the "Modules" page. @@ -39,8 +47,8 @@ See the "Related Pages". + - @ref downloads - @ref readme - - @ref download - @ref usage - @ref threads - @ref libversion @@ -50,63 +58,53 @@ - @ref changes */ -/** @page download Download and Installation +/** @page downloads Download and Installation of the MRW-C++ Library + + Download this documentation in PDF: + - @PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@.pdf 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:
- rpm -Uvh @PACKAGENAME@-minimal-@MAJOR@.@MINOR@.@LEAST@-1.i586.rpm - - http://marc.waeckerlin.org/@PACKAGENAME@/@PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@-1.i586.rpm - - Full runtime library, no multithreading. - - Installation:
- rpm -Uvh @PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@-1.i586.rpm - - http://marc.waeckerlin.org/@PACKAGENAME@/@PACKAGENAME@-mt-@MAJOR@.@MINOR@.@LEAST@-1.i586.rpm - - Full runtime library, with multithreading support. - - Installation:
- rpm -Uvh @PACKAGENAME@-mt-@MAJOR@.@MINOR@.@LEAST@-1.i586.rpm - - http://marc.waeckerlin.org/@PACKAGENAME@/@PACKAGENAME@-devel-@MAJOR@.@MINOR@.@LEAST@-1.i586.rpm - - The package for developers. - - Installation:
- rpm -Uvh @PACKAGENAME@-devel-@MAJOR@.@MINOR@.@LEAST@-1.i586.rpm - Source + - Source TAR-Ball: + - @PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@.tar.gz + - Installation: + -# tar xzf @PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@.tar.gz + -# cd @PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@ + -# ./configure && make all install + - Source RPM Packages: + - @PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@-1.src.rpm + - Installation:
sudo rpmbuild --rebuild @PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@-1.src.rpm - Requirements to build from source: - boost: http://boost.org - cppunit: http://cppunit.sf.net - log4cxx: http://logging.apache.org/log4cxx - doxygen: http://doxygen.org - graphviz: http://www.research.att.com/sw/tools/graphviz - - GNU binutils (you also need the development package, if it is - separete (e.g. in Debian)) + - GNU binutils (you also need the development package, if it is separete (e.g. in Debian)) - GNU g++, GNU make, GNU autotools: http://gnu.org - - Source TAR-Ball: - - http://marc.waeckerlin.org/@PACKAGENAME@/@PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@.tar.gz - - Installation: - -# tar xzf @PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@.tar.gz - -# cd @PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@ - -# ./configure && make all install - - Source RPM Packages: - - http://marc.waeckerlin.org/@PACKAGENAME@/@PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@-1.src.rpm - - Installation:
- sudo rpmbuild --rebuild @PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@-1.src.rpm - - Download this documentation in PDF: - - http://marc.waeckerlin.org/@PACKAGENAME@/@PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@.pdf + - Binary + - Binary RPM Packages (built on i586/SuSE): + - @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 [[:Computer:Linux:Programme:Videorekorder]] + - Installation:
rpm -Uvh @PACKAGENAME@-minimal-@MAJOR@.@MINOR@.@LEAST@-1.i586.rpm + - @PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@-1.i586.rpm + - Full runtime library, no multithreading. + - Installation:
rpm -Uvh @PACKAGENAME@-@MAJOR@.@MINOR@.@LEAST@-1.i586.rpm + - @PACKAGENAME@-mt-@MAJOR@.@MINOR@.@LEAST@-1.i586.rpm + - Full runtime library, with multithreading support. + - Installation:
rpm -Uvh @PACKAGENAME@-mt-@MAJOR@.@MINOR@.@LEAST@-1.i586.rpm + - @PACKAGENAME@-devel-@MAJOR@.@MINOR@.@LEAST@-1.i586.rpm + - The package for developers. + - Installation:
rpm -Uvh @PACKAGENAME@-devel-@MAJOR@.@MINOR@.@LEAST@-1.i586.rpm + - Requirements: + - Boost thread library for multi threading:
http://boost.org + - log4cxx for automated tracing and function traces: + - http://logging.apache.org/log4cxx + - RPM: log4cxx-0.9.7-3.i386.rpm + - 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 diff --git a/mrw/mrwautofunctiontracelog4cxx_test.cpp b/mrw/mrwautofunctiontracelog4cxx_test.cpp index 73fb463..6a889a7 100644 --- a/mrw/mrwautofunctiontracelog4cxx_test.cpp +++ b/mrw/mrwautofunctiontracelog4cxx_test.cpp @@ -86,40 +86,85 @@ namespace mrw { #endif catch (...) {} log4cxx::helpers::Properties properties; - properties.setProperty("log4j.rootLogger", - "OFF, A1"); - properties.setProperty("log4j.logger.mrw.fn", - "DEBUG"); - properties.setProperty("log4j.logger.mrw.fn.log4cxx", - "OFF"); - properties.setProperty("log4j.logger.mrw.fn.boost", - "OFF"); - properties.setProperty("log4j.logger.mrw.fn.Thread", - "OFF"); - properties.setProperty("log4j.logger.mrw.fn.mrw", - "OFF"); - properties.setProperty("log4j.logger.mrw.fn.std", - "OFF"); - properties.setProperty("log4j.logger.mrw.fn.new", - "OFF"); - properties.setProperty("log4j.logger.mrw.fn.CppUnit", - "OFF"); - properties.setProperty("log4j.logger.mrw.fn.__gnu_cxx", - "OFF"); - properties.setProperty("log4j.appender.A1", - "org.apache.log4j.FileAppender"); - properties.setProperty("log4j.appender.A1.layout", - "org.apache.log4j.PatternLayout"); + std::string name, cont; + properties.setProperty((name="log4j.rootLogger", + log4cxx::String(name.begin(), name.end())), + (cont="OFF, A1", + log4cxx::String(cont.begin(), cont.end()))); + properties.setProperty((name="log4j.logger.mrw.fn", + log4cxx::String(name.begin(), name.end())), + (cont="DEBUG", + log4cxx::String(cont.begin(), cont.end()))); + properties.setProperty((name="log4j.logger.mrw.fn.global", + log4cxx::String(name.begin(), name.end())), + (cont="OFF", + log4cxx::String(cont.begin(), cont.end()))); + properties.setProperty((name="log4j.logger.mrw.fn.allocator", + 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.log4cxx", + log4cxx::String(name.begin(), name.end())), + (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 - properties.setProperty("log4j.appender.A1.layout.ConversionPattern", - "%t-%-27c%m%n"); - properties.setProperty("log4j.appender.A1.filename", - "mrwautofunctiontracelog4cxx_test-mt.log"); + properties.setProperty((name="log4j.appender.A1.layout.ConversionPattern", + log4cxx::String(name.begin(), name.end())), + (cont="%t-%-27c%m%n", + 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 - properties.setProperty("log4j.appender.A1.layout.ConversionPattern", - "%-27c%m%n"); - properties.setProperty("log4j.appender.A1.filename", - "mrwautofunctiontracelog4cxx_test.log"); + properties.setProperty((name="log4j.appender.A1.layout.ConversionPattern", + log4cxx::String(name.begin(), name.end())), + (cont="%-27c%m%n", + 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 log4cxx::PropertyConfigurator::configure(properties); #ifdef _MT diff --git a/mrw/stacktrace.cpp b/mrw/stacktrace.cpp index 493ed4a..def645d 100644 --- a/mrw/stacktrace.cpp +++ b/mrw/stacktrace.cpp @@ -87,34 +87,74 @@ namespace mrw { //---------------------------------------------------------------------------- mrw::StackTrace::StackTrace() throw(std::bad_exception) { // 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); void* ba[TRACE_LEVEL]; for (int n(backtrace(ba, TRACE_LEVEL)), i(0); i + 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) { std::stringstream s; @@ -220,7 +260,7 @@ bool mrw::StackTrace::createSymtable(const std::string& fname, void* offs) "for file: \""+fname+'"'; return false; } - mrw::AutoPtr syms(new asymbol*[memsz]); + mrw::AutoPtrAry syms(new asymbol*[memsz]); if (bfd_canonicalize_symtab(const_cast(static_cast(abfd)), syms)<0) { _error = "cannot map bfd symbols - 'bfd_canonicalize_symtab' failed" @@ -339,7 +379,7 @@ std::map mrw::StackTrace::_dic; std::map mrw::StackTrace::_addrs; std::map mrw::StackTrace::_bfd; -std::map > mrw::StackTrace::_syms; +std::map > mrw::StackTrace::_syms; #ifdef _MT boost::recursive_mutex mrw::StackTrace::_mutex; #endif diff --git a/mrw/stacktrace.hpp b/mrw/stacktrace.hpp index 75d0478..57553db 100644 --- a/mrw/stacktrace.hpp +++ b/mrw/stacktrace.hpp @@ -157,6 +157,8 @@ namespace mrw { //................................................................ methods /// the constructor stores the actual stack trace 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 operator std::string() const throw(std::bad_exception); /** @return list of raw stack addresses */ @@ -262,7 +264,7 @@ namespace mrw { static std::map _dic; static std::map _addrs; static std::map _bfd; - static std::map > _syms; + static std::map > _syms; #ifdef _MT static boost::recursive_mutex _mutex; #endif diff --git a/mrw/stacktrace_test.cpp b/mrw/stacktrace_test.cpp index 449a864..9e6f441 100644 --- a/mrw/stacktrace_test.cpp +++ b/mrw/stacktrace_test.cpp @@ -26,7 +26,10 @@ namespace mrw { bool init(mrw::StackTrace::createSymtable()); CPPUNIT_ASSERT_MESSAGE("createSymtable() failed! ERROR=" +mrw::StackTrace::error(), - init); + init + || + mrw::StackTrace::error().find("/valgrind/") + !=std::string::npos); mrw::StackTrace s; int l(__LINE__); std::string f(__FILE__); std::stringstream ss; ss< class LIST> - std::string join(const LIST& l, + template class LIST, + typename CONTENTS> + std::string join(const LIST& l, const std::string& delimiter=" ") throw(std::bad_exception) { std::string result; - for (typename LIST::const_iterator it(l.begin()); + for (typename LIST::const_iterator it(l.begin()); it!=l.end(); ++it) result+=(result.size()?delimiter:"")+mrw::string(*it); return result;