From 76948416a9624ba269d2baeac294c6db0853f104 Mon Sep 17 00:00:00 2001 From: Tim Moore Date: Wed, 4 Mar 2009 11:15:47 +0100 Subject: [PATCH] overhaul sg_throwable to behave like a proper exception Make sg_throwable inherit from std::exception. change exception objects to contain C strings: exception objects should not include objects, like std::string, whose copy constructor could throw. --- simgear/structure/exception.cxx | 174 +++++++++++++++++++++----------- simgear/structure/exception.hxx | 80 ++++++++------- 2 files changed, 161 insertions(+), 93 deletions(-) diff --git a/simgear/structure/exception.cxx b/simgear/structure/exception.cxx index af9be516..c46a1c96 100644 --- a/simgear/structure/exception.cxx +++ b/simgear/structure/exception.cxx @@ -7,42 +7,58 @@ #include "exception.hxx" #include +#include +#include +using std::string; //////////////////////////////////////////////////////////////////////// // Implementation of sg_location class. //////////////////////////////////////////////////////////////////////// sg_location::sg_location () - : _path(""), - _line(-1), + : _line(-1), _column(-1), _byte(-1) { + _path[0] = '\0'; } -sg_location::sg_location (const string &path, int line, int column) - : _path(path), - _line(line), +sg_location::sg_location (const string& path, int line, int column) + : _line(line), _column(column), _byte(-1) { + setPath(path.c_str()); } -sg_location::~sg_location () +sg_location::sg_location (const char* path, int line, int column) + : _line(line), + _column(column), + _byte(-1) +{ + setPath(path); +} + +sg_location::~sg_location () throw () { } -const string & +const char* sg_location::getPath () const { return _path; } void -sg_location::setPath (const string &path) +sg_location::setPath (const char* path) { - _path = path; + if (path) { + strncpy(_path, path, MAX_PATH); + _path[MAX_PATH -1] = '\0'; + } else { + _path[0] = '\0'; + } } int @@ -84,25 +100,21 @@ sg_location::setByte (int byte) string sg_location::asString () const { - char buf[128]; - string out = ""; - if (!_path.empty()) { - out += _path; + std::ostringstream out; + if (_path[0]) { + out << _path; if (_line != -1 || _column != -1) - out += ",\n"; + out << ",\n"; } if (_line != -1) { - sprintf(buf, "line %d", _line); - out += buf; + out << "line " << _line; if (_column != -1) - out += ", "; + out << ", "; } if (_column != -1) { - sprintf(buf, "column %d", _column); - out += buf; + out << "column " << _column; } - return out; - + return out.str(); } @@ -112,22 +124,22 @@ sg_location::asString () const //////////////////////////////////////////////////////////////////////// sg_throwable::sg_throwable () - : _message(""), - _origin("") { + _message[0] = '\0'; + _origin[0] = '\0'; } -sg_throwable::sg_throwable (const string &message, const string &origin) - : _message(message), - _origin(origin) +sg_throwable::sg_throwable (const char* message, const char* origin) { + setMessage(message); + setOrigin(origin); } -sg_throwable::~sg_throwable () +sg_throwable::~sg_throwable () throw () { } -const string & +const char* sg_throwable::getMessage () const { return _message; @@ -136,27 +148,43 @@ sg_throwable::getMessage () const const string sg_throwable::getFormattedMessage () const { - return getMessage(); + return string(getMessage()); } void -sg_throwable::setMessage (const string &message) +sg_throwable::setMessage (const char* message) { - _message = message; + strncpy(_message, message, MAX_TEXT_LEN); + _message[MAX_TEXT_LEN - 1] = '\0'; + } -const string & +const char* sg_throwable::getOrigin () const { return _origin; } void -sg_throwable::setOrigin (const string &origin) +sg_throwable::setOrigin (const char* origin) { - _origin = origin; + if (origin) { + strncpy(_origin, origin, MAX_TEXT_LEN); + _origin[MAX_TEXT_LEN - 1] = '\0'; + } else { + _origin[0] = '\0'; + } } +const char* sg_throwable::what() const throw() +{ + try { + return getMessage(); + } + catch (...) { + return ""; + } +} //////////////////////////////////////////////////////////////////////// @@ -168,16 +196,19 @@ sg_error::sg_error () { } -sg_error::sg_error (const string &message, const string &origin) +sg_error::sg_error (const char* message, const char *origin) : sg_throwable(message, origin) { } -sg_error::~sg_error () +sg_error::sg_error (const string& message, const string& origin) + : sg_throwable(message.c_str(), origin.c_str()) { } - +sg_error::~sg_error () throw () +{ +} //////////////////////////////////////////////////////////////////////// // Implementation of sg_exception class. @@ -188,16 +219,19 @@ sg_exception::sg_exception () { } -sg_exception::sg_exception (const string &message, const string &origin) +sg_exception::sg_exception (const char* message, const char* origin) : sg_throwable(message, origin) { } -sg_exception::~sg_exception () +sg_exception::sg_exception (const string& message, const string& origin) + : sg_throwable(message.c_str(), origin.c_str()) { } - +sg_exception::~sg_exception () throw () +{ +} //////////////////////////////////////////////////////////////////////// // Implementation of sg_io_exception. @@ -208,20 +242,25 @@ sg_io_exception::sg_io_exception () { } -sg_io_exception::sg_io_exception (const string &message, const string &origin) +sg_io_exception::sg_io_exception (const char* message, const char* origin) : sg_exception(message, origin) { } -sg_io_exception::sg_io_exception (const string &message, +sg_io_exception::sg_io_exception (const char* message, const sg_location &location, - const string &origin) + const char* origin) : sg_exception(message, origin), _location(location) { } -sg_io_exception::~sg_io_exception () +sg_io_exception::sg_io_exception (const string& message, const string& origin) + : sg_exception(message, origin) +{ +} + +sg_io_exception::~sg_io_exception () throw () { } @@ -256,33 +295,46 @@ sg_io_exception::setLocation (const sg_location &location) //////////////////////////////////////////////////////////////////////// sg_format_exception::sg_format_exception () - : sg_exception(), - _text("") + : sg_exception() { + _text[0] = '\0'; } -sg_format_exception::sg_format_exception (const string &message, - const string &text, - const string &origin) - : sg_exception(message, origin), - _text(text) +sg_format_exception::sg_format_exception (const char* message, + const char* text, + const char* origin) + : sg_exception(message, origin) { + setText(text); } -sg_format_exception::~sg_format_exception () +sg_format_exception::sg_format_exception (const string& message, + const string& text, + const string& origin) + : sg_exception(message, origin) { + setText(text.c_str()); } -const string & +sg_format_exception::~sg_format_exception () throw () +{ +} + +const char* sg_format_exception::getText () const { return _text; } void -sg_format_exception::setText (const string &text) +sg_format_exception::setText (const char* text) { - _text = text; + if (text) { + strncpy(_text, text, MAX_TEXT_LEN); + _text[MAX_TEXT_LEN] = '\0'; + } else { + _text[0] = '\0'; + } } @@ -296,15 +348,19 @@ sg_range_exception::sg_range_exception () { } -sg_range_exception::sg_range_exception (const string &message, - const string &origin) +sg_range_exception::sg_range_exception (const char* message, + const char* origin) : sg_exception(message, origin) { } -sg_range_exception::~sg_range_exception () +sg_range_exception::sg_range_exception(const string& message, + const string& origin) + : sg_exception(message, origin) { } - +sg_range_exception::~sg_range_exception () throw () +{ +} // end of exception.cxx diff --git a/simgear/structure/exception.hxx b/simgear/structure/exception.hxx index d3b37834..eaf12695 100644 --- a/simgear/structure/exception.hxx +++ b/simgear/structure/exception.hxx @@ -10,12 +10,12 @@ #ifndef __SIMGEAR_MISC_EXCEPTION_HXX #define __SIMGEAR_MISC_EXCEPTION_HXX 1 +#include #include #include using std::string; - /** * Information encapsulating a single location in an external resource * @@ -26,20 +26,22 @@ using std::string; class sg_location { public: + enum {MAX_PATH = 1024}; sg_location (); - sg_location (const string &path, int line = -1, int column = -1); - virtual ~sg_location (); - virtual const string &getPath () const; - virtual void setPath (const string &path); + sg_location(const std::string& path, int line = -1, int column = -1); + explicit sg_location(const char* path, int line = -1, int column = -1); + virtual ~sg_location() throw (); + 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 string asString () const; + virtual std::string asString () const; private: - string _path; + char _path[MAX_PATH]; int _line; int _column; int _byte; @@ -49,20 +51,22 @@ private: /** * Abstract base class for all throwables. */ -class sg_throwable +class sg_throwable : public std::exception { public: + enum {MAX_TEXT_LEN = 1024}; sg_throwable (); - sg_throwable (const string &message, const string &origin = ""); - virtual ~sg_throwable (); - virtual const string &getMessage () const; - virtual const string getFormattedMessage () const; - virtual void setMessage (const string &message); - virtual const string &getOrigin () const; - virtual void setOrigin (const string &origin); + sg_throwable (const char* message, const char* origin = 0); + virtual ~sg_throwable () throw (); + 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 const char* what() const throw(); private: - string _message; - string _origin; + char _message[MAX_TEXT_LEN]; + char _origin[MAX_TEXT_LEN]; }; @@ -80,8 +84,9 @@ class sg_error : public sg_throwable { public: sg_error (); - sg_error (const string &message, const string &origin = ""); - virtual ~sg_error (); + sg_error (const char* message, const char* origin = 0); + sg_error (const std::string& message, const std::string& origin = ""); + virtual ~sg_error () throw (); }; @@ -103,8 +108,9 @@ class sg_exception : public sg_throwable { public: sg_exception (); - sg_exception (const string &message, const string &origin = ""); - virtual ~sg_exception (); + sg_exception (const char* message, const char* origin = 0); + sg_exception (const std::string& message, const std::string& = ""); + virtual ~sg_exception () throw (); }; @@ -123,11 +129,12 @@ class sg_io_exception : public sg_exception { public: sg_io_exception (); - sg_io_exception (const string &message, const string &origin = ""); - sg_io_exception (const string &message, const sg_location &location, - const string &origin = ""); - virtual ~sg_io_exception (); - virtual const string getFormattedMessage () const; + 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 = ""); + virtual ~sg_io_exception () throw (); + virtual const std::string getFormattedMessage () const; virtual const sg_location &getLocation () const; virtual void setLocation (const sg_location &location); private: @@ -150,13 +157,15 @@ class sg_format_exception : public sg_exception { public: sg_format_exception (); - sg_format_exception (const string &message, const string &text, - const string &origin = ""); - virtual ~sg_format_exception (); - virtual const string &getText () const; - virtual void setText (const string &text); + 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 () throw (); + virtual const char* getText () const; + virtual void setText (const char* text); private: - string _text; + char _text[MAX_TEXT_LEN]; }; @@ -173,8 +182,11 @@ class sg_range_exception : public sg_exception { public: sg_range_exception (); - sg_range_exception (const string &message, const string &origin = ""); - virtual ~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 () throw (); }; #endif -- 2.39.5