Another batch of patches: * Put the filter chain parsing function in its own module, filter_config * Fixed a couple of memory leaks in the error handlers of route filter * Got rid of loud g_error() and made filter_config report using GError * Minor fix to error reporting of filter_configured_new, rewrote filter_config to use it.
-- Albin Eldstål-Damlin
>From dddeb2b3124db2a72a0b230a7ac8378715999258 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albin=20Eldst=C3=A5l-Damlin?= <laeder.k...@gmail.com> Date: Mon, 14 Dec 2009 21:09:28 +0100 Subject: [PATCH 1/4] Split filter_config into its own module --- Makefile.am | 2 + src/filter/chain_filter_plugin.c | 97 ----------------------------- src/filter/chain_filter_plugin.h | 12 ---- src/filter_config.c | 125 ++++++++++++++++++++++++++++++++++++++ src/filter_config.h | 46 ++++++++++++++ src/output_init.c | 1 + 6 files changed, 174 insertions(+), 109 deletions(-) create mode 100644 src/filter_config.c create mode 100644 src/filter_config.h diff --git a/Makefile.am b/Makefile.am index a55a5e1..cfed9f2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -47,6 +47,7 @@ mpd_headers = \ src/output_print.h \ src/output_command.h \ src/filter_internal.h \ + src/filter_config.h \ src/filter_plugin.h \ src/filter_registry.h \ src/filter/chain_filter_plugin.h \ @@ -230,6 +231,7 @@ src_mpd_SOURCES = \ src/exclude.c \ src/fd_util.c \ src/fifo_buffer.c \ + src/filter_config.c \ src/filter_plugin.c \ src/filter_registry.c \ src/update.c \ diff --git a/src/filter/chain_filter_plugin.c b/src/filter/chain_filter_plugin.c index 5f9544b..48100bc 100644 --- a/src/filter/chain_filter_plugin.c +++ b/src/filter/chain_filter_plugin.c @@ -25,7 +25,6 @@ #include "filter_registry.h" #include <assert.h> -#include <string.h> struct filter_chain { /** the base class */ @@ -179,99 +178,3 @@ filter_chain_append(struct filter *_chain, struct filter *filter) chain->children = g_slist_append(chain->children, filter); } -/** - * Find the "filter" configuration block for the specified name. - * - * @param filter_template_name the name of the filter template - * @return the configuration block, or NULL if none was configured - */ -static const struct config_param * -filter_plugin_config(const char *filter_template_name) -{ - const struct config_param *param = NULL; - - while ((param = config_get_next_param(CONF_AUDIO_FILTER, param)) != NULL) { - const char *name = - config_get_block_string(param, "name", NULL); - if (name == NULL) - g_error("filter configuration without 'name' name in line %d", - param->line); - - if (strcmp(name, filter_template_name) == 0) - return param; - } - - return NULL; -} - -/** - * Builds a filter chain from a configuration string on the form - * "name1, name2, name3, ..." by looking up each name among the - * configured filter sections. - * @param chain the chain to append filters on - * @param spec the filter chain specification - * @return the number of filters which were successfully added - */ -unsigned int -filter_chain_parse(struct filter *chain, const char *spec) { - - // Split on comma - gchar** tokens = g_strsplit_set(spec, ",", 255); - - int added_filters = 0; - - // Add each name to the filter chain by instantiating an actual filter - char **template_names = tokens; - while (*template_names != NULL) { - const char *plugin_name; - const struct filter_plugin *fp; - struct filter *f; - const struct config_param *cfg; - - // Squeeze whitespace - g_strstrip(*template_names); - - cfg = filter_plugin_config(*template_names); - if (cfg == NULL) { - g_error("Unable to locate filter template %s", - *template_names); - ++template_names; - continue; - } - - // Figure out what kind of a plugin that is - plugin_name = config_get_block_string(cfg, "plugin", NULL); - if (plugin_name == NULL) { - g_error("filter configuration without 'plugin' at line %d", - cfg->line); - ++template_names; - continue; - } - - // Instantiate one of those filter plugins with the template name as a hint - fp = filter_plugin_by_name(plugin_name); - if (fp == NULL) { - g_error("filter plugin not found: %s", - plugin_name); - ++template_names; - continue; - } - - f = filter_new(fp, cfg, NULL); - if (f == NULL) { - g_error("filter plugin initialization failed: %s", - plugin_name); - ++template_names; - continue; - } - - filter_chain_append(chain, f); - ++added_filters; - - ++template_names; - } - - g_strfreev(tokens); - - return added_filters; -} diff --git a/src/filter/chain_filter_plugin.h b/src/filter/chain_filter_plugin.h index 54e0708..f8462b2 100644 --- a/src/filter/chain_filter_plugin.h +++ b/src/filter/chain_filter_plugin.h @@ -45,16 +45,4 @@ filter_chain_new(void); void filter_chain_append(struct filter *chain, struct filter *filter); -/** - * Builds a filter chain from a configuration string on the form - * "name1, name2, name3, ..." by looking up each name among the - * configured filter sections. If no filters are specified, a - * null filter is automatically appended. - * @param chain the chain to append filters on - * @param spec the filter chain specification - * @return the number of filters which were successfully added - */ -unsigned int -filter_chain_parse(struct filter *chain, const char *spec); - #endif diff --git a/src/filter_config.c b/src/filter_config.c new file mode 100644 index 0000000..1e20fa0 --- /dev/null +++ b/src/filter_config.c @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2003-2009 The Music Player Daemon Project + * http://www.musicpd.org + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" +#include "conf.h" +#include "filter/chain_filter_plugin.h" +#include "filter_plugin.h" +#include "filter_internal.h" +#include "filter_registry.h" + +#include <string.h> + +/** + * Find the "filter" configuration block for the specified name. + * + * @param filter_template_name the name of the filter template + * @return the configuration block, or NULL if none was configured + */ +static const struct config_param * +filter_plugin_config(const char *filter_template_name) +{ + const struct config_param *param = NULL; + + while ((param = config_get_next_param(CONF_AUDIO_FILTER, param)) != NULL) { + const char *name = + config_get_block_string(param, "name", NULL); + if (name == NULL) + g_error("filter configuration without 'name' name in line %d", + param->line); + + if (strcmp(name, filter_template_name) == 0) + return param; + } + + return NULL; +} + +/** + * Builds a filter chain from a configuration string on the form + * "name1, name2, name3, ..." by looking up each name among the + * configured filter sections. + * @param chain the chain to append filters on + * @param spec the filter chain specification + * @return the number of filters which were successfully added + */ +unsigned int +filter_chain_parse(struct filter *chain, const char *spec) +{ + + // Split on comma + gchar** tokens = g_strsplit_set(spec, ",", 255); + + int added_filters = 0; + + // Add each name to the filter chain by instantiating an actual filter + char **template_names = tokens; + while (*template_names != NULL) { + const char *plugin_name; + const struct filter_plugin *fp; + struct filter *f; + const struct config_param *cfg; + + // Squeeze whitespace + g_strstrip(*template_names); + + cfg = filter_plugin_config(*template_names); + if (cfg == NULL) { + g_error("Unable to locate filter template %s", + *template_names); + ++template_names; + continue; + } + + // Figure out what kind of a plugin that is + plugin_name = config_get_block_string(cfg, "plugin", NULL); + if (plugin_name == NULL) { + g_error("filter configuration without 'plugin' at line %d", + cfg->line); + ++template_names; + continue; + } + + // Instantiate one of those filter plugins with the template name as a hint + fp = filter_plugin_by_name(plugin_name); + if (fp == NULL) { + g_error("filter plugin not found: %s", + plugin_name); + ++template_names; + continue; + } + + f = filter_new(fp, cfg, NULL); + if (f == NULL) { + g_error("filter plugin initialization failed: %s", + plugin_name); + ++template_names; + continue; + } + + filter_chain_append(chain, f); + ++added_filters; + + ++template_names; + } + + g_strfreev(tokens); + + return added_filters; +} diff --git a/src/filter_config.h b/src/filter_config.h new file mode 100644 index 0000000..eadaf24 --- /dev/null +++ b/src/filter_config.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2003-2009 The Music Player Daemon Project + * http://www.musicpd.org + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/** \file + * + * Utility functions for filter configuration + */ + +#ifndef MPD_FILTER_CONFIG_H +#define MPD_FILTER_CONFIG_H + +#include "conf.h" +#include "filter/chain_filter_plugin.h" +#include "filter_plugin.h" +#include "filter_internal.h" +#include "filter_registry.h" + + +/** + * Builds a filter chain from a configuration string on the form + * "name1, name2, name3, ..." by looking up each name among the + * configured filter sections. + * @param chain the chain to append filters on + * @param spec the filter chain specification + * @return the number of filters which were successfully added + */ +unsigned int +filter_chain_parse(struct filter *chain, const char *spec); + +#endif diff --git a/src/output_init.c b/src/output_init.c index 6ca190f..f4025fb 100644 --- a/src/output_init.c +++ b/src/output_init.c @@ -29,6 +29,7 @@ #include "mixer/software_mixer_plugin.h" #include "filter_plugin.h" #include "filter_registry.h" +#include "filter_config.h" #include "filter/chain_filter_plugin.h" #include <glib.h> -- 1.6.4.4
>From 0591b168dcef71099742dd781b8730d8bca137cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albin=20Eldst=C3=A5l-Damlin?= <laeder.k...@gmail.com> Date: Mon, 14 Dec 2009 21:37:13 +0100 Subject: [PATCH 2/4] Fixed memory leak on incorrect route configuration --- src/filter/route_filter_plugin.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/src/filter/route_filter_plugin.c b/src/filter/route_filter_plugin.c index 9ec30e6..5610220 100644 --- a/src/filter/route_filter_plugin.c +++ b/src/filter/route_filter_plugin.c @@ -159,6 +159,8 @@ route_filter_parse(const struct config_param *param, g_set_error(error_r, config_quark(), 1, "Invalid copy around %d in routes spec: %s", param->line, tokens[c]); + g_strfreev(sd); + g_strfreev(tokens); return; } @@ -196,6 +198,8 @@ route_filter_parse(const struct config_param *param, g_set_error(error_r, config_quark(), 1, "Invalid copy around %d in routes spec: %s", param->line, tokens[c]); + g_strfreev(sd); + g_strfreev(tokens); return; } -- 1.6.4.4
>From 081187e91022d0e2c256d50480786c6d11c405e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albin=20Eldst=C3=A5l-Damlin?= <laeder.k...@gmail.com> Date: Mon, 14 Dec 2009 21:46:45 +0100 Subject: [PATCH 3/4] Proper error reporting from filter_config --- src/filter_config.c | 49 +++++++++++++++++++++++++++++++------------------ src/filter_config.h | 3 ++- src/output_init.c | 11 ++++++++++- 3 files changed, 43 insertions(+), 20 deletions(-) diff --git a/src/filter_config.c b/src/filter_config.c index 1e20fa0..3b3bf17 100644 --- a/src/filter_config.c +++ b/src/filter_config.c @@ -19,6 +19,7 @@ #include "config.h" #include "conf.h" +#include "filter_config.h" #include "filter/chain_filter_plugin.h" #include "filter_plugin.h" #include "filter_internal.h" @@ -26,14 +27,22 @@ #include <string.h> + +static GQuark +filter_quark(void) +{ + return g_quark_from_static_string("filter"); +} + /** * Find the "filter" configuration block for the specified name. * * @param filter_template_name the name of the filter template + * @param error_r space to return an error description * @return the configuration block, or NULL if none was configured */ static const struct config_param * -filter_plugin_config(const char *filter_template_name) +filter_plugin_config(const char *filter_template_name, GError **error_r) { const struct config_param *param = NULL; @@ -41,13 +50,18 @@ filter_plugin_config(const char *filter_template_name) const char *name = config_get_block_string(param, "name", NULL); if (name == NULL) - g_error("filter configuration without 'name' name in line %d", - param->line); + g_set_error(error_r, filter_quark(), 1, + "filter configuration without 'name' name in line %d", + param->line); if (strcmp(name, filter_template_name) == 0) return param; } + g_set_error(error_r, filter_quark(), 1, + "filter template not found: %s", + filter_template_name); + return NULL; } @@ -57,10 +71,11 @@ filter_plugin_config(const char *filter_template_name) * configured filter sections. * @param chain the chain to append filters on * @param spec the filter chain specification + * @param error_r space to return an error description * @return the number of filters which were successfully added */ unsigned int -filter_chain_parse(struct filter *chain, const char *spec) +filter_chain_parse(struct filter *chain, const char *spec, GError **error_r) { // Split on comma @@ -79,38 +94,36 @@ filter_chain_parse(struct filter *chain, const char *spec) // Squeeze whitespace g_strstrip(*template_names); - cfg = filter_plugin_config(*template_names); + cfg = filter_plugin_config(*template_names, error_r); if (cfg == NULL) { - g_error("Unable to locate filter template %s", - *template_names); - ++template_names; - continue; + // The error has already been set, just stop. + break; } // Figure out what kind of a plugin that is plugin_name = config_get_block_string(cfg, "plugin", NULL); if (plugin_name == NULL) { - g_error("filter configuration without 'plugin' at line %d", + g_set_error(error_r, filter_quark(), 1, + "filter configuration without 'plugin' at line %d", cfg->line); - ++template_names; - continue; + break; } // Instantiate one of those filter plugins with the template name as a hint fp = filter_plugin_by_name(plugin_name); if (fp == NULL) { - g_error("filter plugin not found: %s", + g_set_error(error_r, filter_quark(), 2, + "filter plugin not found: %s", plugin_name); - ++template_names; - continue; + break; } f = filter_new(fp, cfg, NULL); if (f == NULL) { - g_error("filter plugin initialization failed: %s", + g_set_error(error_r, filter_quark(), 3, + "filter plugin initialization failed: %s", plugin_name); - ++template_names; - continue; + break; } filter_chain_append(chain, f); diff --git a/src/filter_config.h b/src/filter_config.h index eadaf24..8e20320 100644 --- a/src/filter_config.h +++ b/src/filter_config.h @@ -38,9 +38,10 @@ * configured filter sections. * @param chain the chain to append filters on * @param spec the filter chain specification + * @param error_r space to return an error description * @return the number of filters which were successfully added */ unsigned int -filter_chain_parse(struct filter *chain, const char *spec); +filter_chain_parse(struct filter *chain, const char *spec, GError **error_r); #endif diff --git a/src/output_init.c b/src/output_init.c index f4025fb..ab52578 100644 --- a/src/output_init.c +++ b/src/output_init.c @@ -193,9 +193,18 @@ audio_output_init(struct audio_output *ao, const struct config_param *param, ao->filter = filter_chain_new(); assert(ao->filter != NULL); filter_chain_parse(ao->filter, - config_get_block_string(param, AUDIO_FILTERS, "") + config_get_block_string(param, AUDIO_FILTERS, ""), + &error ); + // It's not really fatal - Part of the filter chain has been set up already + // and even an empty one will work (if only with unexpected behaviour) + if (error != NULL) { + g_warning("Failed to initialize filter chain for '%s': %s", + ao->name, error->message); + g_error_free(error); + } + ao->thread = NULL; ao->command = AO_COMMAND_NONE; ao->mutex = g_mutex_new(); -- 1.6.4.4
>From 3c44d91237d2326ccff8e02d57d740c06187987c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albin=20Eldst=C3=A5l-Damlin?= <laeder.k...@gmail.com> Date: Mon, 14 Dec 2009 21:59:32 +0100 Subject: [PATCH 4/4] Fix and use filter_configured_new() --- src/filter_config.c | 26 +++----------------------- src/filter_plugin.c | 8 ++++++-- 2 files changed, 9 insertions(+), 25 deletions(-) diff --git a/src/filter_config.c b/src/filter_config.c index 3b3bf17..2473baf 100644 --- a/src/filter_config.c +++ b/src/filter_config.c @@ -86,8 +86,6 @@ filter_chain_parse(struct filter *chain, const char *spec, GError **error_r) // Add each name to the filter chain by instantiating an actual filter char **template_names = tokens; while (*template_names != NULL) { - const char *plugin_name; - const struct filter_plugin *fp; struct filter *f; const struct config_param *cfg; @@ -100,29 +98,10 @@ filter_chain_parse(struct filter *chain, const char *spec, GError **error_r) break; } - // Figure out what kind of a plugin that is - plugin_name = config_get_block_string(cfg, "plugin", NULL); - if (plugin_name == NULL) { - g_set_error(error_r, filter_quark(), 1, - "filter configuration without 'plugin' at line %d", - cfg->line); - break; - } - // Instantiate one of those filter plugins with the template name as a hint - fp = filter_plugin_by_name(plugin_name); - if (fp == NULL) { - g_set_error(error_r, filter_quark(), 2, - "filter plugin not found: %s", - plugin_name); - break; - } - - f = filter_new(fp, cfg, NULL); + f = filter_configured_new(cfg, error_r); if (f == NULL) { - g_set_error(error_r, filter_quark(), 3, - "filter plugin initialization failed: %s", - plugin_name); + // The error has already been set, just stop. break; } @@ -136,3 +115,4 @@ filter_chain_parse(struct filter *chain, const char *spec, GError **error_r) return added_filters; } + diff --git a/src/filter_plugin.c b/src/filter_plugin.c index 4567726..ecc4b54 100644 --- a/src/filter_plugin.c +++ b/src/filter_plugin.c @@ -49,14 +49,18 @@ filter_configured_new(const struct config_param *param, GError **error_r) assert(error_r == NULL || *error_r == NULL); plugin_name = config_get_block_string(param, "plugin", NULL); - if (plugin_name == NULL) + if (plugin_name == NULL) { g_set_error(error_r, config_quark(), 0, "No filter plugin specified"); + return NULL; + } plugin = filter_plugin_by_name(plugin_name); - if (plugin == NULL) + if (plugin == NULL) { g_set_error(error_r, config_quark(), 0, "No such filter plugin: %s", plugin_name); + return NULL; + } return filter_new(plugin, param, error_r); } -- 1.6.4.4
------------------------------------------------------------------------------ Return on Information: Google Enterprise Search pays you back Get the facts. http://p.sf.net/sfu/google-dev2dev
_______________________________________________ Musicpd-dev-team mailing list Musicpd-dev-team@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/musicpd-dev-team