PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - ext/intl/collator - collator_is_numeric.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 45 133 33.8 %
Date: 2016-05-03 Functions: 2 3 66.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | PHP Version 7                                                        |
       4             :    +----------------------------------------------------------------------+
       5             :    | This source file is subject to version 3.01 of the PHP license,      |
       6             :    | that is bundled with this package in the file LICENSE, and is        |
       7             :    | available through the world-wide-web at the following url:           |
       8             :    | http://www.php.net/license/3_01.txt                                  |
       9             :    | If you did not receive a copy of the PHP license and are unable to   |
      10             :    | obtain it through the world-wide-web, please send a note to          |
      11             :    | license@php.net so we can mail you a copy immediately.               |
      12             :    +----------------------------------------------------------------------+
      13             :    | Authors: Vadim Savchuk <vsavchuk@productengine.com>                  |
      14             :    |          Dmitry Lakhtyuk <dlakhtyuk@productengine.com>               |
      15             :    +----------------------------------------------------------------------+
      16             :  */
      17             : 
      18             : #include "collator_is_numeric.h"
      19             : 
      20             : /* {{{ collator_u_strtod
      21             :  * Taken from PHP6:zend_u_strtod()
      22             :  */
      23           0 : static double collator_u_strtod(const UChar *nptr, UChar **endptr) /* {{{ */
      24             : {
      25           0 :         const UChar *u = nptr, *nstart;
      26           0 :         UChar c = *u;
      27           0 :         int any = 0;
      28             :         ALLOCA_FLAG(use_heap);
      29             : 
      30           0 :         while (u_isspace(c)) {
      31           0 :                 c = *++u;
      32             :         }
      33           0 :         nstart = u;
      34             : 
      35           0 :         if (c == 0x2D /*'-'*/ || c == 0x2B /*'+'*/) {
      36           0 :                 c = *++u;
      37             :         }
      38             : 
      39           0 :         while (c >= 0x30 /*'0'*/ && c <= 0x39 /*'9'*/) {
      40           0 :                 any = 1;
      41           0 :                 c = *++u;
      42             :         }
      43             : 
      44           0 :         if (c == 0x2E /*'.'*/) {
      45           0 :                 c = *++u;
      46           0 :                 while (c >= 0x30 /*'0'*/ && c <= 0x39 /*'9'*/) {
      47           0 :                         any = 1;
      48           0 :                         c = *++u;
      49             :                 }
      50             :         }
      51             : 
      52           0 :         if ((c == 0x65 /*'e'*/ || c == 0x45 /*'E'*/) && any) {
      53           0 :                 const UChar *e = u;
      54           0 :                 int any_exp = 0;
      55             : 
      56           0 :                 c = *++u;
      57           0 :                 if (c == 0x2D /*'-'*/ || c == 0x2B /*'+'*/) {
      58           0 :                         c = *++u;
      59             :                 }
      60             : 
      61           0 :                 while (c >= 0x30 /*'0'*/ && c <= 0x39 /*'9'*/) {
      62           0 :                         any_exp = 1;
      63           0 :                         c = *++u;
      64             :                 }
      65             : 
      66           0 :                 if (!any_exp) {
      67           0 :                         u = e;
      68             :                 }
      69             :         }
      70             : 
      71           0 :         if (any) {
      72             :                 char buf[64], *numbuf, *bufpos;
      73           0 :                 int length = u - nstart;
      74             :                 double value;
      75             : 
      76           0 :                 if (length < sizeof(buf)) {
      77           0 :                         numbuf = buf;
      78             :                 } else {
      79           0 :                         numbuf = (char *) do_alloca(length + 1, use_heap);
      80             :                 }
      81             : 
      82           0 :                 bufpos = numbuf;
      83             : 
      84           0 :                 while (nstart < u) {
      85           0 :                         *bufpos++ = (char) *nstart++;
      86             :                 }
      87             : 
      88           0 :                 *bufpos = '\0';
      89           0 :                 value = zend_strtod(numbuf, NULL);
      90             : 
      91           0 :                 if (numbuf != buf) {
      92           0 :                         free_alloca(numbuf, use_heap);
      93             :                 }
      94             : 
      95           0 :                 if (endptr != NULL) {
      96           0 :                         *endptr = (UChar *)u;
      97             :                 }
      98             : 
      99           0 :                 return value;
     100             :         }
     101             : 
     102           0 :         if (endptr != NULL) {
     103           0 :                 *endptr = (UChar *)nptr;
     104             :         }
     105             : 
     106           0 :         return 0;
     107             : }
     108             : /* }}} */
     109             : 
     110             : /* {{{ collator_u_strtol
     111             :  * Taken from PHP6:zend_u_strtol()
     112             :  *
     113             :  * Convert a Unicode string to a long integer.
     114             :  *
     115             :  * Ignores `locale' stuff.
     116             :  */
     117         179 : static zend_long collator_u_strtol(nptr, endptr, base)
     118             :         const UChar *nptr;
     119             :         UChar **endptr;
     120             :         register int base;
     121             : {
     122         179 :         register const UChar *s = nptr;
     123             :         register zend_ulong acc;
     124             :         register UChar c;
     125             :         register zend_ulong cutoff;
     126         179 :         register int neg = 0, any, cutlim;
     127             : 
     128         179 :         if (s == NULL) {
     129           0 :                 errno = ERANGE;
     130           0 :                 if (endptr != NULL) {
     131           0 :                         *endptr = NULL;
     132             :                 }
     133           0 :                 return 0;
     134             :         }
     135             : 
     136             :         /*
     137             :          * Skip white space and pick up leading +/- sign if any.
     138             :          * If base is 0, allow 0x for hex and 0 for octal, else
     139             :          * assume decimal; if base is already 16, allow 0x.
     140             :          */
     141             :         do {
     142         181 :                 c = *s++;
     143         181 :         } while (u_isspace(c));
     144         179 :         if (c == 0x2D /*'-'*/) {
     145           0 :                 neg = 1;
     146           0 :                 c = *s++;
     147         179 :         } else if (c == 0x2B /*'+'*/)
     148           0 :                 c = *s++;
     149         179 :         if ((base == 0 || base == 16) &&
     150             :             (c == 0x30 /*'0'*/)
     151           0 :                  && (*s == 0x78 /*'x'*/ || *s == 0x58 /*'X'*/)) {
     152           0 :                 c = s[1];
     153           0 :                 s += 2;
     154           0 :                 base = 16;
     155             :         }
     156         179 :         if (base == 0)
     157           0 :                 base = (c == 0x30 /*'0'*/) ? 8 : 10;
     158             : 
     159             :         /*
     160             :          * Compute the cutoff value between legal numbers and illegal
     161             :          * numbers.  That is the largest legal value, divided by the
     162             :          * base.  An input number that is greater than this value, if
     163             :          * followed by a legal input character, is too big.  One that
     164             :          * is equal to this value may be valid or not; the limit
     165             :          * between valid and invalid numbers is then based on the last
     166             :          * digit.  For instance, if the range for longs is
     167             :          * [-2147483648..2147483647] and the input base is 10,
     168             :          * cutoff will be set to 214748364 and cutlim to either
     169             :          * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
     170             :          * a value > 214748364, or equal but the next digit is > 7 (or 8),
     171             :          * the number is too big, and we will return a range error.
     172             :          *
     173             :          * Set any if any `digits' consumed; make it negative to indicate
     174             :          * overflow.
     175             :          */
     176         179 :         cutoff = neg ? -(zend_ulong)ZEND_LONG_MIN : ZEND_LONG_MAX;
     177         179 :         cutlim = cutoff % (zend_ulong)base;
     178         179 :         cutoff /= (zend_ulong)base;
     179         253 :         for (acc = 0, any = 0;; c = *s++) {
     180         327 :                 if (c >= 0x30 /*'0'*/ && c <= 0x39 /*'9'*/)
     181          74 :                         c -= 0x30 /*'0'*/;
     182         179 :                 else if (c >= 0x41 /*'A'*/ && c <= 0x5A /*'Z'*/)
     183           0 :                         c -= 0x41 /*'A'*/ - 10;
     184         179 :                 else if (c >= 0x61 /*'a'*/ && c <= 0x7A /*'z'*/)
     185          95 :                         c -= 0x61 /*'a'*/ - 10;
     186             :                 else
     187             :                         break;
     188         169 :                 if (c >= base)
     189          95 :                         break;
     190             : 
     191          74 :                 if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
     192           0 :                         any = -1;
     193             :                 else {
     194          74 :                         any = 1;
     195          74 :                         acc *= base;
     196          74 :                         acc += c;
     197             :                 }
     198          74 :         }
     199         179 :         if (any < 0) {
     200           0 :                 acc = neg ? ZEND_LONG_MIN : ZEND_LONG_MAX;
     201           0 :                 errno = ERANGE;
     202         179 :         } else if (neg)
     203           0 :                 acc = -acc;
     204         179 :         if (endptr != NULL)
     205         179 :                 *endptr = (UChar *)(any ? s - 1 : nptr);
     206         179 :         return (acc);
     207             : }
     208             : /* }}} */
     209             : 
     210             : 
     211             : /* {{{ collator_is_numeric]
     212             :  * Taken from PHP6:is_numeric_unicode()
     213             :  */
     214         181 : zend_uchar collator_is_numeric( UChar *str, int32_t length, zend_long *lval, double *dval, int allow_errors )
     215             : {
     216             :         zend_long local_lval;
     217             :         double local_dval;
     218             :         UChar *end_ptr_long, *end_ptr_double;
     219         181 :         int conv_base=10;
     220             : 
     221         181 :         if (!length) {
     222           2 :                 return 0;
     223             :         }
     224             : 
     225             :         /* handle hex numbers */
     226         179 :         if (length>=2 && str[0]=='0' && (str[1]=='x' || str[1]=='X')) {
     227           0 :                 conv_base=16;
     228             :         }
     229             : 
     230         179 :         errno=0;
     231         179 :         local_lval = collator_u_strtol(str, &end_ptr_long, conv_base);
     232         179 :         if (errno != ERANGE) {
     233         179 :                 if (end_ptr_long == str+length) { /* integer string */
     234          34 :                         if (lval) {
     235          34 :                                 *lval = local_lval;
     236             :                         }
     237          34 :                         return IS_LONG;
     238         145 :                 } else if (end_ptr_long == str && *end_ptr_long != '\0' && *str != '.' && *str != '-') { /* ignore partial string matches */
     239         145 :                         return 0;
     240             :                 }
     241             :         } else {
     242           0 :                 end_ptr_long = NULL;
     243             :         }
     244             : 
     245           0 :         if (conv_base == 16) { /* hex string, under UNIX strtod() messes it up */
     246             :                 /* UTODO: keep compatibility with is_numeric_string() here? */
     247           0 :                 return 0;
     248             :         }
     249             : 
     250           0 :         local_dval = collator_u_strtod(str, &end_ptr_double);
     251           0 :         if (local_dval == 0 && end_ptr_double == str) {
     252           0 :                 end_ptr_double = NULL;
     253             :         } else {
     254           0 :                 if (end_ptr_double == str+length) { /* floating point string */
     255           0 :                         if (!zend_finite(local_dval)) {
     256             :                                 /* "inf","nan" and maybe other weird ones */
     257           0 :                                 return 0;
     258             :                         }
     259             : 
     260           0 :                         if (dval) {
     261           0 :                                 *dval = local_dval;
     262             :                         }
     263           0 :                         return IS_DOUBLE;
     264             :                 }
     265             :         }
     266             : 
     267           0 :         if (!allow_errors) {
     268           0 :                 return 0;
     269             :         }
     270           0 :         if (allow_errors == -1) {
     271           0 :                 zend_error(E_NOTICE, "A non well formed numeric value encountered");
     272             :         }
     273             : 
     274           0 :         if (allow_errors) {
     275           0 :                 if (end_ptr_double > end_ptr_long && dval) {
     276           0 :                         *dval = local_dval;
     277           0 :                         return IS_DOUBLE;
     278           0 :                 } else if (end_ptr_long && lval) {
     279           0 :                         *lval = local_lval;
     280           0 :                         return IS_LONG;
     281             :                 }
     282             :         }
     283           0 :         return 0;
     284             : }
     285             : /* }}} */
     286             : 
     287             : /*
     288             :  * Local variables:
     289             :  * tab-width: 4
     290             :  * c-basic-offset: 4
     291             :  * End:
     292             :  * vim600: noet sw=4 ts=4 fdm=marker
     293             :  * vim<600: noet sw=4 ts=4
     294             :  */

Generated by: LCOV version 1.10

Generated at Wed, 04 May 2016 01:00:50 +0000 (52 minutes ago)

Copyright © 2005-2016 The PHP Group
All rights reserved.