Chameleon

Chameleon Svn Source Tree

Root/tags/2.0/i386/libsa/qsort.c

Source at commit 1808 created 12 years 3 months ago.
By blackosx, Revise layout of package installer 'Welcome' file so it looks cleaner. Change the copyright notice to begin from 2009 as seen in the Chameleon 2.0 r431 installer. Should this date be set earlier?
1/*
2 * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 2.0 (the "License"). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
20 * under the License.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24/*
25 * Copyright (c) 1992, 1993
26 *The Regents of the University of California. All rights reserved.
27 *
28 * Redistribution and use in source and binary forms, with or without
29 * modification, are permitted provided that the following conditions
30 * are met:
31 * 1. Redistributions of source code must retain the above copyright
32 * notice, this list of conditions and the following disclaimer.
33 * 2. Redistributions in binary form must reproduce the above copyright
34 * notice, this list of conditions and the following disclaimer in the
35 * documentation and/or other materials provided with the distribution.
36 * 3. All advertising materials mentioning features or use of this software
37 * must display the following acknowledgement:
38 *This product includes software developed by the University of
39 *California, Berkeley and its contributors.
40 * 4. Neither the name of the University nor the names of its contributors
41 * may be used to endorse or promote products derived from this software
42 * without specific prior written permission.
43 *
44 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
45 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
46 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
47 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
48 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
49 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
50 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
52 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
53 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
54 * SUCH DAMAGE.
55 */
56
57
58#include <sys/types.h>
59#include <stdlib.h>
60#include <sys/param.h>
61
62static inline char*med3 __P((char *, char *, char *, int (*)()));
63static inline void swapfunc __P((char *, char *, int, int));
64
65/*
66 * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
67 */
68#define swapcode(TYPE, parmi, parmj, n) { \
69long i = (n) / sizeof (TYPE); \
70register TYPE *pi = (TYPE *) (parmi); \
71register TYPE *pj = (TYPE *) (parmj); \
72do { \
73register TYPEt = *pi;\
74*pi++ = *pj;\
75*pj++ = t;\
76 } while (--i > 0);\
77}
78
79#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
80es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
81
82static inline void
83swapfunc(a, b, n, swaptype)
84char *a, *b;
85int n, swaptype;
86{
87if(swaptype <= 1)
88swapcode(long, a, b, n)
89else
90swapcode(char, a, b, n)
91}
92
93#define swap(a, b)\
94if (swaptype == 0) {\
95long t = *(long *)(a);\
96*(long *)(a) = *(long *)(b);\
97*(long *)(b) = t;\
98} else\
99swapfunc(a, b, es, swaptype)
100
101#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype)
102
103static inline char *
104med3(a, b, c, cmp)
105char *a, *b, *c;
106int (*cmp)();
107{
108return cmp(a, b) < 0 ?
109 (cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a ))
110 :(cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c ));
111}
112
113void
114qsort(a, n, es, cmp)
115void *a;
116size_t n, es;
117int (*cmp)();
118{
119char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
120int d, r, swaptype, swap_cnt;
121
122loop:SWAPINIT(a, es);
123swap_cnt = 0;
124if (n < 7) {
125for (pm = a + es; pm < (char *) a + n * es; pm += es)
126for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
127 pl -= es)
128swap(pl, pl - es);
129return;
130}
131pm = a + (n / 2) * es;
132if (n > 7) {
133pl = a;
134pn = a + (n - 1) * es;
135if (n > 40) {
136d = (n / 8) * es;
137pl = med3(pl, pl + d, pl + 2 * d, cmp);
138pm = med3(pm - d, pm, pm + d, cmp);
139pn = med3(pn - 2 * d, pn - d, pn, cmp);
140}
141pm = med3(pl, pm, pn, cmp);
142}
143swap(a, pm);
144pa = pb = a + es;
145
146pc = pd = a + (n - 1) * es;
147for (;;) {
148while (pb <= pc && (r = cmp(pb, a)) <= 0) {
149if (r == 0) {
150swap_cnt = 1;
151swap(pa, pb);
152pa += es;
153}
154pb += es;
155}
156while (pb <= pc && (r = cmp(pc, a)) >= 0) {
157if (r == 0) {
158swap_cnt = 1;
159swap(pc, pd);
160pd -= es;
161}
162pc -= es;
163}
164if (pb > pc)
165break;
166swap(pb, pc);
167swap_cnt = 1;
168pb += es;
169pc -= es;
170}
171if (swap_cnt == 0) { /* Switch to insertion sort */
172for (pm = a + es; pm < (char *) a + n * es; pm += es)
173for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
174 pl -= es)
175swap(pl, pl - es);
176return;
177}
178
179pn = a + n * es;
180r = MIN(pa - (char *)a, pb - pa);
181vecswap(a, pb - r, r);
182r = MIN(pd - pc, (pn - pd) - (int)es);
183vecswap(pb, pn - r, r);
184if ((r = pb - pa) > (int)es)
185qsort(a, r / es, es, cmp);
186if ((r = pd - pc) > (int)es) {
187/* Iterate rather than recurse to save stack space */
188a = pn - r;
189n = r / es;
190goto loop;
191}
192/*qsort(pn - r, r / es, es, cmp);*/
193}
194

Archive Download this file

Revision: 1808