blob: a6b7e3649523236e5f69dd6c8a06b9410f2ac993 [file] [log] [blame]
#include "config_parser.hpp"
#include <fstream>
#include <regex>
#include <string>
namespace phosphor
{
namespace network
{
namespace config
{
Parser::Parser(const fs::path& filename)
{
setFile(filename);
}
const ValueList& Parser::getValues(std::string_view section,
std::string_view key) const noexcept
{
static const ValueList empty;
auto sit = sections.find(section);
if (sit == sections.end())
{
return empty;
}
auto kit = sit->second.find(key);
if (kit == sit->second.end())
{
return empty;
}
return kit->second;
}
void Parser::setValue(const std::string& section, const std::string& key,
const std::string& value)
{
auto sit = sections.find(section);
if (sit == sections.end())
{
std::tie(sit, std::ignore) = sections.emplace(section, KeyValuesMap{});
}
auto kit = sit->second.find(key);
if (kit == sit->second.end())
{
std::tie(kit, std::ignore) = sit->second.emplace(key, ValueList{});
}
kit->second.push_back(value);
}
void Parser::setFile(const fs::path& filename)
{
std::fstream stream(filename, std::fstream::in);
if (!stream.is_open())
{
return;
}
// clear all the section data.
sections.clear();
static const std::regex commentRegex{R"x(\s*[;#])x"};
static const std::regex sectionRegex{R"x(\s*\[([^\]]+)\])x"};
static const std::regex valueRegex{R"x(\s*(\S[^ \t=]*)\s*=\s*(\S+)\s*$)x"};
std::string section;
std::smatch pieces;
for (std::string line; std::getline(stream, line);)
{
if (line.empty() || std::regex_match(line, pieces, commentRegex))
{
// skip comment lines and blank lines
}
else if (std::regex_match(line, pieces, sectionRegex))
{
if (pieces.size() == 2)
{
section = pieces[1].str();
}
}
else if (std::regex_match(line, pieces, valueRegex))
{
if (pieces.size() == 3)
{
setValue(section, pieces[1].str(), pieces[2].str());
}
}
}
}
} // namespace config
} // namespace network
} // namespace phosphor