source: trunk/libdjvu/GException.h @ 206

Last change on this file since 206 was 206, checked in by Eugene Romanenko, 14 years ago

DJVU plugin: djvulibre updated to version 3.5.19

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