Jelajahi Sumber

2008-09-22 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

	Integrated HelpItem into OptionParser to ease the workload for 
adding
	new options. Removed default value from usage text.
	* src/HelpItem.cc: Removed.
	* src/HelpItem.h: Removed.
	* src/HelpItemFactory.cc: Removed.
	* src/HelpItemFactory.h: Removed.
	* src/Makefile.am
	* src/Makefile.in
	* src/NameMatchOptionHandler.h
	* src/OptionHandler.cc
	* src/OptionHandler.h
	* src/OptionHandlerFactory.cc
	* src/OptionHandlerImpl.h
	* src/OptionParser.cc
	* src/OptionParser.h
	* src/TagContainer.cc: Removed.
	* src/TagContainer.h: Removed.
	* src/TaggedItem.cc: Removed.
	* src/TaggedItem.h: Removed.
	* src/main.cc
	* src/option_processing.cc
	* src/usage_text.h
	* src/version_usage.cc
	* test/HelpItemTest.cc: Removed.
	* test/Makefile.am
	* test/Makefile.in
	* test/OptionHandlerTest.cc
	* test/OptionParserTest.cc
	* test/TagContainerTest.cc: Removed.
Tatsuhiro Tsujikawa 17 tahun lalu
induk
melakukan
f66ed483fa

+ 32 - 0
ChangeLog

@@ -1,3 +1,35 @@
+2008-09-22  Tatsuhiro Tsujikawa  <tujikawa at rednoah dot com>
+
+	Integrated HelpItem into OptionParser to ease the workload for adding
+	new options. Removed default value from usage text.
+	* src/HelpItem.cc: Removed.
+	* src/HelpItem.h: Removed.
+	* src/HelpItemFactory.cc: Removed.
+	* src/HelpItemFactory.h: Removed.
+	* src/Makefile.am
+	* src/Makefile.in
+	* src/NameMatchOptionHandler.h
+	* src/OptionHandler.cc
+	* src/OptionHandler.h
+	* src/OptionHandlerFactory.cc
+	* src/OptionHandlerImpl.h
+	* src/OptionParser.cc
+	* src/OptionParser.h
+	* src/TagContainer.cc: Removed.
+	* src/TagContainer.h: Removed.
+	* src/TaggedItem.cc: Removed.
+	* src/TaggedItem.h: Removed.
+	* src/main.cc
+	* src/option_processing.cc
+	* src/usage_text.h
+	* src/version_usage.cc
+	* test/HelpItemTest.cc: Removed.
+	* test/Makefile.am
+	* test/Makefile.in
+	* test/OptionHandlerTest.cc
+	* test/OptionParserTest.cc
+	* test/TagContainerTest.cc: Removed.
+
 2008-09-19  Tatsuhiro Tsujikawa  <tujikawa at rednoah dot com>
 
 	Moved `TransferStat stat = ...' to inside the `if' clause.

+ 0 - 76
src/HelpItem.h

@@ -1,76 +0,0 @@
-/* <!-- 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"
-#include "A2STR.h"
-
-namespace aria2 {
-
-class HelpItem:public TaggedItem {
-private:
-  std::string _usageText;
-
-  std::string _availableValues;
-
-  std::string _defaultValue;
-
-public:
-  HelpItem(const std::string& name, const std::string& usageText, const std::string& defaultValue = A2STR::NIL):
-    TaggedItem(name),
-    _usageText(usageText),
-    _defaultValue(defaultValue) {}
-
-  virtual ~HelpItem() {}
-
-  void setAvailableValues(const std::string& availableValues)
-  {
-    _availableValues = availableValues;
-  }
-
-  const std::string& getAvailableValues() const
-  {
-    return _availableValues;
-  }
-
-  virtual std::string toString() const;
-};
-
-typedef SharedHandle<HelpItem> HelpItemHandle;
-
-} // namespace aria2
-
-#endif // _D_HELP_ITEM_H_

+ 0 - 576
src/HelpItemFactory.cc

@@ -1,576 +0,0 @@
-/* <!-- 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"
-#include "Option.h"
-#include "StringFormat.h"
-
-namespace aria2 {
-
-HelpItemFactory::HelpItemFactory() {}
-
-TagContainerHandle HelpItemFactory::createHelpItems(const Option* op)
-{
-  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,
-				     op->get(PREF_SPLIT)));
-    item->setAvailableValues("1-16");
-    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_CONNECT_TIMEOUT, TEXT_CONNECT_TIMEOUT,
-				     op->get(PREF_CONNECT_TIMEOUT)));
-    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,
-				     op->get(PREF_ENABLE_DIRECT_IO)));
-    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,
-				     op->get(PREF_ALLOW_PIECE_LENGTH_CHANGE)));
-    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, op->get(PREF_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, op->get(PREF_MAX_CONCURRENT_DOWNLOADS)));
-    item->addTag(TAG_BASIC);
-    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 || defined 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, op->get(PREF_FOLLOW_TORRENT)));
-    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,
-				     op->get(PREF_LISTEN_PORT)));
-    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,
-				     op->get(PREF_SEED_RATIO)));
-    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);
-  }
-  {
-    HelpItemHandle item(new HelpItem(PREF_ENABLE_PEER_EXCHANGE, TEXT_ENABLE_PEER_EXCHANGE,
-				     op->get(PREF_ENABLE_PEER_EXCHANGE)));
-    item->addTag(TAG_BITTORRENT);
-    tc->addItem(item);
-  }
-  {
-    HelpItemHandle item(new HelpItem(PREF_ENABLE_DHT, TEXT_ENABLE_DHT,
-				     op->get(PREF_ENABLE_DHT)));
-    item->addTag(TAG_BASIC);
-    item->addTag(TAG_BITTORRENT);
-    tc->addItem(item);
-  }
-  {
-    HelpItemHandle item(new HelpItem(PREF_DHT_LISTEN_PORT, TEXT_DHT_LISTEN_PORT,
-				     op->get(PREF_DHT_LISTEN_PORT)));
-    item->addTag(TAG_BASIC);
-    item->addTag(TAG_BITTORRENT);
-    tc->addItem(item);
-  }
-  {
-    HelpItemHandle item(new HelpItem(PREF_DHT_ENTRY_POINT, TEXT_DHT_ENTRY_POINT));
-    item->addTag(TAG_BITTORRENT);
-    tc->addItem(item);
-  }
-  {
-    HelpItemHandle item(new HelpItem(PREF_BT_MIN_CRYPTO_LEVEL, TEXT_BT_MIN_CRYPTO_LEVEL,
-				     op->get(PREF_BT_MIN_CRYPTO_LEVEL)));
-    item->addTag(TAG_BITTORRENT);
-    tc->addItem(item);
-  }
-  {
-    HelpItemHandle item(new HelpItem(PREF_BT_REQUIRE_CRYPTO, TEXT_BT_REQUIRE_CRYPTO,
-				     op->get(PREF_BT_REQUIRE_CRYPTO)));
-    item->addTag(TAG_BITTORRENT);
-    tc->addItem(item);
-  }
-  {
-    HelpItemHandle item(new HelpItem(PREF_BT_REQUEST_PEER_SPEED_LIMIT,
-				     TEXT_BT_REQUEST_PEER_SPEED_LIMIT,
-				     op->get(PREF_BT_REQUEST_PEER_SPEED_LIMIT)));
-    item->addTag(TAG_BITTORRENT);
-    tc->addItem(item);
-  }
-  {
-    HelpItemHandle item(new HelpItem(PREF_BT_MAX_OPEN_FILES,
-				     TEXT_BT_MAX_OPEN_FILES,
-				     op->get(PREF_BT_MAX_OPEN_FILES)));
-    item->addTag(TAG_BITTORRENT);
-    tc->addItem(item);
-  }
-  {
-    HelpItemHandle item(new HelpItem(PREF_BT_SEED_UNVERIFIED,
-				     TEXT_BT_SEED_UNVERIFIED,
-				     op->get(PREF_BT_SEED_UNVERIFIED)));
-    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, op->get(PREF_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,
-				     op->get(PREF_METALINK_PREFERRED_PROTOCOL)));
-    item->addTag(TAG_METALINK);
-    tc->addItem(item);
-  }
-  {
-    HelpItemHandle item(new HelpItem(PREF_FOLLOW_METALINK,
-				     TEXT_FOLLOW_METALINK,
-				     op->get(PREF_FOLLOW_METALINK)));
-    item->addTag(TAG_METALINK);
-    tc->addItem(item);
-  }
-  {
-    HelpItemHandle item(new HelpItem(PREF_METALINK_ENABLE_UNIQUE_PROTOCOL,
-				     TEXT_METALINK_ENABLE_UNIQUE_PROTOCOL,
-				     op->get(PREF_METALINK_ENABLE_UNIQUE_PROTOCOL)));
-    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(PREF_NO_CONF, TEXT_NO_CONF));
-    item->addTag(TAG_ADVANCED);
-    tc->addItem(item);
-  }
-  {
-    HelpItemHandle item(new HelpItem(PREF_CONF_PATH, TEXT_CONF_PATH, "$HOME/.aria2/aria2.conf"));
-    item->addTag(TAG_ADVANCED);
-    tc->addItem(item);
-  }
-  {
-    HelpItemHandle item(new HelpItem(PREF_STOP, TEXT_STOP, op->get(PREF_STOP)));
-    item->addTag(TAG_ADVANCED);
-    tc->addItem(item);
-  }
-  {
-    HelpItemHandle item(new HelpItem(PREF_HEADER, TEXT_HEADER));
-    item->addTag(TAG_HTTP);
-    tc->addItem(item);
-  }
-  {
-    HelpItemHandle item(new HelpItem(PREF_QUIET, TEXT_QUIET, V_FALSE));
-    item->addTag(TAG_ADVANCED);
-    tc->addItem(item);
-  }
-#ifdef ENABLE_ASYNC_DNS
-  {
-    HelpItemHandle item(new HelpItem(PREF_ASYNC_DNS, TEXT_ASYNC_DNS, op->get(PREF_ASYNC_DNS)));
-    item->addTag(TAG_ADVANCED);
-    tc->addItem(item);
-  }
-#endif // ENABLE_ASYNC_DNS
-  {
-    HelpItemHandle item(new HelpItem(PREF_FTP_REUSE_CONNECTION, TEXT_FTP_REUSE_CONNECTION, op->get(PREF_FTP_REUSE_CONNECTION)));
-    item->addTag(TAG_FTP);
-    tc->addItem(item);
-  }
-  {
-    HelpItemHandle item(new HelpItem(PREF_SUMMARY_INTERVAL,
-				     TEXT_SUMMARY_INTERVAL,
-				     op->get(PREF_SUMMARY_INTERVAL)));
-    item->addTag(TAG_ADVANCED);
-    tc->addItem(item);
-  }
-  {
-    HelpItemHandle item(new HelpItem(PREF_LOG_LEVEL,
-				     TEXT_LOG_LEVEL,
-				     op->get(PREF_LOG_LEVEL)));
-    item->addTag(TAG_ADVANCED);
-    item->setAvailableValues
-      (StringFormat("%s,%s,%s,%s,%s",
-		    V_DEBUG.c_str(), V_INFO.c_str(), V_NOTICE.c_str(),
-		    V_WARN.c_str(), V_ERROR.c_str()).str());
-    tc->addItem(item);
-  }
-  {
-    HelpItemHandle item(new HelpItem(PREF_REMOTE_TIME, TEXT_REMOTE_TIME,
-				     op->get(PREF_REMOTE_TIME)));
-    item->addTag(TAG_HTTP);
-    item->addTag(TAG_FTP);
-    item->addTag(TAG_ADVANCED);
-    tc->addItem(item);
-  }
-  {
-    HelpItemHandle item(new HelpItem(PREF_MAX_FILE_NOT_FOUND,
-				     TEXT_MAX_FILE_NOT_FOUND,
-				     op->get(PREF_MAX_FILE_NOT_FOUND)));
-    item->addTag(TAG_HTTP);
-    item->addTag(TAG_FTP);
-    tc->addItem(item);	     
-  }
-  {
-    HelpItemHandle item(new HelpItem(PREF_URI_SELECTOR, TEXT_URI_SELECTOR,
-				     op->get(PREF_URI_SELECTOR)));
-    item->addTag(TAG_HTTP);
-    item->addTag(TAG_FTP);
-    item->setAvailableValues(V_INORDER+","+V_FEEDBACK);
-    tc->addItem(item);
-  }
-  {
-    HelpItemHandle item(new HelpItem(PREF_SERVER_STAT_OF, TEXT_SERVER_STAT_OF));
-    item->addTag(TAG_HTTP);
-    item->addTag(TAG_FTP);
-    tc->addItem(item);
-  }
-  {
-    HelpItemHandle item(new HelpItem(PREF_SERVER_STAT_IF, TEXT_SERVER_STAT_IF));
-    item->addTag(TAG_HTTP);
-    item->addTag(TAG_FTP);
-    tc->addItem(item);
-  }
-  {
-    HelpItemHandle item(new HelpItem(PREF_SERVER_STAT_TIMEOUT,
-				     TEXT_SERVER_STAT_TIMEOUT,
-				     "86400 (24hours)"));
-    item->addTag(TAG_HTTP);
-    item->addTag(TAG_FTP);
-    tc->addItem(item);
-  }
-  {
-    HelpItemHandle item(new HelpItem("help", TEXT_HELP, TAG_BASIC));
-    item->setAvailableValues
-      (StringFormat("%s,%s,%s,%s,%s,%s,%s,all", TAG_BASIC, TAG_ADVANCED, TAG_HTTP, TAG_FTP, TAG_METALINK, TAG_BITTORRENT,TAG_HELP).str());
-    item->addTag(TAG_BASIC);
-    item->addTag(TAG_HELP);
-    tc->addItem(item);
-  }
-  return tc;
-}
-
-} // namespace aria2

+ 0 - 55
src/HelpItemFactory.h

@@ -1,55 +0,0 @@
-/* <!-- 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"
-#include "SharedHandle.h"
-
-namespace aria2 {
-
-class TagContainer;
-class Option;
-
-class HelpItemFactory {
-private:
-  HelpItemFactory();
-public:
-  static SharedHandle<TagContainer> createHelpItems(const Option* option);
-};
-
-} // namespace aria2
-
-#endif // _D_HELP_ITEM_FACTORY_H_

+ 2 - 6
src/Makefile.am

@@ -76,7 +76,7 @@ SRCS =  Socket.h\
 	AuthConfigFactory.cc AuthConfigFactory.h\
 	OptionParser.cc OptionParser.h\
 	OptionHandlerFactory.cc OptionHandlerFactory.h\
-	OptionHandler.h\
+	OptionHandler.cc OptionHandler.h\
 	OptionHandlerImpl.h\
 	NameMatchOptionHandler.h\
 	NameResolver.cc NameResolver.h\
@@ -152,10 +152,6 @@ SRCS =  Socket.h\
 	ByteArrayDiskWriter.cc ByteArrayDiskWriter.h\
 	ByteArrayDiskWriterFactory.cc ByteArrayDiskWriterFactory.h\
 	ServerHost.cc ServerHost.h\
-	HelpItem.cc HelpItem.h\
-	TaggedItem.cc TaggedItem.h\
-	TagContainer.cc TagContainer.h\
-	HelpItemFactory.cc HelpItemFactory.h\
 	DownloadContext.cc DownloadContext.h\
 	SingleFileDownloadContext.cc SingleFileDownloadContext.h\
 	TimedHaltCommand.cc TimedHaltCommand.h\
@@ -486,4 +482,4 @@ AM_CPPFLAGS =  -Wall\
 	@LIBGNUTLS_CFLAGS@ @LIBGCRYPT_CFLAGS@ @OPENSSL_CFLAGS@ @XML_CPPFLAGS@\
 	@LIBARES_CPPFLAGS@ @LIBCARES_CPPFLAGS@ @LIBEXPAT_CPPFLAGS@\
 	@LIBZ_CPPFLAGS@	 @SQLITE3_CPPFLAGS@\
-	-DLOCALEDIR=\"$(localedir)\" @DEFS@ #-pg
+	-DLOCALEDIR=\"$(localedir)\" @DEFS@ #-pg

+ 23 - 29
src/Makefile.in

@@ -339,11 +339,12 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
 	DefaultAuthResolver.cc DefaultAuthResolver.h \
 	NetrcAuthResolver.cc NetrcAuthResolver.h AuthConfigFactory.cc \
 	AuthConfigFactory.h OptionParser.cc OptionParser.h \
-	OptionHandlerFactory.cc OptionHandlerFactory.h OptionHandler.h \
-	OptionHandlerImpl.h NameMatchOptionHandler.h NameResolver.cc \
-	NameResolver.h RequestGroup.cc RequestGroup.h \
-	RequestGroupAware.cc RequestGroupAware.h RequestGroupMan.cc \
-	RequestGroupMan.h FileAllocationMan.cc FileAllocationMan.h \
+	OptionHandlerFactory.cc OptionHandlerFactory.h \
+	OptionHandler.cc OptionHandler.h OptionHandlerImpl.h \
+	NameMatchOptionHandler.h NameResolver.cc NameResolver.h \
+	RequestGroup.cc RequestGroup.h RequestGroupAware.cc \
+	RequestGroupAware.h RequestGroupMan.cc RequestGroupMan.h \
+	FileAllocationMan.cc FileAllocationMan.h \
 	FileAllocationCommand.cc FileAllocationCommand.h \
 	FillRequestGroupCommand.cc FillRequestGroupCommand.h \
 	FileAllocationDispatcherCommand.cc \
@@ -392,9 +393,7 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
 	MultiFileAllocationIterator.h PeerConnection.cc \
 	PeerConnection.h ByteArrayDiskWriter.cc ByteArrayDiskWriter.h \
 	ByteArrayDiskWriterFactory.cc ByteArrayDiskWriterFactory.h \
-	ServerHost.cc ServerHost.h HelpItem.cc HelpItem.h \
-	TaggedItem.cc TaggedItem.h TagContainer.cc TagContainer.h \
-	HelpItemFactory.cc HelpItemFactory.h DownloadContext.cc \
+	ServerHost.cc ServerHost.h DownloadContext.cc \
 	DownloadContext.h SingleFileDownloadContext.cc \
 	SingleFileDownloadContext.h TimedHaltCommand.cc \
 	TimedHaltCommand.h CUIDCounter.h DNSCache.h DownloadResult.h \
@@ -764,10 +763,10 @@ am__objects_18 = SocketCore.$(OBJEXT) Command.$(OBJEXT) \
 	AuthConfig.$(OBJEXT) AbstractAuthResolver.$(OBJEXT) \
 	DefaultAuthResolver.$(OBJEXT) NetrcAuthResolver.$(OBJEXT) \
 	AuthConfigFactory.$(OBJEXT) OptionParser.$(OBJEXT) \
-	OptionHandlerFactory.$(OBJEXT) NameResolver.$(OBJEXT) \
-	RequestGroup.$(OBJEXT) RequestGroupAware.$(OBJEXT) \
-	RequestGroupMan.$(OBJEXT) FileAllocationMan.$(OBJEXT) \
-	FileAllocationCommand.$(OBJEXT) \
+	OptionHandlerFactory.$(OBJEXT) OptionHandler.$(OBJEXT) \
+	NameResolver.$(OBJEXT) RequestGroup.$(OBJEXT) \
+	RequestGroupAware.$(OBJEXT) RequestGroupMan.$(OBJEXT) \
+	FileAllocationMan.$(OBJEXT) FileAllocationCommand.$(OBJEXT) \
 	FillRequestGroupCommand.$(OBJEXT) \
 	FileAllocationDispatcherCommand.$(OBJEXT) \
 	FileAllocationEntry.$(OBJEXT) \
@@ -797,11 +796,10 @@ am__objects_18 = SocketCore.$(OBJEXT) Command.$(OBJEXT) \
 	BtRegistry.$(OBJEXT) MultiFileAllocationIterator.$(OBJEXT) \
 	PeerConnection.$(OBJEXT) ByteArrayDiskWriter.$(OBJEXT) \
 	ByteArrayDiskWriterFactory.$(OBJEXT) ServerHost.$(OBJEXT) \
-	HelpItem.$(OBJEXT) TaggedItem.$(OBJEXT) TagContainer.$(OBJEXT) \
-	HelpItemFactory.$(OBJEXT) DownloadContext.$(OBJEXT) \
-	SingleFileDownloadContext.$(OBJEXT) TimedHaltCommand.$(OBJEXT) \
-	prefs.$(OBJEXT) ProtocolDetector.$(OBJEXT) \
-	StringFormat.$(OBJEXT) HttpSkipResponseCommand.$(OBJEXT) \
+	DownloadContext.$(OBJEXT) SingleFileDownloadContext.$(OBJEXT) \
+	TimedHaltCommand.$(OBJEXT) prefs.$(OBJEXT) \
+	ProtocolDetector.$(OBJEXT) StringFormat.$(OBJEXT) \
+	HttpSkipResponseCommand.$(OBJEXT) \
 	InitiateConnectionCommand.$(OBJEXT) \
 	FtpFinishDownloadCommand.$(OBJEXT) A2STR.$(OBJEXT) \
 	RarestPieceSelector.$(OBJEXT) ChunkedDecoder.$(OBJEXT) \
@@ -1063,11 +1061,12 @@ SRCS = Socket.h SocketCore.cc SocketCore.h BinaryStream.h Command.cc \
 	DefaultAuthResolver.cc DefaultAuthResolver.h \
 	NetrcAuthResolver.cc NetrcAuthResolver.h AuthConfigFactory.cc \
 	AuthConfigFactory.h OptionParser.cc OptionParser.h \
-	OptionHandlerFactory.cc OptionHandlerFactory.h OptionHandler.h \
-	OptionHandlerImpl.h NameMatchOptionHandler.h NameResolver.cc \
-	NameResolver.h RequestGroup.cc RequestGroup.h \
-	RequestGroupAware.cc RequestGroupAware.h RequestGroupMan.cc \
-	RequestGroupMan.h FileAllocationMan.cc FileAllocationMan.h \
+	OptionHandlerFactory.cc OptionHandlerFactory.h \
+	OptionHandler.cc OptionHandler.h OptionHandlerImpl.h \
+	NameMatchOptionHandler.h NameResolver.cc NameResolver.h \
+	RequestGroup.cc RequestGroup.h RequestGroupAware.cc \
+	RequestGroupAware.h RequestGroupMan.cc RequestGroupMan.h \
+	FileAllocationMan.cc FileAllocationMan.h \
 	FileAllocationCommand.cc FileAllocationCommand.h \
 	FillRequestGroupCommand.cc FillRequestGroupCommand.h \
 	FileAllocationDispatcherCommand.cc \
@@ -1116,9 +1115,7 @@ SRCS = Socket.h SocketCore.cc SocketCore.h BinaryStream.h Command.cc \
 	MultiFileAllocationIterator.h PeerConnection.cc \
 	PeerConnection.h ByteArrayDiskWriter.cc ByteArrayDiskWriter.h \
 	ByteArrayDiskWriterFactory.cc ByteArrayDiskWriterFactory.h \
-	ServerHost.cc ServerHost.h HelpItem.cc HelpItem.h \
-	TaggedItem.cc TaggedItem.h TagContainer.cc TagContainer.h \
-	HelpItemFactory.cc HelpItemFactory.h DownloadContext.cc \
+	ServerHost.cc ServerHost.h DownloadContext.cc \
 	DownloadContext.h SingleFileDownloadContext.cc \
 	SingleFileDownloadContext.h TimedHaltCommand.cc \
 	TimedHaltCommand.h CUIDCounter.h DNSCache.h DownloadResult.h \
@@ -1398,8 +1395,6 @@ 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@
@@ -1445,6 +1440,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NsCookieParser.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OSMetalinkParserState.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Option.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OptionHandler.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OptionHandlerFactory.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OptionParser.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PStringBuildVisitor.Po@am__quote@
@@ -1500,8 +1496,6 @@ distclean-compile:
 @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)/StringFormat.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)/TimedHaltCommand.Po@am__quote@

+ 63 - 1
src/NameMatchOptionHandler.h

@@ -38,7 +38,15 @@
 #include "OptionHandler.h"
 #include "DlAbortEx.h"
 #include "StringFormat.h"
+#include "A2STR.h"
+#include "Util.h"
 #include <strings.h>
+#include <algorithm>
+#include <sstream>
+#include <iterator>
+
+#define NO_DESCRIPTION A2STR::NIL
+#define NO_DEFAULT_VALUE A2STR::NIL
 
 namespace aria2 {
 
@@ -48,9 +56,24 @@ class NameMatchOptionHandler : public OptionHandler {
 protected:
   std::string _optName;
 
+  std::string _description;
+
+  std::string _defaultValue;
+
+  bool _hidden;
+
+  std::deque<std::string> _tags;
+
   virtual void parseArg(Option* option, const std::string& arg) = 0;
 public:
-  NameMatchOptionHandler(const std::string& optName):_optName(optName) {}
+  NameMatchOptionHandler(const std::string& optName,
+			 const std::string& description = NO_DESCRIPTION,
+			 const std::string& defaultValue = NO_DEFAULT_VALUE,
+			 bool hidden = false):
+    _optName(optName),
+    _description(description),
+    _defaultValue(defaultValue),
+    _hidden(hidden) {}
 
   virtual ~NameMatchOptionHandler() {}
   
@@ -69,6 +92,45 @@ public:
 		      _optName.c_str()).str(), e);
     }
   }
+
+  virtual bool hasTag(const std::string& tag) const
+  {
+    return std::find(_tags.begin(), _tags.end(), tag) != _tags.end();
+  }
+
+  virtual void addTag(const std::string& tag)
+  {
+    _tags.push_back(tag);
+  }
+
+  virtual std::string toTagString() const
+  {
+    std::stringstream s;
+    std::copy(_tags.begin(), _tags.end(),
+	      std::ostream_iterator<std::string>(s, ","));
+    return Util::trim(s.str(), ", ");
+  }
+
+  virtual const std::string& getName() const
+  {
+    return _optName;
+  }
+
+  virtual const std::string& getDescription() const
+  {
+    return _description;
+  }
+
+  virtual const std::string& getDefaultValue() const
+  {
+    return _defaultValue;
+  }
+
+  virtual bool isHidden() const
+  {
+    return _hidden;
+  }
+
 };
 
 typedef SharedHandle<NameMatchOptionHandler> NameMatchOptionHandlerHandle;

+ 14 - 17
src/HelpItem.cc → src/OptionHandler.cc

@@ -32,30 +32,27 @@
  * files in the program, then also delete it here.
  */
 /* copyright --> */
