1
0
mirror of https://github.com/weechat/weechat.git synced 2026-06-25 20:36:38 +02:00
Files
weechat/src/plugins/plugin-config.c
T
Sébastien Helleu cf6aca1619 core: add pointer in some callbacks (closes #406)
This pointer is the first argument received by callbacks, and the
existing argument "data" is now automatically freed by WeeChat when the
object containing the callback is removed.

With this new pointer, the linked list of callbacks in scripts has been
removed. This will improve speed of scripts (using a lot of hooks),
reduce memory used by scripts and reduce time to unload scripts.

Following functions are affected in the C API:

* exec_on_files
* config_new
* config_new_section
* config_new_option
* hook_command
* hook_command_run
* hook_timer
* hook_fd
* hook_process
* hook_process_hashtable
* hook_connect
* hook_print
* hook_signal
* hook_hsignal
* hook_config
* hook_completion
* hook_modifier
* hook_info
* hook_info_hashtable
* hook_infolist
* hook_hdata
* hook_focus
* unhook_all_plugin
* buffer_new
* bar_item_new
* upgrade_new
* upgrade_read
2016-03-21 18:11:21 +01:00

407 lines
11 KiB
C

/*
* plugin-config.c - plugin configuration options (file plugins.conf)
*
* Copyright (C) 2003-2016 Sébastien 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/>.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "../core/weechat.h"
#include "../core/wee-config.h"
#include "../core/wee-hook.h"
#include "../core/wee-list.h"
#include "../core/wee-log.h"
#include "../core/wee-string.h"
#include "plugin-config.h"
#include "weechat-plugin.h"
struct t_config_file *plugin_config_file = NULL;
struct t_config_section *plugin_config_section_var = NULL;
struct t_config_section *plugin_config_section_desc = NULL;
/*
* Searches for a plugin option.
*/
struct t_config_option *
plugin_config_search (const char *plugin_name, const char *option_name)
{
int length;
char *option_full_name;
struct t_config_option *ptr_option;
ptr_option = NULL;
length = strlen (plugin_name) + 1 + strlen (option_name) + 1;
option_full_name = malloc (length);
if (option_full_name)
{
snprintf (option_full_name, length, "%s.%s",
plugin_name, option_name);
ptr_option = config_file_search_option (plugin_config_file,
plugin_config_section_var,
option_full_name);
free (option_full_name);
}
return ptr_option;
}
/*
* Sets value for a plugin option (this function must not be called directly).
*/
int
plugin_config_set_internal (const char *option, const char *value)
{
int rc;
struct t_config_option *ptr_option;
ptr_option = config_file_search_option (plugin_config_file,
plugin_config_section_var,
option);
if (ptr_option)
{
rc = config_file_option_set (ptr_option, value, 0);
}
else
{
ptr_option = config_file_new_option (
plugin_config_file, plugin_config_section_var,
option, "string", NULL,
NULL, 0, 0, "", value, 0,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
rc = (ptr_option) ? WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE : WEECHAT_CONFIG_OPTION_SET_ERROR;
}
return rc;
}
/*
* Sets value for a plugin option (option is created if not found).
*/
int
plugin_config_set (const char *plugin_name, const char *option_name,
const char *value)
{
int length, rc;
char *option_full_name;
rc = WEECHAT_CONFIG_OPTION_SET_ERROR;
length = strlen (plugin_name) + 1 + strlen (option_name) + 1;
option_full_name = malloc (length);
if (option_full_name)
{
snprintf (option_full_name, length, "%s.%s",
plugin_name, option_name);
string_tolower (option_full_name);
rc = plugin_config_set_internal (option_full_name, value);
free (option_full_name);
}
return rc;
}
/*
* Callback for changes on a description option.
*/
void
plugin_config_desc_changed_cb (const void *pointer, void *data,
struct t_config_option *option)
{
struct t_config_option *ptr_option;
/* make C compiler happy */
(void) pointer;
(void) data;
ptr_option = config_file_search_option (plugin_config_file,
plugin_config_section_var,
option->name);
if (ptr_option)
{
if (ptr_option->description)
{
free (ptr_option->description);
ptr_option->description = NULL;
}
if (option->value)
ptr_option->description = strdup (option->value);
}
}
/*
* Sets description for a plugin option (this function must not be called
* directly).
*/
void
plugin_config_set_desc_internal (const char *option, const char *value)
{
struct t_config_option *ptr_option;
ptr_option = config_file_search_option (plugin_config_file,
plugin_config_section_desc,
option);
if (ptr_option)
{
config_file_option_set (ptr_option, value, 1);
}
else
{
ptr_option = config_file_new_option (
plugin_config_file, plugin_config_section_desc,
option, "string", _("description of plugin option"),
NULL, 0, 0, "", value, 0,
NULL, NULL, NULL,
&plugin_config_desc_changed_cb, NULL, NULL,
NULL, NULL, NULL);
}
if (ptr_option)
plugin_config_desc_changed_cb (NULL, NULL, ptr_option);
}
/*
* Sets description for a plugin option.
*/
void
plugin_config_set_desc (const char *plugin_name, const char *option_name,
const char *description)
{
int length;
char *option_full_name;
length = strlen (plugin_name) + 1 + strlen (option_name) + 1;
option_full_name = malloc (length);
if (option_full_name)
{
snprintf (option_full_name, length, "%s.%s",
plugin_name, option_name);
string_tolower (option_full_name);
plugin_config_set_desc_internal (option_full_name, description);
free (option_full_name);
}
}
/*
* Reloads plugins configuration file.
*/
int
plugin_config_reload (const void *pointer, void *data,
struct t_config_file *config_file)
{
/* make C compiler happy */
(void) pointer;
(void) data;
/* remove all plugin options and descriptions */
config_file_section_free_options (plugin_config_section_var);
config_file_section_free_options (plugin_config_section_desc);
/* reload plugins configuration file */
return config_file_reload (config_file);
}
/*
* Sets a plugin option.
*/
int
plugin_config_create_option (const void *pointer, void *data,
struct t_config_file *config_file,
struct t_config_section *section,
const char *option_name, const char *value)
{
struct t_config_option *ptr_option_desc, *ptr_option;
/* make C compiler happy */
(void) pointer;
(void) data;
ptr_option_desc = config_file_search_option (config_file,
plugin_config_section_desc,
option_name);
ptr_option = config_file_new_option (
config_file, section,
option_name, "string",
(ptr_option_desc) ? CONFIG_STRING(ptr_option_desc) : NULL,
NULL, 0, 0, "", value, 0,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
return (ptr_option) ?
WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE : WEECHAT_CONFIG_OPTION_SET_ERROR;
}
/*
* Sets a plugin option description.
*/
int
plugin_config_create_desc (const void *pointer, void *data,
struct t_config_file *config_file,
struct t_config_section *section,
const char *option_name, const char *value)
{
struct t_config_option *ptr_option_var, *ptr_option;
/* make C compiler happy */
(void) pointer;
(void) data;
ptr_option_var = config_file_search_option (config_file,
plugin_config_section_var,
option_name);
if (ptr_option_var)
{
if (ptr_option_var->description)
{
free (ptr_option_var->description);
ptr_option_var->description = NULL;
}
if (value)
ptr_option_var->description = strdup (value);
}
ptr_option = config_file_new_option (
config_file, section,
option_name, "string", _("description of plugin option"),
NULL, 0, 0, "", value, 0,
NULL, NULL, NULL,
&plugin_config_desc_changed_cb, NULL, NULL,
NULL, NULL, NULL);
return (ptr_option) ?
WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE : WEECHAT_CONFIG_OPTION_SET_ERROR;
}
/*
* Deletes a plugin option description.
*/
int
plugin_config_delete_desc (const void *pointer, void *data,
struct t_config_file *config_file,
struct t_config_section *section,
struct t_config_option *option)
{
struct t_config_option *ptr_option_var;
/* make C compiler happy */
(void) pointer;
(void) data;
(void) section;
ptr_option_var = config_file_search_option (config_file,
plugin_config_section_var,
option->name);
if (ptr_option_var)
{
if (ptr_option_var->description)
{
free (ptr_option_var->description);
ptr_option_var->description = NULL;
}
}
config_file_option_free (option);
return WEECHAT_CONFIG_OPTION_UNSET_OK_REMOVED;
}
/*
* Initializes plugins configuration structure.
*/
void
plugin_config_init ()
{
plugin_config_file = config_file_new (NULL, PLUGIN_CONFIG_NAME,
&plugin_config_reload, NULL, NULL);
if (plugin_config_file)
{
plugin_config_section_var = config_file_new_section (
plugin_config_file, "var", 1, 1,
NULL, NULL, NULL,
NULL, NULL, NULL,
NULL, NULL, NULL,
&plugin_config_create_option, NULL, NULL,
NULL, NULL, NULL);
plugin_config_section_desc = config_file_new_section (
plugin_config_file, "desc", 1, 1,
NULL, NULL, NULL,
NULL, NULL, NULL,
NULL, NULL, NULL,
&plugin_config_create_desc, NULL, NULL,
&plugin_config_delete_desc, NULL, NULL);
}
else
{
plugin_config_section_var = NULL;
plugin_config_section_desc = NULL;
}
}
/*
* Reads plugins configuration file.
*/
int
plugin_config_read ()
{
return config_file_read (plugin_config_file);
}
/*
* Writes plugins configuration file.
*/
int
plugin_config_write ()
{
return config_file_write (plugin_config_file);
}
/*
* Ends plugin configuration.
*/
void
plugin_config_end ()
{
/* free all plugin configuration options and descriptions */
config_file_section_free_options (plugin_config_section_var);
config_file_section_free_options (plugin_config_section_desc);
}