3 # This file, ack, is generated code. 
   4 # Please DO NOT EDIT or send patches for it. 
   6 # Please take a look at the source from 
   7 # https://github.com/beyondgrep/ack2 
   8 # and submit patches against the individual files 
  16 our $VERSION = '2.22'; # Check https://beyondgrep.com/ for updates 
  19 use Getopt
::Long 
2.38 (); 
  25 # XXX Don't make this so brute force 
  26 # See also: https://github.com/beyondgrep/ack2/issues/89 
  28 our $opt_after_context; 
  29 our $opt_before_context; 
  34 our $opt_show_filename; 
  48 # Flag if we need any context tracking. 
  49 our $is_tracking_context; 
  51 # These are all our globals. 
  54     $App::Ack
::orig_program_name 
= $0; 
  55     $0 = join(' ', 'ack', $0); 
  56     if ( $App::Ack
::VERSION 
ne $main::VERSION 
) { 
  57         App
::Ack
::die( "Program/library version mismatch\n\t$0 is $main::VERSION\n\t$INC{'App/Ack.pm'} is $App::Ack::VERSION" ); 
  60     # Do preliminary arg checking; 
  61     my $env_is_usable = 1; 
  62     for my $arg ( @ARGV ) { 
  63         last if ( $arg eq '--' ); 
  65         # Get the --thpppt, --bar, --cathy checking out of the way. 
  66         $arg =~ /^--th[pt]+t+$/ and App
::Ack
::thpppt
($arg); 
  67         $arg eq '--bar'         and App
::Ack
::ackbar
(); 
  68         $arg eq '--cathy'       and App
::Ack
::cathy
(); 
  70         # See if we want to ignore the environment. (Don't tell Al Gore.) 
  71         $arg eq '--env'         and $env_is_usable = 1; 
  72         $arg eq '--noenv'       and $env_is_usable = 0; 
  75     if ( !$env_is_usable ) { 
  76         my @keys = ( 'ACKRC', grep { /^ACK_/ } keys %ENV ); 
  81     Getopt
::Long
::Configure
('default', 'no_auto_help', 'no_auto_version'); 
  82     Getopt
::Long
::Configure
('pass_through', 'no_auto_abbrev'); 
  83     Getopt
::Long
::GetOptions
( 
  84         'help'       => sub { App
::Ack
::show_help
(); exit; }, 
  85         'version'    => sub { App
::Ack
::print_version_statement
(); exit; }, 
  86         'man'        => sub { App
::Ack
::show_man
(); exit; }, 
  88     Getopt
::Long
::Configure
('default', 'no_auto_help', 'no_auto_version'); 
  91         App
::Ack
::show_help
(); 
  98 sub _compile_descend_filter 
{ 
 102     my $dont_ignore_dirs = 0; 
 104     for my $filter (@{$opt->{idirs
} || []}) { 
 105         if ($filter->is_inverted()) { 
 113     # If we have one or more --noignore-dir directives, we can't ignore 
 114     # entire subdirectory hierarchies, so we return an "accept all" 
 115     # filter and scrutinize the files more in _compile_file_filter. 
 116     return if $dont_ignore_dirs; 
 117     return unless $idirs; 
 119     $idirs = $opt->{idirs
}; 
 122         my $resource = App
::Ack
::Resource-
>new($File::Next
::dir
); 
 123         return !grep { $_->filter($resource) } @{$idirs}; 
 127 sub _compile_file_filter 
{ 
 128     my ( $opt, $start ) = @_; 
 130     my $ifiles_filters = $opt->{ifiles
}; 
 132     my $filters         = $opt->{'filters'} || []; 
 133     my $direct_filters = App
::Ack
::Filter
::Collection-
>new(); 
 134     my $inverse_filters = App
::Ack
::Filter
::Collection-
>new(); 
 136     foreach my $filter (@{$filters}) { 
 137         if ($filter->is_inverted()) { 
 138             # We want to check if files match the uninverted filters 
 139             $inverse_filters->add($filter->invert()); 
 142             $direct_filters->add($filter); 
 146     my %is_member_of_starting_set = map { (get_file_id
($_) => 1) } @{$start}; 
 148     my @ignore_dir_filter = @{$opt->{idirs
} || []}; 
 149     my @is_inverted       = map { $_->is_inverted() } @ignore_dir_filter; 
 150     # This depends on InverseFilter->invert returning the original filter (for optimization). 
 151     @ignore_dir_filter         = map { $_->is_inverted() ? $_->invert() : $_ } @ignore_dir_filter; 
 152     my $dont_ignore_dir_filter = grep { $_ } @is_inverted; 
 153     my $previous_dir = ''; 
 154     my $previous_dir_ignore_result; 
 158             if ( $File::Next
::name 
=~ /$opt_regex/ && $opt_v ) { 
 161             if ( $File::Next
::name 
!~ /$opt_regex/ && !$opt_v ) { 
 165         # ack always selects files that are specified on the command 
 166         # line, regardless of filetype.  If you want to ack a JPEG, 
 167         # and say "ack foo whatever.jpg" it will do it for you. 
 168         return 1 if $is_member_of_starting_set{ get_file_id
($File::Next
::name
) }; 
 170         if ( $dont_ignore_dir_filter ) { 
 171             if ( $previous_dir eq $File::Next
::dir 
) { 
 172                 if ( $previous_dir_ignore_result ) { 
 177                 my @dirs = File
::Spec-
>splitdir($File::Next
::dir
); 
 181                 for ( my $i = 0; $i < @dirs; $i++) { 
 182                     my $dir_rsrc = App
::Ack
::Resource-
>new(File
::Spec-
>catfile(@dirs[0 .. $i])); 
 185                     for my $filter (@ignore_dir_filter) { 
 186                         if ( $filter->filter($dir_rsrc) ) { 
 187                             $is_ignoring = !$is_inverted[$j]; 
 193                 $previous_dir               = $File::Next
::dir
; 
 194                 $previous_dir_ignore_result = $is_ignoring; 
 196                 if ( $is_ignoring ) { 
 202         # Ignore named pipes found in directory searching.  Named 
 203         # pipes created by subprocesses get specified on the command 
 204         # line, so the rule of "always select whatever is on the 
 205         # command line" wins. 
 206         return 0 if -p 
$File::Next
::name
; 
 208         # We can't handle unreadable filenames; report them. 
 210             use filetest 
'access'; 
 212             if ( not -R 
$File::Next
::name 
) { 
 213                 if ( $App::Ack
::report_bad_filenames 
) { 
 214                     App
::Ack
::warn( "${File::Next::name}: cannot open file for reading" ); 
 220         my $resource = App
::Ack
::Resource-
>new($File::Next
::name
); 
 222         if ( $ifiles_filters && $ifiles_filters->filter($resource) ) { 
 226         my $match_found = $direct_filters->filter($resource); 
 228         # Don't bother invoking inverse filters unless we consider the current resource a match 
 229         if ( $match_found && $inverse_filters->filter( $resource ) ) { 
 237     my $resource = shift; 
 240     my @types = filetypes
( $resource ); 
 241     my $types = join( ',', @types ); 
 242     my $arrow = @types ? ' => ' : ' =>'; 
 243     App
::Ack
::print( $resource->name, $arrow, join( ',', @types ), $ors ); 
 248 # Set default colors, load Term::ANSIColor 
 250     eval 'use Term::ANSIColor 1.10 ()'; 
 251     eval 'use Win32::Console::ANSI' if $App::Ack
::is_windows
; 
 253     $ENV{ACK_COLOR_MATCH
}    ||= 'black on_yellow'; 
 254     $ENV{ACK_COLOR_FILENAME
} ||= 'bold green'; 
 255     $ENV{ACK_COLOR_LINENO
}   ||= 'bold yellow'; 
 261     my ( $resource ) = @_; 
 265     foreach my $k (keys %App::Ack
::mappings
) { 
 266         my $filters = $App::Ack
::mappings
{$k}; 
 268         foreach my $filter (@{$filters}) { 
 269             # Clone the resource. 
 270             my $clone = $resource->clone; 
 271             if ( $filter->filter($clone) ) { 
 278     # http://search.cpan.org/dist/Perl-Critic/lib/Perl/Critic/Policy/Subroutines/ProhibitReturnSort.pm 
 279     @matches = sort @matches; 
 283 # Returns a (fairly) unique identifier for a file. 
 284 # Use this function to compare two files to see if they're 
 285 # equal (ie. the same file, but with a different path/links/etc). 
 287     my ( $filename ) = @_; 
 289     if ( $App::Ack
::is_windows 
) { 
 290         return File
::Next
::reslash
( $filename ); 
 293         # XXX Is this the best method? It always hits the FS. 
 294         if( my ( $dev, $inode ) = (stat($filename))[0, 1] ) { 
 295             return join(':', $dev, $inode); 
 298             # XXX This could be better. 
 304 # Returns a regex object based on a string and command-line options. 
 305 # Dies when the regex $str is undefined (i.e. not given on command line). 
 311     defined $str or App
::Ack
::die( 'No regular expression found.' ); 
 313     $str = quotemeta( $str ) if $opt->{Q
}; 
 315         my $pristine_str = $str; 
 318         $str = "\\b$str" if $pristine_str =~ /^\w/; 
 319         $str = "$str\\b" if $pristine_str =~ /\w$/; 
 322     my $regex_is_lc = $str eq lc $str; 
 323     if ( $opt->{i
} || ($opt->{smart_case
} && $regex_is_lc) ) { 
 327     my $re = eval { qr/$str/m }; 
 329         die "Invalid regex '$str':\n  $@"; 
 336 my $match_column_number; 
 340 # Number of context lines 
 341 my $n_before_ctx_lines; 
 342 my $n_after_ctx_lines; 
 344 # Array to keep track of lines that might be required for a "before" context 
 345 my @before_context_buf; 
 346 # Position to insert next line in @before_context_buf 
 347 my $before_context_pos; 
 349 # Number of "after" context lines still pending 
 350 my $after_context_pending; 
 352 # Number of latest line that got printed 
 358 my $has_printed_something; 
 361     $has_printed_something = 0; 
 364 # Set up context tracking variables. 
 365 sub set_up_line_context 
{ 
 366     $n_before_ctx_lines = $opt_output ? 0 : ($opt_before_context || 0); 
 367     $n_after_ctx_lines  = $opt_output ? 0 : ($opt_after_context || 0); 
 369     @before_context_buf = (undef) x 
$n_before_ctx_lines; 
 370     $before_context_pos = 0; 
 372     $is_tracking_context = $n_before_ctx_lines || $n_after_ctx_lines; 
 379 # Adjust context tracking variables when entering a new file. 
 380 sub set_up_line_context_for_file 
{ 
 381     $printed_line_no = 0; 
 382     $after_context_pending = 0; 
 383     if ( $opt_heading && !$opt_lines ) { 
 392 This subroutine jumps through a number of optimization hoops to 
 393 try to be fast in the more common use cases of ack.  For one thing, 
 394 in non-context tracking searches (not using -A, -B, or -C), 
 395 conditions that normally would be checked inside the loop happen 
 396 outside, resulting in three nearly identical loops for -v, --passthru, 
 397 and normal searching.  Any changes that happen to one should propagate 
 398 to the others if they make sense.  The non-context branches also inline 
 399 does_match for performance reasons; any relevant changes that happen here 
 400 must also happen there. 
 406 sub print_matches_in_resource 
{ 
 407     my ( $resource ) = @_; 
 409     my $max_count      = $opt_m || -1; 
 411     my $filename       = $resource->name; 
 412     my $ors            = $opt_print0 ? "\0" : "\n"; 
 414     my $has_printed_for_this_resource = 0; 
 418     my $fh = $resource->open(); 
 420         if ( $App::Ack
::report_bad_filenames 
) { 
 421             App
::Ack
::warn( "$filename: $!" ); 
 426     my $display_filename = $filename; 
 427     if ( $opt_show_filename && $opt_heading && $opt_color ) { 
 428         $display_filename = Term
::ANSIColor
::colored
($display_filename, $ENV{ACK_COLOR_FILENAME
}); 
 431     # Check for context before the main loop, so we don't pay for it if we don't need it. 
 432     if ( $is_tracking_context ) { 
 433         $after_context_pending = 0; 
 435             if ( does_match
( $_ ) && $max_count ) { 
 436                 if ( !$has_printed_for_this_resource ) { 
 437                     if ( $opt_break && $has_printed_something ) { 
 438                         App
::Ack
::print_blank_line
(); 
 440                     if ( $opt_show_filename && $opt_heading ) { 
 441                         App
::Ack
::print_filename
( $display_filename, $ors ); 
 444                 print_line_with_context
( $filename, $_, $. ); 
 445                 $has_printed_for_this_resource = 1; 
 449             elsif ( $opt_passthru ) { 
 450                 chomp; # XXX Proper newline handling? 
 451                 # XXX Inline this call? 
 452                 if ( $opt_break && !$has_printed_for_this_resource && $has_printed_something ) { 
 453                     App
::Ack
::print_blank_line
(); 
 455                 print_line_with_options
( $filename, $_, $., ':' ); 
 456                 $has_printed_for_this_resource = 1; 
 459                 chomp; # XXX Proper newline handling? 
 460                 print_line_if_context
( $filename, $_, $., '-' ); 
 463             last if ($max_count == 0) && ($after_context_pending == 0); 
 467         if ( $opt_passthru ) { 
 471                 $match_column_number = undef; 
 472                 if ( $opt_v ? !/$opt_regex/o : /$opt_regex/o ) { 
 474                         $match_column_number = $-[0] + 1; 
 476                     if ( !$has_printed_for_this_resource ) { 
 477                         if ( $opt_break && $has_printed_something ) { 
 478                             App
::Ack
::print_blank_line
(); 
 480                         if ( $opt_show_filename && $opt_heading ) { 
 481                             App
::Ack
::print_filename
( $display_filename, $ors ); 
 484                     print_line_with_context
( $filename, $_, $. ); 
 485                     $has_printed_for_this_resource = 1; 
 490                     chomp; # XXX proper newline handling? 
 491                     if ( $opt_break && !$has_printed_for_this_resource && $has_printed_something ) { 
 492                         App
::Ack
::print_blank_line
(); 
 494                     print_line_with_options
( $filename, $_, $., ':' ); 
 495                     $has_printed_for_this_resource = 1; 
 497                 last unless $max_count != 0; 
 503             $match_column_number = undef; 
 505                 if ( !/$opt_regex/o ) { 
 506                     if ( !$has_printed_for_this_resource ) { 
 507                         if ( $opt_break && $has_printed_something ) { 
 508                             App
::Ack
::print_blank_line
(); 
 510                         if ( $opt_show_filename && $opt_heading ) { 
 511                             App
::Ack
::print_filename
( $display_filename, $ors ); 
 514                     print_line_with_context
( $filename, $_, $. ); 
 515                     $has_printed_for_this_resource = 1; 
 519                 last unless $max_count != 0; 
 526                 $match_column_number = undef; 
 527                 if ( /$opt_regex/o ) { 
 528                     $match_column_number = $-[0] + 1; 
 529                     if ( !$has_printed_for_this_resource ) { 
 530                         if ( $opt_break && $has_printed_something ) { 
 531                             App
::Ack
::print_blank_line
(); 
 533                         if ( $opt_show_filename && $opt_heading ) { 
 534                             App
::Ack
::print_filename
( $display_filename, $ors ); 
 538                     print_line_with_options
( $filename, $_, $., ':' ); 
 539                     $has_printed_for_this_resource = 1; 
 543                 last unless $max_count != 0; 
 554 sub print_line_with_options 
{ 
 555     my ( $filename, $line, $line_no, $separator ) = @_; 
 557     $has_printed_something = 1; 
 558     $printed_line_no = $line_no; 
 560     my $ors = $opt_print0 ? "\0" : "\n"; 
 565         $filename = Term
::ANSIColor
::colored
($filename, 
 566             $ENV{ACK_COLOR_FILENAME
}); 
 567         $line_no  = Term
::ANSIColor
::colored
($line_no, 
 568             $ENV{ACK_COLOR_LINENO
}); 
 571     if($opt_show_filename) { 
 573             push @line_parts, $line_no; 
 576             push @line_parts, $filename, $line_no; 
 580             push @line_parts, get_match_column
(); 
 584         while ( $line =~ /$opt_regex/og ) { 
 585             # XXX We need to stop using eval() for --output.  See https://github.com/beyondgrep/ack2/issues/421 
 586             my $output = eval $opt_output; 
 587             App
::Ack
::print( join( $separator, @line_parts, $output ), $ors ); 
 592             # This match is redundant, but we need to perfom it in order to get if capture groups are set. 
 593             $line =~ /$opt_regex/o; 
 595             if ( @+ > 1 ) { # If we have captures... 
 596                 while ( $line =~ /$opt_regex/og ) { 
 597                     my $offset = 0; # Additional offset for when we add stuff. 
 598                     my $previous_match_end = 0; 
 600                     last if $-[0] == $+[0]; 
 602                     for ( my $i = 1; $i < @+; $i++ ) { 
 603                         my ( $match_start, $match_end ) = ( $-[$i], $+[$i] ); 
 605                         next unless defined($match_start); 
 606                         next if $match_start < $previous_match_end; 
 608                         my $substring = substr( $line, 
 609                             $offset + $match_start, $match_end - $match_start ); 
 610                         my $substitution = Term
::ANSIColor
::colored
( $substring, 
 611                             $ENV{ACK_COLOR_MATCH
} ); 
 613                         substr( $line, $offset + $match_start, 
 614                             $match_end - $match_start, $substitution ); 
 616                         $previous_match_end  = $match_end; # Offsets do not need to be applied. 
 617                         $offset             += length( $substitution ) - length( $substring ); 
 620                     pos($line) = $+[0] + $offset; 
 624                 my $matched = 0; # If matched, need to escape afterwards. 
 626                 while ( $line =~ /$opt_regex/og ) { 
 629                     my ( $match_start, $match_end ) = ($-[0], $+[0]); 
 630                     next unless defined($match_start); 
 631                     last if $match_start == $match_end; 
 633                     my $substring = substr( $line, $match_start, 
 634                         $match_end - $match_start ); 
 635                     my $substitution = Term
::ANSIColor
::colored
( $substring, 
 636                         $ENV{ACK_COLOR_MATCH
} ); 
 638                     substr( $line, $match_start, $match_end - $match_start, 
 641                     pos($line) = $match_end + 
 642                     (length( $substitution ) - length( $substring )); 
 644                 # XXX Why do we do this? 
 645                 $line .= "\033[0m\033[K" if $matched; 
 649         push @line_parts, $line; 
 650         App
::Ack
::print( join( $separator, @line_parts ), $ors ); 
 657     my ( $resource, $cb ) = @_; 
 661     my $fh = $resource->open(); 
 663         if ( $App::Ack
::report_bad_filenames 
) { 
 664             App
::Ack
::warn( $resource->name . ': ' . $! ); 
 669     # Check for context before the main loop, so we don't pay for it if we don't need it. 
 670     if ( $is_tracking_context ) { 
 671         $after_context_pending = 0; 
 690 sub print_line_with_context 
{ 
 691     my ( $filename, $matching_line, $line_no ) = @_; 
 693     my $ors                 = $opt_print0 ? "\0" : "\n"; 
 694     my $is_tracking_context = $opt_after_context || $opt_before_context; 
 696     $matching_line =~ s/[\r\n]+$//g; 
 698     # Check if we need to print context lines first. 
 699     if ( $is_tracking_context ) { 
 700         my $before_unprinted = $line_no - $printed_line_no - 1; 
 701         if ( !$is_first_match && ( !$printed_line_no || $before_unprinted > $n_before_ctx_lines ) ) { 
 702             App
::Ack
::print('--', $ors); 
 705         # We want at most $n_before_ctx_lines of context. 
 706         if ( $before_unprinted > $n_before_ctx_lines ) { 
 707             $before_unprinted = $n_before_ctx_lines; 
 710         while ( $before_unprinted > 0 ) { 
 711             my $line = $before_context_buf[($before_context_pos - $before_unprinted + $n_before_ctx_lines) % $n_before_ctx_lines]; 
 715             # Disable $opt->{column} since there are no matches in the context lines. 
 716             local $opt_column = 0; 
 718             print_line_with_options
( $filename, $line, $line_no-$before_unprinted, '-' ); 
 723     print_line_with_options
( $filename, $matching_line, $line_no, ':' ); 
 725     # We want to get the next $n_after_ctx_lines printed. 
 726     $after_context_pending = $n_after_ctx_lines; 
 733 # Print the line only if it's part of a context we need to display. 
 734 sub print_line_if_context 
{ 
 735     my ( $filename, $line, $line_no, $separator ) = @_; 
 737     if ( $after_context_pending ) { 
 738         # Disable $opt_column since there are no matches in the context lines. 
 739         local $opt_column = 0; 
 740         print_line_with_options
( $filename, $line, $line_no, $separator ); 
 741         --$after_context_pending; 
 743     elsif ( $n_before_ctx_lines ) { 
 744         # Save line for "before" context. 
 745         $before_context_buf[$before_context_pos] = $_; 
 746         $before_context_pos = ($before_context_pos+1) % $n_before_ctx_lines; 
 754 # does_match() MUST have an $opt_regex set. 
 758 This subroutine is inlined a few places in print_matches_in_resource 
 759 for performance reasons, so any changes here must be copied there as 
 769     $match_column_number = undef; 
 772         return ( $line !~ /$opt_regex/o ); 
 775         if ( $line =~ /$opt_regex/o ) { 
 776             # @- = @LAST_MATCH_START 
 777             # @+ = @LAST_MATCH_END 
 778             $match_column_number = $-[0] + 1; 
 787 sub get_match_column 
{ 
 788     return $match_column_number; 
 791 sub resource_has_match 
{ 
 792     my ( $resource ) = @_; 
 795     my $fh = $resource->open(); 
 797         if ( $App::Ack
::report_bad_filenames 
) { 
 798             App
::Ack
::warn( $resource->name . ': ' . $! ); 
 803             if (/$opt_regex/o xor $opt_v) { 
 814 sub count_matches_in_resource 
{ 
 815     my ( $resource ) = @_; 
 818     my $fh = $resource->open(); 
 820         if ( $App::Ack
::report_bad_filenames 
) { 
 821             App
::Ack
::warn( $resource->name . ': ' . $! ); 
 826             ++$nmatches if (/$opt_regex/o xor $opt_v); 
 835     my @arg_sources = App
::Ack
::ConfigLoader
::retrieve_arg_sources
(); 
 837     my $opt = App
::Ack
::ConfigLoader
::process_args
( @arg_sources ); 
 839     $opt_after_context  = $opt->{after_context
}; 
 840     $opt_before_context = $opt->{before_context
}; 
 841     $opt_output         = $opt->{output
}; 
 842     $opt_print0         = $opt->{print0
}; 
 843     $opt_color          = $opt->{color
}; 
 844     $opt_heading        = $opt->{heading
}; 
 845     $opt_show_filename  = $opt->{show_filename
}; 
 846     $opt_regex          = $opt->{regex
}; 
 847     $opt_break          = $opt->{break}; 
 848     $opt_count          = $opt->{count
}; 
 853     $opt_lines          = $opt->{lines
}; 
 856     $opt_passthru       = $opt->{passthru
}; 
 857     $opt_column         = $opt->{column
}; 
 859     $App::Ack
::report_bad_filenames 
= !$opt->{dont_report_bad_filenames
}; 
 861     if ( $opt->{flush
} ) { 
 865     if ( !defined($opt_color) && !$opt_g ) { 
 866         my $windows_color = 1; 
 867         if ( $App::Ack
::is_windows 
) { 
 868             $windows_color = eval { require Win32
::Console
::ANSI
; }; 
 870         $opt_color = !App
::Ack
::output_to_pipe
() && $windows_color; 
 872     if ( not defined $opt_heading and not defined $opt_break  ) { 
 873         $opt_heading = $opt_break = $opt->{break} = !App
::Ack
::output_to_pipe
(); 
 876     if ( defined($opt->{H
}) || defined($opt->{h
}) ) { 
 877         $opt_show_filename = $opt->{show_filename
} = $opt->{H
} && !$opt->{h
}; 
 880     if ( my $output = $opt_output ) { 
 881         $output        =~ s{\\}{\\\\}g; 
 882         $output        =~ s{"}{\\"}g; 
 883         $opt_output = qq{"$output"}; 
 887     if ( $App::Ack
::is_filter_mode 
&& !$opt->{files_from
} ) { # probably -x 
 888         $resources    = App
::Ack
::Resources-
>from_stdin( $opt ); 
 889         $opt_regex = shift @ARGV if not defined $opt_regex; 
 890         $opt_regex = $opt->{regex
} = build_regex
( $opt_regex, $opt ); 
 893         if ( $opt_f || $opt_lines ) { 
 895                 App
::Ack
::warn( "regex ($opt_regex) specified with -f or --lines" ); 
 896                 App
::Ack
::exit_from_ack
( 0 ); # XXX the 0 is misleading 
 900             $opt_regex = shift @ARGV if not defined $opt_regex; 
 901             $opt_regex = $opt->{regex
} = build_regex
( $opt_regex, $opt ); 
 903         if ( $opt_regex && $opt_regex =~ /\n/ ) { 
 904             App
::Ack
::exit_from_ack
( 0 ); 
 907         if ( not defined $opt->{files_from
} ) { 
 910         if ( !exists($opt->{show_filename
}) ) { 
 911             unless(@start == 1 && !(-d 
$start[0])) { 
 912                 $opt_show_filename = $opt->{show_filename
} = 1; 
 916         if ( defined $opt->{files_from
} ) { 
 917             $resources = App
::Ack
::Resources-
>from_file( $opt, $opt->{files_from
} ); 
 918             exit 1 unless $resources; 
 921             @start = ('.') unless @start; 
 922             foreach my $target (@start) { 
 923                 if ( !-e 
$target && $App::Ack
::report_bad_filenames
) { 
 924                     App
::Ack
::warn( "$target: No such file or directory" ); 
 928             $opt->{file_filter
}    = _compile_file_filter
($opt, \
@start); 
 929             $opt->{descend_filter
} = _compile_descend_filter
($opt); 
 931             $resources = App
::Ack
::Resources-
>from_argv( $opt, \
@start ); 
 934     App
::Ack
::set_up_pager
( $opt->{pager
} ) if defined $opt->{pager
}; 
 936     my $ors        = $opt_print0 ? "\0" : "\n"; 
 937     my $only_first = $opt->{1}; 
 942     set_up_line_context
(); 
 945     while ( my $resource = $resources->next ) { 
 946         if ($is_tracking_context) { 
 947             set_up_line_context_for_file
(); 
 951             if ( $opt->{show_types
} ) { 
 952                 show_types
( $resource, $ors ); 
 955                 App
::Ack
::print( $resource->name, $ors ); 
 958             last RESOURCES 
if defined($opt_m) && $nmatches >= $opt_m; 
 961             if ( $opt->{show_types
} ) { 
 962                 show_types
( $resource, $ors ); 
 965                 local $opt_show_filename = 0; # XXX Why is this local? 
 967                 print_line_with_options
( '', $resource->name, 0, $ors ); 
 970             last RESOURCES 
if defined($opt_m) && $nmatches >= $opt_m; 
 972         elsif ( $opt_lines ) { 
 974             foreach my $line ( @{ $opt_lines } ) { 
 975                 my @lines             = split /,/, $line; 
 981                 @line_numbers{@lines} = (1) x 
@lines; 
 984             my $filename = $resource->name; 
 986             local $opt_color = 0; 
 988             iterate
( $resource, sub { 
 991                 if ( $line_numbers{$.} ) { 
 992                     print_line_with_context
( $filename, $_, $. ); 
 994                 elsif ( $opt_passthru ) { 
 995                     print_line_with_options
( $filename, $_, $., ':' ); 
 997                 elsif ( $is_tracking_context ) { 
 998                     print_line_if_context
( $filename, $_, $., '-' ); 
1003         elsif ( $opt_count ) { 
1004             my $matches_for_this_file = count_matches_in_resource
( $resource ); 
1006             if ( not $opt_show_filename ) { 
1007                 $total_count += $matches_for_this_file; 
1011             if ( !$opt_l || $matches_for_this_file > 0) { 
1012                 if ( $opt_show_filename ) { 
1013                     App
::Ack
::print( $resource->name, ':', $matches_for_this_file, $ors ); 
1016                     App
::Ack
::print( $matches_for_this_file, $ors ); 
1020         elsif ( $opt_l || $opt_L ) { 
1021             my $is_match = resource_has_match
( $resource ); 
1023             if ( $opt_L ? !$is_match : $is_match ) { 
1024                 App
::Ack
::print( $resource->name, $ors ); 
1027                 last RESOURCES 
if $only_first; 
1028                 last RESOURCES 
if defined($opt_m) && $nmatches >= $opt_m; 
1032             $nmatches += print_matches_in_resource
( $resource, $opt ); 
1033             if ( $nmatches && $only_first ) { 
1039     if ( $opt_count && !$opt_show_filename ) { 
1040         App
::Ack
::print( $total_count, "\n" ); 
1043     close $App::Ack
::fh
; 
1044     App
::Ack
::exit_from_ack
( $nmatches ); 
1053 ack - grep-like text finder 
1057     ack [options] PATTERN [FILE...] 
1058     ack -f [options] [DIRECTORY...] 
1062 ack is designed as an alternative to F<grep> for programmers. 
1064 ack searches the named input files or directories for lines containing a 
1065 match to the given PATTERN.  By default, ack prints the matching lines. 
1066 If no FILE or DIRECTORY is given, the current directory will be searched. 
1068 PATTERN is a Perl regular expression.  Perl regular expressions 
1069 are commonly found in other programming languages, but for the particulars 
1070 of their behavior, please consult 
1071 L<http://perldoc.perl.org/perlreref.html|perlreref>.  If you don't know 
1072 how to use regular expression but are interested in learning, you may 
1073 consult L<http://perldoc.perl.org/perlretut.html|perlretut>.  If you do not 
1074 need or want ack to use regular expressions, please see the 
1075 C<-Q>/C<--literal> option. 
1077 Ack can also list files that would be searched, without actually 
1078 searching them, to let you take advantage of ack's file-type filtering 
1081 =head1 FILE SELECTION 
1083 If files are not specified for searching, either on the command 
1084 line or piped in with the C<-x> option, I<ack> delves into 
1085 subdirectories selecting files for searching. 
1087 I<ack> is intelligent about the files it searches.  It knows about 
1088 certain file types, based on both the extension on the file and, 
1089 in some cases, the contents of the file.  These selections can be 
1090 made with the B<--type> option. 
1092 With no file selection, I<ack> searches through regular files that 
1093 are not explicitly excluded by B<--ignore-dir> and B<--ignore-file> 
1094 options, either present in F<ackrc> files or on the command line. 
1096 The default options for I<ack> ignore certain files and directories.  These 
1101 =item * Backup files: Files matching F<#*#> or ending with F<~>. 
1103 =item * Coredumps: Files matching F<core.\d+> 
1105 =item * Version control directories like F<.svn> and F<.git>. 
1109 Run I<ack> with the C<--dump> option to see what settings are set. 
1111 However, I<ack> always searches the files given on the command line, 
1112 no matter what type.  If you tell I<ack> to search in a coredump, 
1113 it will search in a coredump. 
1115 =head1 DIRECTORY SELECTION 
1117 I<ack> descends through the directory tree of the starting directories 
1118 specified.  If no directories are specified, the current working directory is 
1119 used.  However, it will ignore the shadow directories used by 
1120 many version control systems, and the build directories used by the 
1121 Perl MakeMaker system.  You may add or remove a directory from this 
1122 list with the B<--[no]ignore-dir> option. The option may be repeated 
1123 to add/remove multiple directories from the ignore list. 
1125 For a complete list of directories that do not get searched, run 
1128 =head1 WHEN TO USE GREP 
1130 I<ack> trumps I<grep> as an everyday tool 99% of the time, but don't 
1131 throw I<grep> away, because there are times you'll still need it. 
1133 E.g., searching through huge files looking for regexes that can be 
1134 expressed with I<grep> syntax should be quicker with I<grep>. 
1136 If your script or parent program uses I<grep> C<--quiet> or C<--silent> 
1137 or needs exit 2 on IO error, use I<grep>. 
1145 Specifies an ackrc file to load after all others; see L</"ACKRC LOCATION SEMANTICS">. 
1147 =item B<-A I<NUM>>, B<--after-context=I<NUM>> 
1149 Print I<NUM> lines of trailing context after matching lines. 
1151 =item B<-B I<NUM>>, B<--before-context=I<NUM>> 
1153 Print I<NUM> lines of leading context before matching lines. 
1155 =item B<--[no]break> 
1157 Print a break between results from different files. On by default 
1158 when used interactively. 
1160 =item B<-C [I<NUM>]>, B<--context[=I<NUM>]> 
1162 Print I<NUM> lines (default 2) of context around matching lines. 
1163 You can specify zero lines of context to override another context 
1164 specified in an ackrc. 
1166 =item B<-c>, B<--count> 
1168 Suppress normal output; instead print a count of matching lines for 
1169 each input file.  If B<-l> is in effect, it will only show the 
1170 number of lines for each file that has lines matching.  Without 
1171 B<-l>, some line counts may be zeroes. 
1173 If combined with B<-h> (B<--no-filename>) ack outputs only one total 
1176 =item B<--[no]color>, B<--[no]colour> 
1178 B<--color> highlights the matching text.  B<--nocolor> suppresses 
1179 the color.  This is on by default unless the output is redirected. 
1181 On Windows, this option is off by default unless the 
1182 L<Win32::Console::ANSI> module is installed or the C<ACK_PAGER_COLOR> 
1183 environment variable is used. 
1185 =item B<--color-filename=I<color>> 
1187 Sets the color to be used for filenames. 
1189 =item B<--color-match=I<color>> 
1191 Sets the color to be used for matches. 
1193 =item B<--color-lineno=I<color>> 
1195 Sets the color to be used for line numbers. 
1197 =item B<--[no]column> 
1199 Show the column number of the first match.  This is helpful for 
1200 editors that can place your cursor at a given position. 
1202 =item B<--create-ackrc> 
1204 Dumps the default ack options to standard output.  This is useful for 
1205 when you want to customize the defaults. 
1209 Writes the list of options loaded and where they came from to standard 
1210 output.  Handy for debugging. 
1214 B<--noenv> disables all environment processing. No F<.ackrc> is 
1215 read and all environment variables are ignored. By default, F<ack> 
1216 considers F<.ackrc> and settings in the environment. 
1220 B<--flush> flushes output immediately.  This is off by default 
1221 unless ack is running interactively (when output goes to a pipe or 
1226 Only print the files that would be searched, without actually doing 
1227 any searching.  PATTERN must not be specified, or it will be taken 
1228 as a path to search. 
1230 =item B<--files-from=I<FILE>> 
1232 The list of files to be searched is specified in I<FILE>.  The list of 
1233 files are separated by newlines.  If I<FILE> is C<->, the list is loaded 
1234 from standard input. 
1236 =item B<--[no]filter> 
1238 Forces ack to act as if it were receiving input via a pipe. 
1240 =item B<--[no]follow> 
1242 Follow or don't follow symlinks, other than whatever starting files 
1243 or directories were specified on the command line. 
1245 This is off by default. 
1247 =item B<-g I<PATTERN>> 
1249 Print searchable files where the relative path + filename matches 
1256 is exactly the same as 
1260 This means that just as ack will not search, for example, F<.jpg> 
1261 files, C<-g> will not list F<.jpg> files either.  ack is not intended 
1262 to be a general-purpose file finder. 
1264 Note also that if you have C<-i> in your .ackrc that the filenames 
1265 to be matched will be case-insensitive as well. 
1267 This option can be combined with B<--color> to make it easier to 
1270 =item B<--[no]group> 
1272 B<--group> groups matches by file name.  This is the default 
1273 when used interactively. 
1275 B<--nogroup> prints one result per line, like grep.  This is the 
1276 default when output is redirected. 
1278 =item B<-H>, B<--with-filename> 
1280 Print the filename for each match. This is the default unless searching 
1281 a single explicitly specified file. 
1283 =item B<-h>, B<--no-filename> 
1285 Suppress the prefixing of filenames on output when multiple files are 
1288 =item B<--[no]heading> 
1290 Print a filename heading above each file's results.  This is the default 
1291 when used interactively. 
1293 =item B<--help>, B<-?> 
1295 Print a short help statement. 
1297 =item B<--help-types>, B<--help=types> 
1299 Print all known types. 
1301 =item B<-i>, B<--ignore-case> 
1303 Ignore case distinctions in PATTERN 
1305 =item B<--ignore-ack-defaults> 
1307 Tells ack to completely ignore the default definitions provided with ack. 
1308 This is useful in combination with B<--create-ackrc> if you I<really> want 
1311 =item B<--[no]ignore-dir=I<DIRNAME>>, B<--[no]ignore-directory=I<DIRNAME>> 
1313 Ignore directory (as CVS, .svn, etc are ignored). May be used 
1314 multiple times to ignore multiple directories. For example, mason 
1315 users may wish to include B<--ignore-dir=data>. The B<--noignore-dir> 
1316 option allows users to search directories which would normally be 
1317 ignored (perhaps to research the contents of F<.svn/props> directories). 
1319 The I<DIRNAME> must always be a simple directory name. Nested 
1320 directories like F<foo/bar> are NOT supported. You would need to 
1321 specify B<--ignore-dir=foo> and then no files from any foo directory 
1322 are taken into account by ack unless given explicitly on the command 
1325 =item B<--ignore-file=I<FILTERTYPE:FILTERARGS>> 
1327 Ignore files matching I<FILTERTYPE:FILTERARGS>.  The filters are specified 
1328 identically to file type filters as seen in L</"Defining your own types">. 
1330 =item B<-k>, B<--known-types> 
1332 Limit selected files to those with types that ack knows about.  This is 
1333 equivalent to the default behavior found in ack 1. 
1335 =item B<--lines=I<NUM>> 
1337 Only print line I<NUM> of each file. Multiple lines can be given with multiple 
1338 B<--lines> options or as a comma separated list (B<--lines=3,5,7>). B<--lines=4-7> 
1339 also works. The lines are always output in ascending order, no matter the 
1340 order given on the command line. 
1342 =item B<-l>, B<--files-with-matches> 
1344 Only print the filenames of matching files, instead of the matching text. 
1346 =item B<-L>, B<--files-without-matches> 
1348 Only print the filenames of files that do I<NOT> match. 
1350 =item B<--match I<PATTERN>> 
1352 Specify the I<PATTERN> explicitly. This is helpful if you don't want to put the 
1353 regex as your first argument, e.g. when executing multiple searches over the 
1356     # search for foo and bar in given files 
1357     ack file1 t/file* --match foo 
1358     ack file1 t/file* --match bar 
1360 =item B<-m=I<NUM>>, B<--max-count=I<NUM>> 
1362 Stop reading a file after I<NUM> matches. 
1366 Print this manual page. 
1368 =item B<-n>, B<--no-recurse> 
1370 No descending into subdirectories. 
1374 Show only the part of each line matching PATTERN (turns off text 
1377 =item B<--output=I<expr>> 
1379 Output the evaluation of I<expr> for each line (turns off text 
1381 If PATTERN matches more than once then a line is output for each non-overlapping match. 
1382 For more information please see the section L</"Examples of F<--output>">. 
1384 =item B<--pager=I<program>>, B<--nopager> 
1386 B<--pager> directs ack's output through I<program>.  This can also be specified 
1387 via the C<ACK_PAGER> and C<ACK_PAGER_COLOR> environment variables. 
1389 Using --pager does not suppress grouping and coloring like piping 
1390 output on the command-line does. 
1392 B<--nopager> cancels any setting in ~/.ackrc, C<ACK_PAGER> or C<ACK_PAGER_COLOR>. 
1393 No output will be sent through a pager. 
1397 Prints all lines, whether or not they match the expression.  Highlighting 
1398 will still work, though, so it can be used to highlight matches while 
1399 still seeing the entire file, as in: 
1401     # Watch a log file, and highlight a certain IP address 
1402     $ tail -f ~/access.log | ack --passthru 123.45.67.89 
1406 Only works in conjunction with -f, -g, -l or -c (filename output). The filenames 
1407 are output separated with a null byte instead of the usual newline. This is 
1408 helpful when dealing with filenames that contain whitespace, e.g. 
1410     # remove all files of type html 
1411     ack -f --html --print0 | xargs -0 rm -f 
1413 =item B<-Q>, B<--literal> 
1415 Quote all metacharacters in PATTERN, it is treated as a literal. 
1417 =item B<-r>, B<-R>, B<--recurse> 
1419 Recurse into sub-directories. This is the default and just here for 
1420 compatibility with grep. You can also use it for turning B<--no-recurse> off. 
1424 Suppress error messages about nonexistent or unreadable files.  This is taken 
1427 =item B<--[no]smart-case>, B<--no-smart-case> 
1429 Ignore case in the search strings if PATTERN contains no uppercase 
1430 characters. This is similar to C<smartcase> in vim. This option is 
1431 off by default, and ignored if C<-i> is specified. 
1433 B<-i> always overrides this option. 
1435 =item B<--sort-files> 
1437 Sorts the found files lexicographically.  Use this if you want your file 
1438 listings to be deterministic between runs of I<ack>. 
1440 =item B<--show-types> 
1442 Outputs the filetypes that ack associates with each file. 
1444 Works with B<-f> and B<-g> options. 
1446 =item B<--type=[no]TYPE> 
1448 Specify the types of files to include or exclude from a search. 
1449 TYPE is a filetype, like I<perl> or I<xml>.  B<--type=perl> can 
1450 also be specified as B<--perl>, and B<--type=noperl> can be done 
1453 If a file is of both type "foo" and "bar", specifying --foo and 
1454 --nobar will exclude the file, because an exclusion takes precedence 
1457 Type specifications can be repeated and are ORed together. 
1459 See I<ack --help=types> for a list of valid types. 
1461 =item B<--type-add I<TYPE>:I<FILTER>:I<FILTERARGS>> 
1463 Files with the given FILTERARGS applied to the given FILTER 
1464 are recognized as being of (the existing) type TYPE. 
1465 See also L</"Defining your own types">. 
1468 =item B<--type-set I<TYPE>:I<FILTER>:I<FILTERARGS>> 
1470 Files with the given FILTERARGS applied to the given FILTER are recognized as 
1471 being of type TYPE. This replaces an existing definition for type TYPE.  See 
1472 also L</"Defining your own types">. 
1474 =item B<--type-del I<TYPE>> 
1476 The filters associated with TYPE are removed from Ack, and are no longer considered 
1479 =item B<-v>, B<--invert-match> 
1481 Invert match: select non-matching lines 
1485 Display version and copyright information. 
1487 =item B<-w>, B<--word-regexp> 
1489 =item B<-w>, B<--word-regexp> 
1491 Turn on "words mode".  This sometimes matches a whole word, but the 
1492 semantics is quite subtle.  If the passed regexp begins with a word 
1493 character, then a word boundary is required before the match.  If the 
1494 passed regexp ends with a word character, or with a word character 
1495 followed by newline, then a word boundary is required after the match. 
1497 Thus, for example, B<-w> with the regular expression C<ox> will not 
1498 match the strings C<box> or C<oxen>.  However, if the regular 
1499 expression is C<(ox|ass)> then it will match those strings.  Because 
1500 the regular expression's first character is C<(>, the B<-w> flag has 
1501 no effect at the start, and because the last character is C<)>, it has 
1502 no effect at the end. 
1504 Force PATTERN to match only whole words.  The PATTERN is wrapped with 
1505 C<\b> metacharacters. 
1509 An abbreviation for B<--files-from=->; the list of files to search are read 
1510 from standard input, with one line per file. 
1514 Stops after reporting first match of any kind.  This is different 
1515 from B<--max-count=1> or B<-m1>, where only one match per file is 
1516 shown.  Also, B<-1> works with B<-f> and B<-g>, where B<-m> does 
1521 Display the all-important Bill The Cat logo.  Note that the exact 
1522 spelling of B<--thpppppt> is not important.  It's checked against 
1523 a regular expression. 
1527 Check with the admiral for traps. 
1531 Chocolate, Chocolate, Chocolate! 
1535 =head1 THE .ackrc FILE 
1537 The F<.ackrc> file contains command-line options that are prepended 
1538 to the command line before processing.  Multiple options may live 
1539 on multiple lines.  Lines beginning with a # are ignored.  A F<.ackrc> 
1540 might look like this: 
1542     # Always sort the files 
1545     # Always color, even if piping to another program 
1548     # Use "less -r" as my pager 
1551 Note that arguments with spaces in them do not need to be quoted, 
1552 as they are not interpreted by the shell. Basically, each I<line> 
1553 in the F<.ackrc> file is interpreted as one element of C<@ARGV>. 
1555 F<ack> looks in several locations for F<.ackrc> files; the searching 
1556 process is detailed in L</"ACKRC LOCATION SEMANTICS">.  These 
1557 files are not considered if B<--noenv> is specified on the command line. 
1559 =head1 Defining your own types 
1561 ack allows you to define your own types in addition to the predefined 
1562 types. This is done with command line options that are best put into 
1563 an F<.ackrc> file - then you do not have to define your types over and 
1564 over again. In the following examples the options will always be shown 
1565 on one command line so that they can be easily copy & pasted. 
1567 File types can be specified both with the the I<--type=xxx> option, 
1568 or the file type as an option itself.  For example, if you create 
1569 a filetype of "cobol", you can specify I<--type=cobol> or simply 
1570 I<--cobol>.  File types must be at least two characters long.  This 
1571 is why the C language is I<--cc> and the R language is I<--rr>. 
1573 I<ack --perl foo> searches for foo in all perl files. I<ack --help=types> 
1574 tells you, that perl files are files ending 
1575 in .pl, .pm, .pod or .t. So what if you would like to include .xs 
1576 files as well when searching for --perl files? I<ack --type-add perl:ext:xs --perl foo> 
1577 does this for you. B<--type-add> appends 
1578 additional extensions to an existing type. 
1580 If you want to define a new type, or completely redefine an existing 
1581 type, then use B<--type-set>. I<ack --type-set eiffel:ext:e,eiffel> defines 
1582 the type I<eiffel> to include files with 
1583 the extensions .e or .eiffel. So to search for all eiffel files 
1584 containing the word Bertrand use I<ack --type-set eiffel:ext:e,eiffel --eiffel Bertrand>. 
1585 As usual, you can also write B<--type=eiffel> 
1586 instead of B<--eiffel>. Negation also works, so B<--noeiffel> excludes 
1587 all eiffel files from a search. Redefining also works: I<ack --type-set cc:ext:c,h> 
1588 and I<.xs> files no longer belong to the type I<cc>. 
1590 When defining your own types in the F<.ackrc> file you have to use 
1593   --type-set=eiffel:ext:e,eiffel 
1595 or writing on separate lines 
1600 The following does B<NOT> work in the F<.ackrc> file: 
1602   --type-set eiffel:ext:e,eiffel 
1604 In order to see all currently defined types, use I<--help-types>, e.g. 
1605 I<ack --type-set backup:ext:bak --type-add perl:ext:perl --help-types> 
1607 In addition to filtering based on extension (like ack 1.x allowed), ack 2 
1608 offers additional filter types.  The generic syntax is 
1609 I<--type-set TYPE:FILTER:FILTERARGS>; I<FILTERARGS> depends on the value 
1614 =item is:I<FILENAME> 
1616 I<is> filters match the target filename exactly.  It takes exactly one 
1617 argument, which is the name of the file to match. 
1621     --type-set make:is:Makefile 
1623 =item ext:I<EXTENSION>[,I<EXTENSION2>[,...]] 
1625 I<ext> filters match the extension of the target file against a list 
1626 of extensions.  No leading dot is needed for the extensions. 
1630     --type-set perl:ext:pl,pm,t 
1632 =item match:I<PATTERN> 
1634 I<match> filters match the target filename against a regular expression. 
1635 The regular expression is made case insensitive for the search. 
1639     --type-set make:match:/(gnu)?makefile/ 
1641 =item firstlinematch:I<PATTERN> 
1643 I<firstlinematch> matches the first line of the target file against a 
1644 regular expression.  Like I<match>, the regular expression is made 
1649     --type-add perl:firstlinematch:/perl/ 
1653 More filter types may be made available in the future. 
1655 =head1 ENVIRONMENT VARIABLES 
1657 For commonly-used ack options, environment variables can make life 
1658 much easier.  These variables are ignored if B<--noenv> is specified 
1659 on the command line. 
1665 Specifies the location of the user's F<.ackrc> file.  If this file doesn't 
1666 exist, F<ack> looks in the default location. 
1670 This variable specifies default options to be placed in front of 
1671 any explicit options on the command line. 
1673 =item ACK_COLOR_FILENAME 
1675 Specifies the color of the filename when it's printed in B<--group> 
1676 mode.  By default, it's "bold green". 
1678 The recognized attributes are clear, reset, dark, bold, underline, 
1679 underscore, blink, reverse, concealed black, red, green, yellow, 
1680 blue, magenta, on_black, on_red, on_green, on_yellow, on_blue, 
1681 on_magenta, on_cyan, and on_white.  Case is not significant. 
1682 Underline and underscore are equivalent, as are clear and reset. 
1683 The color alone sets the foreground color, and on_color sets the 
1686 This option can also be set with B<--color-filename>. 
1688 =item ACK_COLOR_MATCH 
1690 Specifies the color of the matching text when printed in B<--color> 
1691 mode.  By default, it's "black on_yellow". 
1693 This option can also be set with B<--color-match>. 
1695 See B<ACK_COLOR_FILENAME> for the color specifications. 
1697 =item ACK_COLOR_LINENO 
1699 Specifies the color of the line number when printed in B<--color> 
1700 mode.  By default, it's "bold yellow". 
1702 This option can also be set with B<--color-lineno>. 
1704 See B<ACK_COLOR_FILENAME> for the color specifications. 
1708 Specifies a pager program, such as C<more>, C<less> or C<most>, to which 
1709 ack will send its output. 
1711 Using C<ACK_PAGER> does not suppress grouping and coloring like 
1712 piping output on the command-line does, except that on Windows 
1713 ack will assume that C<ACK_PAGER> does not support color. 
1715 C<ACK_PAGER_COLOR> overrides C<ACK_PAGER> if both are specified. 
1717 =item ACK_PAGER_COLOR 
1719 Specifies a pager program that understands ANSI color sequences. 
1720 Using C<ACK_PAGER_COLOR> does not suppress grouping and coloring 
1721 like piping output on the command-line does. 
1723 If you are not on Windows, you never need to use C<ACK_PAGER_COLOR>. 
1727 =head1 AVAILABLE COLORS 
1729 F<ack> uses the colors available in Perl's L<Term::ANSIColor> module, which 
1730 provides the following listed values. Note that case does not matter when using 
1733 =head2 Foreground colors 
1735     black  red  green  yellow  blue  magenta  cyan  white 
1737     bright_black  bright_red      bright_green  bright_yellow 
1738     bright_blue   bright_magenta  bright_cyan   bright_white 
1740 =head2 Background colors 
1742     on_black  on_red      on_green  on_yellow 
1743     on_blue   on_magenta  on_cyan   on_white 
1745     on_bright_black  on_bright_red      on_bright_green  on_bright_yellow 
1746     on_bright_blue   on_bright_magenta  on_bright_cyan   on_bright_white 
1748 =head1 ACK & OTHER TOOLS 
1750 =head2 Simple vim integration 
1752 F<ack> integrates easily with the Vim text editor. Set this in your 
1753 F<.vimrc> to use F<ack> instead of F<grep>: 
1757 That example uses C<-k> to search through only files of the types ack 
1758 knows about, but you may use other default flags. Now you can search 
1759 with F<ack> and easily step through the results in Vim: 
1761   :grep Dumper perllib 
1763 =head2 Editor integration 
1765 Many users have integrated ack into their preferred text editors. 
1766 For details and links, see L<https://beyondgrep.com/more-tools/>. 
1768 =head2 Shell and Return Code 
1770 For greater compatibility with I<grep>, I<ack> in normal use returns 
1771 shell return or exit code of 0 only if something is found and 1 if 
1774 (Shell exit code 1 is C<$?=256> in perl with C<system> or backticks.) 
1776 The I<grep> code 2 for errors is not used. 
1778 If C<-f> or C<-g> are specified, then 0 is returned if at least one 
1779 file is found.  If no files are found, then 1 is returned. 
1783 =head1 DEBUGGING ACK PROBLEMS 
1785 If ack gives you output you're not expecting, start with a few simple steps. 
1787 =head2 Use B<--noenv> 
1789 Your environment variables and F<.ackrc> may be doing things you're 
1790 not expecting, or forgotten you specified.  Use B<--noenv> to ignore 
1791 your environment and F<.ackrc>. 
1793 =head2 Use B<-f> to see what files have been selected 
1795 Ack's B<-f> was originally added as a debugging tool.  If ack is 
1796 not finding matches you think it should find, run F<ack -f> to see 
1797 what files have been selected.  You can also add the C<--show-types> 
1798 options to show the type of each file selected. 
1800 =head2 Use B<--dump> 
1802 This lists the ackrc files that are loaded and the options loaded 
1804 So for example you can find a list of directories that do not get searched or where filetypes are defined. 
1808 =head2 Use the F<.ackrc> file. 
1810 The F<.ackrc> is the place to put all your options you use most of 
1811 the time but don't want to remember.  Put all your --type-add and 
1812 --type-set definitions in it.  If you like --smart-case, set it 
1813 there, too.  I also set --sort-files there. 
1815 =head2 Use F<-f> for working with big codesets 
1817 Ack does more than search files.  C<ack -f --perl> will create a 
1818 list of all the Perl files in a tree, ideal for sending into F<xargs>. 
1821     # Change all "this" to "that" in all Perl files in a tree. 
1822     ack -f --perl | xargs perl -p -i -e's/this/that/g' 
1826     perl -p -i -e's/this/that/g' $(ack -f --perl) 
1828 =head2 Use F<-Q> when in doubt about metacharacters 
1830 If you're searching for something with a regular expression 
1831 metacharacter, most often a period in a filename or IP address, add 
1832 the -Q to avoid false positives without all the backslashing.  See 
1833 the following example for more... 
1835 =head2 Use ack to watch log files 
1837 Here's one I used the other day to find trouble spots for a website 
1838 visitor.  The user had a problem loading F<troublesome.gif>, so I 
1839 took the access log and scanned it with ack twice. 
1841     ack -Q aa.bb.cc.dd /path/to/access.log | ack -Q -B5 troublesome.gif 
1843 The first ack finds only the lines in the Apache log for the given 
1844 IP.  The second finds the match on my troublesome GIF, and shows 
1845 the previous five lines from the log in each case. 
1847 =head2 Examples of F<--output> 
1849 Following variables are useful in the expansion string: 
1855 The whole string matched by PATTERN. 
1857 =item C<$1>, C<$2>, ... 
1859 The contents of the 1st, 2nd ... bracketed group in PATTERN. 
1863 The string before the match. 
1867 The string after the match. 
1871 For more details and other variables see 
1872 L<http://perldoc.perl.org/perlvar.html#Variables-related-to-regular-expressions|perlvar>. 
1874 This example shows how to add text around a particular pattern 
1875 (in this case adding _ around word with "e") 
1877     ack2.pl "\w*e\w*" quick.txt --output="$`_$&_$'" 
1878     _The_ quick brown fox jumps over the lazy dog 
1879     The quick brown fox jumps _over_ the lazy dog 
1880     The quick brown fox jumps over _the_ lazy dog 
1882 This shows how to pick out particular parts of a match using ( ) within regular expression. 
1884   ack '=head(\d+)\s+(.*)' --output=' $1 : $2' 
1885   input file contains "=head1 NAME" 
1890 There are ack mailing lists and a Slack channel for ack.  See 
1891 L<https://beyondgrep.com/community/> for details. 
1895 =head2 Why isn't ack finding a match in (some file)? 
1897 First, take a look and see if ack is even looking at the file.  ack is 
1898 intelligent in what files it will search and which ones it won't, but 
1899 sometimes that can be surprising. 
1901 Use the C<-f> switch, with no regex, to see a list of files that ack 
1902 will search for you.  If your file doesn't show up in the list of files 
1903 that C<ack -f> shows, then ack never looks in it. 
1905 NOTE: If you're using an old ack before 2.0, it's probably because it's of 
1906 a type that ack doesn't recognize.  In ack 1.x, the searching behavior is 
1907 driven by filetype.  B<If ack 1.x doesn't know what kind of file it is, 
1908 ack ignores the file.>  You can use the C<--show-types> switch to show 
1909 which type ack thinks each file is. 
1911 =head2 Wouldn't it be great if F<ack> did search & replace? 
1913 No, ack will always be read-only.  Perl has a perfectly good way 
1914 to do search & replace in files, using the C<-i>, C<-p> and C<-n> 
1917 You can certainly use ack to select your files to update.  For 
1918 example, to change all "foo" to "bar" in all PHP files, you can do 
1919 this from the Unix shell: 
1921     $ perl -i -p -e's/foo/bar/g' $(ack -f --php) 
1923 =head2 Can I make ack recognize F<.xyz> files? 
1925 Yes!  Please see L</"Defining your own types">.  If you think 
1926 that F<ack> should recognize a type by default, please see 
1929 =head2 There's already a program/package called ack. 
1933 =head2 Why is it called ack if it's called ack-grep? 
1935 The name of the program is "ack".  Some packagers have called it 
1936 "ack-grep" when creating packages because there's already a package 
1937 out there called "ack" that has nothing to do with this ack. 
1939 I suggest you make a symlink named F<ack> that points to F<ack-grep> 
1940 because one of the crucial benefits of ack is having a name that's 
1941 so short and simple to type. 
1943 To do that, run this with F<sudo> or as root: 
1945    ln -s /usr/bin/ack-grep /usr/bin/ack 
1947 Alternatively, you could use a shell alias: 
1955 =head2 What does F<ack> mean? 
1957 Nothing.  I wanted a name that was easy to type and that you could 
1958 pronounce as a single syllable. 
1960 =head2 Can I do multi-line regexes? 
1962 No, ack does not support regexes that match multiple lines.  Doing 
1963 so would require reading in the entire file at a time. 
1965 If you want to see lines near your match, use the C<--A>, C<--B> 
1966 and C<--C> switches for displaying context. 
1968 =head2 Why is ack telling me I have an invalid option when searching for C<+foo>? 
1970 ack treats command line options beginning with C<+> or C<-> as options; if you 
1971 would like to search for these, you may prefix your search term with C<--> or 
1972 use the C<--match> option.  (However, don't forget that C<+> is a regular 
1973 expression metacharacter!) 
1975 =head2 Why does C<"ack '.{40000,}'"> fail?  Isn't that a valid regex? 
1977 The Perl language limits the repetition quantifier to 32K.  You 
1978 can search for C<.{32767}> but not C<.{32768}>. 
1980 =head2 Ack does "X" and shouldn't, should it? 
1982 We try to remain as close to grep's behavior as possible, so when in doubt, 
1983 see what grep does!  If there's a mismatch in functionality there, please 
1984 bring it up on the ack-users mailing list. 
1986 =head1 ACKRC LOCATION SEMANTICS 
1988 Ack can load its configuration from many sources.  The following list 
1989 specifies the sources Ack looks for configuration files; each one 
1990 that is found is loaded in the order specified here, and 
1991 each one overrides options set in any of the sources preceding 
1992 it.  (For example, if I set --sort-files in my user ackrc, and 
1993 --nosort-files on the command line, the command line takes 
2000 Defaults are loaded from App::Ack::ConfigDefaults.  This can be omitted 
2001 using C<--ignore-ack-defaults>. 
2003 =item * Global ackrc 
2005 Options are then loaded from the global ackrc.  This is located at 
2006 C</etc/ackrc> on Unix-like systems. 
2008 Under Windows XP and earlier, the global ackrc is at 
2009 C<C:\Documents and Settings\All Users\Application Data\ackrc> 
2011 Under Windows Vista/7, the global ackrc is at 
2012 C<C:\ProgramData\ackrc> 
2014 The C<--noenv> option prevents all ackrc files from being loaded. 
2018 Options are then loaded from the user's ackrc.  This is located at 
2019 C<$HOME/.ackrc> on Unix-like systems. 
2021 Under Windows XP and earlier, the user's ackrc is at 
2022 C<C:\Documents and Settings\$USER\Application Data\ackrc>. 
2024 Under Windows Vista/7, the user's ackrc is at 
2025 C<C:\Users\$USER\AppData\Roaming\ackrc>. 
2027 If you want to load a different user-level ackrc, it may be specified 
2028 with the C<$ACKRC> environment variable. 
2030 The C<--noenv> option prevents all ackrc files from being loaded. 
2032 =item * Project ackrc 
2034 Options are then loaded from the project ackrc.  The project ackrc is 
2035 the first ackrc file with the name C<.ackrc> or C<_ackrc>, first searching 
2036 in the current directory, then the parent directory, then the grandparent 
2037 directory, etc.  This can be omitted using C<--noenv>. 
2041 The C<--ackrc> option may be included on the command line to specify an 
2042 ackrc file that can override all others.  It is consulted even if C<--noenv> 
2047 Options are then loaded from the environment variable C<ACK_OPTIONS>.  This can 
2048 be omitted using C<--noenv>. 
2050 =item * Command line 
2052 Options are then loaded from the command line. 
2056 =head1 DIFFERENCES BETWEEN ACK 1.X AND ACK 2.X 
2058 A lot of changes were made for ack 2; here is a list of them. 
2060 =head2 GENERAL CHANGES 
2066 When no selectors are specified, ack 1.x only searches through files that 
2067 it can map to a file type.  ack 2.x, by contrast, will search through 
2068 every regular, non-binary file that is not explicitly ignored via 
2069 B<--ignore-file> or B<--ignore-dir>.  This is similar to the behavior of the 
2070 B<-a/--all> option in ack 1.x. 
2074 A more flexible filter system has been added, so that more powerful file types 
2075 may be created by the user.  For details, please consult 
2076 L</"Defining your own types">. 
2080 ack now loads multiple ackrc files; see L</"ACKRC LOCATION SEMANTICS"> for 
2085 ack's default filter definitions aren't special; you may tell ack to 
2086 completely disregard them if you don't like them. 
2090 =head2 REMOVED OPTIONS 
2096 Because of the change in default search behavior, the B<-a/--all> and 
2097 B<-u/--unrestricted> options have been removed.  In addition, the 
2098 B<-k/--known-types> option was added to cause ack to behave with 
2099 the default search behavior of ack 1.x. 
2103 The B<-G> option has been removed.  Two regular expressions on the 
2104 command line was considered too confusing; to simulate B<-G>'s functionality, 
2105 you may use the new B<-x> option to pipe filenames from one invocation of 
2110 The B<--binary> option has been removed. 
2114 The B<--skipped> option has been removed. 
2118 The B<--text> option has been removed. 
2122 The B<--invert-file-match> option has been removed.  Instead, you may 
2123 use B<-v> with B<-g>. 
2127 =head2 CHANGED OPTIONS 
2133 The options that modify the regular expression's behavior (B<-i>, B<-w>, 
2134 B<-Q>, and B<-v>) may now be used with B<-g>. 
2138 =head2 ADDED OPTIONS 
2144 B<--files-from> was added so that a user may submit a list of filenames as 
2145 a list of files to search. 
2149 B<-x> was added to tell ack to accept a list of filenames via standard input; 
2150 this list is the list of filenames that will be used for the search. 
2154 B<-s> was added to tell ack to suppress error messages about non-existent or 
2159 B<--ignore-directory> and B<--noignore-directory> were added as aliases for 
2160 B<--ignore-dir> and B<--noignore-dir> respectively. 
2164 B<--ignore-file> was added so that users may specify patterns of files to 
2165 ignore (ex. /.*~$/). 
2169 B<--dump> was added to allow users to easily find out which options are 
2174 B<--create-ackrc> was added so that users may create custom ackrc files based 
2175 on the default settings loaded by ack, and so that users may easily view those 
2180 B<--type-del> was added to selectively remove file type definitions. 
2184 B<--ignore-ack-defaults> was added so that users may ignore ack's default 
2185 options in favor of their own. 
2189 B<--bar> was added so ack users may consult Admiral Ackbar. 
2195 Andy Lester, C<< <andy at petdance.com> >> 
2199 Please report any bugs or feature requests to the issues list at 
2200 Github: L<https://github.com/beyondgrep/ack2/issues> 
2204 All enhancement requests MUST first be posted to the ack-users 
2205 mailing list at L<http://groups.google.com/group/ack-users>.  I 
2206 will not consider a request without it first getting seen by other 
2207 ack users.  This includes requests for new filetypes. 
2209 There is a list of enhancements I want to make to F<ack> in the ack 
2210 issues list at Github: L<https://github.com/beyondgrep/ack2/issues> 
2212 Patches are always welcome, but patches with tests get the most 
2217 Support for and information about F<ack> can be found at: 
2221 =item * The ack homepage 
2223 L<https://beyondgrep.com/> 
2225 =item * The ack-users mailing list 
2227 L<http://groups.google.com/group/ack-users> 
2229 =item * The ack issues list at Github 
2231 L<https://github.com/beyondgrep/ack2/issues> 
2233 =item * AnnoCPAN: Annotated CPAN documentation 
2235 L<http://annocpan.org/dist/ack> 
2237 =item * CPAN Ratings 
2239 L<http://cpanratings.perl.org/d/ack> 
2243 L<http://search.cpan.org/dist/ack> 
2247 L<http://metacpan.org/release/ack> 
2249 =item * Git source repository 
2251 L<https://github.com/beyondgrep/ack2> 
2255 =head1 ACKNOWLEDGEMENTS 
2257 How appropriate to have I<ack>nowledgements! 
2259 Thanks to everyone who has contributed to ack in any way, including 
2272 SE<eacute>bastien FeugE<egrave>re, 
2279 RaE<uacute>l GundE<iacute>n, 
2285 RaE<aacute>l GundE<aacute>n, 
2321 Eric Van Dewoestine, 
2330 Christopher J. Madsen, 
2342 GE<aacute>bor SzabE<oacute>, 
2345 E<AElig>var ArnfjE<ouml>rE<eth> Bjarmason, 
2349 Mark Leighton Fisher, 
2355 Nilson Santos F. Jr, 
2360 Ask BjE<oslash>rn Hansen, 
2364 Slaven ReziE<0x107>, 
2374 =head1 COPYRIGHT & LICENSE 
2376 Copyright 2005-2017 Andy Lester. 
2378 This program is free software; you can redistribute it and/or modify 
2379 it under the terms of the Artistic License v2.0. 
2381 See http://www.perlfoundation.org/artistic_license_2_0 or the LICENSE.md 
2382 file that comes with the ack distribution. 
2395     $COPYRIGHT = 'Copyright 2005-2017 Andy Lester.'; 
2410 our $is_filter_mode; 
2411 our $output_to_pipe; 
2417 use File
::Spec 
1.00015 (); 
2420     # These have to be checked before any filehandle diddling. 
2421     $output_to_pipe  = not -t 
*STDOUT
; 
2422     $is_filter_mode = -p STDIN
; 
2424     $is_cygwin       = ($^O eq 'cygwin' || $^O eq 'msys'); 
2425     $is_windows      = ($^O eq 'MSWin32'); 
2426     $dir_sep_chars   = $is_windows ? quotemeta( '\\/' ) : quotemeta( File
::Spec-
>catfile( '', '' ) ); 
2431 sub remove_dir_sep 
{ 
2433     $path =~ s/[$dir_sep_chars]$//; 
2441     return CORE
::warn( _my_program
(), ': ', @_, "\n" ); 
2446     return CORE
::die( _my_program
(), ': ', @_, "\n" ); 
2450     require File
::Basename
; 
2451     return File
::Basename
::basename
( $0 ); 
2456 sub filetypes_supported 
{ 
2457     return keys %mappings; 
2461     my $y = q{_   /|,\\'!.x',=(www)=,   U   }; 
2462     $y =~ tr/,x!w/\nOo_/; 
2464     App
::Ack
::print( "$y ack $_[0]!\n" ); 
2472  3~!I#7#I"7#I!?!+!="+"="+!:! 
2473  2?#I!7!I!?#I!7!I"+"=%+"=# 
2474  1?"+!?*+!=#~"=!+#?"="+! 
2475  0?"+!?"I"?&+!="~!=!~"=!+%="+" 
2476  /I!+!?)+!?!+!=$~!=!~!="+!="+"?!="?! 
2478  ,,!?%I"?(+$=$~!=#:"~$:!~! 
2479  ,I!?!I!?"I"?!+#?"+!?!+#="~$:!~!:!~!:!,!:!,":#~! 
2480  +I!?&+!="+!?#+$=!~":!~!:!~!:!,!:#,!:!,%:" 
2481  *+!I!?!+$=!+!=!+!?$+#=!~":!~":#,$:",#:!,!:! 
2482  *I!?"+!?!+!=$+!?#+#=#~":$,!:",!:!,&:" 
2483  )I!?$=!~!=#+"?!+!=!+!=!~!="~!:!~":!,'.!,%:!~! 
2484  (=!?"+!?!=!~$?"+!?!+!=#~"=",!="~$,$.",#.!:!=! 
2485  (I"+"="~"=!+&=!~"=!~!,!~!+!=!?!+!?!=!I!?!+"=!.",!.!,":! 
2486  %I$?!+!?!=%+!~!+#~!=!~#:#=!~!+!~!=#:!,%.!,!.!:" 
2487  $I!?!=!?!I!+!?"+!=!~!=!~!?!I!?!=!+!=!~#:",!~"=!~!:"~!=!:",&:" '-/ 
2488  $?!+!I!?"+"=!+"~!,!:"+#~#:#,"=!~"=!,!~!,!.",!:".!:! */! !I!t!'!s! !a! !g!r!e!p!!! !/! 
2489  $+"=!+!?!+"~!=!:!~!:"I!+!,!~!=!:!~!,!:!,$:!~".&:"~!,# (-/ 
2490  %~!=!~!=!:!.!+"~!:!,!.!,!~!=!:$.!,":!,!.!:!~!,!:!=!.#="~!,!:" ./! 
2491  %=!~!?!+"?"+!=!~",!.!:!?!~!.!:!,!:!,#.!,!:","~!:!=!~!=!:",!~! ./! 
2492  %+"~":!~!=#~!:!~!,!.!~!:",!~!=!~!.!:!,!.",!:!,":!=":!.!,!:!7! -/! 
2493  %~",!:".#:!=!:!,!:"+!:!~!:!.!,!~!,!.#,!.!,$:"~!,":"~!=! */! 
2494  &=!~!=#+!=!~",!.!:",#:#,!.",+:!,!.",!=!+!?! 
2495  &~!=!~!=!~!:"~#:",!.!,#~!:!.!+!,!.",$.",$.#,!+!I!?! 
2496  &~!="~!:!~":!~",!~!=!~":!,!:!~!,!:!,&.$,#."+!?!I!?!I! 
2497  &~!=!~!=!+!,!:!~!:!=!,!:!~&:$,!.!,".!,".!,#."~!+!?$I! 
2498  &~!=!~!="~!=!:!~":!,!~%:#,!:",!.!,#.",#I!7"I!?!+!?"I" 
2499  &+!I!7!:#~"=!~!:!,!:"~$.!=!.!,!~!,$.#,!~!7!I#?!+!?"I"7! 
2500  %7#?!+!~!:!=!~!=!~":!,!:"~":#.!,)7#I"?"I!7& 
2501  %7#I!=":!=!~!:"~$:"~!:#,!:!,!:!~!:#,!7#I!?#7) 
2502  $7$+!,!~!=#~!:!~!:!~$:#,!.!~!:!=!,":!7#I"?#7+=!?! 
2503  $7#I!~!,!~#=!~!:"~!:!,!:!,#:!=!~",":!7$I!?#I!7*+!=!+" 
2504  "I!7$I!,":!,!.!=":$,!:!,$:$7$I!+!?"I!7+?"I!7!I!7!,! 
2505  !,!7%I!:",!."~":!,&.!,!:!~!I!7$I!+!?"I!7,?!I!7',! 
2506  !7(,!.#~":!,%.!,!7%I!7!?#I"7,+!?!7* 
2507 7+:!,!~#,"=!7'I!?#I"7/+!7+ 
2508 77I!+!7!?!7!I"71+!7, 
2511     return _pic_decode
($x); 
2517  0|! "C!H!O!C!O!L!A!T!E!!! !|! 
2518  0|! "C!H!O!C!O!L!A!T!E!!! !|! 
2519  0|! "C!H!O!C!O!L!A!T!E!!! !|! 
2525  4.! $\! /M!~!.!8! +.!M# 4 
2526  0,!.! (\! .~!M!N! ,+!I!.!M!.! 3 
2527  /?!O!.!M!:! '\! .O!.! +~!Z!=!N!.! 4 
2528  ..! !D!Z!.!Z!.! '\! 9=!M".! 6 
2529  /.! !.!~!M".! '\! 8~! 9 
2531  4.! &:!M! !N"M# !M"N!M! #D!M&=! = 
2532  :M!7!M#:! !~!M!7!,!$!M!:! #.! !O!N!.!M!:!M# ; 
2533  8Z!M"~!N!$!D!.!N!?! !I!N!.! (?!M! !M!,!D!M".! 9 
2534  (?!Z!M!N!:! )=!M!O!8!.!M!+!M! !M!,! !O!M! +,!M!.!M!~!Z!N!M!:! &:!~! 0 
2535  &8!7!.!~!M"D!M!,! &M!?!=!8! !M!,!O! !M!+! !+!O!.!M! $M#~! !.!8!M!Z!.!M! !O!M"Z! %:!~!M!Z!M!Z!.! + 
2536  &:!M!7!,! *M!.!Z!M! !8"M!.!M!~! !.!M!.!=! #~!8!.!M! !7!M! "N!Z#I! !D!M!,!M!.! $."M!,! !M!.! * 
2537  2$!O! "N! !.!M!I! !7" "M! "+!O! !~!M! !d!O!.!7!I!M!.! !.!O!=!M!.! !M",!M!.! %.!$!O!D! + 
2538  1~!O! "M!+! !8!$! "M! "?!O! %Z!8!D!M!?!8!I!O!7!M! #M!.!M! "M",!M! 4 
2539  07!~! ".!8! !.!M! "I!+! !.!M! &Z!D!.!7!=!M! !:!.!M! #:!8"+! !.!+!8! !8! 3 
2540  /~!M! #N! !~!M!$! !.!M! !.!M" &~!M! "~!M!O! "D! $M! !8! "M!,!M!+!D!.! 1 
2541  #.! #?!M!N!.! #~!O! $M!.!7!$! "?" !?!~!M! '7!8!?!M!.!+!M"O! $?"$!D! !.!O! !$!7!I!.! 0 
2542  $,!M!:!O!?! ".! !?!=! $=!:!O! !M! "M! !M! !+!$! (.! +.!M! !M!.! !8! !+"Z!~! $:!M!$! !.! ' 
2543  #.!8!.!I!$! $7!I! %M" !=!M! !~!M!D! "7!I! .I!O! %?!=!,!D! !,!M! !D!~!8!~! %D!M! ( 
2544  #.!M"?! $=!O! %=!N! "8!.! !Z!M! #M!~! (M!:! #.!M" &O! !M!.! !?!,! !8!.!N!~! $8!N!M!,!.! % 
2545  *$!O! &M!,! "O! !.!M!.! #M! (~!M( &O!.! !7! "M! !.!M!.!M!,! #.!M! !M! & 
2546  )=!8!.! $.!M!O!.! "$!.!I!N! !I!M# (7!M(I! %D"Z!M! "=!I! "M! !M!:! #~!D! ' 
2547  )D! &8!N!:! ".!O! !M!="M! "M! (7!M) %." !M!D!."M!.! !$!=! !M!,! + 
2548  (M! &+!.!M! #Z!7!O!M!.!~!8! +,!M#D!?!M#D! #.!Z!M#,!Z!?! !~!N! "N!.! !M! + 
2549  'D!:! %$!D! !?! #M!Z! !8!.! !M"?!7!?!7! '+!I!D! !?!O!:!M!:! ":!M!:! !M!7".!M! "8!+! !:!D! !.!M! * 
2550  %.!O!:! $.!O!+! !D!.! #M! "M!.!+!N!I!Z! "7!M!N!M!N!?!I!7!Z!=!M'D"~! #M!.!8!$! !:! !.!M! "N!?! !,!O! ) 
2551  !.!?!M!:!M!I! %8!,! "M!.! #M! "N! !M!.! !M!.! !+!~! !.!M!.! ':!M! $M! $M!Z!$! !M!.! "D! "M! "?!M! ( 
2552  !7!8! !+!I! ".! "$!=! ":!$! "+! !M!.! !O! !M!I!M".! !=!~! ",!O! '=!M! $$!,! #N!:! ":!8!.! !D!~! !,!M!.! !:!M!.! & 
2553  !:!,!.! &Z" #D! !.!8!."M!.! !8!?!Z!M!.!M! #Z!~! !?!M!Z!.! %~!O!.!8!$!N!8!O!I!:!~! !+! #M!.! !.!M!.! !+!M! ".!~!M!+! $ 
2554  !.! 'D!I! #?!M!.!M!,! !.!Z! !.!8! #M&O!I!?! (~!I!M"." !M!Z!.! !M!N!.! "+!$!.! "M!.! !M!?!.! "8!M! $ 
2555  (O!8! $M! !M!.! ".!:! !+!=! #M! #.!M! !+" *$!M":!.! !M!~! "M!7! #M! #7!Z! "M"$!M!.! !.! # 
2556  '$!Z! #.!7!+!M! $.!,! !+!:! #N! #.!M!.!+!M! +D!M! #=!N! ":!O! #=!M! #Z!D! $M!I! % 
2557  $,! ".! $.!M" %$!.! !?!~! "+!7!." !.!M!,! !M! *,!N!M!.$M!?! "D!,! #M!.! #N! + 
2558  ,M!Z! &M! "I!,! "M! %I!M! !?!=!.! (Z!8!M! $:!M!.! !,!M! $D! #.!M!.! ) 
2559  +8!O! &.!8! "I!,! !~!M! &N!M! !M!D! '?!N!O!." $?!7! "?!~! #M!.! #I!D!.! ( 
2560  3M!,! "N!.! !D" &.!+!M!.! !M":!.":!M!7!M!D! 'M!.! "M!.! "M!,! $I! ) 
2561  3I! #M! "M!,! !:! &.!M" ".!,! !.!$!M!I! #.! !:! !.!M!?! "N!+! ".! / 
2562  1M!,! #.!M!8!M!=!.! +~!N"O!Z"~! *+!M!.! "M! 2 
2563  0.!M! &M!.! 8:! %.!M!Z! "M!=! *O!,! % 
2564  0?!$! &N! )." .,! %."M! ":!M!.! 0 
2565  0N!:! %?!O! #.! ..! &,! &.!D!,! "N!I! 0 
2567     return _pic_decode
($x); 
2571     my($compressed) = @_; 
2572     $compressed =~ s/(.)(.)/$1x(ord($2)-32)/eg; 
2573     App
::Ack
::print( $compressed ); 
2579     my $help_arg = shift || 0; 
2581     return show_help_types
() if $help_arg =~ /^types?/; 
2583     App
::Ack
::print( <<"END_OF_HELP" ); 
2584 Usage: ack [OPTION]... PATTERN [FILES OR DIRECTORIES] 
2586 Search for PATTERN in each source file in the tree from the current 
2587 directory on down.  If any files or directories are specified, then 
2588 only those files and directories are checked.  ack may also search 
2589 STDIN, but only if no file or directory arguments are specified, 
2590 or if one of them is "-". 
2592 Default switches may be specified in ACK_OPTIONS environment variable or 
2593 an .ackrc file. If you want no dependency on the environment, turn it 
2596 Example: ack -i select 
2599   -i, --ignore-case             Ignore case distinctions in PATTERN 
2600   --[no]smart-case              Ignore case distinctions in PATTERN, 
2601                                 only if PATTERN contains no upper case. 
2602                                 Ignored if -i is specified 
2603   -v, --invert-match            Invert match: select non-matching lines 
2604   -w, --word-regexp             Force PATTERN to match only whole words 
2605   -Q, --literal                 Quote all metacharacters; PATTERN is literal 
2608   --lines=NUM                   Only print line(s) NUM of each file 
2609   -l, --files-with-matches      Only print filenames containing matches 
2610   -L, --files-without-matches   Only print filenames with no matches 
2611   --output=expr                 Output the evaluation of expr for each line 
2612                                 (turns off text highlighting) 
2613   -o                            Show only the part of a line matching PATTERN 
2614                                 Same as --output='\$&' 
2615   --passthru                    Print all lines, whether matching or not 
2616   --match PATTERN               Specify PATTERN explicitly. 
2617   -m, --max-count=NUM           Stop searching in each file after NUM matches 
2618   -1                            Stop searching after one match of any kind 
2619   -H, --with-filename           Print the filename for each match (default: 
2620                                 on unless explicitly searching a single file) 
2621   -h, --no-filename             Suppress the prefixing filename on output 
2622   -c, --count                   Show number of lines matching per file 
2623   --[no]column                  Show the column number of the first match 
2625   -A NUM, --after-context=NUM   Print NUM lines of trailing context after 
2627   -B NUM, --before-context=NUM  Print NUM lines of leading context before 
2629   -C [NUM], --context[=NUM]     Print NUM lines (default 2) of output context. 
2631   --print0                      Print null byte as separator between filenames, 
2632                                 only works with -f, -g, -l, -L or -c. 
2634   -s                            Suppress error messages about nonexistent or 
2639   --pager=COMMAND               Pipes all ack output through COMMAND.  For 
2640                                 example, --pager="less -R".  Ignored if output 
2642   --nopager                     Do not send output through a pager.  Cancels 
2643                                 any setting in ~/.ackrc, ACK_PAGER or 
2645   --[no]heading                 Print a filename heading above each file's 
2646                                 results.  (default: on when used interactively) 
2647   --[no]break                   Print a break between results from different 
2648                                 files.  (default: on when used interactively) 
2649   --group                       Same as --heading --break 
2650   --nogroup                     Same as --noheading --nobreak 
2651   --[no]color                   Highlight the matching text (default: on unless 
2652                                 output is redirected, or on Windows) 
2653   --[no]colour                  Same as --[no]color 
2654   --color-filename=COLOR 
2656   --color-lineno=COLOR          Set the color for filenames, matches, and line 
2658   --flush                       Flush output immediately, even when ack is used 
2659                                 non-interactively (when output goes to a pipe or 
2664   -f                            Only print the files selected, without 
2665                                 searching.  The PATTERN must not be specified. 
2666   -g                            Same as -f, but only select files matching 
2668   --sort-files                  Sort the found files lexically. 
2669   --show-types                  Show which types each file has. 
2670   --files-from=FILE             Read the list of files to search from FILE. 
2671   -x                            Read the list of files to search from STDIN. 
2673 File inclusion/exclusion: 
2674   --[no]ignore-dir=name         Add/remove directory from list of ignored dirs 
2675   --[no]ignore-directory=name   Synonym for ignore-dir 
2676   --ignore-file=filter          Add filter for ignoring files 
2677   -r, -R, --recurse             Recurse into subdirectories (default: on) 
2678   -n, --no-recurse              No descending into subdirectories 
2679   --[no]follow                  Follow symlinks.  Default is off. 
2680   -k, --known-types             Include only files of types that ack recognizes. 
2682   --type=X                      Include only X files, where X is a recognized 
2684   --type=noX                    Exclude X files. 
2685                                 See "ack --help-types" for supported filetypes. 
2687 File type specification: 
2688   --type-set TYPE:FILTER:FILTERARGS 
2689                                 Files with the given FILTERARGS applied to the 
2690                                 given FILTER are recognized as being of type 
2691                                 TYPE. This replaces an existing definition for 
2693   --type-add TYPE:FILTER:FILTERARGS 
2694                                 Files with the given FILTERARGS applied to the 
2695                                 given FILTER are recognized as being type TYPE. 
2696   --type-del TYPE               Removes all filters associated with TYPE. 
2700   --[no]env                     Ignore environment variables and global ackrc 
2701                                 files.  --env is legal but redundant. 
2702   --ackrc=filename              Specify an ackrc file to use 
2703   --ignore-ack-defaults         Ignore default definitions included with ack. 
2704   --create-ackrc                Outputs a default ackrc for your customization 
2706   --help, -?                    This help 
2707   --help-types                  Display all known types 
2708   --dump                        Dump information on which options are loaded 
2710   --[no]filter                  Force ack to treat standard input as a pipe 
2711                                 (--filter) or tty (--nofilter) 
2713   --version                     Display version & copyright 
2714   --thpppt                      Bill the Cat 
2715   --bar                         The warning admiral 
2716   --cathy                       Chocolate! Chocolate! Chocolate! 
2718 Exit status is 0 if match, 1 if no match. 
2720 ack's home page is at https://beyondgrep.com/ 
2722 The full ack manual is available by running "ack --man". 
2724 This is version $VERSION of ack.  Run "ack --version" for full version info. 
2732 sub show_help_types 
{ 
2733     App
::Ack
::print( <<'END_OF_HELP' ); 
2734 Usage: ack [OPTION]... PATTERN [FILES OR DIRECTORIES] 
2736 The following is the list of filetypes supported by ack.  You can 
2737 specify a file type with the --type=TYPE format, or the --TYPE 
2738 format.  For example, both --type=perl and --perl work. 
2740 Note that some extensions may appear in multiple types.  For example, 
2741 .pod files are both Perl and Parrot. 
2745     my @types = filetypes_supported
(); 
2748         $maxlen = length if $maxlen < length; 
2750     for my $type ( sort @types ) { 
2751         next if $type =~ /^-/; # Stuff to not show 
2752         my $ext_list = $mappings{$type}; 
2754         if ( ref $ext_list ) { 
2755             $ext_list = join( '; ', map { $_->to_string } @{$ext_list} ); 
2757         App
::Ack
::print( sprintf( "    --[no]%-*.*s %s\n", $maxlen, $maxlen, $type, $ext_list ) ); 
2766     Pod
::Usage
::pod2usage
({ 
2767         -input   
=> $App::Ack
::orig_program_name
, 
2776 sub get_version_statement 
{ 
2779     my $copyright = get_copyright
(); 
2780     my $this_perl = $Config::Config
{perlpath
}; 
2782         my $ext = $Config::Config
{_exe
}; 
2783         $this_perl .= $ext unless $this_perl =~ m/$ext$/i; 
2785     my $ver = sprintf( '%vd', $^V ); 
2787     return <<"END_OF_VERSION"; 
2789 Running under Perl $ver at $this_perl 
2793 This program is free software.  You may modify or distribute it 
2794 under the terms of the Artistic License v2.0. 
2799 sub print_version_statement 
{ 
2800     App
::Ack
::print( get_version_statement
() ); 
2811 sub print                   { print {$fh} @_; return; } 
2812 sub print_blank_line        
{ App
::Ack
::print( "\n" ); return; } 
2813 sub print_filename          
{ App
::Ack
::print( $_[0], $_[1] ); return; } 
2816     my $command = shift; 
2818     return if App
::Ack
::output_to_pipe
(); 
2821     if ( not open( $pager, '|-', $command ) ) { 
2822         App
::Ack
::die( qq{Unable to pipe to pager "$command": $!} ); 
2830 sub output_to_pipe 
{ 
2831     return $output_to_pipe; 
2836     my $nmatches = shift; 
2838     my $rc = $nmatches ? 0 : 1; 
2844 1; # End of App::Ack 
2845 package App
::Ack
::Resource
; 
2856     my $filename = shift; 
2859         filename 
=> $filename, 
2864     if ( $self->{filename
} eq '-' ) { 
2865         $self->{fh
}     = *STDIN
; 
2866         $self->{opened
} = 1; 
2875     return $_[0]->{filename
}; 
2883     # XXX Definedness? Pre-populate the slot with an undef? 
2884     unless ( exists $self->{basename
} ) { 
2885         $self->{basename
} = (File
::Spec-
>splitpath($self->name))[2]; 
2888     return $self->{basename
}; 
2896     if ( !$self->{opened
} ) { 
2897         if ( open $self->{fh
}, '<', $self->{filename
} ) { 
2898             $self->{opened
} = 1; 
2901             $self->{fh
} = undef; 
2910 sub needs_line_scan 
{ 
2914     return 1 if $opt->{v
}; 
2916     my $size = -s 
$self->{fh
}; 
2920     elsif ( $size > 100_000 ) { 
2925     my $rc = sysread( $self->{fh
}, $buffer, $size ); 
2926     if ( !defined($rc) && $App::Ack
::report_bad_filenames 
) { 
2927         App
::Ack
::warn( "$self->{filename}: $!" ); 
2930     return 0 unless $rc && ( $rc == $size ); 
2932     return $buffer =~ /$opt->{regex}/m; 
2940     # Return if we haven't opened the file yet. 
2941     if ( !defined($self->{fh
}) ) { 
2945     if ( !seek( $self->{fh
}, 0, 0 ) && $App::Ack
::report_bad_filenames 
) { 
2946         App
::Ack
::warn( "$self->{filename}: $!" ); 
2957     # Return if we haven't opened the file yet. 
2958     if ( !defined($self->{fh
}) ) { 
2962     if ( !close($self->{fh
}) && $App::Ack
::report_bad_filenames 
) { 
2963         App
::Ack
::warn( $self->name() . ": $!" ); 
2966     $self->{opened
} = 0; 
2976     return __PACKAGE__-
>new($self->name); 
2984     if ( !exists $self->{firstliney
} ) { 
2985         my $fh = $self->open(); 
2987             if ( $App::Ack
::report_bad_filenames 
) { 
2988                 App
::Ack
::warn( $self->name . ': ' . $! ); 
2994         my $rc     = sysread( $fh, $buffer, 250 ); 
2995         unless($rc) { # XXX handle this better? 
2998         $buffer =~ s/[\r\n].*//s; 
2999         $self->{firstliney
} = $buffer; 
3005     return $self->{firstliney
}; 
3009 package App
::Ack
::Resources
; 
3013 use Errno 
qw(EACCES); 
3018 sub _generate_error_handler 
{ 
3021     if ( $opt->{dont_report_bad_filenames
} ) { 
3024             if ( $! == EACCES 
) { 
3027             App
::Ack
::warn( $msg ); 
3033             App
::Ack
::warn( $msg ); 
3044     my $self = bless {}, $class; 
3046     my $file_filter    = undef; 
3047     my $descend_filter = $opt->{descend_filter
}; 
3050         $descend_filter = sub { 
3056         File
::Next
::files
( { 
3057             file_filter     
=> $opt->{file_filter
}, 
3058             descend_filter  
=> $descend_filter, 
3059             error_handler   
=> _generate_error_handler
($opt), 
3060             warning_handler 
=> sub {}, 
3061             sort_files      
=> $opt->{sort_files
}, 
3062             follow_symlinks 
=> $opt->{follow
}, 
3075         File
::Next
::from_file
( { 
3076             error_handler   
=> _generate_error_handler
($opt), 
3077             warning_handler 
=> _generate_error_handler
($opt), 
3078             sort_files      
=> $opt->{sort_files
}, 
3079         }, $file ) or return undef; 
3086 # This is for reading input lines from STDIN, not the list of files from STDIN 
3091     my $self  = bless {}, $class; 
3093     my $has_been_called = 0; 
3095     $self->{iter
} = sub { 
3096         if ( !$has_been_called ) { 
3097             $has_been_called = 1; 
3109     my $file = $self->{iter
}->() or return; 
3111     return App
::Ack
::Resource-
>new( $file ); 
3115 package App
::Ack
::ConfigDefault
; 
3124     return split( /\n/, _options_block
() ); 
3129     return grep { /./ && !/^#/ } options
(); 
3133 sub _options_block 
{ 
3134     my $lines = <<'HERE'; 
3135 # This is the default ackrc for ack version ==VERSION==. 
3137 # There are four different ways to match 
3139 # is:  Match the filename exactly 
3141 # ext: Match the extension of the filename exactly 
3143 # match: Match the filename against a Perl regular expression 
3145 # firstlinematch: Match the first 250 characters of the first line 
3146 #   of text against a Perl regular expression.  This is only for 
3147 #   the --type-add option. 
3150 ### Directories to ignore 
3153 # http://bazaar.canonical.com/ 
3154 --ignore-directory=is:.bzr 
3157 # http://freecode.com/projects/codeville 
3158 --ignore-directory=is:.cdv 
3160 # Interface Builder (Xcode) 
3161 # http://en.wikipedia.org/wiki/Interface_Builder 
3162 --ignore-directory=is:~.dep 
3163 --ignore-directory=is:~.dot 
3164 --ignore-directory=is:~.nib 
3165 --ignore-directory=is:~.plst 
3168 # http://git-scm.com/ 
3169 --ignore-directory=is:.git 
3170 # When using submodules, .git is a file. 
3171 --ignore-file=is:.git 
3174 # http://mercurial.selenic.com/ 
3175 --ignore-directory=is:.hg 
3178 # http://directory.fsf.org/wiki/Quilt 
3179 --ignore-directory=is:.pc 
3182 # http://subversion.tigris.org/ 
3183 --ignore-directory=is:.svn 
3186 # http://www.monotone.ca/ 
3187 --ignore-directory=is:_MTN 
3190 # http://savannah.nongnu.org/projects/cvs 
3191 --ignore-directory=is:CVS 
3194 # http://www.gnu.org/software/rcs/ 
3195 --ignore-directory=is:RCS 
3198 # http://en.wikipedia.org/wiki/Source_Code_Control_System 
3199 --ignore-directory=is:SCCS 
3203 --ignore-directory=is:_darcs 
3206 --ignore-directory=is:_sgbak 
3209 # http://www.gnu.org/software/autoconf/ 
3210 --ignore-directory=is:autom4te.cache 
3212 # Perl module building 
3213 --ignore-directory=is:blib 
3214 --ignore-directory=is:_build 
3216 # Perl Devel::Cover module's output directory 
3217 # https://metacpan.org/release/Devel-Cover 
3218 --ignore-directory=is:cover_db 
3220 # Node modules created by npm 
3221 --ignore-directory=is:node_modules 
3224 # http://www.cmake.org/ 
3225 --ignore-directory=is:CMakeFiles 
3227 # Eclipse workspace folder 
3228 # http://eclipse.org/ 
3229 --ignore-directory=is:.metadata 
3231 # Cabal (Haskell) sandboxes 
3232 # http://www.haskell.org/cabal/users-guide/installing-packages.html 
3233 --ignore-directory=is:.cabal-sandbox 
3238 --ignore-file=ext:bak 
3239 --ignore-file=match:/~$/ 
3242 --ignore-file=match:/^#.+#$/ 
3244 # vi/vim swap files http://vim.org/ 
3245 --ignore-file=match:/[._].*\.swp$/ 
3248 --ignore-file=match:/core\.\d+$/ 
3250 # minified Javascript 
3251 --ignore-file=match:/[.-]min[.]js$/ 
3252 --ignore-file=match:/[.]js[.]min$/ 
3255 --ignore-file=match:/[.]min[.]css$/ 
3256 --ignore-file=match:/[.]css[.]min$/ 
3258 # JS and CSS source maps 
3259 --ignore-file=match:/[.]js[.]map$/ 
3260 --ignore-file=match:/[.]css[.]map$/ 
3262 # PDFs, because they pass Perl's -T detection 
3263 --ignore-file=ext:pdf 
3265 # Common graphics, just as an optimization 
3266 --ignore-file=ext:gif,jpg,jpeg,png 
3269 ### Filetypes defined 
3273 --type-add=perl:ext:pl,pm,pod,t,psgi 
3274 --type-add=perl:firstlinematch:/^#!.*\bperl/ 
3277 --type-add=perltest:ext:t 
3280 # http://www.gnu.org/s/make/ 
3281 --type-add=make:ext:mk 
3282 --type-add=make:ext:mak 
3283 --type-add=make:is:makefile 
3284 --type-add=make:is:Makefile 
3285 --type-add=make:is:Makefile.Debug 
3286 --type-add=make:is:Makefile.Release 
3289 # http://rake.rubyforge.org/ 
3290 --type-add=rake:is:Rakefile 
3293 # http://www.cmake.org/ 
3294 --type-add=cmake:is:CMakeLists.txt 
3295 --type-add=cmake:ext:cmake 
3298 --type-add=actionscript:ext:as,mxml 
3301 # http://www.adaic.org/ 
3302 --type-add=ada:ext:ada,adb,ads 
3305 # http://msdn.microsoft.com/en-us/library/aa286483.aspx 
3306 --type-add=asp:ext:asp 
3309 # http://www.asp.net/ 
3310 --type-add=aspx:ext:master,ascx,asmx,aspx,svc 
3313 --type-add=asm:ext:asm,s 
3316 --type-add=batch:ext:bat,cmd 
3319 # http://en.wikipedia.org/wiki/ColdFusion 
3320 --type-add=cfmx:ext:cfc,cfm,cfml 
3323 # http://clojure.org/ 
3324 --type-add=clojure:ext:clj,cljs,edn,cljc 
3327 # .xs are Perl C files 
3328 --type-add=cc:ext:c,h,xs 
3334 # http://coffeescript.org/ 
3335 --type-add=coffeescript:ext:coffee 
3338 --type-add=cpp:ext:cpp,cc,cxx,m,hpp,hh,h,hxx 
3341 --type-add=hpp:ext:hpp,hh,h,hxx 
3344 --type-add=csharp:ext:cs 
3347 # http://www.w3.org/Style/CSS/ 
3348 --type-add=css:ext:css 
3351 # http://www.dartlang.org/ 
3352 --type-add=dart:ext:dart 
3355 # http://en.wikipedia.org/wiki/Embarcadero_Delphi 
3356 --type-add=delphi:ext:pas,int,dfm,nfm,dof,dpk,dproj,groupproj,bdsgroup,bdsproj 
3359 # http://elixir-lang.org/ 
3360 --type-add=elixir:ext:ex,exs 
3363 # http://www.gnu.org/software/emacs 
3364 --type-add=elisp:ext:el 
3367 # http://www.erlang.org/ 
3368 --type-add=erlang:ext:erl,hrl 
3371 # http://en.wikipedia.org/wiki/Fortran 
3372 --type-add=fortran:ext:f,f77,f90,f95,f03,for,ftn,fpp 
3375 # http://golang.org/ 
3376 --type-add=go:ext:go 
3379 # http://groovy.codehaus.org/ 
3380 --type-add=groovy:ext:groovy,gtmpl,gpp,grunit,gradle 
3383 # http://groovy.codehaus.org/GSP 
3384 --type-add=gsp:ext:gsp 
3387 # http://www.haskell.org/ 
3388 --type-add=haskell:ext:hs,lhs 
3391 --type-add=html:ext:htm,html,xhtml 
3394 # http://jade-lang.com/ 
3395 --type-add=jade:ext:jade 
3398 # http://www.oracle.com/technetwork/java/index.html 
3399 --type-add=java:ext:java,properties 
3402 --type-add=js:ext:js 
3405 # http://www.oracle.com/technetwork/java/javaee/jsp/index.html 
3406 --type-add=jsp:ext:jsp,jspx,jspf,jhtm,jhtml 
3409 # http://www.json.org/ 
3410 --type-add=json:ext:json 
3413 # https://kotlinlang.org/ 
3414 --type-add=kotlin:ext:kt,kts 
3417 # http://www.lesscss.org/ 
3418 --type-add=less:ext:less 
3421 # http://common-lisp.net/ 
3422 --type-add=lisp:ext:lisp,lsp 
3425 # http://www.lua.org/ 
3426 --type-add=lua:ext:lua 
3427 --type-add=lua:firstlinematch:/^#!.*\blua(jit)?/ 
3430 --type-add=objc:ext:m,h 
3433 --type-add=objcpp:ext:mm,h 
3436 # http://caml.inria.fr/ 
3437 --type-add=ocaml:ext:ml,mli,mll,mly 
3440 # http://en.wikipedia.org/wiki/MATLAB 
3441 --type-add=matlab:ext:m 
3444 # http://www.parrot.org/ 
3445 --type-add=parrot:ext:pir,pasm,pmc,ops,pod,pg,tg 
3448 # http://www.php.net/ 
3449 --type-add=php:ext:php,phpt,php3,php4,php5,phtml 
3450 --type-add=php:firstlinematch:/^#!.*\bphp/ 
3454 --type-add=plone:ext:pt,cpt,metadata,cpy,py 
3457 # http://www.python.org/ 
3458 --type-add=python:ext:py 
3459 --type-add=python:firstlinematch:/^#!.*\bpython/ 
3462 # http://www.r-project.org/ 
3466 # http://docutils.sourceforge.net/rst.html 
3467 --type-add=rst:ext:rst 
3470 # http://www.ruby-lang.org/ 
3471 --type-add=ruby:ext:rb,rhtml,rjs,rxml,erb,rake,spec 
3472 --type-add=ruby:is:Rakefile 
3473 --type-add=ruby:firstlinematch:/^#!.*\bruby/ 
3476 # http://www.rust-lang.org/ 
3477 --type-add=rust:ext:rs 
3480 # http://sass-lang.com 
3481 --type-add=sass:ext:sass,scss 
3484 # http://www.scala-lang.org/ 
3485 --type-add=scala:ext:scala 
3488 # http://groups.csail.mit.edu/mac/projects/scheme/ 
3489 --type-add=scheme:ext:scm,ss 
3492 --type-add=shell:ext:sh,bash,csh,tcsh,ksh,zsh,fish 
3493 --type-add=shell:firstlinematch:/^#!.*\b(?:ba|t?c|k|z|fi)?sh\b/ 
3496 # http://www.smalltalk.org/ 
3497 --type-add=smalltalk:ext:st 
3500 # http://www.smarty.net/ 
3501 --type-add=smarty:ext:tpl 
3504 # http://www.iso.org/iso/catalogue_detail.htm?csnumber=45498 
3505 --type-add=sql:ext:sql,ctl 
3508 # http://learnboost.github.io/stylus/ 
3509 --type-add=stylus:ext:styl 
3512 # https://developer.apple.com/swift/ 
3513 --type-add=swift:ext:swift 
3514 --type-add=swift:firstlinematch:/^#!.*\bswift/ 
3517 # http://www.tcl.tk/ 
3518 --type-add=tcl:ext:tcl,itcl,itk 
3521 # http://www.latex-project.org/ 
3522 --type-add=tex:ext:tex,cls,sty 
3524 # Template Toolkit (Perl) 
3525 # http://template-toolkit.org/ 
3526 --type-add=tt:ext:tt,tt2,ttml 
3529 --type-add=vb:ext:bas,cls,frm,ctl,vb,resx 
3532 --type-add=verilog:ext:v,vh,sv 
3535 # http://www.eda.org/twiki/bin/view.cgi/P1076/WebHome 
3536 --type-add=vhdl:ext:vhd,vhdl 
3539 # http://www.vim.org/ 
3540 --type-add=vim:ext:vim 
3543 # http://www.w3.org/TR/REC-xml/ 
3544 --type-add=xml:ext:xml,dtd,xsd,xsl,xslt,ent,wsdl 
3545 --type-add=xml:firstlinematch:/<[?]xml/ 
3549 --type-add=yaml:ext:yaml,yml 
3551     $lines =~ s/==VERSION==/$App::Ack::VERSION/sm; 
3557 package App
::Ack
::ConfigFinder
; 
3564 use File
::Spec 
3.00; 
3566 use if ($^O eq 'MSWin32'), 'Win32'; 
3572     return bless {}, $class; 
3576 sub _remove_redundancies 
{ 
3580     foreach my $config (@configs) { 
3581         my $key = $config->{path
}; 
3582         if ( not $App::Ack
::is_windows 
) { 
3583             # On Unix, uniquify on inode. 
3584             my ($dev, $inode) = (stat $key)[0, 1]; 
3585             $key = "$dev:$inode" if defined $dev; 
3587         undef $config if $seen{$key}++; 
3589     return grep { defined } @configs; 
3593 sub _check_for_ackrc 
{ 
3594     return unless defined $_[0]; 
3596     my @files = grep { -f 
} 
3597                 map { File
::Spec-
>catfile(@_, $_) } 
3600     die File
::Spec-
>catdir(@_) . " contains both .ackrc and _ackrc.\n" . 
3601         "Please remove one of those files.\n" 
3604     return wantarray ? @files : $files[0]; 
3605 } # end _check_for_ackrc 
3609 sub find_config_files 
{ 
3612     if ( $App::Ack
::is_windows 
) { 
3613         push @config_files, map { +{ path 
=> File
::Spec-
>catfile($_, 'ackrc') } } ( 
3614             Win32
::GetFolderPath
(Win32
::CSIDL_COMMON_APPDATA
()), 
3615             Win32
::GetFolderPath
(Win32
::CSIDL_APPDATA
()), 
3619         push @config_files, { path 
=> '/etc/ackrc' }; 
3623     if ( $ENV{'ACKRC'} && -f 
$ENV{'ACKRC'} ) { 
3624         push @config_files, { path 
=> $ENV{'ACKRC'} }; 
3627         push @config_files, map { +{ path 
=> $_ } } _check_for_ackrc
($ENV{'HOME'}); 
3630     my $cwd = Cwd
::getcwd
(); 
3631     return () unless defined $cwd; 
3633     # XXX This should go through some untainted cwd-fetching function, and not get untainted brute-force like this. 
3636     my @dirs = File
::Spec-
>splitdir( $cwd ); 
3638         my $ackrc = _check_for_ackrc
(@dirs); 
3639         if(defined $ackrc) { 
3640             push @config_files, { project 
=> 1, path 
=> $ackrc }; 
3646     # We only test for existence here, so if the file is deleted out from under us, this will fail later. 
3647     return _remove_redundancies
( @config_files ); 
3655     return unless defined $file && -e 
$file; 
3659     open( my $fh, '<', $file ) or App
::Ack
::die( "Unable to read $file: $!" ); 
3660     while ( my $line = <$fh> ) { 
3665         next if $line eq ''; 
3666         next if $line =~ /^\s*#/; 
3668         push( @lines, $line ); 
3670     close $fh or App
::Ack
::die( "Unable to close $file: $!" ); 
3676 package App
::Ack
::ConfigLoader
; 
3682 use Getopt
::Long 
2.38 (); 
3683 use Text
::ParseWords 
3.1 (); 
3686 my @INVALID_COMBINATIONS; 
3689     my @context  = qw( -A -B -C --after-context --before-context --context ); 
3690     my @pretty   = qw( --heading --group --break ); 
3691     my @filename = qw( -h -H --with-filename --no-filename ); 
3693     @INVALID_COMBINATIONS = ( 
3695         [qw(-l)]                 => [@context, @pretty, @filename, qw(-L -o --passthru --output --max-count --column -f -g --show-types)], 
3696         [qw(-L)]                 => [@context, @pretty, @filename, qw(-l -o --passthru --output --max-count --column -f -g --show-types -c --count)], 
3697         [qw(--line)]             => [@context, @pretty, @filename, qw(-l --files-with-matches --files-without-matches -L -o --passthru --match -m --max-count -1 -c --count --column --print0 -f -g --show-types)], 
3698         [qw(-o)]                 => [@context, qw(--output -c --count --column --column -f --show-types)], 
3699         [qw(--passthru)]         => [@context, qw(--output --column -m --max-count -1 -c --count -f -g)], 
3700         [qw(--output)]           => [@context, qw(-c --count -f -g)], 
3701         [qw(--match)]            => [qw(-f -g)], 
3702         [qw(-m --max-count)]     => [qw(-1 -f -g -c --count)], 
3703         [qw(-h --no-filename)]   => [qw(-H --with-filename -f -g --group --heading)], 
3704         [qw(-H --with-filename)] => [qw(-h --no-filename -f -g)], 
3705         [qw(-c --count)]         => [@context, @pretty, qw(--column -f -g)], 
3706         [qw(--column)]           => [qw(-f -g)], 
3707         [@context]               => [qw(-f -g)], 
3708         [qw(-f)]                 => [qw(-g), @pretty], 
3709         [qw(-g)]                 => [qw(-f), @pretty], 
3713 sub _generate_ignore_dir 
{ 
3714     my ( $option_name, $opt ) = @_; 
3716     my $is_inverted = $option_name =~ /^--no/; 
3719         my ( undef, $dir ) = @_; 
3721         $dir = App
::Ack
::remove_dir_sep
( $dir ); 
3722         if ( $dir !~ /:/ ) { 
3723             $dir = 'is:' . $dir; 
3726         my ( $filter_type, $args ) = split /:/, $dir, 2; 
3728         if ( $filter_type eq 'firstlinematch' ) { 
3729             Carp
::croak
( qq{Invalid filter specification "$filter_type" for option '$option_name'} ); 
3732         my $filter = App
::Ack
::Filter-
>create_filter($filter_type, split(/,/, $args)); 
3735         my $previous_inversion_matches = $opt->{idirs
} && !($is_inverted xor $opt->{idirs
}[-1]->is_inverted()); 
3737         if ( $previous_inversion_matches ) { 
3738             $collection = $opt->{idirs
}[-1]; 
3740             if ( $is_inverted ) { 
3741                 # XXX this relies on invert of an inverted filter 
3742                 #     to return the original 
3743                 $collection = $collection->invert() 
3747             $collection = App
::Ack
::Filter
::Collection-
>new(); 
3749             if ( $is_inverted ) { 
3750                 push @{ $opt->{idirs
} }, $collection->invert(); 
3753                 push @{ $opt->{idirs
} }, $collection; 
3757         $collection->add($filter); 
3759         if ( $filter_type eq 'is' ) { 
3760             $collection->add(App
::Ack
::Filter
::IsPath-
>new($args)); 
3765 sub process_filter_spec 
{ 
3768     if ( $spec =~ /^(\w+):(\w+):(.*)/ ) { 
3769         my ( $type_name, $ext_type, $arguments ) = ( $1, $2, $3 ); 
3771         return ( $type_name, 
3772             App
::Ack
::Filter-
>create_filter($ext_type, split(/,/, $arguments)) ); 
3774     elsif ( $spec =~ /^(\w+)=(.*)/ ) { # Check to see if we have ack1-style argument specification. 
3775         my ( $type_name, $extensions ) = ( $1, $2 ); 
3777         my @extensions = split(/,/, $extensions); 
3778         foreach my $extension ( @extensions ) { 
3779             $extension =~ s/^[.]//; 
3782         return ( $type_name, App
::Ack
::Filter-
>create_filter('ext', @extensions) ); 
3785         Carp
::croak 
"invalid filter specification '$spec'"; 
3790 sub uninvert_filter 
{ 
3791     my ( $opt, @filters ) = @_; 
3793     return unless defined $opt->{filters
} && @filters; 
3795     # Loop through all the registered filters.  If we hit one that 
3796     # matches this extension and it's inverted, we need to delete it from 
3798     for ( my $i = 0; $i < @{ $opt->{filters
} }; $i++ ) { 
3799         my $opt_filter = @{ $opt->{filters
} }[$i]; 
3801         # XXX Do a real list comparison? This just checks string equivalence. 
3802         if ( $opt_filter->is_inverted() && "$opt_filter->{filter}" eq "@filters" ) { 
3803             splice @{ $opt->{filters
} }, $i, 1; 
3812 sub process_filetypes 
{ 
3813     my ( $opt, $arg_sources ) = @_; 
3815     Getopt
::Long
::Configure
('default', 'no_auto_help', 'no_auto_version'); # start with default options, minus some annoying ones 
3816     Getopt
::Long
::Configure
( 
3821     my %additional_specs; 
3823     my $add_spec = sub { 
3824         my ( undef, $spec ) = @_; 
3826         my ( $name, $filter ) = process_filter_spec
($spec); 
3828         push @{ $App::Ack
::mappings
{$name} }, $filter; 
3830         $additional_specs{$name . '!'} = sub { 
3831             my ( undef, $value ) = @_; 
3833             my @filters = @{ $App::Ack
::mappings
{$name} }; 
3835                 @filters = map { $_->invert() } @filters; 
3838                 uninvert_filter
( $opt, @filters ); 
3841             push @{ $opt->{'filters'} }, @filters; 
3845     my $set_spec = sub { 
3846         my ( undef, $spec ) = @_; 
3848         my ( $name, $filter ) = process_filter_spec
($spec); 
3850         $App::Ack
::mappings
{$name} = [ $filter ]; 
3852         $additional_specs{$name . '!'} = sub { 
3853             my ( undef, $value ) = @_; 
3855             my @filters = @{ $App::Ack
::mappings
{$name} }; 
3857                 @filters = map { $_->invert() } @filters; 
3860             push @{ $opt->{'filters'} }, @filters; 
3864     my $delete_spec = sub { 
3865         my ( undef, $name ) = @_; 
3867         delete $App::Ack
::mappings
{$name}; 
3868         delete $additional_specs{$name . '!'}; 
3871     my %type_arg_specs = ( 
3872         'type-add=s' => $add_spec, 
3873         'type-set=s' => $set_spec, 
3874         'type-del=s' => $delete_spec, 
3877     foreach my $source (@{$arg_sources}) { 
3878         my ( $source_name, $args ) = @{$source}{qw
/name contents/}; 
3881             # $args are modified in place, so no need to munge $arg_sources 
3882             local @ARGV = @{$args}; 
3883             Getopt
::Long
::GetOptions
(%type_arg_specs); 
3887             ( undef, $source->{contents
} ) = 
3888                 Getopt
::Long
::GetOptionsFromString
($args, %type_arg_specs); 
3892     $additional_specs{'k|known-types'} = sub { 
3893         my ( undef, $value ) = @_; 
3895         my @filters = map { @{$_} } values(%App::Ack
::mappings
); 
3897         push @{ $opt->{'filters'} }, @filters; 
3900     return \
%additional_specs; 
3904 sub removed_option 
{ 
3905     my ( $option, $explanation ) = @_; 
3907     $explanation ||= ''; 
3909         warn "Option '$option' is not valid in ack 2.\n$explanation"; 
3916     my ( $opt, $extra_specs ) = @_; 
3918     my $dash_a_explanation = <<'EOT'; 
3919 You don't need -a, ack 1.x users.  This is because ack 2.x has 
3920 -k/--known-types which makes it only select files of known types, rather 
3921 than any text file (which is the behavior of ack 1.x). 
3923 If you're surprised to see this message because you didn't put -a on the 
3924 command line, you may have options in an .ackrc, or in the ACKRC_OPTIONS 
3925 environment variable.  Try using the --dump flag to help find it. 
3929     sub _context_value 
{ 
3932         # Contexts default to 2. 
3933         return (!defined($val) || ($val < 0)) ? 2 : $val; 
3937         1                   => sub { $opt->{1} = $opt->{m
} = 1 }, 
3938         'A|after-context:-1'  => sub { shift; $opt->{after_context
}  = _context_value
(shift) }, 
3939         'B|before-context:-1' => sub { shift; $opt->{before_context
} = _context_value
(shift) }, 
3940         'C|context:-1'        => sub { shift; $opt->{before_context
} = $opt->{after_context
} = _context_value
(shift) }, 
3941         'a'                 => removed_option
('-a', $dash_a_explanation), 
3942         'all'               => removed_option
('--all', $dash_a_explanation), 
3943         'break!'            => \
$opt->{break}, 
3944         c                   
=> \
$opt->{count
}, 
3945         'color|colour!'     => \
$opt->{color
}, 
3946         'color-match=s'     => \
$ENV{ACK_COLOR_MATCH
}, 
3947         'color-filename=s'  => \
$ENV{ACK_COLOR_FILENAME
}, 
3948         'color-lineno=s'    => \
$ENV{ACK_COLOR_LINENO
}, 
3949         'column!'           => \
$opt->{column
}, 
3950         count               
=> \
$opt->{count
}, 
3951         'create-ackrc'      => sub { print "$_\n" for ( '--ignore-ack-defaults', App
::Ack
::ConfigDefault
::options
() ); exit; }, 
3953             my ( undef, $value ) = @_; 
3956                 $opt->{noenv_seen
} = 1; 
3960         'files-from=s'      => \
$opt->{files_from
}, 
3961         'filter!'           => \
$App::Ack
::is_filter_mode
, 
3962         flush               
=> \
$opt->{flush
}, 
3963         'follow!'           => \
$opt->{follow
}, 
3965         G                   
=> removed_option
('-G'), 
3966         'group!'            => sub { shift; $opt->{heading
} = $opt->{break} = shift }, 
3967         'heading!'          => \
$opt->{heading
}, 
3968         'h|no-filename'     => \
$opt->{h
}, 
3969         'H|with-filename'   => \
$opt->{H
}, 
3970         'i|ignore-case'     => \
$opt->{i
}, 
3971         'ignore-directory|ignore-dir=s' => _generate_ignore_dir
('--ignore-dir', $opt), 
3972         'ignore-file=s'     => sub { 
3973                                     my ( undef, $file ) = @_; 
3975                                     my ( $filter_type, $args ) = split /:/, $file, 2; 
3977                                     my $filter = App
::Ack
::Filter-
>create_filter($filter_type, split(/,/, $args)); 
3979                                     if ( !$opt->{ifiles
} ) { 
3980                                         $opt->{ifiles
} = App
::Ack
::Filter
::Collection-
>new(); 
3982                                     $opt->{ifiles
}->add($filter); 
3984         'lines=s'           => sub { shift; my $val = shift; push @{$opt->{lines
}}, $val }, 
3985         'l|files-with-matches' 
3987         'L|files-without-matches' 
3989         'm|max-count=i'     => \
$opt->{m
}, 
3990         'match=s'           => \
$opt->{regex
}, 
3991         'n|no-recurse'      => \
$opt->{n
}, 
3992         o                   
=> sub { $opt->{output
} = '$&' }, 
3993         'output=s'          => \
$opt->{output
}, 
3995             my ( undef, $value ) = @_; 
3997             $opt->{pager
} = $value || $ENV{PAGER
}; 
3999         'noignore-directory|noignore-dir=s' => _generate_ignore_dir
('--noignore-dir', $opt), 
4000         'nopager'           => sub { $opt->{pager
} = undef }, 
4001         'passthru'          => \
$opt->{passthru
}, 
4002         'print0'            => \
$opt->{print0
}, 
4003         'Q|literal'         => \
$opt->{Q
}, 
4004         'r|R|recurse'       => sub { $opt->{n
} = 0 }, 
4005         's'                 => \
$opt->{dont_report_bad_filenames
}, 
4006         'show-types'        => \
$opt->{show_types
}, 
4007         'smart-case!'       => \
$opt->{smart_case
}, 
4008         'sort-files'        => \
$opt->{sort_files
}, 
4010             my ( $getopt, $value ) = @_; 
4013             if ( $value =~ s/^no// ) { 
4017             my $callback = $extra_specs->{ $value . '!' }; 
4020                 $callback->( $getopt, $cb_value ); 
4023                 Carp
::croak
( "Unknown type '$value'" ); 
4026         'u'                 => removed_option
('-u'), 
4027         'unrestricted'      => removed_option
('--unrestricted'), 
4028         'v|invert-match'    => \
$opt->{v
}, 
4029         'w|word-regexp'     => \
$opt->{w
}, 
4030         'x'                 => sub { $opt->{files_from
} = '-' }, 
4032         'version'           => sub { App
::Ack
::print_version_statement
(); exit; }, 
4033         'help|?:s'          => sub { shift; App
::Ack
::show_help
(@_); exit; }, 
4034         'help-types'        => sub { App
::Ack
::show_help_types
(); exit; }, 
4035         'man'               => sub { App
::Ack
::show_man
(); exit; }, 
4036         $extra_specs ? %{$extra_specs} : (), 
4042     my ( $opt, $extra_specs, $arg_sources ) = @_; 
4044     # Start with default options, minus some annoying ones. 
4045     Getopt
::Long
::Configure
('default', 'no_auto_help', 'no_auto_version'); 
4046     Getopt
::Long
::Configure
( 
4052     my $is_help_types_active; 
4054     foreach my $source (@{$arg_sources}) { 
4055         my ( $source_name, $args ) = @{$source}{qw
/name contents/}; 
4057         if ( $source_name eq 'ARGV' ) { 
4058             $argv_source = $args; 
4063     if ( $argv_source ) { # This *should* always be true, but you never know... 
4064         my @copy = @{$argv_source}; 
4065         local @ARGV = @copy; 
4067         Getopt
::Long
::Configure
('pass_through'); 
4069         Getopt
::Long
::GetOptions
( 
4070             'help-types' => \
$is_help_types_active, 
4073         Getopt
::Long
::Configure
('no_pass_through'); 
4076     my $arg_specs = get_arg_spec
($opt, $extra_specs); 
4078     foreach my $source (@{$arg_sources}) { 
4079         my ( $source_name, $args ) = @{$source}{qw
/name contents/}; 
4081         my $args_for_source = $arg_specs; 
4083         if ( $source->{project
} ) { 
4085                 die "Options --output, --pager and --match are forbidden in project .ackrc files.\n"; 
4088             $args_for_source = { 
4089                 %{$args_for_source}, 
4090                 'output=s' => $illegal, 
4091                 'pager:s'  => $illegal, 
4092                 'match=s'  => $illegal, 
4098             local @ARGV = @{$args}; 
4099             $ret = Getopt
::Long
::GetOptions
( %{$args_for_source} ); 
4103             ( $ret, $source->{contents
} ) = 
4104                 Getopt
::Long
::GetOptionsFromString
( $args, %{$args_for_source} ); 
4107             if ( !$is_help_types_active ) { 
4108                 my $where = $source_name eq 'ARGV' ? 'on command line' : "in $source_name"; 
4109                 App
::Ack
::die( "Invalid option $where" ); 
4112         if ( $opt->{noenv_seen
} ) { 
4113             App
::Ack
::die( "--noenv found in $source_name" ); 
4117     # XXX We need to check on a -- in the middle of a non-ARGV source 
4123 sub should_dump_options 
{ 
4124     my ( $sources ) = @_; 
4126     foreach my $source (@{$sources}) { 
4127         my ( $name, $options ) = @{$source}{qw
/name contents/}; 
4129         if($name eq 'ARGV') { 
4131             local @ARGV = @{$options}; 
4132             Getopt
::Long
::Configure
('default', 'pass_through', 'no_auto_help', 'no_auto_version'); 
4133             Getopt
::Long
::GetOptions
( 
4136             @{$options} = @ARGV; 
4144 sub explode_sources 
{ 
4145     my ( $sources ) = @_; 
4149     Getopt
::Long
::Configure
('default', 'pass_through', 'no_auto_help', 'no_auto_version'); 
4152     my $arg_spec = get_arg_spec
(\
%opt); 
4154     my $add_type = sub { 
4155         my ( undef, $arg ) = @_; 
4158         if ( $arg =~ /(\w+)=/) { 
4159             $arg_spec->{$1} = sub {}; 
4162             ( $arg ) = split /:/, $arg; 
4163             $arg_spec->{$arg} = sub {}; 
4167     my $del_type = sub { 
4168         my ( undef, $arg ) = @_; 
4170         delete $arg_spec->{$arg}; 
4173     foreach my $source (@{$sources}) { 
4174         my ( $name, $options ) = @{$source}{qw
/name contents/}; 
4175         if ( ref($options) ne 'ARRAY' ) { 
4176             $source->{contents
} = $options = 
4177                 [ Text
::ParseWords
::shellwords
($options) ]; 
4180         for my $j ( 0 .. @{$options}-1 ) { 
4181             next unless $options->[$j] =~ /^-/; 
4182             my @chunk = ( $options->[$j] ); 
4183             push @chunk, $options->[$j] while ++$j < @{$options} && $options->[$j] !~ /^-/; 
4187             local @ARGV = @chunk; 
4188             Getopt
::Long
::GetOptions
( 
4189                 'type-add=s' => $add_type, 
4190                 'type-set=s' => $add_type, 
4191                 'type-del=s' => $del_type, 
4193             Getopt
::Long
::GetOptions
( %{$arg_spec} ); 
4195             push @new_sources, { 
4202     return \
@new_sources; 
4209     my $first_a = $a->[0]; 
4210     my $first_b = $b->[0]; 
4212     $first_a =~ s/^--?//; 
4213     $first_b =~ s/^--?//; 
4215     return $first_a cmp $first_b; 
4220     my ( $sources ) = @_; 
4222     $sources = explode_sources
($sources); 
4227     foreach my $source (@{$sources}) { 
4228         my ( $name, $contents ) = @{$source}{qw
/name contents/}; 
4229         if ( not $opts_by_source{$name} ) { 
4230             $opts_by_source{$name} = []; 
4231             push @source_names, $name; 
4233         push @{$opts_by_source{$name}}, $contents; 
4236     foreach my $name (@source_names) { 
4237         my $contents = $opts_by_source{$name}; 
4240         print '=' x 
length($name), "\n"; 
4241         print '  ', join(' ', @{$_}), "\n" foreach sort { compare_opts
($a, $b) } @{$contents}; 
4248 sub remove_default_options_if_needed 
{ 
4249     my ( $sources ) = @_; 
4253     foreach my $index ( 0 .. $#{$sources} ) { 
4254         if ( $sources->[$index]{'name'} eq 'Defaults' ) { 
4255             $default_index = $index; 
4260     return $sources unless defined $default_index; 
4262     my $should_remove = 0; 
4264     # Start with default options, minus some annoying ones. 
4265     Getopt
::Long
::Configure
('default', 'no_auto_help', 'no_auto_version'); 
4266     Getopt
::Long
::Configure
( 
4272     foreach my $index ( $default_index + 1 .. $#{$sources} ) { 
4273         my ( $name, $args ) = @{$sources->[$index]}{qw
/name contents/}; 
4276             local @ARGV = @{$args}; 
4277             Getopt
::Long
::GetOptions
( 
4278                 'ignore-ack-defaults' => \
$should_remove, 
4283             ( undef, $sources->[$index]{contents
} ) = Getopt
::Long
::GetOptionsFromString
($args, 
4284                 'ignore-ack-defaults' => \
$should_remove, 
4289     Getopt
::Long
::Configure
('default'); 
4290     Getopt
::Long
::Configure
('default', 'no_auto_help', 'no_auto_version'); 
4292     return $sources unless $should_remove; 
4294     my @copy = @{$sources}; 
4295     splice @copy, $default_index, 1; 
4300 sub check_for_mutually_exclusive_options 
{ 
4301     my ( $arg_sources ) = @_; 
4303     my %mutually_exclusive_with; 
4304     my @copy = @{$arg_sources}; 
4306     for(my $i = 0; $i < @INVALID_COMBINATIONS; $i += 2) { 
4307         my ( $lhs, $rhs ) = @INVALID_COMBINATIONS[ $i, $i + 1 ]; 
4309         foreach my $l_opt ( @{$lhs} ) { 
4310             foreach my $r_opt ( @{$rhs} ) { 
4311                 push @{ $mutually_exclusive_with{ $l_opt } }, $r_opt; 
4312                 push @{ $mutually_exclusive_with{ $r_opt } }, $l_opt; 
4320         my $source = shift @copy; 
4321         my ( $source_name, $args ) = @{$source}{qw
/name contents/}; 
4322         $args = ref($args) ? [ @{$args} ] : [ Text
::ParseWords
::shellwords
($args) ]; 
4324         foreach my $opt ( @{$args} ) { 
4325             next unless $opt =~ /^[-+]/; 
4326             last if $opt eq '--'; 
4328             if( $opt =~ /^(.*)=/ ) { 
4331             elsif ( $opt =~ /^(-[^-]).+/ ) { 
4335             $set_opts{ $opt } = 1; 
4337             my $mutex_opts = $mutually_exclusive_with{ $opt }; 
4339             next unless $mutex_opts; 
4341             foreach my $mutex_opt ( @{$mutex_opts} ) { 
4342                 if($set_opts{ $mutex_opt }) { 
4343                     die "Options '$mutex_opt' and '$opt' are mutually exclusive\n"; 
4354     my $arg_sources = \
@_; 
4357         pager 
=> $ENV{ACK_PAGER_COLOR
} || $ENV{ACK_PAGER
}, 
4360     check_for_mutually_exclusive_options
($arg_sources); 
4362     $arg_sources = remove_default_options_if_needed
($arg_sources); 
4364     if ( should_dump_options
($arg_sources) ) { 
4365         dump_options
($arg_sources); 
4369     my $type_specs = process_filetypes
(\
%opt, $arg_sources); 
4370     process_other
(\
%opt, $type_specs, $arg_sources); 
4371     while ( @{$arg_sources} ) { 
4372         my $source = shift @{$arg_sources}; 
4373         my ( $source_name, $args ) = @{$source}{qw
/name contents/}; 
4375         # All of our sources should be transformed into an array ref 
4377             if ( $source_name eq 'ARGV' ) { 
4381                 Carp
::croak 
"source '$source_name' has extra arguments!"; 
4385             Carp
::croak 
'The impossible has occurred!'; 
4388     my $filters = ($opt{filters
} ||= []); 
4390     # Throw the default filter in if no others are selected. 
4391     if ( not grep { !$_->is_inverted() } @{$filters} ) { 
4392         push @{$filters}, App
::Ack
::Filter
::Default-
>new(); 
4398 sub retrieve_arg_sources 
{ 
4404     Getopt
::Long
::Configure
('default', 'no_auto_help', 'no_auto_version'); 
4405     Getopt
::Long
::Configure
('pass_through'); 
4406     Getopt
::Long
::Configure
('no_auto_abbrev'); 
4408     Getopt
::Long
::GetOptions
( 
4410         'ackrc=s' => \
$ackrc, 
4413     Getopt
::Long
::Configure
('default', 'no_auto_help', 'no_auto_version'); 
4418         my $finder = App
::Ack
::ConfigFinder-
>new; 
4419         @files  = $finder->find_config_files; 
4422         # We explicitly use open so we get a nice error message. 
4423         # XXX This is a potential race condition!. 
4424         if(open my $fh, '<', $ackrc) { 
4428             die "Unable to load ackrc '$ackrc': $!" 
4430         push( @files, { path 
=> $ackrc } ); 
4433     push @arg_sources, { 
4435         contents 
=> [ App
::Ack
::ConfigDefault
::options_clean
() ], 
4438     foreach my $file ( @files) { 
4439         my @lines = App
::Ack
::ConfigFinder
::read_rcfile
($file->{path
}); 
4442             push @arg_sources, { 
4443                 name     
=> $file->{path
}, 
4444                 contents 
=> \
@lines, 
4445                 project  
=> $file->{project
}, 
4450     if ( $ENV{ACK_OPTIONS
} && !$noenv ) { 
4451         push @arg_sources, { 
4452             name     
=> 'ACK_OPTIONS', 
4453             contents 
=> $ENV{ACK_OPTIONS
}, 
4457     push @arg_sources, { 
4459         contents 
=> [ @ARGV ], 
4462     return @arg_sources; 
4465 1; # End of App::Ack::ConfigLoader 
4466 package App
::Ack
::Filter
; 
4478     my ( undef, $type, @args ) = @_; 
4480     if ( my $package = $filter_types{$type} ) { 
4481         return $package->new(@args); 
4483     Carp
::croak 
"Unknown filter type '$type'"; 
4487 sub register_filter 
{ 
4488     my ( undef, $type, $package ) = @_; 
4490     $filter_types{$type} = $package; 
4499     return App
::Ack
::Filter
::Inverse-
>new( $self ); 
4511     return '(unimplemented to_string)'; 
4522 package App
::Ack
::Filter
::Extension
; 
4528     our @ISA = 'App::Ack::Filter'; 
4533     my ( $class, @extensions ) = @_; 
4535     my $exts = join('|', map { "\Q$_\E"} @extensions); 
4536     my $re   = qr/[.](?:$exts)$/i; 
4539         extensions 
=> \
@extensions, 
4541         groupname  
=> 'ExtensionGroup', 
4546     return App
::Ack
::Filter
::ExtensionGroup-
>new(); 
4550     my ( $self, $resource ) = @_; 
4552     my $re = $self->{'regex'}; 
4554     return $resource->name =~ /$re/; 
4560     my $re = $self->{'regex'}; 
4562     return ref($self) . " - $re"; 
4568     my $exts = $self->{'extensions'}; 
4570     return join(' ', map { ".$_" } @{$exts}); 
4574     App
::Ack
::Filter-
>register_filter(ext 
=> __PACKAGE__
); 
4578 package App
::Ack
::Filter
::FirstLineMatch
; 
4585     our @ISA = 'App::Ack::Filter'; 
4589     my ( $class, $re ) = @_; 
4591     $re =~ s{^/|/$}{}g; # XXX validate? 
4599 # This test reads the first 250 characters of a file, then just uses the 
4600 # first line found in that. This prevents reading something  like an entire 
4601 # .min.js file (which might be only one "line" long) into memory. 
4604     my ( $self, $resource ) = @_; 
4606     my $re = $self->{'regex'}; 
4608     my $line = $resource->firstliney; 
4610     return $line =~ /$re/; 
4616     my $re = $self->{'regex'}; 
4618     return ref($self) . " - $re"; 
4624     (my $re = $self->{regex
}) =~ s{\([^:]*:(.*)\)$}{$1}; 
4626     return "first line matches /$re/"; 
4630     App
::Ack
::Filter-
>register_filter(firstlinematch 
=> __PACKAGE__
); 
4634 package App
::Ack
::Filter
::Is
; 
4640     our @ISA = 'App::Ack::Filter'; 
4643 use File
::Spec 
3.00 (); 
4646     my ( $class, $filename ) = @_; 
4649         filename 
=> $filename, 
4650         groupname 
=> 'IsGroup', 
4655     return App
::Ack
::Filter
::IsGroup-
>new(); 
4659     my ( $self, $resource ) = @_; 
4661     my $filename = $self->{'filename'}; 
4662     my $base     = (File
::Spec-
>splitpath($resource->name))[2]; 
4664     return $base eq $filename; 
4670     my $filename = $self->{'filename'}; 
4672     return ref($self) . " - $filename"; 
4678     my $filename = $self->{'filename'}; 
4684     App
::Ack
::Filter-
>register_filter(is => __PACKAGE__
); 
4688 package App
::Ack
::Filter
::Match
; 
4693     our @ISA = 'App::Ack::Filter'; 
4696 use File
::Spec 
3.00; 
4700     my ( $class, $re ) = @_; 
4702     $re =~ s{^/|/$}{}g; # XXX validate? 
4707         groupname 
=> 'MatchGroup', 
4712     return App
::Ack
::Filter
::MatchGroup-
>new; 
4716     my ( $self, $resource ) = @_; 
4718     my $re = $self->{'regex'}; 
4720     return $resource->basename =~ /$re/; 
4726     my $re = $self->{'regex'}; 
4728     print ref($self) . " - $re"; 
4736     my $re = $self->{'regex'}; 
4738     return "filename matches $re"; 
4742     App
::Ack
::Filter-
>register_filter(match 
=> __PACKAGE__
); 
4746 package App
::Ack
::Filter
::Default
; 
4752     our @ISA = 'App::Ack::Filter'; 
4758     return bless {}, $class; 
4762     my ( $self, $resource ) = @_; 
4764     return -T 
$resource->name; 
4768 package App
::Ack
::Filter
::Inverse
; 
4775     our @ISA = 'App::Ack::Filter'; 
4779     my ( $class, $filter ) = @_; 
4787     my ( $self, $resource ) = @_; 
4789     my $filter = $self->{'filter'}; 
4790     return !$filter->filter( $resource ); 
4796     return $self->{'filter'}; 
4806     my $filter = $self->{'filter'}; 
4812 package App
::Ack
::Filter
::Collection
; 
4818     our @ISA = 'App::Ack::Filter'; 
4831     my ( $self, $resource ) = @_; 
4833     for my $group (values %{$self->{'groups'}}) { 
4834         if ($group->filter($resource)) { 
4839     for my $filter (@{$self->{'ungrouped'}}) { 
4840         if ($filter->filter($resource)) { 
4849     my ( $self, $filter ) = @_; 
4851     if (exists $filter->{'groupname'}) { 
4852         my $group = ($self->{groups
}->{$filter->{groupname
}} ||= $filter->create_group()); 
4853         $group->add($filter); 
4856         push @{$self->{'ungrouped'}}, $filter; 
4865     return ref($self) . " - $self"; 
4871     my $ungrouped = $self->{'ungrouped'}; 
4873     return join(', ', map { "($_)" } @{$ungrouped}); 
4877 package App
::Ack
::Filter
::IsGroup
; 
4883     our @ISA = 'App::Ack::Filter'; 
4886 use File
::Spec 
3.00 (); 
4897     my ( $self, $filter ) = @_; 
4899     $self->{data
}->{ $filter->{filename
} } = 1; 
4905     my ( $self, $resource ) = @_; 
4907     my $data = $self->{'data'}; 
4908     my $base = $resource->basename; 
4910     return exists $data->{$base}; 
4916     return ref($self) . " - $self"; 
4922     return join(' ', keys %{$self->{data
}}); 
4926 package App
::Ack
::Filter
::ExtensionGroup
; 
4932     our @ISA = 'App::Ack::Filter'; 
4944     my ( $self, $filter ) = @_; 
4946     foreach my $ext (@{$filter->{extensions
}}) { 
4947         $self->{data
}->{lc $ext} = 1; 
4954     my ( $self, $resource ) = @_; 
4956     if ($resource->name =~ /[.]([^.]*)$/) { 
4957         return exists $self->{'data'}->{lc $1}; 
4966     return ref($self) . " - $self"; 
4972     return join(' ', map { ".$_" } sort keys %{$self->{data
}}); 
4976 package App
::Ack
::Filter
::MatchGroup
; 
4982     our @ISA = 'App::Ack::Filter'; 
4995     my ( $self, $filter ) = @_; 
4997     push @{ $self->{matches
} }, $filter->{regex
}; 
4999     my $re = join('|', map { "(?:$_)" } @{ $self->{matches
} }); 
5000     $self->{big_re
} = qr/$re/; 
5006     my ( $self, $resource ) = @_; 
5008     my $re = $self->{big_re
}; 
5010     return $resource->basename =~ /$re/; 
5016     # XXX Needs an explicit return. 
5022     # XXX Needs an explicit return. 
5026 package App
::Ack
::Filter
::IsPath
; 
5032     our @ISA = 'App::Ack::Filter'; 
5037     my ( $class, $filename ) = @_; 
5040         filename 
=> $filename, 
5041         groupname 
=> 'IsPathGroup', 
5046     return App
::Ack
::Filter
::IsPathGroup-
>new(); 
5050     my ( $self, $resource ) = @_; 
5052     return $resource->name eq $self->{'filename'}; 
5058     my $filename = $self->{'filename'}; 
5060     return ref($self) . " - $filename"; 
5066     my $filename = $self->{'filename'}; 
5072 package App
::Ack
::Filter
::IsPathGroup
; 
5080     our @ISA = 'App::Ack::Filter'; 
5092     my ( $self, $filter ) = @_; 
5094     $self->{data
}->{ $filter->{filename
} } = 1; 
5100     my ( $self, $resource ) = @_; 
5102     my $data = $self->{'data'}; 
5104     return exists $data->{$resource->name}; 
5110     return ref($self) . " - $self"; 
5116     return join(' ', keys %{$self->{data
}}); 
5126 our $VERSION = '1.16'; 
5132 our $name; # name of the current file 
5133 our $dir;  # dir of the current file 
5135 our %files_defaults; 
5140         file_filter     
=> undef, 
5141         descend_filter  
=> undef, 
5142         error_handler   
=> sub { CORE
::die $_[0] }, 
5143         warning_handler 
=> sub { CORE
::warn @_ }, 
5144         sort_files      
=> undef, 
5145         follow_symlinks 
=> 1, 
5148     %skip_dirs = map {($_,1)} (File
::Spec-
>curdir, File
::Spec-
>updir); 
5153     die _bad_invocation
() if @_ && defined($_[0]) && ($_[0] eq __PACKAGE__
); 
5155     my ($parms,@queue) = _setup
( \
%files_defaults, @_ ); 
5158         my $filter = $parms->{file_filter
}; 
5160             my ($dirname,$file,$fullpath) = splice( @queue, 0, 3 ); 
5161             if ( -f 
$fullpath || -p _ 
|| $fullpath =~ m{^/dev/fd} ) { 
5164                     local $File::Next
::dir 
= $dirname; 
5165                     local $File::Next
::name 
= $fullpath; 
5166                     next if not $filter->(); 
5168                 return wantarray ? ($dirname,$file,$fullpath) : $fullpath; 
5171                 unshift( @queue, _candidate_files
( $parms, $fullpath ) ); 
5185     die _bad_invocation
() if @_ && defined($_[0]) && ($_[0] eq __PACKAGE__
); 
5187     my ($parms,@queue) = _setup
( \
%files_defaults, @_ ); 
5188     my $err  = $parms->{error_handler
}; 
5189     my $warn = $parms->{warning_handler
}; 
5191     my $filename = $queue[1]; 
5193     if ( !defined($filename) ) { 
5194         $err->( 'Must pass a filename to from_file()' ); 
5199     if ( $filename eq '-' ) { 
5203         if ( !open( $fh, '<', $filename ) ) { 
5204             $err->( "Unable to open $filename: $!", $! + 0 ); 
5210         my $filter = $parms->{file_filter
}; 
5211         local $/ = $parms->{nul_separated
} ? "\x00" : $/; 
5212         while ( my $fullpath = <$fh> ) { 
5214             next unless $fullpath =~ /./; 
5215             if ( not ( -f 
$fullpath || -p _ 
) ) { 
5216                 $warn->( "$fullpath: No such file" ); 
5220             my ($volume,$dirname,$file) = File
::Spec-
>splitpath( $fullpath ); 
5223                 local $File::Next
::dir  
= $dirname; 
5224                 local $File::Next
::name 
= $fullpath; 
5225                 next if not $filter->(); 
5227             return wantarray ? ($dirname,$file,$fullpath) : $fullpath; 
5235 sub _bad_invocation 
{ 
5236     my $good = (caller(1))[3]; 
5238     $bad =~ s/(.+)::/$1->/; 
5239     return "$good must not be invoked as $bad"; 
5242 sub sort_standard
($$)   { return $_[0]->[1] cmp $_[1]->[1] } 
5243 sub sort_reverse
($$)    { return $_[1]->[1] cmp $_[0]->[1] } 
5248     my @parts = split( /\//, $path ); 
5250     return $path if @parts < 2; 
5252     return File
::Spec-
>catfile( @parts ); 
5258     my $defaults = shift; 
5259     my $passed_parms = ref $_[0] eq 'HASH' ? {%{+shift}} : {}; # copy parm hash 
5261     my %passed_parms = %{$passed_parms}; 
5264     for my $key ( keys %{$defaults} ) { 
5266             exists $passed_parms{$key} 
5267                 ? delete $passed_parms{$key} 
5268                 : $defaults->{$key}; 
5271     # Any leftover keys are bogus 
5272     for my $badkey ( keys %passed_parms ) { 
5273         my $sub = (caller(1))[3]; 
5274         $parms->{error_handler
}->( "Invalid option passed to $sub(): $badkey" ); 
5277     # If it's not a code ref, assume standard sort 
5278     if ( $parms->{sort_files
} && ( ref($parms->{sort_files
}) ne 'CODE' ) ) { 
5279         $parms->{sort_files
} = \
&sort_standard
; 
5284         my $start = reslash
( $_ ); 
5286             push @queue, ($start,undef,$start); 
5289             push @queue, (undef,$start,$start); 
5293     return ($parms,@queue); 
5297 sub _candidate_files 
{ 
5299     my $dirname = shift; 
5302     if ( !opendir $dh, $dirname ) { 
5303         $parms->{error_handler
}->( "$dirname: $!", $! + 0 ); 
5308     my $descend_filter = $parms->{descend_filter
}; 
5309     my $follow_symlinks = $parms->{follow_symlinks
}; 
5310     my $sort_sub = $parms->{sort_files
}; 
5312     for my $file ( grep { !exists $skip_dirs{$_} } readdir $dh ) { 
5315         my $fullpath = File
::Spec-
>catdir( $dirname, $file ); 
5316         if ( !$follow_symlinks ) { 
5317             next if -l 
$fullpath; 
5321         # Only do directory checking if we have a descend_filter 
5322         if ( $descend_filter ) { 
5323             if ( $has_stat ? (-d _
) : (-d 
$fullpath) ) { 
5324                 local $File::Next
::dir 
= $fullpath; 
5326                 next if not $descend_filter->(); 
5330             push( @newfiles, [ $dirname, $file, $fullpath ] ); 
5333             push( @newfiles, $dirname, $file, $fullpath ); 
5339         return map { @{$_} } sort $sort_sub @newfiles; 
5346 1; # End of File::Next