Add sg_location to all exceptions, add report flag

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
This commit is contained in:
James Turner 2021-02-19 17:38:03 +00:00 committed by James Turner
parent fe96298be5
commit 0ddd3e7f2f
2 changed files with 173 additions and 216 deletions

View File

@ -19,7 +19,7 @@ static ThrowCallback static_callback;
// Implementation of sg_location class.
////////////////////////////////////////////////////////////////////////
sg_location::sg_location ()
sg_location::sg_location() noexcept
: _line(-1),
_column(-1),
_byte(-1)
@ -27,7 +27,7 @@ sg_location::sg_location ()
_path[0] = '\0';
}
sg_location::sg_location (const std::string& path, int line, int column)
sg_location::sg_location(const std::string& path, int line, int column) noexcept
: _line(line),
_column(column),
_byte(-1)
@ -35,15 +35,15 @@ sg_location::sg_location (const std::string& path, int line, int column)
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)
sg_location::sg_location(const char* path, int line, int column) noexcept
: _line(line),
_column(column),
_byte(-1)
@ -51,34 +51,33 @@ sg_location::sg_location (const char* path, int line, int column)
setPath(path);
}
void sg_location::setPath(const char *path) {
void sg_location::setPath(const char* path) noexcept
{
if (path) {
strncpy(_path, path, max_path);
_path[max_path -1] = '\0';
_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) {
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) {
if (static_callback && report) {
static_callback(_message, _origin, loc);
}
}
sg_throwable::~sg_throwable ()
{
}
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_format_exception::sg_format_exception() noexcept
: sg_exception()
{
_text[0] = '\0';
}
sg_format_exception::sg_format_exception (const char* message,
sg_format_exception::sg_format_exception(const char* message,
const char* text,
const char* origin)
: sg_exception(message, origin)
const char* origin,
bool report)
: sg_exception(message, origin, {}, report)
{
setText(text);
}
sg_format_exception::sg_format_exception( const std::string& message,
sg_format_exception::sg_format_exception(const std::string& message,
const std::string& text,
const std::string& origin )
: sg_exception(message, origin)
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 ()
{
}
////////////////////////////////////////////////////////////////////////

View File

@ -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<void(