-#include "HelpItem.h"
-
-namespace aria2 {
+#include "OptionHandler.h"
+#include <ostream>
 
 #define DEFAULT_MSG   _("                              Default: ")
 #define    TAGS_MSG   _("                              Tags: ")
-#define AVAILABLE_MSG _("                              Available Values: ")
+#define POSSIBLE_MSG _("                              Possible Values: ")
+
+namespace aria2 {
 
-std::string HelpItem::toString() const
+std::ostream& operator<<(std::ostream& o, const OptionHandler& optionHandler)
 {
-  std::string s(_usageText+"\n");
-  if(!_availableValues.empty()) {
-    s += AVAILABLE_MSG;
-    s += _availableValues;
-    s += "\n";
+  o << optionHandler.getDescription() << "\n\n";
+  std::string possibleValues = optionHandler.createPossibleValuesString();
+  if(!possibleValues.empty()) {
+    o << POSSIBLE_MSG << possibleValues << "\n";
   }
-  if(!_defaultValue.empty()) {
-    s += DEFAULT_MSG;
-    s += _defaultValue;
-    s += "\n";
+  if(!optionHandler.getDefaultValue().empty()) {
+    o << DEFAULT_MSG << optionHandler.getDefaultValue() << "\n";
   }
-  s += TAGS_MSG;
-  s += toTagString();
-  return s;
+  o << TAGS_MSG << optionHandler.toTagString();
+  return o;
 }
 
 } // namespace aria2

+ 19 - 0
src/OptionHandler.h

@@ -39,6 +39,7 @@
 #include "SharedHandle.h"
 #include <string>
 #include <deque>
+#include <iosfwd>
 
 namespace aria2 {
 
@@ -50,11 +51,29 @@ public:
   
   virtual bool canHandle(const std::string& optName) = 0;
   virtual void parse(Option* option, const std::string& arg) = 0;
+
+  virtual std::string createPossibleValuesString() const = 0;
+
+  virtual bool hasTag(const std::string& tag) const = 0;
+
+  virtual void addTag(const std::string& tag) = 0;
+
+  virtual std::string toTagString() const = 0;
+
+  virtual const std::string& getName() const = 0;
+
+  virtual const std::string& getDescription() const = 0;
+
+  virtual const std::string& getDefaultValue() const = 0;
+
+  virtual bool isHidden() const = 0;
 };
 
 typedef SharedHandle<OptionHandler> OptionHandlerHandle;
 typedef std::deque<OptionHandlerHandle> OptionHandlers;
 
+std::ostream& operator<<(std::ostream& o, const OptionHandler& optionHandler);
+
 } // namespace aria2
 
 #endif // _D_OPTION_HANDLER_H_

+ 879 - 110
src/OptionHandlerFactory.cc

@@ -36,128 +36,897 @@
 #include "prefs.h"
 #include "OptionHandlerImpl.h"
 #include "array_fun.h"
-
-#define SH(X) SharedHandle<OptionHandler>(X)
+#include "usage_text.h"
+#include "A2STR.h"
+#include "Util.h"
+#include "help_tags.h"
+#include "StringFormat.h"
 
 namespace aria2 {
 
 OptionHandlers OptionHandlerFactory::createOptionHandlers()
 {
   OptionHandlers handlers;
-
-
-  handlers.push_back(SH(new HttpProxyOptionHandler(PREF_HTTP_PROXY,
-						   PREF_HTTP_PROXY_HOST,
-						   PREF_HTTP_PROXY_PORT)));
-  handlers.push_back(SH(new DefaultOptionHandler(PREF_HTTP_USER)));
-  handlers.push_back(SH(new DefaultOptionHandler(PREF_HTTP_PASSWD)));
-  handlers.push_back(SH(new DefaultOptionHandler(PREF_HTTP_PROXY_USER)));
-  handlers.push_back(SH(new DefaultOptionHandler(PREF_HTTP_PROXY_PASSWD)));
-  handlers.push_back(SH(new ParameterOptionHandler(PREF_HTTP_AUTH_SCHEME, V_BASIC)));
-  handlers.push_back(SH(new DefaultOptionHandler(PREF_REFERER)));
-  handlers.push_back(SH(new NumberOptionHandler(PREF_RETRY_WAIT, 0, 60)));
-  handlers.push_back(SH(new DefaultOptionHandler(PREF_FTP_USER)));
-  handlers.push_back(SH(new DefaultOptionHandler(PREF_FTP_PASSWD)));
-  handlers.push_back(SH(new ParameterOptionHandler(PREF_FTP_TYPE, V_BINARY, V_ASCII)));
-  handlers.push_back(SH(new ParameterOptionHandler(PREF_FTP_VIA_HTTP_PROXY,
-						V_GET, V_TUNNEL)));
-  handlers.push_back(SH(new UnitNumberOptionHandler(PREF_MIN_SEGMENT_SIZE, 1024)));
-  handlers.push_back(SH(new ParameterOptionHandler(PREF_HTTP_PROXY_METHOD,
-						V_GET, V_TUNNEL)));
-  handlers.push_back(SH(new IntegerRangeOptionHandler(PREF_LISTEN_PORT, 1024, UINT16_MAX)));
-  handlers.push_back(SH(new ParameterOptionHandler(PREF_FOLLOW_TORRENT, V_TRUE, V_MEM, V_FALSE)));
-  handlers.push_back(SH(new BooleanOptionHandler(PREF_NO_PREALLOCATION)));
-  handlers.push_back(SH(new BooleanOptionHandler(PREF_DIRECT_FILE_MAPPING)));
-  handlers.push_back(SH(new IntegerRangeOptionHandler(PREF_SELECT_FILE, 1, INT32_MAX)));
-  handlers.push_back(SH(new NumberOptionHandler(PREF_SEED_TIME, 0)));
-  handlers.push_back(SH(new FloatNumberOptionHandler(PREF_SEED_RATIO, 0.0)));
-  handlers.push_back(SH(new UnitNumberOptionHandler(PREF_MAX_UPLOAD_LIMIT, 0)));
-  handlers.push_back(SH(new DefaultOptionHandler(PREF_METALINK_VERSION)));
-  handlers.push_back(SH(new DefaultOptionHandler(PREF_METALINK_LANGUAGE)));
-  handlers.push_back(SH(new DefaultOptionHandler(PREF_METALINK_OS)));
-  handlers.push_back(SH(new ParameterOptionHandler(PREF_FOLLOW_METALINK, V_TRUE, V_MEM, V_FALSE)));
-  handlers.push_back(SH(new DefaultOptionHandler(PREF_METALINK_LOCATION)));
-  handlers.push_back(SH(new UnitNumberOptionHandler(PREF_LOWEST_SPEED_LIMIT, 0)));
-  handlers.push_back(SH(new UnitNumberOptionHandler(PREF_MAX_DOWNLOAD_LIMIT, 0)));
-  handlers.push_back(SH(new BooleanOptionHandler(PREF_ALLOW_OVERWRITE)));
-  handlers.push_back(SH(new BooleanOptionHandler(PREF_CHECK_INTEGRITY)));
-  handlers.push_back(SH(new BooleanOptionHandler(PREF_REALTIME_CHUNK_CHECKSUM)));
-  handlers.push_back(SH(new BooleanOptionHandler(PREF_DAEMON)));
-  handlers.push_back(SH(new DefaultOptionHandler(PREF_DIR)));
-  handlers.push_back(SH(new DefaultOptionHandler(PREF_OUT)));
-  handlers.push_back(SH(new LogOptionHandler(PREF_LOG)));
-  handlers.push_back(SH(new NumberOptionHandler(PREF_SPLIT, 1, 16)));
-  handlers.push_back(SH(new NumberOptionHandler(PREF_TIMEOUT, 1, 600)));
-  handlers.push_back(SH(new NumberOptionHandler(PREF_MAX_TRIES, 0)));
-  handlers.push_back(SH(new BooleanOptionHandler(PREF_FTP_PASV)));
-  handlers.push_back(SH(new BooleanOptionHandler(PREF_SHOW_FILES)));
-  handlers.push_back(SH(new DefaultOptionHandler(PREF_TORRENT_FILE)));
-  handlers.push_back(SH(new DefaultOptionHandler(PREF_METALINK_FILE)));
-  handlers.push_back(SH(new NumberOptionHandler(PREF_METALINK_SERVERS, 1)));
-  handlers.push_back(SH(new ParameterOptionHandler(PREF_FILE_ALLOCATION,
-						V_NONE, V_PREALLOC)));
-  handlers.push_back(SH(new BooleanOptionHandler(PREF_CONTINUE)));
-  handlers.push_back(SH(new DefaultOptionHandler(PREF_USER_AGENT)));
-  handlers.push_back(SH(new BooleanOptionHandler(PREF_NO_NETRC)));
-  handlers.push_back(SH(new DefaultOptionHandler(PREF_INPUT_FILE)));
-  handlers.push_back(SH(new NumberOptionHandler(PREF_MAX_CONCURRENT_DOWNLOADS, 1, 45)));
-  handlers.push_back(SH(new DefaultOptionHandler(PREF_LOAD_COOKIES)));
-  handlers.push_back(SH(new DefaultOptionHandler(PREF_PEER_ID_PREFIX)));
-  handlers.push_back(SH(new BooleanOptionHandler(PREF_FORCE_SEQUENTIAL)));  
-  handlers.push_back(SH(new BooleanOptionHandler(PREF_AUTO_FILE_RENAMING)));  
-  handlers.push_back(SH(new BooleanOptionHandler(PREF_PARAMETERIZED_URI)));  
-  handlers.push_back(SH(new BooleanOptionHandler(PREF_ENABLE_HTTP_KEEP_ALIVE)));
-  handlers.push_back(SH(new BooleanOptionHandler(PREF_ENABLE_HTTP_PIPELINING)));
-  handlers.push_back(SH(new UnitNumberOptionHandler(PREF_NO_FILE_ALLOCATION_LIMIT, 0)));
-  handlers.push_back(SH(new BooleanOptionHandler(PREF_ENABLE_DIRECT_IO)));
-  handlers.push_back(SH(new BooleanOptionHandler(PREF_ALLOW_PIECE_LENGTH_CHANGE)));
+  // General Options
   {
-    const std::string params[] = { V_HTTP, V_HTTPS, V_FTP, V_NONE };
-    handlers.push_back(SH(new ParameterOptionHandler(PREF_METALINK_PREFERRED_PROTOCOL,
-						     std::deque<std::string>(&params[0], &params[arrayLength(params)]))));
-  }
-  handlers.push_back(SH(new BooleanOptionHandler(PREF_METALINK_ENABLE_UNIQUE_PROTOCOL)));
-  handlers.push_back(SH(new BooleanOptionHandler(PREF_ENABLE_PEER_EXCHANGE)));
-  handlers.push_back(SH(new BooleanOptionHandler(PREF_ENABLE_DHT)));
-  handlers.push_back(SH(new IntegerRangeOptionHandler(PREF_DHT_LISTEN_PORT, 1024, UINT16_MAX)));
-  handlers.push_back(SH(new HostPortOptionHandler(PREF_DHT_ENTRY_POINT,
-					       PREF_DHT_ENTRY_POINT_HOST,
-					       PREF_DHT_ENTRY_POINT_PORT)));
-  handlers.push_back(SH(new NumberOptionHandler(PREF_STOP, 0, INT32_MAX)));
-  handlers.push_back(SH(new ParameterOptionHandler(PREF_BT_MIN_CRYPTO_LEVEL, V_PLAIN, V_ARC4)));
-  handlers.push_back(SH(new BooleanOptionHandler(PREF_BT_REQUIRE_CRYPTO)));
-  handlers.push_back(SH(new NumberOptionHandler(PREF_BT_REQUEST_PEER_SPEED_LIMIT, 0)));
-  handlers.push_back(SH(new NumberOptionHandler(PREF_BT_MAX_OPEN_FILES, 1)));
-  handlers.push_back(SH(new CumulativeOptionHandler(PREF_HEADER, "\n")));
-  handlers.push_back(SH(new BooleanOptionHandler(PREF_QUIET)));
-#ifdef ENABLE_ASYNC_DNS
-  handlers.push_back(SH(new BooleanOptionHandler(PREF_ASYNC_DNS)));
-#endif // ENABLE_ASYNC_DNS
-  handlers.push_back(SH(new BooleanOptionHandler(PREF_FTP_REUSE_CONNECTION)));
-  handlers.push_back(SH(new NumberOptionHandler(PREF_SUMMARY_INTERVAL, 0, INT32_MAX)));
+    SharedHandle<OptionHandler> op(new BooleanOptionHandler
+				   (PREF_ALLOW_OVERWRITE,
+				    TEXT_ALLOW_OVERWRITE,
+				    V_FALSE));
+    op->addTag(TAG_ADVANCED);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new BooleanOptionHandler
+				   (PREF_ALLOW_PIECE_LENGTH_CHANGE,
+				    TEXT_ALLOW_PIECE_LENGTH_CHANGE,
+				    V_FALSE));
+    op->addTag(TAG_ADVANCED);
+    handlers.push_back(op);
+  } 
+  {
+    SharedHandle<OptionHandler> op(new BooleanOptionHandler
+				   (PREF_ASYNC_DNS,
+				    TEXT_ASYNC_DNS,
+				    V_TRUE));
+    op->addTag(TAG_ADVANCED);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new BooleanOptionHandler
+				   (PREF_AUTO_FILE_RENAMING,
+				    TEXT_AUTO_FILE_RENAMING,
+				    V_TRUE));
+    op->addTag(TAG_ADVANCED);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new NumberOptionHandler
+				   (PREF_AUTO_SAVE_INTERVAL,
+				    NO_DESCRIPTION,
+				    "60",
+				    1, 600,
+				    true));
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new BooleanOptionHandler
+				   (PREF_CHECK_INTEGRITY,
+				    TEXT_CHECK_INTEGRITY,
+				    V_FALSE));
+    op->addTag(TAG_BASIC);
+    op->addTag(TAG_BITTORRENT);
+    op->addTag(TAG_METALINK);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new DefaultOptionHandler
+				   (PREF_CONF_PATH,
+				    TEXT_CONF_PATH,
+				    Util::getHomeDir()+"/.aria2/aria2.conf"));
+    op->addTag(TAG_ADVANCED);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new BooleanOptionHandler
+				   (PREF_CONTINUE,
+				    TEXT_CONTINUE,
+				    V_FALSE)); // TODO ommit?
+    op->addTag(TAG_BASIC);
+    op->addTag(TAG_FTP);
+    op->addTag(TAG_HTTP);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new BooleanOptionHandler
+				   (PREF_DAEMON,
+				    TEXT_DAEMON,
+				    V_FALSE)); // TODO ommit?
+    op->addTag(TAG_ADVANCED);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new DefaultOptionHandler
+				   (PREF_DIR,
+				    TEXT_DIR,
+				    "."));
+    op->addTag(TAG_BASIC);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new NumberOptionHandler
+				   (PREF_DNS_TIMEOUT,
+				    NO_DESCRIPTION,
+				    "30",
+				    1, 60,
+				    true));
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new BooleanOptionHandler
+				   (PREF_ENABLE_DIRECT_IO,
+				    TEXT_ENABLE_DIRECT_IO,
+				    V_FALSE));
+    op->addTag(TAG_ADVANCED);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new ParameterOptionHandler
+				   (PREF_FILE_ALLOCATION,
+				    TEXT_FILE_ALLOCATION,
+				    V_PREALLOC,
+				    V_NONE, V_PREALLOC));
+    op->addTag(TAG_BASIC);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new BooleanOptionHandler
+				   (PREF_FORCE_SEQUENTIAL,
+				    TEXT_FORCE_SEQUENTIAL,
+				    V_FALSE));
+    op->addTag(TAG_BASIC);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new DefaultOptionHandler
+				   (PREF_INPUT_FILE,
+				    TEXT_INPUT_FILE,
+				    NO_DEFAULT_VALUE,
+				    "FILENAME,-"));
+    op->addTag(TAG_BASIC);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new DefaultOptionHandler
+				   (PREF_LOG,
+				    TEXT_LOG,
+				    NO_DEFAULT_VALUE,
+				    "FILENAME,-"));
+    op->addTag(TAG_BASIC);
+    handlers.push_back(op);
+  }
   {
     const std::string params[] = { V_DEBUG, V_INFO, V_NOTICE, V_WARN, V_ERROR };
-    handlers.push_back(SH(new ParameterOptionHandler
-			  (PREF_LOG_LEVEL,
-			   std::deque<std::string>(&params[0],
-						   &params[arrayLength(params)]))));
+    SharedHandle<OptionHandler> op(new ParameterOptionHandler
+				   (PREF_LOG_LEVEL,
+				    TEXT_LOG_LEVEL,
+				    V_DEBUG,
+				    std::deque<std::string>
+				    (&params[0],
+				     &params[arrayLength(params)])));
+    op->addTag(TAG_ADVANCED);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new NumberOptionHandler
+				   (PREF_MAX_CONCURRENT_DOWNLOADS,
+				    TEXT_MAX_CONCURRENT_DOWNLOADS,
+				    "5",
+				    1, 45));
+    op->addTag(TAG_BASIC);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new UnitNumberOptionHandler
+				   (PREF_MAX_DOWNLOAD_LIMIT,
+				    TEXT_MAX_DOWNLOAD_LIMIT,
+				    "0",
+				    0));
+    op->addTag(TAG_BITTORRENT);
+    op->addTag(TAG_FTP);
+    op->addTag(TAG_HTTP);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new BooleanOptionHandler
+				   (PREF_NO_CONF,
+				    TEXT_NO_CONF,
+				    V_FALSE));
+    op->addTag(TAG_ADVANCED);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new UnitNumberOptionHandler
+				   (PREF_NO_FILE_ALLOCATION_LIMIT,
+				    TEXT_NO_FILE_ALLOCATION_LIMIT,
+				    "5M",
+				    0));
+    op->addTag(TAG_ADVANCED);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new BooleanOptionHandler
+				   (PREF_PARAMETERIZED_URI,
+				    TEXT_PARAMETERIZED_URI,
+				    V_FALSE));  
+    op->addTag(TAG_ADVANCED);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new BooleanOptionHandler
+				   (PREF_QUIET,
+				    TEXT_QUIET,
+				    V_FALSE));
+    op->addTag(TAG_ADVANCED);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new BooleanOptionHandler
+				   (PREF_REALTIME_CHUNK_CHECKSUM,
+				    TEXT_REALTIME_CHUNK_CHECKSUM,
+				    V_TRUE));
+    op->addTag(TAG_METALINK);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new NumberOptionHandler
+				   (PREF_STOP,
+				    TEXT_STOP,
+				    "0",
+				    0, INT32_MAX));
+    op->addTag(TAG_ADVANCED);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new NumberOptionHandler
+				   (PREF_SUMMARY_INTERVAL,
+				    TEXT_SUMMARY_INTERVAL,
+				    "60",
+				    0, INT32_MAX));
+    op->addTag(TAG_ADVANCED);
+    handlers.push_back(op);
+  }
+  // HTTP/FTP options
+  {
+    SharedHandle<OptionHandler> op(new NumberOptionHandler
+				   (PREF_CONNECT_TIMEOUT,
+				    TEXT_CONNECT_TIMEOUT,
+				    "60",
+				    1, 600));
+    op->addTag(TAG_FTP);
+    op->addTag(TAG_HTTP);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new UnitNumberOptionHandler
+				   (PREF_LOWEST_SPEED_LIMIT,
+				    TEXT_LOWEST_SPEED_LIMIT,
+				    "0",
+				    0));
+    op->addTag(TAG_FTP);
+    op->addTag(TAG_HTTP);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new NumberOptionHandler
+				   (PREF_MAX_FILE_NOT_FOUND,
+				    TEXT_MAX_FILE_NOT_FOUND,
+				    "0",
+				    0));
+    op->addTag(TAG_FTP);
+    op->addTag(TAG_HTTP);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new NumberOptionHandler
+				   (PREF_MAX_TRIES,
+				    TEXT_MAX_TRIES,
+				    "5",
+				    0));
+    op->addTag(TAG_FTP);
+    op->addTag(TAG_HTTP);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new DefaultOptionHandler
+				   (PREF_OUT,
+				    TEXT_OUT,
+				    NO_DEFAULT_VALUE,
+				    "FILENAME"));
+    op->addTag(TAG_BASIC);
+    op->addTag(TAG_FTP);
+    op->addTag(TAG_HTTP);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new BooleanOptionHandler
+				   (PREF_REMOTE_TIME,
+				    TEXT_REMOTE_TIME,
+				    V_FALSE));
+    op->addTag(TAG_FTP);
+    op->addTag(TAG_HTTP);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new NumberOptionHandler
+				   (PREF_RETRY_WAIT,
+				    TEXT_RETRY_WAIT,
+				    "5",
+				    0, 60));
+    op->addTag(TAG_FTP);
+    op->addTag(TAG_HTTP);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new UnitNumberOptionHandler
+				   (PREF_SEGMENT_SIZE,
+				    NO_DESCRIPTION,
+				    "1M",
+				    1024, -1,
+				    true));
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new DefaultOptionHandler
+				   (PREF_SERVER_STAT_IF,
+				    TEXT_SERVER_STAT_IF,
+				    NO_DEFAULT_VALUE,
+				    "FILENAME"));
+    op->addTag(TAG_FTP);
+    op->addTag(TAG_HTTP);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new DefaultOptionHandler
+				   (PREF_SERVER_STAT_OF,
+				    TEXT_SERVER_STAT_OF,
+				    NO_DEFAULT_VALUE,
+				    "FILENAME"));
+    op->addTag(TAG_FTP);
+    op->addTag(TAG_HTTP);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new NumberOptionHandler
+				   (PREF_SERVER_STAT_TIMEOUT,
+				    TEXT_SERVER_STAT_TIMEOUT,
+				    "86400",
+				    0, INT32_MAX));
+    op->addTag(TAG_FTP);
+    op->addTag(TAG_HTTP);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new NumberOptionHandler
+				   (PREF_SPLIT,
+				    TEXT_SPLIT,
+				    "5",
+				    1, 16));
+    op->addTag(TAG_BASIC);
+    op->addTag(TAG_FTP);
+    op->addTag(TAG_HTTP);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new NumberOptionHandler
+				   (PREF_STARTUP_IDLE_TIME,
+				    NO_DESCRIPTION,
+				    "10",
+				    1, 60,
+				    true));
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new NumberOptionHandler
+				   (PREF_TIMEOUT,
+				    TEXT_TIMEOUT,
+				    "60",
+				    1, 600));
+    op->addTag(TAG_FTP);
+    op->addTag(TAG_HTTP);
+    handlers.push_back(op);
   }
