File Coverage

lib/Devel/Trepan/CmdProcessor/Command.pm
Criterion Covered Total %
statement 130 249 52.2
branch 9 16 56.2
condition 3 8 37.5
subroutine 27 37 72.9
pod 0 13 0.0
total 169 323 52.3


line stmt bran cond sub pod time code
1             # -*- coding: utf-8 -*-
2             # Copyright (C) 2011-2014 Rocky Bernstein <rocky@cpan.org>
3 12     12   34401 use Exporter;
  12         38  
  12         600  
4 12     12   79 use warnings;
  12         33  
  12         353  
5              
6 12     12   72 use Carp ();
  12         34  
  12         219  
7 12     12   76 use File::Basename;
  12         38  
  12         819  
8              
9 12     12   88 use rlib '../../..';
  12         32  
  12         155  
10 12     12   5672 use if !defined Devel::Trepan::CmdProcessor, Devel::Trepan::CmdProcessor;
  12         65  
  12         71  
11 12     12   455 use strict;
  12         34  
  12         463  
12              
13             package Devel::Trepan::CmdProcessor::Command;
14 12     12   74 no warnings 'redefine';
  12         26  
  12         491  
15 12     12   2537 use Devel::Trepan::Util qw(hash_merge);
  12         36  
  12         1807  
16              
17             # Because we use Exporter we want to silence:
18             # Use of inherited AUTOLOAD for non-method ... is deprecated
19             sub AUTOLOAD
20             {
21 223     223   688 my $name = our $AUTOLOAD;
22 223         1166 $name =~ s/.*:://; # lose package name
23 223         688 my $target = "DynaLoader::$name";
24 223         4630 goto &$target;
25             }
26              
27       0     sub DESTROY {}
28              
29 12     12   6044 use Array::Columnize;
  12         133808  
  12         1034  
30             sub declared ($) {
31 12     12   129 use constant 1.01; # don't omit this!
  12         337  
  12         1469  
32 13     13 0 49 my $name = shift;
33 13         64 $name =~ s/^::/main::/;
34 13         48 my $pkg = caller;
35 13 50       100 my $full_name = $name =~ /::/ ? $name : "${pkg}::$name";
36 13         1176 $constant::declared{$full_name};
37             }
38              
39 12     12   90 use vars qw(@CMD_VARS @EXPORT @ISA @CMD_ISA @ALIASES $HELP);
  12         33  
  12         1084  
40             BEGIN {
41 12     12   281 @CMD_VARS = qw($HELP $NAME $NEED_RUNNING $NEED_STACK @CMD_VARS);
42             }
43 12     12   73 use vars @CMD_VARS;
  12         38  
  12         1056  
44             @ISA = qw(Exporter);
45              
46             @CMD_ISA = qw(Devel::Trepan::CmdProcessor::Command);
47             @EXPORT = qw(&set_name @CMD_ISA $NEED_RUNNING
48             $NEED_STACK @CMD_VARS declared);
49              
50              
51 12     12   96 use constant NEED_STACK => 0; # We'll say that commands which need a stack
  12         36  
  12         3755  
