Mercurial > audlegacy
diff libaudacious/configfile.c @ 0:cb178e5ad177 trunk
[svn] Import audacious source.
author | nenolod |
---|---|
date | Mon, 24 Oct 2005 03:06:47 -0700 |
parents | |
children | dc9aaf5eba90 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libaudacious/configfile.c Mon Oct 24 03:06:47 2005 -0700 @@ -0,0 +1,493 @@ +/* XMMS - Cross-platform multimedia player + * Copyright (C) 1998-2002 Peter Alm, Mikael Alm, Olle Hallnas, + * Thomas Nilsson and 4Front Technologies + * Copyright (C) 1999-2002 Haavard Kvaalen + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#if defined(HAVE_CONFIG_H) +#include "../config.h" +#endif + +#include "configfile.h" + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <locale.h> + +#include <unistd.h> +#include <sys/stat.h> + + +typedef gboolean(*XmmsCfgValueReadFunc) (ConfigFile * config_file, + const gchar * section, + const gchar * key, + gpointer * value); + +typedef void (*XmmsCfgValueWriteFunc) (ConfigFile * config_file, + const gchar * section, + const gchar * key, + gpointer * value); + +struct _XmmsCfgValueTypeInfo { + XmmsCfgValueReadFunc read; + XmmsCfgValueWriteFunc write; +}; + +typedef struct _XmmsCfgValueTypeInfo XmmsCfgValueTypeInfo; + + +static XmmsCfgValueTypeInfo xmms_cfg_value_type_func[] = { + {(XmmsCfgValueReadFunc) xmms_cfg_read_int, + (XmmsCfgValueWriteFunc) xmms_cfg_write_int}, + {(XmmsCfgValueReadFunc) xmms_cfg_read_float, + (XmmsCfgValueWriteFunc) xmms_cfg_write_float}, + {(XmmsCfgValueReadFunc) xmms_cfg_read_boolean, + (XmmsCfgValueWriteFunc) xmms_cfg_write_boolean}, + {(XmmsCfgValueReadFunc) xmms_cfg_read_string, + (XmmsCfgValueWriteFunc) xmms_cfg_write_string} +}; + + +static ConfigSection *xmms_cfg_create_section(ConfigFile * cfg, + const gchar * name); +static ConfigLine *xmms_cfg_create_string(ConfigSection * section, + const gchar * key, + const gchar * value); +static ConfigSection *xmms_cfg_find_section(ConfigFile * cfg, + const gchar * name); +static ConfigLine *xmms_cfg_find_string(ConfigSection * section, + const gchar * key); + + +ConfigFile *xmms_cfg_new(void) +{ + return g_new0(ConfigFile, 1); +} + +gboolean xmms_cfg_read_value(ConfigFile * config_file, + const gchar * section, const gchar * key, + XmmsCfgValueType value_type, gpointer * value) +{ + return xmms_cfg_value_type_func[value_type].read(config_file, + section, key, value); +} + +void xmms_cfg_write_value(ConfigFile * config_file, + const gchar * section, const gchar * key, + XmmsCfgValueType value_type, gpointer * value) +{ + xmms_cfg_value_type_func[value_type].read(config_file, + section, key, value); +} + +ConfigFile *xmms_cfg_open_file(const gchar * filename) +{ + ConfigFile *cfg; + + gchar *buffer, **lines, *tmp; + gint i; + ConfigSection *section = NULL; + + g_return_val_if_fail(filename != NULL, FALSE); + + if (!g_file_get_contents(filename, &buffer, NULL, NULL)) + return NULL; + + cfg = g_malloc0(sizeof(ConfigFile)); + lines = g_strsplit(buffer, "\n", 0); + g_free(buffer); + i = 0; + while (lines[i]) { + if (lines[i][0] == '[') { + if ((tmp = strchr(lines[i], ']'))) { + *tmp = '\0'; + section = xmms_cfg_create_section(cfg, &lines[i][1]); + } + } else if (lines[i][0] != '#' && section) { + if ((tmp = strchr(lines[i], '='))) { + *tmp = '\0'; + tmp++; + xmms_cfg_create_string(section, lines[i], tmp); + } + } + i++; + } + g_strfreev(lines); + return cfg; +} + +gchar *xmms_cfg_get_default_filename(void) +{ + static gchar *filename = NULL; + if (!filename) + filename = + g_strconcat(g_get_home_dir(), "/", BMP_RCPATH, "/config", + NULL); + return filename; +} + +ConfigFile *xmms_cfg_open_default_file(void) +{ + ConfigFile *ret; + + ret = xmms_cfg_open_file(xmms_cfg_get_default_filename()); + if (!ret) + ret = xmms_cfg_new(); + return ret; +} + +gboolean xmms_cfg_write_file(ConfigFile * cfg, const gchar * filename) +{ + FILE *file; + GList *section_list, *line_list; + ConfigSection *section; + ConfigLine *line; + + g_return_val_if_fail(cfg != NULL, FALSE); + g_return_val_if_fail(filename != NULL, FALSE); + + if (!(file = fopen(filename, "w"))) + return FALSE; + + section_list = cfg->sections; + while (section_list) { + section = (ConfigSection *) section_list->data; + if (section->lines) { + fprintf(file, "[%s]\n", section->name); + line_list = section->lines; + while (line_list) { + line = (ConfigLine *) line_list->data; + fprintf(file, "%s=%s\n", line->key, line->value); + line_list = g_list_next(line_list); + } + fprintf(file, "\n"); + } + section_list = g_list_next(section_list); + } + fclose(file); + return TRUE; +} + +gboolean xmms_cfg_write_default_file(ConfigFile * cfg) +{ + return xmms_cfg_write_file(cfg, xmms_cfg_get_default_filename()); +} + +gboolean xmms_cfg_read_string(ConfigFile * cfg, const gchar * section, + const gchar * key, gchar ** value) +{ + ConfigSection *sect; + ConfigLine *line; + + g_return_val_if_fail(cfg != NULL, FALSE); + g_return_val_if_fail(section != NULL, FALSE); + g_return_val_if_fail(key != NULL, FALSE); + g_return_val_if_fail(value != NULL, FALSE); + + if (!(sect = xmms_cfg_find_section(cfg, section))) + return FALSE; + if (!(line = xmms_cfg_find_string(sect, key))) + return FALSE; + *value = g_strdup(line->value); + return TRUE; +} + +gboolean xmms_cfg_read_int(ConfigFile * cfg, const gchar * section, + const gchar * key, gint * value) +{ + gchar *str; + + g_return_val_if_fail(cfg != NULL, FALSE); + g_return_val_if_fail(section != NULL, FALSE); + g_return_val_if_fail(key != NULL, FALSE); + g_return_val_if_fail(value != NULL, FALSE); + + if (!xmms_cfg_read_string(cfg, section, key, &str)) + return FALSE; + *value = atoi(str); + g_free(str); + + return TRUE; +} + +gboolean xmms_cfg_read_boolean(ConfigFile * cfg, + const gchar * section, const gchar * key, + gboolean * value) +{ + gchar *str; + + g_return_val_if_fail(cfg != NULL, FALSE); + g_return_val_if_fail(section != NULL, FALSE); + g_return_val_if_fail(key != NULL, FALSE); + g_return_val_if_fail(value != NULL, FALSE); + + if (!xmms_cfg_read_string(cfg, section, key, &str)) + return FALSE; + if (!strcasecmp(str, "TRUE")) + *value = TRUE; + else + *value = FALSE; + g_free(str); + return TRUE; +} + +gboolean xmms_cfg_read_float(ConfigFile * cfg, + const gchar * section, const gchar * key, + gfloat * value) +{ + gchar *str, *locale; + + g_return_val_if_fail(cfg != NULL, FALSE); + g_return_val_if_fail(section != NULL, FALSE); + g_return_val_if_fail(key != NULL, FALSE); + g_return_val_if_fail(value != NULL, FALSE); + + if (!xmms_cfg_read_string(cfg, section, key, &str)) + return FALSE; + + locale = g_strdup(setlocale(LC_NUMERIC, NULL)); + setlocale(LC_NUMERIC, "C"); + *value = strtod(str, NULL); + setlocale(LC_NUMERIC, locale); + g_free(locale); + g_free(str); + + return TRUE; +} + +gboolean xmms_cfg_read_double(ConfigFile * cfg, + const gchar * section, const gchar * key, + gdouble * value) +{ + gchar *str, *locale; + + g_return_val_if_fail(cfg != NULL, FALSE); + g_return_val_if_fail(section != NULL, FALSE); + g_return_val_if_fail(key != NULL, FALSE); + g_return_val_if_fail(value != NULL, FALSE); + + if (!xmms_cfg_read_string(cfg, section, key, &str)) + return FALSE; + + locale = g_strdup(setlocale(LC_NUMERIC, NULL)); + setlocale(LC_NUMERIC, "C"); + *value = strtod(str, NULL); + setlocale(LC_NUMERIC, locale); + g_free(locale); + g_free(str); + + return TRUE; +} + +void xmms_cfg_write_string(ConfigFile * cfg, + const gchar * section, const gchar * key, + gchar * value) +{ + ConfigSection *sect; + ConfigLine *line; + + g_return_if_fail(cfg != NULL); + g_return_if_fail(section != NULL); + g_return_if_fail(key != NULL); + g_return_if_fail(value != NULL); + + sect = xmms_cfg_find_section(cfg, section); + if (!sect) + sect = xmms_cfg_create_section(cfg, section); + if ((line = xmms_cfg_find_string(sect, key))) { + g_free(line->value); + line->value = g_strstrip(g_strdup(value)); + } else + xmms_cfg_create_string(sect, key, value); +} + +void xmms_cfg_write_int(ConfigFile * cfg, + const gchar * section, const gchar * key, + gint value) +{ + gchar *strvalue; + + g_return_if_fail(cfg != NULL); + g_return_if_fail(section != NULL); + g_return_if_fail(key != NULL); + + strvalue = g_strdup_printf("%d", value); + xmms_cfg_write_string(cfg, section, key, strvalue); + g_free(strvalue); +} + +void xmms_cfg_write_boolean(ConfigFile * cfg, + const gchar * section, const gchar * key, + gboolean value) +{ + g_return_if_fail(cfg != NULL); + g_return_if_fail(section != NULL); + g_return_if_fail(key != NULL); + + if (value) + xmms_cfg_write_string(cfg, section, key, "TRUE"); + else + xmms_cfg_write_string(cfg, section, key, "FALSE"); +} + +void xmms_cfg_write_float(ConfigFile * cfg, + const gchar * section, const gchar * key, + gfloat value) +{ + gchar *strvalue, *locale; + + g_return_if_fail(cfg != NULL); + g_return_if_fail(section != NULL); + g_return_if_fail(key != NULL); + + locale = g_strdup(setlocale(LC_NUMERIC, NULL)); + setlocale(LC_NUMERIC, "C"); + strvalue = g_strdup_printf("%g", value); + setlocale(LC_NUMERIC, locale); + xmms_cfg_write_string(cfg, section, key, strvalue); + g_free(locale); + g_free(strvalue); +} + +void xmms_cfg_write_double(ConfigFile * cfg, + const gchar * section, const gchar * key, + gdouble value) +{ + gchar *strvalue, *locale; + + g_return_if_fail(cfg != NULL); + g_return_if_fail(section != NULL); + g_return_if_fail(key != NULL); + + locale = g_strdup(setlocale(LC_NUMERIC, NULL)); + setlocale(LC_NUMERIC, "C"); + strvalue = g_strdup_printf("%g", value); + setlocale(LC_NUMERIC, locale); + xmms_cfg_write_string(cfg, section, key, strvalue); + g_free(locale); + g_free(strvalue); +} + +void xmms_cfg_remove_key(ConfigFile * cfg, + const gchar * section, const gchar * key) +{ + ConfigSection *sect; + ConfigLine *line; + + g_return_if_fail(cfg != NULL); + g_return_if_fail(section != NULL); + g_return_if_fail(key != NULL); + + if ((sect = xmms_cfg_find_section(cfg, section)) != NULL) { + if ((line = xmms_cfg_find_string(sect, key)) != NULL) { + g_free(line->key); + g_free(line->value); + g_free(line); + sect->lines = g_list_remove(sect->lines, line); + } + } +} + +void xmms_cfg_free(ConfigFile * cfg) +{ + ConfigSection *section; + ConfigLine *line; + GList *section_list, *line_list; + + if (cfg == NULL) + return; + + section_list = cfg->sections; + while (section_list) { + section = (ConfigSection *) section_list->data; + g_free(section->name); + + line_list = section->lines; + while (line_list) { + line = (ConfigLine *) line_list->data; + g_free(line->key); + g_free(line->value); + g_free(line); + line_list = g_list_next(line_list); + } + g_list_free(section->lines); + g_free(section); + + section_list = g_list_next(section_list); + } + g_list_free(cfg->sections); + g_free(cfg); +} + +static ConfigSection *xmms_cfg_create_section(ConfigFile * cfg, + const gchar * name) +{ + ConfigSection *section; + + section = g_new0(ConfigSection, 1); + section->name = g_strdup(name); + cfg->sections = g_list_append(cfg->sections, section); + + return section; +} + +static ConfigLine *xmms_cfg_create_string(ConfigSection * section, + const gchar * key, + const gchar * value) +{ + ConfigLine *line; + + line = g_new0(ConfigLine, 1); + line->key = g_strstrip(g_strdup(key)); + line->value = g_strstrip(g_strdup(value)); + section->lines = g_list_append(section->lines, line); + + return line; +} + +static ConfigSection *xmms_cfg_find_section(ConfigFile * cfg, + const gchar * name) +{ + ConfigSection *section; + GList *list; + + list = cfg->sections; + while (list) { + section = (ConfigSection *) list->data; + if (!strcasecmp(section->name, name)) + return section; + list = g_list_next(list); + } + return NULL; +} + +static ConfigLine *xmms_cfg_find_string(ConfigSection * section, + const gchar * key) +{ + ConfigLine *line; + GList *list; + + list = section->lines; + while (list) { + line = (ConfigLine *) list->data; + if (!strcasecmp(line->key, key)) + return line; + list = g_list_next(list); + } + return NULL; +}