/* ----------------------------------------------------------------------------- This source file is part of OGRE (Object-oriented Graphics Rendering Engine) For the latest info, see http://www.ogre3d.org/ Copyright (c) 2000-2005 The OGRE Team Also see acknowledgements in Readme.html This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA, or go to http://www.gnu.org/copyleft/lesser.txt. ----------------------------------------------------------------------------- */ #include "OgreStableHeaders.h" #include "OgreException.h" #include "OgreRoot.h" #include "OgreLogManager.h" #ifdef __BORLANDC__ #include #endif namespace Ogre { Exception* Exception::last = NULL; String Exception::msFunctionStack[ OGRE_CALL_STACK_DEPTH ]; ushort Exception::msStackDepth = 0; Exception::Exception(int num, const String& desc, const String& src) : line( 0 ), number( num ), description( desc ), source( src ), stackDepth( msStackDepth ) { // Log this error - not any more, allow catchers to do it //LogManager::getSingleton().logMessage(this->getFullDescription()); // Set last last = this; } Exception::Exception(int num, const String& desc, const String& src, char* fil, long lin) : line( lin ), number( num ), description( desc ), source( src ), file( fil ), stackDepth( msStackDepth ) { // Log this error, mask it from debug though since it may be caught and ignored if(LogManager::getSingletonPtr()) LogManager::getSingleton().logMessage(this->getFullDescription(), LML_CRITICAL, true); // Set last last = this; } Exception::Exception(const Exception& rhs) : line( rhs.line ), number( rhs.number ), description( rhs.description ), source( rhs.source ), file( rhs.file ) { } void Exception::operator = ( const Exception& rhs ) { description = rhs.description; number = rhs.number; source = rhs.source; file = rhs.file; line = rhs.line; } String Exception::getFullDescription(void) const { StringUtil::StrStreamType desc; desc << "An exception has been thrown!\n" "\n" "-----------------------------------\nDetails:\n-----------------------------------\n" "Error #: " << number << "\nFunction: " << source << "\nDescription: " << description << ". "; if( line > 0 ) { desc << "\nFile: " << file; desc << "\nLine: " << line; } #ifdef OGRE_STACK_UNWINDING desc << "\nStack unwinding: "; /* Will cause an overflow, that's why we check that it's smaller. Also note that the call stack index may be greater than the actual call stack size - that's why we begin unrolling with the smallest of the two. */ for( ushort stackUnroll = stackDepth <= OGRE_CALL_STACK_DEPTH ? ( stackDepth - 1 ) : ( OGRE_CALL_STACK_DEPTH - 1 ); stackUnroll < stackDepth; stackUnroll-- ) { desc << msFunctionStack[ stackUnroll ]; desc << "(..) <- "; } desc << "<>"; #endif return desc.str(); } int Exception::getNumber(void) const throw() { return number; } Exception* Exception::getLastException(void) throw() { return last; } //----------------------------------------------------------------------- void Exception::_pushFunction( const String& strFuncName ) throw() { if( msStackDepth < OGRE_CALL_STACK_DEPTH ) msFunctionStack[ msStackDepth ] = strFuncName; msStackDepth++; } //----------------------------------------------------------------------- void Exception::_popFunction() throw() { msStackDepth--; } }