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: 2014-11-15 Functions: 2 3 66.7 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Sat, 15 Nov 2014 06:19:32 +0000 (8 days ago)

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