Skip to content

Commit

Permalink
arithmetic: use getopts()
Browse files Browse the repository at this point in the history
* Create a usage() function so we can call it instead of the magical die("Usage")
* Update regex for validating -r value (accepting integers 0 and above)
* The format of options is compatible with getopts() so switch over to it
* Now we can write -o/ and -r100, or with a space
* Bump version
  • Loading branch information
mknos authored Nov 19, 2023
1 parent 231b9d4 commit b10ce34
Showing 1 changed file with 32 additions and 49 deletions.
81 changes: 32 additions & 49 deletions bin/arithmetic
Original file line number Diff line number Diff line change
Expand Up @@ -15,61 +15,38 @@ License: perl
use strict;
use integer;

my ($VERSION) = '1.2';

my $warnings = 0;

# Print a usuage message on a unknown option.
# Requires my patch to Getopt::Std of 25 Feb 1999.
$SIG {__WARN__} = sub {
if (substr ($_ [0], 0, 14) eq "Unknown option") {die "Usage"};
require File::Basename;
$0 = File::Basename::basename ($0);
$warnings = 1;
warn "$0: @_";
};

$SIG {__DIE__} = sub {
require File::Basename;
$0 = File::Basename::basename ($0);
if (substr ($_ [0], 0, 5) eq "Usage") {
die <<EOF;
$0 (Perl games) $VERSION
$0 [-o +-x/] [-r range]
EOF
}
die "$0: @_";
};

# Get the options.
# o => operators.
# r => range
my $operators = "+";
my $range = 10;
while (@ARGV > 1) {
my $opt = shift;
if ($opt eq '-o') {
$operators = shift;
die "Usage" if $operators =~ m{[^-x+/]};
next;
}
if ($opt eq '-r') {
$range = shift;
die "Usage" if $range =~ /\D/;
next;
}
die "Usage";
}
use File::Basename qw(basename);
use Getopt::Std qw(getopts);

use constant EX_SUCCESS => 0;
use constant EX_FAILURE => 1;

my $Program = basename($0);
my ($VERSION) = '1.3';

my %opt;
getopts('o:r:', \%opt) or usage();
my $operators = '+';
if (defined $opt{'o'}) {
usage() if ($opt{'o'} =~ m{[^-x+/]});
$operators = $opt{'o'};
}
my $range = 10;
if (defined $opt{'r'}) {
usage() if ($range !~ m/\A[0-9]+\Z/);
$range = $opt{'r'};
}
# Special case the range of 0. Since the right operator can only be 0,
# division should be disallowed. die() if division was the only possible
# operator. There will be nothing left.
if ($range == 0) {
$operators =~ s{/+}{}g;
die "division by 0 is not allowed\n" unless $operators;
unless ($operators) {
warn "$Program: division by 0 is not allowed\n";
exit EX_FAILURE;
}
}

die "Usage" if @ARGV;
usage() if @ARGV;

# Play the game!
my $start = time;
Expand Down Expand Up @@ -162,7 +139,13 @@ sub report {
print "\nYou had $correct answers correct, out of $questions. ",
"It took you $time.\n";

exit $warnings;
exit EX_SUCCESS;
}

sub usage {
warn "$Program (Perl games) $VERSION\n";
warn "usage: $Program [-o +-x/] [-r range]\n";
exit EX_FAILURE;
}

__END__
Expand Down

0 comments on commit b10ce34

Please sign in to comment.