commandline
commandline copied to clipboard
HELP: Plus/Minus argument parsing; i.e. -optimize[+|-]
I am looking for a little assistance in seeing if I can parse plus/minus (inclusion/negation) arguments with 'commandline'.
i.e. Argument options like:
- someexecutable -optimize+ -unsafe-
- -optimize[+|-]
- -unsafe[+|-]
- -warnaserror[+|-]
Maybe I am just missing something or I have not had enough coffee, but this one is stumping me.
What's the difference between-optimize+ -unsafe-
and -optimize
(aka leaving the parameter out)?
Hi @sushihangover and thank you for choosing our library.
@nemec I think he is using a single dash for specifying option with long names, this is incorrect.
Correctly defining these long names: optimize
, unsafe
, warnaserror
to accept string (or maybe char), you command line could be:
promt$ someexecutable --optimize + --unsafe -
Is it correct? Helped? If not let us know...
Have nice times!
I am looking for inclusion/negation style [+|-] options (no separator between the argument and the option), i.e. :+1:
-optimize[+|-] Enables advanced compiler optimizations (short: -o)
On the cmd line this would be:
To include optimize:
mybin -optimize
mybin -optimize+
To exclude optimize:
mybin -optimize-
There are various apps that use this style, one would be mono C# mcs compiler....
Thanks...
@sushihangover, I'd like to add that various *mcs commands allow long option names with a single switch (I don't know if also --option
is legal...).
Command Line Parser Library (both stable and pre-release) sticks to classic *nix getopt() style.
Said that, I imagine you'd define optimize
as a switch that is a named option attached to a boolean target property.
At the moment a switch defined as:
[Option('o', "optimize")]
public bool Optimize { get; set; }
Can be activated (set to true
) when specified as:
$ yourbin --optimize
if omitted it will be obviously set to false.
To mimic your behaviour you can define it as string (or maybe char, sincerely I've not used char values in my option types; but it's merely a fact, nothing more) and transform the value:
[Option('o', "optimize")]
public string OptimizeSwitch { get; set; }
public bool Optimize { get { return OptimizeSwitch.Equals("+"); } }
public bool Validate() {
return OptimizeSwitch.Equals("+") || OptimizeSwitch.Equals("-");
}
It's not unusual write some custom validation code. If Options::Validate()
fails you can force the parser to print the help screen.
This is what you can actually do with both stable or pre-release. A better solution could be to plan a property that supplies valid values to the parser. I can imagine this as:
[Option('o', "optimize", AllowedValues=new [] { "+", "-" })]
public string OptimizeSwitch { get; set; }
// here you always need to transform string -> bool
Or provide a custom transformation machinery (with also AllowedValues
):
[Option('o', "optimize", AllowedValues=new [] { "+", "-" }, Mapper="PlusMinusToBool")]
public bool Optimize { get; set; }
public Func<string,bool> PlusMinusToBool {
get {
return value => value.Equals("+");
}
}
Also AllowedValues
could be implemented as lambda function supplied by a property.
What do you think?
(cc/ main contrib.: @mizipzor @gimmemoore @nemec)
Just reasoning about possible evolutions... Instead of AllowedValues
implemented as a list of valid alternatives or with a custom validation function, we can use regular expressions.
[Option('o', "optimize", RegExValidation="^(\+|\-){1}$", Mapper="PlusMinusToBool")]
public bool Optimize { get; set; }
public Func<string,bool> PlusMinusToBool {
get {
return value => value.Equals("+");
}
}
Thanks for the quick info.
History: I happen to be writing a input driver and one of those driver apps is mono's mcs, among others, that also happen to use the same style (lots of perl apps). The argument type of those options are usually scalar vs. booleans, but that is not a hard rule and it is broken all the time.
Not sure of the history or reasoning behind using [+][-] in mcs as it is not getopt() nor any MS convention based, but it does have strong roots in perl and I'm assuming the mono were perl-heads as there is some ancient mono work around that has perl scripts driving tons of things. With mono you can supply options like "-v -v" or "-v+ -v+" which will cause the message verbosity to be set higher then just "-v" (1 vs. 2).
With so many different Makefile/build scripts out of my control, parsing the complete arg list supplied, with /, -, -- seps and altering them and passing them along is about the only option I have... For now, I just grabbed mono's driver.cs and hack'd it up, works ok, but will be a big maintenace issue as it is just basically a huge switch statement.
FYI: There is also Options.cs (supplied via mono source lib in their framework which came from Desk.Options) that handles args (include [+][-] via collection initializers and lambda delegates. Beings a single file drop-in, I might use it when I have to touch driver.cs again.
Thanks for all the info!
More info that I found from the perl minded and Getopt lib
http://perldoc.perl.org/Getopt/Long.html
+
The option does not take an argument and will be incremented by 1 every time it appears on the
command line. E.g. "more+" , when used with --more --more --more, will
increment the value three times, resulting in a value of 3 (provided it was 0 or undefined at first).
The + specifier is ignored if the option destination is not a scalar.
This was a good exchange of info! I also know an Erlang library that accepts a repetition of options (but now I can't remember the name...).
I've to do some testing with 2.0 but CommandLine (with stable I've done it in various projects) is also thought to be included as source. For example you can clone the repo, move -R clone/src/CommandLine
inside YourProject/src
, let VisualStudio (if you use it) show files which not belong to project, include the whole directory in it and discard Properties/AssemblyInfo.cs
.
This is just for information purpose...
Coming back to discussion, also if you choose other path, (if possible) I'd like to know what exactly you'd like to see implemented that currently lacks.
- Customization illustrated in my first reply.
- Built-in [+/-] to increment a numerical scalar value.
- Built-in option repetition to mimic point 2 behaviour with (or without) point 2 itself.
could bools be parsed thus:
--mybool
mybool = true
--mybool=true/false
mybool = true/false
--mybool=1/0
true/false
where the latter 2 would allow the bool to be specifed as being required in the config where a value MUST be passed (rather than just the option).
i understand there is talk about -foo
and +foo
. Personally I use long string names only so how would that play with long names?