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
pull/1/head
Tatsuhiro Tsujikawa 2009-02-07 11:00:34 +00:00
parent bbb3589293
commit 2881dbe025
12 changed files with 819 additions and 841 deletions

View File

@ -1,3 +1,21 @@
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
2009-02-07 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net> 2009-02-07 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Fixed configure error with --disable-epoll Fixed configure error with --disable-epoll

View File

@ -36,14 +36,17 @@
#define _D_NAME_MATCH_OPTION_HANDLER_H_ #define _D_NAME_MATCH_OPTION_HANDLER_H_
#include "OptionHandler.h" #include "OptionHandler.h"
#include "A2STR.h"
#include "Util.h"
#include "OptionHandlerException.h"
#include <strings.h> #include <strings.h>
#include <algorithm> #include <algorithm>
#include <sstream> #include <sstream>
#include <iterator> #include <iterator>
#include "A2STR.h"
#include "Util.h"
#include "OptionHandlerException.h"
#define NO_DESCRIPTION A2STR::NIL #define NO_DESCRIPTION A2STR::NIL
#define NO_DEFAULT_VALUE A2STR::NIL #define NO_DEFAULT_VALUE A2STR::NIL
@ -59,20 +62,30 @@ protected:
std::string _defaultValue; std::string _defaultValue;
bool _hidden;
std::deque<std::string> _tags; 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: public:
NameMatchOptionHandler(const std::string& optName, NameMatchOptionHandler(const std::string& optName,
const std::string& description = NO_DESCRIPTION, const std::string& description = NO_DESCRIPTION,
const std::string& defaultValue = NO_DEFAULT_VALUE, const std::string& defaultValue = NO_DEFAULT_VALUE,
bool hidden = false): ARG_TYPE argType = REQ_ARG,
char shortName = 0):
_optName(optName), _optName(optName),
_description(description), _description(description),
_defaultValue(defaultValue), _defaultValue(defaultValue),
_hidden(hidden) {} _id(0),
_argType(argType),
_shortName(shortName),
_hidden(false) {}
virtual ~NameMatchOptionHandler() {} virtual ~NameMatchOptionHandler() {}
@ -81,7 +94,7 @@ public:
return strcasecmp(_optName.c_str(), optName.c_str()) == 0; 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 { try {
parseArg(option, arg); parseArg(option, arg);
@ -128,6 +141,30 @@ public:
return _hidden; 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; typedef SharedHandle<NameMatchOptionHandler> NameMatchOptionHandlerHandle;

View File

@ -36,11 +36,13 @@
#define _D_OPTION_HANDLER_H_ #define _D_OPTION_HANDLER_H_
#include "common.h" #include "common.h"
#include "SharedHandle.h"
#include <string> #include <string>
#include <deque> #include <deque>
#include <iosfwd> #include <iosfwd>
#include "SharedHandle.h"
namespace aria2 { namespace aria2 {
class Option; class Option;
@ -50,7 +52,7 @@ public:
virtual ~OptionHandler() {} virtual ~OptionHandler() {}
virtual bool canHandle(const std::string& optName) = 0; 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; virtual std::string createPossibleValuesString() const = 0;
@ -67,6 +69,20 @@ public:
virtual const std::string& getDefaultValue() const = 0; virtual const std::string& getDefaultValue() const = 0;
virtual bool isHidden() 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; typedef SharedHandle<OptionHandler> OptionHandlerHandle;

View File

@ -64,19 +64,23 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
op->addTag(TAG_ADVANCED); op->addTag(TAG_ADVANCED);
handlers.push_back(op); handlers.push_back(op);
} }
#ifdef ENABLE_ASYNC_DNS
{ {
SharedHandle<OptionHandler> op(new BooleanOptionHandler SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_ASYNC_DNS, (PREF_ASYNC_DNS,
TEXT_ASYNC_DNS, TEXT_ASYNC_DNS,
V_TRUE)); V_TRUE,
OptionHandler::OPT_ARG));
op->addTag(TAG_ADVANCED); op->addTag(TAG_ADVANCED);
handlers.push_back(op); handlers.push_back(op);
} }
#endif // ENABLE_ASYNC_DNS
{ {
SharedHandle<OptionHandler> op(new BooleanOptionHandler SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_AUTO_FILE_RENAMING, (PREF_AUTO_FILE_RENAMING,
TEXT_AUTO_FILE_RENAMING, TEXT_AUTO_FILE_RENAMING,
V_TRUE)); V_TRUE,
OptionHandler::OPT_ARG));
op->addTag(TAG_ADVANCED); op->addTag(TAG_ADVANCED);
handlers.push_back(op); handlers.push_back(op);
} }
@ -89,16 +93,20 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
op->addTag(TAG_ADVANCED); op->addTag(TAG_ADVANCED);
handlers.push_back(op); handlers.push_back(op);
} }
#ifdef ENABLE_MESSAGE_DIGEST
{ {
SharedHandle<OptionHandler> op(new BooleanOptionHandler SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_CHECK_INTEGRITY, (PREF_CHECK_INTEGRITY,
TEXT_CHECK_INTEGRITY, TEXT_CHECK_INTEGRITY,
V_FALSE)); V_FALSE,
OptionHandler::OPT_ARG,
'V'));
op->addTag(TAG_BASIC); op->addTag(TAG_BASIC);
op->addTag(TAG_BITTORRENT); op->addTag(TAG_BITTORRENT);
op->addTag(TAG_METALINK); op->addTag(TAG_METALINK);
handlers.push_back(op); handlers.push_back(op);
} }
#endif // ENABLE_MESSAGE_DIGEST
{ {
SharedHandle<OptionHandler> op(new DefaultOptionHandler SharedHandle<OptionHandler> op(new DefaultOptionHandler
(PREF_CONF_PATH, (PREF_CONF_PATH,
@ -111,7 +119,9 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
SharedHandle<OptionHandler> op(new BooleanOptionHandler SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_CONTINUE, (PREF_CONTINUE,
TEXT_CONTINUE, TEXT_CONTINUE,
V_FALSE)); // TODO ommit? V_FALSE, // TODO ommit?
OptionHandler::NO_ARG,
'c'));
op->addTag(TAG_BASIC); op->addTag(TAG_BASIC);
op->addTag(TAG_FTP); op->addTag(TAG_FTP);
op->addTag(TAG_HTTP); op->addTag(TAG_HTTP);
@ -121,7 +131,9 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
SharedHandle<OptionHandler> op(new BooleanOptionHandler SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_DAEMON, (PREF_DAEMON,
TEXT_DAEMON, TEXT_DAEMON,
V_FALSE)); // TODO ommit? V_FALSE,
OptionHandler::NO_ARG,
'D')); // TODO ommit?
op->addTag(TAG_ADVANCED); op->addTag(TAG_ADVANCED);
handlers.push_back(op); handlers.push_back(op);
} }
@ -129,32 +141,39 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
SharedHandle<OptionHandler> op(new DefaultOptionHandler SharedHandle<OptionHandler> op(new DefaultOptionHandler
(PREF_DIR, (PREF_DIR,
TEXT_DIR, TEXT_DIR,
".")); ".",
A2STR::NIL,
OptionHandler::REQ_ARG,
'd'));
op->addTag(TAG_BASIC); op->addTag(TAG_BASIC);
handlers.push_back(op); handlers.push_back(op);
} }
{ {
SharedHandle<OptionHandler> op(new NumberOptionHandler SharedHandle<NumberOptionHandler> op(new NumberOptionHandler
(PREF_DNS_TIMEOUT, (PREF_DNS_TIMEOUT,
NO_DESCRIPTION, NO_DESCRIPTION,
"30", "30",
1, 60, 1, 60));
true)); op->hide();
handlers.push_back(op); handlers.push_back(op);
} }
#ifdef ENABLE_DIRECT_IO
{ {
SharedHandle<OptionHandler> op(new BooleanOptionHandler SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_ENABLE_DIRECT_IO, (PREF_ENABLE_DIRECT_IO,
TEXT_ENABLE_DIRECT_IO, TEXT_ENABLE_DIRECT_IO,
V_TRUE)); V_TRUE,
OptionHandler::OPT_ARG));
op->addTag(TAG_ADVANCED); op->addTag(TAG_ADVANCED);
handlers.push_back(op); handlers.push_back(op);
} }
#endif // ENABLE_DIRECT_IO
{ {
SharedHandle<OptionHandler> op(new BooleanOptionHandler SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_ENABLE_HTTP_SERVER, (PREF_ENABLE_HTTP_SERVER,
TEXT_ENABLE_HTTP_SERVER, TEXT_ENABLE_HTTP_SERVER,
V_FALSE)); V_FALSE,
OptionHandler::OPT_ARG));
op->addTag(TAG_EXPERIMENTAL); op->addTag(TAG_EXPERIMENTAL);
handlers.push_back(op); handlers.push_back(op);
} }
@ -183,7 +202,8 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
(PREF_FILE_ALLOCATION, (PREF_FILE_ALLOCATION,
TEXT_FILE_ALLOCATION, TEXT_FILE_ALLOCATION,
V_PREALLOC, V_PREALLOC,
V_NONE, V_PREALLOC)); V_NONE, V_PREALLOC,
'a'));
op->addTag(TAG_BASIC); op->addTag(TAG_BASIC);
handlers.push_back(op); handlers.push_back(op);
} }
@ -191,7 +211,9 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
SharedHandle<OptionHandler> op(new BooleanOptionHandler SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_FORCE_SEQUENTIAL, (PREF_FORCE_SEQUENTIAL,
TEXT_FORCE_SEQUENTIAL, TEXT_FORCE_SEQUENTIAL,
V_FALSE)); V_FALSE,
OptionHandler::OPT_ARG,
'Z'));
op->addTag(TAG_BASIC); op->addTag(TAG_BASIC);
handlers.push_back(op); handlers.push_back(op);
} }
@ -209,7 +231,9 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
(PREF_INPUT_FILE, (PREF_INPUT_FILE,
TEXT_INPUT_FILE, TEXT_INPUT_FILE,
NO_DEFAULT_VALUE, NO_DEFAULT_VALUE,
"FILENAME,-")); "FILENAME,-",
OptionHandler::REQ_ARG,
'i'));
op->addTag(TAG_BASIC); op->addTag(TAG_BASIC);
handlers.push_back(op); handlers.push_back(op);
} }
@ -218,7 +242,9 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
(PREF_LOG, (PREF_LOG,
TEXT_LOG, TEXT_LOG,
NO_DEFAULT_VALUE, NO_DEFAULT_VALUE,
"FILENAME,-")); "FILENAME,-",
OptionHandler::REQ_ARG,
'l'));
op->addTag(TAG_BASIC); op->addTag(TAG_BASIC);
handlers.push_back(op); handlers.push_back(op);
} }
@ -239,7 +265,8 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
(PREF_MAX_CONCURRENT_DOWNLOADS, (PREF_MAX_CONCURRENT_DOWNLOADS,
TEXT_MAX_CONCURRENT_DOWNLOADS, TEXT_MAX_CONCURRENT_DOWNLOADS,
"5", "5",
1, 45)); 1, 45,
'j'));
op->addTag(TAG_BASIC); op->addTag(TAG_BASIC);
handlers.push_back(op); handlers.push_back(op);
} }
@ -258,7 +285,8 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
SharedHandle<OptionHandler> op(new BooleanOptionHandler SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_NO_CONF, (PREF_NO_CONF,
TEXT_NO_CONF, TEXT_NO_CONF,
V_FALSE)); V_FALSE,
OptionHandler::NO_ARG));
op->addTag(TAG_ADVANCED); op->addTag(TAG_ADVANCED);
handlers.push_back(op); handlers.push_back(op);
} }
@ -275,7 +303,9 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
SharedHandle<OptionHandler> op(new BooleanOptionHandler SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_PARAMETERIZED_URI, (PREF_PARAMETERIZED_URI,
TEXT_PARAMETERIZED_URI, TEXT_PARAMETERIZED_URI,
V_FALSE)); V_FALSE,
OptionHandler::OPT_ARG,
'P'));
op->addTag(TAG_ADVANCED); op->addTag(TAG_ADVANCED);
handlers.push_back(op); handlers.push_back(op);
} }
@ -283,10 +313,13 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
SharedHandle<OptionHandler> op(new BooleanOptionHandler SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_QUIET, (PREF_QUIET,
TEXT_QUIET, TEXT_QUIET,
V_FALSE)); V_FALSE,
OptionHandler::OPT_ARG,
'q'));
op->addTag(TAG_ADVANCED); op->addTag(TAG_ADVANCED);
handlers.push_back(op); handlers.push_back(op);
} }
#ifdef ENABLE_MESSAGE_DIGEST
{ {
SharedHandle<OptionHandler> op(new BooleanOptionHandler SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_REALTIME_CHUNK_CHECKSUM, (PREF_REALTIME_CHUNK_CHECKSUM,
@ -295,6 +328,7 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
op->addTag(TAG_METALINK); op->addTag(TAG_METALINK);
handlers.push_back(op); handlers.push_back(op);
} }
#endif // ENABLE_MESSAGE_DIGEST
{ {
SharedHandle<OptionHandler> op(new NumberOptionHandler SharedHandle<OptionHandler> op(new NumberOptionHandler
(PREF_STOP, (PREF_STOP,
@ -349,7 +383,8 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
(PREF_MAX_TRIES, (PREF_MAX_TRIES,
TEXT_MAX_TRIES, TEXT_MAX_TRIES,
"5", "5",
0)); 0, -1,
'm'));
op->addTag(TAG_FTP); op->addTag(TAG_FTP);
op->addTag(TAG_HTTP); op->addTag(TAG_HTTP);
handlers.push_back(op); handlers.push_back(op);
@ -359,7 +394,9 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
(PREF_OUT, (PREF_OUT,
TEXT_OUT, TEXT_OUT,
NO_DEFAULT_VALUE, NO_DEFAULT_VALUE,
"FILENAME")); "FILENAME",
OptionHandler::REQ_ARG,
'o'));
op->addTag(TAG_BASIC); op->addTag(TAG_BASIC);
op->addTag(TAG_FTP); op->addTag(TAG_FTP);
op->addTag(TAG_HTTP); op->addTag(TAG_HTTP);
@ -369,7 +406,9 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
SharedHandle<OptionHandler> op(new BooleanOptionHandler SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_REMOTE_TIME, (PREF_REMOTE_TIME,
TEXT_REMOTE_TIME, TEXT_REMOTE_TIME,
V_FALSE)); V_FALSE,
OptionHandler::OPT_ARG,
'R'));
op->addTag(TAG_FTP); op->addTag(TAG_FTP);
op->addTag(TAG_HTTP); op->addTag(TAG_HTTP);
handlers.push_back(op); handlers.push_back(op);
@ -385,12 +424,12 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
handlers.push_back(op); handlers.push_back(op);
} }
{ {
SharedHandle<OptionHandler> op(new UnitNumberOptionHandler SharedHandle<UnitNumberOptionHandler> op(new UnitNumberOptionHandler
(PREF_SEGMENT_SIZE, (PREF_SEGMENT_SIZE,
NO_DESCRIPTION, NO_DESCRIPTION,
"1M", "1M",
1024, -1, 1024, -1));
true)); op->hide();
handlers.push_back(op); handlers.push_back(op);
} }
{ {
@ -428,19 +467,20 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
(PREF_SPLIT, (PREF_SPLIT,
TEXT_SPLIT, TEXT_SPLIT,
"5", "5",
1)); 1, -1,
's'));
op->addTag(TAG_BASIC); op->addTag(TAG_BASIC);
op->addTag(TAG_FTP); op->addTag(TAG_FTP);
op->addTag(TAG_HTTP); op->addTag(TAG_HTTP);
handlers.push_back(op); handlers.push_back(op);
} }
{ {
SharedHandle<OptionHandler> op(new NumberOptionHandler SharedHandle<NumberOptionHandler> op(new NumberOptionHandler
(PREF_STARTUP_IDLE_TIME, (PREF_STARTUP_IDLE_TIME,
NO_DESCRIPTION, NO_DESCRIPTION,
"10", "10",
1, 60, 1, 60));
true)); op->hide();
handlers.push_back(op); handlers.push_back(op);
} }
{ {
@ -448,7 +488,8 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
(PREF_TIMEOUT, (PREF_TIMEOUT,
TEXT_TIMEOUT, TEXT_TIMEOUT,
"60", "60",
1, 600)); 1, 600,
't'));
op->addTag(TAG_FTP); op->addTag(TAG_FTP);
op->addTag(TAG_HTTP); op->addTag(TAG_HTTP);
handlers.push_back(op); handlers.push_back(op);
@ -487,7 +528,8 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
SharedHandle<OptionHandler> op(new BooleanOptionHandler SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_CHECK_CERTIFICATE, (PREF_CHECK_CERTIFICATE,
TEXT_CHECK_CERTIFICATE, TEXT_CHECK_CERTIFICATE,
V_TRUE)); V_TRUE,
OptionHandler::OPT_ARG));
op->addTag(TAG_HTTP); op->addTag(TAG_HTTP);
op->addTag(TAG_HTTPS); op->addTag(TAG_HTTPS);
handlers.push_back(op); handlers.push_back(op);
@ -496,7 +538,8 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
SharedHandle<OptionHandler> op(new BooleanOptionHandler SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_ENABLE_HTTP_KEEP_ALIVE, (PREF_ENABLE_HTTP_KEEP_ALIVE,
TEXT_ENABLE_HTTP_KEEP_ALIVE, TEXT_ENABLE_HTTP_KEEP_ALIVE,
V_TRUE)); V_TRUE,
OptionHandler::OPT_ARG));
op->addTag(TAG_HTTP); op->addTag(TAG_HTTP);
handlers.push_back(op); handlers.push_back(op);
} }
@ -504,7 +547,8 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
SharedHandle<OptionHandler> op(new BooleanOptionHandler SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_ENABLE_HTTP_PIPELINING, (PREF_ENABLE_HTTP_PIPELINING,
TEXT_ENABLE_HTTP_PIPELINING, TEXT_ENABLE_HTTP_PIPELINING,
V_FALSE)); V_FALSE,
OptionHandler::OPT_ARG));
op->addTag(TAG_HTTP); op->addTag(TAG_HTTP);
handlers.push_back(op); handlers.push_back(op);
} }
@ -553,12 +597,12 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
handlers.push_back(op); handlers.push_back(op);
} }
{ {
SharedHandle<OptionHandler> op(new NumberOptionHandler SharedHandle<NumberOptionHandler> op(new NumberOptionHandler
(PREF_MAX_HTTP_PIPELINING, (PREF_MAX_HTTP_PIPELINING,
NO_DESCRIPTION, NO_DESCRIPTION,
"2", "2",
1, 8, 1, 8));
true)); op->hide();
handlers.push_back(op); handlers.push_back(op);
} }
{ {
@ -577,10 +621,11 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
handlers.push_back(op); handlers.push_back(op);
} }
{ {
SharedHandle<OptionHandler> op(new DefaultOptionHandler SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_USE_HEAD, (PREF_USE_HEAD,
TEXT_USE_HEAD, TEXT_USE_HEAD,
V_TRUE)); V_TRUE,
OptionHandler::OPT_ARG));
op->addTag(TAG_HTTP); op->addTag(TAG_HTTP);
handlers.push_back(op); handlers.push_back(op);
} }
@ -588,7 +633,10 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
SharedHandle<OptionHandler> op(new DefaultOptionHandler SharedHandle<OptionHandler> op(new DefaultOptionHandler
(PREF_USER_AGENT, (PREF_USER_AGENT,
TEXT_USER_AGENT, TEXT_USER_AGENT,
"aria2")); "aria2",
A2STR::NIL,
OptionHandler::REQ_ARG,
'U'));
op->addTag(TAG_HTTP); op->addTag(TAG_HTTP);
handlers.push_back(op); handlers.push_back(op);
} }
@ -605,7 +653,9 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
SharedHandle<OptionHandler> op(new BooleanOptionHandler SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_FTP_PASV, (PREF_FTP_PASV,
TEXT_FTP_PASV, TEXT_FTP_PASV,
V_TRUE)); V_TRUE,
OptionHandler::OPT_ARG,
'p'));
op->addTag(TAG_FTP); op->addTag(TAG_FTP);
handlers.push_back(op); handlers.push_back(op);
} }
@ -613,7 +663,8 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
SharedHandle<OptionHandler> op(new BooleanOptionHandler SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_FTP_REUSE_CONNECTION, (PREF_FTP_REUSE_CONNECTION,
TEXT_FTP_REUSE_CONNECTION, TEXT_FTP_REUSE_CONNECTION,
V_TRUE)); V_TRUE,
OptionHandler::OPT_ARG));
op->addTag(TAG_FTP); op->addTag(TAG_FTP);
handlers.push_back(op); handlers.push_back(op);
} }
@ -635,19 +686,21 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
handlers.push_back(op); handlers.push_back(op);
} }
{ {
SharedHandle<OptionHandler> op(new DefaultOptionHandler SharedHandle<DefaultOptionHandler> op(new DefaultOptionHandler
(PREF_NETRC_PATH, (PREF_NETRC_PATH,
NO_DESCRIPTION, NO_DESCRIPTION,
Util::getHomeDir()+"/.netrc", Util::getHomeDir()+"/.netrc",
"/PATH/TO/NETRC", "/PATH/TO/NETRC"));
true)); op->hide();
handlers.push_back(op); handlers.push_back(op);
} }
{ {
SharedHandle<OptionHandler> op(new BooleanOptionHandler SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_NO_NETRC, (PREF_NO_NETRC,
TEXT_NO_NETRC, TEXT_NO_NETRC,
V_FALSE)); // TODO ommit? V_FALSE, // TODO ommit?
OptionHandler::NO_ARG,
'n'));
op->addTag(TAG_FTP); op->addTag(TAG_FTP);
op->addTag(TAG_HTTP); op->addTag(TAG_HTTP);
handlers.push_back(op); handlers.push_back(op);
@ -705,6 +758,7 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
handlers.push_back(op); handlers.push_back(op);
} }
// BitTorrent/Metalink Options // BitTorrent/Metalink Options
#if defined ENABLE_BITTORRENT || defined ENABLE_METALINK
{ {
SharedHandle<OptionHandler> op(new IntegerRangeOptionHandler SharedHandle<OptionHandler> op(new IntegerRangeOptionHandler
(PREF_SELECT_FILE, (PREF_SELECT_FILE,
@ -719,13 +773,17 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
SharedHandle<OptionHandler> op(new BooleanOptionHandler SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_SHOW_FILES, (PREF_SHOW_FILES,
TEXT_SHOW_FILES, TEXT_SHOW_FILES,
V_FALSE)); // TODO ommit? V_FALSE, // TODO ommit?
OptionHandler::NO_ARG,
'S'));
op->addTag(TAG_BASIC); op->addTag(TAG_BASIC);
op->addTag(TAG_BITTORRENT); op->addTag(TAG_BITTORRENT);
op->addTag(TAG_METALINK); op->addTag(TAG_METALINK);
handlers.push_back(op); handlers.push_back(op);
} }
#endif // ENABLE_BITTORRENT || ENABLE_METALINK
// BitTorrent Specific Options // BitTorrent Specific Options
#ifdef ENABLE_BITTORRENT
{ {
SharedHandle<OptionHandler> op(new DefaultOptionHandler SharedHandle<OptionHandler> op(new DefaultOptionHandler
(PREF_BT_EXTERNAL_IP, (PREF_BT_EXTERNAL_IP,
@ -736,19 +794,20 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
handlers.push_back(op); handlers.push_back(op);
} }
{ {
SharedHandle<OptionHandler> op(new NumberOptionHandler SharedHandle<NumberOptionHandler> op(new NumberOptionHandler
(PREF_BT_KEEP_ALIVE_INTERVAL, (PREF_BT_KEEP_ALIVE_INTERVAL,
NO_DESCRIPTION, NO_DESCRIPTION,
"120", "120",
1, 120, 1, 120));
true)); op->hide();
handlers.push_back(op); handlers.push_back(op);
} }
{ {
SharedHandle<OptionHandler> op(new BooleanOptionHandler SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_BT_HASH_CHECK_SEED, (PREF_BT_HASH_CHECK_SEED,
TEXT_BT_HASH_CHECK_SEED, TEXT_BT_HASH_CHECK_SEED,
V_TRUE)); V_TRUE,
OptionHandler::OPT_ARG));
op->addTag(TAG_BITTORRENT); op->addTag(TAG_BITTORRENT);
handlers.push_back(op); handlers.push_back(op);
} }
@ -798,29 +857,30 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
handlers.push_back(op); handlers.push_back(op);
} }
{ {
SharedHandle<OptionHandler> op(new NumberOptionHandler SharedHandle<NumberOptionHandler> op(new NumberOptionHandler
(PREF_BT_REQUEST_TIMEOUT, (PREF_BT_REQUEST_TIMEOUT,
NO_DESCRIPTION, NO_DESCRIPTION,
"60", "60",
1, 600, 1, 600));
true)); op->hide();
handlers.push_back(op); handlers.push_back(op);
} }
{ {
SharedHandle<OptionHandler> op(new BooleanOptionHandler SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_BT_SEED_UNVERIFIED, (PREF_BT_SEED_UNVERIFIED,
TEXT_BT_SEED_UNVERIFIED, TEXT_BT_SEED_UNVERIFIED,
V_FALSE)); V_FALSE,
OptionHandler::OPT_ARG));
op->addTag(TAG_BITTORRENT); op->addTag(TAG_BITTORRENT);
handlers.push_back(op); handlers.push_back(op);
} }
{ {
SharedHandle<OptionHandler> op(new NumberOptionHandler SharedHandle<NumberOptionHandler> op(new NumberOptionHandler
(PREF_BT_TIMEOUT, (PREF_BT_TIMEOUT,
NO_DESCRIPTION, NO_DESCRIPTION,
"180", "180",
1, 600, 1, 600));
true)); op->hide();
handlers.push_back(op); handlers.push_back(op);
} }
{ {
@ -864,7 +924,8 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
SharedHandle<OptionHandler> op(new BooleanOptionHandler SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_ENABLE_DHT, (PREF_ENABLE_DHT,
TEXT_ENABLE_DHT, TEXT_ENABLE_DHT,
V_FALSE)); V_FALSE,
OptionHandler::OPT_ARG));
op->addTag(TAG_BASIC); op->addTag(TAG_BASIC);
op->addTag(TAG_BITTORRENT); op->addTag(TAG_BITTORRENT);
handlers.push_back(op); handlers.push_back(op);
@ -873,7 +934,8 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
SharedHandle<OptionHandler> op(new BooleanOptionHandler SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_ENABLE_PEER_EXCHANGE, (PREF_ENABLE_PEER_EXCHANGE,
TEXT_ENABLE_PEER_EXCHANGE, TEXT_ENABLE_PEER_EXCHANGE,
V_TRUE)); V_TRUE,
OptionHandler::OPT_ARG));
op->addTag(TAG_BITTORRENT); op->addTag(TAG_BITTORRENT);
handlers.push_back(op); handlers.push_back(op);
} }
@ -911,18 +973,19 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
(PREF_MAX_UPLOAD_LIMIT, (PREF_MAX_UPLOAD_LIMIT,
TEXT_MAX_UPLOAD_LIMIT, TEXT_MAX_UPLOAD_LIMIT,
"0", "0",
0)); 0, -1,
'u'));
op->addTag(TAG_BASIC); op->addTag(TAG_BASIC);
op->addTag(TAG_BITTORRENT); op->addTag(TAG_BITTORRENT);
handlers.push_back(op); handlers.push_back(op);
} }
{ {
SharedHandle<OptionHandler> op(new NumberOptionHandler SharedHandle<NumberOptionHandler> op(new NumberOptionHandler
(PREF_PEER_CONNECTION_TIMEOUT, (PREF_PEER_CONNECTION_TIMEOUT,
NO_DESCRIPTION, NO_DESCRIPTION,
"20", "20",
1, 600, 1, 600));
true)); op->hide();
handlers.push_back(op); handlers.push_back(op);
} }
{ {
@ -954,12 +1017,18 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
{ {
SharedHandle<OptionHandler> op(new DefaultOptionHandler SharedHandle<OptionHandler> op(new DefaultOptionHandler
(PREF_TORRENT_FILE, (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_BASIC);
op->addTag(TAG_BITTORRENT); op->addTag(TAG_BITTORRENT);
handlers.push_back(op); handlers.push_back(op);
} }
#endif // ENABLE_BITTORRENT
// Metalink Specific Options // Metalink Specific Options
#ifdef ENABLE_METALINK
{ {
SharedHandle<OptionHandler> op(new ParameterOptionHandler SharedHandle<OptionHandler> op(new ParameterOptionHandler
(PREF_FOLLOW_METALINK, (PREF_FOLLOW_METALINK,
@ -973,14 +1042,19 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
SharedHandle<OptionHandler> op(new BooleanOptionHandler SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_METALINK_ENABLE_UNIQUE_PROTOCOL, (PREF_METALINK_ENABLE_UNIQUE_PROTOCOL,
TEXT_METALINK_ENABLE_UNIQUE_PROTOCOL, TEXT_METALINK_ENABLE_UNIQUE_PROTOCOL,
V_TRUE)); V_TRUE,
OptionHandler::OPT_ARG));
op->addTag(TAG_METALINK); op->addTag(TAG_METALINK);
handlers.push_back(op); handlers.push_back(op);
} }
{ {
SharedHandle<OptionHandler> op(new DefaultOptionHandler SharedHandle<OptionHandler> op(new DefaultOptionHandler
(PREF_METALINK_FILE, (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_BASIC);
op->addTag(TAG_METALINK); op->addTag(TAG_METALINK);
handlers.push_back(op); handlers.push_back(op);
@ -1022,7 +1096,8 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
(PREF_METALINK_SERVERS, (PREF_METALINK_SERVERS,
TEXT_METALINK_SERVERS, TEXT_METALINK_SERVERS,
"5", "5",
1)); 1, -1,
'C'));
op->addTag(TAG_METALINK); op->addTag(TAG_METALINK);
handlers.push_back(op); handlers.push_back(op);
} }
@ -1033,6 +1108,19 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
op->addTag(TAG_METALINK); op->addTag(TAG_METALINK);
handlers.push_back(op); 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 // Help Option
{ {
SharedHandle<OptionHandler> op(new DefaultOptionHandler SharedHandle<OptionHandler> op(new DefaultOptionHandler
@ -1048,7 +1136,9 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
TAG_METALINK, TAG_METALINK,
TAG_BITTORRENT, TAG_BITTORRENT,
TAG_EXPERIMENTAL, TAG_EXPERIMENTAL,
TAG_HELP).str())); TAG_HELP).str(),
OptionHandler::OPT_ARG,
'h'));
op->addTag(TAG_BASIC); op->addTag(TAG_BASIC);
op->addTag(TAG_HELP); op->addTag(TAG_HELP);
handlers.push_back(op); handlers.push_back(op);

View File

@ -56,12 +56,14 @@
namespace aria2 { namespace aria2 {
class NullOptionHandler : public OptionHandler { class NullOptionHandler : public OptionHandler {
private:
int _id;
public: public:
virtual ~NullOptionHandler() {} virtual ~NullOptionHandler() {}
virtual bool canHandle(const std::string& optName) { return true; } 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; } virtual bool hasTag(const std::string& tag) const { return false; }
@ -78,23 +80,47 @@ public:
virtual std::string createPossibleValuesString() const { return A2STR::NIL; } virtual std::string createPossibleValuesString() const { return A2STR::NIL; }
virtual bool isHidden() const { return true; } 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 { class BooleanOptionHandler : public NameMatchOptionHandler {
public: public:
BooleanOptionHandler(const std::string& optName, BooleanOptionHandler(const std::string& optName,
const std::string& description = NO_DESCRIPTION, const std::string& description = NO_DESCRIPTION,
const std::string& defaultValue = NO_DEFAULT_VALUE): const std::string& defaultValue = NO_DEFAULT_VALUE,
NameMatchOptionHandler(optName, description, defaultValue) {} OptionHandler::ARG_TYPE argType = OptionHandler::REQ_ARG,
char shortName = 0):
NameMatchOptionHandler(optName, description, defaultValue,
argType, shortName) {}
virtual ~BooleanOptionHandler() {} virtual ~BooleanOptionHandler() {}
virtual void parseArg(Option* option, const std::string& optarg) virtual void parseArg(Option& option, const std::string& optarg)
{ {
if(optarg == "true") { if(optarg == "true" ||
option->put(_optName, V_TRUE); (_argType == OptionHandler::OPT_ARG && optarg.empty())) {
option.put(_optName, V_TRUE);
} else if(optarg == "false") { } else if(optarg == "false") {
option->put(_optName, V_FALSE); option.put(_optName, V_FALSE);
} else { } else {
std::string msg = _optName+" "+_("must be either 'true' or 'false'."); std::string msg = _optName+" "+_("must be either 'true' or 'false'.");
throw FatalException(msg); throw FatalException(msg);
@ -115,13 +141,15 @@ public:
IntegerRangeOptionHandler(const std::string& optName, IntegerRangeOptionHandler(const std::string& optName,
const std::string& description, const std::string& description,
const std::string& defaultValue, const std::string& defaultValue,
int32_t min, int32_t max): int32_t min, int32_t max,
NameMatchOptionHandler(optName, description, defaultValue), char shortName = 0):
NameMatchOptionHandler(optName, description, defaultValue,
OptionHandler::REQ_ARG, shortName),
_min(min), _max(max) {} _min(min), _max(max) {}
virtual ~IntegerRangeOptionHandler() {} 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); IntSequence seq = Util::parseIntRange(optarg);
while(seq.hasNext()) { while(seq.hasNext()) {
@ -132,7 +160,7 @@ public:
(StringFormat(msg.c_str(), Util::itos(_min).c_str(), (StringFormat(msg.c_str(), Util::itos(_min).c_str(),
Util::itos(_max).c_str()).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, const std::string& defaultValue = NO_DEFAULT_VALUE,
int64_t min = -1, int64_t min = -1,
int64_t max = -1, int64_t max = -1,
bool hidden = false): char shortName = 0):
NameMatchOptionHandler(optName, description, defaultValue, hidden), NameMatchOptionHandler(optName, description, defaultValue,
OptionHandler::REQ_ARG, shortName),
_min(min), _max(max) {} _min(min), _max(max) {}
virtual ~NumberOptionHandler() {} 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); int64_t num = Util::parseLLInt(optarg);
parseArg(option, num); 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)) { if((_min == -1 || _min <= number) && (_max == -1 || number <= _max)) {
option->put(_optName, Util::itos(number)); option.put(_optName, Util::itos(number));
} else { } else {
std::string msg = _optName+" "; std::string msg = _optName+" ";
if(_min == -1 && _max != -1) { if(_min == -1 && _max != -1) {
@ -200,12 +229,13 @@ public:
const std::string& defaultValue = NO_DEFAULT_VALUE, const std::string& defaultValue = NO_DEFAULT_VALUE,
int64_t min = -1, int64_t min = -1,
int64_t max = -1, int64_t max = -1,
bool hidden = false): char shortName = 0):
NumberOptionHandler(optName, description, defaultValue, min, max, hidden) {} NumberOptionHandler(optName, description, defaultValue, min, max,
shortName) {}
virtual ~UnitNumberOptionHandler() {} 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); int64_t num = Util::getRealSize(optarg);
NumberOptionHandler::parseArg(option, num); NumberOptionHandler::parseArg(option, num);
@ -220,17 +250,19 @@ public:
FloatNumberOptionHandler(const std::string& optName, FloatNumberOptionHandler(const std::string& optName,
const std::string& description = NO_DESCRIPTION, const std::string& description = NO_DESCRIPTION,
const std::string& defaultValue = NO_DEFAULT_VALUE, const std::string& defaultValue = NO_DEFAULT_VALUE,
double min = -1, double max = -1): double min = -1, double max = -1,
NameMatchOptionHandler(optName, description, defaultValue), char shortName = 0):
NameMatchOptionHandler(optName, description, defaultValue,
OptionHandler::REQ_ARG, shortName),
_min(min), _max(max) {} _min(min), _max(max) {}
virtual ~FloatNumberOptionHandler() {} 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); double number = strtod(optarg.c_str(), 0);
if((_min < 0 || _min <= number) && (_max < 0 || number <= _max)) { if((_min < 0 || _min <= number) && (_max < 0 || number <= _max)) {
option->put(_optName, optarg); option.put(_optName, optarg);
} else { } else {
std::string msg = _optName+" "; std::string msg = _optName+" ";
if(_min < 0 && _max >= 0) { if(_min < 0 && _max >= 0) {
@ -279,15 +311,17 @@ public:
const std::string& description = NO_DESCRIPTION, const std::string& description = NO_DESCRIPTION,
const std::string& defaultValue = NO_DEFAULT_VALUE, const std::string& defaultValue = NO_DEFAULT_VALUE,
const std::string& possibleValuesString = A2STR::NIL, const std::string& possibleValuesString = A2STR::NIL,
bool hidden = false): OptionHandler::ARG_TYPE argType = OptionHandler::REQ_ARG,
NameMatchOptionHandler(optName, description, defaultValue, hidden), char shortName = 0):
NameMatchOptionHandler(optName, description, defaultValue, argType,
shortName),
_possibleValuesString(possibleValuesString) {} _possibleValuesString(possibleValuesString) {}
virtual ~DefaultOptionHandler() {} 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 virtual std::string createPossibleValuesString() const
@ -306,18 +340,22 @@ public:
const std::string& description, const std::string& description,
const std::string& defaultValue, const std::string& defaultValue,
const std::string& delim, const std::string& delim,
const std::string& possibleValuesString = A2STR::NIL): const std::string& possibleValuesString = A2STR::NIL,
NameMatchOptionHandler(optName, description, defaultValue), OptionHandler::ARG_TYPE argType =
OptionHandler::REQ_ARG,
char shortName = 0):
NameMatchOptionHandler(optName, description, defaultValue, argType,
shortName),
_delim(delim), _delim(delim),
_possibleValuesString(possibleValuesString) {} _possibleValuesString(possibleValuesString) {}
virtual ~CumulativeOptionHandler() {} 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; value += optarg+_delim;
option->put(_optName, value); option.put(_optName, value);
} }
virtual std::string createPossibleValuesString() const virtual std::string createPossibleValuesString() const
@ -333,15 +371,19 @@ public:
ParameterOptionHandler(const std::string& optName, ParameterOptionHandler(const std::string& optName,
const std::string& description, const std::string& description,
const std::string& defaultValue, const std::string& defaultValue,
const std::deque<std::string>& validParamValues): const std::deque<std::string>& validParamValues,
NameMatchOptionHandler(optName, description, defaultValue), char shortName = 0):
NameMatchOptionHandler(optName, description, defaultValue,
OptionHandler::REQ_ARG, shortName),
_validParamValues(validParamValues) {} _validParamValues(validParamValues) {}
ParameterOptionHandler(const std::string& optName, ParameterOptionHandler(const std::string& optName,
const std::string& description, const std::string& description,
const std::string& defaultValue, const std::string& defaultValue,
const std::string& validParamValue): const std::string& validParamValue,
NameMatchOptionHandler(optName, description, defaultValue) char shortName = 0):
NameMatchOptionHandler(optName, description, defaultValue,
OptionHandler::REQ_ARG, shortName)
{ {
_validParamValues.push_back(validParamValue); _validParamValues.push_back(validParamValue);
} }
@ -350,8 +392,10 @@ public:
const std::string& description, const std::string& description,
const std::string& defaultValue, const std::string& defaultValue,
const std::string& validParamValue1, const std::string& validParamValue1,
const std::string& validParamValue2): const std::string& validParamValue2,
NameMatchOptionHandler(optName, description, defaultValue) char shortName = 0):
NameMatchOptionHandler(optName, description, defaultValue,
OptionHandler::REQ_ARG, shortName)
{ {
_validParamValues.push_back(validParamValue1); _validParamValues.push_back(validParamValue1);
_validParamValues.push_back(validParamValue2); _validParamValues.push_back(validParamValue2);
@ -362,8 +406,10 @@ public:
const std::string& defaultValue, const std::string& defaultValue,
const std::string& validParamValue1, const std::string& validParamValue1,
const std::string& validParamValue2, const std::string& validParamValue2,
const std::string& validParamValue3): const std::string& validParamValue3,
NameMatchOptionHandler(optName, description, defaultValue) char shortName = 0):
NameMatchOptionHandler(optName, description, defaultValue,
OptionHandler::REQ_ARG, shortName)
{ {
_validParamValues.push_back(validParamValue1); _validParamValues.push_back(validParamValue1);
_validParamValues.push_back(validParamValue2); _validParamValues.push_back(validParamValue2);
@ -372,7 +418,7 @@ public:
virtual ~ParameterOptionHandler() {} 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::deque<std::string>::const_iterator itr =
std::find(_validParamValues.begin(), _validParamValues.end(), optarg); std::find(_validParamValues.begin(), _validParamValues.end(), optarg);
@ -388,7 +434,7 @@ public:
} }
throw FatalException(msg); throw FatalException(msg);
} else { } else {
option->put(_optName, optarg); option.put(_optName, optarg);
} }
} }
@ -411,14 +457,16 @@ public:
const std::string& description, const std::string& description,
const std::string& defaultValue, const std::string& defaultValue,
const std::string& hostOptionName, const std::string& hostOptionName,
const std::string& portOptionName): const std::string& portOptionName,
NameMatchOptionHandler(optName, description, defaultValue), char shortName = 0):
NameMatchOptionHandler(optName, description, defaultValue,
OptionHandler::REQ_ARG, shortName),
_hostOptionName(hostOptionName), _hostOptionName(hostOptionName),
_portOptionName(portOptionName) {} _portOptionName(portOptionName) {}
virtual ~HostPortOptionHandler() {} 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, ":"); std::pair<std::string, std::string> proxy = Util::split(optarg, ":");
int32_t port = Util::parseInt(proxy.second); int32_t port = Util::parseInt(proxy.second);
@ -426,14 +474,14 @@ public:
port <= 0 || 65535 < port) { port <= 0 || 65535 < port) {
throw FatalException(_("unrecognized proxy format")); throw FatalException(_("unrecognized proxy format"));
} }
option->put(_optName, optarg); option.put(_optName, optarg);
setHostAndPort(option, proxy.first, port); 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(_hostOptionName, hostname);
option->put(_portOptionName, Util::uitos(port)); option.put(_portOptionName, Util::uitos(port));
} }
virtual std::string createPossibleValuesString() const virtual std::string createPossibleValuesString() const
@ -446,14 +494,16 @@ class HttpProxyOptionHandler : public NameMatchOptionHandler {
public: public:
HttpProxyOptionHandler(const std::string& optName, HttpProxyOptionHandler(const std::string& optName,
const std::string& description, 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 ~HttpProxyOptionHandler() {}
virtual void parseArg(Option* option, const std::string& optarg) virtual void parseArg(Option& option, const std::string& optarg)
{ {
Request req; Request req;
std::string url; std::string url;
@ -463,7 +513,7 @@ public:
url = "http://"+optarg; url = "http://"+optarg;
} }
if(req.setUrl(url)) { if(req.setUrl(url)) {
option->put(_optName, url); option.put(_optName, url);
} else { } else {
throw FatalException(_("unrecognized proxy format")); throw FatalException(_("unrecognized proxy format"));
} }

View File

@ -33,17 +33,126 @@
*/ */
/* copyright --> */ /* copyright --> */
#include "OptionParser.h" #include "OptionParser.h"
#include <unistd.h>
#include <getopt.h>
#include <cstring>
#include <istream>
#include <utility>
#include "Util.h" #include "Util.h"
#include "OptionHandlerImpl.h" #include "OptionHandlerImpl.h"
#include "Option.h" #include "Option.h"
#include "A2STR.h" #include "A2STR.h"
#include "a2functional.h" #include "a2functional.h"
#include <istream> #include "array_fun.h"
#include <utility>
namespace aria2 { 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; std::string line;
int32_t linenum = 0; int32_t linenum = 0;
@ -72,15 +181,20 @@ OptionHandlerHandle OptionParser::getOptionHandlerByName(const std::string& optN
void OptionParser::setOptionHandlers(const std::deque<SharedHandle<OptionHandler> >& optionHandlers) void OptionParser::setOptionHandlers(const std::deque<SharedHandle<OptionHandler> >& optionHandlers)
{ {
_optionHandlers = optionHandlers; _optionHandlers = optionHandlers;
for(std::deque<SharedHandle<OptionHandler> >::iterator i =
_optionHandlers.begin(); i != _optionHandlers.end(); ++i) {
(*i)->setOptionID(++_idCounter);
}
} }
void OptionParser::addOptionHandler void OptionParser::addOptionHandler
(const SharedHandle<OptionHandler>& optionHandler) (const SharedHandle<OptionHandler>& optionHandler)
{ {
optionHandler->setOptionID(++_idCounter);
_optionHandlers.push_back(optionHandler); _optionHandlers.push_back(optionHandler);
} }
void OptionParser::parseDefaultValues(Option* option) const void OptionParser::parseDefaultValues(Option& option) const
{ {
for(std::deque<SharedHandle<OptionHandler> >::const_iterator i = for(std::deque<SharedHandle<OptionHandler> >::const_iterator i =
_optionHandlers.begin(); i != _optionHandlers.end(); ++i) { _optionHandlers.begin(); i != _optionHandlers.end(); ++i) {
@ -137,6 +251,27 @@ OptionParser::findByNameSubstring(const std::string& substring) const
return result; 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 : class FindByName :
public std::unary_function<SharedHandle<OptionHandler> , bool> { public std::unary_function<SharedHandle<OptionHandler> , bool> {
private: private:
@ -150,28 +285,52 @@ public:
} }
}; };
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> SharedHandle<OptionHandler>
OptionParser::findByName(const std::string& name) const OptionParser::findByName(const std::string& name) const
{ {
std::deque<SharedHandle<OptionHandler> >::const_iterator i = return findOptionHandler(_optionHandlers.begin(), _optionHandlers.end(),
std::find_if(_optionHandlers.begin(), _optionHandlers.end(), FindByName(name));
FindByName(name));
if(i == _optionHandlers.end()) {
return SharedHandle<OptionHandler>();
} else {
return *i;
}
} }
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
{
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> >& const std::deque<SharedHandle<OptionHandler> >&
OptionParser::getOptionHandlers() const OptionParser::getOptionHandlers() const
{ {

View File

@ -36,11 +36,13 @@
#define _D_OPTION_PARSER_H_ #define _D_OPTION_PARSER_H_
#include "common.h" #include "common.h"
#include "SharedHandle.h"
#include <string> #include <string>
#include <deque> #include <deque>
#include <iosfwd> #include <iosfwd>
#include "SharedHandle.h"
namespace aria2 { namespace aria2 {
class Option; class Option;
@ -48,16 +50,26 @@ class OptionHandler;
class OptionParser { class OptionParser {
private: private:
int _idCounter;
std::deque<SharedHandle<OptionHandler> > _optionHandlers; std::deque<SharedHandle<OptionHandler> > _optionHandlers;
SharedHandle<OptionHandler> SharedHandle<OptionHandler>
getOptionHandlerByName(const std::string& optName); getOptionHandlerByName(const std::string& optName);
public: public:
OptionParser();
~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 parseDefaultValues(Option* option) const; void parse(Option& option, std::istream& ios);
void parseDefaultValues(Option& option) const;
void setOptionHandlers void setOptionHandlers
(const std::deque<SharedHandle<OptionHandler> >& optionHandlers); (const std::deque<SharedHandle<OptionHandler> >& optionHandlers);
@ -75,6 +87,10 @@ public:
SharedHandle<OptionHandler> SharedHandle<OptionHandler>
findByName(const std::string& name) const; 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; const std::deque<SharedHandle<OptionHandler> >& getOptionHandlers() const;
}; };

View File

@ -215,6 +215,43 @@ size_t arrayLength(T (&a)[0u])
return 0; 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 } // namespace aria2
#endif // _D_ARRAY_FUN_H_ #endif // _D_ARRAY_FUN_H_

View File

@ -157,32 +157,34 @@ static void showFiles(const std::deque<std::string>& uris, const Option* op)
} }
#endif // ENABLE_BITTORRENT || ENABLE_METALINK #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[]) DownloadResult::RESULT main(int argc, char* argv[])
{ {
Option* op = option_processing(argc, argv); std::deque<std::string> args;
std::deque<std::string> args(argv+optind, argv+argc); Option op;
option_processing(op, args, argc, argv);
SimpleRandomizer::init(); SimpleRandomizer::init();
BitfieldManFactory::setDefaultRandomizer(SimpleRandomizer::getInstance()); BitfieldManFactory::setDefaultRandomizer(SimpleRandomizer::getInstance());
if(op->get(PREF_LOG) == "-") { if(op.get(PREF_LOG) == "-") {
LogFactory::setLogFile(DEV_STDOUT); LogFactory::setLogFile(DEV_STDOUT);
} else if(!op->get(PREF_LOG).empty()) { } else if(!op.get(PREF_LOG).empty()) {
LogFactory::setLogFile(op->get(PREF_LOG)); LogFactory::setLogFile(op.get(PREF_LOG));
} else { } else {
LogFactory::setLogFile(DEV_NULL); LogFactory::setLogFile(DEV_NULL);
} }
LogFactory::setLogLevel(op->get(PREF_LOG_LEVEL)); LogFactory::setLogLevel(op.get(PREF_LOG_LEVEL));
if(op->getAsBool(PREF_QUIET)) { if(op.getAsBool(PREF_QUIET)) {
LogFactory::setConsoleOutput(false); LogFactory::setConsoleOutput(false);
} }
#ifdef HAVE_EPOLL #ifdef HAVE_EPOLL
if(op->get(PREF_EVENT_POLL) == V_EPOLL) { if(op.get(PREF_EVENT_POLL) == V_EPOLL) {
SocketCore::useEpoll(); SocketCore::useEpoll();
} else } else
#endif // HAVE_EPOLL #endif // HAVE_EPOLL
if(op->get(PREF_EVENT_POLL) == V_SELECT) { if(op.get(PREF_EVENT_POLL) == V_SELECT) {
SocketCore::useSelect(); SocketCore::useSelect();
} }
DownloadResult::RESULT exitStatus = DownloadResult::FINISHED; DownloadResult::RESULT exitStatus = DownloadResult::FINISHED;
@ -203,48 +205,47 @@ DownloadResult::RESULT main(int argc, char* argv[])
#endif #endif
std::deque<SharedHandle<RequestGroup> > requestGroups; std::deque<SharedHandle<RequestGroup> > requestGroups;
#ifdef ENABLE_BITTORRENT #ifdef ENABLE_BITTORRENT
if(!op->blank(PREF_TORRENT_FILE)) { if(!op.blank(PREF_TORRENT_FILE)) {
if(op->get(PREF_SHOW_FILES) == V_TRUE) { if(op.get(PREF_SHOW_FILES) == V_TRUE) {
showTorrentFile(op->get(PREF_TORRENT_FILE)); showTorrentFile(op.get(PREF_TORRENT_FILE));
return exitStatus; return exitStatus;
} else { } else {
createRequestGroupForBitTorrent(requestGroups, op, args); createRequestGroupForBitTorrent(requestGroups, &op, args);
} }
} }
else else
#endif // ENABLE_BITTORRENT #endif // ENABLE_BITTORRENT
#ifdef ENABLE_METALINK #ifdef ENABLE_METALINK
if(!op->blank(PREF_METALINK_FILE)) { if(!op.blank(PREF_METALINK_FILE)) {
if(op->get(PREF_SHOW_FILES) == V_TRUE) { if(op.get(PREF_SHOW_FILES) == V_TRUE) {
showMetalinkFile(op->get(PREF_METALINK_FILE), op); showMetalinkFile(op.get(PREF_METALINK_FILE), &op);
return exitStatus; return exitStatus;
} else { } else {
createRequestGroupForMetalink(requestGroups, op); createRequestGroupForMetalink(requestGroups, &op);
} }
} }
else else
#endif // ENABLE_METALINK #endif // ENABLE_METALINK
if(!op->blank(PREF_INPUT_FILE)) { if(!op.blank(PREF_INPUT_FILE)) {
createRequestGroupForUriList(requestGroups, op); createRequestGroupForUriList(requestGroups, &op);
#if defined ENABLE_BITTORRENT || defined ENABLE_METALINK #if defined ENABLE_BITTORRENT || defined ENABLE_METALINK
} else if(op->get(PREF_SHOW_FILES) == V_TRUE) { } else if(op.get(PREF_SHOW_FILES) == V_TRUE) {
showFiles(args, op); showFiles(args, &op);
#endif // ENABLE_METALINK || ENABLE_METALINK #endif // ENABLE_METALINK || ENABLE_METALINK
} else { } else {
createRequestGroupForUri(requestGroups, op, args); createRequestGroupForUri(requestGroups, &op, args);
} }
if(requestGroups.empty()) { if(requestGroups.empty()) {
std::cout << MSG_NO_FILES_TO_DOWNLOAD << std::endl; std::cout << MSG_NO_FILES_TO_DOWNLOAD << std::endl;
} else { } else {
exitStatus = MultiUrlRequestInfo(requestGroups, op, getStatCalc(op), exitStatus = MultiUrlRequestInfo(requestGroups, &op, getStatCalc(&op),
getSummaryOut(op)).execute(); getSummaryOut(&op)).execute();
} }
} catch(Exception& ex) { } catch(Exception& ex) {
std::cerr << EX_EXCEPTION_CAUGHT << "\n" << ex.stackTrace() << std::endl; std::cerr << EX_EXCEPTION_CAUGHT << "\n" << ex.stackTrace() << std::endl;
exitStatus = DownloadResult::UNKNOWN_ERROR; exitStatus = DownloadResult::UNKNOWN_ERROR;
} }
delete op;
LogFactory::release(); LogFactory::release();
return exitStatus; return exitStatus;
} }

View File

@ -55,27 +55,12 @@
#include "OptionHandlerException.h" #include "OptionHandlerException.h"
#include "DownloadResult.h" #include "DownloadResult.h"
extern char* optarg;
extern int optind, opterr, optopt;
#include <getopt.h>
namespace aria2 { namespace aria2 {
extern void showVersion(); extern void showVersion();
extern void showUsage(const std::string& keyword, const OptionParser& oparser); extern void showUsage(const std::string& keyword, const OptionParser& oparser);
static std::string toBoolArg(const char* optarg) static void overrideWithEnv(Option& op, const OptionParser& optionParser,
{
std::string arg;
if(!optarg || strlen(optarg) == 0) {
arg = V_TRUE;
} else {
arg = optarg;
}
return arg;
}
static void overrideWithEnv(Option* op, const OptionParser& optionParser,
const std::string& pref, const std::string& pref,
const std::string& envName) 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; OptionParser oparser;
oparser.setOptionHandlers(OptionHandlerFactory::createOptionHandlers()); oparser.setOptionHandlers(OptionHandlerFactory::createOptionHandlers());
try { try {
oparser.parseDefaultValues(op); bool noConf = false;
} catch(Exception& e) { std::string ucfname;
std::cerr << e.stackTrace(); std::stringstream cmdstream;
exit(DownloadResult::UNKNOWN_ERROR); 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) { if(op.defined("version")) {
int optIndex = 0; showVersion();
int lopt; exit(DownloadResult::FINISHED);
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;
} }
break; if(op.defined("help")) {
}
#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':
{
std::string keyword; std::string keyword;
if(optarg == 0 || strlen(optarg) == 0) { if(op.get("help").empty()) {
keyword = TAG_BASIC; keyword = TAG_BASIC;
} else { } else {
keyword = optarg; keyword = op.get("help");
if(Util::startsWith(keyword, "--")) { if(Util::startsWith(keyword, "--")) {
keyword = keyword.substr(2); keyword = keyword.substr(2);
} }
@ -598,13 +115,10 @@ Option* option_processing(int argc, char* const argv[])
showUsage(keyword, oparser); showUsage(keyword, oparser);
exit(DownloadResult::FINISHED); exit(DownloadResult::FINISHED);
} }
default:
showUsage(TAG_HELP, oparser);
exit(DownloadResult::UNKNOWN_ERROR);
} }
}
{ oparser.parseDefaultValues(op);
if(!noConf) { if(!noConf) {
std::string cfname = std::string cfname =
ucfname.empty() ? 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_ALL_PROXY, "all_proxy");
overrideWithEnv(op, oparser, PREF_NO_PROXY, "no_proxy"); overrideWithEnv(op, oparser, PREF_NO_PROXY, "no_proxy");
try { // we must clear eof bit and seek to the beginning of the buffer.
oparser.parse(op, cmdstream); cmdstream.clear();
} catch(OptionHandlerException& e) { cmdstream.seekg(0, std::ios::beg);
std::cerr << e.stackTrace() << "\n" // finaly let's parse and store command-iine options.
<< "Usage:" << "\n" oparser.parse(op, cmdstream);
<< oparser.findByName(e.getOptionName())->getDescription() } catch(OptionHandlerException& e) {
<< std::endl; std::cerr << e.stackTrace() << "\n"
exit(DownloadResult::UNKNOWN_ERROR); << "Usage:" << "\n"
} catch(Exception& e) { << oparser.findByName(e.getOptionName())->getDescription()
std::cerr << e.stackTrace() << std::endl; << std::endl;
showUsage(TAG_HELP, oparser); exit(DownloadResult::UNKNOWN_ERROR);
exit(DownloadResult::UNKNOWN_ERROR); } catch(Exception& e) {
} std::cerr << e.stackTrace() << std::endl;
showUsage(TAG_HELP, oparser);
exit(DownloadResult::UNKNOWN_ERROR);
} }
if( if(
#ifdef ENABLE_BITTORRENT #ifdef ENABLE_BITTORRENT
op->blank(PREF_TORRENT_FILE) && op.blank(PREF_TORRENT_FILE) &&
#endif // ENABLE_BITTORRENT #endif // ENABLE_BITTORRENT
#ifdef ENABLE_METALINK #ifdef ENABLE_METALINK
op->blank(PREF_METALINK_FILE) && op.blank(PREF_METALINK_FILE) &&
#endif // ENABLE_METALINK #endif // ENABLE_METALINK
op->blank(PREF_INPUT_FILE)) { op.blank(PREF_INPUT_FILE)) {
if(optind == argc) { if(uris.empty()) {
std::cerr << MSG_URI_REQUIRED << std::endl; std::cerr << MSG_URI_REQUIRED << std::endl;
showUsage(TAG_HELP, oparser); showUsage(TAG_HELP, oparser);
exit(DownloadResult::UNKNOWN_ERROR); exit(DownloadResult::UNKNOWN_ERROR);
} }
} }
#ifdef HAVE_DAEMON #ifdef HAVE_DAEMON
if(op->getAsBool(PREF_DAEMON)) { if(op.getAsBool(PREF_DAEMON)) {
if(daemon(1, 1) < 0) { if(daemon(1, 1) < 0) {
perror(MSG_DAEMON_FAILED); perror(MSG_DAEMON_FAILED);
exit(DownloadResult::UNKNOWN_ERROR); exit(DownloadResult::UNKNOWN_ERROR);
} }
} }
#endif // HAVE_DAEMON #endif // HAVE_DAEMON
return op;
} }
} // namespace aria2 } // namespace aria2

View File

@ -1,8 +1,9 @@
#include "OptionHandlerImpl.h" #include "OptionHandlerImpl.h"
#include <cppunit/extensions/HelperMacros.h>
#include "prefs.h" #include "prefs.h"
#include "Exception.h" #include "Exception.h"
#include <iostream>
#include <cppunit/extensions/HelperMacros.h>
namespace aria2 { namespace aria2 {
@ -53,7 +54,9 @@ void OptionHandlerTest::testNullOptionHandler()
{ {
NullOptionHandler handler; NullOptionHandler handler;
CPPUNIT_ASSERT(handler.canHandle("foo")); CPPUNIT_ASSERT(handler.canHandle("foo"));
handler.parse(0, "bar"); Option option;
handler.parse(option, "bar");
CPPUNIT_ASSERT(!option.defined("bar"));
} }
void OptionHandlerTest::testBooleanOptionHandler() void OptionHandlerTest::testBooleanOptionHandler()
@ -62,16 +65,14 @@ void OptionHandlerTest::testBooleanOptionHandler()
CPPUNIT_ASSERT(handler.canHandle("foo")); CPPUNIT_ASSERT(handler.canHandle("foo"));
CPPUNIT_ASSERT(!handler.canHandle("foobar")); CPPUNIT_ASSERT(!handler.canHandle("foobar"));
Option option; Option option;
handler.parse(&option, V_TRUE); handler.parse(option, V_TRUE);
CPPUNIT_ASSERT_EQUAL(std::string(V_TRUE), option.get("foo")); CPPUNIT_ASSERT_EQUAL(std::string(V_TRUE), option.get("foo"));
handler.parse(&option, V_FALSE); handler.parse(option, V_FALSE);
CPPUNIT_ASSERT_EQUAL(std::string(V_FALSE), option.get("foo")); CPPUNIT_ASSERT_EQUAL(std::string(V_FALSE), option.get("foo"));
try { try {
handler.parse(&option, "hello"); handler.parse(option, "hello");
CPPUNIT_FAIL("exception must be thrown."); CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception& e) { } catch(Exception& e) {}
std::cerr << e.stackTrace() << std::endl;
}
CPPUNIT_ASSERT_EQUAL(std::string("true,false"), CPPUNIT_ASSERT_EQUAL(std::string("true,false"),
handler.createPossibleValuesString()); handler.createPossibleValuesString());
} }
@ -82,7 +83,7 @@ void OptionHandlerTest::testNumberOptionHandler()
CPPUNIT_ASSERT(handler.canHandle("foo")); CPPUNIT_ASSERT(handler.canHandle("foo"));
CPPUNIT_ASSERT(!handler.canHandle("foobar")); CPPUNIT_ASSERT(!handler.canHandle("foobar"));
Option option; Option option;
handler.parse(&option, "0"); handler.parse(option, "0");
CPPUNIT_ASSERT_EQUAL(std::string("0"), option.get("foo")); CPPUNIT_ASSERT_EQUAL(std::string("0"), option.get("foo"));
CPPUNIT_ASSERT_EQUAL(std::string("*-*"), CPPUNIT_ASSERT_EQUAL(std::string("*-*"),
handler.createPossibleValuesString()); handler.createPossibleValuesString());
@ -92,14 +93,12 @@ void OptionHandlerTest::testNumberOptionHandler_min()
{ {
NumberOptionHandler handler("foo", "", "", 1); NumberOptionHandler handler("foo", "", "", 1);
Option option; Option option;
handler.parse(&option, "1"); handler.parse(option, "1");
CPPUNIT_ASSERT_EQUAL(std::string("1"), option.get("foo")); CPPUNIT_ASSERT_EQUAL(std::string("1"), option.get("foo"));
try { try {
handler.parse(&option, "0"); handler.parse(option, "0");
CPPUNIT_FAIL("exception must be thrown."); CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception& e) { } catch(Exception& e) {}
std::cerr << e.stackTrace() << std::endl;
}
CPPUNIT_ASSERT_EQUAL(std::string("1-*"), CPPUNIT_ASSERT_EQUAL(std::string("1-*"),
handler.createPossibleValuesString()); handler.createPossibleValuesString());
} }
@ -108,14 +107,12 @@ void OptionHandlerTest::testNumberOptionHandler_max()
{ {
NumberOptionHandler handler("foo", "", "", -1, 100); NumberOptionHandler handler("foo", "", "", -1, 100);
Option option; Option option;
handler.parse(&option, "100"); handler.parse(option, "100");
CPPUNIT_ASSERT_EQUAL(std::string("100"), option.get("foo")); CPPUNIT_ASSERT_EQUAL(std::string("100"), option.get("foo"));
try { try {
handler.parse(&option, "101"); handler.parse(option, "101");
CPPUNIT_FAIL("exception must be thrown."); CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception& e) { } catch(Exception& e) {}
std::cerr << e.stackTrace() << std::endl;
}
CPPUNIT_ASSERT_EQUAL(std::string("*-100"), CPPUNIT_ASSERT_EQUAL(std::string("*-100"),
handler.createPossibleValuesString()); handler.createPossibleValuesString());
} }
@ -124,22 +121,18 @@ void OptionHandlerTest::testNumberOptionHandler_min_max()
{ {
NumberOptionHandler handler("foo", "", "", 1, 100); NumberOptionHandler handler("foo", "", "", 1, 100);
Option option; Option option;
handler.parse(&option, "1"); handler.parse(option, "1");
CPPUNIT_ASSERT_EQUAL(std::string("1"), option.get("foo")); CPPUNIT_ASSERT_EQUAL(std::string("1"), option.get("foo"));
handler.parse(&option, "100"); handler.parse(option, "100");
CPPUNIT_ASSERT_EQUAL(std::string("100"), option.get("foo")); CPPUNIT_ASSERT_EQUAL(std::string("100"), option.get("foo"));
try { try {
handler.parse(&option, "0"); handler.parse(option, "0");
CPPUNIT_FAIL("exception must be thrown."); CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception& e) { } catch(Exception& e) {}
std::cerr << e.stackTrace() << std::endl;
}
try { try {
handler.parse(&option, "101"); handler.parse(option, "101");
CPPUNIT_FAIL("exception must be thrown."); CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception& e) { } catch(Exception& e) {}
std::cerr << e.stackTrace() << std::endl;
}
CPPUNIT_ASSERT_EQUAL(std::string("1-100"), CPPUNIT_ASSERT_EQUAL(std::string("1-100"),
handler.createPossibleValuesString()); handler.createPossibleValuesString());
} }
@ -150,29 +143,23 @@ void OptionHandlerTest::testUnitNumberOptionHandler()
CPPUNIT_ASSERT(handler.canHandle("foo")); CPPUNIT_ASSERT(handler.canHandle("foo"));
CPPUNIT_ASSERT(!handler.canHandle("foobar")); CPPUNIT_ASSERT(!handler.canHandle("foobar"));
Option option; Option option;
handler.parse(&option, "4294967296"); handler.parse(option, "4294967296");
CPPUNIT_ASSERT_EQUAL(std::string("4294967296"), option.get("foo")); CPPUNIT_ASSERT_EQUAL(std::string("4294967296"), option.get("foo"));
handler.parse(&option, "4096M"); handler.parse(option, "4096M");
CPPUNIT_ASSERT_EQUAL(std::string("4294967296"), option.get("foo")); CPPUNIT_ASSERT_EQUAL(std::string("4294967296"), option.get("foo"));
handler.parse(&option, "4096K"); handler.parse(option, "4096K");
CPPUNIT_ASSERT_EQUAL(std::string("4194304"), option.get("foo")); CPPUNIT_ASSERT_EQUAL(std::string("4194304"), option.get("foo"));
try { try {
handler.parse(&option, "K"); handler.parse(option, "K");
CPPUNIT_FAIL("exception must be thrown."); CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception& e) { } catch(Exception& e) {}
std::cerr << e.stackTrace();
}
try { try {
handler.parse(&option, "M"); handler.parse(option, "M");
} catch(Exception& e) { } catch(Exception& e) {}
std::cerr << e.stackTrace();
}
try { try {
handler.parse(&option, ""); handler.parse(option, "");
CPPUNIT_FAIL("exception must be thrown."); CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception& e) { } catch(Exception& e) {}
std::cerr << e.stackTrace();
}
} }
void OptionHandlerTest::testParameterOptionHandler_1argInit() void OptionHandlerTest::testParameterOptionHandler_1argInit()
@ -181,14 +168,12 @@ void OptionHandlerTest::testParameterOptionHandler_1argInit()
CPPUNIT_ASSERT(handler.canHandle("foo")); CPPUNIT_ASSERT(handler.canHandle("foo"));
CPPUNIT_ASSERT(!handler.canHandle("foobar")); CPPUNIT_ASSERT(!handler.canHandle("foobar"));
Option option; Option option;
handler.parse(&option, "value1"); handler.parse(option, "value1");
CPPUNIT_ASSERT_EQUAL(std::string("value1"), option.get("foo")); CPPUNIT_ASSERT_EQUAL(std::string("value1"), option.get("foo"));
try { try {
handler.parse(&option, "value3"); handler.parse(option, "value3");
CPPUNIT_FAIL("exception must be thrown."); CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception& e) { } catch(Exception& e) {}
std::cerr << e.stackTrace() << std::endl;
}
CPPUNIT_ASSERT_EQUAL(std::string("value1"), CPPUNIT_ASSERT_EQUAL(std::string("value1"),
handler.createPossibleValuesString()); handler.createPossibleValuesString());
} }
@ -199,16 +184,14 @@ void OptionHandlerTest::testParameterOptionHandler_2argsInit()
CPPUNIT_ASSERT(handler.canHandle("foo")); CPPUNIT_ASSERT(handler.canHandle("foo"));
CPPUNIT_ASSERT(!handler.canHandle("foobar")); CPPUNIT_ASSERT(!handler.canHandle("foobar"));
Option option; Option option;
handler.parse(&option, "value1"); handler.parse(option, "value1");
CPPUNIT_ASSERT_EQUAL(std::string("value1"), option.get("foo")); CPPUNIT_ASSERT_EQUAL(std::string("value1"), option.get("foo"));
handler.parse(&option, "value2"); handler.parse(option, "value2");
CPPUNIT_ASSERT_EQUAL(std::string("value2"), option.get("foo")); CPPUNIT_ASSERT_EQUAL(std::string("value2"), option.get("foo"));
try { try {
handler.parse(&option, "value3"); handler.parse(option, "value3");
CPPUNIT_FAIL("exception must be thrown."); CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception& e) { } catch(Exception& e) {}
std::cerr << e.stackTrace() << std::endl;
}
CPPUNIT_ASSERT_EQUAL(std::string("value1,value2"), CPPUNIT_ASSERT_EQUAL(std::string("value1,value2"),
handler.createPossibleValuesString()); handler.createPossibleValuesString());
} }
@ -223,16 +206,14 @@ void OptionHandlerTest::testParameterOptionHandler_listInit()
CPPUNIT_ASSERT(handler.canHandle("foo")); CPPUNIT_ASSERT(handler.canHandle("foo"));
CPPUNIT_ASSERT(!handler.canHandle("foobar")); CPPUNIT_ASSERT(!handler.canHandle("foobar"));
Option option; Option option;
handler.parse(&option, "value1"); handler.parse(option, "value1");
CPPUNIT_ASSERT_EQUAL(std::string("value1"), option.get("foo")); CPPUNIT_ASSERT_EQUAL(std::string("value1"), option.get("foo"));
handler.parse(&option, "value2"); handler.parse(option, "value2");
CPPUNIT_ASSERT_EQUAL(std::string("value2"), option.get("foo")); CPPUNIT_ASSERT_EQUAL(std::string("value2"), option.get("foo"));
try { try {
handler.parse(&option, "value3"); handler.parse(option, "value3");
CPPUNIT_FAIL("exception must be thrown."); CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception& e) { } catch(Exception& e) {}
std::cerr << e.stackTrace() << std::endl;
}
CPPUNIT_ASSERT_EQUAL(std::string("value1,value2"), CPPUNIT_ASSERT_EQUAL(std::string("value1,value2"),
handler.createPossibleValuesString()); handler.createPossibleValuesString());
} }
@ -243,9 +224,9 @@ void OptionHandlerTest::testDefaultOptionHandler()
CPPUNIT_ASSERT(handler.canHandle("foo")); CPPUNIT_ASSERT(handler.canHandle("foo"));
CPPUNIT_ASSERT(!handler.canHandle("foobar")); CPPUNIT_ASSERT(!handler.canHandle("foobar"));
Option option; Option option;
handler.parse(&option, "bar"); handler.parse(option, "bar");
CPPUNIT_ASSERT_EQUAL(std::string("bar"), option.get("foo")); CPPUNIT_ASSERT_EQUAL(std::string("bar"), option.get("foo"));
handler.parse(&option, ""); handler.parse(option, "");
CPPUNIT_ASSERT_EQUAL(std::string(""), option.get("foo")); CPPUNIT_ASSERT_EQUAL(std::string(""), option.get("foo"));
CPPUNIT_ASSERT_EQUAL(std::string(""), handler.createPossibleValuesString()); CPPUNIT_ASSERT_EQUAL(std::string(""), handler.createPossibleValuesString());
@ -264,7 +245,7 @@ void OptionHandlerTest::testFloatNumberOptionHandler()
CPPUNIT_ASSERT(handler.canHandle("foo")); CPPUNIT_ASSERT(handler.canHandle("foo"));
CPPUNIT_ASSERT(!handler.canHandle("foobar")); CPPUNIT_ASSERT(!handler.canHandle("foobar"));
Option option; Option option;
handler.parse(&option, "1.0"); handler.parse(option, "1.0");
CPPUNIT_ASSERT_EQUAL(std::string("1.0"), option.get("foo")); CPPUNIT_ASSERT_EQUAL(std::string("1.0"), option.get("foo"));
CPPUNIT_ASSERT_EQUAL(std::string("*-*"), CPPUNIT_ASSERT_EQUAL(std::string("*-*"),
handler.createPossibleValuesString()); handler.createPossibleValuesString());
@ -274,14 +255,12 @@ void OptionHandlerTest::testFloatNumberOptionHandler_min()
{ {
FloatNumberOptionHandler handler("foo", "", "", 0.0); FloatNumberOptionHandler handler("foo", "", "", 0.0);
Option option; Option option;
handler.parse(&option, "0.0"); handler.parse(option, "0.0");
CPPUNIT_ASSERT_EQUAL(std::string("0.0"), option.get("foo")); CPPUNIT_ASSERT_EQUAL(std::string("0.0"), option.get("foo"));
try { try {
handler.parse(&option, "-0.1"); handler.parse(option, "-0.1");
CPPUNIT_FAIL("exception must be thrown."); CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception& e) { } catch(Exception& e) {}
std::cerr << e.stackTrace() << std::endl;
}
CPPUNIT_ASSERT_EQUAL(std::string("0.0-*"), CPPUNIT_ASSERT_EQUAL(std::string("0.0-*"),
handler.createPossibleValuesString()); handler.createPossibleValuesString());
} }
@ -290,14 +269,12 @@ void OptionHandlerTest::testFloatNumberOptionHandler_max()
{ {
FloatNumberOptionHandler handler("foo", "", "", -1, 10.0); FloatNumberOptionHandler handler("foo", "", "", -1, 10.0);
Option option; Option option;
handler.parse(&option, "10.0"); handler.parse(option, "10.0");
CPPUNIT_ASSERT_EQUAL(std::string("10.0"), option.get("foo")); CPPUNIT_ASSERT_EQUAL(std::string("10.0"), option.get("foo"));
try { try {
handler.parse(&option, "10.1"); handler.parse(option, "10.1");
CPPUNIT_FAIL("exception must be thrown."); CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception& e) { } catch(Exception& e) {}
std::cerr << e.stackTrace() << std::endl;
}
CPPUNIT_ASSERT_EQUAL(std::string("*-10.0"), CPPUNIT_ASSERT_EQUAL(std::string("*-10.0"),
handler.createPossibleValuesString()); handler.createPossibleValuesString());
} }
@ -306,22 +283,18 @@ void OptionHandlerTest::testFloatNumberOptionHandler_min_max()
{ {
FloatNumberOptionHandler handler("foo", "", "", 0.0, 10.0); FloatNumberOptionHandler handler("foo", "", "", 0.0, 10.0);
Option option; Option option;
handler.parse(&option, "0.0"); handler.parse(option, "0.0");
CPPUNIT_ASSERT_EQUAL(std::string("0.0"), option.get("foo")); CPPUNIT_ASSERT_EQUAL(std::string("0.0"), option.get("foo"));
handler.parse(&option, "10.0"); handler.parse(option, "10.0");
CPPUNIT_ASSERT_EQUAL(std::string("10.0"), option.get("foo")); CPPUNIT_ASSERT_EQUAL(std::string("10.0"), option.get("foo"));
try { try {
handler.parse(&option, "-0.1"); handler.parse(option, "-0.1");
CPPUNIT_FAIL("exception must be thrown."); CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception& e) { } catch(Exception& e) {}
std::cerr << e.stackTrace() << std::endl;
}
try { try {
handler.parse(&option, "10.1"); handler.parse(option, "10.1");
CPPUNIT_FAIL("exception must be thrown."); CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception& e) { } catch(Exception& e) {}
std::cerr << e.stackTrace() << std::endl;
}
CPPUNIT_ASSERT_EQUAL(std::string("0.0-10.0"), CPPUNIT_ASSERT_EQUAL(std::string("0.0-10.0"),
handler.createPossibleValuesString()); handler.createPossibleValuesString());
} }
@ -332,24 +305,22 @@ void OptionHandlerTest::testHttpProxyOptionHandler()
CPPUNIT_ASSERT(handler.canHandle(PREF_HTTP_PROXY)); CPPUNIT_ASSERT(handler.canHandle(PREF_HTTP_PROXY));
CPPUNIT_ASSERT(!handler.canHandle("foobar")); CPPUNIT_ASSERT(!handler.canHandle("foobar"));
Option option; Option option;
handler.parse(&option, "proxy:65535"); handler.parse(option, "proxy:65535");
CPPUNIT_ASSERT_EQUAL(std::string("http://proxy:65535"), CPPUNIT_ASSERT_EQUAL(std::string("http://proxy:65535"),
option.get(PREF_HTTP_PROXY)); option.get(PREF_HTTP_PROXY));
handler.parse(&option, "http://proxy:8080"); handler.parse(option, "http://proxy:8080");
CPPUNIT_ASSERT_EQUAL(std::string("http://proxy:8080"), CPPUNIT_ASSERT_EQUAL(std::string("http://proxy:8080"),
option.get(PREF_HTTP_PROXY)); option.get(PREF_HTTP_PROXY));
handler.parse(&option, "ftp://proxy:8080"); handler.parse(option, "ftp://proxy:8080");
CPPUNIT_ASSERT_EQUAL(std::string("http://ftp://proxy:8080"), CPPUNIT_ASSERT_EQUAL(std::string("http://ftp://proxy:8080"),
option.get(PREF_HTTP_PROXY)); option.get(PREF_HTTP_PROXY));
try { try {
handler.parse(&option, "http://bar:65536"); handler.parse(option, "http://bar:65536");
CPPUNIT_FAIL("exception must be thrown."); CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception& e) { } catch(Exception& e) {}
std::cerr << e.stackTrace() << std::endl;
}
CPPUNIT_ASSERT_EQUAL(std::string("[http://][USER:PASSWORD@]HOST[:PORT]"), CPPUNIT_ASSERT_EQUAL(std::string("[http://][USER:PASSWORD@]HOST[:PORT]"),
handler.createPossibleValuesString()); handler.createPossibleValuesString());
} }

