1f0be0a1fSXin LI /* 2*c77c4889SXin LI * Copyright (C) 1984-2024 Mark Nudelman 3f0be0a1fSXin LI * 4f0be0a1fSXin LI * You may distribute under the terms of either the GNU General Public 5f0be0a1fSXin LI * License or the Less License, as specified in the README file. 6f0be0a1fSXin LI * 796e55cc7SXin LI * For more information, see the README file. 8f0be0a1fSXin LI */ 9f0be0a1fSXin LI 10f0be0a1fSXin LI /* 11f0be0a1fSXin LI * Routines to do pattern matching. 12f0be0a1fSXin LI */ 13f0be0a1fSXin LI 14f0be0a1fSXin LI #include "less.h" 15f0be0a1fSXin LI 16f0be0a1fSXin LI extern int caseless; 1795270f73SXin LI extern int is_caseless; 18b7780dbeSXin LI extern int utf_mode; 19f0be0a1fSXin LI 20f0be0a1fSXin LI /* 21f0be0a1fSXin LI * Compile a search pattern, for future use by match_pattern. 22f0be0a1fSXin LI */ 23*c77c4889SXin LI static int compile_pattern2(constant char *pattern, int search_type, PATTERN_TYPE *comp_pattern, int show_error) 24f0be0a1fSXin LI { 2596e55cc7SXin LI if (search_type & SRCH_NO_REGEX) 2696e55cc7SXin LI return (0); 27f0be0a1fSXin LI { 2896e55cc7SXin LI #if HAVE_GNU_REGEX 2996e55cc7SXin LI struct re_pattern_buffer *comp = (struct re_pattern_buffer *) 3096e55cc7SXin LI ecalloc(1, sizeof(struct re_pattern_buffer)); 3196e55cc7SXin LI re_set_syntax(RE_SYNTAX_POSIX_EXTENDED); 3296e55cc7SXin LI if (re_compile_pattern(pattern, strlen(pattern), comp)) 3396e55cc7SXin LI { 3496e55cc7SXin LI free(comp); 35a15691bfSXin LI if (show_error) 3696e55cc7SXin LI error("Invalid pattern", NULL_PARG); 3796e55cc7SXin LI return (-1); 3896e55cc7SXin LI } 39f6b74a7dSXin LI if (*comp_pattern != NULL) 40f6b74a7dSXin LI { 41f6b74a7dSXin LI regfree(*comp_pattern); 42f6b74a7dSXin LI free(*comp_pattern); 43f6b74a7dSXin LI } 44f6b74a7dSXin LI *comp_pattern = comp; 4596e55cc7SXin LI #endif 46f0be0a1fSXin LI #if HAVE_POSIX_REGCOMP 47f0be0a1fSXin LI regex_t *comp = (regex_t *) ecalloc(1, sizeof(regex_t)); 4895270f73SXin LI if (regcomp(comp, pattern, REGCOMP_FLAG | (is_caseless ? REG_ICASE : 0))) 49f0be0a1fSXin LI { 50f0be0a1fSXin LI free(comp); 51a15691bfSXin LI if (show_error) 52f0be0a1fSXin LI error("Invalid pattern", NULL_PARG); 53f0be0a1fSXin LI return (-1); 54f0be0a1fSXin LI } 55f6b74a7dSXin LI if (*comp_pattern != NULL) 56f6b74a7dSXin LI { 57f6b74a7dSXin LI regfree(*comp_pattern); 58f6b74a7dSXin LI free(*comp_pattern); 59f6b74a7dSXin LI } 60f6b74a7dSXin LI *comp_pattern = comp; 61f0be0a1fSXin LI #endif 62f0be0a1fSXin LI #if HAVE_PCRE 6396e55cc7SXin LI constant char *errstring; 64f0be0a1fSXin LI int erroffset; 65f0be0a1fSXin LI PARG parg; 66b7780dbeSXin LI pcre *comp = pcre_compile(pattern, 6795270f73SXin LI ((utf_mode) ? PCRE_UTF8 | PCRE_NO_UTF8_CHECK : 0) | 6895270f73SXin LI (is_caseless ? PCRE_CASELESS : 0), 69f0be0a1fSXin LI &errstring, &erroffset, NULL); 70f0be0a1fSXin LI if (comp == NULL) 71f0be0a1fSXin LI { 72f0be0a1fSXin LI parg.p_string = (char *) errstring; 73a15691bfSXin LI if (show_error) 74f0be0a1fSXin LI error("%s", &parg); 75f0be0a1fSXin LI return (-1); 76f0be0a1fSXin LI } 77f6b74a7dSXin LI *comp_pattern = comp; 78f0be0a1fSXin LI #endif 79b7780dbeSXin LI #if HAVE_PCRE2 80b7780dbeSXin LI int errcode; 81b7780dbeSXin LI PCRE2_SIZE erroffset; 82b7780dbeSXin LI PARG parg; 83b7780dbeSXin LI pcre2_code *comp = pcre2_compile((PCRE2_SPTR)pattern, strlen(pattern), 8495270f73SXin LI (is_caseless ? PCRE2_CASELESS : 0), 8595270f73SXin LI &errcode, &erroffset, NULL); 86b7780dbeSXin LI if (comp == NULL) 87b7780dbeSXin LI { 88b7780dbeSXin LI if (show_error) 89b7780dbeSXin LI { 90b7780dbeSXin LI char msg[160]; 91b7780dbeSXin LI pcre2_get_error_message(errcode, (PCRE2_UCHAR*)msg, sizeof(msg)); 92b7780dbeSXin LI parg.p_string = msg; 93b7780dbeSXin LI error("%s", &parg); 94b7780dbeSXin LI } 95b7780dbeSXin LI return (-1); 96b7780dbeSXin LI } 97b7780dbeSXin LI *comp_pattern = comp; 98b7780dbeSXin LI #endif 99f0be0a1fSXin LI #if HAVE_RE_COMP 100f0be0a1fSXin LI PARG parg; 101f0be0a1fSXin LI if ((parg.p_string = re_comp(pattern)) != NULL) 102f0be0a1fSXin LI { 103a15691bfSXin LI if (show_error) 104f0be0a1fSXin LI error("%s", &parg); 105f0be0a1fSXin LI return (-1); 106f0be0a1fSXin LI } 107f6b74a7dSXin LI *comp_pattern = 1; 108f0be0a1fSXin LI #endif 109f0be0a1fSXin LI #if HAVE_REGCMP 110f0be0a1fSXin LI char *comp; 111f0be0a1fSXin LI if ((comp = regcmp(pattern, 0)) == NULL) 112f0be0a1fSXin LI { 113a15691bfSXin LI if (show_error) 114f0be0a1fSXin LI error("Invalid pattern", NULL_PARG); 115f0be0a1fSXin LI return (-1); 116f0be0a1fSXin LI } 117f6b74a7dSXin LI if (comp_pattern != NULL) 118f6b74a7dSXin LI free(*comp_pattern); 119f6b74a7dSXin LI *comp_pattern = comp; 120f0be0a1fSXin LI #endif 121f0be0a1fSXin LI #if HAVE_V8_REGCOMP 122f0be0a1fSXin LI struct regexp *comp; 123a15691bfSXin LI reg_show_error = show_error; 124a15691bfSXin LI comp = regcomp(pattern); 125a15691bfSXin LI reg_show_error = 1; 126a15691bfSXin LI if (comp == NULL) 127f0be0a1fSXin LI { 128f0be0a1fSXin LI /* 129f0be0a1fSXin LI * regcomp has already printed an error message 130f0be0a1fSXin LI * via regerror(). 131f0be0a1fSXin LI */ 132f0be0a1fSXin LI return (-1); 133f0be0a1fSXin LI } 134f6b74a7dSXin LI if (*comp_pattern != NULL) 135f6b74a7dSXin LI free(*comp_pattern); 136f6b74a7dSXin LI *comp_pattern = comp; 137f0be0a1fSXin LI #endif 138f0be0a1fSXin LI } 139f0be0a1fSXin LI return (0); 140f0be0a1fSXin LI } 141f0be0a1fSXin LI 142f0be0a1fSXin LI /* 143f0be0a1fSXin LI * Like compile_pattern2, but convert the pattern to lowercase if necessary. 144f0be0a1fSXin LI */ 145*c77c4889SXin LI public int compile_pattern(constant char *pattern, int search_type, int show_error, PATTERN_TYPE *comp_pattern) 146f0be0a1fSXin LI { 147f0be0a1fSXin LI int result; 148f0be0a1fSXin LI 149d713e089SXin LI if (caseless != OPT_ONPLUS || (re_handles_caseless && !(search_type & SRCH_NO_REGEX))) 150f0be0a1fSXin LI { 151*c77c4889SXin LI result = compile_pattern2(pattern, search_type, comp_pattern, show_error); 152*c77c4889SXin LI } else 153*c77c4889SXin LI { 154*c77c4889SXin LI char *cvt_pattern = (char*) ecalloc(1, cvt_length(strlen(pattern), CVT_TO_LC)); 155*c77c4889SXin LI cvt_text(cvt_pattern, pattern, NULL, NULL, CVT_TO_LC); 1562235c7feSXin LI result = compile_pattern2(cvt_pattern, search_type, comp_pattern, show_error); 157f0be0a1fSXin LI free(cvt_pattern); 158*c77c4889SXin LI } 159f0be0a1fSXin LI return (result); 160f0be0a1fSXin LI } 161f0be0a1fSXin LI 162f0be0a1fSXin LI /* 163f0be0a1fSXin LI * Forget that we have a compiled pattern. 164f0be0a1fSXin LI */ 165d713e089SXin LI public void uncompile_pattern(PATTERN_TYPE *pattern) 166f0be0a1fSXin LI { 16796e55cc7SXin LI #if HAVE_GNU_REGEX 168f6b74a7dSXin LI if (*pattern != NULL) 169f6b74a7dSXin LI { 170f6b74a7dSXin LI regfree(*pattern); 171f6b74a7dSXin LI free(*pattern); 172f6b74a7dSXin LI } 173f6b74a7dSXin LI *pattern = NULL; 17496e55cc7SXin LI #endif 175f0be0a1fSXin LI #if HAVE_POSIX_REGCOMP 176f6b74a7dSXin LI if (*pattern != NULL) 177f6b74a7dSXin LI { 178f6b74a7dSXin LI regfree(*pattern); 179f6b74a7dSXin LI free(*pattern); 180f6b74a7dSXin LI } 181f6b74a7dSXin LI *pattern = NULL; 182f0be0a1fSXin LI #endif 183f0be0a1fSXin LI #if HAVE_PCRE 184f6b74a7dSXin LI if (*pattern != NULL) 185f6b74a7dSXin LI pcre_free(*pattern); 186f6b74a7dSXin LI *pattern = NULL; 187f0be0a1fSXin LI #endif 188b7780dbeSXin LI #if HAVE_PCRE2 189b7780dbeSXin LI if (*pattern != NULL) 190b7780dbeSXin LI pcre2_code_free(*pattern); 191b7780dbeSXin LI *pattern = NULL; 192b7780dbeSXin LI #endif 193f0be0a1fSXin LI #if HAVE_RE_COMP 194f6b74a7dSXin LI *pattern = 0; 195f0be0a1fSXin LI #endif 196f0be0a1fSXin LI #if HAVE_REGCMP 197f6b74a7dSXin LI if (*pattern != NULL) 198f6b74a7dSXin LI free(*pattern); 199f6b74a7dSXin LI *pattern = NULL; 200f0be0a1fSXin LI #endif 201f0be0a1fSXin LI #if HAVE_V8_REGCOMP 202f6b74a7dSXin LI if (*pattern != NULL) 203f6b74a7dSXin LI free(*pattern); 204f6b74a7dSXin LI *pattern = NULL; 205f0be0a1fSXin LI #endif 206f0be0a1fSXin LI } 207f0be0a1fSXin LI 2082235c7feSXin LI #if 0 209f0be0a1fSXin LI /* 210a15691bfSXin LI * Can a pattern be successfully compiled? 211a15691bfSXin LI */ 212d713e089SXin LI public int valid_pattern(char *pattern) 213a15691bfSXin LI { 214f6b74a7dSXin LI PATTERN_TYPE comp_pattern; 215a15691bfSXin LI int result; 216a15691bfSXin LI 2172235c7feSXin LI SET_NULL_PATTERN(comp_pattern); 218a15691bfSXin LI result = compile_pattern2(pattern, 0, &comp_pattern, 0); 219a15691bfSXin LI if (result != 0) 220a15691bfSXin LI return (0); 221a15691bfSXin LI uncompile_pattern(&comp_pattern); 222a15691bfSXin LI return (1); 223a15691bfSXin LI } 2242235c7feSXin LI #endif 225a15691bfSXin LI 226a15691bfSXin LI /* 227f0be0a1fSXin LI * Is a compiled pattern null? 228f0be0a1fSXin LI */ 229*c77c4889SXin LI public lbool is_null_pattern(PATTERN_TYPE pattern) 230f0be0a1fSXin LI { 23196e55cc7SXin LI #if HAVE_GNU_REGEX 23296e55cc7SXin LI return (pattern == NULL); 23396e55cc7SXin LI #endif 234f0be0a1fSXin LI #if HAVE_POSIX_REGCOMP 235f0be0a1fSXin LI return (pattern == NULL); 236f0be0a1fSXin LI #endif 237f0be0a1fSXin LI #if HAVE_PCRE 238f0be0a1fSXin LI return (pattern == NULL); 239f0be0a1fSXin LI #endif 240b7780dbeSXin LI #if HAVE_PCRE2 241b7780dbeSXin LI return (pattern == NULL); 242b7780dbeSXin LI #endif 243f0be0a1fSXin LI #if HAVE_RE_COMP 244f0be0a1fSXin LI return (pattern == 0); 245f0be0a1fSXin LI #endif 246f0be0a1fSXin LI #if HAVE_REGCMP 247f0be0a1fSXin LI return (pattern == NULL); 248f0be0a1fSXin LI #endif 249f0be0a1fSXin LI #if HAVE_V8_REGCOMP 250f0be0a1fSXin LI return (pattern == NULL); 251f0be0a1fSXin LI #endif 252a15691bfSXin LI #if NO_REGEX 253a15691bfSXin LI return (pattern == NULL); 254a15691bfSXin LI #endif 255f0be0a1fSXin LI } 256f0be0a1fSXin LI /* 257f0be0a1fSXin LI * Simple pattern matching function. 258f0be0a1fSXin LI * It supports no metacharacters like *, etc. 259f0be0a1fSXin LI */ 260*c77c4889SXin LI static int match(constant char *pattern, size_t pattern_len, constant char *buf, int buf_len, constant char ***sp, constant char ***ep, int nsubs) 261f0be0a1fSXin LI { 262*c77c4889SXin LI constant char *pp; 263*c77c4889SXin LI constant char *lp; 264*c77c4889SXin LI constant char *pattern_end = pattern + pattern_len; 265*c77c4889SXin LI constant char *buf_end = buf + buf_len; 266f0be0a1fSXin LI 267*c77c4889SXin LI (void) nsubs; 268f0be0a1fSXin LI for ( ; buf < buf_end; buf++) 269f0be0a1fSXin LI { 270a15691bfSXin LI for (pp = pattern, lp = buf; ; pp++, lp++) 271a15691bfSXin LI { 272a15691bfSXin LI char cp = *pp; 273a15691bfSXin LI char cl = *lp; 274a15691bfSXin LI if (caseless == OPT_ONPLUS && ASCII_IS_UPPER(cp)) 275a15691bfSXin LI cp = ASCII_TO_LOWER(cp); 276a15691bfSXin LI if (cp != cl) 277a15691bfSXin LI break; 278f0be0a1fSXin LI if (pp == pattern_end || lp == buf_end) 279f0be0a1fSXin LI break; 280a15691bfSXin LI } 281f0be0a1fSXin LI if (pp == pattern_end) 282f0be0a1fSXin LI { 283d713e089SXin LI *(*sp)++ = buf; 284d713e089SXin LI *(*ep)++ = lp; 285f0be0a1fSXin LI return (1); 286f0be0a1fSXin LI } 287f0be0a1fSXin LI } 288d713e089SXin LI **sp = **ep = NULL; 289f0be0a1fSXin LI return (0); 290f0be0a1fSXin LI } 291f0be0a1fSXin LI 292f0be0a1fSXin LI /* 293f0be0a1fSXin LI * Perform a pattern match with the previously compiled pattern. 294d713e089SXin LI * Set sp[0] and ep[0] to the start and end of the matched string. 295d713e089SXin LI * Set sp[i] and ep[i] to the start and end of the i-th matched subpattern. 296d713e089SXin LI * Subpatterns are defined by parentheses in the regex language. 297f0be0a1fSXin LI */ 298*c77c4889SXin LI static int match_pattern1(PATTERN_TYPE pattern, constant char *tpattern, constant char *line, size_t aline_len, constant char **sp, constant char **ep, int nsp, int notbol, int search_type) 299f0be0a1fSXin LI { 300f0be0a1fSXin LI int matched; 301*c77c4889SXin LI int line_len = (int) aline_len; /*{{type-issue}}*/ 302f0be0a1fSXin LI 30396e55cc7SXin LI #if NO_REGEX 30496e55cc7SXin LI search_type |= SRCH_NO_REGEX; 30596e55cc7SXin LI #endif 306f0be0a1fSXin LI if (search_type & SRCH_NO_REGEX) 307d713e089SXin LI matched = match(tpattern, strlen(tpattern), line, line_len, &sp, &ep, nsp); 308f0be0a1fSXin LI else 309f0be0a1fSXin LI { 31096e55cc7SXin LI #if HAVE_GNU_REGEX 31196e55cc7SXin LI { 31296e55cc7SXin LI struct re_registers search_regs; 313f6b74a7dSXin LI pattern->not_bol = notbol; 314f6b74a7dSXin LI pattern->regs_allocated = REGS_UNALLOCATED; 315f6b74a7dSXin LI matched = re_search(pattern, line, line_len, 0, line_len, &search_regs) >= 0; 31696e55cc7SXin LI if (matched) 31796e55cc7SXin LI { 318d713e089SXin LI *sp++ = line + search_regs.start[0]; 319d713e089SXin LI *ep++ = line + search_regs.end[0]; 32096e55cc7SXin LI } 32196e55cc7SXin LI } 32296e55cc7SXin LI #endif 323f0be0a1fSXin LI #if HAVE_POSIX_REGCOMP 324f0be0a1fSXin LI { 325d713e089SXin LI #define RM_COUNT (NUM_SEARCH_COLORS+2) 326d713e089SXin LI regmatch_t rm[RM_COUNT]; 327f0be0a1fSXin LI int flags = (notbol) ? REG_NOTBOL : 0; 328a15691bfSXin LI #ifdef REG_STARTEND 329a15691bfSXin LI flags |= REG_STARTEND; 330d713e089SXin LI rm[0].rm_so = 0; 331d713e089SXin LI rm[0].rm_eo = line_len; 332a15691bfSXin LI #endif 333d713e089SXin LI matched = !regexec(pattern, line, RM_COUNT, rm, flags); 334f0be0a1fSXin LI if (matched) 335f0be0a1fSXin LI { 336d713e089SXin LI int i; 337d713e089SXin LI int ecount; 338d713e089SXin LI for (ecount = RM_COUNT; ecount > 0; ecount--) 339d713e089SXin LI if (rm[ecount-1].rm_so >= 0) 340d713e089SXin LI break; 341d713e089SXin LI if (ecount >= nsp) 342d713e089SXin LI ecount = nsp-1; 343d713e089SXin LI for (i = 0; i < ecount; i++) 344d713e089SXin LI { 345d713e089SXin LI if (rm[i].rm_so < 0) 346d713e089SXin LI { 347d713e089SXin LI *sp++ = *ep++ = line; 348d713e089SXin LI } else 349d713e089SXin LI { 350f0be0a1fSXin LI #ifndef __WATCOMC__ 351d713e089SXin LI *sp++ = line + rm[i].rm_so; 352d713e089SXin LI *ep++ = line + rm[i].rm_eo; 353f0be0a1fSXin LI #else 354d713e089SXin LI *sp++ = rm[i].rm_sp; 355d713e089SXin LI *ep++ = rm[i].rm_ep; 356f0be0a1fSXin LI #endif 357f0be0a1fSXin LI } 358f0be0a1fSXin LI } 359d713e089SXin LI } 360d713e089SXin LI } 361f0be0a1fSXin LI #endif 362f0be0a1fSXin LI #if HAVE_PCRE 363f0be0a1fSXin LI { 364d713e089SXin LI #define OVECTOR_COUNT ((3*NUM_SEARCH_COLORS)+3) 365d713e089SXin LI int ovector[OVECTOR_COUNT]; 366f0be0a1fSXin LI int flags = (notbol) ? PCRE_NOTBOL : 0; 367d713e089SXin LI int i; 368d713e089SXin LI int ecount; 369d713e089SXin LI int mcount = pcre_exec(pattern, NULL, line, line_len, 370d713e089SXin LI 0, flags, ovector, OVECTOR_COUNT); 371d713e089SXin LI matched = (mcount > 0); 372d713e089SXin LI ecount = nsp-1; 373d713e089SXin LI if (ecount > mcount) ecount = mcount; 374d713e089SXin LI for (i = 0; i < ecount*2; ) 375f0be0a1fSXin LI { 376d713e089SXin LI if (ovector[i] < 0 || ovector[i+1] < 0) 377d713e089SXin LI { 378d713e089SXin LI *sp++ = *ep++ = line; 379d713e089SXin LI i += 2; 380d713e089SXin LI } else 381d713e089SXin LI { 382d713e089SXin LI *sp++ = line + ovector[i++]; 383d713e089SXin LI *ep++ = line + ovector[i++]; 384d713e089SXin LI } 385f0be0a1fSXin LI } 386f0be0a1fSXin LI } 387f0be0a1fSXin LI #endif 388b7780dbeSXin LI #if HAVE_PCRE2 389b7780dbeSXin LI { 390b7780dbeSXin LI int flags = (notbol) ? PCRE2_NOTBOL : 0; 391d713e089SXin LI pcre2_match_data *md = pcre2_match_data_create(nsp-1, NULL); 392d713e089SXin LI int mcount = pcre2_match(pattern, (PCRE2_SPTR)line, line_len, 393d713e089SXin LI 0, flags, md, NULL); 394d713e089SXin LI matched = (mcount > 0); 395b7780dbeSXin LI if (matched) 396b7780dbeSXin LI { 397b7780dbeSXin LI PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(md); 398d713e089SXin LI int i; 399d713e089SXin LI int ecount = nsp-1; 400d713e089SXin LI if (ecount > mcount) ecount = mcount; 401d713e089SXin LI for (i = 0; i < ecount*2; ) 402d713e089SXin LI { 403d713e089SXin LI if (ovector[i] < 0 || ovector[i+1] < 0) 404d713e089SXin LI { 405d713e089SXin LI *sp++ = *ep++ = line; 406d713e089SXin LI i += 2; 407d713e089SXin LI } else 408d713e089SXin LI { 409d713e089SXin LI *sp++ = line + ovector[i++]; 410d713e089SXin LI *ep++ = line + ovector[i++]; 411d713e089SXin LI } 412d713e089SXin LI } 413b7780dbeSXin LI } 414b7780dbeSXin LI pcre2_match_data_free(md); 415b7780dbeSXin LI } 416b7780dbeSXin LI #endif 417f0be0a1fSXin LI #if HAVE_RE_COMP 418f0be0a1fSXin LI matched = (re_exec(line) == 1); 419f0be0a1fSXin LI /* 420f0be0a1fSXin LI * re_exec doesn't seem to provide a way to get the matched string. 421f0be0a1fSXin LI */ 422f0be0a1fSXin LI #endif 423f0be0a1fSXin LI #if HAVE_REGCMP 424d713e089SXin LI matched = ((*ep++ = regex(pattern, line)) != NULL); 425f0be0a1fSXin LI if (matched) 426d713e089SXin LI *sp++ = __loc1; 427f0be0a1fSXin LI #endif 428f0be0a1fSXin LI #if HAVE_V8_REGCOMP 429f0be0a1fSXin LI #if HAVE_REGEXEC2 430f6b74a7dSXin LI matched = regexec2(pattern, line, notbol); 431f0be0a1fSXin LI #else 432f6b74a7dSXin LI matched = regexec(pattern, line); 433f0be0a1fSXin LI #endif 434f0be0a1fSXin LI if (matched) 435f0be0a1fSXin LI { 436d713e089SXin LI *sp++ = pattern->startp[0]; 437d713e089SXin LI *ep++ = pattern->endp[0]; 438f0be0a1fSXin LI } 439f0be0a1fSXin LI #endif 440f0be0a1fSXin LI } 441d713e089SXin LI *sp = *ep = NULL; 442f0be0a1fSXin LI matched = (!(search_type & SRCH_NO_MATCH) && matched) || 443f0be0a1fSXin LI ((search_type & SRCH_NO_MATCH) && !matched); 444f0be0a1fSXin LI return (matched); 445f0be0a1fSXin LI } 446f0be0a1fSXin LI 447*c77c4889SXin LI public int match_pattern(PATTERN_TYPE pattern, constant char *tpattern, constant char *line, size_t line_len, constant char **sp, constant char **ep, int nsp, int notbol, int search_type) 448d713e089SXin LI { 449d713e089SXin LI int matched = match_pattern1(pattern, tpattern, line, line_len, sp, ep, nsp, notbol, search_type); 450d713e089SXin LI int i; 451d713e089SXin LI for (i = 1; i <= NUM_SEARCH_COLORS; i++) 452d713e089SXin LI { 453d713e089SXin LI if ((search_type & SRCH_SUBSEARCH(i)) && ep[i] == sp[i]) 454d713e089SXin LI matched = 0; 455d713e089SXin LI } 456d713e089SXin LI return matched; 457d713e089SXin LI } 458d713e089SXin LI 459b7780dbeSXin LI /* 460b7780dbeSXin LI * Return the name of the pattern matching library. 461b7780dbeSXin LI */ 462*c77c4889SXin LI public constant char * pattern_lib_name(void) 463b7780dbeSXin LI { 464b7780dbeSXin LI #if HAVE_GNU_REGEX 465b7780dbeSXin LI return ("GNU"); 466b7780dbeSXin LI #else 467b7780dbeSXin LI #if HAVE_POSIX_REGCOMP 468b7780dbeSXin LI return ("POSIX"); 469b7780dbeSXin LI #else 470b7780dbeSXin LI #if HAVE_PCRE2 471b7780dbeSXin LI return ("PCRE2"); 472b7780dbeSXin LI #else 473b7780dbeSXin LI #if HAVE_PCRE 474b7780dbeSXin LI return ("PCRE"); 475b7780dbeSXin LI #else 476b7780dbeSXin LI #if HAVE_RE_COMP 477b7780dbeSXin LI return ("BSD"); 478b7780dbeSXin LI #else 479b7780dbeSXin LI #if HAVE_REGCMP 480b7780dbeSXin LI return ("V8"); 481b7780dbeSXin LI #else 482b7780dbeSXin LI #if HAVE_V8_REGCOMP 483b7780dbeSXin LI return ("Spencer V8"); 484b7780dbeSXin LI #else 485b7780dbeSXin LI return ("no"); 486b7780dbeSXin LI #endif 487b7780dbeSXin LI #endif 488b7780dbeSXin LI #endif 489b7780dbeSXin LI #endif 490b7780dbeSXin LI #endif 491b7780dbeSXin LI #endif 492b7780dbeSXin LI #endif 493b7780dbeSXin LI } 494