FXException.h

Go to the documentation of this file.
00001 /********************************************************************************
00002 *                                                                               *
00003 *                     E x c e p t i o n  H a n d l i n g                        *
00004 *                                                                               *
00005 *********************************************************************************
00006 *        Copyright (C) 2003-2008 by Niall Douglas.   All Rights Reserved.       *
00007 *       NOTE THAT I DO NOT PERMIT ANY OF MY CODE TO BE PROMOTED TO THE GPL      *
00008 *********************************************************************************
00009 * This code is free software; you can redistribute it and/or modify it under    *
00010 * the terms of the GNU Library General Public License v2.1 as published by the  *
00011 * Free Software Foundation EXCEPT that clause 3 does not apply ie; you may not  *
00012 * "upgrade" this code to the GPL without my prior written permission.           *
00013 * Please consult the file "License_Addendum2.txt" accompanying this file.       *
00014 *                                                                               *
00015 * This code is distributed in the hope that it will be useful,                  *
00016 * but WITHOUT ANY WARRANTY; without even the implied warranty of                *
00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                          *
00018 *********************************************************************************
00019 * $Id:                                                                          *
00020 ********************************************************************************/
00021 
00022 #ifndef FXEXCEPTION_H
00023 #define FXEXCEPTION_H
00024 #include <string.h>
00025 #include <errno.h>
00026 #include <new>  // For std::bad_alloc
00027 #include "FXString.h"
00028 
00029 namespace FX {
00030 
00038 enum FXExceptionFlags
00039 {
00040     FXERRH_ISFATAL=1,           
00041     FXERRH_ISNORETRY=2,         
00042     FXERRH_ISINFORMATIONAL=4,   
00043     FXERRH_ISFROMOTHER=8,       
00044 
00048     FXERRH_HASNESTED=16,
00049     FXERRH_ISDEBUG=32,          
00050     FXERRH_ISFOXEXCEPTION=64    
00051 };
00052 
00058 #ifdef FXEXCEPTION_DISABLESOURCEINFO
00059 #define FXEXCEPTION_FILE(p) (const char *) 0
00060 #define FXEXCEPTION_FUNCTION(p) (const char *) 0
00061 #define FXEXCEPTION_LINE(p) 0
00062 #else
00063 #define FXEXCEPTION_FILE(p) __FILE__
00064 #define FXEXCEPTION_FUNCTION(p) __func__
00065 #define FXEXCEPTION_LINE(p) __LINE__
00066 #endif
00067 
00073 #define FXERRMAKE(e2, msg, code, flags)     FX::FXException e2(FXEXCEPTION_FILE(e2), FXEXCEPTION_FUNCTION(e2), FXEXCEPTION_LINE(e2), msg, code, flags);
00074 
00076 #define FXERRH_THROW(e2)                    { FX::FXException::int_setThrownException(e2); throw std::move(e2); }
00078 #define FXERRG(msg, code, flags)            { FXERRMAKE(_int_e_temp, msg, code, flags); FXERRH_THROW(_int_e_temp); }
00080 #ifdef DEBUG
00081 #define FXERRH(cond, msg, code, flags)      if(!(cond) || FX::FXException::int_testCondition()) FXERRG(msg, code, flags)
00082 #else
00083 #define FXERRH(cond, msg, code, flags)      if(!(cond)) FXERRG(msg, code, flags)
00084 #endif
00085 
00091 enum FXExceptionCodes
00092 {
00093     FXEXCEPTION_USER        =0x00010000,                        
00094     FXEXCEPTION_SYSCODE_BASE=0x0000FFFF,
00095     FXEXCEPTION_BADRANGE    =(FXEXCEPTION_SYSCODE_BASE - 0),    
00096     FXEXCEPTION_NULLPOINTER =(FXEXCEPTION_SYSCODE_BASE - 1),    
00097     FXEXCEPTION_NORESOURCE  =(FXEXCEPTION_SYSCODE_BASE - 2),    
00098     FXEXCEPTION_NOMEMORY    =(FXEXCEPTION_SYSCODE_BASE - 3),    
00099     FXEXCEPTION_NOTSUPPORTED=(FXEXCEPTION_SYSCODE_BASE - 4),    
00100     FXEXCEPTION_NOTFOUND    =(FXEXCEPTION_SYSCODE_BASE - 5),    
00101     FXEXCEPTION_IOERROR     =(FXEXCEPTION_SYSCODE_BASE - 6),    
00102     FXEXCEPTION_CONNECTIONLOST=(FXEXCEPTION_SYSCODE_BASE - 7),  
00103     FXEXCEPTION_NOPERMISSION=(FXEXCEPTION_SYSCODE_BASE - 8),    
00104 
00105     FXEXCEPTION_WINDOW      =(FXEXCEPTION_SYSCODE_BASE - 9),    
00106     FXEXCEPTION_IMAGE       =(FXEXCEPTION_SYSCODE_BASE - 10),   
00107     FXEXCEPTION_FONT        =(FXEXCEPTION_SYSCODE_BASE - 11),   
00108 
00109     FXEXCEPTION_OSSPECIFIC  =(FXEXCEPTION_SYSCODE_BASE - 32),   
00110     FXEXCEPTION_PYTHONERROR =(FXEXCEPTION_SYSCODE_BASE - 33),   
00111 
00112     FXEXCEPTION_INTTHREADCANCEL=(FXEXCEPTION_SYSCODE_BASE - 256)
00113 };
00114 
00119 #define FXERRGOS(code, flags)               { FX::FXException::int_throwOSError(FXEXCEPTION_FILE(code), FXEXCEPTION_FUNCTION(code), FXEXCEPTION_LINE(code), code, flags); }
00120 #define FXERRGOSFN(code, flags, filename)   { FX::FXException::int_throwOSError(FXEXCEPTION_FILE(code), FXEXCEPTION_FUNCTION(code), FXEXCEPTION_LINE(code), code, flags, filename); }
00121 #ifdef DEBUG
00122 #define FXERRHOS(exp)               { int __errcode=(exp); if(__errcode<0 || FX::FXException::int_testCondition()) FXERRGOS(errno, 0); }
00123 #define FXERRHOSFN(exp, filename)   { int __errcode=(exp); if(__errcode<0 || FX::FXException::int_testCondition()) FXERRGOSFN(errno, 0, filename); }
00124 #else
00125 
00128 #define FXERRHOS(exp)               { int __errcode=(exp); if(__errcode<0) FXERRGOS(errno, 0); }
00129 #define FXERRHOSFN(exp, filename)   { int __errcode=(exp); if(__errcode<0) FXERRGOSFN(errno, 0, filename); }
00130 #endif
00131 
00132 //@(
00134 #define FXERRH_TRY          { bool __retryerrorh; do { __retryerrorh=false; FX::FXException_TryHandler __newtryhandler(FXEXCEPTION_FILE(0), FXEXCEPTION_FUNCTION(0), FXEXCEPTION_LINE(0)); try
00136 #define FXERRH_CATCH(e2)    catch(e2)
00137 
00143 #define FXERRH_REPORT(owner, e2)    { if(FX::FXExceptionDialog(owner, e2).execute()) __retryerrorh=true; }
00145 #define FXERRH_ENDTRY       } while(__retryerrorh); }
00146 //@)
00147 
00149 #define FXDELETE(v)         { delete v; v=0; }
00150 
00151 #define FXERRH_NODESTRUCTORMOD
00152 #define FXEXCEPTIONDESTRUCT1 FX::FXException::int_incDestructorCnt(); try
00153 #define FXEXCEPTIONDESTRUCT2 catch(FXException &_int_caught_e) { if(FX::FXException::int_nestedException(_int_caught_e)) throw; } FX::FXException::int_decDestructorCnt()
00154 //@(
00156 #define FXEXCEPTION_STL1 try {
00158 #define FXEXCEPTION_STL2 } catch(const std::bad_alloc &) { FXERRGM }
00159 //@)
00160 //@(
00162 #define FXEXCEPTION_FOXCALLING1 FXERRH_TRY {
00164 #define FXEXCEPTION_FOXCALLING2 } FXERRH_CATCH(FX::FXException &_int_caught_e) { FXERRH_REPORT(FX::FXApp::instance(), _int_caught_e); } FXERRH_ENDTRY
00165 //@)
00166 
00167 
00374 struct FXExceptionPrivate;
00375 template<class type> class QValueList;
00376 class FXException;  // For stupid doxygen parsing bug
00377 #define FXEXCEPTIONAPI_STUPIDDOXYGEN FXEXCEPTIONAPI(FXAPI)
00378 class FXEXCEPTIONAPI_STUPIDDOXYGEN FXException
00379 {
00380   FXExceptionPrivate *p;
00381 private:
00382   FXDLLLOCAL void doStackWalk() throw();
00383   void init(const char *_filename, const char *_function, int _lineno, const FXString &_msg, FXuint _code, FXuint _flags);
00384 public:
00390   FXException(const char *_filename, const char *_function, int _lineno, const FXString &_msg, FXuint _code, FXuint _flags) : p(0)
00391   { init(_filename, _function, _lineno, _msg, _code, _flags); }
00394   FXException() : p(0) { }
00396   FXDEPRECATEDEXT FXException(const FXchar *msg) : p(0) { init((const char *) 0, (const char *) 0, 0, FXString(msg), 0, 0); }
00397 #ifndef HAVE_CPP0XRVALUEREFS
00398   FXException &operator=(FXException &o);
00399 #ifdef HAVE_CONSTTEMPORARIES
00400   FXException(const FXException &other) : p(other.p)
00401   {
00402     FXException &o=const_cast<FXException &>(other);
00403 #else
00404   FXException(FXException &o) : p(o.p)
00405   {
00406 #endif
00407 #else
00408   FXException &&operator=(FXException &&o);
00409 private:
00410   FXException(const FXException &);     // disable copy constructor
00411 public:
00412   FXException(FXException &&o) : p(std::move(o.p))
00413   {
00414 #endif
00415     o.p=0;
00416   }
00418   FXException copy() const;
00420   bool isValid() const throw();
00422   bool isFatal() const throw();
00424   void setFatal(bool _fatal);
00426   void sourceInfo(const char **FXRESTRICT file, const char **FXRESTRICT function, int *FXRESTRICT lineno) const throw();
00428   const FXString &message() const throw();
00430   void setMessage(const FXString &msg);
00432   FXuint code() const throw();
00434   FXuint flags() const throw();
00436   FXulong threadId() const throw();
00441   const FXString &report() const;
00443   FXDEPRECATEDEXT const FXchar *what() const { return message().text(); }
00445   bool isPrimary() const;
00447   FXint nestedLen() const;
00449   FXException nested(FXint idx) const;
00450   virtual ~FXException();
00464   static FXint setGlobalErrorCreationCount(FXint no);
00467   static bool setConstructionBreak(bool v);
00468 
00469   // Internal and not to be publicly used
00470   static FXDLLLOCAL void int_enableNestedExceptionFramework(bool yes=true);
00471   static void int_setThrownException(FXException &e);
00472   static void int_enterTryHandler(const char *srcfile, const char *function, int lineno);
00473   static void int_exitTryHandler() throw();
00474   static void int_incDestructorCnt();
00475   static bool int_nestedException(FXException &e);
00476   static void int_decDestructorCnt();
00477   static bool int_testCondition();
00478   static void int_throwWinError(const char *file, const char *function, int lineno, FXuint code, FXuint flags, const FXString &filename=FXString::nullStr());
00479   static void int_throwOSError(const char *file, const char *function, int lineno, int code, FXuint flags, const FXString &filename=FXString::nullStr());
00480   friend FXAPI FXStream &operator<<(FXStream &s, const FXException &i);
00481   friend FXAPI FXStream &operator>>(FXStream &s, FXException &i);
00482 };
00483 
00485 FXAPI FXStream &operator<<(FXStream &s, const FXException &i);
00487 FXAPI FXStream &operator>>(FXStream &s, FXException &i);
00488 
00489 struct FXException_TryHandler
00490 {
00491     FXException_TryHandler(const char *srcfile, const char *function, int lineno)
00492     {
00493         FXException::int_enterTryHandler(srcfile, function, lineno);
00494     }
00495     ~FXException_TryHandler()
00496     {
00497         FXException::int_exitTryHandler();
00498     }
00499 };
00500 
00501 
00505 class FXEXCEPTIONAPI(FXAPI) FXRangeException : public FXException
00506 {
00507 public:
00509     FXRangeException(const char *_filename, const char *_function, int _lineno, const FXString &_msg)
00510         : FXException(_filename, _function, _lineno, _msg, FXEXCEPTION_BADRANGE, 0) { }
00512     FXDEPRECATEDEXT FXRangeException(const FXchar *msg)
00513         : FXException((const char *) 0, (const char *) 0, 0, msg, FXEXCEPTION_BADRANGE, FXERRH_ISFOXEXCEPTION) { }
00514     FXMOVEBASECLASS(FXRangeException, FXException)
00515 };
00522 #define FXERRGRANGE(msg, flags)     { FX::FXRangeException _int_temp_e(FXEXCEPTION_FILE(msg), FXEXCEPTION_FUNCTION(msg), FXEXCEPTION_LINE(msg), msg, flags); FXERRH_THROW(_int_temp_e); }
00523 
00527 class FXEXCEPTIONAPI(FXAPI) FXPointerException : public FXException
00528 {
00529 public:
00531     FXPointerException(const char *_filename, const char *_function, int _lineno, FXint _flags)
00532         : FXException(_filename, _function, _lineno, "Null pointer", FXEXCEPTION_NULLPOINTER, _flags) { }
00534     FXDEPRECATEDEXT FXPointerException(const FXchar *msg)
00535         : FXException((const char *) 0, (const char *) 0, 0, msg, FXEXCEPTION_NULLPOINTER, FXERRH_ISFOXEXCEPTION) { }
00536     FXMOVEBASECLASS(FXPointerException, FXException)
00537 };
00538 #define FXERRGPTR(flags)            { FX::FXPointerException _int_temp_e(FXEXCEPTION_FILE(flags), FXEXCEPTION_FUNCTION(flags), FXEXCEPTION_LINE(flags), flags); FXERRH_THROW(_int_temp_e); }
00539 
00543 #ifdef DEBUG
00544 #define FXERRHPTR(exp, flags)   if(!(exp) || FX::FXException::int_testCondition()) FXERRGPTR(flags)
00545 #else
00546 #define FXERRHPTR(exp, flags)   if(!(exp)) FXERRGPTR(flags)
00547 #endif
00548 
00552 class FXEXCEPTIONAPI(FXAPI) FXResourceException : public FXException
00553 {
00554 public:
00556     FXResourceException(const char *_filename, const char *_function, int _lineno, const FXString &_msg,
00557         FXuint _code=FXEXCEPTION_NORESOURCE, FXuint _flags=0)
00558         : FXException(_filename, _function, _lineno, _msg, _code, _flags) { }
00560     FXDEPRECATEDEXT FXResourceException(const FXchar *msg)
00561         : FXException((const char *) 0, (const char *) 0, 0, msg, FXEXCEPTION_NORESOURCE, FXERRH_ISFOXEXCEPTION) { }
00562     FXMOVEBASECLASS(FXResourceException, FXException)
00563 };
00564 
00568 class FXEXCEPTIONAPI(FXAPI) FXMemoryException : public FXResourceException
00569 {
00570 public:
00572     FXMemoryException(const char *_filename, const char *_function, int _lineno)
00573         : FXResourceException(_filename, _function, _lineno, "Out of memory", FXEXCEPTION_NOMEMORY, 0) { }
00575     FXDEPRECATEDEXT FXMemoryException(const FXchar *msg)
00576         : FXResourceException((const char *) 0, (const char *) 0, 0, msg, FXEXCEPTION_NOMEMORY, FXERRH_ISFOXEXCEPTION) { }
00577     FXMOVEBASECLASS(FXMemoryException, FXResourceException)
00578 };
00579 #define FXERRGM             { FX::FXMemoryException _int_temp_e(FXEXCEPTION_FILE(0), FXEXCEPTION_FUNCTION(0), FXEXCEPTION_LINE(0)); FXERRH_THROW(_int_temp_e); }
00580 
00589 #ifdef DEBUG
00590 #define FXERRHM(exp)        do { try { if(!FX::FXException::int_testCondition() && (exp)) break; } catch(const std::bad_alloc &) { } FXERRGM; } while(0)
00591 #else
00592 #define FXERRHM(exp)        do { try { if((exp)) break; } catch(const std::bad_alloc &) { } FXERRGM; } while(0)
00593 #endif
00594 
00598 class FXEXCEPTIONAPI(FXAPI) FXNotSupportedException : public FXException
00599 {
00600 public:
00602     FXNotSupportedException(const char *_filename, const char *_function, int _lineno, const FXString &msg)
00603         : FXException(_filename, _function, _lineno, msg, FXEXCEPTION_NOTSUPPORTED, FXERRH_ISNORETRY|FXERRH_ISDEBUG) { }
00604     FXMOVEBASECLASS(FXNotSupportedException, FXException)
00605 };
00610 #define FXERRGNOTSUPP(msg)  { FX::FXNotSupportedException _int_temp_e(FXEXCEPTION_FILE(msg), FXEXCEPTION_FUNCTION(msg), FXEXCEPTION_LINE(msg), msg); FXERRH_THROW(_int_temp_e); }
00611 
00615 class FXEXCEPTIONAPI(FXAPI) FXNotFoundException : public FXResourceException
00616 {
00617 public:
00619     FXNotFoundException(const char *_filename, const char *_function, int _lineno, const FXString &_msg, FXint flags)
00620         : FXResourceException(_filename, _function, _lineno, _msg, FXEXCEPTION_NOTFOUND, flags|FXERRH_ISINFORMATIONAL) { }
00621     FXMOVEBASECLASS(FXNotFoundException, FXResourceException)
00622 };
00629 #define FXERRGNF(msg, flags)    { FX::FXNotFoundException _int_temp_e(FXEXCEPTION_FILE(msg), FXEXCEPTION_FUNCTION(msg), FXEXCEPTION_LINE(msg), msg, flags); FXERRH_THROW(_int_temp_e); }
00630 
00634 class FXEXCEPTIONAPI(FXAPI) FXIOException : public FXResourceException
00635 {
00636 public:
00638     FXIOException(const char *_filename, const char *_function, int _lineno, const FXString &msg, FXuint code=FXEXCEPTION_IOERROR, FXuint flags=0)
00639         : FXResourceException(_filename, _function, _lineno, msg, code, flags) { }
00640     FXMOVEBASECLASS(FXIOException, FXResourceException)
00641 };
00642 #define FXERRGIO(msg)       { FX::FXIOException _int_temp_e(FXEXCEPTION_FILE(msg), FXEXCEPTION_FUNCTION(msg), FXEXCEPTION_LINE(msg), msg); FXERRH_THROW(_int_temp_e); }
00643 
00650 #ifdef DEBUG
00651 #define FXERRHIO(exp)       if(-1==(int)(exp) || FX::FXException::int_testCondition()) FXERRGIO(strerror(errno))
00652 #else
00653 #define FXERRHIO(exp)       if(-1==(int)(exp)) FXERRGIO(strerror(errno))
00654 #endif
00655 
00659 class FXEXCEPTIONAPI(FXAPI) FXConnectionLostException : public FXIOException
00660 {
00661 public:
00663     FXConnectionLostException(const FXString &msg, FXuint flags)
00664         : FXIOException(0, 0, 0, msg, FXEXCEPTION_CONNECTIONLOST, flags|FXERRH_ISINFORMATIONAL) { }
00665     FXMOVEBASECLASS(FXConnectionLostException, FXIOException)
00666 };
00667 #define FXERRGCONLOST(msg, flags)       { FX::FXConnectionLostException _int_temp_e(msg, flags); FXERRH_THROW(_int_temp_e); }
00668 
00672 class FXEXCEPTIONAPI(FXAPI) FXNoPermissionException : public FXException
00673 {
00674 public:
00676     FXNoPermissionException(const FXString &msg, FXuint code=FXEXCEPTION_NOPERMISSION, FXuint flags=0)
00677         : FXException(0, 0, 0, msg, code, flags|FXERRH_ISINFORMATIONAL) { }
00678     FXMOVEBASECLASS(FXNoPermissionException, FXException)
00679 };
00680 #define FXERRGNOPERM(msg, flags)        { FX::FXNoPermissionException _int_temp_e(msg, FXEXCEPTION_NOPERMISSION, flags); FXERRH_THROW(_int_temp_e); }
00681 
00688 class FXEXCEPTIONAPI(FXAPI) FXWindowException : public FXResourceException
00689 {
00690 public:
00692     FXDEPRECATEDEXT FXWindowException(const FXchar *msg)
00693         : FXResourceException((const char *) 0, (const char *) 0, 0, msg, FXEXCEPTION_WINDOW, FXERRH_ISFOXEXCEPTION) { }
00694     FXMOVEBASECLASS(FXWindowException, FXResourceException)
00695 };
00696 
00703 class FXEXCEPTIONAPI(FXAPI) FXImageException : public FXResourceException
00704 {
00705 public:
00707     FXDEPRECATEDEXT FXImageException(const FXchar *msg)
00708         : FXResourceException((const char *) 0, (const char *) 0, 0, msg, FXEXCEPTION_IMAGE, FXERRH_ISFOXEXCEPTION) { }
00709     FXMOVEBASECLASS(FXImageException, FXResourceException)
00710 };
00711 
00718 class FXEXCEPTIONAPI(FXAPI) FXFontException : public FXResourceException
00719 {
00720 public:
00722     FXDEPRECATEDEXT FXFontException(const FXchar *msg)
00723         : FXResourceException((const char *) 0, (const char *) 0, 0, msg, FXEXCEPTION_FONT, FXERRH_ISFOXEXCEPTION) { }
00724     FXMOVEBASECLASS(FXFontException, FXResourceException)
00725 };
00726 
00727 
00728 
00729 } // namespace
00730 
00731 #endif

(C) 2002-2009 Niall Douglas. Some parts (C) to assorted authors.
Generated on Fri Nov 20 18:31:20 2009 for TnFOX by doxygen v1.4.7