aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2012-06-12 23:22:03 +0200
committerMax Kellermann <max@duempel.org>2012-06-12 23:22:03 +0200
commit4eb57e1e9a1718ce93eced6bd4fb06d8abb26477 (patch)
tree2355c6d77273cf614822f5a144005ab1d353863b
parentd662c4c0cc089a6a493a7463e440f0f7e7959b48 (diff)
parent1d52e2cc7727d93e65d557c322b5dd7dc149651c (diff)
downloadmpd-4eb57e1e9a1718ce93eced6bd4fb06d8abb26477.tar.gz
mpd-4eb57e1e9a1718ce93eced6bd4fb06d8abb26477.tar.xz
mpd-4eb57e1e9a1718ce93eced6bd4fb06d8abb26477.zip
Merge branch 'v0.16.x'
Conflicts: src/cmdline.c src/decoder/wildmidi_decoder_plugin.c src/gcc.h src/glib_compat.h src/input_stream.c src/output_list.c src/output_thread.c valgrind.suppressions
-rw-r--r--NEWS2
-rw-r--r--src/archive_list.c53
-rw-r--r--src/archive_list.h12
-rw-r--r--src/audio_parser.c11
-rw-r--r--src/cmdline.c81
-rw-r--r--src/decoder/wildmidi_decoder_plugin.c1
-rw-r--r--src/decoder_list.c15
-rw-r--r--src/decoder_list.h10
-rw-r--r--src/decoder_print.c5
-rw-r--r--src/encoder_list.c18
-rw-r--r--src/encoder_list.h13
-rw-r--r--src/glib_compat.h28
-rw-r--r--src/input_init.c7
-rw-r--r--src/input_registry.h10
-rw-r--r--src/input_stream.c6
-rw-r--r--src/ls.c4
-rw-r--r--src/output_init.c5
-rw-r--r--src/output_list.c19
-rw-r--r--src/output_list.h12
-rw-r--r--src/output_thread.c5
-rw-r--r--src/playlist_list.c31
-rw-r--r--src/playlist_list.h8
-rw-r--r--src/playlist_save.c1
-rw-r--r--src/update_walk.c1
-rw-r--r--valgrind.suppressions56
25 files changed, 239 insertions, 175 deletions
diff --git a/NEWS b/NEWS
index b6ea52096..ec8f167cd 100644
--- a/NEWS
+++ b/NEWS
@@ -43,6 +43,8 @@ ver 0.17 (2011/??/??)
ver 0.16.9 (2012/??/??)
* decoder:
- ffmpeg: support WebM
+* improve --version output
+* WIN32: fix renaming of stored playlists with non-ASCII names
ver 0.16.8 (2012/04/04)
diff --git a/src/archive_list.c b/src/archive_list.c
index 24aa060c9..e23567bdb 100644
--- a/src/archive_list.c
+++ b/src/archive_list.c
@@ -28,7 +28,7 @@
#include <string.h>
#include <glib.h>
-static const struct archive_plugin *const archive_plugins[] = {
+const struct archive_plugin *const archive_plugins[] = {
#ifdef HAVE_BZ2
&bz2_archive_plugin,
#endif
@@ -44,53 +44,32 @@ static const struct archive_plugin *const archive_plugins[] = {
/** which plugins have been initialized successfully? */
static bool archive_plugins_enabled[G_N_ELEMENTS(archive_plugins) - 1];
+#define archive_plugins_for_each_enabled(plugin) \
+ archive_plugins_for_each(plugin) \
+ if (archive_plugins_enabled[archive_plugin_iterator - archive_plugins])
+
const struct archive_plugin *
archive_plugin_from_suffix(const char *suffix)
{
if (suffix == NULL)
return NULL;
- for (unsigned i = 0; archive_plugins[i] != NULL; ++i) {
- const struct archive_plugin *plugin = archive_plugins[i];
- if (archive_plugins_enabled[i] &&
- plugin->suffixes != NULL &&
- string_array_contains(plugin->suffixes, suffix)) {
- ++i;
+ archive_plugins_for_each_enabled(plugin)
+ if (plugin->suffixes != NULL &&
+ string_array_contains(plugin->suffixes, suffix))
return plugin;
- }
- }
+
return NULL;
}
const struct archive_plugin *
archive_plugin_from_name(const char *name)
{
- for (unsigned i = 0; archive_plugins[i] != NULL; ++i) {
- const struct archive_plugin *plugin = archive_plugins[i];
- if (archive_plugins_enabled[i] &&
- strcmp(plugin->name, name) == 0)
+ archive_plugins_for_each_enabled(plugin)
+ if (strcmp(plugin->name, name) == 0)
return plugin;
- }
- return NULL;
-}
-void archive_plugin_print_all_suffixes(FILE * fp)
-{
- const char *const*suffixes;
-
- for (unsigned i = 0; archive_plugins[i] != NULL; ++i) {
- const struct archive_plugin *plugin = archive_plugins[i];
- if (!archive_plugins_enabled[i])
- continue;
-
- suffixes = plugin->suffixes;
- while (suffixes && *suffixes) {
- fprintf(fp, "%s ", *suffixes);
- suffixes++;
- }
- }
- fprintf(fp, "\n");
- fflush(fp);
+ return NULL;
}
void archive_plugin_init_all(void)
@@ -104,10 +83,8 @@ void archive_plugin_init_all(void)
void archive_plugin_deinit_all(void)
{
- for (unsigned i = 0; archive_plugins[i] != NULL; ++i) {
- const struct archive_plugin *plugin = archive_plugins[i];
- if (archive_plugins_enabled[i] && plugin->finish != NULL)
- archive_plugins[i]->finish();
- }
+ archive_plugins_for_each_enabled(plugin)
+ if (plugin->finish != NULL)
+ plugin->finish();
}
diff --git a/src/archive_list.h b/src/archive_list.h
index 24e4063bf..f944583ed 100644
--- a/src/archive_list.h
+++ b/src/archive_list.h
@@ -20,10 +20,16 @@
#ifndef MPD_ARCHIVE_LIST_H
#define MPD_ARCHIVE_LIST_H
-#include <stdio.h>
-
struct archive_plugin;
+extern const struct archive_plugin *const archive_plugins[];
+
+#define archive_plugins_for_each(plugin) \
+ for (const struct archive_plugin *plugin, \
+ *const*archive_plugin_iterator = &archive_plugins[0]; \
+ (plugin = *archive_plugin_iterator) != NULL; \
+ ++archive_plugin_iterator)
+
/* interface for using plugins */
const struct archive_plugin *
@@ -32,8 +38,6 @@ archive_plugin_from_suffix(const char *suffix);
const struct archive_plugin *
archive_plugin_from_name(const char *name);
-void archive_plugin_print_all_suffixes(FILE * fp);
-
/* this is where we "load" all the "plugins" ;-) */
void archive_plugin_init_all(void);
diff --git a/src/audio_parser.c b/src/audio_parser.c
index b1be8887a..152eab5d4 100644
--- a/src/audio_parser.c
+++ b/src/audio_parser.c
@@ -26,6 +26,7 @@
#include "audio_parser.h"
#include "audio_format.h"
#include "audio_check.h"
+#include "gcc.h"
#include <assert.h>
#include <string.h>
@@ -172,6 +173,11 @@ audio_format_parse(struct audio_format *dest, const char *src,
/* parse sample rate */
+#if GCC_CHECK_VERSION(4,7)
+ /* workaround -Wmaybe-uninitialized false positive */
+ rate = 0;
+#endif
+
if (!parse_sample_rate(src, mask, &rate, &src, error_r))
return false;
@@ -183,6 +189,11 @@ audio_format_parse(struct audio_format *dest, const char *src,
/* parse sample format */
+#if GCC_CHECK_VERSION(4,7)
+ /* workaround -Wmaybe-uninitialized false positive */
+ sample_format = SAMPLE_FORMAT_UNDEFINED;
+#endif
+
if (!parse_sample_format(src, mask, &sample_format, &src, error_r))
return false;
diff --git a/src/cmdline.c b/src/cmdline.c
index 8ab317730..a972daf95 100644
--- a/src/cmdline.c
+++ b/src/cmdline.c
@@ -25,15 +25,23 @@
#include "decoder_list.h"
#include "decoder_plugin.h"
#include "output_list.h"
+#include "output_plugin.h"
+#include "input_registry.h"
+#include "input_plugin.h"
+#include "playlist_list.h"
+#include "playlist_plugin.h"
#include "ls.h"
#include "mpd_error.h"
+#include "glib_compat.h"
#ifdef ENABLE_ENCODER
#include "encoder_list.h"
+#include "encoder_plugin.h"
#endif
#ifdef ENABLE_ARCHIVE
#include "archive_list.h"
+#include "archive_plugin.h"
#endif
#include <glib.h>
@@ -54,59 +62,70 @@ cmdline_quark(void)
return g_quark_from_static_string("cmdline");
}
-static void
-print_all_decoders(FILE *fp)
-{
- for (unsigned i = 0; decoder_plugins[i] != NULL; ++i) {
- const struct decoder_plugin *plugin = decoder_plugins[i];
- const char *const*suffixes;
-
- fprintf(fp, "[%s]", plugin->name);
-
- for (suffixes = plugin->suffixes;
- suffixes != NULL && *suffixes != NULL;
- ++suffixes) {
- fprintf(fp, " %s", *suffixes);
- }
-
- fprintf(fp, "\n");
- }
-}
-
G_GNUC_NORETURN
static void version(void)
{
puts(PACKAGE " (MPD: Music Player Daemon) " VERSION " \n"
"\n"
"Copyright (C) 2003-2007 Warren Dukes <warren.dukes@gmail.com>\n"
- "Copyright (C) 2008-2011 Max Kellermann <max@duempel.org>\n"
+ "Copyright (C) 2008-2012 Max Kellermann <max@duempel.org>\n"
"This is free software; see the source for copying conditions. There is NO\n"
"warranty; not even MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
"\n"
- "Supported decoders:\n");
+ "Decoders plugins:");
+
+ decoder_plugins_for_each(plugin) {
+ printf(" [%s]", plugin->name);
- print_all_decoders(stdout);
+ const char *const*suffixes = plugin->suffixes;
+ if (suffixes != NULL)
+ for (; *suffixes != NULL; ++suffixes)
+ printf(" %s", *suffixes);
+
+ puts("");
+ }
puts("\n"
- "Supported outputs:\n");
- audio_output_plugin_print_all_types(stdout);
+ "Output plugins:");
+ audio_output_plugins_for_each(plugin)
+ printf(" %s", plugin->name);
+ puts("");
#ifdef ENABLE_ENCODER
puts("\n"
- "Supported encoders:\n");
- encoder_plugin_print_all_types(stdout);
+ "Encoder plugins:");
+ encoder_plugins_for_each(plugin)
+ printf(" %s", plugin->name);
+ puts("");
#endif
-
#ifdef ENABLE_ARCHIVE
puts("\n"
- "Supported archives:\n");
- archive_plugin_init_all();
- archive_plugin_print_all_suffixes(stdout);
+ "Archive plugins:");
+ archive_plugins_for_each(plugin) {
+ printf(" [%s]", plugin->name);
+
+ const char *const*suffixes = plugin->suffixes;
+ if (suffixes != NULL)
+ for (; *suffixes != NULL; ++suffixes)
+ printf(" %s", *suffixes);
+
+ puts("");
+ }
#endif
puts("\n"
- "Supported protocols:\n");
+ "Input plugins:");
+ input_plugins_for_each(plugin)
+ printf(" %s", plugin->name);
+
+ puts("\n\n"
+ "Playlist plugins:");
+ playlist_plugins_for_each(plugin)
+ printf(" %s", plugin->name);
+
+ puts("\n\n"
+ "Protocols:");
print_supported_uri_schemes_to_fp(stdout);
exit(EXIT_SUCCESS);
diff --git a/src/decoder/wildmidi_decoder_plugin.c b/src/decoder/wildmidi_decoder_plugin.c
index a2224940d..2cdb30a9c 100644
--- a/src/decoder/wildmidi_decoder_plugin.c
+++ b/src/decoder/wildmidi_decoder_plugin.c
@@ -20,6 +20,7 @@
#include "config.h"
#include "decoder_api.h"
#include "tag_handler.h"
+#include "glib_compat.h"
#include <glib.h>
diff --git a/src/decoder_list.c b/src/decoder_list.c
index 2029b3e62..e9e29c691 100644
--- a/src/decoder_list.c
+++ b/src/decoder_list.c
@@ -178,12 +178,9 @@ decoder_plugin_from_mime_type(const char *mimeType, unsigned int next)
const struct decoder_plugin *
decoder_plugin_from_name(const char *name)
{
- for (unsigned i = 0; decoder_plugins[i] != NULL; ++i) {
- const struct decoder_plugin *plugin = decoder_plugins[i];
- if (decoder_plugins_enabled[i] &&
- strcmp(plugin->name, name) == 0)
+ decoder_plugins_for_each_enabled(plugin)
+ if (strcmp(plugin->name, name) == 0)
return plugin;
- }
return NULL;
}
@@ -231,10 +228,6 @@ void decoder_plugin_init_all(void)
void decoder_plugin_deinit_all(void)
{
- for (unsigned i = 0; decoder_plugins[i] != NULL; ++i) {
- const struct decoder_plugin *plugin = decoder_plugins[i];
-
- if (decoder_plugins_enabled[i])
- decoder_plugin_finish(plugin);
- }
+ decoder_plugins_for_each_enabled(plugin)
+ decoder_plugin_finish(plugin);
}
diff --git a/src/decoder_list.h b/src/decoder_list.h
index d259cb195..d0a6ade7e 100644
--- a/src/decoder_list.h
+++ b/src/decoder_list.h
@@ -27,6 +27,16 @@ struct decoder_plugin;
extern const struct decoder_plugin *const decoder_plugins[];
extern bool decoder_plugins_enabled[];
+#define decoder_plugins_for_each(plugin) \
+ for (const struct decoder_plugin *plugin, \
+ *const*decoder_plugin_iterator = &decoder_plugins[0]; \
+ (plugin = *decoder_plugin_iterator) != NULL; \
+ ++decoder_plugin_iterator)
+
+#define decoder_plugins_for_each_enabled(plugin) \
+ decoder_plugins_for_each(plugin) \
+ if (decoder_plugins_enabled[decoder_plugin_iterator - decoder_plugins])
+
/* interface for using plugins */
/**
diff --git a/src/decoder_print.c b/src/decoder_print.c
index 72c40ac75..e14477ed8 100644
--- a/src/decoder_print.c
+++ b/src/decoder_print.c
@@ -48,7 +48,6 @@ decoder_plugin_print(struct client *client,
void
decoder_list_print(struct client *client)
{
- for (unsigned i = 0; decoder_plugins[i] != NULL; ++i)
- if (decoder_plugins_enabled[i])
- decoder_plugin_print(client, decoder_plugins[i]);
+ decoder_plugins_for_each_enabled(plugin)
+ decoder_plugin_print(client, plugin);
}
diff --git a/src/encoder_list.c b/src/encoder_list.c
index d98e617b4..2326c1099 100644
--- a/src/encoder_list.c
+++ b/src/encoder_list.c
@@ -30,7 +30,7 @@ extern const struct encoder_plugin twolame_encoder_plugin;
extern const struct encoder_plugin wave_encoder_plugin;
extern const struct encoder_plugin flac_encoder_plugin;
-static const struct encoder_plugin *encoder_plugins[] = {
+const struct encoder_plugin *const encoder_plugins[] = {
&null_encoder_plugin,
#ifdef ENABLE_VORBIS_ENCODER
&vorbis_encoder_plugin,
@@ -53,19 +53,9 @@ static const struct encoder_plugin *encoder_plugins[] = {
const struct encoder_plugin *
encoder_plugin_get(const char *name)
{
- for (unsigned i = 0; encoder_plugins[i] != NULL; ++i)
- if (strcmp(encoder_plugins[i]->name, name) == 0)
- return encoder_plugins[i];
+ encoder_plugins_for_each(plugin)
+ if (strcmp(plugin->name, name) == 0)
+ return plugin;
return NULL;
}
-
-void
-encoder_plugin_print_all_types(FILE * fp)
-{
- for (unsigned i = 0; encoder_plugins[i] != NULL; ++i)
- fprintf(fp, "%s ", encoder_plugins[i]->name);
-
- fprintf(fp, "\n");
- fflush(fp);
-}
diff --git a/src/encoder_list.h b/src/encoder_list.h
index 6316d5d2f..fb1c9bf9c 100644
--- a/src/encoder_list.h
+++ b/src/encoder_list.h
@@ -20,10 +20,16 @@
#ifndef MPD_ENCODER_LIST_H
#define MPD_ENCODER_LIST_H
-#include <stdio.h>
-
struct encoder_plugin;
+extern const struct encoder_plugin *const encoder_plugins[];
+
+#define encoder_plugins_for_each(plugin) \
+ for (const struct encoder_plugin *plugin, \
+ *const*encoder_plugin_iterator = &encoder_plugins[0]; \
+ (plugin = *encoder_plugin_iterator) != NULL; \
+ ++encoder_plugin_iterator)
+
/**
* Looks up an encoder plugin by its name.
*
@@ -34,7 +40,4 @@ struct encoder_plugin;
const struct encoder_plugin *
encoder_plugin_get(const char *name);
-void
-encoder_plugin_print_all_types(FILE * fp);
-
#endif
diff --git a/src/glib_compat.h b/src/glib_compat.h
index 330c9e779..989bf3b81 100644
--- a/src/glib_compat.h
+++ b/src/glib_compat.h
@@ -109,4 +109,32 @@ g_source_get_time(GSource *source)
#endif
+#if defined(G_OS_WIN32) && defined(g_file_test)
+
+/* Modern GLib on Win32 likes to use UTF-8 for file names.
+It redefines g_file_test() to be g_file_test_utf8().
+This gives incorrect results for non-ASCII files.
+Old g_file_test() is available for *binary compatibility*,
+but symbol is hidden from linker, we copy-paste its definition here */
+
+#undef g_file_test
+
+static inline gboolean
+g_file_test(const gchar *filename, GFileTest test)
+{
+ gchar *utf8_filename = g_locale_to_utf8(filename, -1, NULL, NULL, NULL);
+ gboolean retval;
+
+ if (utf8_filename == NULL)
+ return FALSE;
+
+ retval = g_file_test_utf8(utf8_filename, test);
+
+ g_free(utf8_filename);
+
+ return retval;
+}
+
+#endif
+
#endif
diff --git a/src/input_init.c b/src/input_init.c
index cf5affb4e..e1698b64c 100644
--- a/src/input_init.c
+++ b/src/input_init.c
@@ -99,8 +99,7 @@ input_stream_global_init(GError **error_r)
void input_stream_global_finish(void)
{
- for (unsigned i = 0; input_plugins[i] != NULL; ++i)
- if (input_plugins_enabled[i] &&
- input_plugins[i]->finish != NULL)
- input_plugins[i]->finish();
+ input_plugins_for_each_enabled(plugin)
+ if (plugin->finish != NULL)
+ plugin->finish();
}
diff --git a/src/input_registry.h b/src/input_registry.h
index a1b057469..4f5fff8da 100644
--- a/src/input_registry.h
+++ b/src/input_registry.h
@@ -32,4 +32,14 @@ extern const struct input_plugin *const input_plugins[];
extern bool input_plugins_enabled[];
+#define input_plugins_for_each(plugin) \
+ for (const struct input_plugin *plugin, \
+ *const*input_plugin_iterator = &input_plugins[0]; \
+ (plugin = *input_plugin_iterator) != NULL; \
+ ++input_plugin_iterator)
+
+#define input_plugins_for_each_enabled(plugin) \
+ input_plugins_for_each(plugin) \
+ if (input_plugins_enabled[input_plugin_iterator - input_plugins])
+
#endif
diff --git a/src/input_stream.c b/src/input_stream.c
index 60a1559ba..e445dca6c 100644
--- a/src/input_stream.c
+++ b/src/input_stream.c
@@ -42,13 +42,9 @@ input_stream_open(const char *url,
assert(mutex != NULL);
assert(error_r == NULL || *error_r == NULL);
- for (unsigned i = 0; input_plugins[i] != NULL; ++i) {
- const struct input_plugin *plugin = input_plugins[i];
+ input_plugins_for_each_enabled(plugin) {
struct input_stream *is;
- if (!input_plugins_enabled[i])
- continue;
-
is = plugin->open(url, mutex, cond, &error);
if (is != NULL) {
assert(is->plugin != NULL);
diff --git a/src/ls.c b/src/ls.c
index 5ed9fc579..310c2d7b6 100644
--- a/src/ls.c
+++ b/src/ls.c
@@ -63,10 +63,10 @@ void print_supported_uri_schemes_to_fp(FILE *fp)
const char **prefixes = remoteUrlPrefixes;
#ifdef HAVE_UN
- fprintf(fp, "file:// ");
+ fprintf(fp, " file://");
#endif
while (*prefixes) {
- fprintf(fp, "%s ", *prefixes);
+ fprintf(fp, " %s", *prefixes);
prefixes++;
}
fprintf(fp,"\n");
diff --git a/src/output_init.c b/src/output_init.c
index 3b8a7a9f1..d2c86bfa2 100644
--- a/src/output_init.c
+++ b/src/output_init.c
@@ -49,12 +49,9 @@
static const struct audio_output_plugin *
audio_output_detect(GError **error)
{
- const struct audio_output_plugin *plugin;
- unsigned i;
-
g_warning("Attempt to detect audio output device");
- audio_output_plugins_for_each(plugin, i) {
+ audio_output_plugins_for_each(plugin) {
if (plugin->test_default_device == NULL)
continue;
diff --git a/src/output_list.c b/src/output_list.c
index ffb0698f1..835c02bba 100644
--- a/src/output_list.c
+++ b/src/output_list.c
@@ -39,7 +39,7 @@
#include "output/solaris_output_plugin.h"
#include "output/winmm_output_plugin.h"
-const struct audio_output_plugin *audio_output_plugins[] = {
+const struct audio_output_plugin *const audio_output_plugins[] = {
#ifdef HAVE_SHOUT
&shout_output_plugin,
#endif
@@ -98,24 +98,9 @@ const struct audio_output_plugin *audio_output_plugins[] = {
const struct audio_output_plugin *
audio_output_plugin_get(const char *name)
{
- unsigned int i;
- const struct audio_output_plugin *plugin;
-
- audio_output_plugins_for_each(plugin, i)
+ audio_output_plugins_for_each(plugin)
if (strcmp(plugin->name, name) == 0)
return plugin;
return NULL;
}
-
-void audio_output_plugin_print_all_types(FILE * fp)
-{
- unsigned i;
- const struct audio_output_plugin *plugin;
-
- audio_output_plugins_for_each(plugin, i)
- fprintf(fp, "%s ", plugin->name);
-
- fprintf(fp, "\n");
- fflush(fp);
-}
diff --git a/src/output_list.h b/src/output_list.h
index 3deb31c00..185ada716 100644
--- a/src/output_list.h
+++ b/src/output_list.h
@@ -20,16 +20,14 @@
#ifndef MPD_OUTPUT_LIST_H
#define MPD_OUTPUT_LIST_H
-#include <stdio.h>
-
-extern const struct audio_output_plugin *audio_output_plugins[];
+extern const struct audio_output_plugin *const audio_output_plugins[];
const struct audio_output_plugin *
audio_output_plugin_get(const char *name);
-void audio_output_plugin_print_all_types(FILE * fp);
-
-#define audio_output_plugins_for_each(plugin, i) \
- for (i = 0; (plugin = audio_output_plugins[i]) != NULL; ++i)
+#define audio_output_plugins_for_each(plugin) \
+ for (const struct audio_output_plugin *plugin, \
+ *const*output_plugin_iterator = &audio_output_plugins[0]; \
+ (plugin = *output_plugin_iterator) != NULL; ++output_plugin_iterator)
#endif
diff --git a/src/output_thread.c b/src/output_thread.c
index 02c315af9..4eef2ccdd 100644
--- a/src/output_thread.c
+++ b/src/output_thread.c
@@ -30,6 +30,7 @@
#include "filter/replay_gain_filter_plugin.h"
#include "mpd_error.h"
#include "notify.h"
+#include "gcc.h"
#include <glib.h>
@@ -441,6 +442,10 @@ ao_play_chunk(struct audio_output *ao, const struct music_chunk *chunk)
}
size_t size;
+#if GCC_CHECK_VERSION(4,7)
+ /* workaround -Wmaybe-uninitialized false positive */
+ size = 0;
+#endif
const char *data = ao_filter_chunk(ao, chunk, &size);
if (data == NULL) {
ao_close(ao, false);
diff --git a/src/playlist_list.c b/src/playlist_list.c
index 64f03d46d..3d4edb9e1 100644
--- a/src/playlist_list.c
+++ b/src/playlist_list.c
@@ -42,7 +42,7 @@
#include <string.h>
#include <stdio.h>
-static const struct playlist_plugin *const playlist_plugins[] = {
+const struct playlist_plugin *const playlist_plugins[] = {
&extm3u_playlist_plugin,
&m3u_playlist_plugin,
&xspf_playlist_plugin,
@@ -66,6 +66,10 @@ static const struct playlist_plugin *const playlist_plugins[] = {
/** which plugins have been initialized successfully? */
static bool playlist_plugins_enabled[G_N_ELEMENTS(playlist_plugins)];
+#define playlist_plugins_for_each_enabled(plugin) \
+ playlist_plugins_for_each(plugin) \
+ if (playlist_plugins_enabled[playlist_plugin_iterator - playlist_plugins])
+
/**
* Find the "playlist" configuration block for the specified plugin.
*
@@ -113,9 +117,8 @@ playlist_list_global_init(void)
void
playlist_list_global_finish(void)
{
- for (unsigned i = 0; playlist_plugins[i] != NULL; ++i)
- if (playlist_plugins_enabled[i])
- playlist_plugin_finish(playlist_plugins[i]);
+ playlist_plugins_for_each_enabled(plugin)
+ playlist_plugin_finish(plugin);
}
static struct playlist_provider *
@@ -209,11 +212,8 @@ playlist_list_open_stream_mime2(struct input_stream *is, const char *mime)
assert(is != NULL);
assert(mime != NULL);
- for (unsigned i = 0; playlist_plugins[i] != NULL; ++i) {
- const struct playlist_plugin *plugin = playlist_plugins[i];
-
- if (playlist_plugins_enabled[i] &&
- plugin->open_stream != NULL &&
+ playlist_plugins_for_each_enabled(plugin) {
+ if (plugin->open_stream != NULL &&
plugin->mime_types != NULL &&
string_array_contains(plugin->mime_types, mime)) {
/* rewind the stream, so each plugin gets a
@@ -257,11 +257,8 @@ playlist_list_open_stream_suffix(struct input_stream *is, const char *suffix)
assert(is != NULL);
assert(suffix != NULL);
- for (unsigned i = 0; playlist_plugins[i] != NULL; ++i) {
- const struct playlist_plugin *plugin = playlist_plugins[i];
-
- if (playlist_plugins_enabled[i] &&
- plugin->open_stream != NULL &&
+ playlist_plugins_for_each_enabled(plugin) {
+ if (plugin->open_stream != NULL &&
plugin->suffixes != NULL &&
string_array_contains(plugin->suffixes, suffix)) {
/* rewind the stream, so each plugin gets a
@@ -306,10 +303,8 @@ playlist_suffix_supported(const char *suffix)
{
assert(suffix != NULL);
- for (unsigned i = 0; playlist_plugins[i] != NULL; ++i) {
- const struct playlist_plugin *plugin = playlist_plugins[i];
-
- if (playlist_plugins_enabled[i] && plugin->suffixes != NULL &&
+ playlist_plugins_for_each_enabled(plugin) {
+ if (plugin->suffixes != NULL &&
string_array_contains(plugin->suffixes, suffix))
return true;
}
diff --git a/src/playlist_list.h b/src/playlist_list.h
index 4a2485303..c3967d5ae 100644
--- a/src/playlist_list.h
+++ b/src/playlist_list.h
@@ -27,6 +27,14 @@
struct playlist_provider;
struct input_stream;
+extern const struct playlist_plugin *const playlist_plugins[];
+
+#define playlist_plugins_for_each(plugin) \
+ for (const struct playlist_plugin *plugin, \
+ *const*playlist_plugin_iterator = &playlist_plugins[0]; \
+ (plugin = *playlist_plugin_iterator) != NULL; \
+ ++playlist_plugin_iterator)
+
/**
* Initializes all playlist plugins.
*/
diff --git a/src/playlist_save.c b/src/playlist_save.c
index 6571e286c..122eca332 100644
--- a/src/playlist_save.c
+++ b/src/playlist_save.c
@@ -28,6 +28,7 @@
#include "uri.h"
#include "database.h"
#include "idle.h"
+#include "glib_compat.h"
#include <glib.h>
diff --git a/src/update_walk.c b/src/update_walk.c
index 9ca9115bd..3ee35b2aa 100644
--- a/src/update_walk.c
+++ b/src/update_walk.c
@@ -33,6 +33,7 @@
#include "decoder_list.h"
#include "decoder_plugin.h"
#include "playlist_list.h"
+#include "glib_compat.h"
#include "conf.h"
#include "tag.h"
#include "tag_handler.h"
diff --git a/valgrind.suppressions b/valgrind.suppressions
index a6ffa13c9..939ae6c18 100644
--- a/valgrind.suppressions
+++ b/valgrind.suppressions
@@ -33,23 +33,36 @@
{
g_main_loop_run
Memcheck:Leak
- fun:malloc
- fun:g_malloc
- fun:g_main_context_iterate
+ fun:*alloc
+ ...
+ fun:g_main_context_iterate*
fun:g_main_loop_run
}
{
- g_main_loop_run
+ g_log
Memcheck:Leak
- fun:malloc
- fun:realloc
- fun:g_realloc
- fun:g_ptr_array_maybe_expand
- fun:g_ptr_array_add
- fun:g_main_context_check
- fun:g_main_context_iterate
- fun:g_main_loop_run
+ fun:*alloc
+ ...
+ fun:g_mutex_lock
+ fun:g_log_set_default_handler
+}
+
+{
+ g_mutex
+ Memcheck:Leak
+ fun:*alloc
+ ...
+ fun:thread_memory_from_self*
+ fun:g_slice_*
+}
+
+{
+ g_private
+ Memcheck:Leak
+ fun:*alloc
+ ...
+ fun:g_private_?et
}
{
@@ -117,6 +130,25 @@
}
{
+ g_thread_self
+ Memcheck:Leak
+ fun:*alloc
+ ...
+ fun:g_slice_*
+ fun:g_thread_self
+}
+
+{
+ g_thread_create
+ Memcheck:Leak
+ fun:*alloc
+ ...
+ fun:g_mutex_lock
+ ...
+ fun:g_thread_create
+}
+
+{
g_slice_init_nomessage
Memcheck:Leak
fun:calloc