[ros-diffs] [hyperion] 38311: PSEH 2 test suite - around 90 tests so far, and more coming

hyperion at svn.reactos.org hyperion at svn.reactos.org
Tue Dec 23 20:47:31 CET 2008


Author: hyperion
Date: Tue Dec 23 13:47:30 2008
New Revision: 38311

URL: http://svn.reactos.org/svn/reactos?rev=38311&view=rev
Log:
PSEH 2 test suite - around 90 tests so far, and more coming

Added:
    trunk/rostests/tests/pseh2/
    trunk/rostests/tests/pseh2/pseh2.rbuild   (with props)
    trunk/rostests/tests/pseh2/psehtest.c   (with props)
    trunk/rostests/tests/pseh2/psehtest2.c   (with props)
Modified:
    trunk/rostests/tests/directory.rbuild

Modified: trunk/rostests/tests/directory.rbuild
URL: http://svn.reactos.org/svn/reactos/trunk/rostests/tests/directory.rbuild?rev=38311&r1=38310&r2=38311&view=diff
==============================================================================
--- trunk/rostests/tests/directory.rbuild [iso-8859-1] (original)
+++ trunk/rostests/tests/directory.rbuild [iso-8859-1] Tue Dec 23 13:47:30 2008
@@ -109,7 +109,7 @@
 	<directory name="Imagelistviewer">
 		<xi:include href="Imagelistviewer/imagelistviewer.rbuild" />
 	</directory>
-	
+
 <!-- fixme: iptest -->
 
 	<directory name="isotest">
@@ -174,6 +174,9 @@
 	<directory name="primitives">
 		<xi:include href="primitives/primitives.rbuild" />
 	</directory>
+	<directory name="pseh2">
+		<xi:include href="pseh2/pseh2.rbuild" />
+	</directory>
 
 <!-- fixme: pteb -->
 

Added: trunk/rostests/tests/pseh2/pseh2.rbuild
URL: http://svn.reactos.org/svn/reactos/trunk/rostests/tests/pseh2/pseh2.rbuild?rev=38311&view=auto
==============================================================================
--- trunk/rostests/tests/pseh2/pseh2.rbuild (added)
+++ trunk/rostests/tests/pseh2/pseh2.rbuild [iso-8859-1] Tue Dec 23 13:47:30 2008
@@ -1,0 +1,7 @@
+<?xml version="1.0"?>
+<module name="pseh2_test" type="win32cui" installbase="bin" installname="pseh2_test.exe" allowwarnings="true">
+	<library>wine</library>
+	<library>pseh</library>
+	<file>psehtest.c</file>
+	<file>psehtest2.c</file>
+</module>

Propchange: trunk/rostests/tests/pseh2/pseh2.rbuild
------------------------------------------------------------------------------
    svn:eol-style = native

