Adding framework for an option parser.

git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@448 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
rakshasa
2005-05-31 19:05:55 +00:00
parent a2248f584f
commit 74930f86b3
15 changed files with 415 additions and 85 deletions
+2 -1
View File
@@ -5,4 +5,5 @@ EXTRA_DIST= \
doc/rtorrent.1.txt \ doc/rtorrent.1.txt \
rak/algorithm.h \ rak/algorithm.h \
rak/functional.h \ rak/functional.h \
scripts/checks.m4 scripts/checks.m4 \
scripts/common.m4
+3 -4
View File
@@ -1,6 +1,3 @@
core::Manager::stop() should make sure ongoing hash checks get cleaned
up.
Polling during last phase of shutdown should be very quick, don't use Polling during last phase of shutdown should be very quick, don't use
normal timeout. normal timeout.
@@ -34,4 +31,6 @@ Show torrent creation date?
Recheck hash key. Recheck hash key.
BUG: Doesn't show the last file in the file list. Seperate download management from core::management.
Allow switching/cycling of tracker.
+2 -2
View File
@@ -1,4 +1,4 @@
AC_INIT(rtorrent, 0.2.3, jaris@ifi.uio.no) AC_INIT(rtorrent, 0.2.4, jaris@ifi.uio.no)
AM_INIT_AUTOMAKE AM_INIT_AUTOMAKE
AM_CONFIG_HEADER(config.h) AM_CONFIG_HEADER(config.h)
@@ -20,7 +20,7 @@ TORRENT_CHECK_EXECINFO()
TORRENT_CHECK_CURL() TORRENT_CHECK_CURL()
TORRENT_OTFD() TORRENT_OTFD()
PKG_CHECK_MODULES(STUFF, sigc++-2.0 libtorrent >= 0.6.3, PKG_CHECK_MODULES(STUFF, sigc++-2.0 libtorrent >= 0.6.4,
CXXFLAGS="$CXXFLAGS $STUFF_CFLAGS $CURL_CFLAGS"; CXXFLAGS="$CXXFLAGS $STUFF_CFLAGS $CURL_CFLAGS";
LIBS="$LIBS $STUFF_LIBS $CURL_LIBS") LIBS="$LIBS $STUFF_LIBS $CURL_LIBS")
+4
View File
@@ -16,6 +16,10 @@ rtorrent_LDADD = \
rtorrent_SOURCES = \ rtorrent_SOURCES = \
main.cc \ main.cc \
option_handler.cc \
option_handler.h \
option_handler_rules.cc \
option_handler_rules.h \
option_parser.cc \ option_parser.cc \
option_parser.h \ option_parser.h \
signal_handler.cc \ signal_handler.cc \
+1
View File
@@ -9,6 +9,7 @@ libsub_core_a_SOURCES = \
download.h \ download.h \
download_list.cc \ download_list.cc \
download_list.h \ download_list.h \
download_slot_map.h \
download_store.cc \ download_store.cc \
download_store.h \ download_store.h \
hash_queue.cc \ hash_queue.cc \
+52
View File
@@ -0,0 +1,52 @@
// rTorrent - BitTorrent client
// Copyright (C) 2005, Jari Sundell
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// Contact: Jari Sundell <jaris@ifi.uio.no>
//
// Skomakerveien 33
// 3185 Skoppum, NORWAY
#ifndef RTORRENT_CORE_DOWNLOAD_SLOT_MAP_H
#define RTORRENT_CORE_DOWNLOAD_SLOT_MAP_H
#include <map>
#include <string>
#include <sigc++/slot.h>
#include "download.h"
namespace core {
class DownloadSlotMap : public std::map<std::string, sigc::slot1<void, Download*> > {
public:
typedef sigc::slot1<void, Download*> SlotDownload;
typedef std::map<std::string, SlotDownload> Base;
void insert(const std::string& key, SlotDownload s) { Base::operator[](key) = s; }
void for_each(Download* d);
};
inline void
DownloadSlotMap::for_each(Download* d) {
for (iterator itr = begin(), last = end(); itr != last; ++itr)
itr->second(d);
}
}
#endif
+3
View File
@@ -180,6 +180,7 @@ Manager::create_final(std::istream* s) {
void void
Manager::setup_download(Download* d) { Manager::setup_download(Download* d) {
// These should be in m_defaultSettings.
d->get_download().set_ip(m_dns); d->get_download().set_ip(m_dns);
if (!m_defaultRoot.empty()) if (!m_defaultRoot.empty())
@@ -188,6 +189,8 @@ Manager::setup_download(Download* d) {
d->get_download().get_name() : d->get_download().get_name() :
"")); ""));
m_defaultSettings.for_each(d);
if (m_debugTracker >= 0) if (m_debugTracker >= 0)
d->get_download().signal_tracker_dump(sigc::mem_fun(*this, &Manager::receive_debug_tracker)); d->get_download().signal_tracker_dump(sigc::mem_fun(*this, &Manager::receive_debug_tracker));
+5
View File
@@ -26,6 +26,7 @@
#include <iosfwd> #include <iosfwd>
#include "download_list.h" #include "download_list.h"
#include "download_slot_map.h"
#include "download_store.h" #include "download_store.h"
#include "hash_queue.h" #include "hash_queue.h"
#include "http_queue.h" #include "http_queue.h"
@@ -51,6 +52,8 @@ public:
HashQueue& get_hash_queue() { return m_hashQueue; } HashQueue& get_hash_queue() { return m_hashQueue; }
HttpQueue& get_http_queue() { return m_httpQueue; } HttpQueue& get_http_queue() { return m_httpQueue; }
DownloadSlotMap& get_default_settings() { return m_defaultSettings; }
Poll& get_poll() { return m_poll; } Poll& get_poll() { return m_poll; }
Log& get_log_important() { return m_logImportant; } Log& get_log_important() { return m_logImportant; }
Log& get_log_complete() { return m_logComplete; } Log& get_log_complete() { return m_logComplete; }
@@ -91,6 +94,8 @@ private:
HashQueue m_hashQueue; HashQueue m_hashQueue;
HttpQueue m_httpQueue; HttpQueue m_httpQueue;
DownloadSlotMap m_defaultSettings;
Poll m_poll; Poll m_poll;
Log m_logImportant; Log m_logImportant;
Log m_logComplete; Log m_logComplete;
+40 -35
View File
@@ -48,6 +48,8 @@
#include "utils/task_schedule.h" #include "utils/task_schedule.h"
#include "signal_handler.h" #include "signal_handler.h"
#include "option_handler.h"
#include "option_handler_rules.h"
#include "option_parser.h" #include "option_parser.h"
int64_t utils::Timer::m_cache; int64_t utils::Timer::m_cache;
@@ -89,19 +91,19 @@ do_shutdown(ui::Control* c) {
} }
int int
parse_options(ui::Control* c, int argc, char** argv) { parse_options(ui::Control* c, OptionHandler* optionHandler, int argc, char** argv) {
OptionParser optionParser; OptionParser optionParser;
optionParser.insert_flag('h', sigc::ptr_fun(&print_help)); optionParser.insert_flag('h', sigc::ptr_fun(&print_help));
optionParser.insert_flag('t', sigc::mem_fun(c->get_core(), &core::Manager::debug_tracker));
optionParser.insert_option('b', sigc::mem_fun(c->get_core(), &core::Manager::set_listen_ip)); optionParser.insert_option('b', sigc::mem_fun(c->get_core(), &core::Manager::set_listen_ip));
optionParser.insert_option('d', sigc::mem_fun(c->get_core(), &core::Manager::set_default_root)); optionParser.insert_option('d', sigc::mem_fun(c->get_core(), &core::Manager::set_default_root));
optionParser.insert_option('i', sigc::mem_fun(c->get_core(), &core::Manager::set_dns)); optionParser.insert_option('i', sigc::mem_fun(c->get_core(), &core::Manager::set_dns));
optionParser.insert_option('p', sigc::bind(sigc::ptr_fun(OptionParser::call_int_pair),
sigc::mem_fun(c->get_core(), &core::Manager::set_port_range)));
optionParser.insert_option('s', sigc::mem_fun(c->get_core().get_download_store(), &core::DownloadStore::activate)); optionParser.insert_option('s', sigc::mem_fun(c->get_core().get_download_store(), &core::DownloadStore::activate));
optionParser.insert_flag('t', sigc::mem_fun(c->get_core(), &core::Manager::debug_tracker)); optionParser.insert_int_pair('p', sigc::mem_fun(c->get_core(), &core::Manager::set_port_range));
optionParser.insert_option_list('o', sigc::mem_fun(*optionHandler, &OptionHandler::process));
return optionParser.process(argc, argv); return optionParser.process(argc, argv);
} }
@@ -135,52 +137,57 @@ initialize_core(ui::Control* c) {
int int
main(int argc, char** argv) { main(int argc, char** argv) {
ui::Control uiControl; OptionHandler optionHandler;
ui::Root uiRoot(&uiControl); ui::Control uiControl;
ui::Root uiRoot(&uiControl);
utils::Timer::update(); utils::Timer::update();
srandom(utils::Timer::cache().usec()); srandom(utils::Timer::cache().usec());
srand48(utils::Timer::cache().usec()); srand48(utils::Timer::cache().usec());
optionHandler.insert("min_peers", new OptionHandlerDownloadMinPeers(&uiControl.get_core().get_default_settings()));
try { try {
SignalHandler::set_ignore(SIGPIPE); SignalHandler::set_ignore(SIGPIPE);
SignalHandler::set_handler(SIGINT, sigc::bind(sigc::mem_fun(uiRoot, &ui::Root::set_shutdown_received), true)); SignalHandler::set_handler(SIGINT, sigc::bind(sigc::mem_fun(uiRoot, &ui::Root::set_shutdown_received), true));
SignalHandler::set_handler(SIGSEGV, sigc::bind(sigc::ptr_fun(&do_panic), SIGSEGV)); SignalHandler::set_handler(SIGSEGV, sigc::bind(sigc::ptr_fun(&do_panic), SIGSEGV));
SignalHandler::set_handler(SIGBUS, sigc::bind(sigc::ptr_fun(&do_panic), SIGBUS)); SignalHandler::set_handler(SIGBUS, sigc::bind(sigc::ptr_fun(&do_panic), SIGBUS));
int firstArg = parse_options(&uiControl, argc, argv); int firstArg = parse_options(&uiControl, &optionHandler, argc, argv);
initialize_display(&uiControl); initialize_display(&uiControl);
initialize_core(&uiControl); initialize_core(&uiControl);
uiRoot.init(); uiRoot.init();
load_session_torrents(&uiControl); load_session_torrents(&uiControl);
load_arg_torrents(&uiControl, argv + firstArg, argv + argc); load_arg_torrents(&uiControl, argv + firstArg, argv + argc);
uiControl.get_display().adjust_layout(); uiControl.get_display().adjust_layout();
while (!is_shutting_down || !torrent::get(torrent::SHUTDOWN_DONE)) { while (!is_shutting_down || !torrent::get(torrent::SHUTDOWN_DONE)) {
if (uiRoot.get_shutdown_received()) { if (uiRoot.get_shutdown_received()) {
do_shutdown(&uiControl); do_shutdown(&uiControl);
uiRoot.set_shutdown_received(false); uiRoot.set_shutdown_received(false);
}
utils::Timer::update();
utils::TaskSchedule::perform(utils::Timer::cache());
// This needs to be called every second or so. Currently done by
// the throttle task in libtorrent.
uiControl.get_display().do_update();
uiControl.get_core().get_poll().poll(utils::TaskSchedule::get_timeout());
} }
utils::Timer::update(); uiRoot.cleanup();
utils::TaskSchedule::perform(utils::Timer::cache()); display::Canvas::cleanup();
// This needs to be called every second or so. Currently done by
// the throttle task in libtorrent.
uiControl.get_display().do_update();
uiControl.get_core().get_poll().poll(utils::TaskSchedule::get_timeout()); uiControl.get_core().cleanup();
}
uiRoot.cleanup();
display::Canvas::cleanup();
} catch (std::exception& e) { } catch (std::exception& e) {
display::Canvas::cleanup(); display::Canvas::cleanup();
@@ -189,8 +196,6 @@ main(int argc, char** argv) {
return -1; return -1;
} }
uiControl.get_core().cleanup();
return 0; return 0;
} }
+73
View File
@@ -0,0 +1,73 @@
// rTorrent - BitTorrent client
// Copyright (C) 2005, Jari Sundell
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// Contact: Jari Sundell <jaris@ifi.uio.no>
//
// Skomakerveien 33
// 3185 Skoppum, NORWAY
#include "config.h"
#include <stdexcept>
#include <sigc++/bind.h>
#include <sigc++/hide.h>
#include "option_handler.h"
OptionHandlerBase::~OptionHandlerBase() {
}
void
OptionHandler::insert(const std::string& key, OptionHandlerBase* opt) {
iterator itr = find(key);
if (itr == end()) {
Base::insert(value_type(key, opt));
} else {
delete itr->second;
itr->second = opt;
}
}
void
OptionHandler::erase(const std::string& key) {
iterator itr = find(key);
if (itr == end())
return;
delete itr->second;
Base::erase(itr);
}
void
OptionHandler::clear() {
for (iterator itr = begin(), last = end(); itr != last; ++itr)
delete itr->second;
Base::clear();
}
void
OptionHandler::process(const std::string& key, const std::string& arg) const {
const_iterator itr = find(key);
if (itr == end())
throw std::runtime_error("Could not find option key matching \"" + key + "\"");
itr->second->process(key, arg);
}
+65
View File
@@ -0,0 +1,65 @@
// rTorrent - BitTorrent client
// Copyright (C) 2005, Jari Sundell
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// Contact: Jari Sundell <jaris@ifi.uio.no>
//
// Skomakerveien 33
// 3185 Skoppum, NORWAY
#ifndef RTORRENT_OPTION_HANDLER_H
#define RTORRENT_OPTION_HANDLER_H
#include <map>
#include <string>
struct OptionHandlerBase {
virtual ~OptionHandlerBase();
virtual void process(const std::string& key, const std::string& arg) = 0;
};
class OptionHandler : private std::map<std::string, OptionHandlerBase*> {
public:
typedef std::map<std::string, OptionHandlerBase*> Base;
typedef Base::value_type value_type;
typedef Base::size_type size_type;
typedef Base::iterator iterator;
typedef Base::reverse_iterator reverse_iterator;
typedef Base::const_iterator const_iterator;
typedef Base::const_reverse_iterator const_reverse_iterator;
using Base::empty;
using Base::size;
using Base::begin;
using Base::end;
using Base::rbegin;
using Base::rend;
using Base::find;
// We take over ownership of opt.
void insert(const std::string& key, OptionHandlerBase* opt);
void erase(const std::string& key);
void clear();
void process(const std::string& key, const std::string& arg) const;
};
#endif
+44
View File
@@ -0,0 +1,44 @@
// rTorrent - BitTorrent client
// Copyright (C) 2005, Jari Sundell
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// Contact: Jari Sundell <jaris@ifi.uio.no>
//
// Skomakerveien 33
// 3185 Skoppum, NORWAY
#include "config.h"
#include <cstdio>
#include <stdexcept>
#include <sigc++/bind.h>
#include "option_handler_rules.h"
OptionHandlerDownloadMinPeers::~OptionHandlerDownloadMinPeers() {
}
void
OptionHandlerDownloadMinPeers::process(const std::string& key, const std::string& arg) {
int a;
if (std::sscanf(arg.c_str(), "%i", &a) != 1 ||
a <= 0 ||
a >= (1 << 16))
throw std::runtime_error("Invalid argument for min peers \"" + arg + "\"");
(*m_map)[key] = sigc::bind(sigc::ptr_fun(&OptionHandlerDownloadMinPeers::apply), a);
}
+48
View File
@@ -0,0 +1,48 @@
// rTorrent - BitTorrent client
// Copyright (C) 2005, Jari Sundell
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// Contact: Jari Sundell <jaris@ifi.uio.no>
//
// Skomakerveien 33
// 3185 Skoppum, NORWAY
#ifndef RTORRENT_OPTION_HANDLER_RULES_H
#define RTORRENT_OPTION_HANDLER_RULES_H
#include "core/download_slot_map.h"
#include "option_handler.h"
class OptionHandlerDownloadMinPeers : public OptionHandlerBase {
public:
OptionHandlerDownloadMinPeers(core::DownloadSlotMap* m) : m_map(m) {}
~OptionHandlerDownloadMinPeers();
virtual void process(const std::string& key, const std::string& arg);
private:
// Move these somewhere else? A seperate file with lots of different
// setting appliers. Those would perform the nessesary checks
// themselves.
static void apply(core::Download* d, int arg) {
d->get_download().set_peers_min(arg);
}
core::DownloadSlotMap* m_map;
};
#endif
+51 -25
View File
@@ -23,25 +23,37 @@
#include "config.h" #include "config.h"
#include <cstdio> #include <cstdio>
#include <sstream>
#include <stdexcept> #include <stdexcept>
#include <unistd.h> #include <unistd.h>
#include <sigc++/bind.h>
#include <sigc++/hide.h> #include <sigc++/hide.h>
#include "option_parser.h" #include "option_parser.h"
void void
OptionParser::insert_flag(char c, SlotFlag s) { OptionParser::insert_flag(char c, Slot s) {
m_container[c].m_slot = sigc::hide(s); m_container[c].m_slot = sigc::hide(s);
m_container[c].m_useOption = false; m_container[c].m_useOption = false;
} }
void void
OptionParser::insert_option(char c, SlotOption s) { OptionParser::insert_option(char c, SlotString s) {
m_container[c].m_slot = s; m_container[c].m_slot = s;
m_container[c].m_useOption = true; m_container[c].m_useOption = true;
} }
void
OptionParser::insert_option_list(char c, SlotStringPair s) {
m_container[c].m_slot = sigc::bind<0>(sigc::ptr_fun(&OptionParser::call_option_list), s);
m_container[c].m_useOption = true;
}
void
OptionParser::insert_int_pair(char c, SlotIntPair s) {
m_container[c].m_slot = sigc::bind<0>(sigc::ptr_fun(&OptionParser::call_int_pair), s);
m_container[c].m_useOption = true;
}
int int
OptionParser::process(int argc, char** argv) { OptionParser::process(int argc, char** argv) {
int c; int c;
@@ -49,31 +61,15 @@ OptionParser::process(int argc, char** argv) {
opterr = 0; opterr = 0;
while ((c = getopt(argc, argv, optString.c_str())) != -1) { while ((c = getopt(argc, argv, optString.c_str())) != -1)
if (c == '?') { if (c == '?')
std::stringstream s; throw std::runtime_error("Invalid/unknown option flag \"-" + std::string(1, (char)optopt) + "\". See rtorrent -h for more information.");
s << "Invalid use of option flag -" << (char)optopt << ". Try rtorrent -h for more information."; else
call(c, optarg ? optarg : "");
throw std::runtime_error(s.str());
} else {
call_flag(c, optarg ? optarg : "");
}
}
return optind; return optind;
} }
void
OptionParser::call_int_pair(const std::string& str, SlotIntPair slot) {
int a, b;
if (sscanf(str.c_str(), "%u-%u", &a, &b) != 2)
throw std::runtime_error("Invalid argument \"" + str + "\" should be <a-b>");
slot(a, b);
}
std::string std::string
OptionParser::create_optstring() { OptionParser::create_optstring() {
std::string s; std::string s;
@@ -89,7 +85,7 @@ OptionParser::create_optstring() {
} }
void void
OptionParser::call_flag(char c, const std::string& arg) { OptionParser::call(char c, const std::string& arg) {
Container::iterator itr = m_container.find(c); Container::iterator itr = m_container.find(c);
if (itr == m_container.end()) if (itr == m_container.end())
@@ -97,3 +93,33 @@ OptionParser::call_flag(char c, const std::string& arg) {
itr->second.m_slot(arg); itr->second.m_slot(arg);
} }
void
OptionParser::call_option_list(SlotStringPair slot, const std::string& arg) {
std::string::const_iterator itr = arg.begin();
while (itr != arg.end()) {
std::string::const_iterator last = std::find(itr, arg.end(), ',');
std::string::const_iterator opt = std::find(itr, last, '=');
if (opt == itr || opt == last)
throw std::logic_error("Invalid argument, \"" + arg + "\" should be \"key1=opt1,key2=opt2,...\"");
slot(std::string(itr, opt), std::string(opt + 1, last));
if (last == arg.end())
break;
itr = ++last;
}
}
void
OptionParser::call_int_pair(SlotIntPair slot, const std::string& arg) {
int a, b;
if (std::sscanf(arg.c_str(), "%u-%u", &a, &b) != 2)
throw std::runtime_error("Invalid argument, \"" + arg + "\" should be \"a-b\"");
slot(a, b);
}
+22 -18
View File
@@ -31,31 +31,35 @@
class OptionParser { class OptionParser {
public: public:
typedef sigc::slot0<void> SlotFlag; typedef sigc::slot0<void> Slot;
typedef sigc::slot1<void, const std::string&> SlotOption; typedef sigc::slot1<void, const std::string&> SlotString;
typedef sigc::slot2<void, int, int> SlotIntPair; typedef sigc::slot2<void, const std::string&, const std::string&> SlotStringPair;
typedef sigc::slot2<void, int, int> SlotIntPair;
struct Node { void insert_flag(char c, Slot s);
SlotOption m_slot; void insert_option(char c, SlotString s);
bool m_useOption; void insert_option_list(char c, SlotStringPair s);
}; void insert_int_pair(char c, SlotIntPair s);
typedef std::map<char, Node> Container;
void insert_flag(char c, SlotFlag s);
void insert_option(char c, SlotOption s);
// Returns the index of the first non-option argument. // Returns the index of the first non-option argument.
int process(int argc, char** argv); int process(int argc, char** argv);
static void call_int_pair(const std::string& str, SlotIntPair slot);
private: private:
std::string create_optstring(); std::string create_optstring();
void call_flag(char c, const std::string& arg); void call(char c, const std::string& arg);
static void call_option_list(SlotStringPair slot, const std::string& arg);
static void call_int_pair(SlotIntPair slot, const std::string& arg);
Container m_container; // Use pair instead?
struct Node {
SlotString m_slot;
bool m_useOption;
};
typedef std::map<char, Node> Container;
Container m_container;
}; };
#endif #endif