Index: /pjproject/trunk/pjlib/include/pj/except.h
===================================================================
--- /pjproject/trunk/pjlib/include/pj/except.h	(revision 67)
+++ /pjproject/trunk/pjlib/include/pj/except.h	(revision 68)
@@ -46,10 +46,10 @@
  *
  * This module provides exception handling syntactically similar to C++ in
- * C language. The underlying mechanism use setjmp() and longjmp(), and since
- * these constructs are ANSI standard, the mechanism here should be available
- * on most platforms/compilers which are ANSI compliant.
- *
- * If ANSI libc is not available, then setjmp()/longjmp() implementation will
- * be provided. See <pj/compat/setjmp.h> for compatibility.
+ * C language. In Win32 systems, it uses Windows Structured Exception
+ * Handling (SEH) if macro PJ_EXCEPTION_USE_WIN32_SEH is non-zero.
+ * Otherwise it will use setjmp() and longjmp().
+ *
+ * On some platforms where setjmp/longjmp is not available, setjmp/longjmp 
+ * implementation is provided. See <pj/compat/setjmp.h> for compatibility.
  *
  * The exception handling mechanism is completely thread safe, so the exception
@@ -62,5 +62,7 @@
  *  - You CAN NOT make nested exception in one single function without using
  *    a nested PJ_USE_EXCEPTION.
