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 - ereg - ereg.c
Test: PHP Code Coverage
Date: 2009-11-23 Instrumented lines: 304
Code covered: 87.2 % Executed lines: 265
Legend: not executed executed

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

Generated by: LTP GCOV extension version 1.5

Generated at Mon, 23 Nov 2009 17:39:29 +0000 (33 hours ago)

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