/usr/share/perl5/Makefile/AST/Rule.pm is in libmakefile-parser-perl 0.215-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | package Makefile::AST::Rule;
use strict;
use warnings;
#use Smart::Comments;
use base 'Makefile::AST::Rule::Base';
use Makefile::AST::Command;
use List::MoreUtils;
__PACKAGE__->mk_accessors(qw{
stem target other_targets shell
});
# XXX: generate description for the rule
sub as_str ($) {
my $self = shift;
my $order_part = '';
## as_str: order_prereqs: $self->order_prereqs
if (@{ $self->order_prereqs }) {
$order_part = " | " . join(" ",@{ $self->order_prereqs });
}
### colon: $self->colon
my $str = $self->target . " " .
$self->colon . " " .
join(" ", @{ $self->normal_prereqs }) . "$order_part ; " .
join("", map { "[$_]" } @{ $self->commands });
$str =~ s/\n+//g;
$str =~ s/ +/ /g;
$str;
}
sub prepare_command ($$) {
my ($self, $ast, $raw_cmd,
$silent, $tolerant, $critical) = @_;
## $raw_cmd
my @tokens = $raw_cmd->elements;
# try to recognize modifiers:
my $modifier;
while (@tokens) {
if ($tokens[0]->class eq 'MDOM::Token::Whitespace') {
shift @tokens;
next;
}
last unless $tokens[0]->class eq 'MDOM::Token::Modifier';
$modifier = shift @tokens;
if ($modifier eq '+') {
# XXX is this the right thing to do?
$critical = 1;
} elsif ($modifier eq '-') {
$tolerant = 1;
} elsif ($modifier eq '@') {
$silent = 1;
} else {
die "Unknown modifier: $modifier";
}
}
local $. = $raw_cmd->lineno;
## TOKENS (BEFORE): @tokens
my $cmd = $ast->solve_refs_in_tokens(\@tokens);
### cmd after solve (1): $cmd
$cmd =~ s/^\s+|\s+$//gs;
return () if $cmd =~ /^(\\\n)*\\?$/s;
### cmd after modifier extraction: $cmd
### critical (+): $critical
### tolerant (-): $tolerant
### silent (@): $silent
if ($cmd =~ /(?<!\\)\n/sm) {
# it seems to be a canned sequence of commands
# XXX This is a hack to get things work
my @cmd = split /(?<!\\)\n/, $cmd;
my @ast_cmds;
for (@cmd) {
s/^\s+|\s+$//g;
require MDOM::Document::Gmake;
@tokens = MDOM::Document::Gmake::_tokenize_command($_);
### Reparsed cmd tokens: @tokens
my $cmd = MDOM::Command->new;
$cmd->__add_elements(@tokens);
# XXX upper-level's modifiers should take in
# effect in the recursive calls:
push @ast_cmds, $self->prepare_command($ast, $cmd, $silent, $tolerant, $critical);
}
return @ast_cmds;
}
while (1) {
if ($cmd =~ s/^\s*\+//) {
# XXX is this the right thing to do?
$critical = 1;
} elsif ($cmd =~ s/^\s*-//) {
$tolerant = 1;
} elsif ($cmd =~ s/^\s*\@//) {
$silent = 1;
} else {
last;
}
}
$cmd =~ s/^\s+|\s+$//gs;
return () if $cmd =~ /^(\\\n)*\\?$/s;
return Makefile::AST::Command->new({
silent => $silent,
tolerant => $tolerant,
critical => $critical,
content => $cmd,
target => $self->target,
});
}
sub prepare_commands ($$) {
my ($self, $ast) = @_;
my @normal_prereqs = @{ $self->normal_prereqs };
my @order_prereqs = @{ $self->order_prereqs };
## @normal_prereqs
## @order_prereqs
### run_commands: target: $self->target
### run_commands: Stem: $self->stem
$self->shell($ast->eval_var_value('SHELL'));
$ast->enter_pad;
$ast->add_auto_var(
'@' => [$self->target],
'<' => [$normal_prereqs[0]], # XXX better solutions?
'*' => [$self->stem],
'^' => [join(" ", List::MoreUtils::uniq(@normal_prereqs))],
'+' => [join(" ", @normal_prereqs)],
'|' => [join(" ", List::MoreUtils::uniq(@order_prereqs))],
# XXX add more automatic vars' defs here
);
### auto $*: $ast->get_var('*')
my @ast_cmds;
for my $cmd (@{ $self->commands }) {
$Makefile::AST::Evaluator::CmdRun = 1;
push @ast_cmds, $self->prepare_command($ast, $cmd);
}
$ast->leave_pad;
return @ast_cmds;
}
sub run_command ($$) {
my ($self, $ast_cmd) = @_;
my $cmd = $ast_cmd->content;
if (!$Makefile::AST::Evaluator::Quiet &&
(!$ast_cmd->silent || $Makefile::AST::Evaluator::JustPrint)) {
print "$cmd\n";
}
if (! $Makefile::AST::Evaluator::JustPrint) {
system($self->shell, '-c', $cmd);
if ($? != 0) {
my $retval = $? >> 8;
my $target = $ast_cmd->target;
if (!$Makefile::AST::Evaluator::IgnoreErrors &&
(!$ast_cmd->tolerant || $ast_cmd->critical)) {
# XXX better handling for tolerance
die "$::MAKE: *** [$target] Error $retval\n";
} else {
warn "$::MAKE: [$target] Error $retval (ignored)\n";
}
}
}
}
sub run_commands ($@) {
my $self = shift;
for my $ast_cmd (@_) {
$self->run_command($ast_cmd);
}
}
1;
|