bool report_matches(const wchar_t *arg) { // A return value of true means all is well (even if no matches were found), false indicates // an unrecoverable error. if (regex.code == 0) { // pcre2_compile() failed. return false; } int matched = 0; // See pcre2demo.c for an explanation of this logic. PCRE2_SIZE arglen = wcslen(arg); int rc = report_match( arg, pcre2_match(regex.code, PCRE2_SPTR(arg), arglen, 0, 0, regex.match, 0)); if (rc < 0) { // pcre2 match error. return false; } else if (rc == 0) { // no match return true; } matched++; total_matched++; if (opts.invert_match) { return true; } // Report any additional matches. PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(regex.match); while (opts.all || matched == 0) { uint32_t options = 0; PCRE2_SIZE offset = ovector[1]; // start at end of previous match if (ovector[0] == ovector[1]) { if (ovector[0] == arglen) { break; } options = PCRE2_NOTEMPTY_ATSTART | PCRE2_ANCHORED; } rc = report_match(arg, pcre2_match(regex.code, PCRE2_SPTR(arg), arglen, offset, options, regex.match, 0)); if (rc < 0) { return false; } if (rc == 0) { if (options == 0) { // all matches found break; } ovector[1] = offset + 1; continue; } matched++; total_matched++; } return true; }
void reporter::report_filename_and_match(analyzer::analysis_match_t const& match, std::ostream& buf) const { buf << mebbe_colorize(Color::Magenta, match.file) << ":"; if (options_.print_line_numbers) { buf << match.line << ":"; } if (options_.print_filename || options_.print_line_numbers) { buf << " "; } report_match(match, buf); }
//------------------------------------------------------------------------------ tracker::~tracker() { typedef result_list_type::const_iterator r_iterator; r_iterator riter( main_list.begin() ); r_iterator rend( main_list.end() ); while( riter != rend ) { if( riter->count >= MIN_MATCH_COUNT ) report_match( riter->loc.seqnum, riter->count, riter->s_offset + SAMPLE_SKIP, riter->loc.offset ); ++riter; } }
void reporter::report(analyzer::analysis_t const& analysis, std::ostream& buf) const { // TODO: might be a good idea to use exit codes now for (auto error : analysis.errors) { if (error.error_type == jsgrep::analyzer::QueryError) { buf << "[QueryError] " << error.message << std::endl; break; } } if (options_.verbosity > options_t::VERBOSITY_QUIET) { for (auto error : analysis.errors) { if (error.error_type == jsgrep::analyzer::SourceCodeError) { buf << "[ParseError] " << error.file << ": " << error.message << std::endl; } else if (error.error_type == jsgrep::analyzer::SearchError) { buf << "[InternalError] " << error.file << ": " << error.message << std::endl; } else if (error.error_type != jsgrep::analyzer::QueryError) { buf << "[UnexpectedError] " << error.file << ": " << error.message << std::endl; } } } if (options_.print_match && options_.print_filename) { for (auto match : analysis.matches) { report_filename_and_match(match, buf); } } else if (options_.print_filename) { report_matching_filenames(analysis, buf); } else if (options_.print_match) { for (auto match : analysis.matches) { report_match(match, buf); } } }
//------------------------------------------------------------------------------ void tracker::operator()( const string & index, Uint4 seqnum, string::size_type subject_offset, dup_lookup_table::iterator iter, dup_lookup_table::iterator end ) { typedef result_list_type::const_iterator r_iterator; typedef dup_lookup_table::sample_loc sample_loc; r_iterator riter( main_list.begin() ); r_iterator rend( main_list.end() ); bool do_swap( iter == end ? false : true ); while( true ) if( riter == rend ) if( iter == end ) break; else { aux_list.push_back( result( sample_loc( iter->seqnum, iter->offset + SAMPLE_SKIP ), subject_offset ) ); ++iter; } else if( iter == end ) { if( riter->s_offset + SAMPLE_SKIP + MAX_OFFSET_ERROR < subject_offset ) { if( riter->count >= MIN_MATCH_COUNT ) report_match( riter->loc.seqnum, riter->count, riter->s_offset + SAMPLE_SKIP, riter->loc.offset ); } else aux_list.push_back( *riter ); ++riter; } else // both iter and riter are valid { if( *iter < riter->loc ) { aux_list.push_back( result( sample_loc( iter->seqnum, iter->offset + SAMPLE_SKIP ), subject_offset ) ); ++iter; } else if( *iter > riter->loc ) { if( riter->s_offset + SAMPLE_SKIP + MAX_OFFSET_ERROR < subject_offset ) { if( riter->count >= MIN_MATCH_COUNT ) report_match( riter->loc.seqnum, riter->count, riter->s_offset + SAMPLE_SKIP, riter->loc.offset ); } else aux_list.push_back( *riter ); ++riter; } else // *iter == riter->loc --- same sequence and corresponding offsets { Uint4 count( 1 ); while( riter != rend && riter->loc == *iter ) { if( subject_offset < riter->s_offset + SAMPLE_SKIP - MAX_OFFSET_ERROR ) aux_list.push_back( *riter ); else if( subject_offset > riter->s_offset + SAMPLE_SKIP + MAX_OFFSET_ERROR ) { if( riter->count >= MIN_MATCH_COUNT ) report_match( riter->loc.seqnum, riter->count, riter->s_offset + SAMPLE_SKIP, riter->loc.offset ); } else // MATCH!!! Extend it. count = riter->count + 1; ++riter; } aux_list.push_back( result( sample_loc( iter->seqnum, iter->offset + SAMPLE_SKIP ), subject_offset, count ) ); ++iter; } } // Swap the lists. if( do_swap ) { main_list.clear(); main_list.swap( aux_list ); } }