1
0
mirror of https://github.com/weechat/weechat.git synced 2026-06-25 04:16:38 +02:00
Files
weechat/src/plugins/fset/fset-option.c
T
2020-08-09 10:56:03 +02:00

1851 lines
56 KiB
C

/*
* fset-option.c - manage options displayed by Fast Set buffer
*
* Copyright (C) 2003-2020 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 <https://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include "../weechat-plugin.h"
#include "fset.h"
#include "fset-option.h"
#include "fset-buffer.h"
#include "fset-config.h"
/* options */
struct t_arraylist *fset_options = NULL;
int fset_option_count_marked = 0;
struct t_fset_option_max_length *fset_option_max_length = NULL;
/* filters */
char *fset_option_filter = NULL;
struct t_hashtable *fset_option_filter_hashtable_pointers = NULL;
struct t_hashtable *fset_option_filter_hashtable_extra_vars = NULL;
struct t_hashtable *fset_option_filter_hashtable_options = NULL;
/* refresh */
struct t_hashtable *fset_option_timer_options_changed = NULL;
struct t_hook *fset_option_timer_hook = NULL;
/* types */
char *fset_option_type_string[FSET_OPTION_NUM_TYPES] =
{ N_("boolean"), N_("integer"), N_("string"), N_("color") };
char *fset_option_type_string_short[FSET_OPTION_NUM_TYPES] =
{ "bool", "int", "str", "col" };
char *fset_option_type_string_tiny[FSET_OPTION_NUM_TYPES] =
{ "b", "i", "s", "c" };
/*
* Checks if a fset option pointer is valid.
*
* Returns:
* 1: option exists
* 0: option does not exist
*/
int
fset_option_valid (struct t_fset_option *fset_option)
{
struct t_fset_option *ptr_fset_option;
int num_options, i;
if (!fset_option)
return 0;
num_options = weechat_arraylist_size (fset_options);
for (i = 0; i < num_options; i++)
{
ptr_fset_option = weechat_arraylist_get (fset_options, i);
if (ptr_fset_option == fset_option)
return 1;
}
/* fset option not found */
return 0;
}
/*
* Searches for an option by name.
*
* If line is not NULL, *line is set with the line number of option found
* (-1 if line is not found).
*
* Returns pointer to option found, NULL if not found.
*/
struct t_fset_option *
fset_option_search_by_name (const char *name, int *line)
{
struct t_fset_option *ptr_fset_option;
int num_options, i;
if (line)
*line = -1;
num_options = weechat_arraylist_size (fset_options);
for (i = 0; i < num_options; i++)
{
ptr_fset_option = weechat_arraylist_get (fset_options, i);
if (ptr_fset_option && (strcmp (ptr_fset_option->name, name) == 0))
{
if (line)
*line = i;
return ptr_fset_option;
}
}
/* fset option not found */
return NULL;
}
/*
* Checks if the option value is changed (different from the default value).
*
* Returns:
* 1: value has been changed
* 0: value is the same as default value
*/
int
fset_option_value_is_changed (struct t_fset_option *fset_option)
{
if (!fset_option->value && !fset_option->default_value)
return 0;
if ((fset_option->value && !fset_option->default_value)
|| (!fset_option->value && fset_option->default_value))
{
return 1;
}
return (strcmp (fset_option->value,
fset_option->default_value) != 0) ? 1 : 0;
}
/*
* Sets the value in option, according to its type.
*/
void
fset_option_set_value_string (struct t_config_option *option,
enum t_fset_option_type type, void *value,
int default_value,
char **value_string)
{
char str_value[64];
void *ptr_string_values;
if (!value)
{
*value_string = NULL;
}
else
{
switch (type)
{
case FSET_OPTION_TYPE_BOOLEAN:
*value_string = strdup (*((int *)value) ? "on" : "off");
break;
case FSET_OPTION_TYPE_INTEGER:
ptr_string_values = weechat_config_option_get_pointer (
option, "string_values");
if (ptr_string_values)
{
*value_string = strdup (
(default_value) ? weechat_config_string_default (option) : weechat_config_string (option));
}
else
{
snprintf (str_value, sizeof (str_value), "%d", *((int *)value));
*value_string = strdup (str_value);
}
break;
case FSET_OPTION_TYPE_STRING:
*value_string = strdup (
(default_value) ? weechat_config_string_default (option) : weechat_config_string (option));
break;
case FSET_OPTION_TYPE_COLOR:
*value_string = strdup (
(default_value) ? weechat_config_color_default (option) : weechat_config_color (option));
break;
case FSET_OPTION_NUM_TYPES:
break;
}
}
}
/*
* Checks if a string matches a mask.
*
* If mask has no "*" inside, it just checks if "mask" is inside the "string".
* If mask has at least one "*" inside, the function weechat_string_match is
* used.
*
* Returns:
* 1: string matches mask
* 0: string does not match mask
*/
int
fset_option_string_match (const char *string, const char *mask)
{
if (strchr (mask, '*'))
return weechat_string_match (string, mask, 0);
else
return (weechat_strcasestr (string, mask)) ? 1 : 0;
}
/*
* Adds the properties of an fset option in a hashtable
* (keys and values must be strings).
*/
void
fset_option_add_option_in_hashtable (struct t_hashtable *hashtable,
struct t_fset_option *fset_option)
{
int length;
char *value;
weechat_hashtable_set (hashtable, "file", fset_option->file);
weechat_hashtable_set (hashtable, "section", fset_option->section);
weechat_hashtable_set (hashtable, "option", fset_option->option);
weechat_hashtable_set (hashtable, "name", fset_option->name);
weechat_hashtable_set (hashtable, "parent_name", fset_option->parent_name);
weechat_hashtable_set (hashtable,
"type", _(fset_option_type_string[fset_option->type]));
weechat_hashtable_set (hashtable,
"type_en", fset_option_type_string[fset_option->type]);
weechat_hashtable_set (hashtable,
"type_short", fset_option_type_string_short[fset_option->type]);
weechat_hashtable_set (hashtable,
"type_tiny", fset_option_type_string_tiny[fset_option->type]);
weechat_hashtable_set (hashtable,
"default_value", fset_option->default_value);
weechat_hashtable_set (hashtable, "value", fset_option->value);
if (fset_option->value && (fset_option->type == FSET_OPTION_TYPE_STRING))
{
length = 1 + strlen (fset_option->value) + 1 + 1;
value = malloc (length);
if (value)
{
snprintf (value, length, "\"%s\"", fset_option->value);
weechat_hashtable_set (hashtable, "quoted_value", value);
free (value);
}
else
{
weechat_hashtable_set (hashtable,
"quoted_value", fset_option->value);
}
}
else
{
weechat_hashtable_set (hashtable, "quoted_value", fset_option->value);
}
weechat_hashtable_set (hashtable,
"parent_value", fset_option->parent_value);
weechat_hashtable_set (hashtable, "min", fset_option->min);
weechat_hashtable_set (hashtable, "max", fset_option->max);
weechat_hashtable_set (hashtable,
"description",
(fset_option->description && fset_option->description[0]) ?
_(fset_option->description) : "");
weechat_hashtable_set (hashtable,
"description2",
(fset_option->description && fset_option->description[0]) ?
_(fset_option->description) : _("(no description)"));
weechat_hashtable_set (hashtable,
"description_en", fset_option->description);
weechat_hashtable_set (hashtable,
"description_en2",
(fset_option->description && fset_option->description[0]) ?
fset_option->description : "(no description)");
weechat_hashtable_set (hashtable,
"string_values", fset_option->string_values);
weechat_hashtable_set (hashtable,
"default_value_undef",
(fset_option->default_value == NULL) ? "1" : "0");
weechat_hashtable_set (hashtable,
"value_undef",
(fset_option->value == NULL) ? "1" : "0");
weechat_hashtable_set (hashtable,
"value_changed",
(fset_option_value_is_changed (fset_option)) ? "1" : "0");
}
/*
* Checks if an option is matching current filter(s).
*
* Returns:
* 1: option is matching filter(s)
* 0: option does not match filter(s)
*/
int
fset_option_match_filter (struct t_fset_option *fset_option, const char *filter)
{
int match;
char *result;
if (!filter || !filter[0])
return 1;
if (strncmp (filter, "c:", 2) == 0)
{
/* filter by evaluated condition */
weechat_hashtable_set (fset_option_filter_hashtable_pointers,
"fset_option", fset_option);
fset_option_add_option_in_hashtable (
fset_option_filter_hashtable_extra_vars,
fset_option);
result = weechat_string_eval_expression (
filter + 2,
fset_option_filter_hashtable_pointers,
fset_option_filter_hashtable_extra_vars,
fset_option_filter_hashtable_options);
match = (result && (strcmp (result, "1") == 0)) ? 1 : 0;
if (result)
free (result);
return match;
}
else if (strncmp (filter, "f:", 2) == 0)
{
/* filter by config name */
return (weechat_strcasecmp (fset_option->file,
filter + 2) == 0) ? 1 : 0;
}
else if (strncmp (filter, "t:", 2) == 0)
{
/* filter by type */
return (weechat_strcasecmp (
fset_option_type_string_short[fset_option->type],
filter + 2) == 0) ? 1 : 0;
}
else if (strncmp (filter, "d==", 3) == 0)
{
/* filter by modified values (on exact value) */
if (!fset_option_value_is_changed (fset_option))
return 0;
return (weechat_strcasecmp (
(fset_option->value) ? fset_option->value : FSET_OPTION_VALUE_NULL,
filter + 3) == 0) ? 1 : 0;
}
else if (strncmp (filter, "d=", 2) == 0)
{
/* filter by modified values (on value) */
if (!fset_option_value_is_changed (fset_option))
return 0;
return (fset_option_string_match (
(fset_option->value) ? fset_option->value : FSET_OPTION_VALUE_NULL,
filter + 2)) ? 1 : 0;
}
else if (strncmp (filter, "d:", 2) == 0)
{
/* filter by modified values (on name) */
if (!fset_option_value_is_changed (fset_option))
return 0;
return fset_option_string_match (fset_option->name,
filter + 2) ? 1 : 0;
}
else if (strcmp (filter, "d") == 0)
{
/* filter by modified values */
return (fset_option_value_is_changed (fset_option)) ? 1 : 0;
}
else if (strncmp (filter, "h=", 2) == 0)
{
/* filter by help text (translated) */
return (fset_option_string_match (
(fset_option->description && fset_option->description[0]) ?
_(fset_option->description) : "",
filter + 2)) ? 1 : 0;
}
else if (strncmp (filter, "he=", 3) == 0)
{
/* filter by help text (in English) */
return (fset_option_string_match (
(fset_option->description && fset_option->description[0]) ?
fset_option->description : "",
filter + 3)) ? 1 : 0;
}
else if (strncmp (filter, "==", 2) == 0)
{
/* filter by exact value */
return (weechat_strcasecmp (
(fset_option->value) ? fset_option->value : FSET_OPTION_VALUE_NULL,
filter + 2) == 0) ? 1 : 0;
}
else if (filter[0] == '=')
{
/* filter by value */
return (fset_option_string_match (
(fset_option->value) ? fset_option->value : FSET_OPTION_VALUE_NULL,
filter + 1)) ? 1 : 0;
}
else
{
/* filter by option name */
return (fset_option_string_match (fset_option->name, filter)) ? 1 : 0;
}
}
/*
* Sets (or sets again) values (except name) in an fset option.
*/
void
fset_option_set_values (struct t_fset_option *fset_option,
struct t_config_option *option)
{
const char *ptr_config_name, *ptr_section_name, *ptr_option_name;
const char *ptr_parent_name, *ptr_description;
const char **ptr_string_values;
void *ptr_default_value, *ptr_value;
struct t_config_option *ptr_parent_option;
int length, *ptr_type, *ptr_min, *ptr_max;
char str_value[64];
/* file */
if (fset_option->file)
{
free (fset_option->file);
fset_option->file = NULL;
}
ptr_config_name = weechat_config_option_get_string (option, "config_name");
fset_option->file = strdup (ptr_config_name);
/* section */
if (fset_option->section)
{
free (fset_option->section);
fset_option->section = NULL;
}
ptr_section_name = weechat_config_option_get_string (option, "section_name");
fset_option->section = strdup (ptr_section_name);
/* option */
if (fset_option->option)
{
free (fset_option->option);
fset_option->option = NULL;
}
ptr_option_name = weechat_config_option_get_string (option, "name");
fset_option->option = strdup (ptr_option_name);
/* name */
if (fset_option->name)
{
free (fset_option->name);
fset_option->name = NULL;
}
length = strlen (ptr_config_name) + 1 +
strlen (ptr_section_name) + 1 +
strlen (ptr_option_name) + 1;
fset_option->name = malloc (length);
if (fset_option->name)
{
snprintf (fset_option->name, length, "%s.%s.%s",
ptr_config_name,
ptr_section_name,
ptr_option_name);
}
/* parent name */
if (fset_option->parent_name)
{
free (fset_option->parent_name);
fset_option->parent_name = NULL;
}
ptr_parent_name = weechat_config_option_get_string (option, "parent_name");
fset_option->parent_name = (ptr_parent_name) ? strdup (ptr_parent_name) : NULL;
/* type */
ptr_type = weechat_config_option_get_pointer (option, "type");
fset_option->type = *ptr_type;
/* default value */
if (fset_option->default_value)
{
free (fset_option->default_value);
fset_option->default_value = NULL;
}
ptr_default_value = weechat_config_option_get_pointer (option,
"default_value");
fset_option_set_value_string (option,
fset_option->type,
ptr_default_value,
1,
&fset_option->default_value);
/* value */
if (fset_option->value)
{
free (fset_option->value);
fset_option->value = NULL;
}
ptr_value = weechat_config_option_get_pointer (option, "value");
fset_option_set_value_string (option,
fset_option->type,
ptr_value,
0,
&fset_option->value);
/* parent_value */
if (fset_option->parent_value)
{
free (fset_option->parent_value);
fset_option->parent_value = NULL;
}
if (ptr_parent_name)
{
ptr_parent_option = weechat_config_get (ptr_parent_name);
if (ptr_parent_option)
{
ptr_value = weechat_config_option_get_pointer (ptr_parent_option,
"value");
fset_option_set_value_string (ptr_parent_option,
fset_option->type,
ptr_value,
0,
&fset_option->parent_value);
}
}
/* min value */
if (fset_option->min)
{
free (fset_option->min);
fset_option->min = NULL;
}
ptr_min = weechat_config_option_get_pointer (option, "min");
snprintf (str_value, sizeof (str_value), "%d", *ptr_min);
fset_option->min = strdup (str_value);
/* max value */
if (fset_option->max)
{
free (fset_option->max);
fset_option->max = NULL;
}
ptr_max = weechat_config_option_get_pointer (option, "max");
snprintf (str_value, sizeof (str_value), "%d", *ptr_max);
fset_option->max = strdup (str_value);
/* description */
if (fset_option->description)
{
free (fset_option->description);
fset_option->description = NULL;
}
ptr_description = weechat_config_option_get_string (option, "description");
fset_option->description = strdup ((ptr_description) ? ptr_description : "");
/* string_values */
if (fset_option->string_values)
{
free (fset_option->string_values);
fset_option->string_values = NULL;
}
ptr_string_values = weechat_config_option_get_pointer (option, "string_values");
if (ptr_string_values)
{
fset_option->string_values = weechat_string_build_with_split_string (
ptr_string_values, ",");
}
else
{
fset_option->string_values = strdup ("");
}
}
/*
* Sets max length for fields, for one option.
*/
void
fset_option_set_max_length_fields_option (struct t_fset_option *fset_option)
{
int length, length_value, length_parent_value;
/* file */
length = weechat_utf8_strlen_screen (fset_option->file);
if (length > fset_option_max_length->file)
fset_option_max_length->file = length;
/* section */
length = weechat_utf8_strlen_screen (fset_option->section);
if (length > fset_option_max_length->section)
fset_option_max_length->section = length;
/* option */
length = weechat_utf8_strlen_screen (fset_option->option);
if (length > fset_option_max_length->option)
fset_option_max_length->option = length;
/* name */
length = weechat_utf8_strlen_screen (fset_option->name);
if (length > fset_option_max_length->name)
fset_option_max_length->name = length;
/* parent_name */
length = (fset_option->parent_name) ?
weechat_utf8_strlen_screen (fset_option->name) : 0;
if (length > fset_option_max_length->parent_name)
fset_option_max_length->parent_name = length;
/* type */
length = weechat_utf8_strlen_screen (_(fset_option_type_string[fset_option->type]));
if (length > fset_option_max_length->type)
fset_option_max_length->type = length;
/* type_en */
length = weechat_utf8_strlen_screen (fset_option_type_string[fset_option->type]);
if (length > fset_option_max_length->type_en)
fset_option_max_length->type_en = length;
/* type_short */
length = weechat_utf8_strlen_screen (fset_option_type_string_short[fset_option->type]);
if (length > fset_option_max_length->type_short)
fset_option_max_length->type_short = length;
/* type_tiny */
length = weechat_utf8_strlen_screen (fset_option_type_string_tiny[fset_option->type]);
if (length > fset_option_max_length->type_tiny)
fset_option_max_length->type_tiny = length;
/* default_value */
if (fset_option->default_value)
{
length = weechat_utf8_strlen_screen (fset_option->default_value);
if (fset_option->type == FSET_OPTION_TYPE_STRING)
length += 2;
}
else
{
length = weechat_utf8_strlen_screen (FSET_OPTION_VALUE_NULL);
}
if (length > fset_option_max_length->default_value)
fset_option_max_length->default_value = length;
/* value */
if (fset_option->value)
{
length_value = weechat_utf8_strlen_screen (fset_option->value);
if (fset_option->type == FSET_OPTION_TYPE_STRING)
length_value += 2;
}
else
{
length_value = weechat_utf8_strlen_screen (FSET_OPTION_VALUE_NULL);
}
if (length_value > fset_option_max_length->value)
fset_option_max_length->value = length_value;
/* parent_value */
if (fset_option->parent_value)
{
length_parent_value = weechat_utf8_strlen_screen (fset_option->parent_value);
if (fset_option->type == FSET_OPTION_TYPE_STRING)
length_parent_value += 2;
}
else
{
length_parent_value = weechat_utf8_strlen_screen (FSET_OPTION_VALUE_NULL);
}
if (length_parent_value > fset_option_max_length->parent_value)
fset_option_max_length->parent_value = length_parent_value;
/* value2 */
length = length_value;
if (!fset_option->value)
length += 4 + length_parent_value;
if (length > fset_option_max_length->value2)
fset_option_max_length->value2 = length;
/* min */
length = weechat_utf8_strlen_screen (fset_option->min);
if (length > fset_option_max_length->min)
fset_option_max_length->min = length;
/* max */
length = weechat_utf8_strlen_screen (fset_option->max);
if (length > fset_option_max_length->max)
fset_option_max_length->max = length;
/* description */
length = (fset_option->description && fset_option->description[0]) ?
weechat_utf8_strlen_screen (_(fset_option->description)) : 0;
if (length > fset_option_max_length->description)
fset_option_max_length->description = length;
/* description2 */
length = weechat_utf8_strlen_screen (
(fset_option->description && fset_option->description[0]) ?
_(fset_option->description) : _("(no description)"));
if (length > fset_option_max_length->description2)
fset_option_max_length->description2 = length;
/* description_en */
length = weechat_utf8_strlen_screen (fset_option->description);
if (length > fset_option_max_length->description_en)
fset_option_max_length->description_en = length;
/* description_en2 */
length = weechat_utf8_strlen_screen (
(fset_option->description && fset_option->description[0]) ?
fset_option->description : _("(no description)"));
if (length > fset_option_max_length->description_en2)
fset_option_max_length->description_en2 = length;
/* string_values */
length = weechat_utf8_strlen_screen (fset_option->string_values);
if (length > fset_option_max_length->string_values)
fset_option_max_length->string_values = length;
/* marked */
length = weechat_utf8_strlen_screen (weechat_config_string (fset_config_look_marked_string));
if (length > fset_option_max_length->marked)
fset_option_max_length->marked = length;
length = weechat_utf8_strlen_screen (weechat_config_string (fset_config_look_unmarked_string));
if (length > fset_option_max_length->marked)
fset_option_max_length->marked = length;
}
/*
* Initializes max length for fields.
*/
void
fset_option_init_max_length (struct t_fset_option_max_length *max_length)
{
memset (max_length, 0, sizeof (*max_length));
}
/*
* Sets max length for fields, for all options.
*/
void
fset_option_set_max_length_fields_all ()
{
int i, num_options;
struct t_fset_option *ptr_fset_option;
/* first clear all max lengths */
fset_option_init_max_length (fset_option_max_length);
/* set max length for fields, for all options */
num_options = weechat_arraylist_size (fset_options);
for (i = 0; i < num_options; i++)
{
ptr_fset_option = weechat_arraylist_get (fset_options, i);
if (ptr_fset_option)
fset_option_set_max_length_fields_option (ptr_fset_option);
}
}
/*
* Allocates an fset option structure using a pointer to a
* WeeChat/plugin option.
*
* Returns pointer to new fset option, NULL if error.
*/
struct t_fset_option *
fset_option_alloc (struct t_config_option *option)
{
struct t_fset_option *new_fset_option;
new_fset_option = malloc (sizeof (*new_fset_option));
if (!new_fset_option)
return NULL;
new_fset_option->index = 0;
new_fset_option->file = NULL;
new_fset_option->section = NULL;
new_fset_option->option = NULL;
new_fset_option->name = NULL;
new_fset_option->parent_name = NULL;
new_fset_option->type = 0;
new_fset_option->default_value = NULL;
new_fset_option->value = NULL;
new_fset_option->parent_value = NULL;
new_fset_option->min = NULL;
new_fset_option->max = NULL;
new_fset_option->description = NULL;
new_fset_option->string_values = NULL;
new_fset_option->marked = 0;
fset_option_set_values (new_fset_option, option);
return new_fset_option;
}
/*
* Allocates an fset option structure using a pointer to a
* WeeChat/plugin option.
*
* Returns pointer to new fset option, NULL if the option does not match
* filters or if error.
*/
struct t_fset_option *
fset_option_add (struct t_config_option *option)
{
struct t_fset_option *new_fset_option;
new_fset_option = fset_option_alloc (option);
if (!new_fset_option)
return NULL;
if (!weechat_config_boolean (fset_config_look_show_plugins_desc)
&& (strcmp (new_fset_option->file, "plugins") == 0)
&& (strcmp (new_fset_option->section, "desc") == 0))
{
fset_option_free (new_fset_option);
return NULL;
}
/* check if option match filters (if not, ignore it) */
if (!fset_option_match_filter (new_fset_option, fset_option_filter))
{
fset_option_free (new_fset_option);
return NULL;
}
fset_option_set_max_length_fields_option (new_fset_option);
return new_fset_option;
}
/*
* Compares two options to sort them by name.
*/
int
fset_option_compare_options_cb (void *data, struct t_arraylist *arraylist,
void *pointer1, void *pointer2)
{
int i, reverse, case_sensitive, rc;
const char *ptr_field;
/* make C compiler happy */
(void) data;
(void) arraylist;
if (!fset_hdata_fset_option)
return 1;
for (i = 0; i < fset_config_sort_fields_count; i++)
{
reverse = 1;
case_sensitive = 1;
ptr_field = fset_config_sort_fields[i];
while ((ptr_field[0] == '-') || (ptr_field[0] == '~'))
{
if (ptr_field[0] == '-')
reverse *= -1;
else if (ptr_field[0] == '~')
case_sensitive ^= 1;
ptr_field++;
}
rc = weechat_hdata_compare (fset_hdata_fset_option,
pointer1, pointer2,
ptr_field,
case_sensitive);
rc *= reverse;
if (rc != 0)
return rc;
}
return 1;
}
/*
* Frees an fset option.
*/
void
fset_option_free (struct t_fset_option *fset_option)
{
if (!fset_option)
return;
if (fset_option->file)
free (fset_option->file);
if (fset_option->section)
free (fset_option->section);
if (fset_option->option)
free (fset_option->option);
if (fset_option->name)
free (fset_option->name);
if (fset_option->parent_name)
free (fset_option->parent_name);
if (fset_option->default_value)
free (fset_option->default_value);
if (fset_option->value)
free (fset_option->value);
if (fset_option->parent_value)
free (fset_option->parent_value);
if (fset_option->min)
free (fset_option->min);
if (fset_option->max)
free (fset_option->max);
if (fset_option->description)
free (fset_option->description);
if (fset_option->string_values)
free (fset_option->string_values);
free (fset_option);
}
/*
* Frees an fset option (arraylist callback).
*/
void
fset_option_free_cb (void *data, struct t_arraylist *arraylist, void *pointer)
{
struct t_fset_option *fset_option;
/* make C compiler happy */
(void) data;
(void) arraylist;
fset_option = (struct t_fset_option *)pointer;
fset_option_free (fset_option);
}
/*
* Allocates and returns the arraylist to store options.
*/
struct t_arraylist *
fset_option_get_arraylist_options ()
{
return weechat_arraylist_new (100, 1, 0,
&fset_option_compare_options_cb, NULL,
&fset_option_free_cb, NULL);
}
/*
* Allocates and returns the structure to store max length of fields.
*/
struct t_fset_option_max_length *
fset_option_get_max_length ()
{
struct t_fset_option_max_length *max_length;
max_length = malloc (sizeof (*fset_option_max_length));
if (max_length)
fset_option_init_max_length (max_length);
return max_length;
}
/*
* Gets all options to display in fset buffer.
*/
void
fset_option_get_options ()
{
struct t_fset_option *new_fset_option, *ptr_fset_option;
struct t_config_file *ptr_config;
struct t_config_section *ptr_section;
struct t_config_option *ptr_option;
struct t_hashtable *marked_options;
int i, num_options;
/* save marked options in a hashtable */
if (!weechat_config_boolean (fset_config_look_auto_unmark))
{
marked_options = weechat_hashtable_new (256,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_POINTER,
NULL, NULL);
num_options = weechat_arraylist_size (fset_options);
for (i = 0; i < num_options; i++)
{
ptr_fset_option = weechat_arraylist_get (fset_options, i);
if (ptr_fset_option && ptr_fset_option->marked)
weechat_hashtable_set (marked_options, ptr_fset_option->name, NULL);
}
}
else
{
marked_options = NULL;
}
/* clear options */
weechat_arraylist_clear (fset_options);
fset_option_count_marked = 0;
fset_option_init_max_length (fset_option_max_length);
/* get options */
ptr_config = weechat_hdata_get_list (fset_hdata_config_file,
"config_files");
while (ptr_config)
{
ptr_section = weechat_hdata_pointer (fset_hdata_config_file,
ptr_config, "sections");
while (ptr_section)
{
ptr_option = weechat_hdata_pointer (fset_hdata_config_section,
ptr_section, "options");
while (ptr_option)
{
new_fset_option = fset_option_add (ptr_option);
if (new_fset_option)
weechat_arraylist_add (fset_options, new_fset_option);
ptr_option = weechat_hdata_move (fset_hdata_config_option,
ptr_option, 1);
}
ptr_section = weechat_hdata_move (fset_hdata_config_section,
ptr_section, 1);
}
ptr_config = weechat_hdata_move (fset_hdata_config_file,
ptr_config, 1);
}
num_options = weechat_arraylist_size (fset_options);
for (i = 0; i < num_options; i++)
{
ptr_fset_option = weechat_arraylist_get (fset_options, i);
if (ptr_fset_option)
ptr_fset_option->index = i;
}
/* check selected line */
if (num_options == 0)
fset_buffer_selected_line = 0;
else if (fset_buffer_selected_line >= num_options)
fset_buffer_selected_line = num_options - 1;
/* restore marked options */
if (marked_options)
{
for (i = 0; i < num_options; i++)
{
ptr_fset_option = weechat_arraylist_get (fset_options, i);
if (ptr_fset_option
&& weechat_hashtable_has_key (marked_options,
ptr_fset_option->name))
{
ptr_fset_option->marked = 1;
fset_option_count_marked++;
}
}
weechat_hashtable_free (marked_options);
}
}
/*
* Sets the filter.
*/
void
fset_option_set_filter (const char *filter)
{
if (fset_option_filter)
free (fset_option_filter);
fset_option_filter = (filter && (strcmp (filter, "*") != 0)) ?
strdup (filter) : NULL;
}
/*
* Filters options.
*/
void
fset_option_filter_options (const char *filter)
{
fset_buffer_selected_line = 0;
fset_option_set_filter (filter);
fset_buffer_set_localvar_filter ();
fset_option_get_options ();
fset_buffer_refresh (1);
}
/*
* Toggles a boolean option.
*/
void
fset_option_toggle_value (struct t_fset_option *fset_option,
struct t_config_option *option)
{
if (!fset_option || !option
|| (fset_option->type != FSET_OPTION_TYPE_BOOLEAN))
return;
weechat_config_option_set (option, "toggle", 1);
}
/*
* Adds a value to an integer/color option.
*/
void
fset_option_add_value (struct t_fset_option *fset_option,
struct t_config_option *option,
int value)
{
char str_value[128];
if (!fset_option || !option
|| ((fset_option->type != FSET_OPTION_TYPE_INTEGER)
&& (fset_option->type != FSET_OPTION_TYPE_COLOR)))
return;
snprintf (str_value, sizeof (str_value),
"%s%d",
(value > 0) ? "++" : "--",
(value > 0) ? value : value * -1);
weechat_config_option_set (option, str_value, 1);
}
/*
* Resets the value of an option.
*/
void
fset_option_reset_value (struct t_fset_option *fset_option,
struct t_config_option *option)
{
/* make C compiler happy */
(void) fset_option;
if (!option)
return;
weechat_config_option_reset (option, 1);
}
/*
* Unsets the value of an option.
*/
void
fset_option_unset_value (struct t_fset_option *fset_option,
struct t_config_option *option)
{
/* make C compiler happy */
(void) fset_option;
if (!option)
return;
weechat_config_option_unset (option);
}
/*
* Sets the value of an option.
*
* If set_mode == -1, edit an empty value.
* If set_mode == 0, edit the current value.
* If set_mode == 1, append to the current value (move the cursor at the end of
* value)
*/
void
fset_option_set (struct t_fset_option *fset_option,
struct t_config_option *option,
struct t_gui_buffer *buffer,
int set_mode)
{
int use_mute, add_quotes, length_input, input_pos;
char *ptr_value, *str_input, str_pos[32];
char empty_value[1] = { '\0' };
/* make C compiler happy */
(void) option;
if (!fset_option)
return;
if (set_mode == -1)
ptr_value = empty_value;
else
ptr_value = (fset_option->value) ? fset_option->value : empty_value;
length_input = 64 + strlen (fset_option->name) + strlen (ptr_value) + 1;
str_input = malloc (length_input);
if (!str_input)
return;
use_mute = weechat_config_boolean (fset_config_look_use_mute);
add_quotes = (fset_option->type == FSET_OPTION_TYPE_STRING) ? 1 : 0;
snprintf (str_input, length_input,
"%s/set %s %s%s%s",
(use_mute) ? "/mute " : "",
fset_option->name,
(add_quotes) ? "\"" : "",
ptr_value,
(add_quotes) ? "\"" : "");
weechat_buffer_set (buffer, "input", str_input);
input_pos = ((use_mute) ? 6 : 0) + /* "/mute " */
5 + /* "/set " */
weechat_utf8_strlen (fset_option->name) + 1 +
((add_quotes) ? 1 : 0) +
((set_mode == 1) ? ((fset_option->value) ?
weechat_utf8_strlen (fset_option->value) : 0) : 0);
snprintf (str_pos, sizeof (str_pos), "%d", input_pos);
weechat_buffer_set (buffer, "input_pos", str_pos);
free (str_input);
}
/*
* Marks/unmarks an option.
*/
void
fset_option_toggle_mark (struct t_fset_option *fset_option,
struct t_config_option *option)
{
/* make C compiler happy */
(void) option;
if (!fset_option)
return;
fset_option->marked ^= 1;
fset_option_count_marked += (fset_option->marked) ? 1 : -1;
fset_buffer_display_option (fset_option);
}
/*
* Mark/unmark options matching a filter.
*/
void
fset_option_mark_options_matching_filter (const char *filter, int mark)
{
int num_options, i, mark_old, matching, set_title;
struct t_fset_option *ptr_fset_option;
set_title = 0;
num_options = weechat_arraylist_size (fset_options);
for (i = 0; i < num_options; i++)
{
ptr_fset_option = weechat_arraylist_get (fset_options, i);
if (ptr_fset_option)
{
mark_old = ptr_fset_option->marked;
matching = fset_option_match_filter (ptr_fset_option, filter);
if (matching)
{
if (!mark_old && mark)
{
ptr_fset_option->marked = 1;
fset_option_count_marked++;
fset_buffer_display_option (ptr_fset_option);
set_title = 1;
}
else if (mark_old && !mark)
{
ptr_fset_option->marked = 0;
fset_option_count_marked--;
fset_buffer_display_option (ptr_fset_option);
set_title = 1;
}
}
}
}
if (set_title)
fset_buffer_set_title ();
}
/*
* Unmarks all options.
*/
void
fset_option_unmark_all ()
{
int num_options, marked, set_title, i;
struct t_fset_option *ptr_fset_option;
set_title = 0;
num_options = weechat_arraylist_size (fset_options);
for (i = 0; i < num_options; i++)
{
ptr_fset_option = weechat_arraylist_get (fset_options, i);
if (ptr_fset_option)
{
marked = ptr_fset_option->marked;
ptr_fset_option->marked = 0;
if (marked)
{
fset_buffer_display_option (ptr_fset_option);
set_title = 1;
}
}
}
fset_option_count_marked = 0;
if (set_title)
fset_buffer_set_title ();
}
/*
* Exports options currently displayed in fset buffer.
*
* If with_help == 1, the help is displayed above each option
* and options are separated by an empty line.
*
* Returns:
* 1: export OK
* 0: error
*/
int
fset_option_export (const char *filename, int with_help)
{
int num_options, i;
char *line;
FILE *file;
struct t_fset_option *ptr_fset_option;
struct t_hashtable *hashtable_pointers, *hashtable_extra_vars;
file = fopen (filename, "w");
if (!file)
return 0;
chmod (filename, 0600);
hashtable_pointers = weechat_hashtable_new (
8,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_POINTER,
NULL, NULL);
hashtable_extra_vars = weechat_hashtable_new (
128,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL, NULL);
num_options = weechat_arraylist_size (fset_options);
for (i = 0; i < num_options; i++)
{
ptr_fset_option = weechat_arraylist_get (fset_options, i);
if (ptr_fset_option)
{
weechat_hashtable_set (hashtable_pointers,
"fset_option", ptr_fset_option);
fset_option_add_option_in_hashtable (hashtable_extra_vars,
ptr_fset_option);
if (with_help)
{
if (i > 0)
fprintf (file, "\n");
line = weechat_string_eval_expression (
weechat_config_string (fset_config_format_export_help),
hashtable_pointers,
hashtable_extra_vars,
NULL);
if (line && line[0])
fprintf (file, "%s\n", line);
if (line)
free (line);
}
line = weechat_string_eval_expression (
(ptr_fset_option->value) ?
weechat_config_string (fset_config_format_export_option) :
weechat_config_string (fset_config_format_export_option_null),
hashtable_pointers,
hashtable_extra_vars,
NULL);
if (line && line[0])
fprintf (file, "%s\n", line);
if (line)
free (line);
}
}
fclose (file);
if (hashtable_pointers)
weechat_hashtable_free (hashtable_pointers);
if (hashtable_extra_vars)
weechat_hashtable_free (hashtable_extra_vars);
return 1;
}
/*
* Refreshes the fset buffer after the change of an option.
*/
void
fset_option_config_changed (const char *option_name)
{
struct t_fset_option *ptr_fset_option, *new_fset_option;
struct t_config_option *ptr_option;
int full_refresh, line, num_options;
if (!fset_buffer)
return;
full_refresh = 0;
ptr_fset_option = (option_name) ?
fset_option_search_by_name (option_name, &line) : NULL;
ptr_option = (option_name) ? weechat_config_get (option_name) : NULL;
if (ptr_fset_option)
{
if (ptr_option)
{
fset_option_set_values (ptr_fset_option, ptr_option);
fset_buffer_display_option (ptr_fset_option);
}
else
{
/* option removed: get options and refresh the whole buffer */
full_refresh = 1;
}
}
else if (ptr_option)
{
new_fset_option = fset_option_alloc (ptr_option);
if (fset_option_match_filter (new_fset_option, fset_option_filter))
{
/* option added: get options and refresh the whole buffer */
full_refresh = 1;
}
fset_option_free (new_fset_option);
}
if (full_refresh)
{
fset_option_get_options ();
fset_buffer_refresh (1);
}
else
{
num_options = weechat_arraylist_size (fset_options);
for (line = 0; line < num_options; line++)
{
ptr_fset_option = weechat_arraylist_get (fset_options, line);
if (ptr_fset_option
&& ptr_fset_option->parent_name
&& option_name
&& (strcmp (ptr_fset_option->parent_name, option_name) == 0))
{
ptr_option = weechat_config_get (ptr_fset_option->name);
if (ptr_option)
fset_option_set_values (ptr_fset_option, ptr_option);
}
}
fset_option_set_max_length_fields_all ();
fset_buffer_refresh (0);
}
}
/*
* Callback called by the timer for each option changed.
*/
void
fset_option_timer_option_changed_cb (void *data,
struct t_hashtable *hashtable,
const void *key,
const void *value)
{
/* make C compiler happy */
(void) data;
(void) hashtable;
(void) value;
fset_option_config_changed (key);
}
/*
* Callback for timer after an option is changed.
*/
int
fset_option_config_timer_cb (const void *pointer,
void *data,
int remaining_calls)
{
/* make C compiler happy */
(void) pointer;
(void) data;
(void) remaining_calls;
if (weechat_hashtable_get_integer (
fset_option_timer_options_changed,
"items_count") >= FSET_OPTION_TIMER_MAX_OPTIONS_CHANGED)
{
fset_option_get_options ();
fset_buffer_refresh (1);
}
else
{
weechat_hashtable_map (fset_option_timer_options_changed,
&fset_option_timer_option_changed_cb,
NULL);
}
weechat_hashtable_remove_all (fset_option_timer_options_changed);
fset_option_timer_hook = NULL;
return WEECHAT_RC_OK;
}
/*
* Callback for config option changed.
*/
int
fset_option_config_cb (const void *pointer,
void *data,
const char *option,
const char *value)
{
char *info;
/* make C compiler happy */
(void) pointer;
(void) data;
(void) value;
/* do nothing if fset buffer is not opened */
if (!fset_buffer)
return WEECHAT_RC_OK;
/* do nothing if auto-refresh is disabled for this option */
if (!weechat_string_match_list (option,
(const char **)fset_config_auto_refresh,
0))
return WEECHAT_RC_OK;
/* do nothing if WeeChat is upgrading */
info = weechat_info_get ("weechat_upgrading", NULL);
if (info && (strcmp (info, "1") == 0))
{
free (info);
return WEECHAT_RC_OK;
}
if (info)
free (info);
/*
* we limit the number of options to display with the timer; for example
* on /reload, many options are changed, so we'll get all options and
* display them, instead of change them one by one, which is very slow
*/
if (weechat_hashtable_get_integer (
fset_option_timer_options_changed,
"items_count") < FSET_OPTION_TIMER_MAX_OPTIONS_CHANGED)
{
weechat_hashtable_set (fset_option_timer_options_changed,
option, NULL);
}
if (!fset_option_timer_hook)
{
fset_option_timer_hook = weechat_hook_timer (
1, 0, 1,
&fset_option_config_timer_cb, NULL, NULL);
}
return WEECHAT_RC_OK;
}
/*
* Returns hdata for option.
*/
struct t_hdata *
fset_option_hdata_option_cb (const void *pointer, void *data,
const char *hdata_name)
{
struct t_hdata *hdata;
/* make C compiler happy */
(void) pointer;
(void) data;
hdata = weechat_hdata_new (hdata_name, NULL, NULL, 0, 0, NULL, NULL);
if (hdata)
{
WEECHAT_HDATA_VAR(struct t_fset_option, index, INTEGER, 0, NULL, NULL);
WEECHAT_HDATA_VAR(struct t_fset_option, file, STRING, 0, NULL, NULL);
WEECHAT_HDATA_VAR(struct t_fset_option, section, STRING, 0, NULL, NULL);
WEECHAT_HDATA_VAR(struct t_fset_option, option, STRING, 0, NULL, NULL);
WEECHAT_HDATA_VAR(struct t_fset_option, name, STRING, 0, NULL, NULL);
WEECHAT_HDATA_VAR(struct t_fset_option, parent_name, STRING, 0, NULL, NULL);
WEECHAT_HDATA_VAR(struct t_fset_option, type, INTEGER, 0, NULL, NULL);
WEECHAT_HDATA_VAR(struct t_fset_option, default_value, STRING, 0, NULL, NULL);
WEECHAT_HDATA_VAR(struct t_fset_option, value, STRING, 0, NULL, NULL);
WEECHAT_HDATA_VAR(struct t_fset_option, parent_value, STRING, 0, NULL, NULL);
WEECHAT_HDATA_VAR(struct t_fset_option, min, STRING, 0, NULL, NULL);
WEECHAT_HDATA_VAR(struct t_fset_option, max, STRING, 0, NULL, NULL);
WEECHAT_HDATA_VAR(struct t_fset_option, description, STRING, 0, NULL, NULL);
WEECHAT_HDATA_VAR(struct t_fset_option, string_values, STRING, 0, NULL, NULL);
WEECHAT_HDATA_VAR(struct t_fset_option, marked, INTEGER, 0, NULL, NULL);
}
return hdata;
}
/*
* Adds a fset option in an infolist.
*
* Returns:
* 1: OK
* 0: error
*/
int
fset_option_add_to_infolist (struct t_infolist *infolist,
struct t_fset_option *fset_option)
{
struct t_infolist_item *ptr_item;
if (!infolist || !fset_option)
return 0;
ptr_item = weechat_infolist_new_item (infolist);
if (!ptr_item)
return 0;
if (!weechat_infolist_new_var_integer (ptr_item, "index", fset_option->index))
return 0;
if (!weechat_infolist_new_var_string (ptr_item, "file", fset_option->file))
return 0;
if (!weechat_infolist_new_var_string (ptr_item, "section", fset_option->section))
return 0;
if (!weechat_infolist_new_var_string (ptr_item, "option", fset_option->option))
return 0;
if (!weechat_infolist_new_var_string (ptr_item, "name", fset_option->name))
return 0;
if (!weechat_infolist_new_var_string (ptr_item, "parent_name", fset_option->parent_name))
return 0;
if (!weechat_infolist_new_var_string (ptr_item, "type", _(fset_option_type_string[fset_option->type])))
return 0;
if (!weechat_infolist_new_var_string (ptr_item, "type_en", fset_option_type_string[fset_option->type]))
return 0;
if (!weechat_infolist_new_var_string (ptr_item, "default_value", fset_option->default_value))
return 0;
if (!weechat_infolist_new_var_string (ptr_item, "value", fset_option->value))
return 0;
if (!weechat_infolist_new_var_string (ptr_item, "parent_value", fset_option->parent_value))
return 0;
if (!weechat_infolist_new_var_string (ptr_item, "min", fset_option->min))
return 0;
if (!weechat_infolist_new_var_string (ptr_item, "max", fset_option->max))
return 0;
if (!weechat_infolist_new_var_string (ptr_item, "description",
(fset_option->description && fset_option->description[0]) ?
_(fset_option->description) : ""))
return 0;
if (!weechat_infolist_new_var_string (ptr_item, "description_en", fset_option->description))
return 0;
if (!weechat_infolist_new_var_string (ptr_item, "string_values", fset_option->description))
return 0;
if (!weechat_infolist_new_var_integer (ptr_item, "marked", fset_option->marked))
return 0;
return 1;
}
/*
* Prints fset options in WeeChat log file (usually for crash dump).
*/
void
fset_option_print_log ()
{
struct t_fset_option *ptr_fset_option;
int num_options, i;
num_options = weechat_arraylist_size (fset_options);
for (i = 0; i < num_options; i++)
{
ptr_fset_option = weechat_arraylist_get (fset_options, i);
if (!ptr_fset_option)
continue;
weechat_log_printf ("");
weechat_log_printf ("[fset option (addr:0x%lx)]", ptr_fset_option);
weechat_log_printf (" index . . . . . . . . : %d", ptr_fset_option->index);
weechat_log_printf (" file. . . . . . . . . : '%s'", ptr_fset_option->file);
weechat_log_printf (" section . . . . . . . : '%s'", ptr_fset_option->section);
weechat_log_printf (" option. . . . . . . . : '%s'", ptr_fset_option->option);
weechat_log_printf (" name. . . . . . . . . : '%s'", ptr_fset_option->name);
weechat_log_printf (" parent_name . . . . . : '%s'", ptr_fset_option->parent_name);
weechat_log_printf (" type. . . . . . . . . : %d ('%s')",
ptr_fset_option->type,
fset_option_type_string[ptr_fset_option->type]);
weechat_log_printf (" default_value . . . . : '%s'", ptr_fset_option->default_value);
weechat_log_printf (" value . . . . . . . . : '%s'", ptr_fset_option->value);
weechat_log_printf (" parent_value. . . . . : '%s'", ptr_fset_option->parent_value);
weechat_log_printf (" min . . . . . . . . . : '%s'", ptr_fset_option->min);
weechat_log_printf (" max . . . . . . . . . : '%s'", ptr_fset_option->max);
weechat_log_printf (" description . . . . . : '%s'", ptr_fset_option->description);
weechat_log_printf (" string_values . . . . : '%s'", ptr_fset_option->string_values);
weechat_log_printf (" marked. . . . . . . . : %d", ptr_fset_option->marked);
}
}
/*
* Initializes fset list of options.
*
* Returns:
* 1: OK
* 0: error
*/
int
fset_option_init ()
{
fset_options = fset_option_get_arraylist_options ();
if (!fset_options)
return 0;
fset_option_count_marked = 0;
fset_option_max_length = fset_option_get_max_length ();
if (!fset_option_max_length)
{
weechat_arraylist_free (fset_options);
return 0;
}
fset_option_filter_hashtable_pointers = weechat_hashtable_new (
8,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_POINTER,
NULL, NULL);
if (!fset_option_filter_hashtable_pointers)
{
weechat_arraylist_free (fset_options);
free (fset_option_max_length);
return 0;
}
fset_option_filter_hashtable_extra_vars = weechat_hashtable_new (
128,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL, NULL);
if (!fset_option_filter_hashtable_extra_vars)
{
weechat_arraylist_free (fset_options);
free (fset_option_max_length);
weechat_hashtable_free (fset_option_filter_hashtable_pointers);
return 0;
}
fset_option_filter_hashtable_options = weechat_hashtable_new (
8,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL, NULL);
if (!fset_option_filter_hashtable_options)
{
weechat_arraylist_free (fset_options);
free (fset_option_max_length);
weechat_hashtable_free (fset_option_filter_hashtable_pointers);
weechat_hashtable_free (fset_option_filter_hashtable_extra_vars);
return 0;
}
weechat_hashtable_set (fset_option_filter_hashtable_options,
"type", "condition");
fset_option_timer_options_changed = weechat_hashtable_new (
128,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_POINTER,
NULL, NULL);
if (!fset_option_timer_options_changed)
{
weechat_arraylist_free (fset_options);
free (fset_option_max_length);
weechat_hashtable_free (fset_option_filter_hashtable_pointers);
weechat_hashtable_free (fset_option_filter_hashtable_extra_vars);
weechat_hashtable_free (fset_option_filter_hashtable_options);
return 0;
}
return 1;
}
/*
* Ends fset list of options.
*/
void
fset_option_end ()
{
if (fset_options)
{
weechat_arraylist_free (fset_options);
fset_options = NULL;
}
fset_option_count_marked = 0;
if (fset_option_max_length)
{
free (fset_option_max_length);
fset_option_max_length = NULL;
}
if (fset_option_filter)
{
free (fset_option_filter);
fset_option_filter = NULL;
}
if (fset_option_filter_hashtable_pointers)
{
weechat_hashtable_free (fset_option_filter_hashtable_pointers);
fset_option_filter_hashtable_pointers = NULL;
}
if (fset_option_filter_hashtable_extra_vars)
{
weechat_hashtable_free (fset_option_filter_hashtable_extra_vars);
fset_option_filter_hashtable_extra_vars = NULL;
}
if (fset_option_filter_hashtable_options)
{
weechat_hashtable_free (fset_option_filter_hashtable_options);
fset_option_filter_hashtable_options = NULL;
}
if (fset_option_timer_options_changed)
{
weechat_hashtable_free (fset_option_timer_options_changed);
fset_option_timer_options_changed = NULL;
}
}