Support for variable number of arguments in popt

2011-09-07 Thread Christian Schmidt
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 ...

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.

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.

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 -?

Regards,
Christian
__
POPT Library   http://rpm5.org
Developer Communication List   popt-devel@rpm5.org


Re: Support for variable number of arguments in popt

2011-09-07 Thread Jeff Johnson

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 DIRECTORYuse 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