LTP GCOV extension - code coverage report
Current view: directory - ext/standard - reg.c
Test: PHP Code Coverage
Date: 2007-04-10 Instrumented lines: 285
Code covered: 4.2 % Executed lines: 12
Legend: not executed executed

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

Generated by: LTP GCOV extension version 1.5