/[pcre]/code/trunk/pcre_get.c
ViewVC logotype

Contents of /code/trunk/pcre_get.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 87 - (show annotations) (download)
Sat Feb 24 21:41:21 2007 UTC (7 years, 9 months ago) by nigel
File MIME type: text/plain
File size: 11915 byte(s)
Load pcre-6.5 into code/trunk.

1 /*************************************************
2 * Perl-Compatible Regular Expressions *
3 *************************************************/
4
5 /* PCRE is a library of functions to support regular expressions whose syntax
6 and semantics are as close as possible to those of the Perl 5 language.
7
8 Written by Philip Hazel
9 Copyright (c) 1997-2006 University of Cambridge
10
11 -----------------------------------------------------------------------------
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions are met:
14
15 * Redistributions of source code must retain the above copyright notice,
16 this list of conditions and the following disclaimer.
17
18 * Redistributions in binary form must reproduce the above copyright
19 notice, this list of conditions and the following disclaimer in the
20 documentation and/or other materials provided with the distribution.
21
22 * Neither the name of the University of Cambridge nor the names of its
23 contributors may be used to endorse or promote products derived from
24 this software without specific prior written permission.
25
26 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
30 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 POSSIBILITY OF SUCH DAMAGE.
37 -----------------------------------------------------------------------------
38 */
39
40
41 /* This module contains some convenience functions for extracting substrings
42 from the subject string after a regex match has succeeded. The original idea
43 for these functions came from Scott Wimer. */
44
45
46 #include "pcre_internal.h"
47
48
49 /*************************************************
50 * Find number for named string *
51 *************************************************/
52
53 /* This function is used by the two extraction functions below, as well
54 as being generally available.
55
56 Arguments:
57 code the compiled regex
58 stringname the name whose number is required
59
60 Returns: the number of the named parentheses, or a negative number
61 (PCRE_ERROR_NOSUBSTRING) if not found
62 */
63
64 int
65 pcre_get_stringnumber(const pcre *code, const char *stringname)
66 {
67 int rc;
68 int entrysize;
69 int top, bot;
70 uschar *nametable;
71
72 if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0)
73 return rc;
74 if (top <= 0) return PCRE_ERROR_NOSUBSTRING;
75
76 if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0)
77 return rc;
78 if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0)
79 return rc;
80
81 bot = 0;
82 while (top > bot)
83 {
84 int mid = (top + bot) / 2;
85 uschar *entry = nametable + entrysize*mid;
86 int c = strcmp(stringname, (char *)(entry + 2));
87 if (c == 0) return (entry[0] << 8) + entry[1];
88 if (c > 0) bot = mid + 1; else top = mid;
89 }
90
91 return PCRE_ERROR_NOSUBSTRING;
92 }
93
94
95
96 /*************************************************
97 * Copy captured string to given buffer *
98 *************************************************/
99
100 /* This function copies a single captured substring into a given buffer.
101 Note that we use memcpy() rather than strncpy() in case there are binary zeros
102 in the string.
103
104 Arguments:
105 subject the subject string that was matched
106 ovector pointer to the offsets table
107 stringcount the number of substrings that were captured
108 (i.e. the yield of the pcre_exec call, unless
109 that was zero, in which case it should be 1/3
110 of the offset table size)
111 stringnumber the number of the required substring
112 buffer where to put the substring
113 size the size of the buffer
114
115 Returns: if successful:
116 the length of the copied string, not including the zero
117 that is put on the end; can be zero
118 if not successful:
119 PCRE_ERROR_NOMEMORY (-6) buffer too small
120 PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
121 */
122
123 int
124 pcre_copy_substring(const char *subject, int *ovector, int stringcount,
125 int stringnumber, char *buffer, int size)
126 {
127 int yield;
128 if (stringnumber < 0 || stringnumber >= stringcount)
129 return PCRE_ERROR_NOSUBSTRING;
130 stringnumber *= 2;
131 yield = ovector[stringnumber+1] - ovector[stringnumber];
132 if (size < yield + 1) return PCRE_ERROR_NOMEMORY;
133 memcpy(buffer, subject + ovector[stringnumber], yield);
134 buffer[yield] = 0;
135 return yield;
136 }
137
138
139
140 /*************************************************
141 * Copy named captured string to given buffer *
142 *************************************************/
143
144 /* This function copies a single captured substring into a given buffer,
145 identifying it by name.
146
147 Arguments:
148 code the compiled regex
149 subject the subject string that was matched
150 ovector pointer to the offsets table
151 stringcount the number of substrings that were captured
152 (i.e. the yield of the pcre_exec call, unless
153 that was zero, in which case it should be 1/3
154 of the offset table size)
155 stringname the name of the required substring
156 buffer where to put the substring
157 size the size of the buffer
158
159 Returns: if successful:
160 the length of the copied string, not including the zero
161 that is put on the end; can be zero
162 if not successful:
163 PCRE_ERROR_NOMEMORY (-6) buffer too small
164 PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
165 */
166
167 int
168 pcre_copy_named_substring(const pcre *code, const char *subject, int *ovector,
169 int stringcount, const char *stringname, char *buffer, int size)
170 {
171 int n = pcre_get_stringnumber(code, stringname);
172 if (n <= 0) return n;
173 return pcre_copy_substring(subject, ovector, stringcount, n, buffer, size);
174 }
175
176
177
178 /*************************************************
179 * Copy all captured strings to new store *
180 *************************************************/
181
182 /* This function gets one chunk of store and builds a list of pointers and all
183 of the captured substrings in it. A NULL pointer is put on the end of the list.
184
185 Arguments:
186 subject the subject string that was matched
187 ovector pointer to the offsets table
188 stringcount the number of substrings that were captured
189 (i.e. the yield of the pcre_exec call, unless
190 that was zero, in which case it should be 1/3
191 of the offset table size)
192 listptr set to point to the list of pointers
193
194 Returns: if successful: 0
195 if not successful:
196 PCRE_ERROR_NOMEMORY (-6) failed to get store
197 */
198
199 int
200 pcre_get_substring_list(const char *subject, int *ovector, int stringcount,
201 const char ***listptr)
202 {
203 int i;
204 int size = sizeof(char *);
205 int double_count = stringcount * 2;
206 char **stringlist;
207 char *p;
208
209 for (i = 0; i < double_count; i += 2)
210 size += sizeof(char *) + ovector[i+1] - ovector[i] + 1;
211
212 stringlist = (char **)(pcre_malloc)(size);
213 if (stringlist == NULL) return PCRE_ERROR_NOMEMORY;
214
215 *listptr = (const char **)stringlist;
216 p = (char *)(stringlist + stringcount + 1);
217
218 for (i = 0; i < double_count; i += 2)
219 {
220 int len = ovector[i+1] - ovector[i];
221 memcpy(p, subject + ovector[i], len);
222 *stringlist++ = p;
223 p += len;
224 *p++ = 0;
225 }
226
227 *stringlist = NULL;
228 return 0;
229 }
230
231
232
233 /*************************************************
234 * Free store obtained by get_substring_list *
235 *************************************************/
236
237 /* This function exists for the benefit of people calling PCRE from non-C
238 programs that can call its functions, but not free() or (pcre_free)() directly.
239
240 Argument: the result of a previous pcre_get_substring_list()
241 Returns: nothing
242 */
243
244 void
245 pcre_free_substring_list(const char **pointer)
246 {
247 (pcre_free)((void *)pointer);
248 }
249
250
251
252 /*************************************************
253 * Copy captured string to new store *
254 *************************************************/
255
256 /* This function copies a single captured substring into a piece of new
257 store
258
259 Arguments:
260 subject the subject string that was matched
261 ovector pointer to the offsets table
262 stringcount the number of substrings that were captured
263 (i.e. the yield of the pcre_exec call, unless
264 that was zero, in which case it should be 1/3
265 of the offset table size)
266 stringnumber the number of the required substring
267 stringptr where to put a pointer to the substring
268
269 Returns: if successful:
270 the length of the string, not including the zero that
271 is put on the end; can be zero
272 if not successful:
273 PCRE_ERROR_NOMEMORY (-6) failed to get store
274 PCRE_ERROR_NOSUBSTRING (-7) substring not present
275 */
276
277 int
278 pcre_get_substring(const char *subject, int *ovector, int stringcount,
279 int stringnumber, const char **stringptr)
280 {
281 int yield;
282 char *substring;
283 if (stringnumber < 0 || stringnumber >= stringcount)
284 return PCRE_ERROR_NOSUBSTRING;
285 stringnumber *= 2;
286 yield = ovector[stringnumber+1] - ovector[stringnumber];
287 substring = (char *)(pcre_malloc)(yield + 1);
288 if (substring == NULL) return PCRE_ERROR_NOMEMORY;
289 memcpy(substring, subject + ovector[stringnumber], yield);
290 substring[yield] = 0;
291 *stringptr = substring;
292 return yield;
293 }
294
295
296
297 /*************************************************
298 * Copy named captured string to new store *
299 *************************************************/
300
301 /* This function copies a single captured substring, identified by name, into
302 new store.
303
304 Arguments:
305 code the compiled regex
306 subject the subject string that was matched
307 ovector pointer to the offsets table
308 stringcount the number of substrings that were captured
309 (i.e. the yield of the pcre_exec call, unless
310 that was zero, in which case it should be 1/3
311 of the offset table size)
312 stringname the name of the required substring
313 stringptr where to put the pointer
314
315 Returns: if successful:
316 the length of the copied string, not including the zero
317 that is put on the end; can be zero
318 if not successful:
319 PCRE_ERROR_NOMEMORY (-6) couldn't get memory
320 PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
321 */
322
323 int
324 pcre_get_named_substring(const pcre *code, const char *subject, int *ovector,
325 int stringcount, const char *stringname, const char **stringptr)
326 {
327 int n = pcre_get_stringnumber(code, stringname);
328 if (n <= 0) return n;
329 return pcre_get_substring(subject, ovector, stringcount, n, stringptr);
330 }
331
332
333
334
335 /*************************************************
336 * Free store obtained by get_substring *
337 *************************************************/
338
339 /* This function exists for the benefit of people calling PCRE from non-C
340 programs that can call its functions, but not free() or (pcre_free)() directly.
341
342 Argument: the result of a previous pcre_get_substring()
343 Returns: nothing
344 */
345
346 void
347 pcre_free_substring(const char *pointer)
348 {
349 (pcre_free)((void *)pointer);
350 }
351
352 /* End of pcre_get.c */

webmaster@exim.org
ViewVC Help
Powered by ViewVC 1.1.12