xref: /netbsd-src/external/bsd/less/dist/pattern.c (revision 838f5788460f0f133b15d706e644d692a9d4d6ec)
1*838f5788Ssimonb /*	$NetBSD: pattern.c,v 1.4 2023/10/06 05:49:49 simonb Exp $	*/
220006a0bStron 
320006a0bStron /*
4*838f5788Ssimonb  * Copyright (C) 1984-2023  Mark Nudelman
520006a0bStron  *
620006a0bStron  * You may distribute under the terms of either the GNU General Public
720006a0bStron  * License or the Less License, as specified in the README file.
820006a0bStron  *
9ec18bca0Stron  * For more information, see the README file.
1020006a0bStron  */
1120006a0bStron 
1220006a0bStron /*
1320006a0bStron  * Routines to do pattern matching.
1420006a0bStron  */
1520006a0bStron 
1620006a0bStron #include "less.h"
1720006a0bStron 
1820006a0bStron extern int caseless;
19*838f5788Ssimonb extern int is_caseless;
20*838f5788Ssimonb extern int utf_mode;
2120006a0bStron 
2220006a0bStron /*
2320006a0bStron  * Compile a search pattern, for future use by match_pattern.
2420006a0bStron  */
compile_pattern2(char * pattern,int search_type,PATTERN_TYPE * comp_pattern,int show_error)25*838f5788Ssimonb static int compile_pattern2(char *pattern, int search_type, PATTERN_TYPE *comp_pattern, int show_error)
2620006a0bStron {
27ec18bca0Stron 	if (search_type & SRCH_NO_REGEX)
28ec18bca0Stron 		return (0);
2920006a0bStron   {
30ec18bca0Stron #if HAVE_GNU_REGEX
31ec18bca0Stron 	struct re_pattern_buffer *comp = (struct re_pattern_buffer *)
32ec18bca0Stron 		ecalloc(1, sizeof(struct re_pattern_buffer));
33ec18bca0Stron 	re_set_syntax(RE_SYNTAX_POSIX_EXTENDED);
34ec18bca0Stron 	if (re_compile_pattern(pattern, strlen(pattern), comp))
35ec18bca0Stron 	{
36ec18bca0Stron 		free(comp);
37*838f5788Ssimonb 		if (show_error)
38ec18bca0Stron 			error("Invalid pattern", NULL_PARG);
39ec18bca0Stron 		return (-1);
40ec18bca0Stron 	}
41*838f5788Ssimonb 	if (*comp_pattern != NULL)
42*838f5788Ssimonb 	{
43*838f5788Ssimonb 		regfree(*comp_pattern);
44*838f5788Ssimonb 		free(*comp_pattern);
45*838f5788Ssimonb 	}
46*838f5788Ssimonb 	*comp_pattern = comp;
47ec18bca0Stron #endif
4820006a0bStron #if HAVE_POSIX_REGCOMP
4920006a0bStron 	regex_t *comp = (regex_t *) ecalloc(1, sizeof(regex_t));
50*838f5788Ssimonb 	if (regcomp(comp, pattern, REGCOMP_FLAG | (is_caseless ? REG_ICASE : 0)))
5120006a0bStron 	{
5220006a0bStron 		free(comp);
53*838f5788Ssimonb 		if (show_error)
5420006a0bStron 			error("Invalid pattern", NULL_PARG);
5520006a0bStron 		return (-1);
5620006a0bStron 	}
57*838f5788Ssimonb 	if (*comp_pattern != NULL)
58*838f5788Ssimonb 	{
59*838f5788Ssimonb 		regfree(*comp_pattern);
60*838f5788Ssimonb 		free(*comp_pattern);
61*838f5788Ssimonb 	}
62*838f5788Ssimonb 	*comp_pattern = comp;
6320006a0bStron #endif
6420006a0bStron #if HAVE_PCRE
65ec18bca0Stron 	constant char *errstring;
6620006a0bStron 	int erroffset;
6720006a0bStron 	PARG parg;
68*838f5788Ssimonb 	pcre *comp = pcre_compile(pattern,
69*838f5788Ssimonb 			((utf_mode) ? PCRE_UTF8 | PCRE_NO_UTF8_CHECK : 0) |
70*838f5788Ssimonb 			(is_caseless ? PCRE_CASELESS : 0),
7120006a0bStron 			&errstring, &erroffset, NULL);
7220006a0bStron 	if (comp == NULL)
7320006a0bStron 	{
7420006a0bStron 		parg.p_string = (char *) errstring;
75*838f5788Ssimonb 		if (show_error)
7620006a0bStron 			error("%s", &parg);
7720006a0bStron 		return (-1);
7820006a0bStron 	}
79*838f5788Ssimonb 	*comp_pattern = comp;
80*838f5788Ssimonb #endif
81*838f5788Ssimonb #if HAVE_PCRE2
82*838f5788Ssimonb 	int errcode;
83*838f5788Ssimonb 	PCRE2_SIZE erroffset;
84*838f5788Ssimonb 	PARG parg;
85*838f5788Ssimonb 	pcre2_code *comp = pcre2_compile((PCRE2_SPTR)pattern, strlen(pattern),
86*838f5788Ssimonb 			(is_caseless ? PCRE2_CASELESS : 0),
87*838f5788Ssimonb 			&errcode, &erroffset, NULL);
88*838f5788Ssimonb 	if (comp == NULL)
89*838f5788Ssimonb 	{
90*838f5788Ssimonb 		if (show_error)
91*838f5788Ssimonb 		{
92*838f5788Ssimonb 			char msg[160];
93*838f5788Ssimonb 			pcre2_get_error_message(errcode, (PCRE2_UCHAR*)msg, sizeof(msg));
94*838f5788Ssimonb 			parg.p_string = msg;
95*838f5788Ssimonb 			error("%s", &parg);
96*838f5788Ssimonb 		}
97*838f5788Ssimonb 		return (-1);
98*838f5788Ssimonb 	}
99*838f5788Ssimonb 	*comp_pattern = comp;
10020006a0bStron #endif
10120006a0bStron #if HAVE_RE_COMP
10220006a0bStron 	PARG parg;
10320006a0bStron 	if ((parg.p_string = re_comp(pattern)) != NULL)
10420006a0bStron 	{
105*838f5788Ssimonb 		if (show_error)
10620006a0bStron 			error("%s", &parg);
10720006a0bStron 		return (-1);
10820006a0bStron 	}
109*838f5788Ssimonb 	*comp_pattern = 1;
11020006a0bStron #endif
11120006a0bStron #if HAVE_REGCMP
11220006a0bStron 	char *comp;
11320006a0bStron 	if ((comp = regcmp(pattern, 0)) == NULL)
11420006a0bStron 	{
115*838f5788Ssimonb 		if (show_error)
11620006a0bStron 			error("Invalid pattern", NULL_PARG);
11720006a0bStron 		return (-1);
11820006a0bStron 	}
119*838f5788Ssimonb 	if (comp_pattern != NULL)
120*838f5788Ssimonb 		free(*comp_pattern);
121*838f5788Ssimonb 	*comp_pattern = comp;
12220006a0bStron #endif
12320006a0bStron #if HAVE_V8_REGCOMP
12420006a0bStron 	struct regexp *comp;
125*838f5788Ssimonb 	reg_show_error = show_error;
126*838f5788Ssimonb 	comp = regcomp(pattern);
127*838f5788Ssimonb 	reg_show_error = 1;
128*838f5788Ssimonb 	if (comp == NULL)
12920006a0bStron 	{
13020006a0bStron 		/*
13120006a0bStron 		 * regcomp has already printed an error message
13220006a0bStron 		 * via regerror().
13320006a0bStron 		 */
13420006a0bStron 		return (-1);
13520006a0bStron 	}
136*838f5788Ssimonb 	if (*comp_pattern != NULL)
137*838f5788Ssimonb 		free(*comp_pattern);
138*838f5788Ssimonb 	*comp_pattern = comp;
13920006a0bStron #endif
14020006a0bStron   }
14120006a0bStron 	return (0);
14220006a0bStron }
14320006a0bStron 
14420006a0bStron /*
14520006a0bStron  * Like compile_pattern2, but convert the pattern to lowercase if necessary.
14620006a0bStron  */
compile_pattern(char * pattern,int search_type,int show_error,PATTERN_TYPE * comp_pattern)147*838f5788Ssimonb public int compile_pattern(char *pattern, int search_type, int show_error, PATTERN_TYPE *comp_pattern)
14820006a0bStron {
14920006a0bStron 	char *cvt_pattern;
15020006a0bStron 	int result;
15120006a0bStron 
152*838f5788Ssimonb 	if (caseless != OPT_ONPLUS || (re_handles_caseless && !(search_type & SRCH_NO_REGEX)))
15320006a0bStron 		cvt_pattern = pattern;
15420006a0bStron 	else
15520006a0bStron 	{
15620006a0bStron 		cvt_pattern = (char*) ecalloc(1, cvt_length(strlen(pattern), CVT_TO_LC));
15720006a0bStron 		cvt_text(cvt_pattern, pattern, (int *)NULL, (int *)NULL, CVT_TO_LC);
15820006a0bStron 	}
159*838f5788Ssimonb 	result = compile_pattern2(cvt_pattern, search_type, comp_pattern, show_error);
16020006a0bStron 	if (cvt_pattern != pattern)
16120006a0bStron 		free(cvt_pattern);
16220006a0bStron 	return (result);
16320006a0bStron }
16420006a0bStron 
16520006a0bStron /*
16620006a0bStron  * Forget that we have a compiled pattern.
16720006a0bStron  */
uncompile_pattern(PATTERN_TYPE * pattern)168*838f5788Ssimonb public void uncompile_pattern(PATTERN_TYPE *pattern)
16920006a0bStron {
170ec18bca0Stron #if HAVE_GNU_REGEX
171*838f5788Ssimonb 	if (*pattern != NULL)
172*838f5788Ssimonb 	{
173*838f5788Ssimonb 		regfree(*pattern);
174*838f5788Ssimonb 		free(*pattern);
175*838f5788Ssimonb 	}
176*838f5788Ssimonb 	*pattern = NULL;
177ec18bca0Stron #endif
17820006a0bStron #if HAVE_POSIX_REGCOMP
179*838f5788Ssimonb 	if (*pattern != NULL)
180*838f5788Ssimonb 	{
181*838f5788Ssimonb 		regfree(*pattern);
182*838f5788Ssimonb 		free(*pattern);
183*838f5788Ssimonb 	}
184*838f5788Ssimonb 	*pattern = NULL;
18520006a0bStron #endif
18620006a0bStron #if HAVE_PCRE
187*838f5788Ssimonb 	if (*pattern != NULL)
188*838f5788Ssimonb 		pcre_free(*pattern);
189*838f5788Ssimonb 	*pattern = NULL;
190*838f5788Ssimonb #endif
191*838f5788Ssimonb #if HAVE_PCRE2
192*838f5788Ssimonb 	if (*pattern != NULL)
193*838f5788Ssimonb 		pcre2_code_free(*pattern);
194*838f5788Ssimonb 	*pattern = NULL;
19520006a0bStron #endif
19620006a0bStron #if HAVE_RE_COMP
197*838f5788Ssimonb 	*pattern = 0;
19820006a0bStron #endif
19920006a0bStron #if HAVE_REGCMP
200*838f5788Ssimonb 	if (*pattern != NULL)
201*838f5788Ssimonb 		free(*pattern);
202*838f5788Ssimonb 	*pattern = NULL;
20320006a0bStron #endif
20420006a0bStron #if HAVE_V8_REGCOMP
205*838f5788Ssimonb 	if (*pattern != NULL)
206*838f5788Ssimonb 		free(*pattern);
207*838f5788Ssimonb 	*pattern = NULL;
20820006a0bStron #endif
20920006a0bStron }
21020006a0bStron 
211*838f5788Ssimonb #if 0
212*838f5788Ssimonb /*
213*838f5788Ssimonb  * Can a pattern be successfully compiled?
214*838f5788Ssimonb  */
215*838f5788Ssimonb public int valid_pattern(char *pattern)
216*838f5788Ssimonb {
217*838f5788Ssimonb 	PATTERN_TYPE comp_pattern;
218*838f5788Ssimonb 	int result;
219*838f5788Ssimonb 
220*838f5788Ssimonb 	SET_NULL_PATTERN(comp_pattern);
221*838f5788Ssimonb 	result = compile_pattern2(pattern, 0, &comp_pattern, 0);
222*838f5788Ssimonb 	if (result != 0)
223*838f5788Ssimonb 		return (0);
224*838f5788Ssimonb 	uncompile_pattern(&comp_pattern);
225*838f5788Ssimonb 	return (1);
226*838f5788Ssimonb }
227*838f5788Ssimonb #endif
228*838f5788Ssimonb 
22920006a0bStron /*
23020006a0bStron  * Is a compiled pattern null?
23120006a0bStron  */
is_null_pattern(PATTERN_TYPE pattern)232*838f5788Ssimonb public int is_null_pattern(PATTERN_TYPE pattern)
23320006a0bStron {
234ec18bca0Stron #if HAVE_GNU_REGEX
235ec18bca0Stron 	return (pattern == NULL);
236ec18bca0Stron #endif
23720006a0bStron #if HAVE_POSIX_REGCOMP
23820006a0bStron 	return (pattern == NULL);
23920006a0bStron #endif
24020006a0bStron #if HAVE_PCRE
24120006a0bStron 	return (pattern == NULL);
24220006a0bStron #endif
243*838f5788Ssimonb #if HAVE_PCRE2
244*838f5788Ssimonb 	return (pattern == NULL);
245*838f5788Ssimonb #endif
24620006a0bStron #if HAVE_RE_COMP
24720006a0bStron 	return (pattern == 0);
24820006a0bStron #endif
24920006a0bStron #if HAVE_REGCMP
25020006a0bStron 	return (pattern == NULL);
25120006a0bStron #endif
25220006a0bStron #if HAVE_V8_REGCOMP
25320006a0bStron 	return (pattern == NULL);
25420006a0bStron #endif
255*838f5788Ssimonb #if NO_REGEX
256*838f5788Ssimonb 	return (pattern == NULL);
257*838f5788Ssimonb #endif
25820006a0bStron }
25920006a0bStron /*
26020006a0bStron  * Simple pattern matching function.
26120006a0bStron  * It supports no metacharacters like *, etc.
26220006a0bStron  */
match(char * pattern,int pattern_len,char * buf,int buf_len,char *** sp,char *** ep,int nsubs)263*838f5788Ssimonb static int match(char *pattern, int pattern_len, char *buf, int buf_len, char ***sp, char ***ep, int nsubs)
26420006a0bStron {
265*838f5788Ssimonb 	char *pp, *lp;
266*838f5788Ssimonb 	char *pattern_end = pattern + pattern_len;
267*838f5788Ssimonb 	char *buf_end = buf + buf_len;
26820006a0bStron 
26920006a0bStron 	for ( ;  buf < buf_end;  buf++)
27020006a0bStron 	{
271*838f5788Ssimonb 		for (pp = pattern, lp = buf;  ;  pp++, lp++)
272*838f5788Ssimonb 		{
273*838f5788Ssimonb 			char cp = *pp;
274*838f5788Ssimonb 			char cl = *lp;
275*838f5788Ssimonb 			if (caseless == OPT_ONPLUS && ASCII_IS_UPPER(cp))
276*838f5788Ssimonb 				cp = ASCII_TO_LOWER(cp);
277*838f5788Ssimonb 			if (cp != cl)
278*838f5788Ssimonb 				break;
27920006a0bStron 			if (pp == pattern_end || lp == buf_end)
28020006a0bStron 				break;
281*838f5788Ssimonb 		}
28220006a0bStron 		if (pp == pattern_end)
28320006a0bStron 		{
284*838f5788Ssimonb 			*(*sp)++ = buf;
285*838f5788Ssimonb 			*(*ep)++ = lp;
28620006a0bStron 			return (1);
28720006a0bStron 		}
28820006a0bStron 	}
289*838f5788Ssimonb 	**sp = **ep = NULL;
29020006a0bStron 	return (0);
29120006a0bStron }
29220006a0bStron 
29320006a0bStron /*
29420006a0bStron  * Perform a pattern match with the previously compiled pattern.
295*838f5788Ssimonb  * Set sp[0] and ep[0] to the start and end of the matched string.
296*838f5788Ssimonb  * Set sp[i] and ep[i] to the start and end of the i-th matched subpattern.
297*838f5788Ssimonb  * Subpatterns are defined by parentheses in the regex language.
29820006a0bStron  */
match_pattern1(PATTERN_TYPE pattern,char * tpattern,char * line,int line_len,char ** sp,char ** ep,int nsp,int notbol,int search_type)299*838f5788Ssimonb static int match_pattern1(PATTERN_TYPE pattern, char *tpattern, char *line, int line_len, char **sp, char **ep, int nsp, int notbol, int search_type)
30020006a0bStron {
30120006a0bStron 	int matched;
30220006a0bStron 
303ec18bca0Stron #if NO_REGEX
304ec18bca0Stron 	search_type |= SRCH_NO_REGEX;
305ec18bca0Stron #endif
30620006a0bStron 	if (search_type & SRCH_NO_REGEX)
307*838f5788Ssimonb 		matched = match(tpattern, strlen(tpattern), line, line_len, &sp, &ep, nsp);
30820006a0bStron 	else
30920006a0bStron 	{
310ec18bca0Stron #if HAVE_GNU_REGEX
311ec18bca0Stron 	{
312ec18bca0Stron 		struct re_registers search_regs;
313*838f5788Ssimonb 		pattern->not_bol = notbol;
314*838f5788Ssimonb 		pattern->regs_allocated = REGS_UNALLOCATED;
315*838f5788Ssimonb 		matched = re_search(pattern, line, line_len, 0, line_len, &search_regs) >= 0;
316ec18bca0Stron 		if (matched)
317ec18bca0Stron 		{
318*838f5788Ssimonb 			*sp++ = line + search_regs.start[0];
319*838f5788Ssimonb 			*ep++ = line + search_regs.end[0];
320ec18bca0Stron 		}
321ec18bca0Stron 	}
322ec18bca0Stron #endif
32320006a0bStron #if HAVE_POSIX_REGCOMP
32420006a0bStron 	{
325*838f5788Ssimonb 		#define RM_COUNT (NUM_SEARCH_COLORS+2)
326*838f5788Ssimonb 		regmatch_t rm[RM_COUNT];
32720006a0bStron 		int flags = (notbol) ? REG_NOTBOL : 0;
328*838f5788Ssimonb #ifdef REG_STARTEND
329*838f5788Ssimonb 		flags |= REG_STARTEND;
330*838f5788Ssimonb 		rm[0].rm_so = 0;
331*838f5788Ssimonb 		rm[0].rm_eo = line_len;
332*838f5788Ssimonb #endif
333*838f5788Ssimonb 		matched = !regexec(pattern, line, RM_COUNT, rm, flags);
33420006a0bStron 		if (matched)
33520006a0bStron 		{
336*838f5788Ssimonb 			int i;
337*838f5788Ssimonb 			int ecount;
338*838f5788Ssimonb 			for (ecount = RM_COUNT;  ecount > 0;  ecount--)
339*838f5788Ssimonb 				if (rm[ecount-1].rm_so >= 0)
340*838f5788Ssimonb 					break;
341*838f5788Ssimonb 			if (ecount >= nsp)
342*838f5788Ssimonb 				ecount = nsp-1;
343*838f5788Ssimonb 			for (i = 0;  i < ecount;  i++)
344*838f5788Ssimonb 			{
345*838f5788Ssimonb 				if (rm[i].rm_so < 0)
346*838f5788Ssimonb 				{
347*838f5788Ssimonb 					*sp++ = *ep++ = line;
348*838f5788Ssimonb 				} else
349*838f5788Ssimonb 				{
35020006a0bStron #ifndef __WATCOMC__
351*838f5788Ssimonb 					*sp++ = line + rm[i].rm_so;
352*838f5788Ssimonb 					*ep++ = line + rm[i].rm_eo;
35320006a0bStron #else
354*838f5788Ssimonb 					*sp++ = rm[i].rm_sp;
355*838f5788Ssimonb 					*ep++ = rm[i].rm_ep;
35620006a0bStron #endif
35720006a0bStron 				}
35820006a0bStron 			}
359*838f5788Ssimonb 		}
360*838f5788Ssimonb 	}
36120006a0bStron #endif
36220006a0bStron #if HAVE_PCRE
36320006a0bStron 	{
364*838f5788Ssimonb 		#define OVECTOR_COUNT ((3*NUM_SEARCH_COLORS)+3)
365*838f5788Ssimonb 		int ovector[OVECTOR_COUNT];
36620006a0bStron 		int flags = (notbol) ? PCRE_NOTBOL : 0;
367*838f5788Ssimonb 		int i;
368*838f5788Ssimonb 		int ecount;
369*838f5788Ssimonb 		int mcount = pcre_exec(pattern, NULL, line, line_len,
370*838f5788Ssimonb 			0, flags, ovector, OVECTOR_COUNT);
371*838f5788Ssimonb 		matched = (mcount > 0);
372*838f5788Ssimonb 		ecount = nsp-1;
373*838f5788Ssimonb 		if (ecount > mcount) ecount = mcount;
374*838f5788Ssimonb 		for (i = 0;  i < ecount*2; )
375*838f5788Ssimonb 		{
376*838f5788Ssimonb 			if (ovector[i] < 0 || ovector[i+1] < 0)
377*838f5788Ssimonb 			{
378*838f5788Ssimonb 				*sp++ = *ep++ = line;
379*838f5788Ssimonb 				i += 2;
380*838f5788Ssimonb 			} else
381*838f5788Ssimonb 			{
382*838f5788Ssimonb 				*sp++ = line + ovector[i++];
383*838f5788Ssimonb 				*ep++ = line + ovector[i++];
384*838f5788Ssimonb 			}
385*838f5788Ssimonb 		}
386*838f5788Ssimonb 	}
387*838f5788Ssimonb #endif
388*838f5788Ssimonb #if HAVE_PCRE2
389*838f5788Ssimonb 	{
390*838f5788Ssimonb 		int flags = (notbol) ? PCRE2_NOTBOL : 0;
391*838f5788Ssimonb 		pcre2_match_data *md = pcre2_match_data_create(nsp-1, NULL);
392*838f5788Ssimonb 		int mcount = pcre2_match(pattern, (PCRE2_SPTR)line, line_len,
393*838f5788Ssimonb 			0, flags, md, NULL);
394*838f5788Ssimonb 		matched = (mcount > 0);
39520006a0bStron 		if (matched)
39620006a0bStron 		{
397*838f5788Ssimonb 			PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(md);
398*838f5788Ssimonb 			int i;
399*838f5788Ssimonb 			int ecount = nsp-1;
400*838f5788Ssimonb 			if (ecount > mcount) ecount = mcount;
401*838f5788Ssimonb 			for (i = 0;  i < ecount*2; )
402*838f5788Ssimonb 			{
403*838f5788Ssimonb 				if (ovector[i] < 0 || ovector[i+1] < 0)
404*838f5788Ssimonb 				{
405*838f5788Ssimonb 					*sp++ = *ep++ = line;
406*838f5788Ssimonb 					i += 2;
407*838f5788Ssimonb 				} else
408*838f5788Ssimonb 				{
409*838f5788Ssimonb 					*sp++ = line + ovector[i++];
410*838f5788Ssimonb 					*ep++ = line + ovector[i++];
41120006a0bStron 				}
41220006a0bStron 			}
413*838f5788Ssimonb 		}
414*838f5788Ssimonb 		pcre2_match_data_free(md);
415*838f5788Ssimonb 	}
41620006a0bStron #endif
41720006a0bStron #if HAVE_RE_COMP
41820006a0bStron 	matched = (re_exec(line) == 1);
41920006a0bStron 	/*
42020006a0bStron 	 * re_exec doesn't seem to provide a way to get the matched string.
42120006a0bStron 	 */
42220006a0bStron #endif
42320006a0bStron #if HAVE_REGCMP
424*838f5788Ssimonb 	matched = ((*ep++ = regex(pattern, line)) != NULL);
42520006a0bStron 	if (matched)
426*838f5788Ssimonb 		*sp++ = __loc1;
42720006a0bStron #endif
42820006a0bStron #if HAVE_V8_REGCOMP
42920006a0bStron #if HAVE_REGEXEC2
430*838f5788Ssimonb 	matched = regexec2(pattern, line, notbol);
43120006a0bStron #else
432*838f5788Ssimonb 	matched = regexec(pattern, line);
43320006a0bStron #endif
43420006a0bStron 	if (matched)
43520006a0bStron 	{
436*838f5788Ssimonb 		*sp++ = pattern->startp[0];
437*838f5788Ssimonb 		*ep++ = pattern->endp[0];
43820006a0bStron 	}
43920006a0bStron #endif
44020006a0bStron 	}
441*838f5788Ssimonb 	*sp = *ep = NULL;
44220006a0bStron 	matched = (!(search_type & SRCH_NO_MATCH) && matched) ||
44320006a0bStron 			((search_type & SRCH_NO_MATCH) && !matched);
44420006a0bStron 	return (matched);
44520006a0bStron }
44620006a0bStron 
match_pattern(PATTERN_TYPE pattern,char * tpattern,char * line,int line_len,char ** sp,char ** ep,int nsp,int notbol,int search_type)447*838f5788Ssimonb public int match_pattern(PATTERN_TYPE pattern, char *tpattern, char *line, int line_len, char **sp, char **ep, int nsp, int notbol, int search_type)
448*838f5788Ssimonb {
449*838f5788Ssimonb 	int matched = match_pattern1(pattern, tpattern, line, line_len, sp, ep, nsp, notbol, search_type);
450*838f5788Ssimonb 	int i;
451*838f5788Ssimonb 	for (i = 1;  i <= NUM_SEARCH_COLORS;  i++)
452*838f5788Ssimonb 	{
453*838f5788Ssimonb 		if ((search_type & SRCH_SUBSEARCH(i)) && ep[i] == sp[i])
454*838f5788Ssimonb 			matched = 0;
455*838f5788Ssimonb 	}
456*838f5788Ssimonb 	return matched;
457*838f5788Ssimonb }
458*838f5788Ssimonb 
459*838f5788Ssimonb /*
460*838f5788Ssimonb  * Return the name of the pattern matching library.
461*838f5788Ssimonb  */
pattern_lib_name(void)462*838f5788Ssimonb public char * pattern_lib_name(void)
463*838f5788Ssimonb {
464*838f5788Ssimonb #if HAVE_GNU_REGEX
465*838f5788Ssimonb 	return ("GNU");
466*838f5788Ssimonb #else
467*838f5788Ssimonb #if HAVE_POSIX_REGCOMP
468*838f5788Ssimonb 	return ("POSIX");
469*838f5788Ssimonb #else
470*838f5788Ssimonb #if HAVE_PCRE2
471*838f5788Ssimonb 	return ("PCRE2");
472*838f5788Ssimonb #else
473*838f5788Ssimonb #if HAVE_PCRE
474*838f5788Ssimonb 	return ("PCRE");
475*838f5788Ssimonb #else
476*838f5788Ssimonb #if HAVE_RE_COMP
477*838f5788Ssimonb 	return ("BSD");
478*838f5788Ssimonb #else
479*838f5788Ssimonb #if HAVE_REGCMP
480*838f5788Ssimonb 	return ("V8");
481*838f5788Ssimonb #else
482*838f5788Ssimonb #if HAVE_V8_REGCOMP
483*838f5788Ssimonb 	return ("Spencer V8");
484*838f5788Ssimonb #else
485*838f5788Ssimonb 	return ("no");
486*838f5788Ssimonb #endif
487*838f5788Ssimonb #endif
488*838f5788Ssimonb #endif
489*838f5788Ssimonb #endif
490*838f5788Ssimonb #endif
491*838f5788Ssimonb #endif
492*838f5788Ssimonb #endif
493*838f5788Ssimonb }
494