www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 3780] New: getopt improvements by Igor Lesik

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

           Summary: getopt improvements by Igor Lesik
           Product: D
           Version: unspecified
          Platform: Other
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: andrei metalanguage.com



18:38:17 PST ---
Below is a paste of the page at http://www.curoles.com/j/getoptex.html. The
code should be added to std.getopt, perhaps as an overload of the current
function. Thanks Igor! I will add your name to the authors list when I make the
change.

getoptex

One way to extend Phobos library std.getopt.getopt function is make a wrapper
around it that could be feeded with usage information about every option and
let it automatically gather all usage strings into one usage/help message
block, similarly to Boost program_options library

Links:

http://en.wikipedia.org/wiki/Tuple
http://www.digitalmars.com/d/2.0/phobos/std_getopt.html
http://www.digitalmars.com/d/2.0/phobos/std_typetuple.html
Below is an example how getoptEx could be used:

import getoptex;
import std.stdio;


void main(string[] args)
{
    string inputFile, outputFile;

    bool helpPrinted = getoptEx(
        "Test program to demonstrate getoptEx\n"~
        "written by Igor Lesik on Feb 2010\n"~
        "Usage: test1 { --switch }\n",
        args,
        std.getopt.config.caseInsensitive,
        "input",
            "\tinput file name,\n"~
            "\tmust be html file",
            &inputFile,
        "output",
            "\toutput file name",
            &outputFile,
        "author",
            "\tprint name of\n"~
            "\tthe author",
            delegate() {writeln("Igor Lesik");}
    );

    if (helpPrinted)
        return;

    writeln("Input file name:", inputFile);
    writeln("Output file name:", outputFile);
}
If you call the program with --help option, then output is:

