CLIUtils / CLI11

CLI11 is a command line parser for C++11 and beyond that provides a rich feature set with a simple and intuitive interface.

Home Page:https://cliutils.github.io/CLI11/book/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

select order of positional arguments based using arity as a mode switch?

KantarBruceAdams opened this issue · comments

Hi,
New user experimenting with CLI11 here.
I have an application which I want to parse arguments matching the following pattern:

app ?number1 number2? file1 ?file2?

i.e. legal argument orders are:

file1
file1 file2
number1 number2 file1
number1 number2 file1 file2

Basically I want the interpretation of arguments (or rather the mapping of variables) to vary with the number of arguments given (i.e. the arity) .
Is it possible to do this with CLI11?

I suspect the best we can do is with a mode switch like:

app --mode1 file1 ?file2?
app --mode2 number1 number2 file1 ?file2?

mode1 file1
mode1 file1 file2
mode2 number1 number2 file1
mode2 number1 number2 file1 file2

or by making the numbers options instead of positional arguments. ie.

?--numbers number1 number2? file1 ?file2?

Where --numbers is an option with a type_size() of 2.

A related question. What happens with two or more optional positional arguments?
For example if I reordered the parameters to:

file1 ?file2? ?number1 number2?

There is an ambiguous parse as you can't distinguish between file2 and number1 except on type.

In a roll your own parser (which I would like to replace with something like CLI11) I would solve
the first case by selecting the mode (subcommand) based on the number of (positional) arguments.
I might resolve the second case by testing whether the argument was a number or not (though this has the big caveat of preventing numeric filenames).

Would there be any interest in supporting these behaviours (if they aren't already supported) or would they be considered of dubious value?

Before looking at CLI11 I was thinking along the lines of a parser with methods:

add_option() - like CLI11
add_variable(name,variable)
set_positional_arguments(arity,args)
- override positional arguments for a given arity - no args are optional - all are required.
set_positional_arguments(args)
- default positional argument order, optional args can be omitted

where args is a vector of argument names each mapping to the variable (& type) of the same name.

Would that fit in with the design of CLI11?

Related to this, I am curious about a couple of design choices.
Typically with hand rolled parsers I have a loop to parse the options first and parse the positional arguments after the loop (using -- to mean end of options in the unix style). There is no such separation in the parse() method. Is this for efficiency?
The distinction between a positional argument and an option is not by type. It seems to be just whether the name is specified as an option (i.e. "--option" vs "posArg"). That is great for usability but to me a positional argument is not an option (though it could be optional!). This is a category error.
The hierachy in my head notionally is:

class argument
class option: public argument //an option that accepts zero or more following arguments
class flag: public option //an option that accepts no following arguments
class positionalArgument: public argument

In CLI11 it looks like a positional argument is an option where get_positional() == true && nonpositional() == false. Is that right?

Regards Bruce.

Another way of looking at this is asking how the parser handles ambiguity.
Most sets of command line options don't need any kind of lookahead so a simple parser is suffciient.
My case could be resolved by looking ahead to an "end of input" token.
It might also be resolved by a parser that supports backtracking.
Support for either of those might be more general purpose than using the arity directly as I suggested.

I think this can be closed, there are a couple ways of dealing with this now with the pre-parse callback

Agreed.