From 964e469b98324a4e52f0014afd3a12abb7a1337f Mon Sep 17 00:00:00 2001 From: Konrad Rosenbaum Date: Mon, 30 Apr 2012 15:51:08 +0200 Subject: [PATCH] add config file parsing --- client.cpp | 2 + optparse.cpp | 79 +++++++++++++++++++++++++++++++++++++++++++++++++-------- optparse.h | 8 ++++- 3 files changed, 76 insertions(+), 13 deletions(-) diff --git a/client.cpp b/client.cpp index 7087ba0..3bc2841 100644 --- a/client.cpp +++ b/client.cpp @@ -315,8 +315,10 @@ int main(int argc,char**argv) 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({"file"_Opt,"config"_Opt,Option::ArgumentRequired}, [&](string,string f){pp.parseFile(f);}), }); pp.setErrorCallback([&](string s,Error e){fprintf(stderr,"Syntax error in argument %s: %s\n",s.data(),error2String(e).data());printhelp();exit(1);}); + pp.setNonOptionCallback([](string s){device=s;}); pp.parseArguments(argc,argv); if(DUIDLEN==0){ diff --git a/optparse.cpp b/optparse.cpp index c85a267..38b6b1a 100644 --- a/optparse.cpp +++ b/optparse.cpp @@ -12,7 +12,12 @@ #include "optparse.h" -#include +#include +#include +#include +#include +#include + using namespace std; using namespace OptParse; @@ -84,28 +89,80 @@ void Parser::parseArguments(int argc, const char *const* argv,bool ig) const void Parser::parseArguments(std::list< std::string > argv,bool ig) const { if(ig)argv.pop_front(); - for(auto arg:argv)parseArgument(arg); + for(auto arg:argv)parseArgument(arg,true); } -#include -void Parser::parseArgument(const std::string& arg)const +static inline string trim(std::string s) { + static auto pred=[](char c){return !std::isspace(c);}; + s.erase(s.begin(),find_if(s.begin(),s.end(),pred)); + s.erase(find_if(s.rbegin(),s.rend(),pred).base(),s.end()); + return s; +} + +void Parser::parseArgument(const std::string& arg,bool useprefix)const { - const auto prfs=m_prefix.size(); + const auto prfs=useprefix?m_prefix.size():0; //is it an option style argument? - if(m_prefix.empty() || arg.substr(0,prfs)==m_prefix){ + if(!useprefix || m_prefix.empty() || arg.substr(0,prfs)==m_prefix){ //parse it std::string name,val; auto pe=arg.find('=',prfs); + bool haveArg=false; if(pe==arg.npos) - name=arg.substr(prfs); + name=trim(arg.substr(prfs)); else{ - name=arg.substr(prfs,pe-prfs); - val=arg.substr(pe); + name=trim(arg.substr(prfs,pe-prfs)); + val=trim(arg.substr(pe+1)); + haveArg=true; + } + //find option + bool found=false; + for(auto argi:m_args){ + if(argi.matches(name)){ + found=true; + if(argi.needArg()==Option::NeedArg::ReqArg&&!haveArg){ + if(m_ecall)m_ecall(arg,Error::MissingArgument); + return; + } + if(argi.needArg()==Option::NeedArg::NoArg&&haveArg){ + if(m_ecall)m_ecall(arg,Error::UnexpectedArgument); + return; + } + argi(name,val); + break; + } + } + if(found){ + if(m_call)m_call(name,val); + }else{ + if(m_ecall)m_ecall(arg,Error::UnknownOption); } - cerr<<"opt "<OptionCallback; -enum class Error{Ok=0,UnknownOption,MissingArgument}; +enum class Error{Ok=0,UnknownOption,MissingArgument,UnexpectedArgument}; typedef std::functionErrorCallback; inline std::string error2String(Error e) @@ -62,6 +62,7 @@ inline std::string error2String(Error e) case Error::Ok:return "No Error"; case Error::UnknownOption:return "unkown option"; case Error::MissingArgument:return "argument expected"; + case Error::UnexpectedArgument:return "no argument expected"; default:return "unknown error"; } } @@ -91,6 +92,9 @@ class Argument void setOption(const Option&); void setCallback(OptionCallback oc){m_call=oc;} + + void operator()(std::string name,std::string value)const + {if(m_call)m_call(name,value);} }; class Parser @@ -125,7 +129,7 @@ class Parser void parseFile(const std::string &filename)const; void parseFile(std::istream &stream)const; private: - void parseArgument(const std::string&)const; + void parseArgument(const std::string&,bool)const; }; };//End of namespace -- 1.7.2.5