The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Getopt::Popt - Perl interface to the popt(3) library

SYNOPSIS

    use Getopt::Popt qw(:all);
    
    # setup the options array
    push @options,new Getopt::Popt::Option( 
                                    longName    => "long", 
                                    shortName   => "l",
                                    argInfo     => POPT_ARG_STRING,
                                    arg         => \$qux,
                                    val         => $val);

    # or, if you're lazy, have Getopt::Popt automagically do the new()
    push @options, { shortName => 's', 
                     argInfo => POPT_ARG_NONE, 
                     arg => \$quux,
                     val => 's' 
                   };

    # "val"s can be a single character or an integer:
    push @options, { longName => 'xor',
                     argInfo => POPT_ARG_VAL | POPT_ARGFLAG_XOR,
                     arg => \$quuux,
                     val => 0xbadf00d   # integer
                   },

Enable automatic help/usage messages (--help or --usage):

    push @options, POPT_AUTOHELP;

Create a new popt context:

    $popt = new Getopt::Popt(name       => $alias_name, 
                             argv       => \@ARGV,
                             options    => \@options, 
                             flags      => $flags);

Setup option aliases:

    # load some aliases
    $popt->readDefaultConfig();
    $popt->readConfigFile("/path/to/aliases");
    
    # add your own alias
    $alias = new Getopt::Popt::Alias(longName => "taco", 
                             argv     => [qw(--flavored --kisses)]);
    $popt->addAlias($alias, $alias_flags);

Load options as you would in C:

    # loop through the options, using the popt C way:
    while(($rc = $popt->getNextOpt()) > 0) {
        ...
        # one way to get the arg val
        $bork = $popt->getOptArg();
        ...
        # stuff some args 
        $popt->stuffArgs(qw(-q -u -x));
        ...
        # start over
        $popt->resetContext();
        ...
    }

And handle errors as you would in C:

    $errstr = $popt->strerror($rc);
    $badopt = $popt->badOption($rc,$badopt_flags);

Or try the new perly way:

    eval {
        while(defined($val = $popt->getNextOptChar())) { 
                                              ^^^^-- note!
            # $val is a Scalar::Util::dualvar:
            if($val eq "c") {               # <- character
                ...
            } elsif($val == 0xbeef) {       # <- integer
                ...
            } elsif(ord($val) == 2922) {    # <- utf8, ok!
                ...
            }
            ...
            # you can still stuff args or reset the context as before
            ...
        }
    };
    # check for errors:
    if($@) {
        # prints something like "bad argument: --shoes: unknown option"
        print "bad argument: $@\n"; 
    }

Get leftover args:

    $arg = $popt->peekArg();
    $arg = $popt->getArg();
    @args = $popt->getArgs();

DESCRIPTION

This module provides an interface to (most of) the functions available in the popt library. See the popt(3) manpage for more details about what the popt library can do.

METHODS

Getopt::Popt should look like a fairly natural object oriented mapping to all of the popt functions.

Getopt::Popt

Getopt::Popt->new( %params )

Create a new Getopt::Popt context. Parameters map to the arguments to popt's poptGetContext(), plus one additional argument:

    %params = (
            alias_name  => $name,
            argv        => \@argv,
            options     => \@options,
            flags       => $flags,

            # new and special: 
            dont_prepend_progname => $bool, 
            );

Dies on an error.

$alias_name

Name for lookup in alias definitions (see the popt(3) manpage). Can be empty.

\@argv

