diff --git a/simgear/structure/exception.cxx b/simgear/structure/exception.cxx index 3a6d8f32..fbf93495 100644 --- a/simgear/structure/exception.cxx +++ b/simgear/structure/exception.cxx @@ -13,6 +13,8 @@ #include +static ThrowCallback static_callback; + //////////////////////////////////////////////////////////////////////// // Implementation of sg_location class. //////////////////////////////////////////////////////////////////////// @@ -49,19 +51,7 @@ sg_location::sg_location (const char* path, int line, int column) setPath(path); } -sg_location::~sg_location () -{ -} - -const char* -sg_location::getPath () const -{ - return _path; -} - -void -sg_location::setPath (const char* path) -{ +void sg_location::setPath(const char *path) { if (path) { strncpy(_path, path, max_path); _path[max_path -1] = '\0'; @@ -70,17 +60,9 @@ sg_location::setPath (const char* path) } } -int -sg_location::getLine () const -{ - return _line; -} +const char *sg_location::getPath() const { return _path; } -void -sg_location::setLine (int line) -{ - _line = line; -} +int sg_location::getLine() const { return _line; } int sg_location::getColumn () const @@ -88,11 +70,6 @@ sg_location::getColumn () const return _column; } -void -sg_location::setColumn (int column) -{ - _column = column; -} int sg_location::getByte () const @@ -100,12 +77,6 @@ sg_location::getByte () const return _byte; } -void -sg_location::setByte (int byte) -{ - _byte = byte; -} - std::string sg_location::asString () const { @@ -126,8 +97,8 @@ sg_location::asString () const return out.str(); } +bool sg_location::isValid() const { return strlen(_path) > 0; } - //////////////////////////////////////////////////////////////////////// // Implementation of sg_throwable class. //////////////////////////////////////////////////////////////////////// @@ -138,10 +109,14 @@ sg_throwable::sg_throwable () _origin[0] = '\0'; } -sg_throwable::sg_throwable (const char* message, const char* origin) -{ +sg_throwable::sg_throwable(const char *message, const char *origin, + const sg_location &loc) { setMessage(message); setOrigin(origin); + + if (static_callback) { + static_callback(_message, _origin, loc); + } } sg_throwable::~sg_throwable () @@ -228,16 +203,13 @@ sg_exception::sg_exception () { } -sg_exception::sg_exception (const char* message, const char* origin) - : sg_throwable(message, origin) -{ -} +sg_exception::sg_exception(const char *message, const char *origin, + const sg_location &loc) + : sg_throwable(message, origin, loc) {} -sg_exception::sg_exception( const std::string& message, - const std::string& origin ) - : sg_throwable(message.c_str(), origin.c_str()) -{ -} +sg_exception::sg_exception(const std::string &message, + const std::string &origin, const sg_location &loc) + : sg_throwable(message.c_str(), origin.c_str(), loc) {} sg_exception::~sg_exception () { @@ -257,13 +229,10 @@ sg_io_exception::sg_io_exception (const char* message, const char* origin) { } -sg_io_exception::sg_io_exception (const char* message, - const sg_location &location, - const char* origin) - : sg_exception(message, origin), - _location(location) -{ -} +sg_io_exception::sg_io_exception(const char *message, + const sg_location &location, + const char *origin) + : sg_exception(message, origin, location), _location(location) {} sg_io_exception::sg_io_exception( const std::string& message, const std::string& origin ) @@ -271,13 +240,10 @@ sg_io_exception::sg_io_exception( const std::string& message, { } -sg_io_exception::sg_io_exception( const std::string& message, - const sg_location &location, - const std::string& origin ) - : sg_exception(message, origin), - _location(location) -{ -} +sg_io_exception::sg_io_exception(const std::string &message, + const sg_location &location, + const std::string &origin) + : sg_exception(message, origin, location), _location(location) {} sg_io_exception::~sg_io_exception () { @@ -382,4 +348,9 @@ sg_range_exception::sg_range_exception(const std::string& message, sg_range_exception::~sg_range_exception () { } + +//////////////////////////////////////////////////////////////////////// + +void setThrowCallback(ThrowCallback cb) { static_callback = cb; } + // end of exception.cxx diff --git a/simgear/structure/exception.hxx b/simgear/structure/exception.hxx index e9f6d65c..bf28559e 100644 --- a/simgear/structure/exception.hxx +++ b/simgear/structure/exception.hxx @@ -11,6 +11,7 @@ #define __SIMGEAR_MISC_EXCEPTION_HXX 1 #include +#include #include #include @@ -31,17 +32,20 @@ public: sg_location(const std::string& path, int line = -1, int column = -1); sg_location(const SGPath& path, int line = -1, int column = -1); explicit sg_location(const char* path, int line = -1, int column = -1); - virtual ~sg_location(); - virtual const char* getPath() const; - virtual void setPath (const char* path); - virtual int getLine () const; - virtual void setLine (int line); - virtual int getColumn () const; - virtual void setColumn (int column); - virtual int getByte () const; - virtual void setByte (int byte); - virtual std::string asString () const; + + ~sg_location() = default; + + const char *getPath() const; + int getLine() const; + int getColumn() const; + int getByte() const; + + std::string asString() const; + bool isValid() const; + private: + void setPath(const char *p); + char _path[max_path]; int _line; int _column; @@ -57,7 +61,9 @@ class sg_throwable : public std::exception public: enum {MAX_TEXT_LEN = 1024}; sg_throwable (); - sg_throwable (const char* message, const char* origin = 0); + sg_throwable(const char *message, const char *origin = 0, + const sg_location &loc = {}); + virtual ~sg_throwable (); virtual const char* getMessage () const; virtual const std::string getFormattedMessage () const; @@ -86,7 +92,7 @@ class sg_error : public sg_throwable public: sg_error (); sg_error (const char* message, const char* origin = 0); - sg_error (const std::string& message, const std::string& origin = ""); + sg_error(const std::string &message, const std::string &origin = {}); virtual ~sg_error (); }; @@ -109,8 +115,10 @@ class sg_exception : public sg_throwable { public: sg_exception (); - sg_exception (const char* message, const char* origin = 0); - sg_exception (const std::string& message, const std::string& = ""); + sg_exception(const char *message, const char *origin = 0, + const sg_location &loc = {}); + sg_exception(const std::string &message, const std::string & = {}, + const sg_location &loc = {}); virtual ~sg_exception (); }; @@ -193,6 +201,17 @@ public: virtual ~sg_range_exception (); }; +using ThrowCallback = std::function; + +/** + * @brief Specify a callback to be invoked when an exception is created. + * + * This is used to capture a stack-trace for our crash/error reporting system, + * if a callback is defined + */ +void setThrowCallback(ThrowCallback cb); + #endif // end of exception.hxx