Light update of the exception.cpp: ExceptionBase& ExceptionBase::operator= (const ExceptionBase& ex) : if strdup() is failed then copy string to the internal buf_ with truncate.
Farid. > -----Original Message----- > From: Farid Zaripov [mailto:[EMAIL PROTECTED] > Sent: Wednesday, July 12, 2006 7:18 PM > To: [email protected] > Subject: RE: design of testuite exceptions (was: Re: svn > commit: r418319 - > /incubator/stdcxx/trunk/tests/strings/21.string.io.cpp) > > Martin, I implemented your latest notes about testsuite > exception (rw_exception.h, exception.cpp). The updated > version is attached.
/************************************************************************ * * exception.cpp - exceptions testsuite helpers * * $Id: $ * ************************************************************************ * * Copyright 2006 The Apache Software Foundation or its licensors, * as applicable. * * Copyright 2006 Rogue Wave Software. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * **************************************************************************/ // expand _TEST_EXPORT macros #define _RWSTD_TEST_SRC #include <rw_exception.h> #include <driver.h> #include <rw_printf.h> #include <string.h> // for strncpy() #include <malloc.h> // for free() #include <stddef.h> // for size_t #include <stdarg.h> // for va_arg(), va_list #include <new> // for std::bad_alloc /**************************************************************************/ Exception::~Exception () { } /**************************************************************************/ struct ExceptionBase { char buf_ [256]; char* what_; ExceptionBase (); ExceptionBase (const ExceptionBase&); ~ExceptionBase (); ExceptionBase& operator= (const ExceptionBase&); private: void free_ (); }; ExceptionBase::ExceptionBase () : what_ (buf_) { buf_ [0] = '\0'; } ExceptionBase::ExceptionBase (const ExceptionBase& ex) : what_ (buf_) { *this = ex; } ExceptionBase::~ExceptionBase () { free_ (); } ExceptionBase& ExceptionBase::operator= (const ExceptionBase& ex) { if (&ex != this) { free_ (); if (ex.buf_ != ex.what_) { what_ = strdup (ex.what_); if (!what_) { const size_t maxlen = sizeof (buf_) - 1; what_ = buf_; strncpy (buf_, ex.what_, maxlen); buf_ [maxlen] = '\0'; } } else strncpy (buf_, ex.buf_, sizeof (buf_)); } return *this; } void ExceptionBase::free_ () { if (buf_ != what_) { free (what_); what_ = buf_; } } /**************************************************************************/ struct BadAlloc : std::bad_alloc, ExceptionBase { ~BadAlloc () _THROWS (()) {} const char* what () const _THROWS (()) { return what_; } }; /**************************************************************************/ struct StreamException : Exception, ExceptionBase { StreamException () : Exception (ex_stream) { } const char* what () const { return what_; } }; /**************************************************************************/ _TEST_EXPORT int rw_vasnprintf (char**, size_t*, const char*, va_list); /**************************************************************************/ static int _rw_format (char** pbuf, size_t* pbufsize, const char* file, int line, const char* function, const char* fmt, va_list va) { const int nchars1 = function ? rw_asnprintf (pbuf, pbufsize, "\"%s\", %d, \"%s\" ", file, line, function) : rw_asnprintf (pbuf, pbufsize, "\"%s\", %d, ", file, line); if (0 > nchars1) return nchars1; char *tmpbuf = 0; size_t tmpsize = 0; const int nchars2 = rw_vasnprintf (&tmpbuf, &tmpsize, fmt, va); if (0 > nchars2) { free (tmpbuf); return nchars1; } const int nchars3 = rw_asnprintf (pbuf, pbufsize, "%{+}%s", tmpbuf); free (tmpbuf); return 0 > nchars3 ? nchars1 : nchars1 + nchars3; } // str should be allocated by malloc() call // str shouldn't be free after call _rw_init_exception() static void _rw_init_exception (ExceptionBase& ex, char* str, size_t nchars) { if (nchars < sizeof (ex.buf_)) { memcpy (ex.buf_, str, nchars); ex.buf_ [nchars] = '\0'; free (str); } else ex.what_ = str; } _TEST_EXPORT void rw_throw (ExceptionId exid, const char *file, int line, const char *function, const char *fmt, ...) { // format string char* buf = 0; size_t bufsize = 0; va_list va; va_start (va, fmt); const int nchars = _rw_format (&buf, &bufsize, file, line, function, fmt, va); va_end (va); switch (exid) { case ex_stream: { StreamException ex; _rw_init_exception (ex, buf, nchars); throw ex; } case ex_bad_alloc: { BadAlloc ex; _rw_init_exception (ex, buf, nchars); throw ex; } default: free (buf); throw ex_unknown; } }
