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