using namespace OptParse;
using namespace std;
+
+
/*main loop, message sender, etc.pp.*/
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;}),
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;}),
Argument::Argument(const std::initializer_list< Option >& ol, OptionCallback oc)
:m_call(oc)
{
- //TODO: filter enum opts
for(const Option&o:ol)setOption(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
}
}
+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";
+ }
+}
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;
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;
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);
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);}
};
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;
};