| 329 | } |
| 330 | |
| 331 | Config::OptionInfo Config::findOption( |
| 332 | const std::string& name, const std::string value) |
| 333 | { |
| 334 | const OptionProto* found = nullptr; |
| 335 | |
| 336 | auto searchOptionList = [&](auto& optionList, const std::string& optionName) |
| 337 | { |
| 338 | for (const auto& option : optionList) |
| 339 | { |
| 340 | if (optionName == option.name()) |
| 341 | { |
| 342 | found = &option; |
| 343 | return true; |
| 344 | } |
| 345 | } |
| 346 | return false; |
| 347 | }; |
| 348 | |
| 349 | /* First look for any group names which match. */ |
| 350 | |
| 351 | if (!value.empty()) |
| 352 | for (const auto& optionGroup : base()->option_group()) |
| 353 | if (optionGroup.name() == name) |
| 354 | { |
| 355 | /* The option must therefore be one of these. */ |
| 356 | |
| 357 | if (searchOptionList(optionGroup.option(), value)) |
| 358 | return {&optionGroup, found, true}; |
| 359 | |
| 360 | throw OptionNotFoundException(fmt::format( |
| 361 | "value {} is not valid for option {}; valid values are: {}", |
| 362 | value, |
| 363 | name, |
| 364 | fmt::join(std::views::transform( |
| 365 | optionGroup.option(), &OptionProto::name), |
| 366 | ", "))); |
| 367 | } |
| 368 | |
| 369 | /* Now search for individual options. */ |
| 370 | |
| 371 | if (searchOptionList(base()->option(), name)) |
| 372 | return {nullptr, found, false}; |
| 373 | |
| 374 | for (const auto& optionGroup : base()->option_group()) |
| 375 | { |
| 376 | if (optionGroup.name().empty()) |
| 377 | if (searchOptionList(optionGroup.option(), name)) |
| 378 | return {&optionGroup, found, false}; |
| 379 | } |
| 380 | |
| 381 | throw OptionNotFoundException(fmt::format("option {} not found", name)); |
| 382 | } |
| 383 | |
| 384 | void Config::checkOptionValid(const OptionProto& option) |
| 385 | { |