| 95 | const void *cmp_argument) |
| 96 | #else |
| 97 | qsort_t my_qsort(void *base_ptr, size_t count, size_t size, qsort_cmp cmp) |
| 98 | #endif |
| 99 | { |
| 100 | char *low, *high, *pivot; |
| 101 | stack_node stack[STACK_SIZE], *stack_ptr; |
| 102 | my_bool ptr_cmp; |
| 103 | /* Handle the simple case first */ |
| 104 | /* This will also make the rest of the code simpler */ |
| 105 | if (count <= 1) |
| 106 | SORT_RETURN; |
| 107 | |
| 108 | low = (char*) base_ptr; |
| 109 | high = low+ size * (count - 1); |
| 110 | stack_ptr = stack + 1; |
| 111 | #ifdef HAVE_purify |
| 112 | /* The first element in the stack will be accessed for the last POP */ |
| 113 | stack[0].low=stack[0].high=0; |
| 114 | #endif |
| 115 | pivot = (char *) my_alloca((int) size); |
| 116 | ptr_cmp= size == sizeof(char*) && !((low - (char*) 0)& (sizeof(char*)-1)); |
| 117 | |
| 118 | /* The following loop sorts elements between high and low */ |
| 119 | do |
| 120 | { |
| 121 | char *low_ptr, *high_ptr, *mid; |
| 122 | |
| 123 | count=((size_t) (high - low) / size)+1; |
| 124 | /* If count is small, then an insert sort is faster than qsort */ |
| 125 | if (count < THRESHOLD_FOR_INSERT_SORT) |
| 126 | { |
| 127 | for (low_ptr = low + size; low_ptr <= high; low_ptr += size) |
| 128 | { |
| 129 | char *ptr; |
| 130 | for (ptr = low_ptr; ptr > low && CMP(ptr - size, ptr) > 0; |
| 131 | ptr -= size) |
| 132 | SWAP(ptr, ptr - size, size, ptr_cmp); |
| 133 | } |
| 134 | POP(low, high); |
| 135 | continue; |
| 136 | } |
| 137 | |
| 138 | /* Try to find a good middle element */ |
| 139 | mid= low + size * (count >> 1); |
| 140 | if (count > 40) /* Must be bigger than 24 */ |
| 141 | { |
| 142 | size_t step = size* (count / 8); |
| 143 | MEDIAN(low, low + step, low+step*2); |
| 144 | MEDIAN(mid - step, mid, mid+step); |
| 145 | MEDIAN(high - 2 * step, high-step, high); |
| 146 | /* Put best median in 'mid' */ |
| 147 | MEDIAN(low+step, mid, high-step); |
| 148 | low_ptr = low; |
| 149 | high_ptr = high; |
| 150 | } |
| 151 | else |
| 152 | { |
| 153 | MEDIAN(low, mid, high); |
| 154 | /* The low and high argument are already in sorted against 'pivot' */ |
no outgoing calls
no test coverage detected