Command line arguments, e.g. \@ARGV. NOTE: \@argv will be passed to popt as the array ($0, @argv) (a copy is made so that your \@argv won't be modified) unless given the dont_prepend_progname option (see below).

$flags

Context flags (see CONSTANTS). Defaults to 0.

\@options

Options array. All elements must be either a Getopt::Popt::Option or a hashref; hashrefs will be automagically converted into Getopt::Popt::Options.

$dont_prepend_progname

Don't stick $0 before @argv. Perl's @ARGV just has arguments and does not include the current process name, but popt expects something in argv[0]. So $0 is prepended unless this flag has been set. It's an error if dont_prepend_progname is true but @argv is empty.

Defaults to 0.

Getopt::Popt::getNextOptChar()

This is a wrapper around Getopt::Popt::getNextOpt(). Returns a dualvar (see Scalar::Util) rather than just an integer. In a numeric context ("0+$ch" or "$ch == $number") the return value is the integer value that Getopt::Popt::getNextOpt() would've returned, and in a string context the return value is a character. Really all it saves you is having to use chr() all the time.

Returns undef when it's done reading args, dies with a Getopt::Popt::strerror()'d message on an error.

See the popt(3) manpage for details on these methods:

Getopt::Popt::resetContext()
Getopt::Popt::getNextOpt()
Getopt::Popt::getOptArg()
Getopt::Popt::getArg()
Getopt::Popt::peekArg()
Getopt::Popt::getArgs()
Getopt::Popt::strerror($error)
Getopt::Popt::badOption($flags)
Getopt::Popt::readDefaultConfig()
Getopt::Popt::readConfigFile()
Getopt::Popt::addAlias($alias, $flags)
Getopt::Popt::setOtherOptionHelp($str)
Getopt::Popt::stuffArgs(@args)

Getopt::Popt::Option

SYNOPSIS

Represents a struct poptOption

Getopt::Popt::Option->new( %params )

Create a new option. %params maps to popt's struct poptOption:

    %params = (
            longName    => $longName,
            shortName   => $shortName,  # single char
            argInfo     => $argInfo,    # see CONSTANTS below
            arg         => \$arg,       # depends on $argInfo
            val         => $val,        # integer OR single character
            descrip     => $descrip,
            argDescrip  => $argDescrip,
            );

Dies on an error.

$longName

Long name of the argument, e.g. "--foo"'s long name is "foo".

$shortName

Short name of the argument, e.g. "-f"'s short name is "f". Must be a single character.

$argInfo

An integer, bitwise-ORed with different flags (see CONSTANTS below).

\$arg

A scalar reference, with the scalar being set to the option argument value.

$val

The value to be returned by getNextOpt() (or getNextOptChar()). Can be a single character or an integer.

Note that if you want $val to be a real single-digit integer (and not the character representation of it), pass it in as "+1" or "1.0", or as "\1". If you use any of the bit operations (POPT_ARGFLAG_[AND|OR|XOR]) that popt has, it's important that "1" be a 1 and not ord("1") = 49. Otherwise you probably don't care.

$descrip

Long description of the option, used in generating autohelp.

$argDescrip

Short description of the argument to the option, used in generating autohelp.

Value getters (no setters):

Getopt::Popt::Option::getLongName()
Getopt::Popt::Option::getShortName()
Getopt::Popt::Option::getArgInfo()
Getopt::Popt::Option::getArg()
Getopt::Popt::Option::getVal()
Getopt::Popt::Option::getDescrip()
Getopt::Popt::Option::getArgDescrip()

Getopt::Popt::Alias

SYNOPSIS

Represents a struct poptAlias

Getopt::Popt::Alias->new( %params )

Create a new alias to pass to Getopt::Popt::addAlias(). %params maps to popt's struct poptAlias:

    %params = (
            longName    => $longName,
            shortName   => $shortName,  # single char
            argv        => \@args,      # non-empty array of args
            );

Dies on an error.

CONSTANTS

Most of the constant integers defined in popt.h (except for a few relating to callbacks and table inclusion, see TODO below) are available for import via the :all tag. Other tags are: :argflag for argument flags, :arg for argument types, :autohelp for POPT_AUTOHELP, :badoption for POPT_BADOPTION_NOALIAS, :context for context flags, and :error for error values.

You can use the the POPT_AUTOHELP constant just as you would in C. Just put it on your \@options and autohelp will be enabled.

EXAMPLES

The following is a perl implementation of the example given in the popt(3) manpage.

    #!/usr/bin/perl
    use Getopt::Popt qw(:all);
    use strict;

    main();

    sub usage {
      my $popt = shift;
      my $exitcode = shift;
      my $error = shift;
      my $addl = shift;
      # not implemented:
      # $popt->printUsage(\*STDERR, 0); 
      print STDERR "do --help to show options\n";
      print STDERR "$error $addl\n" if $error;
      exit($exitcode);
    }

    sub main {
      my $c;        # used for argument parsing
      my $portname;
      my $speed;    # used in argument parsing to set speed
      my $raw;      # raw mode?
      my @buf;
      my $popt;

      my @optionsTable = (
          {
            longName => "bps", 
            shortName => 'b', 
            argInfo => POPT_ARG_INT, 
            arg => \$speed, 
            val => 0,
            descrip => "signaling rate in bits-per-second", 
            argDescrip => "BPS" 
          },
          {
            longName => "crnl",
            shortName => 'c',
            argInfo => 0,
            val => 'c',
            descrip => "expand cr characters to cr/lf sequences" 
          },
          {  
            longName => "hwflow",
            shortName => 'h',
            argInfo => 0,
            val => 'h',
            descrip => "use hardware (RTS/CTS) flow control" 
          },
          { 
            longName => "noflow",
            shortName => 'n',
            argInfo => 0,
            val => 'n',
            descrip => "use no flow control" 
          },
          {  
            longName => "raw",
            shortName => 'r',
            argInfo => 0,
            arg => \$raw,
            descrip => "don't perform any character conversions" 
          },
          { 
            longName => "swflow",
            shortName => 's',
            argInfo => 0,
            val => 's',
            descrip => "use software (XON/XOF) flow control" 
          } ,
          POPT_AUTOHELP,
      );

      $popt = new Getopt::Popt(argv => \@ARGV,options => \@optionsTable);
      $popt->setOtherOptionHelp("[OPTIONS]* <port>");

      if (@ARGV < 1) {
        # not implemented
        #$popt->printUsage(optCon, stderr, 0);
        print STDERR "not enough arguments: do --help to show options\n";
        exit(1);
      }

      # Now do options processing, get portname
      eval {
        while (defined($c = $popt->getNextOptChar())) {
          push(@buf,'c') if $c eq 'c';
          push(@buf,'h') if $c eq 'h';
          push(@buf,'s') if $c eq 's';
          push(@buf,'n') if $c eq 'n';
        }
      };

      if ($@) {
        # an error occurred during option processing
        my($msg) = ($@ =~ m/(.*) at [\S]+ line \d+\s*$/);
        printf(STDERR  "bad argument: $msg\n");
        exit 1;
      }

      $portname = $popt->getArg();
      if(($portname eq "") || !($popt->peekArg() eq "")) {
        usage($popt, 1, "Specify a single port", ".e.g., /dev/cua0");
      }


      # Print out options, portname chosen
      print("Options  chosen: ");
      print("-$_ ") foreach @buf;
      print("-r ") if(defined($raw));
      print("-b $speed") if(defined($speed));
      print("\nPortname chosen: $portname\n");

      exit(0);
    }

BUGS

This module should be considered beta quality. Don't use it where a possible buffer overflow or double-free or something would be a bad thing. Comments and bug fixes are greatly appreciated!

POPT_ARG_VAL is converted internally to POPT_ARG_NONE (but don't worry, it still sets \$arg to $val). As a consequence, the behavior may be slightly different.

If you're using POPT_AUTOHELP and the user gives --help or --usage, popt exits and any exit handlers, destructors, etc. won't be called. This is expected to be fixed once printHelp() and printUsage() get implemented (see TODO below).

Tested with popt-1.6 and popt-1.7 on Debian woody i386, and on slack 9 with popt-1.7, YMMV.

TODO

Finish writing this documentation.

Need to implement: printHelp(), printUsage(), callbacks, parseArgvString(), and dupArgv()

Probably won't implement: table inclusion (because it's easier to just pass around perl arrays of options);

SEE ALSO

popt(3), Getopt::Std, Getopt::Long, and everything in http://search.cpan.org/modlist/Option_Parameter_Config_Processing

The latest version of the popt library is distributed with rpm and is always available from: ftp://ftp.rpm.org/pub/rpm/dist.

AUTHORS

This module is by James Baker <jamesb-at-cpan-dot-org>.

The popt library is by Erik W. Troan <ewt-at-redhat-dot-com>.

COPYRIGHT AND DISCLAIMER

This program is Copyright 2003 by James Baker. This program is free software; you can redistribute it and/or modify it under the terms of the Perl Artistic License or the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This program 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 General Public License for more details.

If you do not have a copy of the GNU General Public License write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

2 POD Errors

The following errors were encountered while parsing the POD:

Around line 681:

You forgot a '=back' before '=head3'

Around line 685:

'=item' outside of any '=over'