Mercurial > irccd
changeset 802:f26bb089232d
irccdctl: fix alias invocations
author | David Demelier <markand@malikania.fr> |
---|---|
date | Mon, 12 Nov 2018 21:42:23 +0100 |
parents | fe27ed0c1eae |
children | 14f9e3b03779 |
files | irccdctl/cli.cpp irccdctl/main.cpp libirccd-ctl/irccd/ctl/controller.cpp libirccd-ctl/irccd/ctl/controller.hpp libirccd-test/irccd/test/command_fixture.cpp |
diffstat | 5 files changed, 56 insertions(+), 42 deletions(-) [+] |
line wrap: on
line diff
--- a/irccdctl/cli.cpp Mon Nov 12 21:47:00 2018 +0100 +++ b/irccdctl/cli.cpp Mon Nov 12 21:42:23 2018 +0100 @@ -187,7 +187,7 @@ void get_event(ctl::controller& ctl, std::string fmt) { - ctl.read([&ctl, fmt] (auto code, auto message) { + ctl.recv([&ctl, fmt] (auto code, auto message) { if (code) throw std::system_error(code); @@ -268,25 +268,22 @@ void cli::recv_response(ctl::controller& ctl, nlohmann::json req, handler_t handler) { - ctl.read([&ctl, req, handler, this] (auto code, auto message) { + ctl.recv([&ctl, req, handler, this] (auto code, auto message) { if (code) throw std::system_error(code); const auto c = deserializer(message).get<std::string>("command"); - if (!c) { + if (!c) recv_response(ctl, std::move(req), std::move(handler)); - return; - } - - if (handler) + else if (handler) handler(std::move(message)); }); } void cli::request(ctl::controller& ctl, nlohmann::json req, handler_t handler) { - ctl.write(req, [&ctl, req, handler, this] (auto code) { + ctl.send(req, [&ctl, req, handler, this] (auto code) { if (code) throw std::system_error(code);
--- a/irccdctl/main.cpp Mon Nov 12 21:47:00 2018 +0100 +++ b/irccdctl/main.cpp Mon Nov 12 21:42:23 2018 +0100 @@ -59,6 +59,9 @@ std::unordered_map<std::string, alias> aliases; std::unordered_map<std::string, std::unique_ptr<cli>> commands; +// Vector of commands to execute. +std::vector<std::function<void ()>> requests; + /* * Configuration file parsing. * ------------------------------------------------------------------- @@ -389,9 +392,9 @@ return result; } -void exec(std::vector<std::string>); +void enqueue(std::vector<std::string>); -void exec(const alias& alias, std::vector<std::string> args_copy) +void enqueue(const alias& alias, std::vector<std::string> args_copy) { for (const auto& cmd : alias) { std::vector<std::string> args(args_copy); @@ -424,11 +427,11 @@ std::copy(args.begin(), args.end(), std::back_inserter(cmd_args)); // 4. Finally try to execute. - exec(cmd_args); + enqueue(cmd_args); } } -void exec(std::vector<std::string> args) +void enqueue(std::vector<std::string> args) { assert(args.size() > 0); @@ -438,16 +441,19 @@ // Remove name. args.erase(args.begin()); - if (alias != aliases.end()) - exec(alias->second, args); - else { - auto cmd = commands.find(name); + if (alias != aliases.end()) { + enqueue(alias->second, args); + return; + } + + const auto cmd = commands.find(name); - if (cmd != commands.end()) + if (cmd != commands.end()) + requests.push_back([args, cmd] () { cmd->second->exec(*ctl, args); - else - throw std::invalid_argument("no alias or command named " + name); - } + }); + else + throw std::invalid_argument("no alias or command named " + name); } void init(int &argc, char **&argv) @@ -497,8 +503,13 @@ for (int i = 0; i < argc; ++i) args.push_back(argv[i]); - exec(args); - service.run(); + enqueue(args); + + for (const auto& req : requests) { + req(); + service.run(); + service.reset(); + } } } // !namespace @@ -510,7 +521,7 @@ irccd::ctl::init(argc, argv); // 1. Read command line arguments. - auto result = irccd::ctl::parse(argc, argv); + const auto result = irccd::ctl::parse(argc, argv); /* * 2. Open optional config by command line or by searching it
--- a/libirccd-ctl/irccd/ctl/controller.cpp Mon Nov 12 21:47:00 2018 +0100 +++ b/libirccd-ctl/irccd/ctl/controller.cpp Mon Nov 12 21:42:23 2018 +0100 @@ -39,13 +39,13 @@ { "password", password_ } }); - write(cmd, [handler, info, this] (auto code) { + send(cmd, [handler, info, this] (auto code) { if (code) { handler(std::move(code), nullptr); return; } - read([handler, info] (auto code, auto) { + recv([handler, info] (auto code, auto) { handler(std::move(code), std::move(info)); }); }); @@ -53,7 +53,7 @@ void controller::verify(connect_handler handler) { - read([handler, this] (auto code, auto message) { + recv([handler, this] (auto code, auto message) { if (code) { handler(std::move(code), std::move(message)); return; @@ -106,10 +106,10 @@ }); } -void controller::read(stream::recv_handler handler) +void controller::recv(stream::recv_handler handler) { + assert(stream_); assert(handler); - assert(stream_); auto stream = stream_; @@ -139,10 +139,11 @@ }); } -void controller::write(nlohmann::json message, stream::send_handler handler) +void controller::send(nlohmann::json message, stream::send_handler handler) { + assert(stream_); assert(message.is_object()); - assert(stream_); + assert(handler); auto stream = stream_;
--- a/libirccd-ctl/irccd/ctl/controller.hpp Mon Nov 12 21:47:00 2018 +0100 +++ b/libirccd-ctl/irccd/ctl/controller.hpp Mon Nov 12 21:42:23 2018 +0100 @@ -48,9 +48,9 @@ /** * Connection completion handler. * - * This callback is called when connection has been completed or failed. In - * both case, the error code is set and the JSON object may contain the - * irccd program information. + * This callback is called when connection has been completed or failed. + * In both case, the error code is set and the JSON object may contain + * the * irccd program information. */ using connect_handler = std::function<void (std::error_code, nlohmann::json)>; @@ -92,29 +92,31 @@ /** * Attempt to connect to the irccd daemon. * + * \pre another connect operation must not be running * \pre handler != nullptr * \param handler the handler */ void connect(connect_handler handler); /** - * Queue a receive operation, if receive operations are already running, - * it is queued and ran once ready. + * Request a message. * + * \pre another recv operation must not be running * \pre handler != nullptr * \param handler the recv handler */ - void read(stream::recv_handler handler); + void recv(stream::recv_handler handler); /** - * Queue a send operation, if receive operations are already running, it - * is queued and ran once ready. + * Send a message. * + * \pre another send operation must not be running * \pre message.is_object() + * \pre handler != nullptr * \param message the JSON message * \param handler the optional completion handler */ - void write(nlohmann::json message, stream::send_handler handler = nullptr); + void send(nlohmann::json message, stream::send_handler handler); }; } // !irccd::ctl
--- a/libirccd-test/irccd/test/command_fixture.cpp Mon Nov 12 21:47:00 2018 +0100 +++ b/libirccd-test/irccd/test/command_fixture.cpp Mon Nov 12 21:42:23 2018 +0100 @@ -42,10 +42,13 @@ { result r; - ctl_->write(std::move(json)); - ctl_->read([&] (auto result, auto message) { + ctl_->send(std::move(json), [] (auto code) { + if (code) + throw std::system_error(std::move(code)); + }); + ctl_->recv([&] (auto code, auto message) { r.first = message; - r.second = result; + r.second = code; }); wait_for([&] { return r.second || r.first.is_object();