config/Param: split block-specific attributes to new struct ConfigBlock

The old struct config_param remains only for top-level string options.
This commit is contained in:
Max Kellermann 2015-01-21 22:13:44 +01:00
parent 84e74173de
commit 4fa5538e2b
114 changed files with 871 additions and 732 deletions

View File

@ -20,8 +20,12 @@
#include "config.h" #include "config.h"
#include "Block.hxx" #include "Block.hxx"
#include "ConfigParser.hxx" #include "ConfigParser.hxx"
#include "ConfigPath.hxx"
#include "system/FatalError.hxx" #include "system/FatalError.hxx"
#include "fs/AllocatedPath.hxx"
#include "util/Error.hxx"
#include <assert.h>
#include <stdlib.h> #include <stdlib.h>
int int
@ -57,3 +61,96 @@ BlockParam::GetBoolValue() const
return value2; return value2;
} }
ConfigBlock::~ConfigBlock()
{
delete next;
}
const BlockParam *
ConfigBlock::GetBlockParam(const char *name) const
{
for (const auto &i : block_params) {
if (i.name == name) {
i.used = true;
return &i;
}
}
return nullptr;
}
const char *
ConfigBlock::GetBlockValue(const char *name, const char *default_value) const
{
const BlockParam *bp = GetBlockParam(name);
if (bp == nullptr)
return default_value;
return bp->value.c_str();
}
AllocatedPath
ConfigBlock::GetBlockPath(const char *name, const char *default_value,
Error &error) const
{
assert(!error.IsDefined());
int line2 = line;
const char *s;
const BlockParam *bp = GetBlockParam(name);
if (bp != nullptr) {
line2 = bp->line;
s = bp->value.c_str();
} else {
if (default_value == nullptr)
return AllocatedPath::Null();
s = default_value;
}
AllocatedPath path = ParsePath(s, error);
if (gcc_unlikely(path.IsNull()))
error.FormatPrefix("Invalid path in \"%s\" at line %i: ",
name, line2);
return path;
}
AllocatedPath
ConfigBlock::GetBlockPath(const char *name, Error &error) const
{
return GetBlockPath(name, nullptr, error);
}
int
ConfigBlock::GetBlockValue(const char *name, int default_value) const
{
const BlockParam *bp = GetBlockParam(name);
if (bp == nullptr)
return default_value;
return bp->GetIntValue();
}
unsigned
ConfigBlock::GetBlockValue(const char *name, unsigned default_value) const
{
const BlockParam *bp = GetBlockParam(name);
if (bp == nullptr)
return default_value;
return bp->GetUnsignedValue();
}
gcc_pure
bool
ConfigBlock::GetBlockValue(const char *name, bool default_value) const
{
const BlockParam *bp = GetBlockParam(name);
if (bp == nullptr)
return default_value;
return bp->GetBoolValue();
}

View File

