[1/2] msvcrt: qsort_s implementation and tests (try 3)
Vincas Miliūnas
vincas.miliunas at gmail.com
Wed Nov 3 15:23:53 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/msvcr100/msvcr100.spec | 2 +-
dlls/msvcr80/msvcr80.spec | 2 +-
dlls/msvcr90/msvcr90.spec | 2 +-
dlls/msvcrt/misc.c | 86 +++++++++++++++++++++++++++++++++++++++++++
dlls/msvcrt/msvcrt.spec | 2 +-
5 files changed, 90 insertions(+), 4 deletions(-)
diff --git a/dlls/msvcr100/msvcr100.spec b/dlls/msvcr100/msvcr100.spec
index e451db9..8e02195 100644
--- a/dlls/msvcr100/msvcr100.spec
+++ b/dlls/msvcr100/msvcr100.spec
@@ -1550,7 +1550,7 @@
@ cdecl putwc(long ptr) msvcrt.putwc
@ cdecl putwchar(long) msvcrt.putwchar
@ cdecl qsort(ptr long long ptr) msvcrt.qsort
-@ stub qsort_s
+@ cdecl qsort_s(ptr long long ptr ptr) msvcrt.qsort_s
@ cdecl raise(long) msvcrt.raise
@ cdecl rand() msvcrt.rand
@ cdecl rand_s(ptr) msvcrt.rand_s
diff --git a/dlls/msvcr80/msvcr80.spec b/dlls/msvcr80/msvcr80.spec
index 1734c72..0234b4d 100644
--- a/dlls/msvcr80/msvcr80.spec
+++ b/dlls/msvcr80/msvcr80.spec
@@ -1404,7 +1404,7 @@
@ cdecl putwc(long ptr) msvcrt.putwc
@ cdecl putwchar(long) msvcrt.putwchar
@ cdecl qsort(ptr long long ptr) msvcrt.qsort
-@ stub qsort_s
+@ cdecl qsort_s(ptr long long ptr ptr) msvcrt.qsort_s
@ cdecl raise(long) msvcrt.raise
@ cdecl rand() msvcrt.rand
@ cdecl rand_s(ptr) msvcrt.rand_s
diff --git a/dlls/msvcr90/msvcr90.spec b/dlls/msvcr90/msvcr90.spec
index f188329..d766a41 100644
--- a/dlls/msvcr90/msvcr90.spec
+++ b/dlls/msvcr90/msvcr90.spec
@@ -1388,7 +1388,7 @@
@ cdecl putwc(long ptr) msvcrt.putwc
@ cdecl putwchar(long) msvcrt.putwchar
@ cdecl qsort(ptr long long ptr) msvcrt.qsort
-@ stub qsort_s
+@ cdecl qsort_s(ptr long long ptr ptr) msvcrt.qsort_s
@ cdecl raise(long) msvcrt.raise
@ cdecl rand() msvcrt.rand
@ cdecl rand_s(ptr) msvcrt.rand_s
diff --git a/dlls/msvcrt/misc.c b/dlls/msvcrt/misc.c
index c044d63..5286185 100644
--- a/dlls/msvcrt/misc.c
+++ b/dlls/msvcrt/misc.c
@@ -29,6 +29,7 @@
WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
+typedef int (CDECL *_QSORT_S_COMPARE_FN)(void *, const void *, const void *);
/*********************************************************************
* _beep (MSVCRT.@)
@@ -186,3 +187,88 @@ void CDECL _chkesp(void)
# endif /* __GNUC__ */
#endif /* __i386__ */
+
+/*********************************************************************
+ * Helper function for MSVCRT_qsort_s.
+ *
+ * Based on http://github.com/git/git/blob/master/compat/qsort.c
+ *
+ */
+void msort_with_tmp(void *b, size_t n, size_t s, _QSORT_S_COMPARE_FN cmp,
+ void *context, char *t)
+{
+ char *tmp;
+ char *b1, *b2;
+ size_t n1, n2;
+
+ if (n <= 1)
+ return;
+
+ n1 = n / 2;
+ n2 = n - n1;
+ b1 = b;
+ b2 = (char *)b + (n1 * s);
+
+ msort_with_tmp(b1, n1, s, cmp, context, t);
+ msort_with_tmp(b2, n2, s, cmp, context, t);
+
+ tmp = t;
+
+ while (n1 > 0 && n2 > 0) {
+ if (b1 == b2 || cmp(context, b1, b2) <= 0) {
+ memcpy(tmp, b1, s);
+ tmp += s;
+ b1 += s;
+ --n1;
+ } else {
+ memcpy(tmp, b2, s);
+ tmp += s;
+ b2 += s;
+ --n2;
+ }
+ }
+ if (n1 > 0)
+ memcpy(tmp, b1, n1 * s);
+ memcpy(b, t, (n - n2) * s);
+}
+
+/*********************************************************************
+ * qsort_s (MSVCRT.@)
+ *
+ * Based on http://github.com/git/git/blob/master/compat/qsort.c
+ *
+ */
+void CDECL MSVCRT_qsort_s(void *b, size_t n, size_t s,
+ _QSORT_S_COMPARE_FN cmp, void *context)
+{
+ const size_t size = n * s;
+ char buf[1024];
+
+ if (!MSVCRT_CHECK_PMT(b != NULL || (b == NULL && n == 0)) || !MSVCRT_CHECK_PMT(s > 0) ||
+ !MSVCRT_CHECK_PMT(cmp != NULL))
+ {
+ *MSVCRT__errno() = MSVCRT_EINVAL;
+ return MSVCRT_EINVAL;
+ }
+
+ if (b == NULL && n == 0) {
+ return;
+ }
+
+ if (size < sizeof(buf))
+ {
+ /* The temporary array fits on the small on-stack buffer. */
+ msort_with_tmp(b, n, s, cmp, context, buf);
+ } else {
+ /* It's somewhat large, so malloc it. */
+ char *tmp = (char *) malloc(size);
+ if (!tmp)
+ {
+ *MSVCRT__errno() = MSVCRT_ENOMEM;
+ return;
+ }
+ msort_with_tmp(b, n, s, cmp, context, tmp);
+ free(tmp);
+ }
+}
+
diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec
index a667ada..8442c02 100644
--- a/dlls/msvcrt/msvcrt.spec
+++ b/dlls/msvcrt/msvcrt.spec
@@ -1344,7 +1344,7 @@
@ cdecl putwc(long ptr) MSVCRT_fputwc
@ cdecl putwchar(long) _fputwchar
@ cdecl qsort(ptr long long ptr) ntdll.qsort
-# stub qsort_s
+@ cdecl qsort_s(ptr long long ptr ptr) MSVCRT_qsort_s
@ cdecl raise(long) MSVCRT_raise
@ cdecl rand() MSVCRT_rand
@ cdecl rand_s(ptr) MSVCRT_rand_s
--
1.7.2.3
More information about the wine-patches
mailing list