parent
e303138fcd
commit
93696ef645
23 changed files with 657 additions and 107 deletions
@ -0,0 +1,7 @@ |
|||||||
|
* Fri Apr 24 2004 Marc Wäckerlin <marc@waeckerlin.org> - mrw-c++-0.90 (mrw) |
||||||
|
- initial rpm with two spec files |
||||||
|
- test cases for libmrwexcstderr and libmrwexclog4cxx |
||||||
|
* Thu Apr 23 2004 Marc Wäckerlin <marc@waeckerlin.org> - mrw-c++-0.11 (mrw) |
||||||
|
- better support for solaris, but not yet tested |
||||||
|
- more and better documentation and a pdf file |
||||||
|
- new submodule "Automated Unexpected Handler with Stack Trace" |
@ -0,0 +1,5 @@ |
|||||||
|
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. |
@ -1,9 +1,6 @@ |
|||||||
Please read: |
C++ Library for automated C-Library resource management, UNIX |
||||||
- from the .tar.gz package: |
Pipes, simple and secure UNIX system command execution, runtime |
||||||
mrw/doc/html/index.html |
stack trace and automated unexpected exception handling. |
||||||
- from the .tar.gz installation: |
|
||||||
/usr/local/share/mrw-c++/doc/html/index.html |
HTML and PDF documentation is include in the installation (built with |
||||||
- from the rpm installation: |
Doxygen). |
||||||
/usr/share/doc/packages/mrw-c++/doc/html/index.html |
|
||||||
- the webpage at: |
|
||||||
http://marc.waeckerlin.org/mrw-c++/index.html |
|
||||||
|
@ -0,0 +1,4 @@ |
|||||||
|
#! /bin/sh |
||||||
|
|
||||||
|
make distclean |
||||||
|
aclocal && libtoolize --force && automake && autoconf |
@ -1,11 +1,24 @@ |
|||||||
SUBDIRS = mrw |
SUBDIRS = mrw |
||||||
|
|
||||||
include_HEADERS = mrw/auto.hpp mrw/unistd.hpp \ |
nobase_include_HEADERS = mrw/auto.hpp mrw/unistd.hpp \ |
||||||
mrw/stacktrace.hpp mrw/exception.hpp \ |
mrw/stacktrace.hpp mrw/exception.hpp \ |
||||||
mrw/exec.hpp |
mrw/exec.hpp |
||||||
data_DATA = AUTHORS NEWS README COPYING INSTALL ChangeLog |
infosdir = ${pkgdatadir} |
||||||
|
infos_DATA = AUTHORS NEWS README COPYING INSTALL ChangeLog \ |
||||||
|
@PACKAGENAME@.spec @PACKAGENAME@-devel.spec |
||||||
|
|
||||||
webserver: all check doc dist |
RPMS = /usr/src/packages/RPMS/i586/@PACKAGENAME@-@MAJOR@.@MINOR@-1.i586.rpm \ |
||||||
|
/usr/src/packages/RPMS/i586/@PACKAGENAME@-devel-@MAJOR@.@MINOR@-1.i586.rpm |
||||||
|
|
||||||
|
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 mkdir -p /home/marc/mrw-c++ |
||||||
scp mrw/doc/html/* root@waeckerlin.org:/home/marc/mrw-c++/ |
scp mrw/doc/html/* \ |
||||||
scp @PACKAGENAME@-@MAJOR@.@MINOR@.tar.gz root@waeckerlin.org:/home/marc/mrw-c++/ |
mrw/doc/latex/@PACKAGENAME@-@MAJOR@.@MINOR@.pdf \ |
||||||
|
@PACKAGENAME@-@MAJOR@.@MINOR@.tar.gz \ |
||||||
|
${RPMS} \ |
||||||
|
root@waeckerlin.org:/home/marc/mrw-c++/ |
||||||
|
@ -0,0 +1,42 @@ |
|||||||
|
# rpmbuild -bb --clean @PACKAGENAME@.spec |
||||||
|
Summary: MRW's C++ Class Library, facilities for ease and quality |
||||||
|
Name: @PACKAGENAME@-devel |
||||||
|
Version: @MAJOR@.@MINOR@ |
||||||
|
Release: 1 |
||||||
|
License: LGPL |
||||||
|
Group: Development/Libraries/C++ |
||||||
|
URL: http://marc.waeckerlin.org/mrw-c++/index.html |
||||||
|
Source0: @PACKAGENAME@-@MAJOR@.@MINOR@.tar.gz |
||||||
|
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot |
||||||
|
|
||||||
|
Prefix: /usr |
||||||
|
|
||||||
|
Requires: gcc-c++ >= 3.0 |
||||||
|
Requires: binutils |
||||||
|
Requires: @PACKAGENAME@ = @MAJOR@.@MINOR@ |
||||||
|
|
||||||
|
%description |
||||||
|
@README@ |
||||||
|
|
||||||
|
This Package contains all files required for developement. |
||||||
|
|
||||||
|
%prep |
||||||
|
%setup -q -n @PACKAGENAME@-@MAJOR@.@MINOR@ |
||||||
|
./configure --prefix=$RPM_BUILD_ROOT/usr |
||||||
|
|
||||||
|
%build |
||||||
|
make check |
||||||
|
|
||||||
|
%install |
||||||
|
make install |
||||||
|
rm -rf $RPM_BUILD_ROOT/usr/lib/libmrw*.so* |
||||||
|
|
||||||
|
%clean |
||||||
|
rm -rf $RPM_BUILD_ROOT |
||||||
|
|
||||||
|
%files |
||||||
|
%defattr(-,root,root,-) |
||||||
|
/usr |
||||||
|
|
||||||
|
%changelog |
||||||
|
@CHANGE_LOG@ |
@ -0,0 +1,46 @@ |
|||||||
|
# rpmbuild -bb --clean @PACKAGENAME@.spec |
||||||
|
Summary: MRW's C++ Class Library, facilities for ease and quality |
||||||
|
Name: @PACKAGENAME@ |
||||||
|
Version: @MAJOR@.@MINOR@ |
||||||
|
Release: 1 |
||||||
|
License: LGPL |
||||||
|
Group: Development/Libraries/C++ |
||||||
|
URL: http://marc.waeckerlin.org/mrw-c++/index.html |
||||||
|
Source0: %{name}-%{version}.tar.gz |
||||||
|
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot |
||||||
|
|
||||||
|
Prefix: /usr |
||||||
|
|
||||||
|
Requires: gcc-c++ >= 3.0 |
||||||
|
Requires: binutils |
||||||
|
|
||||||
|
%description |
||||||
|
@README@ |
||||||
|
|
||||||
|
This package contains only the shared libraries required at runtime. |
||||||
|
|
||||||
|
%prep |
||||||
|
%setup -q |
||||||
|
./configure --prefix=$RPM_BUILD_ROOT/usr |
||||||
|
|
||||||
|
%build |
||||||
|
make check |
||||||
|
|
||||||
|
%install |
||||||
|
make install |
||||||
|
rm -rf $RPM_BUILD_ROOT/usr/share/mrw-c++ |
||||||
|
rm -rf $RPM_BUILD_ROOT/usr/include/mrw |
||||||
|
rm -rf $RPM_BUILD_ROOT/usr/lib/libmrw*.la |
||||||
|
rm -rf $RPM_BUILD_ROOT/usr/lib/libmrw*.a |
||||||
|
rmdir $RPM_BUILD_ROOT/usr/include |
||||||
|
rmdir $RPM_BUILD_ROOT/usr/share |
||||||
|
|
||||||
|
%clean |
||||||
|
rm -rf $RPM_BUILD_ROOT |
||||||
|
|
||||||
|
%files |
||||||
|
%defattr(-,root,root,-) |
||||||
|
/usr |
||||||
|
|
||||||
|
%changelog |
||||||
|
@CHANGE_LOG@ |
@ -0,0 +1,91 @@ |
|||||||
|
#include <mrw/stacktrace.hpp> |
||||||
|
#include <mrw/exception.hpp> |
||||||
|
#include <exception> |
||||||
|
#include <log4cxx/logger.h> |
||||||
|
|
||||||
|
namespace mrw { |
||||||
|
|
||||||
|
/** @addtogroup StackTrace */ |
||||||
|
//@{
|
||||||
|
|
||||||
|
/** @addtogroup AutoTrace
|
||||||
|
|
||||||
|
@section trclog4cxx Trace using the log4cxx Library |
||||||
|
|
||||||
|
If you link to the library @c libmrwexclog4cxx using a linker |
||||||
|
option such as: @c -lmrwexclog4cxx, then an unexpected handler |
||||||
|
is registered, that traces a fatal error using the log4cxx |
||||||
|
library. You don't need to change a single line in your code! |
||||||
|
|
||||||
|
The log4cxx library is located at: |
||||||
|
- http://logging.apache.org/log4cxx
|
||||||
|
|
||||||
|
@note The configurator is not installed automatically. If you |
||||||
|
want to trace e.g. on the console, you have to call @c |
||||||
|
log4cxx::BasicConfigurator::configure(); as first statement in |
||||||
|
your @c main(). |
||||||
|
*/ |
||||||
|
//@{
|
||||||
|
|
||||||
|
/// 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 |
||||||
|
to @c -lmrwexclog4cxx. The implementation of this unexpected |
||||||
|
handler is as follows: |
||||||
|
|
||||||
|
@code |
||||||
|
void unexpected_log4cxx() { |
||||||
|
logger->fatal("Unexpected Exception", __FILE__, __LINE__); |
||||||
|
try { |
||||||
|
throw; |
||||||
|
} catch (const mrw::exception& x) { |
||||||
|
StackTrace::createSymtable(); |
||||||
|
logger->fatal(std::string("Reason:\n")+x.what() |
||||||
|
+"\nStack:+\n"+x.stacktrace()); |
||||||
|
} catch (const std::exception& x) { |
||||||
|
logger->fatal(std::string("Reason:\n")+x.what() |
||||||
|
+"\nStack: **** not available ****"); |
||||||
|
} catch (...) { |
||||||
|
logger->fatal(std::string("Reason: **** not available ****\n") |
||||||
|
+"\nStack: **** not available ****"); |
||||||
|
} |
||||||
|
throw std::bad_exception(); |
||||||
|
} |
||||||
|
@endcode |
||||||
|
|
||||||
|
*/ |
||||||
|
void unexpected_log4cxx() { |
||||||
|
logger->fatal("Unexpected Exception", __FILE__, __LINE__); |
||||||
|
try { |
||||||
|
throw; |
||||||
|
} catch (const mrw::exception& x) { |
||||||
|
StackTrace::createSymtable(); |
||||||
|
logger->fatal(std::string("Reason:\n")+x.what() |
||||||
|
+"\nStack:+\n"+x.stacktrace()); |
||||||
|
} catch (const std::exception& x) { |
||||||
|
logger->fatal(std::string("Reason:\n")+x.what() |
||||||
|
+"\nStack: **** not available ****"); |
||||||
|
} catch (...) { |
||||||
|
logger->fatal(std::string("Reason: **** not available ****\n") |
||||||
|
+"\nStack: **** not available ****"); |
||||||
|
} |
||||||
|
throw std::bad_exception(); |
||||||
|
} |
||||||
|
|
||||||
|
//@}
|
||||||
|
//@}
|
||||||
|
|
||||||
|
class AutoStackTrace { |
||||||
|
public: |
||||||
|
AutoStackTrace() { |
||||||
|
std::set_unexpected(&mrw::unexpected_log4cxx); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
// initialize stack traces (load symbols)
|
||||||
|
static AutoStackTrace _autoStackTrace; |
||||||
|
|
||||||
|
} |
@ -0,0 +1,55 @@ |
|||||||
|
#include <mrw/exception.hpp> |
||||||
|
#include <mrw/stacktrace.hpp> |
||||||
|
#include <exception> |
||||||
|
#include <iostream> |
||||||
|
|
||||||
|
void unexpectedHandler() { |
||||||
|
try { |
||||||
|
throw; |
||||||
|
} catch (mrw::exception& x) { |
||||||
|
mrw::StackTrace::createSymtable(); |
||||||
|
std::cerr<<"UNEXPECTED:"<<x.what()<<std::endl |
||||||
|
<<"---------------------------Stack:"<<std::endl |
||||||
|
<<x.stacktrace() |
||||||
|
<<"---------------------------------"<<std::endl; |
||||||
|
} catch (std::exception& x) { |
||||||
|
std::cerr<<"UNEXPECTED:"<<x.what()<<std::endl; |
||||||
|
} catch (...) { |
||||||
|
std::cerr<<"UNKNOWN UNEXPECTED"<<std::endl; |
||||||
|
} |
||||||
|
throw std::bad_exception(); // try to recover
|
||||||
|
} |
||||||
|
|
||||||
|
void fn2() throw(std::bad_exception) { |
||||||
|
std::cout<<"enter fn2"<<std::endl; |
||||||
|
throw mrw::exception(); // that's wrong, no exception excpected
|
||||||
|
std::cout<<"leave fn2"<<std::endl; |
||||||
|
} |
||||||
|
|
||||||
|
void fn1() throw(std::bad_exception) { |
||||||
|
std::cout<<"enter fn1"<<std::endl; |
||||||
|
fn2(); |
||||||
|
std::cout<<"leave fn1"<<std::endl; |
||||||
|
} |
||||||
|
|
||||||
|
void fn0() throw(std::bad_exception) { |
||||||
|
std::cout<<"enter fn0"<<std::endl; |
||||||
|
try { |
||||||
|
fn1(); |
||||||
|
} catch (std::exception& x) { |
||||||
|
std::cerr<<"EXCEPTION caught in fn0:"<<x.what()<<std::endl; |
||||||
|
} |
||||||
|
std::cout<<"leave fn0"<<std::endl; |
||||||
|
} |
||||||
|
|
||||||
|
int main() { |
||||||
|
std::set_unexpected(&unexpectedHandler); |
||||||
|
try { |
||||||
|
std::cout<<"call fn0"<<std::endl; |
||||||
|
fn0(); |
||||||
|
std::cout<<"call of fn0 successful"<<std::endl; |
||||||
|
} catch (...) { |
||||||
|
std::cerr<<"OOOPS!!!"<<std::endl; |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
@ -0,0 +1,68 @@ |
|||||||
|
#include <mrw/exception.hpp> |
||||||
|
#include <log4cxx/basicconfigurator.h> |
||||||
|
#include <cppunit/TestFixture.h> |
||||||
|
#include <cppunit/ui/text/TestRunner.h> |
||||||
|
#include <cppunit/extensions/HelperMacros.h> |
||||||
|
#include <cppunit/extensions/TestFactoryRegistry.h> |
||||||
|
|
||||||
|
namespace mrw { |
||||||
|
class AutoExcLog4CxxTest: public CppUnit::TestFixture { |
||||||
|
private: |
||||||
|
bool enter_unexpectedThrow; |
||||||
|
bool exit_unexpectedThrow; |
||||||
|
bool enter_passUnexpected; |
||||||
|
bool exit_passUnexpected; |
||||||
|
bool enter_catchUnexpected; |
||||||
|
bool exit_catchUnexpected; |
||||||
|
public: |
||||||
|
void setUp() { |
||||||
|
enter_unexpectedThrow = false; |
||||||
|
exit_unexpectedThrow = false; |
||||||
|
enter_passUnexpected = false; |
||||||
|
exit_passUnexpected = false; |
||||||
|
enter_catchUnexpected = false; |
||||||
|
exit_catchUnexpected = false; |
||||||
|
} |
||||||
|
void unexpectedThrow() throw(std::bad_exception) { |
||||||
|
enter_unexpectedThrow = true; |
||||||
|
throw mrw::exception(); |
||||||
|
exit_unexpectedThrow = true; |
||||||
|
} |
||||||
|
void passUnexpected() throw(std::bad_exception) { |
||||||
|
enter_passUnexpected = true; |
||||||
|
unexpectedThrow(); |
||||||
|
exit_passUnexpected = true; |
||||||
|
} |
||||||
|
void catchUnexpected() throw() { |
||||||
|
enter_catchUnexpected = true; |
||||||
|
bool caught(false); |
||||||
|
try { |
||||||
|
passUnexpected(); |
||||||
|
} catch (std::bad_exception&) { |
||||||
|
caught = true; |
||||||
|
} |
||||||
|
CPPUNIT_ASSERT(caught); |
||||||
|
exit_catchUnexpected = true; |
||||||
|
} |
||||||
|
void testcase() { |
||||||
|
catchUnexpected(); |
||||||
|
CPPUNIT_ASSERT(enter_catchUnexpected && |
||||||
|
enter_passUnexpected && |
||||||
|
enter_unexpectedThrow && |
||||||
|
exit_catchUnexpected && |
||||||
|
!exit_passUnexpected && |
||||||
|
!exit_unexpectedThrow); |
||||||
|
} |
||||||
|
CPPUNIT_TEST_SUITE(AutoExcLog4CxxTest); |
||||||
|
CPPUNIT_TEST(testcase); |
||||||
|
CPPUNIT_TEST_SUITE_END(); |
||||||
|
}; |
||||||
|
CPPUNIT_TEST_SUITE_REGISTRATION(AutoExcLog4CxxTest); |
||||||
|
} |
||||||
|
|
||||||
|
int main() { |
||||||
|
log4cxx::BasicConfigurator::configure(); |
||||||
|
CppUnit::TextUi::TestRunner runner; |
||||||
|
runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest()); |
||||||
|
return runner.run() ? 0 : 1; |
||||||
|
} |
@ -0,0 +1,66 @@ |
|||||||
|
#include <mrw/exception.hpp> |
||||||
|
#include <cppunit/TestFixture.h> |
||||||
|
#include <cppunit/ui/text/TestRunner.h> |
||||||
|
#include <cppunit/extensions/HelperMacros.h> |
||||||
|
#include <cppunit/extensions/TestFactoryRegistry.h> |
||||||
|
|
||||||
|
namespace mrw { |
||||||
|
class AutoExcStderrTest: public CppUnit::TestFixture { |
||||||
|
private: |
||||||
|
bool enter_unexpectedThrow; |
||||||
|
bool exit_unexpectedThrow; |
||||||
|
bool enter_passUnexpected; |
||||||
|
bool exit_passUnexpected; |
||||||
|
bool enter_catchUnexpected; |
||||||
|
bool exit_catchUnexpected; |
||||||
|
public: |
||||||
|
void setUp() { |
||||||
|
enter_unexpectedThrow = false; |
||||||
|
exit_unexpectedThrow = false; |
||||||
|
enter_passUnexpected = false; |
||||||
|
exit_passUnexpected = false; |
||||||
|
enter_catchUnexpected = false; |
||||||
|
exit_catchUnexpected = false; |
||||||
|
} |
||||||
|
void unexpectedThrow() throw(std::bad_exception) { |
||||||
|
enter_unexpectedThrow = true; |
||||||
|
throw mrw::exception(); |
||||||
|
exit_unexpectedThrow = true; |
||||||
|
} |
||||||
|
void passUnexpected() throw(std::bad_exception) { |
||||||
|
enter_passUnexpected = true; |
||||||
|
unexpectedThrow(); |
||||||
|
exit_passUnexpected = true; |
||||||
|
} |
||||||
|
void catchUnexpected() throw() { |
||||||
|
enter_catchUnexpected = true; |
||||||
|
bool caught(false); |
||||||
|
try { |
||||||
|
passUnexpected(); |
||||||
|
} catch (std::bad_exception&) { |
||||||
|
caught = true; |
||||||
|
} |
||||||
|
CPPUNIT_ASSERT(caught); |
||||||
|
exit_catchUnexpected = true; |
||||||
|
} |
||||||
|
void testcase() { |
||||||
|
catchUnexpected(); |
||||||
|
CPPUNIT_ASSERT(enter_catchUnexpected && |
||||||
|
enter_passUnexpected && |
||||||
|
enter_unexpectedThrow && |
||||||
|
exit_catchUnexpected && |
||||||
|
!exit_passUnexpected && |
||||||
|
!exit_unexpectedThrow); |
||||||
|
} |
||||||
|
CPPUNIT_TEST_SUITE(AutoExcStderrTest); |
||||||
|
CPPUNIT_TEST(testcase); |
||||||
|
CPPUNIT_TEST_SUITE_END(); |
||||||
|
}; |
||||||
|
CPPUNIT_TEST_SUITE_REGISTRATION(AutoExcStderrTest); |
||||||
|
} |
||||||
|
|
||||||
|
int main() { |
||||||
|
CppUnit::TextUi::TestRunner runner; |
||||||
|
runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest()); |
||||||
|
return runner.run() ? 0 : 1; |
||||||
|
} |
Loading…
Reference in new issue