1 /* String functions which allocate strings on the pool.
2 * By Richard W.M. Jones <rich@annexia.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the Free
16 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 * $Id: pre.c,v 1.3 2003/01/22 14:29:37 rich Exp $
41 /* These private functions are used to capture memory allocations made
42 * by the PCRE library.
44 static void *malloc_in_pool (size_t);
45 static void do_nothing (void *);
46 static pool malloc_pool = 0;
49 precomp (pool pool, const char *pattern, int options)
54 void *(*old_malloc)(size_t);
55 void (*old_free) (void *);
57 /* Allocations to the pool. */
58 old_malloc = pcre_malloc;
60 pcre_malloc = malloc_in_pool;
62 pcre_free = do_nothing;
64 /* Compile the pattern. */
65 result = pcre_compile (pattern, options, &errptr, &erroffset, 0);
69 "pcre: internal error compiling regular expression:\n"
75 pchrs (pool, ' ', erroffset-1));
79 /* Restore memory allocation. */
80 pcre_malloc = old_malloc;
87 prematch (pool pool, const char *str, const pcre *pattern, int options)
89 int err, n, i, ovecsize;
92 void *(*old_malloc)(size_t);
93 void (*old_free) (void *);
95 /* Allocations to the pool. */
96 old_malloc = pcre_malloc;
98 pcre_malloc = malloc_in_pool;
100 pcre_free = do_nothing;
102 /* Get the number of capturing substrings in the pattern (n). */
103 if ((err = pcre_fullinfo (pattern, 0, PCRE_INFO_CAPTURECOUNT, &n)) != 0)
106 /* Allocate a vector large enough to contain the resulting substrings. */
107 ovecsize = (n+1) * 3;
108 ovector = alloca (ovecsize * sizeof (int));
110 /* Do the match. n is the number of strings found. */
111 n = pcre_exec (pattern, 0, str, strlen (str), 0, options, ovector, ovecsize);
113 /* Restore memory allocation. */
114 pcre_malloc = old_malloc;
115 pcre_free = old_free;
117 if (n == PCRE_ERROR_NOMATCH) /* No match, return NULL. */
119 else if (n <= 0) /* Some other error. */
122 /* Some matches. Construct the vector. */
123 result = new_vector (pool, char *);
124 for (i = 0; i < n; ++i)
127 int start = ovector[i*2];
128 int end = ovector[i*2+1];
131 s = pstrndup (pool, str + start, end - start);
132 vector_push_back (result, s);
138 static int do_match_and_sub (pool pool, const char *str, char **newstrp,
139 const pcre *pattern, const char *sub,
140 int startoffset, int options, int cc,
141 int *ovector, int ovecsize, int placeholders);
144 presubst (pool pool, const char *str,
145 const pcre *pattern, const char *sub,
148 char *newstr = pstrdup (pool, "");
149 int cc, err, n, ovecsize;
151 void *(*old_malloc)(size_t);
152 void (*old_free) (void *);
153 int placeholders = (options & PRESUBST_NO_PLACEHOLDERS) ? 0 : 1;
154 int global = (options & PRESUBST_GLOBAL) ? 1 : 0;
156 options &= ~(PRESUBST_NO_PLACEHOLDERS | PRESUBST_GLOBAL);
158 /* Allocations to the pool. */
159 old_malloc = pcre_malloc;
160 old_free = pcre_free;
161 pcre_malloc = malloc_in_pool;
163 pcre_free = do_nothing;
165 /* Get the number of capturing substrings in the pattern. */
166 if ((err = pcre_fullinfo (pattern, 0, PCRE_INFO_CAPTURECOUNT, &cc)) != 0)
169 /* Allocate a vector large enough to contain the resulting substrings. */
170 ovecsize = (cc+1) * 3;
171 ovector = alloca (ovecsize * sizeof (int));
173 /* Find a match and substitute. */
174 n = do_match_and_sub (pool, str, &newstr, pattern, sub, 0, options, cc,
175 ovector, ovecsize, placeholders);
179 /* Do the remaining matches. */
182 n = do_match_and_sub (pool, str, &newstr, pattern, sub, n,
184 ovector, ovecsize, placeholders);
189 /* Concatenate the remainder of the string. */
190 newstr = pstrcat (pool, newstr, str + n);
193 /* Restore memory allocation. */
194 pcre_malloc = old_malloc;
195 pcre_free = old_free;
201 do_match_and_sub (pool pool, const char *str, char **newstrp,
202 const pcre *pattern, const char *sub,
203 int startoffset, int options, int cc,
204 int *ovector, int ovecsize, int placeholders)
207 char *newstr = *newstrp;
209 /* Find the next match. */
210 err = pcre_exec (pattern, 0, str, strlen (str), startoffset,
211 options, ovector, ovecsize);
212 if (err == PCRE_ERROR_NOMATCH) /* No match. */
214 if (startoffset == 0)
215 /* Special case: we can just return the original string. */
216 *newstrp = (char *) str;
219 /* Concatenate the end of the string. */
220 newstr = pstrcat (pool, newstr, str + startoffset);
225 else if (err != cc+1) /* Some other error. */
228 /* Get position of the match. */
232 /* Substitute for the match. */
233 newstr = pstrncat (pool, newstr, str + startoffset, so - startoffset);
238 /* Substitute $1, $2, ... placeholders with captured substrings. */
239 for (i = 0; i < strlen (sub); ++i)
241 if (sub[i] == '$' && (sub[i+1] >= '0' && sub[i+1] <= '9'))
243 int n = sub[i+1] - '0';
246 newstr = pstrncat (pool, newstr, &sub[i], 2);
249 int nso = ovector[n*2];
250 int neo = ovector[n*2+1];
252 newstr = pstrncat (pool, newstr, str+nso, neo-nso);
258 newstr = pstrncat (pool, newstr, &sub[i], 1);
262 newstr = pstrcat (pool, newstr, sub);
269 malloc_in_pool (size_t n)
271 return pmalloc (malloc_pool, n);
277 /* Yes, really, do nothing. */