Skip to content

Commit 4cbfa32

Browse files
committed
Implement strtr frameless handlers
1 parent 894fa15 commit 4cbfa32

File tree

3 files changed

+96
-41
lines changed

3 files changed

+96
-41
lines changed

ext/standard/basic_functions.stub.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2472,6 +2472,8 @@ function ucwords(string $string, string $separators = " \t\r\n\f\v"): string {}
24722472

24732473
/**
24742474
* @compile-time-eval
2475+
* @frameless-function {"arity": 2}
2476+
* @frameless-function {"arity": 3}
24752477
*/
24762478
function strtr(string $string, string|array $from, ?string $to = null): string {}
24772479

ext/standard/basic_functions_arginfo.h

Lines changed: 10 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ext/standard/string.c

Lines changed: 84 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2875,8 +2875,7 @@ static zend_string *php_strtr_ex(zend_string *str, const char *str_from, const c
28752875
}
28762876
/* }}} */
28772877

2878-
/* {{{ php_strtr_array */
2879-
static void php_strtr_array(zval *return_value, zend_string *input, HashTable *pats)
2878+
static void php_strtr_array_ex(zval *return_value, zend_string *input, HashTable *pats)
28802879
{
28812880
const char *str = ZSTR_VAL(input);
28822881
size_t slen = ZSTR_LEN(input);
@@ -3010,7 +3009,6 @@ static void php_strtr_array(zval *return_value, zend_string *input, HashTable *p
30103009
}
30113010
efree(num_bitset);
30123011
}
3013-
/* }}} */
30143012

30153013
/* {{{ count_chars */
30163014
static zend_always_inline zend_long count_chars(const char *p, zend_long length, char ch)
@@ -3369,6 +3367,46 @@ PHPAPI zend_string *php_str_to_str(const char *haystack, size_t length, const ch
33693367
}
33703368
/* }}} */
33713369

3370+
static void php_strtr_array(zval *return_value, zend_string *str, HashTable *from_ht)
3371+
{
3372+
if (zend_hash_num_elements(from_ht) < 1) {
3373+
RETURN_STR_COPY(str);
3374+
} else if (zend_hash_num_elements(from_ht) == 1) {
3375+
zend_long num_key;
3376+
zend_string *str_key, *tmp_str, *replace, *tmp_replace;
3377+
zval *entry;
3378+
3379+
ZEND_HASH_FOREACH_KEY_VAL(from_ht, num_key, str_key, entry) {
3380+
tmp_str = NULL;
3381+
if (UNEXPECTED(!str_key)) {
3382+
str_key = tmp_str = zend_long_to_str(num_key);
3383+
}
3384+
replace = zval_get_tmp_string(entry, &tmp_replace);
3385+
if (ZSTR_LEN(str_key) < 1) {
3386+
php_error_docref(NULL, E_WARNING, "Ignoring replacement of empty string");
3387+
RETVAL_STR_COPY(str);
3388+
} else if (ZSTR_LEN(str_key) == 1) {
3389+
RETVAL_STR(php_char_to_str_ex(str,
3390+
ZSTR_VAL(str_key)[0],
3391+
ZSTR_VAL(replace),
3392+
ZSTR_LEN(replace),
3393+
/* case_sensitive */ true,
3394+
NULL));
3395+
} else {
3396+
zend_long dummy;
3397+
RETVAL_STR(php_str_to_str_ex(str,
3398+
ZSTR_VAL(str_key), ZSTR_LEN(str_key),
3399+
ZSTR_VAL(replace), ZSTR_LEN(replace), &dummy));
3400+
}
3401+
zend_tmp_string_release(tmp_str);
3402+
zend_tmp_string_release(tmp_replace);
3403+
return;
3404+
} ZEND_HASH_FOREACH_END();
3405+
} else {
3406+
php_strtr_array_ex(return_value, str, from_ht);
3407+
}
3408+
}
3409+
33723410
/* {{{ Translates characters in str using given translation tables */
33733411
PHP_FUNCTION(strtr)
33743412
{
@@ -3398,42 +3436,7 @@ PHP_FUNCTION(strtr)
33983436
}
33993437

