www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - getopt usage help to stderr?

reply Andy Valencia <dont spam.me> writes:
This seems like something which needs to be straightforward, and 
yet I've spent a good amount of time getting nowhere.

How does one get the usage information which getopt embeds in a 
result, and spit it out to stderr?  The internals show some help 
output, hard-coded to stdout.  As any Posix CLI coder knows, 
that's _not_ where you want error/help output to be forced.  I 
tried variations of:

```d
     (GetoptResult rslt)
     defaultGetoptFormatter!File(stderr, progname, rslt.options);
```

with no success.  Is there really not a rslt.helpString() or 
somesuch?

Thanks,
Andy

p.s. Ironically, I could probably have coded a getopt in less 
time than I've spent on std.getopt....
Apr 08
next sibling parent "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
I think that you are almost there.

https://dlang.org/phobos/std_getopt.html#.defaultGetoptFormatter

Try using: https://dlang.org/phobos/std_stdio.html#.File.lockingTextWriter

``defaultGetoptFormatter(stderr.lockingTextWriter, "heading", 
helpInformation.options);``
Apr 08
prev sibling parent reply Salih Dincer <salihdb hotmail.com> writes:
On Tuesday, 8 April 2025 at 20:14:56 UTC, Andy Valencia wrote:
 p.s. Ironically, I could probably have coded a getopt in less 
 time than I've spent on std.getopt...
:) Please try the following example with the parameters -h, -e, -l, and -v in that order: ```d import std.array : appender; import std.getopt, std.stdio; void main(string[] args) { enum errMsg = "\nPlease try again!"; string test; bool verbose; try { auto rslt = getopt( args, "exit|e", "Exit process", &test, "verbose|v", "Enable verbose output", &verbose ); if (rslt.helpWanted) { // Capture help text to a string import std.array : appender; import std.format : formattedWrite; auto helpText = appender!string(); defaultGetoptFormatter(helpText, args[0], rslt.options); // Output to stderr stderr.write(helpText.data); return; } } catch (Exception e) { stderr.writeln(e.msg, errMsg); // ... Please try again! // Also output help on error auto helpText = appender!string(); defaultGetoptFormatter(helpText, args[0], getopt(args).options); stderr.write(helpText.data); return; } // Your program logic here if (verbose) writeln("Verbose Mode: on"); } ``` SDB 79
Apr 08
next sibling parent Andy Valencia <dont spam.me> writes:
On Wednesday, 9 April 2025 at 01:23:01 UTC, Salih Dincer wrote:
 On Tuesday, 8 April 2025 at 20:14:56 UTC, Andy Valencia wrote:
 p.s. Ironically, I could probably have coded a getopt in less 
 time than I've spent on std.getopt...
:) Please try the following example with the parameters -h, -e, -l, and -v in that order: ...
Thank you. It turned out, aside from treating stderr with lockingTextWriter, I had a couple "in" arguments, which defaultGetoptFormatter wouldn't accept. So with all that cleared up, help is now available. Thank you again (both of you) for the helpful examples! Andy
Apr 08
prev sibling parent kdevel <kdevel vogtner.de> writes:
On Wednesday, 9 April 2025 at 01:23:01 UTC, Salih Dincer wrote:
 On Tuesday, 8 April 2025 at 20:14:56 UTC, Andy Valencia wrote:
 p.s. Ironically, I could probably have coded a getopt in less 
 time than I've spent on std.getopt...
:) Please try the following example with the parameters -h, -e, -l, and -v in that order:
-h prints what one expects. If help is wanted I expect the usage info be written on stdout though. Nothing bothers more than programs with multiple pages of usage help written you cannot pipe cleanly to less. -e says "-h --help This help information" which is not really true, since "This" help information is the help information of the empty list of the second getopt call in line 37 of your code and not the help for the original list. -l crashes with a stack trace after getopt threw in line 37 (Unrecognized option -l). This crash happens because -l is not removed from args. -v does as expected. That your program prints what it prints in the -e case is due to the fact that in the second getopt call (line 37) the -e flag has already been removed from the original args array. If you put the throw block into a function (clean code) that mechanism no longer works. my 2ยข
Apr 10