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