diff options
author | Eelco Dolstra <edolstra@gmail.com> | 2019-06-18 16:01:35 +0200 |
---|---|---|
committer | Eelco Dolstra <edolstra@gmail.com> | 2019-12-05 20:19:26 +0100 |
commit | ac676856061677559a21670940ac2fac98add9a0 (patch) | |
tree | 0f5444034c6262f8ad92f0fd10c8dcf2b95a8e0c /src/libutil | |
parent | f964f428fe6975e06a273e43c3266928a407454f (diff) |
Make subcommand construction in MultiCommand lazy
(cherry picked from commit a0de58f471c9087d8e6cc60a6078f9940a125b15)
Diffstat (limited to 'src/libutil')
-rw-r--r-- | src/libutil/args.cc | 15 | ||||
-rw-r--r-- | src/libutil/args.hh | 13 |
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; |