void FindInProjectDlg::SearchThread::WriteResult(const MMapBuffer& buf, const wxFileName& filepath, vector<FileMatch>& matches) { if (matches.empty()) return; // Header const wxString path = filepath.GetFullPath(); const wxString format = (matches.size() == 1) ? _("<b>%s - %d match</b>") : _("<b>%s - %d matches</b>"); wxString output = wxString::Format(format, path.c_str(), matches.size()); output += wxT("<br><table cellspacing=0>"); unsigned int linecount = 1; const char* subject = buf.data(); const char* end = subject + buf.Length(); const char* linestart = subject; vector<FileMatch>::iterator m = matches.begin(); const char* matchstart = subject + m->start; // Count lines while (subject < end) { if (subject == matchstart) { // Write linenumber with link wxString line = wxString::Format(wxT("<tr><td bgcolor=#f6f6ef align=\"right\"><a href=\"txmt://open&url=file://%s&line=%d\">%d</a></td><td> "), path.c_str(), linecount, linecount); // Start of line line += wxString(linestart, wxConvUTF8, matchstart-linestart); // Match line += wxT("<i style=\"background-color: yellow\">"); const size_t match_len = m->end - m->start; line += wxString(matchstart, wxConvUTF8, match_len); line += wxT("</i>"); // End of line const char* const matchend = subject + match_len; const char* lineend = matchend; while (lineend < end && *lineend != '\n') ++lineend; line += wxString(matchend, wxConvUTF8, lineend - matchend); line += wxT("</td></tr>"); output += line; ++m; if (m == matches.end()) break; matchstart = buf.data() + m->start; } if (*subject == '\n') { ++linecount; linestart = subject+1; } ++subject; } output += wxT("</table><p>"); m_outputCrit.Enter(); m_output += output; m_outputCrit.Leave(); }
void FindInProjectDlg::SearchThread::DoSearch(const MMapBuffer& buf, const SearchInfo& si, vector<FileMatch>& matches) const { // Ignore binary files (we just check for zero bytes in the first // 100 bytes of the file) const wxFileOffset len = buf.Length(); const char* subject = buf.data(); const char* end_pos = buf.data() + wxMin(100,len); for (; subject < end_pos; ++subject) { if (*subject == '\0') return; } // Prepare vars to avoid lookups in loop const size_t last_char_pos = si.byte_len-1; const char lastChar = si.UTF8buffer[last_char_pos]; const char lastCharUpper = si.matchCase ? '\0' : si.UTF8bufferUpper[last_char_pos]; subject = buf.data() + last_char_pos; end_pos = buf.data() + len; while (subject < end_pos) { const char c = *subject; // Get candidate for last char if (c == lastChar || (!si.matchCase && c == lastCharUpper)) { // Match indiviual chars const char* byte_ptr = subject-1; const char* const first_byte_pos = subject - last_char_pos; unsigned int char_pos = last_char_pos-1; while (byte_ptr >= first_byte_pos) { const char c2 = *byte_ptr; if (c2 != si.UTF8buffer[char_pos]) { if (si.matchCase || c2 != si.UTF8bufferUpper[char_pos]) break; } --byte_ptr; --char_pos; } if (byte_ptr < first_byte_pos) { // We got a match const wxFileOffset matchStart = first_byte_pos - buf.data(); const FileMatch m = {0, 0, matchStart, matchStart + si.byte_len}; matches.push_back(m); subject += si.byte_len; continue; } } // If we don't have a match, see how far we can move char_pos subject += si.charmap[(unsigned char)c]; } }
void SearchThread::DoSearch(const MMapBuffer& buf, const SearchInfo& si, vector<FileMatch>& matches) const { // Ignore binary files (we just check for zero bytes in the first // 100 bytes of the file) const wxFileOffset len = buf.Length(); const char* subject = buf.data(); const char* end_pos = buf.data() + wxMin(100,len); for (; subject < end_pos; ++subject) { if (*subject == '\0') return; } if (si.regex) { const int OVECCOUNT = 30; int ovector[OVECCOUNT]; int pos = 0; int rc = 0; while(1) { rc = pcre_exec( si.regex, // the compiled pattern NULL, // extra data - if we study the pattern buf.data(), // the subject string len, // the length of the subject pos, // start at offset in the subject PCRE_NOTEMPTY, // options ovector, // output vector for substring information OVECCOUNT); // number of elements in the output vector if (rc <= 0) break; const FileMatch m = {0, 0, ovector[0], ovector[1]}; matches.push_back(m); pos = ovector[1]; } } else { // Prepare vars to avoid lookups in loop const size_t last_char_pos = si.byte_len-1; const char lastChar = si.UTF8buffer[last_char_pos]; const char lastCharUpper = si.matchCase ? '\0' : si.UTF8bufferUpper[last_char_pos]; subject = buf.data() + last_char_pos; end_pos = buf.data() + len; while (subject < end_pos) { const char c = *subject; // Get candidate for last char if (c == lastChar || (!si.matchCase && c == lastCharUpper)) { // Match indiviual chars const char* byte_ptr = subject-1; const char* const first_byte_pos = subject - last_char_pos; unsigned int char_pos = last_char_pos-1; while (byte_ptr >= first_byte_pos) { const char c2 = *byte_ptr; if (c2 != si.UTF8buffer[char_pos]) { if (si.matchCase || c2 != si.UTF8bufferUpper[char_pos]) break; } --byte_ptr; --char_pos; } if (byte_ptr < first_byte_pos) { // We got a match const wxFileOffset matchStart = first_byte_pos - buf.data(); const FileMatch m = {0, 0, matchStart, matchStart + si.byte_len}; matches.push_back(m); subject += si.byte_len; continue; } } // If we don't have a match, see how far we can move char_pos subject += si.charmap[(unsigned char)c]; } } }