]> git.tdb.fi Git - libs/core.git/blobdiff - source/core/getopt.cpp
Fix a compilation error on 64-bit systems
[libs/core.git] / source / core / getopt.cpp
index 67c4d4171d1ada94d8077f461175c40878fed669..498977569e2179ee203de59f0e1624b536031f70 100644 (file)
@@ -10,6 +10,12 @@ using namespace std;
 
 namespace Msp {
 
+GetOpt::~GetOpt()
+{
+       for(list<OptBase *>::iterator i=opts.begin(); i!=opts.end(); ++i)
+               delete *i;
+}
+
 /**
 Generates a single line that gives an overview about the known options.
 
@@ -31,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<<']';
        }
@@ -56,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();
+
+       string::size_type 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;
@@ -114,12 +134,6 @@ void GetOpt::operator()(unsigned argc, const char *const *argv)
                args.push_back(argv[i]);
 }
 
-GetOpt::~GetOpt()
-{
-       for(list<OptBase *>::iterator i=opts.begin(); i!=opts.end(); ++i)
-               delete *i;
-}
-
 GetOpt::OptBase &GetOpt::get_option(char s)
 {
        for(list<OptBase *>::iterator i=opts.begin(); i!=opts.end(); ++i)
@@ -150,7 +164,7 @@ unsigned GetOpt::process_long(const char *const *argp)
 
        // See if the argument contains an =
        unsigned equals=0;
-       for(; arg[equals] && arg[equals]!='='; ++equals);
+       for(; arg[equals] && arg[equals]!='='; ++equals) ;
        
        OptBase &opt=get_option(string(arg, equals));
        
@@ -211,4 +225,44 @@ 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;
+}
+
+void GetOpt::OptBase::process()
+{
+       if(arg_type==REQUIRED_ARG)
+               throw UsageError("--"+lng+" requires an argument");
+       ++seen_count;
+
+       store();
+}
+
+void GetOpt::OptBase::process(const string &arg)
+{
+       if(arg_type==NO_ARG)
+               throw UsageError("--"+lng+" takes no argument");
+       ++seen_count;
+
+       store(arg);
+}
+
 } // namespace Msp