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 - standard - strnatcmp.c
Test: PHP Code Coverage
Date: 2009-11-21 Instrumented lines: 72
Code covered: 97.2 % Executed lines: 70
Legend: not executed executed

       1                 : /* -*- mode: c; c-file-style: "k&r" -*-
       2                 : 
       3                 :   Modified for PHP by Andrei Zmievski <andrei@ispi.net>
       4                 : 
       5                 :   strnatcmp.c -- Perform 'natural order' comparisons of strings in C.
       6                 :   Copyright (C) 2000 by Martin Pool <mbp@humbug.org.au>
       7                 : 
       8                 :   This software is provided 'as-is', without any express or implied
       9                 :   warranty.  In no event will the authors be held liable for any damages
      10                 :   arising from the use of this software.
      11                 : 
      12                 :   Permission is granted to anyone to use this software for any purpose,
      13                 :   including commercial applications, and to alter it and redistribute it
      14                 :   freely, subject to the following restrictions:
      15                 : 
      16                 :   1. The origin of this software must not be misrepresented; you must not
      17                 :      claim that you wrote the original software. If you use this software
      18                 :      in a product, an acknowledgment in the product documentation would be
      19                 :      appreciated but is not required.
      20                 :   2. Altered source versions must be plainly marked as such, and must not be
      21                 :      misrepresented as being the original software.
      22                 :   3. This notice may not be removed or altered from any source distribution.
      23                 : */
      24                 : 
      25                 : #include <ctype.h>
      26                 : #include <string.h>
      27                 : #include <assert.h>
      28                 : #include <stdio.h>
      29                 : 
      30                 : #include "php.h"
      31                 : #include "php_string.h"
      32                 : 
      33                 : #if defined(__GNUC__)
      34                 : #  define UNUSED __attribute__((__unused__))
      35                 : #else
      36                 : #  define UNUSED
      37                 : #endif
      38                 : 
      39                 : #if 0
      40                 : static char const *version UNUSED =
      41                 :     "$Id: strnatcmp.c 288896 2009-09-28 13:29:53Z rasmus $";
      42                 : #endif
      43                 : /* {{{ compare_right
      44                 :  */
      45                 : static int
      46                 : compare_right(char const **a, char const *aend, char const **b, char const *bend)
      47             148 : {
      48             148 :         int bias = 0;
      49                 : 
      50                 :         /* The longest run of digits wins.  That aside, the greatest
      51                 :            value wins, but we can't know that it will until we've scanned
      52                 :            both numbers to know that they have the same magnitude, so we
      53                 :            remember it in BIAS. */
      54             268 :         for(;; (*a)++, (*b)++) {
      55             416 :                 if ((*a == aend || !isdigit((int)(unsigned char)**a)) &&
      56                 :                         (*b == bend || !isdigit((int)(unsigned char)**b)))
      57              81 :                         return bias;
      58             335 :                 else if (*a == aend || !isdigit((int)(unsigned char)**a))
      59              28 :                         return -1;
      60             307 :                 else if (*b == bend || !isdigit((int)(unsigned char)**b))
      61              39 :                         return +1;
      62             268 :                 else if (**a < **b) {
      63              81 :                         if (!bias)
      64              52 :                                 bias = -1;
      65             187 :                 } else if (**a > **b) {
      66              94 :                         if (!bias)
      67              66 :                                 bias = +1;
      68                 :                 }
      69             268 :      }
      70                 : 
      71                 :      return 0;
      72                 : }
      73                 : /* }}} */
      74                 : 
      75                 : /* {{{ compare_left
      76                 :  */
      77                 : static int
      78                 : compare_left(char const **a, char const *aend, char const **b, char const *bend)
      79              95 : {
      80                 :      /* Compare two left-aligned numbers: the first to have a
      81                 :         different value wins. */
      82              27 :         for(;; (*a)++, (*b)++) {
      83              95 :                 if ((*a == aend || !isdigit((int)(unsigned char)**a)) &&
      84                 :                         (*b == bend || !isdigit((int)(unsigned char)**b)))
      85              21 :                         return 0;
      86              74 :                 else if (*a == aend || !isdigit((int)(unsigned char)**a))
      87               0 :                         return -1;
      88              74 :                 else if (*b == bend || !isdigit((int)(unsigned char)**b))
      89               0 :                         return +1;
      90              74 :                  else if (**a < **b)
      91              28 :                          return -1;
      92              46 :                  else if (**a > **b)
      93              19 :                          return +1;
      94              27 :      }
      95                 :           
      96                 :      return 0;
      97                 : }
      98                 : /* }}} */
      99                 : 
     100                 : /* {{{ strnatcmp_ex
     101                 :  */
     102                 : PHPAPI int strnatcmp_ex(char const *a, size_t a_len, char const *b, size_t b_len, int fold_case)
     103             499 : {
     104                 :         unsigned char ca, cb;
     105                 :         char const *ap, *bp;
     106             499 :         char const *aend = a + a_len,
     107             499 :                            *bend = b + b_len;
     108                 :         int fractional, result;
     109             499 :         short leading = 1;
     110                 : 
     111             499 :         if (a_len == 0 || b_len == 0)
     112              22 :                 return a_len - b_len;
     113                 : 
     114             477 :         ap = a;
     115             477 :         bp = b;
     116                 :         while (1) {
     117             811 :                 ca = *ap; cb = *bp;
     118                 : 
     119                 :                 /* skip over leading zeros */
     120            1690 :                 while (leading && ca == '0' && (ap+1 < aend) && isdigit(*(ap+1))) {
     121              68 :                         ca = *++ap;
     122                 :                 }
     123                 : 
     124            1667 :                 while (leading && cb == '0' && (bp+1 < bend) && isdigit(*(bp+1))) {
     125              45 :                         cb = *++bp;
     126                 :                 }
     127                 : 
     128             811 :                 leading = 0;
     129                 : 
     130                 :                 /* Skip consecutive whitespace */
     131            1635 :                 while (isspace((int)(unsigned char)ca)) {
     132              13 :                         ca = *++ap;
     133                 :                 }
     134                 : 
     135            1636 :                 while (isspace((int)(unsigned char)cb)) {
     136              14 :                         cb = *++bp;
     137                 :                 }
     138                 : 
     139                 :                 /* process run of digits */
     140             811 :                 if (isdigit((int)(unsigned char)ca)  &&  isdigit((int)(unsigned char)cb)) {
     141             216 :                         fractional = (ca == '0' || cb == '0');
     142                 : 
     143             216 :                         if (fractional)
     144              68 :                                 result = compare_left(&ap, aend, &bp, bend);
     145                 :                         else
     146             148 :                                 result = compare_right(&ap, aend, &bp, bend);
     147                 : 
     148             216 :                         if (result != 0)
     149             185 :                                 return result;
     150              31 :                         else if (ap == aend && bp == bend)
     151                 :                                 /* End of the strings. Let caller sort them out. */
     152              11 :                                 return 0;
     153                 :                         else {
     154                 :                                 /* Keep on comparing from the current point. */
     155              20 :                                 ca = *ap; cb = *bp;
     156                 :                         }
     157                 :                 }
     158                 : 
     159             615 :                 if (fold_case) {
     160             493 :                         ca = toupper((int)(unsigned char)ca);
     161             493 :                         cb = toupper((int)(unsigned char)cb);
     162                 :                 }
     163                 : 
     164             615 :                 if (ca < cb)
     165              95 :                         return -1;
     166             520 :                 else if (ca > cb)
     167             156 :                         return +1;
     168                 : 
     169             364 :                 ++ap; ++bp;
     170             364 :                 if (ap >= aend && bp >= bend)
     171                 :                         /* The strings compare the same.  Perhaps the caller
     172                 :                            will want to call strcmp to break the tie. */
     173              25 :                         return 0;
     174             339 :                 else if (ap >= aend)
     175               2 :                         return -1;
     176             337 :                 else if (bp >= bend)
     177               3 :                         return 1;
     178             334 :         }
     179                 : }
     180                 : /* }}} */
     181                 : 
     182                 : /*
     183                 :  * Local variables:
     184                 :  * tab-width: 4
     185                 :  * c-basic-offset: 4
     186                 :  * End:
     187                 :  * vim600: sw=4 ts=4 fdm=marker
     188                 :  * vim<600: sw=4 ts=4
     189                 :  */

Generated by: LTP GCOV extension version 1.5

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

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