]> git.tdb.fi Git - libs/core.git/commitdiff
Improve GetOpt help generation
authorMikko Rasa <tdb@tdb.fi>
Thu, 7 May 2009 06:01:55 +0000 (06:01 +0000)
committerMikko Rasa <tdb@tdb.fi>
Thu, 7 May 2009 06:01:55 +0000 (06:01 +0000)
source/core/getopt.cpp
source/core/getopt.h

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
index 7e5e25f5a1a9ee9994995cc9c77ca4355db8e8b7..f6c48597c5220f73998f1ced0ccc6faf5411a445 100644 (file)
@@ -27,11 +27,13 @@ public:
        class OptBase
        {
        public:
-               OptBase           &set_help(const std::string &h) { help=h; return *this; }
+               OptBase           &set_help(const std::string &);
+               OptBase           &set_help(const std::string &, const std::string &);
                char              get_short() const               { return shrt; }
                const std::string &get_long() const               { return lng; }
                ArgType           get_arg_type() const            { return arg_type; }
                const std::string &get_help() const               { return help; }
+               const std::string &get_metavar() const            { return metavar; }
                unsigned          get_seen_count() const          { return seen_count; }
                virtual void      process()=0;
                virtual void      process(const std::string &)=0;
@@ -42,8 +44,9 @@ public:
                ArgType     arg_type;
                unsigned    seen_count;
                std::string help;
+               std::string metavar;
 
-               OptBase(char s, const std::string &l, ArgType a): shrt(s), lng(l), arg_type(a), seen_count(0) { }
+               OptBase(char, const std::string &, ArgType);
        };
 
 private: