James Baker > Getopt-Popt > Getopt::Popt

Download:
Getopt-Popt-0.02.tar.gz

Dependencies

Annotate this POD

CPAN RT

Open  0
Report a bug
Module Version: 0.02   Source  

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.