diff --git a/ChangeLog b/ChangeLog index 401dc767..7108db2f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2008-01-05 Tatsuhiro Tsujikawa + + Added categorized option help. Specify category using --help option. + Also added the ability to search options in forward match. + * src/HelpItem.{h, cc} + * test/HelpItemTest.cc + * src/HelpItemFactory.{h, cc} + * src/TagContainer.{h, cc} + * test/TagContainerTest.cc + * src/option_processing.cc + * src/prefs.h + * src/TaggedItem.{h, cc} + * test/TaggedItemTest.cc + * src/version_usage.cc + * src/help_tags.h + * src/usage_text.h + 2008-01-04 Tatsuhiro Tsujikawa Fixed segmentation fault when bad torrent metainfo is parsed. diff --git a/po/POTFILES b/po/POTFILES index b089f4cb..2b834471 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -1,8 +1,10 @@ ../src/OptionHandlerImpl.h \ ../src/message.h \ - ../src/DownloadEngineFactory.cc \ + ../src/usage_text.h \ + ../src/BtSetup.cc \ + ../src/DownloadEngine.cc \ + ../src/HelpItem.cc \ ../src/MultiUrlRequestInfo.cc \ ../src/RequestGroupMan.cc \ ../src/Util.cc \ - ../src/version_usage.cc \ - ../src/BtSetup.cc + ../src/version_usage.cc diff --git a/po/POTFILES.in b/po/POTFILES.in index 9ea375d1..1b291a33 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -1,8 +1,10 @@ src/OptionHandlerImpl.h src/message.h -src/DownloadEngineFactory.cc +src/usage_text.h +src/BtSetup.cc +src/DownloadEngine.cc +src/HelpItem.cc src/MultiUrlRequestInfo.cc src/RequestGroupMan.cc src/Util.cc src/version_usage.cc -src/BtSetup.cc diff --git a/src/HelpItem.cc b/src/HelpItem.cc new file mode 100644 index 00000000..36d6199d --- /dev/null +++ b/src/HelpItem.cc @@ -0,0 +1,58 @@ +/* */ +#include "HelpItem.h" + +#define DEFAULT_MSG _(" Default: ") +#define TAGS_MSG _(" Tags: ") +#define AVAILABLE_MSG _(" Available Values: ") + +ostream& operator<<(ostream& o, const HelpItem& helpItem) +{ + o << helpItem._usageText << "\n"; + if(!helpItem._availableValues.empty()) { + o << AVAILABLE_MSG << helpItem._availableValues << "\n"; + } + if(!helpItem._defaultValue.empty()) { + o << DEFAULT_MSG << helpItem._defaultValue << "\n"; + } + o << TAGS_MSG << helpItem.toTagString(); + return o; +} + +ostream& operator<<(ostream& o, const HelpItemHandle& helpItem) +{ + o << *helpItem.get(); + return o; +} diff --git a/src/HelpItem.h b/src/HelpItem.h new file mode 100644 index 00000000..de261354 --- /dev/null +++ b/src/HelpItem.h @@ -0,0 +1,69 @@ +/* */ +#ifndef _D_HELP_ITEM_H_ +#define _D_HELP_ITEM_H_ + +#include "TaggedItem.h" + +class HelpItem; +typedef SharedHandle HelpItemHandle; + +class HelpItem:public TaggedItem { +private: + string _usageText; + + string _availableValues; + + string _defaultValue; + +public: + HelpItem(const string& name, const string& usageText, const string& defaultValue = ""): + TaggedItem(name), + _usageText(usageText), + _defaultValue(defaultValue) {} + + virtual ~HelpItem() {} + + void setAvailableValues(const string& availableValues) + { + _availableValues = availableValues; + } + + friend ostream& operator<<(ostream& o, const HelpItem& helpItem); + + friend ostream& operator<<(ostream& o, const HelpItemHandle& helpItem); +}; + +#endif // _D_HELP_ITEM_H_ diff --git a/src/HelpItemFactory.cc b/src/HelpItemFactory.cc new file mode 100644 index 00000000..7d530e0c --- /dev/null +++ b/src/HelpItemFactory.cc @@ -0,0 +1,395 @@ +/* */ +#include "HelpItemFactory.h" +#include "TagContainer.h" +#include "HelpItem.h" +#include "usage_text.h" +#include "prefs.h" +#include "a2io.h" +#include "help_tags.h" + +HelpItemFactory::HelpItemFactory() {} + +TagContainerHandle HelpItemFactory::createHelpItems() +{ + TagContainerHandle tc = new TagContainer(); + { + HelpItemHandle item = new HelpItem(PREF_DIR, TEXT_DIR); + item->addTag(TAG_BASIC); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_OUT, TEXT_OUT); + item->addTag(TAG_BASIC); + item->addTag(TAG_HTTP); + item->addTag(TAG_FTP); + tc->addItem(item); + } +#ifdef HAVE_DAEMON + { + HelpItemHandle item = new HelpItem(PREF_DAEMON, TEXT_DAEMON); + item->addTag(TAG_ADVANCED); + tc->addItem(item); + } +#endif // HAVE_DAEMON + { + HelpItemHandle item = new HelpItem(PREF_SPLIT, TEXT_SPLIT); + item->addTag(TAG_BASIC); + item->addTag(TAG_HTTP); + item->addTag(TAG_FTP); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_RETRY_WAIT, TEXT_RETRY_WAIT); + item->addTag(TAG_HTTP); + item->addTag(TAG_FTP); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_TIMEOUT, TEXT_TIMEOUT); + item->addTag(TAG_HTTP); + item->addTag(TAG_FTP); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_MAX_TRIES, TEXT_MAX_TRIES); + item->addTag(TAG_HTTP); + item->addTag(TAG_FTP); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_HTTP_PROXY, TEXT_HTTP_PROXY); + item->addTag(TAG_HTTP); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_HTTP_USER, TEXT_HTTP_USER); + item->addTag(TAG_BASIC); + item->addTag(TAG_HTTP); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_HTTP_PASSWD, TEXT_HTTP_PASSWD); + item->addTag(TAG_BASIC); + item->addTag(TAG_HTTP); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_HTTP_PROXY_USER, TEXT_HTTP_PROXY_USER); + item->addTag(TAG_HTTP); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_HTTP_PROXY_PASSWD, TEXT_HTTP_PROXY_PASSWD); + item->addTag(TAG_HTTP); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_HTTP_PROXY_METHOD, TEXT_HTTP_PROXY_METHOD); + item->addTag(TAG_HTTP); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_HTTP_AUTH_SCHEME, TEXT_HTTP_AUTH_SCHEME); + item->addTag(TAG_HTTP); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_REFERER, TEXT_REFERER); + item->addTag(TAG_HTTP); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_FTP_USER, TEXT_FTP_USER); + item->addTag(TAG_BASIC); + item->addTag(TAG_FTP); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_FTP_PASSWD, TEXT_FTP_PASSWD); + item->addTag(TAG_BASIC); + item->addTag(TAG_FTP); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_FTP_TYPE, TEXT_FTP_TYPE); + item->addTag(TAG_FTP); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_FTP_PASV, TEXT_FTP_PASV); + item->addTag(TAG_FTP); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_FTP_VIA_HTTP_PROXY, TEXT_FTP_VIA_HTTP_PROXY); + item->addTag(TAG_FTP); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_LOWEST_SPEED_LIMIT, TEXT_LOWEST_SPEED_LIMIT); + item->addTag(TAG_HTTP); + item->addTag(TAG_FTP); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_MAX_DOWNLOAD_LIMIT, TEXT_MAX_DOWNLOAD_LIMIT); + item->addTag(TAG_HTTP); + item->addTag(TAG_FTP); + item->addTag(TAG_BITTORRENT); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_FILE_ALLOCATION, TEXT_FILE_ALLOCATION); + item->addTag(TAG_ADVANCED); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_NO_FILE_ALLOCATION_LIMIT, TEXT_NO_FILE_ALLOCATION_LIMIT, "5M"); + item->addTag(TAG_ADVANCED); + tc->addItem(item); + } +#ifdef ENABLE_DIRECT_IO + { + HelpItemHandle item = new HelpItem(PREF_ENABLE_DIRECT_IO, TEXT_ENABLE_DIRECT_IO, V_TRUE); + item->addTag(TAG_ADVANCED); + tc->addItem(item); + } +#endif // ENABLE_DIRECT_IO + { + HelpItemHandle item = new HelpItem(PREF_ALLOW_OVERWRITE, TEXT_ALLOW_OVERWRITE); + item->addTag(TAG_ADVANCED); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_ALLOW_PIECE_LENGTH_CHANGE, TEXT_ALLOW_PIECE_LENGTH_CHANGE, V_FALSE); + item->addTag(TAG_ADVANCED); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_FORCE_SEQUENTIAL, TEXT_FORCE_SEQUENTIAL); + item->addTag(TAG_ADVANCED); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_AUTO_FILE_RENAMING, TEXT_AUTO_FILE_RENAMING); + item->addTag(TAG_ADVANCED); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_PARAMETERIZED_URI, TEXT_PARAMETERIZED_URI); + item->addTag(TAG_ADVANCED); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_ENABLE_HTTP_KEEP_ALIVE, TEXT_ENABLE_HTTP_KEEP_ALIVE); + item->addTag(TAG_HTTP); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_ENABLE_HTTP_PIPELINING, TEXT_ENABLE_HTTP_PIPELINING); + item->addTag(TAG_HTTP); + tc->addItem(item); + } +#ifdef ENABLE_MESSAGE_DIGEST + { + HelpItemHandle item = new HelpItem(PREF_CHECK_INTEGRITY, TEXT_CHECK_INTEGRITY); + item->addTag(TAG_BASIC); + item->addTag(TAG_METALINK); + item->addTag(TAG_BITTORRENT); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_REALTIME_CHUNK_CHECKSUM, TEXT_REALTIME_CHUNK_CHECKSUM); + item->addTag(TAG_METALINK); + tc->addItem(item); + } +#endif // ENABLE_MESSAGE_DIGEST + { + HelpItemHandle item = new HelpItem(PREF_CONTINUE, TEXT_CONTINUE); + item->addTag(TAG_BASIC); + item->addTag(TAG_HTTP); + item->addTag(TAG_FTP); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_USER_AGENT, TEXT_USER_AGENT); + item->addTag(TAG_HTTP); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_NO_NETRC, TEXT_NO_NETRC); + item->addTag(TAG_FTP); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_INPUT_FILE, TEXT_INPUT_FILE); + item->addTag(TAG_BASIC); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_MAX_CONCURRENT_DOWNLOADS, TEXT_MAX_CONCURRENT_DOWNLOADS); + item->addTag(TAG_ADVANCED); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_LOAD_COOKIES, TEXT_LOAD_COOKIES); + item->addTag(TAG_BASIC); + item->addTag(TAG_HTTP); + tc->addItem(item); + } +#if defined ENABLE_BITTORRENT || ENABLE_METALINK + { + HelpItemHandle item = new HelpItem(PREF_SHOW_FILES, TEXT_SHOW_FILES); + item->addTag(TAG_BASIC); + item->addTag(TAG_METALINK); + item->addTag(TAG_BITTORRENT); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_SELECT_FILE, TEXT_SELECT_FILE); + item->addTag(TAG_METALINK); + item->addTag(TAG_BITTORRENT); + tc->addItem(item); + } +#endif // ENABLE_BITTORRENT || ENABLE_METALINK +#ifdef ENABLE_BITTORRENT + { + HelpItemHandle item = new HelpItem(PREF_TORRENT_FILE, TEXT_TORRENT_FILE); + item->addTag(TAG_BASIC); + item->addTag(TAG_BITTORRENT); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_FOLLOW_TORRENT, TEXT_FOLLOW_TORRENT, V_TRUE); + item->addTag(TAG_BITTORRENT); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_DIRECT_FILE_MAPPING, TEXT_DIRECT_FILE_MAPPING); + item->addTag(TAG_BITTORRENT); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_LISTEN_PORT, TEXT_LISTEN_PORT, "6881-6999"); + item->addTag(TAG_BASIC); + item->addTag(TAG_BITTORRENT); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_MAX_UPLOAD_LIMIT, TEXT_MAX_UPLOAD_LIMIT); + item->addTag(TAG_BASIC); + item->addTag(TAG_BITTORRENT); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_SEED_TIME, TEXT_SEED_TIME); + item->addTag(TAG_BITTORRENT); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_SEED_RATIO, TEXT_SEED_RATIO, "1.0"); + item->addTag(TAG_BITTORRENT); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_PEER_ID_PREFIX, TEXT_PEER_ID_PREFIX); + item->addTag(TAG_BITTORRENT); + tc->addItem(item); + } +#endif // ENABLE_BITTORRENT +#ifdef ENABLE_METALINK + { + HelpItemHandle item = new HelpItem(PREF_METALINK_FILE, TEXT_METALINK_FILE); + item->addTag(TAG_BASIC); + item->addTag(TAG_METALINK); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_METALINK_SERVERS, TEXT_METALINK_SERVERS); + item->addTag(TAG_METALINK); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_METALINK_VERSION, TEXT_METALINK_VERSION); + item->addTag(TAG_METALINK); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_METALINK_LANGUAGE, TEXT_METALINK_LANGUAGE); + item->addTag(TAG_METALINK); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_METALINK_OS, TEXT_METALINK_OS); + item->addTag(TAG_METALINK); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_METALINK_LOCATION, TEXT_METALINK_LOCATION); + item->addTag(TAG_METALINK); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_METALINK_PREFERRED_PROTOCOL, TEXT_METALINK_PREFERRED_PROTOCOL, V_NONE); + item->addTag(TAG_METALINK); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_FOLLOW_METALINK, TEXT_FOLLOW_METALINK, V_TRUE); + item->addTag(TAG_METALINK); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem(PREF_METALINK_ENABLE_UNIQUE_PROTOCOL, TEXT_METALINK_ENABLE_UNIQUE_PROTOCOL, V_TRUE); + item->addTag(TAG_METALINK); + tc->addItem(item); + } +#endif // ENABLE_METALINK + { + HelpItemHandle item = new HelpItem("version", TEXT_VERSION); + item->addTag(TAG_BASIC); + tc->addItem(item); + } + { + HelpItemHandle item = new HelpItem("help", TEXT_HELP, TAG_BASIC); + char buf[64]; + snprintf(buf, sizeof(buf), "%s,%s,%s,%s,%s,%s,all", TAG_BASIC, TAG_ADVANCED, TAG_HTTP, TAG_FTP, TAG_METALINK, TAG_BITTORRENT); + item->setAvailableValues(buf); + item->addTag(TAG_BASIC); + tc->addItem(item); + } + return tc; +} diff --git a/src/HelpItemFactory.h b/src/HelpItemFactory.h new file mode 100644 index 00000000..7c2c06a1 --- /dev/null +++ b/src/HelpItemFactory.h @@ -0,0 +1,50 @@ +/* */ +#ifndef _D_HELP_ITEM_FACTORY_H_ +#define _D_HELP_ITEM_FACTORY_H_ + +#include "common.h" + +class TagContainer; +typedef SharedHandle TagContainerHandle; + +class HelpItemFactory { +private: + HelpItemFactory(); +public: + static TagContainerHandle createHelpItems(); +}; + +#endif // _D_HELP_ITEM_FACTORY_H_ diff --git a/src/Makefile.am b/src/Makefile.am index 5a3ec101..7aa71f0a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -147,7 +147,11 @@ SRCS = Socket.h\ MultiFileAllocationIterator.cc MultiFileAllocationIterator.h\ PeerConnection.cc PeerConnection.h\ ByteArrayDiskWriter.cc ByteArrayDiskWriter.h\ - ServerHost.cc + ServerHost.cc\ + HelpItem.cc\ + TaggedItem.cc\ + TagContainer.cc\ + HelpItemFactory.cc # debug_new.cpp if ENABLE_MESSAGE_DIGEST diff --git a/src/Makefile.in b/src/Makefile.in index ba2d0427..ffc90332 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -299,7 +299,8 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \ BtRegistry.cc BtRegistry.h MultiFileAllocationIterator.cc \ MultiFileAllocationIterator.h PeerConnection.cc \ PeerConnection.h ByteArrayDiskWriter.cc ByteArrayDiskWriter.h \ - ServerHost.cc IteratableChunkChecksumValidator.cc \ + ServerHost.cc HelpItem.cc TaggedItem.cc TagContainer.cc \ + HelpItemFactory.cc IteratableChunkChecksumValidator.cc \ IteratableChunkChecksumValidator.h \ IteratableChecksumValidator.cc IteratableChecksumValidator.h \ CheckIntegrityCommand.cc CheckIntegrityCommand.h \ @@ -546,11 +547,12 @@ am__objects_14 = SocketCore.$(OBJEXT) Command.$(OBJEXT) \ Peer.$(OBJEXT) BtRegistry.$(OBJEXT) \ MultiFileAllocationIterator.$(OBJEXT) PeerConnection.$(OBJEXT) \ ByteArrayDiskWriter.$(OBJEXT) ServerHost.$(OBJEXT) \ - $(am__objects_1) $(am__objects_2) $(am__objects_3) \ - $(am__objects_4) $(am__objects_5) $(am__objects_6) \ - $(am__objects_7) $(am__objects_8) $(am__objects_9) \ - $(am__objects_10) $(am__objects_11) $(am__objects_12) \ - $(am__objects_13) + HelpItem.$(OBJEXT) TaggedItem.$(OBJEXT) TagContainer.$(OBJEXT) \ + HelpItemFactory.$(OBJEXT) $(am__objects_1) $(am__objects_2) \ + $(am__objects_3) $(am__objects_4) $(am__objects_5) \ + $(am__objects_6) $(am__objects_7) $(am__objects_8) \ + $(am__objects_9) $(am__objects_10) $(am__objects_11) \ + $(am__objects_12) $(am__objects_13) am_libaria2c_a_OBJECTS = $(am__objects_14) libaria2c_a_OBJECTS = $(am_libaria2c_a_OBJECTS) am__installdirs = "$(DESTDIR)$(bindir)" @@ -845,11 +847,12 @@ SRCS = Socket.h SocketCore.cc SocketCore.h Command.cc Command.h \ BtRegistry.cc BtRegistry.h MultiFileAllocationIterator.cc \ MultiFileAllocationIterator.h PeerConnection.cc \ PeerConnection.h ByteArrayDiskWriter.cc ByteArrayDiskWriter.h \ - ServerHost.cc $(am__append_1) $(am__append_2) $(am__append_3) \ - $(am__append_4) $(am__append_5) $(am__append_6) \ - $(am__append_7) $(am__append_8) $(am__append_9) \ - $(am__append_10) $(am__append_11) $(am__append_12) \ - $(am__append_13) + ServerHost.cc HelpItem.cc TaggedItem.cc TagContainer.cc \ + HelpItemFactory.cc $(am__append_1) $(am__append_2) \ + $(am__append_3) $(am__append_4) $(am__append_5) \ + $(am__append_6) $(am__append_7) $(am__append_8) \ + $(am__append_9) $(am__append_10) $(am__append_11) \ + $(am__append_12) $(am__append_13) noinst_LIBRARIES = libaria2c.a libaria2c_a_SOURCES = $(SRCS) aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\ @@ -1041,6 +1044,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HandshakeExtensionMessage.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HashMetalinkParserState.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HaveEraseCommand.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HelpItem.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HelpItemFactory.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpConnection.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpDownloadCommand.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpHeader.Po@am__quote@ @@ -1123,6 +1128,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SpeedCalc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StreamCheckIntegrityEntry.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StreamFileAllocationEntry.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TagContainer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TaggedItem.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TimeA2.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TimeBasedCommand.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TrackerWatcherCommand.Po@am__quote@ diff --git a/src/TagContainer.cc b/src/TagContainer.cc new file mode 100644 index 00000000..7b736901 --- /dev/null +++ b/src/TagContainer.cc @@ -0,0 +1,106 @@ +/* */ +#include "TagContainer.h" +#include "TaggedItem.h" +#include "Util.h" + +TagContainer::TagContainer() {} + +TagContainer::TagContainer(const TaggedItems& items): + _taggedItems(items) {} + +TagContainer::~TagContainer() {} + +class SingleTagSearch { +private: + string _tag; + + TaggedItems _result; +public: + SingleTagSearch(const string& tag):_tag(tag) {} + + void operator()(const TaggedItemHandle& item) + { + if(item->hasTag(_tag)) { + _result.push_back(item); + } + } + + const TaggedItems& getResult() const + { + return _result; + } +}; + +TaggedItems TagContainer::search(const string& tag) const +{ + return for_each(_taggedItems.begin(), _taggedItems.end(), SingleTagSearch(tag)).getResult(); +} + +class NameMatchForward { +private: + string _name; + + TaggedItems _result; +public: + NameMatchForward(const string& name):_name(name) {} + + void operator()(const TaggedItemHandle& item) + { + if(Util::startsWith(item->getName(), _name)) { + _result.push_back(item); + } + } + + const TaggedItems& getResult() const + { + return _result; + } +}; + +TaggedItems TagContainer::nameMatchForward(const string& name) const +{ + return for_each(_taggedItems.begin(), _taggedItems.end(), NameMatchForward(name)).getResult(); +} + +const TaggedItems& TagContainer::getAllItems() const +{ + return _taggedItems; +} + +void TagContainer::addItem(const TaggedItemHandle& item) +{ + _taggedItems.push_back(item); +} diff --git a/src/TagContainer.h b/src/TagContainer.h new file mode 100644 index 00000000..78021767 --- /dev/null +++ b/src/TagContainer.h @@ -0,0 +1,64 @@ +/* */ +#ifndef _D_TAG_CONTAINER_H_ +#define _D_TAG_CONTAINER_H_ + +#include "common.h" + +class TaggedItem; +typedef SharedHandle TaggedItemHandle; +typedef deque TaggedItems; + +class TagContainer { +private: + TaggedItems _taggedItems; +public: + TagContainer(); + + TagContainer(const TaggedItems& items); + + ~TagContainer(); + + void addItem(const TaggedItemHandle& item); + + TaggedItems search(const string& tag) const; + + TaggedItems nameMatchForward(const string& name) const; + + const TaggedItems& getAllItems() const; +}; + +typedef SharedHandle TagContainerHandle; +#endif // _D_TAG_CONTAINER_H_ diff --git a/src/TaggedItem.cc b/src/TaggedItem.cc new file mode 100644 index 00000000..2eca7d7e --- /dev/null +++ b/src/TaggedItem.cc @@ -0,0 +1,67 @@ +/* */ +#include "TaggedItem.h" +#include + +class Concat { +private: + string _delim; +public: + Concat(const string& delim = ""):_delim(delim) {} + + string operator()(const string& s1, const string& s2) const + { + return s1+_delim+s2; + } +}; + +string TaggedItem::toTagString() const +{ + if(_tags.size()) { + return accumulate(_tags.begin()+1, _tags.end(), _tags.front(), Concat(",")); + } else { + return ""; + } +} + +bool TaggedItem::hasTag(const string& tag) const +{ + return find(_tags.begin(), _tags.end(), tag) != _tags.end(); +} + +bool TaggedItem::operator<(const TaggedItem& item) const +{ + return _name < item._name; +} diff --git a/src/TaggedItem.h b/src/TaggedItem.h new file mode 100644 index 00000000..9ae90314 --- /dev/null +++ b/src/TaggedItem.h @@ -0,0 +1,69 @@ +/* */ +#ifndef _D_TAGGED_ITEM_H_ +#define _D_TAGGED_ITEM_H_ + +#include "common.h" + +class TaggedItem { +private: + string _name; + + Strings _tags; +public: + TaggedItem(const string& name):_name(name) {} + + virtual ~TaggedItem() {} + + void addTag(const string& tag) + { + _tags.push_back(tag); + } + + string toTagString() const; + + bool hasTag(const string& tag) const; + + const string& getName() const + { + return _name; + } + + bool operator<(const TaggedItem& item) const; +}; + +typedef SharedHandle TaggedItemHandle; +typedef deque TaggedItems; +#endif // _D_TAGGED_ITEM_H_ diff --git a/src/help_tags.h b/src/help_tags.h new file mode 100644 index 00000000..9d828b4c --- /dev/null +++ b/src/help_tags.h @@ -0,0 +1,45 @@ +/* */ +#ifndef _D_HELP_TAGS_H_ +#define _D_HELP_TAGS_H_ + +#define TAG_BASIC "basic" +#define TAG_ADVANCED "advanced" +#define TAG_HTTP "http" +#define TAG_FTP "ftp" +#define TAG_METALINK "metalink" +#define TAG_BITTORRENT "bittorrent" + +#endif // _D_HELP_TAGS_H_ diff --git a/src/option_processing.cc b/src/option_processing.cc index 05ec2e69..497bf06e 100644 --- a/src/option_processing.cc +++ b/src/option_processing.cc @@ -41,6 +41,7 @@ #include "message.h" #include "Exception.h" #include "a2io.h" +#include "help_tags.h" #include #include @@ -49,7 +50,7 @@ extern int optind, opterr, optopt; #include extern void showVersion(); -extern void showUsage(); +extern void showUsage(const string& category); static string toBoolArg(const char* optarg) { @@ -212,10 +213,10 @@ Option* option_processing(int argc, char* const argv[]) { "metalink-enable-unique-protocol", optional_argument, &lopt, 106 }, #endif // ENABLE_METALINK { "version", no_argument, NULL, 'v' }, - { "help", no_argument, NULL, 'h' }, + { "help", optional_argument, NULL, 'h' }, { 0, 0, 0, 0 } }; - c = getopt_long(argc, argv, "Dd:o:l:s:pt:m:vhST:M:C:a:cU:ni:j:Z::P::", longOpts, &optIndex); + c = getopt_long(argc, argv, "Dd:o:l:s:pt:m:vh::ST:M:C:a:cU:ni:j:Z::P::", longOpts, &optIndex); if(c == -1) { break; } @@ -416,8 +417,16 @@ Option* option_processing(int argc, char* const argv[]) showVersion(); exit(EXIT_SUCCESS); case 'h': - showUsage(); - exit(EXIT_SUCCESS); + { + string category; + if(optarg == 0 || string(optarg) == "") { + category = TAG_BASIC; + } else { + category = optarg; + } + showUsage(category); + exit(EXIT_SUCCESS); + } default: exit(EXIT_FAILURE); } diff --git a/src/prefs.h b/src/prefs.h index 1ab7422f..cb6c62c3 100644 --- a/src/prefs.h +++ b/src/prefs.h @@ -47,6 +47,7 @@ #undef V_NONE #define V_NONE "none" #define V_MEM "mem" +#define V_ALL "all" /** * General preferences */ diff --git a/src/usage_text.h b/src/usage_text.h new file mode 100644 index 00000000..7647f274 --- /dev/null +++ b/src/usage_text.h @@ -0,0 +1,302 @@ +/* */ + +#define TEXT_DIR \ +_(" -d, --dir=DIR The directory to store the downloaded file.") +#define TEXT_OUT \ +_(" -o, --out=FILE The file name of the downloaded file.") +#define TEXT_LOG \ +_(" -l, --log=LOG The file name of the log file. If '-' is\n"\ + " specified, log is written to stdout.") +#define TEXT_DAEMON \ +_(" -D, --daemon Run as daemon.") +#define TEXT_SPLIT \ +_(" -s, --split=N Download a file using N connections. N must be\n"\ + " between 1 and 5. This option affects all URLs.\n"\ + " Thus, aria2 connects to each URL with\n"\ + " N connections.\n"\ + " Default: 1") +#define TEXT_RETRY_WAIT \ +_(" --retry-wait=SEC Set the seconds to wait to retry after an error\n"\ + " has occured. Specify a value between 0 and 60.\n"\ + " Default: 5") +#define TEXT_TIMEOUT \ +_(" -t, --timeout=SEC Set timeout in seconds. Default: 60") +#define TEXT_MAX_TRIES \ +_(" -m, --max-tries=N Set number of tries. 0 means unlimited.\n"\ + " Default: 5") +#define TEXT_HTTP_PROXY \ +_(" --http-proxy=HOST:PORT Use HTTP proxy server. This affects all URLs.") +#define TEXT_HTTP_USER \ +_(" --http-user=USER Set HTTP user. This affects all URLs.") +#define TEXT_HTTP_PASSWD \ +_(" --http-passwd=PASSWD Set HTTP password. This affects all URLs.") +#define TEXT_HTTP_PROXY_USER \ +_(" --http-proxy-user=USER Set HTTP proxy user. This affects all URLs.") +#define TEXT_HTTP_PROXY_PASSWD \ +_(" --http-proxy-passwd=PASSWD Set HTTP proxy password. This affects all URLs.") +#define TEXT_HTTP_PROXY_METHOD \ +_(" --http-proxy-method=METHOD Set the method to use in proxy request.\n"\ + " METHOD is either 'get' or 'tunnel'.\n"\ + " Default: tunnel") +#define TEXT_HTTP_AUTH_SCHEME \ +_(" --http-auth-scheme=SCHEME Set HTTP authentication scheme. Currently, basic\n"\ + " is the only supported scheme.\n"\ + " Default: basic") +#define TEXT_REFERER \ +_(" --referer=REFERER Set Referer. This affects all URLs.") +#define TEXT_FTP_USER \ +_(" --ftp-user=USER Set FTP user. This affects all URLs.\n"\ + " Default: anonymous") +#define TEXT_FTP_PASSWD \ +_(" --ftp-passwd=PASSWD Set FTP password. This affects all URLs.\n"\ + " Default: ARIA2USER@") +#define TEXT_FTP_TYPE \ +_(" --ftp-type=TYPE Set FTP transfer type. TYPE is either 'binary'\n"\ + " or 'ascii'.\n"\ + " Default: binary") +#define TEXT_FTP_PASV \ +_(" -p, --ftp-pasv Use passive mode in FTP.") +#define TEXT_FTP_VIA_HTTP_PROXY \ +_(" --ftp-via-http-proxy=METHOD Use HTTP proxy in FTP. METHOD is either 'get' or\n"\ + " 'tunnel'.\n"\ + " Default: tunnel") +#define TEXT_LOWEST_SPEED_LIMIT \ +_(" --lowest-speed-limit=SPEED Close connection if download speed is lower than\n"\ + " or equal to this value(bytes per sec).\n"\ + " 0 means aria2 does not have a lowest speed limit.\n"\ + " You can append K or M(1K = 1024, 1M = 1024K).\n"\ + " This option does not affect BitTorrent downloads.\n"\ + " Default: 0") +#define TEXT_MAX_DOWNLOAD_LIMIT \ +_(" --max-download-limit=SPEED Set max download speed in bytes per sec.\n"\ + " 0 means unrestricted.\n"\ + " You can append K or M(1K = 1024, 1M = 1024K).\n"\ + " Default: 0") +#define TEXT_FILE_ALLOCATION \ +_(" --file-allocation=METHOD Specify file allocation method. METHOD is either\n"\ + " 'none' or 'prealloc'. 'none' doesn't pre-allocate\n"\ + " file space. 'prealloc' pre-allocates file space\n"\ + " before download begins. This may take some time\n"\ + " depending on the size of the file.\n"\ + " Default: prealloc") +#define TEXT_NO_FILE_ALLOCATION_LIMIT \ +_(" --no-file-allocation-limit=SIZE No file allocation is made for files whose\n"\ + " size is smaller than SIZE.\n"\ + " You can append K or M(1K = 1024, 1M = 1024K).") +# define TEXT_ENABLE_DIRECT_IO \ +_(" --enable-direct-io[=true|false] Enable directI/O, which lowers cpu usage while\n"\ + " allocating files.\n"\ + " Turn off if you encounter any error") +#define TEXT_ALLOW_OVERWRITE \ +_(" --allow-overwrite=true|false If false, aria2 doesn't download a file which\n"\ + " already exists but the corresponding .aria2 file\n"\ + " doesn't exist.\n"\ + " Default: false") +#define TEXT_ALLOW_PIECE_LENGTH_CHANGE \ +_(" --allow-piece-length-change=true|false If false is given, aria2 aborts download\n"\ + " when a piece length is different from one in\n"\ + " a control file. If true is given, you can proceed\n"\ + " but some download progress will be lost.") +#define TEXT_FORCE_SEQUENTIAL \ +_(" -Z, --force-sequential[=true|false] Fetch URIs in the command-line sequentially\n"\ + " and download each URI in a separate session, like\n"\ + " the usual command-line download utilities.\n"\ + " Default: false") +#define TEXT_AUTO_FILE_RENAMING \ +_(" --auto-file-renaming[=true|false] Rename file name if the same file already\n"\ + " exists. This option works only in http(s)/ftp\n"\ + " download.\n"\ + " The new file name has a dot and a number(1..9999)\n"\ + " appended.\n"\ + " Default: true") +#define TEXT_PARAMETERIZED_URI \ +_(" -P, --parameterized-uri[=true|false] Enable parameterized URI support.\n"\ + " You can specify set of parts:\n"\ + " http://{sv1,sv2,sv3}/foo.iso\n"\ + " Also you can specify numeric sequences with step\n"\ + " counter:\n"\ + " http://host/image[000-100:2].img\n"\ + " A step counter can be omitted.\n"\ + " If all URIs do not point to the same file, such\n"\ + " as the second example above, -Z option is\n"\ + " required.\n"\ + " Default: false") +#define TEXT_ENABLE_HTTP_KEEP_ALIVE \ +_(" --enable-http-keep-alive[=true|false] Enable HTTP/1.1 persistent connection.\n"\ + " Default: false") +#define TEXT_ENABLE_HTTP_PIPELINING \ +_(" --enable-http-pipelining[=true|false] Enable HTTP/1.1 pipelining.\n"\ + " Default: false") +#define TEXT_CHECK_INTEGRITY \ +_(" --check-integrity=true|false Check file integrity by validating piece hash.\n"\ + " This option only affects in BitTorrent downloads\n"\ + " and Metalink downloads with chunk checksums.\n"\ + " Use this option to re-download a damaged portion\n"\ + " of a file.\n"\ + " Default: false") +#define TEXT_REALTIME_CHUNK_CHECKSUM \ +_(" --realtime-chunk-checksum=true|false Validate chunk checksum while\n"\ + " downloading a file in Metalink mode. This option\n"\ + " on affects Metalink mode with chunk checksums.\n"\ + " Default: true") +#define TEXT_CONTINUE \ +_(" -c, --continue Continue downloading a partially downloaded\n"\ + " file. Use this option to resume a download\n"\ + " started by a web browser or another program\n"\ + " which downloads files sequentially from the\n"\ + " beginning. Currently this option is only\n"\ + " applicable to http(s)/ftp downloads.") +#define TEXT_USER_AGENT \ +_(" -U, --user-agent=USER_AGENT Set user agent for http(s) downloads.") +#define TEXT_NO_NETRC \ +_(" -n, --no-netrc Disables netrc support.") +#define TEXT_INPUT_FILE \ +_(" -i, --input-file=FILE Downloads URIs found in FILE. You can specify\n"\ + " multiple URIs for a single entity: separate\n"\ + " URIs on a single line using the TAB character.\n"\ + " Reads input from stdin when '-' is specified.") +#define TEXT_MAX_CONCURRENT_DOWNLOADS \ +_(" -j, --max-concurrent-downloads=N Set maximum number of concurrent downloads.\n"\ + " It should be used with the -i option.\n"\ + " Default: 5") +#define TEXT_LOAD_COOKIES \ +_(" --load-cookies=FILE Load cookies from FILE. The format of FILE is\n"\ + " the same used by Netscape and Mozilla.") +#define TEXT_SHOW_FILES \ +_(" -S, --show-files Print file listing of .torrent or .metalink file\n"\ + " and exit. More detailed information will be listed\n"\ + " in case of torrent file.") +#define TEXT_SELECT_FILE \ +_(" --select-file=INDEX... Set file to download by specifing its index.\n"\ + " You can find the file index using the\n"\ + " --show-files option. Multiple indexes can be\n"\ + " specified by using ',', for example: \"3,6\".\n"\ + " You can also use '-' to specify a range: \"1-5\".\n"\ + " ',' and '-' can be used together.\n"\ + " When used with the -M option, index may vary\n"\ + " depending on the query(see --metalink-* options).") +#define TEXT_TORRENT_FILE \ +_(" -T, --torrent-file=TORRENT_FILE The path to the .torrent file.") +#define TEXT_FOLLOW_TORRENT \ +_(" --follow-torrent=true|false|mem If true or mem is specified, when a file\n"\ + " whose suffix is .torrent or content type is\n"\ + " application/x-bittorrent is downloaded, aria2\n"\ + " parses it as a torrent file and downloads files\n"\ + " mentioned in it.\n"\ + " If mem is specified, a torrent file is not\n"\ + " written to the disk, but is just kept in memory.\n"\ + " If false is specified, the action mentioned above\n"\ + " is not taken.") +#define TEXT_DIRECT_FILE_MAPPING \ +_(" --direct-file-mapping=true|false Directly read from and write to each file\n"\ + " mentioned in .torrent file.\n"\ + " Default: true") +#define TEXT_LISTEN_PORT \ +_(" --listen-port=PORT... Set TCP port number for BitTorrent downloads.\n"\ + " Multiple ports can be specified by using ',',\n"\ + " for example: \"6881,6885\". You can also use '-'\n"\ + " to specify a range: \"6881-6999\". ',' and '-' can\n"\ + " be used together.") +#define TEXT_MAX_UPLOAD_LIMIT \ +_(" --max-upload-limit=SPEED Set max upload speed in bytes per sec.\n"\ + " 0 means unrestricted.\n"\ + " You can append K or M(1K = 1024, 1M = 1024K).\n"\ + " Default: 0") +#define TEXT_SEED_TIME \ +_(" --seed-time=MINUTES Specify seeding time in minutes. Also see the\n"\ + " --seed-ratio option.") +#define TEXT_SEED_RATIO \ +_(" --seed-ratio=RATIO Specify share ratio. Seed completed torrents\n"\ + " until share ratio reaches RATIO. 1.0 is\n"\ + " encouraged. Specify 0.0 if you intend to do\n"\ + " seeding regardless of share ratio.\n"\ + " If --seed-time option is specified along with\n"\ + " this option, seeding ends when at least one of\n"\ + " the conditions is satisfied.") +#define TEXT_PEER_ID_PREFIX \ +_(" --peer-id-prefix=PEERI_ID_PREFIX Specify the prefix of peer ID. The peer ID in\n"\ + " BitTorrent is 20 byte length. If more than 20\n"\ + " bytes are specified, only first 20\n"\ + " bytes are used. If less than 20 bytes are\n"\ + " specified, the random alphabet characters are\n"\ + " added to make it's length 20 bytes.\n"\ + " Default: -aria2-") +#define TEXT_METALINK_FILE \ +_(" -M, --metalink-file=METALINK_FILE The file path to the .metalink file.") +#define TEXT_METALINK_SERVERS \ +_(" -C, --metalink-servers=NUM_SERVERS The number of servers to connect to\n"\ + " simultaneously.\n"\ + " Default: 5") +#define TEXT_METALINK_VERSION \ +_(" --metalink-version=VERSION The version of the file to download.") +#define TEXT_METALINK_LANGUAGE \ +_(" --metalink-language=LANGUAGE The language of the file to download.") +#define TEXT_METALINK_OS \ +_(" --metalink-os=OS The operating system of the file to download.") +#define TEXT_METALINK_LOCATION \ +_(" --metalink-location=LOCATION[,...] The location of the preferred server.\n"\ + " A comma-deliminated list of locations is\n"\ + " acceptable.") +#define TEXT_METALINK_PREFERRED_PROTOCOL \ +_(" --metalink-preferred-protocol=PROTO Specify preferred protocol. The possible\n"\ + " values are 'http', 'https', 'ftp' and 'none'.\n"\ + " Specifiy none to disable this feature.") +#define TEXT_FOLLOW_METALINK \ +_(" --follow-metalink=true|false|mem If true or mem is specified, when a file\n"\ + " whose suffix is .metaink or content type is\n"\ + " application/metalink+xml is downloaded, aria2\n"\ + " parses it as a metalink file and downloads files\n"\ + " mentioned in it.\n"\ + " If mem is specified, a metalink file is not\n"\ + " written to the disk, but is just kept in memory.\n"\ + " If false is specified, the action mentioned above\n"\ + " is not taken.") +#define TEXT_METALINK_ENABLE_UNIQUE_PROTOCOL \ +_(" --metalink-enable-unique-protocol=true|false If true is given and several\n"\ + " protocols are available for a mirror in a metalink\n"\ + " file, aria2 uses one of them.\n"\ + " Use --metalink-preferred-protocol option to\n"\ + " specify the preference of protocol.") +#define TEXT_VERSION \ +_(" -v, --version Print the version number and exit.") +#define TEXT_HELP \ +_(" -h, --help[=CATEGORY] Print usage and exit.\n"\ + " The help messages are classified in several\n"\ + " categories. For example, type \"--help=http\" for\n"\ + " detailed explanation for the options related to\n"\ + " http. If no matching category is found, search\n"\ + " option name in forward match and print the\n"\ + " result.") diff --git a/src/version_usage.cc b/src/version_usage.cc index df90244c..a9cd28d6 100644 --- a/src/version_usage.cc +++ b/src/version_usage.cc @@ -38,12 +38,16 @@ #ifdef ENABLE_MESSAGE_DIGEST # include "messageDigest.h" #endif // ENABLE_MESSAGE_DIGEST - -#define DEFAULT_MSG _(" Default: ") +#include "TagContainer.h" +#include "HelpItem.h" +#include "HelpItemFactory.h" +#include "help_tags.h" +#include "prefs.h" +#include void showVersion() { cout << PACKAGE << _(" version ") << PACKAGE_VERSION << "\n" - << "Copyright (C) 2006, 2007 Tatsuhiro Tsujikawa" << "\n" + << "Copyright (C) 2006, 2008 Tatsuhiro Tsujikawa" << "\n" << "\n" << _("This program is free software; you can redistribute it and/or modify\n" @@ -80,13 +84,12 @@ void showVersion() { #ifdef ENABLE_MESSAGE_DIGEST << "message digest algorithms: " << MessageDigestContext::getSupportedAlgoString() << "\n" #endif // ENABLE_MESSAGE_DIGEST - << "\n" - << _("Contact Info:") << "\n" - << "Tatsuhiro Tsujikawa " - << endl; + << "\n"; + printf(_("Report bugs to %s"), ""); + cout << endl; } -void showUsage() { +void showUsage(const string& category) { printf(_("Usage: %s [options] URL ...\n"), PACKAGE_NAME); #ifdef ENABLE_BITTORRENT printf(_(" %s [options] -T TORRENT_FILE URL ...\n"), PACKAGE_NAME); @@ -95,248 +98,44 @@ void showUsage() { printf(_(" %s [options] -M METALINK_FILE\n"), PACKAGE_NAME); #endif // ENABLE_METALINK cout << endl; - cout << _("Options:") << endl; - cout << _(" -d, --dir=DIR The directory to store the downloaded file.") << endl; - cout << _(" -o, --out=FILE The file name of the downloaded file.") << endl; - cout << _(" -l, --log=LOG The file name of the log file. If '-' is\n" - " specified, log is written to stdout.") << endl; -#ifdef HAVE_DAEMON - cout << _(" -D, --daemon Run as daemon.") << endl; -#endif // HAVE_DAEMON - cout << _(" -s, --split=N Download a file using N connections. N must be\n" - " between 1 and 5. This option affects all URLs.\n" - " Thus, aria2 connects to each URL with\n" - " N connections.\n" - " Default: 1") << endl; - cout << _(" --retry-wait=SEC Set the seconds to wait to retry after an error\n" - " has occured. Specify a value between 0 and 60.\n" - " Default: 5") << endl; - cout << _(" -t, --timeout=SEC Set timeout in seconds. Default: 60") << endl; - cout << _(" -m, --max-tries=N Set number of tries. 0 means unlimited.\n" - " Default: 5") << endl; - /* - cout << _(" --min-segment-size=SIZE[K|M] Set minimum segment size. You can append\n" - " K or M(1K = 1024, 1M = 1024K). This\n" - " value must be greater than or equal to\n" - " 1024. Default: 1M") << endl; - */ - cout << _(" --http-proxy=HOST:PORT Use HTTP proxy server. This affects all URLs.") << endl; - cout << _(" --http-user=USER Set HTTP user. This affects all URLs.") << endl; - cout << _(" --http-passwd=PASSWD Set HTTP password. This affects all URLs.") << endl; - cout << _(" --http-proxy-user=USER Set HTTP proxy user. This affects all URLs.") << endl; - cout << _(" --http-proxy-passwd=PASSWD Set HTTP proxy password. This affects all URLs.") << endl; - cout << _(" --http-proxy-method=METHOD Set the method to use in proxy request.\n" - " METHOD is either 'get' or 'tunnel'.\n" - " Default: tunnel") << endl; - cout << _(" --http-auth-scheme=SCHEME Set HTTP authentication scheme. Currently, basic\n" - " is the only supported scheme.\n" - " Default: basic") << endl; - cout << _(" --referer=REFERER Set Referer. This affects all URLs.") << endl; - cout << _(" --ftp-user=USER Set FTP user. This affects all URLs.\n" - " Default: anonymous") << endl; - cout << _(" --ftp-passwd=PASSWD Set FTP password. This affects all URLs.\n" - " Default: ARIA2USER@") << endl; - cout << _(" --ftp-type=TYPE Set FTP transfer type. TYPE is either 'binary'\n" - " or 'ascii'.\n" - " Default: binary") << endl; - cout << _(" -p, --ftp-pasv Use passive mode in FTP.") << endl; - cout << _(" --ftp-via-http-proxy=METHOD Use HTTP proxy in FTP. METHOD is either 'get' or\n" - " 'tunnel'.\n" - " Default: tunnel") << endl; - cout << _(" --lowest-speed-limit=SPEED Close connection if download speed is lower than\n" - " or equal to this value(bytes per sec).\n" - " 0 means aria2 does not have a lowest speed limit.\n" - " You can append K or M(1K = 1024, 1M = 1024K).\n" - " This option does not affect BitTorrent downloads.\n" - " Default: 0") << endl; - cout << _(" --max-download-limit=SPEED Set max download speed in bytes per sec.\n" - " 0 means unrestricted.\n" - " You can append K or M(1K = 1024, 1M = 1024K).\n" - " Default: 0") << endl; - cout << _(" --file-allocation=METHOD Specify file allocation method. METHOD is either\n" - " 'none' or 'prealloc'. 'none' doesn't pre-allocate\n" - " file space. 'prealloc' pre-allocates file space\n" - " before download begins. This may take some time\n" - " depending on the size of the file.\n" - " Default: prealloc") << endl; - cout << _(" --no-file-allocation-limit=SIZE No file allocation is made for files whose\n" - " size is smaller than SIZE.\n" - " You can append K or M(1K = 1024, 1M = 1024K).") << "\n" - << DEFAULT_MSG << "5M" << "\n"; -#ifdef ENABLE_DIRECT_IO - cout << _(" --enable-direct-io[=true|false] Enable directI/O, which lowers cpu usage while\n" - " allocating files.\n" - " Turn off if you encounter any error") << "\n" - << DEFAULT_MSG << "false" << "\n"; -#endif // ENABLE_DIRECT_IO - cout << _(" --allow-overwrite=true|false If false, aria2 doesn't download a file which\n" - " already exists but the corresponding .aria2 file\n" - " doesn't exist.\n" - " Default: false") << endl; - cout << _(" --allow-piece-length-change=true|false If false is given, aria2 aborts download\n" - " when a piece length is different from one in\n" - " a control file. If true is given, you can proceed\n" - " but some download progress will be lost.") << "\n" - << DEFAULT_MSG << "false" << "\n"; - cout << _(" -Z, --force-sequential[=true|false] Fetch URIs in the command-line sequentially\n" - " and download each URI in a separate session, like\n" - " the usual command-line download utilities.\n" - " Default: false") << endl; - cout << _(" --auto-file-renaming[=true|false] Rename file name if the same file already\n" - " exists. This option works only in http(s)/ftp\n" - " download.\n" - " The new file name has a dot and a number(1..9999)\n" - " appended.\n" - " Default: true") << endl; - cout << _(" -P, --parameterized-uri[=true|false] Enable parameterized URI support.\n" - " You can specify set of parts:\n" - " http://{sv1,sv2,sv3}/foo.iso\n" - " Also you can specify numeric sequences with step\n" - " counter:\n" - " http://host/image[000-100:2].img\n" - " A step counter can be omitted.\n" - " If all URIs do not point to the same file, such\n" - " as the second example above, -Z option is\n" - " required.\n" - " Default: false") << endl; - cout << _(" --enable-http-keep-alive[=true|false] Enable HTTP/1.1 persistent connection.\n" - " Default: false") << endl; - cout << _(" --enable-http-pipelining[=true|false] Enable HTTP/1.1 pipelining.\n" - " Default: false") << endl; -#ifdef ENABLE_MESSAGE_DIGEST - cout << _(" --check-integrity=true|false Check file integrity by validating piece hash.\n" - " This option only affects in BitTorrent downloads\n" - " and Metalink downloads with chunk checksums.\n" - " Use this option to re-download a damaged portion\n" - " of a file.\n" - " Default: false") << endl; - cout << _(" --realtime-chunk-checksum=true|false Validate chunk checksum while\n" - " downloading a file in Metalink mode. This option\n" - " on affects Metalink mode with chunk checksums.\n" - " Default: true") << endl; -#endif // ENABLE_MESSAGE_DIGEST - cout << _(" -c, --continue Continue downloading a partially downloaded\n" - " file. Use this option to resume a download\n" - " started by a web browser or another program\n" - " which downloads files sequentially from the\n" - " beginning. Currently this option is only\n" - " applicable to http(s)/ftp downloads.") << endl; - cout << _(" -U, --user-agent=USER_AGENT Set user agent for http(s) downloads.") << endl; - cout << _(" -n, --no-netrc Disables netrc support.") << endl; - cout << _(" -i, --input-file=FILE Downloads URIs found in FILE. You can specify\n" - " multiple URIs for a single entity: separate\n" - " URIs on a single line using the TAB character.\n" - " Reads input from stdin when '-' is specified.") << endl; - cout << _(" -j, --max-concurrent-downloads=N Set maximum number of concurrent downloads.\n" - " It should be used with the -i option.\n" - " Default: 5") << endl; - cout << _(" --load-cookies=FILE Load cookies from FILE. The format of FILE is\n" - " the same used by Netscape and Mozilla.") << endl; -#if defined ENABLE_BITTORRENT || ENABLE_METALINK - cout << _(" -S, --show-files Print file listing of .torrent or .metalink file\n" - " and exit. More detailed information will be listed\n" - " in case of torrent file.") << endl; - cout << _(" --select-file=INDEX... Set file to download by specifing its index.\n" - " You can find the file index using the\n" - " --show-files option. Multiple indexes can be\n" - " specified by using ',', for example: \"3,6\".\n" - " You can also use '-' to specify a range: \"1-5\".\n" - " ',' and '-' can be used together.\n" - " When used with the -M option, index may vary\n" - " depending on the query(see --metalink-* options).") << endl; -#endif // ENABLE_BITTORRENT || ENABLE_METALINK -#ifdef ENABLE_BITTORRENT - cout << _(" -T, --torrent-file=TORRENT_FILE The path to the .torrent file.") << endl; - cout << _(" --follow-torrent=true|false|mem If true or mem is specified, when a file\n" - " whose suffix is .torrent or content type is\n" - " application/x-bittorrent is downloaded, aria2\n" - " parses it as a torrent file and downloads files\n" - " mentioned in it.\n" - " If mem is specified, a torrent file is not\n" - " written to the disk, but is just kept in memory.\n" - " If false is specified, the action mentioned above\n" - " is not taken.") << "\n" - << DEFAULT_MSG << "true" << "\n"; - cout << _(" --direct-file-mapping=true|false Directly read from and write to each file\n" - " mentioned in .torrent file.\n" - " Default: true") << endl; - cout << _(" --listen-port=PORT... Set TCP port number for BitTorrent downloads.\n" - " Multiple ports can be specified by using ',',\n" - " for example: \"6881,6885\". You can also use '-'\n" - " to specify a range: \"6881-6999\". ',' and '-' can\n" - " be used together.") << "\n" - << DEFAULT_MSG << "6881-6999" << "\n"; - cout << _(" --max-upload-limit=SPEED Set max upload speed in bytes per sec.\n" - " 0 means unrestricted.\n" - " You can append K or M(1K = 1024, 1M = 1024K).\n" - " Default: 0") << endl; - cout << _(" --seed-time=MINUTES Specify seeding time in minutes. Also see the\n" - " --seed-ratio option.") << endl; - cout << _(" --seed-ratio=RATIO Specify share ratio. Seed completed torrents\n" - " until share ratio reaches RATIO. 1.0 is\n" - " encouraged. Specify 0.0 if you intend to do\n" - " seeding regardless of share ratio.\n" - " If --seed-time option is specified along with\n" - " this option, seeding ends when at least one of\n" - " the conditions is satisfied.") << "\n" - << DEFAULT_MSG << "1.0" << "\n"; - cout << _(" --peer-id-prefix=PEERI_ID_PREFIX Specify the prefix of peer ID. The peer ID in\n" - " BitTorrent is 20 byte length. If more than 20\n" - " bytes are specified, only first 20\n" - " bytes are used. If less than 20 bytes are\n" - " specified, the random alphabet characters are\n" - " added to make it's length 20 bytes.\n" - " Default: -aria2-") << endl; -#endif // ENABLE_BITTORRENT -#ifdef ENABLE_METALINK - cout << _(" -M, --metalink-file=METALINK_FILE The file path to the .metalink file.") << endl; - cout << _(" -C, --metalink-servers=NUM_SERVERS The number of servers to connect to\n" - " simultaneously.\n" - " Default: 5") << endl; - cout << _(" --metalink-version=VERSION The version of the file to download.") << endl; - cout << _(" --metalink-language=LANGUAGE The language of the file to download.") << endl; - cout << _(" --metalink-os=OS The operating system of the file to download.") << endl; - cout << _(" --metalink-location=LOCATION[,...] The location of the preferred server.\n" - " A comma-deliminated list of locations is\n" - " acceptable.") << endl; - cout << _(" --metalink-preferred-protocol=PROTO Specify preferred protocol. The possible\n" - " values are 'http', 'https', 'ftp' and 'none'.\n" - " Specifiy none to disable this feature.") << "\n" - << DEFAULT_MSG << "none" << "\n"; - cout << _(" --follow-metalink=true|false|mem If true or mem is specified, when a file\n" - " whose suffix is .metaink or content type is\n" - " application/metalink+xml is downloaded, aria2\n" - " parses it as a metalink file and downloads files\n" - " mentioned in it.\n" - " If mem is specified, a metalink file is not\n" - " written to the disk, but is just kept in memory.\n" - " If false is specified, the action mentioned above\n" - " is not taken.") << "\n" - << DEFAULT_MSG << "true" << "\n"; - cout << _(" --metalink-enable-unique-protocol=true|false If true is given and several\n" - " protocols are available for a mirror in a metalink\n" - " file, aria2 uses one of them.\n" - " Use --metalink-preferred-protocol option to\n" - " specify the preference of protocol.") << "\n" - << DEFAULT_MSG << "true" << "\n"; -#endif // ENABLE_METALINK - cout << _(" -v, --version Print the version number and exit.") << endl; - cout << _(" -h, --help Print this message and exit.") << endl; - cout << endl; - cout << "URL:" << endl; - cout << _(" You can specify multiple URLs. Unless you specify -Z option, all URLs must\n" - " point to the same file or downloading will fail.") << endl; - cout << _(" You can specify both torrent file with -T option and URLs. By doing this,\n" - " download a file from both torrent swarm and http/ftp server at the same time,\n" - " while the data from http/ftp are uploaded to the torrent swarm. Note that\n" - " only single file torrent can be integrated with http/ftp.") << endl; - cout << "\n" - << _(" Make sure that URL is quoted with single(\') or double(\") quotation if it\n" - " contains \"&\" or any characters that have special meaning in shell.") << "\n"; - cout << endl; + TagContainerHandle tc = HelpItemFactory::createHelpItems(); + TaggedItems items = category == V_ALL ? tc->getAllItems() : tc->search(category); + if(items.size() > 0) { + if(category == V_ALL) { + printf(_("Printing all options.")); + } else { + printf(_("Printing options tagged with '%s'."), category.c_str()); + } + cout << "\n"; + cout << _("Options:") << endl; + copy(items.begin(), items.end(), ostream_iterator(cout, "\n")); + } else { + TaggedItems items = tc->nameMatchForward(category); + if(items.size() > 0) { + printf(_("Printing options whose name starts with '%s'."), category.c_str()); + cout << "\n"; + cout << _("Options:") << endl; + copy(items.begin(), items.end(), ostream_iterator(cout, "\n")); + } else { + printf(_("No help category or option name matching with '%s'."), category.c_str()); + cout << "\n"; + cout << HelpItemHandle(tc->nameMatchForward("help").front()) << "\n"; + } + } + if(category == TAG_BASIC) { + cout << "\n" + << "URL:" << "\n" + << _(" You can specify multiple URLs. Unless you specify -Z option, all URLs must\n" + " point to the same file or downloading will fail.") << "\n" + << _(" You can specify both torrent file with -T option and URLs. By doing this,\n" + " download a file from both torrent swarm and http/ftp server at the same time,\n" + " while the data from http/ftp are uploaded to the torrent swarm. Note that\n" + " only single file torrent can be integrated with http/ftp.") << "\n" + << "\n" + << _(" Make sure that URL is quoted with single(\') or double(\") quotation if it\n" + " contains \"&\" or any characters that have special meaning in shell.") << "\n"; + } + cout << "\n"; cout << _("Refer to man page for more information.") << endl; - cout << endl; - printf(_("Report bugs to %s"), ""); - cout << endl; } diff --git a/test/HelpItemTest.cc b/test/HelpItemTest.cc new file mode 100644 index 00000000..7f7fefa9 --- /dev/null +++ b/test/HelpItemTest.cc @@ -0,0 +1,39 @@ +#include "HelpItem.h" +#include +#include + +class HelpItemTest:public CppUnit::TestFixture { + + CPPUNIT_TEST_SUITE(HelpItemTest); + CPPUNIT_TEST(testOperatorStreamOut); + CPPUNIT_TEST_SUITE_END(); +private: + +public: + void setUp() {} + + void testOperatorStreamOut(); +}; + + +CPPUNIT_TEST_SUITE_REGISTRATION(HelpItemTest); + +void HelpItemTest::testOperatorStreamOut() +{ + string usage = + " -m, --max-tries=N Set number of tries. 0 means unlimited."; + HelpItem item("max-tries", usage, "5"); + item.setAvailableValues("0,5,10"); + item.addTag("basic"); + item.addTag("http"); + item.addTag("ftp"); + + stringstream s; + s << item; + + CPPUNIT_ASSERT_EQUAL(usage+"\n"+ + " Available Values: 0,5,10\n" + " Default: 5\n" + " Tags: basic,http,ftp", + s.str()); +} diff --git a/test/Makefile.am b/test/Makefile.am index 61ecb2f2..a240c087 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1,6 +1,9 @@ TESTS = aria2c check_PROGRAMS = $(TESTS) aria2c_SOURCES = AllTest.cc\ + HelpItemTest.cc\ + TaggedItemTest.cc\ + TagContainerTest.cc\ Base64Test.cc\ SequenceTest.cc\ a2functionalTest.cc\ diff --git a/test/Makefile.in b/test/Makefile.in index b2e97ecf..0c1a9e18 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -121,7 +121,8 @@ mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = am__EXEEXT_1 = aria2c$(EXEEXT) -am__aria2c_SOURCES_DIST = AllTest.cc Base64Test.cc SequenceTest.cc \ +am__aria2c_SOURCES_DIST = AllTest.cc HelpItemTest.cc TaggedItemTest.cc \ + TagContainerTest.cc Base64Test.cc SequenceTest.cc \ a2functionalTest.cc FileEntryTest.cc PieceTest.cc \ SegmentTest.cc GrowSegmentTest.cc \ SingleFileAllocationIteratorTest.cc \ @@ -226,10 +227,12 @@ am__aria2c_SOURCES_DIST = AllTest.cc Base64Test.cc SequenceTest.cc \ @ENABLE_METALINK_TRUE@ MetalinkHelperTest.$(OBJEXT) \ @ENABLE_METALINK_TRUE@ MetalinkParserControllerTest.$(OBJEXT) \ @ENABLE_METALINK_TRUE@ MetalinkProcessorTest.$(OBJEXT) -am_aria2c_OBJECTS = AllTest.$(OBJEXT) Base64Test.$(OBJEXT) \ - SequenceTest.$(OBJEXT) a2functionalTest.$(OBJEXT) \ - FileEntryTest.$(OBJEXT) PieceTest.$(OBJEXT) \ - SegmentTest.$(OBJEXT) GrowSegmentTest.$(OBJEXT) \ +am_aria2c_OBJECTS = AllTest.$(OBJEXT) HelpItemTest.$(OBJEXT) \ + TaggedItemTest.$(OBJEXT) TagContainerTest.$(OBJEXT) \ + Base64Test.$(OBJEXT) SequenceTest.$(OBJEXT) \ + a2functionalTest.$(OBJEXT) FileEntryTest.$(OBJEXT) \ + PieceTest.$(OBJEXT) SegmentTest.$(OBJEXT) \ + GrowSegmentTest.$(OBJEXT) \ SingleFileAllocationIteratorTest.$(OBJEXT) \ DefaultBtProgressInfoFileTest.$(OBJEXT) \ SingleFileDownloadContextTest.$(OBJEXT) \ @@ -445,7 +448,8 @@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ TESTS = aria2c -aria2c_SOURCES = AllTest.cc Base64Test.cc SequenceTest.cc \ +aria2c_SOURCES = AllTest.cc HelpItemTest.cc TaggedItemTest.cc \ + TagContainerTest.cc Base64Test.cc SequenceTest.cc \ a2functionalTest.cc FileEntryTest.cc PieceTest.cc \ SegmentTest.cc GrowSegmentTest.cc \ SingleFileAllocationIteratorTest.cc \ @@ -582,6 +586,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FileUriListParserTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GrowSegmentTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HandshakeExtensionMessageTest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HelpItemTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpHeaderProcessorTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpHeaderTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpRequestTest.Po@am__quote@ @@ -623,6 +628,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SingletonHolderTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SpeedCalcTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StreamUriListParserTest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TagContainerTest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TaggedItemTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TimeSeedCriteriaTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UTPexExtensionMessageTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UtilTest.Po@am__quote@ diff --git a/test/TagContainerTest.cc b/test/TagContainerTest.cc new file mode 100644 index 00000000..116887c6 --- /dev/null +++ b/test/TagContainerTest.cc @@ -0,0 +1,49 @@ +#include "TagContainer.h" +#include "TaggedItem.h" +#include + +using namespace std; + +class TagContainerTest:public CppUnit::TestFixture { + + CPPUNIT_TEST_SUITE(TagContainerTest); + CPPUNIT_TEST(testSearch); + CPPUNIT_TEST_SUITE_END(); +private: + +public: + void setUp() {} + + void testSearch(); +}; + + +CPPUNIT_TEST_SUITE_REGISTRATION(TagContainerTest); + +void TagContainerTest::testSearch() +{ + TaggedItemHandle items[] = { + new TaggedItem("alpha"), + new TaggedItem("bravo"), + new TaggedItem("charlie"), + }; + items[0]->addTag("foo"); + items[1]->addTag("foo"); + items[1]->addTag("bar"); + items[2]->addTag("foo"); + + TagContainer tc(TaggedItems(&items[0], &items[3])); + + { + TaggedItems res = tc.search("bar"); + CPPUNIT_ASSERT_EQUAL((size_t)1, res.size()); + CPPUNIT_ASSERT_EQUAL(string("bravo"), res[0]->getName()); + CPPUNIT_ASSERT_EQUAL(string("foo,bar"), res[0]->toTagString()); + } + { + TaggedItems res = tc.nameMatchForward("ch"); + CPPUNIT_ASSERT_EQUAL((size_t)1, res.size()); + CPPUNIT_ASSERT_EQUAL(string("charlie"), res[0]->getName()); + CPPUNIT_ASSERT_EQUAL(string("foo"), res[0]->toTagString()); + } +} diff --git a/test/TaggedItemTest.cc b/test/TaggedItemTest.cc new file mode 100644 index 00000000..68e164f2 --- /dev/null +++ b/test/TaggedItemTest.cc @@ -0,0 +1,39 @@ +#include "TaggedItem.h" +#include + +class TaggedItemTest:public CppUnit::TestFixture { + + CPPUNIT_TEST_SUITE(TaggedItemTest); + CPPUNIT_TEST(testHasTag); + CPPUNIT_TEST(testToTagString); + CPPUNIT_TEST_SUITE_END(); +private: + +public: + void setUp() {} + + void testHasTag(); + void testToTagString(); +}; + + +CPPUNIT_TEST_SUITE_REGISTRATION(TaggedItemTest); + +void TaggedItemTest::testHasTag() +{ + TaggedItem item("alpha"); + item.addTag("foo"); + item.addTag("bar"); + + CPPUNIT_ASSERT(item.hasTag("bar")); + CPPUNIT_ASSERT(!item.hasTag("boo")); +} + +void TaggedItemTest::testToTagString() +{ + TaggedItem item("alpha"); + item.addTag("foo"); + item.addTag("bar"); + + CPPUNIT_ASSERT_EQUAL(string("foo,bar"), item.toTagString()); +}