aboutsummaryrefslogtreecommitdiff
path: root/src/core/ngx_regex.c
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2009-11-16 12:19:02 +0000
committerIgor Sysoev <igor@sysoev.ru>2009-11-16 12:19:02 +0000
commitc05f20ec2eace8239c53f680294c9a2154b39e7d (patch)
treefba2dd2e0c4f7a36f4b396b759645ced61c3c709 /src/core/ngx_regex.c
parentc0ae4716ece5e48c4e82863959d3ae9ff6693e65 (diff)
downloadnginx-c05f20ec2eace8239c53f680294c9a2154b39e7d.tar.gz
nginx-c05f20ec2eace8239c53f680294c9a2154b39e7d.zip
regex named captures
Diffstat (limited to 'src/core/ngx_regex.c')
-rw-r--r--src/core/ngx_regex.c125
1 files changed, 94 insertions, 31 deletions
diff --git a/src/core/ngx_regex.c b/src/core/ngx_regex.c
index c5a495209..18e3c26c5 100644
--- a/src/core/ngx_regex.c
+++ b/src/core/ngx_regex.c
@@ -23,25 +23,16 @@ ngx_regex_init(void)
}
-ngx_regex_t *
-ngx_regex_compile(ngx_str_t *pattern, ngx_int_t options, ngx_pool_t *pool,
- ngx_str_t *err)
+static ngx_inline void
+ngx_regex_malloc_init(ngx_pool_t *pool)
{
- int erroff;
- const char *errstr;
- ngx_regex_t *re;
#if (NGX_THREADS)
ngx_core_tls_t *tls;
-#if (NGX_SUPPRESS_WARN)
- tls = NULL;
-#endif
-
if (ngx_threaded) {
tls = ngx_thread_get_tls(ngx_core_tls_key);
tls->pool = pool;
- } else {
- ngx_pcre_pool = pool;
+ return;
}
#else
@@ -49,35 +40,103 @@ ngx_regex_compile(ngx_str_t *pattern, ngx_int_t options, ngx_pool_t *pool,
ngx_pcre_pool = pool;
#endif
+}
+
+
+static ngx_inline void
+ngx_regex_malloc_done(void)
+{
+#if (NGX_THREADS)
+ ngx_core_tls_t *tls;
+
+ if (ngx_threaded) {
+ tls = ngx_thread_get_tls(ngx_core_tls_key);
+ tls->pool = NULL;
+ return;
+ }
+
+#else
+
+ ngx_pcre_pool = NULL;
+
+#endif
+}
- re = pcre_compile((const char *) pattern->data, (int) options,
+
+ngx_int_t
+ngx_regex_compile(ngx_regex_compile_t *rc)
+{
+ int n, erroff;
+ char *p;
+ const char *errstr;
+ ngx_regex_t *re;
+
+ ngx_regex_malloc_init(rc->pool);
+
+ re = pcre_compile((const char *) rc->pattern.data, (int) rc->options,
&errstr, &erroff, NULL);
+ /* ensure that there is no current pool */
+ ngx_regex_malloc_done();
+
if (re == NULL) {
- if ((size_t) erroff == pattern->len) {
- ngx_snprintf(err->data, err->len - 1,
- "pcre_compile() failed: %s in \"%s\"%Z",
- errstr, pattern->data);
+ if ((size_t) erroff == rc->pattern.len) {
+ rc->err.len = ngx_snprintf(rc->err.data, rc->err.len,
+ "pcre_compile() failed: %s in \"%V\"",
+ errstr, &rc->pattern)
+ - rc->err.data;
+
} else {
- ngx_snprintf(err->data, err->len - 1,
- "pcre_compile() failed: %s in \"%s\" at \"%s\"%Z",
- errstr, pattern->data, pattern->data + erroff);
+ rc->err.len = ngx_snprintf(rc->err.data, rc->err.len,
+ "pcre_compile() failed: %s in \"%V\" at \"%s\"",
+ errstr, &rc->pattern, rc->pattern.data + erroff)
+ - rc->err.data;
}
+
+ return NGX_ERROR;
}
- /* ensure that there is no current pool */
+ rc->regex = re;
-#if (NGX_THREADS)
- if (ngx_threaded) {
- tls->pool = NULL;
- } else {
- ngx_pcre_pool = NULL;
+ n = pcre_fullinfo(re, NULL, PCRE_INFO_CAPTURECOUNT, &rc->captures);
+ if (n < 0) {
+ p = "pcre_fullinfo(\"%V\", PCRE_INFO_CAPTURECOUNT) failed: %d";
+ goto failed;
}
-#else
- ngx_pcre_pool = NULL;
-#endif
- return re;
+ if (rc->captures == 0) {
+ return NGX_OK;
+ }
+
+ n = pcre_fullinfo(re, NULL, PCRE_INFO_NAMECOUNT, &rc->named_captures);
+ if (n < 0) {
+ p = "pcre_fullinfo(\"%V\", PCRE_INFO_NAMECOUNT) failed: %d";
+ goto failed;
+ }
+
+ if (rc->named_captures == 0) {
+ return NGX_OK;
+ }
+
+ n = pcre_fullinfo(re, NULL, PCRE_INFO_NAMEENTRYSIZE, &rc->name_size);
+ if (n < 0) {
+ p = "pcre_fullinfo(\"%V\", PCRE_INFO_NAMEENTRYSIZE) failed: %d";
+ goto failed;
+ }
+
+ n = pcre_fullinfo(re, NULL, PCRE_INFO_NAMETABLE, &rc->names);
+ if (n < 0) {
+ p = "pcre_fullinfo(\"%V\", PCRE_INFO_NAMETABLE) failed: %d";
+ goto failed;
+ }
+
+ return NGX_OK;
+
+failed:
+
+ rc->err.len = ngx_snprintf(rc->err.data, rc->err.len, p, &rc->pattern, n)
+ - rc->err.data;
+ return NGX_OK;
}
@@ -117,7 +176,7 @@ ngx_regex_exec_array(ngx_array_t *a, ngx_str_t *s, ngx_log_t *log)
if (n < 0) {
ngx_log_error(NGX_LOG_ALERT, log, 0,
- ngx_regex_exec_n " failed: %d on \"%V\" using \"%s\"",
+ ngx_regex_exec_n " failed: %i on \"%V\" using \"%s\"",
n, s, re[i].name);
return NGX_ERROR;
}
@@ -141,11 +200,15 @@ ngx_regex_malloc(size_t size)
if (ngx_threaded) {
tls = ngx_thread_get_tls(ngx_core_tls_key);
pool = tls->pool;
+
} else {
pool = ngx_pcre_pool;
}
+
#else
+
pool = ngx_pcre_pool;
+
#endif
if (pool) {