39 #include "blocxx/BLOCXX_config.h"
43 #if defined(BLOCXX_NON_THREAD_SAFE_EXCEPTION_HANDLING)
50 #if defined(BLOCXX_HAVE_ISTREAM) && defined(BLOCXX_HAVE_OSTREAM)
58 namespace BLOCXX_NAMESPACE
61 #if defined(BLOCXX_NON_THREAD_SAFE_EXCEPTION_HANDLING)
77 char* rv =
new (std::nothrow)
char[strlen(str)+1];
90 , m_msg(dupString(msg))
91 , m_subClassId(UNKNOWN_SUBCLASS_ID)
93 , m_errorCode(UNKNOWN_ERROR_CODE)
95 #ifdef BLOCXX_ENABLE_STACK_TRACE_ON_EXCEPTIONS
98 #if defined(BLOCXX_NON_THREAD_SAFE_EXCEPTION_HANDLING)
107 , m_msg(dupString(msg))
108 , m_subClassId(subClassId)
109 , m_subException(subException ? subException->clone() : 0)
110 , m_errorCode(errorCode)
112 #ifdef BLOCXX_ENABLE_STACK_TRACE_ON_EXCEPTIONS
115 #if defined(BLOCXX_NON_THREAD_SAFE_EXCEPTION_HANDLING)
124 , m_msg(dupString(msg))
125 , m_subClassId(subClassId)
126 , m_subException(subException ? subException->clone() : 0)
127 , m_errorCode(errorCode)
129 #ifdef BLOCXX_ENABLE_STACK_TRACE_ON_EXCEPTIONS
132 #if defined(BLOCXX_NON_THREAD_SAFE_EXCEPTION_HANDLING)
141 , m_msg(dupString(e.m_msg))
142 , m_subClassId(e.m_subClassId)
143 , m_subException(e.m_subException ? e.m_subException->clone() : 0)
144 , m_errorCode(e.m_errorCode)
146 #if defined(BLOCXX_NON_THREAD_SAFE_EXCEPTION_HANDLING)
158 #if defined(BLOCXX_NON_THREAD_SAFE_EXCEPTION_HANDLING)
178 std::swap(static_cast<std::exception&>(*
this), static_cast<std::exception&>(rhs));
235 os << e.
type() <<
": ";
244 os <<
"[no message]";
254 os <<
" <" << *subEx << '>
';
260 Exception::what() const throw()
267 Exception::getSubClassId() const
274 Exception::setSubClassId(int subClassId)
276 m_subClassId = subClassId;
281 Exception::clone() const
283 return new(std::nothrow) Exception(*this);
287 void Exception::rethrow() const
294 Exception::getSubException() const
296 return m_subException;
301 Exception::getErrorCode() const
308 Exception::setErrorCode(int errorCode)
310 m_errorCode = errorCode;
313 namespace ExceptionDetail
316 // HPUX, solaris have a thread safe strerror(), windows doesn't have strerror_r(), and doesn
't document whether strerror() is thread safe or not.
317 #if defined(BLOCXX_HPUX) || defined(BLOCXX_SOLARIS) || defined(BLOCXX_WIN32) || defined(BLOCXX_NCR)
319 void portable_strerror_r(int errnum, char * buf, unsigned n)
321 ::strncpy(buf, strerror(errnum), n);
322 buf[n-1] = '\0
'; // just in case...
326 typedef int (*posix_fct)(int, char *, ::std::size_t);
327 typedef char * (*gnu_fct)(int, char *, ::std::size_t);
328 typedef int (*aix_fct)(int, char *, int);
334 // We make the strerror_r_wrap functions into templates so that
335 // code is generated only for the one that gets used.
337 template <typename Dummy>
339 strerror_r_wrap(posix_fct strerror_r, int errnum, char * buf, unsigned n,
342 return strerror_r(errnum, buf, n);
345 template <typename Dummy>
347 strerror_r_wrap(aix_fct strerror_r, int errnum, char * buf, unsigned n,
350 return strerror_r(errnum, buf, n);
353 template <typename Dummy>
355 strerror_r_wrap(gnu_fct strerror_r, int errnum, char * buf, unsigned n,
358 char * errstr = strerror_r(errnum, buf, n);
363 ::strncpy(buf, errstr, n);
373 void portable_strerror_r(int errnum, char * buf, unsigned n)
375 int errc = strerror_r_wrap(&::strerror_r, errnum, buf, n, dummy());
378 ::strncpy(buf, "[Could not create error message for error code]", n);
380 buf[n-1] = '\0
'; // just in case...
384 struct BLOCXX_COMMON_API FormatMsgImpl
389 FormatMsg::FormatMsg(char const * msg, int errnum)
390 : pImpl(new FormatMsgImpl)
393 portable_strerror_r(errnum, arr, BUFSZ);
394 char const * sarr = static_cast<char const *>(arr);
395 pImpl->fm = Format("%1: %2(%3)", msg, errnum, sarr).toString();
398 FormatMsg::~FormatMsg()
402 char const * FormatMsg::get() const
404 return pImpl->fm.c_str();
407 } // namespace ExceptionDetail
409 } // end namespace BLOCXX_NAMESPACE