1/*************************************************
2* Perl-Compatible Regular Expressions *
3*************************************************/
4
5/* PCRE is a library of functions to support regular expressions whose syntax
6and semantics are as close as possible to those of the Perl 5 language.
7
8 Written by Philip Hazel
9 Copyright (c) 1997-2012 University of Cambridge
10
11-----------------------------------------------------------------------------
12Redistribution and use in source and binary forms, with or without
13modification, 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
26THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
30LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36POSSIBILITY OF SUCH DAMAGE.
37-----------------------------------------------------------------------------
38*/
39
40
41/* This module contains some convenience functions for extracting substrings
42from the subject string after a regex match has succeeded. The original idea
43for these functions came from Scott Wimer. */
44
45
46#include "pcre_config.h"
47#include "pcre_internal.h"
48
49
50/*************************************************
51* Find number for named string *
52*************************************************/
53
54/* This function is used by the get_first_set() function below, as well
55as being generally available. It assumes that names are unique.
56
57Arguments:
58 code the compiled regex
59 stringname the name whose number is required
60
61Returns: the number of the named parentheses, or a negative number
62 (PCRE_ERROR_NOSUBSTRING) if not found
63*/
64
65#if defined COMPILE_PCRE8
66PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
67pcre_get_stringnumber(const pcre *code, const char *stringname)
68#elif defined COMPILE_PCRE16
69PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
70pcre16_get_stringnumber(const pcre16 *code, PCRE_SPTR16 stringname)
71#elif defined COMPILE_PCRE32
72PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
73pcre32_get_stringnumber(const pcre32 *code, PCRE_SPTR32 stringname)
74#endif
75{
76int rc;
77int entrysize;
78int top, bot;
79pcre_uchar *nametable;
80
81#ifdef COMPILE_PCRE8
82if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0)
83 return rc;
84if (top <= 0) return PCRE_ERROR_NOSUBSTRING;
85
86if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0)
87 return rc;
88if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0)
89 return rc;
90#endif
91#ifdef COMPILE_PCRE16
92if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0)
93 return rc;
94if (top <= 0) return PCRE_ERROR_NOSUBSTRING;
95
96if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0)
97 return rc;
98if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0)
99 return rc;
100#endif
101#ifdef COMPILE_PCRE32
102if ((rc = pcre32_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0)
103 return rc;
104if (top <= 0) return PCRE_ERROR_NOSUBSTRING;
105
106if ((rc = pcre32_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0)
107 return rc;
108if ((rc = pcre32_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0)
109 return rc;
110#endif
111
112bot = 0;
113while (top > bot)
114 {
115 int mid = (top + bot) / 2;
116 pcre_uchar *entry = nametable + entrysize*mid;
117 int c = STRCMP_UC_UC((pcre_uchar *)stringname,
118 (pcre_uchar *)(entry + IMM2_SIZE));
119 if (c == 0) return GET2(entry, 0);
120 if (c > 0) bot = mid + 1; else top = mid;
121 }
122
123return PCRE_ERROR_NOSUBSTRING;
124}
125
126
127
128/*************************************************
129* Find (multiple) entries for named string *
130*************************************************/
131
132/* This is used by the get_first_set() function below, as well as being
133generally available. It is used when duplicated names are permitted.
134
135Arguments:
136 code the compiled regex
137 stringname the name whose entries required
138 firstptr where to put the pointer to the first entry
139 lastptr where to put the pointer to the last entry
140
141Returns: the length of each entry, or a negative number
142 (PCRE_ERROR_NOSUBSTRING) if not found
143*/
144
145#if defined COMPILE_PCRE8
146PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
147pcre_get_stringtable_entries(const pcre *code, const char *stringname,
148 char **firstptr, char **lastptr)
149#elif defined COMPILE_PCRE16
150PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
151pcre16_get_stringtable_entries(const pcre16 *code, PCRE_SPTR16 stringname,
152 PCRE_UCHAR16 **firstptr, PCRE_UCHAR16 **lastptr)
153#elif defined COMPILE_PCRE32
154PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
155pcre32_get_stringtable_entries(const pcre32 *code, PCRE_SPTR32 stringname,
156 PCRE_UCHAR32 **firstptr, PCRE_UCHAR32 **lastptr)
157#endif
158{
159int rc;
160int entrysize;
161int top, bot;
162pcre_uchar *nametable, *lastentry;
163
164#ifdef COMPILE_PCRE8
165if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0)
166 return rc;
167if (top <= 0) return PCRE_ERROR_NOSUBSTRING;
168
169if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0)
170 return rc;
171if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0)
172 return rc;
173#endif
174#ifdef COMPILE_PCRE16
175if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0)
176 return rc;
177if (top <= 0) return PCRE_ERROR_NOSUBSTRING;
178
179if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0)
180 return rc;
181if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0)
182 return rc;
183#endif
184#ifdef COMPILE_PCRE32
185if ((rc = pcre32_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0)
186 return rc;
187if (top <= 0) return PCRE_ERROR_NOSUBSTRING;
188
189if ((rc = pcre32_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0)
190 return rc;
191if ((rc = pcre32_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0)
192 return rc;
193#endif
194
195lastentry = nametable + entrysize * (top - 1);
196bot = 0;
197while (top > bot)
198 {
199 int mid = (top + bot) / 2;
200 pcre_uchar *entry = nametable + entrysize*mid;
201 int c = STRCMP_UC_UC((pcre_uchar *)stringname,
202 (pcre_uchar *)(entry + IMM2_SIZE));
203 if (c == 0)
204 {
205 pcre_uchar *first = entry;
206 pcre_uchar *last = entry;
207 while (first > nametable)
208 {
209 if (STRCMP_UC_UC((pcre_uchar *)stringname,
210 (pcre_uchar *)(first - entrysize + IMM2_SIZE)) != 0) break;
211 first -= entrysize;
212 }
213 while (last < lastentry)
214 {
215 if (STRCMP_UC_UC((pcre_uchar *)stringname,
216 (pcre_uchar *)(last + entrysize + IMM2_SIZE)) != 0) break;
217 last += entrysize;
218 }
219#if defined COMPILE_PCRE8
220 *firstptr = (char *)first;
221 *lastptr = (char *)last;
222#elif defined COMPILE_PCRE16
223 *firstptr = (PCRE_UCHAR16 *)first;
224 *lastptr = (PCRE_UCHAR16 *)last;
225#elif defined COMPILE_PCRE32
226 *firstptr = (PCRE_UCHAR32 *)first;
227 *lastptr = (PCRE_UCHAR32 *)last;
228#endif
229 return entrysize;
230 }
231 if (c > 0) bot = mid + 1; else top = mid;
232 }
233
234return PCRE_ERROR_NOSUBSTRING;
235}
236
237
238
239/*************************************************
240* Find first set of multiple named strings *
241*************************************************/
242
243/* This function allows for duplicate names in the table of named substrings.
244It returns the number of the first one that was set in a pattern match.
245
246Arguments:
247 code the compiled regex
248 stringname the name of the capturing substring
249 ovector the vector of matched substrings
250 stringcount number of captured substrings
251
252Returns: the number of the first that is set,
253 or the number of the last one if none are set,
254 or a negative number on error
255*/
256
257#if defined COMPILE_PCRE8
258static int
259get_first_set(const pcre *code, const char *stringname, int *ovector,
260 int stringcount)
261#elif defined COMPILE_PCRE16
262static int
263get_first_set(const pcre16 *code, PCRE_SPTR16 stringname, int *ovector,
264 int stringcount)
265#elif defined COMPILE_PCRE32
266static int
267get_first_set(const pcre32 *code, PCRE_SPTR32 stringname, int *ovector,
268 int stringcount)
269#endif
270{
271const REAL_PCRE *re = (const REAL_PCRE *)code;
272int entrysize;
273pcre_uchar *entry;
274#if defined COMPILE_PCRE8
275char *first, *last;
276#elif defined COMPILE_PCRE16
277PCRE_UCHAR16 *first, *last;
278#elif defined COMPILE_PCRE32
279PCRE_UCHAR32 *first, *last;
280#endif
281
282#if defined COMPILE_PCRE8
283if ((re->options & PCRE_DUPNAMES) == 0 && (re->flags & PCRE_JCHANGED) == 0)
284 return pcre_get_stringnumber(code, stringname);
285entrysize = pcre_get_stringtable_entries(code, stringname, &first, &last);
286#elif defined COMPILE_PCRE16
287if ((re->options & PCRE_DUPNAMES) == 0 && (re->flags & PCRE_JCHANGED) == 0)
288 return pcre16_get_stringnumber(code, stringname);
289entrysize = pcre16_get_stringtable_entries(code, stringname, &first, &last);
290#elif defined COMPILE_PCRE32
291if ((re->options & PCRE_DUPNAMES) == 0 && (re->flags & PCRE_JCHANGED) == 0)
292 return pcre32_get_stringnumber(code, stringname);
293entrysize = pcre32_get_stringtable_entries(code, stringname, &first, &last);
294#endif
295if (entrysize <= 0) return entrysize;
296for (entry = (pcre_uchar *)first; entry <= (pcre_uchar *)last; entry += entrysize)
297 {
298 int n = GET2(entry, 0);
299 if (n < stringcount && ovector[n*2] >= 0) return n;
300 }
301return GET2(entry, 0);
302}
303
304
305
306
307/*************************************************
308* Copy captured string to given buffer *
309*************************************************/
310
311/* This function copies a single captured substring into a given buffer.
312Note that we use memcpy() rather than strncpy() in case there are binary zeros
313in the string.
314
315Arguments:
316 subject the subject string that was matched
317 ovector pointer to the offsets table
318 stringcount the number of substrings that were captured
319 (i.e. the yield of the pcre_exec call, unless
320 that was zero, in which case it should be 1/3
321 of the offset table size)
322 stringnumber the number of the required substring
323 buffer where to put the substring
324 size the size of the buffer
325
326Returns: if successful:
327 the length of the copied string, not including the zero
328 that is put on the end; can be zero
329 if not successful:
330 PCRE_ERROR_NOMEMORY (-6) buffer too small
331 PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
332*/
333
334#if defined COMPILE_PCRE8
335PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
336pcre_copy_substring(const char *subject, int *ovector, int stringcount,
337 int stringnumber, char *buffer, int size)
338#elif defined COMPILE_PCRE16
339PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
340pcre16_copy_substring(PCRE_SPTR16 subject, int *ovector, int stringcount,
341 int stringnumber, PCRE_UCHAR16 *buffer, int size)
342#elif defined COMPILE_PCRE32
343PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
344pcre32_copy_substring(PCRE_SPTR32 subject, int *ovector, int stringcount,
345 int stringnumber, PCRE_UCHAR32 *buffer, int size)
346#endif
347{
348int yield;
349if (stringnumber < 0 || stringnumber >= stringcount)
350 return PCRE_ERROR_NOSUBSTRING;
351stringnumber *= 2;
352yield = ovector[stringnumber+1] - ovector[stringnumber];
353if (size < yield + 1) return PCRE_ERROR_NOMEMORY;
354memcpy(buffer, subject + ovector[stringnumber], IN_UCHARS(yield));
355buffer[yield] = 0;
356return yield;
357}
358
359
360
361/*************************************************
362* Copy named captured string to given buffer *
363*************************************************/
364
365/* This function copies a single captured substring into a given buffer,
366identifying it by name. If the regex permits duplicate names, the first
367substring that is set is chosen.
368
369Arguments:
370 code the compiled regex
371 subject the subject string that was matched
372 ovector pointer to the offsets table
373 stringcount the number of substrings that were captured
374 (i.e. the yield of the pcre_exec call, unless
375 that was zero, in which case it should be 1/3
376 of the offset table size)
377 stringname the name of the required substring
378 buffer where to put the substring
379 size the size of the buffer
380
381Returns: if successful:
382 the length of the copied string, not including the zero
383 that is put on the end; can be zero
384 if not successful:
385 PCRE_ERROR_NOMEMORY (-6) buffer too small
386 PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
387*/
388
389#if defined COMPILE_PCRE8
390PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
391pcre_copy_named_substring(const pcre *code, const char *subject,
392 int *ovector, int stringcount, const char *stringname,
393 char *buffer, int size)
394#elif defined COMPILE_PCRE16
395PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
396pcre16_copy_named_substring(const pcre16 *code, PCRE_SPTR16 subject,
397 int *ovector, int stringcount, PCRE_SPTR16 stringname,
398 PCRE_UCHAR16 *buffer, int size)
399#elif defined COMPILE_PCRE32
400PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
401pcre32_copy_named_substring(const pcre32 *code, PCRE_SPTR32 subject,
402 int *ovector, int stringcount, PCRE_SPTR32 stringname,
403 PCRE_UCHAR32 *buffer, int size)
404#endif
405{
406int n = get_first_set(code, stringname, ovector, stringcount);
407if (n <= 0) return n;
408#if defined COMPILE_PCRE8
409return pcre_copy_substring(subject, ovector, stringcount, n, buffer, size);
410#elif defined COMPILE_PCRE16
411return pcre16_copy_substring(subject, ovector, stringcount, n, buffer, size);
412#elif defined COMPILE_PCRE32
413return pcre32_copy_substring(subject, ovector, stringcount, n, buffer, size);
414#endif
415}
416
417
418
419/*************************************************
420* Copy all captured strings to new store *
421*************************************************/
422
423/* This function gets one chunk of store and builds a list of pointers and all
424of the captured substrings in it. A NULL pointer is put on the end of the list.
425
426Arguments:
427 subject the subject string that was matched
428 ovector pointer to the offsets table
429 stringcount the number of substrings that were captured
430 (i.e. the yield of the pcre_exec call, unless
431 that was zero, in which case it should be 1/3
432 of the offset table size)
433 listptr set to point to the list of pointers
434
435Returns: if successful: 0
436 if not successful:
437 PCRE_ERROR_NOMEMORY (-6) failed to get store
438*/
439
440#if defined COMPILE_PCRE8
441PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
442pcre_get_substring_list(const char *subject, int *ovector, int stringcount,
443 const char ***listptr)
444#elif defined COMPILE_PCRE16
445PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
446pcre16_get_substring_list(PCRE_SPTR16 subject, int *ovector, int stringcount,
447 PCRE_SPTR16 **listptr)
448#elif defined COMPILE_PCRE32
449PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
450pcre32_get_substring_list(PCRE_SPTR32 subject, int *ovector, int stringcount,
451 PCRE_SPTR32 **listptr)
452#endif
453{
454int i;
455int size = sizeof(pcre_uchar *);
456int double_count = stringcount * 2;
457pcre_uchar **stringlist;
458pcre_uchar *p;
459
460for (i = 0; i < double_count; i += 2)
461 {
462 size += sizeof(pcre_uchar *) + IN_UCHARS(1);
463 if (ovector[i+1] > ovector[i]) size += IN_UCHARS(ovector[i+1] - ovector[i]);
464 }
465
466stringlist = (pcre_uchar **)(PUBL(malloc))(size);
467if (stringlist == NULL) return PCRE_ERROR_NOMEMORY;
468
469#if defined COMPILE_PCRE8
470*listptr = (const char **)stringlist;
471#elif defined COMPILE_PCRE16
472*listptr = (PCRE_SPTR16 *)stringlist;
473#elif defined COMPILE_PCRE32
474*listptr = (PCRE_SPTR32 *)stringlist;
475#endif
476p = (pcre_uchar *)(stringlist + stringcount + 1);
477
478for (i = 0; i < double_count; i += 2)
479 {
480 int len = (ovector[i+1] > ovector[i])? (ovector[i+1] - ovector[i]) : 0;
481 memcpy(p, subject + ovector[i], IN_UCHARS(len));
482 *stringlist++ = p;
483 p += len;
484 *p++ = 0;
485 }
486
487*stringlist = NULL;
488return 0;
489}
490
491
492
493/*************************************************
494* Free store obtained by get_substring_list *
495*************************************************/
496
497/* This function exists for the benefit of people calling PCRE from non-C
498programs that can call its functions, but not free() or (PUBL(free))()
499directly.
500
501Argument: the result of a previous pcre_get_substring_list()
502Returns: nothing
503*/
504
505#if defined COMPILE_PCRE8
506PCRE_EXP_DEFN void PCRE_CALL_CONVENTION
507pcre_free_substring_list(const char **pointer)
508#elif defined COMPILE_PCRE16
509PCRE_EXP_DEFN void PCRE_CALL_CONVENTION
510pcre16_free_substring_list(PCRE_SPTR16 *pointer)
511#elif defined COMPILE_PCRE32
512PCRE_EXP_DEFN void PCRE_CALL_CONVENTION
513pcre32_free_substring_list(PCRE_SPTR32 *pointer)
514#endif
515{
516(PUBL(free))((void *)pointer);
517}
518
519
520
521/*************************************************
522* Copy captured string to new store *
523*************************************************/
524
525/* This function copies a single captured substring into a piece of new
526store
527
528Arguments:
529 subject the subject string that was matched
530 ovector pointer to the offsets table
531 stringcount the number of substrings that were captured
532 (i.e. the yield of the pcre_exec call, unless
533 that was zero, in which case it should be 1/3
534 of the offset table size)
535 stringnumber the number of the required substring
536 stringptr where to put a pointer to the substring
537
538Returns: if successful:
539 the length of the string, not including the zero that
540 is put on the end; can be zero
541 if not successful:
542 PCRE_ERROR_NOMEMORY (-6) failed to get store
543 PCRE_ERROR_NOSUBSTRING (-7) substring not present
544*/
545
546#if defined COMPILE_PCRE8
547PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
548pcre_get_substring(const char *subject, int *ovector, int stringcount,
549 int stringnumber, const char **stringptr)
550#elif defined COMPILE_PCRE16
551PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
552pcre16_get_substring(PCRE_SPTR16 subject, int *ovector, int stringcount,
553 int stringnumber, PCRE_SPTR16 *stringptr)
554#elif defined COMPILE_PCRE32
555PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
556pcre32_get_substring(PCRE_SPTR32 subject, int *ovector, int stringcount,
557 int stringnumber, PCRE_SPTR32 *stringptr)
558#endif
559{
560int yield;
561pcre_uchar *substring;
562if (stringnumber < 0 || stringnumber >= stringcount)
563 return PCRE_ERROR_NOSUBSTRING;
564stringnumber *= 2;
565yield = ovector[stringnumber+1] - ovector[stringnumber];
566substring = (pcre_uchar *)(PUBL(malloc))(IN_UCHARS(yield + 1));
567if (substring == NULL) return PCRE_ERROR_NOMEMORY;
568memcpy(substring, subject + ovector[stringnumber], IN_UCHARS(yield));
569substring[yield] = 0;
570#if defined COMPILE_PCRE8
571*stringptr = (const char *)substring;
572#elif defined COMPILE_PCRE16
573*stringptr = (PCRE_SPTR16)substring;
574#elif defined COMPILE_PCRE32
575*stringptr = (PCRE_SPTR32)substring;
576#endif
577return yield;
578}
579
580
581
582/*************************************************
583* Copy named captured string to new store *
584*************************************************/
585
586/* This function copies a single captured substring, identified by name, into
587new store. If the regex permits duplicate names, the first substring that is
588set is chosen.
589
590Arguments:
591 code the compiled regex
592 subject the subject string that was matched
593 ovector pointer to the offsets table
594 stringcount the number of substrings that were captured
595 (i.e. the yield of the pcre_exec call, unless
596 that was zero, in which case it should be 1/3
597 of the offset table size)
598 stringname the name of the required substring
599 stringptr where to put the pointer
600
601Returns: if successful:
602 the length of the copied string, not including the zero
603 that is put on the end; can be zero
604 if not successful:
605 PCRE_ERROR_NOMEMORY (-6) couldn't get memory
606 PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
607*/
608
609#if defined COMPILE_PCRE8
610PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
611pcre_get_named_substring(const pcre *code, const char *subject,
612 int *ovector, int stringcount, const char *stringname,
613 const char **stringptr)
614#elif defined COMPILE_PCRE16
615PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
616pcre16_get_named_substring(const pcre16 *code, PCRE_SPTR16 subject,
617 int *ovector, int stringcount, PCRE_SPTR16 stringname,
618 PCRE_SPTR16 *stringptr)
619#elif defined COMPILE_PCRE32
620PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
621pcre32_get_named_substring(const pcre32 *code, PCRE_SPTR32 subject,
622 int *ovector, int stringcount, PCRE_SPTR32 stringname,
623 PCRE_SPTR32 *stringptr)
624#endif
625{
626int n = get_first_set(code, stringname, ovector, stringcount);
627if (n <= 0) return n;
628#if defined COMPILE_PCRE8
629return pcre_get_substring(subject, ovector, stringcount, n, stringptr);
630#elif defined COMPILE_PCRE16
631return pcre16_get_substring(subject, ovector, stringcount, n, stringptr);
632#elif defined COMPILE_PCRE32
633return pcre32_get_substring(subject, ovector, stringcount, n, stringptr);
634#endif
635}
636
637
638
639
640/*************************************************
641* Free store obtained by get_substring *
642*************************************************/
643
644/* This function exists for the benefit of people calling PCRE from non-C
645programs that can call its functions, but not free() or (PUBL(free))()
646directly.
647
648Argument: the result of a previous pcre_get_substring()
649Returns: nothing
650*/
651
652#if defined COMPILE_PCRE8
653PCRE_EXP_DEFN void PCRE_CALL_CONVENTION
654pcre_free_substring(const char *pointer)
655#elif defined COMPILE_PCRE16
656PCRE_EXP_DEFN void PCRE_CALL_CONVENTION
657pcre16_free_substring(PCRE_SPTR16 pointer)
658#elif defined COMPILE_PCRE32
659PCRE_EXP_DEFN void PCRE_CALL_CONVENTION
660pcre32_free_substring(PCRE_SPTR32 pointer)
661#endif
662{
663(PUBL(free))((void *)pointer);
664}
665
666/* End of pcre_get.c */
667