2 * Copyright (C) 1984-2017 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.
19 * Compile a search pattern, for future use by match_pattern.
22 compile_pattern2(pattern, search_type, comp_pattern, show_error)
25 PATTERN_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 re_set_syntax(RE_SYNTAX_POSIX_EXTENDED);
35 if (re_compile_pattern(pattern, strlen(pattern), comp))
39 error("Invalid pattern", NULL_PARG);
42 if (*comp_pattern != NULL)
44 regfree(*comp_pattern);
49 #if HAVE_POSIX_REGCOMP
50 regex_t *comp = (regex_t *) ecalloc(1, sizeof(regex_t));
51 if (regcomp(comp, pattern, REGCOMP_FLAG))
55 error("Invalid pattern", NULL_PARG);
58 if (*comp_pattern != NULL)
60 regfree(*comp_pattern);
67 constant char *errstring;
70 comp = pcre_compile(pattern, 0,
71 &errstring, &erroffset, NULL);
74 parg.p_string = (char *) errstring;
83 if ((parg.p_string = re_comp(pattern)) != NULL)
93 if ((comp = regcmp(pattern, 0)) == NULL)
96 error("Invalid pattern", NULL_PARG);
99 if (comp_pattern != NULL)
101 *comp_pattern = comp;
105 reg_show_error = show_error;
106 comp = regcomp(pattern);
111 * regcomp has already printed an error message
116 if (*comp_pattern != NULL)
118 *comp_pattern = comp;
125 * Like compile_pattern2, but convert the pattern to lowercase if necessary.
128 compile_pattern(pattern, search_type, comp_pattern)
131 PATTERN_TYPE *comp_pattern;
136 if (caseless != OPT_ONPLUS)
137 cvt_pattern = pattern;
140 cvt_pattern = (char*) ecalloc(1, cvt_length(strlen(pattern), CVT_TO_LC));
141 cvt_text(cvt_pattern, pattern, (int *)NULL, (int *)NULL, CVT_TO_LC);
143 result = compile_pattern2(cvt_pattern, search_type, comp_pattern, 1);
144 if (cvt_pattern != pattern)
150 * Forget that we have a compiled pattern.
153 uncompile_pattern(pattern)
154 PATTERN_TYPE *pattern;
157 if (*pattern != NULL)
164 #if HAVE_POSIX_REGCOMP
165 if (*pattern != NULL)
173 if (*pattern != NULL)
181 if (*pattern != NULL)
186 if (*pattern != NULL)
193 * Can a pattern be successfully compiled?
196 valid_pattern(pattern)
199 PATTERN_TYPE comp_pattern;
202 CLEAR_PATTERN(comp_pattern);
203 result = compile_pattern2(pattern, 0, &comp_pattern, 0);
206 uncompile_pattern(&comp_pattern);
211 * Is a compiled pattern null?
214 is_null_pattern(pattern)
215 PATTERN_TYPE pattern;
218 return (pattern == NULL);
220 #if HAVE_POSIX_REGCOMP
221 return (pattern == NULL);
224 return (pattern == NULL);
227 return (pattern == 0);
230 return (pattern == NULL);
233 return (pattern == NULL);
236 return (pattern == NULL);
241 * Simple pattern matching function.
242 * It supports no metacharacters like *, etc.
245 match(pattern, pattern_len, buf, buf_len, pfound, pend)
250 char **pfound, **pend;
253 char *pattern_end = pattern + pattern_len;
254 char *buf_end = buf + buf_len;
256 for ( ; buf < buf_end; buf++)
258 for (pp = pattern, lp = buf; ; pp++, lp++)
262 if (caseless == OPT_ONPLUS && ASCII_IS_UPPER(cp))
263 cp = ASCII_TO_LOWER(cp);
266 if (pp == pattern_end || lp == buf_end)
269 if (pp == pattern_end)
282 * Perform a pattern match with the previously compiled pattern.
283 * Set sp and ep to the start and end of the matched string.
286 match_pattern(pattern, tpattern, line, line_len, sp, ep, notbol, search_type)
287 PATTERN_TYPE pattern;
300 search_type |= SRCH_NO_REGEX;
302 if (search_type & SRCH_NO_REGEX)
303 matched = match(tpattern, strlen(tpattern), line, line_len, sp, ep);
308 struct re_registers search_regs;
309 pattern->not_bol = notbol;
310 pattern->regs_allocated = REGS_UNALLOCATED;
311 matched = re_search(pattern, line, line_len, 0, line_len, &search_regs) >= 0;
314 *sp = line + search_regs.start[0];
315 *ep = line + search_regs.end[0];
319 #if HAVE_POSIX_REGCOMP
322 int flags = (notbol) ? REG_NOTBOL : 0;
324 flags |= REG_STARTEND;
328 matched = !regexec(pattern, line, 1, &rm, flags);
332 *sp = line + rm.rm_so;
333 *ep = line + rm.rm_eo;
343 int flags = (notbol) ? PCRE_NOTBOL : 0;
345 matched = pcre_exec(pattern, NULL, line, line_len,
346 0, flags, ovector, 3) >= 0;
349 *sp = line + ovector[0];
350 *ep = line + ovector[1];
355 matched = (re_exec(line) == 1);
357 * re_exec doesn't seem to provide a way to get the matched string.
362 *ep = regex(pattern, line);
363 matched = (*ep != NULL);
369 matched = regexec2(pattern, line, notbol);
371 matched = regexec(pattern, line);
375 *sp = pattern->startp[0];
376 *ep = pattern->endp[0];
380 matched = (!(search_type & SRCH_NO_MATCH) && matched) ||
381 ((search_type & SRCH_NO_MATCH) && !matched);