diff --git a/cli/main.cpp b/cli/main.cpp index 2c6ab3b..614a274 100644 --- a/cli/main.cpp +++ b/cli/main.cpp @@ -1,14 +1,172 @@ #include #include +#include +#include +#include +#include #include "katja/database.hpp" -int main() +bool trim_info_line(std::string& info_value) { - for (const auto& entry : std::filesystem::directory_iterator(katja::database)) + if (boost::algorithm::ends_with(info_value, "\"")) { - katja::database_package database_entry{ entry.path().filename() }; + info_value.pop_back(); + return false; + } + else if (boost::algorithm::ends_with(info_value, "\\")) + { + info_value.pop_back(); + return true; + } + return false; +} - std::cout << database_entry.to_string() << std::endl; +struct info_file +{ + const std::string program_name; + const std::string version; + const std::string homepage; + const std::string email; + const std::string maintainer; + + info_file(const std::string& program_name, const std::string& version, + const std::string homepage, const std::string& email, const std::string& maintainer) + : program_name(program_name), version(version), homepage(homepage), email(email), maintainer(maintainer) + { + } +}; + +std::optional read_slackbuild_info(const std::filesystem::path& info_filepath) +{ + std::ifstream info_stream{ info_filepath }; + std::string info_line, info_variable, info_value; + std::string program_name, version, homepage, email, maintainer; + std::vector download, md5sum, download_x86_64, md5sum_x86_64, requires; + bool continuation{ false }; + + while (std::getline(info_stream, info_line)) + { + if (info_line.empty()) + { + continue; + } + else if (!continuation) + { + auto equals_position = std::find(info_line.cbegin(), info_line.cend(), '='); + info_variable = std::string(info_line.cbegin(), equals_position); + + if (equals_position == info_line.cend() + || ++equals_position == info_line.cend() || *equals_position != '"') + { + return std::nullopt; + } + info_value = std::string(std::next(equals_position), info_line.cend()); + } + else + { + info_value += info_line; + } + continuation = trim_info_line(info_value); + + if (!continuation) + { + if (info_variable == "PRGNAM") + { + std::swap(program_name, info_value); + } + else if (info_variable == "VERSION") + { + std::swap(version, info_value); + } + else if (info_variable == "HOMEPAGE") + { + std::swap(homepage, info_value); + } + else if (info_variable == "EMAIL") + { + std::swap(email, info_value); + } + else if (info_variable == "MAINTAINER") + { + std::swap(maintainer, info_value); + } + else if (info_variable == "DOWNLOAD") + { + boost::split(download, info_value, boost::is_any_of(" "), boost::token_compress_on); + } + else if (info_variable == "MD5SUM") + { + boost::split(md5sum, info_value, boost::is_any_of(" "), boost::token_compress_on); + } + else if (info_variable == "DOWNLOAD_x86_64") + { + boost::split(download_x86_64, info_value, boost::is_any_of(" "), boost::token_compress_on); + } + else if (info_variable == "MD5SUM_x86_64") + { + boost::split(md5sum_x86_64, info_value, boost::is_any_of(" "), boost::token_compress_on); + } + else if (info_variable == "REQUIRES") + { + boost::split(requires, info_value, boost::is_any_of(" "), boost::token_compress_on); + } + } + } + return std::make_optional(program_name, version, homepage, email, maintainer); +} + +void search_for_slackbuilds(std::vector& info_files, const std::filesystem::path& directory) +{ + for (const auto& entry : std::filesystem::directory_iterator(directory)) + { + std::filesystem::path entry_path = entry; + std::filesystem::path info_filename = entry_path; + info_filename.replace_extension(".info"); + + std::filesystem::path info_filepath = entry_path / info_filename; + + if (std::filesystem::exists(info_filepath)) + { + auto slackbuild_info = read_slackbuild_info(info_filepath); + + if (slackbuild_info.has_value()) + { + info_files.emplace_back(std::move(slackbuild_info.value())); + } + else + { + std::cout << info_filepath << std::endl; + } + } + else if (std::filesystem::is_directory(entry_path)) + { + search_for_slackbuilds(info_files, entry_path); + } + } +} + +int main(int argc, const char **argv) +{ + std::vector info_files; + + if (argc > 1) + { + std::filesystem::path slackbuild_repository{ argv[1] }; + + search_for_slackbuilds(info_files, slackbuild_repository); + for (const auto& slackbuild_info : info_files) + { + std::cout << slackbuild_info.program_name << " " << slackbuild_info.version << " " << std::endl; + } + } + else + { + for (const auto& entry : std::filesystem::directory_iterator(katja::database)) + { + katja::database_package database_entry{ entry.path().filename() }; + + std::cout << database_entry.to_string() << std::endl; + } } return 0; }