Changeset 68
- Timestamp:
- Nov 21, 2005 4:57:02 PM (19 years ago)
- Location:
- pjproject/trunk/pjlib
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjlib/include/pj/except.h
r66 r68 46 46 * 47 47 * This module provides exception handling syntactically similar to C++ in 48 * C language. The underlying mechanism use setjmp() and longjmp(), and since49 * these constructs are ANSI standard, the mechanism here should be available50 * on most platforms/compilers which are ANSI compliant.51 * 52 * If ANSI libc is not available, then setjmp()/longjmp() implementation will53 * beprovided. 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. 54 54 * 55 55 * The exception handling mechanism is completely thread safe, so the exception … … 62 62 * - You CAN NOT make nested exception in one single function without using 63 63 * 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 65 67 * exception is only caught if the type matches. 66 68 * … … 72 74 #define SYNTAX_ERROR 2 73 75 74 int main()76 int sample1() 75 77 { 76 78 PJ_USE_EXCEPTION; // declare local exception stack. … … 82 84 ... // handle exception 1 83 85 } 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.. 86 95 } 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 89 101 } 90 102 PJ_END; … … 127 139 * Actually, this is just a macro to declare local variable which is used to 128 140 * 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. 129 143 * 130 144 * \subsection PJ_TRY PJ_TRY … … 138 152 * \a PJ_CATCH. 139 153 * 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. 145 157 * 146 158 * \subsection PJ_END PJ_END … … 149 161 * \subsection PJ_GET_EXCEPTION PJ_GET_EXCEPTION(void) 150 162 * Get the last exception thrown. This macro is normally called inside the 151 * \a PJ_CATCH or \a PJ_ DEFAULTblock, altough it can be used anywhere where163 * \a PJ_CATCH or \a PJ_CATCH_ANY block, altough it can be used anywhere where 152 164 * the \a PJ_USE_EXCEPTION definition is in scope. 153 165 * … … 200 212 201 213 /** @} */ 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 224 PJ_IDECL_NO_RETURN(void) 225 pj_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 ****************************************************************************/ 202 246 203 247 /** … … 253 297 * @hideinitializer 254 298 */ 255 #define PJ_ DEFAULTelse299 #define PJ_CATCH_ANY else 256 300 257 301 /** … … 276 320 #define PJ_GET_EXCEPTION() (pj_x_code__) 277 321 322 #endif /* PJ_EXCEPTION_USE_WIN32_SEH */ 323 324 278 325 PJ_END_DECL 279 326 -
pjproject/trunk/pjlib/src/pj/except.c
r66 r68 36 36 37 37 38 #if !defined(PJ_EXCEPTION_USE_WIN32_SEH) || PJ_EXCEPTION_USE_WIN32_SEH==0 38 39 PJ_DEF(void) pj_throw_exception_(int exception_id) 39 40 { … … 70 71 pj_thread_local_set(thread_local_id, handler->prev); 71 72 } 73 #endif 72 74 73 75 #if defined(PJ_HAS_EXCEPTION_NAMES) && PJ_HAS_EXCEPTION_NAMES != 0 -
pjproject/trunk/pjlib/src/pjlib-samples/except.c
r65 r68 55 55 randomly_throw_exception(); 56 56 } 57 PJ_CATCH( NO_MEMORY ) { 58 puts("Can't allocate memory"); 59 return 0; 60 } 61 PJ_DEFAULT { 57 PJ_CATCH_ANY { 62 58 pj_exception_id_t x_id; 63 59 -
pjproject/trunk/pjlib/src/pjlib-test/exception.c
r65 r68 66 66 static int test(void) 67 67 { 68 int rc = 0; 68 69 PJ_USE_EXCEPTION; 69 int rc = 0;70 70 71 71 /* … … 75 75 rc = rc; 76 76 } 77 PJ_CATCH( ID_1 ) { 78 rc = -2; 79 } 80 PJ_DEFAULT { 77 PJ_CATCH_ANY { 81 78 rc = -3; 82 79 } … … 96 93 rc = -10; 97 94 } 98 PJ_CATCH( ID_1 ) { 99 if (!rc) rc = 0; 100 } 101 PJ_DEFAULT { 95 PJ_CATCH_ANY { 102 96 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 } 106 102 } 107 103 PJ_END; … … 118 114 rc = -25; 119 115 } 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 } 128 126 } 129 127 PJ_END; … … 140 138 rc = -50; 141 139 } 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 } 147 149 } 148 150 PJ_END;
Note: See TracChangeset
for help on using the changeset viewer.