@ -21,9 +21,14 @@
#define MPD_CONFIG_BLOCK_HXX #define MPD_CONFIG_BLOCK_HXX
#include "check.h" #include "check.h"
#include "Param.hxx"
#include "Compiler.h" #include "Compiler.h"
#include <string> #include <string>
#include <vector>
class Error;
class AllocatedPath;
struct BlockParam { struct BlockParam {
std::string name; std::string name;
@ -50,4 +55,71 @@ struct BlockParam {
bool GetBoolValue() const; bool GetBoolValue() const;
}; };
struct ConfigBlock {
/**
* The next #ConfigBlock with the same name. The destructor
* deletes the whole chain.
*/
ConfigBlock *next;
int line;
std::vector<BlockParam> block_params;
/**
* This flag is false when nobody has queried the value of
* this option yet.
*/
bool used;
explicit ConfigBlock(int _line=-1)
:next(nullptr), line(_line), used(false) {}
ConfigBlock(const ConfigBlock &) = delete;
~ConfigBlock();
ConfigBlock &operator=(const ConfigBlock &) = delete;
/**
* Determine if this is a "null" instance, i.e. an empty
* object that was synthesized and not loaded from a
* configuration file.
*/
bool IsNull() const {
return line < 0;
}
gcc_nonnull_all
void AddBlockParam(const char *_name, const char *_value,
int _line=-1) {
block_params.emplace_back(_name, _value, _line);
}
gcc_nonnull_all gcc_pure
const BlockParam *GetBlockParam(const char *_name) const;
gcc_pure
const char *GetBlockValue(const char *name,
const char *default_value=nullptr) const;
/**
* Same as config_get_path(), but looks up the setting in the
* specified block.
*/
AllocatedPath GetBlockPath(const char *name, const char *default_value,
Error &error) const;
AllocatedPath GetBlockPath(const char *name, Error &error) const;
gcc_pure
int GetBlockValue(const char *name, int default_value) const;
gcc_pure
unsigned GetBlockValue(const char *name, unsigned default_value) const;
gcc_pure
bool GetBlockValue(const char *name, bool default_value) const;
};
#endif #endif

View File

@ -21,6 +21,7 @@
#include "ConfigFile.hxx" #include "ConfigFile.hxx"
#include "Data.hxx" #include "Data.hxx"
#include "Param.hxx" #include "Param.hxx"
#include "Block.hxx"
#include "ConfigTemplates.hxx" #include "ConfigTemplates.hxx"
#include "util/Tokenizer.hxx" #include "util/Tokenizer.hxx"
#include "util/StringUtil.hxx" #include "util/StringUtil.hxx"
@ -38,7 +39,7 @@ static constexpr char CONF_COMMENT = '#';
static constexpr Domain config_file_domain("config_file"); static constexpr Domain config_file_domain("config_file");
static bool static bool
config_read_name_value(struct config_param *param, char *input, unsigned line, config_read_name_value(ConfigBlock &block, char *input, unsigned line,
Error &error) Error &error)
{ {
Tokenizer tokenizer(input); Tokenizer tokenizer(input);
@ -65,7 +66,7 @@ config_read_name_value(struct config_param *param, char *input, unsigned line,
return false; return false;
} }
const BlockParam *bp = param->GetBlockParam(name); const BlockParam *bp = block.GetBlockParam(name);
if (bp != nullptr) { if (bp != nullptr) {
error.Format(config_file_domain, error.Format(config_file_domain,
"\"%s\" is duplicate, first defined on line %i", "\"%s\" is duplicate, first defined on line %i",
@ -73,14 +74,14 @@ config_read_name_value(struct config_param *param, char *input, unsigned line,
return false; return false;
} }
param->AddBlockParam(name, value, line); block.AddBlockParam(name, value, line);
return true; return true;
} }
static struct config_param * static ConfigBlock *
config_read_block(BufferedReader &reader, Error &error) config_read_block(BufferedReader &reader, Error &error)
{ {
struct config_param *ret = new config_param(reader.GetLineNumber()); auto *ret = new ConfigBlock(reader.GetLineNumber());
while (true) { while (true) {
char *line = reader.ReadLine(); char *line = reader.ReadLine();
@ -115,7 +116,7 @@ config_read_block(BufferedReader &reader, Error &error)
/* parse name and value */ /* parse name and value */
if (!config_read_name_value(ret, line, reader.GetLineNumber(), if (!config_read_name_value(*ret, line, reader.GetLineNumber(),
error)) { error)) {
assert(*line != 0); assert(*line != 0);
delete ret; delete ret;
@ -125,6 +126,64 @@ config_read_block(BufferedReader &reader, Error &error)
} }
} }
gcc_nonnull_all
static void
Append(ConfigBlock *&head, ConfigBlock *p)
{
assert(p->next == nullptr);
auto **i = &head;
while (*i != nullptr)
i = &(*i)->next;
*i = p;
}
static bool
ReadConfigBlock(ConfigData &config_data, BufferedReader &reader,
const char *name, ConfigOption o,
Tokenizer &tokenizer,
Error &error)
{
const unsigned i = unsigned(o);
const ConfigTemplate &option = config_block_templates[i];
ConfigBlock *&head = config_data.blocks[i];
if (head != nullptr && !option.repeatable) {
ConfigBlock *block = head;
error.Format(config_file_domain,
"config parameter \"%s\" is first defined "
"on line %d and redefined on line %u\n",
name, block->line,
reader.GetLineNumber());
return false;
}
/* now parse the block or the value */
if (tokenizer.CurrentChar() != '{') {
error.Format(config_file_domain,
"line %u: '{' expected",
reader.GetLineNumber());
return false;
}
char *line = StripLeft(tokenizer.Rest() + 1);
if (*line != 0 && *line != CONF_COMMENT) {
error.Format(config_file_domain,
"line %u: Unknown tokens after '{'",
reader.GetLineNumber());
return false;
}
auto *param = config_read_block(reader, error);
if (param == nullptr)
return false;
Append(head, param);
return true;
}
gcc_nonnull_all gcc_nonnull_all
static void static void
Append(config_param *&head, config_param *p) Append(config_param *&head, config_param *p)
@ -145,7 +204,7 @@ ReadConfigParam(ConfigData &config_data, BufferedReader &reader,
Error &error) Error &error)
{ {
const unsigned i = unsigned(o); const unsigned i = unsigned(o);
const ConfigTemplate &option = config_templates[i]; const ConfigTemplate &option = config_param_templates[i];
config_param *&head = config_data.params[i]; config_param *&head = config_data.params[i];
if (head != nullptr && !option.repeatable) { if (head != nullptr && !option.repeatable) {
@ -160,57 +219,28 @@ ReadConfigParam(ConfigData &config_data, BufferedReader &reader,
/* now parse the block or the value */ /* now parse the block or the value */
struct config_param *param; const char *value = tokenizer.NextString(error);
if (option.block) { if (value == nullptr) {
/* it's a block, call config_read_block() */ if (tokenizer.IsEnd())
if (tokenizer.CurrentChar() != '{') {
error.Format(config_file_domain, error.Format(config_file_domain,
"line %u: '{' expected", "line %u: Value missing",
reader.GetLineNumber()); reader.GetLineNumber());
return false; else
} error.FormatPrefix("line %u: ",
reader.GetLineNumber());
char *line = StripLeft(tokenizer.Rest() + 1); return false;
if (*line != 0 && *line != CONF_COMMENT) {
error.Format(config_file_domain,
"line %u: Unknown tokens after '{'",
reader.GetLineNumber());
return false;
}
param = config_read_block(reader, error);
if (param == nullptr) {
return false;
}
} else {
/* a string value */
const char *value = tokenizer.NextString(error);
if (value == nullptr) {
if (tokenizer.IsEnd())
error.Format(config_file_domain,
"line %u: Value missing",
reader.GetLineNumber());
else
error.FormatPrefix("line %u: ",
reader.GetLineNumber());
return false;
}
if (!tokenizer.IsEnd() &&
tokenizer.CurrentChar() != CONF_COMMENT) {
error.Format(config_file_domain,
"line %u: Unknown tokens after value",
reader.GetLineNumber());
return false;
}
param = new config_param(value,
reader.GetLineNumber());
} }
if (!tokenizer.IsEnd() &&
tokenizer.CurrentChar() != CONF_COMMENT) {
error.Format(config_file_domain,
"line %u: Unknown tokens after value",
reader.GetLineNumber());
return false;
}
auto *param = new config_param(value, reader.GetLineNumber());
Append(head, param); Append(head, param);
return true; return true;
} }
@ -242,10 +272,15 @@ ReadConfigFile(ConfigData &config_data, BufferedReader &reader, Error &error)
"repeatable" flag */ "repeatable" flag */
const ConfigOption o = ParseConfigOptionName(name); const ConfigOption o = ParseConfigOptionName(name);
ConfigBlockOption bo;
if (o != ConfigOption::MAX) { if (o != ConfigOption::MAX) {
if (!ReadConfigParam(config_data, reader, name, o, if (!ReadConfigParam(config_data, reader, name, o,
tokenizer, error)) tokenizer, error))
return false; return false;
} else if ((bo = ParseConfigBlockOptionName(name)) != ConfigBlockOption::MAX) {
if (!ReadConfigBlock(config_data, reader, name, o,
tokenizer, error))
return false;
} else { } else {
error.Format(config_file_domain, error.Format(config_file_domain,
"unrecognized parameter in config file at " "unrecognized parameter in config file at "

View File

@ -22,6 +22,7 @@
#include "ConfigParser.hxx" #include "ConfigParser.hxx"
#include "Data.hxx" #include "Data.hxx"
#include "Param.hxx" #include "Param.hxx"
#include "Block.hxx"
#include "ConfigFile.hxx" #include "ConfigFile.hxx"
#include "ConfigPath.hxx" #include "ConfigPath.hxx"
#include "ConfigError.hxx" #include "ConfigError.hxx"
@ -51,15 +52,15 @@ ReadConfigFile(Path path, Error &error)
} }
static void static void
Check(const config_param *param) Check(const ConfigBlock &block)
{ {
if (!param->used) if (!block.used)
/* this whole config_param was not queried at all - /* this whole block was not queried at all -
the feature might be disabled at compile time? the feature might be disabled at compile time?
Silently ignore it here. */ Silently ignore it here. */
return; return;
for (const auto &i : param->block_params) { for (const auto &i : block.block_params) {
if (!i.used) if (!i.used)
FormatWarning(config_domain, FormatWarning(config_domain,
"option '%s' on line %i was not recognized", "option '%s' on line %i was not recognized",
@ -69,9 +70,9 @@ Check(const config_param *param)
void config_global_check(void) void config_global_check(void)
{ {
for (auto i : config_data.params) for (auto i : config_data.blocks)
for (const config_param *p = i; p != nullptr; p = p->next) for (const auto *p = i; p != nullptr; p = p->next)
Check(p); Check(*p);
} }
const config_param * const config_param *
@ -83,18 +84,27 @@ config_get_param(ConfigOption option)
return param; return param;
} }
const config_param * const ConfigBlock *
config_find_block(ConfigOption option, const char *key, const char *value) config_get_block(ConfigBlockOption option)
{ {
for (const config_param *param = config_get_param(option); ConfigBlock *block = config_data.blocks[unsigned(option)];
param != nullptr; param = param->next) { if (block != nullptr)
const char *value2 = param->GetBlockValue(key); block->used = true;
return block;
}
const ConfigBlock *
config_find_block(ConfigBlockOption option, const char *key, const char *value)
{
for (const auto *block = config_get_block(option);
block != nullptr; block = block->next) {
const char *value2 = block->GetBlockValue(key);
if (value2 == nullptr) if (value2 == nullptr)
FormatFatalError("block without '%s' name in line %d", FormatFatalError("block without '%s' name in line %d",
key, param->line); key, block->line);
if (strcmp(value2, value) == 0) if (strcmp(value2, value) == 0)
return param; return block;
} }
return nullptr; return nullptr;

View File

@ -27,6 +27,7 @@ class Error;
class Path; class Path;
class AllocatedPath; class AllocatedPath;
struct config_param; struct config_param;
struct ConfigBlock;
void config_global_init(void); void config_global_init(void);
void config_global_finish(void); void config_global_finish(void);
@ -44,6 +45,10 @@ gcc_pure
const config_param * const config_param *
config_get_param(enum ConfigOption option); config_get_param(enum ConfigOption option);
gcc_pure
const ConfigBlock *
config_get_block(enum ConfigBlockOption option);
/** /**
* Find a block with a matching attribute. * Find a block with a matching attribute.
* *
@ -52,8 +57,8 @@ config_get_param(enum ConfigOption option);
* @param value the expected attribute value * @param value the expected attribute value
*/ */
gcc_pure gcc_pure
const config_param * const ConfigBlock *
config_find_block(ConfigOption option, const char *key, const char *value); config_find_block(ConfigBlockOption option, const char *key, const char *value);
/* Note on gcc_pure: Some of the functions declared pure are not /* Note on gcc_pure: Some of the functions declared pure are not
really pure in strict sense. They have side effect such that they really pure in strict sense. They have side effect such that they

View File

@ -49,7 +49,6 @@ enum class ConfigOption {
ZEROCONF_ENABLED, ZEROCONF_ENABLED,
PASSWORD, PASSWORD,
DEFAULT_PERMS, DEFAULT_PERMS,
AUDIO_OUTPUT,
AUDIO_OUTPUT_FORMAT, AUDIO_OUTPUT_FORMAT,
MIXER_TYPE, MIXER_TYPE,
REPLAYGAIN, REPLAYGAIN,
@ -73,15 +72,20 @@ enum class ConfigOption {
ID3V1_ENCODING, ID3V1_ENCODING,
METADATA_TO_USE, METADATA_TO_USE,
SAVE_ABSOLUTE_PATHS, SAVE_ABSOLUTE_PATHS,
DECODER,
INPUT,
GAPLESS_MP3_PLAYBACK, GAPLESS_MP3_PLAYBACK,
PLAYLIST_PLUGIN,
AUTO_UPDATE, AUTO_UPDATE,
AUTO_UPDATE_DEPTH, AUTO_UPDATE_DEPTH,
DESPOTIFY_USER, DESPOTIFY_USER,
DESPOTIFY_PASSWORD, DESPOTIFY_PASSWORD,
DESPOTIFY_HIGH_BITRATE, DESPOTIFY_HIGH_BITRATE,
MAX
};
enum class ConfigBlockOption {
AUDIO_OUTPUT,
DECODER,
INPUT,
PLAYLIST_PLUGIN,
AUDIO_FILTER, AUDIO_FILTER,
DATABASE, DATABASE,
NEIGHBORS, NEIGHBORS,
@ -99,4 +103,11 @@ gcc_pure
enum ConfigOption enum ConfigOption
ParseConfigOptionName(const char *name); ParseConfigOptionName(const char *name);
/**
* @return #ConfigOption::MAX if not found
*/
gcc_pure
enum ConfigBlockOption
ParseConfigBlockOptionName(const char *name);
#endif #endif

View File

@ -23,76 +23,105 @@
#include <string.h> #include <string.h>
const ConfigTemplate config_templates[] = { const ConfigTemplate config_param_templates[] = {
{ "music_directory", false, false }, { "music_directory", false },
{ "playlist_directory", false, false }, { "playlist_directory", false },
{ "follow_inside_symlinks", false, false }, { "follow_inside_symlinks", false },
{ "follow_outside_symlinks", false, false }, { "follow_outside_symlinks", false },
{ "db_file", false, false }, { "db_file", false },
{ "sticker_file", false, false }, { "sticker_file", false },
{ "log_file", false, false }, { "log_file", false },
{ "pid_file", false, false }, { "pid_file", false },
{ "state_file", false, false }, { "state_file", false },
{ "state_file_interval", false, false }, { "state_file_interval", false },
{ "restore_paused", false, false }, { "restore_paused", false },
{ "user", false, false }, { "user", false },
{ "group", false, false }, { "group", false },
{ "bind_to_address", true, false }, { "bind_to_address", true },
{ "port", false, false }, { "port", false },
{ "log_level", false, false }, { "log_level", false },
{ "zeroconf_name", false, false }, { "zeroconf_name", false },
{ "zeroconf_enabled", false, false }, { "zeroconf_enabled", false },
{ "password", true, false }, { "password", true },
{ "default_permissions", false, false }, { "default_permissions", false },
{ "audio_output", true, true }, { "audio_output_format", false },
{ "audio_output_format", false, false }, { "mixer_type", false },
{ "mixer_type", false, false }, { "replaygain", false },
{ "replaygain", false, false }, { "replaygain_preamp", false },
{ "replaygain_preamp", false, false }, { "replaygain_missing_preamp", false },
{ "replaygain_missing_preamp", false, false }, { "replaygain_limit", false },
{ "replaygain_limit", false, false }, { "volume_normalization", false },
{ "volume_normalization", false, false }, { "samplerate_converter", false },
{ "samplerate_converter", false, false }, { "audio_buffer_size", false },
{ "audio_buffer_size", false, false }, { "buffer_before_play", false },
{ "buffer_before_play", false, false }, { "http_proxy_host", false },
{ "http_proxy_host", false, false }, { "http_proxy_port", false },
{ "http_proxy_port", false, false }, { "http_proxy_user", false },
{ "http_proxy_user", false, false }, { "http_proxy_password", false },
{ "http_proxy_password", false, false }, { "connection_timeout", false },
{ "connection_timeout", false, false }, { "max_connections", false },
{ "max_connections", false, false }, { "max_playlist_length", false },
{ "max_playlist_length", false, false }, { "max_command_list_size", false },
{ "max_command_list_size", false, false }, { "max_output_buffer_size", false },
{ "max_output_buffer_size", false, false }, { "filesystem_charset", false },
{ "filesystem_charset", false, false }, { "id3v1_encoding", false },
{ "id3v1_encoding", false, false }, { "metadata_to_use", false },
{ "metadata_to_use", false, false }, { "save_absolute_paths_in_playlists", false },
{ "save_absolute_paths_in_playlists", false, false }, { "gapless_mp3_playback", false },
{ "decoder", true, true }, { "auto_update", false },
{ "input", true, true }, { "auto_update_depth", false },
{ "gapless_mp3_playback", false, false }, { "despotify_user", false },
{ "playlist_plugin", true, true }, { "despotify_password", false },
{ "auto_update", false, false }, { "despotify_high_bitrate", false },
{ "auto_update_depth", false, false },
{ "despotify_user", false, false },
{ "despotify_password", false, false},
{ "despotify_high_bitrate", false, false },
{ "filter", true, true },
{ "database", false, true },
{ "neighbors", true, true },
}; };
static constexpr unsigned n_config_templates = ARRAY_SIZE(config_templates); static constexpr unsigned n_config_param_templates =
ARRAY_SIZE(config_param_templates);
static_assert(n_config_templates == unsigned(ConfigOption::MAX), static_assert(n_config_param_templates == unsigned(ConfigOption::MAX),
"Wrong number of config_templates"); "Wrong number of config_param_templates");
const ConfigTemplate config_block_templates[] = {
{ "audio_output", true },
{ "decoder", true },
{ "input", true },
{ "playlist_plugin", true },
{ "filter", true },
{ "database", false },
{ "neighbors", true },
};
static constexpr unsigned n_config_block_templates =
ARRAY_SIZE(config_block_templates);
static_assert(n_config_block_templates == unsigned(ConfigBlockOption::MAX),
"Wrong number of config_block_templates");
gcc_pure
static inline unsigned
ParseConfigTemplateName(const ConfigTemplate templates[], unsigned count,
const char *name)
{
unsigned i = 0;
for (; i < count; ++i)
if (strcmp(templates[i].name, name) == 0)
break;
return i;
}
ConfigOption ConfigOption
ParseConfigOptionName(const char *name) ParseConfigOptionName(const char *name)
{ {
for (unsigned i = 0; i < n_config_templates; ++i) return ConfigOption(ParseConfigTemplateName(config_param_templates,
if (strcmp(config_templates[i].name, name) == 0) n_config_param_templates,
return ConfigOption(i); name));
}
return ConfigOption::MAX;
ConfigBlockOption
ParseConfigBlockOptionName(const char *name)
{
return ConfigBlockOption(ParseConfigTemplateName(config_block_templates,
n_config_block_templates,
name));
} }

View File

@ -23,9 +23,9 @@
struct ConfigTemplate { struct ConfigTemplate {
const char *const name; const char *const name;
const bool repeatable; const bool repeatable;
const bool block;
}; };
extern const ConfigTemplate config_templates[]; extern const ConfigTemplate config_param_templates[];
extern const ConfigTemplate config_block_templates[];
#endif #endif

View File

@ -20,6 +20,7 @@
#include "config.h" #include "config.h"
#include "Data.hxx" #include "Data.hxx"
#include "Param.hxx" #include "Param.hxx"
#include "Block.hxx"
void void
ConfigData::Clear() ConfigData::Clear()
@ -28,4 +29,9 @@ ConfigData::Clear()
delete i; delete i;
i = nullptr; i = nullptr;
} }
for (auto &i : blocks) {
delete i;
i = nullptr;
}
} }

View File

@ -25,9 +25,11 @@
#include <array> #include <array>
struct config_param; struct config_param;
struct ConfigBlock;
struct ConfigData { struct ConfigData {
std::array<config_param *, std::size_t(ConfigOption::MAX)> params; std::array<config_param *, std::size_t(ConfigOption::MAX)> params;
std::array<ConfigBlock *, std::size_t(ConfigBlockOption::MAX)> blocks;
void Clear(); void Clear();
}; };

View File

@ -19,12 +19,6 @@
#include "config.h" #include "config.h"
#include "Param.hxx" #include "Param.hxx"
#include "ConfigPath.hxx"
#include "util/Error.hxx"
#include "fs/AllocatedPath.hxx"
#include <assert.h>
#include <stdlib.h>
config_param::config_param(const char *_value, int _line) config_param::config_param(const char *_value, int _line)
:next(nullptr), value(_value), line(_line), used(false) {} :next(nullptr), value(_value), line(_line), used(false) {}
@ -33,91 +27,3 @@ config_param::~config_param()
{ {
delete next; delete next;
} }
const BlockParam *
config_param::GetBlockParam(const char *name) const
{
for (const auto &i : block_params) {
if (i.name == name) {
i.used = true;
return &i;
}
}
return nullptr;
}
const char *
config_param::GetBlockValue(const char *name, const char *default_value) const
{
const BlockParam *bp = GetBlockParam(name);
if (bp == nullptr)
return default_value;
return bp->value.c_str();
}
AllocatedPath
config_param::GetBlockPath(const char *name, const char *default_value,
Error &error) const
{
assert(!error.IsDefined());
int line2 = line;
const char *s;
const BlockParam *bp = GetBlockParam(name);
if (bp != nullptr) {
line2 = bp->line;
s = bp->value.c_str();
} else {
if (default_value == nullptr)
return AllocatedPath::Null();
s = default_value;
}
AllocatedPath path = ParsePath(s, error);
if (gcc_unlikely(path.IsNull()))
error.FormatPrefix("Invalid path in \"%s\" at line %i: ",
name, line2);
return path;
}
AllocatedPath
config_param::GetBlockPath(const char *name, Error &error) const
{
return GetBlockPath(name, nullptr, error);
}
int
config_param::GetBlockValue(const char *name, int default_value) const
{
const BlockParam *bp = GetBlockParam(name);
if (bp == nullptr)
return default_value;
return bp->GetIntValue();
}
unsigned
config_param::GetBlockValue(const char *name, unsigned default_value) const
{
const BlockParam *bp = GetBlockParam(name);
if (bp == nullptr)
return default_value;
return bp->GetUnsignedValue();
}
gcc_pure
bool
config_param::GetBlockValue(const char *name, bool default_value) const
{
const BlockParam *bp = GetBlockParam(name);
if (bp == nullptr)
return default_value;
return bp->GetBoolValue();
}

View File

@ -20,14 +20,10 @@
#ifndef MPD_CONFIG_PARAM_HXX #ifndef MPD_CONFIG_PARAM_HXX
#define MPD_CONFIG_PARAM_HXX #define MPD_CONFIG_PARAM_HXX
#include "Block.hxx" #include "check.h"
#include "Compiler.h" #include "Compiler.h"
#include <string> #include <string>
#include <vector>
class AllocatedPath;
class Error;
struct config_param { struct config_param {
/** /**
@ -40,8 +36,6 @@ struct config_param {
int line; int line;
std::vector<BlockParam> block_params;
/** /**
* This flag is false when nobody has queried the value of * This flag is false when nobody has queried the value of
* this option yet. * this option yet.
@ -68,37 +62,6 @@ struct config_param {
bool IsNull() const { bool IsNull() const {
return line < 0; return line < 0;
} }
gcc_nonnull_all
void AddBlockParam(const char *_name, const char *_value,
int _line=-1) {
block_params.emplace_back(_name, _value, _line);
}
gcc_nonnull_all gcc_pure
const BlockParam *GetBlockParam(const char *_name) const;
gcc_pure
const char *GetBlockValue(const char *name,
const char *default_value=nullptr) const;
/**
* Same as config_get_path(), but looks up the setting in the
* specified block.
*/
AllocatedPath GetBlockPath(const char *name, const char *default_value,
Error &error) const;
AllocatedPath GetBlockPath(const char *name, Error &error) const;
gcc_pure
int GetBlockValue(const char *name, int default_value) const;
gcc_pure
unsigned GetBlockValue(const char *name, unsigned default_value) const;
gcc_pure
bool GetBlockValue(const char *name, bool default_value) const;
}; };
#endif #endif

View File

@ -22,6 +22,7 @@
#include "DatabaseGlue.hxx" #include "DatabaseGlue.hxx"
#include "config/ConfigGlobal.hxx" #include "config/ConfigGlobal.hxx"
#include "config/Param.hxx" #include "config/Param.hxx"
#include "config/Block.hxx"
#include "config/ConfigError.hxx" #include "config/ConfigError.hxx"
#include "fs/AllocatedPath.hxx" #include "fs/AllocatedPath.hxx"
#include "fs/StandardDirectory.hxx" #include "fs/StandardDirectory.hxx"
@ -32,7 +33,7 @@ Database *
CreateConfiguredDatabase(EventLoop &loop, DatabaseListener &listener, CreateConfiguredDatabase(EventLoop &loop, DatabaseListener &listener,
Error &error) Error &error)
{ {
const auto *param = config_get_param(ConfigOption::DATABASE); const auto *param = config_get_block(ConfigBlockOption::DATABASE);
const auto *path = config_get_param(ConfigOption::DB_FILE); const auto *path = config_get_param(ConfigOption::DB_FILE);
if (param != nullptr && path != nullptr) { if (param != nullptr && path != nullptr) {
@ -42,10 +43,10 @@ CreateConfiguredDatabase(EventLoop &loop, DatabaseListener &listener,
return nullptr; return nullptr;
} }
struct config_param *allocated = nullptr; ConfigBlock *allocated = nullptr;
if (param == nullptr && path != nullptr) { if (param == nullptr && path != nullptr) {
allocated = new config_param("database", path->line); allocated = new ConfigBlock(path->line);
allocated->AddBlockParam("path", path->value.c_str(), allocated->AddBlockParam("path", path->value.c_str(),
path->line); path->line);
param = allocated; param = allocated;
@ -60,7 +61,7 @@ CreateConfiguredDatabase(EventLoop &loop, DatabaseListener &listener,
const auto db_file = AllocatedPath::Build(cache_dir, "mpd.db"); const auto db_file = AllocatedPath::Build(cache_dir, "mpd.db");
allocated = new config_param("database"); allocated = new ConfigBlock();
allocated->AddBlockParam("path", db_file.c_str(), -1); allocated->AddBlockParam("path", db_file.c_str(), -1);
param = allocated; param = allocated;
} }

View File

@ -22,17 +22,17 @@
#include "Registry.hxx" #include "Registry.hxx"
#include "DatabaseError.hxx" #include "DatabaseError.hxx"
#include "util/Error.hxx" #include "util/Error.hxx"
#include "config/Param.hxx" #include "config/Block.hxx"
#include "DatabasePlugin.hxx" #include "DatabasePlugin.hxx"
#include <string.h> #include <string.h>
Database * Database *
DatabaseGlobalInit(EventLoop &loop, DatabaseListener &listener, DatabaseGlobalInit(EventLoop &loop, DatabaseListener &listener,
const config_param &param, Error &error) const ConfigBlock &block, Error &error)
{ {
const char *plugin_name = const char *plugin_name =
param.GetBlockValue("plugin", "simple"); block.GetBlockValue("plugin", "simple");
const DatabasePlugin *plugin = GetDatabasePluginByName(plugin_name); const DatabasePlugin *plugin = GetDatabasePluginByName(plugin_name);
if (plugin == nullptr) { if (plugin == nullptr) {
@ -41,5 +41,5 @@ DatabaseGlobalInit(EventLoop &loop, DatabaseListener &listener,
return nullptr; return nullptr;
} }
return plugin->create(loop, listener, param, error); return plugin->create(loop, listener, block, error);
} }

View File

@ -22,7 +22,7 @@
#include "Compiler.h" #include "Compiler.h"
struct config_param; struct ConfigBlock;
class EventLoop; class EventLoop;
class DatabaseListener; class DatabaseListener;
class Database; class Database;
@ -35,6 +35,6 @@ class Error;
*/ */
Database * Database *
DatabaseGlobalInit(EventLoop &loop, DatabaseListener &listener, DatabaseGlobalInit(EventLoop &loop, DatabaseListener &listener,
const config_param &param, Error &error); const ConfigBlock &block, Error &error);
#endif #endif

View File

@ -26,7 +26,7 @@
#ifndef MPD_DATABASE_PLUGIN_HXX #ifndef MPD_DATABASE_PLUGIN_HXX
#define MPD_DATABASE_PLUGIN_HXX #define MPD_DATABASE_PLUGIN_HXX
struct config_param; struct ConfigBlock;
class Error; class Error;
class EventLoop; class EventLoop;
class DatabaseListener; class DatabaseListener;
@ -47,7 +47,7 @@ struct DatabasePlugin {
* Allocates and configures a database. * Allocates and configures a database.
*/ */
Database *(*create)(EventLoop &loop, DatabaseListener &listener, Database *(*create)(EventLoop &loop, DatabaseListener &listener,
const config_param &param, const ConfigBlock &block,
Error &error); Error &error);
constexpr bool RequireStorage() const { constexpr bool RequireStorage() const {

View File

@ -30,7 +30,7 @@
#include "db/Stats.hxx" #include "db/Stats.hxx"
#include "SongFilter.hxx" #include "SongFilter.hxx"
#include "Compiler.h" #include "Compiler.h"
#include "config/Param.hxx" #include "config/Block.hxx"
#include "tag/TagBuilder.hxx" #include "tag/TagBuilder.hxx"
#include "tag/Tag.hxx" #include "tag/Tag.hxx"
#include "util/Error.hxx" #include "util/Error.hxx"
@ -97,7 +97,7 @@ public:
listener(_listener) {} listener(_listener) {}
static Database *Create(EventLoop &loop, DatabaseListener &listener, static Database *Create(EventLoop &loop, DatabaseListener &listener,
const config_param &param, const ConfigBlock &block,
Error &error); Error &error);
virtual bool Open(Error &error) override; virtual bool Open(Error &error) override;
@ -129,7 +129,7 @@ public:
} }
private: private:
bool Configure(const config_param &param, Error &error); bool Configure(const ConfigBlock &block, Error &error);
bool Connect(Error &error); bool Connect(Error &error);
bool CheckConnection(Error &error); bool CheckConnection(Error &error);
@ -321,10 +321,10 @@ SendConstraints(mpd_connection *connection, const DatabaseSelection &selection)
Database * Database *
ProxyDatabase::Create(EventLoop &loop, DatabaseListener &listener, ProxyDatabase::Create(EventLoop &loop, DatabaseListener &listener,
const config_param &param, Error &error) const ConfigBlock &block, Error &error)
{ {
ProxyDatabase *db = new ProxyDatabase(loop, listener); ProxyDatabase *db = new ProxyDatabase(loop, listener);
if (!db->Configure(param, error)) { if (!db->Configure(block, error)) {
delete db; delete db;
db = nullptr; db = nullptr;
} }
@ -333,11 +333,11 @@ ProxyDatabase::Create(EventLoop &loop, DatabaseListener &listener,
} }
bool bool
ProxyDatabase::Configure(const config_param &param, gcc_unused Error &error) ProxyDatabase::Configure(const ConfigBlock &block, gcc_unused Error &error)
{ {
host = param.GetBlockValue("host", ""); host = block.GetBlockValue("host", "");
port = param.GetBlockValue("port", 0u); port = block.GetBlockValue("port", 0u);
keepalive = param.GetBlockValue("keepalive", false); keepalive = block.GetBlockValue("keepalive", false);
return true; return true;
} }

View File

@ -34,7 +34,7 @@
#include "fs/io/TextFile.hxx" #include "fs/io/TextFile.hxx"
#include "fs/io/BufferedOutputStream.hxx" #include "fs/io/BufferedOutputStream.hxx"
#include "fs/io/FileOutputStream.hxx" #include "fs/io/FileOutputStream.hxx"
#include "config/Param.hxx" #include "config/Block.hxx"
#include "fs/FileSystem.hxx" #include "fs/FileSystem.hxx"
#include "util/CharUtil.hxx" #include "util/CharUtil.hxx"
#include "util/Error.hxx" #include "util/Error.hxx"
@ -76,10 +76,10 @@ inline SimpleDatabase::SimpleDatabase(AllocatedPath &&_path,
Database * Database *
SimpleDatabase::Create(gcc_unused EventLoop &loop, SimpleDatabase::Create(gcc_unused EventLoop &loop,
gcc_unused DatabaseListener &listener, gcc_unused DatabaseListener &listener,
const config_param &param, Error &error) const ConfigBlock &block, Error &error)
{ {
SimpleDatabase *db = new SimpleDatabase(); SimpleDatabase *db = new SimpleDatabase();
if (!db->Configure(param, error)) { if (!db->Configure(block, error)) {
delete db; delete db;
db = nullptr; db = nullptr;
} }
@ -88,9 +88,9 @@ SimpleDatabase::Create(gcc_unused EventLoop &loop,
} }
bool bool
SimpleDatabase::Configure(const config_param &param, Error &error) SimpleDatabase::Configure(const ConfigBlock &block, Error &error)
{ {
path = param.GetBlockPath("path", error); path = block.GetBlockPath("path", error);
if (path.IsNull()) { if (path.IsNull()) {
if (!error.IsDefined()) if (!error.IsDefined())
error.Set(simple_db_domain, error.Set(simple_db_domain,
@ -100,12 +100,12 @@ SimpleDatabase::Configure(const config_param &param, Error &error)
path_utf8 = path.ToUTF8(); path_utf8 = path.ToUTF8();
cache_path = param.GetBlockPath("cache_directory", error); cache_path = block.GetBlockPath("cache_directory", error);
if (path.IsNull() && error.IsDefined()) if (path.IsNull() && error.IsDefined())
return false; return false;
#ifdef ENABLE_ZLIB #ifdef ENABLE_ZLIB
compress = param.GetBlockValue("compress", compress); compress = block.GetBlockValue("compress", compress);
#endif #endif
return true; return true;

View File

@ -28,7 +28,7 @@
#include <cassert> #include <cassert>
struct config_param; struct ConfigBlock;
struct Directory; struct Directory;
struct DatabasePlugin; struct DatabasePlugin;
class EventLoop; class EventLoop;
@ -73,7 +73,7 @@ class SimpleDatabase : public Database {
public: public:
static Database *Create(EventLoop &loop, DatabaseListener &listener, static Database *Create(EventLoop &loop, DatabaseListener &listener,
const config_param &param, const ConfigBlock &block,
Error &error); Error &error);
gcc_pure gcc_pure
@ -134,7 +134,7 @@ public:
} }
private: private:
bool Configure(const config_param &param, Error &error); bool Configure(const ConfigBlock &block, Error &error);
gcc_pure gcc_pure
bool Check(Error &error) const; bool Check(Error &error) const;

View File

@ -33,7 +33,7 @@
#include "db/LightDirectory.hxx" #include "db/LightDirectory.hxx"
#include "db/LightSong.hxx" #include "db/LightSong.hxx"
#include "db/Stats.hxx" #include "db/Stats.hxx"
#include "config/Param.hxx" #include "config/Block.hxx"
#include "tag/TagBuilder.hxx" #include "tag/TagBuilder.hxx"
#include "tag/TagTable.hxx" #include "tag/TagTable.hxx"
#include "util/Error.hxx" #include "util/Error.hxx"
@ -78,7 +78,7 @@ public:
UpnpDatabase():Database(upnp_db_plugin) {} UpnpDatabase():Database(upnp_db_plugin) {}
static Database *Create(EventLoop &loop, DatabaseListener &listener, static Database *Create(EventLoop &loop, DatabaseListener &listener,
const config_param &param, const ConfigBlock &block,
Error &error); Error &error);
virtual bool Open(Error &error) override; virtual bool Open(Error &error) override;
@ -106,7 +106,7 @@ public:
} }
protected: protected:
bool Configure(const config_param &param, Error &error); bool Configure(const ConfigBlock &block, Error &error);
private: private:
bool VisitServer(const ContentDirectoryService &server, bool VisitServer(const ContentDirectoryService &server,
@ -158,10 +158,10 @@ private:
Database * Database *
UpnpDatabase::Create(gcc_unused EventLoop &loop, UpnpDatabase::Create(gcc_unused EventLoop &loop,
gcc_unused DatabaseListener &listener, gcc_unused DatabaseListener &listener,
const config_param &param, Error &error) const ConfigBlock &block, Error &error)
{ {
UpnpDatabase *db = new UpnpDatabase(); UpnpDatabase *db = new UpnpDatabase();
if (!db->Configure(param, error)) { if (!db->Configure(block, error)) {
delete db; delete db;
return nullptr; return nullptr;
} }
@ -173,7 +173,7 @@ UpnpDatabase::Create(gcc_unused EventLoop &loop,
} }
inline bool inline bool
UpnpDatabase::Configure(const config_param &, Error &) UpnpDatabase::Configure(const ConfigBlock &, Error &)
{ {
return true; return true;
} }

View File

@ -36,7 +36,7 @@
#include "tag/Tag.hxx" #include "tag/Tag.hxx"
#include "AudioFormat.hxx" #include "AudioFormat.hxx"
#include "MixRampInfo.hxx" #include "MixRampInfo.hxx"
#include "config/Param.hxx" #include "config/Block.hxx"
#include "Chrono.hxx" #include "Chrono.hxx"
// IWYU pragma: end_exports // IWYU pragma: end_exports

View File

@ -21,7 +21,7 @@
#include "DecoderList.hxx" #include "DecoderList.hxx"
#include "DecoderPlugin.hxx" #include "DecoderPlugin.hxx"
#include "config/ConfigGlobal.hxx" #include "config/ConfigGlobal.hxx"
#include "config/Param.hxx" #include "config/Block.hxx"
#include "plugins/AudiofileDecoderPlugin.hxx" #include "plugins/AudiofileDecoderPlugin.hxx"
#include "plugins/PcmDecoderPlugin.hxx" #include "plugins/PcmDecoderPlugin.hxx"
#include "plugins/DsdiffDecoderPlugin.hxx" #include "plugins/DsdiffDecoderPlugin.hxx"
@ -127,12 +127,12 @@ decoder_plugin_from_name(const char *name)
void decoder_plugin_init_all(void) void decoder_plugin_init_all(void)
{ {
struct config_param empty; ConfigBlock empty;
for (unsigned i = 0; decoder_plugins[i] != nullptr; ++i) { for (unsigned i = 0; decoder_plugins[i] != nullptr; ++i) {
const DecoderPlugin &plugin = *decoder_plugins[i]; const DecoderPlugin &plugin = *decoder_plugins[i];
const struct config_param *param = const auto *param =
config_find_block(ConfigOption::DECODER, "plugin", config_find_block(ConfigBlockOption::DECODER, "plugin",
plugin.name); plugin.name);
if (param == nullptr) if (param == nullptr)

View File

@ -22,7 +22,7 @@
#include "Compiler.h" #include "Compiler.h"
struct config_param; struct ConfigBlock;
class InputStream; class InputStream;
struct tag_handler; struct tag_handler;
class Path; class Path;
@ -44,7 +44,7 @@ struct DecoderPlugin {
* @return true if the plugin was initialized successfully, * @return true if the plugin was initialized successfully,
* false if the plugin is not available * false if the plugin is not available
*/ */
bool (*init)(const config_param &param); bool (*init)(const ConfigBlock &block);
/** /**
* Deinitialize a decoder plugin which was initialized * Deinitialize a decoder plugin which was initialized
@ -112,9 +112,9 @@ struct DecoderPlugin {
* @return true if the plugin was initialized successfully, false if * @return true if the plugin was initialized successfully, false if
* the plugin is not available * the plugin is not available
*/ */
bool Init(const config_param &param) const { bool Init(const ConfigBlock &block) const {
return init != nullptr return init != nullptr
? init(param) ? init(block)
: true; : true;
} }

View File

@ -38,14 +38,14 @@ static constexpr Domain adplug_domain("adplug");
static unsigned sample_rate; static unsigned sample_rate;
static bool static bool
adplug_init(const config_param &param) adplug_init(const ConfigBlock &block)
{ {
FormatDebug(adplug_domain, "adplug %s", FormatDebug(adplug_domain, "adplug %s",
CAdPlug::get_version().c_str()); CAdPlug::get_version().c_str());
Error error; Error error;
sample_rate = param.GetBlockValue("sample_rate", 48000u); sample_rate = block.GetBlockValue("sample_rate", 48000u);
if (!audio_check_sample_rate(sample_rate, error)) { if (!audio_check_sample_rate(sample_rate, error)) {
LogError(error); LogError(error);
return false; return false;

View File

@ -43,7 +43,7 @@ audiofile_error_func(long, const char *msg)
} }
static bool static bool
audiofile_init(const config_param &) audiofile_init(const ConfigBlock &)
{ {
afSetErrorHandler(audiofile_error_func); afSetErrorHandler(audiofile_error_func);
return true; return true;

View File

@ -72,9 +72,9 @@ struct DsdiffMetaData {
static bool lsbitfirst; static bool lsbitfirst;
static bool static bool
dsdiff_init(const config_param &param) dsdiff_init(const ConfigBlock &block)
{ {
lsbitfirst = param.GetBlockValue("lsbitfirst", false); lsbitfirst = block.GetBlockValue("lsbitfirst", false);
return true; return true;
} }

View File

@ -73,7 +73,7 @@ FfmpegOpenInput(AVIOContext *pb,
} }
static bool static bool
ffmpeg_init(gcc_unused const config_param &param) ffmpeg_init(gcc_unused const ConfigBlock &block)
{ {
FfmpegInit(); FfmpegInit();
return true; return true;

View File

@ -291,7 +291,7 @@ flac_decode(Decoder &decoder, InputStream &input_stream)
} }
static bool static bool
oggflac_init(gcc_unused const config_param &param) oggflac_init(gcc_unused const ConfigBlock &block)
{ {
return !!FLAC_API_SUPPORTS_OGG_FLAC; return !!FLAC_API_SUPPORTS_OGG_FLAC;
} }

View File

@ -73,17 +73,17 @@ fluidsynth_mpd_log_function(int level, char *message, gcc_unused void *data)
} }
static bool static bool
fluidsynth_init(const config_param &param) fluidsynth_init(const ConfigBlock &block)
{ {
Error error; Error error;
sample_rate = param.GetBlockValue("sample_rate", 48000u); sample_rate = block.GetBlockValue("sample_rate", 48000u);
if (!audio_check_sample_rate(sample_rate, error)) { if (!audio_check_sample_rate(sample_rate, error)) {
LogError(error); LogError(error);
return false; return false;
} }
soundfont_path = param.GetBlockValue("soundfont", soundfont_path = block.GetBlockValue("soundfont",
"/usr/share/sounds/sf2/FluidR3_GM.sf2"); "/usr/share/sounds/sf2/FluidR3_GM.sf2");
fluid_set_log_function(LAST_LOG_LEVEL, fluid_set_log_function(LAST_LOG_LEVEL,

View File

@ -107,7 +107,7 @@ mad_fixed_to_24_buffer(int32_t *dest, const struct mad_synth *synth,
} }
static bool static bool
mp3_plugin_init(gcc_unused const config_param &param) mp3_plugin_init(gcc_unused const ConfigBlock &block)
{ {
gapless_playback = config_get_bool(ConfigOption::GAPLESS_MP3_PLAYBACK, gapless_playback = config_get_bool(ConfigOption::GAPLESS_MP3_PLAYBACK,
DEFAULT_GAPLESS_MP3_PLAYBACK); DEFAULT_GAPLESS_MP3_PLAYBACK);

View File

@ -109,15 +109,15 @@ static bool mikmod_loop;
static unsigned mikmod_sample_rate; static unsigned mikmod_sample_rate;
static bool static bool
mikmod_decoder_init(const config_param &param) mikmod_decoder_init(const ConfigBlock &block)
{ {
static char params[] = ""; static char params[] = "";
mikmod_loop = param.GetBlockValue("loop", false); mikmod_loop = block.GetBlockValue("loop", false);
mikmod_sample_rate = param.GetBlockValue("sample_rate", 44100u); mikmod_sample_rate = block.GetBlockValue("sample_rate", 44100u);
if (!audio_valid_sample_rate(mikmod_sample_rate)) if (!audio_valid_sample_rate(mikmod_sample_rate))
FormatFatalError("Invalid sample rate in line %d: %u", FormatFatalError("Invalid sample rate in line %d: %u",
param.line, mikmod_sample_rate); block.line, mikmod_sample_rate);
md_device = 0; md_device = 0;
md_reverb = 0; md_reverb = 0;

View File

@ -41,12 +41,12 @@ static constexpr offset_type MODPLUG_FILE_LIMIT = 100 * 1024 * 1024;
static int modplug_loop_count; static int modplug_loop_count;
static bool static bool
modplug_decoder_init(const config_param &param) modplug_decoder_init(const ConfigBlock &block)
{ {
modplug_loop_count = param.GetBlockValue("loop_count", 0); modplug_loop_count = block.GetBlockValue("loop_count", 0);
if (modplug_loop_count < -1) if (modplug_loop_count < -1)
FormatFatalError("Invalid loop count in line %d: %i", FormatFatalError("Invalid loop count in line %d: %i",
param.line, modplug_loop_count); block.line, modplug_loop_count);
return true; return true;
} }

View File

@ -37,7 +37,7 @@
static constexpr Domain mpg123_domain("mpg123"); static constexpr Domain mpg123_domain("mpg123");
static bool static bool
mpd_mpg123_init(gcc_unused const config_param &param) mpd_mpg123_init(gcc_unused const ConfigBlock &block)
{ {
mpg123_init(); mpg123_init();

View File

@ -61,7 +61,7 @@ IsOpusTags(const ogg_packet &packet)
} }
static bool static bool
mpd_opus_init(gcc_unused const config_param &param) mpd_opus_init(gcc_unused const ConfigBlock &block)
{ {
LogDebug(opus_domain, opus_get_version_string()); LogDebug(opus_domain, opus_get_version_string());

View File

@ -64,22 +64,22 @@ sidplay_load_songlength_db(const Path path)
} }
static bool static bool
sidplay_init(const config_param &param) sidplay_init(const ConfigBlock &block)
{ {
/* read the songlengths database file */ /* read the songlengths database file */
Error error; Error error;
const auto database_path = param.GetBlockPath("songlength_database", error); const auto database_path = block.GetBlockPath("songlength_database", error);
if (!database_path.IsNull()) if (!database_path.IsNull())
songlength_database = sidplay_load_songlength_db(database_path); songlength_database = sidplay_load_songlength_db(database_path);
else if (error.IsDefined()) else if (error.IsDefined())
FatalError(error); FatalError(error);
default_songlength = param.GetBlockValue("default_songlength", 0u); default_songlength = block.GetBlockValue("default_songlength", 0u);
all_files_are_containers = all_files_are_containers =
param.GetBlockValue("all_files_are_containers", true); block.GetBlockValue("all_files_are_containers", true);
filter_setting = param.GetBlockValue("filter", true); filter_setting = block.GetBlockValue("filter", true);
return true; return true;
} }

View File

@ -32,7 +32,7 @@
static constexpr Domain sndfile_domain("sndfile"); static constexpr Domain sndfile_domain("sndfile");
static bool static bool
sndfile_init(gcc_unused const config_param &param) sndfile_init(gcc_unused const ConfigBlock &block)
{ {
LogDebug(sndfile_domain, sf_version_string()); LogDebug(sndfile_domain, sf_version_string());
return true; return true;

View File

@ -194,7 +194,7 @@ vorbis_interleave(float *dest, const float *const*src,
/* public */ /* public */
static bool static bool
vorbis_init(gcc_unused const config_param &param) vorbis_init(gcc_unused const ConfigBlock &block)
{ {
#ifndef HAVE_TREMOR #ifndef HAVE_TREMOR
LogDebug(vorbis_domain, vorbis_version_string()); LogDebug(vorbis_domain, vorbis_version_string());

View File

@ -38,11 +38,11 @@ static constexpr Domain wildmidi_domain("wildmidi");
static constexpr unsigned WILDMIDI_SAMPLE_RATE = 48000; static constexpr unsigned WILDMIDI_SAMPLE_RATE = 48000;
static bool static bool
wildmidi_init(const config_param &param) wildmidi_init(const ConfigBlock &block)
{ {
Error error; Error error;
const AllocatedPath path = const AllocatedPath path =
param.GetBlockPath("config_file", block.GetBlockPath("config_file",
"/etc/timidity/timidity.cfg", "/etc/timidity/timidity.cfg",
error); error);
if (path.IsNull()) if (path.IsNull())

View File

@ -31,7 +31,7 @@
#include "EncoderPlugin.hxx" #include "EncoderPlugin.hxx"
#include "AudioFormat.hxx" #include "AudioFormat.hxx"
#include "tag/Tag.hxx" #include "tag/Tag.hxx"
#include "config/Param.hxx" #include "config/Block.hxx"
// IWYU pragma: end_exports // IWYU pragma: end_exports

View File

@ -24,14 +24,14 @@
struct Encoder; struct Encoder;
struct AudioFormat; struct AudioFormat;
struct config_param; struct ConfigBlock;
struct Tag; struct Tag;
class Error; class Error;
struct EncoderPlugin { struct EncoderPlugin {
const char *name; const char *name;
Encoder *(*init)(const config_param &param, Encoder *(*init)(const ConfigBlock &block,
Error &error); Error &error);
void (*finish)(Encoder *encoder); void (*finish)(Encoder *encoder);
@ -69,10 +69,10 @@ struct EncoderPlugin {
* @return an encoder object on success, nullptr on failure * @return an encoder object on success, nullptr on failure
*/ */
static inline Encoder * static inline Encoder *
encoder_init(const EncoderPlugin &plugin, const config_param &param, encoder_init(const EncoderPlugin &plugin, const ConfigBlock &block,
Error &error_r) Error &error_r)
{ {
return plugin.init(param, error_r); return plugin.init(block, error_r);
} }
#endif #endif

View File

@ -56,21 +56,21 @@ struct flac_encoder {
static constexpr Domain flac_encoder_domain("vorbis_encoder"); static constexpr Domain flac_encoder_domain("vorbis_encoder");
static bool static bool
flac_encoder_configure(struct flac_encoder *encoder, const config_param &param, flac_encoder_configure(struct flac_encoder *encoder, const ConfigBlock &block,
gcc_unused Error &error) gcc_unused Error &error)
{ {
encoder->compression = param.GetBlockValue("compression", 5u); encoder->compression = block.GetBlockValue("compression", 5u);
return true; return true;
} }
static Encoder * static Encoder *
flac_encoder_init(const config_param &param, Error &error) flac_encoder_init(const ConfigBlock &block, Error &error)
{ {
flac_encoder *encoder = new flac_encoder(); flac_encoder *encoder = new flac_encoder();
/* load configuration from "param" */ /* load configuration from "block" */
if (!flac_encoder_configure(encoder, param, error)) { if (!flac_encoder_configure(encoder, block, error)) {
/* configuration has failed, roll back and return error */ /* configuration has failed, roll back and return error */
delete encoder; delete encoder;
return nullptr; return nullptr;

View File

@ -47,18 +47,18 @@ struct LameEncoder final {
LameEncoder():encoder(lame_encoder_plugin) {} LameEncoder():encoder(lame_encoder_plugin) {}
bool Configure(const config_param &param, Error &error); bool Configure(const ConfigBlock &block, Error &error);
}; };
static constexpr Domain lame_encoder_domain("lame_encoder"); static constexpr Domain lame_encoder_domain("lame_encoder");
bool bool
LameEncoder::Configure(const config_param &param, Error &error) LameEncoder::Configure(const ConfigBlock &block, Error &error)
{ {
const char *value; const char *value;
char *endptr; char *endptr;
value = param.GetBlockValue("quality"); value = block.GetBlockValue("quality");
if (value != nullptr) { if (value != nullptr) {
/* a quality was configured (VBR) */ /* a quality was configured (VBR) */
@ -72,7 +72,7 @@ LameEncoder::Configure(const config_param &param, Error &error)
return false; return false;
} }
if (param.GetBlockValue("bitrate") != nullptr) { if (block.GetBlockValue("bitrate") != nullptr) {
error.Set(config_domain, error.Set(config_domain,
"quality and bitrate are both defined"); "quality and bitrate are both defined");
return false; return false;
@ -80,7 +80,7 @@ LameEncoder::Configure(const config_param &param, Error &error)
} else { } else {
/* a bit rate was configured */ /* a bit rate was configured */
value = param.GetBlockValue("bitrate"); value = block.GetBlockValue("bitrate");
if (value == nullptr) { if (value == nullptr) {
error.Set(config_domain, error.Set(config_domain,
"neither bitrate nor quality defined"); "neither bitrate nor quality defined");
@ -101,12 +101,12 @@ LameEncoder::Configure(const config_param &param, Error &error)
} }
static Encoder * static Encoder *
lame_encoder_init(const config_param &param, Error &error) lame_encoder_init(const ConfigBlock &block, Error &error)
{ {
LameEncoder *encoder = new LameEncoder(); LameEncoder *encoder = new LameEncoder();
/* load configuration from "param" */ /* load configuration from "block" */
if (!encoder->Configure(param, error)) { if (!encoder->Configure(block, error)) {
/* configuration has failed, roll back and return error */ /* configuration has failed, roll back and return error */
delete encoder; delete encoder;
return nullptr; return nullptr;

View File

@ -36,7 +36,7 @@ struct NullEncoder final {
}; };
static Encoder * static Encoder *
null_encoder_init(gcc_unused const config_param &param, null_encoder_init(gcc_unused const ConfigBlock &block,
gcc_unused Error &error) gcc_unused Error &error)
{ {
NullEncoder *encoder = new NullEncoder(); NullEncoder *encoder = new NullEncoder();

View File

@ -73,9 +73,9 @@ static constexpr Domain opus_encoder_domain("opus_encoder");
static bool static bool
opus_encoder_configure(struct opus_encoder *encoder, opus_encoder_configure(struct opus_encoder *encoder,
const config_param &param, Error &error) const ConfigBlock &block, Error &error)
{ {
const char *value = param.GetBlockValue("bitrate", "auto"); const char *value = block.GetBlockValue("bitrate", "auto");
if (strcmp(value, "auto") == 0) if (strcmp(value, "auto") == 0)
encoder->bitrate = OPUS_AUTO; encoder->bitrate = OPUS_AUTO;
else if (strcmp(value, "max") == 0) else if (strcmp(value, "max") == 0)
@ -90,13 +90,13 @@ opus_encoder_configure(struct opus_encoder *encoder,
} }
} }
encoder->complexity = param.GetBlockValue("complexity", 10u); encoder->complexity = block.GetBlockValue("complexity", 10u);
if (encoder->complexity > 10) { if (encoder->complexity > 10) {
error.Format(config_domain, "Invalid complexity"); error.Format(config_domain, "Invalid complexity");
return false; return false;
} }
value = param.GetBlockValue("signal", "auto"); value = block.GetBlockValue("signal", "auto");
if (strcmp(value, "auto") == 0) if (strcmp(value, "auto") == 0)
encoder->signal = OPUS_AUTO; encoder->signal = OPUS_AUTO;
else if (strcmp(value, "voice") == 0) else if (strcmp(value, "voice") == 0)
@ -112,12 +112,12 @@ opus_encoder_configure(struct opus_encoder *encoder,
} }
static Encoder * static Encoder *
opus_encoder_init(const config_param &param, Error &error) opus_encoder_init(const ConfigBlock &block, Error &error)
{ {
opus_encoder *encoder = new opus_encoder(); opus_encoder *encoder = new opus_encoder();
/* load configuration from "param" */ /* load configuration from "block" */
if (!opus_encoder_configure(encoder, param, error)) { if (!opus_encoder_configure(encoder, block, error)) {
/* configuration has failed, roll back and return error */ /* configuration has failed, roll back and return error */
delete encoder; delete encoder;
return nullptr; return nullptr;

View File

@ -53,7 +53,7 @@ struct ShineEncoder {
ShineEncoder():encoder(shine_encoder_plugin){} ShineEncoder():encoder(shine_encoder_plugin){}
bool Configure(const config_param &param, Error &error); bool Configure(const ConfigBlock &block, Error &error);
bool Setup(Error &error); bool Setup(Error &error);
@ -63,22 +63,21 @@ struct ShineEncoder {
static constexpr Domain shine_encoder_domain("shine_encoder"); static constexpr Domain shine_encoder_domain("shine_encoder");
inline bool inline bool
ShineEncoder::Configure(const config_param &param, ShineEncoder::Configure(const ConfigBlock &block, gcc_unused Error &error)
gcc_unused Error &error)
{ {
shine_set_config_mpeg_defaults(&config.mpeg); shine_set_config_mpeg_defaults(&config.mpeg);
config.mpeg.bitr = param.GetBlockValue("bitrate", 128); config.mpeg.bitr = block.GetBlockValue("bitrate", 128);
return true; return true;
} }
static Encoder * static Encoder *
shine_encoder_init(const config_param &param, Error &error) shine_encoder_init(const ConfigBlock &block, Error &error)
{ {
ShineEncoder *encoder = new ShineEncoder(); ShineEncoder *encoder = new ShineEncoder();
/* load configuration from "param" */ /* load configuration from "block" */
if (!encoder->Configure(param, error)) { if (!encoder->Configure(block, error)) {
/* configuration has failed, roll back and return error */ /* configuration has failed, roll back and return error */
delete encoder; delete encoder;
return nullptr; return nullptr;

View File

@ -53,18 +53,18 @@ struct TwolameEncoder final {
TwolameEncoder():encoder(twolame_encoder_plugin) {} TwolameEncoder():encoder(twolame_encoder_plugin) {}
bool Configure(const config_param &param, Error &error); bool Configure(const ConfigBlock &block, Error &error);
}; };
static constexpr Domain twolame_encoder_domain("twolame_encoder"); static constexpr Domain twolame_encoder_domain("twolame_encoder");
bool bool
TwolameEncoder::Configure(const config_param &param, Error &error) TwolameEncoder::Configure(const ConfigBlock &block, Error &error)
{ {
const char *value; const char *value;
char *endptr; char *endptr;
value = param.GetBlockValue("quality"); value = block.GetBlockValue("quality");
if (value != nullptr) { if (value != nullptr) {
/* a quality was configured (VBR) */ /* a quality was configured (VBR) */
@ -78,7 +78,7 @@ TwolameEncoder::Configure(const config_param &param, Error &error)
return false; return false;
} }
if (param.GetBlockValue("bitrate") != nullptr) { if (block.GetBlockValue("bitrate") != nullptr) {
error.Set(config_domain, error.Set(config_domain,
"quality and bitrate are both defined"); "quality and bitrate are both defined");
return false; return false;
@ -86,7 +86,7 @@ TwolameEncoder::Configure(const config_param &param, Error &error)
} else { } else {
/* a bit rate was configured */ /* a bit rate was configured */
value = param.GetBlockValue("bitrate"); value = block.GetBlockValue("bitrate");
if (value == nullptr) { if (value == nullptr) {
error.Set(config_domain, error.Set(config_domain,
"neither bitrate nor quality defined"); "neither bitrate nor quality defined");
@ -107,15 +107,15 @@ TwolameEncoder::Configure(const config_param &param, Error &error)
} }
static Encoder * static Encoder *
twolame_encoder_init(const config_param &param, Error &error_r) twolame_encoder_init(const ConfigBlock &block, Error &error_r)
{ {
FormatDebug(twolame_encoder_domain, FormatDebug(twolame_encoder_domain,
"libtwolame version %s", get_twolame_version()); "libtwolame version %s", get_twolame_version());
TwolameEncoder *encoder = new TwolameEncoder(); TwolameEncoder *encoder = new TwolameEncoder();
/* load configuration from "param" */ /* load configuration from "block" */
if (!encoder->Configure(param, error_r)) { if (!encoder->Configure(block, error_r)) {
/* configuration has failed, roll back and return error */ /* configuration has failed, roll back and return error */
delete encoder; delete encoder;
return nullptr; return nullptr;

View File

@ -58,9 +58,9 @@ static constexpr Domain vorbis_encoder_domain("vorbis_encoder");
static bool static bool
vorbis_encoder_configure(struct vorbis_encoder &encoder, vorbis_encoder_configure(struct vorbis_encoder &encoder,
const config_param &param, Error &error) const ConfigBlock &block, Error &error)
{ {
const char *value = param.GetBlockValue("quality"); const char *value = block.GetBlockValue("quality");
if (value != nullptr) { if (value != nullptr) {
/* a quality was configured (VBR) */ /* a quality was configured (VBR) */
@ -76,7 +76,7 @@ vorbis_encoder_configure(struct vorbis_encoder &encoder,
return false; return false;
} }
if (param.GetBlockValue("bitrate") != nullptr) { if (block.GetBlockValue("bitrate") != nullptr) {
error.Set(config_domain, error.Set(config_domain,
"quality and bitrate are both defined"); "quality and bitrate are both defined");
return false; return false;
@ -84,7 +84,7 @@ vorbis_encoder_configure(struct vorbis_encoder &encoder,
} else { } else {
/* a bit rate was configured */ /* a bit rate was configured */
value = param.GetBlockValue("bitrate"); value = block.GetBlockValue("bitrate");
if (value == nullptr) { if (value == nullptr) {
error.Set(config_domain, error.Set(config_domain,
"neither bitrate nor quality defined"); "neither bitrate nor quality defined");
@ -106,12 +106,12 @@ vorbis_encoder_configure(struct vorbis_encoder &encoder,
} }
static Encoder * static Encoder *
vorbis_encoder_init(const config_param &param, Error &error) vorbis_encoder_init(const ConfigBlock &block, Error &error)
{ {
vorbis_encoder *encoder = new vorbis_encoder(); vorbis_encoder *encoder = new vorbis_encoder();
/* load configuration from "param" */ /* load configuration from "block" */
if (!vorbis_encoder_configure(*encoder, param, error)) { if (!vorbis_encoder_configure(*encoder, block, error)) {
/* configuration has failed, roll back and return error */ /* configuration has failed, roll back and return error */
delete encoder; delete encoder;
return nullptr; return nullptr;

View File

@ -79,7 +79,7 @@ fill_wave_header(struct wave_header *header, int channels, int bits,
} }
static Encoder * static Encoder *
wave_encoder_init(gcc_unused const config_param &param, wave_encoder_init(gcc_unused const ConfigBlock &block,
gcc_unused Error &error) gcc_unused Error &error)
{ {
WaveEncoder *encoder = new WaveEncoder(); WaveEncoder *encoder = new WaveEncoder();

View File

@ -25,6 +25,7 @@
#include "config/ConfigOption.hxx" #include "config/ConfigOption.hxx"
#include "config/ConfigGlobal.hxx" #include "config/ConfigGlobal.hxx"
#include "config/ConfigError.hxx" #include "config/ConfigError.hxx"
#include "config/Block.hxx"
#include "util/Error.hxx" #include "util/Error.hxx"
#include <algorithm> #include <algorithm>
@ -34,9 +35,8 @@
static bool static bool
filter_chain_append_new(Filter &chain, const char *template_name, Error &error) filter_chain_append_new(Filter &chain, const char *template_name, Error &error)
{ {
const struct config_param *cfg = const auto *cfg = config_find_block(ConfigBlockOption::AUDIO_FILTER,
config_find_block(ConfigOption::AUDIO_FILTER, "name", "name", template_name);
template_name);
if (cfg == nullptr) { if (cfg == nullptr) {
error.Format(config_domain, error.Format(config_domain,
"filter template not found: %s", "filter template not found: %s",

View File

@ -20,7 +20,7 @@
#include "config.h" #include "config.h"
#include "FilterPlugin.hxx" #include "FilterPlugin.hxx"
#include "FilterRegistry.hxx" #include "FilterRegistry.hxx"
#include "config/Param.hxx" #include "config/Block.hxx"
#include "config/ConfigError.hxx" #include "config/ConfigError.hxx"
#include "util/Error.hxx" #include "util/Error.hxx"
@ -28,20 +28,20 @@
Filter * Filter *
filter_new(const struct filter_plugin *plugin, filter_new(const struct filter_plugin *plugin,
const config_param &param, Error &error) const ConfigBlock &block, Error &error)
{ {
assert(plugin != nullptr); assert(plugin != nullptr);
assert(!error.IsDefined()); assert(!error.IsDefined());
return plugin->init(param, error); return plugin->init(block, error);
} }
Filter * Filter *
filter_configured_new(const config_param &param, Error &error) filter_configured_new(const ConfigBlock &block, Error &error)
{ {
assert(!error.IsDefined()); assert(!error.IsDefined());
const char *plugin_name = param.GetBlockValue("plugin"); const char *plugin_name = block.GetBlockValue("plugin");
if (plugin_name == nullptr) { if (plugin_name == nullptr) {
error.Set(config_domain, "No filter plugin specified"); error.Set(config_domain, "No filter plugin specified");
return nullptr; return nullptr;
@ -54,5 +54,5 @@ filter_configured_new(const config_param &param, Error &error)
return nullptr; return nullptr;
} }
return filter_new(plugin, param, error); return filter_new(plugin, block, error);
} }

View File

@ -26,7 +26,7 @@
#ifndef MPD_FILTER_PLUGIN_HXX #ifndef MPD_FILTER_PLUGIN_HXX
#define MPD_FILTER_PLUGIN_HXX #define MPD_FILTER_PLUGIN_HXX
struct config_param; struct ConfigBlock;
class Filter; class Filter;
class Error; class Error;
@ -36,7 +36,7 @@ struct filter_plugin {
/** /**
* Allocates and configures a filter. * Allocates and configures a filter.
*/ */
Filter *(*init)(const config_param &param, Error &error); Filter *(*init)(const ConfigBlock &block, Error &error);
}; };
/** /**
@ -50,7 +50,7 @@ struct filter_plugin {
*/ */
Filter * Filter *
filter_new(const struct filter_plugin *plugin, filter_new(const struct filter_plugin *plugin,
const config_param &param, Error &error); const ConfigBlock &block, Error &error);
/** /**
* Creates a new filter, loads configuration and the plugin name from * Creates a new filter, loads configuration and the plugin name from
@ -62,6 +62,6 @@ filter_new(const struct filter_plugin *plugin,
* @return a new filter object, or nullptr on error * @return a new filter object, or nullptr on error
*/ */
Filter * Filter *
filter_configured_new(const config_param &param, Error &error); filter_configured_new(const ConfigBlock &block, Error &error);
#endif #endif

View File

@ -24,7 +24,7 @@
#include "filter/FilterInternal.hxx" #include "filter/FilterInternal.hxx"
#include "filter/FilterRegistry.hxx" #include "filter/FilterRegistry.hxx"
#include "AudioFormat.hxx" #include "AudioFormat.hxx"
#include "config/Param.hxx" #include "config/Block.hxx"
#include "util/ConstBuffer.hxx" #include "util/ConstBuffer.hxx"
#include <assert.h> #include <assert.h>
@ -70,7 +70,7 @@ AutoConvertFilter::Open(AudioFormat &in_audio_format, Error &error)
if (in_audio_format != child_audio_format) { if (in_audio_format != child_audio_format) {
/* yes - create a convert_filter */ /* yes - create a convert_filter */
const config_param empty; const ConfigBlock empty;
convert = filter_new(&convert_filter_plugin, empty, error); convert = filter_new(&convert_filter_plugin, empty, error);
if (convert == nullptr) { if (convert == nullptr) {
filter->Close(); filter->Close();

View File

@ -70,7 +70,7 @@ private:
static constexpr Domain chain_filter_domain("chain_filter"); static constexpr Domain chain_filter_domain("chain_filter");
static Filter * static Filter *
chain_filter_init(gcc_unused const config_param &param, chain_filter_init(gcc_unused const ConfigBlock &block,
gcc_unused Error &error) gcc_unused Error &error)
{ {
return new ChainFilter(); return new ChainFilter();

View File

@ -59,7 +59,7 @@ public:
}; };
static Filter * static Filter *
convert_filter_init(gcc_unused const config_param &param, convert_filter_init(gcc_unused const ConfigBlock &block,
gcc_unused Error &error) gcc_unused Error &error)
{ {
return new ConvertFilter(); return new ConvertFilter();

View File

@ -42,7 +42,7 @@ public:
}; };
static Filter * static Filter *
normalize_filter_init(gcc_unused const config_param &param, normalize_filter_init(gcc_unused const ConfigBlock &block,
gcc_unused Error &error) gcc_unused Error &error)
{ {
return new NormalizeFilter(); return new NormalizeFilter();

View File

@ -48,7 +48,7 @@ public:
}; };
static Filter * static Filter *
null_filter_init(gcc_unused const config_param &param, null_filter_init(gcc_unused const ConfigBlock &block,
gcc_unused Error &error) gcc_unused Error &error)
{ {
return new NullFilter(); return new NullFilter();

View File

@ -150,7 +150,7 @@ ReplayGainFilter::Update()
} }
static Filter * static Filter *
replay_gain_filter_init(gcc_unused const config_param &param, replay_gain_filter_init(gcc_unused const ConfigBlock &block,
gcc_unused Error &error) gcc_unused Error &error)
{ {
return new ReplayGainFilter(); return new ReplayGainFilter();

View File

@ -41,7 +41,7 @@
#include "config.h" #include "config.h"
#include "config/ConfigError.hxx" #include "config/ConfigError.hxx"
#include "config/Param.hxx" #include "config/Block.hxx"
#include "AudioFormat.hxx" #include "AudioFormat.hxx"
#include "filter/FilterPlugin.hxx" #include "filter/FilterPlugin.hxx"
#include "filter/FilterInternal.hxx" #include "filter/FilterInternal.hxx"
@ -114,11 +114,11 @@ public:
* a>b, c>d, e>f, ... * a>b, c>d, e>f, ...
* where a... are non-unique, non-negative integers * where a... are non-unique, non-negative integers
* and input channel a gets copied to output channel b, etc. * and input channel a gets copied to output channel b, etc.
* @param param the configuration block to read * @param block the configuration block to read
* @param filter a route_filter whose min_channels and sources[] to set * @param filter a route_filter whose min_channels and sources[] to set
* @return true on success, false on error * @return true on success, false on error
*/ */
bool Configure(const config_param &param, Error &error); bool Configure(const ConfigBlock &block, Error &error);
/* virtual methods from class Filter */ /* virtual methods from class Filter */
AudioFormat Open(AudioFormat &af, Error &error) override; AudioFormat Open(AudioFormat &af, Error &error) override;
@ -128,7 +128,7 @@ public:
}; };
bool bool
RouteFilter::Configure(const config_param &param, Error &error) { RouteFilter::Configure(const ConfigBlock &block, Error &error) {
/* TODO: /* TODO:
* With a more clever way of marking "don't copy to output N", * With a more clever way of marking "don't copy to output N",
@ -142,7 +142,7 @@ RouteFilter::Configure(const config_param &param, Error &error) {
min_output_channels = 0; min_output_channels = 0;
// A cowardly default, just passthrough stereo // A cowardly default, just passthrough stereo
const char *routes = param.GetBlockValue("routes", "0>0, 1>1"); const char *routes = block.GetBlockValue("routes", "0>0, 1>1");
while (true) { while (true) {
routes = StripLeft(routes); routes = StripLeft(routes);
@ -205,10 +205,10 @@ RouteFilter::Configure(const config_param &param, Error &error) {
} }
static Filter * static Filter *
route_filter_init(const config_param &param, Error &error) route_filter_init(const ConfigBlock &block, Error &error)
{ {
RouteFilter *filter = new RouteFilter(); RouteFilter *filter = new RouteFilter();
if (!filter->Configure(param, error)) { if (!filter->Configure(block, error)) {
delete filter; delete filter;
return nullptr; return nullptr;
} }

View File

@ -53,7 +53,7 @@ public:
static constexpr Domain volume_domain("pcm_volume"); static constexpr Domain volume_domain("pcm_volume");
static Filter * static Filter *
volume_filter_init(gcc_unused const config_param &param, volume_filter_init(gcc_unused const ConfigBlock &block,
gcc_unused Error &error) gcc_unused Error &error)
{ {
return new VolumeFilter(); return new VolumeFilter();

View File

@ -24,7 +24,7 @@
#include "util/Error.hxx" #include "util/Error.hxx"
#include "config/ConfigGlobal.hxx" #include "config/ConfigGlobal.hxx"
#include "config/ConfigOption.hxx" #include "config/ConfigOption.hxx"
#include "config/Param.hxx" #include "config/Block.hxx"
#include "Log.hxx" #include "Log.hxx"
#include <assert.h> #include <assert.h>
@ -33,7 +33,7 @@
bool bool
input_stream_global_init(Error &error) input_stream_global_init(Error &error)
{ {
const config_param empty; const ConfigBlock empty;
for (unsigned i = 0; input_plugins[i] != nullptr; ++i) { for (unsigned i = 0; input_plugins[i] != nullptr; ++i) {
const InputPlugin *plugin = input_plugins[i]; const InputPlugin *plugin = input_plugins[i];
@ -42,17 +42,17 @@ input_stream_global_init(Error &error)
assert(*plugin->name != 0); assert(*plugin->name != 0);
assert(plugin->open != nullptr); assert(plugin->open != nullptr);
const struct config_param *param = const auto *block =
config_find_block(ConfigOption::INPUT, "plugin", config_find_block(ConfigBlockOption::INPUT, "plugin",
plugin->name); plugin->name);
if (param == nullptr) { if (block == nullptr) {
param = &empty; block = &empty;
} else if (!param->GetBlockValue("enabled", true)) } else if (!block->GetBlockValue("enabled", true))
/* the plugin is disabled in mpd.conf */ /* the plugin is disabled in mpd.conf */
continue; continue;
InputPlugin::InitResult result = plugin->init != nullptr InputPlugin::InitResult result = plugin->init != nullptr
? plugin->init(*param, error) ? plugin->init(*block, error)
: InputPlugin::InitResult::SUCCESS; : InputPlugin::InitResult::SUCCESS;
switch (result) { switch (result) {

View File

@ -34,7 +34,7 @@
#endif #endif
#endif #endif
struct config_param; struct ConfigBlock;
class InputStream; class InputStream;
class Error; class Error;
struct Tag; struct Tag;
@ -69,7 +69,7 @@ struct InputPlugin {
* @return true on success, false if the plugin should be * @return true on success, false if the plugin should be
* disabled * disabled
*/ */
InitResult (*init)(const config_param &param, Error &error); InitResult (*init)(const ConfigBlock &block, Error &error);
/** /**
* Global deinitialization. Called once before MPD shuts * Global deinitialization. Called once before MPD shuts

View File

@ -31,7 +31,7 @@
#include "system/ByteOrder.hxx" #include "system/ByteOrder.hxx"
#include "fs/AllocatedPath.hxx" #include "fs/AllocatedPath.hxx"
#include "Log.hxx" #include "Log.hxx"
#include "config/Param.hxx" #include "config/Block.hxx"
#include "config/ConfigError.hxx" #include "config/ConfigError.hxx"
#include <stdio.h> #include <stdio.h>
@ -106,9 +106,9 @@ static constexpr Domain cdio_domain("cdio");
static bool default_reverse_endian; static bool default_reverse_endian;
static InputPlugin::InitResult static InputPlugin::InitResult
input_cdio_init(const config_param &param, Error &error) input_cdio_init(const ConfigBlock &block, Error &error)
{ {
const char *value = param.GetBlockValue("default_byte_order"); const char *value = block.GetBlockValue("default_byte_order");
if (value != nullptr) { if (value != nullptr) {
if (strcmp(value, "little_endian") == 0) if (strcmp(value, "little_endian") == 0)
default_reverse_endian = IsBigEndian(); default_reverse_endian = IsBigEndian();

View File

@ -23,7 +23,7 @@
#include "../IcyInputStream.hxx" #include "../IcyInputStream.hxx"
#include "../InputPlugin.hxx" #include "../InputPlugin.hxx"
#include "config/ConfigGlobal.hxx" #include "config/ConfigGlobal.hxx"
#include "config/Param.hxx" #include "config/Block.hxx"
#include "tag/Tag.hxx" #include "tag/Tag.hxx"
#include "tag/TagBuilder.hxx" #include "tag/TagBuilder.hxx"
#include "event/SocketMonitor.hxx" #include "event/SocketMonitor.hxx"
@ -535,7 +535,7 @@ CurlMulti::OnTimeout()
*/ */
static InputPlugin::InitResult static InputPlugin::InitResult
input_curl_init(const config_param &param, Error &error) input_curl_init(const ConfigBlock &block, Error &error)
{ {
CURLcode code = curl_global_init(CURL_GLOBAL_ALL); CURLcode code = curl_global_init(CURL_GLOBAL_ALL);
if (code != CURLE_OK) { if (code != CURLE_OK) {
@ -557,10 +557,10 @@ input_curl_init(const config_param &param, Error &error)
http_200_aliases = curl_slist_append(http_200_aliases, "ICY 200 OK"); http_200_aliases = curl_slist_append(http_200_aliases, "ICY 200 OK");
proxy = param.GetBlockValue("proxy"); proxy = block.GetBlockValue("proxy");
proxy_port = param.GetBlockValue("proxy_port", 0u); proxy_port = block.GetBlockValue("proxy_port", 0u);
proxy_user = param.GetBlockValue("proxy_user"); proxy_user = block.GetBlockValue("proxy_user");
proxy_password = param.GetBlockValue("proxy_password"); proxy_password = block.GetBlockValue("proxy_password");
if (proxy == nullptr) { if (proxy == nullptr) {
/* deprecated proxy configuration */ /* deprecated proxy configuration */
@ -571,8 +571,8 @@ input_curl_init(const config_param &param, Error &error)
""); "");
} }
verify_peer = param.GetBlockValue("verify_peer", true); verify_peer = block.GetBlockValue("verify_peer", true);
verify_host = param.GetBlockValue("verify_host", true); verify_host = block.GetBlockValue("verify_host", true);
CURLM *multi = curl_multi_init(); CURLM *multi = curl_multi_init();
if (multi == nullptr) { if (multi == nullptr) {

View File

@ -72,7 +72,7 @@ input_ffmpeg_supported(void)
} }
static InputPlugin::InitResult static InputPlugin::InitResult
input_ffmpeg_init(gcc_unused const config_param &param, input_ffmpeg_init(gcc_unused const ConfigBlock &block,
Error &error) Error &error)
{ {
FfmpegInit(); FfmpegInit();

View File

@ -221,7 +221,7 @@ NfsInputStream::OnNfsFileError(Error &&error)
*/ */
static InputPlugin::InitResult static InputPlugin::InitResult
input_nfs_init(const config_param &, Error &) input_nfs_init(const ConfigBlock &, Error &)
{ {
nfs_init(); nfs_init();
return InputPlugin::InitResult::SUCCESS; return InputPlugin::InitResult::SUCCESS;

View File

@ -66,14 +66,14 @@ public:
*/ */
static InputPlugin::InitResult static InputPlugin::InitResult
input_smbclient_init(gcc_unused const config_param &param, Error &error) input_smbclient_init(gcc_unused const ConfigBlock &block, Error &error)
{ {
if (!SmbclientInit(error)) if (!SmbclientInit(error))
return InputPlugin::InitResult::UNAVAILABLE; return InputPlugin::InitResult::UNAVAILABLE;
// TODO: create one global SMBCCTX here? // TODO: create one global SMBCCTX here?
// TODO: evaluate config_param, call smbc_setOption*() // TODO: evaluate ConfigBlock, call smbc_setOption*()
return InputPlugin::InitResult::SUCCESS; return InputPlugin::InitResult::SUCCESS;
} }

View File

@ -28,10 +28,10 @@ Mixer *
mixer_new(EventLoop &event_loop, mixer_new(EventLoop &event_loop,
const MixerPlugin &plugin, AudioOutput &ao, const MixerPlugin &plugin, AudioOutput &ao,
MixerListener &listener, MixerListener &listener,
const config_param &param, const ConfigBlock &block,
Error &error) Error &error)
{ {
Mixer *mixer = plugin.init(event_loop, ao, listener, param, error); Mixer *mixer = plugin.init(event_loop, ao, listener, block, error);
assert(mixer == nullptr || mixer->IsPlugin(plugin)); assert(mixer == nullptr || mixer->IsPlugin(plugin));

View File

@ -31,12 +31,12 @@ class EventLoop;
struct AudioOutput; struct AudioOutput;
struct MixerPlugin; struct MixerPlugin;
class MixerListener; class MixerListener;
struct config_param; struct ConfigBlock;
Mixer * Mixer *
mixer_new(EventLoop &event_loop, const MixerPlugin &plugin, AudioOutput &ao, mixer_new(EventLoop &event_loop, const MixerPlugin &plugin, AudioOutput &ao,
MixerListener &listener, MixerListener &listener,
const config_param &param, const ConfigBlock &block,
Error &error); Error &error);
void void

View File

@ -27,7 +27,7 @@
#ifndef MPD_MIXER_PLUGIN_HXX #ifndef MPD_MIXER_PLUGIN_HXX
#define MPD_MIXER_PLUGIN_HXX #define MPD_MIXER_PLUGIN_HXX
struct config_param; struct ConfigBlock;
struct AudioOutput; struct AudioOutput;
class Mixer; class Mixer;
class MixerListener; class MixerListener;
@ -46,7 +46,7 @@ struct MixerPlugin {
*/ */
Mixer *(*init)(EventLoop &event_loop, AudioOutput &ao, Mixer *(*init)(EventLoop &event_loop, AudioOutput &ao,
MixerListener &listener, MixerListener &listener,
const config_param &param, const ConfigBlock &block,
Error &error); Error &error);
/** /**

View File

@ -82,7 +82,7 @@ public:
virtual ~AlsaMixer(); virtual ~AlsaMixer();
void Configure(const config_param &param); void Configure(const ConfigBlock &block);
bool Setup(Error &error); bool Setup(Error &error);
/* virtual methods from class Mixer */ /* virtual methods from class Mixer */
@ -162,24 +162,24 @@ alsa_mixer_elem_callback(snd_mixer_elem_t *elem, unsigned mask)
*/ */
inline void inline void
AlsaMixer::Configure(const config_param &param) AlsaMixer::Configure(const ConfigBlock &block)
{ {
device = param.GetBlockValue("mixer_device", device = block.GetBlockValue("mixer_device",
VOLUME_MIXER_ALSA_DEFAULT); VOLUME_MIXER_ALSA_DEFAULT);
control = param.GetBlockValue("mixer_control", control = block.GetBlockValue("mixer_control",
VOLUME_MIXER_ALSA_CONTROL_DEFAULT); VOLUME_MIXER_ALSA_CONTROL_DEFAULT);
index = param.GetBlockValue("mixer_index", index = block.GetBlockValue("mixer_index",
VOLUME_MIXER_ALSA_INDEX_DEFAULT); VOLUME_MIXER_ALSA_INDEX_DEFAULT);
} }
static Mixer * static Mixer *
alsa_mixer_init(EventLoop &event_loop, gcc_unused AudioOutput &ao, alsa_mixer_init(EventLoop &event_loop, gcc_unused AudioOutput &ao,
MixerListener &listener, MixerListener &listener,
const config_param &param, const ConfigBlock &block,
gcc_unused Error &error) gcc_unused Error &error)
{ {
AlsaMixer *am = new AlsaMixer(event_loop, listener); AlsaMixer *am = new AlsaMixer(event_loop, listener);
am->Configure(param); am->Configure(block);
return am; return am;
} }

View File

@ -55,7 +55,7 @@ static Mixer *
null_mixer_init(gcc_unused EventLoop &event_loop, null_mixer_init(gcc_unused EventLoop &event_loop,
gcc_unused AudioOutput &ao, gcc_unused AudioOutput &ao,
MixerListener &listener, MixerListener &listener,
gcc_unused const config_param &param, gcc_unused const ConfigBlock &block,
gcc_unused Error &error) gcc_unused Error &error)
{ {
return new NullMixer(listener); return new NullMixer(listener);

View File

@ -19,7 +19,7 @@
#include "config.h" #include "config.h"
#include "mixer/MixerInternal.hxx" #include "mixer/MixerInternal.hxx"
#include "config/Param.hxx" #include "config/Block.hxx"
#include "system/fd_util.h" #include "system/fd_util.h"
#include "util/ASCII.hxx" #include "util/ASCII.hxx"
#include "util/Error.hxx" #include "util/Error.hxx"
@ -52,7 +52,7 @@ public:
OssMixer(MixerListener &_listener) OssMixer(MixerListener &_listener)
:Mixer(oss_mixer_plugin, _listener) {} :Mixer(oss_mixer_plugin, _listener) {}
bool Configure(const config_param &param, Error &error); bool Configure(const ConfigBlock &block, Error &error);
/* virtual methods from class Mixer */ /* virtual methods from class Mixer */
virtual bool Open(Error &error) override; virtual bool Open(Error &error) override;
@ -79,10 +79,10 @@ oss_find_mixer(const char *name)
} }
inline bool inline bool
OssMixer::Configure(const config_param &param, Error &error) OssMixer::Configure(const ConfigBlock &block, Error &error)
{ {
device = param.GetBlockValue("mixer_device", VOLUME_MIXER_OSS_DEFAULT); device = block.GetBlockValue("mixer_device", VOLUME_MIXER_OSS_DEFAULT);
control = param.GetBlockValue("mixer_control"); control = block.GetBlockValue("mixer_control");
if (control != NULL) { if (control != NULL) {
volume_control = oss_find_mixer(control); volume_control = oss_find_mixer(control);
@ -100,12 +100,12 @@ OssMixer::Configure(const config_param &param, Error &error)
static Mixer * static Mixer *
oss_mixer_init(gcc_unused EventLoop &event_loop, gcc_unused AudioOutput &ao, oss_mixer_init(gcc_unused EventLoop &event_loop, gcc_unused AudioOutput &ao,
MixerListener &listener, MixerListener &listener,
const config_param &param, const ConfigBlock &block,
Error &error) Error &error)
{ {
OssMixer *om = new OssMixer(listener); OssMixer *om = new OssMixer(listener);
if (!om->Configure(param, error)) { if (!om->Configure(block, error)) {
delete om; delete om;
return nullptr; return nullptr;
} }

View File

@ -163,7 +163,7 @@ pulse_mixer_on_change(PulseMixer &pm,
static Mixer * static Mixer *
pulse_mixer_init(gcc_unused EventLoop &event_loop, AudioOutput &ao, pulse_mixer_init(gcc_unused EventLoop &event_loop, AudioOutput &ao,
MixerListener &listener, MixerListener &listener,
gcc_unused const config_param &param, gcc_unused const ConfigBlock &block,
gcc_unused Error &error) gcc_unused Error &error)
{ {
PulseOutput &po = (PulseOutput &)ao; PulseOutput &po = (PulseOutput &)ao;

View File

@ -48,7 +48,7 @@ public:
static Mixer * static Mixer *
roar_mixer_init(gcc_unused EventLoop &event_loop, AudioOutput &ao, roar_mixer_init(gcc_unused EventLoop &event_loop, AudioOutput &ao,
MixerListener &listener, MixerListener &listener,
gcc_unused const config_param &param, gcc_unused const ConfigBlock &block,
gcc_unused Error &error) gcc_unused Error &error)
{ {
return new RoarMixer((RoarOutput &)ao, listener); return new RoarMixer((RoarOutput &)ao, listener);

View File

@ -25,7 +25,7 @@
#include "filter/FilterInternal.hxx" #include "filter/FilterInternal.hxx"
#include "filter/plugins/VolumeFilterPlugin.hxx" #include "filter/plugins/VolumeFilterPlugin.hxx"
#include "pcm/Volume.hxx" #include "pcm/Volume.hxx"
#include "config/Param.hxx" #include "config/Block.hxx"
#include "util/Error.hxx" #include "util/Error.hxx"
#include <assert.h> #include <assert.h>
@ -34,7 +34,7 @@
static Filter * static Filter *
CreateVolumeFilter() CreateVolumeFilter()
{ {
return filter_new(&volume_filter_plugin, config_param(), return filter_new(&volume_filter_plugin, ConfigBlock(),
IgnoreError()); IgnoreError());
} }
@ -90,7 +90,7 @@ static Mixer *
software_mixer_init(gcc_unused EventLoop &event_loop, software_mixer_init(gcc_unused EventLoop &event_loop,
gcc_unused AudioOutput &ao, gcc_unused AudioOutput &ao,
MixerListener &listener, MixerListener &listener,
gcc_unused const config_param &param, gcc_unused const ConfigBlock &block,
gcc_unused Error &error) gcc_unused Error &error)
{ {
return new SoftwareMixer(listener); return new SoftwareMixer(listener);

View File

@ -69,7 +69,7 @@ winmm_volume_encode(int volume)
static Mixer * static Mixer *
winmm_mixer_init(gcc_unused EventLoop &event_loop, AudioOutput &ao, winmm_mixer_init(gcc_unused EventLoop &event_loop, AudioOutput &ao,
MixerListener &listener, MixerListener &listener,
gcc_unused const config_param &param, gcc_unused const ConfigBlock &block,
gcc_unused Error &error) gcc_unused Error &error)
{ {
return new WinmmMixer((WinmmOutput &)ao, listener); return new WinmmMixer((WinmmOutput &)ao, listener);

View File

@ -24,8 +24,8 @@
#include "NeighborPlugin.hxx" #include "NeighborPlugin.hxx"
#include "Info.hxx" #include "Info.hxx"
#include "config/ConfigGlobal.hxx" #include "config/ConfigGlobal.hxx"
#include "config/Param.hxx"
#include "config/ConfigError.hxx" #include "config/ConfigError.hxx"
#include "config/Block.hxx"
#include "util/Error.hxx" #include "util/Error.hxx"
NeighborGlue::Explorer::~Explorer() NeighborGlue::Explorer::~Explorer()
@ -37,9 +37,9 @@ NeighborGlue::~NeighborGlue() {}
static NeighborExplorer * static NeighborExplorer *
CreateNeighborExplorer(EventLoop &loop, NeighborListener &listener, CreateNeighborExplorer(EventLoop &loop, NeighborListener &listener,
const config_param &param, Error &error) const ConfigBlock &block, Error &error)
{ {
const char *plugin_name = param.GetBlockValue("plugin"); const char *plugin_name = block.GetBlockValue("plugin");
if (plugin_name == nullptr) { if (plugin_name == nullptr) {
error.Set(config_domain, error.Set(config_domain,
"Missing \"plugin\" configuration"); "Missing \"plugin\" configuration");
@ -53,18 +53,18 @@ CreateNeighborExplorer(EventLoop &loop, NeighborListener &listener,
return nullptr; return nullptr;
} }
return plugin->create(loop, listener, param, error); return plugin->create(loop, listener, block, error);
} }
bool bool
NeighborGlue::Init(EventLoop &loop, NeighborListener &listener, Error &error) NeighborGlue::Init(EventLoop &loop, NeighborListener &listener, Error &error)
{ {
for (const auto *param = config_get_param(ConfigOption::NEIGHBORS); for (const auto *block = config_get_block(ConfigBlockOption::NEIGHBORS);
param != nullptr; param = param->next) { block != nullptr; block = block->next) {
NeighborExplorer *explorer = NeighborExplorer *explorer =
CreateNeighborExplorer(loop, listener, *param, error); CreateNeighborExplorer(loop, listener, *block, error);
if (explorer == nullptr) { if (explorer == nullptr) {
error.FormatPrefix("Line %i: ", param->line); error.FormatPrefix("Line %i: ", block->line);
return false; return false;
} }

View File

@ -20,7 +20,7 @@
#ifndef MPD_NEIGHBOR_PLUGIN_HXX #ifndef MPD_NEIGHBOR_PLUGIN_HXX
#define MPD_NEIGHBOR_PLUGIN_HXX #define MPD_NEIGHBOR_PLUGIN_HXX
struct config_param; struct ConfigBlock;
class Error; class Error;
class EventLoop; class EventLoop;
class NeighborListener; class NeighborListener;
@ -33,7 +33,7 @@ struct NeighborPlugin {
* Allocates and configures a #NeighborExplorer instance. * Allocates and configures a #NeighborExplorer instance.
*/ */
NeighborExplorer *(*create)(EventLoop &loop, NeighborListener &listener, NeighborExplorer *(*create)(EventLoop &loop, NeighborListener &listener,
const config_param &param, const ConfigBlock &block,
Error &error); Error &error);
}; };

View File

@ -273,7 +273,7 @@ SmbclientNeighborExplorer::ThreadFunc(void *ctx)
static NeighborExplorer * static NeighborExplorer *
smbclient_neighbor_create(gcc_unused EventLoop &loop, smbclient_neighbor_create(gcc_unused EventLoop &loop,
NeighborListener &listener, NeighborListener &listener,
gcc_unused const config_param &param, gcc_unused const ConfigBlock &block,
gcc_unused Error &error) gcc_unused Error &error)
{ {
if (!SmbclientInit(error)) if (!SmbclientInit(error))

View File

@ -127,7 +127,7 @@ UpnpNeighborExplorer::LostUPnP(const ContentDirectoryService &service)
static NeighborExplorer * static NeighborExplorer *
upnp_neighbor_create(gcc_unused EventLoop &loop, upnp_neighbor_create(gcc_unused EventLoop &loop,
NeighborListener &listener, NeighborListener &listener,
gcc_unused const config_param &param, gcc_unused const ConfigBlock &block,
gcc_unused Error &error) gcc_unused Error &error)
{ {
return new UpnpNeighborExplorer(listener); return new UpnpNeighborExplorer(listener);

View File

@ -35,6 +35,7 @@
#include "filter/plugins/ChainFilterPlugin.hxx" #include "filter/plugins/ChainFilterPlugin.hxx"
#include "config/ConfigError.hxx" #include "config/ConfigError.hxx"
#include "config/ConfigGlobal.hxx" #include "config/ConfigGlobal.hxx"
#include "config/Block.hxx"
#include "util/Error.hxx" #include "util/Error.hxx"
#include "Log.hxx" #include "Log.hxx"
@ -95,15 +96,15 @@ audio_output_detect(Error &error)
*/ */
gcc_pure gcc_pure
static MixerType static MixerType
audio_output_mixer_type(const config_param &param) audio_output_mixer_type(const ConfigBlock &block)
{ {
/* read the local "mixer_type" setting */ /* read the local "mixer_type" setting */
const char *p = param.GetBlockValue("mixer_type"); const char *p = block.GetBlockValue("mixer_type");
if (p != nullptr) if (p != nullptr)
return mixer_type_parse(p); return mixer_type_parse(p);
/* try the local "mixer_enabled" setting next (deprecated) */ /* try the local "mixer_enabled" setting next (deprecated) */
if (!param.GetBlockValue("mixer_enabled", true)) if (!block.GetBlockValue("mixer_enabled", true))
return MixerType::NONE; return MixerType::NONE;
/* fall back to the global "mixer_type" setting (also /* fall back to the global "mixer_type" setting (also
@ -114,7 +115,7 @@ audio_output_mixer_type(const config_param &param)
static Mixer * static Mixer *
audio_output_load_mixer(EventLoop &event_loop, AudioOutput &ao, audio_output_load_mixer(EventLoop &event_loop, AudioOutput &ao,
const config_param &param, const ConfigBlock &block,
const MixerPlugin *plugin, const MixerPlugin *plugin,
Filter &filter_chain, Filter &filter_chain,
MixerListener &listener, MixerListener &listener,
@ -122,26 +123,26 @@ audio_output_load_mixer(EventLoop &event_loop, AudioOutput &ao,
{ {
Mixer *mixer; Mixer *mixer;
switch (audio_output_mixer_type(param)) { switch (audio_output_mixer_type(block)) {
case MixerType::NONE: case MixerType::NONE:
case MixerType::UNKNOWN: case MixerType::UNKNOWN:
return nullptr; return nullptr;
case MixerType::NULL_: case MixerType::NULL_:
return mixer_new(event_loop, null_mixer_plugin, ao, listener, return mixer_new(event_loop, null_mixer_plugin, ao, listener,
param, error); block, error);
case MixerType::HARDWARE: case MixerType::HARDWARE:
if (plugin == nullptr) if (plugin == nullptr)
return nullptr; return nullptr;
return mixer_new(event_loop, *plugin, ao, listener, return mixer_new(event_loop, *plugin, ao, listener,
param, error); block, error);
case MixerType::SOFTWARE: case MixerType::SOFTWARE:
mixer = mixer_new(event_loop, software_mixer_plugin, ao, mixer = mixer_new(event_loop, software_mixer_plugin, ao,
listener, listener,
config_param(), ConfigBlock(),
IgnoreError()); IgnoreError());
assert(mixer != nullptr); assert(mixer != nullptr);
@ -155,17 +156,17 @@ audio_output_load_mixer(EventLoop &event_loop, AudioOutput &ao,
} }
bool bool
AudioOutput::Configure(const config_param &param, Error &error) AudioOutput::Configure(const ConfigBlock &block, Error &error)
{ {
if (!param.IsNull()) { if (!block.IsNull()) {
name = param.GetBlockValue(AUDIO_OUTPUT_NAME); name = block.GetBlockValue(AUDIO_OUTPUT_NAME);
if (name == nullptr) { if (name == nullptr) {
error.Set(config_domain, error.Set(config_domain,
"Missing \"name\" configuration"); "Missing \"name\" configuration");
return false; return false;
} }
const char *p = param.GetBlockValue(AUDIO_OUTPUT_FORMAT); const char *p = block.GetBlockValue(AUDIO_OUTPUT_FORMAT);
if (p != nullptr) { if (p != nullptr) {
bool success = bool success =
audio_format_parse(config_audio_format, audio_format_parse(config_audio_format,
@ -180,9 +181,9 @@ AudioOutput::Configure(const config_param &param, Error &error)
config_audio_format.Clear(); config_audio_format.Clear();
} }
tags = param.GetBlockValue("tags", true); tags = block.GetBlockValue("tags", true);
always_on = param.GetBlockValue("always_on", false); always_on = block.GetBlockValue("always_on", false);
enabled = param.GetBlockValue("enabled", true); enabled = block.GetBlockValue("enabled", true);
/* set up the filter chain */ /* set up the filter chain */
@ -193,7 +194,7 @@ AudioOutput::Configure(const config_param &param, Error &error)
if (config_get_bool(ConfigOption::VOLUME_NORMALIZATION, false)) { if (config_get_bool(ConfigOption::VOLUME_NORMALIZATION, false)) {
Filter *normalize_filter = Filter *normalize_filter =
filter_new(&normalize_filter_plugin, config_param(), filter_new(&normalize_filter_plugin, ConfigBlock(),
IgnoreError()); IgnoreError());
assert(normalize_filter != nullptr); assert(normalize_filter != nullptr);
@ -203,7 +204,7 @@ AudioOutput::Configure(const config_param &param, Error &error)
Error filter_error; Error filter_error;
filter_chain_parse(*filter, filter_chain_parse(*filter,
param.GetBlockValue(AUDIO_FILTERS, ""), block.GetBlockValue(AUDIO_FILTERS, ""),
filter_error); filter_error);
// It's not really fatal - Part of the filter chain has been set up already // It's not really fatal - Part of the filter chain has been set up already
@ -221,24 +222,24 @@ AudioOutput::Configure(const config_param &param, Error &error)
static bool static bool
audio_output_setup(EventLoop &event_loop, AudioOutput &ao, audio_output_setup(EventLoop &event_loop, AudioOutput &ao,
MixerListener &mixer_listener, MixerListener &mixer_listener,
const config_param &param, const ConfigBlock &block,
Error &error) Error &error)
{ {
/* create the replay_gain filter */ /* create the replay_gain filter */
const char *replay_gain_handler = const char *replay_gain_handler =
param.GetBlockValue("replay_gain_handler", "software"); block.GetBlockValue("replay_gain_handler", "software");
if (strcmp(replay_gain_handler, "none") != 0) { if (strcmp(replay_gain_handler, "none") != 0) {
ao.replay_gain_filter = filter_new(&replay_gain_filter_plugin, ao.replay_gain_filter = filter_new(&replay_gain_filter_plugin,
param, IgnoreError()); block, IgnoreError());
assert(ao.replay_gain_filter != nullptr); assert(ao.replay_gain_filter != nullptr);
ao.replay_gain_serial = 0; ao.replay_gain_serial = 0;
ao.other_replay_gain_filter = filter_new(&replay_gain_filter_plugin, ao.other_replay_gain_filter = filter_new(&replay_gain_filter_plugin,
param, block,
IgnoreError()); IgnoreError());
assert(ao.other_replay_gain_filter != nullptr); assert(ao.other_replay_gain_filter != nullptr);
@ -251,7 +252,7 @@ audio_output_setup(EventLoop &event_loop, AudioOutput &ao,
/* set up the mixer */ /* set up the mixer */
Error mixer_error; Error mixer_error;
ao.mixer = audio_output_load_mixer(event_loop, ao, param, ao.mixer = audio_output_load_mixer(event_loop, ao, block,
ao.plugin.mixer_plugin, ao.plugin.mixer_plugin,
*ao.filter, *ao.filter,
mixer_listener, mixer_listener,
@ -279,7 +280,7 @@ audio_output_setup(EventLoop &event_loop, AudioOutput &ao,
/* the "convert" filter must be the last one in the chain */ /* the "convert" filter must be the last one in the chain */
ao.convert_filter = filter_new(&convert_filter_plugin, config_param(), ao.convert_filter = filter_new(&convert_filter_plugin, ConfigBlock(),
IgnoreError()); IgnoreError());
assert(ao.convert_filter != nullptr); assert(ao.convert_filter != nullptr);
@ -289,17 +290,17 @@ audio_output_setup(EventLoop &event_loop, AudioOutput &ao,
} }
AudioOutput * AudioOutput *
audio_output_new(EventLoop &event_loop, const config_param &param, audio_output_new(EventLoop &event_loop, const ConfigBlock &block,
MixerListener &mixer_listener, MixerListener &mixer_listener,
PlayerControl &pc, PlayerControl &pc,
Error &error) Error &error)
{ {
const AudioOutputPlugin *plugin; const AudioOutputPlugin *plugin;
if (!param.IsNull()) { if (!block.IsNull()) {
const char *p; const char *p;
p = param.GetBlockValue(AUDIO_OUTPUT_TYPE); p = block.GetBlockValue(AUDIO_OUTPUT_TYPE);
if (p == nullptr) { if (p == nullptr) {
error.Set(config_domain, error.Set(config_domain,
"Missing \"type\" configuration"); "Missing \"type\" configuration");
@ -325,12 +326,12 @@ audio_output_new(EventLoop &event_loop, const config_param &param,
plugin->name); plugin->name);
} }
AudioOutput *ao = ao_plugin_init(plugin, param, error); AudioOutput *ao = ao_plugin_init(plugin, block, error);
if (ao == nullptr) if (ao == nullptr)
return nullptr; return nullptr;
if (!audio_output_setup(event_loop, *ao, mixer_listener, if (!audio_output_setup(event_loop, *ao, mixer_listener,
param, error)) { block, error)) {
ao_plugin_finish(ao); ao_plugin_finish(ao);
return nullptr; return nullptr;
} }

View File

@ -36,7 +36,7 @@ class EventLoop;
class Mixer; class Mixer;
class MixerListener; class MixerListener;
struct MusicChunk; struct MusicChunk;
struct config_param; struct ConfigBlock;
struct PlayerControl; struct PlayerControl;
struct AudioOutputPlugin; struct AudioOutputPlugin;
@ -272,7 +272,7 @@ struct AudioOutput {
AudioOutput(const AudioOutputPlugin &_plugin); AudioOutput(const AudioOutputPlugin &_plugin);
~AudioOutput(); ~AudioOutput();
bool Configure(const config_param &param, Error &error); bool Configure(const ConfigBlock &block, Error &error);
void StartThread(); void StartThread();
void StopThread(); void StopThread();
@ -430,7 +430,7 @@ private:
extern struct notify audio_output_client_notify; extern struct notify audio_output_client_notify;
AudioOutput * AudioOutput *
audio_output_new(EventLoop &event_loop, const config_param &param, audio_output_new(EventLoop &event_loop, const ConfigBlock &block,
MixerListener &mixer_listener, MixerListener &mixer_listener,
PlayerControl &pc, PlayerControl &pc,
Error &error); Error &error);

View File

@ -27,7 +27,7 @@
#include "MusicChunk.hxx" #include "MusicChunk.hxx"
#include "system/FatalError.hxx" #include "system/FatalError.hxx"
#include "util/Error.hxx" #include "util/Error.hxx"
#include "config/Param.hxx" #include "config/Block.hxx"
#include "config/ConfigGlobal.hxx" #include "config/ConfigGlobal.hxx"
#include "config/ConfigOption.hxx" #include "config/ConfigOption.hxx"
#include "notify.hxx" #include "notify.hxx"
@ -53,16 +53,16 @@ MultipleOutputs::~MultipleOutputs()
static AudioOutput * static AudioOutput *
LoadOutput(EventLoop &event_loop, MixerListener &mixer_listener, LoadOutput(EventLoop &event_loop, MixerListener &mixer_listener,
PlayerControl &pc, const config_param &param) PlayerControl &pc, const ConfigBlock &block)
{ {
Error error; Error error;
AudioOutput *output = audio_output_new(event_loop, param, AudioOutput *output = audio_output_new(event_loop, block,
mixer_listener, mixer_listener,
pc, error); pc, error);
if (output == nullptr) { if (output == nullptr) {
if (param.line > 0) if (block.line > 0)
FormatFatalError("line %i: %s", FormatFatalError("line %i: %s",
param.line, block.line,
error.GetMessage()); error.GetMessage());
else else
FatalError(error); FatalError(error);
@ -74,7 +74,7 @@ LoadOutput(EventLoop &event_loop, MixerListener &mixer_listener,
void void
MultipleOutputs::Configure(EventLoop &event_loop, PlayerControl &pc) MultipleOutputs::Configure(EventLoop &event_loop, PlayerControl &pc)
{ {
for (const auto *param = config_get_param(ConfigOption::AUDIO_OUTPUT); for (const auto *param = config_get_block(ConfigBlockOption::AUDIO_OUTPUT);
param != nullptr; param = param->next) { param != nullptr; param = param->next) {
auto output = LoadOutput(event_loop, mixer_listener, auto output = LoadOutput(event_loop, mixer_listener,
pc, *param); pc, *param);
@ -87,7 +87,7 @@ MultipleOutputs::Configure(EventLoop &event_loop, PlayerControl &pc)
if (outputs.empty()) { if (outputs.empty()) {
/* auto-detect device */ /* auto-detect device */
const config_param empty; const ConfigBlock empty;
auto output = LoadOutput(event_loop, mixer_listener, auto output = LoadOutput(event_loop, mixer_listener,
pc, empty); pc, empty);
outputs.push_back(output); outputs.push_back(output);

View File

@ -26,7 +26,7 @@
#include "Internal.hxx" #include "Internal.hxx"
#include "AudioFormat.hxx" #include "AudioFormat.hxx"
#include "tag/Tag.hxx" #include "tag/Tag.hxx"
#include "config/Param.hxx" #include "config/Block.hxx"
// IWYU pragma: end_exports // IWYU pragma: end_exports

View File

@ -23,13 +23,13 @@
AudioOutput * AudioOutput *
ao_plugin_init(const AudioOutputPlugin *plugin, ao_plugin_init(const AudioOutputPlugin *plugin,
const config_param &param, const ConfigBlock &block,
Error &error) Error &error)
{ {
assert(plugin != nullptr); assert(plugin != nullptr);
assert(plugin->init != nullptr); assert(plugin->init != nullptr);
return plugin->init(param, error); return plugin->init(block, error);
} }
void void

View File

@ -24,7 +24,7 @@
#include <stddef.h> #include <stddef.h>
struct config_param; struct ConfigBlock;
struct AudioFormat; struct AudioFormat;
struct Tag; struct Tag;
struct AudioOutput; struct AudioOutput;
@ -55,8 +55,7 @@ struct AudioOutputPlugin {
* @return nullptr on error, or an opaque pointer to the plugin's * @return nullptr on error, or an opaque pointer to the plugin's
* data * data
*/ */
AudioOutput *(*init)(const config_param &param, AudioOutput *(*init)(const ConfigBlock &block, Error &error);
Error &error);
/** /**
* Free resources allocated by this device. * Free resources allocated by this device.
@ -162,7 +161,7 @@ ao_plugin_test_default_device(const AudioOutputPlugin *plugin)
gcc_malloc gcc_malloc
AudioOutput * AudioOutput *
ao_plugin_init(const AudioOutputPlugin *plugin, ao_plugin_init(const AudioOutputPlugin *plugin,
const config_param &param, const ConfigBlock &block,
Error &error); Error &error);
void void

View File

@ -22,14 +22,16 @@
#include "util/Cast.hxx" #include "util/Cast.hxx"
struct ConfigBlock;
template<class T> template<class T>
struct AudioOutputWrapper { struct AudioOutputWrapper {
static T &Cast(AudioOutput &ao) { static T &Cast(AudioOutput &ao) {
return ContainerCast(ao, &T::base); return ContainerCast(ao, &T::base);
} }
static AudioOutput *Init(const config_param &param, Error &error) { static AudioOutput *Init(const ConfigBlock &block, Error &error) {
T *t = T::Create(param, error); T *t = T::Create(block, error);
return t != nullptr return t != nullptr
? &t->base ? &t->base
: nullptr; : nullptr;

View File

@ -142,8 +142,8 @@ struct AlsaOutput {
return device.empty() ? default_device : device.c_str(); return device.empty() ? default_device : device.c_str();
} }
bool Configure(const config_param &param, Error &error); bool Configure(const ConfigBlock &block, Error &error);
static AlsaOutput *Create(const config_param &param, Error &error); static AlsaOutput *Create(const ConfigBlock &block, Error &error);
bool Enable(Error &error); bool Enable(Error &error);
void Disable(); void Disable();
@ -175,35 +175,35 @@ private:
static constexpr Domain alsa_output_domain("alsa_output"); static constexpr Domain alsa_output_domain("alsa_output");
inline bool inline bool
AlsaOutput::Configure(const config_param &param, Error &error) AlsaOutput::Configure(const ConfigBlock &block, Error &error)
{ {
if (!base.Configure(param, error)) if (!base.Configure(block, error))
return false; return false;
device = param.GetBlockValue("device", ""); device = block.GetBlockValue("device", "");
use_mmap = param.GetBlockValue("use_mmap", false); use_mmap = block.GetBlockValue("use_mmap", false);
dop = param.GetBlockValue("dop", false) || dop = block.GetBlockValue("dop", false) ||
/* legacy name from MPD 0.18 and older: */ /* legacy name from MPD 0.18 and older: */
param.GetBlockValue("dsd_usb", false); block.GetBlockValue("dsd_usb", false);
buffer_time = param.GetBlockValue("buffer_time", buffer_time = block.GetBlockValue("buffer_time",
MPD_ALSA_BUFFER_TIME_US); MPD_ALSA_BUFFER_TIME_US);
period_time = param.GetBlockValue("period_time", 0u); period_time = block.GetBlockValue("period_time", 0u);
#ifdef SND_PCM_NO_AUTO_RESAMPLE #ifdef SND_PCM_NO_AUTO_RESAMPLE
if (!param.GetBlockValue("auto_resample", true)) if (!block.GetBlockValue("auto_resample", true))
mode |= SND_PCM_NO_AUTO_RESAMPLE; mode |= SND_PCM_NO_AUTO_RESAMPLE;
#endif #endif
#ifdef SND_PCM_NO_AUTO_CHANNELS #ifdef SND_PCM_NO_AUTO_CHANNELS
if (!param.GetBlockValue("auto_channels", true)) if (!block.GetBlockValue("auto_channels", true))
mode |= SND_PCM_NO_AUTO_CHANNELS; mode |= SND_PCM_NO_AUTO_CHANNELS;
#endif #endif
#ifdef SND_PCM_NO_AUTO_FORMAT #ifdef SND_PCM_NO_AUTO_FORMAT
if (!param.GetBlockValue("auto_format", true)) if (!block.GetBlockValue("auto_format", true))
mode |= SND_PCM_NO_AUTO_FORMAT; mode |= SND_PCM_NO_AUTO_FORMAT;
#endif #endif
@ -211,11 +211,11 @@ AlsaOutput::Configure(const config_param &param, Error &error)
} }
inline AlsaOutput * inline AlsaOutput *
AlsaOutput::Create(const config_param &param, Error &error) AlsaOutput::Create(const ConfigBlock &block, Error &error)
{ {
AlsaOutput *ad = new AlsaOutput(); AlsaOutput *ad = new AlsaOutput();
if (!ad->Configure(param, error)) { if (!ad->Configure(block, error)) {
delete ad; delete ad;
return nullptr; return nullptr;
} }

View File

@ -46,11 +46,11 @@ struct AoOutput {
AoOutput() AoOutput()
:base(ao_output_plugin) {} :base(ao_output_plugin) {}
bool Initialize(const config_param &param, Error &error) { bool Initialize(const ConfigBlock &block, Error &error) {
return base.Configure(param, error); return base.Configure(block, error);
} }
bool Configure(const config_param &param, Error &error); bool Configure(const ConfigBlock &block, Error &error);
}; };
static constexpr Domain ao_output_domain("ao_output"); static constexpr Domain ao_output_domain("ao_output");
@ -90,20 +90,20 @@ ao_output_error(Error &error_r)
} }
inline bool inline bool
AoOutput::Configure(const config_param &param, Error &error) AoOutput::Configure(const ConfigBlock &block, Error &error)
{ {
const char *value; const char *value;
options = nullptr; options = nullptr;
write_size = param.GetBlockValue("write_size", 1024u); write_size = block.GetBlockValue("write_size", 1024u);
if (ao_output_ref == 0) { if (ao_output_ref == 0) {
ao_initialize(); ao_initialize();
} }
ao_output_ref++; ao_output_ref++;
value = param.GetBlockValue("driver", "default"); value = block.GetBlockValue("driver", "default");
if (0 == strcmp(value, "default")) if (0 == strcmp(value, "default"))
driver = ao_default_driver_id(); driver = ao_default_driver_id();
else else
@ -123,9 +123,9 @@ AoOutput::Configure(const config_param &param, Error &error)
} }
FormatDebug(ao_output_domain, "using ao driver \"%s\" for \"%s\"\n", FormatDebug(ao_output_domain, "using ao driver \"%s\" for \"%s\"\n",
ai->short_name, param.GetBlockValue("name", nullptr)); ai->short_name, block.GetBlockValue("name", nullptr));
value = param.GetBlockValue("options", nullptr); value = block.GetBlockValue("options", nullptr);
if (value != nullptr) { if (value != nullptr) {
for (const auto &i : SplitString(value, ';')) { for (const auto &i : SplitString(value, ';')) {
const DivideString ss(i.c_str(), '=', true); const DivideString ss(i.c_str(), '=', true);
@ -145,16 +145,16 @@ AoOutput::Configure(const config_param &param, Error &error)
} }
static AudioOutput * static AudioOutput *
ao_output_init(const config_param &param, Error &error) ao_output_init(const ConfigBlock &block, Error &error)
{ {
AoOutput *ad = new AoOutput(); AoOutput *ad = new AoOutput();
if (!ad->Initialize(param, error)) { if (!ad->Initialize(block, error)) {
delete ad; delete ad;
return nullptr; return nullptr;
} }
if (!ad->Configure(param, error)) { if (!ad->Configure(block, error)) {
delete ad; delete ad;
return nullptr; return nullptr;
} }

View File

@ -51,8 +51,8 @@ struct FifoOutput {
path(AllocatedPath::Null()), input(-1), output(-1), path(AllocatedPath::Null()), input(-1), output(-1),
created(false) {} created(false) {}
bool Initialize(const config_param &param, Error &error) { bool Initialize(const ConfigBlock &block, Error &error) {
return base.Configure(param, error); return base.Configure(block, error);
} }
bool Create(Error &error); bool Create(Error &error);
@ -169,11 +169,11 @@ fifo_open(FifoOutput *fd, Error &error)
} }
static AudioOutput * static AudioOutput *
fifo_output_init(const config_param &param, Error &error) fifo_output_init(const ConfigBlock &block, Error &error)
{ {
FifoOutput *fd = new FifoOutput(); FifoOutput *fd = new FifoOutput();
fd->path = param.GetBlockPath("path", error); fd->path = block.GetBlockPath("path", error);
if (fd->path.IsNull()) { if (fd->path.IsNull()) {
delete fd; delete fd;
@ -185,7 +185,7 @@ fifo_output_init(const config_param &param, Error &error)
fd->path_utf8 = fd->path.ToUTF8(); fd->path_utf8 = fd->path.ToUTF8();
if (!fd->Initialize(param, error)) { if (!fd->Initialize(block, error)) {
delete fd; delete fd;
return nullptr; return nullptr;
} }

View File

@ -83,7 +83,7 @@ struct JackOutput {
JackOutput() JackOutput()
:base(jack_output_plugin) {} :base(jack_output_plugin) {}
bool Configure(const config_param &param, Error &error); bool Configure(const ConfigBlock &block, Error &error);
bool Connect(Error &error); bool Connect(Error &error);
@ -376,14 +376,14 @@ parse_port_list(const char *source, std::string dest[], Error &error)
} }
bool bool
JackOutput::Configure(const config_param &param, Error &error) JackOutput::Configure(const ConfigBlock &block, Error &error)
{ {
if (!base.Configure(param, error)) if (!base.Configure(block, error))
return false; return false;
options = JackNullOption; options = JackNullOption;
name = param.GetBlockValue("client_name", nullptr); name = block.GetBlockValue("client_name", nullptr);
if (name != nullptr) if (name != nullptr)
options = jack_options_t(options | JackUseExactName); options = jack_options_t(options | JackUseExactName);
else else
@ -391,30 +391,30 @@ JackOutput::Configure(const config_param &param, Error &error)
care about the JackUseExactName option */ care about the JackUseExactName option */
name = "Music Player Daemon"; name = "Music Player Daemon";
server_name = param.GetBlockValue("server_name", nullptr); server_name = block.GetBlockValue("server_name", nullptr);
if (server_name != nullptr) if (server_name != nullptr)
options = jack_options_t(options | JackServerName); options = jack_options_t(options | JackServerName);
if (!param.GetBlockValue("autostart", false)) if (!block.GetBlockValue("autostart", false))
options = jack_options_t(options | JackNoStartServer); options = jack_options_t(options | JackNoStartServer);
/* configure the source ports */ /* configure the source ports */
const char *value = param.GetBlockValue("source_ports", "left,right"); const char *value = block.GetBlockValue("source_ports", "left,right");
num_source_ports = parse_port_list(value, source_ports, error); num_source_ports = parse_port_list(value, source_ports, error);
if (num_source_ports == 0) if (num_source_ports == 0)
return false; return false;
/* configure the destination ports */ /* configure the destination ports */
value = param.GetBlockValue("destination_ports", nullptr); value = block.GetBlockValue("destination_ports", nullptr);
if (value == nullptr) { if (value == nullptr) {
/* compatibility with MPD < 0.16 */ /* compatibility with MPD < 0.16 */
value = param.GetBlockValue("ports", nullptr); value = block.GetBlockValue("ports", nullptr);
if (value != nullptr) if (value != nullptr)
FormatWarning(jack_output_domain, FormatWarning(jack_output_domain,
"deprecated option 'ports' in line %d", "deprecated option 'ports' in line %d",
param.line); block.line);
} }
if (value != nullptr) { if (value != nullptr) {
@ -432,9 +432,9 @@ JackOutput::Configure(const config_param &param, Error &error)
"number of source ports (%u) mismatches the " "number of source ports (%u) mismatches the "
"number of destination ports (%u) in line %d", "number of destination ports (%u) in line %d",
num_source_ports, num_destination_ports, num_source_ports, num_destination_ports,
param.line); block.line);
ringbuffer_size = param.GetBlockValue("ringbuffer_size", 32768u); ringbuffer_size = block.GetBlockValue("ringbuffer_size", 32768u);
return true; return true;
} }
@ -463,11 +463,11 @@ JackOutput::Disable()
} }
static AudioOutput * static AudioOutput *
mpd_jack_init(const config_param &param, Error &error) mpd_jack_init(const ConfigBlock &block, Error &error)
{ {
JackOutput *jd = new JackOutput(); JackOutput *jd = new JackOutput();
if (!jd->Configure(param, error)) { if (!jd->Configure(block, error)) {
delete jd; delete jd;
return nullptr; return nullptr;
} }

View File

@ -36,11 +36,11 @@ public:
NullOutput() NullOutput()
:base(null_output_plugin) {} :base(null_output_plugin) {}
bool Initialize(const config_param &param, Error &error) { bool Initialize(const ConfigBlock &block, Error &error) {
return base.Configure(param, error); return base.Configure(block, error);
} }
static NullOutput *Create(const config_param &param, Error &error); static NullOutput *Create(const ConfigBlock &block, Error &error);
bool Open(AudioFormat &audio_format, gcc_unused Error &error) { bool Open(AudioFormat &audio_format, gcc_unused Error &error) {
if (sync) if (sync)
@ -78,16 +78,16 @@ public:
}; };
inline NullOutput * inline NullOutput *
NullOutput::Create(const config_param &param, Error &error) NullOutput::Create(const ConfigBlock &block, Error &error)
{ {
NullOutput *nd = new NullOutput(); NullOutput *nd = new NullOutput();
if (!nd->Initialize(param, error)) { if (!nd->Initialize(block, error)) {
delete nd; delete nd;
return nullptr; return nullptr;
} }
nd->sync = param.GetBlockValue("sync", true); nd->sync = block.GetBlockValue("sync", true);
return nd; return nd;
} }

View File

@ -61,9 +61,9 @@ osx_output_test_default_device(void)
} }
static void static void
osx_output_configure(OSXOutput *oo, const config_param &param) osx_output_configure(OSXOutput *oo, const ConfigBlock &block)
{ {
const char *device = param.GetBlockValue("device"); const char *device = block.GetBlockValue("device");
if (device == nullptr || 0 == strcmp(device, "default")) { if (device == nullptr || 0 == strcmp(device, "default")) {
oo->component_subtype = kAudioUnitSubType_DefaultOutput; oo->component_subtype = kAudioUnitSubType_DefaultOutput;
@ -81,15 +81,15 @@ osx_output_configure(OSXOutput *oo, const config_param &param)
} }
static AudioOutput * static AudioOutput *
osx_output_init(const config_param &param, Error &error) osx_output_init(const ConfigBlock &block, Error &error)
{ {
OSXOutput *oo = new OSXOutput(); OSXOutput *oo = new OSXOutput();
if (!oo->base.Configure(param, error)) { if (!oo->base.Configure(block, error)) {
delete oo; delete oo;
return nullptr; return nullptr;
} }
osx_output_configure(oo, param); osx_output_configure(oo, block);
return &oo->base; return &oo->base;
} }

View File

@ -54,9 +54,9 @@ class OpenALOutput {
OpenALOutput() OpenALOutput()
:base(openal_output_plugin) {} :base(openal_output_plugin) {}
bool Configure(const config_param &param, Error &error); bool Configure(const ConfigBlock &block, Error &error);
static OpenALOutput *Create(const config_param &param, Error &error); static OpenALOutput *Create(const ConfigBlock &block, Error &error);
bool Open(AudioFormat &audio_format, Error &error); bool Open(AudioFormat &audio_format, Error &error);
@ -150,12 +150,12 @@ OpenALOutput::SetupContext(Error &error)
} }
inline bool inline bool
OpenALOutput::Configure(const config_param &param, Error &error) OpenALOutput::Configure(const ConfigBlock &block, Error &error)
{ {
if (!base.Configure(param, error)) if (!base.Configure(block, error))
return false; return false;
device_name = param.GetBlockValue("device"); device_name = block.GetBlockValue("device");
if (device_name == nullptr) if (device_name == nullptr)
device_name = alcGetString(nullptr, device_name = alcGetString(nullptr,
ALC_DEFAULT_DEVICE_SPECIFIER); ALC_DEFAULT_DEVICE_SPECIFIER);
@ -164,11 +164,11 @@ OpenALOutput::Configure(const config_param &param, Error &error)
} }
inline OpenALOutput * inline OpenALOutput *
OpenALOutput::Create(const config_param &param, Error &error) OpenALOutput::Create(const ConfigBlock &block, Error &error)
{ {
OpenALOutput *oo = new OpenALOutput(); OpenALOutput *oo = new OpenALOutput();
if (!oo->Configure(param, error)) { if (!oo->Configure(block, error)) {
delete oo; delete oo;
return nullptr; return nullptr;
} }

View File

@ -87,11 +87,11 @@ public:
:base(oss_output_plugin), :base(oss_output_plugin),
fd(-1), device(_device) {} fd(-1), device(_device) {}
bool Initialize(const config_param &param, Error &error_r) { bool Initialize(const ConfigBlock &block, Error &error_r) {
return base.Configure(param, error_r); return base.Configure(block, error_r);
} }
static OssOutput *Create(const config_param &param, Error &error); static OssOutput *Create(const ConfigBlock &block, Error &error);
#ifdef AFMT_S24_PACKED #ifdef AFMT_S24_PACKED
bool Enable(gcc_unused Error &error) { bool Enable(gcc_unused Error &error) {
@ -192,7 +192,7 @@ oss_open_default(Error &error)
int err[ARRAY_SIZE(default_devices)]; int err[ARRAY_SIZE(default_devices)];
enum oss_stat ret[ARRAY_SIZE(default_devices)]; enum oss_stat ret[ARRAY_SIZE(default_devices)];
const config_param empty; const ConfigBlock empty;
for (int i = ARRAY_SIZE(default_devices); --i >= 0; ) { for (int i = ARRAY_SIZE(default_devices); --i >= 0; ) {
ret[i] = oss_stat_device(default_devices[i], &err[i]); ret[i] = oss_stat_device(default_devices[i], &err[i]);
if (ret[i] == OSS_STAT_NO_ERROR) { if (ret[i] == OSS_STAT_NO_ERROR) {
@ -236,12 +236,12 @@ oss_open_default(Error &error)
} }
inline OssOutput * inline OssOutput *
OssOutput::Create(const config_param &param, Error &error) OssOutput::Create(const ConfigBlock &block, Error &error)
{ {
const char *device = param.GetBlockValue("device"); const char *device = block.GetBlockValue("device");
if (device != nullptr) { if (device != nullptr) {
OssOutput *od = new OssOutput(); OssOutput *od = new OssOutput();
if (!od->Initialize(param, error)) { if (!od->Initialize(block, error)) {
delete od; delete od;
return nullptr; return nullptr;
} }

View File

@ -40,10 +40,10 @@ class PipeOutput {
PipeOutput() PipeOutput()
:base(pipe_output_plugin) {} :base(pipe_output_plugin) {}
bool Configure(const config_param &param, Error &error); bool Configure(const ConfigBlock &block, Error &error);
public: public:
static PipeOutput *Create(const config_param &param, Error &error); static PipeOutput *Create(const ConfigBlock &block, Error &error);
bool Open(AudioFormat &audio_format, Error &error); bool Open(AudioFormat &audio_format, Error &error);
@ -58,12 +58,12 @@ public:
static constexpr Domain pipe_output_domain("pipe_output"); static constexpr Domain pipe_output_domain("pipe_output");
inline bool inline bool
PipeOutput::Configure(const config_param &param, Error &error) PipeOutput::Configure(const ConfigBlock &block, Error &error)
{ {
if (!base.Configure(param, error)) if (!base.Configure(block, error))
return false; return false;
cmd = param.GetBlockValue("command", ""); cmd = block.GetBlockValue("command", "");
if (cmd.empty()) { if (cmd.empty()) {
error.Set(config_domain, error.Set(config_domain,
"No \"command\" parameter specified"); "No \"command\" parameter specified");
@ -74,11 +74,11 @@ PipeOutput::Configure(const config_param &param, Error &error)
} }
inline PipeOutput * inline PipeOutput *
PipeOutput::Create(const config_param &param, Error &error) PipeOutput::Create(const ConfigBlock &block, Error &error)
{ {
PipeOutput *po = new PipeOutput(); PipeOutput *po = new PipeOutput();
if (!po->Configure(param, error)) { if (!po->Configure(block, error)) {
delete po; delete po;
return nullptr; return nullptr;
} }

View File

@ -98,8 +98,8 @@ public:
gcc_const gcc_const
static bool TestDefaultDevice(); static bool TestDefaultDevice();
bool Configure(const config_param &param, Error &error); bool Configure(const ConfigBlock &block, Error &error);
static PulseOutput *Create(const config_param &param, Error &error); static PulseOutput *Create(const ConfigBlock &block, Error &error);
bool Enable(Error &error); bool Enable(Error &error);
void Disable(); void Disable();
@ -430,26 +430,26 @@ PulseOutput::SetupContext(Error &error)
} }
inline bool inline bool
PulseOutput::Configure(const config_param &param, Error &error) PulseOutput::Configure(const ConfigBlock &block, Error &error)
{ {
if (!base.Configure(param, error)) if (!base.Configure(block, error))
return false; return false;
name = param.GetBlockValue("name", "mpd_pulse"); name = block.GetBlockValue("name", "mpd_pulse");
server = param.GetBlockValue("server"); server = block.GetBlockValue("server");
sink = param.GetBlockValue("sink"); sink = block.GetBlockValue("sink");
return true; return true;
} }
PulseOutput * PulseOutput *
PulseOutput::Create(const config_param &param, Error &error) PulseOutput::Create(const ConfigBlock &block, Error &error)
{ {
setenv("PULSE_PROP_media.role", "music", true); setenv("PULSE_PROP_media.role", "music", true);
setenv("PULSE_PROP_application.icon_name", "mpd", true); setenv("PULSE_PROP_application.icon_name", "mpd", true);
auto *po = new PulseOutput(); auto *po = new PulseOutput();
if (!po->Configure(param, error)) { if (!po->Configure(block, error)) {
delete po; delete po;
return nullptr; return nullptr;
} }
@ -926,7 +926,7 @@ PulseOutput::Pause()
inline bool inline bool
PulseOutput::TestDefaultDevice() PulseOutput::TestDefaultDevice()
{ {
const config_param empty; const ConfigBlock empty;
PulseOutput *po = PulseOutput::Create(empty, IgnoreError()); PulseOutput *po = PulseOutput::Create(empty, IgnoreError());
if (po == nullptr) if (po == nullptr)
return false; return false;

View File

@ -81,13 +81,13 @@ class RecorderOutput {
encoder->Dispose(); encoder->Dispose();
} }
bool Initialize(const config_param &param, Error &error_r) { bool Initialize(const ConfigBlock &block, Error &error_r) {
return base.Configure(param, error_r); return base.Configure(block, error_r);
} }
static RecorderOutput *Create(const config_param &param, Error &error); static RecorderOutput *Create(const ConfigBlock &block, Error &error);
bool Configure(const config_param &param, Error &error); bool Configure(const ConfigBlock &block, Error &error);
bool Open(AudioFormat &audio_format, Error &error); bool Open(AudioFormat &audio_format, Error &error);
void Close(); void Close();
@ -117,12 +117,12 @@ private:
}; };
inline bool inline bool
RecorderOutput::Configure(const config_param &param, Error &error) RecorderOutput::Configure(const ConfigBlock &block, Error &error)
{ {
/* read configuration */ /* read configuration */
const char *encoder_name = const char *encoder_name =
param.GetBlockValue("encoder", "vorbis"); block.GetBlockValue("encoder", "vorbis");
const auto encoder_plugin = encoder_plugin_get(encoder_name); const auto encoder_plugin = encoder_plugin_get(encoder_name);
if (encoder_plugin == nullptr) { if (encoder_plugin == nullptr) {
error.Format(config_domain, error.Format(config_domain,
@ -130,11 +130,11 @@ RecorderOutput::Configure(const config_param &param, Error &error)
return false; return false;
} }
path = param.GetBlockPath("path", error); path = block.GetBlockPath("path", error);
if (error.IsDefined()) if (error.IsDefined())
return false; return false;
const char *fmt = param.GetBlockValue("format_path", nullptr); const char *fmt = block.GetBlockValue("format_path", nullptr);
if (fmt != nullptr) if (fmt != nullptr)
format_path = fmt; format_path = fmt;
@ -150,7 +150,7 @@ RecorderOutput::Configure(const config_param &param, Error &error)
/* initialize encoder */ /* initialize encoder */
encoder = encoder_init(*encoder_plugin, param, error); encoder = encoder_init(*encoder_plugin, block, error);
if (encoder == nullptr) if (encoder == nullptr)
return false; return false;
@ -158,16 +158,16 @@ RecorderOutput::Configure(const config_param &param, Error &error)
} }
RecorderOutput * RecorderOutput *
RecorderOutput::Create(const config_param &param, Error &error) RecorderOutput::Create(const ConfigBlock &block, Error &error)
{ {
RecorderOutput *recorder = new RecorderOutput(); RecorderOutput *recorder = new RecorderOutput();
if (!recorder->Initialize(param, error)) { if (!recorder->Initialize(block, error)) {
delete recorder; delete recorder;
return nullptr; return nullptr;
} }
if (!recorder->Configure(param, error)) { if (!recorder->Configure(block, error)) {
delete recorder; delete recorder;
return nullptr; return nullptr;
} }

View File

@ -60,11 +60,11 @@ public:
return &base; return &base;
} }
bool Initialize(const config_param &param, Error &error) { bool Initialize(const ConfigBlock &block, Error &error) {
return base.Configure(param, error); return base.Configure(block, error);
} }
void Configure(const config_param &param); void Configure(const ConfigBlock &block);
bool Open(AudioFormat &audio_format, Error &error); bool Open(AudioFormat &audio_format, Error &error);
void Close(); void Close();
@ -124,28 +124,28 @@ roar_output_set_volume(RoarOutput &roar, unsigned volume)
} }
inline void inline void
RoarOutput::Configure(const config_param &param) RoarOutput::Configure(const ConfigBlock &block)
{ {
host = param.GetBlockValue("server", ""); host = block.GetBlockValue("server", "");
name = param.GetBlockValue("name", "MPD"); name = block.GetBlockValue("name", "MPD");
const char *_role = param.GetBlockValue("role", "music"); const char *_role = block.GetBlockValue("role", "music");
role = _role != nullptr role = _role != nullptr
? roar_str2role(_role) ? roar_str2role(_role)
: ROAR_ROLE_MUSIC; : ROAR_ROLE_MUSIC;
} }
static AudioOutput * static AudioOutput *
roar_init(const config_param &param, Error &error) roar_init(const ConfigBlock &block, Error &error)
{ {
RoarOutput *self = new RoarOutput(); RoarOutput *self = new RoarOutput();
if (!self->Initialize(param, error)) { if (!self->Initialize(block, error)) {
delete self; delete self;
return nullptr; return nullptr;
} }
self->Configure(param); self->Configure(block);
return *self; return *self;
} }

View File

@ -68,11 +68,11 @@ struct ShoutOutput final {
shout_free(shout_conn); shout_free(shout_conn);
} }
bool Initialize(const config_param &param, Error &error) { bool Initialize(const ConfigBlock &block, Error &error) {
return base.Configure(param, error); return base.Configure(block, error);
} }
bool Configure(const config_param &param, Error &error); bool Configure(const ConfigBlock &block, Error &error);
}; };
static int shout_init_count; static int shout_init_count;
@ -92,18 +92,18 @@ shout_encoder_plugin_get(const char *name)
gcc_pure gcc_pure
static const char * static const char *
require_block_string(const config_param &param, const char *name) require_block_string(const ConfigBlock &block, const char *name)
{ {
const char *value = param.GetBlockValue(name); const char *value = block.GetBlockValue(name);
if (value == nullptr) if (value == nullptr)
FormatFatalError("no \"%s\" defined for shout device defined " FormatFatalError("no \"%s\" defined for shout device defined "
"at line %d\n", name, param.line); "at line %d\n", name, block.line);
return value; return value;
} }
inline bool inline bool
ShoutOutput::Configure(const config_param &param, Error &error) ShoutOutput::Configure(const ConfigBlock &block, Error &error)
{ {
const AudioFormat audio_format = base.config_audio_format; const AudioFormat audio_format = base.config_audio_format;
@ -113,22 +113,22 @@ ShoutOutput::Configure(const config_param &param, Error &error)
return false; return false;
} }
const char *host = require_block_string(param, "host"); const char *host = require_block_string(block, "host");
const char *mount = require_block_string(param, "mount"); const char *mount = require_block_string(block, "mount");
unsigned port = param.GetBlockValue("port", 0u); unsigned port = block.GetBlockValue("port", 0u);
if (port == 0) { if (port == 0) {
error.Set(config_domain, "shout port must be configured"); error.Set(config_domain, "shout port must be configured");
return false; return false;
} }
const char *passwd = require_block_string(param, "password"); const char *passwd = require_block_string(block, "password");
const char *name = require_block_string(param, "name"); const char *name = require_block_string(block, "name");
bool is_public = param.GetBlockValue("public", false); bool is_public = block.GetBlockValue("public", false);
const char *user = param.GetBlockValue("user", "source"); const char *user = block.GetBlockValue("user", "source");
const char *value = param.GetBlockValue("quality"); const char *value = block.GetBlockValue("quality");
if (value != nullptr) { if (value != nullptr) {
char *test; char *test;
quality = strtod(value, &test); quality = strtod(value, &test);
@ -141,14 +141,14 @@ ShoutOutput::Configure(const config_param &param, Error &error)
return false; return false;
} }
if (param.GetBlockValue("bitrate") != nullptr) { if (block.GetBlockValue("bitrate") != nullptr) {
error.Set(config_domain, error.Set(config_domain,
"quality and bitrate are " "quality and bitrate are "
"both defined"); "both defined");
return false; return false;
} }
} else { } else {
value = param.GetBlockValue("bitrate"); value = block.GetBlockValue("bitrate");
if (value == nullptr) { if (value == nullptr) {
error.Set(config_domain, error.Set(config_domain,
"neither bitrate nor quality defined"); "neither bitrate nor quality defined");
@ -165,7 +165,7 @@ ShoutOutput::Configure(const config_param &param, Error &error)
} }
} }
const char *encoding = param.GetBlockValue("encoding", "ogg"); const char *encoding = block.GetBlockValue("encoding", "ogg");
const auto encoder_plugin = shout_encoder_plugin_get(encoding); const auto encoder_plugin = shout_encoder_plugin_get(encoding);
if (encoder_plugin == nullptr) { if (encoder_plugin == nullptr) {
error.Format(config_domain, error.Format(config_domain,
@ -174,7 +174,7 @@ ShoutOutput::Configure(const config_param &param, Error &error)
return false; return false;
} }
encoder = encoder_init(*encoder_plugin, param, error); encoder = encoder_init(*encoder_plugin, block, error);
if (encoder == nullptr) if (encoder == nullptr)
return false; return false;
@ -185,7 +185,7 @@ ShoutOutput::Configure(const config_param &param, Error &error)
shout_format = SHOUT_FORMAT_OGG; shout_format = SHOUT_FORMAT_OGG;
unsigned protocol; unsigned protocol;
value = param.GetBlockValue("protocol"); value = block.GetBlockValue("protocol");
if (value != nullptr) { if (value != nullptr) {
if (0 == strcmp(value, "shoutcast") && if (0 == strcmp(value, "shoutcast") &&
0 != strcmp(encoding, "mp3")) { 0 != strcmp(encoding, "mp3")) {
@ -226,21 +226,21 @@ ShoutOutput::Configure(const config_param &param, Error &error)
} }
/* optional paramters */ /* optional paramters */
timeout = param.GetBlockValue("timeout", DEFAULT_CONN_TIMEOUT); timeout = block.GetBlockValue("timeout", DEFAULT_CONN_TIMEOUT);
value = param.GetBlockValue("genre"); value = block.GetBlockValue("genre");
if (value != nullptr && shout_set_genre(shout_conn, value)) { if (value != nullptr && shout_set_genre(shout_conn, value)) {
error.Set(shout_output_domain, shout_get_error(shout_conn)); error.Set(shout_output_domain, shout_get_error(shout_conn));
return false; return false;
} }
value = param.GetBlockValue("description"); value = block.GetBlockValue("description");
if (value != nullptr && shout_set_description(shout_conn, value)) { if (value != nullptr && shout_set_description(shout_conn, value)) {
error.Set(shout_output_domain, shout_get_error(shout_conn)); error.Set(shout_output_domain, shout_get_error(shout_conn));
return false; return false;
} }
value = param.GetBlockValue("url"); value = block.GetBlockValue("url");
if (value != nullptr && shout_set_url(shout_conn, value)) { if (value != nullptr && shout_set_url(shout_conn, value)) {
error.Set(shout_output_domain, shout_get_error(shout_conn)); error.Set(shout_output_domain, shout_get_error(shout_conn));
return false; return false;
@ -272,15 +272,15 @@ ShoutOutput::Configure(const config_param &param, Error &error)
} }
static AudioOutput * static AudioOutput *
my_shout_init_driver(const config_param &param, Error &error) my_shout_init_driver(const ConfigBlock &block, Error &error)
{ {
ShoutOutput *sd = new ShoutOutput(); ShoutOutput *sd = new ShoutOutput();
if (!sd->Initialize(param, error)) { if (!sd->Initialize(block, error)) {
delete sd; delete sd;
return nullptr; return nullptr;
} }
if (!sd->Configure(param, error)) { if (!sd->Configure(block, error)) {
delete sd; delete sd;
return nullptr; return nullptr;
} }

Some files were not shown because too many files have changed in this diff Show More