package App::BoolFindGrep::Grep;
use common::sense;
use charnames q(:full);
use Carp;
use English qw[-no_match_vars];
use IO::File;
use Moo;
use Text::Glob qw[glob_to_regex_string];
our $VERSION = '0.06'; # VERSION
has match_expr => (
is => q(rw),
isa => sub { die if @_ > 1; die if ref $_[0]; },
default => undef,
);
has patterns => ( is => q(rw), default => sub { {}; }, );
has greped => ( is => q(rw), default => sub { {}; }, );
has fixed_strings => (
is => q(rw),
isa => sub { ( $_[0] == 1 || $_[0] == 0 ) or die; },
default => 0,
);
has ignore_case => (
is => q(rw),
isa => sub { ( $_[0] == 1 || $_[0] == 0 ) or die; },
default => 0,
);
has line_regexp => (
is => q(rw),
isa => sub { ( $_[0] == 1 || $_[0] == 0 ) or die; },
default => 0,
);
has word_regexp => (
is => q(rw),
isa => sub { ( $_[0] == 1 || $_[0] == 0 ) or die; },
default => 0,
);
has glob_regexp => (
is => q(rw),
isa => sub { ( $_[0] == 1 || $_[0] == 0 ) or die; },
default => 0,
);
has content_found => (
is => q(rw),
default => sub { {}; },
);
sub process {
my $self = shift;
my @file = splice @_;
return unless defined $self->match_expr();
return unless %{ $self->patterns() };
$self->_process_patterns();
while ( my $file = shift @file ) {
croak sprintf q('%s': nonexistent file.), $file if !-e $file;
croak sprintf q('%s': irregular file.), $file if !-f $file;
croak sprintf q('%s': unreadable file.), $file if !-r $file;
if ( my $fh = IO::File->new( $file, q(r) ) ) {
while ( my $line = readline $fh ) {
chomp $line;
$self->_search( $line, $file, $fh->input_line_number(), );
}
}
else { croak $OS_ERROR; }
}
return 1;
} ## end sub process
sub _search {
my $self = shift;
my $string = shift;
my $file = shift;
my $line_number = shift;
foreach my $pattern ( keys %{ $self->patterns } ) {
my $re = $self->patterns->{$pattern};
$self->greped->{$file}{$pattern} //= 0;
if ( $string =~ m{$re} ) {
$self->greped->{$file}{$pattern}++;
$self->content_found->{$file}{$line_number} = $string;
}
}
return 1;
} ## end sub _search
sub _process_patterns {
my $self = shift;
die if $self->line_regexp() && $self->word_regexp();
foreach my $pattern ( keys %{ $self->patterns() } ) {
my $value = $pattern;
if ( $self->glob_regexp() ) {
$value = glob_to_regex_string($value);
}
else {
$value = quotemeta $value if $self->fixed_strings();
if ( $self->line_regexp() ) {
$value = sprintf q(\A%s\z), $value;
}
elsif ( $self->word_regexp() ) {
$value = sprintf q(\b%s\b), $value;
}
}
$value = $self->ignore_case() ? qr{$value}i : qr{$value};
$self->patterns->{$pattern} = $value;
} ## end foreach my $pattern ( keys ...)
return 1;
} ## end sub _process_patterns
no Moo;
__PACKAGE__->meta->make_immutable;
1;
__END__
=pod
=encoding utf8
=head1 NAME
App::BoolFindGrep::Grep - search lines matching a pattern.
=head1 VERSION
version 0.06
=head1 SYNOPSIS
=head1 DESCRIPTION
=head1 METHODS
=head2 greped
Hash reference to store parsing results.
=head2 match_expr
Scalar with original expression.
=head2 patterns
Hash reference with original operands and processed operands.
=head2 process
Does the work.
=head1 OPTIONS
=head1 ERRORS
=head1 DIAGNOSTICS
=head1 EXAMPLES
=head1 ENVIRONMENT
=head1 FILES
=head1 CAVEATS
=head1 BUGS
=head1 RESTRICTIONS
=head1 NOTES
=head1 AUTHOR
Ronaldo Ferreira de Lima aka jimmy <jimmy at gmail>.
=head1 HISTORY
=head1 SEE ALSO
=cut