使用Boost Program选项读取相对文件路径

时间:2015-03-17 13:14:46

标签: c++ path boost-program-options

我正在使用一个可以从以下位置读取选项的命令行工具:

  • 命令行参数
  • 可选配置文件

我使用Boost Program Options来阅读这些选项,它的工作原理非常好。

我的代码是这样的:

namespace po = boost::program_options;
namespace fs = boost::filesystem;

po::variables_map vm;
po::store(po::parse_command_line(argc, argv, options), vm);
po::store(po::parse_config_file(ifs, options, true), vm);
po::notify(vm);

但是,其中一些选项是文件路径,我希望它们与选项的原点相关。这是我的意思的一个例子:

假设我的工具位于:/usr/local/bin

mytool --foo.path ../config/assets/toto.txt

解析后,foo.path选项应该是/usr/local/config/assets/toto.txt的绝对路径。

现在,如果我在配置文件中指定foo.path,位于/usr/local/config/myconf.cfg,就像这样:

foo.path=assets/toto.txt

我希望路径相对于配置文件(而不是执行路径),并且生成的绝对路径与之前相同。

Boost Program Options中是否有一种方法可以知道选项的值来自何处,以便在将相对路径转换为绝对路径时调整路径?

2 个答案:

答案 0 :(得分:0)

默认情况下,有一个工作目录设置为执行路径。根据工作目录解释所有相对路径(您尝试在应用程序中使用)。 您必须有选择来实现目标:

  1. 在解释配置文件中的相对路径之前更改工作目录。如果需要,您应该在完成阅读配置后恢复工作目录的默认值。
  2. 从配置中获得一些路径后,您必须检查它是否是相对路径。如果是这样,那么您应该使用配置文件的主目录编写代码来构建正确的路径。

答案 1 :(得分:0)

我最终可以通过在每个解析阶段后手动添加上下文来实现这一点。

我写的添加上下文的功能如下:

namespace po = boost::program_options;
namespace fs = boost::filesystem;

void make_path_absolute(
    const std::string& name,
    po::variables_map& vm,
    const fs::path& root)
{
    if (vm.count(name) > 0) {
        const auto path = vm[name].as<fs::path>();

        if (!path.empty()) {
            vm.at(name).value() = fs::absolute(path, root);
        }
    }
}

使用的是:

namespace po = boost::program_options;
namespace fs = boost::filesystem;

po::variables_map vm;

po::store(po::parse_command_line(argc, argv, options), vm);
make_path_absolute("foo.path", vm, fs::current_path());

po::store(po::parse_config_file(ifs, options, true), vm);
make_path_absolute("foo.path", vm, configuration_file.parent_path());

po::notify(vm);

基本上,调用的作用是使路径选项相对于指定的根绝对(如果它已经不存在)。在第一种情况下,root是执行目录,在第二种情况下,它是配置文件父文件夹。