test1.exe --help
Test program to demonstrate getoptEx written by Igor Lesik on Feb 2010 Usage: test1 { --switch } --input input file name, must be html file --output output file name --author print name of the author --help produce help message getopEx implementation: module getoptex; import std.stdio; import std.getopt; private import std.contracts; private import std.typetuple; private import std.conv; bool getoptEx(T...)(string helphdr, ref string[] args, T opts) { enforce(args.length, "Invalid arguments string passed: program name missing"); string helpMsg = GetoptHelp(opts); // extract all help strings bool helpPrinted = false; // state tells if called with "--help" void printHelp() { writeln("\n", helphdr, "\n", helpMsg, "--help", "\n\tproduce help message"); helpPrinted = true; } getopt(args, GetoptEx!(opts), "help", &printHelp); return helpPrinted; } private template GetoptEx(TList...) { static if (TList.length) { static if (is(typeof(TList[0]) : config)) { // it's a configuration flag, lets move on alias TypeTuple!(TList[0],GetoptEx!(TList[1 .. $])) GetoptEx; } else { // it's an option string, eat help string alias TypeTuple!(TList[0],TList[2],GetoptEx!(TList[3 .. $])) GetoptEx; } } else { alias TList GetoptEx; } } private string GetoptHelp(T...)(T opts) { static if (opts.length) { static if (is(typeof(opts[0]) : config)) { // it's a configuration flag, skip it return GetoptHelp(opts[1 .. $]); } else { // it's an option string string option = to!(string)(opts[0]); string help = to!(string)(opts[1]); return( "--"~option~"\n"~help~"\n"~GetoptHelp(opts[3 .. $]) ); } } else { return to!(string)("\n"); } } Page generated by Ddoc. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Feb 07 2010
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3780


Andrei Alexandrescu <andrei metalanguage.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |ASSIGNED
         AssignedTo|nobody puremagic.com        |andrei metalanguage.com
           Severity|normal                      |enhancement


-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 07 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3780




20:12:47 PDT ---
I can't find the code for download. Does anyone have Igor Lesik's email
address?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jun 05 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3780


Igor Lesik <curoles yahoo.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |curoles yahoo.com



I will see how I can work it into github, meanwhile I paste the original page
as comment here. Igor

getoptex

One way to extend Phobos library std.getopt.getopt function is make a wrapper
around it that could be feeded with usage information about every option and
let it automatically gather all usage strings into one usage/help message
block, similarly to Boost program_options library 

Links: 

http://en.wikipedia.org/wiki/Tuple 
http://www.digitalmars.com/d/2.0/phobos/std_getopt.html 
http://www.digitalmars.com/d/2.0/phobos/std_typetuple.html 

Below is an example how getoptEx could be used: 

import getoptex;
import std.stdio;


void main(string[] args)
{
    string inputFile, outputFile;

    bool helpPrinted = getoptEx(
        "Test program to demonstrate getoptEx\n"~
        "written by Igor Lesik on Feb 2010\n"~
        "Usage: test1 { --switch }\n",
        args,
        std.getopt.config.caseInsensitive,
        "input",
            "\tinput file name,\n"~
            "\tmust be html file",
            &inputFile,
        "output",
            "\toutput file name",
            &outputFile,
        "author",
            "\tprint name of\n"~
            "\tthe author",
            delegate() {writeln("Igor Lesik");}
    );

    if (helpPrinted)
        return;

    writeln("Input file name:", inputFile);
    writeln("Output file name:", outputFile);
}

If you call the program with --help option, then output is: 

test1.exe --help
Test program to demonstrate getoptEx written by Igor Lesik on Feb 2010 Usage: test1 { --switch } --input input file name, must be html file --output output file name --author print name of the author --help produce help message getopEx implementation: module getoptex; import std.stdio; import std.getopt; private import std.contracts; private import std.typetuple; private import std.conv; bool getoptEx(T...)(string helphdr, ref string[] args, T opts) { enforce(args.length, "Invalid arguments string passed: program name missing"); string helpMsg = GetoptHelp(opts); // extract all help strings bool helpPrinted = false; // state tells if called with "--help" void printHelp() { writeln("\n", helphdr, "\n", helpMsg, "--help", "\n\tproduce help message"); helpPrinted = true; } getopt(args, GetoptEx!(opts), "help", &printHelp); return helpPrinted; } private template GetoptEx(TList...) { static if (TList.length) { static if (is(typeof(TList[0]) : config)) { // it's a configuration flag, lets move on alias TypeTuple!(TList[0],GetoptEx!(TList[1 .. $])) GetoptEx; } else { // it's an option string, eat help string alias TypeTuple!(TList[0],TList[2],GetoptEx!(TList[3 .. $])) GetoptEx; } } else { alias TList GetoptEx; } } private string GetoptHelp(T...)(T opts) { static if (opts.length) { static if (is(typeof(opts[0]) : config)) { // it's a configuration flag, skip it return GetoptHelp(opts[1 .. $]); } else { // it's an option string string option = to!(string)(opts[0]); string help = to!(string)(opts[1]); return( "--"~option~"\n"~help~"\n"~GetoptHelp(opts[3 .. $]) ); } } else { return to!(string)("\n"); } } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jun 14 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3780


jens.k.mueller gmx.de changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jens.k.mueller gmx.de



Igor, I already have the code in my local repository. I will create pull
request if you don't mind and make you the author of that commit.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jun 15 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3780


Trass3r <mrmocool gmx.de> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |mrmocool gmx.de



Where is that pull request?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 03 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3780




It's still in my local repository. The point is that getting the other changes
in is a bit problematic due to changing of defaults and breaking code. And the
other getopt changes may break code. That's why I wanted to have all changes
(including generating usage information) in one pull request.
At the moment there is no decision whether breaking old code is worth it. That
got me distracted. But I should finish the code. I will provide a new function
called getOptions to avoid breaking any code since there is some controversy
about the proper defaults and similar.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 03 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3780


Alexey G <golovanov_alexey mail.ru> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |golovanov_alexey mail.ru



---
Any news?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 20 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3780




---
Any news?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Dec 22 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3780




PST ---
Didn't have time to get to this, and probably won't for a while. Could anyone
take it over?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 26 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3780




There is my pull request
https://github.com/D-Programming-Language/phobos/pull/1030.

If somebody comments I'm happy to finish it. The reason why I was less willing
to finish it is that I don't like implementing stuff that nobody would use. So
please comment on the API from a usage point of view and I will implement it.

BTW Recently I was wondering whether it is the right way to throw exceptions
because I find that this is not a rare situation. Actually it's a pretty common
situation to do some usage error. But either way I want to finish it.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 26 2013
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3780




PDT ---
 If somebody comments I'm happy to finish it.
Good job! Thanx!
 I don't like implementing stuff that nobody would use.
Nobody? I have no statistics. But, IMHO, everybody, who write small command line utilities with D, today "invent the wheel" every time. Best way - to have this features in std library. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 25 2013