Bug 16604 – [std.getopt] defaultGetoptPrinter can't be used if an exception fires

Status
ASSIGNED
Severity
enhancement
Priority
P4
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2016-10-08T07:29:26Z
Last change time
2024-12-01T16:28:06Z
Assigned to
Eduard Staniloiu
Creator
Kevin
Moved to GitHub: phobos#10204 →

Comments

Comment #0 by kevin — 2016-10-08T07:29:26Z
If an exception is thrown by getopt, the GetoptResults.options array is never returned. If it isn't returned, then I can't use the defaultGetoptPrinter function. This makes it impossible to call defaultGetoptPrinter in the event that a program's user ever makes a mistake. The GetoptResults.options array is static regardless of what options are passed to the arguments of the program. It should always be built before any exceptions fire. The only way around this is to have an exception show a generic "you made a mistake calling the program, call 'program --help' to see usage", or to call getopt with an empty args string and no required parameters to build a second options array first. Both are klunky.
Comment #1 by edi33416 — 2017-01-10T22:07:24Z
There is a more elegant solution. You can use the passThrough config directive. From the docs: "Passing unrecognized options through: If an application needs to do its own processing of whichever arguments getopt did not understand, it can pass the std.getopt.config.passThrough directive to getopt. An unrecognized option such as "--baz" will be found untouched in args after getopt returns." So, you could do something like this: auto helpInformation = getopt( args, std.getopt.config.passThrough, /* Your options here */); if (helpInformation.helpWanted || (args.length > 1)) { defaultGetoptPrinter("Some information about the program.", helpInformation.options); } Any mistaken/nonexistent option will be in args, starting with index 1 (at args[0] you will have the name of your program)
Comment #2 by witold.baryluk+d — 2020-05-11T04:00:13Z
Yeah, I did find the exception throwing a bit problematic, and after some time of scratching, used similar trick to what Eduard proposed here. But the fact that getopt is a function the immediately operates on the args, and doesn't provide introspection or compostability is a problem. I think a Python argparse has a bit more interesting design, not because of it OOP-ness, but because it can have sub-parsers, you can compose them compose them easily, i.e. if you have multiple libraries that can be tweaked by some program flags, it is essentially impossible to use getopt. You can grab the unprocessed args, but then there is no easy way to forward it to other consumers implicitly really. I grow a lot with Google flags ( https://github.com/gflags/gflags ) and golang flags (https://golang.org/pkg/flag/) when I did work at Google, and in fact I like them a lot. Similar solutions exist for Java. If there is a way to do this things easily with getopt, I think documentation should be updated to show how to do it.
Comment #3 by robert.schadek — 2024-12-01T16:28:06Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/phobos/issues/10204 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB