mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
-Added regex cache
-Made module thread-safe
This commit is contained in:
parent
c57c0e9cd5
commit
e3a70c1f04
2 changed files with 115 additions and 17 deletions
104
ext/pcre/pcre.c
104
ext/pcre/pcre.c
|
@ -48,24 +48,53 @@ function_entry pcre_functions[] = {
|
|||
};
|
||||
|
||||
php3_module_entry pcre_module_entry = {
|
||||
"PCRE", pcre_functions, NULL, NULL, php_rinit_pcre, NULL,
|
||||
"PCRE", pcre_functions, php_minit_pcre, php_mshutdown_pcre,
|
||||
php_rinit_pcre, NULL,
|
||||
php_info_pcre, STANDARD_MODULE_PROPERTIES
|
||||
};
|
||||
|
||||
/* }}} */
|
||||
|
||||
#ifdef ZTS
|
||||
int pcre_globals_id;
|
||||
#else
|
||||
php_pcre_globals pcre_globals;
|
||||
#endif
|
||||
|
||||
|
||||
static void *php_pcre_malloc(size_t size)
|
||||
{
|
||||
return emalloc(size);
|
||||
return pemalloc(size, 1);
|
||||
}
|
||||
|
||||
|
||||
static void php_pcre_free(void *ptr)
|
||||
{
|
||||
efree(ptr);
|
||||
pefree(ptr, 1);
|
||||
}
|
||||
|
||||
|
||||
static void _php_free_pcre_cache(void *data)
|
||||
{
|
||||
pcre_cache_entry *pce = (pcre_cache_entry *) data;
|
||||
pefree(pce->re, 1);
|
||||
}
|
||||
|
||||
|
||||
#ifdef ZTS
|
||||
static void _php_pcre_init_globals(php_pcre_globals *pcre_globals)
|
||||
{
|
||||
zend_hash_init(&PCRE_G(pcre_cache), 0, NULL, _php_free_pcre_cache, 1);
|
||||
}
|
||||
|
||||
|
||||
static void _php_pcre_shutdown_globals(php_pcre_globals *pcre_globals)
|
||||
{
|
||||
zend_hash_destroy(&PCRE_G(pcre_cache));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* {{{ void php_info_pcre(ZEND_MODULE_INFO_FUNC_ARGS) */
|
||||
void php_info_pcre(ZEND_MODULE_INFO_FUNC_ARGS)
|
||||
{
|
||||
|
@ -78,6 +107,33 @@ void php_info_pcre(ZEND_MODULE_INFO_FUNC_ARGS)
|
|||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ int php_minit_pcre(INIT_FUNC_ARGS) */
|
||||
int php_minit_pcre(INIT_FUNC_ARGS)
|
||||
{
|
||||
#ifdef ZTS
|
||||
pcre_globals_id = tsrm_allocate_id(
|
||||
sizeof(php_pcre_globals),
|
||||
_php_pcre_init_globals,
|
||||
_php_pcre_shutdown_globals);
|
||||
#else
|
||||
zend_hash_init(&PCRE_G(pcre_cache), 0, NULL, _php_free_pcre_cache, 1);
|
||||
#endif
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ int php_mshutdown_pcre(void) */
|
||||
int php_mshutdown_pcre(SHUTDOWN_FUNC_ARGS)
|
||||
{
|
||||
#ifndef ZTS
|
||||
zend_hash_destroy(&PCRE_G(pcre_cache));
|
||||
#endif
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ int php_rinit_pcre(INIT_FUNC_ARGS) */
|
||||
int php_rinit_pcre(INIT_FUNC_ARGS)
|
||||
{
|
||||
|
@ -97,10 +153,22 @@ static pcre* _pcre_get_compiled_regex(char *regex, pcre_extra *extra) {
|
|||
const char *error;
|
||||
int erroffset;
|
||||
char delimiter;
|
||||
unsigned char *p, *pp;
|
||||
char *p, *pp;
|
||||
char *pattern;
|
||||
int regex_len;
|
||||
int do_study = 0;
|
||||
pcre_cache_entry *pce;
|
||||
pcre_cache_entry new_entry;
|
||||
PCRE_LS_FETCH();
|
||||
|
||||
/* Try to lookup the cached regex entry, and if successful, just pass
|
||||
back the compiled pattern, otherwise go on and compile it. */
|
||||
regex_len = strlen(regex);
|
||||
if (zend_hash_find(&PCRE_G(pcre_cache), regex, regex_len+1, (void **)&pce) == SUCCESS) {
|
||||
extra = pce->extra;
|
||||
return pce->re;
|
||||
}
|
||||
|
||||
p = regex;
|
||||
|
||||
/* Parse through the leading whitespace, and display a warning if we
|
||||
|
@ -188,7 +256,13 @@ static pcre* _pcre_get_compiled_regex(char *regex, pcre_extra *extra) {
|
|||
}
|
||||
|
||||
efree(pattern);
|
||||
|
||||
|
||||
/* Store the compiled pattern and extra info in the cache. */
|
||||
new_entry.re = re;
|
||||
new_entry.extra = extra;
|
||||
zend_hash_update(&PCRE_G(pcre_cache), regex, regex_len+1, (void *)&new_entry,
|
||||
sizeof(pcre_cache_entry), NULL);
|
||||
|
||||
return re;
|
||||
}
|
||||
/* }}} */
|
||||
|
@ -204,7 +278,6 @@ PHP_FUNCTION(pcre_match)
|
|||
pcre *re = NULL;
|
||||
pcre_extra *extra = NULL;
|
||||
int exoptions = 0;
|
||||
const char *error;
|
||||
int count;
|
||||
int *offsets;
|
||||
int size_offsets;
|
||||
|
@ -289,7 +362,7 @@ PHP_FUNCTION(pcre_match)
|
|||
zend_hash_index_update(subpats->value.ht, i, &entry, sizeof(zval *), NULL);
|
||||
}
|
||||
|
||||
efree(stringlist);
|
||||
php_pcre_free(stringlist);
|
||||
}
|
||||
}
|
||||
/* If nothing matched */
|
||||
|
@ -305,7 +378,6 @@ PHP_FUNCTION(pcre_match)
|
|||
}
|
||||
|
||||
efree(offsets);
|
||||
efree(re);
|
||||
|
||||
RETVAL_LONG(matched);
|
||||
}
|
||||
|
@ -337,12 +409,9 @@ PHP_FUNCTION(pcre_replace)
|
|||
pcre *re = NULL;
|
||||
pcre_extra *extra = NULL;
|
||||
int exoptions = 0;
|
||||
const char *error;
|
||||
int count = 0;
|
||||
int *offsets;
|
||||
int size_offsets;
|
||||
int matched;
|
||||
const char ***stringlist;
|
||||
int new_len;
|
||||
int alloc_len;
|
||||
int subject_len;
|
||||
|
@ -354,6 +423,7 @@ PHP_FUNCTION(pcre_replace)
|
|||
*walkbuf,
|
||||
*walk;
|
||||
|
||||
/* Get function parameters and do error-checking. */
|
||||
if (ARG_COUNT(ht) != 3 || getParameters(ht, 3, ®ex, &replace, &subject) == FAILURE) {
|
||||
WRONG_PARAM_COUNT;
|
||||
}
|
||||
|
@ -389,7 +459,8 @@ PHP_FUNCTION(pcre_replace)
|
|||
/* Execute the regular expression. */
|
||||
count = pcre_exec(re, extra, &subject->value.str.val[subject_offset],
|
||||
subject->value.str.len-subject_offset,
|
||||
(subject_offset ? PCRE_NOTBOL : 0), offsets, size_offsets);
|
||||
(subject_offset ? exoptions|PCRE_NOTBOL : exoptions),
|
||||
offsets, size_offsets);
|
||||
|
||||
/* Check for too many substrings condition. */
|
||||
if (count == 0) {
|
||||
|
@ -404,7 +475,7 @@ PHP_FUNCTION(pcre_replace)
|
|||
if ('\\' == *walk &&
|
||||
_pcre_get_backref(walk+1, &backref) &&
|
||||
backref < count) {
|
||||
new_len += offsets[2*backref+1] - offsets[2*backref];
|
||||
new_len += offsets[(backref<<1)+1] - offsets[backref<<1];
|
||||
walk += (backref > 9) ? 3 : 2;
|
||||
} else {
|
||||
new_len++;
|
||||
|
@ -429,9 +500,9 @@ PHP_FUNCTION(pcre_replace)
|
|||
if ('\\' == *walk &&
|
||||
_pcre_get_backref(walk+1, &backref) &&
|
||||
backref < count) {
|
||||
result_len = offsets[2*backref+1] - offsets[2*backref];
|
||||
result_len = offsets[(backref<<1)+1] - offsets[backref<<1];
|
||||
memcpy (walkbuf,
|
||||
&subject->value.str.val[subject_offset + offsets[2*backref]],
|
||||
&subject->value.str.val[subject_offset + offsets[backref<<1]],
|
||||
result_len);
|
||||
walkbuf += result_len;
|
||||
walk += (backref > 9) ? 3 : 2;
|
||||
|
@ -457,7 +528,7 @@ PHP_FUNCTION(pcre_replace)
|
|||
} else {
|
||||
subject_offset += offsets[1];
|
||||
}
|
||||
} else { /* REG_NOMATCH */
|
||||
} else {
|
||||
new_len = strlen(result) + strlen(&subject->value.str.val[subject_offset]);
|
||||
if (new_len + 1 > alloc_len) {
|
||||
alloc_len = new_len + 1; /* now we know exactly how long it is */
|
||||
|
@ -472,7 +543,6 @@ PHP_FUNCTION(pcre_replace)
|
|||
}
|
||||
|
||||
efree(offsets);
|
||||
efree(re);
|
||||
|
||||
RETVAL_STRING(result, 1);
|
||||
efree(result);
|
||||
|
|
|
@ -37,6 +37,8 @@
|
|||
#include "pcre.h"
|
||||
|
||||
extern void php_info_pcre(ZEND_MODULE_INFO_FUNC_ARGS);
|
||||
extern int php_minit_pcre(INIT_FUNC_ARGS);
|
||||
extern int php_mshutdown_pcre(SHUTDOWN_FUNC_ARGS);
|
||||
extern int php_rinit_pcre(INIT_FUNC_ARGS);
|
||||
|
||||
PHP_FUNCTION(pcre_match);
|
||||
|
@ -45,6 +47,32 @@ PHP_FUNCTION(pcre_replace);
|
|||
extern zend_module_entry pcre_module_entry;
|
||||
#define pcre_module_ptr &pcre_module_entry
|
||||
|
||||
typedef struct {
|
||||
pcre *re;
|
||||
pcre_extra *extra;
|
||||
} pcre_cache_entry;
|
||||
|
||||
typedef struct {
|
||||
HashTable pcre_cache;
|
||||
} php_pcre_globals;
|
||||
|
||||
#ifdef ZTS
|
||||
# define PCRE_LS_D php_pcre_globals *pcre_globals
|
||||
# define PCRE_LS_DC , PCRE_LS_D
|
||||
# define PCRE_LS_C pcre_globals
|
||||
# define PCRE_LS_CC , PCRE_LS_C
|
||||
# define PCRE_G(v) (pcre_globals->v)
|
||||
# define PCRE_LS_FETCH() php_pcre_globals *pcre_globals = ts_resource(pcre_globals_id);
|
||||
#else
|
||||
# define PCRE_LS_D
|
||||
# define PCRE_LS_DC
|
||||
# define PCRE_LS_C
|
||||
# define PCRE_LS_CC
|
||||
# define PCRE_G(v) (pcre_globals.v)
|
||||
# define PCRE_LS_FETCH()
|
||||
extern ZEND_API php_pcre_globals pcre_globals;
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#define pcre_module_ptr NULL
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue