annotate lib-src/qsort.c @ 5887:6eca500211f4

Prototype for X509_check_host() has changed, detect this in configure.ac ChangeLog addition: 2015-04-09 Aidan Kehoe <kehoea@parhasard.net> * configure.ac: If X509_check_host() is available, check the number of arguments it takes. Don't use it if it takes any number of arguments other than five. Also don't use it if <openssl/x509v3.h> does not declare it, since if that is so there is no portable way to tell how many arguments it should take, and so we would end up smashing the stack. * configure: Regenerate. src/ChangeLog addition: 2015-04-09 Aidan Kehoe <kehoea@parhasard.net> * tls.c: #include <openssl/x509v3.h> for its prototype for X509_check_host(). * tls.c (tls_open): Pass the new fifth argument to X509_check_host().
author Aidan Kehoe <kehoea@parhasard.net>
date Thu, 09 Apr 2015 14:27:02 +0100
parents 061f4f90f874
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1 /* Plug-compatible replacement for UNIX qsort.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
2 Copyright (C) 1989 Free Software Foundation, Inc.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
3 Written by Douglas C. Schmidt (schmidt@ics.uci.edu)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
4
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
5 This file is part of GNU CC.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
6
5406
061f4f90f874 Convert lib-src/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents: 444
diff changeset
7 GNU QSORT is free software: you can redistribute it and/or modify it
061f4f90f874 Convert lib-src/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents: 444
diff changeset
8 under the terms of the GNU General Public License as published by the
061f4f90f874 Convert lib-src/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents: 444
diff changeset
9 Free Software Foundation, either version 3 of the License, or (at your
061f4f90f874 Convert lib-src/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents: 444
diff changeset
10 option) any later version.
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
11
5406
061f4f90f874 Convert lib-src/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents: 444
diff changeset
12 GNU QSORT is distributed in the hope that it will be useful, but WITHOUT
061f4f90f874 Convert lib-src/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents: 444
diff changeset
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
061f4f90f874 Convert lib-src/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents: 444
diff changeset
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
061f4f90f874 Convert lib-src/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents: 444
diff changeset
15 for more details.
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
16
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
17 You should have received a copy of the GNU General Public License
5406
061f4f90f874 Convert lib-src/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents: 444
diff changeset
18 along with GNU QSORT. If not, see <http://www.gnu.org/licenses/>. */
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
19
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
20 /* Synched up with: FSF 19.28. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
21
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
22 #ifdef sparc
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
23 #include <alloca.h>
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
24 #endif
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
25
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
26 /* Invoke the comparison function, returns either 0, < 0, or > 0. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
27 #define CMP(A,B) ((*cmp)((A),(B)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
28
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
29 /* Byte-wise swap two items of size SIZE. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
30 #define SWAP(A,B,SIZE) do {int sz = (SIZE); char *a = (A); char *b = (B); \
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
31 do { char _temp = *a;*a++ = *b;*b++ = _temp;} while (--sz);} while (0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
32
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
33 /* Copy SIZE bytes from item B to item A. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
34 #define COPY(A,B,SIZE) {int sz = (SIZE); do { *(A)++ = *(B)++; } while (--sz); }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
35
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
36 /* This should be replaced by a standard ANSI macro. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
37 #define BYTES_PER_WORD 8
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
38
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
39 /* The next 4 #defines implement a very fast in-line stack abstraction. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
40 #define STACK_SIZE (BYTES_PER_WORD * sizeof (long))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
41 #define PUSH(LOW,HIGH) do {top->lo = LOW;top++->hi = HIGH;} while (0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
42 #define POP(LOW,HIGH) do {LOW = (--top)->lo;HIGH = top->hi;} while (0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
43 #define STACK_NOT_EMPTY (stack < top)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
44
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
45 /* Discontinue quicksort algorithm when partition gets below this size.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
46 This particular magic number was chosen to work best on a Sun 4/260. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
47 #define MAX_THRESH 4
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
48
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
49 /* Stack node declarations used to store unfulfilled partition obligations. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
50 typedef struct
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
51 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
52 char *lo;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
53 char *hi;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
54 } stack_node;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
55
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
56 /* Order size using quicksort. This implementation incorporates
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
57 four optimizations discussed in Sedgewick:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
58
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
59 1. Non-recursive, using an explicit stack of pointer that store the
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
60 next array partition to sort. To save time, this maximum amount
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
61 of space required to store an array of MAX_INT is allocated on the
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
62 stack. Assuming a 32-bit integer, this needs only 32 *
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
63 sizeof (stack_node) == 136 bits. Pretty cheap, actually.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
64
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 0
diff changeset
65 2. Choose the pivot element using a median-of-three decision tree.
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
66 This reduces the probability of selecting a bad pivot value and
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
67 eliminates certain extraneous comparisons.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
68
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
69 3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
70 insertion sort to order the MAX_THRESH items within each partition.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
71 This is a big win, since insertion sort is faster for small, mostly
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
72 sorted array segments.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
73
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
74 4. The larger of the two sub-partitions is always pushed onto the
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
75 stack first, with the algorithm then concentrating on the
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
76 smaller partition. This *guarantees* no more than log (n)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
77 stack size is needed (actually O(1) in this case)! */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
78
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
79 int
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
80 qsort (base_ptr, total_elems, size, cmp)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
81 char *base_ptr;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
82 int total_elems;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
83 int size;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
84 int (*cmp)();
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
85 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
86 /* Allocating SIZE bytes for a pivot buffer facilitates a better
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
87 algorithm below since we can do comparisons directly on the pivot. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
88 char *pivot_buffer = (char *) alloca (size);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
89 int max_thresh = MAX_THRESH * size;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
90
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
91 if (total_elems > MAX_THRESH)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
92 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
93 char *lo = base_ptr;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
94 char *hi = lo + size * (total_elems - 1);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
95 stack_node stack[STACK_SIZE]; /* Largest size needed for 32-bit int!!! */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
96 stack_node *top = stack + 1;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
97
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
98 while (STACK_NOT_EMPTY)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
99 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
100 char *left_ptr;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
101 char *right_ptr;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
102 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
103 char *pivot = pivot_buffer;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
104 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
105 /* Select median value from among LO, MID, and HI. Rearrange
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
106 LO and HI so the three values are sorted. This lowers the
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
107 probability of picking a pathological pivot value and
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
108 skips a comparison for both the LEFT_PTR and RIGHT_PTR. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
109
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
110 char *mid = lo + size * ((hi - lo) / size >> 1);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
111
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
112 if (CMP (mid, lo) < 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
113 SWAP (mid, lo, size);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
114 if (CMP (hi, mid) < 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
115 SWAP (mid, hi, size);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
116 else
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
117 goto jump_over;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
118 if (CMP (mid, lo) < 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
119 SWAP (mid, lo, size);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
120 jump_over:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
121 COPY (pivot, mid, size);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
122 pivot = pivot_buffer;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
123 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
124 left_ptr = lo + size;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
125 right_ptr = hi - size;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
126
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
127 /* Here's the famous ``collapse the walls'' section of quicksort.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
128 Gotta like those tight inner loops! They are the main reason
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
129 that this algorithm runs much faster than others. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
130 do
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
131 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
132 while (CMP (left_ptr, pivot) < 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
133 left_ptr += size;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
134
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
135 while (CMP (pivot, right_ptr) < 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
136 right_ptr -= size;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
137
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
138 if (left_ptr < right_ptr)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
139 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
140 SWAP (left_ptr, right_ptr, size);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
141 left_ptr += size;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
142 right_ptr -= size;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
143 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
144 else if (left_ptr == right_ptr)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
145 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
146 left_ptr += size;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
147 right_ptr -= size;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
148 break;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
149 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
150 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
151 while (left_ptr <= right_ptr);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
152
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
153 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
154
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
155 /* Set up pointers for next iteration. First determine whether
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
156 left and right partitions are below the threshold size. If so,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
157 ignore one or both. Otherwise, push the larger partition's
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
158 bounds on the stack and continue sorting the smaller one. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
159
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
160 if ((right_ptr - lo) <= max_thresh)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
161 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
162 if ((hi - left_ptr) <= max_thresh) /* Ignore both small partitions. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
163 POP (lo, hi);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
164 else /* Ignore small left partition. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
165 lo = left_ptr;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
166 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
167 else if ((hi - left_ptr) <= max_thresh) /* Ignore small right partition. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
168 hi = right_ptr;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
169 else if ((right_ptr - lo) > (hi - left_ptr)) /* Push larger left partition indices. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
170 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
171 PUSH (lo, right_ptr);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
172 lo = left_ptr;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
173 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
174 else /* Push larger right partition indices. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
175 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
176 PUSH (left_ptr, hi);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
177 hi = right_ptr;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
178 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
179 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
180 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
181
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
182 /* Once the BASE_PTR array is partially sorted by quicksort the rest
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
183 is completely sorted using insertion sort, since this is efficient
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
184 for partitions below MAX_THRESH size. BASE_PTR points to the beginning
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
185 of the array to sort, and END_PTR points at the very last element in
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
186 the array (*not* one beyond it!). */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
187
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
188 #define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
189
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
190 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
191 char *end_ptr = base_ptr + size * (total_elems - 1);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
192 char *run_ptr;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
193 char *tmp_ptr = base_ptr;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
194 char *thresh = MIN (end_ptr, base_ptr + max_thresh);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
195
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
196 /* Find smallest element in first threshold and place it at the
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
197 array's beginning. This is the smallest array element,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
198 and the operation speeds up insertion sort's inner loop. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
199
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
200 for (run_ptr = tmp_ptr + size; run_ptr <= thresh; run_ptr += size)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
201 if (CMP (run_ptr, tmp_ptr) < 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
202 tmp_ptr = run_ptr;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
203
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
204 if (tmp_ptr != base_ptr)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
205 SWAP (tmp_ptr, base_ptr, size);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
206
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
207 /* Insertion sort, running from left-hand-side up to `right-hand-side.'
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
208 Pretty much straight out of the original GNU qsort routine. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
209
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
210 for (run_ptr = base_ptr + size; (tmp_ptr = run_ptr += size) <= end_ptr; )
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
211 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
212
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
213 while (CMP (run_ptr, tmp_ptr -= size) < 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
214 ;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
215
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
216 if ((tmp_ptr += size) != run_ptr)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
217 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
218 char *trav;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
219
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
220 for (trav = run_ptr + size; --trav >= run_ptr;)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
221 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
222 char c = *trav;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
223 char *hi, *lo;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
224
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
225 for (hi = lo = trav; (lo -= size) >= tmp_ptr; hi = lo)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
226 *hi = *lo;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
227 *hi = c;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
228 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
229 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
230
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
231 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
232 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
233 return 1;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
234 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
235