Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tag: php-5.2.2
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 128 lines (104 sloc) 3.4 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2007 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 2.00 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.zend.com/license/2_00.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Sterling Hughes <sterling@php.net> |
+----------------------------------------------------------------------+
*/

/* $Id$ */

#include "zend.h"

#include <limits.h>

#define QSORT_STACK_SIZE (sizeof(size_t) * CHAR_BIT)

static void _zend_qsort_swap(void *a, void *b, size_t siz)
{
register char *tmp_a_char;
register char *tmp_b_char;
register int *tmp_a_int;
register int *tmp_b_int;
register size_t i;
int t_i;
char t_c;

tmp_a_int = (int *) a;
tmp_b_int = (int *) b;

for (i = sizeof(int); i <= siz; i += sizeof(int)) {
t_i = *tmp_a_int;
*tmp_a_int++ = *tmp_b_int;
*tmp_b_int++ = t_i;
}

tmp_a_char = (char *) tmp_a_int;
tmp_b_char = (char *) tmp_b_int;

for (i = i - sizeof(int) + 1; i <= siz; ++i) {
t_c = *tmp_a_char;
*tmp_a_char++ = *tmp_b_char;
*tmp_b_char++ = t_c;
}
}

ZEND_API void zend_qsort(void *base, size_t nmemb, size_t siz, compare_func_t compare TSRMLS_DC)
{
void *begin_stack[QSORT_STACK_SIZE];
void *end_stack[QSORT_STACK_SIZE];
register char *begin;
register char *end;
register char *seg1;
register char *seg2;
register char *seg2p;
register int loop;
uint offset;

begin_stack[0] = (char *) base;
end_stack[0] = (char *) base + ((nmemb - 1) * siz);

for (loop = 0; loop >= 0; --loop) {
begin = begin_stack[loop];
end = end_stack[loop];

while (begin < end) {
offset = (end - begin) >> 1;
_zend_qsort_swap(begin, begin + (offset - (offset % siz)), siz);

seg1 = begin + siz;
seg2 = end;

while (1) {
for (; seg1 < seg2 && compare(begin, seg1 TSRMLS_CC) > 0;
seg1 += siz);

for (; seg2 >= seg1 && compare(seg2, begin TSRMLS_CC) > 0;
seg2 -= siz);

if (seg1 >= seg2)
break;

_zend_qsort_swap(seg1, seg2, siz);

seg1 += siz;
seg2 -= siz;
}

_zend_qsort_swap(begin, seg2, siz);

seg2p = seg2;

if ((seg2p - begin) <= (end - seg2p)) {
if ((seg2p + siz) < end) {
begin_stack[loop] = seg2p + siz;
end_stack[loop++] = end;
}
end = seg2p - siz;
}
else {
if ((seg2p - siz) > begin) {
begin_stack[loop] = begin;
end_stack[loop++] = seg2p - siz;
}
begin = seg2p + siz;
}
}
}
}

/*
* Local Variables:
* c-basic-offset: 4
* tab-width: 4
* End:
* vim600: fdm=marker
* vim: noet sw=4 ts=4
*/
Something went wrong with that request. Please try again.