static unsigned int filterCommandT(const FilterEntries& entries, const char* string, FilterOutput* output) { FuzzyMatcher matcher(string); FilterHighlightBuffer hlbuf; unsigned int matches = 0; for (size_t i = 0; i < entries.entryCount; ++i) { const FilterEntry& e = entries.entries[i]; if (matcher.match(entries.buffer + e.offset, e.length)) { matches++; if (output->options & SO_HIGHLIGHT_MATCHES) processMatchHighlightCommandT(matcher, /* ranked= */ false, hlbuf, e, entries.buffer, output); else processMatch(e, entries.buffer, output); if (matches >= output->limit) break; } } return matches; }
static void processFile(Regex* re, SearchOutput* output, OrderedOutput::Chunk* chunk, HighlightBuffer& hlbuf, const char* path, size_t pathLength, const char* data, size_t size, unsigned int startLine) { const char* range = re->rangePrepare(data, size); const char* begin = range; const char* end = begin + size; unsigned int line = startLine; while (RegexMatch match = re->rangeSearch(begin, end - begin)) { // discard zero-length matches at the end (.* results in an extra line for every file part otherwise) if (match.data == end) break; // update line counter line += 1 + countLines(begin, match.data); // print match const char* lbeg = findLineStart(begin, match.data); const char* lend = findLineEnd(match.data + match.size, end); processMatch(re, output, chunk, hlbuf, path, pathLength, (lbeg - range) + data, lend - lbeg, line, lbeg, match.data - lbeg, match.size); // move to next line if (lend == end) break; begin = lend + 1; } re->rangeFinalize(range); }
static unsigned int filterVisualAssist(const FilterEntries& entries, const FilterEntries& names, const char* string, FilterOutput* output) { std::vector<VisualAssistFragment> fragments; for (auto& s: split(string, isspace)) { fragments.emplace_back(); VisualAssistFragment& f = fragments.back(); f.text = s; f.re.reset(createRegex(s.c_str(), getRegexOptions(output->options | SO_LITERAL))); f.ispath = s.find_first_of("/\\") != std::string::npos; } if (fragments.empty()) return dumpEntries(entries, output); // sort name components first, path components last, larger components first std::sort(fragments.begin(), fragments.end(), [](const VisualAssistFragment& lhs, const VisualAssistFragment& rhs) { return (lhs.ispath != rhs.ispath) ? lhs.ispath < rhs.ispath : lhs.text.length() > rhs.text.length(); }); // gather files by first component std::vector<unsigned int> results; filterRegex(fragments[0].ispath ? entries : names, fragments[0].re.get(), (fragments.size() == 1) ? output->limit : ~0u, [&](unsigned int i) { results.push_back(i); }); // filter results by subsequent components for (size_t i = 1; i < fragments.size(); ++i) { const VisualAssistFragment& f = fragments[i]; results.erase(std::remove_if(results.begin(), results.end(), [&](unsigned int i) -> bool { const FilterEntries& matchEntries = f.ispath ? entries : names; const FilterEntry& me = matchEntries.entries[i]; return f.re->search(matchEntries.buffer + me.offset, me.length).size == 0; }), results.end()); } // trim results according to limit if (results.size() > output->limit) results.resize(output->limit); // output results FilterHighlightBuffer hlbuf; for (auto& i: results) { const FilterEntry& e = entries.entries[i]; if (output->options & SO_HIGHLIGHT_MATCHES) processMatchHighlightVisualAssist(fragments, hlbuf, e, entries.buffer, names.entries[i], names.buffer, output); else processMatch(e, entries.buffer, output); } return results.size(); }
static unsigned int dumpEntries(const FilterEntries& entries, FilterOutput* output) { unsigned int count = std::min(output->limit, entries.entryCount); for (unsigned int i = 0; i < count; ++i) processMatch(entries.entries[i], entries.buffer, output); return count; }
static void processMatchHighlightRegex(Regex* re, FilterHighlightBuffer& hlbuf, const FilterEntry& entry, size_t offset, const char* buffer, FilterOutput* output) { const char* data = entry.offset + buffer; hlbuf.ranges.clear(); highlightRegex(hlbuf.ranges, re, data, entry.length, nullptr, offset); hlbuf.result.clear(); highlight(hlbuf.result, data, entry.length, hlbuf.ranges.empty() ? nullptr : &hlbuf.ranges[0], hlbuf.ranges.size(), kHighlightMatch); processMatch(hlbuf.result.c_str(), hlbuf.result.size(), output); }
static unsigned int filterCommandTRanked(const FilterEntries& entries, const char* string, FilterOutput* output) { FuzzyMatcher matcher(string); typedef std::pair<int, const FilterEntry*> Match; std::vector<Match> matches; unsigned int perfectMatches = 0; for (size_t i = 0; i < entries.entryCount; ++i) { const FilterEntry& e = entries.entries[i]; const char* data = entries.buffer + e.offset; if (matcher.match(data, e.length)) { int score = matcher.rank(data, e.length); assert(score != INT_MAX); matches.push_back(std::make_pair(score, &e)); if (score == 0) { perfectMatches++; if (perfectMatches >= output->limit) break; } } } auto compareMatches = [](const Match& l, const Match& r) { return l.first == r.first ? l.second < r.second : l.first < r.first; }; if (matches.size() <= output->limit) std::sort(matches.begin(), matches.end(), compareMatches); else { std::partial_sort(matches.begin(), matches.begin() + output->limit, matches.end(), compareMatches); matches.resize(output->limit); } FilterHighlightBuffer hlbuf; for (auto& m: matches) { const FilterEntry& e = *m.second; if (output->options & SO_HIGHLIGHT_MATCHES) processMatchHighlightCommandT(matcher, /* ranked= */ true, hlbuf, e, entries.buffer, output); else processMatch(e, entries.buffer, output); } return matches.size(); }
static void processMatchHighlightVisualAssist(const std::vector<VisualAssistFragment>& fragments, FilterHighlightBuffer& hlbuf, const FilterEntry& entry, const char* entryBuffer, const FilterEntry& nameEntry, const char* nameBuffer, FilterOutput* output) { const char* data = entryBuffer + entry.offset; hlbuf.ranges.clear(); for (auto& f: fragments) highlightRegex(hlbuf.ranges, f.re.get(), data, entry.length, nullptr, f.ispath ? 0 : entry.length - nameEntry.length); hlbuf.result.clear(); highlight(hlbuf.result, data, entry.length, hlbuf.ranges.empty() ? nullptr : &hlbuf.ranges[0], hlbuf.ranges.size(), kHighlightMatch); processMatch(hlbuf.result.c_str(), hlbuf.result.size(), output); }
void RFDiagonalWKSubtask::processDiagonal(int x, int y){ //make stack local copies int W = owner->WINDOW_SIZE; int C = owner->C; char unknownChar = owner->unknownChar; const char* xseq = dataX + x + W - 1; //point to the last pos in window -> will be checked first const char* yseq = dataY + y + W - 1; const char* xseqMax = dataX + owner->SIZE_X; const char* yseqMax = dataY + owner->SIZE_Y; assert(xseqMax - xseq >= 0 && yseqMax - yseq >= 0); while (xseq < xseqMax && yseq < yseqMax) { int c = 0; //number of mismatches (temporary) for (const char* s = xseq - W; xseq > s && (c += (PCHAR_MATCHES(xseq, yseq) ? 0 : 1)) <= C; xseq--, yseq--){} if (c > C) { xseq += W; yseq += W; continue; } assert(xseq < dataX || yseq < dataY || !PCHAR_MATCHES(xseq, yseq)); xseq++; yseq++; int len = processMatch(xseq, yseq, xseqMax, yseqMax, c); assert(len >= W); while (len > W && !PCHAR_MATCHES(xseq, yseq)){len--; xseq++; yseq++;} //ensure that match with len > W starts with hit int step = len; while (len > W && !PCHAR_MATCHES(xseq + len - 1, yseq + len - 1)){len--;} //ensure that match with len > W ends with hit int allMatches = 0; const char* xsqS = xseq; const char* ysqS = yseq; for(int i = len-1; i>=0; --i, xsqS++, ysqS++){allMatches += PCHAR_MATCHES(xsqS, ysqS)? 1 : 0;} //matches RFResult r(xseq - dataX, yseq - dataY, len, allMatches); assert(owner->checkResult(r)); diagResults.append(r); xseq += step + 1; yseq += step + 1; } if (!diagResults.isEmpty()) { owner->addToResults(diagResults); diagResults.clear(); } }
static void processMatchHighlightCommandT(FuzzyMatcher& matcher, bool ranked, FilterHighlightBuffer& hlbuf, const FilterEntry& entry, const char* buffer, FilterOutput* output) { const char* data = buffer + entry.offset; assert(matcher.size() > 0); hlbuf.posbuf.resize(matcher.size()); if (ranked) matcher.rank(data, entry.length, &hlbuf.posbuf[0]); else matcher.match(data, entry.length, &hlbuf.posbuf[0]); hlbuf.ranges.resize(hlbuf.posbuf.size()); for (size_t i = 0; i < hlbuf.posbuf.size(); ++i) hlbuf.ranges[i] = std::make_pair(hlbuf.posbuf[i], 1); hlbuf.result.clear(); highlight(hlbuf.result, data, entry.length, hlbuf.ranges.empty() ? nullptr : &hlbuf.ranges[0], hlbuf.ranges.size(), kHighlightMatch); processMatch(hlbuf.result.c_str(), hlbuf.result.size(), output); }
static unsigned int filterRegex(const FilterEntries& entries, const FilterEntries& matchEntries, const char* string, FilterOutput* output) { unsigned int result = 0; std::unique_ptr<Regex> re(createRegex(string, getRegexOptions(output->options))); FilterHighlightBuffer hlbuf; filterRegex(matchEntries, re.get(), output->limit, [&](unsigned int i) { const FilterEntry& e = entries.entries[i]; if (output->options & SO_HIGHLIGHT_MATCHES) processMatchHighlightRegex(re.get(), hlbuf, e, e.length - matchEntries.entries[i].length, entries.buffer, output); else processMatch(e, entries.buffer, output); result++; }); return result; }
int processMatches(MonkState* state, const File* file, const GArray* matches, const MatchCallbacks* callbacks) { if (callbacks->ignore && callbacks->ignore(state, file)) { return 1; } if (callbacks->onAll) { return callbacks->onAll(state, file, matches); } const guint matchCount = matches->len; if (matchCount == 0) { return callbacks->onNo(state, file); } int result = 1; for (guint matchIndex = 0; result && (matchIndex < matchCount); matchIndex++) { const Match* match = match_array_index(matches, matchIndex); result &= processMatch(state, file, match, callbacks); } return result; }
static void processMatch(const FilterEntry& entry, const char* buffer, FilterOutput* output) { processMatch(buffer + entry.offset, entry.length, output); }