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/??/??)
* decoder:
- ffmpeg: support WebM
* improve --version output
* WIN32: fix renaming of stored playlists with non-ASCII names
ver 0.16.8 (2012/04/04)

View File

@ -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,55 +44,34 @@ 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);
}
void archive_plugin_init_all(void)
{
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)
{
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();
}

View File

@ -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);

View File

@ -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;

View File

@ -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:");
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"
"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);

View File

@ -20,6 +20,7 @@
#include "config.h"
#include "decoder_api.h"
#include "tag_handler.h"
#include "glib_compat.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 *
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_plugins_for_each_enabled(plugin)
decoder_plugin_finish(plugin);
}
}

View File

@ -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 */
/**

View File

@ -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);
}

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 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);
}

View File

@ -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

View File

@ -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

View File

@ -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();
}

View File

@ -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

View File

@ -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);

View File

@ -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");

View File

@ -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;

View File

@ -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);
}

View File

@ -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

View File

@ -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);

View File

@ -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;
}

View File

@ -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.
*/

View File

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

View File

@ -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"

View File

@ -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
}
{
@ -116,6 +129,25 @@
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
Memcheck:Leak