[2/6] msvcr80: qsort_s implementation
Vincas Miliūnas
vincas.miliunas at gmail.com
Tue Nov 2 19:06:33 CDT 2010
qsort_s and _itow_s implementation and tests for bug #24925.
---
dlls/msvcr80/msvcr80.c | 76
+++++++++++++++++++++++++++++++++++++++++++++
dlls/msvcr80/msvcr80.spec | 2 +-
2 files changed, 77 insertions(+), 1 deletions(-)
diff --git a/dlls/msvcr80/msvcr80.c b/dlls/msvcr80/msvcr80.c
index 8487c15..ab48440 100644
--- a/dlls/msvcr80/msvcr80.c
+++ b/dlls/msvcr80/msvcr80.c
@@ -29,6 +29,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(msvcr80);
+typedef int (CDECL *_QSORT_S_COMPARE_FN)(void *, const void *, const
void *);
+
/*********************************************************************
* DllMain (MSVCR80.@)
*/
@@ -44,3 +46,77 @@ BOOL WINAPI DllMain(HINSTANCE hdll, DWORD reason,
LPVOID reserved)
}
return TRUE;
}
+
+/*********************************************************************
+ * Helper function for MSVCR80_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 (MSVCR80.@)
+ *
+ * Based on http://github.com/git/git/blob/master/compat/qsort.c
+ *
+ */
+void CDECL MSVCR80_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 (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)
+ {
+ *_errno() = ENOMEM;
+ return;
+ }
+ msort_with_tmp(b, n, s, cmp, context, tmp);
+ free(tmp);
+ }
+}
+
diff --git a/dlls/msvcr80/msvcr80.spec b/dlls/msvcr80/msvcr80.spec
index 5f0198c..0407886 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) MSVCR80_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