- *  - Exceptions will always be caught by the first handle (unlike C++ where
+ *  - You can not provide more than PJ_CATCH or PJ_CATCH_ANY nor use PJ_CATCH
+ *    and PJ_CATCH_ANY for a single PJ_TRY.
+ *  - Exceptions will always be caught by the first handler (unlike C++ where
  *    exception is only caught if the type matches.
  *
@@ -72,5 +74,5 @@
    #define SYNTAX_ERROR  2
   
-   int main()
+   int sample1()
    {
       PJ_USE_EXCEPTION;  // declare local exception stack.
@@ -82,9 +84,19 @@
         ... // handle exception 1
       }
-      PJ_CATCH(SYNTAX_ERROR) {
-        ... // handle exception 2
+      PJ_END;
+   }
+
+   int sample2()
+   {
+      PJ_USE_EXCEPTION;  // declare local exception stack.
+  
+      PJ_TRY {
+        ...// do something..
       }
-      PJ_DEFAULT {
-        ... // handle other exceptions.
+      PJ_CATCH_ANY {
+         if (PJ_GET_EXCEPTION() == NO_MEMORY)
+	    ...; // handle no memory situation
+	 else if (PJ_GET_EXCEPTION() == SYNTAX_ERROR)
+	    ...; // handle syntax error
       }
       PJ_END;
@@ -127,4 +139,6 @@
  * Actually, this is just a macro to declare local variable which is used to
  * push the exception state to the exception stack.
+ * Note: you must specify PJ_USE_EXCEPTION as the last statement in the
+ * local variable declarations, since it may evaluate to nothing.
  *
  * \subsection PJ_TRY PJ_TRY
@@ -138,9 +152,7 @@
  * \a PJ_CATCH.
  *
- * \subsection PJ_DEFAULT PJ_DEFAULT
- * The \a PJ_DEFAULT keyword is normally followed by a block. This block will
- * be executed if the exception being thrown doesn't match any of the \a
- * PJ_CATCH specification. The \a PJ_DEFAULT block \b MUST be placed as the
- * last block of the handlers.
+ * \subsection PJ_CATCH_ANY PJ_CATCH_ANY
+ * The \a PJ_CATCH is normally followed by a block. This block will be executed
+ * if any exception was raised in the TRY block.
  *
  * \subsection PJ_END PJ_END
@@ -149,5 +161,5 @@
  * \subsection PJ_GET_EXCEPTION PJ_GET_EXCEPTION(void)
  * Get the last exception thrown. This macro is normally called inside the
- * \a PJ_CATCH or \a PJ_DEFAULT block, altough it can be used anywhere where
+ * \a PJ_CATCH or \a PJ_CATCH_ANY block, altough it can be used anywhere where
  * the \a PJ_USE_EXCEPTION definition is in scope.
  *
@@ -200,4 +212,36 @@
 
 /** @} */
+
+#if defined(PJ_EXCEPTION_USE_WIN32_SEH) && PJ_EXCEPTION_USE_WIN32_SEH != 0
+/*****************************************************************************
+ **
+ ** IMPLEMENTATION OF EXCEPTION USING WINDOWS SEH
+ **
+ ****************************************************************************/
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+PJ_IDECL_NO_RETURN(void)
+pj_throw_exception_(pj_exception_id_t id) PJ_ATTR_NORETURN
+{
+    RaiseException(id,1,0,NULL);
+}
+
+#define PJ_USE_EXCEPTION    
+#define PJ_TRY		    __try
+#define PJ_CATCH(id)	    __except(GetExceptionCode()==id ? \
+				      EXCEPTION_EXECUTE_HANDLER : \
+				      EXCEPTION_CONTINUE_SEARCH)
+#define PJ_CATCH_ANY	    __except(EXCEPTION_EXECUTE_HANDLER)
+#define PJ_END		    
+#define PJ_THROW(id)	    pj_throw_exception_(id)
+#define PJ_GET_EXCEPTION()  GetExceptionCode()
+
+#else
+/*****************************************************************************
+ **
+ ** IMPLEMENTATION OF EXCEPTION USING GENERIC SETJMP/LONGJMP
+ **
+ ****************************************************************************/
 
 /**
@@ -253,5 +297,5 @@
  * @hideinitializer
  */
-#define PJ_DEFAULT	    else
+#define PJ_CATCH_ANY	    else
 
 /**
@@ -276,4 +320,7 @@
 #define PJ_GET_EXCEPTION()	(pj_x_code__)
 
+#endif	/* PJ_EXCEPTION_USE_WIN32_SEH */
+
+
 PJ_END_DECL
 
Index: /pjproject/trunk/pjlib/src/pj/except.c
===================================================================
--- /pjproject/trunk/pjlib/src/pj/except.c	(revision 67)
+++ /pjproject/trunk/pjlib/src/pj/except.c	(revision 68)
@@ -36,4 +36,5 @@
 
 
+#if !defined(PJ_EXCEPTION_USE_WIN32_SEH) || PJ_EXCEPTION_USE_WIN32_SEH==0
 PJ_DEF(void) pj_throw_exception_(int exception_id)
 {
@@ -70,4 +71,5 @@
     pj_thread_local_set(thread_local_id, handler->prev);
 }
+#endif
 
 #if defined(PJ_HAS_EXCEPTION_NAMES) && PJ_HAS_EXCEPTION_NAMES != 0
Index: /pjproject/trunk/pjlib/src/pjlib-samples/except.c
===================================================================
--- /pjproject/trunk/pjlib/src/pjlib-samples/except.c	(revision 67)
+++ /pjproject/trunk/pjlib/src/pjlib-samples/except.c	(revision 68)
@@ -55,9 +55,5 @@
         randomly_throw_exception();
     }
-    PJ_CATCH( NO_MEMORY ) {
-        puts("Can't allocate memory");
-        return 0;
-    }
-    PJ_DEFAULT {
+    PJ_CATCH_ANY {
         pj_exception_id_t x_id;
         
Index: /pjproject/trunk/pjlib/src/pjlib-test/exception.c
===================================================================
--- /pjproject/trunk/pjlib/src/pjlib-test/exception.c	(revision 67)
+++ /pjproject/trunk/pjlib/src/pjlib-test/exception.c	(revision 68)
@@ -66,6 +66,6 @@
 static int test(void)
 {
+    int rc = 0;
     PJ_USE_EXCEPTION;
-    int rc = 0;
 
     /*
@@ -75,8 +75,5 @@
         rc = rc;
     }
-    PJ_CATCH( ID_1 ) {
-        rc = -2;
-    }
-    PJ_DEFAULT {
+    PJ_CATCH_ANY {
         rc = -3;
     }
@@ -96,12 +93,11 @@
 	rc = -10;
     }
-    PJ_CATCH( ID_1 ) {
-	if (!rc) rc = 0;
-    }
-    PJ_DEFAULT {
+    PJ_CATCH_ANY {
         int id = PJ_GET_EXCEPTION();
-        PJ_LOG(3,("", "...error: got unexpected exception %d (%s)", 
-                  id, pj_exception_id_name(id)));
-	if (!rc) rc = -20;
+	if (id != ID_1) {
+	    PJ_LOG(3,("", "...error: got unexpected exception %d (%s)", 
+		      id, pj_exception_id_name(id)));
+	    if (!rc) rc = -20;
+	}
     }
     PJ_END;
@@ -118,12 +114,14 @@
 	rc = -25;
     }
-    PJ_CATCH( ID_1 ) {
-	if (!rc) rc = -30;
-    }
-    PJ_CATCH( ID_2 ) {
-	if (!rc) rc = 0;
-    }
-    PJ_DEFAULT {
-	if (!rc) rc = -40;
+    PJ_CATCH_ANY {
+	switch (PJ_GET_EXCEPTION()) {
+	case ID_1:
+	    if (!rc) rc = -30; break;
+	case ID_2:
+	    if (!rc) rc = 0; break;
+	default:
+	    if (!rc) rc = -40;
+	    break;
+	}
     }
     PJ_END;
@@ -140,9 +138,13 @@
 	rc = -50;
     }
-    PJ_CATCH( ID_2 ) {
-	if (!rc) rc = -60;
-    }
-    PJ_DEFAULT {
-	if (!rc) rc = 0;
+    PJ_CATCH_ANY {
+	switch (PJ_GET_EXCEPTION()) {
+	case ID_1:
+	    if (!rc) rc = 0;
+	    break;
+	default:
+	    if (!rc) rc = -60;
+	    break;
+	}
     }
     PJ_END;
