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

Contents of /code/trunk/get.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 63 - (show annotations) (download)
Sat Feb 24 21:40:03 2007 UTC (7 years, 8 months ago) by nigel
File MIME type: text/plain
File size: 11406 byte(s)
Load pcre-4.0 into code/trunk.

1 /*************************************************
2 * Perl-Compatible Regular Expressions *
3 *************************************************/
4
5 /*
6 This is a library of functions to support regular expressions whose syntax
7 and semantics are as close as possible to those of the Perl 5 language. See
8 the file Tech.Notes for some information on the internals.
9
10 Written by: Philip Hazel <ph10@cam.ac.uk>
11
12 Copyright (c) 1997-2003 University of Cambridge
13
14 -----------------------------------------------------------------------------
15 Permission is granted to anyone to use this software for any purpose on any
16 computer system, and to redistribute it freely, subject to the following
17 restrictions:
18
19 1. This software is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
22
23 2. The origin of this software must not be misrepresented, either by
24 explicit claim or by omission.
25
26 3. Altered versions must be plainly marked as such, and must not be
27 misrepresented as being the original software.
28
29 4. If PCRE is embedded in any software that is released under the GNU
30 General Purpose Licence (GPL), then the terms of that licence shall
31 supersede any condition above with which it is incompatible.
32 -----------------------------------------------------------------------------
33 */
34
35 /* This module contains some convenience functions for extracting substrings
36 from the subject string after a regex match has succeeded. The original idea
37 for these functions came from Scott Wimer <scottw@cgibuilder.com>. */
38
39
40 /* Include the internals header, which itself includes Standard C headers plus
41 the external pcre header. */
42
43 #include "internal.h"
44
45
46 /*************************************************
47 * Find number for named string *
48 *************************************************/
49
50 /* This function is used by the two extraction functions below, as well
51 as being generally available.
52
53 Arguments:
54 code the compiled regex
55 stringname the name whose number is required
56
57 Returns: the number of the named parentheses, or a negative number
58 (PCRE_ERROR_NOSUBSTRING) if not found
59 */
60
61 int
62 pcre_get_stringnumber(const pcre *code, const char *stringname)
63 {
64 int rc;
65 int entrysize;
66 int top, bot;
67 uschar *nametable;
68
69 if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0)
70 return rc;
71 if (top <= 0) return PCRE_ERROR_NOSUBSTRING;
72
73 if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0)
74 return rc;
75 if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0)
76 return rc;
77
78 bot = 0;
79 while (top > bot)
80 {
81 int mid = (top + bot) / 2;
82 uschar *entry = nametable + entrysize*mid;
83 int c = strcmp(stringname, (char *)(entry + 2));
84 if (c == 0) return (entry[0] << 8) + entry[1];
85 if (c > 0) bot = mid + 1; else top = mid;
86 }
87
88 return PCRE_ERROR_NOSUBSTRING;
89 }
90
91
92
93 /*************************************************
94 * Copy captured string to given buffer *
95 *************************************************/
96
97 /* This function copies a single captured substring into a given buffer.
98 Note that we use memcpy() rather than strncpy() in case there are binary zeros
99 in the string.
100
101 Arguments:
102 subject the subject string that was matched
103 ovector pointer to the offsets table
104 stringcount the number of substrings that were captured
105 (i.e. the yield of the pcre_exec call, unless
106 that was zero, in which case it should be 1/3
107 of the offset table size)
108 stringnumber the number of the required substring
109 buffer where to put the substring
110 size the size of the buffer
111
112 Returns: if successful:
113 the length of the copied string, not including the zero
114 that is put on the end; can be zero
115 if not successful:
116 PCRE_ERROR_NOMEMORY (-6) buffer too small
117 PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
118 */
119
120 int
121 pcre_copy_substring(const char *subject, int *ovector, int stringcount,
122 int stringnumber, char *buffer, int size)
123 {
124 int yield;
125 if (stringnumber < 0 || stringnumber >= stringcount)
126 return PCRE_ERROR_NOSUBSTRING;
127 stringnumber *= 2;
128 yield = ovector[stringnumber+1] - ovector[stringnumber];
129 if (size < yield + 1) return PCRE_ERROR_NOMEMORY;
130 memcpy(buffer, subject + ovector[stringnumber], yield);
131 buffer[yield] = 0;
132 return yield;
133 }
134
135
136
137 /*************************************************
138 * Copy named captured string to given buffer *
139 *************************************************/
140
141 /* This function copies a single captured substring into a given buffer,
142 identifying it by name.
143
144 Arguments:
145 code the compiled regex
146 subject the subject string that was matched
147 ovector pointer to the offsets table
148 stringcount the number of substrings that were captured
149 (i.e. the yield of the pcre_exec call, unless
150 that was zero, in which case it should be 1/3
151 of the offset table size)
152 stringname the name of the required substring
153 buffer where to put the substring
154 size the size of the buffer
155
156 Returns: if successful:
157 the length of the copied string, not including the zero
158 that is put on the end; can be zero
159 if not successful:
160 PCRE_ERROR_NOMEMORY (-6) buffer too small
161 PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
162 */
163
164 int
165 pcre_copy_named_substring(const pcre *code, const char *subject, int *ovector,
166 int stringcount, const char *stringname, char *buffer, int size)
167 {
168 int n = pcre_get_stringnumber(code, stringname);
169 if (n <= 0) return n;
170 return pcre_copy_substring(subject, ovector, stringcount, n, buffer, size);
171 }
172
173
174
175 /*************************************************
176 * Copy all captured strings to new store *
177 *************************************************/
178
179 /* This function gets one chunk of store and builds a list of pointers and all
180 of the captured substrings in it. A NULL pointer is put on the end of the list.
181
182 Arguments:
183 subject the subject string that was matched
184 ovector pointer to the offsets table
185 stringcount the number of substrings that were captured
186 (i.e. the yield of the pcre_exec call, unless
187 that was zero, in which case it should be 1/3
188 of the offset table size)
189 listptr set to point to the list of pointers
190
191 Returns: if successful: 0
192 if not successful:
193 PCRE_ERROR_NOMEMORY (-6) failed to get store
194 */
195
196 int
197 pcre_get_substring_list(const char *subject, int *ovector, int stringcount,
198 const char ***listptr)
199 {
200 int i;
201 int size = sizeof(char *);
202 int double_count = stringcount * 2;
203 char **stringlist;
204 char *p;
205
206 for (i = 0; i < double_count; i += 2)
207 size += sizeof(char *) + ovector[i+1] - ovector[i] + 1;
208
209 stringlist = (char **)(pcre_malloc)(size);
210 if (stringlist == NULL) return PCRE_ERROR_NOMEMORY;
211
212 *listptr = (const char **)stringlist;
213 p = (char *)(stringlist + stringcount + 1);
214
215 for (i = 0; i < double_count; i += 2)
216 {
217 int len = ovector[i+1] - ovector[i];
218 memcpy(p, subject + ovector[i], len);
219 *stringlist++ = p;
220 p += len;
221 *p++ = 0;
222 }
223
224 *stringlist = NULL;
225 return 0;
226 }
227
228
229
230 /*************************************************
231 * Free store obtained by get_substring_list *
232 *************************************************/
233
234 /* This function exists for the benefit of people calling PCRE from non-C
235 programs that can call its functions, but not free() or (pcre_free)() directly.
236
237 Argument: the result of a previous pcre_get_substring_list()
238 Returns: nothing
239 */
240
241 void
242 pcre_free_substring_list(const char **pointer)
243 {
244 (pcre_free)((void *)pointer);
245 }
246
247
248
249 /*************************************************
250 * Copy captured string to new store *
251 *************************************************/
252
253 /* This function copies a single captured substring into a piece of new
254 store
255
256 Arguments:
257 subject the subject string that was matched
258 ovector pointer to the offsets table
259 stringcount the number of substrings that were captured
260 (i.e. the yield of the pcre_exec call, unless
261 that was zero, in which case it should be 1/3
262 of the offset table size)
263 stringnumber the number of the required substring
264 stringptr where to put a pointer to the substring
265
266 Returns: if successful:
267 the length of the string, not including the zero that
268 is put on the end; can be zero
269 if not successful:
270 PCRE_ERROR_NOMEMORY (-6) failed to get store
271 PCRE_ERROR_NOSUBSTRING (-7) substring not present
272 */
273
274 int
275 pcre_get_substring(const char *subject, int *ovector, int stringcount,
276 int stringnumber, const char **stringptr)
277 {
278 int yield;
279 char *substring;
280 if (stringnumber < 0 || stringnumber >= stringcount)
281 return PCRE_ERROR_NOSUBSTRING;
282 stringnumber *= 2;
283 yield = ovector[stringnumber+1] - ovector[stringnumber];
284 substring = (char *)(pcre_malloc)(yield + 1);
285 if (substring == NULL) return PCRE_ERROR_NOMEMORY;
286 memcpy(substring, subject + ovector[stringnumber], yield);
287 substring[yield] = 0;
288 *stringptr = substring;
289 return yield;
290 }
291
292
293
294 /*************************************************
295 * Copy named captured string to new store *
296 *************************************************/
297
298 /* This function copies a single captured substring, identified by name, into
299 new store.
300
301 Arguments:
302 code the compiled regex
303 subject the subject string that was matched
304 ovector pointer to the offsets table
305 stringcount the number of substrings that were captured
306 (i.e. the yield of the pcre_exec call, unless
307 that was zero, in which case it should be 1/3
308 of the offset table size)
309 stringname the name of the required substring
310 stringptr where to put the pointer
311
312 Returns: if successful:
313 the length of the copied string, not including the zero
314 that is put on the end; can be zero
315 if not successful:
316 PCRE_ERROR_NOMEMORY (-6) couldn't get memory
317 PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
318 */
319
320 int
321 pcre_get_named_substring(const pcre *code, const char *subject, int *ovector,
322 int stringcount, const char *stringname, const char **stringptr)
323 {
324 int n = pcre_get_stringnumber(code, stringname);
325 if (n <= 0) return n;
326 return pcre_get_substring(subject, ovector, stringcount, n, stringptr);
327 }
328
329
330
331
332 /*************************************************
333 * Free store obtained by get_substring *
334 *************************************************/
335
336 /* This function exists for the benefit of people calling PCRE from non-C
337 programs that can call its functions, but not free() or (pcre_free)() directly.
338
339 Argument: the result of a previous pcre_get_substring()
340 Returns: nothing
341 */
342
343 void
344 pcre_free_substring(const char *pointer)
345 {
346 (pcre_free)((void *)pointer);
347 }
348
349 /* End of get.c */

webmaster@exim.org
ViewVC Help
Powered by ViewVC 1.1.12