Boost program_options将多个配置文件解析结果存储到一个parsed_options中 [英] Boost program_options store multiple config file parse results into one parsed_options

查看:89
本文介绍了Boost program_options将多个配置文件解析结果存储到一个parsed_options中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图解析命令行中提供的任意数量文件中的未注册选项.假设我有文件:

I'm trying to parse unregistered options in any number of files provided at command line. Let's say I have files:

configs0.ini
configs1.ini
configs2.ini

我想支持其中任何一个.

And I wanted to support any number of these.

我的代码(简体):

namespace po = boost::program_options;
po::options_description cmd_opts{"Options"};
po::options_description config_file_opts;
po::variables_map vm;

cmd_opts.add_options()                                                                                                                                                                                                     
   ("help,h", "Help message")                                       
   ("config_files", po::value<std::vector<std::string>>()->multitoken(), "Configuration files to get settings from")

po::parser.options(reg_config_file_opts).allow_unregistered();

po::store(parse_command_line(argc, argv, cmd_opts), vm);

config_files = vm["config_files"].as<std::vector<std::string>>();
po::parsed_options parsed_opts;

for(auto file : config_files) {
   std::ifstream ifs(file, std::ifstream::in);                                                                                                                                                                             
   if(ifs.fail()) {
      std::cerr << "Error opening config file: " << file << std::endl;
      return false;
   }
   ifs.close();

   <NEED HELP HERE>
   parsed_opt.add(parse_config_file(ifs, reg_config_file_opts));
}

po::store(parsed_opts, vm);

parsed_options是否具有某种.add功能?

Does parsed_options have some sort of .add ability?

推荐答案

  • 说明组件
  • 解析器组件
  • 存储组件
  • 该设计假定您将使用带有一个或多个解析器的一组或多组描述,并将结果合并到一个存储中.

    The design assumes that you will be using one or more sets of descriptions with one or more parsers, and combine the results into one storage.

    实际上,这意味着您将存储到相同的变量映射中,并通知以更新带有副作用的任何值语义.

    In practice this means you will store into the same variable map, and notify to update any value-semantics with side-effects.

    实时演示

    Live Demo

    • 文件 main.cpp

    #include <boost/program_options.hpp>
    #include <boost/program_options/cmdline.hpp>
    #include <boost/program_options/config.hpp>
    #include <fmt/format.h>
    #include <fmt/ranges.h>
    #include <fstream>
    
    namespace po = boost::program_options;
    
    int main() {
        for (auto args : {
                std::vector{"test.exe"},
                std::vector{"test.exe", "--config_files", "a.cfg", "b.cfg", "c.cfg"},
            })
        {
            int const argc    = args.size();
            char const** argv = args.data();
    
            po::options_description cmd_opts{"Options"};
    
            using values = std::vector<std::string>;
            cmd_opts.add_options()                                                                                                                                                                                                     
                ("help,h", "Help message")                                       
                ("config_files", po::value<values>()->multitoken(), "Configuration files to get settings from")
                ;
    
            po::variables_map vm;
            po::variables_map cfg_vm; // can also reuse vm
            po::store(parse_command_line(argc, argv, cmd_opts), vm);
    
            auto& config_files = vm["config_files"];
            if (!config_files.empty()) {
    
                po::options_description config_file_opts;
                config_file_opts.add_options()                                                                                                                                                                                                     
                    ("foo", po::value<values>()->composing())
                    ("bar_a", po::value<values>()->composing())
                    ("bar_b", po::value<values>()->composing())
                    ("bar_c", po::value<values>()->composing())
                    ;
    
                for(auto file : config_files.as<values>()) try {
                    std::ifstream ifs(file);
                    po::store(parse_config_file(ifs, config_file_opts), cfg_vm);
                } catch(std::exception const& e) {
                    fmt::print(stderr, "{}: {}\n", file, e.what());
                }
    
                fmt::print("Cmdline opts\n");
                for (auto& [k, v] : vm) {
                    fmt::print("{}={}\n", k, v.as<values>());
                }
                fmt::print("Combined configs\n");
                for (auto& [k, v] : cfg_vm) {
                    fmt::print("{}={}\n", k, v.as<values>());
                }
            }
        }
    }
    

  • 文件 a.cfg

    foo=foo_val_a
    bar_a=bar_val_a
    

  • 文件 b.cfg

    foo=foo_val_b
    bar_b=bar_val_b
    

  • 文件 c.cfg

    foo=foo_val_c
    bar_c=bar_val_c
    

  • 打印:

    Cmdline opts
    config_files={"a.cfg", "b.cfg", "c.cfg"}
    Combined configs
    bar_a={"bar_val_a"}
    bar_b={"bar_val_b"}
    bar_c={"bar_val_c"}
    foo={"foo_val_a", "foo_val_b", "foo_val_c"}
    

    这篇关于Boost program_options将多个配置文件解析结果存储到一个parsed_options中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