]> granicus.if.org Git - php/commitdiff
Split is_numeric_string_ex() into inline and non-inline parts
authorDmitry Stogov <dmitry@zend.com>
Thu, 18 Sep 2014 18:19:51 +0000 (22:19 +0400)
committerDmitry Stogov <dmitry@zend.com>
Thu, 18 Sep 2014 18:19:51 +0000 (22:19 +0400)
Zend/zend_operators.c
Zend/zend_operators.h

index d3a2da86183ac23203c6fb8644948e03c21e43da..db3e8df8c3e540315e04862c2bb299ba38608653 100644 (file)
@@ -2530,6 +2530,143 @@ ZEND_API zend_uchar is_numeric_str_function(const zend_string *str, zend_long *l
     return is_numeric_string_ex(str->val, str->len, lval, dval, -1, NULL);
 }
 
+ZEND_API zend_uchar _is_numeric_string_ex(const char *str, size_t length, zend_long *lval, double *dval, int allow_errors, int *oflow_info)
+{
+       const char *ptr;
+       int base = 10, digits = 0, dp_or_e = 0;
+       double local_dval = 0.0;
+       zend_uchar type;
+
+       if (!length) {
+               return 0;
+       }
+
+       if (oflow_info != NULL) {
+               *oflow_info = 0;
+       }
+
+       /* Skip any whitespace
+        * This is much faster than the isspace() function */
+       while (*str == ' ' || *str == '\t' || *str == '\n' || *str == '\r' || *str == '\v' || *str == '\f') {
+               str++;
+               length--;
+       }
+       ptr = str;
+
+       if (*ptr == '-' || *ptr == '+') {
+               ptr++;
+       }
+
+       if (ZEND_IS_DIGIT(*ptr)) {
+               /* Handle hex numbers
+                * str is used instead of ptr to disallow signs and keep old behavior */
+               if (length > 2 && *str == '0' && (str[1] == 'x' || str[1] == 'X')) {
+                       base = 16;
+                       ptr += 2;
+               }
+
+               /* Skip any leading 0s */
+               while (*ptr == '0') {
+                       ptr++;
+               }
+
+               /* Count the number of digits. If a decimal point/exponent is found,
+                * it's a double. Otherwise, if there's a dval or no need to check for
+                * a full match, stop when there are too many digits for a long */
+               for (type = IS_LONG; !(digits >= MAX_LENGTH_OF_LONG && (dval || allow_errors == 1)); digits++, ptr++) {
+check_digits:
+                       if (ZEND_IS_DIGIT(*ptr) || (base == 16 && ZEND_IS_XDIGIT(*ptr))) {
+                               continue;
+                       } else if (base == 10) {
+                               if (*ptr == '.' && dp_or_e < 1) {
+                                       goto process_double;
+                               } else if ((*ptr == 'e' || *ptr == 'E') && dp_or_e < 2) {
+                                       const char *e = ptr + 1;
+
+                                       if (*e == '-' || *e == '+') {
+                                               ptr = e++;
+                                       }
+                                       if (ZEND_IS_DIGIT(*e)) {
+                                               goto process_double;
+                                       }
+                               }
+                       }
+
+                       break;
+               }
+
+               if (base == 10) {
+                       if (digits >= MAX_LENGTH_OF_LONG) {
+                               if (oflow_info != NULL) {
+                                       *oflow_info = *str == '-' ? -1 : 1;
+                               }
+                               dp_or_e = -1;
+                               goto process_double;
+                       }
+               } else if (!(digits < SIZEOF_ZEND_LONG * 2 || (digits == SIZEOF_ZEND_LONG * 2 && ptr[-digits] <= '7'))) {
+                       if (dval) {
+                               local_dval = zend_hex_strtod(str, &ptr);
+                       }
+                       if (oflow_info != NULL) {
+                               *oflow_info = 1;
+                       }
+                       type = IS_DOUBLE;
+               }
+       } else if (*ptr == '.' && ZEND_IS_DIGIT(ptr[1])) {
+process_double:
+               type = IS_DOUBLE;
+
+               /* If there's a dval, do the conversion; else continue checking
+                * the digits if we need to check for a full match */
+               if (dval) {
+                       local_dval = zend_strtod(str, &ptr);
+               } else if (allow_errors != 1 && dp_or_e != -1) {
+                       dp_or_e = (*ptr++ == '.') ? 1 : 2;
+                       goto check_digits;
+               }
+       } else {
+               return 0;
+       }
+
+       if (ptr != str + length) {
+               if (!allow_errors) {
+                       return 0;
+               }
+               if (allow_errors == -1) {
+                       zend_error(E_NOTICE, "A non well formed numeric value encountered");
+               }
+       }
+
+       if (type == IS_LONG) {
+               if (digits == MAX_LENGTH_OF_LONG - 1) {
+                       int cmp = strcmp(&ptr[-digits], long_min_digits);
+
+                       if (!(cmp < 0 || (cmp == 0 && *str == '-'))) {
+                               if (dval) {
+                                       *dval = zend_strtod(str, NULL);
+                               }
+                               if (oflow_info != NULL) {
+                                       *oflow_info = *str == '-' ? -1 : 1;
+                               }
+
+                               return IS_DOUBLE;
+                       }
+               }
+
+               if (lval) {
+                       *lval = ZEND_STRTOL(str, NULL, base);
+               }
+
+               return IS_LONG;
+       } else {
+               if (dval) {
+                       *dval = local_dval;
+               }
+
+               return IS_DOUBLE;
+       }
+}
+
 /*
  * Local variables:
  * tab-width: 4
index a50e65d7c2a5f9f6e6a672c5457bea66b5b8aa74..ece77936ebf34e91afa57546b7a32c13be0bd7cf 100644 (file)
@@ -129,150 +129,23 @@ static zend_always_inline zend_long zend_dval_to_lval(double d)
  * could not be represented as such due to overflow. It writes 1 to oflow_info
  * if the integer is larger than ZEND_LONG_MAX and -1 if it's smaller than ZEND_LONG_MIN.
  */
