2 * Copyright (C) 1984-2012 Mark Nudelman
4 * You may distribute under the terms of either the GNU General Public
5 * License or the Less License, as specified in the README file.
7 * For more information, see the README file.
11 * Routines to do pattern matching.
20 * Compile a search pattern, for future use by match_pattern.
23 compile_pattern2(pattern, search_type, comp_pattern)
28 if (search_type & SRCH_NO_REGEX)
32 struct re_pattern_buffer *comp = (struct re_pattern_buffer *)
33 ecalloc(1, sizeof(struct re_pattern_buffer));
34 struct re_pattern_buffer **pcomp =
35 (struct re_pattern_buffer **) comp_pattern;
36 re_set_syntax(RE_SYNTAX_POSIX_EXTENDED);
37 if (re_compile_pattern(pattern, strlen(pattern), comp))
40 error("Invalid pattern", NULL_PARG);
47 #if HAVE_POSIX_REGCOMP
48 regex_t *comp = (regex_t *) ecalloc(1, sizeof(regex_t));
49 regex_t **pcomp = (regex_t **) comp_pattern;
50 if (regcomp(comp, pattern, REGCOMP_FLAG))
53 error("Invalid pattern", NULL_PARG);
62 pcre **pcomp = (pcre **) comp_pattern;
63 constant char *errstring;
66 comp = pcre_compile(pattern, 0,
67 &errstring, &erroffset, NULL);
70 parg.p_string = (char *) errstring;
78 int *pcomp = (int *) comp_pattern;
79 if ((parg.p_string = re_comp(pattern)) != NULL)
88 char **pcomp = (char **) comp_pattern;
89 if ((comp = regcmp(pattern, 0)) == NULL)
91 error("Invalid pattern", NULL_PARG);
100 struct regexp **pcomp = (struct regexp **) comp_pattern;
101 if ((comp = regcomp(pattern)) == NULL)
104 * regcomp has already printed an error message
118 * Like compile_pattern2, but convert the pattern to lowercase if necessary.
121 compile_pattern(pattern, search_type, comp_pattern)
129 if (caseless != OPT_ONPLUS)
130 cvt_pattern = pattern;
133 cvt_pattern = (char*) ecalloc(1, cvt_length(strlen(pattern), CVT_TO_LC));
134 cvt_text(cvt_pattern, pattern, (int *)NULL, (int *)NULL, CVT_TO_LC);
136 result = compile_pattern2(cvt_pattern, search_type, comp_pattern);
137 if (cvt_pattern != pattern)
143 * Forget that we have a compiled pattern.
146 uncompile_pattern(pattern)
150 struct re_pattern_buffer **pcomp = (struct re_pattern_buffer **) pattern;
155 #if HAVE_POSIX_REGCOMP
156 regex_t **pcomp = (regex_t **) pattern;
162 pcre **pcomp = (pcre **) pattern;
168 int *pcomp = (int *) pattern;
172 char **pcomp = (char **) pattern;
178 struct regexp **pcomp = (struct regexp **) pattern;
186 * Is a compiled pattern null?
189 is_null_pattern(pattern)
193 return (pattern == NULL);
195 #if HAVE_POSIX_REGCOMP
196 return (pattern == NULL);
199 return (pattern == NULL);
202 return (pattern == 0);
205 return (pattern == NULL);
208 return (pattern == NULL);
213 * Simple pattern matching function.
214 * It supports no metacharacters like *, etc.
217 match(pattern, pattern_len, buf, buf_len, pfound, pend)
222 char **pfound, **pend;
224 register char *pp, *lp;
225 register char *pattern_end = pattern + pattern_len;
226 register char *buf_end = buf + buf_len;
228 for ( ; buf < buf_end; buf++)
230 for (pp = pattern, lp = buf; *pp == *lp; pp++, lp++)
231 if (pp == pattern_end || lp == buf_end)
233 if (pp == pattern_end)
246 * Perform a pattern match with the previously compiled pattern.
247 * Set sp and ep to the start and end of the matched string.
250 match_pattern(pattern, tpattern, line, line_len, sp, ep, notbol, search_type)
262 struct re_pattern_buffer *spattern = (struct re_pattern_buffer *) pattern;
264 #if HAVE_POSIX_REGCOMP
265 regex_t *spattern = (regex_t *) pattern;
268 pcre *spattern = (pcre *) pattern;
271 int spattern = (int) pattern;
274 char *spattern = (char *) pattern;
277 struct regexp *spattern = (struct regexp *) pattern;
281 search_type |= SRCH_NO_REGEX;
283 if (search_type & SRCH_NO_REGEX)
284 matched = match(tpattern, strlen(tpattern), line, line_len, sp, ep);
289 struct re_registers search_regs;
290 regoff_t *starts = (regoff_t *) ecalloc(1, sizeof (regoff_t));
291 regoff_t *ends = (regoff_t *) ecalloc(1, sizeof (regoff_t));
292 spattern->not_bol = notbol;
293 re_set_registers(spattern, &search_regs, 1, starts, ends);
294 matched = re_search(spattern, line, line_len, 0, line_len, &search_regs) >= 0;
297 *sp = line + search_regs.start[0];
298 *ep = line + search_regs.end[0];
304 #if HAVE_POSIX_REGCOMP
307 int flags = (notbol) ? REG_NOTBOL : 0;
308 matched = !regexec(spattern, line, 1, &rm, flags);
312 *sp = line + rm.rm_so;
313 *ep = line + rm.rm_eo;
323 int flags = (notbol) ? PCRE_NOTBOL : 0;
325 matched = pcre_exec(spattern, NULL, line, line_len,
326 0, flags, ovector, 3) >= 0;
329 *sp = line + ovector[0];
330 *ep = line + ovector[1];
335 matched = (re_exec(line) == 1);
337 * re_exec doesn't seem to provide a way to get the matched string.
342 *ep = regex(spattern, line);
343 matched = (*ep != NULL);
349 matched = regexec2(spattern, line, notbol);
351 matched = regexec(spattern, line);
355 *sp = spattern->startp[0];
356 *ep = spattern->endp[0];
360 matched = (!(search_type & SRCH_NO_MATCH) && matched) ||
361 ((search_type & SRCH_NO_MATCH) && !matched);