source: trunk/libdjvu/GException.h @ 15

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

needed libs update

File size: 12.1 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.10 2005/06/07 23:42:22 leonb Exp $
55// $Name: release_3_5_16 $
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.10 2005/06/07 23:42:22 leonb Exp $# */
120//@{
121
122#include "DjVuGlobal.h"
123
124#ifdef HAVE_NAMESPACES
125namespace DJVU {
126# ifdef NOT_DEFINED // Just to fool emacs c++ mode
127}
128#endif
129#endif
130
131
132
133/** Exception class. 
134    The library always uses macros #G_TRY#, #G_THROW#, #G_CATCH# and #G_ENDCATCH# for
135    throwing and catching exceptions (see \Ref{GException.h}). These macros
136    only deal with exceptions of type #GException#. */
137
138class GException {
139public:
140  enum source_type { GINTERNAL=0, GEXTERNAL, GAPPLICATION, GOTHER };
141  /** Constructs a GException.  This constructor is usually called by macro
142      #G_THROW#.  Argument #cause# is a plain text error message. As a
143      convention, string #ByteStream::EndOfFile# is used when reaching an unexpected
144      end-of-file condition and string #DataPool::Stop# is used when the user
145      interrupts the execution. The remaining arguments are usually provided
146      by the predefined macros #__FILE__#, #__LINE__#, and (G++ and EGCS only)
147      #__PRETTY_FUNCTION__#.  */
148  GException (const char *cause, const char *file=0, int line=0, 
149              const char *func=0, const source_type source=GINTERNAL);
150
151  /** Copy Constructor. */
152  GException (const GException & exc);
153 
154  /** Null Constructor. */
155  GException ();
156 
157  /** Destructor. */
158  virtual ~GException(void);
159 
160  /** Copy Operator. */
161  GException & operator=(const GException & exc);
162 
163  /** Prints an error message on stderr.
164      This function no longer takes a message parameter because
165      some instances used a i18n message id and other instances
166      used a literal string. */
167  void perror(void) const;
168 
169  /** Returns the string describing the cause of the exception.  The returned
170      pointer is never null.  Exception handlers should not rely on the value
171      of the string #cause#.  As a convention however, string
172      #ByteStream::EndOfFile# is used
173      when reaching an unexpected end-of-file condition and string
174      #DataPool::Stop# is used when the user interrupts the execution. These
175      strings can be tested by the exception handlers, with
176      #cmp_cause#. Similar conventional strings may be defined
177      in the future. They all will be small strings with only uppercase
178      characters. */
179  const char* get_cause(void) const;
180
181  /** Compares the cause with the specified string, ignoring anything after
182      the first tab. */
183  int cmp_cause(const char s2[]) const;
184
185  /** Compares the cause with the specified string, ignoring anything after
186      the first tab. */
187  static int cmp_cause(const char s1[],const char s2[]);
188
189  /** Returns the function name from which the exception was thrown.
190      A null pointer is returned if no function name is available. */
191  const char* get_function(void) const { return func; }
192 
193  /** Returns the file name from which the exception was thrown.
194      A null pointer is returned if no file name is available. */
195  const char* get_file(void) const { return file; }
196 
197  /** Returns the exception source */
198  source_type get_source(void) const { return source; }
199 
200  /** Returns the line number from which the exception was thrown.
201      A zero is returned if no line number is available. */
202  int get_line(void) const { return line; };
203 
204  //  Magic cause string
205  static const char * const outofmemory;
206
207private:
208  const char *cause;
209  const char *file;
210  const char *func;
211  int line;
212  source_type source;
213};
214
215//@}
216
217#undef G_TRY
218#undef G_CATCH
219#undef G_CATCH_ALL
220#undef G_ENDCATCH
221#undef G_RETHROW
222#undef G_THROW
223#undef G_THROW_TYPE
224#undef G_THROW_INTERNAL
225#undef G_THROW_EXTERNAL
226#undef G_THROW_APPLICATION
227#undef G_THROW_OTHER
228
229// Check if compiler supports native exceptions
230#if defined(_MSC_VER)
231#define CPP_SUPPORTS_EXCEPTIONS
232#endif
233#if defined(__MWERKS__)
234#define CPP_SUPPORTS_EXCEPTIONS
235#endif
236#if defined(__EXCEPTIONS)
237#define CPP_SUPPORTS_EXCEPTIONS
238#endif
239// Decide which exception model to use
240#ifndef CPP_SUPPORTS_EXCEPTIONS
241#ifndef USE_EXCEPTION_EMULATION
242#define USE_EXCEPTION_EMULATION
243#endif
244#endif
245
246
247#ifndef USE_EXCEPTION_EMULATION
248
249// Compiler supports ANSI C++ exceptions.
250// Defined exception macros accordingly.
251
252class GExceptionHandler {
253public:
254#ifndef NO_LIBGCC_HOOKS
255  static void exthrow(const GException &) no_return;
256#else
257  static void exthrow(const GException ) no_return;
258#endif /* NO_LIBGCC_HOOKS */
259  static void rethrow(void) no_return;
260};
261
262#define G_TRY        try
263#define G_CATCH(n)   catch(const GException &n) {
264#define G_CATCH_ALL   catch(...) {
265#define G_ENDCATCH   }
266#define G_RETHROW    GExceptionHandler::rethrow()
267#define G_EMTHROW(ex)  GExceptionHandler::exthrow(ex)
268#ifdef __GNUG__
269#define G_THROW_TYPE(msg,xtype) GExceptionHandler::exthrow \
270  (GException(msg, __FILE__, __LINE__, __PRETTY_FUNCTION__, xtype))
271#else
272#define G_THROW_TYPE(msg,xtype) GExceptionHandler::exthrow \
273  (GException(msg, __FILE__, __LINE__,0, xtype))
274#endif
275
276#else // USE_EXCEPTION_EMULATION
277
278// Compiler does not support ANSI C++ exceptions.
279// Emulate with setjmp/longjmp.
280
281#include <setjmp.h>
282
283class GExceptionHandler {
284public:
285  jmp_buf jump;
286  GExceptionHandler *next;
287  GException current;
288public:
289  static GExceptionHandler *head;
290  static void emthrow(const GException &) no_return;
291public:
292  GExceptionHandler() { next = head; };
293  ~GExceptionHandler() { head = next; };
294};
295
296#define G_TRY    do { GExceptionHandler __exh; \
297                      if (!setjmp(__exh.jump)) \
298                      { GExceptionHandler::head = &__exh;
299
300#define G_CATCH_ALL } else { GExceptionHandler::head = __exh.next;
301#define G_CATCH(n) G_CATCH_ALL const GException& n = __exh.current;
302
303#define G_ENDCATCH } } while(0)
304
305#define G_RETHROW    GExceptionHandler::emthrow(__exh.current)
306
307#ifdef __GNUG__
308#define G_THROW_TYPE(msg,xtype) GExceptionHandler::emthrow \
309  (GException(msg, __FILE__, __LINE__, __PRETTY_FUNCTION__, xtype))
310#define G_EMTHROW(ex) GExceptionHandler::emthrow(ex)
311#else
312#define G_THROW_TYPE(m,xtype) GExceptionHandler::emthrow \
313  (GException(m, __FILE__, __LINE__,0, xtype))
314#define G_EMTHROW(ex) GExceptionHandler::emthrow(ex)
315#endif
316
317#endif // !CPP_SUPPORTS_EXCEPTIONS
318
319
320inline void
321G_EXTHROW
322(const GException &ex,const char *msg=0,const char *file=0,int line=0,
323  const char *func=0, const GException::source_type source=GException::GINTERNAL)
324{
325  G_EMTHROW( (msg||file||line||func)?
326      GException(msg?msg:ex.get_cause(),
327        file?file:ex.get_file(),
328        line?line:ex.get_line(),
329        func?func:ex.get_function(),
330        source)
331  :ex);
332}
333
334inline void
335G_EXTHROW
336(const char msg[],const char *file=0,int line=0,const char *func=0,
337  const GException::source_type source=GException::GINTERNAL )
338{
339  G_EMTHROW(GException(msg,file,line,func,source));
340}
341
342#define G_THROW(msg) G_THROW_TYPE(msg,GException::GINTERNAL)
343#define G_THROW_INTERNAL(msg) G_THROW_TYPE(msg,GException::GINTERNAL)
344#define G_THROW_EXTERNAL(msg) G_THROW_TYPE(msg,GException::GEXTERNAL)
345#define G_THROW_APPLICATION(msg) G_THROW_TYPE(msg,GException::GAPPLICATION)
346#define G_THROW_OTHER(msg) G_THROW_TYPE(msg,GException::GOTHER)
347
348// -------------- THE END
349
350#ifdef HAVE_NAMESPACES
351}
352# ifndef NOT_USING_DJVU_NAMESPACE
353using namespace DJVU;
354# endif
355#endif
356#endif
Note: See TracBrowser for help on using the repository browser.