diff options
author | Max Kellermann <max@musicpd.org> | 2018-07-18 11:03:19 +0200 |
---|---|---|
committer | Max Kellermann <max@musicpd.org> | 2018-07-18 11:03:19 +0200 |
commit | 9ff2606bb867c98cd1681433ac5e4d21b9ae541a (patch) | |
tree | 60fdf3d17ffbaf51fde7900edf00430d3ec26b72 | |
parent | fd80683ade480d6417d66d0fc882b598738002f8 (diff) |
config/Data: use std::forward_list to manage params and blocks
-rw-r--r-- | src/Listen.cxx | 9 | ||||
-rw-r--r-- | src/Permission.cxx | 33 | ||||
-rw-r--r-- | src/config/Block.cxx | 5 | ||||
-rw-r--r-- | src/config/Block.hxx | 13 | ||||
-rw-r--r-- | src/config/Data.cxx | 68 | ||||
-rw-r--r-- | src/config/Data.hxx | 33 | ||||
-rw-r--r-- | src/config/Global.cxx | 6 | ||||
-rw-r--r-- | src/config/Param.cxx | 5 | ||||
-rw-r--r-- | src/config/Param.hxx | 13 | ||||
-rw-r--r-- | src/neighbor/Glue.cxx | 9 | ||||
-rw-r--r-- | src/output/MultipleOutputs.cxx | 7 |
11 files changed, 85 insertions, 116 deletions
diff --git a/src/Listen.cxx b/src/Listen.cxx index b74777127..2df05c634 100644 --- a/src/Listen.cxx +++ b/src/Listen.cxx @@ -88,14 +88,13 @@ listen_global_init(const ConfigData &config, ClientListener &listener) return; #endif - for (const auto *param = config.GetParam(ConfigOption::BIND_TO_ADDRESS); - param != nullptr; param = param->next) { + for (const auto ¶m : config.GetParamList(ConfigOption::BIND_TO_ADDRESS)) { try { - listen_add_config_param(listener, port, param); + listen_add_config_param(listener, port, ¶m); } catch (...) { std::throw_with_nested(FormatRuntimeError("Failed to listen on %s (line %i)", - param->value.c_str(), - param->line)); + param.value.c_str(), + param.line)); } } diff --git a/src/Permission.cxx b/src/Permission.cxx index 0a195d854..bb67a9585 100644 --- a/src/Permission.cxx +++ b/src/Permission.cxx @@ -91,37 +91,32 @@ void initPermissions(const ConfigData &config) { unsigned permission; - const ConfigParam *param; permission_default = PERMISSION_READ | PERMISSION_ADD | PERMISSION_CONTROL | PERMISSION_ADMIN; - param = config.GetParam(ConfigOption::PASSWORD); - - if (param) { + for (const auto ¶m : config.GetParamList(ConfigOption::PASSWORD)) { permission_default = 0; - do { - const char *separator = - strchr(param->value.c_str(), - PERMISSION_PASSWORD_CHAR); + const char *separator = strchr(param.value.c_str(), + PERMISSION_PASSWORD_CHAR); - if (separator == NULL) - throw FormatRuntimeError("\"%c\" not found in password string " - "\"%s\", line %i", - PERMISSION_PASSWORD_CHAR, - param->value.c_str(), - param->line); + if (separator == NULL) + throw FormatRuntimeError("\"%c\" not found in password string " + "\"%s\", line %i", + PERMISSION_PASSWORD_CHAR, + param.value.c_str(), + param.line); - std::string password(param->value.c_str(), separator); + std::string password(param.value.c_str(), separator); - permission = parsePermissions(separator + 1); + permission = parsePermissions(separator + 1); - permission_passwords.insert(std::make_pair(std::move(password), - permission)); - } while ((param = param->next) != nullptr); + permission_passwords.insert(std::make_pair(std::move(password), + permission)); } + const ConfigParam *param; param = config.GetParam(ConfigOption::DEFAULT_PERMS); if (param) diff --git a/src/config/Block.cxx b/src/config/Block.cxx index 1c5b2c109..15bb5da95 100644 --- a/src/config/Block.cxx +++ b/src/config/Block.cxx @@ -78,11 +78,6 @@ BlockParam::GetBoolValue() const return value2; } -ConfigBlock::~ConfigBlock() -{ - delete next; -} - const BlockParam * ConfigBlock::GetBlockParam(const char *name) const noexcept { diff --git a/src/config/Block.hxx b/src/config/Block.hxx index 380fa2277..035d8c395 100644 --- a/src/config/Block.hxx +++ b/src/config/Block.hxx @@ -55,12 +55,6 @@ struct BlockParam { }; struct ConfigBlock { - /** - * The next #ConfigBlock with the same name. The destructor - * deletes the whole chain. - */ - ConfigBlock *next = nullptr; - int line; std::vector<BlockParam> block_params; @@ -74,11 +68,8 @@ struct ConfigBlock { explicit ConfigBlock(int _line=-1) :line(_line) {} - ConfigBlock(const ConfigBlock &) = delete; - - ~ConfigBlock(); - - ConfigBlock &operator=(const ConfigBlock &) = delete; + ConfigBlock(ConfigBlock &&) = default; + ConfigBlock &operator=(ConfigBlock &&) = default; /** * Determine if this is a "null" instance, i.e. an empty diff --git a/src/config/Data.cxx b/src/config/Data.cxx index f8518aa3d..22f8f399d 100644 --- a/src/config/Data.cxx +++ b/src/config/Data.cxx @@ -19,8 +19,6 @@ #include "config.h" #include "Data.hxx" -#include "Param.hxx" -#include "Block.hxx" #include "Parser.hxx" #include "fs/AllocatedPath.hxx" #include "util/RuntimeError.hxx" @@ -31,35 +29,36 @@ void ConfigData::Clear() { - for (auto &i : params) { - delete i; - i = nullptr; - } + for (auto &i : params) + i.clear(); - for (auto &i : blocks) { - delete i; - i = nullptr; - } + for (auto &i : blocks) + i.clear(); } -gcc_nonnull_all -static void -Append(ConfigParam *&head, ConfigParam *p) +template<typename T> +gcc_pure +static auto +FindLast(const std::forward_list<T> &list) { - assert(p->next == nullptr); - - auto **i = &head; - while (*i != nullptr) - i = &(*i)->next; + auto i = list.before_begin(); + while (std::next(i) != list.end()) + ++i; + return i; +} - *i = p; +template<typename T> +static auto +Append(std::forward_list<T> &list, T &&src) +{ + return list.emplace_after(FindLast(list), std::move(src)); } void ConfigData::AddParam(ConfigOption option, std::unique_ptr<ConfigParam> param) noexcept { - Append(params[size_t(option)], param.release()); + Append(GetParamList(option), std::move(*param)); } const char * @@ -143,39 +142,25 @@ ConfigData::GetBool(ConfigOption option, bool default_value) const return value; } -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; -} - -void +ConfigBlock & ConfigData::AddBlock(ConfigBlockOption option, std::unique_ptr<ConfigBlock> block) noexcept { - Append(blocks[size_t(option)], block.release()); + return *Append(GetBlockList(option), std::move(*block)); } const ConfigBlock * ConfigData::FindBlock(ConfigBlockOption option, const char *key, const char *value) const { - for (const auto *block = GetBlock(option); - block != nullptr; block = block->next) { - const char *value2 = block->GetBlockValue(key); + for (const auto &block : GetBlockList(option)) { + const char *value2 = block.GetBlockValue(key); if (value2 == nullptr) throw FormatRuntimeError("block without '%s' in line %d", - key, block->line); + key, block.line); if (StringIsEqual(value2, value)) - return block; + return █ } return nullptr; @@ -189,8 +174,7 @@ ConfigData::MakeBlock(ConfigBlockOption option, if (block == nullptr) { auto new_block = std::make_unique<ConfigBlock>(); new_block->AddBlockParam(key, value); - block = new_block.get(); - AddBlock(option, std::move(new_block)); + block = &AddBlock(option, std::move(new_block)); } return *block; diff --git a/src/config/Data.hxx b/src/config/Data.hxx index d58948489..2a0cc87e7 100644 --- a/src/config/Data.hxx +++ b/src/config/Data.hxx @@ -21,9 +21,12 @@ #define MPD_CONFIG_DATA_HXX #include "Option.hxx" +#include "Param.hxx" +#include "Block.hxx" #include <array> #include <chrono> +#include <forward_list> #include <memory> struct ConfigParam; @@ -31,17 +34,26 @@ struct ConfigBlock; class AllocatedPath; struct ConfigData { - std::array<ConfigParam *, std::size_t(ConfigOption::MAX)> params{{nullptr}}; - std::array<ConfigBlock *, std::size_t(ConfigBlockOption::MAX)> blocks{{nullptr}}; + std::array<std::forward_list<ConfigParam>, std::size_t(ConfigOption::MAX)> params; + std::array<std::forward_list<ConfigBlock>, std::size_t(ConfigBlockOption::MAX)> blocks; void Clear(); + auto &GetParamList(ConfigOption option) noexcept { + return params[size_t(option)]; + } + + const auto &GetParamList(ConfigOption option) const noexcept { + return params[size_t(option)]; + } + void AddParam(ConfigOption option, std::unique_ptr<ConfigParam> param) noexcept; gcc_pure const ConfigParam *GetParam(ConfigOption option) const noexcept { - return params[size_t(option)]; + const auto &list = GetParamList(option); + return list.empty() ? nullptr : &list.front(); } gcc_pure @@ -81,12 +93,21 @@ struct ConfigData { bool GetBool(ConfigOption option, bool default_value) const; - void AddBlock(ConfigBlockOption option, - std::unique_ptr<ConfigBlock> block) noexcept; + auto &GetBlockList(ConfigBlockOption option) noexcept { + return blocks[size_t(option)]; + } + + const auto &GetBlockList(ConfigBlockOption option) const noexcept { + return blocks[size_t(option)]; + } + + ConfigBlock &AddBlock(ConfigBlockOption option, + std::unique_ptr<ConfigBlock> block) noexcept; gcc_pure const ConfigBlock *GetBlock(ConfigBlockOption option) const noexcept { - return blocks[size_t(option)]; + const auto &list = GetBlockList(option); + return list.empty() ? nullptr : &list.front(); } /** diff --git a/src/config/Global.cxx b/src/config/Global.cxx index fceb5b603..5892896b9 100644 --- a/src/config/Global.cxx +++ b/src/config/Global.cxx @@ -72,9 +72,9 @@ Check(const ConfigBlock &block) void config_global_check(void) { - for (auto i : config_data.blocks) - for (const auto *p = i; p != nullptr; p = p->next) - Check(*p); + for (const auto &list : config_data.blocks) + for (const auto &block : list) + Check(block); } const char * diff --git a/src/config/Param.cxx b/src/config/Param.cxx index bb1962e7d..1df37285a 100644 --- a/src/config/Param.cxx +++ b/src/config/Param.cxx @@ -25,11 +25,6 @@ #include <stdexcept> -ConfigParam::~ConfigParam() -{ - delete next; -} - AllocatedPath ConfigParam::GetPath() const { diff --git a/src/config/Param.hxx b/src/config/Param.hxx index e3346f7e0..d7be49a55 100644 --- a/src/config/Param.hxx +++ b/src/config/Param.hxx @@ -28,12 +28,6 @@ class AllocatedPath; struct ConfigParam { - /** - * The next ConfigParam with the same name. The destructor - * deletes the whole chain. - */ - ConfigParam *next = nullptr; - std::string value; int line; @@ -46,11 +40,8 @@ struct ConfigParam { explicit ConfigParam(V &&_value, int _line=-1) noexcept :value(std::forward<V>(_value)), line(_line) {} - ConfigParam(const ConfigParam &) = delete; - - ~ConfigParam(); - - ConfigParam &operator=(const ConfigParam &) = delete; + ConfigParam(ConfigParam &&) = default; + ConfigParam &operator=(ConfigParam &&) = default; /** * Determine if this is a "null" instance, i.e. an empty diff --git a/src/neighbor/Glue.cxx b/src/neighbor/Glue.cxx index 5118f54a3..154e6331b 100644 --- a/src/neighbor/Glue.cxx +++ b/src/neighbor/Glue.cxx @@ -53,17 +53,16 @@ void NeighborGlue::Init(const ConfigData &config, EventLoop &loop, NeighborListener &listener) { - for (const auto *block = config.GetBlock(ConfigBlockOption::NEIGHBORS); - block != nullptr; block = block->next) { - block->SetUsed(); + for (const auto &block : config.GetBlockList(ConfigBlockOption::NEIGHBORS)) { + block.SetUsed(); try { explorers.emplace_front(CreateNeighborExplorer(loop, listener, - *block)); + block)); } catch (...) { std::throw_with_nested(FormatRuntimeError("Line %i: ", - block->line)); + block.line)); } } } diff --git a/src/output/MultipleOutputs.cxx b/src/output/MultipleOutputs.cxx index f84441fde..af21d2e33 100644 --- a/src/output/MultipleOutputs.cxx +++ b/src/output/MultipleOutputs.cxx @@ -91,13 +91,12 @@ MultipleOutputs::Configure(EventLoop &event_loop, const ReplayGainConfig &replay_gain_config, AudioOutputClient &client) { - for (const auto *param = config.GetBlock(ConfigBlockOption::AUDIO_OUTPUT); - param != nullptr; param = param->next) { - param->SetUsed(); + for (const auto &block : config.GetBlockList(ConfigBlockOption::AUDIO_OUTPUT)) { + block.SetUsed(); auto *output = LoadOutputControl(event_loop, replay_gain_config, mixer_listener, - client, *param); + client, block); if (FindByName(output->GetName()) != nullptr) throw FormatRuntimeError("output devices with identical " "names: %s", output->GetName()); |