Added: trunk/rostests/tests/pseh2/psehtest.c
URL: http://svn.reactos.org/svn/reactos/trunk/rostests/tests/pseh2/psehtest.c?rev=38311&view=auto
==============================================================================
--- trunk/rostests/tests/pseh2/psehtest.c (added)
+++ trunk/rostests/tests/pseh2/psehtest.c [iso-8859-1] Tue Dec 23 13:47:30 2008
@@ -1,0 +1,2436 @@
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <pseh/pseh2.h>
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+#define STANDALONE
+#include <wine/test.h>
+
+extern void no_op(void);
+extern int return_arg(int);
+
+extern int return_zero(void);
+extern int return_positive(void);
+extern int return_negative(void);
+extern int return_one(void);
+extern int return_minusone(void);
+
+extern int return_zero_2(void *);
+extern int return_positive_2(void *);
+extern int return_negative_2(void *);
+extern int return_one_2(void *);
+extern int return_minusone_2(void *);
+
+extern int return_zero_3(int);
+extern int return_positive_3(int);
+extern int return_negative_3(int);
+extern int return_one_3(int);
+extern int return_minusone_3(int);
+
+extern int return_zero_4(void *, int);
+extern int return_positive_4(void *, int);
+extern int return_negative_4(void *, int);
+extern int return_one_4(void *, int);
+extern int return_minusone_4(void *, int);
+
+extern void set_positive(int *);
+
+static int call_test(int (*)(void));
+
+#define DEFINE_TEST(NAME_) \
+	static int test_ ## NAME_(void); \
+ \
+	static void NAME_(void) {  ok(call_test(test_ ## NAME_), "test failed\n"); } \
+ \
+	static int test_ ## NAME_(void)
+
+/* Empty statements *///{{{
+DEFINE_TEST(empty_1)
+{
+	_SEH2_TRY { } _SEH2_EXCEPT(0) { } _SEH2_END;
+	return 1;
+}
+
+DEFINE_TEST(empty_2)
+{
+	_SEH2_TRY { } _SEH2_EXCEPT(-1) { } _SEH2_END;
+	return 1;
+}
+
+DEFINE_TEST(empty_3)
+{
+	_SEH2_TRY { } _SEH2_EXCEPT(1) { } _SEH2_END;
+	return 1;
+}
+
+DEFINE_TEST(empty_4)
+{
+	_SEH2_TRY { } _SEH2_FINALLY { } _SEH2_END;
+	return 1;
+}
+
+DEFINE_TEST(empty_5)
+{
+	_SEH2_TRY { _SEH2_TRY { } _SEH2_EXCEPT(0) { } _SEH2_END; } _SEH2_FINALLY { } _SEH2_END;
+	return 1;
+}
+
+DEFINE_TEST(empty_6)
+{
+	_SEH2_TRY { _SEH2_TRY { } _SEH2_EXCEPT(-1) { } _SEH2_END; } _SEH2_FINALLY { } _SEH2_END;
+	return 1;
+}
+
+DEFINE_TEST(empty_7)
+{
+	_SEH2_TRY { _SEH2_TRY { } _SEH2_EXCEPT(1) { } _SEH2_END; } _SEH2_FINALLY { } _SEH2_END;
+	return 1;
+}
+
+DEFINE_TEST(empty_8)
+{
+	_SEH2_TRY { _SEH2_TRY { } _SEH2_FINALLY { } _SEH2_END; } _SEH2_FINALLY { } _SEH2_END;
+	return 1;
+}
+//}}}
+
+/* Static exception filters *///{{{
+DEFINE_TEST(execute_handler_1)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		RaiseException(0xE00DEAD0, 0, 0, NULL);
+		ret = return_zero();
+	}
+	_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+	{
+		ret = return_positive();
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(continue_execution_1)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		RaiseException(0xE00DEAD0, 0, 0, NULL);
+		ret = return_positive();
+	}
+	_SEH2_EXCEPT(EXCEPTION_CONTINUE_EXECUTION)
+	{
+		ret = return_zero();
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(continue_search_1)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		_SEH2_TRY
+		{
+			RaiseException(0xE00DEAD0, 0, 0, NULL);
+			ret = return_zero();
+		}
+		_SEH2_EXCEPT(EXCEPTION_CONTINUE_SEARCH)
+		{
+			ret = return_zero();
+		}
+		_SEH2_END;
+	}
+	_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+	{
+		ret = return_positive();
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(execute_handler_2)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		RaiseException(0xE00DEAD0, 0, 0, NULL);
+		ret = return_zero();
+	}
+	_SEH2_EXCEPT(12345)
+	{
+		ret = return_positive();
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(continue_execution_2)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		RaiseException(0xE00DEAD0, 0, 0, NULL);
+		ret = return_positive();
+	}
+	_SEH2_EXCEPT(-12345)
+	{
+		ret = return_zero();
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+//}}}
+
+/* Dynamic exception filters *///{{{
+DEFINE_TEST(execute_handler_3)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		RaiseException(0xE00DEAD0, 0, 0, NULL);
+		ret = return_zero();
+	}
+	_SEH2_EXCEPT(return_one())
+	{
+		ret = return_positive();
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(continue_execution_3)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		RaiseException(0xE00DEAD0, 0, 0, NULL);
+		ret = return_positive();
+	}
+	_SEH2_EXCEPT(return_minusone())
+	{
+		ret = return_zero();
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(continue_search_2)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		_SEH2_TRY
+		{
+			RaiseException(0xE00DEAD0, 0, 0, NULL);
+			ret = return_zero();
+		}
+		_SEH2_EXCEPT(return_zero())
+		{
+			ret = return_zero();
+		}
+		_SEH2_END;
+	}
+	_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+	{
+		ret = return_positive();
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(execute_handler_4)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		RaiseException(0xE00DEAD0, 0, 0, NULL);
+		ret = return_zero();
+	}
+	_SEH2_EXCEPT(return_positive())
+	{
+		ret = return_positive();
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(continue_execution_4)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		RaiseException(0xE00DEAD0, 0, 0, NULL);
+		ret = return_positive();
+	}
+	_SEH2_EXCEPT(return_negative())
+	{
+		ret = return_zero();
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+//}}}
+
+/* Dynamic exception filters, using _SEH2_GetExceptionInformation() *///{{{
+DEFINE_TEST(execute_handler_5)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		RaiseException(0xE00DEAD0, 0, 0, NULL);
+		ret = return_zero();
+	}
+	_SEH2_EXCEPT(return_one_2(_SEH2_GetExceptionInformation()))
+	{
+		ret = return_positive();
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(continue_execution_5)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		RaiseException(0xE00DEAD0, 0, 0, NULL);
+		ret = return_positive();
+	}
+	_SEH2_EXCEPT(return_minusone_2(_SEH2_GetExceptionInformation()))
+	{
+		ret = return_zero();
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(continue_search_3)
+{
+	static int ret;
+
+	ret = return_positive();
+
+	_SEH2_TRY
+	{
+		_SEH2_TRY
+		{
+			RaiseException(0xE00DEAD0, 0, 0, NULL);
+			ret = return_zero();
+		}
+		_SEH2_EXCEPT(return_zero_2(_SEH2_GetExceptionInformation()))
+		{
+			ret = return_zero();
+		}
+		_SEH2_END;
+	}
+	_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+	{
+		ret = return_arg(ret);
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(execute_handler_6)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		RaiseException(0xE00DEAD0, 0, 0, NULL);
+		ret = return_zero();
+	}
+	_SEH2_EXCEPT(return_positive_2(_SEH2_GetExceptionInformation()))
+	{
+		ret = return_positive();
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(continue_execution_6)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		RaiseException(0xE00DEAD0, 0, 0, NULL);
+		ret = return_positive();
+	}
+	_SEH2_EXCEPT(return_negative_2(_SEH2_GetExceptionInformation()))
+	{
+		ret = return_zero();
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+//}}}
+
+/* Dynamic exception filters, using _SEH2_GetExceptionCode() *///{{{
+DEFINE_TEST(execute_handler_7)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		RaiseException(0xE00DEAD0, 0, 0, NULL);
+		ret = return_zero();
+	}
+	_SEH2_EXCEPT(return_one_3(_SEH2_GetExceptionCode()))
+	{
+		ret = return_positive();
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(continue_execution_7)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		RaiseException(0xE00DEAD0, 0, 0, NULL);
+		ret = return_positive();
+	}
+	_SEH2_EXCEPT(return_minusone_3(_SEH2_GetExceptionCode()))
+	{
+		ret = return_zero();
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(continue_search_4)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		_SEH2_TRY
+		{
+			RaiseException(0xE00DEAD0, 0, 0, NULL);
+			ret = return_zero();
+		}
+		_SEH2_EXCEPT(return_zero_3(_SEH2_GetExceptionCode()))
+		{
+			ret = return_zero();
+		}
+		_SEH2_END;
+	}
+	_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+	{
+		ret = return_positive();
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(execute_handler_8)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		RaiseException(0xE00DEAD0, 0, 0, NULL);
+		ret = return_zero();
+	}
+	_SEH2_EXCEPT(return_positive_3(_SEH2_GetExceptionCode()))
+	{
+		ret = return_positive();
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(continue_execution_8)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		RaiseException(0xE00DEAD0, 0, 0, NULL);
+		ret = return_positive();
+	}
+	_SEH2_EXCEPT(return_negative_3(_SEH2_GetExceptionCode()))
+	{
+		ret = return_zero();
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+//}}}
+
+/* Dynamic exception filters, using _SEH2_GetExceptionInformation() and _SEH2_GetExceptionCode() *///{{{
+DEFINE_TEST(execute_handler_9)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		RaiseException(0xE00DEAD0, 0, 0, NULL);
+		ret = return_zero();
+	}
+	_SEH2_EXCEPT(return_one_4(_SEH2_GetExceptionInformation(), _SEH2_GetExceptionCode()))
+	{
+		ret = return_positive();
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(continue_execution_9)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		RaiseException(0xE00DEAD0, 0, 0, NULL);
+		ret = return_positive();
+	}
+	_SEH2_EXCEPT(return_minusone_4(_SEH2_GetExceptionInformation(), _SEH2_GetExceptionCode()))
+	{
+		ret = return_zero();
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(continue_search_5)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		_SEH2_TRY
+		{
+			RaiseException(0xE00DEAD0, 0, 0, NULL);
+			ret = return_zero();
+		}
+		_SEH2_EXCEPT(return_zero_4(_SEH2_GetExceptionInformation(), _SEH2_GetExceptionCode()))
+		{
+			ret = return_zero();
+		}
+		_SEH2_END;
+	}
+	_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+	{
+		ret = return_positive();
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(execute_handler_10)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		RaiseException(0xE00DEAD0, 0, 0, NULL);
+		ret = return_zero();
+	}
+	_SEH2_EXCEPT(return_positive_4(_SEH2_GetExceptionInformation(), _SEH2_GetExceptionCode()))
+	{
+		ret = return_positive();
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(continue_execution_10)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		RaiseException(0xE00DEAD0, 0, 0, NULL);
+		ret = return_positive();
+	}
+	_SEH2_EXCEPT(return_negative_4(_SEH2_GetExceptionInformation(), _SEH2_GetExceptionCode()))
+	{
+		ret = return_zero();
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+//}}}
+
+/* Constant exception filters with side effects *///{{{
+DEFINE_TEST(execute_handler_11)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		RaiseException(0xE00DEAD0, 0, 0, NULL);
+		ret = return_zero();
+	}
+	_SEH2_EXCEPT(set_positive(&ret), EXCEPTION_EXECUTE_HANDLER)
+	{
+		ret = ret ? return_positive() : return_zero();
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(continue_execution_11)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		RaiseException(0xE00DEAD0, 0, 0, NULL);
+		ret = ret ? return_positive() : return_zero();
+	}
+	_SEH2_EXCEPT(set_positive(&ret), EXCEPTION_CONTINUE_EXECUTION)
+	{
+		ret = return_zero();
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(continue_search_6)
+{
+	static int ret;
+	static int ret2;
+
+	ret = return_zero();
+	ret2 = return_zero();
+
+	_SEH2_TRY
+	{
+		_SEH2_TRY
+		{
+			RaiseException(0xE00DEAD0, 0, 0, NULL);
+			ret = return_zero();
+			ret2 = return_zero();
+		}
+		_SEH2_EXCEPT(set_positive(&ret), EXCEPTION_CONTINUE_SEARCH)
+		{
+			ret = return_zero();
+			ret2 = return_zero();
+		}
+		_SEH2_END;
+	}
+	_SEH2_EXCEPT(set_positive(&ret2), EXCEPTION_EXECUTE_HANDLER)
+	{
+		ret = return_arg(ret);
+		ret2 = return_arg(ret2);
+	}
+	_SEH2_END;
+
+	return ret == return_positive() && ret2 == return_positive();
+}
+
+DEFINE_TEST(execute_handler_12)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		RaiseException(0xE00DEAD0, 0, 0, NULL);
+		ret = return_zero();
+	}
+	_SEH2_EXCEPT(set_positive(&ret), 12345)
+	{
+		ret = return_arg(ret);
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(continue_execution_12)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		RaiseException(0xE00DEAD0, 0, 0, NULL);
+		ret = return_arg(ret);
+	}
+	_SEH2_EXCEPT(set_positive(&ret), -12345)
+	{
+		ret = return_zero();
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+//}}}
+
+/* _SEH2_LEAVE *///{{{
+DEFINE_TEST(leave_1)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		ret = return_positive();
+		_SEH2_LEAVE;
+		ret = return_zero();
+	}
+	_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+	{
+		ret = return_zero();
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(leave_2)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		ret = return_positive();
+		_SEH2_LEAVE;
+
+		RaiseException(0xE00DEAD0, 0, 0, NULL);
+		ret = return_zero();
+	}
+	_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+	{
+		ret = return_zero();
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(leave_3)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		ret = return_positive();
+
+		if(return_one())
+			_SEH2_LEAVE;
+
+		ret = return_zero();
+	}
+	_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+	{
+		ret = return_zero();
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(leave_4)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		int i;
+		int n = return_one() + return_one();
+
+		for(i = return_zero(); i < n; ++ i)
+		{
+			if(i == return_one())
+			{
+				ret = return_positive();
+				_SEH2_LEAVE;
+			}
+		}
+
+		ret = return_zero();
+	}
+	_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+	{
+		ret = return_zero();
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(leave_5)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		switch(return_one())
+		{
+		case 0: ret = return_zero();
+		case 1: ret = return_positive(); _SEH2_LEAVE;
+		case 2: ret = return_zero();
+		}
+
+		ret = return_zero();
+	}
+	_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+	{
+		ret = return_zero();
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(leave_6)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		_SEH2_TRY
+		{
+			_SEH2_LEAVE;
+		}
+		_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+		{
+			ret = return_zero();
+		}
+		_SEH2_END;
+
+		ret = return_positive();
+	}
+	_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+	{
+		ret = return_zero();
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+//}}}
+
+/* _SEH2_YIELD() *///{{{
+static
+int test_yield_1_helper(void)
+{
+	_SEH2_TRY
+	{
+		_SEH2_YIELD(return return_positive());
+	}
+	_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+	{
+		_SEH2_YIELD(return return_zero());
+	}
+	_SEH2_END;
+
+	return return_zero();
+}
+
+DEFINE_TEST(yield_1)
+{
+	return test_yield_1_helper() == return_positive();
+}
+
+static
+int test_yield_2_helper(void)
+{
+	_SEH2_TRY
+	{
+		RaiseException(0xE00DEAD0, 0, 0, NULL);
+		_SEH2_YIELD(return return_zero());
+	}
+	_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+	{
+		_SEH2_YIELD(return return_positive());
+	}
+	_SEH2_END;
+
+	return return_zero();
+}
+
+DEFINE_TEST(yield_2)
+{
+	return test_yield_2_helper() == return_positive();
+}
+
+static
+int test_yield_3_helper(void)
+{
+	_SEH2_TRY
+	{
+		_SEH2_TRY
+		{
+			_SEH2_YIELD(return return_positive());
+		}
+		_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+		{
+			_SEH2_YIELD(return return_zero());
+		}
+		_SEH2_END;
+
+		_SEH2_YIELD(return return_zero());
+	}
+	_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+	{
+		_SEH2_YIELD(return return_zero());
+	}
+	_SEH2_END;
+
+	return return_zero();
+}
+
+DEFINE_TEST(yield_3)
+{
+	return test_yield_3_helper() == return_positive();
+}
+
+static
+int test_yield_4_helper(void)
+{
+	_SEH2_TRY
+	{
+		_SEH2_TRY
+		{
+			RaiseException(0xE00DEAD0, 0, 0, NULL);
+			_SEH2_YIELD(return return_zero());
+		}
+		_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+		{
+			_SEH2_YIELD(return return_positive());
+		}
+		_SEH2_END;
+
+		_SEH2_YIELD(return return_zero());
+	}
+	_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+	{
+		_SEH2_YIELD(return return_zero());
+	}
+	_SEH2_END;
+
+	return return_zero();
+}
+
+DEFINE_TEST(yield_4)
+{
+	return test_yield_4_helper() == return_positive();
+}
+
+static int test_yield_5_ret;
+
+static
+int test_yield_5_helper(void)
+{
+	test_yield_5_ret = return_zero();
+
+	_SEH2_TRY
+	{
+		_SEH2_YIELD(return return_positive());
+	}
+	_SEH2_FINALLY
+	{
+		test_yield_5_ret = return_positive();
+	}
+	_SEH2_END;
+
+	return return_zero();
+}
+
+DEFINE_TEST(yield_5)
+{
+	return test_yield_5_helper() == return_positive() && test_yield_5_ret == return_positive();
+}
+
+int test_yield_6_ret;
+
+static
+int test_yield_6_helper(void)
+{
+	test_yield_6_ret = return_zero();
+
+	_SEH2_TRY
+	{
+		_SEH2_TRY
+		{
+			_SEH2_YIELD(return return_positive());
+		}
+		_SEH2_FINALLY
+		{
+			test_yield_6_ret = return_positive();
+		}
+		_SEH2_END;
+	}
+	_SEH2_FINALLY
+	{
+		test_yield_6_ret += return_one();
+	}
+	_SEH2_END;
+
+	return return_zero();
+}
+
+DEFINE_TEST(yield_6)
+{
+	return test_yield_6_helper() == return_positive() && test_yield_6_ret == return_positive() + return_one();
+}
+//}}}
+
+/* Termination blocks *///{{{
+DEFINE_TEST(finally_1)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		ret = return_arg(ret);
+	}
+	_SEH2_FINALLY
+	{
+		ret = return_positive();
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(finally_2)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		ret = return_arg(ret);
+		_SEH2_LEAVE;
+	}
+	_SEH2_FINALLY
+	{
+		ret = return_positive();
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(finally_3)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		ret = return_arg(ret);
+		_SEH2_YIELD(goto leave);
+	}
+	_SEH2_FINALLY
+	{
+		ret = return_positive();
+	}
+	_SEH2_END;
+
+leave:
+	return ret == return_positive();
+}
+
+static int test_finally_4_ret;
+
+static int test_finally_4_helper(void)
+{
+	test_finally_4_ret = return_zero();
+
+	_SEH2_TRY
+	{
+		test_finally_4_ret = return_arg(test_finally_4_ret);
+		_SEH2_YIELD(return return_positive());
+	}
+	_SEH2_FINALLY
+	{
+		test_finally_4_ret = return_positive();
+	}
+	_SEH2_END;
+
+	return return_zero();
+}
+
+DEFINE_TEST(finally_4)
+{
+	return test_finally_4_helper() == return_positive() && test_finally_4_ret;
+}
+
+DEFINE_TEST(finally_5)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		_SEH2_TRY
+		{
+			RaiseException(0xE00DEAD0, 0, 0, NULL);
+			ret = return_zero();
+		}
+		_SEH2_FINALLY
+		{
+			ret = return_positive();
+		}
+		_SEH2_END;
+	}
+	_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+	{
+		ret = return_arg(ret);
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(finally_6)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		_SEH2_TRY
+		{
+			ret = return_arg(ret);
+		}
+		_SEH2_FINALLY
+		{
+			if(ret == return_zero())
+				ret = return_positive();
+		}
+		_SEH2_END;
+	}
+	_SEH2_FINALLY
+	{
+		if(ret == return_positive())
+			ret = return_positive() + return_one();
+	}
+	_SEH2_END;
+
+	return ret == return_positive() + return_one();
+}
+
+DEFINE_TEST(finally_7)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		_SEH2_TRY
+		{
+			ret = return_arg(ret);
+			_SEH2_LEAVE;
+		}
+		_SEH2_FINALLY
+		{
+			if(ret == return_zero())
+				ret = return_positive();
+		}
+		_SEH2_END;
+	}
+	_SEH2_FINALLY
+	{
+		if(ret == return_positive())
+			ret = return_positive() + return_one();
+	}
+	_SEH2_END;
+
+	return ret == return_positive() + return_one();
+}
+
+DEFINE_TEST(finally_8)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		_SEH2_TRY
+		{
+			ret = return_arg(ret);
+			_SEH2_YIELD(goto leave);
+		}
+		_SEH2_FINALLY
+		{
+			if(ret == return_zero())
+				ret = return_positive();
+		}
+		_SEH2_END;
+	}
+	_SEH2_FINALLY
+	{
+		if(ret == return_positive())
+			ret = return_positive() + return_one();
+	}
+	_SEH2_END;
+
+leave:
+	return ret == return_positive() + return_one();
+}
+
+static int test_finally_9_ret;
+
+static int test_finally_9_helper(void)
+{
+	test_finally_9_ret = return_zero();
+
+	_SEH2_TRY
+	{
+		_SEH2_TRY
+		{
+			test_finally_9_ret = return_arg(test_finally_9_ret);
+			_SEH2_YIELD(return return_positive());
+		}
+		_SEH2_FINALLY
+		{
+			if(test_finally_9_ret == return_zero())
+				test_finally_9_ret = return_positive();
+		}
+		_SEH2_END;
+	}
+	_SEH2_FINALLY
+	{
+		if(test_finally_9_ret == return_positive())
+			test_finally_9_ret = return_positive() + return_one();
+	}
+	_SEH2_END;
+
+	return return_zero();
+}
+
+DEFINE_TEST(finally_9)
+{
+	return test_finally_9_helper() == return_positive() && test_finally_9_ret == return_positive() + return_one();
+}
+
+DEFINE_TEST(finally_10)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		_SEH2_TRY
+		{
+			_SEH2_TRY
+			{
+				RaiseException(0xE00DEAD0, 0, 0, NULL);
+				ret = return_zero();
+			}
+			_SEH2_FINALLY
+			{
+				if(ret == return_zero())
+					ret = return_positive();
+			}
+			_SEH2_END;
+		}
+		_SEH2_FINALLY
+		{
+			if(ret == return_positive())
+				ret = return_positive() + return_one();
+		}
+		_SEH2_END;
+	}
+	_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+	{
+		ret = return_arg(ret);
+	}
+	_SEH2_END;
+
+	return ret == return_positive() + return_one();
+}
+
+DEFINE_TEST(finally_11)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		_SEH2_TRY
+		{
+			_SEH2_TRY
+			{
+				ret = return_arg(ret);
+			}
+			_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+			{
+				ret = return_zero();
+			}
+			_SEH2_END;
+		}
+		_SEH2_FINALLY
+		{
+			ret = return_positive();
+			RaiseException(0xE00DEAD0, 0, 0, NULL);
+			ret = return_zero();
+		}
+		_SEH2_END;
+	}
+	_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+	{
+		if(ret == return_positive())
+			ret += return_one();
+	}
+	_SEH2_END;
+
+	return ret == return_positive() + return_one();
+}
+
+DEFINE_TEST(finally_12)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		_SEH2_TRY
+		{
+			_SEH2_TRY
+			{
+				ret = return_arg(ret);
+			}
+			_SEH2_FINALLY
+			{
+				ret = return_positive();
+				RaiseException(0xE00DEAD0, 0, 0, NULL);
+				ret = return_zero();
+			}
+			_SEH2_END;
+		}
+		_SEH2_FINALLY
+		{
+			if(ret == return_positive())
+				ret += return_one();
+		}
+		_SEH2_END;
+	}
+	_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+	{
+		if(ret == return_positive() + return_one())
+			ret += return_one();
+	}
+	_SEH2_END;
+
+	return ret == return_positive() + return_one() + return_one();
+}
+
+#if 0
+static int test_finally_13_ret;
+
+static
+void test_finally_13_helper(void)
+{
+	test_finally_13_ret = return_zero();
+
+	_SEH2_TRY
+	{
+		_SEH2_TRY
+		{
+			test_finally_13_ret = return_positive();
+			_SEH2_YIELD(return);
+			test_finally_13_ret = return_zero();
+		}
+		_SEH2_FINALLY
+		{
+			if(test_finally_13_ret == return_positive())
+				test_finally_13_ret += return_one();
+		}
+		_SEH2_END;
+	}
+	_SEH2_FINALLY
+	{
+		if(test_finally_13_ret == return_positive() + return_one())
+			test_finally_13_ret += return_one();
+
+		RaiseException(0xE00DEAD0, 0, 0, NULL);
+		test_finally_13_ret = return_zero();
+	}
+	_SEH2_END;
+
+	test_finally_13_ret = return_zero();
+}
+
+DEFINE_TEST(finally_13)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		ret = return_arg(ret);
+		test_finally_13_helper();
+		ret = return_zero();
+	}
+	_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+	{
+		ret = return_positive();
+	}
+	_SEH2_END;
+
+	return ret == return_positive() && test_finally_13_ret == return_positive() + return_one() + return_one();
+}
+
+static int test_finally_14_ret;
+
+static
+void test_finally_14_helper(void)
+{
+	test_finally_14_ret = return_zero();
+
+	_SEH2_TRY
+	{
+		_SEH2_TRY
+		{
+			_SEH2_TRY
+			{
+				test_finally_14_ret = return_positive();
+				RaiseException(0xE00DEAD0, 0, 0, NULL);
+				test_finally_14_ret = return_zero();
+			}
+			_SEH2_FINALLY
+			{
+				if(test_finally_14_ret == return_positive())
+					test_finally_14_ret += return_one();
+			}
+			_SEH2_END;
+		}
+		_SEH2_FINALLY
+		{
+			if(test_finally_14_ret == return_positive() + return_one())
+				test_finally_14_ret += return_one();
+
+			RaiseException(0xE00DEAD0, 0, 0, NULL);
+			test_finally_14_ret = return_zero();
+		}
+		_SEH2_END;
+	}
+	_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+	{
+		test_finally_14_ret = return_zero();
+	}
+	_SEH2_END;
+
+	test_finally_14_ret = return_zero();
+}
+
+DEFINE_TEST(finally_14)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		ret = return_arg(ret);
+		test_finally_14_helper();
+		ret = return_zero();
+	}
+	_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+	{
+		ret = return_positive();
+	}
+	_SEH2_END;
+
+	return ret == return_positive() && test_finally_14_ret == return_positive() + return_one() + return_one();
+}
+#endif
+//}}}
+
+/* _SEH2_GetExceptionInformation() *///{{{
+static
+int verify_xpointers(struct _EXCEPTION_POINTERS * ep, DWORD code, DWORD flags, DWORD argc, const ULONG_PTR * argv, int * ret, int filter)
+{
+	*ret =
+		ep &&
+		ep->ExceptionRecord &&
+		ep->ContextRecord &&
+		ep->ExceptionRecord->ExceptionCode == code &&
+		ep->ExceptionRecord->ExceptionFlags == flags &&
+		ep->ExceptionRecord->NumberParameters == argc &&
+		(argv || !argc) &&
+		memcmp(ep->ExceptionRecord->ExceptionInformation, argv, sizeof(argv[0]) * argc) == 0;
+
+	if(*ret)
+		*ret = return_positive();
+
+	return filter;
+}
+
+DEFINE_TEST(xpointers_1)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		RaiseException(0xE00DEAD0, 0, 0, NULL);
+	}
+	_SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, 0, 0, NULL, &ret, EXCEPTION_EXECUTE_HANDLER))
+	{
+		ret = return_arg(ret);
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(xpointers_2)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		RaiseException(0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 0, NULL);
+	}
+	_SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 0, NULL, &ret, EXCEPTION_EXECUTE_HANDLER))
+	{
+		ret = return_arg(ret);
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(xpointers_3)
+{
+	static int ret;
+	static const ULONG_PTR args[] = { 1, 2, 12345 };
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		RaiseException(0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 0, args);
+	}
+	_SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 0, args, &ret, EXCEPTION_EXECUTE_HANDLER))
+	{
+		ret = return_arg(ret);
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(xpointers_4)
+{
+	static int ret;
+	static const ULONG_PTR args[] = { 1, 2, 12345 };
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		RaiseException(0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 1, args);
+	}
+	_SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 1, args, &ret, EXCEPTION_EXECUTE_HANDLER))
+	{
+		ret = return_arg(ret);
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(xpointers_5)
+{
+	static int ret;
+	static const ULONG_PTR args[] = { 1, 2, 12345 };
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		RaiseException(0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 2, args);
+	}
+	_SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 2, args, &ret, EXCEPTION_EXECUTE_HANDLER))
+	{
+		ret = return_arg(ret);
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(xpointers_6)
+{
+	static int ret;
+	static const ULONG_PTR args[] = { 1, 2, 12345 };
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		RaiseException(0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 3, args);
+	}
+	_SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 3, args, &ret, EXCEPTION_EXECUTE_HANDLER))
+	{
+		ret = return_arg(ret);
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(xpointers_7)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		RaiseException(0xE00DEAD0, 0, 0, NULL);
+		ret = return_arg(ret);
+	}
+	_SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, 0, 0, NULL, &ret, EXCEPTION_CONTINUE_EXECUTION))
+	{
+		ret = return_zero();
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(xpointers_8)
+{
+	static int ret;
+	static const ULONG_PTR args[] = { 1, 2, 12345 };
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		RaiseException(0xE00DEAD0, 0, 0, args);
+		ret = return_arg(ret);
+	}
+	_SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, 0, 0, args, &ret, EXCEPTION_CONTINUE_EXECUTION))
+	{
+		ret = return_zero();
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(xpointers_9)
+{
+	static int ret;
+	static const ULONG_PTR args[] = { 1, 2, 12345 };
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		RaiseException(0xE00DEAD0, 0, 1, args);
+		ret = return_arg(ret);
+	}
+	_SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, 0, 1, args, &ret, EXCEPTION_CONTINUE_EXECUTION))
+	{
+		ret = return_zero();
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(xpointers_10)
+{
+	static int ret;
+	static const ULONG_PTR args[] = { 1, 2, 12345 };
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		RaiseException(0xE00DEAD0, 0, 2, args);
+		ret = return_arg(ret);
+	}
+	_SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, 0, 2, args, &ret, EXCEPTION_CONTINUE_EXECUTION))
+	{
+		ret = return_zero();
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(xpointers_11)
+{
+	static int ret;
+	static const ULONG_PTR args[] = { 1, 2, 12345 };
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		RaiseException(0xE00DEAD0, 0, 3, args);
+		ret = return_arg(ret);
+	}
+	_SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, 0, 3, args, &ret, EXCEPTION_CONTINUE_EXECUTION))
+	{
+		ret = return_zero();
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(xpointers_12)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		_SEH2_TRY
+		{
+			RaiseException(0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 0, NULL);
+		}
+		_SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 0, NULL, &ret, EXCEPTION_CONTINUE_SEARCH))
+		{
+			ret = return_zero();
+		}
+		_SEH2_END;
+	}
+	_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+	{
+		ret = return_arg(ret);
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(xpointers_13)
+{
+	static int ret;
+	static const ULONG_PTR args[] = { 1, 2, 12345 };
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		_SEH2_TRY
+		{
+			RaiseException(0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 0, args);
+		}
+		_SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 0, args, &ret, EXCEPTION_CONTINUE_SEARCH))
+		{
+			ret = return_zero();
+		}
+		_SEH2_END;
+	}
+	_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+	{
+		ret = return_arg(ret);
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(xpointers_14)
+{
+	static int ret;
+	static const ULONG_PTR args[] = { 1, 2, 12345 };
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		_SEH2_TRY
+		{
+			RaiseException(0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 1, args);
+		}
+		_SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 1, args, &ret, EXCEPTION_CONTINUE_SEARCH))
+		{
+			ret = return_zero();
+		}
+		_SEH2_END;
+	}
+	_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+	{
+		ret = return_arg(ret);
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(xpointers_15)
+{
+	static int ret;
+	static const ULONG_PTR args[] = { 1, 2, 12345 };
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		_SEH2_TRY
+		{
+			RaiseException(0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 2, args);
+		}
+		_SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 2, args, &ret, EXCEPTION_CONTINUE_SEARCH))
+		{
+			ret = return_zero();
+		}
+		_SEH2_END;
+	}
+	_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+	{
+		ret = return_arg(ret);
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(xpointers_16)
+{
+	static int ret;
+	static const ULONG_PTR args[] = { 1, 2, 12345 };
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		_SEH2_TRY
+		{
+			RaiseException(0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 3, args);
+		}
+		_SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 3, args, &ret, EXCEPTION_CONTINUE_SEARCH))
+		{
+			ret = return_zero();
+		}
+		_SEH2_END;
+	}
+	_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+	{
+		ret = return_arg(ret);
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+//}}}
+
+/* _SEH2_GetExceptionCode() *///{{{
+static
+int verify_xcode(int code, int xcode, int * ret, int filter)
+{
+	*ret = code == xcode;
+
+	if(*ret)
+		*ret = return_positive();
+
+	return filter;
+}
+
+DEFINE_TEST(xcode_1)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		RaiseException(0xE00DEAD0, 0, 0, NULL);
+		ret = return_zero();
+	}
+	_SEH2_EXCEPT(verify_xcode(_SEH2_GetExceptionCode(), 0xE00DEAD0, &ret, EXCEPTION_EXECUTE_HANDLER))
+	{
+		ret = return_arg(ret);
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(xcode_2)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		RaiseException(0xE00DEAD0, 0, 0, NULL);
+		ret = return_arg(ret);
+	}
+	_SEH2_EXCEPT(verify_xcode(_SEH2_GetExceptionCode(), 0xE00DEAD0, &ret, EXCEPTION_CONTINUE_EXECUTION))
+	{
+		ret = return_zero();
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(xcode_3)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		_SEH2_TRY
+		{
+			RaiseException(0xE00DEAD0, 0, 0, NULL);
+			ret = return_zero();
+		}
+		_SEH2_EXCEPT(verify_xcode(_SEH2_GetExceptionCode(), 0xE00DEAD0, &ret, EXCEPTION_CONTINUE_SEARCH))
+		{
+			ret = return_zero();
+		}
+		_SEH2_END;
+	}
+	_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+	{
+		ret = return_arg(ret);
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+//}}}
+
+/* _SEH2_AbnormalTermination() *///{{{
+DEFINE_TEST(abnorm_1)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		ret = return_arg(ret);
+	}
+	_SEH2_FINALLY
+	{
+		ret = _SEH2_AbnormalTermination() ? return_zero() : return_positive();
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(abnorm_2)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		_SEH2_LEAVE;
+	}
+	_SEH2_FINALLY
+	{
+		ret = _SEH2_AbnormalTermination() ? return_zero() : return_positive();
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(abnorm_3)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		_SEH2_YIELD(goto leave);
+	}
+	_SEH2_FINALLY
+	{
+		ret = _SEH2_AbnormalTermination() ? return_positive() : return_zero();
+	}
+	_SEH2_END;
+
+leave:
+	return ret == return_positive();
+}
+
+DEFINE_TEST(abnorm_4)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		_SEH2_TRY
+		{
+			RaiseException(0xE00DEAD0, 0, 0, NULL);
+			ret = return_zero();
+		}
+		_SEH2_FINALLY
+		{
+			ret = _SEH2_AbnormalTermination() ? return_positive() : return_zero();
+		}
+		_SEH2_END;
+	}
+	_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+	{
+		ret = return_arg(ret);
+	}
+	_SEH2_END;
+
+	return ret == return_positive();
+}
+
+DEFINE_TEST(abnorm_5)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		_SEH2_TRY
+		{
+			ret = return_arg(ret);
+		}
+		_SEH2_FINALLY
+		{
+			ret = _SEH2_AbnormalTermination() ? return_zero() : return_positive();
+		}
+		_SEH2_END;
+	}
+	_SEH2_FINALLY
+	{
+		ret = ret == return_positive() && !_SEH2_AbnormalTermination() ? return_positive() + return_one() : ret;
+	}
+	_SEH2_END;
+
+	return ret == return_positive() + return_one();
+}
+
+DEFINE_TEST(abnorm_6)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		_SEH2_TRY
+		{
+			_SEH2_LEAVE;
+		}
+		_SEH2_FINALLY
+		{
+			ret = _SEH2_AbnormalTermination() ? return_zero() : return_positive();
+		}
+		_SEH2_END;
+	}
+	_SEH2_FINALLY
+	{
+		ret = ret == return_positive() && !_SEH2_AbnormalTermination() ? return_positive() + return_one() : ret;
+	}
+	_SEH2_END;
+
+	return ret == return_positive() + return_one();
+}
+
+DEFINE_TEST(abnorm_7)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		_SEH2_TRY
+		{
+			_SEH2_YIELD(goto leave);
+		}
+		_SEH2_FINALLY
+		{
+			ret = _SEH2_AbnormalTermination() ? return_positive() : return_zero();
+		}
+		_SEH2_END;
+	}
+	_SEH2_FINALLY
+	{
+		ret = ret == return_positive() && _SEH2_AbnormalTermination() ? return_positive() + return_one() : ret;
+	}
+	_SEH2_END;
+
+leave:
+	return ret == return_positive() + return_one();
+}
+
+DEFINE_TEST(abnorm_8)
+{
+	static int ret;
+
+	ret = return_zero();
+
+	_SEH2_TRY
+	{
+		_SEH2_TRY
+		{
+			_SEH2_TRY
+			{
+				RaiseException(0xE00DEAD0, 0, 0, NULL);
+				ret = return_zero();
+			}
+			_SEH2_FINALLY
+			{
+				ret = _SEH2_AbnormalTermination() ? return_positive() : return_zero();
+			}
+			_SEH2_END;
+		}
+		_SEH2_FINALLY
+		{
+			ret = ret == return_positive() && _SEH2_AbnormalTermination() ? return_positive() + return_one() : ret;
+		}
+		_SEH2_END;
+	}
+	_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+	{
+		ret = return_arg(ret);
+	}
+	_SEH2_END;
+
+	return ret == return_positive() + return_one();
+}
+//}}}
+
+/* System support *///{{{
+// TODO
+//}}}
+
+/* CPU faults *///{{{
+// TODO
+//}}}
+
+#define USE_TEST_NAME_(NAME_) # NAME_
+#define USE_TEST_NAME(NAME_) USE_TEST_NAME_(NAME_)
+#define USE_TEST(NAME_) { USE_TEST_NAME(NAME_), NAME_ }
+
+const struct test winetest_testlist[] =
+{
+	USE_TEST(empty_1),
+	USE_TEST(empty_2),
+	USE_TEST(empty_3),
+	USE_TEST(empty_4),
+	USE_TEST(empty_5),
+	USE_TEST(empty_6),
+	USE_TEST(empty_7),
+	USE_TEST(empty_8),
+
+	USE_TEST(execute_handler_1),
+	USE_TEST(continue_execution_1),
+	USE_TEST(continue_search_1),
+	USE_TEST(execute_handler_2),
+	USE_TEST(continue_execution_2),
+
+	USE_TEST(execute_handler_3),
+	USE_TEST(continue_execution_3),
+	USE_TEST(continue_search_2),
+	USE_TEST(execute_handler_4),
+	USE_TEST(continue_execution_4),
+
+	USE_TEST(execute_handler_5),
+	USE_TEST(continue_execution_5),
+	USE_TEST(continue_search_3),
+	USE_TEST(execute_handler_6),
+	USE_TEST(continue_execution_6),
+
+	USE_TEST(execute_handler_7),
+	USE_TEST(continue_execution_7),
+	USE_TEST(continue_search_4),
+	USE_TEST(execute_handler_8),
+	USE_TEST(continue_execution_8),
+
+	USE_TEST(execute_handler_9),
+	USE_TEST(continue_execution_9),
+	USE_TEST(continue_search_5),
+	USE_TEST(execute_handler_10),
+	USE_TEST(continue_execution_10),
+
+	USE_TEST(execute_handler_11),
+	USE_TEST(continue_execution_11),
+	USE_TEST(continue_search_6),
+	USE_TEST(execute_handler_12),
+	USE_TEST(continue_execution_12),
+
+	USE_TEST(leave_1),
+	USE_TEST(leave_2),
+	USE_TEST(leave_3),
+	USE_TEST(leave_4),
+	USE_TEST(leave_5),
+	USE_TEST(leave_6),
+
+	USE_TEST(yield_1),
+	USE_TEST(yield_2),
+	USE_TEST(yield_3),
+	USE_TEST(yield_4),
+	USE_TEST(yield_5),
+	USE_TEST(yield_6),
+
+	USE_TEST(finally_1),
+	USE_TEST(finally_2),
+	USE_TEST(finally_3),
+	USE_TEST(finally_4),
+	USE_TEST(finally_5),
+	USE_TEST(finally_6),
+	USE_TEST(finally_7),
+	USE_TEST(finally_8),
+	USE_TEST(finally_9),
+	USE_TEST(finally_10),
+	USE_TEST(finally_11),
+	USE_TEST(finally_12),
+#if 0
+	USE_TEST(finally_13),
+	USE_TEST(finally_14),
+#endif
+
+	USE_TEST(xpointers_1),
+	USE_TEST(xpointers_2),
+	USE_TEST(xpointers_3),
+	USE_TEST(xpointers_4),
+	USE_TEST(xpointers_5),
+	USE_TEST(xpointers_6),
+	USE_TEST(xpointers_7),
+	USE_TEST(xpointers_8),
+	USE_TEST(xpointers_9),
+	USE_TEST(xpointers_10),
+	USE_TEST(xpointers_11),
+	USE_TEST(xpointers_12),
+	USE_TEST(xpointers_13),
+	USE_TEST(xpointers_14),
+	USE_TEST(xpointers_15),
+	USE_TEST(xpointers_16),
+
+	USE_TEST(xcode_1),
+	USE_TEST(xcode_2),
+	USE_TEST(xcode_3),
+
+	USE_TEST(abnorm_1),
+	USE_TEST(abnorm_2),
+	USE_TEST(abnorm_3),
+	USE_TEST(abnorm_4),
+	USE_TEST(abnorm_5),
+	USE_TEST(abnorm_6),
+	USE_TEST(abnorm_7),
+	USE_TEST(abnorm_8),
+
+	{ 0, 0 }
+};
+
+static
+LONG WINAPI unhandled_exception(PEXCEPTION_POINTERS ExceptionInfo)
+{
+	ok(0, "unhandled exception %08lX thrown from %p\n", ExceptionInfo->ExceptionRecord->ExceptionCode, ExceptionInfo->ExceptionRecord->ExceptionAddress);
+	return EXCEPTION_CONTINUE_SEARCH;
+}
+
+#if defined(_M_IX86)
+struct volatile_context
+{
+	void * esp;
+	void * ebp;
+	void * ebx;
+	void * esi;
+	void * edi;
+};
+#else
+#error TODO
+#endif
+
+#if defined(__GNUC__)
+static
+__attribute__((noinline))
+int sanity_check(int ret, struct volatile_context * before, struct volatile_context * after)
+{
+	if(ret && memcmp(before, after, sizeof(before)))
+		ok(0, "volatile context corrupted\n");
+
+	return ret;
+}
+
+static
+__attribute__((noinline))
+int call_test(int (* func)(void))
+{
+	static int ret;
+	static LPTOP_LEVEL_EXCEPTION_FILTER prev_unhandled_exception;
+
+	prev_unhandled_exception = SetUnhandledExceptionFilter(&unhandled_exception);
+
+#if defined(__i386__)
+	static struct volatile_context before, after;
+
+	__asm__ __volatile__
+	(
+		"mov %%esp, 0x00 + %c[before]\n"
+		"mov %%ebp, 0x04 + %c[before]\n"
+		"mov %%ebx, 0x08 + %c[before]\n"
+		"mov %%esi, 0x0c + %c[before]\n"
+		"mov %%edi, 0x10 + %c[before]\n"
+		"call *%[test]\n"
+		"mov %%esp, 0x00 + %c[after]\n"
+		"mov %%ebp, 0x04 + %c[after]\n"
+		"mov %%ebx, 0x08 + %c[after]\n"
+		"mov %%esi, 0x0c + %c[after]\n"
+		"mov %%edi, 0x10 + %c[after]\n"
+		"push %[after]\n"
+		"push %[before]\n"
+		"push %[ret]\n"
+		"call %c[sanity_check]\n"
+		"pop %%ecx\n"
+		"pop %%ecx\n"
+		"pop %%ecx\n" :
+		[ret] "=a" (ret) :
+		[test] "r" (func), [before] "i" (&before), [after] "i" (&after), [sanity_check] "i" (&sanity_check) :
+		"ebx", "ecx", "edx", "esi", "edi", "flags", "memory"
+	);
+#else
+#error TODO
+#endif
+
+	SetUnhandledExceptionFilter(prev_unhandled_exception);
+	return ret;
+}
+#else
+#error TODO
+#endif
+
+/* EOF */

