我正在使用一个可以从以下位置读取选项的命令行工具:
我使用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中是否有一种方法可以知道选项的值来自何处,以便在将相对路径转换为绝对路径时调整路径?
答案 0 :(得分:0)
默认情况下,有一个工作目录设置为执行路径。根据工作目录解释所有相对路径(您尝试在应用程序中使用)。 您必须有选择来实现目标:
答案 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是执行目录,在第二种情况下,它是配置文件父文件夹。