set svn:eol-style to native
[reactos.git] / reactos / include / libs / pseh / prettybased.h
index 0991a3e..e3345cf 100644 (file)
-/*\r
- Copyright (c) 2004 KJK::Hyperion\r
\r
- Permission is hereby granted, free of charge, to any person obtaining a copy of\r
- this software and associated documentation files (the "Software"), to deal in\r
- the Software without restriction, including without limitation the rights to\r
- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\r
- of the Software, and to permit persons to whom the Software is furnished to do\r
- so, subject to the following conditions:\r
\r
- The above copyright notice and this permission notice shall be included in all\r
- copies or substantial portions of the Software.\r
\r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-/*\r
-Pretty PSEH\r
-\r
-Made to be macro compatible with ms seh syntax and to be pretty, having the\r
-finally block inline etc. Being pretty is not cheap. PPSEH has more\r
-overhead than PSEH, thou mostly during exception/unwinding. Normal execution\r
-only add the overhead of one setjmp, and only in the try/finally case.\r
-PPSEH is probably much less portable than PSEH also.....\r
-\r
-ALERT!ALERT!ALERT!ALERT!ALERT!ALERT!ALERT!ALERT!ALERT!ALERT!ALERT!ALERT!ALERT!\r
--must always use non-native NLG cause a special version of longjmp (which doesn't\r
-restore esp) is needed\r
-\r
--compiler must use ebp as stack frame pointer, cause the finally block rely\r
-on this to access external variables\r
-\r
--all external variables that are used in the except/finally block MUST be volatile\r
-to prevent variables from being optimized into registers.\r
-See: http://alphalinux.org/archives/axp-list/1998/February1998/0330.html\r
-\r
--you can't use return within a try/except/finally block\r
-\r
--you can't use __LEAVE within a (for/do/while) loop. it will only leave the loop\r
-and not the try-block itself\r
-\r
-\r
-USAGE:\r
-\r
-__TRY{\r
-   __LEAVE;\r
-}\r
-__EXCEPT(_SEH_STATIC_FILTER(EXCEPTION_EXECUTE_HANDLER)){\r
-}\r
-__ENDTRY;\r
-\r
-\r
-__TRY{\r
-}\r
-__FINALLY{\r
-}\r
-__ENDTRY;\r
-\r
-\r
-_SEH_FILTER(filter){\r
-   return EXCEPTION_EXECUTE_HANDLER;\r
-}\r
-__TRY2{\r
-}\r
-__EXCEPT2(filter){\r
-}\r
-__FINALLY2{\r
-}\r
-__ENDTRY2;\r
-\r
-\r
-\r
--Gunnar\r
-\r
-*/\r
-\r
-\r
-#ifndef KJK_PPSEH_FRAMEBASED_H_\r
-#define KJK_PPSEH_FRAMEBASED_H_\r
-\r
-#include <pseh/framebased/internal.h>\r
-#include <pseh/excpt.h>\r
-#include <malloc.h>\r
-\r
-#ifndef offsetof\r
-# include <stddef.h>\r
-#endif\r
-\r
-/*\r
-Must always use non-native NLG since we need a special version of longjmp which does\r
-not restore esp\r
-*/\r
-#include <pseh/setjmp.h>\r
-\r
-\r
-typedef struct __SEHFrame\r
-{\r
- _SEHPortableFrame_t SEH_Header;\r
- _SEHJmpBuf_t SEH_JmpBuf;\r
- _SEHJmpBuf_t* SEH_JmpRetPtr;\r
-}\r
-_SEHFrame_t;\r
-\r
-/*\r
- Note: just define __inline to an empty symbol if your C compiler doesn't\r
- support it\r
-*/\r
-#ifdef __cplusplus\r
-# ifndef __inline\r
-#  define __inline inline\r
-# endif\r
-#endif\r
-\r
-\r
-/* FILTER FUNCTIONS */\r
-/* Declares a filter function's prototype */\r
-#define _SEH_FILTER(NAME_) \\r
- long __stdcall NAME_ \\r
- ( \\r
-  struct _EXCEPTION_POINTERS * _SEHExceptionPointers, \\r
-  struct __SEHPortableFrame * _SEHPortableFrame \\r
- )\r
-\r
-\r
-/* Declares a static filter */\r
-#define _SEH_STATIC_FILTER(ACTION_) ((_SEHFilter_t)((ACTION_) + 2))\r
-\r
-\r
-static __declspec(noreturn) __inline void __stdcall _SEHCompilerSpecificHandler\r
-(\r
- _SEHPortableFrame_t * frame\r
-)\r
-{\r
-   _SEHFrame_t * myframe;\r
-   myframe = (_SEHFrame_t *)(((char *)frame) - offsetof(_SEHFrame_t, SEH_Header));\r
-   _SEHLongJmp(myframe->SEH_JmpBuf, 1);\r
-}\r
-\r
-\r
-\r
-void __stdcall _FinallyPretty\r
-(\r
- struct __SEHPortableFrame * frame\r
-)\r
-{\r
-   _SEHFrame_t * myframe;\r
-   _SEHJmpBuf_t jmpRetBuf;\r
-   \r
-   myframe = (_SEHFrame_t *)(((char *)frame) - offsetof(_SEHFrame_t, SEH_Header));   \r
-    \r
-   if(_SEHSetJmp(jmpRetBuf) == 0)\r
-   {\r
-      myframe->SEH_JmpRetPtr = &jmpRetBuf;\r
-      _SEHLongJmp_KeepEsp(myframe->SEH_JmpBuf, 2);\r
-   }\r
-}\r
-\r
-\r
-        \r
-#define ___EXCEPT_DUAL(filter)                                                \\r
-         } while(0);                                                          \\r
-                                                                              \\r
-         _SEHLeave(&_SEHFrame->SEH_Header);                                   \\r
-      }                                                                       \\r
-      else                                                                    \\r
-      {                                                                       \\r
-         _SEHHandlers.SH_Filter = (filter);                                   \\r
-         _SEHHandlers.SH_Finally = _FinallyPretty;                            \\r
-                                                                              \\r
-         if(_loop == 2 || (_ret = _SEHSetJmp(_SEHFrame->SEH_JmpBuf)))         \\r
-         {                                                                    \\r
-            if (_ret == 1)                                                    \\r
-            {                                                                 \\r
-               _SEHLeave(&_SEHFrame->SEH_Header);                             \\r
-               do                                                             \\r
-               { \r
-\r
-\r
-               \r
-#define ___FINALLY_DUAL                                                       \\r
-               } while (0);                                                   \\r
-            }                                                                 \\r
-                                                                              \\r
-            do                                                                \\r
-            {\r
-               \r
-               \r
-               \r
-#define ___EXCEPT_SINGLE(filter)                                              \\r
-         } while(0);                                                          \\r
-                                                                              \\r
-         _SEHLeave(&_SEHFrame->SEH_Header);                                   \\r
-         break;                                                               \\r
-      }                                                                       \\r
-      else                                                                    \\r
-      {                                                                       \\r
-         _SEHHandlers.SH_Filter = (filter);                                   \\r
-         _SEHHandlers.SH_Finally = (NULL);                                    \\r
-                                                                              \\r
-         if(_SEHSetJmp(_SEHFrame->SEH_JmpBuf))                                \\r
-         {                                                                    \\r
-            _SEHLeave(&_SEHFrame->SEH_Header);                                \\r
-            do                                                                \\r
-            { \r
-\r
-\r
-\r
-#define ___TRY                                                                \\r
-   do                                                                         \\r
-   {                                                                          \\r
-      int _loop =0; int _ret = 0;                                             \\r
-      static _SEHHandlers_t _SEHHandlers =                                    \\r
-      {                                                                       \\r
-      (NULL),                                                                 \\r
-      _SEHCompilerSpecificHandler,                                            \\r
-      (NULL)                                                                  \\r
-      };                                                                      \\r
-                                                                              \\r
-      _SEHFrame_t * _SEHFrame;                                                \\r
-      volatile _SEHPortableFrame_t * _SEHPortableFrame;                       \\r
-                                                                              \\r
-      _SEHFrame = _alloca(sizeof(_SEHFrame_t));                               \\r
-      _SEHFrame->SEH_Header.SPF_Handlers = &_SEHHandlers;                     \\r
-                                                                              \\r
-      _SEHPortableFrame = &_SEHFrame->SEH_Header;                             \\r
-      (void)_SEHPortableFrame;                                                \\r
-                                                                              \\r
-      for(;;_loop++)                                                          \\r
-      if (_loop == 1)                                                         \\r
-      {                                                                       \\r
-         _SEHEnter(&_SEHFrame->SEH_Header);                                   \\r
-                                                                              \\r
-         do                                                                   \\r
-         {\r
-\r
-\r
-#define ___FINALLY_SINGLE                                                     \\r
-         } while(0);                                                          \\r
-                                                                              \\r
-         _SEHLeave(&_SEHFrame->SEH_Header);                                   \\r
-      }                                                                       \\r
-      else                                                                    \\r
-      {                                                                       \\r
-         _SEHHandlers.SH_Filter = _SEH_STATIC_FILTER(_SEH_CONTINUE_SEARCH);   \\r
-         _SEHHandlers.SH_Finally = _FinallyPretty;                            \\r
-                                                                              \\r
-         if(_loop == 2 || (_ret = _SEHSetJmp(_SEHFrame->SEH_JmpBuf)))         \\r
-         {                                                                    \\r
-            do                                                                \\r
-            {\r
-\r
-\r
-\r
-#define ___ENDTRY                                                             \\r
-            } while (0);                                                      \\r
-                                                                              \\r
-            if (_ret == 2)                                                    \\r
-            {                                                                 \\r
-               _SEHLongJmp(*_SEHFrame->SEH_JmpRetPtr, 1);                     \\r
-            }                                                                 \\r
-            break;                                                            \\r
-         }                                                                    \\r
-      }                                                                       \\r
-    } while (0);\r
-\r
-\r
-\r
-#ifdef _MSC_VER\r
-   #define __TRY2 __try{__try\r
-   #define __EXCEPT2 __except\r
-   #define __FINALLY2  }__finally\r
-   #define __ENDTRY2\r
-   #define __TRY __try   \r
-   #define __EXCEPT __except\r
-   #define __FINALLY __finally\r
-   #define __ENDTRY\r
-   #define _SEH_STATIC_FILTER(ACTION_) (ACTION_)   \r
-   #define __LEAVE __leave\r
-   #define __LEAVE2 __leave\r
-#else\r
-   #define __TRY2 ___TRY\r
-   #define __EXCEPT2 ___EXCEPT_DUAL\r
-   #define __FINALLY2 ___FINALLY_DUAL\r
-   #define __ENDTRY2 __ENDTRY\r
-   #define __TRY ___TRY   \r
-   #define __EXCEPT ___EXCEPT_SINGLE\r
-   #define __FINALLY ___FINALLY_SINGLE\r
-   #define __ENDTRY ___ENDTRY\r
-   #define __LEAVE break\r
-   #define __LEAVE2 break\r
-#endif\r
-\r
-\r
-#endif\r
+/*
+ Copyright (c) 2004 KJK::Hyperion
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
+ this software and associated documentation files (the "Software"), to deal in
+ the Software without restriction, including without limitation the rights to
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ of the Software, and to permit persons to whom the Software is furnished to do
+ so, subject to the following conditions:
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+*/
+/*
+Pretty PSEH
+
+Made to be macro compatible with ms seh syntax and to be pretty, having the
+finally block inline etc. Being pretty is not cheap. PPSEH has more
+overhead than PSEH, thou mostly during exception/unwinding. Normal execution
+only add the overhead of one setjmp, and only in the try/finally case.
+PPSEH is probably much less portable than PSEH also.....
+
+ALERT!ALERT!ALERT!ALERT!ALERT!ALERT!ALERT!ALERT!ALERT!ALERT!ALERT!ALERT!ALERT!
+-must always use non-native NLG cause a special version of longjmp (which doesn't
+restore esp) is needed
+
+-compiler must use ebp as stack frame pointer, cause the finally block rely
+on this to access external variables
+
+-all external variables that are used in the except/finally block MUST be volatile
+to prevent variables from being optimized into registers.
+See: http://alphalinux.org/archives/axp-list/1998/February1998/0330.html
+
+-you can't use return within a try/except/finally block
+
+-you can't use __LEAVE within a (for/do/while) loop. it will only leave the loop
+and not the try-block itself
+
+
+USAGE:
+
+__TRY{
+   __LEAVE;
+}
+__EXCEPT(_SEH_STATIC_FILTER(EXCEPTION_EXECUTE_HANDLER)){
+}
+__ENDTRY;
+
+
+__TRY{
+}
+__FINALLY{
+}
+__ENDTRY;
+
+
+_SEH_FILTER(filter){
+   return EXCEPTION_EXECUTE_HANDLER;
+}
+__TRY2{
+}
+__EXCEPT2(filter){
+}
+__FINALLY2{
+}
+__ENDTRY2;
+
+
+
+-Gunnar
+
+*/
+
+
+#ifndef KJK_PPSEH_FRAMEBASED_H_
+#define KJK_PPSEH_FRAMEBASED_H_
+
+#include <pseh/framebased/internal.h>
+#include <pseh/excpt.h>
+#include <malloc.h>
+
+#ifndef offsetof
+# include <stddef.h>
+#endif
+
+/*
+Must always use non-native NLG since we need a special version of longjmp which does
+not restore esp
+*/
+#include <pseh/setjmp.h>
+
+
+typedef struct __SEHFrame
+{
+ _SEHPortableFrame_t SEH_Header;
+ _SEHJmpBuf_t SEH_JmpBuf;
+ _SEHJmpBuf_t* SEH_JmpRetPtr;
+}
+_SEHFrame_t;
+
+/*
+ Note: just define __inline to an empty symbol if your C compiler doesn't
+ support it
+*/
+#ifdef __cplusplus
+# ifndef __inline
+#  define __inline inline
+# endif
+#endif
+
+
+/* FILTER FUNCTIONS */
+/* Declares a filter function's prototype */
+#define _SEH_FILTER(NAME_) \
+ long __stdcall NAME_ \
+ ( \
+  struct _EXCEPTION_POINTERS * _SEHExceptionPointers, \
+  struct __SEHPortableFrame * _SEHPortableFrame \
+ )
+
+
+/* Declares a static filter */
+#define _SEH_STATIC_FILTER(ACTION_) ((_SEHFilter_t)((ACTION_) + 2))
+
+
+static __declspec(noreturn) __inline void __stdcall _SEHCompilerSpecificHandler
+(
+ _SEHPortableFrame_t * frame
+)
+{
+   _SEHFrame_t * myframe;
+   myframe = (_SEHFrame_t *)(((char *)frame) - offsetof(_SEHFrame_t, SEH_Header));
+   _SEHLongJmp(myframe->SEH_JmpBuf, 1);
+}
+
+
+
+void __stdcall _FinallyPretty
+(
+ struct __SEHPortableFrame * frame
+)
+{
+   _SEHFrame_t * myframe;
+   _SEHJmpBuf_t jmpRetBuf;
+   
+   myframe = (_SEHFrame_t *)(((char *)frame) - offsetof(_SEHFrame_t, SEH_Header));   
+    
+   if(_SEHSetJmp(jmpRetBuf) == 0)
+   {
+      myframe->SEH_JmpRetPtr = &jmpRetBuf;
+      _SEHLongJmp_KeepEsp(myframe->SEH_JmpBuf, 2);
+   }
+}
+
+
+        
+#define ___EXCEPT_DUAL(filter)                                                \
+         } while(0);                                                          \
+                                                                              \
+         _SEHLeave(&_SEHFrame->SEH_Header);                                   \
+      }                                                                       \
+      else                                                                    \
+      {                                                                       \
+         _SEHHandlers.SH_Filter = (filter);                                   \
+         _SEHHandlers.SH_Finally = _FinallyPretty;                            \
+                                                                              \
+         if(_loop == 2 || (_ret = _SEHSetJmp(_SEHFrame->SEH_JmpBuf)))         \
+         {                                                                    \
+            if (_ret == 1)                                                    \
+            {                                                                 \
+               _SEHLeave(&_SEHFrame->SEH_Header);                             \
+               do                                                             \
+               { 
+
+
+               
+#define ___FINALLY_DUAL                                                       \
+               } while (0);                                                   \
+            }                                                                 \
+                                                                              \
+            do                                                                \
+            {
+               
+               
+               
+#define ___EXCEPT_SINGLE(filter)                                              \
+         } while(0);                                                          \
+                                                                              \
+         _SEHLeave(&_SEHFrame->SEH_Header);                                   \
+         break;                                                               \
+      }                                                                       \
+      else                                                                    \
+      {                                                                       \
+         _SEHHandlers.SH_Filter = (filter);                                   \
+         _SEHHandlers.SH_Finally = (NULL);                                    \
+                                                                              \
+         if(_SEHSetJmp(_SEHFrame->SEH_JmpBuf))                                \
+         {                                                                    \
+            _SEHLeave(&_SEHFrame->SEH_Header);                                \
+            do                                                                \
+            { 
+
+
+
+#define ___TRY                                                                \
+   do                                                                         \
+   {                                                                          \
+      int _loop =0; int _ret = 0;                                             \
+      static _SEHHandlers_t _SEHHandlers =                                    \
+      {                                                                       \
+      (NULL),                                                                 \
+      _SEHCompilerSpecificHandler,                                            \
+      (NULL)                                                                  \
+      };                                                                      \
+                                                                              \
+      _SEHFrame_t * _SEHFrame;                                                \
+      volatile _SEHPortableFrame_t * _SEHPortableFrame;                       \
+                                                                              \
+      _SEHFrame = _alloca(sizeof(_SEHFrame_t));                               \
+      _SEHFrame->SEH_Header.SPF_Handlers = &_SEHHandlers;                     \
+                                                                              \
+      _SEHPortableFrame = &_SEHFrame->SEH_Header;                             \
+      (void)_SEHPortableFrame;                                                \
+                                                                              \
+      for(;;_loop++)                                                          \
+      if (_loop == 1)                                                         \
+      {                                                                       \
+         _SEHEnter(&_SEHFrame->SEH_Header);                                   \
+                                                                              \
+         do                                                                   \
+         {
+
+
+#define ___FINALLY_SINGLE                                                     \
+         } while(0);                                                          \
+                                                                              \
+         _SEHLeave(&_SEHFrame->SEH_Header);                                   \
+      }                                                                       \
+      else                                                                    \
+      {                                                                       \
+         _SEHHandlers.SH_Filter = _SEH_STATIC_FILTER(_SEH_CONTINUE_SEARCH);   \
+         _SEHHandlers.SH_Finally = _FinallyPretty;                            \
+                                                                              \
+         if(_loop == 2 || (_ret = _SEHSetJmp(_SEHFrame->SEH_JmpBuf)))         \
+         {                                                                    \
+            do                                                                \
+            {
+
+
+
+#define ___ENDTRY                                                             \
+            } while (0);                                                      \
+                                                                              \
+            if (_ret == 2)                                                    \
+            {                                                                 \
+               _SEHLongJmp(*_SEHFrame->SEH_JmpRetPtr, 1);                     \
+            }                                                                 \
+            break;                                                            \
+         }                                                                    \
+      }                                                                       \
+    } while (0);
+
+
+
+#ifdef _MSC_VER
+   #define __TRY2 __try{__try
+   #define __EXCEPT2 __except
+   #define __FINALLY2  }__finally
+   #define __ENDTRY2
+   #define __TRY __try   
+   #define __EXCEPT __except
+   #define __FINALLY __finally
+   #define __ENDTRY
+   #define _SEH_STATIC_FILTER(ACTION_) (ACTION_)   
+   #define __LEAVE __leave
+   #define __LEAVE2 __leave
+#else
+   #define __TRY2 ___TRY
+   #define __EXCEPT2 ___EXCEPT_DUAL
+   #define __FINALLY2 ___FINALLY_DUAL
+   #define __ENDTRY2 __ENDTRY
+   #define __TRY ___TRY   
+   #define __EXCEPT ___EXCEPT_SINGLE
+   #define __FINALLY ___FINALLY_SINGLE
+   #define __ENDTRY ___ENDTRY
+   #define __LEAVE break
+   #define __LEAVE2 break
+#endif
+
+
+#endif