search.c
来自「linux平台中」· C语言 代码 · 共 725 行 · 第 1/2 页
C
725 行
#ifdef MBS_SUPPORT if (MB_CUR_MAX > 1) free(mb_properties);#endif return (size_t)-1; } beg += offset; /* Narrow down to the line containing the candidate, and run it through DFA. */ end = memchr(beg, eol, buflim - beg); end++;#ifdef MBS_SUPPORT if (MB_CUR_MAX > 1 && mb_properties[beg - buf] == 0) continue;#endif while (beg > buf && beg[-1] != eol) --beg; if (kwsm.index < kwset_exact_matches) goto success; if (dfaexec (&dfa, beg, end - beg, &backref) == (size_t) -1) continue; } else { /* No good fixed strings; start with DFA. */ size_t offset = dfaexec (&dfa, beg, buflim - beg, &backref); if (offset == (size_t) -1) break; /* Narrow down to the line we've found. */ beg += offset; end = memchr (beg, eol, buflim - beg); end++; while (beg > buf && beg[-1] != eol) --beg; } /* Successful, no backreferences encountered! */ if (!backref) goto success; } else end = beg + size; /* If we've made it to this point, this means DFA has seen a probable match, and we need to run it through Regex. */ for (i = 0; i < pcount; i++) { patterns[i].regexbuf.not_eol = 0; if (0 <= (start = re_search (&(patterns[i].regexbuf), beg, end - beg - 1, 0, end - beg - 1, &(patterns[i].regs)))) { len = patterns[i].regs.end[0] - start; if (exact) { *match_size = len; return start; } if ((!match_lines && !match_words) || (match_lines && len == end - beg - 1)) goto success; /* If -w, check if the match aligns with word boundaries. We do this iteratively because: (a) the line may contain more than one occurence of the pattern, and (b) Several alternatives in the pattern might be valid at a given point, and we may need to consider a shorter one to find a word boundary. */ if (match_words) while (start >= 0) { if ((start == 0 || !WCHAR ((unsigned char) beg[start - 1])) && (len == end - beg - 1 || !WCHAR ((unsigned char) beg[start + len]))) goto success; if (len > 0) { /* Try a shorter length anchored at the same place. */ --len; patterns[i].regexbuf.not_eol = 1; len = re_match (&(patterns[i].regexbuf), beg, start + len, start, &(patterns[i].regs)); } if (len <= 0) { /* Try looking further on. */ if (start == end - beg - 1) break; ++start; patterns[i].regexbuf.not_eol = 0; start = re_search (&(patterns[i].regexbuf), beg, end - beg - 1, start, end - beg - 1 - start, &(patterns[i].regs)); len = patterns[i].regs.end[0] - start; } } } } /* for Regex patterns. */ } /* for (beg = end ..) */#ifdef MBS_SUPPORT if (MB_CUR_MAX > 1 && mb_properties) free (mb_properties);#endif /* MBS_SUPPORT */ return (size_t) -1; success:#ifdef MBS_SUPPORT if (MB_CUR_MAX > 1 && mb_properties) free (mb_properties);#endif /* MBS_SUPPORT */ *match_size = end - beg; return beg - buf;}static voidFcompile (char const *pattern, size_t size){ char const *beg, *lim, *err; kwsinit (); beg = pattern; do { for (lim = beg; lim < pattern + size && *lim != '\n'; ++lim) ; if ((err = kwsincr (kwset, beg, lim - beg)) != 0) error (2, 0, err); if (lim < pattern + size) ++lim; beg = lim; } while (beg < pattern + size); if ((err = kwsprep (kwset)) != 0) error (2, 0, err);}static size_tFexecute (char const *buf, size_t size, size_t *match_size, int exact){ register char const *beg, *try, *end; register size_t len; char eol = eolbyte; struct kwsmatch kwsmatch;#ifdef MBS_SUPPORT char *mb_properties; if (MB_CUR_MAX > 1) mb_properties = check_multibyte_string (buf, size);#endif /* MBS_SUPPORT */ for (beg = buf; beg <= buf + size; ++beg) { size_t offset = kwsexec (kwset, beg, buf + size - beg, &kwsmatch); if (offset == (size_t) -1) {#ifdef MBS_SUPPORT if (MB_CUR_MAX > 1) free(mb_properties);#endif /* MBS_SUPPORT */ return offset; }#ifdef MBS_SUPPORT if (MB_CUR_MAX > 1 && mb_properties[offset+beg-buf] == 0) continue; /* It is a part of multibyte character. */#endif /* MBS_SUPPORT */ beg += offset; len = kwsmatch.size[0]; if (exact) { *match_size = len;#ifdef MBS_SUPPORT if (MB_CUR_MAX > 1) free (mb_properties);#endif /* MBS_SUPPORT */ return beg - buf; } if (match_lines) { if (beg > buf && beg[-1] != eol) continue; if (beg + len < buf + size && beg[len] != eol) continue; goto success; } else if (match_words) for (try = beg; len; ) { if (try > buf && WCHAR((unsigned char) try[-1])) break; if (try + len < buf + size && WCHAR((unsigned char) try[len])) { offset = kwsexec (kwset, beg, --len, &kwsmatch); if (offset == (size_t) -1) {#ifdef MBS_SUPPORT if (MB_CUR_MAX > 1) free (mb_properties);#endif /* MBS_SUPPORT */ return offset; } try = beg + offset; len = kwsmatch.size[0]; } else goto success; } else goto success; }#ifdef MBS_SUPPORT if (MB_CUR_MAX > 1) free (mb_properties);#endif /* MBS_SUPPORT */ return -1; success: end = memchr (beg + len, eol, (buf + size) - (beg + len)); end++; while (buf < beg && beg[-1] != eol) --beg; *match_size = end - beg;#ifdef MBS_SUPPORT if (MB_CUR_MAX > 1) free (mb_properties);#endif /* MBS_SUPPORT */ return beg - buf;}#if HAVE_LIBPCRE/* Compiled internal form of a Perl regular expression. */static pcre *cre;/* Additional information about the pattern. */static pcre_extra *extra;#endifstatic voidPcompile (char const *pattern, size_t size){#if !HAVE_LIBPCRE error (2, 0, _("The -P option is not supported"));#else int e; char const *ep; char *re = xmalloc (4 * size + 7); int flags = PCRE_MULTILINE | (match_icase ? PCRE_CASELESS : 0); char const *patlim = pattern + size; char *n = re; char const *p; char const *pnul; /* FIXME: Remove this restriction. */ if (eolbyte != '\n') error (2, 0, _("The -P and -z options cannot be combined")); *n = '\0'; if (match_lines) strcpy (n, "^("); if (match_words) strcpy (n, "\\b("); n += strlen (n); /* The PCRE interface doesn't allow NUL bytes in the pattern, so replace each NUL byte in the pattern with the four characters "\000", removing a preceding backslash if there are an odd number of backslashes before the NUL. FIXME: This method does not work with some multibyte character encodings, notably Shift-JIS, where a multibyte character can end in a backslash byte. */ for (p = pattern; (pnul = memchr (p, '\0', patlim - p)); p = pnul + 1) { memcpy (n, p, pnul - p); n += pnul - p; for (p = pnul; pattern < p && p[-1] == '\\'; p--) continue; n -= (pnul - p) & 1; strcpy (n, "\\000"); n += 4; } memcpy (n, p, patlim - p); n += patlim - p; *n = '\0'; if (match_words) strcpy (n, ")\\b"); if (match_lines) strcpy (n, ")$"); cre = pcre_compile (re, flags, &ep, &e, pcre_maketables ()); if (!cre) error (2, 0, ep); extra = pcre_study (cre, 0, &ep); if (ep) error (2, 0, ep); free (re);#endif}static size_tPexecute (char const *buf, size_t size, size_t *match_size, int exact){#if !HAVE_LIBPCRE abort (); return -1;#else /* This array must have at least two elements; everything after that is just for performance improvement in pcre_exec. */ int sub[300]; int e = pcre_exec (cre, extra, buf, size, 0, 0, sub, sizeof sub / sizeof *sub); if (e <= 0) { switch (e) { case PCRE_ERROR_NOMATCH: return -1; case PCRE_ERROR_NOMEMORY: error (2, 0, _("Memory exhausted")); default: abort (); } } else { /* Narrow down to the line we've found. */ char const *beg = buf + sub[0]; char const *end = buf + sub[1]; char const *buflim = buf + size; char eol = eolbyte; if (!exact) { end = memchr (end, eol, buflim - end); end++; while (buf < beg && beg[-1] != eol) --beg; } *match_size = end - beg; return beg - buf; }#endif}struct matcher const matchers[] = { { "default", Gcompile, EGexecute }, { "grep", Gcompile, EGexecute }, { "egrep", Ecompile, EGexecute }, { "awk", Ecompile, EGexecute }, { "fgrep", Fcompile, Fexecute }, { "perl", Pcompile, Pexecute }, { "", 0, 0 },};
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?