mrw-c++-0.92 (mrw)

- new file: version.cpp
- new file header for all sources
- work around warning in mrw::auto<T>
- possibility to compile without log4cxx
- work around bugs in demangle.h and libiberty.h
- corrections in documentation
- added simple tracing mechanism
- more warnings
- small corrections in Auto<>::Free and a new test for it
- possibility to compile without stack trace
This commit is contained in:
Marc Wäckerlin
2004-08-28 16:21:25 +00:00
parent 7a88e4bc43
commit 235a15020b
30 changed files with 1922 additions and 948 deletions

View File

@@ -1,3 +1,25 @@
* Wed Aug 25 2004 Marc Wäckerlin <marc@waeckerlin.org> - mrw-c++-0.92 (mrw)
- new file: version.cpp
- new file header for all sources
- work around warning in mrw::auto<T>
- possibility to compile without log4cxx
- work around bugs in demangle.h and libiberty.h
- corrections in documentation
- added simple tracing mechanism
- more warnings
- small corrections in Auto<>::Free and a new test for it
- pissibility to compile without stack trace
* Wed May 28 2004 Marc Wäckerlin <marc@waeckerlin.org> - mrw-c++-0.92 (mrw)
- no more mrw:: exceptions in header files, all moved to .cpp
- make distclean now clean everything that was generated
- smartpointer_test.cpp was missing in CVS
- new makefile targets tag and release
* Wed May 19 2004 Marc Wäckerlin <marc@waeckerlin.org> - mrw-c++-0.92 (mrw)
- no more auto.cpp
* Tue May 18 2004 Marc Wäckerlin <marc@waeckerlin.org> - mrw-c++-0.92 (mrw)
- correct bfd detection on solaris
- templated auto classes
- forgotten to install in 0.91: header arg.hpp and smartpointer.hpp
* Tue Apr 27 2004 Marc Wäckerlin <marc@waeckerlin.org> - mrw-c++-0.91 (mrw) * Tue Apr 27 2004 Marc Wäckerlin <marc@waeckerlin.org> - mrw-c++-0.91 (mrw)
- mrw/arg.hpp: Command line argument evaluation - mrw/arg.hpp: Command line argument evaluation
- mrw/smartpointer.hpp: Smart pointer implementation - mrw/smartpointer.hpp: Smart pointer implementation

11
NEWS
View File

@@ -1,7 +1,4 @@
New: Command line argument evaluation and SmartPointer Configure can disable stack trace, if you have problems compiling it on your machine. It is also possible to compile without log4cxx.
This is a preliminary release. Especially tests, configure New Feature: Templates are now used for automated resource management
environment, packages and documentation are not yet finished. It New Feature: Command line argument evaluation and SmartPointer
should already work, even though it may be not yet perfect.
It is know not to link on Solaris.

6
README
View File

@@ -1,6 +1,6 @@
C++ Library for automated C-Library resource management, UNIX C++ Library for automated C-Library resource management, UNIX Pipes,
Pipes, simple and secure UNIX system command execution, runtime simple and secure UNIX system command execution, runtime stack trace
stack trace and automated unexpected exception handling. and automated unexpected exception handling.
HTML and PDF documentation is include in the installation (built with HTML and PDF documentation is include in the installation (built with
Doxygen). Doxygen).

View File

@@ -1,4 +1,4 @@
#! /bin/sh #! /bin/sh
make distclean test -f makefile && make distclean
aclocal && libtoolize --force && automake && autoconf aclocal && libtoolize --force && automake -a && autoconf

View File

