source: trunk/libdjvu/GException.h @ 81

Last change on this file since 81 was 17, checked in by Eugene Romanenko, 16 years ago

update makefiles, remove absolute paths, update djvulibre to version 3.5.17

File size: 12.6 KB
Line 
1//C-  -*- C++ -*-
2//C- -------------------------------------------------------------------
3//C- DjVuLibre-3.5
4//C- Copyright (c) 2002  Leon Bottou and Yann Le Cun.
5//C- Copyright (c) 2001  AT&T
6//C-
7//C- This software is subject to, and may be distributed under, the
8//C- GNU General Public License, Version 2. The license should have
9//C- accompanied the software or you may obtain a copy of the license
10//C- from the Free Software Foundation at http://www.fsf.org .
11//C-
12//C- This program is distributed in the hope that it will be useful,
13//C- but WITHOUT ANY WARRANTY; without even the implied warranty of
14//C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15//C- GNU General Public License for more details.
16//C-
17//C- DjVuLibre-3.5 is derived from the DjVu(r) Reference Library
18//C- distributed by Lizardtech Software.  On July 19th 2002, Lizardtech
19//C- Software authorized us to replace the original DjVu(r) Reference
20//C- Library notice by the following text (see doc/lizard2002.djvu):
21//C-
22//C-  ------------------------------------------------------------------
23//C- | DjVu (r) Reference Library (v. 3.5)
24//C- | Copyright (c) 1999-2001 LizardTech, Inc. All Rights Reserved.
25//C- | The DjVu Reference Library is protected by U.S. Pat. No.
26//C- | 6,058,214 and patents pending.
27//C- |
28//C- | This software is subject to, and may be distributed under, the
29//C- | GNU General Public License, Version 2. The license should have
30//C- | accompanied the software or you may obtain a copy of the license
31//C- | from the Free Software Foundation at http://www.fsf.org .
32//C- |
33//C- | The computer code originally released by LizardTech under this
34//C- | license and unmodified by other parties is deemed "the LIZARDTECH
35//C- | ORIGINAL CODE."  Subject to any third party intellectual property
36//C- | claims, LizardTech grants recipient a worldwide, royalty-free,
37//C- | non-exclusive license to make, use, sell, or otherwise dispose of
38//C- | the LIZARDTECH ORIGINAL CODE or of programs derived from the
39//C- | LIZARDTECH ORIGINAL CODE in compliance with the terms of the GNU
40//C- | General Public License.   This grant only confers the right to
41//C- | infringe patent claims underlying the LIZARDTECH ORIGINAL CODE to
42//C- | the extent such infringement is reasonably necessary to enable
43//C- | recipient to make, have made, practice, sell, or otherwise dispose
44//C- | of the LIZARDTECH ORIGINAL CODE (or portions thereof) and not to
45//C- | any greater extent that may be necessary to utilize further
46//C- | modifications or combinations.
47//C- |
48//C- | The LIZARDTECH ORIGINAL CODE is provided "AS IS" WITHOUT WARRANTY
49//C- | OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
50//C- | TO ANY WARRANTY OF NON-INFRINGEMENT, OR ANY IMPLIED WARRANTY OF
51//C- | MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
52//C- +------------------------------------------------------------------
53//
54// $Id: GException.h,v 1.11 2005/11/12 15:52:25 leonb Exp $
55// $Name:  $
56
57#ifndef _GEXCEPTION_H_
58#define _GEXCEPTION_H_
59#ifdef HAVE_CONFIG_H
60# include "config.h"
61#endif
62#if NEED_GNUG_PRAGMAS
63# pragma interface
64#endif
65
66#ifndef no_return
67#ifdef __GNUC__
68#define no_return __attribute__ ((noreturn))
69#else
70#define no_return
71#endif
72#endif
73
74/** @name GException.h
75
76    Files #"GException.h"# and #"GException.cpp"# define a portable exception
77    scheme used through the DjVu Reference Library. This scheme can use native
78    C++ exceptions or an exception emulation based on #longjmp#/#setjmp#. A
79    particular model can be forced a compile time by defining option
80    #CPP_SUPPORTS_EXCEPTIONS# or #USE_EXCEPTION_EMULATION#.
81   
82    This emulation code was motivated because many compilers did not properly
83    support exceptions as mandated by the C++ standard documents. This
84    emulation is now considered obsolete because (a) it is not able to call
85    the proper destructors when an exception occurs, and (b) it is not thread
86    safe.  Although all modern C++ compiler handle exception decently, the
87    exception handling intrinsics are not always thread safe.  Therefore we
88    urge programmers to {\em only} use exceptions to signal error conditions
89    that force the library to discontinue execution.
90   
91    There are four macros for handling exceptions.  Macros #G_TRY#, #G_CATCH# and
92    #G_ENDCATCH# are used to define an exception catching block.  Exceptions can
93    be thrown at all times using macro #G_THROW(cause)#. An exception can be
94    re-thrown from a catch block using macro #G_RETHROW#.
95   
96    Example:
97    \begin{verbatim}
98    G_TRY
99      {
100        // program lines which may result in a call to THROW()
101        G_THROW("message");
102      }
103    G_CATCH(ex)
104      {
105        // Variable ex refers to a GException object.
106        ex.perror(); 
107        // You can rethrow the exception to an outer exception handler.
108        G_RETHROW;
109      }
110    G_ENDCATCH;
111    \end{verbatim}
112
113    @memo
114    Portable exceptions.
115    @author
116    L\'eon Bottou <leonb@research.att.com> -- initial implementation.\\
117    Andrei Erofeev <eaf@geocities.com> -- fixed message memory allocation.
118    @version
119    #$Id: GException.h,v 1.11 2005/11/12 15:52:25 leonb Exp $# */
120//@{
121
122#include "DjVuGlobal.h"
123
124// Check if compiler supports native exceptions
125#ifdef HAVE_CONFIG_H
126# if HAVE_EXCEPTIONS
127#  define CPP_SUPPORTS_EXCEPTIONS
128# endif
129#else
130# if defined(_MSC_VER)
131#  define CPP_SUPPORTS_EXCEPTIONS
132# endif
133# if defined(__MWERKS__)
134#  define CPP_SUPPORTS_EXCEPTIONS
135# endif
136# if defined(__EXCEPTIONS)
137#  define CPP_SUPPORTS_EXCEPTIONS
138# endif
139#endif
140// Decide which exception model to use
141#ifndef CPP_SUPPORTS_EXCEPTIONS
142# ifndef USE_EXCEPTION_EMULATION
143#  define USE_EXCEPTION_EMULATION
144# endif
145#endif
146
147#ifdef USE_EXCEPTION_EMULATION
148# include <setjmp.h>
149#endif
150
151#ifdef HAVE_NAMESPACES
152namespace DJVU {
153# ifdef NOT_DEFINED // Just to fool emacs c++ mode
154}
155# endif
156#endif
157
158/** Exception class. 
159    The library always uses macros #G_TRY#, #G_THROW#, #G_CATCH# and #G_ENDCATCH# for
160    throwing and catching exceptions (see \Ref{GException.h}). These macros
161    only deal with exceptions of type #GException#. */
162
163class GException {
164public:
165  enum source_type { GINTERNAL=0, GEXTERNAL, GAPPLICATION, GOTHER };
166  /** Constructs a GException.  This constructor is usually called by macro
167      #G_THROW#.  Argument #cause# is a plain text error message. As a
168      convention, string #ByteStream::EndOfFile# is used when reaching an unexpected
169      end-of-file condition and string #DataPool::Stop# is used when the user
170      interrupts the execution. The remaining arguments are usually provided
171      by the predefined macros #__FILE__#, #__LINE__#, and (G++ and EGCS only)
172      #__PRETTY_FUNCTION__#.  */
173  GException (const char *cause, const char *file=0, int line=0, 
174              const char *func=0, const source_type source=GINTERNAL);
175
176  /** Copy Constructor. */
177  GException (const GException & exc);
178 
179  /** Null Constructor. */
180  GException ();
181 
182  /** Destructor. */
183  virtual ~GException(void);
184 
185  /** Copy Operator. */
186  GException & operator=(const GException & exc);
187 
188  /** Prints an error message on stderr.
189      This function no longer takes a message parameter because
190      some instances used a i18n message id and other instances
191      used a literal string. */
192  void perror(void) const;
193 
194  /** Returns the string describing the cause of the exception.  The returned
195      pointer is never null.  Exception handlers should not rely on the value
196      of the string #cause#.  As a convention however, string
197      #ByteStream::EndOfFile# is used
198      when reaching an unexpected end-of-file condition and string
199      #DataPool::Stop# is used when the user interrupts the execution. These
200      strings can be tested by the exception handlers, with
201      #cmp_cause#. Similar conventional strings may be defined
202      in the future. They all will be small strings with only uppercase
203      characters. */
204  const char* get_cause(void) const;
205
206  /** Compares the cause with the specified string, ignoring anything after
207      the first tab. */
208  int cmp_cause(const char s2[]) const;
209
210  /** Compares the cause with the specified string, ignoring anything after
211      the first tab. */
212  static int cmp_cause(const char s1[],const char s2[]);
213
214  /** Returns the function name from which the exception was thrown.
215      A null pointer is returned if no function name is available. */
216  const char* get_function(void) const { return func; }
217 
218  /** Returns the file name from which the exception was thrown.
219      A null pointer is returned if no file name is available. */
220  const char* get_file(void) const { return file; }
221 
222  /** Returns the exception source */
223  source_type get_source(void) const { return source; }
224 
225  /** Returns the line number from which the exception was thrown.
226      A zero is returned if no line number is available. */
227  int get_line(void) const { return line; };
228 
229  //  Magic cause string
230  static const char * const outofmemory;
231
232private:
233  const char *cause;
234  const char *file;
235  const char *func;
236  int line;
237  source_type source;
238};
239
240//@}
241
242#undef G_TRY
243#undef G_CATCH
244#undef G_CATCH_ALL
245#undef G_ENDCATCH
246#undef G_RETHROW
247#undef G_THROW
248#undef G_THROW_TYPE
249#undef G_THROW_INTERNAL
250#undef G_THROW_EXTERNAL
251#undef G_THROW_APPLICATION
252#undef G_THROW_OTHER
253
254#ifndef USE_EXCEPTION_EMULATION
255
256// Compiler supports ANSI C++ exceptions.
257// Defined exception macros accordingly.
258
259class GExceptionHandler {
260public:
261#ifndef NO_LIBGCC_HOOKS
262  static void exthrow(const GException &) no_return;
263#else
264  static void exthrow(const GException ) no_return;
265#endif /* NO_LIBGCC_HOOKS */
266  static void rethrow(void) no_return;
267};
268
269#define G_TRY        try
270#define G_CATCH(n)   catch(const GException &n) {
271#define G_CATCH_ALL   catch(...) {
272#define G_ENDCATCH   }
273#define G_RETHROW    GExceptionHandler::rethrow()
274#define G_EMTHROW(ex)  GExceptionHandler::exthrow(ex)
275#ifdef __GNUG__
276#define G_THROW_TYPE(msg,xtype) GExceptionHandler::exthrow \
277  (GException(msg, __FILE__, __LINE__, __PRETTY_FUNCTION__, xtype))
278#else
279#define G_THROW_TYPE(msg,xtype) GExceptionHandler::exthrow \
280  (GException(msg, __FILE__, __LINE__,0, xtype))
281#endif
282
283#else // USE_EXCEPTION_EMULATION
284
285// Compiler does not support ANSI C++ exceptions.
286// Emulate with setjmp/longjmp.
287
288class GExceptionHandler {
289public:
290  jmp_buf jump;
291  GExceptionHandler *next;
292  GException current;
293public:
294  static GExceptionHandler *head;
295  static void emthrow(const GException &) no_return;
296public:
297  GExceptionHandler() { next = head; };
298  ~GExceptionHandler() { head = next; };
299};
300
301#define G_TRY    do { GExceptionHandler __exh; \
302                      if (!setjmp(__exh.jump)) \
303                      { GExceptionHandler::head = &__exh;
304
305#define G_CATCH_ALL } else { GExceptionHandler::head = __exh.next;
306#define G_CATCH(n) G_CATCH_ALL const GException& n = __exh.current;
307
308#define G_ENDCATCH } } while(0)
309
310#define G_RETHROW    GExceptionHandler::emthrow(__exh.current)
311
312#ifdef __GNUG__
313#define G_THROW_TYPE(msg,xtype) GExceptionHandler::emthrow \
314  (GException(msg, __FILE__, __LINE__, __PRETTY_FUNCTION__, xtype))
315#define G_EMTHROW(ex) GExceptionHandler::emthrow(ex)
316#else
317#define G_THROW_TYPE(m,xtype) GExceptionHandler::emthrow \
318  (GException(m, __FILE__, __LINE__,0, xtype))
319#define G_EMTHROW(ex) GExceptionHandler::emthrow(ex)
320#endif
321
322#endif // !CPP_SUPPORTS_EXCEPTIONS
323
324
325inline void
326G_EXTHROW
327(const GException &ex,const char *msg=0,const char *file=0,int line=0,
328  const char *func=0, const GException::source_type source=GException::GINTERNAL)
329{
330  G_EMTHROW( (msg||file||line||func)?
331      GException(msg?msg:ex.get_cause(),
332        file?file:ex.get_file(),
333        line?line:ex.get_line(),
334        func?func:ex.get_function(),
335        source)
336  :ex);
337}
338
339inline void
340G_EXTHROW
341(const char msg[],const char *file=0,int line=0,const char *func=0,
342  const GException::source_type source=GException::GINTERNAL )
343{
344  G_EMTHROW(GException(msg,file,line,func,source));
345}
346
347#define G_THROW(msg) G_THROW_TYPE(msg,GException::GINTERNAL)
348#define G_THROW_INTERNAL(msg) G_THROW_TYPE(msg,GException::GINTERNAL)
349#define G_THROW_EXTERNAL(msg) G_THROW_TYPE(msg,GException::GEXTERNAL)
350#define G_THROW_APPLICATION(msg) G_THROW_TYPE(msg,GException::GAPPLICATION)
351#define G_THROW_OTHER(msg) G_THROW_TYPE(msg,GException::GOTHER)
352
353// -------------- THE END
354
355#ifdef HAVE_NAMESPACES
356}
357# ifndef NOT_USING_DJVU_NAMESPACE
358using namespace DJVU;
359# endif
360#endif
361#endif
Note: See TracBrowser for help on using the repository browser.