summaryrefslogtreecommitdiff
path: root/ext/pcre/php_pcre.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/pcre/php_pcre.c')
-rw-r--r--ext/pcre/php_pcre.c45
1 files changed, 43 insertions, 2 deletions
diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c
index 983dd6d4fc..b815667238 100644
--- a/ext/pcre/php_pcre.c
+++ b/ext/pcre/php_pcre.c
@@ -582,6 +582,10 @@ PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, char *subject, int subjec
int i, rc;
int subpats_order; /* Order of subpattern matches */
int offset_capture; /* Capture match offsets: yes/no */
+ unsigned char *mark = NULL; /* Target for MARK name */
+ zval marks; /* Array of marks for PREG_PATTERN_ORDER */
+
+ ZVAL_UNDEF(&marks);
/* Overwrite the passed-in value for subpatterns with an empty array. */
if (subpats != NULL) {
@@ -624,6 +628,10 @@ PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, char *subject, int subjec
}
extra->match_limit = PCRE_G(backtrack_limit);
extra->match_limit_recursion = PCRE_G(recursion_limit);
+#ifdef PCRE_EXTRA_MARK
+ extra->mark = &mark;
+ extra->flags |= PCRE_EXTRA_MARK;
+#endif
/* Calculate the size of the offsets array, and allocate memory for it. */
rc = pcre_fullinfo(pce->re, extra, PCRE_INFO_CAPTURECOUNT, &num_subpats);
@@ -698,6 +706,13 @@ PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, char *subject, int subjec
offsets[(i<<1)+1] - offsets[i<<1]);
}
}
+ /* Add MARK, if available */
+ if (mark) {
+ if (Z_TYPE(marks) == IS_UNDEF) {
+ array_init(&marks);
+ }
+ add_index_string(&marks, matched - 1, (char *) mark);
+ }
/*
* If the number of captured subpatterns on this run is
* less than the total possible number, pad the result
@@ -726,6 +741,10 @@ PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, char *subject, int subjec
offsets[(i<<1)+1] - offsets[i<<1]);
}
}
+ /* Add MARK, if available */
+ if (mark) {
+ add_assoc_string(&result_set, "MARK", (char *) mark);
+ }
/* And add it to the output array */
zend_hash_next_index_insert(Z_ARRVAL_P(subpats), &result_set);
}
@@ -745,6 +764,10 @@ PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, char *subject, int subjec
offsets[(i<<1)+1] - offsets[i<<1]);
}
}
+ /* Add MARK, if available */
+ if (mark) {
+ add_assoc_string(subpats, "MARK", (char *) mark);
+ }
}
pcre_free((void *) stringlist);
@@ -785,6 +808,10 @@ PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, char *subject, int subjec
zend_hash_next_index_insert(Z_ARRVAL_P(subpats), &match_sets[i]);
}
efree(match_sets);
+
+ if (Z_TYPE(marks) != IS_UNDEF) {
+ add_assoc_zval(subpats, "MARK", &marks);
+ }
}
efree(offsets);
@@ -856,7 +883,7 @@ static int preg_get_backref(char **str, int *backref)
/* {{{ preg_do_repl_func
*/
-static int preg_do_repl_func(zval *function, char *subject, int *offsets, char **subpat_names, int count, char **result TSRMLS_DC)
+static int preg_do_repl_func(zval *function, char *subject, int *offsets, char **subpat_names, int count, unsigned char *mark, char **result TSRMLS_DC)
{
zval retval; /* Function return value */
zval args[1]; /* Argument to pass to function */
@@ -870,6 +897,9 @@ static int preg_do_repl_func(zval *function, char *subject, int *offsets, char *
}
add_next_index_stringl(&args[0], &subject[offsets[i<<1]], offsets[(i<<1)+1] - offsets[i<<1]);
}
+ if (mark) {
+ add_assoc_string(&args[0], "MARK", (char *) mark);
+ }
if (call_user_function_ex(EG(function_table), NULL, function, &retval, 1, args, 0, NULL TSRMLS_CC) == SUCCESS && Z_TYPE(retval) != IS_UNDEF) {
convert_to_string_ex(&retval);
@@ -1025,6 +1055,7 @@ PHPAPI zend_string *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject,
walk_last; /* Last walked character */
int rc,
result_len; /* Length of result */
+ unsigned char *mark = NULL; /* Target for MARK name */
zend_string *result; /* Result of replacement */
if (extra == NULL) {
@@ -1033,6 +1064,10 @@ PHPAPI zend_string *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject,
}
extra->match_limit = PCRE_G(backtrack_limit);
extra->match_limit_recursion = PCRE_G(recursion_limit);
+#ifdef PCRE_EXTRA_MARK
+ extra->mark = &mark;
+ extra->flags |= PCRE_EXTRA_MARK;
+#endif
eval = pce->preg_options & PREG_REPLACE_EVAL;
if (is_callable_replace) {
@@ -1112,7 +1147,7 @@ PHPAPI zend_string *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject,
new_len += eval_result_len;
} else if (is_callable_replace) {
/* Use custom function to get replacement string and its length. */
- eval_result_len = preg_do_repl_func(replace_val, subject, offsets, subpat_names, count, &eval_result TSRMLS_CC);
+ eval_result_len = preg_do_repl_func(replace_val, subject, offsets, subpat_names, count, mark, &eval_result TSRMLS_CC);
new_len += eval_result_len;
} else { /* do regular substitution */
walk = replace;
@@ -1498,6 +1533,9 @@ PHPAPI void php_pcre_split_impl(pcre_cache_entry *pce, char *subject, int subjec
}
extra->match_limit = PCRE_G(backtrack_limit);
extra->match_limit_recursion = PCRE_G(recursion_limit);
+#ifdef PCRE_EXTRA_MARK
+ extra->flags &= ~PCRE_EXTRA_MARK;
+#endif
/* Initialize return value */
array_init(return_value);
@@ -1767,6 +1805,9 @@ PHPAPI void php_pcre_grep_impl(pcre_cache_entry *pce, zval *input, zval *return
}
extra->match_limit = PCRE_G(backtrack_limit);
extra->match_limit_recursion = PCRE_G(recursion_limit);
+#ifdef PCRE_EXTRA_MARK
+ extra->flags &= ~PCRE_EXTRA_MARK;
+#endif
/* Calculate the size of the offsets array, and allocate memory for it. */
rc = pcre_fullinfo(pce->re, extra, PCRE_INFO_CAPTURECOUNT, &size_offsets);