App-PTP

 view release on metacpan or  search on metacpan

lib/App/PTP/Commands.pm  view on Meta::CPAN

# process($file_name, \@pipeline, \%options, \@content, $missing_final_sep)
# Applies all the stage of the pipeline on the given content (which is modified
# in place).
sub process {  ## no critic (RequireArgUnpacking)
               # We are unpacking the arguments but later we are taking a reference on $_[0]
  my ($file_name, $pipeline, $options, $content, $missing_final_separator) = @_;
  if ($options->{debug_mode}) {
    # For long files, we print only the first and last lines.
    my @debug_content = @$content;
    Readonly::Scalar my $NB_DEBUG_LINES => 4;
    Readonly::Scalar my $MAX_LINES_TO_PRINT => 10;
    my $omit_msg = sprintf '... (%d lines omitted)', (@$content - ($NB_DEBUG_LINES * 2));
    splice @debug_content, $NB_DEBUG_LINES, -$NB_DEBUG_LINES, $omit_msg
        if @$content > $MAX_LINES_TO_PRINT;
    if (ref($file_name)) {
      print "Processing $${file_name} with content: ".Dumper(\@debug_content);
    } else {
      print "Processing '${file_name}' with content: ".Dumper(\@debug_content);
    }
    print 'Has final separator: '.($missing_final_separator ? 'false' : 'true')."\n";
  }
  prepare_perl_env($file_name, $options);
  @markers = (0) x scalar(@$content);
  my $markers = \@markers;
  @content_stack = ();
  for my $stage (@$pipeline) {
    my ($command, $code, $modes, @args) = @$stage;
    $N_setter->set(scalar(@$content));
    $modes->{missing_final_separator} = $missing_final_separator;
    $modes->{file_name_ref} = \$_[0];  # this is an alias to the passed value.
    if ($options->{debug_mode}) {
      local $Data::Dumper::Indent = 0;
      printf "Executing command: %s(%s).\n", $command, join(', ', map { Dumper($_) } @args);
    }
    &$code($content, $markers, $modes, $options, @args);
  }
}

sub base_prepare_re {
  my ($re, $modes) = @_;
  if ($modes->{quote_regex}) {
    $re = quotemeta($re);
  }
  if (not $modes->{case_sensitive}) {
    $re = '(?i)'.$re;
  }
  return $re;
}

# prepare_re('re', \%options)
# Applies the modal option on the given regex.
# This function is not exported.
sub prepare_re {
  my ($re, $modes) = @_;
  $re = base_prepare_re($re, $modes);
  my $r;
  if ($modes->{regex_engine} ne 'perl') {
    # Some play to correctly escape whatever special characters might be in the
    # regex while preserving its semantics. This relies on the fact that the
    # 'Terse' option of Data::Dumper is set in the main program.
    # The regex-engine variable has been validated in the Args module.
    my $str_re = Dumper($re);
    my $engine = 're::engine::'.$modes->{regex_engine};
    # We could the safe to avoid this perlcritic warning but we are not actually
    # executing code here, so the safe is not needed (and we would need to find
    # variable names that are guaranteed not to collide with user code).
    $r = eval "use ${engine}; \$re = $str_re; qr/\$re/s";  ## no critic (ProhibitStringyEval)
    if ($@) {
      chomp($@);
      die "FATAL: Cannot use the specified regex engine: ${@}\n";
    }
  } else {
    $r = qr/$re/s;
  }
  return $r;
}

sub quote_for_re {
  my ($text, $modes) = @_;
  if ($modes->{quote_regex}) {
    return quotemeta($text);
  } else {
    # We quote just the '{' or '}' characters.
    return $text =~ s/(\{|\})/\\$1/gr;
  }
}

sub prepare_re2 {
  my ($re, $modes) = @_;
  $re = quote_for_re($re, $modes);
  if (not $modes->{case_sensitive}) {
    $re = '(?i)'.$re;
  }
  my $use_statement = '';
  if ($modes->{regex_engine} ne 'perl') {
    $use_statement = "use re::engine::$modes->{regex_engine};";
  }
  return ($use_statement, "{${re}}");
}

# This interpolate str in the Perl env (unless -Q is in effect).
sub maybe_interpolate {
  my ($str, $modes, $options, $command) = @_;
  if (not $modes->{quote_regex}) {
    $str = eval_in_safe_env("<<\"PTP_EOF_WORD\"\n${str}\nPTP_EOF_WORD\n", $options);
    die "FATAL: Cannot eval string for --${command}: ${@}\n" if $@;
    chomp($str);
  }
  return $str;
}

sub do_grep {
  my ($content, $markers, $modes, $options, $re) = @_;
  my ($use_stmt, $quoted_re) = prepare_re2($re, $modes);
  print "\$re = ${quoted_re}\n" if $options->{debug_mode};
  my $conjunction = $modes->{inverse_match} ? 'if' : 'unless';
  my $wrapped = get_code_in_safe_env("{; ${use_stmt} undef \$_ ${conjunction} m ${quoted_re} }",
    $options, '--grep');
  local $. = 0;
  map {
    $m_setter->set(\$markers->[$.]);



( run in 0.965 second using v1.01-cache-2.11-cpan-39bf76dae61 )