Rewritten OptionParser. Made it simpler and efficient.

pull/2/head
Tatsuhiro Tsujikawa 2011-10-22 01:03:14 +09:00
parent 3832ed97c6
commit d5c8d048ef
16 changed files with 142 additions and 351 deletions

View File

@ -108,6 +108,11 @@ public:
hidden_ = true; hidden_ = true;
} }
virtual const Pref* getPref() const
{
return pref_;
}
virtual char getShortName() const virtual char getShortName() const
{ {
return shortName_; return shortName_;

View File

@ -56,6 +56,7 @@ extern const std::string PATH_TO_DIR;
extern const std::string PATH_TO_COMMAND; extern const std::string PATH_TO_COMMAND;
class Option; class Option;
class Pref;
class OptionHandler { class OptionHandler {
public: public:
@ -82,6 +83,8 @@ public:
virtual void hide() = 0; virtual void hide() = 0;
virtual const Pref* getPref() const = 0;
enum ARG_TYPE { enum ARG_TYPE {
REQ_ARG, REQ_ARG,
OPT_ARG, OPT_ARG,

View File

@ -63,11 +63,6 @@ OptionHandlerException::OptionHandlerException
OptionHandlerException::~OptionHandlerException() throw() {} OptionHandlerException::~OptionHandlerException() throw() {}
const std::string& OptionHandlerException::getOptionName() const throw()
{
return pref_->k;
}
SharedHandle<Exception> OptionHandlerException::copy() const SharedHandle<Exception> OptionHandlerException::copy() const
{ {
SharedHandle<Exception> e(new OptionHandlerException(*this)); SharedHandle<Exception> e(new OptionHandlerException(*this));

View File

@ -57,7 +57,10 @@ public:
virtual ~OptionHandlerException() throw(); virtual ~OptionHandlerException() throw();
const std::string& getOptionName() const throw(); const Pref* getPref() const
{
return pref_;
}
}; };
#define OPTION_HANDLER_EXCEPTION(arg) \ #define OPTION_HANDLER_EXCEPTION(arg) \

View File

@ -63,69 +63,6 @@
namespace aria2 { namespace aria2 {
NullOptionHandler::~NullOptionHandler() {}
bool NullOptionHandler::canHandle(const std::string& optName) { return true; }
void NullOptionHandler::parse(Option& option, const std::string& arg) {}
bool NullOptionHandler::hasTag(const std::string& tag) const { return false; }
void NullOptionHandler::addTag(const std::string& tag) {}
std::string NullOptionHandler::toTagString() const { return A2STR::NIL; }
const std::string& NullOptionHandler::getName() const { return A2STR::NIL; }
const std::string& NullOptionHandler::getDescription() const
{
return A2STR::NIL;
}
const std::string& NullOptionHandler::getDefaultValue() const
{
return A2STR::NIL;
}
std::string NullOptionHandler::createPossibleValuesString() const
{
return A2STR::NIL;
}
bool NullOptionHandler::isHidden() const
{
return true;
}
void NullOptionHandler::hide() {}
OptionHandler::ARG_TYPE NullOptionHandler::getArgType() const
{
return OptionHandler::NO_ARG;
}
int NullOptionHandler::getOptionID() const
{
return id_;
}
void NullOptionHandler::setOptionID(int id)
{
id_ = id;
}
char NullOptionHandler::getShortName() const
{
return 0;
}
bool NullOptionHandler::getEraseAfterParse() const
{
return false;
}
void NullOptionHandler::setEraseAfterParse(bool eraseAfterParse) {}
BooleanOptionHandler::BooleanOptionHandler BooleanOptionHandler::BooleanOptionHandler
(const Pref* pref, (const Pref* pref,
const std::string& description, const std::string& description,
@ -828,6 +765,11 @@ void DeprecatedOptionHandler::hide()
depOptHandler_->hide(); depOptHandler_->hide();
} }
const Pref* DeprecatedOptionHandler::getPref() const
{
return depOptHandler_->getPref();
}
OptionHandler::ARG_TYPE DeprecatedOptionHandler::getArgType() const OptionHandler::ARG_TYPE DeprecatedOptionHandler::getArgType() const
{ {
return depOptHandler_->getArgType(); return depOptHandler_->getArgType();

View File

@ -46,30 +46,6 @@ namespace aria2 {
class Option; class Option;
class Pref; class Pref;
class NullOptionHandler : public OptionHandler {
private:
int id_;
public:
virtual ~NullOptionHandler();
virtual bool canHandle(const std::string& optName);
virtual void parse(Option& option, const std::string& arg);
virtual bool hasTag(const std::string& tag) const;
virtual void addTag(const std::string& tag);
virtual std::string toTagString() const;
virtual const std::string& getName() const;
virtual const std::string& getDescription() const;
virtual const std::string& getDefaultValue() const;
virtual std::string createPossibleValuesString() const;
virtual bool isHidden() const;
virtual void hide();
virtual OptionHandler::ARG_TYPE getArgType() const;
virtual int getOptionID() const;
virtual void setOptionID(int id);
virtual char getShortName() const;
virtual bool getEraseAfterParse() const;
virtual void setEraseAfterParse(bool eraseAfterParse);
};
class BooleanOptionHandler : public NameMatchOptionHandler { class BooleanOptionHandler : public NameMatchOptionHandler {
public: public:
BooleanOptionHandler(const Pref* pref, BooleanOptionHandler(const Pref* pref,
@ -329,6 +305,7 @@ public:
virtual const std::string& getDefaultValue() const; virtual const std::string& getDefaultValue() const;
virtual bool isHidden() const; virtual bool isHidden() const;
virtual void hide(); virtual void hide();
virtual const Pref* getPref() const;
virtual ARG_TYPE getArgType() const; virtual ARG_TYPE getArgType() const;
virtual char getShortName() const; virtual char getShortName() const;
virtual int getOptionID() const; virtual int getOptionID() const;

View File

@ -54,8 +54,9 @@
namespace aria2 { namespace aria2 {
OptionParser::OptionParser(): OptionParser::OptionParser()
idCounter_(0) : handlers_(option::countOption()),
shortOpts_(256)
{} {}
OptionParser::~OptionParser() {} OptionParser::~OptionParser() {}
@ -66,7 +67,7 @@ size_t countPublicOption(InputIterator first, InputIterator last)
{ {
size_t count = 0; size_t count = 0;
for(; first != last; ++first) { for(; first != last; ++first) {
if(!(*first)->isHidden()) { if(*first && !(*first)->isHidden()) {
++count; ++count;
} }
} }
@ -80,7 +81,7 @@ void putOptions(struct option* longOpts, int* plopt,
InputIterator first, InputIterator last) InputIterator first, InputIterator last)
{ {
for(; first != last; ++first) { for(; first != last; ++first) {
if(!(*first)->isHidden()) { if(*first && !(*first)->isHidden()) {
#ifdef HAVE_OPTION_CONST_NAME #ifdef HAVE_OPTION_CONST_NAME
(*longOpts).name = (*first)->getName().c_str(); (*longOpts).name = (*first)->getName().c_str();
#else // !HAVE_OPTION_CONST_NAME #else // !HAVE_OPTION_CONST_NAME
@ -101,7 +102,7 @@ void putOptions(struct option* longOpts, int* plopt,
} }
if((*first)->getShortName() == 0) { if((*first)->getShortName() == 0) {
(*longOpts).flag = plopt; (*longOpts).flag = plopt;
(*longOpts).val = (*first)->getOptionID(); (*longOpts).val = (*first)->getPref()->i;
} else { } else {
(*longOpts).flag = 0; (*longOpts).flag = 0;
(*longOpts).val = (*first)->getShortName(); (*longOpts).val = (*first)->getShortName();
@ -122,7 +123,7 @@ std::string createOptstring(InputIterator first, InputIterator last)
{ {
std::string str = ""; std::string str = "";
for(; first != last; ++first) { for(; first != last; ++first) {
if(!(*first)->isHidden()) { if(*first && !(*first)->isHidden()) {
if((*first)->getShortName() != 0) { if((*first)->getShortName() != 0) {
str += (*first)->getShortName(); str += (*first)->getShortName();
if((*first)->getArgType() == OptionHandler::REQ_ARG) { if((*first)->getArgType() == OptionHandler::REQ_ARG) {
@ -139,15 +140,14 @@ std::string createOptstring(InputIterator first, InputIterator last)
void OptionParser::parseArg void OptionParser::parseArg
(std::ostream& out, std::vector<std::string>& nonopts, (std::ostream& out, std::vector<std::string>& nonopts,
int argc, char* argv[]) int argc, char* argv[]) const
{ {
size_t numPublicOption = countPublicOption(optionHandlers_.begin(), size_t numPublicOption = countPublicOption(handlers_.begin(),
optionHandlers_.end()); handlers_.end());
int lopt; int lopt;
array_ptr<struct option> longOpts(new struct option[numPublicOption+1]); array_ptr<struct option> longOpts(new struct option[numPublicOption+1]);
putOptions(longOpts, &lopt,optionHandlers_.begin(),optionHandlers_.end()); putOptions(longOpts, &lopt,handlers_.begin(),handlers_.end());
std::string optstring = createOptstring(optionHandlers_.begin(), std::string optstring = createOptstring(handlers_.begin(), handlers_.end());
optionHandlers_.end());
while(1) { while(1) {
int c = getopt_long(argc, argv, optstring.c_str(), longOpts, 0); int c = getopt_long(argc, argv, optstring.c_str(), longOpts, 0);
if(c == -1) { if(c == -1) {
@ -155,7 +155,7 @@ void OptionParser::parseArg
} }
SharedHandle<OptionHandler> op; SharedHandle<OptionHandler> op;
if(c == 0) { if(c == 0) {
op = findByID(lopt); op = findById(lopt);
} else { } else {
op = findByShortName(c); op = findByShortName(c);
} }
@ -177,12 +177,10 @@ void OptionParser::parseArg
std::copy(argv+optind, argv+argc, std::back_inserter(nonopts)); 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; std::string line;
int32_t linenum = 0;
while(getline(is, line)) { while(getline(is, line)) {
++linenum;
if(util::startsWith(line, A2STR::SHARP_C)) { if(util::startsWith(line, A2STR::SHARP_C)) {
continue; continue;
} }
@ -191,217 +189,106 @@ void OptionParser::parse(Option& option, std::istream& is)
if(nv.first.empty()) { if(nv.first.empty()) {
continue; continue;
} }
OptionHandlerHandle handler = getOptionHandlerByName(nv.first); const SharedHandle<OptionHandler>& handler = find(option::k2p(nv.first));
handler->parse(option, nv.second); if(handler) {
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());
}
return handler;
}
void OptionParser::setOptionHandlers 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 = for(std::vector<SharedHandle<OptionHandler> >::const_iterator i =
optionHandlers_.begin(), eoi = optionHandlers_.end(); handlers.begin(), eoi = handlers.end(); i != eoi; ++i) {
i != eoi; ++i) { addOptionHandler(*i);
(*i)->setOptionID(++idCounter_);
} }
std::sort(optionHandlers_.begin(), optionHandlers_.end(),
OptionHandlerNameLesser());
} }
void OptionParser::addOptionHandler void OptionParser::addOptionHandler(const SharedHandle<OptionHandler>& handler)
(const SharedHandle<OptionHandler>& optionHandler)
{ {
optionHandler->setOptionID(++idCounter_); size_t optId = handler->getPref()->i;
std::vector<SharedHandle<OptionHandler> >::iterator i = assert(optId < handlers_.size());
std::lower_bound(optionHandlers_.begin(), optionHandlers_.end(), handlers_[optId] = handler;
optionHandler, OptionHandlerNameLesser()); if(handler->getShortName()) {
optionHandlers_.insert(i, optionHandler); shortOpts_[static_cast<unsigned char>(handler->getShortName())] = optId;
}
} }
void OptionParser::parseDefaultValues(Option& option) const void OptionParser::parseDefaultValues(Option& option) const
{ {
for(std::vector<SharedHandle<OptionHandler> >::const_iterator i = for(std::vector<SharedHandle<OptionHandler> >::const_iterator i =
optionHandlers_.begin(), eoi = optionHandlers_.end(); handlers_.begin(), eoi = handlers_.end(); i != eoi; ++i) {
i != eoi; ++i) { if(*i && !(*i)->getDefaultValue().empty()) {
if(!(*i)->getDefaultValue().empty()) {
(*i)->parse(option, (*i)->getDefaultValue()); (*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> > std::vector<SharedHandle<OptionHandler> >
OptionParser::findByTag(const std::string& tag) const OptionParser::findByTag(const std::string& tag) const
{ {
std::vector<SharedHandle<OptionHandler> > result; std::vector<SharedHandle<OptionHandler> > result;
std::remove_copy_if(optionHandlers_.begin(), optionHandlers_.end(), for(std::vector<SharedHandle<OptionHandler> >::const_iterator i =
std::back_inserter(result), handlers_.begin(), eoi = handlers_.end(); i != eoi; ++i) {
std::not1(FindOptionHandlerByTag(tag))); if(*i && !(*i)->isHidden() && (*i)->hasTag(tag)) {
std::sort(result.begin(), result.end(), OptionHandlerIDLesser()); result.push_back(*i);
}
}
return result; 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> > std::vector<SharedHandle<OptionHandler> >
OptionParser::findByNameSubstring(const std::string& substring) const OptionParser::findByNameSubstring(const std::string& substring) const
{ {
std::vector<SharedHandle<OptionHandler> > result; std::vector<SharedHandle<OptionHandler> > result;
std::remove_copy_if(optionHandlers_.begin(), optionHandlers_.end(), for(std::vector<SharedHandle<OptionHandler> >::const_iterator i =
std::back_inserter(result), handlers_.begin(), eoi = handlers_.end(); i != eoi; ++i) {
std::not1(FindOptionHandlerByNameSubstring(substring))); if(*i && !(*i)->isHidden() &&
std::sort(result.begin(), result.end(), OptionHandlerIDLesser()); (*i)->getName().find(substring) != std::string::npos) {
result.push_back(*i);
}
}
return result; return result;
} }
std::vector<SharedHandle<OptionHandler> > OptionParser::findAll() const std::vector<SharedHandle<OptionHandler> > OptionParser::findAll() const
{ {
std::vector<SharedHandle<OptionHandler> > result; std::vector<SharedHandle<OptionHandler> > result;
std::remove_copy_if(optionHandlers_.begin(), optionHandlers_.end(), for(std::vector<SharedHandle<OptionHandler> >::const_iterator i =
std::back_inserter(result), handlers_.begin(), eoi = handlers_.end(); i != eoi; ++i) {
mem_fun_sh(&OptionHandler::isHidden)); if(*i && !(*i)->isHidden()) {
std::sort(result.begin(), result.end(), OptionHandlerIDLesser()); result.push_back(*i);
}
}
return result; return result;
} }
namespace { const SharedHandle<OptionHandler>& OptionParser::find(const Pref* pref) const
template<typename InputIterator, typename Predicate>
SharedHandle<OptionHandler> findOptionHandler
(InputIterator first, InputIterator last, Predicate pred)
{ {
SharedHandle<OptionHandler> handler; return findById(pref->i);
InputIterator i = std::find_if(first, last, pred);
if(i != last) {
handler = *i;
}
return handler;
} }
} // namespace
SharedHandle<OptionHandler> const SharedHandle<OptionHandler>& OptionParser::findById(size_t id) const
OptionParser::findByName(const std::string& name) const
{ {
SharedHandle<OptionHandler> handler(new DummyOptionHandler(name)); if(id >= handlers_.size()) {
std::vector<SharedHandle<OptionHandler> >::const_iterator i = return handlers_[0];
std::lower_bound(optionHandlers_.begin(), optionHandlers_.end(), }
handler, OptionHandlerNameLesser()); const SharedHandle<OptionHandler>& h = handlers_[id];
if(i != optionHandlers_.end() && (*i)->getName() == name && if(!h || h->isHidden()) {
!(*i)->isHidden()) { return handlers_[0];
handler = *i;
} else { } else {
handler.reset(); return h;
} }
return handler;
} }
namespace { const SharedHandle<OptionHandler>& OptionParser::findByShortName
class FindOptionHandlerByID:public std::unary_function (char shortName) const
<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_;
}
};
} // namespace
SharedHandle<OptionHandler> OptionParser::findByID(int id) const
{ {
return findOptionHandler(optionHandlers_.begin(), optionHandlers_.end(), size_t idx = static_cast<unsigned char>(shortName);
FindOptionHandlerByID(id)); return findById(shortOpts_[idx]);
} }
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
{
return findOptionHandler(optionHandlers_.begin(), optionHandlers_.end(),
FindOptionHandlerByShortName(shortName));
}
SharedHandle<OptionParser> OptionParser::optionParser_; SharedHandle<OptionParser> OptionParser::optionParser_;
const SharedHandle<OptionParser>& OptionParser::getInstance() const SharedHandle<OptionParser>& OptionParser::getInstance()

View File

@ -47,38 +47,32 @@ namespace aria2 {
class Option; class Option;
class OptionHandler; class OptionHandler;
class Pref;
class OptionParser { class OptionParser {
private: private:
int idCounter_; std::vector<SharedHandle<OptionHandler> > handlers_;
// Index of handler in handlers_ for option who has short option name.
// optionHandlers_ is sorted by OptionHandler::getName() in std::vector<size_t> shortOpts_;
// ascending order.
std::vector<SharedHandle<OptionHandler> > optionHandlers_;
SharedHandle<OptionHandler>
getOptionHandlerByName(const std::string& optName);
static SharedHandle<OptionParser> optionParser_; static SharedHandle<OptionParser> optionParser_;
public: public:
OptionParser(); OptionParser();
~OptionParser(); ~OptionParser();
// Parses options in argv and writes option name and value to out in // Parses options in argv and writes option name and value to out in
// NAME=VALUE format. Non-option strings are stored in nonopts. // NAME=VALUE format. Non-option strings are stored in nonopts.
// Throws Exception when an unrecognized option is found. // Throws Exception when an unrecognized option is found.
void parseArg(std::ostream& out, std::vector<std::string>& nonopts, void parseArg(std::ostream& out, std::vector<std::string>& nonopts,
int argc, char* argv[]); int argc, char* argv[]) const;
void parse(Option& option, std::istream& ios); void parse(Option& option, std::istream& ios) const;
void parseDefaultValues(Option& option) const; void parseDefaultValues(Option& option) const;
void setOptionHandlers void setOptionHandlers
(const std::vector<SharedHandle<OptionHandler> >& optionHandlers); (const std::vector<SharedHandle<OptionHandler> >& handlers);
void addOptionHandler(const SharedHandle<OptionHandler>& optionHandler); void addOptionHandler(const SharedHandle<OptionHandler>& handler);
// Hidden options are not returned. // Hidden options are not returned.
std::vector<SharedHandle<OptionHandler> > std::vector<SharedHandle<OptionHandler> >
@ -92,20 +86,17 @@ public:
std::vector<SharedHandle<OptionHandler> > findAll() const; std::vector<SharedHandle<OptionHandler> > findAll() const;
// Hidden options are not returned. // Hidden options are not returned.
SharedHandle<OptionHandler> const SharedHandle<OptionHandler>& find(const Pref* pref) const;
findByName(const std::string& name) const;
// Hidden options are not returned. // Hidden options are not returned.
SharedHandle<OptionHandler> findByID(int id) const; const SharedHandle<OptionHandler>& findById(size_t id) const;
// Hidden options are not returned. // Hidden options are not returned.
SharedHandle<OptionHandler> findByShortName(char shortName) const; const SharedHandle<OptionHandler>& findByShortName(char shortName) const;
static const SharedHandle<OptionParser>& getInstance(); static const SharedHandle<OptionParser>& getInstance();
}; };
typedef SharedHandle<OptionParser> OptionParserHandle;
} // namespace aria2 } // namespace aria2
#endif // D_OPTION_PARSER_H #endif // D_OPTION_PARSER_H

View File

@ -93,16 +93,16 @@ void gatherOption
(fmt("%s option cannot be used in this context.", (fmt("%s option cannot be used in this context.",
optionName.c_str())); optionName.c_str()));
} else { } else {
SharedHandle<OptionHandler> optionHandler = const Pref* pref = option::k2p(optionName);
optionParser->findByName(optionName); const SharedHandle<OptionHandler>& handler = optionParser->find(pref);
if(!optionHandler) { if(!handler) {
throw DL_ABORT_EX throw DL_ABORT_EX
(fmt("We don't know how to deal with %s option", (fmt("We don't know how to deal with %s option",
optionName.c_str())); optionName.c_str()));
} }
const String* opval = downcast<String>((*first).second); const String* opval = downcast<String>((*first).second);
if(opval) { if(opval) {
optionHandler->parse(*option.get(), opval->s()); handler->parse(*option.get(), opval->s());
} else { } else {
// header and index-out option can take array as value // header and index-out option can take array as value
const List* oplist = downcast<List>((*first).second); const List* oplist = downcast<List>((*first).second);
@ -112,7 +112,7 @@ void gatherOption
eoi = oplist->end(); argiter != eoi; ++argiter) { eoi = oplist->end(); argiter != eoi; ++argiter) {
const String* opval = downcast<String>(*argiter); const String* opval = downcast<String>(*argiter);
if(opval) { if(opval) {
optionHandler->parse(*option.get(), opval->s()); handler->parse(*option.get(), opval->s());
} }
} }
} }

View File

@ -1244,8 +1244,8 @@ SharedHandle<ValueBase> GetGlobalOptionRpcMethod::process
if(!e->getOption()->defined(pref)) { if(!e->getOption()->defined(pref)) {
continue; continue;
} }
SharedHandle<OptionHandler> h = getOptionParser()->findByName(pref->k); const SharedHandle<OptionHandler>& h = getOptionParser()->find(pref);
if(h && !h->isHidden()) { if(h) {
result->put(pref->k, e->getOption()->get(pref)); result->put(pref->k, e->getOption()->get(pref));
} }
} }

View File

@ -43,14 +43,13 @@
#include "OptionHandler.h" #include "OptionHandler.h"
#include "A2STR.h" #include "A2STR.h"
#include "BufferedFile.h" #include "BufferedFile.h"
#include "OptionParser.h"
namespace aria2 { namespace aria2 {
UriListParser::UriListParser(const std::string& filename) UriListParser::UriListParser(const std::string& filename)
: fp_(filename, BufferedFile::READ) : fp_(filename, BufferedFile::READ)
{ {}
optparser_.setOptionHandlers(OptionHandlerFactory::createOptionHandlers());
}
UriListParser::~UriListParser() {} UriListParser::~UriListParser() {}
@ -64,6 +63,7 @@ void UriListParser::parseNext(std::vector<std::string>& uris, Option& op)
} }
line_.assign(&buf[0], &buf[strlen(buf)]); line_.assign(&buf[0], &buf[strlen(buf)]);
} }
const SharedHandle<OptionParser>& optparser = OptionParser::getInstance();
while(1) { while(1) {
if(!util::startsWith(line_, A2STR::SHARP_C) && !util::strip(line_).empty()){ if(!util::startsWith(line_, A2STR::SHARP_C) && !util::strip(line_).empty()){
util::split(line_, std::back_inserter(uris), "\t", true); util::split(line_, std::back_inserter(uris), "\t", true);
@ -83,7 +83,7 @@ void UriListParser::parseNext(std::vector<std::string>& uris, Option& op)
break; break;
} }
} }
optparser_.parse(op, ss); optparser->parse(op, ss);
return; return;
} }
if(!fp_.getsn(buf, sizeof(buf))) { if(!fp_.getsn(buf, sizeof(buf))) {

View File

@ -42,7 +42,6 @@
#include <iosfwd> #include <iosfwd>
#include "Option.h" #include "Option.h"
#include "OptionParser.h"
#include "BufferedFile.h" #include "BufferedFile.h"
namespace aria2 { namespace aria2 {
@ -51,8 +50,6 @@ class UriListParser {
private: private:
BufferedFile fp_; BufferedFile fp_;
OptionParser optparser_;
std::string line_; std::string line_;
public: public:
UriListParser(const std::string& filename); UriListParser(const std::string& filename);

View File

@ -64,17 +64,20 @@
namespace aria2 { namespace aria2 {
extern void showVersion(); extern void showVersion();
extern void showUsage(const std::string& keyword, const OptionParser& oparser); extern void showUsage
(const std::string& keyword, const SharedHandle<OptionParser>& oparser);
namespace { namespace {
void overrideWithEnv(Option& op, const OptionParser& optionParser, void overrideWithEnv
const Pref* pref, (Option& op,
const std::string& envName) const SharedHandle<OptionParser>& optionParser,
const Pref* pref,
const std::string& envName)
{ {
char* value = getenv(envName.c_str()); char* value = getenv(envName.c_str());
if(value) { if(value) {
try { try {
optionParser.findByName(pref->k)->parse(op, value); optionParser->find(pref)->parse(op, value);
} catch(Exception& e) { } catch(Exception& e) {
global::cerr()->printf global::cerr()->printf
("Caught Error while parsing environment variable '%s'\n%s\n", ("Caught Error while parsing environment variable '%s'\n%s\n",
@ -88,17 +91,16 @@ void overrideWithEnv(Option& op, const OptionParser& optionParser,
void option_processing(Option& op, std::vector<std::string>& uris, void option_processing(Option& op, std::vector<std::string>& uris,
int argc, char* argv[]) int argc, char* argv[])
{ {
OptionParser oparser; const SharedHandle<OptionParser>& oparser = OptionParser::getInstance();
oparser.setOptionHandlers(OptionHandlerFactory::createOptionHandlers());
try { try {
bool noConf = false; bool noConf = false;
std::string ucfname; std::string ucfname;
std::stringstream cmdstream; std::stringstream cmdstream;
oparser.parseArg(cmdstream, uris, argc, argv); oparser->parseArg(cmdstream, uris, argc, argv);
{ {
// first evaluate --no-conf and --conf-path options. // first evaluate --no-conf and --conf-path options.
Option op; Option op;
oparser.parse(op, cmdstream); oparser->parse(op, cmdstream);
noConf = op.getAsBool(PREF_NO_CONF); noConf = op.getAsBool(PREF_NO_CONF);
ucfname = op.get(PREF_CONF_PATH); ucfname = op.get(PREF_CONF_PATH);
@ -125,13 +127,12 @@ void option_processing(Option& op, std::vector<std::string>& uris,
} }
} }
oparser.parseDefaultValues(op); oparser->parseDefaultValues(op);
if(!noConf) { if(!noConf) {
std::string cfname = std::string cfname =
ucfname.empty() ? ucfname.empty() ?
oparser.findByName(PREF_CONF_PATH->k)->getDefaultValue(): oparser->find(PREF_CONF_PATH)->getDefaultValue() : ucfname;
ucfname;
if(File(cfname).isFile()) { if(File(cfname).isFile()) {
std::stringstream ss; std::stringstream ss;
@ -142,16 +143,14 @@ void option_processing(Option& op, std::vector<std::string>& uris,
} }
} }
try { try {
oparser.parse(op, ss); oparser->parse(op, ss);
} catch(OptionHandlerException& e) { } catch(OptionHandlerException& e) {
global::cerr()->printf("Parse error in %s\n%s\n", global::cerr()->printf("Parse error in %s\n%s\n",
cfname.c_str(), cfname.c_str(),
e.stackTrace().c_str()); e.stackTrace().c_str());
SharedHandle<OptionHandler> h = oparser.findByName(e.getOptionName()); const SharedHandle<OptionHandler>& h = oparser->find(e.getPref());
if(h) { if(h) {
global::cerr()->printf global::cerr()->printf("Usage:\n%s\n", h->getDescription().c_str());
("Usage:\n%s\n",
oparser.findByName(e.getOptionName())->getDescription().c_str());
} }
exit(e.getErrorCode()); exit(e.getErrorCode());
} catch(Exception& e) { } catch(Exception& e) {
@ -178,7 +177,7 @@ void option_processing(Option& op, std::vector<std::string>& uris,
cmdstream.clear(); cmdstream.clear();
cmdstream.seekg(0, std::ios::beg); cmdstream.seekg(0, std::ios::beg);
// finaly let's parse and store command-iine options. // finaly let's parse and store command-iine options.
oparser.parse(op, cmdstream); oparser->parse(op, cmdstream);
#ifdef __MINGW32__ #ifdef __MINGW32__
for(std::map<std::string, std::string>::iterator i = op.begin(); for(std::map<std::string, std::string>::iterator i = op.begin();
i != op.end(); ++i) { i != op.end(); ++i) {
@ -189,7 +188,7 @@ void option_processing(Option& op, std::vector<std::string>& uris,
#endif // __MINGW32__ #endif // __MINGW32__
} catch(OptionHandlerException& e) { } catch(OptionHandlerException& e) {
global::cerr()->printf("%s\n", e.stackTrace().c_str()); global::cerr()->printf("%s\n", e.stackTrace().c_str());
SharedHandle<OptionHandler> h = oparser.findByName(e.getOptionName()); const SharedHandle<OptionHandler>& h = oparser->find(e.getPref());
if(h) { if(h) {
std::ostringstream ss; std::ostringstream ss;
ss << *h; ss << *h;

View File

@ -80,20 +80,22 @@ void showVersion() {
<< _("Visit") << " " << PACKAGE_URL << std::endl; << _("Visit") << " " << PACKAGE_URL << std::endl;
} }
void showUsage(const std::string& keyword, const OptionParser& oparser) { void showUsage
(const std::string& keyword,
const SharedHandle<OptionParser>& oparser) {
std::cout << _("Usage: aria2c [OPTIONS] [URI | MAGNET | TORRENT_FILE |" std::cout << _("Usage: aria2c [OPTIONS] [URI | MAGNET | TORRENT_FILE |"
" METALINK_FILE]...") << "\n" " METALINK_FILE]...") << "\n"
<< "\n"; << "\n";
if(util::startsWith(keyword, "#")) { if(util::startsWith(keyword, "#")) {
std::vector<SharedHandle<OptionHandler> > handlers = std::vector<SharedHandle<OptionHandler> > handlers =
keyword == TAG_ALL ? oparser.findAll():oparser.findByTag(keyword); keyword == TAG_ALL ? oparser->findAll() : oparser->findByTag(keyword);
if(keyword == TAG_ALL) { if(keyword == TAG_ALL) {
std::cout << _("Printing all options."); std::cout << _("Printing all options.");
} else { } else {
std::cout << fmt(_("Printing options tagged with '%s'."), std::cout << fmt(_("Printing options tagged with '%s'."),
keyword.c_str()); keyword.c_str());
std::cout << "\n"; std::cout << "\n";
SharedHandle<OptionHandler> help = oparser.findByName("help"); const SharedHandle<OptionHandler>& help = oparser->find(PREF_HELP);
std::cout << fmt(_("See -h option to know other command-line" std::cout << fmt(_("See -h option to know other command-line"
" options(%s)."), " options(%s)."),
help->createPossibleValuesString().c_str()); help->createPossibleValuesString().c_str());
@ -106,7 +108,7 @@ void showUsage(const std::string& keyword, const OptionParser& oparser) {
} }
} else { } else {
std::vector<SharedHandle<OptionHandler> > handlers = std::vector<SharedHandle<OptionHandler> > handlers =
oparser.findByNameSubstring(keyword); oparser->findByNameSubstring(keyword);
if(!handlers.empty()) { if(!handlers.empty()) {
std::cout << fmt(_("Printing options whose name includes '%s'."), std::cout << fmt(_("Printing options whose name includes '%s'."),
keyword.c_str()) keyword.c_str())
@ -119,7 +121,7 @@ void showUsage(const std::string& keyword, const OptionParser& oparser) {
} else { } else {
std::cout << fmt(_("No option matching with '%s'."), std::cout << fmt(_("No option matching with '%s'."),
keyword.c_str()) keyword.c_str())
<< "\n" << *oparser.findByName("help") << "\n"; << "\n" << *oparser->find(PREF_HELP) << "\n";
} }
} }

View File

@ -11,7 +11,6 @@ namespace aria2 {
class OptionHandlerTest:public CppUnit::TestFixture { class OptionHandlerTest:public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(OptionHandlerTest); CPPUNIT_TEST_SUITE(OptionHandlerTest);
CPPUNIT_TEST(testNullOptionHandler);
CPPUNIT_TEST(testBooleanOptionHandler); CPPUNIT_TEST(testBooleanOptionHandler);
CPPUNIT_TEST(testNumberOptionHandler); CPPUNIT_TEST(testNumberOptionHandler);
CPPUNIT_TEST(testNumberOptionHandler_min); CPPUNIT_TEST(testNumberOptionHandler_min);
@ -33,7 +32,6 @@ class OptionHandlerTest:public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
public: public:
void testNullOptionHandler();
void testBooleanOptionHandler(); void testBooleanOptionHandler();
void testNumberOptionHandler(); void testNumberOptionHandler();
void testNumberOptionHandler_min(); void testNumberOptionHandler_min();
@ -57,15 +55,6 @@ public:
CPPUNIT_TEST_SUITE_REGISTRATION( OptionHandlerTest ); CPPUNIT_TEST_SUITE_REGISTRATION( OptionHandlerTest );
void OptionHandlerTest::testNullOptionHandler()
{
NullOptionHandler handler;
CPPUNIT_ASSERT(handler.canHandle("foo"));
Option option;
handler.parse(option, "bar");
CPPUNIT_ASSERT(!option.defined(PREF_TIMEOUT));
}
void OptionHandlerTest::testBooleanOptionHandler() void OptionHandlerTest::testBooleanOptionHandler()
{ {
BooleanOptionHandler handler(PREF_DAEMON); BooleanOptionHandler handler(PREF_DAEMON);

View File

@ -20,9 +20,9 @@ class OptionParserTest:public CppUnit::TestFixture {
CPPUNIT_TEST(testFindAll); CPPUNIT_TEST(testFindAll);
CPPUNIT_TEST(testFindByNameSubstring); CPPUNIT_TEST(testFindByNameSubstring);
CPPUNIT_TEST(testFindByTag); CPPUNIT_TEST(testFindByTag);
CPPUNIT_TEST(testFindByName); CPPUNIT_TEST(testFind);
CPPUNIT_TEST(testFindByShortName); CPPUNIT_TEST(testFindByShortName);
CPPUNIT_TEST(testFindByID); CPPUNIT_TEST(testFindById);
CPPUNIT_TEST(testParseDefaultValues); CPPUNIT_TEST(testParseDefaultValues);
CPPUNIT_TEST(testParseArg); CPPUNIT_TEST(testParseArg);
CPPUNIT_TEST(testParse); CPPUNIT_TEST(testParse);
@ -66,9 +66,9 @@ public:
void testFindAll(); void testFindAll();
void testFindByNameSubstring(); void testFindByNameSubstring();
void testFindByTag(); void testFindByTag();
void testFindByName(); void testFind();
void testFindByShortName(); void testFindByShortName();
void testFindByID(); void testFindById();
void testParseDefaultValues(); void testParseDefaultValues();
void testParseArg(); void testParseArg();
void testParse(); void testParse();
@ -104,35 +104,36 @@ void OptionParserTest::testFindByTag()
CPPUNIT_ASSERT_EQUAL(std::string("out"), res[1]->getName()); CPPUNIT_ASSERT_EQUAL(std::string("out"), res[1]->getName());
} }
void OptionParserTest::testFindByName() void OptionParserTest::testFind()
{ {
SharedHandle<OptionHandler> dir = oparser_->findByName("dir"); const SharedHandle<OptionHandler>& dir = oparser_->find(PREF_DIR);
CPPUNIT_ASSERT(dir); CPPUNIT_ASSERT(dir);
CPPUNIT_ASSERT_EQUAL(std::string("dir"), dir->getName()); CPPUNIT_ASSERT_EQUAL(std::string("dir"), dir->getName());
SharedHandle<OptionHandler> daemon = oparser_->findByName("daemon"); const SharedHandle<OptionHandler>& daemon = oparser_->find(PREF_DAEMON);
CPPUNIT_ASSERT(!daemon); CPPUNIT_ASSERT(!daemon);
SharedHandle<OptionHandler> timeout2 = oparser_->findByName("timeout2"); const SharedHandle<OptionHandler>& log = oparser_->find(PREF_LOG);
CPPUNIT_ASSERT(!timeout2); CPPUNIT_ASSERT(!log);
} }
void OptionParserTest::testFindByShortName() void OptionParserTest::testFindByShortName()
{ {
SharedHandle<OptionHandler> timeout = oparser_->findByShortName('A'); const SharedHandle<OptionHandler>& timeout = oparser_->findByShortName('A');
CPPUNIT_ASSERT(timeout); CPPUNIT_ASSERT(timeout);
CPPUNIT_ASSERT_EQUAL(std::string("timeout"), timeout->getName()); CPPUNIT_ASSERT_EQUAL(std::string("timeout"), timeout->getName());
CPPUNIT_ASSERT(!oparser_->findByShortName('C')); CPPUNIT_ASSERT(!oparser_->findByShortName('C'));
} }
void OptionParserTest::testFindByID() void OptionParserTest::testFindById()
{ {
SharedHandle<OptionHandler> timeout = oparser_->findByID(1); const SharedHandle<OptionHandler>& timeout =
oparser_->findById(PREF_TIMEOUT->i);
CPPUNIT_ASSERT(timeout); CPPUNIT_ASSERT(timeout);
CPPUNIT_ASSERT_EQUAL(std::string("timeout"), timeout->getName()); CPPUNIT_ASSERT_EQUAL(std::string("timeout"), timeout->getName());
CPPUNIT_ASSERT(!oparser_->findByID(3)); CPPUNIT_ASSERT(!oparser_->findById(9999));
} }
void OptionParserTest::testParseDefaultValues() void OptionParserTest::testParseDefaultValues()