Propchange: trunk/rostests/tests/pseh2/psehtest.c
------------------------------------------------------------------------------
    svn:eol-style = native

Added: trunk/rostests/tests/pseh2/psehtest2.c
URL: http://svn.reactos.org/svn/reactos/trunk/rostests/tests/pseh2/psehtest2.c?rev=38311&view=auto
==============================================================================
--- trunk/rostests/tests/pseh2/psehtest2.c (added)
+++ trunk/rostests/tests/pseh2/psehtest2.c [iso-8859-1] Tue Dec 23 13:47:30 2008
@@ -1,0 +1,138 @@
+extern
+int return_arg(int arg)
+{
+	return arg;
+}
+
+extern
+void no_op(void)
+{
+}
+
+extern
+int return_zero(void)
+{
+	return 0;
+}
+
+extern
+int return_positive(void)
+{
+	return 1234;
+}
+
+extern
+int return_negative(void)
+{
+	return -1234;
+}
+
+extern
+int return_one(void)
+{
+	return 1;
+}
+
+extern
+int return_minusone(void)
+{
+	return -1;
+}
+
+extern
+int return_zero_2(void * p)
+{
+	return 0;
+}
+
+extern
+int return_positive_2(void * p)
+{
+	return 1234;
+}
+
+extern
+int return_negative_2(void * p)
+{
+	return -1234;
+}
+
+extern
+int return_one_2(void * p)
+{
+	return 1;
+}
+
+extern
+int return_minusone_2(void * p)
+{
+	return -1;
+}
+
+extern
+int return_zero_3(int n)
+{
+	return 0;
+}
+
+extern
+int return_positive_3(int n)
+{
+	return 1234;
+}
+
+extern
+int return_negative_3(int n)
+{
+	return -1234;
+}
+
+extern
+int return_one_3(int n)
+{
+	return 1;
+}
+
+extern
+int return_minusone_3(int n)
+{
+	return -1;
+}
+
+extern
+int return_zero_4(void * p, int n)
+{
+	return 0;
+}
+
+extern
+int return_positive_4(void * p, int n)
+{
+	return 1234;
+}
+
+extern
+int return_negative_4(void * p, int n)
+{
+	return -1234;
+}
+
+extern
+int return_one_4(void * p, int n)
+{
+	return 1;
+}
+
+extern
+int return_minusone_4(void * p, int n)
+{
+	return -1;
+}
+
+extern
+void set_positive(int * p)
+{
+	*p = 1234;
+}
+
+/* EOF */

Propchange: trunk/rostests/tests/pseh2/psehtest2.c
------------------------------------------------------------------------------
    svn:eol-style = native



More information about the Ros-diffs mailing list