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/grapheme - grapheme_util.c
Test: PHP Code Coverage
Date: 2009-11-21 Instrumented lines: 251
Code covered: 76.5 % Executed lines: 192
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                 :    | Author: Ed Batutis <ed@batutis.com>                                  |
      14                 :    +----------------------------------------------------------------------+
      15                 :  */
      16                 : 
      17                 : /* {{{ includes */
      18                 : #ifdef HAVE_CONFIG_H
      19                 : #include "config.h"
      20                 : #endif
      21                 : 
      22                 : #include <php.h>
      23                 : #include "grapheme.h"
      24                 : #include "grapheme_util.h"
      25                 : #include "intl_common.h"
      26                 : 
      27                 : #include <unicode/utypes.h>
      28                 : #include <unicode/ucol.h>
      29                 : #include <unicode/ustring.h>
      30                 : #include <unicode/ubrk.h>
      31                 : 
      32                 : #include "ext/standard/php_string.h"
      33                 : 
      34                 : ZEND_EXTERN_MODULE_GLOBALS( intl )
      35                 : 
      36                 : /* }}} */
      37                 : 
      38                 : /* {{{ grapheme_close_global_iterator - clean up */
      39                 : void
      40                 : grapheme_close_global_iterator( TSRMLS_D )
      41               1 : {
      42               1 :         UBreakIterator *global_break_iterator = INTL_G( grapheme_iterator );
      43                 : 
      44               1 :         if ( NULL != global_break_iterator ) {
      45               1 :                 ubrk_close(global_break_iterator);
      46                 :         }
      47               1 : }
      48                 : /* }}} */
      49                 : 
      50                 : /* {{{ grapheme_intl_case_fold: convert string to lowercase */
      51                 : void
      52                 : grapheme_intl_case_fold(UChar** ptr_to_free, UChar **str, int32_t *str_len, UErrorCode *pstatus )
      53             146 : {
      54                 :     UChar *dest;
      55                 :     int32_t dest_len, size_required;
      56                 : 
      57                 :     /* allocate a destination string that is a bit larger than the src, hoping that is enough */
      58             146 :     dest_len = (*str_len) + ( *str_len / 10 );
      59             146 :     dest = (UChar*) eumalloc(dest_len);
      60                 : 
      61             146 :     *pstatus = U_ZERO_ERROR;
      62             146 :     size_required = u_strFoldCase(dest, dest_len, *str, *str_len, U_FOLD_CASE_DEFAULT, pstatus);
      63                 : 
      64             146 :     dest_len = size_required;
      65                 : 
      66             146 :     if ( U_BUFFER_OVERFLOW_ERROR == *pstatus ) {
      67                 : 
      68               0 :         dest = (UChar*) eurealloc(dest, dest_len);
      69                 : 
      70               0 :         *pstatus = U_ZERO_ERROR;
      71               0 :         size_required = u_strFoldCase(dest, dest_len, *str, *str_len, U_FOLD_CASE_DEFAULT, pstatus);
      72                 :     }
      73                 : 
      74             146 :     if ( U_FAILURE(*pstatus) ) {
      75               0 :         return;
      76                 :     }
      77                 : 
      78             146 :     if ( NULL != ptr_to_free) {
      79             146 :         efree(*ptr_to_free);
      80             146 :         *ptr_to_free = dest;
      81                 :     }
      82                 : 
      83             146 :     *str = dest;
      84             146 :     *str_len = dest_len;
      85                 : 
      86             146 :     return;
      87                 : }
      88                 : /* }}} */
      89                 : 
      90                 : /* {{{ grapheme_substr_ascii f='from' - starting point, l='length' */
      91                 : void
      92                 : grapheme_substr_ascii(char *str, int str_len, int f, int l, int argc, char **sub_str, int *sub_str_len)
      93               6 : {
      94               6 :     *sub_str = NULL;
      95                 : 
      96               6 :     if (argc > 2) {
      97               4 :         if ((l < 0 && -l > str_len)) {
      98               0 :             return;
      99               4 :         } else if (l > str_len) {
     100               1 :             l = str_len;
     101                 :         }
     102                 :     } else {
     103               2 :         l = str_len;
     104                 :     }
     105                 : 
     106               6 :     if (f > str_len || (f < 0 && -f > str_len)) {
     107               0 :         return;
     108                 :     }
     109                 : 
     110               6 :     if (l < 0 && (l + str_len - f) < 0) {
     111               0 :         return;
     112                 :     }
     113                 : 
     114                 :     /* if "from" position is negative, count start position from the end
     115                 :      * of the string
     116                 :      */
     117               6 :     if (f < 0) {
     118               0 :         f = str_len + f;
     119               0 :         if (f < 0) {
     120               0 :             f = 0;
     121                 :         }
     122                 :     }
     123                 : 
     124                 : 
     125                 :     /* if "length" position is negative, set it to the length
     126                 :      * needed to stop that many chars from the end of the string
     127                 :      */
     128               6 :     if (l < 0) {
     129               0 :         l = (str_len - f) + l;
     130               0 :         if (l < 0) {
     131               0 :             l = 0;
     132                 :         }
     133                 :     }
     134                 : 
     135               6 :     if (f >= str_len) {
     136               0 :         return;
     137                 :     }
     138                 : 
     139               6 :     if ((f + l) > str_len) {
     140               2 :         l = str_len - f;
     141                 :     }
     142                 : 
     143               6 :     *sub_str = str + f;
     144               6 :     *sub_str_len = l;
     145                 : 
     146               6 :     return;
     147                 : }
     148                 : /* }}} */
     149                 : 
     150                 : /* {{{ grapheme_strrpos_utf16 - strrpos using utf16 */
     151                 : int
     152                 : grapheme_strrpos_utf16(unsigned char *haystack, int32_t haystack_len, unsigned char*needle, int32_t needle_len, int32_t offset, int f_ignore_case TSRMLS_DC)
     153              38 : {
     154                 :     UChar *uhaystack, *puhaystack, *uhaystack_end, *uneedle;
     155                 :     int32_t uhaystack_len, uneedle_len;
     156                 :     UErrorCode status;
     157                 :     unsigned char u_break_iterator_buffer[U_BRK_SAFECLONE_BUFFERSIZE];
     158              38 :     UBreakIterator* bi = NULL;
     159                 :     int ret_pos, pos;
     160                 : 
     161                 :     /* convert the strings to UTF-16. */
     162              38 :     uhaystack = NULL;
     163              38 :     uhaystack_len = 0;
     164              38 :     status = U_ZERO_ERROR;
     165              38 :     intl_convert_utf8_to_utf16(&uhaystack, &uhaystack_len, (char *) haystack, haystack_len, &status );
     166                 : 
     167              38 :     if ( U_FAILURE( status ) ) {
     168                 :         /* Set global error code. */
     169               0 :         intl_error_set_code( NULL, status TSRMLS_CC );
     170                 : 
     171                 :         /* Set error messages. */
     172               0 :         intl_error_set_custom_msg( NULL, "Error converting input string to UTF-16", 1 TSRMLS_CC );
     173               0 :         efree( uhaystack );
     174               0 :         return -1;
     175                 :     }
     176                 : 
     177              38 :     if ( f_ignore_case ) {
     178              19 :         grapheme_intl_case_fold(&uhaystack, &uhaystack, &uhaystack_len, &status );
     179                 :     }
     180                 : 
     181                 :     /* get a pointer to the haystack taking into account the offset */
     182              38 :     bi = NULL;
     183              38 :     status = U_ZERO_ERROR;
     184              38 :     bi = grapheme_get_break_iterator(u_break_iterator_buffer, &status TSRMLS_CC );
     185                 : 
     186              38 :     puhaystack = grapheme_get_haystack_offset(bi, uhaystack, uhaystack_len, offset);
     187                 : 
     188              38 :     if ( NULL == puhaystack ) {
     189               0 :         intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "grapheme_strpos: Offset not contained in string", 1 TSRMLS_CC );
     190               0 :         efree( uhaystack );
     191               0 :         ubrk_close (bi);
     192               0 :         return -1;
     193                 :     }
     194                 : 
     195              38 :     uneedle = NULL;
     196              38 :     uneedle_len = 0;
     197              38 :     status = U_ZERO_ERROR;
     198              38 :     intl_convert_utf8_to_utf16(&uneedle, &uneedle_len, (char *) needle, needle_len, &status );
     199                 : 
     200              38 :     if ( U_FAILURE( status ) ) {
     201                 :         /* Set global error code. */
     202               0 :         intl_error_set_code( NULL, status TSRMLS_CC );
     203                 : 
     204                 :         /* Set error messages. */
     205               0 :         intl_error_set_custom_msg( NULL, "Error converting input string to UTF-16", 1 TSRMLS_CC );
     206               0 :         efree( uhaystack );
     207               0 :         efree( uneedle );
     208               0 :         ubrk_close (bi);
     209               0 :         return -1;
     210                 :     }
     211                 : 
     212              38 :     if ( f_ignore_case ) {
     213              19 :         grapheme_intl_case_fold(&uneedle, &uneedle, &uneedle_len, &status );
     214                 :     }
     215                 : 
     216              38 :     ret_pos = -1;   /* -1 represents 'not found' */
     217                 : 
     218                 :     /* back up until there's needle_len characters to compare */
     219                 : 
     220              38 :     uhaystack_end = uhaystack + uhaystack_len;
     221              38 :     pos = ubrk_last(bi);
     222              38 :     puhaystack = uhaystack + pos;
     223                 : 
     224             166 :     while ( uhaystack_end - puhaystack < uneedle_len ) {
     225                 : 
     226              94 :         pos = ubrk_previous(bi);
     227                 : 
     228              94 :         if ( UBRK_DONE == pos ) {
     229               4 :             break;
     230                 :         }
     231                 : 
     232              90 :         puhaystack = uhaystack + pos;
     233                 :     }
     234                 : 
     235                 :     /* is there enough haystack left to hold the needle? */
     236              38 :     if ( ( uhaystack_end - puhaystack ) < uneedle_len ) {
     237                 :         /* not enough, not found */
     238               4 :         goto exit;
     239                 :     }
     240                 : 
     241             108 :     while ( UBRK_DONE != pos ) {
     242                 : 
     243              66 :         if (!u_memcmp(uneedle, puhaystack, uneedle_len)) {  /* needle_len - 1 in zend memnstr? */
     244                 : 
     245                 :             /* does the grapheme in the haystack end at the same place as the last grapheme in the needle? */
     246                 : 
     247              30 :             if ( ubrk_isBoundary(bi, pos + uneedle_len) ) {
     248                 : 
     249                 :                 /* found it, get grapheme count offset */
     250              26 :                 ret_pos = grapheme_count_graphemes(bi, uhaystack, pos);
     251              26 :                 break;
     252                 :             }
     253                 : 
     254                 :             /* set position back */
     255               4 :             ubrk_isBoundary(bi, pos);
     256                 :         }
     257                 : 
     258              40 :         pos = ubrk_previous(bi);
     259              40 :         puhaystack = uhaystack + pos;
     260                 :     }
     261                 : 
     262              38 : exit:
     263              38 :     efree( uhaystack );
     264              38 :     efree( uneedle );
     265              38 :     ubrk_close (bi);
     266                 : 
     267              38 :     return ret_pos;
     268                 : }
     269                 : 
     270                 : /* }}} */
     271                 : 
     272                 : /* {{{ grapheme_strpos_utf16 - strrpos using utf16*/
     273                 : int
     274                 : grapheme_strpos_utf16(unsigned char *haystack, int32_t haystack_len, unsigned char*needle, int32_t needle_len, int32_t offset, int32_t *puchar_pos, int f_ignore_case TSRMLS_DC)
     275              88 : {
     276                 :         UChar *uhaystack, *puhaystack, *uneedle;
     277                 :         int32_t uhaystack_len, uneedle_len;
     278                 :         int ret_pos;
     279                 :         unsigned char u_break_iterator_buffer[U_BRK_SAFECLONE_BUFFERSIZE];
     280                 :         UBreakIterator* bi;
     281                 :         UErrorCode status;
     282                 : 
     283              88 :         *puchar_pos = -1;
     284                 : 
     285                 :         /* convert the strings to UTF-16. */
     286                 : 
     287              88 :         uhaystack = NULL;
     288              88 :         uhaystack_len = 0;
     289              88 :         status = U_ZERO_ERROR;
     290              88 :         intl_convert_utf8_to_utf16(&uhaystack, &uhaystack_len, (char *) haystack, haystack_len, &status );
     291                 : 
     292              88 :         if ( U_FAILURE( status ) ) {
     293                 :                 /* Set global error code. */
     294               0 :                 intl_error_set_code( NULL, status TSRMLS_CC );
     295                 : 
     296                 :                 /* Set error messages. */
     297               0 :                 intl_error_set_custom_msg( NULL, "Error converting input string to UTF-16", 1 TSRMLS_CC );
     298               0 :                 efree( uhaystack );
     299               0 :                 return -1;
     300                 :         }
     301                 : 
     302                 :         /* get a pointer to the haystack taking into account the offset */
     303              88 :         bi = NULL;
     304              88 :         status = U_ZERO_ERROR;
     305              88 :         bi = grapheme_get_break_iterator(u_break_iterator_buffer, &status TSRMLS_CC );
     306                 :         
     307              88 :         puhaystack = grapheme_get_haystack_offset(bi, uhaystack, uhaystack_len, offset);
     308              88 :         uhaystack_len = (uhaystack_len - ( puhaystack - uhaystack));
     309                 : 
     310              88 :         if ( NULL == puhaystack ) {
     311                 :         
     312               0 :                 intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "grapheme_strpos: Offset not contained in string", 1 TSRMLS_CC );
     313                 :                 
     314               0 :                 efree( uhaystack );
     315               0 :                 ubrk_close (bi);
     316                 :                                         
     317               0 :                 return -1;
     318                 :         }
     319                 : 
     320              88 :         if ( f_ignore_case ) {
     321              54 :                 grapheme_intl_case_fold(&uhaystack, &puhaystack, &uhaystack_len, &status );
     322                 :         }
     323                 : 
     324              88 :         uneedle = NULL;
     325              88 :         uneedle_len = 0;
     326              88 :         status = U_ZERO_ERROR;
     327              88 :         intl_convert_utf8_to_utf16(&uneedle, &uneedle_len, (char *) needle, needle_len, &status );
     328                 : 
     329              88 :         if ( U_FAILURE( status ) ) {
     330                 :                 /* Set global error code. */
     331               0 :                 intl_error_set_code( NULL, status TSRMLS_CC );
     332                 : 
     333                 :                 /* Set error messages. */
     334               0 :                 intl_error_set_custom_msg( NULL, "Error converting input string to UTF-16", 1 TSRMLS_CC );
     335               0 :                 efree( uhaystack );
     336               0 :                 efree( uneedle );
     337               0 :                 ubrk_close (bi);
     338                 :                 
     339               0 :                 return -1;
     340                 :         }
     341                 : 
     342              88 :         if ( f_ignore_case ) {
     343              54 :                 grapheme_intl_case_fold(&uneedle, &uneedle, &uneedle_len, &status );
     344                 :         }
     345                 : 
     346              88 :         ret_pos = grapheme_memnstr_grapheme(bi, puhaystack, uneedle, uneedle_len, puhaystack + uhaystack_len );
     347                 :         
     348              88 :         *puchar_pos = ubrk_current(bi);
     349                 : 
     350              88 :         efree( uhaystack );
     351              88 :         efree( uneedle );
     352              88 :         ubrk_close (bi);
     353                 : 
     354              88 :         return ret_pos;
     355                 : }
     356                 : 
     357                 : /* }}} */
     358                 : 
     359                 : /* {{{ grapheme_ascii_check: ASCII check */
     360                 : int grapheme_ascii_check(const unsigned char *day, int32_t len)
     361             349 : {
     362             349 :         int ret_len = len;
     363            1489 :         while ( len-- ) {
     364            1000 :         if ( *day++ > 0x7f )
     365             209 :                 return -1;
     366                 :         }
     367                 : 
     368             140 :         return ret_len;
     369                 : }
     370                 : 
     371                 : /* }}} */
     372                 : 
     373                 : /* {{{ grapheme_split_string: find and optionally return grapheme boundaries */
     374                 : int grapheme_split_string(const UChar *text, int32_t text_length, int boundary_array[], int boundary_array_len TSRMLS_DC )
     375               4 : {
     376                 :         unsigned char u_break_iterator_buffer[U_BRK_SAFECLONE_BUFFERSIZE];
     377               4 :         UErrorCode              status = U_ZERO_ERROR;
     378                 :         int ret_len, pos;
     379                 :         UBreakIterator* bi;
     380                 : 
     381               4 :         bi = grapheme_get_break_iterator((void*)u_break_iterator_buffer, &status TSRMLS_CC );
     382                 : 
     383               4 :         if( U_FAILURE(status) ) {
     384               0 :                 return -1;
     385                 :         }
     386                 :         
     387               4 :         ubrk_setText(bi, text, text_length,     &status);
     388                 : 
     389               4 :         pos = 0;
     390                 :         
     391              29 :         for ( ret_len = 0; pos != UBRK_DONE; ) {
     392                 :         
     393              21 :                 pos = ubrk_next(bi);
     394                 :                 
     395              21 :                 if ( pos != UBRK_DONE ) {
     396                 :                 
     397              17 :                         if ( NULL != boundary_array && ret_len < boundary_array_len ) {
     398               0 :                                 boundary_array[ret_len] = pos;
     399                 :                         }
     400                 : 
     401              17 :                         ret_len++;
     402                 :                 }
     403                 :         }
     404                 :                         
     405               4 :         ubrk_close(bi);
     406                 :         
     407               4 :         return ret_len;
     408                 : }
     409                 : /* }}} */
     410                 : 
     411                 : /* {{{ grapheme_count_graphemes */
     412                 : inline int32_t
     413                 : grapheme_count_graphemes(UBreakIterator *bi, UChar *string, int32_t string_len)
     414              97 : {
     415              97 :         int ret_len = 0;
     416              97 :         int pos = 0;
     417              97 :         UErrorCode              status = U_ZERO_ERROR;
     418                 :         
     419              97 :         ubrk_setText(bi, string, string_len, &status);
     420                 : 
     421                 :         do {
     422                 :         
     423             341 :                 pos = ubrk_next(bi);
     424                 :                 
     425             341 :                 if ( UBRK_DONE != pos ) {
     426             244 :                         ret_len++;
     427                 :                 }
     428                 :                 
     429             341 :         } while ( UBRK_DONE != pos );
     430                 :         
     431              97 :         return ret_len;
     432                 : }
     433                 : /* }}} */
     434                 : 
     435                 : /* {{{ grapheme_memnstr_grapheme: find needle in haystack using grapheme boundaries */
     436                 : inline int32_t
     437                 : grapheme_memnstr_grapheme(UBreakIterator *bi, UChar *haystack, UChar *needle, int32_t needle_len, UChar *end)
     438              88 : {
     439              88 :         UChar *p = haystack;
     440              88 :         UChar ne = needle[needle_len-1];
     441                 :         UErrorCode status;
     442                 :         int32_t grapheme_offset;
     443                 :         
     444              88 :         end -= needle_len;
     445                 : 
     446             232 :         while (p <= end) {
     447                 : 
     448             142 :                 if ((p = u_memchr(p, *needle, (end-p+1))) && ne == p[needle_len-1]) {
     449                 : 
     450              89 :                         if (!u_memcmp(needle, p, needle_len - 1)) {  /* needle_len - 1 works because if needle_len is 1, we've already tested the char */
     451                 : 
     452                 :                                 /* does the grapheme end here? */
     453                 : 
     454              89 :                                 status = U_ZERO_ERROR;
     455              89 :                                 ubrk_setText (bi, haystack, (end - haystack) + needle_len, &status);
     456                 : 
     457              89 :                                 if ( ubrk_isBoundary (bi, (p - haystack) + needle_len) ) {
     458                 : 
     459                 :                                         /* found it, get grapheme count offset */
     460              71 :                                         grapheme_offset = grapheme_count_graphemes(bi, haystack, (p - haystack));
     461                 : 
     462              71 :                                         return grapheme_offset;
     463                 :                                 }
     464                 :                         }
     465                 :                 }
     466                 : 
     467              71 :                 if (p == NULL) {
     468              15 :                         return -1;
     469                 :                 }
     470                 : 
     471              56 :                 p++;
     472                 :         }
     473                 : 
     474               2 :         return -1;
     475                 : }
     476                 : 
     477                 : /* }}} */
     478                 : 
     479                 : /* {{{ grapheme_memrstr_grapheme: reverse find needle in haystack using grapheme boundaries */
     480                 : inline void *grapheme_memrchr_grapheme(const void *s, int c, int32_t n)
     481               0 : {
     482                 :         register unsigned char *e;
     483                 : 
     484               0 :         if (n <= 0) {
     485               0 :                 return NULL;
     486                 :         }
     487                 : 
     488               0 :         for (e = (unsigned char *)s + n - 1; e >= (unsigned char *)s; e--) {
     489               0 :                 if (*e == (unsigned char)c) {
     490               0 :                         return (void *)e;
     491                 :                 }
     492                 :         }
     493                 : 
     494               0 :         return NULL;
     495                 : }
     496                 : /* }}} */
     497                 : 
     498                 : /* {{{  grapheme_get_haystack_offset - bump the haystack pointer based on the grapheme count offset */
     499                 : UChar *
     500                 : grapheme_get_haystack_offset(UBreakIterator* bi, UChar *uhaystack, int32_t uhaystack_len, int32_t offset)
     501             126 : {
     502                 :         UErrorCode              status;
     503                 :         int32_t pos;
     504                 :         int32_t (*iter_op)(UBreakIterator* bi);
     505                 :         int iter_incr;
     506                 : 
     507             126 :         if ( NULL != bi ) {
     508             126 :                 status = U_ZERO_ERROR;
     509             126 :                 ubrk_setText (bi, uhaystack, uhaystack_len, &status);
     510                 :         }
     511                 : 
     512             126 :         if ( 0 == offset ) {
     513             110 :                 return uhaystack;
     514                 :         }
     515                 :         
     516              16 :         if ( offset < 0 ) {
     517               0 :                 iter_op = ubrk_previous;
     518               0 :                 ubrk_last(bi); /* one past the end */
     519               0 :                 iter_incr = 1;
     520                 :         }
     521                 :         else {
     522              16 :                 iter_op = ubrk_next;
     523              16 :                 iter_incr = -1;
     524                 :         }
     525                 :         
     526              16 :         pos = 0;
     527                 :         
     528              64 :         while ( pos != UBRK_DONE && offset != 0 ) {
     529                 :         
     530              32 :                 pos = iter_op(bi);
     531                 :                 
     532              32 :                 if ( UBRK_DONE != pos ) {
     533              32 :                         offset += iter_incr;
     534                 :                 }
     535                 :         }
     536                 : 
     537              16 :         if ( offset != 0 ) {
     538               0 :                 return NULL;
     539                 :         }
     540                 :         
     541              16 :         return uhaystack + pos;
     542                 : }
     543                 : /* }}} */
     544                 : 
     545                 : /* {{{ grapheme_strrpos_ascii: borrowed from the php ext/standard/string.c */
     546                 :  int32_t
     547                 : grapheme_strrpos_ascii(unsigned char *haystack, int32_t haystack_len, unsigned char *needle, int32_t needle_len, int32_t offset)
     548              38 : {
     549                 :         unsigned char *p, *e;
     550                 : 
     551              38 :         if (offset >= 0) {
     552              38 :                 p = haystack + offset;
     553              38 :                 e = haystack + haystack_len - needle_len;
     554                 :         } else {
     555               0 :                 p = haystack;
     556               0 :                 if (needle_len > -offset) {
     557               0 :                         e = haystack + haystack_len - needle_len;
     558                 :                 } else {
     559               0 :                         e = haystack + haystack_len + offset;
     560                 :                 }
     561                 :         }
     562                 : 
     563              38 :         if (needle_len == 1) {
     564                 :                 /* Single character search can shortcut memcmps */
     565              52 :                 while (e >= p) {
     566              34 :                         if (*e == *needle) {
     567              10 :                                 return (e - p + (offset > 0 ? offset : 0));
     568                 :                         }
     569              24 :                         e--;
     570                 :                 }
     571               4 :                 return -1;
     572                 :         }
     573                 : 
     574              56 :         while (e >= p) {
     575              22 :                 if (memcmp(e, needle, needle_len) == 0) {
     576              14 :                         return (e - p + (offset > 0 ? offset : 0));
     577                 :                 }
     578               8 :                 e--;
     579                 :         }
     580                 : 
     581              10 :         return -1;
     582                 : }
     583                 : 
     584                 : /* }}} */
     585                 : 
     586                 : /* {{{ grapheme_get_break_iterator: get a clone of the global character break iterator */
     587                 : UBreakIterator* 
     588                 : grapheme_get_break_iterator(void *stack_buffer, UErrorCode *status TSRMLS_DC )
     589             244 : {
     590                 :         int32_t buffer_size;
     591                 : 
     592             244 :         UBreakIterator *global_break_iterator = INTL_G( grapheme_iterator );
     593                 : 
     594             244 :         if ( NULL == global_break_iterator ) {
     595                 : 
     596               1 :                 global_break_iterator = ubrk_open(UBRK_CHARACTER, 
     597                 :                                                                                         NULL,   /* icu default locale - locale has no effect on this iterator */
     598                 :                                                                                         NULL,   /* text not set in global iterator */
     599                 :                                                                                         0,              /* text length = 0 */
     600                 :                                                                                         status);
     601                 : 
     602               1 :                 INTL_G(grapheme_iterator) = global_break_iterator;
     603                 :         }
     604                 : 
     605             244 :         buffer_size = U_BRK_SAFECLONE_BUFFERSIZE;
     606                 : 
     607             244 :         return ubrk_safeClone(global_break_iterator, stack_buffer, &buffer_size, status);
     608                 : }
     609                 : /* }}} */
     610                 : 
     611                 : /*
     612                 :  * Local variables:
     613                 :  * tab-width: 4
     614                 :  * c-basic-offset: 4
     615                 :  * End:
     616                 :  * vim600: fdm=marker
     617                 :  * vim: noet sw=4 ts=4
     618                 :  */
     619                 : 

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.