www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - String argument with optional value in std.getopt

reply Hassan <azi.hassan live.fr> writes:
Hello

I'm trying to get getopt to recognize an argument that may or may 
not take a value. Here's an example :

./hashtrack --list
./hashtrack --list filter

The problem is that if I point list to a string variable, the 
first call fails with "Missing value for argument --list".

I tried having it point to a callback with an optional second 
parameter :

void cb(string option, string value = "")
{
     writeln("--list");
     option.writeln();
     value.writeln();
}

But I get the same error. I also tried having two callbacks with 
the same name. The first one takes a single argument, and the 
second one accepts two :

void cb(string option)
{
     writeln("--list");
     option.writeln();
}

void cb(string option, string value)
{
     writeln("--list");
     option.writeln();
     value.writeln();
}

But it only calls the first one. I'm using DMD64 D Compiler 
v2.090.0. Any pointers ?
Aug 08 2020
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 8/8/20 7:58 PM, Hassan wrote:
 Hello
 
 I'm trying to get getopt to recognize an argument that may or may not 
 take a value. Here's an example :
 
 ../hashtrack --list
 ../hashtrack --list filter
 
 The problem is that if I point list to a string variable, the first call 
 fails with "Missing value for argument --list".
 
 I tried having it point to a callback with an optional second parameter :
 
 void cb(string option, string value = "")
 {
      writeln("--list");
      option.writeln();
      value.writeln();
 }
 
 But I get the same error. I also tried having two callbacks with the 
 same name. The first one takes a single argument, and the second one 
 accepts two :
 
 void cb(string option)
 {
      writeln("--list");
      option.writeln();
 }
 
 void cb(string option, string value)
 {
      writeln("--list");
      option.writeln();
      value.writeln();
 }
 
 But it only calls the first one. I'm using DMD64 D Compiler v2.090.0. 
 Any pointers ?
getopt doesn't support optional parameters. Two things I can think of: 1. Have 2 options that do the same thing, but only one accepts a parameter (e.g. `--list` and `--listf filter`) 2. If your optional parameters are not tied to the option itself, then don't accept them via getopt. In other words, if `hashtrack filter` is supposed to be valid, then filter isn't an option after all, it's a standard parameter. -Steve
Aug 09 2020
parent Hassan <azi.hassan live.fr> writes:
Thanks for the reply Steve

On Sunday, 9 August 2020 at 12:20:16 UTC, Steven Schveighoffer 
wrote:
 2. If your optional parameters are not tied to the option 
 itself, then don't accept them via getopt. In other words, if 
 `hashtrack filter` is supposed to be valid, then filter isn't 
 an option after all, it's a standard parameter.
"filter" can be any string really. It's like an input to the list option : hashtrack --list filter_by_this_word I wasn't aware that there was a distinction between parameters and options. The tool I'm writing is a D port of an existing Go command line utility that uses parameters everywhere, things like "hashtrack list" instead of "hashtrack --list". I decided to use options as opposed to parameters because then I would get to use getopt to handle "args" and display a nicely formatted --help output. I decided to go with this second solution even though "hashtrack filter" isn't technically valid. Here's what I did : void main() { //.... bool list; auto opts = args.getopt( "login", "Creates a session token and store it in the local filesystem in a config file", &login, "logout", "Remove the locally stored session token", &logout, "track", "Tracks one or more hashtags", &track, "untrack", "Untracks one or more previously tracked hashtags", &untrack, "tracks", "Displays the hashtags you are tracking", &tracks, "list", "Displays the latest 50 captured tweets", &list, "watch", "Stream and display the captured tweets in real-time", &watch, "status", "Displays who you are, if logged in", &status, "endpoint", "Point to another server", &endpoint, "config", "Load a custom config file", &config ); //.... if(list) { string filter = args.length > 1 ? args[1] : ""; tracking.list(filter).each!writeln; } }
Aug 09 2020