Exemple #1
0
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();
}
Exemple #2
0
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];
    }
}
Exemple #3
0
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];
        }
    }
}