diff options
-rw-r--r-- | src/core/wee-config-file.c | 539 | ||||
-rw-r--r-- | src/core/wee-config-file.h | 43 | ||||
-rw-r--r-- | src/core/wee-config-option.c | 568 | ||||
-rw-r--r-- | src/core/wee-config-option.h | 68 |
4 files changed, 1218 insertions, 0 deletions
diff --git a/src/core/wee-config-file.c b/src/core/wee-config-file.c new file mode 100644 index 000000000..5cabd5a07 --- /dev/null +++ b/src/core/wee-config-file.c @@ -0,0 +1,539 @@ +/* + * Copyright (c) 2003-2007 by FlashCode <flashcode@flashtux.org> + * See README for License detail, AUTHORS for developers list. + * + * This program 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. + * + * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* wee-config-file.c: I/O functions to read/write options in a config file */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <limits.h> +#include <time.h> +#include <pwd.h> +#include <sys/types.h> +#include <sys/stat.h> + +#include "weechat.h" +#include "wee-config-file.h" +#include "wee-config-option.h" +#include "wee-log.h" +#include "wee-string.h" +#include "wee-utf8.h" +#include "../gui/gui-chat.h" +#include "../gui/gui-color.h" + + +/* + * config_file_read_option: read an option for a section in config file + * This function is called when a new section begins + * or for an option of a section + * if options == NULL, then option is out of section + * if option_name == NULL, it's beginning of section + * otherwise it's an option for a section + * Return: 0 = successful + * -1 = option not found + * -2 = bad format/value + */ + +int +config_file_read_option (struct t_config_option *options, + char *option_name, char *value) +{ + struct t_config_option *ptr_option; + + if (option_name) + { + /* no option allowed outside a section by default */ + if (!options) + return -1; + + /* search option in list of options for section */ + ptr_option = config_option_search (options, option_name); + if (!ptr_option) + return -1; + + /* set value for option found */ + if (config_option_set (ptr_option, value) < 0) + return -2; + } + else + { + /* by default, does nothing for a new section */ + } + + /* all ok */ + return 0; +} + +/* + * config_file_read: read a configuration file + * return: 0 = successful + * -1 = config file file not found + * -2 = error in config file + */ + +int +config_file_read (char **config_sections, struct t_config_option **options, + t_config_func_read_option **read_functions, + t_config_func_read_option *read_function_default, + t_config_func_write_options **write_default_functions, + char *config_filename) +{ + int filename_length; + char *filename; + FILE *file; + int section, line_number, rc; + char line[1024], *ptr_line, *ptr_line2, *pos, *pos2; + + filename_length = strlen (weechat_home) + strlen (config_filename) + 2; + filename = (char *) malloc (filename_length * sizeof (char)); + if (!filename) + return -2; + snprintf (filename, filename_length, "%s%s%s", + weechat_home, DIR_SEPARATOR, config_filename); + if ((file = fopen (filename, "r")) == NULL) + { + /* if no default write functions provided and that config file + is not here, then return without doing anything */ + if (!write_default_functions) + return 0; + + /* create default config, then go on with reading */ + config_file_write_default (config_sections, options, + write_default_functions, + config_filename); + if ((file = fopen (filename, "r")) == NULL) + { + gui_chat_printf (NULL, _("%s config file \"%s\" not found.\n"), + WEECHAT_WARNING, filename); + free (filename); + return -1; + } + } + + config_option_section_option_set_default_values (config_sections, options); + + section = -1; + line_number = 0; + while (!feof (file)) + { + ptr_line = fgets (line, sizeof (line) - 1, file); + line_number++; + if (ptr_line) + { + /* encode line to internal charset */ + ptr_line2 = string_iconv_to_internal (NULL, ptr_line); + if (ptr_line2) + { + snprintf (line, sizeof (line) - 1, "%s", ptr_line2); + free (ptr_line2); + } + + /* skip spaces */ + while (ptr_line[0] == ' ') + ptr_line++; + /* not a comment and not an empty line */ + if ((ptr_line[0] != '#') && (ptr_line[0] != '\r') + && (ptr_line[0] != '\n')) + { + /* beginning of section */ + if (ptr_line[0] == '[') + { + pos = strchr (line, ']'); + if (pos == NULL) + gui_chat_printf (NULL, + _("%s %s, line %d: invalid syntax, " + "missing \"]\"\n"), + WEECHAT_WARNING, filename, + line_number); + else + { + pos[0] = '\0'; + pos = ptr_line + 1; + section = config_option_section_get_index (config_sections, pos); + if (section < 0) + gui_chat_printf (NULL, + _("%s %s, line %d: unknown section " + "identifier (\"%s\")\n"), + WEECHAT_WARNING, filename, + line_number, pos); + else + { + rc = ((int) (read_functions[section]) (options[section], + NULL, NULL)); + if (rc < 0) + gui_chat_printf (NULL, + _("%s %s, line %d: error " + "reading new section \"%s\"\n"), + WEECHAT_WARNING, filename, + line_number, pos); + } + } + } + else + { + pos = strchr (line, '='); + if (pos == NULL) + gui_chat_printf (NULL, + _("%s %s, line %d: invalid syntax, " + "missing \"=\"\n"), + WEECHAT_WARNING, filename, + line_number); + else + { + pos[0] = '\0'; + pos++; + + /* remove spaces before '=' */ + pos2 = pos - 2; + while ((pos2 > line) && (pos2[0] == ' ')) + { + pos2[0] = '\0'; + pos2--; + } + + /* skip spaces after '=' */ + while (pos[0] && (pos[0] == ' ')) + { + pos++; + } + + /* remove CR/LF */ + pos2 = strchr (pos, '\r'); + if (pos2 != NULL) + pos2[0] = '\0'; + pos2 = strchr (pos, '\n'); + if (pos2 != NULL) + pos2[0] = '\0'; + + /* remove simple or double quotes + and spaces at the end */ + if (strlen(pos) > 1) + { + pos2 = pos + strlen (pos) - 1; + while ((pos2 > pos) && (pos2[0] == ' ')) + { + pos2[0] = '\0'; + pos2--; + } + pos2 = pos + strlen (pos) - 1; + if (((pos[0] == '\'') && + (pos2[0] == '\'')) || + ((pos[0] == '"') && + (pos2[0] == '"'))) + { + pos2[0] = '\0'; + pos++; + } + } + + if (section < 0) + rc = ((int) (read_function_default) (NULL, line, pos)); + else + rc = ((int) (read_functions[section]) (options[section], + line, pos)); + if (rc < 0) + { + switch (rc) + { + case -1: + if (section < 0) + gui_chat_printf (NULL, + _("%s %s, line %d: unknown " + "option \"%s\" " + "(outside a section)\n"), + WEECHAT_WARNING, + filename, + line_number, line); + else + gui_chat_printf (NULL, + _("%s %s, line %d: option " + "\"%s\" unknown for " + "section \"%s\"\n"), + WEECHAT_WARNING, filename, + line_number, line, + config_sections[section]); + break; + case -2: + gui_chat_printf (NULL, + _("%s %s, line %d: invalid " + "value for option \"%s\"\n"), + WEECHAT_WARNING, filename, + line_number, line); + break; + } + } + } + } + } + } + } + + fclose (file); + free (filename); + + return 0; +} + +/* + * config_file_write_options: write a section with options in a config file + * This function is called when config is saved, + * for a section with standard options + * Return: 0 = successful + * -1 = write error + */ + +int +config_file_write_options (FILE *file, char *section_name, + struct t_config_option *options) +{ + int i; + + string_iconv_fprintf (file, "\n[%s]\n", section_name); + + for (i = 0; options[i].name; i++) + { + switch (options[i].type) + { + case OPTION_TYPE_BOOLEAN: + string_iconv_fprintf (file, "%s = %s\n", + options[i].name, + (options[i].ptr_int && + *options[i].ptr_int) ? + "on" : "off"); + break; + case OPTION_TYPE_INT: + string_iconv_fprintf (file, "%s = %d\n", + options[i].name, + (options[i].ptr_int) ? + *options[i].ptr_int : + options[i].default_int); + break; + case OPTION_TYPE_INT_WITH_STRING: + string_iconv_fprintf (file, "%s = %s\n", + options[i].name, + (options[i].ptr_int) ? + options[i].array_values[*options[i].ptr_int] : + options[i].array_values[options[i].default_int]); + break; + case OPTION_TYPE_COLOR: + string_iconv_fprintf (file, "%s = %s\n", + options[i].name, + (options[i].ptr_int) ? + gui_color_get_name (*options[i].ptr_int) : + options[i].default_string); + break; + case OPTION_TYPE_STRING: + string_iconv_fprintf (file, "%s = \"%s\"\n", + options[i].name, + (options[i].ptr_string) ? + *options[i].ptr_string : + options[i].default_string); + break; + } + } + + /* all ok */ + return 0; +} + +/* + * config_file_write_options_default_values: write a section with options in a config file + * This function is called when new config file + * is created, with default values, for a + * section with standard options + * Return: 0 = successful + * -1 = write error + */ + +int +config_file_write_options_default_values (FILE *file, char *section_name, + struct t_config_option *options) +{ + int i; + + string_iconv_fprintf (file, "\n[%s]\n", section_name); + + for (i = 0; options[i].name; i++) + { + switch (options[i].type) + { + case OPTION_TYPE_BOOLEAN: + string_iconv_fprintf (file, "%s = %s\n", + options[i].name, + (options[i].default_int) ? + "on" : "off"); + break; + case OPTION_TYPE_INT: + string_iconv_fprintf (file, "%s = %d\n", + options[i].name, + options[i].default_int); + break; + case OPTION_TYPE_INT_WITH_STRING: + case OPTION_TYPE_COLOR: + string_iconv_fprintf (file, "%s = %s\n", + options[i].name, + options[i].default_string); + break; + case OPTION_TYPE_STRING: + string_iconv_fprintf (file, "%s = \"%s\"\n", + options[i].name, + options[i].default_string); + break; + } + } + + /* all ok */ + return 0; +} + +/* + * config_file_write_header: write header in a config file + */ + +void +config_file_write_header (FILE *file) +{ + time_t current_time; + + current_time = time (NULL); + string_iconv_fprintf (file, _("#\n# %s configuration file, created by " + "%s v%s on %s"), + PACKAGE_NAME, PACKAGE_NAME, PACKAGE_VERSION, + ctime (¤t_time)); + string_iconv_fprintf (file, _("# WARNING! Be careful when editing this file, " + "WeeChat may write it at any time.\n#\n")); +} + +/* + * config_file_write_default: create a default configuration file + * return: 0 if ok + * < 0 if error + */ + +int +config_file_write_default (char **config_sections, struct t_config_option **options, + t_config_func_write_options **write_functions, + char *config_filename) +{ + int filename_length, i, rc; + char *filename; + FILE *file; + + filename_length = strlen (weechat_home) + + strlen (config_filename) + 2; + filename = + (char *) malloc (filename_length * sizeof (char)); + if (!filename) + return -2; + snprintf (filename, filename_length, "%s%s%s", + weechat_home, DIR_SEPARATOR, config_filename); + if ((file = fopen (filename, "w")) == NULL) + { + gui_chat_printf (NULL, _("%s cannot create file \"%s\"\n"), + WEECHAT_ERROR, filename); + free (filename); + return -1; + } + + string_iconv_fprintf (stdout, + _("%s: creating default config file \"%s\"...\n"), + PACKAGE_NAME, + config_filename); + weechat_log_printf (_("Creating default config file \"%s\"\n"), + config_filename); + + config_file_write_header (file); + + for (i = 0; config_sections[i]; i++) + { + rc = ((int) (write_functions[i]) (file, config_sections[i], + options[i])); + } + + fclose (file); + chmod (filename, 0600); + free (filename); + return 0; +} + +/* + * config_file_write: write a configurtion file + * return: 0 if ok + * < 0 if error + */ + +int +config_file_write (char **config_sections, struct t_config_option **options, + t_config_func_write_options **write_functions, + char *config_filename) +{ + int filename_length, i, rc; + char *filename, *filename2; + FILE *file; + + filename_length = strlen (weechat_home) + + strlen (config_filename) + 2; + filename = + (char *) malloc (filename_length * sizeof (char)); + if (!filename) + return -2; + snprintf (filename, filename_length, "%s%s%s", + weechat_home, DIR_SEPARATOR, config_filename); + + filename2 = (char *) malloc ((filename_length + 32) * sizeof (char)); + if (!filename2) + { + free (filename); + return -2; + } + snprintf (filename2, filename_length + 32, "%s.weechattmp", filename); + + if ((file = fopen (filename2, "w")) == NULL) + { + gui_chat_printf (NULL, _("%s cannot create file \"%s\"\n"), + WEECHAT_ERROR, filename2); + free (filename); + free (filename2); + return -1; + } + + config_file_write_header (file); + + for (i = 0; config_sections[i]; i++) + { + rc = ((int) (write_functions[i]) (file, config_sections[i], + options[i])); + } + + fclose (file); + chmod (filename2, 0600); + unlink (filename); + rc = rename (filename2, filename); + free (filename); + free (filename2); + if (rc != 0) + return -1; + return 0; +} diff --git a/src/core/wee-config-file.h b/src/core/wee-config-file.h new file mode 100644 index 000000000..cde80def3 --- /dev/null +++ b/src/core/wee-config-file.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2003-2007 by FlashCode <flashcode@flashtux.org> + * See README for License detail, AUTHORS for developers list. + * + * This program 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. + * + * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef __WEECHAT_CONFIG_FILE_H +#define __WEECHAT_CONFIG_FILE_H 1 + +#include "wee-config-option.h" + +typedef int (t_config_func_read_option) (struct t_config_option *, char *, char *); +typedef int (t_config_func_write_options) (FILE *, char *, struct t_config_option *); + +extern int config_file_read_option (struct t_config_option *, char *, char *); +extern int config_file_read (char **, struct t_config_option **, + t_config_func_read_option **, + t_config_func_read_option *, + t_config_func_write_options **, + char *); + +extern int config_file_write_options (FILE *, char *, struct t_config_option *); +extern int config_file_write_options_default_values (FILE *, char *, + struct t_config_option *); +extern int config_file_write_default (char **, struct t_config_option **, + t_config_func_write_options **, char *); +extern int config_file_write (char **, struct t_config_option **, + t_config_func_write_options **, char *); + +#endif /* wee-config-file.h */ diff --git a/src/core/wee-config-option.c b/src/core/wee-config-option.c new file mode 100644 index 000000000..9d8decb43 --- /dev/null +++ b/src/core/wee-config-option.c @@ -0,0 +1,568 @@ +/* + * Copyright (c) 2003-2007 by FlashCode <flashcode@flashtux.org> + * See README for License detail, AUTHORS for developers list. + * + * This program 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. + * + * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* wee-config-option.c: manages WeeChat/protocols options */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <limits.h> +#include <time.h> +#include <pwd.h> +#include <sys/types.h> +#include <sys/stat.h> + +#include "weechat.h" +#include "wee-config-option.h" +#include "wee-hook.h" +#include "wee-string.h" +#include "wee-utf8.h" +#include "../gui/gui-chat.h" +#include "../gui/gui-color.h" + + +/* + * config_option_get_pos_array_values: return position of a string in an array of values + * return -1 if not found, otherwise position + */ + +int +config_option_get_pos_array_values (char **array, char *string) +{ + int i; + + i = 0; + while (array[i]) + { + if (string_strcasecmp (array[i], string) == 0) + return i; + i++; + } + + /* string not found in array */ + return -1; +} + +/* + * config_option_list_remove: remove an item from a list for an option + * (for options with value like: "abc:1,def:blabla") + */ + +void +config_option_list_remove (char **string, char *item) +{ + char *name, *pos, *pos2; + + if (!string || !(*string)) + return; + + name = (char *) malloc (strlen (item) + 2); + strcpy (name, item); + strcat (name, ":"); + pos = string_strcasestr (*string, name); + free (name); + if (pos) + { + pos2 = pos + strlen (item); + if (pos2[0] == ':') + { + pos2++; + if (pos2[0]) + { + while (pos2[0] && (pos2[0] != ',')) + pos2++; + if (pos2[0] == ',') + pos2++; + if (!pos2[0] && (pos != (*string))) + pos--; + strcpy (pos, pos2); + if (!(*string)[0]) + { + free (*string); + *string = NULL; + } + else + (*string) = (char *) realloc (*string, strlen (*string) + 1); + } + } + } +} + +/* + * config_option_list_set: set an item from a list for an option + * (for options with value like: "abc:1,def:blabla") + */ + +void +config_option_list_set (char **string, char *item, char *value) +{ + config_option_list_remove (string, item); + + if (!(*string)) + { + (*string) = (char *) malloc (strlen (item) + 1 + strlen (value) + 1); + (*string)[0] = '\0'; + } + else + (*string) = (char *) realloc (*string, + strlen (*string) + 1 + + strlen (item) + 1 + strlen (value) + 1); + + if ((*string)[0]) + strcat (*string, ","); + strcat (*string, item); + strcat (*string, ":"); + strcat (*string, value); +} + +/* + * config_option_list_get_value: return position of item value in the list + * (for options with value like: "abc:1,def:blabla") + */ + +void +config_option_list_get_value (char **string, char *item, + char **pos_found, int *length) +{ + char *name, *pos, *pos2, *pos_comma; + + *pos_found = NULL; + *length = 0; + + if (!string || !(*string)) + return; + + name = (char *) malloc (strlen (item) + 2); + strcpy (name, item); + strcat (name, ":"); + pos = string_strcasestr (*string, name); + free (name); + if (pos) + { + pos2 = pos + strlen (item); + if (pos2[0] == ':') + { + pos2++; + *pos_found = pos2; + pos_comma = strchr (pos2, ','); + if (pos_comma) + *length = pos_comma - pos2; + else + *length = strlen (pos2); + } + } +} + +/* + * config_option_option_get_boolean_value: get boolean value with user text + * return: BOOL_FALSE or BOOL_TRUE + */ + +int +config_option_option_get_boolean_value (char *text) +{ + if ((string_strcasecmp (text, "on") == 0) + || (string_strcasecmp (text, "yes") == 0) + || (string_strcasecmp (text, "y") == 0) + || (string_strcasecmp (text, "true") == 0) + || (string_strcasecmp (text, "t") == 0) + || (string_strcasecmp (text, "1") == 0)) + return BOOL_TRUE; + + if ((string_strcasecmp (text, "off") == 0) + || (string_strcasecmp (text, "no") == 0) + || (string_strcasecmp (text, "n") == 0) + || (string_strcasecmp (text, "false") == 0) + || (string_strcasecmp (text, "f") == 0) + || (string_strcasecmp (text, "0") == 0)) + return BOOL_FALSE; + + /* invalid text */ + return -1; +} + +/* + * config_option_set: set new value for an option + * return: 0 if success + * -1 if error (bad value) + */ + +int +config_option_set (struct t_config_option *option, char *value) +{ + int int_value; + + switch (option->type) + { + case OPTION_TYPE_BOOLEAN: + int_value = config_option_option_get_boolean_value (value); + switch (int_value) + { + case BOOL_TRUE: + *(option->ptr_int) = BOOL_TRUE; + break; + case BOOL_FALSE: + *(option->ptr_int) = BOOL_FALSE; + break; + default: + return -1; + } + break; + case OPTION_TYPE_INT: + int_value = atoi (value); + if ((int_value < option->min) || (int_value > option->max)) + return -1; + *(option->ptr_int) = int_value; + break; + case OPTION_TYPE_INT_WITH_STRING: + int_value = config_option_get_pos_array_values (option->array_values, + value); + if (int_value < 0) + return -1; + *(option->ptr_int) = int_value; + break; + case OPTION_TYPE_STRING: + if ((option->max > 0) && (utf8_strlen (value) > option->max)) + return -1; + if (*(option->ptr_string)) + free (*(option->ptr_string)); + *(option->ptr_string) = strdup (value); + break; + case OPTION_TYPE_COLOR: + if (!gui_color_assign (option->ptr_int, value)) + return -1; + break; + } + + hook_config_exec ("weechat", option->name, value); + + return 0; +} + +/* + * config_option_search: look for an option in a section and + * return pointer to this option + * If option is not found, NULL is returned + */ + +struct t_config_option * +config_option_search (struct t_config_option *config_options, char *option_name) +{ + int i; + + for (i = 0; config_options[i].name; i++) + { + /* if option found, return pointer */ + if (string_strcasecmp (config_options[i].name, option_name) == 0) + return &config_options[i]; + } + + /* option not found */ + return NULL; +} + +/* + * config_option_section_option_search: look for an option and return pointer to this option + * if option is not found, NULL is returned + */ + +struct t_config_option * +config_option_section_option_search (char **config_sections, + struct t_config_option **config_options, + char *option_name) +{ + int i; + struct t_config_option *ptr_option; + + for (i = 0; config_sections[i]; i++) + { + ptr_option = config_option_search (config_options[i], + option_name); + if (ptr_option) + return ptr_option; + } + + /* option not found */ + return NULL; +} + +/* + * config_option_section_option_search_get_value: look for type and value of an option + * if option is not found, NULL is returned + */ + +void +config_option_section_option_search_get_value (char **config_sections, + struct t_config_option **config_options, + char *option_name, + struct t_config_option **output_option, + void **output_option_value) +{ + struct t_config_option *ptr_option; + void *ptr_value; + + ptr_option = NULL; + ptr_value = NULL; + + ptr_option = config_option_section_option_search (config_sections, + config_options, + option_name); + if (ptr_option) + { + switch (ptr_option->type) + { + case OPTION_TYPE_BOOLEAN: + case OPTION_TYPE_INT: + case OPTION_TYPE_INT_WITH_STRING: + case OPTION_TYPE_COLOR: + ptr_value = (void *)(ptr_option->ptr_int); + break; + case OPTION_TYPE_STRING: + ptr_value = (void *)(ptr_option->ptr_string); + break; + } + if (ptr_option) + { + *output_option = ptr_option; + *output_option_value = ptr_value; + } + } +} + +/* + * config_option_section_option_set_value_by_name: set new value for an option (found by name) + * return: 0 if success + * -1 if bad value for option + * -2 if option is not found + */ + +int +config_option_section_option_set_value_by_name (char **config_sections, + struct t_config_option **config_options, + char *option_name, char *value) +{ + struct t_config_option *ptr_option; + + ptr_option = config_option_section_option_search (config_sections, + config_options, + option_name); + if (ptr_option) + return config_option_set (ptr_option, value); + else + return -2; +} + +/* + * config_option_section_get_index: get section index by name + * return -1 if section is not found + */ + +int +config_option_section_get_index (char **config_sections, char *section_name) +{ + int i; + + for (i = 0; config_sections[i]; i++) + { + if (string_strcasecmp (config_sections[i], section_name) == 0) + return i; + } + + /* option not found */ + return -1; +} + +/* + * config_option_section_get_name: get section name by option pointer + */ + +char * +config_option_section_get_name (char **config_sections, + struct t_config_option **config_options, + struct t_config_option *ptr_option) +{ + int i, j; + + for (i = 0; config_sections[i]; i++) + { + for (j = 0; config_options[i][j].name; j++) + { + /* if option found, return pointer to section name */ + if (ptr_option == &config_options[i][j]) + return config_sections[i]; + } + } + + /* option not found */ + return NULL; +} + +/* + * config_option_section_option_set_default_values: initialize config options + * with default values + */ + +void +config_option_section_option_set_default_values (char **config_sections, + struct t_config_option **config_options) +{ + int i, j, int_value; + + for (i = 0; config_sections[i]; i++) + { + if (config_options[i]) + { + for (j = 0; config_options[i][j].name; j++) + { + switch (config_options[i][j].type) + { + case OPTION_TYPE_BOOLEAN: + case OPTION_TYPE_INT: + *config_options[i][j].ptr_int = + config_options[i][j].default_int; + break; + case OPTION_TYPE_INT_WITH_STRING: + int_value = config_option_get_pos_array_values ( + config_options[i][j].array_values, + config_options[i][j].default_string); + if (int_value < 0) + gui_chat_printf (NULL, + _("%s unable to assign default int with " + "string (\"%s\")\n"), + WEECHAT_WARNING, + config_options[i][j].default_string); + else + *config_options[i][j].ptr_int = int_value; + break; + case OPTION_TYPE_STRING: + *config_options[i][j].ptr_string = + strdup (config_options[i][j].default_string); + break; + case OPTION_TYPE_COLOR: + if (!gui_color_assign (config_options[i][j].ptr_int, + config_options[i][j].default_string)) + gui_chat_printf (NULL, + _("%s unable to assign default color " + "(\"%s\")\n"), + WEECHAT_WARNING, + config_options[i][j].default_string); + break; + } + } + } + } +} + +/* + * config_option_print_stdout: print options on standard output + */ + +void +config_option_print_stdout (char **config_sections, + struct t_config_option **config_options) +{ + int i, j, k; + + for (i = 0; config_sections[i]; i++) + { + if (config_options[i]) + { + j = 0; + while (config_options[i][j].name) + { + string_iconv_fprintf (stdout, + "* %s:\n", + config_options[i][j].name); + switch (config_options[i][j].type) + { + case OPTION_TYPE_BOOLEAN: + string_iconv_fprintf (stdout, _(" . type: boolean\n")); + string_iconv_fprintf (stdout, _(" . values: 'on' or 'off'\n")); + string_iconv_fprintf (stdout, _(" . default value: '%s'\n"), + (config_options[i][j].default_int == BOOL_TRUE) ? + "on" : "off"); + break; + case OPTION_TYPE_INT: + string_iconv_fprintf (stdout, _(" . type: integer\n")); + string_iconv_fprintf (stdout, _(" . values: between %d and %d\n"), + config_options[i][j].min, + config_options[i][j].max); + string_iconv_fprintf (stdout, _(" . default value: %d\n"), + config_options[i][j].default_int); + break; + case OPTION_TYPE_INT_WITH_STRING: + string_iconv_fprintf (stdout, _(" . type: string\n")); + string_iconv_fprintf (stdout, _(" . values: ")); + k = 0; + while (config_options[i][j].array_values[k]) + { + string_iconv_fprintf (stdout, "'%s'", + config_options[i][j].array_values[k]); + if (config_options[i][j].array_values[k + 1]) + string_iconv_fprintf (stdout, ", "); + k++; + } + string_iconv_fprintf (stdout, "\n"); + string_iconv_fprintf (stdout, _(" . default value: '%s'\n"), + (config_options[i][j].default_string) ? + config_options[i][j].default_string : _("empty")); + break; + case OPTION_TYPE_STRING: + switch (config_options[i][j].max) + { + case 0: + string_iconv_fprintf (stdout, _(" . type: string\n")); + string_iconv_fprintf (stdout, _(" . values: any string\n")); + break; + case 1: + string_iconv_fprintf (stdout, _(" . type: char\n")); + string_iconv_fprintf (stdout, _(" . values: any char\n")); + break; + default: + string_iconv_fprintf (stdout, _(" . type: string\n")); + string_iconv_fprintf (stdout, _(" . values: any string (limit: %d chars)\n"), + config_options[i][j].max); + break; + } + string_iconv_fprintf (stdout, _(" . default value: '%s'\n"), + (config_options[i][j].default_string) ? + config_options[i][j].default_string : _("empty")); + break; + case OPTION_TYPE_COLOR: + string_iconv_fprintf (stdout, _(" . type: color\n")); + string_iconv_fprintf (stdout, _(" . values: color (depends on GUI used)\n")); + string_iconv_fprintf (stdout, _(" . default value: '%s'\n"), + (config_options[i][j].default_string) ? + config_options[i][j].default_string : _("empty")); + break; + } + string_iconv_fprintf (stdout, _(" . description: %s\n"), + _(config_options[i][j].description)); + string_iconv_fprintf (stdout, "\n"); + j++; + } + } + } +} diff --git a/src/core/wee-config-option.h b/src/core/wee-config-option.h new file mode 100644 index 000000000..652c7d916 --- /dev/null +++ b/src/core/wee-config-option.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2003-2007 by FlashCode <flashcode@flashtux.org> + * See README for License detail, AUTHORS for developers list. + * + * This program 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. + * + * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef __WEECHAT_CONFIG_OPTION_H +#define __WEECHAT_CONFIG_OPTION_H 1 + +#define OPTION_TYPE_BOOLEAN 1 /* values: on/off */ +#define OPTION_TYPE_INT 2 /* values: from min to max */ +#define OPTION_TYPE_INT_WITH_STRING 3 /* values: one from **array_values */ +#define OPTION_TYPE_STRING 4 /* values: any string, may be empty */ +#define OPTION_TYPE_COLOR 5 /* values: a color struct */ + + +#define BOOL_FALSE 0 +#define BOOL_TRUE 1 + +struct t_config_option +{ + char *name; + char *description; + int type; + int min, max; + int default_int; + char *default_string; + char **array_values; + int *ptr_int; + char **ptr_string; + void (*handler_change)(); +}; + +extern int config_option_get_pos_array_values (char **, char *); +extern void config_option_list_remove (char **, char *); +extern void config_option_list_set (char **, char *, char *); +extern void config_option_list_get_value (char **, char *, char **, int *); +extern int config_option_option_get_boolean_value (char *); +extern int config_option_set (struct t_config_option *, char *); +extern struct t_config_option *config_option_search (struct t_config_option *, char *); +extern struct t_config_option *config_option_section_option_search (char **, + struct t_config_option **, + char *); +extern void config_option_section_option_search_get_value (char **, struct t_config_option **, + char *, struct t_config_option **, + void **); +extern int config_option_section_option_set_value_by_name (char **, + struct t_config_option **, + char *, char *); +extern int config_option_section_get_index (char **, char *); +extern void config_option_section_option_set_default_values (char **, + struct t_config_option **); +extern void config_option_print_stdout (char **, struct t_config_option **); + +#endif /* wee-config-option.h */ |