Hello community, here is the log from the commit of package ack for openSUSE:Factory checked in at 2019-09-30 16:01:41 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/ack (Old) and /work/SRC/openSUSE:Factory/.ack.new.2352 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ack" Mon Sep 30 16:01:41 2019 rev:27 rq:734003 version:3.1.1 Changes: -------- --- /work/SRC/openSUSE:Factory/ack/ack.changes 2019-08-22 10:54:52.069679793 +0200 +++ /work/SRC/openSUSE:Factory/.ack.new.2352/ack.changes 2019-09-30 16:01:48.132832879 +0200 @@ -1,0 +2,9 @@ +Thu Sep 26 09:33:14 UTC 2019 - Andreas Stieger <andreas.stie...@gmx.de> + +- ack 3.1.1: + * Improve the speed up the -l, -L and -c options +- includes changes from 3.1.0: + * Added the --range-start and --range-end options to allow + searching only ranges of + +------------------------------------------------------------------- Old: ---- ack-v3.0.3.tar.gz New: ---- ack-v3.1.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ack.spec ++++++ --- /var/tmp/diff_new_pack.G7RWSg/_old 2019-09-30 16:01:48.704831358 +0200 +++ /var/tmp/diff_new_pack.G7RWSg/_new 2019-09-30 16:01:48.704831358 +0200 @@ -24,7 +24,7 @@ %endif %{!?perl_make_install: %global perl_make_install make DESTDIR=%{buildroot} install_vendor} Name: ack -Version: 3.0.3 +Version: 3.1.1 Release: 0 Summary: Grep-Like Text Finder License: Artistic-2.0 @@ -35,7 +35,7 @@ Patch3: ack-add_spec.patch BuildRequires: make BuildRequires: perl >= 5.10.1 -BuildRequires: perl(File::Next) >= 1.10 +BuildRequires: perl(File::Next) >= 1.18 Requires: perl >= 5.10.1 Requires: perl-App-Ack = %{version}-%{release} Requires: perl-base = %{perl_version} @@ -55,7 +55,7 @@ Summary: Grep-Like Text Finder Perl Module Group: Development/Libraries/Perl Requires: perl-base = %{perl_version} -Requires: perl(File::Next) >= 1.10 +Requires: perl(File::Next) >= 1.18 %description -n perl-App-Ack App::Ack is a grep-like tool tailored to working with large trees of source ++++++ ack-v3.0.3.tar.gz -> ack-v3.1.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ack-v3.0.3/Changes new/ack-v3.1.1/Changes --- old/ack-v3.0.3/Changes 2019-08-21 06:42:25.000000000 +0200 +++ new/ack-v3.1.1/Changes 2019-09-01 05:58:05.000000000 +0200 @@ -1,6 +1,30 @@ History file for ack 3. https://beyondgrep.com/ +v3.1.1 Sat Aug 31 22:56:10 CDT 2019 +======================================== +[SPEEDUP] +Improved the speed up the -l, -L and -c options by pre-scanning the file +in bulk before doing line-by-line scan. (GH #221) + +[FIXES] +On Windows, patterns with $ to mark the end of the line would not match. +(GH #229) + +[DOCUMENTATION] +Fixed docs that referred to --range-stop instead of --range-end. (GH #228) + +[INTERNALS] +Now requires File::Next 1.18. + + +v3.1.0 Thu Aug 22 22:43:15 CDT 2019 +======================================== +[FEATURES] +Added the --range-start and --range-end options to allow searching only +ranges of each file. (GH #165) + + v3.0.3 Tue Aug 20 23:42:02 CDT 2019 ======================================== [FIXES] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ack-v3.0.3/MANIFEST new/ack-v3.1.1/MANIFEST --- old/ack-v3.0.3/MANIFEST 2019-08-21 06:43:20.000000000 +0200 +++ new/ack-v3.1.1/MANIFEST 2019-09-01 06:01:46.000000000 +0200 @@ -129,6 +129,13 @@ t/etc/shebang.sh.xxx t/home/.ackrc + +t/range/rangefile.pm +t/range/america-the-beautiful.html +t/range/anchors-aweigh.html +t/range/johnny-rebeck.txt +t/range/stars-and-stripes-forever.html + t/swamp/#emacs-workfile.pl# t/swamp/0 t/swamp/CMakeLists.txt diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ack-v3.0.3/META.json new/ack-v3.1.1/META.json --- old/ack-v3.0.3/META.json 2019-08-21 06:43:20.000000000 +0200 +++ new/ack-v3.1.1/META.json 2019-09-01 06:01:46.000000000 +0200 @@ -34,7 +34,7 @@ "requires" : { "Cwd" : "3.00", "File::Basename" : "1.00015", - "File::Next" : "1.16", + "File::Next" : "1.18", "File::Spec" : "3.00", "File::Temp" : "0.19", "Getopt::Long" : "2.39", @@ -69,6 +69,6 @@ }, "x_MailingList" : "https://groups.google.com/group/ack-users" }, - "version" : "v3.0.3", + "version" : "v3.1.1", "x_serialization_backend" : "JSON::PP version 4.04" } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ack-v3.0.3/META.yml new/ack-v3.1.1/META.yml --- old/ack-v3.0.3/META.yml 2019-08-21 06:43:20.000000000 +0200 +++ new/ack-v3.1.1/META.yml 2019-09-01 06:01:46.000000000 +0200 @@ -20,7 +20,7 @@ requires: Cwd: '3.00' File::Basename: '1.00015' - File::Next: '1.16' + File::Next: '1.18' File::Spec: '3.00' File::Temp: '0.19' Getopt::Long: '2.39' @@ -43,5 +43,5 @@ homepage: https://beyondgrep.com/ license: https://www.perlfoundation.org/artistic-license-20.html repository: git://github.com/beyondgrep/ack3.git -version: v3.0.3 +version: v3.1.1 x_serialization_backend: 'CPAN::Meta::YAML version 0.018' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ack-v3.0.3/Makefile.PL new/ack-v3.1.1/Makefile.PL --- old/ack-v3.0.3/Makefile.PL 2019-08-21 06:41:14.000000000 +0200 +++ new/ack-v3.1.1/Makefile.PL 2019-09-01 05:58:01.000000000 +0200 @@ -30,7 +30,7 @@ PREREQ_PM => { 'Cwd' => '3.00', 'File::Basename' => '1.00015', - 'File::Next' => '1.16', + 'File::Next' => '1.18', 'File::Spec' => '3.00', 'File::Temp' => '0.19', # For newdir() 'Getopt::Long' => '2.39', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ack-v3.0.3/ack new/ack-v3.1.1/ack --- old/ack-v3.0.3/ack 2019-08-21 06:42:32.000000000 +0200 +++ new/ack-v3.1.1/ack 2019-09-01 05:58:05.000000000 +0200 @@ -4,7 +4,7 @@ use warnings; use version; -our $VERSION = version->declare( 'v3.0.3' ); # Check https://beyondgrep.com/ for updates +our $VERSION = version->declare( 'v3.1.1' ); # Check https://beyondgrep.com/ for updates use 5.010001; @@ -43,6 +43,9 @@ our $opt_output; our $opt_passthru; our $opt_p; +our $opt_range_start; +our $opt_range_end; +our $opt_range_invert; our $opt_regex; our $opt_show_filename; our $opt_show_types; @@ -52,8 +55,11 @@ # Flag if we need any context tracking. our $is_tracking_context; -# Special /m version of our $opt_regex. -our $line_scan_regex; +# The regex that we search for in each file. +our $search_re; + +# Special /m version of our $search_re. +our $scan_re; our @special_vars_used_by_opt_output; @@ -134,12 +140,23 @@ $opt_output = $opt->{output}; $opt_p = $opt->{p}; $opt_passthru = $opt->{passthru}; + $opt_range_start = $opt->{range_start}; + $opt_range_end = $opt->{range_end}; + $opt_range_invert = $opt->{range_invert}; $opt_regex = $opt->{regex}; $opt_show_filename = $opt->{show_filename}; $opt_show_types = $opt->{show_types}; $opt_underline = $opt->{underline}; $opt_v = $opt->{v}; + + if ( $opt_range_start ) { + ($opt_range_start, undef) = build_regex( $opt_range_start, {} ); + } + if ( $opt_range_end ) { + ($opt_range_end, undef) = build_regex( $opt_range_end, {} ); + } + $App::Ack::report_bad_filenames = !$opt->{s}; $App::Ack::ors = $opt->{print0} ? "\0" : "\n"; @@ -182,18 +199,19 @@ my $files; if ( $App::Ack::is_filter_mode && !$opt->{files_from} ) { # probably -x $files = App::Ack::Files->from_stdin(); - $opt_regex = shift @ARGV if not defined $opt_regex; - $opt_regex = build_regex( $opt_regex, $opt ); + $opt_regex //= shift @ARGV; + ($search_re, $scan_re) = build_regex( $opt_regex, $opt ); } else { if ( $opt_f ) { # No need to check for regex, since mutex options are handled elsewhere. } else { - $opt_regex = shift @ARGV if not defined $opt_regex; - $opt_regex = build_regex( $opt_regex, $opt ); + $opt_regex //= shift @ARGV; + ($search_re, $scan_re) = build_regex( $opt_regex, $opt ); } - if ( $opt_regex && $opt_regex =~ /\n/ ) { + # XXX What is this checking for? + if ( $search_re && $search_re =~ /\n/ ) { App::Ack::exit_from_ack( 0 ); } my @start; @@ -238,25 +256,15 @@ } # ack -f - if ( $opt_f ) { + if ( $opt_f || $opt_g ) { if ( $opt_show_types ) { App::Ack::show_types( $file ); } - else { - App::Ack::say( $file->name ); - } - ++$nmatches; - last FILES if defined($opt_m) && $nmatches >= $opt_m; - } - # ack -g - elsif ( $opt_g ) { - if ( $opt_show_types ) { - App::Ack::show_types( $file ); + elsif ( $opt_g ) { + print_line_with_options( undef, $file->name, 0, $App::Ack::ors ); } else { - local $opt_show_filename = 0; # XXX Why is this local? - - print_line_with_options( '', $file->name, 0, $App::Ack::ors ); + App::Ack::say( $file->name ); } ++$nmatches; last FILES if defined($opt_m) && $nmatches >= $opt_m; @@ -281,7 +289,7 @@ } # ack -l, ack -L elsif ( $opt_l || $opt_L ) { - my $is_match = file_has_match( $file ); + my $is_match = count_matches_in_file( $file, 1 ); if ( $opt_L ? !$is_match : $is_match ) { App::Ack::say( $file->name ); @@ -300,30 +308,12 @@ # Slurp up an entire file up to 10M, see if there are any matches # in it, and if so, let us know so we can iterate over it directly. my $needs_line_scan = 1; - if ( $opt_regex && !$opt_passthru && !$opt_v ) { - if ( $file->open() && -f $file->{fh} ) { - my $buffer; - my $size = 10_000_000; - my $rc = sysread( $file->{fh}, $buffer, $size ); - if ( !defined($rc) ) { - if ( $App::Ack::report_bad_filenames ) { - App::Ack::warn( $file->name . ": $!" ); - } - $needs_line_scan = 0; - } - else { - # If we read all 10M, then we need to scan the rest. - if ( $rc == $size ) { - $needs_line_scan = 1; - } - else { - # Check for the pattern in what we got. - $needs_line_scan = ($buffer =~ /$line_scan_regex/o); - } - if ( $needs_line_scan ) { - $file->reset(); - } - } + if ( !$opt_passthru && !$opt_v ) { + if ( $file->may_be_present( $scan_re ) ) { + $file->reset(); + } + else { + $needs_line_scan = 0; } } if ( $needs_line_scan ) { @@ -333,7 +323,7 @@ last FILES; } } - } + } # while file->next if ( $opt_c && !$opt_show_filename ) { App::Ack::print( $total_count, "\n" ); @@ -406,7 +396,7 @@ return sub { if ( $opt_g ) { - if ( $File::Next::name =~ /$opt_regex/o ) { + if ( $File::Next::name =~ /$search_re/o ) { return 0 if $opt_v; } else { @@ -560,19 +550,22 @@ $str = "(?i)$str"; } + my $scan_re = undef; my $re = eval { qr/$str/ }; if ( $re ) { - $line_scan_regex = eval { qr/$str/m }; + if ( $str !~ /\$/ ) { + # No line_scan is possible if there's a $ in the regex. + $scan_re = eval { qr/$str/m }; + } } - if ( !$re || !$line_scan_regex ) { + else { my $err = $@; chomp $err; App::Ack::die( "Invalid regex '$str':\n $err" ); } - return $re; - + return ($re, $scan_re); } my $match_colno; @@ -647,22 +640,32 @@ # Check for context before the main loop, so we don't pay for it if we don't need it. if ( $is_tracking_context ) { + local $_ = undef; + $after_context_pending = 0; + + my ($using_ranges, $in_range) = range_setup(); + while ( <$fh> ) { chomp; - my $does_match; $match_colno = undef; - if ( $opt_v ) { - $does_match = !/$opt_regex/o; - } - else { - if ( $does_match = /$opt_regex/o ) { - # @- = @LAST_MATCH_START - # @+ = @LAST_MATCH_END - $match_colno = $-[0] + 1; + $in_range = 1 if ( $using_ranges && !$in_range && $opt_range_start && /$opt_range_start/o ); + + my $does_match; + if ( $in_range ) { + if ( $opt_v ) { + $does_match = !/$search_re/o; + } + else { + if ( $does_match = /$search_re/o ) { + # @- = @LAST_MATCH_START + # @+ = @LAST_MATCH_END + $match_colno = $-[0] + 1; + } } } + if ( $does_match && $max_count ) { if ( !$has_printed_for_this_file ) { if ( $opt_break && $has_printed_something ) { @@ -691,16 +694,23 @@ } } + $in_range = 0 if ( $using_ranges && $in_range && $opt_range_end && /$opt_range_end/o ); + last if ($max_count == 0) && ($after_context_pending == 0); } } elsif ( $opt_passthru ) { local $_ = undef; + my ($using_ranges, $in_range) = range_setup(); + while ( <$fh> ) { chomp; + + $in_range = 1 if ( $using_ranges && !$in_range && $opt_range_start && /$opt_range_start/o ); + $match_colno = undef; - if ( $opt_v ? !/$opt_regex/o : /$opt_regex/o ) { + if ( $in_range && ($opt_v xor /$search_re/o) ) { if ( !$opt_v ) { $match_colno = $-[0] + 1; } @@ -721,9 +731,12 @@ if ( $opt_break && !$has_printed_for_this_file && $has_printed_something ) { App::Ack::print_blank_line(); } - print_line_with_options( $filename, $_, $., ':' ); + print_line_with_options( $filename, $_, $., ':', 1 ); $has_printed_for_this_file = 1; } + + $in_range = 0 if ( $using_ranges && $in_range && $opt_range_end && /$opt_range_end/o ); + last if $max_count == 0; } } @@ -731,59 +744,79 @@ local $_ = undef; $match_colno = undef; + my ($using_ranges, $in_range) = range_setup(); + while ( <$fh> ) { chomp; - if ( !/$opt_regex/o ) { - if ( !$has_printed_for_this_file ) { - if ( $opt_break && $has_printed_something ) { - App::Ack::print_blank_line(); - } - if ( $opt_show_filename && $opt_heading ) { - App::Ack::say( $display_filename ); + + $in_range = 1 if ( $using_ranges && !$in_range && $opt_range_start && /$opt_range_start/o ); + + if ( $in_range ) { + if ( !/$search_re/o ) { + if ( !$has_printed_for_this_file ) { + if ( $opt_break && $has_printed_something ) { + App::Ack::print_blank_line(); + } + if ( $opt_show_filename && $opt_heading ) { + App::Ack::say( $display_filename ); + } } + print_line_with_context( $filename, $_, $. ); + $has_printed_for_this_file = 1; + $nmatches++; + $max_count--; } - print_line_with_context( $filename, $_, $. ); - $has_printed_for_this_file = 1; - $nmatches++; - $max_count--; } + + $in_range = 0 if ( $using_ranges && $in_range && $opt_range_end && /$opt_range_end/o ); + last if $max_count == 0; } } - else { + else { # Normal search: No context, no -v, no --passthru local $_ = undef; my $last_match_lineno; + my ($using_ranges, $in_range) = range_setup(); + while ( <$fh> ) { chomp; - $match_colno = undef; - if ( /$opt_regex/o ) { - $match_colno = $-[0] + 1; - if ( !$has_printed_for_this_file ) { - if ( $opt_break && $has_printed_something ) { - App::Ack::print_blank_line(); - } - if ( $opt_show_filename && $opt_heading ) { - App::Ack::say( $display_filename ); - } - } - if ( $opt_p ) { - if ( $last_match_lineno ) { - if ( $. > $last_match_lineno + $opt_p ) { + + $in_range = 1 if ( $using_ranges && !$in_range && $opt_range_start && /$opt_range_start/o ); + + if ( $in_range ) { + $match_colno = undef; + if ( /$search_re/o ) { + $match_colno = $-[0] + 1; + if ( !$has_printed_for_this_file ) { + if ( $opt_break && $has_printed_something ) { App::Ack::print_blank_line(); } + if ( $opt_show_filename && $opt_heading ) { + App::Ack::say( $display_filename ); + } } - elsif ( !$opt_break && $has_printed_something ) { - App::Ack::print_blank_line(); + if ( $opt_p ) { + if ( $last_match_lineno ) { + if ( $. > $last_match_lineno + $opt_p ) { + App::Ack::print_blank_line(); + } + } + elsif ( !$opt_break && $has_printed_something ) { + App::Ack::print_blank_line(); + } } + s/[\r\n]+$//; + print_line_with_options( $filename, $_, $., ':' ); + $has_printed_for_this_file = 1; + $nmatches++; + $max_count--; + $last_match_lineno = $.; } - s/[\r\n]+$//; - print_line_with_options( $filename, $_, $., ':' ); - $has_printed_for_this_file = 1; - $nmatches++; - $max_count--; - $last_match_lineno = $.; } + + $in_range = 0 if ( $using_ranges && $in_range && $opt_range_end && /$opt_range_end/o ); + last if $max_count == 0; } } @@ -793,33 +826,14 @@ sub print_line_with_options { - my ( $filename, $line, $lineno, $separator ) = @_; + my ( $filename, $line, $lineno, $separator, $skip_coloring ) = @_; $has_printed_something = 1; $printed_lineno = $lineno; my @line_parts; - # Figure out how many spaces are used per line for the ANSI coloring. - state $chars_used_by_coloring; - if ( !defined($chars_used_by_coloring) ) { - $chars_used_by_coloring = 0; - if ( $opt_color ) { - my $filename_uses = length( Term::ANSIColor::colored( 'x', $ENV{ACK_COLOR_FILENAME} ) ) - 1; - my $lineno_uses = length( Term::ANSIColor::colored( 'x', $ENV{ACK_COLOR_LINENO} ) ) - 1; - if ( $opt_heading ) { - $chars_used_by_coloring = $lineno_uses; - } - else { - $chars_used_by_coloring = $filename_uses + $lineno_uses; - } - if ( $opt_column ) { - $chars_used_by_coloring += length( Term::ANSIColor::colored( 'x', $ENV{ACK_COLOR_LINENO} ) ) - 1; - } - } - } - - if ( $opt_show_filename ) { + if ( $opt_show_filename && defined($filename) ) { my $colno; $colno = get_match_colno() if $opt_column; if ( $opt_color ) { @@ -829,16 +843,15 @@ } if ( $opt_heading ) { push @line_parts, $lineno; - push @line_parts, $colno if $opt_column; } else { push @line_parts, $filename, $lineno; - push @line_parts, $colno if $opt_column; } + push @line_parts, $colno if $opt_column; } if ( $opt_output ) { - while ( $line =~ /$opt_regex/og ) { + while ( $line =~ /$search_re/og ) { my $output = $opt_output; if ( @special_vars_used_by_opt_output ) { no strict; @@ -859,11 +872,9 @@ my $underline = ''; # We have to do underlining before any highlighting because highlighting modifies string length. - if ( $opt_underline ) { - while ( $line =~ /$opt_regex/og ) { - my $match_start = $-[0]; - next unless defined($match_start); - + if ( $opt_underline && !$skip_coloring ) { + while ( $line =~ /$search_re/og ) { + my $match_start = $-[0] // next; my $match_end = $+[0]; my $match_length = $match_end - $match_start; last if $match_length <= 0; @@ -874,28 +885,24 @@ $underline .= ('^' x $match_length); } } - if ( $opt_color ) { + if ( $opt_color && !$skip_coloring ) { my $highlighted = 0; # If highlighted, need to escape afterwards. - while ( $line =~ /$opt_regex/og ) { - my $match_start = $-[0]; - next unless defined($match_start); - + while ( $line =~ /$search_re/og ) { + my $match_start = $-[0] // next; my $match_end = $+[0]; my $match_length = $match_end - $match_start; last if $match_length <= 0; - if ( $opt_color ) { - my $substring = substr( $line, $match_start, $match_length ); - my $substitution = Term::ANSIColor::colored( $substring, $ENV{ACK_COLOR_MATCH} ); + my $substring = substr( $line, $match_start, $match_length ); + my $substitution = Term::ANSIColor::colored( $substring, $ENV{ACK_COLOR_MATCH} ); - # Fourth argument replaces the string specified by the first three. - substr( $line, $match_start, $match_length, $substitution ); + # Fourth argument replaces the string specified by the first three. + substr( $line, $match_start, $match_length, $substitution ); - # Move the offset of where /g left off forward the number of spaces of highlighting. - pos($line) = $match_end + (length( $substitution ) - length( $substring )); - $highlighted = 1; - } + # Move the offset of where /g left off forward the number of spaces of highlighting. + pos($line) = $match_end + (length( $substitution ) - length( $substring )); + $highlighted = 1; } # Reset formatting and delete everything to the end of the line. $line .= "\e[0m\e[K" if $highlighted; @@ -904,7 +911,20 @@ push @line_parts, $line; App::Ack::say( join( $separator, @line_parts ) ); + # Print the underline, if appropriate. if ( $underline ne '' ) { + # Figure out how many spaces are used per line for the ANSI coloring. + state $chars_used_by_coloring; + if ( !defined($chars_used_by_coloring) ) { + $chars_used_by_coloring = 0; + if ( $opt_color ) { + my $len_fn = sub { length( Term::ANSIColor::colored( 'x', $ENV{$_[0]} ) ) - 1 }; + $chars_used_by_coloring += $len_fn->('ACK_COLOR_FILENAME') unless $opt_heading; + $chars_used_by_coloring += $len_fn->('ACK_COLOR_LINENO'); + $chars_used_by_coloring += $len_fn->('ACK_COLOR_COLNO') if $opt_column; + } + } + pop @line_parts; # Leave only the stuff on the left. if ( @line_parts ) { my $stuff_on_the_left = join( $separator, @line_parts ); @@ -965,44 +985,54 @@ return $match_colno; } -# Same as C<count_matches_in_file>, but exits as soon as there is a match. -sub file_has_match { - my ( $file ) = @_; +sub count_matches_in_file { + my $file = shift; + my $bail = shift; # True if we're just checking for existence. + + my $nmatches = 0; + my $do_scan = 1; - my $has_match = 0; - my $fh = $file->open(); - if ( !$fh ) { + if ( !$file->open() ) { + $do_scan = 0; if ( $App::Ack::report_bad_filenames ) { - App::Ack::warn( $file->name . ': ' . $! ); + App::Ack::warn( $file->name . ": $!" ); } } else { - while ( <$fh> ) { - chomp; - if (/$opt_regex/o xor $opt_v) { - $has_match = 1; - last; + if ( !$opt_v ) { + if ( !$file->may_be_present( $scan_re ) ) { + $do_scan = 0; } } - $file->close; } - return $has_match; -} + if ( $do_scan ) { + $file->reset(); -sub count_matches_in_file { - my ( $file ) = @_; + my ($using_ranges, $in_range) = range_setup(); - my $nmatches = 0; - my $fh = $file->open; - if ( !$fh ) { - if ( $App::Ack::report_bad_filenames ) { - App::Ack::warn( $file->name . ': ' . $! ); + my $fh = $file->{fh}; + if ( $using_ranges ) { + while ( <$fh> ) { + chomp; + $in_range = 1 if ( !$in_range && $opt_range_start && /$opt_range_start/o ); + if ( $in_range ) { + if ( /$search_re/o xor $opt_v ) { + ++$nmatches; + last if $bail; + } + } + $in_range = 0 if ( $in_range && $opt_range_end && /$opt_range_end/o ); + } } - } - else { - while ( <$fh> ) { - ++$nmatches if (/$opt_regex/o xor $opt_v); + else { + while ( <$fh> ) { + chomp; + if ( /$search_re/o xor $opt_v ) { + ++$nmatches; + last if $bail; + } + } } $file->close; } @@ -1011,6 +1041,14 @@ } +sub range_setup { + my $using_ranges = $opt_range_start || $opt_range_end; + my $in_range = !$using_ranges || (!$opt_range_start && $opt_range_end); + + return ($using_ranges, $in_range); +} + + =pod =encoding UTF-8 @@ -1035,9 +1073,9 @@ PATTERN is a Perl regular expression. Perl regular expressions are commonly found in other programming languages, but for the particulars of their behavior, please consult -L<https://perldoc.perl.org/perlreref.html|perlreref>. If you don't know +L<perlreref|https://perldoc.perl.org/perlreref.html>. If you don't know how to use regular expression but are interested in learning, you may -consult L<https://perldoc.perl.org/perlretut.html|perlretut>. If you do not +consult L<perlretut|https://perldoc.perl.org/perlretut.html>. If you do not need or want ack to use regular expressions, please see the C<-Q>/C<--literal> option. @@ -1092,6 +1130,102 @@ For a complete list of directories that do not get searched, run C<ack --dump>. +=head1 MATCHING IN A RANGE OF LINES + +The C<--range-start> and C<--range-end> options let you specify ranges of +lines to search within each file. + +Say you had the following file, called F<testfile>: + + # This function calls print on "foo". + sub foo { + print 'foo'; + } + my $print = 1; + sub bar { + print 'bar'; + } + my $task = 'print'; + +Calling C<ack print> will give us five matches: + + $ ack print testfile + # This function calls print on "foo". + print 'foo'; + my $print = 1; + print 'bar'; + my $task = 'print'; + +What if we only want to search for C<print> within the subroutines? We can +specify ranges of lines that we want ack to search. The range starts with +any line that matches the pattern C<^sub \w+>, and stops with any line that +matches C<^}>. + + $ ack --range-start='^sub \w+' --range-end='^}' print testfile + print 'foo'; + print 'bar'; + +Note that ack searched two ranges of lines. The listing below shows which +lines were in a range and which were out of the range. + + Out # This function calls print on "foo". + In sub foo { + In print 'foo'; + In } + Out my $print = 1; + In sub bar { + In print 'bar'; + In } + Out my $task = 'print'; + +You don't have to specify both C<--range-start> and C<--range-end>. IF +C<--range-start> is omitted, then the range runs from the first line in the +file unitl the first line that matches C<--range-end>. Similarly, if +C<--range-end> is omitted, the range runs from the first line matching +C<--range-start> to the end of the file. + +For example, if you wanted to search all HTML files up until the first +instance of the C<< <body> >>, you could do + + ack foo --range-end='<body>' + +Or to search after Perl's `__DATA__` or `__END__` markers, you would do + + ack pattern --range-end='^__(END|DATA)__' + +It's possible for a range to start and stop on the same line. For example + + --range-start='<title>' --range-end='</title>' + +would match this line as both the start and end of the range, making a +one-line range. + + <title>Page title</title> + +Note that the patterns in C<--range-start> and C<--range-end> are not +affected by options like C<-i>, C<-w> and C<-Q> that modify the behavior of +the main pattern being matched. + +Again, ranges only affect where matches are looked for. Everything else in +ack works the same way. Using C<-c> option with a range will give a count +of all the matches that appear within those ranges. The C<-l> shows those +files that have a match within a range, and the C<-L> option shows files +that do not have a match within a range. + +The C<-v> option for negating a match works inside the range, too. +To see lines that don't match "google" within the "<head>" section of +your HTML files, you could do: + + ack google -v --html --range-start='<head' --range-end='</head>' + +Specifying a range to search does not affect how matches are displayed. +The context for a match will still be the same, and + +Using the context options work the same way, and will show context +lines for matches even if the context lines fall outside the range. +Similarly, C<--passthru> will show all lines in the file, but only show +matches for lines within the range. + =head1 OPTIONS =over 4 @@ -1474,6 +1608,11 @@ Recurse into sub-directories. This is the default and just here for compatibility with grep. You can also use it for turning B<--no-recurse> off. +=item B<--range-start=PATTERN>, B<--range-end=PATTERN> + +Specifies patterns that mark the start and end of a range. See +L<MATCHING IN A RANGE OF LINES> for details. + =item B<-s> Suppress error messages about nonexistent or unreadable files. This is taken @@ -2114,6 +2253,7 @@ How appropriate to have I<ack>nowledgements! Thanks to everyone who has contributed to ack in any way, including +Salomon Smeke, M. Scott Ford, Anders Eriksson, H.Merijn Brand, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ack-v3.0.3/lib/App/Ack/ConfigLoader.pm new/ack-v3.1.1/lib/App/Ack/ConfigLoader.pm --- old/ack-v3.0.3/lib/App/Ack/ConfigLoader.pm 2019-08-21 06:17:45.000000000 +0200 +++ new/ack-v3.1.1/lib/App/Ack/ConfigLoader.pm 2019-08-23 05:40:06.000000000 +0200 @@ -309,6 +309,9 @@ 'P' => sub { $opt->{p} = 0 }, 'Q|literal' => \$opt->{Q}, 'r|R|recurse' => sub { $opt->{n} = 0 }, + 'range-start=s' => \$opt->{range_start}, + 'range-end=s' => \$opt->{range_end}, + 'range-invert!' => \$opt->{range_invert}, 's' => \$opt->{s}, 'show-types' => \$opt->{show_types}, 'S|smart-case!' => sub { my (undef,$value) = @_; $opt->{S} = $value; $opt->{i} = 0 if $value; }, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ack-v3.0.3/lib/App/Ack/File.pm new/ack-v3.1.1/lib/App/Ack/File.pm --- old/ack-v3.0.3/lib/App/Ack/File.pm 2019-08-21 06:41:14.000000000 +0200 +++ new/ack-v3.1.1/lib/App/Ack/File.pm 2019-09-01 05:58:01.000000000 +0200 @@ -91,10 +91,45 @@ } +sub may_be_present { + my $self = shift; + my $regex = shift; + + # The $regex may be undef if it had a "$" in it, and is therefore unsuitable for this heuristic. + + my $may_be_present = 1; + if ( $regex && $self->open() && -f $self->{fh} ) { + my $buffer; + my $size = 10_000_000; + my $rc = sysread( $self->{fh}, $buffer, $size ); + if ( !defined($rc) ) { + if ( $App::Ack::report_bad_filenames ) { + App::Ack::warn( $self->name . ": $!" ); + } + $may_be_present = 0; + } + else { + # If we read all 10M, then we need to scan the rest. + # If there are any carriage returns, our results are flaky, so scan the rest. + if ( ($rc == $size) || (index($buffer,"\r") >= 0) ) { + $may_be_present = 1; + } + else { + if ( $buffer !~ /$regex/o ) { + $may_be_present = 0; + } + } + } + } + + return $may_be_present; +} + + =head2 $file->reset() Resets the file back to the beginning. This is only called if -C<needs_line_scan()> is true, but not always if C<needs_line_scan()> +C<may_be_present()> is true, but not always if C<may_be_present()> is true. =cut diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ack-v3.0.3/lib/App/Ack.pm new/ack-v3.1.1/lib/App/Ack.pm --- old/ack-v3.0.3/lib/App/Ack.pm 2019-08-21 06:42:43.000000000 +0200 +++ new/ack-v3.1.1/lib/App/Ack.pm 2019-09-01 05:58:05.000000000 +0200 @@ -17,7 +17,7 @@ our $COPYRIGHT; BEGIN { use version; - $VERSION = version->declare( 'v3.0.3' ); # Check https://beyondgrep.com/ for updates + $VERSION = version->declare( 'v3.1.1' ); # Check https://beyondgrep.com/ for updates $COPYRIGHT = 'Copyright 2005-2019 Andy Lester.'; } our $STANDALONE = 0; @@ -236,6 +236,8 @@ -v, --invert-match Invert match: select non-matching lines -w, --word-regexp Force PATTERN to match only whole words -Q, --literal Quote all metacharacters; PATTERN is literal + --range-start PATTERN Specify PATTERN as the start of a match range. + --range-end PATTERN Specify PATTERN as the end of a match range. --match PATTERN Specify PATTERN explicitly. Typically omitted. Search output: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ack-v3.0.3/t/ack-passthru.t new/ack-v3.1.1/t/ack-passthru.t --- old/ack-v3.0.3/t/ack-passthru.t 2019-08-21 06:41:14.000000000 +0200 +++ new/ack-v3.1.1/t/ack-passthru.t 2019-08-23 05:40:06.000000000 +0200 @@ -3,7 +3,7 @@ use warnings; use strict; -use Test::More tests => 4; +use Test::More tests => 5; use lib 't'; use Util; @@ -13,7 +13,10 @@ my @full_speech = <DATA>; chomp @full_speech; -subtest 'Normal' => sub { +my @johnny_rebeck = read_file( 't/range/johnny-rebeck.txt' ); +chomp @johnny_rebeck; + +subtest 'Gettysburg without --passthru' => sub { plan tests => 2; my @expected = line_split( <<'HERE' ); @@ -30,7 +33,8 @@ lists_match( \@results, \@expected, 'Search for war' ); }; -subtest 'With --passthru' => sub { + +subtest 'Gettysburg with --passthru' => sub { plan tests => 2; my @expected = color_match( qr/war/, @full_speech ); @@ -43,6 +47,31 @@ }; +subtest '--passthru with/without ranges' => sub { + plan tests => 4; + + my @args = qw( Rebeck --passthru --color t/range/johnny-rebeck.txt ); + my @expected = color_match( qr/Rebeck/, @johnny_rebeck ); + + my @results = run_ack( @args ); + lists_match( \@results, \@expected, q{Searching without a range} ); + + my @range_expected; + my $nmatches = 0; + for my $line ( @johnny_rebeck ) { + if ( $line =~ /Rebeck/ ) { + ++$nmatches; + if ( $nmatches == 2 || $nmatches == 3 ) { + ($line) = color_match( qr/Rebeck/, $line ); + } + } + push( @range_expected, $line ); + } + @results = run_ack( @args, '--range-start=CHORUS', '--range-end=VERSE' ); + lists_match( \@results, \@range_expected, q{Searching with a range} ); +}; + + SKIP: { skip 'Input options have not been implemented for Win32 yet', 2 if is_windows(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ack-v3.0.3/t/config-loader.t new/ack-v3.1.1/t/config-loader.t --- old/ack-v3.0.3/t/config-loader.t 2019-08-21 06:17:45.000000000 +0200 +++ new/ack-v3.1.1/t/config-loader.t 2019-08-23 05:40:06.000000000 +0200 @@ -13,35 +13,38 @@ delete @ENV{qw( PAGER ACK_PAGER ACK_PAGER_COLOR )}; my %defaults = ( - 'break' => undef, - c => undef, - color => undef, - column => undef, - f => undef, - files_from => undef, - filters => [ App::Ack::Filter::Default->new ], - follow => undef, - g => undef, - h => undef, - H => undef, - heading => undef, - l => undef, - L => undef, - m => undef, - n => undef, - output => undef, - p => undef, - pager => undef, - passthru => undef, - print0 => undef, - Q => undef, - regex => undef, - s => undef, - show_types => undef, - sort_files => undef, - underline => undef, - v => undef, - w => undef, + 'break' => undef, + c => undef, + color => undef, + column => undef, + f => undef, + files_from => undef, + filters => [ App::Ack::Filter::Default->new ], + follow => undef, + g => undef, + h => undef, + H => undef, + heading => undef, + l => undef, + L => undef, + m => undef, + n => undef, + output => undef, + p => undef, + pager => undef, + passthru => undef, + print0 => undef, + Q => undef, + range_start => undef, + range_end => undef, + range_invert => undef, + regex => undef, + s => undef, + show_types => undef, + sort_files => undef, + underline => undef, + v => undef, + w => undef, ); test_loader( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ack-v3.0.3/t/issue491.t new/ack-v3.1.1/t/issue491.t --- old/ack-v3.0.3/t/issue491.t 2019-05-20 03:39:43.000000000 +0200 +++ new/ack-v3.1.1/t/issue491.t 2019-09-01 05:58:01.000000000 +0200 @@ -1,6 +1,25 @@ #!perl -T -# https://github.com/beyondgrep/ack2/issues/491 +=pod + +This test checks for problems where line endings aren't handled correctly +by our pre-scanning of the file. + + # https://github.com/beyondgrep/ack2/issues/491 + v2.14 with "-l" not emitting all matching files. + + > echo ' ' >space-newline.txt + > echo $' \n' >space-newline-newline.txt + > ack ' $' space-newline*.txt + space-newline-newline.txt + 1: + + space-newline.txt + 1: + > ack -l ' $' space-newline*.txt + space-newline.txt + +=cut use strict; use warnings; @@ -16,22 +35,58 @@ my $wd = getcwd_clean(); safe_chdir( $dir->dirname ); -write_file('space-newline.txt', " \n"); -write_file('space-newline-newline.txt', " \n\n"); - -my @results = run_ack('-l', ' $', 'space-newline.txt', 'space-newline-newline.txt'); -sets_match(\@results, [ - 'space-newline.txt', - 'space-newline-newline.txt', -], 'both files should be in -l output'); - -@results = run_ack('-c', ' $', 'space-newline.txt', 'space-newline-newline.txt'); - -sets_match(\@results, [ - 'space-newline.txt:1', - 'space-newline-newline.txt:1', -], 'both files should be in -c output with correct counts'); +my %matching_files = ( + 'space-newline.txt' => " \n", + 'space-newline-space.txt' => " \n\t", + 'space-newline-newline.txt' => " \n\n", + 'space-newline-and-more.txt' => "this\n \nthat\n", + 'words-and-spaces.txt' => "this \nand that\n", +); +my %nonmatching_files = ( + 'tabby.txt' => "\t\n", + 'also-tabby.txt' => " \t\n", +); + +my %all_files = ( %matching_files, %nonmatching_files ); +while ( my ($file,$content) = each %all_files ) { + write_file( $file, $content ); +} +my @all_files = keys %all_files; +my @matching_files = keys %matching_files; +my @nonmatching_files = keys %nonmatching_files; + +subtest 'Match normally' => sub { + plan tests => 2; + + my @results = run_ack( ' $', @all_files ); + my @files_matched = @results; + s/:.*// for @files_matched; + sets_match( \@files_matched, [ @matching_files ], 'Found all the matching files in results' ); +}; + +subtest 'Match with -l' => sub { + plan tests => 2; + + my @results = run_ack( '-l', ' $', @all_files ); + sets_match( \@results, [ @matching_files ], 'Matching files should be in -l output' ); +}; + +subtest 'Non-match with -L' => sub { + plan tests => 2; + + my @results = run_ack( '-L', ' $', @all_files ); + sets_match( \@results, [ @nonmatching_files ], 'Nonmatching files should be in -L output' ); +}; + +subtest 'Count with -c' => sub { + plan tests => 2; + + my @results = run_ack( '-c', ' $', @all_files ); + sets_match( \@results, [ + map { "$_:" . ( $matching_files{$_} ? 1 : 0 ) } @all_files + ], 'Matching files should be in -c output with correct counts' ); +}; safe_chdir( $wd ); # Get out of temp directory so it can be cleaned up. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ack-v3.0.3/t/lowercase.t new/ack-v3.1.1/t/lowercase.t --- old/ack-v3.0.3/t/lowercase.t 2019-08-21 06:41:14.000000000 +0200 +++ new/ack-v3.1.1/t/lowercase.t 2019-08-23 05:40:06.000000000 +0200 @@ -4,7 +4,7 @@ use strict; use 5.010; -use Test::More tests => 2;; +use Test::More tests => 2; use App::Ack; @@ -107,11 +107,5 @@ sub _big_split { my $str = shift; - my @list = split( /\n/, $str ); - - @list = grep /./, @list; - - @list = grep !/^#/, @list; - - return @list; + return grep { /./ && !/^#/ } split( /\n/, $str ); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ack-v3.0.3/t/range/america-the-beautiful.html new/ack-v3.1.1/t/range/america-the-beautiful.html --- old/ack-v3.0.3/t/range/america-the-beautiful.html 1970-01-01 01:00:00.000000000 +0100 +++ new/ack-v3.1.1/t/range/america-the-beautiful.html 2019-08-23 05:40:06.000000000 +0200 @@ -0,0 +1,53 @@ +<!DOCTYPE html> +<html> + <head> + <title>America the Beautiful</title> + </head> + <body> + <h1>America the Beautiful</h1> + + <div id="verse-1"> + O beautiful for spacious skies, + For amber waves of grain, + For purple mountain majesties + Above the fruited plain! + America! America! + God shed His grace on thee + And crown thy good with brotherhood + From sea to shining sea! + </div> + + <div id="verse-2"> + O beautiful for pilgrim feet, + Whose stern, impassioned stress + A thoroughfare for freedom beat + Across the wilderness! + America! America! + God mend thine every flaw, + Confirm thy soul in self-control, + Thy liberty in law! + </div> + + <div id="verse-3"> + O beautiful for heroes proved + In liberating strife, + Who more than self their country loved + And mercy more than life! + America! America! + May God thy gold refine, + Till all success be nobleness, + And every gain divine! + </div> + + <div id="verse-4"> + O beautiful for patriot dream + That sees beyond the years + Thine alabaster cities gleam + Undimmed by human tears! + America! America! + God shed His grace on thee + And crown thy good with brotherhood + From sea to shining sea! + </div> + </body> +</html> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ack-v3.0.3/t/range/anchors-aweigh.html new/ack-v3.1.1/t/range/anchors-aweigh.html --- old/ack-v3.0.3/t/range/anchors-aweigh.html 1970-01-01 01:00:00.000000000 +0100 +++ new/ack-v3.1.1/t/range/anchors-aweigh.html 2019-08-23 05:40:06.000000000 +0200 @@ -0,0 +1,30 @@ +<!DOCTYPE html> +<html> + <head> + <title>Anchors Aweigh</title>> + </head> + <body> + <h1>Anchors Aweigh</h1> + + <div id="verse-1"> + Stand Navy out to sea, fight our battle cry! + We'll never change our course so vicious foes steer shy-y-y-y! + Roll out the TNT, anchors aweigh! + Sail on to victory, and sink their bones to Davy Jones, hooray! + </div> + + <div id="verse-2"> + Anchors Aweigh, my boys, Anchors Aweigh! + Farewell to foreign Shores, we sail at break of day-ay-ay-ay; + Through our last night ashore, drink to the foam, + Until we meet once more, here's wishing you a happy voyage home! + </div> + + <div id="verse-3"> + Blue of the mighty deep, Gold of God's great sun; + Let these our colors be, Till All of time be done-n-n-ne; + On seven seas we learn, Navy's stern call: + Faith, courage, service true, With honor over, honor over all. + </div> + </body> +</html> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ack-v3.0.3/t/range/johnny-rebeck.txt new/ack-v3.1.1/t/range/johnny-rebeck.txt --- old/ack-v3.0.3/t/range/johnny-rebeck.txt 1970-01-01 01:00:00.000000000 +0100 +++ new/ack-v3.1.1/t/range/johnny-rebeck.txt 2019-08-23 05:40:06.000000000 +0200 @@ -0,0 +1,29 @@ +VERSE +There once was a little Dutchman +His name was Johnny Rebeck +He was a dealer in sauerkraut +And sausages and speck +He was the finest Dutchman +The best you've ever seen +'til one day he invented +A great big sausage machine +Bang! + +CHORUS +Oh, Mr. Johnny Rebeck what makes you be so mean? +I told you you'd be sorry for inventing that machine +Now all the neighbors' cats and dogs will nevermore be seen +They'll all be ground to sausages in Johnny Rebeck's machine. +Bang! + +VERSE +One night the darn thing busted +The darn thing wouldn't go +So Johnny Rebeck crawled inside +To see what made it so +That night his wife had a nightmare +And walking in her sleep +She turned the crank +And gave it a yank +Pooooor Johnny Rebeck was meat +Bang! diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ack-v3.0.3/t/range/rangefile.pm new/ack-v3.1.1/t/range/rangefile.pm --- old/ack-v3.0.3/t/range/rangefile.pm 1970-01-01 01:00:00.000000000 +0100 +++ new/ack-v3.1.1/t/range/rangefile.pm 2019-08-23 05:40:06.000000000 +0200 @@ -0,0 +1,25 @@ +package RangeFile; + +# For testing the range function. + +use warnings; +use strict; +use 5.010; + +# This function calls print on "foo". +sub foo { + print 'foo'; + return 1; +} + +my $print = 1; +my $update = 5; + +sub bar { + print 'bar'; + return 2; +} +my $task = 'print'; +$update = 12; + +1; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ack-v3.0.3/t/range/stars-and-stripes-forever.html new/ack-v3.1.1/t/range/stars-and-stripes-forever.html --- old/ack-v3.0.3/t/range/stars-and-stripes-forever.html 1970-01-01 01:00:00.000000000 +0100 +++ new/ack-v3.1.1/t/range/stars-and-stripes-forever.html 2019-08-23 05:40:06.000000000 +0200 @@ -0,0 +1,62 @@ +<!DOCTYPE html> +<html> + <head> + <title>The Stars and Stripes Forever</title> + </head> + <body> + <h1>The Stars and Stripes Forever</h1> + + <h2>By John Philip Sousa</h2> + + <div id="first-strain"> + Let martial note in triumph float + And liberty extend its mighty hand + A flag appears 'mid thunderous cheers, + The banner of the Western land. + The emblem of the brave and true + Its folds protect no tyrant crew; + The red and white and starry blue + Is freedom's shield and hope. + + Let eagle shriek from lofty peak + The never-ending watchword of our land; + Let summer breeze waft through the trees + The echo of the chorus grand. + Sing out for liberty and light, + Sing out for freedom and the right. + Sing out for Union and its might, + O patriotic sons. + </div> + + <div id="second-strain"> + Other nations may deem their flags the best + And cheer them with fervid elation + But the flag of the North and South and West + Is the flag of flags, the flag of Freedom's nation. + </div> + + <div id="trio"> + Hurrah for the flag of the free! + May it wave as our standard forever, + The gem of the land and the sea, + The banner of the right. + Let despots remember the day + When our fathers with mighty endeavor + Proclaimed as they marched to the fray + That by their might and by their right + It waves forever. + </div> + + <div id="grandioso"> + Hurrah for the flag of the free. + May it wave as our standard forever + The gem of the land and the sea, + The banner of the right. + Let despots remember the day + When our fathers with mighty endeavor + Proclaimed as they marched to the fray, + That by their might and by their right + It waves forever. + </div> + </body> +</html> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ack-v3.0.3/xt/coding-standards.t new/ack-v3.1.1/xt/coding-standards.t --- old/ack-v3.0.3/xt/coding-standards.t 2019-07-05 05:21:07.000000000 +0200 +++ new/ack-v3.1.1/xt/coding-standards.t 2019-08-23 05:40:06.000000000 +0200 @@ -24,7 +24,7 @@ push( @files, @these_files ); } -@files = grep !/lowercase.t/, @files; # lowercase.t has hi-bit and it's OK. +@files = grep { !/lowercase.t/ } @files; # lowercase.t has hi-bit and it's OK. plan tests => scalar @files;