# Display.pm: Class Used for Controlling the Display package RDA::Object::Display; # $Id: Display.pm,v 2.12 2012/04/25 06:44:50 mschenke Exp $ # ARCS: $Header: /home/cvs/cvs/RDA_4/src/scripting/lib/RDA/Object/Display.pm,v 2.12 2012/04/25 06:44:50 mschenke Exp $ # # Change History # 20120422 MSC Apply agent changes. =head1 NAME RDA::Object::Display - Class Used for Controlling the Display =head1 SYNOPSIS require RDA::Object::Display; =head1 DESCRIPTION The objects of the C class are used for controlling the display. It is a sub class of L. The following methods are available: =cut use strict; BEGIN { use Exporter; use RDA::Handle::Data; use RDA::Handle::Memory; use RDA::Object; use RDA::Object::Rda; } # Define the global public variables use vars qw($VERSION @ISA %SDCL); $VERSION = sprintf("%d.%02d", q$Revision: 2.12 $ =~ /(\d+)\.(\d+)/); @ISA = qw(RDA::Object Exporter); %SDCL = ( als => { 'echo' => ['$[DSP]', 'dsp_line'], 'explain' => ['$[DSP]', 'explain'], }, beg => \&_begin_display, glb => ['$[DSP]'], inc => [qw(RDA::Object)], met => { 'dsp_block' => {ret => 0}, 'dsp_data' => {ret => 0}, 'dsp_error' => {ret => 0}, 'dsp_line' => {ret => 0, evl => 'L'}, 'dsp_pod' => {ret => 0}, 'dsp_report' => {ret => 0}, 'dsp_string' => {ret => 0}, 'dsp_text' => {ret => 0}, 'get_info' => {ret => 0}, 'explain' => {ret => 0}, 'set_info' => {ret => 0}, 'wrap_string' => {ret => 0}, }, ); # Define the global private constants # Define the global private variables my %tb_det = ( '_B_' => ".I ' \001- '\n", '_P_' => ".I ' '\n", 'Action' => ".I 'Action: '\n", 'Cause' => ".I 'Cause: '\n", ); my %tb_err = ( 'EXPL' => 'expl.txt', 'IRDA' => 'irda.txt', 'OCM' => 'ocm.txt', 'ODRDA' => 'odrda.txt', 'RDA' => 'err.txt', 'STB' => 'stb.txt', ); # Report the module version number sub Version { $VERSION; } =head2 S<$h = RDA::Object::Display-Enew($agt)> The object constructor. This method enables you to specify the agent reference as an argument. C is represented by a blessed hash reference. The following special keys are used: =over 12 =item S< B<'_agt'> > Associated agent reference =item S< B<'_cfg'> > RDA software configuration reference =item S< B<'_col'> > Screen width (in columns) =item S< B<'_out'> > Output indicator =item S< B<'_pag'> > Pager redirection =item S< B<'_sep'> > Separation line =item S< B<'_vms'> > VMS indicator =back Internal keys are prefixed by an underscore. =cut sub new { my ($cls, $agt) = @_; my ($cfg, $slf); # Create the library object $cfg = $agt->get_config; $slf = bless { _agt => $agt, _col => $cfg->get_columns, _cfg => $cfg, _out => $agt->get_info('out') ? 0 : 1, _vms => $cfg->is_vms, }, ref($cls) || $cls; # Extra initialization $slf->{'_pag'} = exists($ENV{'PAGER'}) ? '| '.$ENV{'PAGER'} : $slf->{'_vms'} ? '| TYPE/PAGE=SAVE SYS$INPUT' : '| more'; $slf->{'_pag'} .= ' 2>&1' if $cfg->is_unix || $cfg->is_cygwin; $slf->{'_sep'} = '-' x $slf->{'_col'}; # Return the object reference $slf; } =head2 S<$h-Edelete> This method deletes the library object. =cut sub delete { undef %{$_[0]}; undef $_[0]; } =head2 S<$h-Edsp_block($txt[,$var])> This method displays a text block. The text can contain variables that are resolved through attributes specified as a hash. When the variable is not defined, settings and properties are used. =cut sub dsp_block { my ($slf, $txt, $var) = @_; _dsp_text($slf, $var, (ref($txt) eq 'ARRAY') ? RDA::Handle::Data->new($txt) : ref($txt) ? $txt : RDA::Handle::Memory->new($txt)); } =head2 S<$h-Edsp_data($dat[,$flg])> This method displays the data content. When the flag is set, it displays the data through a pager. =cut sub dsp_data { my ($slf, $dat, $flg) = @_; my ($pid, $ret); return 0 unless $slf->{'_out'} && defined($dat); $dat = join("\n", @$dat, '') if ref($dat); return syswrite(STDOUT, $dat, length($dat)) unless $flg && -t STDOUT; $pid = open(OUT, $slf->{'_pag'}); die "RDA-01210: Cannot open pager:\n $!\n" unless $pid; $ret = syswrite(OUT, $dat, length($dat)); close(OUT); waitpid($pid, 0); $ret; } =head2 S<$h-Edsp_error($err)> This method displays the explanation of the specified error. =cut sub dsp_error { my ($slf, $err, $flg) = @_; $slf->{'_out'} ? dsp_report($slf, RDA::Handle::Memory->new(explain($slf, $err)), defined($flg) ? $flg : 0) : 0; } =head2 S<$h-Edsp_line($lin)> This method displays the specified line. It converts the leading spaces and a possible bullet character in a prefix and wrap the words according to the display width. Is also recognizes a Ctrl-A character as separator between the prefix and the text. =cut sub dsp_line { my ($slf, $lin) = @_; my ($buf); return 0 unless $slf->{'_out'} && defined($lin); $lin =~ s/^(.*?)\001// || $lin =~ s/^(\s*([o\-\*]\s+)?)//; $buf = length($lin) ? wrap_string($slf, $1, $lin) : $1; syswrite(STDOUT, $buf, length($buf)); } =head2 S<$h-Edsp_pod($fil[,$flg])> This method displays data in Perl documentation format. When you specify an array of file as argument, it converts the first readable file from that list. When the flag is set or not specified, it displays the documentation through a pager. =cut sub dsp_pod { my ($slf, $fil, $flg) = @_; if ($slf->{'_out'} && defined($fil)) { my ($cfg, $pth); # Initialize Pod on first use unless (exists($slf->{'_pod'})) { eval "require RDA::Object::Pod"; die "RDA-01211: Package 'RDA::Object::Pod' not available:\n $@\n" if $@; $slf->{'_pod'} = RDA::Object::Pod->new($slf->{'_cfg'}); } # Display the documentation $cfg = $slf->{'_cfg'}; $flg = 1 unless defined($flg); if (ref($fil) eq 'ARRAY') { foreach my $pth (@$fil) { return _dsp_pod($slf, $pth, $flg) if -r $pth; } } elsif ($cfg->is_absolute($fil)) { return _dsp_pod($slf, $fil, $flg); } else { return _dsp_pod($slf, $pth, $flg) if -r ($pth = $cfg->get_file('D_RDA_POD', $fil, '.pod')) || -r ($pth = $cfg->get_file('D_RDA_CODE', $fil, '.def')) || -r ($pth = $cfg->get_file('D_RDA_CODE', $fil, '.ctl')) || -r ($pth = $cfg->get_file('D_RDA_PERL', $fil, '.pod')) || -r ($pth = $cfg->get_file('D_RDA_POD', $fil, '.pm')) || -r ($pth = $cfg->get_file('D_RDA_PERL', $fil, '.pm')); } } 0; } sub _dsp_pod { my ($slf, $fil, $flg) = @_; my ($pid, $ret); if ($flg && -t STDOUT) { die "RDA-01210: Cannot open pager:\n $!\n" unless ($pid = open(OUT, $slf->{'_pag'})); $ret = $slf->{'_pod'}->pod2text(\*OUT, $fil); close(OUT); waitpid($pid, 0); } else { $ret = $slf->{'_pod'}->pod2text(\*STDOUT, $fil); } $ret; } =head2 S<$h-Edsp_report($rpt[,$flg])> This method formats and displays a report. You can specify the report as a string or a reference to an array of lines. When the flag is set or is not specified, it displays the report through a pager. It returns the number of lines effectively treated. Following format directives are available: Multi-Column output: .C <# spaces> ... Indented paragraph: .I '' <# new lines> ... New lines: .N <# new lines> Paragraph: .P <# new lines> ... Query (Web only) .Q ='