Skip to content

Commit 8edafae

Browse files
committed
Implement strtr frameless handlers
1 parent 9349bff commit 8edafae

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
{
@@ -3396,42 +3434,7 @@ PHP_FUNCTION(strtr)
33963434
}
33973435

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

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

0 commit comments

Comments
 (0)