]> git.tdb.fi Git - libs/core.git/blobdiff - source/core/getopt.cpp
Improve GetOpt help generation
[libs/core.git] / source / core / getopt.cpp
index b8e24132b7718ad39f5e3ed63abff7635d1d260c..8fd13a0c0593bc28dab3f276597b8de8a2cf6dd7 100644 (file)
@@ -37,18 +37,18 @@ string GetOpt::generate_usage(const string &argv0) const
                        if(!(*i)->get_long().empty())
                                line<<'|';
                        else if((*i)->get_arg_type()==OPTIONAL_ARG)
-                               line<<"[ARG]";
+                               line<<'['<<(*i)->get_metavar()<<']';
                        else if((*i)->get_arg_type()==REQUIRED_ARG)
-                               line<<" ARG";
+                               line<<' '<<(*i)->get_metavar();
                }
                if(!(*i)->get_long().empty())
                {
                        line<<"--"<<(*i)->get_long();
 
                        if((*i)->get_arg_type()==OPTIONAL_ARG)
-                               line<<"[=ARG]";
+                               line<<"[="<<(*i)->get_metavar()<<']';
                        else if((*i)->get_arg_type()==REQUIRED_ARG)
-                               line<<"=ARG";
+                               line<<'='<<(*i)->get_metavar();
                }
                line<<']';
        }
@@ -62,34 +62,48 @@ The returned string will have a linefeed at the end.
 */
 string GetOpt::generate_help() const
 {
-       string result;
+       bool any_short=false;
+       for(list<OptBase *>::const_iterator i=opts.begin(); (!any_short && i!=opts.end()); ++i)
+               any_short=(*i)->get_short();
+
+       unsigned maxw=0;
+       list<string> switches;
        for(list<OptBase *>::const_iterator i=opts.begin(); i!=opts.end(); ++i)
        {
-               ostringstream line;
-               line<<"  ";
+               ostringstream swtch;
                if((*i)->get_short())
                {
-                       line<<'-'<<(*i)->get_short();
+                       swtch<<'-'<<(*i)->get_short();
                        if(!(*i)->get_long().empty())
-                               line<<", ";
+                               swtch<<", ";
                        else if((*i)->get_arg_type()==OPTIONAL_ARG)
-                               line<<"[ARG]";
+                               swtch<<'['<<(*i)->get_metavar()<<']';
                        else if((*i)->get_arg_type()==REQUIRED_ARG)
-                               line<<" ARG";
+                               swtch<<' '<<(*i)->get_metavar();
                }
+               else if(any_short)
+                       swtch<<"    ";
                if(!(*i)->get_long().empty())
                {
-                       line<<"--"<<(*i)->get_long();
+                       swtch<<"--"<<(*i)->get_long();
 
                        if((*i)->get_arg_type()==OPTIONAL_ARG)
-                               line<<"[=ARG]";
+                               swtch<<"[="<<(*i)->get_metavar()<<']';
                        else if((*i)->get_arg_type()==REQUIRED_ARG)
-                               line<<"=ARG";
+                               swtch<<'='<<(*i)->get_metavar();
                }
+               switches.push_back(swtch.str());
+               maxw=max(maxw, switches.back().size());
+       }
 
-               line<<"  "<<(*i)->get_help()<<'\n';
-
-               result+=line.str();
+       string result;
+       list<string>::const_iterator j=switches.begin();
+       for(list<OptBase *>::const_iterator i=opts.begin(); i!=opts.end(); ++i, ++j)
+       {
+               result+="  "+*j;
+               result+=string(maxw+2-j->size(), ' ');
+               result+=(*i)->get_help();
+               result+='\n';
        }
        
        return result;
@@ -211,4 +225,26 @@ unsigned GetOpt::process_short(const char *const *argp)
        return 1;
 }
 
+
+GetOpt::OptBase::OptBase(char s, const std::string &l, ArgType a):
+       shrt(s),
+       lng(l),
+       arg_type(a),
+       seen_count(0),
+       metavar("ARG")
+{ }
+
+GetOpt::OptBase &GetOpt::OptBase::set_help(const string &h)
+{
+       help=h;
+       return *this;
+}
+
+GetOpt::OptBase &GetOpt::OptBase::set_help(const string &h, const string &m)
+{
+       help=h;
+       metavar=m;
+       return *this;
+}
+
 } // namespace Msp