Mercurial > hg > nginx
comparison src/core/ngx_regex.c @ 3325:42c16d8bddbe
regex named captures
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Mon, 16 Nov 2009 12:19:02 +0000 |
parents | be47fe127f8c |
children | 169d84ff4064 |
comparison
equal
deleted
inserted
replaced
3324:616da2ea901f | 3325:42c16d8bddbe |
---|---|
21 pcre_malloc = ngx_regex_malloc; | 21 pcre_malloc = ngx_regex_malloc; |
22 pcre_free = ngx_regex_free; | 22 pcre_free = ngx_regex_free; |
23 } | 23 } |
24 | 24 |
25 | 25 |
26 ngx_regex_t * | 26 static ngx_inline void |
27 ngx_regex_compile(ngx_str_t *pattern, ngx_int_t options, ngx_pool_t *pool, | 27 ngx_regex_malloc_init(ngx_pool_t *pool) |
28 ngx_str_t *err) | 28 { |
29 { | |
30 int erroff; | |
31 const char *errstr; | |
32 ngx_regex_t *re; | |
33 #if (NGX_THREADS) | 29 #if (NGX_THREADS) |
34 ngx_core_tls_t *tls; | 30 ngx_core_tls_t *tls; |
35 | |
36 #if (NGX_SUPPRESS_WARN) | |
37 tls = NULL; | |
38 #endif | |
39 | 31 |
40 if (ngx_threaded) { | 32 if (ngx_threaded) { |
41 tls = ngx_thread_get_tls(ngx_core_tls_key); | 33 tls = ngx_thread_get_tls(ngx_core_tls_key); |
42 tls->pool = pool; | 34 tls->pool = pool; |
43 } else { | 35 return; |
44 ngx_pcre_pool = pool; | |
45 } | 36 } |
46 | 37 |
47 #else | 38 #else |
48 | 39 |
49 ngx_pcre_pool = pool; | 40 ngx_pcre_pool = pool; |
50 | 41 |
51 #endif | 42 #endif |
52 | 43 } |
53 re = pcre_compile((const char *) pattern->data, (int) options, | 44 |
45 | |
46 static ngx_inline void | |
47 ngx_regex_malloc_done(void) | |
48 { | |
49 #if (NGX_THREADS) | |
50 ngx_core_tls_t *tls; | |
51 | |
52 if (ngx_threaded) { | |
53 tls = ngx_thread_get_tls(ngx_core_tls_key); | |
54 tls->pool = NULL; | |
55 return; | |
56 } | |
57 | |
58 #else | |
59 | |
60 ngx_pcre_pool = NULL; | |
61 | |
62 #endif | |
63 } | |
64 | |
65 | |
66 ngx_int_t | |
67 ngx_regex_compile(ngx_regex_compile_t *rc) | |
68 { | |
69 int n, erroff; | |
70 char *p; | |
71 const char *errstr; | |
72 ngx_regex_t *re; | |
73 | |
74 ngx_regex_malloc_init(rc->pool); | |
75 | |
76 re = pcre_compile((const char *) rc->pattern.data, (int) rc->options, | |
54 &errstr, &erroff, NULL); | 77 &errstr, &erroff, NULL); |
55 | 78 |
79 /* ensure that there is no current pool */ | |
80 ngx_regex_malloc_done(); | |
81 | |
56 if (re == NULL) { | 82 if (re == NULL) { |
57 if ((size_t) erroff == pattern->len) { | 83 if ((size_t) erroff == rc->pattern.len) { |
58 ngx_snprintf(err->data, err->len - 1, | 84 rc->err.len = ngx_snprintf(rc->err.data, rc->err.len, |
59 "pcre_compile() failed: %s in \"%s\"%Z", | 85 "pcre_compile() failed: %s in \"%V\"", |
60 errstr, pattern->data); | 86 errstr, &rc->pattern) |
87 - rc->err.data; | |
88 | |
61 } else { | 89 } else { |
62 ngx_snprintf(err->data, err->len - 1, | 90 rc->err.len = ngx_snprintf(rc->err.data, rc->err.len, |
63 "pcre_compile() failed: %s in \"%s\" at \"%s\"%Z", | 91 "pcre_compile() failed: %s in \"%V\" at \"%s\"", |
64 errstr, pattern->data, pattern->data + erroff); | 92 errstr, &rc->pattern, rc->pattern.data + erroff) |
93 - rc->err.data; | |
65 } | 94 } |
66 } | 95 |
67 | 96 return NGX_ERROR; |
68 /* ensure that there is no current pool */ | 97 } |
69 | 98 |
70 #if (NGX_THREADS) | 99 rc->regex = re; |
71 if (ngx_threaded) { | 100 |
72 tls->pool = NULL; | 101 n = pcre_fullinfo(re, NULL, PCRE_INFO_CAPTURECOUNT, &rc->captures); |
73 } else { | 102 if (n < 0) { |
74 ngx_pcre_pool = NULL; | 103 p = "pcre_fullinfo(\"%V\", PCRE_INFO_CAPTURECOUNT) failed: %d"; |
75 } | 104 goto failed; |
76 #else | 105 } |
77 ngx_pcre_pool = NULL; | 106 |
78 #endif | 107 if (rc->captures == 0) { |
79 | 108 return NGX_OK; |
80 return re; | 109 } |
110 | |
111 n = pcre_fullinfo(re, NULL, PCRE_INFO_NAMECOUNT, &rc->named_captures); | |
112 if (n < 0) { | |
113 p = "pcre_fullinfo(\"%V\", PCRE_INFO_NAMECOUNT) failed: %d"; | |
114 goto failed; | |
115 } | |
116 | |
117 if (rc->named_captures == 0) { | |
118 return NGX_OK; | |
119 } | |
120 | |
121 n = pcre_fullinfo(re, NULL, PCRE_INFO_NAMEENTRYSIZE, &rc->name_size); | |
122 if (n < 0) { | |
123 p = "pcre_fullinfo(\"%V\", PCRE_INFO_NAMEENTRYSIZE) failed: %d"; | |
124 goto failed; | |
125 } | |
126 | |
127 n = pcre_fullinfo(re, NULL, PCRE_INFO_NAMETABLE, &rc->names); | |
128 if (n < 0) { | |
129 p = "pcre_fullinfo(\"%V\", PCRE_INFO_NAMETABLE) failed: %d"; | |
130 goto failed; | |
131 } | |
132 | |
133 return NGX_OK; | |
134 | |
135 failed: | |
136 | |
137 rc->err.len = ngx_snprintf(rc->err.data, rc->err.len, p, &rc->pattern, n) | |
138 - rc->err.data; | |
139 return NGX_OK; | |
81 } | 140 } |
82 | 141 |
83 | 142 |
84 ngx_int_t | 143 ngx_int_t |
85 ngx_regex_capture_count(ngx_regex_t *re) | 144 ngx_regex_capture_count(ngx_regex_t *re) |
115 continue; | 174 continue; |
116 } | 175 } |
117 | 176 |
118 if (n < 0) { | 177 if (n < 0) { |
119 ngx_log_error(NGX_LOG_ALERT, log, 0, | 178 ngx_log_error(NGX_LOG_ALERT, log, 0, |
120 ngx_regex_exec_n " failed: %d on \"%V\" using \"%s\"", | 179 ngx_regex_exec_n " failed: %i on \"%V\" using \"%s\"", |
121 n, s, re[i].name); | 180 n, s, re[i].name); |
122 return NGX_ERROR; | 181 return NGX_ERROR; |
123 } | 182 } |
124 | 183 |
125 /* match */ | 184 /* match */ |
139 ngx_core_tls_t *tls; | 198 ngx_core_tls_t *tls; |
140 | 199 |
141 if (ngx_threaded) { | 200 if (ngx_threaded) { |
142 tls = ngx_thread_get_tls(ngx_core_tls_key); | 201 tls = ngx_thread_get_tls(ngx_core_tls_key); |
143 pool = tls->pool; | 202 pool = tls->pool; |
203 | |
144 } else { | 204 } else { |
145 pool = ngx_pcre_pool; | 205 pool = ngx_pcre_pool; |
146 } | 206 } |
207 | |
147 #else | 208 #else |
209 | |
148 pool = ngx_pcre_pool; | 210 pool = ngx_pcre_pool; |
211 | |
149 #endif | 212 #endif |
150 | 213 |
151 if (pool) { | 214 if (pool) { |
152 return ngx_palloc(pool, size); | 215 return ngx_palloc(pool, size); |
153 } | 216 } |