I will take a look at this soon, thanks.

On Thu, 06 Jun 2002, David Brown wrote:
> Hi Andrei, all:
> 
> (This is a re-send of a previous message that received no replies; my
> apologies if you've already seen/considered it)
> 
> In a previous patch 
> (http://news.php.net/article.php?group=php.dev&article=84281), support
> was added to preg_split for capturing offsets along with matches. The
> attached patch adds similar support to preg_match and preg_match_all via
> a new PREG_MATCH_OFFSET_CAPTURE flag.
> 
> The code handles capturing offsets for both subpattern matches and whole
> pattern matches, using the previously-added add_offset_pair helper function.
> 
> The flag is a new fourth (and optional) parameter for preg_match, and
> are or'd into the existing 'order' parameter for preg_match_all, above
> PREG_SET_ORDER and PREG_PATTERN_ORDER.
> 
> The patch below is diffed against the CVS head - humbly sumbitted for
> application, rejection, suggestions, or extensive flaming. :)
> 
> 
> Thanks in advance,
> 
> - Dave
>   [EMAIL PROTECTED]
> 
> 
> --- ext/pcre/php_pcre.c.orig  Tue Jun  4 13:02:50 2002
> +++ ext/pcre/php_pcre.c       Tue Jun  4 13:12:10 2002
> @@ -35,7 +35,9 @@
>  #define PREG_PATTERN_ORDER                   0
>  #define PREG_SET_ORDER                               1
>  
> -#define      PREG_SPLIT_NO_EMPTY                     (1<<0)
> +#define PREG_MATCH_OFFSET_CAPTURE    (1<<2)
> +
> +#define PREG_SPLIT_NO_EMPTY                  (1<<0)
>  #define PREG_SPLIT_DELIM_CAPTURE     (1<<1)
>  #define PREG_SPLIT_OFFSET_CAPTURE    (1<<2)
>  
> @@ -99,6 +101,7 @@
>       
>       REGISTER_LONG_CONSTANT("PREG_PATTERN_ORDER", PREG_PATTERN_ORDER, CONST_CS | 
>CONST_PERSISTENT);
>       REGISTER_LONG_CONSTANT("PREG_SET_ORDER", PREG_SET_ORDER, CONST_CS | 
>CONST_PERSISTENT);
> +     REGISTER_LONG_CONSTANT("PREG_MATCH_OFFSET_CAPTURE", PREG_MATCH_OFFSET_CAPTURE, 
>CONST_CS | CONST_PERSISTENT);
>       REGISTER_LONG_CONSTANT("PREG_SPLIT_NO_EMPTY", PREG_SPLIT_NO_EMPTY, CONST_CS | 
>CONST_PERSISTENT);
>       REGISTER_LONG_CONSTANT("PREG_SPLIT_DELIM_CAPTURE", PREG_SPLIT_DELIM_CAPTURE, 
>CONST_CS | CONST_PERSISTENT);
>       REGISTER_LONG_CONSTANT("PREG_SPLIT_OFFSET_CAPTURE", PREG_SPLIT_OFFSET_CAPTURE, 
>CONST_CS | CONST_PERSISTENT);
> @@ -310,6 +313,24 @@
>  }
>  /* }}} */
>  
> +/* {{{ add_offset_pair
> + */
> +static inline void add_offset_pair(zval *result, char *str, int len, int offset)
> +{
> +     zval *match_pair;
> +
> +     ALLOC_ZVAL(match_pair);
> +     array_init(match_pair);
> +     INIT_PZVAL(match_pair);
> +
> +     /* Add (match, offset) to the return value */
> +     add_next_index_stringl(match_pair, str, len, 1);
> +     add_next_index_long(match_pair, offset);
> +     
> +     zend_hash_next_index_insert(Z_ARRVAL_P(result), &match_pair, sizeof(zval *), 
>NULL);
> +}
> +/* }}} */
> +
>  /* {{{ php_pcre_match
>   */
>  static void php_pcre_match(INTERNAL_FUNCTION_PARAMETERS, int global)
> @@ -335,6 +356,7 @@
>       int                              matched;                       /* Has 
>anything matched */
>       int                              i;
>       int                              subpats_order_val = 0; /* Integer value of 
>subpats_order */
> +     int                              offset_capture = 0;    /* If offsets should 
>be captured */
>       int                              g_notempty = 0;        /* If the match should 
>not be empty */
>       const char         **stringlist;                /* Used to hold list of 
>subpatterns */
>       char                    *match;                         /* The current match */
> @@ -363,11 +385,17 @@
>       
>                       /* Make sure subpats_order is a number */
>                       convert_to_long_ex(subpats_order);
> -                     subpats_order_val = Z_LVAL_PP(subpats_order);
> -                     if (subpats_order_val < PREG_PATTERN_ORDER ||
> -                             subpats_order_val > PREG_SET_ORDER) {
> -                             zend_error(E_WARNING, "Wrong value for parameter 4 in 
>call to preg_match_all()");
> -                     }
> +            offset_capture = (Z_LVAL_PP(subpats_order) & PREG_MATCH_OFFSET_CAPTURE);
> +            
> +                     if (global) {
> +              subpats_order_val = (Z_LVAL_PP(subpats_order) & 1UL);
> +                     
> +              if ((subpats_order_val < PREG_PATTERN_ORDER) ||
> +                  (subpats_order_val > PREG_SET_ORDER)) {
> +                               zend_error(E_WARNING, "Wrong value for parameter 4 
>in call to preg_match_all()");
> +                       }
> +            }
> +
>                       break;
>                       
>               default:
> @@ -442,8 +470,13 @@
>                                       if (subpats_order_val == PREG_PATTERN_ORDER) {
>                                               /* For each subpattern, insert it into 
>the appropriate array. */
>                                               for (i = 0; i < count; i++) {
> -                                                     
>add_next_index_stringl(match_sets[i], (char *)stringlist[i],
> -                                                                                    
>            offsets[(i<<1)+1] - offsets[i<<1], 1);
> +                                                     if (offset_capture) {
> +                                                             
>add_offset_pair(match_sets[i], (char *)stringlist[i],
> +                                                                                    
>         offsets[(i<<1)+1] - offsets[i<<1], offsets[i<<1]);
> +                                                     } else {
> +                                                             
>add_next_index_stringl(match_sets[i], (char *)stringlist[i],
> +                                                                                    
>                         offsets[(i<<1)+1] - offsets[i<<1], 1);
> +                                                     }
>                                               }
>                                               /*
>                                                * If the number of captured 
>subpatterns on this run is
> @@ -463,8 +496,13 @@
>                                               
>                                               /* Add all the subpatterns to it */
>                                               for (i = 0; i < count; i++) {
> -                                                     
>add_next_index_stringl(result_set, (char *)stringlist[i],
> -                                                                                    
>            offsets[(i<<1)+1] - offsets[i<<1], 1);
> +                                                     if (offset_capture) {
> +                                                             
>add_offset_pair(result_set, (char *)stringlist[i],
> +                                                                                    
>                         offsets[(i<<1)+1] - offsets[i<<1], offsets[i<<1]);
> +                                                     } else {
> +                                                             
>add_next_index_stringl(result_set, (char *)stringlist[i],
> +                                                                                    
>                         offsets[(i<<1)+1] - offsets[i<<1], 1);
> +                                                     }
>                                               }
>                                               /* And add it to the output array */
>                                               
>zend_hash_next_index_insert(Z_ARRVAL_PP(subpats), &result_set,
> @@ -474,8 +512,13 @@
>                               else {                  /* single pattern matching */
>                                       /* For each subpattern, insert it into the 
>subpatterns array. */
>                                       for (i = 0; i < count; i++) {
> -                                             add_next_index_stringl((*subpats), 
>(char *)stringlist[i],
> -                                                                                    
>    offsets[(i<<1)+1] - offsets[i<<1], 1);
> +                                             if (offset_capture) {
> +                                                     add_offset_pair((*subpats), 
>(char *)stringlist[i],
> +                                                                                    
> offsets[(i<<1)+1] - offsets[i<<1], offsets[i<<1]);
> +                                             } else {
> +                                                     
>add_next_index_stringl((*subpats), (char *)stringlist[i],
> +                                                                                    
>                 offsets[(i<<1)+1] - offsets[i<<1], 1);
> +                                             }
>                                       }
>                               }
>  
> @@ -518,7 +561,7 @@
>  }
>  /* }}} */
>  
> -/* {{{ proto int preg_match(string pattern, string subject [, array subpatterns])
> +/* {{{ proto int preg_match(string pattern, string subject [, array matches [, int 
>flags]])
>     Perform a Perl-style regular expression match */
>  PHP_FUNCTION(preg_match)
>  {
> @@ -1063,21 +1106,6 @@
>       preg_replace_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
>  }
>  /* }}} */
> -
> -static inline void add_offset_pair(zval *result, char *str, int len, int offset)
> -{
> -     zval *match_pair;
> -
> -     ALLOC_ZVAL(match_pair);
> -     array_init(match_pair);
> -     INIT_PZVAL(match_pair);
> -
> -     /* Add (match, offset) to the return value */
> -     add_next_index_stringl(match_pair, str, len, 1);
> -     add_next_index_long(match_pair, offset);
> -     
> -     zend_hash_next_index_insert(Z_ARRVAL_P(result), &match_pair, sizeof(zval *), 
>NULL);
> -}
>  
>  /* {{{ proto array preg_split(string pattern, string subject [, int limit [, int 
>flags]]) 
>     Split string into an array using a perl-style regular expression as a delimiter 
>*/
> 



-Andrei                                       http://www.gravitonic.com/
* DOS is, quite possibly, the worst text-adventure game ever. *

-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to