Changeset 68 for pjproject/trunk


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

Changed syntax to support Windows SEH

Location:
pjproject/trunk/pjlib
Files:
4 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 
  • pjproject/trunk/pjlib/src/pj/except.c

    r66 r68  
    3636 
    3737 
     38#if !defined(PJ_EXCEPTION_USE_WIN32_SEH) || PJ_EXCEPTION_USE_WIN32_SEH==0 
    3839PJ_DEF(void) pj_throw_exception_(int exception_id) 
    3940{ 
     
    7071    pj_thread_local_set(thread_local_id, handler->prev); 
    7172} 
     73#endif 
    7274 
    7375#if defined(PJ_HAS_EXCEPTION_NAMES) && PJ_HAS_EXCEPTION_NAMES != 0 
  • pjproject/trunk/pjlib/src/pjlib-samples/except.c

    r65 r68  
    5555        randomly_throw_exception(); 
    5656    } 
    57     PJ_CATCH( NO_MEMORY ) { 
    58         puts("Can't allocate memory"); 
    59         return 0; 
    60     } 
    61     PJ_DEFAULT { 
     57    PJ_CATCH_ANY { 
    6258        pj_exception_id_t x_id; 
    6359         
  • pjproject/trunk/pjlib/src/pjlib-test/exception.c

    r65 r68  
    6666static int test(void) 
    6767{ 
     68    int rc = 0; 
    6869    PJ_USE_EXCEPTION; 
    69     int rc = 0; 
    7070 
    7171    /* 
     
    7575        rc = rc; 
    7676    } 
    77     PJ_CATCH( ID_1 ) { 
    78         rc = -2; 
    79     } 
    80     PJ_DEFAULT { 
     77    PJ_CATCH_ANY { 
    8178        rc = -3; 
    8279    } 
     
    9693        rc = -10; 
    9794    } 
    98     PJ_CATCH( ID_1 ) { 
    99         if (!rc) rc = 0; 
    100     } 
    101     PJ_DEFAULT { 
     95    PJ_CATCH_ANY { 
    10296        int id = PJ_GET_EXCEPTION(); 
    103         PJ_LOG(3,("", "...error: got unexpected exception %d (%s)",  
    104                   id, pj_exception_id_name(id))); 
    105         if (!rc) rc = -20; 
     97        if (id != ID_1) { 
     98            PJ_LOG(3,("", "...error: got unexpected exception %d (%s)",  
     99                      id, pj_exception_id_name(id))); 
     100            if (!rc) rc = -20; 
     101        } 
    106102    } 
    107103    PJ_END; 
     
    118114        rc = -25; 
    119115    } 
    120     PJ_CATCH( ID_1 ) { 
    121         if (!rc) rc = -30; 
    122     } 
    123     PJ_CATCH( ID_2 ) { 
    124         if (!rc) rc = 0; 
    125     } 
    126     PJ_DEFAULT { 
    127         if (!rc) rc = -40; 
     116    PJ_CATCH_ANY { 
     117        switch (PJ_GET_EXCEPTION()) { 
     118        case ID_1: 
     119            if (!rc) rc = -30; break; 
     120        case ID_2: 
     121            if (!rc) rc = 0; break; 
     122        default: 
     123            if (!rc) rc = -40; 
     124            break; 
     125        } 
    128126    } 
    129127    PJ_END; 
     
    140138        rc = -50; 
    141139    } 
    142     PJ_CATCH( ID_2 ) { 
    143         if (!rc) rc = -60; 
    144     } 
    145     PJ_DEFAULT { 
    146         if (!rc) rc = 0; 
     140    PJ_CATCH_ANY { 
     141        switch (PJ_GET_EXCEPTION()) { 
     142        case ID_1: 
     143            if (!rc) rc = 0; 
     144            break; 
     145        default: 
     146            if (!rc) rc = -60; 
     147            break; 
     148        } 
    147149    } 
    148150    PJ_END; 
Note: See TracChangeset for help on using the changeset viewer.