aboutsummaryrefslogtreecommitdiff
path: root/src/libutil
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2019-06-18 16:01:35 +0200
committerEelco Dolstra <edolstra@gmail.com>2019-12-05 20:19:26 +0100
commitac676856061677559a21670940ac2fac98add9a0 (patch)
tree0f5444034c6262f8ad92f0fd10c8dcf2b95a8e0c /src/libutil
parentf964f428fe6975e06a273e43c3266928a407454f (diff)
Make subcommand construction in MultiCommand lazy
(cherry picked from commit a0de58f471c9087d8e6cc60a6078f9940a125b15)
Diffstat (limited to 'src/libutil')
-rw-r--r--src/libutil/args.cc15
-rw-r--r--src/libutil/args.hh13
2 files changed, 17 insertions, 11 deletions
diff --git a/src/libutil/args.cc b/src/libutil/args.cc
index 2837dacc9..217495c26 100644
--- a/src/libutil/args.cc
+++ b/src/libutil/args.cc
@@ -215,17 +215,15 @@ void Command::printHelp(const string & programName, std::ostream & out)
}
}
-MultiCommand::MultiCommand(const std::vector<ref<Command>> & _commands)
+MultiCommand::MultiCommand(const Commands & commands)
+ : commands(commands)
{
- for (auto & command : _commands)
- commands.emplace(command->name(), command);
-
expectedArgs.push_back(ExpectedArg{"command", 1, true, [=](std::vector<std::string> ss) {
assert(!command);
auto i = commands.find(ss[0]);
if (i == commands.end())
throw UsageError("'%s' is not a recognised command", ss[0]);
- command = i->second;
+ command = i->second();
}});
}
@@ -246,10 +244,11 @@ void MultiCommand::printHelp(const string & programName, std::ostream & out)
out << "Available commands:\n";
Table2 table;
- for (auto & command : commands) {
- auto descr = command.second->description();
+ for (auto & i : commands) {
+ auto command = i.second();
+ auto descr = command->description();
if (!descr.empty())
- table.push_back(std::make_pair(command.second->name(), descr));
+ table.push_back(std::make_pair(command->name(), descr));
}
printTable(out, table);
}
diff --git a/src/libutil/args.hh b/src/libutil/args.hh
index 21f4327c5..54336b17b 100644
--- a/src/libutil/args.hh
+++ b/src/libutil/args.hh
@@ -192,8 +192,15 @@ public:
run() method. */
struct Command : virtual Args
{
+private:
+ std::string _name;
+
+public:
+
virtual ~Command() { }
- virtual std::string name() = 0;
+
+ std::string name() { return _name; }
+
virtual void prepare() { };
virtual void run() = 0;
@@ -210,7 +217,7 @@ struct Command : virtual Args
void printHelp(const string & programName, std::ostream & out) override;
};
-typedef std::map<std::string, ref<Command>> Commands;
+typedef std::map<std::string, std::function<ref<Command>()>> Commands;
/* An argument parser that supports multiple subcommands,
i.e. ‘<command> <subcommand>’. */
@@ -221,7 +228,7 @@ public:
std::shared_ptr<Command> command;
- MultiCommand(const std::vector<ref<Command>> & commands);
+ MultiCommand(const Commands & commands);
void printHelp(const string & programName, std::ostream & out) override;