diff --git a/src/initcpio.cpp b/src/initcpio.cpp index 4c89173..fd83b59 100644 --- a/src/initcpio.cpp +++ b/src/initcpio.cpp @@ -3,6 +3,7 @@ #include // for ofstream +#include #include #if defined(__clang__) @@ -62,4 +63,33 @@ bool Initcpio::write() const noexcept { return true; } +bool Initcpio::parse_file() noexcept { + auto&& file_content = utils::read_whole_file(m_file_path); + + const auto& parse_line = [](auto&& line) -> std::vector { + auto&& open_bracket_pos = line.find('('); + auto&& close_bracket = ranges::find(line, ')'); + if (open_bracket_pos != std::string::npos && close_bracket != line.end()) { + const auto length = ranges::distance(line.begin() + static_cast(open_bracket_pos), close_bracket - 1); + + auto&& input_data = line.substr(open_bracket_pos + 1, static_cast(length)); + return input_data | ranges::views::split(' ') | ranges::to>(); + } + return {}; + }; + + auto&& file_content_lines = utils::make_multiline(file_content); + for (auto&& line : file_content_lines) { + if (line.starts_with("MODULES")) { + modules = parse_line(line); + } else if (line.starts_with("FILES")) { + files = parse_line(line); + } else if (line.starts_with("HOOKS")) { + hooks = parse_line(line); + } + } + + return true; +} + } // namespace detail diff --git a/src/initcpio.hpp b/src/initcpio.hpp index 848ae3c..6cec77f 100644 --- a/src/initcpio.hpp +++ b/src/initcpio.hpp @@ -11,6 +11,19 @@ class Initcpio { public: Initcpio(const std::string_view& file_path) noexcept : m_file_path(file_path) {} + bool parse_file() noexcept; + + inline bool append_module(std::string&& module) noexcept { + if (!this->parse_file()) { return false; } + modules.emplace_back(std::move(module)); + return this->write(); + } + inline bool append_hook(std::string&& hook) noexcept { + if (!this->parse_file()) { return false; } + hooks.emplace_back(std::move(hook)); + return this->write(); + } + bool write() const noexcept; std::vector modules{}; diff --git a/tests/unit-initcpio.cpp b/tests/unit-initcpio.cpp index f00443d..f5e994d 100644 --- a/tests/unit-initcpio.cpp +++ b/tests/unit-initcpio.cpp @@ -28,7 +28,7 @@ HOOKS=(base udev autodetect modconf block filesystems keyboard fsck) static constexpr auto MKINITCPIO_TEST = R"( # MODULES -MODULES=(crc32c-intel) +MODULES=(radeon crc32c-intel) # BINARIES BINARIES=() @@ -37,7 +37,7 @@ BINARIES=() FILES=() # HOOKS -HOOKS=(base usr lvm2 zfs) +HOOKS=(base udev autodetect modconf block filesystems keyboard fsck btrfs usr lvm2 zfs) )"; @@ -55,15 +55,17 @@ int main() { auto initcpio = detail::Initcpio{filename}; // Insert data. + initcpio.append_module("radeon"); + initcpio.append_hook("btrfs"); initcpio.modules.insert(initcpio.modules.end(), {"crc32c-intel"}); - initcpio.hooks.insert(initcpio.hooks.end(), {"base", "usr", "lvm2", "zfs"}); + initcpio.hooks.insert(initcpio.hooks.end(), {"usr", "lvm2", "zfs"}); // Write data. assert(initcpio.write()); // Check if file is equal to test data. // "\n# MODULES\nMODULES=(crc32c-intel)\n\n# BINARIES\nBINARIES=()\n\n# FILES\nFILES=()\n\n# HOOKS\nHOOKS=(base usr lvm2 zfs)"\n - const auto&& file_content = utils::read_whole_file(filename); + const auto& file_content = utils::read_whole_file(filename); assert(file_content == MKINITCPIO_TEST); // Cleanup.