Fix: Headers are now installed.
[libsex.git] / src / Exception.cxx
blob6348dd2632cd8e280249c03f0e377f5cd3bbaac8
1 #include <libsex/Exception.hxx>
2 #include <cstring> // strncpy()
4 namespace libsex {
6 Exception::Exception(const char* const message) throw()
7 : _previous(0)
9 _initMessage(message);
12 Exception::Exception(
13 const char* const message,
14 const Exception& previous) throw()
15 : _previous(0)
17 _initMessage(message);
18 try {
19 _previous = previous.clone();
20 } catch (std::bad_alloc& e) {
21 // We need to know the amount of characters
22 // that can be put into _message.
24 // Size to begin with:
25 unsigned int length = Exception::LENGTH;
26 // Substract characters written so far:
27 length -= strlen(_message);
28 // Substract nullbyte appended by strcat().
29 // Prevent underflow.
30 if (length > 0) --length;
32 // Add notice to our original message:
33 strncat(_message, "\n"
34 "DOUBLE FAULT! "
35 "Caught std::bad_alloc in "
36 "constructor of an exception.",
37 length);
41 Exception::~Exception() throw()
43 if (_previous) delete _previous;
46 void Exception::write(std::ostream& out) const throw(std::ios_base::failure)
48 out << what();
51 void Exception::backtrace(std::ostream& out) const throw(std::ios_base::failure)
53 write(out);
54 if (_previous != 0) {
55 out << "\n";
56 _previous->backtrace(out);
60 const Exception* Exception::clone() const
61 throw(std::bad_alloc)
63 if (_previous) {
64 return new Exception(_message, *_previous);
65 } else {
66 return new Exception(_message);
70 const char* Exception::what() const throw()
72 return _message;
75 void Exception::_initMessage(const char* const message)
77 strncpy(_message, message, Exception::LENGTH);
78 // if |message| < |_message|
79 // strncpy() will pad with 0
80 // else
81 // strncpy() will NOT add a trailing 0!
82 _message[Exception::LENGTH] = 0;
85 } // namespace