Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / tools / perl-5.8.0 / lib / site_perl / 5.8.0 / CommandTerm / Rl.pm
CommitLineData
86530b38
AT
1package CommandTerm::Rl;
2
3require 5.004;
4use strict;
5use Term::ReadLine;
6use Term::ANSIColor;
7use FileHandle;
8use POSIX;
9use CommandTerm;
10
11use vars qw(
12 @ISA
13 %DerivedConfig
14 $TABDLY
15);
16
17@ISA = qw(CommandTerm);
18
19BEGIN {
20 %DerivedConfig = (
21 'dataFace' => 'clear',
22 'statusFace' => 'green',
23 'errorFace' => 'red',
24 );
25 $TABDLY = 0x00001800;
26}
27
28sub New {
29 my ($class, $name, $cfgfile, $app_config) = @_;
30 my $self = {};
31
32 bless $self, $class;
33
34 $self->InitSignalHandlers;
35
36 $self->Init($name, $cfgfile, $app_config, \%DerivedConfig);
37
38 $self->{'Termios'} = undef;
39 $self->{'OrigTermios'} = undef;
40 $self->{'ReadFD'} = '';
41 $self->{'WriteFD'} = '';
42 $self->{'ReadCallbacks'} = {};
43 $self->{'WriteCallbacks'} = {};
44 $self->{'GotInterrupt'} = 0;
45
46 $self->InitTerminal;
47 $self->InitReadLine;
48
49 return $self;
50}
51
52sub MainLoop {
53 my ($self) = @_;
54
55 my ($fileno, $fd_read, $fd_write);
56
57 while( 1 ) {
58
59 if( $self->GotInterrupt ) {
60 $self->HandleInterrupt;
61 $self->GotInterrupt(0);
62 }
63
64 if( $self->UpdatePrompt ) {
65 $self->CloseRedirection;
66 $self->fileevent(
67 *STDIN,
68 'readable' => sub{ $self->ReadLine->callback_read_char; }
69 );
70 $self->ReadLine->CallbackHandlerInstall(
71 $self->GetPrompt,
72 sub { $self->ProcessLine(@_); }
73 );
74 $self->UpdatePrompt(0);
75 }
76
77 next if select($fd_read = $self->ReadFD, $fd_write = $self->WriteFD, undef, 1.0) < 0;
78
79 foreach $fileno (keys %{ $self->ReadCallbacks }) {
80 &{ $self->{'ReadCallbacks'}{$fileno} } if vec($fd_read, $fileno, 1);
81 }
82
83 foreach $fileno (keys %{ $self->WriteCallbacks }) {
84 &{ $self->{'WriteCallbacks'}{$fileno} } if vec($fd_write, $fileno, 1);
85 }
86
87 }
88}
89
90sub Print {
91 my ($self, $how, @what) = @_;
92 my $what = join '', @what;
93
94 my $LOGFILE = $self->LogFH;
95 my $ReDirFH = $self->ReDirFH;
96
97 print $LOGFILE $what if defined($LOGFILE);
98
99 if( $ReDirFH ) {
100 print { $ReDirFH } $what;
101 } elsif( $ENV{'TERM'} and $ENV{'TERM'} ne 'vt100' ) {
102 print colored($what, $how);
103 } else {
104 print $what;
105 }
106}
107
108sub Title {
109 my ($self, $titlestr) = @_;
110
111 print STDOUT "\e]2;$titlestr\cg";
112}
113
114sub Icon {
115 my ($self, $iconstr) = @_;
116
117 print STDOUT "\e]1;$iconstr\cg";
118}
119
120sub clear {
121 my ($self) = @_;
122
123 $self->ReadLine->CallbackHandlerInstall('', sub {});
124 $self->ReadLine->call_function('clear-screen');
125 $self->Attribs->{'erase_empty_line'} = 1;
126 $self->ReadLine->stuff_char(ord("\n"));
127 $self->ReadLine->callback_read_char;
128 $self->Attribs->{'erase_empty_line'} = 0;
129}
130
131sub InitSignalHandlers {
132 my ($self) = @_;
133
134 $self->SUPER::InitSignalHandlers;
135 $SIG{'INT'} = sub { $self->GotInterrupt(1); };
136}
137
138sub InitTerminal {
139 my ($self) = @_;
140
141 STDOUT->autoflush(1);
142
143 my $Termios = POSIX::Termios->new;
144 my $OrigTermios = POSIX::Termios->new;
145
146 if( not $Termios->getattr(STDIN_FILENO) ) {
147 $self->PrintError("Error in getattr for STDIN(", STDIN_FILENO, "): $!\n ");
148 $self->PrintError("Weird terminal behavior may occur.\n");
149 return;
150 }
151
152 $OrigTermios->getattr(STDIN_FILENO);
153
154 $Termios->setlflag(($Termios->getlflag | ISIG) & ~ICANON);
155 $Termios->setoflag($Termios->getoflag & ~$TABDLY);
156 $Termios->setcc(VTIME, 1);
157 $Termios->setcc(VINTR, 3);
158 if( not $Termios->setattr(STDIN_FILENO, TCSANOW) ) {
159 $self->PrintError("Error in setattr for STDIN(", STDIN_FILENO, "): $!\n ");
160 $self->PrintError("Weird terminal behavior may occur.\n");
161 $Termios = undef;
162 }
163
164 $self->Termios($Termios);
165 $self->OrigTermios($OrigTermios);
166}
167
168sub InitReadLine {
169 my ($self) = @_;
170
171 $self->SUPER::InitReadLine;
172
173 if( $ENV{'TERM'} and $ENV{'TERM'} eq 'vt100' ) {
174 # turn off all ornaments if the terminal can't handle it
175 $self->ReadLine->ornaments(0);
176 } else {
177 # else set prompt to bold
178 $self->ReadLine->ornaments('md,me,,');
179 }
180}
181
182sub TogglePrompt {
183 my ($self) = @_;
184
185 &{ $self->TogglePromptCallback };
186
187 my $line = $self->Attribs->{'line_buffer'};
188
189 # This bit of magic just erases the current line, prompt included.
190 $self->ReadLine->CallbackHandlerInstall('', sub {});
191 $self->Attribs->{'erase_empty_line'} = 1;
192 $self->ReadLine->stuff_char(ord("\n"));
193 $self->ReadLine->callback_read_char;
194 $self->Attribs->{'erase_empty_line'} = 0;
195
196 # Install a new prompt and restore the old line
197 $self->ReadLine->CallbackHandlerInstall($self->GetPrompt, sub { $self->ProcessLine(@_); });
198 $self->ReadLine->insert_text($line);
199}
200
201sub HandleInterrupt {
202 my ($self) = @_;
203 my $ReadLine = $self->ReadLine;
204 my $Attribs = $self->Attribs;
205
206 if( $Attribs and $Attribs->{'end'} != 0 ) {
207 $ReadLine->modifying;
208 $ReadLine->delete_text;
209 $Attribs->{'point'} = $Attribs->{'end'} = 0;
210 $ReadLine->redisplay;
211 } else {
212 &{ $self->HandleInterruptCallback };
213 }
214}
215
216sub DefaultInterruptCallback {
217 my ($self) = @_;
218
219 print STDOUT "\n";
220 $self->UpdatePrompt(1);
221}
222
223sub fileevent {
224 my ($self, $fh, $readwrite, $func) = @_;
225
226 return unless defined($fh) and defined($readwrite);
227
228 my $fileno = fileno($fh);
229
230 if( $readwrite eq 'readable' ) {
231 if( defined($func) and ref($func) eq 'CODE' ) {
232 vec($self->{'ReadFD'}, $fileno, 1) = 1;
233 $self->{'ReadCallbacks'}{$fileno} = $func;
234 } else {
235 vec($self->{'ReadFD'}, $fileno, 1) = 0;
236 delete $self->{'ReadCallbacks'}{$fileno}
237 }
238 } elsif( $readwrite eq 'writable' ) {
239 if( defined($func) and ref($func) eq 'CODE' ) {
240 vec($self->{'WriteFD'}, $fileno, 1) = 1;
241 $self->{'WriteCallbacks'}{$fileno} = $func;
242 } else {
243 vec($self->{'WriteFD'}, $fileno, 1) = 0;
244 delete $self->{'WriteCallbacks'}{$fileno};
245 }
246 } else {
247 $self->PrintError("Bad mode to fileevent: '$readwrite'\n");
248 }
249}
250
251sub Shutdown {
252 my ($self) = @_;
253
254 $self->OrigTermios->setattr(STDIN_FILENO, TCSANOW) if $self->OrigTermios;
255}
256
257sub ProcessLine {
258 my ($self, $line) = @_;
259 my $ReadLine = $self->ReadLine;
260 my $Attribs = $self->Attribs;
261
262 # User typed Ctrl-D
263 unless( defined($line) ) {
264 print STDOUT "\n";
265 $self->quit;
266 }
267
268 $ReadLine->delete_text;
269 $Attribs->{'point'} = $Attribs->{'end'} = 0;
270
271 $self->UpdatePrompt(1);
272 $self->fileevent(*STDIN, 'readable' => '');
273 $ReadLine->callback_handler_remove;
274
275 $self->SUPER::ProcessLine($line);
276}
277
2781;