22
22
23
23
/* Synced with php 3.0 revision 1.193 1999-06-16 [ssb] */
24
24
25
- #define _GNU_SOURCE 1
26
25
#include <stdio.h>
27
26
#include <stdint.h>
28
27
#include "php.h"
@@ -135,7 +134,7 @@ static char *php_bin2hex(const unsigned char *old, const size_t oldlen, size_t *
135
134
size_t i , j ;
136
135
137
136
result = (unsigned char * ) safe_emalloc (oldlen , 2 * sizeof (char ), 1 );
138
-
137
+
139
138
for (i = j = 0 ; i < oldlen ; i ++ ) {
140
139
result [j ++ ] = hexconvtab [old [i ] >> 4 ];
141
140
result [j ++ ] = hexconvtab [old [i ] & 15 ];
@@ -2841,7 +2840,7 @@ static inline void php_strtr_populate_shift(PATNREPL *patterns, int patnum, int
2841
2840
for (i = 0 ; i < patnum ; i ++ ) {
2842
2841
for (j = 0 ; j < m - B + 1 ; j ++ ) {
2843
2842
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 );
2845
2844
shift -> entries [h ] = MIN (shift -> entries [h ], m - j - B );
2846
2845
}
2847
2846
}
@@ -2874,6 +2873,62 @@ static int php_strtr_compare_hash_suffix(const void *a, const void *b, void *ctx
2874
2873
}
2875
2874
}
2876
2875
/* }}} */
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
+ /* }}} */
2877
2932
/* {{{ php_strtr_free_strp */
2878
2933
static void php_strtr_free_strp (void * strp )
2879
2934
{
@@ -2967,11 +3022,11 @@ static PPRES *php_strtr_array_prepare(STR *text, PATNREPL *patterns, int patnum,
2967
3022
php_strtr_populate_shift (patterns , patnum , B , res -> m , res -> shift );
2968
3023
2969
3024
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 ;
2971
3026
2972
3027
res -> patterns = safe_emalloc (patnum , sizeof (* res -> patterns ), 0 );
2973
3028
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 );
2975
3030
2976
3031
res -> prefix = safe_emalloc (patnum , sizeof (* res -> prefix ), 0 );
2977
3032
for (i = 0 ; i < patnum ; i ++ ) {
@@ -3050,7 +3105,7 @@ static void php_strtr_array_do_repl(STR *text, PPRES *d, zval *return_value)
3050
3105
if (L (& pnr -> pat ) > L (text ) - pos ||
3051
3106
memcmp (S (& pnr -> pat ), & S (text )[pos ], L (& pnr -> pat )) != 0 )
3052
3107
continue ;
3053
-
3108
+
3054
3109
smart_str_appendl (& result , & S (text )[nextwpos ], pos - nextwpos );
3055
3110
smart_str_appendl (& result , S (& pnr -> repl ), L (& pnr -> repl ));
3056
3111
pos += L (& pnr -> pat );
@@ -3076,7 +3131,7 @@ end_outer_loop: ;
3076
3131
3077
3132
/* {{{ php_strtr_array */
3078
3133
static void php_strtr_array (zval * return_value , char * str , int slen , HashTable * pats )
3079
- {
3134
+ {
3080
3135
PPRES * data ;
3081
3136
STR text ;
3082
3137
PATNREPL * patterns ;
0 commit comments