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
master
Marc Wäckerlin 21 years ago
parent 7a88e4bc43
commit 235a15020b
  1. 22
      ChangeLog
  2. 11
      NEWS
  3. 6
      README
  4. 4
      bootstrap.sh
  5. 62
      configure.in
  6. 43
      makefile.am
  7. 25
      mrw-c++-devel.spec.in
  8. 25
      mrw-c++.spec.in
  9. 231
      mrw/arg.hpp
  10. 266
      mrw/auto.hpp
  11. 44
      mrw/auto_test.cpp
  12. 52
      mrw/autostacktracelog4cxx.cpp
  13. 25
      mrw/autostacktracestderr.cpp
  14. 15
      mrw/doxyfile.in
  15. 37
      mrw/exception.cpp
  16. 43
      mrw/exception.hpp
  17. 42
      mrw/exec.cpp
  18. 45
      mrw/exec.hpp
  19. 25
      mrw/exec_test.cpp
  20. 1186
      mrw/libmrw.doxytag
  21. 108
      mrw/makefile.am
  22. 8
      mrw/mrw.hpp.in
  23. 25
      mrw/mrwexclog4cxx_test.cpp
  24. 25
      mrw/mrwexcstderr_test.cpp
  25. 164
      mrw/simpletrace.hpp
  26. 65
      mrw/smartpointer.hpp
  27. 79
      mrw/stacktrace.cpp
  28. 31
      mrw/stacktrace.hpp
  29. 25
      mrw/stacktrace_test.cpp
  30. 53
      mrw/unistd.hpp

@ -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)
- mrw/arg.hpp: Command line argument evaluation
- mrw/smartpointer.hpp: Smart pointer implementation

11
NEWS

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

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

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

