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 - reg.c
Test: PHP Code Coverage
Date: 2009-11-19 Instrumented lines: 308
Code covered: 87.7 % Executed lines: 270
Legend: not executed executed

       1                 : /*
       2                 :    +----------------------------------------------------------------------+
       3                 :    | PHP Version 5                                                        |
       4                 :    +----------------------------------------------------------------------+
       5                 :    | Copyright (c) 1997-2009 The PHP Group                                |
       6                 :    +----------------------------------------------------------------------+
       7                 :    | This source file is subject to version 3.01 of the PHP license,      |
       8                 :    | that is bundled with this package in the file LICENSE, and is        |
       9                 :    | available through the world-wide-web at the following url:           |
      10                 :    | http://www.php.net/license/3_01.txt                                  |
      11                 :    | If you did not receive a copy of the PHP license and are unable to   |
      12                 :    | obtain it through the world-wide-web, please send a note to          |
      13                 :    | license@php.net so we can mail you a copy immediately.               |
      14                 :    +----------------------------------------------------------------------+
      15                 :    | Authors: Rasmus Lerdorf <rasmus@php.net>                             |
      16                 :    |          Jim Winstead <jimw@php.net>                                 |
      17                 :    |          Jaakko Hyvätti <jaakko@hyvatti.iki.fi>                      | 
      18                 :    +----------------------------------------------------------------------+
      19                 :  */
      20                 : /* $Id: reg.c 281355 2009-05-29 00:03:28Z scottmac $ */
      21                 : 
      22                 : #include <stdio.h>
      23                 : #include <ctype.h>
      24                 : #include "php.h"
      25                 : #include "php_string.h"
      26                 : #include "reg.h"
      27                 : #include "ext/standard/info.h"
      28                 : 
      29                 : ZEND_DECLARE_MODULE_GLOBALS(reg)
      30                 : 
      31                 : typedef struct {
      32                 :         regex_t preg;
      33                 :         int cflags;
      34                 :         unsigned int lastuse;
      35                 : } reg_cache;
      36                 : 
      37                 : static int reg_magic = 0;
      38                 : #define EREG_CACHE_SIZE 4096
      39                 : 
      40                 : /* {{{ ereg_lru_cmp */
      41                 : static int ereg_lru_cmp(const void *a, const void *b TSRMLS_DC)
      42               0 : {
      43               0 :         Bucket *f = *((Bucket **) a);
      44               0 :         Bucket *s = *((Bucket **) b);
      45                 : 
      46               0 :         if (((reg_cache *)f->pData)->lastuse <
      47                 :                                 ((reg_cache *)s->pData)->lastuse) {
      48               0 :                 return -1;
      49               0 :         } else if (((reg_cache *)f->pData)->lastuse ==
      50                 :                                 ((reg_cache *)s->pData)->lastuse) {
      51               0 :                 return 0;
      52                 :         } else {
      53               0 :                 return 1;
      54                 :         }
      55                 : }
      56                 : /* }}} */
      57                 : 
      58                 : /* {{{ static ereg_clean_cache */
      59                 : static int ereg_clean_cache(void *data, void *arg TSRMLS_DC)
      60               0 : {
      61               0 :         int *num_clean = (int *)arg;
      62                 : 
      63               0 :         if (*num_clean > 0) {
      64               0 :                 (*num_clean)--;
      65               0 :                 return ZEND_HASH_APPLY_REMOVE;
      66                 :         } else {
      67               0 :                 return ZEND_HASH_APPLY_STOP;
      68                 :         }
      69                 : }
      70                 : /* }}} */
      71                 : 
      72                 : /* {{{ _php_regcomp
      73                 :  */
      74                 : static int _php_regcomp(regex_t *preg, const char *pattern, int cflags)
      75             795 : {
      76             795 :         int r = 0;
      77             795 :         int patlen = strlen(pattern);
      78             795 :         reg_cache *rc = NULL;
      79                 :         TSRMLS_FETCH();
      80                 : 
      81             795 :         if (zend_hash_num_elements(&REG(ht_rc)) >= EREG_CACHE_SIZE) {
      82               0 :                 if (REG(lru_counter) >= (1 << 31) || zend_hash_sort(&REG(ht_rc), zend_qsort, ereg_lru_cmp, 0 TSRMLS_CC) == FAILURE) {
      83               0 :                         zend_hash_clean(&REG(ht_rc));
      84               0 :                         REG(lru_counter) = 0;
      85                 :                 } else {
      86               0 :                         int num_clean = EREG_CACHE_SIZE / 2;
      87               0 :                         zend_hash_apply_with_argument(&REG(ht_rc), ereg_clean_cache, &num_clean TSRMLS_CC);
      88                 :                 }
      89                 :         }
      90                 : 
      91             795 :         if(zend_hash_find(&REG(ht_rc), (char *) pattern, patlen+1, (void **) &rc) == SUCCESS
      92                 :            && rc->cflags == cflags) {
      93                 : #ifdef HAVE_REGEX_T_RE_MAGIC
      94                 :                 /*
      95                 :                  * We use a saved magic number to see whether cache is corrupted, and if it
      96                 :                  * is, we flush it and compile the pattern from scratch.
      97                 :                  */
      98             390 :                 if (rc->preg.re_magic != reg_magic) {
      99               0 :                         zend_hash_clean(&REG(ht_rc));
     100               0 :                         REG(lru_counter) = 0;
     101                 :                 } else {
     102             390 :                         memcpy(preg, &rc->preg, sizeof(*preg));
     103             390 :                         return r;
     104                 :                 }
     105                 :         }
     106                 : 
     107             405 :         r = regcomp(preg, pattern, cflags);
     108             405 :         if(!r) {
     109                 :                 reg_cache rcp;
     110                 : 
     111             259 :                 rcp.cflags = cflags;
     112             259 :                 rcp.lastuse = ++(REG(lru_counter));
     113             259 :                 memcpy(&rcp.preg, preg, sizeof(*preg));
     114                 :                 /*
     115                 :                  * Since we don't have access to the actual MAGIC1 definition in the private
     116                 :                  * header file, we save the magic value immediately after compilation. Hopefully,
     117                 :                  * it's good.
     118                 :                  */
     119             259 :                 if (!reg_magic) reg_magic = preg->re_magic;
     120             259 :                 zend_hash_update(&REG(ht_rc), (char *) pattern, patlen+1,
     121                 :                                                  (void *) &rcp, sizeof(rcp), NULL);
     122                 :         }
     123                 : #else
     124                 :                 memcpy(preg, &rc->preg, sizeof(*preg));
     125                 :         } else {
     126                 :                 r = regcomp(preg, pattern, cflags);
     127                 :                 if(!r) {
     128                 :                         reg_cache rcp;
     129                 : 
     130                 :                         rcp.cflags = cflags;
     131                 :                         rcp.lastuse = ++(REG(lru_counter));
     132                 :                         memcpy(&rcp.preg, preg, sizeof(*preg));
     133                 :                         zend_hash_update(&REG(ht_rc), (char *) pattern, patlen+1,
     134                 :                                                          (void *) &rcp, sizeof(rcp), NULL);
     135                 :                 }
     136                 :         }
     137                 : #endif
     138             405 :         return r;
     139                 : }
     140                 : /* }}} */
     141                 : 
     142                 : static void _free_reg_cache(reg_cache *rc) 
     143             259 : {
     144             259 :         regfree(&rc->preg);
     145             259 : }
     146                 : 
     147                 : #undef regfree
     148                 : #define regfree(a);
     149                 : #undef regcomp
     150                 : #define regcomp(a, b, c) _php_regcomp(a, b, c)
     151                 :         
     152                 : static void php_reg_init_globals(zend_reg_globals *reg_globals TSRMLS_DC)
     153           13565 : {
     154           13565 :         zend_hash_init(&reg_globals->ht_rc, 0, NULL, (void (*)(void *)) _free_reg_cache, 1);
     155           13565 :         reg_globals->lru_counter = 0;
     156           13565 : }
     157                 : 
     158                 : static void php_reg_destroy_globals(zend_reg_globals *reg_globals TSRMLS_DC)
     159           13597 : {
     160           13597 :         zend_hash_destroy(&reg_globals->ht_rc);
     161           13597 : }
     162                 : 
     163                 : PHP_MINIT_FUNCTION(regex)
     164           13565 : {
     165           13565 :         ZEND_INIT_MODULE_GLOBALS(reg, php_reg_init_globals, php_reg_destroy_globals);
     166           13565 :         return SUCCESS;
     167                 : }
     168                 : 
     169                 : PHP_MSHUTDOWN_FUNCTION(regex)
     170           13597 : {
     171                 : #ifndef ZTS
     172           13597 :         php_reg_destroy_globals(&reg_globals TSRMLS_CC);
     173                 : #endif
     174                 : 
     175           13597 :         return SUCCESS;
     176                 : }
     177                 : 
     178                 : PHP_MINFO_FUNCTION(regex)
     179               6 : {
     180                 : #if HSREGEX
     181               6 :         php_info_print_table_row(2, "Regex Library", "Bundled library enabled");
     182                 : #else
     183                 :         php_info_print_table_row(2, "Regex Library", "System library enabled");
     184                 : #endif
     185               6 : }
     186                 : 
     187                 : 
     188                 : /* {{{ php_reg_eprint
     189                 :  * php_reg_eprint - convert error number to name
     190                 :  */
     191             146 : static void php_reg_eprint(int err, regex_t *re) {
     192             146 :         char *buf = NULL, *message = NULL;
     193                 :         size_t len;
     194                 :         size_t buf_len;
     195                 : 
     196                 : #ifdef REG_ITOA
     197                 :         /* get the length of the message */
     198             146 :         buf_len = regerror(REG_ITOA | err, re, NULL, 0);
     199             146 :         if (buf_len) {
     200             146 :                 buf = (char *)safe_emalloc(buf_len, sizeof(char), 0);
     201             146 :                 if (!buf) return; /* fail silently */
     202                 :                 /* finally, get the error message */
     203             146 :                 regerror(REG_ITOA | err, re, buf, buf_len);
     204                 :         }
     205                 : #else
     206                 :         buf_len = 0;
     207                 : #endif
     208             146 :         len = regerror(err, re, NULL, 0);
     209             146 :         if (len) {
     210                 :                 TSRMLS_FETCH();
     211                 : 
     212             146 :                 message = (char *)safe_emalloc((buf_len + len + 2), sizeof(char), 0);
     213             146 :                 if (!message) {
     214               0 :                         return; /* fail silently */
     215                 :                 }
     216             146 :                 if (buf_len) {
     217             146 :                         snprintf(message, buf_len, "%s: ", buf);
     218             146 :                         buf_len += 1; /* so pointer math below works */
     219                 :                 }
     220                 :                 /* drop the message into place */
     221             146 :                 regerror(err, re, message + buf_len, len);
     222                 : 
     223             146 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", message);
     224                 :         }
     225                 : 
     226             146 :         STR_FREE(buf);
     227             146 :         STR_FREE(message);
     228                 : }
     229                 : /* }}} */
     230                 : 
     231                 : /* {{{ php_ereg
     232                 :  */
     233                 : static void php_ereg(INTERNAL_FUNCTION_PARAMETERS, int icase)
     234             253 : {
     235                 :         zval **regex,                   /* Regular expression */
     236                 :                 **findin,               /* String to apply expression to */
     237             253 :                 **array = NULL;         /* Optional register array */
     238                 :         regex_t re;
     239                 :         regmatch_t *subs;
     240                 :         int err, match_len, string_len;
     241                 :         uint i;
     242             253 :         int copts = 0;
     243                 :         off_t start, end;
     244             253 :         char *buf = NULL;
     245             253 :         char *string = NULL;
     246             253 :         int   argc = ZEND_NUM_ARGS();
     247                 :         
     248             253 :         if (argc < 2 || argc > 3 ||
     249                 :             zend_get_parameters_ex(argc, &regex, &findin, &array) == FAILURE) {
     250               4 :                 WRONG_PARAM_COUNT;
     251                 :         }
     252                 : 
     253             249 :         if (icase)
     254             123 :                 copts |= REG_ICASE;
     255                 :         
     256             249 :         if (argc == 2)
     257              57 :                 copts |= REG_NOSUB;
     258                 : 
     259                 :         /* compile the regular expression from the supplied regex */
     260             249 :         if (Z_TYPE_PP(regex) == IS_STRING) {
     261             203 :                 err = regcomp(&re, Z_STRVAL_PP(regex), REG_EXTENDED | copts);
     262                 :         } else {
     263                 :                 /* we convert numbers to integers and treat them as a string */
     264              46 :                 if (Z_TYPE_PP(regex) == IS_DOUBLE)
     265              10 :                         convert_to_long_ex(regex);      /* get rid of decimal places */
     266              46 :                 convert_to_string_ex(regex);
     267                 :                 /* don't bother doing an extended regex with just a number */
     268              46 :                 err = regcomp(&re, Z_STRVAL_PP(regex), copts);
     269                 :         }
     270                 : 
     271             249 :         if (err) {
     272              46 :                 php_reg_eprint(err, &re);
     273              46 :                 RETURN_FALSE;
     274                 :         }
     275                 : 
     276                 :         /* make a copy of the string we're looking in */
     277             203 :         convert_to_string_ex(findin);
     278             203 :         string = estrndup(Z_STRVAL_PP(findin), Z_STRLEN_PP(findin));
     279                 : 
     280                 :         /* allocate storage for (sub-)expression-matches */
     281             203 :         subs = (regmatch_t *)ecalloc(sizeof(regmatch_t),re.re_nsub+1);
     282                 :         
     283                 :         /* actually execute the regular expression */
     284             203 :         err = regexec(&re, string, re.re_nsub+1, subs, 0);
     285             203 :         if (err && err != REG_NOMATCH) {
     286               0 :                 php_reg_eprint(err, &re);
     287                 :                 regfree(&re);
     288               0 :                 efree(subs);
     289               0 :                 RETURN_FALSE;
     290                 :         }
     291             203 :         match_len = 1;
     292                 : 
     293             203 :         if (array && err != REG_NOMATCH) {
     294              99 :                 match_len = (int) (subs[0].rm_eo - subs[0].rm_so);
     295              99 :                 string_len = Z_STRLEN_PP(findin) + 1;
     296                 : 
     297              99 :                 buf = emalloc(string_len);
     298                 : 
     299              99 :                 zval_dtor(*array);      /* start with clean array */
     300              99 :                 array_init(*array);
     301                 : 
     302            4358 :                 for (i = 0; i <= re.re_nsub; i++) {
     303            4259 :                         start = subs[i].rm_so;
     304            4259 :                         end = subs[i].rm_eo;
     305            8510 :                         if (start != -1 && end > 0 && start < string_len && end < string_len && start < end) {
     306            4251 :                                 add_index_stringl(*array, i, string+start, end-start, 1);
     307                 :                         } else {
     308               8 :                                 add_index_bool(*array, i, 0);
     309                 :                         }
     310                 :                 }
     311              99 :                 efree(buf);
     312                 :         }
     313                 : 
     314             203 :         efree(subs);
     315             203 :         efree(string);
     316             203 :         if (err == REG_NOMATCH) {
     317              75 :                 RETVAL_FALSE;
     318                 :         } else {
     319             128 :                 if (match_len == 0)
     320               4 :                         match_len = 1;
     321             128 :                 RETVAL_LONG(match_len);
     322                 :         }
     323                 :         regfree(&re);
     324                 : }
     325                 : /* }}} */
     326                 : 
     327                 : /* {{{ proto int ereg(string pattern, string string [, array registers])
     328                 :    Regular expression match */
     329                 : PHP_FUNCTION(ereg)
     330             128 : {
     331             128 :         php_ereg(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
     332             128 : }
     333                 : /* }}} */
     334                 : 
     335                 : /* {{{ proto int eregi(string pattern, string string [, array registers])
     336                 :    Case-insensitive regular expression match */
     337                 : PHP_FUNCTION(eregi)
     338             125 : {
     339             125 :         php_ereg(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
     340             125 : }
     341                 : /* }}} */
     342                 : 
     343                 : /* {{{ php_reg_replace
     344                 :  * this is the meat and potatoes of regex replacement! */
     345                 : PHPAPI char *php_reg_replace(const char *pattern, const char *replace, const char *string, int icase, int extended)
     346             234 : {
     347                 :         regex_t re;
     348                 :         regmatch_t *subs;
     349                 : 
     350                 :         char *buf,      /* buf is where we build the replaced string */
     351                 :              *nbuf,     /* nbuf is used when we grow the buffer */
     352                 :                  *walkbuf; /* used to walk buf when replacing backrefs */
     353                 :         const char *walk; /* used to walk replacement string for backrefs */
     354                 :         int buf_len;
     355                 :         int pos, tmp, string_len, new_l;
     356             234 :         int err, copts = 0;
     357                 : 
     358             234 :         string_len = strlen(string);
     359                 : 
     360             234 :         if (icase) {
     361             109 :                 copts = REG_ICASE;
     362                 :         }
     363             234 :         if (extended) {
     364             234 :                 copts |= REG_EXTENDED;
     365                 :         }
     366                 : 
     367             234 :         err = regcomp(&re, pattern, copts);
     368             234 :         if (err) {
     369              54 :                 php_reg_eprint(err, &re);
     370              54 :                 return ((char *) -1);
     371                 :         }
     372                 : 
     373                 : 
     374                 :         /* allocate storage for (sub-)expression-matches */
     375             180 :         subs = (regmatch_t *)ecalloc(sizeof(regmatch_t),re.re_nsub+1);
     376                 : 
     377                 :         /* start with a buffer that is twice the size of the stringo
     378                 :            we're doing replacements in */
     379             180 :         buf_len = 2 * string_len + 1;
     380             180 :         buf = safe_emalloc(buf_len, sizeof(char), 0);
     381                 : 
     382             180 :         err = pos = 0;
     383             180 :         buf[0] = '\0';
     384             901 :         while (!err) {
     385             548 :                 err = regexec(&re, &string[pos], re.re_nsub+1, subs, (pos ? REG_NOTBOL : 0));
     386                 : 
     387             548 :                 if (err && err != REG_NOMATCH) {
     388               0 :                         php_reg_eprint(err, &re);
     389               0 :                         efree(subs);
     390               0 :                         efree(buf);
     391                 :                         regfree(&re);
     392               0 :                         return ((char *) -1);
     393                 :                 }
     394                 : 
     395             548 :                 if (!err) {
     396                 :                         /* backref replacement is done in two passes:
     397                 :                            1) find out how long the string will be, and allocate buf
     398                 :                            2) copy the part before match, replacement and backrefs to buf
     399                 : 
     400                 :                            Jaakko Hyvätti <Jaakko.Hyvatti@iki.fi>
     401                 :                            */
     402                 : 
     403             375 :                         new_l = strlen(buf) + subs[0].rm_so; /* part before the match */
     404             375 :                         walk = replace;
     405            7533 :                         while (*walk) {
     406            6793 :                                 if ('\\' == *walk && isdigit((unsigned char)walk[1]) && ((unsigned char)walk[1]) - '0' <= (int)re.re_nsub) {
     407              10 :                                         if (subs[walk[1] - '0'].rm_so > -1 && subs[walk[1] - '0'].rm_eo > -1) {
     408              10 :                                                 new_l += subs[walk[1] - '0'].rm_eo - subs[walk[1] - '0'].rm_so;
     409                 :                                         }    
     410              10 :                                         walk += 2;
     411                 :                                 } else {
     412            6773 :                                         new_l++;
     413            6773 :                                         walk++;
     414                 :                                 }
     415                 :                         }
     416             375 :                         if (new_l + 1 > buf_len) {
     417              37 :                                 buf_len = 1 + buf_len + 2 * new_l;
     418              37 :                                 nbuf = emalloc(buf_len);
     419              37 :                                 strcpy(nbuf, buf);
     420              37 :                                 efree(buf);
     421              37 :                                 buf = nbuf;
     422                 :                         }
     423             375 :                         tmp = strlen(buf);
     424                 :                         /* copy the part of the string before the match */
     425             375 :                         strncat(buf, &string[pos], subs[0].rm_so);
     426                 : 
     427                 :                         /* copy replacement and backrefs */
     428             375 :                         walkbuf = &buf[tmp + subs[0].rm_so];
     429             375 :                         walk = replace;
     430            7533 :                         while (*walk) {
     431            6793 :                                 if ('\\' == *walk && isdigit(walk[1]) && walk[1] - '0' <= (int)re.re_nsub) {
     432              10 :                                         if (subs[walk[1] - '0'].rm_so > -1 && subs[walk[1] - '0'].rm_eo > -1
     433                 :                                                 /* this next case shouldn't happen. it does. */
     434                 :                                                 && subs[walk[1] - '0'].rm_so <= subs[walk[1] - '0'].rm_eo) {
     435                 :                                                 
     436              10 :                                                 tmp = subs[walk[1] - '0'].rm_eo - subs[walk[1] - '0'].rm_so;
     437              10 :                                                 memcpy (walkbuf, &string[pos + subs[walk[1] - '0'].rm_so], tmp);
     438              10 :                                                 walkbuf += tmp;
     439                 :                                         }
     440              10 :                                         walk += 2;
     441                 :                                 } else {
     442            6773 :                                         *walkbuf++ = *walk++;
     443                 :                                 }
     444                 :                         }
     445             375 :                         *walkbuf = '\0';
     446                 : 
     447                 :                         /* and get ready to keep looking for replacements */
     448             375 :                         if (subs[0].rm_so == subs[0].rm_eo) {
     449             144 :                                 if (subs[0].rm_so + pos >= string_len) {
     450               7 :                                         break;
     451                 :                                 }
     452             137 :                                 new_l = strlen (buf) + 1;
     453             137 :                                 if (new_l + 1 > buf_len) {
     454               0 :                                         buf_len = 1 + buf_len + 2 * new_l;
     455               0 :                                         nbuf = safe_emalloc(buf_len, sizeof(char), 0);
     456               0 :                                         strcpy(nbuf, buf);
     457               0 :                                         efree(buf);
     458               0 :                                         buf = nbuf;
     459                 :                                 }
     460             137 :                                 pos += subs[0].rm_eo + 1;
     461             137 :                                 buf [new_l-1] = string [pos-1];
     462             137 :                                 buf [new_l] = '\0';
     463                 :                         } else {
     464             231 :                                 pos += subs[0].rm_eo;
     465                 :                         }
     466                 :                 } else { /* REG_NOMATCH */
     467             173 :                         new_l = strlen(buf) + strlen(&string[pos]);
     468             173 :                         if (new_l + 1 > buf_len) {
     469               8 :                                 buf_len = new_l + 1; /* now we know exactly how long it is */
     470               8 :                                 nbuf = safe_emalloc(buf_len, sizeof(char), 0);
     471               8 :                                 strcpy(nbuf, buf);
     472               8 :                                 efree(buf);
     473               8 :                                 buf = nbuf;
     474                 :                         }
     475                 :                         /* stick that last bit of string on our output */
     476             173 :                         strlcat(buf, &string[pos], buf_len);
     477                 :                 }
     478                 :         }
     479                 : 
     480                 :         /* don't want to leak memory .. */
     481             180 :         efree(subs);
     482                 :         regfree(&re);
     483                 : 
     484                 :         /* whew. */
     485             180 :         return (buf);
     486                 : }
     487                 : /* }}} */
     488                 : 
     489                 : /* {{{ php_ereg_replace
     490                 :  */
     491                 : static void php_ereg_replace(INTERNAL_FUNCTION_PARAMETERS, int icase)
     492             238 : {
     493                 :         zval **arg_pattern,
     494                 :                 **arg_replace,
     495                 :                 **arg_string;
     496                 :         char *pattern;
     497                 :         char *string;
     498                 :         char *replace;
     499                 :         char *ret;
     500                 :         
     501             238 :         if (ZEND_NUM_ARGS() != 3 || 
     502                 :             zend_get_parameters_ex(3, &arg_pattern, &arg_replace, &arg_string) == FAILURE) {
     503               4 :                 WRONG_PARAM_COUNT;
     504                 :         }
     505                 : 
     506             234 :         if (Z_TYPE_PP(arg_pattern) == IS_STRING) {
     507             370 :                 if (Z_STRVAL_PP(arg_pattern) && Z_STRLEN_PP(arg_pattern))
     508             182 :                         pattern = estrndup(Z_STRVAL_PP(arg_pattern), Z_STRLEN_PP(arg_pattern));
     509                 :                 else
     510               6 :                         pattern = STR_EMPTY_ALLOC();
     511                 :         } else {
     512              46 :                 convert_to_long_ex(arg_pattern);
     513              46 :                 pattern = emalloc(2);
     514              46 :                 pattern[0] = (char) Z_LVAL_PP(arg_pattern);
     515              46 :                 pattern[1] = '\0';
     516                 :         }
     517                 : 
     518             234 :         if (Z_TYPE_PP(arg_replace) == IS_STRING) {
     519             370 :                 if (Z_STRVAL_PP(arg_replace) && Z_STRLEN_PP(arg_replace))
     520             182 :                         replace = estrndup(Z_STRVAL_PP(arg_replace), Z_STRLEN_PP(arg_replace));
     521                 :                 else
     522               6 :                         replace = STR_EMPTY_ALLOC();
     523                 :         } else {
     524              46 :                 convert_to_long_ex(arg_replace);
     525              46 :                 replace = emalloc(2);
     526              46 :                 replace[0] = (char) Z_LVAL_PP(arg_replace);
     527              46 :                 replace[1] = '\0';
     528                 :         }
     529                 : 
     530             234 :         convert_to_string_ex(arg_string);
     531             452 :         if (Z_STRVAL_PP(arg_string) && Z_STRLEN_PP(arg_string))
     532             218 :                 string = estrndup(Z_STRVAL_PP(arg_string), Z_STRLEN_PP(arg_string));
     533                 :         else
     534              16 :                 string = STR_EMPTY_ALLOC();
     535                 : 
     536                 :         /* do the actual work */
     537             234 :         ret = php_reg_replace(pattern, replace, string, icase, 1);
     538             234 :         if (ret == (char *) -1) {
     539              54 :                 RETVAL_FALSE;
     540                 :         } else {
     541             180 :                 RETVAL_STRING(ret, 1);
     542             180 :                 STR_FREE(ret);
     543                 :         }
     544                 : 
     545             234 :         STR_FREE(string);
     546             234 :         STR_FREE(replace);
     547             234 :         STR_FREE(pattern);
     548                 : }
     549                 : /* }}} */
     550                 : 
     551                 : /* {{{ proto string ereg_replace(string pattern, string replacement, string string)
     552                 :    Replace regular expression */
     553                 : PHP_FUNCTION(ereg_replace)
     554             127 : {
     555             127 :         php_ereg_replace(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
     556             127 : }
     557                 : /* }}} */
     558                 : 
     559                 : /* {{{ proto string eregi_replace(string pattern, string replacement, string string)
     560                 :    Case insensitive replace regular expression */
     561                 : PHP_FUNCTION(eregi_replace)
     562             111 : {
     563             111 :         php_ereg_replace(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
     564             111 : }
     565                 : /* }}} */
     566                 : 
     567                 : /* {{{ php_split
     568                 :  */
     569                 : static void php_split(INTERNAL_FUNCTION_PARAMETERS, int icase)
     570             316 : {
     571             316 :         zval **spliton, **str, **arg_count = NULL;
     572                 :         regex_t re;
     573                 :         regmatch_t subs[1];
     574                 :         char *strp, *endp;
     575             316 :         int err, size, count = -1, copts = 0;
     576             316 :         int argc = ZEND_NUM_ARGS();
     577                 : 
     578             316 :         if (argc < 2 || argc > 3 ||
     579                 :             zend_get_parameters_ex(argc, &spliton, &str, &arg_count) == FAILURE) {
     580               4 :                 WRONG_PARAM_COUNT;
     581                 :         }
     582                 :     
     583             312 :         if (argc > 2) {
     584             189 :                 convert_to_long_ex(arg_count);
     585             189 :                 count = Z_LVAL_PP(arg_count);
     586                 :         }
     587                 :     
     588             312 :         if (icase)
     589             125 :                 copts = REG_ICASE;
     590                 :     
     591             312 :         convert_to_string_ex(spliton);                                        
     592             312 :         convert_to_string_ex(str);                                            
     593                 : 
     594             312 :         strp = Z_STRVAL_PP(str);
     595             312 :         endp = strp + Z_STRLEN_PP(str);
     596                 : 
     597             312 :         err = regcomp(&re, Z_STRVAL_PP(spliton), REG_EXTENDED | copts);
     598             312 :         if (err) {
     599              46 :                 php_reg_eprint(err, &re);
     600              46 :                 RETURN_FALSE;
     601                 :         }
     602                 : 
     603             266 :         array_init(return_value);
     604                 : 
     605                 :         /* churn through str, generating array entries as we go */
     606             843 :         while ((count == -1 || count > 1) && !(err = regexec(&re, strp, 1, subs, 0))) {
     607             434 :                 if (subs[0].rm_so == 0 && subs[0].rm_eo) {
     608                 :                         /* match is at start of string, return empty string */
     609             115 :                         add_next_index_stringl(return_value, "", 0, 1);
     610                 :                         /* skip ahead the length of the regex match */
     611             115 :                         strp += subs[0].rm_eo;
     612             204 :                 } else if (subs[0].rm_so == 0 && subs[0].rm_eo == 0) {
     613                 :                         /* No more matches */
     614                 :                         regfree(&re);
     615                 : 
     616               8 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Regular Expression");
     617                 :                         
     618               8 :                         zend_hash_destroy(Z_ARRVAL_P(return_value));
     619               8 :                         efree(Z_ARRVAL_P(return_value));
     620               8 :                         RETURN_FALSE;
     621                 :                 } else {
     622                 :                         /* On a real match */
     623                 : 
     624                 :                         /* make a copy of the substring */
     625             196 :                         size = subs[0].rm_so;
     626                 :                 
     627                 :                         /* add it to the array */
     628             196 :                         add_next_index_stringl(return_value, strp, size, 1);
     629                 : 
     630                 :                         /* point at our new starting point */
     631             196 :                         strp = strp + subs[0].rm_eo;
     632                 :                 }
     633                 : 
     634                 :                 /* if we're only looking for a certain number of points,
     635                 :                    stop looking once we hit it */
     636             311 :                 if (count != -1) {
     637              93 :                         count--;
     638                 :                 }
     639                 :         }
     640                 : 
     641                 :         /* see if we encountered an error */
     642             258 :         if (err && err != REG_NOMATCH) {
     643               0 :                 php_reg_eprint(err, &re);
     644                 :                 regfree(&re);
     645               0 :                 zend_hash_destroy(Z_ARRVAL_P(return_value));
     646               0 :                 efree(Z_ARRVAL_P(return_value));
     647               0 :                 RETURN_FALSE;
     648                 :         }
     649                 : 
     650                 :         /* otherwise we just have one last element to add to the array */
     651             258 :         size = endp - strp;
     652                 :         
     653             258 :         add_next_index_stringl(return_value, strp, size, 1);
     654                 : 
     655                 :         regfree(&re);
     656                 : }
     657                 : /* }}} */
     658                 : 
     659                 : /* {{{ proto array split(string pattern, string string [, int limit])
     660                 :    Split string into array by regular expression */
     661                 : PHP_FUNCTION(split)
     662             189 : {
     663             189 :         php_split(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
     664             189 : }
     665                 : /* }}} */
     666                 : 
     667                 : /* {{{ proto array spliti(string pattern, string string [, int limit])
     668                 :    Split string into array by regular expression case-insensitive */
     669                 : 
     670                 : PHP_FUNCTION(spliti)
     671             127 : {
     672             127 :         php_split(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
     673             127 : }
     674                 : 
     675                 : /* }}} */
     676                 : 
     677                 : /* {{{ proto string sql_regcase(string string)
     678                 :    Make regular expression for case insensitive match */
     679                 : PHPAPI PHP_FUNCTION(sql_regcase)
     680              28 : {
     681                 :         zval **string;
     682                 :         char *tmp;
     683                 :         unsigned char c;
     684                 :         register int i, j;
     685                 :         
     686              28 :         if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1, &string)==FAILURE) {
     687               2 :                 WRONG_PARAM_COUNT;
     688                 :         }       
     689              26 :         convert_to_string_ex(string);
     690                 :         
     691              26 :         tmp = safe_emalloc(Z_STRLEN_PP(string), 4, 1);
     692                 :         
     693             120 :         for (i = j = 0; i < Z_STRLEN_PP(string); i++) {
     694              94 :                 c = (unsigned char) Z_STRVAL_PP(string)[i];
     695              94 :                 if(isalpha(c)) {
     696              41 :                         tmp[j++] = '[';
     697              41 :                         tmp[j++] = toupper(c);
     698              41 :                         tmp[j++] = tolower(c);
     699              41 :                         tmp[j++] = ']';
     700                 :                 } else {
     701              53 :                         tmp[j++] = c;
     702                 :                 }
     703                 :         }
     704              26 :         tmp[j] = 0;
     705                 : 
     706              26 :         RETVAL_STRINGL(tmp, j, 1);
     707              26 :         efree(tmp);
     708                 : }
     709                 : /* }}} */
     710                 : 
     711                 : /*
     712                 :  * Local variables:
     713                 :  * tab-width: 4
     714                 :  * c-basic-offset: 4
     715                 :  * End:
     716                 :  * vim600: noet sw=4 ts=4 fdm=marker
     717                 :  * vim<600: noet sw=4 ts=4
     718                 :  */

Generated by: LTP GCOV extension version 1.5

Generated at Thu, 19 Nov 2009 08:20:22 +0000 (5 days ago)

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