init: add Parser::AddSingleLineParser()

Add the ability to override the current section being parsed and
instead parse a line by itself if a given line starts with a specific
prefix.

Test: Boot bullhead
Change-Id: Idbbf2682b78996b41d05f3db655c8937a8c6ccda
This commit is contained in:
Tom Cherry 2017-04-24 16:55:30 -07:00
parent 5002a48cee
commit 35c5bcc89c
2 changed files with 34 additions and 12 deletions

View file

@ -20,6 +20,7 @@
#include <android-base/logging.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include "parser.h"
#include "util.h"
@ -37,6 +38,10 @@ void Parser::AddSectionParser(const std::string& name,
section_parsers_[name] = std::move(parser);
}
void Parser::AddSingleLineParser(const std::string& prefix, LineCallback callback) {
line_callbacks_.emplace_back(prefix, callback);
}
void Parser::ParseData(const std::string& filename, const std::string& data) {
//TODO: Use a parser with const input and remove this copy
std::vector<char> data_copy(data.begin(), data.end());
@ -63,6 +68,20 @@ void Parser::ParseData(const std::string& filename, const std::string& data) {
if (args.empty()) {
break;
}
// If we have a line matching a prefix we recognize, call its callback and unset any
// current section parsers. This is meant for /sys/ and /dev/ line entries for uevent.
for (const auto& [prefix, callback] : line_callbacks_) {
if (android::base::StartsWith(args[0], prefix.c_str())) {
if (section_parser) section_parser->EndSection();
std::string ret_err;
if (!callback(std::move(args), &ret_err)) {
parse_error(&state, "%s\n", ret_err.c_str());
}
section_parser = nullptr;
break;
}
}
if (section_parsers_.count(args[0])) {
if (section_parser) {
section_parser->EndSection();

View file

@ -57,24 +57,26 @@ class SectionParser {
class Parser {
public:
// LineCallback is the type for callbacks that can parse a line starting with a given prefix.
//
// They take the form of bool Callback(std::vector<std::string>&& args, std::string* err)
//
// Similar to ParseSection() and ParseLineSection(), this function returns bool with false
// indicating a failure and has an std::string* err parameter into which an error string can
// be written.
using LineCallback = std::function<bool(std::vector<std::string>&&, std::string*)>;
static Parser& GetInstance();
// Exposed for testing
Parser();
bool ParseConfig(const std::string& path);
void AddSectionParser(const std::string& name,
std::unique_ptr<SectionParser> parser);
void set_is_system_etc_init_loaded(bool loaded) {
is_system_etc_init_loaded_ = loaded;
}
void set_is_vendor_etc_init_loaded(bool loaded) {
is_vendor_etc_init_loaded_ = loaded;
}
void set_is_odm_etc_init_loaded(bool loaded) {
is_odm_etc_init_loaded_ = loaded;
}
void AddSectionParser(const std::string& name, std::unique_ptr<SectionParser> parser);
void AddSingleLineParser(const std::string& prefix, LineCallback callback);
void set_is_system_etc_init_loaded(bool loaded) { is_system_etc_init_loaded_ = loaded; }
void set_is_vendor_etc_init_loaded(bool loaded) { is_vendor_etc_init_loaded_ = loaded; }
void set_is_odm_etc_init_loaded(bool loaded) { is_odm_etc_init_loaded_ = loaded; }
bool is_system_etc_init_loaded() { return is_system_etc_init_loaded_; }
bool is_vendor_etc_init_loaded() { return is_vendor_etc_init_loaded_; }
bool is_odm_etc_init_loaded() { return is_odm_etc_init_loaded_; }
@ -85,6 +87,7 @@ class Parser {
bool ParseConfigDir(const std::string& path);
std::map<std::string, std::unique_ptr<SectionParser>> section_parsers_;
std::vector<std::pair<std::string, LineCallback>> line_callbacks_;
bool is_system_etc_init_loaded_ = false;
bool is_vendor_etc_init_loaded_ = false;
bool is_odm_etc_init_loaded_ = false;