# HG changeset patch # User David Demelier # Date 1473764237 -7200 # Node ID 60b94daf4d24d82fa34d76fbb2473ef1c1c9e6d5 # Parent f04acabfbbe5ca5b490f202def039e58f7dbe0c8 CMake: update irccd_define_plugin, closes #534 Also add a native debugging plugin. diff -r f04acabfbbe5 -r 60b94daf4d24 cmake/IrccdOptions.cmake --- a/cmake/IrccdOptions.cmake Mon Sep 12 17:54:27 2016 +0200 +++ b/cmake/IrccdOptions.cmake Tue Sep 13 12:57:17 2016 +0200 @@ -86,18 +86,6 @@ option(WITH_MAN "Install man pages" ${DEFAULT_MAN}) option(WITH_PKGCONFIG "Enable pkg-config file" ${DEFAULT_PKGCONFIG}) -# Build options for all plugins. -foreach (plugin ${IRCCD_PLUGINS}) - string(TOUPPER ${plugin} optname) - option(WITH_PLUGIN_${optname} "Enable ${plugin} plugin" On) - - if (NOT WITH_PLUGIN_${optname}) - set(WITH_PLUGIN_${optname}_MSG "No (disabled by user)") - else () - set(WITH_PLUGIN_${optname}_MSG "Yes") - endif () -endforeach () - set(WITH_TEST_IRCHOST "127.0.0.1" CACHE STRING "IRC host for tests") set(WITH_TEST_IRCPORT 6667 CACHE STRING "IRC port for test") diff -r f04acabfbbe5 -r 60b94daf4d24 cmake/IrccdVersion.cmake --- a/cmake/IrccdVersion.cmake Mon Sep 12 17:54:27 2016 +0200 +++ b/cmake/IrccdVersion.cmake Tue Sep 13 12:57:17 2016 +0200 @@ -35,16 +35,3 @@ set(IRCCD_RELEASE_DATE_MONTH 04) set(IRCCD_RELEASE_DATE_DAY 19) set(IRCCD_RELEASE_DATE "${IRCCD_RELEASE_DATE_YEAR}-${IRCCD_RELEASE_DATE_MONTH}-${IRCCD_RELEASE_DATE_DAY}") - -# All plugins. -set( - IRCCD_PLUGINS - ask - auth - hangman - history - logger - plugin - roulette - CACHE INTERNAL "" -) diff -r f04acabfbbe5 -r 60b94daf4d24 cmake/function/IrccdDefinePlugin.cmake --- a/cmake/function/IrccdDefinePlugin.cmake Mon Sep 12 17:54:27 2016 +0200 +++ b/cmake/function/IrccdDefinePlugin.cmake Tue Sep 13 12:57:17 2016 +0200 @@ -20,18 +20,146 @@ # irccd_define_plugin # ------------------------------------------------------------------- # -# Define a JavaScript plugin, the file will be configured using configure_file and then installed. +# irccd_define_plugin( +# NAME canonical plugin name +# TYPE JS or NATIVE +# DOCS documentation files in markdown +# +# Options for TYPE JS: +# +# SCRIPT absolute path to the Javascript file (ending with .js) +# +# Options for TYPE NATIVE: +# +# SOURCES c++ source files # -# Parameters: -# file The plugin full file path +# Create a Javascript or Native plugin. +# +# The NAME parameter identifies the plugin. The same name will be used for the +# plugin filename. +# +# Both Javascript and native plugins are supported specified by the TYPE +# parameter to JS or NATIVE respectively. For Javascript plugin, a unique file +# must be given as SCRIPT parameter. For native plugins, any source files can +# be given as SOURCES parameter. +# +# Additional documentation can be built in markdown and installed along the +# plugin using DOCS parameter. +# +# A CMake option is also created in the form OPTION_ where PLG is the +# uppercase NAME value. # -macro(irccd_define_plugin file) - get_filename_component(name ${file} NAME) - set(base ${IRCCD_FAKEROOTDIR}/${WITH_PLUGINDIR}) + +function(_irccd_define_javascript_plugin) + if (NOT PLG_SCRIPT) + message(FATAL_ERROR "Missing SCRIPT parameter") + endif () + + get_filename_component(name ${PLG_SCRIPT} NAME) + + configure_file( + ${PLG_SCRIPT} + ${IRCCD_FAKEROOTDIR}/${WITH_PLUGINDIR}/${name} + ) + + install( + FILES ${IRCCD_FAKEROOTDIR}/${WITH_PLUGINDIR}/${name} + COMPONENT ${PLG_NAME} + DESTINATION ${WITH_PLUGINDIR} + ) + + add_custom_target( + plugin-${PLG_NAME} + DEPENDS ${PLG_OUTPUT_DOC} + ) +endfunction() + +function(_irccd_define_native_plugin) + if (NOT PLG_SOURCES) + message(FATAL_ERROR "Missing SOURCES parameter") + endif () + + add_library(plugin-${PLG_NAME} MODULE ${PLG_SOURCES} ${PLG_OUTPUT_DOC}) + + # Move the target into the native plugin directory and rename it. + set_target_properties( + plugin-${PLG_NAME} + PROPERTIES + PREFIX "" + OUTPUT_NAME ${PLG_NAME} + LIBRARY_OUTPUT_DIRECTORY ${IRCCD_FAKEROOTDIR}/${WITH_NPLUGINDIR} + ) + foreach (c ${CMAKE_CONFIGURATION_TYPES}) + string(TOUPPER CONFIG ${c}) + set_target_properties( + plugin-${PLG_NAME} + PROPERTIES + OUTPUT_NAME_${CONFIG} ${PLG_NAME} + LIBRARY_OUTPUT_DIRECTORY_${CONFIG} ${IRCCD_FAKEROOTDIR}/${WITH_NPLUGINDIR} + ) + endforeach() + target_link_libraries(plugin-${PLG_NAME} libirccd) + install( + TARGETS plugin-${PLG_NAME} + COMPONENT ${PLG_NAME} + LIBRARY DESTINATION ${WITH_NPLUGINDIR} + ) +endfunction() - # Substitude variables in the JavaScript file. - configure_file(${file} ${base}/${name}) +function(irccd_define_plugin) + set(options "") + set(oneValueArgs NAME TYPE SCRIPT) + set(multiValueArgs DOCS SOURCES) + + cmake_parse_arguments(PLG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if (NOT PLG_NAME) + message(FATAL_ERROR "Missing NAME parameter") + endif () + + string(TOUPPER ${PLG_NAME} PLG_UPPER_NAME) + option(WITH_PLUGIN_${PLG_UPPER_NAME} "Enable ${PLG_NAME} plugin" On) + + if (NOT WITH_PLUGIN_${PLG_UPPER_NAME}) + setg(WITH_PLUGIN_${PLG_UPPER_NAME}_MSG "No (disabled by user)") + else () + setg(WITH_PLUGIN_${PLG_UPPER_NAME}_MSG "Yes") + + # Optional documentation. + if (PLG_DOCS AND WITH_HTML) + set(basedocdir ${IRCCD_FAKEROOTDIR}/${WITH_DOCDIR}) + set(PLG_OUTPUT_DOC ${basedocdir}/plugin/${PLG_NAME}.html) + file(RELATIVE_PATH baseurl ${basedocdir}/plugin ${basedocdir}) - # Install the plugin file. - install(FILES ${base}/${name} DESTINATION ${WITH_PLUGINDIR}) -endmacro() + pandoc( + OUTPUT ${basedocdir}/plugin/${PLG_NAME}.html + SOURCES ${PLG_DOCS} + TEMPLATE ${resources_SOURCE_DIR}/template.html + DEPENDS + ${resources_SOURCE_DIR}/template.html + docs-resources + ARGS -Vguide + VARIABLE baseurl:${baseurl} + FROM markdown TO html5 + STANTALONE MAKE_DIRECTORY TOC + ) + install( + FILES ${basedocdir}/plugin/${PLG_NAME}.html + COMPONENT ${PLG_NAME} + DESTINATION ${WITH_DOCDIR}/plugin + ) + endif () + + if (PLG_TYPE MATCHES "JS") + _irccd_define_javascript_plugin() + elseif (PLG_TYPE MATCHES "NATIVE") + _irccd_define_native_plugin() + else () + message(FATAL_ERROR "Invalid TYPE given, must be JS or NATIVE") + endif () + + # Component grouping in installer. + setg(CPACK_COMPONENT_${PLG_UPPER_NAME}_GROUP "Plugins") + setg(CPACK_COMPONENT_${PLG_UPPER_NAME}_DESCRIPTION "Install ${PLG_NAME} plugin.") + endif () +endfunction() diff -r f04acabfbbe5 -r 60b94daf4d24 irccd/main.cpp --- a/irccd/main.cpp Mon Sep 12 17:54:27 2016 +0200 +++ b/irccd/main.cpp Tue Sep 13 12:57:17 2016 +0200 @@ -265,7 +265,13 @@ return 1; } + /* + * Assign instance to nullptr to force deletion of irccd and all its + * associated objects before any other static global values such as + * loggers. + */ instance->run(); + instance = nullptr; return 0; } diff -r f04acabfbbe5 -r 60b94daf4d24 lib/irccd/path.cpp --- a/lib/irccd/path.cpp Mon Sep 12 17:54:27 2016 +0200 +++ b/lib/irccd/path.cpp Tue Sep 13 12:57:17 2016 +0200 @@ -520,7 +520,8 @@ list.push_back(clean(systemPlugins())); break; case PathNativePlugins: - list.push_back(clean(systemPlugins())); + list.push_back(clean(fs::cwd())); + list.push_back(clean(systemNativePlugins())); break; default: break; diff -r f04acabfbbe5 -r 60b94daf4d24 lib/irccd/server.hpp --- a/lib/irccd/server.hpp Mon Sep 12 17:54:27 2016 +0200 +++ b/lib/irccd/server.hpp Tue Sep 13 12:57:17 2016 +0200 @@ -79,14 +79,6 @@ }; /** - * \brief Some variables that are needed in many places internally. - */ -class Cache { -public: - -}; - -/** * \brief Channel event. */ class ChannelModeEvent { diff -r f04acabfbbe5 -r 60b94daf4d24 plugins/CMakeLists.txt --- a/plugins/CMakeLists.txt Mon Sep 12 17:54:27 2016 +0200 +++ b/plugins/CMakeLists.txt Tue Sep 13 12:57:17 2016 +0200 @@ -18,68 +18,30 @@ project(plugins) -add_custom_target( - all-plugins ALL - COMMENT "Irccd plugins" -) - -set_target_properties( - all-plugins - PROPERTIES - FOLDER meta +set( + IRCCD_PLUGINS + ask + auth + hangman + history + logger + plugin + roulette + CACHE INTERNAL "" ) foreach (plugin ${IRCCD_PLUGINS}) - string(TOUPPER ${plugin} optname) - - if (WITH_PLUGIN_${optname}) - # 1. Configure the plugin and install it. - irccd_define_plugin(${plugin}/${plugin}.js) - - # 2. Build documentation. - if (WITH_HTML) - set(basedocdir ${IRCCD_FAKEROOTDIR}/${WITH_DOCDIR}) - file(RELATIVE_PATH baseurl ${basedocdir}/plugin ${basedocdir}) - - pandoc( - OUTPUT ${basedocdir}/plugin/${plugin}.html - SOURCES ${plugin}/${plugin}.md - TEMPLATE ${resources_SOURCE_DIR}/template.html - DEPENDS - ${resources_SOURCE_DIR}/template.html - docs-resources - ARGS -Vguide - VARIABLE baseurl:${baseurl} - FROM markdown TO html5 - STANTALONE MAKE_DIRECTORY TOC - ) + irccd_define_plugin( + NAME ${plugin} + TYPE JS + SCRIPT ${plugins_SOURCE_DIR}/${plugin}/${plugin}.js + DOCS ${plugins_SOURCE_DIR}/${plugin}/${plugin}.md + ) +endforeach () - list(APPEND outputs ${basedocdir}/plugin/${plugin}.html) - install( - FILES ${basedocdir}/plugin/${plugin}.html - COMPONENT ${plugin} - DESTINATION ${WITH_DOCDIR}/plugin - ) - string(TOUPPER ${plugin} CMP) - setg(CPACK_COMPONENT_${CMP}_DESCRIPTION "Install ${plugin}.") - setg(CPACK_COMPONENT_${CMP}_GROUP "Plugins") - endif () - - add_custom_target( - plugin-${plugin} - SOURCES - ${outputs} - ${plugin}/${plugin}.js - ${plugin}/${plugin}.md - ) - - set_target_properties( - plugin-${plugin} - PROPERTIES - PROJECT_LABEL ${plugin} - FOLDER plugins - ) - - add_dependencies(all-plugins plugin-${plugin}) - endif () -endforeach () +# Debug plugins. +irccd_define_plugin( + NAME debugnative + TYPE NATIVE + SOURCES ${plugins_SOURCE_DIR}/debugnative/main.cpp +) diff -r f04acabfbbe5 -r 60b94daf4d24 plugins/debugnative/main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/debugnative/main.cpp Tue Sep 13 12:57:17 2016 +0200 @@ -0,0 +1,207 @@ +/* + * main.cpp -- native plugin for debugging + * + * Copyright (c) 2013-2016 David Demelier + * + * 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 + +#include +#include +#include +#include +#include + +using namespace irccd; + +extern "C" { + +DYNLIB_EXPORT void irccd_onChannelMode(Irccd &, const ChannelModeEvent &event) +{ + log::info() << "plugin debugnative: onChannelMode event\n"; + log::info() << "plugin debugnative: server: " << event.server->name() << std::endl; + log::info() << "plugin debugnative: origin: " << event.origin << std::endl; + log::info() << "plugin debugnative: channel: " << event.channel << std::endl; + log::info() << "plugin debugnative: mode: " << event.mode << std::endl; + log::info() << "plugin debugnative: argument: " << event.argument << std::endl; +} + +DYNLIB_EXPORT void irccd_onChannelNotice(Irccd &, const ChannelNoticeEvent &event) +{ + log::info() << "plugin debugnative: onChannelNotice event\n"; + log::info() << "plugin debugnative: server: " << event.server->name() << std::endl; + log::info() << "plugin debugnative: origin: " << event.origin << std::endl; + log::info() << "plugin debugnative: channel: " << event.channel << std::endl; + log::info() << "plugin debugnative: message: " << event.message << std::endl; +} + +DYNLIB_EXPORT void irccd_onCommand(Irccd &, const MessageEvent &event) +{ + log::info() << "plugin debugnative: onCommand event\n"; + log::info() << "plugin debugnative: server: " << event.server->name() << std::endl; + log::info() << "plugin debugnative: origin: " << event.origin << std::endl; + log::info() << "plugin debugnative: channel: " << event.channel << std::endl; + log::info() << "plugin debugnative: message: " << event.message << std::endl; +} + +DYNLIB_EXPORT void irccd_onConnect(Irccd &, const ConnectEvent &event) +{ + log::info() << "plugin debugnative: onConnect event\n"; + log::info() << "plugin debugnative: server: " << event.server->name() << std::endl; +} + +DYNLIB_EXPORT void irccd_onInvite(Irccd &, const InviteEvent &event) +{ + log::info() << "plugin debugnative: onInvite event\n"; + log::info() << "plugin debugnative: server: " << event.server->name() << std::endl; + log::info() << "plugin debugnative: origin: " << event.origin << std::endl; + log::info() << "plugin debugnative: channel: " << event.channel << std::endl; + log::info() << "plugin debugnative: nickname: " << event.nickname << std::endl; +} + +DYNLIB_EXPORT void irccd_onJoin(Irccd &, const JoinEvent &event) +{ + log::info() << "plugin debugnative: onJoin event\n"; + log::info() << "plugin debugnative: server: " << event.server->name() << std::endl; + log::info() << "plugin debugnative: origin: " << event.origin << std::endl; + log::info() << "plugin debugnative: channel: " << event.channel << std::endl; +} + +DYNLIB_EXPORT void irccd_onKick(Irccd &, const KickEvent &event) +{ + log::info() << "plugin debugnative: onKick event\n"; + log::info() << "plugin debugnative: server: " << event.server->name() << std::endl; + log::info() << "plugin debugnative: origin: " << event.origin << std::endl; + log::info() << "plugin debugnative: channel: " << event.channel << std::endl; + log::info() << "plugin debugnative: target: " << event.target << std::endl; + log::info() << "plugin debugnative: reason: " << event.reason << std::endl; +} + +DYNLIB_EXPORT void irccd_onLoad(Irccd &, DynlibPlugin &) +{ + log::info() << "plugin debugnative: onLoad event\n"; +} + +DYNLIB_EXPORT void irccd_onMessage(Irccd &, const MessageEvent &event) +{ + + log::info() << "plugin debugnative: onMessage event\n"; + log::info() << "plugin debugnative: server: " << event.server->name() << std::endl; + log::info() << "plugin debugnative: origin: " << event.origin << std::endl; + log::info() << "plugin debugnative: channel: " << event.channel << std::endl; + log::info() << "plugin debugnative: message: " << event.message << std::endl; +} + +DYNLIB_EXPORT void irccd_onMe(Irccd &, const MeEvent &event) +{ + log::info() << "plugin debugnative: onMe event\n"; + log::info() << "plugin debugnative: server: " << event.server->name() << std::endl; + log::info() << "plugin debugnative: origin: " << event.origin << std::endl; + log::info() << "plugin debugnative: channel: " << event.channel << std::endl; + log::info() << "plugin debugnative: message: " << event.message << std::endl; +} + +DYNLIB_EXPORT void irccd_onMode(Irccd &, const ModeEvent &event) +{ + log::info() << "plugin debugnative: onMode event\n"; + log::info() << "plugin debugnative: server: " << event.server->name() << std::endl; + log::info() << "plugin debugnative: origin: " << event.origin << std::endl; + log::info() << "plugin debugnative: mode: " << event.mode << std::endl; +} + +DYNLIB_EXPORT void irccd_onNames(Irccd &, const NamesEvent &event) +{ + log::info() << "plugin debugnative: onNames event\n"; + log::info() << "plugin debugnative: server: " << event.server->name() << std::endl; + log::info() << "plugin debugnative: channel: " << event.channel << std::endl; + log::info() << "plugin debugnative: names: " + << util::join(event.names.begin(), event.names.end(), ", ") + << std::endl; +} + +DYNLIB_EXPORT void irccd_onNick(Irccd &, const NickEvent &event) +{ + log::info() << "plugin debugnative: onNick event\n"; + log::info() << "plugin debugnative: server: " << event.server->name() << std::endl; + log::info() << "plugin debugnative: origin: " << event.origin << std::endl; + log::info() << "plugin debugnative: nickname: " << event.nickname << std::endl; +} + +DYNLIB_EXPORT void irccd_onNotice(Irccd &, const NoticeEvent &event) +{ + log::info() << "plugin debugnative: onNotice event\n"; + log::info() << "plugin debugnative: server: " << event.server->name() << std::endl; + log::info() << "plugin debugnative: origin: " << event.origin << std::endl; + log::info() << "plugin debugnative: message: " << event.message << std::endl; +} + +DYNLIB_EXPORT void irccd_onPart(Irccd &, const PartEvent &event) +{ + log::info() << "plugin debugnative: onPart event\n"; + log::info() << "plugin debugnative: server: " << event.server->name() << std::endl; + log::info() << "plugin debugnative: origin: " << event.origin << std::endl; + log::info() << "plugin debugnative: channel: " << event.channel << std::endl; + log::info() << "plugin debugnative: reason: " << event.reason << std::endl; +} + +DYNLIB_EXPORT void irccd_onQuery(Irccd &, const QueryEvent &event) +{ + log::info() << "plugin debugnative: onQuery event\n"; + log::info() << "plugin debugnative: server: " << event.server->name() << std::endl; + log::info() << "plugin debugnative: origin: " << event.origin << std::endl; + log::info() << "plugin debugnative: message: " << event.message << std::endl; +} + +DYNLIB_EXPORT void irccd_onQueryCommand(Irccd &, const QueryEvent &event) +{ + log::info() << "plugin debugnative: onQueryCommand event\n"; + log::info() << "plugin debugnative: server: " << event.server->name() << std::endl; + log::info() << "plugin debugnative: origin: " << event.origin << std::endl; + log::info() << "plugin debugnative: message: " << event.message << std::endl; +} + +DYNLIB_EXPORT void irccd_onReload(Irccd &, DynlibPlugin &) +{ + log::info() << "plugin debugnative: onReload event\n"; +} + +DYNLIB_EXPORT void irccd_onTopic(Irccd &, const TopicEvent &event) +{ + log::info() << "plugin debugnative: onTopic event\n"; + log::info() << "plugin debugnative: server: " << event.server->name() << std::endl; + log::info() << "plugin debugnative: origin: " << event.origin << std::endl; + log::info() << "plugin debugnative: channel: " << event.channel << std::endl; + log::info() << "plugin debugnative: topic: " << event.topic << std::endl; +} + +DYNLIB_EXPORT void irccd_onUnload(Irccd &, DynlibPlugin &) +{ + log::info() << "plugin debugnative: onUnload event\n"; +} + +DYNLIB_EXPORT void irccd_onWhois(Irccd &, const WhoisEvent &event) +{ + log::info() << "plugin debugnative: onWhois event\n"; + log::info() << "plugin debugnative: server: " << event.server->name() << std::endl; + log::info() << "plugin debugnative: nick: " << event.whois.nick << std::endl; + log::info() << "plugin debugnative: user: " << event.whois.user << std::endl; + log::info() << "plugin debugnative: host: " << event.whois.host << std::endl; + log::info() << "plugin debugnative: channels: " + << util::join(event.whois.channels.begin(), + event.whois.channels.end(), ", ") + << std::endl; +} + +} // !C