summaryrefslogtreecommitdiff
path: root/includes/Exceptions.h
diff options
context:
space:
mode:
authorPixel <pixel@nobis-crew.org>2011-12-04 01:19:09 -0800
committerPixel <pixel@nobis-crew.org>2011-12-04 01:20:10 -0800
commitd440c3f50a918a932293ad98bcec96eaa4683222 (patch)
tree33e8e42a8e4506ae9da70cdb44dd133bde7f7219 /includes/Exceptions.h
parente5577eb7a643ce7885e5d14660a6d24254161622 (diff)
Reworked some things in the architecture, mainly exceptions and asserts.
-) Removed Assert() -) Added AAssert(), IAssert(), RAssert(), TAssert() and Failure() -) Reworked all asserts in the code, and added meaningful messages to them. -) Changed the way the startup code is generated; BALAU_STARTUP is no longer necessary.
Diffstat (limited to 'includes/Exceptions.h')
-rw-r--r--includes/Exceptions.h90
1 files changed, 77 insertions, 13 deletions
diff --git a/includes/Exceptions.h b/includes/Exceptions.h
index c397265..1f65b12 100644
--- a/includes/Exceptions.h
+++ b/includes/Exceptions.h
@@ -1,5 +1,6 @@
#pragma once
+#include <stdarg.h>
#include <typeinfo>
#include <cxxabi.h>
#include <BString.h>
@@ -9,11 +10,12 @@ namespace Balau {
class GeneralException {
public:
- GeneralException(const char * msg) : m_msg(::strdup(msg)) { genTrace(); }
- GeneralException(const String & msg) : m_msg(msg.strdup()) { genTrace(); }
- GeneralException(const GeneralException & e) : m_msg(strdup(e.m_msg)), m_trace(e.m_trace) { }
+ GeneralException(const char * msg, const char * details = NULL) : m_msg(::strdup(msg)) { setDetails(details); genTrace(); }
+ GeneralException(const String & msg, const char * details = NULL) : m_msg(msg.strdup()) { setDetails(details); genTrace(); }
+ GeneralException(const GeneralException & e) : m_msg(strdup(e.m_msg)), m_trace(e.m_trace) { setDetails(e.m_details); }
~GeneralException() { if (m_msg) free(m_msg); }
const char * getMsg() const { return m_msg; }
+ const char * getDetails() const { return m_details; }
const std::vector<String> getTrace() const { return m_trace; }
protected:
@@ -23,37 +25,78 @@ class GeneralException {
private:
char * m_msg;
+ char * m_details;
std::vector<String> m_trace;
+
+ void setDetails(const char * details) {
+ if (details)
+ m_details = ::strdup(details);
+ else
+ m_details = NULL;
+ }
+};
+
+class RessourceException : public GeneralException {
+ public:
+ RessourceException(const String & msg, const char * details) : GeneralException(msg, details) { }
};
-static inline void * malloc(size_t size) throw (GeneralException) {
+void ExitHelper(const String & msg, const char * fmt = NULL, ...) __attribute__((format(printf, 2, 3)));
+
+static inline void * malloc(size_t size) {
void * r = ::malloc(size);
if (!r && size)
- throw GeneralException("Failed to allocate memory.");
+ ExitHelper("Failed to allocate memory", "%li bytes", size);
return r;
}
-static inline void * calloc(size_t count, size_t size) throw (GeneralException) {
+static inline void * calloc(size_t count, size_t size) {
void * r = ::calloc(count, size);
if (!r && ((count * size) != 0))
- throw GeneralException("Failed to allocate memory.");
+ ExitHelper("Failed to allocate memory", "%li * %li = %li bytes", count, size, count * size);
return r;
}
-static inline void * realloc(void * previous, size_t size) throw (GeneralException) {
+static inline void * realloc(void * previous, size_t size) {
void * r = ::realloc(previous, size);
if (!r && size)
- throw GeneralException("Failed to allocate memory.");
+ ExitHelper("Failed to re-allocate memory", "%li bytes", size);
return r;
}
-static inline void AssertHelper(const String & msg) throw(GeneralException) { throw GeneralException(msg); }
+static inline void AssertHelperInner(const String & msg, const char * details = NULL) throw (GeneralException) {
+ throw GeneralException(msg, details);
+}
+
+static inline void AssertHelper(const String & msg, const char * fmt = NULL, ...) __attribute__((format(printf, 2, 3)));
+
+static inline void AssertHelper(const String & msg, const char * fmt, ...) {
+ if (fmt) {
+ String details;
+ va_list ap;
+ va_start(ap, fmt);
+ details.set(fmt, ap);
+ va_end(ap);
+ AssertHelperInner(msg, details.to_charp());
+ } else {
+ AssertHelperInner(msg);
+ }
+}
+
+class TestException : public GeneralException {
+ public:
+ TestException(const String & msg) : GeneralException(msg) { }
+};
+
+static inline void TestHelper(const String & msg) throw (TestException) {
+ throw TestException(msg);
+}
class ClassName {
public:
@@ -72,8 +115,29 @@ ClassName::ClassName(T * ptr) {
};
-#define Assert(c) if (!(c)) { \
+#define Failure(msg) Balau::AssertHelper(msg);
+#define FailureDetails(msg, ...) Balau::AssertHelper(msg, __VA_ARGS__);
+
+#define IAssert(c, ...) if (!__builtin_expect(!!(c), 0)) { \
+ Balau::String msg; \
+ msg.set("Internal Assertion " #c " failed at %s:%i", __FILE__, __LINE__); \
+ Balau::AssertHelper(msg, __VA_ARGS__); \
+}
+
+#define AAssert(c, ...) if (!__builtin_expect(!!(c), 0)) { \
+ Balau::String msg; \
+ msg.set("API Assertion " #c " failed at %s:%i", __FILE__, __LINE__); \
+ Balau::AssertHelper(msg, __VA_ARGS__); \
+}
+
+#define RAssert(c, ...) if (!__builtin_expect(!!(c), 0)) { \
+ Balau::String msg; \
+ msg.set("Ressource Assertion " #c " failed at %s:%i", __FILE__, __LINE__); \
+ Balau::ExitHelper(msg, __VA_ARGS__); \
+}
+
+#define TAssert(c) if (!__builtin_expect(!!(c), 0)) { \
Balau::String msg; \
- msg.set("Assertion " #c " failed at %s:%i", __FILE__, __LINE__); \
- Balau::AssertHelper(msg); \
+ msg.set("UnitTest Assert " #c " failed at %s:%i", __FILE__, __LINE__); \
+ Balau::TestHelper(msg); \
}