From: Sara Golemon Date: Tue, 19 Sep 2006 23:27:03 +0000 (+0000) Subject: Refactor parameter parsing into the 21st century and flag Unicode readiness X-Git-Tag: RELEASE_1_0_0RC1~1615 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=17f279b2ca176e4e5edf916e23ed888a1f84daa3;p=php Refactor parameter parsing into the 21st century and flag Unicode readiness --- diff --git a/ext/bcmath/bcmath.c b/ext/bcmath/bcmath.c index 05bfb06642..750feaad57 100644 --- a/ext/bcmath/bcmath.c +++ b/ext/bcmath/bcmath.c @@ -220,238 +220,190 @@ static void php_str2num(bc_num *num, char *str TSRMLS_DC) } /* }}} */ -/* {{{ proto string bcadd(string left_operand, string right_operand [, int scale]) + +/* {{{ proto string bcadd(string left_operand, string right_operand [, int scale]) U Returns the sum of two arbitrary precision numbers */ PHP_FUNCTION(bcadd) { - zval **left, **right, **scale_param; + char *left, *right; + int left_len, right_len; + long scale = BCG(bc_precision); bc_num first, second, result; - int scale = BCG(bc_precision); - - switch (ZEND_NUM_ARGS()) { - case 2: - if (zend_get_parameters_ex(2, &left, &right) == FAILURE) { - WRONG_PARAM_COUNT; - } - break; - case 3: - if (zend_get_parameters_ex(3, &left, &right, &scale_param) == FAILURE) { - WRONG_PARAM_COUNT; - } - convert_to_long_ex(scale_param); - scale = (int) (Z_LVAL_PP(scale_param) < 0) ? 0 : Z_LVAL_PP(scale_param); - break; - default: - WRONG_PARAM_COUNT; - break; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", &left, &left_len, &right, &right_len, &scale) == FAILURE) { + return; + } + + if (scale < 0) { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Invalid scale given, using zero"); + scale = 0; } - convert_to_string_ex(left); - convert_to_string_ex(right); + bc_init_num(&first TSRMLS_CC); bc_init_num(&second TSRMLS_CC); bc_init_num(&result TSRMLS_CC); - php_str2num(&first, Z_STRVAL_PP(left) TSRMLS_CC); - php_str2num(&second, Z_STRVAL_PP(right) TSRMLS_CC); - bc_add (first, second, &result, scale); + php_str2num(&first, left TSRMLS_CC); + php_str2num(&second, right TSRMLS_CC); + + bc_add(first, second, &result, scale); if (result->n_scale > scale) { result->n_scale = scale; } - Z_STRVAL_P(return_value) = bc_num2str(result); - Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value)); - Z_TYPE_P(return_value) = IS_STRING; + + RETVAL_STRING(bc_num2str(result), 0); + bc_free_num(&first); bc_free_num(&second); bc_free_num(&result); - return; } /* }}} */ -/* {{{ proto string bcsub(string left_operand, string right_operand [, int scale]) +/* {{{ proto string bcsub(string left_operand, string right_operand [, int scale]) U Returns the difference between two arbitrary precision numbers */ PHP_FUNCTION(bcsub) { - zval **left, **right, **scale_param; + char *left, *right; + int left_len, right_len; + long scale = BCG(bc_precision); bc_num first, second, result; - int scale = BCG(bc_precision); - - switch (ZEND_NUM_ARGS()) { - case 2: - if (zend_get_parameters_ex(2, &left, &right) == FAILURE) { - WRONG_PARAM_COUNT; - } - break; - case 3: - if (zend_get_parameters_ex(3, &left, &right, &scale_param) == FAILURE) { - WRONG_PARAM_COUNT; - } - convert_to_long_ex(scale_param); - scale = (int) (Z_LVAL_PP(scale_param) < 0) ? 0 : Z_LVAL_PP(scale_param); - break; - default: - WRONG_PARAM_COUNT; - break; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", &left, &left_len, &right, &right_len, &scale) == FAILURE) { + return; } - convert_to_string_ex(left); - convert_to_string_ex(right); + + if (scale < 0) { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Invalid scale given, using zero"); + scale = 0; + } + bc_init_num(&first TSRMLS_CC); bc_init_num(&second TSRMLS_CC); bc_init_num(&result TSRMLS_CC); - php_str2num(&first, Z_STRVAL_PP(left) TSRMLS_CC); - php_str2num(&second, Z_STRVAL_PP(right) TSRMLS_CC); - bc_sub (first, second, &result, scale); + php_str2num(&first, left TSRMLS_CC); + php_str2num(&second, right TSRMLS_CC); + + bc_sub(first, second, &result, scale); if (result->n_scale > scale) { result->n_scale = scale; } - Z_STRVAL_P(return_value) = bc_num2str(result); - Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value)); - Z_TYPE_P(return_value) = IS_STRING; + + RETVAL_STRING(bc_num2str(result), 0); + bc_free_num(&first); bc_free_num(&second); bc_free_num(&result); - return; } /* }}} */ -/* {{{ proto string bcmul(string left_operand, string right_operand [, int scale]) +/* {{{ proto string bcmul(string left_operand, string right_operand [, int scale]) U Returns the multiplication of two arbitrary precision numbers */ PHP_FUNCTION(bcmul) { - zval **left, **right, **scale_param; + char *left, *right; + int left_len, right_len; + long scale = BCG(bc_precision); bc_num first, second, result; - int scale = BCG(bc_precision); - - switch (ZEND_NUM_ARGS()) { - case 2: - if (zend_get_parameters_ex(2, &left, &right) == FAILURE) { - WRONG_PARAM_COUNT; - } - break; - case 3: - if (zend_get_parameters_ex(3, &left, &right, &scale_param) == FAILURE) { - WRONG_PARAM_COUNT; - } - convert_to_long_ex(scale_param); - scale = (int) (Z_LVAL_PP(scale_param) < 0) ? 0 : Z_LVAL_PP(scale_param); - break; - default: - WRONG_PARAM_COUNT; - break; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", &left, &left_len, &right, &right_len, &scale) == FAILURE) { + return; + } + + if (scale < 0) { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Invalid scale given, using zero"); + scale = 0; } - convert_to_string_ex(left); - convert_to_string_ex(right); + bc_init_num(&first TSRMLS_CC); bc_init_num(&second TSRMLS_CC); bc_init_num(&result TSRMLS_CC); - php_str2num(&first, Z_STRVAL_PP(left) TSRMLS_CC); - php_str2num(&second, Z_STRVAL_PP(right) TSRMLS_CC); - bc_multiply (first, second, &result, scale TSRMLS_CC); + php_str2num(&first, left TSRMLS_CC); + php_str2num(&second, right TSRMLS_CC); + + bc_multiply(first, second, &result, scale); if (result->n_scale > scale) { result->n_scale = scale; } - Z_STRVAL_P(return_value) = bc_num2str(result); - Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value)); - Z_TYPE_P(return_value) = IS_STRING; + + RETVAL_STRING(bc_num2str(result), 0); + bc_free_num(&first); bc_free_num(&second); bc_free_num(&result); - return; } /* }}} */ -/* {{{ proto string bcdiv(string left_operand, string right_operand [, int scale]) +/* {{{ proto string bcdiv(string left_operand, string right_operand [, int scale]) U Returns the quotient of two arbitrary precision numbers (division) */ PHP_FUNCTION(bcdiv) { - zval **left, **right, **scale_param; + char *left, *right; + int left_len, right_len; + long scale = BCG(bc_precision); bc_num first, second, result; - int scale = BCG(bc_precision); - - switch (ZEND_NUM_ARGS()) { - case 2: - if (zend_get_parameters_ex(2, &left, &right) == FAILURE) { - WRONG_PARAM_COUNT; - } - break; - case 3: - if (zend_get_parameters_ex(3, &left, &right, &scale_param) == FAILURE) { - WRONG_PARAM_COUNT; - } - convert_to_long_ex(scale_param); - scale = (int) (Z_LVAL_PP(scale_param) < 0) ? 0 : Z_LVAL_PP(scale_param); - break; - default: - WRONG_PARAM_COUNT; - break; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", &left, &left_len, &right, &right_len, &scale) == FAILURE) { + return; + } + + if (scale < 0) { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Invalid scale given, using zero"); + scale = 0; } - convert_to_string_ex(left); - convert_to_string_ex(right); + bc_init_num(&first TSRMLS_CC); bc_init_num(&second TSRMLS_CC); bc_init_num(&result TSRMLS_CC); - php_str2num(&first, Z_STRVAL_PP(left) TSRMLS_CC); - php_str2num(&second, Z_STRVAL_PP(right) TSRMLS_CC); - switch (bc_divide(first, second, &result, scale TSRMLS_CC)) { - case 0: /* OK */ - if (result->n_scale > scale) { - result->n_scale = scale; - } - Z_STRVAL_P(return_value) = bc_num2str(result); - Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value)); - Z_TYPE_P(return_value) = IS_STRING; - break; - case -1: /* division by zero */ - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Division by zero"); - break; + php_str2num(&first, left TSRMLS_CC); + php_str2num(&second, right TSRMLS_CC); + + if (bc_divide(first, second, &result, scale TSRMLS_CC) == 0) { + if (result->n_scale > scale) { + result->n_scale = scale; + } + RETVAL_STRING(bc_num2str(result), 0); + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Division by zero"); + RETVAL_NULL(); } + bc_free_num(&first); bc_free_num(&second); bc_free_num(&result); - return; } /* }}} */ -/* {{{ proto string bcmod(string left_operand, string right_operand) +/* {{{ proto string bcmod(string left_operand, string right_operand) U Returns the modulus of the two arbitrary precision operands */ PHP_FUNCTION(bcmod) { - zval **left, **right; + char *left, *right; + int left_len, right_len; bc_num first, second, result; - switch (ZEND_NUM_ARGS()) { - case 2: - if (zend_get_parameters_ex(2, &left, &right) == FAILURE) { - WRONG_PARAM_COUNT; - } - break; - default: - WRONG_PARAM_COUNT; - break; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &left, &left_len, &right, &right_len) == FAILURE) { + return; } - convert_to_string_ex(left); - convert_to_string_ex(right); + bc_init_num(&first TSRMLS_CC); bc_init_num(&second TSRMLS_CC); bc_init_num(&result TSRMLS_CC); - bc_str2num(&first, Z_STRVAL_PP(left), 0 TSRMLS_CC); - bc_str2num(&second, Z_STRVAL_PP(right), 0 TSRMLS_CC); - switch (bc_modulo(first, second, &result, 0 TSRMLS_CC)) { - case 0: - Z_STRVAL_P(return_value) = bc_num2str(result); - Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value)); - Z_TYPE_P(return_value) = IS_STRING; - break; - case -1: - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Division by zero"); - break; + php_str2num(&first, left TSRMLS_CC); + php_str2num(&second, right TSRMLS_CC); + + if (bc_modulo(first, second, &result, 0 TSRMLS_CC) == 0) { + RETVAL_STRING(bc_num2str(result), 0); + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Division by zero"); + RETVAL_NULL(); } + bc_free_num(&first); bc_free_num(&second); bc_free_num(&result); - return; } /* }}} */ -/* {{{ proto string bcpowmod(string x, string y, string mod [, int scale]) +/* {{{ proto string bcpowmod(string x, string y, string mod [, int scale]) U Returns the value of an arbitrary precision number raised to the power of another reduced by a modulous */ PHP_FUNCTION(bcpowmod) { @@ -461,7 +413,12 @@ PHP_FUNCTION(bcpowmod) long scale = BCG(bc_precision); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss|l", &left, &left_len, &right, &right_len, &modulous, &modulous_len, &scale) == FAILURE) { - WRONG_PARAM_COUNT; + return; + } + + if (scale < 0) { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Invalid scale given, using zero"); + scale = 0; } bc_init_num(&first TSRMLS_CC); @@ -471,164 +428,143 @@ PHP_FUNCTION(bcpowmod) php_str2num(&first, left TSRMLS_CC); php_str2num(&second, right TSRMLS_CC); php_str2num(&mod, modulous TSRMLS_CC); - bc_raisemod(first, second, mod, &result, scale TSRMLS_CC); - if (result->n_scale > scale) { - result->n_scale = scale; + if (bc_raisemod(first, second, mod, &result, scale TSRMLS_CC) == 0) { + if (result->n_scale > scale) { + result->n_scale = scale; + } + RETVAL_STRING(bc_num2str(result), 0); + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Division by zero"); + RETVAL_NULL(); } - Z_STRVAL_P(return_value) = bc_num2str(result); - Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value)); - Z_TYPE_P(return_value) = IS_STRING; + + bc_free_num(&first); bc_free_num(&second); bc_free_num(&mod); bc_free_num(&result); - return; } /* }}} */ -/* {{{ proto string bcpow(string x, string y [, int scale]) +/* {{{ proto string bcpow(string x, string y [, int scale]) U Returns the value of an arbitrary precision number raised to the power of another */ PHP_FUNCTION(bcpow) { - zval **left, **right, **scale_param; + char *left, *right; + int left_len, right_len; + long scale = BCG(bc_precision); bc_num first, second, result; - int scale = BCG(bc_precision); - - switch (ZEND_NUM_ARGS()) { - case 2: - if (zend_get_parameters_ex(2, &left, &right) == FAILURE) { - WRONG_PARAM_COUNT; - } - break; - case 3: - if (zend_get_parameters_ex(3, &left, &right, &scale_param) == FAILURE) { - WRONG_PARAM_COUNT; - } - convert_to_long_ex(scale_param); - scale = (int) (Z_LVAL_PP(scale_param) < 0) ? 0 : Z_LVAL_PP(scale_param); - break; - default: - WRONG_PARAM_COUNT; - break; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", &left, &left_len, &right, &right_len, &scale) == FAILURE) { + return; } - convert_to_string_ex(left); - convert_to_string_ex(right); + + if (scale < 0) { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Invalid scale given, using zero"); + scale = 0; + } + bc_init_num(&first TSRMLS_CC); bc_init_num(&second TSRMLS_CC); bc_init_num(&result TSRMLS_CC); - php_str2num(&first, Z_STRVAL_PP(left) TSRMLS_CC); - php_str2num(&second, Z_STRVAL_PP(right) TSRMLS_CC); + php_str2num(&first, left TSRMLS_CC); + php_str2num(&second, right TSRMLS_CC); + bc_raise (first, second, &result, scale TSRMLS_CC); if (result->n_scale > scale) { result->n_scale = scale; } - Z_STRVAL_P(return_value) = bc_num2str(result); - Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value)); - Z_TYPE_P(return_value) = IS_STRING; + if (result->n_scale > scale) { + result->n_scale = scale; + } + RETVAL_STRING(bc_num2str(result), 0); + bc_free_num(&first); bc_free_num(&second); bc_free_num(&result); - return; } /* }}} */ -/* {{{ proto string bcsqrt(string operand [, int scale]) +/* {{{ proto string bcsqrt(string operand [, int scale]) U Returns the square root of an arbitray precision number */ PHP_FUNCTION(bcsqrt) { - zval **left, **scale_param; + char *operand; + int operand_len; + long scale = BCG(bc_precision); bc_num result; - int scale = BCG(bc_precision); - - switch (ZEND_NUM_ARGS()) { - case 1: - if (zend_get_parameters_ex(1, &left) == FAILURE) { - WRONG_PARAM_COUNT; - } - break; - case 2: - if (zend_get_parameters_ex(2, &left, &scale_param) == FAILURE) { - WRONG_PARAM_COUNT; - } - convert_to_long_ex(scale_param); - scale = (int) (Z_LVAL_PP(scale_param) < 0) ? 0 : Z_LVAL_PP(scale_param); - break; - default: - WRONG_PARAM_COUNT; - break; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &operand, &operand_len, &scale) == FAILURE) { + return; + } + + if (scale < 0) { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Invalid scale given, using zero"); + scale = 0; } - convert_to_string_ex(left); + bc_init_num(&result TSRMLS_CC); - php_str2num(&result, Z_STRVAL_PP(left) TSRMLS_CC); + php_str2num(&result, operand TSRMLS_CC); if (bc_sqrt (&result, scale TSRMLS_CC) != 0) { if (result->n_scale > scale) { result->n_scale = scale; } - Z_STRVAL_P(return_value) = bc_num2str(result); - Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value)); - Z_TYPE_P(return_value) = IS_STRING; + RETVAL_STRING(bc_num2str(result), 0); } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Square root of negative number"); + RETVAL_NULL(); } bc_free_num(&result); - return; } /* }}} */ -/* {{{ proto int bccomp(string left_operand, string right_operand [, int scale]) +/* {{{ proto int bccomp(string left_operand, string right_operand [, int scale]) U Compares two arbitrary precision numbers */ PHP_FUNCTION(bccomp) { - zval **left, **right, **scale_param; + char *left, *right; + int left_len, right_len; + long scale = BCG(bc_precision); bc_num first, second; - int scale = BCG(bc_precision); - - switch (ZEND_NUM_ARGS()) { - case 2: - if (zend_get_parameters_ex(2, &left, &right) == FAILURE) { - WRONG_PARAM_COUNT; - } - break; - case 3: - if (zend_get_parameters_ex(3, &left, &right, &scale_param) == FAILURE) { - WRONG_PARAM_COUNT; - } - convert_to_long_ex(scale_param); - scale = (int) (Z_LVAL_PP(scale_param) < 0) ? 0 : Z_LVAL_PP(scale_param); - break; - default: - WRONG_PARAM_COUNT; - break; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", &left, &left_len, &right, &right_len, &scale) == FAILURE) { + return; + } + + if (scale < 0) { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Invalid scale given, using zero"); + scale = 0; } - convert_to_string_ex(left); - convert_to_string_ex(right); bc_init_num(&first TSRMLS_CC); bc_init_num(&second TSRMLS_CC); - bc_str2num(&first, Z_STRVAL_PP(left), scale TSRMLS_CC); - bc_str2num(&second, Z_STRVAL_PP(right), scale TSRMLS_CC); - Z_LVAL_P(return_value) = bc_compare(first, second); - Z_TYPE_P(return_value) = IS_LONG; + bc_str2num(&first, left, scale TSRMLS_CC); + bc_str2num(&second, right, scale TSRMLS_CC); + + RETVAL_LONG(bc_compare(first, second)); bc_free_num(&first); bc_free_num(&second); - return; } /* }}} */ -/* {{{ proto bool bcscale(int scale) +/* {{{ proto bool bcscale(int scale) U Sets default scale parameter for all bc math functions */ PHP_FUNCTION(bcscale) { - zval **new_scale; - - if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &new_scale) == FAILURE) { - WRONG_PARAM_COUNT; + long scale; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &scale) == FAILURE) { + return; + } + + if (scale < 0) { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Invalid scale given, using zero"); + scale = 0; } - convert_to_long_ex(new_scale); - BCG(bc_precision) = (Z_LVAL_PP(new_scale) < 0) ? 0 : Z_LVAL_PP(new_scale); + BCG(bc_precision) = scale; RETURN_TRUE; }