File Coverage

lib/Devel/Trepan/Interface/Script.pm
Criterion Covered Total %
statement 57 90 63.3
branch 3 18 16.6
condition 1 3 33.3
subroutine 15 23 65.2
pod 0 7 0.0
total 76 141 53.9


line stmt bran cond sub pod time code
1             # -*- coding: utf-8 -*-
2             # This line is for testing purposes \
3             # Copyright (C) 2011-2012 Rocky Bernstein <rocky@cpan.org>
4              
5             # Module for reading debugger scripts
6              
7 13     13   18955 use warnings; no warnings 'redefine';
  13     13   34  
  13         409  
  13         76  
  13         37  
  13         470  
8 13     13   85 use Exporter;
  13         48  
  13         604  
9 13     13   7583 use IO::File;
  13         17424  
  13         1536  
10              
11 13     13   94 use rlib '../../..';
  13         39  
  13         81  
12              
13             package Devel::Trepan::Interface::Script;
14             our (@ISA);
15 13     13   5278 use if !@ISA, Devel::Trepan::Interface;
  13         45  
  13         110  
16 13     13   1464 use if !@ISA, Devel::Trepan::Interface::ComCodes;
  13         35  
  13         71  
17 13     13   1106 use Devel::Trepan::IO::Input;
  13         47  
  13         1392  
18 13     13   5332 use Devel::Trepan::IO::StringArray;
  13         43  
  13         390  
19 13     13   103 use Devel::Trepan::Util qw(hash_merge);
  13         35  
  13         1034  
20 13     13   78 use strict;
  13         38  
  13         298  
21 13     13   73 use vars qw(@EXPORT @ISA);
  13         31  
  13         834  
22             @ISA = qw(Devel::Trepan::Interface Exporter);
23              
24 13         10675 use constant DEFAULT_OPTS => {
25             abort_on_error => 1,
26             confirm_val => 0,
27             verbose => 0
28 13     13   110 };
  13         36  
29            
30             sub new
31             {
32 1     1   120 my ($class, $script_name, $out, $opts) = @_;
33 1 50       4 $opts = {} unless defined $opts;
34              
35 1         5 $opts = hash_merge($opts, DEFAULT_OPTS);
36              
37 1         3 my $self = {};
38             # FIXME if $script_name is invalid, we get undef $fh and then
39             # Interface->new uses STDIN.
40 1         8 my $fh = IO::File->new($script_name, 'r');
41 1         105 $self = Devel::Trepan::Interface->new($fh, $out, $opts);
42 1         6 $self->{script_name} = $script_name;
43 1         3 $self->{input_lineno} = 0;
44 1         3 $self->{buffer_output} = [];
45 1 50 33     6 unless ($opts->{verbose} or $out) {
46 1         6 $self->{output} = Devel::Trepan::IO::StringArrayOutput->new($self->{buffer_output});
47             }
48 1         6 bless $self, $class;
49 1         3 $self;
50             }
51              
52              
53             # Closes input only.
54             sub close($)
55             {
56 0     0   0 my $self = shift;
57 0         0 $self->{input}->close;
58             }
59              
60             # Called when a dangerous action is about to be done, to make
61             # sure it's okay.
62             #
63             # Could look also look for interactive input and
64             # use that. For now, though we'll simplify.
65             sub confirm($$$)
66             {
67 0     0 0 0 my ($self, $prompt, $default) = @_;
68 0         0 $self->{opts}{default_confirm};
69             }
70              
71             # Common routine for reporting debugger error messages.
72             #
73             sub errmsg($$;$)
74             {
75 0     0 0 0 my ($self, $msg, $prefix) = @_;
76 0 0       0 $prefix = '*** ' unless defined $prefix;
77             # self.verbose shows lines so we don't have to duplicate info
78             # here. Perhaps there should be a 'terse' mode to never show
79             # position info.
80 0         0 my $mess = sprintf "%s%s", $prefix, $msg;
81              
82 0 0       0 if ($self->{opts}{verbose}) {
83             my $location = sprintf("%s:%s: Error in source command file",
84             $self->{script_name},
85 0         0 $self->{input_lineno});
86 0         0 $mess = sprintf("%s:\n%s%s", $prefix, $location, $prefix, $msg);
87             }
88            
89 0         0 $self->msg($mess);
90             # FIXME: should we just set a flag and report eof? to be more
91             # consistent with File and IO?
92 0 0       0 die if $self->{opts}{abort_on_error};
93             }
94              
95             sub msg($$)
96             {
97 0     0 0 0 my ($self, $msg) = @_;
98             ## FIXME: there must be a better way to do this...
99 0 0       0 if ($self->{output}->isa('Devel::Trepan::IO::TCPServer')) {
100 0         0 $self->{output}->writeline(PRINT . $msg);
101             } else {
102 0         0 $self->{output}->writeline($msg);
103             }
104             }
105              
106             sub is_interactive() { 0; }
107              
108             sub is_closed($)
109             {
110 0     0 0 0 my($self) = shift;
111 0         0 $self->{input}->eof;
112             }
113              
114             sub has_completion() { 0; }
115 0     0 0 0 sub has_term_readline($) { 0; }
116              
117             # Script interface to read a command. `prompt' is a parameter for
118             # compatibilty and is ignored.
119             sub read_command($;$)
120             {
121 0     0 0 0 my ($self, $prompt)=@_;
122 0 0       0 $prompt = '' unless defined $prompt;
123 0         0 $self->{input_lineno} += 1;
124 0         0 my $last = $self->readline();
125 0         0 my $line = '';
126 0         0 while ('\\' eq substr($last, -1)) {
127 0         0 $line .= substr($last, 0, -1) . "\n";
128 0         0 $last = $self->readline();
129             }
130 0         0 $line .= $last;
131              
132 0 0       0 if ($self->{opts}{verbose}) {
133             my $location = sprintf("%s line %s",
134             $self->{script_name},
135 0         0 $self->{input_lineno});
136 0         0 my $mess = sprintf '+ %s: %s', $location, $line;
137 0         0 $self->msg($mess);
138             }
139             # Do something with history?
140 0         0 return $line;
141             }
142              
143             # Script interface to read a line. `prompt' is a parameter for
144             # compatibilty and is ignored.
145             #
146             # Could decide make this look for interactive input?
147             sub readline($;$)
148             {
149 1     1   5 my ($self, $prompt) = @_;
150 1 50       3 $prompt = '' unless defined $prompt;
151 1         27 my $line = $self->{input}->getline;
152 1         41 chomp $line;
153 1         3 return $line;
154             }
155              
156             sub remove_history($;$)
157       0 0   {
158             }
159              
160             # sub DESTROY($)
161             # {
162             # my $self = shift;
163             # Devel::Trepan::Interface::DESTROY($self);
164             # }
165              
166             # Demo
167             unless (caller) {
168             my $intf = __PACKAGE__->new(__FILE__);
169             my $line = $intf->readline();
170             print "Line read: ${line}\n";
171             $line = $intf->read_command();
172             print "Second Line read: ${line}\n";
173             }
174              
175             1;