diff options
author | Zeev Suraski <zeev@php.net> | 2001-08-13 00:28:18 +0000 |
---|---|---|
committer | Zeev Suraski <zeev@php.net> | 2001-08-13 00:28:18 +0000 |
commit | 8722b31d8af773cd108eb3d3cf541b47c6a99db1 (patch) | |
tree | 3dd3affd9b5138db78e2258e4fcce994708a5c06 | |
parent | e8f4e4660c1884ba36f5d7948a15b7ca559fccac (diff) | |
download | php-git-8722b31d8af773cd108eb3d3cf541b47c6a99db1.tar.gz |
MFZE1
-rw-r--r-- | Zend/zend_API.c | 4 | ||||
-rw-r--r-- | Zend/zend_operators.c | 92 | ||||
-rw-r--r-- | Zend/zend_operators.h | 84 |
3 files changed, 58 insertions, 122 deletions
diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 3145ce5987..7390aab7eb 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -239,7 +239,7 @@ static char *zend_parse_arg_impl(zval **arg, va_list *va, char **spec) double d; int type; - if ((type = is_numeric_string(Z_STRVAL_PP(arg), Z_STRLEN_PP(arg), p, &d)) == 0) { + if ((type = is_numeric_string(Z_STRVAL_PP(arg), Z_STRLEN_PP(arg), p, &d, 0)) == 0) { return "long"; } else if (type == IS_DOUBLE) { *p = (long) d; @@ -273,7 +273,7 @@ static char *zend_parse_arg_impl(zval **arg, va_list *va, char **spec) long l; int type; - if ((type = is_numeric_string(Z_STRVAL_PP(arg), Z_STRLEN_PP(arg), &l, p)) == 0) { + if ((type = is_numeric_string(Z_STRVAL_PP(arg), Z_STRLEN_PP(arg), &l, p, 0)) == 0) { return "double"; } else if (type == IS_LONG) { *p = (double) l; diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index 8ac4164420..42f0972600 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -114,7 +114,7 @@ ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC) char *strval; strval = op->value.str.val; - switch ((op->type=is_numeric_string(strval, op->value.str.len, &op->value.lval, &op->value.dval))) { + switch ((op->type=is_numeric_string(strval, op->value.str.len, &op->value.lval, &op->value.dval, 1))) { case IS_DOUBLE: case IS_LONG: break; @@ -152,7 +152,7 @@ ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC) switch ((op)->type) { \ case IS_STRING: \ { \ - switch (((holder).type=is_numeric_string((op)->value.str.val, (op)->value.str.len, &(holder).value.lval, &(holder).value.dval))) { \ + switch (((holder).type=is_numeric_string((op)->value.str.val, (op)->value.str.len, &(holder).value.lval, &(holder).value.dval, 1))) { \ case IS_DOUBLE: \ case IS_LONG: \ break; \ @@ -1456,7 +1456,7 @@ ZEND_API int increment_function(zval *op1) double dval; char *strval = op1->value.str.val; - switch (is_numeric_string(strval, op1->value.str.len, &lval, &dval)) { + switch (is_numeric_string(strval, op1->value.str.len, &lval, &dval, 0)) { case IS_LONG: op1->value.lval = lval+1; op1->type = IS_LONG; @@ -1502,7 +1502,7 @@ ZEND_API int decrement_function(zval *op1) op1->value.lval = -1; op1->type = IS_LONG; break; - } else if (is_numeric_string(op1->value.str.val, op1->value.str.len, &lval, NULL)==IS_LONG) { /* long */ + } else if (is_numeric_string(op1->value.str.val, op1->value.str.len, &lval, NULL, 0)==IS_LONG) { /* long */ STR_FREE(op1->value.str.val); op1->value.lval = lval-1; op1->type = IS_LONG; @@ -1627,8 +1627,8 @@ ZEND_API void zendi_smart_strcmp(zval *result, zval *s1, zval *s2) long lval1, lval2; double dval1, dval2; - if ((ret1=is_numeric_string(s1->value.str.val, s1->value.str.len, &lval1, &dval1)) && - (ret2=is_numeric_string(s2->value.str.val, s2->value.str.len, &lval2, &dval2))) { + if ((ret1=is_numeric_string(s1->value.str.val, s1->value.str.len, &lval1, &dval1, 0)) && + (ret2=is_numeric_string(s2->value.str.val, s2->value.str.len, &lval2, &dval2, 0))) { #if 0&&WITH_BCMATH if ((ret1==FLAG_IS_BC) || (ret2==FLAG_IS_BC)) { bc_num first, second; @@ -1703,83 +1703,3 @@ ZEND_API void zend_compare_objects(zval *result, zval *o1, zval *o2 TSRMLS_DC) } zend_compare_symbol_tables(result, Z_OBJPROP_P(o1), Z_OBJPROP_P(o2) TSRMLS_CC); } - - -/* returns 0 for non-numeric string - * returns IS_DOUBLE for floating point string, and assigns the value to *dval (if it's not NULL) - * returns IS_LONG for integer strings, and assigns the value to *lval (if it's not NULL) - * returns FLAG_IS_BC if the number might lose accuracy when converted to a double - */ - -#if 0 - -static inline int is_numeric_string(char *str, int length, long *lval, double *dval) -{ - register char *p=str, *end=str+length; - unsigned char had_period=0, had_exponent=0; - char *end_ptr; - - if (!length) { - return 0; - } - switch (*p) { - case '-': - case '+': - while (*++p==' '); /* ignore spaces after the sign */ - break; - default: - break; - } - while (p<end) { - if (isdigit((int)(unsigned char)*p)) { - p++; - } else if (*p=='.') { - if (had_period) { - return 0; - } else { - had_period=1; - p++; - } - } else if (*p=='e' || *p=='E') { - p++; - if (is_numeric_string(p, length - (int) (p-str), NULL, NULL)==IS_LONG) { /* valid exponent */ - had_exponent=1; - break; - } else { - return 0; - } - } else { - return 0; - } - } - errno=0; - if (had_period || had_exponent) { /* floating point number */ - double local_dval; - - local_dval = strtod(str, &end_ptr); - if (errno==ERANGE || end_ptr != str+length) { /* overflow or bad string */ - return 0; - } else { - if (dval) { - *dval = local_dval; - } - return IS_DOUBLE; - } - } else { - long local_lval; - - local_lval = strtol(str, &end_ptr, 10); - if (errno==ERANGE || end_ptr != str+length) { /* overflow or bad string */ - return 0; - } else { - if (lval) { - *lval = local_lval; - } - return IS_LONG; - } - } -} - - - -#endif diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h index b1e2a4410e..3cc733a70d 100644 --- a/Zend/zend_operators.h +++ b/Zend/zend_operators.h @@ -58,11 +58,11 @@ ZEND_API int is_not_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) ZEND_API int is_smaller_function(zval *result, zval *op1, zval *op2 TSRMLS_DC); ZEND_API int is_smaller_or_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC); -static inline int is_numeric_string(char *str, int length, long *lval, double *dval) +static inline int is_numeric_string(char *str, int length, long *lval, double *dval, zend_bool allow_errors) { long local_lval; double local_dval; - char *end_ptr; + char *end_ptr_long, *end_ptr_double; int conv_base=10; if (!length) { @@ -74,12 +74,16 @@ static inline int is_numeric_string(char *str, int length, long *lval, double *d conv_base=16; } errno=0; - local_lval = strtol(str, &end_ptr, conv_base); - if (errno!=ERANGE && end_ptr == str+length) { /* integer string */ - if (lval) { - *lval = local_lval; + local_lval = strtol(str, &end_ptr_long, conv_base); + if (errno!=ERANGE) { + if (end_ptr_long == str+length) { /* integer string */ + if (lval) { + *lval = local_lval; + } + return IS_LONG; } - return IS_LONG; + } else { + end_ptr_long=NULL; } if (conv_base==16) { /* hex string, under UNIX strtod() messes it up */ @@ -87,40 +91,52 @@ static inline int is_numeric_string(char *str, int length, long *lval, double *d } errno=0; - local_dval = strtod(str, &end_ptr); - if (errno!=ERANGE && end_ptr == str+length) { /* floating point string */ - if (! zend_finite(local_dval)) { - /* "inf","nan" and maybe other weird ones */ - return 0; - } + local_dval = strtod(str, &end_ptr_double); + if (errno!=ERANGE) { + if (end_ptr_double == str+length) { /* floating point string */ + if (! zend_finite(local_dval)) { + /* "inf","nan" and maybe other weird ones */ + return 0; + } - if (dval) { - *dval = local_dval; - } + if (dval) { + *dval = local_dval; + } #if 0&&WITH_BCMATH - if (length>16) { - register char *ptr=str, *end=str+length; - - while (ptr<end) { - switch(*ptr++) { - case 'e': - case 'E': - /* scientific notation, not handled by the BC library */ - return IS_DOUBLE; - break; - default: - break; + if (length>16) { + register char *ptr=str, *end=str+length; + + while (ptr<end) { + switch(*ptr++) { + case 'e': + case 'E': + /* scientific notation, not handled by the BC library */ + return IS_DOUBLE; + break; + default: + break; + } } + return FLAG_IS_BC; + } else { + return IS_DOUBLE; } - return FLAG_IS_BC; - } else { - return IS_DOUBLE; - } #else - return IS_DOUBLE; + return IS_DOUBLE; #endif + } + } else { + end_ptr_double=NULL; + } + if (allow_errors) { + if (end_ptr_double>end_ptr_long && dval) { + *dval = local_dval; + return IS_DOUBLE; + } else if (end_ptr_long && lval) { + *lval = local_lval; + return IS_LONG; + } } - return 0; } |