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

LTP GCOV extension - code coverage report
Current view: directory - intl/collator - collator_is_numeric.c
Test: PHP Code Coverage
Date: 2009-11-21 Instrumented lines: 132
Code covered: 34.1 % Executed lines: 45
Legend: not executed executed

       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                 : static double collator_u_strtod(const UChar *nptr, UChar **endptr) /* {{{ */
      35               0 : {
      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                 : static long collator_u_strtol(nptr, endptr, base)
     129                 :         const UChar *nptr;
     130                 :         UChar **endptr;
     131                 :         register int base;
     132             204 : {
     133             204 :         register const UChar *s = nptr;
     134                 :         register unsigned long acc;
     135                 :         register UChar c;
     136                 :         register unsigned long cutoff;
     137             204 :         register int neg = 0, any, cutlim;
     138                 : 
     139             204 :         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             210 :                 c = *s++;
     154             210 :         } while (u_isspace(c));
     155             204 :         if (c == 0x2D /*'-'*/) {
     156               0 :                 neg = 1;
     157               0 :                 c = *s++;
     158             204 :         } else if (c == 0x2B /*'+'*/)
     159               0 :                 c = *s++;
     160             204 :         if ((base == 0 || base == 16) &&
     161                 :             (c == 0x30 /*'0'*/)
     162                 :                  && (*s == 0x78 /*'x'*/ || *s == 0x58 /*'X'*/)) {
     163               0 :                 c = s[1];
     164               0 :                 s += 2;
     165               0 :                 base = 16;
     166                 :         }
     167             204 :         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             204 :         cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX;
     188             204 :         cutlim = cutoff % (unsigned long)base;
     189             204 :         cutoff /= (unsigned long)base;
     190             302 :         for (acc = 0, any = 0;; c = *s++) {
     191             400 :                 if (c >= 0x30 /*'0'*/ && c <= 0x39 /*'9'*/)
     192              98 :                         c -= 0x30 /*'0'*/;
     193             204 :                 else if (c >= 0x41 /*'A'*/ && c <= 0x5A /*'Z'*/)
     194               0 :                         c -= 0x41 /*'A'*/ - 10;
     195             204 :                 else if (c >= 0x61 /*'a'*/ && c <= 0x7A /*'z'*/)
     196             106 :                         c -= 0x61 /*'a'*/ - 10;
     197                 :                 else
     198                 :                         break;
     199             204 :                 if (c >= base)
     200             106 :                         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             204 :         if (any < 0) {
     211               0 :                 acc = neg ? LONG_MIN : LONG_MAX;
     212               0 :                 errno = ERANGE;
     213             204 :         } else if (neg)
     214               0 :                 acc = -acc;
     215             204 :         if (endptr != NULL)
     216             204 :                 *endptr = (UChar *)(any ? s - 1 : nptr);
     217             204 :         return (acc);
     218                 : }
     219                 : /* }}} */
     220                 : 
     221                 : 
     222                 : /* {{{ collator_is_numeric]
     223                 :  * Taken from PHP6:is_numeric_unicode()
     224                 :  */
     225                 : zend_uchar collator_is_numeric( UChar *str, int length, long *lval, double *dval, int allow_errors )
     226             212 : {
     227                 :         long local_lval;
     228                 :         double local_dval;
     229                 :         UChar *end_ptr_long, *end_ptr_double;
     230             212 :         int conv_base=10;
     231                 : 
     232             212 :         if (!length) {
     233               8 :                 return 0;
     234                 :         }
     235                 : 
     236                 :         /* handle hex numbers */
     237             204 :         if (length>=2 && str[0]=='0' && (str[1]=='x' || str[1]=='X')) {
     238               0 :                 conv_base=16;
     239                 :         }
     240                 : 
     241             204 :         errno=0;
     242             204 :         local_lval = collator_u_strtol(str, &end_ptr_long, conv_base);
     243             204 :         if (errno != ERANGE) {
     244             204 :                 if (end_ptr_long == str+length) { /* integer string */
     245              46 :                         if (lval) {
     246              46 :                                 *lval = local_lval;
     247                 :                         }
     248              46 :                         return IS_LONG;
     249             158 :                 } else if (end_ptr_long == str && *end_ptr_long != '\0' && *str != '.' && *str != '-') { /* ignore partial string matches */
     250             158 :                         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: LTP GCOV extension version 1.5

Generated at Sat, 21 Nov 2009 12:27:01 +0000 (3 days ago)

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