00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 
00057 #ifndef _GEXCEPTION_H_
00058 #define _GEXCEPTION_H_
00059 #ifdef HAVE_CONFIG_H
00060 #include "config.h"
00061 #endif
00062 #if NEED_GNUG_PRAGMAS
00063 # pragma interface
00064 #endif
00065 
00066 #ifndef no_return
00067 #ifdef __GNUC__
00068 #define no_return __attribute__ ((noreturn))
00069 #else
00070 #define no_return
00071 #endif
00072 #endif
00073 
00121 
00122 #include "DjVuGlobal.h"
00123 
00124 #ifdef HAVE_NAMESPACES
00125 namespace DJVU {
00126 # ifdef NOT_DEFINED // Just to fool emacs c++ mode
00127 }
00128 #endif
00129 #endif
00130 
00131 
00132 
00138 class GException {
00139 public:
00140   enum source_type { GINTERNAL=0, GEXTERNAL, GAPPLICATION, GOTHER };
00148   GException (const char *cause, const char *file=0, int line=0, 
00149               const char *func=0, const source_type source=GINTERNAL);
00150 
00152   GException (const GException & exc);
00153   
00155   GException ();
00156   
00158   virtual ~GException(void);
00159   
00161   GException & operator=(const GException & exc);
00162   
00167   void perror(void) const;
00168   
00179   const char* get_cause(void) const;
00180 
00183   int cmp_cause(const char s2[]) const;
00184 
00187   static int cmp_cause(const char s1[],const char s2[]);
00188 
00191   const char* get_function(void) const { return func; }
00192   
00195   const char* get_file(void) const { return file; }
00196  
00198   source_type get_source(void) const { return source; }
00199  
00202   int get_line(void) const { return line; };
00203   
00204   
00205   static const char * const outofmemory;
00206 
00207 private:
00208   const char *cause;
00209   const char *file;
00210   const char *func;
00211   int line;
00212   source_type source;
00213 };
00214 
00216 
00217 #undef G_TRY
00218 #undef G_CATCH
00219 #undef G_CATCH_ALL
00220 #undef G_ENDCATCH
00221 #undef G_RETHROW
00222 #undef G_THROW
00223 #undef G_THROW_TYPE
00224 #undef G_THROW_INTERNAL
00225 #undef G_THROW_EXTERNAL
00226 #undef G_THROW_APPLICATION
00227 #undef G_THROW_OTHER
00228 
00229 
00230 #if defined(_MSC_VER)
00231 #define CPP_SUPPORTS_EXCEPTIONS
00232 #endif
00233 #if defined(__MWERKS__)
00234 #define CPP_SUPPORTS_EXCEPTIONS
00235 #endif
00236 #if defined(__EXCEPTIONS)
00237 #define CPP_SUPPORTS_EXCEPTIONS
00238 #endif
00239 
00240 #ifndef CPP_SUPPORTS_EXCEPTIONS
00241 #ifndef USE_EXCEPTION_EMULATION
00242 #define USE_EXCEPTION_EMULATION
00243 #endif
00244 #endif
00245 
00246 
00247 #ifndef USE_EXCEPTION_EMULATION
00248 
00249 
00250 
00251 
00252 class GExceptionHandler {
00253 public:
00254 #ifndef NO_LIBGCC_HOOKS
00255   static void exthrow(const GException &) no_return;
00256 #else
00257   static void exthrow(const GException ) no_return;
00258 #endif 
00259   static void rethrow(void) no_return;
00260 };
00261 
00262 #define G_TRY        try
00263 #define G_CATCH(n)   catch(const GException &n) { 
00264 #define G_CATCH_ALL   catch(...) { 
00265 #define G_ENDCATCH   } 
00266 #define G_RETHROW    GExceptionHandler::rethrow()
00267 #define G_EMTHROW(ex)  GExceptionHandler::exthrow(ex)
00268 #ifdef __GNUG__
00269 #define G_THROW_TYPE(msg,xtype) GExceptionHandler::exthrow \
00270   (GException(msg, __FILE__, __LINE__, __PRETTY_FUNCTION__, xtype))
00271 #else
00272 #define G_THROW_TYPE(msg,xtype) GExceptionHandler::exthrow \
00273   (GException(msg, __FILE__, __LINE__,0, xtype))
00274 #endif
00275 
00276 #else // USE_EXCEPTION_EMULATION
00277 
00278 
00279 
00280 
00281 #include <setjmp.h>
00282 
00283 class GExceptionHandler {
00284 public:
00285   jmp_buf jump;
00286   GExceptionHandler *next;
00287   GException current;
00288 public:
00289   static GExceptionHandler *head;
00290   static void emthrow(const GException &) no_return;
00291 public:
00292   GExceptionHandler() { next = head; };
00293   ~GExceptionHandler() { head = next; };
00294 };
00295 
00296 #define G_TRY    do { GExceptionHandler __exh; \
00297                       if (!setjmp(__exh.jump)) \
00298                       { GExceptionHandler::head = &__exh;
00299 
00300 #define G_CATCH_ALL } else { GExceptionHandler::head = __exh.next; 
00301 #define G_CATCH(n) G_CATCH_ALL const GException& n = __exh.current;
00302 
00303 #define G_ENDCATCH } } while(0)
00304 
00305 #define G_RETHROW    GExceptionHandler::emthrow(__exh.current)
00306 
00307 #ifdef __GNUG__
00308 #define G_THROW_TYPE(msg,xtype) GExceptionHandler::emthrow \
00309   (GException(msg, __FILE__, __LINE__, __PRETTY_FUNCTION__, xtype)) 
00310 #define G_EMTHROW(ex) GExceptionHandler::emthrow(ex)
00311 #else
00312 #define G_THROW_TYPE(m,xtype) GExceptionHandler::emthrow \
00313   (GException(m, __FILE__, __LINE__,0, xtype))
00314 #define G_EMTHROW(ex) GExceptionHandler::emthrow(ex)
00315 #endif
00316 
00317 #endif // !CPP_SUPPORTS_EXCEPTIONS
00318 
00319 
00320 inline void
00321 G_EXTHROW
00322 (const GException &ex,const char *msg=0,const char *file=0,int line=0,
00323   const char *func=0, const GException::source_type source=GException::GINTERNAL)
00324 {
00325   G_EMTHROW( (msg||file||line||func)?
00326       GException(msg?msg:ex.get_cause(),
00327         file?file:ex.get_file(),
00328         line?line:ex.get_line(),
00329         func?func:ex.get_function(),
00330         source)
00331   :ex);
00332 }
00333 
00334 inline void
00335 G_EXTHROW
00336 (const char msg[],const char *file=0,int line=0,const char *func=0,
00337   const GException::source_type source=GException::GINTERNAL )
00338 {
00339   G_EMTHROW(GException(msg,file,line,func,source));
00340 }
00341 
00342 #define G_THROW(msg) G_THROW_TYPE(msg,GException::GINTERNAL)
00343 #define G_THROW_INTERNAL(msg) G_THROW_TYPE(msg,GException::GINTERNAL)
00344 #define G_THROW_EXTERNAL(msg) G_THROW_TYPE(msg,GException::GEXTERNAL)
00345 #define G_THROW_APPLICATION(msg) G_THROW_TYPE(msg,GException::GAPPLICATION)
00346 #define G_THROW_OTHER(msg) G_THROW_TYPE(msg,GException::GOTHER)
00347 
00348 
00349 
00350 #ifdef HAVE_NAMESPACES
00351 }
00352 # ifndef NOT_USING_DJVU_NAMESPACE
00353 using namespace DJVU;
00354 # endif
00355 #endif
00356 #endif