diff options
author | randomdan <randomdan@localhost> | 2011-12-16 19:44:00 +0000 |
---|---|---|
committer | randomdan <randomdan@localhost> | 2011-12-16 19:44:00 +0000 |
commit | 9b728d20cfadb185ccbe6df9c553af71155cb348 (patch) | |
tree | 05af7babef544e4832c293d149aa7a33e3181b03 | |
parent | Remove straggling references to XML and configuration from recent changes (diff) | |
download | project2-9b728d20cfadb185ccbe6df9c553af71155cb348.tar.bz2 project2-9b728d20cfadb185ccbe6df9c553af71155cb348.tar.xz project2-9b728d20cfadb185ccbe6df9c553af71155cb348.zip |
Improvements to the handling of command line arguments
-rw-r--r-- | project2/cgi/cgiEnvironment.cpp | 6 | ||||
-rw-r--r-- | project2/cgi/cgiEnvironment.h | 1 | ||||
-rw-r--r-- | project2/cgi/testCgi.cpp | 16 | ||||
-rw-r--r-- | project2/common/environment.cpp | 38 | ||||
-rw-r--r-- | project2/common/options.cpp | 49 | ||||
-rw-r--r-- | project2/common/options.h | 9 | ||||
-rw-r--r-- | project2/common/optionsSource.h | 7 | ||||
-rw-r--r-- | project2/common/variables-modconfig.cpp | 12 | ||||
-rw-r--r-- | project2/console/claOptions.cpp | 89 | ||||
-rw-r--r-- | project2/console/consoleEnvironment.cpp | 3 | ||||
-rw-r--r-- | project2/xml/transformHtml.cpp | 4 |
11 files changed, 168 insertions, 66 deletions
diff --git a/project2/cgi/cgiEnvironment.cpp b/project2/cgi/cgiEnvironment.cpp index ae7ad52..7b2b254 100644 --- a/project2/cgi/cgiEnvironment.cpp +++ b/project2/cgi/cgiEnvironment.cpp @@ -120,6 +120,12 @@ HostnamePlatformIdentifier::reset() const } } +bool +HostnamePlatformIdentifier::paramRequired() const +{ + return true; +} + void HostnamePlatformIdentifier::consume(const Glib::ustring & p, const Glib::ustring & r) const { diff --git a/project2/cgi/cgiEnvironment.h b/project2/cgi/cgiEnvironment.h index 654f772..28e47d3 100644 --- a/project2/cgi/cgiEnvironment.h +++ b/project2/cgi/cgiEnvironment.h @@ -15,6 +15,7 @@ class HostnamePlatformIdentifier : public Options::Target { HostnamePlatformIdentifier(); virtual ~HostnamePlatformIdentifier(); void reset() const; + bool paramRequired() const; void consume(const Glib::ustring &, const Glib::ustring &) const; const Glib::ustring & derivedPlatform() const; private: diff --git a/project2/cgi/testCgi.cpp b/project2/cgi/testCgi.cpp index c2e8d4e..855e59b 100644 --- a/project2/cgi/testCgi.cpp +++ b/project2/cgi/testCgi.cpp @@ -10,6 +10,20 @@ (name, Options::value(optStore.insert(OptStore::value_type(name, new std::string())).first->second, def), desc) class TestInput : public cgicc::CgiInput { public: + class TestConfigConsumer : public ConfigConsumer { + public: + TestConfigConsumer(const Options * os) : o(os) { + } + void operator()(const Glib::ustring & n, const Glib::ustring & p, const Glib::ustring & v) const { + o->consume(n, p, v); + } + const Options::Option * get(const Glib::ustring &) const { + return NULL; + } + private: + const Options * o; + }; + typedef std::string * StrPtr; typedef std::map<std::string, StrPtr> OptStore; OptStore optStore; @@ -45,7 +59,7 @@ class TestInput : public cgicc::CgiInput { ; FileOptions fo(".testCgi.settings"); opts.reset(); - fo.loadInto(boost::bind(&Options::consume, &opts, _1, _2, _3)); + fo.loadInto(TestConfigConsumer(&opts)); } const Options * options() const { diff --git a/project2/common/environment.cpp b/project2/common/environment.cpp index 891f1d9..2047813 100644 --- a/project2/common/environment.cpp +++ b/project2/common/environment.cpp @@ -44,30 +44,40 @@ optionsHelper(AllOptions * ao, const Options * options) } } -static -void -consumeIntoAll(const AllOptions * ao, const Glib::ustring & n, const Glib::ustring & p, const Glib::ustring & v) -{ - BOOST_FOREACH(const Options * o, *ao) { - o->consume(n, p, v); - } -} +class DefaultConfigConsumer : public ConfigConsumer { + public: + void operator()(const Glib::ustring & n, const Glib::ustring & p, const Glib::ustring & v) const { + BOOST_FOREACH(const Options * o, allOptions) { + o->consume(n, p, v); + } + } + const Options::Option * get(const Glib::ustring & n) const { + BOOST_FOREACH(const Options * os, allOptions) { + const Options::Option * o = os->find(n); + if (o) { + return o; + } + } + return NULL; + } + AllOptions allOptions; +}; void Environment::init() { - AllOptions allOptions; - allOptions.push_back(&commonOptions); - allOptions.push_back(&engineOptions()); - LoaderBase::onAllComponents(boost::bind(optionsHelper, &allOptions, boost::bind(&ComponentLoader::options, _1))); + DefaultConfigConsumer dcc; + dcc.allOptions.push_back(&commonOptions); + dcc.allOptions.push_back(&engineOptions()); + LoaderBase::onAllComponents(boost::bind(optionsHelper, &dcc.allOptions, boost::bind(&ComponentLoader::options, _1))); - BOOST_FOREACH(const AllOptions::value_type & v, allOptions) { + BOOST_FOREACH(const AllOptions::value_type & v, dcc.allOptions) { v->reset(); } typedef std::map<std::string, boost::shared_ptr<OptionsSourceLoader> > ConfigParsersMap; BOOST_FOREACH(const ConfigParsersMap::value_type & cp, *LoaderBase::objLoaders<OptionsSourceLoader>()) { - cp.second->create()->loadInto(boost::bind(&consumeIntoAll, &allOptions, _1, _2, _3)); + cp.second->create()->loadInto(dcc); } Logger()->clear(); diff --git a/project2/common/options.cpp b/project2/common/options.cpp index a99c78e..8ff7f55 100644 --- a/project2/common/options.cpp +++ b/project2/common/options.cpp @@ -6,42 +6,66 @@ class NamedOption : public Options::Option { public: NamedOption(Glib::ustring const & n, Options::TargetPtr t, Glib::ustring const & d) : - name(n), + id(n), target(t), desc(d) { } void consume(const Glib::ustring & n, const Glib::ustring & p, const Glib::ustring & v) const { - if (n == name) { + if (n == id) { target->consume(p, v); } } void reset() const { target->reset(); } + bool accepts(const Glib::ustring & n) const { + return (n == id); + } + bool paramRequired() const { + return target->paramRequired(); + } + Glib::ustring name() const { + return id; + } + Glib::ustring description() const { + return desc; + } - const Glib::ustring name; + const Glib::ustring id; const Options::TargetPtr target; const Glib::ustring desc; }; class OptionAlias : public Options::Option { public: - OptionAlias(const Glib::ustring & a, Options::TargetPtr t) : + OptionAlias(const Glib::ustring & a, const NamedOption * t) : alias(a), target(t) { } void consume(const Glib::ustring & a, const Glib::ustring & p, const Glib::ustring & v) const { if (a == alias) { - target->consume(p, v); + target->target->consume(p, v); } } void reset() const { - target->reset(); + target->target->reset(); + } + bool accepts(const Glib::ustring & n) const { + return (n == alias); + } + bool paramRequired() const { + return target->target->paramRequired(); + } + Glib::ustring name() const { + return alias; + } + Glib::ustring description() const { + return "Alias for " + target->name(); } const Glib::ustring alias; - const Options::TargetPtr target; + const NamedOption * target; }; Options::Options(Glib::ustring const&) @@ -60,7 +84,7 @@ Options::operator()(const Glib::ustring & a) { for (OptionList::const_reverse_iterator i = options.rbegin(); i != options.rend(); i++) { if (const NamedOption * no = dynamic_cast<const NamedOption *>(i->get())) { - options.push_back(new OptionAlias(a, no->target)); + options.push_back(new OptionAlias(a, no)); break; } } @@ -89,6 +113,15 @@ Options::consume(const Glib::ustring & n, const Glib::ustring & p, const Glib::u o->consume(n, p, v); } } +const Options::Option * +Options::find(const Glib::ustring & n) const { + BOOST_FOREACH(const OptionPtr & o, options) { + if (o->accepts(n)) { + return o.get(); + } + } + return NULL; +} Options::InstanceTarget::InstanceTarget() : ts(Default) diff --git a/project2/common/options.h b/project2/common/options.h index 77c71b5..207848a 100644 --- a/project2/common/options.h +++ b/project2/common/options.h @@ -16,6 +16,7 @@ class Options { class Target : public IntrusivePtrBase { public: virtual void reset() const = 0; + virtual bool paramRequired() const = 0; virtual void consume(const Glib::ustring & platform, const Glib::ustring & value) const = 0; }; typedef boost::intrusive_ptr<Target> TargetPtr; @@ -23,6 +24,9 @@ class Options { class InstanceTarget : public Target { public: InstanceTarget(); + bool paramRequired() const { + return true; + } void consume(const Glib::ustring & platform, const Glib::ustring & value) const; protected: virtual void assign(const Glib::ustring & value) const = 0; @@ -79,6 +83,10 @@ class Options { class Option : public IntrusivePtrBase { public: virtual void reset() const = 0; + virtual bool paramRequired() const = 0; + virtual Glib::ustring name() const = 0; + virtual Glib::ustring description() const = 0; + virtual bool accepts(const Glib::ustring & name) const = 0; virtual void consume(const Glib::ustring & name, const Glib::ustring & platform, const Glib::ustring & value) const = 0; }; typedef boost::intrusive_ptr<Option> OptionPtr; @@ -101,6 +109,7 @@ class Options { void reset() const; void consume(const Glib::ustring & name, const Glib::ustring & platform, const Glib::ustring & value) const; + const Option * find(const Glib::ustring & name) const; private: typedef std::list<OptionPtr> OptionList; OptionList options; diff --git a/project2/common/optionsSource.h b/project2/common/optionsSource.h index 59d404f..c73a500 100644 --- a/project2/common/optionsSource.h +++ b/project2/common/optionsSource.h @@ -5,8 +5,13 @@ #include <glibmm/ustring.h> #include <intrusivePtrBase.h> #include "scriptLoader.h" +#include "options.h" -typedef boost::function3<void, const Glib::ustring &, const Glib::ustring &, const Glib::ustring &> ConfigConsumer; +class ConfigConsumer { + public: + virtual void operator()(const Glib::ustring &, const Glib::ustring &, const Glib::ustring &) const = 0; + virtual const Options::Option * get(const Glib::ustring & name) const = 0; +}; /// Base class of things that load options class OptionsSource : public IntrusivePtrBase { diff --git a/project2/common/variables-modconfig.cpp b/project2/common/variables-modconfig.cpp index 0dd7feb..3f5e25a 100644 --- a/project2/common/variables-modconfig.cpp +++ b/project2/common/variables-modconfig.cpp @@ -56,6 +56,18 @@ class VariableConfigLoader : public VariableLoaderImpl<VariableConfig> { } } } + bool accepts(const Glib::ustring & n) const { + return (boost::algorithm::starts_with(n, "application.")); + } + bool paramRequired() const { + return true; + } + Glib::ustring name() const { + return "application.*"; + } + Glib::ustring description() const { + return "Load settings into the client application"; + } }; VariableConfigLoader() : opts("Variables - ModConfig options") diff --git a/project2/console/claOptions.cpp b/project2/console/claOptions.cpp index d3f7745..b931392 100644 --- a/project2/console/claOptions.cpp +++ b/project2/console/claOptions.cpp @@ -1,69 +1,78 @@ #include <pch.hpp> +#include <stdio.h> #include <boost/foreach.hpp> #include "../common/optionsSource.h" #include "../common/exceptions.h" #include "consoleEnvironment.h" StaticMessageException(InvalidScriptName, "Script name should be group/name"); +SimpleMessageException(ArgumentRequired); +SimpleMessageException(UnknownOption); class CommandLineArguments : public OptionsSource { public: - typedef std::list<Glib::ustring> optionList; void loadInto(const ConfigConsumer & consume) const { int argc = ConsoleEnvironment::argc; char ** argv = ConsoleEnvironment::argv; bool moreopts = true; - optionList opts, values; for (int x = 1; x < argc; x += 1) { if (moreopts && strcmp(argv[x], "--") == 0) { moreopts = false; } else if (moreopts && strncmp(argv[x], "--", 2) == 0) { - opts.push_back(argv[x] + 2); + Glib::ustring name(argv[x] + 2); + const Options::Option * o = consume.get(name); + if (!o) { + throw UnknownOption(name); + } + if (o->paramRequired()) { + x += 1; + if (x >= argc) { + throw ArgumentRequired(name); + } + consume(name, Environment::getCurrent()->platform(), argv[x]); + } + else { + consume(name, Environment::getCurrent()->platform(), name); + } } else if (moreopts && *(argv[x]) == '-') { - const char * o = argv[x] + 1; - while (*o) { - opts.push_back(Glib::ustring(1, *o)); - o += 1; + const char * n = argv[x] + 1; + while (*n) { + Glib::ustring name(1, *n++); + const Options::Option * o = consume.get(name); + if (!o) { + throw UnknownOption(name); + } + if (o->paramRequired()) { + if (!*n) { + x += 1; + if (x >= argc) { + throw ArgumentRequired(name); + } + consume(name, Environment::getCurrent()->platform(), argv[x]); + } + else { + consume(name, Environment::getCurrent()->platform(), n); + n += 1; + } + } + else { + consume(name, Environment::getCurrent()->platform(), name); + } } } else { - values.push_back(argv[x]); - } - } - - BOOST_FOREACH (const optionList::value_type & i, opts) { - Glib::ustring name, plat; - Glib::ustring::size_type sl = i.find('/'); - if (sl != (Glib::ustring::size_type)-1) { - name = i.substr(0, sl); - plat = i.substr(sl + 1); - } - else { - name = i; - } - if (values.size()) { - consume(name, plat, values.front()); - values.pop_front(); - } - else { - consume(name, plat, Glib::ustring()); - } - } - - BOOST_FOREACH (const optionList::value_type & i, values) { - Glib::ustring group, name; - Glib::ustring::size_type sl = i.find('/'); - if (sl != (Glib::ustring::size_type)-1) { - group = i.substr(0, sl); - name = i.substr(sl + 1); - } - else { - throw InvalidScriptName(); + char * sl = strchr(argv[x], '/'); + if (sl) { + *sl++ = '\0'; + ConsoleEnvironment::todolist.push_back(ConsoleEnvironment::ToDo(argv[x], sl)); + } + else { + throw InvalidScriptName(); + } } - ConsoleEnvironment::todolist.push_back(ConsoleEnvironment::ToDo(group, name)); } } }; diff --git a/project2/console/consoleEnvironment.cpp b/project2/console/consoleEnvironment.cpp index a378fc9..25c2f40 100644 --- a/project2/console/consoleEnvironment.cpp +++ b/project2/console/consoleEnvironment.cpp @@ -29,6 +29,9 @@ operator>>(std::basic_istream<_CharT, _Traits> & s, ConsoleEnvironment::QueryPar class ShowHelpTrigger : public Options::Target { public: void reset() const { } + bool paramRequired() const { + return false; + } void consume(const Glib::ustring &, const Glib::ustring &) const { fprintf(stdout, "Help\n"); exit(1); diff --git a/project2/xml/transformHtml.cpp b/project2/xml/transformHtml.cpp index 6efb7e5..ebde94b 100644 --- a/project2/xml/transformHtml.cpp +++ b/project2/xml/transformHtml.cpp @@ -20,9 +20,9 @@ class TransformXmlToHtml : public TransformImpl<xmlpp::Document, HtmlDocument> { throw xmlpp::exception("Failed to perform transformation"); } } - void configure(const xmlpp::Element * e) + void configure(ScriptNodePtr e) { - stylesheet = e->get_attribute_value("style"); + stylesheet = e->value("style").as<Glib::ustring>(); } private: Glib::ustring stylesheet; |