Ignore:
Timestamp:
Nov 21, 2005 4:57:02 PM (19 years ago)
Author:
bennylp
Message:

Changed syntax to support Windows SEH

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjlib/include/pj/except.h

    r66 r68  
    4646 * 
    4747 * This module provides exception handling syntactically similar to C++ in 
    48  * C language. The underlying mechanism use setjmp() and longjmp(), and since 
    49  * these constructs are ANSI standard, the mechanism here should be available 
    50  * on most platforms/compilers which are ANSI compliant. 
    51  * 
    52  * If ANSI libc is not available, then setjmp()/longjmp() implementation will 
    53  * be provided. See <pj/compat/setjmp.h> for compatibility. 
     48 * C language. In Win32 systems, it uses Windows Structured Exception 
     49 * Handling (SEH) if macro PJ_EXCEPTION_USE_WIN32_SEH is non-zero. 
     50 * Otherwise it will use setjmp() and longjmp(). 
     51 * 
     52 * On some platforms where setjmp/longjmp is not available, setjmp/longjmp  
     53 * implementation is provided. See <pj/compat/setjmp.h> for compatibility. 
    5454 * 
    5555 * The exception handling mechanism is completely thread safe, so the exception 
     
    6262 *  - You CAN NOT make nested exception in one single function without using 
    6363 *    a nested PJ_USE_EXCEPTION. 
    64  *  - Exceptions will always be caught by the first handle (unlike C++ where 
     64 *  - You can not provide more than PJ_CATCH or PJ_CATCH_ANY nor use PJ_CATCH 
     65 *    and PJ_CATCH_ANY for a single PJ_TRY. 
     66 *  - Exceptions will always be caught by the first handler (unlike C++ where 
    6567 *    exception is only caught if the type matches. 
    6668 * 
     
    7274   #define SYNTAX_ERROR  2 
    7375   
    74    int main() 
     76   int sample1() 
    7577   { 
    7678      PJ_USE_EXCEPTION;  // declare local exception stack. 
     
    8284        ... // handle exception 1 
    8385      } 
    84       PJ_CATCH(SYNTAX_ERROR) { 
    85         ... // handle exception 2 
     86      PJ_END; 
     87   } 
     88 
     89   int sample2() 
     90   { 
     91      PJ_USE_EXCEPTION;  // declare local exception stack. 
     92   
     93      PJ_TRY { 
     94        ...// do something.. 
    8695      } 
    87       PJ_DEFAULT { 
    88         ... // handle other exceptions. 
     96      PJ_CATCH_ANY { 
     97         if (PJ_GET_EXCEPTION() == NO_MEMORY) 
     98            ...; // handle no memory situation 
     99         else if (PJ_GET_EXCEPTION() == SYNTAX_ERROR) 
     100            ...; // handle syntax error 
    89101      } 
    90102      PJ_END; 
     
    127139 * Actually, this is just a macro to declare local variable which is used to 
    128140 * push the exception state to the exception stack. 
     141 * Note: you must specify PJ_USE_EXCEPTION as the last statement in the 
     142 * local variable declarations, since it may evaluate to nothing. 
    129143 * 
    130144 * \subsection PJ_TRY PJ_TRY 
     
    138152 * \a PJ_CATCH. 
    139153 * 
    140  * \subsection PJ_DEFAULT PJ_DEFAULT 
    141  * The \a PJ_DEFAULT keyword is normally followed by a block. This block will 
    142  * be executed if the exception being thrown doesn't match any of the \a 
    143  * PJ_CATCH specification. The \a PJ_DEFAULT block \b MUST be placed as the 
    144  * last block of the handlers. 
     154 * \subsection PJ_CATCH_ANY PJ_CATCH_ANY 
     155 * The \a PJ_CATCH is normally followed by a block. This block will be executed 
     156 * if any exception was raised in the TRY block. 
    145157 * 
    146158 * \subsection PJ_END PJ_END 
     
    149161 * \subsection PJ_GET_EXCEPTION PJ_GET_EXCEPTION(void) 
    150162 * Get the last exception thrown. This macro is normally called inside the 
    151  * \a PJ_CATCH or \a PJ_DEFAULT block, altough it can be used anywhere where 
     163 * \a PJ_CATCH or \a PJ_CATCH_ANY block, altough it can be used anywhere where 
    152164 * the \a PJ_USE_EXCEPTION definition is in scope. 
    153165 * 
     
    200212 
    201213/** @} */ 
     214 
     215#if defined(PJ_EXCEPTION_USE_WIN32_SEH) && PJ_EXCEPTION_USE_WIN32_SEH != 0 
     216/***************************************************************************** 
     217 ** 
     218 ** IMPLEMENTATION OF EXCEPTION USING WINDOWS SEH 
     219 ** 
     220 ****************************************************************************/ 
     221#define WIN32_LEAN_AND_MEAN 
     222#include <windows.h> 
     223 
     224PJ_IDECL_NO_RETURN(void) 
     225pj_throw_exception_(pj_exception_id_t id) PJ_ATTR_NORETURN 
     226{ 
     227    RaiseException(id,1,0,NULL); 
     228} 
     229 
     230#define PJ_USE_EXCEPTION     
     231#define PJ_TRY              __try 
     232#define PJ_CATCH(id)        __except(GetExceptionCode()==id ? \ 
     233                                      EXCEPTION_EXECUTE_HANDLER : \ 
     234                                      EXCEPTION_CONTINUE_SEARCH) 
     235#define PJ_CATCH_ANY        __except(EXCEPTION_EXECUTE_HANDLER) 
     236#define PJ_END               
     237#define PJ_THROW(id)        pj_throw_exception_(id) 
     238#define PJ_GET_EXCEPTION()  GetExceptionCode() 
     239 
     240#else 
     241/***************************************************************************** 
     242 ** 
     243 ** IMPLEMENTATION OF EXCEPTION USING GENERIC SETJMP/LONGJMP 
     244 ** 
     245 ****************************************************************************/ 
    202246 
    203247/** 
     
    253297 * @hideinitializer 
    254298 */ 
    255 #define PJ_DEFAULT          else 
     299#define PJ_CATCH_ANY        else 
    256300 
    257301/** 
     
    276320#define PJ_GET_EXCEPTION()      (pj_x_code__) 
    277321 
     322#endif  /* PJ_EXCEPTION_USE_WIN32_SEH */ 
     323 
     324 
    278325PJ_END_DECL 
    279326 
Note: See TracChangeset for help on using the changeset viewer.