-  handlers.push_back(SH(new BooleanOptionHandler(PREF_BT_SEED_UNVERIFIED)));
   {
     const std::string params[] = { V_INORDER, V_FEEDBACK };
-    handlers.push_back(SH(new ParameterOptionHandler
-			  (PREF_URI_SELECTOR,
-			   std::deque<std::string>
-			   (&params[0], &params[arrayLength(params)]))));
-  }
-  handlers.push_back(SH(new NumberOptionHandler(PREF_SERVER_STAT_TIMEOUT,
-						0, INT32_MAX)));
-  handlers.push_back(SH(new DefaultOptionHandler(PREF_SERVER_STAT_IF)));
-  handlers.push_back(SH(new DefaultOptionHandler(PREF_SERVER_STAT_OF)));
-  handlers.push_back(SH(new BooleanOptionHandler(PREF_REMOTE_TIME)));
-  handlers.push_back(SH(new NumberOptionHandler(PREF_CONNECT_TIMEOUT, 1, 600)));
-  handlers.push_back(SH(new NumberOptionHandler(PREF_MAX_FILE_NOT_FOUND, 0)));
-
+    SharedHandle<OptionHandler> op(new ParameterOptionHandler
+				   (PREF_URI_SELECTOR,
+				    TEXT_URI_SELECTOR,
+				    V_INORDER,
+				    std::deque<std::string>
+				    (&params[0], &params[arrayLength(params)])));
+    op->addTag(TAG_FTP);
+    op->addTag(TAG_HTTP);
+    handlers.push_back(op);
+  }
+  // HTTP Specific Options
+  {
+    SharedHandle<OptionHandler> op(new BooleanOptionHandler
+				   (PREF_ENABLE_HTTP_KEEP_ALIVE,
+				    TEXT_ENABLE_HTTP_KEEP_ALIVE,
+				    V_TRUE));
+    op->addTag(TAG_HTTP);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new BooleanOptionHandler
+				   (PREF_ENABLE_HTTP_PIPELINING,
+				    TEXT_ENABLE_HTTP_PIPELINING,
+				    V_FALSE));
+    op->addTag(TAG_HTTP);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new CumulativeOptionHandler
+				   (PREF_HEADER,
+				    TEXT_HEADER,
+				    NO_DEFAULT_VALUE,
+				    "\n"));
+    op->addTag(TAG_HTTP);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new ParameterOptionHandler
+				   (PREF_HTTP_AUTH_SCHEME,
+				    TEXT_HTTP_AUTH_SCHEME,
+				    V_BASIC,
+				    V_BASIC));
+    op->addTag(TAG_HTTP);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new DefaultOptionHandler
+				   (PREF_HTTP_PASSWD,
+				    TEXT_HTTP_PASSWD));
+    op->addTag(TAG_BASIC);
+    op->addTag(TAG_HTTP);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new HttpProxyOptionHandler
+				   (PREF_HTTP_PROXY,
+				    TEXT_HTTP_PROXY,
+				    NO_DEFAULT_VALUE,
+				    PREF_HTTP_PROXY_HOST,
+				    PREF_HTTP_PROXY_PORT));
+    op->addTag(TAG_HTTP);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new DefaultOptionHandler
+				   (PREF_HTTP_PROXY_USER,
+				    TEXT_HTTP_PROXY_USER));
+    op->addTag(TAG_HTTP);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new DefaultOptionHandler
+				   (PREF_HTTP_PROXY_PASSWD,
+				    TEXT_HTTP_PROXY_PASSWD));
+    op->addTag(TAG_HTTP);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new ParameterOptionHandler
+				   (PREF_HTTP_PROXY_METHOD,
+				    TEXT_HTTP_PROXY_METHOD,
+				    V_TUNNEL,
+				    V_GET, V_TUNNEL));
+    op->addTag(TAG_HTTP);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new DefaultOptionHandler
+				   (PREF_HTTP_USER,
+				    TEXT_HTTP_USER));
+    op->addTag(TAG_BASIC);
+    op->addTag(TAG_HTTP);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new DefaultOptionHandler
+				   (PREF_LOAD_COOKIES,
+				    TEXT_LOAD_COOKIES,
+				    NO_DEFAULT_VALUE,
+				    "FILENAME"));
+    op->addTag(TAG_BASIC);
+    op->addTag(TAG_HTTP);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new NumberOptionHandler
+				   (PREF_MAX_HTTP_PIPELINING,
+				    NO_DESCRIPTION,
+				    "2",
+				    1, 8,
+				    true));
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new DefaultOptionHandler
+				   (PREF_REFERER,
+				    TEXT_REFERER));
+    op->addTag(TAG_HTTP);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new DefaultOptionHandler
+				   (PREF_USER_AGENT,
+				    TEXT_USER_AGENT,
+				    "aria2"));
+    op->addTag(TAG_HTTP);
+    handlers.push_back(op);
+  }
+  // FTP Specific Options
+  {
+    SharedHandle<OptionHandler> op(new DefaultOptionHandler
+				   (PREF_FTP_PASSWD,
+				    TEXT_FTP_PASSWD,
+				    "ARIA2USER@"));
+    op->addTag(TAG_BASIC);
+    op->addTag(TAG_FTP);
+    handlers.push_back(op);
+  }    
+  {
+    SharedHandle<OptionHandler> op(new BooleanOptionHandler
+				   (PREF_FTP_PASV,
+				    TEXT_FTP_PASV,
+				    V_FALSE)); // TODO ommit?
+    op->addTag(TAG_FTP);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new BooleanOptionHandler
+				   (PREF_FTP_REUSE_CONNECTION,
+				    TEXT_FTP_REUSE_CONNECTION,
+				    V_TRUE));
+    op->addTag(TAG_FTP);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new ParameterOptionHandler
+				   (PREF_FTP_TYPE,
+				    TEXT_FTP_TYPE,
+				    V_BINARY,
+				    V_BINARY, V_ASCII));
+    op->addTag(TAG_FTP);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new DefaultOptionHandler
+				   (PREF_FTP_USER,
+				    TEXT_FTP_USER,
+				    "anonymous"));
+    op->addTag(TAG_BASIC);
+    op->addTag(TAG_FTP);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new ParameterOptionHandler
+				   (PREF_FTP_VIA_HTTP_PROXY,
+				    TEXT_FTP_VIA_HTTP_PROXY,
+				    V_TUNNEL,
+				    V_GET, V_TUNNEL));
+    op->addTag(TAG_FTP);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new DefaultOptionHandler
+				   (PREF_NETRC_PATH,
+				    NO_DESCRIPTION,
+				    Util::getHomeDir()+"/.netrc",
+				    "/PATH/TO/NETRC",
+				    true));
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new BooleanOptionHandler
+				   (PREF_NO_NETRC,
+				    TEXT_NO_NETRC,
+				    V_FALSE)); // TODO ommit?
+    op->addTag(TAG_FTP);
+    handlers.push_back(op);
+  }
+  // BitTorrent/Metalink Options
+  {
+    SharedHandle<OptionHandler> op(new IntegerRangeOptionHandler
+				   (PREF_SELECT_FILE,
+				    TEXT_SELECT_FILE,
+				    NO_DEFAULT_VALUE,
+				    1, INT32_MAX));
+    op->addTag(TAG_BITTORRENT);
+    op->addTag(TAG_METALINK);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new BooleanOptionHandler
+				   (PREF_SHOW_FILES,
+				    TEXT_SHOW_FILES,
+				    V_FALSE)); // TODO ommit?
+    op->addTag(TAG_BASIC);
+    op->addTag(TAG_BITTORRENT);
+    op->addTag(TAG_METALINK);
+    handlers.push_back(op);
+  }
+  // BitTorrent Specific Options
+  {
+    SharedHandle<OptionHandler> op(new NumberOptionHandler
+				   (PREF_BT_KEEP_ALIVE_INTERVAL,
+				    NO_DESCRIPTION,
+				    "120",
+				    1, 120,
+				    true));
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new NumberOptionHandler
+				   (PREF_BT_MAX_OPEN_FILES,
+				    TEXT_BT_MAX_OPEN_FILES,
+				    "100",
+				    1));
+    op->addTag(TAG_BITTORRENT);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new ParameterOptionHandler
+				   (PREF_BT_MIN_CRYPTO_LEVEL,
+				    TEXT_BT_MIN_CRYPTO_LEVEL,
+				    V_PLAIN,
+				    V_PLAIN, V_ARC4));
+    op->addTag(TAG_BITTORRENT);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new UnitNumberOptionHandler
+				   (PREF_BT_REQUEST_PEER_SPEED_LIMIT,
+				    TEXT_BT_REQUEST_PEER_SPEED_LIMIT,
+				    "50K",
+				    0));
+    op->addTag(TAG_BITTORRENT);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new BooleanOptionHandler
+				   (PREF_BT_REQUIRE_CRYPTO,
+				    TEXT_BT_REQUIRE_CRYPTO,
+				    V_FALSE));
+    op->addTag(TAG_BITTORRENT);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new NumberOptionHandler
+				   (PREF_BT_REQUEST_TIMEOUT,
+				    NO_DESCRIPTION,
+				    "60",
+				    1, 600,
+				    true));
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new BooleanOptionHandler
+				   (PREF_BT_SEED_UNVERIFIED,
+				    TEXT_BT_SEED_UNVERIFIED,
+				    V_FALSE));
+    op->addTag(TAG_BITTORRENT);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new NumberOptionHandler
+				   (PREF_BT_TIMEOUT,
+				    NO_DESCRIPTION,
+				    "180",
+				    1, 600,
+				    true));
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new BooleanOptionHandler
+				   (PREF_DIRECT_FILE_MAPPING,
+				    TEXT_DIRECT_FILE_MAPPING,
+				    V_TRUE));
+    op->addTag(TAG_BITTORRENT);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new HostPortOptionHandler
+				   (PREF_DHT_ENTRY_POINT,
+				    TEXT_DHT_ENTRY_POINT,
+				    NO_DEFAULT_VALUE,
+				    PREF_DHT_ENTRY_POINT_HOST,
+				    PREF_DHT_ENTRY_POINT_PORT));
+    op->addTag(TAG_BITTORRENT);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new DefaultOptionHandler
+				   (PREF_DHT_FILE_PATH,
+				    NO_DESCRIPTION,
+				    Util::getHomeDir()+"/.aria2/dht.dat",
+				    "/PATH/TO/DHT_DAT",
+				    true));
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new IntegerRangeOptionHandler
+				   (PREF_DHT_LISTEN_PORT,
+				    TEXT_DHT_LISTEN_PORT,
+				    "6881-6999",
+				    1024, UINT16_MAX));
+    op->addTag(TAG_BASIC);
+    op->addTag(TAG_BITTORRENT);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new BooleanOptionHandler
+				   (PREF_ENABLE_DHT,
+				    TEXT_ENABLE_DHT,
+				    V_FALSE));
+    op->addTag(TAG_BASIC);
+    op->addTag(TAG_BITTORRENT);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new BooleanOptionHandler
+				   (PREF_ENABLE_PEER_EXCHANGE,
+				    TEXT_ENABLE_PEER_EXCHANGE,
+				    V_TRUE));
+    op->addTag(TAG_BITTORRENT);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new ParameterOptionHandler
+				   (PREF_FOLLOW_TORRENT,
+				    TEXT_FOLLOW_TORRENT,
+				    V_TRUE,
+				    V_TRUE, V_MEM, V_FALSE));
+    op->addTag(TAG_BITTORRENT);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new IntegerRangeOptionHandler
+				   (PREF_LISTEN_PORT,
+				    TEXT_LISTEN_PORT,
+				    "6881-6999",
+				    1024, UINT16_MAX));
+    op->addTag(TAG_BASIC);
+    op->addTag(TAG_BITTORRENT);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new UnitNumberOptionHandler
+				   (PREF_MAX_UPLOAD_LIMIT,
+				    TEXT_MAX_UPLOAD_LIMIT,
+				    "0",
+				    0));
+    op->addTag(TAG_BASIC);
+    op->addTag(TAG_BITTORRENT);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new NumberOptionHandler
+				   (PREF_PEER_CONNECTION_TIMEOUT,
+				    NO_DESCRIPTION,
+				    "20",
+				    1, 600,
+				    true));
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new DefaultOptionHandler
+				   (PREF_PEER_ID_PREFIX,
+				    TEXT_PEER_ID_PREFIX,
+				    "-aria2-"));
+    op->addTag(TAG_BITTORRENT);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new NumberOptionHandler
+				   (PREF_SEED_TIME,
+				    TEXT_SEED_TIME,
+				    NO_DEFAULT_VALUE,
+				    0));
+    op->addTag(TAG_BITTORRENT);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new FloatNumberOptionHandler
+				   (PREF_SEED_RATIO,
+				    TEXT_SEED_RATIO,
+				    "1.0",
+				    0.0));
+    op->addTag(TAG_BITTORRENT);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new DefaultOptionHandler
+				   (PREF_TORRENT_FILE,
+				    TEXT_TORRENT_FILE));
+    op->addTag(TAG_BASIC);
+    op->addTag(TAG_BITTORRENT);
+    handlers.push_back(op);
+  }
+  // Metalink Specific Options
+  {
+    SharedHandle<OptionHandler> op(new ParameterOptionHandler
+				   (PREF_FOLLOW_METALINK,
+				    TEXT_FOLLOW_METALINK,
+				    V_TRUE,
+				    V_TRUE, V_MEM, V_FALSE));
+    op->addTag(TAG_METALINK);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new BooleanOptionHandler
+				   (PREF_METALINK_ENABLE_UNIQUE_PROTOCOL,
+				    TEXT_METALINK_ENABLE_UNIQUE_PROTOCOL,
+				    V_TRUE));
+    op->addTag(TAG_METALINK);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new DefaultOptionHandler
+				   (PREF_METALINK_FILE,
+				    TEXT_METALINK_FILE));
+    op->addTag(TAG_BASIC);
+    op->addTag(TAG_METALINK);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new DefaultOptionHandler
+				   (PREF_METALINK_LANGUAGE,
+				    TEXT_METALINK_LANGUAGE));
+    op->addTag(TAG_METALINK);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new DefaultOptionHandler
+				   (PREF_METALINK_LOCATION,
+				    TEXT_METALINK_LOCATION));
+    op->addTag(TAG_METALINK);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new DefaultOptionHandler
+				   (PREF_METALINK_OS,
+				    TEXT_METALINK_OS));
+    op->addTag(TAG_METALINK);
+    handlers.push_back(op);
+  }
+  {
+    const std::string params[] = { V_HTTP, V_HTTPS, V_FTP, V_NONE };
+    SharedHandle<OptionHandler> op(new ParameterOptionHandler
+				   (PREF_METALINK_PREFERRED_PROTOCOL,
+				    TEXT_METALINK_PREFERRED_PROTOCOL,
+				    V_NONE,
+				    std::deque<std::string>
+				    (&params[0], &params[arrayLength(params)])));
+    op->addTag(TAG_METALINK);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new NumberOptionHandler
+				   (PREF_METALINK_SERVERS,
+				    TEXT_METALINK_SERVERS,
+				    "5",
+				    1));
+    op->addTag(TAG_METALINK);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new DefaultOptionHandler
+				   (PREF_METALINK_VERSION,
+				    TEXT_METALINK_VERSION));
+    op->addTag(TAG_METALINK);
+    handlers.push_back(op);
+  }
+  // Help Option
+  {
+    SharedHandle<OptionHandler> op(new DefaultOptionHandler
+				   ("help",
+				    TEXT_HELP,
+				    TAG_BASIC,
+				    StringFormat("%s,%s,%s,%s,%s,%s,%s,all",
+						 TAG_BASIC,
+						 TAG_ADVANCED,
+						 TAG_HTTP,
+						 TAG_FTP,
+						 TAG_METALINK,
+						 TAG_BITTORRENT,
+						 TAG_HELP).str()));
+    op->addTag(TAG_BASIC);
+    op->addTag(TAG_HELP);
+    handlers.push_back(op);
+  }
+  
   return handlers;
 }
 

