mirror of
https://github.com/sheumann/hush.git
synced 2025-03-11 03:31:40 +00:00
Add our own version of qsort, because the one from ORCA/C is recursive and can use thousands of KB of stack space.
The new version is a heap sort implementation adapted from musl libc.
This commit is contained in:
parent
e97a83d054
commit
8cdae3cd7a
3
Makefile
3
Makefile
@ -53,7 +53,8 @@ LIBBB_C_SRC = \
|
||||
libbb/safe.poll.c \
|
||||
libbb/parse.mode.c \
|
||||
libbb/poll.c \
|
||||
libbb/pgrp.c
|
||||
libbb/pgrp.c \
|
||||
libbb/qsort.c
|
||||
|
||||
LIBBB_D_SRC = \
|
||||
libbb/xfuncs.printf.c \
|
||||
|
@ -52,7 +52,8 @@ SRCS = \
|
||||
libbb/vfork.and.run.c \
|
||||
libbb/poll.c \
|
||||
libbb/get.exec.path.c \
|
||||
libbb/pgrp.c
|
||||
libbb/pgrp.c \
|
||||
libbb/qsort.c
|
||||
OBJS = $(SRCS:.c=.o)
|
||||
|
||||
INCLUDES = -I include -I shell -I libbb
|
||||
|
57
libbb/qsort.c
Normal file
57
libbb/qsort.c
Normal file
@ -0,0 +1,57 @@
|
||||
/* We use our own version of qsort because ORCA/C's version is recursive and
|
||||
* can take up quite a bit of stack space (at least several thousand KB).
|
||||
*
|
||||
* This implementation is adapted from (an old version of) musl libc.
|
||||
*
|
||||
* Copyright (c) 2005-2011 Rich Felker
|
||||
* Originally licensed under the GNU LGPL version 2.1 or later.
|
||||
* Licensed under GPLv2 (pursuant to clause 3 of the LGPL version 2.1),
|
||||
* see file LICENSE in this source tree.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* A simple heap sort implementation.. only in-place O(nlogn) sort I know. */
|
||||
|
||||
#define MIN(a, b) ((a)<(b) ? (a) : (b))
|
||||
|
||||
static void swap(char *a, char *b, size_t len)
|
||||
{
|
||||
char tmp;
|
||||
char *a_end = a + len;
|
||||
while (a != a_end) {
|
||||
tmp = *a;
|
||||
*a++ = *b;
|
||||
*b++ = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
static void sift(char *base, size_t root, size_t nel, size_t width, int (*cmp)(const void *, const void *))
|
||||
{
|
||||
size_t max;
|
||||
|
||||
while (2*root <= nel) {
|
||||
max = 2*root;
|
||||
if (max < nel && cmp(base+max*width, base+(max+1)*width) < 0)
|
||||
max++;
|
||||
if (max && cmp(base+root*width, base+max*width) < 0) {
|
||||
swap(base+root*width, base+max*width, width);
|
||||
root = max;
|
||||
} else break;
|
||||
}
|
||||
}
|
||||
|
||||
void qsort(void *_base, size_t nel, size_t width, int (*cmp)(const void *, const void *))
|
||||
{
|
||||
char *base = _base;
|
||||
size_t i;
|
||||
|
||||
if (!nel) return;
|
||||
for (i=(nel+1)/2; i; i--)
|
||||
sift(base, i-1, nel-1, width, cmp);
|
||||
for (i=nel-1; i; i--) {
|
||||
swap(base, base+i*width, width);
|
||||
sift(base, 0, i-1, width, cmp);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user