File Coverage

blib/lib/Psh/Strategy.pm
Criterion Covered Total %
statement 3 113 2.6
branch 0 38 0.0
condition 0 12 0.0
subroutine 1 18 5.5
pod 4 17 23.5
total 8 198 4.0


line stmt bran cond sub pod time code
1             package Psh::Strategy;
2              
3 1     1   7 use strict;
  1         2  
  1         1436  
4             require Psh::Util;
5             require Psh::OS;
6              
7             my %loaded=();
8             my %active=();
9             my @order=();
10              
11             my @lvl1order=();
12             my @lvl2order=();
13             my @lvl3order=();
14              
15             sub CONSUME_LINE() { 1; }
16             sub CONSUME_WORDS() { 2; } # currently unsupported
17             sub CONSUME_TOKENS() { 3; }
18              
19             #####################################################################
20             # Strategy List
21             #####################################################################
22              
23             sub get {
24 0     0 0   my $name= shift;
25 0           $name=ucfirst(lc($name));
26 0           my $obj;
27 0 0         unless (exists $loaded{$name}) {
28 0           my $tmp='Psh::Strategy::'.$name;
29 0           eval "use $tmp;";
30 0 0         if ($@) {
31 0           print STDERR "$@";
32 0           return undef;
33             }
34 0           eval {
35 0           $obj= "Psh::Strategy::$name"->new();
36             };
37 0 0 0       if ($@ or !$obj) {
38 0           print STDERR "$@";
39 0           return undef;
40             }
41 0           $loaded{$name}= $obj;
42 0           return $obj;
43             }
44 0           return $loaded{$name};
45             }
46              
47             sub remove {
48 0     0 0   my $name= shift;
49 0           @order= grep { $name ne $_->name } @order;
  0            
50 0 0         delete $active{$name} if $active{$name};
51 0           regenerate_cache();
52             }
53              
54             sub list {
55 0     0 0   return @order;
56             }
57              
58             sub available_list {
59 0     0 0   my %result= ();
60 0           foreach my $tmp (@INC) {
61 0           my $tmpdir= Psh::OS::catdir($tmp,'Psh','Strategy');
62 0           my @tmp= Psh::OS::glob('*.pm',$tmpdir);
63 0           foreach my $strat (@tmp) {
64 0           $strat=~s/\.pm$//;
65 0           $strat=lc($strat);
66 0           $result{$strat}=1;
67             }
68             }
69 0           return sort keys %result;
70             }
71              
72             sub find {
73 0     0 0   my $strategy= shift;
74 0           $strategy=lc($strategy);
75 0           for (my $i=0; $i<@order; $i++) {
76 0 0         if ($order[$i]->name() eq $strategy) {
77 0           return $i;
78             }
79             }
80 0           return -1;
81             }
82              
83             sub add {
84 0     0 0   my $str_obj= shift;
85 0           my $suggested_pos= shift;
86              
87 0           my $max= $#order; # add right before eval
88 0           my $min= 0;
89              
90 0           my @tmp= $str_obj->runs_before();
91 0 0         if (@tmp) {
92 0           foreach (@tmp) {
93 0           my $tmp= find($_);
94 0 0 0       $max= $tmp if $tmp<$max and $tmp>=0;
95             }
96             }
97 0           my $consumes= $str_obj->consumes();
98 0           for (my $i=0; $i<=$max; $i++) {
99 0 0         if ($order[$i]->consumes()<$consumes) {
100 0 0         $min= $i if $i>$min;
101 0           next;
102             }
103 0 0         if ($order[$i]->consumes()>$consumes) {
104 0 0         $max= $i if $i<$max;
105 0           last;
106             }
107             }
108 0           my $pos=$max;
109 0 0         if (defined $suggested_pos) {
110 0 0 0       if ($pos>=$min and $pos<=$max) {
111 0           $pos=$suggested_pos;
112             }
113             }
114 0           splice(@order,$pos,0,$str_obj);
115 0           $active{$str_obj->name}=1;
116 0           regenerate_cache();
117             }
118              
119             sub regenerate_cache {
120 0 0   0 0   @lvl1order= grep { $_ && $_->consumes() == CONSUME_LINE } @order;
  0            
121 0 0         @lvl2order= grep { $_ && $_->consumes() == CONSUME_WORDS } @order;
  0            
122 0 0         @lvl3order= grep { $_ && $_->consumes() == CONSUME_TOKENS } @order;
  0            
123             }
124              
125             sub parser_strategy_list {
126 0     0 0   return (\@lvl1order,\@lvl2order,\@lvl3order);
127             }
128              
129             sub parser_return_objects {
130 0     0 0   my @objs= map { get($_) } @_;
  0            
131 0           my @lvl1= grep { $_->consumes() == CONSUME_LINE } @objs;
  0            
132 0           my @lvl2= grep { $_->consumes() == CONSUME_WORDS } @objs;
  0            
133 0           my @lvl3= grep { $_->consumes() == CONSUME_TOKENS } @objs;
  0            
134 0           return (\@lvl1,\@lvl2,\@lvl3);
135             }
136              
137             sub setup_defaults {
138 0     0 0   require Psh::StrategyBunch;
139 0           foreach my $name (qw(bang perl brace built_in perlfunc executable eval)) {
140 0           my $tmpname= ucfirst($name);
141 0           my $obj;
142 0           eval {
143 0           $obj= "Psh::Strategy::$tmpname"->new();
144             };
145 0           push @order, $obj;
146 0           $loaded{$tmpname}= $obj;
147 0           $active{$name}= 1;
148             }
149 0 0         if ($^O =~ /darwin/i) {
150 0           splice(@order,@order-1,0, get('darwin_apps'));
151 0           $active{darwin_apps}=1;
152             }
153 0           regenerate_cache();
154             }
155              
156             sub active {
157 0     0 0   my $name= shift;
158 0           return $active{$name};
159             }
160              
161             #####################################################################
162             # Base class for strategies
163             #####################################################################
164              
165             sub new {
166 0     0 0   my $proto= shift;
167 0   0       my $class= ref($proto) || $proto;
168 0           my %init= ();
169 0           my $name;
170 0 0         if ($class=~/^Psh::Strategy::(.*)$/) {
171 0           $name= lc($1);
172 0 0         return $loaded{$name} if exists $loaded{$name};
173             } else {
174 0           die 'Strategies must be in Psh::Strategy:: namespace!';
175             }
176 0           my $self = \%init;
177 0           $self->{name}= $name;
178 0           bless $self, $class;
179 0           return $self;
180             }
181              
182             sub name {
183 0     0 0   return $_[0]->{name};
184             }
185              
186             sub runs_before {
187 0     0 1   return ();
188             }
189              
190             sub consumes {
191 0     0 1   die 'Abstract method';
192             }
193              
194             sub applies {
195 0     0 1   die 'Abstract method';
196             }
197              
198             sub execute {
199 0     0 1   die 'Abstract method';
200             }
201              
202             1;
203              
204             __END__