config/Data: add WithEach(ConfigBlockOption)
To improve error messages without making callers more complex.
This commit is contained in:
parent
89a18b49a7
commit
ae4f4d3533
@ -143,3 +143,10 @@ ConfigBlock::GetBlockValue(const char *name, bool default_value) const
|
|||||||
|
|
||||||
return bp->GetBoolValue();
|
return bp->GetBoolValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ConfigBlock::ThrowWithNested() const
|
||||||
|
{
|
||||||
|
std::throw_with_nested(FormatRuntimeError("Error in block on line %i",
|
||||||
|
line));
|
||||||
|
}
|
||||||
|
@ -137,6 +137,14 @@ struct ConfigBlock {
|
|||||||
unsigned GetPositiveValue(const char *name, unsigned default_value) const;
|
unsigned GetPositiveValue(const char *name, unsigned default_value) const;
|
||||||
|
|
||||||
bool GetBlockValue(const char *name, bool default_value) const;
|
bool GetBlockValue(const char *name, bool default_value) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call this method in a "catch" block to throw a nested
|
||||||
|
* exception showing the location of this block in the
|
||||||
|
* configuration file.
|
||||||
|
*/
|
||||||
|
[[noreturn]]
|
||||||
|
void ThrowWithNested() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -121,6 +121,26 @@ struct ConfigData {
|
|||||||
|
|
||||||
ConfigBlock &MakeBlock(ConfigBlockOption option,
|
ConfigBlock &MakeBlock(ConfigBlockOption option,
|
||||||
const char *key, const char *value);
|
const char *key, const char *value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invoke the given function for each instance of the
|
||||||
|
* specified block.
|
||||||
|
*
|
||||||
|
* Exceptions thrown by the function will be nested in one
|
||||||
|
* that specifies the location of the block.
|
||||||
|
*/
|
||||||
|
template<typename F>
|
||||||
|
void WithEach(ConfigBlockOption option, F &&f) const {
|
||||||
|
for (const auto &block : GetBlockList(option)) {
|
||||||
|
block.SetUsed();
|
||||||
|
|
||||||
|
try {
|
||||||
|
f(block);
|
||||||
|
} catch (...) {
|
||||||
|
block.ThrowWithNested();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -48,24 +48,16 @@ void
|
|||||||
NeighborGlue::Init(const ConfigData &config,
|
NeighborGlue::Init(const ConfigData &config,
|
||||||
EventLoop &loop, NeighborListener &listener)
|
EventLoop &loop, NeighborListener &listener)
|
||||||
{
|
{
|
||||||
for (const auto &block : config.GetBlockList(ConfigBlockOption::NEIGHBORS)) {
|
config.WithEach(ConfigBlockOption::NEIGHBORS, [&, this](const auto &block){
|
||||||
block.SetUsed();
|
const char *plugin_name = block.GetBlockValue("plugin");
|
||||||
|
if (plugin_name == nullptr)
|
||||||
|
throw std::runtime_error("Missing \"plugin\" configuration");
|
||||||
|
|
||||||
try {
|
explorers.emplace_front(plugin_name,
|
||||||
const char *plugin_name = block.GetBlockValue("plugin");
|
CreateNeighborExplorer(loop, listener,
|
||||||
if (plugin_name == nullptr)
|
plugin_name,
|
||||||
throw std::runtime_error("Missing \"plugin\" configuration");
|
block));
|
||||||
|
});
|
||||||
explorers.emplace_front(plugin_name,
|
|
||||||
CreateNeighborExplorer(loop,
|
|
||||||
listener,
|
|
||||||
plugin_name,
|
|
||||||
block));
|
|
||||||
} catch (...) {
|
|
||||||
std::throw_with_nested(FormatRuntimeError("Line %i: ",
|
|
||||||
block.line));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -92,8 +92,7 @@ MultipleOutputs::Configure(EventLoop &event_loop, EventLoop &rt_event_loop,
|
|||||||
const AudioOutputDefaults defaults(config);
|
const AudioOutputDefaults defaults(config);
|
||||||
FilterFactory filter_factory(config);
|
FilterFactory filter_factory(config);
|
||||||
|
|
||||||
for (const auto &block : config.GetBlockList(ConfigBlockOption::AUDIO_OUTPUT)) {
|
config.WithEach(ConfigBlockOption::AUDIO_OUTPUT, [&, this](const auto &block){
|
||||||
block.SetUsed();
|
|
||||||
auto output = LoadOutputControl(event_loop, rt_event_loop,
|
auto output = LoadOutputControl(event_loop, rt_event_loop,
|
||||||
replay_gain_config,
|
replay_gain_config,
|
||||||
mixer_listener,
|
mixer_listener,
|
||||||
@ -104,7 +103,7 @@ MultipleOutputs::Configure(EventLoop &event_loop, EventLoop &rt_event_loop,
|
|||||||
"names: %s", output->GetName());
|
"names: %s", output->GetName());
|
||||||
|
|
||||||
outputs.emplace_back(std::move(output));
|
outputs.emplace_back(std::move(output));
|
||||||
}
|
});
|
||||||
|
|
||||||
if (outputs.empty()) {
|
if (outputs.empty()) {
|
||||||
/* auto-detect device */
|
/* auto-detect device */
|
||||||
|
Loading…
Reference in New Issue
Block a user