www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 11737] New: Allow optional string value for getopt switches

reply d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=11737

           Summary: Allow optional string value for getopt switches
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: Phobos
        AssignedTo: nobody puremagic.com
        ReportedBy: arttu.h yandex.com



Say you want a command line switch like --log. This should enable logging to a
predefined file default.log. User should also be able to use --log=somefile.log
to define where things should be logged.

I tried to achieve this with getopt, but couldn't find a way for it. Adding
--log twice to getopt doesn't work as it just throws an exception if the given
value doesn't fit whatever was added first.

Perhaps there are some workarounds for this such as using config.passThrough
and manually handling --log. However, as this is quite common in command-line
parsing, it would be a nice addition to getopt.

One way this could be achieved: allow an option that takes a string value, but
can be used without a value, in which case the string is set to a default
value.

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Dec 13 2013
next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=11737


Andrej Mitrovic <andrej.mitrovich gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |andrei erdani.com,
                   |                            |andrej.mitrovich gmail.com



10:54:11 PST ---
I'm thinking of the following, this current code will allow --log=value, but
not --log:

-----
import std.getopt;
import std.stdio;

void main(string[] args)
{
    getopt(args,
           "log",
           (string option, string value)
           {
                // store value here
                writeln(value);
           });
}
-----

$ rdmd test.d --log=foo
 foo
$ rdmd test.d --log
 object.Exception C:\dmd-git\dmd2\windows\bin\..\..\src\phobos\std\getop
t.d(486): Missing value for argument --log. So it's meant to catch bugs. However I think we can extend this, and make getopt check whether the value parameter has a default initializer: ----- import std.getopt; import std.stdio; void main(string[] args) { getopt(args, "log", (string option, string value = "bar") // should allow '--log' { // value is either set (e.g. --log=foo), or set to "bar" (--log) writeln(value); }); } ----- That way we don't break code and introduce this new feature. Andrei, thoughts? -- Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Dec 15 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=11737




PST ---
I think the default argument trick is quite neat. Andrej, would you care to
implement it?

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Dec 15 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=11737


Orvid King <blah38621 gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |blah38621 gmail.com




 I think the default argument trick is quite neat. Andrej, would you care to
 implement it?
I'm sure he'd love to implement it, but delegate and function pointer types don't currently keep any information on the name or default value of their parameters, meaning that this is currently impossible without declaring a function and passing it as an alias template parameter. -- Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Dec 15 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=11737




PST ---
Upon a bit more thinking, the trick is rather subtle. Perhaps it would be more
straightforward to allow two lambdas with the same option, and invoke the
appropriate one.

import std.getopt;
import std.stdio;

void main(string[] args)
{
    getopt(args,
           "log",
           (string option)  // should allow '--log'
           {
           },
           "log",
           (string option, string value)  // should allow '--log=value'
           {
           });
);
}

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Dec 15 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=11737






 I think the default argument trick is quite neat. Andrej, would you care to
 implement it?
I'm sure he'd love to implement it, but delegate and function pointer types don't currently keep any information on the name or default value of their parameters, meaning that this is currently impossible without declaring a function and passing it as an alias template parameter.
I just realized this probably came off a wee bit more confrontational than I meant it to, woops. Either way, I think the default value option for a delegate is a beautiful way to solve the problem, as I think having 2 separate delegates is just a bit too verbose, especially as they are likely to contain the exact same code. -- Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Dec 15 2013
prev sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=11737




12:30:23 PST ---


 I think the default argument trick is quite neat. Andrej, would you care to
 implement it?
I'm sure he'd love to implement it, but delegate and function pointer types don't currently keep any information on the name or default value of their parameters, meaning that this is currently impossible without declaring a function and passing it as an alias template parameter.
getopt is a variadic template, so it's possible to extract this information: ----- import std.traits; void getopt(T...)(ref string[] args, T opts) { static assert(ParameterDefaultValueTuple!(opts[1])[1] == "bar"); } void main(string[] args) { getopt(args, "log", (string option, string value = "bar") { }); } ----- -- Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Dec 15 2013