On Sep 7, 2011, at 4:44 AM, Christian Schmidt wrote:

> Hi,
> 
> I'm trying to parse a command line that can contain multiple variable
> number of arguments for a parameter, e.g.
> 
> <program> -r /dev/sda /dev/sdb -m /dev/sdc /dev/sdd -b 16m …
> 

Traditionally, uglix was designed with the model
        PROGRAM OPTIONS ARGUMENTS
and that is captured in strict POSIX (and still common on *BSD systems iirc).

The default option processing enhances --options=arg to take the "next"
item, and there is the "=" that has been added to introduce some form
of "stickiness".

What you are seeking with multiple arguments to a single option
(and I understand well why you are attempting) isn't well supported
anywhere afaik. The usual solution is to embed white space within
quotes like

        <program> -r "/dev/sda /dev/sdb" -m "/dev/sdc /dev/sdd" -b 16m

> The reason for the space separated lists is simply shell expansion.
> Given existing device nodes you could write <program> -r /dev/sd[ab] -m
> /dev/sd[cd] -b 16m ... to reach the same. Similar expansion could be
> done with {a..z} or wildcard patterns. However this is not a case of
> leftover arguments since the context (in the above example, -r or -m) is
> relevant.
> 

Got it.

> So far I tried to use POPT_ARG_ARGV (which expects one -r/-m for each
> argument) as well as poptPeekArg from within a r/m handler to look at
> the next word in the command line. However, poptPeekArg only seems to
> work after all arguments are parsed.
> 

Yes I can believe that poptPeekArg() isn't going to work for what you
intend. I _MIGHT_ be able to make poptPeekArg() "work" that way, but
its rather tricky to unravel nested coroutine recursions to get
that job done. The implementation would likely need a backtracking
parser so that all the options copuld be parsed out to determine
what exactly the "next" argument should be. POPT is already doing
that to support the rather obscure "!#:+" syntax used by popt aliases.

(aside)
The syntax choice was derived from KSH/BASH … but its dreadfully obscure
shell functionality and only "!#:+" is implemented in POPT.

Here's some usage examples from /usr/lib/rpm/rpmpopt:

        #       [--dbpath DIRECTORY"    "use database in DIRECTORY"
        rpm     alias --dbpath          --define '_dbpath !#:+'
        #       [--ftpport <port>]      "port number of ftp server (or proxy)"
        rpm     alias --ftpport         --define '_ftpport !#:+'
        #       [--ftpproxy <host>]     "hostname or IP of ftp proxy"
        rpm     alias --ftpproxy        --define '_ftpproxy !#:+'
        #       [--httpport <port>]     "port number of http server (or proxy)"
        rpm     alias --httpport        --define '_httpport !#:+'
        #       [--httpproxy <host>]    "hostname or IP of http proxy"
        rpm     alias --httpproxy       --define '_httpproxy !#:+'

You _MIGHT_ be able to consume the next two arguments by rewriting -m/-r
with an alias, and then rewriting what is passed to the program with
a POPT_ARGFLAG_DOC_HIDDEN helper option (--mstuff/--rstuff used in example) like

        program alias -m        --mstuff !#:+ --mstuff !#:+
        program alias -r        --rstuff !#:+ --rstuff !#:+

if the number of "arguments" to -m and -r is always 2 strings.

> Is there a way to realize what I'm trying within the current version of
> popt, and if not, would there be any interest (or chance of being added)
> implementing a POP_ARG_LIST that would act like POPT_ARG_ARGV, but take
> all arguments until the next parameter starting with a "-"?
> 

There's likely some other alternatives using a POPT callback (caveat: it
would require peeping into POPT internal data structures)

And its possible to rewind/restart POPT argument processing, but that
too is quite tricky (RPM used to do multiple passes on options/args
in order to extract one option that then modified how the options were
further processed: total PITA to maintain and not KISS reliable engineering …)

hth

73 de Jeff
> Regards,
> Christian
> ______________________________________________________________________
> POPT Library                                           http://rpm5.org
> Developer Communication List                       popt-devel@rpm5.org

______________________________________________________________________
POPT Library                                           http://rpm5.org
Developer Communication List                       popt-devel@rpm5.org

Reply via email to