+ 155 - 33
src/OptionHandlerImpl.h

@@ -42,8 +42,12 @@
 #include "prefs.h"
 #include "Option.h"
 #include "StringFormat.h"
+#include "A2STR.h"
 #include <utility>
 #include <algorithm>
+#include <numeric>
+#include <sstream>
+#include <iterator>
 
 namespace aria2 {
 
@@ -54,11 +58,31 @@ public:
   virtual bool canHandle(const std::string& optName) { return true; }
 
   virtual void parse(Option* option, const std::string& arg) {}
+
+  virtual bool hasTag(const std::string& tag) const { return false; }
+
+  virtual void addTag(const std::string& tag) {}
+
+  virtual std::string toTagString() const { return A2STR::NIL; }
+
+  virtual const std::string& getName() const { return A2STR::NIL; }
+
+  virtual const std::string& getDescription() const { return A2STR::NIL; }
+
+  virtual const std::string& getDefaultValue() const { return A2STR::NIL; }
+
+  virtual std::string createPossibleValuesString() const { return A2STR::NIL; }
+
+  virtual bool isHidden() const { return true; }
 };
 
 class BooleanOptionHandler : public NameMatchOptionHandler {
 public:
-  BooleanOptionHandler(const std::string& optName):NameMatchOptionHandler(optName) {}
+  BooleanOptionHandler(const std::string& optName,
+		       const std::string& description = NO_DESCRIPTION,
+		       const std::string& defaultValue = NO_DEFAULT_VALUE):
+    NameMatchOptionHandler(optName, description, defaultValue) {}
+
   virtual ~BooleanOptionHandler() {}
 
   virtual void parseArg(Option* option, const std::string& optarg)
@@ -72,6 +96,11 @@ public:
       throw FatalException(msg);
     }
   }
+
+  virtual std::string createPossibleValuesString() const
+  {
+    return "true,false";
+  }
 };
 
 class IntegerRangeOptionHandler : public NameMatchOptionHandler {
@@ -79,7 +108,12 @@ private:
   int32_t _min;
   int32_t _max;
 public:
-  IntegerRangeOptionHandler(const std::string& optName, int32_t min, int32_t max):NameMatchOptionHandler(optName), _min(min), _max(max) {}
+  IntegerRangeOptionHandler(const std::string& optName,
+			    const std::string& description,
+			    const std::string& defaultValue,
+			    int32_t min, int32_t max):
+    NameMatchOptionHandler(optName, description, defaultValue),
+    _min(min), _max(max) {}
 
   virtual ~IntegerRangeOptionHandler() {}
 
@@ -97,6 +131,11 @@ public:
       option->put(_optName, optarg);
     }
   }
