diff options
| author | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2011-10-22 01:03:14 +0900 |
|---|---|---|
| committer | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2011-10-22 01:03:14 +0900 |
| commit | d5c8d048efeb524d5d2222b4547f9dd19e943f13 (patch) | |
| tree | 117dd74fff2594be1ee6d6ba00dc9d8c301bf05e /src/OptionParser.cc | |
| parent | 3832ed97c616eff0057d7a0e5a161c4282537160 (diff) | |
Rewritten OptionParser. Made it simpler and efficient.
Diffstat (limited to 'src/OptionParser.cc')
| -rw-r--r-- | src/OptionParser.cc | 239 |
1 files changed, 63 insertions, 176 deletions
diff --git a/src/OptionParser.cc b/src/OptionParser.cc index 336ef032..bd7551c1 100644 --- a/src/OptionParser.cc +++ b/src/OptionParser.cc @@ -54,8 +54,9 @@ namespace aria2 { -OptionParser::OptionParser(): - idCounter_(0) +OptionParser::OptionParser() + : handlers_(option::countOption()), + shortOpts_(256) {} OptionParser::~OptionParser() {} @@ -66,7 +67,7 @@ size_t countPublicOption(InputIterator first, InputIterator last) { size_t count = 0; for(; first != last; ++first) { - if(!(*first)->isHidden()) { + if(*first && !(*first)->isHidden()) { ++count; } } @@ -80,7 +81,7 @@ void putOptions(struct option* longOpts, int* plopt, InputIterator first, InputIterator last) { for(; first != last; ++first) { - if(!(*first)->isHidden()) { + if(*first && !(*first)->isHidden()) { #ifdef HAVE_OPTION_CONST_NAME (*longOpts).name = (*first)->getName().c_str(); #else // !HAVE_OPTION_CONST_NAME @@ -101,7 +102,7 @@ void putOptions(struct option* longOpts, int* plopt, } if((*first)->getShortName() == 0) { (*longOpts).flag = plopt; - (*longOpts).val = (*first)->getOptionID(); + (*longOpts).val = (*first)->getPref()->i; } else { (*longOpts).flag = 0; (*longOpts).val = (*first)->getShortName(); @@ -122,7 +123,7 @@ std::string createOptstring(InputIterator first, InputIterator last) { std::string str = ""; for(; first != last; ++first) { - if(!(*first)->isHidden()) { + if(*first && !(*first)->isHidden()) { if((*first)->getShortName() != 0) { str += (*first)->getShortName(); if((*first)->getArgType() == OptionHandler::REQ_ARG) { @@ -139,15 +140,14 @@ std::string createOptstring(InputIterator first, InputIterator last) void OptionParser::parseArg (std::ostream& out, std::vector<std::string>& nonopts, - int argc, char* argv[]) + int argc, char* argv[]) const { - size_t numPublicOption = countPublicOption(optionHandlers_.begin(), - optionHandlers_.end()); + size_t numPublicOption = countPublicOption(handlers_.begin(), + handlers_.end()); int lopt; array_ptr<struct option> longOpts(new struct option[numPublicOption+1]); - putOptions(longOpts, &lopt,optionHandlers_.begin(),optionHandlers_.end()); - std::string optstring = createOptstring(optionHandlers_.begin(), - optionHandlers_.end()); + putOptions(longOpts, &lopt,handlers_.begin(),handlers_.end()); + std::string optstring = createOptstring(handlers_.begin(), handlers_.end()); while(1) { int c = getopt_long(argc, argv, optstring.c_str(), longOpts, 0); if(c == -1) { @@ -155,7 +155,7 @@ void OptionParser::parseArg } SharedHandle<OptionHandler> op; if(c == 0) { - op = findByID(lopt); + op = findById(lopt); } else { op = findByShortName(c); } @@ -177,12 +177,10 @@ void OptionParser::parseArg std::copy(argv+optind, argv+argc, std::back_inserter(nonopts)); } -void OptionParser::parse(Option& option, std::istream& is) +void OptionParser::parse(Option& option, std::istream& is) const { std::string line; - int32_t linenum = 0; while(getline(is, line)) { - ++linenum; if(util::startsWith(line, A2STR::SHARP_C)) { continue; } @@ -191,217 +189,106 @@ void OptionParser::parse(Option& option, std::istream& is) if(nv.first.empty()) { continue; } - OptionHandlerHandle handler = getOptionHandlerByName(nv.first); - handler->parse(option, nv.second); - } -} - -namespace { -class DummyOptionHandler:public NullOptionHandler { -protected: - virtual void parseArg(Option& option, const std::string& arg) {} -public: - DummyOptionHandler(const std::string& optName) - : NullOptionHandler(), - optName_(optName) - {} - - virtual const std::string& getName() const - { - return optName_; - } -private: - std::string optName_; -}; -} // namespace - -OptionHandlerHandle OptionParser::getOptionHandlerByName -(const std::string& optName) -{ - SharedHandle<OptionHandler> handler(new DummyOptionHandler(optName)); - std::vector<SharedHandle<OptionHandler> >::const_iterator i = - std::lower_bound(optionHandlers_.begin(), optionHandlers_.end(), - handler, OptionHandlerNameLesser()); - if(i != optionHandlers_.end() && (*i)->canHandle(optName)) { - handler = *i; - } else { - handler.reset(new NullOptionHandler()); + const SharedHandle<OptionHandler>& handler = find(option::k2p(nv.first)); + if(handler) { + handler->parse(option, nv.second); + } } - return handler; } void OptionParser::setOptionHandlers -(const std::vector<SharedHandle<OptionHandler> >& optionHandlers) +(const std::vector<SharedHandle<OptionHandler> >& handlers) { - optionHandlers_ = optionHandlers; for(std::vector<SharedHandle<OptionHandler> >::const_iterator i = - optionHandlers_.begin(), eoi = optionHandlers_.end(); - i != eoi; ++i) { - (*i)->setOptionID(++idCounter_); + handlers.begin(), eoi = handlers.end(); i != eoi; ++i) { + addOptionHandler(*i); } - std::sort(optionHandlers_.begin(), optionHandlers_.end(), - OptionHandlerNameLesser()); } -void OptionParser::addOptionHandler -(const SharedHandle<OptionHandler>& optionHandler) +void OptionParser::addOptionHandler(const SharedHandle<OptionHandler>& handler) { - optionHandler->setOptionID(++idCounter_); - std::vector<SharedHandle<OptionHandler> >::iterator i = - std::lower_bound(optionHandlers_.begin(), optionHandlers_.end(), - optionHandler, OptionHandlerNameLesser()); - optionHandlers_.insert(i, optionHandler); + size_t optId = handler->getPref()->i; + assert(optId < handlers_.size()); + handlers_[optId] = handler; + if(handler->getShortName()) { + shortOpts_[static_cast<unsigned char>(handler->getShortName())] = optId; + } } void OptionParser::parseDefaultValues(Option& option) const { for(std::vector<SharedHandle<OptionHandler> >::const_iterator i = - optionHandlers_.begin(), eoi = optionHandlers_.end(); - i != eoi; ++i) { - if(!(*i)->getDefaultValue().empty()) { + handlers_.begin(), eoi = handlers_.end(); i != eoi; ++i) { + if(*i && !(*i)->getDefaultValue().empty()) { (*i)->parse(option, (*i)->getDefaultValue()); } } } -namespace { -class FindOptionHandlerByTag : - public std::unary_function<SharedHandle<OptionHandler>, bool> { -private: - std::string tag_; -public: - FindOptionHandlerByTag(const std::string& tag):tag_(tag) {} - - bool operator()(const SharedHandle<OptionHandler>& optionHandler) const - { - return !optionHandler->isHidden() && optionHandler->hasTag(tag_); - } -}; -} // namespace - std::vector<SharedHandle<OptionHandler> > OptionParser::findByTag(const std::string& tag) const { std::vector<SharedHandle<OptionHandler> > result; - std::remove_copy_if(optionHandlers_.begin(), optionHandlers_.end(), - std::back_inserter(result), - std::not1(FindOptionHandlerByTag(tag))); - std::sort(result.begin(), result.end(), OptionHandlerIDLesser()); + for(std::vector<SharedHandle<OptionHandler> >::const_iterator i = + handlers_.begin(), eoi = handlers_.end(); i != eoi; ++i) { + if(*i && !(*i)->isHidden() && (*i)->hasTag(tag)) { + result.push_back(*i); + } + } return result; } -namespace { -class FindOptionHandlerByNameSubstring : - public std::unary_function<SharedHandle<OptionHandler> , bool> { -private: - std::string substring_; -public: - FindOptionHandlerByNameSubstring - (const std::string& substring):substring_(substring) {} - - bool operator()(const SharedHandle<OptionHandler>& optionHandler) const - { - return !optionHandler->isHidden() && - optionHandler->getName().find(substring_) != std::string::npos; - } -}; -} // namespace - std::vector<SharedHandle<OptionHandler> > OptionParser::findByNameSubstring(const std::string& substring) const { std::vector<SharedHandle<OptionHandler> > result; - std::remove_copy_if(optionHandlers_.begin(), optionHandlers_.end(), - std::back_inserter(result), - std::not1(FindOptionHandlerByNameSubstring(substring))); - std::sort(result.begin(), result.end(), OptionHandlerIDLesser()); + for(std::vector<SharedHandle<OptionHandler> >::const_iterator i = + handlers_.begin(), eoi = handlers_.end(); i != eoi; ++i) { + if(*i && !(*i)->isHidden() && + (*i)->getName().find(substring) != std::string::npos) { + result.push_back(*i); + } + } return result; } std::vector<SharedHandle<OptionHandler> > OptionParser::findAll() const { std::vector<SharedHandle<OptionHandler> > result; - std::remove_copy_if(optionHandlers_.begin(), optionHandlers_.end(), - std::back_inserter(result), - mem_fun_sh(&OptionHandler::isHidden)); - std::sort(result.begin(), result.end(), OptionHandlerIDLesser()); + for(std::vector<SharedHandle<OptionHandler> >::const_iterator i = + handlers_.begin(), eoi = handlers_.end(); i != eoi; ++i) { + if(*i && !(*i)->isHidden()) { + result.push_back(*i); + } + } return result; } -namespace { -template<typename InputIterator, typename Predicate> -SharedHandle<OptionHandler> findOptionHandler -(InputIterator first, InputIterator last, Predicate pred) +const SharedHandle<OptionHandler>& OptionParser::find(const Pref* pref) const { - SharedHandle<OptionHandler> handler; - InputIterator i = std::find_if(first, last, pred); - if(i != last) { - handler = *i; - } - return handler; + return findById(pref->i); } -} // namespace -SharedHandle<OptionHandler> -OptionParser::findByName(const std::string& name) const +const SharedHandle<OptionHandler>& OptionParser::findById(size_t id) const { - SharedHandle<OptionHandler> handler(new DummyOptionHandler(name)); - std::vector<SharedHandle<OptionHandler> >::const_iterator i = - std::lower_bound(optionHandlers_.begin(), optionHandlers_.end(), - handler, OptionHandlerNameLesser()); - if(i != optionHandlers_.end() && (*i)->getName() == name && - !(*i)->isHidden()) { - handler = *i; - } else { - handler.reset(); + if(id >= handlers_.size()) { + return handlers_[0]; } - return handler; -} - -namespace { -class FindOptionHandlerByID:public std::unary_function -<SharedHandle<OptionHandler>, bool> { -private: - int id_; -public: - FindOptionHandlerByID(int id):id_(id) {} - - bool operator()(const SharedHandle<OptionHandler>& optionHandler) const - { - return !optionHandler->isHidden() && optionHandler->getOptionID() == id_; + const SharedHandle<OptionHandler>& h = handlers_[id]; + if(!h || h->isHidden()) { + return handlers_[0]; + } else { + return h; } -}; -} // namespace - -SharedHandle<OptionHandler> OptionParser::findByID(int id) const -{ - return findOptionHandler(optionHandlers_.begin(), optionHandlers_.end(), - FindOptionHandlerByID(id)); } -namespace { -class FindOptionHandlerByShortName: - public std::unary_function<SharedHandle<OptionHandler>, bool> { -private: - char shortName_; -public: - FindOptionHandlerByShortName(char shortName):shortName_(shortName) {} - - bool operator()(const SharedHandle<OptionHandler>& optionHandler) const - { - return !optionHandler->isHidden() && - optionHandler->getShortName() == shortName_; - } -}; -} // namespace - -SharedHandle<OptionHandler> OptionParser::findByShortName(char shortName) const +const SharedHandle<OptionHandler>& OptionParser::findByShortName +(char shortName) const { - return findOptionHandler(optionHandlers_.begin(), optionHandlers_.end(), - FindOptionHandlerByShortName(shortName)); + size_t idx = static_cast<unsigned char>(shortName); + return findById(shortOpts_[idx]); } - SharedHandle<OptionParser> OptionParser::optionParser_; const SharedHandle<OptionParser>& OptionParser::getInstance() |
