~ubuntu-branches/ubuntu/trusty/sflphone/trusty

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject-2.0.1/pjlib/include/pj/except.h

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2014-01-28 18:23:36 UTC
  • mfrom: (4.3.4 sid)
  • Revision ID: package-import@ubuntu.com-20140128182336-jrsv0k9u6cawc068
Tags: 1.3.0-1
* New upstream release 
  - Fixes "New Upstream Release" (Closes: #735846)
  - Fixes "Ringtone does not stop" (Closes: #727164)
  - Fixes "[sflphone-kde] crash on startup" (Closes: #718178)
  - Fixes "sflphone GUI crashes when call is hung up" (Closes: #736583)
* Build-Depends: ensure GnuTLS 2.6
  - libucommon-dev (>= 6.0.7-1.1), libccrtp-dev (>= 2.0.6-3)
  - Fixes "FTBFS Build-Depends libgnutls{26,28}-dev" (Closes: #722040)
* Fix "boost 1.49 is going away" unversioned Build-Depends: (Closes: #736746)
* Add Build-Depends: libsndfile-dev, nepomuk-core-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Id: except.h 3553 2011-05-05 06:14:19Z nanang $ */
2
 
/*
3
 
 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4
 
 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
5
 
 *
6
 
 * This program is free software; you can redistribute it and/or modify
7
 
 * it under the terms of the GNU General Public License as published by
8
 
 * the Free Software Foundation; either version 2 of the License, or
9
 
 * (at your option) any later version.
10
 
 *
11
 
 * This program is distributed in the hope that it will be useful,
12
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
 * GNU General Public License for more details.
15
 
 *
16
 
 * You should have received a copy of the GNU General Public License
17
 
 * along with this program; if not, write to the Free Software
18
 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 
 */
20
 
#ifndef __PJ_EXCEPTION_H__
21
 
#define __PJ_EXCEPTION_H__
22
 
 
23
 
/**
24
 
 * @file except.h
25
 
 * @brief Exception Handling in C.
26
 
 */
27
 
 
28
 
#include <pj/types.h>
29
 
#include <pj/compat/setjmp.h>
30
 
#include <pj/log.h>
31
 
 
32
 
 
33
 
PJ_BEGIN_DECL
34
 
 
35
 
 
36
 
/**
37
 
 * @defgroup PJ_EXCEPT Exception Handling
38
 
 * @ingroup PJ_MISC
39
 
 * @{
40
 
 *
41
 
 * \section pj_except_sample_sec Quick Example
42
 
 *
43
 
 * For the impatient, take a look at some examples:
44
 
 *  - @ref page_pjlib_samples_except_c
45
 
 *  - @ref page_pjlib_exception_test
46
 
 *
47
 
 * \section pj_except_except Exception Handling
48
 
 *
49
 
 * This module provides exception handling syntactically similar to C++ in
50
 
 * C language. In Win32 systems, it uses Windows Structured Exception
51
 
 * Handling (SEH) if macro PJ_EXCEPTION_USE_WIN32_SEH is non-zero.
52
 
 * Otherwise it will use setjmp() and longjmp().
53
 
 *
54
 
 * On some platforms where setjmp/longjmp is not available, setjmp/longjmp
55
 
 * implementation is provided. See <pj/compat/setjmp.h> for compatibility.
56
 
 *
57
 
 * The exception handling mechanism is completely thread safe, so the exception
58
 
 * thrown by one thread will not interfere with other thread.
59
 
 *
60
 
 * The exception handling constructs are similar to C++. The blocks will be
61
 
 * constructed similar to the following sample:
62
 
 *
63
 
 * \verbatim
64
 
   #define NO_MEMORY     1
65
 
   #define SYNTAX_ERROR  2
66
 
 
67
 
   int sample1()
68
 
   {
69
 
      PJ_USE_EXCEPTION;  // declare local exception stack.
70
 
 
71
 
      PJ_TRY {
72
 
        ...// do something..
73
 
      }
74
 
      PJ_CATCH(NO_MEMORY) {
75
 
        ... // handle exception 1
76
 
      }
77
 
      PJ_END;
78
 
   }
79
 
 
80
 
   int sample2()
81
 
   {
82
 
      PJ_USE_EXCEPTION;  // declare local exception stack.
83
 
 
84
 
      PJ_TRY {
85
 
        ...// do something..
86
 
      }
87
 
      PJ_CATCH_ANY {
88
 
         if (PJ_GET_EXCEPTION() == NO_MEMORY)
89
 
            ...; // handle no memory situation
90
 
         else if (PJ_GET_EXCEPTION() == SYNTAX_ERROR)
91
 
            ...; // handle syntax error
92
 
      }
93
 
      PJ_END;
94
 
   }
95
 
   \endverbatim
96
 
 *
97
 
 * The above sample uses hard coded exception ID. It is @b strongly
98
 
 * recommended that applications request a unique exception ID instead
99
 
 * of hard coded value like above.
100
 
 *
101
 
 * \section pj_except_reg Exception ID Allocation
102
 
 *
103
 
 * To ensure that exception ID (number) are used consistently and to
104
 
 * prevent ID collisions in an application, it is strongly suggested that
105
 
 * applications allocate an exception ID for each possible exception
106
 
 * type. As a bonus of this process, the application can identify
107
 
 * the name of the exception when the particular exception is thrown.
108
 
 *
109
 
 * Exception ID management are performed with the following APIs:
110
 
 *  - #pj_exception_id_alloc().
111
 
 *  - #pj_exception_id_free().
112
 
 *  - #pj_exception_id_name().
113
 
 *
114
 
 *
115
 
 * PJLIB itself automatically allocates one exception id, i.e.
116
 
 * #PJ_NO_MEMORY_EXCEPTION which is declared in <pj/pool.h>. This exception
117
 
 * ID is raised by default pool policy when it fails to allocate memory.
118
 
 *
119
 
 * CAVEATS:
120
 
 *  - unlike C++ exception, the scheme here won't call destructors of local
121
 
 *    objects if exception is thrown. Care must be taken when a function
122
 
 *    hold some resorce such as pool or mutex etc.
123
 
 *  - You CAN NOT make nested exception in one single function without using
124
 
 *    a nested PJ_USE_EXCEPTION. Samples:
125
 
  \verbatim
126
 
        void wrong_sample()
127
 
        {
128
 
            PJ_USE_EXCEPTION;
129
 
 
130
 
            PJ_TRY {
131
 
                // Do stuffs
132
 
                ...
133
 
            }
134
 
            PJ_CATCH_ANY {
135
 
                // Do other stuffs
136
 
                ....
137
 
                ..
138
 
 
139
 
                // The following block is WRONG! You MUST declare
140
 
                // PJ_USE_EXCEPTION once again in this block.
141
 
                PJ_TRY {
142
 
                    ..
143
 
                }
144
 
                PJ_CATCH_ANY {
145
 
                    ..
146
 
                }
147
 
                PJ_END;
148
 
            }
149
 
            PJ_END;
150
 
        }
151
 
 
152
 
  \endverbatim
153
 
 
154
 
 *  - You MUST NOT exit the function inside the PJ_TRY block. The correct way
155
 
 *    is to return from the function after PJ_END block is executed.
156
 
 *    For example, the following code will yield crash not in this code,
157
 
 *    but rather in the subsequent execution of PJ_TRY block:
158
 
  \verbatim
159
 
        void wrong_sample()
160
 
        {
161
 
            PJ_USE_EXCEPTION;
162
 
 
163
 
            PJ_TRY {
164
 
                // do some stuffs
165
 
                ...
166
 
                return;         <======= DO NOT DO THIS!
167
 
            }
168
 
            PJ_CATCH_ANY {
169
 
            }
170
 
            PJ_END;
171
 
        }
172
 
  \endverbatim
173
 
 
174
 
 *  - You can not provide more than PJ_CATCH or PJ_CATCH_ANY nor use PJ_CATCH
175
 
 *    and PJ_CATCH_ANY for a single PJ_TRY.
176
 
 *  - Exceptions will always be caught by the first handler (unlike C++ where
177
 
 *    exception is only caught if the type matches.
178
 
 
179
 
 * \section PJ_EX_KEYWORDS Keywords
180
 
 *
181
 
 * \subsection PJ_THROW PJ_THROW(expression)
182
 
 * Throw an exception. The expression thrown is an integer as the result of
183
 
 * the \a expression. This keyword can be specified anywhere within the
184
 
 * program.
185
 
 *
186
 
 * \subsection PJ_USE_EXCEPTION PJ_USE_EXCEPTION
187
 
 * Specify this in the variable definition section of the function block
188
 
 * (or any blocks) to specify that the block has \a PJ_TRY/PJ_CATCH exception
189
 
 * block.
190
 
 * Actually, this is just a macro to declare local variable which is used to
191
 
 * push the exception state to the exception stack.
192
 
 * Note: you must specify PJ_USE_EXCEPTION as the last statement in the
193
 
 * local variable declarations, since it may evaluate to nothing.
194
 
 *
195
 
 * \subsection PJ_TRY PJ_TRY
196
 
 * The \a PJ_TRY keyword is typically followed by a block. If an exception is
197
 
 * thrown in this block, then the execution will resume to the \a PJ_CATCH
198
 
 * handler.
199
 
 *
200
 
 * \subsection PJ_CATCH PJ_CATCH(expression)
201
 
 * The \a PJ_CATCH is normally followed by a block. This block will be executed
202
 
 * if the exception being thrown is equal to the expression specified in the
203
 
 * \a PJ_CATCH.
204
 
 *
205
 
 * \subsection PJ_CATCH_ANY PJ_CATCH_ANY
206
 
 * The \a PJ_CATCH is normally followed by a block. This block will be executed
207
 
 * if any exception was raised in the TRY block.
208
 
 *
209
 
 * \subsection PJ_END PJ_END
210
 
 * Specify this keyword to mark the end of \a PJ_TRY / \a PJ_CATCH blocks.
211
 
 *
212
 
 * \subsection PJ_GET_EXCEPTION PJ_GET_EXCEPTION(void)
213
 
 * Get the last exception thrown. This macro is normally called inside the
214
 
 * \a PJ_CATCH or \a PJ_CATCH_ANY block, altough it can be used anywhere where
215
 
 * the \a PJ_USE_EXCEPTION definition is in scope.
216
 
 *
217
 
 *
218
 
 * \section pj_except_examples_sec Examples
219
 
 *
220
 
 * For some examples on how to use the exception construct, please see:
221
 
 *  - @ref page_pjlib_samples_except_c
222
 
 *  - @ref page_pjlib_exception_test
223
 
 */
224
 
 
225
 
/**
226
 
 * Allocate a unique exception id.
227
 
 * Applications don't have to allocate a unique exception ID before using
228
 
 * the exception construct. However, by doing so it ensures that there is
229
 
 * no collisions of exception ID.
230
 
 *
231
 
 * As a bonus, when exception number is acquired through this function,
232
 
 * the library can assign name to the exception (only if
233
 
 * PJ_HAS_EXCEPTION_NAMES is enabled (default is yes)) and find out the
234
 
 * exception name when it catches an exception.
235
 
 *
236
 
 * @param name      Name to be associated with the exception ID.
237
 
 * @param id        Pointer to receive the ID.
238
 
 *
239
 
 * @return          PJ_SUCCESS on success or PJ_ETOOMANY if the library
240
 
 *                  is running out out ids.
241
 
 */
242
 
PJ_DECL(pj_status_t) pj_exception_id_alloc(const char *name,
243
 
                                           pj_exception_id_t *id);
244
 
 
245
 
/**
246
 
 * Free an exception id.
247
 
 *
248
 
 * @param id        The exception ID.
249
 
 *
250
 
 * @return          PJ_SUCCESS or the appropriate error code.
251
 
 */
252
 
PJ_DECL(pj_status_t) pj_exception_id_free(pj_exception_id_t id);
253
 
 
254
 
/**
255
 
 * Retrieve name associated with the exception id.
256
 
 *
257
 
 * @param id        The exception ID.
258
 
 *
259
 
 * @return          The name associated with the specified ID.
260
 
 */
261
 
PJ_DECL(const char*) pj_exception_id_name(pj_exception_id_t id);
262
 
 
263
 
 
264
 
/** @} */
265
 
 
266
 
#if defined(PJ_EXCEPTION_USE_WIN32_SEH) && PJ_EXCEPTION_USE_WIN32_SEH != 0
267
 
/*****************************************************************************
268
 
 **
269
 
 ** IMPLEMENTATION OF EXCEPTION USING WINDOWS SEH
270
 
 **
271
 
 ****************************************************************************/
272
 
#define WIN32_LEAN_AND_MEAN
273
 
#include <windows.h>
274
 
 
275
 
PJ_IDECL_NO_RETURN(void)
276
 
pj_throw_exception_(pj_exception_id_t id) PJ_ATTR_NORETURN
277
 
{
278
 
    RaiseException(id,1,0,NULL);
279
 
}
280
 
 
281
 
#define PJ_USE_EXCEPTION
282
 
#define PJ_TRY              __try
283
 
#define PJ_CATCH(id)        __except(GetExceptionCode()==id ? \
284
 
                                      EXCEPTION_EXECUTE_HANDLER : \
285
 
                                      EXCEPTION_CONTINUE_SEARCH)
286
 
#define PJ_CATCH_ANY        __except(EXCEPTION_EXECUTE_HANDLER)
287
 
#define PJ_END
288
 
#define PJ_THROW(id)        pj_throw_exception_(id)
289
 
#define PJ_GET_EXCEPTION()  GetExceptionCode()
290
 
 
291
 
 
292
 
#elif defined(PJ_SYMBIAN) && PJ_SYMBIAN!=0
293
 
/*****************************************************************************
294
 
 **
295
 
 ** IMPLEMENTATION OF EXCEPTION USING SYMBIAN LEAVE/TRAP FRAMEWORK
296
 
 **
297
 
 ****************************************************************************/
298
 
 
299
 
/* To include this file, the source file must be compiled as
300
 
 * C++ code!
301
 
 */
302
 
#ifdef __cplusplus
303
 
 
304
 
class TPjException
305
 
{
306
 
public:
307
 
    int code_;
308
 
};
309
 
 
310
 
#define PJ_USE_EXCEPTION
311
 
#define PJ_TRY                  try
312
 
//#define PJ_CATCH(id)
313
 
#define PJ_CATCH_ANY            catch (const TPjException & pj_excp_)
314
 
#define PJ_END
315
 
#define PJ_THROW(x_id)          do { TPjException e; e.code_=x_id; throw e;} \
316
 
                                while (0)
317
 
#define PJ_GET_EXCEPTION()      pj_excp_.code_
318
 
 
319
 
#else
320
 
 
321
 
#define PJ_USE_EXCEPTION
322
 
#define PJ_TRY
323
 
#define PJ_CATCH_ANY            if (0)
324
 
#define PJ_END
325
 
#define PJ_THROW(x_id)          do { PJ_LOG(1,("PJ_THROW"," error code = %d",x_id)); } while (0)
326
 
#define PJ_GET_EXCEPTION()      0
327
 
 
328
 
#endif  /* __cplusplus */
329
 
 
330
 
#else
331
 
/*****************************************************************************
332
 
 **
333
 
 ** IMPLEMENTATION OF EXCEPTION USING GENERIC SETJMP/LONGJMP
334
 
 **
335
 
 ****************************************************************************/
336
 
 
337
 
/**
338
 
 * This structure (which should be invisible to user) manages the TRY handler
339
 
 * stack.
340
 
 */
341
 
struct pj_exception_state_t
342
 
{
343
 
    struct pj_exception_state_t *prev;  /**< Previous state in the list. */
344
 
    pj_jmp_buf state;                   /**< jmp_buf.                    */
345
 
};
346
 
 
347
 
/**
348
 
 * Throw exception.
349
 
 * @param id    Exception Id.
350
 
 */
351
 
PJ_DECL_NO_RETURN(void)
352
 
pj_throw_exception_(pj_exception_id_t id) PJ_ATTR_NORETURN;
353
 
 
354
 
/**
355
 
 * Push exception handler.
356
 
 */
357
 
PJ_DECL(void) pj_push_exception_handler_(struct pj_exception_state_t *rec);
358
 
 
359
 
/**
360
 
 * Pop exception handler.
361
 
 */
362
 
PJ_DECL(void) pj_pop_exception_handler_(struct pj_exception_state_t *rec);
363
 
 
364
 
/**
365
 
 * Declare that the function will use exception.
366
 
 * @hideinitializer
367
 
 */
368
 
#define PJ_USE_EXCEPTION    struct pj_exception_state_t pj_x_except__; int pj_x_code__
369
 
 
370
 
/**
371
 
 * Start exception specification block.
372
 
 * @hideinitializer
373
 
 */
374
 
#define PJ_TRY              if (1) { \
375
 
                                pj_push_exception_handler_(&pj_x_except__); \
376
 
                                pj_x_code__ = pj_setjmp(pj_x_except__.state); \
377
 
                                if (pj_x_code__ == 0)
378
 
/**
379
 
 * Catch the specified exception Id.
380
 
 * @param id    The exception number to catch.
381
 
 * @hideinitializer
382
 
 */
383
 
#define PJ_CATCH(id)        else if (pj_x_code__ == (id))
384
 
 
385
 
/**
386
 
 * Catch any exception number.
387
 
 * @hideinitializer
388
 
 */
389
 
#define PJ_CATCH_ANY        else
390
 
 
391
 
/**
392
 
 * End of exception specification block.
393
 
 * @hideinitializer
394
 
 */
395
 
#define PJ_END                  pj_pop_exception_handler_(&pj_x_except__); \
396
 
                            } else {}
397
 
 
398
 
/**
399
 
 * Throw exception.
400
 
 * @param exception_id  The exception number.
401
 
 * @hideinitializer
402
 
 */
403
 
#define PJ_THROW(exception_id)  pj_throw_exception_(exception_id)
404
 
 
405
 
/**
406
 
 * Get current exception.
407
 
 * @return      Current exception code.
408
 
 * @hideinitializer
409
 
 */
410
 
#define PJ_GET_EXCEPTION()      (pj_x_code__)
411
 
 
412
 
#endif  /* PJ_EXCEPTION_USE_WIN32_SEH */
413
 
 
414
 
 
415
 
PJ_END_DECL
416
 
 
417
 
 
418
 
 
419
 
#endif  /* __PJ_EXCEPTION_H__ */