#include "config_parser.hpp" #include "xyz/openbmc_project/Common/error.hpp" #include #include #include #include #include #include #include #include namespace phosphor { namespace network { namespace config { using namespace phosphor::logging; using namespace sdbusplus::xyz::openbmc_project::Common::Error; Parser::Parser(const fs::path& filePath) { setFile(filePath); } KeyValues Parser::getSection(const std::string& section) { auto it = sections.find(section); if (it == sections.end()) { log("ConfigParser: Section not found", entry("SECTION=%s",section)); elog(); } return it->second; } std::vector Parser::getValues(const std::string& section, const std::string& key) { std::vector values; auto keyValues = getSection(section); auto it = keyValues.find(key); if (it == keyValues.end()) { log("ConfigParser: Key not found", entry("KEY=%s",key)); elog(); } for (; it != keyValues.end() && key == it->first; it++) { values.push_back(it->second); } return values; } bool Parser::isValueExist(const std::string& section, const std::string& key, const std::string& value) { try { auto values = getValues(section, key); auto it = std::find(values.begin(), values.end(), value); return it != std::end(values) ? true : false; } catch (InternalFailure& e) { commit(); } return false; } void Parser::setValue(const std::string& section, const std::string& key, const std::string& value) { KeyValues values; auto it = sections.find(section); if (it != sections.end()) { values = std::move(it->second); } values.insert(std::make_pair(key, value)); if (it != sections.end()) { it->second = std::move(values); } else { sections.insert(std::make_pair(section, std::move(values))); } } #if 0 void Parser::print() { for (auto section : sections) { std::cout << "[" << section.first << "]\n\n"; for (auto keyValue : section.second) { std::cout << keyValue.first << "=" << keyValue.second << "\n"; } } } #endif void Parser::setFile(const fs::path& filePath) { this->filePath = filePath; std::fstream stream; stream.open(filePath.string(), std::fstream::in); if (!stream.is_open()) { return; } //clear all the section data. sections.clear(); parse(stream); stream.close(); } void Parser::parse(std::istream& in) { 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(in, 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