@@ -1,9 +1,34 @@
## @file
##
## $Id$
##
## $Date$
## $Author$
##
## @copy &copy; Marc W&auml;ckerlin
## @license LGPL, see file <a href="license.html">COPYING</a>
##
## $Log$
## Revision 1.6 2004/08/28 16:21:07 marc
## mrw-c++-0.92 (mrw)
## - new file: version.cpp
## - new file header for all sources
## - work around warning in mrw::auto<T>
## - possibility to compile without log4cxx
## - work around bugs in demangle.h and libiberty.h
## - corrections in documentation
## - added simple tracing mechanism
## - more warnings
## - small corrections in Auto<>::Free and a new test for it
## - possibility to compile without stack trace
##
# init # init
AC_INIT([mrw/mrw.hpp.in]) AC_INIT([mrw/mrw.hpp.in])
PACKAGENAME=mrw-c++ PACKAGENAME=mrw-c++
MAJOR=0 MAJOR=0
MINOR=91 MINOR=92
SUPPORT=beta SUPPORT=
AM_INIT_AUTOMAKE(@PACKAGENAME@, @MAJOR@.@MINOR@, [marc@waeckerlin.org]) AM_INIT_AUTOMAKE(@PACKAGENAME@, @MAJOR@.@MINOR@, [marc@waeckerlin.org])
# macros # macros
@@ -29,10 +54,12 @@ AC_CHECK_PROG(have_dot, dot, yes, no)
AC_CHECK_HEADER(sys/old_procfs.h, [AM_CPPFLAGS=-D__solaris__]) AC_CHECK_HEADER(sys/old_procfs.h, [AM_CPPFLAGS=-D__solaris__])
# libraries # libraries
AC_CHECK_HEADER(log4cxx/logger.h, [have_log4cxx=yes])
AC_SEARCH_LIBS(cplus_demangle, iberty, [AC_MSG_RESULT([OK])], AC_SEARCH_LIBS(cplus_demangle, iberty, [AC_MSG_RESULT([OK])],
[AC_MSG_ERROR([Library iberty is required!])]) [AC_MSG_ERROR([Library iberty is required!])])
AC_SEARCH_LIBS(bfd_arch_list, bfd, [AC_MSG_RESULT([OK])], AC_SEARCH_LIBS(bfd_arch_list, bfd, [AC_MSG_RESULT([OK])],
AC_SEARCH_LIBS(bfd_arch_list, bfd, [AC_MSG_RESULT([OK])], [ac_cv_search_bfd_arch_list=;
]AC_SEARCH_LIBS(bfd_arch_list, bfd, [AC_MSG_RESULT([OK])],
[AC_MSG_ERROR([BFD library libbfd is required])], [-lintl])) [AC_MSG_ERROR([BFD library libbfd is required])], [-lintl]))
# Arguments # Arguments
@@ -40,12 +67,24 @@ AM_MAINTAINER_MODE
AC_ARG_ENABLE(pedantic, AC_ARG_ENABLE(pedantic,
[ --enable-pedantic enable all warnings and checks, abort on warnings], [ --enable-pedantic enable all warnings and checks, abort on warnings],
[test "$enableval" = "yes" && \ [test "$enableval" = "yes" && \
AM_CXXFLAGS="${AM_CXXFLAGS:-} -pedantic-errors -Wall -W -Wfloat-equal -Wundef -Wendif-labels -Wpointer-arith -Wcast-align -Wwrite-strings -Wconversion -Wsign-compare -Wmissing-format-attribute -Wno-multichar -Wpacked -Wredundant-decls -Werror"]) AM_CXXFLAGS="${AM_CXXFLAGS:-} -pedantic-errors -Wall -W -Wfloat-equal -Wundef -Wendif-labels -Wpointer-arith -Wcast-align -Wwrite-strings -Wconversion -Wsign-compare -Wmissing-format-attribute -Wno-multichar -Wpacked -Wredundant-decls -Werror -Wshadow -Wcast-qual -Wno-ctor-dtor-privacy"])
dnl lib: -Wshadow -Wcast-qual dnl problem in libs: -Wshadow -Wcast-qual
dnl auto.hpp: -Wno-ctor-dtor-privacy (removed)
AC_ARG_ENABLE(dot, 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(log4cxx,
[ --disable-log4cxx disable use of log4cxx library in automated
stack trace],
[have_log4cxx="$enableval"])
AM_CONDITIONAL(HAVE_LOG4CXX, test "$have_log4cxx" = "yes")
AC_ARG_ENABLE(stacktrace,
[ --disable-stacktrace disable stack trace, use this if you cannot
compile the library on your system otherwise and
you still want to use the other parts],
[have_stacktrace="$enableval"], [have_stacktrace="yes"])
AM_CONDITIONAL(HAVE_STACKTRACE, test "$have_stacktrace" = "yes")
# export macros # export macros
AC_SUBST(HAVE_DOT) AC_SUBST(HAVE_DOT)
@@ -58,7 +97,7 @@ AC_SUBST(AM_CPPFLAGS)
# create output # create output
AC_CONFIG_FILES([makefile mrw-c++.spec mrw-c++-devel.spec AC_CONFIG_FILES([makefile mrw-c++.spec mrw-c++-devel.spec
mrw/makefile mrw/doxyfile mrw/mrw.hpp]) mrw/makefile mrw/doxyfile mrw/mrw.hpp mrw/version.cpp])
AC_OUTPUT AC_OUTPUT
# infos and warnings # infos and warnings
@@ -70,6 +109,9 @@ if test "$have_dot" = "no"; then
AC_MSG_WARN([Missing program dot! AC_MSG_WARN([Missing program dot!
- when you rebild documentation with make doc, there are no generated images - when you rebild documentation with make doc, there are no generated images
- there are precompiled derieved files in the distribution]); fi - there are precompiled derieved files in the distribution]); fi
if test "$have_log4cxx" != "yes"; then
AC_MSG_WARN([Library log4cxx will not be used!
AC_MSG_WARN([************** THE FLAGS = ${AM_CXXFLAGS}]); - if you want it, download it from:
http://logging.apache.org/log4cxx]); fi
if test "$have_stacktrace" != "yes"; then
AC_MSG_WARN([mrw::StackTrace is disabled!]); fi

View File

@@ -1,10 +1,35 @@
## @file
##
## $Id$
##
## $Date$
## $Author$
##
## @copy &copy; Marc W&auml;ckerlin
## @license LGPL, see file <a href="license.html">COPYING</a>
##
## $Log$
## Revision 1.6 2004/08/28 16:21:07 marc
## mrw-c++-0.92 (mrw)
## - new file: version.cpp
## - new file header for all sources
## - work around warning in mrw::auto<T>
## - possibility to compile without log4cxx
## - work around bugs in demangle.h and libiberty.h
## - corrections in documentation
## - added simple tracing mechanism
## - more warnings
## - small corrections in Auto<>::Free and a new test for it
## - possibility to compile without stack trace
##
SUBDIRS = mrw SUBDIRS = mrw
EXTRA_DIST = bootstrap.sh EXTRA_DIST = bootstrap.sh
nobase_include_HEADERS = mrw/auto.hpp mrw/unistd.hpp \ nobase_include_HEADERS = mrw/auto.hpp mrw/unistd.hpp \
mrw/stacktrace.hpp mrw/exception.hpp \ mrw/stacktrace.hpp mrw/exception.hpp \
mrw/exec.hpp mrw/exec.hpp mrw/arg.hpp mrw/smartpointer.hpp
infosdir = ${pkgdatadir} infosdir = ${pkgdatadir}
infos_DATA = AUTHORS NEWS README COPYING INSTALL ChangeLog \ infos_DATA = AUTHORS NEWS README COPYING INSTALL ChangeLog \
@PACKAGENAME@.spec @PACKAGENAME@-devel.spec @PACKAGENAME@.spec @PACKAGENAME@-devel.spec
@@ -12,15 +37,29 @@ infos_DATA = AUTHORS NEWS README COPYING INSTALL ChangeLog \
RPMS = /usr/src/packages/RPMS/i586/@PACKAGENAME@-@MAJOR@.@MINOR@-1.i586.rpm \ RPMS = /usr/src/packages/RPMS/i586/@PACKAGENAME@-@MAJOR@.@MINOR@-1.i586.rpm \
/usr/src/packages/RPMS/i586/@PACKAGENAME@-devel-@MAJOR@.@MINOR@-1.i586.rpm /usr/src/packages/RPMS/i586/@PACKAGENAME@-devel-@MAJOR@.@MINOR@-1.i586.rpm
release: rpm tag webserver
tag:
cvs ci -R .
cvs tag -FR REL_@PACKAGENAME@-@MAJOR@-@MINOR@ .
rpm: dist rpm: dist
cp @PACKAGENAME@-@MAJOR@.@MINOR@.tar.gz /usr/src/packages/SOURCES/ cp @PACKAGENAME@-@MAJOR@.@MINOR@.tar.gz /usr/src/packages/SOURCES/
rpmbuild -bb --clean @PACKAGENAME@.spec rpmbuild -bb --clean @PACKAGENAME@.spec
rpmbuild -bb --clean @PACKAGENAME@-devel.spec rpmbuild -bb --clean @PACKAGENAME@-devel.spec
webserver: all check dist ${RPMS} webserver: all check dist ${RPMS}
ssh root@waeckerlin.org mkdir -p /home/marc/mrw-c++ ssh root@waeckerlin.org bash -c \
'"rm -r /home/marc/mrw-c++; mkdir -p /home/marc/mrw-c++"'
scp mrw/doc/html/* \ scp mrw/doc/html/* \
mrw/doc/latex/@PACKAGENAME@-@MAJOR@.@MINOR@.pdf \ mrw/doc/latex/@PACKAGENAME@-@MAJOR@.@MINOR@.pdf \
@PACKAGENAME@-@MAJOR@.@MINOR@.tar.gz \ @PACKAGENAME@-@MAJOR@.@MINOR@.tar.gz \
${RPMS} \ ${RPMS} \
root@waeckerlin.org:/home/marc/mrw-c++/ root@waeckerlin.org:/home/marc/mrw-c++/
distclean-local:
- find . -name '*~' | xargs rm
- rm -r autom4te.cache
- rm aclocal.m4 config.guess config.sub configure \
depcomp install-sh ltmain.sh makefile makefile.in \
missing mkinstalldirs

View File

@@ -1,3 +1,28 @@
## @file
##
## $Id$
##
## $Date$
## $Author$
##
## @copy &copy; Marc W&auml;ckerlin
## @license LGPL, see file <a href="license.html">COPYING</a>
##
## $Log$
## Revision 1.2 2004/08/28 16:21:07 marc
## mrw-c++-0.92 (mrw)
## - new file: version.cpp
## - new file header for all sources
## - work around warning in mrw::auto<T>
## - possibility to compile without log4cxx
## - work around bugs in demangle.h and libiberty.h
## - corrections in documentation
## - added simple tracing mechanism
## - more warnings
## - small corrections in Auto<>::Free and a new test for it
## - possibility to compile without stack trace
##
# rpmbuild -bb --clean @PACKAGENAME@.spec # rpmbuild -bb --clean @PACKAGENAME@.spec
Summary: MRW's C++ Class Library, facilities for ease and quality Summary: MRW's C++ Class Library, facilities for ease and quality
Name: @PACKAGENAME@-devel Name: @PACKAGENAME@-devel

View File

@@ -1,3 +1,28 @@
## @file
##
## $Id$
##
## $Date$
## $Author$
##
## @copy &copy; Marc W&auml;ckerlin
## @license LGPL, see file <a href="license.html">COPYING</a>
##
## $Log$
## Revision 1.2 2004/08/28 16:21:07 marc
## mrw-c++-0.92 (mrw)
## - new file: version.cpp
## - new file header for all sources
## - work around warning in mrw::auto<T>
## - possibility to compile without log4cxx
## - work around bugs in demangle.h and libiberty.h
## - corrections in documentation
## - added simple tracing mechanism
## - more warnings
## - small corrections in Auto<>::Free and a new test for it
## - possibility to compile without stack trace
##
# rpmbuild -bb --clean @PACKAGENAME@.spec # rpmbuild -bb --clean @PACKAGENAME@.spec
Summary: MRW's C++ Class Library, facilities for ease and quality Summary: MRW's C++ Class Library, facilities for ease and quality
Name: @PACKAGENAME@ Name: @PACKAGENAME@

View File

@@ -1,7 +1,30 @@
#include <mrw/exception.hpp> /** @file
$Id$
$Date$
$Author$
@copy &copy; Marc W&auml;ckerlin
@license LGPL, see file <a href="license.html">COPYING</a>
$Log$
Revision 1.2 2004/08/28 16:21:25 marc
mrw-c++-0.92 (mrw)
- new file: version.cpp
- new file header for all sources
- work around warning in mrw::auto<T>
- possibility to compile without log4cxx
- work around bugs in demangle.h and libiberty.h
- corrections in documentation
- added simple tracing mechanism
- more warnings
- small corrections in Auto<>::Free and a new test for it
- possibility to compile without stack trace
*/
#include <mrw/stacktrace.hpp> #include <mrw/stacktrace.hpp>
#include <mrw/smartpointer.hpp> #include <mrw/smartpointer.hpp>
#include <mrw/simpletrace.hpp>
#include <stdlib.h> // exit #include <stdlib.h> // exit
#include <string> #include <string>
#include <vector> #include <vector>
@@ -125,7 +148,7 @@ namespace mrw {
bool theBoolean = args[3]->toBool(); bool theBoolean = args[3]->toBool();
@endcode @endcode
@section argParts Setup Command Line from Different Program Parts <h3>Setup Command Line from Different Program Parts</h3>
If your software is large and splitted into different parts (or If your software is large and splitted into different parts (or
sub projects or modules, ...), all with their own parameter, you sub projects or modules, ...), all with their own parameter, you
@@ -180,19 +203,15 @@ namespace mrw {
@throw mrw::bad_cast if the instance is not a string @throw mrw::bad_cast if the instance is not a string
@return the string, if the instance is a string @return the string, if the instance is a string
*/ */
virtual const std::string& toString() const throw(mrw::exception) { virtual const std::string& toString() const throw(std::exception);
throw mrw::bad_cast();
}
/** @brief If the instance is an @c int, return that integer, /** @brief If the instance is an @c int, return that integer,
otherwise throw an exception. otherwise throw an exception.
@throw mrw::bad_cast if the instance is not a integer @throw mrw::bad_cast if the instance is not a integer
@return the integer, if the instance is a integer @return the integer, if the instance is a integer
*/ */
virtual int toInt() const throw(mrw::exception) { virtual int toInt() const throw(std::exception);
throw mrw::bad_cast();
}
/** @brief If the instance is an @c bool, return that boolean, /** @brief If the instance is an @c bool, return that boolean,
otherwise throw an exception. otherwise throw an exception.
@note the following typings are converted to @c true: @note the following typings are converted to @c true:
@@ -203,19 +222,19 @@ namespace mrw {
@throw mrw::bad_cast if the instance is not a boolean @throw mrw::bad_cast if the instance is not a boolean
@return the boolean, if the instance is a boolean @return the boolean, if the instance is a boolean
*/ */
virtual bool toBool() const throw(mrw::exception) { virtual bool toBool() const throw(std::exception);
throw mrw::bad_cast();
}
/// @brief returns a printable representation of the value /// @brief returns a printable representation of the value
virtual std::string printable() const throw(mrw::bad_exception) = 0; virtual std::string printable() const throw(std::bad_exception) = 0;
/// @brief returns a printable typename of the value /// @brief returns a printable typename of the value
virtual const std::string& typestr() const throw(mrw::bad_exception)=0; virtual const std::string& typestr() const throw(std::bad_exception)=0;
protected: protected:
friend class Args; // allow assign for Param /// Allow assign for Args, make it a friend.
virtual void operator=(const std::string&) throw(mrw::exception) = 0; friend class Args;
/// Only the class itself and friends (Args) are allowed to assign.
virtual void operator=(const std::string&) throw(std::exception) = 0;
}; };
private: private:
@@ -223,20 +242,20 @@ namespace mrw {
class StringValue: public Value { class StringValue: public Value {
public: public:
virtual ~StringValue() {} virtual ~StringValue() {}
StringValue(const std::string& s) throw(mrw::bad_exception): _s(s) { StringValue(const std::string& s) throw(std::bad_exception): _s(s) {
} }
virtual const std::string& toString() const throw(mrw::exception) { virtual const std::string& toString() const throw(std::exception) {
return _s; return _s;
} }
virtual const std::string& typestr() const throw(mrw::bad_exception) { virtual const std::string& typestr() const throw(std::bad_exception) {
static std::string name("string"); static std::string name("string");
return name; return name;
} }
virtual std::string printable() const throw(mrw::bad_exception) { virtual std::string printable() const throw(std::bad_exception) {
return _s; return _s;
} }
protected: protected:
virtual void operator=(const std::string& s) throw(mrw::exception) { virtual void operator=(const std::string& s) throw(std::exception) {
_s = s; _s = s;
} }
private: private:
@@ -246,22 +265,20 @@ namespace mrw {
class IntValue: public Value { class IntValue: public Value {
public: public:
virtual ~IntValue() {} virtual ~IntValue() {}
IntValue(int i) throw(mrw::bad_exception): _i(i) { IntValue(int i) throw(std::bad_exception): _i(i) {
} }
virtual int toInt() const throw(mrw::exception) { virtual int toInt() const throw(std::exception) {
return _i; return _i;
} }
virtual const std::string& typestr() const throw(mrw::bad_exception) { virtual const std::string& typestr() const throw(std::bad_exception) {
static std::string name("integer"); static std::string name("integer");
return name; return name;
} }
virtual std::string printable() const throw(mrw::bad_exception) { virtual std::string printable() const throw(std::bad_exception) {
return ((std::stringstream&)(std::stringstream()<<_i)).str(); return ((std::stringstream&)(std::stringstream()<<_i)).str();
} }
protected: protected:
virtual void operator=(const std::string& s) throw(mrw::exception) { virtual void operator=(const std::string& s) throw(std::exception);
if (!(std::stringstream(s)>>_i)) throw mrw::bad_cast();
}
private: private:
int _i; int _i;
}; };
@@ -269,20 +286,20 @@ namespace mrw {
class BoolValue: public Value { class BoolValue: public Value {
public: public:
virtual ~BoolValue() {} virtual ~BoolValue() {}
BoolValue(bool b) throw(mrw::bad_exception): _b(b) { BoolValue(bool b) throw(std::bad_exception): _b(b) {
} }
virtual bool toBool() const throw(mrw::exception) { virtual bool toBool() const throw(std::exception) {
return _b; return _b;
} }
virtual const std::string& typestr() const throw(mrw::bad_exception) { virtual const std::string& typestr() const throw(std::bad_exception) {
static std::string name("boolean (\"yes\" or \"no\")"); static std::string name("boolean (\"yes\" or \"no\")");
return name; return name;
} }
virtual std::string printable() const throw(mrw::bad_exception) { virtual std::string printable() const throw(std::bad_exception) {
return _b?"yes":"no"; return _b?"yes":"no";
} }
protected: protected:
virtual void operator=(const std::string& s) throw(mrw::exception) { virtual void operator=(const std::string& s) throw(std::exception) {
_b = s=="true" || s=="yes" || s=="on"; _b = s=="true" || s=="yes" || s=="on";
} }
private: private:
@@ -300,25 +317,25 @@ namespace mrw {
} }
/// @brief add one more mandatory string parameter /// @brief add one more mandatory string parameter
Param& operator<<(const char* const s) throw(mrw::bad_exception) { Param& operator<<(const char* const s) throw(std::bad_exception) {
_params.push_back(new StringValue(s)); _params.push_back(new StringValue(s));
return *this; return *this;
} }
/// @brief add one more mandatory string parameter /// @brief add one more mandatory string parameter
Param& operator<<(const std::string& s) throw(mrw::bad_exception) { Param& operator<<(const std::string& s) throw(std::bad_exception) {
_params.push_back(new StringValue(s)); _params.push_back(new StringValue(s));
return *this; return *this;
} }
/// @brief add one more mandatory integer parameter /// @brief add one more mandatory integer parameter
Param& operator<<(int i) throw(mrw::bad_exception) { Param& operator<<(int i) throw(std::bad_exception) {
_params.push_back(new IntValue(i)); _params.push_back(new IntValue(i));
return *this; return *this;
} }
// @brief add one more mandatory boolean parameter // @brief add one more mandatory boolean parameter
Param& operator<<(bool b) throw(mrw::bad_exception) { Param& operator<<(bool b) throw(std::bad_exception) {
_params.push_back(new BoolValue(b)); _params.push_back(new BoolValue(b));
return *this; return *this;
} }
@@ -326,26 +343,15 @@ namespace mrw {
/** @brief get parameter number @i /** @brief get parameter number @i
@throw mrw::out_of_range if @c i is too big */ @throw mrw::out_of_range if @c i is too big */
const mrw::SmartPointer<Value>& operator[](unsigned int i) const const mrw::SmartPointer<Value>& operator[](unsigned int i) const
throw(mrw::exception) { throw(std::exception);
if (i<_params.size()) return _params[i];
throw mrw::out_of_range
(((std::stringstream&)
(std::stringstream()<<"check failed: "
<<i<<'<'<<_params.size())).str());
}
private: private:
/// Allow set for Args, make it a friend.
friend class Args; // allow set friend class Args; // allow set
mrw::SmartPointer<Value>& setable(unsigned int i) /// Get a parameter with acces right for setting.
throw(mrw::exception) { /// This is allowed for the class itself and friends (Args) only.
if (i<_params.size()) return _params[i]; mrw::SmartPointer<Value>& setable(unsigned int i) throw(std::exception);
throw mrw::out_of_range
(((std::stringstream&)
(std::stringstream()<<"check failed: "
<<i<<'<'<<_params.size())).str());
}
}; };
/** @brief this class represents one command line option /** @brief this class represents one command line option
@@ -369,13 +375,13 @@ namespace mrw {
@param shortname short name of the option @param shortname short name of the option
@param longname long name of the option, must start with "--" @param longname long name of the option, must start with "--"
@param param the additional parameter @param param the additional parameter
@param help the help string for this option @param helptext the help string for this option
*/ */
Opt::Opt(const char shortname, const std::string& longname, Opt(const char shortname, const std::string& longname,
const Param& param, const std::string& help) const Param& param, const std::string& helptext)
throw(mrw::bad_exception): throw(std::bad_exception):
_set(false), _shortname(shortname), _longname(longname), _set(false), _shortname(shortname), _longname(longname),
_param(param), _help(help) { _param(param), _help(helptext) {
} }
/** @brief create a simple @c mrw::Opt /** @brief create a simple @c mrw::Opt
@@ -385,17 +391,16 @@ namespace mrw {
@param shortname short name of the option @param shortname short name of the option
@param longname long name of the option, must start with "--" @param longname long name of the option, must start with "--"
@param help the help string for this option @param helptext the help string for this option
*/ */
Opt::Opt(const char shortname, const std::string& longname, Opt(const char shortname, const std::string& longname,
const std::string& help) const std::string& helptext) throw(std::bad_exception):
throw(mrw::bad_exception):
_set(false), _shortname(shortname), _longname(longname), _set(false), _shortname(shortname), _longname(longname),
_help(help) { _help(helptext) {
} }
/** @brief get the help text for this option */ /** @brief get the help text for this option */
const std::string& help() const throw(mrw::bad_exception) { const std::string& help() const throw(std::bad_exception) {
return _help; return _help;
} }
@@ -423,17 +428,19 @@ namespace mrw {
@return a smart pointer to the value (default or given by the user) @return a smart pointer to the value (default or given by the user)
*/ */
const mrw::SmartPointer<Param::Value>& operator[](unsigned int i) const const mrw::SmartPointer<Param::Value>& operator[](unsigned int i) const
throw(mrw::exception) { throw(std::exception) {
return _param[i]; return _param[i];
} }
private: private:
friend class Args; // is allowed to set values /// Allow set values, make Args a friend.
void set() const throw(mrw::bad_exception) { friend class Args;
/// Set @c _set to true, available only for friends (Args).
void set() const throw(std::bad_exception) {
_set = true; _set = true;
} }
Param& args() const throw(mrw::bad_exception) { Param& args() const throw(std::bad_exception) {
return _param; return _param;
} }
mutable bool _set; mutable bool _set;
@@ -469,7 +476,7 @@ namespace mrw {
typedef std::list<std::string> OtherArgs; typedef std::list<std::string> OtherArgs;
/// @brief get the one and only instance /// @brief get the one and only instance
static Args& instance() throw(mrw::bad_exception) { // singleton static Args& instance() throw(std::bad_exception) { // singleton
static Args _instance; static Args _instance;
return _instance; return _instance;
} }
@@ -485,15 +492,7 @@ namespace mrw {
<<mrw::Opt('v', "--verbose", "print more information"); <<mrw::Opt('v', "--verbose", "print more information");
@endcode @endcode
*/ */
Args& operator<<(const mrw::Opt& opt) throw(mrw::invalid_argument) { Args& operator<<(const mrw::Opt& opt) throw(std::invalid_argument);
// twice the same, but other sort order
Options::iterator it(_options.insert(_options.end(), opt));
if (!_shortopts.insert(ShortOpts::value_type(opt._shortname, it)).second)
throw mrw::invalid_argument(std::string(1, opt._shortname));
if (!_longopts.insert(LongOpts::value_type(opt._longname, it)).second)
throw mrw::invalid_argument(opt._longname);
return *this;
}
/** @brief setup the number of arguments /** @brief setup the number of arguments
@@ -509,7 +508,7 @@ namespace mrw {
} }
@endcode @endcode
*/ */
Args& operator<<(int argc) throw(mrw::bad_exception) { Args& operator<<(int argc) throw(std::bad_exception) {
_argc = argc; _argc = argc;
return *this; return *this;
} }
@@ -528,11 +527,7 @@ namespace mrw {
} }
@endcode @endcode
*/ */
Args& operator<<(const char *const*const argv) throw(mrw::exception) { Args& operator<<(const char *const*const argv) throw(std::exception);
if (_argc<0)
throw mrw::invalid_argument("argc was not set when shifting argv");
return parse(_argc, argv);
}
/** @brief add a description text /** @brief add a description text
@@ -547,7 +542,7 @@ namespace mrw {
mrw::Args::instance()<<"this is a description for --help"; mrw::Args::instance()<<"this is a description for --help";
@endcode @endcode
*/ */
Args& operator<<(const std::string& description) throw(mrw::exception) { Args& operator<<(const std::string& description) throw(std::exception) {
if (_description=="") if (_description=="")
_description = description; _description = description;
else else
@@ -569,29 +564,21 @@ namespace mrw {
mrw::Args::instance()<<'h'; mrw::Args::instance()<<'h';
@endcode @endcode
*/ */
Args& operator<<(char help) throw(mrw::exception) { Args& operator<<(char helpopt) throw(std::exception) {
_help = help; _help = helpopt;
return *this; return *this;
} }
/** @brief get an option, given the short option name /** @brief get an option, given the short option name
@throw mrw::out_of_range if the option does not exist @throw mrw::out_of_range if the option does not exist
*/ */
const Opt& find(char c) const throw(mrw::exception) { const Opt& find(char c) const throw(std::exception);
ShortOpts::const_iterator it(_shortopts.find(c));
if (it==_shortopts.end()) throw mrw::out_of_range(std::string(1, c));
return *it->second;
}
/** @brief get an option, given the long option name /** @brief get an option, given the long option name
@throw mrw::out_of_range if the option does not exist @throw mrw::out_of_range if the option does not exist
*/ */
const Opt& find(const std::string& s) const throw(mrw::exception) { const Opt& find(const std::string& s) const throw(std::exception);
LongOpts::const_iterator it(_longopts.find(s));
if (it==_longopts.end()) throw mrw::out_of_range(s);
return *it->second;
}
/** @brief get all non interpreted options /** @brief get all non interpreted options
All user options that don't fit the defined and interpreted All user options that don't fit the defined and interpreted
@@ -603,7 +590,7 @@ namespace mrw {
} }
/** @brief get the file name of the executable, that's @c argv[0] */ /** @brief get the file name of the executable, that's @c argv[0] */
const std::string& filename() throw(mrw::bad_exception) { const std::string& filename() throw(std::bad_exception) {
return _filename; return _filename;
} }
@@ -630,48 +617,12 @@ namespace mrw {
} }
private: private:
Args& parse(int argc, const char*const*const argv) throw(mrw::exception) { Args(): _argc(-1), _help(0) {} // singleton
if (argc>0) _filename = argv[0]; Args& operator=(const Args&); // singleton, not implemented
for (int i(1); i<argc; ++i) { Args& parse(int argc, const char*const*const argv) throw(std::exception);
std::string arg(argv[i]);
if (arg.find("--")==0 && arg!="--") { // long arguments
LongOpts::iterator it(_longopts.find(arg));
if (it!=_longopts.end() || i+it->second->args().size()>=argc)
throw mrw::invalid_argument(arg);
it->second->set();
for (int j(0), l(it->second->args().size()); j<l; ++j) {
*(it->second->args().setable(j)) = argv[++i];
}
} else if (arg.find("-")==0) { // short arguments
// first check all, then set all
for (int j(1), l(arg.size()); j<l; ++j) {
ShortOpts::iterator it(_shortopts.find(arg[j]));
if (it==_shortopts.end() || it->second->args().size()>0 &&
(j+1!=l || i+it->second->args().size()>=argc))
throw mrw::invalid_argument(arg);
}
for (int j(1), l(arg.size()); j<l; ++j) {
ShortOpts::iterator it(_shortopts.find(arg[j]));
it->second->set();
if (j+1==l && it->second->args().size()>0) {
for (int k(0); k < it->second->args().size(); ++k) {
*(it->second->args().setable(k)) = argv[++i];
}
}
}
} else {
if (arg!="--") _otherargs.push_back(arg);
while (++i<argc) _otherargs.push_back(argv[i]);
}
}
if (_help && find(_help)) help();
return *this;
}
typedef std::list<Opt> Options; typedef std::list<Opt> Options;
typedef std::map<char, Options::iterator> ShortOpts; typedef std::map<char, Options::iterator> ShortOpts;
typedef std::map<std::string, Options::iterator> LongOpts; typedef std::map<std::string, Options::iterator> LongOpts;
Args(): _argc(-1), _help(0) {} // singleton
Args& operator=(const Args&); // singleton, not implemented
std::string _filename; std::string _filename;
Options _options; Options _options;
ShortOpts _shortopts; ShortOpts _shortopts;

View File

@@ -1,9 +1,38 @@
/** @file
$Id$
$Date$
$Author$
@copy &copy; Marc W&auml;ckerlin
@license LGPL, see file <a href="license.html">COPYING</a>
$Log$
Revision 1.3 2004/08/28 16:21:25 marc
mrw-c++-0.92 (mrw)
- new file: version.cpp
- new file header for all sources
- work around warning in mrw::auto<T>
- possibility to compile without log4cxx
- work around bugs in demangle.h and libiberty.h
- corrections in documentation
- added simple tracing mechanism
- more warnings
- small corrections in Auto<>::Free and a new test for it
- possibility to compile without stack trace
*/
#ifndef __MRW_AUTO_HPP__ #ifndef __MRW_AUTO_HPP__
#define __MRW_AUTO_HPP__ #define __MRW_AUTO_HPP__
#include <sys/types.h> // size_t #include <sys/types.h> // size_t
#include <sys/mman.h> // PROT_READ, MAP_SHARED #include <sys/mman.h> // munmap, PROT_READ, MAP_SHARED
#include <bfd.h> // bfd* #include <stdexcept>
// forward
class bfd;
extern "C" int bfd_close(bfd*);
namespace mrw { namespace mrw {
@@ -18,126 +47,183 @@ namespace mrw {
*/ */
//@{ //@{
/** @brief Automatically frees a resource when destructed.
@pre #include <mrw/auto.hpp>
AutoResource works exactly like std::auto_ptr, but for any
resource instead of new allocated pointers. Whenever the context
of AutoResource is left, the resource is freed by a call to the
given function. This way, resources are freed even in case of
exceptions.
Declare an automated file descriptor handler, a BFD handler and
a @c malloc-/ @c free handler (all these typedefs are already
part of the library):
@code
typedef mrw::AutoResource<int, int(*)(int), &close, int, -1> AutoFile;
typedef mrw::AutoResource<bfd*, int(*)(bfd*), &bfd_close, int> AutoBfd;
template<class T> class Auto {
public:
typedef mrw::AutoResource<T, void(*)(void*), &free, int, 0> Free;
};
@endcode
@param RESOURCE_TYPE type of the resorce to manage
@param FUNCTION_PTR type of the function that frees the resource
@param FREE_FUNCTION the function that frees the resource
@param INITIAL_VALUE_TYPE type of the initial value
(pointers may have to be initialized by an integer)
@param INITIAL_VALUE value when the resource is unassigned
@param FREE_TYPE type to free, if cast is needed
*/
template<typename RESOURCE_TYPE,
typename FUNCTION_PTR,
FUNCTION_PTR FREE_FUNCTION,
typename INITIAL_VALUE_TYPE = RESOURCE_TYPE,
INITIAL_VALUE_TYPE INITIAL_VALUE = 0,
typename FREE_TYPE = RESOURCE_TYPE>
class AutoResource {
public:
/// @brief Construct from an allocated resource.
/// The resource is freed if necessary.
/// AutoResource takes over ownership of the resource.
explicit AutoResource(FREE_TYPE res = INITIAL_VALUE)
throw(std::bad_exception): _res((RESOURCE_TYPE)res) {
}
/// @brief Takeover ownership from another AutoResource.
AutoResource(AutoResource& o) throw(std::bad_exception):
_res(o.release()) {
}
/// @brief Free resource. Calls @c reset().
~AutoResource() throw(std::bad_exception) {reset();}
/// @brief Assign new resource. Calls @c reset().
/// The resource is freed if necessary.
AutoResource& operator=(RESOURCE_TYPE res) throw(std::bad_exception) {
return reset(res);
}
/// @brief Takeover ownership from another AutoResorce.
/// Calls @c reset() from @c this and @c release() from @c other.
AutoResource& operator=(AutoResource& other) throw(std::bad_exception) {
return reset(other.release());
}
/// @brief Get the resource.
operator const RESOURCE_TYPE&() const throw(std::bad_exception) {
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).
RESOURCE_TYPE& getClean() throw(std::bad_exception) {
reset();
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!=INITIAL_VALUE;
}
/// @brief Give away ownership of the resource.
/// @return old resource
RESOURCE_TYPE release() throw(std::bad_exception) {
RESOURCE_TYPE res(_res); _res=INITIAL_VALUE;
return res;
}
/// @brief Assign a new resorce.
/// The old resource of @c this is freed if necessary.
AutoResource& reset(RESOURCE_TYPE res = INITIAL_VALUE)
throw(std::bad_exception) {
if (_res!=INITIAL_VALUE) (*FREE_FUNCTION)((FREE_TYPE)_res);
_res = res;
return *this;
}
private:
RESOURCE_TYPE _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>
AutoFile works exactly like std::auto_ptr, but not for files AutoFile works exactly like std::auto_ptr, but for files
instead of pointers. Whenever the context of AutoFile is left, instead of pointers. Whenever the context of AutoFile is left,
the opened file is close. This way, resources are freed even in the opened file is close. This way, resources are freed even in
case of exceptions. case of exceptions.
*/ */
class AutoFile { typedef mrw::AutoResource<int, int(*)(int), &close, int, -1> AutoFile;
public:
/// @brief Construct from an opened file.
/// @note Don't close @c fd
explicit AutoFile(int fd = -1) throw(): _fd(fd) {}
/// @brief Takeover ownership from another AutoFile.
AutoFile(AutoFile& o) throw(): _fd(o.release()) {}
/// @brief Closes file if open.
~AutoFile() throw() {reset();}
/// @brief Assign new file descriptor.
/// The old file of @c this is closed if open.
AutoFile& operator=(int fd) throw() {return reset(fd);}
/// @brief Takeover ownership from another AutoFile.
/// The old file of @c this is closed if open.
AutoFile& operator=(AutoFile& other) throw() {
return reset(other.release());
}
/// @brief get the file descriptor @return file descriptor
operator const int() const throw() {
return _fd;
}
/// @brief Give away ownership of the file. @return old file descriptor
int release() throw() {
int ret(_fd); _fd=-1;
return ret;
}
/// @brief assign a new file descriptor
/** The old file of @c this is closed if open. */
AutoFile& reset(int = -1) throw();
private:
int _fd; ///< the file descriptor
};
/** @brief Automatically call @c munmap for mmaped files on destruction. /** @brief Resorce handle for @c mmap.
It integrates pointer and size of a memory mapped file similar
to a @c std::pair.
*/
class MMapHandle {
public:
void* first;
size_t second;
/// @brief Constructor that initializes the values through a call to mmap.
MMapHandle(int, size_t=0, void* = 0,
int = PROT_READ, int = MAP_SHARED, off_t = 0)
throw(std::bad_exception);
/// @brief Reset to zero, value of int is ignored.
MMapHandle& operator=(int) throw(std::bad_exception) {
first = 0; second = 0;
return *this;
}
/// @brief Compare to zero, returns true, if i and handle are both zero.
bool operator==(int i) const throw(std::bad_exception) {
return i==0 && first==0 && second==0;
}
};
inline void munmap(MMapHandle& res) throw(std::bad_exception) {
if (res.first!=0 && res.second>0)
::munmap(res.first, res.second);
}
/** @brief Automatically calls @c munmap on destruction for mmaped files.
@pre #include <mrw/auto.hpp> @pre #include <mrw/auto.hpp>
It's the same as std::auto_ptr, but for @c mmap instead of @c It's the same as std::auto_ptr, but for @c mmap instead of @c
new. When the context of @c AutoMapper is left, @c munmap is new. When the context of @c AutoMapper is left, @c munmap is
called. called.
*/ */
class AutoMapper { typedef mrw::AutoResource<MMapHandle, void(*)(MMapHandle&), &mrw::munmap, int>
public: AutoMapper;
AutoMapper(void* cont = 0, size_t sz = 0) throw():
_cont(cont), _sz(sz) {}
AutoMapper(int, size_t=0, void* = 0,
int = PROT_READ, int = MAP_SHARED, off_t = 0) throw();
~AutoMapper() throw();
operator const void*() const throw() {return _cont;}
AutoMapper& set(void* cont, size_t sz) throw() {
_cont=cont; _sz=sz;
return *this;
}
void* release() throw() {
void* ret(_cont); _cont=0; _sz=0;
return ret;
}
const void* last() const throw() {
return _cont && _sz ? (void*)((size_t)_cont+_sz-1) : 0;
}
private:
void* _cont;
size_t _sz;
};
/** @brief Automatically call @c bfd_close for @c bfd*. /** @brief Automatically calls @c bfd_close for @c bfd*.
@pre #include <mrw/auto.hpp> @pre #include <mrw/auto.hpp>
It acts like a @c std::auto_ptr, but for @c bfd*, that means it It acts like a @c std::auto_ptr, but for @c bfd*, that means it
calls @c bfd_close whenever the context is left. calls @c bfd_close whenever the context is left.
*/ */
class AutoBfd { typedef mrw::AutoResource<bfd*, int(*)(bfd*), &bfd_close, int> AutoBfd;
public:
AutoBfd(bfd* p=0) throw(): _bfd(p) {}
~AutoBfd() throw() {if (_bfd) bfd_close(_bfd);}
AutoBfd& operator=(bfd* p) throw() {
release(); _bfd=p; return *this;
}
AutoBfd& operator=(AutoBfd& o) throw() {
release(); _bfd=o.release(); return *this;
}
operator bfd*() throw() {return _bfd;}
bfd* operator->() throw() {return _bfd;}
bfd* release() throw() {bfd* res(_bfd); _bfd = 0; return res;}
private:
bfd* _bfd;
};
/** @brief Automatically calls @c free for @c malloc allocated memory. /** @brief Automatically calls @c free for @c malloc allocated memory.
Instanciate it as @c mrw::Auto<TYPE*>::Free.
@pre #include <mrw/auto.hpp> @pre #include <mrw/auto.hpp>
It works like a @c std::auto_ptr, but for memory that was It works like a @c std::auto_ptr, but for memory that was
allocated with @c malloc, not @c new. Memory is freed, whenever allocated with @c malloc, not @c new. Memory is freed, whenever
the context od @c AutoFree is left. the context od @c AutoFree is left.
@code
{ // enter context
Auto<char*>::Free cp = (char*)malloc(5);
cp.getClean() = (char*)malloc(10); // old storage of 5 bytes is freed
} // memory is freed on destruction of cp
@endcode
*/ */
template <class T> class AutoFree { template<class T> class Auto {
public: public:
AutoFree(T* p=0) throw(): _p(p) {} typedef mrw::AutoResource<T, void(*)(void*), &free, int, 0, void*> Free;
AutoFree(AutoFree& o) throw(): _p(o.release()) {} private:
~AutoFree() throw() {if (_p) free(_p);} /** @internal
AutoFree& operator=(T* p) throw() { work around compiler warning:
release(); _p=p; return *this; "only defines private constructors and has no friends" */
} friend class ThisIsADummyToEliminateWarnings;
AutoFree& operator=(AutoFree& o) throw() { /// Forbidden to instanciate.
release(); _p=o.release(); return *this; Auto(); Auto(const Auto&);
}
operator T*() {return _p;}
operator T**() {return &_p;}
operator bool() {return _p;}
T* release() throw() {T* r(_p); _p=0; return r;}
private:
T* _p;
}; };
//@} //@}
} }
#endif #endif

View File

@@ -1,9 +1,35 @@
/** @file
$Id$
$Date$
$Author$
@copy &copy; Marc W&auml;ckerlin
@license LGPL, see file <a href="license.html">COPYING</a>
$Log$
Revision 1.3 2004/08/28 16:21:25 marc
mrw-c++-0.92 (mrw)
- new file: version.cpp
- new file header for all sources
- work around warning in mrw::auto<T>
- possibility to compile without log4cxx
- work around bugs in demangle.h and libiberty.h
- corrections in documentation
- added simple tracing mechanism
- more warnings
- small corrections in Auto<>::Free and a new test for it
- possibility to compile without stack trace
*/
#include <mrw/auto.hpp> #include <mrw/auto.hpp>
#include <cppunit/TestFixture.h> #include <cppunit/TestFixture.h>
#include <cppunit/ui/text/TestRunner.h> #include <cppunit/ui/text/TestRunner.h>
#include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/HelperMacros.h>
#include <cppunit/extensions/TestFactoryRegistry.h> #include <cppunit/extensions/TestFactoryRegistry.h>
#include <fcntl.h> // open #include <fcntl.h> // open
#include <string.h> // strncpy
class AutoTest: public CppUnit::TestFixture { class AutoTest: public CppUnit::TestFixture {
public: public:
@@ -18,10 +44,10 @@ public:
mrw::AutoFile b(a); mrw::AutoFile b(a);
CPPUNIT_ASSERT(a==-1 && i==b); // b has taken ownership CPPUNIT_ASSERT(a==-1 && i==b); // b has taken ownership
CPPUNIT_ASSERT(read(b, &c, 1)==1 && c=='H'); // file is good CPPUNIT_ASSERT(read(b, &c, 1)==1 && c=='H'); // file is good
mrw::AutoFile c(i); mrw::AutoFile cc(i);
CPPUNIT_ASSERT(i==b && b==c); // ooops, two owner! CPPUNIT_ASSERT(i==b && b==cc); // ooops, two owner!
c.release(); cc.release();
CPPUNIT_ASSERT(i==b && c==-1); // it's ok now CPPUNIT_ASSERT(i==b && cc==-1); // it's ok now
b = open("test.dat", O_RDONLY); b = open("test.dat", O_RDONLY);
//close(i); //close(i);
CPPUNIT_ASSERT(read(i, &c, 1)==-1); // old file is closed CPPUNIT_ASSERT(read(i, &c, 1)==-1); // old file is closed
@@ -31,8 +57,18 @@ public:
} }
CPPUNIT_ASSERT(read(i, &c, 1)==-1); // file is closed now CPPUNIT_ASSERT(read(i, &c, 1)==-1); // file is closed now
} }
void AutoFree() {
const char C[] = "Hello World";
mrw::Auto<char*>::Free c(malloc(sizeof(C)));
CPPUNIT_ASSERT(c);
strncpy(c, C, sizeof(C));
CPPUNIT_ASSERT(std::string(c)==C);
c.release();
CPPUNIT_ASSERT(c==0);
}
CPPUNIT_TEST_SUITE(AutoTest); CPPUNIT_TEST_SUITE(AutoTest);
CPPUNIT_TEST(AutoFile); CPPUNIT_TEST(AutoFile);
CPPUNIT_TEST(AutoFree);
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
}; };
CPPUNIT_TEST_SUITE_REGISTRATION(AutoTest); CPPUNIT_TEST_SUITE_REGISTRATION(AutoTest);

View File

@@ -1,3 +1,28 @@
/** @file
$Id$
$Date$
$Author$
@copy &copy; Marc W&auml;ckerlin
@license LGPL, see file <a href="license.html">COPYING</a>
$Log$
Revision 1.2 2004/08/28 16:21:25 marc
mrw-c++-0.92 (mrw)
- new file: version.cpp
- new file header for all sources
- work around warning in mrw::auto<T>
- possibility to compile without log4cxx
- work around bugs in demangle.h and libiberty.h
- corrections in documentation
- added simple tracing mechanism
- more warnings
- small corrections in Auto<>::Free and a new test for it
- possibility to compile without stack trace
*/
#include <mrw/stacktrace.hpp> #include <mrw/stacktrace.hpp>
#include <mrw/exception.hpp> #include <mrw/exception.hpp>
#include <exception> #include <exception>
@@ -27,9 +52,6 @@ namespace mrw {
*/ */
//@{ //@{
/// The log4cxx logger where the trace is written to.
static log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger(_T("libmrw"));
/** @brief unexpected handler, that traces using log4cxx /** @brief unexpected handler, that traces using log4cxx
The unexpected handler is installed automatically when you link The unexpected handler is installed automatically when you link
@@ -38,19 +60,21 @@ namespace mrw {
@code @code
void unexpected_log4cxx() { void unexpected_log4cxx() {
log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger(_T("libmrw"));
logger->fatal("Unexpected Exception", __FILE__, __LINE__); logger->fatal("Unexpected Exception", __FILE__, __LINE__);
StackTrace::createSymtable();
std::string st((std::string)StackTrace());
try { try {
throw; throw;
} catch (const mrw::exception& x) { } catch (const mrw::exception& x) {
StackTrace::createSymtable();
logger->fatal(std::string("Reason:\n")+x.what() logger->fatal(std::string("Reason:\n")+x.what()
+"\nStack:+\n"+x.stacktrace()); +"\nStack:+\n"+x.stacktrace());
} catch (const std::exception& x) { } catch (const std::exception& x) {
logger->fatal(std::string("Reason:\n")+x.what() logger->fatal(std::string("Reason:\n")+x.what()
+"\nStack: **** not available ****"); +"\nStack:\n"+st);
} catch (...) { } catch (...) {
logger->fatal(std::string("Reason: **** not available ****\n") logger->fatal(std::string("Reason: **** not available ****")
+"\nStack: **** not available ****"); +"\nStack:\n"+st);
} }
throw std::bad_exception(); throw std::bad_exception();
} }
@@ -58,19 +82,21 @@ namespace mrw {
*/ */
void unexpected_log4cxx() { void unexpected_log4cxx() {
log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger(_T("libmrw"));
logger->fatal("Unexpected Exception", __FILE__, __LINE__); logger->fatal("Unexpected Exception", __FILE__, __LINE__);
StackTrace::createSymtable();
std::string st((std::string)StackTrace());
try { try {
throw; throw;
} catch (const mrw::exception& x) { } catch (const mrw::exception& x) {
StackTrace::createSymtable();
logger->fatal(std::string("Reason:\n")+x.what() logger->fatal(std::string("Reason:\n")+x.what()
+"\nStack:+\n"+x.stacktrace()); +"\nStack:+\n"+x.stacktrace());
} catch (const std::exception& x) { } catch (const std::exception& x) {
logger->fatal(std::string("Reason:\n")+x.what() logger->fatal(std::string("Reason:\n")+x.what()
+"\nStack: **** not available ****"); +"\nStack:\n"+st);
} catch (...) { } catch (...) {
logger->fatal(std::string("Reason: **** not available ****\n") logger->fatal(std::string("Reason: **** not available ****")
+"\nStack: **** not available ****"); +"\nStack:\n"+st);
} }
throw std::bad_exception(); throw std::bad_exception();
} }

View File

@@ -1,3 +1,28 @@
/** @file
$Id$
$Date$
$Author$
@copy &copy; Marc W&auml;ckerlin
@license LGPL, see file <a href="license.html">COPYING</a>
$Log$
Revision 1.3 2004/08/28 16:21:25 marc
mrw-c++-0.92 (mrw)
- new file: version.cpp
- new file header for all sources
- work around warning in mrw::auto<T>
- possibility to compile without log4cxx
- work around bugs in demangle.h and libiberty.h
- corrections in documentation
- added simple tracing mechanism
- more warnings
- small corrections in Auto<>::Free and a new test for it
- possibility to compile without stack trace
*/
#include <mrw/stacktrace.hpp> #include <mrw/stacktrace.hpp>
#include <mrw/exception.hpp> #include <mrw/exception.hpp>
#include <exception> #include <exception>

View File

@@ -9,6 +9,19 @@
## @license LGPL, see file <a href="license.html">COPYING</a> ## @license LGPL, see file <a href="license.html">COPYING</a>
## ##
## $Log$ ## $Log$
## Revision 1.7 2004/08/28 16:21:25 marc
## mrw-c++-0.92 (mrw)
## - new file: version.cpp
## - new file header for all sources
## - work around warning in mrw::auto<T>
## - possibility to compile without log4cxx
## - work around bugs in demangle.h and libiberty.h
## - corrections in documentation
## - added simple tracing mechanism
## - more warnings
## - small corrections in Auto<>::Free and a new test for it
## - possibility to compile without stack trace
##
## Revision 1.6 2004/08/25 15:26:18 marc ## Revision 1.6 2004/08/25 15:26:18 marc
## new file header ## new file header
## ##
@@ -879,7 +892,7 @@ INCLUDE_FILE_PATTERNS =
# or name=definition (no spaces). If the definition and the = are # or name=definition (no spaces). If the definition and the = are
# omitted =1 is assumed. # omitted =1 is assumed.
PREDEFINED = PREDEFINED = HAVE_STACKTRACE
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
# this tag can be used to specify a list of macro names that should be expanded. # this tag can be used to specify a list of macro names that should be expanded.

View File

@@ -1,5 +1,40 @@
/** @file
$Id$
$Date$
$Author$
@copy &copy; Marc W&auml;ckerlin
@license LGPL, see file <a href="license.html">COPYING</a>
$Log$
Revision 1.2 2004/08/28 16:21:25 marc
mrw-c++-0.92 (mrw)
- new file: version.cpp
- new file header for all sources
- work around warning in mrw::auto<T>
- possibility to compile without log4cxx
- work around bugs in demangle.h and libiberty.h
- corrections in documentation
- added simple tracing mechanism
- more warnings
- small corrections in Auto<>::Free and a new test for it
- possibility to compile without stack trace
*/
#include <mrw/exception.hpp> #include <mrw/exception.hpp>
#include <mrw/stacktrace.hpp>
#ifdef HAVE_STACKTRACE
# include <mrw/stacktrace.hpp>
#else
namespace mrw {
class StackTrace {
public:
operator std::string() throw() {return "";}
};
}
#endif
namespace mrw { namespace mrw {
exception::exception() throw(std::bad_exception): exception::exception() throw(std::bad_exception):

View File

@@ -1,3 +1,28 @@
/** @file
$Id$
$Date$
$Author$
@copy &copy; Marc W&auml;ckerlin
@license LGPL, see file <a href="license.html">COPYING</a>
$Log$
Revision 1.4 2004/08/28 16:21:25 marc
mrw-c++-0.92 (mrw)
- new file: version.cpp
- new file header for all sources
- work around warning in mrw::auto<T>
- possibility to compile without log4cxx
- work around bugs in demangle.h and libiberty.h
- corrections in documentation
- added simple tracing mechanism
- more warnings
- small corrections in Auto<>::Free and a new test for it
- possibility to compile without stack trace
*/
#ifndef __MRW_EXCEPTION_HPP__ #ifndef __MRW_EXCEPTION_HPP__
#define __MRW_EXCEPTION_HPP__ #define __MRW_EXCEPTION_HPP__
@@ -51,10 +76,20 @@ namespace mrw {
@subsection excsug Suggested Exception Handling Rules @subsection excsug Suggested Exception Handling Rules
-# derieve all your exceptions from mrw::exception -# derieve all your exceptions from mrw::exception
-# write exception specifications as follows: -# write exception specifications as follows: @n
- if any exception is thrown, specify @c throw(mrw::exception) (this specification is "binary", it only declares whether an exception
is thrown or not, but it does not specify which exact exception can
be thrown)
- if no exception is thrown, specify @c throw(std::bad_exception) - if no exception is thrown, specify @c throw(std::bad_exception)
-# document the exact exception thrown with Doxygen's \@throw tag instead of @c throw() as you would normally specify
- if any exception is thrown specify @c throw(std::exception) @n
(@b Note: If you need a more specific declaration, you must also
declare @c std::bad_exception in addition to your exceptions!)
- only declare @c throw() if you are 100% sure, that it is absolutely
impossible that this method ever throws an exception, that means
this method calls no other function or method (not even from a
system library) that does not declare @c throw()
-# document the exact exception thrown with Doxygen's @c \@throw tag
-# write an unexpected handler as follows -# write an unexpected handler as follows
(or link to a @ref AutoTrace "library"): (or link to a @ref AutoTrace "library"):
@@ -164,7 +199,7 @@ call of fn0 successful
... ...
} }
@endcode @endcode
*/ */
class exception: public std::exception { class exception: public std::exception {
public: public:
exception() throw(std::bad_exception); exception() throw(std::bad_exception);

View File

@@ -1,5 +1,31 @@
/** @file
$Id$
$Date$
$Author$
@copy &copy; Marc W&auml;ckerlin
@license LGPL, see file <a href="license.html">COPYING</a>
$Log$
Revision 1.4 2004/08/28 16:21:25 marc
mrw-c++-0.92 (mrw)
- new file: version.cpp
- new file header for all sources
- work around warning in mrw::auto<T>
- possibility to compile without log4cxx
- work around bugs in demangle.h and libiberty.h
- corrections in documentation
- added simple tracing mechanism
- more warnings
- small corrections in Auto<>::Free and a new test for it
- possibility to compile without stack trace
*/
#include <mrw/exec.hpp> #include <mrw/exec.hpp>
#include <mrw/unistd.hpp> #include <mrw/unistd.hpp>
#include <mrw/exception.hpp>
#include <sys/wait.h> // waitpid #include <sys/wait.h> // waitpid
#include <unistd.h> // fork, exec #include <unistd.h> // fork, exec
#include <string.h> // memcpy #include <string.h> // memcpy
@@ -47,7 +73,7 @@ mrw::Cmd::operator mrw::Exec() const throw(std::bad_exception) {
return mrw::Exec(*this); return mrw::Exec(*this);
} }
mrw::Exec mrw::Cmd::execute(bool throwExc) const throw(mrw::exception) { mrw::Exec mrw::Cmd::execute(bool throwExc) const throw(std::exception) {
return mrw::Exec(*this).execute(throwExc); return mrw::Exec(*this).execute(throwExc);
} }
@@ -83,13 +109,13 @@ mrw::Exec& mrw::Exec::operator=(const mrw::Exec& e) throw(std::bad_exception) {
return *this; return *this;
} }
mrw::Exec& mrw::Exec::execute(bool throwExc) throw(mrw::exception) { mrw::Exec& mrw::Exec::execute(bool throwExc) throw(std::exception) {
/** This method calls @c fork, sets up a pipe connection to pass @c /** This method calls @c fork, sets up a pipe connection to pass @c
stdout and @c stderr from the child process to the parent process stdout and @c stderr from the child process to the parent process
using mrw::pipe and calls @c execvp to execute the program. */ using mrw::Pipe and calls @c execvp to execute the program. */
_success = false; _success = false;
_res = _err = ""; _res = _err = "";
mrw::pipe stdOut, stdErr; mrw::Pipe stdOut, stdErr;
if (!stdOut || !stdErr) if (!stdOut || !stdErr)
throw mrw::ExecutionFailedExc("cannot create pipe", *_cmd); throw mrw::ExecutionFailedExc("cannot create pipe", *_cmd);
pid_t pid(fork()); pid_t pid(fork());
@@ -131,13 +157,13 @@ mrw::Exec& mrw::Exec::execute(bool throwExc) throw(mrw::exception) {
return *this; return *this;
} }
mrw::Exec& mrw::Exec::operator>>(std::string& res) throw(mrw::exception) { mrw::Exec& mrw::Exec::operator>>(std::string& res) throw(std::exception) {
execute(); execute();
res += _res; res += _res;
return *this; return *this;
} }
mrw::Exec::operator std::string&() throw(mrw::exception) { mrw::Exec::operator std::string&() throw(std::exception) {
if (!_success) execute(); if (!_success) execute();
return _res; return _res;
} }
@@ -146,12 +172,12 @@ mrw::Exec::operator bool() throw(std::bad_exception) {
return _success; return _success;
} }
std::string& mrw::Exec::result() throw(mrw::exception) { std::string& mrw::Exec::result() throw(std::exception) {
if (!_success) execute(); if (!_success) execute();
return _res; return _res;
} }
std::string& mrw::Exec::error() throw(mrw::exception) { std::string& mrw::Exec::error() throw(std::exception) {
if (!_success) execute(); if (!_success) execute();
return _err; return _err;
} }

View File

@@ -1,3 +1,28 @@
/** @file
$Id$
$Date$
$Author$
@copy &copy; Marc W&auml;ckerlin
@license LGPL, see file <a href="license.html">COPYING</a>
$Log$
Revision 1.3 2004/08/28 16:21:25 marc
mrw-c++-0.92 (mrw)
- new file: version.cpp
- new file header for all sources
- work around warning in mrw::auto<T>
- possibility to compile without log4cxx
- work around bugs in demangle.h and libiberty.h
- corrections in documentation
- added simple tracing mechanism
- more warnings
- small corrections in Auto<>::Free and a new test for it
- possibility to compile without stack trace
*/
#ifndef __MRW_EXEC_HPP__ #ifndef __MRW_EXEC_HPP__
#define __MRW_EXEC_HPP__ #define __MRW_EXEC_HPP__
@@ -116,7 +141,7 @@ namespace mrw {
- if given parameter is @c true (the default) also if the - if given parameter is @c true (the default) also if the
executed program terminates with an error executed program terminates with an error
*/ */
Exec& execute(bool=true) throw(mrw::exception); Exec& execute(bool=true) throw(std::exception);
/** @brief Executes the command if not done, streams @c stdout into a string /** @brief Executes the command if not done, streams @c stdout into a string
@@ -127,7 +152,7 @@ namespace mrw {
@throw ExecutionFailedExc in case of any failure or if the @throw ExecutionFailedExc in case of any failure or if the
executed program does not return a zero exit status. executed program does not return a zero exit status.
*/ */
Exec& operator>>(std::string&) throw(mrw::exception); Exec& operator>>(std::string&) throw(std::exception);
/** @brief Executes the command if not done, returns @c stdout as string /** @brief Executes the command if not done, returns @c stdout as string
@@ -140,7 +165,7 @@ namespace mrw {
@throw ExecutionFailedExc in case of any failure or if the @throw ExecutionFailedExc in case of any failure or if the
executed program does not return a zero exit status. executed program does not return a zero exit status.
*/ */
operator std::string&() throw(mrw::exception); operator std::string&() throw(std::exception);
/** @return /** @return
- @c true if the last execution was successful - @c true if the last execution was successful
@@ -160,7 +185,7 @@ namespace mrw {
@throw ExecutionFailedExc in case of any failure or if the @throw ExecutionFailedExc in case of any failure or if the
executed program does not return a zero exit status. executed program does not return a zero exit status.
*/ */
std::string& result() throw(mrw::exception); std::string& result() throw(std::exception);
/** @brief Executes the command if not done, returns @c stderr as string /** @brief Executes the command if not done, returns @c stderr as string
@@ -173,7 +198,7 @@ namespace mrw {
@throw ExecutionFailedExc in case of any failure or if the @throw ExecutionFailedExc in case of any failure or if the
executed program does not return a zero exit status. executed program does not return a zero exit status.
*/ */
std::string& error() throw(mrw::exception); std::string& error() throw(std::exception);
/** @return /** @return
- @c true if the last execution was successful - @c true if the last execution was successful
@@ -231,7 +256,7 @@ namespace mrw {
operator std::string() const throw(std::bad_exception); operator std::string() const throw(std::bad_exception);
/** @return a mrw::Exec that's constructed with this class */ /** @return a mrw::Exec that's constructed with this class */
operator Exec() const throw(std::bad_exception); operator mrw::Exec() const throw(std::bad_exception);
/** @brief Create a mrw::Exec and execute the command /** @brief Create a mrw::Exec and execute the command
@@ -254,11 +279,13 @@ namespace mrw {
- if given parameter is @c true (the default) also if the - if given parameter is @c true (the default) also if the
executed program terminates with an error executed program terminates with an error
*/ */
Exec execute(bool=true) const throw(mrw::exception); Exec execute(bool=true) const throw(std::exception);
private: private:
friend class Exec; // is allowed to call path() and args() /// Exec is allowed to call @c path() and @c args().
Cmd(); // no default constructor friend class Exec;
/// No default constructor.
Cmd();
const char* path() const throw(std::bad_exception); const char* path() const throw(std::bad_exception);
char** args() const throw(std::bad_exception); char** args() const throw(std::bad_exception);
typedef std::list<std::string> ArgList; typedef std::list<std::string> ArgList;

View File

@@ -1,3 +1,28 @@
/** @file
$Id$
$Date$
$Author$
@copy &copy; Marc W&auml;ckerlin
@license LGPL, see file <a href="license.html">COPYING</a>
$Log$
Revision 1.4 2004/08/28 16:21:25 marc
mrw-c++-0.92 (mrw)
- new file: version.cpp
- new file header for all sources
- work around warning in mrw::auto<T>
- possibility to compile without log4cxx
- work around bugs in demangle.h and libiberty.h
- corrections in documentation
- added simple tracing mechanism
- more warnings
- small corrections in Auto<>::Free and a new test for it
- possibility to compile without stack trace
*/
#include <mrw/exec.hpp> #include <mrw/exec.hpp>
#include <mrw/stacktrace.hpp> #include <mrw/stacktrace.hpp>
#include <cppunit/TestFixture.h> #include <cppunit/TestFixture.h>

View File

@@ -1,9 +1,161 @@
<?xml version='1.0' encoding='ISO-8859-1' standalone='yes'?> <?xml version='1.0' encoding='ISO-8859-1' standalone='yes'?>
<tagfile> <tagfile>
<compound kind="page"> <compound kind="page">
<filename>index</filename>
<title></title>
<name>index</name> <name>index</name>
<title></title>
<filename>index</filename>
<docanchor>moreinfo</docanchor>
<docanchor>download</docanchor>
<docanchor>intro</docanchor>
<docanchor>threads</docanchor>
<docanchor>usage</docanchor>
</compound>
<compound kind="file">
<name>arg.cpp</name>
<path>/privat/home/marc/pro/mrw-c++/mrw/</path>
<filename>arg_8cpp</filename>
</compound>
<compound kind="file">
<name>arg.hpp</name>
<path>/privat/home/marc/pro/mrw-c++/mrw/</path>
<filename>arg_8hpp</filename>
</compound>
<compound kind="file">
<name>auto.hpp</name>
<path>/privat/home/marc/pro/mrw-c++/mrw/</path>
<filename>auto_8hpp</filename>
<member kind="function">
<type>int</type>
<name>bfd_close</name>
<anchor>a0</anchor>
<arglist>(bfd *)</arglist>
</member>
</compound>
<compound kind="file">
<name>autostacktracelog4cxx.cpp</name>
<path>/privat/home/marc/pro/mrw-c++/mrw/</path>
<filename>autostacktracelog4cxx_8cpp</filename>
</compound>
<compound kind="file">
<name>autostacktracestderr.cpp</name>
<path>/privat/home/marc/pro/mrw-c++/mrw/</path>
<filename>autostacktracestderr_8cpp</filename>
</compound>
<compound kind="file">
<name>exception.cpp</name>
<path>/privat/home/marc/pro/mrw-c++/mrw/</path>
<filename>exception_8cpp</filename>
</compound>
<compound kind="file">
<name>exception.hpp</name>
<path>/privat/home/marc/pro/mrw-c++/mrw/</path>
<filename>exception_8hpp</filename>
</compound>
<compound kind="file">
<name>exec.cpp</name>
<path>/privat/home/marc/pro/mrw-c++/mrw/</path>
<filename>exec_8cpp</filename>
</compound>
<compound kind="file">
<name>exec.hpp</name>
<path>/privat/home/marc/pro/mrw-c++/mrw/</path>
<filename>exec_8hpp</filename>
</compound>
<compound kind="file">
<name>simpletrace.hpp</name>
<path>/privat/home/marc/pro/mrw-c++/mrw/</path>
<filename>simpletrace_8hpp</filename>
<member kind="define">
<type>#define</type>
<name>METHOD</name>
<anchor>ga0</anchor>
<arglist>(name)</arglist>
</member>
<member kind="define">
<type>#define</type>
<name>FUNCTION</name>
<anchor>ga1</anchor>
<arglist>(name)</arglist>
</member>
<member kind="define">
<type>#define</type>
<name>CALL</name>
<anchor>ga2</anchor>
<arglist>(name)</arglist>
</member>
<member kind="define">
<type>#define</type>
<name>TRACE</name>
<anchor>ga3</anchor>
<arglist>(text)</arglist>
</member>
<member kind="define">
<type>#define</type>
<name>TRACE_OFF</name>
<anchor>ga4</anchor>
<arglist></arglist>
</member>
<member kind="define">
<type>#define</type>
<name>TRACE_ON</name>
<anchor>ga5</anchor>
<arglist></arglist>
</member>
<member kind="define">
<type>#define</type>
<name>NO_TRACE</name>
<anchor>ga6</anchor>
<arglist></arglist>
</member>
</compound>
<compound kind="file">
<name>smartpointer.hpp</name>
<path>/privat/home/marc/pro/mrw-c++/mrw/</path>
<filename>smartpointer_8hpp</filename>
</compound>
<compound kind="file">
<name>stacktrace.cpp</name>
<path>/privat/home/marc/pro/mrw-c++/mrw/</path>
<filename>stacktrace_8cpp</filename>
<member kind="define">
<type>#define</type>
<name>HAVE_DECL_BASENAME</name>
<anchor>a0</anchor>
<arglist></arglist>
</member>
<member kind="define">
<type>#define</type>
<name>HAVE_DECL_ASPRINTF</name>
<anchor>a1</anchor>
<arglist></arglist>
</member>
<member kind="define">
<type>#define</type>
<name>HAVE_DECL_VASPRINTF</name>
<anchor>a2</anchor>
<arglist></arglist>
</member>
<member kind="define">
<type>#define</type>
<name>typename</name>
<anchor>a3</anchor>
<arglist></arglist>
</member>
</compound>
<compound kind="file">
<name>stacktrace.hpp</name>
<path>/privat/home/marc/pro/mrw-c++/mrw/</path>
<filename>stacktrace_8hpp</filename>
</compound>
<compound kind="file">
<name>unistd.hpp</name>
<path>/privat/home/marc/pro/mrw-c++/mrw/</path>
<filename>unistd_8hpp</filename>
</compound>
<compound kind="file">
<name>version.cpp</name>
<path>/privat/home/marc/pro/mrw-c++/mrw/</path>
<filename>version_8cpp</filename>
</compound> </compound>
<compound kind="page"> <compound kind="page">
<name>license</name> <name>license</name>
@@ -34,20 +186,43 @@
<name>arguments</name> <name>arguments</name>
<title>C++ Evaluation of Command Line Arguments</title> <title>C++ Evaluation of Command Line Arguments</title>
<filename>group__arguments.html</filename> <filename>group__arguments.html</filename>
<class kind="class">mrw::Args</class>
<class kind="class">mrw::Opt</class>
<class kind="class">mrw::Param</class> <class kind="class">mrw::Param</class>
<class kind="class">mrw::Opt</class>
<class kind="class">mrw::Args</class>
</compound> </compound>
<compound kind="group"> <compound kind="group">
<name>AutoTools</name> <name>AutoTools</name>
<title>Classes for Automated Resource Handling</title> <title>Classes for Automated Resource Handling</title>
<filename>group__AutoTools.html</filename> <filename>group__AutoTools.html</filename>
<class kind="class">mrw::AutoBfd</class> <class kind="class">mrw::AutoResource</class>
<class kind="class">mrw::AutoFile</class> <class kind="class">mrw::MMapHandle</class>
<class kind="class">mrw::AutoFree</class> <class kind="class">mrw::Auto</class>
<class kind="class">mrw::AutoMapper</class>
<class kind="class">mrw::pipe</class>
<class kind="class">mrw::SmartPointer</class> <class kind="class">mrw::SmartPointer</class>
<class kind="class">mrw::Pipe</class>
<member kind="typedef">
<type>mrw::AutoResource&lt; int, int(*)(int),&amp;close, int,-1 &gt;</type>
<name>AutoFile</name>
<anchor>ga0</anchor>
<arglist></arglist>
</member>
<member kind="typedef">
<type>mrw::AutoResource&lt; MMapHandle, void(*)(MMapHandle &amp;),&amp;mrw::munmap, int &gt;</type>
<name>AutoMapper</name>
<anchor>ga1</anchor>
<arglist></arglist>
</member>
<member kind="typedef">
<type>mrw::AutoResource&lt; bfd *, int(*)(bfd *),&amp;bfd_close, int &gt;</type>
<name>AutoBfd</name>
<anchor>ga2</anchor>
<arglist></arglist>
</member>
<member kind="function">
<type>void</type>
<name>munmap</name>
<anchor>ga3</anchor>
<arglist>(MMapHandle &amp;res)</arglist>
</member>
</compound> </compound>
<compound kind="group"> <compound kind="group">
<name>AutoTrace</name> <name>AutoTrace</name>
@@ -56,50 +231,257 @@
<member kind="function"> <member kind="function">
<type>void</type> <type>void</type>
<name>unexpected_log4cxx</name> <name>unexpected_log4cxx</name>
<anchor>a1</anchor> <anchor>ga0</anchor>
<arglist>()</arglist> <arglist>()</arglist>
</member> </member>
<member kind="function"> <member kind="function">
<type>void</type> <type>void</type>
<name>unexpected_stderr</name> <name>unexpected_stderr</name>
<anchor>a2</anchor> <anchor>ga1</anchor>
<arglist>()</arglist> <arglist>()</arglist>
</member> </member>
<docanchor>trcstderr</docanchor>
<docanchor>trclog4cxx</docanchor>
</compound> </compound>
<compound kind="group"> <compound kind="group">
<name>CmdExec</name> <name>CmdExec</name>
<title>Execute UNIX Commands</title> <title>Execute UNIX Commands</title>
<filename>group__CmdExec.html</filename> <filename>group__CmdExec.html</filename>
<class kind="class">mrw::Cmd</class>
<class kind="class">mrw::Exec</class>
<class kind="class">mrw::ExecutionFailedExc</class> <class kind="class">mrw::ExecutionFailedExc</class>
<class kind="class">mrw::Exec</class>
<class kind="class">mrw::Cmd</class>
</compound>
<compound kind="group">
<name>SimpleTrace</name>
<title>Simple Tracing (for temporary debugging)</title>
<filename>group__SimpleTrace.html</filename>
<namespace>mrw</namespace>
<member kind="define">
<type>#define</type>
<name>METHOD</name>
<anchor>ga0</anchor>
<arglist>(name)</arglist>
</member>
<member kind="define">
<type>#define</type>
<name>FUNCTION</name>
<anchor>ga1</anchor>
<arglist>(name)</arglist>
</member>
<member kind="define">
<type>#define</type>
<name>CALL</name>
<anchor>ga2</anchor>
<arglist>(name)</arglist>
</member>
<member kind="define">
<type>#define</type>
<name>TRACE</name>
<anchor>ga3</anchor>
<arglist>(text)</arglist>
</member>
<member kind="define">
<type>#define</type>
<name>TRACE_OFF</name>
<anchor>ga4</anchor>
<arglist></arglist>
</member>
<member kind="define">
<type>#define</type>
<name>TRACE_ON</name>
<anchor>ga5</anchor>
<arglist></arglist>
</member>
<member kind="define">
<type>#define</type>
<name>NO_TRACE</name>
<anchor>ga6</anchor>
<arglist></arglist>
</member>
</compound> </compound>
<compound kind="group"> <compound kind="group">
<name>StackTrace</name> <name>StackTrace</name>
<title>Collect and Format a Stack Trace</title> <title>Collect and Format a Stack Trace</title>
<filename>group__StackTrace.html</filename> <filename>group__StackTrace.html</filename>
<subgroup>AutoTrace</subgroup> <subgroup>AutoTrace</subgroup>
<class kind="class">mrw::exception</class>
<class kind="class">mrw::bad_alloc</class> <class kind="class">mrw::bad_alloc</class>
<class kind="class">mrw::bad_cast</class> <class kind="class">mrw::bad_cast</class>
<class kind="class">mrw::bad_exception</class> <class kind="class">mrw::bad_exception</class>
<class kind="class">mrw::bad_typeid</class> <class kind="class">mrw::bad_typeid</class>
<class kind="class">mrw::logic_error</class>
<class kind="class">mrw::domain_error</class> <class kind="class">mrw::domain_error</class>
<class kind="class">mrw::exception</class>
<class kind="class">mrw::invalid_argument</class> <class kind="class">mrw::invalid_argument</class>
<class kind="class">mrw::length_error</class> <class kind="class">mrw::length_error</class>
<class kind="class">mrw::logic_error</class>
<class kind="class">mrw::out_of_range</class> <class kind="class">mrw::out_of_range</class>
<class kind="class">mrw::runtime_error</class>
<class kind="class">mrw::overflow_error</class> <class kind="class">mrw::overflow_error</class>
<class kind="class">mrw::range_error</class> <class kind="class">mrw::range_error</class>
<class kind="class">mrw::runtime_error</class>
<class kind="class">mrw::StackTrace</class>
<class kind="class">mrw::underflow_error</class> <class kind="class">mrw::underflow_error</class>
<class kind="class">mrw::StackTrace</class>
<member kind="function"> <member kind="function">
<type>std::ostream &amp;</type> <type>std::ostream &amp;</type>
<name>operator&lt;&lt;</name> <name>operator&lt;&lt;</name>
<anchor>a0</anchor> <anchor>ga0</anchor>
<arglist>(std::ostream &amp;os, const StackTrace &amp;st)</arglist> <arglist>(std::ostream &amp;os, const StackTrace &amp;st)</arglist>
</member> </member>
<docanchor>excsug</docanchor>
<docanchor>excprob</docanchor>
<docanchor>exc</docanchor>
</compound>
<compound kind="class">
<name>mrw::Param</name>
<filename>classmrw_1_1Param.html</filename>
<member kind="function">
<type>int</type>
<name>size</name>
<anchor>a0</anchor>
<arglist>() const </arglist>
</member>
<member kind="function">
<type>Param &amp;</type>
<name>operator&lt;&lt;</name>
<anchor>a1</anchor>
<arglist>(const char *const s)</arglist>
</member>
<member kind="function">
<type>Param &amp;</type>
<name>operator&lt;&lt;</name>
<anchor>a2</anchor>
<arglist>(const std::string &amp;s)</arglist>
</member>
<member kind="function">
<type>Param &amp;</type>
<name>operator&lt;&lt;</name>
<anchor>a3</anchor>
<arglist>(int i)</arglist>
</member>
<member kind="function">
<type>Param &amp;</type>
<name>operator&lt;&lt;</name>
<anchor>a4</anchor>
<arglist>(bool b)</arglist>
</member>
<member kind="function">
<type>const mrw::SmartPointer&lt; Value &gt; &amp;</type>
<name>operator[]</name>
<anchor>a5</anchor>
<arglist>(unsigned int i) const </arglist>
</member>
</compound>
<compound kind="class">
<name>mrw::Param::Value</name>
<filename>classmrw_1_1Param_1_1Value.html</filename>
<member kind="function" virtualness="virtual">
<type>virtual const std::string &amp;</type>
<name>toString</name>
<anchor>a1</anchor>
<arglist>() const </arglist>
</member>
<member kind="function" virtualness="virtual">
<type>virtual int</type>
<name>toInt</name>
<anchor>a2</anchor>
<arglist>() const </arglist>
</member>
<member kind="function" virtualness="virtual">
<type>virtual bool</type>
<name>toBool</name>
<anchor>a3</anchor>
<arglist>() const </arglist>
</member>
<member kind="function" virtualness="pure">
<type>virtual std::string</type>
<name>printable</name>
<anchor>a4</anchor>
<arglist>() const=0</arglist>
</member>
<member kind="function" virtualness="pure">
<type>virtual const std::string &amp;</type>
<name>typestr</name>
<anchor>a5</anchor>
<arglist>() const=0</arglist>
</member>
<member kind="function" protection="protected" virtualness="pure">
<type>virtual void</type>
<name>operator=</name>
<anchor>b0</anchor>
<arglist>(const std::string &amp;)=0</arglist>
</member>
</compound>
<compound kind="class">
<name>mrw::Param::Value</name>
<filename>classmrw_1_1Param_1_1Value.html</filename>
<member kind="function" virtualness="virtual">
<type>virtual const std::string &amp;</type>
<name>toString</name>
<anchor>a1</anchor>
<arglist>() const </arglist>
</member>
<member kind="function" virtualness="virtual">
<type>virtual int</type>
<name>toInt</name>
<anchor>a2</anchor>
<arglist>() const </arglist>
</member>
<member kind="function" virtualness="virtual">
<type>virtual bool</type>
<name>toBool</name>
<anchor>a3</anchor>
<arglist>() const </arglist>
</member>
<member kind="function" virtualness="pure">
<type>virtual std::string</type>
<name>printable</name>
<anchor>a4</anchor>
<arglist>() const=0</arglist>
</member>
<member kind="function" virtualness="pure">
<type>virtual const std::string &amp;</type>
<name>typestr</name>
<anchor>a5</anchor>
<arglist>() const=0</arglist>
</member>
<member kind="function" protection="protected" virtualness="pure">
<type>virtual void</type>
<name>operator=</name>
<anchor>b0</anchor>
<arglist>(const std::string &amp;)=0</arglist>
</member>
</compound>
<compound kind="class">
<name>mrw::Opt</name>
<filename>classmrw_1_1Opt.html</filename>
<member kind="function">
<type></type>
<name>Opt</name>
<anchor>a0</anchor>
<arglist>(const char shortname, const std::string &amp;longname, const Param &amp;param, const std::string &amp;helptext)</arglist>
</member>
<member kind="function">
<type></type>
<name>Opt</name>
<anchor>a1</anchor>
<arglist>(const char shortname, const std::string &amp;longname, const std::string &amp;helptext)</arglist>
</member>
<member kind="function">
<type>const std::string &amp;</type>
<name>help</name>
<anchor>a2</anchor>
<arglist>() const </arglist>
</member>
<member kind="function">
<type></type>
<name>operator bool</name>
<anchor>a3</anchor>
<arglist>() const </arglist>
</member>
<member kind="function">
<type>const mrw::SmartPointer&lt; Param::Value &gt; &amp;</type>
<name>operator[]</name>
<anchor>a4</anchor>
<arglist>(unsigned int i) const </arglist>
</member>
</compound> </compound>
<compound kind="class"> <compound kind="class">
<name>mrw::Args</name> <name>mrw::Args</name>
@@ -138,19 +520,19 @@
<type>Args &amp;</type> <type>Args &amp;</type>
<name>operator&lt;&lt;</name> <name>operator&lt;&lt;</name>
<anchor>a4</anchor> <anchor>a4</anchor>
<arglist>(char help)</arglist> <arglist>(char helpopt)</arglist>
</member> </member>
<member kind="function"> <member kind="function">
<type>const Opt &amp;</type> <type>const Opt &amp;</type>
<name>find</name> <name>find</name>
<anchor>a5</anchor> <anchor>a5</anchor>
<arglist>(char c) const</arglist> <arglist>(char c) const </arglist>
</member> </member>
<member kind="function"> <member kind="function">
<type>const Opt &amp;</type> <type>const Opt &amp;</type>
<name>find</name> <name>find</name>
<anchor>a6</anchor> <anchor>a6</anchor>
<arglist>(const std::string &amp;s) const</arglist> <arglist>(const std::string &amp;s) const </arglist>
</member> </member>
<member kind="function"> <member kind="function">
<type>const OtherArgs &amp;</type> <type>const OtherArgs &amp;</type>
@@ -178,134 +560,53 @@
</member> </member>
</compound> </compound>
<compound kind="class"> <compound kind="class">
<name>mrw::AutoBfd</name> <name>mrw::AutoResource</name>
<filename>classmrw_1_1AutoBfd.html</filename> <filename>classmrw_1_1AutoResource.html</filename>
<templarg>RESOURCE_TYPE</templarg>
<templarg>FUNCTION_PTR</templarg>
<templarg>FREE_FUNCTION</templarg>
<templarg>INITIAL_VALUE_TYPE</templarg>
<templarg>INITIAL_VALUE</templarg>
<templarg>FREE_TYPE</templarg>
<member kind="function"> <member kind="function">
<type></type> <type></type>
<name>AutoBfd</name> <name>AutoResource</name>
<anchor>a0</anchor> <anchor>a0</anchor>
<arglist>(bfd *p=0)</arglist> <arglist>(FREE_TYPE res=INITIAL_VALUE)</arglist>
</member>
<member kind="function">
<type>AutoBfd &amp;</type>
<name>operator=</name>
<anchor>a2</anchor>
<arglist>(bfd *p)</arglist>
</member>
<member kind="function">
<type>AutoBfd &amp;</type>
<name>operator=</name>
<anchor>a3</anchor>
<arglist>(AutoBfd &amp;o)</arglist>
</member> </member>
<member kind="function"> <member kind="function">
<type></type> <type></type>
<name>operator bfd *</name> <name>AutoResource</name>
<anchor>a4</anchor>
<arglist>()</arglist>
</member>
<member kind="function">
<type>bfd *</type>
<name>operator-&gt;</name>
<anchor>a5</anchor>
<arglist>()</arglist>
</member>
<member kind="function">
<type>bfd *</type>
<name>release</name>
<anchor>a6</anchor>
<arglist>()</arglist>
</member>
</compound>
<compound kind="class">
<name>mrw::AutoFile</name>
<filename>classmrw_1_1AutoFile.html</filename>
<member kind="function">
<type></type>
<name>AutoFile</name>
<anchor>a0</anchor>
<arglist>(int fd=-1)</arglist>
</member>
<member kind="function">
<type></type>
<name>AutoFile</name>
<anchor>a1</anchor> <anchor>a1</anchor>
<arglist>(AutoFile &amp;o)</arglist> <arglist>(AutoResource &amp;o)</arglist>
</member> </member>
<member kind="function"> <member kind="function">
<type></type> <type></type>
<name>~AutoFile</name> <name>~AutoResource</name>
<anchor>a2</anchor> <anchor>a2</anchor>
<arglist>()</arglist> <arglist>()</arglist>
</member> </member>
<member kind="function"> <member kind="function">
<type>AutoFile &amp;</type> <type>AutoResource &amp;</type>
<name>operator=</name> <name>operator=</name>
<anchor>a3</anchor> <anchor>a3</anchor>
<arglist>(int fd)</arglist> <arglist>(RESOURCE_TYPE res)</arglist>
</member> </member>
<member kind="function"> <member kind="function">
<type>AutoFile &amp;</type> <type>AutoResource &amp;</type>
<name>operator=</name> <name>operator=</name>
<anchor>a4</anchor> <anchor>a4</anchor>
<arglist>(AutoFile &amp;other)</arglist> <arglist>(AutoResource &amp;other)</arglist>
</member> </member>
<member kind="function"> <member kind="function">
<type></type> <type></type>
<name>operator const int</name> <name>operator const RESOURCE_TYPE &amp;</name>
<anchor>a5</anchor> <anchor>a5</anchor>
<arglist>() const</arglist> <arglist>() const </arglist>
</member> </member>
<member kind="function"> <member kind="function">
<type>int</type> <type>RESOURCE_TYPE &amp;</type>
<name>release</name> <name>getClean</name>
<anchor>a6</anchor>
<arglist>()</arglist>
</member>
<member kind="function">
<type>AutoFile &amp;</type>
<name>reset</name>
<anchor>a7</anchor>
<arglist>(int=-1)</arglist>
</member>
</compound>
<compound kind="class">
<name>mrw::AutoFree</name>
<filename>classmrw_1_1AutoFree.html</filename>
<templarg>T</templarg>
<member kind="function">
<type></type>
<name>AutoFree</name>
<anchor>a0</anchor>
<arglist>(T *p=0)</arglist>
</member>
<member kind="function">
<type></type>
<name>AutoFree</name>
<anchor>a1</anchor>
<arglist>(AutoFree &amp;o)</arglist>
</member>
<member kind="function">
<type>AutoFree &amp;</type>
<name>operator=</name>
<anchor>a3</anchor>
<arglist>(T *p)</arglist>
</member>
<member kind="function">
<type>AutoFree &amp;</type>
<name>operator=</name>
<anchor>a4</anchor>
<arglist>(AutoFree &amp;o)</arglist>
</member>
<member kind="function">
<type></type>
<name>operator T *</name>
<anchor>a5</anchor>
<arglist>()</arglist>
</member>
<member kind="function">
<type></type>
<name>operator T **</name>
<anchor>a6</anchor> <anchor>a6</anchor>
<arglist>()</arglist> <arglist>()</arglist>
</member> </member>
@@ -313,53 +614,80 @@
<type></type> <type></type>
<name>operator bool</name> <name>operator bool</name>
<anchor>a7</anchor> <anchor>a7</anchor>
<arglist>()</arglist> <arglist>() const </arglist>
</member> </member>
<member kind="function"> <member kind="function">
<type>T *</type> <type>RESOURCE_TYPE</type>
<name>release</name> <name>release</name>
<anchor>a8</anchor> <anchor>a8</anchor>
<arglist>()</arglist> <arglist>()</arglist>
</member> </member>
<member kind="function">
<type>AutoResource &amp;</type>
<name>reset</name>
<anchor>a9</anchor>
<arglist>(RESOURCE_TYPE res=INITIAL_VALUE)</arglist>
</member>
</compound> </compound>
<compound kind="class"> <compound kind="class">
<name>mrw::AutoMapper</name> <name>mrw::MMapHandle</name>
<filename>classmrw_1_1AutoMapper.html</filename> <filename>classmrw_1_1MMapHandle.html</filename>
<member kind="function"> <member kind="function">
<type></type> <type></type>
<name>AutoMapper</name> <name>MMapHandle</name>
<anchor>a0</anchor> <anchor>a0</anchor>
<arglist>(void *cont=0, size_t sz=0)</arglist>
</member>
<member kind="function">
<type></type>
<name>AutoMapper</name>
<anchor>a1</anchor>
<arglist>(int, size_t=0, void *=0, int=PROT_READ, int=MAP_SHARED, off_t=0)</arglist> <arglist>(int, size_t=0, void *=0, int=PROT_READ, int=MAP_SHARED, off_t=0)</arglist>
</member> </member>
<member kind="function"> <member kind="function">
<type></type> <type>MMapHandle &amp;</type>
<name>operator const void *</name> <name>operator=</name>
<anchor>a3</anchor> <anchor>a1</anchor>
<arglist>() const</arglist> <arglist>(int)</arglist>
</member> </member>
<member kind="function"> <member kind="function">
<type>AutoMapper &amp;</type> <type>bool</type>
<name>set</name> <name>operator==</name>
<anchor>a4</anchor> <anchor>a2</anchor>
<arglist>(void *cont, size_t sz)</arglist> <arglist>(int i) const </arglist>
</member> </member>
<member kind="function"> <member kind="variable">
<type>void *</type> <type>void *</type>
<name>release</name> <name>first</name>
<anchor>a5</anchor> <anchor>o0</anchor>
<arglist>()</arglist> <arglist></arglist>
</member>
<member kind="variable">
<type>size_t</type>
<name>second</name>
<anchor>o1</anchor>
<arglist></arglist>
</member>
</compound>
<compound kind="class">
<name>mrw::Auto</name>
<filename>classmrw_1_1Auto.html</filename>
<templarg>T</templarg>
<member kind="typedef">
<type>mrw::AutoResource&lt; T, void(*)(void *),&amp;free, int, 0, void * &gt;</type>
<name>Free</name>
<anchor>w0</anchor>
<arglist></arglist>
</member>
</compound>
<compound kind="class">
<name>mrw::exception</name>
<filename>classmrw_1_1exception.html</filename>
<member kind="function" virtualness="virtual">
<type>virtual const char *</type>
<name>what</name>
<anchor>a2</anchor>
<arglist>() const </arglist>
</member> </member>
<member kind="function"> <member kind="function">
<type>const void *</type> <type>const std::string &amp;</type>
<name>last</name> <name>stacktrace</name>
<anchor>a6</anchor> <anchor>a3</anchor>
<arglist>() const</arglist> <arglist>() const </arglist>
</member> </member>
</compound> </compound>
<compound kind="class"> <compound kind="class">
@@ -370,7 +698,7 @@
<type>virtual const char *</type> <type>virtual const char *</type>
<name>what</name> <name>what</name>
<anchor>a0</anchor> <anchor>a0</anchor>
<arglist>() const</arglist> <arglist>() const </arglist>
</member> </member>
</compound> </compound>
<compound kind="class"> <compound kind="class">
@@ -381,7 +709,7 @@
<type>virtual const char *</type> <type>virtual const char *</type>
<name>what</name> <name>what</name>
<anchor>a0</anchor> <anchor>a0</anchor>
<arglist>() const</arglist> <arglist>() const </arglist>
</member> </member>
</compound> </compound>
<compound kind="class"> <compound kind="class">
@@ -392,7 +720,7 @@
<type>virtual const char *</type> <type>virtual const char *</type>
<name>what</name> <name>what</name>
<anchor>a0</anchor> <anchor>a0</anchor>
<arglist>() const</arglist> <arglist>() const </arglist>
</member> </member>
</compound> </compound>
<compound kind="class"> <compound kind="class">
@@ -403,47 +731,24 @@
<type>virtual const char *</type> <type>virtual const char *</type>
<name>what</name> <name>what</name>
<anchor>a0</anchor> <anchor>a0</anchor>
<arglist>() const</arglist> <arglist>() const </arglist>
</member> </member>
</compound> </compound>
<compound kind="class"> <compound kind="class">
<name>mrw::Cmd</name> <name>mrw::logic_error</name>
<filename>classmrw_1_1Cmd.html</filename> <filename>classmrw_1_1logic__error.html</filename>
<base virtualness="virtual">mrw::exception</base>
<member kind="function"> <member kind="function">
<type></type> <type></type>
<name>Cmd</name> <name>logic_error</name>
<anchor>a0</anchor> <anchor>a0</anchor>
<arglist>(const std::string &amp;)</arglist> <arglist>(const std::string &amp;arg)</arglist>
</member> </member>
<member kind="function"> <member kind="function" virtualness="virtual">
<type>Cmd &amp;</type> <type>virtual const char *</type>
<name>operator,</name> <name>what</name>
<anchor>a1</anchor> <anchor>a1</anchor>
<arglist>(const std::string &amp;)</arglist> <arglist>() const </arglist>
</member>
<member kind="function">
<type>Cmd &amp;</type>
<name>operator&lt;&lt;</name>
<anchor>a2</anchor>
<arglist>(const std::string &amp;)</arglist>
</member>
<member kind="function">
<type></type>
<name>operator std::string</name>
<anchor>a3</anchor>
<arglist>() const</arglist>
</member>
<member kind="function">
<type></type>
<name>operator Exec</name>
<anchor>a4</anchor>
<arglist>() const</arglist>
</member>
<member kind="function">
<type>Exec</type>
<name>execute</name>
<anchor>a5</anchor>
<arglist>(bool=true) const</arglist>
</member> </member>
</compound> </compound>
<compound kind="class"> <compound kind="class">
@@ -460,23 +765,143 @@
<type>virtual const char *</type> <type>virtual const char *</type>
<name>what</name> <name>what</name>
<anchor>a1</anchor> <anchor>a1</anchor>
<arglist>() const</arglist> <arglist>() const </arglist>
</member> </member>
</compound> </compound>
<compound kind="class"> <compound kind="class">
<name>mrw::exception</name> <name>mrw::invalid_argument</name>
<filename>classmrw_1_1exception.html</filename> <filename>classmrw_1_1invalid__argument.html</filename>
<base virtualness="virtual">mrw::exception</base>
<member kind="function">
<type></type>
<name>invalid_argument</name>
<anchor>a0</anchor>
<arglist>(const std::string &amp;arg)</arglist>
</member>
<member kind="function" virtualness="virtual">
<type>virtual const char *</type>
<name>what</name>
<anchor>a1</anchor>
<arglist>() const </arglist>
</member>
</compound>
<compound kind="class">
<name>mrw::length_error</name>
<filename>classmrw_1_1length__error.html</filename>
<base virtualness="virtual">mrw::exception</base>
<member kind="function">
<type></type>
<name>length_error</name>
<anchor>a0</anchor>
<arglist>(const std::string &amp;arg)</arglist>
</member>
<member kind="function" virtualness="virtual">
<type>virtual const char *</type>
<name>what</name>
<anchor>a1</anchor>
<arglist>() const </arglist>
</member>
</compound>
<compound kind="class">
<name>mrw::out_of_range</name>
<filename>classmrw_1_1out__of__range.html</filename>
<base virtualness="virtual">mrw::exception</base>
<member kind="function">
<type></type>
<name>out_of_range</name>
<anchor>a0</anchor>
<arglist>(const std::string &amp;arg)</arglist>
</member>
<member kind="function" virtualness="virtual">
<type>virtual const char *</type>
<name>what</name>
<anchor>a1</anchor>
<arglist>() const </arglist>
</member>
</compound>
<compound kind="class">
<name>mrw::runtime_error</name>
<filename>classmrw_1_1runtime__error.html</filename>
<base virtualness="virtual">mrw::exception</base>
<member kind="function">
<type></type>
<name>runtime_error</name>
<anchor>a0</anchor>
<arglist>(const std::string &amp;arg)</arglist>
</member>
<member kind="function" virtualness="virtual">
<type>virtual const char *</type>
<name>what</name>
<anchor>a1</anchor>
<arglist>() const </arglist>
</member>
</compound>
<compound kind="class">
<name>mrw::overflow_error</name>
<filename>classmrw_1_1overflow__error.html</filename>
<base virtualness="virtual">mrw::exception</base>
<member kind="function">
<type></type>
<name>overflow_error</name>
<anchor>a0</anchor>
<arglist>(const std::string &amp;arg)</arglist>
</member>
<member kind="function" virtualness="virtual">
<type>virtual const char *</type>
<name>what</name>
<anchor>a1</anchor>
<arglist>() const </arglist>
</member>
</compound>
<compound kind="class">
<name>mrw::range_error</name>
<filename>classmrw_1_1range__error.html</filename>
<base virtualness="virtual">mrw::exception</base>
<member kind="function">
<type></type>
<name>range_error</name>
<anchor>a0</anchor>
<arglist>(const std::string &amp;arg)</arglist>
</member>
<member kind="function" virtualness="virtual">
<type>virtual const char *</type>
<name>what</name>
<anchor>a1</anchor>
<arglist>() const </arglist>
</member>
</compound>
<compound kind="class">
<name>mrw::underflow_error</name>
<filename>classmrw_1_1underflow__error.html</filename>
<base virtualness="virtual">mrw::exception</base>
<member kind="function">
<type></type>
<name>underflow_error</name>
<anchor>a0</anchor>
<arglist>(const std::string &amp;arg)</arglist>
</member>
<member kind="function" virtualness="virtual">
<type>virtual const char *</type>
<name>what</name>
<anchor>a1</anchor>
<arglist>() const </arglist>
</member>
</compound>
<compound kind="class">
<name>mrw::ExecutionFailedExc</name>
<filename>classmrw_1_1ExecutionFailedExc.html</filename>
<base>mrw::exception</base>
<member kind="function">
<type></type>
<name>ExecutionFailedExc</name>
<anchor>a0</anchor>
<arglist>(const std::string &amp;, const std::string &amp;)</arglist>
</member>
<member kind="function" virtualness="virtual"> <member kind="function" virtualness="virtual">
<type>virtual const char *</type> <type>virtual const char *</type>
<name>what</name> <name>what</name>
<anchor>a2</anchor> <anchor>a2</anchor>
<arglist>() const</arglist> <arglist>() const </arglist>
</member>
<member kind="function">
<type>const std::string &amp;</type>
<name>stacktrace</name>
<anchor>a3</anchor>
<arglist>() const</arglist>
</member> </member>
</compound> </compound>
<compound kind="class"> <compound kind="class">
@@ -544,363 +969,43 @@
</member> </member>
</compound> </compound>
<compound kind="class"> <compound kind="class">
<name>mrw::ExecutionFailedExc</name> <name>mrw::Cmd</name>
<filename>classmrw_1_1ExecutionFailedExc.html</filename> <filename>classmrw_1_1Cmd.html</filename>
<base>mrw::exception</base>
<member kind="function"> <member kind="function">
<type></type> <type></type>
<name>ExecutionFailedExc</name> <name>Cmd</name>
<anchor>a0</anchor> <anchor>a0</anchor>
<arglist>(const std::string &amp;, const std::string &amp;)</arglist> <arglist>(const std::string &amp;)</arglist>
</member> </member>
<member kind="function" virtualness="virtual">
<type>virtual const char *</type>
<name>what</name>
<anchor>a2</anchor>
<arglist>() const</arglist>
</member>
</compound>
<compound kind="class">
<name>mrw::invalid_argument</name>
<filename>classmrw_1_1invalid__argument.html</filename>
<base virtualness="virtual">mrw::exception</base>
<member kind="function"> <member kind="function">
<type></type> <type>Cmd &amp;</type>
<name>invalid_argument</name> <name>operator,</name>
<anchor>a0</anchor>
<arglist>(const std::string &amp;arg)</arglist>
</member>
<member kind="function" virtualness="virtual">
<type>virtual const char *</type>
<name>what</name>
<anchor>a1</anchor> <anchor>a1</anchor>
<arglist>() const</arglist> <arglist>(const std::string &amp;)</arglist>
</member>
</compound>
<compound kind="class">
<name>mrw::length_error</name>
<filename>classmrw_1_1length__error.html</filename>
<base virtualness="virtual">mrw::exception</base>
<member kind="function">
<type></type>
<name>length_error</name>
<anchor>a0</anchor>
<arglist>(const std::string &amp;arg)</arglist>
</member>
<member kind="function" virtualness="virtual">
<type>virtual const char *</type>
<name>what</name>
<anchor>a1</anchor>
<arglist>() const</arglist>
</member>
</compound>
<compound kind="class">
<name>mrw::logic_error</name>
<filename>classmrw_1_1logic__error.html</filename>
<base virtualness="virtual">mrw::exception</base>
<member kind="function">
<type></type>
<name>logic_error</name>
<anchor>a0</anchor>
<arglist>(const std::string &amp;arg)</arglist>
</member>
<member kind="function" virtualness="virtual">
<type>virtual const char *</type>
<name>what</name>
<anchor>a1</anchor>
<arglist>() const</arglist>
</member>
</compound>
<compound kind="class">
<name>mrw::Opt</name>
<filename>classmrw_1_1Opt.html</filename>
<member kind="function">
<type></type>
<name>Opt::Opt</name>
<anchor>a0</anchor>
<arglist>(const char shortname, const std::string &amp;longname, const Param &amp;param, const std::string &amp;help)</arglist>
</member> </member>
<member kind="function"> <member kind="function">
<type></type> <type>Cmd &amp;</type>
<name>Opt::Opt</name>
<anchor>a1</anchor>
<arglist>(const char shortname, const std::string &amp;longname, const std::string &amp;help)</arglist>
</member>
<member kind="function">
<type>const std::string &amp;</type>
<name>help</name>
<anchor>a2</anchor>
<arglist>() const</arglist>
</member>
<member kind="function">
<type></type>
<name>operator bool</name>
<anchor>a3</anchor>
<arglist>() const</arglist>
</member>
<member kind="function">
<type>const mrw::SmartPointer&lt; Param::Value &gt; &amp;</type>
<name>operator[]</name>
<anchor>a4</anchor>
<arglist>(unsigned int i) const</arglist>
</member>
</compound>
<compound kind="class">
<name>mrw::out_of_range</name>
<filename>classmrw_1_1out__of__range.html</filename>
<base virtualness="virtual">mrw::exception</base>
<member kind="function">
<type></type>
<name>out_of_range</name>
<anchor>a0</anchor>
<arglist>(const std::string &amp;arg)</arglist>
</member>
<member kind="function" virtualness="virtual">
<type>virtual const char *</type>
<name>what</name>
<anchor>a1</anchor>
<arglist>() const</arglist>
</member>
</compound>
<compound kind="class">
<name>mrw::overflow_error</name>
<filename>classmrw_1_1overflow__error.html</filename>
<base virtualness="virtual">mrw::exception</base>
<member kind="function">
<type></type>
<name>overflow_error</name>
<anchor>a0</anchor>
<arglist>(const std::string &amp;arg)</arglist>
</member>
<member kind="function" virtualness="virtual">
<type>virtual const char *</type>
<name>what</name>
<anchor>a1</anchor>
<arglist>() const</arglist>
</member>
</compound>
<compound kind="class">
<name>mrw::Param</name>
<filename>classmrw_1_1Param.html</filename>
<member kind="function">
<type>int</type>
<name>size</name>
<anchor>a0</anchor>
<arglist>() const</arglist>
</member>
<member kind="function">
<type>Param &amp;</type>
<name>operator&lt;&lt;</name>
<anchor>a1</anchor>
<arglist>(const char *const s)</arglist>
</member>
<member kind="function">
<type>Param &amp;</type>
<name>operator&lt;&lt;</name> <name>operator&lt;&lt;</name>
<anchor>a2</anchor> <anchor>a2</anchor>
<arglist>(const std::string &amp;s)</arglist> <arglist>(const std::string &amp;)</arglist>
</member> </member>
<member kind="function"> <member kind="function">
<type>Param &amp;</type> <type></type>
<name>operator&lt;&lt;</name> <name>operator std::string</name>
<anchor>a3</anchor> <anchor>a3</anchor>
<arglist>(int i)</arglist> <arglist>() const </arglist>
</member> </member>
<member kind="function"> <member kind="function">
<type>Param &amp;</type> <type></type>
<name>operator&lt;&lt;</name> <name>operator mrw::Exec</name>
<anchor>a4</anchor> <anchor>a4</anchor>
<arglist>(bool b)</arglist> <arglist>() const </arglist>
</member> </member>
<member kind="function"> <member kind="function">
<type>const mrw::SmartPointer&lt; Value &gt; &amp;</type> <type>Exec</type>
<name>operator[]</name> <name>execute</name>
<anchor>a5</anchor> <anchor>a5</anchor>
<arglist>(unsigned int i) const</arglist> <arglist>(bool=true) const </arglist>
</member>
</compound>
<compound kind="class">
<name>mrw::Param::Value</name>
<filename>classmrw_1_1Param_1_1Value.html</filename>
<member kind="function" virtualness="virtual">
<type>virtual const std::string &amp;</type>
<name>toString</name>
<anchor>a1</anchor>
<arglist>() const</arglist>
</member>
<member kind="function" virtualness="virtual">
<type>virtual int</type>
<name>toInt</name>
<anchor>a2</anchor>
<arglist>() const</arglist>
</member>
<member kind="function" virtualness="virtual">
<type>virtual bool</type>
<name>toBool</name>
<anchor>a3</anchor>
<arglist>() const</arglist>
</member>
<member kind="function" virtualness="pure">
<type>virtual std::string</type>
<name>printable</name>
<anchor>a4</anchor>
<arglist>() const=0</arglist>
</member>
<member kind="function" virtualness="pure">
<type>virtual const std::string &amp;</type>
<name>typestr</name>
<anchor>a5</anchor>
<arglist>() const=0</arglist>
</member>
<member kind="function" protection="public" virtualness="pure">
<type>virtual void</type>
<name>operator=</name>
<anchor>b0</anchor>
<arglist>(const std::string &amp;)=0</arglist>
</member>
</compound>
<compound kind="class">
<name>mrw::Param::Value</name>
<filename>classmrw_1_1Param_1_1Value.html</filename>
<member kind="function" virtualness="virtual">
<type>virtual const std::string &amp;</type>
<name>toString</name>
<anchor>a1</anchor>
<arglist>() const</arglist>
</member>
<member kind="function" virtualness="virtual">
<type>virtual int</type>
<name>toInt</name>
<anchor>a2</anchor>
<arglist>() const</arglist>
</member>
<member kind="function" virtualness="virtual">
<type>virtual bool</type>
<name>toBool</name>
<anchor>a3</anchor>
<arglist>() const</arglist>
</member>
<member kind="function" virtualness="pure">
<type>virtual std::string</type>
<name>printable</name>
<anchor>a4</anchor>
<arglist>() const=0</arglist>
</member>
<member kind="function" virtualness="pure">
<type>virtual const std::string &amp;</type>
<name>typestr</name>
<anchor>a5</anchor>
<arglist>() const=0</arglist>
</member>
<member kind="function" protection="public" virtualness="pure">
<type>virtual void</type>
<name>operator=</name>
<anchor>b0</anchor>
<arglist>(const std::string &amp;)=0</arglist>
</member>
</compound>
<compound kind="class">
<name>mrw::pipe</name>
<filename>classmrw_1_1pipe.html</filename>
<member kind="function">
<type></type>
<name>pipe</name>
<anchor>a0</anchor>
<arglist>()</arglist>
</member>
<member kind="function">
<type></type>
<name>~pipe</name>
<anchor>a1</anchor>
<arglist>()</arglist>
</member>
<member kind="function">
<type>void</type>
<name>close</name>
<anchor>a2</anchor>
<arglist>()</arglist>
</member>
<member kind="function">
<type>void</type>
<name>close_in</name>
<anchor>a3</anchor>
<arglist>()</arglist>
</member>
<member kind="function">
<type>void</type>
<name>close_out</name>
<anchor>a4</anchor>
<arglist>()</arglist>
</member>
<member kind="function">
<type></type>
<name>operator bool</name>
<anchor>a5</anchor>
<arglist>()</arglist>
</member>
<member kind="function">
<type>int</type>
<name>error</name>
<anchor>a6</anchor>
<arglist>()</arglist>
</member>
<member kind="function">
<type>void</type>
<name>connect_cout</name>
<anchor>a7</anchor>
<arglist>()</arglist>
</member>
<member kind="function">
<type>void</type>
<name>connect_cerr</name>
<anchor>a8</anchor>
<arglist>()</arglist>
</member>
<member kind="function">
<type>int</type>
<name>istream</name>
<anchor>a9</anchor>
<arglist>()</arglist>
</member>
<member kind="function">
<type>int</type>
<name>ostream</name>
<anchor>a10</anchor>
<arglist>()</arglist>
</member>
</compound>
<compound kind="class">
<name>mrw::range_error</name>
<filename>classmrw_1_1range__error.html</filename>
<base virtualness="virtual">mrw::exception</base>
<member kind="function">
<type></type>
<name>range_error</name>
<anchor>a0</anchor>
<arglist>(const std::string &amp;arg)</arglist>
</member>
<member kind="function" virtualness="virtual">
<type>virtual const char *</type>
<name>what</name>
<anchor>a1</anchor>
<arglist>() const</arglist>
</member>
</compound>
<compound kind="class">
<name>mrw::runtime_error</name>
<filename>classmrw_1_1runtime__error.html</filename>
<base virtualness="virtual">mrw::exception</base>
<member kind="function">
<type></type>
<name>runtime_error</name>
<anchor>a0</anchor>
<arglist>(const std::string &amp;arg)</arglist>
</member>
<member kind="function" virtualness="virtual">
<type>virtual const char *</type>
<name>what</name>
<anchor>a1</anchor>
<arglist>() const</arglist>
</member> </member>
</compound> </compound>
<compound kind="class"> <compound kind="class">
@@ -953,19 +1058,19 @@
<type>const TYPE &amp;</type> <type>const TYPE &amp;</type>
<name>operator *</name> <name>operator *</name>
<anchor>a9</anchor> <anchor>a9</anchor>
<arglist>() const</arglist> <arglist>() const </arglist>
</member> </member>
<member kind="function"> <member kind="function">
<type>TYPE *const</type> <type>TYPE *const </type>
<name>operator-&gt;</name> <name>operator-&gt;</name>
<anchor>a10</anchor> <anchor>a10</anchor>
<arglist>()</arglist> <arglist>()</arglist>
</member> </member>
<member kind="function"> <member kind="function">
<type>const TYPE *const</type> <type>const TYPE *const </type>
<name>operator-&gt;</name> <name>operator-&gt;</name>
<anchor>a11</anchor> <anchor>a11</anchor>
<arglist>() const</arglist> <arglist>() const </arglist>
</member> </member>
<member kind="function"> <member kind="function">
<type></type> <type></type>
@@ -993,19 +1098,19 @@
<type></type> <type></type>
<name>operator std::string</name> <name>operator std::string</name>
<anchor>a1</anchor> <anchor>a1</anchor>
<arglist>() const</arglist> <arglist>() const </arglist>
</member> </member>
<member kind="function"> <member kind="function">
<type></type> <type></type>
<name>operator const AddressTrace &amp;</name> <name>operator const AddressTrace &amp;</name>
<anchor>a2</anchor> <anchor>a2</anchor>
<arglist>() const</arglist> <arglist>() const </arglist>
</member> </member>
<member kind="function"> <member kind="function">
<type>const StackTrace &amp;</type> <type>const StackTrace &amp;</type>
<name>print</name> <name>print</name>
<anchor>a3</anchor> <anchor>a3</anchor>
<arglist>(std::ostream &amp;os) const</arglist> <arglist>(std::ostream &amp;os) const </arglist>
</member> </member>
<member kind="function" static="yes"> <member kind="function" static="yes">
<type>CodePos</type> <type>CodePos</type>
@@ -1089,20 +1194,73 @@
</member> </member>
</compound> </compound>
<compound kind="class"> <compound kind="class">
<name>mrw::underflow_error</name> <name>mrw::Pipe</name>
<filename>classmrw_1_1underflow__error.html</filename> <filename>classmrw_1_1Pipe.html</filename>
<base virtualness="virtual">mrw::exception</base>
<member kind="function"> <member kind="function">
<type></type> <type></type>
<name>underflow_error</name> <name>Pipe</name>
<anchor>a0</anchor> <anchor>a0</anchor>
<arglist>(const std::string &amp;arg)</arglist> <arglist>()</arglist>
</member> </member>
<member kind="function" virtualness="virtual"> <member kind="function">
<type>virtual const char *</type> <type></type>
<name>what</name> <name>~Pipe</name>
<anchor>a1</anchor> <anchor>a1</anchor>
<arglist>() const</arglist> <arglist>()</arglist>
</member>
<member kind="function">
<type>void</type>
<name>close</name>
<anchor>a2</anchor>
<arglist>()</arglist>
</member>
<member kind="function">
<type>void</type>
<name>close_in</name>
<anchor>a3</anchor>
<arglist>()</arglist>
</member>
<member kind="function">
<type>void</type>
<name>close_out</name>
<anchor>a4</anchor>
<arglist>()</arglist>
</member>
<member kind="function">
<type></type>
<name>operator bool</name>
<anchor>a5</anchor>
<arglist>()</arglist>
</member>
<member kind="function">
<type>int</type>
<name>error</name>
<anchor>a6</anchor>
<arglist>()</arglist>
</member>
<member kind="function">
<type>void</type>
<name>connect_cout</name>
<anchor>a7</anchor>
<arglist>()</arglist>
</member>
<member kind="function">
<type>void</type>
<name>connect_cerr</name>
<anchor>a8</anchor>
<arglist>()</arglist>
</member>
<member kind="function">
<type>int</type>
<name>istream</name>
<anchor>a9</anchor>
<arglist>()</arglist>
</member>
<member kind="function">
<type>int</type>
<name>ostream</name>
<anchor>a10</anchor>
<arglist>()</arglist>
</member> </member>
</compound> </compound>
</tagfile> </tagfile>

View File

@@ -1,51 +1,102 @@
AM_CPPFLAGS := ${AM_CPPFLAGS} -I.. ## @file
##
## $Id$
##
## $Date$
## $Author$
##
## @copy &copy; Marc W&auml;ckerlin
## @license LGPL, see file <a href="license.html">COPYING</a>
##
## $Log$
## Revision 1.6 2004/08/28 16:21:25 marc
## mrw-c++-0.92 (mrw)
## - new file: version.cpp
## - new file header for all sources
## - work around warning in mrw::auto<T>
## - possibility to compile without log4cxx
## - work around bugs in demangle.h and libiberty.h
## - corrections in documentation
## - added simple tracing mechanism
## - more warnings
## - small corrections in Auto<>::Free and a new test for it
## - possibility to compile without stack trace
##
AM_CPPFLAGS += -I..
if HAVE_STACKTRACE
AM_CPPFLAGS += -DHAVE_STACKTRACE
endif
CLEANFILES = doxygen.error CLEANFILES = doxygen.error
examplesdir = ${pkgdatadir}/examples examplesdir = ${pkgdatadir}/examples
examples_DATA = examples/* examples_DATA = examples/*
htmldir = ${pkgdatadir}/doc/html htmldir = ${pkgdatadir}/doc/html
html_DATA = doc/html/* html_DATA = doc/html/index.html doc/html/*
pdfdir = ${pkgdatadir}/doc/pdf pdfdir = ${pkgdatadir}/doc/pdf
pdf_DATA = doc/latex/@PACKAGENAME@-@MAJOR@.@MINOR@.pdf pdf_DATA = doc/latex/@PACKAGENAME@-@MAJOR@.@MINOR@.pdf
EXTRA_DIST = test.dat ${examples_DATA} ${html_DATA} ${pdf_DATA} EXTRA_DIST = test.dat ${examples_DATA} ${html_DATA} ${pdf_DATA}
lib_LTLIBRARIES = libmrw.la libmrwexcstderr.la libmrwexclog4cxx.la lib_LTLIBRARIES = libmrw.la
if HAVE_STACKTRACE
lib_LTLIBRARIES += libmrwexcstderr.la
if HAVE_LOG4CXX
lib_LTLIBRARIES += libmrwexclog4cxx.la
endif
endif
libmrw_la_SOURCES = mrw.hpp \ libmrw_la_SOURCES = mrw.hpp \
auto.hpp auto.cpp unistd.hpp smartpointer.hpp \ auto.hpp unistd.hpp smartpointer.hpp \
stacktrace.hpp stacktrace.cpp exception.hpp exception.cpp \ exception.hpp exception.cpp \
exec.hpp exec.cpp \ exec.hpp exec.cpp \
arg.hpp arg.hpp arg.cpp version.cpp
if HAVE_STACKTRACE
libmrw_la_SOURCES += stacktrace.hpp stacktrace.cpp
endif
libmrw_la_LDFLAGS = -version-info @MAJOR@:@MINOR@ libmrw_la_LDFLAGS = -version-info @MAJOR@:@MINOR@
libmrwexcstderr_la_SOURCES = autostacktracestderr.cpp if HAVE_STACKTRACE
libmrwexcstderr_la_LDFLAGS = -version-info @MAJOR@:@MINOR@ libmrwexcstderr_la_SOURCES = autostacktracestderr.cpp version.cpp
libmrwexcstderr_la_LIBADD = -lmrw libmrwexcstderr_la_LDFLAGS = -version-info @MAJOR@:@MINOR@
libmrwexcstderr_la_LIBADD = -lmrw
libmrwexclog4cxx_la_SOURCES = autostacktracelog4cxx.cpp if HAVE_LOG4CXX
libmrwexclog4cxx_la_LDFLAGS = -version-info @MAJOR@:@MINOR@ libmrwexclog4cxx_la_SOURCES = autostacktracelog4cxx.cpp version.cpp
libmrwexclog4cxx_la_LIBADD = -lmrw libmrwexclog4cxx_la_LDFLAGS = -version-info @MAJOR@:@MINOR@
libmrwexclog4cxx_la_LIBADD = -lmrw
endif
endif
check_PROGRAMS = auto_test smartpointer_test exec_test \ check_PROGRAMS = auto_test smartpointer_test exec_test
stacktrace_test mrwexcstderr_test mrwexclog4cxx_test if HAVE_STACKTRACE
auto_test_SOURCES = auto_test.cpp check_PROGRAMS += stacktrace_test mrwexcstderr_test
if HAVE_LOG4CXX
check_PROGRAMS += mrwexclog4cxx_test
endif
endif
auto_test_SOURCES = auto_test.cpp version.cpp
auto_test_CPPFLAGS = -I.. -g3 auto_test_CPPFLAGS = -I.. -g3
auto_test_LDADD = -lmrw -lcppunit auto_test_LDADD = -lmrw -lcppunit
smartpointer_test_SOURCES = smartpointer_test.cpp smartpointer_test_SOURCES = smartpointer_test.cpp version.cpp
smartpointer_test_CPPFLAGS = -I.. -g3 smartpointer_test_CPPFLAGS = -I.. -g3
smartpointer_test_LDADD = -lmrw -lcppunit smartpointer_test_LDADD = -lmrw -lcppunit
exec_test_SOURCES = exec_test.cpp exec_test_SOURCES = exec_test.cpp version.cpp
exec_test_CPPFLAGS = -I.. -g3 exec_test_CPPFLAGS = -I.. -g3
exec_test_LDADD = -lmrw -lcppunit exec_test_LDADD = -lmrw -lcppunit
stacktrace_test_SOURCES = stacktrace_test.cpp if HAVE_STACKTRACE
stacktrace_test_CPPFLAGS = -I.. -g3 stacktrace_test_SOURCES = stacktrace_test.cpp version.cpp
stacktrace_test_LDADD = -lmrw -lcppunit stacktrace_test_CPPFLAGS = -I.. -g3
mrwexcstderr_test_SOURCES = mrwexcstderr_test.cpp stacktrace_test_LDADD = -lmrw -lcppunit
mrwexcstderr_test_CPPFLAGS = -I.. -g3 mrwexcstderr_test_SOURCES = mrwexcstderr_test.cpp version.cpp
mrwexcstderr_test_LDADD = -lmrwexcstderr -lcppunit mrwexcstderr_test_CPPFLAGS = -I.. -g3
mrwexclog4cxx_test_SOURCES = mrwexclog4cxx_test.cpp mrwexcstderr_test_LDADD = -lmrwexcstderr -lcppunit
mrwexclog4cxx_test_CPPFLAGS = -I.. -g3 if HAVE_LOG4CXX
mrwexclog4cxx_test_LDADD = -lmrwexclog4cxx -lcppunit -llog4cxx mrwexclog4cxx_test_SOURCES = mrwexclog4cxx_test.cpp version.cpp
mrwexclog4cxx_test_CPPFLAGS = -I.. -g3
mrwexclog4cxx_test_LDADD = -lmrwexclog4cxx -lcppunit -llog4cxx
endif
endif
TESTS = ${check_PROGRAMS} TESTS = ${check_PROGRAMS}
deps = ../COPYING ../README ../INSTALL ../NEWS ../ChangeLog deps = ../COPYING ../README ../INSTALL ../NEWS ../ChangeLog
@@ -55,3 +106,8 @@ doc/html/index.html: doxyfile *.[ch]pp ${deps}
doc/latex/@PACKAGENAME@-@MAJOR@.@MINOR@.pdf: doxyfile *.[ch]pp ${deps} doc/latex/@PACKAGENAME@-@MAJOR@.@MINOR@.pdf: doxyfile *.[ch]pp ${deps}
cd doc/latex && make && \ cd doc/latex && make && \
mv refman.pdf @PACKAGENAME@-@MAJOR@.@MINOR@.pdf mv refman.pdf @PACKAGENAME@-@MAJOR@.@MINOR@.pdf
clean-local:
- rm doxygen.err libmrw.doxytag
distclean-local:
- rm -r doc/html/* doc/latex/*
- rm makefile makefile.in doxygen.err libmrw.doxytag

View File

@@ -41,6 +41,14 @@
@section moreinfo Additional Information @section moreinfo Additional Information
@section threads Thread Safety
All classes are not thread safe, that means they should either
always be accessed from the same thread, or you are responsible
for locking. If you need thread safety as a feature, please send
me an email and ask me for it (you find the adress in the package
or on my personal homepage: http://marc.waeckerlin.org).
See the <a href="pages.html">"Related Pages"</a>. See the <a href="pages.html">"Related Pages"</a>.
- @ref license "License Information (LGPL)" - @ref license "License Information (LGPL)"

View File

@@ -1,3 +1,28 @@
/** @file
$Id$
$Date$
$Author$
@copy &copy; Marc W&auml;ckerlin
@license LGPL, see file <a href="license.html">COPYING</a>
$Log$
Revision 1.2 2004/08/28 16:21:25 marc
mrw-c++-0.92 (mrw)
- new file: version.cpp
- new file header for all sources
- work around warning in mrw::auto<T>
- possibility to compile without log4cxx
- work around bugs in demangle.h and libiberty.h
- corrections in documentation
- added simple tracing mechanism
- more warnings
- small corrections in Auto<>::Free and a new test for it
- possibility to compile without stack trace
*/
#include <mrw/exception.hpp> #include <mrw/exception.hpp>
#include <log4cxx/basicconfigurator.h> #include <log4cxx/basicconfigurator.h>
#include <cppunit/TestFixture.h> #include <cppunit/TestFixture.h>

View File

@@ -1,3 +1,28 @@
/** @file
$Id$
$Date$
$Author$
@copy &copy; Marc W&auml;ckerlin
@license LGPL, see file <a href="license.html">COPYING</a>
$Log$
Revision 1.2 2004/08/28 16:21:25 marc
mrw-c++-0.92 (mrw)
- new file: version.cpp
- new file header for all sources
- work around warning in mrw::auto<T>
- possibility to compile without log4cxx
- work around bugs in demangle.h and libiberty.h
- corrections in documentation
- added simple tracing mechanism
- more warnings
- small corrections in Auto<>::Free and a new test for it
- possibility to compile without stack trace
*/
#include <mrw/exception.hpp> #include <mrw/exception.hpp>
#include <cppunit/TestFixture.h> #include <cppunit/TestFixture.h>
#include <cppunit/ui/text/TestRunner.h> #include <cppunit/ui/text/TestRunner.h>

View File

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

View File

@@ -1,3 +1,28 @@
/** @file
$Id$
$Date$
$Author$
@copy &copy; Marc W&auml;ckerlin
@license LGPL, see file <a href="license.html">COPYING</a>
$Log$
Revision 1.2 2004/08/28 16:21:25 marc
mrw-c++-0.92 (mrw)
- new file: version.cpp
- new file header for all sources
- work around warning in mrw::auto<T>
- possibility to compile without log4cxx
- work around bugs in demangle.h and libiberty.h
- corrections in documentation
- added simple tracing mechanism
- more warnings
- small corrections in Auto<>::Free and a new test for it
- possibility to compile without stack trace
*/
#ifndef __MRW__SMARTPOINTER_HPP__ #ifndef __MRW__SMARTPOINTER_HPP__
#define __MRW__SMARTPOINTER_HPP__ #define __MRW__SMARTPOINTER_HPP__
@@ -7,17 +32,17 @@ namespace mrw {
private: private:
unsigned int _cnt; unsigned int _cnt;
public: public:
PointerCounter(): PointerCounter() throw():
_cnt(1) { _cnt(1) {
} }
PointerCounter* incr() { PointerCounter* incr() throw() {
++_cnt; ++_cnt;
return this; return this;
} }
int decr() { int decr() throw() {
return --_cnt; return --_cnt;
} }
int get() { int get() throw() {
return _cnt; return _cnt;
} }
}; };
@@ -25,11 +50,11 @@ namespace mrw {
class SmartPointerParent { class SmartPointerParent {
protected: protected:
template<class TYPE> template<class TYPE>
PointerCounter* getCounter(TYPE& sp) { PointerCounter* getCounter(TYPE& sp) throw() {
return sp._cnt; return sp._cnt;
} }
template<class TYPE> template<class TYPE>
typename TYPE::Pointer getPointer(TYPE& sp) { typename TYPE::Pointer getPointer(TYPE& sp) throw() {
return sp._ptr; return sp._ptr;
} }
}; };
@@ -68,7 +93,7 @@ namespace mrw {
PointerCounter* _cnt; PointerCounter* _cnt;
TYPE* _ptr; TYPE* _ptr;
private: private:
void drop() { void drop() throw() {
if (_cnt && !_cnt->decr()) { if (_cnt && !_cnt->decr()) {
delete _cnt; _cnt=0; delete _cnt; _cnt=0;
delete _ptr; _ptr=0; delete _ptr; _ptr=0;
@@ -78,30 +103,30 @@ namespace mrw {
friend class SmartPointerParent; friend class SmartPointerParent;
friend class SmartPointerTest; friend class SmartPointerTest;
public: public:
SmartPointer(): SmartPointer() throw():
_cnt(0), _ptr(0) { _cnt(0), _ptr(0) {
} }
SmartPointer(const SmartPointer<TYPE>& o): SmartPointer(const SmartPointer<TYPE>& o) throw():
_cnt(o._cnt?o._cnt->incr():0), _ptr(o._ptr) { _cnt(o._cnt?o._cnt->incr():0), _ptr(o._ptr) {
} }
SmartPointer(TYPE* ptr): SmartPointer(TYPE* ptr) throw():
_cnt(ptr ? new PointerCounter : 0), _ptr(ptr) { _cnt(ptr ? new PointerCounter : 0), _ptr(ptr) {
} }
template<class OTHER> SmartPointer(const SmartPointer<OTHER>& o): template<class OTHER> SmartPointer(const SmartPointer<OTHER>& o) throw():
_cnt(0), _ptr(dynamic_cast<TYPE*>(getPointer(o))) { _cnt(0), _ptr(dynamic_cast<TYPE*>(getPointer(o))) {
if (_ptr) _cnt = getCounter(o)->incr(); if (_ptr) _cnt = getCounter(o)->incr();
} }
~SmartPointer() { ~SmartPointer() throw() {
drop(); drop();
} }
SmartPointer& operator=(const SmartPointer<TYPE>& o) { SmartPointer& operator=(const SmartPointer<TYPE>& o) throw() {
if (o._ptr==_ptr) return *this; if (o._ptr==_ptr) return *this;
drop(); drop();
_cnt = o._cnt ? o._cnt->incr() : 0; _cnt = o._cnt ? o._cnt->incr() : 0;
_ptr = o._ptr; _ptr = o._ptr;
return *this; return *this;
} }
SmartPointer& operator=(TYPE* ptr) { SmartPointer& operator=(TYPE* ptr) throw() {
if (ptr==_ptr) return *this; if (ptr==_ptr) return *this;
drop(); drop();
_cnt = ptr ? new PointerCounter : 0; _cnt = ptr ? new PointerCounter : 0;
@@ -109,26 +134,26 @@ namespace mrw {
return *this; return *this;
} }
template<class OTHER> template<class OTHER>
SmartPointer& operator=(const SmartPointer<OTHER>& o) { SmartPointer& operator=(const SmartPointer<OTHER>& o) throw() {
if (getPointer(o)==_ptr) return *this; if (getPointer(o)==_ptr) return *this;
drop(); drop();
_ptr = dynamic_cast<TYPE*>(getPointer(o)); _ptr = dynamic_cast<TYPE*>(getPointer(o));
_cnt = _ptr ? getCounter(o)->incr() : 0; _cnt = _ptr ? getCounter(o)->incr() : 0;
return *this; return *this;
} }
TYPE& operator*() { TYPE& operator*() throw() {
return *_ptr; return *_ptr;
} }
const TYPE& operator*() const { const TYPE& operator*() const throw() {
return *_ptr; return *_ptr;
} }
TYPE* const operator->() { TYPE* const operator->() throw() {
return _ptr; return _ptr;
} }
const TYPE* const operator->() const { const TYPE* const operator->() const throw() {
return _ptr; return _ptr;
} }
operator bool() { operator bool() throw() {
return _ptr!=0; return _ptr!=0;
} }
}; };

View File

@@ -1,3 +1,28 @@
/** @file
$Id$
$Date$
$Author$
@copy &copy; Marc W&auml;ckerlin
@license LGPL, see file <a href="license.html">COPYING</a>
$Log$
Revision 1.3 2004/08/28 16:21:25 marc
mrw-c++-0.92 (mrw)
- new file: version.cpp
- new file header for all sources
- work around warning in mrw::auto<T>
- possibility to compile without log4cxx
- work around bugs in demangle.h and libiberty.h
- corrections in documentation
- added simple tracing mechanism
- more warnings
- small corrections in Auto<>::Free and a new test for it
- possibility to compile without stack trace
*/
#include <mrw/stacktrace.hpp> #include <mrw/stacktrace.hpp>
#include <sstream> #include <sstream>
#include <unistd.h> #include <unistd.h>
@@ -17,7 +42,33 @@
#endif #endif
#include <bfd.h> #include <bfd.h>
extern "C" { extern "C" {
#include <demangle.h>
/// @bug redefined in libiberty.h
# define HAVE_DECL_BASENAME 1
/// @bug redefined in libiberty.h
# define HAVE_DECL_ASPRINTF 1
/// @bug redefined in libiberty.h
# define HAVE_DECL_VASPRINTF 1
/** @bug
- in file file: /usr/include/demangle.h
- of package: binutils-2.15.90.0.1.1-31
An idiot unfortunately abused the C++ keyword @c typename as
variable name to @c cplus_demangle_fill_builtin_type, so I have
to work around it.
*/
# define typename anotherNameThatsNotAKeyword
# include <demangle.h>
# undef typename
// // copied from demangle.h because of compiler warnings in libliberty.h
// // (... throws different exception)
// #define DMGL_PARAMS (1 << 0) /* Include function args */
// #define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */
// /// @bug demangle.h includes libiberty.h which throws different
// /// exceptions for the same functions than other standard libraries,
// /// so I can't include demangle.h!
// extern char * cplus_demangle(const char *, int);
} }
#include <iomanip> #include <iomanip>
@@ -31,15 +82,15 @@ namespace mrw {
or the MS PE format. These formats have a number of leading '.'s or the MS PE format. These formats have a number of leading '.'s
on at least some symbols, so we remove all dots to avoid on at least some symbols, so we remove all dots to avoid
confusing the demangler. */ confusing the demangler. */
const char* p (name); const char* p(name);
while (p && *p == '.') ++p; while (p && *p == '.') ++p;
mrw::AutoFree<char> res(cplus_demangle(p, DMGL_ANSI | DMGL_PARAMS)); Auto<char*>::Free res(cplus_demangle(p, DMGL_ANSI | DMGL_PARAMS));
if (res) { if (res) {
/* Now put back any stripped dots. */ /* Now put back any stripped dots. */
if (p==name) return (char*)res; if (p==name) return static_cast<const char*>(res);
std::string add_dots('.', p-name); std::string add_dots('.', p-name);
return add_dots+=(char*)res; return add_dots+=static_cast<const char*>(res);
} }
return name; return name;
} }
@@ -118,7 +169,8 @@ namespace mrw {
static const char* file(0); static const char* file(0);
static const char* function(0); static const char* function(0);
unsigned int line; unsigned int line;
if (!bfd_find_nearest_line(_bfd, (*_dic)[*it].second, _syms.get(), if (!bfd_find_nearest_line(const_cast<bfd*>(static_cast<const bfd*>(_bfd)),
(*_dic)[*it].second, _syms.get(),
vma_addr-*it, &file, &function, &line)) vma_addr-*it, &file, &function, &line))
return CodePos(addr, "????", "????", 0); return CodePos(addr, "????", "????", 0);
return CodePos(addr, mrw::demangle(_bfd, function), file?file:"????", line); return CodePos(addr, mrw::demangle(_bfd, function), file?file:"????", line);
@@ -129,13 +181,18 @@ namespace mrw {
if (_dic.get()) return true; if (_dic.get()) return true;
AutoBfd abfd(bfd_openr((fname!="" ? fname : filename()).c_str(), 0)); AutoBfd abfd(bfd_openr((fname!="" ? fname : filename()).c_str(), 0));
long memsz(-1); long memsz(-1);
AutoFree<char*> m(0); Auto<char**>::Free m(0);
if (!abfd || bfd_check_format(abfd, bfd_archive) || if (!abfd || bfd_check_format(abfd, bfd_archive) ||
!bfd_check_format_matches(abfd, bfd_object, m) || !bfd_check_format_matches(abfd, bfd_object, &(m.getClean())) ||
!(bfd_get_file_flags(abfd)&HAS_SYMS) || !(bfd_get_file_flags(const_cast<bfd*>(static_cast<const bfd*>(abfd)))
(memsz=bfd_get_symtab_upper_bound(abfd))<0) return false; &HAS_SYMS) ||
(memsz=bfd_get_symtab_upper_bound
(const_cast<bfd*>(static_cast<const bfd*>(abfd))))<0)
return false;
std::auto_ptr<asymbol*> syms(new asymbol*[memsz]); std::auto_ptr<asymbol*> syms(new asymbol*[memsz]);
if (bfd_canonicalize_symtab(abfd, syms.get())<0) return false; if (bfd_canonicalize_symtab(const_cast<bfd*>(static_cast<const bfd*>(abfd)),
syms.get())<0)
return false;
_bfd = abfd; _bfd = abfd;
_syms = syms; _syms = syms;
_dic = std::auto_ptr<Translator>(new Translator()); _dic = std::auto_ptr<Translator>(new Translator());

View File

@@ -1,3 +1,28 @@
/** @file
$Id$
$Date$
$Author$
@copy &copy; Marc W&auml;ckerlin
@license LGPL, see file <a href="license.html">COPYING</a>
$Log$
Revision 1.4 2004/08/28 16:21:25 marc
mrw-c++-0.92 (mrw)
- new file: version.cpp
- new file header for all sources
- work around warning in mrw::auto<T>
- possibility to compile without log4cxx
- work around bugs in demangle.h and libiberty.h
- corrections in documentation
- added simple tracing mechanism
- more warnings
- small corrections in Auto<>::Free and a new test for it
- possibility to compile without stack trace
*/
// g++ -Wall -D__SOLARIS__ -g -I /home/public/freeware/include -L /home/public/freeware/lib -I . stacktrace.cxx -lbfd -liberty // g++ -Wall -D__SOLARIS__ -g -I /home/public/freeware/include -L /home/public/freeware/lib -I . stacktrace.cxx -lbfd -liberty
#ifndef __MRW_STACKTRACE_HPP__ #ifndef __MRW_STACKTRACE_HPP__
#define __MRW_STACKTRACE_HPP__ #define __MRW_STACKTRACE_HPP__
@@ -82,7 +107,7 @@ namespace mrw {
@note Symbol evaluation requires the ELF library and an ELF system. @note Symbol evaluation requires the ELF library and an ELF system.
@section sttech Technology <h3>Technology</h3>
On GNU glibc based systems (Linux), the stack trace is collected On GNU glibc based systems (Linux), the stack trace is collected
with GNU glibc's function @c backtrace(). On other systems with GNU glibc's function @c backtrace(). On other systems
@@ -103,7 +128,7 @@ namespace mrw {
executable file name as an argument to @c executable file name as an argument to @c
mrw::StackTrace::createSymtable(). mrw::StackTrace::createSymtable().
@section stdrawbacks Draw Backs <h3>Draw Backs</h3>
Unfortunately it is not possible to extract the source file name Unfortunately it is not possible to extract the source file name
and line number information if the executable was not compiled and line number information if the executable was not compiled
@@ -139,7 +164,7 @@ namespace mrw {
StackTrace() throw(std::bad_exception); StackTrace() throw(std::bad_exception);
/// 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 */
operator const AddressTrace&() const throw(std::bad_exception) { operator const AddressTrace&() const throw(std::bad_exception) {
return _trace; return _trace;
} }

View File

@@ -1,3 +1,28 @@
/** @file
$Id$
$Date$
$Author$
@copy &copy; Marc W&auml;ckerlin
@license LGPL, see file <a href="license.html">COPYING</a>
$Log$
Revision 1.4 2004/08/28 16:21:25 marc
mrw-c++-0.92 (mrw)
- new file: version.cpp
- new file header for all sources
- work around warning in mrw::auto<T>
- possibility to compile without log4cxx
- work around bugs in demangle.h and libiberty.h
- corrections in documentation
- added simple tracing mechanism
- more warnings
- small corrections in Auto<>::Free and a new test for it
- possibility to compile without stack trace
*/
#include <mrw/stacktrace.hpp> #include <mrw/stacktrace.hpp>
#include <cppunit/TestFixture.h> #include <cppunit/TestFixture.h>
#include <cppunit/ui/text/TestRunner.h> #include <cppunit/ui/text/TestRunner.h>

View File

@@ -1,18 +1,33 @@
/** @file /** @file
$Id$
$Date$
$Author$
@copy &copy; Marc W&auml;ckerlin
@license LGPL, see file <a href="license.html">COPYING</a>
$Log$ $Log$
Revision 1.5 2004/08/28 16:21:25 marc
mrw-c++-0.92 (mrw)
- new file: version.cpp
- new file header for all sources
- work around warning in mrw::auto<T>
- possibility to compile without log4cxx
- work around bugs in demangle.h and libiberty.h
- corrections in documentation
- added simple tracing mechanism
- more warnings
- small corrections in Auto<>::Free and a new test for it
- possibility to compile without stack trace
Revision 1.4 2004/08/25 08:35:09 marc Revision 1.4 2004/08/25 08:35:09 marc
change in file header change in file header
Revision 1.3 2004/08/25 08:22:19 marc Revision 1.3 2004/08/25 08:22:19 marc
added file header added file header
@copy &copy; Copyright Marc W&auml;ckerlin $Date$
@author Last Change: $Author$
@date Last Change: $Date$
@version $Id$
@licence see file COPYING or license.html
*/ */
#ifndef __MRW_UNISTD_HPP__ #ifndef __MRW_UNISTD_HPP__
#define __MRW_UNISTD_HPP__ #define __MRW_UNISTD_HPP__
@@ -36,7 +51,7 @@ namespace mrw {
int _lastError; int _lastError;
public: public:
/// creates a unix pipe /// creates a unix pipe
Pipe(): _lastError(-1) { Pipe() throw(std::bad_exception): _lastError(-1) {
_fd[0] = -1; _fd[0] = -1;
_fd[1] = -1; _fd[1] = -1;
if (::pipe(_fd)==-1) if (::pipe(_fd)==-1)
@@ -45,16 +60,16 @@ namespace mrw {
} }
} }
/// destructor closes pipe if still open /// destructor closes pipe if still open
~Pipe() { ~Pipe() throw(std::bad_exception) {
close(); close();
} }
/// closes pipe if open /// closes pipe if open
void close() { void close() throw(std::bad_exception) {
close_in(); close_in();
close_out(); close_out();
} }
/// closes input pipe if open /// closes input pipe if open
void close_in() { void close_in() throw(std::bad_exception) {
if (_fd[0]!=-1) while (::close(_fd[0])==-1) if (errno!=EINTR) { if (_fd[0]!=-1) while (::close(_fd[0])==-1) if (errno!=EINTR) {
_lastError = errno; _lastError = errno;
break; break;
@@ -62,30 +77,30 @@ namespace mrw {
_fd[0] = -1; _fd[0] = -1;
} }
/// closes output pipe if open /// closes output pipe if open
void close_out() { void close_out() throw(std::bad_exception) {
if (_fd[1]!=-1) while (::close(_fd[1])==-1) if (errno!=EINTR) { if (_fd[1]!=-1) while (::close(_fd[1])==-1) if (errno!=EINTR) {
_lastError = errno; _lastError = errno;
break; break;
} }
_fd[1] = -1; _fd[1] = -1;
} }
/// @return true if no error occured /** @return true if no error occured */
operator bool() { operator bool() throw() {
return _lastError == -1; return _lastError == -1;
} }
/// @return last error code, -1 if no error /** @return last error code, -1 if no error */
int error() { int error() throw() {
return _lastError; return _lastError;
} }
/// connect output stream to @c stdout /// connect output stream to @c stdout
void connect_cout() { void connect_cout() throw(std::bad_exception) {
while (::dup2(_fd[1], 1)==-1) if (errno!=EINTR) { while (::dup2(_fd[1], 1)==-1) if (errno!=EINTR) {
_lastError = errno; _lastError = errno;
return; return;
} }
} }
/// connect output stream to @c stderr /// connect output stream to @c stderr
void connect_cerr() { void connect_cerr() throw(std::bad_exception) {
while (::dup2(_fd[1], 2)==-1) if (errno!=EINTR) { while (::dup2(_fd[1], 2)==-1) if (errno!=EINTR) {
_lastError = errno; _lastError = errno;
return; return;
@@ -94,13 +109,13 @@ namespace mrw {
/// get an input stream /// get an input stream
/** @return stream to read from /** @return stream to read from
@note invalid after destruction or @c close or @c close_in */ @note invalid after destruction or @c close or @c close_in */
int istream() { int istream() throw(std::bad_exception) {
return _fd[0]; return _fd[0];
} }
/// get an output stream /// get an output stream
/** @return stream to write to /** @return stream to write to
@note invalid after destruction or @c close or @c close_out */ @note invalid after destruction or @c close or @c close_out */
int ostream() { int ostream() throw(std::bad_exception) {
return _fd[1]; return _fd[1];
} }
}; };