|
@@ -9835,22 +9835,48 @@ dir_scan_callback(struct de *de, void *data)
|
|
|
}
|
|
|
|
|
|
|
|
|
-typedef void (*tsortfunc)(const void *data1, const void *data2, void *userarg);
|
|
|
-
|
|
|
static void
|
|
|
mg_sort(void *data,
|
|
|
size_t elemcount,
|
|
|
size_t elemsize,
|
|
|
- tsortfunc sortfunc,
|
|
|
+ int (*compfunc)(const void *data1, const void *data2, void *userarg),
|
|
|
void *userarg)
|
|
|
{
|
|
|
- /* Do nothing and check if this is the reason for our MacOS crash. This
|
|
|
- * could be because of a different order of arguments for qsort_r between
|
|
|
- * Linux and MacOS:
|
|
|
+ /* We cannot use qsort_r here. For a detailed reason, see
|
|
|
+ * https://github.com/civetweb/civetweb/issues/1048#issuecomment-1047093014
|
|
|
* https://stackoverflow.com/questions/39560773/different-declarations-of-qsort-r-on-mac-and-linux
|
|
|
- * Anyway: Why sort at server side if this could be done on client side in
|
|
|
- * Javascript as well?
|
|
|
*/
|
|
|
+
|
|
|
+ /* We use ShellSort here with this gap sequence: https://oeis.org/A102549 */
|
|
|
+ int A102549[9] = {1, 4, 10, 23, 57, 132, 301, 701, 1750};
|
|
|
+ int Aidx, gap, i, j, k;
|
|
|
+ void *tmp = alloca(elemsize);
|
|
|
+
|
|
|
+ for (Aidx = 8; Aidx >= 0; Aidx--) {
|
|
|
+ gap = A102549[Aidx];
|
|
|
+ if (gap > elemcount / 2) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ for (i = 0; i < gap; i++) {
|
|
|
+ for (j = i; j < elemcount; j += gap) {
|
|
|
+ memcpy(tmp, (void *)((ptrdiff_t)data + elemsize * j), elemsize);
|
|
|
+
|
|
|
+ for (k = j; k >= gap; k -= gap) {
|
|
|
+ void *cmp =
|
|
|
+ (void *)((ptrdiff_t)data + elemsize * (k - gap));
|
|
|
+ int cmpres = compfunc(cmp, tmp, userarg);
|
|
|
+ if (cmpres > 0) {
|
|
|
+ memcpy((void *)((ptrdiff_t)data + elemsize * k),
|
|
|
+ cmp,
|
|
|
+ elemsize);
|
|
|
+ } else {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ memcpy((void *)((ptrdiff_t)data + elemsize * k), tmp, elemsize);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
|