diff --git a/src/AbstractOptionHandler.cc b/src/AbstractOptionHandler.cc index f06c9ea3..46ba7c7a 100644 --- a/src/AbstractOptionHandler.cc +++ b/src/AbstractOptionHandler.cc @@ -40,6 +40,7 @@ #include "a2functional.h" #include "Option.h" #include "prefs.h" +#include "help_tags.h" namespace aria2 { @@ -54,17 +55,12 @@ AbstractOptionHandler::AbstractOptionHandler defaultValue_(defaultValue), argType_(argType), shortName_(shortName), - hidden_(false), - eraseAfterParse_(false), - initialOption_(false), - changeOption_(false), - changeOptionForReserved_(false), - globalChangeOption_(false), - cumulative_(false) + tags_(0), + flags_(0) {} AbstractOptionHandler::~AbstractOptionHandler() {} - + void AbstractOptionHandler::parse(Option& option, const std::string& arg) { try { @@ -74,19 +70,29 @@ void AbstractOptionHandler::parse(Option& option, const std::string& arg) } } -bool AbstractOptionHandler::hasTag(const std::string& tag) const +bool AbstractOptionHandler::hasTag(uint32_t tag) const { - return std::find(tags_.begin(), tags_.end(), tag) != tags_.end(); + return (tags_ & (1 << tag)); } -void AbstractOptionHandler::addTag(const std::string& tag) +void AbstractOptionHandler::addTag(uint32_t tag) { - tags_.push_back(tag); + tags_ |= (1 << tag); } std::string AbstractOptionHandler::toTagString() const { - return strjoin(tags_.begin(), tags_.end(), ", "); + std::string s; + for(int i = 0; i < MAX_HELP_TAG; ++i) { + if(tags_ & (1 << i)) { + s += strHelpTag(i); + s += ", "; + } + } + if(!s.empty()) { + s.resize(s.size() - 2); + } + return s; } const char* AbstractOptionHandler::getName() const @@ -94,4 +100,83 @@ const char* AbstractOptionHandler::getName() const return pref_->k; } +void AbstractOptionHandler::updateFlags(int flag, bool val) +{ + if(val) { + flags_ |= flag; + } else { + flags_ &= ~flag; + } +} + +bool AbstractOptionHandler::isHidden() const +{ + return flags_ & FLAG_HIDDEN; +} + +void AbstractOptionHandler::hide() +{ + updateFlags(FLAG_HIDDEN, true); +} + +bool AbstractOptionHandler::getEraseAfterParse() const +{ + return flags_ & FLAG_ERASE_AFTER_PARSE; +} + +void AbstractOptionHandler::setEraseAfterParse(bool f) +{ + updateFlags(FLAG_ERASE_AFTER_PARSE, f); +} + +bool AbstractOptionHandler::getInitialOption() const +{ + return flags_ & FLAG_INITIAL_OPTION; +} + +void AbstractOptionHandler::setInitialOption(bool f) +{ + updateFlags(FLAG_INITIAL_OPTION, f); +} + +bool AbstractOptionHandler::getChangeOption() const +{ + return flags_ & FLAG_CHANGE_OPTION; +} + +void AbstractOptionHandler::setChangeOption(bool f) +{ + updateFlags(FLAG_CHANGE_OPTION, f); +} + +bool AbstractOptionHandler::getChangeOptionForReserved() const +{ + return flags_ & FLAG_CHANGE_OPTION_FOR_RESERVED; +} + +void AbstractOptionHandler::setChangeOptionForReserved(bool f) +{ + updateFlags(FLAG_CHANGE_OPTION_FOR_RESERVED, f); +} + +bool AbstractOptionHandler::getChangeGlobalOption() const +{ + return flags_ & FLAG_CHANGE_GLOBAL_OPTION; +} + +void AbstractOptionHandler::setChangeGlobalOption(bool f) +{ + updateFlags(FLAG_CHANGE_GLOBAL_OPTION, f); +} + +bool AbstractOptionHandler::getCumulative() const +{ + return flags_ & FLAG_CUMULATIVE; +} + +void AbstractOptionHandler::setCumulative(bool f) +{ + updateFlags(FLAG_CUMULATIVE, f); +} + } // namespace aria2 diff --git a/src/AbstractOptionHandler.h b/src/AbstractOptionHandler.h index c7faf4b9..296852b6 100644 --- a/src/AbstractOptionHandler.h +++ b/src/AbstractOptionHandler.h @@ -37,10 +37,6 @@ #include "OptionHandler.h" -#include - -#include "A2STR.h" - namespace aria2 { class Option; @@ -54,22 +50,10 @@ protected: std::string defaultValue_; - std::vector tags_; - OptionHandler::ARG_TYPE argType_; char shortName_; - bool hidden_; - - bool eraseAfterParse_; - - bool initialOption_; - bool changeOption_; - bool changeOptionForReserved_; - bool globalChangeOption_; - bool cumulative_; - virtual void parseArg(Option& option, const std::string& arg) = 0; public: AbstractOptionHandler(const Pref* pref, @@ -79,12 +63,12 @@ public: char shortName = 0); virtual ~AbstractOptionHandler(); - + virtual void parse(Option& option, const std::string& arg); - virtual bool hasTag(const std::string& tag) const; + virtual bool hasTag(uint32_t tag) const; - virtual void addTag(const std::string& tag); + virtual void addTag(uint32_t tag); virtual std::string toTagString() const; @@ -100,16 +84,6 @@ public: return defaultValue_; } - virtual bool isHidden() const - { - return hidden_; - } - - virtual void hide() - { - hidden_ = true; - } - virtual const Pref* getPref() const { return pref_; @@ -125,65 +99,51 @@ public: return argType_; } - virtual bool getEraseAfterParse() const - { - return eraseAfterParse_; - } + virtual bool isHidden() const; - virtual void setEraseAfterParse(bool eraseAfterParse) - { - eraseAfterParse_ = eraseAfterParse; - } + virtual void hide(); - virtual bool getInitialOption() const - { - return initialOption_; - } + virtual bool getEraseAfterParse() const; - virtual void setInitialOption(bool f) - { - initialOption_ = f; - } + virtual void setEraseAfterParse(bool f); - virtual bool getChangeOption() const - { - return changeOption_; - } + virtual bool getInitialOption() const; - virtual void setChangeOption(bool f) - { - changeOption_ = f; - } + virtual void setInitialOption(bool f); - virtual bool getChangeOptionForReserved() const - { - return changeOptionForReserved_; - } + virtual bool getChangeOption() const; - virtual void setChangeOptionForReserved(bool f) - { - changeOptionForReserved_ = f; - } + virtual void setChangeOption(bool f); - virtual bool getChangeGlobalOption() const - { - return globalChangeOption_; - } + virtual bool getChangeOptionForReserved() const; - virtual void setChangeGlobalOption(bool f) - { - globalChangeOption_ = f; - } + virtual void setChangeOptionForReserved(bool f); - virtual bool getCumulative() const - { - return cumulative_; - } + virtual bool getChangeGlobalOption() const; - virtual void setCumulative(bool f) - { - cumulative_ = f; - } + virtual void setChangeGlobalOption(bool f); + + virtual bool getCumulative() const; + + virtual void setCumulative(bool f); + + enum Flag { + FLAG_HIDDEN = 1, + FLAG_ERASE_AFTER_PARSE = 1 << 1, + FLAG_INITIAL_OPTION = 1 << 2, + FLAG_CHANGE_OPTION = 1 << 3, + FLAG_CHANGE_OPTION_FOR_RESERVED = 1 << 4, + FLAG_CHANGE_GLOBAL_OPTION = 1 << 5, + FLAG_CUMULATIVE = 1 << 6 + }; +private: + // bitwise OR of (1 << HelpTag value) defined in help_tags.h. + uint32_t tags_; + + // bitwise OR of Flag values. + uint8_t flags_; + + void updateFlags(int flag, bool val); }; } // namespace aria2 diff --git a/src/Makefile.am b/src/Makefile.am index a4a88790..d129221f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -149,7 +149,7 @@ SRCS = Socket.h\ a2netcompat.h\ a2time.h\ array_fun.h\ - help_tags.h\ + help_tags.cc help_tags.h\ prefs.cc prefs.h\ usage_text.h\ ProtocolDetector.cc ProtocolDetector.h\ diff --git a/src/OptionHandler.h b/src/OptionHandler.h index 3e17ada7..a0f0ed8a 100644 --- a/src/OptionHandler.h +++ b/src/OptionHandler.h @@ -62,14 +62,14 @@ struct Pref; class OptionHandler { public: virtual ~OptionHandler() {} - + virtual void parse(Option& option, const std::string& arg) = 0; virtual std::string createPossibleValuesString() const = 0; - virtual bool hasTag(const std::string& tag) const = 0; + virtual bool hasTag(uint32_t tag) const = 0; - virtual void addTag(const std::string& tag) = 0; + virtual void addTag(uint32_t tag) = 0; virtual std::string toTagString() const = 0; diff --git a/src/OptionHandlerFactory.cc b/src/OptionHandlerFactory.cc index 1910f81c..cfb47001 100644 --- a/src/OptionHandlerFactory.cc +++ b/src/OptionHandlerFactory.cc @@ -2173,29 +2173,16 @@ OptionHandlerFactory::createOptionHandlers() } // Help Option { - static std::string tags[] = { - TAG_BASIC, - TAG_ADVANCED, - TAG_HTTP, - TAG_HTTPS, - TAG_FTP, - TAG_METALINK, - TAG_BITTORRENT, - TAG_COOKIE, - TAG_HOOK, - TAG_FILE, - TAG_RPC, - TAG_CHECKSUM, - TAG_EXPERIMENTAL, - TAG_DEPRECATED, - TAG_HELP, - TAG_ALL - }; - static std::string tagsStr = strjoin(vbegin(tags), vend(tags), ", "); + std::string tagsStr; + for(int i = 0; i < MAX_HELP_TAG; ++i) { + tagsStr += strHelpTag(i); + tagsStr += ", "; + } + tagsStr += STR_TAG_ALL; SharedHandle op(new DefaultOptionHandler (PREF_HELP, TEXT_HELP, - TAG_BASIC, + strHelpTag(TAG_BASIC), tagsStr, OptionHandler::OPT_ARG, 'h')); diff --git a/src/OptionHandlerImpl.cc b/src/OptionHandlerImpl.cc index 89c39298..86cc9d28 100644 --- a/src/OptionHandlerImpl.cc +++ b/src/OptionHandlerImpl.cc @@ -630,12 +630,12 @@ std::string DeprecatedOptionHandler::createPossibleValuesString() const return depOptHandler_->createPossibleValuesString(); } -bool DeprecatedOptionHandler::hasTag(const std::string& tag) const +bool DeprecatedOptionHandler::hasTag(uint32_t tag) const { return depOptHandler_->hasTag(tag); } -void DeprecatedOptionHandler::addTag(const std::string& tag) +void DeprecatedOptionHandler::addTag(uint32_t tag) { depOptHandler_->addTag(tag); } diff --git a/src/OptionHandlerImpl.h b/src/OptionHandlerImpl.h index b046cd8a..7537ffbd 100644 --- a/src/OptionHandlerImpl.h +++ b/src/OptionHandlerImpl.h @@ -40,6 +40,7 @@ #include #include "AbstractOptionHandler.h" +#include "A2STR.h" namespace aria2 { @@ -278,8 +279,8 @@ public: SharedHandle()); virtual void parse(Option& option, const std::string& arg); virtual std::string createPossibleValuesString() const; - virtual bool hasTag(const std::string& tag) const; - virtual void addTag(const std::string& tag); + virtual bool hasTag(uint32_t tag) const; + virtual void addTag(uint32_t tag); virtual std::string toTagString() const; virtual const char* getName() const; virtual const char* getDescription() const; diff --git a/src/OptionParser.cc b/src/OptionParser.cc index 04778f78..53e0c2c0 100644 --- a/src/OptionParser.cc +++ b/src/OptionParser.cc @@ -268,7 +268,7 @@ void OptionParser::parseDefaultValues(Option& option) const } std::vector > -OptionParser::findByTag(const std::string& tag) const +OptionParser::findByTag(uint32_t tag) const { std::vector > result; for(std::vector >::const_iterator i = diff --git a/src/OptionParser.h b/src/OptionParser.h index 8d28bbeb..901fe8ec 100644 --- a/src/OptionParser.h +++ b/src/OptionParser.h @@ -76,7 +76,7 @@ public: // Hidden options are not returned. std::vector > - findByTag(const std::string& tag) const; + findByTag(uint32_t tag) const; // Hidden options are not returned. std::vector > diff --git a/src/help_tags.cc b/src/help_tags.cc new file mode 100644 index 00000000..9b32729f --- /dev/null +++ b/src/help_tags.cc @@ -0,0 +1,83 @@ +/* */ +#include "help_tags.h" + +#include + +#include "array_fun.h" + +namespace aria2 { + +namespace { +const char* HELP_TAG_NAMES[] = { + "#basic", + "#advanced", + "#http", + "#https", + "#ftp", + "#metalink", + "#bittorrent", + "#cookie", + "#hook", + "#file", + "#rpc", + "#checksum", + "#experimental", + "#deprecated", + "#help" +}; +} // namespace + +const char* strHelpTag(uint32_t tag) +{ + if(tag >= MAX_HELP_TAG) { + return "UNKNOWN"; + } else { + return HELP_TAG_NAMES[tag]; + } +} + +uint32_t idHelpTag(const char* tagName) +{ + for(const char** p = vbegin(HELP_TAG_NAMES), ** eop = vend(HELP_TAG_NAMES); + p != eop; ++p) { + if(strcmp(*p, tagName) == 0) { + return p - vbegin(HELP_TAG_NAMES); + } + } + return MAX_HELP_TAG; +} + +} // namespace aria2 diff --git a/src/help_tags.h b/src/help_tags.h index 13665dbe..e6f5de1c 100644 --- a/src/help_tags.h +++ b/src/help_tags.h @@ -2,7 +2,7 @@ /* * aria2 - The high speed download utility * - * Copyright (C) 2006 Tatsuhiro Tsujikawa + * Copyright (C) 2012 Tatsuhiro Tsujikawa * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -35,21 +35,38 @@ #ifndef D_HELP_TAGS_H #define D_HELP_TAGS_H -#define TAG_BASIC "#basic" -#define TAG_ADVANCED "#advanced" -#define TAG_HTTP "#http" -#define TAG_HTTPS "#https" -#define TAG_FTP "#ftp" -#define TAG_METALINK "#metalink" -#define TAG_BITTORRENT "#bittorrent" -#define TAG_COOKIE "#cookie" -#define TAG_HOOK "#hook" -#define TAG_FILE "#file" -#define TAG_RPC "#rpc" -#define TAG_CHECKSUM "#checksum" -#define TAG_EXPERIMENTAL "#experimental" -#define TAG_DEPRECATED "#deprecated" -#define TAG_HELP "#help" -#define TAG_ALL "#all" +#include "common.h" + +namespace aria2 { + +enum HelpTag { + TAG_BASIC, + TAG_ADVANCED, + TAG_HTTP, + TAG_HTTPS, + TAG_FTP, + TAG_METALINK, + TAG_BITTORRENT, + TAG_COOKIE, + TAG_HOOK, + TAG_FILE, + TAG_RPC, + TAG_CHECKSUM, + TAG_EXPERIMENTAL, + TAG_DEPRECATED, + TAG_HELP, + MAX_HELP_TAG +}; + +#define STR_TAG_ALL "#all" + +// Returns tag name of the given |tag| ID. +const char* strHelpTag(uint32_t tag); + +// Returns the corresponding enum value of the given |tagName|. If +// there is no such tag, returns MAX_HELP_TAG. +uint32_t idHelpTag(const char* tagName); + +} // namespace aria2 #endif // D_HELP_TAGS_H diff --git a/src/option_processing.cc b/src/option_processing.cc index c1c6d065..66be040e 100644 --- a/src/option_processing.cc +++ b/src/option_processing.cc @@ -198,7 +198,7 @@ void option_processing(Option& op, std::vector& uris, if(op.defined(PREF_HELP)) { std::string keyword; if(op.get(PREF_HELP).empty()) { - keyword = TAG_BASIC; + keyword = strHelpTag(TAG_BASIC); } else { keyword = op.get(PREF_HELP); if(util::startsWith(keyword, "--")) { @@ -217,7 +217,7 @@ void option_processing(Option& op, std::vector& uris, oparser->parseDefaultValues(op); if(!noConf) { - std::string cfname = + std::string cfname = ucfname.empty() ? oparser->find(PREF_CONF_PATH)->getDefaultValue() : ucfname; @@ -249,7 +249,7 @@ void option_processing(Option& op, std::vector& uris, global::cerr()->printf(_("Configuration file %s is not found."), cfname.c_str()); global::cerr()->printf("\n"); - showUsage(TAG_HELP, oparser, global::cerr()); + showUsage(strHelpTag(TAG_HELP), oparser, global::cerr()); exit(error_code::UNKNOWN_ERROR); } } diff --git a/src/version_usage.cc b/src/version_usage.cc index 26f3a63e..77dd9e98 100644 --- a/src/version_usage.cc +++ b/src/version_usage.cc @@ -94,8 +94,9 @@ void showUsage return; } else if(keyword[0] == '#') { std::vector > handlers = - keyword == TAG_ALL ? oparser->findAll() : oparser->findByTag(keyword); - if(keyword == TAG_ALL) { + keyword == STR_TAG_ALL ? oparser->findAll() : + oparser->findByTag(idHelpTag(keyword.c_str())); + if(keyword == STR_TAG_ALL) { out->printf(_("Printing all options.")); } else { out->printf(_("Printing options tagged with '%s'."), @@ -111,7 +112,7 @@ void showUsage write(out, *(*i)); out->printf("\n"); } - } else { + } else { std::vector > handlers = oparser->findByNameSubstring(keyword); if(!handlers.empty()) { @@ -132,7 +133,7 @@ void showUsage write(out, *oparser->find(PREF_HELP)); } } - if(keyword == TAG_BASIC) { + if(keyword == strHelpTag(TAG_BASIC)) { out->printf("URI, MAGNET, TORRENT_FILE, METALINK_FILE:\n"); out->printf(_(" You can specify multiple HTTP(S)/FTP URIs. Unless you specify -Z option, all\n" " URIs must point to the same file or downloading will fail.")); diff --git a/test/OptionHandlerTest.cc b/test/OptionHandlerTest.cc index d3da8902..1d01b6a8 100644 --- a/test/OptionHandlerTest.cc +++ b/test/OptionHandlerTest.cc @@ -5,6 +5,7 @@ #include "Option.h" #include "prefs.h" #include "Exception.h" +#include "help_tags.h" namespace aria2 { @@ -28,7 +29,7 @@ class OptionHandlerTest:public CppUnit::TestFixture { CPPUNIT_TEST(testHttpProxyOptionHandler); CPPUNIT_TEST(testDeprecatedOptionHandler); CPPUNIT_TEST_SUITE_END(); - + public: void testBooleanOptionHandler(); void testNumberOptionHandler(); @@ -207,13 +208,13 @@ void OptionHandlerTest::testDefaultOptionHandler() CPPUNIT_ASSERT_EQUAL(std::string(""), option.get(PREF_TIMEOUT)); CPPUNIT_ASSERT_EQUAL(std::string(""), handler.createPossibleValuesString()); - handler.addTag("apple"); - CPPUNIT_ASSERT_EQUAL(std::string("apple"), handler.toTagString()); - handler.addTag("orange"); - CPPUNIT_ASSERT_EQUAL(std::string("apple, orange"), handler.toTagString()); - CPPUNIT_ASSERT(handler.hasTag("apple")); - CPPUNIT_ASSERT(handler.hasTag("orange")); - CPPUNIT_ASSERT(!handler.hasTag("pineapple")); + handler.addTag(TAG_ADVANCED); + CPPUNIT_ASSERT_EQUAL(std::string("#advanced"), handler.toTagString()); + handler.addTag(TAG_BASIC); + CPPUNIT_ASSERT_EQUAL(std::string("#basic, #advanced"), handler.toTagString()); + CPPUNIT_ASSERT(handler.hasTag(TAG_ADVANCED)); + CPPUNIT_ASSERT(handler.hasTag(TAG_BASIC)); + CPPUNIT_ASSERT(!handler.hasTag(TAG_HTTP)); } void OptionHandlerTest::testFloatNumberOptionHandler() diff --git a/test/OptionParserTest.cc b/test/OptionParserTest.cc index 727432f0..f8c07985 100644 --- a/test/OptionParserTest.cc +++ b/test/OptionParserTest.cc @@ -11,6 +11,7 @@ #include "Option.h" #include "array_fun.h" #include "prefs.h" +#include "help_tags.h" namespace aria2 { @@ -37,28 +38,28 @@ public: SharedHandle timeout (new DefaultOptionHandler(PREF_TIMEOUT, NO_DESCRIPTION, "ALPHA", "", OptionHandler::REQ_ARG, 'A')); - timeout->addTag("apple"); + timeout->addTag(TAG_BASIC); timeout->setEraseAfterParse(true); oparser_->addOptionHandler(timeout); SharedHandle dir(new DefaultOptionHandler(PREF_DIR)); - dir->addTag("apple"); - dir->addTag("orange"); - dir->addTag("pineapple"); + dir->addTag(TAG_BASIC); + dir->addTag(TAG_HTTP); + dir->addTag(TAG_FILE); oparser_->addOptionHandler(dir); SharedHandle daemon (new DefaultOptionHandler(PREF_DAEMON, NO_DESCRIPTION, "CHARLIE", "", OptionHandler::REQ_ARG, 'C')); daemon->hide(); - daemon->addTag("pineapple"); + daemon->addTag(TAG_FILE); oparser_->addOptionHandler(daemon); SharedHandle out (new UnitNumberOptionHandler(PREF_OUT, NO_DESCRIPTION, "1M", -1, -1, 'D')); - out->addTag("pineapple"); - oparser_->addOptionHandler(out); + out->addTag(TAG_FILE); + oparser_->addOptionHandler(out); } void tearDown() {} @@ -98,7 +99,7 @@ void OptionParserTest::testFindByNameSubstring() void OptionParserTest::testFindByTag() { std::vector > res = - oparser_->findByTag("pineapple"); + oparser_->findByTag(TAG_FILE); CPPUNIT_ASSERT_EQUAL((size_t)2, res.size()); CPPUNIT_ASSERT_EQUAL(std::string("dir"), std::string(res[0]->getName())); CPPUNIT_ASSERT_EQUAL(std::string("out"), std::string(res[1]->getName()));