/* This file is part of MAUS: http://micewww.pp.rl.ac.uk/projects/maus
*
* MAUS is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* MAUS 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MAUS. If not, see .
*
*/
#ifndef SRC_COMMON_CPP_UTILS_EXCEPTION_HH
#define SRC_COMMON_CPP_UTILS_EXCEPTION_HH 1
#include
#include
#include
#include
#include
namespace MAUS {
/** MAUS exception class
*
* Exception has a severity (exceptionLevel), an error message and a
* location. Also function to return the stack trace (gcc only).
*
* If you aren't using gcc, you need to define NO_STACKTRACE at compile time
*
* Note the throw() directives are there to explicitly declare that we cannot
* throw an exception in this stuff
*/
class Exception : public std::exception {
public:
/** ExceptionLevel enumerates the severity of the exception.
*
* I use an enumeration to distinguish between different error levels.
* - nonRecoverable means the internal state of the programme is no longer
* well-defined i.e. some memory problem or so.
* - recoverable means that in principle we could keep on running, although
* most of the time this results in end of run (usually indicates typo in
* an input file).
* If we start doing GUIs, then the distinction becomes important. Most stuff
* should be recoverable.
*/
enum exceptionLevel {recoverable, nonRecoverable};
/** constructor - with error level, error message and location
*
* note this makes a stack trace which can be slow.
*/
Exception(exceptionLevel level, std::string errorMessage, std::string location)
throw();
/** constructor - does nothing */
Exception() throw();
/** destructor - does nothing */
~Exception() throw() {}
/** Return char buffer of message+" at "+location
*
* Memory remains owned by Exception
*/
const char* what() const throw() {return &_what[0];}
/** Print the error message and location
*
* Prints to error message to Squeak::mout(Squeak::error) and Location to
* Squeak::mout(Squeak::debug)
*/
void Print();
/** Get the severity of the exception */
inline exceptionLevel GetErrorLevel() const {return _level;}
/** Get the error message (as defined by constructor) */
inline std::string GetMessage() const {return _message;}
/** Set the error message */
inline void SetMessage(std::string new_message);
/** Get the location (as defined by Exception constructor) of the error */
std::string GetLocation() const {return _location;}
/** Return the stack trace if it was stored */
std::string GetStackTrace() const {return _stacktrace;}
/** Gcc-specific code to recover the stack trace as a string.
*
* Will skip traces below skipTrace (so, for example, if we want to know
* where the Exception was thrown we might set skipTrace to 2, to skip
* MakeStackTrace and Exception constructor).
*/
static std::string MakeStackTrace(size_t skipTrace);
/** Set that it makes a stack trace on exception */
static void SetWillDoStackTrace(bool willDoStackTrace);
/** Return whether makes a stack trace on exception */
static bool GetWillDoStackTrace();
private:
inline void SetWhat(std::string what_str);
static const size_t _maxStackSize;
static bool _willDoStackTrace;
std::string _message;
std::string _location;
std::string _stacktrace;
std::vector _what;
exceptionLevel _level;
};
void Exception::SetMessage(std::string new_message) {
_message = new_message;
SetWhat(_message+" at "+_location);
}
void Exception::SetWhat(std::string what_str) {
_what = std::vector(what_str.size()+1);
snprintf(&_what[0], what_str.size()+1, "%s", what_str.c_str());
}
}
#endif