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