Skip to content

Commit d7bac4f

Browse files
committed
Remove _GNU_SOURCE, add local heap sort
1 parent e5029ac commit d7bac4f

File tree

1 file changed

+62
-7
lines changed

1 file changed

+62
-7
lines changed

ext/standard/string.c

Lines changed: 62 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222

2323
/* Synced with php 3.0 revision 1.193 1999-06-16 [ssb] */
2424

25-
#define _GNU_SOURCE 1
2625
#include <stdio.h>
2726
#include <stdint.h>
2827
#include "php.h"
@@ -135,7 +134,7 @@ static char *php_bin2hex(const unsigned char *old, const size_t oldlen, size_t *
135134
size_t i, j;
136135

137136
result = (unsigned char *) safe_emalloc(oldlen, 2 * sizeof(char), 1);
138-
137+
139138
for (i = j = 0; i < oldlen; i++) {
140139
result[j++] = hexconvtab[old[i] >> 4];
141140
result[j++] = hexconvtab[old[i] & 15];
@@ -2841,7 +2840,7 @@ static inline void php_strtr_populate_shift(PATNREPL *patterns, int patnum, int
28412840
for (i = 0; i < patnum; i++) {
28422841
for (j = 0; j < m - B + 1; j++) {
28432842
HASH h = php_strtr_hash(&S(&patterns[i].pat)[j], B) & shift->table_mask;
2844-
assert((long long) m - (long long) j - B >= 0);
2843+
assert((long long) m - (long long) j - B >= 0);
28452844
shift->entries[h] = MIN(shift->entries[h], m - j - B);
28462845
}
28472846
}
@@ -2874,6 +2873,62 @@ static int php_strtr_compare_hash_suffix(const void *a, const void *b, void *ctx
28742873
}
28752874
}
28762875
/* }}} */
2876+
/* {{{ Sorting (no zend_qsort_r in this PHP version) */
2877+
#define HS_LEFT(i) ((i) * 2 + 1)
2878+
#define HS_RIGHT(i) ((i) * 2 + 2)
2879+
#define HS_PARENT(i) (((i) - 1) / 2);
2880+
#define HS_OFF(data, i) ((void *)(&((data)->arr)[i]))
2881+
#define HS_CMP_CALL(data, i1, i2) \
2882+
(php_strtr_compare_hash_suffix(HS_OFF((data), (i1)), HS_OFF((data), (i2)), (data)->res))
2883+
struct hs_data {
2884+
PATNREPL *arr;
2885+
size_t nel;
2886+
size_t heapel;
2887+
PPRES *res;
2888+
};
2889+
static inline void php_strtr_swap(PATNREPL *a, PATNREPL *b)
2890+
{
2891+
PATNREPL tmp = *a;
2892+
*a = *b;
2893+
*b = tmp;
2894+
}
2895+
static inline void php_strtr_fix_heap(struct hs_data *data, size_t i)
2896+
{
2897+
size_t li = HS_LEFT(i),
2898+
ri = HS_RIGHT(i),
2899+
largei;
2900+
if (li < data->heapel && HS_CMP_CALL(data, li, i) > 0) {
2901+
largei = li;
2902+
} else {
2903+
largei = i;
2904+
}
2905+
if (ri < data->heapel && HS_CMP_CALL(data, ri, largei) > 0) {
2906+
largei = ri;
2907+
}
2908+
if (largei != i) {
2909+
php_strtr_swap(HS_OFF(data, i), HS_OFF(data, largei));
2910+
php_strtr_fix_heap(data, largei);
2911+
}
2912+
}
2913+
static inline void php_strtr_build_heap(struct hs_data *data)
2914+
{
2915+
size_t i;
2916+
for (i = data->nel / 2; i > 0; i--) {
2917+
php_strtr_fix_heap(data, i - 1);
2918+
}
2919+
}
2920+
static inline void php_strtr_heapsort(PATNREPL *arr, size_t nel, PPRES *res)
2921+
{
2922+
struct hs_data data = { arr, nel, nel, res };
2923+
size_t i;
2924+
php_strtr_build_heap(&data);
2925+
for (i = nel; i > 1; i--) {
2926+
php_strtr_swap(arr, HS_OFF(&data, i - 1));
2927+
data.heapel--;
2928+
php_strtr_fix_heap(&data, 0);
2929+
}
2930+
}
2931+
/* }}} */
28772932
/* {{{ php_strtr_free_strp */
28782933
static void php_strtr_free_strp(void *strp)
28792934
{
@@ -2967,11 +3022,11 @@ static PPRES *php_strtr_array_prepare(STR *text, PATNREPL *patterns, int patnum,
29673022
php_strtr_populate_shift(patterns, patnum, B, res->m, res->shift);
29683023

29693024
res->hash = safe_emalloc(HASH_TAB_SIZE, sizeof(*res->hash->entries), sizeof(*res->shift));
2970-
res->hash->table_mask = HASH_TAB_SIZE - 1;
3025+
res->hash->table_mask = HASH_TAB_SIZE - 1;
29713026

29723027
res->patterns = safe_emalloc(patnum, sizeof(*res->patterns), 0);
29733028
memcpy(res->patterns, patterns, sizeof(*patterns) * patnum);
2974-
qsort_r(res->patterns, patnum, sizeof(*res->patterns), php_strtr_compare_hash_suffix, res);
3029+
php_strtr_heapsort(res->patterns, patnum, res);
29753030

29763031
res->prefix = safe_emalloc(patnum, sizeof(*res->prefix), 0);
29773032
for (i = 0; i < patnum; i++) {
@@ -3050,7 +3105,7 @@ static void php_strtr_array_do_repl(STR *text, PPRES *d, zval *return_value)
30503105
if (L(&pnr->pat) > L(text) - pos ||
30513106
memcmp(S(&pnr->pat), &S(text)[pos], L(&pnr->pat)) != 0)
30523107
continue;
3053-
3108+
30543109
smart_str_appendl(&result, &S(text)[nextwpos], pos - nextwpos);
30553110
smart_str_appendl(&result, S(&pnr->repl), L(&pnr->repl));
30563111
pos += L(&pnr->pat);
@@ -3076,7 +3131,7 @@ end_outer_loop: ;
30763131

30773132
/* {{{ php_strtr_array */
30783133
static void php_strtr_array(zval *return_value, char *str, int slen, HashTable *pats)
3079-
{
3134+
{
30803135
PPRES *data;
30813136
STR text;
30823137
PATNREPL *patterns;

0 commit comments

Comments
 (0)