1#--------------------------------------------------------------------- 2package Getopt::Mixed; 3# 4# Copyright 1995 Christopher J. Madsen 5# 6# Author: Christopher J. Madsen <ac608@yfn.ysu.edu> 7# Created: 1 Jan 1995 8# Version: $Revision: 1.8 $ ($Date: 1996/02/09 00:05:00 $) 9# Note that RCS revision 1.23 => $Getopt::Mixed::VERSION = "1.023" 10# 11# This program is free software; you can redistribute it and/or modify 12# it under the terms of the GNU General Public License as published by 13# the Free Software Foundation; either version 2, or (at your option) 14# any later version. 15# 16# This program is distributed in the hope that it will be useful, 17# but WITHOUT ANY WARRANTY; without even the implied warranty of 18# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19# GNU General Public License for more details. 20# 21# You should have received a copy of the GNU General Public License 22# along with Perl; see the file COPYING. If not, write to the 23# Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 24# 25# Process both single-character and extended options 26#--------------------------------------------------------------------- 27 28require 5.000; 29use Carp; 30 31require Exporter; 32@ISA = qw(Exporter); 33@EXPORT = (); 34@EXPORT_OK = qw(abortMsg getOptions nextOption); 35 36#===================================================================== 37# Package Global Variables: 38 39BEGIN 40{ 41 # The permissible settings for $order: 42 $REQUIRE_ORDER = 0; 43 $PERMUTE = 1; 44 $RETURN_IN_ORDER = 2; 45 46 # Regular expressions: 47 $intRegexp = '^[-+]?\d+$'; # Match an integer 48 $floatRegexp = '^[-+]?(\d*\.?\d+|\d+\.)$'; # Match a real number 49 $typeChars = 'sif'; # Match type characters 50 51 # Convert RCS revision number (must be main branch) to d.ddd format: 52 ' $Revision: 1.8 $ ' =~ / (\d+)\.(\d{1,3}) / 53 or die "Invalid version number"; 54 $VERSION = sprintf("%d.%03d",$1,$2); 55} # end BEGIN 56 57#===================================================================== 58# Subroutines: 59#--------------------------------------------------------------------- 60# Initialize the option processor: 61# 62# You should set any customization variables *after* calling init. 63# 64# For a description of option declarations, see the documentation at 65# the end of this file. 66# 67# Input: 68# List of option declarations (separated by whitespace) 69# If the first argument is entirely non-alphanumeric characters 70# with no whitespace, it is the characters that start options. 71 72sub init 73{ 74 undef %options; 75 my($opt,$type); 76 77 $ignoreCase = 1; # Ignore case by default 78 $optionStart = "-"; # Dash is the default option starter 79 80 # If the first argument is entirely non-alphanumeric characters 81 # with no whitespace, it is the desired value for $optionStart: 82 $optionStart = shift @_ if $_[0] =~ /^[^a-z0-9\s]+$/i; 83 84 foreach $group (@_) { 85 # Ignore case unless there are upper-case options: 86 $ignoreCase = 0 if $group =~ /[A-Z]/; 87 foreach $option (split(/\s+/,$group)) { 88 croak "Invalid option declaration `$option'" 89 unless $option =~ /^([^=:>]+)([=:][$typeChars]|>[^=:>]+)?$/o; 90 $opt = $1; 91 $type = $2 || ""; 92 if ($type =~ /^>(.*)$/) { 93 $type = $1; 94 croak "Invalid synonym `$option'" 95 if (not defined $options{$type} 96 or $options{$type} =~ /^[^:=]/); 97 } # end if synonym 98 $options{$opt} = $type; 99 } # end foreach option 100 } # end foreach group 101 102 # Handle POSIX compliancy: 103 if (defined $ENV{"POSIXLY_CORRECT"}) { 104 $order = $REQUIRE_ORDER; 105 } else { 106 $order = $PERMUTE; 107 } 108 109 $optionEnd = 0; 110 $badOption = \&badOption; 111 $checkArg = \&checkArg; 112} # end init 113 114#--------------------------------------------------------------------- 115# Clean up when we're done: 116# 117# This just releases the memory used by the %options hash. 118# 119# If 'help' was defined as an option, a new hash with just 'help' is 120# created, in case the program calls abortMsg. 121 122sub cleanup 123{ 124 my $help = defined($options{'help'}); 125 undef %options; 126 $options{'help'} = "" if $help; 127} # end cleanup 128 129#--------------------------------------------------------------------- 130# Abort program with message: 131# 132# Prints program name and arguments to STDERR 133# If --help is an option, prints message saying 'Try --help' 134# Exits with code 1 135 136sub abortMsg 137{ 138 my $name = $0; 139 $name =~ s|^.+[\\/]||; # Remove any directories from name 140 print STDERR $name,": ",@_,"\n"; 141 print STDERR "Try `$name --help' for more information.\n" 142 if defined $options{"help"}; 143 exit 1; 144} # end abortMsg 145 146#--------------------------------------------------------------------- 147# Standard function for handling bad options: 148# 149# Prints an error message and exits. 150# 151# You can override this by setting $Getopt::Mixed::badOption to a 152# function reference. 153# 154# Input: 155# Index into @ARGV 156# The option that caused the error 157# An optional string describing the problem 158# Currently, this can be 159# undef The option was not recognized 160# 'ambiguous' The option could match several long options 161# 162# Note: 163# The option has already been removed from @ARGV. To put it back, 164# you can say: 165# splice(@ARGV,$_[0],0,$_[1]); 166# 167# If your function returns, it should return whatever you want 168# nextOption to return. 169 170sub badOption 171{ 172 my ($index, $option, $problem) = @_; 173 174 $problem = 'unrecognized' unless $problem; 175 176 abortMsg("$problem option `$option'"); 177} # end badOption 178 179#--------------------------------------------------------------------- 180# Make sure we have the proper argument for this option: 181# 182# You can override this by setting $Getopt::Mixed::checkArg to a 183# function reference. 184# 185# Input: 186# $i: Position of argument in @ARGV 187# $value: The text appended to the option (undef if no text) 188# $option: The pretty name of the option (as the user typed it) 189# $type: The type of the option 190# 191# Returns: 192# The value of the option's argument 193 194sub checkArg 195{ 196 my ($i,$value,$option,$type) = @_; 197 198 abortMsg("option `$option' does not take an argument") 199 if (not $type and defined $value); 200 201 if ($type =~ /^=/) { 202 # An argument is required for this option: 203 $value = splice(@ARGV,$i,1) unless defined $value; 204 abortMsg("option `$option' requires an argument") 205 unless defined $value; 206 } 207 208 if ($type =~ /i$/) { 209 abortMsg("option `$option' requires integer argument") 210 if (defined $value and $value !~ /$intRegexp/o); 211 } 212 elsif ($type =~ /f$/) { 213 abortMsg("option `$option' requires numeric argument") 214 if (defined $value and $value !~ /$floatRegexp/o); 215 } 216 elsif ($type =~ /^[=:]/ and ref($checkType)) { 217 $value = &$checkType($i,$value,$option,$type); 218 } 219 220 $value = "" if not defined $value and $type =~ /^:/; 221 222 $value; 223} # end checkArg 224 225#--------------------------------------------------------------------- 226# Find a match for an incomplete long option: 227# 228# Input: 229# The option text to match 230# 231# Returns: 232# The option that matched, or 233# undef, if no option matched, or 234# (undef, 'ambiguous'), if multiple options matched 235 236sub findMatch 237{ 238 my $opt = shift; 239 240 $opt =~ s/-/[^-]*-/g; 241 $opt .= ".*"; 242 243 my @matches = grep(/^$opt$/, keys %options); 244 245 return undef if $#matches < 0; 246 return $matches[0] if $#matches == 0; 247 248 $opt = $matches[0]; 249 $opt = $options{$opt} if $options{$opt} =~ /^[^=:]/; 250 251 foreach (@matches) { 252 return (undef, 'ambiguous') 253 unless $_ eq $opt or $options{$_} eq $opt; 254 } 255 256 $opt; 257} # end findMatch 258 259#--------------------------------------------------------------------- 260# Return the next option: 261# 262# Returns a list of 3 elements: (OPTION, VALUE, PRETTYNAME), where 263# OPTION is the name of the option, 264# VALUE is its argument, and 265# PRETTYNAME is the option as the user entered it. 266# Returns the null list if there are no more options to process 267# 268# If $order is $RETURN_IN_ORDER, and this is a normal argument (not an 269# option), OPTION will be the null string, VALUE will be the argument, 270# and PRETTYNAME will be undefined. 271 272sub nextOption 273{ 274 return () if $#ARGV < 0; # No more arguments 275 276 if ($optionEnd) { 277 # We aren't processing any more options: 278 return ("", shift @ARGV) if $order == $RETURN_IN_ORDER; 279 return (); 280 } 281 282 # Find the next option: 283 my $i = 0; 284 while (length($ARGV[$i]) < 2 or 285 index($optionStart,substr($ARGV[$i],0,1)) < 0) { 286 return () if $order == $REQUIRE_ORDER; 287 return ("", shift @ARGV) if $order == $RETURN_IN_ORDER; 288 ++$i; 289 return () if $i > $#ARGV; 290 } # end while 291 292 # Process the option: 293 my($option,$opt,$value,$optType,$prettyOpt); 294 $option = $ARGV[$i]; 295 if (substr($option,0,1) eq substr($option,1,1)) { 296 # If the option start character is repeated, it's a long option: 297 splice @ARGV,$i,1; 298 if (length($option) == 2) { 299 # A double dash by itself marks the end of the options: 300 $optionEnd = 1; # Don't process any more options 301 return nextOption(); 302 } # end if bare double dash 303 $opt = substr($option,2); 304 if ($opt =~ /^([^=]+)=(.*)$/) { 305 $opt = $1; 306 $value = $2; 307 } # end if option is followed by value 308 $opt =~ tr/A-Z/a-z/ if $ignoreCase; 309 $prettyOpt = substr($option,0,2) . $opt; 310 my $problem; 311 ($opt, $problem) = findMatch($opt) 312 unless defined $options{$opt} and length($opt) > 1; 313 return &$badOption($i,$option,$problem) unless $opt; 314 $optType = $options{$opt}; 315 if ($optType =~ /^[^:=]/) { 316 $opt = $optType; 317 $optType = $options{$opt}; 318 } 319 $value = &$checkArg($i,$value,$prettyOpt,$optType); 320 } # end if long option 321 else { 322 # It's a short option: 323 $opt = substr($option,1,1); 324 $opt =~ tr/A-Z/a-z/ if $ignoreCase; 325 return &$badOption($i,$option) unless defined $options{$opt}; 326 $optType = $options{$opt}; 327 if ($optType =~ /^[^:=]/) { 328 $opt = $optType; 329 $optType = $options{$opt}; 330 } 331 if (length($option) == 2 or $optType) { 332 # This is the last option in the group, so remove the group: 333 splice(@ARGV,$i,1); 334 } else { 335 # Just remove this option from the group: 336 substr($ARGV[$i],1,1) = ""; 337 } 338 if ($optType) { 339 $value = (length($option) > 2) ? substr($option,2) : undef; 340 $value =~ s/^=// if $value; # Allow either -d3 or -d=3 341 } # end if option takes an argument 342 $prettyOpt = substr($option,0,2); 343 $value = &$checkArg($i,$value,$prettyOpt,$optType); 344 } # end else short option 345 ($opt,$value,$prettyOpt); 346} # end nextOption 347 348#--------------------------------------------------------------------- 349# Get options: 350# 351# Input: 352# The same as for init() 353# If no parameters are supplied, init() is NOT called. This allows 354# you to call init() yourself and then change the configuration 355# variables. 356# 357# Output Variables: 358# Sets $opt_X for each `-X' option encountered. 359# 360# Note that if --apple is a synonym for -a, then --apple will cause 361# $opt_a to be set, not $opt_apple. 362 363sub getOptions 364{ 365 &init if $#_ >= 0; # Pass arguments (if any) on to init 366 367 # If you want to use $RETURN_IN_ORDER, you have to call 368 # nextOption yourself; getOptions doesn't support it: 369 $order = $PERMUTE if $order == $RETURN_IN_ORDER; 370 371 my ($option,$value,$package); 372 373 $package = (caller)[0]; 374 375 while (($option, $value) = nextOption()) { 376 $option =~ s/\W/_/g; # Make a legal Perl identifier 377 $value = 1 unless defined $value; 378 eval("\$" . $package . '::opt_' . $option . ' = $value;'); 379 } # end while 380 381 cleanup(); 382} # end getOptions 383 384#===================================================================== 385# Package return value: 386 387$VERSION; 388 389__END__ 390 391=head1 NAME 392 393Getopt::Mixed - getopt processing with both long and short options 394 395=head1 SYNOPSIS 396 397 use Getopt::Mixed; 398 Getopt::Mixed::getOptions(...option-descriptions...); 399 ...examine $opt_* variables... 400 401or 402 403 use Getopt::Mixed "nextOption"; 404 Getopt::Mixed::init(...option-descriptions...); 405 while (($option, $value) = nextOption()) { 406 ...process option... 407 } 408 Getopt::Mixed::cleanup(); 409 410=head1 DESCRIPTION 411 412This package is my response to the standard modules Getopt::Std and 413Getopt::Long. C<Std> doesn't support long options, and C<Long> 414doesn't support short options. I wanted both, since long options are 415easier to remember and short options are faster to type. 416 417This package is intended to be the "Getopt-to-end-all-Getop's". It 418combines (I hope) flexibility and simplicity. It supports both short 419options (introduced by C<->) and long options (introduced by C<-->). 420Short options which do not take an argument can be grouped together. 421Short options which do take an argument must be the last option in 422their group, because everything following the option will be 423considered to be its argument. 424 425There are two methods for using Getopt::Mixed: the simple method and 426the flexible method. Both methods use the same format for option 427descriptions. 428 429=head2 Option Descriptions 430 431The option-description arguments required by C<init> and C<getOptions> 432are strings composed of individual option descriptions. Several 433option descriptions can appear in the same string if they are 434separated by whitespace. 435 436Each description consists of the option name and an optional trailing 437argument specifier. Option names may consist of any characters but 438whitespace, C<=>, C<:>, and C<E<gt>>. 439 440Values for argument specifiers are: 441 442 <none> option does not take an argument 443 =s :s option takes a mandatory (=) or optional (:) string argument 444 =i :i option takes a mandatory (=) or optional (:) integer argument 445 =f :f option takes a mandatory (=) or optional (:) real number argument 446 >new option is a synonym for option `new' 447 448The C<E<gt>> specifier is not really an argument specifier. It 449defines an option as being a synonym for another option. For example, 450"a=i apples>a" would define B<-a> as an option that requires an 451integer argument and B<--apples> as a synonym for B<-a>. Only one 452level of synonyms is supported, and the root option must be listed 453first. For example, "apples>a a=i" and "a=i apples>a oranges>apples" 454are illegal; use "a=i apples>a oranges>a" if that's what you want. 455 456For example, in the option description: 457 "a b=i c:s apple baker>b charlie:s" 458 -a and --apple do not take arguments 459 -b takes a mandatory integer argument 460 --baker is a synonym for -b 461 -c and --charlie take an optional string argument 462 463If the first argument to C<init> or C<getOptions> is entirely 464non-alphanumeric characters with no whitespace, it represents the 465characters which can begin options. 466 467=head2 User Interface 468 469From the user's perspective, short options are introduced by a dash 470(C<->) and long options are introduced by a double dash (C<-->). 471Short options may be combined ("-a -b" can be written "-ab"), but an 472option that takes an argument must be the last one in its group, 473because anything following it is considered part of the argument. A 474double dash by itself marks the end of the options; all arguments 475following it are treated as normal arguments, not options. A single 476dash by itself is treated as a normal argument, I<not> an option. 477 478Long options may be abbreviated. An option B<--all-the-time> could be 479abbreviated B<--all>, B<--a--tim>, or even B<--a>. Note that B<--time> 480would not work; the abbreviation must start at the beginning of the 481option name. If an abbreviation is ambiguous, an error message will 482be printed. 483 484In the following examples, B<-i> and B<--int> take integer arguments, 485B<-f> and B<--float> take floating point arguments, and B<-s> and 486B<--string> take string arguments. All other options do not take an 487argument. 488 489 -i24 -f24.5 -sHello 490 -i=24 --int=-27 -f=24.5 --float=0.27 -s=Hello --string=Hello 491 492If the argument is required, it can also be separated by whitespace: 493 494 -i 24 --int -27 -f 24.5 --float 0.27 -s Hello --string Hello 495 496Note that if the option is followed by C<=>, whatever follows the C<=> 497I<is> the argument, even if it's the null string. In the example 498 499 -i= 24 -f= 24.5 -s= Hello 500 501B<-i> and B<-f> will cause an error, because the null string is not a 502number, but B<-s> is perfectly legal; its argument is the null string, 503not "Hello". 504 505Remember that optional arguments I<cannot> be separated from the 506option by whitespace. 507 508=head2 The Simple Method 509 510The simple method is 511 512 use Getopt::Mixed; 513 Getopt::Mixed::getOptions(...option-descriptions...); 514 515You then examine the C<$opt_*> variables to find out what options were 516specified and the C<@ARGV> array to see what arguments are left. 517 518If B<-a> is an option that doesn't take an argument, then C<$opt_a> 519will be set to 1 if the option is present, or left undefined if the 520option is not present. 521 522If B<-b> is an option that takes an argument, then C<$opt_b> will be 523set to the value of the argument if the option is present, or left 524undefined if the option is not present. If the argument is optional 525but not supplied, C<$opt_b> will be set to the null string. 526 527Note that even if you specify that an option I<requires> a string 528argument, you can still get the null string (if the user specifically 529enters it). If the option requires a numeric argument, you will never 530get the null string (because it isn't a number). 531 532When converting the option name to a Perl identifier, any non-word 533characters in the name will be converted to underscores (C<_>). 534 535If the same option occurs more than once, only the last occurrence 536will be recorded. If that's not acceptable, you'll have to use the 537flexible method instead. 538 539=head2 The Flexible Method 540 541The flexible method is 542 543 use Getopt::Mixed "nextOption"; 544 Getopt::Mixed::init(...option-descriptions...); 545 while (($option, $value, $pretty) = nextOption()) { 546 ...process option... 547 } 548 Getopt::Mixed::cleanup(); 549 550This lets you process arguments one at a time. You can then handle 551repeated options any way you want to. It also lets you see option 552names with non-alphanumeric characters without any translation. This 553is also the only method that lets you find out what order the options 554and other arguments were in. 555 556First, you call Getopt::Mixed::init with the option descriptions. 557Then, you keep calling nextOption until it returns an empty list. 558Finally, you call Getopt::Mixed::cleanup when you're done. The 559remaining (non-option) arguments will be found in @ARGV. 560 561Each call to nextOption returns a list of the next option, its value, 562and the option as the user typed it. The value will be undefined if 563the option does not take an argument. The option is stripped of its 564starter (e.g., you get "a" and "foo", not "-a" or "--foo"). If you 565want to print an error message, use the third element, which does 566include the option starter. 567 568=head1 OTHER FUNCTIONS 569 570Getopt::Mixed provides one other function you can use. C<abortMsg> 571prints its arguments on STDERR, plus your program's name and a 572newline. It then exits with status 1. For example, if F<foo.pl> 573calls C<abortMsg> like this: 574 575 Getopt::Mixed::abortMsg("Error"); 576 577The output will be: 578 579 foo.pl: Error 580 581=head1 CUSTOMIZATION 582 583There are several customization variables you can set. All of these 584variables should be set I<after> calling Getopt::Mixed::init and 585I<before> calling nextOption. 586 587If you set any of these variables, you I<must> check the version 588number first. The easiest way to do this is like this: 589 590 use Getopt::Mixed 1.006; 591 592If you are using the simple method, and you want to set these 593variables, you'll need to call init before calling getOptions, like 594this: 595 596 use Getopt::Mixed 1.006; 597 Getopt::Mixed::init(...option-descriptions...); 598 ...set configuration variables... 599 Getopt::Mixed::getOptions(); # IMPORTANT: no parameters 600 601=over 4 602 603=item $order 604 605$order can be set to $REQUIRE_ORDER, $PERMUTE, or $RETURN_IN_ORDER. 606The default is $REQUIRE_ORDER if the environment variable 607POSIXLY_CORRECT has been set, $PERMUTE otherwise. 608 609$REQUIRE_ORDER means that no options can follow the first argument 610which isn't an option. 611 612$PERMUTE means that all options are treated as if they preceded all 613other arguments. 614 615$RETURN_IN_ORDER means that all arguments maintain their ordering. 616When nextOption is called, and the next argument is not an option, it 617returns the null string as the option and the argument as the value. 618nextOption never returns the null list until all the arguments have 619been processed. 620 621=item $ignoreCase 622 623Ignore case when matching options. Default is 1 unless the option 624descriptions contain an upper-case letter. 625 626=item $optionStart 627 628A string of characters that can start options. Default is "-". 629 630=item $badOption 631 632A reference to a function that is called when an unrecognized option 633is encountered. The function receives three arguments. $_[0] is the 634position in @ARGV where the option came from. $_[1] is the option as 635the user typed it (including the option start character). $_[2] is 636either undef or a string describing the reason the option was not 637recognized (Currently, the only possible value is 'ambiguous', for a 638long option with several possible matches). The option has already 639been removed from @ARGV. To put it back, you can say: 640 641 splice(@ARGV,$_[0],0,$_[1]); 642 643The function can do anything you want to @ARGV. It should return 644whatever you want nextOption to return. 645 646The default is a function that prints an error message and exits the 647program. 648 649=item $checkArg 650 651A reference to a function that is called to make sure the argument 652type is correct. The function receives four arguments. $_[0] is the 653position in @ARGV where the option came from. $_[1] is the text 654following the option, or undefined if there was no text following the 655option. $_[2] is the name of the option as the user typed it 656(including the option start character), suitable for error messages. 657$_[3] is the argument type specifier. 658 659The function can do anything you want to @ARGV. It should return 660the value for this option. 661 662The default is a function that prints an error message and exits the 663program if the argument is not the right type for the option. You can 664also adjust the behavior of the default function by changing 665$intRegexp or $floatRegexp. 666 667=item $intRegexp 668 669A regular expression that matches an integer. Default is 670'^[-+]?\d+$', which matches a string of digits preceded by an 671optional sign. Unlike the other configuration variables, this cannot 672be changed after nextOption is called, because the pattern is compiled 673only once. 674 675=item $floatRegexp 676 677A regular expression that matches a floating point number. Default is 678'^[-+]?(\d*\.?\d+|\d+\.)$', which matches the following formats: 679"123", "123.", "123.45", and ".123" (plus an optional sign). It does 680not match exponential notation. Unlike the other configuration 681variables, this cannot be changed after nextOption is called, because 682the pattern is compiled only once. 683 684=item $typeChars 685 686A string of the characters which are legal argument types. The 687default is 'sif', for String, Integer, and Floating point arguments. 688The string should consist only of letters. Upper case letters are 689discouraged, since this will hamper the case-folding of options. If 690you change this, you should set $checkType to a function that will 691check arguments of your new type. Unlike the other configuration 692variables, this must be set I<before> calling init(), and cannot be 693changed afterwards. 694 695=item $checkType 696 697If you add new types to $typeChars, you should set this to a function 698which will check arguments of the new types. 699 700=back 701 702=head1 BUGS 703 704=over 4 705 706=item * 707 708This document should be expanded. 709 710=item * 711 712A long option must be at least two characters long. Sorry. 713 714=item * 715 716The C<!> argument specifier of Getopt::Long is not supported, but you 717could have options B<--foo> and B<--nofoo> and then do something like: 718 719 $opt_foo = 0 if $opt_nofoo; 720 721=item * 722 723The C<@> argument specifier of Getopt::Long is not supported. If you 724want your values pushed into an array, you'll have to use nextOption 725and do it yourself. 726 727=back 728 729=head1 LICENSE 730 731Getopt::Mixed is distributed under the terms of the GNU General Public 732License as published by the Free Software Foundation; either version 7332, or (at your option) any later version. 734 735This means it is distributed in the hope that it will be useful, but 736I<without any warranty>; without even the implied warranty of 737I<merchantability> or I<fitness for a particular purpose>. See the 738GNU General Public License for more details. 739 740Since Perl scripts are only compiled at runtime, and simply calling 741Getopt::Mixed does I<not> bring your program under the GPL, the only 742real restriction is that you can't use Getopt::Mixed in an 743binary-only distribution produced with C<dump> (unless you also 744provide source code). 745 746=head1 AUTHOR 747 748Christopher J. Madsen E<lt>F<ac608@yfn.ysu.edu>E<gt> 749 750Thanks are also due to Andreas Koenig for helping Getopt::Mixed 751conform to the standards for Perl modules and for answering a bunch of 752questions. Any remaining deficiencies are my fault. 753 754=cut 755