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

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject-2.1.0/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__ */
 
420
 
 
421