2 * Copyright (C) 1984-2011 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 about less, or for information on how to
8 * contact the author, see the README file.
12 * Routines to do pattern matching.
21 * Compile a search pattern, for future use by match_pattern.
24 compile_pattern2(pattern, search_type, comp_pattern)
29 if ((search_type & SRCH_NO_REGEX) == 0)
31 #if HAVE_POSIX_REGCOMP
32 regex_t *comp = (regex_t *) ecalloc(1, sizeof(regex_t));
33 regex_t **pcomp = (regex_t **) comp_pattern;
34 if (regcomp(comp, pattern, REGCOMP_FLAG))
37 error("Invalid pattern", NULL_PARG);
46 pcre **pcomp = (pcre **) comp_pattern;
47 const char *errstring;
50 comp = pcre_compile(pattern, 0,
51 &errstring, &erroffset, NULL);
54 parg.p_string = (char *) errstring;
62 int *pcomp = (int *) comp_pattern;
63 if ((parg.p_string = re_comp(pattern)) != NULL)
72 char **pcomp = (char **) comp_pattern;
73 if ((comp = regcmp(pattern, 0)) == NULL)
75 error("Invalid pattern", NULL_PARG);
84 struct regexp **pcomp = (struct regexp **) comp_pattern;
85 if ((comp = regcomp(pattern)) == NULL)
88 * regcomp has already printed an error message
102 * Like compile_pattern2, but convert the pattern to lowercase if necessary.
105 compile_pattern(pattern, search_type, comp_pattern)
113 if (caseless != OPT_ONPLUS)
114 cvt_pattern = pattern;
117 cvt_pattern = (char*) ecalloc(1, cvt_length(strlen(pattern), CVT_TO_LC));
118 cvt_text(cvt_pattern, pattern, (int *)NULL, (int *)NULL, CVT_TO_LC);
120 result = compile_pattern2(cvt_pattern, search_type, comp_pattern);
121 if (cvt_pattern != pattern)
127 * Forget that we have a compiled pattern.
130 uncompile_pattern(pattern)
133 #if HAVE_POSIX_REGCOMP
134 regex_t **pcomp = (regex_t **) pattern;
140 pcre **pcomp = (pcre **) pattern;
146 int *pcomp = (int *) pattern;
150 char **pcomp = (char **) pattern;
156 struct regexp **pcomp = (struct regexp **) pattern;
164 * Is a compiled pattern null?
167 is_null_pattern(pattern)
170 #if HAVE_POSIX_REGCOMP
171 return (pattern == NULL);
174 return (pattern == NULL);
177 return (pattern == 0);
180 return (pattern == NULL);
183 return (pattern == NULL);
186 return (search_pattern != NULL);
191 * Simple pattern matching function.
192 * It supports no metacharacters like *, etc.
195 match(pattern, pattern_len, buf, buf_len, pfound, pend)
200 char **pfound, **pend;
202 register char *pp, *lp;
203 register char *pattern_end = pattern + pattern_len;
204 register char *buf_end = buf + buf_len;
206 for ( ; buf < buf_end; buf++)
208 for (pp = pattern, lp = buf; *pp == *lp; pp++, lp++)
209 if (pp == pattern_end || lp == buf_end)
211 if (pp == pattern_end)
224 * Perform a pattern match with the previously compiled pattern.
225 * Set sp and ep to the start and end of the matched string.
228 match_pattern(pattern, tpattern, line, line_len, sp, ep, notbol, search_type)
239 #if HAVE_POSIX_REGCOMP
240 regex_t *spattern = (regex_t *) pattern;
243 pcre *spattern = (pcre *) pattern;
246 int spattern = (int) pattern;
249 char *spattern = (char *) pattern;
252 struct regexp *spattern = (struct regexp *) pattern;
255 if (search_type & SRCH_NO_REGEX)
256 matched = match(tpattern, strlen(tpattern), line, line_len, sp, ep);
259 #if HAVE_POSIX_REGCOMP
262 int flags = (notbol) ? REG_NOTBOL : 0;
263 matched = !regexec(spattern, line, 1, &rm, flags);
267 *sp = line + rm.rm_so;
268 *ep = line + rm.rm_eo;
278 int flags = (notbol) ? PCRE_NOTBOL : 0;
280 matched = pcre_exec(spattern, NULL, line, line_len,
281 0, flags, ovector, 3) >= 0;
284 *sp = line + ovector[0];
285 *ep = line + ovector[1];
290 matched = (re_exec(line) == 1);
292 * re_exec doesn't seem to provide a way to get the matched string.
297 *ep = regex(spattern, line);
298 matched = (*ep != NULL);
304 matched = regexec2(spattern, line, notbol);
306 matched = regexec(spattern, line);
310 *sp = spattern->startp[0];
311 *ep = spattern->endp[0];
315 matched = match(tpattern, strlen(tpattern), line, line_len, sp, ep);
318 matched = (!(search_type & SRCH_NO_MATCH) && matched) ||
319 ((search_type & SRCH_NO_MATCH) && !matched);