+
+  virtual std::string createPossibleValuesString() const
+  {
+    return Util::itos(_min)+"-"+Util::itos(_max);
+  }
 };
 
 class NumberOptionHandler : public NameMatchOptionHandler {
@@ -104,7 +143,14 @@ private:
   int64_t _min;
   int64_t _max;
 public:
-  NumberOptionHandler(const std::string& optName, int64_t min = -1, int64_t max = -1):NameMatchOptionHandler(optName), _min(min), _max(max) {}
+  NumberOptionHandler(const std::string& optName,
+		      const std::string& description = NO_DESCRIPTION,
+		      const std::string& defaultValue = NO_DEFAULT_VALUE,
+		      int64_t min = -1,
+		      int64_t max = -1,
+		      bool hidden = false):
+    NameMatchOptionHandler(optName, description, defaultValue, hidden),
+    _min(min), _max(max) {}
 
   virtual ~NumberOptionHandler() {}
 
@@ -135,11 +181,23 @@ public:
       throw FatalException(msg);
     }
   }
+
+  virtual std::string createPossibleValuesString() const
+  {
+    return (_min == -1 ? "*" : Util::itos(_min))+"-"+
+      (_max == -1 ? "*" : Util::itos(_max));
+  }
 };
 
 class UnitNumberOptionHandler : public NumberOptionHandler {
 public:
-  UnitNumberOptionHandler(const std::string& optName, int64_t min = -1, int64_t max = -1):NumberOptionHandler(optName, min, max) {}
+  UnitNumberOptionHandler(const std::string& optName,
+			  const std::string& description = NO_DESCRIPTION,
+			  const std::string& defaultValue = NO_DEFAULT_VALUE,
+			  int64_t min = -1,
+			  int64_t max = -1,
+			  bool hidden = false):
+    NumberOptionHandler(optName, description, defaultValue, min, max, hidden) {}
 
   virtual ~UnitNumberOptionHandler() {}
 
@@ -155,7 +213,12 @@ private:
   double _min;
   double _max;
 public:
-  FloatNumberOptionHandler(const std::string& optName, double min = -1, double max = -1):NameMatchOptionHandler(optName), _min(min), _max(max) {}
+  FloatNumberOptionHandler(const std::string& optName,
+			   const std::string& description = NO_DESCRIPTION,
+			   const std::string& defaultValue = NO_DEFAULT_VALUE,
+			   double min = -1, double max = -1):
+    NameMatchOptionHandler(optName, description, defaultValue),
+    _min(min), _max(max) {}
 
   virtual ~FloatNumberOptionHandler() {}
 
@@ -181,11 +244,40 @@ public:
       throw FatalException(msg);
     }
   }
+
+  virtual std::string createPossibleValuesString() const
+  {
+    std::string valuesString;
+    if(_min < 0) {
+      valuesString += "*";
+    } else {
+      char buf[11];
+      snprintf(buf, sizeof(buf), "%.1f", _min);
+      valuesString += buf;
+    }
+    valuesString += "-";
+    if(_max < 0) {
+      valuesString += "*";
+    } else {
+      char buf[11];
+      snprintf(buf, sizeof(buf), "%.1f", _max);
+      valuesString += buf;
+    }
+    return valuesString;
+  }
 };
 
 class DefaultOptionHandler : public NameMatchOptionHandler {
+private:
+  std::string _possibleValuesString;
 public:
-  DefaultOptionHandler(const std::string& optName):NameMatchOptionHandler(optName) {}
+  DefaultOptionHandler(const std::string& optName,
+		       const std::string& description = NO_DESCRIPTION,
+		       const std::string& defaultValue = NO_DEFAULT_VALUE,
+		       const std::string& possibleValuesString = A2STR::NIL,
+		       bool hidden = false):
+    NameMatchOptionHandler(optName, description, defaultValue, hidden),
+    _possibleValuesString(possibleValuesString) {}
 
   virtual ~DefaultOptionHandler() {}
 
@@ -193,16 +285,27 @@ public:
   {
     option->put(_optName, optarg);
   }
+
+  virtual std::string createPossibleValuesString() const
+  {
+    return _possibleValuesString;
+  }
 };
 
 class CumulativeOptionHandler : public NameMatchOptionHandler {
 private:
   std::string _delim;
+
+  std::string _possibleValuesString;
 public:
   CumulativeOptionHandler(const std::string& optName,
-			  const std::string& delim):
-    NameMatchOptionHandler(optName),
-    _delim(delim) {}
+			  const std::string& description,
+			  const std::string& defaultValue,
+			  const std::string& delim,
+			  const std::string& possibleValuesString = A2STR::NIL):
+    NameMatchOptionHandler(optName, description, defaultValue),
+    _delim(delim),
+    _possibleValuesString(possibleValuesString) {}
 
   virtual ~CumulativeOptionHandler() {}
 
@@ -212,35 +315,51 @@ public:
     value += optarg+_delim;
     option->put(_optName, value);
   }
+
+  virtual std::string createPossibleValuesString() const
+  {
+    return _possibleValuesString;
+  }
 };
 
 class ParameterOptionHandler : public NameMatchOptionHandler {
 private:
   std::deque<std::string> _validParamValues;
 public:
-  ParameterOptionHandler(const std::string& optName, const std::deque<std::string>& validParamValues):
-    NameMatchOptionHandler(optName), _validParamValues(validParamValues) {}
+  ParameterOptionHandler(const std::string& optName,
+			 const std::string& description,
+			 const std::string& defaultValue,
+			 const std::deque<std::string>& validParamValues):
+    NameMatchOptionHandler(optName, description, defaultValue),
+    _validParamValues(validParamValues) {}
 
-  ParameterOptionHandler(const std::string& optName, const std::string& validParamValue):
-    NameMatchOptionHandler(optName)
+  ParameterOptionHandler(const std::string& optName,
+			 const std::string& description,
+			 const std::string& defaultValue,
+			 const std::string& validParamValue):
+    NameMatchOptionHandler(optName, description, defaultValue)
   {
     _validParamValues.push_back(validParamValue);
   }
 
   ParameterOptionHandler(const std::string& optName,
+			 const std::string& description,
+			 const std::string& defaultValue,
 			 const std::string& validParamValue1,
 			 const std::string& validParamValue2):
-    NameMatchOptionHandler(optName)
+    NameMatchOptionHandler(optName, description, defaultValue)
   {
     _validParamValues.push_back(validParamValue1);
     _validParamValues.push_back(validParamValue2);
   }
 
   ParameterOptionHandler(const std::string& optName,
+			 const std::string& description,
+			 const std::string& defaultValue,
 			 const std::string& validParamValue1,
 			 const std::string& validParamValue2,
 			 const std::string& validParamValue3):
-    NameMatchOptionHandler(optName)
+    NameMatchOptionHandler(optName, description, defaultValue)
   {
     _validParamValues.push_back(validParamValue1);
     _validParamValues.push_back(validParamValue2);
@@ -268,6 +387,14 @@ public:
       option->put(_optName, optarg);
     }
   }
+
+  virtual std::string createPossibleValuesString() const
+  {
+    std::stringstream s;
+    std::copy(_validParamValues.begin(), _validParamValues.end(),
+	      std::ostream_iterator<std::string>(s, ","));
+    return Util::trim(s.str(), ", ");
+  }
 };
 
 class HostPortOptionHandler : public NameMatchOptionHandler {
@@ -277,9 +404,11 @@ private:
   std::string _portOptionName;
 public:
   HostPortOptionHandler(const std::string& optName,
+			const std::string& description,
+			const std::string& defaultValue,
 			const std::string& hostOptionName,
 			const std::string& portOptionName):
-    NameMatchOptionHandler(optName),
+    NameMatchOptionHandler(optName, description, defaultValue),
     _hostOptionName(hostOptionName),
     _portOptionName(portOptionName) {}
 
@@ -302,14 +431,23 @@ public:
     option->put(_hostOptionName, hostname);
     option->put(_portOptionName, Util::uitos(port));
   }
+
+  virtual std::string createPossibleValuesString() const
+  {
+    return "HOST:PORT";
+  }
 };
 
 class HttpProxyOptionHandler : public HostPortOptionHandler {
 public:
   HttpProxyOptionHandler(const std::string& optName,
+			 const std::string& description,
+			 const std::string& defaultValue,
 			 const std::string& hostOptionName,
 			 const std::string& portOptionName):
-    HostPortOptionHandler(optName, hostOptionName, portOptionName) {}
+    HostPortOptionHandler(optName, description, defaultValue,
+			  hostOptionName, portOptionName)
+  {}
 
   virtual ~HttpProxyOptionHandler() {}
 
@@ -320,22 +458,6 @@ public:
   }
 };
 
-class LogOptionHandler : public NameMatchOptionHandler {
-public:
-  LogOptionHandler(const std::string& optName):NameMatchOptionHandler(optName) {}
-
-  virtual ~LogOptionHandler() {}
-
-  virtual void parseArg(Option* option, const std::string& optarg)
-  {
-    if("-" == optarg) {
-      option->put(PREF_STDOUT_LOG, V_TRUE);
-    } else {
-      option->put(PREF_LOG, optarg);
-    }
-  }
-};
-
 } // namespace aria2
 
 #endif // _D_OPTION_HANDLER_IMPL_H_

+ 105 - 0
src/OptionParser.cc

@@ -37,6 +37,7 @@
 #include "OptionHandlerImpl.h"
 #include "Option.h"
 #include "A2STR.h"
+#include "a2functional.h"
 #include <istream>
 #include <utility>
 
@@ -73,4 +74,108 @@ void OptionParser::setOptionHandlers(const std::deque<SharedHandle<OptionHandler
   _optionHandlers = optionHandlers;
 }
 
+void OptionParser::addOptionHandler
+(const SharedHandle<OptionHandler>& optionHandler)
+{
+  _optionHandlers.push_back(optionHandler);
+}
+
+void OptionParser::parseDefaultValues(Option* option) const
+{
+  for(std::deque<SharedHandle<OptionHandler> >::const_iterator i =
+	_optionHandlers.begin(); i != _optionHandlers.end(); ++i) {
+    if(!(*i)->getDefaultValue().empty()) {
+      (*i)->parse(option, (*i)->getDefaultValue());
+    }
+  }
+}
+
+class FindByTag :
+  public std::unary_function<SharedHandle<OptionHandler>, bool> {
+private:
+  std::string _tag;
+public:
+  FindByTag(const std::string& tag):_tag(tag) {}
+
+  bool operator()(const SharedHandle<OptionHandler>& optionHandler) const
+  {
+    return !optionHandler->isHidden() && optionHandler->hasTag(_tag);
+  }
+};
+
+std::deque<SharedHandle<OptionHandler> >
+OptionParser::findByTag(const std::string& tag) const
+{
+  std::deque<SharedHandle<OptionHandler> > result;
+  std::remove_copy_if(_optionHandlers.begin(), _optionHandlers.end(),
+		      std::back_inserter(result),
+		      std::not1(FindByTag(tag)));
+  return result;
+}
+
+class FindByNameSubstring :
+  public std::unary_function<SharedHandle<OptionHandler> , bool> {
+private:
+  std::string _substring;
+public:
+  FindByNameSubstring(const std::string& substring):_substring(substring) {}
+
+  bool operator()(const SharedHandle<OptionHandler>& optionHandler) const
+  {
+    return !optionHandler->isHidden() &&
+      optionHandler->getName().find(_substring) != std::string::npos;
+  }
+};
+
+std::deque<SharedHandle<OptionHandler> >
+OptionParser::findByNameSubstring(const std::string& substring) const
+{
+  std::deque<SharedHandle<OptionHandler> > result;
+  std::remove_copy_if(_optionHandlers.begin(), _optionHandlers.end(),
+		      std::back_inserter(result),
+		      std::not1(FindByNameSubstring(substring)));
+  return result;  
+}
+
+class FindByName :
+  public std::unary_function<SharedHandle<OptionHandler> , bool> {
+private:
+  std::string _name;
+public:
+  FindByName(const std::string& name):_name(name) {}
+
+  bool operator()(const SharedHandle<OptionHandler>& optionHandler) const
+  {
+    return !optionHandler->isHidden() && optionHandler->getName() == _name;
+  }
+};
+
+std::deque<SharedHandle<OptionHandler> > OptionParser::findAll() const
+{
+  std::deque<SharedHandle<OptionHandler> > result;
+  std::remove_copy_if(_optionHandlers.begin(), _optionHandlers.end(),
+		      std::back_inserter(result),
+		      mem_fun_sh(&OptionHandler::isHidden));
+  return result;
+}
+
+SharedHandle<OptionHandler>
+OptionParser::findByName(const std::string& name) const
+{
+  std::deque<SharedHandle<OptionHandler> >::const_iterator i =
+    std::find_if(_optionHandlers.begin(), _optionHandlers.end(),
+		 FindByName(name));
+  if(i == _optionHandlers.end()) {
+    return SharedHandle<OptionHandler>();
+  } else {
+    return *i;
+  }
+}
+
+const std::deque<SharedHandle<OptionHandler> >&
+OptionParser::getOptionHandlers() const
+{
+  return _optionHandlers;
+}
+
 } // namespace aria2

+ 22 - 3
src/OptionParser.h

@@ -49,14 +49,33 @@ class OptionHandler;
 class OptionParser {
 private:
   std::deque<SharedHandle<OptionHandler> > _optionHandlers;
+
+  SharedHandle<OptionHandler>
+  getOptionHandlerByName(const std::string& optName);
 public:
   ~OptionParser() {}
 
-  SharedHandle<OptionHandler> getOptionHandlerByName(const std::string& optName);
-
   void parse(Option* option, std::istream& ios);
 
-  void setOptionHandlers(const std::deque<SharedHandle<OptionHandler> >& optionHandlers);
+  void parseDefaultValues(Option* option) const;
+
+  void setOptionHandlers
+  (const std::deque<SharedHandle<OptionHandler> >& optionHandlers);
+
+  void addOptionHandler(const SharedHandle<OptionHandler>& optionHandler);
+
+  std::deque<SharedHandle<OptionHandler> >
+  findByTag(const std::string& tag) const;
+
+  std::deque<SharedHandle<OptionHandler> >
+  findByNameSubstring(const std::string& substring) const;
+
+  std::deque<SharedHandle<OptionHandler> > findAll() const;
+
+  SharedHandle<OptionHandler>
+  findByName(const std::string& name) const;
+
+  const std::deque<SharedHandle<OptionHandler> >& getOptionHandlers() const;
 };
 
 typedef SharedHandle<OptionParser> OptionParserHandle;

+ 0 - 121
src/TagContainer.cc

