From: "Vincas Miliƫnas" Subject: [2/6] msvcr80: qsort_s implementation (try 2) Message-Id: <4CD14C33.4040107@gmail.com> Date: Wed, 03 Nov 2010 13:49:07 +0200 qsort_s and _itow_s implementation and tests for bug #24925. Because of Thunderbird's default text formatting, the patch got broken; a good resource on solving this is http://kerneltrap.org/Linux/Email_Clients_and_Patches --- 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