Revision | 849cfab1c54b56687b4343e5a8448ff7408493b9 (tree) |
---|---|
Time | 2001-01-17 13:47:48 |
Author | Manuel Novoa III <mjn3@code...> |
Commiter | Manuel Novoa III |
UnDOSified file and added assert when debugging.
@@ -1,72 +1,71 @@ | ||
1 | -/* +++Date last modified: 05-Jul-1997 */ | |
2 | - | |
3 | -/* | |
4 | -** ssort() -- Fast, small, qsort()-compatible Shell sort | |
5 | -** | |
6 | -** by Ray Gardner, public domain 5/90 | |
7 | -*/ | |
8 | - | |
9 | -/* | |
10 | - * Manuel Novoa III Dec 2000 | |
11 | - * | |
12 | - * There were several problems with the qsort code contained in uClibc. | |
13 | - * It assumed sizeof(int) was 2 and sizeof(long) was 4. It then had three | |
14 | - * seperate quiicksort routines based on the width of the data passed: 2, 4, | |
15 | - * or anything else <= 128. If the width was > 128, it returned -1 (although | |
16 | - * qsort should not return a value) and did no sorting. On i386 with | |
17 | - * -Os -fomit-frame-pointer -ffunction-sections, the text segment of qsort.o | |
18 | - * was 1358 bytes, with an additional 4 bytes in bss. | |
19 | - * | |
20 | - * I decided to completely replace the existing code with a small | |
21 | - * implementation of a shell sort. It is a drop-in replacement for the | |
22 | - * standard qsort and, with the same gcc flags as above, the text segment | |
23 | - * size on i386 is only 183 bytes. | |
24 | - * | |
25 | - * Grabbed original file rg_ssort.c from snippets.org. | |
26 | - * Modified original code to avoid possible overflow in wgap calculation. | |
27 | - * Modified wgap calculation in loop and eliminated variables gap and wnel. | |
28 | - */ | |
29 | - | |
30 | - | |
31 | -#include <stdlib.h> | |
32 | - | |
33 | -void qsort (void *base, | |
34 | - size_t nel, | |
35 | - size_t width, | |
36 | - int (*comp)(const void *, const void *)) | |
37 | -{ | |
38 | - size_t wgap, i, j, k; | |
39 | - char *a, *b, tmp; | |
40 | - | |
41 | -#if 0 | |
42 | - /* Note: still conceivable that nel * width could overflow! */ | |
43 | - assert(width > 0); | |
44 | -#endif | |
45 | - | |
46 | - if (nel > 1) { | |
47 | - for (wgap = 0; ++wgap < (nel-1)/3 ; wgap *= 3) {} | |
48 | - wgap *= width; | |
49 | - nel *= width; /* convert nel to 'wnel' */ | |
50 | - do { | |
51 | - for (i = wgap; i < nel; i += width) { | |
52 | - for (j = i - wgap; ;j -= wgap) { | |
53 | - a = j + ((char *)base); | |
54 | - b = a + wgap; | |
55 | - if ( (*comp)(a, b) <= 0 ) { | |
56 | - break; | |
57 | - } | |
58 | - k = width; | |
59 | - do { | |
60 | - tmp = *a; | |
61 | - *a++ = *b; | |
62 | - *b++ = tmp; | |
63 | - } while ( --k ); | |
64 | - if (j < wgap) { | |
65 | - break; | |
66 | - } | |
67 | - } | |
68 | - } | |
69 | - wgap = (wgap - width)/3; | |
70 | - } while (wgap); | |
71 | - } | |
72 | -} | |
1 | +/* +++Date last modified: 05-Jul-1997 */ | |
2 | + | |
3 | +/* | |
4 | +** ssort() -- Fast, small, qsort()-compatible Shell sort | |
5 | +** | |
6 | +** by Ray Gardner, public domain 5/90 | |
7 | +*/ | |
8 | + | |
9 | +/* | |
10 | + * Manuel Novoa III Dec 2000 | |
11 | + * | |
12 | + * There were several problems with the qsort code contained in uClibc. | |
13 | + * It assumed sizeof(int) was 2 and sizeof(long) was 4. It then had three | |
14 | + * seperate quiicksort routines based on the width of the data passed: 2, 4, | |
15 | + * or anything else <= 128. If the width was > 128, it returned -1 (although | |
16 | + * qsort should not return a value) and did no sorting. On i386 with | |
17 | + * -Os -fomit-frame-pointer -ffunction-sections, the text segment of qsort.o | |
18 | + * was 1358 bytes, with an additional 4 bytes in bss. | |
19 | + * | |
20 | + * I decided to completely replace the existing code with a small | |
21 | + * implementation of a shell sort. It is a drop-in replacement for the | |
22 | + * standard qsort and, with the same gcc flags as above, the text segment | |
23 | + * size on i386 is only 183 bytes. | |
24 | + * | |
25 | + * Grabbed original file rg_ssort.c from snippets.org. | |
26 | + * Modified original code to avoid possible overflow in wgap calculation. | |
27 | + * Modified wgap calculation in loop and eliminated variables gap and wnel. | |
28 | + */ | |
29 | + | |
30 | + | |
31 | +#include <stdlib.h> | |
32 | +#include <assert.h> | |
33 | + | |
34 | +void qsort (void *base, | |
35 | + size_t nel, | |
36 | + size_t width, | |
37 | + int (*comp)(const void *, const void *)) | |
38 | +{ | |
39 | + size_t wgap, i, j, k; | |
40 | + char *a, *b, tmp; | |
41 | + | |
42 | + /* Note: still conceivable that nel * width could overflow! */ | |
43 | + assert(width > 0); | |
44 | + | |
45 | + if (nel > 1) { | |
46 | + for (wgap = 0; ++wgap < (nel-1)/3 ; wgap *= 3) {} | |
47 | + wgap *= width; | |
48 | + nel *= width; /* convert nel to 'wnel' */ | |
49 | + do { | |
50 | + for (i = wgap; i < nel; i += width) { | |
51 | + for (j = i - wgap; ;j -= wgap) { | |
52 | + a = j + ((char *)base); | |
53 | + b = a + wgap; | |
54 | + if ( (*comp)(a, b) <= 0 ) { | |
55 | + break; | |
56 | + } | |
57 | + k = width; | |
58 | + do { | |
59 | + tmp = *a; | |
60 | + *a++ = *b; | |
61 | + *b++ = tmp; | |
62 | + } while ( --k ); | |
63 | + if (j < wgap) { | |
64 | + break; | |
65 | + } | |
66 | + } | |
67 | + } | |
68 | + wgap = (wgap - width)/3; | |
69 | + } while (wgap); | |
70 | + } | |
71 | +} |