From 0ddd3e7f2f2ee52ec9a5aabfed1bc24ebe246273 Mon Sep 17 00:00:00 2001 From: James Turner Date: Fri, 19 Feb 2021 17:38:03 +0000 Subject: [PATCH] Add sg_location to all exceptions, add report flag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move sg_location member up to the base clase, since it’s potentially useful in more types. Allow suppression of the report callback when the exception is thrown --- simgear/structure/exception.cxx | 267 +++++++++++++------------------- simgear/structure/exception.hxx | 122 ++++++++------- 2 files changed, 173 insertions(+), 216 deletions(-) diff --git a/simgear/structure/exception.cxx b/simgear/structure/exception.cxx index fbf93495..e19bb2d7 100644 --- a/simgear/structure/exception.cxx +++ b/simgear/structure/exception.cxx @@ -19,66 +19,65 @@ static ThrowCallback static_callback; // Implementation of sg_location class. //////////////////////////////////////////////////////////////////////// -sg_location::sg_location () - : _line(-1), - _column(-1), - _byte(-1) +sg_location::sg_location() noexcept + : _line(-1), + _column(-1), + _byte(-1) { _path[0] = '\0'; } -sg_location::sg_location (const std::string& path, int line, int column) - : _line(line), - _column(column), - _byte(-1) +sg_location::sg_location(const std::string& path, int line, int column) noexcept + : _line(line), + _column(column), + _byte(-1) { setPath(path.c_str()); } -sg_location::sg_location (const SGPath& path, int line, int column) -: _line(line), -_column(column), -_byte(-1) +sg_location::sg_location(const SGPath& path, int line, int column) noexcept + : _line(line), + _column(column), + _byte(-1) { setPath(path.utf8Str().c_str()); } -sg_location::sg_location (const char* path, int line, int column) - : _line(line), - _column(column), - _byte(-1) +sg_location::sg_location(const char* path, int line, int column) noexcept + : _line(line), + _column(column), + _byte(-1) { setPath(path); } -void sg_location::setPath(const char *path) { - if (path) { - strncpy(_path, path, max_path); - _path[max_path -1] = '\0'; - } else { - _path[0] = '\0'; - } +void sg_location::setPath(const char* path) noexcept +{ + if (path) { + strncpy(_path, path, max_path); + _path[max_path - 1] = '\0'; + } else { + _path[0] = '\0'; + } } -const char *sg_location::getPath() const { return _path; } +const char* sg_location::getPath() const noexcept { return _path; } -int sg_location::getLine() const { return _line; } +int sg_location::getLine() const noexcept { return _line; } -int -sg_location::getColumn () const +int sg_location::getColumn() const noexcept { return _column; } -int -sg_location::getByte () const +int sg_location::getByte() const noexcept { return _byte; } std::string -sg_location::asString () const +sg_location::asString() const noexcept { std::ostringstream out; if (_path[0]) { @@ -97,46 +96,48 @@ sg_location::asString () const return out.str(); } -bool sg_location::isValid() const { return strlen(_path) > 0; } +bool sg_location::isValid() const noexcept { return strlen(_path) > 0; } //////////////////////////////////////////////////////////////////////// // Implementation of sg_throwable class. //////////////////////////////////////////////////////////////////////// -sg_throwable::sg_throwable () +sg_throwable::sg_throwable() noexcept { _message[0] = '\0'; _origin[0] = '\0'; } -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 () +sg_throwable::sg_throwable(const char* message, const char* origin, + const sg_location& loc, bool report) noexcept : _location(loc) { + setMessage(message); + setOrigin(origin); + + if (static_callback && report) { + static_callback(_message, _origin, loc); + } } const char* -sg_throwable::getMessage () const +sg_throwable::getMessage() const noexcept { return _message; } -const std::string -sg_throwable::getFormattedMessage () const +std::string +sg_throwable::getFormattedMessage() const noexcept { - return std::string(getMessage()); + std::string ret = getMessage(); + const std::string loc = getLocation().asString(); + if (loc.length()) { + ret += "\n at "; + ret += loc; + } + return ret; } -void -sg_throwable::setMessage (const char* message) +void sg_throwable::setMessage(const char* message) noexcept { strncpy(_message, message, MAX_TEXT_LEN); _message[MAX_TEXT_LEN - 1] = '\0'; @@ -144,13 +145,12 @@ sg_throwable::setMessage (const char* message) } const char* -sg_throwable::getOrigin () const +sg_throwable::getOrigin() const noexcept { return _origin; } -void -sg_throwable::setOrigin (const char* origin) +void sg_throwable::setOrigin(const char* origin) noexcept { if (origin) { strncpy(_origin, origin, MAX_TEXT_LEN); @@ -170,27 +170,27 @@ const char* sg_throwable::what() const noexcept } } - +sg_location sg_throwable::getLocation() const noexcept +{ + return _location; +} + +void sg_throwable::setLocation(const sg_location& location) noexcept +{ + _location = location; +} + //////////////////////////////////////////////////////////////////////// // Implementation of sg_error class. //////////////////////////////////////////////////////////////////////// -sg_error::sg_error () - : sg_throwable () +sg_error::sg_error(const char* message, const char* origin, bool report) noexcept + : sg_throwable(message, origin, {}, report) { } -sg_error::sg_error (const char* message, const char *origin) - : sg_throwable(message, origin) -{ -} - -sg_error::sg_error(const std::string& message, const std::string& origin) - : sg_throwable(message.c_str(), origin.c_str()) -{ -} - -sg_error::~sg_error () +sg_error::sg_error(const std::string& message, const std::string& origin, bool report) noexcept + : sg_throwable(message.c_str(), origin.c_str(), {}, report) { } @@ -198,121 +198,81 @@ sg_error::~sg_error () // Implementation of sg_exception class. //////////////////////////////////////////////////////////////////////// -sg_exception::sg_exception () - : sg_throwable () -{ -} +sg_exception::sg_exception(const char* message, const char* origin, + const sg_location& loc, bool report) noexcept + : sg_throwable(message, origin, loc, report) {} -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, const sg_location& loc, + bool report) noexcept + : sg_throwable(message.c_str(), origin.c_str(), loc, report) {} -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 () -{ -} //////////////////////////////////////////////////////////////////////// // Implementation of sg_io_exception. //////////////////////////////////////////////////////////////////////// -sg_io_exception::sg_io_exception () - : sg_exception() +sg_io_exception::sg_io_exception(const char* message, const char* origin, bool report) + : sg_exception(message, origin, {}, report) { } -sg_io_exception::sg_io_exception (const char* message, const char* origin) - : sg_exception(message, origin) +sg_io_exception::sg_io_exception(const char* message, + const sg_location& location, + const char* origin, + bool report) + : sg_exception(message, origin, location, report) {} + +sg_io_exception::sg_io_exception(const std::string& message, + const std::string& origin, + bool report) + : sg_exception(message, origin, {}, report) { } -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 ) - : sg_exception(message, origin) -{ -} - -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 () -{ -} - -const std::string -sg_io_exception::getFormattedMessage () const -{ - std::string ret = getMessage(); - std::string loc = getLocation().asString(); - if (loc.length()) { - ret += "\n at "; - ret += loc; - } - return ret; -} - -const sg_location & -sg_io_exception::getLocation () const -{ - return _location; -} - -void -sg_io_exception::setLocation (const sg_location &location) -{ - _location = location; -} +sg_io_exception::sg_io_exception(const std::string& message, + const sg_location& location, + const std::string& origin, + bool report) + : sg_exception(message, origin, location, report) {} - //////////////////////////////////////////////////////////////////////// // Implementation of sg_format_exception. //////////////////////////////////////////////////////////////////////// -sg_format_exception::sg_format_exception () - : sg_exception() +sg_format_exception::sg_format_exception() noexcept + : sg_exception() { _text[0] = '\0'; } -sg_format_exception::sg_format_exception (const char* message, - const char* text, - const char* origin) - : sg_exception(message, origin) +sg_format_exception::sg_format_exception(const char* message, + const char* text, + const char* origin, + bool report) + : sg_exception(message, origin, {}, report) { setText(text); } -sg_format_exception::sg_format_exception( const std::string& message, - const std::string& text, - const std::string& origin ) - : sg_exception(message, origin) +sg_format_exception::sg_format_exception(const std::string& message, + const std::string& text, + const std::string& origin, + bool report) + : sg_exception(message, origin, {}, report) { setText(text.c_str()); } -sg_format_exception::~sg_format_exception () -{ -} const char* -sg_format_exception::getText () const +sg_format_exception::getText() const noexcept { return _text; } -void -sg_format_exception::setText (const char* text) +void sg_format_exception::setText(const char* text) noexcept { if (text) { strncpy(_text, text, MAX_TEXT_LEN); @@ -328,26 +288,19 @@ sg_format_exception::setText (const char* text) // Implementation of sg_range_exception. //////////////////////////////////////////////////////////////////////// -sg_range_exception::sg_range_exception () - : sg_exception() -{ -} - -sg_range_exception::sg_range_exception (const char* message, - const char* origin) - : sg_exception(message, origin) +sg_range_exception::sg_range_exception(const char* message, + const char* origin, bool report) + : sg_exception(message, origin, {}, report) { } sg_range_exception::sg_range_exception(const std::string& message, - const std::string& origin) - : sg_exception(message, origin) + const std::string& origin, + bool report) + : sg_exception(message, origin, {}, report) { } -sg_range_exception::~sg_range_exception () -{ -} //////////////////////////////////////////////////////////////////////// diff --git a/simgear/structure/exception.hxx b/simgear/structure/exception.hxx index bf28559e..8d606b0e 100644 --- a/simgear/structure/exception.hxx +++ b/simgear/structure/exception.hxx @@ -28,23 +28,23 @@ class sg_location { public: enum {max_path = 1024}; - sg_location (); - 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); + sg_location() noexcept; + sg_location(const std::string& path, int line = -1, int column = -1) noexcept; + sg_location(const SGPath& path, int line = -1, int column = -1) noexcept; + explicit sg_location(const char* path, int line = -1, int column = -1) noexcept; ~sg_location() = default; - const char *getPath() const; - int getLine() const; - int getColumn() const; - int getByte() const; + const char* getPath() const noexcept; + int getLine() const noexcept; + int getColumn() const noexcept; + int getByte() const noexcept; - std::string asString() const; - bool isValid() const; + std::string asString() const noexcept; + bool isValid() const noexcept; -private: - void setPath(const char *p); + private: + void setPath(const char* p) noexcept; char _path[max_path]; int _line; @@ -60,20 +60,26 @@ class sg_throwable : public std::exception { public: enum {MAX_TEXT_LEN = 1024}; - sg_throwable (); - sg_throwable(const char *message, const char *origin = 0, - const sg_location &loc = {}); + sg_throwable() noexcept; + sg_throwable(const char* message, const char* origin = 0, + const sg_location& loc = {}, bool report = true) noexcept; - virtual ~sg_throwable (); - virtual const char* getMessage () const; - virtual const std::string getFormattedMessage () const; - virtual void setMessage (const char* message); - virtual const char* getOrigin () const; - virtual void setOrigin (const char *origin); + virtual ~sg_throwable() noexcept = default; + + virtual const char* getMessage() const noexcept; + std::string getFormattedMessage() const noexcept; + virtual void setMessage(const char* message) noexcept; + virtual const char* getOrigin() const noexcept; + virtual void setOrigin(const char* origin) noexcept; virtual const char* what() const noexcept; -private: + + sg_location getLocation() const noexcept; + void setLocation(const sg_location& location) noexcept; + + private: char _message[MAX_TEXT_LEN]; char _origin[MAX_TEXT_LEN]; + sg_location _location; }; @@ -90,10 +96,10 @@ private: 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 = {}); - virtual ~sg_error (); + sg_error() noexcept = default; + sg_error(const char* message, const char* origin = 0, bool report = true) noexcept; + sg_error(const std::string& message, const std::string& origin = {}, bool report = true) noexcept; + virtual ~sg_error() noexcept = default; }; @@ -114,12 +120,12 @@ public: class sg_exception : public sg_throwable { public: - sg_exception (); - 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 (); + sg_exception() noexcept = default; + sg_exception(const char* message, const char* origin = 0, + const sg_location& loc = {}, bool report = true) noexcept; + sg_exception(const std::string& message, const std::string& = {}, + const sg_location& loc = {}, bool report = true) noexcept; + virtual ~sg_exception() noexcept = default; }; @@ -137,20 +143,15 @@ public: class sg_io_exception : public sg_exception { public: - sg_io_exception (); - sg_io_exception (const char* message, const char* origin = 0); - sg_io_exception (const char* message, const sg_location &location, - const char* origin = 0); - sg_io_exception (const std::string &message, const std::string &origin = ""); - sg_io_exception (const std::string &message, const sg_location &location, - const std::string &origin = ""); + sg_io_exception() noexcept = default; + sg_io_exception(const char* message, const char* origin = 0, bool report = true); + sg_io_exception(const char* message, const sg_location& location, + const char* origin = 0, bool report = true); + sg_io_exception(const std::string& message, const std::string& origin = {}, bool report = true); + sg_io_exception(const std::string& message, const sg_location& location, + const std::string& origin = {}, bool report = true); - virtual ~sg_io_exception (); - virtual const std::string getFormattedMessage () const; - virtual const sg_location &getLocation () const; - virtual void setLocation (const sg_location &location); -private: - sg_location _location; + virtual ~sg_io_exception() noexcept = default; }; @@ -168,14 +169,15 @@ private: class sg_format_exception : public sg_exception { public: - sg_format_exception (); - sg_format_exception (const char* message, const char* text, - const char* origin = 0); - sg_format_exception (const std::string& message, const std::string& text, - const std::string& origin = ""); - virtual ~sg_format_exception (); - virtual const char* getText () const; - virtual void setText (const char* text); + sg_format_exception() noexcept; + sg_format_exception(const char* message, const char* text, + const char* origin = 0, bool report = true); + sg_format_exception(const std::string& message, const std::string& text, + const std::string& origin = {}, bool report = true); + + const char* getText() const noexcept; + void setText(const char* text) noexcept; + private: char _text[MAX_TEXT_LEN]; }; @@ -193,12 +195,14 @@ private: class sg_range_exception : public sg_exception { public: - sg_range_exception (); - sg_range_exception (const char* message, - const char* origin = 0); - sg_range_exception (const std::string& message, - const std::string& origin = ""); - virtual ~sg_range_exception (); + sg_range_exception() noexcept = default; + sg_range_exception(const char* message, + const char* origin = 0, + bool report = true); + sg_range_exception(const std::string& message, + const std::string& origin = {}, + bool report = true); + virtual ~sg_range_exception() noexcept = default; }; using ThrowCallback = std::function