С помощью параметров командной строки я могу сделать следующее:
po::variables_map vm;
auto parsedOptions = po::command_line_parser(argc, argv).options(optionsDescription1).allow_unregistered().run();
po::store(parsedOptions, vm);
po::notify(vm);
auto unregistered = po::collect_unrecognized(parsedOptions.options, po::include_positional);
po::variables_map vm2;
auto parsedOptions2 = po::command_line_parser(unregistered).options(optionsDescription2).run();
po::store(parsedOptions2, vm2);
po::notify(vm2);
Это прекрасно работает, потому что collect_unregistered()
собирает токены командной строки в точности так, как они появились в командной строке. Тем не менее, это не работает для конфигурационных файлов. Я могу разобрать файл конфигурации, разрешив незарегистрированные параметры, но когда я собираю незарегистрированные параметры, я получаю результат, который я не могу использовать.
po::variables_map vm;
auto parsedOptions = po::parse_config_file<char>(filename, optionsDescription1, true);
po::store(parsedOptions, vm);
po::notify(vm);
auto unregistered = po::collect_unrecognized(parsedOptions.options, po::include_positional);
В этом случае я получаю имена и значения перечисленных опций. Например, если файл конфигурации содержит следующие параметры:
unregistered_option1=value1
unregistered_option2=value2
Тогда я получаю значения unregistered_option1
, value1
, unregistered_option2
, value2
в строковом векторе unregistered
, Парсер Boost не может сделать ничего полезного с этим форматом. Есть ли способ проанализировать этот список (то есть проанализировать все параметры, которые не были распознаны первым options_description
с другим options_description
)? Конечно, я могу просто снова проанализировать файл со вторым options_description
с allow_unregistered
установлен, но тогда я не могу проверить опции, неизвестные обоим описаниям.
Вы не должны полагаться на недостатки collect_unrecognized()
возвращаемое значение, вы всегда можете обнаружить, обработать и восстановить параметры самостоятельно, в результате parse_config_file()
сохраняет наблюдаемые отношения для неизвестных вариантов:
auto parsed_options = parse_config_file(ifs, config_file_options, true);
store(parsed_options, vm);
...
for (const auto& o : parsed_options.options) {
if (vm.find(o.string_key) == vm.end()) {
// an unknown option
cout << o.string_key << "=" << o.value << "\n";
}
}