1
0
mirror of https://github.com/weechat/weechat.git synced 2026-07-10 03:33:12 +02:00

Add new plugin "rmodifier": alter modifier strings with regular expressions (bug #26964)

This commit is contained in:
Sebastien Helleu
2010-08-11 15:43:20 +02:00
parent 6f063c95f1
commit d59d099e82
51 changed files with 3155 additions and 131 deletions
+31
View File
@@ -0,0 +1,31 @@
#
# Copyright (C) 2010 Sebastien Helleu <flashcode@flashtux.org>
#
# 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 <http://www.gnu.org/licenses/>.
#
ADD_LIBRARY(rmodifier MODULE
rmodifier.c rmodifier.h
rmodifier-command.c rmodifier-command.h
rmodifier-completion.c rmodifier-completion.h
rmodifier-config.c rmodifier-config.h
rmodifier-debug.c rmodifier-debug.h
rmodifier-info.c rmodifier-info.h)
SET_TARGET_PROPERTIES(rmodifier PROPERTIES PREFIX "")
TARGET_LINK_LIBRARIES(rmodifier)
INSTALL(TARGETS rmodifier LIBRARY DESTINATION ${LIBDIR}/plugins)
+41
View File
@@ -0,0 +1,41 @@
#
# Copyright (C) 2010 Sebastien Helleu <flashcode@flashtux.org>
#
# 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 <http://www.gnu.org/licenses/>.
#
INCLUDES = -DLOCALEDIR=\"$(datadir)/locale\" $(RMODIFIER_CFLAGS)
libdir = ${weechat_libdir}/plugins
lib_LTLIBRARIES = rmodifier.la
rmodifier_la_SOURCES = rmodifier.c \
rmodifier.h \
rmodifier-command.c \
rmodifier-command.h \
rmodifier-completion.c \
rmodifier-completion.h \
rmodifier-config.c \
rmodifier-config.h \
rmodifier-debug.c \
rmodifier-debug.h \
rmodifier-info.c \
rmodifier-info.h
rmodifier_la_LDFLAGS = -module
rmodifier_la_LIBADD = $(RMODIFIER_LFLAGS)
EXTRA_DIST = CMakeLists.txt
+265
View File
@@ -0,0 +1,265 @@
/*
* Copyright (C) 2010 Sebastien Helleu <flashcode@flashtux.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
/*
* rmodifier-command.c: rmodifier command
*/
#include <stdlib.h>
#include "../weechat-plugin.h"
#include "rmodifier.h"
#include "rmodifier-command.h"
#include "rmodifier-config.h"
/*
* rmodifier_command_print: print a rmodifier
*/
void
rmodifier_command_print (const char *name, const char *modifiers,
const char *str_regex, const char *groups)
{
weechat_printf (NULL,
" %s[%s%s%s]%s %s%s: \"%s%s%s\" [%s%s%s]",
weechat_color ("chat_delimiters"),
weechat_color ("chat"),
name,
weechat_color ("chat_delimiters"),
weechat_color ("chat"),
modifiers,
weechat_color ("chat_delimiters"),
weechat_color ("chat_host"),
str_regex,
weechat_color ("chat_delimiters"),
weechat_color ("chat"),
groups,
weechat_color ("chat_delimiters"));
}
/*
* rmodifier_command_list: list rmodifiers
*/
void
rmodifier_command_list (const char *message)
{
struct t_rmodifier *ptr_rmodifier;
if (rmodifier_list)
{
weechat_printf (NULL, "");
weechat_printf (NULL, message);
for (ptr_rmodifier = rmodifier_list; ptr_rmodifier;
ptr_rmodifier = ptr_rmodifier->next_rmodifier)
{
rmodifier_command_print (ptr_rmodifier->name,
ptr_rmodifier->modifiers,
ptr_rmodifier->str_regex,
ptr_rmodifier->groups);
}
}
else
weechat_printf (NULL, _("No rmodifier defined"));
}
/*
* rmodifier_command_cb: manage rmodifiers
*/
int
rmodifier_command_cb (void *data, struct t_gui_buffer *buffer, int argc,
char **argv, char **argv_eol)
{
struct t_rmodifier *ptr_rmodifier;
struct t_config_option *ptr_option;
int i, count;
/* make C compiler happy */
(void) data;
(void) buffer;
if ((argc == 1)
|| ((argc == 2) && (weechat_strcasecmp (argv[1], "list") == 0)))
{
/* list all rmodifiers */
rmodifier_command_list (_("List of rmodifiers:"));
return WEECHAT_RC_OK;
}
if (weechat_strcasecmp (argv[1], "listdefault") == 0)
{
/* list default rmodifiers */
weechat_printf (NULL, "");
weechat_printf (NULL, _("Default rmodifiers:"));
for (i = 0; rmodifier_config_default_list[i][0]; i++)
{
rmodifier_command_print (rmodifier_config_default_list[i][0],
rmodifier_config_default_list[i][1],
rmodifier_config_default_list[i][2],
rmodifier_config_default_list[i][3]);
}
return WEECHAT_RC_OK;
}
if (weechat_strcasecmp (argv[1], "add") == 0)
{
/* add a rmodifier */
if (argc < 6)
{
weechat_printf (NULL,
_("%sError: missing arguments for \"%s\" "
"command"),
weechat_prefix ("error"), "rmodifier");
return WEECHAT_RC_ERROR;
}
ptr_rmodifier = rmodifier_new (argv[2], argv[3], argv_eol[5], argv[4]);
if (!ptr_rmodifier)
{
weechat_printf (NULL,
_("%s%s: error creating rmodifier \"%s\""),
weechat_prefix ("error"), RMODIFIER_PLUGIN_NAME,
argv[2]);
return WEECHAT_RC_ERROR;
}
/* create config option */
ptr_option = weechat_config_search_option (rmodifier_config_file,
rmodifier_config_section_modifier,
argv[2]);
if (ptr_option)
weechat_config_option_free (ptr_option);
rmodifier_config_modifier_new_option (ptr_rmodifier->name,
ptr_rmodifier->modifiers,
ptr_rmodifier->str_regex,
ptr_rmodifier->groups);
/* display message */
weechat_printf (NULL, _("Rmodifier \"%s\" created"),
ptr_rmodifier->name);
return WEECHAT_RC_OK;
}
if (weechat_strcasecmp (argv[1], "del") == 0)
{
/* add a rmodifier */
if (argc < 3)
{
weechat_printf (NULL,
_("%sError: missing arguments for \"%s\" "
"command"),
weechat_prefix ("error"), "rmodifier");
return WEECHAT_RC_ERROR;
}
if (weechat_strcasecmp (argv[2], "-all") == 0)
{
count = rmodifier_count;
rmodifier_free_all ();
weechat_config_section_free_options (rmodifier_config_section_modifier);
if (count > 0)
weechat_printf (NULL, _("%d rmodifiers removed"), count);
}
else
{
for (i = 2; i < argc; i++)
{
ptr_rmodifier = rmodifier_search (argv[i]);
if (ptr_rmodifier)
{
ptr_option = weechat_config_search_option (rmodifier_config_file,
rmodifier_config_section_modifier,
argv[i]);
if (ptr_option)
weechat_config_option_free (ptr_option);
rmodifier_free (ptr_rmodifier);
weechat_printf (NULL, _("Rmodifier \"%s\" removed"),
argv[i]);
}
else
{
weechat_printf (NULL, _("%sRmodifier \"%s\" not found"),
weechat_prefix ("error"), argv[i]);
}
}
}
return WEECHAT_RC_OK;
}
/* restore default rmodifiers (only with "-yes", for security reason) */
if (weechat_strcasecmp (argv[1], "default") == 0)
{
if ((argc >= 3) && (weechat_strcasecmp (argv[2], "-yes") == 0))
{
rmodifier_free_all ();
weechat_config_section_free_options (rmodifier_config_section_modifier);
rmodifier_create_default ();
rmodifier_command_list (_("Default rmodifiers restored:"));
}
else
{
weechat_printf (NULL,
_("%sError: \"-yes\" argument is required for "
"restoring default rmodifiers (security reason)"),
weechat_prefix ("error"));
return WEECHAT_RC_ERROR;
}
return WEECHAT_RC_OK;
}
return WEECHAT_RC_OK;
}
/*
* rmodifier_command_init: add /rmodifier command
*/
void
rmodifier_command_init ()
{
weechat_hook_command ("rmodifier",
N_("alter modifier strings with regular expressions"),
N_("[list] | [listdefault] | "
"[add name modifiers groups regex] | "
"[del name|-all [name...]] | [default -yes]"),
N_(" list: list all rmodifiers\n"
"listdefault: list default rmodifiers\n"
" add: add a rmodifier\n"
" name: name of rmodifier\n"
" modifiers: comma separated list of modifiers\n"
" groups: action on groups found: comma separated "
"list of groups (from 1 to 9) with optional \"*\" "
"after number to hide group\n"
" regex: regular expression\n"
" del: delete a rmodifier\n"
" -all: delete all rmodifiers\n"
" default: restore default rmodifiers\n\n"
"Examples:\n"
" hide everything typed after a command /password:\n"
" /rmodifier add password input_text_display 1,2* ^(/password +)(.*)\n"
" delete rmodifier \"password\":\n"
" /rmodifier del password\n"
" delete all rmodifiers:\n"
" /rmodifier del -all"),
"list"
" || listdefault"
" || add %(rmodifier)"
" || del %(rmodifier)|-all %(rmodifier)|%*"
" || default",
&rmodifier_command_cb, NULL);
}
+25
View File
@@ -0,0 +1,25 @@
/*
* Copyright (C) 2010 Sebastien Helleu <flashcode@flashtux.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef __WEECHAT_RMODIFIER_COMMAND_H
#define __WEECHAT_RMODIFIER_COMMAND_H 1
extern void rmodifier_command_init ();
#endif /* __WEECHAT_RMODIFIER_COMMAND_H */
@@ -0,0 +1,66 @@
/*
* Copyright (C) 2010 Sebastien Helleu <flashcode@flashtux.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
/*
* rmodifier-completion.c: completion for rmodifier command
*/
#include <stdlib.h>
#include "../weechat-plugin.h"
#include "rmodifier.h"
#include "rmodifier-completion.h"
/*
* rmodifier_completion_cb: callback for completion with list of rmodifiers
*/
int
rmodifier_completion_cb (void *data, const char *completion_item,
struct t_gui_buffer *buffer,
struct t_gui_completion *completion)
{
struct t_rmodifier *ptr_rmodifier;
/* make C compiler happy */
(void) data;
(void) completion_item;
(void) buffer;
for (ptr_rmodifier = rmodifier_list; ptr_rmodifier;
ptr_rmodifier = ptr_rmodifier->next_rmodifier)
{
weechat_hook_completion_list_add (completion, ptr_rmodifier->name,
0, WEECHAT_LIST_POS_SORT);
}
return WEECHAT_RC_OK;
}
/*
* rmodifier_completion_init: initialize rmodifier plugin
*/
void
rmodifier_completion_init ()
{
weechat_hook_completion ("rmodifier", N_("list of rmodifiers"),
&rmodifier_completion_cb, NULL);
}
@@ -0,0 +1,25 @@
/*
* Copyright (C) 2010 Sebastien Helleu <flashcode@flashtux.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef __WEECHAT_RMODIFIER_COMPLETION_H
#define __WEECHAT_RMODIFIER_COMPLETION_H 1
extern void rmodifier_completion_init ();
#endif /* __WEECHAT_RMODIFIER_COMPLETION_H */
+291
View File
@@ -0,0 +1,291 @@
/*
* Copyright (C) 2010 Sebastien Helleu <flashcode@flashtux.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
/*
* rmodifier-config.c: rmodifier configuration options (file rmodifier.conf)
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include "../weechat-plugin.h"
#include "rmodifier.h"
#include "rmodifier-config.h"
struct t_config_file *rmodifier_config_file = NULL;
struct t_config_section *rmodifier_config_section_modifier = NULL;
struct t_config_option *rmodifier_config_look_hide_char;
char *rmodifier_config_default_list[][4] =
{
{ "nickserv", "history_add,input_text_display",
"^(/(msg|quote) +nickserv +(identify|ghost \\S+) +)(.*)", "1,4*"
},
{ "oper", "history_add,input_text_display",
"^(/oper +\\S+ +)(.*)", "1,2*"
},
{ "set_pass", "history_add",
"^(/set +\\S*password\\S* +)(.*)", "1,2*"
},
{ NULL, NULL, NULL, NULL },
};
/*
* rmodifier_config_reload: reload rmodifier configuration file
*/
int
rmodifier_config_reload (void *data, struct t_config_file *config_file)
{
/* make C compiler happy */
(void) data;
rmodifier_free_all ();
return weechat_config_reload (config_file);
}
/*
* rmodifier_config_modifier_change_cb: callback called when a rmodifier is
* modified in section "modifier"
*/
void
rmodifier_config_modifier_change_cb (void *data, struct t_config_option *option)
{
/* make C compiler happy */
(void) data;
rmodifier_new_with_string (weechat_config_option_get_pointer (option, "name"),
weechat_config_option_get_pointer (option, "value"));
}
/*
* rmodifier_config_modifier_delete_cb: callback called when rmodifier option
* is deleted in section "modifier"
*/
void
rmodifier_config_modifier_delete_cb (void *data, struct t_config_option *option)
{
struct t_rmodifier *ptr_rmodifier;
/* make C compiler happy */
(void) data;
ptr_rmodifier = rmodifier_search (weechat_config_option_get_pointer (option,
"name"));
if (ptr_rmodifier)
rmodifier_free (ptr_rmodifier);
}
/*
* rmodifier_config_modifier_write_default_cb: write default rmodifiers in
* configuration file in section
* "modifier"
*/
int
rmodifier_config_modifier_write_default_cb (void *data,
struct t_config_file *config_file,
const char *section_name)
{
int i;
/* make C compiler happy */
(void) data;
if (!weechat_config_write_line (config_file, section_name, NULL))
return WEECHAT_CONFIG_WRITE_ERROR;
for (i = 0; rmodifier_config_default_list[i][0]; i++)
{
if (!weechat_config_write_line (config_file,
rmodifier_config_default_list[i][0],
"\"%s;%s;%s\"",
rmodifier_config_default_list[i][1],
rmodifier_config_default_list[i][2],
rmodifier_config_default_list[i][3]))
return WEECHAT_CONFIG_WRITE_ERROR;
}
return WEECHAT_CONFIG_WRITE_OK;
}
/*
* rmodifier_config_modifier_new_option: create new option in section "modifier"
*/
void
rmodifier_config_modifier_new_option (const char *name, const char *modifiers,
const char *regex, const char *groups)
{
int length;
char *value;
length = strlen (modifiers) + 1 + strlen (regex) + 1 +
((groups) ? strlen (groups) : 0) + 1;
value = malloc (length);
if (value)
{
snprintf (value, length, "%s;%s;%s",
modifiers, regex,
(groups) ? groups : "");
weechat_config_new_option (rmodifier_config_file,
rmodifier_config_section_modifier,
name, "string", NULL,
NULL, 0, 0, "", value, 0,
NULL, NULL,
&rmodifier_config_modifier_change_cb, NULL,
&rmodifier_config_modifier_delete_cb, NULL);
free (value);
}
}
/*
* rmodifier_config_modifier_create_option_cb: callback to create option in
* "modifier" section
*/
int
rmodifier_config_modifier_create_option_cb (void *data,
struct t_config_file *config_file,
struct t_config_section *section,
const char *option_name,
const char *value)
{
struct t_rmodifier *ptr_rmodifier;
int rc;
/* make C compiler happy */
(void) data;
(void) config_file;
(void) section;
rc = WEECHAT_CONFIG_OPTION_SET_ERROR;
/* create rmodifier */
ptr_rmodifier = rmodifier_search (option_name);
if (ptr_rmodifier)
rmodifier_free (ptr_rmodifier);
if (value && value[0])
{
ptr_rmodifier = rmodifier_new_with_string (option_name, value);
if (ptr_rmodifier)
{
rc = WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE;
/* create option */
rmodifier_config_modifier_new_option (ptr_rmodifier->name,
ptr_rmodifier->modifiers,
ptr_rmodifier->str_regex,
ptr_rmodifier->groups);
}
else
rc = WEECHAT_CONFIG_OPTION_SET_ERROR;
}
else
rc = WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE;
if (rc == WEECHAT_CONFIG_OPTION_SET_ERROR)
{
weechat_printf (NULL,
_("%s%s: error creating rmodifier "
"\"%s\" => \"%s\""),
weechat_prefix ("error"), RMODIFIER_PLUGIN_NAME,
option_name, value);
}
return rc;
}
/*
* rmodifier_config_init: init rmodifier configuration file
* return: 1 if ok, 0 if error
*/
int
rmodifier_config_init ()
{
struct t_config_section *ptr_section;
rmodifier_config_file = weechat_config_new (RMODIFIER_CONFIG_NAME,
&rmodifier_config_reload, NULL);
if (!rmodifier_config_file)
return 0;
/* look */
ptr_section = weechat_config_new_section (rmodifier_config_file, "look",
0, 0,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL);
if (!ptr_section)
{
weechat_config_free (rmodifier_config_file);
return 0;
}
rmodifier_config_look_hide_char = weechat_config_new_option (
rmodifier_config_file, ptr_section,
"hide_char", "string",
N_("char used to hide part of a string"),
NULL, 0, 0, "*", NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL);
/* modifier */
ptr_section = weechat_config_new_section (rmodifier_config_file, "modifier",
0, 0,
NULL, NULL,
NULL, NULL,
&rmodifier_config_modifier_write_default_cb, NULL,
&rmodifier_config_modifier_create_option_cb, NULL,
NULL, NULL);
if (!ptr_section)
{
weechat_config_free (rmodifier_config_file);
return 0;
}
rmodifier_config_section_modifier = ptr_section;
return 1;
}
/*
* rmodifier_config_read: read rmodifier configuration file
*/
int
rmodifier_config_read ()
{
return weechat_config_read (rmodifier_config_file);
}
/*
* rmodifier_config_write: write rmodifier configuration file
*/
int
rmodifier_config_write ()
{
return weechat_config_write (rmodifier_config_file);
}
+40
View File
@@ -0,0 +1,40 @@
/*
* Copyright (C) 2010 Sebastien Helleu <flashcode@flashtux.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef __WEECHAT_RMODIFIER_CONFIG_H
#define __WEECHAT_RMODIFIER_CONFIG_H 1
#define RMODIFIER_CONFIG_NAME "rmodifier"
extern struct t_config_file *rmodifier_config_file;
extern struct t_config_section *rmodifier_config_section_modifier;
struct t_config_option *rmodifier_config_look_hide_char;
extern char *rmodifier_config_default_list[][4];
extern void rmodifier_config_modifier_new_option (const char *name,
const char *modifiers,
const char *regex,
const char *groups);
extern int rmodifier_config_init ();
extern int rmodifier_config_read ();
extern int rmodifier_config_write ();
#endif /* __WEECHAT_RMODIFIER_CONFIG_H */
+68
View File
@@ -0,0 +1,68 @@
/*
* Copyright (C) 2010 Sebastien Helleu <flashcode@flashtux.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
/*
* rmodifier-debug.c: debug functions for rmodifier plugin
*/
#include <stdlib.h>
#include <string.h>
#include "../weechat-plugin.h"
#include "rmodifier.h"
#include "rmodifier-debug.h"
/*
* rmodifier_debug_signal_debug_dump_cb: dump rmodifier data in WeeChat log file
*/
int
rmodifier_debug_signal_debug_dump_cb (void *data, const char *signal,
const char *type_data, void *signal_data)
{
/* make C compiler happy */
(void) data;
(void) signal;
(void) type_data;
(void) signal_data;
weechat_log_printf ("");
weechat_log_printf ("***** \"%s\" plugin dump *****",
weechat_plugin->name);
rmodifier_print_log ();
weechat_log_printf ("");
weechat_log_printf ("***** End of \"%s\" plugin dump *****",
weechat_plugin->name);
return WEECHAT_RC_OK;
}
/*
* rmodifier_debug_init: initialize debug for rmodifier plugin
*/
void
rmodifier_debug_init ()
{
weechat_hook_signal ("debug_dump",
&rmodifier_debug_signal_debug_dump_cb, NULL);
}
+25
View File
@@ -0,0 +1,25 @@
/*
* Copyright (C) 2010 Sebastien Helleu <flashcode@flashtux.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef __WEECHAT_RMODIFIER_DEBUG_H
#define __WEECHAT_RMODIFIER_DEBUG_H 1
extern void rmodifier_debug_init ();
#endif /* __WEECHAT_RMODIFIER_DEBUG_H */
+105
View File
@@ -0,0 +1,105 @@
/*
* Copyright (C) 2010 Sebastien Helleu <flashcode@flashtux.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
/*
* rmodifier-info.c: info and infolist hooks for rmodifier plugin
*/
#include <stdlib.h>
#include "../weechat-plugin.h"
#include "rmodifier.h"
#include "rmodifier-info.h"
/*
* rmodifier_info_get_infolist_cb: callback called when rmodifier infolist is
* asked
*/
struct t_infolist *
rmodifier_info_get_infolist_cb (void *data, const char *infolist_name,
void *pointer, const char *arguments)
{
struct t_infolist *ptr_infolist;
struct t_rmodifier *ptr_rmodifier;
/* make C compiler happy */
(void) data;
(void) arguments;
if (!infolist_name || !infolist_name[0])
return NULL;
if (weechat_strcasecmp (infolist_name, RMODIFIER_PLUGIN_NAME) == 0)
{
if (pointer && !rmodifier_valid (pointer))
return NULL;
ptr_infolist = weechat_infolist_new ();
if (ptr_infolist)
{
if (pointer)
{
/* build list with only one rmodifier */
if (!rmodifier_add_to_infolist (ptr_infolist, pointer))
{
weechat_infolist_free (ptr_infolist);
return NULL;
}
return ptr_infolist;
}
else
{
/* build list with all rmodifiers matching arguments */
for (ptr_rmodifier = rmodifier_list; ptr_rmodifier;
ptr_rmodifier = ptr_rmodifier->next_rmodifier)
{
if (!arguments || !arguments[0]
|| weechat_string_match (ptr_rmodifier->name, arguments, 0))
{
if (!rmodifier_add_to_infolist (ptr_infolist, ptr_rmodifier))
{
weechat_infolist_free (ptr_infolist);
return NULL;
}
}
}
return ptr_infolist;
}
}
}
return NULL;
}
/*
* rmodifier_info_init: initialize info and infolist hooks for rmodifier plugin
*/
void
rmodifier_info_init ()
{
/* rmodifier infolist hooks */
weechat_hook_infolist ("rmodifier", N_("list of rmodifiers"),
N_("rmodifier pointer (optional)"),
N_("rmodifier name (can start or end with \"*\" as "
"joker) (optional)"),
&rmodifier_info_get_infolist_cb, NULL);
}
+25
View File
@@ -0,0 +1,25 @@
/*
* Copyright (C) 2010 Sebastien Helleu <flashcode@flashtux.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef __WEECHAT_RMODIFIER_INFO_H
#define __WEECHAT_RMODIFIER_INFO_H 1
extern void rmodifier_info_init ();
#endif /* __WEECHAT_RMODIFIER_INFO_H */
+573
View File
@@ -0,0 +1,573 @@
/*
* Copyright (C) 2010 Sebastien Helleu <flashcode@flashtux.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
/*
* rmodifier.c: alter modifier strings with regular expressions
* (useful for hiding passwords in input or command history)
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "../weechat-plugin.h"
#include "rmodifier.h"
#include "rmodifier-command.h"
#include "rmodifier-completion.h"
#include "rmodifier-config.h"
#include "rmodifier-debug.h"
#include "rmodifier-info.h"
WEECHAT_PLUGIN_NAME(RMODIFIER_PLUGIN_NAME);
WEECHAT_PLUGIN_DESCRIPTION("Regex modifier plugin for WeeChat");
WEECHAT_PLUGIN_AUTHOR("Sebastien Helleu <flashcode@flashtux.org>");
WEECHAT_PLUGIN_VERSION(WEECHAT_VERSION);
WEECHAT_PLUGIN_LICENSE(WEECHAT_LICENSE);
struct t_weechat_plugin *weechat_rmodifier_plugin = NULL;
struct t_rmodifier *rmodifier_list = NULL;
struct t_rmodifier *last_rmodifier = NULL;
int rmodifier_count = 0;
struct t_weelist *rmodifier_hook_list = NULL;
/*
* rmodifier_valid: check if a rmodifier pointer exists
* return 1 if rmodifier exists
* 0 if rmodifier is not found
*/
int
rmodifier_valid (struct t_rmodifier *rmodifier)
{
struct t_rmodifier *ptr_rmodifier;
if (!rmodifier)
return 0;
for (ptr_rmodifier = rmodifier_list; ptr_rmodifier;
ptr_rmodifier = ptr_rmodifier->next_rmodifier)
{
if (ptr_rmodifier == rmodifier)
return 1;
}
/* rmodifier not found */
return 0;
}
/*
* rmodifier_search: search a rmodifier
*/
struct t_rmodifier *
rmodifier_search (const char *name)
{
struct t_rmodifier *ptr_rmodifier;
for (ptr_rmodifier = rmodifier_list; ptr_rmodifier;
ptr_rmodifier = ptr_rmodifier->next_rmodifier)
{
if (strcmp (name, ptr_rmodifier->name) == 0)
return ptr_rmodifier;
}
return NULL;
}
/*
* rmodifier_hide_string: hide a string (using char defined in option
* "rmodifier.look.hide_char")
*/
char *
rmodifier_hide_string (const char *string)
{
int length, i;
char *result;
if (!string || !string[0])
return NULL;
length = weechat_utf8_strlen (string);
result = malloc ((length * strlen (weechat_config_string (rmodifier_config_look_hide_char))) + 1);
if (!result)
return NULL;
result[0] = '\0';
for (i = 0; i < length; i++)
{
strcat (result, weechat_config_string (rmodifier_config_look_hide_char));
}
return result;
}
/*
* rmodifier_replace_groups: replace groups in a string, using regex_match
* found by call to regexec()
*/
char *
rmodifier_replace_groups (const char *string, regmatch_t regex_match[],
const char *groups)
{
char *result, *str_group, *string_to_add;
const char *ptr_groups;
int length, num_group;
length = 1;
result = malloc (length);
if (!result)
return NULL;
result[0] = '\0';
ptr_groups = groups;
while (ptr_groups && ptr_groups[0])
{
if ((ptr_groups[0] >= '1') && (ptr_groups[0] <= '9'))
{
num_group = ptr_groups[0] - '0';
if (regex_match[num_group].rm_so >= 0)
{
str_group = weechat_strndup (string + regex_match[num_group].rm_so,
regex_match[num_group].rm_eo -regex_match[num_group].rm_so);
if (str_group)
{
string_to_add = NULL;
if (ptr_groups[1] == '*')
string_to_add = rmodifier_hide_string (str_group);
else
string_to_add = strdup (str_group);
if (string_to_add)
{
length += strlen (string_to_add);
result = realloc (result, length);
if (!result)
return NULL;
strcat (result, string_to_add);
free (string_to_add);
}
free (str_group);
}
}
}
ptr_groups = weechat_utf8_next_char (ptr_groups);
}
return result;
}
/*
* rmodifier_modifier_cb: callback for a modifier
*/
char *
rmodifier_modifier_cb (void *data, const char *modifier,
const char *modifier_data, const char *string)
{
struct t_rmodifier *rmodifier;
regmatch_t regex_match[9];
int i;
/* make C compiler happy */
(void) modifier;
(void) modifier_data;
rmodifier = (struct t_rmodifier *)data;
/* reset matching groups */
for (i = 0; i < 9; i++)
{
regex_match[i].rm_so = -1;
}
/* execute regex and return modified string if matching */
if (regexec (rmodifier->regex, string, 9, regex_match, 0) == 0)
{
return rmodifier_replace_groups (string, regex_match,
rmodifier->groups);
}
/* regex not matching */
return NULL;
}
/*
* rmodifier_create_regex: create regex for a rmodifier
*/
void
rmodifier_create_regex (struct t_rmodifier *rmodifier)
{
if (rmodifier->regex)
{
regfree (rmodifier->regex);
free (rmodifier->regex);
}
rmodifier->regex = malloc (sizeof (*rmodifier->regex));
if (!rmodifier->regex)
return;
if (regcomp (rmodifier->regex, rmodifier->str_regex,
REG_EXTENDED | REG_ICASE) != 0)
{
weechat_printf (NULL,
_("%s%s: error compiling regular expression \"%s\""),
weechat_prefix ("error"), RMODIFIER_PLUGIN_NAME,
rmodifier->str_regex);
free (rmodifier->regex);
return;
}
}
/*
* rmodifier_hook_modifiers: hook modifiers for a rmodifier
*/
void
rmodifier_hook_modifiers (struct t_rmodifier *rmodifier)
{
char **argv;
int argc, i;
argv = weechat_string_split (rmodifier->modifiers, ",", 0, 0, &argc);
if (argv)
{
rmodifier->hooks = malloc (sizeof (*rmodifier->hooks) * argc);
if (rmodifier->hooks)
{
for (i = 0; i < argc; i++)
{
rmodifier->hooks[i] = weechat_hook_modifier (argv[i],
&rmodifier_modifier_cb,
rmodifier);
}
rmodifier->hooks_count = argc;
}
weechat_string_free_split (argv);
}
}
/*
* rmodifier_new: create new rmodifier and add it to rmodifier list
*/
struct t_rmodifier *
rmodifier_new (const char *name, const char *modifiers, const char *str_regex,
const char *groups)
{
struct t_rmodifier *new_rmodifier, *ptr_rmodifier;
if (!name || !name[0] || !modifiers || !modifiers[0]
|| !str_regex || !str_regex[0])
return NULL;
ptr_rmodifier = rmodifier_search (name);
if (ptr_rmodifier)
rmodifier_free (ptr_rmodifier);
new_rmodifier = malloc (sizeof (*new_rmodifier));
if (new_rmodifier)
{
new_rmodifier->name = strdup (name);
new_rmodifier->hooks = NULL;
new_rmodifier->modifiers = strdup (modifiers);
new_rmodifier->str_regex = strdup (str_regex);
new_rmodifier->regex = NULL;
new_rmodifier->groups = strdup ((groups) ? groups : "");
/* create regex and modifiers */
rmodifier_create_regex (new_rmodifier);
rmodifier_hook_modifiers (new_rmodifier);
if (rmodifier_list)
{
/* add rmodifier to end of list */
new_rmodifier->prev_rmodifier = last_rmodifier;
new_rmodifier->next_rmodifier = NULL;
last_rmodifier->next_rmodifier = new_rmodifier;
last_rmodifier = new_rmodifier;
}
else
{
new_rmodifier->prev_rmodifier = NULL;
new_rmodifier->next_rmodifier = NULL;
rmodifier_list = new_rmodifier;
last_rmodifier = new_rmodifier;
}
rmodifier_count++;
}
return new_rmodifier;
}
/*
* rmodifier_new_with_string: create a rmodifier with a single string, which
* contains: "modifiers;regex;groups"
*/
struct t_rmodifier *
rmodifier_new_with_string (const char *name, const char *value)
{
struct t_rmodifier *new_rmodifier;
char *pos1, *pos2, *modifiers, *str_regex;
new_rmodifier = NULL;
pos1 = strchr (value, ';');
pos2 = rindex (value, ';');
if (pos1 && pos2 && (pos2 > pos1))
{
modifiers = weechat_strndup (value, pos1 - value);
str_regex = weechat_strndup (pos1 + 1, pos2 - (pos1 + 1));
if (modifiers && str_regex)
{
new_rmodifier = rmodifier_new (name,
modifiers, str_regex, pos2 + 1);
}
if (modifiers)
free (modifiers);
if (str_regex)
free (str_regex);
}
return new_rmodifier;
}
/*
* rmodifer_create_default: create default rmodifiers
*/
void
rmodifier_create_default ()
{
int i;
for (i = 0; rmodifier_config_default_list[i][0]; i++)
{
if (rmodifier_new (rmodifier_config_default_list[i][0],
rmodifier_config_default_list[i][1],
rmodifier_config_default_list[i][2],
rmodifier_config_default_list[i][3]))
{
rmodifier_config_modifier_new_option (rmodifier_config_default_list[i][0],
rmodifier_config_default_list[i][1],
rmodifier_config_default_list[i][2],
rmodifier_config_default_list[i][3]);
}
}
}
/*
* rmodifier_free: free a rmodifier and remove it from list
*/
void
rmodifier_free (struct t_rmodifier *rmodifier)
{
struct t_rmodifier *new_rmodifier_list;
int i;
/* remove rmodifier from list */
if (last_rmodifier == rmodifier)
last_rmodifier = rmodifier->prev_rmodifier;
if (rmodifier->prev_rmodifier)
{
(rmodifier->prev_rmodifier)->next_rmodifier = rmodifier->next_rmodifier;
new_rmodifier_list = rmodifier_list;
}
else
new_rmodifier_list = rmodifier->next_rmodifier;
if (rmodifier->next_rmodifier)
(rmodifier->next_rmodifier)->prev_rmodifier = rmodifier->prev_rmodifier;
/* free data */
if (rmodifier->name)
free (rmodifier->name);
if (rmodifier->modifiers)
free (rmodifier->modifiers);
if (rmodifier->hooks)
{
for (i = 0; i < rmodifier->hooks_count; i++)
{
weechat_unhook (rmodifier->hooks[i]);
}
free (rmodifier->hooks);
}
if (rmodifier->str_regex)
free (rmodifier->str_regex);
if (rmodifier->regex)
{
regfree (rmodifier->regex);
free (rmodifier->regex);
}
if (rmodifier->groups)
free (rmodifier->groups);
free (rmodifier);
rmodifier_count--;
rmodifier_list = new_rmodifier_list;
}
/*
* rmodifier_free_all: free all rmodifier
*/
void
rmodifier_free_all ()
{
while (rmodifier_list)
{
rmodifier_free (rmodifier_list);
}
}
/*
* rmodifier_add_to_infolist: add a rmodifier in an infolist
* return 1 if ok, 0 if error
*/
int
rmodifier_add_to_infolist (struct t_infolist *infolist,
struct t_rmodifier *rmodifier)
{
struct t_infolist_item *ptr_item;
char option_name[64];
int i;
if (!infolist || !rmodifier)
return 0;
ptr_item = weechat_infolist_new_item (infolist);
if (!ptr_item)
return 0;
if (!weechat_infolist_new_var_string (ptr_item, "name", rmodifier->name))
return 0;
if (!weechat_infolist_new_var_string (ptr_item, "modifiers", rmodifier->modifiers))
return 0;
for (i = 0; i < rmodifier->hooks_count; i++)
{
snprintf (option_name, sizeof (option_name), "hook_%05d", i + 1);
if (!weechat_infolist_new_var_pointer (ptr_item, option_name,
rmodifier->hooks[i]))
return 0;
}
if (!weechat_infolist_new_var_integer (ptr_item, "hooks_count", rmodifier->hooks_count))
return 0;
if (!weechat_infolist_new_var_string (ptr_item, "str_regex", rmodifier->str_regex))
return 0;
if (!weechat_infolist_new_var_pointer (ptr_item, "regex", rmodifier->regex))
return 0;
if (!weechat_infolist_new_var_string (ptr_item, "groups", rmodifier->groups))
return 0;
return 1;
}
/*
* rmodifier_print_log: print rmodifiers in log (usually for crash dump)
*/
void
rmodifier_print_log ()
{
struct t_rmodifier *ptr_rmodifier;
int i;
for (ptr_rmodifier = rmodifier_list; ptr_rmodifier;
ptr_rmodifier = ptr_rmodifier->next_rmodifier)
{
weechat_log_printf ("");
weechat_log_printf ("[rmodifier %s (addr:0x%lx)]", ptr_rmodifier->name, ptr_rmodifier);
weechat_log_printf (" modifiers. . . . . . : '%s'", ptr_rmodifier->modifiers);
weechat_log_printf (" hooks. . . . . . . . : 0x%lx", ptr_rmodifier->hooks);
for (i = 0; i < ptr_rmodifier->hooks_count; i++)
{
weechat_log_printf (" hooks[%03d] . . . . : 0x%lx", i, ptr_rmodifier->hooks[i]);
}
weechat_log_printf (" hooks_count. . . . . : %d", ptr_rmodifier->hooks_count);
weechat_log_printf (" str_regex. . . . . . : '%s'", ptr_rmodifier->str_regex);
weechat_log_printf (" regex. . . . . . . . : 0x%lx", ptr_rmodifier->regex);
weechat_log_printf (" groups . . . . . . . : '%s'", ptr_rmodifier->groups);
weechat_log_printf (" prev_rmodifier . . . : 0x%lx", ptr_rmodifier->prev_rmodifier);
weechat_log_printf (" next_rmodifier . . . : 0x%lx", ptr_rmodifier->next_rmodifier);
}
}
/*
* weechat_plugin_init: initialize rmodifier plugin
*/
int
weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[])
{
/* make C compiler happy */
(void) argc;
(void) argv;
weechat_plugin = plugin;
rmodifier_count = 0;
rmodifier_hook_list = weechat_list_new ();
if (!rmodifier_config_init ())
{
weechat_printf (NULL,
_("%s%s: error creating configuration file"),
weechat_prefix("error"), RMODIFIER_PLUGIN_NAME);
return WEECHAT_RC_ERROR;
}
rmodifier_config_read ();
rmodifier_command_init ();
rmodifier_completion_init ();
rmodifier_info_init ();
rmodifier_debug_init ();
return WEECHAT_RC_OK;
}
/*
* weechat_plugin_end: end rmodifier plugin
*/
int
weechat_plugin_end (struct t_weechat_plugin *plugin)
{
/* make C compiler happy */
(void) plugin;
rmodifier_config_write ();
rmodifier_free_all ();
weechat_list_free (rmodifier_hook_list);
weechat_config_free (rmodifier_config_file);
return WEECHAT_RC_OK;
}
+62
View File
@@ -0,0 +1,62 @@
/*
* Copyright (C) 2010 Sebastien Helleu <flashcode@flashtux.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef __WEECHAT_RMODIFIER_H
#define __WEECHAT_RMODIFIER_H 1
#include <regex.h>
#define weechat_plugin weechat_rmodifier_plugin
#define RMODIFIER_PLUGIN_NAME "rmodifier"
struct t_rmodifier
{
char *name; /* name of rmodifier */
char *modifiers; /* modifiers */
struct t_hook **hooks; /* hooks for modifiers */
int hooks_count; /* number of hooks */
char *str_regex; /* string with regex */
regex_t *regex; /* regex */
char *groups; /* actions on groups in regex */
/* (keep, delete, hide) */
struct t_rmodifier *prev_rmodifier; /* link to previous rmodifier */
struct t_rmodifier *next_rmodifier; /* link to next rmodifier */
};
extern struct t_rmodifier *rmodifier_list;
extern int rmodifier_count;
extern struct t_weechat_plugin *weechat_rmodifier_plugin;
extern int rmodifier_valid (struct t_rmodifier *rmodifier);
extern struct t_rmodifier *rmodifier_search (const char *name);
struct t_rmodifier *rmodifier_new (const char *name,
const char *modifiers,
const char *str_regex,
const char *groups);
extern struct t_rmodifier *rmodifier_new_with_string (const char *name,
const char *value);
extern void rmodifier_create_default ();
extern void rmodifier_free (struct t_rmodifier *rmodifier);
extern void rmodifier_free_all ();
extern int rmodifier_add_to_infolist (struct t_infolist *infolist,
struct t_rmodifier *rmodifier);
extern void rmodifier_print_log ();
#endif /* __WEECHAT_RMODIFIER_H */