#define NO_TARIFF_NAME "*_NO_TARIFF_*"
#define NO_CORP_NAME "*_NO_CORP_*"
-#define mega (1024 * 1024)
-
#define MONITOR_TIME_DELAY_SEC (60)
#endif
PROG = sgconf
SRCS = ./main.cpp \
- ./common_sg.cpp
+ ./common_sg.cpp \
+ ./options.cpp \
+ ./actions.cpp
STGLIBS = conffiles \
srvconf \
--- /dev/null
+/*
+ * 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
+ */
+
+/*
+ * Author : Maxim Mamontov <faust@stargazer.dp.ua>
+ */
+
+#ifndef __STG_SGCONF_ACTION_H__
+#define __STG_SGCONF_ACTION_H__
+
+#include <string>
+#include <stdexcept>
+
+namespace SGCONF
+{
+
+class OPTION_BLOCK;
+struct PARSER_STATE;
+
+class ACTION
+{
+ public:
+ virtual ~ACTION() {}
+
+ virtual ACTION * Clone() const = 0;
+ virtual std::string ParamDescription() const = 0;
+ virtual std::string DefaultDescription() const = 0;
+ virtual OPTION_BLOCK & Suboptions() = 0;
+ virtual PARSER_STATE Parse(int argc, char ** argv) = 0;
+
+ class ERROR : public std::runtime_error
+ {
+ public:
+ ERROR(const std::string & message)
+ : std::runtime_error(message.c_str()) {}
+ };
+};
+
+template <typename T>
+class ACTION_CLONE_MIXIN : public ACTION
+{
+ public:
+ virtual ACTION * Clone() const { return new T(*this); }
+};
+
+} // namespace SGCONF
+
+#endif
--- /dev/null
+/*
+ * 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
+ */
+
+/*
+ * Author : Maxim Mamontov <faust@stargazer.dp.ua>
+ */
--- /dev/null
+/*
+ * 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
+ */
+
+/*
+ * Author : Maxim Mamontov <faust@stargazer.dp.ua>
+ */
+
+#ifndef __STG_SGCONF_ACTIONS_H__
+#define __STG_SGCONF_ACTIONS_H__
+
+#include "action.h"
+#include "options.h"
+#include "parser_state.h"
+
+#include "stg/common.h"
+#include "stg/resetable.h"
+
+#include <string>
+
+namespace SGCONF
+{
+
+typedef void (* FUNC0)();
+
+template <typename F>
+class FUNC0_ACTION : public ACTION
+{
+ public:
+ FUNC0_ACTION(const F & func) : m_func(func) {}
+
+ virtual ACTION * Clone() const { return new FUNC0_ACTION<F>(*this); }
+
+ virtual std::string ParamDescription() const { return ""; }
+ virtual std::string DefaultDescription() const { return ""; }
+ virtual OPTION_BLOCK & Suboptions() { return m_suboptions; }
+ virtual PARSER_STATE Parse(int argc, char ** argv)
+ {
+ m_func();
+ return PARSER_STATE(true, argc, argv);
+ }
+
+ private:
+ F m_func;
+ OPTION_BLOCK m_suboptions;
+};
+
+template <typename F>
+inline
+FUNC0_ACTION<F> * MakeFunc0Action(F func)
+{
+return new FUNC0_ACTION<F>(func);
+}
+
+template <typename T>
+class PARAM_ACTION : public ACTION
+{
+ public:
+ PARAM_ACTION(RESETABLE<T> & param,
+ const T & defaultValue,
+ const std::string & paramDescription)
+ : m_param(param),
+ m_defaltValue(defaultValue),
+ m_description(paramDescription),
+ m_hasDefault(true)
+ {}
+ PARAM_ACTION(RESETABLE<T> & param,
+ const std::string & paramDescription)
+ : m_param(param),
+ m_description(paramDescription),
+ m_hasDefault(false)
+ {}
+
+ virtual ACTION * Clone() const { return new PARAM_ACTION<T>(*this); }
+
+ virtual std::string ParamDescription() const { return m_description; }
+ virtual std::string DefaultDescription() const;
+ virtual OPTION_BLOCK & Suboptions() { return m_suboptions; }
+ virtual PARSER_STATE Parse(int argc, char ** argv);
+
+ private:
+ RESETABLE<T> & m_param;
+ T m_defaltValue;
+ std::string m_description;
+ bool m_hasDefault;
+ OPTION_BLOCK m_suboptions;
+};
+
+template <typename T>
+inline
+std::string PARAM_ACTION<T>::DefaultDescription() const
+{
+return m_hasDefault ? " (default: '" + x2str(m_defaltValue) + "')"
+ : "";
+}
+
+template <>
+inline
+std::string PARAM_ACTION<std::string>::DefaultDescription() const
+{
+return m_hasDefault ? " (default: '" + m_defaltValue + "')"
+ : "";
+}
+
+template <typename T>
+inline
+PARSER_STATE PARAM_ACTION<T>::Parse(int argc, char ** argv)
+{
+if (argc == 0 ||
+ argv == NULL ||
+ *argv == NULL)
+ throw ERROR("Missing argument.");
+T value;
+if (str2x(*argv, value))
+ throw ERROR(std::string("Bad argument: '") + *argv + "'");
+m_param = value;
+return PARSER_STATE(false, --argc, ++argv);
+}
+
+template <>
+inline
+PARSER_STATE PARAM_ACTION<std::string>::Parse(int argc, char ** argv)
+{
+if (argc == 0 ||
+ argv == NULL ||
+ *argv == NULL)
+ throw ERROR("Missing argument.");
+m_param = *argv;
+return PARSER_STATE(false, --argc, ++argv);
+}
+
+template <typename T>
+inline
+PARAM_ACTION<T> * MakeParamAction(RESETABLE<T> & param,
+ const T & defaultValue,
+ const std::string & paramDescription)
+{
+return new PARAM_ACTION<T>(param, defaultValue, paramDescription);
+}
+
+template <typename T>
+inline
+PARAM_ACTION<T> * MakeParamAction(RESETABLE<T> & param,
+ const std::string & paramDescription)
+{
+return new PARAM_ACTION<T>(param, paramDescription);
+}
+
+} // namespace SGCONF
+
+#endif
+++ /dev/null
-/*
- * 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
- */
-
-/*
- * Author : Maxim Mamontov <faust@stargazer.dp.ua>
- */
-
-#ifndef __STG_SGCONF_COMPOSER_H__
-#define __STG_SGCONF_COMPOSER_H__
-
-#include "parser_state.h"
-
-namespace SGCONF
-{
-
-class COMPOSER
-{
- public:
- typedef PARSER_STATE (* FUNC)(int, char **, CONFIG&);
- COMPOSER(int argc, char ** argv)
- : m_done(false), m_result(0)
- { mstate.argc = argc; m_state.argv = argv; }
- COMPOSER compose(FUNC func)
- {
- if (m_done)
- return COMPOSER(m_result);
- try
- {
- PARSER_STATE state(func(m_state.argc, m_state.argv, m_state.config));
- if (state.result)
- return COMPOSER(0);
- else
- return COMPOSER(state);
- }
- catch (const PARSER_ERROR& ex)
- {
- std::cerr << ex.what() << "\n";
- return COMPOSER(-1);
- }
- }
- int exec()
- {
- if (m_done)
- return m_result;
- Usage();
- return -1;
- }
-
- private:
- bool m_done;
- int m_result;
- PARSER_STATE m_state;
-
- COMPOSER(int result)
- : m_done(true),
- m_result(result)
- {
- }
-
- COMPOSER(const PARSER_STATE& state)
- : m_done(false),
- m_result(0),
- m_state(state)
-};
-
-}
/*
* Author : Boris Mikhailenko <stg34@stargazer.dp.ua>
- */
-
- /*
- $Author: faust $
- $Revision: 1.25 $
- $Date: 2010/03/25 14:37:43 $
+ * Author : Maxim Mamontov <faust@stargazer.dp.ua>
*/
#include "request.h"
#include "common_sg.h"
#include "sg_error_codes.h"
+#include "options.h"
+#include "actions.h"
+#include "config.h"
+
#include "stg/user_conf.h"
#include "stg/user_stat.h"
#include "stg/common.h"
typedef T type;
};
+template <typename T>
+struct nullary_function
+{
+typedef T result_type;
+};
+
+template <typename F>
+class binder0 : public nullary_function<typename F::result_type>
+{
+ public:
+ binder0(const F & func, const typename F::argument_type & arg)
+ : m_func(func), m_arg(arg) {}
+ typename F::result_type operator()() const { return m_func(m_arg); }
+ private:
+ F m_func;
+ typename F::argument_type m_arg;
+};
+
+template <typename F>
+inline
+binder0<F> bind0(const F & func, const typename F::argument_type & arg)
+{
+return binder0<F>(func, arg);
+}
+
+template <typename C, typename A, typename R>
+class METHOD1_ADAPTER : public std::unary_function<A, R>
+{
+ public:
+ METHOD1_ADAPTER(R (C::* func)(A), C & obj) : m_func(func), m_obj(obj) {}
+ R operator()(A arg) { return (m_obj.*m_func)(arg); }
+ private:
+ R (C::* m_func)(A);
+ C & m_obj;
+};
+
+template <typename C, typename A, typename R>
+class CONST_METHOD1_ADAPTER : public std::unary_function<A, R>
+{
+ public:
+ CONST_METHOD1_ADAPTER(R (C::* func)(A) const, C & obj) : m_func(func), m_obj(obj) {}
+ R operator()(A arg) const { return (m_obj.*m_func)(arg); }
+ private:
+ R (C::* m_func)(A) const;
+ C & m_obj;
+};
+
+template <typename C, typename A, typename R>
+METHOD1_ADAPTER<C, A, R> Method1Adapt(R (C::* func)(A), C & obj)
+{
+return METHOD1_ADAPTER<C, A, R>(func, obj);
+}
+
+template <typename C, typename A, typename R>
+CONST_METHOD1_ADAPTER<C, A, R> Method1Adapt(R (C::* func)(A) const, C & obj)
+{
+return CONST_METHOD1_ADAPTER<C, A, R>(func, obj);
+}
+
template <typename T>
bool SetArrayItem(T & array, const char * index, const typename ARRAY_TYPE<T>::type & value)
{
return true;
}
-void Usage(bool full);
+void Usage();
+void UsageAll();
+void UsageImpl(bool full);
void UsageConnection();
void UsageAdmins(bool full);
void UsageTariffs(bool full);
void UsageServices(bool full);
void UsageCorporations(bool full);
+void Version();
+
} // namespace anonymous
+namespace SGCONF
+{
+
+class CONFIG_ACTION : public ACTION
+{
+ public:
+ CONFIG_ACTION(CONFIG & config,
+ const std::string & paramDescription)
+ : m_config(config),
+ m_description(paramDescription)
+ {}
+
+ virtual ACTION * Clone() const { return new CONFIG_ACTION(*this); }
+
+ virtual std::string ParamDescription() const { return m_description; }
+ virtual std::string DefaultDescription() const { return ""; }
+ virtual OPTION_BLOCK & Suboptions() { return m_suboptions; }
+ virtual PARSER_STATE Parse(int argc, char ** argv);
+
+ private:
+ CONFIG & m_config;
+ std::string m_description;
+ OPTION_BLOCK m_suboptions;
+
+ void ParseCredentials(const std::string & credentials);
+ void ParseHostAndPort(const std::string & hostAndPort);
+};
+
+PARSER_STATE CONFIG_ACTION::Parse(int argc, char ** argv)
+{
+if (argc == 0 ||
+ argv == NULL ||
+ *argv == NULL)
+ throw ERROR("Missing argument.");
+char * pos = strchr(*argv, '@');
+if (pos != NULL)
+ {
+ ParseCredentials(std::string(*argv, pos));
+ ParseHostAndPort(std::string(pos + 1));
+ }
+else
+ {
+ ParseHostAndPort(std::string(*argv));
+ }
+return PARSER_STATE(false, --argc, ++argv);
+}
+
+void CONFIG_ACTION::ParseCredentials(const std::string & credentials)
+{
+std::string::size_type pos = credentials.find_first_of(':');
+if (pos != std::string::npos)
+ {
+ m_config.userName = credentials.substr(0, pos);
+ m_config.userPass = credentials.substr(pos + 1);
+ }
+else
+ {
+ m_config.userName = credentials;
+ }
+}
+
+void CONFIG_ACTION::ParseHostAndPort(const std::string & hostAndPort)
+{
+std::string::size_type pos = hostAndPort.find_first_of(':');
+if (pos != std::string::npos)
+ {
+ m_config.server = hostAndPort.substr(0, pos);
+ uint16_t port = 0;
+ if (str2x(hostAndPort.substr(pos + 1), port))
+ throw ERROR("Invalid port value: '" + hostAndPort.substr(pos + 1) + "'");
+ m_config.port = port;
+ }
+else
+ {
+ m_config.server = hostAndPort;
+ }
+}
+
+inline
+CONFIG_ACTION * MakeParamAction(CONFIG & config,
+ const std::string & paramDescription)
+{
+return new CONFIG_ACTION(config, paramDescription);
+}
+
+} // namespace SGCONF
+
time_t stgTime;
struct option long_options_get[] = {
return ProcessSetUser(req.server.data(), req.port.data(), req.admLogin.data(), req.admPasswd.data(), req.login.data(), conf, stat);
}
//-----------------------------------------------------------------------------
-PARSER_STATE TryParse(const PARSERS& parsers, char ** argv, int argc)
-{
-PARSERS::const_iterator it = parsers.find(*argv);
-if (it != parsers.end())
- return it->second(++argv, --argc);
-PARSER_STATE state;
-state.argc = argc;
-state.argv = argv;
-state.result = false;
-return state;
-}
-//-----------------------------------------------------------------------------
-PARSER_STATE ParseCommon(int argc, char ** argv, CONFIG& config)
+int main(int argc, char **argv)
{
-if (pos == 0)
- ++pos;
+SGCONF::CONFIG config;
-PARSERS parsers;
-parsers.add<std::string>("-c", "--config", config.configFile);
-parsers.add<void>("-h", "--help", Usage, false);
-parsers.add<void>("--help-all", Usage, true);
-parsers.add<void>("-v", "--version", Version);
+SGCONF::OPTION_BLOCKS blocks;
+blocks.Add("General options")
+ .Add("c", "config", SGCONF::MakeParamAction(config.configFile, std::string("~/.config/stg/sgconf.conf"), "<config file>"), "override default config file")
+ .Add("h", "help", SGCONF::MakeFunc0Action(bind0(Method1Adapt(&SGCONF::OPTION_BLOCKS::Help, blocks), 0)), "\t\tshow this help and exit")
+ .Add("help-all", SGCONF::MakeFunc0Action(UsageAll), "\t\tshow full help and exit")
+ .Add("v", "version", SGCONF::MakeFunc0Action(Version), "\t\tshow version information and exit");
+blocks.Add("Connection options")
+ .Add("s", "server", SGCONF::MakeParamAction(config.server, std::string("localhost"), "<address>"), "\t\thost to connect")
+ .Add("p", "port", SGCONF::MakeParamAction(config.port, uint16_t(5555), "<port>"), "\t\tport to connect")
+ .Add("u", "username", SGCONF::MakeParamAction(config.userName, std::string("admin"), "<username>"), "\tadministrative login")
+ .Add("w", "userpass", SGCONF::MakeParamAction(config.userPass, "<password>"), "\tpassword for the administrative login")
+ .Add("a", "address", SGCONF::MakeParamAction(config, "<connection string>"), "connection params as a single string in format: <login>:<password>@<host>:<port>");
-while (true)
- {
- PARSER_STATE state(TryParse(parsers, argv, argc, config));
- if (state.argv == argv)
- return state; // No-op
- if (state.argc == 0)
- return state; // EOF
- if (state.result)
- return state; // Done
- argv = state.argv;
- argc = state.argc;
- }
-assert(0 && "Can't be here.");
-return PARSER_STATE();
+SGCONF::PARSER_STATE state(false, argc, argv);
+
+try
+{
+state = blocks.Parse(--argc, ++argv); // Skipping self name
}
-//-----------------------------------------------------------------------------
-int main(int argc, char **argv)
+catch (const SGCONF::OPTION::ERROR& ex)
{
-Usage(true);
-exit(0);
+std::cerr << ex.what() << "\n";
+return -1;
+}
-// Ok - succesfully parsed
-// Done - don't continue, return 0
-// Error - don't continue, return -1
-// No-op - nothing changed
+if (state.stop)
+ return 0;
-return COMPOSER(argv).compose(ParseCommon)
- .compose(ReadConfig)
- .compose(ParseCommand)
- .exec();
+if (state.argc > 0)
+ {
+ std::cerr << "Unknown option: '" << *state.argv << "'\n";
+ return -1;
+ }
+return 0;
if (argc < 2)
{
- // TODO: no arguments
- Usage(false);
+ Usage();
return 1;
}
namespace
{
-void Usage(bool full)
+void Usage()
+{
+UsageImpl(false);
+}
+
+void UsageAll()
+{
+UsageImpl(true);
+}
+
+void UsageImpl(bool full)
{
std::cout << "sgconf is the Stargazer management utility.\n\n"
<< "Usage:\n"
<< "\t\t--set-cash <cash>[:<message>]\tnew corporation's cash and optional comment message\n\n";
}
+void Version()
+{
+std::cout << "sgconf, version: 2.0.0-alpha.\n";
+}
+
} // namespace anonymous
--- /dev/null
+/*
+ * 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
+ */
+
+/*
+ * Author : Maxim Mamontov <faust@stargazer.dp.ua>
+ */
+
+#include "options.h"
+
+#include "action.h"
+#include "parser_state.h"
+
+#include <iostream>
+#include <functional>
+#include <algorithm>
+
+using SGCONF::OPTION;
+using SGCONF::OPTION_BLOCK;
+using SGCONF::OPTION_BLOCKS;
+using SGCONF::ACTION;
+using SGCONF::PARSER_STATE;
+
+OPTION::OPTION(const std::string & shortName,
+ const std::string & longName,
+ ACTION * action,
+ const std::string & description)
+ : m_shortName(shortName),
+ m_longName(longName),
+ m_action(action),
+ m_description(description)
+{
+}
+
+OPTION::OPTION(const std::string & longName,
+ ACTION * action,
+ const std::string & description)
+ : m_longName(longName),
+ m_action(action),
+ m_description(description)
+{
+}
+
+OPTION::OPTION(const OPTION & rhs)
+ : m_shortName(rhs.m_shortName),
+ m_longName(rhs.m_longName),
+ m_action(rhs.m_action->Clone()),
+ m_description(rhs.m_description)
+{
+}
+
+OPTION::~OPTION()
+{
+delete m_action;
+}
+
+void OPTION::Help(size_t level) const
+{
+if (!m_action)
+ throw ERROR("Option is not defined.");
+std::string indent(level, '\t');
+std::cout << indent << "\t";
+if (!m_shortName.empty())
+ std::cout << "-" << m_shortName << ", ";
+std::cout << "--" << m_longName << " " << m_action->ParamDescription()
+ << "\t" << m_description << m_action->DefaultDescription() << "\n";
+m_action->Suboptions().Help(level + 1);
+}
+
+bool OPTION::Check(const char * arg) const
+{
+if (arg == NULL)
+ return false;
+
+if (*arg++ != '-')
+ return false;
+
+if (*arg == '-')
+ return m_longName == arg + 1;
+
+return m_shortName == arg;
+}
+
+PARSER_STATE OPTION::Parse(int argc, char ** argv)
+{
+if (!m_action)
+ throw ERROR("Option is not defined.");
+try
+ {
+ return m_action->Parse(argc, argv);
+ }
+catch (const ACTION::ERROR & ex)
+ {
+ if (m_longName.empty())
+ throw ERROR("-" + m_shortName + ": " + ex.what());
+ else
+ throw ERROR("--" + m_longName + ", -" + m_shortName + ": " + ex.what());
+ }
+}
+
+OPTION_BLOCK & OPTION_BLOCK::Add(const std::string & shortName,
+ const std::string & longName,
+ ACTION * action,
+ const std::string & description)
+{
+m_options.push_back(OPTION(shortName, longName, action, description));
+return *this;
+}
+
+OPTION_BLOCK & OPTION_BLOCK::Add(const std::string & longName,
+ ACTION * action,
+ const std::string & description)
+{
+m_options.push_back(OPTION(longName, action, description));
+return *this;
+}
+
+void OPTION_BLOCK::Help(size_t level) const
+{
+if (m_options.empty())
+ return;
+std::cout << m_description << ":\n";
+std::for_each(m_options.begin(),
+ m_options.end(),
+ std::bind2nd(std::mem_fun_ref(&OPTION::Help), level + 1));
+}
+
+PARSER_STATE OPTION_BLOCK::Parse(int argc, char ** argv)
+{
+PARSER_STATE state(false, argc, argv);
+while (state.argc > 0 && !state.stop)
+ {
+ std::vector<OPTION>::iterator it = std::find_if(m_options.begin(), m_options.end(), std::bind2nd(std::mem_fun_ref(&OPTION::Check), *state.argv));
+ if (it != m_options.end())
+ state = it->Parse(--state.argc, ++state.argv);
+ else
+ break;
+ ++it;
+ }
+return state;
+}
+
+void OPTION_BLOCKS::Help(size_t level) const
+{
+std::list<OPTION_BLOCK>::const_iterator it(m_blocks.begin());
+while (it != m_blocks.end())
+ {
+ it->Help(level);
+ std::cout << "\n";
+ ++it;
+ }
+}
+
+PARSER_STATE OPTION_BLOCKS::Parse(int argc, char ** argv)
+{
+PARSER_STATE state(false, argc, argv);
+std::list<OPTION_BLOCK>::iterator it(m_blocks.begin());
+while (!state.stop && it != m_blocks.end())
+ {
+ state = it->Parse(state.argc, state.argv);
+ ++it;
+ }
+return state;
+}
--- /dev/null
+/*
+ * 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
+ */
+
+/*
+ * Author : Maxim Mamontov <faust@stargazer.dp.ua>
+ */
+
+#ifndef __STG_SGCONF_OPTIONS_H__
+#define __STG_SGCONF_OPTIONS_H__
+
+#include <string>
+#include <vector>
+#include <list>
+#include <stdexcept>
+#include <cstddef> // size_t
+
+namespace SGCONF
+{
+
+class ACTION;
+struct PARSER_STATE;
+
+class OPTION
+{
+ public:
+ OPTION(const std::string & shortName,
+ const std::string & longName,
+ ACTION * action,
+ const std::string & description);
+ OPTION(const std::string & longName,
+ ACTION * action,
+ const std::string & description);
+ OPTION(const OPTION & rhs);
+ ~OPTION();
+
+ OPTION & operator=(const OPTION & rhs);
+
+ void Help(size_t level = 0) const;
+ PARSER_STATE Parse(int argc, char ** argv);
+ bool Check(const char * arg) const;
+
+ class ERROR : public std::runtime_error
+ {
+ public:
+ ERROR(const std::string & message)
+ : std::runtime_error(message.c_str()) {}
+ };
+
+ private:
+ std::string m_shortName;
+ std::string m_longName;
+ ACTION * m_action;
+ std::string m_description;
+};
+
+class OPTION_BLOCK
+{
+ public:
+ OPTION_BLOCK() {}
+ OPTION_BLOCK(const std::string & description)
+ : m_description(description) {}
+ OPTION_BLOCK & Add(const std::string & shortName,
+ const std::string & longName,
+ ACTION * action,
+ const std::string & description);
+ OPTION_BLOCK & Add(const std::string & longName,
+ ACTION * action,
+ const std::string & description);
+
+ void Help(size_t level) const;
+
+ PARSER_STATE Parse(int argc, char ** argv);
+
+ private:
+ std::vector<OPTION> m_options;
+ std::string m_description;
+};
+
+class OPTION_BLOCKS
+{
+ public:
+ OPTION_BLOCK & Add(const std::string & description)
+ { m_blocks.push_back(OPTION_BLOCK(description)); return m_blocks.back(); }
+ void Help(size_t level) const;
+ PARSER_STATE Parse(int argc, char ** argv);
+
+ private:
+ std::list<OPTION_BLOCK> m_blocks;
+};
+
+} // namespace SGCONF
+
+#endif
#ifndef __STG_SGCONF_PARSER_STATE_H__
#define __STG_SGCONF_PARSER_STATE_H__
-#include "config.h"
-
namespace SGCONF
{
struct PARSER_STATE
{
- CONFIG config;
- bool result;
+ PARSER_STATE(bool s, int c, char ** v) : stop(s), argc(c), argv(v) {}
+ bool stop;
int argc;
char ** argv;
};
}
+
+#endif
+++ /dev/null
-/*
- * 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
- */
-
-/*
- * Author : Maxim Mamontov <faust@stargazer.dp.ua>
- */
-
-#ifndef __STG_SGCONF_PARSERS_H__
-#define __STG_SGCONF_PARSERS_H__
-
-namespace SGCONF
-{
-
-typedef void (*FUNC0)();
-
-template <typename T>
-struct FUNC1
-{
-typedef void (*type)(T);
-};
-
-class PARSER
-{
- public:
- virtual PARSER_STATE parse(int, char **, CONFIG&) = 0;
-};
-
-template <typename T>
-class PARAM_PARSER : public PARSER
-{
- public:
- PARAM_PARSER(T& var) : m_var(var) {}
- virtual PARSER_STATE parse(int argc, char ** argv, CONFIG& config)
- {
- std::istringstream stream(argv[0]);
- stream >> m_var;
- PARSER_STATE state;
- state.argc = argc - 1;
- state.argv = argv + 1;
- state.config = config;
- state.result = false;
- return state;
- }
-
- private:
- T& m_var;
-};
-
-class FUNC0_PARSER
-{
- public:
- FUNC0_PARSER(FUNC0 func) : m_func(func) {}
- virtual PARSER_STATE parse(int argc, char ** argv, CONFIG& config)
- {
- m_func();
- PARSER_STATE state;
- state.argc = argc - 1;
- state.argv = argv + 1;
- state.config = config;
- state.result = true;
- return state;
- }
-
- private:
- FUNC0 m_func;
-};
-
-template <typename T>
-class FUNC1_PARSER
-{
- public:
- FUNC1_PARSER(typename FUNC1<T>::type func, const T & arg) : m_func(func), m_arg(arg) {}
- virtual PARSER_STATE parse(int argc, char ** argv, CONFIG& config)
- {
- m_func(m_arg);
- PARSER_STATE state;
- state.argc = argc - 1;
- state.argv = argv + 1;
- state.config = config;
- state.result = true;
- return state;
- }
-
- private:
- typename FUNC1<T>::type m_func;
- T m_arg;
-}
-
-class PARSERS
-{
- public:
- typedef PARSER_STATE (* FUNC)(int, char **, CONFIG&);
-
- template <typename T>
- void add(const std::string & shortToken,
- const std::string & fullToken,
- T& var);
-
- template <>
- void add<void>(const std:string & shortToken,
- const std::string & fullToken,
- FUNC0 func);
- template <typename V>
- void add<void>(const std:string & shortToken,
- const std::string & fullToken,
- FUNC1 func, const V& v);
-
- private:
-};
-
-}