[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