]> git.mxchange.org Git - simgear.git/commitdiff
overhaul sg_throwable to behave like a proper exception
authorTim Moore <timoore@redhat.com>
Wed, 4 Mar 2009 10:15:47 +0000 (11:15 +0100)
committerTim Moore <timoore@redhat.com>
Tue, 16 Jun 2009 09:11:13 +0000 (11:11 +0200)
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
simgear/structure/exception.hxx

index af9be51648c1af0a089b85170668f0442cea5959..c46a1c9636c25aac25b40dfca32469cf27385fd7 100644 (file)
@@ -7,42 +7,58 @@
 
 #include "exception.hxx"
 #include <stdio.h>
+#include <cstring>
+#include <sstream>
 
+using std::string;
 \f
 ////////////////////////////////////////////////////////////////////////
 // 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 "";
+  }
+}
 
 \f
 ////////////////////////////////////////////////////////////////////////
@@ -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 ()
+{
+}
 \f
 ////////////////////////////////////////////////////////////////////////
 // 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 ()
+{
+}
 \f
 ////////////////////////////////////////////////////////////////////////
 // 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
index d3b37834e9e8d360e3a567fb186482d93d18b551..eaf126959f5901f4482f3be686d59400b58c89f3 100644 (file)
 #ifndef __SIMGEAR_MISC_EXCEPTION_HXX
 #define __SIMGEAR_MISC_EXCEPTION_HXX 1
 
+#include <exception>
 #include <simgear/compiler.h>
 #include <string>
 
 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