[PATCH 3/4] msvcr90/tests: Add a commandline interface to call application termination functions

Detlef Riekenberg wine.dev at web.de
Sun Jan 30 16:34:40 CST 2011


Available options:
 --set_app_type value
 --set_error_mode value
 --set_abort_behavior value mask
 --abort
 --amsg_exit value
 --assert

--
By by ... Detlef
---
 dlls/msvcr90/tests/msvcr90.c |  167 ++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 162 insertions(+), 5 deletions(-)

diff --git a/dlls/msvcr90/tests/msvcr90.c b/dlls/msvcr90/tests/msvcr90.c
index d4a7262..27b0fda 100644
--- a/dlls/msvcr90/tests/msvcr90.c
+++ b/dlls/msvcr90/tests/msvcr90.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2010 Detlef Riekenberg
+ * Copyright 2010-2011 Detlef Riekenberg
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -72,6 +72,11 @@ static int (__cdecl *p_wcsncat_s)(wchar_t *dst, size_t elem, const wchar_t *src,
 static void (__cdecl *p_qsort_s)(void *, size_t, size_t, int (__cdecl *)(void *, const void *, const void *), void *);
 static int (__cdecl *p_controlfp_s)(unsigned int *, unsigned int, unsigned int);
 static int (__cdecl *p_atoflt)(_CRT_FLOAT *, char *);
+static int (__cdecl *p__set_app_type)(int);
+static int (__cdecl *p_set_error_mode)(int);
+static void (__cdecl *p_abort)(void);
+static void (__cdecl *p_amsg_exit)(int);
+static void (__cdecl *p_assert)(const char*, const char*, unsigned int);
 static unsigned int (__cdecl *p_set_abort_behavior)(unsigned int, unsigned int);
 static int (__cdecl *p_sopen_s)(int*, const char*, int, int, int);
 static int (__cdecl *p_wsopen_s)(int*, const wchar_t*, int, int, int);
@@ -83,6 +88,9 @@ static void* (WINAPI *pEncodePointer)(void *);
 
 static int cb_called[4];
 static int g_qsort_s_context_counter;
+static int my_argc;
+static char ** my_argv;
+
 
 static inline int almost_equal_f(float f1, float f2)
 {
@@ -786,6 +794,145 @@ if (0)
     p_free(mem);
 }
 
+/*********************************************************************
+ * Test various combinations related to application termination.
+ * 
+ * the behavior of the C runtime depends on the application type, the errormode
+ * and the abort behavior setting.
+ * Use WINETEST_DEBUG=2 to get more infos
+ *
+ * Available options:
+ * --set_app_type value
+ *      set the application type
+ *      1: Console (default failure output is stderr)
+ *      2: GUI     (default failure output is a messagebox)
+ *      other: GUI
+ *
+ * --set_error_mode value
+ *      set the error mode (default is 0)
+ *      0: failure message output depends on the app type
+ *      1: print the failure message to stderr 
+ *      2: display a messagebox with the failure message 
+ *      3: return the current error mode
+ *      <0 or >3: Application terminate with errorlevel 0xC0000417
+ *
+ * --set_abort_behavior value mask
+ *      update the abort behavior (default is 3)
+ *      result includes 0x01: (_WRITE_ABORT_MSG) output the failure message for abort
+ *      result includes 0x02: (_CALL_REPORTFAULT) report not generated in w2k/xp
+ *
+ * --abort
+ *      abort the application with the failure message #10 (in wine: abnormal program termination)
+ *
+ * --amsg_exit value
+ *      display the given runtime failure message. examples:
+ *      2: float support not loaded
+ *      8: nospace left for arguments
+ *      10: message for the abort function (in wine: abnormal program termination)
+ *
+ * --assert
+ *      display an assertion failure message with "winetest" as reason
+ *
+ */
+static void slave_process(void)
+{
+    int i = 0;
+
+    while ((winetest_debug > 1) && (my_argc > i)) {
+        trace("argv_%d: '%s'\n", i, my_argv[i]);
+        i++;
+    }
+
+    i = 2;
+    while ((my_argc > i) && (my_argv[i][0] == '-') && (my_argv[i][1] == '-')){
+
+        if (!strcmp(my_argv[i], "--set_abort_behavior")) {
+            int old;
+            int current;
+            int behavior_val = 0;
+            int behavior_mask = 0;
+
+            i++;
+            if (my_argc > i) {
+                behavior_val = atoi(my_argv[i]);
+                i++;
+            }
+
+            if (my_argc > i) {
+                behavior_mask = atoi(my_argv[i]);
+                i++;
+            }
+
+            old = p_set_abort_behavior(behavior_val, behavior_mask);
+
+            if (winetest_debug > 1)
+                trace("old: 0x%x, new bits 0x%x for mask 0x%x\n", old, (behavior_val & behavior_mask), behavior_mask);
+
+            current = p_set_abort_behavior(0, 0);
+
+            if (winetest_debug > 1)
+                trace("current: 0x%x\n", current);
+
+        }
+        else if (!strcmp(my_argv[i], "--set_app_type")) {
+            int newtype = 0;
+
+            i++;
+            if ((my_argc > i) && (isdigit(my_argv[i][0]))) {
+                newtype = atoi(my_argv[i]);
+                i++;
+
+                if (winetest_debug > 1)
+                    trace("new app_type: %d\n", newtype);
+
+                p__set_app_type(newtype);
+
+            }
+        }
+        else if (!strcmp(my_argv[i], "--set_error_mode")) {
+            int newmode = 0;
+            int res;
+
+            i++;
+            if ((my_argc > i) && (isdigit(my_argv[i][0]))) {
+                newmode = atoi(my_argv[i]);
+                i++;
+
+                if (winetest_debug > 1)
+                    trace("new error_mode: %d\n", newmode);
+
+                res = p_set_error_mode(newmode);
+                if (winetest_debug > 1)
+                    trace("_set_error_mode returned %d\n", res);
+            }
+        }
+        else if (!strcmp(my_argv[i], "--abort")) {
+            p_abort();
+        }
+        else if (!strcmp(my_argv[i], "--assert")) {
+            p_assert("winetest", "msvcr90.c", __LINE__);
+        }
+        else if (!strcmp(my_argv[i], "--amsg_exit")) {
+            int amsg_val = 0;
+
+            i++;
+            if ((my_argc > i) && (isdigit(my_argv[i][0]))) {
+                amsg_val = atoi(my_argv[i]);
+            }
+            p_amsg_exit(amsg_val);
+        }
+        else {
+            trace("bad command: '%s'\n", my_argv[i]);
+            exit(1);
+        }
+    }
+
+    trace("bad command: '%s'\n", my_argv[i]);
+    exit(1);
+}
+
+/* ########## */
+
 START_TEST(msvcr90)
 {
     HMODULE hcrt;
@@ -799,10 +946,6 @@ START_TEST(msvcr90)
     }
 
     p_set_invalid_parameter_handler = (void *) GetProcAddress(hcrt, "_set_invalid_parameter_handler");
-    if(p_set_invalid_parameter_handler)
-        ok(p_set_invalid_parameter_handler(test_invalid_parameter_handler) == NULL,
-                "Invalid parameter handler was already set\n");
-
     p_initterm_e = (void *) GetProcAddress(hcrt, "_initterm_e");
     p_encode_pointer = (void *) GetProcAddress(hcrt, "_encode_pointer");
     p_decode_pointer = (void *) GetProcAddress(hcrt, "_decode_pointer");
@@ -818,6 +961,11 @@ START_TEST(msvcr90)
     p_qsort_s = (void *) GetProcAddress(hcrt, "qsort_s");
     p_controlfp_s = (void *) GetProcAddress(hcrt, "_controlfp_s");
     p_atoflt = (void* )GetProcAddress(hcrt, "_atoflt");
+    p__set_app_type = (void *) GetProcAddress(hcrt, "__set_app_type");
+    p_set_error_mode = (void *) GetProcAddress(hcrt, "_set_error_mode");
+    p_abort = (void*) GetProcAddress(hcrt, "abort");
+    p_amsg_exit = (void*) GetProcAddress(hcrt, "_amsg_exit");
+    p_assert = (void*) GetProcAddress(hcrt, "_assert");
     p_set_abort_behavior = (void *) GetProcAddress(hcrt, "_set_abort_behavior");
     p_sopen_s = (void*) GetProcAddress(hcrt, "_sopen_s");
     p_wsopen_s = (void*) GetProcAddress(hcrt, "_wsopen_s");
@@ -828,6 +976,15 @@ START_TEST(msvcr90)
     hkernel32 = GetModuleHandleA("kernel32.dll");
     pEncodePointer = (void *) GetProcAddress(hkernel32, "EncodePointer");
 
+    my_argc = winetest_get_mainargs(&my_argv);
+    if (my_argc > 2) {
+        slave_process();
+    }
+
+    if(p_set_invalid_parameter_handler)
+        ok(p_set_invalid_parameter_handler(test_invalid_parameter_handler) == NULL,
+                "Invalid parameter handler was already set\n");
+
     test__initterm_e();
     test__encode_pointer();
     test_error_messages();
-- 
1.7.1




More information about the wine-patches mailing list