Mercurial > irccd
changeset 488:7e273b7f4f92
Irccd: new coding style, closes #576
line wrap: on
line diff
--- a/irccd/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/irccd/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -44,18 +44,18 @@ #include "irccd.hpp" #if defined(WITH_JS) -# include "mod-directory.hpp" -# include "mod-elapsed-timer.hpp" -# include "mod-file.hpp" -# include "mod-irccd.hpp" -# include "mod-logger.hpp" -# include "mod-plugin.hpp" -# include "mod-server.hpp" -# include "mod-system.hpp" -# include "mod-timer.hpp" -# include "mod-unicode.hpp" -# include "mod-util.hpp" -# include "plugin-js.hpp" +# include <js_directory_module.hpp> +# include <js_elapsed_timer_module.hpp> +# include <js_file_module.hpp> +# include <js_irccd_module.hpp> +# include <js_logger_module.hpp> +# include <js_plugin_module.hpp> +# include <js_server_module.hpp> +# include <js_system_module.hpp> +# include <js_timer_module.hpp> +# include <js_unicode_module.hpp> +# include <js_util_module.hpp> +# include "js_plugin.hpp" #endif using namespace fmt::literals; @@ -64,11 +64,11 @@ namespace { -std::unique_ptr<Irccd> instance; +std::unique_ptr<irccd::irccd> instance; void usage() { - std::cerr << "usage: " << sys::programName() << " [options...]\n\n"; + std::cerr << "usage: " << sys::program_name() << " [options...]\n\n"; std::cerr << "Available options:\n"; std::cerr << " -c, --config file specify the configuration file\n"; std::cerr << " -f, --foreground do not run as a daemon\n"; @@ -78,7 +78,7 @@ std::exit(1); } -void version(const option::Result &options) +void version(const option::Result& options) { std::cout << IRCCD_VERSION << std::endl; @@ -106,13 +106,13 @@ instance->stop(); } -void init(int &argc, char **&argv) +void init(int& argc, char**& argv) { // Needed for some components. - sys::setProgramName("irccd"); + sys::set_program_name("irccd"); // Default logging to console. - log::setVerbose(false); + log::set_verbose(false); // Register some signals. signal(SIGINT, stop); @@ -130,7 +130,7 @@ ++ argv; } -option::Result parse(int &argc, char **&argv) +option::Result parse(int& argc, char**& argv) { // Parse command line options. option::Result result; @@ -150,7 +150,7 @@ result = option::read(argc, argv, options); - for (const auto &pair : result) { + for (const auto& pair : result) { if (pair.first == "-h" || pair.first == "--help") usage(); // NOTREACHED @@ -158,32 +158,32 @@ version(result); // NOTREACHED if (pair.first == "-v" || pair.first == "--verbose") - log::setVerbose(true); + log::set_verbose(true); } - } catch (const std::exception &ex) { - log::warning() << sys::programName() << ": " << ex.what() << std::endl; + } catch (const std::exception& ex) { + log::warning() << sys::program_name() << ": " << ex.what() << std::endl; usage(); } return result; } -Config open(const option::Result &result) +config open(const option::Result& result) { auto it = result.find("-c"); if (it != result.end() || (it = result.find("--config")) != result.end()) { try { - return Config(it->second); + return config(it->second); } catch (const std::exception &ex) { throw std::runtime_error("{}: {}"_format(it->second, ex.what())); } } - return Config::find(); + return config::find(); } -void loadPid(const std::string &path) +void load_pid(const std::string& path) { if (path.empty()) return; @@ -200,12 +200,12 @@ #else throw std::runtime_error("pidfile option not supported on this platform"); #endif - } catch (const std::exception &ex) { + } catch (const std::exception& ex) { log::warning() << "irccd: " << ex.what() << std::endl; } } -void loadGid(const std::string gid) +void load_gid(const std::string& gid) { try { if (!gid.empty()) @@ -214,12 +214,12 @@ #else throw std::runtime_error(" gid option not supported on this platform"); #endif - } catch (const std::exception &ex) { + } catch (const std::exception& ex) { log::warning() << "irccd: " << ex.what() << std::endl; } } -void loadUid(const std::string &uid) +void load_uid(const std::string& uid) { try { if (!uid.empty()) @@ -228,12 +228,12 @@ #else throw std::runtime_error("uid option not supported on this platform"); #endif - } catch (const std::exception &ex) { + } catch (const std::exception& ex) { log::warning() << "irccd: " << ex.what() << std::endl; } } -void loadForeground(bool foreground, const option::Result &options) +void load_foreground(bool foreground, const option::Result& options) { try { #if defined(HAVE_DAEMON) @@ -243,12 +243,12 @@ if (options.count("-f") > 0 || options.count("--foreground") > 0 || foreground) throw std::runtime_error("foreground option not supported on this platform"); #endif - } catch (const std::exception &ex) { + } catch (const std::exception& ex) { log::warning() << "irccd: " << ex.what() << std::endl; } } -void load(const Config &config, const option::Result &options) +void load(const config& config, const option::Result& options) { /* * Order matters, please be careful when changing this. @@ -258,95 +258,95 @@ */ // [logs] and [format] sections. - config.loadLogs(); - config.loadFormats(); + config.load_logs(); + config.load_formats(); // Show message here to use the formats. log::info() << "irccd: using " << config.path() << std::endl; // [general] section. - loadPid(config.pidfile()); - loadGid(config.gid()); - loadUid(config.uid()); - loadForeground(config.isForeground(), options); + load_pid(config.pidfile()); + load_gid(config.gid()); + load_uid(config.uid()); + load_foreground(config.is_foreground(), options); // [transport] - for (const auto &transport : config.loadTransports()) + for (const auto& transport : config.load_transports()) instance->transports().add(transport); // [server] section. - for (const auto &server : config.loadServers()) + for (const auto& server : config.load_servers()) instance->servers().add(server); // [rule] section. - for (const auto &rule : config.loadRules()) + for (const auto& rule : config.load_rules()) instance->rules().add(rule); // [plugin] section. - config.loadPlugins(*instance); + config.load_plugins(*instance); } } // !namespace -int main(int argc, char **argv) +int main(int argc, char** argv) { init(argc, argv); option::Result options = parse(argc, argv); - instance = std::make_unique<Irccd>(); - instance->commands().add(std::make_unique<command::PluginConfigCommand>()); - instance->commands().add(std::make_unique<command::PluginInfoCommand>()); - instance->commands().add(std::make_unique<command::PluginListCommand>()); - instance->commands().add(std::make_unique<command::PluginLoadCommand>()); - instance->commands().add(std::make_unique<command::PluginReloadCommand>()); - instance->commands().add(std::make_unique<command::PluginUnloadCommand>()); - instance->commands().add(std::make_unique<command::ServerChannelModeCommand>()); - instance->commands().add(std::make_unique<command::ServerChannelNoticeCommand>()); - instance->commands().add(std::make_unique<command::ServerConnectCommand>()); - instance->commands().add(std::make_unique<command::ServerDisconnectCommand>()); - instance->commands().add(std::make_unique<command::ServerInfoCommand>()); - instance->commands().add(std::make_unique<command::ServerInviteCommand>()); - instance->commands().add(std::make_unique<command::ServerJoinCommand>()); - instance->commands().add(std::make_unique<command::ServerKickCommand>()); - instance->commands().add(std::make_unique<command::ServerListCommand>()); - instance->commands().add(std::make_unique<command::ServerMeCommand>()); - instance->commands().add(std::make_unique<command::ServerMessageCommand>()); - instance->commands().add(std::make_unique<command::ServerModeCommand>()); - instance->commands().add(std::make_unique<command::ServerNickCommand>()); - instance->commands().add(std::make_unique<command::ServerNoticeCommand>()); - instance->commands().add(std::make_unique<command::ServerPartCommand>()); - instance->commands().add(std::make_unique<command::ServerReconnectCommand>()); - instance->commands().add(std::make_unique<command::ServerTopicCommand>()); - instance->commands().add(std::make_unique<command::RuleAddCommand>()); - instance->commands().add(std::make_unique<command::RuleEditCommand>()); - instance->commands().add(std::make_unique<command::RuleInfoCommand>()); - instance->commands().add(std::make_unique<command::RuleListCommand>()); - instance->commands().add(std::make_unique<command::RuleMoveCommand>()); - instance->commands().add(std::make_unique<command::RuleRemoveCommand>()); + instance = std::make_unique<irccd::irccd>(); + instance->commands().add(std::make_unique<plugin_config_command>()); + instance->commands().add(std::make_unique<plugin_info_command>()); + instance->commands().add(std::make_unique<plugin_list_command>()); + instance->commands().add(std::make_unique<plugin_load_command>()); + instance->commands().add(std::make_unique<plugin_reload_command>()); + instance->commands().add(std::make_unique<plugin_unload_command>()); + instance->commands().add(std::make_unique<server_channel_mode_command>()); + instance->commands().add(std::make_unique<server_channel_notice_command>()); + instance->commands().add(std::make_unique<server_connect_command>()); + instance->commands().add(std::make_unique<server_disconnect_command>()); + instance->commands().add(std::make_unique<server_info_command>()); + instance->commands().add(std::make_unique<server_invite_command>()); + instance->commands().add(std::make_unique<server_join_command>()); + instance->commands().add(std::make_unique<server_kick_command>()); + instance->commands().add(std::make_unique<server_list_command>()); + instance->commands().add(std::make_unique<server_me_command>()); + instance->commands().add(std::make_unique<server_message_command>()); + instance->commands().add(std::make_unique<server_mode_command>()); + instance->commands().add(std::make_unique<server_nick_command>()); + instance->commands().add(std::make_unique<server_notice_command>()); + instance->commands().add(std::make_unique<server_part_command>()); + instance->commands().add(std::make_unique<server_reconnect_command>()); + instance->commands().add(std::make_unique<server_topic_command>()); + instance->commands().add(std::make_unique<rule_add_command>()); + instance->commands().add(std::make_unique<rule_edit_command>()); + instance->commands().add(std::make_unique<rule_info_command>()); + instance->commands().add(std::make_unique<rule_list_command>()); + instance->commands().add(std::make_unique<rule_move_command>()); + instance->commands().add(std::make_unique<rule_remove_command>()); // Load Javascript API and plugin loader. #if defined(WITH_JS) - auto loader = std::make_unique<JsPluginLoader>(*instance); + auto loader = std::make_unique<js_plugin_loader>(*instance); - loader->addModule(std::make_unique<IrccdModule>()); - loader->addModule(std::make_unique<DirectoryModule>()); - loader->addModule(std::make_unique<ElapsedTimerModule>()); - loader->addModule(std::make_unique<FileModule>()); - loader->addModule(std::make_unique<LoggerModule>()); - loader->addModule(std::make_unique<PluginModule>()); - loader->addModule(std::make_unique<ServerModule>()); - loader->addModule(std::make_unique<SystemModule>()); - loader->addModule(std::make_unique<TimerModule>()); - loader->addModule(std::make_unique<UnicodeModule>()); - loader->addModule(std::make_unique<UtilModule>()); + loader->add_module(std::make_unique<js_irccd_module>()); + loader->add_module(std::make_unique<js_directory_module>()); + loader->add_module(std::make_unique<js_elapsed_timer_module>()); + loader->add_module(std::make_unique<js_file_module>()); + loader->add_module(std::make_unique<js_logger_module>()); + loader->add_module(std::make_unique<js_plugin_module>()); + loader->add_module(std::make_unique<js_server_module>()); + loader->add_module(std::make_unique<js_system_module>()); + loader->add_module(std::make_unique<js_timer_module>()); + loader->add_module(std::make_unique<js_unicode_module>()); + loader->add_module(std::make_unique<js_util_module>()); instance->plugins().addLoader(std::move(loader)); #endif try { load(open(options), options); - } catch (const std::exception &ex) { + } catch (const std::exception& ex) { log::warning() << "error: " << ex.what() << std::endl; return 1; }
--- a/irccdctl/cli.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/irccdctl/cli.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -40,8 +40,8 @@ void Cli::check(const nlohmann::json &response) { - if (!util::json::getBool(response, "status", false)) { - auto error = util::json::getString(response, "error"); + if (!util::json::get_bool(response, "status", false)) { + auto error = util::json::get_string(response, "error"); if (error.empty()) throw std::runtime_error("command failed with an unknown error"); @@ -78,7 +78,7 @@ if (!msg.is_object()) throw std::runtime_error("no response received"); - if (util::json::getString(msg, "command") != m_name) + if (util::json::get_string(msg, "command") != m_name) throw std::runtime_error("unexpected command result received"); check(msg); @@ -187,10 +187,10 @@ auto result = request(irccdctl, {{ "plugin", args[0] }}); std::cout << std::boolalpha; - std::cout << "Author : " << util::json::getString(result, "author") << std::endl; - std::cout << "License : " << util::json::getString(result, "license") << std::endl; - std::cout << "Summary : " << util::json::getString(result, "summary") << std::endl; - std::cout << "Version : " << util::json::getString(result, "version") << std::endl; + std::cout << "Author : " << util::json::get_string(result, "author") << std::endl; + std::cout << "License : " << util::json::get_string(result, "license") << std::endl; + std::cout << "Summary : " << util::json::get_string(result, "summary") << std::endl; + std::cout << "Version : " << util::json::get_string(result, "version") << std::endl; } /* @@ -407,7 +407,7 @@ }); if (copy.size() == 3) { - if (!util::isNumber(copy[2])) + if (!util::is_int(copy[2])) throw std::invalid_argument("invalid port number"); object["port"] = std::stoi(copy[2]); @@ -909,9 +909,9 @@ // Index. if (result.count("-i") > 0) - json["index"] = util::toNumber<unsigned>(result.find("-i")->second); + json["index"] = util::to_number<unsigned>(result.find("-i")->second); if (result.count("--index") > 0) - json["index"] = util::toNumber<unsigned>(result.find("--index")->second); + json["index"] = util::to_number<unsigned>(result.find("--index")->second); // And action. if (copy[0] != "accept" && copy[0] != "drop") @@ -1013,7 +1013,7 @@ } // Index. - json["index"] = util::toNumber<unsigned>(copy[0]); + json["index"] = util::to_number<unsigned>(copy[0]); check(request(irccdctl, json)); }
--- a/irccdctl/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/irccdctl/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -51,7 +51,7 @@ bool first = true; for (const auto &cmd : commands) { - log::warning() << (first ? "usage: " : " ") << sys::programName() << " " + log::warning() << (first ? "usage: " : " ") << sys::program_name() << " " << cmd->usage() << std::endl; first = false; } @@ -61,7 +61,7 @@ void help() { - log::warning() << "usage: " << sys::programName() << " [options...] <command> [command-options...] [command-args...]\n\n"; + log::warning() << "usage: " << sys::program_name() << " [options...] <command> [command-options...] [command-args...]\n\n"; log::warning() << "General options:\n"; log::warning() << "\t-c, --config file\tspecify the configuration file\n"; log::warning() << "\t --help\t\tshow this help\n"; @@ -78,7 +78,7 @@ log::warning() << "\t" << std::left << std::setw(32) << cmd->name() << cmd->summary() << std::endl; - log::warning() << "\nFor more information on a command, type " << sys::programName() << " help <command>" << std::endl; + log::warning() << "\nFor more information on a command, type " << sys::program_name() << " help <command>" << std::endl; std::exit(1); } @@ -91,7 +91,7 @@ if (it == commands.end()) { log::warning() << "no command named " << command << std::endl; } else { - log::warning() << "usage: " << sys::programName() << " " << (*it)->usage() << "\n" << std::endl; + log::warning() << "usage: " << sys::program_name() << " " << (*it)->usage() << "\n" << std::endl; log::warning() << (*it)->help() << std::endl; } @@ -116,9 +116,9 @@ * domain = "ipv4 or ipv6" (Optional, default: ipv4) * ssl = true | false */ -void readConnectIp(const ini::Section &sc) +void readConnectIp(const ini::section &sc) { - ini::Section::const_iterator it; + ini::section::const_iterator it; std::string host, port; if ((it = sc.find("host")) == sc.end()) @@ -145,7 +145,7 @@ address = net::resolveOne(host, port, domain, SOCK_STREAM); - if ((it = sc.find("ssl")) != sc.end() && util::isBoolean(it->value())) + if ((it = sc.find("ssl")) != sc.end() && util::is_boolean(it->value())) #if defined(WITH_SSL) client = std::make_unique<TlsClient>(); #else @@ -165,7 +165,7 @@ * type = "unix" * path = "path to socket file" */ -void readConnectLocal(const ini::Section &sc) +void readConnectLocal(const ini::section &sc) { #if !defined(IRCCD_SYSTEM_WINDOWS) auto it = sc.find("path"); @@ -188,7 +188,7 @@ * * Generic function for reading the [connect] section. */ -void readConnect(const ini::Section &sc) +void readConnect(const ini::section &sc) { auto it = sc.find("type"); @@ -218,12 +218,12 @@ * [general] * verbose = true */ -void readGeneral(const ini::Section &sc) +void readGeneral(const ini::section &sc) { auto verbose = sc.find("verbose"); if (verbose != sc.end()) - log::setVerbose(util::isBoolean(verbose->value())); + log::set_verbose(util::is_boolean(verbose->value())); } /* @@ -236,7 +236,7 @@ * cmd1 = ( "command", "arg1, "...", "argn" ) * cmd2 = ( "command", "arg1, "...", "argn" ) */ -Alias readAlias(const ini::Section &sc, const std::string &name) +Alias readAlias(const ini::section &sc, const std::string &name) { Alias alias(name); @@ -265,8 +265,8 @@ void read(const std::string &path) { try { - ini::Document doc = ini::readFile(path); - ini::Document::const_iterator it; + ini::document doc = ini::read_file(path); + ini::document::const_iterator it; if (!client && (it = doc.find("connect")) != doc.end()) readConnect(*it); @@ -414,10 +414,10 @@ } if (result.count("-v") != 0 || result.count("--verbose") != 0) { - log::setVerbose(true); + log::set_verbose(true); } } catch (const std::exception &ex) { - log::warning("{}: {}"_format(sys::programName(), ex.what())); + log::warning("{}: {}"_format(sys::program_name(), ex.what())); usage(); } @@ -494,7 +494,7 @@ void init(int &argc, char **&argv) { - sys::setProgramName("irccdctl"); + sys::set_program_name("irccdctl"); net::init(); --argc; @@ -569,7 +569,7 @@ } } } catch (const std::exception &ex) { - log::warning() << sys::programName() << ": " << ex.what() << std::endl; + log::warning() << sys::program_name() << ": " << ex.what() << std::endl; std::exit(1); } @@ -586,7 +586,7 @@ } if (!client) { - log::warning("{}: no connection specified"_format(sys::programName())); + log::warning("{}: no connection specified"_format(sys::program_name())); std::exit(1); } @@ -611,6 +611,6 @@ try { exec(args); } catch (const std::exception &ex) { - std::cerr << sys::programName() << ": unrecoverable error: " << ex.what() << std::endl; + std::cerr << sys::program_name() << ": unrecoverable error: " << ex.what() << std::endl; } }
--- a/libcommon/irccd/ini.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/libcommon/irccd/ini.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -26,25 +26,21 @@ // for PathIsRelative. #if defined(_WIN32) -# if !defined(WIN32_LEAN_AND_MEAN) -# define WIN32_LEAN_AND_MEAN -# endif - -# include <shlwapi.h> +# include <Shlwapi.h> #endif #include "ini.hpp" namespace irccd { +namespace ini { + namespace { -using namespace ini; +using stream_iterator = std::istreambuf_iterator<char>; +using token_iterator = std::vector<token>::const_iterator; -using StreamIterator = std::istreambuf_iterator<char>; -using TokenIterator = std::vector<Token>::const_iterator; - -inline bool isAbsolute(const std::string &path) noexcept +inline bool is_absolute(const std::string& path) noexcept { #if defined(_WIN32) return !PathIsRelative(path.c_str()); @@ -53,28 +49,28 @@ #endif } -inline bool isQuote(char c) noexcept +inline bool is_quote(char c) noexcept { return c == '\'' || c == '"'; } -inline bool isSpace(char c) noexcept +inline bool is_space(char c) noexcept { // Custom version because std::isspace includes \n as space. return c == ' ' || c == '\t'; } -inline bool isList(char c) noexcept +inline bool is_list(char c) noexcept { return c == '(' || c == ')' || c == ','; } -inline bool isReserved(char c) noexcept +inline bool is_reserved(char c) noexcept { - return isList(c) || isQuote(c) || c == '[' || c == ']' || c == '@' || c == '#' || c == '='; + return is_list(c) || is_quote(c) || c == '[' || c == ']' || c == '@' || c == '#' || c == '='; } -void analyseLine(int &line, int &column, StreamIterator &it) noexcept +void analyse_line(int& line, int& column, stream_iterator& it) noexcept { assert(*it == '\n'); @@ -83,7 +79,7 @@ column = 0; } -void analyseComment(int &column, StreamIterator &it, StreamIterator end) noexcept +void analyse_comment(int& column, stream_iterator& it, stream_iterator end) noexcept { assert(*it == '#'); @@ -93,36 +89,36 @@ } } -void analyseSpaces(int &column, StreamIterator &it, StreamIterator end) noexcept +void analyse_spaces(int& column, stream_iterator& it, stream_iterator end) noexcept { - assert(isSpace(*it)); + assert(is_space(*it)); - while (it != end && isSpace(*it)) { + while (it != end && is_space(*it)) { ++ column; ++ it; } } -void analyseList(Tokens &list, int line, int &column, StreamIterator &it) noexcept +void analyse_list(tokens& list, int line, int& column, stream_iterator& it) noexcept { - assert(isList(*it)); + assert(is_list(*it)); switch (*it++) { case '(': - list.emplace_back(Token::ListBegin, line, column++); + list.emplace_back(token::list_begin, line, column++); break; case ')': - list.emplace_back(Token::ListEnd, line, column++); + list.emplace_back(token::list_end, line, column++); break; case ',': - list.emplace_back(Token::Comma, line, column++); + list.emplace_back(token::comma, line, column++); break; default: break; } } -void analyseSection(Tokens &list, int &line, int &column, StreamIterator &it, StreamIterator end) +void analyse_section(tokens& list, int& line, int& column, stream_iterator& it, stream_iterator end) { assert(*it == '['); @@ -132,35 +128,39 @@ // Read section name. ++ it; while (it != end && *it != ']') { - if (*it == '\n') - throw Error(line, column, "section not terminated, missing ']'"); - if (isReserved(*it)) - throw Error(line, column, "section name expected after '[', got '" + std::string(1, *it) + "'"); + if (*it == '\n') { + throw exception(line, column, "section not terminated, missing ']'"); + } + if (is_reserved(*it)) { + throw exception(line, column, "section name expected after '[', got '" + std::string(1, *it) + "'"); + } ++ column; value += *it++; } - if (it == end) - throw Error(line, column, "section name expected after '[', got <EOF>"); - if (value.empty()) - throw Error(line, column, "empty section name"); + if (it == end) { + throw exception(line, column, "section name expected after '[', got <EOF>"); + } + if (value.empty()) { + throw exception(line, column, "empty section name"); + } // Remove ']'. ++ it; - list.emplace_back(Token::Section, line, save, std::move(value)); + list.emplace_back(token::section, line, save, std::move(value)); } -void analyseAssign(Tokens &list, int &line, int &column, StreamIterator &it) +void analyse_assign(tokens& list, int& line, int& column, stream_iterator& it) { assert(*it == '='); - list.push_back({ Token::Assign, line, column++ }); + list.push_back({ token::assign, line, column++ }); ++ it; } -void analyseQuotedWord(Tokens &list, int &line, int &column, StreamIterator &it, StreamIterator end) +void analyse_quoted_word(tokens& list, int& line, int& column, stream_iterator& it, stream_iterator end) { std::string value; int save = column; @@ -172,31 +172,32 @@ value += *it++; } - if (it == end) - throw Error(line, column, "undisclosed '" + std::string(1, quote) + "', got <EOF>"); + if (it == end) { + throw exception(line, column, "undisclosed '" + std::string(1, quote) + "', got <EOF>"); + } // Remove quote. ++ it; - list.push_back({ Token::QuotedWord, line, save, std::move(value) }); + list.push_back({ token::quoted_word, line, save, std::move(value) }); } -void analyseWord(Tokens &list, int &line, int &column, StreamIterator &it, StreamIterator end) +void analyse_word(tokens& list, int& line, int& column, stream_iterator& it, stream_iterator end) { - assert(!isReserved(*it)); + assert(!is_reserved(*it)); std::string value; int save = column; - while (it != end && !std::isspace(*it) && !isReserved(*it)) { + while (it != end && !std::isspace(*it) && !is_reserved(*it)) { ++ column; value += *it++; } - list.push_back({ Token::Word, line, save, std::move(value) }); + list.push_back({ token::word, line, save, std::move(value) }); } -void analyseInclude(Tokens &list, int &line, int &column, StreamIterator &it, StreamIterator end) +void analyse_include(tokens& list, int& line, int& column, stream_iterator& it, stream_iterator end) { assert(*it == '@'); @@ -205,117 +206,127 @@ // Read include. ++ it; - while (it != end && !isSpace(*it)) { + while (it != end && !is_space(*it)) { ++ column; include += *it++; } - if (include != "include") - throw Error(line, column, "expected include after '@' token"); + if (include != "include") { + throw exception(line, column, "expected include after '@' token"); + } - list.push_back({ Token::Include, line, save }); + list.push_back({ token::include, line, save }); } -void parseOptionValueSimple(Option &option, TokenIterator &it) +void parse_option_value_simple(option& option, token_iterator& it) { - assert(it->type() == Token::Word || it->type() == Token::QuotedWord); + assert(it->type() == token::word || it->type() == token::quoted_word); option.push_back((it++)->value()); } -void parseOptionValueList(Option &option, TokenIterator &it, TokenIterator end) +void parse_option_value_list(option& option, token_iterator& it, token_iterator end) { - assert(it->type() == Token::ListBegin); + assert(it->type() == token::list_begin); - TokenIterator save = it++; + token_iterator save = it++; - while (it != end && it->type() != Token::ListEnd) { + while (it != end && it->type() != token::list_end) { switch (it->type()) { - case Token::Comma: + case token::comma: // Previous must be a word. - if (it[-1].type() != Token::Word && it[-1].type() != Token::QuotedWord) - throw Error(it->line(), it->column(), "unexpected comma after '" + it[-1].value() + "'"); + if (it[-1].type() != token::word && it[-1].type() != token::quoted_word) { + throw exception(it->line(), it->column(), "unexpected comma after '" + it[-1].value() + "'"); + } ++ it; break; - case Token::Word: - case Token::QuotedWord: + case token::word: + case token::quoted_word: option.push_back((it++)->value()); break; default: - throw Error(it->line(), it->column(), "unexpected '" + it[-1].value() + "' in list construct"); + throw exception(it->line(), it->column(), "unexpected '" + it[-1].value() + "' in list construct"); break; } } - if (it == end) - throw Error(save->line(), save->column(), "unterminated list construct"); + if (it == end) { + throw exception(save->line(), save->column(), "unterminated list construct"); + } // Remove ). ++ it; } -void parseOption(Section &sc, TokenIterator &it, TokenIterator end) +void parse_option(section& sc, token_iterator& it, token_iterator end) { - Option option(it->value()); - - TokenIterator save = it; + option option(it->value()); + token_iterator save(it); // No '=' or something else? - if (++it == end) - throw Error(save->line(), save->column(), "expected '=' assignment, got <EOF>"); - if (it->type() != Token::Assign) - throw Error(it->line(), it->column(), "expected '=' assignment, got " + it->value()); + if (++it == end) { + throw exception(save->line(), save->column(), "expected '=' assignment, got <EOF>"); + } + if (it->type() != token::assign) { + throw exception(it->line(), it->column(), "expected '=' assignment, got " + it->value()); + } // Empty options are allowed so just test for words. if (++it != end) { - if (it->type() == Token::Word || it->type() == Token::QuotedWord) - parseOptionValueSimple(option, it); - else if (it->type() == Token::ListBegin) - parseOptionValueList(option, it, end); + if (it->type() == token::word || it->type() == token::quoted_word) { + parse_option_value_simple(option, it); + } else if (it->type() == token::list_begin) { + parse_option_value_list(option, it, end); + } } sc.push_back(std::move(option)); } -void parseInclude(Document &doc, const std::string &path, TokenIterator &it, TokenIterator end) +void parse_include(document& doc, const std::string& path, token_iterator& it, token_iterator end) { - TokenIterator save = it; + token_iterator save(it); - if (++it == end) - throw Error(save->line(), save->column(), "expected file name after '@include' statement, got <EOF>"); - if (it->type() != Token::Word && it->type() != Token::QuotedWord) - throw Error(it->line(), it->column(), "expected file name after '@include' statement, got " + it->value()); + if (++it == end) { + throw exception(save->line(), save->column(), "expected file name after '@include' statement, got <EOF>"); + } + if (it->type() != token::word && it->type() != token::quoted_word) { + throw exception(it->line(), it->column(), "expected file name after '@include' statement, got " + it->value()); + } std::string value = (it++)->value(); std::string file; - if (!isAbsolute(value)) + if (!is_absolute(value)) { #if defined(_WIN32) file = path + "\\" + value; #else file = path + "/" + value; #endif - else + } else { file = value; + } - for (const auto &sc : readFile(file)) + for (const auto& sc : read_file(file)) { doc.push_back(sc); + } } -void parseSection(Document &doc, TokenIterator &it, TokenIterator end) +void parse_section(document& doc, token_iterator& it, token_iterator end) { - Section sc(it->value()); + section sc(it->value()); // Skip [section]. ++ it; // Read until next section. - while (it != end && it->type() != Token::Section) { - if (it->type() != Token::Word) - throw Error(it->line(), it->column(), "unexpected token '" + it->value() + "' in section definition"); + while (it != end && it->type() != token::section) { + if (it->type() != token::word) { + throw exception(it->line(), it->column(), "unexpected token '" + it->value() + "' in section definition"); + } - parseOption(sc, it, end); + parse_option(sc, it, end); } doc.push_back(std::move(sc)); @@ -323,96 +334,98 @@ } // !namespace -namespace ini { - -Tokens analyse(std::istreambuf_iterator<char> it, std::istreambuf_iterator<char> end) +tokens analyse(std::istreambuf_iterator<char> it, std::istreambuf_iterator<char> end) { - Tokens list; + tokens list; int line = 1; int column = 0; while (it != end) { - if (*it == '\n') - analyseLine(line, column, it); - else if (*it == '#') - analyseComment(column, it, end); - else if (*it == '[') - analyseSection(list, line, column, it, end); - else if (*it == '=') - analyseAssign(list, line, column, it); - else if (isSpace(*it)) - analyseSpaces(column, it, end); - else if (*it == '@') - analyseInclude(list, line, column, it, end); - else if (isQuote(*it)) - analyseQuotedWord(list, line, column, it, end); - else if (isList(*it)) - analyseList(list, line, column, it); - else - analyseWord(list, line, column, it, end); + if (*it == '\n') { + analyse_line(line, column, it); + } else if (*it == '#') { + analyse_comment(column, it, end); + } else if (*it == '[') { + analyse_section(list, line, column, it, end); + } else if (*it == '=') { + analyse_assign(list, line, column, it); + } else if (is_space(*it)) { + analyse_spaces(column, it, end); + } else if (*it == '@') { + analyse_include(list, line, column, it, end); + } else if (is_quote(*it)) { + analyse_quoted_word(list, line, column, it, end); + } else if (is_list(*it)) { + analyse_list(list, line, column, it); + } else { + analyse_word(list, line, column, it, end); + } } return list; } -Tokens analyse(std::istream &stream) +tokens analyse(std::istream& stream) { return analyse(std::istreambuf_iterator<char>(stream), {}); } -Document parse(const Tokens &tokens, const std::string &path) +document parse(const tokens& tokens, const std::string& path) { - Document doc; - TokenIterator it = tokens.cbegin(); - TokenIterator end = tokens.cend(); + document doc; + token_iterator it = tokens.cbegin(); + token_iterator end = tokens.cend(); while (it != end) { switch (it->type()) { - case Token::Include: - parseInclude(doc, path, it, end); + case token::include: + parse_include(doc, path, it, end); break; - case Token::Section: - parseSection(doc, it, end); + case token::section: + parse_section(doc, it, end); break; default: - throw Error(it->line(), it->column(), "unexpected '" + it->value() + "' on root document"); + throw exception(it->line(), it->column(), "unexpected '" + it->value() + "' on root document"); } } return doc; } -Document readFile(const std::string &filename) +document read_file(const std::string& filename) { // Get parent path. auto parent = filename; auto pos = parent.find_last_of("/\\"); - if (pos != std::string::npos) + if (pos != std::string::npos) { parent.erase(pos); - else + } else { parent = "."; + } std::ifstream input(filename); - if (!input) - throw Error(0, 0, std::strerror(errno)); + if (!input) { + throw exception(0, 0, std::strerror(errno)); + } return parse(analyse(input), parent); } -Document readString(const std::string &buffer) +document read_string(const std::string& buffer) { std::istringstream iss(buffer); return parse(analyse(iss)); } -void dump(const Tokens &tokens) +void dump(const tokens& tokens) { - for (const Token &token: tokens) + for (const token& token: tokens) { // TODO: add better description std::cout << token.line() << ":" << token.column() << ": " << token.value() << std::endl; + } } } // !ini
--- a/libcommon/irccd/ini.hpp Fri Aug 11 13:45:42 2017 +0200 +++ b/libcommon/irccd/ini.hpp Tue Sep 26 17:18:47 2017 +0200 @@ -16,13 +16,14 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef IRCCD_INI_HPP -#define IRCCD_INI_HPP +#ifndef INI_HPP +#define INI_HPP /** * \file ini.hpp * \brief Extended .ini file parser. * \author David Demelier <markand@malikania.fr> + * \version 1.0.0 */ /** @@ -42,7 +43,8 @@ * - an option **must** always be defined in a section, * - empty options must be surrounded by quotes, * - lists can not includes trailing commas, - * - include statement must always be at the beginning of files (in no sections), + * - include statement must always be at the beginning of files + * (in no sections), * - comments starts with # until the end of line, * - options with spaces **must** use quotes. * @@ -57,7 +59,8 @@ * * # Redefinition * - * Sections can be redefined multiple times and are kept the order they are seen. + * Sections can be redefined multiple times and are kept the order they are + * seen. * * ````ini * [section] @@ -67,7 +70,7 @@ * value = "2" * ```` * - * The ini::Document object will contains two ini::Section. + * The ini::document object will contains two ini::Section. * * # Lists * @@ -86,8 +89,8 @@ * * # Include statement * - * You can split a file into several pieces, if the include statement contains a relative path, the path will be relative - * to the current file being parsed. + * You can split a file into several pieces, if the include statement contains a + * relative path, the path will be relative to the current file being parsed. * * You **must** use the include statement before any section. * @@ -103,6 +106,32 @@ * ```` */ +/** + * \cond INI_HIDDEN_SYMBOLS + */ + +#if !defined(IRCCD_EXPORT) +# if defined(INI_DLL) +# if defined(_WIN32) +# if defined(INI_BUILDING_DLL) +# define IRCCD_EXPORT __declspec(dllexport) +# else +# define IRCCD_EXPORT __declspec(dllimport) +# endif +# else +# define IRCCD_EXPORT +# endif +# else +# define IRCCD_EXPORT +# endif +#endif + +/** + * \endcond + */ + +#include <sysconfig.hpp> + #include <algorithm> #include <cassert> #include <exception> @@ -110,8 +139,6 @@ #include <string> #include <vector> -#include "sysconfig.hpp" - namespace irccd { /** @@ -119,16 +146,16 @@ */ namespace ini { -class Document; +class document; /** - * \brief Error in a file. + * \brief exception in a file. */ -class Error : public std::exception { +class exception : public std::exception { private: int m_line; //!< line number int m_column; //!< line column - std::string m_message; //!< error message + std::string m_message; //!< exception message public: /** @@ -138,7 +165,7 @@ * \param column the column * \param msg the message */ - inline Error(int line, int column, std::string msg) noexcept + inline exception(int line, int column, std::string msg) noexcept : m_line(line) , m_column(column) , m_message(std::move(msg)) @@ -166,11 +193,11 @@ } /** - * Return the raw error message (no line and column shown). + * Return the raw exception message (no line and column shown). * - * \return the error message + * \return the exception message */ - const char *what() const noexcept override + const char* what() const noexcept override { return m_message.c_str(); } @@ -183,24 +210,24 @@ * * \see analyze */ -class Token { +class token { public: /** - * \brief Token type. + * \brief token type. */ - enum Type { - Include, //!< include statement - Section, //!< [section] - Word, //!< word without quotes - QuotedWord, //!< word with quotes - Assign, //!< = assignment - ListBegin, //!< begin of list ( - ListEnd, //!< end of list ) - Comma //!< list separation + enum type { + include, //!< include statement + section, //!< [section] + word, //!< word without quotes + quoted_word, //!< word with quotes + assign, //!< = assignment + list_begin, //!< begin of list ( + list_end, //!< end of list ) + comma //!< list separation }; private: - Type m_type; + type m_type; int m_line; int m_column; std::string m_value; @@ -214,30 +241,30 @@ * \param column the column * \param value the value */ - Token(Type type, int line, int column, std::string value = "") noexcept + token(type type, int line, int column, std::string value = "") noexcept : m_type(type) , m_line(line) , m_column(column) { switch (type) { - case Include: + case include: m_value = "@include"; break; - case Section: - case Word: - case QuotedWord: + case section: + case word: + case quoted_word: m_value = value; break; - case Assign: + case assign: m_value = "="; break; - case ListBegin: + case list_begin: m_value = "("; break; - case ListEnd: + case list_end: m_value = ")"; break; - case Comma: + case comma: m_value = ","; break; default: @@ -250,7 +277,7 @@ * * \return the type */ - inline Type type() const noexcept + inline type type() const noexcept { return m_type; } @@ -276,12 +303,12 @@ } /** - * Get the value. For words, quoted words and section, the value is the content. Otherwise it's the - * characters parsed. + * Get the value. For words, quoted words and section, the value is the + * content. Otherwise it's the characters parsed. * * \return the value */ - inline const std::string &value() const noexcept + inline const std::string& value() const noexcept { return m_value; } @@ -290,12 +317,12 @@ /** * List of tokens in order they are analyzed. */ -using Tokens = std::vector<Token>; +using tokens = std::vector<token>; /** - * \brief Option definition. + * \brief option definition. */ -class Option : public std::vector<std::string> { +class option : public std::vector<std::string> { private: std::string m_key; @@ -306,7 +333,7 @@ * \pre key must not be empty * \param key the key */ - inline Option(std::string key) noexcept + inline option(std::string key) noexcept : std::vector<std::string>() , m_key(std::move(key)) { @@ -320,7 +347,7 @@ * \param key the key * \param value the value */ - inline Option(std::string key, std::string value) noexcept + inline option(std::string key, std::string value) noexcept : m_key(std::move(key)) { assert(!m_key.empty()); @@ -335,7 +362,7 @@ * \param key the key * \param values the values */ - inline Option(std::string key, std::vector<std::string> values) noexcept + inline option(std::string key, std::vector<std::string> values) noexcept : std::vector<std::string>(std::move(values)) , m_key(std::move(key)) { @@ -347,7 +374,7 @@ * * \return the key */ - inline const std::string &key() const noexcept + inline const std::string& key() const noexcept { return m_key; } @@ -357,7 +384,7 @@ * * \return the value */ - inline const std::string &value() const noexcept + inline const std::string& value() const noexcept { static std::string dummy; @@ -368,7 +395,7 @@ /** * \brief Section that contains one or more options. */ -class Section : public std::vector<Option> { +class section : public std::vector<option> { private: std::string m_key; @@ -379,7 +406,7 @@ * \pre key must not be empty * \param key the key */ - inline Section(std::string key) noexcept + inline section(std::string key) noexcept : m_key(std::move(key)) { assert(!m_key.empty()); @@ -390,7 +417,7 @@ * * \return the key */ - inline const std::string &key() const noexcept + inline const std::string& key() const noexcept { return m_key; } @@ -401,7 +428,7 @@ * \param key the option key * \return true if the option exists */ - inline bool contains(const std::string &key) const noexcept + inline bool contains(const std::string& key) const noexcept { return find(key) != end(); } @@ -412,9 +439,9 @@ * \param key the key * \return the iterator or end() if not found */ - inline iterator find(const std::string &key) noexcept + inline iterator find(const std::string& key) noexcept { - return std::find_if(begin(), end(), [&] (const auto &o) { + return std::find_if(begin(), end(), [&] (const auto& o) { return o.key() == key; }); } @@ -425,9 +452,9 @@ * \param key the key * \return the iterator or end() if not found */ - inline const_iterator find(const std::string &key) const noexcept + inline const_iterator find(const std::string& key) const noexcept { - return std::find_if(cbegin(), cend(), [&] (const auto &o) { + return std::find_if(cbegin(), cend(), [&] (const auto& o) { return o.key() == key; }); } @@ -439,7 +466,7 @@ * \return the option * \pre contains(key) must return true */ - inline Option &operator[](const std::string &key) + inline option& operator[](const std::string& key) { assert(contains(key)); @@ -453,7 +480,7 @@ * \return the option * \pre contains(key) must return true */ - inline const Option &operator[](const std::string &key) const + inline const option& operator[](const std::string& key) const { assert(contains(key)); @@ -463,7 +490,7 @@ /** * Inherited operators. */ - using std::vector<Option>::operator[]; + using std::vector<option>::operator[]; }; /** @@ -471,7 +498,7 @@ * \see readFile * \see readString */ -class Document : public std::vector<Section> { +class document : public std::vector<section> { public: /** * Check if a document has a specific section. @@ -479,9 +506,9 @@ * \param key the key * \return true if the document contains the section */ - inline bool contains(const std::string &key) const noexcept + inline bool contains(const std::string& key) const noexcept { - return std::find_if(begin(), end(), [&] (const auto &sc) { return sc.key() == key; }) != end(); + return find(key) != end(); } /** @@ -490,9 +517,9 @@ * \param key the key * \return the iterator or end() if not found */ - inline iterator find(const std::string &key) noexcept + inline iterator find(const std::string& key) noexcept { - return std::find_if(begin(), end(), [&] (const auto &o) { + return std::find_if(begin(), end(), [&] (const auto& o) { return o.key() == key; }); } @@ -503,9 +530,9 @@ * \param key the key * \return the iterator or end() if not found */ - inline const_iterator find(const std::string &key) const noexcept + inline const_iterator find(const std::string& key) const noexcept { - return std::find_if(cbegin(), cend(), [&] (const auto &o) { + return std::find_if(cbegin(), cend(), [&] (const auto& o) { return o.key() == key; }); } @@ -517,7 +544,7 @@ * \return the section * \pre contains(key) must return true */ - inline Section &operator[](const std::string &key) + inline section& operator[](const std::string& key) { assert(contains(key)); @@ -531,7 +558,7 @@ * \return the section * \pre contains(key) must return true */ - inline const Section &operator[](const std::string &key) const + inline const section& operator[](const std::string& key) const { assert(contains(key)); @@ -541,31 +568,31 @@ /** * Inherited operators. */ - using std::vector<Section>::operator[]; + using std::vector<section>::operator[]; }; /** - * Analyse a stream and detect potential syntax errors. This does not parse the file like including other - * files in include statement. + * Analyse a stream and detect potential syntax errors. This does not parse the + * file like including other files in include statement. * - * It does only analysis, for example if an option is defined under no section, this does not trigger an - * error while it's invalid. + * It does only analysis, for example if an option is defined under no section, + * this does not trigger an exception while it's invalid. * * \param it the iterator * \param end where to stop * \return the list of tokens - * \throws Error on errors + * \throws exception on errors */ -IRCCD_EXPORT Tokens analyse(std::istreambuf_iterator<char> it, std::istreambuf_iterator<char> end); +IRCCD_EXPORT tokens analyse(std::istreambuf_iterator<char> it, std::istreambuf_iterator<char> end); /** * Overloaded function for stream. * * \param stream the stream * \return the list of tokens - * \throws Error on errors + * \throws exception on errors */ -IRCCD_EXPORT Tokens analyse(std::istream &stream); +IRCCD_EXPORT tokens analyse(std::istream& stream); /** * Parse the produced tokens. @@ -573,39 +600,40 @@ * \param tokens the tokens * \param path the parent path * \return the document - * \throw Error on errors + * \throw exception on errors */ -IRCCD_EXPORT Document parse(const Tokens &tokens, const std::string &path = "."); +IRCCD_EXPORT document parse(const tokens& tokens, const std::string& path = "."); /** * Parse a file. * * \param filename the file name * \return the document - * \throw Error on errors + * \throw exception on errors */ -IRCCD_EXPORT Document readFile(const std::string &filename); +IRCCD_EXPORT document read_file(const std::string& filename); /** * Parse a string. * - * If the string contains include statements, they are relative to the current working directory. + * If the string contains include statements, they are relative to the current + * working directory. * * \param buffer the buffer * \return the document - * \throw Error on errors + * \throw exception on exceptions */ -IRCCD_EXPORT Document readString(const std::string &buffer); +IRCCD_EXPORT document read_string(const std::string& buffer); /** * Show all tokens and their description. * * \param tokens the tokens */ -IRCCD_EXPORT void dump(const Tokens &tokens); +IRCCD_EXPORT void dump(const tokens& tokens); } // !ini } // !irccd -#endif // !IRCCD_INI_HPP +#endif // !INI_HPP
--- a/libcommon/irccd/logger.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/libcommon/irccd/logger.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -44,33 +44,33 @@ */ std::atomic<bool> verbose{false}; -std::unique_ptr<Logger> iface{new ConsoleLogger}; -std::unique_ptr<Filter> filter{new Filter}; +std::unique_ptr<logger> use_iface{new console_logger}; +std::unique_ptr<filter> use_filter{new filter}; /* - * Buffer -- output buffer. + * buffer -- output buffer. * ------------------------------------------------------------------ * * This class inherits from std::stringbuf and writes the messages to the * specified interface function which is one of info, warning and debug. */ -class Buffer : public std::stringbuf { +class buffer : public std::stringbuf { public: - enum Level { - Debug, - Info, - Warning + enum class level { + debug, + info, + warning }; private: - Level m_level; + level level_; void debug(std::string line) { // Print only in debug mode, the buffer is flushed anyway. #if !defined(NDEBUG) - iface->debug(filter->preDebug(std::move(line))); + use_iface->debug(use_filter->pre_debug(std::move(line))); #else (void)line; #endif @@ -80,19 +80,19 @@ { // Print only if verbose, the buffer will be flushed anyway. if (verbose) - iface->info(filter->preInfo(std::move(line))); + use_iface->info(use_filter->pre_info(std::move(line))); } void warning(std::string line) { - iface->warning(filter->preWarning(std::move(line))); + use_iface->warning(use_filter->pre_warning(std::move(line))); } public: - inline Buffer(Level level) noexcept - : m_level(level) + inline buffer(level level) noexcept + : level_(level) { - assert(level >= Debug && level <= Warning); + assert(level >= level::debug && level <= level::warning); } virtual int sync() override @@ -101,19 +101,19 @@ std::string::size_type pos; while ((pos = buffer.find("\n")) != std::string::npos) { - std::string line = buffer.substr(0, pos); + auto line = buffer.substr(0, pos); // Remove this line. buffer.erase(buffer.begin(), buffer.begin() + pos + 1); - switch (m_level) { - case Level::Debug: + switch (level_) { + case level::debug: debug(std::move(line)); break; - case Level::Info: + case level::info: info(std::move(line)); break; - case Level::Warning: + case level::warning: warning(std::move(line)); break; default: @@ -133,108 +133,108 @@ */ // Buffers. -Buffer bufferInfo{Buffer::Info}; -Buffer bufferWarning{Buffer::Warning}; -Buffer bufferDebug{Buffer::Debug}; +buffer buffer_info{buffer::level::info}; +buffer buffer_warning{buffer::level::warning}; +buffer buffer_debug{buffer::level::debug}; // Stream outputs. -std::ostream streamInfo(&bufferInfo); -std::ostream streamWarning(&bufferWarning); -std::ostream streamDebug(&bufferDebug); +std::ostream stream_info(&buffer_info); +std::ostream stream_warning(&buffer_warning); +std::ostream stream_debug(&buffer_debug); } // !namespace /* - * ConsoleLogger + * console_logger * ------------------------------------------------------------------ */ -void ConsoleLogger::info(const std::string &line) +void console_logger::info(const std::string& line) { std::cout << line << std::endl; } -void ConsoleLogger::warning(const std::string &line) +void console_logger::warning(const std::string& line) { std::cerr << line << std::endl; } -void ConsoleLogger::debug(const std::string &line) +void console_logger::debug(const std::string& line) { std::cout << line << std::endl; } /* - * FileLogger + * file_logger * ------------------------------------------------------------------ */ -FileLogger::FileLogger(std::string normal, std::string errors) - : m_outputNormal(std::move(normal)) - , m_outputError(std::move(errors)) +file_logger::file_logger(std::string normal, std::string errors) + : output_normal_(std::move(normal)) + , output_error_(std::move(errors)) { } -void FileLogger::info(const std::string &line) +void file_logger::info(const std::string& line) { - std::ofstream(m_outputNormal, std::ofstream::out | std::ofstream::app) << line << std::endl; + std::ofstream(output_normal_, std::ofstream::out | std::ofstream::app) << line << std::endl; } -void FileLogger::warning(const std::string &line) +void file_logger::warning(const std::string& line) { - std::ofstream(m_outputError, std::ofstream::out | std::ofstream::app) << line << std::endl; + std::ofstream(output_error_, std::ofstream::out | std::ofstream::app) << line << std::endl; } -void FileLogger::debug(const std::string &line) +void file_logger::debug(const std::string& line) { - std::ofstream(m_outputNormal, std::ofstream::out | std::ofstream::app) << line << std::endl; + std::ofstream(output_normal_, std::ofstream::out | std::ofstream::app) << line << std::endl; } /* - * SilentLogger + * silent_logger * ------------------------------------------------------------------ */ -void SilentLogger::info(const std::string &) +void silent_logger::info(const std::string&) { } -void SilentLogger::warning(const std::string &) +void silent_logger::warning(const std::string&) { } -void SilentLogger::debug(const std::string &) +void silent_logger::debug(const std::string&) { } /* - * SyslogLogger + * syslog_logger * ------------------------------------------------------------------ */ #if defined(HAVE_SYSLOG) -SyslogLogger::SyslogLogger() +syslog_logger::syslog_logger() { - openlog(sys::programName().c_str(), LOG_PID, LOG_DAEMON); + openlog(sys::program_name().c_str(), LOG_PID, LOG_DAEMON); } -SyslogLogger::~SyslogLogger() +syslog_logger::~syslog_logger() { closelog(); } -void SyslogLogger::info(const std::string &line) +void syslog_logger::info(const std::string& line) { syslog(LOG_INFO | LOG_USER, "%s", line.c_str()); } -void SyslogLogger::warning(const std::string &line) +void syslog_logger::warning(const std::string& line) { syslog(LOG_WARNING | LOG_USER, "%s", line.c_str()); } -void SyslogLogger::debug(const std::string &line) +void syslog_logger::debug(const std::string& line) { syslog(LOG_DEBUG | LOG_USER, "%s", line.c_str()); } @@ -246,50 +246,50 @@ * ------------------------------------------------------------------ */ -void setLogger(std::unique_ptr<Logger> newiface) noexcept +void set_logger(std::unique_ptr<logger> new_iface) noexcept { - assert(newiface); + assert(new_iface); - iface = std::move(newiface); + use_iface = std::move(new_iface); } -void setFilter(std::unique_ptr<Filter> newfilter) noexcept +void set_filter(std::unique_ptr<filter> newfilter) noexcept { - assert(filter); + assert(newfilter); - filter = std::move(newfilter); + use_filter = std::move(newfilter); } -std::ostream &info(const std::string &message) +std::ostream& info(const std::string& message) { if (!message.empty()) - streamInfo << message << std::endl; + stream_info << message << std::endl; - return streamInfo; + return stream_info; } -std::ostream &warning(const std::string &message) +std::ostream& warning(const std::string& message) { if (!message.empty()) - streamWarning << message << std::endl; + stream_warning << message << std::endl; - return streamWarning; + return stream_warning; } -std::ostream &debug(const std::string &message) +std::ostream& debug(const std::string& message) { if (!message.empty()) - streamDebug << message << std::endl; + stream_debug << message << std::endl; - return streamDebug; + return stream_debug; } -bool isVerbose() noexcept +bool is_verbose() noexcept { return verbose; } -void setVerbose(bool mode) noexcept +void set_verbose(bool mode) noexcept { verbose = mode; }
--- a/libcommon/irccd/logger.hpp Fri Aug 11 13:45:42 2017 +0200 +++ b/libcommon/irccd/logger.hpp Tue Sep 26 17:18:47 2017 +0200 @@ -35,26 +35,26 @@ namespace log { /* - * Logger -- abstract logging interface + * logger -- abstract logging interface * ------------------------------------------------------------------ */ /** * \brief Interface to implement new logger mechanisms. * - * Derive from this class and use log::setLogger() to change logging system. + * Derive from this class and use log::set_logger() to change logging system. * - * \see File - * \see Console - * \see Syslog - * \see Silent + * \see file_logger + * \see console_logger + * \see syslog_logger + * \see silent_logger */ -class Logger { +class logger { public: /** * Virtual destructor defaulted. */ - virtual ~Logger() = default; + virtual ~logger() = default; /** * Write a debug message. @@ -64,7 +64,7 @@ * \param line the data * \see log::debug */ - virtual void debug(const std::string &line) = 0; + virtual void debug(const std::string& line) = 0; /** * Write a information message. @@ -74,7 +74,7 @@ * \param line the data * \see log::info */ - virtual void info(const std::string &line) = 0; + virtual void info(const std::string& line) = 0; /** * Write an error message. @@ -84,11 +84,11 @@ * \param line the data * \see log::warning */ - virtual void warning(const std::string &line) = 0; + virtual void warning(const std::string& line) = 0; }; /* - * Filter -- modify messages before printing + * filter -- modify messages before printing * ------------------------------------------------------------------ */ @@ -97,12 +97,12 @@ * * Derive from this class and use log::setFilter. */ -class Filter { +class filter { public: /** * Virtual destructor defaulted. */ - virtual ~Filter() = default; + virtual ~filter() = default; /** * Update the debug message. @@ -110,7 +110,7 @@ * \param input the message * \return the updated message */ - virtual std::string preDebug(std::string input) const + virtual std::string pre_debug(std::string input) const { return input; } @@ -121,7 +121,7 @@ * \param input the message * \return the updated message */ - virtual std::string preInfo(std::string input) const + virtual std::string pre_info(std::string input) const { return input; } @@ -132,14 +132,14 @@ * \param input the message * \return the updated message */ - virtual std::string preWarning(std::string input) const + virtual std::string pre_warning(std::string input) const { return input; } }; /* - * Console -- logs to console + * console_logger -- logs to console * ------------------------------------------------------------------ */ @@ -147,36 +147,36 @@ * \brief Logger implementation for console output using std::cout and * std::cerr. */ -class ConsoleLogger : public Logger { +class console_logger : public logger { public: /** - * \copydoc Logger::debug + * \copydoc logger::debug */ - IRCCD_EXPORT void debug(const std::string &line) override; + void debug(const std::string& line) override; /** - * \copydoc Logger::info + * \copydoc logger::info */ - IRCCD_EXPORT void info(const std::string &line) override; + void info(const std::string& line) override; /** - * \copydoc Logger::warning + * \copydoc logger::warning */ - IRCCD_EXPORT void warning(const std::string &line) override; + void warning(const std::string& line) override; }; /* - * File -- logs to a file + * file_logger -- logs to a file * ------------------------------------------------------------------ */ /** * \brief Output to a files. */ -class FileLogger : public Logger { +class file_logger : public logger { private: - std::string m_outputNormal; - std::string m_outputError; + std::string output_normal_; + std::string output_error_; public: /** @@ -185,26 +185,26 @@ * \param normal the path to the normal logs * \param errors the path to the errors logs */ - IRCCD_EXPORT FileLogger(std::string normal, std::string errors); + file_logger(std::string normal, std::string errors); /** - * \copydoc Logger::debug + * \copydoc logger::debug */ - IRCCD_EXPORT void debug(const std::string &line) override; + void debug(const std::string& line) override; /** - * \copydoc Logger::info + * \copydoc logger::info */ - IRCCD_EXPORT void info(const std::string &line) override; + void info(const std::string& line) override; /** - * \copydoc Logger::warning + * \copydoc logger::warning */ - IRCCD_EXPORT void warning(const std::string &line) override; + void warning(const std::string& line) override; }; /* - * Silent -- disable all logs + * silent_logger -- disable all logs * ------------------------------------------------------------------ */ @@ -213,26 +213,26 @@ * * Useful for unit tests when some classes may emits log. */ -class SilentLogger : public Logger { +class silent_logger : public logger { public: /** - * \copydoc Logger::debug + * \copydoc logger::debug */ - IRCCD_EXPORT void debug(const std::string &line) override; + void debug(const std::string& line) override; /** - * \copydoc Logger::info + * \copydoc logger::info */ - IRCCD_EXPORT void info(const std::string &line) override; + void info(const std::string& line) override; /** - * \copydoc Logger::warning + * \copydoc logger::warning */ - IRCCD_EXPORT void warning(const std::string &line) override; + void warning(const std::string& line) override; }; /* - * Syslog -- system logger + * syslog_logger -- system logger * ------------------------------------------------------------------ */ @@ -241,32 +241,32 @@ /** * \brief Implements logger into syslog. */ -class SyslogLogger : public Logger { +class syslog_logger : public logger { public: /** * Open the syslog. */ - IRCCD_EXPORT SyslogLogger(); + syslog_logger(); /** * Close the syslog. */ - IRCCD_EXPORT ~SyslogLogger(); + ~syslog_logger(); /** - * \copydoc Logger::debug + * \copydoc logger::debug */ - IRCCD_EXPORT void debug(const std::string &line) override; + void debug(const std::string& line) override; /** - * \copydoc Logger::info + * \copydoc logger::info */ - IRCCD_EXPORT void info(const std::string &line) override; + void info(const std::string& line) override; /** - * \copydoc Logger::warning + * \copydoc logger::warning */ - IRCCD_EXPORT void warning(const std::string &line) override; + void warning(const std::string& line) override; }; #endif // !HAVE_SYSLOG @@ -282,7 +282,7 @@ * \pre iface must not be null * \param iface the new interface */ -IRCCD_EXPORT void setLogger(std::unique_ptr<Logger> iface) noexcept; +IRCCD_EXPORT void set_logger(std::unique_ptr<logger> iface) noexcept; /** * Set an optional filter. @@ -290,7 +290,7 @@ * \pre filter must not be null * \param filter the filter */ -IRCCD_EXPORT void setFilter(std::unique_ptr<Filter> filter) noexcept; +IRCCD_EXPORT void set_filter(std::unique_ptr<filter> filter) noexcept; /** * Get the stream for informational messages. @@ -301,7 +301,7 @@ * \return the stream * \note Has no effect if verbose is set to false. */ -IRCCD_EXPORT std::ostream &info(const std::string &message = ""); +IRCCD_EXPORT std::ostream& info(const std::string& message = ""); /** * Get the stream for warnings. @@ -311,7 +311,7 @@ * \param message the optional message to write * \return the stream */ -IRCCD_EXPORT std::ostream &warning(const std::string &message = ""); +IRCCD_EXPORT std::ostream& warning(const std::string& message = ""); /** * Get the stream for debug messages. @@ -322,21 +322,21 @@ * \return the stream * \note Has no effect if compiled in release mode. */ -IRCCD_EXPORT std::ostream &debug(const std::string &message = ""); +IRCCD_EXPORT std::ostream& debug(const std::string& message = ""); /** * Tells if verbose is enabled. * * \return true if enabled */ -IRCCD_EXPORT bool isVerbose() noexcept; +IRCCD_EXPORT bool is_verbose() noexcept; /** * Set the verbosity mode. * * \param mode the new mode */ -IRCCD_EXPORT void setVerbose(bool mode) noexcept; +IRCCD_EXPORT void set_verbose(bool mode) noexcept; } // !log
--- a/libcommon/irccd/system.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/libcommon/irccd/system.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -111,15 +111,15 @@ namespace { /* - * XXX: the setprogname() function keeps a pointer without copying it so when + * The setprogname() function keeps a pointer without copying it so when * main's argv is modified, we're not using the same name so create our own * copy. */ -std::string programNameCopy; +std::string program_name_value; /* - * setHelper. + * set_privileges. * ------------------------------------------------------------------ * * This is an helper for setting the uid or gid. It accepts both numeric and @@ -140,28 +140,32 @@ * - getter the function to get the id from the informal structure */ template <typename IntType, typename LookupFunc, typename SetterFunc, typename FieldGetter> -void setHelper(const std::string &typeName, const std::string &value, LookupFunc lookup, SetterFunc setter, FieldGetter getter) +void set_privileges(const std::string& type_name, + const std::string& value, + LookupFunc lookup, + SetterFunc setter, + FieldGetter getter) { - IntType id; + IntType id = 0; - if (util::isNumber(value)) + if (util::is_int(value)) id = std::stoi(value); else { auto info = lookup(value.c_str()); if (info == nullptr) { - log::warning() << "irccd: invalid " << typeName << ": " << std::strerror(errno) << std::endl; + log::warning() << "irccd: invalid " << type_name << ": " << std::strerror(errno) << std::endl; return; } else { id = getter(info); - log::debug() << "irccd: " << typeName << " " << value << " resolved to: " << id << std::endl; + log::debug() << "irccd: " << type_name << " " << value << " resolved to: " << id << std::endl; } } if (setter(id) < 0) - log::warning() << "irccd: could not set " << typeName << ": " << std::strerror(errno) << std::endl; + log::warning() << "irccd: could not set " << type_name << ": " << std::strerror(errno) << std::endl; else - log::info() << "irccd: setting " << typeName << " to " << value << std::endl; + log::info() << "irccd: setting " << type_name << " to " << value << std::endl; } /* @@ -397,18 +401,18 @@ } // !namespace -void setProgramName(std::string name) noexcept +void set_program_name(std::string name) noexcept { - programNameCopy = std::move(name); + program_name_value = std::move(name); #if defined(HAVE_SETPROGNAME) - setprogname(programNameCopy.c_str()); + setprogname(program_name_value.c_str()); #endif } -const std::string &programName() noexcept +const std::string& program_name() noexcept { - return programNameCopy; + return program_name_value; } std::string name() @@ -513,7 +517,7 @@ #endif } -std::string env(const std::string &var) +std::string env(const std::string& var) { auto value = std::getenv(var.c_str()); @@ -525,9 +529,9 @@ #if defined(HAVE_SETUID) -void setUid(const std::string &value) +void set_uid(const std::string& value) { - setHelper<uid_t>("uid", value, &getpwnam, &setuid, [] (const struct passwd *pw) { + set_privileges<uid_t>("uid", value, &getpwnam, &setuid, [] (auto pw) { return pw->pw_uid; }); } @@ -536,9 +540,9 @@ #if defined(HAVE_SETGID) -void setGid(const std::string &value) +void set_gid(const std::string& value) { - setHelper<gid_t>("gid", value, &getgrnam, &setgid, [] (const struct group *gr) { + set_privileges<gid_t>("gid", value, &getgrnam, &setgid, [] (auto gr) { return gr->gr_gid; }); }
--- a/libcommon/irccd/system.hpp Fri Aug 11 13:45:42 2017 +0200 +++ b/libcommon/irccd/system.hpp Tue Sep 26 17:18:47 2017 +0200 @@ -44,14 +44,14 @@ * * \param name the program name */ -IRCCD_EXPORT void setProgramName(std::string name) noexcept; +IRCCD_EXPORT void set_program_name(std::string name) noexcept; /** * Get the program name. * * \return the program name */ -IRCCD_EXPORT const std::string &programName() noexcept; +IRCCD_EXPORT const std::string& program_name() noexcept; /** * Get the system name. @@ -72,7 +72,7 @@ * * \return the number of seconds */ -IRCCD_EXPORT uint64_t uptime(); +IRCCD_EXPORT std::uint64_t uptime(); /** * Get the milliseconds elapsed since the application @@ -80,14 +80,14 @@ * * \return the milliseconds */ -IRCCD_EXPORT uint64_t ticks(); +IRCCD_EXPORT std::uint64_t ticks(); /** * Get an environment variable. * * \return the value or empty string */ -IRCCD_EXPORT std::string env(const std::string &var); +IRCCD_EXPORT std::string env(const std::string& var); /** * Get home directory usually /home/foo @@ -103,7 +103,7 @@ * * \param value the value */ -IRCCD_EXPORT void setUid(const std::string &value); +IRCCD_EXPORT void set_uid(const std::string& value); #endif @@ -114,7 +114,7 @@ * * \param value the value */ -IRCCD_EXPORT void setGid(const std::string &value); +IRCCD_EXPORT void set_gid(const std::string& value); #endif
--- a/libcommon/irccd/util.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/libcommon/irccd/util.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -45,7 +45,7 @@ namespace { -const std::unordered_map<std::string, int> colorTable{ +const std::unordered_map<std::string, int> colors{ { "white", 0 }, { "black", 1 }, { "blue", 2 }, @@ -64,7 +64,7 @@ { "lightgrey", 15 } }; -const std::unordered_map<std::string, char> attributesTable{ +const std::unordered_map<std::string, char> attributes{ { "bold", '\x02' }, { "italic", '\x09' }, { "strike", '\x13' }, @@ -74,12 +74,12 @@ { "reverse", '\x16' } }; -inline bool isReserved(char token) noexcept +inline bool is_reserved(char token) noexcept { return token == '#' || token == '@' || token == '$' || token == '!'; } -std::string substituteDate(const std::string &text, const Substitution ¶ms) +std::string subst_date(const std::string& text, const subst& params) { std::ostringstream oss; @@ -87,7 +87,8 @@ oss << std::put_time(std::localtime(¶ms.time), text.c_str()); #else /* - * Quick and dirty hack because GCC does not have this function. + * Quick and dirty hack because old version of GCC does not have this + * function. */ char buffer[4096]; @@ -99,7 +100,7 @@ return oss.str(); } -std::string substituteKeywords(const std::string &content, const Substitution ¶ms) +std::string subst_keywords(const std::string& content, const subst& params) { auto value = params.keywords.find(content); @@ -109,7 +110,7 @@ return ""; } -std::string substituteEnv(const std::string &content) +std::string subst_env(const std::string& content) { auto value = std::getenv(content.c_str()); @@ -119,14 +120,14 @@ return ""; } -std::string substituteAttributes(const std::string &content) +std::string subst_attrs(const std::string& content) { std::stringstream oss; std::vector<std::string> list = split(content, ","); // @{} means reset. if (list.empty()) - return std::string(1, attributesTable.at("reset")); + return std::string(1, attributes.at("reset")); // Remove useless spaces. std::transform(list.begin(), list.end(), list.begin(), strip); @@ -142,19 +143,19 @@ oss << '\x03'; // Foreground. - auto it = colorTable.find(foreground); - if (it != colorTable.end()) + auto it = colors.find(foreground); + if (it != colors.end()) oss << it->second; // Background. - if (list.size() >= 2 && (it = colorTable.find(list[1])) != colorTable.end()) + if (list.size() >= 2 && (it = colors.find(list[1])) != colors.end()) oss << "," << it->second; // Attributes. for (std::size_t i = 2; i < list.size(); ++i) { - auto attribute = attributesTable.find(list[i]); + auto attribute = attributes.find(list[i]); - if (attribute != attributesTable.end()) + if (attribute != attributes.end()) oss << attribute->second; } } @@ -162,10 +163,10 @@ return oss.str(); } -std::string substituteShell(const std::string &command) +std::string subst_shell(const std::string& command) { #if defined(HAVE_POPEN) - std::unique_ptr<FILE, std::function<int (FILE *)>> fp(popen(command.c_str(), "r"), pclose); + std::unique_ptr<FILE, std::function<int (FILE*)>> fp(popen(command.c_str(), "r"), pclose); if (fp == nullptr) throw std::runtime_error(std::strerror(errno)); @@ -190,9 +191,9 @@ #endif } -std::string substitute(std::string::const_iterator &it, std::string::const_iterator &end, char token, const Substitution ¶ms) +std::string substitute(std::string::const_iterator& it, std::string::const_iterator& end, char token, const subst& params) { - assert(isReserved(token)); + assert(is_reserved(token)); std::string content, value; @@ -212,20 +213,20 @@ switch (token) { case '#': - if (params.flags & Substitution::Keywords) - value = substituteKeywords(content, params); + if ((params.flags & subst_flags::keywords) == subst_flags::keywords) + value = subst_keywords(content, params); break; case '$': - if (params.flags & Substitution::Env) - value = substituteEnv(content); + if ((params.flags & subst_flags::env) == subst_flags::env) + value = subst_env(content); break; case '@': - if (params.flags & Substitution::IrcAttrs) - value = substituteAttributes(content); + if ((params.flags & subst_flags::irc_attrs) == subst_flags::irc_attrs) + value = subst_attrs(content); break; case '!': - if (params.flags & Substitution::Shell) - value = substituteShell(content); + if ((params.flags & subst_flags::shell) == subst_flags::shell) + value = subst_shell(content); break; default: break; @@ -236,33 +237,33 @@ } // !namespace -std::string format(std::string text, const Substitution ¶ms) +std::string format(std::string text, const subst& params) { /* * Change the date format before anything else to avoid interpolation with * keywords and user input. */ - if (params.flags & Substitution::Date) - text = substituteDate(text, params); + if ((params.flags & subst_flags::date) == subst_flags::date) + text = subst_date(text, params); std::ostringstream oss; for (auto it = text.cbegin(), end = text.cend(); it != end; ) { auto token = *it; - /* Is the current character a reserved token or not? */ - if (!isReserved(token)) { + // Is the current character a reserved token or not? + if (!is_reserved(token)) { oss << *it++; continue; } - /* The token was at the end, just write it and return now. */ + // The token was at the end, just write it and return now. if (++it == end) { oss << token; continue; } - /* The token is declaring a template variable, substitute it. */ + // The token is declaring a template variable, substitute it. if (*it == '{') { oss << substitute(++it, end, token, params); continue; @@ -307,7 +308,7 @@ return str; } -std::vector<std::string> split(const std::string &list, const std::string &delimiters, int max) +std::vector<std::string> split(const std::string& list, const std::string& delimiters, int max) { std::vector<std::string> result; std::size_t next = -1, current; @@ -338,10 +339,10 @@ return result; } -MessagePair parseMessage(std::string message, const std::string &cc, const std::string &name) +message_pack parse_message(std::string message, const std::string& cc, const std::string& name) { - std::string result = message; - bool iscommand = false; + auto result = message; + auto iscommand = false; // handle special commands "!<plugin> command" if (cc.length() > 0) { @@ -371,10 +372,13 @@ } } - return MessagePair(result, ((iscommand) ? MessageType::Command : MessageType::Message)); + return { + iscommand ? message_pack::type::command : message_pack::type::message, + result + }; } -bool isBoolean(std::string value) noexcept +bool is_boolean(std::string value) noexcept { std::transform(value.begin(), value.end(), value.begin(), [] (auto c) { return toupper(c); @@ -383,7 +387,7 @@ return value == "1" || value == "YES" || value == "TRUE" || value == "ON"; } -bool isInt(const std::string &str, int base) noexcept +bool is_int(const std::string &str, int base) noexcept { if (str.empty()) return false; @@ -395,7 +399,7 @@ return *ptr == 0; } -bool isReal(const std::string &str) noexcept +bool is_real(const std::string &str) noexcept { if (str.empty()) return false; @@ -407,7 +411,7 @@ return *ptr == 0; } -std::string nextNetwork(std::string &input) +std::string next_network(std::string& input) { std::string result; std::string::size_type pos = input.find("\r\n\r\n");
--- a/libcommon/irccd/util.hpp Fri Aug 11 13:45:42 2017 +0200 +++ b/libcommon/irccd/util.hpp Tue Sep 26 17:18:47 2017 +0200 @@ -51,8 +51,7 @@ namespace util { /** - * \enum MessageType - * \brief Describe which type of message has been received + * \brief Pack a message and its type * * On channels and queries, you may have a special command or a standard message * depending on the beginning of the message. @@ -60,36 +59,95 @@ * Example: `!reminder help' may invoke the command event if a plugin reminder * exists. */ -enum class MessageType { - Command, //!< special command - Message //!< standard message +struct message_pack { + /** + * \brief Describe which type of message has been received + */ + enum class type { + command, //!< special command + message //!< standard message + } type; + + /** + * Message content. + */ + std::string message; +}; + +/** + * \brief Disable or enable some features. + */ +enum class subst_flags : std::uint8_t { + date = (1 << 0), //!< date templates + keywords = (1 << 1), //!< keywords + env = (1 << 2), //!< environment variables + shell = (1 << 3), //!< command line command + irc_attrs = (1 << 4) //!< IRC escape codes }; /** - * \brief Combine the type of message and its content. + * \cond ENUM_HIDDEN_SYMBOLS */ -using MessagePair = std::pair<std::string, MessageType>; + +inline subst_flags operator^(subst_flags v1, subst_flags v2) noexcept +{ + return static_cast<subst_flags>(static_cast<unsigned>(v1) ^ static_cast<unsigned>(v2)); +} + +inline subst_flags operator&(subst_flags v1, subst_flags v2) noexcept +{ + return static_cast<subst_flags>(static_cast<unsigned>(v1)& static_cast<unsigned>(v2)); +} + +inline subst_flags operator|(subst_flags v1, subst_flags v2) noexcept +{ + return static_cast<subst_flags>(static_cast<unsigned>(v1) | static_cast<unsigned>(v2)); +} + +inline subst_flags operator~(subst_flags v) noexcept +{ + return static_cast<subst_flags>(~static_cast<unsigned>(v)); +} + +inline subst_flags& operator|=(subst_flags& v1, subst_flags v2) noexcept +{ + v1 = static_cast<subst_flags>(static_cast<unsigned>(v1) | static_cast<unsigned>(v2)); + + return v1; +} + +inline subst_flags& operator&=(subst_flags& v1, subst_flags v2) noexcept +{ + v1 = static_cast<subst_flags>(static_cast<unsigned>(v1)& static_cast<unsigned>(v2)); + + return v1; +} + +inline subst_flags& operator^=(subst_flags& v1, subst_flags v2) noexcept +{ + v1 = static_cast<subst_flags>(static_cast<unsigned>(v1) ^ static_cast<unsigned>(v2)); + + return v1; +} + +/** + * \endcond + */ /** * \brief Used for format() function. */ -class Substitution { +class subst { public: /** - * \brief Disable or enable some features. - */ - enum Flags { - Date = (1 << 0), //!< date templates - Keywords = (1 << 1), //!< keywords - Env = (1 << 2), //!< environment variables - Shell = (1 << 3), //!< command line command - IrcAttrs = (1 << 4) //!< IRC escape codes - }; - - /** * Flags for selecting templates. */ - std::uint8_t flags{Date | Keywords | Env | IrcAttrs}; + subst_flags flags{ + subst_flags::date | + subst_flags::keywords | + subst_flags::env | + subst_flags::irc_attrs + }; /** * Fill that field if you want a date. @@ -156,7 +214,7 @@ * - <strong>\@{white,black,bold,underline}</strong>: will write white text on * black in both bold and underline. */ -IRCCD_EXPORT std::string format(std::string text, const Substitution ¶ms = {}); +IRCCD_EXPORT std::string format(std::string text, const subst& params = {}); /** * Remove leading and trailing spaces. @@ -174,7 +232,7 @@ * \param max max number of split * \return a list of string splitted */ -IRCCD_EXPORT std::vector<std::string> split(const std::string &list, const std::string &delimiters, int max = -1); +IRCCD_EXPORT std::vector<std::string> split(const std::string& list, const std::string& delimiters, int max = -1); /** * Join values by a separator and return a string. @@ -228,12 +286,17 @@ /** * Parse IRC message and determine if it's a command or a simple message. * + * If it's a command, the plugin invocation command is removed from the + * original message, otherwise it is copied verbatime. + * * \param message the message line - * \param commandChar the command char (e.g '!') + * \param cchar the command char (e.g '!') * \param plugin the plugin name * \return the pair */ -IRCCD_EXPORT MessagePair parseMessage(std::string message, const std::string &commandChar, const std::string &plugin); +IRCCD_EXPORT message_pack parse_message(std::string message, + const std::string& cchar, + const std::string& plugin); /** * Server and identities must have strict names. This function can @@ -242,7 +305,7 @@ * \param name the identifier name * \return true if is valid */ -inline bool isIdentifierValid(const std::string &name) +inline bool is_identifier(const std::string& name) { return std::regex_match(name, std::regex("[A-Za-z0-9-_]+")); } @@ -254,7 +317,7 @@ * \return true if is boolean * \note this function is case-insensitive */ -IRCCD_EXPORT bool isBoolean(std::string value) noexcept; +IRCCD_EXPORT bool is_boolean(std::string value) noexcept; /** * Check if the string is an integer. @@ -263,15 +326,15 @@ * \param base the optional base * \return true if integer */ -IRCCD_EXPORT bool isInt(const std::string &value, int base = 10) noexcept; - +IRCCD_EXPORT bool is_int(const std::string& value, int base = 10) noexcept; + /** * Check if the string is real. * * \param value the value * \return true if real */ -IRCCD_EXPORT bool isReal(const std::string &value) noexcept; +IRCCD_EXPORT bool is_real(const std::string& value) noexcept; /** * Check if the string is a number. @@ -279,23 +342,9 @@ * \param value the value * \return true if it is a number */ -inline bool isNumber(const std::string &value) noexcept +inline bool is_number(const std::string& value) noexcept { - return isInt(value) || isReal(value); -} - -/** - * Tells if a number is bound between the limits. - * - * \param value the value to check - * \param min the minimum - * \param max the maximum - * \return true if value is beyond the limits - */ -template <typename T> -constexpr bool isBound(T value, T min = std::numeric_limits<T>::min(), T max = std::numeric_limits<T>::max()) noexcept -{ - return value >= min && value <= max; + return is_int(value) || is_real(value); } /** @@ -316,7 +365,9 @@ * \throw std::out_of_range if the number is not between min and max */ template <typename T> -inline T toNumber(const std::string &number, T min = std::numeric_limits<T>::min(), T max = std::numeric_limits<T>::max()) +inline T to_number(const std::string& number, + T min = std::numeric_limits<T>::min(), + T max = std::numeric_limits<T>::max()) { static_assert(std::is_integral<T>::value, "T must be integer type"); @@ -334,14 +385,6 @@ } /** - * Parse a network message from an input buffer and remove it from it. - * - * \param input the buffer, will be updated - * \return the message or empty string if there is nothing - */ -IRCCD_EXPORT std::string nextNetwork(std::string &input); - -/** * Use arguments to avoid compiler warnings about unused parameters. */ template <typename... Args> @@ -350,6 +393,14 @@ } /** + * Parse a network message from an input buffer and remove it from it. + * + * \param input the buffer, will be updated + * \return the message or empty string if there is nothing + */ +IRCCD_EXPORT std::string next_network(std::string& input); + +/** * Utilities for nlohmann json. */ namespace json { @@ -363,7 +414,7 @@ * \return the value * \throw std::runtime_error if the property is missing */ -inline nlohmann::json require(const nlohmann::json &json, const std::string &key, nlohmann::json::value_t type) +inline nlohmann::json require(const nlohmann::json& json, const std::string& key, nlohmann::json::value_t type) { auto it = json.find(key); auto dummy = nlohmann::json(type); @@ -384,7 +435,7 @@ * \return the boolean * \throw std::runtime_error if the property is missing or not a boolean */ -inline bool requireBool(const nlohmann::json &json, const std::string &key) +inline bool require_bool(const nlohmann::json& json, const std::string& key) { return require(json, key, nlohmann::json::value_t::boolean); } @@ -397,7 +448,7 @@ * \return the int * \throw std::runtime_error if the property is missing or not ant int */ -inline std::int64_t requireInt(const nlohmann::json &json, const std::string &key) +inline std::int64_t require_int(const nlohmann::json& json, const std::string& key) { auto it = json.find(key); @@ -420,7 +471,7 @@ * \return the unsigned int * \throw std::runtime_error if the property is missing or not ant int */ -inline std::uint64_t requireUint(const nlohmann::json &json, const std::string &key) +inline std::uint64_t require_uint(const nlohmann::json& json, const std::string& key) { auto it = json.find(key); @@ -443,7 +494,7 @@ * \return the string * \throw std::runtime_error if the property is missing or not a string */ -inline std::string requireString(const nlohmann::json &json, const std::string &key) +inline std::string require_string(const nlohmann::json& json, const std::string& key) { return require(json, key, nlohmann::json::value_t::string); } @@ -456,11 +507,11 @@ * \return the identifier * \throw std::runtime_error if the property is invalid */ -inline std::string requireIdentifier(const nlohmann::json &json, const std::string &key) +inline std::string require_identifier(const nlohmann::json& json, const std::string& key) { - auto id = requireString(json, key); + auto id = require_string(json, key); - if (!isIdentifierValid(id)) + if (!is_identifier(id)) throw std::runtime_error("invalid '{}' identifier property"); return id; @@ -473,7 +524,7 @@ * \param def the default value if not boolean * \return a boolean */ -inline bool toBool(const nlohmann::json &json, bool def = false) noexcept +inline bool to_bool(const nlohmann::json& json, bool def = false) noexcept { return json.is_boolean() ? json.get<bool>() : def; } @@ -485,7 +536,7 @@ * \param def the default value if not an int * \return an int */ -inline std::int64_t toInt(const nlohmann::json &json, std::int64_t def = 0) noexcept +inline std::int64_t to_int(const nlohmann::json& json, std::int64_t def = 0) noexcept { return json.is_number_integer() ? json.get<std::int64_t>() : def; } @@ -497,7 +548,7 @@ * \param def the default value if not a unsigned int * \return an unsigned int */ -inline std::uint64_t toUint(const nlohmann::json &json, std::uint64_t def = 0) noexcept +inline std::uint64_t to_uint(const nlohmann::json& json, std::uint64_t def = 0) noexcept { return json.is_number_unsigned() ? json.get<std::uint64_t>() : def; } @@ -509,7 +560,7 @@ * \param def the default value if not a string * \return a string */ -inline std::string toString(const nlohmann::json &json, std::string def = "") noexcept +inline std::string to_string(const nlohmann::json& json, std::string def = "") noexcept { return json.is_string() ? json.get<std::string>() : def; } @@ -521,7 +572,7 @@ * \param property the property key * \return the value or null one if not found */ -inline nlohmann::json get(const nlohmann::json &json, const std::string &property) noexcept +inline nlohmann::json get(const nlohmann::json& json, const std::string& property) noexcept { auto it = json.find(property); @@ -539,9 +590,11 @@ * \param def the default value * \return the boolean */ -inline bool getBool(const nlohmann::json &json, const std::string &key, bool def = false) noexcept +inline bool get_bool(const nlohmann::json& json, + const std::string& key, + bool def = false) noexcept { - return toBool(get(json, key), def); + return to_bool(get(json, key), def); } /** @@ -552,9 +605,11 @@ * \param def the default value * \return the int */ -inline std::int64_t getInt(const nlohmann::json &json, const std::string &key, std::int64_t def = 0) noexcept +inline std::int64_t get_int(const nlohmann::json& json, + const std::string& key, + std::int64_t def = 0) noexcept { - return toInt(get(json, key), def); + return to_int(get(json, key), def); } /** @@ -565,9 +620,11 @@ * \param def the default value * \return the unsigned int */ -inline std::uint64_t getUint(const nlohmann::json &json, const std::string &key, std::uint64_t def = 0) noexcept +inline std::uint64_t get_uint(const nlohmann::json& json, + const std::string& key, + std::uint64_t def = 0) noexcept { - return toUint(get(json, key), def); + return to_uint(get(json, key), def); } /** @@ -580,12 +637,12 @@ * \return the value */ template <typename T> -inline T getIntRange(const nlohmann::json &json, - const std::string &key, - std::int64_t min = std::numeric_limits<T>::min(), - std::int64_t max = std::numeric_limits<T>::max()) noexcept +inline T get_int_range(const nlohmann::json& json, + const std::string& key, + std::int64_t min = std::numeric_limits<T>::min(), + std::int64_t max = std::numeric_limits<T>::max()) noexcept { - return clamp(getInt(json, key), min, max); + return clamp(get_int(json, key), min, max); } /** @@ -598,12 +655,12 @@ * \return value */ template <typename T> -inline T getUintRange(const nlohmann::json &json, - const std::string &key, - std::uint64_t min = std::numeric_limits<T>::min(), - std::uint64_t max = std::numeric_limits<T>::max()) noexcept +inline T get_uint_range(const nlohmann::json& json, + const std::string& key, + std::uint64_t min = std::numeric_limits<T>::min(), + std::uint64_t max = std::numeric_limits<T>::max()) noexcept { - return clamp(getUint(json, key), min, max); + return clamp(get_uint(json, key), min, max); } /** @@ -614,9 +671,11 @@ * \param def the default value * \return the string */ -inline std::string getString(const nlohmann::json &json, const std::string &key, std::string def = "") noexcept +inline std::string get_string(const nlohmann::json& json, + const std::string& key, + std::string def = "") noexcept { - return toString(get(json, key), def); + return to_string(get(json, key), def); } /** @@ -625,7 +684,7 @@ * \param value the value * \return the string */ -inline std::string pretty(const nlohmann::json &value) +inline std::string pretty(const nlohmann::json& value) { switch (value.type()) { case nlohmann::json::value_t::boolean: @@ -644,7 +703,7 @@ * \param prop the property * \return the pretty value or empty if key does not exist */ -inline std::string pretty(const nlohmann::json &object, const std::string &prop) +inline std::string pretty(const nlohmann::json& object, const std::string& prop) { auto it = object.find(prop);
--- a/libirccd-js/CMakeLists.txt Fri Aug 11 13:45:42 2017 +0200 +++ b/libirccd-js/CMakeLists.txt Tue Sep 26 17:18:47 2017 +0200 @@ -21,37 +21,37 @@ set( HEADERS ${libirccd-js_SOURCE_DIR}/irccd/duktape.hpp - ${libirccd-js_SOURCE_DIR}/irccd/mod-directory.hpp - ${libirccd-js_SOURCE_DIR}/irccd/mod-elapsed-timer.hpp - ${libirccd-js_SOURCE_DIR}/irccd/mod-file.hpp - ${libirccd-js_SOURCE_DIR}/irccd/mod-irccd.hpp - ${libirccd-js_SOURCE_DIR}/irccd/mod-logger.hpp - ${libirccd-js_SOURCE_DIR}/irccd/mod-plugin.hpp - ${libirccd-js_SOURCE_DIR}/irccd/mod-server.hpp - ${libirccd-js_SOURCE_DIR}/irccd/mod-system.hpp - ${libirccd-js_SOURCE_DIR}/irccd/mod-timer.hpp + ${libirccd-js_SOURCE_DIR}/irccd/js_directory_module.hpp + ${libirccd-js_SOURCE_DIR}/irccd/js_elapsed_timer_module.hpp + ${libirccd-js_SOURCE_DIR}/irccd/js_file_module.hpp + ${libirccd-js_SOURCE_DIR}/irccd/js_irccd_module.hpp + ${libirccd-js_SOURCE_DIR}/irccd/js_logger_module.hpp + ${libirccd-js_SOURCE_DIR}/irccd/js_plugin_module.hpp + ${libirccd-js_SOURCE_DIR}/irccd/js_server_module.hpp + ${libirccd-js_SOURCE_DIR}/irccd/js_system_module.hpp + ${libirccd-js_SOURCE_DIR}/irccd/js_timer_module.hpp ${libirccd-js_SOURCE_DIR}/irccd/module.hpp - ${libirccd-js_SOURCE_DIR}/irccd/mod-unicode.hpp - ${libirccd-js_SOURCE_DIR}/irccd/mod-util.hpp - ${libirccd-js_SOURCE_DIR}/irccd/plugin-js.hpp + ${libirccd-js_SOURCE_DIR}/irccd/js_unicode_module.hpp + ${libirccd-js_SOURCE_DIR}/irccd/js_util_module.hpp + ${libirccd-js_SOURCE_DIR}/irccd/js_plugin.hpp ${libirccd-js_SOURCE_DIR}/irccd/timer.hpp ${libirccd-js_SOURCE_DIR}/irccd/unicode.hpp ) set( SOURCES - ${libirccd-js_SOURCE_DIR}/irccd/mod-directory.cpp - ${libirccd-js_SOURCE_DIR}/irccd/mod-elapsed-timer.cpp - ${libirccd-js_SOURCE_DIR}/irccd/mod-file.cpp - ${libirccd-js_SOURCE_DIR}/irccd/mod-irccd.cpp - ${libirccd-js_SOURCE_DIR}/irccd/mod-logger.cpp - ${libirccd-js_SOURCE_DIR}/irccd/mod-plugin.cpp - ${libirccd-js_SOURCE_DIR}/irccd/mod-server.cpp - ${libirccd-js_SOURCE_DIR}/irccd/mod-system.cpp - ${libirccd-js_SOURCE_DIR}/irccd/mod-timer.cpp - ${libirccd-js_SOURCE_DIR}/irccd/mod-unicode.cpp - ${libirccd-js_SOURCE_DIR}/irccd/mod-util.cpp - ${libirccd-js_SOURCE_DIR}/irccd/plugin-js.cpp + ${libirccd-js_SOURCE_DIR}/irccd/js_directory_module.cpp + ${libirccd-js_SOURCE_DIR}/irccd/js_elapsed_timer_module.cpp + ${libirccd-js_SOURCE_DIR}/irccd/js_file_module.cpp + ${libirccd-js_SOURCE_DIR}/irccd/js_irccd_module.cpp + ${libirccd-js_SOURCE_DIR}/irccd/js_logger_module.cpp + ${libirccd-js_SOURCE_DIR}/irccd/js_plugin_module.cpp + ${libirccd-js_SOURCE_DIR}/irccd/js_server_module.cpp + ${libirccd-js_SOURCE_DIR}/irccd/js_system_module.cpp + ${libirccd-js_SOURCE_DIR}/irccd/js_timer_module.cpp + ${libirccd-js_SOURCE_DIR}/irccd/js_unicode_module.cpp + ${libirccd-js_SOURCE_DIR}/irccd/js_util_module.cpp + ${libirccd-js_SOURCE_DIR}/irccd/js_plugin.cpp ${libirccd-js_SOURCE_DIR}/irccd/timer.cpp ${libirccd-js_SOURCE_DIR}/irccd/unicode.cpp )
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libirccd-js/irccd/js_directory_module.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -0,0 +1,384 @@ +/* + * js_directory_module.cpp -- irccd.Directory API + * + * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <cerrno> +#include <cstdio> +#include <cstring> +#include <fstream> +#include <regex> +#include <stdexcept> +#include <string> + +#include <boost/filesystem.hpp> + +#include "duktape.hpp" +#include "fs.hpp" +#include "js_directory_module.hpp" +#include "js_irccd_module.hpp" +#include "js_plugin.hpp" +#include "sysconfig.hpp" + +namespace irccd { + +namespace { + +std::string path(duk_context *ctx) +{ + duk_push_this(ctx); + duk_get_prop_string(ctx, -1, "path"); + + if (duk_get_type(ctx, -1) != DUK_TYPE_STRING) + duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a Directory object"); + + auto ret = dukx_get_std_string(ctx, -1); + + if (ret.empty()) + duk_error(ctx, DUK_ERR_TYPE_ERROR, "directory object has empty path"); + + duk_pop_n(ctx, 2); + + return ret; +} + +/* + * Find an entry recursively (or not) in a directory using a predicate which can + * be used to test for regular expression, equality. + * + * Do not use this function directly, use: + * + * - find_name + * - find_regex + */ +template <typename Pred> +std::string find_path(const std::string& base, bool recursive, Pred&& pred) +{ + /* + * For performance reason, we first iterate over all entries that are + * not directories to avoid going deeper recursively if the requested + * file is in the current directory. + */ + auto entries = fs::readdir(base); + + for (const auto& entry : entries) + if (entry.type != fs::Entry::Dir && pred(entry.name)) + return base + entry.name; + + if (!recursive) + return ""; + + for (const auto& entry : entries) { + if (entry.type == fs::Entry::Dir) { + std::string next = base + entry.name + fs::separator(); + std::string path = find_path(next, true, pred); + + if (!path.empty()) + return path; + } + } + + return ""; +} + +/* + * Helper for finding by equality. + */ +std::string find_name(std::string base, const std::string& pattern, bool recursive) +{ + return find_path(base, recursive, [&] (const auto& entryname) -> bool { + return pattern == entryname; + }); +} + +/* + * Helper for finding by regular expression + */ +std::string find_regex(const std::string& base, std::string pattern, bool recursive) +{ + std::regex regexp(pattern, std::regex::ECMAScript); + std::smatch smatch; + + return find_path(base, recursive, [&] (const auto& entryname) -> bool { + return std::regex_match(entryname, smatch, regexp); + }); +} + +/* + * Generic find function for: + * + * - Directory.find + * - Directory.prototype.find + * + * The patternIndex is the argument where to test if the argument is a regex or + * a string. + */ +duk_ret_t find(duk_context* ctx, std::string base, bool recursive, int pattern_index) +{ + try { + std::string path; + + if (duk_is_string(ctx, pattern_index)) + path = find_name(base, duk_get_string(ctx, pattern_index), recursive); + else { + // Check if it's a valid RegExp object. + duk_get_global_string(ctx, "RegExp"); + auto is_regex = duk_instanceof(ctx, pattern_index, -1); + duk_pop(ctx); + + if (is_regex) { + duk_get_prop_string(ctx, pattern_index, "source"); + auto pattern = duk_to_string(ctx, -1); + duk_pop(ctx); + + path = find_regex(base, pattern, recursive); + } else + duk_error(ctx, DUK_ERR_TYPE_ERROR, "pattern must be a string or a regex expression"); + } + + if (path.empty()) + return 0; + + dukx_push_std_string(ctx, path); + } catch (const std::exception& ex) { + duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); + } + + return 1; +} + +/* + * Generic remove function for: + * + * - Directory.remove + * - Directory.prototype.remove + */ +duk_ret_t remove(duk_context* ctx, const std::string& path, bool recursive) +{ + boost::system::error_code ec; + + if (!boost::filesystem::is_directory(path, ec) || ec) + dukx_throw(ctx, system_error(EINVAL, "not a directory")); + + if (!recursive) + boost::filesystem::remove(path, ec); + else + boost::filesystem::remove_all(path, ec); + + return 0; +} + +/* + * Method: Directory.find(pattern, recursive) + * -------------------------------------------------------- + * + * Synonym of Directory.find(path, pattern, recursive) but the path is taken + * from the directory object. + * + * Arguments: + * - pattern, the regular expression or file name, + * - recursive, set to true to search recursively (default: false). + * Returns: + * The path to the file or undefined if not found. + * Throws: + * - Any exception on error. + */ +duk_ret_t method_find(duk_context* ctx) +{ + return find(ctx, path(ctx), duk_get_boolean(ctx, 1), 0); +} + +/* + * Method: Directory.remove(recursive) + * -------------------------------------------------------- + * + * Synonym of Directory.remove(recursive) but the path is taken from the + * directory object. + * + * Arguments: + * - recursive, recursively or not (default: false). + * Throws: + * - Any exception on error. + */ +duk_ret_t method_remove(duk_context* ctx) +{ + return remove(ctx, path(ctx), duk_get_boolean(ctx, 0)); +} + +const duk_function_list_entry methods[] = { + { "find", method_find, DUK_VARARGS }, + { "remove", method_remove, 1 }, + { nullptr, nullptr, 0 } +}; + +/* + * Directory "static" functions + * ------------------------------------------------------------------ + */ + +/* + * Function: irccd.Directory(path, flags) [constructor] + * -------------------------------------------------------- + * + * Opens and read the directory at the specified path. + * + * Arguments: + * - path, the path to the directory, + * - flags, the optional flags (default: 0). + * Throws: + * - Any exception on error + */ +duk_ret_t constructor(duk_context* ctx) +{ + if (!duk_is_constructor_call(ctx)) + return 0; + + try { + auto path = duk_require_string(ctx, 0); + auto flags = duk_get_uint(ctx, 1); + + if (!boost::filesystem::is_directory(path)) + dukx_throw(ctx, system_error(EINVAL, "not a directory")); + + auto list = fs::readdir(path, flags); + + duk_push_this(ctx); + duk_push_string(ctx, "count"); + duk_push_int(ctx, list.size()); + duk_def_prop(ctx, -3, DUK_DEFPROP_ENUMERABLE | DUK_DEFPROP_HAVE_VALUE); + duk_push_string(ctx, "path"); + dukx_push_std_string(ctx, path); + duk_def_prop(ctx, -3, DUK_DEFPROP_ENUMERABLE | DUK_DEFPROP_HAVE_VALUE); + duk_push_string(ctx, "entries"); + duk_push_array(ctx); + + for (unsigned i = 0; i < list.size(); ++i) { + duk_push_object(ctx); + dukx_push_std_string(ctx, list[i].name); + duk_put_prop_string(ctx, -2, "name"); + duk_push_int(ctx, list[i].type); + duk_put_prop_string(ctx, -2, "type"); + duk_put_prop_index(ctx, -2, i); + } + + duk_def_prop(ctx, -3, DUK_DEFPROP_ENUMERABLE | DUK_DEFPROP_HAVE_VALUE); + } catch (const std::exception& ex) { + dukx_throw(ctx, system_error(errno, ex.what())); + } + + return 0; +} + +/* + * Function: irccd.Directory.find(path, pattern, recursive) + * -------------------------------------------------------- + * + * Find an entry by a pattern or a regular expression. + * + * Arguments: + * - path, the base path, + * - pattern, the regular expression or file name, + * - recursive, set to true to search recursively (default: false). + * Returns: + * The path to the file or undefined on errors or not found. + */ +duk_ret_t func_find(duk_context* ctx) +{ + return find(ctx, duk_require_string(ctx, 0), duk_get_boolean(ctx, 2), 1); +} + +/* + * Function: irccd.Directory.remove(path, recursive) + * -------------------------------------------------------- + * + * Remove the directory optionally recursively. + * + * Arguments: + * - path, the path to the directory, + * - recursive, recursively or not (default: false). + * Throws: + * - Any exception on error. + */ +duk_ret_t func_remove(duk_context *ctx) +{ + return remove(ctx, duk_require_string(ctx, 0), duk_get_boolean(ctx, 1)); +} + +/* + * Function: irccd.Directory.mkdir(path, mode = 0700) + * -------------------------------------------------------- + * + * Create a directory specified by path. It will create needed subdirectories + * just like you have invoked mkdir -p. + * + * Arguments: + * - path, the path to the directory, + * Throws: + * - Any exception on error. + */ +duk_ret_t func_mkdir(duk_context *ctx) +{ + try { + boost::filesystem::create_directories(duk_require_string(ctx, 0)); + } catch (const std::exception &ex) { + dukx_throw(ctx, system_error(errno, ex.what())); + } + + return 0; +} + +const duk_function_list_entry functions[] = { + { "find", func_find, DUK_VARARGS }, + { "mkdir", func_mkdir, DUK_VARARGS }, + { "remove", func_remove, DUK_VARARGS }, + { nullptr, nullptr, 0 } +}; + +const duk_number_list_entry constants[] = { + { "Dot", static_cast<int>(fs::Dot) }, + { "DotDot", static_cast<int>(fs::DotDot) }, + { "TypeUnknown", static_cast<int>(fs::Entry::Unknown) }, + { "TypeDir", static_cast<int>(fs::Entry::Dir) }, + { "TypeFile", static_cast<int>(fs::Entry::File) }, + { "TypeLink", static_cast<int>(fs::Entry::Link) }, + { nullptr, 0 } +}; + +} // !namespace + +js_directory_module::js_directory_module() noexcept + : module("Irccd.Directory") +{ +} + +void js_directory_module::load(irccd&, std::shared_ptr<js_plugin> plugin) +{ + StackAssert sa(plugin->context()); + + duk_get_global_string(plugin->context(), "Irccd"); + duk_push_c_function(plugin->context(), constructor, 2); + duk_put_number_list(plugin->context(), -1, constants); + duk_put_function_list(plugin->context(), -1, functions); + dukx_push_std_string(plugin->context(), std::string{fs::separator()}); + duk_put_prop_string(plugin->context(), -2, "separator"); + duk_push_object(plugin->context()); + duk_put_function_list(plugin->context(), -1, methods); + duk_put_prop_string(plugin->context(), -2, "prototype"); + duk_put_prop_string(plugin->context(), -2, "Directory"); + duk_pop(plugin->context()); +} + +} // !irccd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libirccd-js/irccd/js_directory_module.hpp Tue Sep 26 17:18:47 2017 +0200 @@ -0,0 +1,50 @@ +/* + * js_directory_module.hpp -- irccd.Directory API + * + * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef IRCCD_JS_DIRECTORY_MODULE_HPP +#define IRCCD_JS_DIRECTORY_MODULE_HPP + +/** + * \file mod-directory.hpp + * \brief irccd.Directory JavaScript API. + */ + +#include "module.hpp" + +namespace irccd { + +/** + * \brief irccd.Directory JavaScript API. + * \ingroup modules + */ +class js_directory_module : public module { +public: + /** + * Constructor. + */ + js_directory_module() noexcept; + + /** + * \copydoc Module::load + */ + void load(irccd &irccd, std::shared_ptr<js_plugin> plugin) override; +}; + +} // !irccd + +#endif // !IRCCD_JS_DIRECTORY_MODULE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libirccd-js/irccd/js_elapsed_timer_module.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -0,0 +1,162 @@ +/* + * js_elapsed_timer_module.cpp -- irccd.ElapsedTimer API + * + * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <irccd/elapsed-timer.hpp> +#include <irccd/js_plugin.hpp> + +#include "js_elapsed_timer_module.hpp" + +namespace irccd { + +namespace { + +const char* signature("\xff""\xff""irccd-elapsed-timer-ptr"); + +ElapsedTimer* self(duk_context* ctx) +{ + StackAssert sa(ctx); + + duk_push_this(ctx); + duk_get_prop_string(ctx, -1, signature); + auto ptr = static_cast<ElapsedTimer*>(duk_to_pointer(ctx, -1)); + duk_pop_2(ctx); + + if (!ptr) + duk_error(ctx, DUK_ERR_TYPE_ERROR, "not an ElapsedTimer object"); + + return ptr; +} + +/* + * Method: ElapsedTimer.pause + * ------------------------------------------------------------------ + * + * Pause the timer, without resetting the current elapsed time stored. + */ +duk_ret_t pause(duk_context* ctx) +{ + self(ctx)->pause(); + + return 0; +} + +/* + * Method: ElapsedTimer.reset + * ------------------------------------------------------------------ + * + * Reset the elapsed time to 0, the status is not modified. + */ +duk_ret_t reset(duk_context* ctx) +{ + self(ctx)->reset(); + + return 0; +} + +/* + * Method: ElapsedTimer.restart + * ------------------------------------------------------------------ + * + * Restart the timer without resetting the current elapsed time. + */ +duk_ret_t restart(duk_context* ctx) +{ + self(ctx)->restart(); + + return 0; +} + +/* + * Method: ElapsedTimer.elapsed + * ------------------------------------------------------------------ + * + * Get the number of elapsed milliseconds. + * + * Returns: + * The time elapsed. + */ +duk_ret_t elapsed(duk_context* ctx) +{ + duk_push_uint(ctx, self(ctx)->elapsed()); + + return 1; +} + +/* + * Function: Irccd.ElapsedTimer() [constructor] + * ------------------------------------------------------------------ + * + * Construct a new ElapsedTimer object. + */ +duk_ret_t constructor(duk_context* ctx) +{ + duk_push_this(ctx); + duk_push_pointer(ctx, new ElapsedTimer); + duk_put_prop_string(ctx, -2, signature); + duk_pop(ctx); + + return 0; +} + +/* + * Function: irccd.ElapsedTimer() [destructor] + * ------------------------------------------------------------------ + * + * Delete the property. + */ +duk_ret_t destructor(duk_context* ctx) +{ + duk_get_prop_string(ctx, 0, signature); + delete static_cast<ElapsedTimer*>(duk_to_pointer(ctx, -1)); + duk_pop(ctx); + duk_del_prop_string(ctx, 0, signature); + + return 0; +} + +const duk_function_list_entry methods[] = { + { "elapsed", elapsed, 0 }, + { "pause", pause, 0 }, + { "reset", reset, 0 }, + { "restart", restart, 0 }, + { nullptr, nullptr, 0 } +}; + +} // !namespace + +js_elapsed_timer_module::js_elapsed_timer_module() noexcept + : module("Irccd.ElapsedTimer") +{ +} + +void js_elapsed_timer_module::load(irccd&, std::shared_ptr<js_plugin> plugin) +{ + StackAssert sa(plugin->context()); + + duk_get_global_string(plugin->context(), "Irccd"); + duk_push_c_function(plugin->context(), constructor, 0); + duk_push_object(plugin->context()); + duk_put_function_list(plugin->context(), -1, methods); + duk_push_c_function(plugin->context(), destructor, 1); + duk_set_finalizer(plugin->context(), -2); + duk_put_prop_string(plugin->context(), -2, "prototype"); + duk_put_prop_string(plugin->context(), -2, "ElapsedTimer"); + duk_pop(plugin->context()); +} + +} // !irccd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libirccd-js/irccd/js_elapsed_timer_module.hpp Tue Sep 26 17:18:47 2017 +0200 @@ -0,0 +1,50 @@ +/* + * js_elapsed_timer_module.hpp -- irccd.ElapsedTimer API + * + * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef IRCCD_JS_ELAPSED_TIMER_MODULE_HPP +#define IRCCD_JS_ELAPSED_TIMER_MODULE_HPP + +/** + * \file js_elapsed_timer_module.hpp + * \brief irccd.ElapsedTimer JavaScript API. + */ + +#include "module.hpp" + +namespace irccd { + +/** + * \brief Irccd.ElapsedTimer JavaScript API. + * \ingroup Javascript modules + */ +class js_elapsed_timer_module : public module { +public: + /** + * Constructor. + */ + js_elapsed_timer_module() noexcept; + + /** + * \copydoc module::load + */ + void load(irccd& irccd, std::shared_ptr<js_plugin> plugin) override; +}; + +} // !irccd + +#endif // !IRCCD_JS_ELAPSED_TIMER_MODULE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libirccd-js/irccd/js_file_module.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -0,0 +1,700 @@ +/* + * js_file_module.cpp -- Irccd.File API + * + * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <algorithm> +#include <array> +#include <cassert> +#include <iterator> +#include <vector> + +#include <boost/filesystem.hpp> + +#include <irccd/sysconfig.hpp> + +#if defined(HAVE_STAT) +# include <sys/types.h> +# include <sys/stat.h> +#endif + +#include <irccd/fs.hpp> +#include <irccd/js_plugin.hpp> + +#include "js_file_module.hpp" +#include "js_irccd_module.hpp" + +namespace irccd { + +namespace { + +const char *signature("\xff""\xff""irccd-file-ptr"); +const char *prototype("\xff""\xff""irccd-file-prototype"); + +#if defined(HAVE_STAT) + +/* + * push_stat + * ------------------------------------------------------------------ + */ + +void push_stat(duk_context* ctx, const struct stat& st) +{ + StackAssert sa(ctx, 1); + + duk_push_object(ctx); + +#if defined(HAVE_STAT_ST_ATIME) + duk_push_int(ctx, st.st_atime); + duk_put_prop_string(ctx, -2, "atime"); +#endif +#if defined(HAVE_STAT_ST_BLKSIZE) + duk_push_int(ctx, st.st_blksize); + duk_put_prop_string(ctx, -2, "blksize"); +#endif +#if defined(HAVE_STAT_ST_BLOCKS) + duk_push_int(ctx, st.st_blocks); + duk_put_prop_string(ctx, -2, "blocks"); +#endif +#if defined(HAVE_STAT_ST_CTIME) + duk_push_int(ctx, st.st_ctime); + duk_put_prop_string(ctx, -2, "ctime"); +#endif +#if defined(HAVE_STAT_ST_DEV) + duk_push_int(ctx, st.st_dev); + duk_put_prop_string(ctx, -2, "dev"); +#endif +#if defined(HAVE_STAT_ST_GID) + duk_push_int(ctx, st.st_gid); + duk_put_prop_string(ctx, -2, "gid"); +#endif +#if defined(HAVE_STAT_ST_INO) + duk_push_int(ctx, st.st_ino); + duk_put_prop_string(ctx, -2, "ino"); +#endif +#if defined(HAVE_STAT_ST_MODE) + duk_push_int(ctx, st.st_mode); + duk_put_prop_string(ctx, -2, "mode"); +#endif +#if defined(HAVE_STAT_ST_MTIME) + duk_push_int(ctx, st.st_mtime); + duk_put_prop_string(ctx, -2, "mtime"); +#endif +#if defined(HAVE_STAT_ST_NLINK) + duk_push_int(ctx, st.st_nlink); + duk_put_prop_string(ctx, -2, "nlink"); +#endif +#if defined(HAVE_STAT_ST_RDEV) + duk_push_int(ctx, st.st_rdev); + duk_put_prop_string(ctx, -2, "rdev"); +#endif +#if defined(HAVE_STAT_ST_SIZE) + duk_push_int(ctx, st.st_size); + duk_put_prop_string(ctx, -2, "size"); +#endif +#if defined(HAVE_STAT_ST_UID) + duk_push_int(ctx, st.st_uid); + duk_put_prop_string(ctx, -2, "uid"); +#endif +} + +#endif // !HAVE_STAT + +// Remove trailing \r for CRLF line style. +inline std::string clear_crlf(std::string input) +{ + if (input.length() > 0 && input.back() == '\r') + input.pop_back(); + + return input; +} + +file* self(duk_context* ctx) +{ + StackAssert sa(ctx); + + duk_push_this(ctx); + duk_get_prop_string(ctx, -1, signature); + auto ptr = static_cast<file*>(duk_to_pointer(ctx, -1)); + duk_pop_2(ctx); + + if (!ptr) + duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a File object"); + + return ptr; +} + +/* + * File methods. + * ------------------------------------------------------------------ + */ + +/* + * Method: File.basename() + * -------------------------------------------------------- + * + * Synonym of `irccd.File.basename(path)` but with the path from the file. + * + * duk_ret_turns: + * The base name. + */ +duk_ret_t method_basename(duk_context* ctx) +{ + dukx_push_std_string(ctx, fs::baseName(self(ctx)->path())); + + return 1; +} + +/* + * Method: File.close() + * -------------------------------------------------------- + * + * Force close of the file, automatically called when object is collected. + */ +duk_ret_t method_close(duk_context* ctx) +{ + self(ctx)->close(); + + return 0; +} + +/* + * Method: File.dirname() + * -------------------------------------------------------- + * + * Synonym of `irccd.File.dirname(path)` but with the path from the file. + * + * duk_ret_turns: + * The directory name. + */ +duk_ret_t method_dirname(duk_context* ctx) +{ + dukx_push_std_string(ctx, fs::dirName(self(ctx)->path())); + + return 1; +} + +/* + * Method: File.lines() + * -------------------------------------------------------- + * + * Read all lines and return an array. + * + * duk_ret_turns: + * An array with all lines. + * Throws + * - Any exception on error. + */ +duk_ret_t method_lines(duk_context* ctx) +{ + duk_push_array(ctx); + + std::FILE* fp = self(ctx)->handle(); + std::string buffer; + std::array<char, 128> data; + std::int32_t i = 0; + + while (std::fgets(&data[0], data.size(), fp) != nullptr) { + buffer += data.data(); + + auto pos = buffer.find('\n'); + + if (pos != std::string::npos) { + dukx_push_std_string(ctx, clear_crlf(buffer.substr(0, pos))); + duk_put_prop_index(ctx, -2, i++); + + buffer.erase(0, pos + 1); + } + } + + // Maybe an error in the stream. + if (std::ferror(fp)) + dukx_throw(ctx, system_error()); + + // Missing '\n' in end of file. + if (!buffer.empty()) { + dukx_push_std_string(ctx, clear_crlf(buffer)); + duk_put_prop_index(ctx, -2, i++); + } + + return 1; +} + +/* + * Method: File.read(amount) + * -------------------------------------------------------- + * + * Read the specified amount of characters or the whole file. + * + * Arguments: + * - amount, the amount of characters or -1 to read all (Optional, default: -1). + * duk_ret_turns: + * The string. + * Throws: + * - Any exception on error. + */ +duk_ret_t method_read(duk_context* ctx) +{ + auto file = self(ctx); + auto amount = duk_is_number(ctx, 0) ? duk_get_int(ctx, 0) : -1; + + if (amount == 0 || file->handle() == nullptr) + return 0; + + try { + std::string data; + std::size_t total = 0; + + if (amount < 0) { + std::array<char, 128> buffer; + std::size_t nread; + + while ((nread = std::fread(&buffer[0], sizeof (buffer[0]), buffer.size(), file->handle())) > 0) { + if (std::ferror(file->handle())) + dukx_throw(ctx, system_error()); + + std::copy(buffer.begin(), buffer.begin() + nread, std::back_inserter(data)); + total += nread; + } + } else { + data.resize((std::size_t)amount); + total = std::fread(&data[0], sizeof (data[0]), (std::size_t)amount, file->handle()); + + if (std::ferror(file->handle())) + dukx_throw(ctx, system_error()); + + data.resize(total); + } + + dukx_push_std_string(ctx, data); + } catch (const std::exception&) { + dukx_throw(ctx, system_error()); + } + + return 1; +} + +/* + * Method: File.readline() + * -------------------------------------------------------- + * + * Read the next line available. + * + * duk_ret_turns: + * The next line or undefined if eof. + * Throws: + * - Any exception on error. + */ +duk_ret_t method_readline(duk_context* ctx) +{ + std::FILE* fp = self(ctx)->handle(); + std::string result; + + if (fp == nullptr || std::feof(fp)) + return 0; + for (int ch; (ch = std::fgetc(fp)) != EOF && ch != '\n'; ) + result += (char)ch; + if (std::ferror(fp)) + dukx_throw(ctx, system_error()); + + dukx_push_std_string(ctx, clear_crlf(result)); + + return 1; +} + +/* + * Method: File.remove() + * -------------------------------------------------------- + * + * Synonym of File.remove(path) but with the path from the file. + * + * Throws: + * - Any exception on error. + */ +duk_ret_t method_remove(duk_context* ctx) +{ + if (::remove(self(ctx)->path().c_str()) < 0) + dukx_throw(ctx, system_error()); + + return 0; +} + +/* + * Method: File.seek(type, amount) + * -------------------------------------------------------- + * + * Sets the position in the file. + * + * Arguments: + * - type, the type of setting (File.SeekSet, File.SeekCur, File.SeekSet), + * - amount, the new offset. + * Throws: + * - Any exception on error. + */ +duk_ret_t method_seek(duk_context* ctx) +{ + auto fp = self(ctx)->handle(); + auto type = duk_require_int(ctx, 0); + auto amount = duk_require_int(ctx, 1); + + if (fp != nullptr && std::fseek(fp, amount, type) != 0) + dukx_throw(ctx, system_error()); + + return 0; +} + +#if defined(HAVE_STAT) + +/* + * Method: File.stat() [optional] + * -------------------------------------------------------- + * + * Synonym of File.stat(path) but with the path from the file. + * + * duk_ret_turns: + * The stat information. + * Throws: + * - Any exception on error. + */ +duk_ret_t method_stat(duk_context* ctx) +{ + auto file = self(ctx); + struct stat st; + + if (file->handle() == nullptr && ::stat(file->path().c_str(), &st) < 0) + dukx_throw(ctx, system_error()); + else + push_stat(ctx, st); + + return 1; +} + +#endif // !HAVE_STAT + +/* + * Method: File.tell() + * -------------------------------------------------------- + * + * Get the actual position in the file. + * + * duk_ret_turns: + * The position. + * Throws: + * - Any exception on error. + */ +duk_ret_t method_tell(duk_context* ctx) +{ + auto fp = self(ctx)->handle(); + long pos; + + if (fp == nullptr) + return 0; + + if ((pos = std::ftell(fp)) == -1L) + dukx_throw(ctx, system_error()); + else + duk_push_int(ctx, pos); + + return 1; +} + +/* + * Method: File.write(data) + * -------------------------------------------------------- + * + * Write some characters to the file. + * + * Arguments: + * - data, the character to write. + * duk_ret_turns: + * The number of bytes written. + * Throws: + * - Any exception on error. + */ +duk_ret_t method_write(duk_context* ctx) +{ + std::FILE* fp = self(ctx)->handle(); + std::string data = duk_require_string(ctx, 0); + + if (fp == nullptr) + return 0; + + auto nwritten = std::fwrite(data.c_str(), 1, data.length(), fp); + + if (std::ferror(fp)) + dukx_throw(ctx, system_error()); + + duk_push_uint(ctx, nwritten); + + return 1; +} + +const duk_function_list_entry methods[] = { + { "basename", method_basename, 0 }, + { "close", method_close, 0 }, + { "dirname", method_dirname, 0 }, + { "lines", method_lines, 0 }, + { "read", method_read, 1 }, + { "readline", method_readline, 0 }, + { "remove", method_remove, 0 }, + { "seek", method_seek, 2 }, +#if defined(HAVE_STAT) + { "stat", method_stat, 0 }, +#endif + { "tell", method_tell, 0 }, + { "write", method_write, 1 }, + { nullptr, nullptr, 0 } +}; + +/* + * File "static" functions + * ------------------------------------------------------------------ + */ + +/* + * Function: Irccd.File(path, mode) [constructor] + * -------------------------------------------------------- + * + * Open a file specified by path with the specified mode. + * + * Arguments: + * - path, the path to the file, + * - mode, the mode string. + * Throws: + * - Any exception on error. + */ +duk_ret_t constructor(duk_context* ctx) +{ + if (!duk_is_constructor_call(ctx)) + return 0; + + try { + dukx_new_file(ctx, new file(duk_require_string(ctx, 0), duk_require_string(ctx, 1))); + } catch (const std::exception &) { + dukx_throw(ctx, system_error()); + } + + return 0; +} + +/* + * Function: Irccd.File() [destructor] + * ------------------------------------------------------------------ + * + * Delete the property. + */ +duk_ret_t destructor(duk_context* ctx) +{ + duk_get_prop_string(ctx, 0, signature); + delete static_cast<file*>(duk_to_pointer(ctx, -1)); + duk_pop(ctx); + duk_del_prop_string(ctx, 0, signature); + + return 0; +} + +/* + * Function: Irccd.File.basename(path) + * -------------------------------------------------------- + * + * duk_ret_turn the file basename as specified in `basename(3)` C function. + * + * Arguments: + * - path, the path to the file. + * duk_ret_turns: + * The base name. + */ +duk_ret_t function_basename(duk_context* ctx) +{ + dukx_push_std_string(ctx, fs::baseName(duk_require_string(ctx, 0))); + + return 1; +} + +/* + * Function: Irccd.File.dirname(path) + * -------------------------------------------------------- + * + * duk_ret_turn the file directory name as specified in `dirname(3)` C function. + * + * Arguments: + * - path, the path to the file. + * duk_ret_turns: + * The directory name. + */ +duk_ret_t function_dirname(duk_context* ctx) +{ + dukx_push_std_string(ctx, fs::dirName(duk_require_string(ctx, 0))); + + return 1; +} + +/* + * Function: Irccd.File.exists(path) + * -------------------------------------------------------- + * + * Check if the file exists. + * + * Arguments: + * - path, the path to the file. + * duk_ret_turns: + * True if exists. + * Throws: + * - Any exception if we don't have access. + */ +duk_ret_t function_exists(duk_context* ctx) +{ + try { + duk_push_boolean(ctx, boost::filesystem::exists(duk_require_string(ctx, 0))); + } catch (...) { + duk_push_boolean(ctx, false); + } + + return 1; +} + +/* + * function Irccd.File.remove(path) + * -------------------------------------------------------- + * + * Remove the file at the specified path. + * + * Arguments: + * - path, the path to the file. + * Throws: + * - Any exception on error. + */ +duk_ret_t function_remove(duk_context* ctx) +{ + if (::remove(duk_require_string(ctx, 0)) < 0) + dukx_throw(ctx, system_error()); + + return 0; +} + +#if defined(HAVE_STAT) + +/* + * function Irccd.File.stat(path) [optional] + * -------------------------------------------------------- + * + * Get file information at the specified path. + * + * Arguments: + * - path, the path to the file. + * duk_ret_turns: + * The stat information. + * Throws: + * - Any exception on error. + */ +duk_ret_t function_stat(duk_context* ctx) +{ + struct stat st; + + if (::stat(duk_require_string(ctx, 0), &st) < 0) + dukx_throw(ctx, system_error()); + + push_stat(ctx, st); + + return 1; +} + +#endif // !HAVE_STAT + +const duk_function_list_entry functions[] = { + { "basename", function_basename, 1 }, + { "dirname", function_dirname, 1 }, + { "exists", function_exists, 1 }, + { "remove", function_remove, 1 }, +#if defined(HAVE_STAT) + { "stat", function_stat, 1 }, +#endif + { nullptr, nullptr, 0 } +}; + +const duk_number_list_entry constants[] = { + { "SeekCur", SEEK_CUR }, + { "SeekEnd", SEEK_END }, + { "SeekSet", SEEK_SET }, + { nullptr, 0 } +}; + +} // !namespace + +js_file_module::js_file_module() noexcept + : module("Irccd.File") +{ +} + +void js_file_module::load(irccd&, std::shared_ptr<js_plugin> plugin) +{ + StackAssert sa(plugin->context()); + + duk_get_global_string(plugin->context(), "Irccd"); + duk_push_c_function(plugin->context(), constructor, 2); + duk_put_number_list(plugin->context(), -1, constants); + duk_put_function_list(plugin->context(), -1, functions); + duk_push_object(plugin->context()); + duk_put_function_list(plugin->context(), -1, methods); + duk_push_c_function(plugin->context(), destructor, 1); + duk_set_finalizer(plugin->context(), -2); + duk_dup(plugin->context(), -1); + duk_put_global_string(plugin->context(), prototype); + duk_put_prop_string(plugin->context(), -2, "prototype"); + duk_put_prop_string(plugin->context(), -2, "File"); + duk_pop(plugin->context()); +} + +void dukx_new_file(duk_context* ctx, file* fp) +{ + assert(ctx); + assert(fp); + + StackAssert sa(ctx); + + duk_push_this(ctx); + duk_push_pointer(ctx, fp); + duk_put_prop_string(ctx, -2, signature); + duk_pop(ctx); +} + +void dukx_push_file(duk_context* ctx, file* fp) +{ + assert(ctx); + assert(fp); + + StackAssert sa(ctx, 1); + + duk_push_object(ctx); + duk_push_pointer(ctx, fp); + duk_put_prop_string(ctx, -2, signature); + duk_get_global_string(ctx, prototype); + duk_set_prototype(ctx, -2); +} + +file* dukx_require_file(duk_context* ctx, duk_idx_t index) +{ + if (!duk_is_object(ctx, index) || !duk_has_prop_string(ctx, index, signature)) + duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a File object"); + + duk_get_prop_string(ctx, index, signature); + auto fp = static_cast<file*>(duk_to_pointer(ctx, -1)); + duk_pop(ctx); + + return fp; +} + +} // !irccd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libirccd-js/irccd/js_file_module.hpp Tue Sep 26 17:18:47 2017 +0200 @@ -0,0 +1,184 @@ +/* + * js_file_module.hpp -- Irccd.File API + * + * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef IRCCD_JS_FILE_MODULE_HPP +#define IRCCD_JS_FILE_MODULE_HPP + +/** + * \file js_file_module.hpp + * \brief Irccd.File JavaScript API. + */ + +#include <cassert> +#include <cerrno> +#include <cstdio> +#include <cstring> +#include <functional> +#include <stdexcept> +#include <string> + +#include "duktape.hpp" +#include "module.hpp" + +namespace irccd { + +/** + * \brief Object for Javascript to perform I/O. + * + * This class can be constructed to Javascript. + * + * It is used in: + * + * - Irccd.File [constructor] + * - Irccd.System.popen (optional) + */ +class file { +private: + file(const file&) = delete; + file& operator=(const file&) = delete; + + file(file&&) = delete; + file& operator=(file&&) = delete; + +private: + std::string path_; + std::FILE *stream_; + std::function<void (std::FILE*)> destructor_; + +public: + /** + * Construct a file specified by path + * + * \param path the path + * \param mode the mode string (for std::fopen) + * \throw std::runtime_error on failures + */ + inline file(std::string path, const std::string& mode) + : path_(std::move(path)) + , destructor_([] (std::FILE* fp) { std::fclose(fp); }) + { + if ((stream_ = std::fopen(path_.c_str(), mode.c_str())) == nullptr) + throw std::runtime_error(std::strerror(errno)); + } + + /** + * Construct a file from a already created FILE pointer (e.g. popen). + * + * The class takes ownership of fp and will close it. + * + * \pre destructor must not be null + * \param fp the file pointer + * \param destructor the function to close fp (e.g. std::fclose) + */ + inline file(std::FILE* fp, std::function<void (std::FILE*)> destructor) noexcept + : stream_(fp) + , destructor_(std::move(destructor)) + { + assert(destructor_ != nullptr); + } + + /** + * Closes the file. + */ + virtual ~file() noexcept + { + close(); + } + + /** + * Get the path. + * + * \return the path + * \warning empty when constructed from the FILE constructor + */ + inline const std::string& path() const noexcept + { + return path_; + } + + /** + * Get the handle. + * + * \return the handle or nullptr if the stream was closed + */ + inline std::FILE* handle() noexcept + { + return stream_; + } + + /** + * Force close, can be safely called multiple times. + */ + inline void close() noexcept + { + if (stream_) { + destructor_(stream_); + stream_ = nullptr; + } + } +}; + +/** + * \brief Irccd.File JavaScript API. + * \ingroup modules + */ +class js_file_module : public module { +public: + /** + * Constructor. + */ + js_file_module() noexcept; + + /** + * \copydoc Module::load + */ + void load(irccd& irccd, std::shared_ptr<js_plugin> plugin) override; +}; + +/** + * Construct the file as this. + * + * The object prototype takes ownership of fp and will be deleted once + * collected. + * + * \pre fp != nullptr + * \param ctx the the context + * \param fp the file + */ +IRCCD_EXPORT void dukx_new_file(duk_context* ctx, file* fp); + +/** + * Push a file. + * + * \pre fp != nullptr + * \param ctx the the context + * \param fp the file + */ +IRCCD_EXPORT void dukx_push_file(duk_context* ctx, file* fp); + +/** + * Require a file. Raises a JavaScript error if not a File. + * + * \param ctx the context + * \param index the index + */ +IRCCD_EXPORT file* dukx_require_file(duk_context* ctx, duk_idx_t index); + +} // !irccd + +#endif // !IRCCD_JS_FILE_MODULE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libirccd-js/irccd/js_irccd_module.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -0,0 +1,232 @@ +/* + * js_irccd_module.cpp -- Irccd API + * + * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <cerrno> +#include <string> +#include <unordered_map> + +#include <irccd/js_plugin.hpp> +#include <irccd/sysconfig.hpp> + +#include "js_irccd_module.hpp" + +namespace irccd { + +namespace { + +const std::unordered_map<std::string, int> errors{ + { "E2BIG", E2BIG }, + { "EACCES", EACCES }, + { "EADDRINUSE", EADDRINUSE }, + { "EADDRNOTAVAIL", EADDRNOTAVAIL }, + { "EAFNOSUPPORT", EAFNOSUPPORT }, + { "EAGAIN", EAGAIN }, + { "EALREADY", EALREADY }, + { "EBADF", EBADF }, +#if defined(EBADMSG) + { "EBADMSG", EBADMSG }, +#endif + { "EBUSY", EBUSY }, + { "ECANCELED", ECANCELED }, + { "ECHILD", ECHILD }, + { "ECONNABORTED", ECONNABORTED }, + { "ECONNREFUSED", ECONNREFUSED }, + { "ECONNRESET", ECONNRESET }, + { "EDEADLK", EDEADLK }, + { "EDESTADDRREQ", EDESTADDRREQ }, + { "EDOM", EDOM }, + { "EEXIST", EEXIST }, + { "EFAULT", EFAULT }, + { "EFBIG", EFBIG }, + { "EHOSTUNREACH", EHOSTUNREACH }, +#if defined(EIDRM) + { "EIDRM", EIDRM }, +#endif + { "EILSEQ", EILSEQ }, + { "EINPROGRESS", EINPROGRESS }, + { "EINTR", EINTR }, + { "EINVAL", EINVAL }, + { "EIO", EIO }, + { "EISCONN", EISCONN }, + { "EISDIR", EISDIR }, + { "ELOOP", ELOOP }, + { "EMFILE", EMFILE }, + { "EMLINK", EMLINK }, + { "EMSGSIZE", EMSGSIZE }, + { "ENAMETOOLONG", ENAMETOOLONG }, + { "ENETDOWN", ENETDOWN }, + { "ENETRESET", ENETRESET }, + { "ENETUNREACH", ENETUNREACH }, + { "ENFILE", ENFILE }, + { "ENOBUFS", ENOBUFS }, +#if defined(ENODATA) + { "ENODATA", ENODATA }, +#endif + { "ENODEV", ENODEV }, + { "ENOENT", ENOENT }, + { "ENOEXEC", ENOEXEC }, + { "ENOLCK", ENOLCK }, +#if defined(ENOLINK) + { "ENOLINK", ENOLINK }, +#endif + { "ENOMEM", ENOMEM }, +#if defined(ENOMSG) + { "ENOMSG", ENOMSG }, +#endif + { "ENOPROTOOPT", ENOPROTOOPT }, + { "ENOSPC", ENOSPC }, +#if defined(ENOSR) + { "ENOSR", ENOSR }, +#endif +#if defined(ENOSTR) + { "ENOSTR", ENOSTR }, +#endif + { "ENOSYS", ENOSYS }, + { "ENOTCONN", ENOTCONN }, + { "ENOTDIR", ENOTDIR }, + { "ENOTEMPTY", ENOTEMPTY }, +#if defined(ENOTRECOVERABLE) + { "ENOTRECOVERABLE", ENOTRECOVERABLE }, +#endif + { "ENOTSOCK", ENOTSOCK }, + { "ENOTSUP", ENOTSUP }, + { "ENOTTY", ENOTTY }, + { "ENXIO", ENXIO }, + { "EOPNOTSUPP", EOPNOTSUPP }, + { "EOVERFLOW", EOVERFLOW }, + { "EOWNERDEAD", EOWNERDEAD }, + { "EPERM", EPERM }, + { "EPIPE", EPIPE }, + { "EPROTO", EPROTO }, + { "EPROTONOSUPPORT", EPROTONOSUPPORT }, + { "EPROTOTYPE", EPROTOTYPE }, + { "ERANGE", ERANGE }, + { "EROFS", EROFS }, + { "ESPIPE", ESPIPE }, + { "ESRCH", ESRCH }, +#if defined(ETIME) + { "ETIME", ETIME }, +#endif + { "ETIMEDOUT", ETIMEDOUT }, +#if defined(ETXTBSY) + { "ETXTBSY", ETXTBSY }, +#endif + { "EWOULDBLOCK", EWOULDBLOCK }, + { "EXDEV", EXDEV } +}; + +duk_ret_t constructor(duk_context* ctx) +{ + duk_push_this(ctx); + duk_push_int(ctx, duk_require_int(ctx, 0)); + duk_put_prop_string(ctx, -2, "errno"); + duk_push_string(ctx, duk_require_string(ctx, 1)); + duk_put_prop_string(ctx, -2, "message"); + duk_push_string(ctx, "SystemError"); + duk_put_prop_string(ctx, -2, "name"); + duk_pop(ctx); + + return 0; +} + +} // !namespace + +system_error::system_error() + : errno_(errno) + , message_(std::strerror(errno_)) +{ +} + +system_error::system_error(int e, std::string message) + : errno_(e) + , message_(std::move(message)) +{ +} + +void system_error::raise(duk_context *ctx) const +{ + StackAssert sa(ctx, 0); + + duk_get_global_string(ctx, "Irccd"); + duk_get_prop_string(ctx, -1, "SystemError"); + duk_remove(ctx, -2); + duk_push_int(ctx, errno_); + dukx_push_std_string(ctx, message_); + duk_new(ctx, 2); + duk_throw(ctx); +} + +js_irccd_module::js_irccd_module() noexcept + : module("Irccd") +{ +} + +void js_irccd_module::load(irccd& irccd, std::shared_ptr<js_plugin> plugin) +{ + StackAssert sa(plugin->context()); + + // irccd. + duk_push_object(plugin->context()); + + // Version. + duk_push_object(plugin->context()); + duk_push_int(plugin->context(), IRCCD_VERSION_MAJOR); + duk_put_prop_string(plugin->context(), -2, "major"); + duk_push_int(plugin->context(), IRCCD_VERSION_MINOR); + duk_put_prop_string(plugin->context(), -2, "minor"); + duk_push_int(plugin->context(), IRCCD_VERSION_PATCH); + duk_put_prop_string(plugin->context(), -2, "patch"); + duk_put_prop_string(plugin->context(), -2, "version"); + + // Create the system_error that inherits from Error. + duk_push_c_function(plugin->context(), constructor, 2); + + // Put errno codes into the irccd.system_error object. + for (const auto& pair : errors) { + duk_push_int(plugin->context(), pair.second); + duk_put_prop_string(plugin->context(), -2, pair.first.c_str()); + } + + duk_push_object(plugin->context()); + duk_get_global_string(plugin->context(), "Error"); + duk_get_prop_string(plugin->context(), -1, "prototype"); + duk_remove(plugin->context(), -2); + duk_set_prototype(plugin->context(), -2); + duk_put_prop_string(plugin->context(), -2, "prototype"); + duk_put_prop_string(plugin->context(), -2, "SystemError"); + + // Set irccd as global. + duk_put_global_string(plugin->context(), "Irccd"); + + // Store global instance. + duk_push_pointer(plugin->context(), &irccd); + duk_put_global_string(plugin->context(), "\xff""\xff""irccd-ref"); +} + +irccd& dukx_get_irccd(duk_context *ctx) +{ + StackAssert sa(ctx); + + duk_get_global_string(ctx, "\xff""\xff""irccd-ref"); + auto ptr = static_cast<irccd*>(duk_to_pointer(ctx, -1)); + duk_pop(ctx); + + return *ptr; +} + +} // !irccd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libirccd-js/irccd/js_irccd_module.hpp Tue Sep 26 17:18:47 2017 +0200 @@ -0,0 +1,93 @@ +/* + * js_irccd_module.hpp -- Irccd API + * + * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef IRCCD_JS_IRCCD_MODULE_HPP +#define IRCCD_JS_IRCCD_MODULE_HPP + +/** + * \file js_irccd_module.hpp + * \brief irccd JavaScript API. + */ + +#include <cerrno> +#include <cstring> +#include <string> + +#include "duktape.hpp" +#include "module.hpp" + +namespace irccd { + +/** + * \brief Custom JavaScript exception for system error. + */ +class system_error { +private: + int errno_; + std::string message_; + +public: + /** + * Create a system error from the current errno value. + */ + system_error(); + + /** + * Create a system error with the given errno and message. + * + * \param e the errno number + * \param message the message + */ + system_error(int e, std::string message); + + /** + * Raise the SystemError Javascript exception. + * + * \param ctx the context + */ + void raise(duk_context* ctx) const; +}; + +/** + * \brief Irccd JavaScript API. + * \ingroup modules + */ +class js_irccd_module : public module { +public: + /** + * Constructor. + */ + js_irccd_module() noexcept; + + /** + * \copydoc module::load + */ + void load(irccd& irccd, std::shared_ptr<js_plugin> plugin) override; +}; + +/** + * Get irccd instance stored in this context. + * + * \param ctx the context + * \return the irccd reference + */ +irccd& dukx_get_irccd(duk_context* ctx); + +} // !irccd + +#endif // !IRCCD_JS_IRCCD_MODULE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libirccd-js/irccd/js_logger_module.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -0,0 +1,103 @@ +/* + * js_logger_module.cpp -- Irccd.Logger API + * + * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <irccd/logger.hpp> + +#include "js_plugin.hpp" +#include "js_logger_module.hpp" +#include "js_plugin_module.hpp" + +namespace irccd { + +namespace { + +duk_ret_t print(duk_context* ctx, std::ostream &out) +{ + out << "plugin " << dukx_get_plugin(ctx)->name() << ": " << duk_require_string(ctx, 0) << std::endl; + + return 0; +} + +/* + * Function: Irccd.Logger.info(message) + * -------------------------------------------------------- + * + * Write a verbose message. + * + * Arguments: + * - message, the message. + */ +duk_ret_t info(duk_context* ctx) +{ + return print(ctx, log::info()); +} + +/* + * Function: irccd.Logger.warning(message) + * -------------------------------------------------------- + * + * Write a warning message. + * + * Arguments: + * - message, the warning. + */ +duk_ret_t warning(duk_context* ctx) +{ + return print(ctx, log::warning()); +} + +/* + * Function: Logger.debug(message) + * -------------------------------------------------------- + * + * Write a debug message, only shown if irccd is compiled in debug. + * + * Arguments: + * - message, the message. + */ +duk_ret_t debug(duk_context* ctx) +{ + return print(ctx, log::debug()); +} + +const duk_function_list_entry functions[] = { + { "info", info, 1 }, + { "warning", warning, 1 }, + { "debug", debug, 1 }, + { nullptr, nullptr, 0 } +}; + +} // !namespace + +js_logger_module::js_logger_module() noexcept + : module("Irccd.Logger") +{ +} + +void js_logger_module::load(irccd&, std::shared_ptr<js_plugin> plugin) +{ + StackAssert sa(plugin->context()); + + duk_get_global_string(plugin->context(), "Irccd"); + duk_push_object(plugin->context()); + duk_put_function_list(plugin->context(), -1, functions); + duk_put_prop_string(plugin->context(), -2, "Logger"); + duk_pop(plugin->context()); +} + +} // !irccd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libirccd-js/irccd/js_logger_module.hpp Tue Sep 26 17:18:47 2017 +0200 @@ -0,0 +1,50 @@ +/* + * js_logger_module.hpp -- Irccd.Logger API + * + * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef IRCCD_JS_LOGGER_MODULE_HPP +#define IRCCD_JS_LOGGER_MODULE_HPP + +/** + * \file js_logger_module.hpp + * \brief Irccd.Logger JavaScript API. + */ + +#include "module.hpp" + +namespace irccd { + +/** + * \brief irccd.Logger JavaScript API. + * \ingroup modules + */ +class js_logger_module : public module { +public: + /** + * Constructor. + */ + js_logger_module() noexcept; + + /** + * \copydoc Module::load + */ + void load(irccd& irccd, std::shared_ptr<js_plugin> plugin) override; +}; + +} // !irccd + +#endif // !IRCCD_JS_LOGGER_MODULE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libirccd-js/irccd/js_plugin.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -0,0 +1,434 @@ +/* + * plugin-js.cpp -- JavaScript plugins for irccd + * + * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <boost/filesystem.hpp> + +#include "sysconfig.hpp" + +#if defined(HAVE_STAT) +# include <sys/stat.h> +# include <cerrno> +# include <cstring> +#endif + +#include "fs.hpp" +#include "irccd.hpp" +#include "logger.hpp" +#include "js_plugin_module.hpp" +#include "js_server_module.hpp" +#include "js_plugin.hpp" +#include "service.hpp" +#include "timer.hpp" + +namespace irccd { + +const std::string js_plugin::config_property{"\xff""\xff""irccd-plugin-config"}; +const std::string js_plugin::format_property{"\xff""\xff""irccd-plugin-format"}; +const std::string js_plugin::paths_property{"\xff""\xff""irccd-plugin-paths"}; + +std::unordered_map<std::string, std::string> js_plugin::get_table(const std::string& name) const +{ + StackAssert sa(context_); + std::unordered_map<std::string, std::string> result; + + duk_get_global_string(context_, name.c_str()); + dukx_enumerate(context_, -1, 0, true, [&] (auto ctx) { + result.emplace(duk_to_string(ctx, -2), duk_to_string(ctx, -1)); + }); + duk_pop(context_); + + return result; +} + +void js_plugin::put_table(const std::string& name, const std::unordered_map<std::string, std::string>& vars) +{ + StackAssert sa(context_); + + duk_get_global_string(context_, name.c_str()); + + for (const auto &pair : vars) { + dukx_push_std_string(context_, pair.second); + duk_put_prop_string(context_, -2, pair.first.c_str()); + } + + duk_pop(context_); +} + +void js_plugin::call(const std::string& name, unsigned nargs) +{ + duk_get_global_string(context_, name.c_str()); + + if (duk_get_type(context_, -1) == DUK_TYPE_UNDEFINED) + // Function not defined, remove the undefined value and all arguments. + duk_pop_n(context_, nargs + 1); + else { + // Call the function and discard the result. + duk_insert(context_, -nargs - 1); + + if (duk_pcall(context_, nargs) != 0) + throw dukx_exception(context_, -1, true); + + duk_pop(context_); + } +} + +void js_plugin::put_vars() +{ + StackAssert sa(context_); + + duk_push_pointer(context_, this); + duk_put_global_string(context_, "\xff""\xff""plugin"); + dukx_push_std_string(context_, name()); + duk_put_global_string(context_, "\xff""\xff""name"); + dukx_push_std_string(context_, path()); + duk_put_global_string(context_, "\xff""\xff""path"); +} + +js_plugin::js_plugin(std::string name, std::string path) + : plugin(name, path) +{ + /* + * Create two special tables for configuration and formats, they are + * referenced later as + * + * - irccd.Plugin.config + * - irccd.Plugin.format + * - irccd.Plugin.paths + * + * In js_plugin_module.cpp. + */ + duk_push_object(context_); + duk_put_global_string(context_, config_property.c_str()); + duk_push_object(context_); + duk_put_global_string(context_, format_property.c_str()); + duk_push_object(context_); + duk_put_global_string(context_, paths_property.c_str()); + + // Used by many Javascript APIs. + duk_push_object(context_); + duk_put_global_string(context_, "irccd"); +} + +void js_plugin::on_channel_mode(irccd &, const channel_mode_event &event) +{ + StackAssert sa(context_); + + dukx_push_server(context_, std::move(event.server)); + dukx_push_std_string(context_, event.origin); + dukx_push_std_string(context_, event.channel); + dukx_push_std_string(context_, event.mode); + dukx_push_std_string(context_, event.argument); + call("onChannelMode", 5); +} + +void js_plugin::on_channel_notice(irccd &, const channel_notice_event &event) +{ + StackAssert sa(context_); + + dukx_push_server(context_, std::move(event.server)); + dukx_push_std_string(context_, event.origin); + dukx_push_std_string(context_, event.channel); + dukx_push_std_string(context_, event.message); + call("onChannelNotice", 4); +} + +void js_plugin::on_command(irccd &, const message_event &event) +{ + StackAssert sa(context_); + + dukx_push_server(context_, std::move(event.server)); + dukx_push_std_string(context_, event.origin); + dukx_push_std_string(context_, event.channel); + dukx_push_std_string(context_, event.message); + call("onCommand", 4); +} + +void js_plugin::on_connect(irccd &, const connect_event &event) +{ + StackAssert sa(context_); + + dukx_push_server(context_, std::move(event.server)); + call("onConnect", 1); +} + +void js_plugin::on_invite(irccd &, const invite_event &event) +{ + StackAssert sa(context_); + + dukx_push_server(context_, std::move(event.server)); + dukx_push_std_string(context_, event.origin); + dukx_push_std_string(context_, event.channel); + call("onInvite", 3); +} + +void js_plugin::on_join(irccd &, const join_event &event) +{ + StackAssert sa(context_); + + dukx_push_server(context_, std::move(event.server)); + dukx_push_std_string(context_, event.origin); + dukx_push_std_string(context_, event.channel); + call("onJoin", 3); +} + +void js_plugin::on_kick(irccd &, const kick_event &event) +{ + StackAssert sa(context_); + + dukx_push_server(context_, std::move(event.server)); + dukx_push_std_string(context_, event.origin); + dukx_push_std_string(context_, event.channel); + dukx_push_std_string(context_, event.target); + dukx_push_std_string(context_, event.reason); + call("onKick", 5); +} + +void js_plugin::on_load(irccd &irccd) +{ + StackAssert sa(context_); + + /* + * Duktape currently emit useless warnings when a file do + * not exists so we do a homemade access. + */ +#if defined(HAVE_STAT) + struct stat st; + + if (::stat(path().c_str(), &st) < 0) + throw std::runtime_error(std::strerror(errno)); +#endif + + // Try to load the file (does not call onLoad yet). + dukx_peval_file(context_, path()); + duk_pop(context_); + + /* + * We put configuration and formats after loading the file and before + * calling onLoad to allow the plugin adding configuration to + * irccd.Plugin.(config|format) before the user. + */ + put_vars(); + set_config(irccd.plugins().config(name())); + set_formats(irccd.plugins().formats(name())); + set_paths(irccd.plugins().paths(name())); + + // Read metadata . + duk_get_global_string(context_, "info"); + + if (duk_get_type(context_, -1) == DUK_TYPE_OBJECT) { + // 'author' + duk_get_prop_string(context_, -1, "author"); + set_author(duk_is_string(context_, -1) ? duk_get_string(context_, -1) : author()); + duk_pop(context_); + + // 'license' + duk_get_prop_string(context_, -1, "license"); + set_license(duk_is_string(context_, -1) ? duk_get_string(context_, -1) : license()); + duk_pop(context_); + + // 'summary' + duk_get_prop_string(context_, -1, "summary"); + set_summary(duk_is_string(context_, -1) ? duk_get_string(context_, -1) : summary()); + duk_pop(context_); + + // 'version' + duk_get_prop_string(context_, -1, "version"); + set_version(duk_is_string(context_, -1) ? duk_get_string(context_, -1) : version()); + duk_pop(context_); + } + + duk_pop(context_); + call("onLoad", 0); +} + +void js_plugin::on_message(irccd &, const message_event &event) +{ + StackAssert sa(context_); + + dukx_push_server(context_, std::move(event.server)); + dukx_push_std_string(context_, event.origin); + dukx_push_std_string(context_, event.channel); + dukx_push_std_string(context_, event.message); + call("onMessage", 4); +} + +void js_plugin::on_me(irccd &, const me_event &event) +{ + StackAssert sa(context_); + + dukx_push_server(context_, std::move(event.server)); + dukx_push_std_string(context_, event.origin); + dukx_push_std_string(context_, event.channel); + dukx_push_std_string(context_, event.message); + call("onMe", 4); +} + +void js_plugin::on_mode(irccd &, const mode_event &event) +{ + StackAssert sa(context_); + + dukx_push_server(context_, std::move(event.server)); + dukx_push_std_string(context_, event.origin); + dukx_push_std_string(context_, event.mode); + call("onMode", 3); +} + +void js_plugin::on_names(irccd &, const names_event &event) +{ + StackAssert sa(context_); + + dukx_push_server(context_, std::move(event.server)); + dukx_push_std_string(context_, event.channel); + dukx_push_array(context_, event.names, dukx_push_std_string); + call("onNames", 3); +} + +void js_plugin::on_nick(irccd &, const nick_event &event) +{ + StackAssert sa(context_); + + dukx_push_server(context_, std::move(event.server)); + dukx_push_std_string(context_, event.origin); + dukx_push_std_string(context_, event.nickname); + call("onNick", 3); +} + +void js_plugin::on_notice(irccd &, const notice_event &event) +{ + StackAssert sa(context_); + + dukx_push_server(context_, std::move(event.server)); + dukx_push_std_string(context_, event.origin); + dukx_push_std_string(context_, event.message); + call("onNotice", 3); +} + +void js_plugin::on_part(irccd &, const part_event &event) +{ + StackAssert sa(context_); + + dukx_push_server(context_, std::move(event.server)); + dukx_push_std_string(context_, event.origin); + dukx_push_std_string(context_, event.channel); + dukx_push_std_string(context_, event.reason); + call("onPart", 4); +} + +void js_plugin::on_query(irccd &, const query_event &event) +{ + StackAssert sa(context_); + + dukx_push_server(context_, std::move(event.server)); + dukx_push_std_string(context_, event.origin); + dukx_push_std_string(context_, event.message); + call("onQuery", 3); +} + +void js_plugin::on_query_command(irccd &, const query_event &event) +{ + StackAssert sa(context_); + + dukx_push_server(context_, std::move(event.server)); + dukx_push_std_string(context_, event.origin); + dukx_push_std_string(context_, event.message); + call("onQueryCommand", 3); +} + +void js_plugin::on_reload(irccd &) +{ + StackAssert sa(context_); + + call("onReload"); +} + +void js_plugin::on_topic(irccd &, const topic_event &event) +{ + StackAssert sa(context_); + + dukx_push_server(context_, std::move(event.server)); + dukx_push_std_string(context_, event.origin); + dukx_push_std_string(context_, event.channel); + dukx_push_std_string(context_, event.topic); + call("onTopic", 4); +} + +void js_plugin::on_unload(irccd &) +{ + StackAssert sa(context_); + + call("onUnload"); +} + +void js_plugin::on_whois(irccd &, const whois_event &event) +{ + StackAssert sa(context_); + + dukx_push_server(context_, std::move(event.server)); + duk_push_object(context_); + dukx_push_std_string(context_, event.whois.nick); + duk_put_prop_string(context_, -2, "nickname"); + dukx_push_std_string(context_, event.whois.user); + duk_put_prop_string(context_, -2, "username"); + dukx_push_std_string(context_, event.whois.realname); + duk_put_prop_string(context_, -2, "realname"); + dukx_push_std_string(context_, event.whois.host); + duk_put_prop_string(context_, -2, "host"); + dukx_push_array(context_, event.whois.channels, dukx_push_std_string); + duk_put_prop_string(context_, -2, "channels"); + call("onWhois", 2); +} + +js_plugin_loader::js_plugin_loader(irccd &irccd) noexcept + : plugin_loader({}, { ".js" }) + , irccd_(irccd) +{ +} + +js_plugin_loader::~js_plugin_loader() noexcept = default; + +void js_plugin_loader::add_module(std::unique_ptr<module> module) +{ + assert(module); + + modules_.push_back(std::move(module)); +} + +std::shared_ptr<plugin> js_plugin_loader::open(const std::string& id, + const std::string& path) noexcept +{ + if (path.rfind(".js") == std::string::npos) + return nullptr; + + try { + auto plugin = std::make_shared<js_plugin>(id, path); + + for (const auto& mod : modules_) { + log::debug() << "plugin " << plugin->name() << ": "; + log::debug() << "loading " << mod->name() << " Javascript API" << std::endl; + mod->load(irccd_, plugin); + } + + return plugin; + } catch (const std::exception &ex) { + log::warning() << "plugin " << id << ": " << ex.what() << std::endl; + } + + return nullptr; +} + +} // !irccd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libirccd-js/irccd/js_plugin.hpp Tue Sep 26 17:18:47 2017 +0200 @@ -0,0 +1,277 @@ +/* + * js_plugin.hpp -- JavaScript plugins for irccd + * + * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef IRCCD_JS_PLUGIN_HPP +#define IRCCD_JS_PLUGIN_HPP + +/** + * \file js_plugin.hpp + * \brief JavaScript plugins for irccd. + */ + +#include <vector> + +#include "duktape.hpp" +#include "plugin.hpp" + +namespace irccd { + +class module; + +/** + * \brief JavaScript plugins for irccd. + * \ingroup plugins + */ +class js_plugin : public plugin { +public: + /** + * Global property where to read/write plugin configuration (object). + */ + static const std::string config_property; + + /** + * Global property where to read/write plugin formats (object). + */ + static const std::string format_property; + + /** + * Global property where paths are defined (object). + */ + static const std::string paths_property; + +private: + // JavaScript context + UniqueContext context_; + + // Private helpers. + std::unordered_map<std::string, std::string> get_table(const std::string&) const; + void put_table(const std::string&, const std::unordered_map<std::string, std::string>&); + void call(const std::string&, unsigned = 0); + void put_vars(); + +public: + /** + * Constructor. + * + * \param name the plugin name + * \param path the path to the plugin + */ + js_plugin(std::string name, std::string path); + + /** + * Access the Duktape context. + * + * \return the context + */ + inline UniqueContext& context() noexcept + { + return context_; + } + + /** + * \copydoc Plugin::config + */ + plugin_config config() override + { + return get_table(config_property); + } + + /** + * \copydoc Plugin::setConfig + */ + void set_config(plugin_config config) override + { + put_table(config_property, config); + } + + /** + * \copydoc Plugin::formats + */ + plugin_formats formats() override + { + return get_table(format_property); + } + + /** + * \copydoc Plugin::setFormats + */ + void set_formats(plugin_formats formats) override + { + put_table(format_property, formats); + } + + /** + * \copydoc Plugin::paths + */ + plugin_paths paths() override + { + return get_table(paths_property); + } + + /** + * \copydoc Plugin::set_paths + */ + void set_paths(plugin_paths paths) override + { + put_table(paths_property, std::move(paths)); + } + + /** + * \copydoc Plugin::on_command + */ + void on_command(irccd& irccd, const message_event& event) override; + + /** + * \copydoc Plugin::on_connect + */ + void on_connect(irccd& irccd, const connect_event& event) override; + + /** + * \copydoc Plugin::on_channel_mode + */ + void on_channel_mode(irccd& irccd, const channel_mode_event& event) override; + + /** + * \copydoc Plugin::on_channel_notice + */ + void on_channel_notice(irccd& irccd, const channel_notice_event& event) override; + + /** + * \copydoc Plugin::on_invite + */ + void on_invite(irccd& irccd, const invite_event& event) override; + + /** + * \copydoc Plugin::on_join + */ + void on_join(irccd& irccd, const join_event& event) override; + + /** + * \copydoc Plugin::on_kick + */ + void on_kick(irccd& irccd, const kick_event& event) override; + + /** + * \copydoc Plugin::on_load + */ + void on_load(irccd& irccd) override; + + /** + * \copydoc Plugin::on_message + */ + void on_message(irccd& irccd, const message_event& event) override; + + /** + * \copydoc Plugin::on_me + */ + void on_me(irccd& irccd, const me_event& event) override; + + /** + * \copydoc Plugin::on_mode + */ + void on_mode(irccd& irccd, const mode_event& event) override; + + /** + * \copydoc Plugin::on_names + */ + void on_names(irccd& irccd, const names_event& event) override; + + /** + * \copydoc Plugin::on_nick + */ + void on_nick(irccd& irccd, const nick_event& event) override; + + /** + * \copydoc Plugin::on_notice + */ + void on_notice(irccd& irccd, const notice_event& event) override; + + /** + * \copydoc Plugin::on_part + */ + void on_part(irccd& irccd, const part_event& event) override; + + /** + * \copydoc Plugin::on_query + */ + void on_query(irccd& irccd, const query_event& event) override; + + /** + * \copydoc Plugin::on_query_command + */ + void on_query_command(irccd& irccd, const query_event& event) override; + + /** + * \copydoc Plugin::on_reload + */ + void on_reload(irccd& irccd) override; + + /** + * \copydoc Plugin::on_topic + */ + void on_topic(irccd& irccd, const topic_event& event) override; + + /** + * \copydoc Plugin::on_unload + */ + void on_unload(irccd& irccd) override; + + /** + * \copydoc Plugin::on_whois + */ + void on_whois(irccd& irccd, const whois_event& event) override; +}; + +/** + * \brief Implementation for searching Javascript plugins. + */ +class js_plugin_loader : public plugin_loader { +private: + irccd& irccd_; + std::vector<std::unique_ptr<module>> modules_; + +public: + /** + * Constructor. + * + * \param irccd the irccd instance + */ + js_plugin_loader(irccd& irccd) noexcept; + + /** + * Destructor defaulted. + */ + ~js_plugin_loader() noexcept; + + /** + * Register a new module for loading new plugins. + * + * \param module the module to add + */ + void add_module(std::unique_ptr<module> module); + + /** + * \copydoc PluginLoader::open + */ + std::shared_ptr<plugin> open(const std::string& id, + const std::string& path) noexcept override; +}; + +} // !irccd + +#endif // !IRCCD_PLUGIN_JS_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libirccd-js/irccd/js_plugin_module.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -0,0 +1,385 @@ +/* + * js_plugin_module.cpp -- Irccd.Plugin API + * + * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <irccd/irccd.hpp> +#include <irccd/service.hpp> + +#include "js_irccd_module.hpp" +#include "js_plugin.hpp" +#include "js_plugin_module.hpp" + +namespace irccd { + +namespace { + +const char plugin_ref[] = "\xff""\xff""irccd-plugin-ptr"; + +/* + * wrap + * ------------------------------------------------------------------ + * + * Wrap function for these functions because they all takes the same arguments. + * + * - load, + * - reload, + * - unload. + */ +template <typename Func> +duk_idx_t wrap(duk_context* ctx, int nret, Func&& func) +{ + std::string name = duk_require_string(ctx, 0); + + try { + func(dukx_get_irccd(ctx), name); + } catch (const std::out_of_range &ex) { + dukx_throw(ctx, ReferenceError(ex.what())); + } catch (const std::exception &ex) { + dukx_throw(ctx, Error(ex.what())); + } + + return nret; +} + +/* + * set + * ------------------------------------------------------------------ + * + * This setter is used to replace the Irccd.Plugin.(config|format|paths) + * property when the plugin assign a new one. + * + * Because the plugin configuration always has higher priority, when a new + * object is assigned to 'config' or to the 'format' property, the plugin + * configuration is merged to the assigned one, adding or replacing any values. + * + * Example: + * + * Plugin 'xyz' does: + * + * Irccd.Plugin.config = { + * mode: "simple", + * level: "123" + * }; + * + * The user configuration is: + * + * [plugin.xyz] + * mode = "hard" + * path = "/var" + * + * The final user table looks like this: + * + * Irccd.Plugin.Config = { + * mode: "hard", + * level: "123", + * path: "/var" + * }; + */ +duk_ret_t set(duk_context* ctx, const std::string& name) +{ + if (!duk_is_object(ctx, 0)) + duk_error(ctx, DUK_ERR_TYPE_ERROR, "'%s' property must be object", name.c_str()); + + // Merge old table with new one. + duk_get_global_string(ctx, name.c_str()); + duk_enum(ctx, -1, 0); + + while (duk_next(ctx, -1, true)) + duk_put_prop(ctx, 0); + + // Pop enum and old table. + duk_pop_2(ctx); + + // Replace the old table with the new assigned one. + duk_put_global_string(ctx, name.c_str()); + + return 0; +} + +/* + * get + * ------------------------------------------------------------------ + * + * Get the Irccd.Plugin.(config|format|paths) property. + */ +duk_ret_t get(duk_context* ctx, const std::string& name) +{ + duk_get_global_string(ctx, name.c_str()); + + return 1; +} + +/* + * set_config + * ------------------------------------------------------------------ + * + * Wrap setter for Irccd.Plugin.config property. + */ +duk_ret_t set_config(duk_context* ctx) +{ + return set(ctx, js_plugin::config_property); +} + +/* + * get_config + * ------------------------------------------------------------------ + * + * Wrap getter for Irccd.Plugin.config property. + */ +duk_ret_t get_config(duk_context* ctx) +{ + return get(ctx, js_plugin::config_property); +} + +/* + * set_format + * ------------------------------------------------------------------ + * + * Wrap setter for Irccd.Plugin.format property. + */ +duk_ret_t set_format(duk_context* ctx) +{ + return set(ctx, js_plugin::format_property); +} + +/* + * get_format + * ------------------------------------------------------------------ + * + * Wrap getter for Irccd.Plugin.format property. + */ +duk_ret_t get_format(duk_context* ctx) +{ + return get(ctx, js_plugin::format_property); +} + +/* + * set_paths + * ------------------------------------------------------------------ + * + * Wrap setter for Irccd.Plugin.format property. + */ +duk_ret_t set_paths(duk_context* ctx) +{ + return set(ctx, js_plugin::paths_property); +} + +/* + * get_paths + * ------------------------------------------------------------------ + * + * Wrap getter for Irccd.Plugin.format property. + */ +duk_ret_t get_paths(duk_context* ctx) +{ + return get(ctx, js_plugin::paths_property); +} + +/* + * Function: Irccd.Plugin.info([name]) + * ------------------------------------------------------------------ + * + * Get information about a plugin. + * + * The returned object as the following properties: + * + * - name: (string) the plugin identifier, + * - author: (string) the author, + * - license: (string) the license, + * - summary: (string) a short description, + * - version: (string) the version + * + * Arguments: + * - name, the plugin identifier, if not specified the current plugin is + * selected. + * Returns: + * The plugin information or undefined if the plugin was not found. + */ +duk_idx_t info(duk_context* ctx) +{ + std::shared_ptr<plugin> plugin; + + if (duk_get_top(ctx) >= 1) + plugin = dukx_get_irccd(ctx).plugins().get(duk_require_string(ctx, 0)); + else + plugin = dukx_get_plugin(ctx); + + if (!plugin) + return 0; + + duk_push_object(ctx); + dukx_push_std_string(ctx, plugin->name()); + duk_put_prop_string(ctx, -2, "name"); + dukx_push_std_string(ctx, plugin->author()); + duk_put_prop_string(ctx, -2, "author"); + dukx_push_std_string(ctx, plugin->license()); + duk_put_prop_string(ctx, -2, "license"); + dukx_push_std_string(ctx, plugin->summary()); + duk_put_prop_string(ctx, -2, "summary"); + dukx_push_std_string(ctx, plugin->version()); + duk_put_prop_string(ctx, -2, "version"); + + return 1; +} + +/* + * Function: Irccd.Plugin.list() + * ------------------------------------------------------------------ + * + * Get the list of plugins, the array returned contains all plugin names. + * + * Returns: + * The list of all plugin names. + */ +duk_idx_t list(duk_context* ctx) +{ + dukx_push_array(ctx, dukx_get_irccd(ctx).plugins().list(), [] (auto ctx, auto plugin) { + dukx_push_std_string(ctx, plugin->name()); + }); + + return 1; +} + +/* + * Function: Irccd.Plugin.load(name) + * ------------------------------------------------------------------ + * + * Load a plugin by name. This function will search through the standard + * directories. + * + * Arguments: + * - name, the plugin identifier. + * Throws: + * - Error on errors, + * - ReferenceError if the plugin was not found. + */ +duk_idx_t load(duk_context* ctx) +{ + return wrap(ctx, 0, [&] (irccd &irccd, const std::string &name) { + irccd.plugins().load(name); + }); +} + +/* + * Function: Irccd.Plugin.reload(name) + * ------------------------------------------------------------------ + * + * Reload a plugin by name. + * + * Arguments: + * - name, the plugin identifier. + * Throws: + * - Error on errors, + * - ReferenceError if the plugin was not found. + */ +duk_idx_t reload(duk_context* ctx) +{ + return wrap(ctx, 0, [&] (irccd &irccd, const std::string &name) { + irccd.plugins().reload(name); + }); +} + +/* + * Function: Irccd.Plugin.unload(name) + * ------------------------------------------------------------------ + * + * Unload a plugin by name. + * + * Arguments: + * - name, the plugin identifier. + * Throws: + * - Error on errors, + * - ReferenceError if the plugin was not found. + */ +duk_idx_t unload(duk_context* ctx) +{ + return wrap(ctx, 0, [&] (irccd &irccd, const std::string &name) { + irccd.plugins().unload(name); + }); +} + +const duk_function_list_entry functions[] = { + { "info", info, DUK_VARARGS }, + { "list", list, 0 }, + { "load", load, 1 }, + { "reload", reload, 1 }, + { "unload", unload, 1 }, + { nullptr, nullptr, 0 } +}; + +} // !namespace + +js_plugin_module::js_plugin_module() noexcept + : module("Irccd.Plugin") +{ +} + +void js_plugin_module::load(irccd&, std::shared_ptr<js_plugin> plugin) +{ + StackAssert sa(plugin->context()); + + duk_push_pointer(plugin->context(), new std::weak_ptr<js_plugin>(plugin)); + duk_push_object(plugin->context()); + duk_push_c_function(plugin->context(), [] (auto ctx) -> duk_ret_t { + duk_get_global_string(ctx, plugin_ref); + delete static_cast<std::shared_ptr<js_plugin>*>(duk_to_pointer(ctx, -1)); + duk_pop(ctx); + duk_push_null(ctx); + duk_put_global_string(ctx, plugin_ref); + return 0; + }, 1); + duk_set_finalizer(plugin->context(), -2); + duk_put_global_string(plugin->context(), "\xff""\xff""dummy-shared-ptr"); + duk_put_global_string(plugin->context(), plugin_ref); + duk_get_global_string(plugin->context(), "Irccd"); + duk_push_object(plugin->context()); + duk_put_function_list(plugin->context(), -1, functions); + + // 'config' property. + duk_push_string(plugin->context(), "config"); + duk_push_c_function(plugin->context(), get_config, 0); + duk_push_c_function(plugin->context(), set_config, 1); + duk_def_prop(plugin->context(), -4, DUK_DEFPROP_HAVE_GETTER | DUK_DEFPROP_HAVE_SETTER); + + // 'format' property. + duk_push_string(plugin->context(), "format"); + duk_push_c_function(plugin->context(), get_format, 0); + duk_push_c_function(plugin->context(), set_format, 1); + duk_def_prop(plugin->context(), -4, DUK_DEFPROP_HAVE_GETTER | DUK_DEFPROP_HAVE_SETTER); + + // 'format' property. + duk_push_string(plugin->context(), "paths"); + duk_push_c_function(plugin->context(), get_paths, 0); + duk_push_c_function(plugin->context(), set_paths, 1); + duk_def_prop(plugin->context(), -4, DUK_DEFPROP_HAVE_GETTER | DUK_DEFPROP_HAVE_SETTER); + + duk_put_prop_string(plugin->context(), -2, "Plugin"); + duk_pop(plugin->context()); +} + +std::shared_ptr<js_plugin> dukx_get_plugin(duk_context* ctx) +{ + StackAssert sa(ctx); + + duk_get_global_string(ctx, plugin_ref); + auto plugin = static_cast<std::weak_ptr<js_plugin>*>(duk_to_pointer(ctx, -1)); + duk_pop(ctx); + + return plugin->lock(); +} + +} // !irccd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libirccd-js/irccd/js_plugin_module.hpp Tue Sep 26 17:18:47 2017 +0200 @@ -0,0 +1,59 @@ +/* + * js_plugin_module.hpp -- Irccd.Plugin API + * + * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef IRCCD_JS_PLUGIN_MODULE_HPP +#define IRCCD_JS_PLUGIN_MODULE_HPP + +/** + * \file js_plugin_module.hpp + * \brief Irccd.Plugin JavaScript API. + */ + +#include "duktape.hpp" +#include "module.hpp" + +namespace irccd { + +/** + * \brief Irccd.Plugin JavaScript API. + * \ingroup modules + */ +class js_plugin_module : public module { +public: + /** + * Irccd.Plugin. + */ + js_plugin_module() noexcept; + + /** + * \copydoc Module::load + */ + void load(irccd& irccd, std::shared_ptr<js_plugin> plugin) override; +}; + +/** + * Access the plugin stored in this context. + * + * \param ctx the context + * \return the plugin + */ +std::shared_ptr<js_plugin> dukx_get_plugin(duk_context* ctx); + +} // !irccd + +#endif // !IRCCD_JS_PLUGIN_MODULE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libirccd-js/irccd/js_server_module.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -0,0 +1,581 @@ +/* + * js_server_module.cpp -- Irccd.Server API + * + * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <cassert> +#include <sstream> +#include <unordered_map> + +#include <irccd.hpp> +#include <irccd/js_plugin.hpp> +#include <irccd/server.hpp> +#include <irccd/service.hpp> + +#include "js_irccd_module.hpp" +#include "js_server_module.hpp" + +namespace irccd { + +namespace { + +const char *signature("\xff""\xff""irccd-server-ptr"); +const char *prototype("\xff""\xff""irccd-server-prototype"); + +std::shared_ptr<server> self(duk_context* ctx) +{ + StackAssert sa(ctx); + + duk_push_this(ctx); + duk_get_prop_string(ctx, -1, signature); + auto ptr = duk_to_pointer(ctx, -1); + duk_pop_2(ctx); + + if (!ptr) + duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a Server object"); + + return *static_cast<std::shared_ptr<server>*>(ptr); +} + +/* + * Method: Server.cmode(channel, mode) + * ------------------------------------------------------------------ + * + * Change a channel mode. + * + * Arguments: + * - channel, the channel, + * - mode, the mode. + */ +duk_ret_t cmode(duk_context* ctx) +{ + self(ctx)->cmode(duk_require_string(ctx, 0), duk_require_string(ctx, 1)); + + return 0; +} + +/* + * Method: Server.cnotice(channel, message) + * ------------------------------------------------------------------ + * + * Send a channel notice. + * + * Arguments: + * - channel, the channel, + * - message, the message. + */ +duk_ret_t cnotice(duk_context* ctx) +{ + self(ctx)->cnotice(duk_require_string(ctx, 0), duk_require_string(ctx, 1)); + + return 0; +} + +/* + * Method: Server.info() + * ------------------------------------------------------------------ + * + * Get the server information as an object containing the following properties: + * + * name: the server unique name + * host: the host name + * port: the port number + * ssl: true if using ssl + * sslVerify: true if ssl was verified + * channels: an array of all channels + */ +duk_ret_t info(duk_context* ctx) +{ + auto server = self(ctx); + + duk_push_object(ctx); + dukx_push_std_string(ctx, server->name()); + duk_put_prop_string(ctx, -2, "name"); + dukx_push_std_string(ctx, server->host()); + duk_put_prop_string(ctx, -2, "host"); + duk_push_int(ctx, server->port()); + duk_put_prop_string(ctx, -2, "port"); + duk_push_boolean(ctx, server->flags() & server::ssl); + duk_put_prop_string(ctx, -2, "ssl"); + duk_push_boolean(ctx, server->flags() & server::ssl_verify); + duk_put_prop_string(ctx, -2, "sslVerify"); + dukx_push_std_string(ctx, server->command_char()); + duk_put_prop_string(ctx, -2, "commandChar"); + dukx_push_std_string(ctx, server->realname()); + duk_put_prop_string(ctx, -2, "realname"); + dukx_push_std_string(ctx, server->nickname()); + duk_put_prop_string(ctx, -2, "nickname"); + dukx_push_std_string(ctx, server->username()); + duk_put_prop_string(ctx, -2, "username"); + dukx_push_array(ctx, server->channels(), [&] (auto ctx, auto channel) { + dukx_push_std_string(ctx, channel); + }); + duk_put_prop_string(ctx, -2, "channels"); + + return 1; +} + +/* + * Method: Server.invite(target, channel) + * ------------------------------------------------------------------ + * + * Invite someone to a channel. + * + * Arguments: + * - target, the target to invite, + * - channel, the channel. + */ +duk_ret_t invite(duk_context* ctx) +{ + self(ctx)->invite(duk_require_string(ctx, 0), duk_require_string(ctx, 1)); + + return 0; +} + +/* + * Method: Server.join(channel, password = undefined) + * ------------------------------------------------------------------ + * + * Join a channel with an optional password. + * + * Arguments: + * - channel, the channel to join, + * - password, the password or undefined to not use. + */ +duk_ret_t join(duk_context* ctx) +{ + self(ctx)->join(duk_require_string(ctx, 0), dukx_get_std_string(ctx, 1)); + + return 0; +} + +/* + * Method: Server.kick(target, channel, reason = undefined) + * ------------------------------------------------------------------ + * + * Kick someone from a channel. + * + * Arguments: + * - target, the target to kick, + * - channel, the channel, + * - reason, the optional reason or undefined to not set. + */ +duk_ret_t kick(duk_context* ctx) +{ + self(ctx)->kick(duk_require_string(ctx, 0), duk_require_string(ctx, 1), dukx_get_std_string(ctx, 2)); + + return 0; +} + +/* + * Method: Server.me(target, message) + * ------------------------------------------------------------------ + * + * Send a CTCP Action. + * + * Arguments: + * - target, the target or a channel, + * - message, the message. + */ +duk_ret_t me(duk_context* ctx) +{ + self(ctx)->me(duk_require_string(ctx, 0), duk_require_string(ctx, 1)); + + return 0; +} + +/* + * Method: Server.message(target, message) + * ------------------------------------------------------------------ + * + * Send a message. + * + * Arguments: + * - target, the target or a channel, + * - message, the message. + */ +duk_ret_t message(duk_context* ctx) +{ + self(ctx)->message(duk_require_string(ctx, 0), duk_require_string(ctx, 1)); + + return 0; +} + +/* + * Method: Server.mode(mode) + * ------------------------------------------------------------------ + * + * Change your mode. + * + * Arguments: + * - mode, the new mode. + */ +duk_ret_t mode(duk_context* ctx) +{ + self(ctx)->mode(duk_require_string(ctx, 0)); + + return 0; +} + +/* + * Method: Server.names(channel) + * ------------------------------------------------------------------ + * + * Get the list of names from a channel. + * + * Arguments: + * - channel, the channel. + */ +duk_ret_t names(duk_context* ctx) +{ + self(ctx)->names(duk_require_string(ctx, 0)); + + return 0; +} + +/* + * Method: Server.nick(nickname) + * ------------------------------------------------------------------ + * + * Change the nickname. + * + * Arguments: + * - nickname, the nickname. + */ +duk_ret_t nick(duk_context* ctx) +{ + self(ctx)->set_nickname(duk_require_string(ctx, 0)); + + return 0; +} + +/* + * Method: Server.notice(target, message) + * ------------------------------------------------------------------ + * + * Send a private notice. + * + * Arguments: + * - target, the target, + * - message, the notice message. + */ +duk_ret_t notice(duk_context* ctx) +{ + self(ctx)->notice(duk_require_string(ctx, 0), duk_require_string(ctx, 1)); + + return 0; +} + +/* + * Method: Server.part(channel, reason = undefined) + * ------------------------------------------------------------------ + * + * Leave a channel. + * + * Arguments: + * - channel, the channel to leave, + * - reason, the optional reason, keep undefined for portability. + */ +duk_ret_t part(duk_context* ctx) +{ + self(ctx)->part(duk_require_string(ctx, 0), dukx_get_std_string(ctx, 1)); + + return 0; +} + +/* + * Method: Server.send(raw) + * ------------------------------------------------------------------ + * + * Send a raw message to the IRC server. + * + * Arguments: + * - raw, the raw message (without terminators). + */ +duk_ret_t send(duk_context* ctx) +{ + self(ctx)->send(duk_require_string(ctx, 0)); + + return 0; +} + +/* + * Method: Server.topic(channel, topic) + * ------------------------------------------------------------------ + * + * Change a channel topic. + * + * Arguments: + * - channel, the channel, + * - topic, the new topic. + */ +duk_ret_t topic(duk_context* ctx) +{ + self(ctx)->topic(duk_require_string(ctx, 0), duk_require_string(ctx, 1)); + + return 0; +} + +/* + * Method: Server.whois(target) + * ------------------------------------------------------------------ + * + * Get whois information. + * + * Arguments: + * - target, the target. + */ +duk_ret_t whois(duk_context* ctx) +{ + self(ctx)->whois(duk_require_string(ctx, 0)); + + return 0; +} + +/* + * Method: Server.toString() + * ------------------------------------------------------------------ + * + * Convert the object to std::string, convenience for adding the object + * as property key. + * + * duk_ret_turns: + * The server name (unique). + */ +duk_ret_t toString(duk_context* ctx) +{ + dukx_push_std_string(ctx, self(ctx)->name()); + + return 1; +} + +/* + * Function: Irccd.Server(params) [constructor] + * ------------------------------------------------------------------ + * + * Construct a new server. + * + * Params must be filled with the following properties: + * + * name: the name, + * host: the host, + * ipv6: true to use ipv6, (Optional: default false) + * port: the port number, (Optional: default 6667) + * password: the password, (Optional: default none) + * channels: array of channels (Optiona: default empty) + * ssl: true to use ssl, (Optional: default false) + * sslVerify: true to verify (Optional: default true) + * nickname: "nickname", (Optional, default: irccd) + * username: "user name", (Optional, default: irccd) + * realname: "real name", (Optional, default: IRC Client Daemon) + * commandChar: "!", (Optional, the command char, default: "!") + */ +duk_ret_t constructor(duk_context* ctx) +{ + if (!duk_is_constructor_call(ctx)) + return 0; + + duk_check_type(ctx, 0, DUK_TYPE_OBJECT); + + try { + auto json = duk_json_encode(ctx, 0); + auto s = server::from_json(nlohmann::json::parse(json)); + + duk_push_this(ctx); + duk_push_pointer(ctx, new std::shared_ptr<server>(std::move(s))); + duk_put_prop_string(ctx, -2, signature); + duk_pop(ctx); + } catch (const std::exception& ex) { + duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); + } + + return 0; +} + +/* + * Function: Irccd.Server() [destructor] + * ------------------------------------------------------------------ + * + * Delete the property. + */ +duk_ret_t destructor(duk_context* ctx) +{ + duk_get_prop_string(ctx, 0, signature); + delete static_cast<std::shared_ptr<server>*>(duk_to_pointer(ctx, -1)); + duk_pop(ctx); + duk_del_prop_string(ctx, 0, signature); + + return 0; +} + +/* + * Function: Irccd.Server.add(s) + * ------------------------------------------------------------------ + * + * Register a new server to the irccd instance. + * + * Arguments: + * - s, the server to add. + */ +duk_ret_t add(duk_context* ctx) +{ + dukx_get_irccd(ctx).servers().add(dukx_require_server(ctx, 0)); + + return 0; +} + +/* + * Function: Irccd.Server.find(name) + * ------------------------------------------------------------------ + * + * Find a server by name. + * + * Arguments: + * - name, the server name + * duk_ret_turns: + * The server object or undefined if not found. + */ +duk_ret_t find(duk_context* ctx) +{ + auto server = dukx_get_irccd(ctx).servers().get(duk_require_string(ctx, 0)); + + if (!server) + return 0; + + dukx_push_server(ctx, server); + + return 1; +} + +/* + * Function: Irccd.Server.list() + * ------------------------------------------------------------------ + * + * Get the map of all loaded servers. + * + * duk_ret_turns: + * An object with string-to-servers pairs. + */ +duk_ret_t list(duk_context* ctx) +{ + duk_push_object(ctx); + + for (const auto &server : dukx_get_irccd(ctx).servers().servers()) { + dukx_push_server(ctx, server); + duk_put_prop_string(ctx, -2, server->name().c_str()); + } + + return 1; +} + +/* + * Function: irccd.Server.remove(name) + * ------------------------------------------------------------------ + * + * Remove a server from the irccd instance. You can pass the server object since + * it's coercible to a string. + * + * Arguments: + * - name the server name. + */ +duk_ret_t remove(duk_context* ctx) +{ + dukx_get_irccd(ctx).servers().remove(duk_require_string(ctx, 0)); + + return 0; +} + +const duk_function_list_entry methods[] = { + { "cmode", cmode, 2 }, + { "cnotice", cnotice, 2 }, + { "info", info, 0 }, + { "invite", invite, 2 }, + { "join", join, DUK_VARARGS }, + { "kick", kick, DUK_VARARGS }, + { "me", me, 2 }, + { "message", message, 2 }, + { "mode", mode, 1 }, + { "names", names, 1 }, + { "nick", nick, 1 }, + { "notice", notice, 2 }, + { "part", part, DUK_VARARGS }, + { "send", send, 1 }, + { "topic", topic, 2 }, + { "whois", whois, 1 }, + { "toString", toString, 0 }, + { nullptr, nullptr, 0 } +}; + +const duk_function_list_entry functions[] = { + { "add", add, 1 }, + { "find", find, 1 }, + { "list", list, 0 }, + { "remove", remove, 1 }, + { nullptr, nullptr, 0 } +}; + +} // !namespace + +js_server_module::js_server_module() noexcept + : module("Irccd.Server") +{ +} + +void js_server_module::load(irccd&, std::shared_ptr<js_plugin> plugin) +{ + StackAssert sa(plugin->context()); + + duk_get_global_string(plugin->context(), "Irccd"); + duk_push_c_function(plugin->context(), constructor, 1); + duk_put_function_list(plugin->context(), -1, functions); + duk_push_object(plugin->context()); + duk_put_function_list(plugin->context(), -1, methods); + duk_push_c_function(plugin->context(), destructor, 1); + duk_set_finalizer(plugin->context(), -2); + duk_dup_top(plugin->context()); + duk_put_global_string(plugin->context(), prototype); + duk_put_prop_string(plugin->context(), -2, "prototype"); + duk_put_prop_string(plugin->context(), -2, "Server"); + duk_pop(plugin->context()); +} + +void dukx_push_server(duk_context* ctx, std::shared_ptr<server> server) +{ + assert(ctx); + assert(server); + + StackAssert sa(ctx, 1); + + duk_push_object(ctx); + duk_push_pointer(ctx, new std::shared_ptr<class server>(std::move(server))); + duk_put_prop_string(ctx, -2, signature); + duk_get_global_string(ctx, prototype); + duk_set_prototype(ctx, -2); +} + +std::shared_ptr<server> dukx_require_server(duk_context* ctx, duk_idx_t index) +{ + if (!duk_is_object(ctx, index) || !duk_has_prop_string(ctx, index, signature)) + duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a Server object"); + + duk_get_prop_string(ctx, index, signature); + auto file = *static_cast<std::shared_ptr<server> *>(duk_to_pointer(ctx, -1)); + duk_pop(ctx); + + return file; +} + +} // !irccd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libirccd-js/irccd/js_server_module.hpp Tue Sep 26 17:18:47 2017 +0200 @@ -0,0 +1,70 @@ +/* + * js_server_module.hpp -- Irccd.Server API + * + * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef IRCCD_JS_SERVER_MODULE_HPP +#define IRCCD_JS_SERVER_MODULE_HPP + +/** + * \file mod-server.hpp + * \brief irccd.Server JavaScript API. + */ + +#include "duktape.hpp" +#include "module.hpp" +#include "server.hpp" + +namespace irccd { + +/** + * \brief irccd.Server JavaScript API. + * \ingroup modules + */ +class js_server_module : public module { +public: + /** + * irccd.Server. + */ + js_server_module() noexcept; + + /** + * \copydoc Module::load + */ + void load(irccd& irccd, std::shared_ptr<js_plugin> plugin) override; +}; + +/** + * Push a server. + * + * \pre server != nullptr + * \param ctx the context + * \param server the server + */ +void dukx_push_server(duk_context* ctx, std::shared_ptr<server> server); + +/** + * Require a server. Raise a JavaScript error if not a Server. + * + * \param ctx the context + * \param index the index + * \return the server + */ +std::shared_ptr<server> dukx_require_server(duk_context* ctx, duk_idx_t index); + +} // !irccd + +#endif // !IRCCD_JS_SERVER_MODULE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libirccd-js/irccd/js_system_module.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -0,0 +1,244 @@ +/* + * js_system_module.cpp -- Irccd.System API + * + * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <chrono> +#include <cstdlib> +#include <thread> + +#include <irccd/sysconfig.hpp> + +#if defined(HAVE_POPEN) +# include <cstdio> +#endif + +#include <irccd/js_plugin.hpp> +#include <irccd/system.hpp> + +#include "js_file_module.hpp" +#include "js_irccd_module.hpp" +#include "js_system_module.hpp" + +namespace irccd { + +namespace { + +/* + * Function: irccd.System.env(key) + * ------------------------------------------------------------------ + * + * Get an environment system variable. + * + * Arguments: + * - key, the environment variable. + * Returns: + * The value. + */ +duk_ret_t env(duk_context* ctx) +{ + dukx_push_std_string(ctx, sys::env(dukx_get_std_string(ctx, 0))); + + return 1; +} + +/* + * Function: irccd.System.exec(cmd) + * ------------------------------------------------------------------ + * + * Execute a system command. + * + * Arguments: + * - cmd, the command to execute. + */ +duk_ret_t exec(duk_context* ctx) +{ + std::system(duk_get_string(ctx, 0)); + + return 0; +} + +/* + * Function: irccd.System.home() + * ------------------------------------------------------------------ + * + * Get the operating system user's home. + * + * Returns: + * The user home directory. + */ +duk_ret_t home(duk_context* ctx) +{ + dukx_push_std_string(ctx, sys::home()); + + return 1; +} + +/* + * Function: irccd.System.name() + * ------------------------------------------------------------------ + * + * Get the operating system name. + * + * Returns: + * The system name. + */ +duk_ret_t name(duk_context* ctx) +{ + dukx_push_std_string(ctx, sys::name()); + + return 1; +} + +#if defined(HAVE_POPEN) + +/* + * Function: irccd.System.popen(cmd, mode) [optional] + * ------------------------------------------------------------------ + * + * Wrapper for popen(3) if the function is available. + * + * Arguments: + * - cmd, the command to execute, + * - mode, the mode (e.g. "r"). + * Returns: + * A irccd.File object. + * Throws + * - irccd.system_error on failures. + */ +duk_ret_t popen(duk_context* ctx) +{ + auto fp = ::popen(duk_require_string(ctx, 0), duk_require_string(ctx, 1)); + + if (fp == nullptr) + dukx_throw(ctx, system_error()); + + dukx_push_file(ctx, new file(fp, [] (auto fp) { ::pclose(fp); })); + + return 1; +} + +#endif // !HAVE_POPEN + +/* + * Function: irccd.System.sleep(delay) + * ------------------------------------------------------------------ + * + * Sleep the main loop for the specific delay in seconds. + */ +duk_ret_t sleep(duk_context* ctx) +{ + std::this_thread::sleep_for(std::chrono::seconds(duk_get_int(ctx, 0))); + + return 0; +} + +/* + * Function: irccd.System.ticks() + * ------------------------------------------------------------------ + * + * Get the number of milliseconds since irccd was started. + * + * Returns: + * The number of milliseconds. + */ +duk_ret_t ticks(duk_context* ctx) +{ + duk_push_int(ctx, sys::ticks()); + + return 1; +} + +/* + * Function: irccd.System.usleep(delay) + * ------------------------------------------------------------------ + * + * Sleep the main loop for the specific delay in microseconds. + */ +duk_ret_t usleep(duk_context* ctx) +{ + std::this_thread::sleep_for(std::chrono::microseconds(duk_get_int(ctx, 0))); + + return 0; +} + +/* + * Function: irccd.System.uptime() + * ------------------------------------------------------------------ + * + * Get the system uptime. + * + * Returns: + * The system uptime. + */ +duk_ret_t uptime(duk_context* ctx) +{ + duk_push_int(ctx, sys::uptime()); + + return 0; +} + +/* + * Function: irccd.System.version() + * ------------------------------------------------------------------ + * + * Get the operating system version. + * + * Returns: + * The system version. + */ +duk_ret_t version(duk_context* ctx) +{ + dukx_push_std_string(ctx, sys::version()); + + return 1; +} + +const duk_function_list_entry functions[] = { + { "env", env, 1 }, + { "exec", exec, 1 }, + { "home", home, 0 }, + { "name", name, 0 }, +#if defined(HAVE_POPEN) + { "popen", popen, 2 }, +#endif + { "sleep", sleep, 1 }, + { "ticks", ticks, 0 }, + { "uptime", uptime, 0 }, + { "usleep", usleep, 1 }, + { "version", version, 0 }, + { nullptr, nullptr, 0 } +}; + +} // !namespace + +js_system_module::js_system_module() noexcept + : module("Irccd.System") +{ +} + +void js_system_module::load(irccd&, std::shared_ptr<js_plugin> plugin) +{ + StackAssert sa(plugin->context()); + + duk_get_global_string(plugin->context(), "Irccd"); + duk_push_object(plugin->context()); + duk_put_function_list(plugin->context(), -1, functions); + duk_put_prop_string(plugin->context(), -2, "System"); + duk_pop(plugin->context()); +} + +} // !irccd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libirccd-js/irccd/js_system_module.hpp Tue Sep 26 17:18:47 2017 +0200 @@ -0,0 +1,50 @@ +/* + * js_system_module.hpp -- Irccd.System API + * + * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef IRCCD_JS_SYSTEM_MODULE_HPP +#define IRCCD_JS_SYSTEM_MODULE_HPP + +/** + * \file mod-system.hpp + * \brief irccd.System JavaScript API. + */ + +#include "module.hpp" + +namespace irccd { + +/** + * \brief irccd.System JavaScript API. + * \ingroup modules + */ +class js_system_module : public module { +public: + /** + * irccd.System. + */ + js_system_module() noexcept; + + /** + * \copydoc Module::load + */ + void load(irccd& irccd, std::shared_ptr<js_plugin> plugin) override; +}; + +} // !irccd + +#endif // !IRCCD_JS_SYSTEM_MODULE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libirccd-js/irccd/js_timer_module.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -0,0 +1,210 @@ +/* + * js_timer_module.cpp -- Irccd.timer API + * + * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <format.h> + +#include <irccd/irccd.hpp> +#include <irccd/logger.hpp> +#include <irccd/js_plugin.hpp> +#include <irccd/timer.hpp> + +#include "js_irccd_module.hpp" +#include "js_plugin_module.hpp" +#include "js_timer_module.hpp" + +using namespace fmt::literals; + +namespace irccd { + +namespace { + +const char* signature("\xff""\xff""irccd-timer-ptr"); +const char* callback_table("\xff""\xff""irccd-timer-callbacks"); + +void handle_signal(irccd& instance, std::weak_ptr<js_plugin> ptr, std::string key) +{ + auto plugin = ptr.lock(); + + if (!plugin) + return; + + instance.post([plugin, key] (irccd &) { + StackAssert sa(plugin->context()); + + duk_get_global_string(plugin->context(), callback_table); + duk_get_prop_string(plugin->context(), -1, key.c_str()); + duk_remove(plugin->context(), -2); + + if (duk_is_callable(plugin->context(), -1)) { + if (duk_pcall(plugin->context(), 0) != 0) + log::warning("plugin {}: {}"_format(plugin->name(), dukx_exception(plugin->context(), -1).stack)); + else + duk_pop(plugin->context()); + } else + duk_pop(plugin->context()); + }); +} + +std::shared_ptr<timer> self(duk_context* ctx) +{ + StackAssert sa(ctx); + + duk_push_this(ctx); + duk_get_prop_string(ctx, -1, signature); + auto ptr = duk_to_pointer(ctx, -1); + duk_pop_2(ctx); + + if (!ptr) + duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a timer object"); + + return *static_cast<std::shared_ptr<timer>*>(ptr); +} + +/* + * Method: timer.start() + * -------------------------------------------------------- + * + * Start the timer. If the timer is already started the method is a no-op. + */ +duk_ret_t start(duk_context* ctx) +{ + auto timer = self(ctx); + + if (!timer->is_running()) + timer->start(); + + return 0; +} + +/* + * Method: timer.stop() + * -------------------------------------------------------- + * + * Stop the timer. + */ +duk_ret_t stop(duk_context* ctx) +{ + auto timer = self(ctx); + + if (timer->is_running()) + timer->stop(); + + return 0; +} + +const duk_function_list_entry methods[] = { + { "start", start, 0 }, + { "stop", stop, 0 }, + { nullptr, nullptr, 0 } +}; + +/* + * Function: Irccd.timer(type, delay, callback) [constructor] + * -------------------------------------------------------- + * + * Create a new timer object. + * + * Arguments: + * - type, the type of timer (irccd.timer.Single or irccd.timer.Repeat), + * - delay, the interval in milliseconds, + * - callback, the function to call. + */ +duk_ret_t constructor(duk_context* ctx) +{ + // Check parameters. + auto type = duk_require_int(ctx, 0); + auto delay = duk_require_int(ctx, 1); + + if (type < static_cast<int>(timer::type::single) || type > static_cast<int>(timer::type::repeat)) + duk_error(ctx, DUK_ERR_TYPE_ERROR, "invalid timer type"); + if (delay < 0) + duk_error(ctx, DUK_ERR_TYPE_ERROR, "negative delay given"); + if (!duk_is_callable(ctx, 2)) + duk_error(ctx, DUK_ERR_TYPE_ERROR, "missing callback function"); + + // Construct the timer in 'this'. + auto& irccd = dukx_get_irccd(ctx); + auto tm = std::make_shared<timer>(static_cast<timer::type>(type), delay); + auto hash = std::to_string(reinterpret_cast<std::uintptr_t>(tm.get())); + + tm->on_signal.connect(std::bind(handle_signal, std::ref(irccd), + std::weak_ptr<js_plugin>(dukx_get_plugin(ctx)), hash)); + + duk_push_this(ctx); + duk_push_pointer(ctx, new std::shared_ptr<timer>(std::move(tm))); + duk_put_prop_string(ctx, -2, signature); + duk_push_string(ctx, hash.c_str()); + duk_put_prop_string(ctx, -2, "\xff""\xff""timer-key"); + duk_push_c_function(ctx, [] (duk_context* ctx) -> duk_ret_t { + StackAssert sa(ctx); + + duk_get_prop_string(ctx, 0, "\xff""\xff""timer-key"); + auto hash = duk_get_string(ctx, -1); + duk_pop(ctx); + duk_get_prop_string(ctx, 0, signature); + static_cast<std::shared_ptr<timer>*>(duk_to_pointer(ctx, -1))->get()->stop(); + delete static_cast<std::shared_ptr<timer>*>(duk_to_pointer(ctx, -1)); + duk_pop(ctx); + duk_get_global_string(ctx, callback_table); + duk_del_prop_string(ctx, -1, hash); + duk_pop(ctx); + log::debug("plugin: timer destroyed"); + + return 0; + }, 1); + duk_set_finalizer(ctx, -2); + + // Save a callback function into the callback table. + duk_get_global_string(ctx, callback_table); + duk_dup(ctx, 2); + duk_put_prop_string(ctx, -2, hash.c_str()); + duk_pop(ctx); + + return 0; +} + +const duk_number_list_entry constants[] = { + { "Single", static_cast<int>(timer::type::single) }, + { "Repeat", static_cast<int>(timer::type::repeat) }, + { nullptr, 0 } +}; + +} // !namespace + +js_timer_module::js_timer_module() noexcept + : module("Irccd.timer") +{ +} + +void js_timer_module::load(irccd&, std::shared_ptr<js_plugin> plugin) +{ + StackAssert sa(plugin->context()); + + duk_get_global_string(plugin->context(), "Irccd"); + duk_push_c_function(plugin->context(), constructor, 3); + duk_put_number_list(plugin->context(), -1, constants); + duk_push_object(plugin->context()); + duk_put_function_list(plugin->context(), -1, methods); + duk_put_prop_string(plugin->context(), -2, "prototype"); + duk_put_prop_string(plugin->context(), -2, "Timer"); + duk_pop(plugin->context()); + duk_push_object(plugin->context()); + duk_put_global_string(plugin->context(), callback_table); +} + +} // !irccd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libirccd-js/irccd/js_timer_module.hpp Tue Sep 26 17:18:47 2017 +0200 @@ -0,0 +1,50 @@ +/* + * js_timer_module.hpp -- Irccd.Timer API + * + * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef IRCCD_JS_TIMER_MODULE_HPP +#define IRCCD_JS_TIMER_MODULE_HPP + +/** + * \file js_timer_module + * \brief irccd.Timer JavaScript API. + */ + +#include "module.hpp" + +namespace irccd { + +/** + * \brief Irccd.Timer JavaScript API. + * \ingroup modules + */ +class js_timer_module : public module { +public: + /** + * Constructor. + */ + js_timer_module() noexcept; + + /** + * \copydoc module::load + */ + void load(irccd& irccd, std::shared_ptr<js_plugin> plugin) override; +}; + +} // !irccd + +#endif // !IRCCD_MOD_TIMER_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libirccd-js/irccd/js_unicode_module.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -0,0 +1,153 @@ +/* + * js_unicode_module.cpp -- Irccd.Unicode API + * + * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <irccd/js_plugin.hpp> + +#include "duktape.hpp" +#include "js_unicode_module.hpp" +#include "unicode.hpp" + +namespace irccd { + +namespace { + +/* + * Function: Irccd.Unicode.isDigit(code) + * -------------------------------------------------------- + * + * Arguments: + * - code, the code point. + * Returns: + * True if the code is in the digit category. + */ +duk_ret_t is_digit(duk_context* ctx) +{ + duk_push_boolean(ctx, unicode::isdigit(duk_get_int(ctx, 0))); + + return 1; +} + +/* + * Function: Irccd.Unicode.isLetter(code) + * -------------------------------------------------------- + * + * Arguments: + * - code, the code point. + * Returns: + * True if the code is in the letter category. + */ +duk_ret_t is_letter(duk_context* ctx) +{ + duk_push_boolean(ctx, unicode::isalpha(duk_get_int(ctx, 0))); + + return 1; +} + +/* + * Function: Irccd.Unicode.isLower(code) + * -------------------------------------------------------- + * + * Arguments: + * - code, the code point. + * Returns: + * True if the code is lower case. + */ +duk_ret_t is_lower(duk_context* ctx) +{ + duk_push_boolean(ctx, unicode::islower(duk_get_int(ctx, 0))); + + return 1; +} + +/* + * Function: Irccd.Unicode.isSpace(code) + * -------------------------------------------------------- + * + * Arguments: + * - code, the code point. + * Returns: + * True if the code is in the space category. + */ +duk_ret_t is_space(duk_context* ctx) +{ + duk_push_boolean(ctx, unicode::isspace(duk_get_int(ctx, 0))); + + return 1; +} + +/* + * Function: Irccd.Unicode.isTitle(code) + * -------------------------------------------------------- + * + * Arguments: + * - code, the code point. + * Returns: + * True if the code is title case. + */ +duk_ret_t is_title(duk_context* ctx) +{ + duk_push_boolean(ctx, unicode::istitle(duk_get_int(ctx, 0))); + + return 1; +} + +/* + * Function: Irccd.Unicode.isUpper(code) + * -------------------------------------------------------- + * + * Arguments: + * - code, the code point. + * Returns: + * True if the code is upper case. + */ +duk_ret_t is_upper(duk_context* ctx) +{ + duk_push_boolean(ctx, unicode::isupper(duk_get_int(ctx, 0))); + + return 1; +} + +const duk_function_list_entry functions[] = { + { "isDigit", is_digit, 1 }, + { "isLetter", is_letter, 1 }, + { "isLower", is_lower, 1 }, + { "isSpace", is_space, 1 }, + { "isTitle", is_title, 1 }, + { "isUpper", is_upper, 1 }, + { nullptr, nullptr, 0 } +}; + +} // !namespace + +js_unicode_module::js_unicode_module() noexcept + : module("Irccd.Unicode") +{ +} + +void js_unicode_module::load(irccd&, std::shared_ptr<js_plugin> plugin) +{ + StackAssert sa(plugin->context()); + + duk_get_global_string(plugin->context(), "Irccd"); + duk_push_object(plugin->context()); + duk_put_function_list(plugin->context(), -1, functions); + duk_put_prop_string(plugin->context(), -2, "Unicode"); + duk_pop(plugin->context()); +} + +} // !irccd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libirccd-js/irccd/js_unicode_module.hpp Tue Sep 26 17:18:47 2017 +0200 @@ -0,0 +1,50 @@ +/* + * js_unicode_module.hpp -- Irccd.Unicode API + * + * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef IRCCD_JS_UNICODE_MODULE_HPP +#define IRCCD_JS_UNICODE_MODULE_HPP + +/** + * \file js_unicode_module.hpp + * \brief irccd.Unicode JavaScript API. + */ + +#include "module.hpp" + +namespace irccd { + +/** + * \brief Irccd.Unicode JavaScript API. + * \ingroup modules + */ +class js_unicode_module : public module { +public: + /** + * Constructor. + */ + js_unicode_module() noexcept; + + /** + * \copydoc Module::load + */ + void load(irccd& irccd, std::shared_ptr<js_plugin> plugin) override; +}; + +} // !irccd + +#endif // !IRCCD_JS_UNICODE_MODULE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libirccd-js/irccd/js_util_module.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -0,0 +1,300 @@ +/* + * js_util_module.cpp -- Irccd.Util API + * + * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <climits> + +#include <libircclient.h> + +#include <irccd/util.hpp> + +#include "js_util_module.hpp" +#include "js_plugin.hpp" + +namespace irccd { + +namespace { + +/* + * Read parameters for irccd.Util.format function, the object is defined as + * following: + * + * { + * date: the date object + * flags: the flags (not implemented yet) + * field1: a field to substitute in #{} pattern + * field2: a field to substitute in #{} pattern + * fieldn: ... + * } + */ +util::subst get_subst(duk_context* ctx, int index) +{ + util::subst params; + + if (!duk_is_object(ctx, index)) + return params; + + dukx_enumerate(ctx, index, 0, true, [&] (auto) { + if (dukx_get_std_string(ctx, -2) == "date") + params.time = static_cast<time_t>(duk_get_number(ctx, -1) / 1000); + else + params.keywords.insert({dukx_get_std_string(ctx, -2), dukx_get_std_string(ctx, -1)}); + }); + + return params; +} + +/* + * split (for Irccd.Util.cut) + * ------------------------------------------------------------------ + * + * Extract individual tokens in array or a whole string as a std:::vector. + */ +std::vector<std::string> split(duk_context* ctx) +{ + duk_require_type_mask(ctx, 0, DUK_TYPE_MASK_OBJECT | DUK_TYPE_MASK_STRING); + + std::vector<std::string> result; + std::string pattern = " \t\n"; + + if (duk_is_string(ctx, 0)) + result = util::split(dukx_get_std_string(ctx, 0), pattern); + else if (duk_is_array(ctx, 0)) { + duk_enum(ctx, 0, DUK_ENUM_ARRAY_INDICES_ONLY); + + while (duk_next(ctx, -1, 1)) { + // Split individual tokens as array if spaces are found. + auto tmp = util::split(duk_to_string(ctx, -1), pattern); + + result.insert(result.end(), tmp.begin(), tmp.end()); + duk_pop_2(ctx); + } + } + + return result; +} + +/* + * limit (for Irccd.Util.cut) + * ------------------------------------------------------------------ + * + * Get the maxl/maxc argument. + * + * The argument value is the default and also used as the result returned. + */ +int limit(duk_context* ctx, int index, const char* name, int value) +{ + if (duk_get_top(ctx) < index || !duk_is_number(ctx, index)) + return value; + + value = duk_to_int(ctx, index); + + if (value <= 0) + duk_error(ctx, DUK_ERR_RANGE_ERROR, "argument %d (%s) must be positive", index, name); + + return value; +} + +/* + * lines (for Irccd.Util.cut) + * ------------------------------------------------------------------ + * + * Build a list of lines. + * + * Several cases possible: + * + * - s is the current line + * - abc is the token to add + * + * s = "" (new line) + * s -> "abc" + * + * s = "hello world" (enough room) + * s -> "hello world abc" + * + * s = "hello world" (not enough room: maxc is smaller) + * s+1 = "abc" + */ +std::vector<std::string> lines(duk_context* ctx, const std::vector<std::string>& tokens, int maxc) +{ + std::vector<std::string> result{""}; + + for (const auto& s : tokens) { + if (s.length() > static_cast<std::size_t>(maxc)) + duk_error(ctx, DUK_ERR_RANGE_ERROR, "word '%s' could not fit in maxc limit (%d)", s.c_str(), maxc); + + // Compute the length required (prepend a space if needed) + auto required = s.length() + (result.back().empty() ? 0 : 1); + + if (result.back().length() + required > static_cast<std::size_t>(maxc)) + result.push_back(s); + else { + if (!result.back().empty()) + result.back() += ' '; + + result.back() += s; + } + } + + return result; +} + +/* + * Function: Irccd.Util.cut(data, maxc, maxl) + * -------------------------------------------------------- + * + * Cut a piece of data into several lines. + * + * The argument data is a string or a list of strings. In any case, all strings + * are first splitted by spaces and trimmed. This ensure that useless + * whitespaces are discarded. + * + * The argument maxc controls the maximum of characters allowed per line, it can + * be a positive integer. If undefined is given, a default of 72 is used. + * + * The argument maxl controls the maximum of lines allowed. It can be a positive + * integer or undefined for an infinite list. + * + * If maxl is used as a limit and the data can not fit within the bounds, + * undefined is returned. + * + * An empty list may be returned if empty strings were found. + * + * Arguments: + * - data, a string or an array of strings, + * - maxc, max number of colums (Optional, default: 72), + * - maxl, max number of lines (Optional, default: undefined). + * Returns: + * A list of strings ready to be sent or undefined if the data is too big. + * Throws: + * - RangeError if maxl or maxc are negative numbers, + * - RangeError if one word length was bigger than maxc, + * - TypeError if data is not a string or a list of strings. + */ +duk_ret_t cut(duk_context* ctx) +{ + auto list = lines(ctx, split(ctx), limit(ctx, 1, "maxc", 72)); + auto maxl = limit(ctx, 2, "maxl", INT_MAX); + + if (list.size() > static_cast<std::size_t>(maxl)) + return 0; + + // Empty list but lines() returns at least one. + if (list.size() == 1 && list[0].empty()) { + duk_push_array(ctx); + return 1; + } + + dukx_push_array(ctx, list, dukx_push_std_string); + + return 1; +} + +/* + * Function: Irccd.Util.format(text, parameters) + * -------------------------------------------------------- + * + * Format a string with templates. + * + * Arguments: + * - input, the text to update, + * - params, the parameters. + * Returns: + * The converted text. + */ +duk_ret_t format(duk_context* ctx) +{ + try { + dukx_push_std_string(ctx, util::format(dukx_get_std_string(ctx, 0), get_subst(ctx, 1))); + } catch (const std::exception &ex) { + dukx_throw(ctx, SyntaxError(ex.what())); + } + + return 1; +} + +/* + * Function: Irccd.Util.splituser(ident) + * -------------------------------------------------------- + * + * Return the nickname part from a full username. + * + * Arguments: + * - ident, the full identity. + * Returns: + * The nickname. + */ +duk_ret_t splituser(duk_context* ctx) +{ + auto target = duk_require_string(ctx, 0); + char nick[32] = {0}; + + irc_target_get_nick(target, nick, sizeof (nick) -1); + duk_push_string(ctx, nick); + + return 1; +} + +/* + * Function: Irccd.Util.splithost(ident) + * -------------------------------------------------------- + * + * Return the hostname part from a full username. + * + * Arguments: + * - ident, the full identity. + * Returns: + * The hostname. + */ +duk_ret_t splithost(duk_context* ctx) +{ + auto target = duk_require_string(ctx, 0); + char host[32] = {0}; + + irc_target_get_host(target, host, sizeof (host) -1); + duk_push_string(ctx, host); + + return 1; +} + +const duk_function_list_entry functions[] = { + { "cut", cut, DUK_VARARGS }, + { "format", format, DUK_VARARGS }, + { "splituser", splituser, 1 }, + { "splithost", splithost, 1 }, + { nullptr, nullptr, 0 } +}; + +} // !namespace + +js_util_module::js_util_module() noexcept + : module("Irccd.Util") +{ +} + +void js_util_module::load(irccd&, std::shared_ptr<js_plugin> plugin) +{ + StackAssert sa(plugin->context()); + + duk_get_global_string(plugin->context(), "Irccd"); + duk_push_object(plugin->context()); + duk_put_function_list(plugin->context(), -1, functions); + duk_put_prop_string(plugin->context(), -2, "Util"); + duk_pop(plugin->context()); +} + +} // !irccd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libirccd-js/irccd/js_util_module.hpp Tue Sep 26 17:18:47 2017 +0200 @@ -0,0 +1,50 @@ +/* + * js_util_module.hpp -- Irccd.Util API + * + * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef IRCCD_JS_UTIL_MODULE_HPP +#define IRCCD_JS_UTIL_MODULE_HPP + +/** + * \file js_util_module.hpp + * \brief irccd.Util JavaScript API. + */ + +#include "module.hpp" + +namespace irccd { + +/** + * \brief Irccd.Util JavaScript API. + * \ingroup modules + */ +class js_util_module : public module { +public: + /** + * Constructor. + */ + js_util_module() noexcept; + + /** + * \copydoc module::load + */ + void load(irccd& irccd, std::shared_ptr<js_plugin> plugin) override; +}; + +} // !irccd + +#endif // !IRCCD_MOD_UTIL_HPP
--- a/libirccd-js/irccd/mod-directory.cpp Fri Aug 11 13:45:42 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,386 +0,0 @@ -/* - * mod-directory.cpp -- Irccd.Directory API - * - * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <cerrno> -#include <cstdio> -#include <cstring> -#include <fstream> -#include <regex> -#include <stdexcept> -#include <string> - -#include <boost/filesystem.hpp> - -#include "duktape.hpp" -#include "fs.hpp" -#include "mod-directory.hpp" -#include "mod-irccd.hpp" -#include "plugin-js.hpp" -#include "sysconfig.hpp" - -namespace irccd { - -namespace { - -std::string path(duk_context *ctx) -{ - duk_push_this(ctx); - duk_get_prop_string(ctx, -1, "path"); - - if (duk_get_type(ctx, -1) != DUK_TYPE_STRING) - duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a Directory object"); - - auto ret = dukx_get_std_string(ctx, -1); - - if (ret.empty()) - duk_error(ctx, DUK_ERR_TYPE_ERROR, "directory object has empty path"); - - duk_pop_n(ctx, 2); - - return ret; -} - -/* - * Find an entry recursively (or not) in a directory using a predicate which can - * be used to test for regular expression, equality. - * - * Do not use this function directly, use: - * - * - findName - * - findRegex - */ -template <typename Pred> -std::string findPath(const std::string &base, bool recursive, Pred pred) -{ - /* - * For performance reason, we first iterate over all entries that are - * not directories to avoid going deeper recursively if the requested - * file is in the current directory. - */ - auto entries = fs::readdir(base); - - for (const auto &entry : entries) - if (entry.type != fs::Entry::Dir && pred(entry.name)) - return base + entry.name; - - if (!recursive) - return ""; - - for (const auto &entry : entries) { - if (entry.type == fs::Entry::Dir) { - std::string next = base + entry.name + fs::separator(); - std::string path = findPath(next, true, pred); - - if (!path.empty()) - return path; - } - } - - return ""; -} - -/* - * Helper for finding by equality. - */ -std::string findName(std::string base, const std::string &pattern, bool recursive) -{ - return findPath(base, recursive, [&] (const std::string &entryname) -> bool { - return pattern == entryname; - }); -} - -/* - * Helper for finding by regular expression - */ -std::string findRegex(const std::string &base, std::string pattern, bool recursive) -{ - std::regex regexp(pattern, std::regex::ECMAScript); - std::smatch smatch; - - return findPath(base, recursive, [&] (const std::string &entryname) -> bool { - return std::regex_match(entryname, smatch, regexp); - }); -} - -/* - * Generic find function for: - * - * - Directory.find - * - Directory.prototype.find - * - * The patternIndex is the argument where to test if the argument is a regex or - * a string. - */ -duk_ret_t find(duk_context *ctx, std::string base, bool recursive, int patternIndex) -{ - try { - std::string path; - - if (duk_is_string(ctx, patternIndex)) - path = findName(base, duk_get_string(ctx, patternIndex), recursive); - else { - // Check if it's a valid RegExp object. - duk_get_global_string(ctx, "RegExp"); - auto isRegex = duk_instanceof(ctx, patternIndex, -1); - duk_pop(ctx); - - if (isRegex) { - duk_get_prop_string(ctx, patternIndex, "source"); - auto pattern = duk_to_string(ctx, -1); - duk_pop(ctx); - - path = findRegex(base, pattern, recursive); - } else - duk_error(ctx, DUK_ERR_TYPE_ERROR, "pattern must be a string or a regex expression"); - } - - if (path.empty()) - return 0; - - dukx_push_std_string(ctx, path); - } catch (const std::exception &ex) { - duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); - } - - return 1; -} - -/* - * Generic remove function for: - * - * - Directory.remove - * - Directory.prototype.remove - */ -duk_ret_t remove(duk_context *ctx, const std::string &path, bool recursive) -{ - boost::system::error_code ec; - - if (!boost::filesystem::is_directory(path, ec) || ec) { - dukx_throw(ctx, SystemError(EINVAL, "not a directory")); - } - - if (!recursive) { - boost::filesystem::remove(path, ec); - } else { - boost::filesystem::remove_all(path, ec); - } - - return 0; -} - -/* - * Method: Directory.find(pattern, recursive) - * -------------------------------------------------------- - * - * Synonym of Directory.find(path, pattern, recursive) but the path is taken - * from the directory object. - * - * Arguments: - * - pattern, the regular expression or file name, - * - recursive, set to true to search recursively (default: false). - * Returns: - * The path to the file or undefined if not found. - * Throws: - * - Any exception on error. - */ -duk_ret_t methodFind(duk_context *ctx) -{ - return find(ctx, path(ctx), duk_get_boolean(ctx, 1), 0); -} - -/* - * Method: Directory.remove(recursive) - * -------------------------------------------------------- - * - * Synonym of Directory.remove(recursive) but the path is taken from the - * directory object. - * - * Arguments: - * - recursive, recursively or not (default: false). - * Throws: - * - Any exception on error. - */ -duk_ret_t methodRemove(duk_context *ctx) -{ - return remove(ctx, path(ctx), duk_get_boolean(ctx, 0)); -} - -const duk_function_list_entry methods[] = { - { "find", methodFind, DUK_VARARGS }, - { "remove", methodRemove, 1 }, - { nullptr, nullptr, 0 } -}; - -/* - * Directory "static" functions - * ------------------------------------------------------------------ - */ - -/* - * Function: Irccd.Directory(path, flags) [constructor] - * -------------------------------------------------------- - * - * Opens and read the directory at the specified path. - * - * Arguments: - * - path, the path to the directory, - * - flags, the optional flags (default: 0). - * Throws: - * - Any exception on error - */ -duk_ret_t constructor(duk_context *ctx) -{ - if (!duk_is_constructor_call(ctx)) - return 0; - - try { - std::string path = duk_require_string(ctx, 0); - std::int8_t flags = duk_get_uint(ctx, 1); - - if (!boost::filesystem::is_directory(path)) - dukx_throw(ctx, SystemError(EINVAL, "not a directory")); - - std::vector<fs::Entry> list = fs::readdir(path, flags); - - duk_push_this(ctx); - duk_push_string(ctx, "count"); - duk_push_int(ctx, list.size()); - duk_def_prop(ctx, -3, DUK_DEFPROP_ENUMERABLE | DUK_DEFPROP_HAVE_VALUE); - duk_push_string(ctx, "path"); - dukx_push_std_string(ctx, path); - duk_def_prop(ctx, -3, DUK_DEFPROP_ENUMERABLE | DUK_DEFPROP_HAVE_VALUE); - duk_push_string(ctx, "entries"); - duk_push_array(ctx); - - for (unsigned i = 0; i < list.size(); ++i) { - duk_push_object(ctx); - dukx_push_std_string(ctx, list[i].name); - duk_put_prop_string(ctx, -2, "name"); - duk_push_int(ctx, list[i].type); - duk_put_prop_string(ctx, -2, "type"); - duk_put_prop_index(ctx, -2, i); - } - - duk_def_prop(ctx, -3, DUK_DEFPROP_ENUMERABLE | DUK_DEFPROP_HAVE_VALUE); - } catch (const std::exception &ex) { - dukx_throw(ctx, SystemError(errno, ex.what())); - } - - return 0; -} - -/* - * Function: Irccd.Directory.find(path, pattern, recursive) - * -------------------------------------------------------- - * - * Find an entry by a pattern or a regular expression. - * - * Arguments: - * - path, the base path, - * - pattern, the regular expression or file name, - * - recursive, set to true to search recursively (default: false). - * Returns: - * The path to the file or undefined on errors or not found. - */ -duk_ret_t funcFind(duk_context *ctx) -{ - return find(ctx, duk_require_string(ctx, 0), duk_get_boolean(ctx, 2), 1); -} - -/* - * Function: Irccd.Directory.remove(path, recursive) - * -------------------------------------------------------- - * - * Remove the directory optionally recursively. - * - * Arguments: - * - path, the path to the directory, - * - recursive, recursively or not (default: false). - * Throws: - * - Any exception on error. - */ -duk_ret_t funcRemove(duk_context *ctx) -{ - return remove(ctx, duk_require_string(ctx, 0), duk_get_boolean(ctx, 1)); -} - -/* - * Function: Irccd.Directory.mkdir(path, mode = 0700) - * -------------------------------------------------------- - * - * Create a directory specified by path. It will create needed subdirectories - * just like you have invoked mkdir -p. - * - * Arguments: - * - path, the path to the directory, - * Throws: - * - Any exception on error. - */ -duk_ret_t funcMkdir(duk_context *ctx) -{ - try { - boost::filesystem::create_directories(duk_require_string(ctx, 0)); - } catch (const std::exception &ex) { - dukx_throw(ctx, SystemError(errno, ex.what())); - } - - return 0; -} - -const duk_function_list_entry functions[] = { - { "find", funcFind, DUK_VARARGS }, - { "mkdir", funcMkdir, DUK_VARARGS }, - { "remove", funcRemove, DUK_VARARGS }, - { nullptr, nullptr, 0 } -}; - -const duk_number_list_entry constants[] = { - { "Dot", static_cast<int>(fs::Dot) }, - { "DotDot", static_cast<int>(fs::DotDot) }, - { "TypeUnknown", static_cast<int>(fs::Entry::Unknown) }, - { "TypeDir", static_cast<int>(fs::Entry::Dir) }, - { "TypeFile", static_cast<int>(fs::Entry::File) }, - { "TypeLink", static_cast<int>(fs::Entry::Link) }, - { nullptr, 0 } -}; - -} // !namespace - -DirectoryModule::DirectoryModule() noexcept - : Module("Irccd.Directory") -{ -} - -void DirectoryModule::load(Irccd &, std::shared_ptr<JsPlugin> plugin) -{ - StackAssert sa(plugin->context()); - - duk_get_global_string(plugin->context(), "Irccd"); - duk_push_c_function(plugin->context(), constructor, 2); - duk_put_number_list(plugin->context(), -1, constants); - duk_put_function_list(plugin->context(), -1, functions); - dukx_push_std_string(plugin->context(), std::string{fs::separator()}); - duk_put_prop_string(plugin->context(), -2, "separator"); - duk_push_object(plugin->context()); - duk_put_function_list(plugin->context(), -1, methods); - duk_put_prop_string(plugin->context(), -2, "prototype"); - duk_put_prop_string(plugin->context(), -2, "Directory"); - duk_pop(plugin->context()); -} - -} // !irccd
--- a/libirccd-js/irccd/mod-directory.hpp Fri Aug 11 13:45:42 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* - * mod-directory.hpp -- Irccd.Directory API - * - * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef IRCCD_MOD_DIRECTORY_HPP -#define IRCCD_MOD_DIRECTORY_HPP - -/** - * \file mod-directory.hpp - * \brief Irccd.Directory JavaScript API. - */ - -#include "module.hpp" - -namespace irccd { - -/** - * \brief Irccd.Directory JavaScript API. - * \ingroup modules - */ -class DirectoryModule : public Module { -public: - /** - * Irccd.Directory. - */ - IRCCD_EXPORT DirectoryModule() noexcept; - - /** - * \copydoc Module::load - */ - IRCCD_EXPORT void load(Irccd &irccd, std::shared_ptr<JsPlugin> plugin) override; -}; - -} // !irccd - -#endif // !IRCCD_MOD_DIRECTORY_HPP
--- a/libirccd-js/irccd/mod-elapsed-timer.cpp Fri Aug 11 13:45:42 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,161 +0,0 @@ -/* - * mod-elapsed-timer.cpp -- Irccd.ElapsedTimer API - * - * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "elapsed-timer.hpp" -#include "mod-elapsed-timer.hpp" -#include "plugin-js.hpp" - -namespace irccd { - -namespace { - -const char *Signature("\xff""\xff""irccd-elapsed-timer-ptr"); - -ElapsedTimer *self(duk_context *ctx) -{ - StackAssert sa(ctx); - - duk_push_this(ctx); - duk_get_prop_string(ctx, -1, Signature); - auto ptr = static_cast<ElapsedTimer *>(duk_to_pointer(ctx, -1)); - duk_pop_2(ctx); - - if (!ptr) - duk_error(ctx, DUK_ERR_TYPE_ERROR, "not an ElapsedTimer object"); - - return ptr; -} - -/* - * Method: ElapsedTimer.pause - * ------------------------------------------------------------------ - * - * Pause the timer, without resetting the current elapsed time stored. - */ -duk_ret_t pause(duk_context *ctx) -{ - self(ctx)->pause(); - - return 0; -} - -/* - * Method: ElapsedTimer.reset - * ------------------------------------------------------------------ - * - * Reset the elapsed time to 0, the status is not modified. - */ -duk_ret_t reset(duk_context *ctx) -{ - self(ctx)->reset(); - - return 0; -} - -/* - * Method: ElapsedTimer.restart - * ------------------------------------------------------------------ - * - * Restart the timer without resetting the current elapsed time. - */ -duk_ret_t restart(duk_context *ctx) -{ - self(ctx)->restart(); - - return 0; -} - -/* - * Method: ElapsedTimer.elapsed - * ------------------------------------------------------------------ - * - * Get the number of elapsed milliseconds. - * - * Returns: - * The time elapsed. - */ -duk_ret_t elapsed(duk_context *ctx) -{ - duk_push_uint(ctx, self(ctx)->elapsed()); - - return 1; -} - -/* - * Function: Irccd.ElapsedTimer() [constructor] - * ------------------------------------------------------------------ - * - * Construct a new ElapsedTimer object. - */ -duk_ret_t constructor(duk_context *ctx) -{ - duk_push_this(ctx); - duk_push_pointer(ctx, new ElapsedTimer); - duk_put_prop_string(ctx, -2, Signature); - duk_pop(ctx); - - return 0; -} - -/* - * Function: Irccd.ElapsedTimer() [destructor] - * ------------------------------------------------------------------ - * - * Delete the property. - */ -duk_ret_t destructor(duk_context *ctx) -{ - duk_get_prop_string(ctx, 0, Signature); - delete static_cast<ElapsedTimer *>(duk_to_pointer(ctx, -1)); - duk_pop(ctx); - duk_del_prop_string(ctx, 0, Signature); - - return 0; -} - -const duk_function_list_entry methods[] = { - { "elapsed", elapsed, 0 }, - { "pause", pause, 0 }, - { "reset", reset, 0 }, - { "restart", restart, 0 }, - { nullptr, nullptr, 0 } -}; - -} // !namespace - -ElapsedTimerModule::ElapsedTimerModule() noexcept - : Module("Irccd.ElapsedTimer") -{ -} - -void ElapsedTimerModule::load(Irccd &, std::shared_ptr<JsPlugin> plugin) -{ - StackAssert sa(plugin->context()); - - duk_get_global_string(plugin->context(), "Irccd"); - duk_push_c_function(plugin->context(), constructor, 0); - duk_push_object(plugin->context()); - duk_put_function_list(plugin->context(), -1, methods); - duk_push_c_function(plugin->context(), destructor, 1); - duk_set_finalizer(plugin->context(), -2); - duk_put_prop_string(plugin->context(), -2, "prototype"); - duk_put_prop_string(plugin->context(), -2, "ElapsedTimer"); - duk_pop(plugin->context()); -} - -} // !irccd
--- a/libirccd-js/irccd/mod-elapsed-timer.hpp Fri Aug 11 13:45:42 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* - * mod-elapsed-timer.hpp -- Irccd.ElapsedTimer API - * - * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef IRCCD_MOD_ELAPSED_TIMER_HPP -#define IRCCD_MOD_ELAPSED_TIMER_HPP - -/** - * \file mod-elapsed-timer.hpp - * \brief Irccd.ElapsedTimer JavaScript API. - */ - -#include "module.hpp" - -namespace irccd { - -/** - * \brief Irccd.ElapsedTimer JavaScript API. - * \ingroup modules - */ -class ElapsedTimerModule : public Module { -public: - /** - * Irccd.ElapsedTimer. - */ - IRCCD_EXPORT ElapsedTimerModule() noexcept; - - /** - * \copydoc Module::load - */ - IRCCD_EXPORT void load(Irccd &irccd, std::shared_ptr<JsPlugin> plugin) override; -}; - -} // !irccd - -#endif // !IRCCD_MOD_ELAPSED_TIMER_HPP
--- a/libirccd-js/irccd/mod-file.cpp Fri Aug 11 13:45:42 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,699 +0,0 @@ -/* - * mod-file.cpp -- Irccd.File API - * - * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <algorithm> -#include <array> -#include <cassert> -#include <iterator> -#include <vector> - -#include <boost/filesystem.hpp> - -#include "sysconfig.hpp" - -#if defined(HAVE_STAT) -# include <sys/types.h> -# include <sys/stat.h> -#endif - -#include "fs.hpp" -#include "mod-file.hpp" -#include "mod-irccd.hpp" -#include "plugin-js.hpp" - -namespace irccd { - -namespace { - -const char *Signature("\xff""\xff""irccd-file-ptr"); -const char *Prototype("\xff""\xff""irccd-file-prototype"); - -#if defined(HAVE_STAT) - -/* - * pushStat - * ------------------------------------------------------------------ - */ - -void pushStat(duk_context *ctx, const struct stat &st) -{ - StackAssert sa(ctx, 1); - - duk_push_object(ctx); - -#if defined(HAVE_STAT_ST_ATIME) - duk_push_int(ctx, st.st_atime); - duk_put_prop_string(ctx, -2, "atime"); -#endif -#if defined(HAVE_STAT_ST_BLKSIZE) - duk_push_int(ctx, st.st_blksize); - duk_put_prop_string(ctx, -2, "blksize"); -#endif -#if defined(HAVE_STAT_ST_BLOCKS) - duk_push_int(ctx, st.st_blocks); - duk_put_prop_string(ctx, -2, "blocks"); -#endif -#if defined(HAVE_STAT_ST_CTIME) - duk_push_int(ctx, st.st_ctime); - duk_put_prop_string(ctx, -2, "ctime"); -#endif -#if defined(HAVE_STAT_ST_DEV) - duk_push_int(ctx, st.st_dev); - duk_put_prop_string(ctx, -2, "dev"); -#endif -#if defined(HAVE_STAT_ST_GID) - duk_push_int(ctx, st.st_gid); - duk_put_prop_string(ctx, -2, "gid"); -#endif -#if defined(HAVE_STAT_ST_INO) - duk_push_int(ctx, st.st_ino); - duk_put_prop_string(ctx, -2, "ino"); -#endif -#if defined(HAVE_STAT_ST_MODE) - duk_push_int(ctx, st.st_mode); - duk_put_prop_string(ctx, -2, "mode"); -#endif -#if defined(HAVE_STAT_ST_MTIME) - duk_push_int(ctx, st.st_mtime); - duk_put_prop_string(ctx, -2, "mtime"); -#endif -#if defined(HAVE_STAT_ST_NLINK) - duk_push_int(ctx, st.st_nlink); - duk_put_prop_string(ctx, -2, "nlink"); -#endif -#if defined(HAVE_STAT_ST_RDEV) - duk_push_int(ctx, st.st_rdev); - duk_put_prop_string(ctx, -2, "rdev"); -#endif -#if defined(HAVE_STAT_ST_SIZE) - duk_push_int(ctx, st.st_size); - duk_put_prop_string(ctx, -2, "size"); -#endif -#if defined(HAVE_STAT_ST_UID) - duk_push_int(ctx, st.st_uid); - duk_put_prop_string(ctx, -2, "uid"); -#endif -} - -#endif // !HAVE_STAT - -// Remove trailing \r for CRLF line style. -inline std::string clearCr(std::string input) -{ - if (input.length() > 0 && input.back() == '\r') - input.pop_back(); - - return input; -} - -File *self(duk_context *ctx) -{ - StackAssert sa(ctx); - - duk_push_this(ctx); - duk_get_prop_string(ctx, -1, Signature); - auto ptr = static_cast<File *>(duk_to_pointer(ctx, -1)); - duk_pop_2(ctx); - - if (!ptr) - duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a File object"); - - return ptr; -} - -/* - * File methods. - * ------------------------------------------------------------------ - */ - -/* - * Method: File.basename() - * -------------------------------------------------------- - * - * Synonym of `Irccd.File.basename(path)` but with the path from the file. - * - * duk_ret_turns: - * The base name. - */ -duk_ret_t methodBasename(duk_context *ctx) -{ - dukx_push_std_string(ctx, fs::baseName(self(ctx)->path())); - - return 1; -} - -/* - * Method: File.close() - * -------------------------------------------------------- - * - * Force close of the file, automatically called when object is collected. - */ -duk_ret_t methodClose(duk_context *ctx) -{ - self(ctx)->close(); - - return 0; -} - -/* - * Method: File.dirname() - * -------------------------------------------------------- - * - * Synonym of `Irccd.File.dirname(path)` but with the path from the file. - * - * duk_ret_turns: - * The directory name. - */ -duk_ret_t methodDirname(duk_context *ctx) -{ - dukx_push_std_string(ctx, fs::dirName(self(ctx)->path())); - - return 1; -} - -/* - * Method: File.lines() - * -------------------------------------------------------- - * - * Read all lines and return an array. - * - * duk_ret_turns: - * An array with all lines. - * Throws - * - Any exception on error. - */ -duk_ret_t methodLines(duk_context *ctx) -{ - duk_push_array(ctx); - - std::FILE *fp = self(ctx)->handle(); - std::string buffer; - std::array<char, 128> data; - std::int32_t i = 0; - - while (std::fgets(&data[0], data.size(), fp) != nullptr) { - buffer += data.data(); - - auto pos = buffer.find('\n'); - - if (pos != std::string::npos) { - dukx_push_std_string(ctx, clearCr(buffer.substr(0, pos))); - duk_put_prop_index(ctx, -2, i++); - - buffer.erase(0, pos + 1); - } - } - - // Maybe an error in the stream. - if (std::ferror(fp)) - dukx_throw(ctx, SystemError()); - - // Missing '\n' in end of file. - if (!buffer.empty()) { - dukx_push_std_string(ctx, clearCr(buffer)); - duk_put_prop_index(ctx, -2, i++); - } - - return 1; -} - -/* - * Method: File.read(amount) - * -------------------------------------------------------- - * - * Read the specified amount of characters or the whole file. - * - * Arguments: - * - amount, the amount of characters or -1 to read all (Optional, default: -1). - * duk_ret_turns: - * The string. - * Throws: - * - Any exception on error. - */ -duk_ret_t methodRead(duk_context *ctx) -{ - auto file = self(ctx); - auto amount = duk_is_number(ctx, 0) ? duk_get_int(ctx, 0) : -1; - - if (amount == 0 || file->handle() == nullptr) - return 0; - - try { - std::string data; - std::size_t total = 0; - - if (amount < 0) { - std::array<char, 128> buffer; - std::size_t nread; - - while ((nread = std::fread(&buffer[0], sizeof (buffer[0]), buffer.size(), file->handle())) > 0) { - if (std::ferror(file->handle())) - dukx_throw(ctx, SystemError()); - - std::copy(buffer.begin(), buffer.begin() + nread, std::back_inserter(data)); - total += nread; - } - } else { - data.resize((std::size_t)amount); - total = std::fread(&data[0], sizeof (data[0]), (std::size_t)amount, file->handle()); - - if (std::ferror(file->handle())) - dukx_throw(ctx, SystemError()); - - data.resize(total); - } - - dukx_push_std_string(ctx, data); - } catch (const std::exception &) { - dukx_throw(ctx, SystemError()); - } - - return 1; -} - -/* - * Method: File.readline() - * -------------------------------------------------------- - * - * Read the next line available. - * - * duk_ret_turns: - * The next line or undefined if eof. - * Throws: - * - Any exception on error. - */ -duk_ret_t methodReadline(duk_context *ctx) -{ - std::FILE *fp = self(ctx)->handle(); - std::string result; - - if (fp == nullptr || std::feof(fp)) - return 0; - for (int ch; (ch = std::fgetc(fp)) != EOF && ch != '\n'; ) - result += (char)ch; - if (std::ferror(fp)) - dukx_throw(ctx, SystemError()); - - dukx_push_std_string(ctx, clearCr(result)); - - return 1; -} - -/* - * Method: File.remove() - * -------------------------------------------------------- - * - * Synonym of File.remove(path) but with the path from the file. - * - * Throws: - * - Any exception on error. - */ -duk_ret_t methodRemove(duk_context *ctx) -{ - if (::remove(self(ctx)->path().c_str()) < 0) - dukx_throw(ctx, SystemError()); - - return 0; -} - -/* - * Method: File.seek(type, amount) - * -------------------------------------------------------- - * - * Sets the position in the file. - * - * Arguments: - * - type, the type of setting (File.SeekSet, File.SeekCur, File.SeekSet), - * - amount, the new offset. - * Throws: - * - Any exception on error. - */ -duk_ret_t methodSeek(duk_context *ctx) -{ - auto fp = self(ctx)->handle(); - auto type = duk_require_int(ctx, 0); - auto amount = duk_require_int(ctx, 1); - - if (fp != nullptr && std::fseek(fp, amount, type) != 0) - dukx_throw(ctx, SystemError()); - - return 0; -} - -#if defined(HAVE_STAT) - -/* - * Method: File.stat() [optional] - * -------------------------------------------------------- - * - * Synonym of File.stat(path) but with the path from the file. - * - * duk_ret_turns: - * The stat information. - * Throws: - * - Any exception on error. - */ -duk_ret_t methodStat(duk_context *ctx) -{ - auto file = self(ctx); - struct stat st; - - if (file->handle() == nullptr && ::stat(file->path().c_str(), &st) < 0) - dukx_throw(ctx, SystemError()); - else - pushStat(ctx, st); - - return 1; -} - -#endif // !HAVE_STAT - -/* - * Method: File.tell() - * -------------------------------------------------------- - * - * Get the actual position in the file. - * - * duk_ret_turns: - * The position. - * Throws: - * - Any exception on error. - */ -duk_ret_t methodTell(duk_context *ctx) -{ - auto fp = self(ctx)->handle(); - long pos; - - if (fp == nullptr) - return 0; - - if ((pos = std::ftell(fp)) == -1L) - dukx_throw(ctx, SystemError()); - else - duk_push_int(ctx, pos); - - return 1; -} - -/* - * Method: File.write(data) - * -------------------------------------------------------- - * - * Write some characters to the file. - * - * Arguments: - * - data, the character to write. - * duk_ret_turns: - * The number of bytes written. - * Throws: - * - Any exception on error. - */ -duk_ret_t methodWrite(duk_context *ctx) -{ - std::FILE *fp = self(ctx)->handle(); - std::string data = duk_require_string(ctx, 0); - - if (fp == nullptr) - return 0; - - std::size_t nwritten = std::fwrite(data.c_str(), 1, data.length(), fp); - - if (std::ferror(fp)) - dukx_throw(ctx, SystemError()); - - duk_push_uint(ctx, nwritten); - - return 1; -} - -const duk_function_list_entry methods[] = { - { "basename", methodBasename, 0 }, - { "close", methodClose, 0 }, - { "dirname", methodDirname, 0 }, - { "lines", methodLines, 0 }, - { "read", methodRead, 1 }, - { "readline", methodReadline, 0 }, - { "remove", methodRemove, 0 }, - { "seek", methodSeek, 2 }, -#if defined(HAVE_STAT) - { "stat", methodStat, 0 }, -#endif - { "tell", methodTell, 0 }, - { "write", methodWrite, 1 }, - { nullptr, nullptr, 0 } -}; - -/* - * File "static" functions - * ------------------------------------------------------------------ - */ - -/* - * Function: Irccd.File(path, mode) [constructor] - * -------------------------------------------------------- - * - * Open a file specified by path with the specified mode. - * - * Arguments: - * - path, the path to the file, - * - mode, the mode string. - * Throws: - * - Any exception on error. - */ -duk_ret_t constructor(duk_context *ctx) -{ - if (!duk_is_constructor_call(ctx)) - return 0; - - try { - dukx_new_file(ctx, new File(duk_require_string(ctx, 0), duk_require_string(ctx, 1))); - } catch (const std::exception &) { - dukx_throw(ctx, SystemError()); - } - - return 0; -} - -/* - * Function: Irccd.File() [destructor] - * ------------------------------------------------------------------ - * - * Delete the property. - */ -duk_ret_t destructor(duk_context *ctx) -{ - duk_get_prop_string(ctx, 0, Signature); - delete static_cast<File *>(duk_to_pointer(ctx, -1)); - duk_pop(ctx); - duk_del_prop_string(ctx, 0, Signature); - - return 0; -} - -/* - * Function: Irccd.File.basename(path) - * -------------------------------------------------------- - * - * duk_ret_turn the file basename as specified in `basename(3)` C function. - * - * Arguments: - * - path, the path to the file. - * duk_ret_turns: - * The base name. - */ -duk_ret_t functionBasename(duk_context *ctx) -{ - dukx_push_std_string(ctx, fs::baseName(duk_require_string(ctx, 0))); - - return 1; -} - -/* - * Function: Irccd.File.dirname(path) - * -------------------------------------------------------- - * - * duk_ret_turn the file directory name as specified in `dirname(3)` C function. - * - * Arguments: - * - path, the path to the file. - * duk_ret_turns: - * The directory name. - */ -duk_ret_t functionDirname(duk_context *ctx) -{ - dukx_push_std_string(ctx, fs::dirName(duk_require_string(ctx, 0))); - - return 1; -} - -/* - * Function: Irccd.File.exists(path) - * -------------------------------------------------------- - * - * Check if the file exists. - * - * Arguments: - * - path, the path to the file. - * duk_ret_turns: - * True if exists. - * Throws: - * - Any exception if we don't have access. - */ -duk_ret_t functionExists(duk_context *ctx) -{ - try { - duk_push_boolean(ctx, boost::filesystem::exists(duk_require_string(ctx, 0))); - } catch (...) { - duk_push_boolean(ctx, false); - } - - return 1; -} - -/* - * function Irccd.File.remove(path) - * -------------------------------------------------------- - * - * Remove the file at the specified path. - * - * Arguments: - * - path, the path to the file. - * Throws: - * - Any exception on error. - */ -duk_ret_t functionRemove(duk_context *ctx) -{ - if (::remove(duk_require_string(ctx, 0)) < 0) - dukx_throw(ctx, SystemError()); - - return 0; -} - -#if defined(HAVE_STAT) - -/* - * function Irccd.File.stat(path) [optional] - * -------------------------------------------------------- - * - * Get file information at the specified path. - * - * Arguments: - * - path, the path to the file. - * duk_ret_turns: - * The stat information. - * Throws: - * - Any exception on error. - */ -duk_ret_t functionStat(duk_context *ctx) -{ - struct stat st; - - if (::stat(duk_require_string(ctx, 0), &st) < 0) - dukx_throw(ctx, SystemError()); - - pushStat(ctx, st); - - return 1; -} - -#endif // !HAVE_STAT - -const duk_function_list_entry functions[] = { - { "basename", functionBasename, 1 }, - { "dirname", functionDirname, 1 }, - { "exists", functionExists, 1 }, - { "remove", functionRemove, 1 }, -#if defined(HAVE_STAT) - { "stat", functionStat, 1 }, -#endif - { nullptr, nullptr, 0 } -}; - -const duk_number_list_entry constants[] = { - { "SeekCur", SEEK_CUR }, - { "SeekEnd", SEEK_END }, - { "SeekSet", SEEK_SET }, - { nullptr, 0 } -}; - -} // !namespace - -FileModule::FileModule() noexcept - : Module("Irccd.File") -{ -} - -void FileModule::load(Irccd &, std::shared_ptr<JsPlugin> plugin) -{ - StackAssert sa(plugin->context()); - - duk_get_global_string(plugin->context(), "Irccd"); - duk_push_c_function(plugin->context(), constructor, 2); - duk_put_number_list(plugin->context(), -1, constants); - duk_put_function_list(plugin->context(), -1, functions); - duk_push_object(plugin->context()); - duk_put_function_list(plugin->context(), -1, methods); - duk_push_c_function(plugin->context(), destructor, 1); - duk_set_finalizer(plugin->context(), -2); - duk_dup(plugin->context(), -1); - duk_put_global_string(plugin->context(), Prototype); - duk_put_prop_string(plugin->context(), -2, "prototype"); - duk_put_prop_string(plugin->context(), -2, "File"); - duk_pop(plugin->context()); -} - -void dukx_new_file(duk_context *ctx, File *fp) -{ - assert(ctx); - assert(fp); - - StackAssert sa(ctx); - - duk_push_this(ctx); - duk_push_pointer(ctx, fp); - duk_put_prop_string(ctx, -2, Signature); - duk_pop(ctx); -} - -void dukx_push_file(duk_context *ctx, File *fp) -{ - assert(ctx); - assert(fp); - - StackAssert sa(ctx, 1); - - duk_push_object(ctx); - duk_push_pointer(ctx, fp); - duk_put_prop_string(ctx, -2, Signature); - duk_get_global_string(ctx, Prototype); - duk_set_prototype(ctx, -2); -} - -File *dukx_require_file(duk_context *ctx, duk_idx_t index) -{ - if (!duk_is_object(ctx, index) || !duk_has_prop_string(ctx, index, Signature)) - duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a File object"); - - duk_get_prop_string(ctx, index, Signature); - File *file = static_cast<File *>(duk_to_pointer(ctx, -1)); - duk_pop(ctx); - - return file; -} - -} // !irccd
--- a/libirccd-js/irccd/mod-file.hpp Fri Aug 11 13:45:42 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,184 +0,0 @@ -/* - * mod-file.hpp -- Irccd.File API - * - * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef IRCCD_MOD_FILE_HPP -#define IRCCD_MOD_FILE_HPP - -/** - * \file mod-file.hpp - * \brief Irccd.File JavaScript API. - */ - -#include <cassert> -#include <cerrno> -#include <cstdio> -#include <cstring> -#include <functional> -#include <stdexcept> -#include <string> - -#include "duktape.hpp" -#include "module.hpp" - -namespace irccd { - -/** - * \brief Object for Javascript to perform I/O. - * - * This class can be constructed to Javascript. - * - * It is used in: - * - * - Irccd.File [constructor] - * - Irccd.System.popen (optional) - */ -class File { -private: - File(const File &) = delete; - File &operator=(const File &) = delete; - - File(File &&) = delete; - File &operator=(File &&) = delete; - -private: - std::string m_path; - std::FILE *m_stream; - std::function<void (std::FILE *)> m_destructor; - -public: - /** - * Construct a file specified by path - * - * \param path the path - * \param mode the mode string (for std::fopen) - * \throw std::runtime_error on failures - */ - inline File(std::string path, const std::string &mode) - : m_path(std::move(path)) - , m_destructor([] (std::FILE *fp) { std::fclose(fp); }) - { - if ((m_stream = std::fopen(m_path.c_str(), mode.c_str())) == nullptr) - throw std::runtime_error(std::strerror(errno)); - } - - /** - * Construct a file from a already created FILE pointer (e.g. popen). - * - * The class takes ownership of fp and will close it. - * - * \pre destructor must not be null - * \param fp the file pointer - * \param destructor the function to close fp (e.g. std::fclose) - */ - inline File(std::FILE *fp, std::function<void (std::FILE *)> destructor) noexcept - : m_stream(fp) - , m_destructor(std::move(destructor)) - { - assert(m_destructor != nullptr); - } - - /** - * Closes the file. - */ - virtual ~File() noexcept - { - close(); - } - - /** - * Get the path. - * - * \return the path - * \warning empty when constructed from the FILE constructor - */ - inline const std::string &path() const noexcept - { - return m_path; - } - - /** - * Get the handle. - * - * \return the handle or nullptr if the stream was closed - */ - inline std::FILE *handle() noexcept - { - return m_stream; - } - - /** - * Force close, can be safely called multiple times. - */ - inline void close() noexcept - { - if (m_stream) { - m_destructor(m_stream); - m_stream = nullptr; - } - } -}; - -/** - * \brief Irccd.File JavaScript API. - * \ingroup modules - */ -class FileModule : public Module { -public: - /** - * Irccd.File. - */ - IRCCD_EXPORT FileModule() noexcept; - - /** - * \copydoc Module::load - */ - IRCCD_EXPORT void load(Irccd &irccd, std::shared_ptr<JsPlugin> plugin) override; -}; - -/** - * Construct the file as this. - * - * The object prototype takes ownership of fp and will be deleted once - * collected. - * - * \pre fp != nullptr - * \param ctx the the context - * \param fp the file - */ -IRCCD_EXPORT void dukx_new_file(duk_context *ctx, File *fp); - -/** - * Push a file. - * - * \pre fp != nullptr - * \param ctx the the context - * \param fp the file - */ -IRCCD_EXPORT void dukx_push_file(duk_context *ctx, File *fp); - -/** - * Require a file. Raises a JavaScript error if not a File. - * - * \param ctx the context - * \param index the index - */ -IRCCD_EXPORT File *dukx_require_file(duk_context *ctx, duk_idx_t index); - -} // !irccd - -#endif // !IRCCD_MOD_FILE_HPP
--- a/libirccd-js/irccd/mod-irccd.cpp Fri Aug 11 13:45:42 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,231 +0,0 @@ -/* - * mod-irccd.cpp -- Irccd API - * - * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <cerrno> -#include <string> -#include <unordered_map> - -#include "mod-irccd.hpp" -#include "plugin-js.hpp" -#include "sysconfig.hpp" - -namespace irccd { - -namespace { - -const std::unordered_map<std::string, int> errors{ - { "E2BIG", E2BIG }, - { "EACCES", EACCES }, - { "EADDRINUSE", EADDRINUSE }, - { "EADDRNOTAVAIL", EADDRNOTAVAIL }, - { "EAFNOSUPPORT", EAFNOSUPPORT }, - { "EAGAIN", EAGAIN }, - { "EALREADY", EALREADY }, - { "EBADF", EBADF }, -#if defined(EBADMSG) - { "EBADMSG", EBADMSG }, -#endif - { "EBUSY", EBUSY }, - { "ECANCELED", ECANCELED }, - { "ECHILD", ECHILD }, - { "ECONNABORTED", ECONNABORTED }, - { "ECONNREFUSED", ECONNREFUSED }, - { "ECONNRESET", ECONNRESET }, - { "EDEADLK", EDEADLK }, - { "EDESTADDRREQ", EDESTADDRREQ }, - { "EDOM", EDOM }, - { "EEXIST", EEXIST }, - { "EFAULT", EFAULT }, - { "EFBIG", EFBIG }, - { "EHOSTUNREACH", EHOSTUNREACH }, -#if defined(EIDRM) - { "EIDRM", EIDRM }, -#endif - { "EILSEQ", EILSEQ }, - { "EINPROGRESS", EINPROGRESS }, - { "EINTR", EINTR }, - { "EINVAL", EINVAL }, - { "EIO", EIO }, - { "EISCONN", EISCONN }, - { "EISDIR", EISDIR }, - { "ELOOP", ELOOP }, - { "EMFILE", EMFILE }, - { "EMLINK", EMLINK }, - { "EMSGSIZE", EMSGSIZE }, - { "ENAMETOOLONG", ENAMETOOLONG }, - { "ENETDOWN", ENETDOWN }, - { "ENETRESET", ENETRESET }, - { "ENETUNREACH", ENETUNREACH }, - { "ENFILE", ENFILE }, - { "ENOBUFS", ENOBUFS }, -#if defined(ENODATA) - { "ENODATA", ENODATA }, -#endif - { "ENODEV", ENODEV }, - { "ENOENT", ENOENT }, - { "ENOEXEC", ENOEXEC }, - { "ENOLCK", ENOLCK }, -#if defined(ENOLINK) - { "ENOLINK", ENOLINK }, -#endif - { "ENOMEM", ENOMEM }, -#if defined(ENOMSG) - { "ENOMSG", ENOMSG }, -#endif - { "ENOPROTOOPT", ENOPROTOOPT }, - { "ENOSPC", ENOSPC }, -#if defined(ENOSR) - { "ENOSR", ENOSR }, -#endif -#if defined(ENOSTR) - { "ENOSTR", ENOSTR }, -#endif - { "ENOSYS", ENOSYS }, - { "ENOTCONN", ENOTCONN }, - { "ENOTDIR", ENOTDIR }, - { "ENOTEMPTY", ENOTEMPTY }, -#if defined(ENOTRECOVERABLE) - { "ENOTRECOVERABLE", ENOTRECOVERABLE }, -#endif - { "ENOTSOCK", ENOTSOCK }, - { "ENOTSUP", ENOTSUP }, - { "ENOTTY", ENOTTY }, - { "ENXIO", ENXIO }, - { "EOPNOTSUPP", EOPNOTSUPP }, - { "EOVERFLOW", EOVERFLOW }, - { "EOWNERDEAD", EOWNERDEAD }, - { "EPERM", EPERM }, - { "EPIPE", EPIPE }, - { "EPROTO", EPROTO }, - { "EPROTONOSUPPORT", EPROTONOSUPPORT }, - { "EPROTOTYPE", EPROTOTYPE }, - { "ERANGE", ERANGE }, - { "EROFS", EROFS }, - { "ESPIPE", ESPIPE }, - { "ESRCH", ESRCH }, -#if defined(ETIME) - { "ETIME", ETIME }, -#endif - { "ETIMEDOUT", ETIMEDOUT }, -#if defined(ETXTBSY) - { "ETXTBSY", ETXTBSY }, -#endif - { "EWOULDBLOCK", EWOULDBLOCK }, - { "EXDEV", EXDEV } -}; - -duk_ret_t constructor(duk_context *ctx) -{ - duk_push_this(ctx); - duk_push_int(ctx, duk_require_int(ctx, 0)); - duk_put_prop_string(ctx, -2, "errno"); - duk_push_string(ctx, duk_require_string(ctx, 1)); - duk_put_prop_string(ctx, -2, "message"); - duk_push_string(ctx, "SystemError"); - duk_put_prop_string(ctx, -2, "name"); - duk_pop(ctx); - - return 0; -} - -} // !namespace - -SystemError::SystemError() - : m_errno(errno) - , m_message(std::strerror(m_errno)) -{ -} - -SystemError::SystemError(int e, std::string message) - : m_errno(e) - , m_message(std::move(message)) -{ -} - -void SystemError::raise(duk_context *ctx) const -{ - StackAssert sa(ctx, 0); - - duk_get_global_string(ctx, "Irccd"); - duk_get_prop_string(ctx, -1, "SystemError"); - duk_remove(ctx, -2); - duk_push_int(ctx, m_errno); - dukx_push_std_string(ctx, m_message); - duk_new(ctx, 2); - duk_throw(ctx); -} - -IrccdModule::IrccdModule() noexcept - : Module("Irccd") -{ -} - -void IrccdModule::load(Irccd &irccd, std::shared_ptr<JsPlugin> plugin) -{ - StackAssert sa(plugin->context()); - - // Irccd. - duk_push_object(plugin->context()); - - // Version. - duk_push_object(plugin->context()); - duk_push_int(plugin->context(), IRCCD_VERSION_MAJOR); - duk_put_prop_string(plugin->context(), -2, "major"); - duk_push_int(plugin->context(), IRCCD_VERSION_MINOR); - duk_put_prop_string(plugin->context(), -2, "minor"); - duk_push_int(plugin->context(), IRCCD_VERSION_PATCH); - duk_put_prop_string(plugin->context(), -2, "patch"); - duk_put_prop_string(plugin->context(), -2, "version"); - - // Create the SystemError that inherits from Error. - duk_push_c_function(plugin->context(), constructor, 2); - - // Put errno codes into the Irccd.SystemError object. - for (const auto &pair : errors) { - duk_push_int(plugin->context(), pair.second); - duk_put_prop_string(plugin->context(), -2, pair.first.c_str()); - } - - duk_push_object(plugin->context()); - duk_get_global_string(plugin->context(), "Error"); - duk_get_prop_string(plugin->context(), -1, "prototype"); - duk_remove(plugin->context(), -2); - duk_set_prototype(plugin->context(), -2); - duk_put_prop_string(plugin->context(), -2, "prototype"); - duk_put_prop_string(plugin->context(), -2, "SystemError"); - - // Set Irccd as global. - duk_put_global_string(plugin->context(), "Irccd"); - - // Store global instance. - duk_push_pointer(plugin->context(), &irccd); - duk_put_global_string(plugin->context(), "\xff""\xff""irccd-ref"); -} - -Irccd &dukx_get_irccd(duk_context *ctx) -{ - StackAssert sa(ctx); - - duk_get_global_string(ctx, "\xff""\xff""irccd-ref"); - Irccd *irccd = static_cast<Irccd *>(duk_to_pointer(ctx, -1)); - duk_pop(ctx); - - return *irccd; -} - -} // !irccd
--- a/libirccd-js/irccd/mod-irccd.hpp Fri Aug 11 13:45:42 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,93 +0,0 @@ -/* - * mod-irccd.hpp -- Irccd API - * - * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef IRCCD_MOD_IRCCD_HPP -#define IRCCD_MOD_IRCCD_HPP - -/** - * \file mod-irccd.hpp - * \brief Irccd JavaScript API. - */ - -#include <cerrno> -#include <cstring> -#include <string> - -#include "duktape.hpp" -#include "module.hpp" - -namespace irccd { - -/** - * \brief Custom JavaScript exception for system error. - */ -class SystemError { -private: - int m_errno; - std::string m_message; - -public: - /** - * Create a system error from the current errno value. - */ - IRCCD_EXPORT SystemError(); - - /** - * Create a system error with the given errno and message. - * - * \param e the errno number - * \param message the message - */ - IRCCD_EXPORT SystemError(int e, std::string message); - - /** - * Raise the SystemError. - * - * \param ctx the context - */ - IRCCD_EXPORT void raise(duk_context *ctx) const; -}; - -/** - * \brief Irccd JavaScript API. - * \ingroup modules - */ -class IrccdModule : public Module { -public: - /** - * Irccd. - */ - IRCCD_EXPORT IrccdModule() noexcept; - - /** - * \copydoc Module::load - */ - IRCCD_EXPORT void load(Irccd &irccd, std::shared_ptr<JsPlugin> plugin) override; -}; - -/** - * Get irccd instance stored in this context. - * - * \param ctx the context - * \return the irccd reference - */ -Irccd &dukx_get_irccd(duk_context *ctx); - -} // !irccd - -#endif // !IRCCD_MOD_IRCCD_HPP
--- a/libirccd-js/irccd/mod-logger.cpp Fri Aug 11 13:45:42 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,102 +0,0 @@ -/* - * mod-logger.cpp -- Irccd.Logger API - * - * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "mod-logger.hpp" -#include "mod-plugin.hpp" -#include "logger.hpp" -#include "plugin-js.hpp" - -namespace irccd { - -namespace { - -duk_ret_t print(duk_context *ctx, std::ostream &out) -{ - out << "plugin " << dukx_get_plugin(ctx)->name() << ": " << duk_require_string(ctx, 0) << std::endl; - - return 0; -} - -/* - * Function: Irccd.Logger.info(message) - * -------------------------------------------------------- - * - * Write a verbose message. - * - * Arguments: - * - message, the message. - */ -duk_ret_t info(duk_context *ctx) -{ - return print(ctx, log::info()); -} - -/* - * Function: Irccd.Logger.warning(message) - * -------------------------------------------------------- - * - * Write a warning message. - * - * Arguments: - * - message, the warning. - */ -duk_ret_t warning(duk_context *ctx) -{ - return print(ctx, log::warning()); -} - -/* - * Function: Logger.debug(message) - * -------------------------------------------------------- - * - * Write a debug message, only shown if irccd is compiled in debug. - * - * Arguments: - * - message, the message. - */ -duk_ret_t debug(duk_context *ctx) -{ - return print(ctx, log::debug()); -} - -const duk_function_list_entry functions[] = { - { "info", info, 1 }, - { "warning", warning, 1 }, - { "debug", debug, 1 }, - { nullptr, nullptr, 0 } -}; - -} // !namespace - -LoggerModule::LoggerModule() noexcept - : Module("Irccd.Logger") -{ -} - -void LoggerModule::load(Irccd &, std::shared_ptr<JsPlugin> plugin) -{ - StackAssert sa(plugin->context()); - - duk_get_global_string(plugin->context(), "Irccd"); - duk_push_object(plugin->context()); - duk_put_function_list(plugin->context(), -1, functions); - duk_put_prop_string(plugin->context(), -2, "Logger"); - duk_pop(plugin->context()); -} - -} // !irccd
--- a/libirccd-js/irccd/mod-logger.hpp Fri Aug 11 13:45:42 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* - * mod-logger.hpp -- Irccd.Logger API - * - * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef IRCCD_MOD_LOGGER_HPP -#define IRCCD_MOD_LOGGER_HPP - -/** - * \file mod-logger.hpp - * \brief Irccd.Logger JavaScript API. - */ - -#include "module.hpp" - -namespace irccd { - -/** - * \brief Irccd.Logger JavaScript API. - * \ingroup modules - */ -class LoggerModule : public Module { -public: - /** - * Irccd.Logger. - */ - IRCCD_EXPORT LoggerModule() noexcept; - - /** - * \copydoc Module::load - */ - IRCCD_EXPORT void load(Irccd &irccd, std::shared_ptr<JsPlugin> plugin) override; -}; - -} // !irccd - -#endif // !IRCCD_MOD_LOGGER_HPP
--- a/libirccd-js/irccd/mod-plugin.cpp Fri Aug 11 13:45:42 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,383 +0,0 @@ -/* - * mod-plugin.cpp -- Irccd.Plugin API - * - * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "irccd.hpp" -#include "plugin-js.hpp" -#include "service.hpp" -#include "mod-irccd.hpp" -#include "mod-plugin.hpp" - -namespace irccd { - -namespace { - -const char PluginGlobal[] = "\xff""\xff""irccd-plugin-ptr"; - -/* - * wrap - * ------------------------------------------------------------------ - * - * Wrap function for these functions because they all takes the same arguments. - * - * - load, - * - reload, - * - unload. - */ -template <typename Func> -duk_idx_t wrap(duk_context *ctx, int nret, Func &&func) -{ - std::string name = duk_require_string(ctx, 0); - - try { - func(dukx_get_irccd(ctx), name); - } catch (const std::out_of_range &ex) { - dukx_throw(ctx, ReferenceError(ex.what())); - } catch (const std::exception &ex) { - dukx_throw(ctx, Error(ex.what())); - } - - return nret; -} - -/* - * set - * ------------------------------------------------------------------ - * - * This setter is used to replace the Irccd.plugin->(config|format) property when - * the plugin assign a new one. - * - * Because the plugin configuration always has higher priority, when a new - * object is assigned to 'config' or to the 'format' property, the plugin - * configuration is merged to the assigned one, adding or replacing any values. - * - * Example: - * - * Plugin 'xyz' does: - * - * Irccd.plugin->config = { - * mode: "simple", - * level: "123" - * }; - * - * The user configuration is: - * - * [plugin->xyz] - * mode = "hard" - * path = "/var" - * - * The final user table looks like this: - * - * Irccd.plugin->config = { - * mode: "hard", - * level: "123", - * path: "/var" - */ -duk_ret_t set(duk_context *ctx, const char *name) -{ - if (!duk_is_object(ctx, 0)) - duk_error(ctx, DUK_ERR_TYPE_ERROR, "'%s' property must be object", name); - - // Merge old table with new one. - duk_get_global_string(ctx, name); - duk_enum(ctx, -1, 0); - - while (duk_next(ctx, -1, true)) - duk_put_prop(ctx, 0); - - // Pop enum and old table. - duk_pop_2(ctx); - - // Replace the old table with the new assigned one. - duk_put_global_string(ctx, name); - - return 0; -} - -/* - * get - * ------------------------------------------------------------------ - * - * Get the Irccd.plugin->(config|format|paths) property. - */ -duk_ret_t get(duk_context *ctx, const char *name) -{ - duk_get_global_string(ctx, name); - - return 1; -} - -/* - * setConfig - * ------------------------------------------------------------------ - * - * Wrap setter for Irccd.plugin->config property. - */ -duk_ret_t setConfig(duk_context *ctx) -{ - return set(ctx, JsPlugin::ConfigProperty); -} - -/* - * getConfig - * ------------------------------------------------------------------ - * - * Wrap getter for Irccd.plugin->config property. - */ -duk_ret_t getConfig(duk_context *ctx) -{ - return get(ctx, JsPlugin::ConfigProperty); -} - -/* - * setFormat - * ------------------------------------------------------------------ - * - * Wrap setter for Irccd.plugin->format property. - */ -duk_ret_t setFormat(duk_context *ctx) -{ - return set(ctx, JsPlugin::FormatProperty); -} - -/* - * getFormat - * ------------------------------------------------------------------ - * - * Wrap getter for Irccd.plugin->format property. - */ -duk_ret_t getFormat(duk_context *ctx) -{ - return get(ctx, JsPlugin::FormatProperty); -} - -/* - * setPaths - * ------------------------------------------------------------------ - * - * Wrap setter for Irccd.plugin->format property. - */ -duk_ret_t setPaths(duk_context *ctx) -{ - return set(ctx, JsPlugin::PathsProperty); -} - -/* - * getPaths - * ------------------------------------------------------------------ - * - * Wrap getter for Irccd.plugin->format property. - */ -duk_ret_t getPaths(duk_context *ctx) -{ - return get(ctx, JsPlugin::PathsProperty); -} - -/* - * Function: Irccd.plugin.info([name]) - * ------------------------------------------------------------------ - * - * Get information about a plugin-> - * - * The returned object as the following properties: - * - * - name: (string) the plugin identifier, - * - author: (string) the author, - * - license: (string) the license, - * - summary: (string) a short description, - * - version: (string) the version - * - * Arguments: - * - name, the plugin identifier, if not specified the current plugin is - * selected. - * Returns: - * The plugin information or undefined if the plugin was not found. - */ -duk_idx_t info(duk_context *ctx) -{ - std::shared_ptr<Plugin> plugin; - - if (duk_get_top(ctx) >= 1) - plugin = dukx_get_irccd(ctx).plugins().get(duk_require_string(ctx, 0)); - else - plugin = dukx_get_plugin(ctx); - - if (!plugin) - return 0; - - duk_push_object(ctx); - dukx_push_std_string(ctx, plugin->name()); - duk_put_prop_string(ctx, -2, "name"); - dukx_push_std_string(ctx, plugin->author()); - duk_put_prop_string(ctx, -2, "author"); - dukx_push_std_string(ctx, plugin->license()); - duk_put_prop_string(ctx, -2, "license"); - dukx_push_std_string(ctx, plugin->summary()); - duk_put_prop_string(ctx, -2, "summary"); - dukx_push_std_string(ctx, plugin->version()); - duk_put_prop_string(ctx, -2, "version"); - - return 1; -} - -/* - * Function: Irccd.plugin->list() - * ------------------------------------------------------------------ - * - * Get the list of plugins, the array returned contains all plugin names. - * - * Returns: - * The list of all plugin names. - */ -duk_idx_t list(duk_context *ctx) -{ - dukx_push_array(ctx, dukx_get_irccd(ctx).plugins().list(), [] (auto ctx, auto plugin) { - dukx_push_std_string(ctx, plugin->name()); - }); - - return 1; -} - -/* - * Function: Irccd.plugin->load(name) - * ------------------------------------------------------------------ - * - * Load a plugin by name. This function will search through the standard - * directories. - * - * Arguments: - * - name, the plugin identifier. - * Throws: - * - Error on errors, - * - ReferenceError if the plugin was not found. - */ -duk_idx_t load(duk_context *ctx) -{ - return wrap(ctx, 0, [&] (Irccd &irccd, const std::string &name) { - irccd.plugins().load(name); - }); -} - -/* - * Function: Irccd.plugin->reload(name) - * ------------------------------------------------------------------ - * - * Reload a plugin by name. - * - * Arguments: - * - name, the plugin identifier. - * Throws: - * - Error on errors, - * - ReferenceError if the plugin was not found. - */ -duk_idx_t reload(duk_context *ctx) -{ - return wrap(ctx, 0, [&] (Irccd &irccd, const std::string &name) { - irccd.plugins().reload(name); - }); -} - -/* - * Function: Irccd.plugin->unload(name) - * ------------------------------------------------------------------ - * - * Unload a plugin by name. - * - * Arguments: - * - name, the plugin identifier. - * Throws: - * - Error on errors, - * - ReferenceError if the plugin was not found. - */ -duk_idx_t unload(duk_context *ctx) -{ - return wrap(ctx, 0, [&] (Irccd &irccd, const std::string &name) { - irccd.plugins().unload(name); - }); -} - -const duk_function_list_entry functions[] = { - { "info", info, DUK_VARARGS }, - { "list", list, 0 }, - { "load", load, 1 }, - { "reload", reload, 1 }, - { "unload", unload, 1 }, - { nullptr, nullptr, 0 } -}; - -} // !namespace - -PluginModule::PluginModule() noexcept - : Module("Irccd.Plugin") -{ -} - -void PluginModule::load(Irccd &, std::shared_ptr<JsPlugin> plugin) -{ - StackAssert sa(plugin->context()); - - duk_push_pointer(plugin->context(), new std::weak_ptr<JsPlugin>(plugin)); - duk_push_object(plugin->context()); - duk_push_c_function(plugin->context(), [] (auto *ctx) -> duk_ret_t { - duk_get_global_string(ctx, PluginGlobal); - delete static_cast<std::shared_ptr<JsPlugin> *>(duk_to_pointer(ctx, -1)); - duk_pop(ctx); - duk_push_null(ctx); - duk_put_global_string(ctx, PluginGlobal); - return 0; - }, 1); - duk_set_finalizer(plugin->context(), -2); - duk_put_global_string(plugin->context(), "\xff""\xff""dummy-shared-ptr"); - duk_put_global_string(plugin->context(), PluginGlobal); - duk_get_global_string(plugin->context(), "Irccd"); - duk_push_object(plugin->context()); - duk_put_function_list(plugin->context(), -1, functions); - - // 'config' property. - duk_push_string(plugin->context(), "config"); - duk_push_c_function(plugin->context(), getConfig, 0); - duk_push_c_function(plugin->context(), setConfig, 1); - duk_def_prop(plugin->context(), -4, DUK_DEFPROP_HAVE_GETTER | DUK_DEFPROP_HAVE_SETTER); - - // 'format' property. - duk_push_string(plugin->context(), "format"); - duk_push_c_function(plugin->context(), getFormat, 0); - duk_push_c_function(plugin->context(), setFormat, 1); - duk_def_prop(plugin->context(), -4, DUK_DEFPROP_HAVE_GETTER | DUK_DEFPROP_HAVE_SETTER); - - // 'format' property. - duk_push_string(plugin->context(), "paths"); - duk_push_c_function(plugin->context(), getPaths, 0); - duk_push_c_function(plugin->context(), setPaths, 1); - duk_def_prop(plugin->context(), -4, DUK_DEFPROP_HAVE_GETTER | DUK_DEFPROP_HAVE_SETTER); - - duk_put_prop_string(plugin->context(), -2, "Plugin"); - duk_pop(plugin->context()); -} - -std::shared_ptr<JsPlugin> dukx_get_plugin(duk_context *ctx) -{ - StackAssert sa(ctx); - - duk_get_global_string(ctx, PluginGlobal); - auto plugin = static_cast<std::weak_ptr<JsPlugin> *>(duk_to_pointer(ctx, -1)); - duk_pop(ctx); - - return plugin->lock(); -} - -} // !irccd
--- a/libirccd-js/irccd/mod-plugin.hpp Fri Aug 11 13:45:42 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,59 +0,0 @@ -/* - * mod-plugin.hpp -- Irccd.Plugin API - * - * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef IRCCD_MOD_PLUGIN_HPP -#define IRCCD_MOD_PLUGIN_HPP - -/** - * \file mod-plugin.hpp - * \brief Irccd.Plugin JavaScript API. - */ - -#include "duktape.hpp" -#include "module.hpp" - -namespace irccd { - -/** - * \brief Irccd.Plugin JavaScript API. - * \ingroup modules - */ -class PluginModule : public Module { -public: - /** - * Irccd.Plugin. - */ - IRCCD_EXPORT PluginModule() noexcept; - - /** - * \copydoc Module::load - */ - IRCCD_EXPORT void load(Irccd &irccd, std::shared_ptr<JsPlugin> plugin) override; -}; - -/** - * Access the plugin stored in this context. - * - * \param ctx the context - * \return the plugin - */ -std::shared_ptr<irccd::JsPlugin> dukx_get_plugin(duk_context *ctx); - -} // !irccd - -#endif // !IRCCD_MOD_PLUGIN_HPP
--- a/libirccd-js/irccd/mod-server.cpp Fri Aug 11 13:45:42 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,580 +0,0 @@ -/* - * mod-server.cpp -- Irccd.Server API - * - * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <cassert> -#include <sstream> -#include <unordered_map> - -#include "irccd.hpp" -#include "mod-irccd.hpp" -#include "mod-server.hpp" -#include "plugin-js.hpp" -#include "server.hpp" -#include "service.hpp" - -namespace irccd { - -namespace { - -const char *Signature("\xff""\xff""irccd-server-ptr"); -const char *Prototype("\xff""\xff""irccd-server-prototype"); - -std::shared_ptr<Server> self(duk_context *ctx) -{ - StackAssert sa(ctx); - - duk_push_this(ctx); - duk_get_prop_string(ctx, -1, Signature); - auto ptr = duk_to_pointer(ctx, -1); - duk_pop_2(ctx); - - if (!ptr) - duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a Server object"); - - return *static_cast<std::shared_ptr<Server> *>(ptr); -} - -/* - * Method: Server.cmode(channel, mode) - * ------------------------------------------------------------------ - * - * Change a channel mode. - * - * Arguments: - * - channel, the channel, - * - mode, the mode. - */ -duk_ret_t cmode(duk_context *ctx) -{ - self(ctx)->cmode(duk_require_string(ctx, 0), duk_require_string(ctx, 1)); - - return 0; -} - -/* - * Method: Server.cnotice(channel, message) - * ------------------------------------------------------------------ - * - * Send a channel notice. - * - * Arguments: - * - channel, the channel, - * - message, the message. - */ -duk_ret_t cnotice(duk_context *ctx) -{ - self(ctx)->cnotice(duk_require_string(ctx, 0), duk_require_string(ctx, 1)); - - return 0; -} - -/* - * Method: Server.info() - * ------------------------------------------------------------------ - * - * Get the server information as an object containing the following properties: - * - * name: the server unique name - * host: the host name - * port: the port number - * ssl: true if using ssl - * sslVerify: true if ssl was verified - * channels: an array of all channels - */ -duk_ret_t info(duk_context *ctx) -{ - auto server = self(ctx); - - duk_push_object(ctx); - dukx_push_std_string(ctx, server->name()); - duk_put_prop_string(ctx, -2, "name"); - dukx_push_std_string(ctx, server->host()); - duk_put_prop_string(ctx, -2, "host"); - duk_push_int(ctx, server->port()); - duk_put_prop_string(ctx, -2, "port"); - duk_push_boolean(ctx, server->flags() & Server::Ssl); - duk_put_prop_string(ctx, -2, "ssl"); - duk_push_boolean(ctx, server->flags() & Server::SslVerify); - duk_put_prop_string(ctx, -2, "sslVerify"); - dukx_push_std_string(ctx, server->commandCharacter()); - duk_put_prop_string(ctx, -2, "commandChar"); - dukx_push_std_string(ctx, server->realname()); - duk_put_prop_string(ctx, -2, "realname"); - dukx_push_std_string(ctx, server->nickname()); - duk_put_prop_string(ctx, -2, "nickname"); - dukx_push_std_string(ctx, server->username()); - duk_put_prop_string(ctx, -2, "username"); - dukx_push_array(ctx, server->channels(), [&] (auto ctx, auto channel) { - dukx_push_std_string(ctx, channel); - }); - duk_put_prop_string(ctx, -2, "channels"); - - return 1; -} - -/* - * Method: Server.invite(target, channel) - * ------------------------------------------------------------------ - * - * Invite someone to a channel. - * - * Arguments: - * - target, the target to invite, - * - channel, the channel. - */ -duk_ret_t invite(duk_context *ctx) -{ - self(ctx)->invite(duk_require_string(ctx, 0), duk_require_string(ctx, 1)); - - return 0; -} - -/* - * Method: Server.join(channel, password = undefined) - * ------------------------------------------------------------------ - * - * Join a channel with an optional password. - * - * Arguments: - * - channel, the channel to join, - * - password, the password or undefined to not use. - */ -duk_ret_t join(duk_context *ctx) -{ - self(ctx)->join(duk_require_string(ctx, 0), dukx_get_std_string(ctx, 1)); - - return 0; -} - -/* - * Method: Server.kick(target, channel, reason = undefined) - * ------------------------------------------------------------------ - * - * Kick someone from a channel. - * - * Arguments: - * - target, the target to kick, - * - channel, the channel, - * - reason, the optional reason or undefined to not set. - */ -duk_ret_t kick(duk_context *ctx) -{ - self(ctx)->kick(duk_require_string(ctx, 0), duk_require_string(ctx, 1), dukx_get_std_string(ctx, 2)); - - return 0; -} - -/* - * Method: Server.me(target, message) - * ------------------------------------------------------------------ - * - * Send a CTCP Action. - * - * Arguments: - * - target, the target or a channel, - * - message, the message. - */ -duk_ret_t me(duk_context *ctx) -{ - self(ctx)->me(duk_require_string(ctx, 0), duk_require_string(ctx, 1)); - - return 0; -} - -/* - * Method: Server.message(target, message) - * ------------------------------------------------------------------ - * - * Send a message. - * - * Arguments: - * - target, the target or a channel, - * - message, the message. - */ -duk_ret_t message(duk_context *ctx) -{ - self(ctx)->message(duk_require_string(ctx, 0), duk_require_string(ctx, 1)); - - return 0; -} - -/* - * Method: Server.mode(mode) - * ------------------------------------------------------------------ - * - * Change your mode. - * - * Arguments: - * - mode, the new mode. - */ -duk_ret_t mode(duk_context *ctx) -{ - self(ctx)->mode(duk_require_string(ctx, 0)); - - return 0; -} - -/* - * Method: Server.names(channel) - * ------------------------------------------------------------------ - * - * Get the list of names from a channel. - * - * Arguments: - * - channel, the channel. - */ -duk_ret_t names(duk_context *ctx) -{ - self(ctx)->names(duk_require_string(ctx, 0)); - - return 0; -} - -/* - * Method: Server.nick(nickname) - * ------------------------------------------------------------------ - * - * Change the nickname. - * - * Arguments: - * - nickname, the nickname. - */ -duk_ret_t nick(duk_context *ctx) -{ - self(ctx)->setNickname(duk_require_string(ctx, 0)); - - return 0; -} - -/* - * Method: Server.notice(target, message) - * ------------------------------------------------------------------ - * - * Send a private notice. - * - * Arguments: - * - target, the target, - * - message, the notice message. - */ -duk_ret_t notice(duk_context *ctx) -{ - self(ctx)->notice(duk_require_string(ctx, 0), duk_require_string(ctx, 1)); - - return 0; -} - -/* - * Method: Server.part(channel, reason = undefined) - * ------------------------------------------------------------------ - * - * Leave a channel. - * - * Arguments: - * - channel, the channel to leave, - * - reason, the optional reason, keep undefined for portability. - */ -duk_ret_t part(duk_context *ctx) -{ - self(ctx)->part(duk_require_string(ctx, 0), dukx_get_std_string(ctx, 1)); - - return 0; -} - -/* - * Method: Server.send(raw) - * ------------------------------------------------------------------ - * - * Send a raw message to the IRC server. - * - * Arguments: - * - raw, the raw message (without terminators). - */ -duk_ret_t send(duk_context *ctx) -{ - self(ctx)->send(duk_require_string(ctx, 0)); - - return 0; -} - -/* - * Method: Server.topic(channel, topic) - * ------------------------------------------------------------------ - * - * Change a channel topic. - * - * Arguments: - * - channel, the channel, - * - topic, the new topic. - */ -duk_ret_t topic(duk_context *ctx) -{ - self(ctx)->topic(duk_require_string(ctx, 0), duk_require_string(ctx, 1)); - - return 0; -} - -/* - * Method: Server.whois(target) - * ------------------------------------------------------------------ - * - * Get whois information. - * - * Arguments: - * - target, the target. - */ -duk_ret_t whois(duk_context *ctx) -{ - self(ctx)->whois(duk_require_string(ctx, 0)); - - return 0; -} - -/* - * Method: Server.toString() - * ------------------------------------------------------------------ - * - * Convert the object to std::string, convenience for adding the object - * as property key. - * - * duk_ret_turns: - * The server name (unique). - */ -duk_ret_t toString(duk_context *ctx) -{ - dukx_push_std_string(ctx, self(ctx)->name()); - - return 1; -} - -/* - * Function: Irccd.Server(params) [constructor] - * ------------------------------------------------------------------ - * - * Construct a new server. - * - * Params must be filled with the following properties: - * - * name: the name, - * host: the host, - * ipv6: true to use ipv6, (Optional: default false) - * port: the port number, (Optional: default 6667) - * password: the password, (Optional: default none) - * channels: array of channels (Optiona: default empty) - * ssl: true to use ssl, (Optional: default false) - * sslVerify: true to verify (Optional: default true) - * nickname: "nickname", (Optional, default: irccd) - * username: "user name", (Optional, default: irccd) - * realname: "real name", (Optional, default: IRC Client Daemon) - * commandChar: "!", (Optional, the command char, default: "!") - */ -duk_ret_t constructor(duk_context *ctx) -{ - if (!duk_is_constructor_call(ctx)) - return 0; - - duk_check_type(ctx, 0, DUK_TYPE_OBJECT); - - try { - auto json = duk_json_encode(ctx, 0); - auto s = Server::fromJson(nlohmann::json::parse(json)); - - duk_push_this(ctx); - duk_push_pointer(ctx, new std::shared_ptr<Server>(std::move(s))); - duk_put_prop_string(ctx, -2, Signature); - duk_pop(ctx); - } catch (const std::exception &ex) { - duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); - } - - return 0; -} - -/* - * Function: Irccd.Server() [destructor] - * ------------------------------------------------------------------ - * - * Delete the property. - */ -duk_ret_t destructor(duk_context *ctx) -{ - duk_get_prop_string(ctx, 0, Signature); - delete static_cast<std::shared_ptr<Server> *>(duk_to_pointer(ctx, -1)); - duk_pop(ctx); - duk_del_prop_string(ctx, 0, Signature); - - return 0; -} - -/* - * Function: Irccd.Server.add(s) - * ------------------------------------------------------------------ - * - * Register a new server to the irccd instance. - * - * Arguments: - * - s, the server to add. - */ -duk_ret_t add(duk_context *ctx) -{ - dukx_get_irccd(ctx).servers().add(dukx_require_server(ctx, 0)); - - return 0; -} - -/* - * Function: Irccd.Server.find(name) - * ------------------------------------------------------------------ - * - * Find a server by name. - * - * Arguments: - * - name, the server name - * duk_ret_turns: - * The server object or undefined if not found. - */ -duk_ret_t find(duk_context *ctx) -{ - auto server = dukx_get_irccd(ctx).servers().get(duk_require_string(ctx, 0)); - - if (!server) - return 0; - - dukx_push_server(ctx, server); - - return 1; -} - -/* - * Function: Irccd.Server.list() - * ------------------------------------------------------------------ - * - * Get the map of all loaded servers. - * - * duk_ret_turns: - * An object with string-to-servers pairs. - */ -duk_ret_t list(duk_context *ctx) -{ - duk_push_object(ctx); - - for (const auto &server : dukx_get_irccd(ctx).servers().servers()) { - dukx_push_server(ctx, server); - duk_put_prop_string(ctx, -2, server->name().c_str()); - } - - return 1; -} - -/* - * Function: Irccd.Server.remove(name) - * ------------------------------------------------------------------ - * - * Remove a server from the irccd instance. You can pass the server object since - * it's coercible to a string. - * - * Arguments: - * - name the server name. - */ -duk_ret_t remove(duk_context *ctx) -{ - dukx_get_irccd(ctx).servers().remove(duk_require_string(ctx, 0)); - - return 0; -} - -const duk_function_list_entry methods[] = { - { "cmode", cmode, 2 }, - { "cnotice", cnotice, 2 }, - { "info", info, 0 }, - { "invite", invite, 2 }, - { "join", join, DUK_VARARGS }, - { "kick", kick, DUK_VARARGS }, - { "me", me, 2 }, - { "message", message, 2 }, - { "mode", mode, 1 }, - { "names", names, 1 }, - { "nick", nick, 1 }, - { "notice", notice, 2 }, - { "part", part, DUK_VARARGS }, - { "send", send, 1 }, - { "topic", topic, 2 }, - { "whois", whois, 1 }, - { "toString", toString, 0 }, - { nullptr, nullptr, 0 } -}; - -const duk_function_list_entry functions[] = { - { "add", add, 1 }, - { "find", find, 1 }, - { "list", list, 0 }, - { "remove", remove, 1 }, - { nullptr, nullptr, 0 } -}; - -} // !namespace - -ServerModule::ServerModule() noexcept - : Module("Irccd.Server") -{ -} - -void ServerModule::load(Irccd &, std::shared_ptr<JsPlugin> plugin) -{ - StackAssert sa(plugin->context()); - - duk_get_global_string(plugin->context(), "Irccd"); - duk_push_c_function(plugin->context(), constructor, 1); - duk_put_function_list(plugin->context(), -1, functions); - duk_push_object(plugin->context()); - duk_put_function_list(plugin->context(), -1, methods); - duk_push_c_function(plugin->context(), destructor, 1); - duk_set_finalizer(plugin->context(), -2); - duk_dup_top(plugin->context()); - duk_put_global_string(plugin->context(), Prototype); - duk_put_prop_string(plugin->context(), -2, "prototype"); - duk_put_prop_string(plugin->context(), -2, "Server"); - duk_pop(plugin->context()); -} - -void dukx_push_server(duk_context *ctx, std::shared_ptr<Server> server) -{ - assert(ctx); - assert(server); - - StackAssert sa(ctx, 1); - - duk_push_object(ctx); - duk_push_pointer(ctx, new std::shared_ptr<Server>(std::move(server))); - duk_put_prop_string(ctx, -2, Signature); - duk_get_global_string(ctx, Prototype); - duk_set_prototype(ctx, -2); -} - -std::shared_ptr<Server> dukx_require_server(duk_context *ctx, duk_idx_t index) -{ - if (!duk_is_object(ctx, index) || !duk_has_prop_string(ctx, index, Signature)) - duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a Server object"); - - duk_get_prop_string(ctx, index, Signature); - auto file = *static_cast<std::shared_ptr<Server> *>(duk_to_pointer(ctx, -1)); - duk_pop(ctx); - - return file; -} - -} // !irccd
--- a/libirccd-js/irccd/mod-server.hpp Fri Aug 11 13:45:42 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,70 +0,0 @@ -/* - * mod-server.hpp -- Irccd.Server API - * - * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef IRCCD_MOD_SERVER_HPP -#define IRCCD_MOD_SERVER_HPP - -/** - * \file mod-server.hpp - * \brief Irccd.Server JavaScript API. - */ - -#include "duktape.hpp" -#include "module.hpp" -#include "server.hpp" - -namespace irccd { - -/** - * \brief Irccd.Server JavaScript API. - * \ingroup modules - */ -class ServerModule : public Module { -public: - /** - * Irccd.Server. - */ - IRCCD_EXPORT ServerModule() noexcept; - - /** - * \copydoc Module::load - */ - IRCCD_EXPORT void load(Irccd &irccd, std::shared_ptr<JsPlugin> plugin) override; -}; - -/** - * Push a server. - * - * \pre server != nullptr - * \param ctx the context - * \param server the server - */ -IRCCD_EXPORT void dukx_push_server(duk_context *ctx, std::shared_ptr<Server> server); - -/** - * Require a server. Raise a JavaScript error if not a Server. - * - * \param ctx the context - * \param index the index - * \return the server - */ -IRCCD_EXPORT std::shared_ptr<Server> dukx_require_server(duk_context *ctx, duk_idx_t index); - -} // !irccd - -#endif // !IRCCD_JS_SERVER_HPP
--- a/libirccd-js/irccd/mod-system.cpp Fri Aug 11 13:45:42 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,243 +0,0 @@ -/* - * mod-system.cpp -- Irccd.System API - * - * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <chrono> -#include <cstdlib> -#include <thread> - -#include "sysconfig.hpp" - -#if defined(HAVE_POPEN) -# include <cstdio> -#endif - -#include "mod-file.hpp" -#include "mod-irccd.hpp" -#include "mod-system.hpp" -#include "plugin-js.hpp" -#include "system.hpp" - -namespace irccd { - -namespace { - -/* - * Function: Irccd.System.env(key) - * ------------------------------------------------------------------ - * - * Get an environment system variable. - * - * Arguments: - * - key, the environment variable. - * Returns: - * The value. - */ -duk_ret_t env(duk_context *ctx) -{ - dukx_push_std_string(ctx, sys::env(dukx_get_std_string(ctx, 0))); - - return 1; -} - -/* - * Function: Irccd.System.exec(cmd) - * ------------------------------------------------------------------ - * - * Execute a system command. - * - * Arguments: - * - cmd, the command to execute. - */ -duk_ret_t exec(duk_context *ctx) -{ - std::system(duk_get_string(ctx, 0)); - - return 0; -} - -/* - * Function: Irccd.System.home() - * ------------------------------------------------------------------ - * - * Get the operating system user's home. - * - * Returns: - * The user home directory. - */ -duk_ret_t home(duk_context *ctx) -{ - dukx_push_std_string(ctx, sys::home()); - - return 1; -} - -/* - * Function: Irccd.System.name() - * ------------------------------------------------------------------ - * - * Get the operating system name. - * - * Returns: - * The system name. - */ -duk_ret_t name(duk_context *ctx) -{ - dukx_push_std_string(ctx, sys::name()); - - return 1; -} - -#if defined(HAVE_POPEN) - -/* - * Function: Irccd.System.popen(cmd, mode) [optional] - * ------------------------------------------------------------------ - * - * Wrapper for popen(3) if the function is available. - * - * Arguments: - * - cmd, the command to execute, - * - mode, the mode (e.g. "r"). - * Returns: - * A Irccd.File object. - * Throws - * - Irccd.SystemError on failures. - */ -duk_ret_t popen(duk_context *ctx) -{ - auto fp = ::popen(duk_require_string(ctx, 0), duk_require_string(ctx, 1)); - - if (fp == nullptr) - dukx_throw(ctx, SystemError()); - - dukx_push_file(ctx, new File(fp, [] (std::FILE *fp) { ::pclose(fp); })); - - return 1; -} - -#endif // !HAVE_POPEN - -/* - * Function: Irccd.System.sleep(delay) - * ------------------------------------------------------------------ - * - * Sleep the main loop for the specific delay in seconds. - */ -duk_ret_t sleep(duk_context *ctx) -{ - std::this_thread::sleep_for(std::chrono::seconds(duk_get_int(ctx, 0))); - - return 0; -} - -/* - * Function: Irccd.System.ticks() - * ------------------------------------------------------------------ - * - * Get the number of milliseconds since irccd was started. - * - * Returns: - * The number of milliseconds. - */ -duk_ret_t ticks(duk_context *ctx) -{ - duk_push_int(ctx, sys::ticks()); - - return 1; -} - -/* - * Function: Irccd.System.usleep(delay) - * ------------------------------------------------------------------ - * - * Sleep the main loop for the specific delay in microseconds. - */ -duk_ret_t usleep(duk_context *ctx) -{ - std::this_thread::sleep_for(std::chrono::microseconds(duk_get_int(ctx, 0))); - - return 0; -} - -/* - * Function: Irccd.System.uptime() - * ------------------------------------------------------------------ - * - * Get the system uptime. - * - * Returns: - * The system uptime. - */ -duk_ret_t uptime(duk_context *ctx) -{ - duk_push_int(ctx, sys::uptime()); - - return 0; -} - -/* - * Function: Irccd.System.version() - * ------------------------------------------------------------------ - * - * Get the operating system version. - * - * Returns: - * The system version. - */ -duk_ret_t version(duk_context *ctx) -{ - dukx_push_std_string(ctx, sys::version()); - - return 1; -} - -const duk_function_list_entry functions[] = { - { "env", env, 1 }, - { "exec", exec, 1 }, - { "home", home, 0 }, - { "name", name, 0 }, -#if defined(HAVE_POPEN) - { "popen", popen, 2 }, -#endif - { "sleep", sleep, 1 }, - { "ticks", ticks, 0 }, - { "uptime", uptime, 0 }, - { "usleep", usleep, 1 }, - { "version", version, 0 }, - { nullptr, nullptr, 0 } -}; - -} // !namespace - -SystemModule::SystemModule() noexcept - : Module("Irccd.System") -{ -} - -void SystemModule::load(Irccd &, std::shared_ptr<JsPlugin> plugin) -{ - StackAssert sa(plugin->context()); - - duk_get_global_string(plugin->context(), "Irccd"); - duk_push_object(plugin->context()); - duk_put_function_list(plugin->context(), -1, functions); - duk_put_prop_string(plugin->context(), -2, "System"); - duk_pop(plugin->context()); -} - -} // !irccd
--- a/libirccd-js/irccd/mod-system.hpp Fri Aug 11 13:45:42 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* - * mod-system.hpp -- Irccd.System API - * - * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef IRCCD_MOD_SYSTEM_HPP -#define IRCCD_MOD_SYSTEM_HPP - -/** - * \file mod-system.hpp - * \brief Irccd.System JavaScript API. - */ - -#include "module.hpp" - -namespace irccd { - -/** - * \brief Irccd.System JavaScript API. - * \ingroup modules - */ -class SystemModule : public Module { -public: - /** - * Irccd.System. - */ - IRCCD_EXPORT SystemModule() noexcept; - - /** - * \copydoc Module::load - */ - IRCCD_EXPORT void load(Irccd &irccd, std::shared_ptr<JsPlugin> plugin) override; -}; - -} // !irccd - -#endif // !IRCCD_MOD_SYSTEM_HPP
--- a/libirccd-js/irccd/mod-timer.cpp Fri Aug 11 13:45:42 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,209 +0,0 @@ -/* - * mod-timer.cpp -- Irccd.Timer API - * - * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <format.h> - -#include "irccd.hpp" -#include "logger.hpp" -#include "mod-irccd.hpp" -#include "mod-timer.hpp" -#include "mod-plugin.hpp" -#include "plugin-js.hpp" -#include "timer.hpp" - -using namespace fmt::literals; - -namespace irccd { - -namespace { - -const char *Signature("\xff""\xff""irccd-timer-ptr"); -const char *CallbackTable("\xff""\xff""irccd-timer-callbacks"); - -void handleSignal(Irccd& irccd, std::weak_ptr<JsPlugin> ptr, std::string key) -{ - auto plugin = ptr.lock(); - - if (!plugin) - return; - - irccd.post([plugin, key] (Irccd &) { - StackAssert sa(plugin->context()); - - duk_get_global_string(plugin->context(), CallbackTable); - duk_get_prop_string(plugin->context(), -1, key.c_str()); - duk_remove(plugin->context(), -2); - - if (duk_is_callable(plugin->context(), -1)) { - if (duk_pcall(plugin->context(), 0) != 0) - log::warning("plugin {}: {}"_format(plugin->name(), dukx_exception(plugin->context(), -1).stack)); - else - duk_pop(plugin->context()); - } else - duk_pop(plugin->context()); - }); -} - -std::shared_ptr<Timer> self(duk_context *ctx) -{ - StackAssert sa(ctx); - - duk_push_this(ctx); - duk_get_prop_string(ctx, -1, Signature); - auto ptr = duk_to_pointer(ctx, -1); - duk_pop_2(ctx); - - if (!ptr) - duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a Timer object"); - - return *static_cast<std::shared_ptr<Timer> *>(ptr); -} - -/* - * Method: Timer.start() - * -------------------------------------------------------- - * - * Start the timer. If the timer is already started the method is a no-op. - */ -duk_ret_t start(duk_context *ctx) -{ - auto timer = self(ctx); - - if (!timer->isRunning()) - timer->start(); - - return 0; -} - -/* - * Method: Timer.stop() - * -------------------------------------------------------- - * - * Stop the timer. - */ -duk_ret_t stop(duk_context *ctx) -{ - auto timer = self(ctx); - - if (timer->isRunning()) - timer->stop(); - - return 0; -} - -const duk_function_list_entry methods[] = { - { "start", start, 0 }, - { "stop", stop, 0 }, - { nullptr, nullptr, 0 } -}; - -/* - * Function: Irccd.Timer(type, delay, callback) [constructor] - * -------------------------------------------------------- - * - * Create a new timer object. - * - * Arguments: - * - type, the type of timer (Irccd.Timer.Single or Irccd.Timer.Repeat), - * - delay, the interval in milliseconds, - * - callback, the function to call. - */ -duk_ret_t constructor(duk_context *ctx) -{ - // Check parameters. - auto type = duk_require_int(ctx, 0); - auto delay = duk_require_int(ctx, 1); - - if (type < static_cast<int>(TimerType::Single) || type > static_cast<int>(TimerType::Repeat)) - duk_error(ctx, DUK_ERR_TYPE_ERROR, "invalid timer type"); - if (delay < 0) - duk_error(ctx, DUK_ERR_TYPE_ERROR, "negative delay given"); - if (!duk_is_callable(ctx, 2)) - duk_error(ctx, DUK_ERR_TYPE_ERROR, "missing callback function"); - - // Construct the timer in 'this'. - auto &irccd = dukx_get_irccd(ctx); - auto timer = std::make_shared<Timer>(static_cast<TimerType>(type), delay); - auto hash = std::to_string(reinterpret_cast<std::uintptr_t>(timer.get())); - - timer->onSignal.connect(std::bind(handleSignal, std::ref(irccd), - std::weak_ptr<JsPlugin>(dukx_get_plugin(ctx)), hash)); - - duk_push_this(ctx); - duk_push_pointer(ctx, new std::shared_ptr<Timer>(std::move(timer))); - duk_put_prop_string(ctx, -2, Signature); - duk_push_string(ctx, hash.c_str()); - duk_put_prop_string(ctx, -2, "\xff""\xff""timer-key"); - duk_push_c_function(ctx, [] (duk_context *ctx) -> duk_ret_t { - StackAssert sa(ctx); - - duk_get_prop_string(ctx, 0, "\xff""\xff""timer-key"); - auto hash = duk_get_string(ctx, -1); - duk_pop(ctx); - duk_get_prop_string(ctx, 0, Signature); - static_cast<std::shared_ptr<Timer> *>(duk_to_pointer(ctx, -1))->get()->stop(); - delete static_cast<std::shared_ptr<Timer> *>(duk_to_pointer(ctx, -1)); - duk_pop(ctx); - duk_get_global_string(ctx, CallbackTable); - duk_del_prop_string(ctx, -1, hash); - duk_pop(ctx); - log::debug("plugin: timer destroyed"); - - return 0; - }, 1); - duk_set_finalizer(ctx, -2); - - // Save a callback function into the callback table. - duk_get_global_string(ctx, CallbackTable); - duk_dup(ctx, 2); - duk_put_prop_string(ctx, -2, hash.c_str()); - duk_pop(ctx); - - return 0; -} - -const duk_number_list_entry constants[] = { - { "Single", static_cast<int>(TimerType::Single) }, - { "Repeat", static_cast<int>(TimerType::Repeat) }, - { nullptr, 0 } -}; - -} // !namespace - -TimerModule::TimerModule() noexcept - : Module("Irccd.Timer") -{ -} - -void TimerModule::load(Irccd &, std::shared_ptr<JsPlugin> plugin) -{ - StackAssert sa(plugin->context()); - - duk_get_global_string(plugin->context(), "Irccd"); - duk_push_c_function(plugin->context(), constructor, 3); - duk_put_number_list(plugin->context(), -1, constants); - duk_push_object(plugin->context()); - duk_put_function_list(plugin->context(), -1, methods); - duk_put_prop_string(plugin->context(), -2, "prototype"); - duk_put_prop_string(plugin->context(), -2, "Timer"); - duk_pop(plugin->context()); - duk_push_object(plugin->context()); - duk_put_global_string(plugin->context(), CallbackTable); -} - -} // !irccd
--- a/libirccd-js/irccd/mod-timer.hpp Fri Aug 11 13:45:42 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* - * mod-timer.hpp -- Irccd.Timer API - * - * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef IRCCD_MOD_TIMER_HPP -#define IRCCD_MOD_TIMER_HPP - -/** - * \file mod-timer.hpp - * \brief Irccd.Timer JavaScript API. - */ - -#include "module.hpp" - -namespace irccd { - -/** - * \brief Irccd.Timer JavaScript API. - * \ingroup modules - */ -class TimerModule : public Module { -public: - /** - * Irccd.Timer. - */ - IRCCD_EXPORT TimerModule() noexcept; - - /** - * \copydoc Module::load - */ - IRCCD_EXPORT void load(Irccd &irccd, std::shared_ptr<JsPlugin> plugin) override; -}; - -} // !irccd - -#endif // !IRCCD_MOD_TIMER_HPP
--- a/libirccd-js/irccd/mod-unicode.cpp Fri Aug 11 13:45:42 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,152 +0,0 @@ -/* - * mod-unicode.cpp -- Irccd.Unicode API - * - * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "duktape.hpp" -#include "mod-unicode.hpp" -#include "plugin-js.hpp" -#include "unicode.hpp" - -namespace irccd { - -namespace { - -/* - * Function: Irccd.Unicode.isDigit(code) - * -------------------------------------------------------- - * - * Arguments: - * - code, the code point. - * Returns: - * True if the code is in the digit category. - */ -duk_ret_t isDigit(duk_context *ctx) -{ - duk_push_boolean(ctx, unicode::isdigit(duk_get_int(ctx, 0))); - - return 1; -} - -/* - * Function: Irccd.Unicode.isLetter(code) - * -------------------------------------------------------- - * - * Arguments: - * - code, the code point. - * Returns: - * True if the code is in the letter category. - */ -duk_ret_t isLetter(duk_context *ctx) -{ - duk_push_boolean(ctx, unicode::isalpha(duk_get_int(ctx, 0))); - - return 1; -} - -/* - * Function: Irccd.Unicode.isLower(code) - * -------------------------------------------------------- - * - * Arguments: - * - code, the code point. - * Returns: - * True if the code is lower case. - */ -duk_ret_t isLower(duk_context *ctx) -{ - duk_push_boolean(ctx, unicode::islower(duk_get_int(ctx, 0))); - - return 1; -} - -/* - * Function: Irccd.Unicode.isSpace(code) - * -------------------------------------------------------- - * - * Arguments: - * - code, the code point. - * Returns: - * True if the code is in the space category. - */ -duk_ret_t isSpace(duk_context *ctx) -{ - duk_push_boolean(ctx, unicode::isspace(duk_get_int(ctx, 0))); - - return 1; -} - -/* - * Function: Irccd.Unicode.isTitle(code) - * -------------------------------------------------------- - * - * Arguments: - * - code, the code point. - * Returns: - * True if the code is title case. - */ -duk_ret_t isTitle(duk_context *ctx) -{ - duk_push_boolean(ctx, unicode::istitle(duk_get_int(ctx, 0))); - - return 1; -} - -/* - * Function: Irccd.Unicode.isUpper(code) - * -------------------------------------------------------- - * - * Arguments: - * - code, the code point. - * Returns: - * True if the code is upper case. - */ -duk_ret_t isUpper(duk_context *ctx) -{ - duk_push_boolean(ctx, unicode::isupper(duk_get_int(ctx, 0))); - - return 1; -} - -const duk_function_list_entry functions[] = { - { "isDigit", isDigit, 1 }, - { "isLetter", isLetter, 1 }, - { "isLower", isLower, 1 }, - { "isSpace", isSpace, 1 }, - { "isTitle", isTitle, 1 }, - { "isUpper", isUpper, 1 }, - { nullptr, nullptr, 0 } -}; - -} // !namespace - -UnicodeModule::UnicodeModule() noexcept - : Module("Irccd.Unicode") -{ -} - -void UnicodeModule::load(Irccd &, std::shared_ptr<JsPlugin> plugin) -{ - StackAssert sa(plugin->context()); - - duk_get_global_string(plugin->context(), "Irccd"); - duk_push_object(plugin->context()); - duk_put_function_list(plugin->context(), -1, functions); - duk_put_prop_string(plugin->context(), -2, "Unicode"); - duk_pop(plugin->context()); -} - -} // !irccd
--- a/libirccd-js/irccd/mod-unicode.hpp Fri Aug 11 13:45:42 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* - * mod-unicode.cpp -- Irccd.Unicode API - * - * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef IRCCD_MOD_UNICODE_HPP -#define IRCCD_MOD_UNICODE_HPP - -/** - * \file mod-unicode.hpp - * \brief Irccd.Unicode JavaScript API. - */ - -#include "module.hpp" - -namespace irccd { - -/** - * \brief Irccd.Unicode JavaScript API. - * \ingroup modules - */ -class UnicodeModule : public Module { -public: - /** - * Irccd.Unicode. - */ - IRCCD_EXPORT UnicodeModule() noexcept; - - /** - * \copydoc Module::load - */ - IRCCD_EXPORT void load(Irccd &irccd, std::shared_ptr<JsPlugin> plugin) override; -}; - -} // !irccd - -#endif // !IRCCD_MOD_UNICODE_HPP
--- a/libirccd-js/irccd/mod-util.cpp Fri Aug 11 13:45:42 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,303 +0,0 @@ -/* - * mod-util.cpp -- Irccd.Util API - * - * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <climits> - -#include <libircclient.h> - -#include "mod-util.hpp" -#include "plugin-js.hpp" -#include "util.hpp" - -namespace irccd { - -namespace { - -/** - * Read parameters for Irccd.Util.format function, the object is defined as - * following: - * - * { - * date: the date object - * flags: the flags (not implemented yet) - * field1: a field to substitute in #{} pattern - * field2: a field to substitute in #{} pattern - * fieldn: ... - * } - */ -util::Substitution getSubstitution(duk_context *ctx, int index) -{ - util::Substitution params; - - if (!duk_is_object(ctx, index)) - return params; - - dukx_enumerate(ctx, index, 0, true, [&] (duk_context *) { - if (dukx_get_std_string(ctx, -2) == "date") - params.time = static_cast<time_t>(duk_get_number(ctx, -1) / 1000); - else - params.keywords.insert({dukx_get_std_string(ctx, -2), dukx_get_std_string(ctx, -1)}); - }); - - return params; -} - -/* - * split (for Irccd.Util.cut as cut) - * ------------------------------------------------------------------ - * - * Extract individual tokens in array or a whole string as a std:::vector. - */ -std::vector<std::string> split(duk_context *ctx) -{ - duk_require_type_mask(ctx, 0, DUK_TYPE_MASK_OBJECT | DUK_TYPE_MASK_STRING); - - std::vector<std::string> result; - std::string pattern = " \t\n"; - - if (duk_is_string(ctx, 0)) { - result = util::split(dukx_get_std_string(ctx, 0), pattern); - } else if (duk_is_array(ctx, 0)) { - duk_enum(ctx, 0, DUK_ENUM_ARRAY_INDICES_ONLY); - - while (duk_next(ctx, -1, 1)) { - // Split individual tokens as array if spaces are found. - auto tmp = util::split(duk_to_string(ctx, -1), pattern); - - result.insert(result.end(), tmp.begin(), tmp.end()); - duk_pop_2(ctx); - } - } - - return result; -} - -/* - * limit (for Irccd.Util.cut as cut) - * ------------------------------------------------------------------ - * - * Get the maxl/maxc argument. - * - * The argument value is the default and also used as the result returned. - */ -int limit(duk_context *ctx, int index, const char *name, int value) -{ - if (duk_get_top(ctx) < index || !duk_is_number(ctx, index)) { - return value; - } - - value = duk_to_int(ctx, index); - - if (value <= 0) { - duk_error(ctx, DUK_ERR_RANGE_ERROR, "argument %d (%s) must be positive", index, name); - } - - return value; -} - -/* - * lines (for Irccd.Util.cut as cut) - * ------------------------------------------------------------------ - * - * Build a list of lines. - * - * Several cases possible: - * - * - s is the current line - * - abc is the token to add - * - * s = "" (new line) - * s -> "abc" - * - * s = "hello world" (enough room) - * s -> "hello world abc" - * - * s = "hello world" (not enough room: maxc is smaller) - * s+1 = "abc" - */ -std::vector<std::string> lines(duk_context *ctx, const std::vector<std::string>& tokens, int maxc) -{ - std::vector<std::string> result{""}; - - for (const auto &s : tokens) { - if (s.length() > static_cast<std::size_t>(maxc)) { - duk_error(ctx, DUK_ERR_RANGE_ERROR, "word '%s' could not fit in maxc limit (%d)", s.c_str(), maxc); - } - - // Compute the length required (prepend a space if needed) - auto required = s.length() + (result.back().empty() ? 0 : 1); - - if (result.back().length() + required > static_cast<std::size_t>(maxc)) { - result.push_back(s); - } else { - if (!result.back().empty()) { - result.back() += ' '; - } - result.back() += s; - } - } - - return result; -} - -/* - * Function: Irccd.Util.cut(data, maxc, maxl) - * -------------------------------------------------------- - * - * Cut a piece of data into several lines. - * - * The argument data is a string or a list of strings. In any case, all strings - * are first splitted by spaces and trimmed. This ensure that useless - * whitespaces are discarded. - * - * The argument maxc controls the maximum of characters allowed per line, it can - * be a positive integer. If undefined is given, a default of 72 is used. - * - * The argument maxl controls the maximum of lines allowed. It can be a positive - * integer or undefined for an infinite list. - * - * If maxl is used as a limit and the data can not fit within the bounds, - * undefined is returned. - * - * An empty list may be returned if empty strings were found. - * - * Arguments: - * - data, a string or an array of strings, - * - maxc, max number of colums (Optional, default: 72), - * - maxl, max number of lines (Optional, default: undefined). - * Returns: - * A list of strings ready to be sent or undefined if the data is too big. - * Throws: - * - RangeError if maxl or maxc are negative numbers, - * - RangeError if one word length was bigger than maxc, - * - TypeError if data is not a string or a list of strings. - */ -duk_ret_t cut(duk_context *ctx) -{ - auto list = lines(ctx, split(ctx), limit(ctx, 1, "maxc", 72)); - auto maxl = limit(ctx, 2, "maxl", INT_MAX); - - if (list.size() > static_cast<std::size_t>(maxl)) { - return 0; - } - - // Empty list but lines() returns at least one. - if (list.size() == 1 && list[0].empty()) { - duk_push_array(ctx); - return 1; - } - - dukx_push_array(ctx, list, dukx_push_std_string); - - return 1; -} - -/* - * Function: Irccd.Util.format(text, parameters) - * -------------------------------------------------------- - * - * Format a string with templates. - * - * Arguments: - * - input, the text to update, - * - params, the parameters. - * Returns: - * The converted text. - */ -duk_ret_t format(duk_context *ctx) -{ - try { - dukx_push_std_string(ctx, util::format(dukx_get_std_string(ctx, 0), getSubstitution(ctx, 1))); - } catch (const std::exception &ex) { - dukx_throw(ctx, SyntaxError(ex.what())); - } - - return 1; -} - -/* - * Function: Irccd.Util.splituser(ident) - * -------------------------------------------------------- - * - * Return the nickname part from a full username. - * - * Arguments: - * - ident, the full identity. - * Returns: - * The nickname. - */ -duk_ret_t splituser(duk_context *ctx) -{ - auto target = duk_require_string(ctx, 0); - char nick[32] = {0}; - - irc_target_get_nick(target, nick, sizeof (nick) -1); - duk_push_string(ctx, nick); - - return 1; -} - -/* - * Function: Irccd.Util.splithost(ident) - * -------------------------------------------------------- - * - * Return the hostname part from a full username. - * - * Arguments: - * - ident, the full identity. - * Returns: - * The hostname. - */ -duk_ret_t splithost(duk_context *ctx) -{ - auto target = duk_require_string(ctx, 0); - char host[32] = {0}; - - irc_target_get_host(target, host, sizeof (host) -1); - duk_push_string(ctx, host); - - return 1; -} - -const duk_function_list_entry functions[] = { - { "cut", cut, DUK_VARARGS }, - { "format", format, DUK_VARARGS }, - { "splituser", splituser, 1 }, - { "splithost", splithost, 1 }, - { nullptr, nullptr, 0 } -}; - -} // !namespace - -UtilModule::UtilModule() noexcept - : Module("Irccd.Util") -{ -} - -void UtilModule::load(Irccd &, std::shared_ptr<JsPlugin> plugin) -{ - StackAssert sa(plugin->context()); - - duk_get_global_string(plugin->context(), "Irccd"); - duk_push_object(plugin->context()); - duk_put_function_list(plugin->context(), -1, functions); - duk_put_prop_string(plugin->context(), -2, "Util"); - duk_pop(plugin->context()); -} - -} // !irccd
--- a/libirccd-js/irccd/mod-util.hpp Fri Aug 11 13:45:42 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* - * mod-util.hpp -- Irccd.Util API - * - * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef IRCCD_MOD_UTIL_HPP -#define IRCCD_MOD_UTIL_HPP - -/** - * \file mod-util.hpp - * \brief Irccd.Util JavaScript API. - */ - -#include "module.hpp" - -namespace irccd { - -/** - * \brief Irccd.Util JavaScript API. - * \ingroup modules - */ -class UtilModule : public Module { -public: - /** - * Irccd.Util. - */ - IRCCD_EXPORT UtilModule() noexcept; - - /** - * \copydoc Module::load - */ - IRCCD_EXPORT void load(Irccd &irccd, std::shared_ptr<JsPlugin> plugin) override; -}; - -} // !irccd - -#endif // !IRCCD_MOD_UTIL_HPP
--- a/libirccd-js/irccd/module.hpp Fri Aug 11 13:45:42 2017 +0200 +++ b/libirccd-js/irccd/module.hpp Tue Sep 26 17:18:47 2017 +0200 @@ -21,11 +21,11 @@ /** * \file module.hpp - * \brief JavaScript API module. + * \brief Javascript API module. */ /** - * \defgroup modules JavaScript modules + * \defgroup Javascript modules. * \brief Modules for the JavaScript API. */ @@ -37,15 +37,15 @@ namespace irccd { -class Irccd; -class JsPlugin; +class irccd; +class js_plugin; /** * \brief JavaScript API module. */ -class Module { +class module { private: - std::string m_name; + std::string name_; public: /** @@ -53,25 +53,25 @@ * * \pre !name.empty() */ - inline Module(std::string name) noexcept - : m_name(std::move(name)) + inline module(std::string name) noexcept + : name_(std::move(name)) { - assert(!m_name.empty()); + assert(!name_.empty()); } /** * Virtual destructor defaulted. */ - virtual ~Module() = default; + virtual ~module() noexcept = default; /** * Get the module name. * * \return the name */ - inline const std::string &name() const noexcept + inline const std::string& name() const noexcept { - return m_name; + return name_; } /** @@ -80,7 +80,7 @@ * \param irccd the irccd instance * \param plugin the plugin */ - virtual void load(Irccd &irccd, std::shared_ptr<JsPlugin> plugin) + virtual void load(irccd& irccd, std::shared_ptr<js_plugin> plugin) { util::unused(irccd, plugin); }
--- a/libirccd-js/irccd/plugin-js.cpp Fri Aug 11 13:45:42 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,434 +0,0 @@ -/* - * plugin-js.cpp -- JavaScript plugins for irccd - * - * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <boost/filesystem.hpp> - -#include "sysconfig.hpp" - -#if defined(HAVE_STAT) -# include <sys/stat.h> -# include <cerrno> -# include <cstring> -#endif - -#include "fs.hpp" -#include "irccd.hpp" -#include "logger.hpp" -#include "mod-plugin.hpp" -#include "mod-server.hpp" -#include "plugin-js.hpp" -#include "service.hpp" -#include "timer.hpp" - -namespace irccd { - -const char JsPlugin::ConfigProperty[] = "\xff""\xff""irccd-plugin-config"; -const char JsPlugin::FormatProperty[] = "\xff""\xff""irccd-plugin-format"; -const char JsPlugin::PathsProperty[] = "\xff""\xff""irccd-plugin-paths"; - -std::unordered_map<std::string, std::string> JsPlugin::getTable(const char *name) const -{ - StackAssert sa(m_context); - std::unordered_map<std::string, std::string> result; - - duk_get_global_string(m_context, name); - dukx_enumerate(m_context, -1, 0, true, [&] (auto ctx) { - result.emplace(duk_to_string(ctx, -2), duk_to_string(ctx, -1)); - }); - duk_pop(m_context); - - return result; -} - -void JsPlugin::putTable(const char *name, const std::unordered_map<std::string, std::string> &vars) -{ - StackAssert sa(m_context); - - duk_get_global_string(m_context, name); - - for (const auto &pair : vars) { - dukx_push_std_string(m_context, pair.second); - duk_put_prop_string(m_context, -2, pair.first.c_str()); - } - - duk_pop(m_context); -} - -void JsPlugin::call(const std::string &name, unsigned nargs) -{ - duk_get_global_string(m_context, name.c_str()); - - if (duk_get_type(m_context, -1) == DUK_TYPE_UNDEFINED) - // Function not defined, remove the undefined value and all arguments. - duk_pop_n(m_context, nargs + 1); - else { - // Call the function and discard the result. - duk_insert(m_context, -nargs - 1); - - if (duk_pcall(m_context, nargs) != 0) - throw dukx_exception(m_context, -1, true); - - duk_pop(m_context); - } -} - -void JsPlugin::putVars() -{ - StackAssert sa(m_context); - - duk_push_pointer(m_context, this); - duk_put_global_string(m_context, "\xff""\xff""plugin"); - dukx_push_std_string(m_context, name()); - duk_put_global_string(m_context, "\xff""\xff""name"); - dukx_push_std_string(m_context, path()); - duk_put_global_string(m_context, "\xff""\xff""path"); -} - -JsPlugin::JsPlugin(std::string name, std::string path) - : Plugin(name, path) -{ - /* - * Create two special tables for configuration and formats, they are - * referenced later as - * - * - Irccd.Plugin.config - * - Irccd.Plugin.format - * - Irccd.Plugin.paths - * - * In mod-plugin.cpp. - */ - duk_push_object(m_context); - duk_put_global_string(m_context, ConfigProperty); - duk_push_object(m_context); - duk_put_global_string(m_context, FormatProperty); - duk_push_object(m_context); - duk_put_global_string(m_context, PathsProperty); - - // Used by many Javascript APIs. - duk_push_object(m_context); - duk_put_global_string(m_context, "Irccd"); -} - -void JsPlugin::onChannelMode(Irccd &, const ChannelModeEvent &event) -{ - StackAssert sa(m_context); - - dukx_push_server(m_context, std::move(event.server)); - dukx_push_std_string(m_context, event.origin); - dukx_push_std_string(m_context, event.channel); - dukx_push_std_string(m_context, event.mode); - dukx_push_std_string(m_context, event.argument); - call("onChannelMode", 5); -} - -void JsPlugin::onChannelNotice(Irccd &, const ChannelNoticeEvent &event) -{ - StackAssert sa(m_context); - - dukx_push_server(m_context, std::move(event.server)); - dukx_push_std_string(m_context, event.origin); - dukx_push_std_string(m_context, event.channel); - dukx_push_std_string(m_context, event.message); - call("onChannelNotice", 4); -} - -void JsPlugin::onCommand(Irccd &, const MessageEvent &event) -{ - StackAssert sa(m_context); - - dukx_push_server(m_context, std::move(event.server)); - dukx_push_std_string(m_context, event.origin); - dukx_push_std_string(m_context, event.channel); - dukx_push_std_string(m_context, event.message); - call("onCommand", 4); -} - -void JsPlugin::onConnect(Irccd &, const ConnectEvent &event) -{ - StackAssert sa(m_context); - - dukx_push_server(m_context, std::move(event.server)); - call("onConnect", 1); -} - -void JsPlugin::onInvite(Irccd &, const InviteEvent &event) -{ - StackAssert sa(m_context); - - dukx_push_server(m_context, std::move(event.server)); - dukx_push_std_string(m_context, event.origin); - dukx_push_std_string(m_context, event.channel); - call("onInvite", 3); -} - -void JsPlugin::onJoin(Irccd &, const JoinEvent &event) -{ - StackAssert sa(m_context); - - dukx_push_server(m_context, std::move(event.server)); - dukx_push_std_string(m_context, event.origin); - dukx_push_std_string(m_context, event.channel); - call("onJoin", 3); -} - -void JsPlugin::onKick(Irccd &, const KickEvent &event) -{ - StackAssert sa(m_context); - - dukx_push_server(m_context, std::move(event.server)); - dukx_push_std_string(m_context, event.origin); - dukx_push_std_string(m_context, event.channel); - dukx_push_std_string(m_context, event.target); - dukx_push_std_string(m_context, event.reason); - call("onKick", 5); -} - -void JsPlugin::onLoad(Irccd &irccd) -{ - StackAssert sa(m_context); - - /* - * Duktape currently emit useless warnings when a file do - * not exists so we do a homemade access. - */ -#if defined(HAVE_STAT) - struct stat st; - - if (::stat(path().c_str(), &st) < 0) - throw std::runtime_error(std::strerror(errno)); -#endif - - // Try to load the file (does not call onLoad yet). - dukx_peval_file(m_context, path()); - duk_pop(m_context); - - /* - * We put configuration and formats after loading the file and before - * calling onLoad to allow the plugin adding configuration to - * Irccd.Plugin.(config|format) before the user. - */ - putVars(); - setConfig(irccd.plugins().config(name())); - setFormats(irccd.plugins().formats(name())); - setPaths(irccd.plugins().paths(name())); - - // Read metadata . - duk_get_global_string(m_context, "info"); - - if (duk_get_type(m_context, -1) == DUK_TYPE_OBJECT) { - // 'author' - duk_get_prop_string(m_context, -1, "author"); - setAuthor(duk_is_string(m_context, -1) ? duk_get_string(m_context, -1) : author()); - duk_pop(m_context); - - // 'license' - duk_get_prop_string(m_context, -1, "license"); - setLicense(duk_is_string(m_context, -1) ? duk_get_string(m_context, -1) : license()); - duk_pop(m_context); - - // 'summary' - duk_get_prop_string(m_context, -1, "summary"); - setSummary(duk_is_string(m_context, -1) ? duk_get_string(m_context, -1) : summary()); - duk_pop(m_context); - - // 'version' - duk_get_prop_string(m_context, -1, "version"); - setVersion(duk_is_string(m_context, -1) ? duk_get_string(m_context, -1) : version()); - duk_pop(m_context); - } - - duk_pop(m_context); - call("onLoad", 0); -} - -void JsPlugin::onMessage(Irccd &, const MessageEvent &event) -{ - StackAssert sa(m_context); - - dukx_push_server(m_context, std::move(event.server)); - dukx_push_std_string(m_context, event.origin); - dukx_push_std_string(m_context, event.channel); - dukx_push_std_string(m_context, event.message); - call("onMessage", 4); -} - -void JsPlugin::onMe(Irccd &, const MeEvent &event) -{ - StackAssert sa(m_context); - - dukx_push_server(m_context, std::move(event.server)); - dukx_push_std_string(m_context, event.origin); - dukx_push_std_string(m_context, event.channel); - dukx_push_std_string(m_context, event.message); - call("onMe", 4); -} - -void JsPlugin::onMode(Irccd &, const ModeEvent &event) -{ - StackAssert sa(m_context); - - dukx_push_server(m_context, std::move(event.server)); - dukx_push_std_string(m_context, event.origin); - dukx_push_std_string(m_context, event.mode); - call("onMode", 3); -} - -void JsPlugin::onNames(Irccd &, const NamesEvent &event) -{ - StackAssert sa(m_context); - - dukx_push_server(m_context, std::move(event.server)); - dukx_push_std_string(m_context, event.channel); - dukx_push_array(m_context, event.names, dukx_push_std_string); - call("onNames", 3); -} - -void JsPlugin::onNick(Irccd &, const NickEvent &event) -{ - StackAssert sa(m_context); - - dukx_push_server(m_context, std::move(event.server)); - dukx_push_std_string(m_context, event.origin); - dukx_push_std_string(m_context, event.nickname); - call("onNick", 3); -} - -void JsPlugin::onNotice(Irccd &, const NoticeEvent &event) -{ - StackAssert sa(m_context); - - dukx_push_server(m_context, std::move(event.server)); - dukx_push_std_string(m_context, event.origin); - dukx_push_std_string(m_context, event.message); - call("onNotice", 3); -} - -void JsPlugin::onPart(Irccd &, const PartEvent &event) -{ - StackAssert sa(m_context); - - dukx_push_server(m_context, std::move(event.server)); - dukx_push_std_string(m_context, event.origin); - dukx_push_std_string(m_context, event.channel); - dukx_push_std_string(m_context, event.reason); - call("onPart", 4); -} - -void JsPlugin::onQuery(Irccd &, const QueryEvent &event) -{ - StackAssert sa(m_context); - - dukx_push_server(m_context, std::move(event.server)); - dukx_push_std_string(m_context, event.origin); - dukx_push_std_string(m_context, event.message); - call("onQuery", 3); -} - -void JsPlugin::onQueryCommand(Irccd &, const QueryEvent &event) -{ - StackAssert sa(m_context); - - dukx_push_server(m_context, std::move(event.server)); - dukx_push_std_string(m_context, event.origin); - dukx_push_std_string(m_context, event.message); - call("onQueryCommand", 3); -} - -void JsPlugin::onReload(Irccd &) -{ - StackAssert sa(m_context); - - call("onReload"); -} - -void JsPlugin::onTopic(Irccd &, const TopicEvent &event) -{ - StackAssert sa(m_context); - - dukx_push_server(m_context, std::move(event.server)); - dukx_push_std_string(m_context, event.origin); - dukx_push_std_string(m_context, event.channel); - dukx_push_std_string(m_context, event.topic); - call("onTopic", 4); -} - -void JsPlugin::onUnload(Irccd &) -{ - StackAssert sa(m_context); - - call("onUnload"); -} - -void JsPlugin::onWhois(Irccd &, const WhoisEvent &event) -{ - StackAssert sa(m_context); - - dukx_push_server(m_context, std::move(event.server)); - duk_push_object(m_context); - dukx_push_std_string(m_context, event.whois.nick); - duk_put_prop_string(m_context, -2, "nickname"); - dukx_push_std_string(m_context, event.whois.user); - duk_put_prop_string(m_context, -2, "username"); - dukx_push_std_string(m_context, event.whois.realname); - duk_put_prop_string(m_context, -2, "realname"); - dukx_push_std_string(m_context, event.whois.host); - duk_put_prop_string(m_context, -2, "host"); - dukx_push_array(m_context, event.whois.channels, dukx_push_std_string); - duk_put_prop_string(m_context, -2, "channels"); - call("onWhois", 2); -} - -JsPluginLoader::JsPluginLoader(Irccd &irccd) noexcept - : PluginLoader({}, { ".js" }) - , m_irccd(irccd) -{ -} - -JsPluginLoader::~JsPluginLoader() noexcept = default; - -void JsPluginLoader::addModule(std::unique_ptr<Module> module) -{ - assert(module); - - m_modules.push_back(std::move(module)); -} - -std::shared_ptr<Plugin> JsPluginLoader::open(const std::string &id, - const std::string &path) noexcept -{ - if (path.rfind(".js") == std::string::npos) - return nullptr; - - try { - auto plugin = std::make_shared<JsPlugin>(id, path); - - for (const auto &mod : m_modules) { - log::debug() << "plugin " << plugin->name() << ": "; - log::debug() << "loading " << mod->name() << " Javascript API" << std::endl; - mod->load(m_irccd, plugin); - } - - return plugin; - } catch (const std::exception &ex) { - log::warning() << "plugin " << id << ": " << ex.what() << std::endl; - } - - return nullptr; -} - -} // !irccd
--- a/libirccd-js/irccd/plugin-js.hpp Fri Aug 11 13:45:42 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,264 +0,0 @@ -/* - * plugin-js.hpp -- JavaScript plugins for irccd - * - * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef IRCCD_PLUGIN_JS_HPP -#define IRCCD_PLUGIN_JS_HPP - -/** - * \file plugin-js.hpp - * \brief JavaScript plugins for irccd. - */ - -#include <vector> - -#include "duktape.hpp" -#include "plugin.hpp" - -namespace irccd { - -class Module; - -/** - * \brief JavaScript plugins for irccd. - * \ingroup plugins - */ -class JsPlugin : public Plugin { -public: - /** - * Global property where to read/write plugin configuration (object). - */ - static const char ConfigProperty[]; - - /** - * Global property where to read/write plugin formats (object). - */ - static const char FormatProperty[]; - - /** - * Global property where paths are defined (object). - */ - static const char PathsProperty[]; - -private: - // JavaScript context - UniqueContext m_context; - - // Private helpers. - std::unordered_map<std::string, std::string> getTable(const char *name) const; - void putTable(const char *name, const std::unordered_map<std::string, std::string> &vars); - void call(const std::string &name, unsigned nargs = 0); - void putVars(); - -public: - /** - * Constructor. - * - * \param name the plugin name - * \param path the path to the plugin - */ - IRCCD_EXPORT JsPlugin(std::string name, std::string path); - - /** - * Access the Duktape context. - * - * \return the context - */ - inline UniqueContext &context() noexcept - { - return m_context; - } - - /** - * \copydoc Plugin::config - */ - PluginConfig config() override - { - return getTable(ConfigProperty); - } - - /** - * \copydoc Plugin::setConfig - */ - void setConfig(PluginConfig config) override - { - putTable(ConfigProperty, config); - } - - /** - * \copydoc Plugin::formats - */ - PluginFormats formats() override - { - return getTable(FormatProperty); - } - - /** - * \copydoc Plugin::setFormats - */ - void setFormats(PluginFormats formats) override - { - putTable(FormatProperty, formats); - } - - /** - * \copydoc Plugin::paths - */ - PluginPaths paths() override - { - return getTable(PathsProperty); - } - - /** - * \copydoc Plugin::set_paths - */ - void setPaths(PluginPaths paths) override - { - putTable(PathsProperty, std::move(paths)); - } - - /** - * \copydoc Plugin::onCommand - */ - IRCCD_EXPORT void onCommand(Irccd &irccd, const MessageEvent &event) override; - - /** - * \copydoc Plugin::onConnect - */ - IRCCD_EXPORT void onConnect(Irccd &irccd, const ConnectEvent &event) override; - - /** - * \copydoc Plugin::onChannelMode - */ - IRCCD_EXPORT void onChannelMode(Irccd &irccd, const ChannelModeEvent &event) override; - - /** - * \copydoc Plugin::onChannelNotice - */ - IRCCD_EXPORT void onChannelNotice(Irccd &irccd, const ChannelNoticeEvent &event) override; - - /** - * \copydoc Plugin::onInvite - */ - IRCCD_EXPORT void onInvite(Irccd &irccd, const InviteEvent &event) override; - - /** - * \copydoc Plugin::onJoin - */ - IRCCD_EXPORT void onJoin(Irccd &irccd, const JoinEvent &event) override; - - /** - * \copydoc Plugin::onKick - */ - IRCCD_EXPORT void onKick(Irccd &irccd, const KickEvent &event) override; - - /** - * \copydoc Plugin::onLoad - */ - IRCCD_EXPORT void onLoad(Irccd &irccd) override; - - /** - * \copydoc Plugin::onMessage - */ - IRCCD_EXPORT void onMessage(Irccd &irccd, const MessageEvent &event) override; - - /** - * \copydoc Plugin::onMe - */ - IRCCD_EXPORT void onMe(Irccd &irccd, const MeEvent &event) override; - - /** - * \copydoc Plugin::onMode - */ - IRCCD_EXPORT void onMode(Irccd &irccd, const ModeEvent &event) override; - - /** - * \copydoc Plugin::onNames - */ - IRCCD_EXPORT void onNames(Irccd &irccd, const NamesEvent &event) override; - - /** - * \copydoc Plugin::onNick - */ - IRCCD_EXPORT void onNick(Irccd &irccd, const NickEvent &event) override; - - /** - * \copydoc Plugin::onNotice - */ - IRCCD_EXPORT void onNotice(Irccd &irccd, const NoticeEvent &event) override; - - /** - * \copydoc Plugin::onPart - */ - IRCCD_EXPORT void onPart(Irccd &irccd, const PartEvent &event) override; - - /** - * \copydoc Plugin::onQuery - */ - IRCCD_EXPORT void onQuery(Irccd &irccd, const QueryEvent &event) override; - - /** - * \copydoc Plugin::onQueryCommand - */ - IRCCD_EXPORT void onQueryCommand(Irccd &irccd, const QueryEvent &event) override; - - /** - * \copydoc Plugin::onReload - */ - IRCCD_EXPORT void onReload(Irccd &irccd) override; - - /** - * \copydoc Plugin::onTopic - */ - IRCCD_EXPORT void onTopic(Irccd &irccd, const TopicEvent &event) override; - - /** - * \copydoc Plugin::onUnload - */ - IRCCD_EXPORT void onUnload(Irccd &irccd) override; - - /** - * \copydoc Plugin::onWhois - */ - IRCCD_EXPORT void onWhois(Irccd &irccd, const WhoisEvent &event) override; -}; - -/** - * \brief Implementation for searching Javascript plugins. - */ -class JsPluginLoader : public PluginLoader { -private: - Irccd &m_irccd; - std::vector<std::unique_ptr<Module>> m_modules; - -public: - JsPluginLoader(Irccd &irccd) noexcept; - - ~JsPluginLoader() noexcept; - - void addModule(std::unique_ptr<Module> module); - - /** - * \copydoc PluginLoader::find - */ - std::shared_ptr<Plugin> open(const std::string &id, - const std::string &path) noexcept override; -}; - -} // !irccd - -#endif // !IRCCD_PLUGIN_JS_HPP
--- a/libirccd-js/irccd/timer.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/libirccd-js/irccd/timer.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -25,80 +25,80 @@ namespace irccd { -void Timer::run() +void timer::run() { - while (m_state != Stopped) { - std::unique_lock<std::mutex> lock(m_mutex); + while (state_ != state::stopped) { + std::unique_lock<std::mutex> lock(mutex_); // Wait in case the timer is paused. - m_condition.wait(lock, [&] () { - return m_state == Running; + condition_.wait(lock, [&] () { + return state_ == state::running; }); - if (m_state != Running) + if (state_ != state::running) continue; // Wait the timer delay or the interrupt. - m_condition.wait_for(lock, std::chrono::milliseconds(m_delay), [&] () { - return m_state != Running; + condition_.wait_for(lock, std::chrono::milliseconds(delay_), [&] () { + return state_ != state::running; }); - if (m_state == Running) { + if (state_ == state::running) { // Signal process. - onSignal(); + on_signal(); - if (m_type == TimerType::Single) - m_state = Stopped; + if (type_ == type::single) + state_ = state::stopped; } } - onEnd(); + on_end(); } -Timer::Timer(TimerType type, unsigned delay) noexcept - : m_type(type) - , m_delay(delay) - , m_thread(std::bind(&Timer::run, this)) +timer::timer(type type, unsigned delay) noexcept + : type_(type) + , delay_(delay) + , thread_(std::bind(&timer::run, this)) { } -Timer::~Timer() +timer::~timer() { - assert(m_state != Running); + assert(state_ != state::running); try { { - std::lock_guard<std::mutex> lk(m_mutex); + std::lock_guard<std::mutex> lk(mutex_); - m_state = Stopped; - m_condition.notify_one(); + state_ = state::stopped; + condition_.notify_one(); } - m_thread.join(); + thread_.join(); } catch (...) { } } -void Timer::start() +void timer::start() { - assert(m_state != Running); + assert(state_ != state::running); { - std::lock_guard<std::mutex> lk(m_mutex); - m_state = Running; + std::lock_guard<std::mutex> lk(mutex_); + state_ = state::running; } - m_condition.notify_one(); + condition_.notify_one(); } -void Timer::stop() +void timer::stop() { { - std::lock_guard<std::mutex> lk(m_mutex); - m_state = Paused; + std::lock_guard<std::mutex> lk(mutex_); + state_ = state::paused; } - m_condition.notify_one(); + condition_.notify_one(); } } // !irccd
--- a/libirccd-js/irccd/timer.hpp Fri Aug 11 13:45:42 2017 +0200 +++ b/libirccd-js/irccd/timer.hpp Tue Sep 26 17:18:47 2017 +0200 @@ -36,15 +36,6 @@ namespace irccd { /** - * \enum TimerType - * \brief Type of timer - */ -enum class TimerType { - Single, //!< The timer ends after execution - Repeat //!< The timer loops -}; - -/** * \brief Timer class * * A timer is a thread object that emits a signal periodically or just one time. It is perfectly pausable and resumable @@ -56,15 +47,23 @@ * We use a condition variable to wait for the specified delay unless the timer * must be stopped. */ -class Timer { +class timer { public: /** + * \brief Type of timer + */ + enum class type { + single, //!< The timer ends after execution + repeat //!< The timer loops + }; + + /** * Signal: onSignal * ---------------------------------------------------------- * * Called when the timeout expires. */ - Signal<> onSignal; + Signal<> on_signal; /** * Signal: onEnd @@ -72,23 +71,23 @@ * * Called when the timeout ends. */ - Signal<> onEnd; + Signal<> on_end; private: - enum { - Paused, - Running, - Stopped + enum class state { + paused, + running, + stopped }; - TimerType m_type; - unsigned m_delay; + type type_; + unsigned delay_; // Thread management. - std::atomic<int> m_state{Paused}; - std::mutex m_mutex; - std::condition_variable m_condition; - std::thread m_thread; + std::atomic<state> state_{state::paused}; + std::mutex mutex_; + std::condition_variable condition_; + std::thread thread_; void run(); @@ -102,14 +101,14 @@ * \param delay the delay in milliseconds * \post isRunning() returns false */ - IRCCD_EXPORT Timer(TimerType type, unsigned delay) noexcept; + timer(type type, unsigned delay) noexcept; /** * Destructor, closes the thread. * * \pre stop() must have been called. */ - IRCCD_EXPORT virtual ~Timer(); + virtual ~timer(); /** * Start the thread. @@ -119,23 +118,23 @@ * \pre onEnd() must have been called * \note Thread-safe */ - IRCCD_EXPORT void start(); + void start(); /** * Stop the timer, may be used by the user to stop it. * * \note Thread-safe */ - IRCCD_EXPORT void stop(); + void stop(); /** * Get the type of timer. * * \return the type. */ - inline TimerType type() const noexcept + inline type get_type() const noexcept { - return m_type; + return type_; } /** @@ -144,9 +143,9 @@ * \return true if still alive * \note Thread-safe */ - inline bool isRunning() const noexcept + inline bool is_running() const noexcept { - return m_state == Running; + return state_ == state::running; } };
--- a/libirccd-test/irccd/command-tester.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/libirccd-test/irccd/command-tester.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -24,15 +24,15 @@ namespace irccd { -CommandTester::CommandTester(std::unique_ptr<Command> cmd, - std::unique_ptr<Server> server) +CommandTester::CommandTester(std::unique_ptr<command> cmd, + std::unique_ptr<server> server) : m_irccdctl(std::make_unique<Client>()) { // Be silent. - log::setLogger(std::make_unique<log::SilentLogger>()); - log::setVerbose(false); + log::set_logger(std::make_unique<log::silent_logger>()); + log::set_verbose(false); - auto tpt = std::make_unique<TransportServerIp>("*", 0); + auto tpt = std::make_unique<transport_server_ip>("*", 0); auto port = tpt->port(); m_irccd.transports().add(std::move(tpt));
--- a/libirccd-test/irccd/command-tester.hpp Fri Aug 11 13:45:42 2017 +0200 +++ b/libirccd-test/irccd/command-tester.hpp Tue Sep 26 17:18:47 2017 +0200 @@ -28,18 +28,17 @@ namespace irccd { -class Command; -class Server; +class command; +class server; class CommandTester : public testing::Test { protected: - Irccd m_irccd; + irccd m_irccd; Irccdctl m_irccdctl; public: - CommandTester(std::unique_ptr<Command> cmd = nullptr, - std::unique_ptr<Server> server = nullptr); - + CommandTester(std::unique_ptr<command> cmd = nullptr, + std::unique_ptr<server> server = nullptr); template <typename Predicate> void poll(Predicate &&predicate)
--- a/libirccd-test/irccd/plugin-tester.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/libirccd-test/irccd/plugin-tester.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -16,18 +16,18 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "mod-directory.hpp" -#include "mod-elapsed-timer.hpp" -#include "mod-file.hpp" -#include "mod-irccd.hpp" -#include "mod-logger.hpp" -#include "mod-plugin.hpp" -#include "mod-server.hpp" -#include "mod-system.hpp" -#include "mod-timer.hpp" -#include "mod-unicode.hpp" -#include "mod-util.hpp" -#include "plugin-js.hpp" +#include "js_directory_module.hpp" +#include "js_elapsed_timer_module.hpp" +#include "js_file_module.hpp" +#include "js_irccd_module.hpp" +#include "js_logger_module.hpp" +#include "js_plugin_module.hpp" +#include "js_server_module.hpp" +#include "js_system_module.hpp" +#include "js_timer_module.hpp" +#include "js_unicode_module.hpp" +#include "js_util_module.hpp" +#include "js_plugin.hpp" #include "plugin-tester.hpp" #include "service.hpp" @@ -35,21 +35,21 @@ PluginTester::PluginTester() { - auto loader = std::make_unique<JsPluginLoader>(m_irccd); + auto loader = std::make_unique<js_plugin_loader>(m_irccd); - loader->addModule(std::make_unique<IrccdModule>()); - loader->addModule(std::make_unique<DirectoryModule>()); - loader->addModule(std::make_unique<ElapsedTimerModule>()); - loader->addModule(std::make_unique<FileModule>()); - loader->addModule(std::make_unique<LoggerModule>()); - loader->addModule(std::make_unique<PluginModule>()); - loader->addModule(std::make_unique<ServerModule>()); - loader->addModule(std::make_unique<SystemModule>()); - loader->addModule(std::make_unique<TimerModule>()); - loader->addModule(std::make_unique<UnicodeModule>()); - loader->addModule(std::make_unique<UtilModule>()); + loader->add_module(std::make_unique<js_irccd_module>()); + loader->add_module(std::make_unique<js_directory_module>()); + loader->add_module(std::make_unique<js_elapsed_timer_module>()); + loader->add_module(std::make_unique<js_file_module>()); + loader->add_module(std::make_unique<js_logger_module>()); + loader->add_module(std::make_unique<js_plugin_module>()); + loader->add_module(std::make_unique<js_server_module>()); + loader->add_module(std::make_unique<js_system_module>()); + loader->add_module(std::make_unique<js_timer_module>()); + loader->add_module(std::make_unique<js_unicode_module>()); + loader->add_module(std::make_unique<js_util_module>()); - m_irccd.plugins().addLoader(std::move(loader)); + m_irccd.plugins().add_loader(std::move(loader)); } } // !irccd
--- a/libirccd-test/irccd/plugin-tester.hpp Fri Aug 11 13:45:42 2017 +0200 +++ b/libirccd-test/irccd/plugin-tester.hpp Tue Sep 26 17:18:47 2017 +0200 @@ -27,7 +27,7 @@ class PluginTester : public testing::Test { protected: - Irccd m_irccd; + irccd m_irccd; public: PluginTester();
--- a/libirccd-test/irccd/plugin_test.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/libirccd-test/irccd/plugin_test.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -16,18 +16,18 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include <irccd/mod-directory.hpp> -#include <irccd/mod-elapsed-timer.hpp> -#include <irccd/mod-file.hpp> -#include <irccd/mod-irccd.hpp> -#include <irccd/mod-logger.hpp> -#include <irccd/mod-plugin.hpp> -#include <irccd/mod-server.hpp> -#include <irccd/mod-system.hpp> -#include <irccd/mod-timer.hpp> -#include <irccd/mod-unicode.hpp> -#include <irccd/mod-util.hpp> -#include <irccd/plugin-js.hpp> +#include <irccd/js_directory_module.hpp> +#include <irccd/js_elapsed_timer_module.hpp> +#include <irccd/js_file_module.hpp> +#include <irccd/js_irccd_module.hpp> +#include <irccd/js_logger_module.hpp> +#include <irccd/js_plugin_module.hpp> +#include <irccd/js_server_module.hpp> +#include <irccd/js_system_module.hpp> +#include <irccd/js_timer_module.hpp> +#include <irccd/js_unicode_module.hpp> +#include <irccd/js_util_module.hpp> +#include <irccd/js_plugin.hpp> #include <irccd/service.hpp> #include "plugin_test.hpp" @@ -36,19 +36,19 @@ plugin_test::plugin_test(std::string name, std::string path) { - JsPluginLoader loader(irccd_); + js_plugin_loader loader(irccd_); - loader.addModule(std::make_unique<IrccdModule>()); - loader.addModule(std::make_unique<DirectoryModule>()); - loader.addModule(std::make_unique<ElapsedTimerModule>()); - loader.addModule(std::make_unique<FileModule>()); - loader.addModule(std::make_unique<LoggerModule>()); - loader.addModule(std::make_unique<PluginModule>()); - loader.addModule(std::make_unique<ServerModule>()); - loader.addModule(std::make_unique<SystemModule>()); - loader.addModule(std::make_unique<TimerModule>()); - loader.addModule(std::make_unique<UnicodeModule>()); - loader.addModule(std::make_unique<UtilModule>()); + loader.add_module(std::make_unique<js_irccd_module>()); + loader.add_module(std::make_unique<js_directory_module>()); + loader.add_module(std::make_unique<js_elapsed_timer_module>()); + loader.add_module(std::make_unique<js_file_module>()); + loader.add_module(std::make_unique<js_logger_module>()); + loader.add_module(std::make_unique<js_plugin_module>()); + loader.add_module(std::make_unique<js_server_module>()); + loader.add_module(std::make_unique<js_system_module>()); + loader.add_module(std::make_unique<js_timer_module>()); + loader.add_module(std::make_unique<js_unicode_module>()); + loader.add_module(std::make_unique<js_util_module>()); plugin_ = loader.open(name, path); irccd_.plugins().add(plugin_);
--- a/libirccd-test/irccd/server-tester.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/libirccd-test/irccd/server-tester.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -21,7 +21,7 @@ namespace irccd { ServerTester::ServerTester(std::string name) - : Server(std::move(name)) + : server(std::move(name)) { }
--- a/libirccd-test/irccd/server-tester.hpp Fri Aug 11 13:45:42 2017 +0200 +++ b/libirccd-test/irccd/server-tester.hpp Tue Sep 26 17:18:47 2017 +0200 @@ -32,7 +32,7 @@ /** * \brief Useless server for testing purpose. */ -class IRCCD_EXPORT ServerTester : public Server { +class IRCCD_EXPORT ServerTester : public server { public: /** * Create a server with named 'test' by default.
--- a/libirccd/CMakeLists.txt Fri Aug 11 13:45:42 2017 +0200 +++ b/libirccd/CMakeLists.txt Tue Sep 26 17:18:47 2017 +0200 @@ -22,9 +22,7 @@ HEADERS ${libirccd_SOURCE_DIR}/irccd/command.hpp ${libirccd_SOURCE_DIR}/irccd/config.hpp - ${libirccd_SOURCE_DIR}/irccd/dynlib.hpp ${libirccd_SOURCE_DIR}/irccd/irccd.hpp - ${libirccd_SOURCE_DIR}/irccd/plugin-dynlib.hpp ${libirccd_SOURCE_DIR}/irccd/plugin.hpp ${libirccd_SOURCE_DIR}/irccd/rule.hpp ${libirccd_SOURCE_DIR}/irccd/server.hpp @@ -38,7 +36,6 @@ ${libirccd_SOURCE_DIR}/irccd/config.cpp ${libirccd_SOURCE_DIR}/irccd/irccd.cpp ${libirccd_SOURCE_DIR}/irccd/plugin.cpp - ${libirccd_SOURCE_DIR}/irccd/plugin-dynlib.cpp ${libirccd_SOURCE_DIR}/irccd/rule.cpp ${libirccd_SOURCE_DIR}/irccd/server.cpp ${libirccd_SOURCE_DIR}/irccd/service.cpp
--- a/libirccd/irccd/command.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/libirccd/irccd/command.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -26,11 +26,9 @@ namespace irccd { -namespace command { - namespace { -void execSet(Irccd &, TransportClient &client, Plugin &plugin, const nlohmann::json &args) +void exec_set(transport_client& client, plugin& plugin, const nlohmann::json& args) { assert(args.count("value") > 0); @@ -45,12 +43,12 @@ auto config = plugin.config(); config[*var] = *value; - plugin.setConfig(config); + plugin.set_config(config); client.success("plugin-config"); } } -void execGet(Irccd &, TransportClient &client, Plugin &plugin, const nlohmann::json &args) +void exec_get(transport_client& client, plugin& plugin, const nlohmann::json& args) { auto variables = nlohmann::json::object(); auto var = args.find("variable"); @@ -58,7 +56,7 @@ if (var != args.end() && var->is_string()) variables[var->get<std::string>()] = plugin.config()[*var]; else - for (const auto &pair : plugin.config()) + for (const auto& pair : plugin.config()) variables[pair.first] = pair.second; /* @@ -72,19 +70,19 @@ }); } -nlohmann::json toJson(const Rule &rule) +nlohmann::json to_json(const rule& rule) { - auto join = [] (const auto &set) { + auto join = [] (const auto& set) { auto array = nlohmann::json::array(); - for (const auto &entry : set) + for (const auto& entry : set) array.push_back(entry); return array; }; auto str = [] (auto action) { switch (action) { - case RuleAction::Accept: + case rule::action_type::accept: return "accept"; default: return "drop"; @@ -100,18 +98,18 @@ }; } -Rule fromJson(const nlohmann::json &json) +rule from_json(const nlohmann::json& json) { - auto toset = [] (auto object, auto name) -> RuleSet { - RuleSet result; + auto toset = [] (auto object, auto name) { + rule::set result; - for (const auto &s : object[name]) + for (const auto& s : object[name]) if (s.is_string()) result.insert(s.template get<std::string>()); return result; }; - auto toaction = [] (auto object, auto name) -> RuleAction { + auto toaction = [] (auto object, auto name) { auto v = object[name]; if (!v.is_string()) @@ -119,9 +117,9 @@ auto s = v.template get<std::string>(); if (s == "accept") - return RuleAction::Accept; + return rule::action_type::accept; if (s == "drop") - return RuleAction::Drop; + return rule::action_type::drop; throw std::runtime_error("unknown action '"s + s + "' given"); }; @@ -138,30 +136,29 @@ } // !namespace -PluginConfigCommand::PluginConfigCommand() - : Command("plugin-config") +plugin_config_command::plugin_config_command() + : command("plugin-config") { } -void PluginConfigCommand::exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) +void plugin_config_command::exec(irccd& irccd, transport_client& client, const nlohmann::json& args) { - auto plugin = irccd.plugins().require(util::json::requireIdentifier(args, "plugin")); + auto plugin = irccd.plugins().require(util::json::require_identifier(args, "plugin")); if (args.count("value") > 0) - execSet(irccd, client, *plugin, args); + exec_set(client, *plugin, args); else - execGet(irccd, client, *plugin, args); + exec_get(client, *plugin, args); } - -PluginInfoCommand::PluginInfoCommand() - : Command("plugin-info") +plugin_info_command::plugin_info_command() + : command("plugin-info") { } -void PluginInfoCommand::exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) +void plugin_info_command::exec(irccd& irccd, transport_client& client, const nlohmann::json& args) { - auto plugin = irccd.plugins().require(util::json::requireIdentifier(args, "plugin")); + auto plugin = irccd.plugins().require(util::json::require_identifier(args, "plugin")); client.success("plugin-info", { { "author", plugin->author() }, @@ -171,16 +168,16 @@ }); } -PluginListCommand::PluginListCommand() - : Command("plugin-list") +plugin_list_command::plugin_list_command() + : command("plugin-list") { } -void PluginListCommand::exec(Irccd &irccd, TransportClient &client, const nlohmann::json &) +void plugin_list_command::exec(irccd& irccd, transport_client& client, const nlohmann::json&) { auto list = nlohmann::json::array(); - for (const auto &plugin : irccd.plugins().list()) + for (const auto& plugin : irccd.plugins().list()) list += plugin->name(); client.success("plugin-list", { @@ -188,75 +185,75 @@ }); } -PluginLoadCommand::PluginLoadCommand() - : Command("plugin-load") +plugin_load_command::plugin_load_command() + : command("plugin-load") { } -void PluginLoadCommand::exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) +void plugin_load_command::exec(irccd& irccd, transport_client& client, const nlohmann::json& args) { - irccd.plugins().load(util::json::requireIdentifier(args, "plugin")); + irccd.plugins().load(util::json::require_identifier(args, "plugin")); client.success("plugin-load"); } -PluginReloadCommand::PluginReloadCommand() - : Command("plugin-reload") +plugin_reload_command::plugin_reload_command() + : command("plugin-reload") { } -void PluginReloadCommand::exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) +void plugin_reload_command::exec(irccd& irccd, transport_client& client, const nlohmann::json& args) { - irccd.plugins().require(util::json::requireIdentifier(args, "plugin"))->onReload(irccd); + irccd.plugins().require(util::json::require_identifier(args, "plugin"))->on_reload(irccd); client.success("plugin-reload"); } -PluginUnloadCommand::PluginUnloadCommand() - : Command("plugin-unload") +plugin_unload_command::plugin_unload_command() + : command("plugin-unload") { } -void PluginUnloadCommand::exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) +void plugin_unload_command::exec(irccd& irccd, transport_client& client, const nlohmann::json& args) { - irccd.plugins().unload(util::json::requireIdentifier(args, "plugin")); + irccd.plugins().unload(util::json::require_identifier(args, "plugin")); client.success("plugin-unload"); } -ServerChannelModeCommand::ServerChannelModeCommand() - : Command("server-cmode") +server_channel_mode_command::server_channel_mode_command() + : command("server-cmode") { } -void ServerChannelModeCommand::exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) +void server_channel_mode_command::exec(irccd& irccd, transport_client& client, const nlohmann::json& args) { - irccd.servers().require(util::json::requireIdentifier(args, "server"))->cmode( - util::json::requireString(args, "channel"), - util::json::requireString(args, "mode") + irccd.servers().require(util::json::require_identifier(args, "server"))->cmode( + util::json::require_string(args, "channel"), + util::json::require_string(args, "mode") ); client.success("server-cmode"); } -ServerChannelNoticeCommand::ServerChannelNoticeCommand() - : Command("server-cnotice") +server_channel_notice_command::server_channel_notice_command() + : command("server-cnotice") { } -void ServerChannelNoticeCommand::exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) +void server_channel_notice_command::exec(irccd& irccd, transport_client& client, const nlohmann::json& args) { - irccd.servers().require(util::json::requireString(args, "server"))->cnotice( - util::json::requireString(args, "channel"), - util::json::requireString(args, "message") + irccd.servers().require(util::json::require_string(args, "server"))->cnotice( + util::json::require_string(args, "channel"), + util::json::require_string(args, "message") ); client.success("server-cnotice"); } -ServerConnectCommand::ServerConnectCommand() - : Command("server-connect") +server_connect_command::server_connect_command() + : command("server-connect") { } -void ServerConnectCommand::exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) +void server_connect_command::exec(irccd& irccd, transport_client& client, const nlohmann::json& args) { - auto server = Server::fromJson(args); + auto server = server::from_json(args); if (irccd.servers().has(server->name())) client.error("server-connect", "server already exists"); @@ -266,12 +263,12 @@ } } -ServerDisconnectCommand::ServerDisconnectCommand() - : Command("server-disconnect") +server_disconnect_command::server_disconnect_command() + : command("server-disconnect") { } -void ServerDisconnectCommand::exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) +void server_disconnect_command::exec(irccd& irccd, transport_client& client, const nlohmann::json& args) { auto it = args.find("server"); @@ -283,15 +280,15 @@ client.success("server-disconnect"); } -ServerInfoCommand::ServerInfoCommand() - : Command("server-info") +server_info_command::server_info_command() + : command("server-info") { } -void ServerInfoCommand::exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) +void server_info_command::exec(irccd& irccd, transport_client& client, const nlohmann::json& args) { auto response = nlohmann::json::object(); - auto server = irccd.servers().require(util::json::requireIdentifier(args, "server")); + auto server = irccd.servers().require(util::json::require_identifier(args, "server")); // General stuff. response.push_back({"name", server->name()}); @@ -303,210 +300,210 @@ response.push_back({"channels", server->channels()}); // Optional stuff. - if (server->flags() & Server::Ipv6) + if (server->flags() & server::ipv6) response.push_back({"ipv6", true}); - if (server->flags() & Server::Ssl) + if (server->flags() & server::ssl) response.push_back({"ssl", true}); - if (server->flags() & Server::SslVerify) + if (server->flags() & server::ssl_verify) response.push_back({"sslVerify", true}); client.success("server-info", response); } -ServerInviteCommand::ServerInviteCommand() - : Command("server-invite") +server_invite_command::server_invite_command() + : command("server-invite") { } -void ServerInviteCommand::exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) +void server_invite_command::exec(irccd& irccd, transport_client& client, const nlohmann::json& args) { - irccd.servers().require(util::json::requireIdentifier(args, "server"))->invite( - util::json::requireString(args, "target"), - util::json::requireString(args, "channel") + irccd.servers().require(util::json::require_identifier(args, "server"))->invite( + util::json::require_string(args, "target"), + util::json::require_string(args, "channel") ); client.success("server-invite"); } -ServerJoinCommand::ServerJoinCommand() - : Command("server-join") +server_join_command::server_join_command() + : command("server-join") { } -void ServerJoinCommand::exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) +void server_join_command::exec(irccd& irccd, transport_client& client, const nlohmann::json& args) { - irccd.servers().require(util::json::requireIdentifier(args, "server"))->join( - util::json::requireString(args, "channel"), - util::json::getString(args, "password") + irccd.servers().require(util::json::require_identifier(args, "server"))->join( + util::json::require_string(args, "channel"), + util::json::get_string(args, "password") ); client.success("server-join"); } -ServerKickCommand::ServerKickCommand() - : Command("server-kick") +server_kick_command::server_kick_command() + : command("server-kick") { } -void ServerKickCommand::exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) +void server_kick_command::exec(irccd& irccd, transport_client& client, const nlohmann::json& args) { - irccd.servers().require(util::json::requireIdentifier(args, "server"))->kick( - util::json::requireString(args, "target"), - util::json::requireString(args, "channel"), - util::json::getString(args, "reason") + irccd.servers().require(util::json::require_identifier(args, "server"))->kick( + util::json::require_string(args, "target"), + util::json::require_string(args, "channel"), + util::json::get_string(args, "reason") ); client.success("server-kick"); } -ServerListCommand::ServerListCommand() - : Command("server-list") +server_list_command::server_list_command() + : command("server-list") { } -void ServerListCommand::exec(Irccd &irccd, TransportClient &client, const nlohmann::json &) +void server_list_command::exec(irccd& irccd, transport_client& client, const nlohmann::json&) { auto json = nlohmann::json::object(); auto list = nlohmann::json::array(); - for (const auto &server : irccd.servers().servers()) + for (const auto& server : irccd.servers().servers()) list.push_back(server->name()); json.push_back({"list", std::move(list)}); client.success("server-list", json); } -ServerMeCommand::ServerMeCommand() - : Command("server-me") +server_me_command::server_me_command() + : command("server-me") { } -void ServerMeCommand::exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) +void server_me_command::exec(irccd& irccd, transport_client& client, const nlohmann::json& args) { - irccd.servers().require(util::json::requireIdentifier(args, "server"))->me( - util::json::requireString(args, "target"), - util::json::requireString(args, "message") + irccd.servers().require(util::json::require_identifier(args, "server"))->me( + util::json::require_string(args, "target"), + util::json::require_string(args, "message") ); client.success("server-me"); } -ServerMessageCommand::ServerMessageCommand() - : Command("server-message") +server_message_command::server_message_command() + : command("server-message") { } -void ServerMessageCommand::exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) +void server_message_command::exec(irccd& irccd, transport_client& client, const nlohmann::json& args) { - irccd.servers().require(util::json::requireIdentifier(args, "server"))->message( - util::json::requireString(args, "target"), - util::json::requireString(args, "message") + irccd.servers().require(util::json::require_identifier(args, "server"))->message( + util::json::require_string(args, "target"), + util::json::require_string(args, "message") ); client.success("server-message"); } -ServerModeCommand::ServerModeCommand() - : Command("server-mode") +server_mode_command::server_mode_command() + : command("server-mode") { } -void ServerModeCommand::exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) +void server_mode_command::exec(irccd& irccd, transport_client& client, const nlohmann::json& args) { - irccd.servers().require(util::json::requireIdentifier(args, "server"))->mode( - util::json::requireString(args, "mode") + irccd.servers().require(util::json::require_identifier(args, "server"))->mode( + util::json::require_string(args, "mode") ); client.success("server-mode"); } -ServerNickCommand::ServerNickCommand() - : Command("server-nick") +server_nick_command::server_nick_command() + : command("server-nick") { } -void ServerNickCommand::exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) +void server_nick_command::exec(irccd& irccd, transport_client& client, const nlohmann::json& args) { - irccd.servers().require(util::json::requireIdentifier(args, "server"))->setNickname( - util::json::requireString(args, "nickname") + irccd.servers().require(util::json::require_identifier(args, "server"))->set_nickname( + util::json::require_string(args, "nickname") ); client.success("server-nick"); } -ServerNoticeCommand::ServerNoticeCommand() - : Command("server-notice") +server_notice_command::server_notice_command() + : command("server-notice") { } -void ServerNoticeCommand::exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) +void server_notice_command::exec(irccd& irccd, transport_client& client, const nlohmann::json& args) { - irccd.servers().require(util::json::requireIdentifier(args, "server"))->notice( - util::json::requireString(args, "target"), - util::json::requireString(args, "message") + irccd.servers().require(util::json::require_identifier(args, "server"))->notice( + util::json::require_string(args, "target"), + util::json::require_string(args, "message") ); client.success("server-notice"); } -ServerPartCommand::ServerPartCommand() - : Command("server-part") +server_part_command::server_part_command() + : command("server-part") { } -void ServerPartCommand::exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) +void server_part_command::exec(irccd& irccd, transport_client& client, const nlohmann::json& args) { - irccd.servers().require(util::json::requireIdentifier(args, "server"))->part( - util::json::requireString(args, "channel"), - util::json::getString(args, "reason") + irccd.servers().require(util::json::require_identifier(args, "server"))->part( + util::json::require_string(args, "channel"), + util::json::get_string(args, "reason") ); client.success("server-part"); } -ServerReconnectCommand::ServerReconnectCommand() - : Command("server-reconnect") +server_reconnect_command::server_reconnect_command() + : command("server-reconnect") { } -void ServerReconnectCommand::exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) +void server_reconnect_command::exec(irccd& irccd, transport_client& client, const nlohmann::json& args) { auto server = args.find("server"); if (server != args.end() && server->is_string()) irccd.servers().require(*server)->reconnect(); else - for (auto &server : irccd.servers().servers()) + for (auto& server : irccd.servers().servers()) server->reconnect(); client.success("server-reconnect"); } -ServerTopicCommand::ServerTopicCommand() - : Command("server-topic") +server_topic_command::server_topic_command() + : command("server-topic") { } -void ServerTopicCommand::exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) +void server_topic_command::exec(irccd& irccd, transport_client& client, const nlohmann::json& args) { - irccd.servers().require(util::json::requireIdentifier(args, "server"))->topic( - util::json::requireString(args, "channel"), - util::json::requireString(args, "topic") + irccd.servers().require(util::json::require_identifier(args, "server"))->topic( + util::json::require_string(args, "channel"), + util::json::require_string(args, "topic") ); client.success("server-topic"); } -RuleEditCommand::RuleEditCommand() - : Command("rule-edit") +rule_edit_command::rule_edit_command() + : command("rule-edit") { } -void RuleEditCommand::exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) +void rule_edit_command::exec(irccd& irccd, transport_client& client, const nlohmann::json& args) { - static const auto updateset = [] (auto &set, auto args, const auto &key) { - for (const auto &v : args["remove-"s + key]) { + static const auto updateset = [] (auto& set, auto args, const auto& key) { + for (const auto& v : args["remove-"s + key]) { if (v.is_string()) set.erase(v.template get<std::string>()); } - for (const auto &v : args["add-"s + key]) { + for (const auto& v : args["add-"s + key]) { if (v.is_string()) set.insert(v.template get<std::string>()); } }; // Create a copy to avoid incomplete edition in case of errors. - auto index = util::json::requireUint(args, "index"); + auto index = util::json::require_uint(args, "index"); auto rule = irccd.rules().require(index); updateset(rule.channels(), args, "channels"); @@ -523,9 +520,9 @@ } if (action->get<std::string>() == "accept") - rule.setAction(RuleAction::Accept); + rule.set_action(rule::action_type::accept); else if (action->get<std::string>() == "drop") - rule.setAction(RuleAction::Drop); + rule.set_action(rule::action_type::drop); else { client.error("rule-edit", "invalid action '"s + action->get<std::string>() + "'"); return; @@ -537,39 +534,39 @@ client.success("rule-edit"); } -RuleListCommand::RuleListCommand() - : Command("rule-list") +rule_list_command::rule_list_command() + : command("rule-list") { } -void RuleListCommand::exec(Irccd &irccd, TransportClient &client, const nlohmann::json &) +void rule_list_command::exec(irccd& irccd, transport_client& client, const nlohmann::json&) { auto array = nlohmann::json::array(); for (const auto& rule : irccd.rules().list()) - array.push_back(toJson(rule)); + array.push_back(to_json(rule)); client.success("rule-list", {{ "list", std::move(array) }}); } -RuleInfoCommand::RuleInfoCommand() - : Command("rule-info") +rule_info_command::rule_info_command() + : command("rule-info") { } -void RuleInfoCommand::exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) +void rule_info_command::exec(irccd& irccd, transport_client& client, const nlohmann::json& args) { - client.success("rule-info", toJson(irccd.rules().require(util::json::requireUint(args, "index")))); + client.success("rule-info", to_json(irccd.rules().require(util::json::require_uint(args, "index")))); } -RuleRemoveCommand::RuleRemoveCommand() - : Command("rule-remove") +rule_remove_command::rule_remove_command() + : command("rule-remove") { } -void RuleRemoveCommand::exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) +void rule_remove_command::exec(irccd& irccd, transport_client& client, const nlohmann::json& args) { - unsigned position = util::json::requireUint(args, "index"); + unsigned position = util::json::require_uint(args, "index"); if (irccd.rules().length() == 0) client.error("rule-remove", "rule list is empty"); @@ -581,15 +578,15 @@ } } -RuleMoveCommand::RuleMoveCommand() - : Command("rule-move") +rule_move_command::rule_move_command() + : command("rule-move") { } -void RuleMoveCommand::exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) +void rule_move_command::exec(irccd& irccd, transport_client& client, const nlohmann::json& args) { - auto from = util::json::requireUint(args, "from"); - auto to = util::json::requireUint(args, "to"); + auto from = util::json::require_uint(args, "from"); + auto to = util::json::require_uint(args, "to"); /* * Examples of moves @@ -635,15 +632,15 @@ } } -RuleAddCommand::RuleAddCommand() - : Command("rule-add") +rule_add_command::rule_add_command() + : command("rule-add") { } -void RuleAddCommand::exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) +void rule_add_command::exec(irccd& irccd, transport_client& client, const nlohmann::json& args) { - auto index = util::json::getUint(args, "index", irccd.rules().length()); - auto rule = fromJson(args); + auto index = util::json::get_uint(args, "index", irccd.rules().length()); + auto rule = from_json(args); if (index > irccd.rules().length()) client.error("rule-add", "index is out of range"); @@ -653,6 +650,4 @@ } } -} // !command - } // !irccd
--- a/libirccd/irccd/command.hpp Fri Aug 11 13:45:42 2017 +0200 +++ b/libirccd/irccd/command.hpp Tue Sep 26 17:18:47 2017 +0200 @@ -33,16 +33,16 @@ namespace irccd { -class Irccd; -class Irccdctl; -class TransportClient; +class irccd; +class irccdctl; +class transport_client; /** * \brief Server side remote command */ -class Command { +class command { private: - std::string m_name; + std::string name_; public: /** @@ -51,25 +51,25 @@ * \pre !name.empty() * \param name the command name */ - inline Command(std::string name) noexcept - : m_name(std::move(name)) + inline command(std::string name) noexcept + : name_(std::move(name)) { - assert(!m_name.empty()); + assert(!name_.empty()); } /** * Default destructor virtual. */ - virtual ~Command() = default; + virtual ~command() = default; /** * Return the command name, must not have spaces. * * \return the command name */ - inline const std::string &name() const noexcept + inline const std::string& name() const noexcept { - return m_name; + return name_; } /** @@ -85,474 +85,473 @@ * \param client the client * \param args the client arguments */ - IRCCD_EXPORT virtual void exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) = 0; + virtual void exec(irccd& irccd, transport_client& client, const nlohmann::json& args) = 0; }; -namespace command { - /** * \brief Implementation of plugin-config transport command. */ -class PluginConfigCommand : public Command { +class plugin_config_command : public command { public: /** * Constructor. */ - IRCCD_EXPORT PluginConfigCommand(); + plugin_config_command(); /** - * \copydoc Command::exec + * \copydoc command::exec */ - IRCCD_EXPORT void exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) override; + void exec(irccd& irccd, transport_client& client, const nlohmann::json& args) override; }; /** * \brief Implementation of plugin-info transport command. */ -class PluginInfoCommand : public Command { +class plugin_info_command : public command { public: /** * Constructor. */ - IRCCD_EXPORT PluginInfoCommand(); + plugin_info_command(); /** - * \copydoc Command::exec + * \copydoc command::exec */ - IRCCD_EXPORT void exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) override; + void exec(irccd& irccd, transport_client& client, const nlohmann::json& args) override; }; /** * \brief Implementation of plugin-list transport command. */ -class PluginListCommand : public Command { +class plugin_list_command : public command { public: /** * Constructor. */ - IRCCD_EXPORT PluginListCommand(); + plugin_list_command(); /** - * \copydoc Command::exec + * \copydoc command::exec */ - IRCCD_EXPORT void exec(Irccd &irccd, TransportClient &client, const nlohmann::json &request) override; + void exec(irccd& irccd, transport_client& client, const nlohmann::json& request) override; }; /** * \brief Implementation of plugin-load transport command. */ -class PluginLoadCommand : public Command { +class plugin_load_command : public command { public: /** * Constructor. */ - IRCCD_EXPORT PluginLoadCommand(); + plugin_load_command(); /** - * \copydoc Command::exec + * \copydoc command::exec */ - IRCCD_EXPORT void exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) override; + void exec(irccd& irccd, transport_client& client, const nlohmann::json& args) override; }; /** * \brief Implementation of plugin-reload transport command. */ -class PluginReloadCommand : public Command { +class plugin_reload_command : public command { public: /** * Constructor. */ - IRCCD_EXPORT PluginReloadCommand(); + plugin_reload_command(); /** - * \copydoc Command::exec + * \copydoc command::exec */ - IRCCD_EXPORT void exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) override; + void exec(irccd& irccd, transport_client& client, const nlohmann::json& args) override; }; /** * \brief Implementation of plugin-unload transport command. */ -class PluginUnloadCommand : public Command { +class plugin_unload_command : public command { public: /** * Constructor. */ - IRCCD_EXPORT PluginUnloadCommand(); + plugin_unload_command(); /** - * \copydoc Command::exec + * \copydoc command::exec */ - IRCCD_EXPORT void exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) override; + void exec(irccd& irccd, transport_client& client, const nlohmann::json& args) override; }; /** * \brief Implementation of server-cmode transport command. */ -class ServerChannelModeCommand : public Command { +class server_channel_mode_command : public command { public: /** * Constructor. */ - IRCCD_EXPORT ServerChannelModeCommand(); + server_channel_mode_command(); /** - * \copydoc Command::exec + * \copydoc command::exec */ - IRCCD_EXPORT void exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) override; + void exec(irccd& irccd, transport_client& client, const nlohmann::json& args) override; }; /** * \brief Implementation of server-cnotice transport command. */ -class ServerChannelNoticeCommand : public Command { +class server_channel_notice_command : public command { public: /** * Constructor. */ - IRCCD_EXPORT ServerChannelNoticeCommand(); + server_channel_notice_command(); /** - * \copydoc Command::exec + * \copydoc command::exec */ - IRCCD_EXPORT void exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) override; + void exec(irccd& irccd, transport_client& client, const nlohmann::json& args) override; }; /** * \brief Implementation of server-connect transport command. */ -class ServerConnectCommand : public Command { +class server_connect_command : public command { public: /** * Constructor. */ - IRCCD_EXPORT ServerConnectCommand(); + server_connect_command(); /** - * \copydoc Command::exec + * \copydoc command::exec */ - IRCCD_EXPORT void exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) override; + void exec(irccd& irccd, transport_client& client, const nlohmann::json& args) override; }; /** * \brief Implementation of server-disconnect transport command. */ -class IRCCD_EXPORT ServerDisconnectCommand : public Command { +class server_disconnect_command : public command { public: /** * Constructor. */ - ServerDisconnectCommand(); + server_disconnect_command(); /** - * \copydoc Command::exec + * \copydoc command::exec */ - void exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) override; + void exec(irccd& irccd, transport_client& client, const nlohmann::json& args) override; }; /** * \brief Implementation of server-info transport command. */ -class IRCCD_EXPORT ServerInfoCommand : public Command { +class server_info_command : public command { public: /** * Constructor. */ - ServerInfoCommand(); + server_info_command(); /** - * \copydoc Command::exec + * \copydoc command::exec */ - void exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) override; + void exec(irccd& irccd, transport_client& client, const nlohmann::json& args) override; }; /** * \brief Implementation of server-invite transport command. */ -class ServerInviteCommand : public Command { +class server_invite_command : public command { public: /** * Constructor. */ - IRCCD_EXPORT ServerInviteCommand(); + server_invite_command(); /** - * \copydoc Command::exec + * \copydoc command::exec */ - IRCCD_EXPORT void exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) override; + void exec(irccd& irccd, transport_client& client, const nlohmann::json& args) override; }; /** * \brief Implementation of server-join transport command. */ -class ServerJoinCommand : public Command { +class server_join_command : public command { public: /** * Constructor. */ - IRCCD_EXPORT ServerJoinCommand(); + server_join_command(); /** - * \copydoc Command::exec + * \copydoc command::exec */ - IRCCD_EXPORT void exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) override; + void exec(irccd& irccd, transport_client& client, const nlohmann::json& args) override; }; /** * \brief Implementation of server-kick transport command. */ -class ServerKickCommand : public Command { +class server_kick_command : public command { public: /** * Constructor. */ - IRCCD_EXPORT ServerKickCommand(); + server_kick_command(); /** - * \copydoc Command::exec + * \copydoc command::exec */ - IRCCD_EXPORT void exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) override; + void exec(irccd& irccd, transport_client& client, const nlohmann::json& args) override; }; /** * \brief Implementation of server-list transport command. */ -class ServerListCommand : public Command { +class server_list_command : public command { public: /** * Constructor. */ - IRCCD_EXPORT ServerListCommand(); + server_list_command(); /** - * \copydoc Command::exec + * \copydoc command::exec */ - IRCCD_EXPORT void exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) override; + void exec(irccd& irccd, transport_client& client, const nlohmann::json& args) override; }; /** * \brief Implementation of server-me transport command. */ -class IRCCD_EXPORT ServerMeCommand : public Command { +class server_me_command : public command { public: /** * Constructor. */ - ServerMeCommand(); + server_me_command(); /** - * \copydoc Command::exec + * \copydoc command::exec */ - void exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) override; + void exec(irccd& irccd, transport_client& client, const nlohmann::json& args) override; }; /** * \brief Implementation of server-message transport command. */ -class IRCCD_EXPORT ServerMessageCommand : public Command { +class server_message_command : public command { public: /** * Constructor. */ - ServerMessageCommand(); + server_message_command(); /** - * \copydoc Command::exec + * \copydoc command::exec */ - void exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) override; + void exec(irccd& irccd, transport_client& client, const nlohmann::json& args) override; }; /** * \brief Implementation of server-mode transport command. */ -class IRCCD_EXPORT ServerModeCommand : public Command { +class server_mode_command : public command { public: /** * Constructor. */ - ServerModeCommand(); + server_mode_command(); /** - * \copydoc Command::exec + * \copydoc command::exec */ - void exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) override; + void exec(irccd& irccd, transport_client& client, const nlohmann::json& args) override; }; /** * \brief Implementation of server-nick transport command. */ -class IRCCD_EXPORT ServerNickCommand : public Command { +class server_nick_command : public command { public: /** * Constructor. */ - ServerNickCommand(); + server_nick_command(); /** - * \copydoc Command::exec + * \copydoc command::exec */ - void exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) override; + void exec(irccd& irccd, transport_client& client, const nlohmann::json& args) override; }; /** * \brief Implementation of server-notice transport command. */ -class IRCCD_EXPORT ServerNoticeCommand : public Command { +class server_notice_command : public command { public: /** * Constructor. */ - ServerNoticeCommand(); + server_notice_command(); /** - * \copydoc Command::exec + * \copydoc command::exec */ - void exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) override; + void exec(irccd& irccd, transport_client& client, const nlohmann::json& args) override; }; /** * \brief Implementation of server-part transport command. */ -class IRCCD_EXPORT ServerPartCommand : public Command { +class server_part_command : public command { public: /** * Constructor. */ - ServerPartCommand(); + server_part_command(); /** - * \copydoc Command::exec + * \copydoc command::exec */ - void exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) override; + void exec(irccd& irccd, transport_client& client, const nlohmann::json& args) override; }; /** * \brief Implementation of server-reconnect transport command. */ -class ServerReconnectCommand : public Command { +class server_reconnect_command : public command { public: /** * Constructor. */ - IRCCD_EXPORT ServerReconnectCommand(); + server_reconnect_command(); /** - * \copydoc Command::exec + * \copydoc command::exec */ - IRCCD_EXPORT void exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) override; + void exec(irccd& irccd, transport_client& client, const nlohmann::json& args) override; }; /** * \brief Implementation of server-topic transport command. */ -class IRCCD_EXPORT ServerTopicCommand : public Command { +class server_topic_command : public command { public: /** * Constructor. */ - ServerTopicCommand(); + server_topic_command(); /** - * \copydoc Command::exec + * \copydoc command::exec */ - void exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) override; + void exec(irccd& irccd, transport_client& client, const nlohmann::json& args) override; }; -class IRCCD_EXPORT RuleEditCommand : public Command { +/** + * \brief Implementation of rule-edit transport command. + */ +class rule_edit_command : public command { public: /** * Constructor. */ - RuleEditCommand(); + rule_edit_command(); /** - * \copydoc Command::exec + * \copydoc command::exec */ - void exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) override; + void exec(irccd& irccd, transport_client& client, const nlohmann::json& args) override; }; /** * \brief Implementation of rule-list transport command. */ -class IRCCD_EXPORT RuleListCommand : public Command { +class rule_list_command : public command { public: /** * Constructor. */ - RuleListCommand(); + rule_list_command(); /** - * \copydoc Command::exec + * \copydoc command::exec */ - void exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) override; + void exec(irccd& irccd, transport_client& client, const nlohmann::json& args) override; }; /** * \brief Implementation of rule-info transport command. */ -class IRCCD_EXPORT RuleInfoCommand : public Command { +class rule_info_command : public command { public: /** * Constructor. */ - RuleInfoCommand(); + rule_info_command(); /** - * \copydoc Command::exec + * \copydoc command::exec */ - void exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) override; + void exec(irccd& irccd, transport_client& client, const nlohmann::json& args) override; }; /** * \brief Implementation of rule-remove transport command. */ -class IRCCD_EXPORT RuleRemoveCommand : public Command { +class rule_remove_command : public command { public: /** * Constructor. */ - RuleRemoveCommand(); + rule_remove_command(); /** - * \copydoc Command::exec + * \copydoc command::exec */ - void exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) override; + void exec(irccd& irccd, transport_client& client, const nlohmann::json& args) override; }; /** * \brief Implementation of rule-move transport command. */ -class IRCCD_EXPORT RuleMoveCommand : public Command { +class rule_move_command : public command { public: /** * Constructor. */ - RuleMoveCommand(); + rule_move_command(); /** - * \copydoc Command::exec + * \copydoc command::exec */ - void exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) override; + void exec(irccd& irccd, transport_client& client, const nlohmann::json& args) override; }; /** * \brief Implementation of rule-add transport command. */ -class IRCCD_EXPORT RuleAddCommand : public Command { +class rule_add_command : public command { public: /** * Constructor. */ - RuleAddCommand(); + rule_add_command(); /** - * \copydoc Command::exec + * \copydoc command::exec */ - void exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) override; + void exec(irccd& irccd, transport_client& client, const nlohmann::json& args) override; }; -} // !command - } // !irccd #endif // !IRCCD_COMMAND_HPP
--- a/libirccd/irccd/config.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/libirccd/irccd/config.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -41,43 +41,43 @@ namespace { -class IrccdLogFilter : public log::Filter { +class irccd_log_filter : public log::filter { private: - std::string convert(const std::string &tmpl, std::string input) const + std::string convert(const std::string& tmpl, std::string input) const { if (tmpl.empty()) return input; - util::Substitution params; + util::subst params; - params.flags &= ~(util::Substitution::IrcAttrs); + params.flags &= ~(util::subst_flags::irc_attrs); params.keywords.emplace("message", std::move(input)); return util::format(tmpl, params); } public: - std::string m_debug; - std::string m_info; - std::string m_warning; + std::string debug_; + std::string info_; + std::string warning_; - std::string preDebug(std::string input) const override + std::string pre_debug(std::string input) const override { - return convert(m_debug, std::move(input)); + return convert(debug_, std::move(input)); } - std::string preInfo(std::string input) const override + std::string pre_info(std::string input) const override { - return convert(m_info, std::move(input)); + return convert(info_, std::move(input)); } - std::string preWarning(std::string input) const override + std::string pre_warning(std::string input) const override { - return convert(m_warning, std::move(input)); + return convert(warning_, std::move(input)); } }; -std::string get(const ini::Document &doc, const std::string §ion, const std::string &key) +std::string get(const ini::document& doc, const std::string& section, const std::string& key) { auto its = doc.find(section); @@ -92,19 +92,19 @@ return ito->value(); } -PluginConfig loadPluginConfig(const ini::Section &sc) +plugin_config load_plugin_config(const ini::section& sc) { - PluginConfig config; + plugin_config config; - for (const auto &option : sc) + for (const auto& option : sc) config.emplace(option.key(), option.value()); return config; } -PluginPaths readPaths(const ini::Section& sc) +plugin_paths read_paths(const ini::section& sc) { - PluginPaths paths; + plugin_paths paths; for (const auto& opt : sc) paths.emplace(opt.key(), opt.value()); @@ -112,7 +112,7 @@ return paths; } -std::unique_ptr<log::Logger> loadLogFile(const ini::Section &sc) +std::unique_ptr<log::logger> load_log_file(const ini::section& sc) { /* * TODO: improve that with CMake options. @@ -125,31 +125,31 @@ std::string errors = "/var/log/irccd/errors.txt"; #endif - ini::Section::const_iterator it; + ini::section::const_iterator it; if ((it = sc.find("path-logs")) != sc.end()) normal = it->value(); if ((it = sc.find("path-errors")) != sc.end()) errors = it->value(); - return std::make_unique<log::FileLogger>(std::move(normal), std::move(errors)); + return std::make_unique<log::file_logger>(std::move(normal), std::move(errors)); } -std::unique_ptr<log::Logger> loadLogSyslog() +std::unique_ptr<log::logger> load_log_syslog() { #if defined(HAVE_SYSLOG) - return std::make_unique<log::SyslogLogger>(); + return std::make_unique<log::syslog_logger>(); #else throw std::runtime_error("logs: syslog is not available on this platform"); #endif // !HAVE_SYSLOG } -std::shared_ptr<TransportServer> loadTransportIp(const ini::Section &sc) +std::shared_ptr<transport_server> load_transport_ip(const ini::section& sc) { assert(sc.key() == "transport"); - std::shared_ptr<TransportServer> transport; - ini::Section::const_iterator it; + std::shared_ptr<transport_server> transport; + ini::section::const_iterator it; // Port. int port; @@ -158,8 +158,8 @@ throw std::invalid_argument("transport: missing 'port' parameter"); try { - port = util::toNumber<std::uint16_t>(it->value()); - } catch (const std::exception &) { + port = util::to_number<std::uint16_t>(it->value()); + } catch (const std::exception&) { throw std::invalid_argument("transport: invalid port number: {}"_format(it->value())); } @@ -169,7 +169,7 @@ if ((it = sc.find("address")) != sc.end()) address = it->value(); - std::uint8_t mode = TransportServerIp::v4; + std::uint8_t mode = transport_server_ip::v4; /* * Documentation stated family but code checked for 'domain' option. @@ -181,11 +181,11 @@ if ((it = sc.find("domain")) != sc.end() || (it = sc.find("family")) != sc.end()) { mode = 0; - for (const auto &v : *it) { + for (const auto& v : *it) { if (v == "ipv4") - mode |= TransportServerIp::v4; + mode |= transport_server_ip::v4; if (v == "ipv6") - mode |= TransportServerIp::v6; + mode |= transport_server_ip::v6; } } @@ -193,7 +193,7 @@ std::string pkey; std::string cert; - if ((it = sc.find("ssl")) != sc.end() && util::isBoolean(it->value())) { + if ((it = sc.find("ssl")) != sc.end() && util::is_boolean(it->value())) { if ((it = sc.find("certificate")) == sc.end()) throw std::invalid_argument("transport: missing 'certificate' parameter"); @@ -209,26 +209,26 @@ throw std::invalid_argument("transport: family must at least have ipv4 or ipv6"); if (pkey.empty()) - return std::make_shared<TransportServerIp>(address, port, mode); + return std::make_shared<transport_server_ip>(address, port, mode); #if defined(WITH_SSL) - return std::make_shared<TransportServerTls>(pkey, cert, address, port, mode); + return std::make_shared<transport_server_tls>(pkey, cert, address, port, mode); #else throw std::invalid_argument("transport: SSL disabled"); #endif } -std::shared_ptr<TransportServer> loadTransportUnix(const ini::Section &sc) +std::shared_ptr<transport_server> load_transport_unix(const ini::section& sc) { assert(sc.key() == "transport"); #if !defined(IRCCD_SYSTEM_WINDOWS) - ini::Section::const_iterator it = sc.find("path"); + ini::section::const_iterator it = sc.find("path"); if (it == sc.end()) throw std::invalid_argument("transport: missing 'path' parameter"); - return std::make_shared<TransportServerLocal>(it->value()); + return std::make_shared<transport_server_local>(it->value()); #else (void)sc; @@ -236,120 +236,122 @@ #endif } -std::shared_ptr<TransportServer> loadTransport(const ini::Section &sc) +std::shared_ptr<transport_server> load_transport(const ini::section& sc) { assert(sc.key() == "transport"); - std::shared_ptr<TransportServer> transport; - ini::Section::const_iterator it = sc.find("type"); + std::shared_ptr<transport_server> transport; + ini::section::const_iterator it = sc.find("type"); if (it == sc.end()) throw std::invalid_argument("transport: missing 'type' parameter"); if (it->value() == "ip") - transport = loadTransportIp(sc); + transport = load_transport_ip(sc); else if (it->value() == "unix") - transport = loadTransportUnix(sc); + transport = load_transport_unix(sc); else throw std::invalid_argument("transport: invalid type given: {}"_format(it->value())); if ((it = sc.find("password")) != sc.end()) - transport->setPassword(it->value()); + transport->set_password(it->value()); return transport; } -Rule loadRule(const ini::Section &sc) +rule load_rule(const ini::section& sc) { assert(sc.key() == "rule"); // Simple converter from std::vector to std::unordered_set. - auto toSet = [] (const std::vector<std::string> &v) -> std::unordered_set<std::string> { + auto toset = [] (const auto& v) { return std::unordered_set<std::string>(v.begin(), v.end()); }; - RuleSet servers, channels, origins, plugins, events; - RuleAction action = RuleAction::Accept; + rule::set servers, channels, origins, plugins, events; + rule::action_type action = rule::action_type::accept; // Get the sets. - ini::Section::const_iterator it; + ini::section::const_iterator it; if ((it = sc.find("servers")) != sc.end()) - servers = toSet(*it); + servers = toset(*it); if ((it = sc.find("channels")) != sc.end()) - channels = toSet(*it); + channels = toset(*it); if ((it = sc.find("origins")) != sc.end()) - origins = toSet(*it); + origins = toset(*it); if ((it = sc.find("plugins")) != sc.end()) - plugins = toSet(*it); + plugins = toset(*it); if ((it = sc.find("channels")) != sc.end()) - channels = toSet(*it); + channels = toset(*it); // Get the action. if ((it = sc.find("action")) == sc.end()) throw std::invalid_argument("rule: missing 'action'' parameter"); if (it->value() == "drop") - action = RuleAction::Drop; + action = rule::action_type::drop; else if (it->value() == "accept") - action = RuleAction::Accept; + action = rule::action_type::accept; else throw std::invalid_argument("rule: invalid action given: {}"_format(it->value())); - return Rule(std::move(servers), - std::move(channels), - std::move(origins), - std::move(plugins), - std::move(events), - action); + return { + std::move(servers), + std::move(channels), + std::move(origins), + std::move(plugins), + std::move(events), + action + }; } -std::shared_ptr<Server> loadServer(const ini::Section &sc, const Config &config) +std::shared_ptr<server> load_server(const ini::section& sc, const config& config) { assert(sc.key() == "server"); // Name. - ini::Section::const_iterator it; + ini::section::const_iterator it; if ((it = sc.find("name")) == sc.end()) throw std::invalid_argument("server: missing 'name' parameter"); - else if (!util::isIdentifierValid(it->value())) + else if (!util::is_identifier(it->value())) throw std::invalid_argument("server: invalid identifier: {}"_format(it->value())); - auto server = std::make_shared<Server>(it->value()); + auto sv = std::make_shared<server>(it->value()); // Host if ((it = sc.find("host")) == sc.end()) - throw std::invalid_argument("server {}: missing host"_format(server->name())); + throw std::invalid_argument("server {}: missing host"_format(sv->name())); - server->setHost(it->value()); + sv->set_host(it->value()); // Optional password if ((it = sc.find("password")) != sc.end()) - server->setPassword(it->value()); + sv->set_password(it->value()); // Optional flags - if ((it = sc.find("ipv6")) != sc.end() && util::isBoolean(it->value())) - server->setFlags(server->flags() | Server::Ipv6); - if ((it = sc.find("ssl")) != sc.end() && util::isBoolean(it->value())) - server->setFlags(server->flags() | Server::Ssl); - if ((it = sc.find("ssl-verify")) != sc.end() && util::isBoolean(it->value())) - server->setFlags(server->flags() | Server::SslVerify); + if ((it = sc.find("ipv6")) != sc.end() && util::is_boolean(it->value())) + sv->set_flags(sv->flags() | server::ipv6); + if ((it = sc.find("ssl")) != sc.end() && util::is_boolean(it->value())) + sv->set_flags(sv->flags() | server::ssl); + if ((it = sc.find("ssl-verify")) != sc.end() && util::is_boolean(it->value())) + sv->set_flags(sv->flags() | server::ssl_verify); // Optional identity if ((it = sc.find("identity")) != sc.end()) - config.loadServerIdentity(*server, it->value()); + config.load_server_identity(*sv, it->value()); // Options - if ((it = sc.find("auto-rejoin")) != sc.end() && util::isBoolean(it->value())) - server->setFlags(server->flags() | Server::AutoRejoin); - if ((it = sc.find("join-invite")) != sc.end() && util::isBoolean(it->value())) - server->setFlags(server->flags() | Server::JoinInvite); + if ((it = sc.find("auto-rejoin")) != sc.end() && util::is_boolean(it->value())) + sv->set_flags(sv->flags() | server::auto_rejoin); + if ((it = sc.find("join-invite")) != sc.end() && util::is_boolean(it->value())) + sv->set_flags(sv->flags() | server::join_invite); // Channels if ((it = sc.find("channels")) != sc.end()) { - for (const std::string &s : *it) { - Channel channel; + for (const auto& s : *it) { + channel channel; if (auto pos = s.find(":") != std::string::npos) { channel.name = s.substr(0, pos); @@ -357,42 +359,40 @@ } else channel.name = s; - //server.channels.push_back(std::move(channel)); - //server->join() - server->join(channel.name, channel.password); + sv->join(channel.name, channel.password); } } if ((it = sc.find("command-char")) != sc.end()) - server->setCommandCharacter(it->value()); + sv->set_command_char(it->value()); // Reconnect and ping timeout try { if ((it = sc.find("port")) != sc.end()) - server->setPort(util::toNumber<std::uint16_t>(it->value())); + sv->set_port(util::to_number<std::uint16_t>(it->value())); if ((it = sc.find("reconnect-tries")) != sc.end()) - server->setReconnectTries(util::toNumber<std::int8_t>(it->value())); + sv->set_reconnect_tries(util::to_number<std::int8_t>(it->value())); if ((it = sc.find("reconnect-timeout")) != sc.end()) - server->setReconnectDelay(util::toNumber<std::uint16_t>(it->value())); + sv->set_reconnect_delay(util::to_number<std::uint16_t>(it->value())); if ((it = sc.find("ping-timeout")) != sc.end()) - server->setPingTimeout(util::toNumber<std::uint16_t>(it->value())); - } catch (const std::exception &) { - log::warning("server {}: invalid number for {}: {}"_format(server->name(), it->key(), it->value())); + sv->set_ping_timeout(util::to_number<std::uint16_t>(it->value())); + } catch (const std::exception&) { + log::warning("server {}: invalid number for {}: {}"_format(sv->name(), it->key(), it->value())); } - return server; + return sv; } } // !namespace -Config Config::find() +config config::find() { for (const auto& path : sys::config_filenames("irccd.conf")) { try { boost::system::error_code ec; if (boost::filesystem::exists(path, ec) && !ec) - return Config(path); - } catch (const std::exception &ex) { + return config(path); + } catch (const std::exception& ex) { log::warning() << path << ": " << ex.what() << std::endl; } } @@ -400,9 +400,9 @@ throw std::runtime_error("no configuration file found"); } -void Config::loadServerIdentity(Server &server, const std::string &identity) const +void config::load_server_identity(server& server, const std::string& identity) const { - ini::Document::const_iterator sc = std::find_if(m_document.begin(), m_document.end(), [&] (const auto &sc) { + auto sc = std::find_if(document_.begin(), document_.end(), [&] (const auto& sc) { if (sc.key() != "identity") return false; @@ -411,169 +411,169 @@ return name != sc.end() && name->value() == identity; }); - if (sc == m_document.end()) + if (sc == document_.end()) return; - ini::Section::const_iterator it; + ini::section::const_iterator it; if ((it = sc->find("username")) != sc->end()) - server.setUsername(it->value()); + server.set_username(it->value()); if ((it = sc->find("realname")) != sc->end()) - server.setRealname(it->value()); + server.set_realname(it->value()); if ((it = sc->find("nickname")) != sc->end()) - server.setNickname(it->value()); + server.set_nickname(it->value()); if ((it = sc->find("ctcp-version")) != sc->end()) - server.setCtcpVersion(it->value()); + server.set_ctcp_version(it->value()); } -PluginConfig Config::findPluginConfig(const std::string &name) const +plugin_config config::find_plugin_config(const std::string& name) const { - assert(util::isIdentifierValid(name)); + assert(util::is_identifier(name)); std::string fullname = std::string("plugin.") + name; - for (const auto §ion : m_document) { + for (const auto& section : document_) { if (section.key() != fullname) continue; - return loadPluginConfig(section); + return load_plugin_config(section); } - return PluginConfig(); + return plugin_config(); } -PluginFormats Config::findPluginFormats(const std::string &name) const +plugin_formats config::find_plugin_formats(const std::string& name) const { - assert(util::isIdentifierValid(name)); + assert(util::is_identifier(name)); - auto section = m_document.find(std::string("format.") + name); + auto section = document_.find(std::string("format.") + name); - if (section == m_document.end()) - return PluginFormats(); + if (section == document_.end()) + return plugin_formats(); - PluginFormats formats; + plugin_formats formats; - for (const auto &opt : *section) + for (const auto& opt : *section) formats.emplace(opt.key(), opt.value()); return formats; } -PluginPaths Config::findPluginPaths(const std::string& name) const +plugin_paths config::find_plugin_paths(const std::string& name) const { - assert(util::isIdentifierValid(name)); + assert(util::is_identifier(name)); - auto section = m_document.find(std::string("paths.") + name); + auto section = document_.find(std::string("paths.") + name); - if (section == m_document.end()) - return PluginPaths(); + if (section == document_.end()) + return plugin_paths(); - return readPaths(*section); + return read_paths(*section); } -bool Config::isVerbose() const noexcept +bool config::is_verbose() const noexcept { - return util::isBoolean(get(m_document, "logs", "verbose")); + return util::is_boolean(get(document_, "logs", "verbose")); } -bool Config::isForeground() const noexcept +bool config::is_foreground() const noexcept { - return util::isBoolean(get(m_document, "general", "foreground")); + return util::is_boolean(get(document_, "general", "foreground")); } -std::string Config::pidfile() const +std::string config::pidfile() const { - return get(m_document, "general", "pidfile"); + return get(document_, "general", "pidfile"); } -std::string Config::uid() const +std::string config::uid() const { - return get(m_document, "general", "uid"); + return get(document_, "general", "uid"); } -std::string Config::gid() const +std::string config::gid() const { - return get(m_document, "general", "gid"); + return get(document_, "general", "gid"); } -void Config::loadLogs() const +void config::load_logs() const { - ini::Document::const_iterator sc = m_document.find("logs"); + ini::document::const_iterator sc = document_.find("logs"); - if (sc == m_document.end()) + if (sc == document_.end()) return; - ini::Section::const_iterator it; + ini::section::const_iterator it; if ((it = sc->find("type")) != sc->end()) { - std::unique_ptr<log::Logger> iface; + std::unique_ptr<log::logger> iface; // Console is the default, no test case. if (it->value() == "file") - iface = loadLogFile(*sc); + iface = load_log_file(*sc); else if (it->value() == "syslog") - iface = loadLogSyslog(); + iface = load_log_syslog(); else if (it->value() != "console") throw std::runtime_error("logs: unknown log type: {}"_format(it->value())); if (iface) - log::setLogger(std::move(iface)); + log::set_logger(std::move(iface)); } } -void Config::loadFormats() const +void config::load_formats() const { - ini::Document::const_iterator sc = m_document.find("format"); + ini::document::const_iterator sc = document_.find("format"); + ini::section::const_iterator it; - if (sc == m_document.end()) + if (sc == document_.end()) return; - std::unique_ptr<IrccdLogFilter> filter = std::make_unique<IrccdLogFilter>(); - ini::Section::const_iterator it; + auto filter = std::make_unique<irccd_log_filter>(); if ((it = sc->find("debug")) != sc->cend()) - filter->m_debug = it->value(); + filter->debug_ = it->value(); if ((it = sc->find("info")) != sc->cend()) - filter->m_info = it->value(); + filter->info_ = it->value(); if ((it = sc->find("warning")) != sc->cend()) - filter->m_warning = it->value(); + filter->warning_ = it->value(); - log::setFilter(std::move(filter)); + log::set_filter(std::move(filter)); } -std::vector<std::shared_ptr<TransportServer>> Config::loadTransports() const +std::vector<std::shared_ptr<transport_server>> config::load_transports() const { - std::vector<std::shared_ptr<TransportServer>> transports; + std::vector<std::shared_ptr<transport_server>> transports; - for (const auto §ion : m_document) + for (const auto& section : document_) if (section.key() == "transport") - transports.push_back(loadTransport(section)); + transports.push_back(load_transport(section)); return transports; } -std::vector<Rule> Config::loadRules() const +std::vector<rule> config::load_rules() const { - std::vector<Rule> rules; + std::vector<rule> rules; - for (const auto §ion : m_document) + for (const auto& section : document_) if (section.key() == "rule") - rules.push_back(loadRule(section)); + rules.push_back(load_rule(section)); return rules; } -std::vector<std::shared_ptr<Server>> Config::loadServers() const +std::vector<std::shared_ptr<server>> config::load_servers() const { - std::vector<std::shared_ptr<Server>> servers; + std::vector<std::shared_ptr<server>> servers; - for (const auto §ion : m_document) { + for (const auto& section : document_) { if (section.key() != "server") continue; try { - servers.push_back(loadServer(section, *this)); - } catch (const std::exception &ex) { + servers.push_back(load_server(section, *this)); + } catch (const std::exception& ex) { log::warning(ex.what()); } } @@ -581,34 +581,34 @@ return servers; } -PluginPaths Config::loadPaths() const +plugin_paths config::load_paths() const { - auto section = m_document.find("paths"); + auto section = document_.find("paths"); - if (section == m_document.end()) + if (section == document_.end()) return {}; - return readPaths(*section); + return read_paths(*section); } -void Config::loadPlugins(Irccd &irccd) const +void config::load_plugins(irccd& irccd) const { - auto it = m_document.find("plugins"); + auto it = document_.find("plugins"); - irccd.plugins().setPaths(loadPaths()); + irccd.plugins().set_paths(load_paths()); - if (it != m_document.end()) { - for (const auto &option : *it) { - if (!util::isIdentifierValid(option.key())) + if (it != document_.end()) { + for (const auto& option : *it) { + if (!util::is_identifier(option.key())) continue; - auto paths = findPluginPaths(option.key()); + auto paths = find_plugin_paths(option.key()); if (!paths.empty()) - irccd.plugins().setPaths(std::move(paths)); + irccd.plugins().set_paths(std::move(paths)); - irccd.plugins().setConfig(option.key(), findPluginConfig(option.key())); - irccd.plugins().setFormats(option.key(), findPluginFormats(option.key())); + irccd.plugins().set_config(option.key(), find_plugin_config(option.key())); + irccd.plugins().set_formats(option.key(), find_plugin_formats(option.key())); irccd.plugins().load(option.key(), option.value()); } }
--- a/libirccd/irccd/config.hpp Fri Aug 11 13:45:42 2017 +0200 +++ b/libirccd/irccd/config.hpp Tue Sep 26 17:18:47 2017 +0200 @@ -34,18 +34,18 @@ namespace irccd { -class Irccd; -class Rule; -class Server; -class TransportServer; +class irccd; +class rule; +class server; +class transport_server; /** * \brief Read .ini configuration file for irccd */ -class Config { +class config { private: - std::string m_path; - ini::Document m_document; + std::string path_; + ini::document document_; public: /** @@ -54,16 +54,16 @@ * \return the config * \throw std::exception on errors or if no config could be found */ - IRCCD_EXPORT static Config find(); + static config find(); /** * Load the configuration from the specified path. * * \param path the path */ - inline Config(std::string path) - : m_path(std::move(path)) - , m_document(ini::readFile(m_path)) + inline config(std::string path) + : path_(std::move(path)) + , document_(ini::read_file(path_)) { } @@ -72,9 +72,9 @@ * * \return the path */ - inline const std::string &path() const noexcept + inline const std::string& path() const noexcept { - return m_path; + return path_; } /** @@ -85,7 +85,7 @@ * \param name the identity name * \return default identity if cannot be found */ - IRCCD_EXPORT void loadServerIdentity(Server &server, const std::string &name) const; + void load_server_identity(server& server, const std::string& name) const; /** * Find a plugin configuration if defined in the configuration file. @@ -93,7 +93,7 @@ * \pre util::isValidIdentifier(name) * \return the configuration or empty if not found */ - IRCCD_EXPORT PluginConfig findPluginConfig(const std::string &name) const; + plugin_config find_plugin_config(const std::string& name) const; /** * Find plugin formats if defined. @@ -101,7 +101,7 @@ * \pre util::isValidIdentifier(name) * \return the formats or empty one if not found */ - IRCCD_EXPORT PluginFormats findPluginFormats(const std::string &name) const; + plugin_formats find_plugin_formats(const std::string& name) const; /** * Find plugin paths if defined. @@ -109,80 +109,80 @@ * \pre util::isValidIdentifier(name) * \param name the plugin name */ - IRCCD_EXPORT PluginPaths findPluginPaths(const std::string& name) const; + plugin_paths find_plugin_paths(const std::string& name) const; /** * Get the path to the pidfile. * * \return the path or empty if not defined */ - IRCCD_EXPORT std::string pidfile() const; + std::string pidfile() const; /** * Get the uid. * * \return the uid or empty one if no one is set */ - IRCCD_EXPORT std::string uid() const; + std::string uid() const; /** * Get the gid. * * \return the gid or empty one if no one is set */ - IRCCD_EXPORT std::string gid() const; + std::string gid() const; /** * Check if verbosity is enabled. * * \return true if verbosity was requested */ - IRCCD_EXPORT bool isVerbose() const noexcept; + bool is_verbose() const noexcept; /** * Check if foreground is specified (= no daemonize). * * \return true if foreground was requested */ - IRCCD_EXPORT bool isForeground() const noexcept; + bool is_foreground() const noexcept; /** * Load logging interface. */ - IRCCD_EXPORT void loadLogs() const; + void load_logs() const; /** * Load formats for logging. */ - IRCCD_EXPORT void loadFormats() const; + void load_formats() const; /** * Load transports. * * \return the set of transports */ - IRCCD_EXPORT std::vector<std::shared_ptr<TransportServer>> loadTransports() const; + std::vector<std::shared_ptr<transport_server>> load_transports() const; /** * Load rules. * * \return the rules */ - IRCCD_EXPORT std::vector<Rule> loadRules() const; + std::vector<rule> load_rules() const; /** * Get the list of servers defined. * * \return the list of servers */ - IRCCD_EXPORT std::vector<std::shared_ptr<Server>> loadServers() const; + std::vector<std::shared_ptr<server>> load_servers() const; /** * Load default paths for plugins. * * \return the map of paths */ - IRCCD_EXPORT PluginPaths loadPaths() const; + plugin_paths load_paths() const; /** * Get the list of defined plugins. @@ -190,7 +190,7 @@ * \param irccd the irccd instance * \return the list of plugins */ - IRCCD_EXPORT void loadPlugins(Irccd &irccd) const; + void load_plugins(irccd& irccd) const; }; } // !irccd
--- a/libirccd/irccd/irccd.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/libirccd/irccd/irccd.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -22,79 +22,74 @@ #include "service.hpp" #include "util.hpp" -using namespace std; -using namespace std::placeholders; -using namespace std::string_literals; - namespace irccd { -Irccd::Irccd() - : m_commandService(std::make_shared<CommandService>()) - , m_interruptService(std::make_shared<InterruptService>()) - , m_servers(std::make_shared<ServerService>(*this)) - , m_transports(std::make_shared<TransportService>(*this)) - , m_ruleService(std::make_shared<RuleService>()) - , m_plugins(std::make_shared<PluginService>(*this)) +irccd::irccd() + : command_service_(std::make_shared<command_service>()) + , itr_service_(std::make_shared<interrupt_service>()) + , server_service_(std::make_shared<server_service>(*this)) + , tpt_service_(std::make_shared<transport_service>(*this)) + , rule_service_(std::make_shared<rule_service>()) + , plugin_service_(std::make_shared<plugin_service>(*this)) { } -void Irccd::post(std::function<void (Irccd &)> ev) noexcept +void irccd::post(std::function<void (irccd&)> ev) noexcept { - std::lock_guard<mutex> lock(m_mutex); + std::lock_guard<std::mutex> lock(mutex_); - m_events.push_back(move(ev)); - m_interruptService->interrupt(); + events_.push_back(std::move(ev)); + itr_service_->interrupt(); } -void Irccd::run() +void irccd::run() { - while (m_running) + while (running_) util::poller::poll(250, *this); } -void Irccd::prepare(fd_set &in, fd_set &out, net::Handle &max) +void irccd::prepare(fd_set& in, fd_set& out, net::Handle& max) { - util::poller::prepare(in, out, max, *m_interruptService, *m_servers, *m_transports); + util::poller::prepare(in, out, max, *itr_service_, *server_service_, *tpt_service_); } -void Irccd::sync(fd_set &in, fd_set &out) +void irccd::sync(fd_set& in, fd_set& out) { - if (!m_running) { + if (!running_) return; - } - util::poller::sync(in, out, *m_interruptService, *m_servers, *m_transports); + util::poller::sync(in, out, *itr_service_, *server_service_, *tpt_service_); - if (!m_running) { + if (!running_) return; - } /* * Make a copy because the events can add other events while we are * iterating it. Also lock because the timers may alter these events too. */ - std::vector<std::function<void (Irccd &)>> copy; + std::vector<std::function<void (irccd&)>> copy; { - std::lock_guard<mutex> lock(m_mutex); + std::lock_guard<std::mutex> lock(mutex_); - copy = move(m_events); - m_events.clear(); + copy = std::move(events_); + events_.clear(); } if (copy.size() > 0) - log::debug() << "irccd: dispatching " << copy.size() << " event" << (copy.size() > 1 ? "s" : "") << endl; + log::debug() << "irccd: dispatching " << copy.size() << " event" + << (copy.size() > 1 ? "s" : "") << std::endl; - for (auto &ev : copy) + for (auto& ev : copy) ev(*this); } -void Irccd::stop() +void irccd::stop() { - log::debug() << "irccd: requesting to stop now" << endl; + log::debug() << "irccd: requesting to stop now" << std::endl; - m_running = false; - m_interruptService->interrupt(); + running_ = false; + itr_service_->interrupt(); } } // !irccd
--- a/libirccd/irccd/irccd.hpp Fri Aug 11 13:45:42 2017 +0200 +++ b/libirccd/irccd/irccd.hpp Tue Sep 26 17:18:47 2017 +0200 @@ -38,52 +38,52 @@ */ namespace irccd { -class CommandService; -class InterruptService; -class PluginService; -class RuleService; -class ServerService; -class TransportService; +class command_service; +class interrupt_service; +class plugin_service; +class rule_service; +class server_service; +class transport_service; /** * \brief Irccd main instance. */ -class Irccd { +class irccd { private: // Main loop stuff. - std::atomic<bool> m_running{true}; - std::mutex m_mutex; - std::vector<std::function<void (Irccd &)>> m_events; + std::atomic<bool> running_{true}; + std::mutex mutex_; + std::vector<std::function<void (irccd&)>> events_; // Services. - std::shared_ptr<CommandService> m_commandService; - std::shared_ptr<InterruptService> m_interruptService; - std::shared_ptr<ServerService> m_servers; - std::shared_ptr<TransportService> m_transports; - std::shared_ptr<RuleService> m_ruleService; - std::shared_ptr<PluginService> m_plugins; + std::shared_ptr<command_service> command_service_; + std::shared_ptr<interrupt_service> itr_service_; + std::shared_ptr<server_service> server_service_; + std::shared_ptr<transport_service> tpt_service_; + std::shared_ptr<rule_service> rule_service_; + std::shared_ptr<plugin_service> plugin_service_; // Not copyable and not movable because services has references to irccd. - Irccd(const Irccd &) = delete; - Irccd(Irccd &&) = delete; + irccd(const irccd&) = delete; + irccd(irccd&&) = delete; - Irccd &operator=(const Irccd &) = delete; - Irccd &operator=(Irccd &&) = delete; + irccd& operator=(const irccd&) = delete; + irccd& operator=(irccd&&) = delete; public: /** * Prepare standard services. */ - IRCCD_EXPORT Irccd(); + irccd(); /** * Access the command service. * * \return the service */ - inline CommandService &commands() noexcept + inline command_service& commands() noexcept { - return *m_commandService; + return *command_service_; } /** @@ -91,9 +91,9 @@ * * \return the service */ - inline ServerService &servers() noexcept + inline server_service& servers() noexcept { - return *m_servers; + return *server_service_; } /** @@ -101,9 +101,9 @@ * * \return the service */ - inline TransportService &transports() noexcept + inline transport_service& transports() noexcept { - return *m_transports; + return *tpt_service_; } /** @@ -111,9 +111,9 @@ * * \return the service */ - inline RuleService &rules() noexcept + inline rule_service& rules() noexcept { - return *m_ruleService; + return *rule_service_; } /** @@ -121,9 +121,9 @@ * * \return the service */ - inline PluginService &plugins() noexcept + inline plugin_service& plugins() noexcept { - return *m_plugins; + return *plugin_service_; } /** @@ -133,7 +133,7 @@ * \param out the output set * \param max the maximum handle */ - IRCCD_EXPORT void prepare(fd_set &in, fd_set &out, net::Handle &max); + void prepare(fd_set& in, fd_set& out, net::Handle& max); /** * Synchronize the services. @@ -141,7 +141,7 @@ * \param in the input set * \param out the output set */ - IRCCD_EXPORT void sync(fd_set &in, fd_set &out); + void sync(fd_set& in, fd_set& out); /** * Add an event to the queue. This will immediately signals the event loop @@ -150,17 +150,17 @@ * \param ev the event * \note Thread-safe */ - IRCCD_EXPORT void post(std::function<void (Irccd &)> ev) noexcept; + void post(std::function<void (irccd&)> ev) noexcept; /** * Loop forever by calling prepare and sync indefinitely. */ - IRCCD_EXPORT void run(); + void run(); /** * Request to stop, usually from a signal. */ - IRCCD_EXPORT void stop(); + void stop(); }; } // !irccd
--- a/libirccd/irccd/plugin-dynlib.hpp Fri Aug 11 13:45:42 2017 +0200 +++ b/libirccd/irccd/plugin-dynlib.hpp Tue Sep 26 17:18:47 2017 +0200 @@ -81,8 +81,8 @@ OnWhois m_onWhois; // Configuration and formats. - PluginConfig m_config; - PluginFormats m_formats; + plugin_config m_config; + plugin_formats m_formats; public: /** @@ -97,107 +97,107 @@ /** * \copydoc Plugin::onCommand */ - IRCCD_EXPORT void onCommand(Irccd &irccd, const MessageEvent &event) override; + IRCCD_EXPORT void onCommand(irccd &irccd, const MessageEvent &event) override; /** * \copydoc Plugin::onConnect */ - IRCCD_EXPORT void onConnect(Irccd &irccd, const ConnectEvent &event) override; + IRCCD_EXPORT void onConnect(irccd &irccd, const ConnectEvent &event) override; /** * \copydoc Plugin::onChannelMode */ - IRCCD_EXPORT void onChannelMode(Irccd &irccd, const ChannelModeEvent &event) override; + IRCCD_EXPORT void onChannelMode(irccd &irccd, const ChannelModeEvent &event) override; /** * \copydoc Plugin::onChannelNotice */ - IRCCD_EXPORT void onChannelNotice(Irccd &irccd, const ChannelNoticeEvent &event) override; + IRCCD_EXPORT void onChannelNotice(irccd &irccd, const ChannelNoticeEvent &event) override; /** * \copydoc Plugin::onInvite */ - IRCCD_EXPORT void onInvite(Irccd &irccd, const InviteEvent &event) override; + IRCCD_EXPORT void onInvite(irccd &irccd, const InviteEvent &event) override; /** * \copydoc Plugin::onJoin */ - IRCCD_EXPORT void onJoin(Irccd &irccd, const JoinEvent &event) override; + IRCCD_EXPORT void onJoin(irccd &irccd, const JoinEvent &event) override; /** * \copydoc Plugin::onKick */ - IRCCD_EXPORT void onKick(Irccd &irccd, const KickEvent &event) override; + IRCCD_EXPORT void onKick(irccd &irccd, const KickEvent &event) override; /** * \copydoc Plugin::onLoad */ - IRCCD_EXPORT void onLoad(Irccd &irccd) override; + IRCCD_EXPORT void onLoad(irccd &irccd) override; /** * \copydoc Plugin::onMessage */ - IRCCD_EXPORT void onMessage(Irccd &irccd, const MessageEvent &event) override; + IRCCD_EXPORT void onMessage(irccd &irccd, const MessageEvent &event) override; /** * \copydoc Plugin::onMe */ - IRCCD_EXPORT void onMe(Irccd &irccd, const MeEvent &event) override; + IRCCD_EXPORT void onMe(irccd &irccd, const MeEvent &event) override; /** * \copydoc Plugin::onMode */ - IRCCD_EXPORT void onMode(Irccd &irccd, const ModeEvent &event) override; + IRCCD_EXPORT void onMode(irccd &irccd, const ModeEvent &event) override; /** * \copydoc Plugin::onNames */ - IRCCD_EXPORT void onNames(Irccd &irccd, const NamesEvent &event) override; + IRCCD_EXPORT void onNames(irccd &irccd, const NamesEvent &event) override; /** * \copydoc Plugin::onNick */ - IRCCD_EXPORT void onNick(Irccd &irccd, const NickEvent &event) override; + IRCCD_EXPORT void onNick(irccd &irccd, const NickEvent &event) override; /** * \copydoc Plugin::onNotice */ - IRCCD_EXPORT void onNotice(Irccd &irccd, const NoticeEvent &event) override; + IRCCD_EXPORT void onNotice(irccd &irccd, const NoticeEvent &event) override; /** * \copydoc Plugin::onPart */ - IRCCD_EXPORT void onPart(Irccd &irccd, const PartEvent &event) override; + IRCCD_EXPORT void onPart(irccd &irccd, const PartEvent &event) override; /** * \copydoc Plugin::onQuery */ - IRCCD_EXPORT void onQuery(Irccd &irccd, const QueryEvent &event) override; + IRCCD_EXPORT void onQuery(irccd &irccd, const QueryEvent &event) override; /** * \copydoc Plugin::onQueryCommand */ - IRCCD_EXPORT void onQueryCommand(Irccd &irccd, const QueryEvent &event) override; + IRCCD_EXPORT void onQueryCommand(irccd &irccd, const QueryEvent &event) override; /** * \copydoc Plugin::onReload */ - IRCCD_EXPORT void onReload(Irccd &irccd) override; + IRCCD_EXPORT void onReload(irccd &irccd) override; /** * \copydoc Plugin::onTopic */ - IRCCD_EXPORT void onTopic(Irccd &irccd, const TopicEvent &event) override; + IRCCD_EXPORT void onTopic(irccd &irccd, const TopicEvent &event) override; /** * \copydoc Plugin::onUnload */ - IRCCD_EXPORT void onUnload(Irccd &irccd) override; + IRCCD_EXPORT void onUnload(irccd &irccd) override; /** * \copydoc Plugin::onWhois */ - IRCCD_EXPORT void onWhois(Irccd &irccd, const WhoisEvent &event) override; + IRCCD_EXPORT void onWhois(irccd &irccd, const WhoisEvent &event) override; }; /**
--- a/libirccd/irccd/plugin.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/libirccd/irccd/plugin.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -29,14 +29,14 @@ } // !namespace -PluginLoader::PluginLoader(std::vector<std::string> directories, - std::vector<std::string> extensions) +plugin_loader::plugin_loader(std::vector<std::string> directories, + std::vector<std::string> extensions) : directories_(std::move(directories)) , extensions_(std::move(extensions)) { } -std::shared_ptr<Plugin> PluginLoader::find(const std::string& name) noexcept +std::shared_ptr<plugin> plugin_loader::find(const std::string& name) noexcept { if (extensions_.empty()) return nullptr; @@ -51,7 +51,7 @@ filenames.push_back(dir + "/" + name + ext); } - std::shared_ptr<Plugin> plugin; + std::shared_ptr<plugin> plugin; for (const auto& candidate : filenames) { boost::system::error_code ec;
--- a/libirccd/irccd/plugin.hpp Fri Aug 11 13:45:42 2017 +0200 +++ b/libirccd/irccd/plugin.hpp Tue Sep 26 17:18:47 2017 +0200 @@ -21,7 +21,7 @@ /** * \file plugin.hpp - * \brief Irccd plugins + * \brief irccd plugins */ /** @@ -40,22 +40,22 @@ namespace irccd { -class Irccd; +class irccd; /** * \brief Configuration map extract from config file. */ -using PluginConfig = std::unordered_map<std::string, std::string>; +using plugin_config = std::unordered_map<std::string, std::string>; /** * \brief Formats for plugins. */ -using PluginFormats = std::unordered_map<std::string, std::string>; +using plugin_formats = std::unordered_map<std::string, std::string>; /** * \brief Paths for plugins. */ -using PluginPaths = std::unordered_map<std::string, std::string>; +using plugin_paths = std::unordered_map<std::string, std::string>; /** * \ingroup plugins @@ -63,17 +63,17 @@ * * A plugin is identified by name and can be loaded and unloaded at runtime. */ -class Plugin : public std::enable_shared_from_this<Plugin> { +class plugin : public std::enable_shared_from_this<plugin> { private: // Plugin information - std::string m_name; - std::string m_path; + std::string name_; + std::string path_; // Metadata - std::string m_author{"unknown"}; - std::string m_license{"unknown"}; - std::string m_summary{"unknown"}; - std::string m_version{"unknown"}; + std::string author_{"unknown"}; + std::string license_{"unknown"}; + std::string summary_{"unknown"}; + std::string version_{"unknown"}; public: /** @@ -83,25 +83,25 @@ * \param path the fully resolved path to the plugin * \throws std::runtime_error on errors */ - inline Plugin(std::string name, std::string path) noexcept - : m_name(std::move(name)) - , m_path(std::move(path)) + inline plugin(std::string name, std::string path) noexcept + : name_(std::move(name)) + , path_(std::move(path)) { } /** * Temporary, close all timers. */ - virtual ~Plugin() = default; + virtual ~plugin() = default; /** * Get the plugin name. * * \return the plugin name */ - inline const std::string &name() const noexcept + inline const std::string& name() const noexcept { - return m_name; + return name_; } /** @@ -110,9 +110,9 @@ * \return the plugin path * \note some plugins may not exist on the disk */ - inline const std::string &path() const noexcept + inline const std::string& path() const noexcept { - return m_path; + return path_; } /** @@ -120,9 +120,9 @@ * * \return the author */ - inline const std::string &author() const noexcept + inline const std::string& author() const noexcept { - return m_author; + return author_; } /** @@ -130,9 +130,9 @@ * * \param author the author */ - inline void setAuthor(std::string author) noexcept + inline void set_author(std::string author) noexcept { - m_author = std::move(author); + author_ = std::move(author); } /** @@ -140,9 +140,9 @@ * * \return the license */ - inline const std::string &license() const noexcept + inline const std::string& license() const noexcept { - return m_license; + return license_; } /** @@ -150,9 +150,9 @@ * * \param license the license */ - inline void setLicense(std::string license) noexcept + inline void set_license(std::string license) noexcept { - m_license = std::move(license); + license_ = std::move(license); } /** @@ -160,9 +160,9 @@ * * \return the summary */ - inline const std::string &summary() const noexcept + inline const std::string& summary() const noexcept { - return m_summary; + return summary_; } /** @@ -170,9 +170,9 @@ * * \param summary the summary */ - inline void setSummary(std::string summary) noexcept + inline void set_summary(std::string summary) noexcept { - m_summary = std::move(summary); + summary_ = std::move(summary); } /** @@ -180,9 +180,9 @@ * * \return the version */ - inline const std::string &version() const noexcept + inline const std::string& version() const noexcept { - return m_version; + return version_; } /** @@ -190,9 +190,9 @@ * * \param version the version */ - inline void setVersion(std::string version) noexcept + inline void set_version(std::string version) noexcept { - m_version = std::move(version); + version_ = std::move(version); } /** @@ -200,7 +200,7 @@ * * \return the config */ - virtual PluginConfig config() + virtual plugin_config config() { return {}; } @@ -210,7 +210,7 @@ * * \param config the configuration */ - virtual void setConfig(PluginConfig config) + virtual void set_config(plugin_config config) { util::unused(config); } @@ -220,7 +220,7 @@ * * \return the format */ - virtual PluginFormats formats() + virtual plugin_formats formats() { return {}; } @@ -230,7 +230,7 @@ * * \param formats the formats */ - virtual void setFormats(PluginFormats formats) + virtual void set_formats(plugin_formats formats) { util::unused(formats); } @@ -240,7 +240,7 @@ * * \return the paths */ - virtual PluginPaths paths() + virtual plugin_paths paths() { return {}; } @@ -250,7 +250,7 @@ * * \param paths the paths */ - virtual void setPaths(PluginPaths paths) + virtual void set_paths(plugin_paths paths) { util::unused(paths); } @@ -263,7 +263,7 @@ * \param irccd the irccd instance * \param event the event */ - virtual void onCommand(Irccd &irccd, const MessageEvent &event) + virtual void on_command(irccd& irccd, const message_event& event) { util::unused(irccd, event); } @@ -274,7 +274,7 @@ * \param irccd the irccd instance * \param event the event */ - virtual void onConnect(Irccd &irccd, const ConnectEvent &event) + virtual void on_connect(irccd& irccd, const connect_event& event) { util::unused(irccd, event); } @@ -285,7 +285,7 @@ * \param irccd the irccd instance * \param event the event */ - virtual void onChannelMode(Irccd &irccd, const ChannelModeEvent &event) + virtual void on_channel_mode(irccd& irccd, const channel_mode_event& event) { util::unused(irccd, event); } @@ -296,7 +296,7 @@ * \param irccd the irccd instance * \param event the event */ - virtual void onChannelNotice(Irccd &irccd, const ChannelNoticeEvent &event) + virtual void on_channel_notice(irccd& irccd, const channel_notice_event& event) { util::unused(irccd, event); } @@ -307,7 +307,7 @@ * \param irccd the irccd instance * \param event the event */ - virtual void onInvite(Irccd &irccd, const InviteEvent &event) + virtual void on_invite(irccd& irccd, const invite_event& event) { util::unused(irccd, event); } @@ -318,7 +318,7 @@ * \param irccd the irccd instance * \param event the event */ - virtual void onJoin(Irccd &irccd, const JoinEvent &event) + virtual void on_join(irccd& irccd, const join_event& event) { util::unused(irccd, event); } @@ -329,7 +329,7 @@ * \param irccd the irccd instance * \param event the event */ - virtual void onKick(Irccd &irccd, const KickEvent &event) + virtual void on_kick(irccd& irccd, const kick_event& event) { util::unused(irccd, event); } @@ -339,7 +339,7 @@ * * \param irccd the irccd instance */ - virtual void onLoad(Irccd &irccd) + virtual void on_load(irccd& irccd) { util::unused(irccd); } @@ -350,7 +350,7 @@ * \param irccd the irccd instance * \param event the event */ - virtual void onMessage(Irccd &irccd, const MessageEvent &event) + virtual void on_message(irccd& irccd, const message_event& event) { util::unused(irccd, event); } @@ -361,7 +361,7 @@ * \param irccd the irccd instance * \param event the event */ - virtual void onMe(Irccd &irccd, const MeEvent &event) + virtual void on_me(irccd& irccd, const me_event& event) { util::unused(irccd, event); } @@ -372,7 +372,7 @@ * \param irccd the irccd instance * \param event the event */ - virtual void onMode(Irccd &irccd, const ModeEvent &event) + virtual void on_mode(irccd& irccd, const mode_event& event) { util::unused(irccd, event); } @@ -383,7 +383,7 @@ * \param irccd the irccd instance * \param event the event */ - virtual void onNames(Irccd &irccd, const NamesEvent &event) + virtual void on_names(irccd& irccd, const names_event& event) { util::unused(irccd, event); } @@ -394,7 +394,7 @@ * \param irccd the irccd instance * \param event the event */ - virtual void onNick(Irccd &irccd, const NickEvent &event) + virtual void on_nick(irccd& irccd, const nick_event& event) { util::unused(irccd, event); } @@ -405,7 +405,7 @@ * \param irccd the irccd instance * \param event the event */ - virtual void onNotice(Irccd &irccd, const NoticeEvent &event) + virtual void on_notice(irccd& irccd, const notice_event& event) { util::unused(irccd, event); } @@ -416,7 +416,7 @@ * \param irccd the irccd instance * \param event the event */ - virtual void onPart(Irccd &irccd, const PartEvent &event) + virtual void on_part(irccd& irccd, const part_event& event) { util::unused(irccd, event); } @@ -427,7 +427,7 @@ * \param irccd the irccd instance * \param event the event */ - virtual void onQuery(Irccd &irccd, const QueryEvent &event) + virtual void on_query(irccd& irccd, const query_event& event) { util::unused(irccd, event); } @@ -438,7 +438,7 @@ * \param irccd the irccd instance * \param event the event */ - virtual void onQueryCommand(Irccd &irccd, const QueryEvent &event) + virtual void on_query_command(irccd& irccd, const query_event& event) { util::unused(irccd, event); } @@ -448,7 +448,7 @@ * * \param irccd the irccd instance */ - virtual void onReload(Irccd &irccd) + virtual void on_reload(irccd& irccd) { util::unused(irccd); } @@ -459,7 +459,7 @@ * \param irccd the irccd instance * \param event the event */ - virtual void onTopic(Irccd &irccd, const TopicEvent &event) + virtual void on_topic(irccd& irccd, const topic_event& event) { util::unused(irccd, event); } @@ -469,7 +469,7 @@ * * \param irccd the irccd instance */ - virtual void onUnload(Irccd &irccd) + virtual void on_unload(irccd& irccd) { util::unused(irccd); } @@ -480,7 +480,7 @@ * \param irccd the irccd instance * \param event the event */ - virtual void onWhois(Irccd &irccd, const WhoisEvent &event) + virtual void on_whois(irccd& irccd, const whois_event& event) { util::unused(irccd, event); } @@ -489,16 +489,16 @@ /** * \brief Abstract interface for searching plugins. * - * This class is used to make loading of plugins extensible, the PluginService + * This class is used to make loading of plugins extensible, the plugin_service * knows some predefined plugins loaders and use them to search for available * plugins. * * This makes easier to implement new plugins or new ways of loading them. * - * \see DynlibPluginLoader - * \see JsPluginLoader + * \see dynlib_plugin_loader + * \see js_plugin_loader */ -class PluginLoader { +class plugin_loader { private: std::vector<std::string> directories_; std::vector<std::string> extensions_; @@ -516,8 +516,8 @@ * \param directories directories to search * \param extensions the list of extensions supported */ - PluginLoader(std::vector<std::string> directories = {}, - std::vector<std::string> extensions = {}); + plugin_loader(std::vector<std::string> directories = {}, + std::vector<std::string> extensions = {}); /** * Set directories where to search plugins. @@ -547,8 +547,8 @@ * * \param file the file */ - virtual std::shared_ptr<Plugin> open(const std::string &id, - const std::string &file) noexcept = 0; + virtual std::shared_ptr<plugin> open(const std::string& id, + const std::string& file) noexcept = 0; /** * Search for a plugin named by this id. @@ -556,7 +556,7 @@ * \param id the plugin id * \return the plugin */ - virtual std::shared_ptr<Plugin> find(const std::string &id) noexcept; + virtual std::shared_ptr<plugin> find(const std::string& id) noexcept; }; } // !irccd
--- a/libirccd/irccd/rule.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/libirccd/irccd/rule.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -18,111 +18,42 @@ #include <algorithm> #include <cctype> -#include <stdexcept> -#include "logger.hpp" #include "rule.hpp" -#include "util.hpp" - -using namespace std; - -namespace { - -const std::unordered_set<std::string> validEvents{ - "onChannelMode" - "onChannelNotice", - "onCommand", - "onConnect", - "onInvite", - "onJoin", - "onKick", - "onMessage", - "onMode", - "onNames", - "onNick", - "onNotice", - "onPart", - "onQuery", - "onQueryCommand", - "onTopic", - "onWhois" -}; - -} // !namespace namespace irccd { -bool Rule::matchMap(const RuleSet &map, const std::string &value) const noexcept +bool rule::match_set(const set& set, const std::string& value) const noexcept { - return value.empty() || map.empty() || map.count(value) == 1; + return value.empty() || set.empty() || set.count(value) == 1; } -Rule::Rule(RuleSet servers, RuleSet channels, RuleSet origins, RuleSet plugins, RuleSet events, RuleAction action) - : m_servers(std::move(servers)) - , m_channels(std::move(channels)) - , m_origins(std::move(origins)) - , m_plugins(std::move(plugins)) - , m_events(std::move(events)) - , m_action(action) +rule::rule(set servers, set channels, set origins, set plugins, set events, action_type action) + : servers_(std::move(servers)) + , channels_(std::move(channels)) + , origins_(std::move(origins)) + , plugins_(std::move(plugins)) + , events_(std::move(events)) + , action_(action) { - for (const std::string &n : m_events) - if (validEvents.count(n) == 0) - throw std::invalid_argument(n + " is not a valid event name"); } -bool Rule::match(const std::string &server, - const std::string &channel, - const std::string &nick, - const std::string &plugin, - const std::string &event) const noexcept +bool rule::match(const std::string& server, + const std::string& channel, + const std::string& nick, + const std::string& plugin, + const std::string& event) const noexcept { auto tolower = [] (auto str) { std::transform(str.begin(), str.end(), str.begin(), ::tolower); return str; }; - return matchMap(m_servers, tolower(server)) && - matchMap(m_channels, tolower(channel)) && - matchMap(m_origins, tolower(nick)) && - matchMap(m_plugins, tolower(plugin)) && - matchMap(m_events, event); -} - -RuleAction Rule::action() const noexcept -{ - return m_action; -} - -void Rule::setAction(RuleAction action) noexcept -{ - assert(action == RuleAction::Accept || action == RuleAction::Drop); - - m_action = action; -} - -const RuleSet &Rule::servers() const noexcept -{ - return m_servers; -} - -const RuleSet &Rule::channels() const noexcept -{ - return m_channels; -} - -const RuleSet &Rule::origins() const noexcept -{ - return m_origins; -} - -const RuleSet &Rule::plugins() const noexcept -{ - return m_plugins; -} - -const RuleSet &Rule::events() const noexcept -{ - return m_events; + return match_set(servers_, tolower(server)) && + match_set(channels_, tolower(channel)) && + match_set(origins_, tolower(nick)) && + match_set(plugins_, tolower(plugin)) && + match_set(events_, event); } } // !irccd
--- a/libirccd/irccd/rule.hpp Fri Aug 11 13:45:42 2017 +0200 +++ b/libirccd/irccd/rule.hpp Tue Sep 26 17:18:47 2017 +0200 @@ -24,47 +24,45 @@ * \brief Rule description */ -#include <sstream> +#include <cassert> #include <string> #include <unordered_set> -#include <utility> -#include <vector> #include "sysconfig.hpp" namespace irccd { /** - * List of criterias. - */ -using RuleSet = std::unordered_set<std::string>; - -/** - * \enum RuleAction - * \brief Rule action - */ -enum class RuleAction { - Accept, //!< The event is accepted (default) - Drop //!< The event is dropped -}; - -/** * \brief Manage rule to activate or deactive events. */ -class Rule { +class rule { +public: + /** + * List of criterias. + */ + using set = std::unordered_set<std::string>; + + /** + * \brief Rule action type. + */ + enum class action_type { + accept, //!< The event is accepted (default) + drop //!< The event is dropped + }; + private: - RuleSet m_servers; - RuleSet m_channels; - RuleSet m_origins; - RuleSet m_plugins; - RuleSet m_events; - RuleAction m_action{RuleAction::Accept}; + set servers_; + set channels_; + set origins_; + set plugins_; + set events_; + action_type action_{action_type::accept}; /* - * Check if a map contains the value and return true if it is - * or return true if value is empty (which means applicable). + * Check if a set contains the value and return true if it is or return + * true if value is empty (which means applicable). */ - bool matchMap(const RuleSet &map, const std::string &value) const noexcept; + bool match_set(const set&, const std::string&) const noexcept; public: /** @@ -78,12 +76,12 @@ * \param action the rule action * \throw std::invalid_argument if events are invalid */ - IRCCD_EXPORT Rule(RuleSet servers = RuleSet{}, - RuleSet channels = RuleSet{}, - RuleSet nicknames = RuleSet{}, - RuleSet plugins = RuleSet{}, - RuleSet events = RuleSet{}, - RuleAction action = RuleAction::Accept); + rule(set servers = {}, + set channels = {}, + set nicknames = {}, + set plugins = {}, + set events = {}, + action_type action = action_type::accept); /** * Check if that rule apply for the given criterias. @@ -95,41 +93,52 @@ * \param event the event * \return true if match */ - IRCCD_EXPORT bool match(const std::string &server, - const std::string &channel, - const std::string &nick, - const std::string &plugin, - const std::string &event) const noexcept; + bool match(const std::string& server, + const std::string& channel, + const std::string& nick, + const std::string& plugin, + const std::string& event) const noexcept; /** * Get the action. * * \return the action */ - IRCCD_EXPORT RuleAction action() const noexcept; + inline action_type action() const noexcept + { + return action_; + } /** * Set the action. * * \pre action must be valid */ - IRCCD_EXPORT void setAction(RuleAction action) noexcept; + inline void set_action(action_type action) noexcept + { + assert(action == action_type::accept || action == action_type::drop); + + action_ = action; + } /** * Get the servers. * * \return the servers */ - IRCCD_EXPORT const RuleSet &servers() const noexcept; + inline const set& servers() const noexcept + { + return servers_; + } /** * Overloaded function. * * \return the servers */ - inline RuleSet &servers() noexcept + inline set& servers() noexcept { - return m_servers; + return servers_; } /** @@ -137,17 +146,19 @@ * * \return the channels */ - IRCCD_EXPORT const RuleSet &channels() const noexcept; - + inline const set& channels() const noexcept + { + return channels_; + } /** * Overloaded function. * * \return the channels */ - inline RuleSet &channels() noexcept + inline set& channels() noexcept { - return m_channels; + return channels_; } /** @@ -155,24 +166,29 @@ * * \return the origins */ - IRCCD_EXPORT const RuleSet &origins() const noexcept; + inline const set& origins() const noexcept + { + return origins_; + } /** * Get the plugins. * * \return the plugins */ - IRCCD_EXPORT const RuleSet &plugins() const noexcept; - + inline const set& plugins() const noexcept + { + return plugins_; + } /** * Overloaded function. * * \return the plugins */ - inline RuleSet &plugins() noexcept + inline set& plugins() noexcept { - return m_plugins; + return plugins_; } /** @@ -180,17 +196,19 @@ * * \return the events */ - IRCCD_EXPORT const RuleSet &events() const noexcept; - + inline const set& events() const noexcept + { + return events_; + } /** * Overloaded function. * * \return the events */ - inline RuleSet& events() noexcept + inline set& events() noexcept { - return m_events; + return events_; } };
--- a/libirccd/irccd/server.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/libirccd/irccd/server.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -44,86 +44,86 @@ namespace irccd { /* - * Server::Session declaration. + * server::session declaration. * ------------------------------------------------------------------ */ -class Server::Session { +class server::session { public: - std::unique_ptr<irc_session_t, void (*)(irc_session_t *)> m_handle{nullptr, nullptr}; + std::unique_ptr<irc_session_t, void (*)(irc_session_t *)> handle_{nullptr, nullptr}; - inline operator const irc_session_t *() const noexcept + inline operator const irc_session_t*() const noexcept { - return m_handle.get(); + return handle_.get(); } - inline operator irc_session_t *() noexcept + inline operator irc_session_t*() noexcept { - return m_handle.get(); + return handle_.get(); } - inline bool isConnected() const noexcept + inline bool is_connected() const noexcept { - return irc_is_connected(m_handle.get()); + return irc_is_connected(handle_.get()); } }; /* - * Server::State declaration. + * server::state declaration. * ------------------------------------------------------------------ */ -class Server::State { +class server::state { public: - State() = default; - virtual ~State() = default; - virtual void prepare(Server &, fd_set &, fd_set &, net::Handle &) = 0; + state() = default; + virtual ~state() = default; + virtual void prepare(server&, fd_set&, fd_set&, net::Handle&) = 0; virtual std::string ident() const = 0; }; /* - * Server::DisconnectedState declaration. + * server::disconnected_state declaration. * ------------------------------------------------------------------ */ -class Server::DisconnectedState : public Server::State { +class server::disconnected_state : public server::state { private: - ElapsedTimer m_timer; + ElapsedTimer timer_; public: - void prepare(Server &, fd_set &, fd_set &, net::Handle &) override; + void prepare(server&, fd_set&, fd_set&, net::Handle&) override; std::string ident() const override; }; /* - * Server::ConnectingState declaration. + * server::connecting_state declaration. * ------------------------------------------------------------------ */ -class Server::ConnectingState : public State { +class server::connecting_state : public state { private: enum { - Disconnected, - Connecting - } m_state{Disconnected}; + disconnected, + connecting + } state_{disconnected}; - ElapsedTimer m_timer; + ElapsedTimer timer_; - bool connect(Server &server); + bool connect(server& server); public: - void prepare(Server &, fd_set &, fd_set &, net::Handle &) override; + void prepare(server&, fd_set&, fd_set&, net::Handle&) override; std::string ident() const override; }; /* - * Server::ConnectedState declaration. + * server::connected_state declaration. * ------------------------------------------------------------------ */ -class Server::ConnectedState : public State { +class server::connected_state : public state { public: - void prepare(Server &, fd_set &, fd_set &, net::Handle &) override; + void prepare(server&, fd_set&, fd_set&, net::Handle&) override; std::string ident() const override; }; @@ -135,24 +135,24 @@ * * Make sure to build a C++ string with a not-null C string. */ -inline std::string strify(const char *s) +inline std::string strify(const char* s) { return (s == nullptr) ? "" : std::string(s); } /* - * cleanPrefix + * clean_prefix * ------------------------------------------------------------------ * * Remove the user prefix only if it is present in the mode table, for example * removes @ from @irccd if and only if @ is a character mode (e.g. operator). */ -std::string cleanPrefix(const std::map<ChannelMode, char> &modes, std::string nickname) +std::string clean_prefix(const std::map<channel_mode, char>& modes, std::string nickname) { if (nickname.length() == 0) return nickname; - for (const auto &pair : modes) + for (const auto& pair : modes) if (nickname[0] == pair.second) nickname.erase(0, 1); @@ -160,32 +160,33 @@ } /* - * extractPrefixes + * extract_prefixes * ------------------------------------------------------------------ * * Read modes from the IRC event numeric. */ -std::map<ChannelMode, char> extractPrefixes(const std::string &line) +std::map<channel_mode, char> extract_prefixes(const std::string& line) { + // FIXME: what if line has different size? std::pair<char, char> table[16]; std::string buf = line.substr(7); - std::map<ChannelMode, char> modes; + std::map<channel_mode, char> modes; for (int i = 0; i < 16; ++i) table[i] = std::make_pair(-1, -1); int j = 0; - bool readModes = true; + bool read_modes = true; for (size_t i = 0; i < buf.size(); ++i) { if (buf[i] == '(') continue; if (buf[i] == ')') { j = 0; - readModes = false; + read_modes = false; continue; } - if (readModes) + if (read_modes) table[j++].first = buf[i]; else table[j++].second = buf[i]; @@ -193,7 +194,7 @@ // Put these as a map of mode to prefix. for (int i = 0; i < 16; ++i) { - auto key = static_cast<ChannelMode>(table[i].first); + auto key = static_cast<channel_mode>(table[i].first); auto value = table[i].second; modes.emplace(key, value); @@ -204,57 +205,68 @@ } // !namespace -void Server::removeJoinedChannel(const std::string &channel) +void server::remove_joined_channel(const std::string& channel) { - m_jchannels.erase(std::remove(m_jchannels.begin(), m_jchannels.end(), channel), m_jchannels.end()); + jchannels_.erase(std::remove(jchannels_.begin(), jchannels_.end(), channel), jchannels_.end()); } -void Server::handleConnect(const char *, const char **) noexcept +void server::handle_connect(const char*, const char**) noexcept { // Reset the number of tried reconnection. - m_recocur = 1; + recocur_ = 1; // Reset the timer. - m_timer.reset(); + timer_.reset(); // Reset joined channels. - m_jchannels.clear(); + jchannels_.clear(); // Don't forget to change state and notify. - next(std::make_unique<ConnectedState>()); - onConnect(ConnectEvent{shared_from_this()}); + next(std::make_unique<connected_state>()); + on_connect(connect_event{shared_from_this()}); // Auto join listed channels. - for (const auto &channel : m_rchannels) { - log::info() << "server " << m_name << ": auto joining " << channel.name << std::endl; + for (const auto& channel : rchannels_) { + log::info() << "server " << name_ << ": auto joining " << channel.name << std::endl; join(channel.name, channel.password); } } -void Server::handleChannel(const char *orig, const char **params) noexcept +void server::handle_channel(const char* orig, const char** params) noexcept { - onMessage(MessageEvent{shared_from_this(), strify(orig), strify(params[0]), strify(params[1])}); + on_message({shared_from_this(), strify(orig), strify(params[0]), strify(params[1])}); } -void Server::handleChannelMode(const char *orig, const char **params) noexcept +void server::handle_channel_mode(const char* orig, const char** params) noexcept { - onChannelMode(ChannelModeEvent{shared_from_this(), strify(orig), strify(params[0]), strify(params[1]), strify(params[2])}); + on_channel_mode({ + shared_from_this(), + strify(orig), + strify(params[0]), + strify(params[1]), + strify(params[2]) + }); } -void Server::handleChannelNotice(const char *orig, const char **params) noexcept +void server::handle_channel_notice(const char* orig, const char** params) noexcept { - onChannelNotice(ChannelNoticeEvent{shared_from_this(), strify(orig), strify(params[0]), strify(params[1])}); + on_channel_notice({ + shared_from_this(), + strify(orig), + strify(params[0]), + strify(params[1]) + }); } -void Server::handleCtcpAction(const char *orig, const char **params) noexcept +void server::handle_ctcp_action(const char* orig, const char** params) noexcept { - onMe(MeEvent{shared_from_this(), strify(orig), strify(params[0]), strify(params[1])}); + on_me({shared_from_this(), strify(orig), strify(params[0]), strify(params[1])}); } -void Server::handleInvite(const char *orig, const char **params) noexcept +void server::handle_invite(const char* orig, const char** params) noexcept { // If joininvite is set, join the channel. - if ((m_flags & JoinInvite) && isSelf(strify(params[0]))) + if ((flags_ & join_invite) && is_self(strify(params[0]))) join(strify(params[1])); /* @@ -262,55 +274,61 @@ * quit uncommon to need it so it is passed as the last argument to be * optional in the plugin. */ - onInvite(InviteEvent{shared_from_this(), strify(orig), strify(params[1]), strify(params[0])}); + on_invite({shared_from_this(), strify(orig), strify(params[1]), strify(params[0])}); } -void Server::handleJoin(const char *orig, const char **params) noexcept +void server::handle_join(const char* orig, const char** params) noexcept { - if (isSelf(strify(orig))) - m_jchannels.push_back(strify(params[0])); + if (is_self(strify(orig))) + jchannels_.push_back(strify(params[0])); - onJoin(JoinEvent{shared_from_this(), strify(orig), strify(params[0])}); + on_join({shared_from_this(), strify(orig), strify(params[0])}); } -void Server::handleKick(const char *orig, const char **params) noexcept +void server::handle_kick(const char* orig, const char** params) noexcept { - if (isSelf(strify(params[1]))) { + if (is_self(strify(params[1]))) { // Remove the channel from the joined list. - removeJoinedChannel(strify(params[0])); + remove_joined_channel(strify(params[0])); // Rejoin the channel if the option has been set and I was kicked. - if (m_flags & AutoRejoin) + if (flags_ & auto_rejoin) join(strify(params[0])); } - onKick(KickEvent{shared_from_this(), strify(orig), strify(params[0]), strify(params[1]), strify(params[2])}); -} - -void Server::handleMode(const char *orig, const char **params) noexcept -{ - onMode(ModeEvent{shared_from_this(), strify(orig), strify(params[1])}); + on_kick({ + shared_from_this(), + strify(orig), + strify(params[0]), + strify(params[1]), + strify(params[2]) + }); } -void Server::handleNick(const char *orig, const char **params) noexcept +void server::handle_mode(const char* orig, const char** params) noexcept +{ + on_mode({shared_from_this(), strify(orig), strify(params[1])}); +} + +void server::handle_nick(const char* orig, const char** params) noexcept { // Update our nickname. - if (isSelf(strify(orig))) - m_nickname = strify(params[0]); + if (is_self(strify(orig))) + nickname_ = strify(params[0]); - onNick(NickEvent{shared_from_this(), strify(orig), strify(params[0])}); + on_nick({shared_from_this(), strify(orig), strify(params[0])}); } -void Server::handleNotice(const char *orig, const char **params) noexcept +void server::handle_notice(const char* orig, const char** params) noexcept { /* * Like handleInvite, the notice provides the target nickname, we discard * it. */ - onNotice(NoticeEvent{shared_from_this(), strify(orig), strify(params[1])}); + on_notice({shared_from_this(), strify(orig), strify(params[1])}); } -void Server::handleNumeric(unsigned int event, const char **params, unsigned int c) noexcept +void server::handle_numeric(unsigned int event, const char** params, unsigned int c) noexcept { if (event == LIBIRC_RFC_RPL_NAMREPLY) { /* @@ -327,11 +345,11 @@ if (c < 4 || params[2] == nullptr || params[3] == nullptr) return; - std::vector<std::string> users = util::split(params[3], " \t"); + auto users = util::split(params[3], " \t"); // The listing may add some prefixes, remove them if needed. - for (std::string u : users) - m_namesMap[params[2]].insert(cleanPrefix(m_modes, u)); + for (auto u : users) + names_map_[params[2]].insert(clean_prefix(modes_, u)); } else if (event == LIBIRC_RFC_RPL_ENDOFNAMES) { /* * Called when end of name listing has finished on a channel. @@ -343,12 +361,16 @@ if (c < 3 || params[1] == nullptr) return; - auto it = m_namesMap.find(params[1]); - if (it != m_namesMap.end()) { - onNames(NamesEvent{shared_from_this(), params[1], std::vector<std::string>(it->second.begin(), it->second.end())}); + auto it = names_map_.find(params[1]); + if (it != names_map_.end()) { + on_names({ + shared_from_this(), + params[1], + std::vector<std::string>(it->second.begin(), it->second.end()) + }); // Don't forget to remove the list. - m_namesMap.erase(it); + names_map_.erase(it); } } else if (event == LIBIRC_RFC_RPL_WHOISUSER) { /* @@ -364,14 +386,14 @@ if (c < 6 || !params[1] || !params[2] || !params[3] || !params[5]) return; - Whois info; + class whois info; info.nick = strify(params[1]); info.user = strify(params[2]); info.host = strify(params[3]); info.realname = strify(params[5]); - m_whoisMap.emplace(info.nick, info); + whois_map_.emplace(info.nick, info); } else if (event == LIBIRC_RFC_RPL_WHOISCHANNELS) { /* * Called when we have received channels for one user. @@ -383,13 +405,13 @@ if (c < 3 || !params[1] || !params[2]) return; - auto it = m_whoisMap.find(params[1]); - if (it != m_whoisMap.end()) { - std::vector<std::string> channels = util::split(params[2], " \t"); + auto it = whois_map_.find(params[1]); + if (it != whois_map_.end()) { + auto channels = util::split(params[2], " \t"); // Clean their prefixes. for (auto &s : channels) - s = cleanPrefix(m_modes, s); + s = clean_prefix(modes_, s); it->second.channels = std::move(channels); } @@ -401,12 +423,12 @@ * params[1] == nickname * params[2] == End of WHOIS list */ - auto it = m_whoisMap.find(params[1]); - if (it != m_whoisMap.end()) { - onWhois(WhoisEvent{shared_from_this(), it->second}); + auto it = whois_map_.find(params[1]); + if (it != whois_map_.end()) { + on_whois({shared_from_this(), it->second}); // Don't forget to remove. - m_whoisMap.erase(it); + whois_map_.erase(it); } } else if (event == /* RPL_BOUNCE */ 5) { /* @@ -414,80 +436,80 @@ */ for (unsigned int i = 0; i < c; ++i) { if (strncmp(params[i], "PREFIX", 6) == 0) { - m_modes = extractPrefixes(params[i]); + modes_ = extract_prefixes(params[i]); break; } } } } -void Server::handlePart(const char *orig, const char **params) noexcept +void server::handle_part(const char* orig, const char** params) noexcept { // Remove the channel from the joined list if I left a channel. - if (isSelf(strify(orig))) - removeJoinedChannel(strify(params[0])); + if (is_self(strify(orig))) + remove_joined_channel(strify(params[0])); - onPart(PartEvent{shared_from_this(), strify(orig), strify(params[0]), strify(params[1])}); + on_part({shared_from_this(), strify(orig), strify(params[0]), strify(params[1])}); } -void Server::handlePing(const char *, const char **) noexcept +void server::handle_ping(const char*, const char**) noexcept { // Reset the timer to detect disconnection. - m_timer.reset(); + timer_.reset(); } -void Server::handleQuery(const char *orig, const char **params) noexcept +void server::handle_query(const char* orig, const char** params) noexcept { - onQuery(QueryEvent{shared_from_this(), strify(orig), strify(params[1])}); + on_query({shared_from_this(), strify(orig), strify(params[1])}); } -void Server::handleTopic(const char *orig, const char **params) noexcept +void server::handle_topic(const char* orig, const char** params) noexcept { - onTopic(TopicEvent{shared_from_this(), strify(orig), strify(params[0]), strify(params[1])}); + on_topic({shared_from_this(), strify(orig), strify(params[0]), strify(params[1])}); } -std::shared_ptr<Server> Server::fromJson(const nlohmann::json &object) +std::shared_ptr<server> server::from_json(const nlohmann::json& object) { - auto server = std::make_shared<Server>(util::json::requireIdentifier(object, "name")); + auto sv = std::make_shared<server>(util::json::require_identifier(object, "name")); - server->setHost(util::json::requireString(object, "host")); - server->setPassword(util::json::getString(object, "password")); - server->setNickname(util::json::getString(object, "nickname", server->nickname())); - server->setRealname(util::json::getString(object, "realname", server->realname())); - server->setUsername(util::json::getString(object, "username", server->username())); - server->setCtcpVersion(util::json::getString(object, "ctcpVersion", server->ctcpVersion())); - server->setCommandCharacter(util::json::getString(object, "commandChar", server->commandCharacter())); + sv->set_host(util::json::require_string(object, "host")); + sv->set_password(util::json::get_string(object, "password")); + sv->set_nickname(util::json::get_string(object, "nickname", sv->nickname())); + sv->set_realname(util::json::get_string(object, "realname", sv->realname())); + sv->set_username(util::json::get_string(object, "username", sv->username())); + sv->set_ctcp_version(util::json::get_string(object, "ctcpVersion", sv->ctcp_version())); + sv->set_command_char(util::json::get_string(object, "commandChar", sv->command_char())); if (object.find("port") != object.end()) - server->setPort(util::json::getUintRange<std::uint16_t>(object, "port")); - if (util::json::getBool(object, "ipv6")) - server->setFlags(server->flags() | Server::Ipv6); - if (util::json::getBool(object, "ssl")) - server->setFlags(server->flags() | Server::Ssl); - if (util::json::getBool(object, "sslVerify")) - server->setFlags(server->flags() | Server::SslVerify); - if (util::json::getBool(object, "autoRejoin")) - server->setFlags(server->flags() | Server::AutoRejoin); - if (util::json::getBool(object, "joinInvite")) - server->setFlags(server->flags() | Server::JoinInvite); + sv->set_port(util::json::get_uint_range<std::uint16_t>(object, "port")); + if (util::json::get_bool(object, "ipv6")) + sv->set_flags(sv->flags() | server::ipv6); + if (util::json::get_bool(object, "ssl")) + sv->set_flags(sv->flags() | server::ssl); + if (util::json::get_bool(object, "sslVerify")) + sv->set_flags(sv->flags() | server::ssl_verify); + if (util::json::get_bool(object, "autoRejoin")) + sv->set_flags(sv->flags() | server::auto_rejoin); + if (util::json::get_bool(object, "joinInvite")) + sv->set_flags(sv->flags() | server::join_invite); - return server; + return sv; } -Channel Server::splitChannel(const std::string &value) +channel server::split_channel(const std::string& value) { auto pos = value.find(':'); if (pos != std::string::npos) - return { value.substr(0, pos), value.substr(pos + 1) }; + return {value.substr(0, pos), value.substr(pos + 1)}; - return { value, "" }; + return {value, ""}; } -Server::Server(std::string name) - : m_name(std::move(name)) - , m_session(std::make_unique<Session>()) - , m_state(std::make_unique<ConnectingState>()) +server::server(std::string name) + : name_(std::move(name)) + , session_(std::make_unique<session>()) + , state_(std::make_unique<connecting_state>()) { irc_callbacks_t callbacks; @@ -503,126 +525,126 @@ * * While doing this, discard useless arguments. */ - callbacks.event_channel = [] (irc_session_t *session, const char *, const char *orig, const char **params, unsigned) { - static_cast<Server *>(irc_get_ctx(session))->handleChannel(orig, params); + callbacks.event_channel = [] (auto session, auto, auto orig, auto params, auto) { + static_cast<server*>(irc_get_ctx(session))->handle_channel(orig, params); }; - callbacks.event_channel_notice = [] (irc_session_t *session, const char *, const char *orig, const char **params, unsigned) { - static_cast<Server *>(irc_get_ctx(session))->handleChannelNotice(orig, params); + callbacks.event_channel_notice = [] (auto session, auto, auto orig, auto params, auto) { + static_cast<server*>(irc_get_ctx(session))->handle_channel_notice(orig, params); }; - callbacks.event_connect = [] (irc_session_t *session, const char *, const char *orig, const char **params, unsigned) { - static_cast<Server *>(irc_get_ctx(session))->handleConnect(orig, params); + callbacks.event_connect = [] (auto session, auto, auto orig, auto params, auto) { + static_cast<server*>(irc_get_ctx(session))->handle_connect(orig, params); }; - callbacks.event_ctcp_action = [] (irc_session_t *session, const char *, const char *orig, const char **params, unsigned) { - static_cast<Server *>(irc_get_ctx(session))->handleCtcpAction(orig, params); + callbacks.event_ctcp_action = [] (auto session, auto, auto orig, auto params, auto) { + static_cast<server*>(irc_get_ctx(session))->handle_ctcp_action(orig, params); }; - callbacks.event_invite = [] (irc_session_t *session, const char *, const char *orig, const char **params, unsigned) { - static_cast<Server *>(irc_get_ctx(session))->handleInvite(orig, params); + callbacks.event_invite = [] (auto session, auto, auto orig, auto params, auto) { + static_cast<server*>(irc_get_ctx(session))->handle_invite(orig, params); }; - callbacks.event_join = [] (irc_session_t *session, const char *, const char *orig, const char **params, unsigned) { - static_cast<Server *>(irc_get_ctx(session))->handleJoin(orig, params); + callbacks.event_join = [] (auto session, auto, auto orig, auto params, auto) { + static_cast<server*>(irc_get_ctx(session))->handle_join(orig, params); }; - callbacks.event_kick = [] (irc_session_t *session, const char *, const char *orig, const char **params, unsigned) { - static_cast<Server *>(irc_get_ctx(session))->handleKick(orig, params); + callbacks.event_kick = [] (auto session, auto, auto orig, auto params, auto) { + static_cast<server*>(irc_get_ctx(session))->handle_kick(orig, params); }; - callbacks.event_mode = [] (irc_session_t *session, const char *, const char *orig, const char **params, unsigned) { - static_cast<Server *>(irc_get_ctx(session))->handleChannelMode(orig, params); + callbacks.event_mode = [] (auto session, auto, auto orig, auto params, auto) { + static_cast<server*>(irc_get_ctx(session))->handle_channel_mode(orig, params); }; - callbacks.event_nick = [] (irc_session_t *session, const char *, const char *orig, const char **params, unsigned) { - static_cast<Server *>(irc_get_ctx(session))->handleNick(orig, params); + callbacks.event_nick = [] (auto session, auto, auto orig, auto params, auto) { + static_cast<server*>(irc_get_ctx(session))->handle_nick(orig, params); }; - callbacks.event_notice = [] (irc_session_t *session, const char *, const char *orig, const char **params, unsigned) { - static_cast<Server *>(irc_get_ctx(session))->handleNotice(orig, params); + callbacks.event_notice = [] (auto session, auto, auto orig, auto params, auto) { + static_cast<server*>(irc_get_ctx(session))->handle_notice(orig, params); }; - callbacks.event_numeric = [] (irc_session_t *session, unsigned int event, const char *, const char **params, unsigned int count) { - static_cast<Server *>(irc_get_ctx(session))->handleNumeric(event, params, count); + callbacks.event_numeric = [] (auto session, auto event, auto, auto params, auto count) { + static_cast<server*>(irc_get_ctx(session))->handle_numeric(event, params, count); }; - callbacks.event_part = [] (irc_session_t *session, const char *, const char *orig, const char **params, unsigned) { - static_cast<Server *>(irc_get_ctx(session))->handlePart(orig, params); + callbacks.event_part = [] (auto session, auto, auto orig, auto params, auto) { + static_cast<server*>(irc_get_ctx(session))->handle_part(orig, params); }; - callbacks.event_ping = [] (irc_session_t *session, const char *, const char *orig, const char **params, unsigned) { - static_cast<Server *>(irc_get_ctx(session))->handlePing(orig, params); + callbacks.event_ping = [] (auto session, auto, auto orig, auto params, auto) { + static_cast<server*>(irc_get_ctx(session))->handle_ping(orig, params); }; - callbacks.event_privmsg = [] (irc_session_t *session, const char *, const char *orig, const char **params, unsigned) { - static_cast<Server *>(irc_get_ctx(session))->handleQuery(orig, params); + callbacks.event_privmsg = [] (auto session, auto, auto orig, auto params, auto) { + static_cast<server*>(irc_get_ctx(session))->handle_query(orig, params); }; - callbacks.event_topic = [] (irc_session_t *session, const char *, const char *orig, const char **params, unsigned) { - static_cast<Server *>(irc_get_ctx(session))->handleTopic(orig, params); + callbacks.event_topic = [] (auto session, auto, auto orig, auto params, auto) { + static_cast<server*>(irc_get_ctx(session))->handle_topic(orig, params); }; - callbacks.event_umode = [] (irc_session_t *session, const char *, const char *orig, const char **params, unsigned) { - static_cast<Server *>(irc_get_ctx(session))->handleMode(orig, params); + callbacks.event_umode = [] (auto session, auto, auto orig, auto params, auto) { + static_cast<server*>(irc_get_ctx(session))->handle_mode(orig, params); }; - m_session->m_handle = {irc_create_session(&callbacks), irc_destroy_session}; + session_->handle_ = {irc_create_session(&callbacks), irc_destroy_session}; // Save this to the session. - irc_set_ctx(*m_session, this); - irc_set_ctcp_version(*m_session, m_ctcpversion.c_str()); + irc_set_ctx(*session_, this); + irc_set_ctcp_version(*session_, ctcpversion_.c_str()); } -Server::~Server() +server::~server() { - irc_disconnect(*m_session); + irc_disconnect(*session_); } -void Server::setNickname(std::string nickname) +void server::set_nickname(std::string nickname) { - if (m_session->isConnected()) - m_queue.push([=] () { - return irc_cmd_nick(*m_session, nickname.c_str()) == 0; + if (session_->is_connected()) + queue_.push([=] () { + return irc_cmd_nick(*session_, nickname.c_str()) == 0; }); else - m_nickname = std::move(nickname); + nickname_ = std::move(nickname); } -void Server::setCtcpVersion(std::string ctcpversion) +void server::set_ctcp_version(std::string ctcpversion) { - m_ctcpversion = std::move(ctcpversion); - irc_set_ctcp_version(*m_session, m_ctcpversion.c_str()); + ctcpversion_ = std::move(ctcpversion); + irc_set_ctcp_version(*session_, ctcpversion_.c_str()); } -void Server::next(std::unique_ptr<State> state) noexcept +void server::next(std::unique_ptr<state> state) noexcept { - m_stateNext = std::move(state); + state_next_ = std::move(state); } -std::string Server::status() const noexcept +std::string server::status() const noexcept { - return !m_state ? "null" : m_state->ident(); + return state_ ? state_->ident() : "null"; } -void Server::update() noexcept +void server::update() noexcept { - if (m_stateNext) { - log::debug("server {}: switch state {} -> {}"_format(m_name, m_state->ident(), m_stateNext->ident())); + if (state_next_) { + log::debug("server {}: switch state {} -> {}"_format(name_, state_->ident(), state_next_->ident())); - m_state = std::move(m_stateNext); - m_stateNext = nullptr; + state_ = std::move(state_next_); + state_next_ = nullptr; // Reset channels. - m_jchannels.clear(); + jchannels_.clear(); } } -void Server::disconnect() noexcept +void server::disconnect() noexcept { using namespace std::placeholders; - irc_disconnect(*m_session); - onDie(); + irc_disconnect(*session_); + on_die(); } -void Server::reconnect() noexcept +void server::reconnect() noexcept { - irc_disconnect(*m_session); - next(std::make_unique<ConnectingState>()); + irc_disconnect(*session_); + next(std::make_unique<connecting_state>()); } -void Server::prepare(fd_set &setinput, fd_set &setoutput, net::Handle &maxfd) noexcept +void server::prepare(fd_set& setinput, fd_set& setoutput, net::Handle& maxfd) noexcept { - m_state->prepare(*this, setinput, setoutput, maxfd); + state_->prepare(*this, setinput, setoutput, maxfd); } -void Server::sync(fd_set &setinput, fd_set &setoutput) +void server::sync(fd_set &setinput, fd_set &setoutput) { /* * 1. Send maximum of command possible if available for write @@ -632,200 +654,200 @@ */ bool done = false; - while (!m_queue.empty() && !done) { - if (m_queue.front()()) - m_queue.pop(); + while (!queue_.empty() && !done) { + if (queue_.front()()) + queue_.pop(); else done = true; } // 2. Read data. - irc_process_select_descriptors(*m_session, &setinput, &setoutput); + irc_process_select_descriptors(*session_, &setinput, &setoutput); } -bool Server::isSelf(const std::string &nick) const noexcept +bool server::is_self(const std::string& nick) const noexcept { char target[32]{0}; irc_target_get_nick(nick.c_str(), target, sizeof (target)); - return m_nickname == target; + return nickname_ == target; } -void Server::cmode(std::string channel, std::string mode) +void server::cmode(std::string channel, std::string mode) { - m_queue.push([=] () { - return irc_cmd_channel_mode(*m_session, channel.c_str(), mode.c_str()) == 0; + queue_.push([=] () { + return irc_cmd_channel_mode(*session_, channel.c_str(), mode.c_str()) == 0; }); } -void Server::cnotice(std::string channel, std::string message) +void server::cnotice(std::string channel, std::string message) { - m_queue.push([=] () { - return irc_cmd_notice(*m_session, channel.c_str(), message.c_str()) == 0; + queue_.push([=] () { + return irc_cmd_notice(*session_, channel.c_str(), message.c_str()) == 0; }); } -void Server::invite(std::string target, std::string channel) +void server::invite(std::string target, std::string channel) { - m_queue.push([=] () { - return irc_cmd_invite(*m_session, target.c_str(), channel.c_str()) == 0; + queue_.push([=] () { + return irc_cmd_invite(*session_, target.c_str(), channel.c_str()) == 0; }); } -void Server::join(std::string channel, std::string password) +void server::join(std::string channel, std::string password) { // 1. Add the channel or update it to the requested channels. - auto it = std::find_if(m_rchannels.begin(), m_rchannels.end(), [&] (const auto &c) { + auto it = std::find_if(rchannels_.begin(), rchannels_.end(), [&] (const auto& c) { return c.name == channel; }); - if (it == m_rchannels.end()) - m_rchannels.push_back({ channel, password }); + if (it == rchannels_.end()) + rchannels_.push_back({ channel, password }); else *it = { channel, password }; // 2. Join if not found and connected. - if (m_session->isConnected()) - irc_cmd_join(*m_session, channel.c_str(), password.empty() ? nullptr : password.c_str()); + if (session_->is_connected()) + irc_cmd_join(*session_, channel.c_str(), password.empty() ? nullptr : password.c_str()); } -void Server::kick(std::string target, std::string channel, std::string reason) +void server::kick(std::string target, std::string channel, std::string reason) { - m_queue.push([=] () { - return irc_cmd_kick(*m_session, target.c_str(), channel.c_str(), reason.c_str()) == 0; + queue_.push([=] () { + return irc_cmd_kick(*session_, target.c_str(), channel.c_str(), reason.c_str()) == 0; }); } -void Server::me(std::string target, std::string message) +void server::me(std::string target, std::string message) { - m_queue.push([=] () { - return irc_cmd_me(*m_session, target.c_str(), message.c_str()) == 0; + queue_.push([=] () { + return irc_cmd_me(*session_, target.c_str(), message.c_str()) == 0; }); } -void Server::message(std::string target, std::string message) +void server::message(std::string target, std::string message) { - m_queue.push([=] () { - return irc_cmd_msg(*m_session, target.c_str(), message.c_str()) == 0; + queue_.push([=] () { + return irc_cmd_msg(*session_, target.c_str(), message.c_str()) == 0; }); } -void Server::mode(std::string mode) +void server::mode(std::string mode) { - m_queue.push([=] () { - return irc_cmd_user_mode(*m_session, mode.c_str()) == 0; + queue_.push([=] () { + return irc_cmd_user_mode(*session_, mode.c_str()) == 0; }); } -void Server::names(std::string channel) +void server::names(std::string channel) { - m_queue.push([=] () { - return irc_cmd_names(*m_session, channel.c_str()) == 0; + queue_.push([=] () { + return irc_cmd_names(*session_, channel.c_str()) == 0; }); } -void Server::notice(std::string target, std::string message) +void server::notice(std::string target, std::string message) { - m_queue.push([=] () { - return irc_cmd_notice(*m_session, target.c_str(), message.c_str()) == 0; + queue_.push([=] () { + return irc_cmd_notice(*session_, target.c_str(), message.c_str()) == 0; }); } -void Server::part(std::string channel, std::string reason) +void server::part(std::string channel, std::string reason) { - m_queue.push([=] () -> bool { + queue_.push([=] () -> bool { if (reason.empty()) - return irc_cmd_part(*m_session, channel.c_str()) == 0; + return irc_cmd_part(*session_, channel.c_str()) == 0; - return irc_send_raw(*m_session, "PART %s :%s", channel.c_str(), reason.c_str()); + return irc_send_raw(*session_, "PART %s :%s", channel.c_str(), reason.c_str()); }); } -void Server::send(std::string raw) +void server::send(std::string raw) { - m_queue.push([=] () { - return irc_send_raw(*m_session, raw.c_str()) == 0; + queue_.push([=] () { + return irc_send_raw(*session_, raw.c_str()) == 0; }); } -void Server::topic(std::string channel, std::string topic) +void server::topic(std::string channel, std::string topic) { - m_queue.push([=] () { - return irc_cmd_topic(*m_session, channel.c_str(), topic.c_str()) == 0; + queue_.push([=] () { + return irc_cmd_topic(*session_, channel.c_str(), topic.c_str()) == 0; }); } -void Server::whois(std::string target) +void server::whois(std::string target) { - m_queue.push([=] () { - return irc_cmd_whois(*m_session, target.c_str()) == 0; + queue_.push([=] () { + return irc_cmd_whois(*session_, target.c_str()) == 0; }); } /* - * Server::DisconnectedState implementation + * server::disconnected_state implementation * ------------------------------------------------------------------ */ -void Server::DisconnectedState::prepare(Server &server, fd_set &, fd_set &, net::Handle &) +void server::disconnected_state::prepare(server& server, fd_set&, fd_set&, net::Handle&) { - if (server.m_recotries == 0) { - log::warning() << "server " << server.m_name << ": reconnection disabled, skipping" << std::endl; - server.onDie(); - } else if (server.m_recotries > 0 && server.m_recocur > server.m_recotries) { - log::warning() << "server " << server.m_name << ": giving up" << std::endl; - server.onDie(); + if (server.recotries_ == 0) { + log::warning() << "server " << server.name_ << ": reconnection disabled, skipping" << std::endl; + server.on_die(); + } else if (server.recotries_ > 0 && server.recocur_ > server.recotries_) { + log::warning() << "server " << server.name_ << ": giving up" << std::endl; + server.on_die(); } else { - if (m_timer.elapsed() > static_cast<unsigned>(server.m_recodelay * 1000)) { - irc_disconnect(*server.m_session); + if (timer_.elapsed() > static_cast<unsigned>(server.recodelay_ * 1000)) { + irc_disconnect(*server.session_); - server.m_recocur ++; - server.next(std::make_unique<ConnectingState>()); + server.recocur_ ++; + server.next(std::make_unique<connecting_state>()); } } } -std::string Server::DisconnectedState::ident() const +std::string server::disconnected_state::ident() const { return "Disconnected"; } /* - * Server::ConnectingState implementation + * server::connecting_state implementation * ------------------------------------------------------------------ */ -bool Server::ConnectingState::connect(Server &server) +bool server::connecting_state::connect(server& server) { - const char *password = server.m_password.empty() ? nullptr : server.m_password.c_str(); - std::string host = server.m_host; - int code; + auto password = server.password_.empty() ? nullptr : server.password_.c_str(); + auto host = server.host_; // libircclient requires # for SSL connection. #if defined(WITH_SSL) - if (server.m_flags & Server::Ssl) + if (server.flags_ & server::ssl) host.insert(0, 1, '#'); - if (!(server.m_flags & Server::SslVerify)) - irc_option_set(*server.m_session, LIBIRC_OPTION_SSL_NO_VERIFY); + if (!(server.flags_ & server::ssl_verify)) + irc_option_set(*server.session_, LIBIRC_OPTION_SSL_NO_VERIFY); #endif - if (server.flags() & Server::Ipv6) { - code = irc_connect6(*server.m_session, host.c_str(), server.m_port, password, - server.m_nickname.c_str(), - server.m_username.c_str(), - server.m_realname.c_str()); + int code; + if (server.flags() & server::ipv6) { + code = irc_connect6(*server.session_, host.c_str(), server.port_, password, + server.nickname_.c_str(), + server.username_.c_str(), + server.realname_.c_str()); } else { - code = irc_connect(*server.m_session, host.c_str(), server.m_port, password, - server.m_nickname.c_str(), - server.m_username.c_str(), - server.m_realname.c_str()); + code = irc_connect(*server.session_, host.c_str(), server.port_, password, + server.nickname_.c_str(), + server.username_.c_str(), + server.realname_.c_str()); } return code == 0; } -void Server::ConnectingState::prepare(Server &server, fd_set &setinput, fd_set &setoutput, net::Handle &maxfd) +void server::connecting_state::prepare(server& server, fd_set& setinput, fd_set& setoutput, net::Handle& maxfd) { /* * The connect function will either fail if the hostname wasn't resolved or @@ -840,20 +862,20 @@ * * Otherwise, the libircclient event_connect will change the state. */ - if (m_state == Connecting) { - if (m_timer.elapsed() > static_cast<unsigned>(server.m_recodelay * 1000)) { + if (state_ == connecting) { + if (timer_.elapsed() > static_cast<unsigned>(server.recodelay_ * 1000)) { log::warning() << "server " << server.name() << ": timeout while connecting" << std::endl; - server.next(std::make_unique<DisconnectedState>()); - } else if (!irc_is_connected(*server.m_session)) { - log::warning() << "server " << server.m_name << ": error while connecting: "; - log::warning() << irc_strerror(irc_errno(*server.m_session)) << std::endl; + server.next(std::make_unique<disconnected_state>()); + } else if (!irc_is_connected(*server.session_)) { + log::warning() << "server " << server.name_ << ": error while connecting: "; + log::warning() << irc_strerror(irc_errno(*server.session_)) << std::endl; - if (server.m_recotries != 0) - log::warning("server {}: retrying in {} seconds"_format(server.m_name, server.m_recodelay)); + if (server.recotries_ != 0) + log::warning("server {}: retrying in {} seconds"_format(server.name_, server.recodelay_)); - server.next(std::make_unique<DisconnectedState>()); + server.next(std::make_unique<disconnected_state>()); } else - irc_add_select_descriptors(*server.m_session, &setinput, &setoutput, reinterpret_cast<int *>(&maxfd)); + irc_add_select_descriptors(*server.session_, &setinput, &setoutput, reinterpret_cast<int*>(&maxfd)); } else { /* * This is needed if irccd is started before DHCP or if DNS cache is @@ -862,49 +884,49 @@ #if !defined(IRCCD_SYSTEM_WINDOWS) (void)res_init(); #endif - log::info("server {}: trying to connect to {}, port {}"_format(server.m_name, server.m_host, server.m_port)); + log::info("server {}: trying to connect to {}, port {}"_format(server.name_, server.host_, server.port_)); if (!connect(server)) { - log::warning() << "server " << server.m_name << ": disconnected while connecting: "; - log::warning() << irc_strerror(irc_errno(*server.m_session)) << std::endl; - server.next(std::make_unique<DisconnectedState>()); + log::warning() << "server " << server.name_ << ": disconnected while connecting: "; + log::warning() << irc_strerror(irc_errno(*server.session_)) << std::endl; + server.next(std::make_unique<disconnected_state>()); } else { - m_state = Connecting; + state_ = connecting; - if (irc_is_connected(*server.m_session)) - irc_add_select_descriptors(*server.m_session, &setinput, &setoutput, reinterpret_cast<int *>(&maxfd)); + if (irc_is_connected(*server.session_)) + irc_add_select_descriptors(*server.session_, &setinput, &setoutput, reinterpret_cast<int*>(&maxfd)); } } } -std::string Server::ConnectingState::ident() const +std::string server::connecting_state::ident() const { return "Connecting"; } /* - * Server::ConnectedState implementation + * server::connected_state implementation * ------------------------------------------------------------------ */ -void Server::ConnectedState::prepare(Server &server, fd_set &setinput, fd_set &setoutput, net::Handle &maxfd) +void server::connected_state::prepare(server& server, fd_set& setinput, fd_set& setoutput, net::Handle& maxfd) { - if (!irc_is_connected(*server.m_session)) { - log::warning() << "server " << server.m_name << ": disconnected" << std::endl; + if (!irc_is_connected(*server.session_)) { + log::warning() << "server " << server.name_ << ": disconnected" << std::endl; - if (server.m_recodelay > 0) - log::warning("server {}: retrying in {} seconds"_format(server.m_name, server.m_recodelay)); + if (server.recodelay_ > 0) + log::warning("server {}: retrying in {} seconds"_format(server.name_, server.recodelay_)); - server.next(std::make_unique<DisconnectedState>()); - } else if (server.m_timer.elapsed() >= server.m_timeout * 1000) { - log::warning() << "server " << server.m_name << ": ping timeout after " - << (server.m_timer.elapsed() / 1000) << " seconds" << std::endl; - server.next(std::make_unique<DisconnectedState>()); + server.next(std::make_unique<disconnected_state>()); + } else if (server.timer_.elapsed() >= server.timeout_ * 1000) { + log::warning() << "server " << server.name_ << ": ping timeout after " + << (server.timer_.elapsed() / 1000) << " seconds" << std::endl; + server.next(std::make_unique<disconnected_state>()); } else - irc_add_select_descriptors(*server.m_session, &setinput, &setoutput, reinterpret_cast<int *>(&maxfd)); + irc_add_select_descriptors(*server.session_, &setinput, &setoutput, reinterpret_cast<int*>(&maxfd)); } -std::string Server::ConnectedState::ident() const +std::string server::connected_state::ident() const { return "Connected"; }
--- a/libirccd/irccd/server.hpp Fri Aug 11 13:45:42 2017 +0200 +++ b/libirccd/irccd/server.hpp Tue Sep 26 17:18:47 2017 +0200 @@ -44,23 +44,23 @@ namespace irccd { -class Server; +class server; /** * \brief Prefixes for nicknames. */ -enum class ChannelMode { - Creator = 'O', //!< Channel creator - HalfOperator = 'h', //!< Half operator - Operator = 'o', //!< Channel operator - Protection = 'a', //!< Unkillable - Voiced = 'v' //!< Voice power +enum class channel_mode { + creator = 'O', //!< Channel creator + half_op = 'h', //!< Half operator + op = 'o', //!< Channel operator + protection = 'a', //!< Unkillable + voiced = 'v' //!< Voice power }; /** * \brief A channel to join with an optional password. */ -class Channel { +class channel { public: std::string name; //!< the channel to join std::string password; //!< the optional password @@ -69,7 +69,7 @@ /** * \brief Describe a whois information. */ -class Whois { +class whois { public: std::string nick; //!< user's nickname std::string user; //!< user's user @@ -81,9 +81,9 @@ /** * \brief Channel event. */ -class ChannelModeEvent { +class channel_mode_event { public: - std::shared_ptr<Server> server; //!< The server. + std::shared_ptr<class server> server; //!< The server. std::string origin; //!< The originator. std::string channel; //!< The channel. std::string mode; //!< The mode. @@ -93,9 +93,9 @@ /** * \brief Channel notice event. */ -class ChannelNoticeEvent { +class channel_notice_event { public: - std::shared_ptr<Server> server; //!< The server. + std::shared_ptr<class server> server; //!< The server. std::string origin; //!< The originator. std::string channel; //!< The channel. std::string message; //!< The notice message. @@ -104,17 +104,17 @@ /** * \brief Connection success event. */ -class ConnectEvent { +class connect_event { public: - std::shared_ptr<Server> server; //!< The server. + std::shared_ptr<class server> server; //!< The server. }; /** * \brief Invite event. */ -class InviteEvent { +class invite_event { public: - std::shared_ptr<Server> server; //!< The server. + std::shared_ptr<class server> server; //!< The server. std::string origin; //!< The originator. std::string channel; //!< The channel. std::string nickname; //!< The nickname (you). @@ -123,9 +123,9 @@ /** * \brief Join event. */ -class JoinEvent { +class join_event { public: - std::shared_ptr<Server> server; //!< The server. + std::shared_ptr<class server> server; //!< The server. std::string origin; //!< The originator. std::string channel; //!< The channel. }; @@ -133,9 +133,9 @@ /** * \brief Kick event. */ -class KickEvent { +class kick_event { public: - std::shared_ptr<Server> server; //!< The server. + std::shared_ptr<class server> server; //!< The server. std::string origin; //!< The originator. std::string channel; //!< The channel. std::string target; //!< The target. @@ -145,9 +145,9 @@ /** * \brief Message event. */ -class MessageEvent { +class message_event { public: - std::shared_ptr<Server> server; //!< The server. + std::shared_ptr<class server> server; //!< The server. std::string origin; //!< The originator. std::string channel; //!< The channel. std::string message; //!< The message. @@ -156,9 +156,9 @@ /** * \brief CTCP action event. */ -class MeEvent { +class me_event { public: - std::shared_ptr<Server> server; //!< The server. + std::shared_ptr<class server> server; //!< The server. std::string origin; //!< The originator. std::string channel; //!< The channel. std::string message; //!< The message. @@ -167,9 +167,9 @@ /** * \brief Mode event. */ -class ModeEvent { +class mode_event { public: - std::shared_ptr<Server> server; //!< The server. + std::shared_ptr<class server> server; //!< The server. std::string origin; //!< The originator. std::string mode; //!< The mode. }; @@ -177,9 +177,9 @@ /** * \brief Names listing event. */ -class NamesEvent { +class names_event { public: - std::shared_ptr<Server> server; //!< The server. + std::shared_ptr<class server> server; //!< The server. std::string channel; //!< The channel. std::vector<std::string> names; //!< The names. }; @@ -187,9 +187,9 @@ /** * \brief Nick change event. */ -class NickEvent { +class nick_event { public: - std::shared_ptr<Server> server; //!< The server. + std::shared_ptr<class server> server; //!< The server. std::string origin; //!< The originator. std::string nickname; //!< The new nickname. }; @@ -197,9 +197,9 @@ /** * \brief Notice event. */ -class NoticeEvent { +class notice_event { public: - std::shared_ptr<Server> server; //!< The server. + std::shared_ptr<class server> server; //!< The server. std::string origin; //!< The originator. std::string message; //!< The message. }; @@ -207,9 +207,9 @@ /** * \brief Part event. */ -class PartEvent { +class part_event { public: - std::shared_ptr<Server> server; //!< The server. + std::shared_ptr<class server> server; //!< The server. std::string origin; //!< The originator. std::string channel; //!< The channel. std::string reason; //!< The reason. @@ -218,9 +218,9 @@ /** * \brief Query event. */ -class QueryEvent { +class query_event { public: - std::shared_ptr<Server> server; //!< The server. + std::shared_ptr<class server> server; //!< The server. std::string origin; //!< The originator. std::string message; //!< The message. }; @@ -228,9 +228,9 @@ /** * \brief Topic event. */ -class TopicEvent { +class topic_event { public: - std::shared_ptr<Server> server; //!< The server. + std::shared_ptr<class server> server; //!< The server. std::string origin; //!< The originator. std::string channel; //!< The channel. std::string topic; //!< The topic message. @@ -239,10 +239,10 @@ /** * \brief Whois event. */ -class WhoisEvent { +class whois_event { public: - std::shared_ptr<Server> server; //!< The server. - Whois whois; //!< The whois information. + std::shared_ptr<class server> server; //!< The server. + class whois whois; //!< The whois information. }; /** @@ -261,90 +261,90 @@ * Note: the server is set in non blocking mode, commands are placed in a queue * and sent when only when they are ready. */ -class Server : public std::enable_shared_from_this<Server> { +class server : public std::enable_shared_from_this<server> { public: /** * Bridge for libircclient. */ - class Session; + class session; /** * \brief Various options for server. */ enum { - Ipv6 = (1 << 0), //!< Connect using IPv6 - Ssl = (1 << 1), //!< Use SSL - SslVerify = (1 << 2), //!< Verify SSL - AutoRejoin = (1 << 3), //!< Auto rejoin a kick - JoinInvite = (1 << 4) //!< Join a channel on invitation + ipv6 = (1 << 0), //!< Connect using IPv6 + ssl = (1 << 1), //!< Use SSL + ssl_verify = (1 << 2), //!< Verify SSL + auto_rejoin = (1 << 3), //!< Auto rejoin a kick + join_invite = (1 << 4) //!< Join a channel on invitation }; /** - * Signal: onChannelMode + * Signal: on_channel_mode * ---------------------------------------------------------- * * Triggered when someone changed the channel mode. */ - Signal<ChannelModeEvent> onChannelMode; + Signal<channel_mode_event> on_channel_mode; /** - * Signal: onChannelNotice + * Signal: on_channel_notice * ---------------------------------------------------------- * * Triggered when a notice has been sent on a channel. */ - Signal<ChannelNoticeEvent> onChannelNotice; + Signal<channel_notice_event> on_channel_notice; /** - * Signal: onConnect + * Signal: on_connect * ---------------------------------------------------------- * * Triggered when the server is successfully connected. */ - Signal<ConnectEvent> onConnect; + Signal<connect_event> on_connect; /** - * Signal: onDie + * Signal: on_die * ---------------------------------------------------------- * * The server is dead. */ - Signal<> onDie; + Signal<> on_die; /** - * Signal: onInvite + * Signal: on_invite * ---------------------------------------------------------- * * Triggered when an invite has been sent to you (the bot). */ - Signal<InviteEvent> onInvite; + Signal<invite_event> on_invite; /** - * Signal: onJoin + * Signal: on_join * ---------------------------------------------------------- * * Triggered when a user has joined the channel, it also includes you. */ - Signal<JoinEvent> onJoin; + Signal<join_event> on_join; /** - * Signal: onKick + * Signal: on_kick * ---------------------------------------------------------- * * Triggered when someone has been kicked from a channel. */ - Signal<KickEvent> onKick; + Signal<kick_event> on_kick; /** - * ServerEvent: onMessage + * Signal: on_message * ---------------------------------------------------------- * * Triggered when a message on a channel has been sent. */ - Signal<MessageEvent> onMessage; + Signal<message_event> on_message; /** - * Signal: onMe + * Signal: on_me * ---------------------------------------------------------- * * Triggered on a CTCP Action. @@ -352,140 +352,140 @@ * This is both used in a channel and in a private message so the target may * be a channel or your nickname. */ - Signal<MeEvent> onMe; + Signal<me_event> on_me; /** - * Signal: onMode + * Signal: on_mode * ---------------------------------------------------------- * * Triggered when the server changed your user mode. */ - Signal<ModeEvent> onMode; + Signal<mode_event> on_mode; /** - * Signal: onNames + * Signal: on_names * ---------------------------------------------------------- * * Triggered when names listing has finished on a channel. */ - Signal<NamesEvent> onNames; + Signal<names_event> on_names; /** - * Signal: onNick + * Signal: on_nick * ---------------------------------------------------------- * * Triggered when someone changed its nickname, it also includes you. */ - Signal<NickEvent> onNick; + Signal<nick_event> on_nick; /** - * Signal: onNotice + * Signal: on_notice * ---------------------------------------------------------- * * Triggered when someone has sent a notice to you. */ - Signal<NoticeEvent> onNotice; + Signal<notice_event> on_notice; /** - * Signal: onPart + * Signal: on_part * ---------------------------------------------------------- * * Triggered when someone has left the channel. */ - Signal<PartEvent> onPart; + Signal<part_event> on_part; /** - * Signal: onQuery + * Signal: on_query * ---------------------------------------------------------- * * Triggered when someone has sent you a private message. */ - Signal<QueryEvent> onQuery; + Signal<query_event> on_query; /** - * Signal: onTopic + * Signal: on_topic * ---------------------------------------------------------- * * Triggered when someone changed the channel topic. */ - Signal<TopicEvent> onTopic; + Signal<topic_event> on_topic; /** - * Signal: onWhois + * Signal: on_whois * ---------------------------------------------------------- * * Triggered when whois information has been received. */ - Signal<WhoisEvent> onWhois; + Signal<whois_event> on_whois; private: - class State; - class ConnectedState; - class ConnectingState; - class DisconnectedState; + class state; + class connected_state; + class connecting_state; + class disconnected_state; // Requested and joined channels. - std::vector<Channel> m_rchannels; - std::vector<std::string> m_jchannels; + std::vector<channel> rchannels_; + std::vector<std::string> jchannels_; // Identifier. - std::string m_name; + std::string name_; // Connection information - std::string m_host; - std::string m_password; - std::uint16_t m_port{6667}; - std::uint8_t m_flags{0}; + std::string host_; + std::string password_; + std::uint16_t port_{6667}; + std::uint8_t flags_{0}; // Identity. - std::string m_nickname{"irccd"}; - std::string m_username{"irccd"}; - std::string m_realname{"IRC Client Daemon"}; - std::string m_ctcpversion{"IRC Client Daemon"}; + std::string nickname_{"irccd"}; + std::string username_{"irccd"}; + std::string realname_{"IRC Client Daemon"}; + std::string ctcpversion_{"IRC Client Daemon"}; // Settings. - std::string m_commandCharacter{"!"}; - std::int8_t m_recotries{-1}; - std::uint16_t m_recodelay{30}; - std::uint16_t m_timeout{1000}; + std::string command_char_{"!"}; + std::int8_t recotries_{-1}; + std::uint16_t recodelay_{30}; + std::uint16_t timeout_{1000}; // Queue of requests to send. - std::queue<std::function<bool ()>> m_queue; + std::queue<std::function<bool ()>> queue_; // libircclient session (bridge). - std::unique_ptr<Session> m_session; + std::unique_ptr<session> session_; // States. - std::unique_ptr<State> m_state; - std::unique_ptr<State> m_stateNext; + std::unique_ptr<state> state_; + std::unique_ptr<state> state_next_; // Misc. - ElapsedTimer m_timer; - std::map<ChannelMode, char> m_modes; - std::int8_t m_recocur{0}; - std::map<std::string, std::set<std::string>> m_namesMap; - std::map<std::string, Whois> m_whoisMap; + ElapsedTimer timer_; + std::map<channel_mode, char> modes_; + std::int8_t recocur_{0}; + std::map<std::string, std::set<std::string>> names_map_; + std::map<std::string, class whois> whois_map_; // Private helpers. - void removeJoinedChannel(const std::string &channel); + void remove_joined_channel(const std::string& channel); // Handle libircclient callbacks. - void handleChannel(const char *, const char **) noexcept; - void handleChannelMode(const char *, const char **) noexcept; - void handleChannelNotice(const char *, const char **) noexcept; - void handleConnect(const char *, const char **) noexcept; - void handleCtcpAction(const char *, const char **) noexcept; - void handleInvite(const char *, const char **) noexcept; - void handleJoin(const char *, const char **) noexcept; - void handleKick(const char *, const char **) noexcept; - void handleMode(const char *, const char **) noexcept; - void handleNick(const char *, const char **) noexcept; - void handleNotice(const char *, const char **) noexcept; - void handleNumeric(unsigned int, const char **, unsigned int) noexcept; - void handlePart(const char *, const char **) noexcept; - void handlePing(const char *, const char **) noexcept; - void handleQuery(const char *, const char **) noexcept; - void handleTopic(const char *, const char **) noexcept; + void handle_channel(const char*, const char**) noexcept; + void handle_channel_mode(const char*, const char**) noexcept; + void handle_channel_notice(const char*, const char**) noexcept; + void handle_connect(const char*, const char**) noexcept; + void handle_ctcp_action(const char*, const char**) noexcept; + void handle_invite(const char*, const char**) noexcept; + void handle_join(const char*, const char**) noexcept; + void handle_kick(const char*, const char**) noexcept; + void handle_mode(const char*, const char**) noexcept; + void handle_nick(const char*, const char**) noexcept; + void handle_notice(const char*, const char**) noexcept; + void handle_numeric(unsigned int, const char**, unsigned int) noexcept; + void handle_part(const char*, const char**) noexcept; + void handle_ping(const char*, const char**) noexcept; + void handle_query(const char*, const char**) noexcept; + void handle_topic(const char*, const char**) noexcept; public: /** @@ -497,37 +497,37 @@ * \return the server * \throw std::exception on failures */ - IRCCD_EXPORT static std::shared_ptr<Server> fromJson(const nlohmann::json &object); + static std::shared_ptr<server> from_json(const nlohmann::json& object); /** - * Split a channel from the form channel:password into a ServerChannel + * Split a channel from the form channel:password into a server_channel * object. * * \param value the value * \return a channel */ - IRCCD_EXPORT static Channel splitChannel(const std::string &value); + static channel split_channel(const std::string& value); /** * Construct a server. * * \param name the identifier */ - IRCCD_EXPORT Server(std::string name); + server(std::string name); /** * Destructor. Close the connection if needed. */ - IRCCD_EXPORT virtual ~Server(); + virtual ~server(); /** * Get the server identifier. * * \return the id */ - inline const std::string &name() const noexcept + inline const std::string& name() const noexcept { - return m_name; + return name_; } /** @@ -535,9 +535,9 @@ * * \return the hostname */ - inline const std::string &host() const noexcept + inline const std::string& host() const noexcept { - return m_host; + return host_; } /** @@ -545,9 +545,9 @@ * * \param host the hostname */ - inline void setHost(std::string host) noexcept + inline void set_host(std::string host) noexcept { - m_host = std::move(host); + host_ = std::move(host); } /** @@ -555,9 +555,9 @@ * * \return the password */ - inline const std::string &password() const noexcept + inline const std::string& password() const noexcept { - return m_password; + return password_; } /** @@ -567,9 +567,9 @@ * * \param password the password */ - inline void setPassword(std::string password) noexcept + inline void set_password(std::string password) noexcept { - m_password = std::move(password); + password_ = std::move(password); } /** @@ -579,7 +579,7 @@ */ inline std::uint16_t port() const noexcept { - return m_port; + return port_; } /** @@ -587,9 +587,9 @@ * * \param port the port */ - inline void setPort(std::uint16_t port) noexcept + inline void set_port(std::uint16_t port) noexcept { - m_port = port; + port_ = port; } /** @@ -599,20 +599,17 @@ */ inline std::uint8_t flags() const noexcept { - return m_flags; + return flags_; } /** * Set the flags. * - * \pre flags must be valid * \param flags the flags */ - inline void setFlags(std::uint8_t flags) noexcept + inline void set_flags(std::uint8_t flags) noexcept { - assert(flags <= 0x1f); - - m_flags = flags; + flags_ = flags; } /** @@ -620,9 +617,9 @@ * * \return the nickname */ - inline const std::string &nickname() const noexcept + inline const std::string& nickname() const noexcept { - return m_nickname; + return nickname_; } /** @@ -633,16 +630,16 @@ * * \param nickname the nickname */ - IRCCD_EXPORT virtual void setNickname(std::string nickname); + virtual void set_nickname(std::string nickname); /** * Get the username. * * \return the username */ - inline const std::string &username() const noexcept + inline const std::string& username() const noexcept { - return m_username; + return username_; } /** @@ -651,9 +648,9 @@ * \param name the username * \note the username will be changed on the next connection */ - inline void setUsername(std::string name) noexcept + inline void set_username(std::string name) noexcept { - m_username = std::move(name); + username_ = std::move(name); } /** @@ -661,9 +658,9 @@ * * \return the realname */ - inline const std::string &realname() const noexcept + inline const std::string& realname() const noexcept { - return m_realname; + return realname_; } /** @@ -672,9 +669,9 @@ * \param realname the username * \note the username will be changed on the next connection */ - inline void setRealname(std::string realname) noexcept + inline void set_realname(std::string realname) noexcept { - m_realname = std::move(realname); + realname_ = std::move(realname); } /** @@ -682,9 +679,9 @@ * * \return the CTCP version */ - inline const std::string &ctcpVersion() const noexcept + inline const std::string& ctcp_version() const noexcept { - return m_ctcpversion; + return ctcpversion_; } /** @@ -692,29 +689,29 @@ * * \param ctcpversion the version */ - IRCCD_EXPORT void setCtcpVersion(std::string ctcpversion); + void set_ctcp_version(std::string ctcpversion); /** * Get the command character. * * \return the character */ - inline const std::string &commandCharacter() const noexcept + inline const std::string& command_char() const noexcept { - return m_commandCharacter; + return command_char_; } /** * Set the command character. * - * \pre !commandCharacter.empty() - * \param commandCharacter the command character + * \pre !command_char_.empty() + * \param command_char the command character */ - inline void setCommandCharacter(std::string commandCharacter) noexcept + inline void set_command_char(std::string command_char) noexcept { - assert(!commandCharacter.empty()); + assert(!command_char.empty()); - m_commandCharacter = std::move(commandCharacter); + command_char_ = std::move(command_char); } /** @@ -722,9 +719,9 @@ * * \return the number of reconnections */ - inline std::int8_t reconnectTries() const noexcept + inline std::int8_t reconnect_tries() const noexcept { - return m_recotries; + return recotries_; } /** @@ -732,11 +729,11 @@ * * A value less than 0 means infinite. * - * \param reconnectTries the number of reconnections + * \param reconnect_tries the number of reconnections */ - inline void setReconnectTries(std::int8_t reconnectTries) noexcept + inline void set_reconnect_tries(std::int8_t reconnect_tries) noexcept { - m_recotries = reconnectTries; + recotries_ = reconnect_tries; } /** @@ -744,19 +741,19 @@ * * \return the number of seconds */ - inline std::uint16_t reconnectDelay() const noexcept + inline std::uint16_t reconnect_delay() const noexcept { - return m_recodelay; + return recodelay_; } /** * Set the number of seconds before retrying. * - * \param reconnectDelay the number of seconds + * \param reconnect_delay the number of seconds */ - inline void setReconnectDelay(std::uint16_t reconnectDelay) noexcept + inline void set_reconnect_delay(std::uint16_t reconnect_delay) noexcept { - m_recodelay = reconnectDelay; + recodelay_ = reconnect_delay; } /** @@ -764,19 +761,19 @@ * * \return the ping timeout */ - inline std::uint16_t pingTimeout() const noexcept + inline std::uint16_t ping_timeout() const noexcept { - return m_timeout; + return timeout_; } /** * Set the ping timeout before considering a server as dead. * - * \param pingTimeout the delay in seconds + * \param ping_timeout the delay in seconds */ - inline void setPingTimeout(std::uint16_t pingTimeout) noexcept + inline void set_ping_timeout(std::uint16_t ping_timeout) noexcept { - m_timeout = pingTimeout; + timeout_ = ping_timeout; } /** @@ -784,9 +781,9 @@ * * \return the channels */ - inline const std::vector<std::string> &channels() const noexcept + inline const std::vector<std::string>& channels() const noexcept { - return m_jchannels; + return jchannels_; } /** @@ -794,36 +791,36 @@ * * \param state the new state */ - IRCCD_EXPORT void next(std::unique_ptr<State> state) noexcept; + void next(std::unique_ptr<state> state) noexcept; /** * Get the state current id. * * \return the state id */ - IRCCD_EXPORT std::string status() const noexcept; + std::string status() const noexcept; /** * Switch to next state if it has. */ - IRCCD_EXPORT void update() noexcept; + void update() noexcept; /** * Force disconnection. */ - IRCCD_EXPORT void disconnect() noexcept; + void disconnect() noexcept; /** * Asks for a reconnection. */ - IRCCD_EXPORT virtual void reconnect() noexcept; + virtual void reconnect() noexcept; /** * Prepare the IRC session. * * \warning Not thread-safe */ - IRCCD_EXPORT virtual void prepare(fd_set &setinput, fd_set &setoutput, net::Handle &maxfd) noexcept; + virtual void prepare(fd_set& setinput, fd_set& setoutput, net::Handle& maxfd) noexcept; /** * Process incoming/outgoing data after selection. @@ -832,7 +829,7 @@ * \param setoutput * \throw any exception that have been throw from user functions */ - IRCCD_EXPORT virtual void sync(fd_set &setinput, fd_set &setoutput); + virtual void sync(fd_set& setinput, fd_set& setoutput); /** * Determine if the nickname is the bot itself. @@ -840,7 +837,7 @@ * \param nick the nickname to check * \return true if it is the bot */ - IRCCD_EXPORT bool isSelf(const std::string &nick) const noexcept; + bool is_self(const std::string& nick) const noexcept; /** * Change the channel mode. @@ -848,7 +845,7 @@ * \param channel the channel * \param mode the new mode */ - IRCCD_EXPORT virtual void cmode(std::string channel, std::string mode); + virtual void cmode(std::string channel, std::string mode); /** * Send a channel notice. @@ -856,7 +853,7 @@ * \param channel the channel * \param message message notice */ - IRCCD_EXPORT virtual void cnotice(std::string channel, std::string message); + virtual void cnotice(std::string channel, std::string message); /** * Invite a user to a channel. @@ -864,7 +861,7 @@ * \param target the target nickname * \param channel the channel */ - IRCCD_EXPORT virtual void invite(std::string target, std::string channel); + virtual void invite(std::string target, std::string channel); /** * Join a channel, the password is optional and can be kept empty. @@ -872,7 +869,7 @@ * \param channel the channel to join * \param password the optional password */ - IRCCD_EXPORT virtual void join(std::string channel, std::string password = ""); + virtual void join(std::string channel, std::string password = ""); /** * Kick someone from the channel. Please be sure to have the rights @@ -882,7 +879,7 @@ * \param channel from which channel * \param reason the optional reason */ - IRCCD_EXPORT virtual void kick(std::string target, std::string channel, std::string reason = ""); + virtual void kick(std::string target, std::string channel, std::string reason = ""); /** * Send a CTCP Action as known as /me. The target may be either a @@ -891,7 +888,7 @@ * \param target the nickname or the channel * \param message the message */ - IRCCD_EXPORT virtual void me(std::string target, std::string message); + virtual void me(std::string target, std::string message); /** * Send a message to the specified target or channel. @@ -899,21 +896,21 @@ * \param target the target * \param message the message */ - IRCCD_EXPORT virtual void message(std::string target, std::string message); + virtual void message(std::string target, std::string message); /** * Change your user mode. * * \param mode the mode */ - IRCCD_EXPORT virtual void mode(std::string mode); + virtual void mode(std::string mode); /** * Request the list of names. * * \param channel the channel */ - IRCCD_EXPORT virtual void names(std::string channel); + virtual void names(std::string channel); /** * Send a private notice. @@ -921,7 +918,7 @@ * \param target the target * \param message the notice message */ - IRCCD_EXPORT virtual void notice(std::string target, std::string message); + virtual void notice(std::string target, std::string message); /** * Part from a channel. @@ -932,7 +929,7 @@ * \param channel the channel to leave * \param reason the optional reason */ - IRCCD_EXPORT virtual void part(std::string channel, std::string reason = ""); + virtual void part(std::string channel, std::string reason = ""); /** * Send a raw message to the IRC server. You don't need to add @@ -941,7 +938,7 @@ * \warning Use this function with care * \param raw the raw message (without `\r\n\r\n`) */ - IRCCD_EXPORT virtual void send(std::string raw); + virtual void send(std::string raw); /** * Change the channel topic. @@ -949,14 +946,14 @@ * \param channel the channel * \param topic the desired topic */ - IRCCD_EXPORT virtual void topic(std::string channel, std::string topic); + virtual void topic(std::string channel, std::string topic); /** * Request for whois information. * * \param target the target nickname */ - IRCCD_EXPORT virtual void whois(std::string target); + virtual void whois(std::string target); }; } // !irccd
--- a/libirccd/irccd/service.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/libirccd/irccd/service.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -35,129 +35,129 @@ namespace irccd { /* - * CommandService. + * command_service. * ------------------------------------------------------------------ */ -bool CommandService::contains(const std::string &name) const noexcept +bool command_service::contains(const std::string& name) const noexcept { return find(name) != nullptr; } -std::shared_ptr<Command> CommandService::find(const std::string &name) const noexcept +std::shared_ptr<command> command_service::find(const std::string& name) const noexcept { - auto it = std::find_if(m_commands.begin(), m_commands.end(), [&] (const auto &cmd) { + auto it = std::find_if(commands_.begin(), commands_.end(), [&] (const auto& cmd) { return cmd->name() == name; }); - return it == m_commands.end() ? nullptr : *it; + return it == commands_.end() ? nullptr : *it; } -void CommandService::add(std::shared_ptr<Command> command) +void command_service::add(std::shared_ptr<command> command) { - auto it = std::find_if(m_commands.begin(), m_commands.end(), [&] (const auto &cmd) { + auto it = std::find_if(commands_.begin(), commands_.end(), [&] (const auto& cmd) { return cmd->name() == command->name(); }); - if (it != m_commands.end()) + if (it != commands_.end()) *it = std::move(command); else - m_commands.push_back(std::move(command)); + commands_.push_back(std::move(command)); } /* - * InterruptService. + * interrupt_service. * ------------------------------------------------------------------ */ -InterruptService::InterruptService() - : m_in(AF_INET, 0) - , m_out(AF_INET, 0) +interrupt_service::interrupt_service() + : in_(AF_INET, 0) + , out_(AF_INET, 0) { // Bind a socket to any port. - m_in.set(net::option::SockReuseAddress(true)); - m_in.bind(net::ipv4::any(0)); - m_in.listen(1); + in_.set(net::option::SockReuseAddress(true)); + in_.bind(net::ipv4::any(0)); + in_.listen(1); // Do the socket pair. - m_out.connect(net::ipv4::pton("127.0.0.1", net::ipv4::port(m_in.getsockname()))); - m_in = m_in.accept(); - m_out.set(net::option::SockBlockMode(false)); + out_.connect(net::ipv4::pton("127.0.0.1", net::ipv4::port(in_.getsockname()))); + in_ = in_.accept(); + out_.set(net::option::SockBlockMode(false)); } -void InterruptService::prepare(fd_set &in, fd_set &, net::Handle &max) +void interrupt_service::prepare(fd_set& in, fd_set&, net::Handle& max) { - FD_SET(m_in.handle(), &in); + FD_SET(in_.handle(), &in); - if (m_in.handle() > max) - max = m_in.handle(); + if (in_.handle() > max) + max = in_.handle(); } -void InterruptService::sync(fd_set &in, fd_set &) +void interrupt_service::sync(fd_set& in, fd_set&) { - if (FD_ISSET(m_in.handle(), &in)) { + if (FD_ISSET(in_.handle(), &in)) { static std::array<char, 32> tmp; try { log::debug("irccd: interrupt service recv"); - m_in.recv(tmp.data(), 32); - } catch (const std::exception &ex) { + in_.recv(tmp.data(), 32); + } catch (const std::exception& ex) { log::warning() << "irccd: interrupt service error: " << ex.what() << std::endl; } } } -void InterruptService::interrupt() noexcept +void interrupt_service::interrupt() noexcept { try { static char byte; log::debug("irccd: interrupt service send"); - m_out.send(&byte, 1); - } catch (const std::exception &ex) { + out_.send(&byte, 1); + } catch (const std::exception& ex) { log::warning() << "irccd: interrupt service error: " << ex.what() << std::endl; } } /* - * PluginService. + * plugin_service. * ------------------------------------------------------------------ */ -PluginService::PluginService(Irccd &irccd) noexcept - : m_irccd(irccd) +plugin_service::plugin_service(irccd& irccd) noexcept + : irccd_(irccd) { - m_default_paths.emplace("cache", sys::cachedir()); - m_default_paths.emplace("data", sys::datadir()); - m_default_paths.emplace("config", sys::sysconfigdir()); + default_paths_.emplace("cache", sys::cachedir()); + default_paths_.emplace("data", sys::datadir()); + default_paths_.emplace("config", sys::sysconfigdir()); } -PluginService::~PluginService() +plugin_service::~plugin_service() { - for (const auto &plugin : m_plugins) - plugin->onUnload(m_irccd); + for (const auto& plugin : plugins_) + plugin->on_unload(irccd_); } -bool PluginService::has(const std::string &name) const noexcept +bool plugin_service::has(const std::string& name) const noexcept { - return std::count_if(m_plugins.cbegin(), m_plugins.cend(), [&] (const auto &plugin) { + return std::count_if(plugins_.cbegin(), plugins_.cend(), [&] (const auto& plugin) { return plugin->name() == name; }) > 0; } -std::shared_ptr<Plugin> PluginService::get(const std::string &name) const noexcept +std::shared_ptr<plugin> plugin_service::get(const std::string& name) const noexcept { - auto it = std::find_if(m_plugins.begin(), m_plugins.end(), [&] (const auto &plugin) { + auto it = std::find_if(plugins_.begin(), plugins_.end(), [&] (const auto& plugin) { return plugin->name() == name; }); - if (it == m_plugins.end()) + if (it == plugins_.end()) return nullptr; return *it; } -std::shared_ptr<Plugin> PluginService::require(const std::string &name) const +std::shared_ptr<plugin> plugin_service::require(const std::string& name) const { auto plugin = get(name); @@ -167,84 +167,84 @@ return plugin; } -void PluginService::add(std::shared_ptr<Plugin> plugin) +void plugin_service::add(std::shared_ptr<plugin> plugin) { - m_plugins.push_back(std::move(plugin)); + plugins_.push_back(std::move(plugin)); } -void PluginService::addLoader(std::unique_ptr<PluginLoader> loader) +void plugin_service::add_loader(std::unique_ptr<plugin_loader> loader) { - m_loaders.push_back(std::move(loader)); + loaders_.push_back(std::move(loader)); } -void PluginService::setConfig(const std::string &name, PluginConfig config) +void plugin_service::set_config(const std::string& name, plugin_config config) { - m_config.emplace(name, std::move(config)); + config_.emplace(name, std::move(config)); } -PluginConfig PluginService::config(const std::string &name) const +plugin_config plugin_service::config(const std::string& name) const { - auto it = m_config.find(name); + auto it = config_.find(name); - if (it != m_config.end()) + if (it != config_.end()) return it->second; - return PluginConfig(); + return plugin_config(); } -void PluginService::setFormats(const std::string &name, PluginFormats formats) +void plugin_service::set_formats(const std::string& name, plugin_formats formats) { - m_formats.emplace(name, std::move(formats)); + formats_.emplace(name, std::move(formats)); } -PluginFormats PluginService::formats(const std::string &name) const +plugin_formats plugin_service::formats(const std::string& name) const { - auto it = m_formats.find(name); + auto it = formats_.find(name); - if (it != m_formats.end()) + if (it != formats_.end()) return it->second; - return PluginFormats(); + return plugin_formats(); } -const PluginPaths& PluginService::paths() const noexcept +const plugin_paths& plugin_service::paths() const noexcept { - return m_default_paths; + return default_paths_; } -PluginPaths PluginService::paths(const std::string& name) const +plugin_paths plugin_service::paths(const std::string& name) const { - auto result = m_default_paths; - auto overriden = m_paths.find(name); + auto result = default_paths_; + auto overriden = paths_.find(name); // For all default paths, append the plugin name. for (auto& pair : result) pair.second += "/plugin/"s + name; // Now, mere overriden paths. - if (overriden != m_paths.end()) + if (overriden != paths_.end()) for (const auto& pair : overriden->second) result[pair.first] = pair.second; return result; } -void PluginService::setPaths(PluginPaths paths) +void plugin_service::set_paths(plugin_paths paths) { // If the paths is empty or not complete, do not erase default items. for (const auto& pair : paths) - m_default_paths[pair.first] = pair.second; + default_paths_[pair.first] = pair.second; } -void PluginService::setPaths(const std::string& name, PluginPaths paths) +void plugin_service::set_paths(const std::string& name, plugin_paths paths) { - m_paths.emplace(name, std::move(paths)); + paths_.emplace(name, std::move(paths)); } -std::shared_ptr<Plugin> PluginService::open(const std::string &id, - const std::string &path) +std::shared_ptr<plugin> plugin_service::open(const std::string& id, + const std::string& path) { - for (const auto &loader : m_loaders) { + for (const auto& loader : loaders_) { auto plugin = loader->open(id, path); if (plugin) @@ -254,9 +254,9 @@ return nullptr; } -std::shared_ptr<Plugin> PluginService::find(const std::string &id) +std::shared_ptr<plugin> plugin_service::find(const std::string& id) { - for (const auto &loader : m_loaders) { + for (const auto& loader : loaders_) { auto plugin = loader->find(id); if (plugin) @@ -266,13 +266,13 @@ return nullptr; } -void PluginService::load(std::string name, std::string path) +void plugin_service::load(std::string name, std::string path) { if (has(name)) return; try { - std::shared_ptr<Plugin> plugin; + std::shared_ptr<plugin> plugin; if (path.empty()) plugin = find(name); @@ -280,83 +280,83 @@ plugin = open(name, std::move(path)); if (plugin) { - plugin->setConfig(m_config[name]); - plugin->setFormats(m_formats[name]); - plugin->setPaths(paths(name)); - plugin->onLoad(m_irccd); + plugin->set_config(config_[name]); + plugin->set_formats(formats_[name]); + plugin->set_paths(paths(name)); + plugin->on_load(irccd_); add(std::move(plugin)); } - } catch (const std::exception &ex) { + } catch (const std::exception& ex) { log::warning("plugin {}: {}"_format(name, ex.what())); } } -void PluginService::reload(const std::string &name) +void plugin_service::reload(const std::string& name) { auto plugin = get(name); if (plugin) - plugin->onReload(m_irccd); + plugin->on_reload(irccd_); } -void PluginService::unload(const std::string &name) +void plugin_service::unload(const std::string& name) { - auto it = std::find_if(m_plugins.begin(), m_plugins.end(), [&] (const auto &plugin) { + auto it = std::find_if(plugins_.begin(), plugins_.end(), [&] (const auto& plugin) { return plugin->name() == name; }); - if (it != m_plugins.end()) { - (*it)->onUnload(m_irccd); - m_plugins.erase(it); + if (it != plugins_.end()) { + (*it)->on_unload(irccd_); + plugins_.erase(it); } } /* - * RuleService. + * rule_service. * ------------------------------------------------------------------ */ -void RuleService::add(Rule rule) +void rule_service::add(rule rule) { - m_rules.push_back(std::move(rule)); + rules_.push_back(std::move(rule)); } -void RuleService::insert(Rule rule, unsigned position) +void rule_service::insert(rule rule, unsigned position) { - assert(position <= m_rules.size()); + assert(position <= rules_.size()); - m_rules.insert(m_rules.begin() + position, std::move(rule)); + rules_.insert(rules_.begin() + position, std::move(rule)); } -void RuleService::remove(unsigned position) +void rule_service::remove(unsigned position) { - assert(position < m_rules.size()); + assert(position < rules_.size()); - m_rules.erase(m_rules.begin() + position); + rules_.erase(rules_.begin() + position); } -const Rule &RuleService::require(unsigned position) const +const rule &rule_service::require(unsigned position) const { - if (position >= m_rules.size()) + if (position >= rules_.size()) throw std::out_of_range("rule " + std::to_string(position) + " does not exist"); - return m_rules[position]; + return rules_[position]; } -Rule &RuleService::require(unsigned position) +rule &rule_service::require(unsigned position) { - if (position >= m_rules.size()) + if (position >= rules_.size()) throw std::out_of_range("rule " + std::to_string(position) + " does not exist"); - return m_rules[position]; + return rules_[position]; } -bool RuleService::solve(const std::string &server, - const std::string &channel, - const std::string &origin, - const std::string &plugin, - const std::string &event) noexcept +bool rule_service::solve(const std::string& server, + const std::string& channel, + const std::string& origin, + const std::string& plugin, + const std::string& event) noexcept { bool result = true; @@ -364,60 +364,59 @@ origin, plugin, event)); int i = 0; - for (const Rule &rule : m_rules) { + for (const auto& rule : rules_) { log::debug() << " candidate " << i++ << ":\n" - << " servers: " << util::join(rule.servers().begin(), rule.servers().end()) << "\n" - << " channels: " << util::join(rule.channels().begin(), rule.channels().end()) << "\n" - << " origins: " << util::join(rule.origins().begin(), rule.origins().end()) << "\n" - << " plugins: " << util::join(rule.plugins().begin(), rule.plugins().end()) << "\n" - << " events: " << util::join(rule.events().begin(), rule.events().end()) << "\n" - << " action: " << ((rule.action() == RuleAction::Accept) ? "accept" : "drop") << std::endl; + << " servers: " << util::join(rule.servers().begin(), rule.servers().end()) << "\n" + << " channels: " << util::join(rule.channels().begin(), rule.channels().end()) << "\n" + << " origins: " << util::join(rule.origins().begin(), rule.origins().end()) << "\n" + << " plugins: " << util::join(rule.plugins().begin(), rule.plugins().end()) << "\n" + << " events: " << util::join(rule.events().begin(), rule.events().end()) << "\n" + << " action: " << ((rule.action() == rule::action_type::accept) ? "accept" : "drop") << std::endl; if (rule.match(server, channel, origin, plugin, event)) - result = rule.action() == RuleAction::Accept; + result = rule.action() == rule::action_type::accept; } return result; } /* - * ServerService. + * server_service. * ------------------------------------------------------------------ */ -class EventHandler { +class event_handler { public: std::string server; std::string origin; std::string target; - std::function<std::string (Plugin &)> functionName; - std::function<void (Plugin &)> functionExec; + std::function<std::string (plugin &)> function_name; + std::function<void (plugin &)> function_exec; - void operator()(Irccd &irccd) const + void operator()(irccd& irccd) const { - for (auto &plugin : irccd.plugins().list()) { - auto eventname = functionName(*plugin); + for (auto& plugin : irccd.plugins().list()) { + auto eventname = function_name(*plugin); auto allowed = irccd.rules().solve(server, target, origin, plugin->name(), eventname); if (!allowed) { log::debug() << "rule: event skipped on match" << std::endl; continue; - } else - log::debug() << "rule: event allowed" << std::endl; + } + + log::debug() << "rule: event allowed" << std::endl; - // TODO: server-event must not know which type of plugin. - // TODO: get generic error. - // TODO: this is the responsability of service-plugin. + // TODO: this is the responsability of plugin_service. try { - functionExec(*plugin); - } catch (const std::exception &ex) { + function_exec(*plugin); + } catch (const std::exception& ex) { log::warning() << "plugin " << plugin->name() << ": error: " << ex.what() << std::endl; } } } }; -void ServerService::handleChannelMode(const ChannelModeEvent &ev) +void server_service::handle_channel_mode(const channel_mode_event& ev) { log::debug() << "server " << ev.server->name() << ": event onChannelMode:\n"; log::debug() << " origin: " << ev.origin << "\n"; @@ -425,7 +424,7 @@ log::debug() << " mode: " << ev.mode << "\n"; log::debug() << " argument: " << ev.argument << std::endl; - m_irccd.transports().broadcast(nlohmann::json::object({ + irccd_.transports().broadcast(nlohmann::json::object({ { "event", "onChannelMode" }, { "server", ev.server->name() }, { "origin", ev.origin }, @@ -434,24 +433,24 @@ { "argument", ev.argument } })); - m_irccd.post(EventHandler{ev.server->name(), ev.origin, ev.channel, - [=] (Plugin &) -> std::string { + irccd_.post(event_handler{ev.server->name(), ev.origin, ev.channel, + [=] (plugin&) -> std::string { return "onChannelMode"; }, - [=] (Plugin &plugin) { - plugin.onChannelMode(m_irccd, ev); + [=] (plugin& plugin) { + plugin.on_channel_mode(irccd_, ev); } }); } -void ServerService::handleChannelNotice(const ChannelNoticeEvent &ev) +void server_service::handle_channel_notice(const channel_notice_event& ev) { log::debug() << "server " << ev.server->name() << ": event onChannelNotice:\n"; log::debug() << " origin: " << ev.origin << "\n"; log::debug() << " channel: " << ev.channel << "\n"; log::debug() << " message: " << ev.message << std::endl; - m_irccd.transports().broadcast(nlohmann::json::object({ + irccd_.transports().broadcast(nlohmann::json::object({ { "event", "onChannelNotice" }, { "server", ev.server->name() }, { "origin", ev.origin }, @@ -459,83 +458,83 @@ { "message", ev.message } })); - m_irccd.post(EventHandler{ev.server->name(), ev.origin, ev.channel, - [=] (Plugin &) -> std::string { + irccd_.post(event_handler{ev.server->name(), ev.origin, ev.channel, + [=] (plugin&) -> std::string { return "onChannelNotice"; }, - [=] (Plugin &plugin) { - plugin.onChannelNotice(m_irccd, ev); + [=] (plugin& plugin) { + plugin.on_channel_notice(irccd_, ev); } }); } -void ServerService::handleConnect(const ConnectEvent &ev) +void server_service::handle_connect(const connect_event& ev) { log::debug() << "server " << ev.server->name() << ": event onConnect" << std::endl; - m_irccd.transports().broadcast(nlohmann::json::object({ + irccd_.transports().broadcast(nlohmann::json::object({ { "event", "onConnect" }, { "server", ev.server->name() } })); - m_irccd.post(EventHandler{ev.server->name(), /* origin */ "", /* channel */ "", - [=] (Plugin &) -> std::string { + irccd_.post(event_handler{ev.server->name(), /* origin */ "", /* channel */ "", + [=] (plugin&) -> std::string { return "onConnect"; }, - [=] (Plugin &plugin) { - plugin.onConnect(m_irccd, ev); + [=] (plugin& plugin) { + plugin.on_connect(irccd_, ev); } }); } -void ServerService::handleInvite(const InviteEvent &ev) +void server_service::handle_invite(const invite_event& ev) { log::debug() << "server " << ev.server->name() << ": event onInvite:\n"; log::debug() << " origin: " << ev.origin << "\n"; log::debug() << " channel: " << ev.channel << "\n"; log::debug() << " target: " << ev.nickname << std::endl; - m_irccd.transports().broadcast(nlohmann::json::object({ + irccd_.transports().broadcast(nlohmann::json::object({ { "event", "onInvite" }, { "server", ev.server->name() }, { "origin", ev.origin }, { "channel", ev.channel } })); - m_irccd.post(EventHandler{ev.server->name(), ev.origin, ev.channel, - [=] (Plugin &) -> std::string { + irccd_.post(event_handler{ev.server->name(), ev.origin, ev.channel, + [=] (plugin&) -> std::string { return "onInvite"; }, - [=] (Plugin &plugin) { - plugin.onInvite(m_irccd, ev); + [=] (plugin& plugin) { + plugin.on_invite(irccd_, ev); } }); } -void ServerService::handleJoin(const JoinEvent &ev) +void server_service::handle_join(const join_event& ev) { log::debug() << "server " << ev.server->name() << ": event onJoin:\n"; log::debug() << " origin: " << ev.origin << "\n"; log::debug() << " channel: " << ev.channel << std::endl; - m_irccd.transports().broadcast(nlohmann::json::object({ + irccd_.transports().broadcast(nlohmann::json::object({ { "event", "onJoin" }, { "server", ev.server->name() }, { "origin", ev.origin }, { "channel", ev.channel } })); - m_irccd.post(EventHandler{ev.server->name(), ev.origin, ev.channel, - [=] (Plugin &) -> std::string { + irccd_.post(event_handler{ev.server->name(), ev.origin, ev.channel, + [=] (plugin&) -> std::string { return "onJoin"; }, - [=] (Plugin &plugin) { - plugin.onJoin(m_irccd, ev); + [=] (plugin& plugin) { + plugin.on_join(irccd_, ev); } }); } -void ServerService::handleKick(const KickEvent &ev) +void server_service::handle_kick(const kick_event& ev) { log::debug() << "server " << ev.server->name() << ": event onKick:\n"; log::debug() << " origin: " << ev.origin << "\n"; @@ -543,7 +542,7 @@ log::debug() << " target: " << ev.target << "\n"; log::debug() << " reason: " << ev.reason << std::endl; - m_irccd.transports().broadcast(nlohmann::json::object({ + irccd_.transports().broadcast(nlohmann::json::object({ { "event", "onKick" }, { "server", ev.server->name() }, { "origin", ev.origin }, @@ -552,24 +551,24 @@ { "reason", ev.reason } })); - m_irccd.post(EventHandler{ev.server->name(), ev.origin, ev.channel, - [=] (Plugin &) -> std::string { + irccd_.post(event_handler{ev.server->name(), ev.origin, ev.channel, + [=] (plugin&) -> std::string { return "onKick"; }, - [=] (Plugin &plugin) { - plugin.onKick(m_irccd, ev); + [=] (plugin& plugin) { + plugin.on_kick(irccd_, ev); } }); } -void ServerService::handleMessage(const MessageEvent &ev) +void server_service::handle_message(const message_event& ev) { log::debug() << "server " << ev.server->name() << ": event onMessage:\n"; log::debug() << " origin: " << ev.origin << "\n"; log::debug() << " channel: " << ev.channel << "\n"; log::debug() << " message: " << ev.message << std::endl; - m_irccd.transports().broadcast(nlohmann::json::object({ + irccd_.transports().broadcast(nlohmann::json::object({ { "event", "onMessage" }, { "server", ev.server->name() }, { "origin", ev.origin }, @@ -577,32 +576,36 @@ { "message", ev.message } })); - m_irccd.post(EventHandler{ev.server->name(), ev.origin, ev.channel, - [=] (Plugin &plugin) -> std::string { - return util::parseMessage(ev.message, ev.server->commandCharacter(), plugin.name()).second == util::MessageType::Command ? "onCommand" : "onMessage"; + irccd_.post(event_handler{ev.server->name(), ev.origin, ev.channel, + [=] (plugin& plugin) -> std::string { + return util::parse_message( + ev.message, + ev.server->command_char(), + plugin.name() + ).type == util::message_pack::type::command ? "onCommand" : "onMessage"; }, - [=] (Plugin &plugin) mutable { + [=] (plugin& plugin) mutable { auto copy = ev; - auto pack = util::parseMessage(copy.message, copy.server->commandCharacter(), plugin.name()); + auto pack = util::parse_message(copy.message, copy.server->command_char(), plugin.name()); - copy.message = pack.first; + copy.message = pack.message; - if (pack.second == util::MessageType::Command) - plugin.onCommand(m_irccd, copy); + if (pack.type == util::message_pack::type::command) + plugin.on_command(irccd_, copy); else - plugin.onMessage(m_irccd, copy); + plugin.on_message(irccd_, copy); } }); } -void ServerService::handleMe(const MeEvent &ev) +void server_service::handle_me(const me_event& ev) { log::debug() << "server " << ev.server->name() << ": event onMe:\n"; log::debug() << " origin: " << ev.origin << "\n"; log::debug() << " target: " << ev.channel << "\n"; log::debug() << " message: " << ev.message << std::endl; - m_irccd.transports().broadcast(nlohmann::json::object({ + irccd_.transports().broadcast(nlohmann::json::object({ { "event", "onMe" }, { "server", ev.server->name() }, { "origin", ev.origin }, @@ -610,40 +613,40 @@ { "message", ev.message } })); - m_irccd.post(EventHandler{ev.server->name(), ev.origin, ev.channel, - [=] (Plugin &) -> std::string { + irccd_.post(event_handler{ev.server->name(), ev.origin, ev.channel, + [=] (plugin&) -> std::string { return "onMe"; }, - [=] (Plugin &plugin) { - plugin.onMe(m_irccd, ev); + [=] (plugin& plugin) { + plugin.on_me(irccd_, ev); } }); } -void ServerService::handleMode(const ModeEvent &ev) +void server_service::handle_mode(const mode_event& ev) { log::debug() << "server " << ev.server->name() << ": event onMode\n"; log::debug() << " origin: " << ev.origin << "\n"; log::debug() << " mode: " << ev.mode << std::endl; - m_irccd.transports().broadcast(nlohmann::json::object({ + irccd_.transports().broadcast(nlohmann::json::object({ { "event", "onMode" }, { "server", ev.server->name() }, { "origin", ev.origin }, { "mode", ev.mode } })); - m_irccd.post(EventHandler{ev.server->name(), ev.origin, /* channel */ "", - [=] (Plugin &) -> std::string { + irccd_.post(event_handler{ev.server->name(), ev.origin, /* channel */ "", + [=] (plugin &) -> std::string { return "onMode"; }, - [=] (Plugin &plugin) { - plugin.onMode(m_irccd, ev); + [=] (plugin &plugin) { + plugin.on_mode(irccd_, ev); } }); } -void ServerService::handleNames(const NamesEvent &ev) +void server_service::handle_names(const names_event& ev) { log::debug() << "server " << ev.server->name() << ": event onNames:\n"; log::debug() << " channel: " << ev.channel << "\n"; @@ -651,80 +654,80 @@ auto names = nlohmann::json::array(); - for (const auto &v : ev.names) + for (const auto& v : ev.names) names.push_back(v); - m_irccd.transports().broadcast(nlohmann::json::object({ + irccd_.transports().broadcast(nlohmann::json::object({ { "event", "onNames" }, { "server", ev.server->name() }, { "channel", ev.channel }, { "names", std::move(names) } })); - m_irccd.post(EventHandler{ev.server->name(), /* origin */ "", ev.channel, - [=] (Plugin &) -> std::string { + irccd_.post(event_handler{ev.server->name(), /* origin */ "", ev.channel, + [=] (plugin&) -> std::string { return "onNames"; }, - [=] (Plugin &plugin) { - plugin.onNames(m_irccd, ev); + [=] (plugin& plugin) { + plugin.on_names(irccd_, ev); } }); } -void ServerService::handleNick(const NickEvent &ev) +void server_service::handle_nick(const nick_event& ev) { log::debug() << "server " << ev.server->name() << ": event onNick:\n"; log::debug() << " origin: " << ev.origin << "\n"; log::debug() << " nickname: " << ev.nickname << std::endl; - m_irccd.transports().broadcast(nlohmann::json::object({ + irccd_.transports().broadcast(nlohmann::json::object({ { "event", "onNick" }, { "server", ev.server->name() }, { "origin", ev.origin }, { "nickname", ev.nickname } })); - m_irccd.post(EventHandler{ev.server->name(), ev.origin, /* channel */ "", - [=] (Plugin &) -> std::string { + irccd_.post(event_handler{ev.server->name(), ev.origin, /* channel */ "", + [=] (plugin&) -> std::string { return "onNick"; }, - [=] (Plugin &plugin) { - plugin.onNick(m_irccd, ev); + [=] (plugin& plugin) { + plugin.on_nick(irccd_, ev); } }); } -void ServerService::handleNotice(const NoticeEvent &ev) +void server_service::handle_notice(const notice_event& ev) { log::debug() << "server " << ev.server->name() << ": event onNotice:\n"; log::debug() << " origin: " << ev.origin << "\n"; log::debug() << " message: " << ev.message << std::endl; - m_irccd.transports().broadcast(nlohmann::json::object({ + irccd_.transports().broadcast(nlohmann::json::object({ { "event", "onNotice" }, { "server", ev.server->name() }, { "origin", ev.origin }, { "message", ev.message } })); - m_irccd.post(EventHandler{ev.server->name(), ev.origin, /* channel */ "", - [=] (Plugin &) -> std::string { + irccd_.post(event_handler{ev.server->name(), ev.origin, /* channel */ "", + [=] (plugin&) -> std::string { return "onNotice"; }, - [=] (Plugin &plugin) { - plugin.onNotice(m_irccd, ev); + [=] (plugin& plugin) { + plugin.on_notice(irccd_, ev); } }); } -void ServerService::handlePart(const PartEvent &ev) +void server_service::handle_part(const part_event& ev) { log::debug() << "server " << ev.server->name() << ": event onPart:\n"; log::debug() << " origin: " << ev.origin << "\n"; log::debug() << " channel: " << ev.channel << "\n"; log::debug() << " reason: " << ev.reason << std::endl; - m_irccd.transports().broadcast(nlohmann::json::object({ + irccd_.transports().broadcast(nlohmann::json::object({ { "event", "onPart" }, { "server", ev.server->name() }, { "origin", ev.origin }, @@ -732,55 +735,59 @@ { "reason", ev.reason } })); - m_irccd.post(EventHandler{ev.server->name(), ev.origin, ev.channel, - [=] (Plugin &) -> std::string { + irccd_.post(event_handler{ev.server->name(), ev.origin, ev.channel, + [=] (plugin&) -> std::string { return "onPart"; }, - [=] (Plugin &plugin) { - plugin.onPart(m_irccd, ev); + [=] (plugin& plugin) { + plugin.on_part(irccd_, ev); } }); } -void ServerService::handleQuery(const QueryEvent &ev) +void server_service::handle_query(const query_event& ev) { log::debug() << "server " << ev.server->name() << ": event onQuery:\n"; log::debug() << " origin: " << ev.origin << "\n"; log::debug() << " message: " << ev.message << std::endl; - m_irccd.transports().broadcast(nlohmann::json::object({ + irccd_.transports().broadcast(nlohmann::json::object({ { "event", "onQuery" }, { "server", ev.server->name() }, { "origin", ev.origin }, { "message", ev.message } })); - m_irccd.post(EventHandler{ev.server->name(), ev.origin, /* channel */ "", - [=] (Plugin &plugin) -> std::string { - return util::parseMessage(ev.message, ev.server->commandCharacter(), plugin.name()).second == util::MessageType::Command ? "onQueryCommand" : "onQuery"; + irccd_.post(event_handler{ev.server->name(), ev.origin, /* channel */ "", + [=] (plugin& plugin) -> std::string { + return util::parse_message( + ev.message, + ev.server->command_char(), + plugin.name() + ).type == util::message_pack::type::command ? "onQueryCommand" : "onQuery"; }, - [=] (Plugin &plugin) mutable { + [=] (plugin& plugin) mutable { auto copy = ev; - auto pack = util::parseMessage(copy.message, copy.server->commandCharacter(), plugin.name()); + auto pack = util::parse_message(copy.message, copy.server->command_char(), plugin.name()); - copy.message = pack.first; + copy.message = pack.message; - if (pack.second == util::MessageType::Command) - plugin.onQueryCommand(m_irccd, copy); + if (pack.type == util::message_pack::type::command) + plugin.on_query_command(irccd_, copy); else - plugin.onQuery(m_irccd, copy); + plugin.on_query(irccd_, copy); } }); } -void ServerService::handleTopic(const TopicEvent &ev) +void server_service::handle_topic(const topic_event& ev) { log::debug() << "server " << ev.server->name() << ": event onTopic:\n"; log::debug() << " origin: " << ev.origin << "\n"; log::debug() << " channel: " << ev.channel << "\n"; log::debug() << " topic: " << ev.topic << std::endl; - m_irccd.transports().broadcast(nlohmann::json::object({ + irccd_.transports().broadcast(nlohmann::json::object({ { "event", "onTopic" }, { "server", ev.server->name() }, { "origin", ev.origin }, @@ -788,17 +795,17 @@ { "topic", ev.topic } })); - m_irccd.post(EventHandler{ev.server->name(), ev.origin, ev.channel, - [=] (Plugin &) -> std::string { + irccd_.post(event_handler{ev.server->name(), ev.origin, ev.channel, + [=] (plugin&) -> std::string { return "onTopic"; }, - [=] (Plugin &plugin) { - plugin.onTopic(m_irccd, ev); + [=] (plugin& plugin) { + plugin.on_topic(irccd_, ev); } }); } -void ServerService::handleWhois(const WhoisEvent &ev) +void server_service::handle_whois(const whois_event& ev) { log::debug() << "server " << ev.server->name() << ": event onWhois\n"; log::debug() << " nickname: " << ev.whois.nick << "\n"; @@ -807,7 +814,7 @@ log::debug() << " realname: " << ev.whois.realname << "\n"; log::debug() << " channels: " << util::join(ev.whois.channels.begin(), ev.whois.channels.end()) << std::endl; - m_irccd.transports().broadcast(nlohmann::json::object({ + irccd_.transports().broadcast(nlohmann::json::object({ { "event", "onWhois" }, { "server", ev.server->name() }, { "nickname", ev.whois.nick }, @@ -816,93 +823,93 @@ { "realname", ev.whois.realname } })); - m_irccd.post(EventHandler{ev.server->name(), /* origin */ "", /* channel */ "", - [=] (Plugin &) -> std::string { + irccd_.post(event_handler{ev.server->name(), /* origin */ "", /* channel */ "", + [=] (plugin&) -> std::string { return "onWhois"; }, - [=] (Plugin &plugin) { - plugin.onWhois(m_irccd, ev); + [=] (plugin& plugin) { + plugin.on_whois(irccd_, ev); } }); } -ServerService::ServerService(Irccd &irccd) - : m_irccd(irccd) +server_service::server_service(irccd &irccd) + : irccd_(irccd) { } -void ServerService::prepare(fd_set &in, fd_set &out, net::Handle &max) +void server_service::prepare(fd_set& in, fd_set& out, net::Handle& max) { - for (auto &server : m_servers) { + for (auto& server : servers_) { server->update(); server->prepare(in, out, max); } } -void ServerService::sync(fd_set &in, fd_set &out) +void server_service::sync(fd_set& in, fd_set& out) { - for (auto &server : m_servers) + for (auto& server : servers_) server->sync(in, out); } -bool ServerService::has(const std::string &name) const noexcept +bool server_service::has(const std::string& name) const noexcept { - return std::count_if(m_servers.cbegin(), m_servers.end(), [&] (const auto &server) { + return std::count_if(servers_.cbegin(), servers_.end(), [&] (const auto& server) { return server->name() == name; }) > 0; } -void ServerService::add(std::shared_ptr<Server> server) +void server_service::add(std::shared_ptr<server> server) { assert(!has(server->name())); using namespace std::placeholders; - std::weak_ptr<Server> ptr(server); + std::weak_ptr<class server> ptr(server); - server->onChannelMode.connect(std::bind(&ServerService::handleChannelMode, this, _1)); - server->onChannelNotice.connect(std::bind(&ServerService::handleChannelNotice, this, _1)); - server->onConnect.connect(std::bind(&ServerService::handleConnect, this, _1)); - server->onInvite.connect(std::bind(&ServerService::handleInvite, this, _1)); - server->onJoin.connect(std::bind(&ServerService::handleJoin, this, _1)); - server->onKick.connect(std::bind(&ServerService::handleKick, this, _1)); - server->onMessage.connect(std::bind(&ServerService::handleMessage, this, _1)); - server->onMe.connect(std::bind(&ServerService::handleMe, this, _1)); - server->onMode.connect(std::bind(&ServerService::handleMode, this, _1)); - server->onNames.connect(std::bind(&ServerService::handleNames, this, _1)); - server->onNick.connect(std::bind(&ServerService::handleNick, this, _1)); - server->onNotice.connect(std::bind(&ServerService::handleNotice, this, _1)); - server->onPart.connect(std::bind(&ServerService::handlePart, this, _1)); - server->onQuery.connect(std::bind(&ServerService::handleQuery, this, _1)); - server->onTopic.connect(std::bind(&ServerService::handleTopic, this, _1)); - server->onWhois.connect(std::bind(&ServerService::handleWhois, this, _1)); - server->onDie.connect([this, ptr] () { - m_irccd.post([=] (Irccd &) { + server->on_channel_mode.connect(std::bind(&server_service::handle_channel_mode, this, _1)); + server->on_channel_notice.connect(std::bind(&server_service::handle_channel_notice, this, _1)); + server->on_connect.connect(std::bind(&server_service::handle_connect, this, _1)); + server->on_invite.connect(std::bind(&server_service::handle_invite, this, _1)); + server->on_join.connect(std::bind(&server_service::handle_join, this, _1)); + server->on_kick.connect(std::bind(&server_service::handle_kick, this, _1)); + server->on_message.connect(std::bind(&server_service::handle_message, this, _1)); + server->on_me.connect(std::bind(&server_service::handle_me, this, _1)); + server->on_mode.connect(std::bind(&server_service::handle_mode, this, _1)); + server->on_names.connect(std::bind(&server_service::handle_names, this, _1)); + server->on_nick.connect(std::bind(&server_service::handle_nick, this, _1)); + server->on_notice.connect(std::bind(&server_service::handle_notice, this, _1)); + server->on_part.connect(std::bind(&server_service::handle_part, this, _1)); + server->on_query.connect(std::bind(&server_service::handle_query, this, _1)); + server->on_topic.connect(std::bind(&server_service::handle_topic, this, _1)); + server->on_whois.connect(std::bind(&server_service::handle_whois, this, _1)); + server->on_die.connect([this, ptr] () { + irccd_.post([=] (irccd&) { auto server = ptr.lock(); if (server) { log::info("server {}: removed"_format(server->name())); - m_servers.erase(std::find(m_servers.begin(), m_servers.end(), server)); + servers_.erase(std::find(servers_.begin(), servers_.end(), server)); } }); }); - m_servers.push_back(std::move(server)); + servers_.push_back(std::move(server)); } -std::shared_ptr<Server> ServerService::get(const std::string &name) const noexcept +std::shared_ptr<server> server_service::get(const std::string& name) const noexcept { - auto it = std::find_if(m_servers.begin(), m_servers.end(), [&] (const auto &server) { + auto it = std::find_if(servers_.begin(), servers_.end(), [&] (const auto& server) { return server->name() == name; }); - if (it == m_servers.end()) + if (it == servers_.end()) return nullptr; return *it; } -std::shared_ptr<Server> ServerService::require(const std::string &name) const +std::shared_ptr<server> server_service::require(const std::string& name) const { auto server = get(name); @@ -912,36 +919,36 @@ return server; } -void ServerService::remove(const std::string &name) +void server_service::remove(const std::string& name) { - auto it = std::find_if(m_servers.begin(), m_servers.end(), [&] (const auto &server) { + auto it = std::find_if(servers_.begin(), servers_.end(), [&] (const auto& server) { return server->name() == name; }); - if (it != m_servers.end()) { + if (it != servers_.end()) { (*it)->disconnect(); - m_servers.erase(it); + servers_.erase(it); } } -void ServerService::clear() noexcept +void server_service::clear() noexcept { - for (auto &server : m_servers) + for (auto &server : servers_) server->disconnect(); - m_servers.clear(); + servers_.clear(); } /* - * TransportService. + * transport_service. * ------------------------------------------------------------------ */ -void TransportService::handleCommand(std::weak_ptr<TransportClient> ptr, const nlohmann::json &object) +void transport_service::handle_command(std::weak_ptr<transport_client> ptr, const nlohmann::json& object) { assert(object.is_object()); - m_irccd.post([=] (Irccd &) { + irccd_.post([=] (irccd&) { // 0. Be sure the object still exists. auto tc = ptr.lock(); @@ -955,41 +962,41 @@ return; } - auto cmd = m_irccd.commands().find(*name); + auto cmd = irccd_.commands().find(*name); if (!cmd) tc->error(*name, "command does not exist"); else { try { - cmd->exec(m_irccd, *tc, object); - } catch (const std::exception &ex) { + cmd->exec(irccd_, *tc, object); + } catch (const std::exception& ex) { tc->error(cmd->name(), ex.what()); } } }); } -void TransportService::handleDie(std::weak_ptr<TransportClient> ptr) +void transport_service::handle_die(std::weak_ptr<transport_client> ptr) { - m_irccd.post([=] (Irccd &) { + irccd_.post([=] (irccd &) { log::info("transport: client disconnected"); auto tc = ptr.lock(); if (tc) - m_clients.erase(std::find(m_clients.begin(), m_clients.end(), tc)); + clients_.erase(std::find(clients_.begin(), clients_.end(), tc)); }); } -TransportService::TransportService(Irccd &irccd) noexcept - : m_irccd(irccd) +transport_service::transport_service(irccd& irccd) noexcept + : irccd_(irccd) { } -void TransportService::prepare(fd_set &in, fd_set &out, net::Handle &max) +void transport_service::prepare(fd_set& in, fd_set& out, net::Handle& max) { // Add transport servers. - for (const auto &transport : m_servers) { + for (const auto& transport : servers_) { FD_SET(transport->handle(), &in); if (transport->handle() > max) @@ -997,58 +1004,58 @@ } // Transport clients. - for (const auto &client : m_clients) + for (const auto& client : clients_) client->prepare(in, out, max); } -void TransportService::sync(fd_set &in, fd_set &out) +void transport_service::sync(fd_set& in, fd_set& out) { using namespace std::placeholders; // Transport clients. - for (const auto &client : m_clients) { + for (const auto& client : clients_) { try { client->sync(in, out); - } catch (const std::exception &ex) { + } catch (const std::exception& ex) { log::info() << "transport: client disconnected: " << ex.what() << std::endl; - handleDie(client); + handle_die(client); } } // Transport servers. - for (const auto &transport : m_servers) { + for (const auto& transport : servers_) { if (!FD_ISSET(transport->handle(), &in)) continue; log::debug("transport: new client connected"); - std::shared_ptr<TransportClient> client = transport->accept(); - std::weak_ptr<TransportClient> ptr(client); + std::shared_ptr<transport_client> client = transport->accept(); + std::weak_ptr<transport_client> ptr(client); try { // Connect signals. - client->onCommand.connect(std::bind(&TransportService::handleCommand, this, ptr, _1)); - client->onDie.connect(std::bind(&TransportService::handleDie, this, ptr)); + client->on_command.connect(std::bind(&transport_service::handle_command, this, ptr, _1)); + client->on_die.connect(std::bind(&transport_service::handle_die, this, ptr)); // Register it. - m_clients.push_back(std::move(client)); - } catch (const std::exception &ex) { + clients_.push_back(std::move(client)); + } catch (const std::exception& ex) { log::info() << "transport: client disconnected: " << ex.what() << std::endl; } } } -void TransportService::add(std::shared_ptr<TransportServer> ts) +void transport_service::add(std::shared_ptr<transport_server> ts) { - m_servers.push_back(std::move(ts)); + servers_.push_back(std::move(ts)); } -void TransportService::broadcast(const nlohmann::json &json) +void transport_service::broadcast(const nlohmann::json& json) { assert(json.is_object()); - for (const auto &client : m_clients) - if (client->state() == TransportClient::Ready) + for (const auto& client : clients_) + if (client->state() == transport_client::state::ready) client->send(json); }
--- a/libirccd/irccd/service.hpp Fri Aug 11 13:45:42 2017 +0200 +++ b/libirccd/irccd/service.hpp Tue Sep 26 17:18:47 2017 +0200 @@ -21,7 +21,7 @@ /** * \file service.hpp - * \brief Irccd services. + * \brief irccd services. */ #include <memory> @@ -40,7 +40,7 @@ namespace irccd { /* - * CommandService. + * command_service. * ------------------------------------------------------------------ */ @@ -48,9 +48,9 @@ * \brief Store remote commands. * \ingroup services */ -class CommandService { +class command_service { private: - std::vector<std::shared_ptr<Command>> m_commands; + std::vector<std::shared_ptr<command>> commands_; public: /** @@ -58,9 +58,9 @@ * * \return the list of commands. */ - inline const std::vector<std::shared_ptr<Command>> &commands() const noexcept + inline const std::vector<std::shared_ptr<command>>& commands() const noexcept { - return m_commands; + return commands_; } /** @@ -69,7 +69,7 @@ * \param name the command name * \return true if the command exists */ - IRCCD_EXPORT bool contains(const std::string &name) const noexcept; + bool contains(const std::string& name) const noexcept; /** * Find a command by name. @@ -77,7 +77,7 @@ * \param name the command name * \return the command or empty one if not found */ - IRCCD_EXPORT std::shared_ptr<Command> find(const std::string &name) const noexcept; + std::shared_ptr<command> find(const std::string& name) const noexcept; /** * Add a command or replace existing one. @@ -85,11 +85,11 @@ * \pre command != nullptr * \param command the command name */ - IRCCD_EXPORT void add(std::shared_ptr<Command> command); + void add(std::shared_ptr<command> command); }; /* - * InterruptService. + * interrupt_service. * ------------------------------------------------------------------ */ @@ -97,10 +97,10 @@ * \brief Interrupt irccd event loop. * \ingroup services */ -class InterruptService { +class interrupt_service { private: - net::TcpSocket m_in; - net::TcpSocket m_out; + net::TcpSocket in_; + net::TcpSocket out_; public: /** @@ -108,26 +108,26 @@ * * \throw std::runtime_error on errors */ - IRCCD_EXPORT InterruptService(); + interrupt_service(); /** * \copydoc Service::prepare */ - IRCCD_EXPORT void prepare(fd_set &in, fd_set &out, net::Handle &max); + void prepare(fd_set& in, fd_set& out, net::Handle& max); /** * \copydoc Service::sync */ - IRCCD_EXPORT void sync(fd_set &in, fd_set &out); + void sync(fd_set& in, fd_set& out); /** * Request interruption. */ - IRCCD_EXPORT void interrupt() noexcept; + void interrupt() noexcept; }; /* - * PluginService. + * plugin_service. * ------------------------------------------------------------------ */ @@ -135,15 +135,15 @@ * \brief Manage plugins. * \ingroup services */ -class PluginService { +class plugin_service { private: - Irccd &m_irccd; - PluginPaths m_default_paths; - std::vector<std::shared_ptr<Plugin>> m_plugins; - std::vector<std::unique_ptr<PluginLoader>> m_loaders; - std::unordered_map<std::string, PluginConfig> m_config; - std::unordered_map<std::string, PluginFormats> m_formats; - std::unordered_map<std::string, PluginPaths> m_paths; + irccd& irccd_; + plugin_paths default_paths_; + std::vector<std::shared_ptr<plugin>> plugins_; + std::vector<std::unique_ptr<plugin_loader>> loaders_; + std::unordered_map<std::string, plugin_config> config_; + std::unordered_map<std::string, plugin_formats> formats_; + std::unordered_map<std::string, plugin_paths> paths_; public: /** @@ -151,21 +151,21 @@ * * \param irccd the irccd instance */ - IRCCD_EXPORT PluginService(Irccd &irccd) noexcept; + plugin_service(irccd& irccd) noexcept; /** * Destroy plugins. */ - IRCCD_EXPORT ~PluginService(); + ~plugin_service(); /** * Get the list of plugins. * * \return the list of plugins */ - inline const std::vector<std::shared_ptr<Plugin>> &list() const noexcept + inline const std::vector<std::shared_ptr<plugin>>& list() const noexcept { - return m_plugins; + return plugins_; } /** @@ -174,7 +174,7 @@ * \param name the plugin id * \return true if has plugin */ - IRCCD_EXPORT bool has(const std::string &name) const noexcept; + bool has(const std::string& name) const noexcept; /** * Get a loaded plugin or null if not found. @@ -182,7 +182,7 @@ * \param name the plugin id * \return the plugin or empty one if not found */ - IRCCD_EXPORT std::shared_ptr<Plugin> get(const std::string &name) const noexcept; + std::shared_ptr<plugin> get(const std::string& name) const noexcept; /** * Find a loaded plugin. @@ -191,7 +191,7 @@ * \return the plugin * \throws std::out_of_range if not found */ - IRCCD_EXPORT std::shared_ptr<Plugin> require(const std::string &name) const; + std::shared_ptr<plugin> require(const std::string& name) const; /** * Add the specified plugin to the registry. @@ -200,14 +200,14 @@ * \param plugin the plugin * \note the plugin is only added to the list, no action is performed on it */ - IRCCD_EXPORT void add(std::shared_ptr<Plugin> plugin); + void add(std::shared_ptr<plugin> plugin); /** * Add a loader. * * \param loader the loader */ - IRCCD_EXPORT void addLoader(std::unique_ptr<PluginLoader> loader); + void add_loader(std::unique_ptr<plugin_loader> loader); /** * Configure a plugin. @@ -217,7 +217,7 @@ * \param name the plugin name * \param config the new configuration */ - IRCCD_EXPORT void setConfig(const std::string &name, PluginConfig config); + void set_config(const std::string& name, plugin_config config); /** * Get a configuration for a plugin. @@ -225,7 +225,7 @@ * \param name the plugin name * \return the configuration or default one if not found */ - IRCCD_EXPORT PluginConfig config(const std::string &name) const; + plugin_config config(const std::string& name) const; /** * Add formatting for a plugin. @@ -233,7 +233,7 @@ * \param name the plugin name * \param formats the formats */ - IRCCD_EXPORT void setFormats(const std::string &name, PluginFormats formats); + void set_formats(const std::string& name, plugin_formats formats); /** * Get formats for a plugin. @@ -241,14 +241,14 @@ * \param name the plugin name * \return the formats */ - IRCCD_EXPORT PluginFormats formats(const std::string &name) const; + plugin_formats formats(const std::string& name) const; /** * Get the default paths for plugins. * * \return the paths */ - IRCCD_EXPORT const PluginPaths& paths() const noexcept; + const plugin_paths& paths() const noexcept; /** * Get the paths for the specified plugin. @@ -256,14 +256,14 @@ * \param name the plugin * \return the paths */ - IRCCD_EXPORT PluginPaths paths(const std::string& name) const; + plugin_paths paths(const std::string& name) const; /** * Set default paths. * * \param paths the default paths (for all plugins) */ - IRCCD_EXPORT void setPaths(PluginPaths paths); + void set_paths(plugin_paths paths); /** * Override paths for the specified plugin. @@ -271,20 +271,20 @@ * \param name the plugin name * \param paths the paths */ - void setPaths(const std::string& name, PluginPaths paths); + void set_paths(const std::string& name, plugin_paths paths); /** * Generic function for opening the plugin at the given path. * - * This function will search for every PluginLoader and call open() on it, + * This function will search for every pluginLoader and call open() on it, * the first one that success will be returned. * * \param id the plugin id * \param path the path to the file * \return the plugin or nullptr on failures */ - IRCCD_EXPORT std::shared_ptr<Plugin> open(const std::string &id, - const std::string &path); + std::shared_ptr<plugin> open(const std::string& id, + const std::string& path); /** * Generic function for finding a plugin. @@ -292,7 +292,7 @@ * \param id the plugin id * \return the plugin or nullptr on failures */ - IRCCD_EXPORT std::shared_ptr<Plugin> find(const std::string &id); + std::shared_ptr<plugin> find(const std::string& id); /** * Convenient wrapper that loads a plugin, call onLoad and add it to the @@ -303,14 +303,14 @@ * \param name the name * \param path the optional path (searched if empty) */ - IRCCD_EXPORT void load(std::string name, std::string path = ""); + void load(std::string name, std::string path = ""); /** * Unload a plugin and remove it. * * \param name the plugin id */ - IRCCD_EXPORT void unload(const std::string &name); + void unload(const std::string& name); /** * Reload a plugin by calling onReload. @@ -318,11 +318,11 @@ * \param name the plugin name * \throw std::exception on failures */ - IRCCD_EXPORT void reload(const std::string &name); + void reload(const std::string& name); }; /* - * RuleService. + * rule_service. * ------------------------------------------------------------------ */ @@ -330,9 +330,9 @@ * \brief Store and solve rules. * \ingroup services */ -class RuleService { +class rule_service { private: - std::vector<Rule> m_rules; + std::vector<rule> rules_; public: /** @@ -340,9 +340,9 @@ * * \return the list of rules */ - inline const std::vector<Rule> &list() const noexcept + inline const std::vector<rule>& list() const noexcept { - return m_rules; + return rules_; } /** @@ -352,7 +352,7 @@ */ inline std::size_t length() const noexcept { - return m_rules.size(); + return rules_.size(); } /** @@ -360,7 +360,7 @@ * * \param rule the rule to append */ - IRCCD_EXPORT void add(Rule rule); + void add(rule rule); /** * Insert a new rule at the specified position. @@ -368,7 +368,7 @@ * \param rule the rule * \param position the position */ - IRCCD_EXPORT void insert(Rule rule, unsigned position); + void insert(rule rule, unsigned position); /** * Remove a new rule from the specified position. @@ -376,7 +376,7 @@ * \pre position must be valid * \param position the position */ - IRCCD_EXPORT void remove(unsigned position); + void remove(unsigned position); /** * Get a rule at the specified index or throw an exception if not found. @@ -385,14 +385,14 @@ * \return the rule * \throw std::out_of_range if position is invalid */ - IRCCD_EXPORT const Rule &require(unsigned position) const; + const rule& require(unsigned position) const; /** * Overloaded function. * * \copydoc require */ - IRCCD_EXPORT Rule& require(unsigned position); + rule& require(unsigned position); /** * Resolve the action to execute with the specified list of rules. @@ -404,15 +404,15 @@ * \param event the event name (e.g onKick) * \return true if the plugin must be called */ - IRCCD_EXPORT bool solve(const std::string &server, - const std::string &channel, - const std::string &origin, - const std::string &plugin, - const std::string &event) noexcept; + bool solve(const std::string& server, + const std::string& channel, + const std::string& origin, + const std::string& plugin, + const std::string& event) noexcept; }; /* - * ServerService. + * server_service. * ------------------------------------------------------------------ */ @@ -420,52 +420,52 @@ * \brief Manage IRC servers. * \ingroup services */ -class ServerService { +class server_service { private: - Irccd &m_irccd; - std::vector<std::shared_ptr<Server>> m_servers; + irccd& irccd_; + std::vector<std::shared_ptr<server>> servers_; - void handleChannelMode(const ChannelModeEvent &); - void handleChannelNotice(const ChannelNoticeEvent &); - void handleConnect(const ConnectEvent &); - void handleInvite(const InviteEvent &); - void handleJoin(const JoinEvent &); - void handleKick(const KickEvent &); - void handleMessage(const MessageEvent &); - void handleMe(const MeEvent &); - void handleMode(const ModeEvent &); - void handleNames(const NamesEvent &); - void handleNick(const NickEvent &); - void handleNotice(const NoticeEvent &); - void handlePart(const PartEvent &); - void handleQuery(const QueryEvent &); - void handleTopic(const TopicEvent &); - void handleWhois(const WhoisEvent &); + void handle_channel_mode(const channel_mode_event&); + void handle_channel_notice(const channel_notice_event&); + void handle_connect(const connect_event&); + void handle_invite(const invite_event&); + void handle_join(const join_event&); + void handle_kick(const kick_event&); + void handle_message(const message_event&); + void handle_me(const me_event&); + void handle_mode(const mode_event&); + void handle_names(const names_event&); + void handle_nick(const nick_event&); + void handle_notice(const notice_event&); + void handle_part(const part_event&); + void handle_query(const query_event&); + void handle_topic(const topic_event&); + void handle_whois(const whois_event&); public: /** * Create the server service. */ - IRCCD_EXPORT ServerService(Irccd &instance); + server_service(irccd& instance); /** * \copydoc Service::prepare */ - IRCCD_EXPORT void prepare(fd_set &in, fd_set &out, net::Handle &max); + void prepare(fd_set& in, fd_set& out, net::Handle& max); /** * \copydoc Service::sync */ - IRCCD_EXPORT void sync(fd_set &in, fd_set &out); + void sync(fd_set& in, fd_set& out); /** * Get the list of servers * * \return the servers */ - inline const std::vector<std::shared_ptr<Server>> &servers() const noexcept + inline const std::vector<std::shared_ptr<server>>& servers() const noexcept { - return m_servers; + return servers_; } /** @@ -474,7 +474,7 @@ * \param name the name * \return true if exists */ - IRCCD_EXPORT bool has(const std::string &name) const noexcept; + bool has(const std::string& name) const noexcept; /** * Add a new server to the application. @@ -482,7 +482,7 @@ * \pre hasServer must return false * \param sv the server */ - IRCCD_EXPORT void add(std::shared_ptr<Server> sv); + void add(std::shared_ptr<server> sv); /** * Get a server or empty one if not found @@ -490,7 +490,7 @@ * \param name the server name * \return the server or empty one if not found */ - IRCCD_EXPORT std::shared_ptr<Server> get(const std::string &name) const noexcept; + std::shared_ptr<server> get(const std::string& name) const noexcept; /** * Find a server by name. @@ -499,7 +499,7 @@ * \return the server * \throw std::out_of_range if the server does not exist */ - IRCCD_EXPORT std::shared_ptr<Server> require(const std::string &name) const; + std::shared_ptr<server> require(const std::string& name) const; /** * Remove a server from the irccd instance. @@ -508,37 +508,37 @@ * * \param name the server name */ - IRCCD_EXPORT void remove(const std::string &name); + void remove(const std::string& name); /** * Remove all servers. * * All servers will be disconnected. */ - IRCCD_EXPORT void clear() noexcept; + void clear() noexcept; }; /* - * TransportService. + * transport_service. * ------------------------------------------------------------------ */ -class TransportServer; -class TransportClient; +class transport_server; +class transport_client; /** * \brief manage transport servers and clients. * \ingroup services */ -class TransportService { +class transport_service { private: - Irccd &m_irccd; + irccd& irccd_; - std::vector<std::shared_ptr<TransportServer>> m_servers; - std::vector<std::shared_ptr<TransportClient>> m_clients; + std::vector<std::shared_ptr<transport_server>> servers_; + std::vector<std::shared_ptr<transport_client>> clients_; - void handleCommand(std::weak_ptr<TransportClient>, const nlohmann::json &); - void handleDie(std::weak_ptr<TransportClient>); + void handle_command(std::weak_ptr<transport_client>, const nlohmann::json&); + void handle_die(std::weak_ptr<transport_client>); public: /** @@ -546,24 +546,24 @@ * * \param irccd the irccd instance */ - IRCCD_EXPORT TransportService(Irccd &irccd) noexcept; + transport_service(irccd& irccd) noexcept; /** * \copydoc Service::prepare */ - IRCCD_EXPORT void prepare(fd_set &in, fd_set &out, net::Handle &max); + void prepare(fd_set& in, fd_set& out, net::Handle& max); /** * \copydoc Service::sync */ - IRCCD_EXPORT void sync(fd_set &in, fd_set &out); + void sync(fd_set& in, fd_set& out); /** * Add a transport server. * * \param ts the transport server */ - IRCCD_EXPORT void add(std::shared_ptr<TransportServer> ts); + void add(std::shared_ptr<transport_server> ts); /** * Send data to all clients. @@ -571,7 +571,7 @@ * \pre object.is_object() * \param object the json object */ - IRCCD_EXPORT void broadcast(const nlohmann::json &object); + void broadcast(const nlohmann::json& object); }; } // !irccd
--- a/libirccd/irccd/transport.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/libirccd/irccd/transport.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -24,23 +24,23 @@ namespace irccd { /* - * TransportClient + * transport_client * ------------------------------------------------------------------ */ -void TransportClient::error(const std::string &msg) +void transport_client::error(const std::string& msg) { - m_state = Closing; + state_ = state::closing; send({{ "error", msg }}); } -void TransportClient::flush() noexcept +void transport_client::flush() noexcept { - for (std::size_t pos; (pos = m_input.find("\r\n\r\n")) != std::string::npos; ) { - auto message = m_input.substr(0, pos); + for (std::size_t pos; (pos = input_.find("\r\n\r\n")) != std::string::npos; ) { + auto message = input_.substr(0, pos); - m_input.erase(m_input.begin(), m_input.begin() + pos + 4); + input_.erase(input_.begin(), input_.begin() + pos + 4); try { auto document = nlohmann::json::parse(message); @@ -48,23 +48,23 @@ if (!document.is_object()) error("invalid argument"); else - onCommand(document); - } catch (const std::exception &ex) { + on_command(document); + } catch (const std::exception& ex) { error(ex.what()); } } } -void TransportClient::authenticate() noexcept +void transport_client::authenticate() noexcept { - auto pos = m_input.find("\r\n\r\n"); + auto pos = input_.find("\r\n\r\n"); if (pos == std::string::npos) return; - auto msg = m_input.substr(0, pos); + auto msg = input_.substr(0, pos); - m_input.erase(m_input.begin(), m_input.begin() + pos + 4); + input_.erase(input_.begin(), input_.begin() + pos + 4); try { auto doc = nlohmann::json::parse(msg); @@ -80,22 +80,22 @@ auto pw = doc.find("password"); auto result = true; - if (pw == doc.end() || !pw->is_string() || *pw != m_parent.password()) { - m_state = Closing; + if (pw == doc.end() || !pw->is_string() || *pw != parent_.password()) { + state_ = state::closing; result = false; } else - m_state = Ready; + state_ = state::ready; send({ { "response", "auth" }, { "result", result } }); - } catch (const std::exception &ex) { + } catch (const std::exception& ex) { error(ex.what()); } } -void TransportClient::recv() noexcept +void transport_client::recv() noexcept { try { std::string buffer; @@ -104,45 +104,45 @@ buffer.resize(recv(&buffer[0], buffer.size())); if (buffer.empty()) - onDie(); + on_die(); - m_input += std::move(buffer); + input_ += std::move(buffer); } catch (const std::exception &) { - onDie(); + on_die(); } } -void TransportClient::send() noexcept +void transport_client::send() noexcept { try { - auto ns = send(&m_output[0], m_output.size()); + auto ns = send(&output_[0], output_.size()); if (ns == 0) - onDie(); + on_die(); - m_output.erase(0, ns); - } catch (const std::exception &ex) { - onDie(); + output_.erase(0, ns); + } catch (const std::exception&) { + on_die(); } } -unsigned TransportClient::recv(void *buffer, unsigned length) +unsigned transport_client::recv(void* buffer, unsigned length) { - return m_socket.recv(buffer, length); + return socket_.recv(buffer, length); } -unsigned TransportClient::send(const void *buffer, unsigned length) +unsigned transport_client::send(const void* buffer, unsigned length) { - return m_socket.send(buffer, length); + return socket_.send(buffer, length); } -TransportClient::TransportClient(TransportServer &parent, net::TcpSocket socket) - : m_parent(parent) - , m_socket(std::move(socket)) +transport_client::transport_client(transport_server& parent, net::TcpSocket socket) + : parent_(parent) + , socket_(std::move(socket)) { - assert(m_socket.isOpen()); + assert(socket_.isOpen()); - m_socket.set(net::option::SockBlockMode(false)); + socket_.set(net::option::SockBlockMode(false)); // Send some information. auto object = nlohmann::json::object({ @@ -162,65 +162,65 @@ send(object); } -void TransportClient::prepare(fd_set &in, fd_set &out, net::Handle &max) +void transport_client::prepare(fd_set& in, fd_set& out, net::Handle& max) { - if (m_socket.handle() > max) - max = m_socket.handle(); + if (socket_.handle() > max) + max = socket_.handle(); - switch (m_state) { - case Greeting: - FD_SET(m_socket.handle(), &in); - FD_SET(m_socket.handle(), &out); + switch (state_) { + case state::greeting: + FD_SET(socket_.handle(), &in); + FD_SET(socket_.handle(), &out); break; - case Authenticating: - FD_SET(m_socket.handle(), &in); + case state::authenticating: + FD_SET(socket_.handle(), &in); break; - case Ready: - FD_SET(m_socket.handle(), &in); + case state::ready: + FD_SET(socket_.handle(), &in); - if (!m_output.empty()) - FD_SET(m_socket.handle(), &out); + if (!output_.empty()) + FD_SET(socket_.handle(), &out); break; - case Closing: - if (!m_output.empty()) - FD_SET(m_socket.handle(), &out); + case state::closing: + if (!output_.empty()) + FD_SET(socket_.handle(), &out); else - onDie(); + on_die(); break; default: break; } } -void TransportClient::sync(fd_set &in, fd_set &out) +void transport_client::sync(fd_set& in, fd_set& out) { - switch (m_state) { - case Greeting: - if (FD_ISSET(m_socket.handle(), &in)) + switch (state_) { + case state::greeting: + if (FD_ISSET(socket_.handle(), &in)) recv(); - else if (FD_ISSET(m_socket.handle(), &out)) + else if (FD_ISSET(socket_.handle(), &out)) send(); - if (m_output.empty()) - m_state = m_parent.password().empty() ? Ready : Authenticating; + if (output_.empty()) + state_ = parent_.password().empty() ? state::ready : state::authenticating; break; - case Authenticating: - if (FD_ISSET(m_socket.handle(), &in)) + case state::authenticating: + if (FD_ISSET(socket_.handle(), &in)) recv(); authenticate(); break; - case Ready: - if (FD_ISSET(m_socket.handle(), &in)) + case state::ready: + if (FD_ISSET(socket_.handle(), &in)) recv(); - if (FD_ISSET(m_socket.handle(), &out)) + if (FD_ISSET(socket_.handle(), &out)) send(); flush(); break; - case Closing: - if (FD_ISSET(m_socket.handle(), &out)) + case state::closing: + if (FD_ISSET(socket_.handle(), &out)) send(); break; default: @@ -228,15 +228,15 @@ } } -void TransportClient::send(const nlohmann::json &json) +void transport_client::send(const nlohmann::json& json) { assert(json.is_object()); - m_output += json.dump(); - m_output += "\r\n\r\n"; + output_ += json.dump(); + output_ += "\r\n\r\n"; } -void TransportClient::success(const std::string &cmd, nlohmann::json extra) +void transport_client::success(const std::string& cmd, nlohmann::json extra) { assert(extra.is_object() || extra.is_null()); @@ -246,11 +246,11 @@ extra["command"] = cmd; extra["status"] = true; - m_output += extra.dump(); - m_output += "\r\n\r\n"; + output_ += extra.dump(); + output_ += "\r\n\r\n"; } -void TransportClient::error(const std::string &cmd, const std::string &error, nlohmann::json extra) +void transport_client::error(const std::string& cmd, const std::string& error, nlohmann::json extra) { assert(extra.is_object() || extra.is_null()); @@ -261,141 +261,145 @@ extra["status"] = false; extra["error"] = error; - m_output += extra.dump(); - m_output += "\r\n\r\n"; + output_ += extra.dump(); + output_ += "\r\n\r\n"; } /* - * TransportClientTls + * transport_client_tls * ------------------------------------------------------------------ */ #if defined(WITH_SSL) -void TransportClientTls::handshake() +void transport_client_tls::handshake() { try { - m_ssl.handshake(); - m_handshake = HandshakeReady; - } catch (const net::WantReadError &) { - m_handshake = HandshakeRead; - } catch (const net::WantWriteError &) { - m_handshake = HandshakeWrite; - } catch (const std::exception &) { - onDie(); + ssl_.handshake(); + handshake_ = handshake::ready; + } catch (const net::WantReadError&) { + handshake_ = handshake::read; + } catch (const net::WantWriteError&) { + handshake_ = handshake::write; + } catch (const std::exception&) { + on_die(); } } -TransportClientTls::TransportClientTls(const std::string &pkey, - const std::string &cert, - TransportServer &server, - net::TcpSocket socket) - : TransportClient(server, std::move(socket)) - , m_ssl(m_socket) +transport_client_tls::transport_client_tls(const std::string& pkey, + const std::string& cert, + transport_server& parent, + net::TcpSocket socket) + : transport_client(parent, std::move(socket)) + , ssl_(socket_) { - m_ssl.setPrivateKey(pkey); - m_ssl.setCertificate(cert); + ssl_.setPrivateKey(pkey); + ssl_.setCertificate(cert); handshake(); } -unsigned TransportClientTls::recv(void *buffer, unsigned length) +unsigned transport_client_tls::recv(void* buffer, unsigned length) { unsigned nread = 0; try { - nread = m_ssl.recv(buffer, length); - } catch (const net::WantReadError &) { - m_handshake = HandshakeRead; - } catch (const net::WantWriteError &) { - m_handshake = HandshakeWrite; + nread = ssl_.recv(buffer, length); + } catch (const net::WantReadError&) { + handshake_ = handshake::read; + } catch (const net::WantWriteError&) { + handshake_ = handshake::write; + } catch (const std::exception&) { + on_die(); } return nread; } -unsigned TransportClientTls::send(const void *buffer, unsigned length) +unsigned transport_client_tls::send(const void* buffer, unsigned length) { unsigned nsent = 0; try { - nsent = m_ssl.send(buffer, length); - } catch (const net::WantReadError &) { - m_handshake = HandshakeRead; + nsent = ssl_.send(buffer, length); + } catch (const net::WantReadError&) { + handshake_ = handshake::read; } catch (const net::WantWriteError &) { - m_handshake = HandshakeWrite; + handshake_ = handshake::write; + } catch (const std::exception&) { + on_die(); } return nsent; } -void TransportClientTls::prepare(fd_set &in, fd_set &out, net::Handle &max) +void transport_client_tls::prepare(fd_set& in, fd_set& out, net::Handle& max) { - if (m_socket.handle() > max) - max = m_socket.handle(); + if (socket_.handle() > max) + max = socket_.handle(); - switch (m_handshake) { - case HandshakeRead: - FD_SET(m_socket.handle(), &in); + switch (handshake_) { + case handshake::read: + FD_SET(socket_.handle(), &in); break; - case HandshakeWrite: - FD_SET(m_socket.handle(), &out); + case handshake::write: + FD_SET(socket_.handle(), &out); break; default: - TransportClient::prepare(in, out, max); + transport_client::prepare(in, out, max); break; } } -void TransportClientTls::sync(fd_set &in, fd_set &out) +void transport_client_tls::sync(fd_set& in, fd_set& out) { - switch (m_handshake) { - case HandshakeRead: - case HandshakeWrite: + switch (handshake_) { + case handshake::read: + case handshake::write: handshake(); break; default: - TransportClient::sync(in, out); + transport_client::sync(in, out); } } #endif // !WITH_SSL /* - * TransportServerIp + * transport_server_ip * ------------------------------------------------------------------ */ -TransportServerIp::TransportServerIp(const std::string &address, - std::uint16_t port, - std::uint8_t mode) - : TransportServer(net::TcpSocket((mode & v6) ? AF_INET6 : AF_INET, 0)) +transport_server_ip::transport_server_ip(const std::string& address, + std::uint16_t port, + std::uint8_t mode) + : transport_server(net::TcpSocket((mode & v6) ? AF_INET6 : AF_INET, 0)) { assert((mode & v6) || (mode & v4)); - m_socket.set(net::option::SockReuseAddress(true)); + socket_.set(net::option::SockReuseAddress(true)); if (mode & v6) { // Disable or enable IPv4 when using IPv6. - m_socket.set(net::option::Ipv6Only(!(mode & v4))); + socket_.set(net::option::Ipv6Only(!(mode & v4))); if (address == "*") - m_socket.bind(net::ipv6::any(port)); + socket_.bind(net::ipv6::any(port)); else - m_socket.bind(net::ipv6::pton(address, port)); + socket_.bind(net::ipv6::pton(address, port)); } else { if (address == "*") - m_socket.bind(net::ipv4::any(port)); + socket_.bind(net::ipv4::any(port)); else - m_socket.bind(net::ipv4::pton(address, port)); + socket_.bind(net::ipv4::pton(address, port)); } - m_socket.listen(); + socket_.listen(); } -std::uint16_t TransportServerIp::port() const +std::uint16_t transport_server_ip::port() const { - auto addr = m_socket.getsockname(); + auto addr = socket_.getsockname(); return addr.domain() == AF_INET ? ntohs(addr.as<sockaddr_in>().sin_port) @@ -403,48 +407,48 @@ } /* - * TransportServerTls + * transport_server_tls * ------------------------------------------------------------------ */ #if defined(WITH_SSL) -TransportServerTls::TransportServerTls(const std::string &pkey, - const std::string &cert, - const std::string &address, - std::uint16_t port, - std::uint8_t mode) - : TransportServerIp(address, port, mode) - , m_privatekey(pkey) - , m_cert(cert) +transport_server_tls::transport_server_tls(const std::string& pkey, + const std::string& cert, + const std::string& address, + std::uint16_t port, + std::uint8_t mode) + : transport_server_ip(address, port, mode) + , privatekey_(pkey) + , cert_(cert) { } -std::unique_ptr<TransportClient> TransportServerTls::accept() +std::unique_ptr<transport_client> transport_server_tls::accept() { - return std::make_unique<TransportClientTls>(m_privatekey, m_cert, *this, m_socket.accept()); + return std::make_unique<transport_client_tls>(privatekey_, cert_, *this, socket_.accept()); } #endif // !WITH_SSL /* - * TransportServerLocal + * transport_server_local * ------------------------------------------------------------------ */ #if !defined(IRCCD_SYSTEM_WINDOWS) -TransportServerLocal::TransportServerLocal(std::string path) - : TransportServer(net::TcpSocket(AF_LOCAL, 0)) - , m_path(std::move(path)) +transport_server_local::transport_server_local(std::string path) + : transport_server(net::TcpSocket(AF_LOCAL, 0)) + , path_(std::move(path)) { - m_socket.bind(net::local::create(m_path, true)); - m_socket.listen(); + socket_.bind(net::local::create(path_, true)); + socket_.listen(); } -TransportServerLocal::~TransportServerLocal() +transport_server_local::~transport_server_local() { - ::remove(m_path.c_str()); + ::remove(path_.c_str()); } #endif
--- a/libirccd/irccd/transport.hpp Fri Aug 11 13:45:42 2017 +0200 +++ b/libirccd/irccd/transport.hpp Tue Sep 26 17:18:47 2017 +0200 @@ -36,53 +36,53 @@ namespace irccd { -class TransportServer; +class transport_server; /** * \brief Client connected to irccd. * * This class emits a warning upon clients request through onCommand signal. */ -class TransportClient { +class transport_client { public: /** * \brief Client state */ - enum State { - Greeting, //!< client is getting irccd info - Authenticating, //!< client requires authentication - Ready, //!< client is ready to use - Closing //!< client must disconnect + enum class state { + greeting, //!< client is getting irccd info + authenticating, //!< client requires authentication + ready, //!< client is ready to use + closing //!< client must disconnect }; /** - * Signal: onCommand + * Signal: on_command * ---------------------------------------------------------- * * Arguments: * - the command */ - Signal<const nlohmann::json &> onCommand; + Signal<const nlohmann::json&> on_command; /** - * Signal: onDie + * Signal: on_die * ---------------------------------------------------------- * * The client has disconnected. */ - Signal<> onDie; + Signal<> on_die; private: - void error(const std::string &msg); + void error(const std::string& msg); void flush() noexcept; void authenticate() noexcept; protected: - State m_state{Greeting}; //!< current client state - TransportServer &m_parent; //!< parent transport server - net::TcpSocket m_socket; //!< socket - std::string m_input; //!< input buffer - std::string m_output; //!< output buffer + state state_{state::greeting}; //!< current client state + transport_server& parent_; //!< parent transport server + net::TcpSocket socket_; //!< socket + std::string input_; //!< input buffer + std::string output_; //!< output buffer /** * Fill the input buffer with available data. @@ -101,7 +101,7 @@ * \param length the buffer length * \return the number of bytes received */ - IRCCD_EXPORT virtual unsigned recv(void *buffer, unsigned length); + virtual unsigned recv(void* buffer, unsigned length); /** * Try to send some data into the given buffer. @@ -110,7 +110,7 @@ * \param length the buffer length * \return the number of bytes sent */ - IRCCD_EXPORT virtual unsigned send(const void *buffer, unsigned length); + virtual unsigned send(const void* buffer, unsigned length); public: /** @@ -120,21 +120,21 @@ * \param parent the parent server * \param socket the new socket */ - IRCCD_EXPORT TransportClient(TransportServer &parent, net::TcpSocket socket); + transport_client(transport_server& parent, net::TcpSocket socket); /** * Virtual destructor defaulted. */ - virtual ~TransportClient() = default; + virtual ~transport_client() = default; /** * Get the client state. * * \return the client state */ - inline State state() const noexcept + inline enum state state() const noexcept { - return m_state; + return state_; } /** @@ -143,17 +143,17 @@ * \pre json.is_object() * \param json the json object */ - IRCCD_EXPORT void send(const nlohmann::json &json); + void send(const nlohmann::json& json); /** * \copydoc Service::prepare */ - IRCCD_EXPORT virtual void prepare(fd_set &in, fd_set &out, net::Handle &max); + virtual void prepare(fd_set& in, fd_set& out, net::Handle& max); /** * \copydoc Service::sync */ - IRCCD_EXPORT virtual void sync(fd_set &in, fd_set &out); + virtual void sync(fd_set& in, fd_set& out); /** * Send a successful command to the client with optional extra data @@ -162,7 +162,7 @@ * \param cmd the command name * \param extra the optional extra data */ - IRCCD_EXPORT void success(const std::string &cmd, nlohmann::json extra = nullptr); + void success(const std::string& cmd, nlohmann::json extra = nullptr); /** * Send an error status to the client. @@ -172,9 +172,9 @@ * \param error the error string * \param extra the optional extra data */ - IRCCD_EXPORT void error(const std::string &cmd, - const std::string &error, - nlohmann::json extra = nullptr); + void error(const std::string& cmd, + const std::string& error, + nlohmann::json extra = nullptr); }; /* @@ -187,15 +187,15 @@ /** * \brief TLS version of transport client. */ -class TransportClientTls : public TransportClient { +class transport_client_tls : public transport_client { private: - enum { - HandshakeWrite, - HandshakeRead, - HandshakeReady - } m_handshake{HandshakeReady}; + enum class handshake { + write, + read, + ready + } handshake_{handshake::ready}; - net::TlsSocket m_ssl; + net::TlsSocket ssl_; void handshake(); @@ -203,12 +203,12 @@ /** * \copydoc TransportClient::recv */ - unsigned recv(void *buffer, unsigned length) override; + unsigned recv(void* buffer, unsigned length) override; /** * \copydoc TransportClient::send */ - unsigned send(const void *buffer, unsigned length) override; + unsigned send(const void* buffer, unsigned length) override; public: /** @@ -221,20 +221,20 @@ * \param parent the parent server * \param socket the new socket */ - IRCCD_EXPORT TransportClientTls(const std::string &pkey, - const std::string &cert, - TransportServer &server, - net::TcpSocket socket); + transport_client_tls(const std::string& pkey, + const std::string& cert, + transport_server& server, + net::TcpSocket socket); /** * \copydoc TransportClient::prepare */ - IRCCD_EXPORT void prepare(fd_set &in, fd_set &out, net::Handle &max) override; + void prepare(fd_set& in, fd_set& out, net::Handle& max) override; /** * \copydoc TransportClient::sync */ - IRCCD_EXPORT void sync(fd_set &in, fd_set &out) override; + void sync(fd_set& in, fd_set& out) override; }; #endif // !WITH_SSL @@ -252,32 +252,32 @@ * * The transport class supports the following domains: * - * | Domain | Class | - * |-----------------------|-----------------------| - * | IPv4, IPv6 | TransportServerIp | - * | Unix (not on Windows) | TransportServerUnix | + * | Domain | Class | + * |-----------------------|------------------------| + * | IPv4, IPv6 | transport_server_ip | + * | Unix (not on Windows) | transport_server_local | * * Note: IPv4 and IPv6 can be combined, using TransportServer::IPv6 and its * option. */ -class TransportServer { +class transport_server { private: - TransportServer(const TransportServer &) = delete; - TransportServer(TransportServer &&) = delete; + transport_server(const transport_server&) = delete; + transport_server(transport_server&&) = delete; - TransportServer &operator=(const TransportServer &) = delete; - TransportServer &operator=(TransportServer &&) = delete; + transport_server& operator=(const transport_server&) = delete; + transport_server& operator=(transport_server&&) = delete; protected: - net::TcpSocket m_socket; - std::string m_password; + net::TcpSocket socket_; + std::string password_; public: /** * Default constructor. */ - inline TransportServer(net::TcpSocket socket) - : m_socket(std::move(socket)) + inline transport_server(net::TcpSocket socket) + : socket_(std::move(socket)) { } @@ -288,7 +288,7 @@ */ inline net::Handle handle() const noexcept { - return m_socket.handle(); + return socket_.handle(); } /** @@ -296,9 +296,9 @@ * * \return the password */ - inline const std::string &password() const noexcept + inline const std::string& password() const noexcept { - return m_password; + return password_; } /** @@ -306,36 +306,36 @@ * * \return the password */ - inline void setPassword(std::string password) noexcept + inline void set_password(std::string password) noexcept { - m_password = std::move(password); + password_ = std::move(password); } /** * Destructor defaulted. */ - virtual ~TransportServer() = default; + virtual ~transport_server() = default; /** * Accept a new client depending on the domain. * * \return the new client */ - virtual std::unique_ptr<TransportClient> accept() + virtual std::unique_ptr<transport_client> accept() { - return std::make_unique<TransportClient>(*this, m_socket.accept()); + return std::make_unique<transport_client>(*this, socket_.accept()); } }; /** * \brief Create IP transport. */ -class TransportServerIp : public TransportServer { +class transport_server_ip : public transport_server { public: /** * \brief Domain to use. */ - enum Mode { + enum mode { v4 = (1 << 0), //!< IPv6 v6 = (1 << 1) //!< IPv4 }; @@ -347,9 +347,9 @@ * \param port the port number * \param mode the domains to use (can be OR'ed) */ - IRCCD_EXPORT TransportServerIp(const std::string &address, - std::uint16_t port, - std::uint8_t mode = v4); + transport_server_ip(const std::string& address, + std::uint16_t port, + std::uint8_t mode = v4); /** * Get the associated port. @@ -364,10 +364,10 @@ /** * \brief TLS over IP transport. */ -class TransportServerTls : public TransportServerIp { +class transport_server_tls : public transport_server_ip { private: - std::string m_privatekey; - std::string m_cert; + std::string privatekey_; + std::string cert_; public: /** @@ -379,16 +379,16 @@ * \param port the port number * \param mode the domains to use (can be OR'ed) */ - IRCCD_EXPORT TransportServerTls(const std::string &pkey, - const std::string &cert, - const std::string &address, - std::uint16_t port, - std::uint8_t mode = v4); + transport_server_tls(const std::string& pkey, + const std::string& cert, + const std::string& address, + std::uint16_t port, + std::uint8_t mode = mode::v4); /** * \copydoc TransportServer::accept */ - IRCCD_EXPORT std::unique_ptr<TransportClient> accept() override; + std::unique_ptr<transport_client> accept() override; }; #endif // !WITH_SSL @@ -398,9 +398,9 @@ /** * \brief Implementation of transports for Unix sockets. */ -class TransportServerLocal : public TransportServer { +class transport_server_local : public transport_server { private: - std::string m_path; + std::string path_; public: /** @@ -408,12 +408,12 @@ * * \param path the path */ - IRCCD_EXPORT TransportServerLocal(std::string path); + transport_server_local(std::string path); /** * Destroy the transport and remove the file. */ - IRCCD_EXPORT ~TransportServerLocal(); + ~transport_server_local(); }; #endif // !IRCCD_SYSTEM_WINDOWS
--- a/libirccdctl/irccd/client.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/libirccdctl/irccd/client.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -104,7 +104,7 @@ std::string msg; do { - msg = util::nextNetwork(cnx.m_input); + msg = util::next_network(cnx.m_input); if (!msg.empty()) parse(cnx, msg); @@ -151,7 +151,7 @@ { cnt.recv(); - auto msg = util::nextNetwork(cnt.m_input); + auto msg = util::next_network(cnt.m_input); if (msg.empty()) return; @@ -277,7 +277,7 @@ void verify(Client &cnx) const { - auto msg = util::nextNetwork(cnx.m_input); + auto msg = util::next_network(cnx.m_input); if (msg.empty()) return;
--- a/tests/cmd-plugin-config/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/cmd-plugin-config/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -22,35 +22,32 @@ #include <service.hpp> using namespace irccd; -using namespace irccd::command; namespace { -struct CustomPlugin : public Plugin { - PluginConfig m_config; +struct CustomPlugin : public plugin { + plugin_config m_config; CustomPlugin(std::string name = "test") - : Plugin(std::move(name), "") + : plugin(std::move(name), "") { } - PluginConfig config() override + plugin_config config() override { return m_config; } - void setConfig(PluginConfig config) override + void set_config(plugin_config config) override { m_config = std::move(config); } }; - - class PluginConfigCommandTest : public CommandTester { public: PluginConfigCommandTest() - : CommandTester(std::make_unique<PluginConfigCommand>()) + : CommandTester(std::make_unique<plugin_config_command>()) { } }; @@ -85,7 +82,7 @@ auto plugin = std::make_unique<CustomPlugin>("test"); auto json = nlohmann::json(); - plugin->setConfig({ + plugin->set_config({ { "x1", "10" }, { "x2", "20" } }); @@ -118,7 +115,7 @@ auto plugin = std::make_unique<CustomPlugin>("test"); auto json = nlohmann::json(); - plugin->setConfig({ + plugin->set_config({ { "x1", "10" }, { "x2", "20" } });
--- a/tests/cmd-plugin-info/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/cmd-plugin-info/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -23,14 +23,13 @@ #include <plugin.hpp> using namespace irccd; -using namespace irccd::command; namespace { class PluginInfoCommandTest : public CommandTester { public: PluginInfoCommandTest() - : CommandTester(std::make_unique<PluginInfoCommand>()) + : CommandTester(std::make_unique<plugin_info_command>()) { } }; @@ -38,15 +37,15 @@ TEST_F(PluginInfoCommandTest, basic) { try { - auto plugin = std::make_unique<Plugin>("test", ""); + auto plg = std::make_unique<plugin>("test", ""); auto response = nlohmann::json(); - plugin->setAuthor("Francis Beaugrand"); - plugin->setLicense("GPL"); - plugin->setSummary("Completely useless plugin"); - plugin->setVersion("0.0.0.0.0.0.0.0.1-beta5"); + plg->set_author("Francis Beaugrand"); + plg->set_license("GPL"); + plg->set_summary("Completely useless plugin"); + plg->set_version("0.0.0.0.0.0.0.0.1-beta5"); - m_irccd.plugins().add(std::move(plugin)); + m_irccd.plugins().add(std::move(plg)); m_irccdctl.client().onMessage.connect([&] (auto msg) { response = std::move(msg); });
--- a/tests/cmd-plugin-list/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/cmd-plugin-list/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -23,17 +23,16 @@ #include <plugin.hpp> using namespace irccd; -using namespace irccd::command; namespace { class PluginListCommandTest : public CommandTester { public: PluginListCommandTest() - : CommandTester(std::make_unique<PluginListCommand>()) + : CommandTester(std::make_unique<plugin_list_command>()) { - m_irccd.plugins().add(std::make_unique<Plugin>("t1", "")); - m_irccd.plugins().add(std::make_unique<Plugin>("t2", "")); + m_irccd.plugins().add(std::make_unique<plugin>("t1", "")); + m_irccd.plugins().add(std::make_unique<plugin>("t2", "")); } };
--- a/tests/cmd-plugin-load/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/cmd-plugin-load/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -23,30 +23,29 @@ #include <plugin.hpp> using namespace irccd; -using namespace irccd::command; namespace { -class CustomLoader : public PluginLoader { +class CustomLoader : public plugin_loader { public: - std::shared_ptr<Plugin> open(const std::string &, + std::shared_ptr<plugin> open(const std::string &, const std::string &) noexcept override { return nullptr; } - std::shared_ptr<Plugin> find(const std::string &id) noexcept override + std::shared_ptr<plugin> find(const std::string &id) noexcept override { - return std::make_unique<Plugin>(id, ""); + return std::make_unique<plugin>(id, ""); } }; class PluginLoadCommandTest : public CommandTester { public: PluginLoadCommandTest() - : CommandTester(std::make_unique<PluginLoadCommand>()) + : CommandTester(std::make_unique<plugin_load_command>()) { - m_irccd.plugins().addLoader(std::make_unique<CustomLoader>()); + m_irccd.plugins().add_loader(std::make_unique<CustomLoader>()); } };
--- a/tests/cmd-plugin-reload/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/cmd-plugin-reload/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -23,20 +23,19 @@ #include <plugin.hpp> using namespace irccd; -using namespace irccd::command; namespace { bool called = false; -class CustomPlugin : public Plugin { +class CustomPlugin : public plugin { public: CustomPlugin() - : Plugin("test", "") + : plugin("test", "") { } - void onReload(Irccd &) override + void on_reload(irccd::irccd &) override { called = true; } @@ -45,7 +44,7 @@ class PluginReloadCommandTest : public CommandTester { public: PluginReloadCommandTest() - : CommandTester(std::make_unique<PluginReloadCommand>()) + : CommandTester(std::make_unique<plugin_reload_command>()) { called = false; }
--- a/tests/cmd-plugin-unload/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/cmd-plugin-unload/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -23,20 +23,19 @@ #include <plugin.hpp> using namespace irccd; -using namespace irccd::command; namespace { bool called = false; -class CustomPlugin : public Plugin { +class CustomPlugin : public plugin { public: CustomPlugin() - : Plugin("test", "") + : plugin("test", "") { } - void onUnload(Irccd &) override + void on_unload(irccd::irccd &) override { called = true; } @@ -45,7 +44,7 @@ class PluginUnloadCommandTest : public CommandTester { public: PluginUnloadCommandTest() - : CommandTester(std::make_unique<PluginUnloadCommand>()) + : CommandTester(std::make_unique<plugin_unload_command>()) { called = false; }
--- a/tests/cmd-rule-add/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/cmd-rule-add/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -21,7 +21,6 @@ #include <service.hpp> using namespace irccd; -using namespace irccd::command; class RuleAddCommandTest : public CommandTester { protected: @@ -42,9 +41,9 @@ public: RuleAddCommandTest() - : CommandTester(std::make_unique<RuleAddCommand>()) + : CommandTester(std::make_unique<rule_add_command>()) { - m_irccd.commands().add(std::make_unique<RuleListCommand>()); + m_irccd.commands().add(std::make_unique<rule_list_command>()); m_irccdctl.client().onMessage.connect([&] (auto result) { m_result = result; });
--- a/tests/cmd-rule-edit/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/cmd-rule-edit/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -21,7 +21,6 @@ #include <service.hpp> using namespace irccd; -using namespace irccd::command; class RuleEditCommandTest : public CommandTester { protected: @@ -42,16 +41,16 @@ public: RuleEditCommandTest() - : CommandTester(std::make_unique<RuleEditCommand>()) + : CommandTester(std::make_unique<rule_edit_command>()) { - m_irccd.commands().add(std::make_unique<RuleInfoCommand>()); - m_irccd.rules().add(Rule( + m_irccd.commands().add(std::make_unique<rule_info_command>()); + m_irccd.rules().add(rule( { "s1", "s2" }, { "c1", "c2" }, { "o1", "o2" }, { "p1", "p2" }, { "onMessage", "onCommand" }, - RuleAction::Drop + rule::action_type::drop )); m_irccdctl.client().onMessage.connect([&] (auto result) { m_result = result;
--- a/tests/cmd-rule-info/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/cmd-rule-info/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -21,7 +21,6 @@ #include <service.hpp> using namespace irccd; -using namespace irccd::command; class RuleInfoCommandTest : public CommandTester { protected: @@ -42,23 +41,23 @@ public: RuleInfoCommandTest() - : CommandTester(std::make_unique<RuleInfoCommand>()) + : CommandTester(std::make_unique<rule_info_command>()) { - m_irccd.rules().add(Rule( + m_irccd.rules().add(rule( { "s1", "s2" }, { "c1", "c2" }, { "o1", "o2" }, { "p1", "p2" }, { "onMessage", "onCommand" }, - RuleAction::Drop + rule::action_type::drop )); - m_irccd.rules().add(Rule( + m_irccd.rules().add(rule( { "s1", }, { "c1", }, { "o1", }, { "p1", }, { "onMessage", }, - RuleAction::Accept + rule::action_type::accept )); m_irccdctl.client().onMessage.connect([&] (auto result) { m_result = result;
--- a/tests/cmd-rule-list/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/cmd-rule-list/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -21,7 +21,6 @@ #include <service.hpp> using namespace irccd; -using namespace irccd::command; class RuleListCommandTest : public CommandTester { protected: @@ -42,23 +41,23 @@ public: RuleListCommandTest() - : CommandTester(std::make_unique<RuleListCommand>()) + : CommandTester(std::make_unique<rule_list_command>()) { - m_irccd.rules().add(Rule( + m_irccd.rules().add(rule( { "s1", "s2" }, { "c1", "c2" }, { "o1", "o2" }, { "p1", "p2" }, { "onMessage", "onCommand" }, - RuleAction::Drop + rule::action_type::drop )); - m_irccd.rules().add(Rule( + m_irccd.rules().add(rule( { "s1", }, { "c1", }, { "o1", }, { "p1", }, { "onMessage", }, - RuleAction::Accept + rule::action_type::accept )); m_irccdctl.client().request({{ "command", "rule-list" }}); m_irccdctl.client().onMessage.connect([&] (auto result) {
--- a/tests/cmd-rule-move/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/cmd-rule-move/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -21,7 +21,6 @@ #include <service.hpp> using namespace irccd; -using namespace irccd::command; class RuleMoveCommandTest : public CommandTester { protected: @@ -42,32 +41,32 @@ public: RuleMoveCommandTest() - : CommandTester(std::make_unique<RuleMoveCommand>()) + : CommandTester(std::make_unique<rule_move_command>()) { - m_irccd.commands().add(std::make_unique<RuleListCommand>()); - m_irccd.rules().add(Rule( + m_irccd.commands().add(std::make_unique<rule_list_command>()); + m_irccd.rules().add(rule( { "s0" }, { "c0" }, { "o0" }, { "p0" }, { "onMessage" }, - RuleAction::Drop + rule::action_type::drop )); - m_irccd.rules().add(Rule( + m_irccd.rules().add(rule( { "s1", }, { "c1", }, { "o1", }, { "p1", }, { "onMessage", }, - RuleAction::Accept + rule::action_type::accept )); - m_irccd.rules().add(Rule( + m_irccd.rules().add(rule( { "s2", }, { "c2", }, { "o2", }, { "p2", }, { "onMessage", }, - RuleAction::Accept + rule::action_type::accept )); m_irccdctl.client().onMessage.connect([&] (auto result) { m_result = result;
--- a/tests/cmd-rule-remove/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/cmd-rule-remove/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -21,7 +21,6 @@ #include <service.hpp> using namespace irccd; -using namespace irccd::command; class RuleRemoveCommandTest : public CommandTester { protected: @@ -42,24 +41,24 @@ public: RuleRemoveCommandTest() - : CommandTester(std::make_unique<RuleRemoveCommand>()) + : CommandTester(std::make_unique<rule_remove_command>()) { - m_irccd.commands().add(std::make_unique<RuleListCommand>()); - m_irccd.rules().add(Rule( + m_irccd.commands().add(std::make_unique<rule_list_command>()); + m_irccd.rules().add(rule( { "s1", "s2" }, { "c1", "c2" }, { "o1", "o2" }, { "p1", "p2" }, { "onMessage", "onCommand" }, - RuleAction::Drop + rule::action_type::drop )); - m_irccd.rules().add(Rule( + m_irccd.rules().add(rule( { "s1", }, { "c1", }, { "o1", }, { "p1", }, { "onMessage", }, - RuleAction::Accept + rule::action_type::accept )); m_irccdctl.client().onMessage.connect([&] (auto result) { m_result = result;
--- a/tests/cmd-server-cmode/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/cmd-server-cmode/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -21,12 +21,11 @@ #include <server-tester.hpp> using namespace irccd; -using namespace irccd::command; namespace { -std::string channel; -std::string mode; +std::string cmd_channel; +std::string cmd_mode; } // !namespace @@ -34,15 +33,15 @@ public: void cmode(std::string channel, std::string mode) { - ::channel = channel; - ::mode = mode; + ::cmd_channel = channel; + ::cmd_mode = mode; } }; class ServerChannelModeCommandTest : public CommandTester { public: ServerChannelModeCommandTest() - : CommandTester(std::make_unique<ServerChannelModeCommand>(), + : CommandTester(std::make_unique<server_channel_mode_command>(), std::make_unique<ServerChannelModeTest>()) { m_irccdctl.client().request({ @@ -58,11 +57,11 @@ { try { poll([&] () { - return !channel.empty() && !mode.empty(); + return !cmd_channel.empty() && !cmd_mode.empty(); }); - ASSERT_EQ("#staff", channel); - ASSERT_EQ("+c", mode); + ASSERT_EQ("#staff", cmd_channel); + ASSERT_EQ("+c", cmd_mode); } catch (const std::exception &ex) { FAIL() << ex.what(); }
--- a/tests/cmd-server-cnotice/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/cmd-server-cnotice/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -21,12 +21,11 @@ #include <server-tester.hpp> using namespace irccd; -using namespace irccd::command; namespace { -std::string channel; -std::string message; +std::string cmd_channel; +std::string cmd_message; } // !namespace @@ -34,15 +33,15 @@ public: virtual void cnotice(std::string channel, std::string message) override { - ::channel = channel; - ::message = message; + ::cmd_channel = channel; + ::cmd_message = message; } }; class ServerChannelNoticeCommandTest : public CommandTester { public: ServerChannelNoticeCommandTest() - : CommandTester(std::make_unique<ServerChannelNoticeCommand>(), + : CommandTester(std::make_unique<server_channel_notice_command>(), std::make_unique<ServerChannelNoticeTest>()) { m_irccdctl.client().request({ @@ -58,11 +57,11 @@ { try { poll([&] () { - return !channel.empty() && !message.empty(); + return !cmd_channel.empty() && !cmd_message.empty(); }); - ASSERT_EQ("#staff", channel); - ASSERT_EQ("silence", message); + ASSERT_EQ("#staff", cmd_channel); + ASSERT_EQ("silence", cmd_message); } catch (const std::exception &ex) { FAIL() << ex.what(); }
--- a/tests/cmd-server-connect/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/cmd-server-connect/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -22,7 +22,6 @@ #include <service.hpp> using namespace irccd; -using namespace irccd::command; namespace { @@ -33,7 +32,7 @@ class ServerConnectCommandTest : public CommandTester { public: ServerConnectCommandTest() - : CommandTester(std::make_unique<ServerConnectCommand>()) + : CommandTester(std::make_unique<server_connect_command>()) { message = nullptr; @@ -101,12 +100,12 @@ ASSERT_EQ("francis", s->nickname()); ASSERT_EQ("the_francis", s->realname()); ASSERT_EQ("frc", s->username()); - ASSERT_EQ("::", s->commandCharacter()); - ASSERT_EQ("ultra bot", s->ctcpVersion()); - ASSERT_TRUE(s->flags() & Server::Ssl); - ASSERT_TRUE(s->flags() & Server::SslVerify); - ASSERT_TRUE(s->flags() & Server::AutoRejoin); - ASSERT_TRUE(s->flags() & Server::JoinInvite); + ASSERT_EQ("::", s->command_char()); + ASSERT_EQ("ultra bot", s->ctcp_version()); + ASSERT_TRUE(s->flags() & server::ssl); + ASSERT_TRUE(s->flags() & server::ssl_verify); + ASSERT_TRUE(s->flags() & server::auto_rejoin); + ASSERT_TRUE(s->flags() & server::join_invite); } catch (const std::exception &ex) { FAIL() << ex.what(); }
--- a/tests/cmd-server-disconnect/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/cmd-server-disconnect/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -23,12 +23,11 @@ #include <server.hpp> using namespace irccd; -using namespace irccd::command; class ServerDisconnectCommandTest : public CommandTester { public: ServerDisconnectCommandTest() - : CommandTester(std::make_unique<ServerDisconnectCommand>()) + : CommandTester(std::make_unique<server_disconnect_command>()) { } };
--- a/tests/cmd-server-info/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/cmd-server-info/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -22,7 +22,6 @@ #include <service.hpp> using namespace irccd; -using namespace irccd::command; namespace { @@ -33,7 +32,7 @@ class ServerInfoCommandTest : public CommandTester { public: ServerInfoCommandTest() - : CommandTester(std::make_unique<ServerInfoCommand>()) + : CommandTester(std::make_unique<server_info_command>()) { message = nullptr; @@ -48,16 +47,16 @@ try { auto server = std::make_unique<ServerTester>(); - server->setHost("example.org"); - server->setPort(8765); - server->setPassword("none"); - server->setNickname("pascal"); - server->setUsername("psc"); - server->setRealname("Pascal le grand frere"); - server->setCtcpVersion("yeah"); - server->setCommandCharacter("@"); - server->setReconnectTries(80); - server->setPingTimeout(20000); + server->set_host("example.org"); + server->set_port(8765); + server->set_password("none"); + server->set_nickname("pascal"); + server->set_username("psc"); + server->set_realname("Pascal le grand frere"); + server->set_ctcp_version("yeah"); + server->set_command_char("@"); + server->set_reconnect_tries(80); + server->set_ping_timeout(20000); m_irccd.servers().add(std::move(server)); m_irccdctl.client().request({
--- a/tests/cmd-server-invite/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/cmd-server-invite/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -21,12 +21,11 @@ #include <server-tester.hpp> using namespace irccd; -using namespace irccd::command; namespace { -std::string target; -std::string channel; +std::string cmd_target; +std::string cmd_channel; } // !namespace @@ -34,15 +33,15 @@ public: void invite(std::string target, std::string channel) override { - ::target = target; - ::channel = channel; + ::cmd_target = target; + ::cmd_channel = channel; } }; class ServerInviteCommandTest : public CommandTester { public: ServerInviteCommandTest() - : CommandTester(std::make_unique<ServerInviteCommand>(), + : CommandTester(std::make_unique<server_invite_command>(), std::make_unique<ServerInviteTest>()) { m_irccdctl.client().request({ @@ -58,11 +57,11 @@ { try { poll([&] () { - return !target.empty() && !channel.empty(); + return !cmd_target.empty() && !cmd_channel.empty(); }); - ASSERT_EQ("francis", target); - ASSERT_EQ("#music", channel); + ASSERT_EQ("francis", cmd_target); + ASSERT_EQ("#music", cmd_channel); } catch (const std::exception &ex) { FAIL() << ex.what(); }
--- a/tests/cmd-server-join/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/cmd-server-join/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -21,12 +21,11 @@ #include <server-tester.hpp> using namespace irccd; -using namespace irccd::command; namespace { -std::string channel; -std::string password; +std::string cmd_channel; +std::string cmd_password; } // !namespace @@ -34,21 +33,19 @@ public: void join(std::string channel, std::string password) override { - ::channel = channel; - ::password = password; + ::cmd_channel = channel; + ::cmd_password = password; } }; class ServerJoinCommandTest : public CommandTester { public: ServerJoinCommandTest() - : CommandTester(std::make_unique<ServerJoinCommand>(), + : CommandTester(std::make_unique<server_join_command>(), std::make_unique<ServerJoinTest>()) { - channel.clear(); - password.clear(); - - + cmd_channel.clear(); + cmd_password.clear(); } }; @@ -63,11 +60,11 @@ }); poll([&] () { - return !channel.empty(); + return !cmd_channel.empty(); }); - ASSERT_EQ("#music", channel); - ASSERT_EQ("plop", password); + ASSERT_EQ("#music", cmd_channel); + ASSERT_EQ("plop", cmd_password); } catch (const std::exception &ex) { FAIL() << ex.what(); } @@ -83,11 +80,11 @@ }); poll([&] () { - return !channel.empty(); + return !cmd_channel.empty(); }); - ASSERT_EQ("#music", channel); - ASSERT_EQ("", password); + ASSERT_EQ("#music", cmd_channel); + ASSERT_EQ("", cmd_password); } catch (const std::exception &ex) { FAIL() << ex.what(); }
--- a/tests/cmd-server-kick/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/cmd-server-kick/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -21,13 +21,12 @@ #include <server-tester.hpp> using namespace irccd; -using namespace irccd::command; namespace { -std::string target; -std::string channel; -std::string reason; +std::string cmd_target; +std::string cmd_channel; +std::string cmd_reason; } // !namespace @@ -35,21 +34,21 @@ public: void kick(std::string target, std::string channel, std::string reason) override { - ::target = target; - ::channel = channel; - ::reason = reason; + ::cmd_target = target; + ::cmd_channel = channel; + ::cmd_reason = reason; } }; class ServerKickCommandTest : public CommandTester { public: ServerKickCommandTest() - : CommandTester(std::make_unique<ServerKickCommand>(), + : CommandTester(std::make_unique<server_kick_command>(), std::make_unique<ServerKickTest>()) { - target.clear(); - channel.clear(); - reason.clear(); + cmd_target.clear(); + cmd_channel.clear(); + cmd_reason.clear(); } }; @@ -65,12 +64,12 @@ }); poll([&] () { - return !target.empty() && !channel.empty(); + return !cmd_target.empty() && !cmd_channel.empty(); }); - ASSERT_EQ("francis", target); - ASSERT_EQ("#staff", channel); - ASSERT_EQ("too noisy", reason); + ASSERT_EQ("francis", cmd_target); + ASSERT_EQ("#staff", cmd_channel); + ASSERT_EQ("too noisy", cmd_reason); } catch (const std::exception &ex) { FAIL() << ex.what(); } @@ -87,12 +86,12 @@ }); poll([&] () { - return !target.empty() && !channel.empty(); + return !cmd_target.empty() && !cmd_channel.empty(); }); - ASSERT_EQ("francis", target); - ASSERT_EQ("#staff", channel); - ASSERT_EQ("", reason); + ASSERT_EQ("francis", cmd_target); + ASSERT_EQ("#staff", cmd_channel); + ASSERT_EQ("", cmd_reason); } catch (const std::exception &ex) { FAIL() << ex.what(); }
--- a/tests/cmd-server-list/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/cmd-server-list/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -22,7 +22,6 @@ #include <service.hpp> using namespace irccd; -using namespace irccd::command; namespace { @@ -33,7 +32,7 @@ class ServerListCommandTest : public CommandTester { public: ServerListCommandTest() - : CommandTester(std::make_unique<ServerListCommand>()) + : CommandTester(std::make_unique<server_list_command>()) { m_irccd.servers().add(std::make_unique<ServerTester>("s1")); m_irccd.servers().add(std::make_unique<ServerTester>("s2"));
--- a/tests/cmd-server-me/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/cmd-server-me/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -21,7 +21,6 @@ #include <server-tester.hpp> using namespace irccd; -using namespace irccd::command; namespace { @@ -42,7 +41,7 @@ class ServerMeCommandTest : public CommandTester { public: ServerMeCommandTest() - : CommandTester(std::make_unique<ServerMeCommand>(), + : CommandTester(std::make_unique<server_me_command>(), std::make_unique<ServerMeTest>()) { m_irccdctl.client().request({
--- a/tests/cmd-server-message/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/cmd-server-message/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -21,7 +21,6 @@ #include <server-tester.hpp> using namespace irccd; -using namespace irccd::command; namespace { @@ -42,7 +41,7 @@ class ServerMessageCommandTest : public CommandTester { public: ServerMessageCommandTest() - : CommandTester(std::make_unique<ServerMessageCommand>(), + : CommandTester(std::make_unique<server_message_command>(), std::make_unique<ServerMessageTest>()) { m_irccdctl.client().request({
--- a/tests/cmd-server-mode/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/cmd-server-mode/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -21,7 +21,6 @@ #include <server-tester.hpp> using namespace irccd; -using namespace irccd::command; namespace { @@ -40,7 +39,7 @@ class ServerModeCommandTest : public CommandTester { public: ServerModeCommandTest() - : CommandTester(std::make_unique<ServerModeCommand>(), + : CommandTester(std::make_unique<server_mode_command>(), std::make_unique<ServerModeTest>()) { m_irccdctl.client().request({
--- a/tests/cmd-server-nick/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/cmd-server-nick/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -21,7 +21,6 @@ #include <server-tester.hpp> using namespace irccd; -using namespace irccd::command; namespace { @@ -31,7 +30,7 @@ class ServerNickTest : public ServerTester { public: - void setNickname(std::string nick) override + void set_nickname(std::string nick) override { ::nick = nick; } @@ -40,7 +39,7 @@ class ServerNickCommandTest : public CommandTester { public: ServerNickCommandTest() - : CommandTester(std::make_unique<ServerNickCommand>(), + : CommandTester(std::make_unique<server_nick_command>(), std::make_unique<ServerNickTest>()) { m_irccdctl.client().request({
--- a/tests/cmd-server-notice/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/cmd-server-notice/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -21,12 +21,11 @@ #include <server-tester.hpp> using namespace irccd; -using namespace irccd::command; namespace { -std::string channel; -std::string message; +std::string cmd_channel; +std::string cmd_message; } // !namespace @@ -34,15 +33,15 @@ public: void notice(std::string channel, std::string message) override { - ::channel = channel; - ::message = message; + ::cmd_channel = channel; + ::cmd_message = message; } }; class ServerNoticeCommandTest : public CommandTester { public: ServerNoticeCommandTest() - : CommandTester(std::make_unique<ServerNoticeCommand>(), + : CommandTester(std::make_unique<server_notice_command>(), std::make_unique<ServerNoticeTest>()) { m_irccdctl.client().request({ @@ -58,11 +57,11 @@ { try { poll([&] () { - return !channel.empty() && !message.empty(); + return !cmd_channel.empty() && !cmd_message.empty(); }); - ASSERT_EQ("#staff", channel); - ASSERT_EQ("quiet!", message); + ASSERT_EQ("#staff", cmd_channel); + ASSERT_EQ("quiet!", cmd_message); } catch (const std::exception &ex) { FAIL() << ex.what(); }
--- a/tests/cmd-server-part/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/cmd-server-part/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -21,12 +21,11 @@ #include <server-tester.hpp> using namespace irccd; -using namespace irccd::command; namespace { -std::string channel; -std::string reason; +std::string cmd_channel; +std::string cmd_reason; } // !namespace @@ -34,19 +33,19 @@ public: void part(std::string channel, std::string reason) override { - ::channel = channel; - ::reason = reason; + ::cmd_channel = channel; + ::cmd_reason = reason; } }; class ServerPartCommandTest : public CommandTester { public: ServerPartCommandTest() - : CommandTester(std::make_unique<ServerPartCommand>(), + : CommandTester(std::make_unique<server_part_command>(), std::make_unique<ServerPartTest>()) { - channel.clear(); - reason.clear(); + cmd_channel.clear(); + cmd_reason.clear(); } }; @@ -61,11 +60,11 @@ }); poll([&] () { - return !channel.empty(); + return !cmd_channel.empty(); }); - ASSERT_EQ("#staff", channel); - ASSERT_EQ("too noisy", reason); + ASSERT_EQ("#staff", cmd_channel); + ASSERT_EQ("too noisy", cmd_reason); } catch (const std::exception &ex) { FAIL() << ex.what(); } @@ -81,11 +80,11 @@ }); poll([&] () { - return !channel.empty(); + return !cmd_channel.empty(); }); - ASSERT_EQ("#staff", channel); - ASSERT_TRUE(reason.empty()); + ASSERT_EQ("#staff", cmd_channel); + ASSERT_TRUE(cmd_reason.empty()); } catch (const std::exception &ex) { FAIL() << ex.what(); }
--- a/tests/cmd-server-reconnect/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/cmd-server-reconnect/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -22,7 +22,6 @@ #include <service.hpp> using namespace irccd; -using namespace irccd::command; namespace { @@ -52,7 +51,7 @@ class ServerReconnectCommandTest : public CommandTester { public: ServerReconnectCommandTest() - : CommandTester(std::make_unique<ServerReconnectCommand>()) + : CommandTester(std::make_unique<server_reconnect_command>()) { m_irccd.servers().add(std::make_unique<ServerReconnectTest>("s1", s1)); m_irccd.servers().add(std::make_unique<ServerReconnectTest>("s2", s2));
--- a/tests/cmd-server-topic/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/cmd-server-topic/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -21,12 +21,11 @@ #include <server-tester.hpp> using namespace irccd; -using namespace irccd::command; namespace { -std::string channel; -std::string topic; +std::string cmd_channel; +std::string cmd_topic; } // !namespace @@ -34,15 +33,15 @@ public: void topic(std::string channel, std::string topic) override { - ::channel = channel; - ::topic = topic; + ::cmd_channel = channel; + ::cmd_topic = topic; } }; class ServerTopicCommandTest : public CommandTester { public: ServerTopicCommandTest() - : CommandTester(std::make_unique<ServerTopicCommand>(), + : CommandTester(std::make_unique<server_topic_command>(), std::make_unique<ServerTopicTest>()) { m_irccdctl.client().request({ @@ -58,11 +57,11 @@ { try { poll([&] () { - return !channel.empty() && !topic.empty(); + return !cmd_channel.empty() && !cmd_topic.empty(); }); - ASSERT_EQ("#staff", channel); - ASSERT_EQ("new version", topic); + ASSERT_EQ("#staff", cmd_channel); + ASSERT_EQ("new version", cmd_topic); } catch (const std::exception &ex) { FAIL() << ex.what(); }
--- a/tests/js-elapsedtimer/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/js-elapsedtimer/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -1,5 +1,5 @@ /* - * main.cpp -- test Irccd.ElapsedTimer API + * main.cpp -- test irccd.ElapsedTimer API * * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> * @@ -21,9 +21,9 @@ #include <thread> #include <irccd/irccd.hpp> -#include <irccd/mod-irccd.hpp> -#include <irccd/mod-elapsed-timer.hpp> -#include <irccd/plugin-js.hpp> +#include <irccd/js_irccd_module.hpp> +#include <irccd/js_elapsed_timer_module.hpp> +#include <irccd/js_plugin.hpp> #include <irccd/service.hpp> using namespace irccd; @@ -31,14 +31,14 @@ class TestElapsedTimer : public testing::Test { protected: - Irccd m_irccd; - std::shared_ptr<JsPlugin> m_plugin; + irccd::irccd m_irccd; + std::shared_ptr<js_plugin> m_plugin; TestElapsedTimer() - : m_plugin(std::make_shared<JsPlugin>("empty", SOURCEDIR "/empty.js")) + : m_plugin(std::make_shared<js_plugin>("empty", SOURCEDIR "/empty.js")) { - IrccdModule().load(m_irccd, m_plugin); - ElapsedTimerModule().load(m_irccd, m_plugin); + js_irccd_module().load(m_irccd, m_plugin); + js_elapsed_timer_module().load(m_irccd, m_plugin); } };
--- a/tests/js-file/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/js-file/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -21,23 +21,23 @@ #include <gtest/gtest.h> #include <irccd/irccd.hpp> -#include <irccd/mod-file.hpp> -#include <irccd/mod-irccd.hpp> -#include <irccd/plugin-js.hpp> +#include <irccd/js_file_module.hpp> +#include <irccd/js_irccd_module.hpp> +#include <irccd/js_plugin.hpp> #include <irccd/service.hpp> using namespace irccd; class TestJsFile : public testing::Test { protected: - Irccd m_irccd; - std::shared_ptr<JsPlugin> m_plugin; + irccd::irccd m_irccd; + std::shared_ptr<js_plugin> m_plugin; TestJsFile() - : m_plugin(std::make_shared<JsPlugin>("empty", SOURCEDIR "/empty.js")) + : m_plugin(std::make_shared<js_plugin>("empty", SOURCEDIR "/empty.js")) { - IrccdModule().load(m_irccd, m_plugin); - FileModule().load(m_irccd, m_plugin); + js_irccd_module().load(m_irccd, m_plugin); + js_file_module().load(m_irccd, m_plugin); } };
--- a/tests/js-irccd/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/js-irccd/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -19,8 +19,8 @@ #include <gtest/gtest.h> #include <irccd/irccd.hpp> -#include <irccd/mod-irccd.hpp> -#include <irccd/plugin-js.hpp> +#include <irccd/js_irccd_module.hpp> +#include <irccd/js_plugin.hpp> #include <irccd/service.hpp> #include <irccd/sysconfig.hpp> @@ -28,13 +28,13 @@ class TestJsIrccd : public testing::Test { protected: - Irccd m_irccd; - std::shared_ptr<JsPlugin> m_plugin; + irccd::irccd m_irccd; + std::shared_ptr<js_plugin> m_plugin; TestJsIrccd() - : m_plugin(std::make_shared<JsPlugin>("empty", SOURCEDIR "/empty.js")) + : m_plugin(std::make_shared<js_plugin>("empty", SOURCEDIR "/empty.js")) { - IrccdModule().load(m_irccd, m_plugin); + js_irccd_module().load(m_irccd, m_plugin); } }; @@ -98,7 +98,7 @@ { try { duk_push_c_function(m_plugin->context(), [] (duk_context *ctx) -> duk_ret_t { - dukx_throw(ctx, SystemError(EINVAL, "hey")); + dukx_throw(ctx, system_error(EINVAL, "hey")); return 0; }, 0);
--- a/tests/js-logger/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/js-logger/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -16,105 +16,86 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include <gtest/gtest.h> +#define BOOST_TEST_MODULE "Logger Javascript API" +#include <boost/test/unit_test.hpp> -#include <irccd/irccd.hpp> #include <irccd/logger.hpp> -#include <irccd/mod-irccd.hpp> -#include <irccd/mod-logger.hpp> -#include <irccd/mod-plugin.hpp> -#include <irccd/plugin-js.hpp> -#include <irccd/service.hpp> -#include <irccd/sysconfig.hpp> +#include <irccd/js_logger_module.hpp> +#include <irccd/js_plugin_module.hpp> + +#include <js_test.hpp> + +namespace irccd { -using namespace irccd; +class logger_test : public js_test<js_logger_module, js_plugin_module> { +protected: + std::string line_info; + std::string line_warning; + std::string line_debug; -namespace { + class my_logger : public log::logger { + private: + logger_test& test_; -std::string lineInfo; -std::string lineWarning; -std::string lineDebug; + public: + inline my_logger(logger_test& test) noexcept + : test_(test) + { + } + + void info(const std::string& line) override + { + test_.line_info = line; + } -} // !namespace + void warning(const std::string& line) override + { + test_.line_warning = line; + } -class LoggerIfaceTest : public log::Logger { -public: - void info(const std::string &line) override + void debug(const std::string& line) override + { + test_.line_debug = line; + } + }; + + logger_test() { - lineInfo = line; - } - - void warning(const std::string &line) override - { - lineWarning = line; - } - - void debug(const std::string &line) override - { - lineDebug = line; + log::set_verbose(true); + log::set_logger(std::make_unique<my_logger>(*this)); } }; -class TestJsLogger : public testing::Test { -protected: - Irccd m_irccd; - std::shared_ptr<JsPlugin> m_plugin; +BOOST_FIXTURE_TEST_SUITE(js_logger_suite, logger_test) - TestJsLogger() - : m_plugin(std::make_shared<JsPlugin>("test", SOURCEDIR "/empty.js")) - { - IrccdModule().load(m_irccd, m_plugin); - PluginModule().load(m_irccd, m_plugin); - LoggerModule().load(m_irccd, m_plugin); - } -}; +BOOST_AUTO_TEST_CASE(info) +{ + if (duk_peval_string(plugin_->context(), "Irccd.Logger.info(\"hello!\");") != 0) + throw dukx_exception(plugin_->context(), -1); -TEST_F(TestJsLogger, info) -{ - try { - if (duk_peval_string(m_plugin->context(), "Irccd.Logger.info(\"hello!\");") != 0) - throw dukx_exception(m_plugin->context(), -1); - - ASSERT_EQ("plugin test: hello!", lineInfo); - } catch (const std::exception &ex) { - FAIL() << ex.what(); - } + BOOST_TEST("plugin test: hello!" == line_info); } -TEST_F(TestJsLogger, warning) +BOOST_AUTO_TEST_CASE(warning) { - try { - if (duk_peval_string(m_plugin->context(), "Irccd.Logger.warning(\"FAIL!\");") != 0) - throw dukx_exception(m_plugin->context(), -1); + if (duk_peval_string(plugin_->context(), "Irccd.Logger.warning(\"FAIL!\");") != 0) + throw dukx_exception(plugin_->context(), -1); - ASSERT_EQ("plugin test: FAIL!", lineWarning); - } catch (const std::exception &ex) { - FAIL() << ex.what(); - } + BOOST_TEST("plugin test: FAIL!" == line_warning); } #if !defined(NDEBUG) -TEST_F(TestJsLogger, debug) +BOOST_AUTO_TEST_CASE(debug) { - try { - if (duk_peval_string(m_plugin->context(), "Irccd.Logger.debug(\"starting\");") != 0) - throw dukx_exception(m_plugin->context(), -1); + if (duk_peval_string(plugin_->context(), "Irccd.Logger.debug(\"starting\");") != 0) + throw dukx_exception(plugin_->context(), -1); - ASSERT_EQ("plugin test: starting", lineDebug); - } catch (const std::exception &ex) { - FAIL() << ex.what(); - } + BOOST_TEST("plugin test: starting" == line_debug); } #endif -int main(int argc, char **argv) -{ - testing::InitGoogleTest(&argc, argv); +BOOST_AUTO_TEST_SUITE_END() - log::setVerbose(true); - log::setLogger(std::make_unique<LoggerIfaceTest>()); - - return RUN_ALL_TESTS(); -} +} // !irccd
--- a/tests/js-system/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/js-system/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -19,10 +19,10 @@ #include <gtest/gtest.h> #include <irccd/irccd.hpp> -#include <irccd/mod-file.hpp> -#include <irccd/mod-irccd.hpp> -#include <irccd/mod-system.hpp> -#include <irccd/plugin-js.hpp> +#include <irccd/js_file_module.hpp> +#include <irccd/js_irccd_module.hpp> +#include <irccd/js_system_module.hpp> +#include <irccd/js_plugin.hpp> #include <irccd/service.hpp> #include <irccd/sysconfig.hpp> #include <irccd/system.hpp> @@ -31,15 +31,15 @@ class TestJsSystem : public testing::Test { protected: - Irccd m_irccd; - std::shared_ptr<JsPlugin> m_plugin; + irccd::irccd m_irccd; + std::shared_ptr<js_plugin> m_plugin; TestJsSystem() - : m_plugin(std::make_shared<JsPlugin>("empty", SOURCEDIR "/empty.js")) + : m_plugin(std::make_shared<js_plugin>("empty", SOURCEDIR "/empty.js")) { - IrccdModule().load(m_irccd, m_plugin); - FileModule().load(m_irccd, m_plugin); - SystemModule().load(m_irccd, m_plugin); + js_irccd_module().load(m_irccd, m_plugin); + js_file_module().load(m_irccd, m_plugin); + js_system_module().load(m_irccd, m_plugin); } };
--- a/tests/js-timer/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/js-timer/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -16,96 +16,50 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include <gtest/gtest.h> +#define BOOST_TEST_MODULE "Timer Javascript API" +#include <boost/test/unit_test.hpp> +#include <boost/timer/timer.hpp> -#include <irccd/elapsed-timer.hpp> -#include <irccd/irccd.hpp> -#include <irccd/logger.hpp> -#include <irccd/mod-irccd.hpp> -#include <irccd/mod-plugin.hpp> -#include <irccd/mod-timer.hpp> -#include <irccd/plugin-js.hpp> -#include <irccd/service.hpp> -#include <irccd/system.hpp> - -using namespace irccd; +#include <irccd/js_plugin_module.hpp> +#include <irccd/js_timer_module.hpp> -class TestJsTimer : public testing::Test { -protected: - Irccd m_irccd; - std::shared_ptr<JsPlugin> m_plugin; +#include <js_test.hpp> + +namespace irccd { - void open(const std::string &file) - { - m_plugin = std::make_shared<JsPlugin>("timer", file); - - IrccdModule().load(m_irccd, m_plugin); - PluginModule().load(m_irccd, m_plugin); - TimerModule().load(m_irccd, m_plugin); - - m_plugin->onLoad(m_irccd); - m_irccd.plugins().add(m_plugin); - } +class fixture : public js_test<js_plugin_module, js_timer_module> { +public: + using js_test::js_test; }; -TEST_F(TestJsTimer, single) +BOOST_AUTO_TEST_SUITE(js_timer_suite) + +BOOST_AUTO_TEST_CASE(single) { - open(DIRECTORY "/timer-single.js"); - - ElapsedTimer timer; + fixture f(DIRECTORY "/timer-single.js"); - while (timer.elapsed() < 3000) - util::poller::poll(512, m_irccd); + boost::timer::cpu_timer timer; - ASSERT_TRUE(duk_get_global_string(m_plugin->context(), "count")); - ASSERT_EQ(1, duk_get_int(m_plugin->context(), -1)); + while (timer.elapsed().wall / 1000000LL < 3000) + util::poller::poll(512, f.irccd_); + + BOOST_TEST(duk_get_global_string(f.plugin_->context(), "count")); + BOOST_TEST(duk_get_int(f.plugin_->context(), -1) == 1); } -TEST_F(TestJsTimer, repeat) +BOOST_AUTO_TEST_CASE(repeat) { - open(DIRECTORY "/timer-repeat.js"); + fixture f(DIRECTORY "/timer-repeat.js"); - ElapsedTimer timer; + boost::timer::cpu_timer timer; - while (timer.elapsed() < 3000) - util::poller::poll(512, m_irccd); + while (timer.elapsed().wall / 1000000LL < 3000) + util::poller::poll(512, f.irccd_); - ASSERT_TRUE(duk_get_global_string(m_plugin->context(), "count")); - ASSERT_GE(duk_get_int(m_plugin->context(), -1), 5); + BOOST_TEST(duk_get_global_string(f.plugin_->context(), "count")); + BOOST_TEST(duk_get_int(f.plugin_->context(), -1) >= 5); } -#if 0 - -/* - * XXX: currently disabled because it will break single-shot timers. - */ - -TEST(Basic, pending) -{ - /* - * This test ensure that if pending actions on a stopped timer are never executed. - */ - Irccd irccd; - ElapsedTimer timer; - - auto plugin = std::make_shared<Plugin>("timer", DIRECTORY "/timer-pending.js"); +BOOST_AUTO_TEST_SUITE_END() - irccd.addPlugin(plugin); - irccd.poll(); - irccd.dispatch(); - - ASSERT_EQ(0, plugin->context().getGlobal<int>("count")); -} - -#endif - -int main(int argc, char **argv) -{ - // Needed for some components. - sys::setProgramName("irccd"); - log::setLogger(std::make_unique<log::SilentLogger>()); - log::setVerbose(true); - testing::InitGoogleTest(&argc, argv); - - return RUN_ALL_TESTS(); -} +} // !irccd
--- a/tests/js-unicode/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/js-unicode/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -23,9 +23,9 @@ #include <gtest/gtest.h> #include <irccd/irccd.hpp> -#include <irccd/mod-irccd.hpp> -#include <irccd/mod-unicode.hpp> -#include <irccd/plugin-js.hpp> +#include <irccd/js_irccd_module.hpp> +#include <irccd/js_unicode_module.hpp> +#include <irccd/js_plugin.hpp> #include <irccd/service.hpp> #include <irccd/system.hpp> @@ -33,14 +33,14 @@ class TestJsUnicode : public testing::Test { protected: - Irccd m_irccd; - std::shared_ptr<JsPlugin> m_plugin; + irccd::irccd m_irccd; + std::shared_ptr<js_plugin> m_plugin; TestJsUnicode() - : m_plugin(std::make_shared<JsPlugin>("empty", SOURCEDIR "/empty.js")) + : m_plugin(std::make_shared<js_plugin>("empty", SOURCEDIR "/empty.js")) { - IrccdModule().load(m_irccd, m_plugin); - UnicodeModule().load(m_irccd, m_plugin); + js_irccd_module().load(m_irccd, m_plugin); + js_unicode_module().load(m_irccd, m_plugin); } };
--- a/tests/js-util/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/js-util/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -19,9 +19,9 @@ #include <gtest/gtest.h> #include <irccd/irccd.hpp> -#include <irccd/mod-irccd.hpp> -#include <irccd/mod-util.hpp> -#include <irccd/plugin-js.hpp> +#include <irccd/js_irccd_module.hpp> +#include <irccd/js_util_module.hpp> +#include <irccd/js_plugin.hpp> #include <irccd/service.hpp> #include <irccd/system.hpp> @@ -29,14 +29,14 @@ class TestJsUtil : public testing::Test { protected: - Irccd m_irccd; - std::shared_ptr<JsPlugin> m_plugin; + irccd::irccd m_irccd; + std::shared_ptr<js_plugin> m_plugin; TestJsUtil() - : m_plugin(std::make_shared<JsPlugin>("empty", SOURCEDIR "/empty.js")) + : m_plugin(std::make_shared<js_plugin>("empty", SOURCEDIR "/empty.js")) { - IrccdModule().load(m_irccd, m_plugin); - UtilModule().load(m_irccd, m_plugin); + js_irccd_module().load(m_irccd, m_plugin); + js_util_module().load(m_irccd, m_plugin); } };
--- a/tests/js/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/js/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -16,16 +16,17 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include <gtest/gtest.h> +#define BOOST_TEST_MODULE "Javascript" +#include <boost/test/unit_test.hpp> #include <duktape.hpp> #include <fs.hpp> namespace irccd { -class Test : public testing::Test { +class test { protected: - UniqueContext m_ctx; + UniqueContext ctx_; }; /* @@ -33,37 +34,34 @@ * ------------------------------------------------------------------ */ -TEST_F(Test, no_file) +BOOST_FIXTURE_TEST_SUITE(test_suite, test) + +BOOST_AUTO_TEST_CASE(no_file) { - ASSERT_THROW(dukx_peval_file(m_ctx, "nonexistent"), Exception); + BOOST_REQUIRE_THROW(dukx_peval_file(ctx_, "nonexistent"), Exception); try { - dukx_peval_file(m_ctx, "nonexistent"); + dukx_peval_file(ctx_, "nonexistent"); } catch (const Exception& ex) { - ASSERT_EQ("Error", ex.name); - ASSERT_EQ("nonexistent", ex.fileName); + BOOST_REQUIRE_EQUAL("Error", ex.name); + BOOST_REQUIRE_EQUAL("nonexistent", ex.fileName); } } -TEST_F(Test, syntax_error) +BOOST_AUTO_TEST_CASE(syntax_error) { - ASSERT_THROW(dukx_peval_file(m_ctx, SOURCEDIR "/syntax-error.js"), Exception); + BOOST_REQUIRE_THROW(dukx_peval_file(ctx_, SOURCEDIR "/syntax-error.js"), Exception); try { - dukx_peval_file(m_ctx, SOURCEDIR "/syntax-error.js"); + dukx_peval_file(ctx_, SOURCEDIR "/syntax-error.js"); } catch (const Exception& ex) { - ASSERT_EQ("SyntaxError", ex.name); - ASSERT_EQ("syntax-error.js", fs::baseName(ex.fileName)); - ASSERT_EQ(6, ex.lineNumber); - ASSERT_EQ("empty expression not allowed (line 6)", ex.message); + BOOST_REQUIRE_EQUAL("SyntaxError", ex.name); + BOOST_REQUIRE_EQUAL("syntax-error.js", fs::baseName(ex.fileName)); + BOOST_REQUIRE_EQUAL(6, ex.lineNumber); + BOOST_REQUIRE_EQUAL("empty expression not allowed (line 6)", ex.message); } } -} // !irccd +BOOST_AUTO_TEST_SUITE_END() -int main(int argc, char **argv) -{ - testing::InitGoogleTest(&argc, argv); - - return RUN_ALL_TESTS(); -} +} // !irccd
--- a/tests/logger/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/logger/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -32,7 +32,7 @@ } // !namespace -class MyInterface : public log::Logger { +class MyInterface : public log::logger { public: void debug(const std::string &line) override { @@ -50,19 +50,19 @@ } }; -class MyFilter : public log::Filter { +class MyFilter : public log::filter { public: - std::string preDebug(std::string input) const override + std::string pre_debug(std::string input) const override { return std::reverse(input.begin(), input.end()), input; } - std::string preInfo(std::string input) const override + std::string pre_info(std::string input) const override { return std::reverse(input.begin(), input.end()), input; } - std::string preWarning(std::string input) const override + std::string pre_warning(std::string input) const override { return std::reverse(input.begin(), input.end()), input; } @@ -95,9 +95,9 @@ int main(int argc, char **argv) { - log::setVerbose(true); - log::setLogger(std::make_unique<MyInterface>()); - log::setFilter(std::make_unique<MyFilter>()); + log::set_verbose(true); + log::set_logger(std::make_unique<MyInterface>()); + log::set_filter(std::make_unique<MyFilter>()); testing::InitGoogleTest(&argc, argv);
--- a/tests/plugin-ask/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/plugin-ask/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -26,13 +26,13 @@ using namespace irccd; -class server_test : public Server { +class server_test : public server { private: std::string last_; public: inline server_test() - : Server("test") + : server("test") { } @@ -72,7 +72,7 @@ * answers in that amount of tries. */ for (int i = 0; i < 1000; ++i) { - plugin_->on_command(irccd_, MessageEvent{server_, "tester", "#dummy", ""}); + plugin_->on_command(irccd_, {server_, "tester", "#dummy", ""}); if (server_->last() == "#dummy:tester, YES") yes = true;
--- a/tests/plugin-auth/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/plugin-auth/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -26,13 +26,13 @@ using namespace irccd; -class server_test : public Server { +class server_test : public server { private: std::string last_; public: inline server_test(std::string name) - : Server(std::move(name)) + : server(std::move(name)) { } @@ -76,21 +76,21 @@ TEST_F(auth_test, nickserv1) { - plugin_->on_connect(irccd_, ConnectEvent{nickserv1_}); + plugin_->on_connect(irccd_, {nickserv1_}); ASSERT_EQ("NickServ:identify plopation", nickserv1_->last()); } TEST_F(auth_test, nickserv2) { - plugin_->on_connect(irccd_, ConnectEvent{nickserv2_}); + plugin_->on_connect(irccd_, {nickserv2_}); ASSERT_EQ("NickServ:identify jean something", nickserv2_->last()); } TEST_F(auth_test, quakenet) { - plugin_->on_connect(irccd_, ConnectEvent{quakenet_}); + plugin_->on_connect(irccd_, {quakenet_}); ASSERT_EQ("Q@CServe.quakenet.org:AUTH mario hello", quakenet_->last()); }
--- a/tests/plugin-hangman/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/plugin-hangman/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -29,13 +29,13 @@ using namespace irccd; -class ServerTest : public Server { +class ServerTest : public server { private: std::string m_last; public: inline ServerTest() - : Server("test") + : server("test") { } @@ -53,13 +53,13 @@ class HangmanTest : public PluginTester { protected: std::shared_ptr<ServerTest> m_server; - std::shared_ptr<Plugin> m_plugin; + std::shared_ptr<plugin> m_plugin; public: HangmanTest() : m_server(std::make_shared<ServerTest>()) { - m_irccd.plugins().setFormats("hangman", { + m_irccd.plugins().set_formats("hangman", { { "asked", "asked=#{plugin}:#{command}:#{server}:#{channel}:#{origin}:#{nickname}:#{letter}" }, { "dead", "dead=#{plugin}:#{command}:#{server}:#{channel}:#{origin}:#{nickname}:#{word}" }, { "found", "found=#{plugin}:#{command}:#{server}:#{channel}:#{origin}:#{nickname}:#{word}" }, @@ -72,14 +72,14 @@ }); } - void load(PluginConfig config = PluginConfig()) + void load(plugin_config config = {}) { // Add file if not there. if (config.count("file") == 0) config.emplace("file", SOURCEDIR "/words.conf"); - m_irccd.plugins().setConfig("hangman", config); - m_irccd.plugins().load("hangman", PLUGINDIR "/hangman.js"); + m_irccd.plugins().set_config("hangman", config); + m_irccd.plugins().load("hangman", CMAKE_SOURCE_DIR "/plugins/hangman/hangman.js"); m_plugin = m_irccd.plugins().require("hangman"); } }; @@ -88,9 +88,9 @@ { load({{ "collaborative", "false" }}); - m_plugin->onCommand(m_irccd, MessageEvent{m_server, "jean!jean@localhost", "#hangman", ""}); - m_plugin->onMessage(m_irccd, MessageEvent{m_server, "jean!jean@localhost", "#hangman", "s"}); - m_plugin->onMessage(m_irccd, MessageEvent{m_server, "jean!jean@localhost", "#hangman", "s"}); + m_plugin->on_command(m_irccd, {m_server, "jean!jean@localhost", "#hangman", ""}); + m_plugin->on_message(m_irccd, {m_server, "jean!jean@localhost", "#hangman", "s"}); + m_plugin->on_message(m_irccd, {m_server, "jean!jean@localhost", "#hangman", "s"}); ASSERT_EQ("#hangman:asked=hangman:!hangman:test:#hangman:jean!jean@localhost:jean:s", m_server->last()); } @@ -99,17 +99,17 @@ { load({{ "collaborative", "false" }}); - m_plugin->onCommand(m_irccd, MessageEvent{m_server, "jean!jean@localhost", "#hangman", ""}); - m_plugin->onMessage(m_irccd, MessageEvent{m_server, "jean!jean@localhost", "#hangman", "a"}); - m_plugin->onMessage(m_irccd, MessageEvent{m_server, "jean!jean@localhost", "#hangman", "b"}); - m_plugin->onMessage(m_irccd, MessageEvent{m_server, "jean!jean@localhost", "#hangman", "c"}); - m_plugin->onMessage(m_irccd, MessageEvent{m_server, "jean!jean@localhost", "#hangman", "d"}); - m_plugin->onMessage(m_irccd, MessageEvent{m_server, "jean!jean@localhost", "#hangman", "e"}); - m_plugin->onMessage(m_irccd, MessageEvent{m_server, "jean!jean@localhost", "#hangman", "f"}); - m_plugin->onMessage(m_irccd, MessageEvent{m_server, "jean!jean@localhost", "#hangman", "g"}); - m_plugin->onMessage(m_irccd, MessageEvent{m_server, "jean!jean@localhost", "#hangman", "h"}); - m_plugin->onMessage(m_irccd, MessageEvent{m_server, "jean!jean@localhost", "#hangman", "i"}); - m_plugin->onMessage(m_irccd, MessageEvent{m_server, "jean!jean@localhost", "#hangman", "j"}); + m_plugin->on_command(m_irccd, {m_server, "jean!jean@localhost", "#hangman", ""}); + m_plugin->on_message(m_irccd, {m_server, "jean!jean@localhost", "#hangman", "a"}); + m_plugin->on_message(m_irccd, {m_server, "jean!jean@localhost", "#hangman", "b"}); + m_plugin->on_message(m_irccd, {m_server, "jean!jean@localhost", "#hangman", "c"}); + m_plugin->on_message(m_irccd, {m_server, "jean!jean@localhost", "#hangman", "d"}); + m_plugin->on_message(m_irccd, {m_server, "jean!jean@localhost", "#hangman", "e"}); + m_plugin->on_message(m_irccd, {m_server, "jean!jean@localhost", "#hangman", "f"}); + m_plugin->on_message(m_irccd, {m_server, "jean!jean@localhost", "#hangman", "g"}); + m_plugin->on_message(m_irccd, {m_server, "jean!jean@localhost", "#hangman", "h"}); + m_plugin->on_message(m_irccd, {m_server, "jean!jean@localhost", "#hangman", "i"}); + m_plugin->on_message(m_irccd, {m_server, "jean!jean@localhost", "#hangman", "j"}); ASSERT_EQ("#hangman:dead=hangman:!hangman:test:#hangman:jean!jean@localhost:jean:sky", m_server->last()); } @@ -118,8 +118,8 @@ { load({{ "collaborative", "false" }}); - m_plugin->onCommand(m_irccd, MessageEvent{m_server, "jean!jean@localhost", "#hangman", ""}); - m_plugin->onMessage(m_irccd, MessageEvent{m_server, "jean!jean@localhost", "#hangman", "s"}); + m_plugin->on_command(m_irccd, {m_server, "jean!jean@localhost", "#hangman", ""}); + m_plugin->on_message(m_irccd, {m_server, "jean!jean@localhost", "#hangman", "s"}); ASSERT_EQ("#hangman:found=hangman:!hangman:test:#hangman:jean!jean@localhost:jean:s _ _", m_server->last()); } @@ -128,7 +128,7 @@ { load(); - m_plugin->onCommand(m_irccd, MessageEvent{m_server, "jean!jean@localhost", "#hangman", ""}); + m_plugin->on_command(m_irccd, {m_server, "jean!jean@localhost", "#hangman", ""}); ASSERT_EQ("#hangman:start=hangman:!hangman:test:#hangman:jean!jean@localhost:jean:_ _ _", m_server->last()); } @@ -137,10 +137,10 @@ { load({{ "collaborative", "false" }}); - m_plugin->onCommand(m_irccd, MessageEvent{m_server, "jean!jean@localhost", "#hangman", ""}); - m_plugin->onMessage(m_irccd, MessageEvent{m_server, "jean!jean@localhost", "#hangman", "s"}); - m_plugin->onMessage(m_irccd, MessageEvent{m_server, "jean!jean@localhost", "#hangman", "k"}); - m_plugin->onMessage(m_irccd, MessageEvent{m_server, "jean!jean@localhost", "#hangman", "y"}); + m_plugin->on_command(m_irccd, {m_server, "jean!jean@localhost", "#hangman", ""}); + m_plugin->on_message(m_irccd, {m_server, "jean!jean@localhost", "#hangman", "s"}); + m_plugin->on_message(m_irccd, {m_server, "jean!jean@localhost", "#hangman", "k"}); + m_plugin->on_message(m_irccd, {m_server, "jean!jean@localhost", "#hangman", "y"}); ASSERT_EQ("#hangman:win=hangman:!hangman:test:#hangman:jean!jean@localhost:jean:sky", m_server->last()); } @@ -149,8 +149,8 @@ { load({{ "collaborative", "false" }}); - m_plugin->onCommand(m_irccd, MessageEvent{m_server, "jean!jean@localhost", "#hangman", ""}); - m_plugin->onCommand(m_irccd, MessageEvent{m_server, "jean!jean@localhost", "#hangman", "sky"}); + m_plugin->on_command(m_irccd, {m_server, "jean!jean@localhost", "#hangman", ""}); + m_plugin->on_command(m_irccd, {m_server, "jean!jean@localhost", "#hangman", "sky"}); ASSERT_EQ("#hangman:win=hangman:!hangman:test:#hangman:jean!jean@localhost:jean:sky", m_server->last()); } @@ -159,8 +159,8 @@ { load(); - m_plugin->onCommand(m_irccd, MessageEvent{m_server, "jean!jean@localhost", "#hangman", ""}); - m_plugin->onMessage(m_irccd, MessageEvent{m_server, "jean!jean@localhost", "#hangman", "x"}); + m_plugin->on_command(m_irccd, {m_server, "jean!jean@localhost", "#hangman", ""}); + m_plugin->on_message(m_irccd, {m_server, "jean!jean@localhost", "#hangman", "x"}); ASSERT_EQ("#hangman:wrong-letter=hangman:!hangman:test:#hangman:jean!jean@localhost:jean:x", m_server->last()); } @@ -169,8 +169,8 @@ { load(); - m_plugin->onCommand(m_irccd, MessageEvent{m_server, "jean!jean@localhost", "#hangman", ""}); - m_plugin->onCommand(m_irccd, MessageEvent{m_server, "jean!jean@localhost", "#hangman", "cheese"}); + m_plugin->on_command(m_irccd, {m_server, "jean!jean@localhost", "#hangman", ""}); + m_plugin->on_command(m_irccd, {m_server, "jean!jean@localhost", "#hangman", "cheese"}); ASSERT_EQ("#hangman:wrong-word=hangman:!hangman:test:#hangman:jean!jean@localhost:jean:cheese", m_server->last()); } @@ -180,10 +180,10 @@ // Disable collaborative mode. load({{ "collaborative", "false" }}); - m_plugin->onCommand(m_irccd, MessageEvent{m_server, "jean!jean@localhost", "#hangman", ""}); - m_plugin->onMessage(m_irccd, MessageEvent{m_server, "jean!jean@localhost", "#hangman", "s"}); + m_plugin->on_command(m_irccd, {m_server, "jean!jean@localhost", "#hangman", ""}); + m_plugin->on_message(m_irccd, {m_server, "jean!jean@localhost", "#hangman", "s"}); ASSERT_EQ("#hangman:found=hangman:!hangman:test:#hangman:jean!jean@localhost:jean:s _ _", m_server->last()); - m_plugin->onMessage(m_irccd, MessageEvent{m_server, "jean!jean@localhost", "#hangman", "k"}); + m_plugin->on_message(m_irccd, {m_server, "jean!jean@localhost", "#hangman", "k"}); ASSERT_EQ("#hangman:found=hangman:!hangman:test:#hangman:jean!jean@localhost:jean:s k _", m_server->last()); } @@ -192,12 +192,12 @@ // Enable collaborative mode. load({{ "collaborative", "true" }}); - m_plugin->onCommand(m_irccd, MessageEvent{m_server, "jean!jean@localhost", "#hangman", ""}); - m_plugin->onMessage(m_irccd, MessageEvent{m_server, "jean!jean@localhost", "#hangman", "s"}); + m_plugin->on_command(m_irccd, {m_server, "jean!jean@localhost", "#hangman", ""}); + m_plugin->on_message(m_irccd, {m_server, "jean!jean@localhost", "#hangman", "s"}); ASSERT_EQ("#hangman:found=hangman:!hangman:test:#hangman:jean!jean@localhost:jean:s _ _", m_server->last()); - m_plugin->onMessage(m_irccd, MessageEvent{m_server, "jean!jean@localhost", "#hangman", "k"}); + m_plugin->on_message(m_irccd, {m_server, "jean!jean@localhost", "#hangman", "k"}); ASSERT_EQ("#hangman:wrong-player=hangman:!hangman:test:#hangman:jean!jean@localhost:jean:k", m_server->last()); - m_plugin->onMessage(m_irccd, MessageEvent{m_server, "francis!francis@localhost", "#hangman", "k"}); + m_plugin->on_message(m_irccd, {m_server, "francis!francis@localhost", "#hangman", "k"}); ASSERT_EQ("#hangman:found=hangman:!hangman:test:#hangman:francis!francis@localhost:francis:s k _", m_server->last()); } @@ -205,12 +205,12 @@ { load(); - m_plugin->onCommand(m_irccd, MessageEvent{m_server, "jean!jean@localhost", "#hangman", ""}); - m_plugin->onMessage(m_irccd, MessageEvent{m_server, "jean!jean@localhost", "#HANGMAN", "s"}); + m_plugin->on_command(m_irccd, {m_server, "jean!jean@localhost", "#hangman", ""}); + m_plugin->on_message(m_irccd, {m_server, "jean!jean@localhost", "#HANGMAN", "s"}); ASSERT_EQ("#hangman:found=hangman:!hangman:test:#hangman:jean!jean@localhost:jean:s _ _", m_server->last()); - m_plugin->onMessage(m_irccd, MessageEvent{m_server, "jean!jean@localhost", "#HaNGMaN", "k"}); + m_plugin->on_message(m_irccd, {m_server, "jean!jean@localhost", "#HaNGMaN", "k"}); ASSERT_EQ("#hangman:wrong-player=hangman:!hangman:test:#hangman:jean!jean@localhost:jean:k", m_server->last()); - m_plugin->onMessage(m_irccd, MessageEvent{m_server, "francis!francis@localhost", "#hAngmAn", "k"}); + m_plugin->on_message(m_irccd, {m_server, "francis!francis@localhost", "#hAngmAn", "k"}); ASSERT_EQ("#hangman:found=hangman:!hangman:test:#hangman:francis!francis@localhost:francis:s k _", m_server->last()); } @@ -219,13 +219,13 @@ load(); // Query mode is never collaborative. - m_plugin->onQueryCommand(m_irccd, QueryEvent{m_server, "jean!jean@localhost", ""}); + m_plugin->on_query_command(m_irccd, {m_server, "jean!jean@localhost", ""}); ASSERT_EQ("jean:start=hangman:!hangman:test:jean:jean!jean@localhost:jean:_ _ _", m_server->last()); - m_plugin->onQuery(m_irccd, QueryEvent{m_server, "jean!jean@localhost", "s"}); + m_plugin->on_query(m_irccd, {m_server, "jean!jean@localhost", "s"}); ASSERT_EQ("jean:found=hangman:!hangman:test:jean:jean!jean@localhost:jean:s _ _", m_server->last()); - m_plugin->onQuery(m_irccd, QueryEvent{m_server, "jean!jean@localhost", "k"}); + m_plugin->on_query(m_irccd, {m_server, "jean!jean@localhost", "k"}); ASSERT_EQ("jean:found=hangman:!hangman:test:jean:jean!jean@localhost:jean:s k _", m_server->last()); - m_plugin->onQueryCommand(m_irccd, QueryEvent{m_server, "jean!jean@localhost", "sky"}); + m_plugin->on_query_command(m_irccd, {m_server, "jean!jean@localhost", "sky"}); ASSERT_EQ("jean:win=hangman:!hangman:test:jean:jean!jean@localhost:jean:sky", m_server->last()); } @@ -233,9 +233,9 @@ { load(); - m_plugin->onCommand(m_irccd, MessageEvent{m_server, "jean!jean@localhost", "#hangman", ""}); - m_plugin->onMessage(m_irccd, MessageEvent{m_server, "jean!jean@localhost", "#hangman", "y"}); - m_plugin->onCommand(m_irccd, MessageEvent{m_server, "jean!jean@localhost", "#hangman", ""}); + m_plugin->on_command(m_irccd, {m_server, "jean!jean@localhost", "#hangman", ""}); + m_plugin->on_message(m_irccd, {m_server, "jean!jean@localhost", "#hangman", "y"}); + m_plugin->on_command(m_irccd, {m_server, "jean!jean@localhost", "#hangman", ""}); ASSERT_EQ("#hangman:running=hangman:!hangman:test:#hangman:jean!jean@localhost:jean:_ _ y", m_server->last()); } @@ -259,20 +259,20 @@ }; std::unordered_set<unsigned> found; - m_plugin->setFormats({ + m_plugin->set_formats({ { "start", "#{word}" } }); unsigned last, current; // 1. Initial game + finish. - m_plugin->onCommand(m_irccd, MessageEvent{m_server, "jean!jean@localhost", "#hangman", ""}); + m_plugin->on_command(m_irccd, {m_server, "jean!jean@localhost", "#hangman", ""}); last = m_server->last().length(); found.insert(last); - m_plugin->onCommand(m_irccd, MessageEvent{m_server, "jean!jean@localhost", "#hangman", words[last]}); + m_plugin->on_command(m_irccd, {m_server, "jean!jean@localhost", "#hangman", words[last]}); // 2. Current must not be the last one. - m_plugin->onCommand(m_irccd, MessageEvent{m_server, "jean!jean@localhost", "#hangman", ""}); + m_plugin->on_command(m_irccd, {m_server, "jean!jean@localhost", "#hangman", ""}); current = m_server->last().length(); ASSERT_NE(last, current); @@ -280,10 +280,10 @@ found.insert(current); last = current; - m_plugin->onCommand(m_irccd, MessageEvent{m_server, "jean!jean@localhost", "#hangman", words[current]}); + m_plugin->on_command(m_irccd, {m_server, "jean!jean@localhost", "#hangman", words[current]}); // 3. Last word must be the one that is kept into the map. - m_plugin->onCommand(m_irccd, MessageEvent{m_server, "jean!jean@localhost", "#hangman", ""}); + m_plugin->on_command(m_irccd, {m_server, "jean!jean@localhost", "#hangman", ""}); current = m_server->last().length(); ASSERT_NE(last, current);
--- a/tests/plugin-history/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/plugin-history/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -28,13 +28,13 @@ using namespace irccd; -class server_test : public Server { +class server_test : public server { private: std::string last_; public: inline server_test() - : Server("test") + : server("test") { } @@ -81,7 +81,7 @@ { load({{ "file", SOURCEDIR "/broken-conf.json" }}); - plugin_->on_command(irccd_, MessageEvent{server_, "jean!jean@localhost", "#history", "seen francis"}); + plugin_->on_command(irccd_, {server_, "jean!jean@localhost", "#history", "seen francis"}); ASSERT_EQ("#history:error=history:!history:test:#history:jean!jean@localhost:jean", server_->last()); } @@ -92,8 +92,8 @@ remove(BINARYDIR "/seen.json"); load({{ "file", BINARYDIR "/seen.json" }}); - plugin_->on_message(irccd_, MessageEvent{server_, "jean!jean@localhost", "#history", "hello"}); - plugin_->on_command(irccd_, MessageEvent{server_, "destructor!dst@localhost", "#history", "seen jean"}); + plugin_->on_message(irccd_, {server_, "jean!jean@localhost", "#history", "hello"}); + plugin_->on_command(irccd_, {server_, "destructor!dst@localhost", "#history", "seen jean"}); ASSERT_TRUE(std::regex_match(server_->last(), rule)); } @@ -105,8 +105,8 @@ remove(BINARYDIR "/said.json"); load({{ "file", BINARYDIR "/said.json" }}); - plugin_->on_message(irccd_, MessageEvent{server_, "jean!jean@localhost", "#history", "hello"}); - plugin_->on_command(irccd_, MessageEvent{server_, "destructor!dst@localhost", "#history", "said jean"}); + plugin_->on_message(irccd_, {server_, "jean!jean@localhost", "#history", "hello"}); + plugin_->on_command(irccd_, {server_, "destructor!dst@localhost", "#history", "said jean"}); ASSERT_TRUE(std::regex_match(server_->last(), rule)); } @@ -116,8 +116,8 @@ remove(BINARYDIR "/unknown.json"); load({{ "file", BINARYDIR "/unknown.json" }}); - plugin_->on_message(irccd_, MessageEvent{server_, "jean!jean@localhost", "#history", "hello"}); - plugin_->on_command(irccd_, MessageEvent{server_, "destructor!dst@localhost", "#history", "seen nobody"}); + plugin_->on_message(irccd_, {server_, "jean!jean@localhost", "#history", "hello"}); + plugin_->on_command(irccd_, {server_, "destructor!dst@localhost", "#history", "seen nobody"}); ASSERT_EQ("#history:unknown=history:!history:test:#history:destructor!dst@localhost:destructor:nobody", server_->last()); } @@ -129,11 +129,11 @@ remove(BINARYDIR "/case.json"); load({{"file", BINARYDIR "/case.json"}}); - plugin_->on_message(irccd_, MessageEvent{server_, "JeaN!JeaN@localhost", "#history", "hello"}); + plugin_->on_message(irccd_, {server_, "JeaN!JeaN@localhost", "#history", "hello"}); - plugin_->on_command(irccd_, MessageEvent{server_, "destructor!dst@localhost", "#HISTORY", "said JEAN"}); + plugin_->on_command(irccd_, {server_, "destructor!dst@localhost", "#HISTORY", "said JEAN"}); ASSERT_TRUE(std::regex_match(server_->last(), rule)); - plugin_->on_command(irccd_, MessageEvent{server_, "destructor!dst@localhost", "#HiSToRy", "said JeaN"}); + plugin_->on_command(irccd_, {server_, "destructor!dst@localhost", "#HiSToRy", "said JeaN"}); ASSERT_TRUE(std::regex_match(server_->last(), rule)); }
--- a/tests/plugin-logger/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/plugin-logger/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -32,7 +32,7 @@ class logger_test : public plugin_test { protected: - std::shared_ptr<Server> server_; + std::shared_ptr<server> server_; std::string last() const { @@ -44,7 +44,7 @@ public: logger_test() : plugin_test(PLUGIN_NAME, PLUGIN_PATH) - , server_(std::make_shared<Server>("test")) + , server_(std::make_shared<server>("test")) { remove(BINARYDIR "/log.txt"); @@ -77,7 +77,7 @@ { load(); - plugin_->on_channel_mode(irccd_, ChannelModeEvent{server_, "jean!jean@localhost", "#staff", "+o", "jean"}); + plugin_->on_channel_mode(irccd_, {server_, "jean!jean@localhost", "#staff", "+o", "jean"}); ASSERT_EQ("cmode=test:#staff:jean!jean@localhost:jean:+o:jean\n", last()); } @@ -86,7 +86,7 @@ { load(); - plugin_->on_channel_notice(irccd_, ChannelNoticeEvent{server_, "jean!jean@localhost", "#staff", "bonjour!"}); + plugin_->on_channel_notice(irccd_, {server_, "jean!jean@localhost", "#staff", "bonjour!"}); ASSERT_EQ("cnotice=test:#staff:jean!jean@localhost:jean:bonjour!\n", last()); } @@ -95,7 +95,7 @@ { load(); - plugin_->on_join(irccd_, JoinEvent{server_, "jean!jean@localhost", "#staff"}); + plugin_->on_join(irccd_, {server_, "jean!jean@localhost", "#staff"}); ASSERT_EQ("join=test:#staff:jean!jean@localhost:jean\n", last()); } @@ -104,7 +104,7 @@ { load(); - plugin_->on_kick(irccd_, KickEvent{server_, "jean!jean@localhost", "#staff", "badboy", "please do not flood"}); + plugin_->on_kick(irccd_, {server_, "jean!jean@localhost", "#staff", "badboy", "please do not flood"}); ASSERT_EQ("kick=test:#staff:jean!jean@localhost:jean:badboy:please do not flood\n", last()); } @@ -113,7 +113,7 @@ { load(); - plugin_->on_me(irccd_, MeEvent{server_, "jean!jean@localhost", "#staff", "is drinking water"}); + plugin_->on_me(irccd_, {server_, "jean!jean@localhost", "#staff", "is drinking water"}); ASSERT_EQ("me=test:#staff:jean!jean@localhost:jean:is drinking water\n", last()); } @@ -122,7 +122,7 @@ { load(); - plugin_->on_message(irccd_, MessageEvent{server_, "jean!jean@localhost", "#staff", "hello guys"}); + plugin_->on_message(irccd_, {server_, "jean!jean@localhost", "#staff", "hello guys"}); ASSERT_EQ("message=test:#staff:jean!jean@localhost:jean:hello guys\n", last()); } @@ -131,7 +131,7 @@ { load(); - plugin_->on_mode(irccd_, ModeEvent{server_, "jean!jean@localhost", "+i"}); + plugin_->on_mode(irccd_, {server_, "jean!jean@localhost", "+i"}); ASSERT_EQ("mode=test:jean!jean@localhost:jean:+i:\n", last()); } @@ -140,7 +140,7 @@ { load(); - plugin_->on_notice(irccd_, NoticeEvent{server_, "jean!jean@localhost", "tu veux voir mon chat ?"}); + plugin_->on_notice(irccd_, {server_, "jean!jean@localhost", "tu veux voir mon chat ?"}); ASSERT_EQ("notice=test:jean!jean@localhost:jean:tu veux voir mon chat ?\n", last()); } @@ -149,7 +149,7 @@ { load(); - plugin_->on_part(irccd_, PartEvent{server_, "jean!jean@localhost", "#staff", "too noisy here"}); + plugin_->on_part(irccd_, {server_, "jean!jean@localhost", "#staff", "too noisy here"}); ASSERT_EQ("part=test:#staff:jean!jean@localhost:jean:too noisy here\n", last()); } @@ -158,7 +158,7 @@ { load(); - plugin_->on_query(irccd_, QueryEvent{server_, "jean!jean@localhost", "much irccd, wow"}); + plugin_->on_query(irccd_, {server_, "jean!jean@localhost", "much irccd, wow"}); ASSERT_EQ("query=test:jean!jean@localhost:jean:much irccd, wow\n", last()); } @@ -167,7 +167,7 @@ { load(); - plugin_->on_topic(irccd_, TopicEvent{server_, "jean!jean@localhost", "#staff", "oh yeah yeaaaaaaaah"}); + plugin_->on_topic(irccd_, {server_, "jean!jean@localhost", "#staff", "oh yeah yeaaaaaaaah"}); ASSERT_EQ("topic=test:#staff:jean!jean@localhost:jean:oh yeah yeaaaaaaaah\n", last()); } @@ -176,7 +176,7 @@ { load(); - plugin_->on_message(irccd_, MessageEvent{server_, "jean!jean@localhost", "#STAFF", "hello guys"}); + plugin_->on_message(irccd_, {server_, "jean!jean@localhost", "#STAFF", "hello guys"}); ASSERT_EQ("message=test:#staff:jean!jean@localhost:jean:hello guys\n", last()); } @@ -184,7 +184,7 @@ int main(int argc, char** argv) { testing::InitGoogleTest(&argc, argv); - log::setLogger(std::make_unique<log::SilentLogger>()); + log::set_logger(std::make_unique<log::silent_logger>()); return RUN_ALL_TESTS(); }
--- a/tests/plugin-plugin/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/plugin-plugin/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -31,13 +31,13 @@ using namespace irccd; -class server_test : public Server { +class server_test : public server { private: std::string last_; public: inline server_test() - : Server("test") + : server("test") { } @@ -87,26 +87,26 @@ TEST_F(plugin_test_suite, formatUsage) { - plugin_->on_command(irccd_, MessageEvent{server_, "jean!jean@localhost", "#staff", ""}); + plugin_->on_command(irccd_, {server_, "jean!jean@localhost", "#staff", ""}); ASSERT_EQ("#staff:usage=plugin:!plugin:test:#staff:jean!jean@localhost:jean", server_->last()); - plugin_->on_command(irccd_, MessageEvent{server_, "jean!jean@localhost", "#staff", "fail"}); + plugin_->on_command(irccd_, {server_, "jean!jean@localhost", "#staff", "fail"}); ASSERT_EQ("#staff:usage=plugin:!plugin:test:#staff:jean!jean@localhost:jean", server_->last()); - plugin_->on_command(irccd_, MessageEvent{server_, "jean!jean@localhost", "#staff", "info"}); + plugin_->on_command(irccd_, {server_, "jean!jean@localhost", "#staff", "info"}); ASSERT_EQ("#staff:usage=plugin:!plugin:test:#staff:jean!jean@localhost:jean", server_->last()); } TEST_F(plugin_test_suite, formatInfo) { - plugin_->on_command(irccd_, MessageEvent{server_, "jean!jean@localhost", "#staff", "info fake"}); + plugin_->on_command(irccd_, {server_, "jean!jean@localhost", "#staff", "info fake"}); ASSERT_EQ("#staff:info=plugin:!plugin:test:#staff:jean!jean@localhost:jean:jean:BEER:fake:Fake White Beer 2000:0.0.0.0.0.1", server_->last()); } TEST_F(plugin_test_suite, formatNotFound) { - plugin_->on_command(irccd_, MessageEvent{server_, "jean!jean@localhost", "#staff", "info doesnotexistsihope"}); + plugin_->on_command(irccd_, {server_, "jean!jean@localhost", "#staff", "info doesnotexistsihope"}); ASSERT_EQ("#staff:not-found=plugin:!plugin:test:#staff:jean!jean@localhost:jean:doesnotexistsihope", server_->last()); } @@ -116,7 +116,7 @@ for (int i = 0; i < 100; ++i) irccd_.plugins().add(std::make_shared<plugin>("plugin-n-{}"_format(i), "")); - plugin_->on_command(irccd_, MessageEvent{server_, "jean!jean@localhost", "#staff", "list"}); + plugin_->on_command(irccd_, {server_, "jean!jean@localhost", "#staff", "list"}); ASSERT_EQ("#staff:too-long=plugin:!plugin:test:#staff:jean!jean@localhost:jean", server_->last()); } @@ -124,7 +124,7 @@ int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); - log::setLogger(std::make_unique<log::SilentLogger>()); + log::set_logger(std::make_unique<log::silent_logger>()); return RUN_ALL_TESTS(); }
--- a/tests/rules/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/rules/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -66,55 +66,55 @@ */ class RulesTest : public testing::Test { protected: - RuleService m_rules; + rule_service m_rules; RulesTest() { // #1 { m_rules.add({ - RuleSet{ }, // Servers - RuleSet{ "#staff" }, // Channels - RuleSet{ }, // Origins - RuleSet{ }, // Plugins - RuleSet{ "onCommand" }, // Events - RuleAction::Drop + rule::set{ }, // Servers + rule::set{ "#staff" }, // Channels + rule::set{ }, // Origins + rule::set{ }, // Plugins + rule::set{ "onCommand" }, // Events + rule::action_type::drop }); } // #2 { m_rules.add({ - RuleSet{ "unsafe" }, - RuleSet{ "#staff" }, - RuleSet{ }, - RuleSet{ }, - RuleSet{ "onCommand" }, - RuleAction::Accept + rule::set{ "unsafe" }, + rule::set{ "#staff" }, + rule::set{ }, + rule::set{ }, + rule::set{ "onCommand" }, + rule::action_type::accept }); } // #3-1 { m_rules.add({ - RuleSet{}, - RuleSet{}, - RuleSet{}, - RuleSet{"game"}, - RuleSet{}, - RuleAction::Drop + rule::set{}, + rule::set{}, + rule::set{}, + rule::set{"game"}, + rule::set{}, + rule::action_type::drop }); } // #3-2 { m_rules.add({ - RuleSet{ "malikania", "localhost" }, - RuleSet{ "#games" }, - RuleSet{ }, - RuleSet{ "game" }, - RuleSet{ "onCommand", "onMessage" }, - RuleAction::Accept + rule::set{ "malikania", "localhost" }, + rule::set{ "#games" }, + rule::set{ }, + rule::set{ "game" }, + rule::set{ "onCommand", "onMessage" }, + rule::action_type::accept }); } } @@ -122,7 +122,7 @@ TEST_F(RulesTest, basicMatch1) { - Rule m; + rule m; /* * [rule] @@ -133,7 +133,7 @@ TEST_F(RulesTest, basicMatch2) { - Rule m(RuleSet{"freenode"}); + rule m(rule::set{"freenode"}); /* * [rule] @@ -147,7 +147,7 @@ TEST_F(RulesTest, basicMatch3) { - Rule m(RuleSet{"freenode"}, RuleSet{"#staff"}); + rule m(rule::set{"freenode"}, rule::set{"#staff"}); /* * [rule] @@ -162,7 +162,7 @@ TEST_F(RulesTest, basicMatch4) { - Rule m(RuleSet{"malikania"}, RuleSet{"#staff"}, RuleSet{"a"}); + rule m(rule::set{"malikania"}, rule::set{"#staff"}, rule::set{"a"}); /* * [rule] @@ -178,7 +178,7 @@ TEST_F(RulesTest, complexMatch1) { - Rule m(RuleSet{"malikania", "freenode"}); + rule m(rule::set{"malikania", "freenode"}); /* * [rule] @@ -238,7 +238,7 @@ int main(int argc, char **argv) { - irccd::log::setLogger(std::make_unique<irccd::log::SilentLogger>()); + irccd::log::set_logger(std::make_unique<irccd::log::silent_logger>()); testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS();
--- a/tests/service-plugin/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/service-plugin/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -25,9 +25,9 @@ TEST(service_plugin, default_paths) { - Irccd irccd; + irccd irccd; - irccd.plugins().setPaths({ + irccd.plugins().set_paths({ { "cache", "/var/cache/irccd" }, { "config", "/etc/irccd" }, { "data", "/usr/local/share/irccd" } @@ -42,14 +42,14 @@ TEST(service_plugin, override_cache) { - Irccd irccd; + irccd irccd; - irccd.plugins().setPaths({ + irccd.plugins().set_paths({ { "cache", "/var/cache/irccd" }, { "config", "/etc/irccd" }, { "data", "/usr/local/share/irccd" } }); - irccd.plugins().setPaths("ask", { + irccd.plugins().set_paths("ask", { { "cache", "/opt/cache/ask" } }); @@ -62,14 +62,14 @@ TEST(service_plugin, override_config) { - Irccd irccd; + irccd irccd; - irccd.plugins().setPaths({ + irccd.plugins().set_paths({ { "cache", "/var/cache/irccd" }, { "config", "/etc/irccd" }, { "data", "/usr/local/share/irccd" } }); - irccd.plugins().setPaths("ask", { + irccd.plugins().set_paths("ask", { { "config", "/opt/config/ask" } }); @@ -82,14 +82,14 @@ TEST(service_plugin, override_data) { - Irccd irccd; + irccd irccd; - irccd.plugins().setPaths({ + irccd.plugins().set_paths({ { "cache", "/var/cache/irccd" }, { "config", "/etc/irccd" }, { "data", "/usr/local/share/irccd" } }); - irccd.plugins().setPaths("ask", { + irccd.plugins().set_paths("ask", { { "data", "/opt/data/ask" } }); @@ -102,14 +102,14 @@ TEST(service_plugin, override_all) { - Irccd irccd; + irccd irccd; - irccd.plugins().setPaths({ + irccd.plugins().set_paths({ { "cache", "/var/cache/irccd" }, { "config", "/etc/irccd" }, { "data", "/usr/local/share/irccd" } }); - irccd.plugins().setPaths("ask", { + irccd.plugins().set_paths("ask", { { "cache", "/opt/cache/ask" }, { "config", "/opt/config/ask" }, { "data", "/opt/data/ask" } @@ -124,14 +124,14 @@ TEST(service_plugin, extra_paths) { - Irccd irccd; + irccd irccd; - irccd.plugins().setPaths({ + irccd.plugins().set_paths({ { "cache", "/var/cache/irccd" }, { "config", "/etc/irccd" }, { "data", "/usr/local/share/irccd" } }); - irccd.plugins().setPaths("ask", { + irccd.plugins().set_paths("ask", { { "extra", "/opt/magic" } });
--- a/tests/timer/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/timer/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -25,16 +25,16 @@ using namespace std::chrono_literals; /* -------------------------------------------------------- - * Timer object itself + * timer object itself * -------------------------------------------------------- */ TEST(Basic, single) { - Timer timer(TimerType::Single, 1000); + timer timer(timer::type::single, 1000); ElapsedTimer elapsed; int count = 0; - timer.onSignal.connect([&] () { + timer.on_signal.connect([&] () { count = elapsed.elapsed(); }); @@ -45,15 +45,14 @@ ASSERT_GE(count, 900); ASSERT_LE(count, 1100); - } TEST(Basic, repeat) { - Timer timer(TimerType::Repeat, 500); + timer timer(timer::type::repeat, 500); int max = 0; - timer.onSignal.connect([&] () { + timer.on_signal.connect([&] () { max ++; }); @@ -69,10 +68,10 @@ TEST(Basic, restart) { - Timer timer(TimerType::Repeat, 500); + timer timer(timer::type::repeat, 500); int max = 0; - timer.onSignal.connect([&] () { + timer.on_signal.connect([&] () { max ++; });
--- a/tests/util/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/tests/util/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -16,89 +16,105 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include <cstdint> +#define BOOST_TEST_MODULE "util" +#include <boost/test/unit_test.hpp> -#include <gtest/gtest.h> +#include <cstdint> #include <irccd/util.hpp> #include <irccd/system.hpp> +namespace std { + +std::ostream& operator<<(std::ostream& out, const std::vector<std::string>& list) +{ + for (const auto& s : list) + out << s << " "; + + return out; +} + +} // !std + namespace irccd { -/* -------------------------------------------------------- +BOOST_AUTO_TEST_SUITE(format) + +/* * util::format function - * -------------------------------------------------------- */ + * -------------------------------------------------------- + */ -TEST(Format, nothing) +BOOST_AUTO_TEST_CASE(nothing) { std::string expected = "hello world!"; std::string result = util::format("hello world!"); - ASSERT_EQ(expected, result); + BOOST_REQUIRE_EQUAL(expected, result); } -TEST(Format, escape) +BOOST_AUTO_TEST_CASE(escape) { - util::Substitution params; + util::subst params; params.keywords.emplace("target", "hello"); - ASSERT_EQ("$@#", util::format("$@#")); - ASSERT_EQ(" $ @ # ", util::format(" $ @ # ")); - ASSERT_EQ("#", util::format("#")); - ASSERT_EQ(" # ", util::format(" # ")); - ASSERT_EQ("#@", util::format("#@")); - ASSERT_EQ("##", util::format("##")); - ASSERT_EQ("#!", util::format("#!")); - ASSERT_EQ("#{target}", util::format("##{target}")); - ASSERT_EQ("@hello", util::format("@#{target}", params)); - ASSERT_EQ("hello#", util::format("#{target}#", params)); - ASSERT_ANY_THROW(util::format("#{failure")); + BOOST_REQUIRE_EQUAL("$@#", util::format("$@#")); + BOOST_REQUIRE_EQUAL(" $ @ # ", util::format(" $ @ # ")); + BOOST_REQUIRE_EQUAL("#", util::format("#")); + BOOST_REQUIRE_EQUAL(" # ", util::format(" # ")); + BOOST_REQUIRE_EQUAL("#@", util::format("#@")); + BOOST_REQUIRE_EQUAL("##", util::format("##")); + BOOST_REQUIRE_EQUAL("#!", util::format("#!")); + BOOST_REQUIRE_EQUAL("#{target}", util::format("##{target}")); + BOOST_REQUIRE_EQUAL("@hello", util::format("@#{target}", params)); + BOOST_REQUIRE_EQUAL("hello#", util::format("#{target}#", params)); + BOOST_REQUIRE_THROW(util::format("#{failure"), std::exception); } -TEST(Format, disableDate) +BOOST_AUTO_TEST_CASE(disable_date) { - util::Substitution params; + util::subst params; - params.flags &= ~(util::Substitution::Date); + params.flags &= ~(util::subst_flags::date); - ASSERT_EQ("%H:%M", util::format("%H:%M", params)); + BOOST_REQUIRE_EQUAL("%H:%M", util::format("%H:%M", params)); } -TEST(Format, disableKeywords) +BOOST_AUTO_TEST_CASE(disable_keywords) { - util::Substitution params; + util::subst params; params.keywords.emplace("target", "hello"); - params.flags &= ~(util::Substitution::Keywords); + params.flags &= ~(util::subst_flags::keywords); - ASSERT_EQ("#{target}", util::format("#{target}", params)); + BOOST_REQUIRE_EQUAL("#{target}", util::format("#{target}", params)); } -TEST(Format, disableEnv) +BOOST_AUTO_TEST_CASE(disable_env) { - util::Substitution params; + util::subst params; - params.flags &= ~(util::Substitution::Env); + params.flags &= ~(util::subst_flags::env); - ASSERT_EQ("${HOME}", util::format("${HOME}", params)); + BOOST_REQUIRE_EQUAL("${HOME}", util::format("${HOME}", params)); } -TEST(Format, keywordSimple) +BOOST_AUTO_TEST_CASE(keyword_simple) { - util::Substitution params; + util::subst params; params.keywords.insert({"target", "irccd"}); std::string expected = "hello irccd!"; std::string result = util::format("hello #{target}!", params); - ASSERT_EQ(expected, result); + BOOST_REQUIRE_EQUAL(expected, result); } -TEST(Format, keywordMultiple) +BOOST_AUTO_TEST_CASE(keyword_multiple) { - util::Substitution params; + util::subst params; params.keywords.insert({"target", "irccd"}); params.keywords.insert({"source", "nightmare"}); @@ -106,30 +122,30 @@ std::string expected = "hello irccd from nightmare!"; std::string result = util::format("hello #{target} from #{source}!", params); - ASSERT_EQ(expected, result); + BOOST_REQUIRE_EQUAL(expected, result); } -TEST(Format, keywordAdjTwice) +BOOST_AUTO_TEST_CASE(keyword_adj_twice) { - util::Substitution params; + util::subst params; params.keywords.insert({"target", "irccd"}); std::string expected = "hello irccdirccd!"; std::string result = util::format("hello #{target}#{target}!", params); - ASSERT_EQ(expected, result); + BOOST_REQUIRE_EQUAL(expected, result); } -TEST(Format, keywordMissing) +BOOST_AUTO_TEST_CASE(keyword_missing) { std::string expected = "hello !"; std::string result = util::format("hello #{target}!"); - ASSERT_EQ(expected, result); + BOOST_REQUIRE_EQUAL(expected, result); } -TEST(Format, envSimple) +BOOST_AUTO_TEST_CASE(env_simple) { std::string home = sys::env("HOME"); @@ -137,282 +153,311 @@ std::string expected = "my home is " + home; std::string result = util::format("my home is ${HOME}"); - ASSERT_EQ(expected, result); + BOOST_REQUIRE_EQUAL(expected, result); } } -TEST(Format, envMissing) +BOOST_AUTO_TEST_CASE(env_missing) { std::string expected = "value is "; std::string result = util::format("value is ${HOPE_THIS_VAR_NOT_EXIST}"); - ASSERT_EQ(expected, result); + BOOST_REQUIRE_EQUAL(expected, result); } -/* -------------------------------------------------------- +BOOST_AUTO_TEST_SUITE_END() + +/* * util::split function - * -------------------------------------------------------- */ + * -------------------------------------------------------- + */ -using List = std::vector<std::string>; +BOOST_AUTO_TEST_SUITE(split) -TEST(Split, simple) +using list = std::vector<std::string>; + +BOOST_AUTO_TEST_CASE(simple) { - List expected { "a", "b" }; - List result = util::split("a;b", ";"); + list expected { "a", "b" }; + list result = util::split("a;b", ";"); - ASSERT_EQ(expected, result); + BOOST_REQUIRE_EQUAL(expected, result); } -TEST(Split, cut) +BOOST_AUTO_TEST_CASE(cut) { - List expected { "msg", "#staff", "foo bar baz" }; - List result = util::split("msg;#staff;foo bar baz", ";", 3); + list expected { "msg", "#staff", "foo bar baz" }; + list result = util::split("msg;#staff;foo bar baz", ";", 3); - ASSERT_EQ(expected, result); + BOOST_REQUIRE_EQUAL(expected, result); } -/* -------------------------------------------------------- +BOOST_AUTO_TEST_SUITE_END() + +/* * util::strip function - * -------------------------------------------------------- */ + * -------------------------------------------------------- + */ -TEST(Strip, left) +BOOST_AUTO_TEST_SUITE(strip) + +BOOST_AUTO_TEST_CASE(left) { std::string value = " 123"; std::string result = util::strip(value); - ASSERT_EQ("123", result); + BOOST_REQUIRE_EQUAL("123", result); } -TEST(Strip, right) +BOOST_AUTO_TEST_CASE(right) { std::string value = "123 "; std::string result = util::strip(value); - ASSERT_EQ("123", result); + BOOST_REQUIRE_EQUAL("123", result); } -TEST(Strip, both) +BOOST_AUTO_TEST_CASE(both) { std::string value = " 123 "; std::string result = util::strip(value); - ASSERT_EQ("123", result); + BOOST_REQUIRE_EQUAL("123", result); } -TEST(Strip, none) +BOOST_AUTO_TEST_CASE(none) { std::string value = "without"; std::string result = util::strip(value); - ASSERT_EQ("without", result); + BOOST_REQUIRE_EQUAL("without", result); } -TEST(Strip, betweenEmpty) +BOOST_AUTO_TEST_CASE(betweenEmpty) { std::string value = "one list"; std::string result = util::strip(value); - ASSERT_EQ("one list", result); + BOOST_REQUIRE_EQUAL("one list", result); } -TEST(Strip, betweenLeft) +BOOST_AUTO_TEST_CASE(betweenLeft) { std::string value = " space at left"; std::string result = util::strip(value); - ASSERT_EQ("space at left", result); + BOOST_REQUIRE_EQUAL("space at left", result); } -TEST(Strip, betweenRight) +BOOST_AUTO_TEST_CASE(betweenRight) { std::string value = "space at right "; std::string result = util::strip(value); - ASSERT_EQ("space at right", result); + BOOST_REQUIRE_EQUAL("space at right", result); } -TEST(Strip, betweenBoth) +BOOST_AUTO_TEST_CASE(betweenBoth) { std::string value = " space at both "; std::string result = util::strip(value); - ASSERT_EQ("space at both", result); + BOOST_REQUIRE_EQUAL("space at both", result); } -TEST(Strip, empty) +BOOST_AUTO_TEST_CASE(empty) { std::string value = " "; std::string result = util::strip(value); - ASSERT_EQ("", result); -} + BOOST_REQUIRE_EQUAL("", result); +} + +BOOST_AUTO_TEST_SUITE_END() -/* -------------------------------------------------------- +/* * util::join function - * -------------------------------------------------------- */ + * -------------------------------------------------------- + */ -TEST(Join, empty) +BOOST_AUTO_TEST_SUITE(join) + +BOOST_AUTO_TEST_CASE(empty) { std::string expected = ""; std::string result = util::join<int>({}); - ASSERT_EQ(expected, result); + BOOST_REQUIRE_EQUAL(expected, result); } -TEST(Join, one) +BOOST_AUTO_TEST_CASE(one) { std::string expected = "1"; std::string result = util::join({1}); - ASSERT_EQ(expected, result); + BOOST_REQUIRE_EQUAL(expected, result); } -TEST(Join, two) +BOOST_AUTO_TEST_CASE(two) { std::string expected = "1:2"; std::string result = util::join({1, 2}); - ASSERT_EQ(expected, result); + BOOST_REQUIRE_EQUAL(expected, result); } -TEST(Join, delimiterString) +BOOST_AUTO_TEST_CASE(delimiterString) { std::string expected = "1;;2;;3"; std::string result = util::join({1, 2, 3}, ";;"); - ASSERT_EQ(expected, result); + BOOST_REQUIRE_EQUAL(expected, result); } -TEST(Join, delimiterChar) +BOOST_AUTO_TEST_CASE(delimiterChar) { std::string expected = "1@2@3@4"; std::string result = util::join({1, 2, 3, 4}, '@'); - ASSERT_EQ(expected, result); + BOOST_REQUIRE_EQUAL(expected, result); } -/* -------------------------------------------------------- - * util::isIdentifierValid function - * -------------------------------------------------------- */ +BOOST_AUTO_TEST_SUITE_END() + +/* + * util::is_identifier function + * -------------------------------------------------------- + */ -TEST(IsIdentifierValid, correct) +BOOST_AUTO_TEST_SUITE(is_identifier_valid) + +BOOST_AUTO_TEST_CASE(correct) { - ASSERT_TRUE(util::isIdentifierValid("localhost")); - ASSERT_TRUE(util::isIdentifierValid("localhost2")); - ASSERT_TRUE(util::isIdentifierValid("localhost2-4_")); + BOOST_REQUIRE(util::is_identifier("localhost")); + BOOST_REQUIRE(util::is_identifier("localhost2")); + BOOST_REQUIRE(util::is_identifier("localhost2-4_")); } -TEST(IsIdentifierValid, incorrect) +BOOST_AUTO_TEST_CASE(incorrect) { - ASSERT_FALSE(util::isIdentifierValid("")); - ASSERT_FALSE(util::isIdentifierValid("localhost with spaces")); - ASSERT_FALSE(util::isIdentifierValid("localhost*")); - ASSERT_FALSE(util::isIdentifierValid("&&")); - ASSERT_FALSE(util::isIdentifierValid("@'")); - ASSERT_FALSE(util::isIdentifierValid("##")); - ASSERT_FALSE(util::isIdentifierValid("===++")); + BOOST_REQUIRE(!util::is_identifier("")); + BOOST_REQUIRE(!util::is_identifier("localhost with spaces")); + BOOST_REQUIRE(!util::is_identifier("localhost*")); + BOOST_REQUIRE(!util::is_identifier("&&")); + BOOST_REQUIRE(!util::is_identifier("@'")); + BOOST_REQUIRE(!util::is_identifier("##")); + BOOST_REQUIRE(!util::is_identifier("===++")); } -/* -------------------------------------------------------- - * util::isBoolean function - * -------------------------------------------------------- */ +BOOST_AUTO_TEST_SUITE_END() -TEST(IsBoolean, correct) +/* + * util::is_boolean function + * -------------------------------------------------------- + */ + +BOOST_AUTO_TEST_SUITE(is_boolean) + +BOOST_AUTO_TEST_CASE(correct) { // true - ASSERT_TRUE(util::isBoolean("true")); - ASSERT_TRUE(util::isBoolean("True")); - ASSERT_TRUE(util::isBoolean("TRUE")); - ASSERT_TRUE(util::isBoolean("TruE")); + BOOST_REQUIRE(util::is_boolean("true")); + BOOST_REQUIRE(util::is_boolean("True")); + BOOST_REQUIRE(util::is_boolean("TRUE")); + BOOST_REQUIRE(util::is_boolean("TruE")); // yes - ASSERT_TRUE(util::isBoolean("yes")); - ASSERT_TRUE(util::isBoolean("Yes")); - ASSERT_TRUE(util::isBoolean("YES")); - ASSERT_TRUE(util::isBoolean("YeS")); + BOOST_REQUIRE(util::is_boolean("yes")); + BOOST_REQUIRE(util::is_boolean("Yes")); + BOOST_REQUIRE(util::is_boolean("YES")); + BOOST_REQUIRE(util::is_boolean("YeS")); // on - ASSERT_TRUE(util::isBoolean("on")); - ASSERT_TRUE(util::isBoolean("On")); - ASSERT_TRUE(util::isBoolean("oN")); - ASSERT_TRUE(util::isBoolean("ON")); + BOOST_REQUIRE(util::is_boolean("on")); + BOOST_REQUIRE(util::is_boolean("On")); + BOOST_REQUIRE(util::is_boolean("oN")); + BOOST_REQUIRE(util::is_boolean("ON")); // 1 - ASSERT_TRUE(util::isBoolean("1")); + BOOST_REQUIRE(util::is_boolean("1")); +} + +BOOST_AUTO_TEST_CASE(incorrect) +{ + BOOST_REQUIRE(!util::is_boolean("false")); + BOOST_REQUIRE(!util::is_boolean("lol")); + BOOST_REQUIRE(!util::is_boolean("")); + BOOST_REQUIRE(!util::is_boolean("0")); } -TEST(IsBoolean, incorrect) +BOOST_AUTO_TEST_SUITE_END() + +/* + * util::is_number function + * -------------------------------------------------------- + */ + +BOOST_AUTO_TEST_SUITE(is_number) + +BOOST_AUTO_TEST_CASE(correct) { - ASSERT_FALSE(util::isBoolean("false")); - ASSERT_FALSE(util::isBoolean("lol")); - ASSERT_FALSE(util::isBoolean("")); - ASSERT_FALSE(util::isBoolean("0")); + BOOST_REQUIRE(util::is_number("123")); + BOOST_REQUIRE(util::is_number("-123")); + BOOST_REQUIRE(util::is_number("123.67")); } -/* -------------------------------------------------------- - * util::isNumber function - * -------------------------------------------------------- */ - -TEST(IsNumber, correct) +BOOST_AUTO_TEST_CASE(incorrect) { - ASSERT_TRUE(util::isNumber("123")); - ASSERT_TRUE(util::isNumber("-123")); - ASSERT_TRUE(util::isNumber("123.67")); + BOOST_REQUIRE(!util::is_number("lol")); + BOOST_REQUIRE(!util::is_number("this is not a number")); } -TEST(IsNumber, incorrect) -{ - ASSERT_FALSE(util::isNumber("lol")); - ASSERT_FALSE(util::isNumber("this is not a number")); -} +BOOST_AUTO_TEST_SUITE_END() /* - * util::toNumber function + * util::to_number function * ------------------------------------------------------------------ */ -TEST(ToNumber, correct) +BOOST_AUTO_TEST_SUITE(to_number) + +BOOST_AUTO_TEST_CASE(correct) { /* unsigned */ - ASSERT_EQ(50u, util::toNumber<std::uint8_t>("50")); - ASSERT_EQ(5000u, util::toNumber<std::uint16_t>("5000")); - ASSERT_EQ(50000u, util::toNumber<std::uint32_t>("50000")); - ASSERT_EQ(500000u, util::toNumber<std::uint64_t>("500000")); + BOOST_REQUIRE_EQUAL(50u, util::to_number<std::uint8_t>("50")); + BOOST_REQUIRE_EQUAL(5000u, util::to_number<std::uint16_t>("5000")); + BOOST_REQUIRE_EQUAL(50000u, util::to_number<std::uint32_t>("50000")); + BOOST_REQUIRE_EQUAL(500000u, util::to_number<std::uint64_t>("500000")); /* signed */ - ASSERT_EQ(-50, util::toNumber<std::int8_t>("-50")); - ASSERT_EQ(-500, util::toNumber<std::int16_t>("-500")); - ASSERT_EQ(-5000, util::toNumber<std::int32_t>("-5000")); - ASSERT_EQ(-50000, util::toNumber<std::int64_t>("-50000")); + BOOST_REQUIRE_EQUAL(-50, util::to_number<std::int8_t>("-50")); + BOOST_REQUIRE_EQUAL(-500, util::to_number<std::int16_t>("-500")); + BOOST_REQUIRE_EQUAL(-5000, util::to_number<std::int32_t>("-5000")); + BOOST_REQUIRE_EQUAL(-50000, util::to_number<std::int64_t>("-50000")); } -TEST(ToNumber, incorrect) +BOOST_AUTO_TEST_CASE(incorrect) { /* unsigned */ - ASSERT_THROW(util::toNumber<std::uint8_t>("300"), std::out_of_range); - ASSERT_THROW(util::toNumber<std::uint16_t>("80000"), std::out_of_range); - ASSERT_THROW(util::toNumber<std::uint8_t>("-125"), std::out_of_range); - ASSERT_THROW(util::toNumber<std::uint16_t>("-25000"), std::out_of_range); + BOOST_REQUIRE_THROW(util::to_number<std::uint8_t>("300"), std::out_of_range); + BOOST_REQUIRE_THROW(util::to_number<std::uint16_t>("80000"), std::out_of_range); + BOOST_REQUIRE_THROW(util::to_number<std::uint8_t>("-125"), std::out_of_range); + BOOST_REQUIRE_THROW(util::to_number<std::uint16_t>("-25000"), std::out_of_range); /* signed */ - ASSERT_THROW(util::toNumber<std::int8_t>("300"), std::out_of_range); - ASSERT_THROW(util::toNumber<std::int16_t>("80000"), std::out_of_range); - ASSERT_THROW(util::toNumber<std::int8_t>("-300"), std::out_of_range); - ASSERT_THROW(util::toNumber<std::int16_t>("-80000"), std::out_of_range); + BOOST_REQUIRE_THROW(util::to_number<std::int8_t>("300"), std::out_of_range); + BOOST_REQUIRE_THROW(util::to_number<std::int16_t>("80000"), std::out_of_range); + BOOST_REQUIRE_THROW(util::to_number<std::int8_t>("-300"), std::out_of_range); + BOOST_REQUIRE_THROW(util::to_number<std::int16_t>("-80000"), std::out_of_range); /* not numbers */ - ASSERT_THROW(util::toNumber<std::uint8_t>("nonono"), std::invalid_argument); + BOOST_REQUIRE_THROW(util::to_number<std::uint8_t>("nonono"), std::invalid_argument); /* custom ranges */ - ASSERT_THROW(util::toNumber<std::uint8_t>("50", 0, 10), std::out_of_range); - ASSERT_THROW(util::toNumber<std::int8_t>("-50", -10, 10), std::out_of_range); + BOOST_REQUIRE_THROW(util::to_number<std::uint8_t>("50", 0, 10), std::out_of_range); + BOOST_REQUIRE_THROW(util::to_number<std::int8_t>("-50", -10, 10), std::out_of_range); } +BOOST_AUTO_TEST_SUITE_END() + } // !irccd - -int main(int argc, char **argv) -{ - testing::InitGoogleTest(&argc, argv); - - return RUN_ALL_TESTS(); -}