]>
git.saurik.com Git - apple/libc.git/blob - stdlib/FreeBSD/qsort.c
   2  * Copyright (c) 1992, 1993 
   3  *      The Regents of the University of California.  All rights reserved. 
   5  * Redistribution and use in source and binary forms, with or without 
   6  * modification, are permitted provided that the following conditions 
   8  * 1. Redistributions of source code must retain the above copyright 
   9  *    notice, this list of conditions and the following disclaimer. 
  10  * 2. Redistributions in binary form must reproduce the above copyright 
  11  *    notice, this list of conditions and the following disclaimer in the 
  12  *    documentation and/or other materials provided with the distribution. 
  13  * 3. All advertising materials mentioning features or use of this software 
  14  *    must display the following acknowledgement: 
  15  *      This product includes software developed by the University of 
  16  *      California, Berkeley and its contributors. 
  17  * 4. Neither the name of the University nor the names of its contributors 
  18  *    may be used to endorse or promote products derived from this software 
  19  *    without specific prior written permission. 
  21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 
  22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
  23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
  24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 
  25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
  26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
  27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
  28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
  29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
  30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
  34 #if defined(LIBC_SCCS) && !defined(lint) 
  35 static char sccsid
[] = "@(#)qsort.c     8.1 (Berkeley) 6/4/93"; 
  36 #endif /* LIBC_SCCS and not lint */ 
  37 #include <sys/cdefs.h> 
  38 __FBSDID("$FreeBSD: src/lib/libc/stdlib/qsort.c,v 1.12 2002/09/10 02:04:49 wollman Exp $"); 
  43 typedef int              cmp_t(void *, const void *, const void *); 
  45 typedef int              cmp_t(const void *, const void *); 
  47 static inline char      *med3(char *, char *, char *, cmp_t 
*, void *); 
  48 static inline void       swapfunc(char *, char *, int, int); 
  50 #define min(a, b)       (a) < (b) ? a : b 
  53  * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function". 
  55 #define swapcode(TYPE, parmi, parmj, n) {               \ 
  56         long i = (n) / sizeof (TYPE);                   \ 
  57         TYPE *pi = (TYPE *) (parmi);            \ 
  58         TYPE *pj = (TYPE *) (parmj);            \ 
  66 #define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \ 
  67         es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1; 
  70 swapfunc(a
, b
, n
, swaptype
) 
  75                 swapcode(long, a
, b
, n
) 
  77                 swapcode(char, a
, b
, n
) 
  81         if (swaptype == 0) {                            \ 
  82                 long t = *(long *)(a);                  \ 
  83                 *(long *)(a) = *(long *)(b);            \ 
  86                 swapfunc(a, b, es, swaptype) 
  88 #define vecswap(a, b, n)        if ((n) > 0) swapfunc(a, b, n, swaptype) 
  91 #define CMP(t, x, y) (cmp((t), (x), (y))) 
  93 #define CMP(t, x, y) (cmp((x), (y))) 
  97 med3(char *a
, char *b
, char *c
, cmp_t 
*cmp
, void *thunk
 
 103         return CMP(thunk
, a
, b
) < 0 ? 
 104                (CMP(thunk
, b
, c
) < 0 ? b 
: (CMP(thunk
, a
, c
) < 0 ? c 
: a 
)) 
 105               :(CMP(thunk
, b
, c
) > 0 ? b 
: (CMP(thunk
, a
, c
) < 0 ? a 
: c 
)); 
 110 qsort_r(void *a
, size_t n
, size_t es
, void *thunk
, cmp_t 
*cmp
) 
 114 qsort(void *a
, size_t n
, size_t es
, cmp_t 
*cmp
) 
 117         char *pa
, *pb
, *pc
, *pd
, *pl
, *pm
, *pn
; 
 118         int d
, r
, swaptype
, swap_cnt
; 
 120 loop
:   SWAPINIT(a
, es
); 
 123                 for (pm 
= (char *)a 
+ es
; pm 
< (char *)a 
+ n 
* es
; pm 
+= es
) 
 125                              pl 
> (char *)a 
&& CMP(thunk
, pl 
- es
, pl
) > 0; 
 130         pm 
= (char *)a 
+ (n 
/ 2) * es
; 
 133                 pn 
= (char *)a 
+ (n 
- 1) * es
; 
 136                         pl 
= med3(pl
, pl 
+ d
, pl 
+ 2 * d
, cmp
, thunk
); 
 137                         pm 
= med3(pm 
- d
, pm
, pm 
+ d
, cmp
, thunk
); 
 138                         pn 
= med3(pn 
- 2 * d
, pn 
- d
, pn
, cmp
, thunk
); 
 140                 pm 
= med3(pl
, pm
, pn
, cmp
, thunk
); 
 143         pa 
= pb 
= (char *)a 
+ es
; 
 145         pc 
= pd 
= (char *)a 
+ (n 
- 1) * es
; 
 147                 while (pb 
<= pc 
&& (r 
= CMP(thunk
, pb
, a
)) <= 0) { 
 155                 while (pb 
<= pc 
&& (r 
= CMP(thunk
, pc
, a
)) >= 0) { 
 170         if (swap_cnt 
== 0) {  /* Switch to insertion sort */ 
 171                 for (pm 
= (char *)a 
+ es
; pm 
< (char *)a 
+ n 
* es
; pm 
+= es
) 
 173                              pl 
> (char *)a 
&& CMP(thunk
, pl 
- es
, pl
) > 0; 
 179         pn 
= (char *)a 
+ n 
* es
; 
 180         r 
= min(pa 
- (char *)a
, pb 
- pa
); 
 181         vecswap(a
, pb 
- r
, r
); 
 182         r 
= min(pd 
- pc
, pn 
- pd 
- es
); 
 183         vecswap(pb
, pn 
- r
, r
); 
 184         if ((r 
= pb 
- pa
) > es
) 
 186                 qsort_r(a
, r 
/ es
, es
, thunk
, cmp
); 
 188                 qsort(a
, r 
/ es
, es
, cmp
); 
 190         if ((r 
= pd 
- pc
) > es
) { 
 191                 /* Iterate rather than recurse to save stack space */ 
 196 /*              qsort(pn - r, r / es, es, cmp);*/