| # | 
 | # Copyright 1999, 2000, 2001 Patrik Stridvall | 
 | # | 
 | # This library is free software; you can redistribute it and/or | 
 | # modify it under the terms of the GNU Lesser General Public | 
 | # License as published by the Free Software Foundation; either | 
 | # version 2.1 of the License, or (at your option) any later version. | 
 | # | 
 | # This library is distributed in the hope that it will be useful, | 
 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | 
 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
 | # Lesser General Public License for more details. | 
 | # | 
 | # You should have received a copy of the GNU Lesser General Public | 
 | # License along with this library; if not, write to the Free Software | 
 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA | 
 | # | 
 |  | 
 | package output; | 
 |  | 
 | use strict; | 
 |  | 
 | use vars qw($VERSION @ISA @EXPORT @EXPORT_OK); | 
 | require Exporter; | 
 |  | 
 | @ISA = qw(Exporter); | 
 | @EXPORT = qw(); | 
 | @EXPORT_OK = qw($output); | 
 |  | 
 | use vars qw($output); | 
 |  | 
 | $output = '_output'->new; | 
 |  | 
 | package _output; | 
 |  | 
 | use strict; | 
 |  | 
 | my $stdout_isatty = -t STDOUT; | 
 | my $stderr_isatty = -t STDERR; | 
 |  | 
 | sub new($) { | 
 |     my $proto = shift; | 
 |     my $class = ref($proto) || $proto; | 
 |     my $self  = {}; | 
 |     bless ($self, $class); | 
 |  | 
 |     my $progress_enabled = \${$self->{PROGRESS_ENABLED}}; | 
 |     my $progress = \${$self->{PROGRESS}}; | 
 |     my $last_progress = \${$self->{LAST_PROGRESS}}; | 
 |     my $last_time = \${$self->{LAST_TIME}}; | 
 |     my $progress_count = \${$self->{PROGRESS_COUNT}}; | 
 |     my $prefix = \${$self->{PREFIX}}; | 
 |     my $prefix_callback = \${$self->{PREFIX_CALLBACK}}; | 
 |  | 
 |     $$progress_enabled = 1; | 
 |     $$progress = ""; | 
 |     $$last_progress = ""; | 
 |     $$last_time = 0; | 
 |     $$progress_count = 0; | 
 |     $$prefix = undef; | 
 |     $$prefix_callback = undef; | 
 |  | 
 |     return $self; | 
 | } | 
 |  | 
 | sub DESTROY { | 
 |     my $self = shift; | 
 |  | 
 |     $self->hide_progress; | 
 | } | 
 |  | 
 | sub enable_progress($) { | 
 |     my $self = shift; | 
 |     my $progress_enabled = \${$self->{PROGRESS_ENABLED}}; | 
 |  | 
 |     $$progress_enabled = 1; | 
 | } | 
 |  | 
 | sub disable_progress($) { | 
 |     my $self = shift; | 
 |     my $progress_enabled = \${$self->{PROGRESS_ENABLED}}; | 
 |  | 
 |     $$progress_enabled = 0; | 
 | } | 
 |  | 
 | sub show_progress($) { | 
 |     my $self = shift; | 
 |     my $progress_enabled = \${$self->{PROGRESS_ENABLED}}; | 
 |     my $progress = ${$self->{PROGRESS}}; | 
 |     my $last_progress = \${$self->{LAST_PROGRESS}}; | 
 |     my $progress_count = \${$self->{PROGRESS_COUNT}}; | 
 |  | 
 |     $$progress_count++; | 
 |  | 
 |     if($$progress_enabled) { | 
 | 	if($$progress_count > 0 && $$progress && $stderr_isatty) { | 
 |             # If progress has more than $columns characters the xterm will | 
 |             # scroll to the next line and our ^H characters will fail to | 
 |             # erase it. | 
 |             my $columns=$ENV{COLUMNS} || 80; | 
 |             $progress = substr $progress,0,($columns-1); | 
 | 	    print STDERR $progress; | 
 | 	    $$last_progress = $progress; | 
 | 	} | 
 |     } | 
 | } | 
 |  | 
 | sub hide_progress($)  { | 
 |     my $self = shift; | 
 |     my $progress_enabled = \${$self->{PROGRESS_ENABLED}}; | 
 |     my $progress = \${$self->{PROGRESS}}; | 
 |     my $last_progress = \${$self->{LAST_PROGRESS}}; | 
 |     my $progress_count = \${$self->{PROGRESS_COUNT}}; | 
 |  | 
 |     $$progress_count--; | 
 |  | 
 |     if($$progress_enabled) { | 
 | 	if($$last_progress && $stderr_isatty) { | 
 | 	    my $message=" " x length($$last_progress); | 
 | 	    print STDERR $message; | 
 | 	    undef $$last_progress; | 
 | 	} | 
 |     } | 
 | } | 
 |  | 
 | sub update_progress($) { | 
 |     my $self = shift; | 
 |     my $progress_enabled = \${$self->{PROGRESS_ENABLED}}; | 
 |     my $progress = ${$self->{PROGRESS}}; | 
 |     my $last_progress = \${$self->{LAST_PROGRESS}}; | 
 |  | 
 |     if($$progress_enabled) { | 
 |         # If progress has more than $columns characters the xterm will | 
 |         # scroll to the next line and our ^H characters will fail to | 
 |         # erase it. | 
 |         my $columns=$ENV{COLUMNS} || 80; | 
 |         $progress = substr $progress,0,($columns-1); | 
 |  | 
 | 	my $prefix = ""; | 
 | 	my $suffix = ""; | 
 | 	if($$last_progress) { | 
 |             $prefix = "" x length($$last_progress); | 
 |  | 
 | 	    my $diff = length($$last_progress)-length($progress); | 
 | 	    if($diff > 0) { | 
 |                 $suffix = (" " x $diff) . ("" x $diff); | 
 | 	    } | 
 | 	} | 
 | 	print STDERR $prefix, $progress, $suffix; | 
 | 	$$last_progress = $progress; | 
 |     } | 
 | } | 
 |  | 
 | sub progress($$) { | 
 |     my $self = shift; | 
 |     my $progress = \${$self->{PROGRESS}}; | 
 |     my $last_time = \${$self->{LAST_TIME}}; | 
 |  | 
 |     my $new_progress = shift; | 
 |     if(defined($new_progress)) { | 
 | 	if(!defined($$progress) || $new_progress ne $$progress) { | 
 | 	    $$progress = $new_progress; | 
 |  | 
 | 	    $self->update_progress; | 
 | 	    $$last_time = 0; | 
 | 	} | 
 |     } else { | 
 | 	return $$progress; | 
 |     } | 
 | } | 
 |  | 
 | sub lazy_progress($$) { | 
 |     my $self = shift; | 
 |     my $progress = \${$self->{PROGRESS}}; | 
 |     my $last_time = \${$self->{LAST_TIME}}; | 
 |  | 
 |     $$progress = shift; | 
 |  | 
 |     my $time = time(); | 
 |     if($time - $$last_time > 0) { | 
 | 	$self->update_progress; | 
 |     	$$last_time = $time; | 
 |     } | 
 | } | 
 |  | 
 | sub prefix($$) { | 
 |     my $self = shift; | 
 |     my $prefix = \${$self->{PREFIX}}; | 
 |     my $prefix_callback = \${$self->{PREFIX_CALLBACK}}; | 
 |  | 
 |     my $new_prefix = shift; | 
 |     if(defined($new_prefix)) { | 
 | 	if(!defined($$prefix) || $new_prefix ne $$prefix) { | 
 | 	    $$prefix = $new_prefix; | 
 | 	    $$prefix_callback = undef; | 
 | 	} | 
 |     } else { | 
 | 	return $$prefix; | 
 |     } | 
 | } | 
 |  | 
 | sub prefix_callback($) { | 
 |     my $self = shift; | 
 |  | 
 |     my $prefix = \${$self->{PREFIX}}; | 
 |     my $prefix_callback = \${$self->{PREFIX_CALLBACK}}; | 
 |  | 
 |     $$prefix = undef; | 
 |     $$prefix_callback = shift; | 
 | } | 
 |  | 
 | sub write($$) { | 
 |     my $self = shift; | 
 |  | 
 |     my $message = shift; | 
 |  | 
 |     my $prefix = \${$self->{PREFIX}}; | 
 |     my $prefix_callback = \${$self->{PREFIX_CALLBACK}}; | 
 |  | 
 |     $self->hide_progress if $stdout_isatty; | 
 |     if(defined($$prefix)) { | 
 | 	print $$prefix . $message; | 
 |     } elsif(defined($$prefix_callback)) { | 
 | 	print &{$$prefix_callback}() . $message; | 
 |     } else { | 
 | 	print $message; | 
 |     } | 
 |     $self->show_progress if $stdout_isatty; | 
 | } | 
 |  | 
 | 1; |