# -*- perl -*- # IO.pm $Id: Io.pm,v 1.4.2.1 2000/01/30 13:56:23 jens Exp $ # (C) Copyright Jens G Jensen # This file is part of epsmerge and is distributed under GNU GPL package Io; use strict; sub new { return bless {}, shift; } sub my_print { my ($self, $where, $what) = @_; print { $where } $what; } package Io_Console; use strict; use Options; use vars qw(@ISA); @ISA = qw(Io); # Basic rule for console IO: Input is taken from STDIN unless STDIN is # not interactive in which case it is currently an error. Output is # written to STDOUT unless option '-o' points to stdout in which case # output is written to STDERR. No error is reported when _creating_ the # Io class. sub new { my $self = Io::new(@_); $self->{'in'} = \*STDIN; # no error yet even if STDIN is not interactive $self->{'out'} = Options->new()->getopts('o') eq 'stdout' ? \*STDERR : \*STDOUT; return $self; } # Input: # 1. A message string, possibly with newlines in it; # 2. A reference to a list of possible answers; # 3. The index number of the default answer, or -1 or undef if # there should be no default (0 is the first entry); # 4. Boolean string: whether an answer not in the list is permitted: # the string is printed as question if other options are permitted, # if empty then no other option is permitted. # Output: # One of the answers from the list (or not, see 4). sub ask { my ($self, $text, $items, $default, $allow_other) = @_; die "Not running interactively" unless -t $self->{'in'}; print { $self->{'out'} } "$text\n"; my $o; $default = -1 unless defined $default; # user's input will be off by one, usual caveats apply for ( $o = 0; $o < @$items; ++$o ) { if( $o == $default ) { # mark default somehow print { $self->{'out'} } $o+1, ":-> \t$items->[$o] \t<-\n"; } else { print { $self->{'out'} } $o+1, ": \t$items->[$o]\n"; } } # $o == @$items at this point... print { $self->{'out'} } $o+1, ": \t$allow_other\n" if $allow_other; my $i = 0; # <> doesn't like complicated things, not even {}s my $stdin_ref_hack = $self->{'in'}; do { $i = <$stdin_ref_hack>; chomp $i; $i = $default+1 if $i eq ""; } until ( $i =~ /^[0-9]+$/ && $i > 0 && $i <= $o + ($allow_other ? 1 : 0) ); my $answer; if ( $i > $o ) { print { $self->{'out'} } "> "; # a prompt, visual cue... $answer = <$stdin_ref_hack>; chomp $answer; } else { $answer = $items->[$i-1]; } return $answer; } # Call with a message and, optionally, a priority which should be one of the following: # 'D': debug (0) # 'I': info (1) # 'W': warning (2) # 'E': error (3) # 'F': fatal (4) # Otherwise, 'info' is assumed. sub message { my $self = shift; my $level = index 'DIWEF', @_ ? $_[0] : 'I'; my $opt = Options->new(); if( $opt->getopts('debug') || $level && $opt->getopts('verbose') || $level > 1 && ! $opt->getopts('q') ) { my_print $self->{'out'}, "$_[0]\n"; } } sub status { # currently only for debugging purposes print STDERR "Status: $_[1]\n"; } 1;