@ -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
AC_INIT([mrw/mrw.hpp.in])
PACKAGENAME=mrw-c++
MAJOR=0
MINOR=91
SUPPORT=beta
MINOR=92
SUPPORT=
AM_INIT_AUTOMAKE(@PACKAGENAME@, @MAJOR@.@MINOR@, [marc@waeckerlin.org])
# macros
@ -29,10 +54,12 @@ AC_CHECK_PROG(have_dot, dot, yes, no)
AC_CHECK_HEADER(sys/old_procfs.h, [AM_CPPFLAGS=-D__solaris__])
# libraries
AC_CHECK_HEADER(log4cxx/logger.h, [have_log4cxx=yes])
AC_SEARCH_LIBS(cplus_demangle, iberty, [AC_MSG_RESULT([OK])],
[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_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]))
# Arguments
@ -40,12 +67,24 @@ AM_MAINTAINER_MODE
AC_ARG_ENABLE(pedantic,
[ --enable-pedantic enable all warnings and checks, abort on warnings],
[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"])
dnl lib: -Wshadow -Wcast-qual
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 problem in libs: -Wshadow -Wcast-qual
dnl auto.hpp: -Wno-ctor-dtor-privacy (removed)
AC_ARG_ENABLE(dot,
[ --disable-dot disable dot graphic tools for documentation],
[ --disable-dot disable dot graphic tools for documentation],
[have_dot="$enableval"])
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
AC_SUBST(HAVE_DOT)
@ -58,7 +97,7 @@ AC_SUBST(AM_CPPFLAGS)
# create output
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
# infos and warnings
@ -70,6 +109,9 @@ if test "$have_dot" = "no"; then
AC_MSG_WARN([Missing program dot!
- when you rebild documentation with make doc, there are no generated images
- there are precompiled derieved files in the distribution]); fi
AC_MSG_WARN([************** THE FLAGS = ${AM_CXXFLAGS}]);
if test "$have_log4cxx" != "yes"; then
AC_MSG_WARN([Library log4cxx will not be used!
- 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

@ -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
EXTRA_DIST = bootstrap.sh
nobase_include_HEADERS = mrw/auto.hpp mrw/unistd.hpp \
mrw/stacktrace.hpp mrw/exception.hpp \
mrw/exec.hpp
mrw/exec.hpp mrw/arg.hpp mrw/smartpointer.hpp
infosdir = ${pkgdatadir}
infos_DATA = AUTHORS NEWS README COPYING INSTALL ChangeLog \
@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 \
/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
cp @PACKAGENAME@-@MAJOR@.@MINOR@.tar.gz /usr/src/packages/SOURCES/
rpmbuild -bb --clean @PACKAGENAME@.spec
rpmbuild -bb --clean @PACKAGENAME@-devel.spec
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/* \
mrw/doc/latex/@PACKAGENAME@-@MAJOR@.@MINOR@.pdf \
@PACKAGENAME@-@MAJOR@.@MINOR@.tar.gz \
${RPMS} \
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

@ -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
Summary: MRW's C++ Class Library, facilities for ease and quality
Name: @PACKAGENAME@-devel

@ -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
Summary: MRW's C++ Class Library, facilities for ease and quality
Name: @PACKAGENAME@

@ -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/smartpointer.hpp>
#include <mrw/simpletrace.hpp>
#include <stdlib.h> // exit
#include <string>
#include <vector>
@ -125,7 +148,7 @@ namespace mrw {
bool theBoolean = args[3]->toBool();
@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
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
@return the string, if the instance is a string
*/
virtual const std::string& toString() const throw(mrw::exception) {
throw mrw::bad_cast();
}
virtual const std::string& toString() const throw(std::exception);
/** @brief If the instance is an @c int, return that integer,
otherwise throw an exception.
@throw mrw::bad_cast if the instance is not a integer
@return the integer, if the instance is a integer
*/
virtual int toInt() const throw(mrw::exception) {
throw mrw::bad_cast();
}
virtual int toInt() const throw(std::exception);
/** @brief If the instance is an @c bool, return that boolean,
otherwise throw an exception.
@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
@return the boolean, if the instance is a boolean
*/
virtual bool toBool() const throw(mrw::exception) {
throw mrw::bad_cast();
}
virtual bool toBool() const throw(std::exception);
/// @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
virtual const std::string& typestr() const throw(mrw::bad_exception)=0;
virtual const std::string& typestr() const throw(std::bad_exception)=0;
protected:
friend class Args; // allow assign for Param
virtual void operator=(const std::string&) throw(mrw::exception) = 0;
/// Allow assign for Args, make it a friend.
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:
@ -223,20 +242,20 @@ namespace mrw {
class StringValue: public Value {
public:
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;
}
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");
return name;
}
virtual std::string printable() const throw(mrw::bad_exception) {
virtual std::string printable() const throw(std::bad_exception) {
return _s;
}
protected:
virtual void operator=(const std::string& s) throw(mrw::exception) {
virtual void operator=(const std::string& s) throw(std::exception) {
_s = s;
}
private:
@ -246,22 +265,20 @@ namespace mrw {
class IntValue: public Value {
public:
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;
}
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");
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();
}
protected:
virtual void operator=(const std::string& s) throw(mrw::exception) {
if (!(std::stringstream(s)>>_i)) throw mrw::bad_cast();
}
virtual void operator=(const std::string& s) throw(std::exception);
private:
int _i;
};
@ -269,20 +286,20 @@ namespace mrw {
class BoolValue: public Value {
public:
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;
}
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\")");
return name;
}
virtual std::string printable() const throw(mrw::bad_exception) {
virtual std::string printable() const throw(std::bad_exception) {
return _b?"yes":"no";
}
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";
}
private:
@ -300,25 +317,25 @@ namespace mrw {
}
/// @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));
return *this;
}
/// @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));
return *this;
}
/// @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));
return *this;
}
// @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));
return *this;
}
@ -326,26 +343,15 @@ namespace mrw {
/** @brief get parameter number @i
@throw mrw::out_of_range if @c i is too big */
const mrw::SmartPointer<Value>& operator[](unsigned int i) const
throw(mrw::exception) {
if (i<_params.size()) return _params[i];
throw mrw::out_of_range
(((std::stringstream&)
(std::stringstream()<<"check failed: "
<<i<<'<'<<_params.size())).str());
}
throw(std::exception);
private:
/// Allow set for Args, make it a friend.
friend class Args; // allow set
mrw::SmartPointer<Value>& setable(unsigned int i)
throw(mrw::exception) {
if (i<_params.size()) return _params[i];
throw mrw::out_of_range
(((std::stringstream&)
(std::stringstream()<<"check failed: "
<<i<<'<'<<_params.size())).str());
}
/// Get a parameter with acces right for setting.
/// This is allowed for the class itself and friends (Args) only.
mrw::SmartPointer<Value>& setable(unsigned int i) throw(std::exception);
};
/** @brief this class represents one command line option
@ -369,13 +375,13 @@ namespace mrw {
@param shortname short name of the option
@param longname long name of the option, must start with "--"
@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,
const Param& param, const std::string& help)
throw(mrw::bad_exception):
Opt(const char shortname, const std::string& longname,
const Param& param, const std::string& helptext)
throw(std::bad_exception):
_set(false), _shortname(shortname), _longname(longname),
_param(param), _help(help) {
_param(param), _help(helptext) {
}
/** @brief create a simple @c mrw::Opt
@ -385,17 +391,16 @@ namespace mrw {
@param shortname short name of the option
@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,
const std::string& help)
throw(mrw::bad_exception):
Opt(const char shortname, const std::string& longname,
const std::string& helptext) throw(std::bad_exception):
_set(false), _shortname(shortname), _longname(longname),
_help(help) {
_help(helptext) {
}
/** @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;
}
@ -423,17 +428,19 @@ namespace mrw {
@return a smart pointer to the value (default or given by the user)
*/
const mrw::SmartPointer<Param::Value>& operator[](unsigned int i) const
throw(mrw::exception) {
throw(std::exception) {
return _param[i];
}
private:
friend class Args; // is allowed to set values
void set() const throw(mrw::bad_exception) {
/// Allow set values, make Args a friend.
friend class Args;
/// Set @c _set to true, available only for friends (Args).
void set() const throw(std::bad_exception) {
_set = true;
}
Param& args() const throw(mrw::bad_exception) {
Param& args() const throw(std::bad_exception) {
return _param;
}
mutable bool _set;
@ -469,7 +476,7 @@ namespace mrw {
typedef std::list<std::string> OtherArgs;
/// @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;
return _instance;
}
@ -485,15 +492,7 @@ namespace mrw {
<<mrw::Opt('v', "--verbose", "print more information");
@endcode
*/
Args& operator<<(const mrw::Opt& opt) throw(mrw::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;
}
Args& operator<<(const mrw::Opt& opt) throw(std::invalid_argument);
/** @brief setup the number of arguments
@ -509,7 +508,7 @@ namespace mrw {
}
@endcode
*/
Args& operator<<(int argc) throw(mrw::bad_exception) {
Args& operator<<(int argc) throw(std::bad_exception) {
_argc = argc;
return *this;
}
@ -528,11 +527,7 @@ namespace mrw {
}
@endcode
*/
Args& operator<<(const char *const*const argv) throw(mrw::exception) {
if (_argc<0)
throw mrw::invalid_argument("argc was not set when shifting argv");
return parse(_argc, argv);
}
Args& operator<<(const char *const*const argv) throw(std::exception);
/** @brief add a description text
@ -547,7 +542,7 @@ namespace mrw {
mrw::Args::instance()<<"this is a description for --help";
@endcode
*/
Args& operator<<(const std::string& description) throw(mrw::exception) {
Args& operator<<(const std::string& description) throw(std::exception) {
if (_description=="")
_description = description;
else
@ -569,29 +564,21 @@ namespace mrw {
mrw::Args::instance()<<'h';
@endcode
*/
Args& operator<<(char help) throw(mrw::exception) {
_help = help;
Args& operator<<(char helpopt) throw(std::exception) {
_help = helpopt;
return *this;
}
/** @brief get an option, given the short option name
@throw mrw::out_of_range if the option does not exist
*/
const Opt& find(char c) const throw(mrw::exception) {
ShortOpts::const_iterator it(_shortopts.find(c));
if (it==_shortopts.end()) throw mrw::out_of_range(std::string(1, c));
return *it->second;
}
const Opt& find(char c) const throw(std::exception);
/** @brief get an option, given the long option name
@throw mrw::out_of_range if the option does not exist
*/
const Opt& find(const std::string& s) const throw(mrw::exception) {
LongOpts::const_iterator it(_longopts.find(s));
if (it==_longopts.end()) throw mrw::out_of_range(s);
return *it->second;
}
const Opt& find(const std::string& s) const throw(std::exception);
/** @brief get all non interpreted options
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] */
const std::string& filename() throw(mrw::bad_exception) {
const std::string& filename() throw(std::bad_exception) {
return _filename;
}
@ -630,48 +617,12 @@ namespace mrw {
}
private:
Args& parse(int argc, const char*const*const argv) throw(mrw::exception) {
if (argc>0) _filename = argv[0];
for (int i(1); i<argc; ++i) {
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;
}
Args(): _argc(-1), _help(0) {} // singleton
Args& operator=(const Args&); // singleton, not implemented
Args& parse(int argc, const char*const*const argv) throw(std::exception);
typedef std::list<Opt> Options;
typedef std::map<char, Options::iterator> ShortOpts;
typedef std::map<std::string, Options::iterator> LongOpts;
Args(): _argc(-1), _help(0) {} // singleton
Args& operator=(const Args&); // singleton, not implemented
std::string _filename;
Options _options;
ShortOpts _shortopts;

@ -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__
#define __MRW_AUTO_HPP__
#include <sys/types.h> // size_t
#include <sys/mman.h> // PROT_READ, MAP_SHARED
#include <bfd.h> // bfd*
#include <sys/mman.h> // munmap, PROT_READ, MAP_SHARED
#include <stdexcept>
// forward
class bfd;
extern "C" int bfd_close(bfd*);
namespace mrw {
@ -18,126 +47,183 @@ namespace mrw {
*/
//@{
/** @brief Automatically closes a file when destructed.
/** @brief Automatically frees a resource when destructed.
@pre #include <mrw/auto.hpp>
AutoFile works exactly like std::auto_ptr, but not for files
instead of pointers. Whenever the context of AutoFile is left,
the opened file is close. This way, resources are freed even in
case of exceptions.
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
*/
class AutoFile {
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 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() {
/// @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 file descriptor @return file descriptor
operator const int() const throw() {
return _fd;
/// @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 Give away ownership of the file. @return old file descriptor
int release() throw() {
int ret(_fd); _fd=-1;
return ret;
/// @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;
}
/// @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
RESOURCE_TYPE _res; ///< the resource to be managed
};
/** @brief Automatically call @c munmap for mmaped files on destruction.
/** @brief Automatically closes a file when destructed.
@pre #include <mrw/auto.hpp>
AutoFile works exactly like std::auto_ptr, but for files
instead of pointers. Whenever the context of AutoFile is left,
the opened file is close. This way, resources are freed even in
case of exceptions.
*/
typedef mrw::AutoResource<int, int(*)(int), &close, int, -1> AutoFile;
/** @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>
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
called.
*/
class AutoMapper {
public:
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;
};
typedef mrw::AutoResource<MMapHandle, void(*)(MMapHandle&), &mrw::munmap, int>
AutoMapper;
/** @brief Automatically call @c bfd_close for @c bfd*.
/** @brief Automatically calls @c bfd_close for @c bfd*.
@pre #include <mrw/auto.hpp>
It acts like a @c std::auto_ptr, but for @c bfd*, that means it
calls @c bfd_close whenever the context is left.
*/
class 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;
};
typedef mrw::AutoResource<bfd*, int(*)(bfd*), &bfd_close, int> AutoBfd;
/** @brief Automatically calls @c free for @c malloc allocated memory.
Instanciate it as @c mrw::Auto<TYPE*>::Free.
@pre #include <mrw/auto.hpp>
It works like a @c std::auto_ptr, but for memory that was
allocated with @c malloc, not @c new. Memory is freed, whenever
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 {
public:
AutoFree(T* p=0) throw(): _p(p) {}
AutoFree(AutoFree& o) throw(): _p(o.release()) {}
~AutoFree() throw() {if (_p) free(_p);}
AutoFree& operator=(T* p) throw() {
release(); _p=p; return *this;
}
AutoFree& operator=(AutoFree& o) throw() {
release(); _p=o.release(); return *this;
}
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;
template<class T> class Auto {
public:
typedef mrw::AutoResource<T, void(*)(void*), &free, int, 0, void*> Free;
private:
/** @internal
work around compiler warning:
"only defines private constructors and has no friends" */
friend class ThisIsADummyToEliminateWarnings;
/// Forbidden to instanciate.
Auto(); Auto(const Auto&);
};
//@}
}
#endif

@ -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 <cppunit/TestFixture.h>
#include <cppunit/ui/text/TestRunner.h>
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <fcntl.h> // open
#include <string.h> // strncpy
class AutoTest: public CppUnit::TestFixture {
public:
@ -18,10 +44,10 @@ public:
mrw::AutoFile b(a);
CPPUNIT_ASSERT(a==-1 && i==b); // b has taken ownership
CPPUNIT_ASSERT(read(b, &c, 1)==1 && c=='H'); // file is good
mrw::AutoFile c(i);
CPPUNIT_ASSERT(i==b && b==c); // ooops, two owner!
c.release();
CPPUNIT_ASSERT(i==b && c==-1); // it's ok now
mrw::AutoFile cc(i);
CPPUNIT_ASSERT(i==b && b==cc); // ooops, two owner!
cc.release();
CPPUNIT_ASSERT(i==b && cc==-1); // it's ok now
b = open("test.dat", O_RDONLY);
//close(i);
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
}
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(AutoFile);
CPPUNIT_TEST(AutoFree);
CPPUNIT_TEST_SUITE_END();
};
CPPUNIT_TEST_SUITE_REGISTRATION(AutoTest);

@ -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/exception.hpp>
#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
The unexpected handler is installed automatically when you link
@ -38,19 +60,21 @@ namespace mrw {
@code
void unexpected_log4cxx() {
log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger(_T("libmrw"));
logger->fatal("Unexpected Exception", __FILE__, __LINE__);
StackTrace::createSymtable();
std::string st((std::string)StackTrace());
try {
throw;
} catch (const mrw::exception& x) {
StackTrace::createSymtable();
logger->fatal(std::string("Reason:\n")+x.what()
+"\nStack:+\n"+x.stacktrace());
+"\nStack:+\n"+x.stacktrace());
} catch (const std::exception& x) {
logger->fatal(std::string("Reason:\n")+x.what()
+"\nStack: **** not available ****");
+"\nStack:\n"+st);
} catch (...) {
logger->fatal(std::string("Reason: **** not available ****\n")
+"\nStack: **** not available ****");
logger->fatal(std::string("Reason: **** not available ****")
+"\nStack:\n"+st);
}
throw std::bad_exception();
}
@ -58,19 +82,21 @@ namespace mrw {
*/
void unexpected_log4cxx() {
log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger(_T("libmrw"));
logger->fatal("Unexpected Exception", __FILE__, __LINE__);
StackTrace::createSymtable();
std::string st((std::string)StackTrace());
try {
throw;
} catch (const mrw::exception& x) {
StackTrace::createSymtable();
logger->fatal(std::string("Reason:\n")+x.what()
+"\nStack:+\n"+x.stacktrace());
+"\nStack:+\n"+x.stacktrace());
} catch (const std::exception& x) {
logger->fatal(std::string("Reason:\n")+x.what()
+"\nStack: **** not available ****");
+"\nStack:\n"+st);
} catch (...) {
logger->fatal(std::string("Reason: **** not available ****\n")
+"\nStack: **** not available ****");
logger->fatal(std::string("Reason: **** not available ****")
+"\nStack:\n"+st);
}
throw std::bad_exception();
}

@ -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/exception.hpp>
#include <exception>

@ -9,6 +9,19 @@
## @license LGPL, see file <a href="license.html">COPYING</a>
##
## $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
## new file header
##
@ -879,7 +892,7 @@ INCLUDE_FILE_PATTERNS =
# or name=definition (no spaces). If the definition and the = are
# omitted =1 is assumed.
PREDEFINED =
PREDEFINED = HAVE_STACKTRACE
# 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.

@ -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/stacktrace.hpp>
#ifdef HAVE_STACKTRACE
# include <mrw/stacktrace.hpp>
#else
namespace mrw {
class StackTrace {
public:
operator std::string() throw() {return "";}
};
}
#endif
namespace mrw {
exception::exception() throw(std::bad_exception):

@ -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__
#define __MRW_EXCEPTION_HPP__
@ -51,10 +76,20 @@ namespace mrw {
@subsection excsug Suggested Exception Handling Rules
-# derieve all your exceptions from mrw::exception
-# write exception specifications as follows:
- if any exception is thrown, specify @c throw(mrw::exception)
-# write exception specifications as follows: @n
(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)
-# 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
(or link to a @ref AutoTrace "library"):
@ -164,7 +199,7 @@ call of fn0 successful
...
}
@endcode
*/
*/
class exception: public std::exception {
public:
exception() throw(std::bad_exception);

@ -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/unistd.hpp>
#include <mrw/exception.hpp>
#include <sys/wait.h> // waitpid
#include <unistd.h> // fork, exec
#include <string.h> // memcpy
@ -47,7 +73,7 @@ mrw::Cmd::operator mrw::Exec() const throw(std::bad_exception) {
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);
}
@ -83,13 +109,13 @@ mrw::Exec& mrw::Exec::operator=(const mrw::Exec& e) throw(std::bad_exception) {
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
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;
_res = _err = "";
mrw::pipe stdOut, stdErr;
mrw::Pipe stdOut, stdErr;
if (!stdOut || !stdErr)
throw mrw::ExecutionFailedExc("cannot create pipe", *_cmd);
pid_t pid(fork());
@ -131,13 +157,13 @@ mrw::Exec& mrw::Exec::execute(bool throwExc) throw(mrw::exception) {
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();
res += _res;
return *this;
}
mrw::Exec::operator std::string&() throw(mrw::exception) {
mrw::Exec::operator std::string&() throw(std::exception) {
if (!_success) execute();
return _res;
}
@ -146,12 +172,12 @@ mrw::Exec::operator bool() throw(std::bad_exception) {
return _success;
}
std::string& mrw::Exec::result() throw(mrw::exception) {
std::string& mrw::Exec::result() throw(std::exception) {
if (!_success) execute();
return _res;
}
std::string& mrw::Exec::error() throw(mrw::exception) {
std::string& mrw::Exec::error() throw(std::exception) {
if (!_success) execute();
return _err;
}

@ -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__
#define __MRW_EXEC_HPP__
@ -116,7 +141,7 @@ namespace mrw {
- if given parameter is @c true (the default) also if the
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
@ -127,7 +152,7 @@ namespace mrw {
@throw ExecutionFailedExc in case of any failure or if the
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
@ -140,7 +165,7 @@ namespace mrw {
@throw ExecutionFailedExc in case of any failure or if the
executed program does not return a zero exit status.
*/
operator std::string&() throw(mrw::exception);
operator std::string&() throw(std::exception);
/** @return
- @c true if the last execution was successful
@ -160,7 +185,7 @@ namespace mrw {
@throw ExecutionFailedExc in case of any failure or if the
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
@ -173,7 +198,7 @@ namespace mrw {
@throw ExecutionFailedExc in case of any failure or if the
executed program does not return a zero exit status.
*/
std::string& error() throw(mrw::exception);
std::string& error() throw(std::exception);
/** @return
- @c true if the last execution was successful
@ -231,7 +256,7 @@ namespace mrw {
operator std::string() const throw(std::bad_exception);
/** @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
@ -254,11 +279,13 @@ namespace mrw {
- if given parameter is @c true (the default) also if the
executed program terminates with an error
*/
Exec execute(bool=true) const throw(mrw::exception);
Exec execute(bool=true) const throw(std::exception);
private:
friend class Exec; // is allowed to call path() and args()
Cmd(); // no default constructor
/// Exec is allowed to call @c path() and @c args().
friend class Exec;
/// No default constructor.
Cmd();
const char* path() const throw(std::bad_exception);
char** args() const throw(std::bad_exception);
typedef std::list<std::string> ArgList;

@ -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/stacktrace.hpp>
#include <cppunit/TestFixture.h>

@ -1,9 +1,161 @@
<?xml version='1.0' encoding='ISO-8859-1' standalone='yes'?>
<tagfile>
<compound kind="page">
<filename>index</filename>
<title></title>
<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 kind="page">
<name>license</name>
@ -34,20 +186,43 @@
<name>arguments</name>
<title>C++ Evaluation of Command Line Arguments</title>
<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::Opt</class>
<class kind="class">mrw::Args</class>
</compound>
<compound kind="group">
<name>AutoTools</name>
<title>Classes for Automated Resource Handling</title>
<filename>group__AutoTools.html</filename>
<class kind="class">mrw::AutoBfd</class>
<class kind="class">mrw::AutoFile</class>
<class kind="class">mrw::AutoFree</class>
<class kind="class">mrw::AutoMapper</class>
<class kind="class">mrw::pipe</class>
<class kind="class">mrw::AutoResource</class>
<class kind="class">mrw::MMapHandle</class>
<class kind="class">mrw::Auto</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 kind="group">
<name>AutoTrace</name>
@ -56,50 +231,257 @@
<member kind="function">
<type>void</type>
<name>unexpected_log4cxx</name>
<anchor>a1</anchor>
<anchor>ga0</anchor>
<arglist>()</arglist>
</member>
<member kind="function">
<type>void</type>
<name>unexpected_stderr</name>
<anchor>a2</anchor>
<anchor>ga1</anchor>
<arglist>()</arglist>
</member>
<docanchor>trcstderr</docanchor>
<docanchor>trclog4cxx</docanchor>
</compound>
<compound kind="group">
<name>CmdExec</name>
<title>Execute UNIX Commands</title>
<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::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 kind="group">
<name>StackTrace</name>
<title>Collect and Format a Stack Trace</title>
<filename>group__StackTrace.html</filename>
<subgroup>AutoTrace</subgroup>
<class kind="class">mrw::exception</class>
<class kind="class">mrw::bad_alloc</class>
<class kind="class">mrw::bad_cast</class>
<class kind="class">mrw::bad_exception</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::exception</class>
<class kind="class">mrw::invalid_argument</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::runtime_error</class>
<class kind="class">mrw::overflow_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::StackTrace</class>
<member kind="function">
<type>std::ostream &amp;</type>
<name>operator&lt;&lt;</name>
<anchor>a0</anchor>
<anchor>ga0</anchor>
<arglist>(std::ostream &amp;os, const StackTrace &amp;st)</arglist>
</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 kind="class">
<name>mrw::Args</name>
@ -138,19 +520,19 @@
<type>Args &amp;</type>
<name>operator&lt;&lt;</name>
<anchor>a4</anchor>
<arglist>(char help)</arglist>
<arglist>(char helpopt)</arglist>
</member>
<member kind="function">
<type>const Opt &amp;</type>
<name>find</name>
<anchor>a5</anchor>
<arglist>(char c) const</arglist>
<arglist>(char c) const </arglist>
</member>
<member kind="function">
<type>const Opt &amp;</type>
<name>find</name>
<anchor>a6</anchor>
<arglist>(const std::string &amp;s) const</arglist>
<arglist>(const std::string &amp;s) const </arglist>
</member>
<member kind="function">
<type>const OtherArgs &amp;</type>
@ -178,188 +560,134 @@
</member>
</compound>
<compound kind="class">
<name>mrw::AutoBfd</name>
<filename>classmrw_1_1AutoBfd.html</filename>
<name>mrw::AutoResource</name>
<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">
<type></type>
<name>AutoBfd</name>
<name>AutoResource</name>
<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>
<type></type>
<name>AutoResource</name>
<anchor>a1</anchor>
<arglist>(AutoResource &amp;o)</arglist>
</member>
<member kind="function">
<type></type>
<name>~AutoResource</name>
<anchor>a2</anchor>
<arglist>(bfd *p)</arglist>
<arglist>()</arglist>
</member>
<member kind="function">
<type>AutoBfd &amp;</type>
<type>AutoResource &amp;</type>
<name>operator=</name>
<anchor>a3</anchor>
<arglist>(AutoBfd &amp;o)</arglist>
<arglist>(RESOURCE_TYPE res)</arglist>
</member>
<member kind="function">
<type></type>
<name>operator bfd *</name>
<type>AutoResource &amp;</type>
<name>operator=</name>
<anchor>a4</anchor>
<arglist>()</arglist>
<arglist>(AutoResource &amp;other)</arglist>
</member>
<member kind="function">
<type>bfd *</type>
<name>operator-&gt;</name>
<type></type>
<name>operator const RESOURCE_TYPE &amp;</name>
<anchor>a5</anchor>
<arglist>() const </arglist>
</member>
<member kind="function">
<type>RESOURCE_TYPE &amp;</type>
<name>getClean</name>
<anchor>a6</anchor>
<arglist>()</arglist>
</member>
<member kind="function">
<type>bfd *</type>
<type></type>
<name>operator bool</name>
<anchor>a7</anchor>
<arglist>() const </arglist>
</member>
<member kind="function">
<type>RESOURCE_TYPE</type>
<name>release</name>
<anchor>a6</anchor>
<anchor>a8</anchor>
<arglist>()</arglist>
</member>
<member kind="function">
<type>AutoResource &amp;</type>
<name>reset</name>
<anchor>a9</anchor>
<arglist>(RESOURCE_TYPE res=INITIAL_VALUE)</arglist>
</member>
</compound>
<compound kind="class">
<name>mrw::AutoFile</name>
<filename>classmrw_1_1AutoFile.html</filename>
<name>mrw::MMapHandle</name>
<filename>classmrw_1_1MMapHandle.html</filename>
<member kind="function">
<type></type>
<name>AutoFile</name>
<name>MMapHandle</name>
<anchor>a0</anchor>
<arglist>(int fd=-1)</arglist>
<arglist>(int, size_t=0, void *=0, int=PROT_READ, int=MAP_SHARED, off_t=0)</arglist>
</member>
<member kind="function">
<type></type>
<name>AutoFile</name>
<type>MMapHandle &amp;</type>
<name>operator=</name>
<anchor>a1</anchor>
<arglist>(AutoFile &amp;o)</arglist>
<arglist>(int)</arglist>
</member>
<member kind="function">
<type></type>
<name>~AutoFile</name>
<type>bool</type>
<name>operator==</name>
<anchor>a2</anchor>
<arglist>()</arglist>
<arglist>(int i) const </arglist>
</member>
<member kind="function">
<type>AutoFile &amp;</type>
<name>operator=</name>
<anchor>a3</anchor>
<arglist>(int fd)</arglist>
</member>
<member kind="function">
<type>AutoFile &amp;</type>
<name>operator=</name>
<anchor>a4</anchor>
<arglist>(AutoFile &amp;other)</arglist>
</member>
<member kind="function">
<type></type>
<name>operator const int</name>
<anchor>a5</anchor>
<arglist>() const</arglist>
</member>
<member kind="function">
<type>int</type>
<name>release</name>
<anchor>a6</anchor>
<arglist>()</arglist>
<member kind="variable">
<type>void *</type>
<name>first</name>
<anchor>o0</anchor>
<arglist></arglist>
</member>
<member kind="function">
<type>AutoFile &amp;</type>
<name>reset</name>
<anchor>a7</anchor>
<arglist>(int=-1)</arglist>
<member kind="variable">
<type>size_t</type>
<name>second</name>
<anchor>o1</anchor>
<arglist></arglist>
</member>
</compound>
<compound kind="class">
<name>mrw::AutoFree</name>
<filename>classmrw_1_1AutoFree.html</filename>
<name>mrw::Auto</name>
<filename>classmrw_1_1Auto.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>
<arglist>()</arglist>
</member>
<member kind="function">
<type></type>
<name>operator bool</name>
<anchor>a7</anchor>
<arglist>()</arglist>
</member>
<member kind="function">
<type>T *</type>
<name>release</name>
<anchor>a8</anchor>
<arglist>()</arglist>
<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::AutoMapper</name>
<filename>classmrw_1_1AutoMapper.html</filename>
<member kind="function">
<type></type>
<name>AutoMapper</name>
<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>
<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 kind="function">
<type></type>
<name>operator const void *</name>
<type>const std::string &amp;</type>
<name>stacktrace</name>
<anchor>a3</anchor>
<arglist>() const</arglist>
</member>
<member kind="function">
<type>AutoMapper &amp;</type>
<name>set</name>
<anchor>a4</anchor>
<arglist>(void *cont, size_t sz)</arglist>
</member>
<member kind="function">
<type>void *</type>
<name>release</name>
<anchor>a5</anchor>
<arglist>()</arglist>
</member>
<member kind="function">
<type>const void *</type>
<name>last</name>
<anchor>a6</anchor>
<arglist>() const</arglist>
<arglist>() const </arglist>
</member>
</compound>
<compound kind="class">
@ -370,7 +698,7 @@
<type>virtual const char *</type>
<name>what</name>
<anchor>a0</anchor>
<arglist>() const</arglist>
<arglist>() const </arglist>
</member>
</compound>
<compound kind="class">
@ -381,7 +709,7 @@
<type>virtual const char *</type>
<name>what</name>
<anchor>a0</anchor>
<arglist>() const</arglist>
<arglist>() const </arglist>
</member>
</compound>
<compound kind="class">
@ -392,7 +720,7 @@
<type>virtual const char *</type>
<name>what</name>
<anchor>a0</anchor>
<arglist>() const</arglist>
<arglist>() const </arglist>
</member>
</compound>
<compound kind="class">
@ -403,47 +731,24 @@
<type>virtual const char *</type>
<name>what</name>
<anchor>a0</anchor>
<arglist>() const</arglist>
<arglist>() const </arglist>
</member>
</compound>
<compound kind="class">
<name>mrw::Cmd</name>
<filename>classmrw_1_1Cmd.html</filename>
<name>mrw::logic_error</name>
<filename>classmrw_1_1logic__error.html</filename>
<base virtualness="virtual">mrw::exception</base>
<member kind="function">
<type></type>
<name>Cmd</name>
<name>logic_error</name>
<anchor>a0</anchor>
<arglist>(const std::string &amp;)</arglist>
<arglist>(const std::string &amp;arg)</arglist>
</member>
<member kind="function">
<type>Cmd &amp;</type>
<name>operator,</name>
<member kind="function" virtualness="virtual">
<type>virtual const char *</type>
<name>what</name>
<anchor>a1</anchor>
<arglist>(const std::string &amp;)</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>
<arglist>() const </arglist>
</member>
</compound>
<compound kind="class">
@ -460,104 +765,7 @@
<type>virtual const char *</type>
<name>what</name>
<anchor>a1</anchor>
<arglist>() const</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 kind="function">
<type>const std::string &amp;</type>
<name>stacktrace</name>
<anchor>a3</anchor>
<arglist>() const</arglist>
</member>
</compound>
<compound kind="class">
<name>mrw::Exec</name>
<filename>classmrw_1_1Exec.html</filename>
<member kind="function">
<type></type>
<name>Exec</name>
<anchor>a0</anchor>
<arglist>(const mrw::Cmd &amp;)</arglist>
</member>
<member kind="function">
<type></type>
<name>Exec</name>
<anchor>a1</anchor>
<arglist>(const mrw::Exec &amp;)</arglist>
</member>
<member kind="function">
<type>Exec &amp;</type>
<name>operator=</name>
<anchor>a3</anchor>
<arglist>(const mrw::Exec &amp;)</arglist>
</member>
<member kind="function">
<type>Exec &amp;</type>
<name>execute</name>
<anchor>a4</anchor>
<arglist>(bool=true)</arglist>
</member>
<member kind="function">
<type>Exec &amp;</type>
<name>operator&gt;&gt;</name>
<anchor>a5</anchor>
<arglist>(std::string &amp;)</arglist>
</member>
<member kind="function">
<type></type>
<name>operator std::string &amp;</name>
<anchor>a6</anchor>
<arglist>()</arglist>
</member>
<member kind="function">
<type></type>
<name>operator bool</name>
<anchor>a7</anchor>
<arglist>()</arglist>
</member>
<member kind="function">
<type>std::string &amp;</type>
<name>result</name>
<anchor>a8</anchor>
<arglist>()</arglist>
</member>
<member kind="function">
<type>std::string &amp;</type>
<name>error</name>
<anchor>a9</anchor>
<arglist>()</arglist>
</member>
<member kind="function">
<type>bool</type>
<name>success</name>
<anchor>a10</anchor>
<arglist>()</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">
<type>virtual const char *</type>
<name>what</name>
<anchor>a2</anchor>
<arglist>() const</arglist>
<arglist>() const </arglist>
</member>
</compound>
<compound kind="class">
@ -574,7 +782,7 @@
<type>virtual const char *</type>
<name>what</name>
<anchor>a1</anchor>
<arglist>() const</arglist>
<arglist>() const </arglist>
</member>
</compound>
<compound kind="class">
@ -591,16 +799,16 @@
<type>virtual const char *</type>
<name>what</name>
<anchor>a1</anchor>
<arglist>() const</arglist>
<arglist>() const </arglist>
</member>
</compound>
<compound kind="class">
<name>mrw::logic_error</name>
<filename>classmrw_1_1logic__error.html</filename>
<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>logic_error</name>
<name>out_of_range</name>
<anchor>a0</anchor>
<arglist>(const std::string &amp;arg)</arglist>
</member>
@ -608,50 +816,16 @@
<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 kind="function">
<type></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>
<arglist>() const </arglist>
</member>
</compound>
<compound kind="class">
<name>mrw::out_of_range</name>
<filename>classmrw_1_1out__of__range.html</filename>
<name>mrw::runtime_error</name>
<filename>classmrw_1_1runtime__error.html</filename>
<base virtualness="virtual">mrw::exception</base>
<member kind="function">
<type></type>
<name>out_of_range</name>
<name>runtime_error</name>
<anchor>a0</anchor>
<arglist>(const std::string &amp;arg)</arglist>
</member>
@ -659,7 +833,7 @@
<type>virtual const char *</type>
<name>what</name>
<anchor>a1</anchor>
<arglist>() const</arglist>
<arglist>() const </arglist>
</member>
</compound>
<compound kind="class">
@ -674,233 +848,164 @@
</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>
<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>
<name>what</name>
<anchor>a1</anchor>
<arglist>() const </arglist>
</member>
</compound>
<compound kind="class">
<name>mrw::Param::Value</name>
<filename>classmrw_1_1Param_1_1Value.html</filename>
<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 std::string &amp;</type>
<name>toString</name>
<type>virtual const char *</type>
<name>what</name>
<anchor>a1</anchor>
<arglist>() const</arglist>
<arglist>() const </arglist>
</member>
<member kind="function" virtualness="virtual">
<type>virtual int</type>
<name>toInt</name>
<anchor>a2</anchor>
<arglist>() const</arglist>
</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 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>
<type>virtual const char *</type>
<name>what</name>
<anchor>a1</anchor>
<arglist>() 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>
<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">
<type>virtual int</type>
<name>toInt</name>
<type>virtual const char *</type>
<name>what</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>
<arglist>() const </arglist>
</member>
</compound>
<compound kind="class">
<name>mrw::pipe</name>
<filename>classmrw_1_1pipe.html</filename>
<name>mrw::Exec</name>
<filename>classmrw_1_1Exec.html</filename>
<member kind="function">
<type></type>
<name>pipe</name>
<name>Exec</name>
<anchor>a0</anchor>
<arglist>()</arglist>
<arglist>(const mrw::Cmd &amp;)</arglist>
</member>
<member kind="function">
<type></type>
<name>~pipe</name>
<name>Exec</name>
<anchor>a1</anchor>
<arglist>()</arglist>
</member>
<member kind="function">
<type>void</type>
<name>close</name>
<anchor>a2</anchor>
<arglist>()</arglist>
<arglist>(const mrw::Exec &amp;)</arglist>
</member>
<member kind="function">
<type>void</type>
<name>close_in</name>
<type>Exec &amp;</type>
<name>operator=</name>
<anchor>a3</anchor>
<arglist>()</arglist>
<arglist>(const mrw::Exec &amp;)</arglist>
</member>
<member kind="function">
<type>void</type>
<name>close_out</name>
<type>Exec &amp;</type>
<name>execute</name>
<anchor>a4</anchor>
<arglist>()</arglist>
<arglist>(bool=true)</arglist>
</member>
<member kind="function">
<type></type>
<name>operator bool</name>
<type>Exec &amp;</type>
<name>operator&gt;&gt;</name>
<anchor>a5</anchor>
<arglist>()</arglist>
<arglist>(std::string &amp;)</arglist>
</member>
<member kind="function">
<type>int</type>
<name>error</name>
<type></type>
<name>operator std::string &amp;</name>
<anchor>a6</anchor>
<arglist>()</arglist>
</member>
<member kind="function">
<type>void</type>
<name>connect_cout</name>
<type></type>
<name>operator bool</name>
<anchor>a7</anchor>
<arglist>()</arglist>
</member>
<member kind="function">
<type>void</type>
<name>connect_cerr</name>
<type>std::string &amp;</type>
<name>result</name>
<anchor>a8</anchor>
<arglist>()</arglist>
</member>
<member kind="function">
<type>int</type>
<name>istream</name>
<type>std::string &amp;</type>
<name>error</name>
<anchor>a9</anchor>
<arglist>()</arglist>
</member>
<member kind="function">
<type>int</type>
<name>ostream</name>
<type>bool</type>
<name>success</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>
<name>mrw::Cmd</name>
<filename>classmrw_1_1Cmd.html</filename>
<member kind="function">
<type></type>
<name>range_error</name>
<name>Cmd</name>
<anchor>a0</anchor>
<arglist>(const std::string &amp;arg)</arglist>
<arglist>(const std::string &amp;)</arglist>
</member>
<member kind="function" virtualness="virtual">
<type>virtual const char *</type>
<name>what</name>
<member kind="function">
<type>Cmd &amp;</type>
<name>operator,</name>
<anchor>a1</anchor>
<arglist>() const</arglist>
<arglist>(const std::string &amp;)</arglist>
</member>
<member kind="function">
<type>Cmd &amp;</type>
<name>operator&lt;&lt;</name>
<anchor>a2</anchor>
<arglist>(const std::string &amp;)</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>
<name>operator std::string</name>
<anchor>a3</anchor>
<arglist>() const </arglist>
</member>
<member kind="function" virtualness="virtual">
<type>virtual const char *</type>
<name>what</name>
<anchor>a1</anchor>
<arglist>() const</arglist>
<member kind="function">
<type></type>
<name>operator mrw::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>
</compound>
<compound kind="class">
@ -953,19 +1058,19 @@
<type>const TYPE &amp;</type>
<name>operator *</name>
<anchor>a9</anchor>
<arglist>() const</arglist>
<arglist>() const </arglist>
</member>
<member kind="function">
<type>TYPE *const</type>
<type>TYPE *const </type>
<name>operator-&gt;</name>
<anchor>a10</anchor>
<arglist>()</arglist>
</member>
<member kind="function">
<type>const TYPE *const</type>
<type>const TYPE *const </type>
<name>operator-&gt;</name>
<anchor>a11</anchor>
<arglist>() const</arglist>
<arglist>() const </arglist>
</member>
<member kind="function">
<type></type>
@ -993,19 +1098,19 @@
<type></type>
<name>operator std::string</name>
<anchor>a1</anchor>
<arglist>() const</arglist>
<arglist>() const </arglist>
</member>
<member kind="function">
<type></type>
<name>operator const AddressTrace &amp;</name>
<anchor>a2</anchor>
<arglist>() const</arglist>
<arglist>() const </arglist>
</member>
<member kind="function">
<type>const StackTrace &amp;</type>
<name>print</name>
<anchor>a3</anchor>
<arglist>(std::ostream &amp;os) const</arglist>
<arglist>(std::ostream &amp;os) const </arglist>
</member>
<member kind="function" static="yes">
<type>CodePos</type>
@ -1089,20 +1194,73 @@
</member>
</compound>
<compound kind="class">
<name>mrw::underflow_error</name>
<filename>classmrw_1_1underflow__error.html</filename>
<base virtualness="virtual">mrw::exception</base>
<name>mrw::Pipe</name>
<filename>classmrw_1_1Pipe.html</filename>
<member kind="function">
<type></type>
<name>underflow_error</name>
<name>Pipe</name>
<anchor>a0</anchor>
<arglist>(const std::string &amp;arg)</arglist>
<arglist>()</arglist>
</member>
<member kind="function" virtualness="virtual">
<type>virtual const char *</type>
<name>what</name>
<member kind="function">
<type></type>
<name>~Pipe</name>
<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>
</compound>
</tagfile>

@ -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
examplesdir = ${pkgdatadir}/examples
examples_DATA = examples/*
htmldir = ${pkgdatadir}/doc/html
html_DATA = doc/html/*
html_DATA = doc/html/index.html doc/html/*
pdfdir = ${pkgdatadir}/doc/pdf
pdf_DATA = doc/latex/@PACKAGENAME@-@MAJOR@.@MINOR@.pdf
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 \
auto.hpp auto.cpp unistd.hpp smartpointer.hpp \
stacktrace.hpp stacktrace.cpp exception.hpp exception.cpp \
auto.hpp unistd.hpp smartpointer.hpp \
exception.hpp exception.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@
libmrwexcstderr_la_SOURCES = autostacktracestderr.cpp
libmrwexcstderr_la_LDFLAGS = -version-info @MAJOR@:@MINOR@
libmrwexcstderr_la_LIBADD = -lmrw
if HAVE_STACKTRACE
libmrwexcstderr_la_SOURCES = autostacktracestderr.cpp version.cpp
libmrwexcstderr_la_LDFLAGS = -version-info @MAJOR@:@MINOR@
libmrwexcstderr_la_LIBADD = -lmrw
libmrwexclog4cxx_la_SOURCES = autostacktracelog4cxx.cpp
libmrwexclog4cxx_la_LDFLAGS = -version-info @MAJOR@:@MINOR@
libmrwexclog4cxx_la_LIBADD = -lmrw
if HAVE_LOG4CXX
libmrwexclog4cxx_la_SOURCES = autostacktracelog4cxx.cpp version.cpp
libmrwexclog4cxx_la_LDFLAGS = -version-info @MAJOR@:@MINOR@
libmrwexclog4cxx_la_LIBADD = -lmrw
endif
endif
check_PROGRAMS = auto_test smartpointer_test exec_test \
stacktrace_test mrwexcstderr_test mrwexclog4cxx_test
auto_test_SOURCES = auto_test.cpp
check_PROGRAMS = auto_test smartpointer_test exec_test
if HAVE_STACKTRACE
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_LDADD = -lmrw -lcppunit
smartpointer_test_SOURCES = smartpointer_test.cpp
smartpointer_test_SOURCES = smartpointer_test.cpp version.cpp
smartpointer_test_CPPFLAGS = -I.. -g3
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_LDADD = -lmrw -lcppunit
stacktrace_test_SOURCES = stacktrace_test.cpp
stacktrace_test_CPPFLAGS = -I.. -g3
stacktrace_test_LDADD = -lmrw -lcppunit
mrwexcstderr_test_SOURCES = mrwexcstderr_test.cpp
mrwexcstderr_test_CPPFLAGS = -I.. -g3
mrwexcstderr_test_LDADD = -lmrwexcstderr -lcppunit
mrwexclog4cxx_test_SOURCES = mrwexclog4cxx_test.cpp
mrwexclog4cxx_test_CPPFLAGS = -I.. -g3
mrwexclog4cxx_test_LDADD = -lmrwexclog4cxx -lcppunit -llog4cxx
if HAVE_STACKTRACE
stacktrace_test_SOURCES = stacktrace_test.cpp version.cpp
stacktrace_test_CPPFLAGS = -I.. -g3
stacktrace_test_LDADD = -lmrw -lcppunit
mrwexcstderr_test_SOURCES = mrwexcstderr_test.cpp version.cpp
mrwexcstderr_test_CPPFLAGS = -I.. -g3
mrwexcstderr_test_LDADD = -lmrwexcstderr -lcppunit
if HAVE_LOG4CXX
mrwexclog4cxx_test_SOURCES = mrwexclog4cxx_test.cpp version.cpp
mrwexclog4cxx_test_CPPFLAGS = -I.. -g3
mrwexclog4cxx_test_LDADD = -lmrwexclog4cxx -lcppunit -llog4cxx
endif
endif
TESTS = ${check_PROGRAMS}
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}
cd doc/latex && make && \
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

@ -41,6 +41,14 @@
@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>.
- @ref license "License Information (LGPL)"

@ -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 <log4cxx/basicconfigurator.h>
#include <cppunit/TestFixture.h>

@ -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 <cppunit/TestFixture.h>
#include <cppunit/ui/text/TestRunner.h>

@ -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__
#define __MRW_SIMPLETRACE_HPP__
#include <iostream>
#include <iomanip>
#include <string>
// GENERIC TRACER FOR TESTS ---------------------------------------------------
// (without file/line)
/** @defgroup SimpleTrace Simple Tracing (for temporary debugging)
@pre #include <mrw/simpletrace.hpp>
Here is a simple tracing to @c std::cout mechanism for temporary
debugging and simple testing purposes. Might be useful when
experimenting and exploring new C++ language constructs. Please
note that you can only trace in methods and functions that start
with @c METHOD respectively @c FUNCTION.
Please note that you should not use this simple mechanism for real
projects, only for your experiments! For your work, use
<a href="http://logging.apache.org/log4cxx">log4cxx</a>!
The trace of the following code:
@code
#include <mrw/simpletrace.hpp>
void fn(int i=0) {
FUNCTION; // trace entry and exit
if (!i) TRACE("Hello World, this is a nice text!");
if (i<4) fn(++i);
}
class A {
public:
A() {
NO_TRACE; // don't trace in constructor
method(); // not traced
}
void method() {
METHOD; // trace entry and exit
CALL(fn()); // trace before call
fn();
}
};
int main(int, char**) {
FUNCTION;
CALL(A().method());
A().method();
TRACE("No more trace:");
TRACE_OFF;
A().method();
TRACE_ON;
TRACE("Back again");
return 0;
}
@endcode
Produces this output:
@verbatim
tmp.cpp:20 0: \ main
tmp.cpp:21 0: -> A().method()
tmp.cpp:14 0xbffff10f: \ method
tmp.cpp:15 0xbffff10f: -> fn()
tmp.cpp:3 0: \ fn
tmp.cpp:4 0: **** Hello World, this is a nice text! ****
tmp.cpp:3 0: \ fn
tmp.cpp:3 0: \ fn
tmp.cpp:3 0: \ fn
tmp.cpp:3 0: \ fn
tmp.cpp:3 0: / fn
tmp.cpp:3 0: / fn
tmp.cpp:3 0: / fn
tmp.cpp:3 0: / fn
tmp.cpp:3 0: / fn
tmp.cpp:14 0xbffff10f: / method
tmp.cpp:23 0: **** No more trace: ****
tmp.cpp:27 0: **** Back again ****
tmp.cpp:20 0: / main
@endverbatim
*/
//@{
#ifndef __GNUG__
#define METHOD(name) mrw::FnTrace fnTrace(this, name)
#define FUNCTION(name) mrw::FnTrace fnTrace(0, name)
/// Declare method entrance, place as first line in method.
#define METHOD(name) mrw::FnTrace fnTrace(this, #name, __FILE__, __LINE__)
/// Declare function entrance, place as first line in function.
#define FUNCTION(name) mrw::FnTrace fnTrace(0, #name, __FILE__, __LINE__)
#else
#define METHOD mrw::FnTrace fnTrace(this, __FUNCTION__)
#define FUNCTION mrw::FnTrace fnTrace(0, __FUNCTION__)
/// Declare method entrance, place as first line in method.
/// GNU g++ knows the method name.
#define METHOD mrw::FnTrace fnTrace(this, __FUNCTION__, __FILE__, __LINE__)
/// Declare function entrance, place as first line in function.
/// GNU g++ knows the method name.
#define FUNCTION mrw::FnTrace fnTrace(0, __FUNCTION__, __FILE__, __LINE__)
#endif
#define CALL(name) fnTrace.call(name)
#define TRACE(name) fnTrace.trace(name)
/// Document the call of another method (before you call it).
#define CALL(name) fnTrace.call(#name, __FILE__, __LINE__)
/// Trace an arbitrary text.
#define TRACE(text) fnTrace.trace(text, __FILE__, __LINE__)
/// Turn all tracing off (from here on).
#define TRACE_OFF mrw::FnTrace::off()
/// Turn all tracing off (from here on).
#define TRACE_ON mrw::FnTrace::on()
/// Don't trace in this scope (from here on).
#define NO_TRACE mrw::NoTrace noTrace;
namespace mrw {
class FnTrace {
public:
FnTrace(const void* addr, const std::string& name):
_addr(addr), _name(name) {
FnTrace(const void* addr, const std::string& name,
const std::string& file, unsigned long line) throw():
_addr(addr), _name(name), _file(file), _line(line) {
if (_off==0)
std::cout<<std::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::endl;
++_level;
}
~FnTrace() {
~FnTrace() throw() {
--_level;
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::endl;
}
void call(const std::string& name) {
void call(const std::string& name,
const std::string& file, unsigned long line) throw() {
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::endl;
}
void trace(const std::string& name) {
void trace(const std::string& text,
const std::string& file, unsigned long line) throw() {
if (_off==0)
std::cout<<std::hex<<std::setw(15)<<_addr<<": "<<std::dec
<<std::setw(4+_level)<<std::setfill(' ')<<" **** "<<name
std::cout<<std::setw(15)<<file<<':'<<std::setiosflags(std::ios::left)
<<std::setw(5)<<line<<std::resetiosflags(std::ios::left)<<' '
<<std::hex<<std::setw(15)<<_addr<<": "<<std::dec
<<std::setw(4+_level)<<std::setfill(' ')<<" **** "<<text
<<" **** "<<std::endl;
}
static void off() {
static void off() throw() {
++_off;
}
static void on() {
static void on() throw() {
if (_off>0) --_off;
}
private:
const void* _addr;
const std::string _name;
const std::string _file;
unsigned long _line;
static unsigned int _level;
static unsigned int _off;
};
@ -65,8 +184,9 @@ namespace mrw {
unsigned int FnTrace::_off(0);
class NoTrace {
public:
NoTrace() {TRACE_OFF;}
~NoTrace() {TRACE_ON;}
NoTrace() throw() {TRACE_OFF;}
~NoTrace() throw() {TRACE_ON;}
};
}
//@}
#endif

@ -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__
#define __MRW__SMARTPOINTER_HPP__
@ -7,17 +32,17 @@ namespace mrw {
private:
unsigned int _cnt;
public:
PointerCounter():
PointerCounter() throw():
_cnt(1) {
}
PointerCounter* incr() {
PointerCounter* incr() throw() {
++_cnt;
return this;
}
int decr() {
int decr() throw() {
return --_cnt;
}
int get() {
int get() throw() {
return _cnt;
}
};
@ -25,11 +50,11 @@ namespace mrw {
class SmartPointerParent {
protected:
template<class TYPE>
PointerCounter* getCounter(TYPE& sp) {
PointerCounter* getCounter(TYPE& sp) throw() {
return sp._cnt;
}
template<class TYPE>
typename TYPE::Pointer getPointer(TYPE& sp) {
typename TYPE::Pointer getPointer(TYPE& sp) throw() {
return sp._ptr;
}
};
@ -68,7 +93,7 @@ namespace mrw {
PointerCounter* _cnt;
TYPE* _ptr;
private:
void drop() {
void drop() throw() {
if (_cnt && !_cnt->decr()) {
delete _cnt; _cnt=0;
delete _ptr; _ptr=0;
@ -78,30 +103,30 @@ namespace mrw {
friend class SmartPointerParent;
friend class SmartPointerTest;
public:
SmartPointer():
SmartPointer() throw():
_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) {
}
SmartPointer(TYPE* ptr):
SmartPointer(TYPE* ptr) throw():
_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))) {
if (_ptr) _cnt = getCounter(o)->incr();
}
~SmartPointer() {
~SmartPointer() throw() {
drop();
}
SmartPointer& operator=(const SmartPointer<TYPE>& o) {
SmartPointer& operator=(const SmartPointer<TYPE>& o) throw() {
if (o._ptr==_ptr) return *this;
drop();
_cnt = o._cnt ? o._cnt->incr() : 0;
_ptr = o._ptr;
return *this;
}
SmartPointer& operator=(TYPE* ptr) {
SmartPointer& operator=(TYPE* ptr) throw() {
if (ptr==_ptr) return *this;
drop();
_cnt = ptr ? new PointerCounter : 0;
@ -109,26 +134,26 @@ namespace mrw {
return *this;
}
template<class OTHER>
SmartPointer& operator=(const SmartPointer<OTHER>& o) {
SmartPointer& operator=(const SmartPointer<OTHER>& o) throw() {
if (getPointer(o)==_ptr) return *this;
drop();
_ptr = dynamic_cast<TYPE*>(getPointer(o));
_cnt = _ptr ? getCounter(o)->incr() : 0;
return *this;
}
TYPE& operator*() {
TYPE& operator*() throw() {
return *_ptr;
}
const TYPE& operator*() const {
const TYPE& operator*() const throw() {
return *_ptr;
}
TYPE* const operator->() {
TYPE* const operator->() throw() {
return _ptr;
}
const TYPE* const operator->() const {
const TYPE* const operator->() const throw() {
return _ptr;
}
operator bool() {
operator bool() throw() {
return _ptr!=0;
}
};

@ -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 <sstream>
#include <unistd.h>
@ -17,7 +42,33 @@
#endif
#include <bfd.h>
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>
@ -31,15 +82,15 @@ namespace mrw {
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
confusing the demangler. */
const char* p (name);
const char* p(name);
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) {
/* 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);
return add_dots+=(char*)res;
return add_dots+=static_cast<const char*>(res);
}
return name;
}
@ -118,7 +169,8 @@ namespace mrw {
static const char* file(0);
static const char* function(0);
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))
return CodePos(addr, "????", "????", 0);
return CodePos(addr, mrw::demangle(_bfd, function), file?file:"????", line);
@ -129,13 +181,18 @@ namespace mrw {
if (_dic.get()) return true;
AutoBfd abfd(bfd_openr((fname!="" ? fname : filename()).c_str(), 0));
long memsz(-1);
AutoFree<char*> m(0);
Auto<char**>::Free m(0);
if (!abfd || bfd_check_format(abfd, bfd_archive) ||
!bfd_check_format_matches(abfd, bfd_object, m) ||
!(bfd_get_file_flags(abfd)&HAS_SYMS) ||
(memsz=bfd_get_symtab_upper_bound(abfd))<0) return false;
!bfd_check_format_matches(abfd, bfd_object, &(m.getClean())) ||
!(bfd_get_file_flags(const_cast<bfd*>(static_cast<const bfd*>(abfd)))
&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]);
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;
_syms = syms;
_dic = std::auto_ptr<Translator>(new Translator());

@ -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
#ifndef __MRW_STACKTRACE_HPP__
#define __MRW_STACKTRACE_HPP__
@ -82,7 +107,7 @@ namespace mrw {
@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
with GNU glibc's function @c backtrace(). On other systems
@ -103,7 +128,7 @@ namespace mrw {
executable file name as an argument to @c
mrw::StackTrace::createSymtable().
@section stdrawbacks Draw Backs
<h3>Draw Backs</h3>
Unfortunately it is not possible to extract the source file name
and line number information if the executable was not compiled
@ -139,7 +164,7 @@ namespace mrw {
StackTrace() throw(std::bad_exception);
/// evaluates the symbol table and returns the formatted stack trace
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) {
return _trace;
}

@ -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 <cppunit/TestFixture.h>
#include <cppunit/ui/text/TestRunner.h>

@ -1,18 +1,33 @@
/** @file
$Id$
$Date$
$Author$
@copy &copy; Marc W&auml;ckerlin
@license LGPL, see file <a href="license.html">COPYING</a>
$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
change in file header
Revision 1.3 2004/08/25 08:22:19 marc
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__
#define __MRW_UNISTD_HPP__
@ -36,7 +51,7 @@ namespace mrw {
int _lastError;
public:
/// creates a unix pipe
Pipe(): _lastError(-1) {
Pipe() throw(std::bad_exception): _lastError(-1) {
_fd[0] = -1;
_fd[1] = -1;
if (::pipe(_fd)==-1)
@ -45,16 +60,16 @@ namespace mrw {
}
}
/// destructor closes pipe if still open
~Pipe() {
~Pipe() throw(std::bad_exception) {
close();
}
/// closes pipe if open
void close() {
void close() throw(std::bad_exception) {
close_in();
close_out();
}
/// 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) {
_lastError = errno;
break;
@ -62,30 +77,30 @@ namespace mrw {
_fd[0] = -1;
}
/// 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) {
_lastError = errno;
break;
}
_fd[1] = -1;
}
/// @return true if no error occured
operator bool() {
/** @return true if no error occured */
operator bool() throw() {
return _lastError == -1;
}
/// @return last error code, -1 if no error
int error() {
/** @return last error code, -1 if no error */
int error() throw() {
return _lastError;
}
/// 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) {
_lastError = errno;
return;
}
}
/// 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) {
_lastError = errno;
return;
@ -94,13 +109,13 @@ namespace mrw {
/// get an input stream
/** @return stream to read from
@note invalid after destruction or @c close or @c close_in */
int istream() {
int istream() throw(std::bad_exception) {
return _fd[0];
}
/// get an output stream
/** @return stream to write to
@note invalid after destruction or @c close or @c close_out */
int ostream() {
int ostream() throw(std::bad_exception) {
return _fd[1];
}
};

Loading…
Cancel
Save