Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 35c5bcc8 authored by Tom Cherry's avatar Tom Cherry
Browse files

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
parent 5002a48c
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -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();
+15 −12
Original line number Diff line number Diff line
@@ -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;