diff --git a/bin/tr b/bin/tr index e35356ca..33325562 100755 --- a/bin/tr +++ b/bin/tr @@ -16,35 +16,45 @@ License: perl use strict; +use File::Basename qw(basename); + +use constant EX_SUCCESS => 0; +use constant EX_FAILURE => 1; + +my $Program = basename($0); + my( %opt, # option hash $string1, # from set $string2, # to set ); - -END { - close STDOUT || die "$0: can't close stdout: $!\n"; - $? = 1 if $? == 255; # from die -} - sub usage { - warn "$0: @_\n" if @_; - die "usage: $0 [-csd] string1 string2 [file ...]\n"; + warn "usage: $Program [-cdsUC] string1 string2\n"; + exit EX_FAILURE; } @opt{ qw/c s d U C/ } = ('') x 5; -while ($ARGV[0] =~ s/^-(?=.)//) { +while (defined($ARGV[0]) && $ARGV[0] =~ s/^-(?=.)//) { for my $flag (split(//,$ARGV[0])) { - usage("unknown flag: `$flag'") unless 'csdUC' =~ /\Q$flag/; - warn "$0: `$flag' flag already set\n" if $opt{$flag}; + if ('cdsUC' !~ m/\Q$flag/) { + warn "unknown option: '$flag'\n"; + usage(); + } $opt{$flag} = $flag; } shift; } - -usage("Not enough arguments") unless @ARGV > 1; +my $narg = ($opt{'d'} && !$opt{'s'}) ? 1 : 2; +if (scalar(@ARGV) < $narg) { + warn "missing operand\n"; + usage(); +} +if (scalar(@ARGV) > $narg) { + warn "extra operand\n"; + usage(); +} # remove spurious [...] for (($string1, $string2) = splice(@ARGV, 0, 2)) { @@ -60,11 +70,12 @@ eval qq{ tr[$string1][$string2]$opts; print; } + 1; +} or do { + warn "$Program: $@\n"; + exit EX_FAILURE; }; - -die if $@; - -exit (0); # XXX: Doen't detect failed opens +exit EX_SUCCESS; # XXX: Doen't detect failed opens __END__ @@ -88,23 +99,23 @@ Here are the options: =over -=item c +=item -c Complement the SEARCHLIST. -=item d +=item -d Delete found but unreplaced characters. -=item s +=item -s Squash duplicate replaced characters. -=item U +=item -U Translate to/from UTF-8. -=item C +=item -C Translate to/from 8-bit char (octet).