start on option help master
authorKonrad Rosenbaum <konrad@silmor.de>
Tue, 1 May 2012 20:01:34 +0000 (22:01 +0200)
committerKonrad Rosenbaum <konrad@silmor.de>
Tue, 1 May 2012 20:01:34 +0000 (22:01 +0200)
client.cpp
optparse.cpp
optparse.h

index 3bc2841..f5d1e41 100644 (file)
@@ -292,6 +292,8 @@ struct option longopt[]= {
 
 using namespace OptParse;
 using namespace std;
+
+
 /*main loop, message sender, etc.pp.*/
 int main(int argc,char**argv)
 {
@@ -300,8 +302,12 @@ int main(int argc,char**argv)
        /*parse options*/
        argv0=*argv;
        Parser pp({
-               Argument({"local-id"_Opt,"l"_Opt,Option::ArgumentRequired}, [](string,string a){localid=a;}),
-               Argument({"log-level"_Opt,'L'_Opt,Option::ArgumentRequired}, [](string,string a){setloglevel(a);}),
+               Argument({"local-id"_Opt,"l"_Opt,Option::ArgumentRequired,
+                       "set the local ID from which the DUID is calculated"_Descr},
+                       [](string,string a){localid=a;}),
+               Argument({"log-level"_Opt,'L'_Opt,Option::ArgumentRequired,
+                       "set the log level (default is warn), must be one of: none, error, warn, info, debug"_Descr},
+                       [](string,string a){setloglevel(a);}),
                Argument({"prefix"_Opt,'p'_Opt},[](std::string,std::string){getprefix=1;}),
                Argument({"no-prefix"_Opt,'P'_Opt},[](std::string,std::string){getprefix=0;}),
                Argument({"address"_Opt,'a'_Opt},[](string,string){getaddress=1;}),
@@ -311,7 +317,7 @@ int main(int argc,char**argv)
                Argument({"rapid-commit"_Opt,'c'_Opt},[](string,string){userapid=1;}),
                Argument({"no-rapid-commit"_Opt,'C'_Opt},[](string,string){userapid=1;}),
                Argument({"retries"_Opt,'r'_Opt,Option::ArgumentRequired},[](string,string a){retries=atoi(a.data());}),
-               Argument({"help"_Opt,'h'_Opt},[](string,string){printhelp();exit(0);}),
+               Argument({"help"_Opt,'h'_Opt},[&](string,string){printhelp();pp.printHelp(2);exit(0);}),
                Argument({"duid"_Opt,'u'_Opt,Option::ArgumentRequired}, [](string,string a){setduid(a);}),
                Argument({"dev"_Opt,"device"_Opt,Option::ArgumentRequired}, [](string,string a){device=a;}),
                Argument({"script"_Opt,"s"_Opt,Option::ArgumentRequired}, [](string, string a){script=a;}),
index 38b6b1a..140ecc9 100644 (file)
@@ -34,7 +34,6 @@ Argument::Argument(const Option& o, OptionCallback oc)
 Argument::Argument(const std::initializer_list< Option >& ol, OptionCallback oc)
        :m_call(oc)
 {
-       //TODO: filter enum opts
        for(const Option&o:ol)setOption(o);
 }
 
@@ -59,6 +58,8 @@ void Argument::setOption(const Option& o)
        if(o.type()==Option::Type::NeedArg)
                if(o.needArg()!=Option::NeedArg::Null)
                        m_arg=o.needArg();
+       if(o.type()==Option::Type::Description)
+               m_descr=o.name();
 }
 
 Argument Parser::get(const std::string& n) const
@@ -165,4 +166,31 @@ void Parser::parseFile(std::istream& stream) const
        }
 }
 
+void Parser::printHelp(int base, int indent) const
+{
+       //calc indents
+       std::string basestr,indstr;
+       for(int i=0;i<base;i++)basestr+=' ';
+       for(int i=0;i<(base+indent);i++)indstr+=' ';
+       //print
+       for(auto arg:m_args){
+               cout<<basestr;
+               bool na=false,nac=false;
+               switch(arg.needArg()){
+                       case Option::NeedArg::OptArg:nac=true;//fallthrough
+                       case Option::NeedArg::ReqArg:na=true;break;
+                       default:break;
+               }
+               bool nfirst=false;
+               for(auto opt:arg.options()){
+                       if(nfirst)cout<<" | ";
+                       nfirst=true;
+                       cout<<m_prefix<<opt;
+                       if(nac)cout<<"[";
+                       if(na)cout<<"=arg";
+                       if(nac)cout<<"]";
+               }
+               cout<<"\n"<<indstr<<arg.description()<<"\n";
+       }
+}
 
index 00c4a1c..15a4894 100644 (file)
@@ -23,12 +23,12 @@ namespace OptParse {
 class Option
 {
        public:
-               enum class Type {Null=0,OptName,NeedArg};
+               enum class Type {Null=0,OptName,NeedArg,Description};
                enum class NeedArg{Null=0,NoArg,OptArg,ReqArg};
                
                Option():m_type(Type::Null),m_arg(NeedArg::Null){}
                Option(char s):m_type(Type::OptName),m_arg(NeedArg::Null){m_str+=s;}
-               Option(std::string s):m_type(Type::OptName),m_str(s),m_arg(NeedArg::Null){}
+               Option(std::string s,Type t=Type::OptName):m_type(t),m_str(s),m_arg(NeedArg::Null){}
                Option(NeedArg a):m_type(Type::NeedArg),m_arg(a){}
                Option(const Option&o)=default;
                Option(Option&&o)=default;
@@ -50,6 +50,7 @@ class Option
 
 inline Option operator"" _Opt(char const* s,size_t sz){return Option(std::string(s,sz));}
 inline Option operator"" _Opt(char s){std::string st;st+=s;return Option(st);}
+inline Option operator"" _Descr(char const* s,size_t sz){return Option(std::string(s,sz),Option::Type::Description);}
 
 typedef std::function<void(std::string,std::string)>OptionCallback;
 
@@ -74,6 +75,7 @@ class Argument
        std::vector<std::string> m_opt;
        Option::NeedArg m_arg;
        OptionCallback m_call;
+       std::string m_descr;
        public:
                Argument():m_arg(Option::NeedArg::Null){}
                Argument(const Option&o,OptionCallback oc=nullptr);
@@ -93,6 +95,11 @@ class Argument
                void setOption(const Option&);
                void setCallback(OptionCallback oc){m_call=oc;}
                
+               void setDescription(const std::string&s){m_descr=s;}
+               std::string description()const{return m_descr;}
+               
+               std::vector<std::string> options()const{return m_opt;}
+               
                void operator()(std::string name,std::string value)const
                {if(m_call)m_call(name,value);}
 };
@@ -128,6 +135,8 @@ class Parser
                
                void parseFile(const std::string &filename)const;
                void parseFile(std::istream &stream)const;
+               
+               void printHelp(int base=0,int indent=2)const;
        private:
                void parseArgument(const std::string&,bool)const;
 };