comparison src/core/ngx_regex.c @ 665:0b460e61bdcd default tip

Merge with nginx 1.0.0.
author Maxim Dounin <mdounin@mdounin.ru>
date Mon, 25 Apr 2011 04:22:17 +0400
parents 697030d79811
children
comparison
equal deleted inserted replaced
572:06419a2298a9 665:0b460e61bdcd
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; 36 }
45 } 37
46 38 #endif
47 #else
48 39
49 ngx_pcre_pool = pool; 40 ngx_pcre_pool = pool;
41 }
42
43
44 static ngx_inline void
45 ngx_regex_malloc_done(void)
46 {
47 #if (NGX_THREADS)
48 ngx_core_tls_t *tls;
49
50 if (ngx_threaded) {
51 tls = ngx_thread_get_tls(ngx_core_tls_key);
52 tls->pool = NULL;
53 return;
54 }
50 55
51 #endif 56 #endif
52 57
53 re = pcre_compile((const char *) pattern->data, (int) options, 58 ngx_pcre_pool = NULL;
59 }
60
61
62 ngx_int_t
63 ngx_regex_compile(ngx_regex_compile_t *rc)
64 {
65 int n, erroff;
66 char *p;
67 const char *errstr;
68 ngx_regex_t *re;
69
70 ngx_regex_malloc_init(rc->pool);
71
72 re = pcre_compile((const char *) rc->pattern.data, (int) rc->options,
54 &errstr, &erroff, NULL); 73 &errstr, &erroff, NULL);
55 74
75 /* ensure that there is no current pool */
76 ngx_regex_malloc_done();
77
56 if (re == NULL) { 78 if (re == NULL) {
57 if ((size_t) erroff == pattern->len) { 79 if ((size_t) erroff == rc->pattern.len) {
58 ngx_snprintf(err->data, err->len - 1, 80 rc->err.len = ngx_snprintf(rc->err.data, rc->err.len,
59 "pcre_compile() failed: %s in \"%s\"%Z", 81 "pcre_compile() failed: %s in \"%V\"",
60 errstr, pattern->data); 82 errstr, &rc->pattern)
83 - rc->err.data;
84
61 } else { 85 } else {
62 ngx_snprintf(err->data, err->len - 1, 86 rc->err.len = ngx_snprintf(rc->err.data, rc->err.len,
63 "pcre_compile() failed: %s in \"%s\" at \"%s\"%Z", 87 "pcre_compile() failed: %s in \"%V\" at \"%s\"",
64 errstr, pattern->data, pattern->data + erroff); 88 errstr, &rc->pattern, rc->pattern.data + erroff)
89 - rc->err.data;
65 } 90 }
66 } 91
67 92 return NGX_ERROR;
68 /* ensure that there is no current pool */ 93 }
69 94
70 #if (NGX_THREADS) 95 rc->regex = re;
71 if (ngx_threaded) { 96
72 tls->pool = NULL; 97 n = pcre_fullinfo(re, NULL, PCRE_INFO_CAPTURECOUNT, &rc->captures);
73 } else { 98 if (n < 0) {
74 ngx_pcre_pool = NULL; 99 p = "pcre_fullinfo(\"%V\", PCRE_INFO_CAPTURECOUNT) failed: %d";
75 } 100 goto failed;
76 #else 101 }
77 ngx_pcre_pool = NULL; 102
78 #endif 103 if (rc->captures == 0) {
79 104 return NGX_OK;
80 return re; 105 }
106
107 n = pcre_fullinfo(re, NULL, PCRE_INFO_NAMECOUNT, &rc->named_captures);
108 if (n < 0) {
109 p = "pcre_fullinfo(\"%V\", PCRE_INFO_NAMECOUNT) failed: %d";
110 goto failed;
111 }
112
113 if (rc->named_captures == 0) {
114 return NGX_OK;
115 }
116
117 n = pcre_fullinfo(re, NULL, PCRE_INFO_NAMEENTRYSIZE, &rc->name_size);
118 if (n < 0) {
119 p = "pcre_fullinfo(\"%V\", PCRE_INFO_NAMEENTRYSIZE) failed: %d";
120 goto failed;
121 }
122
123 n = pcre_fullinfo(re, NULL, PCRE_INFO_NAMETABLE, &rc->names);
124 if (n < 0) {
125 p = "pcre_fullinfo(\"%V\", PCRE_INFO_NAMETABLE) failed: %d";
126 goto failed;
127 }
128
129 return NGX_OK;
130
131 failed:
132
133 rc->err.len = ngx_snprintf(rc->err.data, rc->err.len, p, &rc->pattern, n)
134 - rc->err.data;
135 return NGX_OK;
81 } 136 }
82 137
83 138
84 ngx_int_t 139 ngx_int_t
85 ngx_regex_capture_count(ngx_regex_t *re) 140 ngx_regex_capture_count(ngx_regex_t *re)
93 if (rc < 0) { 148 if (rc < 0) {
94 return (ngx_int_t) rc; 149 return (ngx_int_t) rc;
95 } 150 }
96 151
97 return (ngx_int_t) n; 152 return (ngx_int_t) n;
98 }
99
100
101 ngx_int_t
102 ngx_regex_exec(ngx_regex_t *re, ngx_str_t *s, int *captures, ngx_int_t size)
103 {
104 int rc;
105
106 rc = pcre_exec(re, NULL, (const char *) s->data, s->len, 0, 0,
107 captures, size);
108
109 if (rc == -1) {
110 return NGX_REGEX_NO_MATCHED;
111 }
112
113 return rc;
114 } 153 }
115 154
116 155
117 ngx_int_t 156 ngx_int_t
118 ngx_regex_exec_array(ngx_array_t *a, ngx_str_t *s, ngx_log_t *log) 157 ngx_regex_exec_array(ngx_array_t *a, ngx_str_t *s, ngx_log_t *log)
131 continue; 170 continue;
132 } 171 }
133 172
134 if (n < 0) { 173 if (n < 0) {
135 ngx_log_error(NGX_LOG_ALERT, log, 0, 174 ngx_log_error(NGX_LOG_ALERT, log, 0,
136 ngx_regex_exec_n " failed: %d on \"%V\" using \"%s\"", 175 ngx_regex_exec_n " failed: %i on \"%V\" using \"%s\"",
137 n, s, re[i].name); 176 n, s, re[i].name);
138 return NGX_ERROR; 177 return NGX_ERROR;
139 } 178 }
140 179
141 /* match */ 180 /* match */
155 ngx_core_tls_t *tls; 194 ngx_core_tls_t *tls;
156 195
157 if (ngx_threaded) { 196 if (ngx_threaded) {
158 tls = ngx_thread_get_tls(ngx_core_tls_key); 197 tls = ngx_thread_get_tls(ngx_core_tls_key);
159 pool = tls->pool; 198 pool = tls->pool;
199
160 } else { 200 } else {
161 pool = ngx_pcre_pool; 201 pool = ngx_pcre_pool;
162 } 202 }
203
163 #else 204 #else
205
164 pool = ngx_pcre_pool; 206 pool = ngx_pcre_pool;
207
165 #endif 208 #endif
166 209
167 if (pool) { 210 if (pool) {
168 return ngx_palloc(pool, size); 211 return ngx_palloc(pool, size);
169 } 212 }