Vincas Miliūnas : msvcrt: Added qsort_s implementation .

Alexandre Julliard julliard at winehq.org
Thu Nov 18 11:09:30 CST 2010


Module: wine
Branch: master
Commit: 955e2f90505a6e6e591e447e1dcc4dacab56f6cf
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=955e2f90505a6e6e591e447e1dcc4dacab56f6cf

Author: Vincas Miliūnas <vincas.miliunas at gmail.com>
Date:   Wed Nov 17 18:07:47 2010 +0200

msvcrt: Added qsort_s implementation.

---

 dlls/msvcr100/msvcr100.spec |    2 +-
 dlls/msvcr80/msvcr80.spec   |    2 +-
 dlls/msvcr90/msvcr90.spec   |    2 +-
 dlls/msvcrt/misc.c          |   67 +++++++++++++++++++++++++++++++++++++++++++
 dlls/msvcrt/msvcrt.spec     |    2 +-
 5 files changed, 71 insertions(+), 4 deletions(-)

diff --git a/dlls/msvcr100/msvcr100.spec b/dlls/msvcr100/msvcr100.spec
index 28243de..6e860e8 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 9206b93..17785be 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 ea00630..663e1b7 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..d37fc72 100644
--- a/dlls/msvcrt/misc.c
+++ b/dlls/msvcrt/misc.c
@@ -186,3 +186,70 @@ void CDECL _chkesp(void)
 # endif  /* __GNUC__ */
 
 #endif  /* __i386__ */
+
+/*********************************************************************
+ * Helper function for MSVCRT_qsort_s.
+ *
+ * Based on NTDLL_qsort in dlls/ntdll/misc.c
+ */
+static void MSVCRT_mergesort( void *arr, void *barr, size_t elemsize,
+        int (CDECL *compar)(void *, const void *, const void *),
+        size_t left, size_t right, void *context )
+{
+    if (right>left) {
+        size_t i, j, k, m;
+        m=left+(right-left)/2;
+        MSVCRT_mergesort(arr, barr, elemsize, compar, left, m, context);
+        MSVCRT_mergesort(arr, barr, elemsize, compar, m+1, right, context);
+
+#define X(a,i) ((char*)a+elemsize*(i))
+        for (i=m+1; i>left; i--)
+            memcpy (X(barr,(i-1)),X(arr,(i-1)),elemsize);
+        for (j=m; j<right; j++)
+            memcpy (X(barr,(right+m-j)),X(arr,(j+1)),elemsize);
+
+        /* i=left; j=right; */
+        for (k=left; i<=m && j>m; k++) {
+            if (i==j || compar(context, X(barr,i),X(barr,j))<=0) {
+                memcpy(X(arr,k),X(barr,i),elemsize);
+                i++;
+            } else {
+                memcpy(X(arr,k),X(barr,j),elemsize);
+                j--;
+            }
+        }
+        for (; i<=m; i++, k++)
+            memcpy(X(arr,k),X(barr,i),elemsize);
+        for (; j>m; j--, k++)
+            memcpy(X(arr,k),X(barr,j),elemsize);
+    }
+#undef X
+}
+
+/*********************************************************************
+ * qsort_s (MSVCRT.@)
+ *
+ * Based on NTDLL_qsort in dlls/ntdll/misc.c
+ */
+void CDECL MSVCRT_qsort_s(void *base, MSVCRT_size_t nmemb, MSVCRT_size_t size,
+    int (CDECL *compar)(void *, const void *, const void *), void *context)
+{
+    void *secondarr;
+    const size_t total_size = nmemb*size;
+
+    if (!MSVCRT_CHECK_PMT(base != NULL || (base == NULL && nmemb == 0)) ||
+            !MSVCRT_CHECK_PMT(size > 0) || !MSVCRT_CHECK_PMT(compar != NULL) ||
+            total_size / size != nmemb)
+    {
+        *MSVCRT__errno() = MSVCRT_EINVAL;
+        return;
+    }
+
+    if (nmemb < 2) return;
+
+    secondarr = MSVCRT_malloc(total_size);
+    if (!secondarr)
+        return;
+    MSVCRT_mergesort(base, secondarr, size, compar, 0, nmemb-1, context);
+    MSVCRT_free(secondarr);
+}
diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec
index 63e3b71..3db6fa4 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




More information about the wine-cvs mailing list