-static inline zend_uchar is_numeric_string_ex(const char *str, size_t length, zend_long *lval, double *dval, int allow_errors, int *oflow_info)
-{
-       const char *ptr;
-       int base = 10, digits = 0, dp_or_e = 0;
-       double local_dval = 0.0;
-       zend_uchar type;
-
-       if (!length) {
-               return 0;
-       }
-
-       if (oflow_info != NULL) {
-               *oflow_info = 0;
-       }
-
-       /* Skip any whitespace
-        * This is much faster than the isspace() function */
-       while (*str == ' ' || *str == '\t' || *str == '\n' || *str == '\r' || *str == '\v' || *str == '\f') {
-               str++;
-               length--;
-       }
-       ptr = str;
-
-       if (*ptr == '-' || *ptr == '+') {
-               ptr++;
-       }
-
-       if (ZEND_IS_DIGIT(*ptr)) {
-               /* Handle hex numbers
-                * str is used instead of ptr to disallow signs and keep old behavior */
-               if (length > 2 && *str == '0' && (str[1] == 'x' || str[1] == 'X')) {
-                       base = 16;
-                       ptr += 2;
-               }
-
-               /* Skip any leading 0s */
-               while (*ptr == '0') {
-                       ptr++;
-               }
-
-               /* Count the number of digits. If a decimal point/exponent is found,
-                * it's a double. Otherwise, if there's a dval or no need to check for
-                * a full match, stop when there are too many digits for a long */
-               for (type = IS_LONG; !(digits >= MAX_LENGTH_OF_LONG && (dval || allow_errors == 1)); digits++, ptr++) {
-check_digits:
-                       if (ZEND_IS_DIGIT(*ptr) || (base == 16 && ZEND_IS_XDIGIT(*ptr))) {
-                               continue;
-                       } else if (base == 10) {
-                               if (*ptr == '.' && dp_or_e < 1) {
-                                       goto process_double;
-                               } else if ((*ptr == 'e' || *ptr == 'E') && dp_or_e < 2) {
-                                       const char *e = ptr + 1;
-
-                                       if (*e == '-' || *e == '+') {
-                                               ptr = e++;
-                                       }
-                                       if (ZEND_IS_DIGIT(*e)) {
-                                               goto process_double;
-                                       }
-                               }
-                       }
+ZEND_API zend_uchar _is_numeric_string_ex(const char *str, size_t length, zend_long *lval, double *dval, int allow_errors, int *oflow_info);
 
-                       break;
-               }
-
-               if (base == 10) {
-                       if (digits >= MAX_LENGTH_OF_LONG) {
-                               if (oflow_info != NULL) {
-                                       *oflow_info = *str == '-' ? -1 : 1;
-                               }
-                               dp_or_e = -1;
-                               goto process_double;
-                       }
-               } else if (!(digits < SIZEOF_ZEND_LONG * 2 || (digits == SIZEOF_ZEND_LONG * 2 && ptr[-digits] <= '7'))) {
-                       if (dval) {
-                               local_dval = zend_hex_strtod(str, &ptr);
-                       }
-                       if (oflow_info != NULL) {
-                               *oflow_info = 1;
-                       }
-                       type = IS_DOUBLE;
-               }
-       } else if (*ptr == '.' && ZEND_IS_DIGIT(ptr[1])) {
-process_double:
-               type = IS_DOUBLE;
-
-               /* If there's a dval, do the conversion; else continue checking
-                * the digits if we need to check for a full match */
-               if (dval) {
-                       local_dval = zend_strtod(str, &ptr);
-               } else if (allow_errors != 1 && dp_or_e != -1) {
-                       dp_or_e = (*ptr++ == '.') ? 1 : 2;
-                       goto check_digits;
-               }
-       } else {
+static zend_always_inline zend_uchar is_numeric_string_ex(const char *str, size_t length, zend_long *lval, double *dval, int allow_errors, int *oflow_info)
+{
+       if (*str > '9') {
                return 0;
        }
-
-       if (ptr != str + length) {
-               if (!allow_errors) {
-                       return 0;
-               }
-               if (allow_errors == -1) {
-                       zend_error(E_NOTICE, "A non well formed numeric value encountered");
-               }
-       }
-
-       if (type == IS_LONG) {
-               if (digits == MAX_LENGTH_OF_LONG - 1) {
-                       int cmp = strcmp(&ptr[-digits], long_min_digits);
-
-                       if (!(cmp < 0 || (cmp == 0 && *str == '-'))) {
-                               if (dval) {
-                                       *dval = zend_strtod(str, NULL);
-                               }
-                               if (oflow_info != NULL) {
-                                       *oflow_info = *str == '-' ? -1 : 1;
-                               }
-
-                               return IS_DOUBLE;
-                       }
-               }
-
-               if (lval) {
-                       *lval = ZEND_STRTOL(str, NULL, base);
-               }
-
-               return IS_LONG;
-       } else {
-               if (dval) {
-                       *dval = local_dval;
-               }
-
-               return IS_DOUBLE;
-       }
+       return _is_numeric_string_ex(str, length, lval, dval, allow_errors, oflow_info);
 }
 
-static inline zend_uchar is_numeric_string(const char *str, size_t length, zend_long *lval, double *dval, int allow_errors) {
+static zend_always_inline zend_uchar is_numeric_string(const char *str, size_t length, zend_long *lval, double *dval, int allow_errors) {
     return is_numeric_string_ex(str, length, lval, dval, allow_errors, NULL);
 }
 
 ZEND_API zend_uchar is_numeric_str_function(const zend_string *str, zend_long *lval, double *dval);
 
-static inline const char *
+static zend_always_inline const char *
 zend_memnstr(const char *haystack, const char *needle, size_t needle_len, char *end)
 {
        const char *p = haystack;
@@ -309,7 +182,7 @@ zend_memnstr(const char *haystack, const char *needle, size_t needle_len, char *
        return NULL;
 }
 
-static inline const void *zend_memrchr(const void *s, int c, size_t n)
+static zend_always_inline const void *zend_memrchr(const void *s, int c, size_t n)
 {
        register const unsigned char *e;