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
This commit is contained in:
Max Kellermann 2012-06-12 23:22:03 +02:00
commit 4eb57e1e9a
25 changed files with 239 additions and 175 deletions

2
NEWS
View File

@ -43,6 +43,8 @@ ver 0.17 (2011/??/??)
ver 0.16.9 (2012/??/??) ver 0.16.9 (2012/??/??)
* decoder: * decoder:
- ffmpeg: support WebM - ffmpeg: support WebM
* improve --version output
* WIN32: fix renaming of stored playlists with non-ASCII names
ver 0.16.8 (2012/04/04) ver 0.16.8 (2012/04/04)

View File

@ -28,7 +28,7 @@
#include <string.h> #include <string.h>
#include <glib.h> #include <glib.h>
static const struct archive_plugin *const archive_plugins[] = { const struct archive_plugin *const archive_plugins[] = {
#ifdef HAVE_BZ2 #ifdef HAVE_BZ2
&bz2_archive_plugin, &bz2_archive_plugin,
#endif #endif
@ -44,55 +44,34 @@ static const struct archive_plugin *const archive_plugins[] = {
/** which plugins have been initialized successfully? */ /** which plugins have been initialized successfully? */
static bool archive_plugins_enabled[G_N_ELEMENTS(archive_plugins) - 1]; 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 * const struct archive_plugin *
archive_plugin_from_suffix(const char *suffix) archive_plugin_from_suffix(const char *suffix)
{ {
if (suffix == NULL) if (suffix == NULL)
return NULL; return NULL;
for (unsigned i = 0; archive_plugins[i] != NULL; ++i) { archive_plugins_for_each_enabled(plugin)
const struct archive_plugin *plugin = archive_plugins[i]; if (plugin->suffixes != NULL &&
if (archive_plugins_enabled[i] && string_array_contains(plugin->suffixes, suffix))
plugin->suffixes != NULL &&
string_array_contains(plugin->suffixes, suffix)) {
++i;
return plugin; return plugin;
}
}
return NULL; return NULL;
} }
const struct archive_plugin * const struct archive_plugin *
archive_plugin_from_name(const char *name) archive_plugin_from_name(const char *name)
{ {
for (unsigned i = 0; archive_plugins[i] != NULL; ++i) { archive_plugins_for_each_enabled(plugin)
const struct archive_plugin *plugin = archive_plugins[i]; if (strcmp(plugin->name, name) == 0)
if (archive_plugins_enabled[i] &&
strcmp(plugin->name, name) == 0)
return plugin; return plugin;
}
return NULL; 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);
}
void archive_plugin_init_all(void) void archive_plugin_init_all(void)
{ {
for (unsigned i = 0; archive_plugins[i] != NULL; ++i) { for (unsigned i = 0; archive_plugins[i] != NULL; ++i) {
@ -104,10 +83,8 @@ void archive_plugin_init_all(void)
void archive_plugin_deinit_all(void) void archive_plugin_deinit_all(void)
{ {
for (unsigned i = 0; archive_plugins[i] != NULL; ++i) { archive_plugins_for_each_enabled(plugin)
const struct archive_plugin *plugin = archive_plugins[i]; if (plugin->finish != NULL)
if (archive_plugins_enabled[i] && plugin->finish != NULL) plugin->finish();
archive_plugins[i]->finish();
}
} }

View File

@ -20,10 +20,16 @@
#ifndef MPD_ARCHIVE_LIST_H #ifndef MPD_ARCHIVE_LIST_H
#define MPD_ARCHIVE_LIST_H #define MPD_ARCHIVE_LIST_H
#include <stdio.h>
struct archive_plugin; 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 */ /* interface for using plugins */
const struct archive_plugin * const struct archive_plugin *
@ -32,8 +38,6 @@ archive_plugin_from_suffix(const char *suffix);
const struct archive_plugin * const struct archive_plugin *
archive_plugin_from_name(const char *name); archive_plugin_from_name(const char *name);
void archive_plugin_print_all_suffixes(FILE * fp);
/* this is where we "load" all the "plugins" ;-) */ /* this is where we "load" all the "plugins" ;-) */
void archive_plugin_init_all(void); void archive_plugin_init_all(void);

View File

@ -26,6 +26,7 @@
#include "audio_parser.h" #include "audio_parser.h"
#include "audio_format.h" #include "audio_format.h"
#include "audio_check.h" #include "audio_check.h"
#include "gcc.h"
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
@ -172,6 +173,11 @@ audio_format_parse(struct audio_format *dest, const char *src,
/* parse sample rate */ /* 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)) if (!parse_sample_rate(src, mask, &rate, &src, error_r))
return false; return false;
@ -183,6 +189,11 @@ audio_format_parse(struct audio_format *dest, const char *src,
/* parse sample format */ /* 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)) if (!parse_sample_format(src, mask, &sample_format, &src, error_r))
return false; return false;

View File

@ -25,15 +25,23 @@
#include "decoder_list.h" #include "decoder_list.h"
#include "decoder_plugin.h" #include "decoder_plugin.h"
#include "output_list.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 "ls.h"
#include "mpd_error.h" #include "mpd_error.h"
#include "glib_compat.h"
#ifdef ENABLE_ENCODER #ifdef ENABLE_ENCODER
#include "encoder_list.h" #include "encoder_list.h"
#include "encoder_plugin.h"
#endif #endif
#ifdef ENABLE_ARCHIVE #ifdef ENABLE_ARCHIVE
#include "archive_list.h" #include "archive_list.h"
#include "archive_plugin.h"
#endif #endif
#include <glib.h> #include <glib.h>
@ -54,59 +62,70 @@ cmdline_quark(void)
return g_quark_from_static_string("cmdline"); 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 G_GNUC_NORETURN
static void version(void) static void version(void)
{ {
puts(PACKAGE " (MPD: Music Player Daemon) " VERSION " \n" puts(PACKAGE " (MPD: Music Player Daemon) " VERSION " \n"
"\n" "\n"
"Copyright (C) 2003-2007 Warren Dukes <warren.dukes@gmail.com>\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" "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" "warranty; not even MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
"\n" "\n"
"Supported decoders:\n"); "Decoders plugins:");
print_all_decoders(stdout); decoder_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("");
}
puts("\n" puts("\n"
"Supported outputs:\n"); "Output plugins:");
audio_output_plugin_print_all_types(stdout); audio_output_plugins_for_each(plugin)
printf(" %s", plugin->name);
puts("");
#ifdef ENABLE_ENCODER #ifdef ENABLE_ENCODER
puts("\n" puts("\n"
"Supported encoders:\n"); "Encoder plugins:");
encoder_plugin_print_all_types(stdout); encoder_plugins_for_each(plugin)
printf(" %s", plugin->name);
puts("");
#endif #endif
#ifdef ENABLE_ARCHIVE #ifdef ENABLE_ARCHIVE
puts("\n" puts("\n"
"Supported archives:\n"); "Archive plugins:");
archive_plugin_init_all(); archive_plugins_for_each(plugin) {
archive_plugin_print_all_suffixes(stdout); printf(" [%s]", plugin->name);
const char *const*suffixes = plugin->suffixes;
if (suffixes != NULL)
for (; *suffixes != NULL; ++suffixes)
printf(" %s", *suffixes);
puts("");
}
#endif #endif
puts("\n" 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); print_supported_uri_schemes_to_fp(stdout);
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);

View File

@ -20,6 +20,7 @@
#include "config.h" #include "config.h"
#include "decoder_api.h" #include "decoder_api.h"
#include "tag_handler.h" #include "tag_handler.h"
#include "glib_compat.h"
#include <glib.h> #include <glib.h>

View File

@ -178,12 +178,9 @@ decoder_plugin_from_mime_type(const char *mimeType, unsigned int next)
const struct decoder_plugin * const struct decoder_plugin *
decoder_plugin_from_name(const char *name) decoder_plugin_from_name(const char *name)
{ {
for (unsigned i = 0; decoder_plugins[i] != NULL; ++i) { decoder_plugins_for_each_enabled(plugin)
const struct decoder_plugin *plugin = decoder_plugins[i]; if (strcmp(plugin->name, name) == 0)
if (decoder_plugins_enabled[i] &&
strcmp(plugin->name, name) == 0)
return plugin; return plugin;
}
return NULL; return NULL;
} }
@ -231,10 +228,6 @@ void decoder_plugin_init_all(void)
void decoder_plugin_deinit_all(void) void decoder_plugin_deinit_all(void)
{ {
for (unsigned i = 0; decoder_plugins[i] != NULL; ++i) { decoder_plugins_for_each_enabled(plugin)
const struct decoder_plugin *plugin = decoder_plugins[i]; decoder_plugin_finish(plugin);
if (decoder_plugins_enabled[i])
decoder_plugin_finish(plugin);
}
} }

View File

@ -27,6 +27,16 @@ struct decoder_plugin;
extern const struct decoder_plugin *const decoder_plugins[]; extern const struct decoder_plugin *const decoder_plugins[];
extern bool decoder_plugins_enabled[]; 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 */ /* interface for using plugins */
/** /**

View File

@ -48,7 +48,6 @@ decoder_plugin_print(struct client *client,
void void
decoder_list_print(struct client *client) decoder_list_print(struct client *client)
{ {
for (unsigned i = 0; decoder_plugins[i] != NULL; ++i) decoder_plugins_for_each_enabled(plugin)
if (decoder_plugins_enabled[i]) decoder_plugin_print(client, plugin);
decoder_plugin_print(client, decoder_plugins[i]);
} }

View File

@ -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 wave_encoder_plugin;
extern const struct encoder_plugin flac_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, &null_encoder_plugin,
#ifdef ENABLE_VORBIS_ENCODER #ifdef ENABLE_VORBIS_ENCODER
&vorbis_encoder_plugin, &vorbis_encoder_plugin,
@ -53,19 +53,9 @@ static const struct encoder_plugin *encoder_plugins[] = {
const struct encoder_plugin * const struct encoder_plugin *
encoder_plugin_get(const char *name) encoder_plugin_get(const char *name)
{ {
for (unsigned i = 0; encoder_plugins[i] != NULL; ++i) encoder_plugins_for_each(plugin)
if (strcmp(encoder_plugins[i]->name, name) == 0) if (strcmp(plugin->name, name) == 0)
return encoder_plugins[i]; return plugin;
return NULL; 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);
}

View File

@ -20,10 +20,16 @@
#ifndef MPD_ENCODER_LIST_H #ifndef MPD_ENCODER_LIST_H
#define MPD_ENCODER_LIST_H #define MPD_ENCODER_LIST_H
#include <stdio.h>
struct encoder_plugin; 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. * Looks up an encoder plugin by its name.
* *
@ -34,7 +40,4 @@ struct encoder_plugin;
const struct encoder_plugin * const struct encoder_plugin *
encoder_plugin_get(const char *name); encoder_plugin_get(const char *name);
void
encoder_plugin_print_all_types(FILE * fp);
#endif #endif

View File

@ -109,4 +109,32 @@ g_source_get_time(GSource *source)
#endif #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 #endif

View File

@ -99,8 +99,7 @@ input_stream_global_init(GError **error_r)
void input_stream_global_finish(void) void input_stream_global_finish(void)
{ {
for (unsigned i = 0; input_plugins[i] != NULL; ++i) input_plugins_for_each_enabled(plugin)
if (input_plugins_enabled[i] && if (plugin->finish != NULL)
input_plugins[i]->finish != NULL) plugin->finish();
input_plugins[i]->finish();
} }

View File

@ -32,4 +32,14 @@ extern const struct input_plugin *const input_plugins[];
extern bool input_plugins_enabled[]; 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 #endif

View File

@ -42,13 +42,9 @@ input_stream_open(const char *url,
assert(mutex != NULL); assert(mutex != NULL);
assert(error_r == NULL || *error_r == NULL); assert(error_r == NULL || *error_r == NULL);
for (unsigned i = 0; input_plugins[i] != NULL; ++i) { input_plugins_for_each_enabled(plugin) {
const struct input_plugin *plugin = input_plugins[i];
struct input_stream *is; struct input_stream *is;
if (!input_plugins_enabled[i])
continue;
is = plugin->open(url, mutex, cond, &error); is = plugin->open(url, mutex, cond, &error);
if (is != NULL) { if (is != NULL) {
assert(is->plugin != NULL); assert(is->plugin != NULL);

View File

@ -63,10 +63,10 @@ void print_supported_uri_schemes_to_fp(FILE *fp)
const char **prefixes = remoteUrlPrefixes; const char **prefixes = remoteUrlPrefixes;
#ifdef HAVE_UN #ifdef HAVE_UN
fprintf(fp, "file:// "); fprintf(fp, " file://");
#endif #endif
while (*prefixes) { while (*prefixes) {
fprintf(fp, "%s ", *prefixes); fprintf(fp, " %s", *prefixes);
prefixes++; prefixes++;
} }
fprintf(fp,"\n"); fprintf(fp,"\n");

View File

@ -49,12 +49,9 @@
static const struct audio_output_plugin * static const struct audio_output_plugin *
audio_output_detect(GError **error) audio_output_detect(GError **error)
{ {
const struct audio_output_plugin *plugin;
unsigned i;
g_warning("Attempt to detect audio output device"); 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) if (plugin->test_default_device == NULL)
continue; continue;

View File

@ -39,7 +39,7 @@
#include "output/solaris_output_plugin.h" #include "output/solaris_output_plugin.h"
#include "output/winmm_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 #ifdef HAVE_SHOUT
&shout_output_plugin, &shout_output_plugin,
#endif #endif
@ -98,24 +98,9 @@ const struct audio_output_plugin *audio_output_plugins[] = {
const struct audio_output_plugin * const struct audio_output_plugin *
audio_output_plugin_get(const char *name) audio_output_plugin_get(const char *name)
{ {
unsigned int i; audio_output_plugins_for_each(plugin)
const struct audio_output_plugin *plugin;
audio_output_plugins_for_each(plugin, i)
if (strcmp(plugin->name, name) == 0) if (strcmp(plugin->name, name) == 0)
return plugin; return plugin;
return NULL; 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);
}

View File

@ -20,16 +20,14 @@
#ifndef MPD_OUTPUT_LIST_H #ifndef MPD_OUTPUT_LIST_H
#define MPD_OUTPUT_LIST_H #define MPD_OUTPUT_LIST_H
#include <stdio.h> extern const struct audio_output_plugin *const audio_output_plugins[];
extern const struct audio_output_plugin *audio_output_plugins[];
const struct audio_output_plugin * const struct audio_output_plugin *
audio_output_plugin_get(const char *name); audio_output_plugin_get(const char *name);
void audio_output_plugin_print_all_types(FILE * fp); #define audio_output_plugins_for_each(plugin) \
for (const struct audio_output_plugin *plugin, \
#define audio_output_plugins_for_each(plugin, i) \ *const*output_plugin_iterator = &audio_output_plugins[0]; \
for (i = 0; (plugin = audio_output_plugins[i]) != NULL; ++i) (plugin = *output_plugin_iterator) != NULL; ++output_plugin_iterator)
#endif #endif

View File

@ -30,6 +30,7 @@
#include "filter/replay_gain_filter_plugin.h" #include "filter/replay_gain_filter_plugin.h"
#include "mpd_error.h" #include "mpd_error.h"
#include "notify.h" #include "notify.h"
#include "gcc.h"
#include <glib.h> #include <glib.h>
@ -441,6 +442,10 @@ ao_play_chunk(struct audio_output *ao, const struct music_chunk *chunk)
} }
size_t size; 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); const char *data = ao_filter_chunk(ao, chunk, &size);
if (data == NULL) { if (data == NULL) {
ao_close(ao, false); ao_close(ao, false);

View File

@ -42,7 +42,7 @@
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
static const struct playlist_plugin *const playlist_plugins[] = { const struct playlist_plugin *const playlist_plugins[] = {
&extm3u_playlist_plugin, &extm3u_playlist_plugin,
&m3u_playlist_plugin, &m3u_playlist_plugin,
&xspf_playlist_plugin, &xspf_playlist_plugin,
@ -66,6 +66,10 @@ static const struct playlist_plugin *const playlist_plugins[] = {
/** which plugins have been initialized successfully? */ /** which plugins have been initialized successfully? */
static bool playlist_plugins_enabled[G_N_ELEMENTS(playlist_plugins)]; 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. * Find the "playlist" configuration block for the specified plugin.
* *
@ -113,9 +117,8 @@ playlist_list_global_init(void)
void void
playlist_list_global_finish(void) playlist_list_global_finish(void)
{ {
for (unsigned i = 0; playlist_plugins[i] != NULL; ++i) playlist_plugins_for_each_enabled(plugin)
if (playlist_plugins_enabled[i]) playlist_plugin_finish(plugin);
playlist_plugin_finish(playlist_plugins[i]);
} }
static struct playlist_provider * static struct playlist_provider *
@ -209,11 +212,8 @@ playlist_list_open_stream_mime2(struct input_stream *is, const char *mime)
assert(is != NULL); assert(is != NULL);
assert(mime != NULL); assert(mime != NULL);
for (unsigned i = 0; playlist_plugins[i] != NULL; ++i) { playlist_plugins_for_each_enabled(plugin) {
const struct playlist_plugin *plugin = playlist_plugins[i]; if (plugin->open_stream != NULL &&
if (playlist_plugins_enabled[i] &&
plugin->open_stream != NULL &&
plugin->mime_types != NULL && plugin->mime_types != NULL &&
string_array_contains(plugin->mime_types, mime)) { string_array_contains(plugin->mime_types, mime)) {
/* rewind the stream, so each plugin gets a /* 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(is != NULL);
assert(suffix != NULL); assert(suffix != NULL);
for (unsigned i = 0; playlist_plugins[i] != NULL; ++i) { playlist_plugins_for_each_enabled(plugin) {
const struct playlist_plugin *plugin = playlist_plugins[i]; if (plugin->open_stream != NULL &&
if (playlist_plugins_enabled[i] &&
plugin->open_stream != NULL &&
plugin->suffixes != NULL && plugin->suffixes != NULL &&
string_array_contains(plugin->suffixes, suffix)) { string_array_contains(plugin->suffixes, suffix)) {
/* rewind the stream, so each plugin gets a /* rewind the stream, so each plugin gets a
@ -306,10 +303,8 @@ playlist_suffix_supported(const char *suffix)
{ {
assert(suffix != NULL); assert(suffix != NULL);
for (unsigned i = 0; playlist_plugins[i] != NULL; ++i) { playlist_plugins_for_each_enabled(plugin) {
const struct playlist_plugin *plugin = playlist_plugins[i]; if (plugin->suffixes != NULL &&
if (playlist_plugins_enabled[i] && plugin->suffixes != NULL &&
string_array_contains(plugin->suffixes, suffix)) string_array_contains(plugin->suffixes, suffix))
return true; return true;
} }

View File

@ -27,6 +27,14 @@
struct playlist_provider; struct playlist_provider;
struct input_stream; 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. * Initializes all playlist plugins.
*/ */

View File

@ -28,6 +28,7 @@
#include "uri.h" #include "uri.h"
#include "database.h" #include "database.h"
#include "idle.h" #include "idle.h"
#include "glib_compat.h"
#include <glib.h> #include <glib.h>

View File

@ -33,6 +33,7 @@
#include "decoder_list.h" #include "decoder_list.h"
#include "decoder_plugin.h" #include "decoder_plugin.h"
#include "playlist_list.h" #include "playlist_list.h"
#include "glib_compat.h"
#include "conf.h" #include "conf.h"
#include "tag.h" #include "tag.h"
#include "tag_handler.h" #include "tag_handler.h"

View File

@ -33,23 +33,36 @@
{ {
g_main_loop_run g_main_loop_run
Memcheck:Leak Memcheck:Leak
fun:malloc fun:*alloc
fun:g_malloc ...
fun:g_main_context_iterate fun:g_main_context_iterate*
fun:g_main_loop_run fun:g_main_loop_run
} }
{ {
g_main_loop_run g_log
Memcheck:Leak Memcheck:Leak
fun:malloc fun:*alloc
fun:realloc ...
fun:g_realloc fun:g_mutex_lock
fun:g_ptr_array_maybe_expand fun:g_log_set_default_handler
fun:g_ptr_array_add }
fun:g_main_context_check
fun:g_main_context_iterate {
fun:g_main_loop_run g_mutex
Memcheck:Leak
fun:*alloc
...
fun:thread_memory_from_self*
fun:g_slice_*
}
{
g_private
Memcheck:Leak
fun:*alloc
...
fun:g_private_?et
} }
{ {
@ -116,6 +129,25 @@
fun:g_thread_init_glib fun:g_thread_init_glib
} }
{
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 g_slice_init_nomessage
Memcheck:Leak Memcheck:Leak