00001 #include "util/exception.hh"
00002
00003 #ifdef __GXX_RTTI
00004 #include <typeinfo>
00005 #endif
00006
00007 #include <cerrno>
00008 #include <cstring>
00009
00010 #if defined(_WIN32) || defined(_WIN64)
00011 #include <windows.h>
00012 #include <io.h>
00013 #endif
00014
00015 namespace util {
00016
00017 Exception::Exception() throw() {}
00018 Exception::~Exception() throw() {}
00019
00020 void Exception::SetLocation(const char *file, unsigned int line, const char *func, const char *child_name, const char *condition) {
00021
00022
00023
00024
00025
00026 std::string old_text;
00027 what_.swap(old_text);
00028 what_ << file << ':' << line;
00029 if (func) what_ << " in " << func << " threw ";
00030 if (child_name) {
00031 what_ << child_name;
00032 } else {
00033 #ifdef __GXX_RTTI
00034 what_ << typeid(this).name();
00035 #else
00036 what_ << "an exception";
00037 #endif
00038 }
00039 if (condition) {
00040 what_ << " because `" << condition << '\'';
00041 }
00042 what_ << ".\n";
00043 what_ << old_text;
00044 }
00045
00046 namespace {
00047
00048 #ifdef __GNUC__
00049 const char *HandleStrerror(int ret, const char *buf) __attribute__ ((unused));
00050 const char *HandleStrerror(const char *ret, const char * ) __attribute__ ((unused));
00051 #endif
00052
00053 #ifdef __clang__
00054 #pragma clang diagnostic push
00055 #pragma clang diagnostic ignored "-Wunused-function"
00056 #endif
00057
00058 const char *HandleStrerror(int ret, const char *buf) {
00059 if (!ret) return buf;
00060 return NULL;
00061 }
00062
00063
00064 const char *HandleStrerror(const char *ret, const char * ) {
00065 return ret;
00066 }
00067 #ifdef __clang__
00068 #pragma clang diagnostic pop
00069 #endif
00070 }
00071
00072 ErrnoException::ErrnoException() throw() : errno_(errno) {
00073 char buf[200];
00074 buf[0] = 0;
00075 #if defined(sun) || defined(_WIN32) || defined(_WIN64)
00076 const char *add = strerror(errno);
00077 #else
00078 const char *add = HandleStrerror(strerror_r(errno, buf, 200), buf);
00079 #endif
00080
00081 if (add) {
00082 *this << add << ' ';
00083 }
00084 }
00085
00086 ErrnoException::~ErrnoException() throw() {}
00087
00088 OverflowException::OverflowException() throw() {}
00089 OverflowException::~OverflowException() throw() {}
00090
00091 #if defined(_WIN32) || defined(_WIN64)
00092 WindowsException::WindowsException() throw() {
00093 unsigned int last_error = GetLastError();
00094 char error_msg[256] = "";
00095 if (!FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, last_error, LANG_NEUTRAL, error_msg, sizeof(error_msg), NULL)) {
00096 *this << "Windows error " << GetLastError() << " while formatting Windows error " << last_error << ". ";
00097 } else {
00098 *this << "Windows error " << last_error << ": " << error_msg;
00099 }
00100 }
00101 WindowsException::~WindowsException() throw() {}
00102 #endif
00103
00104 }