Mercurial > irccd
changeset 160:c1acfacc46bd
Irccd: dll export and style
line wrap: on
line diff
--- a/cmake/IrccdSystem.cmake Mon May 23 14:05:41 2016 +0200 +++ b/cmake/IrccdSystem.cmake Tue May 24 13:00:35 2016 +0200 @@ -55,7 +55,7 @@ set(CMAKE_CXX_FLAGS "-Wall -Wextra -std=c++14 ${CMAKE_CXX_FLAGS}") endif () elseif (MSVC14) - set(CMAKE_C_FLAGS "/DWIN32_LEAN_AND_MEAN /DNOMINMAX /wd4267 /wd48000 /D_CRT_SECURE_NO_WARNINGS ${CMAKE_C_FLAGS}") + set(CMAKE_C_FLAGS "/DWIN32_LEAN_AND_MEAN /DNOMINMAX /wd4267 /wd4800 /D_CRT_SECURE_NO_WARNINGS ${CMAKE_C_FLAGS}") set(CMAKE_CXX_FLAGS "/DWIN32_LEAN_AND_MEAN /DNOMINMAX /wd4267 /wd4800 /D_CRT_SECURE_NO_WARNINGS /EHsc ${CMAKE_CXX_FLAGS}") else () message(WARNING "Unsupported ${CMAKE_CXX_COMPILER_ID}, may not build correctly.")
--- a/cmake/internal/sysconfig.hpp.in Mon May 23 14:05:41 2016 +0200 +++ b/cmake/internal/sysconfig.hpp.in Tue May 24 13:00:35 2016 +0200 @@ -94,4 +94,19 @@ #cmakedefine HAVE_STAT_ST_UID #cmakedefine HAVE_SYSLOG +/* + * Export stuff. + * ------------------------------------------------------------------ + */ + +#if defined(_WIN32) +# if defined(IRCCD_BUILDING_DLL) +# define IRCCD_EXPORT __declspec(dllexport) +# else +# define IRCCD_EXPORT __declspec(dllimport) +# endif +#else +# define IRCCD_EXPORT +#endif + #endif // !IRCCD_SYSCONFIG_H
--- a/lib/CMakeLists.txt Mon May 23 14:05:41 2016 +0200 +++ b/lib/CMakeLists.txt Tue May 24 13:00:35 2016 +0200 @@ -34,8 +34,14 @@ ${OPENSSL_INCLUDE_DIR} ) +source_group(irccd FILES ${HEADERS} ${SOURCES}) + if (IRCCD_SYSTEM_WINDOWS) list(APPEND LIBRARIES ws2_32 shlwapi) + + if (BUILD_SHARED_LIBS) + list(APPEND FLAGS IRCCD_BUILDING_DLL) + endif () elseif (IRCCD_SYSTEM_MAC) list(APPEND LIBRARIES resolv) elseif (IRCCD_SYSTEM_LINUX) @@ -43,12 +49,18 @@ endif () target_link_libraries(libirccd extern-duktape extern-ircclient extern-jansson extern-cppformat ${LIBRARIES}) +target_compile_definitions(libirccd PRIVATE ${FLAGS}) set_target_properties( libirccd PROPERTIES PREFIX "" OUTPUT_NAME_DEBUG libirccd2d + RUNTIME_OUTPUT_DIRECTORY ${IRCCD_FAKEROOTDIR}/${WITH_BINDIR} + RUNTIME_OUTPUT_DIRECTORY_DEBUG ${IRCCD_FAKEROOTDIR}/${WITH_BINDIR} + RUNTIME_OUTPUT_DIRECTORY_RELEASE ${IRCCD_FAKEROOTDIR}/${WITH_BINDIR} + RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${IRCCD_FAKEROOTDIR}/${WITH_BINDIR} + RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL ${IRCCD_FAKEROOTDIR}/${WITH_BINDIR} VERSION ${IRCCD_VERSION} SOVERSION ${IRCCD_VERSION_SHLIB} )
--- a/lib/irccd/alias.cpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/alias.cpp Tue May 24 13:00:35 2016 +0200 @@ -27,11 +27,10 @@ { assert(!value.empty()); - if ((m_isPlaceholder = std::regex_match(value, std::regex("^%\\d+$")))) { + if ((m_isPlaceholder = std::regex_match(value, std::regex("^%\\d+$")))) m_value = value.substr(1); - } else { + else m_value = std::move(value); - } } unsigned AliasArg::index() const noexcept @@ -50,11 +49,10 @@ std::ostream &operator<<(std::ostream &out, const AliasArg &arg) { - if (arg.m_isPlaceholder) { + if (arg.m_isPlaceholder) out << "%" << arg.m_value; - } else { + else out << arg.m_value; - } return out; }
--- a/lib/irccd/alias.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/alias.hpp Tue May 24 13:00:35 2016 +0200 @@ -28,6 +28,8 @@ #include <string> #include <vector> +#include "sysconfig.hpp" + namespace irccd { /** @@ -51,7 +53,7 @@ * \pre value must not be empty * \param value the value */ - AliasArg(std::string value); + IRCCD_EXPORT AliasArg(std::string value); /** * Check if the argument is a placeholder. @@ -69,7 +71,7 @@ * \pre isPlaceholder() must return true * \return the position */ - unsigned index() const noexcept; + IRCCD_EXPORT unsigned index() const noexcept; /** * Get the real value. @@ -77,7 +79,7 @@ * \pre isPlaceholder() must return false * \return the value */ - const std::string &value() const noexcept; + IRCCD_EXPORT const std::string &value() const noexcept; /** * Output the alias to the stream. @@ -85,7 +87,7 @@ * \param out the output stream * \return out */ - friend std::ostream &operator<<(std::ostream &out, const AliasArg &); + IRCCD_EXPORT friend std::ostream &operator<<(std::ostream &out, const AliasArg &); }; /**
--- a/lib/irccd/application.cpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/application.cpp Tue May 24 13:00:35 2016 +0200 @@ -1,76 +1,76 @@ -/* - * application.cpp -- super base class to create irccd front ends - * - * Copyright (c) 2013-2016 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 "application.hpp" -#include "cmd-help.hpp" -#include "cmd-plugin-info.hpp" -#include "cmd-plugin-list.hpp" -#include "cmd-plugin-load.hpp" -#include "cmd-plugin-reload.hpp" -#include "cmd-plugin-unload.hpp" -#include "cmd-server-cmode.hpp" -#include "cmd-server-cnotice.hpp" -#include "cmd-server-connect.hpp" -#include "cmd-server-disconnect.hpp" -#include "cmd-server-info.hpp" -#include "cmd-server-invite.hpp" -#include "cmd-server-join.hpp" -#include "cmd-server-kick.hpp" -#include "cmd-server-list.hpp" -#include "cmd-server-me.hpp" -#include "cmd-server-message.hpp" -#include "cmd-server-mode.hpp" -#include "cmd-server-nick.hpp" -#include "cmd-server-notice.hpp" -#include "cmd-server-part.hpp" -#include "cmd-server-reconnect.hpp" -#include "cmd-server-topic.hpp" -#include "cmd-watch.hpp" - -namespace irccd { - -Application::Application() -{ - /* Register all commands */ - addCommand(std::make_unique<command::Help>()); - addCommand(std::make_unique<command::PluginInfo>()); - addCommand(std::make_unique<command::PluginList>()); - addCommand(std::make_unique<command::PluginLoad>()); - addCommand(std::make_unique<command::PluginReload>()); - addCommand(std::make_unique<command::PluginUnload>()); - addCommand(std::make_unique<command::ServerChannelMode>()); - addCommand(std::make_unique<command::ServerChannelNotice>()); - addCommand(std::make_unique<command::ServerConnect>()); - addCommand(std::make_unique<command::ServerDisconnect>()); - addCommand(std::make_unique<command::ServerInfo>()); - addCommand(std::make_unique<command::ServerInvite>()); - addCommand(std::make_unique<command::ServerJoin>()); - addCommand(std::make_unique<command::ServerKick>()); - addCommand(std::make_unique<command::ServerList>()); - addCommand(std::make_unique<command::ServerMe>()); - addCommand(std::make_unique<command::ServerMessage>()); - addCommand(std::make_unique<command::ServerMode>()); - addCommand(std::make_unique<command::ServerNick>()); - addCommand(std::make_unique<command::ServerNotice>()); - addCommand(std::make_unique<command::ServerPart>()); - addCommand(std::make_unique<command::ServerReconnect>()); - addCommand(std::make_unique<command::ServerTopic>()); - addCommand(std::make_unique<command::Watch>()); -} - -} // !irccd +/* + * application.cpp -- super base class to create irccd front ends + * + * Copyright (c) 2013-2016 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 "application.hpp" +#include "cmd-help.hpp" +#include "cmd-plugin-info.hpp" +#include "cmd-plugin-list.hpp" +#include "cmd-plugin-load.hpp" +#include "cmd-plugin-reload.hpp" +#include "cmd-plugin-unload.hpp" +#include "cmd-server-cmode.hpp" +#include "cmd-server-cnotice.hpp" +#include "cmd-server-connect.hpp" +#include "cmd-server-disconnect.hpp" +#include "cmd-server-info.hpp" +#include "cmd-server-invite.hpp" +#include "cmd-server-join.hpp" +#include "cmd-server-kick.hpp" +#include "cmd-server-list.hpp" +#include "cmd-server-me.hpp" +#include "cmd-server-message.hpp" +#include "cmd-server-mode.hpp" +#include "cmd-server-nick.hpp" +#include "cmd-server-notice.hpp" +#include "cmd-server-part.hpp" +#include "cmd-server-reconnect.hpp" +#include "cmd-server-topic.hpp" +#include "cmd-watch.hpp" + +namespace irccd { + +Application::Application() +{ + // Register all commands. + addCommand(std::make_unique<command::Help>()); + addCommand(std::make_unique<command::PluginInfo>()); + addCommand(std::make_unique<command::PluginList>()); + addCommand(std::make_unique<command::PluginLoad>()); + addCommand(std::make_unique<command::PluginReload>()); + addCommand(std::make_unique<command::PluginUnload>()); + addCommand(std::make_unique<command::ServerChannelMode>()); + addCommand(std::make_unique<command::ServerChannelNotice>()); + addCommand(std::make_unique<command::ServerConnect>()); + addCommand(std::make_unique<command::ServerDisconnect>()); + addCommand(std::make_unique<command::ServerInfo>()); + addCommand(std::make_unique<command::ServerInvite>()); + addCommand(std::make_unique<command::ServerJoin>()); + addCommand(std::make_unique<command::ServerKick>()); + addCommand(std::make_unique<command::ServerList>()); + addCommand(std::make_unique<command::ServerMe>()); + addCommand(std::make_unique<command::ServerMessage>()); + addCommand(std::make_unique<command::ServerMode>()); + addCommand(std::make_unique<command::ServerNick>()); + addCommand(std::make_unique<command::ServerNotice>()); + addCommand(std::make_unique<command::ServerPart>()); + addCommand(std::make_unique<command::ServerReconnect>()); + addCommand(std::make_unique<command::ServerTopic>()); + addCommand(std::make_unique<command::Watch>()); +} + +} // !irccd
--- a/lib/irccd/application.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/application.hpp Tue May 24 13:00:35 2016 +0200 @@ -29,6 +29,7 @@ #include <unordered_map> #include "command.hpp" +#include "sysconfig.hpp" namespace irccd { @@ -51,7 +52,7 @@ /** * Create the application and fill the commands with predefined commands. */ - Application(); + IRCCD_EXPORT Application(); /** * Access the remote commands.
--- a/lib/irccd/cmd-help.cpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/cmd-help.cpp Tue May 24 13:00:35 2016 +0200 @@ -43,11 +43,10 @@ { auto it = irccdctl.commands().find(args.arg(0U)); - if (it == irccdctl.commands().end()) { + if (it == irccdctl.commands().end()) log::warning() << "there is no command named: " << args.arg(0U) << std::endl; - } else { + else log::warning() << it->second->usage() << std::flush; - } return nullptr; }
--- a/lib/irccd/cmd-help.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/cmd-help.hpp Tue May 24 13:00:35 2016 +0200 @@ -36,19 +36,19 @@ */ class Help : public RemoteCommand { public: - Help(); + IRCCD_EXPORT Help(); - std::vector<Arg> args() const override; + IRCCD_EXPORT std::vector<Arg> args() const override; /** * \copydoc RemoteCommand::help */ - std::string help() const override; + IRCCD_EXPORT std::string help() const override; /** * \copydoc RemoteCommand::request */ - json::Value request(Irccdctl &irccdctl, const RemoteCommandRequest &args) const override; + IRCCD_EXPORT json::Value request(Irccdctl &irccdctl, const RemoteCommandRequest &args) const override; }; } // !command
--- a/lib/irccd/cmd-plugin-info.cpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/cmd-plugin-info.cpp Tue May 24 13:00:35 2016 +0200 @@ -71,7 +71,7 @@ { RemoteCommand::result(irccdctl, result); - /* Plugin information */ + // Plugin information. if (result.valueOr("status", false).toBool()) { std::cout << std::boolalpha; std::cout << "Author : " << result.valueOr("author", "").toString(true) << std::endl;
--- a/lib/irccd/cmd-plugin-info.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/cmd-plugin-info.hpp Tue May 24 13:00:35 2016 +0200 @@ -39,32 +39,32 @@ /** * Constructor. */ - PluginInfo(); + IRCCD_EXPORT PluginInfo(); /** * \copydoc RemoteCommand::help */ - std::string help() const override; + IRCCD_EXPORT std::string help() const override; /** * \copydoc RemoteCommand::args */ - std::vector<Arg> args() const override; + IRCCD_EXPORT std::vector<Arg> args() const override; /** * \copydoc RemoteCommand::request */ - json::Value request(Irccdctl &irccdctl, const RemoteCommandRequest &args) const override; + IRCCD_EXPORT json::Value request(Irccdctl &irccdctl, const RemoteCommandRequest &args) const override; /** * \copydoc RemoteCommand::exec */ - json::Value exec(Irccd &irccd, const json::Value &request) const override; + IRCCD_EXPORT json::Value exec(Irccd &irccd, const json::Value &request) const override; /** * \copydoc RemoteCommand::result */ - void result(Irccdctl &irccdctl, const json::Value &response) const override; + IRCCD_EXPORT void result(Irccdctl &irccdctl, const json::Value &response) const override; }; } // !command
--- a/lib/irccd/cmd-plugin-list.cpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/cmd-plugin-list.cpp Tue May 24 13:00:35 2016 +0200 @@ -44,9 +44,8 @@ json::Value response = RemoteCommand::exec(irccd, request); json::Value list = json::array({}); - for (const auto &plugin : irccd.pluginService().plugins()) { + for (const auto &plugin : irccd.pluginService().plugins()) list.append(plugin->name()); - } response.insert("list", std::move(list)); @@ -63,9 +62,8 @@ { RemoteCommand::result(irccdctl, object); - for (const auto &n : object.valueOr("list", json::Type::Array, json::array({}))) { + for (const auto &n : object.valueOr("list", json::Type::Array, json::array({}))) std::cout << n.toString() << std::endl; - } } } // !command
--- a/lib/irccd/cmd-plugin-list.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/cmd-plugin-list.hpp Tue May 24 13:00:35 2016 +0200 @@ -39,22 +39,22 @@ /** * Constructor. */ - PluginList(); + IRCCD_EXPORT PluginList(); /** * \copydoc RemoteCommand::help */ - std::string help() const override; + IRCCD_EXPORT std::string help() const override; /** * \copydoc RemoteCommand::exec */ - json::Value exec(Irccd &irccd, const json::Value &request) const override; + IRCCD_EXPORT json::Value exec(Irccd &irccd, const json::Value &request) const override; /** * \copydoc RemoteCommand::result */ - void result(Irccdctl &irccdctl, const json::Value &response) const override; + IRCCD_EXPORT void result(Irccdctl &irccdctl, const json::Value &response) const override; }; } // !command
--- a/lib/irccd/cmd-plugin-load.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/cmd-plugin-load.hpp Tue May 24 13:00:35 2016 +0200 @@ -39,22 +39,22 @@ /** * Constructor. */ - PluginLoad(); + IRCCD_EXPORT PluginLoad(); /** * \copydoc RemoteCommand::help */ - std::string help() const override; + IRCCD_EXPORT std::string help() const override; /** * \copydoc RemoteCommand::args */ - std::vector<Arg> args() const override; + IRCCD_EXPORT std::vector<Arg> args() const override; /** * \copydoc RemoteCommand::exec */ - json::Value exec(Irccd &irccd, const json::Value &request) const override; + IRCCD_EXPORT json::Value exec(Irccd &irccd, const json::Value &request) const override; }; } // !command
--- a/lib/irccd/cmd-plugin-reload.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/cmd-plugin-reload.hpp Tue May 24 13:00:35 2016 +0200 @@ -39,22 +39,22 @@ /** * Constructor. */ - PluginReload(); + IRCCD_EXPORT PluginReload(); /** * \copydoc RemoteCommand::help */ - std::string help() const override; + IRCCD_EXPORT std::string help() const override; /** * \copydoc RemoteCommand::args */ - std::vector<Arg> args() const override; + IRCCD_EXPORT std::vector<Arg> args() const override; /** * \copydoc RemoteCommand::exec */ - json::Value exec(Irccd &irccd, const json::Value &request) const override; + IRCCD_EXPORT json::Value exec(Irccd &irccd, const json::Value &request) const override; }; } // !command
--- a/lib/irccd/cmd-plugin-unload.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/cmd-plugin-unload.hpp Tue May 24 13:00:35 2016 +0200 @@ -39,22 +39,22 @@ /** * Constructor. */ - PluginUnload(); + IRCCD_EXPORT PluginUnload(); /** * \copydoc RemoteCommand::help */ - std::string help() const override; + IRCCD_EXPORT std::string help() const override; /** * \copydoc RemoteCommand::args */ - std::vector<Arg> args() const override; + IRCCD_EXPORT std::vector<Arg> args() const override; /** * \copydoc RemoteCommand::exec */ - json::Value exec(Irccd &irccd, const json::Value &request) const override; + IRCCD_EXPORT json::Value exec(Irccd &irccd, const json::Value &request) const override; }; } // !command
--- a/lib/irccd/cmd-server-cmode.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/cmd-server-cmode.hpp Tue May 24 13:00:35 2016 +0200 @@ -39,22 +39,22 @@ /** * Constructor. */ - ServerChannelMode(); + IRCCD_EXPORT ServerChannelMode(); /** * \copydoc RemoteCommand::help */ - std::string help() const override; + IRCCD_EXPORT std::string help() const override; /** * \copydoc RemoteCommand::args */ - std::vector<Arg> args() const override; + IRCCD_EXPORT std::vector<Arg> args() const override; /** * \copydoc RemoteCommand::exec */ - json::Value exec(Irccd &irccd, const json::Value &request) const override; + IRCCD_EXPORT json::Value exec(Irccd &irccd, const json::Value &request) const override; }; } // !command
--- a/lib/irccd/cmd-server-cnotice.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/cmd-server-cnotice.hpp Tue May 24 13:00:35 2016 +0200 @@ -48,22 +48,22 @@ /** * Constructor. */ - ServerChannelNotice(); + IRCCD_EXPORT ServerChannelNotice(); /** * \copydoc RemoteCommand::help */ - std::string help() const override; + IRCCD_EXPORT std::string help() const override; /** * \copydoc RemoteCommand::args */ - std::vector<Arg> args() const override; + IRCCD_EXPORT std::vector<Arg> args() const override; /** * \copydoc RemoteCommand::exec */ - json::Value exec(Irccd &irccd, const json::Value &request) const override; + IRCCD_EXPORT json::Value exec(Irccd &irccd, const json::Value &request) const override; }; } // !command
--- a/lib/irccd/cmd-server-connect.cpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/cmd-server-connect.cpp Tue May 24 13:00:35 2016 +0200 @@ -38,12 +38,10 @@ { auto it = object.find("name"); - if (it == object.end()) { + if (it == object.end()) throw std::invalid_argument("missing 'name' property"); - } - if (!it->isString() || !util::isIdentifierValid(it->toString())) { + if (!it->isString() || !util::isIdentifierValid(it->toString())) throw std::invalid_argument("invalid server name"); - } return it->toString(); } @@ -52,12 +50,10 @@ { auto it = object.find("host"); - if (it == object.end()) { + if (it == object.end()) throw std::invalid_argument("missing 'host' property"); - } - if (!it->isString()) { + if (!it->isString()) throw std::invalid_argument("invalid host"); - } return it->toString(); } @@ -67,11 +63,9 @@ auto it = object.find("port"); uint16_t port = 6667; - if (it != object.end()) { - if (it->isInt() && it->toInt() >= 0 && it->toInt() <= std::numeric_limits<std::uint16_t>::max()) { + if (it != object.end()) + if (it->isInt() && it->toInt() >= 0 && it->toInt() <= std::numeric_limits<std::uint16_t>::max()) port = static_cast<std::uint16_t>(it->toInt()); - } - } return port; } @@ -90,9 +84,8 @@ throw std::invalid_argument("ssl is disabled"); #endif - if (object.valueOr("sslVerify", json::Type::Boolean, false).toBool()) { + if (object.valueOr("sslVerify", json::Type::Boolean, false).toBool()) info.flags |= ServerInfo::SslVerify; - } return info; } @@ -155,12 +148,10 @@ json::Value ServerConnect::exec(Irccd &irccd, const json::Value &request) const { - auto server = std::make_shared<Server>(readInfoName(request), readInfo(request), readIdentity(request), - readSettings(request)); + auto server = std::make_shared<Server>(readInfoName(request), readInfo(request), readIdentity(request), readSettings(request)); - if (irccd.serverService().has(server->name())) { + if (irccd.serverService().has(server->name())) throw std::invalid_argument("server '{}' already exists"_format(server->name())); - } irccd.serverService().add(std::move(server));
--- a/lib/irccd/cmd-server-connect.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/cmd-server-connect.hpp Tue May 24 13:00:35 2016 +0200 @@ -39,27 +39,27 @@ /** * Constructor. */ - ServerConnect(); + IRCCD_EXPORT ServerConnect(); /** * \copydoc RemoteCommand::help */ - std::string help() const override; + IRCCD_EXPORT std::string help() const override; /** * \copydoc RemoteCommand::options */ - std::vector<Option> options() const override; + IRCCD_EXPORT std::vector<Option> options() const override; /** * \copydoc RemoteCommand::args */ - std::vector<Arg> args() const override; + IRCCD_EXPORT std::vector<Arg> args() const override; /** * \copydoc RemoteCommand::exec */ - json::Value exec(Irccd &irccd, const json::Value &request) const override; + IRCCD_EXPORT json::Value exec(Irccd &irccd, const json::Value &request) const override; }; } // !command
--- a/lib/irccd/cmd-server-disconnect.cpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/cmd-server-disconnect.cpp Tue May 24 13:00:35 2016 +0200 @@ -44,11 +44,10 @@ { auto it = request.find("server"); - if (it == request.end()) { + if (it == request.end()) irccd.serverService().clear(); - } else { + else irccd.serverService().remove(it->toString()); - } return RemoteCommand::exec(irccd, request); }
--- a/lib/irccd/cmd-server-disconnect.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/cmd-server-disconnect.hpp Tue May 24 13:00:35 2016 +0200 @@ -39,24 +39,24 @@ /** * Constructor. */ - ServerDisconnect(); + IRCCD_EXPORT ServerDisconnect(); /** * \copydoc RemoteCommand::help */ - std::string help() const override; + IRCCD_EXPORT std::string help() const override; /** * Get list of arguments required. * * \return the arguments required */ - std::vector<Arg> args() const override; + IRCCD_EXPORT std::vector<Arg> args() const override; /** * \copydoc RemoteCommand::exec */ - json::Value exec(Irccd &irccd, const json::Value &request) const override; + IRCCD_EXPORT json::Value exec(Irccd &irccd, const json::Value &request) const override; }; } // !command
--- a/lib/irccd/cmd-server-info.cpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/cmd-server-info.cpp Tue May 24 13:00:35 2016 +0200 @@ -64,23 +64,19 @@ response.insert("username", server->identity().username); response.insert("realname", server->identity().realname); - /* Optional stuff */ - if (server->info().flags & irccd::ServerInfo::Ipv6) { + // Optional stuff. + if (server->info().flags & irccd::ServerInfo::Ipv6) response.insert("ipv6", true); - } - if (server->info().flags & irccd::ServerInfo::Ssl) { + if (server->info().flags & irccd::ServerInfo::Ssl) response.insert("ssl", true); - } - if (server->info().flags & irccd::ServerInfo::SslVerify) { + if (server->info().flags & irccd::ServerInfo::SslVerify) response.insert("sslVerify", true); - } /* Channel list */ auto channels = json::array({}); - for (const auto &c : server->settings().channels) { + for (const auto &c : server->settings().channels) channels.append(c.name); - } response.insert("channels", std::move(channels)); @@ -91,7 +87,7 @@ { RemoteCommand::result(irccdctl, response); - /* Server information */ + // Server information. std::cout << std::boolalpha; std::cout << "Name : " << response.valueOr("name", "").toString(true) << std::endl; std::cout << "Host : " << response.valueOr("host", "").toString(true) << std::endl; @@ -100,16 +96,15 @@ std::cout << "SSL : " << response.valueOr("ssl", "").toString(true) << std::endl; std::cout << "SSL verified : " << response.valueOr("sslVerify", "").toString(true) << std::endl; - /* Channels */ + // Channels. std::cout << "Channels : "; - for (const json::Value &v : response.valueOr("channels", json::Type::Array, json::array({}))) { + for (const json::Value &v : response.valueOr("channels", json::Type::Array, json::array({}))) std::cout << v.toString() << " "; - } std::cout << std::endl; - /* Identity */ + // Identity. std::cout << "Nickname : " << response.valueOr("nickname", "").toString(true) << std::endl; std::cout << "User name : " << response.valueOr("username", "").toString(true) << std::endl; std::cout << "Real name : " << response.valueOr("realname", "").toString(true) << std::endl;
--- a/lib/irccd/cmd-server-info.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/cmd-server-info.hpp Tue May 24 13:00:35 2016 +0200 @@ -36,32 +36,32 @@ */ class ServerInfo : public RemoteCommand { public: - ServerInfo(); + IRCCD_EXPORT ServerInfo(); /** * \copydoc RemoteCommand::help */ - std::string help() const override; + IRCCD_EXPORT std::string help() const override; /** * \copydoc RemoteCommand::args */ - std::vector<Arg> args() const override; + IRCCD_EXPORT std::vector<Arg> args() const override; /** * \copydoc RemoteCommand::request */ - json::Value request(Irccdctl &irccdctl, const RemoteCommandRequest &args) const override; + IRCCD_EXPORT json::Value request(Irccdctl &irccdctl, const RemoteCommandRequest &args) const override; /** * \copydoc RemoteCommand::exec */ - json::Value exec(Irccd &irccd, const json::Value &request) const override; + IRCCD_EXPORT json::Value exec(Irccd &irccd, const json::Value &request) const override; /** * \copydoc RemoteCommand::result */ - void result(Irccdctl &irccdctl, const json::Value &response) const override; + IRCCD_EXPORT void result(Irccdctl &irccdctl, const json::Value &response) const override; }; } // !command
--- a/lib/irccd/cmd-server-invite.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/cmd-server-invite.hpp Tue May 24 13:00:35 2016 +0200 @@ -36,29 +36,27 @@ */ class ServerInvite : public RemoteCommand { public: - ServerInvite(); + IRCCD_EXPORT ServerInvite(); /** * \copydoc RemoteCommand::help */ - std::string help() const override; + IRCCD_EXPORT std::string help() const override; /** * \copydoc RemoteCommand::args */ - std::vector<Arg> args() const override; + IRCCD_EXPORT std::vector<Arg> args() const override; /** * \copydoc RemoteCommand::request */ - json::Value request(Irccdctl &irccdctl, const RemoteCommandRequest &args) const override; + IRCCD_EXPORT json::Value request(Irccdctl &irccdctl, const RemoteCommandRequest &args) const override; /** * \copydoc RemoteCommand::exec */ - json::Value exec(Irccd &irccd, const json::Value &request) const override; - - + IRCCD_EXPORT json::Value exec(Irccd &irccd, const json::Value &request) const override; }; } // !command
--- a/lib/irccd/cmd-server-join.cpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/cmd-server-join.cpp Tue May 24 13:00:35 2016 +0200 @@ -51,9 +51,8 @@ { "channel", args.args()[1] } }); - if (args.length() == 3) { + if (args.length() == 3) req.insert("password", args.args()[2]); - } return req; }
--- a/lib/irccd/cmd-server-join.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/cmd-server-join.hpp Tue May 24 13:00:35 2016 +0200 @@ -36,27 +36,27 @@ */ class ServerJoin : public RemoteCommand { public: - ServerJoin(); + IRCCD_EXPORT ServerJoin(); /** * \copydoc RemoteCommand::help */ - std::string help() const override; + IRCCD_EXPORT std::string help() const override; /** * \copydoc RemoteCommand::args */ - std::vector<Arg> args() const override; + IRCCD_EXPORT std::vector<Arg> args() const override; /** * \copydoc RemoteCommand::request */ - json::Value request(Irccdctl &irccdctl, const RemoteCommandRequest &args) const override; + IRCCD_EXPORT json::Value request(Irccdctl &irccdctl, const RemoteCommandRequest &args) const override; /** * \copydoc RemoteCommand::exec */ - json::Value exec(Irccd &irccd, const json::Value &request) const override; + IRCCD_EXPORT json::Value exec(Irccd &irccd, const json::Value &request) const override; }; } // !command
--- a/lib/irccd/cmd-server-kick.cpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/cmd-server-kick.cpp Tue May 24 13:00:35 2016 +0200 @@ -53,9 +53,8 @@ { "channel", args.arg(2) } }); - if (args.length() == 4) { + if (args.length() == 4) req.insert("reason", args.arg(3)); - } return req; }
--- a/lib/irccd/cmd-server-kick.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/cmd-server-kick.hpp Tue May 24 13:00:35 2016 +0200 @@ -36,27 +36,27 @@ */ class ServerKick : public RemoteCommand { public: - ServerKick(); + IRCCD_EXPORT ServerKick(); /** * \copydoc RemoteCommand::help */ - std::string help() const override; + IRCCD_EXPORT std::string help() const override; /** * \copydoc RemoteCommand::args */ - std::vector<Arg> args() const override; + IRCCD_EXPORT std::vector<Arg> args() const override; /** * \copydoc RemoteCommand::request */ - json::Value request(Irccdctl &irccdctl, const RemoteCommandRequest &args) const override; + IRCCD_EXPORT json::Value request(Irccdctl &irccdctl, const RemoteCommandRequest &args) const override; /** * \copydoc RemoteCommand::exec */ - json::Value exec(Irccd &irccd, const json::Value &request) const override; + IRCCD_EXPORT json::Value exec(Irccd &irccd, const json::Value &request) const override; }; } // !command
--- a/lib/irccd/cmd-server-list.cpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/cmd-server-list.cpp Tue May 24 13:00:35 2016 +0200 @@ -42,9 +42,8 @@ auto json = json::object({}); auto list = json::array({}); - for (const auto &server : irccd.serverService().servers()) { + for (const auto &server : irccd.serverService().servers()) list.append(server->name()); - } json.insert("list", std::move(list)); @@ -53,9 +52,8 @@ void ServerList::result(Irccdctl &, const json::Value &response) const { - for (const auto &n : response.valueOr("list", json::Type::Array, json::array({}))) { + for (const auto &n : response.valueOr("list", json::Type::Array, json::array({}))) std::cout << n.toString() << std::endl; - } } } // !command
--- a/lib/irccd/cmd-server-list.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/cmd-server-list.hpp Tue May 24 13:00:35 2016 +0200 @@ -36,16 +36,16 @@ */ class ServerList : public RemoteCommand { public: - ServerList(); + IRCCD_EXPORT ServerList(); /** * \copydoc RemoteCommand::help */ - std::string help() const override; + IRCCD_EXPORT std::string help() const override; - json::Value exec(Irccd &irccd, const json::Value &request) const override; + IRCCD_EXPORT json::Value exec(Irccd &irccd, const json::Value &request) const override; - void result(Irccdctl &irccdctl, const json::Value &response) const override; + IRCCD_EXPORT void result(Irccdctl &irccdctl, const json::Value &response) const override; }; } // !command
--- a/lib/irccd/cmd-server-me.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/cmd-server-me.hpp Tue May 24 13:00:35 2016 +0200 @@ -36,27 +36,27 @@ */ class ServerMe : public RemoteCommand { public: - ServerMe(); + IRCCD_EXPORT ServerMe(); /** * \copydoc RemoteCommand::help */ - std::string help() const override; + IRCCD_EXPORT std::string help() const override; /** * \copydoc RemoteCommand::args */ - std::vector<Arg> args() const override; + IRCCD_EXPORT std::vector<Arg> args() const override; /** * \copydoc RemoteCommand::request */ - json::Value request(Irccdctl &irccdctl, const RemoteCommandRequest &args) const override; + IRCCD_EXPORT json::Value request(Irccdctl &irccdctl, const RemoteCommandRequest &args) const override; /** * \copydoc RemoteCommand::exec */ - json::Value exec(Irccd &irccd, const json::Value &request) const override; + IRCCD_EXPORT json::Value exec(Irccd &irccd, const json::Value &request) const override; }; } // !command
--- a/lib/irccd/cmd-server-message.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/cmd-server-message.hpp Tue May 24 13:00:35 2016 +0200 @@ -36,27 +36,27 @@ */ class ServerMessage : public RemoteCommand { public: - ServerMessage(); + IRCCD_EXPORT ServerMessage(); /** * \copydoc RemoteCommand::help */ - std::string help() const override; + IRCCD_EXPORT std::string help() const override; /** * \copydoc RemoteCommand::args */ - std::vector<Arg> args() const override; + IRCCD_EXPORT std::vector<Arg> args() const override; /** * \copydoc RemoteCommand::request */ - json::Value request(Irccdctl &irccdctl, const RemoteCommandRequest &args) const override; + IRCCD_EXPORT json::Value request(Irccdctl &irccdctl, const RemoteCommandRequest &args) const override; /** * \copydoc RemoteCommand::exec */ - json::Value exec(Irccd &irccd, const json::Value &request) const override; + IRCCD_EXPORT json::Value exec(Irccd &irccd, const json::Value &request) const override; }; } // !command
--- a/lib/irccd/cmd-server-mode.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/cmd-server-mode.hpp Tue May 24 13:00:35 2016 +0200 @@ -36,27 +36,27 @@ */ class ServerMode : public RemoteCommand { public: - ServerMode(); + IRCCD_EXPORT ServerMode(); /** * \copydoc RemoteCommand::help */ - std::string help() const override; + IRCCD_EXPORT std::string help() const override; /** * \copydoc RemoteCommand::args */ - std::vector<Arg> args() const override; + IRCCD_EXPORT std::vector<Arg> args() const override; /** * \copydoc RemoteCommand::request */ - json::Value request(Irccdctl &irccdctl, const RemoteCommandRequest &args) const override; + IRCCD_EXPORT json::Value request(Irccdctl &irccdctl, const RemoteCommandRequest &args) const override; /** * \copydoc RemoteCommand::exec */ - json::Value exec(Irccd &irccd, const json::Value &request) const override; + IRCCD_EXPORT json::Value exec(Irccd &irccd, const json::Value &request) const override; }; } // !command
--- a/lib/irccd/cmd-server-nick.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/cmd-server-nick.hpp Tue May 24 13:00:35 2016 +0200 @@ -36,27 +36,27 @@ */ class ServerNick : public RemoteCommand { public: - ServerNick(); + IRCCD_EXPORT ServerNick(); /** * \copydoc RemoteCommand::help */ - std::string help() const override; + IRCCD_EXPORT std::string help() const override; /** * \copydoc RemoteCommand::args */ - std::vector<Arg> args() const override; + IRCCD_EXPORT std::vector<Arg> args() const override; /** * \copydoc RemoteCommand::request */ - json::Value request(Irccdctl &irccdctl, const RemoteCommandRequest &args) const override; + IRCCD_EXPORT json::Value request(Irccdctl &irccdctl, const RemoteCommandRequest &args) const override; /** * \copydoc RemoteCommand::exec */ - json::Value exec(Irccd &irccd, const json::Value &request) const override; + IRCCD_EXPORT json::Value exec(Irccd &irccd, const json::Value &request) const override; }; } // !command
--- a/lib/irccd/cmd-server-notice.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/cmd-server-notice.hpp Tue May 24 13:00:35 2016 +0200 @@ -36,27 +36,27 @@ */ class ServerNotice : public RemoteCommand { public: - ServerNotice(); + IRCCD_EXPORT ServerNotice(); /** * \copydoc RemoteCommand::help */ - std::string help() const override; + IRCCD_EXPORT std::string help() const override; /** * \copydoc RemoteCommand::args */ - std::vector<Arg> args() const override; + IRCCD_EXPORT std::vector<Arg> args() const override; /** * \copydoc RemoteCommand::request */ - json::Value request(Irccdctl &irccdctl, const RemoteCommandRequest &args) const override; + IRCCD_EXPORT json::Value request(Irccdctl &irccdctl, const RemoteCommandRequest &args) const override; /** * \copydoc RemoteCommand::exec */ - json::Value exec(Irccd &irccd, const json::Value &request) const override; + IRCCD_EXPORT json::Value exec(Irccd &irccd, const json::Value &request) const override; }; } // !command
--- a/lib/irccd/cmd-server-part.cpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/cmd-server-part.cpp Tue May 24 13:00:35 2016 +0200 @@ -51,9 +51,8 @@ { "channel", args.arg(1) } }); - if (args.length() == 3) { + if (args.length() == 3) req.insert("reason", args.arg(2)); - } return req; }
--- a/lib/irccd/cmd-server-part.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/cmd-server-part.hpp Tue May 24 13:00:35 2016 +0200 @@ -36,27 +36,27 @@ */ class ServerPart : public RemoteCommand { public: - ServerPart(); + IRCCD_EXPORT ServerPart(); /** * \copydoc RemoteCommand::help */ - std::string help() const override; + IRCCD_EXPORT std::string help() const override; /** * \copydoc RemoteCommand::args */ - std::vector<Arg> args() const override; + IRCCD_EXPORT std::vector<Arg> args() const override; /** * \copydoc RemoteCommand::request */ - json::Value request(Irccdctl &irccdctl, const RemoteCommandRequest &args) const override; + IRCCD_EXPORT json::Value request(Irccdctl &irccdctl, const RemoteCommandRequest &args) const override; /** * \copydoc RemoteCommand::exec */ - json::Value exec(Irccd &irccd, const json::Value &request) const override; + IRCCD_EXPORT json::Value exec(Irccd &irccd, const json::Value &request) const override; }; } // !command
--- a/lib/irccd/cmd-server-reconnect.cpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/cmd-server-reconnect.cpp Tue May 24 13:00:35 2016 +0200 @@ -49,13 +49,11 @@ { auto server = request.find("server"); - if (server != request.end() && server->isString()) { + if (server != request.end() && server->isString()) irccd.serverService().require(server->toString())->reconnect(); - } else { - for (auto &server : irccd.serverService().servers()) { + else + for (auto &server : irccd.serverService().servers()) server->reconnect(); - } - } return nullptr; }
--- a/lib/irccd/cmd-server-reconnect.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/cmd-server-reconnect.hpp Tue May 24 13:00:35 2016 +0200 @@ -36,27 +36,27 @@ */ class ServerReconnect : public RemoteCommand { public: - ServerReconnect(); + IRCCD_EXPORT ServerReconnect(); /** * \copydoc RemoteCommand::help */ - std::string help() const override; + IRCCD_EXPORT std::string help() const override; /** * \copydoc RemoteCommand::args */ - std::vector<Arg> args() const override; + IRCCD_EXPORT std::vector<Arg> args() const override; /** * \copydoc RemoteCommand::request */ - json::Value request(Irccdctl &irccdctl, const RemoteCommandRequest &args) const override; + IRCCD_EXPORT json::Value request(Irccdctl &irccdctl, const RemoteCommandRequest &args) const override; /** * \copydoc RemoteCommand::exec */ - json::Value exec(Irccd &irccd, const json::Value &request) const override; + IRCCD_EXPORT json::Value exec(Irccd &irccd, const json::Value &request) const override; }; } // !command
--- a/lib/irccd/cmd-server-topic.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/cmd-server-topic.hpp Tue May 24 13:00:35 2016 +0200 @@ -36,27 +36,27 @@ */ class ServerTopic : public RemoteCommand { public: - ServerTopic(); + IRCCD_EXPORT ServerTopic(); /** * \copydoc RemoteCommand::help */ - std::string help() const override; + IRCCD_EXPORT std::string help() const override; /** * \copydoc RemoteCommand::args */ - std::vector<Arg> args() const override; + IRCCD_EXPORT std::vector<Arg> args() const override; /** * \copydoc RemoteCommand::request */ - json::Value request(Irccdctl &irccdctl, const RemoteCommandRequest &args) const override; + IRCCD_EXPORT json::Value request(Irccdctl &irccdctl, const RemoteCommandRequest &args) const override; /** * \copydoc RemoteCommand::exec */ - json::Value exec(Irccd &irccd, const json::Value &request) const override; + IRCCD_EXPORT json::Value exec(Irccd &irccd, const json::Value &request) const override; }; } // !command
--- a/lib/irccd/cmd-watch.cpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/cmd-watch.cpp Tue May 24 13:00:35 2016 +0200 @@ -212,23 +212,21 @@ { std::string format = request.optionOr("format", "native"); - if (format != "native" && format != "json") { + if (format != "native" && format != "json") throw std::invalid_argument("invalid format given: " + format); - } while (ctl.connection().isConnected()) { try { auto object = ctl.connection().next(-1); auto it = events.find(object.valueOr("event", "").toString()); - /* Silently ignore to avoid breaking user output */ - if (it == events.end()) { + // Silently ignore to avoid breaking user output. + if (it == events.end()) continue; - } - if (format == "json") { + if (format == "json") std::cout << object.toJson() << std::endl; - } else { + else { it->second(object); std::cout << std::endl; }
--- a/lib/irccd/cmd-watch.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/cmd-watch.hpp Tue May 24 13:00:35 2016 +0200 @@ -36,19 +36,19 @@ */ class Watch : public RemoteCommand { public: - Watch(); + IRCCD_EXPORT Watch(); - std::vector<Option> options() const override; + IRCCD_EXPORT std::vector<Option> options() const override; /** * \copydoc RemoteCommand::help */ - std::string help() const override; + IRCCD_EXPORT std::string help() const override; /** * \copydoc RemoteCommand::request */ - json::Value request(Irccdctl &irccdctl, const RemoteCommandRequest &request) const override; + IRCCD_EXPORT json::Value request(Irccdctl &irccdctl, const RemoteCommandRequest &request) const override; }; } // !command
--- a/lib/irccd/command.cpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/command.cpp Tue May 24 13:00:35 2016 +0200 @@ -34,37 +34,35 @@ oss << "usage: " << sys::programName() << " " << m_name; - /* Options summary */ - if (options().size() > 0) { + // Options summary. + if (options().size() > 0) oss << " [options...]"; - } - /* Arguments summary */ + // Arguments summary. if (args().size() > 0) { oss << " "; - for (const auto &arg : args()) { + for (const auto &arg : args()) oss << (arg.required() ? "" : "[") << arg.name() << (arg.required() ? "" : "]") << " "; - } } - /* Description */ + // Description. oss << "\n\n" << help() << "\n\n"; - /* Options */ + // Options. if (options().size() > 0) { oss << "Options:\n"; for (const auto &opt : options()) { std::ostringstream optoss; - /* Construct the line for the option in a single string to pad it correctly */ + // Construct the line for the option in a single string to pad it correctly. optoss << " "; optoss << (!opt.simpleKey().empty() ? ("-"s + opt.simpleKey() + " ") : " "); optoss << (!opt.longKey().empty() ? ("--"s + opt.longKey() + " "s) : ""); optoss << opt.arg(); - /* Add it padded with spaces */ + // Add it padded with spaces. oss << std::left << std::setw(28) << optoss.str(); oss << opt.description() << "\n"; } @@ -101,9 +99,8 @@ { auto it = response.find("error"); - if (it != response.end() && it->isString()) { + if (it != response.end() && it->isString()) log::warning() << "irccdctl: " << it->toString() << std::endl; - } } } // !irccd
--- a/lib/irccd/command.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/command.hpp Tue May 24 13:00:35 2016 +0200 @@ -29,6 +29,7 @@ #include <vector> #include "json.hpp" +#include "sysconfig.hpp" namespace irccd { @@ -267,7 +268,7 @@ * * \return the usage */ - std::string usage() const; + IRCCD_EXPORT std::string usage() const; /** * Return the help message. @@ -301,14 +302,14 @@ * * \return the minimum */ - unsigned min() const noexcept; + IRCCD_EXPORT unsigned min() const noexcept; /** * Get the maximum number of arguments required. * * \return the maximum */ - unsigned max() const noexcept; + IRCCD_EXPORT unsigned max() const noexcept; /** * Prepare a JSON request to the daemon. @@ -322,7 +323,7 @@ * \return the JSON object to send to the daemon * \post the returned JSON value must be an object */ - virtual json::Value request(Irccdctl &irccdctl, const RemoteCommandRequest &args) const; + IRCCD_EXPORT virtual json::Value request(Irccdctl &irccdctl, const RemoteCommandRequest &args) const; /** * Execute the command in the daemon. @@ -338,7 +339,7 @@ * \param request the JSON request * \return the response */ - virtual json::Value exec(Irccd &irccd, const json::Value &request) const; + IRCCD_EXPORT virtual json::Value exec(Irccd &irccd, const json::Value &request) const; /** * What to do when receiving the response from irccd. @@ -348,7 +349,7 @@ * \param irccdctl the irccdctl instan e * \param response the JSON response */ - virtual void result(Irccdctl &irccdctl, const json::Value &response) const; + IRCCD_EXPORT virtual void result(Irccdctl &irccdctl, const json::Value &response) const; }; /**
--- a/lib/irccd/config.cpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/config.cpp Tue May 24 13:00:35 2016 +0200 @@ -43,9 +43,8 @@ private: std::string convert(const std::string &tmpl, std::string input) const { - if (tmpl.empty()) { + if (tmpl.empty()) return input; - } util::Substitution params; @@ -80,15 +79,13 @@ { auto its = doc.find(section); - if (its == doc.end()) { + if (its == doc.end()) return ""; - } auto ito = its->find(key); - if (ito == its->end()) { + if (ito == its->end()) return ""; - } return ito->value(); } @@ -106,18 +103,14 @@ // Optional stuff. ini::Section::const_iterator it; - if ((it = sc.find("username")) != sc.end()) { + if ((it = sc.find("username")) != sc.end()) identity.username = it->value(); - } - if ((it = sc.find("realname")) != sc.end()) { + if ((it = sc.find("realname")) != sc.end()) identity.realname = it->value(); - } - if ((it = sc.find("nickname")) != sc.end()) { + if ((it = sc.find("nickname")) != sc.end()) identity.nickname = it->value(); - } - if ((it = sc.find("ctcp-version")) != sc.end()) { + if ((it = sc.find("ctcp-version")) != sc.end()) identity.ctcpversion = it->value(); - } return identity; } @@ -126,9 +119,8 @@ { PluginConfig config; - for (const auto &option : sc) { + for (const auto &option : sc) config.emplace(option.key(), option.value()); - } return config; } @@ -148,12 +140,10 @@ ini::Section::const_iterator it; - if ((it = sc.find("path-logs")) != sc.end()) { + if ((it = sc.find("path-logs")) != sc.end()) normal = it->value(); - } - if ((it = sc.find("path-errors")) != sc.end()) { + if ((it = sc.find("path-errors")) != sc.end()) errors = it->value(); - } return std::make_unique<log::File>(std::move(normal), std::move(errors)); } @@ -174,12 +164,11 @@ std::shared_ptr<TransportServer> transport; ini::Section::const_iterator it; - // Port + // Port. int port; - if ((it = sc.find("port")) == sc.cend()) { + if ((it = sc.find("port")) == sc.cend()) throw std::invalid_argument("transport: missing 'port' parameter"); - } try { port = util::toNumber<std::uint16_t>(it->value()); @@ -187,12 +176,11 @@ throw std::invalid_argument("transport: invalid port number: {}"_format(it->value())); } - // Address + // Address. std::string address = "*"; - if ((it = sc.find("address")) != sc.end()) { + if ((it = sc.find("address")) != sc.end()) address = it->value(); - } // Domain bool ipv6 = true; @@ -203,22 +191,19 @@ ipv4 = false; for (const auto &v : *it) { - if (v == "ipv4") { + if (v == "ipv4") ipv4 = true; - } - if (v == "ipv6") { + if (v == "ipv6") ipv6 = true; - } } } - if (ipv6) { + if (ipv6) transport = std::make_shared<TransportServerIp>(AF_INET6, move(address), port, !ipv4); - } else if (ipv4) { + else if (ipv4) transport = std::make_shared<TransportServerIp>(AF_INET, move(address), port); - } else { + else throw std::invalid_argument("transport: domain must at least have ipv4 or ipv6"); - } return transport; } @@ -230,9 +215,8 @@ #if !defined(IRCCD_SYSTEM_WINDOWS) ini::Section::const_iterator it = sc.find("path"); - if (it == sc.end()) { + if (it == sc.end()) throw std::invalid_argument("transport: missing 'path' parameter"); - } return std::make_shared<TransportServerUnix>(it->value()); #else @@ -249,17 +233,15 @@ std::shared_ptr<TransportServer> transport; ini::Section::const_iterator it = sc.find("type"); - if (it == sc.end()) { + if (it == sc.end()) throw std::invalid_argument("transport: missing 'type' parameter"); - } - if (it->value() == "ip") { + if (it->value() == "ip") transport = loadTransportIp(sc); - } else if (it->value() == "unix") { + else if (it->value() == "unix") transport = loadTransportUnix(sc); - } else { + else throw std::invalid_argument("transport: invalid type given: {}"_format(it->value())); - } return transport; } @@ -268,7 +250,7 @@ { assert(sc.key() == "rule"); - // Simple converter from std::vector to std::unordered_set + // Simple converter from std::vector to std::unordered_set. auto toSet = [] (const std::vector<std::string> &v) -> std::unordered_set<std::string> { return std::unordered_set<std::string>(v.begin(), v.end()); }; @@ -276,37 +258,30 @@ RuleSet servers, channels, origins, plugins, events; RuleAction action = RuleAction::Accept; - // Get the sets + // Get the sets. ini::Section::const_iterator it; - if ((it = sc.find("servers")) != sc.end()) { + if ((it = sc.find("servers")) != sc.end()) servers = toSet(*it); - } - if ((it = sc.find("channels")) != sc.end()) { + if ((it = sc.find("channels")) != sc.end()) channels = toSet(*it); - } - if ((it = sc.find("origins")) != sc.end()) { + if ((it = sc.find("origins")) != sc.end()) origins = toSet(*it); - } - if ((it = sc.find("plugins")) != sc.end()) { + if ((it = sc.find("plugins")) != sc.end()) plugins = toSet(*it); - } - if ((it = sc.find("channels")) != sc.end()) { + if ((it = sc.find("channels")) != sc.end()) channels = toSet(*it); - } - // Get the action - if ((it = sc.find("action")) == sc.end()) { + // Get the action. + if ((it = sc.find("action")) == sc.end()) throw std::invalid_argument("rule: missing 'action'' parameter"); - } - if (it->value() == "drop") { + if (it->value() == "drop") action = RuleAction::Drop; - } else if (it->value() == "accept") { + else if (it->value() == "accept") action = RuleAction::Accept; - } else { + else throw std::invalid_argument("rule: invalid action given: {}"_format(it->value())); - } return Rule(std::move(servers), std::move(channels), @@ -325,28 +300,25 @@ ServerIdentity identity; ServerSettings settings; - // Name + // Name. ini::Section::const_iterator it; - if ((it = sc.find("name")) == sc.end()) { + if ((it = sc.find("name")) == sc.end()) throw std::invalid_argument("server: missing 'name' parameter"); - } else if (!util::isIdentifierValid(it->value())) { + else if (!util::isIdentifierValid(it->value())) throw std::invalid_argument("server: invalid identifier: {}"_format(it->value())); - } name = it->value(); // Host - if ((it = sc.find("host")) == sc.end()) { + if ((it = sc.find("host")) == sc.end()) throw std::invalid_argument("server {}: missing host"_format(name)); - } info.host = it->value(); // Optional identity - if ((it = sc.find("identity")) != sc.end()) { + if ((it = sc.find("identity")) != sc.end()) identity = config.findIdentity(it->value()); - } // Optional port if ((it = sc.find("port")) != sc.end()) { @@ -358,32 +330,26 @@ } // Optional password - if ((it = sc.find("password")) != sc.end()) { + if ((it = sc.find("password")) != sc.end()) info.password = it->value(); - } // Optional flags - if ((it = sc.find("ipv6")) != sc.end() && util::isBoolean(it->value())) { + if ((it = sc.find("ipv6")) != sc.end() && util::isBoolean(it->value())) info.flags |= ServerInfo::Ipv6; - } if ((it = sc.find("ssl")) != sc.end()) { - if (util::isBoolean(it->value())) { + if (util::isBoolean(it->value())) info.flags |= ServerInfo::Ssl; - } } if ((it = sc.find("ssl-verify")) != sc.end()) { - if (util::isBoolean(it->value())) { + if (util::isBoolean(it->value())) info.flags |= ServerInfo::SslVerify; - } } // Options - if ((it = sc.find("auto-rejoin")) != sc.end() && util::isBoolean(it->value())) { + if ((it = sc.find("auto-rejoin")) != sc.end() && util::isBoolean(it->value())) settings.flags |= ServerSettings::AutoRejoin; - } - if ((it = sc.find("join-invite")) != sc.end() && util::isBoolean(it->value())) { + if ((it = sc.find("join-invite")) != sc.end() && util::isBoolean(it->value())) settings.flags |= ServerSettings::JoinInvite; - } // Channels if ((it = sc.find("channels")) != sc.end()) { @@ -393,28 +359,23 @@ if (auto pos = s.find(":") != std::string::npos) { channel.name = s.substr(0, pos); channel.password = s.substr(pos + 1); - } else { + } else channel.name = s; - } settings.channels.push_back(std::move(channel)); } } - if ((it = sc.find("command-char")) != sc.end()) { + if ((it = sc.find("command-char")) != sc.end()) settings.command = it->value(); - } // Reconnect and ping timeout try { - if ((it = sc.find("reconnect-tries")) != sc.end()) { + if ((it = sc.find("reconnect-tries")) != sc.end()) settings.reconnectTries = util::toNumber<std::int8_t>(it->value()); - } - if ((it = sc.find("reconnect-timeout")) != sc.end()) { + if ((it = sc.find("reconnect-timeout")) != sc.end()) settings.reconnectDelay = util::toNumber<std::uint16_t>(it->value()); - } - if ((it = sc.find("ping-timeout")) != sc.end()) { + if ((it = sc.find("ping-timeout")) != sc.end()) settings.pingTimeout = util::toNumber<std::uint16_t>(it->value()); - } } catch (const std::exception &) { log::warning("server {}: invalid number for {}: {}"_format(name, it->key(), it->value())); } @@ -429,9 +390,8 @@ for (const auto &path : path::list(path::PathConfig)) { std::string fullpath = path + "irccd.conf"; - if (!fs::isReadable(fullpath)) { + if (!fs::isReadable(fullpath)) continue; - } try { return Config(fullpath); @@ -448,9 +408,8 @@ assert(util::isIdentifierValid(name)); for (const auto §ion : m_document) { - if (section.key() != "identity") { + if (section.key() != "identity") continue; - } auto it = section.find("name"); @@ -462,9 +421,8 @@ log::warning("identity: invalid identifier: {}"_format(it->value())); continue; } - if (it->value() != name) { + if (it->value() != name) continue; - } return loadIdentity(section); } @@ -479,9 +437,8 @@ std::string fullname = std::string("plugin.") + name; for (const auto §ion : m_document) { - if (section.key() != fullname) { + if (section.key() != fullname) continue; - } return loadPluginConfig(section); } @@ -535,27 +492,24 @@ { ini::Document::const_iterator sc = m_document.find("logs"); - if (sc == m_document.end()) { + if (sc == m_document.end()) return; - } ini::Section::const_iterator it; if ((it = sc->find("type")) != sc->end()) { std::unique_ptr<log::Interface> iface; - /* Console is the default, no test case */ - if (it->value() == "file") { + // Console is the default, no test case. + if (it->value() == "file") iface = loadLogFile(*sc); - } else if (it->value() == "syslog") { + else if (it->value() == "syslog") iface = loadLogSyslog(); - } else { + else throw std::runtime_error("logs: unknown log type: {}"_format(it->value())); - } - if (iface) { + if (iface) log::setInterface(std::move(iface)); - } } } @@ -563,22 +517,18 @@ { ini::Document::const_iterator sc = m_document.find("format"); - if (sc == m_document.end()) { + if (sc == m_document.end()) return; - } std::unique_ptr<IrccdLogFilter> filter = std::make_unique<IrccdLogFilter>(); ini::Section::const_iterator it; - if ((it = sc->find("debug")) != sc->cend()) { + if ((it = sc->find("debug")) != sc->cend()) filter->m_debug = it->value(); - } - if ((it = sc->find("info")) != sc->cend()) { + if ((it = sc->find("info")) != sc->cend()) filter->m_info = it->value(); - } - if ((it = sc->find("warning")) != sc->cend()) { + if ((it = sc->find("warning")) != sc->cend()) filter->m_warning = it->value(); - } log::setFilter(std::move(filter)); } @@ -587,11 +537,9 @@ { std::vector<std::shared_ptr<TransportServer>> transports; - for (const auto §ion : m_document) { - if (section.key() == "transport") { + for (const auto §ion : m_document) + if (section.key() == "transport") transports.push_back(loadTransport(section)); - } - } return transports; } @@ -600,11 +548,9 @@ { std::vector<Rule> rules; - for (const auto §ion : m_document) { - if (section.key() == "rule") { + for (const auto §ion : m_document) + if (section.key() == "rule") rules.push_back(loadRule(section)); - } - } return rules; } @@ -614,9 +560,8 @@ std::vector<std::shared_ptr<Server>> servers; for (const auto §ion : m_document) { - if (section.key() != "server") { + if (section.key() != "server") continue; - } try { servers.push_back(loadServer(section, *this)); @@ -634,9 +579,8 @@ if (it != m_document.end()) { for (const auto &option : *it) { - if (!util::isIdentifierValid(option.key())) { + if (!util::isIdentifierValid(option.key())) continue; - } irccd.pluginService().configure(option.key(), findPluginConfig(option.key())); irccd.pluginService().setFormats(option.key(), findPluginFormats(option.key()));
--- a/lib/irccd/config.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/config.hpp Tue May 24 13:00:35 2016 +0200 @@ -30,6 +30,7 @@ #include "ini.hpp" #include "plugin.hpp" +#include "sysconfig.hpp" namespace irccd { @@ -55,7 +56,7 @@ * \return the config * \throw std::exception on errors or if no config could be found */ - static Config find(); + IRCCD_EXPORT static Config find(); /** * Load the configuration from the specified path. @@ -84,7 +85,7 @@ * \pre util::isValidIdentifier(name) * \return default identity if cannot be found */ - ServerIdentity findIdentity(const std::string &name) const; + IRCCD_EXPORT ServerIdentity findIdentity(const std::string &name) const; /** * Find a plugin configuration if defined in the configuration file. @@ -92,7 +93,7 @@ * \pre util::isValidIdentifier(name) * \return the configuration or empty if not found */ - PluginConfig findPluginConfig(const std::string &name) const; + IRCCD_EXPORT PluginConfig findPluginConfig(const std::string &name) const; /** * Find plugin formats if defined. @@ -100,73 +101,73 @@ * \pre util::isValidIdentifier(name) * \return the formats or empty one if not found */ - PluginFormats findPluginFormats(const std::string &name) const; + IRCCD_EXPORT PluginFormats findPluginFormats(const std::string &name) const; /** * Get the path to the pidfile. * * \return the path or empty if not defined */ - std::string pidfile() const; + IRCCD_EXPORT std::string pidfile() const; /** * Get the uid. * * \return the uid or empty one if no one is set */ - std::string uid() const; + IRCCD_EXPORT std::string uid() const; /** * Get the gid. * * \return the gid or empty one if no one is set */ - std::string gid() const; + IRCCD_EXPORT std::string gid() const; /** * Check if verbosity is enabled. * * \return true if verbosity was requested */ - bool isVerbose() const noexcept; + IRCCD_EXPORT bool isVerbose() const noexcept; /** * Check if foreground is specified (= no daemonize). * * \return true if foreground was requested */ - bool isForeground() const noexcept; + IRCCD_EXPORT bool isForeground() const noexcept; /** * Load logging interface. */ - void loadLogs() const; + IRCCD_EXPORT void loadLogs() const; /** * Load formats for logging. */ - void loadFormats() const; + IRCCD_EXPORT void loadFormats() const; /** * Load transports. * * \return the set of transports */ - std::vector<std::shared_ptr<TransportServer>> loadTransports() const; + IRCCD_EXPORT std::vector<std::shared_ptr<TransportServer>> loadTransports() const; /** * Load rules. * * \return the rules */ - std::vector<Rule> loadRules() const; + IRCCD_EXPORT std::vector<Rule> loadRules() const; /** * Get the list of servers defined. * * \return the list of servers */ - std::vector<std::shared_ptr<Server>> loadServers() const; + IRCCD_EXPORT std::vector<std::shared_ptr<Server>> loadServers() const; /** * Get the list of defined plugins. @@ -174,7 +175,7 @@ * \param irccd the irccd instance * \return the list of plugins */ - void loadPlugins(Irccd &irccd) const; + IRCCD_EXPORT void loadPlugins(Irccd &irccd) const; }; } // !irccd
--- a/lib/irccd/connection.cpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/connection.cpp Tue May 24 13:00:35 2016 +0200 @@ -28,9 +28,8 @@ while (isConnected()) { json::Value object = next(clamp(timeout)); - if (object.isObject() && object["response"].toString() == name) { + if (object.isObject() && object["response"].toString() == name) return object; - } } throw std::runtime_error("connection lost"); @@ -41,9 +40,8 @@ auto object = next(name, timeout); auto value = object.at("status").toString(); - if (!value.empty() && value != "ok") { + if (!value.empty() && value != "ok") throw std::runtime_error(object.at("error").toString()); - } } } // !irccd
--- a/lib/irccd/connection.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/connection.hpp Tue May 24 13:00:35 2016 +0200 @@ -30,6 +30,7 @@ #include "elapsed-timer.hpp" #include "json.hpp" #include "sockets.hpp" +#include "sysconfig.hpp" #include "system.hpp" #include "util.hpp" @@ -73,7 +74,7 @@ * \return the object * \throw net::Error on errors or on timeout */ - json::Value next(const std::string &name, int timeout = 30000); + IRCCD_EXPORT json::Value next(const std::string &name, int timeout = 30000); /** * Just wait if the operation succeeded. @@ -81,7 +82,7 @@ * \param name the response name * \param timeout the timeout */ - void verify(const std::string &name, int timeout = 30000); + IRCCD_EXPORT void verify(const std::string &name, int timeout = 30000); /** * Check if the socket is still connected. @@ -131,7 +132,7 @@ net::Listener<> m_listener; Address m_address; - /* Input buffer */ + // Input buffer. std::string m_input; public: @@ -140,7 +141,7 @@ * * \param address the address */ - ConnectionBase(Address address) + inline ConnectionBase(Address address) : m_address(std::move(address)) { m_socket.set(net::option::SockBlockMode{false}); @@ -150,7 +151,7 @@ /** * \copydoc Connection::isConnected */ - bool isConnected() const noexcept override + inline bool isConnected() const noexcept override { return m_socket.state() == net::State::Connected; } @@ -189,7 +190,7 @@ { assert(!msg.empty()); - /* Add termination */ + // Add termination. msg += "\r\n\r\n"; m_listener.remove(m_socket.handle()); @@ -197,48 +198,45 @@ m_timer.reset(); while (!msg.empty()) { - /* Do not wait the time that is already passed */ + // Do not wait the time that is already passed. m_listener.wait(clamp(timeout)); - /* Try to send at most as possible */ + // Try to send at most as possible. msg.erase(0, m_socket.send(msg)); } - /* Timeout? */ - if (!msg.empty()) { + // Timeout? + if (!msg.empty()) throw std::runtime_error("operation timed out while sending to irccd"); - } } template <typename Address> json::Value ConnectionBase<Address>::next(int timeout) { - /* Maybe there is already something */ + // Maybe there is already something. std::string buffer = util::nextNetwork(m_input); m_listener.remove(m_socket.handle()); m_listener.set(m_socket.handle(), net::Condition::Readable); m_timer.reset(); - /* Read if there is nothing */ + // Read if there is nothing. while (buffer.empty() && isConnected()) { - /* Wait and read */ + // Wait and read. m_listener.wait(clamp(timeout)); m_input += m_socket.recv(512); - /* Finally try */ + // Finally try. buffer = util::nextNetwork(m_input); } - if (!isConnected()) { + if (!isConnected()) throw std::runtime_error("connection lost"); - } json::Value value(json::Buffer{buffer}); - if (!value.isObject()) { + if (!value.isObject()) throw std::invalid_argument("invalid message received"); - } return value; }
--- a/lib/irccd/elapsed-timer.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/elapsed-timer.hpp Tue May 24 13:00:35 2016 +0200 @@ -26,6 +26,8 @@ #include <chrono> +#include "sysconfig.hpp" + namespace irccd { /** @@ -50,7 +52,7 @@ /** * Construct the elapsed timer, start counting. */ - ElapsedTimer() noexcept; + IRCCD_EXPORT ElapsedTimer() noexcept; /** * Virtual destructor defaulted. @@ -60,24 +62,24 @@ /** * Put the timer on pause, the already elapsed time is stored. */ - void pause() noexcept; + IRCCD_EXPORT void pause() noexcept; /** * Restart the timer, does not reset it. */ - void restart() noexcept; + IRCCD_EXPORT void restart() noexcept; /** * Reset the timer to 0. */ - void reset() noexcept; + IRCCD_EXPORT void reset() noexcept; /** * Get the number of elapsed milliseconds. * * \return the milliseconds */ - unsigned elapsed() noexcept; + IRCCD_EXPORT unsigned elapsed() noexcept; }; } // !irccd
--- a/lib/irccd/fs.cpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/fs.cpp Tue May 24 13:00:35 2016 +0200 @@ -69,9 +69,8 @@ { auto fp = std::fopen(path.c_str(), mode.c_str()); - if (fp == nullptr) { + if (fp == nullptr) return false; - } std::fclose(fp); @@ -112,17 +111,17 @@ if (input.empty()) return input; - /* First, remove any duplicates */ + // First, remove any duplicates. input.erase(std::unique(input.begin(), input.end(), [&] (char c1, char c2) { return c1 == c2 && (c1 == '/' || c1 == '\\'); }), input.end()); - /* Add a trailing / or \\ */ + // Add a trailing / or \\. char c = input[input.length() - 1]; if (c != '/' && c != '\\') input += separator(); - /* Now converts all / to \\ for Windows and the opposite for Unix */ + // Now converts all / to \\ for Windows and the opposite for Unix. #if defined(_WIN32) std::replace(input.begin(), input.end(), '/', '\\'); #else
--- a/lib/irccd/fs.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/fs.hpp Tue May 24 13:00:35 2016 +0200 @@ -36,6 +36,8 @@ #include <string> #include <vector> +#include "sysconfig.hpp" + namespace irccd { namespace fs { @@ -70,24 +72,6 @@ }; /** - * Check if two entries are identical. - * - * \param e1 the first entry - * \param e2 the second entry - * \return true if they are identical - */ -bool operator==(const Entry &e1, const Entry &e2) noexcept; - -/** - * Check if two entries are different. - * - * \param e1 the first entry - * \param e2 the second entry - * \return true if they are different - */ -bool operator!=(const Entry &e1, const Entry &e2) noexcept; - -/** * Get the separator for that system. * * \return \ on Windows and / otherwise @@ -107,7 +91,7 @@ * \param path the path * \return the updated path */ -std::string clean(std::string path); +IRCCD_EXPORT std::string clean(std::string path); /** * Get the base name from a path. @@ -117,7 +101,7 @@ * \param path the path * \return the base name */ -std::string baseName(std::string path); +IRCCD_EXPORT std::string baseName(std::string path); /** * Get the parent directory from a path. @@ -127,7 +111,7 @@ * \param path the path * \return the parent directory */ -std::string dirName(std::string path); +IRCCD_EXPORT std::string dirName(std::string path); /** * Get stat information. @@ -136,7 +120,7 @@ * \return the stat information * \throw std::runtime_error on failure */ -struct stat stat(const std::string &path); +IRCCD_EXPORT struct stat stat(const std::string &path); /** * Check if a file exists. @@ -146,7 +130,7 @@ * \param path the path to check * \return true if the path exists */ -bool exists(const std::string &path) noexcept; +IRCCD_EXPORT bool exists(const std::string &path) noexcept; /** * Check if the path is absolute. @@ -154,7 +138,7 @@ * \param path the path * \return true if the path is absolute */ -bool isAbsolute(const std::string &path) noexcept; +IRCCD_EXPORT bool isAbsolute(const std::string &path) noexcept; /** * Check if the path is relative. @@ -162,7 +146,7 @@ * \param path the path * \return true if the path is absolute */ -bool isRelative(const std::string &path) noexcept; +IRCCD_EXPORT bool isRelative(const std::string &path) noexcept; /** * Check if the file is readable. @@ -170,7 +154,7 @@ * \param path the path * \return true if has read access */ -bool isReadable(const std::string &path) noexcept; +IRCCD_EXPORT bool isReadable(const std::string &path) noexcept; /** * Check if the file is writable. @@ -178,7 +162,7 @@ * \param path the path * \return true if has write access */ -bool isWritable(const std::string &path) noexcept; +IRCCD_EXPORT bool isWritable(const std::string &path) noexcept; /** * Check if the file is a regular file. @@ -186,7 +170,7 @@ * \param path the path * \return true if it is a file and false if not or not readable */ -bool isFile(const std::string &path) noexcept; +IRCCD_EXPORT bool isFile(const std::string &path) noexcept; /** * Check if the file is a directory. @@ -194,7 +178,7 @@ * \param path the path * \return true if it is a directory and false if not or not readable */ -bool isDirectory(const std::string &path) noexcept; +IRCCD_EXPORT bool isDirectory(const std::string &path) noexcept; /** * Check if the file is a symbolic link. @@ -202,7 +186,7 @@ * \param path the path * \return true if it is a symbolic link and false if not or not readable */ -bool isSymlink(const std::string &path) noexcept; +IRCCD_EXPORT bool isSymlink(const std::string &path) noexcept; /** * Read a directory and return a list of entries (not recursive). @@ -212,7 +196,7 @@ * \return the list of entries * \throw std::runtime_error on failure */ -std::vector<Entry> readdir(const std::string &path, int flags = 0); +IRCCD_EXPORT std::vector<Entry> readdir(const std::string &path, int flags = 0); /** * Create a directory recursively. @@ -222,7 +206,7 @@ * \throw std::runtime_error on failure * \post all intermediate directories are created */ -void mkdir(const std::string &path, int mode = 0700); +IRCCD_EXPORT void mkdir(const std::string &path, int mode = 0700); /** * Remove a directory recursively. @@ -231,7 +215,7 @@ * * \param path the path */ -void rmdir(const std::string &path) noexcept; +IRCCD_EXPORT void rmdir(const std::string &path) noexcept; /** * Search an item recursively. @@ -311,7 +295,7 @@ * \return the current working directory * \throw std::runtime_error on failure */ -std::string cwd(); +IRCCD_EXPORT std::string cwd(); } // !fs
--- a/lib/irccd/ini.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/ini.hpp Tue May 24 13:00:35 2016 +0200 @@ -110,6 +110,8 @@ #include <string> #include <vector> +#include "sysconfig.hpp" + namespace irccd { /** @@ -559,7 +561,7 @@ * \return the list of tokens * \throws Error on errors */ -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. @@ -568,7 +570,7 @@ * \return the list of tokens * \throws Error on errors */ -Tokens analyse(std::istream &stream); +IRCCD_EXPORT Tokens analyse(std::istream &stream); /** * Parse the produced tokens. @@ -578,7 +580,7 @@ * \return the document * \throw Error on errors */ -Document parse(const Tokens &tokens, const std::string &path = "."); +IRCCD_EXPORT Document parse(const Tokens &tokens, const std::string &path = "."); /** * Parse a file. @@ -587,7 +589,7 @@ * \return the document * \throw Error on errors */ -Document readFile(const std::string &filename); +IRCCD_EXPORT Document readFile(const std::string &filename); /** * Parse a string. @@ -598,14 +600,14 @@ * \return the document * \throw Error on errors */ -Document readString(const std::string &buffer); +IRCCD_EXPORT Document readString(const std::string &buffer); /** * Show all tokens and their description. * * \param tokens the tokens */ -void dump(const Tokens &tokens); +IRCCD_EXPORT void dump(const Tokens &tokens); } // !ini
--- a/lib/irccd/irccd.cpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/irccd.cpp Tue May 24 13:00:35 2016 +0200 @@ -70,9 +70,8 @@ FD_ZERO(&setinput); FD_ZERO(&setoutput); - for (const auto &service : m_services) { + for (const auto &service : m_services) service->prepare(setinput, setoutput, max); - } // Do the selection. struct timeval tv; @@ -83,9 +82,8 @@ int error = select(max + 1, &setinput, &setoutput, nullptr, &tv); // Skip anyway if requested to stop - if (!m_running) { + if (!m_running) return; - } // Skip on error. if (error < 0 && errno != EINTR) { @@ -94,9 +92,8 @@ } // Process after selection. - for (const auto &service : m_services) { + for (const auto &service : m_services) service->sync(setinput, setoutput); - } } void Irccd::dispatch() @@ -114,13 +111,11 @@ m_events.clear(); } - if (copy.size() > 0) { + if (copy.size() > 0) log::debug() << "irccd: dispatching " << copy.size() << " event" << (copy.size() > 1 ? "s" : "") << endl; - } - for (auto &ev : copy) { + for (auto &ev : copy) ev(*this); - } } void Irccd::stop()
--- a/lib/irccd/irccd.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/irccd.hpp Tue May 24 13:00:35 2016 +0200 @@ -32,6 +32,7 @@ #include <vector> #include "application.hpp" +#include "sysconfig.hpp" namespace irccd { @@ -75,7 +76,7 @@ /** * Prepare standard services. */ - Irccd(); + IRCCD_EXPORT Irccd(); /** * Add a generic service. @@ -144,27 +145,27 @@ * \param ev the event * \note Thread-safe */ - void post(std::function<void (Irccd &)> ev) noexcept; + IRCCD_EXPORT void post(std::function<void (Irccd &)> ev) noexcept; /** * Loop forever by calling poll() and dispatch() indefinitely. */ - void run(); + IRCCD_EXPORT void run(); /** * Poll the next events without blocking (250 ms max). */ - void poll(); + IRCCD_EXPORT void poll(); /** * Dispatch the pending events, usually after calling poll(). */ - void dispatch(); + IRCCD_EXPORT void dispatch(); /** * Request to stop, usually from a signal. */ - void stop(); + IRCCD_EXPORT void stop(); }; } // !irccd
--- a/lib/irccd/irccdctl.cpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/irccdctl.cpp Tue May 24 13:00:35 2016 +0200 @@ -124,21 +124,19 @@ { ini::Section::const_iterator it; - /* host */ + // Host. std::string host; - if ((it = sc.find("host")) == sc.end()) { + if ((it = sc.find("host")) == sc.end()) throw std::invalid_argument("missing host parameter"); - } host = it->value(); - /* port */ + // Port. int port; - if ((it = sc.find("port")) == sc.end()) { + if ((it = sc.find("port")) == sc.end()) throw std::invalid_argument("missing port parameter"); - } try { port = std::stoi(it->value()); @@ -146,17 +144,16 @@ throw std::invalid_argument("invalid port number: " + it->value()); } - /* domain */ + // Domain. Ip::Type domain{Ip::v4}; if ((it = sc.find("domain")) != sc.end()) { - if (it->value() == "ipv6") { + if (it->value() == "ipv6") domain = Ip::v6; - } else if (it->value() == "ipv4") { + else if (it->value() == "ipv4") domain = Ip::v4; - } else { + else throw std::invalid_argument("invalid domain: " + it->value()); - } } m_connection = std::make_unique<ConnectionBase<Ip>>(Ip{host, port, domain}); @@ -183,66 +180,59 @@ { auto it = sc.find("type"); - if (it == sc.end()) { + if (it == sc.end()) throw std::invalid_argument("missing type parameter"); - } - if (it->value() == "ip") { + if (it->value() == "ip") readConnectIp(sc); - } else if (it->value() == "unix") { + else if (it->value() == "unix") readConnectUnix(sc); - } else { + else throw std::invalid_argument("invalid type given: " + it->value()); - } } void Irccdctl::readGeneral(const ini::Section &sc) { auto verbose = sc.find("verbose"); - if (verbose != sc.end()) { + if (verbose != sc.end()) log::setVerbose(util::isBoolean(verbose->value())); - } } void Irccdctl::readAliases(const ini::Section &sc) { for (const ini::Option &option : sc) { - /* This is the alias name */ + // This is the alias name. Alias alias(option.key()); - if (m_commands.count(option.key()) > 0) { + if (m_commands.count(option.key()) > 0) throw std::invalid_argument("there is already a command named " + option.key()); - } - /* Iterate over the list of commands to execute for this alias */ + // Iterate over the list of commands to execute for this alias. for (const std::string &repl : option) { - /* This is the alias split string */ + // This is the alias split string. std::vector<std::string> list = util::split(repl, " \t"); - if (list.size() < 1) { + if (list.size() < 1) throw std::invalid_argument("alias require at least one argument"); - } - /* First argument is the command/alias to execute */ + // First argument is the command/alias to execute. std::string command = list[0]; - /* This is the alias arguments */ + // This is the alias arguments. std::vector<AliasArg> args; - for (auto it = list.begin() + 1; it != list.end(); ++it) { + for (auto it = list.begin() + 1; it != list.end(); ++it) args.push_back(std::move(*it)); - } alias.push_back({std::move(command), std::move(args)}); } - /* Show for debugging purpose */ + // Show for debugging purpose. log::debug("alias {}:"_format(option.key())); - for (const auto &cmd : alias) { + for (const auto &cmd : alias) log::debug(" {} {}"_format(cmd.command(), util::join(cmd.args().begin(), cmd.args().end(), ' '))); - } m_aliases.emplace(option.key(), std::move(alias)); } @@ -253,20 +243,17 @@ ini::Document doc = ini::readFile(path); ini::Document::const_iterator it = doc.find("connect"); - /* Do not try to read [connect] if specified at command line */ - if (it != doc.end() && options.count("-t") == 0 && options.count("--type") == 0) { + // Do not try to read [connect] if specified at command line. + if (it != doc.end() && options.count("-t") == 0 && options.count("--type") == 0) readConnect(*it); - } - if ((it = doc.find("general")) != doc.end()) { + if ((it = doc.find("general")) != doc.end()) readGeneral(*it); - } - if ((it = doc.find("alias")) != doc.end()) { + if ((it = doc.find("alias")) != doc.end()) readAliases(*it); - } } /* - * Initialize a connection from the command line + * Initialize a connection from the command line. * ------------------------------------------------------------------ */ @@ -274,21 +261,19 @@ { parser::Result::const_iterator it; - /* host (-h or --host) */ + // Host (-h or --host). std::string host; - if ((it = options.find("-h")) == options.end() && (it = options.find("--host")) == options.end()) { + if ((it = options.find("-h")) == options.end() && (it = options.find("--host")) == options.end()) throw std::invalid_argument("missing host argument (-h or --host)"); - } host = it->second; - /* port (-p or --port) */ + // Port (-p or --port). int port; - if ((it = options.find("-p")) == options.end() && (it = options.find("--port")) == options.end()) { + if ((it = options.find("-p")) == options.end() && (it = options.find("--port")) == options.end()) throw std::invalid_argument("missing port argument (-p or --port)"); - } try { port = std::stoi(it->second); @@ -304,9 +289,8 @@ #if !defined(IRCCD_SYSTEM_WINDOWS) parser::Result::const_iterator it; - if ((it = options.find("-P")) == options.end() && (it = options.find("--path")) == options.end()) { + if ((it = options.find("-P")) == options.end() && (it = options.find("--path")) == options.end()) throw std::invalid_argument("missing path parameter (-P or --path)"); - } m_connection = std::make_unique<ConnectionBase<Local>>(Local{it->second, false}); #else @@ -322,22 +306,19 @@ auto it = options.find("-t"); - if (it == options.end()) { + if (it == options.end()) it = options.find("--type"); - } - if (it->second == "ip" || it->second == "ipv6") { + if (it->second == "ip" || it->second == "ipv6") return parseConnectIp(options, it->second == "ipv6"); - } - if (it->second == "unix") { + if (it->second == "unix") return parseConnectUnix(options); - } throw std::invalid_argument("invalid type given: " + it->second); } parser::Result Irccdctl::parse(int &argc, char **&argv) const { - /* 1. Parse command line options */ + // 1. Parse command line options. parser::Options def{ { "-c", true }, { "--config", true }, @@ -364,9 +345,8 @@ // NOTREACHED } - if (result.count("-v") != 0 || result.count("--verbose") != 0) { + if (result.count("-v") != 0 || result.count("--verbose") != 0) log::setVerbose(true); - } } catch (const std::exception &ex) { log::warning("{}: {}"_format(sys::programName(), ex.what())); usage(); @@ -377,20 +357,18 @@ void Irccdctl::exec(const RemoteCommand &cmd, std::vector<std::string> args) { - /* 1. Build options from command line arguments. */ + // 1. Build options from command line arguments. parser::Options def; for (const auto &opt : cmd.options()) { - /* parser::read needs '-' and '--' so add them */ - if (!opt.simpleKey().empty()) { + // parser::read needs '-' and '--' so add them. + if (!opt.simpleKey().empty()) def.emplace("-"s + opt.simpleKey(), !opt.arg().empty()); - } - if (!opt.longKey().empty()) { + if (!opt.longKey().empty()) def.emplace("--"s + opt.longKey(), !opt.arg().empty()); - } } - /* 2. Parse them, remove them from args (in parser::read) and build the map with id. */ + // 2. Parse them, remove them from args (in parser::read) and build the map with id. RemoteCommandRequest::Options requestOptions; for (const auto &pair : parser::read(args, def)) { @@ -402,27 +380,24 @@ requestOptions.emplace(it->id(), pair.second); } - /* 3. Check number of arguments. */ - if (args.size() < cmd.min()) { + // 3. Check number of arguments. + if (args.size() < cmd.min()) throw std::runtime_error("too few arguments"); - } - if (args.size() > cmd.max()) { + if (args.size() > cmd.max()) throw std::runtime_error("too many arguments"); - } - /* 4. Construct the request, if the returned value is not an object, do not send anything (e.g. help). */ + // 4. Construct the request, if the returned value is not an object, do not send anything (e.g. help). json::Value request = cmd.request(*this, RemoteCommandRequest(std::move(requestOptions), std::move(args))); - if (!request.isObject()) { + if (!request.isObject()) return; - } request.insert("command", cmd.name()); - /* 5. Send the command */ + // 5. Send the command. m_connection->send(request.toJson(0), 30000); - /* 6. Parse the result */ + // 6. Parse the result. cmd.result(*this, m_connection->next(cmd.name(), 30000)); } @@ -433,34 +408,31 @@ std::vector<std::string> cmdArgs; std::vector<std::string>::size_type toremove = 0; - /* 1. Append command name before */ + // 1. Append command name before. cmdArgs.push_back(cmd.command()); for (const AliasArg &arg : cmd.args()) { if (arg.isPlaceholder()) { - if (args.size() < arg.index() + 1) { + if (args.size() < arg.index() + 1) throw std::invalid_argument("missing argument for placeholder %" + std::to_string(arg.index())); - } cmdArgs.push_back(args[arg.index()]); - if (arg.index() + 1 > toremove) { + if (arg.index() + 1 > toremove) toremove = arg.index() + 1; - } - } else { + } else cmdArgs.push_back(arg.value()); - } } assert(toremove <= args.size()); - /* 2. Remove the arguments that been placed in placeholders */ + // 2. Remove the arguments that been placed in placeholders. args.erase(args.begin(), args.begin() + toremove); - /* 3. Now append the rest of arguments */ + // 3. Now append the rest of arguments. std::copy(args.begin(), args.end(), std::back_inserter(cmdArgs)); - /* 4. Finally try to execute */ + // 4. Finally try to execute. exec(cmdArgs); } } @@ -472,19 +444,18 @@ auto name = args[0]; auto alias = m_aliases.find(name); - /* Remove name */ + // Remove name. args.erase(args.begin()); - if (alias != m_aliases.end()) { + if (alias != m_aliases.end()) exec(alias->second, args); - } else { + else { auto cmd = m_commands.find(name); - if (cmd != m_commands.end()) { + if (cmd != m_commands.end()) exec(*cmd->second, args); - } else { + else throw std::invalid_argument("no alias or command named " + name); - } } } @@ -492,17 +463,16 @@ { log::info("{}: connecting to irccd..."_format(sys::programName())); - /* Try to connect */ + // Try to connect. m_connection->connect(30000); - /* Get irccd information */ + // Get irccd information. json::Value object = m_connection->next(30000); - if (!object.contains("program") || object.at("program").toString() != "irccd") { + if (!object.contains("program") || object.at("program").toString() != "irccd") throw std::runtime_error("not an irccd server"); - } - /* Get values */ + // Get values. m_major = object.at("major").toInt(); m_minor = object.at("minor").toInt(); m_patch = object.at("patch").toInt(); @@ -516,7 +486,7 @@ void Irccdctl::run(int argc, char **argv) { - /* 1. Read command line arguments */ + // 1. Read command line arguments. parser::Result result = parse(argc, argv); /* @@ -529,21 +499,19 @@ * 3. From the configuration file searched through directories */ try { - if (result.count("-t") > 0 || result.count("--type") > 0) { + if (result.count("-t") > 0 || result.count("--type") > 0) parseConnect(result); - } auto it = result.find("-c"); - if (it != result.end() || (it = result.find("--config")) != result.end()) { + if (it != result.end() || (it = result.find("--config")) != result.end()) read(it->second, result); - } else { + else { for (const std::string &dir : path::list(path::PathConfig)) { std::string path = dir + "irccdctl.conf"; - if (fs::exists(path)) { + if (fs::exists(path)) read(path, result); - } } } } catch (const std::exception &ex) { @@ -556,7 +524,7 @@ // NOTREACHED } - /* help does not require connection */ + // Help does not require connection. if (std::strcmp(argv[0], "help") != 0) { if (!m_connection) { log::warning("{}: no connection specified"_format(sys::programName())); @@ -566,12 +534,11 @@ connect(); } - /* Build a vector of arguments */ + // Build a vector of arguments. std::vector<std::string> args; - for (int i = 0; i < argc; ++i) { + for (int i = 0; i < argc; ++i) args.push_back(argv[i]); - } exec(args); }
--- a/lib/irccd/irccdctl.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/irccdctl.hpp Tue May 24 13:00:35 2016 +0200 @@ -49,12 +49,12 @@ */ class Irccdctl : public Application { private: - /* Irccd's information */ + // Irccd's information. unsigned short m_major{0}; unsigned short m_minor{0}; unsigned short m_patch{0}; - /* Irccd's compilation option */ + // Irccd's compilation option. bool m_javascript{true}; bool m_ssl{true}; @@ -84,7 +84,7 @@ * \param cmd the command * \param args the arguments */ - void exec(const RemoteCommand &cmd, std::vector<std::string> args); + IRCCD_EXPORT void exec(const RemoteCommand &cmd, std::vector<std::string> args); /** * Execute the given alias. @@ -92,14 +92,14 @@ * \param alias the alias * \param args the arguments */ - void exec(const Alias &alias, std::vector<std::string> args); + IRCCD_EXPORT void exec(const Alias &alias, std::vector<std::string> args); /** * Resolve the command line arguments. * * \param args the main arguments */ - void exec(std::vector<std::string> args); + IRCCD_EXPORT void exec(std::vector<std::string> args); /** * Get the connection. @@ -117,7 +117,7 @@ * \param argc the number of arguments * \param argv the arguments */ - void run(int argc, char **argv); + IRCCD_EXPORT void run(int argc, char **argv); }; } // !irccd
--- a/lib/irccd/json.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/json.hpp Tue May 24 13:00:35 2016 +0200 @@ -36,6 +36,8 @@ #include <utility> #include <vector> +#include "sysconfig.hpp" + namespace irccd { /** @@ -372,7 +374,7 @@ * * \param type the type */ - Value(Type type); + IRCCD_EXPORT Value(Type type); /** * Construct a null value. @@ -469,7 +471,7 @@ * \param buffer the text * \throw Error on errors */ - Value(const Buffer &buffer); + IRCCD_EXPORT Value(const Buffer &buffer); /** * Construct a value from a file. @@ -477,7 +479,7 @@ * \param file the file * \throw Error on errors */ - Value(const File &file); + IRCCD_EXPORT Value(const File &file); /** * Move constructor. @@ -527,7 +529,7 @@ /** * Destructor. */ - ~Value(); + IRCCD_EXPORT ~Value(); /** * Get an iterator to the beginning. @@ -622,21 +624,21 @@ * * \return the value or false if not a boolean */ - bool toBool() const noexcept; + IRCCD_EXPORT bool toBool() const noexcept; /** * Get the value as integer. * * \return the value or 0 if not a integer */ - int toInt() const noexcept; + IRCCD_EXPORT int toInt() const noexcept; /** * Get the value as real. * * \return the value or 0 if not a real */ - double toReal() const noexcept; + IRCCD_EXPORT double toReal() const noexcept; /** * Get the value as string. @@ -1152,7 +1154,7 @@ * \param input the input * \return the escaped string */ -std::string escape(const std::string &input); +IRCCD_EXPORT std::string escape(const std::string &input); /** * Convenient function for creating array from initializer list.
--- a/lib/irccd/logger.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/logger.hpp Tue May 24 13:00:35 2016 +0200 @@ -24,12 +24,12 @@ * \brief Logging facilities. */ -#include "sysconfig.hpp" - #include <memory> #include <sstream> #include <utility> +#include "sysconfig.hpp" + namespace irccd { namespace log { @@ -161,17 +161,17 @@ /** * \copydoc Interface::debug */ - void debug(const std::string &line) override; + IRCCD_EXPORT void debug(const std::string &line) override; /** * \copydoc Interface::info */ - void info(const std::string &line) override; + IRCCD_EXPORT void info(const std::string &line) override; /** * \copydoc Interface::warning */ - void warning(const std::string &line) override; + IRCCD_EXPORT void warning(const std::string &line) override; }; /* @@ -194,22 +194,22 @@ * \param normal the path to the normal logs * \param errors the path to the errors logs */ - File(std::string normal, std::string errors); + IRCCD_EXPORT File(std::string normal, std::string errors); /** * \copydoc Interface::debug */ - void debug(const std::string &line) override; + IRCCD_EXPORT void debug(const std::string &line) override; /** * \copydoc Interface::info */ - void info(const std::string &line) override; + IRCCD_EXPORT void info(const std::string &line) override; /** * \copydoc Interface::warning */ - void warning(const std::string &line) override; + IRCCD_EXPORT void warning(const std::string &line) override; }; /* @@ -227,17 +227,17 @@ /** * \copydoc Interface::debug */ - void debug(const std::string &line) override; + IRCCD_EXPORT void debug(const std::string &line) override; /** * \copydoc Interface::info */ - void info(const std::string &line) override; + IRCCD_EXPORT void info(const std::string &line) override; /** * \copydoc Interface::warning */ - void warning(const std::string &line) override; + IRCCD_EXPORT void warning(const std::string &line) override; }; /* @@ -255,27 +255,27 @@ /** * Open the syslog. */ - Syslog(); + IRCCD_EXPORT Syslog(); /** * Close the syslog. */ - ~Syslog(); + IRCCD_EXPORT ~Syslog(); /** * \copydoc Interface::debug */ - void debug(const std::string &line) override; + IRCCD_EXPORT void debug(const std::string &line) override; /** * \copydoc Interface::info */ - void info(const std::string &line) override; + IRCCD_EXPORT void info(const std::string &line) override; /** * \copydoc Interface::warning */ - void warning(const std::string &line) override; + IRCCD_EXPORT void warning(const std::string &line) override; }; #endif // !HAVE_SYSLOG @@ -291,7 +291,7 @@ * \pre iface must not be null * \param iface the new interface */ -void setInterface(std::unique_ptr<Interface> iface) noexcept; +IRCCD_EXPORT void setInterface(std::unique_ptr<Interface> iface) noexcept; /** * Set an optional filter. @@ -299,7 +299,7 @@ * \pre filter must not be null * \param filter the filter */ -void setFilter(std::unique_ptr<Filter> filter) noexcept; +IRCCD_EXPORT void setFilter(std::unique_ptr<Filter> filter) noexcept; /** * Get the stream for informational messages. @@ -310,7 +310,7 @@ * \return the stream * \note Has no effect if verbose is set to false. */ -std::ostream &info(const std::string &message = ""); +IRCCD_EXPORT std::ostream &info(const std::string &message = ""); /** * Get the stream for warnings. @@ -320,7 +320,7 @@ * \param message the optional message to write * \return the stream */ -std::ostream &warning(const std::string &message = ""); +IRCCD_EXPORT std::ostream &warning(const std::string &message = ""); /** * Get the stream for debug messages. @@ -331,21 +331,21 @@ * \return the stream * \note Has no effect if compiled in release mode. */ -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 */ -bool isVerbose() noexcept; +IRCCD_EXPORT bool isVerbose() noexcept; /** * Set the verbosity mode. * * \param mode the new mode */ -void setVerbose(bool mode) noexcept; +IRCCD_EXPORT void setVerbose(bool mode) noexcept; } // !log
--- a/lib/irccd/mod-directory.cpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/mod-directory.cpp Tue May 24 13:00:35 2016 +0200 @@ -41,15 +41,13 @@ duk::push(ctx, duk::This{}); duk::getProperty<void>(ctx, -1, "path"); - if (duk::type(ctx, -1) != DUK_TYPE_STRING) { + if (duk::type(ctx, -1) != DUK_TYPE_STRING) duk::raise(ctx, duk::TypeError("invalid this binding")); - } std::string ret = duk::get<std::string>(ctx, -1); - if (ret.empty()) { + if (ret.empty()) duk::raise(ctx, duk::TypeError("invalid directory with empty path")); - } duk::pop(ctx, 2); @@ -76,23 +74,20 @@ auto entries = fs::readdir(base); for (const auto &entry : entries) { - if (entry.type != fs::Entry::Dir && pred(entry.name)) { + if (entry.type != fs::Entry::Dir && pred(entry.name)) return base + entry.name; - } } - if (!recursive) { + 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()) { + if (!path.empty()) return path; - } } } @@ -137,26 +132,24 @@ try { std::string path; - if (duk::is<std::string>(ctx, patternIndex)) { + if (duk::is<std::string>(ctx, patternIndex)) path = findName(base, duk::get<std::string>(ctx, patternIndex), recursive); - } else { - /* Check if it's a valid RegExp object */ + else { + // Check if it's a valid RegExp object. duk::getGlobal<void>(ctx, "RegExp"); bool isRegex = duk::instanceof(ctx, patternIndex, -1); duk::pop(ctx); - if (isRegex) { + if (isRegex) path = findRegex(base, duk::getProperty<std::string>(ctx, patternIndex, "source"), recursive); - } else { + else duk::raise(ctx, duk::TypeError("pattern must be a string or a regex expression")); - } } - if (path.empty()) { + if (path.empty()) return 0; - } duk::push(ctx, path); } catch (const std::exception &ex) { @@ -174,9 +167,8 @@ */ duk::Ret remove(duk::ContextPtr ctx, const std::string &path, bool recursive) { - if (!fs::isDirectory(path)) { + if (!fs::isDirectory(path)) duk::raise(ctx, SystemError(EINVAL, "not a directory")); - } if (!recursive) { #if defined(_WIN32) @@ -184,9 +176,8 @@ #else ::remove(path.c_str()); #endif - } else { + } else fs::rmdir(path.c_str()); - } return 0; } @@ -251,17 +242,15 @@ */ duk::Ret constructor(duk::ContextPtr ctx) { - if (!duk_is_constructor_call(ctx)) { + if (!duk_is_constructor_call(ctx)) return 0; - } try { std::string path = duk::require<std::string>(ctx, 0); std::int8_t flags = duk::optional<int>(ctx, 1, 0); - if (!fs::isDirectory(path)) { + if (!fs::isDirectory(path)) duk::raise(ctx, SystemError(EINVAL, "not a directory")); - } std::vector<fs::Entry> list = fs::readdir(path, flags);
--- a/lib/irccd/mod-directory.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/mod-directory.hpp Tue May 24 13:00:35 2016 +0200 @@ -38,12 +38,12 @@ /** * Irccd.Directory. */ - DirectoryModule() noexcept; + IRCCD_EXPORT DirectoryModule() noexcept; /** * \copydoc Module::load */ - virtual void load(Irccd &irccd, JsPlugin &plugin); + IRCCD_EXPORT void load(Irccd &irccd, JsPlugin &plugin) override; }; } // !irccd
--- a/lib/irccd/mod-elapsed-timer.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/mod-elapsed-timer.hpp Tue May 24 13:00:35 2016 +0200 @@ -36,12 +36,12 @@ /** * Irccd.ElapsedTimer. */ - ElapsedTimerModule() noexcept; + IRCCD_EXPORT ElapsedTimerModule() noexcept; /** * \copydoc Module::load */ - virtual void load(Irccd &irccd, JsPlugin &plugin); + IRCCD_EXPORT virtual void load(Irccd &irccd, JsPlugin &plugin); }; } // !irccd
--- a/lib/irccd/mod-file.cpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/mod-file.cpp Tue May 24 13:00:35 2016 +0200 @@ -107,9 +107,8 @@ /* Remove trailing \r for CRLF line style */ inline std::string clearCr(std::string input) { - if (input.length() > 0 && input.back() == '\r') { + if (input.length() > 0 && input.back() == '\r') input.pop_back(); - } return input; } @@ -195,15 +194,13 @@ } } - /* Maybe an error in the stream */ - if (std::ferror(fp)) { + // Maybe an error in the stream. + if (std::ferror(fp)) duk::raise(ctx, SystemError()); - } - /* Missing '\n' in end of file */ - if (!buffer.empty()) { + // Missing '\n' in end of file. + if (!buffer.empty()) duk::putProperty(ctx, -1, i++, clearCr(buffer)); - } return 1; } @@ -226,9 +223,8 @@ auto amount = duk::optional<int>(ctx, 0, -1); auto file = duk::self<duk::Pointer<File>>(ctx); - if (amount == 0 || file->handle() == nullptr) { + if (amount == 0 || file->handle() == nullptr) return 0; - } try { std::string data; @@ -241,9 +237,8 @@ while (!std::feof(file->handle())) { nread = std::fread(&buffer[0], sizeof (buffer[0]), buffer.size(), file->handle()); - if (std::ferror(file->handle())) { + if (std::ferror(file->handle())) duk::raise(ctx, SystemError()); - } std::copy(buffer.begin(), buffer.begin() + nread, std::back_inserter(data)); total += nread; @@ -252,9 +247,8 @@ 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())) { + if (std::ferror(file->handle())) duk::raise(ctx, SystemError()); - } data.resize(total); } @@ -283,17 +277,12 @@ std::FILE *fp = duk::self<duk::Pointer<File>>(ctx)->handle(); std::string result; - if (fp == nullptr || std::feof(fp)) { + if (fp == nullptr || std::feof(fp)) return 0; - } - - for (int ch; (ch = std::fgetc(fp)) != EOF && ch != '\n'; ) { + for (int ch; (ch = std::fgetc(fp)) != EOF && ch != '\n'; ) result += (char)ch; - } - - if (std::ferror(fp)) { + if (std::ferror(fp)) duk::raise(ctx, SystemError()); - } duk::push(ctx, clearCr(result)); @@ -311,9 +300,8 @@ */ duk::Ret methodRemove(duk::ContextPtr ctx) { - if (::remove(duk::self<duk::Pointer<File>>(ctx)->path().c_str()) < 0) { + if (::remove(duk::self<duk::Pointer<File>>(ctx)->path().c_str()) < 0) duk::raise(ctx, SystemError()); - } return 0; } @@ -336,9 +324,8 @@ auto amount = duk::require<int>(ctx, 1); auto fp = duk::self<duk::Pointer<File>>(ctx)->handle(); - if (fp != nullptr && std::fseek(fp, amount, type) != 0) { + if (fp != nullptr && std::fseek(fp, amount, type) != 0) duk::raise(ctx, SystemError()); - } return 0; } @@ -361,11 +348,10 @@ struct stat st; auto file = duk::self<duk::Pointer<File>>(ctx); - if (file->handle() == nullptr && ::stat(file->path().c_str(), &st) < 0) { + if (file->handle() == nullptr && ::stat(file->path().c_str(), &st) < 0) duk::raise(ctx, SystemError()); - } else { + else duk::push(ctx, st); - } return 1; } @@ -388,15 +374,13 @@ auto fp = duk::self<duk::Pointer<File>>(ctx)->handle(); long pos; - if (fp == nullptr) { + if (fp == nullptr) return 0; - } - if ((pos = std::ftell(fp)) == -1L) { + if ((pos = std::ftell(fp)) == -1L) duk::raise(ctx, SystemError()); - } else { + else duk::push(ctx, (int)pos); - } return 1; } @@ -419,15 +403,13 @@ std::FILE *fp = duk::self<duk::Pointer<File>>(ctx)->handle(); std::string data = duk::require<std::string>(ctx, 0); - if (fp == nullptr) { + if (fp == nullptr) return 0; - } std::size_t nwritten = std::fwrite(data.c_str(), 1, data.length(), fp); - if (std::ferror(fp)) { + if (std::ferror(fp)) duk::raise(ctx, SystemError()); - } duk::push(ctx, (int)nwritten); @@ -469,9 +451,8 @@ */ duk::Ret constructor(duk::ContextPtr ctx) { - if (!duk_is_constructor_call(ctx)) { + if (!duk_is_constructor_call(ctx)) return 0; - } std::string path = duk::require<std::string>(ctx, 0); std::string mode = duk::require<std::string>(ctx, 1); @@ -554,9 +535,8 @@ */ duk::Ret functionRemove(duk::ContextPtr ctx) { - if (::remove(duk::require<std::string>(ctx, 0).c_str()) < 0) { + if (::remove(duk::require<std::string>(ctx, 0).c_str()) < 0) duk::raise(ctx, SystemError()); - } return 0; } @@ -580,9 +560,8 @@ { struct stat st; - if (::stat(duk::require<std::string>(ctx, 0).c_str(), &st) < 0) { + if (::stat(duk::require<std::string>(ctx, 0).c_str(), &st) < 0) duk::raise(ctx, SystemError()); - } duk::push(ctx, st);
--- a/lib/irccd/mod-file.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/mod-file.hpp Tue May 24 13:00:35 2016 +0200 @@ -189,12 +189,12 @@ /** * Irccd.File. */ - FileModule() noexcept; + IRCCD_EXPORT FileModule() noexcept; /** * \copydoc Module::load */ - void load(Irccd &irccd, JsPlugin &plugin) override; + IRCCD_EXPORT void load(Irccd &irccd, JsPlugin &plugin) override; }; } // !irccd
--- a/lib/irccd/mod-irccd.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/mod-irccd.hpp Tue May 24 13:00:35 2016 +0200 @@ -47,7 +47,7 @@ /** * Create a system error from the current errno value. */ - SystemError(); + IRCCD_EXPORT SystemError(); /** * Create a system error with the given errno and message. @@ -55,14 +55,14 @@ * \param e the errno number * \param message the message */ - SystemError(int e, std::string message); + IRCCD_EXPORT SystemError(int e, std::string message); /** * Raise the SystemError. * * \param ctx the context */ - void raise(duk::ContextPtr ctx) const; + IRCCD_EXPORT void raise(duk::ContextPtr ctx) const; }; /** @@ -73,12 +73,12 @@ /** * Irccd. */ - IrccdModule() noexcept; + IRCCD_EXPORT IrccdModule() noexcept; /** * \copydoc Module::load */ - void load(Irccd &irccd, JsPlugin &plugin) override; + IRCCD_EXPORT void load(Irccd &irccd, JsPlugin &plugin) override; }; } // !irccd
--- a/lib/irccd/mod-logger.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/mod-logger.hpp Tue May 24 13:00:35 2016 +0200 @@ -36,12 +36,12 @@ /** * Irccd.Logger. */ - LoggerModule() noexcept; + IRCCD_EXPORT LoggerModule() noexcept; /** * \copydoc Module::load */ - void load(Irccd &irccd, JsPlugin &plugin) override; + IRCCD_EXPORT void load(Irccd &irccd, JsPlugin &plugin) override; }; } // !irccd
--- a/lib/irccd/mod-plugin.cpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/mod-plugin.cpp Tue May 24 13:00:35 2016 +0200 @@ -71,15 +71,13 @@ { Plugin *plugin = nullptr; - if (duk::top(ctx) >= 1) { + if (duk::top(ctx) >= 1) plugin = duk::getGlobal<duk::RawPointer<Irccd>>(ctx, "\xff""\xff""irccd")->pluginService().get(duk::require<std::string>(ctx, 0)).get(); - } else { + else plugin = duk::getGlobal<duk::RawPointer<Plugin>>(ctx, "\xff""\xff""plugin"); - } - if (!plugin) { + if (!plugin) return 0; - } duk::push(ctx, duk::Object{}); duk::putProperty(ctx, -1, "name", plugin->name()); @@ -105,9 +103,8 @@ duk::push(ctx, duk::Array{}); int i = 0; - for (const auto &plugin : duk::getGlobal<duk::RawPointer<Irccd>>(ctx, "\xff""\xff""irccd")->pluginService().plugins()) { + for (const auto &plugin : duk::getGlobal<duk::RawPointer<Irccd>>(ctx, "\xff""\xff""irccd")->pluginService().plugins()) duk::putProperty(ctx, -1, i++, plugin->name()); - } return 1; }
--- a/lib/irccd/mod-plugin.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/mod-plugin.hpp Tue May 24 13:00:35 2016 +0200 @@ -36,12 +36,12 @@ /** * Irccd.Plugin. */ - PluginModule() noexcept; + IRCCD_EXPORT PluginModule() noexcept; /** * \copydoc Module::load */ - virtual void load(Irccd &irccd, JsPlugin &plugin); + IRCCD_EXPORT virtual void load(Irccd &irccd, JsPlugin &plugin); }; } // !irccd
--- a/lib/irccd/mod-server.cpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/mod-server.cpp Tue May 24 13:00:35 2016 +0200 @@ -91,13 +91,12 @@ duk::putProperty(ctx, -1, "nickname", server->identity().nickname); duk::putProperty(ctx, -1, "username", server->identity().username); - /* Channels */ + // Channels. duk::push(ctx, duk::Array{}); int i = 0; - for (const auto &channel : server->settings().channels) { + for (const auto &channel : server->settings().channels) duk::putProperty(ctx, -1, i++, channel.name); - } duk::putProperty(ctx, -2, "channels"); @@ -390,19 +389,16 @@ identity.ctcpversion = duk::optionalProperty<std::string>(ctx, 0, "version", identity.ctcpversion); // Settings part. - for (const auto &chan: duk::getProperty<std::vector<std::string>>(ctx, 0, "channels")) { + for (const auto &chan: duk::getProperty<std::vector<std::string>>(ctx, 0, "channels")) settings.channels.push_back(Server::splitChannel(chan)); - } settings.reconnectTries = duk::optionalProperty<int>(ctx, 0, "recoTries", (int)settings.reconnectTries); settings.reconnectDelay = duk::optionalProperty<int>(ctx, 0, "recoTimeout", (int)settings.reconnectDelay); - if (duk::optionalProperty<bool>(ctx, 0, "joinInvite", false)) { + if (duk::optionalProperty<bool>(ctx, 0, "joinInvite", false)) settings.flags |= ServerSettings::JoinInvite; - } - if (duk::optionalProperty<bool>(ctx, 0, "autoRejoin", false)) { + if (duk::optionalProperty<bool>(ctx, 0, "autoRejoin", false)) settings.flags |= ServerSettings::AutoRejoin; - } try { duk::construct(ctx, duk::Shared<Server>{std::make_shared<Server>(std::move(name), std::move(info), @@ -427,9 +423,8 @@ { auto server = duk::get<duk::Shared<Server>>(ctx, 0); - if (server) { + if (server) duk::getGlobal<duk::RawPointer<Irccd>>(ctx, "\xff""\xff""irccd")->serverService().add(server); - } return 0; } @@ -472,9 +467,8 @@ { duk::push(ctx, duk::Object{}); - for (const auto &server : duk::getGlobal<duk::RawPointer<Irccd>>(ctx, "\xff""\xff""irccd")->serverService().servers()) { + for (const auto &server : duk::getGlobal<duk::RawPointer<Irccd>>(ctx, "\xff""\xff""irccd")->serverService().servers()) duk::putProperty(ctx, -1, server->name(), duk::Shared<Server>{server}); - } return 1; }
--- a/lib/irccd/mod-server.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/mod-server.hpp Tue May 24 13:00:35 2016 +0200 @@ -83,12 +83,12 @@ /** * Irccd.Server. */ - ServerModule() noexcept; + IRCCD_EXPORT ServerModule() noexcept; /** * \copydoc Module::load */ - void load(Irccd &irccd, JsPlugin &plugin) override; + IRCCD_EXPORT void load(Irccd &irccd, JsPlugin &plugin) override; }; } // !irccd
--- a/lib/irccd/mod-system.cpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/mod-system.cpp Tue May 24 13:00:35 2016 +0200 @@ -122,9 +122,8 @@ { auto fp = ::popen(duk::require<const char *>(ctx, 0), duk::require<const char *>(ctx, 1)); - if (fp == nullptr) { + if (fp == nullptr) duk::raise(ctx, SystemError{}); - } duk::push(ctx, duk::Pointer<File>{new File(fp, [] (std::FILE *fp) { ::pclose(fp); })});
--- a/lib/irccd/mod-system.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/mod-system.hpp Tue May 24 13:00:35 2016 +0200 @@ -36,12 +36,12 @@ /** * Irccd.System. */ - SystemModule() noexcept; + IRCCD_EXPORT SystemModule() noexcept; /** * \copydoc Module::load */ - void load(Irccd &irccd, JsPlugin &plugin) override; + IRCCD_EXPORT void load(Irccd &irccd, JsPlugin &plugin) override; }; } // !irccd
--- a/lib/irccd/mod-timer.cpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/mod-timer.cpp Tue May 24 13:00:35 2016 +0200 @@ -54,9 +54,8 @@ { auto plugin = ptr.lock(); - if (!plugin) { + if (!plugin) return; - } auto irccd = duk::getGlobal<duk::RawPointer<Irccd>>(plugin->context(), "\xff""\xff""irccd"); @@ -68,14 +67,12 @@ duk::remove(plugin->context(), -2); if (duk::is<duk::Function>(plugin->context(), -1)) { - if (duk::pcall(plugin->context()) != 0) { + if (duk::pcall(plugin->context()) != 0) log::warning("plugin {}: {}"_format(plugin->name(), duk::error(plugin->context(), -1).stack)); - } duk::pop(plugin->context()); - } else { + } else duk::pop(plugin->context()); - } }); } @@ -89,9 +86,8 @@ { auto timer = duk::self<duk::Shared<Timer>>(ctx); - if (!timer->isRunning()) { + if (!timer->isRunning()) timer->start(); - } return 0; } @@ -106,9 +102,8 @@ { auto timer = duk::self<duk::Shared<Timer>>(ctx); - if (timer->isRunning()) { + if (timer->isRunning()) timer->stop(); - } return 0; } @@ -135,15 +130,12 @@ 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)) { + if (type < static_cast<int>(TimerType::Single) || type > static_cast<int>(TimerType::Repeat)) duk::raise(ctx, DUK_ERR_TYPE_ERROR, "invalid timer type"); - } - if (delay < 0) { + if (delay < 0) duk::raise(ctx, DUK_ERR_TYPE_ERROR, "negative delay given"); - } - if (!duk::is<duk::Function>(ctx, 2)) { + if (!duk::is<duk::Function>(ctx, 2)) duk::raise(ctx, DUK_ERR_TYPE_ERROR, "missing callback function"); - } // Construct the timer in 'this'. auto timer = std::make_shared<Timer>(static_cast<TimerType>(type), delay);
--- a/lib/irccd/mod-timer.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/mod-timer.hpp Tue May 24 13:00:35 2016 +0200 @@ -36,12 +36,12 @@ /** * Irccd.Timer. */ - TimerModule() noexcept; + IRCCD_EXPORT TimerModule() noexcept; /** * \copydoc Module::load */ - void load(Irccd &irccd, JsPlugin &plugin) override; + IRCCD_EXPORT void load(Irccd &irccd, JsPlugin &plugin) override; }; } // !irccd
--- a/lib/irccd/mod-unicode.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/mod-unicode.hpp Tue May 24 13:00:35 2016 +0200 @@ -36,12 +36,12 @@ /** * Irccd.Unicode. */ - UnicodeModule() noexcept; + IRCCD_EXPORT UnicodeModule() noexcept; /** * \copydoc Module::load */ - void load(Irccd &irccd, JsPlugin &plugin) override; + IRCCD_EXPORT void load(Irccd &irccd, JsPlugin &plugin) override; }; } // !irccd
--- a/lib/irccd/mod-util.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/mod-util.hpp Tue May 24 13:00:35 2016 +0200 @@ -36,12 +36,12 @@ /** * Irccd.Util. */ - UtilModule() noexcept; + IRCCD_EXPORT UtilModule() noexcept; /** * \copydoc Module::load */ - void load(Irccd &irccd, JsPlugin &plugin) override; + IRCCD_EXPORT void load(Irccd &irccd, JsPlugin &plugin) override; }; } // !irccd
--- a/lib/irccd/module.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/module.hpp Tue May 24 13:00:35 2016 +0200 @@ -1,95 +1,96 @@ -/* - * module.hpp -- JavaScript API module - * - * Copyright (c) 2013-2016 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_MODULE_HPP -#define IRCCD_MODULE_HPP - -/** - * \file module.hpp - * \brief JavaScript API module. - */ - -#include <cassert> - -#include "util.hpp" - -namespace irccd { - -class Irccd; -class JsPlugin; - -/** - * \brief JavaScript API module. - */ -class Module { -private: - std::string m_name; - -public: - /** - * Default constructor. - * - * \pre !name.empty() - */ - inline Module(std::string name) noexcept - : m_name(std::move(name)) - { - assert(!m_name.empty()); - } - - /** - * Virtual destructor defaulted. - */ - virtual ~Module() = default; - - /** - * Get the module name. - * - * \return the name - */ - inline const std::string &name() const noexcept - { - return m_name; - } - - /** - * Load the module into the JavaScript plugin. - * - * \param irccd the irccd instance - * \param plugin the plugin - */ - virtual void load(Irccd &irccd, JsPlugin &plugin) - { - util::unused(irccd, plugin); - } - - /** - * Unload the module from the JavaScript plugin. - * - * \param irccd the irccd instance - * \param plugin the plugin - */ - virtual void unload(Irccd &irccd, JsPlugin &plugin) - { - util::unused(irccd, plugin); - } -}; - -} // !irccd - -#endif // !IRCCD_MODULE_HPP +/* + * module.hpp -- JavaScript API module + * + * Copyright (c) 2013-2016 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_MODULE_HPP +#define IRCCD_MODULE_HPP + +/** + * \file module.hpp + * \brief JavaScript API module. + */ + +#include <cassert> + +#include "sysconfig.hpp" +#include "util.hpp" + +namespace irccd { + +class Irccd; +class JsPlugin; + +/** + * \brief JavaScript API module. + */ +class Module { +private: + std::string m_name; + +public: + /** + * Default constructor. + * + * \pre !name.empty() + */ + inline Module(std::string name) noexcept + : m_name(std::move(name)) + { + assert(!m_name.empty()); + } + + /** + * Virtual destructor defaulted. + */ + virtual ~Module() = default; + + /** + * Get the module name. + * + * \return the name + */ + inline const std::string &name() const noexcept + { + return m_name; + } + + /** + * Load the module into the JavaScript plugin. + * + * \param irccd the irccd instance + * \param plugin the plugin + */ + virtual void load(Irccd &irccd, JsPlugin &plugin) + { + util::unused(irccd, plugin); + } + + /** + * Unload the module from the JavaScript plugin. + * + * \param irccd the irccd instance + * \param plugin the plugin + */ + virtual void unload(Irccd &irccd, JsPlugin &plugin) + { + util::unused(irccd, plugin); + } +}; + +} // !irccd + +#endif // !IRCCD_MODULE_HPP
--- a/lib/irccd/options.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/options.hpp Tue May 24 13:00:35 2016 +0200 @@ -30,6 +30,8 @@ #include <utility> #include <vector> +#include "sysconfig.hpp" + namespace irccd { /** @@ -128,7 +130,7 @@ * \throw MissingValue * \throw InvalidOption */ -Result read(std::vector<std::string> &args, const Options &definition); +IRCCD_EXPORT Result read(std::vector<std::string> &args, const Options &definition); /** * Overloaded function for usage with main() arguments. @@ -141,7 +143,7 @@ * \throw MissingValue * \throw InvalidOption */ -Result read(int &argc, char **&argv, const Options &definition); +IRCCD_EXPORT Result read(int &argc, char **&argv, const Options &definition); } // !parser
--- a/lib/irccd/path.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/path.hpp Tue May 24 13:00:35 2016 +0200 @@ -27,6 +27,8 @@ #include <string> #include <vector> +#include "sysconfig.hpp" + namespace irccd { namespace path { @@ -64,7 +66,7 @@ * * \param argv0 the path to the executable (argv[0]) */ -void setApplicationPath(const std::string &argv0); +IRCCD_EXPORT void setApplicationPath(const std::string &argv0); /** * Clean a path by removing any extra / or \ and add a trailing one. @@ -72,7 +74,7 @@ * \param path the path * \return the updated path */ -std::string clean(std::string path); +IRCCD_EXPORT std::string clean(std::string path); /** * Generic function for path retrievement. @@ -84,7 +86,7 @@ * \param owner system or user wide * \return the path */ -std::string get(Path path, Owner owner); +IRCCD_EXPORT std::string get(Path path, Owner owner); /** * Generic function for multiple paths. @@ -95,7 +97,7 @@ * \param path the type of path * \return the list of preferred directories in order */ -std::vector<std::string> list(Path path); +IRCCD_EXPORT std::vector<std::string> list(Path path); } // !path
--- a/lib/irccd/plugin-dynlib.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/plugin-dynlib.hpp Tue May 24 13:00:35 2016 +0200 @@ -93,120 +93,120 @@ /** * \copydoc Plugin::onCommand */ - void onCommand(Irccd &irccd, - const std::shared_ptr<Server> &server, - const std::string &origin, - const std::string &channel, - const std::string &message) override; + IRCCD_EXPORT void onCommand(Irccd &irccd, + const std::shared_ptr<Server> &server, + const std::string &origin, + const std::string &channel, + const std::string &message) override; /** * \copydoc Plugin::onConnect */ - void onConnect(Irccd &irccd, const std::shared_ptr<Server> &server) override; + IRCCD_EXPORT void onConnect(Irccd &irccd, const std::shared_ptr<Server> &server) override; /** * \copydoc Plugin::onChannelMode */ - void onChannelMode(Irccd &irccd, - const std::shared_ptr<Server> &server, - const std::string &origin, - const std::string &channel, - const std::string &mode, - const std::string &arg) override; + IRCCD_EXPORT void onChannelMode(Irccd &irccd, + const std::shared_ptr<Server> &server, + const std::string &origin, + const std::string &channel, + const std::string &mode, + const std::string &arg) override; /** * \copydoc Plugin::onChannelNotice */ - void onChannelNotice(Irccd &irccd, - const std::shared_ptr<Server> &server, - const std::string &origin, - const std::string &channel, - const std::string ¬ice) override; + IRCCD_EXPORT void onChannelNotice(Irccd &irccd, + const std::shared_ptr<Server> &server, + const std::string &origin, + const std::string &channel, + const std::string ¬ice) override; /** * \copydoc Plugin::onInvite */ - void onInvite(Irccd &irccd, const std::shared_ptr<Server> &server, const std::string &origin, const std::string &channel) override; + IRCCD_EXPORT void onInvite(Irccd &irccd, const std::shared_ptr<Server> &server, const std::string &origin, const std::string &channel) override; /** * \copydoc Plugin::onJoin */ - void onJoin(Irccd &irccd, const std::shared_ptr<Server> &server, const std::string &origin, const std::string &channel) override; + IRCCD_EXPORT void onJoin(Irccd &irccd, const std::shared_ptr<Server> &server, const std::string &origin, const std::string &channel) override; /** * \copydoc Plugin::onKick */ - void onKick(Irccd &irccd, - const std::shared_ptr<Server> &server, - const std::string &origin, - const std::string &channel, - const std::string &target, - const std::string &reason) override; + IRCCD_EXPORT void onKick(Irccd &irccd, + const std::shared_ptr<Server> &server, + const std::string &origin, + const std::string &channel, + const std::string &target, + const std::string &reason) override; /** * \copydoc Plugin::onLoad */ - void onLoad(Irccd &irccd) override; + IRCCD_EXPORT void onLoad(Irccd &irccd) override; /** * \copydoc Plugin::onMessage */ - void onMessage(Irccd &irccd, - const std::shared_ptr<Server> &server, - const std::string &origin, - const std::string &channel, - const std::string &message) override; + IRCCD_EXPORT void onMessage(Irccd &irccd, + const std::shared_ptr<Server> &server, + const std::string &origin, + const std::string &channel, + const std::string &message) override; /** * \copydoc Plugin::onMe */ - void onMe(Irccd &irccd, - const std::shared_ptr<Server> &server, - const std::string &origin, - const std::string &channel, - const std::string &message) override; + IRCCD_EXPORT void onMe(Irccd &irccd, + const std::shared_ptr<Server> &server, + const std::string &origin, + const std::string &channel, + const std::string &message) override; /** * \copydoc Plugin::onMode */ - void onMode(Irccd &irccd, const std::shared_ptr<Server> &server, const std::string &origin, const std::string &mode) override; + IRCCD_EXPORT void onMode(Irccd &irccd, const std::shared_ptr<Server> &server, const std::string &origin, const std::string &mode) override; /** * \copydoc Plugin::onNames */ - void onNames(Irccd &irccd, - const std::shared_ptr<Server> &server, - const std::string &channel, - const std::vector<std::string> &list) override; + IRCCD_EXPORT void onNames(Irccd &irccd, + const std::shared_ptr<Server> &server, + const std::string &channel, + const std::vector<std::string> &list) override; /** * \copydoc Plugin::onNick */ - void onNick(Irccd &irccd, const std::shared_ptr<Server> &server, const std::string &origin, const std::string &nick) override; + IRCCD_EXPORT void onNick(Irccd &irccd, const std::shared_ptr<Server> &server, const std::string &origin, const std::string &nick) override; /** * \copydoc Plugin::onNotice */ - void onNotice(Irccd &irccd, const std::shared_ptr<Server> &server, const std::string &origin, const std::string ¬ice) override; + IRCCD_EXPORT void onNotice(Irccd &irccd, const std::shared_ptr<Server> &server, const std::string &origin, const std::string ¬ice) override; /** * \copydoc Plugin::onPart */ - void onPart(Irccd &irccd, - const std::shared_ptr<Server> &server, - const std::string &origin, - const std::string &channel, - const std::string &reason) override; + IRCCD_EXPORT void onPart(Irccd &irccd, + const std::shared_ptr<Server> &server, + const std::string &origin, + const std::string &channel, + const std::string &reason) override; /** * \copydoc Plugin::onQuery */ - void onQuery(Irccd &irccd, const std::shared_ptr<Server> &server, const std::string &origin, const std::string &message) override; + IRCCD_EXPORT void onQuery(Irccd &irccd, const std::shared_ptr<Server> &server, const std::string &origin, const std::string &message) override; /** * \copydoc Plugin::onQueryCommand */ - void onQueryCommand(Irccd &irccd, + IRCCD_EXPORT void onQueryCommand(Irccd &irccd, const std::shared_ptr<Server> &server, const std::string &origin, const std::string &message) override; @@ -214,26 +214,26 @@ /** * \copydoc Plugin::onReload */ - void onReload(Irccd &irccd) override; + IRCCD_EXPORT void onReload(Irccd &irccd) override; /** * \copydoc Plugin::onTopic */ - void onTopic(Irccd &irccd, - const std::shared_ptr<Server> &server, - const std::string &origin, - const std::string &channel, - const std::string &topic) override; + IRCCD_EXPORT void onTopic(Irccd &irccd, + const std::shared_ptr<Server> &server, + const std::string &origin, + const std::string &channel, + const std::string &topic) override; /** * \copydoc Plugin::onUnload */ - void onUnload(Irccd &irccd) override; + IRCCD_EXPORT void onUnload(Irccd &irccd) override; /** * \copydoc Plugin::onWhois */ - void onWhois(Irccd &irccd, const std::shared_ptr<Server> &server, const ServerWhois &info) override; + IRCCD_EXPORT void onWhois(Irccd &irccd, const std::shared_ptr<Server> &server, const ServerWhois &info) override; }; } // !irccd
--- a/lib/irccd/plugin-js.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/plugin-js.hpp Tue May 24 13:00:35 2016 +0200 @@ -60,7 +60,7 @@ * \param path the path to the plugin * \param config the configuration */ - JsPlugin(std::string name, std::string path, const PluginConfig &config = PluginConfig()); + IRCCD_EXPORT JsPlugin(std::string name, std::string path, const PluginConfig &config = PluginConfig()); /** * Access the Duktape context. @@ -73,149 +73,149 @@ } /** - * \copydoc Plugin::onCommand - */ - void onCommand(Irccd &irccd, - const std::shared_ptr<Server> &server, - const std::string &origin, - const std::string &channel, - const std::string &message) override; + * \copydoc Plugin::onCommand + */ + IRCCD_EXPORT void onCommand(Irccd &irccd, + const std::shared_ptr<Server> &server, + const std::string &origin, + const std::string &channel, + const std::string &message) override; /** - * \copydoc Plugin::onConnect - */ - void onConnect(Irccd &irccd, const std::shared_ptr<Server> &server) override; + * \copydoc Plugin::onConnect + */ + IRCCD_EXPORT void onConnect(Irccd &irccd, const std::shared_ptr<Server> &server) override; /** - * \copydoc Plugin::onChannelMode - */ - void onChannelMode(Irccd &irccd, - const std::shared_ptr<Server> &server, - const std::string &origin, - const std::string &channel, - const std::string &mode, - const std::string &arg) override; + * \copydoc Plugin::onChannelMode + */ + IRCCD_EXPORT void onChannelMode(Irccd &irccd, + const std::shared_ptr<Server> &server, + const std::string &origin, + const std::string &channel, + const std::string &mode, + const std::string &arg) override; /** - * \copydoc Plugin::onChannelNotice - */ - void onChannelNotice(Irccd &irccd, - const std::shared_ptr<Server> &server, - const std::string &origin, - const std::string &channel, - const std::string ¬ice) override; + * \copydoc Plugin::onChannelNotice + */ + IRCCD_EXPORT void onChannelNotice(Irccd &irccd, + const std::shared_ptr<Server> &server, + const std::string &origin, + const std::string &channel, + const std::string ¬ice) override; /** - * \copydoc Plugin::onInvite - */ - void onInvite(Irccd &irccd, const std::shared_ptr<Server> &server, const std::string &origin, const std::string &channel) override; + * \copydoc Plugin::onInvite + */ + IRCCD_EXPORT void onInvite(Irccd &irccd, const std::shared_ptr<Server> &server, const std::string &origin, const std::string &channel) override; /** - * \copydoc Plugin::onJoin - */ - void onJoin(Irccd &irccd, const std::shared_ptr<Server> &server, const std::string &origin, const std::string &channel) override; + * \copydoc Plugin::onJoin + */ + IRCCD_EXPORT void onJoin(Irccd &irccd, const std::shared_ptr<Server> &server, const std::string &origin, const std::string &channel) override; /** - * \copydoc Plugin::onKick - */ - void onKick(Irccd &irccd, - const std::shared_ptr<Server> &server, - const std::string &origin, - const std::string &channel, - const std::string &target, - const std::string &reason) override; + * \copydoc Plugin::onKick + */ + IRCCD_EXPORT void onKick(Irccd &irccd, + const std::shared_ptr<Server> &server, + const std::string &origin, + const std::string &channel, + const std::string &target, + const std::string &reason) override; /** - * \copydoc Plugin::onLoad - */ - void onLoad(Irccd &irccd) override; + * \copydoc Plugin::onLoad + */ + IRCCD_EXPORT void onLoad(Irccd &irccd) override; /** - * \copydoc Plugin::onMessage - */ - void onMessage(Irccd &irccd, - const std::shared_ptr<Server> &server, - const std::string &origin, - const std::string &channel, - const std::string &message) override; + * \copydoc Plugin::onMessage + */ + IRCCD_EXPORT void onMessage(Irccd &irccd, + const std::shared_ptr<Server> &server, + const std::string &origin, + const std::string &channel, + const std::string &message) override; /** - * \copydoc Plugin::onMe - */ - void onMe(Irccd &irccd, - const std::shared_ptr<Server> &server, - const std::string &origin, - const std::string &channel, - const std::string &message) override; + * \copydoc Plugin::onMe + */ + IRCCD_EXPORT void onMe(Irccd &irccd, + const std::shared_ptr<Server> &server, + const std::string &origin, + const std::string &channel, + const std::string &message) override; /** - * \copydoc Plugin::onMode - */ - void onMode(Irccd &irccd, const std::shared_ptr<Server> &server, const std::string &origin, const std::string &mode) override; + * \copydoc Plugin::onMode + */ + IRCCD_EXPORT void onMode(Irccd &irccd, const std::shared_ptr<Server> &server, const std::string &origin, const std::string &mode) override; /** - * \copydoc Plugin::onNames - */ - void onNames(Irccd &irccd, - const std::shared_ptr<Server> &server, - const std::string &channel, - const std::vector<std::string> &list) override; + * \copydoc Plugin::onNames + */ + IRCCD_EXPORT void onNames(Irccd &irccd, + const std::shared_ptr<Server> &server, + const std::string &channel, + const std::vector<std::string> &list) override; /** - * \copydoc Plugin::onNick - */ - void onNick(Irccd &irccd, const std::shared_ptr<Server> &server, const std::string &origin, const std::string &nick) override; + * \copydoc Plugin::onNick + */ + IRCCD_EXPORT void onNick(Irccd &irccd, const std::shared_ptr<Server> &server, const std::string &origin, const std::string &nick) override; /** - * \copydoc Plugin::onNotice - */ - void onNotice(Irccd &irccd, const std::shared_ptr<Server> &server, const std::string &origin, const std::string ¬ice) override; + * \copydoc Plugin::onNotice + */ + IRCCD_EXPORT void onNotice(Irccd &irccd, const std::shared_ptr<Server> &server, const std::string &origin, const std::string ¬ice) override; /** - * \copydoc Plugin::onPart - */ - void onPart(Irccd &irccd, - const std::shared_ptr<Server> &server, - const std::string &origin, - const std::string &channel, - const std::string &reason) override; + * \copydoc Plugin::onPart + */ + IRCCD_EXPORT void onPart(Irccd &irccd, + const std::shared_ptr<Server> &server, + const std::string &origin, + const std::string &channel, + const std::string &reason) override; /** - * \copydoc Plugin::onQuery - */ - void onQuery(Irccd &irccd, const std::shared_ptr<Server> &server, const std::string &origin, const std::string &message) override; + * \copydoc Plugin::onQuery + */ + IRCCD_EXPORT void onQuery(Irccd &irccd, const std::shared_ptr<Server> &server, const std::string &origin, const std::string &message) override; /** - * \copydoc Plugin::onQueryCommand - */ - void onQueryCommand(Irccd &irccd, - const std::shared_ptr<Server> &server, - const std::string &origin, - const std::string &message) override; + * \copydoc Plugin::onQueryCommand + */ + IRCCD_EXPORT void onQueryCommand(Irccd &irccd, + const std::shared_ptr<Server> &server, + const std::string &origin, + const std::string &message) override; /** - * \copydoc Plugin::onReload - */ - void onReload(Irccd &irccd) override; + * \copydoc Plugin::onReload + */ + IRCCD_EXPORT void onReload(Irccd &irccd) override; /** - * \copydoc Plugin::onTopic - */ - void onTopic(Irccd &irccd, - const std::shared_ptr<Server> &server, - const std::string &origin, - const std::string &channel, - const std::string &topic) override; + * \copydoc Plugin::onTopic + */ + IRCCD_EXPORT void onTopic(Irccd &irccd, + const std::shared_ptr<Server> &server, + const std::string &origin, + const std::string &channel, + const std::string &topic) override; /** - * \copydoc Plugin::onUnload - */ - void onUnload(Irccd &irccd) override; + * \copydoc Plugin::onUnload + */ + IRCCD_EXPORT void onUnload(Irccd &irccd) override; /** - * \copydoc Plugin::onWhois - */ - void onWhois(Irccd &irccd, const std::shared_ptr<Server> &server, const ServerWhois &info) override; + * \copydoc Plugin::onWhois + */ + IRCCD_EXPORT void onWhois(Irccd &irccd, const std::shared_ptr<Server> &server, const ServerWhois &info) override; }; } // !irccd
--- a/lib/irccd/plugin.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/plugin.hpp Tue May 24 13:00:35 2016 +0200 @@ -29,6 +29,7 @@ #include <unordered_map> #include <vector> +#include "sysconfig.hpp" #include "util.hpp" namespace irccd {
--- a/lib/irccd/rule.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/rule.hpp Tue May 24 13:00:35 2016 +0200 @@ -30,6 +30,8 @@ #include <utility> #include <vector> +#include "sysconfig.hpp" + namespace irccd { /** @@ -77,12 +79,12 @@ * \param action the rule action * \throw std::invalid_argument if events are invalid */ - Rule(RuleSet servers = RuleSet{}, - RuleSet channels = RuleSet{}, - RuleSet nicknames = RuleSet{}, - RuleSet plugins = RuleSet{}, - RuleSet events = RuleSet{}, - RuleAction action = RuleAction::Accept); + IRCCD_EXPORT Rule(RuleSet servers = RuleSet{}, + RuleSet channels = RuleSet{}, + RuleSet nicknames = RuleSet{}, + RuleSet plugins = RuleSet{}, + RuleSet events = RuleSet{}, + RuleAction action = RuleAction::Accept); /** * Check if that rule apply for the given criterias. @@ -94,53 +96,53 @@ * \param event the event * \return true if match */ - bool match(const std::string &server, - const std::string &channel, - const std::string &nick, - const std::string &plugin, - const std::string &event) const noexcept; + 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; /** * Get the action. * * \return the action */ - RuleAction action() const noexcept; + IRCCD_EXPORT RuleAction action() const noexcept; /** * Get the servers. * * \return the servers */ - const RuleSet &servers() const noexcept; + IRCCD_EXPORT const RuleSet &servers() const noexcept; /** * Get the channels. * * \return the channels */ - const RuleSet &channels() const noexcept; + IRCCD_EXPORT const RuleSet &channels() const noexcept; /** * Get the origins. * * \return the origins */ - const RuleSet &origins() const noexcept; + IRCCD_EXPORT const RuleSet &origins() const noexcept; /** * Get the plugins. * * \return the plugins */ - const RuleSet &plugins() const noexcept; + IRCCD_EXPORT const RuleSet &plugins() const noexcept; /** * Get the events. * * \return the events */ - const RuleSet &events() const noexcept; + IRCCD_EXPORT const RuleSet &events() const noexcept; }; } // !irccd
--- a/lib/irccd/server-event.cpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/server-event.cpp Tue May 24 13:00:35 2016 +0200 @@ -28,41 +28,39 @@ ServerEvent::ServerEvent(std::string server, std::string origin, std::string target, - std::function<std::string (Plugin &)> plugin_function_name, - std::function<void (Plugin &)> plugin_exec) + std::function<std::string (Plugin &)> functionName, + std::function<void (Plugin &)> exec) : m_server(std::move(server)) , m_origin(std::move(origin)) , m_target(std::move(target)) - , m_plugin_function_name(std::move(plugin_function_name)) - , m_plugin_exec(std::move(plugin_exec)) + , m_functionName(std::move(functionName)) + , m_exec(std::move(exec)) { } void ServerEvent::operator()(Irccd &irccd) const { for (auto &plugin : irccd.pluginService().plugins()) { - auto eventname = m_plugin_function_name(*plugin); + auto eventname = m_functionName(*plugin); auto allowed = irccd.ruleService().solve(m_server, m_target, m_origin, plugin->name(), eventname); if (!allowed) { log::debug() << "rule: event skipped on match" << std::endl; continue; - } else { + } else log::debug() << "rule: event allowed" << std::endl; - } - // TODO: server-event must not know which type of plugin + // TODO: server-event must not know which type of plugin. + // TODO: get generic error. try { - m_plugin_exec(*plugin); + m_exec(*plugin); } catch (const duk::ErrorInfo &info) { log::warning() << "plugin " << plugin->name() << ": error: " << info.what() << std::endl; - if (!info.fileName.empty()) { + if (!info.fileName.empty()) log::warning() << " " << info.fileName << ":" << info.lineNumber << std::endl; - } - if (!info.stack.empty()) { + if (!info.stack.empty()) log::warning() << " " << info.stack << std::endl; - } } } }
--- a/lib/irccd/server-event.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/server-event.hpp Tue May 24 13:00:35 2016 +0200 @@ -47,8 +47,8 @@ std::string m_server; std::string m_origin; std::string m_target; - std::function<std::string (Plugin &)> m_plugin_function_name; - std::function<void (Plugin &)> m_plugin_exec; + std::function<std::string (Plugin &)> m_functionName; + std::function<void (Plugin &)> m_exec; public: /** @@ -57,21 +57,21 @@ * \param server the server name * \param origin the origin * \param target the target (channel or nickname) - * \param plugin_function_name the JavaScript function to call (only for rules) - * \param plugin_exec the plugin executor + * \param functionName the function to call (only for rules) + * \param exec the plugin executor */ - ServerEvent(std::string server, - std::string origin, - std::string target, - std::function<std::string (Plugin &)> plugin_function_name, - std::function<void (Plugin &)> plugin_exec); + IRCCD_EXPORT ServerEvent(std::string server, + std::string origin, + std::string target, + std::function<std::string (Plugin &)> functionName, + std::function<void (Plugin &)> exec); /** * Execute the event. * * \param irccd the irccd instance */ - void operator()(Irccd &irccd) const; + IRCCD_EXPORT void operator()(Irccd &irccd) const; }; } // !irccd
--- a/lib/irccd/server-state-connected.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/server-state-connected.hpp Tue May 24 13:00:35 2016 +0200 @@ -38,12 +38,12 @@ /** * \copydoc ServerState::prepare */ - void prepare(Server &server, fd_set &setinput, fd_set &setoutput, net::Handle &maxfd) override; + IRCCD_EXPORT void prepare(Server &server, fd_set &setinput, fd_set &setoutput, net::Handle &maxfd) override; /** * \copydoc ServerState::ident */ - std::string ident() const override; + IRCCD_EXPORT std::string ident() const override; }; } // !state
--- a/lib/irccd/server-state-connecting.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/server-state-connecting.hpp Tue May 24 13:00:35 2016 +0200 @@ -43,12 +43,12 @@ /** * \copydoc ServerState::prepare */ - void prepare(Server &server, fd_set &setinput, fd_set &setoutput, net::Handle &maxfd) override; + IRCCD_EXPORT void prepare(Server &server, fd_set &setinput, fd_set &setoutput, net::Handle &maxfd) override; /** * \copydoc ServerState::ident */ - std::string ident() const override; + IRCCD_EXPORT std::string ident() const override; }; } // !state
--- a/lib/irccd/server-state-disconnected.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/server-state-disconnected.hpp Tue May 24 13:00:35 2016 +0200 @@ -42,12 +42,12 @@ /** * \copydoc ServerState::prepare */ - void prepare(Server &server, fd_set &setinput, fd_set &setoutput, net::Handle &maxfd) override; + IRCCD_EXPORT void prepare(Server &server, fd_set &setinput, fd_set &setoutput, net::Handle &maxfd) override; /** * \copydoc ServerState::ident */ - std::string ident() const override; + IRCCD_EXPORT std::string ident() const override; }; } // !state
--- a/lib/irccd/server.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/server.hpp Tue May 24 13:00:35 2016 +0200 @@ -38,6 +38,7 @@ #include "elapsed-timer.hpp" #include "server-state.hpp" #include "signals.hpp" +#include "sysconfig.hpp" namespace irccd { @@ -416,7 +417,7 @@ * \param value the value * \return a channel */ - static ServerChannel splitChannel(const std::string &value); + IRCCD_EXPORT static ServerChannel splitChannel(const std::string &value); /** * Construct a server. @@ -426,12 +427,12 @@ * \param identity the identity * \param settings the settings */ - Server(std::string name, ServerInfo info, ServerIdentity identity = {}, ServerSettings settings = {}); + IRCCD_EXPORT Server(std::string name, ServerInfo info, ServerIdentity identity = {}, ServerSettings settings = {}); /** * Destructor. Close the connection if needed. */ - virtual ~Server(); + IRCCD_EXPORT virtual ~Server(); /** * Get the server identifier. @@ -518,17 +519,17 @@ /** * Switch to next state if it has. */ - void update() noexcept; + IRCCD_EXPORT void update() noexcept; /** * Force disconnection. */ - void disconnect() noexcept; + IRCCD_EXPORT void disconnect() noexcept; /** * Asks for a reconnection. */ - void reconnect() noexcept; + IRCCD_EXPORT void reconnect() noexcept; /** * Prepare the IRC session. @@ -547,7 +548,7 @@ * \param setoutput * \throw any exception that have been throw from user functions */ - void sync(fd_set &setinput, fd_set &setoutput); + IRCCD_EXPORT void sync(fd_set &setinput, fd_set &setoutput); /** * Determine if the nickname is the bot itself. @@ -555,7 +556,7 @@ * \param nick the nickname to check * \return true if it is the bot */ - bool isSelf(const std::string &nick) const noexcept; + IRCCD_EXPORT bool isSelf(const std::string &nick) const noexcept; /** * Change the channel mode. @@ -563,7 +564,7 @@ * \param channel the channel * \param mode the new mode */ - virtual void cmode(std::string channel, std::string mode); + IRCCD_EXPORT virtual void cmode(std::string channel, std::string mode); /** * Send a channel notice. @@ -571,7 +572,7 @@ * \param channel the channel * \param message message notice */ - virtual void cnotice(std::string channel, std::string message); + IRCCD_EXPORT virtual void cnotice(std::string channel, std::string message); /** * Invite a user to a channel. @@ -579,7 +580,7 @@ * \param target the target nickname * \param channel the channel */ - virtual void invite(std::string target, std::string channel); + IRCCD_EXPORT virtual void invite(std::string target, std::string channel); /** * Join a channel, the password is optional and can be kept empty. @@ -587,7 +588,7 @@ * \param channel the channel to join * \param password the optional password */ - virtual void join(std::string channel, std::string password = ""); + IRCCD_EXPORT virtual void join(std::string channel, std::string password = ""); /** * Kick someone from the channel. Please be sure to have the rights @@ -597,7 +598,7 @@ * \param channel from which channel * \param reason the optional reason */ - virtual void kick(std::string target, std::string channel, std::string reason = ""); + IRCCD_EXPORT 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 @@ -606,7 +607,7 @@ * \param target the nickname or the channel * \param message the message */ - virtual void me(std::string target, std::string message); + IRCCD_EXPORT virtual void me(std::string target, std::string message); /** * Send a message to the specified target or channel. @@ -614,28 +615,28 @@ * \param target the target * \param message the message */ - virtual void message(std::string target, std::string message); + IRCCD_EXPORT virtual void message(std::string target, std::string message); /** * Change your user mode. * * \param mode the mode */ - virtual void mode(std::string mode); + IRCCD_EXPORT virtual void mode(std::string mode); /** * Request the list of names. * * \param channel the channel */ - virtual void names(std::string channel); + IRCCD_EXPORT virtual void names(std::string channel); /** * Change your nickname. * * \param newnick the new nickname to use */ - virtual void nick(std::string newnick); + IRCCD_EXPORT virtual void nick(std::string newnick); /** * Send a private notice. @@ -643,7 +644,7 @@ * \param target the target * \param message the notice message */ - virtual void notice(std::string target, std::string message); + IRCCD_EXPORT virtual void notice(std::string target, std::string message); /** * Part from a channel. @@ -653,7 +654,7 @@ * \param channel the channel to leave * \param reason the optional reason */ - virtual void part(std::string channel, std::string reason = ""); + IRCCD_EXPORT virtual void part(std::string channel, std::string reason = ""); /** * Send a raw message to the IRC server. You don't need to add @@ -662,7 +663,7 @@ * \warning Use this function with care * \param raw the raw message (without `\r\n\r\n`) */ - virtual void send(std::string raw); + IRCCD_EXPORT virtual void send(std::string raw); /** * Change the channel topic. @@ -670,14 +671,14 @@ * \param channel the channel * \param topic the desired topic */ - virtual void topic(std::string channel, std::string topic); + IRCCD_EXPORT virtual void topic(std::string channel, std::string topic); /** * Request for whois information. * * \param target the target nickname */ - virtual void whois(std::string target); + IRCCD_EXPORT virtual void whois(std::string target); }; } // !irccd
--- a/lib/irccd/service-interrupt.cpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/service-interrupt.cpp Tue May 24 13:00:35 2016 +0200 @@ -38,9 +38,8 @@ { FD_SET(m_in.handle(), &in); - if (m_in.handle() > max) { + if (m_in.handle() > max) max = m_in.handle(); - } } void InterruptService::sync(fd_set &in, fd_set &)
--- a/lib/irccd/service-interrupt.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/service-interrupt.hpp Tue May 24 13:00:35 2016 +0200 @@ -42,22 +42,22 @@ * * \throw std::runtime_error on errors */ - InterruptService(); + IRCCD_EXPORT InterruptService(); /** * \copydoc Service::prepare */ - void prepare(fd_set &in, fd_set &out, net::Handle &max) override; + IRCCD_EXPORT void prepare(fd_set &in, fd_set &out, net::Handle &max) override; /** * \copydoc Service::sync */ - void sync(fd_set &in, fd_set &out) override; + IRCCD_EXPORT void sync(fd_set &in, fd_set &out) override; /** * Request interruption. */ - void interrupt() noexcept; + IRCCD_EXPORT void interrupt() noexcept; }; } // !irccd
--- a/lib/irccd/service-module.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/service-module.hpp Tue May 24 13:00:35 2016 +0200 @@ -42,7 +42,7 @@ /** * Construct the service and predefined irccd API. */ - ModuleService(); + IRCCD_EXPORT ModuleService(); /** * Get all modules. @@ -59,7 +59,7 @@ * * \param name the name */ - bool contains(const std::string &name) const; + IRCCD_EXPORT bool contains(const std::string &name) const; /** * Add a JavaScript API module. @@ -68,7 +68,7 @@ * \pre !contains(module) * \param module the module */ - void add(std::shared_ptr<Module> module); + IRCCD_EXPORT void add(std::shared_ptr<Module> module); }; } // !irccd
--- a/lib/irccd/service-plugin.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/service-plugin.hpp Tue May 24 13:00:35 2016 +0200 @@ -1,166 +1,166 @@ -/* - * service-plugin.hpp -- manage plugins - * - * Copyright (c) 2013-2016 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_SERVICE_PLUGIN_HPP -#define IRCCD_SERVICE_PLUGIN_HPP - -/** - * \file service-plugin.hpp - * \brief Manage plugins. - */ - -#include <unordered_map> -#include <memory> -#include <vector> - -#include "plugin-js.hpp" - -namespace irccd { - -class Irccd; - -/** - * \brief Manage plugins. - */ -class PluginService { -private: - Irccd &m_irccd; - std::vector<std::shared_ptr<Plugin>> m_plugins; - std::unordered_map<std::string, PluginConfig> m_config; - std::unordered_map<std::string, PluginFormats> m_formats; - -public: - /** - * Create the plugin service. - * - * \param irccd the irccd instance - */ - PluginService(Irccd &irccd) noexcept; - - /** - * Destroy plugins. - */ - ~PluginService(); - - /** - * Get the list of plugins. - * - * \return the list of plugins - */ - inline const std::vector<std::shared_ptr<Plugin>> &plugins() const noexcept - { - return m_plugins; - } - - /** - * Check if a plugin is loaded. - * - * \param name the plugin id - * \return true if has plugin - */ - bool has(const std::string &name) const noexcept; - - /** - * Get a loaded plugin or null if not found. - * - * \param name the plugin id - * \return the plugin or empty one if not found - */ - std::shared_ptr<Plugin> get(const std::string &name) const noexcept; - - /** - * Find a loaded plugin. - * - * \param name the plugin id - * \return the plugin - * \throws std::out_of_range if not found - */ - std::shared_ptr<Plugin> require(const std::string &name) const; - - /** - * Add the specified plugin to the registry. - * - * \pre plugin != nullptr - * \param plugin the plugin - * \note the plugin is only added to the list, no action is performed on it - */ - void add(std::shared_ptr<Plugin> plugin); - - /** - * Configure a plugin. - * - * If the plugin is already loaded, its configuration is updated. - * - * \param name the plugin name - * \param config the new configuration - */ - void configure(const std::string &name, PluginConfig config); - - /** - * Get a configuration for a plugin. - * - * \param name the plugin name - * \return the configuration or default one if not found - */ - PluginConfig config(const std::string &name) const; - - /** - * Add formatting for a plugin. - * - * \param name the plugin name - * \param formats the formats - */ - void setFormats(const std::string &name, PluginFormats formats); - - /** - * Get formats for a plugin. - * - * \param name the plugin name - * \return the formats - */ - PluginFormats formats(const std::string &name) const; - - /** - * Convenient wrapper that loads a plugin, call onLoad and add it to the registry. - * - * Any errors are printed using logger. - * - * \param name the name - * \param path the optional path (searched if empty) - */ - void load(std::string name, std::string path = ""); - - /** - * Unload a plugin and remove it. - * - * \param name the plugin id - */ - void unload(const std::string &name); - - /** - * Reload a plugin by calling onReload. - * - * \param name the plugin name - * \throw std::exception on failures - */ - void reload(const std::string &name); -}; - -} // !irccd - -#endif // !IRCCD_SERVICE_PLUGIN_HPP +/* + * service-plugin.hpp -- manage plugins + * + * Copyright (c) 2013-2016 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_SERVICE_PLUGIN_HPP +#define IRCCD_SERVICE_PLUGIN_HPP + +/** + * \file service-plugin.hpp + * \brief Manage plugins. + */ + +#include <unordered_map> +#include <memory> +#include <vector> + +#include "plugin-js.hpp" + +namespace irccd { + +class Irccd; + +/** + * \brief Manage plugins. + */ +class PluginService { +private: + Irccd &m_irccd; + std::vector<std::shared_ptr<Plugin>> m_plugins; + std::unordered_map<std::string, PluginConfig> m_config; + std::unordered_map<std::string, PluginFormats> m_formats; + +public: + /** + * Create the plugin service. + * + * \param irccd the irccd instance + */ + IRCCD_EXPORT PluginService(Irccd &irccd) noexcept; + + /** + * Destroy plugins. + */ + IRCCD_EXPORT ~PluginService(); + + /** + * Get the list of plugins. + * + * \return the list of plugins + */ + inline const std::vector<std::shared_ptr<Plugin>> &plugins() const noexcept + { + return m_plugins; + } + + /** + * Check if a plugin is loaded. + * + * \param name the plugin id + * \return true if has plugin + */ + IRCCD_EXPORT bool has(const std::string &name) const noexcept; + + /** + * Get a loaded plugin or null if not found. + * + * \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; + + /** + * Find a loaded plugin. + * + * \param name the plugin id + * \return the plugin + * \throws std::out_of_range if not found + */ + IRCCD_EXPORT std::shared_ptr<Plugin> require(const std::string &name) const; + + /** + * Add the specified plugin to the registry. + * + * \pre plugin != nullptr + * \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); + + /** + * Configure a plugin. + * + * If the plugin is already loaded, its configuration is updated. + * + * \param name the plugin name + * \param config the new configuration + */ + IRCCD_EXPORT void configure(const std::string &name, PluginConfig config); + + /** + * Get a configuration for a plugin. + * + * \param name the plugin name + * \return the configuration or default one if not found + */ + IRCCD_EXPORT PluginConfig config(const std::string &name) const; + + /** + * Add formatting for a plugin. + * + * \param name the plugin name + * \param formats the formats + */ + IRCCD_EXPORT void setFormats(const std::string &name, PluginFormats formats); + + /** + * Get formats for a plugin. + * + * \param name the plugin name + * \return the formats + */ + IRCCD_EXPORT PluginFormats formats(const std::string &name) const; + + /** + * Convenient wrapper that loads a plugin, call onLoad and add it to the registry. + * + * Any errors are printed using logger. + * + * \param name the name + * \param path the optional path (searched if empty) + */ + IRCCD_EXPORT 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); + + /** + * Reload a plugin by calling onReload. + * + * \param name the plugin name + * \throw std::exception on failures + */ + IRCCD_EXPORT void reload(const std::string &name); +}; + +} // !irccd + +#endif // !IRCCD_SERVICE_PLUGIN_HPP
--- a/lib/irccd/service-rule.cpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/service-rule.cpp Tue May 24 13:00:35 2016 +0200 @@ -1,79 +1,78 @@ -/* - * service-rule.cpp -- store and solve rules - * - * Copyright (c) 2013-2016 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 <format.h> - -#include "logger.hpp" -#include "service-rule.hpp" -#include "util.hpp" - -using namespace fmt::literals; - -namespace irccd { - -void RuleService::add(Rule rule) -{ - m_rules.push_back(std::move(rule)); -} - -void RuleService::insert(Rule rule, unsigned position) -{ - assert(position <= m_rules.size()); - - m_rules.insert(m_rules.begin() + position, std::move(rule)); -} - -void RuleService::remove(unsigned position) -{ - assert(position < m_rules.size()); - - m_rules.erase(m_rules.begin() + 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 result = true; - - log::debug("rule: solving for server={}, channel={}, origin={}, plugin={}, event={}"_format(server, channel, - origin, plugin, event)); - - int i = 0; - for (const Rule &rule : m_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; - - if (rule.match(server, channel, origin, plugin, event)) { - result = rule.action() == RuleAction::Accept; - } - } - - return result; -} - -} // !irccd +/* + * service-rule.cpp -- store and solve rules + * + * Copyright (c) 2013-2016 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 <format.h> + +#include "logger.hpp" +#include "service-rule.hpp" +#include "util.hpp" + +using namespace fmt::literals; + +namespace irccd { + +void RuleService::add(Rule rule) +{ + m_rules.push_back(std::move(rule)); +} + +void RuleService::insert(Rule rule, unsigned position) +{ + assert(position <= m_rules.size()); + + m_rules.insert(m_rules.begin() + position, std::move(rule)); +} + +void RuleService::remove(unsigned position) +{ + assert(position < m_rules.size()); + + m_rules.erase(m_rules.begin() + 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 result = true; + + log::debug("rule: solving for server={}, channel={}, origin={}, plugin={}, event={}"_format(server, channel, + origin, plugin, event)); + + int i = 0; + for (const Rule &rule : m_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; + + if (rule.match(server, channel, origin, plugin, event)) + result = rule.action() == RuleAction::Accept; + } + + return result; +} + +} // !irccd
--- a/lib/irccd/service-rule.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/service-rule.hpp Tue May 24 13:00:35 2016 +0200 @@ -1,103 +1,103 @@ -/* - * service-rule.hpp -- store and solve rules - * - * Copyright (c) 2013-2016 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_SERVICE_RULE_HPP -#define IRCCD_SERVICE_RULE_HPP - -/** - * \file service-rule.hpp - * \brief Store and solve rules. - */ - -#include <vector> - -#include "rule.hpp" - -namespace irccd { - -/** - * \brief Store and solve rules. - */ -class RuleService { -private: - std::vector<Rule> m_rules; - -public: - /** - * Get the list of rules. - * - * \return the list of rules - */ - inline const std::vector<Rule> &rules() const noexcept - { - return m_rules; - } - - /** - * Get the number of rules. - * - * \return the number of rules - */ - inline unsigned length() const noexcept - { - return m_rules.size(); - } - - /** - * Append a rule. - * - * \param rule the rule to append - */ - void add(Rule rule); - - /** - * Insert a new rule at the specified position. - * - * \param rule the rule - * \param position the position - */ - void insert(Rule rule, unsigned position); - - /** - * Remove a new rule from the specified position. - * - * \pre position must be valid - * \param position the position - */ - void remove(unsigned position); - - /** - * Resolve the action to execute with the specified list of rules. - * - * \param server the server name - * \param channel the channel name - * \param origin the origin - * \param plugin the plugin name - * \param event the event name (e.g onKick) - * \return true if the plugin must be called - */ - bool solve(const std::string &server, - const std::string &channel, - const std::string &origin, - const std::string &plugin, - const std::string &event) noexcept; -}; - -} // !irccd - -#endif // !IRCCD_SERVICE_RULE_HPP +/* + * service-rule.hpp -- store and solve rules + * + * Copyright (c) 2013-2016 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_SERVICE_RULE_HPP +#define IRCCD_SERVICE_RULE_HPP + +/** + * \file service-rule.hpp + * \brief Store and solve rules. + */ + +#include <vector> + +#include "rule.hpp" + +namespace irccd { + +/** + * \brief Store and solve rules. + */ +class RuleService { +private: + std::vector<Rule> m_rules; + +public: + /** + * Get the list of rules. + * + * \return the list of rules + */ + inline const std::vector<Rule> &rules() const noexcept + { + return m_rules; + } + + /** + * Get the number of rules. + * + * \return the number of rules + */ + inline unsigned length() const noexcept + { + return m_rules.size(); + } + + /** + * Append a rule. + * + * \param rule the rule to append + */ + IRCCD_EXPORT void add(Rule rule); + + /** + * Insert a new rule at the specified position. + * + * \param rule the rule + * \param position the position + */ + IRCCD_EXPORT void insert(Rule rule, unsigned position); + + /** + * Remove a new rule from the specified position. + * + * \pre position must be valid + * \param position the position + */ + IRCCD_EXPORT void remove(unsigned position); + + /** + * Resolve the action to execute with the specified list of rules. + * + * \param server the server name + * \param channel the channel name + * \param origin the origin + * \param plugin the plugin name + * \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; +}; + +} // !irccd + +#endif // !IRCCD_SERVICE_RULE_HPP
--- a/lib/irccd/service-server.cpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/service-server.cpp Tue May 24 13:00:35 2016 +0200 @@ -38,9 +38,8 @@ { std::shared_ptr<Server> server = ptr.lock(); - if (!server) { + if (!server) return; - } log::debug() << "server " << server->name() << ": event onChannelMode:\n"; log::debug() << " origin: " << origin << "\n"; @@ -74,9 +73,8 @@ { std::shared_ptr<Server> server = ptr.lock(); - if (!server) { + if (!server) return; - } log::debug() << "server " << server->name() << ": event onChannelNotice:\n"; log::debug() << " origin: " << origin << "\n"; @@ -107,9 +105,8 @@ { std::shared_ptr<Server> server = ptr.lock(); - if (!server) { + if (!server) return; - } log::debug() << "server " << server->name() << ": event onConnect" << std::endl; @@ -134,9 +131,8 @@ { std::shared_ptr<Server> server = ptr.lock(); - if (!server) { + if (!server) return; - } log::debug() << "server " << server->name() << ": event onInvite:\n"; log::debug() << " origin: " << origin << "\n"; @@ -166,9 +162,8 @@ { std::shared_ptr<Server> server = ptr.lock(); - if (!server) { + if (!server) return; - } log::debug() << "server " << server->name() << ": event onJoin:\n"; log::debug() << " origin: " << origin << "\n"; @@ -197,9 +192,8 @@ { std::shared_ptr<Server> server = ptr.lock(); - if (!server) { + if (!server) return; - } log::debug() << "server " << server->name() << ": event onKick:\n"; log::debug() << " origin: " << origin << "\n"; @@ -232,9 +226,8 @@ { std::shared_ptr<Server> server = ptr.lock(); - if (!server) { + if (!server) return; - } log::debug() << "server " << server->name() << ": event onMessage:\n"; log::debug() << " origin: " << origin << "\n"; @@ -270,9 +263,8 @@ { std::shared_ptr<Server> server = ptr.lock(); - if (!server) { + if (!server) return; - } log::debug() << "server " << server->name() << ": event onMe:\n"; log::debug() << " origin: " << origin << "\n"; @@ -303,9 +295,8 @@ { std::shared_ptr<Server> server = ptr.lock(); - if (!server) { + if (!server) return; - } log::debug() << "server " << server->name() << ": event onMode\n"; log::debug() << " origin: " << origin << "\n"; @@ -334,9 +325,8 @@ { std::shared_ptr<Server> server = ptr.lock(); - if (!server) { + if (!server) return; - } log::debug() << "server " << server->name() << ": event onNames:\n"; log::debug() << " channel: " << channel << "\n"; @@ -367,9 +357,8 @@ { std::shared_ptr<Server> server = ptr.lock(); - if (!server) { + if (!server) return; - } log::debug() << "server " << server->name() << ": event onNick:\n"; log::debug() << " origin: " << origin << "\n"; @@ -398,9 +387,8 @@ { std::shared_ptr<Server> server = ptr.lock(); - if (!server) { + if (!server) return; - } log::debug() << "server " << server->name() << ": event onNotice:\n"; log::debug() << " origin: " << origin << "\n"; @@ -429,9 +417,8 @@ { std::shared_ptr<Server> server = ptr.lock(); - if (!server) { + if (!server) return; - } log::debug() << "server " << server->name() << ": event onPart:\n"; log::debug() << " origin: " << origin << "\n"; @@ -462,9 +449,8 @@ { std::shared_ptr<Server> server = ptr.lock(); - if (!server) { + if (!server) return; - } log::debug() << "server " << server->name() << ": event onQuery:\n"; log::debug() << " origin: " << origin << "\n"; @@ -498,9 +484,8 @@ { std::shared_ptr<Server> server = ptr.lock(); - if (!server) { + if (!server) return; - } log::debug() << "server " << server->name() << ": event onTopic:\n"; log::debug() << " origin: " << origin << "\n"; @@ -531,9 +516,8 @@ { std::shared_ptr<Server> server = ptr.lock(); - if (!server) { + if (!server) return; - } log::debug() << "server " << server->name() << ": event onWhois\n"; log::debug() << " nickname: " << whois.nick << "\n"; @@ -577,9 +561,8 @@ void ServerService::sync(fd_set &in, fd_set &out) { - for (auto &server : m_servers) { + for (auto &server : m_servers) server->sync(in, out); - } } bool ServerService::has(const std::string &name) const noexcept @@ -633,9 +616,8 @@ return server->name() == name; }); - if (it == m_servers.end()) { + if (it == m_servers.end()) return nullptr; - } return *it; } @@ -644,9 +626,8 @@ { auto server = get(name); - if (!server) { + if (!server) throw std::invalid_argument("server {} not found"_format(name)); - } return server; } @@ -665,9 +646,8 @@ void ServerService::clear() noexcept { - for (auto &server : m_servers) { + for (auto &server : m_servers) server->disconnect(); - } m_servers.clear(); }
--- a/lib/irccd/service-server.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/service-server.hpp Tue May 24 13:00:35 2016 +0200 @@ -65,17 +65,17 @@ /** * Create the server service. */ - ServerService(Irccd &instance); + IRCCD_EXPORT ServerService(Irccd &instance); /** * \copydoc Service::prepare */ - void prepare(fd_set &in, fd_set &out, net::Handle &max) override; + IRCCD_EXPORT void prepare(fd_set &in, fd_set &out, net::Handle &max) override; /** * \copydoc Service::sync */ - void sync(fd_set &in, fd_set &out) override; + IRCCD_EXPORT void sync(fd_set &in, fd_set &out) override; /** * Get the list of servers @@ -93,7 +93,7 @@ * \param name the name * \return true if exists */ - bool has(const std::string &name) const noexcept; + IRCCD_EXPORT bool has(const std::string &name) const noexcept; /** * Add a new server to the application. @@ -101,7 +101,7 @@ * \pre hasServer must return false * \param sv the server */ - void add(std::shared_ptr<Server> sv); + IRCCD_EXPORT void add(std::shared_ptr<Server> sv); /** * Get a server or empty one if not found @@ -109,7 +109,7 @@ * \param name the server name * \return the server or empty one if not found */ - std::shared_ptr<Server> get(const std::string &name) const noexcept; + IRCCD_EXPORT std::shared_ptr<Server> get(const std::string &name) const noexcept; /** * Find a server by name. @@ -118,8 +118,7 @@ * \return the server * \throw std::out_of_range if the server does not exist */ - std::shared_ptr<Server> require(const std::string &name) const; - + IRCCD_EXPORT std::shared_ptr<Server> require(const std::string &name) const; /** * Remove a server from the irccd instance. @@ -128,14 +127,14 @@ * * \param name the server name */ - void remove(const std::string &name); + IRCCD_EXPORT void remove(const std::string &name); /** * Remove all servers. * * All servers will be disconnected. */ - void clear() noexcept; + IRCCD_EXPORT void clear() noexcept; }; } // !irccd
--- a/lib/irccd/service-transport.cpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/service-transport.cpp Tue May 24 13:00:35 2016 +0200 @@ -32,9 +32,8 @@ // 0. Be sure the object still exists. auto tc = ptr.lock(); - if (!tc) { + if (!tc) return; - } // 1. Check if the Json object is valid. auto name = object.find("command"); @@ -85,9 +84,8 @@ auto tc = ptr.lock(); - if (tc) { + if (tc) m_clients.erase(std::find(m_clients.begin(), m_clients.end(), tc)); - } }); } @@ -102,21 +100,18 @@ for (const auto &transport : m_servers) { FD_SET(transport->handle(), &in); - if (transport->handle() > max) { + if (transport->handle() > max) max = transport->handle(); - } } // Transport clients. for (const auto &client : m_clients) { FD_SET(client->handle(), &in); - if (client->hasOutput()) { + if (client->hasOutput()) FD_SET(client->handle(), &out); - } - if (client->handle() > max) { + if (client->handle() > max) max = client->handle(); - } } } @@ -126,9 +121,8 @@ // Transport servers. for (const auto &transport : m_servers) { - if (!FD_ISSET(transport->handle(), &in)) { + if (!FD_ISSET(transport->handle(), &in)) continue; - } log::debug("transport: new client connected"); @@ -174,9 +168,8 @@ void TransportService::broadcast(std::string data) { // Asynchronous send. - for (const auto &client : m_clients) { + for (const auto &client : m_clients) client->send(data); - } } } // !irccd
--- a/lib/irccd/service-transport.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/service-transport.hpp Tue May 24 13:00:35 2016 +0200 @@ -56,31 +56,31 @@ * * \param irccd the irccd instance */ - TransportService(Irccd &irccd) noexcept; + IRCCD_EXPORT TransportService(Irccd &irccd) noexcept; /** * \copydoc Service::prepare */ - void prepare(fd_set &in, fd_set &out, net::Handle &max) override; + IRCCD_EXPORT void prepare(fd_set &in, fd_set &out, net::Handle &max) override; /** * \copydoc Service::sync */ - void sync(fd_set &in, fd_set &out) override; + IRCCD_EXPORT void sync(fd_set &in, fd_set &out) override; /** * Add a transport server. * * \param ts the transport server */ - void add(std::shared_ptr<TransportServer> ts); + IRCCD_EXPORT void add(std::shared_ptr<TransportServer> ts); /** * Send data to all clients. * * \param data the data */ - void broadcast(std::string data); + IRCCD_EXPORT void broadcast(std::string data); };
--- a/lib/irccd/service.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/service.hpp Tue May 24 13:00:35 2016 +0200 @@ -25,6 +25,8 @@ */ #include "sockets.hpp" +#include "sysconfig.hpp" +#include "util.hpp" namespace irccd { @@ -60,9 +62,7 @@ */ virtual void prepare(fd_set &in, fd_set &out, net::Handle &max) { - (void)in; - (void)out; - (void)max; + util::unused(in, out, max); } /** @@ -73,8 +73,7 @@ */ virtual void sync(fd_set &in, fd_set &out) { - (void)in; - (void)out; + util::unused(in, out); } };
--- a/lib/irccd/sockets.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/sockets.hpp Tue May 24 13:00:35 2016 +0200 @@ -63,6 +63,8 @@ * | Mac OS X | kqueue(2) | Kqueue | */ +#include "sysconfig.hpp" + #if defined(_WIN32) # if _WIN32_WINNT >= 0x0600 && !defined(SOCKET_HAVE_POLL) # define SOCKET_HAVE_POLL @@ -295,12 +297,12 @@ * Initialize the socket library. Except if you defined SOCKET_NO_AUTO_INIT, you don't need to call this * function manually. */ -void init() noexcept; +IRCCD_EXPORT void init() noexcept; /** * Close the socket library. */ -void finish() noexcept; +IRCCD_EXPORT void finish() noexcept; #if !defined(SOCKET_NO_SSL) @@ -313,12 +315,12 @@ * Initialize the OpenSSL library. Except if you defined SOCKET_NO_AUTO_SSL_INIT, you don't need to call this function * manually. */ -void init() noexcept; +IRCCD_EXPORT void init() noexcept; /** * Close the OpenSSL library. */ -void finish() noexcept; +IRCCD_EXPORT void finish() noexcept; } // !ssl @@ -330,7 +332,7 @@ * * \return a string message */ -std::string error(); +IRCCD_EXPORT std::string error(); /** * Get the last system error. @@ -338,7 +340,7 @@ * \param errn the error number (errno or WSAGetLastError) * \return the error */ -std::string error(int errn); +IRCCD_EXPORT std::string error(int errn); /* }}} */ @@ -379,7 +381,7 @@ * \param code which kind of error * \param function the function name */ - Error(Code code, std::string function); + IRCCD_EXPORT Error(Code code, std::string function); /** * Constructor that use the system error set by the user. @@ -388,7 +390,7 @@ * \param function the function name * \param error the error */ - Error(Code code, std::string function, int error); + IRCCD_EXPORT Error(Code code, std::string function, int error); /** * Constructor that set the error specified by the user. @@ -397,7 +399,7 @@ * \param function the function name * \param error the error */ - Error(Code code, std::string function, std::string error); + IRCCD_EXPORT Error(Code code, std::string function, std::string error); /** * Get which function has triggered the error. @@ -2826,7 +2828,7 @@ /** * Return the sockets */ - std::vector<ListenerStatus> wait(const ListenerTable &table, int ms); + IRCCD_EXPORT std::vector<ListenerStatus> wait(const ListenerTable &table, int ms); /** * Backend identifier @@ -2857,17 +2859,17 @@ /** * Set the handle. */ - void set(const ListenerTable &, Handle, Condition, bool); + IRCCD_EXPORT void set(const ListenerTable &, Handle, Condition, bool); /** * Unset the handle. */ - void unset(const ListenerTable &, Handle, Condition, bool); + IRCCD_EXPORT void unset(const ListenerTable &, Handle, Condition, bool); /** * Wait for events. */ - std::vector<ListenerStatus> wait(const ListenerTable &, int ms); + IRCCD_EXPORT std::vector<ListenerStatus> wait(const ListenerTable &, int ms); /** * Backend identifier @@ -2904,27 +2906,27 @@ /** * Construct the epoll instance. */ - Epoll(); + IRCCD_EXPORT Epoll(); /** * Close the epoll instance. */ - ~Epoll(); + IRCCD_EXPORT ~Epoll(); /** * Set the handle. */ - void set(const ListenerTable &, Handle, Condition, bool); + IRCCD_EXPORT void set(const ListenerTable &, Handle, Condition, bool); /** * Unset the handle. */ - void unset(const ListenerTable &, Handle, Condition, bool); + IRCCD_EXPORT void unset(const ListenerTable &, Handle, Condition, bool); /** * Wait for events. */ - std::vector<ListenerStatus> wait(const ListenerTable &, int); + IRCCD_EXPORT std::vector<ListenerStatus> wait(const ListenerTable &, int); /** * Backend identifier @@ -2962,27 +2964,27 @@ /** * Construct the kqueue instance. */ - Kqueue(); + IRCCD_EXPORT Kqueue(); /** * Destroy the kqueue instance. */ - ~Kqueue(); + IRCCD_EXPORT ~Kqueue(); /** * Set the handle. */ - void set(const ListenerTable &, Handle, Condition, bool); + IRCCD_EXPORT void set(const ListenerTable &, Handle, Condition, bool); /** * Unset the handle. */ - void unset(const ListenerTable &, Handle, Condition, bool); + IRCCD_EXPORT void unset(const ListenerTable &, Handle, Condition, bool); /** * Wait for events. */ - std::vector<ListenerStatus> wait(const ListenerTable &, int); + IRCCD_EXPORT std::vector<ListenerStatus> wait(const ListenerTable &, int); /** * Backend identifier @@ -3303,789 +3305,6 @@ } }; -/* }}} */ - -/* - * Callback - * ------------------------------------------------------------------ - * - * Function owner with tests. - */ - -/* {{{ Callback */ - -/** - * \class Callback - * \brief Convenient signal owner that checks if the target is valid. - * - * This class also catch all errors thrown from signals to avoid interfering with our process. - */ -template <typename... Args> -class Callback : public std::function<void (Args...)> { -public: - /** - * Inherited constructors. - */ - using std::function<void (Args...)>::function; - - /** - * Execute the callback only if a target is set. - */ - void operator()(Args... args) const - { - if (*this) { - try { - std::function<void (Args...)>::operator()(args...); - } catch (...) { - } - } - } -}; - -/* }}} */ - -/* - * StreamConnection - * ------------------------------------------------------------------ - * - * Client connected on the server side. - */ - -/* {{{ StreamConnection */ - -/** - * \class StreamConnection - * \brief Connected client on the server side. - * - * This object is created from StreamServer when a new client is connected, it is the higher - * level object of sockets and completely asynchronous. - */ -template <typename Address, typename Protocol> -class StreamConnection { -public: - /** - * Called when the output has changed. - */ - using WriteHandler = Callback<>; - -private: - /* Signals */ - WriteHandler m_onWrite; - - /* Sockets and output buffer */ - Socket<Address, Protocol> m_socket; - std::string m_output; - -public: - /** - * Create the connection. - * - * \param s the socket - */ - StreamConnection(Socket<Address, Protocol> s) - : m_socket{std::move(s)} - { - m_socket.set(net::option::SockBlockMode{false}); - } - - /** - * Access the underlying socket. - * - * \return the socket - * \warning use with care - */ - inline Socket<Address, Protocol> &socket() noexcept - { - return m_socket; - } - - /** - * Access the current output. - * - * \return the output - */ - inline const std::string &output() const noexcept - { - return m_output; - } - - /** - * Overloaded function - * - * \return the output - * \warning use with care, avoid modifying the output if you don't know what you're doing - */ - inline std::string &output() noexcept - { - return m_output; - } - - /** - * Post some data to be sent asynchronously. - * - * \param str the data to append - */ - inline void send(std::string str) - { - m_output += str; - m_onWrite(); - } - - /** - * Kill the client. - */ - inline void close() - { - m_socket.close(); - } - - /** - * Set the write handler, the signal is emitted when the output has changed so that the StreamServer owner - * knows that there are some data to send. - * - * \param handler the handler - * \warning you usually never need to set this yourself - */ - inline void setWriteHandler(WriteHandler handler) - { - m_onWrite = std::move(handler); - } -}; - -/* }}} */ - -/* - * StreamServer - * ------------------------------------------------------------------ - * - * Convenient stream oriented server. - */ - -/* {{{ StreamServer */ - -/** - * \class StreamServer - * \brief Convenient stream server for TCP and TLS. - * - * This class does all the things for you as accepting new clients, listening for it and sending data. It works - * asynchronously without blocking to let you control your process workflow. - * - * This class is not thread safe and you must not call any of the functions from different threads. - */ -template <typename Address, typename Protocol> -class StreamServer { -public: - /** - * Handler when a new client is connected. - */ - using ConnectionHandler = Callback<const std::shared_ptr<StreamConnection<Address, Protocol>> &>; - - /** - * Handler when a client is disconnected. - */ - using DisconnectionHandler = Callback<const std::shared_ptr<StreamConnection<Address, Protocol>> &>; - - /** - * Handler when data has been received from a client. - */ - using ReadHandler = Callback<const std::shared_ptr<StreamConnection<Address, Protocol>> &, const std::string &>; - - /** - * Handler when data has been correctly sent to a client. - */ - using WriteHandler = Callback<const std::shared_ptr<StreamConnection<Address, Protocol>> &, const std::string &>; - - /** - * Handler when an error occured. - */ - using ErrorHandler = Callback<const Error &>; - - /** - * Handler when there was a timeout. - */ - using TimeoutHandler = Callback<>; - -private: - using ClientMap = std::map<Handle, std::shared_ptr<StreamConnection<Address, Protocol>>>; - - /* Signals */ - ConnectionHandler m_onConnection; - DisconnectionHandler m_onDisconnection; - ReadHandler m_onRead; - WriteHandler m_onWrite; - ErrorHandler m_onError; - TimeoutHandler m_onTimeout; - - /* Sockets */ - Socket<Address, Protocol> m_master; - Listener<> m_listener; - ClientMap m_clients; - - /* - * Update flags depending on the required condition. - */ - void updateFlags(std::shared_ptr<StreamConnection<Address, Protocol>> &client) - { - assert(client->socket().action() != Action::None); - - m_listener.remove(client->socket().handle()); - m_listener.set(client->socket().handle(), client->socket().condition()); - } - - /* - * Continue accept process. - */ - template <typename AcceptCall> - void processAccept(std::shared_ptr<StreamConnection<Address, Protocol>> &client, const AcceptCall &acceptFunc) - { - try { - /* Do the accept */ - acceptFunc(); - - /* 1. First remove completely the client */ - m_listener.remove(client->socket().handle()); - - /* 2. If accept is not finished, wait for the appropriate condition */ - if (client->socket().state() == State::Accepted) { - /* 3. Client is accepted, notify the user */ - m_listener.set(client->socket().handle(), Condition::Readable); - m_onConnection(client); - } else { - /* Operation still in progress */ - updateFlags(client); - } - } catch (const Error &error) { - m_clients.erase(client->socket().handle()); - m_listener.remove(client->socket().handle()); - m_onError(error); - } - } - - /* - * Process initial accept of master socket, this is the initial accepting process. Except on errors, the - * socket is stored but the user will be notified only once the socket is completely accepted. - */ - void processInitialAccept() - { - // TODO: store address too. - std::shared_ptr<StreamConnection<Address, Protocol>> client = std::make_shared<StreamConnection<Address, Protocol>>(m_master.accept(nullptr)); - std::weak_ptr<StreamConnection<Address, Protocol>> ptr{client}; - - /* 1. Register output changed to update listener */ - client->setWriteHandler([this, ptr] () { - auto client = ptr.lock(); - - /* Do not update the listener immediately if an action is pending */ - if (client && client->socket().action() == Action::None && !client->output().empty()) { - m_listener.set(client->socket().handle(), Condition::Writable); - } - }); - - /* 2. Add the client */ - m_clients.insert(std::make_pair(client->socket().handle(), client)); - - /* - * 2. Do an initial check to set the listener flags, at this moment the socket may or not be - * completely accepted. - */ - processAccept(client, [&] () {}); - } - - /* - * Read or complete the read operation. - */ - void processRead(std::shared_ptr<StreamConnection<Address, Protocol>> &client) - { - /* - * Read because there is something to read or because the pending operation is - * read and must complete. - */ - auto buffer = client->socket().recv(512); - - /* - * Now the receive operation may be completed, in that case, two possibilities: - * - * 1. The action is set to None (completed) - * 2. The action is still not complete, update the flags - */ - if (client->socket().action() == Action::None) { - /* Empty mean normal disconnection */ - if (buffer.empty()) { - m_listener.remove(client->socket().handle()); - m_clients.erase(client->socket().handle()); - m_onDisconnection(client); - } else { - /* - * At this step, it is possible that we were completing a receive operation, in this - * case the write flag may be removed, add it if required. - */ - if (!client->output().empty()) { - m_listener.set(client->socket().handle(), Condition::Writable); - } - - m_onRead(client, buffer); - } - } else { - /* Operation in progress */ - updateFlags(client); - } - } - - /* - * Flush the output buffer. - */ - void processWrite(std::shared_ptr<StreamConnection<Address, Protocol>> &client) - { - auto &output = client->output(); - auto nsent = client->socket().send(output); - - if (client->socket().action() == Action::None) { - /* 1. Create a copy of content that has been sent */ - auto sent = output.substr(0, nsent); - - /* 2. Erase the content sent */ - output.erase(0, nsent); - - /* 3. Update listener */ - if (output.empty()) { - m_listener.unset(client->socket().handle(), Condition::Writable); - } - - /* 4. Notify user */ - m_onWrite(client, sent); - } else { - updateFlags(client); - } - } - - void processSync(std::shared_ptr<StreamConnection<Address, Protocol>> &client, Condition flags) - { - try { - auto action = client->socket().action(); - - if (action == Action::Receive || - (action == Action::None && (flags & Condition::Readable) == Condition::Readable)) { - processRead(client); - } else if ((flags & Condition::Writable) == Condition::Writable) { - processWrite(client); - } - } catch (const Error &error) { - m_onDisconnection(client); - m_listener.remove(client->socket().handle()); - m_clients.erase(client->socket().handle()); - } - } - -public: - /** - * Create a stream server with the specified address to bind. - * - * \param protocol the protocol (Tcp or Tls) - * \param address the address to bind - * \param max the max number to listen - * \throw Error on errors - */ - StreamServer(Protocol protocol, const Address &address, int max = 128) - : m_master{std::move(protocol), address} - { - // TODO: m_onError - m_master.set(SOL_SOCKET, SO_REUSEADDR, 1); - m_master.bind(address); - m_master.listen(max); - m_listener.set(m_master.handle(), Condition::Readable); - } - - /** - * Set the connection handler, called when a new client is connected. - * - * \param handler the handler - */ - inline void setConnectionHandler(ConnectionHandler handler) - { - m_onConnection = std::move(handler); - } - - /** - * Set the disconnection handler, called when a client died. - * - * \param handler the handler - */ - inline void setDisconnectionHandler(DisconnectionHandler handler) - { - m_onDisconnection = std::move(handler); - } - - /** - * Set the receive handler, called when a client has sent something. - * - * \param handler the handler - */ - inline void setReadHandler(ReadHandler handler) - { - m_onRead = std::move(handler); - } - - /** - * Set the writing handler, called when some data has been sent to a client. - * - * \param handler the handler - */ - inline void setWriteHandler(WriteHandler handler) - { - m_onWrite = std::move(handler); - } - - /** - * Set the error handler, called when unrecoverable error has occured. - * - * \param handler the handler - */ - inline void setErrorHandler(ErrorHandler handler) - { - m_onError = std::move(handler); - } - - /** - * Set the timeout handler, called when the selection has timeout. - * - * \param handler the handler - */ - inline void setTimeoutHandler(TimeoutHandler handler) - { - m_onTimeout = std::move(handler); - } - - /** - * Poll for the next event. - * - * \param timeout the timeout (-1 for indefinitely) - * \throw Error on errors - */ - void poll(int timeout = -1) - { - try { - auto st = m_listener.wait(timeout); - - if (st.socket == m_master.handle()) { - /* New client */ - processInitialAccept(); - } else { - /* Recv / Send / Accept on a client */ - auto client = m_clients[st.socket]; - - if (client->socket().state() == State::Accepted) { - processSync(client, st.flags); - } else { - processAccept(client, [&] () { client->socket().accept(); }); - } - } - } catch (const Error &error) { - if (error.code() == Error::Timeout) { - m_onTimeout(); - } else { - m_onError(error); - } - } - } -}; - -/* }}} */ - -/* - * StreamClient - * ------------------------------------------------------------------ - */ - -/* {{{ StreamClient */ - -/** - * \class StreamClient - * \brief Client side connection to a server. - * - * This class is not thread safe and you must not call any of the functions from different threads. - */ -template <typename Address, typename Protocol> -class StreamClient { -public: - /** - * Handler when connection is complete. - */ - using ConnectionHandler = Callback<>; - - /** - * Handler when data has been received. - */ - using ReadHandler = Callback<const std::string &>; - - /** - * Handler when data has been sent correctly. - */ - using WriteHandler = Callback<const std::string &>; - - /** - * Handler when disconnected. - */ - using DisconnectionHandler = Callback<>; - - /** - * Handler on unrecoverable error. - */ - using ErrorHandler = Callback<const Error &>; - - /** - * Handler when timeout occured. - */ - using TimeoutHandler = Callback<>; - -private: - /* Signals */ - ConnectionHandler m_onConnection; - ReadHandler m_onRead; - WriteHandler m_onWrite; - DisconnectionHandler m_onDisconnection; - ErrorHandler m_onError; - TimeoutHandler m_onTimeout; - - /* Socket */ - Socket<Address, Protocol> m_socket; - Listener<> m_listener; - - /* Output buffer */ - std::string m_output; - - /* - * Update the flags after an uncompleted operation. This function must only be called when the operation - * has not complete (e.g. connect, recv, send). - */ - void updateFlags() - { - assert(m_socket.action() != Action::None); - - m_listener.remove(m_socket.handle()); - m_listener.set(m_socket.handle(), m_socket.condition()); - } - - /* - * This is the generic connect helper, it will be used to both initiate the connection or to continue the - * connection process if needed. - * - * Thus the template parameter is the appropriate function to call either, m_socket.connect(address) or - * m_socket.connect(). - * - * See poll() and connect() to understand. - */ - template <typename ConnectCall> - void processConnect(const ConnectCall &connectFunc) - { - /* Call m_socket.connect() or m_socket.connect(address) */ - connectFunc(); - - /* Remove entirely */ - m_listener.remove(m_socket.handle()); - - if (m_socket.state() == State::Connected) { - m_onConnection(); - m_listener.set(m_socket.handle(), Condition::Readable); - } else { - /* Connection still in progress */ - updateFlags(); - } - } - - /* - * Receive or complete the receive command, if the command is not complete, the listener is updated - * accordingly. - */ - void processRead() - { - auto received = m_socket.recv(512); - - if (m_socket.action() == Action::None) { - /* 0 means disconnection */ - if (received.empty()) { - m_onDisconnection(); - } else { - /* - * At this step, it is possible that we were completing a receive operation, in this - * case the write flag may be removed, add it if required. - */ - if (m_output.empty()) { - m_listener.unset(m_socket.handle(), Condition::Writable); - } - - m_onRead(received); - } - } else { - /* Receive operation in progress */ - updateFlags(); - } - } - - /* - * Send or complete the send command, if the command is not complete, the listener is updated - * accordingly. - */ - void processWrite() - { - auto nsent = m_socket.send(m_output); - - if (m_socket.action() == Action::None) { - /* 1. Make a copy of what has been sent */ - auto sent = m_output.substr(0, nsent); - - /* 2. Erase sent content */ - m_output.erase(0, nsent); - - /* 3. Update flags if needed */ - if (m_output.empty()) { - m_listener.unset(m_socket.handle(), Condition::Writable); - } - - /* 4. Notify user */ - m_onWrite(sent); - } else { - /* Send operation in progress */ - updateFlags(); - } - } - - /* - * Receive or send. - */ - void processSync(Condition condition) - { - if ((m_socket.action() == Action::Receive) || - (m_socket.action() == Action::None && (condition & Condition::Readable) == Condition::Readable)) { - processRead(); - } else { - processWrite(); - } - } - -public: - /** - * Create a client. The client is automatically marked as non-blocking. - * - * \param protocol the protocol (Tcp or Tls) - * \param address the optional address - * \throw net::Error on failures - */ - StreamClient(Protocol protocol = {}, const Address &address = {}) - : m_socket{std::move(protocol), address} - { - m_socket.set(net::option::SockBlockMode{false}); - m_listener.set(m_socket.handle(), Condition::Readable); - } - - /** - * Set the connection handler, called when the connection succeed. - * - * \param handler the handler - */ - inline void setConnectionHandler(ConnectionHandler handler) - { - m_onConnection = std::move(handler); - } - - /** - * Set the disconnection handler, called when the server closed the connection. - * - * \param handler the handler - */ - inline void setDisconnectionHandler(DisconnectionHandler handler) - { - m_onDisconnection = std::move(handler); - } - - /** - * Set the read handler, called when we received something. - * - * \param handler the handler - */ - inline void setReadHandler(ReadHandler handler) - { - m_onRead = std::move(handler); - } - - /** - * Set the write handler, called when we successfully sent data. - * - * \param handler the handler - */ - inline void setWriteHandler(WriteHandler handler) - { - m_onWrite = std::move(handler); - } - - /** - * Set the error handler, called when unexpected error occurs. - * - * \param handler the handler - */ - inline void setErrorHandler(ErrorHandler handler) - { - m_onError = std::move(handler); - } - - /** - * Connect to a server, this function may connect immediately or not in any case the connection handler - * will be called when the connection completed. - * - * \param address the address to connect to - */ - void connect(const Address &address) noexcept - { - assert(m_socket.state() == State::Open); - - processConnect([&] () { m_socket.connect(address); }); - } - - /** - * Asynchronously send data to the server. - * - * \param str the data to append - */ - void send(std::string str) - { - m_output += str; - - /* Don't update the listener if there is a pending operation */ - if (m_socket.state() == State::Connected && m_socket.action() == Action::None && !m_output.empty()) { - m_listener.set(m_socket.handle(), Condition::Writable); - } - } - - /** - * Wait for the next event. - * - * \param timeout the time to wait in milliseconds - * \throw Error on errors - */ - void poll(int timeout = -1) noexcept - { - try { - auto st = m_listener.wait(timeout); - - if (m_socket.state() != State::Connected) { - /* Continue the connection */ - processConnect([&] () { m_socket.connect(); }); - } else { - /* Read / Write */ - processSync(st.flags); - } - } catch (const Error &error) { - if (error.code() == Error::Timeout) { - m_onTimeout(); - } else { - m_listener.remove(m_socket.handle()); - m_onError(error); - } - } - } -}; - -/* }}} */ - } // !net } // !irccd
--- a/lib/irccd/system.cpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/system.cpp Tue May 24 13:00:35 2016 +0200 @@ -52,14 +52,14 @@ #endif -/* For sys::setGid */ +// For sys::setGid. #if defined(HAVE_SETGID) # include <sys/types.h> # include <unistd.h> # include <grp.h> #endif -/* For sys::setUid */ +// For sys::setUid. #if defined(HAVE_SETGID) # include <sys/types.h> # include <unistd.h> @@ -100,9 +100,9 @@ { IntType id; - if (util::isNumber(value)) { + if (util::isNumber(value)) id = std::stoi(value); - } else { + else { auto info = lookup(value.c_str()); if (info == nullptr) { @@ -110,16 +110,14 @@ return; } else { id = getter(info); - log::debug() << "irccd: " << typeName << " " << value << " resolved to: " << id << std::endl; } } - if (setter(id) < 0) { + if (setter(id) < 0) log::warning() << "irccd: could not set " << typeName << ": " << std::strerror(errno) << std::endl; - } else { + else log::info() << "irccd: setting " << typeName << " to " << value << std::endl; - } } /* @@ -175,9 +173,8 @@ #else struct utsname uts; - if (uname(&uts) < 0) { + if (uname(&uts) < 0) throw std::runtime_error(std::strerror(errno)); - } return std::string(uts.release); #endif @@ -190,9 +187,8 @@ #elif defined(IRCCD_SYSTEM_LINUX) struct sysinfo info; - if (sysinfo(&info) < 0) { + if (sysinfo(&info) < 0) throw std::runtime_error(std::strerror(errno)); - } return info.uptime; #elif defined(IRCCD_SYSTEM_MAC) @@ -200,20 +196,18 @@ size_t length = sizeof (boottime); int mib[2] = { CTL_KERN, KERN_BOOTTIME }; - if (sysctl(mib, 2, &boottime, &length, nullptr, 0) < 0) { + if (sysctl(mib, 2, &boottime, &length, nullptr, 0) < 0) throw std::runtime_error(std::strerror(errno)); - } time_t bsec = boottime.tv_sec, csec = time(nullptr); return difftime(csec, bsec); #else - /* BSD */ + // BSD. struct timespec ts; - if (clock_gettime(CLOCK_UPTIME, &ts) < 0) { + if (clock_gettime(CLOCK_UPTIME, &ts) < 0) throw std::runtime_error(std::strerror(errno)); - } return ts.tv_sec; #endif @@ -241,9 +235,8 @@ #if defined(IRCCD_SYSTEM_WINDOWS) char path[MAX_PATH]; - if (SHGetFolderPathA(nullptr, CSIDL_LOCAL_APPDATA, nullptr, 0, path) != S_OK) { + if (SHGetFolderPathA(nullptr, CSIDL_LOCAL_APPDATA, nullptr, 0, path) != S_OK) return ""; - } return std::string(path); #else @@ -255,9 +248,8 @@ { auto value = std::getenv(var.c_str()); - if (value == nullptr) { + if (value == nullptr) return ""; - } return value; }
--- a/lib/irccd/system.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/system.hpp Tue May 24 13:00:35 2016 +0200 @@ -38,35 +38,35 @@ * * \param name the program name */ -void setProgramName(std::string name) noexcept; +IRCCD_EXPORT void setProgramName(std::string name) noexcept; /** * Get the program name. * * \return the program name */ -const std::string &programName() noexcept; +IRCCD_EXPORT const std::string &programName() noexcept; /** * Get the system name. * * \return the name */ -std::string name(); +IRCCD_EXPORT std::string name(); /** * Get the system version. * * \return the version */ -std::string version(); +IRCCD_EXPORT std::string version(); /** * Get the number of seconds elapsed since the boottime. * * \return the number of seconds */ -uint64_t uptime(); +IRCCD_EXPORT uint64_t uptime(); /** * Get the milliseconds elapsed since the application @@ -74,21 +74,21 @@ * * \return the milliseconds */ -uint64_t ticks(); +IRCCD_EXPORT uint64_t ticks(); /** * Get an environment variable. * * \return the value or empty string */ -std::string env(const std::string &var); +IRCCD_EXPORT std::string env(const std::string &var); /** * Get home directory usually /home/foo * * \return the home directory */ -std::string home(); +IRCCD_EXPORT std::string home(); #if defined(HAVE_SETUID) @@ -97,7 +97,7 @@ * * \param value the value */ -void setUid(const std::string &value); +IRCCD_EXPORT void setUid(const std::string &value); #endif @@ -108,7 +108,7 @@ * * \param value the value */ -void setGid(const std::string &value); +IRCCD_EXPORT void setGid(const std::string &value); #endif
--- a/lib/irccd/timer.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/timer.hpp Tue May 24 13:00:35 2016 +0200 @@ -31,6 +31,7 @@ #include <thread> #include "signals.hpp" +#include "sysconfig.hpp" namespace irccd { @@ -102,14 +103,14 @@ * \param delay the delay in milliseconds * \post isRunning() returns false */ - Timer(TimerType type, unsigned delay) noexcept; + IRCCD_EXPORT Timer(TimerType type, unsigned delay) noexcept; /** * Destructor, closes the thread. * * \pre stop() must have been called. */ - virtual ~Timer(); + IRCCD_EXPORT virtual ~Timer(); /** * Start the thread. @@ -119,14 +120,14 @@ * \pre onEnd() must have been called * \note Thread-safe */ - void start(); + IRCCD_EXPORT void start(); /** * Stop the timer, may be used by the user to stop it. * * \note Thread-safe */ - void stop(); + IRCCD_EXPORT void stop(); /** * Get the type of timer.
--- a/lib/irccd/transport-client.cpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/transport-client.cpp Tue May 24 13:00:35 2016 +0200 @@ -26,9 +26,8 @@ { json::Value document(json::Buffer{message}); - if (!document.isObject()) { + if (!document.isObject()) throw std::invalid_argument("the message is not a valid JSON object"); - } onCommand(document); }
--- a/lib/irccd/transport-client.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/transport-client.hpp Tue May 24 13:00:35 2016 +0200 @@ -32,6 +32,7 @@ #include "server.hpp" #include "signals.hpp" #include "sockets.hpp" +#include "sysconfig.hpp" namespace irccd { @@ -89,7 +90,7 @@ * \param setinput the input fd_set * \param setoutput the output fd_set */ - void sync(fd_set &setinput, fd_set &setoutput); + IRCCD_EXPORT void sync(fd_set &setinput, fd_set &setoutput); /** * Send some data, it will be pushed to the outgoing buffer. @@ -99,7 +100,7 @@ * * \param message the message */ - void send(std::string message); + IRCCD_EXPORT void send(std::string message); /** * Tell if the client has data pending for output. @@ -157,9 +158,8 @@ try { auto message = m_socket.recv(512); - if (message.empty()) { + if (message.empty()) onDie(); - } m_input += message; } catch (const std::exception &) {
--- a/lib/irccd/transport-server.cpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/transport-server.cpp Tue May 24 13:00:35 2016 +0200 @@ -39,10 +39,9 @@ { m_socket.set(net::option::SockReuseAddress{true}); - /* Disable or enable IPv4 when using IPv6 */ - if (domain == AF_INET6) { + // Disable or enable IPv4 when using IPv6. + if (domain == AF_INET6) m_socket.set(net::option::Ipv6Only{ipv6only}); - } m_socket.bind(net::address::Ip{address, port, static_cast<net::address::Ip::Type>(domain)}); m_socket.listen();
--- a/lib/irccd/transport-server.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/transport-server.hpp Tue May 24 13:00:35 2016 +0200 @@ -100,17 +100,17 @@ * \param ipv6only set to true to disable IPv4 * \throw net::Error on failures */ - TransportServerIp(int domain, const std::string &address, int port, bool ipv6only = true); + IRCCD_EXPORT TransportServerIp(int domain, const std::string &address, int port, bool ipv6only = true); /** * \copydoc TransportServer::socket */ - net::Handle handle() noexcept override; + IRCCD_EXPORT net::Handle handle() noexcept override; /** * \copydoc TransportServer::accept */ - std::shared_ptr<TransportClient> accept() override; + IRCCD_EXPORT std::shared_ptr<TransportClient> accept() override; }; #if !defined(IRCCD_SYSTEM_WINDOWS) @@ -130,22 +130,22 @@ * * \param path the path */ - TransportServerUnix(std::string path); + IRCCD_EXPORT TransportServerUnix(std::string path); /** * Destroy the transport and remove the file. */ - ~TransportServerUnix(); + IRCCD_EXPORT ~TransportServerUnix(); /** * \copydoc TransportServer::socket */ - net::Handle handle() noexcept override; + IRCCD_EXPORT net::Handle handle() noexcept override; /** * \copydoc TransportServer::accept */ - std::shared_ptr<TransportClient> accept() override; + IRCCD_EXPORT std::shared_ptr<TransportClient> accept() override; }; #endif // !_WIN32
--- a/lib/irccd/unicode.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/unicode.hpp Tue May 24 13:00:35 2016 +0200 @@ -27,12 +27,14 @@ #include <stdexcept> #include <string> +#include "sysconfig.hpp" + namespace irccd { namespace unicode { -void encode(char32_t point, char res[5]) noexcept; -void decode(char32_t &c, const char *res) noexcept; +IRCCD_EXPORT void encode(char32_t point, char res[5]) noexcept; +IRCCD_EXPORT void decode(char32_t &c, const char *res) noexcept; /** * Get the number of bytes for the first multi byte character from a @@ -44,7 +46,7 @@ * \param c the first multi byte character * \return the number of bytes [1-4] */ -int nbytesUtf8(char c) noexcept; +IRCCD_EXPORT int nbytesUtf8(char c) noexcept; /** * Get the number of bytes for the unicode point. @@ -52,7 +54,7 @@ * \param point the unicode point * \return the number of bytes [1-4] or -1 on invalid */ -int nbytesPoint(char32_t point) noexcept; +IRCCD_EXPORT int nbytesPoint(char32_t point) noexcept; /** * Get real number of character in a string. @@ -61,7 +63,7 @@ * \return the length * \throw std::invalid_argument on invalid sequence */ -int length(const std::string &str); +IRCCD_EXPORT int length(const std::string &str); /** * Iterate over all real characters in the UTF-8 string. @@ -97,7 +99,7 @@ * \return the UTF-8 string * \throw std::invalid_argument on invalid sequence */ -std::string toUtf8(const std::u32string &array); +IRCCD_EXPORT std::string toUtf8(const std::u32string &array); /** * Convert a UTF-8 string to UTF-32 string. @@ -106,7 +108,7 @@ * \return the UTF-32 string * \throw std::invalid_argument on invalid sequence */ -std::u32string toUtf32(const std::string &str); +IRCCD_EXPORT std::u32string toUtf32(const std::string &str); /** * Check if the unicode character is space. @@ -114,7 +116,7 @@ * \param c the character * \return true if space */ -bool isspace(char32_t c) noexcept; +IRCCD_EXPORT bool isspace(char32_t c) noexcept; /** * Check if the unicode character is digit. @@ -122,7 +124,7 @@ * \param c the character * \return true if digit */ -bool isdigit(char32_t c) noexcept; +IRCCD_EXPORT bool isdigit(char32_t c) noexcept; /** * Check if the unicode character is alpha category. @@ -130,7 +132,7 @@ * \param c the character * \return true if alpha */ -bool isalpha(char32_t c) noexcept; +IRCCD_EXPORT bool isalpha(char32_t c) noexcept; /** * Check if the unicode character is upper case. @@ -138,7 +140,7 @@ * \param c the character * \return true if upper case */ -bool isupper(char32_t c) noexcept; +IRCCD_EXPORT bool isupper(char32_t c) noexcept; /** * Check if the unicode character is lower case. @@ -146,7 +148,7 @@ * \param c the character * \return true if lower case */ -bool islower(char32_t c) noexcept; +IRCCD_EXPORT bool islower(char32_t c) noexcept; /** * Check if the unicode character is title case. @@ -154,7 +156,7 @@ * \param c the character * \return true if title case */ -bool istitle(char32_t c) noexcept; +IRCCD_EXPORT bool istitle(char32_t c) noexcept; /** * Convert to upper case. @@ -162,7 +164,7 @@ * \param c the character * \return the upper case character */ -char32_t toupper(char32_t c) noexcept; +IRCCD_EXPORT char32_t toupper(char32_t c) noexcept; /** * Convert to lower case. @@ -170,7 +172,7 @@ * \param c the character * \return the lower case character */ -char32_t tolower(char32_t c) noexcept; +IRCCD_EXPORT char32_t tolower(char32_t c) noexcept; /** * Convert to title case. @@ -178,7 +180,7 @@ * \param c the character * \return the title case character */ -char32_t totitle(char32_t c) noexcept; +IRCCD_EXPORT char32_t totitle(char32_t c) noexcept; /** * Convert the UTF-32 string to upper case.
--- a/lib/irccd/util.cpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/util.cpp Tue May 24 13:00:35 2016 +0200 @@ -95,9 +95,8 @@ { auto value = params.keywords.find(content); - if (value != params.keywords.end()) { + if (value != params.keywords.end()) return value->second; - } return ""; } @@ -106,9 +105,8 @@ { auto value = std::getenv(content.c_str()); - if (value != nullptr) { + if (value != nullptr) return value; - } return ""; } @@ -118,12 +116,11 @@ std::stringstream oss; std::vector<std::string> list = split(content, ","); - /* @{} means reset */ - if (list.empty()) { + // @{} means reset. + if (list.empty()) return std::string(1, attributesTable.at("reset")); - } - /* Remove useless spaces */ + // Remove useless spaces. std::transform(list.begin(), list.end(), list.begin(), strip); /* @@ -133,27 +130,24 @@ */ auto foreground = list[0]; if (!foreground.empty() || list.size() >= 2) { - /* Color sequence */ + // Color sequence. oss << '\x03'; - /* Foreground */ + // Foreground. auto it = colorTable.find(foreground); - if (it != colorTable.end()) { + if (it != colorTable.end()) oss << it->second; - } - /* Background */ - if (list.size() >= 2 && (it = colorTable.find(list[1])) != colorTable.end()) { + // Background. + if (list.size() >= 2 && (it = colorTable.find(list[1])) != colorTable.end()) oss << "," << it->second; - } - /* Attributes */ + // Attributes. for (std::size_t i = 2; i < list.size(); ++i) { auto attribute = attributesTable.find(list[i]); - if (attribute != attributesTable.end()) { + if (attribute != attributesTable.end()) oss << attribute->second; - } } } @@ -166,38 +160,32 @@ std::string content, value; - if (it == end) { + if (it == end) return ""; - } - while (it != end && *it != '}') { + while (it != end && *it != '}') content += *it++; - } - if (it == end || *it != '}') { + if (it == end || *it != '}') throw std::invalid_argument("unclosed "s + token + " construct"s); - } it++; - /* Create default original value if flag is disabled */ + // Create default original value if flag is disabled. value = std::string(1, token) + "{"s + content + "}"s; switch (token) { case '#': - if (params.flags & Substitution::Keywords) { + if (params.flags & Substitution::Keywords) value = substituteKeywords(content, params); - } break; case '$': - if (params.flags & Substitution::Env) { + if (params.flags & Substitution::Env) value = substituteEnv(content); - } break; case '@': - if (params.flags & Substitution::IrcAttrs) { + if (params.flags & Substitution::IrcAttrs) substituteAttributes(content); - } break; default: break; @@ -214,9 +202,8 @@ * Change the date format before anything else to avoid interpolation with keywords and * user input. */ - if (params.flags & Substitution::Date) { + if (params.flags & Substitution::Date) text = substituteDate(text, params); - } std::ostringstream oss; @@ -260,11 +247,10 @@ * "##hello" -> "##hello" * "##{hello}" -> "#{hello}" */ - if (++it == end) { + if (++it == end) oss << token << token; - } else if (*it == '{') { + else if (*it == '{') oss << token; - } } return oss.str(); @@ -287,9 +273,8 @@ int count = 1; bool finished = false; - if (list.empty()) { + if (list.empty()) return result; - } do { std::string val; @@ -297,7 +282,7 @@ current = next + 1; next = list.find_first_of(delimiters, current); - // split max, get until the end + // split max, get until the end. if (max >= 0 && count++ >= max) { val = list.substr(current, std::string::npos); finished = true; @@ -328,22 +313,20 @@ * is a space, we check until we find a space, if not * typing "!foo123123" will trigger foo plugin. */ - if (pos == std::string::npos) { + if (pos == std::string::npos) iscommand = result == fullcommand; - } else { + else iscommand = result.length() >= fullcommand.length() && result.compare(0, pos, fullcommand) == 0; - } if (iscommand) { /* * If no space is found we just set the message to "" otherwise * the plugin name will be passed through onCommand */ - if (pos == std::string::npos) { + if (pos == std::string::npos) result = ""; - } else { + else result = message.substr(pos + 1); - } } } @@ -357,9 +340,8 @@ bool isInt(const std::string &str, int base) noexcept { - if (str.empty()) { + if (str.empty()) return false; - } char *ptr; @@ -370,9 +352,8 @@ bool isReal(const std::string &str) noexcept { - if (str.empty()) { + if (str.empty()) return false; - } char *ptr;
--- a/lib/irccd/util.hpp Mon May 23 14:05:41 2016 +0200 +++ b/lib/irccd/util.hpp Tue May 24 13:00:35 2016 +0200 @@ -35,6 +35,8 @@ #include <unordered_map> #include <vector> +#include "sysconfig.hpp" + namespace irccd { namespace util { @@ -132,7 +134,7 @@ * - <strong>\@{default,yellow}</strong>: will write default color text on yellow background, * - <strong>\@{white,black,bold,underline}</strong>: will write white text on black in both bold and underline. */ -std::string format(std::string text, const Substitution ¶ms = {}); +IRCCD_EXPORT std::string format(std::string text, const Substitution ¶ms = {}); /** * Remove leading and trailing spaces. @@ -140,7 +142,7 @@ * \param str the string * \return the removed white spaces */ -std::string strip(std::string str); +IRCCD_EXPORT std::string strip(std::string str); /** * Split a string by delimiters. @@ -150,7 +152,7 @@ * \param max max number of split * \return a list of string splitted */ -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. @@ -167,9 +169,8 @@ if (first != last) { oss << *first; - while (++first != last) { + while (++first != last) oss << delim << *first; - } } return oss.str(); @@ -196,7 +197,7 @@ * \param plugin the plugin name * \return the pair */ -MessagePair parseMessage(std::string message, const std::string &commandChar, const std::string &plugin); +IRCCD_EXPORT MessagePair parseMessage(std::string message, const std::string &commandChar, const std::string &plugin); /** * Server and identities must have strict names. This function can @@ -217,7 +218,7 @@ * \return true if is boolean * \note this function is case-insensitive */ -bool isBoolean(std::string value) noexcept; +IRCCD_EXPORT bool isBoolean(std::string value) noexcept; /** * Check if the string is an integer. @@ -226,7 +227,7 @@ * \param base the optional base * \return true if integer */ -bool isInt(const std::string &value, int base = 10) noexcept; +IRCCD_EXPORT bool isInt(const std::string &value, int base = 10) noexcept; /** * Check if the string is real. @@ -234,7 +235,7 @@ * \param value the value * \return true if real */ -bool isReal(const std::string &value) noexcept; +IRCCD_EXPORT bool isReal(const std::string &value) noexcept; /** * Check if the string is a number. @@ -271,15 +272,13 @@ std::conditional_t<std::is_unsigned<T>::value, unsigned long long, long long> value; - if (std::is_unsigned<T>::value) { + if (std::is_unsigned<T>::value) value = std::stoull(number); - } else { + else value = std::stoll(number); - } - if (value < min || value > max) { + if (value < min || value > max) throw std::out_of_range("out of range"); - } return static_cast<T>(value); } @@ -290,7 +289,7 @@ * \param input the buffer, will be updated * \return the message or empty string if there is nothing */ -std::string nextNetwork(std::string &input); +IRCCD_EXPORT std::string nextNetwork(std::string &input); /** * Use arguments to avoid compiler warnings about unused parameters.