Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HELP: Plus/Minus argument parsing; i.e. -optimize[+|-] #158

Open
sushihangover opened this issue Jun 12, 2015 · 9 comments
Open

HELP: Plus/Minus argument parsing; i.e. -optimize[+|-] #158

sushihangover opened this issue Jun 12, 2015 · 9 comments

Comments

@sushihangover
Copy link

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.

@nemec
Copy link
Collaborator

nemec commented Jun 12, 2015

What's the difference between-optimize+ -unsafe- and -optimize (aka leaving the parameter out)?

@gsscoder
Copy link
Owner

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!

@sushihangover
Copy link
Author

I am looking for inclusion/negation style [+|-] options (no separator between the argument and the option), i.e. 👍

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

@gsscoder
Copy link
Owner

@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)

@gsscoder
Copy link
Owner

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("+");
  }
}

@sushihangover
Copy link
Author

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!

@sushihangover
Copy link
Author

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.

@gsscoder
Copy link
Owner

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.

  1. Customization illustrated in my first reply.
  2. Built-in [+/-] to increment a numerical scalar value.
  3. Built-in option repetition to mimic point 2 behaviour with (or without) point 2 itself.

@ChangePlaces
Copy link

ChangePlaces commented Feb 11, 2017

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants