That's not what Program Options is about. You can use it to read ini files, but not with the code shown. You are literally invoking parse_command_line
(not parse_config_file
).
The code you show allows you to parse the name of a config file from the command line. This is also why the value is std::string file_name
.
Maybe we're missing (quite a lot of) code, because there's also nothing invoking to_cout
in your code, nevermind that it wouldn't work with vm
because the argument type doesn't directly match. I know you can loop over matched names in the variable map, and this is likely what you did, but that's all not very relevant.
Even if you did call parse_config_file
would not know how to read that file format, as the documented format is an INI-file flavour.
The Good News
The good news is that your config file does have a format that closely resembles INFO files as supported by Boost Property Tree. Which gives me the first opportunity in 10 years¹ to actually suggest using that library: It seems to be more or less precisely what you are after:
Live On Coliru
#include <boost/property_tree/info_parser.hpp>
#include <iostream>
extern std::string config;
int main() {
boost::property_tree::ptree pt;
std::istringstream iss(config);
read_info(iss, pt);
write_info(std::cout, pt);
}
std::string config = R"(
Resnet50 {
Layer CONV1 {
Type: CONV
Stride { X: 2, Y: 2 }
Dimensions { K: 64, C: 3, R: 7, S: 7, Y:224, X:224 }
}
Layer CONV2_1_1 {
Type: CONV
Stride { X: 1, Y: 1 }
Dimensions { K: 64, C: 64, R: 1, S: 1, Y: 56, X: 56 }
}
}
)";
Prints
Resnet50
{
Layer CONV1
{
Type: CONV
Stride
{
X: 2,
Y: 2
}
Dimensions
{
K: 64,
C: 3,
R: 7,
S: 7,
Y:224, X:224
}
}
Layer CONV2_1_1
{
Type: CONV
Stride
{
X: 1,
Y: 1
}
Dimensions
{
K: 64,
C: 64,
R: 1,
S: 1,
Y: 56,
X: 56
}
}
}
Tieing It Together
You may tie it together with a CLI argument for the filename:
Live On Coliru
#include <boost/property_tree/info_parser.hpp>
#include <boost/program_options.hpp>
#include <iostream>
using boost::property_tree::ptree;
int main(int argc, char* argv[]) {
std::string file_name;
{
namespace po = boost::program_options;
po::options_description cliopts("options");
cliopts.add_options() //
("config_file", po::value<std::string>(&file_name),
"HW configuration file");
po::variables_map vm;
po::store(po::parse_command_line(argc, argv, cliopts), vm);
if (!vm.contains("config_file")) {
std::cerr << cliopts << '\n';
return 255;
}
po::notify(vm); // sets file_name
}
boost::property_tree::ptree pt;
{
std::ifstream ifs(file_name);
read_info(ifs, pt);
} // closes file
for (auto const& [key, sub] : pt.get_child("Resnet50")) {
std::cout << key << " " << sub.get_value("") << "\n";
}
}
Then for running ./test.exe --config_file config.cfg
it may print e.g.
Layer CONV1
Layer CONV2_1_1
¹ 10 years (and more) of admonishing people not to abuse Property Tree as an XML, INI, or JSON parser, because it is none of these things. It's ... a property tree library.