| 191 | } |
| 192 | |
| 193 | static void auxsort (lua_State *L, int l, int u) { |
| 194 | while (l < u) { /* for tail recursion */ |
| 195 | int i, j; |
| 196 | /* sort elements a[l], a[(l+u)/2] and a[u] */ |
| 197 | lua_rawgeti(L, 1, l); |
| 198 | lua_rawgeti(L, 1, u); |
| 199 | if (sort_comp(L, -1, -2)) /* a[u] < a[l]? */ |
| 200 | set2(L, l, u); /* swap a[l] - a[u] */ |
| 201 | else |
| 202 | lua_pop(L, 2); |
| 203 | if (u-l == 1) break; /* only 2 elements */ |
| 204 | i = (l+u)/2; |
| 205 | lua_rawgeti(L, 1, i); |
| 206 | lua_rawgeti(L, 1, l); |
| 207 | if (sort_comp(L, -2, -1)) /* a[i]<a[l]? */ |
| 208 | set2(L, i, l); |
| 209 | else { |
| 210 | lua_pop(L, 1); /* remove a[l] */ |
| 211 | lua_rawgeti(L, 1, u); |
| 212 | if (sort_comp(L, -1, -2)) /* a[u]<a[i]? */ |
| 213 | set2(L, i, u); |
| 214 | else |
| 215 | lua_pop(L, 2); |
| 216 | } |
| 217 | if (u-l == 2) break; /* only 3 elements */ |
| 218 | lua_rawgeti(L, 1, i); /* Pivot */ |
| 219 | lua_pushvalue(L, -1); |
| 220 | lua_rawgeti(L, 1, u-1); |
| 221 | set2(L, i, u-1); |
| 222 | /* a[l] <= P == a[u-1] <= a[u], only need to sort from l+1 to u-2 */ |
| 223 | i = l; j = u-1; |
| 224 | for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */ |
| 225 | /* repeat ++i until a[i] >= P */ |
| 226 | while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) { |
| 227 | if (i>u) luaL_error(L, "invalid order function for sorting"); |
| 228 | lua_pop(L, 1); /* remove a[i] */ |
| 229 | } |
| 230 | /* repeat --j until a[j] <= P */ |
| 231 | while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) { |
| 232 | if (j<l) luaL_error(L, "invalid order function for sorting"); |
| 233 | lua_pop(L, 1); /* remove a[j] */ |
| 234 | } |
| 235 | if (j<i) { |
| 236 | lua_pop(L, 3); /* pop pivot, a[i], a[j] */ |
| 237 | break; |
| 238 | } |
| 239 | set2(L, i, j); |
| 240 | } |
| 241 | lua_rawgeti(L, 1, u-1); |
| 242 | lua_rawgeti(L, 1, i); |
| 243 | set2(L, u-1, i); /* swap pivot (a[u-1]) with a[i] */ |
| 244 | /* a[l..i-1] <= a[i] == P <= a[i+1..u] */ |
| 245 | /* adjust so that smaller half is in [j..i] and larger one in [l..u] */ |
| 246 | if (i-l < u-i) { |
| 247 | j=l; i=i-1; l=i+2; |
| 248 | } |
| 249 | else { |
| 250 | j=i+1; i=u; u=j-2; |
no test coverage detected