diff options
author | Max Kellermann <max@duempel.org> | 2015-01-21 22:13:44 +0100 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2015-01-21 23:56:33 +0100 |
commit | 4fa5538e2bed36903b403e1aaee2462d22b456dc (patch) | |
tree | 292b66e10e6b97e2363fde34a81c027a67d3a9fe /src/config | |
parent | 84e74173de85a3897cfe67150297987f8c8bf52e (diff) | |
download | mpd-4fa5538e2bed36903b403e1aaee2462d22b456dc.tar.gz mpd-4fa5538e2bed36903b403e1aaee2462d22b456dc.tar.xz mpd-4fa5538e2bed36903b403e1aaee2462d22b456dc.zip |
config/Param: split block-specific attributes to new struct ConfigBlock
The old struct config_param remains only for top-level string options.
Diffstat (limited to 'src/config')
-rw-r--r-- | src/config/Block.cxx | 97 | ||||
-rw-r--r-- | src/config/Block.hxx | 72 | ||||
-rw-r--r-- | src/config/ConfigFile.cxx | 139 | ||||
-rw-r--r-- | src/config/ConfigGlobal.cxx | 38 | ||||
-rw-r--r-- | src/config/ConfigGlobal.hxx | 9 | ||||
-rw-r--r-- | src/config/ConfigOption.hxx | 19 | ||||
-rw-r--r-- | src/config/ConfigTemplates.cxx | 157 | ||||
-rw-r--r-- | src/config/ConfigTemplates.hxx | 4 | ||||
-rw-r--r-- | src/config/Data.cxx | 6 | ||||
-rw-r--r-- | src/config/Data.hxx | 2 | ||||
-rw-r--r-- | src/config/Param.cxx | 94 | ||||
-rw-r--r-- | src/config/Param.hxx | 39 |
12 files changed, 406 insertions, 270 deletions
diff --git a/src/config/Block.cxx b/src/config/Block.cxx index ba26c560f..a74903b10 100644 --- a/src/config/Block.cxx +++ b/src/config/Block.cxx @@ -20,8 +20,12 @@ #include "config.h" #include "Block.hxx" #include "ConfigParser.hxx" +#include "ConfigPath.hxx" #include "system/FatalError.hxx" +#include "fs/AllocatedPath.hxx" +#include "util/Error.hxx" +#include <assert.h> #include <stdlib.h> int @@ -57,3 +61,96 @@ BlockParam::GetBoolValue() const 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(); +} diff --git a/src/config/Block.hxx b/src/config/Block.hxx index c2194eff9..23b064695 100644 --- a/src/config/Block.hxx +++ b/src/config/Block.hxx @@ -21,9 +21,14 @@ #define MPD_CONFIG_BLOCK_HXX #include "check.h" +#include "Param.hxx" #include "Compiler.h" #include <string> +#include <vector> + +class Error; +class AllocatedPath; struct BlockParam { std::string name; @@ -50,4 +55,71 @@ struct BlockParam { 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 diff --git a/src/config/ConfigFile.cxx b/src/config/ConfigFile.cxx index 38945f8ec..a5ad020d4 100644 --- a/src/config/ConfigFile.cxx +++ b/src/config/ConfigFile.cxx @@ -21,6 +21,7 @@ #include "ConfigFile.hxx" #include "Data.hxx" #include "Param.hxx" +#include "Block.hxx" #include "ConfigTemplates.hxx" #include "util/Tokenizer.hxx" #include "util/StringUtil.hxx" @@ -38,7 +39,7 @@ static constexpr char CONF_COMMENT = '#'; static constexpr Domain config_file_domain("config_file"); 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) { Tokenizer tokenizer(input); @@ -65,7 +66,7 @@ config_read_name_value(struct config_param *param, char *input, unsigned line, return false; } - const BlockParam *bp = param->GetBlockParam(name); + const BlockParam *bp = block.GetBlockParam(name); if (bp != nullptr) { error.Format(config_file_domain, "\"%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; } - param->AddBlockParam(name, value, line); + block.AddBlockParam(name, value, line); return true; } -static struct config_param * +static ConfigBlock * config_read_block(BufferedReader &reader, Error &error) { - struct config_param *ret = new config_param(reader.GetLineNumber()); + auto *ret = new ConfigBlock(reader.GetLineNumber()); while (true) { char *line = reader.ReadLine(); @@ -115,7 +116,7 @@ config_read_block(BufferedReader &reader, Error &error) /* parse name and value */ - if (!config_read_name_value(ret, line, reader.GetLineNumber(), + if (!config_read_name_value(*ret, line, reader.GetLineNumber(), error)) { assert(*line != 0); delete ret; @@ -127,6 +128,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 +static void Append(config_param *&head, config_param *p) { assert(p->next == nullptr); @@ -145,7 +204,7 @@ ReadConfigParam(ConfigData &config_data, BufferedReader &reader, Error &error) { 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]; if (head != nullptr && !option.repeatable) { @@ -160,57 +219,28 @@ ReadConfigParam(ConfigData &config_data, BufferedReader &reader, /* now parse the block or the value */ - struct config_param *param; - if (option.block) { - /* it's a block, call config_read_block() */ - - 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) { + const char *value = tokenizer.NextString(error); + if (value == nullptr) { + if (tokenizer.IsEnd()) error.Format(config_file_domain, - "line %u: Unknown tokens after '{'", + "line %u: Value missing", reader.GetLineNumber()); - return false; - } + else + error.FormatPrefix("line %u: ", + reader.GetLineNumber()); - 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; - } + 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); return true; } @@ -242,10 +272,15 @@ ReadConfigFile(ConfigData &config_data, BufferedReader &reader, Error &error) "repeatable" flag */ const ConfigOption o = ParseConfigOptionName(name); + ConfigBlockOption bo; if (o != ConfigOption::MAX) { if (!ReadConfigParam(config_data, reader, name, o, tokenizer, error)) return false; + } else if ((bo = ParseConfigBlockOptionName(name)) != ConfigBlockOption::MAX) { + if (!ReadConfigBlock(config_data, reader, name, o, + tokenizer, error)) + return false; } else { error.Format(config_file_domain, "unrecognized parameter in config file at " diff --git a/src/config/ConfigGlobal.cxx b/src/config/ConfigGlobal.cxx index 5c04ea93e..192baffec 100644 --- a/src/config/ConfigGlobal.cxx +++ b/src/config/ConfigGlobal.cxx @@ -22,6 +22,7 @@ #include "ConfigParser.hxx" #include "Data.hxx" #include "Param.hxx" +#include "Block.hxx" #include "ConfigFile.hxx" #include "ConfigPath.hxx" #include "ConfigError.hxx" @@ -51,15 +52,15 @@ ReadConfigFile(Path path, Error &error) } static void -Check(const config_param *param) +Check(const ConfigBlock &block) { - if (!param->used) - /* this whole config_param was not queried at all - + if (!block.used) + /* this whole block was not queried at all - the feature might be disabled at compile time? Silently ignore it here. */ return; - for (const auto &i : param->block_params) { + for (const auto &i : block.block_params) { if (!i.used) FormatWarning(config_domain, "option '%s' on line %i was not recognized", @@ -69,9 +70,9 @@ Check(const config_param *param) void config_global_check(void) { - for (auto i : config_data.params) - for (const config_param *p = i; p != nullptr; p = p->next) - Check(p); + for (auto i : config_data.blocks) + for (const auto *p = i; p != nullptr; p = p->next) + Check(*p); } const config_param * @@ -83,18 +84,27 @@ config_get_param(ConfigOption option) return param; } -const config_param * -config_find_block(ConfigOption option, const char *key, const char *value) +const ConfigBlock * +config_get_block(ConfigBlockOption option) +{ + ConfigBlock *block = config_data.blocks[unsigned(option)]; + if (block != nullptr) + block->used = true; + return block; +} + +const ConfigBlock * +config_find_block(ConfigBlockOption option, const char *key, const char *value) { - for (const config_param *param = config_get_param(option); - param != nullptr; param = param->next) { - const char *value2 = param->GetBlockValue(key); + for (const auto *block = config_get_block(option); + block != nullptr; block = block->next) { + const char *value2 = block->GetBlockValue(key); if (value2 == nullptr) FormatFatalError("block without '%s' name in line %d", - key, param->line); + key, block->line); if (strcmp(value2, value) == 0) - return param; + return block; } return nullptr; diff --git a/src/config/ConfigGlobal.hxx b/src/config/ConfigGlobal.hxx index ac7d5c4fd..3c6a938a6 100644 --- a/src/config/ConfigGlobal.hxx +++ b/src/config/ConfigGlobal.hxx @@ -27,6 +27,7 @@ class Error; class Path; class AllocatedPath; struct config_param; +struct ConfigBlock; void config_global_init(void); void config_global_finish(void); @@ -44,6 +45,10 @@ gcc_pure const config_param * config_get_param(enum ConfigOption option); +gcc_pure +const ConfigBlock * +config_get_block(enum ConfigBlockOption option); + /** * Find a block with a matching attribute. * @@ -52,8 +57,8 @@ config_get_param(enum ConfigOption option); * @param value the expected attribute value */ gcc_pure -const config_param * -config_find_block(ConfigOption option, const char *key, const char *value); +const ConfigBlock * +config_find_block(ConfigBlockOption option, const char *key, const char *value); /* Note on gcc_pure: Some of the functions declared pure are not really pure in strict sense. They have side effect such that they diff --git a/src/config/ConfigOption.hxx b/src/config/ConfigOption.hxx index c3f4c9aad..8cc0d42d5 100644 --- a/src/config/ConfigOption.hxx +++ b/src/config/ConfigOption.hxx @@ -49,7 +49,6 @@ enum class ConfigOption { ZEROCONF_ENABLED, PASSWORD, DEFAULT_PERMS, - AUDIO_OUTPUT, AUDIO_OUTPUT_FORMAT, MIXER_TYPE, REPLAYGAIN, @@ -73,15 +72,20 @@ enum class ConfigOption { ID3V1_ENCODING, METADATA_TO_USE, SAVE_ABSOLUTE_PATHS, - DECODER, - INPUT, GAPLESS_MP3_PLAYBACK, - PLAYLIST_PLUGIN, AUTO_UPDATE, AUTO_UPDATE_DEPTH, DESPOTIFY_USER, DESPOTIFY_PASSWORD, DESPOTIFY_HIGH_BITRATE, + MAX +}; + +enum class ConfigBlockOption { + AUDIO_OUTPUT, + DECODER, + INPUT, + PLAYLIST_PLUGIN, AUDIO_FILTER, DATABASE, NEIGHBORS, @@ -99,4 +103,11 @@ gcc_pure enum ConfigOption ParseConfigOptionName(const char *name); +/** + * @return #ConfigOption::MAX if not found + */ +gcc_pure +enum ConfigBlockOption +ParseConfigBlockOptionName(const char *name); + #endif diff --git a/src/config/ConfigTemplates.cxx b/src/config/ConfigTemplates.cxx index 8f01d4104..1ceef9119 100644 --- a/src/config/ConfigTemplates.cxx +++ b/src/config/ConfigTemplates.cxx @@ -23,76 +23,105 @@ #include <string.h> -const ConfigTemplate config_templates[] = { - { "music_directory", false, false }, - { "playlist_directory", false, false }, - { "follow_inside_symlinks", false, false }, - { "follow_outside_symlinks", false, false }, - { "db_file", false, false }, - { "sticker_file", false, false }, - { "log_file", false, false }, - { "pid_file", false, false }, - { "state_file", false, false }, - { "state_file_interval", false, false }, - { "restore_paused", false, false }, - { "user", false, false }, - { "group", false, false }, - { "bind_to_address", true, false }, - { "port", false, false }, - { "log_level", false, false }, - { "zeroconf_name", false, false }, - { "zeroconf_enabled", false, false }, - { "password", true, false }, - { "default_permissions", false, false }, - { "audio_output", true, true }, - { "audio_output_format", false, false }, - { "mixer_type", false, false }, - { "replaygain", false, false }, - { "replaygain_preamp", false, false }, - { "replaygain_missing_preamp", false, false }, - { "replaygain_limit", false, false }, - { "volume_normalization", false, false }, - { "samplerate_converter", false, false }, - { "audio_buffer_size", false, false }, - { "buffer_before_play", false, false }, - { "http_proxy_host", false, false }, - { "http_proxy_port", false, false }, - { "http_proxy_user", false, false }, - { "http_proxy_password", false, false }, - { "connection_timeout", false, false }, - { "max_connections", false, false }, - { "max_playlist_length", false, false }, - { "max_command_list_size", false, false }, - { "max_output_buffer_size", false, false }, - { "filesystem_charset", false, false }, - { "id3v1_encoding", false, false }, - { "metadata_to_use", false, false }, - { "save_absolute_paths_in_playlists", false, false }, - { "decoder", true, true }, - { "input", true, true }, - { "gapless_mp3_playback", false, false }, - { "playlist_plugin", true, true }, - { "auto_update", false, 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 }, +const ConfigTemplate config_param_templates[] = { + { "music_directory", false }, + { "playlist_directory", false }, + { "follow_inside_symlinks", false }, + { "follow_outside_symlinks", false }, + { "db_file", false }, + { "sticker_file", false }, + { "log_file", false }, + { "pid_file", false }, + { "state_file", false }, + { "state_file_interval", false }, + { "restore_paused", false }, + { "user", false }, + { "group", false }, + { "bind_to_address", true }, + { "port", false }, + { "log_level", false }, + { "zeroconf_name", false }, + { "zeroconf_enabled", false }, + { "password", true }, + { "default_permissions", false }, + { "audio_output_format", false }, + { "mixer_type", false }, + { "replaygain", false }, + { "replaygain_preamp", false }, + { "replaygain_missing_preamp", false }, + { "replaygain_limit", false }, + { "volume_normalization", false }, + { "samplerate_converter", false }, + { "audio_buffer_size", false }, + { "buffer_before_play", false }, + { "http_proxy_host", false }, + { "http_proxy_port", false }, + { "http_proxy_user", false }, + { "http_proxy_password", false }, + { "connection_timeout", false }, + { "max_connections", false }, + { "max_playlist_length", false }, + { "max_command_list_size", false }, + { "max_output_buffer_size", false }, + { "filesystem_charset", false }, + { "id3v1_encoding", false }, + { "metadata_to_use", false }, + { "save_absolute_paths_in_playlists", false }, + { "gapless_mp3_playback", false }, + { "auto_update", false }, + { "auto_update_depth", false }, + { "despotify_user", false }, + { "despotify_password", false }, + { "despotify_high_bitrate", false }, }; -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), - "Wrong number of config_templates"); +static_assert(n_config_param_templates == unsigned(ConfigOption::MAX), + "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 ParseConfigOptionName(const char *name) { - for (unsigned i = 0; i < n_config_templates; ++i) - if (strcmp(config_templates[i].name, name) == 0) - return ConfigOption(i); + return ConfigOption(ParseConfigTemplateName(config_param_templates, + n_config_param_templates, + name)); +} - return ConfigOption::MAX; +ConfigBlockOption +ParseConfigBlockOptionName(const char *name) +{ + return ConfigBlockOption(ParseConfigTemplateName(config_block_templates, + n_config_block_templates, + name)); } diff --git a/src/config/ConfigTemplates.hxx b/src/config/ConfigTemplates.hxx index f034773e3..1aa6c6e8d 100644 --- a/src/config/ConfigTemplates.hxx +++ b/src/config/ConfigTemplates.hxx @@ -23,9 +23,9 @@ struct ConfigTemplate { const char *const name; const bool repeatable; - const bool block; }; -extern const ConfigTemplate config_templates[]; +extern const ConfigTemplate config_param_templates[]; +extern const ConfigTemplate config_block_templates[]; #endif diff --git a/src/config/Data.cxx b/src/config/Data.cxx index 4aae9f7dc..52521e31a 100644 --- a/src/config/Data.cxx +++ b/src/config/Data.cxx @@ -20,6 +20,7 @@ #include "config.h" #include "Data.hxx" #include "Param.hxx" +#include "Block.hxx" void ConfigData::Clear() @@ -28,4 +29,9 @@ ConfigData::Clear() delete i; i = nullptr; } + + for (auto &i : blocks) { + delete i; + i = nullptr; + } } diff --git a/src/config/Data.hxx b/src/config/Data.hxx index 56e7d2553..6036c49e6 100644 --- a/src/config/Data.hxx +++ b/src/config/Data.hxx @@ -25,9 +25,11 @@ #include <array> struct config_param; +struct ConfigBlock; struct ConfigData { std::array<config_param *, std::size_t(ConfigOption::MAX)> params; + std::array<ConfigBlock *, std::size_t(ConfigBlockOption::MAX)> blocks; void Clear(); }; diff --git a/src/config/Param.cxx b/src/config/Param.cxx index 376f50ee7..bfd9743d2 100644 --- a/src/config/Param.cxx +++ b/src/config/Param.cxx @@ -19,12 +19,6 @@ #include "config.h" #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) :next(nullptr), value(_value), line(_line), used(false) {} @@ -33,91 +27,3 @@ config_param::~config_param() { 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(); -} diff --git a/src/config/Param.hxx b/src/config/Param.hxx index a3cd3f83a..e6a039c2a 100644 --- a/src/config/Param.hxx +++ b/src/config/Param.hxx @@ -20,14 +20,10 @@ #ifndef MPD_CONFIG_PARAM_HXX #define MPD_CONFIG_PARAM_HXX -#include "Block.hxx" +#include "check.h" #include "Compiler.h" #include <string> -#include <vector> - -class AllocatedPath; -class Error; struct config_param { /** @@ -40,8 +36,6 @@ struct config_param { int line; - std::vector<BlockParam> block_params; - /** * This flag is false when nobody has queried the value of * this option yet. @@ -68,37 +62,6 @@ struct config_param { 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 |