52             # to run have to declare that and those that
53             # don't don't have to mention it.
54             unless (@ISA) {
55             eval <<'EOE';
56             use constant CATEGORY => 'Each command should set a category';
57             EOE
58             }
59              
60             # use constant NEED_RUNNING = 0; # We'll say that commands which need a a currently
61             # # running program. It's possible we have a stack even though
62             # # the program isn't running, e.g. there was an exception.
63             # # and we've faked the stack. (If this is not so, we can
64             # # don't need this and can simple use $NEED_STACK.
65              
66             $HELP = 'Each command should set help text text';
67              
68             sub set_name() {
69 500     500 0 2520 my ($pkg, $file, $line) = caller;
70 500         23667 lc(File::Basename::basename($file, '.pm'));
71             }
72              
73             sub new($$) {
74 447     447 0 1668 my($class, $proc) = @_;
75             my $self = {
76             proc => $proc,
77             class => $class,
78             dbgr => $proc->{dbgr}
79 447         6031 };
80 447         1291 my $base_prefix="Devel::Trepan::CmdProcessor::Command::";
81 447         1309 for my $field (@CMD_VARS) {
82 2235         5851 my $sigil = substr($field, 0, 1);
83 2235 50       7494 my $new_field = index('$@', $sigil) >= 0 ? substr($field, 1) : $field;
84 2235 100       5811 if ($sigil eq '$') {
    50          
85 1788         87396 $self->{lc $new_field} =
86             eval "\$${class}::${new_field} || \$${base_prefix}${new_field}";
87             } elsif ($sigil eq '@') {
88 447         20822 $self->{lc $new_field} = eval "[\@${class}::${new_field}]";
89             } else {
90 0         0 die "Woah - bad sigil in variable $field: $sigil ";
91             }
92             }
93 12     12   99 no warnings;
  12         40  
  12         805  
94 447         20199 my @ary = eval "${class}::ALIASES()";
95 447 100       2653 $self->{aliases} = @ary ? [@ary] : [];
96 12     12   105 no strict 'refs';
  12         38  
  12         8617  
97 447     1   25733 *{"${class}::Category"} = eval "sub { ${class}::CATEGORY() }";
  447     1   2978  
  1     0   1480  
  1         1568  
  1         1481  
  1         1465  
  1         1428  
  1         1455  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  1         1799  
  1         1283  
  1         1384  
  1         1345  
  1         1385  
  1         1337  
  1         1338  
  1         1487  
  1         1333  
  1         2045  
  1         1359  
  1         906  
  1         2031  
  1         1270  
  1         1273  
  1         1319  
  1         844  
  1         1409  
  1         1451  
  1         1268  
  1         859  
  1         1412  
  1         1394  
  1         1314  
  1         920  
  1         1406  
  1         1604  
  1         1377  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
98 447     0   24476 *{"${class}::name"} = eval "sub { \$${class}::NAME }";
  447     0   2800  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  7         2969  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
99 447         19927 my $short_help = eval "${class}::SHORT_HELP()";
100 447 50       2540 $self->{short_help} = $short_help if $short_help;
101 447         1290 bless $self, $class;
102 447         10665 $self;
103             }
104              
105             # List command names aligned in columns
106             sub columnize_commands($$$) {
107 2     2 0 7 my ($self, $commands, $opts) = @_;
108 2         7 my $width = $self->{settings}{maxwidth};
109 2 50       8 $opts = {} unless $opts;
110 2         23 $opts = hash_merge($opts, {displaywidth => $width,
111             colsep => ' ',
112             ljust => 1,
113             lineprefix => ' '});
114 2         12 my $r = Array::Columnize::columnize($commands, $opts);
115 2         5455 chomp $r;
116 2         16 return $r;
117             }
118              
119             sub columnize_numbers($$) {
120 0     0 0 0 my ($self, $commands) = @_;
121 0         0 my $width = $self->settings->{maxwidth};
122 0         0 my $r = Array::Columnize::columnize($commands,
123             {displaywidth => $width,
124             colsep => ', ',
125             ljust => 0,
126             lineprefix => ' '});
127 0         0 chomp $r;
128 0         0 return $r;
129             }
130              
131             # FIXME: probably there is a way to do the delegation to proc methods
132             # without having type it all out.
133              
134             sub confirm($$$) {
135 0     0 0 0 my ($self, $message, $default) = @_;
136 0         0 $self->{proc}->confirm($message, $default);
137             }
138              
139             sub errmsg($$;$) {
140 2     2 0 6 my ($self, $message, $opts) = @_;
141 2   50     11 $opts ||= {};
142 2         11 $self->{proc}->errmsg([$message], $opts);
143             }
144              
145             # sub obj_const($$$) {
146             # my ($self, $obj, $name) = @_;
147             # $obj->class.const_get($name)
148             # }
149              
150             # Convenience short-hand for $self->{proc}->msg
151             sub msg($$;$) {
152 3     3 0 7 my ($self, $message, $opts) = @_;
153 3   50     17 $opts ||= {};
154 3         16 $self->{proc}->msg($message, $opts);
155             }
156              
157             # Convenience short-hand for $self->{proc}->msg_nocr
158             sub msg_nocr($$;$) {
159 0     0 0 0 my ($self, $message, $opts) = @_;
160 0   0     0 $opts ||= {};
161 0         0 $self->{proc}->msg_nocr($message, $opts);
162             }
163              
164             # The method that implements the debugger command.
165             sub run {
166 0     0 0 0 Carp::croak "RuntimeError: You need to define this method elsewhere";
167             }
168              
169             sub section($$;$) {
170 2     2 0 5 my ($self, $message, $opts) = @_;
171 2   50     11 $opts ||={};
172 2         11 $self->{proc}->section($message, $opts);
173             }
174              
175             sub settings($) {
176 0     0 0   my ($self) = @_;
177 0           $self->{proc}{settings};
178             }
179              
180             sub short_help($) {
181 0     0 0   my ($self) = @_;
182 0 0         return $self->{short_help} if defined $self->{short_help};
183 0           my @ary = split("\n", $self->{help});
184 0           $self->{short_help} = $ary[0];
185             }
186              
187             unless (caller) {
188             require Devel::Trepan::CmdProcessor::Mock;
189             my $proc = Devel::Trepan::CmdProcessor::Mock::setup();
190             my $cmd = Devel::Trepan::CmdProcessor::Command->new($proc);
191             # print $cmd->short_help, "\n";
192             # print $cmd, "\n";
193             # print $cmd->Category, "\n";
194             # print $cmd->{name}, "\n";
195             # print $cmd->MIN_ARGS, "\n";
196             # p cmd.complete('aa');
197             }
198              
199             1;