View File

@ -1,10 +1,16 @@
#include "OptionParser.h" #include "OptionParser.h"
#include <cstring>
#include <sstream>
#include <deque>
#include <cppunit/extensions/HelperMacros.h>
#include "OptionHandlerImpl.h" #include "OptionHandlerImpl.h"
#include "Exception.h" #include "Exception.h"
#include "Util.h" #include "Util.h"
#include "Option.h" #include "Option.h"
#include <iostream> #include "array_fun.h"
#include <cppunit/extensions/HelperMacros.h>
namespace aria2 { namespace aria2 {
@ -15,7 +21,10 @@ class OptionParserTest:public CppUnit::TestFixture {
CPPUNIT_TEST(testFindByNameSubstring); CPPUNIT_TEST(testFindByNameSubstring);
CPPUNIT_TEST(testFindByTag); CPPUNIT_TEST(testFindByTag);
CPPUNIT_TEST(testFindByName); CPPUNIT_TEST(testFindByName);
CPPUNIT_TEST(testFindByShortName);
CPPUNIT_TEST(testFindByID);
CPPUNIT_TEST(testParseDefaultValues); CPPUNIT_TEST(testParseDefaultValues);
CPPUNIT_TEST(testParseArg);
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
private: private:
SharedHandle<OptionParser> _oparser; SharedHandle<OptionParser> _oparser;
@ -24,26 +33,27 @@ public:
{ {
_oparser.reset(new OptionParser()); _oparser.reset(new OptionParser());
SharedHandle<OptionHandler> alpha(new DefaultOptionHandler("alpha", SharedHandle<OptionHandler> alpha
"", (new DefaultOptionHandler("alpha", NO_DESCRIPTION, "ALPHA", "",
"ALPHA")); OptionHandler::REQ_ARG, 'A'));
alpha->addTag("apple"); alpha->addTag("apple");
_oparser->addOptionHandler(alpha); _oparser->addOptionHandler(alpha);
SharedHandle<OptionHandler> bravo(new DefaultOptionHandler("bravo")); SharedHandle<OptionHandler> bravo(new DefaultOptionHandler("bravo"));
bravo->addTag("apple"); bravo->addTag("apple");
bravo->addTag("orange"); bravo->addTag("orange");
bravo->addTag("pineapple"); bravo->addTag("pineapple");
_oparser->addOptionHandler(bravo); _oparser->addOptionHandler(bravo);
SharedHandle<OptionHandler> charlie(new DefaultOptionHandler("charlie",
"", SharedHandle<DefaultOptionHandler> charlie
"CHARLIE", (new DefaultOptionHandler("charlie", NO_DESCRIPTION, "CHARLIE", "",
"", OptionHandler::REQ_ARG, 'C'));
true)); charlie->hide();
charlie->addTag("pineapple"); charlie->addTag("pineapple");
_oparser->addOptionHandler(charlie); _oparser->addOptionHandler(charlie);
SharedHandle<OptionHandler> delta(new UnitNumberOptionHandler("delta",
"", SharedHandle<OptionHandler> delta
"1M")); (new UnitNumberOptionHandler("delta", NO_DESCRIPTION, "1M", -1, -1, 'D'));
delta->addTag("pineapple"); delta->addTag("pineapple");
_oparser->addOptionHandler(delta); _oparser->addOptionHandler(delta);
} }
@ -54,7 +64,10 @@ public:
void testFindByNameSubstring(); void testFindByNameSubstring();
void testFindByTag(); void testFindByTag();
void testFindByName(); void testFindByName();
void testFindByShortName();
void testFindByID();
void testParseDefaultValues(); void testParseDefaultValues();
void testParseArg();
}; };
@ -97,14 +110,69 @@ void OptionParserTest::testFindByName()
CPPUNIT_ASSERT(charlie.isNull()); CPPUNIT_ASSERT(charlie.isNull());
} }
void OptionParserTest::testFindByShortName()
{
SharedHandle<OptionHandler> alpha = _oparser->findByShortName('A');
CPPUNIT_ASSERT(!alpha.isNull());
CPPUNIT_ASSERT_EQUAL(std::string("alpha"), alpha->getName());
CPPUNIT_ASSERT(_oparser->findByShortName('C').isNull());
}
void OptionParserTest::testFindByID()
{
SharedHandle<OptionHandler> alpha = _oparser->findByID(1);
CPPUNIT_ASSERT(!alpha.isNull());
CPPUNIT_ASSERT_EQUAL(std::string("alpha"), alpha->getName());
CPPUNIT_ASSERT(_oparser->findByID(3).isNull());
}
void OptionParserTest::testParseDefaultValues() void OptionParserTest::testParseDefaultValues()
{ {
Option option; Option option;
_oparser->parseDefaultValues(&option); _oparser->parseDefaultValues(option);
CPPUNIT_ASSERT_EQUAL(std::string("ALPHA"), option.get("alpha")); CPPUNIT_ASSERT_EQUAL(std::string("ALPHA"), option.get("alpha"));
CPPUNIT_ASSERT_EQUAL(std::string("1048576"), option.get("delta")); CPPUNIT_ASSERT_EQUAL(std::string("1048576"), option.get("delta"));
CPPUNIT_ASSERT_EQUAL(std::string("CHARLIE"), option.get("charlie")); CPPUNIT_ASSERT_EQUAL(std::string("CHARLIE"), option.get("charlie"));
CPPUNIT_ASSERT(!option.defined("bravo")); CPPUNIT_ASSERT(!option.defined("bravo"));
} }
void OptionParserTest::testParseArg()
{
Option option;
char prog[7];
strncpy(prog, "aria2c", sizeof(prog));
char optionAlpha[3];
strncpy(optionAlpha, "-A", sizeof(optionAlpha));
char argAlpha[6];
strncpy(argAlpha, "ALPHA", sizeof(argAlpha));
char optionBravo[8];
strncpy(optionBravo, "--bravo", sizeof(optionBravo));
char argBravo[6];
strncpy(argBravo, "BRAVO", sizeof(argBravo));
char nonopt1[8];
strncpy(nonopt1, "nonopt1", sizeof(nonopt1));
char nonopt2[8];
strncpy(nonopt2, "nonopt2", sizeof(nonopt2));
char* const argv[] = { prog, optionAlpha, argAlpha, optionBravo, argBravo,
nonopt1, nonopt2 };
int argc = arrayLength(argv);
std::stringstream s;
std::deque<std::string> nonopts;
_oparser->parseArg(s, nonopts, argc, argv);
CPPUNIT_ASSERT_EQUAL(std::string("alpha=ALPHA\n"
"bravo=BRAVO\n"), s.str());
CPPUNIT_ASSERT_EQUAL((size_t)2, nonopts.size());
CPPUNIT_ASSERT_EQUAL(std::string("nonopt1"), nonopts[0]);
CPPUNIT_ASSERT_EQUAL(std::string("nonopt2"), nonopts[1]);
}
} // namespace aria2 } // namespace aria2