From: Andrei Zmievski Date: Sat, 8 Jul 2000 20:38:23 +0000 (+0000) Subject: @- Updated str_pad() to be able to pad on left/right/both sides. (Andrei) X-Git-Tag: PRE_FILE_COMPILE_API_CHANGE~354 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=885e40db053b968ea448844a66839c9cfceb8240;p=php @- Updated str_pad() to be able to pad on left/right/both sides. (Andrei) --- diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 1cda0abfe6..6c0dafc4aa 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -657,6 +657,7 @@ PHP_MINIT_FUNCTION(basic) register_phpinfo_constants(INIT_FUNC_ARGS_PASSTHRU); register_html_constants(INIT_FUNC_ARGS_PASSTHRU); + register_string_constants(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(regex)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(file)(INIT_FUNC_ARGS_PASSTHRU); diff --git a/ext/standard/php_string.h b/ext/standard/php_string.h index b387faa72c..88b70f22c1 100644 --- a/ext/standard/php_string.h +++ b/ext/standard/php_string.h @@ -123,4 +123,6 @@ PHPAPI char *php_strerror(int errnum); #define strerror php_strerror #endif +void register_string_constants(INIT_FUNC_ARGS); + #endif /* PHP_STRING_H */ diff --git a/ext/standard/string.c b/ext/standard/string.c index cdc9cb0e8c..44cdc4dd4e 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -36,6 +36,17 @@ #include "php_globals.h" #include "basic_functions.h" +#define STR_PAD_LEFT 0 +#define STR_PAD_RIGHT 1 +#define STR_PAD_BOTH 2 + +void register_string_constants(INIT_FUNC_ARGS) +{ + REGISTER_LONG_CONSTANT("STR_PAD_LEFT", STR_PAD_LEFT, CONST_PERSISTENT|CONST_CS); + REGISTER_LONG_CONSTANT("STR_PAD_RIGHT", STR_PAD_RIGHT, CONST_PERSISTENT|CONST_CS); + REGISTER_LONG_CONSTANT("STR_PAD_BOTH", STR_PAD_BOTH, CONST_PERSISTENT|CONST_CS); +} + int php_tag_find(char *tag, int len, char *set); /* this is read-only, so it's ok */ @@ -2571,22 +2582,28 @@ PHP_FUNCTION(substr_count) /* }}} */ -/* {{{ proto string str_pad(string input, int pad_length [, string pad_string]) +/* {{{ proto string str_pad(string input, int pad_length [, string pad_string [, int pad_type ]]) Returns input string padded on the left or right to specified length with pad_string */ PHP_FUNCTION(str_pad) { + /* Input arguments */ zval **input, /* Input string */ - **pad_length, /* Length to pad to (positive/negative) */ - **pad_string; /* Padding string */ - int pad_length_abs; /* Absolute padding length */ + **pad_length, /* Length to pad to */ + **pad_string, /* Padding string */ + **pad_type; /* Padding type (left/right/both) */ + + /* Helper variables */ + int num_pad_chars; /* Number of padding characters (total - input size) */ char *result = NULL; /* Resulting string */ int result_len = 0; /* Length of the resulting string */ char *pad_str_val = " "; /* Pointer to padding string */ int pad_str_len = 1; /* Length of the padding string */ - int i; + int pad_type_val = STR_PAD_RIGHT; /* The padding type value */ + int i, left_pad, right_pad; - if (ZEND_NUM_ARGS() < 2 || ZEND_NUM_ARGS() > 3 || - zend_get_parameters_ex(ZEND_NUM_ARGS(), &input, &pad_length, &pad_string) == FAILURE) { + + if (ZEND_NUM_ARGS() < 2 || ZEND_NUM_ARGS() > 4 || + zend_get_parameters_ex(ZEND_NUM_ARGS(), &input, &pad_length, &pad_string, &pad_type) == FAILURE) { WRONG_PARAM_COUNT; } @@ -2594,11 +2611,11 @@ PHP_FUNCTION(str_pad) convert_to_string_ex(input); convert_to_long_ex(pad_length); - pad_length_abs = abs(Z_LVAL_PP(pad_length)); + num_pad_chars = Z_LVAL_PP(pad_length) - Z_STRLEN_PP(input); /* If resulting string turns out to be shorter than input string, we simply copy the input and return. */ - if (pad_length_abs <= Z_STRLEN_PP(input)) { + if (num_pad_chars < 0) { *return_value = **input; zval_copy_ctor(return_value); return; @@ -2614,26 +2631,49 @@ PHP_FUNCTION(str_pad) } pad_str_val = Z_STRVAL_PP(pad_string); pad_str_len = Z_STRLEN_PP(pad_string); + + if (ZEND_NUM_ARGS() > 3) { + convert_to_long_ex(pad_type); + pad_type_val = Z_LVAL_PP(pad_type); + if (pad_type_val < STR_PAD_LEFT || pad_type_val > STR_PAD_BOTH) { + php_error(E_WARNING, "Padding type has to be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH in %s()", get_active_function_name()); + return; + } + } } - result = (char *)emalloc(pad_length_abs+1); + result = (char *)emalloc(Z_STRLEN_PP(input) + num_pad_chars + 1); - /* If positive, we pad on the right and copy the input now. */ - if (Z_LVAL_PP(pad_length) > 0) { - memcpy(result, Z_STRVAL_PP(input), Z_STRLEN_PP(input)); - result_len = Z_STRLEN_PP(input); + /* We need to figure out the left/right padding lengths. */ + switch (pad_type_val) { + case STR_PAD_RIGHT: + left_pad = 0; + right_pad = num_pad_chars; + break; + + case STR_PAD_LEFT: + left_pad = num_pad_chars; + right_pad = 0; + break; + + case STR_PAD_BOTH: + left_pad = num_pad_chars / 2; + right_pad = num_pad_chars - left_pad; + break; } - /* Loop through pad string, copying it into result. */ - for (i = 0; i < pad_length_abs - Z_STRLEN_PP(input); i++) { + /* First we pad on the left. */ + for (i = 0; i < left_pad; i++) + result[result_len++] = pad_str_val[i % pad_str_len]; + + /* Then we copy the input string. */ + memcpy(result + result_len, Z_STRVAL_PP(input), Z_STRLEN_PP(input)); + result_len += Z_STRLEN_PP(input); + + /* Finally, we pad on the right. */ + for (i = 0; i < right_pad; i++) result[result_len++] = pad_str_val[i % pad_str_len]; - } - /* If negative, we've padded on the left, and copy the input now. */ - if (Z_LVAL_PP(pad_length) < 0) { - memcpy(result + result_len, Z_STRVAL_PP(input), Z_STRLEN_PP(input)); - result_len += Z_STRLEN_PP(input); - } result[result_len] = '\0'; RETURN_STRINGL(result, result_len, 0);