This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Merge branch 'blead' of ssh://perl5.git.perl.org/gitroot/perl into blead
[perl5.git] / cpan / Term-Cap / Cap.pm
CommitLineData
a0d0e21e 1package Term::Cap;
2ef86165 2
0ca33fed
JS
3# Since the debugger uses Term::ReadLine which uses Term::Cap, we want
4# to load as few modules as possible. This includes Carp.pm.
085f5cc4
RGS
5sub carp
6{
0ca33fed
JS
7 require Carp;
8 goto &Carp::carp;
9}
10
085f5cc4
RGS
11sub croak
12{
0ca33fed
JS
13 require Carp;
14 goto &Carp::croak;
15}
16
7cae2445 17use strict;
85e6fe83 18
d2492938 19use vars qw($VERSION $VMS_TERMCAP);
7cae2445 20use vars qw($termpat $state $first $entry);
2ef86165 21
b9411ff2 22$VERSION = '1.13';
b75c8c73 23
e14c93b3
DL
24# Version undef: Thu Dec 14 20:02:42 CST 1995 by sanders@bsdi.com
25# Version 1.00: Thu Nov 30 23:34:29 EST 2000 by schwern@pobox.com
26# [PATCH] $VERSION crusade, strict, tests, etc... all over lib/
27# Version 1.01: Wed May 23 00:00:00 CST 2001 by d-lewart@uiuc.edu
28# Avoid warnings in Tgetent and Tputs
2ef86165
JS
29# Version 1.02: Sat Nov 17 13:50:39 GMT 2001 by jns@gellyfish.com
30# Altered layout of the POD
31# Added Test::More to PREREQ_PM in Makefile.PL
32# Fixed no argument Tgetent()
2ab0daaa
JS
33# Version 1.03: Wed Nov 28 10:09:38 GMT 2001
34# VMS Support from Charles Lane <lane@DUPHY4.Physics.Drexel.Edu>
2608af5d
JS
35# Version 1.04: Thu Nov 29 16:22:03 GMT 2001
36# Fixed warnings in test
7cae2445
JS
37# Version 1.05: Mon Dec 3 15:33:49 GMT 2001
38# Don't try to fall back on infocmp if it's not there. From chromatic.
d2492938
JS
39# Version 1.06: Thu Dec 6 18:43:22 GMT 2001
40# Preload the default VMS termcap from Charles Lane
41# Don't carp at setting OSPEED unless warnings are on.
8bb18277
JS
42# Version 1.07: Wed Jan 2 21:35:09 GMT 2002
43# Sanity check on infocmp output from Norton Allen
44# Repaired INSTALLDIRS thanks to Michael Schwern
0ca33fed
JS
45# Version 1.08: Sat Sep 28 11:33:15 BST 2002
46# Late loading of 'Carp' as per Michael Schwern
47# Version 1.09: Tue Apr 20 12:06:51 BST 2004
48# Merged in changes from and to Core
49# Core (Fri Aug 30 14:15:55 CEST 2002):
50# Cope with comments lines from 'infocmp' from Brendan O'Dea
51# Allow for EBCDIC in Tgoto magic test.
085f5cc4
RGS
52# Version 1.10: Thu Oct 18 16:52:20 BST 2007
53# Don't use try to use $ENV{HOME} if it doesn't exist
54# Give Win32 'dumb' if TERM isn't set
55# Provide fallback 'dumb' termcap entry as last resort
305a762d
JS
56# Version 1.11: Thu Oct 25 09:33:07 BST 2007
57# EBDIC fixes from Chun Bing Ge <gecb@cn.ibm.com>
76ea3a66
JS
58# Version 1.12: Sat Dec 8 00:10:21 GMT 2007
59# QNX test fix from Matt Kraai <kraai@ftbfs.org>
b9411ff2
DH
60# Version 1.13: Thu Dec 22 22:21:09 GMT 2011
61# POD error fix from Domin Hargreaves <dom@earth.li>
76ea3a66 62#
cb1a09d0
AD
63# TODO:
64# support Berkeley DB termcaps
cb1a09d0
AD
65# force $FH into callers package?
66# keep $FH in object at Tgetent time?
67
68=head1 NAME
69
70Term::Cap - Perl termcap interface
71
72=head1 SYNOPSIS
73
74 require Term::Cap;
75 $terminal = Tgetent Term::Cap { TERM => undef, OSPEED => $ospeed };
76 $terminal->Trequire(qw/ce ku kd/);
77 $terminal->Tgoto('cm', $col, $row, $FH);
78 $terminal->Tputs('dl', $count, $FH);
79 $terminal->Tpad($string, $count, $FH);
80
81=head1 DESCRIPTION
82
83These are low-level functions to extract and use capabilities from
84a terminal capability (termcap) database.
85
2ef86165
JS
86More information on the terminal capabilities will be found in the
87termcap manpage on most Unix-like systems.
cb1a09d0 88
2ef86165 89=head2 METHODS
cb1a09d0 90
cb1a09d0
AD
91The output strings for B<Tputs> are cached for counts of 1 for performance.
92B<Tgoto> and B<Tpad> do not cache. C<$self-E<gt>{_xx}> is the raw termcap
93data and C<$self-E<gt>{xx}> is the cached version.
94
95 print $terminal->Tpad($self->{_xx}, 1);
96
97B<Tgoto>, B<Tputs>, and B<Tpad> return the string and will also
98output the string to $FH if specified.
99
cb1a09d0
AD
100
101=cut
102
d2492938
JS
103# Preload the default VMS termcap.
104# If a different termcap is required then the text of one can be supplied
105# in $Term::Cap::VMS_TERMCAP before Tgetent is called.
106
085f5cc4
RGS
107if ( $^O eq 'VMS' )
108{
109 chomp( my @entry = <DATA> );
110 $VMS_TERMCAP = join '', @entry;
d2492938
JS
111}
112
cb1a09d0 113# Returns a list of termcap files to check.
d2492938 114
085f5cc4
RGS
115sub termcap_path
116{ ## private
cb1a09d0 117 my @termcap_path;
085f5cc4 118
cb1a09d0 119 # $TERMCAP, if it's a filespec
085f5cc4
RGS
120 push( @termcap_path, $ENV{TERMCAP} )
121 if (
122 ( exists $ENV{TERMCAP} )
123 && (
124 ( $^O eq 'os2' || $^O eq 'MSWin32' || $^O eq 'dos' )
125 ? $ENV{TERMCAP} =~ /^[a-z]:[\\\/]/is
126 : $ENV{TERMCAP} =~ /^\//s
127 )
128 );
129 if ( ( exists $ENV{TERMPATH} ) && ( $ENV{TERMPATH} ) )
130 {
131
132 # Add the users $TERMPATH
133 push( @termcap_path, split( /(:|\s+)/, $ENV{TERMPATH} ) );
cb1a09d0 134 }
085f5cc4
RGS
135 else
136 {
137
138 # Defaults
139 push( @termcap_path,
140 exists $ENV{'HOME'} ? $ENV{'HOME'} . '/.termcap' : undef,
141 '/etc/termcap', '/usr/share/misc/termcap', );
a687059c 142 }
d2492938 143
cb1a09d0 144 # return the list of those termcaps that exist
085f5cc4 145 return grep { defined $_ && -f $_ } @termcap_path;
748a9306
LW
146}
147
c0e71a27
DH
148=over 4
149
2ef86165
JS
150=item B<Tgetent>
151
152Returns a blessed object reference which the user can
153then use to send the control strings to the terminal using B<Tputs>
154and B<Tgoto>.
155
156The function extracts the entry of the specified terminal
157type I<TERM> (defaults to the environment variable I<TERM>) from the
158database.
159
160It will look in the environment for a I<TERMCAP> variable. If
161found, and the value does not begin with a slash, and the terminal
162type name is the same as the environment string I<TERM>, the
163I<TERMCAP> string is used instead of reading a termcap file. If
164it does begin with a slash, the string is used as a path name of
165the termcap file to search. If I<TERMCAP> does not begin with a
166slash and name is different from I<TERM>, B<Tgetent> searches the
167files F<$HOME/.termcap>, F</etc/termcap>, and F</usr/share/misc/termcap>,
168in that order, unless the environment variable I<TERMPATH> exists,
169in which case it specifies a list of file pathnames (separated by
170spaces or colons) to be searched B<instead>. Whenever multiple
171files are searched and a tc field occurs in the requested entry,
172the entry it names must be found in the same file or one of the
173succeeding files. If there is a C<:tc=...:> in the I<TERMCAP>
174environment variable string it will continue the search in the
175files as above.
176
177The extracted termcap entry is available in the object
178as C<$self-E<gt>{TERMCAP}>.
179
180It takes a hash reference as an argument with two optional keys:
181
182=over 2
183
184=item OSPEED
185
186The terminal output bit rate (often mistakenly called the baud rate)
187for this terminal - if not set a warning will be generated
188and it will be defaulted to 9600. I<OSPEED> can be be specified as
189either a POSIX termios/SYSV termio speeds (where 9600 equals 9600) or
190an old DSD-style speed ( where 13 equals 9600).
191
192
193=item TERM
194
195The terminal type whose termcap entry will be used - if not supplied it will
196default to $ENV{TERM}: if that is not set then B<Tgetent> will croak.
197
198=back
199
200It calls C<croak> on failure.
201
202=cut
203
085f5cc4
RGS
204sub Tgetent
205{ ## public -- static method
cb1a09d0 206 my $class = shift;
2ef86165
JS
207 my ($self) = @_;
208
209 $self = {} unless defined $self;
210 bless $self, $class;
211
085f5cc4
RGS
212 my ( $term, $cap, $search, $field, $max, $tmp_term, $TERMCAP );
213 local ( $termpat, $state, $first, $entry ); # used inside eval
cb1a09d0
AD
214 local $_;
215
216 # Compute PADDING factor from OSPEED (to be used by Tpad)
085f5cc4
RGS
217 if ( !$self->{OSPEED} )
218 {
219 if ($^W)
220 {
221 carp "OSPEED was not set, defaulting to 9600";
d2492938 222 }
085f5cc4 223 $self->{OSPEED} = 9600;
cb1a09d0 224 }
085f5cc4
RGS
225 if ( $self->{OSPEED} < 16 )
226 {
227
228 # delays for old style speeds
229 my @pad = (
230 0, 200, 133.3, 90.9, 74.3, 66.7, 50, 33.3,
231 16.7, 8.3, 5.5, 4.1, 2, 1, .5, .2
232 );
233 $self->{PADDING} = $pad[ $self->{OSPEED} ];
cb1a09d0 234 }
085f5cc4
RGS
235 else
236 {
237 $self->{PADDING} = 10000 / $self->{OSPEED};
cb1a09d0
AD
238 }
239
085f5cc4
RGS
240 unless ( $self->{TERM} )
241 {
242 if ( $ENV{TERM} )
243 {
244 $self->{TERM} = $ENV{TERM} ;
245 }
246 else
247 {
248 if ( $^O eq 'Win32' )
249 {
250 $self->{TERM} = 'dumb';
251 }
252 else
253 {
254 croak "TERM not set";
255 }
256 }
257 }
258
259 $term = $self->{TERM}; # $term is the term type we are looking for
cb1a09d0
AD
260
261 # $tmp_term is always the next term (possibly :tc=...:) we are looking for
262 $tmp_term = $self->{TERM};
cb1a09d0 263
085f5cc4
RGS
264 # protect any pattern metacharacters in $tmp_term
265 $termpat = $tmp_term;
266 $termpat =~ s/(\W)/\\$1/g;
267
268 my $foo = ( exists $ENV{TERMCAP} ? $ENV{TERMCAP} : '' );
cb1a09d0
AD
269
270 # $entry is the extracted termcap entry
085f5cc4
RGS
271 if ( ( $foo !~ m:^/:s ) && ( $foo =~ m/(^|\|)${termpat}[:|]/s ) )
272 {
273 $entry = $foo;
cb1a09d0
AD
274 }
275
2ef86165 276 my @termcap_path = termcap_path();
e66fb0c2 277
085f5cc4 278 unless ( @termcap_path || $entry )
e66fb0c2 279 {
2ab0daaa 280
085f5cc4
RGS
281 # last resort--fake up a termcap from terminfo
282 local $ENV{TERM} = $term;
283
284 if ( $^O eq 'VMS' )
285 {
286 $entry = $VMS_TERMCAP;
7cae2445 287 }
085f5cc4
RGS
288 else
289 {
290 if ( grep { -x "$_/infocmp" } split /:/, $ENV{PATH} )
291 {
292 eval {
293 my $tmp = `infocmp -C 2>/dev/null`;
294 $tmp =~ s/^#.*\n//gm; # remove comments
295 if ( ( $tmp !~ m%^/%s )
296 && ( $tmp =~ /(^|\|)${termpat}[:|]/s ) )
297 {
298 $entry = $tmp;
299 }
300 };
301 }
302 else
303 {
304 # this is getting desperate now
305 if ( $self->{TERM} eq 'dumb' )
306 {
307 $entry = 'dumb|80-column dumb tty::am::co#80::bl=^G:cr=^M:do=^J:sf=^J:';
308 }
309 }
7cae2445 310 }
2f6e8d9f 311 }
e66fb0c2 312
cb1a09d0
AD
313 croak "Can't find a valid termcap file" unless @termcap_path || $entry;
314
085f5cc4
RGS
315 $state = 1; # 0 == finished
316 # 1 == next file
317 # 2 == search again
cb1a09d0 318
085f5cc4 319 $first = 0; # first entry (keeps term name)
cb1a09d0 320
085f5cc4 321 $max = 32; # max :tc=...:'s
cb1a09d0 322
085f5cc4
RGS
323 if ($entry)
324 {
325
326 # ok, we're starting with $TERMCAP
327 $first++; # we're the first entry
328 # do we need to continue?
329 if ( $entry =~ s/:tc=([^:]+):/:/ )
330 {
331 $tmp_term = $1;
332
333 # protect any pattern metacharacters in $tmp_term
334 $termpat = $tmp_term;
335 $termpat =~ s/(\W)/\\$1/g;
336 }
337 else
338 {
339 $state = 0; # we're already finished
340 }
cb1a09d0
AD
341 }
342
343 # This is eval'ed inside the while loop for each file
344 $search = q{
54310121 345 while (<TERMCAP>) {
cb1a09d0
AD
346 next if /^\\t/ || /^#/;
347 if ($_ =~ m/(^|\\|)${termpat}[:|]/o) {
348 chomp;
349 s/^[^:]*:// if $first++;
350 $state = 0;
54310121 351 while ($_ =~ s/\\\\$//) {
352 defined(my $x = <TERMCAP>) or last;
353 $_ .= $x; chomp;
354 }
cb1a09d0 355 last;
748a9306 356 }
cb1a09d0 357 }
55497cff 358 defined $entry or $entry = '';
e14c93b3 359 $entry .= $_ if $_;
cb1a09d0 360 };
748a9306 361
085f5cc4
RGS
362 while ( $state != 0 )
363 {
364 if ( $state == 1 )
365 {
366
367 # get the next TERMCAP
368 $TERMCAP = shift @termcap_path
369 || croak "failed termcap lookup on $tmp_term";
370 }
371 else
372 {
373
374 # do the same file again
375 # prevent endless recursion
376 $max-- || croak "failed termcap loop at $tmp_term";
377 $state = 1; # ok, maybe do a new file next time
378 }
379
380 open( TERMCAP, "< $TERMCAP\0" ) || croak "open $TERMCAP: $!";
381 eval $search;
382 die $@ if $@;
383 close TERMCAP;
cb1a09d0 384
085f5cc4
RGS
385 # If :tc=...: found then search this file again
386 $entry =~ s/:tc=([^:]+):/:/ && ( $tmp_term = $1, $state = 2 );
cb1a09d0 387
085f5cc4
RGS
388 # protect any pattern metacharacters in $tmp_term
389 $termpat = $tmp_term;
390 $termpat =~ s/(\W)/\\$1/g;
a687059c 391 }
cb1a09d0
AD
392
393 croak "Can't find $term" if $entry eq '';
085f5cc4
RGS
394 $entry =~ s/:+\s*:+/:/g; # cleanup $entry
395 $entry =~ s/:+/:/g; # cleanup $entry
396 $self->{TERMCAP} = $entry; # save it
397 # print STDERR "DEBUG: $entry = ", $entry, "\n";
a687059c 398
748a9306 399 # Precompile $entry into the object
cb1a09d0 400 $entry =~ s/^[^:]*://;
085f5cc4
RGS
401 foreach $field ( split( /:[\s:\\]*/, $entry ) )
402 {
403 if ( defined $field && $field =~ /^(\w\w)$/ )
404 {
405 $self->{ '_' . $field } = 1 unless defined $self->{ '_' . $1 };
406
407 # print STDERR "DEBUG: flag $1\n";
408 }
409 elsif ( defined $field && $field =~ /^(\w\w)\@/ )
410 {
411 $self->{ '_' . $1 } = "";
412
413 # print STDERR "DEBUG: unset $1\n";
414 }
415 elsif ( defined $field && $field =~ /^(\w\w)#(.*)/ )
416 {
417 $self->{ '_' . $1 } = $2 unless defined $self->{ '_' . $1 };
418
419 # print STDERR "DEBUG: numeric $1 = $2\n";
420 }
421 elsif ( defined $field && $field =~ /^(\w\w)=(.*)/ )
422 {
423
424 # print STDERR "DEBUG: string $1 = $2\n";
425 next if defined $self->{ '_' . ( $cap = $1 ) };
426 $_ = $2;
305a762d
JS
427 if ( ord('A') == 193 )
428 {
429 s/\\E/\047/g;
430 s/\\(\d\d\d)/pack('c',oct($1) & 0177)/eg;
431 s/\\n/\n/g;
432 s/\\r/\r/g;
433 s/\\t/\t/g;
434 s/\\b/\b/g;
435 s/\\f/\f/g;
436 s/\\\^/\337/g;
437 s/\^\?/\007/g;
438 s/\^(.)/pack('c',ord($1) & 31)/eg;
439 s/\\(.)/$1/g;
440 s/\337/^/g;
441 }
442 else
443 {
444 s/\\E/\033/g;
445 s/\\(\d\d\d)/pack('c',oct($1) & 0177)/eg;
446 s/\\n/\n/g;
447 s/\\r/\r/g;
448 s/\\t/\t/g;
449 s/\\b/\b/g;
450 s/\\f/\f/g;
451 s/\\\^/\377/g;
452 s/\^\?/\177/g;
453 s/\^(.)/pack('c',ord($1) & 31)/eg;
454 s/\\(.)/$1/g;
455 s/\377/^/g;
456 }
085f5cc4
RGS
457 $self->{ '_' . $cap } = $_;
458 }
459
460 # else { carp "junk in $term ignored: $field"; }
a687059c 461 }
cb1a09d0
AD
462 $self->{'_pc'} = "\0" unless defined $self->{'_pc'};
463 $self->{'_bc'} = "\b" unless defined $self->{'_bc'};
464 $self;
a687059c
LW
465}
466
cb1a09d0 467# $terminal->Tpad($string, $cnt, $FH);
2ef86165
JS
468
469=item B<Tpad>
470
471Outputs a literal string with appropriate padding for the current terminal.
472
473It takes three arguments:
474
475=over 2
476
477=item B<$string>
478
479The literal string to be output. If it starts with a number and an optional
480'*' then the padding will be increased by an amount relative to this number,
481if the '*' is present then this amount will me multiplied by $cnt. This part
482of $string is removed before output/
483
484=item B<$cnt>
485
486Will be used to modify the padding applied to string as described above.
487
488=item B<$FH>
489
490An optional filehandle (or IO::Handle ) that output will be printed to.
491
492=back
493
494The padded $string is returned.
495
496=cut
497
085f5cc4
RGS
498sub Tpad
499{ ## public
cb1a09d0 500 my $self = shift;
085f5cc4
RGS
501 my ( $string, $cnt, $FH ) = @_;
502 my ( $decr, $ms );
503
504 if ( defined $string && $string =~ /(^[\d.]+)(\*?)(.*)$/ )
505 {
506 $ms = $1;
507 $ms *= $cnt if $2;
508 $string = $3;
509 $decr = $self->{PADDING};
510 if ( $decr > .1 )
511 {
512 $ms += $decr / 2;
513 $string .= $self->{'_pc'} x ( $ms / $decr );
514 }
a687059c
LW
515 }
516 print $FH $string if $FH;
517 $string;
518}
519
cb1a09d0 520# $terminal->Tputs($cap, $cnt, $FH);
2ef86165
JS
521
522=item B<Tputs>
523
524Output the string for the given capability padded as appropriate without
525any parameter substitution.
526
527It takes three arguments:
528
529=over 2
530
531=item B<$cap>
532
533The capability whose string is to be output.
534
535=item B<$cnt>
536
537A count passed to Tpad to modify the padding applied to the output string.
538If $cnt is zero or one then the resulting string will be cached.
539
540=item B<$FH>
541
542An optional filehandle (or IO::Handle ) that output will be printed to.
543
544=back
545
546The appropriate string for the capability will be returned.
547
548=cut
549
085f5cc4
RGS
550sub Tputs
551{ ## public
cb1a09d0 552 my $self = shift;
085f5cc4 553 my ( $cap, $cnt, $FH ) = @_;
cb1a09d0 554 my $string;
748a9306 555
2ef86165
JS
556 $cnt = 0 unless $cnt;
557
085f5cc4
RGS
558 if ( $cnt > 1 )
559 {
560 $string = Tpad( $self, $self->{ '_' . $cap }, $cnt );
561 }
562 else
563 {
564
565 # cache result because Tpad can be slow
566 unless ( exists $self->{$cap} )
567 {
568 $self->{$cap} =
569 exists $self->{"_$cap"}
570 ? Tpad( $self, $self->{"_$cap"}, 1 )
571 : undef;
572 }
573 $string = $self->{$cap};
748a9306
LW
574 }
575 print $FH $string if $FH;
576 $string;
577}
578
cb1a09d0 579# $terminal->Tgoto($cap, $col, $row, $FH);
2ef86165
JS
580
581=item B<Tgoto>
582
583B<Tgoto> decodes a cursor addressing string with the given parameters.
584
585There are four arguments:
586
587=over 2
588
589=item B<$cap>
590
591The name of the capability to be output.
592
593=item B<$col>
594
595The first value to be substituted in the output string ( usually the column
596in a cursor addressing capability )
597
598=item B<$row>
599
600The second value to be substituted in the output string (usually the row
601in cursor addressing capabilities)
602
603=item B<$FH>
604
605An optional filehandle (or IO::Handle ) to which the output string will be
606printed.
607
608=back
609
610Substitutions are made with $col and $row in the output string with the
611following sprintf() line formats:
612
613 %% output `%'
614 %d output value as in printf %d
615 %2 output value as in printf %2d
616 %3 output value as in printf %3d
617 %. output value as in printf %c
618 %+x add x to value, then do %.
619
620 %>xy if value > x then add y, no output
621 %r reverse order of two parameters, no output
622 %i increment by one, no output
623 %B BCD (16*(value/10)) + (value%10), no output
624
625 %n exclusive-or all parameters with 0140 (Datamedia 2500)
626 %D Reverse coding (value - 2*(value%16)), no output (Delta Data)
627
628The output string will be returned.
629
630=cut
631
085f5cc4
RGS
632sub Tgoto
633{ ## public
cb1a09d0 634 my $self = shift;
085f5cc4
RGS
635 my ( $cap, $code, $tmp, $FH ) = @_;
636 my $string = $self->{ '_' . $cap };
cb1a09d0 637 my $result = '';
085f5cc4 638 my $after = '';
cb1a09d0 639 my $online = 0;
085f5cc4
RGS
640 my @tmp = ( $tmp, $code );
641 my $cnt = $code;
642
643 while ( $string =~ /^([^%]*)%(.)(.*)/ )
644 {
645 $result .= $1;
646 $code = $2;
647 $string = $3;
648 if ( $code eq 'd' )
649 {
650 $result .= sprintf( "%d", shift(@tmp) );
651 }
652 elsif ( $code eq '.' )
653 {
654 $tmp = shift(@tmp);
655 if ( $tmp == 0 || $tmp == 4 || $tmp == 10 )
656 {
657 if ($online)
658 {
659 ++$tmp, $after .= $self->{'_up'} if $self->{'_up'};
660 }
661 else
662 {
663 ++$tmp, $after .= $self->{'_bc'};
664 }
665 }
666 $result .= sprintf( "%c", $tmp );
667 $online = !$online;
668 }
669 elsif ( $code eq '+' )
670 {
671 $result .= sprintf( "%c", shift(@tmp) + ord($string) );
672 $string = substr( $string, 1, 99 );
673 $online = !$online;
674 }
675 elsif ( $code eq 'r' )
676 {
677 ( $code, $tmp ) = @tmp;
678 @tmp = ( $tmp, $code );
679 $online = !$online;
680 }
681 elsif ( $code eq '>' )
682 {
683 ( $code, $tmp, $string ) = unpack( "CCa99", $string );
684 if ( $tmp[$[] > $code )
685 {
686 $tmp[$[] += $tmp;
687 }
688 }
689 elsif ( $code eq '2' )
690 {
691 $result .= sprintf( "%02d", shift(@tmp) );
692 $online = !$online;
693 }
694 elsif ( $code eq '3' )
695 {
696 $result .= sprintf( "%03d", shift(@tmp) );
697 $online = !$online;
698 }
699 elsif ( $code eq 'i' )
700 {
701 ( $code, $tmp ) = @tmp;
702 @tmp = ( $code + 1, $tmp + 1 );
703 }
704 else
705 {
706 return "OOPS";
707 }
a687059c 708 }
085f5cc4 709 $string = Tpad( $self, $result . $string . $after, $cnt );
748a9306
LW
710 print $FH $string if $FH;
711 $string;
712}
713
cb1a09d0 714# $terminal->Trequire(qw/ce ku kd/);
2ef86165
JS
715
716=item B<Trequire>
717
718Takes a list of capabilities as an argument and will croak if one is not
719found.
720
721=cut
722
085f5cc4
RGS
723sub Trequire
724{ ## public
cb1a09d0 725 my $self = shift;
085f5cc4
RGS
726 my ( $cap, @undefined );
727 foreach $cap (@_)
728 {
729 push( @undefined, $cap )
730 unless defined $self->{ '_' . $cap } && $self->{ '_' . $cap };
748a9306 731 }
cb1a09d0 732 croak "Terminal does not support: (@undefined)" if @undefined;
a687059c
LW
733}
734
2ef86165
JS
735=back
736
737=head1 EXAMPLES
738
739 use Term::Cap;
740
741 # Get terminal output speed
742 require POSIX;
743 my $termios = new POSIX::Termios;
744 $termios->getattr;
745 my $ospeed = $termios->getospeed;
746
747 # Old-style ioctl code to get ospeed:
748 # require 'ioctl.pl';
749 # ioctl(TTY,$TIOCGETP,$sgtty);
750 # ($ispeed,$ospeed) = unpack('cc',$sgtty);
751
752 # allocate and initialize a terminal structure
753 $terminal = Tgetent Term::Cap { TERM => undef, OSPEED => $ospeed };
754
755 # require certain capabilities to be available
756 $terminal->Trequire(qw/ce ku kd/);
757
758 # Output Routines, if $FH is undefined these just return the string
cb1a09d0 759
2ef86165
JS
760 # Tgoto does the % expansion stuff with the given args
761 $terminal->Tgoto('cm', $col, $row, $FH);
762
763 # Tputs doesn't do any % expansion.
764 $terminal->Tputs('dl', $count = 1, $FH);
765
766=head1 COPYRIGHT AND LICENSE
767
768Please see the README file in distribution.
769
770=head1 AUTHOR
771
772This module is part of the core Perl distribution and is also maintained
773for CPAN by Jonathan Stowe <jns@gellyfish.com>.
774
775=head1 SEE ALSO
776
777termcap(5)
778
779=cut
2ab0daaa
JS
780
781# Below is a default entry for systems where there are terminals but no
782# termcap
7831;
a69e7784 784__DATA__
2ab0daaa
JS
785vt220|vt200|DEC VT220 in vt100 emulation mode:
786am:mi:xn:xo:
787co#80:li#24:
788RA=\E[?7l:SA=\E[?7h:
789ac=kkllmmjjnnwwqquuttvvxx:ae=\E(B:al=\E[L:as=\E(0:
790bl=^G:cd=\E[J:ce=\E[K:cl=\E[H\E[2J:cm=\E[%i%d;%dH:
791cr=^M:cs=\E[%i%d;%dr:dc=\E[P:dl=\E[M:do=\E[B:
792ei=\E[4l:ho=\E[H:im=\E[4h:
793is=\E[1;24r\E[24;1H:
794nd=\E[C:
795kd=\E[B::kl=\E[D:kr=\E[C:ku=\E[A:le=^H:
796mb=\E[5m:md=\E[1m:me=\E[m:mr=\E[7m:
797kb=\0177:
798r2=\E>\E[24;1H\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h\E=:rc=\E8:
799sc=\E7:se=\E[27m:sf=\ED:so=\E[7m:sr=\EM:ta=^I:
800ue=\E[24m:up=\E[A:us=\E[4m:ve=\E[?25h:vi=\E[?25l:
801