#include #include #include #include #include #include #include "katja/database.hpp" bool trim_info_line(std::string& info_value) { if (boost::algorithm::ends_with(info_value, "\"")) { info_value.pop_back(); return false; } else if (boost::algorithm::ends_with(info_value, "\\")) { info_value.pop_back(); return true; } return false; } 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; }