#ifndef ERMYTH_EXCEPTION_H #define ERMYTH_EXCEPTION_H #include #include #include #include #ifdef __GNUC__ # define CURFUNC __PRETTY_FUNCTION__ #elif defined(__BORLANDC__) # define CURFUNC __FUNC__ #else # define CURFUNC __FUNCTION__ #endif #define SRCINF srcinf (__FILE__, __LINE__, CURFUNC) #define EBUFSIZE 1024 struct srcinf { srcinf (char const *file, unsigned int line, char const *func) : m_info (info (file, line, func)) { } unsigned int line() const throw() { return m_info.line; } char const *file() const throw() { return m_info.file; } char const *func() const throw() { return m_info.func; } srcinf &operator = (srcinf const &rhs) { if (this != &rhs) this->m_info = rhs.m_info; return *this; } srcinf (srcinf const &rhs) { this->m_info = rhs.m_info; } private: struct info { char const *file; unsigned line; char const *func; info () : file (0), line (0), func (0) { } info (char const *file, unsigned line, char const *func) : file (file ? file : ""), line (line), func (func ? func : " ()") { } }; info m_info; }; struct exception : std::exception { virtual const char *what() const throw () { return m_what ? m_what : ""; } protected: explicit exception (const char *fmt, ...) { va_list ap; va_start (ap, fmt); vsnprintf (m_what, EBUFSIZE - 1, fmt, ap); va_end (ap); } explicit exception (srcinf const &si, char const *fmt, ...) { va_list ap; va_start (ap, fmt); what (si, fmt, ap); va_end (ap); } void what (srcinf const &si, char const *fmt, va_list ap) throw () { char buf[EBUFSIZE]; char *bufptr = buf; int l = snprintf (bufptr, EBUFSIZE - 1, "%s(#%d): %s: ", si.file (), si.line (), si.func ()); vsnprintf (bufptr + l, EBUFSIZE - 1, fmt, ap); what (buf); } void what (char const *fmt, va_list ap) throw () { char buf[EBUFSIZE]; vsnprintf (buf, EBUFSIZE - 1, fmt, ap); what (buf); } void what (char const *w) throw () { std::copy (w, w + EBUFSIZE, m_what); } exception () { } private: char m_what[EBUFSIZE]; }; struct nullpointer_exception : exception { explicit nullpointer_exception () { } explicit nullpointer_exception (char const *fmt, ...) { va_list ap; va_start (ap, fmt); what (fmt, ap); va_end (ap); } explicit nullpointer_exception (srcinf const &si, char const *fmt, ...) { va_list ap; va_start (ap, fmt); what (si, fmt, ap); va_end (ap); } }; #endif // ERMYTH_EXCEPTION_H