-
-
Notifications
You must be signed in to change notification settings - Fork 741
Fix issue 14724 - std.getopt: config.required breaks --help #3489
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
Conversation
} | ||
cfg.required = false; | ||
|
||
return getoptImpl(args, cfg, rslt, opts[lowSliceIdx .. $]); | ||
getoptImpl(args, cfg, rslt, opts[lowSliceIdx .. $]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't this kill the tail-call optimization?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see getopt being enough of bottleneck anywhere to care about micro-optimizations like tail-call here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably not. I'm not a huge fan of allocating the exceptions without throwing them though.
I think this can be handled easier by processing the --help option first (possibly outside the Impl function). Then you know while processing each parameter that --help has been passed or not. |
if you handle help outside impl, the "not so new h|help" functionally would break legacy code, as currently the user can use h and help for anything they want. Changing that is not good IMO. Even if that would re-enable tail-call optimization, if it was present in the first place. |
This is possible to work around:
if(helpIncluded)
return getOptImpl(args, cfg, rslt, options);
else
return getOptImpl(args, cfg, rslt, "help|h", "This help information.", () {rslt.helpWanted = true;}, options); And you can avoid all the specific help code in the implementation. This should be identical to current implementation result, but without triggering exception on --help. As it is, I think the way this is done is terrible. What if the app isn't written in English? |
the searching part would require to iterate the complete input, properly recursive as it is done currently. I think the cure is worse than the disease (IMO it is not even a problem) |
No. foreach(opt; options)
static if(is(typeof(opt) == string))
if(opt == "help|h") helpIncluded = true; |
Also note, the current code will add a "help" option at the end for displaying help, even if you have handled help on your own. |
actually I think that is not the case the in-build help is only used if there are no more options to process but you still have arguments left. |
import std.getopt;
void main(string[] args)
{
bool help;
auto rslt = getopt(args, "help|h", "test help", &help);
if (help)
{
defaultGetoptPrinter("Some information about the program.",
rslt.options);
}
}
|
hm, my bad |
Thinking about this some more. I really am kind of not liking that we handle unspecified required arguments with an exception. Even if we fix this, someone who handles --help on their own will be subject to the same issue. I don't know a good way to fix this. |
Updated PR title to be more descriptive. |
@quickfur thanks |
some nicer impl
@schveiguy @quickfur please have a look the tail recursion returned |
LGTM. |
I'll merge, but I found another problem that will make this problem obsolete :) See https://issues.dlang.org/show_bug.cgi?id=14921 |
Auto-merge toggled on |
Fix issue 14724 - std.getopt: config.required breaks --help
std.getopt: Re-add constructor removed in PR #3489
std.getopt: Re-add constructor removed in PR #3489
https://issues.dlang.org/show_bug.cgi?id=14724