[2/2] msvcrt/tests: qsort_s implementation and tests (try 3)
Vincas Miliūnas
vincas.miliunas at gmail.com
Wed Nov 3 15:24:11 CDT 2010
qsort_s implementation and tests for bug #24925.
Moved the code from msvcr80 to msvcrt.
Added parameter validation for implementation and tests.
---
dlls/msvcrt/tests/misc.c | 179 ++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 179 insertions(+), 0 deletions(-)
diff --git a/dlls/msvcrt/tests/misc.c b/dlls/msvcrt/tests/misc.c
index a4a1bd3..7ef2789 100644
--- a/dlls/msvcrt/tests/misc.c
+++ b/dlls/msvcrt/tests/misc.c
@@ -22,6 +22,44 @@
#include <errno.h>
#include "msvcrt.h"
+#define DEFINE_EXPECT(func) \
+ static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
+
+#define SET_EXPECT(func) \
+ expect_ ## func = TRUE
+
+#define CHECK_EXPECT2(func) \
+ do { \
+ ok(expect_ ##func, "unexpected call " #func "\n"); \
+ called_ ## func = TRUE; \
+ }while(0)
+
+#define CHECK_EXPECT(func) \
+ do { \
+ CHECK_EXPECT2(func); \
+ expect_ ## func = FALSE; \
+ }while(0)
+
+#define CHECK_CALLED(func) \
+ do { \
+ ok(called_ ## func, "expected " #func "\n"); \
+ expect_ ## func = called_ ## func = FALSE; \
+ }while(0)
+
+#define CHECK_NOT_CALLED(func) \
+ do { \
+ ok(!called_ ## func, "unexpected " #func "\n"); \
+ expect_ ## func = called_ ## func = FALSE; \
+ }while(0)
+
+#define CLEAR_CALLED(func) \
+ expect_ ## func = called_ ## func = FALSE
+
+DEFINE_EXPECT(invalid_parameter_handler);
+
+typedef int (CDECL *_QSORT_S_COMPARE_FN)(void *, const void *, const void *);
+
+static _invalid_parameter_handler (__cdecl *p_set_invalid_parameter_handler)(_invalid_parameter_handler);
static int (__cdecl *prand_s)(unsigned int *);
static int (__cdecl *pmemcpy_s)(void *, MSVCRT_size_t, void*, MSVCRT_size_t);
static int (__cdecl *pI10_OUTPUT)(long double, int, int, void*);
@@ -30,11 +68,31 @@ static int (__cdecl *p_get_doserrno)(int *);
static int (__cdecl *p_get_errno)(int *);
static int (__cdecl *p_set_doserrno)(int);
static int (__cdecl *p_set_errno)(int);
+static void (__cdecl *p_qsort_s)(void *, size_t, size_t, _QSORT_S_COMPARE_FN, void *);
+
+static int g_qsort_s_context_counter;
+
+static void __cdecl test_invalid_parameter_handler(const wchar_t *expression,
+ const wchar_t *function, const wchar_t *file,
+ unsigned line, uintptr_t arg)
+{
+ CHECK_EXPECT(invalid_parameter_handler);
+ ok(expression == NULL, "expression is not NULL\n");
+ ok(function == NULL, "function is not NULL\n");
+ ok(file == NULL, "file is not NULL\n");
+ ok(line == 0, "line = %u\n", line);
+ ok(arg == 0, "arg = %lx\n", (UINT_PTR)arg);
+}
static void init(void)
{
HMODULE hmod = GetModuleHandleA("msvcrt.dll");
+ p_set_invalid_parameter_handler = (void *) GetProcAddress(hmod, "_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");
+
prand_s = (void *)GetProcAddress(hmod, "rand_s");
pmemcpy_s = (void*)GetProcAddress(hmod, "memcpy_s");
pI10_OUTPUT = (void*)GetProcAddress(hmod, "$I10_OUTPUT");
@@ -43,6 +101,7 @@ static void init(void)
p_get_errno = (void *)GetProcAddress(hmod, "_get_errno");
p_set_doserrno = (void *)GetProcAddress(hmod, "_set_doserrno");
p_set_errno = (void *)GetProcAddress(hmod, "_set_errno");
+ p_qsort_s = (void *)GetProcAddress(hmod, "qsort_s");
}
static void test_rand_s(void)
@@ -351,6 +410,125 @@ static void test__set_errno(void)
ok(errno == 0xdeadbeef, "Expected errno to be 0xdeadbeef, got %d\n", errno);
}
+/* ########## */
+/* Borrowed from dlls/ntdll/tests/string.c */
+
+static __cdecl int intcomparefunc(void *context, const void *a, const void*b)
+{
+ ok (a != b, "must never get the same pointer\n");
+ ++*(int *) context;
+ return (*(int*)a) - (*(int*)b);
+}
+
+static __cdecl int charcomparefunc(void *context, const void *a, const void*b)
+{
+ ok (a != b, "must never get the same pointer\n");
+ ++*(int *) context;
+ return (*(char*)a) - (*(char*)b);
+}
+
+static __cdecl int strcomparefunc(void *context, const void *a, const void*b)
+{
+ ok (a != b, "must never get the same pointer\n");
+ ++*(int *) context;
+ return lstrcmpA(*(char**)a,*(char**)b);
+}
+
+static void test_qsort_s(void)
+{
+ int arr[5] = { 23, 42, 8, 4, 16 };
+ char carr[5] = { 42, 23, 4, 8, 16 };
+ const char *strarr[7] = {
+ "Hello",
+ "Wine",
+ "World",
+ "!",
+ "Hopefully",
+ "Sorted",
+ "."
+ };
+
+ SET_EXPECT(invalid_parameter_handler);
+ p_qsort_s(NULL, 0, 0, NULL, NULL);
+ CHECK_CALLED(invalid_parameter_handler);
+
+ SET_EXPECT(invalid_parameter_handler);
+ p_qsort_s(NULL, 0, 0, intcomparefunc, NULL);
+ CHECK_CALLED(invalid_parameter_handler);
+
+ SET_EXPECT(invalid_parameter_handler);
+ p_qsort_s(NULL, 0, sizeof(int), NULL, NULL);
+ CHECK_CALLED(invalid_parameter_handler);
+
+ SET_EXPECT(invalid_parameter_handler);
+ p_qsort_s(NULL, 1, sizeof(int), intcomparefunc, NULL);
+ CHECK_CALLED(invalid_parameter_handler);
+
+ g_qsort_s_context_counter = 0;
+ p_qsort_s(NULL, 0, sizeof(int), intcomparefunc, NULL);
+ ok(g_qsort_s_context_counter == 0, "callback shouldn't have been called\n");
+
+ g_qsort_s_context_counter = 0;
+ p_qsort_s((void*)arr, 0, sizeof(int), intcomparefunc, &g_qsort_s_context_counter);
+ ok(g_qsort_s_context_counter == 0, "callback shouldn't have been called\n");
+ ok(arr[0] == 23, "badly sorted, nmemb=0, arr[0] is %d\n", arr[0]);
+ ok(arr[1] == 42, "badly sorted, nmemb=0, arr[1] is %d\n", arr[1]);
+ ok(arr[2] == 8, "badly sorted, nmemb=0, arr[2] is %d\n", arr[2]);
+ ok(arr[3] == 4, "badly sorted, nmemb=0, arr[3] is %d\n", arr[3]);
+ ok(arr[4] == 16, "badly sorted, nmemb=0, arr[4] is %d\n", arr[4]);
+
+ g_qsort_s_context_counter = 0;
+ p_qsort_s((void*)arr, 1, sizeof(int), intcomparefunc, &g_qsort_s_context_counter);
+ ok(g_qsort_s_context_counter == 0, "callback shouldn't have been called\n");
+ ok(arr[0] == 23, "badly sorted, nmemb=1, arr[0] is %d\n", arr[0]);
+ ok(arr[1] == 42, "badly sorted, nmemb=1, arr[1] is %d\n", arr[1]);
+ ok(arr[2] == 8, "badly sorted, nmemb=1, arr[2] is %d\n", arr[2]);
+ ok(arr[3] == 4, "badly sorted, nmemb=1, arr[3] is %d\n", arr[3]);
+ ok(arr[4] == 16, "badly sorted, nmemb=1, arr[4] is %d\n", arr[4]);
+
+ SET_EXPECT(invalid_parameter_handler);
+ g_qsort_s_context_counter = 0;
+ p_qsort_s((void*)arr, 5, 0, intcomparefunc, &g_qsort_s_context_counter);
+ ok(g_qsort_s_context_counter == 0, "callback shouldn't have been called\n");
+ ok(arr[0] == 23, "badly sorted, size=0, arr[0] is %d\n", arr[0]);
+ ok(arr[1] == 42, "badly sorted, size=0, arr[1] is %d\n", arr[1]);
+ ok(arr[2] == 8, "badly sorted, size=0, arr[2] is %d\n", arr[2]);
+ ok(arr[3] == 4, "badly sorted, size=0, arr[3] is %d\n", arr[3]);
+ ok(arr[4] == 16, "badly sorted, size=0, arr[4] is %d\n", arr[4]);
+ CHECK_CALLED(invalid_parameter_handler);
+
+ g_qsort_s_context_counter = 0;
+ p_qsort_s((void*)arr, 5, sizeof(int), intcomparefunc, &g_qsort_s_context_counter);
+ ok(g_qsort_s_context_counter > 0, "callback wasn't called\n");
+ ok(arr[0] == 4, "badly sorted, arr[0] is %d\n", arr[0]);
+ ok(arr[1] == 8, "badly sorted, arr[1] is %d\n", arr[1]);
+ ok(arr[2] == 16, "badly sorted, arr[2] is %d\n", arr[2]);
+ ok(arr[3] == 23, "badly sorted, arr[3] is %d\n", arr[3]);
+ ok(arr[4] == 42, "badly sorted, arr[4] is %d\n", arr[4]);
+
+ g_qsort_s_context_counter = 0;
+ p_qsort_s((void*)carr, 5, sizeof(char), charcomparefunc, &g_qsort_s_context_counter);
+ ok(g_qsort_s_context_counter > 0, "callback wasn't called\n");
+ ok(carr[0] == 4, "badly sorted, carr[0] is %d\n", carr[0]);
+ ok(carr[1] == 8, "badly sorted, carr[1] is %d\n", carr[1]);
+ ok(carr[2] == 16, "badly sorted, carr[2] is %d\n", carr[2]);
+ ok(carr[3] == 23, "badly sorted, carr[3] is %d\n", carr[3]);
+ ok(carr[4] == 42, "badly sorted, carr[4] is %d\n", carr[4]);
+
+ g_qsort_s_context_counter = 0;
+ p_qsort_s((void*)strarr, 7, sizeof(char*), strcomparefunc, &g_qsort_s_context_counter);
+ ok(g_qsort_s_context_counter > 0, "callback wasn't called\n");
+ ok(!strcmp(strarr[0],"!"), "badly sorted, strarr[0] is %s\n", strarr[0]);
+ ok(!strcmp(strarr[1],"."), "badly sorted, strarr[1] is %s\n", strarr[1]);
+ ok(!strcmp(strarr[2],"Hello"), "badly sorted, strarr[2] is %s\n", strarr[2]);
+ ok(!strcmp(strarr[3],"Hopefully"), "badly sorted, strarr[3] is %s\n", strarr[3]);
+ ok(!strcmp(strarr[4],"Sorted"), "badly sorted, strarr[4] is %s\n", strarr[4]);
+ ok(!strcmp(strarr[5],"Wine"), "badly sorted, strarr[5] is %s\n", strarr[5]);
+ ok(!strcmp(strarr[6],"World"), "badly sorted, strarr[6] is %s\n", strarr[6]);
+}
+
+/* ########## */
+
START_TEST(misc)
{
init();
@@ -363,4 +541,5 @@ START_TEST(misc)
test__get_errno();
test__set_doserrno();
test__set_errno();
+ test_qsort_s();
}
--
1.7.2.3
More information about the wine-patches
mailing list