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

Commit 89bcc85e authored by Tom Cherry's avatar Tom Cherry
Browse files

init: use Result<T> for the parsing functions

Test: boot bullhead
Merged-In: I7f00c5f0f54dd4fe05df73e1d6a89b56d788e113
Change-Id: I7f00c5f0f54dd4fe05df73e1d6a89b56d788e113
parent 557946e5
Loading
Loading
Loading
Loading
+32 −41
Original line number Diff line number Diff line
@@ -53,19 +53,16 @@ Action::Action(bool oneshot, const std::string& filename, int line)

const KeywordMap<BuiltinFunction>* Action::function_map_ = nullptr;

bool Action::AddCommand(const std::vector<std::string>& args, int line, std::string* err) {
Result<Success> Action::AddCommand(const std::vector<std::string>& args, int line) {
    if (!function_map_) {
        *err = "no function map available";
        return false;
        return Error() << "no function map available";
    }

    auto function = function_map_->FindFunction(args, err);
    if (!function) {
        return false;
    }
    auto function = function_map_->FindFunction(args);
    if (!function) return Error() << function.error();

    AddCommand(function, args, line);
    return true;
    AddCommand(*function, args, line);
    return Success();
}

void Action::AddCommand(BuiltinFunction f, const std::vector<std::string>& args, int line) {
@@ -105,67 +102,60 @@ void Action::ExecuteCommand(const Command& command) const {
    }
}

bool Action::ParsePropertyTrigger(const std::string& trigger, std::string* err) {
Result<Success> Action::ParsePropertyTrigger(const std::string& trigger) {
    const static std::string prop_str("property:");
    std::string prop_name(trigger.substr(prop_str.length()));
    size_t equal_pos = prop_name.find('=');
    if (equal_pos == std::string::npos) {
        *err = "property trigger found without matching '='";
        return false;
        return Error() << "property trigger found without matching '='";
    }

    std::string prop_value(prop_name.substr(equal_pos + 1));
    prop_name.erase(equal_pos);

    if (auto [it, inserted] = property_triggers_.emplace(prop_name, prop_value); !inserted) {
        *err = "multiple property triggers found for same property";
        return false;
        return Error() << "multiple property triggers found for same property";
    }
    return true;
    return Success();
}

bool Action::InitTriggers(const std::vector<std::string>& args, std::string* err) {
Result<Success> Action::InitTriggers(const std::vector<std::string>& args) {
    const static std::string prop_str("property:");
    for (std::size_t i = 0; i < args.size(); ++i) {
        if (args[i].empty()) {
            *err = "empty trigger is not valid";
            return false;
            return Error() << "empty trigger is not valid";
        }

        if (i % 2) {
            if (args[i] != "&&") {
                *err = "&& is the only symbol allowed to concatenate actions";
                return false;
                return Error() << "&& is the only symbol allowed to concatenate actions";
            } else {
                continue;
            }
        }

        if (!args[i].compare(0, prop_str.length(), prop_str)) {
            if (!ParsePropertyTrigger(args[i], err)) {
                return false;
            if (auto result = ParsePropertyTrigger(args[i]); !result) {
                return result;
            }
        } else {
            if (!event_trigger_.empty()) {
                *err = "multiple event triggers are not allowed";
                return false;
                return Error() << "multiple event triggers are not allowed";
            }

            event_trigger_ = args[i];
        }
    }

    return true;
    return Success();
}

bool Action::InitSingleTrigger(const std::string& trigger) {
Result<Success> Action::InitSingleTrigger(const std::string& trigger) {
    std::vector<std::string> name_vector{trigger};
    std::string err;
    bool ret = InitTriggers(name_vector, &err);
    if (!ret) {
        LOG(ERROR) << "InitSingleTrigger failed due to: " << err;
    if (auto result = InitTriggers(name_vector); !result) {
        return Error() << "InitTriggers() failed: " << result.error();
    }
    return ret;
    return Success();
}

// This function checks that all property triggers are satisfied, that is
@@ -263,7 +253,8 @@ void ActionManager::QueueBuiltinAction(BuiltinFunction func, const std::string&
    auto action = std::make_unique<Action>(true, "<Builtin Action>", 0);
    std::vector<std::string> name_vector{name};

    if (!action->InitSingleTrigger(name)) {
    if (auto result = action->InitSingleTrigger(name); !result) {
        LOG(ERROR) << "Cannot queue BuiltinAction for " << name << ": " << result.error();
        return;
    }

@@ -332,25 +323,25 @@ void ActionManager::ClearQueue() {
    current_command_ = 0;
}

bool ActionParser::ParseSection(std::vector<std::string>&& args, const std::string& filename,
                                int line, std::string* err) {
Result<Success> ActionParser::ParseSection(std::vector<std::string>&& args,
                                           const std::string& filename, int line) {
    std::vector<std::string> triggers(args.begin() + 1, args.end());
    if (triggers.size() < 1) {
        *err = "actions must have a trigger";
        return false;
        return Error() << "Actions must have a trigger";
    }

    auto action = std::make_unique<Action>(false, filename, line);
    if (!action->InitTriggers(triggers, err)) {
        return false;

    if (auto result = action->InitTriggers(triggers); !result) {
        return Error() << "InitTriggers() failed: " << result.error();
    }

    action_ = std::move(action);
    return true;
    return Success();
}

bool ActionParser::ParseLineSection(std::vector<std::string>&& args, int line, std::string* err) {
    return action_ ? action_->AddCommand(std::move(args), line, err) : false;
Result<Success> ActionParser::ParseLineSection(std::vector<std::string>&& args, int line) {
    return action_ ? action_->AddCommand(std::move(args), line) : Success();
}

void ActionParser::EndSection() {
+7 −7
Original line number Diff line number Diff line
@@ -54,10 +54,10 @@ class Action {
  public:
    explicit Action(bool oneshot, const std::string& filename, int line);

    bool AddCommand(const std::vector<std::string>& args, int line, std::string* err);
    Result<Success> AddCommand(const std::vector<std::string>& args, int line);
    void AddCommand(BuiltinFunction f, const std::vector<std::string>& args, int line);
    bool InitTriggers(const std::vector<std::string>& args, std::string* err);
    bool InitSingleTrigger(const std::string& trigger);
    Result<Success> InitTriggers(const std::vector<std::string>& args);
    Result<Success> InitSingleTrigger(const std::string& trigger);
    std::size_t NumCommands() const;
    void ExecuteOneCommand(std::size_t command) const;
    void ExecuteAllCommands() const;
@@ -79,7 +79,7 @@ private:
    void ExecuteCommand(const Command& command) const;
    bool CheckPropertyTriggers(const std::string& name = "",
                               const std::string& value = "") const;
    bool ParsePropertyTrigger(const std::string& trigger, std::string* err);
    Result<Success> ParsePropertyTrigger(const std::string& trigger);

    std::map<std::string, std::string> property_triggers_;
    std::string event_trigger_;
@@ -121,9 +121,9 @@ class ActionParser : public SectionParser {
  public:
    ActionParser(ActionManager* action_manager)
        : action_manager_(action_manager), action_(nullptr) {}
    bool ParseSection(std::vector<std::string>&& args, const std::string& filename, int line,
                      std::string* err) override;
    bool ParseLineSection(std::vector<std::string>&& args, int line, std::string* err) override;
    Result<Success> ParseSection(std::vector<std::string>&& args, const std::string& filename,
                                 int line) override;
    Result<Success> ParseLineSection(std::vector<std::string>&& args, int line) override;
    void EndSection() override;

  private:
+5 −7
Original line number Diff line number Diff line
@@ -23,24 +23,22 @@
namespace android {
namespace init {

bool ImportParser::ParseSection(std::vector<std::string>&& args, const std::string& filename,
                                int line, std::string* err) {
Result<Success> ImportParser::ParseSection(std::vector<std::string>&& args,
                                           const std::string& filename, int line) {
    if (args.size() != 2) {
        *err = "single argument needed for import\n";
        return false;
        return Error() << "single argument needed for import\n";
    }

    std::string conf_file;
    bool ret = expand_props(args[1], &conf_file);
    if (!ret) {
        *err = "error while expanding import";
        return false;
        return Error() << "error while expanding import";
    }

    LOG(INFO) << "Added '" << conf_file << "' to import list";
    if (filename_.empty()) filename_ = filename;
    imports_.emplace_back(std::move(conf_file), line);
    return true;
    return Success();
}

void ImportParser::EndFile() {
+2 −2
Original line number Diff line number Diff line
@@ -28,8 +28,8 @@ namespace init {
class ImportParser : public SectionParser {
  public:
    ImportParser(Parser* parser) : parser_(parser) {}
    bool ParseSection(std::vector<std::string>&& args, const std::string& filename, int line,
                      std::string* err) override;
    Result<Success> ParseSection(std::vector<std::string>&& args, const std::string& filename,
                                 int line) override;
    void EndFile() override;

  private:
+12 −17
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@

#include <android-base/stringprintf.h>

#include "result.h"

namespace android {
namespace init {

@@ -34,20 +36,17 @@ class KeywordMap {
    virtual ~KeywordMap() {
    }

    const Function FindFunction(const std::vector<std::string>& args, std::string* err) const {
    const Result<Function> FindFunction(const std::vector<std::string>& args) const {
        using android::base::StringPrintf;

        if (args.empty()) {
            *err = "keyword needed, but not provided";
            return nullptr;
        }
        if (args.empty()) return Error() << "Keyword needed, but not provided";

        auto& keyword = args[0];
        auto num_args = args.size() - 1;

        auto function_info_it = map().find(keyword);
        if (function_info_it == map().end()) {
            *err = StringPrintf("invalid keyword '%s'", keyword.c_str());
            return nullptr;
            return Error() << StringPrintf("Invalid keyword '%s'", keyword.c_str());
        }

        auto function_info = function_info_it->second;
@@ -55,22 +54,18 @@ class KeywordMap {
        auto min_args = std::get<0>(function_info);
        auto max_args = std::get<1>(function_info);
        if (min_args == max_args && num_args != min_args) {
            *err = StringPrintf("%s requires %zu argument%s",
                                keyword.c_str(), min_args,
            return Error() << StringPrintf("%s requires %zu argument%s", keyword.c_str(), min_args,
                                           (min_args > 1 || min_args == 0) ? "s" : "");
            return nullptr;
        }

        if (num_args < min_args || num_args > max_args) {
            if (max_args == std::numeric_limits<decltype(max_args)>::max()) {
                *err = StringPrintf("%s requires at least %zu argument%s",
                                    keyword.c_str(), min_args,
                                    min_args > 1 ? "s" : "");
                return Error() << StringPrintf("%s requires at least %zu argument%s",
                                               keyword.c_str(), min_args, min_args > 1 ? "s" : "");
            } else {
                *err = StringPrintf("%s requires between %zu and %zu arguments",
                return Error() << StringPrintf("%s requires between %zu and %zu arguments",
                                               keyword.c_str(), min_args, max_args);
            }
            return nullptr;
        }

        return std::get<Function>(function_info);
Loading