summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrandomdan <randomdan@localhost>2011-12-16 19:44:00 +0000
committerrandomdan <randomdan@localhost>2011-12-16 19:44:00 +0000
commit6d0464b7c44084a7a9f28f3becc5f1585b697bf0 (patch)
tree05af7babef544e4832c293d149aa7a33e3181b03
parentRemove straggling references to XML and configuration from recent changes (diff)
downloadproject2-6d0464b7c44084a7a9f28f3becc5f1585b697bf0.tar.bz2
project2-6d0464b7c44084a7a9f28f3becc5f1585b697bf0.tar.xz
project2-6d0464b7c44084a7a9f28f3becc5f1585b697bf0.zip
Improvements to the handling of command line arguments
-rw-r--r--project2/cgi/cgiEnvironment.cpp6
-rw-r--r--project2/cgi/cgiEnvironment.h1
-rw-r--r--project2/cgi/testCgi.cpp16
-rw-r--r--project2/common/environment.cpp38
-rw-r--r--project2/common/options.cpp49
-rw-r--r--project2/common/options.h9
-rw-r--r--project2/common/optionsSource.h7
-rw-r--r--project2/common/variables-modconfig.cpp12
-rw-r--r--project2/console/claOptions.cpp89
-rw-r--r--project2/console/consoleEnvironment.cpp3
-rw-r--r--project2/xml/transformHtml.cpp4
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;