libc: Add qsort (with a test!!)
This commit is contained in:
parent
44815b08c7
commit
1025248cc7
@ -113,7 +113,8 @@ extern "C"
|
||||
/* Runs a shell command. */
|
||||
int system(const char* command);
|
||||
|
||||
void qsort(void*, size_t, size_t, int (*)(const void*, const void*)); // Not implemented.
|
||||
/* Sorts the array pointed to by base of nmemb items of the specified size using the comparison function compar. */
|
||||
void qsort(void* base, size_t nmemb, size_t size, int (*compar)(const void*, const void*));
|
||||
|
||||
void* bsearch(const void*, const void*, size_t, size_t, int (*)(const void*, const void*)); // Not implemented.
|
||||
|
||||
|
@ -77,6 +77,51 @@ template <typename Arg, typename Struct> static inline Struct common_div(Arg a,
|
||||
return result;
|
||||
}
|
||||
|
||||
static void qswap(void* ptr1, void* ptr2, size_t size)
|
||||
{
|
||||
char* x = (char*)ptr1;
|
||||
char* y = (char*)ptr2;
|
||||
|
||||
while (size--)
|
||||
{
|
||||
char t = *x;
|
||||
*x = *y;
|
||||
*y = t;
|
||||
x += 1;
|
||||
y += 1;
|
||||
}
|
||||
}
|
||||
|
||||
static size_t partition(void* base, size_t start, size_t end, size_t size, int (*compar)(const void*, const void*))
|
||||
{
|
||||
auto atindex = [&base, &size](size_t index) { return (void*)((char*)base + (index * size)); };
|
||||
|
||||
void* pivot = atindex(end);
|
||||
size_t i = (start - 1);
|
||||
|
||||
for (size_t j = start; j <= end - 1; j++)
|
||||
{
|
||||
if (compar(atindex(j), pivot) < 0)
|
||||
{
|
||||
i++;
|
||||
qswap(atindex(i), atindex(j), size);
|
||||
}
|
||||
}
|
||||
|
||||
qswap(atindex(i + 1), pivot, size);
|
||||
return i + 1;
|
||||
}
|
||||
|
||||
static void quicksort(void* base, size_t start, size_t end, size_t size, int (*compar)(const void*, const void*))
|
||||
{
|
||||
if (start < end)
|
||||
{
|
||||
size_t pivot = partition(base, start, end, size, compar);
|
||||
quicksort(base, start, pivot - 1, size, compar);
|
||||
quicksort(base, pivot + 1, end, size, compar);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
__lc_noreturn void abort()
|
||||
@ -175,9 +220,9 @@ extern "C"
|
||||
return status;
|
||||
}
|
||||
|
||||
void qsort(void*, size_t, size_t, int (*)(const void*, const void*))
|
||||
void qsort(void* base, size_t nmemb, size_t size, int (*compar)(const void*, const void*))
|
||||
{
|
||||
NOT_IMPLEMENTED("qsort");
|
||||
quicksort(base, 0, nmemb - 1, size, compar);
|
||||
}
|
||||
|
||||
void* bsearch(const void*, const void*, size_t, size_t, int (*)(const void*, const void*))
|
||||
|
@ -25,6 +25,7 @@ DEFINE_TEST(srand);
|
||||
DEFINE_TEST(malloc);
|
||||
DEFINE_TEST(calloc);
|
||||
DEFINE_TEST(mktemp);
|
||||
DEFINE_TEST(qsort);
|
||||
|
||||
int main()
|
||||
{
|
||||
@ -53,4 +54,5 @@ int main()
|
||||
RUN_TEST(malloc);
|
||||
RUN_TEST(calloc);
|
||||
RUN_TEST(mktemp);
|
||||
RUN_TEST(qsort);
|
||||
}
|
@ -155,12 +155,55 @@ DEFINE_TEST(mktemp)
|
||||
|
||||
int rc = access(ptr, F_OK);
|
||||
|
||||
EXPECT_NOT_EQ(rc, 0); // FIXME: This could actually happen, since that's why mktemp is deprecated.
|
||||
EXPECT_NOT_EQ(rc, 0); // FIXME: This could actually happen, since that's why mktemp is deprecated.
|
||||
// Another process could create the file between generating the name and actually using it.
|
||||
|
||||
rc = strcmp(ptr, template2);
|
||||
|
||||
EXPECT_NOT_EQ(rc, 0);
|
||||
|
||||
TEST_SUCCESS();
|
||||
}
|
||||
|
||||
static int compare_char(const void* p1, const void* p2)
|
||||
{
|
||||
const char* c1 = (const char*)p1;
|
||||
const char* c2 = (const char*)p2;
|
||||
if (*c1 < *c2) return -1;
|
||||
if (*c1 > *c2) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int compare_int(const void* p1, const void* p2)
|
||||
{
|
||||
const int* c1 = (const int*)p1;
|
||||
const int* c2 = (const int*)p2;
|
||||
if (*c1 < *c2) return -1;
|
||||
if (*c1 > *c2) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_TEST(qsort)
|
||||
{
|
||||
START_TEST(qsort);
|
||||
|
||||
char unsorted[] = "elacbkdjf";
|
||||
const char sorted[] = "abcdefjkl";
|
||||
|
||||
qsort(unsorted, 9, sizeof(char), compare_char);
|
||||
|
||||
int rc = memcmp(sorted, unsorted, 9);
|
||||
|
||||
EXPECT_EQ(rc, 0);
|
||||
|
||||
int unsorted2[] = {1500, 45, 3, 11, 41, 90, 6, 32, 5, 76};
|
||||
const int sorted2[] = {3, 5, 6, 11, 32, 41, 45, 76, 90, 1500};
|
||||
|
||||
qsort(unsorted2, 10, sizeof(int), compare_int);
|
||||
|
||||
rc = memcmp(unsorted2, sorted2, 10);
|
||||
|
||||
EXPECT_EQ(rc, 0);
|
||||
|
||||
TEST_SUCCESS();
|
||||
}
|
Loading…
Reference in New Issue
Block a user