@@ -1,121 +0,0 @@
-/* <!-- 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"
-#include <algorithm>
-
-namespace aria2 {
-
-TagContainer::TagContainer() {}
-
-TagContainer::TagContainer(const TaggedItems& items):
-  _taggedItems(items) {}
-
-TagContainer::~TagContainer() {}
-
-class SingleTagSearch {
-private:
-  std::string _tag;
-
-  TaggedItems _result;
-public:
-  SingleTagSearch(const std::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 std::string& tag) const
-{
-  return std::for_each(_taggedItems.begin(), _taggedItems.end(), SingleTagSearch(tag)).getResult();
-}
-
-class NameMatchForward {
-private:
-  std::string _name;
-
-  TaggedItems _result;
-public:
-  NameMatchForward(const std::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 std::string& name) const
-{
-  return std::for_each(_taggedItems.begin(), _taggedItems.end(), NameMatchForward(name)).getResult();
-}
-
-TaggedItemHandle TagContainer::nameMatch(const std::string& name) const
-{
-  TaggedItems::const_iterator itr = std::find(_taggedItems.begin(), _taggedItems.end(), TaggedItemHandle(new TaggedItem(name)));
-  if(itr == _taggedItems.end()) {
-    return SharedHandle<TaggedItem>();
-  } else {
-    return *itr;
-  }
-}
-
-const TaggedItems& TagContainer::getAllItems() const
-{
-  return _taggedItems;
-}
-
-void TagContainer::addItem(const TaggedItemHandle& item)
-{
-  _taggedItems.push_back(item);
-}
-
-} // namespace aria2

+ 0 - 71
src/TagContainer.h

@@ -1,71 +0,0 @@
-/* <!-- 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"
-#include "SharedHandle.h"
-#include <deque>
-
-namespace aria2 {
-
-class TaggedItem;
-
-class TagContainer {
-private:
-  std::deque<SharedHandle<TaggedItem> > _taggedItems;
-public:
-  TagContainer();
-
-  TagContainer(const std::deque<SharedHandle<TaggedItem> >& items);
-
-  ~TagContainer();
-  
-  void addItem(const SharedHandle<TaggedItem>& item);
-
-  std::deque<SharedHandle<TaggedItem> > search(const std::string& tag) const;
-
-  std::deque<SharedHandle<TaggedItem> > nameMatchForward(const std::string& name) const;
-
-  SharedHandle<TaggedItem> nameMatch(const std::string& name) const;
-
-  const std::deque<SharedHandle<TaggedItem> >& getAllItems() const;
-};
-
-typedef SharedHandle<TagContainer> TagContainerHandle;
-
-} // namespace aria2
-
-#endif // _D_TAG_CONTAINER_H_

+ 0 - 91
src/TaggedItem.cc

@@ -1,91 +0,0 @@
-/* <!-- 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 "a2functional.h"
-#include "A2STR.h"
-#include <algorithm>
-#include <ostream>
-
-namespace aria2 {
-
-std::string TaggedItem::toTagString() const
-{
-  if(_tags.size()) {
-    std::string s(*_tags.begin());
-    for(std::deque<std::string>::const_iterator i = _tags.begin()+1;
-	i != _tags.end(); ++i) {
-      s += ","+(*i);
-    }
-    return s;
-  } else {
-    return A2STR::NIL;
-  }
-}
-
-bool TaggedItem::hasTag(const std::string& tag) const
-{
-  return std::find(_tags.begin(), _tags.end(), tag) != _tags.end();
-}
-
-bool TaggedItem::operator<(const TaggedItem& item) const
-{
-  return _name < item._name;
-}
-
-bool TaggedItem::operator==(const TaggedItem& item) const
-{
-  return _name == item._name;
-}
-
-std::string TaggedItem::toString() const
-{
-  return toTagString();
-}
-
-std::ostream&
-operator<<(std::ostream& o, const TaggedItem& item)
-{
-  o << item.toString();
-  return o;
-}
-
-std::ostream&
-operator<<(std::ostream& o, const SharedHandle<TaggedItem>& item)
-{
-  o << (*item.get()).toString();
-  return o;
-}
-
-} // namespace aria2

+ 0 - 88
src/TaggedItem.h

@@ -1,88 +0,0 @@
-/* <!-- 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"
-#include "SharedHandle.h"
-#include <string>
-#include <deque>
-#include <iosfwd>
-
-namespace aria2 {
-
-class TaggedItem {
-private:
-  std::string _name;
-
-  std::deque<std::string> _tags;
-public:
-  TaggedItem(const std::string& name):_name(name) {}
-
-  virtual ~TaggedItem() {}
-
-  void addTag(const std::string& tag)
-  {
-    _tags.push_back(tag);
-  }
-
-  std::string toTagString() const;
-
-  bool hasTag(const std::string& tag) const;
-
-  const std::string& getName() const
-  {
-    return _name;
-  }
-
-  bool operator<(const TaggedItem& item) const;
-
-  bool operator==(const TaggedItem& item) const;
-
-  virtual std::string toString() const;
-
-  friend std::ostream&
-  operator<<(std::ostream& o, const TaggedItem& item);
-
-  friend std::ostream&
-  operator<<(std::ostream& o, const SharedHandle<TaggedItem>& item);
-};
-
-typedef SharedHandle<TaggedItem> TaggedItemHandle;
-typedef std::deque<TaggedItemHandle> TaggedItems;
-
-} // namespace aria2
-
-#endif // _D_TAGGED_ITEM_H_

+ 2 - 2
src/main.cc

@@ -348,9 +348,9 @@ int main(int argc, char* argv[])
 
   SimpleRandomizer::init();
   BitfieldManFactory::setDefaultRandomizer(SimpleRandomizer::getInstance());
-  if(op->getAsBool(PREF_STDOUT_LOG)) {
+  if(op->get(PREF_LOG) == "-") {
     LogFactory::setLogFile(DEV_STDOUT);
-  } else if(op->get(PREF_LOG).size()) {
+  } else if(!op->get(PREF_LOG).empty()) {
     LogFactory::setLogFile(op->get(PREF_LOG));
   } else {
     LogFactory::setLogFile(DEV_NULL);

+ 25 - 109
src/option_processing.cc

@@ -58,7 +58,7 @@ extern int optind, opterr, optopt;
 namespace aria2 {
 
 extern void showVersion();
-extern void showUsage(const std::string& category, const Option* option);
+extern void showUsage(const std::string& keyword, const OptionParser& oparser);
 
 static std::string toBoolArg(const char* optarg)
 {
@@ -71,110 +71,25 @@ static std::string toBoolArg(const char* optarg)
   return arg;
 }
 
-Option* createDefaultOption()
-{
-  Option* op = new Option();
-  op->put(PREF_STDOUT_LOG, V_FALSE);
-  op->put(PREF_DIR, ".");
-  op->put(PREF_SPLIT, "5");
-  op->put(PREF_DAEMON, V_FALSE);
-  op->put(PREF_SEGMENT_SIZE, Util::itos((int32_t)(1024*1024)));
-  op->put(PREF_LISTEN_PORT, "6881-6999");
-  op->put(PREF_METALINK_SERVERS, "5");
-  op->put(PREF_FOLLOW_TORRENT,
-#ifdef ENABLE_BITTORRENT
-	  V_TRUE
-#else
-	  V_FALSE
-#endif // ENABLE_BITTORRENT
-	  );
-  op->put(PREF_FOLLOW_METALINK,
-#ifdef ENABLE_METALINK
-	  V_TRUE
-#else
-	  V_FALSE
-#endif // ENABLE_METALINK
-	  );
-  op->put(PREF_RETRY_WAIT, "5");
-  op->put(PREF_TIMEOUT, "60");
-  op->put(PREF_DNS_TIMEOUT, "30");
-  op->put(PREF_CONNECT_TIMEOUT, "60");
-  op->put(PREF_PEER_CONNECTION_TIMEOUT, "20");
-  op->put(PREF_BT_TIMEOUT, "180");
-  op->put(PREF_BT_REQUEST_TIMEOUT, "60");
-  op->put(PREF_BT_KEEP_ALIVE_INTERVAL, "120");
-  op->put(PREF_MIN_SEGMENT_SIZE, "1048576");// 1M
-  op->put(PREF_MAX_TRIES, "5");
-  op->put(PREF_HTTP_AUTH_SCHEME, V_BASIC);
-  op->put(PREF_HTTP_PROXY_METHOD, V_TUNNEL);
-  op->put(PREF_FTP_TYPE, V_BINARY);
-  op->put(PREF_FTP_VIA_HTTP_PROXY, V_TUNNEL);
-  op->put(PREF_AUTO_SAVE_INTERVAL, "60");
-  op->put(PREF_DIRECT_FILE_MAPPING, V_TRUE);
-  op->put(PREF_LOWEST_SPEED_LIMIT, "0");
-  op->put(PREF_MAX_DOWNLOAD_LIMIT, "0");
-  op->put(PREF_MAX_UPLOAD_LIMIT, "0");
-  op->put(PREF_STARTUP_IDLE_TIME, "10");
-  op->put(PREF_TRACKER_MAX_TRIES, "10");
-  op->put(PREF_FILE_ALLOCATION, V_PREALLOC);
-  op->put(PREF_NO_FILE_ALLOCATION_LIMIT, "5242880"); // 5MiB
-  op->put(PREF_ALLOW_OVERWRITE, V_FALSE);
-  op->put(PREF_REALTIME_CHUNK_CHECKSUM, V_TRUE);
-  op->put(PREF_CHECK_INTEGRITY, V_FALSE);
-  op->put(PREF_NETRC_PATH, Util::getHomeDir()+"/.netrc");
-  op->put(PREF_CONTINUE, V_FALSE);
-  op->put(PREF_USER_AGENT, "aria2");
-  op->put(PREF_NO_NETRC, V_FALSE);
-  op->put(PREF_MAX_CONCURRENT_DOWNLOADS, "5");
-  op->put(PREF_DIRECT_DOWNLOAD_TIMEOUT, "300");
-  op->put(PREF_FORCE_SEQUENTIAL, V_FALSE);
-  op->put(PREF_AUTO_FILE_RENAMING, V_TRUE);
-  op->put(PREF_PARAMETERIZED_URI, V_FALSE);
-  op->put(PREF_ENABLE_HTTP_KEEP_ALIVE, V_TRUE);
-  op->put(PREF_ENABLE_HTTP_PIPELINING, V_FALSE);
-  op->put(PREF_MAX_HTTP_PIPELINING, "2");
-  op->put(PREF_SEED_RATIO, "1.0");
-  op->put(PREF_ENABLE_DIRECT_IO, V_FALSE);
-  op->put(PREF_ALLOW_PIECE_LENGTH_CHANGE, V_FALSE);
-  op->put(PREF_METALINK_PREFERRED_PROTOCOL, V_NONE);
-  op->put(PREF_METALINK_ENABLE_UNIQUE_PROTOCOL, V_TRUE);
-  op->put(PREF_ENABLE_PEER_EXCHANGE, V_TRUE);
-  op->put(PREF_ENABLE_DHT, V_FALSE);
-  op->put(PREF_DHT_LISTEN_PORT, "6881-6999");
-  op->put(PREF_DHT_FILE_PATH, Util::getHomeDir()+"/.aria2/dht.dat");
-  op->put(PREF_BT_MIN_CRYPTO_LEVEL, V_PLAIN);
-  op->put(PREF_BT_REQUIRE_CRYPTO, V_FALSE);
-  op->put(PREF_BT_REQUEST_PEER_SPEED_LIMIT, "51200");
-  op->put(PREF_BT_MAX_OPEN_FILES, "100");
-  op->put(PREF_BT_SEED_UNVERIFIED, V_FALSE);
-  op->put(PREF_QUIET, V_FALSE);
-  op->put(PREF_STOP, "0");
-#ifdef ENABLE_ASYNC_DNS
-  op->put(PREF_ASYNC_DNS, V_TRUE);
-#else
-  op->put(PREF_ASYNC_DNS, V_FALSE);
-#endif // ENABLE_ASYNC_DNS
-  op->put(PREF_FTP_REUSE_CONNECTION, V_TRUE);
-  op->put(PREF_SUMMARY_INTERVAL, "60");
-  op->put(PREF_LOG_LEVEL, V_DEBUG);
-  op->put(PREF_URI_SELECTOR, V_INORDER);
-  op->put(PREF_SERVER_STAT_TIMEOUT, "86400");// 1day
-  op->put(PREF_REMOTE_TIME, V_FALSE);
-  op->put(PREF_MAX_FILE_NOT_FOUND, "0");
-  return op;
-}
-
 Option* option_processing(int argc, char* const argv[])
 {
   std::stringstream cmdstream;
   int32_t c;
-  Option* op = createDefaultOption();
+  Option* op = new Option();
 
   // following options are not parsed by OptionHandler and not stored in Option.
   bool noConf = false;
-  std::string defaultCfname = Util::getHomeDir()+"/.aria2/aria2.conf";
   std::string ucfname;
 
+  OptionParser oparser;
+  oparser.setOptionHandlers(OptionHandlerFactory::createOptionHandlers());
+  try {
+    oparser.parseDefaultValues(op);
+  } catch(Exception& e) {
+    std::cerr << e.stackTrace();
+    exit(EXIT_FAILURE);
+  }
+
   while(1) {
     int optIndex = 0;
     int lopt;
@@ -575,25 +490,23 @@ Option* option_processing(int argc, char* const argv[])
 	} else {
 	  category = optarg;
 	}
-	showUsage(category, createDefaultOption());
+	showUsage(category, oparser);
 	exit(EXIT_SUCCESS);
       }
     default:
-      showUsage(TAG_HELP, op);
+      showUsage(TAG_HELP, oparser);
       exit(EXIT_FAILURE);
     }
   }
 
   {
-    OptionParser oparser;
     oparser.setOptionHandlers(OptionHandlerFactory::createOptionHandlers());
     if(!noConf) {
-      std::string cfname;
-      if(ucfname.size()) {
-	cfname = ucfname;
-      } else {
-	cfname = defaultCfname;
-      }
+      std::string cfname = 
+	ucfname.empty() ?
+	oparser.findByName(PREF_CONF_PATH)->getDefaultValue():
+	ucfname;
+
       if(File(cfname).isFile()) {
 	std::ifstream cfstream(cfname.c_str());
 	try {
@@ -603,16 +516,19 @@ Option* option_processing(int argc, char* const argv[])
 		    << e.stackTrace() << std::endl;
 	  exit(EXIT_FAILURE);
 	}
-      } else if(ucfname.size()) {
-	std::cout << StringFormat("Configuration file %s is not found.", cfname.c_str())
+      } else if(!ucfname.empty()) {
+	std::cerr << StringFormat("Configuration file %s is not found.",
+				  cfname.c_str())
 		  << "\n";
+	showUsage(TAG_HELP, oparser);
+	exit(EXIT_FAILURE);
       }
     }
     try {
       oparser.parse(op, cmdstream);
     } catch(Exception& e) {
       std::cerr << e.stackTrace() << std::endl;
-      showUsage(TAG_HELP, op);
+      showUsage(TAG_HELP, oparser);
       exit(EXIT_FAILURE);
     }
   }
@@ -632,7 +548,7 @@ Option* option_processing(int argc, char* const argv[])
      !op->defined(PREF_INPUT_FILE)) {
     if(optind == argc) {
       std::cerr << MSG_URI_REQUIRED << std::endl;
-      showUsage(TAG_HELP, op);
+      showUsage(TAG_HELP, oparser);
       exit(EXIT_FAILURE);
     }
   }

+ 28 - 53
src/usage_text.h

@@ -51,13 +51,11 @@ _(" -s, --split=N                Download a file using N connections. If more\n"
   "                              simultaneously. Please see -j option too.")
 #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")
+  "                              has occured.")
 #define TEXT_TIMEOUT \
-_(" -t, --timeout=SEC            Set timeout in seconds. Default: 60")
+_(" -t, --timeout=SEC            Set timeout in seconds.")
 #define TEXT_MAX_TRIES \
-_(" -m, --max-tries=N            Set number of tries. 0 means unlimited.\n"\
-  "                              Default: 5")
+_(" -m, --max-tries=N            Set number of tries. 0 means unlimited.")
 #define TEXT_HTTP_PROXY \
 _(" --http-proxy=HOST:PORT       Use HTTP proxy server. This affects all URLs.")
 #define TEXT_HTTP_USER \
@@ -69,50 +67,38 @@ _(" --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")
+_(" --http-proxy-method=METHOD   Set the method to use in proxy request.")
 #define TEXT_HTTP_AUTH_SCHEME \
 _(" --http-auth-scheme=SCHEME    Set HTTP authentication scheme. Currently, basic\n"\
-  "                              is the only supported scheme.\n"\
-  "                              Default: basic")
+  "                              is the only supported scheme.")
 #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")
+_(" --ftp-user=USER              Set FTP user. This affects all URLs.")
 #define TEXT_FTP_PASSWD \
-_(" --ftp-passwd=PASSWD          Set FTP password. This affects all URLs.\n"\
-  "                              Default: ARIA2USER@")
+_(" --ftp-passwd=PASSWD          Set FTP password. This affects all URLs.")
 #define TEXT_FTP_TYPE \
-_(" --ftp-type=TYPE              Set FTP transfer type. TYPE is either 'binary'\n"\
-  "                              or 'ascii'.\n"\
-  "                              Default: binary")
+_(" --ftp-type=TYPE              Set FTP transfer type.")
 #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")
+_(" --ftp-via-http-proxy=METHOD  Use HTTP proxy in FTP.")
 #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")
+  "                              This option does not affect BitTorrent downloads.")
 #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")
+  "                              You can append K or M(1K = 1024, 1M = 1024K).")
 #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")
+_(" --file-allocation=METHOD     Specify file allocation method.\n"\
+  "                              'none' doesn't pre-allocate file space. 'prealloc'\n"\
+  "                              pre-allocates file space before download begins.\n"\
+  "                              This may take some time depending on the size of\n"\
+  "                              the file.")
 #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"\
@@ -124,8 +110,7 @@ _(" --enable-direct-io[=true|false] Enable directI/O, which lowers cpu usage whi
 #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")
+  "                              doesn't exist.")
 #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"\
@@ -134,15 +119,13 @@ _(" --allow-piece-length-change=true|false If false is given, aria2 aborts downl
 #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")
+  "                              the usual command-line download utilities.")
 #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")
+  "                              appended.")
 #define TEXT_PARAMETERIZED_URI \
 _(" -P, --parameterized-uri[=true|false] Enable parameterized URI support.\n"\
   "                              You can specify set of parts:\n"\
@@ -153,25 +136,21 @@ _(" -P, --parameterized-uri[=true|false] Enable parameterized URI support.\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")
+  "                              required.")
 #define TEXT_ENABLE_HTTP_KEEP_ALIVE \
 _(" --enable-http-keep-alive[=true|false] Enable HTTP/1.1 persistent connection.")
 #define TEXT_ENABLE_HTTP_PIPELINING \
-_(" --enable-http-pipelining[=true|false] Enable HTTP/1.1 pipelining.\n"\
-  "                              Default: false")
+_(" --enable-http-pipelining[=true|false] Enable HTTP/1.1 pipelining.")
 #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")
+  "                              of a file.")
 #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")
+  "                              on affects Metalink mode with chunk checksums.")
 #define TEXT_CONTINUE \
 _(" -c, --continue               Continue downloading a partially downloaded\n"\
   "                              file. Use this option to resume a download\n"\
@@ -221,8 +200,7 @@ _(" --follow-torrent=true|false|mem If true or mem is specified, when a file\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")
+  "                              mentioned in .torrent file.")
 #define TEXT_LISTEN_PORT \
 _(" --listen-port=PORT...        Set TCP port number for BitTorrent downloads.\n"\
   "                              Multiple ports can be specified by using ',',\n"\
@@ -232,8 +210,7 @@ _(" --listen-port=PORT...        Set TCP port number for BitTorrent downloads.\n
 #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")
+  "                              You can append K or M(1K = 1024, 1M = 1024K).")
 #define TEXT_SEED_TIME \
 _(" --seed-time=MINUTES          Specify seeding time in minutes. Also see the\n"\
   "                              --seed-ratio option.")
@@ -251,8 +228,7 @@ _(" --peer-id-prefix=PEERI_ID_PREFIX Specify the prefix of peer ID. The peer ID
   "                              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-")
+  "                              added to make it's length 20 bytes.")
 #define TEXT_ENABLE_PEER_EXCHANGE \
 _(" --enable-peer-exchange[=true|false] Enable Peer Exchange extension.")
 #define TEXT_ENABLE_DHT \
@@ -330,7 +306,7 @@ _(" -h, --help[=CATEGORY]        Print usage and exit.\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 using a given word, in forward match\n"\
+  "                              option name using a given word in middle match\n"\
   "                              and print the result.")
 #define TEXT_NO_CONF \
 _(" --no-conf                    Disable loading aria2.conf file.")
@@ -373,8 +349,7 @@ _(" --max-file-not-found=NUM     If aria2 recieves `file not found' status from
   "                              This options is only effective only when using\n"\
   "                              HTTP/FTP servers.")
 #define TEXT_URI_SELECTOR \
-_(" --uri-selector=SELECTOR      Specify URI selection algorithm. Possible values\n"\
-  "                              are 'inorder' and 'feedback'.\n"\
+_(" --uri-selector=SELECTOR      Specify URI selection algorithm.\n"\
   "                              If 'inorder' is given, URI is tried in the order\n"\
   "                              appeared in the URI list.\n"\
   "                              If 'feedback' is given, aria2 uses download speed\n"\

+ 36 - 29
src/version_usage.cc

@@ -39,12 +39,11 @@
 #ifdef ENABLE_MESSAGE_DIGEST
 # include "messageDigest.h"
 #endif // ENABLE_MESSAGE_DIGEST
-#include "TagContainer.h"
-#include "HelpItem.h"
-#include "HelpItemFactory.h"
 #include "help_tags.h"
 #include "prefs.h"
 #include "StringFormat.h"
+#include "OptionParser.h"
+#include "OptionHandler.h"
 #include <iostream>
 #include <iterator>
 #include <algorithm>
@@ -73,42 +72,50 @@ void showVersion() {
 	    << std::endl;
 }
 
-void showUsage(const std::string& category, const Option* option) {
-  std::cout << StringFormat(_("Usage: %s [OPTIONS] [URL | TORRENT_FILE | METALINK_FILE]..."), PACKAGE_NAME) << "\n"
+void showUsage(const std::string& keyword, const OptionParser& oparser) {
+  std::cout << StringFormat(_("Usage: %s [OPTIONS] [URL | TORRENT_FILE |"
+			      " METALINK_FILE]..."), PACKAGE_NAME) << "\n"
 	    << "\n";
 
-  SharedHandle<TagContainer> tc = HelpItemFactory::createHelpItems(option);
-  std::deque<SharedHandle<TaggedItem> > items =
-    category == V_ALL ? tc->getAllItems() : tc->search(category);
-  if(items.size() > 0) {
-    if(category == V_ALL) {
+  std::deque<SharedHandle<OptionHandler> > handlers =
+    keyword == V_ALL ? oparser.findAll():oparser.findByTag(keyword);
+  if(handlers.empty()) {
+    std::deque<SharedHandle<OptionHandler> > handlers =
+      oparser.findByNameSubstring(keyword);
+    if(!handlers.empty()) {
+      std::cout << StringFormat(_("Printing options whose name includes"
+				  " '%s'."), keyword.c_str())
+		<< "\n"
+		<< _("Options:") << "\n";
+      std::copy(handlers.begin(), handlers.end(),
+		std::ostream_iterator<SharedHandle<OptionHandler> >
+		(std::cout, "\n\n"));
+    } else {
+      std::cout << StringFormat(_("No help category or option name matching"
+				  " with '%s'."), keyword.c_str())
+		<< "\n" << oparser.findByName("help") << "\n";
+    }
+  } else {
+    if(keyword == V_ALL) {
       std::cout << _("Printing all options.");
     } else {
-      std::cout << StringFormat(_("Printing options tagged with '%s'."), category.c_str());
+      std::cout << StringFormat(_("Printing options tagged with '%s'."),
+				keyword.c_str());
       std::cout << "\n";
-      SharedHandle<HelpItem> helpItem
-	(dynamic_pointer_cast<HelpItem>(tc->nameMatch("help")));
-      std::cout << StringFormat(_("See -h option to know other command-line options(%s)."),
-				helpItem->getAvailableValues().c_str());
+      SharedHandle<OptionHandler> help = oparser.findByName("help");
+      std::cout << StringFormat(_("See -h option to know other command-line"
+				  " options(%s)."),
+				help->createPossibleValuesString().c_str());
     }
     std::cout << "\n"
 	      << _("Options:") << "\n";
 
-    std::copy(items.begin(), items.end(), std::ostream_iterator<SharedHandle<TaggedItem> >(std::cout, "\n"));
-
-  } else {
-    std::deque<SharedHandle<TaggedItem> > items = tc->nameMatchForward(category);
-    if(items.size() > 0) {
-      std::cout << StringFormat(_("Printing options whose name starts with '%s'."), category.c_str())
-		<< "\n"
-		<< _("Options:") << "\n";
-      std::copy(items.begin(), items.end(), std::ostream_iterator<SharedHandle<TaggedItem> >(std::cout, "\n"));
-    } else {
-      std::cout << StringFormat(_("No help category or option name matching with '%s'."), category.c_str())
-		<< "\n" << tc->nameMatch("help") << "\n";
-    }
+    std::copy(handlers.begin(), handlers.end(),
+	      std::ostream_iterator<SharedHandle<OptionHandler> >
+	      (std::cout, "\n\n"));
   }
-  if(category == TAG_BASIC) {
+
+  if(keyword == TAG_BASIC) {
     std::cout << "\n"
 	      << "URL, TORRENT_FILE, METALINK_FILE:" << "\n"
 	      << _(" You can specify multiple URLs. Unless you specify -Z option, all URLs must\n"

+ 0 - 43
test/HelpItemTest.cc

@@ -1,43 +0,0 @@
-#include "HelpItem.h"
-#include <sstream>
-#include <cppunit/extensions/HelperMacros.h>
-
-namespace aria2 {
-
-class HelpItemTest:public CppUnit::TestFixture {
-
-  CPPUNIT_TEST_SUITE(HelpItemTest);
-  CPPUNIT_TEST(testToString);
-  CPPUNIT_TEST_SUITE_END();
-private:
-
-public:
-  void setUp() {}
-
-  void testToString();
-};
-
-
-CPPUNIT_TEST_SUITE_REGISTRATION(HelpItemTest);
-
-void HelpItemTest::testToString()
-{
-  std::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");
-  
-  std::stringstream s;
-  s << item.toString();
-
-  CPPUNIT_ASSERT_EQUAL(usage+"\n"+
-		       "                              Available Values: 0,5,10\n"
-		       "                              Default: 5\n"
-		       "                              Tags: basic,http,ftp",
-		       s.str());
-}
-
-} // namespace aria2

+ 2 - 4
test/Makefile.am

@@ -4,9 +4,6 @@ aria2c_SOURCES = AllTest.cc\
 	TestUtil.cc TestUtil.h\
 	SocketCoreTest.cc\
 	array_funTest.cc\
-	HelpItemTest.cc\
-	TaggedItemTest.cc\
-	TagContainerTest.cc\
 	Base64Test.cc\
 	SequenceTest.cc\
 	a2functionalTest.cc\
@@ -63,7 +60,8 @@ aria2c_SOURCES = AllTest.cc\
 	CookieStorageTest.cc\
 	TimeTest.cc\
 	CopyDiskAdaptorTest.cc\
-	FtpConnectionTest.cc
+	FtpConnectionTest.cc\
+	OptionParserTest.cc
 
 if HAVE_LIBZ
 aria2c_SOURCES += GZipDecoderTest.cc

+ 14 - 18
test/Makefile.in

@@ -169,8 +169,7 @@ CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
 am__EXEEXT_1 = aria2c$(EXEEXT)
 am__aria2c_SOURCES_DIST = AllTest.cc TestUtil.cc TestUtil.h \
-	SocketCoreTest.cc array_funTest.cc HelpItemTest.cc \
-	TaggedItemTest.cc TagContainerTest.cc Base64Test.cc \
+	SocketCoreTest.cc array_funTest.cc Base64Test.cc \
 	SequenceTest.cc a2functionalTest.cc FileEntryTest.cc \
 	PieceTest.cc SegmentTest.cc GrowSegmentTest.cc \
 	SingleFileAllocationIteratorTest.cc \
@@ -195,8 +194,8 @@ am__aria2c_SOURCES_DIST = AllTest.cc TestUtil.cc TestUtil.h \
 	ServerStatTest.cc NsCookieParserTest.cc \
 	DirectDiskAdaptorTest.cc CookieTest.cc CookieStorageTest.cc \
 	TimeTest.cc CopyDiskAdaptorTest.cc FtpConnectionTest.cc \
-	GZipDecoderTest.cc Sqlite3MozCookieParserTest.cc \
-	MessageDigestHelperTest.cc \
+	OptionParserTest.cc GZipDecoderTest.cc \
+	Sqlite3MozCookieParserTest.cc MessageDigestHelperTest.cc \
 	IteratableChunkChecksumValidatorTest.cc \
 	IteratableChecksumValidatorTest.cc BtAllowedFastMessageTest.cc \
 	BtBitfieldMessageTest.cc BtCancelMessageTest.cc \
@@ -335,11 +334,10 @@ am__aria2c_SOURCES_DIST = AllTest.cc TestUtil.cc TestUtil.h \
 @ENABLE_METALINK_TRUE@	MetalinkProcessorTest.$(OBJEXT)
 am_aria2c_OBJECTS = AllTest.$(OBJEXT) TestUtil.$(OBJEXT) \
 	SocketCoreTest.$(OBJEXT) array_funTest.$(OBJEXT) \
-	HelpItemTest.$(OBJEXT) TaggedItemTest.$(OBJEXT) \
-	TagContainerTest.$(OBJEXT) Base64Test.$(OBJEXT) \
-	SequenceTest.$(OBJEXT) a2functionalTest.$(OBJEXT) \
-	FileEntryTest.$(OBJEXT) PieceTest.$(OBJEXT) \
-	SegmentTest.$(OBJEXT) GrowSegmentTest.$(OBJEXT) \
+	Base64Test.$(OBJEXT) SequenceTest.$(OBJEXT) \
+	a2functionalTest.$(OBJEXT) FileEntryTest.$(OBJEXT) \
+	PieceTest.$(OBJEXT) SegmentTest.$(OBJEXT) \
+	GrowSegmentTest.$(OBJEXT) \
 	SingleFileAllocationIteratorTest.$(OBJEXT) \
 	DefaultBtProgressInfoFileTest.$(OBJEXT) \
 	SingleFileDownloadContextTest.$(OBJEXT) \
@@ -368,8 +366,9 @@ am_aria2c_OBJECTS = AllTest.$(OBJEXT) TestUtil.$(OBJEXT) \
 	NsCookieParserTest.$(OBJEXT) DirectDiskAdaptorTest.$(OBJEXT) \
 	CookieTest.$(OBJEXT) CookieStorageTest.$(OBJEXT) \
 	TimeTest.$(OBJEXT) CopyDiskAdaptorTest.$(OBJEXT) \
-	FtpConnectionTest.$(OBJEXT) $(am__objects_1) $(am__objects_2) \
-	$(am__objects_3) $(am__objects_4) $(am__objects_5)
+	FtpConnectionTest.$(OBJEXT) OptionParserTest.$(OBJEXT) \
+	$(am__objects_1) $(am__objects_2) $(am__objects_3) \
+	$(am__objects_4) $(am__objects_5)
 aria2c_OBJECTS = $(am_aria2c_OBJECTS)
 am__DEPENDENCIES_1 =
 aria2c_DEPENDENCIES = ../src/libaria2c.a $(am__DEPENDENCIES_1)
@@ -566,8 +565,7 @@ target_vendor = @target_vendor@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 aria2c_SOURCES = AllTest.cc TestUtil.cc TestUtil.h SocketCoreTest.cc \
-	array_funTest.cc HelpItemTest.cc TaggedItemTest.cc \
-	TagContainerTest.cc Base64Test.cc SequenceTest.cc \
+	array_funTest.cc Base64Test.cc SequenceTest.cc \
 	a2functionalTest.cc FileEntryTest.cc PieceTest.cc \
 	SegmentTest.cc GrowSegmentTest.cc \
 	SingleFileAllocationIteratorTest.cc \
@@ -592,8 +590,8 @@ aria2c_SOURCES = AllTest.cc TestUtil.cc TestUtil.h SocketCoreTest.cc \
 	ServerStatTest.cc NsCookieParserTest.cc \
 	DirectDiskAdaptorTest.cc CookieTest.cc CookieStorageTest.cc \
 	TimeTest.cc CopyDiskAdaptorTest.cc FtpConnectionTest.cc \
-	$(am__append_1) $(am__append_2) $(am__append_3) \
-	$(am__append_4) $(am__append_5)
+	OptionParserTest.cc $(am__append_1) $(am__append_2) \
+	$(am__append_3) $(am__append_4) $(am__append_5)
 
 #aria2c_CXXFLAGS = ${CPPUNIT_CFLAGS} -I../src -I../lib -Wall -D_FILE_OFFSET_BITS=64
 #aria2c_LDFLAGS = ${CPPUNIT_LIBS}
@@ -765,7 +763,6 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GZipDecoderTest.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@
@@ -790,6 +787,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetrcTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NsCookieParserTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OptionHandlerTest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OptionParserTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OptionTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PStringBuildVisitorTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ParameterizedStringParserTest.Po@am__quote@
@@ -818,8 +816,6 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SpeedCalcTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Sqlite3MozCookieParserTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StringFormatTest.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)/TestUtil.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TimeSeedCriteriaTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TimeTest.Po@am__quote@

+ 46 - 28
test/OptionHandlerTest.cc

@@ -24,7 +24,6 @@ class OptionHandlerTest:public CppUnit::TestFixture {
   CPPUNIT_TEST(testFloatNumberOptionHandler_min);
   CPPUNIT_TEST(testFloatNumberOptionHandler_max);
   CPPUNIT_TEST(testFloatNumberOptionHandler_min_max);
-  CPPUNIT_TEST(testLogOptionHandler);
   CPPUNIT_TEST(testHttpProxyOptionHandler);
   CPPUNIT_TEST_SUITE_END();
   
@@ -44,7 +43,6 @@ public:
   void testFloatNumberOptionHandler_min();
   void testFloatNumberOptionHandler_max();
   void testFloatNumberOptionHandler_min_max();
-  void testLogOptionHandler();
   void testHttpProxyOptionHandler();
 };
 
@@ -74,6 +72,8 @@ void OptionHandlerTest::testBooleanOptionHandler()
   } catch(Exception& e) {
     std::cerr << e.stackTrace() << std::endl;
   }
+  CPPUNIT_ASSERT_EQUAL(std::string("true,false"),
+		       handler.createPossibleValuesString());
 }
 
 void OptionHandlerTest::testNumberOptionHandler()
@@ -84,11 +84,13 @@ void OptionHandlerTest::testNumberOptionHandler()
   Option option;
   handler.parse(&option, "0");
   CPPUNIT_ASSERT_EQUAL(std::string("0"), option.get("foo"));
+  CPPUNIT_ASSERT_EQUAL(std::string("*-*"),
+		       handler.createPossibleValuesString());
 }
 
 void OptionHandlerTest::testNumberOptionHandler_min()
 {
-  NumberOptionHandler handler("foo", 1);
+  NumberOptionHandler handler("foo", "", "", 1);
   Option option;
   handler.parse(&option, "1");
   CPPUNIT_ASSERT_EQUAL(std::string("1"), option.get("foo"));
@@ -98,12 +100,13 @@ void OptionHandlerTest::testNumberOptionHandler_min()
   } catch(Exception& e) {
     std::cerr << e.stackTrace() << std::endl;
   }
-
+  CPPUNIT_ASSERT_EQUAL(std::string("1-*"),
+		       handler.createPossibleValuesString());
 }
 
 void OptionHandlerTest::testNumberOptionHandler_max()
 {
-  NumberOptionHandler handler("foo", -1, 100);
+  NumberOptionHandler handler("foo", "", "", -1, 100);
   Option option;
   handler.parse(&option, "100");
   CPPUNIT_ASSERT_EQUAL(std::string("100"), option.get("foo"));
@@ -113,11 +116,13 @@ void OptionHandlerTest::testNumberOptionHandler_max()
   } catch(Exception& e) {
     std::cerr << e.stackTrace() << std::endl;
   }
+  CPPUNIT_ASSERT_EQUAL(std::string("*-100"),
+		       handler.createPossibleValuesString());
 }
 
 void OptionHandlerTest::testNumberOptionHandler_min_max()
 {
-  NumberOptionHandler handler("foo", 1, 100);
+  NumberOptionHandler handler("foo", "", "", 1, 100);
   Option option;
   handler.parse(&option, "1");
   CPPUNIT_ASSERT_EQUAL(std::string("1"), option.get("foo"));
@@ -135,6 +140,8 @@ void OptionHandlerTest::testNumberOptionHandler_min_max()
   } catch(Exception& e) {
     std::cerr << e.stackTrace() << std::endl;
   }
+  CPPUNIT_ASSERT_EQUAL(std::string("1-100"),
+		       handler.createPossibleValuesString());
 }
 
 void OptionHandlerTest::testUnitNumberOptionHandler()
@@ -170,7 +177,7 @@ void OptionHandlerTest::testUnitNumberOptionHandler()
 
 void OptionHandlerTest::testParameterOptionHandler_1argInit()
 {
-  ParameterOptionHandler handler("foo", "value1");
+  ParameterOptionHandler handler("foo", "", "", "value1");
   CPPUNIT_ASSERT(handler.canHandle("foo"));
   CPPUNIT_ASSERT(!handler.canHandle("foobar"));
   Option option;
@@ -182,11 +189,13 @@ void OptionHandlerTest::testParameterOptionHandler_1argInit()
   } catch(Exception& e) {
     std::cerr << e.stackTrace() << std::endl;
   }
+  CPPUNIT_ASSERT_EQUAL(std::string("value1"),
+		       handler.createPossibleValuesString());
 }
 
 void OptionHandlerTest::testParameterOptionHandler_2argsInit()
 {
-  ParameterOptionHandler handler("foo", "value1", "value2");
+  ParameterOptionHandler handler("foo", "", "", "value1", "value2");
   CPPUNIT_ASSERT(handler.canHandle("foo"));
   CPPUNIT_ASSERT(!handler.canHandle("foobar"));
   Option option;
@@ -200,6 +209,8 @@ void OptionHandlerTest::testParameterOptionHandler_2argsInit()
   } catch(Exception& e) {
     std::cerr << e.stackTrace() << std::endl;
   }
+  CPPUNIT_ASSERT_EQUAL(std::string("value1,value2"),
+		       handler.createPossibleValuesString());
 }
 
 void OptionHandlerTest::testParameterOptionHandler_listInit()
@@ -208,7 +219,7 @@ void OptionHandlerTest::testParameterOptionHandler_listInit()
   validValues.push_back("value1");
   validValues.push_back("value2");
 
-  ParameterOptionHandler handler("foo", validValues);
+  ParameterOptionHandler handler("foo", "", "", validValues);
   CPPUNIT_ASSERT(handler.canHandle("foo"));
   CPPUNIT_ASSERT(!handler.canHandle("foobar"));
   Option option;
@@ -222,6 +233,8 @@ void OptionHandlerTest::testParameterOptionHandler_listInit()
   } catch(Exception& e) {
     std::cerr << e.stackTrace() << std::endl;
   }
+  CPPUNIT_ASSERT_EQUAL(std::string("value1,value2"),
+		       handler.createPossibleValuesString());
 }
 
 void OptionHandlerTest::testDefaultOptionHandler()
@@ -234,6 +247,15 @@ void OptionHandlerTest::testDefaultOptionHandler()
   CPPUNIT_ASSERT_EQUAL(std::string("bar"), option.get("foo"));
   handler.parse(&option, "");
   CPPUNIT_ASSERT_EQUAL(std::string(""), option.get("foo"));
+  CPPUNIT_ASSERT_EQUAL(std::string(""), handler.createPossibleValuesString());
+
+  handler.addTag("apple");
+  CPPUNIT_ASSERT_EQUAL(std::string("apple"), handler.toTagString());
+  handler.addTag("orange");
+  CPPUNIT_ASSERT_EQUAL(std::string("apple,orange"), handler.toTagString());
+  CPPUNIT_ASSERT(handler.hasTag("apple"));
+  CPPUNIT_ASSERT(handler.hasTag("orange"));
+  CPPUNIT_ASSERT(!handler.hasTag("pineapple"));
 }
 
 void OptionHandlerTest::testFloatNumberOptionHandler()
@@ -244,11 +266,13 @@ void OptionHandlerTest::testFloatNumberOptionHandler()
   Option option;
   handler.parse(&option, "1.0");
   CPPUNIT_ASSERT_EQUAL(std::string("1.0"), option.get("foo"));
+  CPPUNIT_ASSERT_EQUAL(std::string("*-*"),
+		       handler.createPossibleValuesString());
 }
 
 void OptionHandlerTest::testFloatNumberOptionHandler_min()
 {
-  FloatNumberOptionHandler handler("foo", 0.0);
+  FloatNumberOptionHandler handler("foo", "", "", 0.0);
   Option option;
   handler.parse(&option, "0.0");
   CPPUNIT_ASSERT_EQUAL(std::string("0.0"), option.get("foo"));
@@ -258,11 +282,13 @@ void OptionHandlerTest::testFloatNumberOptionHandler_min()
   } catch(Exception& e) {
     std::cerr << e.stackTrace() << std::endl;
   }
+  CPPUNIT_ASSERT_EQUAL(std::string("0.0-*"),
+		       handler.createPossibleValuesString());
 }
 
 void OptionHandlerTest::testFloatNumberOptionHandler_max()
 {
-  FloatNumberOptionHandler handler("foo", -1, 10.0);
+  FloatNumberOptionHandler handler("foo", "", "", -1, 10.0);
   Option option;
   handler.parse(&option, "10.0");
   CPPUNIT_ASSERT_EQUAL(std::string("10.0"), option.get("foo"));
@@ -272,11 +298,13 @@ void OptionHandlerTest::testFloatNumberOptionHandler_max()
   } catch(Exception& e) {
     std::cerr << e.stackTrace() << std::endl;
   }
+  CPPUNIT_ASSERT_EQUAL(std::string("*-10.0"),
+		       handler.createPossibleValuesString());
 }
 
 void OptionHandlerTest::testFloatNumberOptionHandler_min_max()
 {
-  FloatNumberOptionHandler handler("foo", 0.0, 10.0);
+  FloatNumberOptionHandler handler("foo", "", "", 0.0, 10.0);
   Option option;
   handler.parse(&option, "0.0");
   CPPUNIT_ASSERT_EQUAL(std::string("0.0"), option.get("foo"));
@@ -294,27 +322,15 @@ void OptionHandlerTest::testFloatNumberOptionHandler_min_max()
   } catch(Exception& e) {
     std::cerr << e.stackTrace() << std::endl;
   }
-}
-
-void OptionHandlerTest::testLogOptionHandler()
-{
-  LogOptionHandler handler("foo");
-  CPPUNIT_ASSERT(handler.canHandle("foo"));
-  CPPUNIT_ASSERT(!handler.canHandle("foobar"));
-  Option option;
-  handler.parse(&option, "/tmp/log.txt");
-  CPPUNIT_ASSERT_EQUAL(std::string("/tmp/log.txt"), option.get(PREF_LOG));
-  CPPUNIT_ASSERT_EQUAL(std::string(""), option.get(PREF_STDOUT_LOG));
-
-  option.clear();
-  handler.parse(&option, "-");
-  CPPUNIT_ASSERT_EQUAL(std::string(""), option.get(PREF_LOG));
-  CPPUNIT_ASSERT_EQUAL(std::string(V_TRUE), option.get(PREF_STDOUT_LOG));
+  CPPUNIT_ASSERT_EQUAL(std::string("0.0-10.0"),
+		       handler.createPossibleValuesString());
 }
 
 void OptionHandlerTest::testHttpProxyOptionHandler()
 {
   HttpProxyOptionHandler handler(PREF_HTTP_PROXY,
+				 "",
+				 "",
 				 PREF_HTTP_PROXY_HOST,
 				 PREF_HTTP_PROXY_PORT);
   CPPUNIT_ASSERT(handler.canHandle(PREF_HTTP_PROXY));
@@ -356,6 +372,8 @@ void OptionHandlerTest::testHttpProxyOptionHandler()
   } catch(Exception& e) {
     std::cerr << e.stackTrace() << std::endl;
   }
+  CPPUNIT_ASSERT_EQUAL(std::string("HOST:PORT"),
+		       handler.createPossibleValuesString());
 }
 
 } // namespace aria2

+ 110 - 0
test/OptionParserTest.cc

@@ -0,0 +1,110 @@
+#include "OptionParser.h"
+#include "OptionHandlerImpl.h"
+#include "Exception.h"
+#include "Util.h"
+#include "Option.h"
+#include <iostream>
+#include <cppunit/extensions/HelperMacros.h>
+
+namespace aria2 {
+
+class OptionParserTest:public CppUnit::TestFixture {
+
+  CPPUNIT_TEST_SUITE(OptionParserTest);
+  CPPUNIT_TEST(testFindAll);
+  CPPUNIT_TEST(testFindByNameSubstring);
+  CPPUNIT_TEST(testFindByTag);
+  CPPUNIT_TEST(testFindByName);
+  CPPUNIT_TEST(testParseDefaultValues);
+  CPPUNIT_TEST_SUITE_END();
+private:
+  SharedHandle<OptionParser> _oparser;
+public:
+  void setUp()
+  {
+    _oparser.reset(new OptionParser());
+
+    SharedHandle<OptionHandler> alpha(new DefaultOptionHandler("alpha",
+							       "",
+							       "ALPHA"));
+    alpha->addTag("apple");
+    _oparser->addOptionHandler(alpha);
+    SharedHandle<OptionHandler> bravo(new DefaultOptionHandler("bravo"));
+    bravo->addTag("apple");
+    bravo->addTag("orange");
+    bravo->addTag("pineapple");
+    _oparser->addOptionHandler(bravo);
+    SharedHandle<OptionHandler> charlie(new DefaultOptionHandler("charlie",
+								 "",
+								 "CHARLIE",
+								 "",
+								 true));
+    charlie->addTag("pineapple");
+    _oparser->addOptionHandler(charlie);
+    SharedHandle<OptionHandler> delta(new UnitNumberOptionHandler("delta",
+								  "",
+								  "1M"));
+    delta->addTag("pineapple");
+    _oparser->addOptionHandler(delta);    
+  }
+
+  void tearDown() {}
+
+  void testFindAll();
+  void testFindByNameSubstring();
+  void testFindByTag();
+  void testFindByName();
+  void testParseDefaultValues();
+};
+
+
+CPPUNIT_TEST_SUITE_REGISTRATION(OptionParserTest);
+
+void OptionParserTest::testFindAll()
+{
+  std::deque<SharedHandle<OptionHandler> > res = _oparser->findAll();
+  CPPUNIT_ASSERT_EQUAL((size_t)3, res.size());
+  CPPUNIT_ASSERT_EQUAL(std::string("alpha"), res[0]->getName());
+  CPPUNIT_ASSERT_EQUAL(std::string("bravo"), res[1]->getName());
+  CPPUNIT_ASSERT_EQUAL(std::string("delta"), res[2]->getName());
+}
+
+void OptionParserTest::testFindByNameSubstring()
+{
+  std::deque<SharedHandle<OptionHandler> > res =
+    _oparser->findByNameSubstring("l");
+  CPPUNIT_ASSERT_EQUAL((size_t)2, res.size());
+  CPPUNIT_ASSERT_EQUAL(std::string("alpha"), res[0]->getName());
+  CPPUNIT_ASSERT_EQUAL(std::string("delta"), res[1]->getName());
+}
+
+void OptionParserTest::testFindByTag()
+{
+  std::deque<SharedHandle<OptionHandler> > res =
+    _oparser->findByTag("pineapple");
+  CPPUNIT_ASSERT_EQUAL((size_t)2, res.size());
+  CPPUNIT_ASSERT_EQUAL(std::string("bravo"), res[0]->getName());
+  CPPUNIT_ASSERT_EQUAL(std::string("delta"), res[1]->getName());
+}
+
+void OptionParserTest::testFindByName()
+{
+  SharedHandle<OptionHandler> bravo = _oparser->findByName("bravo");
+  CPPUNIT_ASSERT(!bravo.isNull());
+  CPPUNIT_ASSERT_EQUAL(std::string("bravo"), bravo->getName());
+
+  SharedHandle<OptionHandler> charlie = _oparser->findByName("charlie");
+  CPPUNIT_ASSERT(charlie.isNull());
+}
+
+void OptionParserTest::testParseDefaultValues()
+{
+  Option option;
+  _oparser->parseDefaultValues(&option);
+  CPPUNIT_ASSERT_EQUAL(std::string("ALPHA"), option.get("alpha"));
+  CPPUNIT_ASSERT_EQUAL(std::string("1048576"), option.get("delta"));
+  CPPUNIT_ASSERT_EQUAL(std::string("CHARLIE"), option.get("charlie"));
+  CPPUNIT_ASSERT(!option.defined("bravo"));
+}
+
+} // namespace aria2

+ 0 - 72
test/TagContainerTest.cc

@@ -1,72 +0,0 @@
-#include "TagContainer.h"
-#include "TaggedItem.h"
-#include <cppunit/extensions/HelperMacros.h>
-
-namespace aria2 {
-
-class TagContainerTest:public CppUnit::TestFixture {
-
-  CPPUNIT_TEST_SUITE(TagContainerTest);
-  CPPUNIT_TEST(testSearch);
-  CPPUNIT_TEST(testNameMatch);
-  CPPUNIT_TEST_SUITE_END();
-private:
-public:
-  void setUp() {}
-
-  void testSearch();
-  void testNameMatch();
-};
-
-
-CPPUNIT_TEST_SUITE_REGISTRATION(TagContainerTest);
-
-void TagContainerTest::testSearch()
-{
-  TaggedItemHandle items[] = {
-    SharedHandle<TaggedItem>(new TaggedItem("alpha")),
-    SharedHandle<TaggedItem>(new TaggedItem("bravo")),
-    SharedHandle<TaggedItem>(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(std::string("bravo"), res[0]->getName());
-    CPPUNIT_ASSERT_EQUAL(std::string("foo,bar"), res[0]->toTagString());
-  }
-  {
-    TaggedItems res = tc.nameMatchForward("ch");
-    CPPUNIT_ASSERT_EQUAL((size_t)1, res.size());
-    CPPUNIT_ASSERT_EQUAL(std::string("charlie"), res[0]->getName());
-    CPPUNIT_ASSERT_EQUAL(std::string("foo"), res[0]->toTagString());
-  }
-}
-
-void TagContainerTest::testNameMatch()
-{
-  TaggedItemHandle items[] = {
-    SharedHandle<TaggedItem>(new TaggedItem("alpha")),
-    SharedHandle<TaggedItem>(new TaggedItem("bravo")),
-    SharedHandle<TaggedItem>(new TaggedItem("charlie")),
-    SharedHandle<TaggedItem>(new TaggedItem("bravo"))
-  };
-  items[1]->addTag("foo");
-  TagContainer tc(TaggedItems(&items[0], &items[3]));
-  {
-    TaggedItemHandle item = tc.nameMatch("bravo");
-    CPPUNIT_ASSERT_EQUAL(std::string("bravo"), item->getName());
-    CPPUNIT_ASSERT_EQUAL(std::string("foo"), item->toTagString());
-  }
-  {
-    CPPUNIT_ASSERT(tc.nameMatch("delta").isNull());
-  }
-}
-
-} // namespace aria2

+ 0 - 56
test/TaggedItemTest.cc

@@ -1,56 +0,0 @@
-#include "TaggedItem.h"
-#include <cppunit/extensions/HelperMacros.h>
-
-namespace aria2 {
-
-class TaggedItemTest:public CppUnit::TestFixture {
-
-  CPPUNIT_TEST_SUITE(TaggedItemTest);
-  CPPUNIT_TEST(testHasTag);
-  CPPUNIT_TEST(testToTagString);
-  CPPUNIT_TEST(testOperatorEqual);
-  CPPUNIT_TEST_SUITE_END();
-private:
-
-public:
-  void setUp() {}
-
-  void testHasTag();
-  void testToTagString();
-  void testOperatorEqual();
-};
-
-
-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(std::string("foo,bar"), item.toTagString());
-}
-
-void TaggedItemTest::testOperatorEqual()
-{
-  TaggedItem none("");
-  TaggedItem foo("foo");
-  TaggedItem foo2("foo");
-  TaggedItem bar("bar");
-  CPPUNIT_ASSERT(!(none == foo));
-  CPPUNIT_ASSERT(!(bar == foo));
-  CPPUNIT_ASSERT(foo == foo);
-}
-
-} // namespace aria2