]> granicus.if.org Git - php/commitdiff
MFZE1
authorZeev Suraski <zeev@php.net>
Mon, 13 Aug 2001 00:28:18 +0000 (00:28 +0000)
committerZeev Suraski <zeev@php.net>
Mon, 13 Aug 2001 00:28:18 +0000 (00:28 +0000)
Zend/zend_API.c
Zend/zend_operators.c
Zend/zend_operators.h

index 3145ce598765be5816b853a950f9101bf8cb1347..7390aab7eb1d947420022ed4e15a0ba276df6362 100644 (file)
@@ -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;
index 8ac41644203fce755b4dc679ae757d5d2fa3df83..42f09726005fa3c38c8496e7dde1c976dddaade3 100644 (file)
@@ -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
index b1e2a4410e09789a589c74038a487198e8cac21b..3cc733a70d10af38d8af03d731f3900d617ef008 100644 (file)
@@ -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;
 }