/**
@class GATS_Exception
@brief Embodies the GATS_Exception base class.
@note The constructor of this class is protected meaning you can not create instances
of this class directly but rather you must derive your exception objects from
this class.
@date $Date: 2007-01-10 11:06:55 -0500 (Wed, 10 Jan 2007) $
@version $Rev$
@author
- Lance Deaver
@copyright
(©) Copyright 2006 by GATS Inc.
11864 Canon Blvd., Suite 101, Newport News, VA 23606
All Rights Reserved. No part of this software or publication may be
reproduced, stored in a retrieval system, or transmitted, in any form
or by any means, electronic, mechanical, photocopying, recording, or
otherwise without the prior written permission of GATS Inc.
@see GATS_Exception.h
@todo Add an EXPORT macro so windows users can preface functions with the decspl
when constructing DLL files.
@bug None known
$Id$
$Id$
*/
#include "GATS_Exception.h"
#include
#include
#ifdef __linux__ //Provides stack tracing options on linux platforms
#include
#endif
/**
* The GATS_Exception copy constructor.
*/
GATS_Exception::GATS_Exception(const GATS_Exception& e) throw() :
std::exception(e),
what_(e.what_ ),
filename_(e.filename_),
linenumber_(e.linenumber_)
#ifdef __linux__
,stack_(e.stack_)
#endif
{
}
/**
* Destroy a GATS_Exception object.
*/
GATS_Exception::~GATS_Exception() throw()
{
}
/**
* This is the GATS_Exception class constructor. On a linux system this constructor
* will store a stack trace that may be useful when debugging programs. Also this
* constructor receives the source filename and line number and that also can be
* useful when chasing a problem
*
* @parm[in] w A useful error message explaining the reason an exception was thrown.
* @param[in] filename The source filename throwing the exception. Usually retrieved from the __FILE__ compiler macro.
* @param[in] linenumber The line number in the source file that the exception was thrown. Usually retrieved from the __LINE__ macro.
*/
GATS_Exception::GATS_Exception(const char* w, const char* filename, const unsigned int linenumber) throw()
: what_(w), filename_(filename), linenumber_(linenumber)
{
#ifdef __linux__
// Acquire the stack trace...
void * array[25];
size_t entries = backtrace( array, sizeof( array ) / sizeof( void* ) );
char ** symbols = backtrace_symbols( array, entries );
if ( symbols == 0 ) {
// Probable out of memory condition; we'll skip
// over the full stack.
entries = 0;
}
// Store it into our Vector. We are skipping the
// top-most element, since this will be this
// constructor, which is not particularly interesting.
// We are also skipping the next line, because the
// __FILE__ and __LINE__ have that location already.
stack_.reserve( entries > 2 ? entries - 2 : 0 );
for ( size_t i = 2; i < entries; ++i ) {
stack_.push_back( symbols[i] );
}
// Free up the allocated memory.
free( symbols );
#endif
}
/**
* The GATS_Exception assignment operator
*/
GATS_Exception& GATS_Exception::operator=(const GATS_Exception& rhs) throw()
{
std::exception::operator=(rhs);
what_ = rhs.what_;
filename_ = rhs.filename_;
linenumber_=rhs.linenumber_;
#ifdef __linux__
stack_=rhs.stack_;
#endif
return *this;
}
/**
* This class will return a string containing the exception message along with the
* souce filename and linenumber where the exception occurred. On linux systems, a stack
* trace will also be appended.
*/
std::string GATS_Exception::StackTrace() const throw()
{
std::stringstream st;
st << what_ << std::endl;
st << " at " << filename_ << ": " << linenumber_ << std::endl;
#ifdef __linux__
for ( unsigned int i = 0, size = stack_.size(); i < size; ++i ) {
st << " at " << stack_[i] << std::endl;
}
#endif
return st.str();
}
/**
* This is a protected function that is declared virtual meaning it can be overloaded
* in derived classes. It defines the format of the print message when
* using the << operator for a class.
*
* @param[in] o A reference to std::ostream such as cout or a fstream.
*/
void GATS_Exception::PrintOn(std::ostream& o) const
{
o << what_ << '\n' << " at " << filename_ << ": " << linenumber_ << std::endl;
}
/**
* A overloaded << std::stream operator that provides printing of the data elements
* in the GATS_Exception class.
*/
std::ostream& operator<<( std::ostream& o, const GATS_Exception& e )
{
e.PrintOn(o);
return o;
}