summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2009-02-07 11:00:34 +0000
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2009-02-07 11:00:34 +0000
commit2881dbe025d2002fc5260969cd0c402404713ebc (patch)
tree4d30de40e909a9c9e9f3d2bdb0ad2748afc35922 /src
parentbbb3589293139db527cf72f0a30e989fc2889a53 (diff)
2009-02-07 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Added OptionParser::parseArg() which internally uses getopt_long to parse command-line options. All command-line options are now configured by OptionHandler. No manual editing of struct option* is required any more. * src/NameMatchOptionHandler.h * src/OptionHandler.h * src/OptionHandlerFactory.cc * src/OptionHandlerImpl.h * src/OptionParser.cc * src/OptionParser.h * src/array_fun.h * src/main.cc * src/option_processing.cc * test/OptionHandlerTest.cc * test/OptionParserTest.cc
Diffstat (limited to 'src')
-rw-r--r--src/NameMatchOptionHandler.h55
-rw-r--r--src/OptionHandler.h20
-rw-r--r--src/OptionHandlerFactory.cc280
-rw-r--r--src/OptionHandlerImpl.h156
-rw-r--r--src/OptionParser.cc197
-rw-r--r--src/OptionParser.h22
-rw-r--r--src/array_fun.h37
-rw-r--r--src/main.cc53
-rw-r--r--src/option_processing.cc567
9 files changed, 654 insertions, 733 deletions
diff --git a/src/NameMatchOptionHandler.h b/src/NameMatchOptionHandler.h
index 8ef962fa..a1024951 100644
--- a/src/NameMatchOptionHandler.h
+++ b/src/NameMatchOptionHandler.h
@@ -36,14 +36,17 @@
#define _D_NAME_MATCH_OPTION_HANDLER_H_
#include "OptionHandler.h"
-#include "A2STR.h"
-#include "Util.h"
-#include "OptionHandlerException.h"
+
#include <strings.h>
+
#include <algorithm>
#include <sstream>
#include <iterator>
+#include "A2STR.h"
+#include "Util.h"
+#include "OptionHandlerException.h"
+
#define NO_DESCRIPTION A2STR::NIL
#define NO_DEFAULT_VALUE A2STR::NIL
@@ -59,20 +62,30 @@ protected:
std::string _defaultValue;
- bool _hidden;
-
std::deque<std::string> _tags;
- virtual void parseArg(Option* option, const std::string& arg) = 0;
+ int _id;
+
+ OptionHandler::ARG_TYPE _argType;
+
+ char _shortName;
+
+ bool _hidden;
+
+ virtual void parseArg(Option& option, const std::string& arg) = 0;
public:
NameMatchOptionHandler(const std::string& optName,
const std::string& description = NO_DESCRIPTION,
const std::string& defaultValue = NO_DEFAULT_VALUE,
- bool hidden = false):
+ ARG_TYPE argType = REQ_ARG,
+ char shortName = 0):
_optName(optName),
_description(description),
_defaultValue(defaultValue),
- _hidden(hidden) {}
+ _id(0),
+ _argType(argType),
+ _shortName(shortName),
+ _hidden(false) {}
virtual ~NameMatchOptionHandler() {}
@@ -81,7 +94,7 @@ public:
return strcasecmp(_optName.c_str(), optName.c_str()) == 0;
}
- virtual void parse(Option* option, const std::string& arg)
+ virtual void parse(Option& option, const std::string& arg)
{
try {
parseArg(option, arg);
@@ -128,6 +141,30 @@ public:
return _hidden;
}
+ void hide()
+ {
+ _hidden = true;
+ }
+
+ virtual char getShortName() const
+ {
+ return _shortName;
+ }
+
+ virtual int getOptionID() const
+ {
+ return _id;
+ }
+
+ virtual void setOptionID(int id)
+ {
+ _id = id;
+ }
+
+ virtual OptionHandler::ARG_TYPE getArgType() const
+ {
+ return _argType;
+ }
};
typedef SharedHandle<NameMatchOptionHandler> NameMatchOptionHandlerHandle;
diff --git a/src/OptionHandler.h b/src/OptionHandler.h
index 5a5eb952..c8306488 100644
--- a/src/OptionHandler.h
+++ b/src/OptionHandler.h
@@ -36,11 +36,13 @@
#define _D_OPTION_HANDLER_H_
#include "common.h"
-#include "SharedHandle.h"
+
#include <string>
#include <deque>
#include <iosfwd>
+#include "SharedHandle.h"
+
namespace aria2 {
class Option;
@@ -50,7 +52,7 @@ public:
virtual ~OptionHandler() {}
virtual bool canHandle(const std::string& optName) = 0;
- virtual void parse(Option* option, const std::string& arg) = 0;
+ virtual void parse(Option& option, const std::string& arg) = 0;
virtual std::string createPossibleValuesString() const = 0;
@@ -67,6 +69,20 @@ public:
virtual const std::string& getDefaultValue() const = 0;
virtual bool isHidden() const = 0;
+
+ enum ARG_TYPE {
+ REQ_ARG,
+ OPT_ARG,
+ NO_ARG
+ };
+
+ virtual ARG_TYPE getArgType() const = 0;
+
+ virtual char getShortName() const = 0;
+
+ virtual int getOptionID() const = 0;
+
+ virtual void setOptionID(int id) = 0;
};
typedef SharedHandle<OptionHandler> OptionHandlerHandle;
diff --git a/src/OptionHandlerFactory.cc b/src/OptionHandlerFactory.cc
index 0b3ac849..df0df63c 100644
--- a/src/OptionHandlerFactory.cc
+++ b/src/OptionHandlerFactory.cc
@@ -64,19 +64,23 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
op->addTag(TAG_ADVANCED);
handlers.push_back(op);
}
+#ifdef ENABLE_ASYNC_DNS
{
SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_ASYNC_DNS,
TEXT_ASYNC_DNS,
- V_TRUE));
+ V_TRUE,
+ OptionHandler::OPT_ARG));
op->addTag(TAG_ADVANCED);
handlers.push_back(op);
}
+#endif // ENABLE_ASYNC_DNS
{
SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_AUTO_FILE_RENAMING,
TEXT_AUTO_FILE_RENAMING,
- V_TRUE));
+ V_TRUE,
+ OptionHandler::OPT_ARG));
op->addTag(TAG_ADVANCED);
handlers.push_back(op);
}
@@ -89,16 +93,20 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
op->addTag(TAG_ADVANCED);
handlers.push_back(op);
}
+#ifdef ENABLE_MESSAGE_DIGEST
{
SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_CHECK_INTEGRITY,
TEXT_CHECK_INTEGRITY,
- V_FALSE));
+ V_FALSE,
+ OptionHandler::OPT_ARG,
+ 'V'));
op->addTag(TAG_BASIC);
op->addTag(TAG_BITTORRENT);
op->addTag(TAG_METALINK);
handlers.push_back(op);
}
+#endif // ENABLE_MESSAGE_DIGEST
{
SharedHandle<OptionHandler> op(new DefaultOptionHandler
(PREF_CONF_PATH,
@@ -111,7 +119,9 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_CONTINUE,
TEXT_CONTINUE,
- V_FALSE)); // TODO ommit?
+ V_FALSE, // TODO ommit?
+ OptionHandler::NO_ARG,
+ 'c'));
op->addTag(TAG_BASIC);
op->addTag(TAG_FTP);
op->addTag(TAG_HTTP);
@@ -121,7 +131,9 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_DAEMON,
TEXT_DAEMON,
- V_FALSE)); // TODO ommit?
+ V_FALSE,
+ OptionHandler::NO_ARG,
+ 'D')); // TODO ommit?
op->addTag(TAG_ADVANCED);
handlers.push_back(op);
}
@@ -129,32 +141,39 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
SharedHandle<OptionHandler> op(new DefaultOptionHandler
(PREF_DIR,
TEXT_DIR,
- "."));
+ ".",
+ A2STR::NIL,
+ OptionHandler::REQ_ARG,
+ 'd'));
op->addTag(TAG_BASIC);
handlers.push_back(op);
}
{
- SharedHandle<OptionHandler> op(new NumberOptionHandler
- (PREF_DNS_TIMEOUT,
- NO_DESCRIPTION,
- "30",
- 1, 60,
- true));
+ SharedHandle<NumberOptionHandler> op(new NumberOptionHandler
+ (PREF_DNS_TIMEOUT,
+ NO_DESCRIPTION,
+ "30",
+ 1, 60));
+ op->hide();
handlers.push_back(op);
}
+#ifdef ENABLE_DIRECT_IO
{
SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_ENABLE_DIRECT_IO,
TEXT_ENABLE_DIRECT_IO,
- V_TRUE));
+ V_TRUE,
+ OptionHandler::OPT_ARG));
op->addTag(TAG_ADVANCED);
handlers.push_back(op);
}
+#endif // ENABLE_DIRECT_IO
{
SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_ENABLE_HTTP_SERVER,
TEXT_ENABLE_HTTP_SERVER,
- V_FALSE));
+ V_FALSE,
+ OptionHandler::OPT_ARG));
op->addTag(TAG_EXPERIMENTAL);
handlers.push_back(op);
}
@@ -183,7 +202,8 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
(PREF_FILE_ALLOCATION,
TEXT_FILE_ALLOCATION,
V_PREALLOC,
- V_NONE, V_PREALLOC));
+ V_NONE, V_PREALLOC,
+ 'a'));
op->addTag(TAG_BASIC);
handlers.push_back(op);
}
@@ -191,7 +211,9 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_FORCE_SEQUENTIAL,
TEXT_FORCE_SEQUENTIAL,
- V_FALSE));
+ V_FALSE,
+ OptionHandler::OPT_ARG,
+ 'Z'));
op->addTag(TAG_BASIC);
handlers.push_back(op);
}
@@ -209,7 +231,9 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
(PREF_INPUT_FILE,
TEXT_INPUT_FILE,
NO_DEFAULT_VALUE,
- "FILENAME,-"));
+ "FILENAME,-",
+ OptionHandler::REQ_ARG,
+ 'i'));
op->addTag(TAG_BASIC);
handlers.push_back(op);
}
@@ -218,7 +242,9 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
(PREF_LOG,
TEXT_LOG,
NO_DEFAULT_VALUE,
- "FILENAME,-"));
+ "FILENAME,-",
+ OptionHandler::REQ_ARG,
+ 'l'));
op->addTag(TAG_BASIC);
handlers.push_back(op);
}
@@ -239,7 +265,8 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
(PREF_MAX_CONCURRENT_DOWNLOADS,
TEXT_MAX_CONCURRENT_DOWNLOADS,
"5",
- 1, 45));
+ 1, 45,
+ 'j'));
op->addTag(TAG_BASIC);
handlers.push_back(op);
}
@@ -258,7 +285,8 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_NO_CONF,
TEXT_NO_CONF,
- V_FALSE));
+ V_FALSE,
+ OptionHandler::NO_ARG));
op->addTag(TAG_ADVANCED);
handlers.push_back(op);
}
@@ -275,7 +303,9 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_PARAMETERIZED_URI,
TEXT_PARAMETERIZED_URI,
- V_FALSE));
+ V_FALSE,
+ OptionHandler::OPT_ARG,
+ 'P'));
op->addTag(TAG_ADVANCED);
handlers.push_back(op);
}
@@ -283,10 +313,13 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_QUIET,
TEXT_QUIET,
- V_FALSE));
+ V_FALSE,
+ OptionHandler::OPT_ARG,
+ 'q'));
op->addTag(TAG_ADVANCED);
handlers.push_back(op);
}
+#ifdef ENABLE_MESSAGE_DIGEST
{
SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_REALTIME_CHUNK_CHECKSUM,
@@ -295,6 +328,7 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
op->addTag(TAG_METALINK);
handlers.push_back(op);
}
+#endif // ENABLE_MESSAGE_DIGEST
{
SharedHandle<OptionHandler> op(new NumberOptionHandler
(PREF_STOP,
@@ -349,7 +383,8 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
(PREF_MAX_TRIES,
TEXT_MAX_TRIES,
"5",
- 0));
+ 0, -1,
+ 'm'));
op->addTag(TAG_FTP);
op->addTag(TAG_HTTP);
handlers.push_back(op);
@@ -359,7 +394,9 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
(PREF_OUT,
TEXT_OUT,
NO_DEFAULT_VALUE,
- "FILENAME"));
+ "FILENAME",
+ OptionHandler::REQ_ARG,
+ 'o'));
op->addTag(TAG_BASIC);
op->addTag(TAG_FTP);
op->addTag(TAG_HTTP);
@@ -369,7 +406,9 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_REMOTE_TIME,
TEXT_REMOTE_TIME,
- V_FALSE));
+ V_FALSE,
+ OptionHandler::OPT_ARG,
+ 'R'));
op->addTag(TAG_FTP);
op->addTag(TAG_HTTP);
handlers.push_back(op);
@@ -385,12 +424,12 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
handlers.push_back(op);
}
{
- SharedHandle<OptionHandler> op(new UnitNumberOptionHandler
- (PREF_SEGMENT_SIZE,
- NO_DESCRIPTION,
- "1M",
- 1024, -1,
- true));
+ SharedHandle<UnitNumberOptionHandler> op(new UnitNumberOptionHandler
+ (PREF_SEGMENT_SIZE,
+ NO_DESCRIPTION,
+ "1M",
+ 1024, -1));
+ op->hide();
handlers.push_back(op);
}
{
@@ -428,19 +467,20 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
(PREF_SPLIT,
TEXT_SPLIT,
"5",
- 1));
+ 1, -1,
+ 's'));
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));
+ SharedHandle<NumberOptionHandler> op(new NumberOptionHandler
+ (PREF_STARTUP_IDLE_TIME,
+ NO_DESCRIPTION,
+ "10",
+ 1, 60));
+ op->hide();
handlers.push_back(op);
}
{
@@ -448,7 +488,8 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
(PREF_TIMEOUT,
TEXT_TIMEOUT,
"60",
- 1, 600));
+ 1, 600,
+ 't'));
op->addTag(TAG_FTP);
op->addTag(TAG_HTTP);
handlers.push_back(op);
@@ -487,7 +528,8 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_CHECK_CERTIFICATE,
TEXT_CHECK_CERTIFICATE,
- V_TRUE));
+ V_TRUE,
+ OptionHandler::OPT_ARG));
op->addTag(TAG_HTTP);
op->addTag(TAG_HTTPS);
handlers.push_back(op);
@@ -496,7 +538,8 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_ENABLE_HTTP_KEEP_ALIVE,
TEXT_ENABLE_HTTP_KEEP_ALIVE,
- V_TRUE));
+ V_TRUE,
+ OptionHandler::OPT_ARG));
op->addTag(TAG_HTTP);
handlers.push_back(op);
}
@@ -504,7 +547,8 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_ENABLE_HTTP_PIPELINING,
TEXT_ENABLE_HTTP_PIPELINING,
- V_FALSE));
+ V_FALSE,
+ OptionHandler::OPT_ARG));
op->addTag(TAG_HTTP);
handlers.push_back(op);
}
@@ -553,12 +597,12 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
handlers.push_back(op);
}
{
- SharedHandle<OptionHandler> op(new NumberOptionHandler
- (PREF_MAX_HTTP_PIPELINING,
- NO_DESCRIPTION,
- "2",
- 1, 8,
- true));
+ SharedHandle<NumberOptionHandler> op(new NumberOptionHandler
+ (PREF_MAX_HTTP_PIPELINING,
+ NO_DESCRIPTION,
+ "2",
+ 1, 8));
+ op->hide();
handlers.push_back(op);
}
{
@@ -577,10 +621,11 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
handlers.push_back(op);
}
{
- SharedHandle<OptionHandler> op(new DefaultOptionHandler
+ SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_USE_HEAD,
TEXT_USE_HEAD,
- V_TRUE));
+ V_TRUE,
+ OptionHandler::OPT_ARG));
op->addTag(TAG_HTTP);
handlers.push_back(op);
}
@@ -588,7 +633,10 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
SharedHandle<OptionHandler> op(new DefaultOptionHandler
(PREF_USER_AGENT,
TEXT_USER_AGENT,
- "aria2"));
+ "aria2",
+ A2STR::NIL,
+ OptionHandler::REQ_ARG,
+ 'U'));
op->addTag(TAG_HTTP);
handlers.push_back(op);
}
@@ -605,7 +653,9 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_FTP_PASV,
TEXT_FTP_PASV,
- V_TRUE));
+ V_TRUE,
+ OptionHandler::OPT_ARG,
+ 'p'));
op->addTag(TAG_FTP);
handlers.push_back(op);
}
@@ -613,7 +663,8 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_FTP_REUSE_CONNECTION,
TEXT_FTP_REUSE_CONNECTION,
- V_TRUE));
+ V_TRUE,
+ OptionHandler::OPT_ARG));
op->addTag(TAG_FTP);
handlers.push_back(op);
}
@@ -635,19 +686,21 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
handlers.push_back(op);
}
{
- SharedHandle<OptionHandler> op(new DefaultOptionHandler
- (PREF_NETRC_PATH,
- NO_DESCRIPTION,
- Util::getHomeDir()+"/.netrc",
- "/PATH/TO/NETRC",
- true));
+ SharedHandle<DefaultOptionHandler> op(new DefaultOptionHandler
+ (PREF_NETRC_PATH,
+ NO_DESCRIPTION,
+ Util::getHomeDir()+"/.netrc",
+ "/PATH/TO/NETRC"));
+ op->hide();
handlers.push_back(op);
}
{
SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_NO_NETRC,
TEXT_NO_NETRC,
- V_FALSE)); // TODO ommit?
+ V_FALSE, // TODO ommit?
+ OptionHandler::NO_ARG,
+ 'n'));
op->addTag(TAG_FTP);
op->addTag(TAG_HTTP);
handlers.push_back(op);
@@ -705,6 +758,7 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
handlers.push_back(op);
}
// BitTorrent/Metalink Options
+#if defined ENABLE_BITTORRENT || defined ENABLE_METALINK
{
SharedHandle<OptionHandler> op(new IntegerRangeOptionHandler
(PREF_SELECT_FILE,
@@ -719,13 +773,17 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_SHOW_FILES,
TEXT_SHOW_FILES,
- V_FALSE)); // TODO ommit?
+ V_FALSE, // TODO ommit?
+ OptionHandler::NO_ARG,
+ 'S'));
op->addTag(TAG_BASIC);
op->addTag(TAG_BITTORRENT);
op->addTag(TAG_METALINK);
handlers.push_back(op);
}
+#endif // ENABLE_BITTORRENT || ENABLE_METALINK
// BitTorrent Specific Options
+#ifdef ENABLE_BITTORRENT
{
SharedHandle<OptionHandler> op(new DefaultOptionHandler
(PREF_BT_EXTERNAL_IP,
@@ -736,19 +794,20 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
handlers.push_back(op);
}
{
- SharedHandle<OptionHandler> op(new NumberOptionHandler
- (PREF_BT_KEEP_ALIVE_INTERVAL,
- NO_DESCRIPTION,
- "120",
- 1, 120,
- true));
+ SharedHandle<NumberOptionHandler> op(new NumberOptionHandler
+ (PREF_BT_KEEP_ALIVE_INTERVAL,
+ NO_DESCRIPTION,
+ "120",
+ 1, 120));
+ op->hide();
handlers.push_back(op);
}
{
SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_BT_HASH_CHECK_SEED,
TEXT_BT_HASH_CHECK_SEED,
- V_TRUE));
+ V_TRUE,
+ OptionHandler::OPT_ARG));
op->addTag(TAG_BITTORRENT);
handlers.push_back(op);
}
@@ -798,29 +857,30 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
handlers.push_back(op);
}
{
- SharedHandle<OptionHandler> op(new NumberOptionHandler
- (PREF_BT_REQUEST_TIMEOUT,
- NO_DESCRIPTION,
- "60",
- 1, 600,
- true));
+ SharedHandle<NumberOptionHandler> op(new NumberOptionHandler
+ (PREF_BT_REQUEST_TIMEOUT,
+ NO_DESCRIPTION,
+ "60",
+ 1, 600));
+ op->hide();
handlers.push_back(op);
}
{
SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_BT_SEED_UNVERIFIED,
TEXT_BT_SEED_UNVERIFIED,
- V_FALSE));
+ V_FALSE,
+ OptionHandler::OPT_ARG));
op->addTag(TAG_BITTORRENT);
handlers.push_back(op);
}
{
- SharedHandle<OptionHandler> op(new NumberOptionHandler
- (PREF_BT_TIMEOUT,
- NO_DESCRIPTION,
- "180",
- 1, 600,
- true));
+ SharedHandle<NumberOptionHandler> op(new NumberOptionHandler
+ (PREF_BT_TIMEOUT,
+ NO_DESCRIPTION,
+ "180",
+ 1, 600));
+ op->hide();
handlers.push_back(op);
}
{
@@ -864,7 +924,8 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_ENABLE_DHT,
TEXT_ENABLE_DHT,
- V_FALSE));
+ V_FALSE,
+ OptionHandler::OPT_ARG));
op->addTag(TAG_BASIC);
op->addTag(TAG_BITTORRENT);
handlers.push_back(op);
@@ -873,7 +934,8 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_ENABLE_PEER_EXCHANGE,
TEXT_ENABLE_PEER_EXCHANGE,
- V_TRUE));
+ V_TRUE,
+ OptionHandler::OPT_ARG));
op->addTag(TAG_BITTORRENT);
handlers.push_back(op);
}
@@ -911,18 +973,19 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
(PREF_MAX_UPLOAD_LIMIT,
TEXT_MAX_UPLOAD_LIMIT,
"0",
- 0));
+ 0, -1,
+ 'u'));
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));
+ SharedHandle<NumberOptionHandler> op(new NumberOptionHandler
+ (PREF_PEER_CONNECTION_TIMEOUT,
+ NO_DESCRIPTION,
+ "20",
+ 1, 600));
+ op->hide();
handlers.push_back(op);
}
{
@@ -954,12 +1017,18 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
{
SharedHandle<OptionHandler> op(new DefaultOptionHandler
(PREF_TORRENT_FILE,
- TEXT_TORRENT_FILE));
+ TEXT_TORRENT_FILE,
+ NO_DEFAULT_VALUE,
+ A2STR::NIL,
+ OptionHandler::REQ_ARG,
+ 'T'));
op->addTag(TAG_BASIC);
op->addTag(TAG_BITTORRENT);
handlers.push_back(op);
}
+#endif // ENABLE_BITTORRENT
// Metalink Specific Options
+#ifdef ENABLE_METALINK
{
SharedHandle<OptionHandler> op(new ParameterOptionHandler
(PREF_FOLLOW_METALINK,
@@ -973,14 +1042,19 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_METALINK_ENABLE_UNIQUE_PROTOCOL,
TEXT_METALINK_ENABLE_UNIQUE_PROTOCOL,
- V_TRUE));
+ V_TRUE,
+ OptionHandler::OPT_ARG));
op->addTag(TAG_METALINK);
handlers.push_back(op);
}
{
SharedHandle<OptionHandler> op(new DefaultOptionHandler
(PREF_METALINK_FILE,
- TEXT_METALINK_FILE));
+ TEXT_METALINK_FILE,
+ NO_DEFAULT_VALUE,
+ A2STR::NIL,
+ OptionHandler::REQ_ARG,
+ 'M'));
op->addTag(TAG_BASIC);
op->addTag(TAG_METALINK);
handlers.push_back(op);
@@ -1022,7 +1096,8 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
(PREF_METALINK_SERVERS,
TEXT_METALINK_SERVERS,
"5",
- 1));
+ 1, -1,
+ 'C'));
op->addTag(TAG_METALINK);
handlers.push_back(op);
}
@@ -1033,6 +1108,19 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
op->addTag(TAG_METALINK);
handlers.push_back(op);
}
+#endif // ENABLE_METALINK
+ // Version Option
+ {
+ SharedHandle<OptionHandler> op(new DefaultOptionHandler
+ ("version",
+ TEXT_VERSION,
+ NO_DEFAULT_VALUE,
+ A2STR::NIL,
+ OptionHandler::NO_ARG,
+ 'v'));
+ op->addTag(TAG_BASIC);
+ handlers.push_back(op);
+ }
// Help Option
{
SharedHandle<OptionHandler> op(new DefaultOptionHandler
@@ -1048,7 +1136,9 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
TAG_METALINK,
TAG_BITTORRENT,
TAG_EXPERIMENTAL,
- TAG_HELP).str()));
+ TAG_HELP).str(),
+ OptionHandler::OPT_ARG,
+ 'h'));
op->addTag(TAG_BASIC);
op->addTag(TAG_HELP);
handlers.push_back(op);
diff --git a/src/OptionHandlerImpl.h b/src/OptionHandlerImpl.h
index b9160115..5d3b00d8 100644
--- a/src/OptionHandlerImpl.h
+++ b/src/OptionHandlerImpl.h
@@ -56,12 +56,14 @@
namespace aria2 {
class NullOptionHandler : public OptionHandler {
+private:
+ int _id;
public:
virtual ~NullOptionHandler() {}
virtual bool canHandle(const std::string& optName) { return true; }
- virtual void parse(Option* option, const std::string& arg) {}
+ virtual void parse(Option& option, const std::string& arg) {}
virtual bool hasTag(const std::string& tag) const { return false; }
@@ -78,23 +80,47 @@ public:
virtual std::string createPossibleValuesString() const { return A2STR::NIL; }
virtual bool isHidden() const { return true; }
+
+ virtual OptionHandler::ARG_TYPE getArgType() const
+ {
+ return OptionHandler::NO_ARG;
+ }
+
+ virtual int getOptionID() const
+ {
+ return _id;
+ }
+
+ virtual void setOptionID(int id)
+ {
+ _id = id;
+ }
+
+ virtual char getShortName() const
+ {
+ return 0;
+ }
};
class BooleanOptionHandler : public NameMatchOptionHandler {
public:
BooleanOptionHandler(const std::string& optName,
const std::string& description = NO_DESCRIPTION,
- const std::string& defaultValue = NO_DEFAULT_VALUE):
- NameMatchOptionHandler(optName, description, defaultValue) {}
+ const std::string& defaultValue = NO_DEFAULT_VALUE,
+ OptionHandler::ARG_TYPE argType = OptionHandler::REQ_ARG,
+ char shortName = 0):
+ NameMatchOptionHandler(optName, description, defaultValue,
+ argType, shortName) {}
virtual ~BooleanOptionHandler() {}
- virtual void parseArg(Option* option, const std::string& optarg)
+ virtual void parseArg(Option& option, const std::string& optarg)
{
- if(optarg == "true") {
- option->put(_optName, V_TRUE);
+ if(optarg == "true" ||
+ (_argType == OptionHandler::OPT_ARG && optarg.empty())) {
+ option.put(_optName, V_TRUE);
} else if(optarg == "false") {
- option->put(_optName, V_FALSE);
+ option.put(_optName, V_FALSE);
} else {
std::string msg = _optName+" "+_("must be either 'true' or 'false'.");
throw FatalException(msg);
@@ -115,13 +141,15 @@ public:
IntegerRangeOptionHandler(const std::string& optName,
const std::string& description,
const std::string& defaultValue,
- int32_t min, int32_t max):
- NameMatchOptionHandler(optName, description, defaultValue),
+ int32_t min, int32_t max,
+ char shortName = 0):
+ NameMatchOptionHandler(optName, description, defaultValue,
+ OptionHandler::REQ_ARG, shortName),
_min(min), _max(max) {}
virtual ~IntegerRangeOptionHandler() {}
- virtual void parseArg(Option* option, const std::string& optarg)
+ virtual void parseArg(Option& option, const std::string& optarg)
{
IntSequence seq = Util::parseIntRange(optarg);
while(seq.hasNext()) {
@@ -132,7 +160,7 @@ public:
(StringFormat(msg.c_str(), Util::itos(_min).c_str(),
Util::itos(_max).c_str()).str());
}
- option->put(_optName, optarg);
+ option.put(_optName, optarg);
}
}
@@ -152,22 +180,23 @@ public:
const std::string& defaultValue = NO_DEFAULT_VALUE,
int64_t min = -1,
int64_t max = -1,
- bool hidden = false):
- NameMatchOptionHandler(optName, description, defaultValue, hidden),
+ char shortName = 0):
+ NameMatchOptionHandler(optName, description, defaultValue,
+ OptionHandler::REQ_ARG, shortName),
_min(min), _max(max) {}
virtual ~NumberOptionHandler() {}
- virtual void parseArg(Option* option, const std::string& optarg)
+ virtual void parseArg(Option& option, const std::string& optarg)
{
int64_t num = Util::parseLLInt(optarg);
parseArg(option, num);
}
- void parseArg(Option* option, int64_t number)
+ void parseArg(Option& option, int64_t number)
{
if((_min == -1 || _min <= number) && (_max == -1 || number <= _max)) {
- option->put(_optName, Util::itos(number));
+ option.put(_optName, Util::itos(number));
} else {
std::string msg = _optName+" ";
if(_min == -1 && _max != -1) {
@@ -200,12 +229,13 @@ public:
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) {}
+ char shortName = 0):
+ NumberOptionHandler(optName, description, defaultValue, min, max,
+ shortName) {}
virtual ~UnitNumberOptionHandler() {}
- virtual void parseArg(Option* option, const std::string& optarg)
+ virtual void parseArg(Option& option, const std::string& optarg)
{
int64_t num = Util::getRealSize(optarg);
NumberOptionHandler::parseArg(option, num);
@@ -220,17 +250,19 @@ public:
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),
+ double min = -1, double max = -1,
+ char shortName = 0):
+ NameMatchOptionHandler(optName, description, defaultValue,
+ OptionHandler::REQ_ARG, shortName),
_min(min), _max(max) {}
virtual ~FloatNumberOptionHandler() {}
- virtual void parseArg(Option* option, const std::string& optarg)
+ virtual void parseArg(Option& option, const std::string& optarg)
{
double number = strtod(optarg.c_str(), 0);
if((_min < 0 || _min <= number) && (_max < 0 || number <= _max)) {
- option->put(_optName, optarg);
+ option.put(_optName, optarg);
} else {
std::string msg = _optName+" ";
if(_min < 0 && _max >= 0) {
@@ -279,15 +311,17 @@ public:
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),
+ OptionHandler::ARG_TYPE argType = OptionHandler::REQ_ARG,
+ char shortName = 0):
+ NameMatchOptionHandler(optName, description, defaultValue, argType,
+ shortName),
_possibleValuesString(possibleValuesString) {}
virtual ~DefaultOptionHandler() {}
- virtual void parseArg(Option* option, const std::string& optarg)
+ virtual void parseArg(Option& option, const std::string& optarg)
{
- option->put(_optName, optarg);
+ option.put(_optName, optarg);
}
virtual std::string createPossibleValuesString() const
@@ -306,18 +340,22 @@ public:
const std::string& description,
const std::string& defaultValue,
const std::string& delim,
- const std::string& possibleValuesString = A2STR::NIL):
- NameMatchOptionHandler(optName, description, defaultValue),
+ const std::string& possibleValuesString = A2STR::NIL,
+ OptionHandler::ARG_TYPE argType =
+ OptionHandler::REQ_ARG,
+ char shortName = 0):
+ NameMatchOptionHandler(optName, description, defaultValue, argType,
+ shortName),
_delim(delim),
_possibleValuesString(possibleValuesString) {}
virtual ~CumulativeOptionHandler() {}
- virtual void parseArg(Option* option, const std::string& optarg)
+ virtual void parseArg(Option& option, const std::string& optarg)
{
- std::string value = option->get(_optName);
+ std::string value = option.get(_optName);
value += optarg+_delim;
- option->put(_optName, value);
+ option.put(_optName, value);
}
virtual std::string createPossibleValuesString() const
@@ -333,15 +371,19 @@ public:
ParameterOptionHandler(const std::string& optName,
const std::string& description,
const std::string& defaultValue,
- const std::deque<std::string>& validParamValues):
- NameMatchOptionHandler(optName, description, defaultValue),
+ const std::deque<std::string>& validParamValues,
+ char shortName = 0):
+ NameMatchOptionHandler(optName, description, defaultValue,
+ OptionHandler::REQ_ARG, shortName),
_validParamValues(validParamValues) {}
ParameterOptionHandler(const std::string& optName,
const std::string& description,
const std::string& defaultValue,
- const std::string& validParamValue):
- NameMatchOptionHandler(optName, description, defaultValue)
+ const std::string& validParamValue,
+ char shortName = 0):
+ NameMatchOptionHandler(optName, description, defaultValue,
+ OptionHandler::REQ_ARG, shortName)
{
_validParamValues.push_back(validParamValue);
}
@@ -350,8 +392,10 @@ public:
const std::string& description,
const std::string& defaultValue,
const std::string& validParamValue1,
- const std::string& validParamValue2):
- NameMatchOptionHandler(optName, description, defaultValue)
+ const std::string& validParamValue2,
+ char shortName = 0):
+ NameMatchOptionHandler(optName, description, defaultValue,
+ OptionHandler::REQ_ARG, shortName)
{
_validParamValues.push_back(validParamValue1);
_validParamValues.push_back(validParamValue2);
@@ -362,8 +406,10 @@ public:
const std::string& defaultValue,
const std::string& validParamValue1,
const std::string& validParamValue2,
- const std::string& validParamValue3):
- NameMatchOptionHandler(optName, description, defaultValue)
+ const std::string& validParamValue3,
+ char shortName = 0):
+ NameMatchOptionHandler(optName, description, defaultValue,
+ OptionHandler::REQ_ARG, shortName)
{
_validParamValues.push_back(validParamValue1);
_validParamValues.push_back(validParamValue2);
@@ -372,7 +418,7 @@ public:
virtual ~ParameterOptionHandler() {}
- virtual void parseArg(Option* option, const std::string& optarg)
+ virtual void parseArg(Option& option, const std::string& optarg)
{
std::deque<std::string>::const_iterator itr =
std::find(_validParamValues.begin(), _validParamValues.end(), optarg);
@@ -388,7 +434,7 @@ public:
}
throw FatalException(msg);
} else {
- option->put(_optName, optarg);
+ option.put(_optName, optarg);
}
}
@@ -411,14 +457,16 @@ public:
const std::string& description,
const std::string& defaultValue,
const std::string& hostOptionName,
- const std::string& portOptionName):
- NameMatchOptionHandler(optName, description, defaultValue),
+ const std::string& portOptionName,
+ char shortName = 0):
+ NameMatchOptionHandler(optName, description, defaultValue,
+ OptionHandler::REQ_ARG, shortName),
_hostOptionName(hostOptionName),
_portOptionName(portOptionName) {}
virtual ~HostPortOptionHandler() {}
- virtual void parseArg(Option* option, const std::string& optarg)
+ virtual void parseArg(Option& option, const std::string& optarg)
{
std::pair<std::string, std::string> proxy = Util::split(optarg, ":");
int32_t port = Util::parseInt(proxy.second);
@@ -426,14 +474,14 @@ public:
port <= 0 || 65535 < port) {
throw FatalException(_("unrecognized proxy format"));
}
- option->put(_optName, optarg);
+ option.put(_optName, optarg);
setHostAndPort(option, proxy.first, port);
}
- void setHostAndPort(Option* option, const std::string& hostname, uint16_t port)
+ void setHostAndPort(Option& option, const std::string& hostname, uint16_t port)
{
- option->put(_hostOptionName, hostname);
- option->put(_portOptionName, Util::uitos(port));
+ option.put(_hostOptionName, hostname);
+ option.put(_portOptionName, Util::uitos(port));
}
virtual std::string createPossibleValuesString() const
@@ -446,14 +494,16 @@ class HttpProxyOptionHandler : public NameMatchOptionHandler {
public:
HttpProxyOptionHandler(const std::string& optName,
const std::string& description,
- const std::string& defaultValue)
+ const std::string& defaultValue,
+ char shortName = 0)
:
- NameMatchOptionHandler(optName, description, defaultValue)
+ NameMatchOptionHandler(optName, description, defaultValue,
+ OptionHandler::REQ_ARG, shortName)
{}
virtual ~HttpProxyOptionHandler() {}
- virtual void parseArg(Option* option, const std::string& optarg)
+ virtual void parseArg(Option& option, const std::string& optarg)
{
Request req;
std::string url;
@@ -463,7 +513,7 @@ public:
url = "http://"+optarg;
}
if(req.setUrl(url)) {
- option->put(_optName, url);
+ option.put(_optName, url);
} else {
throw FatalException(_("unrecognized proxy format"));
}
diff --git a/src/OptionParser.cc b/src/OptionParser.cc
index a2db7b06..c2ef8333 100644
--- a/src/OptionParser.cc
+++ b/src/OptionParser.cc
@@ -33,17 +33,126 @@
*/
/* copyright --> */
#include "OptionParser.h"
+
+#include <unistd.h>
+#include <getopt.h>
+
+#include <cstring>
+#include <istream>
+#include <utility>
+
#include "Util.h"
#include "OptionHandlerImpl.h"
#include "Option.h"
#include "A2STR.h"
#include "a2functional.h"
-#include <istream>
-#include <utility>
+#include "array_fun.h"
namespace aria2 {
-void OptionParser::parse(Option* option, std::istream& is)
+OptionParser::OptionParser():_idCounter(0) {}
+
+template<typename InputIterator>
+static size_t countPublicOption(InputIterator first, InputIterator last)
+{
+ size_t count = 0;
+ for(; first != last; ++first) {
+ if(!(*first)->isHidden()) {
+ ++count;
+ }
+ }
+ return count;
+}
+
+template<typename InputIterator>
+static void putOptions(struct option* longOpts, int* plopt,
+ InputIterator first, InputIterator last)
+{
+ for(; first != last; ++first) {
+ if(!(*first)->isHidden()) {
+ (*longOpts).name = (*first)->getName().c_str();
+ switch((*first)->getArgType()) {
+ case OptionHandler::REQ_ARG:
+ (*longOpts).has_arg = required_argument;
+ break;
+ case OptionHandler::OPT_ARG:
+ (*longOpts).has_arg = optional_argument;
+ break;
+ case OptionHandler::NO_ARG:
+ (*longOpts).has_arg = no_argument;
+ break;
+ default:
+ abort();
+ }
+ if((*first)->getShortName() == 0) {
+ (*longOpts).flag = plopt;
+ (*longOpts).val = (*first)->getOptionID();
+ } else {
+ (*longOpts).flag = 0;
+ (*longOpts).val = (*first)->getShortName();
+ }
+ ++longOpts;
+ }
+ }
+ (*longOpts).name = 0;
+ (*longOpts).has_arg = 0;
+ (*longOpts).flag = 0;
+ (*longOpts).val = 0;
+}
+
+template<typename InputIterator>
+static std::string createOptstring(InputIterator first, InputIterator last)
+{
+ std::string str = "";
+ for(; first != last; ++first) {
+ if(!(*first)->isHidden()) {
+ if((*first)->getShortName() != 0) {
+ str += (*first)->getShortName();
+ if((*first)->getArgType() == OptionHandler::REQ_ARG) {
+ str += ":";
+ } else if((*first)->getArgType() == OptionHandler::OPT_ARG) {
+ str += "::";
+ }
+ }
+ }
+ }
+ return str;
+}
+
+void OptionParser::parseArg
+(std::ostream& out, std::deque<std::string>& nonopts, int argc, char* const argv[])
+{
+ size_t numPublicOption = countPublicOption(_optionHandlers.begin(),
+ _optionHandlers.end());
+ int lopt;
+ array_ptr<struct option> longOpts(new struct option[numPublicOption+1]);
+ putOptions(&longOpts[0], &lopt,_optionHandlers.begin(),_optionHandlers.end());
+ std::string optstring = createOptstring(_optionHandlers.begin(),
+ _optionHandlers.end());
+ while(1) {
+ int c = getopt_long(argc, argv, optstring.c_str(), &longOpts[0], 0);
+ if(c == -1) {
+ break;
+ }
+ SharedHandle<OptionHandler> op;
+ if(c == 0) {
+ op = findByID(lopt);
+ } else {
+ op = findByShortName(c);
+ }
+ if(op.isNull()) {
+ throw FatalException("Unknown option");
+ }
+ out << op->getName() << "=";
+ if(optarg) {
+ out << optarg;
+ }
+ out << "\n";
+ }
+ std::copy(argv+optind, argv+argc, std::back_inserter(nonopts));
+}
+
+void OptionParser::parse(Option& option, std::istream& is)
{
std::string line;
int32_t linenum = 0;
@@ -72,15 +181,20 @@ OptionHandlerHandle OptionParser::getOptionHandlerByName(const std::string& optN
void OptionParser::setOptionHandlers(const std::deque<SharedHandle<OptionHandler> >& optionHandlers)
{
_optionHandlers = optionHandlers;
+ for(std::deque<SharedHandle<OptionHandler> >::iterator i =
+ _optionHandlers.begin(); i != _optionHandlers.end(); ++i) {
+ (*i)->setOptionID(++_idCounter);
+ }
}
void OptionParser::addOptionHandler
(const SharedHandle<OptionHandler>& optionHandler)
{
+ optionHandler->setOptionID(++_idCounter);
_optionHandlers.push_back(optionHandler);
}
-void OptionParser::parseDefaultValues(Option* option) const
+void OptionParser::parseDefaultValues(Option& option) const
{
for(std::deque<SharedHandle<OptionHandler> >::const_iterator i =
_optionHandlers.begin(); i != _optionHandlers.end(); ++i) {
@@ -137,6 +251,27 @@ OptionParser::findByNameSubstring(const std::string& substring) const
return result;
}
+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;
+}
+
+template<typename InputIterator, typename Predicate>
+static SharedHandle<OptionHandler> findOptionHandler
+(InputIterator first, InputIterator last, Predicate pred)
+{
+ InputIterator i = std::find_if(first, last, pred);
+ if(i == last) {
+ return SharedHandle<OptionHandler>();
+ } else {
+ return *i;
+ }
+}
+
class FindByName :
public std::unary_function<SharedHandle<OptionHandler> , bool> {
private:
@@ -150,28 +285,52 @@ public:
}
};
-std::deque<SharedHandle<OptionHandler> > OptionParser::findAll() const
+SharedHandle<OptionHandler>
+OptionParser::findByName(const std::string& name) 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;
+ return findOptionHandler(_optionHandlers.begin(), _optionHandlers.end(),
+ FindByName(name));
}
-SharedHandle<OptionHandler>
-OptionParser::findByName(const std::string& name) const
+class FindByID:public std::unary_function<SharedHandle<OptionHandler>, bool> {
+private:
+ int _id;
+public:
+ FindByID(int id):_id(id) {}
+
+ bool operator()(const SharedHandle<OptionHandler>& optionHandler) const
+ {
+ return !optionHandler->isHidden() && optionHandler->getOptionID() == _id;
+ }
+};
+
+SharedHandle<OptionHandler> OptionParser::findByID(int id) 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;
+ return findOptionHandler(_optionHandlers.begin(), _optionHandlers.end(),
+ FindByID(id));
+}
+
+class FindByShortName:
+ public std::unary_function<SharedHandle<OptionHandler>, bool> {
+private:
+ char _shortName;
+public:
+ FindByShortName(char shortName):_shortName(shortName) {}
+
+ bool operator()(const SharedHandle<OptionHandler>& optionHandler) const
+ {
+ return !optionHandler->isHidden() &&
+ optionHandler->getShortName() == _shortName;
}
+};
+
+SharedHandle<OptionHandler> OptionParser::findByShortName(char shortName) const
+{
+ return findOptionHandler(_optionHandlers.begin(), _optionHandlers.end(),
+ FindByShortName(shortName));
}
+
const std::deque<SharedHandle<OptionHandler> >&
OptionParser::getOptionHandlers() const
{
diff --git a/src/OptionParser.h b/src/OptionParser.h
index fc5fce9c..b02f46c1 100644
--- a/src/OptionParser.h
+++ b/src/OptionParser.h
@@ -36,11 +36,13 @@
#define _D_OPTION_PARSER_H_
#include "common.h"
-#include "SharedHandle.h"
+
#include <string>
#include <deque>
#include <iosfwd>
+#include "SharedHandle.h"
+
namespace aria2 {
class Option;
@@ -48,16 +50,26 @@ class OptionHandler;
class OptionParser {
private:
+ int _idCounter;
+
std::deque<SharedHandle<OptionHandler> > _optionHandlers;
SharedHandle<OptionHandler>
getOptionHandlerByName(const std::string& optName);
public:
+ OptionParser();
+
~OptionParser() {}
- void parse(Option* option, std::istream& ios);
+ // Parses options in argv and writes option name and value to out in
+ // NAME=VALUE format. Non-option strings are stored in nonopts.
+ // Throws FatalException when an unrecognized option is found.
+ void parseArg(std::ostream& out, std::deque<std::string>& nonopts,
+ int argc, char* const argv[]);
+
+ void parse(Option& option, std::istream& ios);
- void parseDefaultValues(Option* option) const;
+ void parseDefaultValues(Option& option) const;
void setOptionHandlers
(const std::deque<SharedHandle<OptionHandler> >& optionHandlers);
@@ -75,6 +87,10 @@ public:
SharedHandle<OptionHandler>
findByName(const std::string& name) const;
+ SharedHandle<OptionHandler> findByID(int id) const;
+
+ SharedHandle<OptionHandler> findByShortName(char shortName) const;
+
const std::deque<SharedHandle<OptionHandler> >& getOptionHandlers() const;
};
diff --git a/src/array_fun.h b/src/array_fun.h
index ccf837a0..0c2327f4 100644
--- a/src/array_fun.h
+++ b/src/array_fun.h
@@ -215,6 +215,43 @@ size_t arrayLength(T (&a)[0u])
return 0;
}
+template<typename T>
+class array_ptr {
+private:
+ T* _array;
+
+ // Copies are not allowed. Let's make them private.
+ array_ptr(const array_ptr& s);
+
+ template<typename S>
+ array_ptr(const array_ptr<S>& s);
+
+ array_ptr& operator=(const array_ptr& s);
+
+ template<typename S>
+ array_ptr& operator=(const array_ptr<S>& s);
+
+public:
+ array_ptr():_array(0) {}
+
+ explicit array_ptr(T* array):_array(array) {}
+
+ ~array_ptr()
+ {
+ delete [] _array;
+ }
+
+ T& operator[](size_t index)
+ {
+ return _array[index];
+ }
+
+ const T& operator[](size_t index) const
+ {
+ return _array[index];
+ }
+};
+
} // namespace aria2
#endif // _D_ARRAY_FUN_H_
diff --git a/src/main.cc b/src/main.cc
index 2ca2479d..aea7bcc2 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -157,32 +157,34 @@ static void showFiles(const std::deque<std::string>& uris, const Option* op)
}
#endif // ENABLE_BITTORRENT || ENABLE_METALINK
-extern Option* option_processing(int argc, char* const argv[]);
+extern void option_processing(Option& option, std::deque<std::string>& uris,
+ int argc, char* const argv[]);
DownloadResult::RESULT main(int argc, char* argv[])
{
- Option* op = option_processing(argc, argv);
- std::deque<std::string> args(argv+optind, argv+argc);
+ std::deque<std::string> args;
+ Option op;
+ option_processing(op, args, argc, argv);
SimpleRandomizer::init();
BitfieldManFactory::setDefaultRandomizer(SimpleRandomizer::getInstance());
- if(op->get(PREF_LOG) == "-") {
+ if(op.get(PREF_LOG) == "-") {
LogFactory::setLogFile(DEV_STDOUT);
- } else if(!op->get(PREF_LOG).empty()) {
- LogFactory::setLogFile(op->get(PREF_LOG));
+ } else if(!op.get(PREF_LOG).empty()) {
+ LogFactory::setLogFile(op.get(PREF_LOG));
} else {
LogFactory::setLogFile(DEV_NULL);
}
- LogFactory::setLogLevel(op->get(PREF_LOG_LEVEL));
- if(op->getAsBool(PREF_QUIET)) {
+ LogFactory::setLogLevel(op.get(PREF_LOG_LEVEL));
+ if(op.getAsBool(PREF_QUIET)) {
LogFactory::setConsoleOutput(false);
}
#ifdef HAVE_EPOLL
- if(op->get(PREF_EVENT_POLL) == V_EPOLL) {
+ if(op.get(PREF_EVENT_POLL) == V_EPOLL) {
SocketCore::useEpoll();
} else
#endif // HAVE_EPOLL
- if(op->get(PREF_EVENT_POLL) == V_SELECT) {
+ if(op.get(PREF_EVENT_POLL) == V_SELECT) {
SocketCore::useSelect();
}
DownloadResult::RESULT exitStatus = DownloadResult::FINISHED;
@@ -203,48 +205,47 @@ DownloadResult::RESULT main(int argc, char* argv[])
#endif
std::deque<SharedHandle<RequestGroup> > requestGroups;
#ifdef ENABLE_BITTORRENT
- if(!op->blank(PREF_TORRENT_FILE)) {
- if(op->get(PREF_SHOW_FILES) == V_TRUE) {
- showTorrentFile(op->get(PREF_TORRENT_FILE));
+ if(!op.blank(PREF_TORRENT_FILE)) {
+ if(op.get(PREF_SHOW_FILES) == V_TRUE) {
+ showTorrentFile(op.get(PREF_TORRENT_FILE));
return exitStatus;
} else {
- createRequestGroupForBitTorrent(requestGroups, op, args);
+ createRequestGroupForBitTorrent(requestGroups, &op, args);
}
}
else
#endif // ENABLE_BITTORRENT
#ifdef ENABLE_METALINK
- if(!op->blank(PREF_METALINK_FILE)) {
- if(op->get(PREF_SHOW_FILES) == V_TRUE) {
- showMetalinkFile(op->get(PREF_METALINK_FILE), op);
+ if(!op.blank(PREF_METALINK_FILE)) {
+ if(op.get(PREF_SHOW_FILES) == V_TRUE) {
+ showMetalinkFile(op.get(PREF_METALINK_FILE), &op);
return exitStatus;
} else {
- createRequestGroupForMetalink(requestGroups, op);
+ createRequestGroupForMetalink(requestGroups, &op);
}
}
else
#endif // ENABLE_METALINK
- if(!op->blank(PREF_INPUT_FILE)) {
- createRequestGroupForUriList(requestGroups, op);
+ if(!op.blank(PREF_INPUT_FILE)) {
+ createRequestGroupForUriList(requestGroups, &op);
#if defined ENABLE_BITTORRENT || defined ENABLE_METALINK
- } else if(op->get(PREF_SHOW_FILES) == V_TRUE) {
- showFiles(args, op);
+ } else if(op.get(PREF_SHOW_FILES) == V_TRUE) {
+ showFiles(args, &op);
#endif // ENABLE_METALINK || ENABLE_METALINK
} else {
- createRequestGroupForUri(requestGroups, op, args);
+ createRequestGroupForUri(requestGroups, &op, args);
}
if(requestGroups.empty()) {
std::cout << MSG_NO_FILES_TO_DOWNLOAD << std::endl;
} else {
- exitStatus = MultiUrlRequestInfo(requestGroups, op, getStatCalc(op),
- getSummaryOut(op)).execute();
+ exitStatus = MultiUrlRequestInfo(requestGroups, &op, getStatCalc(&op),
+ getSummaryOut(&op)).execute();
}
} catch(Exception& ex) {
std::cerr << EX_EXCEPTION_CAUGHT << "\n" << ex.stackTrace() << std::endl;
exitStatus = DownloadResult::UNKNOWN_ERROR;
}
- delete op;
LogFactory::release();
return exitStatus;
}
diff --git a/src/option_processing.cc b/src/option_processing.cc
index 81e72096..681c531f 100644
--- a/src/option_processing.cc
+++ b/src/option_processing.cc
@@ -55,27 +55,12 @@
#include "OptionHandlerException.h"
#include "DownloadResult.h"
-extern char* optarg;
-extern int optind, opterr, optopt;
-#include <getopt.h>
-
namespace aria2 {
extern void showVersion();
extern void showUsage(const std::string& keyword, const OptionParser& oparser);
-static std::string toBoolArg(const char* optarg)
-{
- std::string arg;
- if(!optarg || strlen(optarg) == 0) {
- arg = V_TRUE;
- } else {
- arg = optarg;
- }
- return arg;
-}
-
-static void overrideWithEnv(Option* op, const OptionParser& optionParser,
+static void overrideWithEnv(Option& op, const OptionParser& optionParser,
const std::string& pref,
const std::string& envName)
{
@@ -92,501 +77,33 @@ static void overrideWithEnv(Option* op, const OptionParser& optionParser,
}
}
-Option* option_processing(int argc, char* const argv[])
+void option_processing(Option& op, std::deque<std::string>& uris,
+ int argc, char* const argv[])
{
- std::stringstream cmdstream;
- int32_t c;
- Option* op = new Option();
-
- // following options are not parsed by OptionHandler and not stored in Option.
- bool noConf = false;
- std::string ucfname;
-
OptionParser oparser;
oparser.setOptionHandlers(OptionHandlerFactory::createOptionHandlers());
try {
- oparser.parseDefaultValues(op);
- } catch(Exception& e) {
- std::cerr << e.stackTrace();
- exit(DownloadResult::UNKNOWN_ERROR);
- }
+ bool noConf = false;
+ std::string ucfname;
+ std::stringstream cmdstream;
+ oparser.parseArg(cmdstream, uris, argc, argv);
+ {
+ // first evaluate --no-conf and --conf-path options.
+ Option op;
+ oparser.parse(op, cmdstream);
+ noConf = op.getAsBool(PREF_NO_CONF);
+ ucfname = op.get(PREF_CONF_PATH);
- while(1) {
- int optIndex = 0;
- int lopt;
- static struct option longOpts[] = {
-#ifdef HAVE_DAEMON
- { PREF_DAEMON.c_str(), no_argument, NULL, 'D' },
-#endif // HAVE_DAEMON
- { PREF_DIR.c_str(), required_argument, NULL, 'd' },
- { PREF_OUT.c_str(), required_argument, NULL, 'o' },
- { PREF_LOG.c_str(), required_argument, NULL, 'l' },
- { PREF_SPLIT.c_str(), required_argument, NULL, 's' },
- { PREF_TIMEOUT.c_str(), required_argument, NULL, 't' },
- { PREF_MAX_TRIES.c_str(), required_argument, NULL, 'm' },
- { PREF_HTTP_PROXY.c_str(), required_argument, &lopt, 1 },
- { PREF_HTTP_USER.c_str(), required_argument, &lopt, 2 },
- { PREF_HTTP_PASSWD.c_str(), required_argument, &lopt, 3 },
- { "http-proxy-user", required_argument, &lopt, 4 },
- { "http-proxy-passwd", required_argument, &lopt, 5 },
- { PREF_HTTP_AUTH_SCHEME.c_str(), required_argument, &lopt, 6 },
- { PREF_REFERER.c_str(), required_argument, &lopt, 7 },
- { PREF_RETRY_WAIT.c_str(), required_argument, &lopt, 8 },
- { PREF_FTP_USER.c_str(), required_argument, &lopt, 9 },
- { PREF_FTP_PASSWD.c_str(), required_argument, &lopt, 10 },
- { PREF_FTP_TYPE.c_str(), required_argument, &lopt, 11 },
- { PREF_FTP_PASV.c_str(), optional_argument, 0, 'p' },
- { "ftp-via-http-proxy", required_argument, &lopt, 12 },
- { "http-proxy-method", required_argument, &lopt, 14 },
- { PREF_LOWEST_SPEED_LIMIT.c_str(), required_argument, &lopt, 200 },
- { PREF_MAX_DOWNLOAD_LIMIT.c_str(), required_argument, &lopt, 201 },
- { PREF_FILE_ALLOCATION.c_str(), required_argument, 0, 'a' },
- { PREF_ALLOW_OVERWRITE.c_str(), required_argument, &lopt, 202 },
-#ifdef ENABLE_MESSAGE_DIGEST
- { PREF_CHECK_INTEGRITY.c_str(), optional_argument, 0, 'V' },
- { PREF_REALTIME_CHUNK_CHECKSUM.c_str(), required_argument, &lopt, 204 },
-#endif // ENABLE_MESSAGE_DIGEST
- { PREF_CONTINUE.c_str(), no_argument, 0, 'c' },
- { PREF_USER_AGENT.c_str(), required_argument, 0, 'U' },
- { PREF_NO_NETRC.c_str(), no_argument, 0, 'n' },
- { PREF_INPUT_FILE.c_str(), required_argument, 0, 'i' },
- { PREF_MAX_CONCURRENT_DOWNLOADS.c_str(), required_argument, 0, 'j' },
- { PREF_LOAD_COOKIES.c_str(), required_argument, &lopt, 205 },
- { PREF_FORCE_SEQUENTIAL.c_str(), optional_argument, 0, 'Z' },
- { PREF_AUTO_FILE_RENAMING.c_str(), optional_argument, &lopt, 206 },
- { PREF_PARAMETERIZED_URI.c_str(), optional_argument, 0, 'P' },
- { PREF_ENABLE_HTTP_KEEP_ALIVE.c_str(), optional_argument, &lopt, 207 },
- { PREF_ENABLE_HTTP_PIPELINING.c_str(), optional_argument, &lopt, 208 },
- { PREF_NO_FILE_ALLOCATION_LIMIT.c_str(), required_argument, &lopt, 209 },
-#ifdef ENABLE_DIRECT_IO
- { PREF_ENABLE_DIRECT_IO.c_str(), optional_argument, &lopt, 210 },
-#endif // ENABLE_DIRECT_IO
- { PREF_ALLOW_PIECE_LENGTH_CHANGE.c_str(), required_argument, &lopt, 211 },
- { PREF_NO_CONF.c_str(), no_argument, &lopt, 212 },
- { PREF_CONF_PATH.c_str(), required_argument, &lopt, 213 },
- { PREF_STOP.c_str(), required_argument, &lopt, 214 },
- { PREF_HEADER.c_str(), required_argument, &lopt, 215 },
- { PREF_QUIET.c_str(), optional_argument, 0, 'q' },
-#ifdef ENABLE_ASYNC_DNS
- { PREF_ASYNC_DNS.c_str(), optional_argument, &lopt, 216 },
-#endif // ENABLE_ASYNC_DNS
- { PREF_FTP_REUSE_CONNECTION.c_str(), optional_argument, &lopt, 217 },
- { PREF_SUMMARY_INTERVAL.c_str(), required_argument, &lopt, 218 },
- { PREF_LOG_LEVEL.c_str(), required_argument, &lopt, 219 },
- { PREF_URI_SELECTOR.c_str(), required_argument, &lopt, 220 },
- { PREF_SERVER_STAT_IF.c_str(), required_argument, &lopt, 221 },
- { PREF_SERVER_STAT_OF.c_str(), required_argument, &lopt, 222 },
- { PREF_SERVER_STAT_TIMEOUT.c_str(), required_argument, &lopt, 223 },
- { PREF_REMOTE_TIME.c_str(), optional_argument, 0, 'R' },
- { PREF_CONNECT_TIMEOUT.c_str(), required_argument, &lopt, 224 },
- { PREF_MAX_FILE_NOT_FOUND.c_str(), required_argument, &lopt, 225 },
- { PREF_AUTO_SAVE_INTERVAL.c_str(), required_argument, &lopt, 226 },
- { PREF_HTTPS_PROXY.c_str(), required_argument, &lopt, 227 },
- { PREF_FTP_PROXY.c_str(), required_argument, &lopt, 228 },
- { PREF_ALL_PROXY.c_str(), required_argument, &lopt, 229 },
- { PREF_PROXY_METHOD.c_str(), required_argument, &lopt, 230 },
- { PREF_CERTIFICATE.c_str(), required_argument, &lopt, 231 },
- { PREF_PRIVATE_KEY.c_str(), required_argument, &lopt, 232 },
- { PREF_CA_CERTIFICATE.c_str(), optional_argument, &lopt, 233 },
- { PREF_CHECK_CERTIFICATE.c_str(), optional_argument, &lopt, 234 },
- { PREF_NO_PROXY.c_str(), required_argument, &lopt, 235 },
- { PREF_USE_HEAD.c_str(), optional_argument, &lopt, 236 },
- { PREF_EVENT_POLL.c_str(), required_argument, &lopt, 237 },
- { PREF_HTTP_SERVER_LISTEN_PORT.c_str(), required_argument, &lopt, 238 },
- { PREF_ENABLE_HTTP_SERVER.c_str(), optional_argument, &lopt, 239 },
-#if defined ENABLE_BITTORRENT || defined ENABLE_METALINK
- { PREF_SHOW_FILES.c_str(), no_argument, NULL, 'S' },
- { PREF_SELECT_FILE.c_str(), required_argument, &lopt, 21 },
-#endif // ENABLE_BITTORRENT || ENABLE_METALINK
-#ifdef ENABLE_BITTORRENT
- { PREF_TORRENT_FILE.c_str(), required_argument, NULL, 'T' },
- { PREF_LISTEN_PORT.c_str(), required_argument, &lopt, 15 },
- { PREF_FOLLOW_TORRENT.c_str(), required_argument, &lopt, 16 },
- { PREF_DIRECT_FILE_MAPPING.c_str(), required_argument, &lopt, 19 },
- // TODO remove upload-limit.
- //{ "upload-limit".c_str(), required_argument, &lopt, 20 },
- { PREF_SEED_TIME.c_str(), required_argument, &lopt, 22 },
- { PREF_SEED_RATIO.c_str(), required_argument, &lopt, 23 },
- { PREF_MAX_UPLOAD_LIMIT.c_str(), required_argument, 0, 'u' },
- { PREF_PEER_ID_PREFIX.c_str(), required_argument, &lopt, 25 },
- { PREF_ENABLE_PEER_EXCHANGE.c_str(), optional_argument, &lopt, 26 },
- { PREF_ENABLE_DHT.c_str(), optional_argument, &lopt, 27 },
- { PREF_DHT_LISTEN_PORT.c_str(), required_argument, &lopt, 28 },
- { PREF_DHT_ENTRY_POINT.c_str(), required_argument, &lopt, 29 },
- { PREF_BT_MIN_CRYPTO_LEVEL.c_str(), required_argument, &lopt, 30 },
- { PREF_BT_REQUIRE_CRYPTO.c_str(), required_argument, &lopt, 31 },
- { PREF_BT_REQUEST_PEER_SPEED_LIMIT.c_str(), required_argument, &lopt, 32 },
- { PREF_BT_MAX_OPEN_FILES.c_str(), required_argument, &lopt, 33 },
- { PREF_BT_SEED_UNVERIFIED.c_str(), optional_argument, &lopt, 34 },
- { PREF_DHT_FILE_PATH.c_str(), required_argument, &lopt, 35 },
- { PREF_MAX_OVERALL_UPLOAD_LIMIT.c_str(), required_argument, &lopt, 36 },
- { PREF_BT_HASH_CHECK_SEED.c_str(), optional_argument, &lopt, 37 },
- { PREF_BT_MAX_PEERS.c_str(), required_argument, &lopt, 38 },
- { PREF_BT_EXTERNAL_IP.c_str(), required_argument, &lopt, 39 },
-#endif // ENABLE_BITTORRENT
-#ifdef ENABLE_METALINK
- { PREF_METALINK_FILE.c_str(), required_argument, NULL, 'M' },
- { PREF_METALINK_SERVERS.c_str(), required_argument, NULL, 'C' },
- { PREF_METALINK_VERSION.c_str(), required_argument, &lopt, 100 },
- { PREF_METALINK_LANGUAGE.c_str(), required_argument, &lopt, 101 },
- { PREF_METALINK_OS.c_str(), required_argument, &lopt, 102 },
- { PREF_FOLLOW_METALINK.c_str(), required_argument, &lopt, 103 },
- { PREF_METALINK_LOCATION.c_str(), required_argument, &lopt, 104 },
- { PREF_METALINK_PREFERRED_PROTOCOL.c_str(), required_argument, &lopt, 105 },
- { PREF_METALINK_ENABLE_UNIQUE_PROTOCOL.c_str(), optional_argument, &lopt, 106 },
-#endif // ENABLE_METALINK
- { "version", no_argument, NULL, 'v' },
- { "help", optional_argument, NULL, 'h' },
- { 0, 0, 0, 0 }
- };
- c = getopt_long(argc, argv,
- "Dd:o:l:s:p::t:m:vh::ST:M:C:a:cU:ni:j:Z::P::q::R::V::u:",
- longOpts, &optIndex);
- if(c == -1) {
- break;
- }
- switch(c) {
- case 0:{
- switch(lopt) {
- case 1:
- cmdstream << PREF_HTTP_PROXY << "=" << optarg << "\n";
- break;
- case 2:
- cmdstream << PREF_HTTP_USER << "=" << optarg << "\n";
- break;
- case 3:
- cmdstream << PREF_HTTP_PASSWD << "=" << optarg << "\n";
- break;
- case 4:
- std::cout << "--http-proxy-user was deprecated. See --http-proxy,"
- << " --https-proxy, --ftp-proxy, --all-proxy options."
- << std::endl;
- exit(DownloadResult::UNKNOWN_ERROR);
- case 5:
- std::cout << "--http-proxy-passwd was deprecated. See --http-proxy,"
- << " --https-proxy, --ftp-proxy, --all-proxy options."
- << std::endl;
- exit(DownloadResult::UNKNOWN_ERROR);
- case 6:
- cmdstream << PREF_HTTP_AUTH_SCHEME << "=" << optarg << "\n";
- break;
- case 7:
- cmdstream << PREF_REFERER << "=" << optarg << "\n";
- break;
- case 8:
- cmdstream << PREF_RETRY_WAIT << "=" << optarg << "\n";
- break;
- case 9:
- cmdstream << PREF_FTP_USER << "=" << optarg << "\n";
- break;
- case 10:
- cmdstream << PREF_FTP_PASSWD << "=" << optarg << "\n";
- break;
- case 11:
- cmdstream << PREF_FTP_TYPE << "=" << optarg << "\n";
- break;
- case 12:
- std::cout << "--ftp-via-http-proxy was deprecated."
- << " Use --http-proxy-method option instead."
- << std::endl;
- exit(DownloadResult::UNKNOWN_ERROR);
- case 14:
- std::cout << "--http-proxy-method was deprecated."
- << " Use --proxy-method option instead."
- << std::endl;
- exit(DownloadResult::UNKNOWN_ERROR);
- case 15:
- cmdstream << PREF_LISTEN_PORT << "=" << optarg << "\n";
- break;
- case 16:
- cmdstream << PREF_FOLLOW_TORRENT << "=" << optarg << "\n";
- break;
- case 19:
- cmdstream << PREF_DIRECT_FILE_MAPPING << "=" << optarg << "\n";
- break;
- case 21:
- cmdstream << PREF_SELECT_FILE << "=" << optarg << "\n";
- break;
- case 22:
- cmdstream << PREF_SEED_TIME << "=" << optarg << "\n";
- break;
- case 23:
- cmdstream << PREF_SEED_RATIO << "=" << optarg << "\n";
- break;
- case 25:
- cmdstream << PREF_PEER_ID_PREFIX << "=" << optarg << "\n";
- break;
- case 26:
- cmdstream << PREF_ENABLE_PEER_EXCHANGE << "=" << toBoolArg(optarg) << "\n";
- break;
- case 27:
- cmdstream << PREF_ENABLE_DHT << "=" << toBoolArg(optarg) << "\n";
- break;
- case 28:
- cmdstream << PREF_DHT_LISTEN_PORT << "=" << optarg << "\n";
- break;
- case 29:
- cmdstream << PREF_DHT_ENTRY_POINT << "=" << optarg << "\n";
- break;
- case 30:
- cmdstream << PREF_BT_MIN_CRYPTO_LEVEL << "=" << optarg << "\n";
- break;
- case 31:
- cmdstream << PREF_BT_REQUIRE_CRYPTO << "=" << optarg << "\n";
- break;
- case 32:
- cmdstream << PREF_BT_REQUEST_PEER_SPEED_LIMIT << "=" << optarg << "\n";
- break;
- case 33:
- cmdstream << PREF_BT_MAX_OPEN_FILES << "=" << optarg << "\n";
- break;
- case 34:
- cmdstream << PREF_BT_SEED_UNVERIFIED << "=" << toBoolArg(optarg)
- << "\n";
- break;
- case 35:
- cmdstream << PREF_DHT_FILE_PATH << "=" << optarg << "\n";
- break;
- case 36:
- cmdstream << PREF_MAX_OVERALL_UPLOAD_LIMIT << "=" << optarg << "\n";
- break;
- case 37:
- cmdstream << PREF_BT_HASH_CHECK_SEED << "=" << optarg << "\n";
- break;
- case 38:
- cmdstream << PREF_BT_MAX_PEERS << "=" << optarg << "\n";
- break;
- case 39:
- cmdstream << PREF_BT_EXTERNAL_IP << "=" << optarg << "\n";
- break;
- case 100:
- cmdstream << PREF_METALINK_VERSION << "=" << optarg << "\n";
- break;
- case 101:
- cmdstream << PREF_METALINK_LANGUAGE << "=" << optarg << "\n";
- break;
- case 102:
- cmdstream << PREF_METALINK_OS << "=" << optarg << "\n";
- break;
- case 103:
- cmdstream << PREF_FOLLOW_METALINK << "=" << optarg << "\n";
- break;
- case 104:
- cmdstream << PREF_METALINK_LOCATION << "=" << optarg << "\n";
- break;
- case 105:
- cmdstream << PREF_METALINK_PREFERRED_PROTOCOL << "=" << optarg << "\n";
- break;
- case 106:
- cmdstream << PREF_METALINK_ENABLE_UNIQUE_PROTOCOL << "=" << toBoolArg(optarg) << "\n";
- break;
- case 200:
- cmdstream << PREF_LOWEST_SPEED_LIMIT << "=" << optarg << "\n";
- break;
- case 201:
- cmdstream << PREF_MAX_DOWNLOAD_LIMIT << "=" << optarg << "\n";
- break;
- case 202:
- cmdstream << PREF_ALLOW_OVERWRITE << "=" << optarg << "\n";
- break;
- case 204:
- cmdstream << PREF_REALTIME_CHUNK_CHECKSUM << "=" << optarg << "\n";
- break;
- case 205:
- cmdstream << PREF_LOAD_COOKIES << "=" << optarg << "\n";
- break;
- case 206:
- cmdstream << PREF_AUTO_FILE_RENAMING << "=" << toBoolArg(optarg) << "\n";
- break;
- case 207:
- cmdstream << PREF_ENABLE_HTTP_KEEP_ALIVE << "=" << toBoolArg(optarg) << "\n";
- break;
- case 208:
- cmdstream << PREF_ENABLE_HTTP_PIPELINING << "=" << toBoolArg(optarg) << "\n";
- break;
- case 209:
- cmdstream << PREF_NO_FILE_ALLOCATION_LIMIT << "=" << optarg << "\n";
- break;
- case 210:
- cmdstream << PREF_ENABLE_DIRECT_IO << "=" << toBoolArg(optarg) << "\n";
- break;
- case 211:
- cmdstream << PREF_ALLOW_PIECE_LENGTH_CHANGE << "=" << optarg << "\n";
- break;
- case 212:
- noConf = true;
- break;
- case 213:
- ucfname = optarg;
- break;
- case 214:
- cmdstream << PREF_STOP << "=" << optarg << "\n";
- break;
- case 215:
- cmdstream << PREF_HEADER << "=" << optarg << "\n";
- break;
-#ifdef ENABLE_ASYNC_DNS
- case 216:
- cmdstream << PREF_ASYNC_DNS << "=" << toBoolArg(optarg) << "\n";
- break;
-#endif // ENABLE_ASYNC_DNS
- case 217:
- cmdstream << PREF_FTP_REUSE_CONNECTION << "=" << toBoolArg(optarg) << "\n";
- break;
- case 218:
- cmdstream << PREF_SUMMARY_INTERVAL << "=" << optarg << "\n";
- break;
- case 219:
- cmdstream << PREF_LOG_LEVEL << "=" << optarg << "\n";
- break;
- case 220:
- cmdstream << PREF_URI_SELECTOR << "=" << optarg << "\n";
- break;
- case 221:
- cmdstream << PREF_SERVER_STAT_IF << "=" << optarg << "\n";
- break;
- case 222:
- cmdstream << PREF_SERVER_STAT_OF << "=" << optarg << "\n";
- break;
- case 223:
- cmdstream << PREF_SERVER_STAT_TIMEOUT << "=" << optarg << "\n";
- break;
- case 224:
- cmdstream << PREF_CONNECT_TIMEOUT << "=" << optarg << "\n";
- break;
- case 225:
- cmdstream << PREF_MAX_FILE_NOT_FOUND << "=" << optarg << "\n";
- break;
- case 226:
- cmdstream << PREF_AUTO_SAVE_INTERVAL << "=" << optarg << "\n";
- break;
- case 227:
- cmdstream << PREF_HTTPS_PROXY << "=" << optarg << "\n";
- break;
- case 228:
- cmdstream << PREF_FTP_PROXY << "=" << optarg << "\n";
- break;
- case 229:
- cmdstream << PREF_ALL_PROXY << "=" << optarg << "\n";
- break;
- case 230:
- cmdstream << PREF_PROXY_METHOD << "=" << optarg << "\n";
- break;
- case 231:
- cmdstream << PREF_CERTIFICATE << "=" << optarg << "\n";
- break;
- case 232:
- cmdstream << PREF_PRIVATE_KEY << "=" << optarg << "\n";
- break;
- case 233:
- cmdstream << PREF_CA_CERTIFICATE << "=" << optarg << "\n";
- break;
- case 234:
- cmdstream << PREF_CHECK_CERTIFICATE << "=" << toBoolArg(optarg) << "\n";
- break;
- case 235:
- cmdstream << PREF_NO_PROXY << "=" << optarg << "\n";
- break;
- case 236:
- cmdstream << PREF_USE_HEAD << "=" << toBoolArg(optarg) << "\n";
- break;
- case 237:
- cmdstream << PREF_EVENT_POLL << "=" << optarg << "\n";
- break;
- case 238:
- cmdstream << PREF_HTTP_SERVER_LISTEN_PORT << "=" << optarg << "\n";
- break;
- case 239:
- cmdstream << PREF_ENABLE_HTTP_SERVER << "=" << toBoolArg(optarg)
- << "\n";
- break;
+ if(op.defined("version")) {
+ showVersion();
+ exit(DownloadResult::FINISHED);
}
- break;
- }
-#ifdef HAVE_DAEMON
- case 'D':
- cmdstream << PREF_DAEMON << "=" << V_TRUE << "\n";
- break;
-#endif // HAVE_DAEMON
- case 'd':
- cmdstream << PREF_DIR << "=" << optarg << "\n";
- break;
- case 'o':
- cmdstream << PREF_OUT << "=" << optarg << "\n";
- break;
- case 'l':
- cmdstream << PREF_LOG << "=" << optarg << "\n";
- break;
- case 's':
- cmdstream << PREF_SPLIT << "=" << optarg << "\n";
- break;
- case 't':
- cmdstream << PREF_TIMEOUT << "=" << optarg << "\n";
- break;
- case 'm':
- cmdstream << PREF_MAX_TRIES << "=" << optarg << "\n";
- break;
- case 'p':
- cmdstream << PREF_FTP_PASV << "=" << toBoolArg(optarg) << "\n";
- break;
- case 'S':
- cmdstream << PREF_SHOW_FILES << "=" << V_TRUE << "\n";
- break;
- case 'T':
- cmdstream << PREF_TORRENT_FILE << "=" << optarg << "\n";
- break;
- case 'M':
- cmdstream << PREF_METALINK_FILE << "=" << optarg << "\n";
- break;
- case 'C':
- cmdstream << PREF_METALINK_SERVERS << "=" << optarg << "\n";
- break;
- case 'a':
- cmdstream << PREF_FILE_ALLOCATION << "=" << optarg << "\n";
- break;
- case 'c':
- cmdstream << PREF_CONTINUE << "=" << V_TRUE << "\n";
- break;
- case 'U':
- cmdstream << PREF_USER_AGENT << "=" << optarg << "\n";
- break;
- case 'n':
- cmdstream << PREF_NO_NETRC << "=" << V_TRUE << "\n";
- break;
- case 'i':
- cmdstream << PREF_INPUT_FILE << "=" << optarg << "\n";
- break;
- case 'j':
- cmdstream << PREF_MAX_CONCURRENT_DOWNLOADS << "=" << optarg << "\n";
- break;
- case 'Z':
- cmdstream << PREF_FORCE_SEQUENTIAL << "=" << toBoolArg(optarg) << "\n";
- break;
- case 'P':
- cmdstream << PREF_PARAMETERIZED_URI << "=" << toBoolArg(optarg) << "\n";
- break;
- case 'q':
- cmdstream << PREF_QUIET << "=" << toBoolArg(optarg) << "\n";
- break;
- case 'R':
- cmdstream << PREF_REMOTE_TIME << "=" << toBoolArg(optarg) << "\n";
- break;
- case 'V':
- cmdstream << PREF_CHECK_INTEGRITY << "=" << toBoolArg(optarg) << "\n";
- break;
- case 'u':
- cmdstream << PREF_MAX_UPLOAD_LIMIT << "=" << optarg << "\n";
- break;
- case 'v':
- showVersion();
- exit(DownloadResult::FINISHED);
- case 'h':
- {
+ if(op.defined("help")) {
std::string keyword;
- if(optarg == 0 || strlen(optarg) == 0) {
+ if(op.get("help").empty()) {
keyword = TAG_BASIC;
} else {
- keyword = optarg;
+ keyword = op.get("help");
if(Util::startsWith(keyword, "--")) {
keyword = keyword.substr(2);
}
@@ -598,13 +115,10 @@ Option* option_processing(int argc, char* const argv[])
showUsage(keyword, oparser);
exit(DownloadResult::FINISHED);
}
- default:
- showUsage(TAG_HELP, oparser);
- exit(DownloadResult::UNKNOWN_ERROR);
}
- }
- {
+ oparser.parseDefaultValues(op);
+
if(!noConf) {
std::string cfname =
ucfname.empty() ?
@@ -642,43 +156,44 @@ Option* option_processing(int argc, char* const argv[])
overrideWithEnv(op, oparser, PREF_ALL_PROXY, "all_proxy");
overrideWithEnv(op, oparser, PREF_NO_PROXY, "no_proxy");
- try {
- oparser.parse(op, cmdstream);
- } catch(OptionHandlerException& e) {
- std::cerr << e.stackTrace() << "\n"
- << "Usage:" << "\n"
- << oparser.findByName(e.getOptionName())->getDescription()
- << std::endl;
- exit(DownloadResult::UNKNOWN_ERROR);
- } catch(Exception& e) {
- std::cerr << e.stackTrace() << std::endl;
- showUsage(TAG_HELP, oparser);
- exit(DownloadResult::UNKNOWN_ERROR);
- }
+ // we must clear eof bit and seek to the beginning of the buffer.
+ cmdstream.clear();
+ cmdstream.seekg(0, std::ios::beg);
+ // finaly let's parse and store command-iine options.
+ oparser.parse(op, cmdstream);
+ } catch(OptionHandlerException& e) {
+ std::cerr << e.stackTrace() << "\n"
+ << "Usage:" << "\n"
+ << oparser.findByName(e.getOptionName())->getDescription()
+ << std::endl;
+ exit(DownloadResult::UNKNOWN_ERROR);
+ } catch(Exception& e) {
+ std::cerr << e.stackTrace() << std::endl;
+ showUsage(TAG_HELP, oparser);
+ exit(DownloadResult::UNKNOWN_ERROR);
}
if(
#ifdef ENABLE_BITTORRENT
- op->blank(PREF_TORRENT_FILE) &&
+ op.blank(PREF_TORRENT_FILE) &&
#endif // ENABLE_BITTORRENT
#ifdef ENABLE_METALINK
- op->blank(PREF_METALINK_FILE) &&
+ op.blank(PREF_METALINK_FILE) &&
#endif // ENABLE_METALINK
- op->blank(PREF_INPUT_FILE)) {
- if(optind == argc) {
+ op.blank(PREF_INPUT_FILE)) {
+ if(uris.empty()) {
std::cerr << MSG_URI_REQUIRED << std::endl;
showUsage(TAG_HELP, oparser);
exit(DownloadResult::UNKNOWN_ERROR);
}
}
#ifdef HAVE_DAEMON
- if(op->getAsBool(PREF_DAEMON)) {
+ if(op.getAsBool(PREF_DAEMON)) {
if(daemon(1, 1) < 0) {
perror(MSG_DAEMON_FAILED);
exit(DownloadResult::UNKNOWN_ERROR);
}
}
#endif // HAVE_DAEMON
- return op;
}
} // namespace aria2