00001
00002
00003
00004
00005
00006
00007
00008
00009 static const char rcsid[] __attribute__((used)) = "$Id: Exception.cpp 1197 2014-10-14 22:26:11Z sella $";
00010
00011 #include "Exception.h"
00012
00013 #include <stdio.h>
00014 #include <string.h>
00015 #include <stdlib.h>
00016 #include <stdarg.h>
00017
00018 #ifdef __GNUG__
00019 #include <cxxabi.h>
00020 #endif
00021
00022 #include <string>
00023
00024 #define BUFFER_SIZE 32768
00025
00026 using namespace sella;
00027
00028
00029 extern int errno;
00030
00031 Exception::Exception(const char *function, const char *file, int line, int code) throw () :
00032 function(function),
00033 file(file),
00034 line(line),
00035 code(code)
00036 { }
00037
00038 Exception::Exception(bool sysmsg, const char *function, const char *file, int line, int code, const char *format, ...) throw () :
00039 function(function),
00040 file(file),
00041 line(line),
00042 code(code)
00043 {
00044 EXCEPTION_BUILDMESSAGE_CODE
00045 }
00046
00047 Exception::Exception(const Exception &other) throw () :
00048 function(other.function),
00049 file(other.file),
00050 line(other.line),
00051 code(other.code),
00052 message(other.message),
00053 cache(other.cache)
00054 { }
00055
00056 Exception::Exception(const Exception &&other) throw () :
00057 function(std::move(other.function)),
00058 file(std::move(other.file)),
00059 line(other.line),
00060 code(other.code),
00061 message(std::move(other.message)),
00062 cache(std::move(other.cache))
00063 { }
00064
00065 Exception::~Exception() throw () { }
00066
00067 Exception& sella::Exception::operator=(const Exception &other) throw () {
00068 if (this != &other) {
00069 this->function = other.function;
00070 this->file = other.file;
00071 this->line = other.line;
00072 this->code = other.code;
00073 this->message = other.message;
00074 this->cache = other.cache;
00075 }
00076
00077 return *this;
00078 }
00079
00080 Exception& sella::Exception::operator=(const Exception &&other) throw () {
00081 if (this != &other) {
00082 this->function = std::move(other.function);
00083 this->file = std::move(other.file);
00084 this->line = other.line;
00085 this->code = other.code;
00086 this->message = std::move(other.message);
00087 this->cache = std::move(other.cache);
00088 }
00089
00090 return *this;
00091 }
00092
00093 const char* Exception::what() const throw () {
00094 return this->message.c_str();
00095 }
00096
00097 const std::string& Exception::getMessage() const throw () {
00098 return this->message;
00099 }
00100
00101 const std::string& Exception::getFunction() const throw () {
00102 return this->function;
00103 }
00104
00105 const std::string& Exception::getFile() const throw () {
00106 return this->file;
00107 }
00108
00109 const std::string Exception::getName() const throw () {
00110 return std::string("sella::Exception");
00111 }
00112
00113 int Exception::getLine() const throw () {
00114 return this->line;
00115 }
00116
00117 int Exception::getCode() const throw () {
00118 return this->code;
00119 }
00120
00121 const std::string& Exception::str() const throw () {
00122 if (cache.empty()) {
00123 char buf[20];
00124
00125 snprintf(buf, sizeof(buf), ":%d]", this->line);
00126
00127 cache = (this->message + " [" + this->file + buf);
00128 }
00129
00130 return cache;
00131 }
00132
00133 const char* Exception::c_str() const throw () {
00134 return str().c_str();
00135 }
00136
00137 void Exception::buildMessage(bool sysmsg, const char *format, va_list list) throw () {
00138 char buffer[BUFFER_SIZE];
00139 std::string error;
00140
00141 if (sysmsg) {
00142 buffer[0] = 0;
00143 error = ": ";
00144 error.append(strerror_r(errno, buffer, sizeof(buffer)));
00145 }
00146
00147 vsnprintf(buffer, sizeof(buffer), format, list);
00148
00149 this->message = buffer;
00150 this->message.append(error);
00151
00152 cache.clear();
00153 }
00154
00155 const std::string Exception::demangle(const char *name) const throw () {
00156 #ifdef __GNUG__
00157 int s;
00158 char *d;
00159 std::string res;
00160
00161 d = abi::__cxa_demangle(name, NULL, NULL, &s);
00162
00163 if (s == 0) {
00164 res = d;
00165 std::free(d);
00166 }
00167
00168 return std::move(res);
00169 #else
00170 return std::string(name);
00171 #endif
00172 }
00173
00174
00175
00176