summaryrefslogtreecommitdiffstats
path: root/lib/libc/stdlib/merge.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc/stdlib/merge.c')
-rw-r--r--lib/libc/stdlib/merge.c50
1 files changed, 31 insertions, 19 deletions
diff --git a/lib/libc/stdlib/merge.c b/lib/libc/stdlib/merge.c
index 01a9028..6b368c3 100644
--- a/lib/libc/stdlib/merge.c
+++ b/lib/libc/stdlib/merge.c
@@ -56,10 +56,18 @@ __FBSDID("$FreeBSD$");
#include <stdlib.h>
#include <string.h>
-static void setup(u_char *, u_char *, size_t, size_t,
- int (*)(const void *, const void *));
-static void insertionsort(u_char *, size_t, size_t,
- int (*)(const void *, const void *));
+#ifdef I_AM_MERGESORT_B
+#include "block_abi.h"
+#define DECLARE_CMP DECLARE_BLOCK(int, cmp, const void *, const void *)
+typedef DECLARE_BLOCK(int, cmp_t, const void *, const void *);
+#define CMP(x, y) CALL_BLOCK(cmp, x, y)
+#else
+typedef int (*cmp_t)(const void *, const void *);
+#define CMP(x, y) cmp(x, y)
+#endif
+
+static void setup(u_char *, u_char *, size_t, size_t, cmp_t);
+static void insertionsort(u_char *, size_t, size_t, cmp_t);
#define ISIZE sizeof(int)
#define PSIZE sizeof(u_char *)
@@ -95,11 +103,15 @@ static void insertionsort(u_char *, size_t, size_t,
* Arguments are as for qsort.
*/
int
+#ifdef I_AM_MERGESORT_B
+mergesort_b(base, nmemb, size, cmp)
+#else
mergesort(base, nmemb, size, cmp)
+#endif
void *base;
size_t nmemb;
size_t size;
- int (*cmp)(const void *, const void *);
+ cmp_t cmp;
{
size_t i;
int sense;
@@ -141,7 +153,7 @@ mergesort(base, nmemb, size, cmp)
p2 = *EVAL(p2);
l2 = list1 + (p2 - list2);
while (f1 < l1 && f2 < l2) {
- if ((*cmp)(f1, f2) <= 0) {
+ if (CMP(f1, f2) <= 0) {
q = f2;
b = f1, t = l1;
sense = -1;
@@ -151,7 +163,7 @@ mergesort(base, nmemb, size, cmp)
sense = 0;
}
if (!big) { /* here i = 0 */
- while ((b += size) < t && cmp(q, b) >sense)
+ while ((b += size) < t && CMP(q, b) >sense)
if (++i == 6) {
big = 1;
goto EXPONENTIAL;
@@ -160,12 +172,12 @@ mergesort(base, nmemb, size, cmp)
EXPONENTIAL: for (i = size; ; i <<= 1)
if ((p = (b + i)) >= t) {
if ((p = t - size) > b &&
- (*cmp)(q, p) <= sense)
+ CMP(q, p) <= sense)
t = p;
else
b = p;
break;
- } else if ((*cmp)(q, p) <= sense) {
+ } else if (CMP(q, p) <= sense) {
t = p;
if (i == size)
big = 0;
@@ -174,14 +186,14 @@ EXPONENTIAL: for (i = size; ; i <<= 1)
b = p;
while (t > b+size) {
i = (((t - b) / size) >> 1) * size;
- if ((*cmp)(q, p = b + i) <= sense)
+ if (CMP(q, p = b + i) <= sense)
t = p;
else
b = p;
}
goto COPY;
FASTCASE: while (i > size)
- if ((*cmp)(q,
+ if (CMP(q,
p = b + (i >>= 1)) <= sense)
t = p;
else
@@ -261,8 +273,8 @@ COPY: b = t;
void
setup(list1, list2, n, size, cmp)
size_t n, size;
- int (*cmp)(const void *, const void *);
u_char *list1, *list2;
+ cmp_t cmp;
{
int i, length, size2, tmp, sense;
u_char *f1, *f2, *s, *l2, *last, *p2;
@@ -285,12 +297,12 @@ setup(list1, list2, n, size, cmp)
#ifdef NATURAL
p2 = list2;
f1 = list1;
- sense = (cmp(f1, f1 + size) > 0);
+ sense = (CMP(f1, f1 + size) > 0);
for (; f1 < last; sense = !sense) {
length = 2;
/* Find pairs with same sense. */
for (f2 = f1 + size2; f2 < last; f2 += size2) {
- if ((cmp(f2, f2+ size) > 0) != sense)
+ if ((CMP(f2, f2+ size) > 0) != sense)
break;
length += 2;
}
@@ -303,7 +315,7 @@ setup(list1, list2, n, size, cmp)
} else { /* Natural merge */
l2 = f2;
for (f2 = f1 + size2; f2 < l2; f2 += size2) {
- if ((cmp(f2-size, f2) > 0) != sense) {
+ if ((CMP(f2-size, f2) > 0) != sense) {
p2 = *EVAL(p2) = f2 - list1 + list2;
if (sense > 0)
reverse(f1, f2-size);
@@ -313,7 +325,7 @@ setup(list1, list2, n, size, cmp)
if (sense > 0)
reverse (f1, f2-size);
f1 = f2;
- if (f2 < last || cmp(f2 - size, f2) > 0)
+ if (f2 < last || CMP(f2 - size, f2) > 0)
p2 = *EVAL(p2) = f2 - list1 + list2;
else
p2 = *EVAL(p2) = list2 + n*size;
@@ -322,7 +334,7 @@ setup(list1, list2, n, size, cmp)
#else /* pairwise merge only. */
for (f1 = list1, p2 = list2; f1 < last; f1 += size2) {
p2 = *EVAL(p2) = p2 + size2;
- if (cmp (f1, f1 + size) > 0)
+ if (CMP (f1, f1 + size) > 0)
swap(f1, f1 + size);
}
#endif /* NATURAL */
@@ -336,7 +348,7 @@ static void
insertionsort(a, n, size, cmp)
u_char *a;
size_t n, size;
- int (*cmp)(const void *, const void *);
+ cmp_t cmp;
{
u_char *ai, *s, *t, *u, tmp;
int i;
@@ -344,7 +356,7 @@ insertionsort(a, n, size, cmp)
for (ai = a+size; --n >= 1; ai += size)
for (t = ai; t > a; t -= size) {
u = t - size;
- if (cmp(u, t) <= 0)
+ if (CMP(u, t) <= 0)
break;
swap(u, t);
}
OpenPOWER on IntegriCloud