34003438
if (!to) {
3401-
if (zend_hash_num_elements(from_ht) < 1) {
3402-
RETURN_STR_COPY(str);
3403-
} else if (zend_hash_num_elements(from_ht) == 1) {
3404-
zend_long num_key;
3405-
zend_string *str_key, *tmp_str, *replace, *tmp_replace;
3406-
zval *entry;
3407-
3408-
ZEND_HASH_FOREACH_KEY_VAL(from_ht, num_key, str_key, entry) {
3409-
tmp_str = NULL;
3410-
if (UNEXPECTED(!str_key)) {
3411-
str_key = tmp_str = zend_long_to_str(num_key);
3412-
}
3413-
replace = zval_get_tmp_string(entry, &tmp_replace);
3414-
if (ZSTR_LEN(str_key) < 1) {
3415-
php_error_docref(NULL, E_WARNING, "Ignoring replacement of empty string");
3416-
RETVAL_STR_COPY(str);
3417-
} else if (ZSTR_LEN(str_key) == 1) {
3418-
RETVAL_STR(php_char_to_str_ex(str,
3419-
ZSTR_VAL(str_key)[0],
3420-
ZSTR_VAL(replace),
3421-
ZSTR_LEN(replace),
3422-
/* case_sensitive */ true,
3423-
NULL));
3424-
} else {
3425-
zend_long dummy;
3426-
RETVAL_STR(php_str_to_str_ex(str,
3427-
ZSTR_VAL(str_key), ZSTR_LEN(str_key),
3428-
ZSTR_VAL(replace), ZSTR_LEN(replace), &dummy));
3429-
}
3430-
zend_tmp_string_release(tmp_str);
3431-
zend_tmp_string_release(tmp_replace);
3432-
return;
3433-
} ZEND_HASH_FOREACH_END();
3434-
} else {
3435-
php_strtr_array(return_value, str, from_ht);
3436-
}
3439+
php_strtr_array(return_value, str, from_ht);
34373440
} else {
34383441
RETURN_STR(php_strtr_ex(str,
34393442
ZSTR_VAL(from_str),
@@ -3443,6 +3446,48 @@ PHP_FUNCTION(strtr)
34433446
}
34443447
/* }}} */
34453448

3449+
ZEND_FRAMELESS_FUNCTION(strtr, 2)
3450+
{
3451+
zval str_tmp;
3452+
zend_string *str;
3453+
zval *from;
3454+
3455+
Z_FLF_PARAM_STR(1, str, str_tmp);
3456+
Z_FLF_PARAM_ARRAY(2, from);
3457+
3458+
if (ZSTR_LEN(str) == 0) {
3459+
RETVAL_EMPTY_STRING();
3460+
goto flf_clean;
3461+
}
3462+
3463+
php_strtr_array(return_value, str, Z_ARR_P(from));
3464+
3465+
flf_clean:
3466+
Z_FLF_PARAM_FREE_STR(1, str_tmp);
3467+
}
3468+
3469+
ZEND_FRAMELESS_FUNCTION(strtr, 3)
3470+
{
3471+
zval str_tmp, from_tmp, to_tmp;
3472+
zend_string *str, *from, *to;
3473+
3474+
Z_FLF_PARAM_STR(1, str, str_tmp);
3475+
Z_FLF_PARAM_STR(2, from, from_tmp);
3476+
Z_FLF_PARAM_STR(3, to, to_tmp);
3477+
3478+
if (ZSTR_LEN(str) == 0) {
3479+
RETVAL_EMPTY_STRING();
3480+
goto flf_clean;
3481+
}
3482+
3483+
RETVAL_STR(php_strtr_ex(str, ZSTR_VAL(from), ZSTR_VAL(to), MIN(ZSTR_LEN(from), ZSTR_LEN(to))));
3484+
3485+
flf_clean:
3486+
Z_FLF_PARAM_FREE_STR(1, str_tmp);
3487+
Z_FLF_PARAM_FREE_STR(2, from_tmp);
3488+
Z_FLF_PARAM_FREE_STR(3, to_tmp);
3489+
}
3490+
34463491
/* {{{ Reverse a string */
34473492
#ifdef ZEND_INTRIN_SSSE3_NATIVE
34483493
#include <tmmintrin.h>

0 commit comments

Comments
 (0)