浏览代码

2008-01-05 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

	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
Tatsuhiro Tsujikawa 18 年之前
父节点
当前提交
fce7b4b32f
共有 23 个文件被更改,包括 1481 次插入278 次删除
  1. 17 0
      ChangeLog
  2. 5 3
      po/POTFILES
  3. 4 2
      po/POTFILES.in
  4. 58 0
      src/HelpItem.cc
  5. 69 0
      src/HelpItem.h
  6. 395 0
      src/HelpItemFactory.cc
  7. 50 0
      src/HelpItemFactory.h
  8. 5 1
      src/Makefile.am
  9. 18 11
      src/Makefile.in
  10. 106 0
      src/TagContainer.cc
  11. 64 0
      src/TagContainer.h
  12. 67 0
      src/TaggedItem.cc
  13. 69 0
      src/TaggedItem.h
  14. 45 0
      src/help_tags.h
  15. 14 5
      src/option_processing.cc
  16. 1 0
      src/prefs.h
  17. 302 0
      src/usage_text.h
  18. 49 250
      src/version_usage.cc
  19. 39 0
      test/HelpItemTest.cc
  20. 3 0
      test/Makefile.am
  21. 13 6
      test/Makefile.in
  22. 49 0
      test/TagContainerTest.cc
  23. 39 0
      test/TaggedItemTest.cc

+ 17 - 0
ChangeLog

@@ -1,3 +1,20 @@
+2008-01-05  Tatsuhiro Tsujikawa  <tujikawa at rednoah dot com>
+
+	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  <tujikawa at rednoah dot com>
 
 	Fixed segmentation fault when bad torrent metainfo is parsed.

+ 5 - 3
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

+ 4 - 2
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

+ 58 - 0
src/HelpItem.cc

@@ -0,0 +1,58 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL.  If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so.  If you
+ * do not wish to do so, delete this exception statement from your
+ * version.  If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#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;
+}

+ 69 - 0
src/HelpItem.h

@@ -0,0 +1,69 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL.  If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so.  If you
+ * do not wish to do so, delete this exception statement from your
+ * version.  If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_HELP_ITEM_H_
+#define _D_HELP_ITEM_H_
+
+#include "TaggedItem.h"
+
+class HelpItem;
+typedef SharedHandle<HelpItem> 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_

+ 395 - 0
src/HelpItemFactory.cc

@@ -0,0 +1,395 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL.  If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so.  If you
+ * do not wish to do so, delete this exception statement from your
+ * version.  If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#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;
+}

+ 50 - 0
src/HelpItemFactory.h

@@ -0,0 +1,50 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL.  If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so.  If you
+ * do not wish to do so, delete this exception statement from your
+ * version.  If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_HELP_ITEM_FACTORY_H_
+#define _D_HELP_ITEM_FACTORY_H_
+
+#include "common.h"
+
+class TagContainer;
+typedef SharedHandle<TagContainer> TagContainerHandle;
+
+class HelpItemFactory {
+private:
+  HelpItemFactory();
+public:
+  static TagContainerHandle createHelpItems();
+};
+
+#endif // _D_HELP_ITEM_FACTORY_H_

+ 5 - 1
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

+ 18 - 11
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@

+ 106 - 0
src/TagContainer.cc

@@ -0,0 +1,106 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL.  If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so.  If you
+ * do not wish to do so, delete this exception statement from your
+ * version.  If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#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);
+}

+ 64 - 0
src/TagContainer.h

@@ -0,0 +1,64 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL.  If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so.  If you
+ * do not wish to do so, delete this exception statement from your
+ * version.  If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_TAG_CONTAINER_H_
+#define _D_TAG_CONTAINER_H_
+
+#include "common.h"
+
+class TaggedItem;
+typedef SharedHandle<TaggedItem> TaggedItemHandle;
+typedef deque<TaggedItemHandle> 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<TagContainer> TagContainerHandle;
+#endif // _D_TAG_CONTAINER_H_

+ 67 - 0
src/TaggedItem.cc

@@ -0,0 +1,67 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL.  If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so.  If you
+ * do not wish to do so, delete this exception statement from your
+ * version.  If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#include "TaggedItem.h"
+#include <numeric>
+
+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;
+}

+ 69 - 0
src/TaggedItem.h

@@ -0,0 +1,69 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL.  If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so.  If you
+ * do not wish to do so, delete this exception statement from your
+ * version.  If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#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<TaggedItem> TaggedItemHandle;
+typedef deque<TaggedItemHandle> TaggedItems;
+#endif // _D_TAGGED_ITEM_H_

+ 45 - 0
src/help_tags.h

@@ -0,0 +1,45 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL.  If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so.  If you
+ * do not wish to do so, delete this exception statement from your
+ * version.  If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#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_

+ 14 - 5
src/option_processing.cc

@@ -41,6 +41,7 @@
 #include "message.h"
 #include "Exception.h"
 #include "a2io.h"
+#include "help_tags.h"
 #include <fstream>
 #include <sstream>
 
@@ -49,7 +50,7 @@ extern int optind, opterr, optopt;
 #include <getopt.h>
 
 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);
     }

+ 1 - 0
src/prefs.h

@@ -47,6 +47,7 @@
 #undef V_NONE
 #define V_NONE "none"
 #define V_MEM "mem"
+#define V_ALL "all"
 /**
  * General preferences
  */

+ 302 - 0
src/usage_text.h

@@ -0,0 +1,302 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL.  If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so.  If you
+ * do not wish to do so, delete this exception statement from your
+ * version.  If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+
+#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.")

+ 49 - 250
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 <iterator>
 
 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 <tujikawa at users dot sourceforge dot net>"
-       << endl;
+       << "\n";
+    printf(_("Report bugs to %s"), "<tujikawa at users dot sourceforge dot net>");
+    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<HelpItemHandle>(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<HelpItemHandle>(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"), "<tujikawa at users dot sourceforge dot net>");
-  cout << endl;
 }

+ 39 - 0
test/HelpItemTest.cc

@@ -0,0 +1,39 @@
+#include "HelpItem.h"
+#include <sstream>
+#include <cppunit/extensions/HelperMacros.h>
+
+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());
+}

+ 3 - 0
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\

+ 13 - 6
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@

+ 49 - 0
test/TagContainerTest.cc

@@ -0,0 +1,49 @@
+#include "TagContainer.h"
+#include "TaggedItem.h"
+#include <cppunit/extensions/HelperMacros.h>
+
+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());
+  }
+}

+ 39 - 0
test/TaggedItemTest.cc

@@ -0,0 +1,39 @@
+#include "TaggedItem.h"
+#include <cppunit/extensions/HelperMacros.h>
+
+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());
+}