| # | |
| # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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; |