From 30942f7f62e47eec761a63ca4da7767859c82ce6 Mon Sep 17 00:00:00 2001 From: Sebastien Helleu Date: Sat, 25 Jan 2014 13:29:03 +0100 Subject: trigger: add trigger plugin --- CMakeLists.txt | 1 + configure.ac | 19 + po/POTFILES.in | 72 +-- po/srcfiles.cmake | 84 +-- src/core/wee-command.c | 33 +- src/core/wee-config.c | 207 ++++--- src/core/wee-proxy.c | 157 +++--- src/core/wee-string.c | 219 +++++++- src/core/wee-string.h | 4 +- src/gui/gui-bar.c | 433 +++++++-------- src/plugins/CMakeLists.txt | 12 +- src/plugins/Makefile.am | 16 +- src/plugins/plugin.c | 1 + src/plugins/trigger/CMakeLists.txt | 31 ++ src/plugins/trigger/Makefile.am | 42 ++ src/plugins/trigger/trigger-buffer.c | 180 +++++++ src/plugins/trigger/trigger-buffer.h | 32 ++ src/plugins/trigger/trigger-callback.c | 597 +++++++++++++++++++++ src/plugins/trigger/trigger-callback.h | 38 ++ src/plugins/trigger/trigger-command.c | 352 ++++++++++++ src/plugins/trigger/trigger-command.h | 25 + src/plugins/trigger/trigger-completion.c | 185 +++++++ src/plugins/trigger/trigger-completion.h | 25 + src/plugins/trigger/trigger-config.c | 484 +++++++++++++++++ src/plugins/trigger/trigger-config.h | 40 ++ src/plugins/trigger/trigger.c | 894 +++++++++++++++++++++++++++++++ src/plugins/trigger/trigger.h | 129 +++++ src/plugins/weechat-plugin.h | 9 +- 28 files changed, 3806 insertions(+), 515 deletions(-) create mode 100644 src/plugins/trigger/CMakeLists.txt create mode 100644 src/plugins/trigger/Makefile.am create mode 100644 src/plugins/trigger/trigger-buffer.c create mode 100644 src/plugins/trigger/trigger-buffer.h create mode 100644 src/plugins/trigger/trigger-callback.c create mode 100644 src/plugins/trigger/trigger-callback.h create mode 100644 src/plugins/trigger/trigger-command.c create mode 100644 src/plugins/trigger/trigger-command.h create mode 100644 src/plugins/trigger/trigger-completion.c create mode 100644 src/plugins/trigger/trigger-completion.h create mode 100644 src/plugins/trigger/trigger-config.c create mode 100644 src/plugins/trigger/trigger-config.h create mode 100644 src/plugins/trigger/trigger.c create mode 100644 src/plugins/trigger/trigger.h diff --git a/CMakeLists.txt b/CMakeLists.txt index b750950c8..7dd8f85fb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,6 +85,7 @@ OPTION(ENABLE_RUBY "Enable Ruby scripting language" ON) OPTION(ENABLE_LUA "Enable Lua scripting language" ON) OPTION(ENABLE_TCL "Enable Tcl scripting language" ON) OPTION(ENABLE_GUILE "Enable Scheme (guile) scripting language" ON) +OPTION(ENABLE_TRIGGER "Enable Trigger plugin" ON) OPTION(ENABLE_XFER "Enable Xfer plugin" ON) OPTION(ENABLE_MAN "Enable build of man page" OFF) OPTION(ENABLE_DOC "Enable build of documentation" OFF) diff --git a/configure.ac b/configure.ac index 6d7784b55..2e8d582ec 100644 --- a/configure.ac +++ b/configure.ac @@ -116,6 +116,7 @@ AH_VERBATIM([PLUGIN_RUBY], [#undef PLUGIN_RUBY]) AH_VERBATIM([PLUGIN_LUA], [#undef PLUGIN_LUA]) AH_VERBATIM([PLUGIN_TCL], [#undef PLUGIN_TCL]) AH_VERBATIM([PLUGIN_GUILE], [#undef PLUGIN_GUILE]) +AH_VERBATIM([PLUGIN_TRIGGER], [#undef PLUGIN_TRIGGER]) AH_VERBATIM([PLUGIN_XFER], [#undef PLUGIN_XFER]) AH_VERBATIM([MAN], [#undef MAN]) AH_VERBATIM([DOC], [#undef DOC]) @@ -145,6 +146,7 @@ AC_ARG_ENABLE(ruby, [ --disable-ruby turn off Ruby script plug AC_ARG_ENABLE(lua, [ --disable-lua turn off Lua script plugin (default=compiled if found)],enable_lua=$enableval,enable_lua=yes) AC_ARG_ENABLE(tcl, [ --disable-tcl turn off Tcl script plugin (default=compiled if found)],enable_tcl=$enableval,enable_tcl=yes) AC_ARG_ENABLE(guile, [ --disable-guile turn off Guile (scheme) script plugin (default=compiled if found)],enable_guile=$enableval,enable_guile=yes) +AC_ARG_ENABLE(trigger, [ --disable-trigger turn off Trigger plugin (default=compiled)],enable_trigger=$enableval,enable_trigger=yes) AC_ARG_ENABLE(xfer, [ --disable-xfer turn off Xfer (file transfer) plugin (default=compiled if found)],enable_xfer=$enableval,enable_xfer=yes) AC_ARG_WITH(lua-inc, [ --with-lua-inc=DIR, lua include files are in DIR (default=autodetect)],lua_inc=$withval,lua_inc='') AC_ARG_WITH(lua-lib, [ --with-lua-lib=DIR, lua library files are in DIR (default=autodetect)],lua_lib=$withval,lua_lib='') @@ -800,6 +802,18 @@ if test "x$enable_guile" = "xyes" ; then AC_DEFINE(PLUGIN_GUILE) fi +# --------------------------------- trigger ------------------------------------ + +if test "x$enable_trigger" = "xyes" ; then + TRIGGER_CFLAGS="" + TRIGGER_LFLAGS="" + AC_SUBST(TRIGGER_CFLAGS) + AC_SUBST(TRIGGER_LFLAGS) + AC_DEFINE(PLUGIN_TRIGGER) +else + not_asked="$not_asked trigger" +fi + # ---------------------------------- xfer -------------------------------------- if test "x$enable_xfer" = "xyes" ; then @@ -1125,6 +1139,7 @@ AM_CONDITIONAL(PLUGIN_RUBY, test "$enable_ruby" = "yes") AM_CONDITIONAL(PLUGIN_LUA, test "$enable_lua" = "yes") AM_CONDITIONAL(PLUGIN_TCL, test "$enable_tcl" = "yes") AM_CONDITIONAL(PLUGIN_GUILE, test "$enable_guile" = "yes") +AM_CONDITIONAL(PLUGIN_TRIGGER, test "$enable_trigger" = "yes") AM_CONDITIONAL(PLUGIN_XFER, test "$enable_xfer" = "yes") AM_CONDITIONAL(MAN, test "$enable_man" = "yes") AM_CONDITIONAL(DOC, test "$enable_doc" = "yes") @@ -1157,6 +1172,7 @@ AC_OUTPUT([Makefile src/plugins/lua/Makefile src/plugins/tcl/Makefile src/plugins/guile/Makefile + src/plugins/trigger/Makefile src/plugins/xfer/Makefile src/gui/Makefile src/gui/curses/Makefile @@ -1224,6 +1240,9 @@ fi if test "x$enable_guile" = "xyes"; then listplugins="$listplugins guile($GUILE_VERSION)" fi +if test "x$enable_trigger" = "xyes"; then + listplugins="$listplugins trigger" +fi if test "x$enable_xfer" = "xyes"; then listplugins="$listplugins xfer" fi diff --git a/po/POTFILES.in b/po/POTFILES.in index 7ef0678f8..ab669ac08 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -1,3 +1,4 @@ +./doc/docgen.py ./src/core/wee-backtrace.c ./src/core/wee-backtrace.h ./src/core/weechat.c @@ -33,9 +34,9 @@ ./src/core/wee-string.c ./src/core/wee-string.h ./src/core/wee-upgrade.c -./src/core/wee-upgrade.h ./src/core/wee-upgrade-file.c ./src/core/wee-upgrade-file.h +./src/core/wee-upgrade.h ./src/core/wee-url.c ./src/core/wee-url.h ./src/core/wee-utf8.c @@ -64,12 +65,10 @@ ./src/gui/gui-chat.h ./src/gui/gui-color.c ./src/gui/gui-color.h -./src/gui/gui-cursor.c -./src/gui/gui-cursor.h -./src/gui/gui-mouse.c -./src/gui/gui-mouse.h ./src/gui/gui-completion.c ./src/gui/gui-completion.h +./src/gui/gui-cursor.c +./src/gui/gui-cursor.h ./src/gui/gui-filter.c ./src/gui/gui-filter.h ./src/gui/gui-focus.c @@ -87,26 +86,28 @@ ./src/gui/gui-line.c ./src/gui/gui-line.h ./src/gui/gui-main.h +./src/gui/gui-mouse.c +./src/gui/gui-mouse.h ./src/gui/gui-nicklist.c ./src/gui/gui-nicklist.h ./src/gui/gui-window.c ./src/gui/gui-window.h ./src/plugins/alias/alias.c -./src/plugins/alias/alias.h ./src/plugins/alias/alias-config.c ./src/plugins/alias/alias-config.h +./src/plugins/alias/alias.h ./src/plugins/alias/alias-info.c ./src/plugins/alias/alias-info.h -./src/plugins/aspell/weechat-aspell.c -./src/plugins/aspell/weechat-aspell.h ./src/plugins/aspell/weechat-aspell-bar-item.c ./src/plugins/aspell/weechat-aspell-bar-item.h +./src/plugins/aspell/weechat-aspell.c ./src/plugins/aspell/weechat-aspell-command.c ./src/plugins/aspell/weechat-aspell-command.h ./src/plugins/aspell/weechat-aspell-completion.c ./src/plugins/aspell/weechat-aspell-completion.h ./src/plugins/aspell/weechat-aspell-config.c ./src/plugins/aspell/weechat-aspell-config.h +./src/plugins/aspell/weechat-aspell.h ./src/plugins/aspell/weechat-aspell-info.c ./src/plugins/aspell/weechat-aspell-info.h ./src/plugins/aspell/weechat-aspell-speller.c @@ -166,12 +167,12 @@ ./src/plugins/irc/irc-sasl.h ./src/plugins/irc/irc-server.c ./src/plugins/irc/irc-server.h -./src/plugins/logger/logger.c -./src/plugins/logger/logger.h ./src/plugins/logger/logger-buffer.c ./src/plugins/logger/logger-buffer.h +./src/plugins/logger/logger.c ./src/plugins/logger/logger-config.c ./src/plugins/logger/logger-config.h +./src/plugins/logger/logger.h ./src/plugins/logger/logger-info.c ./src/plugins/logger/logger-info.h ./src/plugins/logger/logger-tail.c @@ -180,12 +181,28 @@ ./src/plugins/lua/weechat-lua-api.h ./src/plugins/lua/weechat-lua.c ./src/plugins/lua/weechat-lua.h +./src/plugins/perl/weechat-perl-api.c +./src/plugins/perl/weechat-perl-api.h +./src/plugins/perl/weechat-perl.c +./src/plugins/perl/weechat-perl.h ./src/plugins/plugin-api.c ./src/plugins/plugin-api.h ./src/plugins/plugin.c ./src/plugins/plugin-config.c ./src/plugins/plugin-config.h ./src/plugins/plugin.h +./src/plugins/plugin-script-api.c +./src/plugins/plugin-script-api.h +./src/plugins/plugin-script.c +./src/plugins/plugin-script-callback.c +./src/plugins/plugin-script-callback.h +./src/plugins/plugin-script.h +./src/plugins/python/weechat-python-api.c +./src/plugins/python/weechat-python-api.h +./src/plugins/python/weechat-python.c +./src/plugins/python/weechat-python.h +./src/plugins/relay/irc/relay-irc.c +./src/plugins/relay/irc/relay-irc.h ./src/plugins/relay/relay-buffer.c ./src/plugins/relay/relay-buffer.h ./src/plugins/relay/relay.c @@ -210,8 +227,6 @@ ./src/plugins/relay/relay-upgrade.h ./src/plugins/relay/relay-websocket.c ./src/plugins/relay/relay-websocket.h -./src/plugins/relay/irc/relay-irc.c -./src/plugins/relay/irc/relay-irc.h ./src/plugins/relay/weechat/relay-weechat.c ./src/plugins/relay/weechat/relay-weechat.h ./src/plugins/relay/weechat/relay-weechat-msg.c @@ -232,36 +247,22 @@ ./src/plugins/rmodifier/rmodifier.h ./src/plugins/rmodifier/rmodifier-info.c ./src/plugins/rmodifier/rmodifier-info.h -./src/plugins/perl/weechat-perl-api.c -./src/plugins/perl/weechat-perl-api.h -./src/plugins/perl/weechat-perl.c -./src/plugins/perl/weechat-perl.h -./src/plugins/plugin-script.c -./src/plugins/plugin-script.h -./src/plugins/plugin-script-api.c -./src/plugins/plugin-script-api.h -./src/plugins/plugin-script-callback.c -./src/plugins/plugin-script-callback.h -./src/plugins/python/weechat-python-api.c -./src/plugins/python/weechat-python-api.h -./src/plugins/python/weechat-python.c -./src/plugins/python/weechat-python.h ./src/plugins/ruby/weechat-ruby-api.c ./src/plugins/ruby/weechat-ruby-api.h ./src/plugins/ruby/weechat-ruby.c ./src/plugins/ruby/weechat-ruby.h -./src/plugins/script/script.c -./src/plugins/script/script.h ./src/plugins/script/script-action.c ./src/plugins/script/script-action.h ./src/plugins/script/script-buffer.c ./src/plugins/script/script-buffer.h +./src/plugins/script/script.c ./src/plugins/script/script-command.c ./src/plugins/script/script-command.h ./src/plugins/script/script-completion.c ./src/plugins/script/script-completion.h ./src/plugins/script/script-config.c ./src/plugins/script/script-config.h +./src/plugins/script/script.h ./src/plugins/script/script-info.c ./src/plugins/script/script-info.h ./src/plugins/script/script-repo.c @@ -270,6 +271,18 @@ ./src/plugins/tcl/weechat-tcl-api.h ./src/plugins/tcl/weechat-tcl.c ./src/plugins/tcl/weechat-tcl.h +./src/plugins/trigger/trigger.c +./src/plugins/trigger/trigger-buffer.c +./src/plugins/trigger/trigger-buffer.h +./src/plugins/trigger/trigger-callback.c +./src/plugins/trigger/trigger-callback.h +./src/plugins/trigger/trigger-command.c +./src/plugins/trigger/trigger-command.h +./src/plugins/trigger/trigger-completion.c +./src/plugins/trigger/trigger-completion.h +./src/plugins/trigger/trigger-config.c +./src/plugins/trigger/trigger-config.h +./src/plugins/trigger/trigger.h ./src/plugins/weechat-plugin.h ./src/plugins/xfer/xfer-buffer.c ./src/plugins/xfer/xfer-buffer.h @@ -286,11 +299,10 @@ ./src/plugins/xfer/xfer-dcc.h ./src/plugins/xfer/xfer-file.c ./src/plugins/xfer/xfer-file.h +./src/plugins/xfer/xfer.h ./src/plugins/xfer/xfer-info.c ./src/plugins/xfer/xfer-info.h -./src/plugins/xfer/xfer.h ./src/plugins/xfer/xfer-network.c ./src/plugins/xfer/xfer-network.h ./src/plugins/xfer/xfer-upgrade.c ./src/plugins/xfer/xfer-upgrade.h -./doc/docgen.py diff --git a/po/srcfiles.cmake b/po/srcfiles.cmake index d4af8b1ac..de4d5c2f9 100644 --- a/po/srcfiles.cmake +++ b/po/srcfiles.cmake @@ -1,4 +1,5 @@ SET(WEECHAT_SOURCES +./doc/docgen.py ./src/core/wee-backtrace.c ./src/core/wee-backtrace.h ./src/core/weechat.c @@ -34,9 +35,9 @@ SET(WEECHAT_SOURCES ./src/core/wee-string.c ./src/core/wee-string.h ./src/core/wee-upgrade.c -./src/core/wee-upgrade.h ./src/core/wee-upgrade-file.c ./src/core/wee-upgrade-file.h +./src/core/wee-upgrade.h ./src/core/wee-url.c ./src/core/wee-url.h ./src/core/wee-utf8.c @@ -65,10 +66,10 @@ SET(WEECHAT_SOURCES ./src/gui/gui-chat.h ./src/gui/gui-color.c ./src/gui/gui-color.h -./src/gui/gui-cursor.c -./src/gui/gui-cursor.h ./src/gui/gui-completion.c ./src/gui/gui-completion.h +./src/gui/gui-cursor.c +./src/gui/gui-cursor.h ./src/gui/gui-filter.c ./src/gui/gui-filter.h ./src/gui/gui-focus.c @@ -93,21 +94,21 @@ SET(WEECHAT_SOURCES ./src/gui/gui-window.c ./src/gui/gui-window.h ./src/plugins/alias/alias.c -./src/plugins/alias/alias.h ./src/plugins/alias/alias-config.c ./src/plugins/alias/alias-config.h +./src/plugins/alias/alias.h ./src/plugins/alias/alias-info.c ./src/plugins/alias/alias-info.h -./src/plugins/aspell/weechat-aspell.c -./src/plugins/aspell/weechat-aspell.h ./src/plugins/aspell/weechat-aspell-bar-item.c ./src/plugins/aspell/weechat-aspell-bar-item.h +./src/plugins/aspell/weechat-aspell.c ./src/plugins/aspell/weechat-aspell-command.c ./src/plugins/aspell/weechat-aspell-command.h ./src/plugins/aspell/weechat-aspell-completion.c ./src/plugins/aspell/weechat-aspell-completion.h ./src/plugins/aspell/weechat-aspell-config.c ./src/plugins/aspell/weechat-aspell-config.h +./src/plugins/aspell/weechat-aspell.h ./src/plugins/aspell/weechat-aspell-info.c ./src/plugins/aspell/weechat-aspell-info.h ./src/plugins/aspell/weechat-aspell-speller.c @@ -117,6 +118,10 @@ SET(WEECHAT_SOURCES ./src/plugins/fifo/fifo.h ./src/plugins/fifo/fifo-info.c ./src/plugins/fifo/fifo-info.h +./src/plugins/guile/weechat-guile-api.c +./src/plugins/guile/weechat-guile-api.h +./src/plugins/guile/weechat-guile.c +./src/plugins/guile/weechat-guile.h ./src/plugins/irc/irc-bar-item.c ./src/plugins/irc/irc-bar-item.h ./src/plugins/irc/irc-buffer.c @@ -163,22 +168,42 @@ SET(WEECHAT_SOURCES ./src/plugins/irc/irc-sasl.h ./src/plugins/irc/irc-server.c ./src/plugins/irc/irc-server.h -./src/plugins/logger/logger.c -./src/plugins/logger/logger.h ./src/plugins/logger/logger-buffer.c ./src/plugins/logger/logger-buffer.h +./src/plugins/logger/logger.c ./src/plugins/logger/logger-config.c ./src/plugins/logger/logger-config.h +./src/plugins/logger/logger.h ./src/plugins/logger/logger-info.c ./src/plugins/logger/logger-info.h ./src/plugins/logger/logger-tail.c ./src/plugins/logger/logger-tail.h +./src/plugins/lua/weechat-lua-api.c +./src/plugins/lua/weechat-lua-api.h +./src/plugins/lua/weechat-lua.c +./src/plugins/lua/weechat-lua.h +./src/plugins/perl/weechat-perl-api.c +./src/plugins/perl/weechat-perl-api.h +./src/plugins/perl/weechat-perl.c +./src/plugins/perl/weechat-perl.h ./src/plugins/plugin-api.c ./src/plugins/plugin-api.h ./src/plugins/plugin.c ./src/plugins/plugin-config.c ./src/plugins/plugin-config.h ./src/plugins/plugin.h +./src/plugins/plugin-script-api.c +./src/plugins/plugin-script-api.h +./src/plugins/plugin-script.c +./src/plugins/plugin-script-callback.c +./src/plugins/plugin-script-callback.h +./src/plugins/plugin-script.h +./src/plugins/python/weechat-python-api.c +./src/plugins/python/weechat-python-api.h +./src/plugins/python/weechat-python.c +./src/plugins/python/weechat-python.h +./src/plugins/relay/irc/relay-irc.c +./src/plugins/relay/irc/relay-irc.h ./src/plugins/relay/relay-buffer.c ./src/plugins/relay/relay-buffer.h ./src/plugins/relay/relay.c @@ -203,8 +228,6 @@ SET(WEECHAT_SOURCES ./src/plugins/relay/relay-upgrade.h ./src/plugins/relay/relay-websocket.c ./src/plugins/relay/relay-websocket.h -./src/plugins/relay/irc/relay-irc.c -./src/plugins/relay/irc/relay-irc.h ./src/plugins/relay/weechat/relay-weechat.c ./src/plugins/relay/weechat/relay-weechat.h ./src/plugins/relay/weechat/relay-weechat-msg.c @@ -225,44 +248,22 @@ SET(WEECHAT_SOURCES ./src/plugins/rmodifier/rmodifier.h ./src/plugins/rmodifier/rmodifier-info.c ./src/plugins/rmodifier/rmodifier-info.h -./src/plugins/guile/weechat-guile-api.c -./src/plugins/guile/weechat-guile-api.h -./src/plugins/guile/weechat-guile.c -./src/plugins/guile/weechat-guile.h -./src/plugins/lua/weechat-lua-api.c -./src/plugins/lua/weechat-lua-api.h -./src/plugins/lua/weechat-lua.c -./src/plugins/lua/weechat-lua.h -./src/plugins/perl/weechat-perl-api.c -./src/plugins/perl/weechat-perl-api.h -./src/plugins/perl/weechat-perl.c -./src/plugins/perl/weechat-perl.h -./src/plugins/plugin-script.c -./src/plugins/plugin-script.h -./src/plugins/plugin-script-api.c -./src/plugins/plugin-script-api.h -./src/plugins/plugin-script-callback.c -./src/plugins/plugin-script-callback.h -./src/plugins/python/weechat-python-api.c -./src/plugins/python/weechat-python-api.h -./src/plugins/python/weechat-python.c -./src/plugins/python/weechat-python.h ./src/plugins/ruby/weechat-ruby-api.c ./src/plugins/ruby/weechat-ruby-api.h ./src/plugins/ruby/weechat-ruby.c ./src/plugins/ruby/weechat-ruby.h -./src/plugins/script/script.c -./src/plugins/script/script.h ./src/plugins/script/script-action.c ./src/plugins/script/script-action.h ./src/plugins/script/script-buffer.c ./src/plugins/script/script-buffer.h +./src/plugins/script/script.c ./src/plugins/script/script-command.c ./src/plugins/script/script-command.h ./src/plugins/script/script-completion.c ./src/plugins/script/script-completion.h ./src/plugins/script/script-config.c ./src/plugins/script/script-config.h +./src/plugins/script/script.h ./src/plugins/script/script-info.c ./src/plugins/script/script-info.h ./src/plugins/script/script-repo.c @@ -271,6 +272,18 @@ SET(WEECHAT_SOURCES ./src/plugins/tcl/weechat-tcl-api.h ./src/plugins/tcl/weechat-tcl.c ./src/plugins/tcl/weechat-tcl.h +./src/plugins/trigger/trigger.c +./src/plugins/trigger/trigger-buffer.c +./src/plugins/trigger/trigger-buffer.h +./src/plugins/trigger/trigger-callback.c +./src/plugins/trigger/trigger-callback.h +./src/plugins/trigger/trigger-command.c +./src/plugins/trigger/trigger-command.h +./src/plugins/trigger/trigger-completion.c +./src/plugins/trigger/trigger-completion.h +./src/plugins/trigger/trigger-config.c +./src/plugins/trigger/trigger-config.h +./src/plugins/trigger/trigger.h ./src/plugins/weechat-plugin.h ./src/plugins/xfer/xfer-buffer.c ./src/plugins/xfer/xfer-buffer.h @@ -287,12 +300,11 @@ SET(WEECHAT_SOURCES ./src/plugins/xfer/xfer-dcc.h ./src/plugins/xfer/xfer-file.c ./src/plugins/xfer/xfer-file.h +./src/plugins/xfer/xfer.h ./src/plugins/xfer/xfer-info.c ./src/plugins/xfer/xfer-info.h -./src/plugins/xfer/xfer.h ./src/plugins/xfer/xfer-network.c ./src/plugins/xfer/xfer-network.h ./src/plugins/xfer/xfer-upgrade.c ./src/plugins/xfer/xfer-upgrade.h -./doc/docgen.py ) diff --git a/src/core/wee-command.c b/src/core/wee-command.c index d17330df2..6b7abc5c5 100644 --- a/src/core/wee-command.c +++ b/src/core/wee-command.c @@ -5011,13 +5011,14 @@ command_set_display_section (struct t_config_file *config_file, struct t_config_section *section) { gui_chat_printf (NULL, ""); - gui_chat_printf (NULL, "%s[%s%s%s]%s (%s)", - GUI_COLOR(GUI_COLOR_CHAT_DELIMITERS), - GUI_COLOR(GUI_COLOR_CHAT_BUFFER), - section->name, - GUI_COLOR(GUI_COLOR_CHAT_DELIMITERS), - GUI_COLOR(GUI_COLOR_CHAT), - config_file->filename); + gui_chat_printf_date_tags (NULL, 0, "no_trigger", + "%s[%s%s%s]%s (%s)", + GUI_COLOR(GUI_COLOR_CHAT_DELIMITERS), + GUI_COLOR(GUI_COLOR_CHAT_BUFFER), + section->name, + GUI_COLOR(GUI_COLOR_CHAT_DELIMITERS), + GUI_COLOR(GUI_COLOR_CHAT), + config_file->filename); } /* @@ -5054,7 +5055,8 @@ command_set_display_option (struct t_config_option *option, (CONFIG_BOOLEAN_DEFAULT(option)) ? "on" : "off"); display_default = str_default; } - gui_chat_printf_date_tags (NULL, 0, GUI_CHAT_TAG_NO_HIGHLIGHT, + gui_chat_printf_date_tags (NULL, 0, + "no_trigger," GUI_CHAT_TAG_NO_HIGHLIGHT, "%s%s.%s.%s%s = %s%s%s%s%s%s%s%s%s%s", (message) ? message : " ", option->config_file->name, @@ -5089,7 +5091,8 @@ command_set_display_option (struct t_config_option *option, } if (option->string_values) { - gui_chat_printf_date_tags (NULL, 0, GUI_CHAT_TAG_NO_HIGHLIGHT, + gui_chat_printf_date_tags (NULL, 0, + "no_trigger," GUI_CHAT_TAG_NO_HIGHLIGHT, "%s%s.%s.%s%s = %s%s%s%s%s%s%s%s%s%s", (message) ? message : " ", option->config_file->name, @@ -5109,7 +5112,8 @@ command_set_display_option (struct t_config_option *option, } else { - gui_chat_printf_date_tags (NULL, 0, GUI_CHAT_TAG_NO_HIGHLIGHT, + gui_chat_printf_date_tags (NULL, 0, + "no_trigger," GUI_CHAT_TAG_NO_HIGHLIGHT, "%s%s.%s.%s%s = %s%d%s%s%s%s%s%s%s%s", (message) ? message : " ", option->config_file->name, @@ -5134,7 +5138,8 @@ command_set_display_option (struct t_config_option *option, { display_default = CONFIG_STRING_DEFAULT(option); } - gui_chat_printf_date_tags (NULL, 0, GUI_CHAT_TAG_NO_HIGHLIGHT, + gui_chat_printf_date_tags (NULL, 0, + "no_trigger," GUI_CHAT_TAG_NO_HIGHLIGHT, "%s%s.%s.%s%s = \"%s%s%s\"%s%s%s%s%s%s%s%s%s%s%s", (message) ? message : " ", option->config_file->name, @@ -5167,7 +5172,8 @@ command_set_display_option (struct t_config_option *option, } } color_name = gui_color_get_name (CONFIG_COLOR(option)); - gui_chat_printf_date_tags (NULL, 0, GUI_CHAT_TAG_NO_HIGHLIGHT, + gui_chat_printf_date_tags (NULL, 0, + "no_trigger," GUI_CHAT_TAG_NO_HIGHLIGHT, "%s%s.%s.%s%s = %s%s%s%s%s%s%s%s%s%s", (message) ? message : " ", option->config_file->name, @@ -5192,7 +5198,8 @@ command_set_display_option (struct t_config_option *option, } else { - gui_chat_printf_date_tags (NULL, 0, GUI_CHAT_TAG_NO_HIGHLIGHT, + gui_chat_printf_date_tags (NULL, 0, + "no_trigger," GUI_CHAT_TAG_NO_HIGHLIGHT, "%s%s.%s.%s", (message) ? message : " ", option->config_file->name, diff --git a/src/core/wee-config.c b/src/core/wee-config.c index 0b45ee981..ae28760d8 100644 --- a/src/core/wee-config.c +++ b/src/core/wee-config.c @@ -1308,66 +1308,64 @@ config_weechat_proxy_read_cb (void *data, struct t_config_file *config_file, /* make C compiler happy */ (void) data; (void) config_file; - (void) section; - if (option_name) + if (!option_name) + return WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE; + + pos_option = strchr (option_name, '.'); + if (!pos_option) + return WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE; + + proxy_name = string_strndup (option_name, pos_option - option_name); + if (!proxy_name) + return WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE; + + pos_option++; + + /* search temporary proxy */ + for (ptr_temp_proxy = weechat_temp_proxies; ptr_temp_proxy; + ptr_temp_proxy = ptr_temp_proxy->next_proxy) + { + if (strcmp (ptr_temp_proxy->name, proxy_name) == 0) + break; + } + if (!ptr_temp_proxy) { - pos_option = strchr (option_name, '.'); - if (pos_option) + /* create new temporary proxy */ + ptr_temp_proxy = proxy_alloc (proxy_name); + if (ptr_temp_proxy) { - proxy_name = string_strndup (option_name, pos_option - option_name); - if (proxy_name) - { - pos_option++; - for (ptr_temp_proxy = weechat_temp_proxies; ptr_temp_proxy; - ptr_temp_proxy = ptr_temp_proxy->next_proxy) - { - if (strcmp (ptr_temp_proxy->name, proxy_name) == 0) - break; - } - if (!ptr_temp_proxy) - { - /* create new temp proxy */ - ptr_temp_proxy = proxy_alloc (proxy_name); - if (ptr_temp_proxy) - { - /* add new temp proxy at end of queue */ - ptr_temp_proxy->prev_proxy = last_weechat_temp_proxy; - ptr_temp_proxy->next_proxy = NULL; - - if (!weechat_temp_proxies) - weechat_temp_proxies = ptr_temp_proxy; - else - last_weechat_temp_proxy->next_proxy = ptr_temp_proxy; - last_weechat_temp_proxy = ptr_temp_proxy; - } - } - - if (ptr_temp_proxy) - { - index_option = proxy_search_option (pos_option); - if (index_option >= 0) - { - proxy_create_option_temp (ptr_temp_proxy, index_option, - value); - } - else - { - gui_chat_printf (NULL, - _("%sWarning: unknown option for " - "section \"%s\": %s (value: \"%s\")"), - gui_chat_prefix[GUI_CHAT_PREFIX_ERROR], - section->name, - option_name, - value); - } - } + /* add new proxy at the end */ + ptr_temp_proxy->prev_proxy = last_weechat_temp_proxy; + ptr_temp_proxy->next_proxy = NULL; + if (!weechat_temp_proxies) + weechat_temp_proxies = ptr_temp_proxy; + else + last_weechat_temp_proxy->next_proxy = ptr_temp_proxy; + last_weechat_temp_proxy = ptr_temp_proxy; + } + } - free (proxy_name); - } + if (ptr_temp_proxy) + { + index_option = proxy_search_option (pos_option); + if (index_option >= 0) + { + proxy_create_option_temp (ptr_temp_proxy, index_option, + value); + } + else + { + gui_chat_printf (NULL, + _("%sWarning: unknown option for section \"%s\": " + "%s (value: \"%s\")"), + gui_chat_prefix[GUI_CHAT_PREFIX_ERROR], + section->name, option_name, value); } } + free (proxy_name); + return WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE; } @@ -1389,64 +1387,63 @@ config_weechat_bar_read_cb (void *data, struct t_config_file *config_file, (void) config_file; (void) section; - if (option_name) + if (!option_name) + return WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE; + + pos_option = strchr (option_name, '.'); + if (!pos_option) + return WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE; + + bar_name = string_strndup (option_name, pos_option - option_name); + if (!bar_name) + return WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE; + + pos_option++; + + /* search temporary bar */ + for (ptr_temp_bar = gui_temp_bars; ptr_temp_bar; + ptr_temp_bar = ptr_temp_bar->next_bar) + { + if (strcmp (ptr_temp_bar->name, bar_name) == 0) + break; + } + if (!ptr_temp_bar) { - pos_option = strchr (option_name, '.'); - if (pos_option) + /* create new temporary bar */ + ptr_temp_bar = gui_bar_alloc (bar_name); + if (ptr_temp_bar) { - bar_name = string_strndup (option_name, pos_option - option_name); - if (bar_name) - { - pos_option++; - for (ptr_temp_bar = gui_temp_bars; ptr_temp_bar; - ptr_temp_bar = ptr_temp_bar->next_bar) - { - if (strcmp (ptr_temp_bar->name, bar_name) == 0) - break; - } - if (!ptr_temp_bar) - { - /* create new temp bar */ - ptr_temp_bar = gui_bar_alloc (bar_name); - if (ptr_temp_bar) - { - /* add new temp bar at end of queue */ - ptr_temp_bar->prev_bar = last_gui_temp_bar; - ptr_temp_bar->next_bar = NULL; - - if (!gui_temp_bars) - gui_temp_bars = ptr_temp_bar; - else - last_gui_temp_bar->next_bar = ptr_temp_bar; - last_gui_temp_bar = ptr_temp_bar; - } - } - - if (ptr_temp_bar) - { - index_option = gui_bar_search_option (pos_option); - if (index_option >= 0) - { - gui_bar_create_option_temp (ptr_temp_bar, index_option, - value); - } - else - { - gui_chat_printf (NULL, - _("%sWarning: unknown option for " - "section \"%s\": %s (value: \"%s\")"), - gui_chat_prefix[GUI_CHAT_PREFIX_ERROR], - section->name, - option_name, - value); - } - } + /* add new bar at the end */ + ptr_temp_bar->prev_bar = last_gui_temp_bar; + ptr_temp_bar->next_bar = NULL; + if (!gui_temp_bars) + gui_temp_bars = ptr_temp_bar; + else + last_gui_temp_bar->next_bar = ptr_temp_bar; + last_gui_temp_bar = ptr_temp_bar; + } + } - free (bar_name); - } + if (ptr_temp_bar) + { + index_option = gui_bar_search_option (pos_option); + if (index_option >= 0) + { + gui_bar_create_option_temp (ptr_temp_bar, index_option, + value); + } + else + { + gui_chat_printf (NULL, + _("%sWarning: unknown option for section \"%s\": " + "%s (value: \"%s\")"), + gui_chat_prefix[GUI_CHAT_PREFIX_ERROR], + section->name, option_name, value); } } + free (bar_name); + return WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE; } diff --git a/src/core/wee-proxy.c b/src/core/wee-proxy.c index 7fc81ccf8..08b6190a4 100644 --- a/src/core/wee-proxy.c +++ b/src/core/wee-proxy.c @@ -294,69 +294,70 @@ proxy_create_option (const char *proxy_name, int index_option, length = strlen (proxy_name) + 1 + strlen (proxy_option_string[index_option]) + 1; option_name = malloc (length); - if (option_name) - { - snprintf (option_name, length, "%s.%s", - proxy_name, proxy_option_string[index_option]); + if (!option_name) + return NULL; - switch (index_option) - { - case PROXY_OPTION_TYPE: - ptr_option = config_file_new_option ( - weechat_config_file, weechat_config_section_proxy, - option_name, "integer", - N_("proxy type (http (default), socks4, socks5)"), - "http|socks4|socks5", 0, 0, value, NULL, 0, - NULL, NULL, NULL, NULL, NULL, NULL); - break; - case PROXY_OPTION_IPV6: - ptr_option = config_file_new_option ( - weechat_config_file, weechat_config_section_proxy, - option_name, "boolean", - N_("connect to proxy using ipv6"), - NULL, 0, 0, value, NULL, 0, - NULL, NULL, NULL, NULL, NULL, NULL); - break; - case PROXY_OPTION_ADDRESS: - ptr_option = config_file_new_option ( - weechat_config_file, weechat_config_section_proxy, - option_name, "string", - N_("proxy server address (IP or hostname)"), - NULL, 0, 0, value, NULL, 0, - NULL, NULL, NULL, NULL, NULL, NULL); - break; - case PROXY_OPTION_PORT: - ptr_option = config_file_new_option ( - weechat_config_file, weechat_config_section_proxy, - option_name, "integer", - N_("port for connecting to proxy server"), - NULL, 0, 65535, value, NULL, 0, - NULL, NULL, NULL, NULL, NULL, NULL); - break; - case PROXY_OPTION_USERNAME: - ptr_option = config_file_new_option ( - weechat_config_file, weechat_config_section_proxy, - option_name, "string", - N_("username for proxy server " - "(note: content is evaluated, see /help eval)"), - NULL, 0, 0, value, NULL, 0, - NULL, NULL, NULL, NULL, NULL, NULL); - break; - case PROXY_OPTION_PASSWORD: - ptr_option = config_file_new_option ( - weechat_config_file, weechat_config_section_proxy, - option_name, "string", - N_("password for proxy server " - "(note: content is evaluated, see /help eval)"), - NULL, 0, 0, value, NULL, 0, - NULL, NULL, NULL, NULL, NULL, NULL); - break; - case PROXY_NUM_OPTIONS: - break; - } - free (option_name); + snprintf (option_name, length, "%s.%s", + proxy_name, proxy_option_string[index_option]); + + switch (index_option) + { + case PROXY_OPTION_TYPE: + ptr_option = config_file_new_option ( + weechat_config_file, weechat_config_section_proxy, + option_name, "integer", + N_("proxy type (http (default), socks4, socks5)"), + "http|socks4|socks5", 0, 0, value, NULL, 0, + NULL, NULL, NULL, NULL, NULL, NULL); + break; + case PROXY_OPTION_IPV6: + ptr_option = config_file_new_option ( + weechat_config_file, weechat_config_section_proxy, + option_name, "boolean", + N_("connect to proxy using ipv6"), + NULL, 0, 0, value, NULL, 0, + NULL, NULL, NULL, NULL, NULL, NULL); + break; + case PROXY_OPTION_ADDRESS: + ptr_option = config_file_new_option ( + weechat_config_file, weechat_config_section_proxy, + option_name, "string", + N_("proxy server address (IP or hostname)"), + NULL, 0, 0, value, NULL, 0, + NULL, NULL, NULL, NULL, NULL, NULL); + break; + case PROXY_OPTION_PORT: + ptr_option = config_file_new_option ( + weechat_config_file, weechat_config_section_proxy, + option_name, "integer", + N_("port for connecting to proxy server"), + NULL, 0, 65535, value, NULL, 0, + NULL, NULL, NULL, NULL, NULL, NULL); + break; + case PROXY_OPTION_USERNAME: + ptr_option = config_file_new_option ( + weechat_config_file, weechat_config_section_proxy, + option_name, "string", + N_("username for proxy server " + "(note: content is evaluated, see /help eval)"), + NULL, 0, 0, value, NULL, 0, + NULL, NULL, NULL, NULL, NULL, NULL); + break; + case PROXY_OPTION_PASSWORD: + ptr_option = config_file_new_option ( + weechat_config_file, weechat_config_section_proxy, + option_name, "string", + N_("password for proxy server " + "(note: content is evaluated, see /help eval)"), + NULL, 0, 0, value, NULL, 0, + NULL, NULL, NULL, NULL, NULL, NULL); + break; + case PROXY_NUM_OPTIONS: + break; } + free (option_name); + return ptr_option; } @@ -423,24 +424,24 @@ proxy_new_with_options (const char *name, /* create proxy */ new_proxy = proxy_alloc (name); - if (new_proxy) - { - new_proxy->options[PROXY_OPTION_TYPE] = type; - new_proxy->options[PROXY_OPTION_IPV6] = ipv6; - new_proxy->options[PROXY_OPTION_ADDRESS] = address; - new_proxy->options[PROXY_OPTION_PORT] = port; - new_proxy->options[PROXY_OPTION_USERNAME] = username; - new_proxy->options[PROXY_OPTION_PASSWORD] = password; - - /* add proxy to proxies list */ - new_proxy->prev_proxy = last_weechat_proxy; - if (weechat_proxies) - last_weechat_proxy->next_proxy = new_proxy; - else - weechat_proxies = new_proxy; - last_weechat_proxy = new_proxy; - new_proxy->next_proxy = NULL; - } + if (!new_proxy) + return NULL; + + new_proxy->options[PROXY_OPTION_TYPE] = type; + new_proxy->options[PROXY_OPTION_IPV6] = ipv6; + new_proxy->options[PROXY_OPTION_ADDRESS] = address; + new_proxy->options[PROXY_OPTION_PORT] = port; + new_proxy->options[PROXY_OPTION_USERNAME] = username; + new_proxy->options[PROXY_OPTION_PASSWORD] = password; + + /* add proxy to proxies list */ + new_proxy->prev_proxy = last_weechat_proxy; + if (weechat_proxies) + last_weechat_proxy->next_proxy = new_proxy; + else + weechat_proxies = new_proxy; + last_weechat_proxy = new_proxy; + new_proxy->next_proxy = NULL; return new_proxy; } diff --git a/src/core/wee-string.c b/src/core/wee-string.c index ab29d9632..c19215c4a 100644 --- a/src/core/wee-string.c +++ b/src/core/wee-string.c @@ -947,13 +947,13 @@ string_regex_flags (const char *regex, int default_flags, int *flags) */ int -string_regcomp (void *preg, const char *regex, int default_flags) +string_regcomp (regex_t *preg, const char *regex, int default_flags) { const char *ptr_regex; int flags; ptr_regex = string_regex_flags (regex, default_flags, &flags); - return regcomp ((regex_t *)preg, ptr_regex, flags); + return regcomp (preg, ptr_regex, flags); } /* @@ -1144,6 +1144,221 @@ string_has_highlight_regex (const char *string, const char *regex) return rc; } +/* + * Get replacement string for a regex, using array of "match" + * (for more info, see function "string_replace_regex"). + * + * Note: result must be freed after use. + */ + +char * +string_replace_regex_get_replace (const char *string, regmatch_t *regex_match, + const char *replace) +{ + int length, length_current, length_add, match; + const char *ptr_replace, *ptr_add; + char *result, *result2, *modified_replace, *temp; + + /* default length is length*2, it will grow later if needed */ + length = (strlen (string) * 2); + result = malloc (length + 1); + if (!result) + return NULL; + + result[0] = '\0'; + length_current = 0; + ptr_replace = replace; + while (ptr_replace && ptr_replace[0]) + { + ptr_add = NULL; + length_add = 0; + modified_replace = NULL; + + if (ptr_replace[0] == '\\') + { + if (ptr_replace[1] == '\\') + { + ptr_add = ptr_replace; + length_add = 1; + ptr_replace += 2; + } + else if (isdigit ((unsigned char)ptr_replace[1])) + { + match = ptr_replace[1] - '0'; + if (regex_match[match].rm_so >= 0) + { + ptr_add = string + regex_match[match].rm_so; + length_add = regex_match[match].rm_eo - regex_match[match].rm_so; + } + ptr_replace += 2; + } + else if ((ptr_replace[1] >= 32) + && (ptr_replace[1] <= 126) + && isdigit ((unsigned char)ptr_replace[2])) + { + match = ptr_replace[2] - '0'; + if (regex_match[match].rm_so >= 0) + { + temp = string_strndup (string + regex_match[match].rm_so, + regex_match[match].rm_eo - regex_match[match].rm_so); + if (temp) + { + length_add = utf8_strlen (temp); + modified_replace = malloc (length_add + 1); + if (modified_replace) + { + memset (modified_replace, ptr_replace[1], + length_add); + modified_replace[length_add] = '\0'; + ptr_add = modified_replace; + } + free (temp); + } + } + ptr_replace += 3; + } + else + { + /* just ignore the '\' */ + ptr_replace++; + } + } + else + { + ptr_add = ptr_replace; + length_add = utf8_char_size (ptr_replace); + ptr_replace += length_add; + } + + if (ptr_add) + { + if (length_current + length_add > length) + { + length = (length * 2 >= length_current + length_add) ? + length * 2 : length_current + length_add; + result2 = realloc (result, length + 1); + if (!result2) + { + if (modified_replace) + free (modified_replace); + free (result); + return NULL; + } + result = result2; + } + memcpy (result + length_current, ptr_add, length_add); + length_current += length_add; + result[length_current] = '\0'; + } + if (modified_replace) + free (modified_replace); + } + + return result; +} + +/* + * Replaces a string by new one in a string, using a regular expression for + * searching string. + * + * The argument "regex" is a pointer to a regex compiled with function regcomp + * (or WeeChat function string_regcomp). + * + * The argument "replace" can contain references to matching groups, from \1 + * to \9 for match 1 to 9 (\0 is the whole match). + * Special references \c0 to \c9 can be used to replace all matching chars by + * the char 'c', which can be between space (32) and '~' (126). + * For example \*1 will replace matching chars in group 1 by '*'. + * + * Note: result must be freed after use. + */ + +char * +string_replace_regex (const char *string, regex_t *regex, const char *replace) +{ + char *result, *result2, *str_replace; + int length, length_replace, start_offset, i, rc, end; + regmatch_t regex_match[10]; + + if (!string) + return NULL; + + length = strlen (string) + 1; + result = malloc (length); + if (!result) + return NULL; + snprintf (result, length, "%s", string); + + start_offset = 0; + while (result && result[start_offset]) + { + for (i = 0; i < 10; i++) + { + regex_match[i].rm_so = -1; + } + + rc = regexec (regex, result + start_offset, 10, regex_match, 0); + /* + * no match found: exit the loop (if rm_eo == 0, it is an empty match + * at beginning of string: we consider there is no match, to prevent an + * infinite loop) + */ + if ((rc != 0) + || (regex_match[0].rm_so < 0) || (regex_match[0].rm_eo <= 0)) + { + break; + } + + /* adjust the start/end offsets */ + for (i = 0; i < 10; i++) + { + if (regex_match[i].rm_so >= 0) + { + regex_match[i].rm_so += start_offset; + regex_match[i].rm_eo += start_offset; + } + } + + /* check if the regex matched the end of string */ + end = !result[regex_match[0].rm_eo]; + + str_replace = string_replace_regex_get_replace (result, regex_match, + replace); + length_replace = (str_replace) ? strlen (str_replace) : 0; + + length = regex_match[0].rm_so + length_replace + + strlen (result + regex_match[0].rm_eo) + 1; + result2 = malloc (length); + if (!result2) + { + free (result); + return NULL; + } + result2[0] = '\0'; + if (regex_match[0].rm_so > 0) + { + memcpy (result2, result, regex_match[0].rm_so); + result2[regex_match[0].rm_so] = '\0'; + } + if (str_replace) + strcat (result2, str_replace); + strcat (result2, result + regex_match[0].rm_eo); + + free (result); + result = result2; + + if (str_replace) + free (str_replace); + + if (end) + break; + + start_offset = regex_match[0].rm_so + length_replace; + } + + return result; +} + /* * Splits a string according to separators. * diff --git a/src/core/wee-string.h b/src/core/wee-string.h index 9a7c5d76b..99276217e 100644 --- a/src/core/wee-string.h +++ b/src/core/wee-string.h @@ -51,12 +51,14 @@ extern char *string_convert_escaped_chars (const char *string); extern char *string_mask_to_regex (const char *mask); extern const char *string_regex_flags (const char *regex, int default_flags, int *flags); -extern int string_regcomp (void *preg, const char *regex, int default_flags); +extern int string_regcomp (regex_t *preg, const char *regex, int default_flags); extern int string_has_highlight (const char *string, const char *highlight_words); extern int string_has_highlight_regex_compiled (const char *string, regex_t *regex); extern int string_has_highlight_regex (const char *string, const char *regex); +extern char *string_replace_regex (const char *string, regex_t *regex, + const char *replace); extern char **string_split (const char *string, const char *separators, int keep_eol, int num_items_max, int *num_items); extern char **string_split_shared (const char *string, const char *separators, diff --git a/src/gui/gui-bar.c b/src/gui/gui-bar.c index 4a48124c8..2d255ba8c 100644 --- a/src/gui/gui-bar.c +++ b/src/gui/gui-bar.c @@ -1368,157 +1368,157 @@ gui_bar_create_option (const char *bar_name, int index_option, const char *value length = strlen (bar_name) + 1 + strlen (gui_bar_option_string[index_option]) + 1; option_name = malloc (length); - if (option_name) - { - snprintf (option_name, length, "%s.%s", - bar_name, gui_bar_option_string[index_option]); + if (!option_name) + return NULL; - switch (index_option) - { - case GUI_BAR_OPTION_HIDDEN: - ptr_option = config_file_new_option ( - weechat_config_file, weechat_config_section_bar, - option_name, "boolean", - N_("true if bar is hidden, false if it is displayed"), - NULL, 0, 0, value, NULL, 0, - NULL, NULL, &gui_bar_config_change_hidden, NULL, NULL, NULL); - break; - case GUI_BAR_OPTION_PRIORITY: - ptr_option = config_file_new_option ( - weechat_config_file, weechat_config_section_bar, - option_name, "integer", - N_("bar priority (high number means bar displayed first)"), - NULL, 0, INT_MAX, value, NULL, 0, - NULL, NULL, &gui_bar_config_change_priority, NULL, NULL, NULL); - break; - case GUI_BAR_OPTION_TYPE: - ptr_option = config_file_new_option ( - weechat_config_file, weechat_config_section_bar, - option_name, "integer", - N_("bar type (root, window, window_active, window_inactive)"), - "root|window|window_active|window_inactive", 0, 0, value, NULL, 0, - &gui_bar_config_check_type, NULL, NULL, NULL, NULL, NULL); - break; - case GUI_BAR_OPTION_CONDITIONS: - ptr_option = config_file_new_option ( - weechat_config_file, weechat_config_section_bar, - option_name, "string", - N_("condition(s) for displaying bar (for bars of type " - "\"window\"): a simple condition: \"active\", " - "\"inactive\", \"nicklist\" (window must be active/" - "inactive, buffer must have a nicklist), or an " - "expression with condition(s) (see /help eval), like: " - "\"${nicklist} && ${window.win_width} > 100\" " - "(local variables for expression are ${active}, " - "${inactive} and ${nicklist})"), - NULL, 0, 0, value, NULL, 0, - NULL, NULL, &gui_bar_config_change_conditions, NULL, NULL, NULL); - break; - case GUI_BAR_OPTION_POSITION: - ptr_option = config_file_new_option ( - weechat_config_file, weechat_config_section_bar, - option_name, "integer", - N_("bar position (bottom, top, left, right)"), - "bottom|top|left|right", 0, 0, value, NULL, 0, - NULL, NULL, &gui_bar_config_change_position, NULL, NULL, NULL); - break; - case GUI_BAR_OPTION_FILLING_TOP_BOTTOM: - ptr_option = config_file_new_option ( - weechat_config_file, weechat_config_section_bar, - option_name, "integer", - N_("bar filling direction (\"horizontal\" (from left to " - "right) or \"vertical\" (from top to bottom)) when bar " - "position is top or bottom"), - "horizontal|vertical|columns_horizontal|columns_vertical", - 0, 0, value, NULL, 0, - NULL, NULL, &gui_bar_config_change_filling, NULL, NULL, NULL); - break; - case GUI_BAR_OPTION_FILLING_LEFT_RIGHT: - ptr_option = config_file_new_option ( - weechat_config_file, weechat_config_section_bar, - option_name, "integer", - N_("bar filling direction (\"horizontal\" (from left to " - "right) or \"vertical\" (from top to bottom)) when bar " - "position is left or right"), - "horizontal|vertical|columns_horizontal|columns_vertical", - 0, 0, value, NULL, 0, - NULL, NULL, &gui_bar_config_change_filling, NULL, NULL, NULL); - break; - case GUI_BAR_OPTION_SIZE: - ptr_option = config_file_new_option ( - weechat_config_file, weechat_config_section_bar, - option_name, "integer", - N_("bar size in chars (0 = auto size)"), - NULL, 0, INT_MAX, value, NULL, 0, - &gui_bar_config_check_size, NULL, - &gui_bar_config_change_size, NULL, - NULL, NULL); - break; - case GUI_BAR_OPTION_SIZE_MAX: - ptr_option = config_file_new_option ( - weechat_config_file, weechat_config_section_bar, - option_name, "integer", - N_("max bar size in chars (0 = no limit)"), - NULL, 0, INT_MAX, value, NULL, 0, - NULL, NULL, - &gui_bar_config_change_size_max, NULL, - NULL, NULL); - break; - case GUI_BAR_OPTION_COLOR_FG: - ptr_option = config_file_new_option ( - weechat_config_file, weechat_config_section_bar, - option_name, "color", - N_("default text color for bar"), - NULL, 0, 0, value, NULL, 0, - NULL, NULL, - &gui_bar_config_change_color, NULL, - NULL, NULL); - break; - case GUI_BAR_OPTION_COLOR_DELIM: - ptr_option = config_file_new_option ( - weechat_config_file, weechat_config_section_bar, - option_name, "color", - N_("default delimiter color for bar"), - NULL, 0, 0, value, NULL, 0, - NULL, NULL, - &gui_bar_config_change_color, NULL, - NULL, NULL); - break; - case GUI_BAR_OPTION_COLOR_BG: - ptr_option = config_file_new_option ( - weechat_config_file, weechat_config_section_bar, - option_name, "color", - N_("default background color for bar"), - NULL, 0, 0, value, NULL, 0, - NULL, NULL, - &gui_bar_config_change_color, NULL, - NULL, NULL); - break; - case GUI_BAR_OPTION_SEPARATOR: - ptr_option = config_file_new_option ( - weechat_config_file, weechat_config_section_bar, - option_name, "boolean", - N_("separator line between bar and other bars/windows"), - NULL, 0, 0, value, NULL, 0, - NULL, NULL, &gui_bar_config_change_separator, NULL, NULL, NULL); - break; - case GUI_BAR_OPTION_ITEMS: - ptr_option = config_file_new_option ( - weechat_config_file, weechat_config_section_bar, - option_name, "string", - N_("items of bar, they can be separated by comma (space " - "between items) or \"+\" (glued items); special syntax " - "\"@buffer:item\" can be used to force buffer used when " - "displaying the bar item"), - NULL, 0, 0, gui_bar_default_items (bar_name), value, 0, - NULL, NULL, &gui_bar_config_change_items, NULL, NULL, NULL); - break; - case GUI_BAR_NUM_OPTIONS: - break; - } - free (option_name); + snprintf (option_name, length, "%s.%s", + bar_name, gui_bar_option_string[index_option]); + + switch (index_option) + { + case GUI_BAR_OPTION_HIDDEN: + ptr_option = config_file_new_option ( + weechat_config_file, weechat_config_section_bar, + option_name, "boolean", + N_("true if bar is hidden, false if it is displayed"), + NULL, 0, 0, value, NULL, 0, + NULL, NULL, &gui_bar_config_change_hidden, NULL, NULL, NULL); + break; + case GUI_BAR_OPTION_PRIORITY: + ptr_option = config_file_new_option ( + weechat_config_file, weechat_config_section_bar, + option_name, "integer", + N_("bar priority (high number means bar displayed first)"), + NULL, 0, INT_MAX, value, NULL, 0, + NULL, NULL, &gui_bar_config_change_priority, NULL, NULL, NULL); + break; + case GUI_BAR_OPTION_TYPE: + ptr_option = config_file_new_option ( + weechat_config_file, weechat_config_section_bar, + option_name, "integer", + N_("bar type (root, window, window_active, window_inactive)"), + "root|window|window_active|window_inactive", 0, 0, value, NULL, 0, + &gui_bar_config_check_type, NULL, NULL, NULL, NULL, NULL); + break; + case GUI_BAR_OPTION_CONDITIONS: + ptr_option = config_file_new_option ( + weechat_config_file, weechat_config_section_bar, + option_name, "string", + N_("condition(s) for displaying bar (for bars of type " + "\"window\"): a simple condition: \"active\", \"inactive\", " + "\"nicklist\" (window must be active/inactive, buffer must " + "have a nicklist), or an expression with condition(s) (see " + "/help eval), like: \"${nicklist} && ${window.win_width} > " + "100\" (local variables for expression are ${active}, " + "${inactive} and ${nicklist})"), + NULL, 0, 0, value, NULL, 0, + NULL, NULL, &gui_bar_config_change_conditions, NULL, NULL, NULL); + break; + case GUI_BAR_OPTION_POSITION: + ptr_option = config_file_new_option ( + weechat_config_file, weechat_config_section_bar, + option_name, "integer", + N_("bar position (bottom, top, left, right)"), + "bottom|top|left|right", 0, 0, value, NULL, 0, + NULL, NULL, &gui_bar_config_change_position, NULL, NULL, NULL); + break; + case GUI_BAR_OPTION_FILLING_TOP_BOTTOM: + ptr_option = config_file_new_option ( + weechat_config_file, weechat_config_section_bar, + option_name, "integer", + N_("bar filling direction (\"horizontal\" (from left to right) " + "or \"vertical\" (from top to bottom)) when bar position is " + "top or bottom"), + "horizontal|vertical|columns_horizontal|columns_vertical", + 0, 0, value, NULL, 0, + NULL, NULL, &gui_bar_config_change_filling, NULL, NULL, NULL); + break; + case GUI_BAR_OPTION_FILLING_LEFT_RIGHT: + ptr_option = config_file_new_option ( + weechat_config_file, weechat_config_section_bar, + option_name, "integer", + N_("bar filling direction (\"horizontal\" (from left to right) " + "or \"vertical\" (from top to bottom)) when bar position is " + "left or right"), + "horizontal|vertical|columns_horizontal|columns_vertical", + 0, 0, value, NULL, 0, + NULL, NULL, &gui_bar_config_change_filling, NULL, NULL, NULL); + break; + case GUI_BAR_OPTION_SIZE: + ptr_option = config_file_new_option ( + weechat_config_file, weechat_config_section_bar, + option_name, "integer", + N_("bar size in chars (0 = auto size)"), + NULL, 0, INT_MAX, value, NULL, 0, + &gui_bar_config_check_size, NULL, + &gui_bar_config_change_size, NULL, + NULL, NULL); + break; + case GUI_BAR_OPTION_SIZE_MAX: + ptr_option = config_file_new_option ( + weechat_config_file, weechat_config_section_bar, + option_name, "integer", + N_("max bar size in chars (0 = no limit)"), + NULL, 0, INT_MAX, value, NULL, 0, + NULL, NULL, + &gui_bar_config_change_size_max, NULL, + NULL, NULL); + break; + case GUI_BAR_OPTION_COLOR_FG: + ptr_option = config_file_new_option ( + weechat_config_file, weechat_config_section_bar, + option_name, "color", + N_("default text color for bar"), + NULL, 0, 0, value, NULL, 0, + NULL, NULL, + &gui_bar_config_change_color, NULL, + NULL, NULL); + break; + case GUI_BAR_OPTION_COLOR_DELIM: + ptr_option = config_file_new_option ( + weechat_config_file, weechat_config_section_bar, + option_name, "color", + N_("default delimiter color for bar"), + NULL, 0, 0, value, NULL, 0, + NULL, NULL, + &gui_bar_config_change_color, NULL, + NULL, NULL); + break; + case GUI_BAR_OPTION_COLOR_BG: + ptr_option = config_file_new_option ( + weechat_config_file, weechat_config_section_bar, + option_name, "color", + N_("default background color for bar"), + NULL, 0, 0, value, NULL, 0, + NULL, NULL, + &gui_bar_config_change_color, NULL, + NULL, NULL); + break; + case GUI_BAR_OPTION_SEPARATOR: + ptr_option = config_file_new_option ( + weechat_config_file, weechat_config_section_bar, + option_name, "boolean", + N_("separator line between bar and other bars/windows"), + NULL, 0, 0, value, NULL, 0, + NULL, NULL, &gui_bar_config_change_separator, NULL, NULL, NULL); + break; + case GUI_BAR_OPTION_ITEMS: + ptr_option = config_file_new_option ( + weechat_config_file, weechat_config_section_bar, + option_name, "string", + N_("items of bar, they can be separated by comma (space " + "between items) or \"+\" (glued items); special syntax " + "\"@buffer:item\" can be used to force buffer used when " + "displaying the bar item"), + NULL, 0, 0, gui_bar_default_items (bar_name), value, 0, + NULL, NULL, &gui_bar_config_change_items, NULL, NULL, NULL); + break; + case GUI_BAR_NUM_OPTIONS: + break; } + free (option_name); + return ptr_option; } @@ -1535,53 +1535,10 @@ gui_bar_create_option_temp (struct t_gui_bar *temp_bar, int index_option, new_option = gui_bar_create_option (temp_bar->name, index_option, value); - if (new_option) + if (new_option + && (index_option >= 0) && (index_option < GUI_BAR_NUM_OPTIONS)) { - switch (index_option) - { - case GUI_BAR_OPTION_HIDDEN: - temp_bar->options[GUI_BAR_OPTION_HIDDEN] = new_option; - break; - case GUI_BAR_OPTION_PRIORITY: - temp_bar->options[GUI_BAR_OPTION_PRIORITY] = new_option; - break; - case GUI_BAR_OPTION_TYPE: - temp_bar->options[GUI_BAR_OPTION_TYPE] = new_option; - break; - case GUI_BAR_OPTION_CONDITIONS: - temp_bar->options[GUI_BAR_OPTION_CONDITIONS] = new_option; - break; - case GUI_BAR_OPTION_POSITION: - temp_bar->options[GUI_BAR_OPTION_POSITION] = new_option; - break; - case GUI_BAR_OPTION_FILLING_TOP_BOTTOM: - temp_bar->options[GUI_BAR_OPTION_FILLING_TOP_BOTTOM] = new_option; - break; - case GUI_BAR_OPTION_FILLING_LEFT_RIGHT: - temp_bar->options[GUI_BAR_OPTION_FILLING_LEFT_RIGHT] = new_option; - break; - case GUI_BAR_OPTION_SIZE: - temp_bar->options[GUI_BAR_OPTION_SIZE] = new_option; - break; - case GUI_BAR_OPTION_SIZE_MAX: - temp_bar->options[GUI_BAR_OPTION_SIZE_MAX] = new_option; - break; - case GUI_BAR_OPTION_COLOR_FG: - temp_bar->options[GUI_BAR_OPTION_COLOR_FG] = new_option; - break; - case GUI_BAR_OPTION_COLOR_DELIM: - temp_bar->options[GUI_BAR_OPTION_COLOR_DELIM] = new_option; - break; - case GUI_BAR_OPTION_COLOR_BG: - temp_bar->options[GUI_BAR_OPTION_COLOR_BG] = new_option; - break; - case GUI_BAR_OPTION_SEPARATOR: - temp_bar->options[GUI_BAR_OPTION_SEPARATOR] = new_option; - break; - case GUI_BAR_OPTION_ITEMS: - temp_bar->options[GUI_BAR_OPTION_ITEMS] = new_option; - break; - } + temp_bar->options[index_option] = new_option; } } @@ -1648,51 +1605,51 @@ gui_bar_new_with_options (const char *name, /* create bar */ new_bar = gui_bar_alloc (name); - if (new_bar) - { - new_bar->options[GUI_BAR_OPTION_HIDDEN] = hidden; - new_bar->options[GUI_BAR_OPTION_PRIORITY] = priority; - new_bar->options[GUI_BAR_OPTION_TYPE] = type; - new_bar->options[GUI_BAR_OPTION_CONDITIONS] = conditions; - new_bar->options[GUI_BAR_OPTION_POSITION] = position; - new_bar->options[GUI_BAR_OPTION_FILLING_TOP_BOTTOM] = filling_top_bottom; - new_bar->options[GUI_BAR_OPTION_FILLING_LEFT_RIGHT] = filling_left_right; - new_bar->options[GUI_BAR_OPTION_SIZE] = size; - new_bar->options[GUI_BAR_OPTION_SIZE_MAX] = size_max; - new_bar->options[GUI_BAR_OPTION_COLOR_FG] = color_fg; - new_bar->options[GUI_BAR_OPTION_COLOR_DELIM] = color_delim; - new_bar->options[GUI_BAR_OPTION_COLOR_BG] = color_bg; - new_bar->options[GUI_BAR_OPTION_SEPARATOR] = separator; - new_bar->options[GUI_BAR_OPTION_ITEMS] = items; - new_bar->items_count = 0; - new_bar->items_subcount = NULL; - new_bar->items_array = NULL; - new_bar->items_buffer = NULL; - new_bar->items_prefix = NULL; - new_bar->items_name = NULL; - new_bar->items_suffix = NULL; - gui_bar_set_items_array (new_bar, CONFIG_STRING(items)); - new_bar->bar_window = NULL; - new_bar->bar_refresh_needed = 1; - - /* add bar to bars list */ - gui_bar_insert (new_bar); + if (!new_bar) + return NULL; - /* add window bar */ - if (CONFIG_INTEGER(new_bar->options[GUI_BAR_OPTION_TYPE]) == GUI_BAR_TYPE_ROOT) - { - /* create only one window for bar */ - gui_bar_window_new (new_bar, NULL); - gui_window_ask_refresh (1); - } - else + new_bar->options[GUI_BAR_OPTION_HIDDEN] = hidden; + new_bar->options[GUI_BAR_OPTION_PRIORITY] = priority; + new_bar->options[GUI_BAR_OPTION_TYPE] = type; + new_bar->options[GUI_BAR_OPTION_CONDITIONS] = conditions; + new_bar->options[GUI_BAR_OPTION_POSITION] = position; + new_bar->options[GUI_BAR_OPTION_FILLING_TOP_BOTTOM] = filling_top_bottom; + new_bar->options[GUI_BAR_OPTION_FILLING_LEFT_RIGHT] = filling_left_right; + new_bar->options[GUI_BAR_OPTION_SIZE] = size; + new_bar->options[GUI_BAR_OPTION_SIZE_MAX] = size_max; + new_bar->options[GUI_BAR_OPTION_COLOR_FG] = color_fg; + new_bar->options[GUI_BAR_OPTION_COLOR_DELIM] = color_delim; + new_bar->options[GUI_BAR_OPTION_COLOR_BG] = color_bg; + new_bar->options[GUI_BAR_OPTION_SEPARATOR] = separator; + new_bar->options[GUI_BAR_OPTION_ITEMS] = items; + new_bar->items_count = 0; + new_bar->items_subcount = NULL; + new_bar->items_array = NULL; + new_bar->items_buffer = NULL; + new_bar->items_prefix = NULL; + new_bar->items_name = NULL; + new_bar->items_suffix = NULL; + gui_bar_set_items_array (new_bar, CONFIG_STRING(items)); + new_bar->bar_window = NULL; + new_bar->bar_refresh_needed = 1; + + /* add bar to bars list */ + gui_bar_insert (new_bar); + + /* add window bar */ + if (CONFIG_INTEGER(new_bar->options[GUI_BAR_OPTION_TYPE]) == GUI_BAR_TYPE_ROOT) + { + /* create only one window for bar */ + gui_bar_window_new (new_bar, NULL); + gui_window_ask_refresh (1); + } + else + { + /* create bar window for all opened windows */ + for (ptr_win = gui_windows; ptr_win; + ptr_win = ptr_win->next_window) { - /* create bar window for all opened windows */ - for (ptr_win = gui_windows; ptr_win; - ptr_win = ptr_win->next_window) - { - gui_bar_window_new (new_bar, ptr_win); - } + gui_bar_window_new (new_bar, ptr_win); } } @@ -1867,7 +1824,7 @@ gui_bar_use_temp_bars () } } - /* free all temp bars */ + /* free all temporary bars */ while (gui_temp_bars) { next_temp_bar = gui_temp_bars->next_bar; diff --git a/src/plugins/CMakeLists.txt b/src/plugins/CMakeLists.txt index 3e6ac0e26..41a03412a 100644 --- a/src/plugins/CMakeLists.txt +++ b/src/plugins/CMakeLists.txt @@ -96,10 +96,6 @@ IF(ENABLE_SCRIPT) ADD_SUBDIRECTORY( script ) ENDIF(ENABLE_SCRIPT) -IF(ENABLE_XFER) - ADD_SUBDIRECTORY( xfer ) -ENDIF(ENABLE_XFER) - IF(ENABLE_SCRIPTS AND ENABLE_PERL) FIND_PACKAGE(Perl) IF(PERL_FOUND) @@ -142,4 +138,12 @@ IF(ENABLE_SCRIPTS AND ENABLE_GUILE) ENDIF(GUILE_FOUND) ENDIF(ENABLE_SCRIPTS AND ENABLE_GUILE) +IF(ENABLE_TRIGGER) + ADD_SUBDIRECTORY( trigger ) +ENDIF(ENABLE_TRIGGER) + +IF(ENABLE_XFER) + ADD_SUBDIRECTORY( xfer ) +ENDIF(ENABLE_XFER) + INSTALL(FILES weechat-plugin.h DESTINATION ${INCLUDEDIR}) diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am index 16c0e35ac..bfddd6274 100644 --- a/src/plugins/Makefile.am +++ b/src/plugins/Makefile.am @@ -75,10 +75,6 @@ if PLUGIN_SCRIPT script_dir = script endif -if PLUGIN_XFER -xfer_dir = xfer -endif - if PLUGIN_PERL perl_dir = perl endif @@ -103,10 +99,18 @@ if PLUGIN_GUILE guile_dir = guile endif +if PLUGIN_TRIGGER +trigger_dir = trigger +endif + +if PLUGIN_XFER +xfer_dir = xfer +endif + SUBDIRS = . $(alias_dir) $(aspell_dir) $(charset_dir) $(fifo_dir) $(irc_dir) \ - $(logger_dir) $(relay_dir) $(rmodifier_dir) $(script_dir) $(xfer_dir) \ + $(logger_dir) $(relay_dir) $(rmodifier_dir) $(script_dir) \ $(perl_dir) $(python_dir) $(ruby_dir) $(lua_dir) $(tcl_dir) \ - $(guile_dir) + $(guile_dir) $(trigger_dir) $(xfer_dir) EXTRA_DIST = CMakeLists.txt diff --git a/src/plugins/plugin.c b/src/plugins/plugin.c index a10c7874b..424735560 100644 --- a/src/plugins/plugin.c +++ b/src/plugins/plugin.c @@ -521,6 +521,7 @@ plugin_load (const char *filename, int argc, char **argv) new_plugin->string_regcomp = &string_regcomp; new_plugin->string_has_highlight = &string_has_highlight; new_plugin->string_has_highlight_regex = &string_has_highlight_regex; + new_plugin->string_replace_regex = &string_replace_regex; new_plugin->string_split = &string_split; new_plugin->string_free_split = &string_free_split; new_plugin->string_build_with_split_string = &string_build_with_split_string; diff --git a/src/plugins/trigger/CMakeLists.txt b/src/plugins/trigger/CMakeLists.txt new file mode 100644 index 000000000..59d8e1c00 --- /dev/null +++ b/src/plugins/trigger/CMakeLists.txt @@ -0,0 +1,31 @@ +# +# Copyright (C) 2014 Sébastien Helleu +# +# This file is part of WeeChat, the extensible chat client. +# +# WeeChat is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# WeeChat is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with WeeChat. If not, see . +# + +ADD_LIBRARY(trigger MODULE +trigger.c trigger.h +trigger-buffer.c trigger-buffer.h +trigger-callback.c trigger-callback.h +trigger-command.c trigger-command.h +trigger-completion.c trigger-completion.h +trigger-config.c trigger-config.h) +SET_TARGET_PROPERTIES(trigger PROPERTIES PREFIX "") + +TARGET_LINK_LIBRARIES(trigger) + +INSTALL(TARGETS trigger LIBRARY DESTINATION ${LIBDIR}/plugins) diff --git a/src/plugins/trigger/Makefile.am b/src/plugins/trigger/Makefile.am new file mode 100644 index 000000000..2486c0359 --- /dev/null +++ b/src/plugins/trigger/Makefile.am @@ -0,0 +1,42 @@ +# +# Copyright (C) 2014 Sébastien Helleu +# +# This file is part of WeeChat, the extensible chat client. +# +# WeeChat is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# WeeChat is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with WeeChat. If not, see . +# + +AM_CPPFLAGS = -DLOCALEDIR=\"$(datadir)/locale\" $(TRIGGER_CFLAGS) + +libdir = ${weechat_libdir}/plugins + +lib_LTLIBRARIES = trigger.la + +trigger_la_SOURCES = trigger.c \ + trigger.h \ + trigger-buffer.c \ + trigger-buffer.h \ + trigger-callback.c \ + trigger-callback.h \ + trigger-command.c \ + trigger-command.h \ + trigger-completion.c \ + trigger-completion.h \ + trigger-config.c \ + trigger-config.h + +trigger_la_LDFLAGS = -module -no-undefined +trigger_la_LIBADD = $(TRIGGER_LFLAGS) + +EXTRA_DIST = CMakeLists.txt diff --git a/src/plugins/trigger/trigger-buffer.c b/src/plugins/trigger/trigger-buffer.c new file mode 100644 index 000000000..186c97f0c --- /dev/null +++ b/src/plugins/trigger/trigger-buffer.c @@ -0,0 +1,180 @@ +/* + * trigger-buffer.c - debug buffer for triggers + * + * Copyright (C) 2014 Sébastien Helleu + * + * This file is part of WeeChat, the extensible chat client. + * + * WeeChat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * WeeChat is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WeeChat. If not, see . + */ + +#include +#include +#include + +#include "../weechat-plugin.h" +#include "trigger.h" +#include "trigger-buffer.h" + + +struct t_gui_buffer *trigger_buffer = NULL; + + +/* + * Callback called for each entry in hashtable. + */ + +void +trigger_buffer_hashtable_map_cb (void *data, + struct t_hashtable *hashtable, + const void *key, const void *value) +{ + const char *value_type; + char *value_no_color; + + /* make C compiler happy */ + (void) data; + (void) hashtable; + + value_type = weechat_hashtable_get_string (hashtable, "type_values"); + if (!value_type) + return; + + if (strcmp (value_type, "string") == 0) + { + value_no_color = weechat_string_remove_color ((const char *)value, NULL); + weechat_printf_tags (trigger_buffer, "no_trigger", + "\t %s: \"%s\"", + (char *)key, + (value_no_color) ? value_no_color : (const char *)value); + if (value_no_color) + free (value_no_color); + } + else if (strcmp (value_type, "pointer") == 0) + { + weechat_printf_tags (trigger_buffer, "no_trigger", + "\t %s: 0x%lx", + (char *)key, + value); + } +} + +/* + * Displays a hashtable on trigger buffer. + */ + +void +trigger_buffer_display_hashtable (const char *name, + struct t_hashtable *hashtable) +{ + if (!trigger_buffer) + return; + + weechat_printf_tags (trigger_buffer, "no_trigger", " %s:", name); + + weechat_hashtable_map (hashtable, &trigger_buffer_hashtable_map_cb, NULL); +} + +/* + * Callback for user data in trigger buffer. + */ + +int +trigger_buffer_input_cb (void *data, struct t_gui_buffer *buffer, + const char *input_data) +{ + /* make C compiler happy */ + (void) data; + + /* close buffer */ + if (strcmp (input_data, "q") == 0) + { + weechat_buffer_close (buffer); + return WEECHAT_RC_OK; + } + + return WEECHAT_RC_OK; +} + +/* + * Callback called when trigger buffer is closed. + */ + +int +trigger_buffer_close_cb (void *data, struct t_gui_buffer *buffer) +{ + /* make C compiler happy */ + (void) data; + (void) buffer; + + trigger_buffer = NULL; + + return WEECHAT_RC_OK; +} + +/* + * Restore buffer callbacks (input and close) for buffer created by trigger + * plugin. + */ + +void +trigger_buffer_set_callbacks () +{ + struct t_gui_buffer *ptr_buffer; + + ptr_buffer = weechat_buffer_search (TRIGGER_PLUGIN_NAME, + TRIGGER_BUFFER_NAME); + if (ptr_buffer) + { + trigger_buffer = ptr_buffer; + weechat_buffer_set_pointer (trigger_buffer, "close_callback", + &trigger_buffer_close_cb); + weechat_buffer_set_pointer (trigger_buffer, "input_callback", + &trigger_buffer_input_cb); + } +} + +/* + * Opens script buffer. + */ + +void +trigger_buffer_open (int switch_to_buffer) +{ + if (!trigger_buffer) + { + trigger_buffer = weechat_buffer_new (TRIGGER_BUFFER_NAME, + &trigger_buffer_input_cb, NULL, + &trigger_buffer_close_cb, NULL); + + /* failed to create buffer ? then return */ + if (!trigger_buffer) + return; + + weechat_buffer_set (trigger_buffer, "title", _("Trigger monitor")); + + if (!weechat_buffer_get_integer (trigger_buffer, "short_name_is_set")) + weechat_buffer_set (trigger_buffer, "short_name", TRIGGER_BUFFER_NAME); + weechat_buffer_set (trigger_buffer, "localvar_set_type", "debug"); + weechat_buffer_set (trigger_buffer, "localvar_set_server", TRIGGER_BUFFER_NAME); + weechat_buffer_set (trigger_buffer, "localvar_set_channel", TRIGGER_BUFFER_NAME); + weechat_buffer_set (trigger_buffer, "localvar_set_no_log", "1"); + + /* disable all highlights on this buffer */ + weechat_buffer_set (trigger_buffer, "highlight_words", "-"); + } + + if (switch_to_buffer) + weechat_buffer_set (trigger_buffer, "display", "1"); +} diff --git a/src/plugins/trigger/trigger-buffer.h b/src/plugins/trigger/trigger-buffer.h new file mode 100644 index 000000000..a4bc02fd4 --- /dev/null +++ b/src/plugins/trigger/trigger-buffer.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2014 Sébastien Helleu + * + * This file is part of WeeChat, the extensible chat client. + * + * WeeChat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * WeeChat is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WeeChat. If not, see . + */ + +#ifndef __WEECHAT_TRIGGER_BUFFER_H +#define __WEECHAT_TRIGGER_BUFFER_H 1 + +#define TRIGGER_BUFFER_NAME "monitor" + +struct t_gui_buffer *trigger_buffer; + +extern void trigger_buffer_display_hashtable (const char *name, + struct t_hashtable *hashtable); +extern void trigger_buffer_set_callbacks (); +extern void trigger_buffer_open (int switch_to_buffer); + +#endif /* __WEECHAT_TRIGGER_BUFFER_H */ diff --git a/src/plugins/trigger/trigger-callback.c b/src/plugins/trigger/trigger-callback.c new file mode 100644 index 000000000..e14ee6e2e --- /dev/null +++ b/src/plugins/trigger/trigger-callback.c @@ -0,0 +1,597 @@ +/* + * trigger-callback.c - callbacks for triggers + * + * Copyright (C) 2014 Sébastien Helleu + * + * This file is part of WeeChat, the extensible chat client. + * + * WeeChat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * WeeChat is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WeeChat. If not, see . + */ + +#include +#include +#include +#include + +#include "../weechat-plugin.h" +#include "trigger.h" +#include "trigger-buffer.h" + + +/* one hashtable by hook, used in callback to evaluate "conditions" */ +struct t_hashtable *trigger_callback_hashtable_options = NULL; + + +/* + * Checks conditions for a trigger. + * + * Returns: + * 1: conditions are true (or no condition set in trigger) + * 0: conditions are false + */ + +int +trigger_callback_check_conditions (struct t_trigger *trigger, + struct t_hashtable *pointers, + struct t_hashtable *extra_vars) +{ + const char *conditions; + char *value; + int rc; + + conditions = weechat_config_string (trigger->options[TRIGGER_OPTION_CONDITIONS]); + if (!conditions || !conditions[0]) + return 1; + + value = weechat_string_eval_expression (conditions, + pointers, + extra_vars, + trigger_callback_hashtable_options); + rc = (value && (strcmp (value, "1") == 0)); + if (value) + free (value); + + return rc; +} + +/* + * Replaces text using one or more regex in the trigger. + * + * Note: result must be freed after use. + */ + +char * +trigger_callback_replace_regex (struct t_trigger *trigger, const char *string) +{ + char *temp, *res; + int i; + + if (trigger->regex_count == 0) + return strdup (string); + + res = NULL; + + for (i = 0; i < trigger->regex_count; i++) + { + temp = weechat_string_replace_regex ((res) ? res : string, + trigger->regex[i].regex, + trigger->regex[i].replace_eval); + if (!temp) + return res; + res = temp; + } + + return res; +} + +/* + * Executes the trigger command(s). + */ + +void +trigger_callback_run_command (struct t_trigger *trigger, + struct t_gui_buffer *buffer, + struct t_hashtable *pointers, + struct t_hashtable *extra_vars) +{ + const char *command; + char *command_eval, **commands, **ptr_command; + + command = weechat_config_string (trigger->options[TRIGGER_OPTION_COMMAND]); + if (!command || !command[0]) + return; + + command_eval = weechat_string_eval_expression (command, pointers, + extra_vars, NULL); + if (command_eval) + { + commands = weechat_string_split_command (command_eval, ';'); + if (commands) + { + for (ptr_command = commands; *ptr_command; ptr_command++) + { + /* display debug info on trigger buffer */ + if (trigger_buffer) + { + weechat_printf_tags (trigger_buffer, "no_trigger", + "\t running command \"%s\"", + *ptr_command); + } + weechat_command (buffer, *ptr_command); + } + weechat_string_free_split_command (commands); + trigger->hook_count_cmd++; + } + free (command_eval); + } +} + +/* + * Callback for a signal hooked. + */ + +int +trigger_callback_signal_cb (void *data, const char *signal, + const char *type_data, void *signal_data) +{ + struct t_trigger *trigger; + struct t_hashtable *extra_vars; + const char *command, *ptr_signal_data; + char str_data[128], *signal_data2; + int rc; + + /* get trigger pointer, return immediately if not found or trigger running */ + trigger = (struct t_trigger *)data; + if (!trigger || trigger->hook_running) + return WEECHAT_RC_OK; + + trigger->hook_count_cb++; + trigger->hook_running = 1; + + extra_vars = NULL; + + rc = trigger_return_code[weechat_config_integer (trigger->options[TRIGGER_OPTION_RETURN_CODE])]; + + /* + * in a signal, the only possible action is to execute a command; + * so if the command is empty, just exit without checking conditions + */ + command = weechat_config_string (trigger->options[TRIGGER_OPTION_COMMAND]); + if (!command || !command[0]) + goto end; + + /* create hashtable */ + extra_vars = weechat_hashtable_new (32, + WEECHAT_HASHTABLE_STRING, + WEECHAT_HASHTABLE_STRING, + NULL, + NULL); + if (!extra_vars) + goto end; + + /* add data in hashtable used for conditions/replace/command */ + weechat_hashtable_set (extra_vars, "tg_signal", signal); + if (strcmp (type_data, WEECHAT_HOOK_SIGNAL_STRING) == 0) + { + ptr_signal_data = (const char *)signal_data; + } + else if (strcmp (type_data, WEECHAT_HOOK_SIGNAL_INT) == 0) + { + snprintf (str_data, sizeof (str_data), + "%d", *((int *)signal_data)); + ptr_signal_data = str_data; + } + else if (strcmp (type_data, WEECHAT_HOOK_SIGNAL_POINTER) == 0) + { + str_data[0] = '\0'; + if (signal_data) + { + snprintf (str_data, sizeof (str_data), + "0x%lx", (long unsigned int)signal_data); + } + ptr_signal_data = str_data; + } + weechat_hashtable_set (extra_vars, "tg_signal_data", ptr_signal_data); + + /* display debug info on trigger buffer */ + if (!trigger_buffer && (weechat_trigger_plugin->debug >= 1)) + trigger_buffer_open (0); + if (trigger_buffer) + { + weechat_printf_tags (trigger_buffer, "no_trigger", + "signal\t%s%s", + weechat_color ("chat_channel"), + trigger->name); + weechat_printf_tags (trigger_buffer, "no_trigger", + "\t signal_data: \"%s%s\"", + ptr_signal_data, + weechat_color ("reset")); + trigger_buffer_display_hashtable ("extra_vars", extra_vars); + } + + /* check conditions */ + if (!trigger_callback_check_conditions (trigger, NULL, extra_vars)) + goto end; + + /* replace text with regex */ + if (trigger->regex_count > 0) + { + signal_data2 = trigger_callback_replace_regex (trigger, ptr_signal_data); + if (signal_data2) + { + weechat_hashtable_set (extra_vars, "tg_signal_data", signal_data2); + free (signal_data2); + } + } + + /* execute command */ + trigger_callback_run_command (trigger, NULL, NULL, extra_vars); + +end: + if (extra_vars) + weechat_hashtable_free (extra_vars); + trigger->hook_running = 0; + return rc; +} + +/* + * Callback for a hsignal hooked. + */ + +int +trigger_callback_hsignal_cb (void *data, const char *signal, + struct t_hashtable *hashtable) +{ + (void) data; + (void) signal; + (void) hashtable; + + return WEECHAT_RC_OK; +} + +/* + * Callback for a modifier hooked. + */ + +char * +trigger_callback_modifier_cb (void *data, const char *modifier, + const char *modifier_data, const char *string) +{ + struct t_trigger *trigger; + struct t_hashtable *extra_vars; + const char *command; + char *string_modified, *pos, *pos2, *plugin_name, *buffer_name; + char *buffer_full_name, *tags; + int no_trigger, length; + + no_trigger = 0; + + /* get trigger pointer, return immediately if not found or trigger running */ + trigger = (struct t_trigger *)data; + if (!trigger || trigger->hook_running) + return NULL; + + trigger->hook_count_cb++; + trigger->hook_running = 1; + + extra_vars = NULL; + string_modified = NULL; + + /* + * in a modifier, the only possible actions are regex or command; + * so if both are empty, just exit without checking conditions + */ + command = weechat_config_string (trigger->options[TRIGGER_OPTION_COMMAND]); + if ((!command || !command[0]) && !trigger->regex) + goto end; + + /* create hashtable */ + extra_vars = weechat_hashtable_new (32, + WEECHAT_HASHTABLE_STRING, + WEECHAT_HASHTABLE_STRING, + NULL, + NULL); + if (!extra_vars) + goto end; + + /* add data in hashtable used for conditions/replace/command */ + weechat_hashtable_set (extra_vars, "tg_modifier", modifier); + weechat_hashtable_set (extra_vars, "tg_modifier_data", modifier_data); + weechat_hashtable_set (extra_vars, "tg_string", string); + + /* add special variables for a WeeChat message */ + if (strcmp (modifier, "weechat_print") == 0) + { + pos = strchr (modifier_data, ';'); + if (pos) + { + plugin_name = weechat_strndup (modifier_data, pos - modifier_data); + if (plugin_name) + { + weechat_hashtable_set (extra_vars, "tg_plugin", plugin_name); + pos++; + pos2 = strchr (pos, ';'); + if (pos2) + { + buffer_name = weechat_strndup (pos, pos2 - pos); + if (buffer_name) + { + length = strlen (plugin_name) + 1 + strlen (buffer_name) + 1; + buffer_full_name = malloc (length); + if (buffer_full_name) + { + snprintf (buffer_full_name, length, + "%s.%s", plugin_name, buffer_name); + weechat_hashtable_set (extra_vars, "tg_buffer", + buffer_full_name); + free (buffer_full_name); + } + free (buffer_name); + } + pos2++; + if (pos2[0]) + { + length = 1 + strlen (pos2) + 1 + 1; + tags = malloc (length); + if (tags) + { + snprintf (tags, length, ",%s,", pos2); + weechat_hashtable_set (extra_vars, "tg_tags", tags); + if (strstr (tags, ",no_trigger,")) + no_trigger = 1; + free (tags); + } + } + } + free (plugin_name); + } + } + } + + /* + * ignore this modifier if "no_trigger" was in tags + * (for modifier "weechat_print") + */ + if (no_trigger) + goto end; + + /* display debug info on trigger buffer */ + if (!trigger_buffer && (weechat_trigger_plugin->debug >= 1)) + trigger_buffer_open (0); + if (trigger_buffer) + { + weechat_printf_tags (trigger_buffer, "no_trigger", + "modifier\t%s%s", + weechat_color ("chat_channel"), + trigger->name); + weechat_printf_tags (trigger_buffer, "no_trigger", + "\t modifier: %s", modifier); + weechat_printf_tags (trigger_buffer, "no_trigger", + "\t modifier_data: \"%s%s\"", + modifier_data, + weechat_color ("reset")); + trigger_buffer_display_hashtable ("extra_vars", extra_vars); + } + + /* check conditions */ + if (!trigger_callback_check_conditions (trigger, NULL, extra_vars)) + goto end; + + /* replace text with regex */ + if (trigger->regex_count > 0) + { + string_modified = trigger_callback_replace_regex (trigger, string); + if (string_modified) + { + weechat_hashtable_set (extra_vars, "tg_string", string_modified); + if (strcmp (string, string_modified) == 0) + { + /* regex did not change the string, ignore it */ + free (string_modified); + string_modified = NULL; + } + } + } + + /* execute command */ + trigger_callback_run_command (trigger, NULL, NULL, extra_vars); + +end: + if (extra_vars) + weechat_hashtable_free (extra_vars); + trigger->hook_running = 0; + return string_modified; +} + +/* + * Callback for a print hooked. + */ + +int +trigger_callback_print_cb (void *data, struct t_gui_buffer *buffer, + time_t date, int tags_count, const char **tags, + int displayed, int highlight, const char *prefix, + const char *message) +{ + struct t_trigger *trigger; + struct t_hashtable *pointers, *extra_vars; + const char *command, *localvar_type; + char *message2, *str_tags, *str_tags2, str_temp[128]; + int i, rc, length, tag_notify_private; + struct tm *date_tmp; + + /* get trigger pointer, return immediately if not found or trigger running */ + trigger = (struct t_trigger *)data; + if (!trigger || trigger->hook_running) + return WEECHAT_RC_OK; + + trigger->hook_count_cb++; + trigger->hook_running = 1; + + pointers = NULL; + extra_vars = NULL; + + rc = trigger_return_code[weechat_config_integer (trigger->options[TRIGGER_OPTION_RETURN_CODE])]; + + /* return if the buffer does not match buffers defined in the trigger */ + if (trigger->hook_print_buffers + && !weechat_buffer_match_list (buffer, trigger->hook_print_buffers)) + goto end; + + /* + * in a print, the only possible action is to execute a command; + * so if the command is empty, just exit without checking conditions + */ + command = weechat_config_string (trigger->options[TRIGGER_OPTION_COMMAND]); + if (!command || !command[0]) + goto end; + + /* create hashtables */ + pointers = weechat_hashtable_new (32, + WEECHAT_HASHTABLE_STRING, + WEECHAT_HASHTABLE_POINTER, + NULL, + NULL); + if (!pointers) + goto end; + extra_vars = weechat_hashtable_new (32, + WEECHAT_HASHTABLE_STRING, + WEECHAT_HASHTABLE_STRING, + NULL, + NULL); + if (!extra_vars) + goto end; + + /* add data in hashtable used for conditions/replace/command */ + weechat_hashtable_set (pointers, "buffer", buffer); + date_tmp = localtime (&date); + if (date_tmp) + { + strftime (str_temp, sizeof (str_temp), "%Y-%m-%d %H:%M:%S", date_tmp); + weechat_hashtable_set (extra_vars, "tg_date", str_temp); + } + snprintf (str_temp, sizeof (str_temp), "%d", tags_count); + weechat_hashtable_set (extra_vars, "tg_tags_count", str_temp); + str_tags = weechat_string_build_with_split_string (tags, ","); + if (str_tags) + { + /* build string with tags and commas around: ",tag1,tag2,tag3," */ + length = 1 + strlen (str_tags) + 1 + 1; + str_tags2 = malloc (length); + if (str_tags2) + { + snprintf (str_tags2, length, ",%s,", str_tags); + weechat_hashtable_set (extra_vars, "tg_tags", str_tags2); + free (str_tags2); + } + free (str_tags); + } + snprintf (str_temp, sizeof (str_temp), "%d", displayed); + weechat_hashtable_set (extra_vars, "tg_displayed", str_temp); + snprintf (str_temp, sizeof (str_temp), "%d", highlight); + weechat_hashtable_set (extra_vars, "tg_highlight", str_temp); + weechat_hashtable_set (extra_vars, "tg_prefix", prefix); + weechat_hashtable_set (extra_vars, "tg_message", message); + + localvar_type = weechat_buffer_get_string (buffer, "localvar_type"); + tag_notify_private = 0; + + for (i = 0; i < tags_count; i++) + { + if (strcmp (tags[i], "no_trigger") == 0) + { + goto end; + } + else if (strcmp (tags[i], "notify_private") == 0) + { + tag_notify_private = 1; + } + } + snprintf (str_temp, sizeof (str_temp), "%d", + (tag_notify_private && localvar_type && + (strcmp (localvar_type, "private") == 0)) ? 1 : 0); + weechat_hashtable_set (extra_vars, "tg_msg_pv", str_temp); + + /* display debug info on trigger buffer */ + if (!trigger_buffer && (weechat_trigger_plugin->debug >= 1)) + trigger_buffer_open (0); + if (trigger_buffer) + { + weechat_printf_tags (trigger_buffer, "no_trigger", + "print\t%s%s", + weechat_color ("chat_channel"), + trigger->name); + weechat_printf_tags (trigger_buffer, "no_trigger", + "\t buffer: %s", + weechat_buffer_get_string (buffer, "full_name")); + trigger_buffer_display_hashtable ("pointers", pointers); + trigger_buffer_display_hashtable ("extra_vars", extra_vars); + } + + /* check conditions */ + if (!trigger_callback_check_conditions (trigger, pointers, extra_vars)) + goto end; + + /* replace text with regex */ + if (trigger->regex_count > 0) + { + message2 = trigger_callback_replace_regex (trigger, message); + if (message2) + { + weechat_hashtable_set (extra_vars, "tg_message", message); + free (message2); + } + } + + /* execute command */ + trigger_callback_run_command (trigger, buffer, pointers, extra_vars); + +end: + if (pointers) + weechat_hashtable_free (pointers); + if (extra_vars) + weechat_hashtable_free (extra_vars); + trigger->hook_running = 0; + return rc; +} + +/* + * Initializes trigger callback. + */ + +void +trigger_callback_init () +{ + trigger_callback_hashtable_options = weechat_hashtable_new (32, + WEECHAT_HASHTABLE_STRING, + WEECHAT_HASHTABLE_STRING, + NULL, + NULL); + if (trigger_callback_hashtable_options) + { + weechat_hashtable_set (trigger_callback_hashtable_options, + "type", "condition"); + } +} + +/* + * Ends trigger callback. + */ + +void +trigger_callback_end () +{ + if (trigger_callback_hashtable_options) + weechat_hashtable_free (trigger_callback_hashtable_options); +} diff --git a/src/plugins/trigger/trigger-callback.h b/src/plugins/trigger/trigger-callback.h new file mode 100644 index 000000000..b9327709b --- /dev/null +++ b/src/plugins/trigger/trigger-callback.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2014 Sébastien Helleu + * + * This file is part of WeeChat, the extensible chat client. + * + * WeeChat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * WeeChat is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WeeChat. If not, see . + */ + +#ifndef __WEECHAT_TRIGGER_CALLBACK_H +#define __WEECHAT_TRIGGER_CALLBACK_H 1 + +extern int trigger_callback_signal_cb (void *data, const char *signal, + const char *type_data, void *signal_data); +extern int trigger_callback_hsignal_cb (void *data, const char *signal, + struct t_hashtable *hashtable); +extern char *trigger_callback_modifier_cb (void *data, const char *modifier, + const char *modifier_data, + const char *string); +extern int trigger_callback_print_cb (void *data, struct t_gui_buffer *buffer, + time_t date, int tags_count, + const char **tags, int displayed, + int highlight, const char *prefix, + const char *message); +extern void trigger_callback_init (); +extern void trigger_callback_end (); + +#endif /* __WEECHAT_TRIGGER_CALLBACK_H */ diff --git a/src/plugins/trigger/trigger-command.c b/src/plugins/trigger/trigger-command.c new file mode 100644 index 000000000..a38ffcc28 --- /dev/null +++ b/src/plugins/trigger/trigger-command.c @@ -0,0 +1,352 @@ +/* + * trigger-command.c - trigger command + * + * Copyright (C) 2014 Sébastien Helleu + * + * This file is part of WeeChat, the extensible chat client. + * + * WeeChat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * WeeChat is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WeeChat. If not, see . + */ + +#include +#include + +#include "../weechat-plugin.h" +#include "trigger.h" +#include "trigger-buffer.h" +#include "trigger-config.h" + + +/* + * Callback for command "/trigger": manage triggers. + */ + +int +trigger_command_trigger (void *data, struct t_gui_buffer *buffer, int argc, + char **argv, char **argv_eol) +{ + struct t_trigger *ptr_trigger; + const char *option; + int i, type, count, index_option, enabled; + + /* make C compiler happy */ + (void) data; + (void) buffer; + + /* list all triggers */ + if ((argc == 1) + || ((argc == 2) && (weechat_strcasecmp (argv[1], "list") == 0))) + { + if (triggers) + { + weechat_printf_tags (NULL, "no_trigger", ""); + weechat_printf_tags (NULL, "no_trigger", _("List of triggers:")); + for (ptr_trigger = triggers; ptr_trigger; + ptr_trigger = ptr_trigger->next_trigger) + { + weechat_printf_tags (NULL, "no_trigger", + " %s: %s, \"%s\" (%d hooks, %d/%d) %s", + ptr_trigger->name, + weechat_config_string (ptr_trigger->options[TRIGGER_OPTION_HOOK]), + weechat_config_string (ptr_trigger->options[TRIGGER_OPTION_ARGUMENTS]), + ptr_trigger->hooks_count, + ptr_trigger->hook_count_cb, + ptr_trigger->hook_count_cmd, + weechat_config_boolean (ptr_trigger->options[TRIGGER_OPTION_ENABLED]) ? + "" : _("(disabled)")); + option = weechat_config_string (ptr_trigger->options[TRIGGER_OPTION_CONDITIONS]); + if (option && option[0]) + { + weechat_printf_tags (NULL, "no_trigger", + " conditions: \"%s\"", option); + } + if (ptr_trigger->regex_count > 0) + { + weechat_printf_tags (NULL, "no_trigger", + " %d regex:", + ptr_trigger->regex_count); + for (i = 0; i < ptr_trigger->regex_count; i++) + { + weechat_printf_tags (NULL, "no_trigger", + " %d: %s%s %s-->%s %s", + i + 1, + weechat_color (weechat_config_string (trigger_config_color_regex)), + ptr_trigger->regex[i].str_regex, + weechat_color ("chat_delimiters"), + weechat_color (weechat_config_string (trigger_config_color_replace)), + ptr_trigger->regex[i].replace); + } + } + option = weechat_config_string (ptr_trigger->options[TRIGGER_OPTION_COMMAND]); + if (option && option[0]) + { + weechat_printf_tags (NULL, "no_trigger", + " command: \"%s\"", option); + } + } + } + else + { + weechat_printf_tags (NULL, "no_trigger", _("No trigger defined")); + } + return WEECHAT_RC_OK; + } + + /* add a trigger */ + if (weechat_strcasecmp (argv[1], "add") == 0) + { + if (argc < 4) + { + weechat_printf_tags (NULL, "no_trigger", + _("%sError: missing arguments for \"%s\" " + "command"), + weechat_prefix ("error"), "trigger"); + return WEECHAT_RC_OK; + } + type = trigger_search_hook_type (argv[3]); + if (type < 0) + { + weechat_printf_tags (NULL, "no_trigger", + _("%s%s: invalid hook type \"%s\""), + weechat_prefix ("error"), TRIGGER_PLUGIN_NAME, + argv[3]); + return WEECHAT_RC_OK; + } + ptr_trigger = trigger_alloc (argv[2]); + if (!ptr_trigger) + { + weechat_printf_tags (NULL, "no_trigger", + _("%s%s: error creating trigger \"%s\""), + weechat_prefix ("error"), TRIGGER_PLUGIN_NAME, + argv[2]); + return WEECHAT_RC_OK; + } + if (trigger_new (argv[2], "on", argv[3], + (argc > 4) ? argv_eol[4] : "", + "", "", "", "ok")) + { + weechat_printf_tags (NULL, "no_trigger", + _("Trigger \"%s\" created"), argv[2]); + } + else + { + weechat_printf_tags (NULL, "no_trigger", + _("%sError: failed to create trigger \"%s\""), + weechat_prefix ("error"), argv[2]); + } + return WEECHAT_RC_OK; + } + + /* set option in a trigger */ + if (weechat_strcasecmp (argv[1], "set") == 0) + { + if (argc < 5) + { + weechat_printf_tags (NULL, "no_trigger", + _("%sError: missing arguments for \"%s\" " + "command"), + weechat_prefix ("error"), "trigger"); + return WEECHAT_RC_OK; + } + ptr_trigger = trigger_search (argv[2]); + if (!ptr_trigger) + { + weechat_printf_tags (NULL, "no_trigger", + _("%sTrigger \"%s\" not found"), + weechat_prefix ("error"), argv[2]); + return WEECHAT_RC_OK; + } + if (weechat_strcasecmp (argv[3], "name") == 0) + { + trigger_rename (ptr_trigger, argv_eol[4]); + } + else + { + index_option = trigger_search_option (argv[3]); + if (index_option < 0) + { + weechat_printf_tags (NULL, "no_trigger", + _("%sTrigger option \"%s\" not found"), + weechat_prefix ("error"), argv[3]); + return WEECHAT_RC_OK; + } + weechat_config_option_set (ptr_trigger->options[index_option], + argv_eol[4], 1); + } + weechat_printf_tags (NULL, "no_trigger", + _("Trigger \"%s\" updated"), ptr_trigger->name); + return WEECHAT_RC_OK; + } + + /* delete a trigger */ + if (weechat_strcasecmp (argv[1], "del") == 0) + { + if (argc < 3) + { + weechat_printf_tags (NULL, "no_trigger", + _("%sError: missing arguments for \"%s\" " + "command"), + weechat_prefix ("error"), "trigger"); + return WEECHAT_RC_OK; + } + if (weechat_strcasecmp (argv[2], "-all") == 0) + { + count = triggers_count; + trigger_free_all (); + if (count > 0) + weechat_printf_tags (NULL, "no_trigger", + _("%d triggers removed"), count); + } + else + { + for (i = 2; i < argc; i++) + { + ptr_trigger = trigger_search (argv[i]); + if (ptr_trigger) + { + trigger_free (ptr_trigger); + weechat_printf_tags (NULL, "no_trigger", + _("Trigger \"%s\" removed"), argv[i]); + } + else + { + weechat_printf_tags (NULL, "no_trigger", + _("%sTrigger \"%s\" not found"), + weechat_prefix ("error"), argv[i]); + } + } + } + return WEECHAT_RC_OK; + } + + /* enable/disable/toggle a trigger */ + if ((weechat_strcasecmp (argv[1], "enable") == 0) + || (weechat_strcasecmp (argv[1], "disable") == 0) + || (weechat_strcasecmp (argv[1], "toggle") == 0)) + { + if (argc < 3) + { + weechat_printf_tags (NULL, "no_trigger", + _("%sError: missing arguments for \"%s\" " + "command"), + weechat_prefix ("error"), "trigger"); + return WEECHAT_RC_OK; + } + ptr_trigger = trigger_search (argv[2]); + if (!ptr_trigger) + { + weechat_printf_tags (NULL, "no_trigger", + _("%sTrigger \"%s\" not found"), + weechat_prefix ("error"), argv[2]); + return WEECHAT_RC_OK; + } + if (weechat_strcasecmp (argv[1], "enable") == 0) + enabled = 1; + else if (weechat_strcasecmp (argv[1], "disable") == 0) + enabled = 0; + else + { + enabled = weechat_config_boolean (ptr_trigger->options[TRIGGER_OPTION_ENABLED]) ? + 0 : 1; + } + weechat_config_option_set (ptr_trigger->options[TRIGGER_OPTION_ENABLED], + (enabled) ? "on" : "off", 1); + weechat_printf_tags (NULL, "no_trigger", + (enabled) ? + _("Trigger \"%s\" enabled") : + _("Trigger \"%s\" disabled"), + ptr_trigger->name); + return WEECHAT_RC_OK; + } + + /* open the trigger monitor buffer */ + if (weechat_strcasecmp (argv[1], "monitor") == 0) + { + trigger_buffer_open (1); + return WEECHAT_RC_OK; + } + + return WEECHAT_RC_OK; +} + +/* + * Hooks trigger commands. + */ + +void +trigger_command_init () +{ + weechat_hook_command ( + "trigger", + N_("manage triggers"), + N_("list" + " || add []" + " || set