From 5a967ad8ba620c4aa1881e7ec72ffebbf56e96e8 Mon Sep 17 00:00:00 2001 From: BurntRanch <69512353+BurntRanch@users.noreply.github.com> Date: Thu, 19 Jun 2025 22:25:31 +0300 Subject: [PATCH 001/143] plugins: trying to add plugins support (concepts atm) --- include/parse.hpp | 20 +++++----- include/query.hpp | 33 +++++++++++----- src/display.cpp | 24 +++++++++--- src/gui.cpp | 2 +- src/libs/toml++/Makefile | 2 +- src/parse.cpp | 77 ++++++++++++++++++++----------------- src/query/android/gpu.cpp | 2 +- src/query/android/theme.cpp | 4 +- src/query/linux/disk.cpp | 36 ++++------------- src/query/linux/gpu.cpp | 20 ++++------ src/query/linux/theme.cpp | 32 +++++++-------- 11 files changed, 127 insertions(+), 125 deletions(-) diff --git a/include/parse.hpp b/include/parse.hpp index 9100cd23..1d13f983 100644 --- a/include/parse.hpp +++ b/include/parse.hpp @@ -26,16 +26,14 @@ #ifndef _PARSE_HPP #define _PARSE_HPP +#include +#include #include #include #include #include - #include "config.hpp" - -// from query.hpp -using systemInfo_t = - std::unordered_map>>; +#include "query.hpp" /* The additional args that parse() needs for getting the necessary infos/configs. * Only used for making the argument passing more clear. @@ -43,7 +41,7 @@ using systemInfo_t = */ struct parse_args_t { - systemInfo_t& systemInfo; + moduleMap_t& systemInfo; std::string& pureOutput; std::vector& layout; std::vector& tmp_layout; @@ -66,7 +64,7 @@ struct parse_args_t * @param parsingLayout If we are parsing layout or not * @param no_more_reset If we are recursively parsing, e.g we are inside tags */ -std::string parse(std::string input, systemInfo_t& systemInfo, std::string& pureOutput, +std::string parse(std::string input, moduleMap_t& systemInfo, std::string& pureOutput, std::vector& layout, std::vector& tmp_layout, const Config& config, const colors_t& colors, const bool parsingLayout, bool& no_more_reset); @@ -83,8 +81,8 @@ std::string parse(const std::string& input, std::string& _, parse_args_t& parse_ * @param moduleMemberName The module member name * @param parse_args The parse() like arguments */ -void addValueFromModuleMember(const std::string& moduleName, const std::string& moduleMemberName, - parse_args_t& parse_args); +// void addValueFromModuleMember(const std::string& moduleName, const std::string& moduleMemberName, +// parse_args_t& parse_args); /* Set module only values to a systemInfo_t map. * If the name of said module matches any module name, it will be added @@ -92,7 +90,7 @@ void addValueFromModuleMember(const std::string& moduleName, const std::string& * @param moduleName The module name * @param parse_args The parse() like arguments */ -void addValueFromModule(const std::string& moduleName, parse_args_t& parse_args); +// void addValueFromModule(const std::string& moduleName, parse_args_t& parse_args); /* * Return an info module member value @@ -100,7 +98,7 @@ void addValueFromModule(const std::string& moduleName, parse_args_t& parse_args) * @param moduleName The module name * @param moduleMemberName The module member name */ -std::string getInfoFromName(const systemInfo_t& systemInfo, const std::string_view moduleName, +const std::string getInfoFromName(const moduleMap_t& systemInfo, const std::string_view moduleName, const std::string_view moduleMemberName); /* diff --git a/include/query.hpp b/include/query.hpp index 9408593b..37a77f47 100644 --- a/include/query.hpp +++ b/include/query.hpp @@ -28,13 +28,14 @@ #include #include +#include +#include #include #include #include #include #include "config.hpp" -#include "parse.hpp" #include "util.hpp" extern "C" { @@ -52,9 +53,21 @@ extern "C" { #include } -// Special variable for storing info modules values -using systemInfo_t = - std::unordered_map>>; +struct module_t { + std::string name; + std::vector> submodules; + std::function handler; + + module_t(const std::string &name, const std::vector> &submodules, const std::function handler) : name(name), submodules(submodules), handler(handler) { + + } +}; + +struct parse_args_t; + +// Map from a modules name to its pointer. +using moduleMap_t = + std::unordered_map>; // used in systemInfo_t most of the time using variant = std::variant; @@ -173,10 +186,10 @@ class Theme std::string cursor_size{ UNKNOWN }; }; - Theme(const std::uint8_t ver, systemInfo_t& queried_themes, const std::string& theme_name_version, + Theme(const std::uint8_t ver/*, moduleMap_t& queried_themes*/, const std::string& theme_name_version, const Config& config, const bool gsettings_only = false); - Theme(systemInfo_t& queried_themes, const Config& config, const bool gsettings_only = false); + Theme(/*moduleMap_t& queried_themes, */const Config& config, const bool gsettings_only = false); std::string gtk_theme() noexcept; std::string gtk_icon_theme() noexcept; @@ -188,7 +201,7 @@ class Theme User query_user; std::string m_wmde_name; std::string m_theme_name; - systemInfo_t& m_queried_themes; + // moduleMap_t& m_queried_themes; static Theme_t m_theme_infos; }; @@ -242,7 +255,7 @@ class GPU std::string vendor{ MAGIC_LINE }; }; - GPU(const std::string& id, systemInfo_t& queried_gpus); + GPU(const std::string& id/*, moduleMap_t& queried_gpus*/); std::string& name() noexcept; std::string& vendor() noexcept; @@ -299,7 +312,7 @@ class Disk int types_disk = 0; }; - Disk(const std::string& path, systemInfo_t& queried_paths, parse_args_t& parse_args, + Disk(const std::string& path, parse_args_t& parse_args, const bool auto_module = false); double& total_amount() noexcept; @@ -314,7 +327,7 @@ class Disk { return m_disks_formats; } private: - std::vector m_disks_formats, m_queried_devices; + std::vector m_disks_formats/*, m_queried_devices*/; static Disk_t m_disk_infos; }; diff --git a/src/display.cpp b/src/display.cpp index ea7673a0..4de42ca7 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -29,6 +29,9 @@ #include "platform.hpp" #include #include +#include +#include +#include #ifndef GUI_APP # define STB_IMAGE_IMPLEMENTATION @@ -92,7 +95,7 @@ std::string Display::detect_distro(const Config& config) #endif } -static std::vector render_with_image(systemInfo_t& systemInfo, std::vector& layout, +static std::vector render_with_image(moduleMap_t& systemInfo, std::vector& layout, const Config& config, const colors_t& colors, const std::string_view path, const std::uint16_t font_width, const std::uint16_t font_height) @@ -217,12 +220,21 @@ static bool get_pos(int& y, int& x) return true; } +const std::string test() { + return "Test!!!"; +} + std::vector Display::render(const Config& config, const colors_t& colors, const bool already_analyzed_file, const std::string_view path) { - systemInfo_t systemInfo{}; + moduleMap_t moduleMap{}; std::vector asciiArt{}, layout{ config.args_layout.empty() ? config.layout : config.args_layout }; + std::shared_ptr module = std::make_shared("test!", std::vector>(), test); + + /* TODO(burntranch): remove test */ + moduleMap.emplace("test.module.123", std::move(module)); + debug("Display::render path = {}", path); bool isImage = false; @@ -266,7 +278,7 @@ std::vector Display::render(const Config& config, const colors_t& c std::ifstream distro_file(distro_path); std::string line, _; std::vector tmp_layout; - parse_args_t parse_args{ systemInfo, _, layout, tmp_layout, config, colors, false }; + parse_args_t parse_args{ moduleMap, _, layout, tmp_layout, config, colors, false }; while (std::getline(distro_file, line)) { @@ -294,7 +306,7 @@ std::vector Display::render(const Config& config, const colors_t& c get_pos(y, x); fmt::print("\033[{};{}H", y, x); - return render_with_image(systemInfo, layout, config, colors, path, font_width, font_height); + return render_with_image(moduleMap, layout, config, colors, path, font_width, font_height); } if (Display::ascii_logo_fd != -1) @@ -319,7 +331,7 @@ std::vector Display::render(const Config& config, const colors_t& c { std::string pureOutput; std::vector tmp_layout; - parse_args_t parse_args{ systemInfo, pureOutput, layout, tmp_layout, config, colors, false }; + parse_args_t parse_args{ moduleMap, pureOutput, layout, tmp_layout, config, colors, false }; std::string asciiArt_s = parse(line, parse_args); parse_args.no_more_reset = false; @@ -348,7 +360,7 @@ std::vector Display::render(const Config& config, const colors_t& c std::string _; std::vector tmp_layout; - parse_args_t parse_args{ systemInfo, _, layout, tmp_layout, config, colors, true }; + parse_args_t parse_args{ moduleMap, _, layout, tmp_layout, config, colors, true }; for (size_t i = 0; i < layout.size(); ++i) { layout[i] = parse(layout[i], parse_args); diff --git a/src/gui.cpp b/src/gui.cpp index a36373dd..7225a8d7 100644 --- a/src/gui.cpp +++ b/src/gui.cpp @@ -63,7 +63,7 @@ using namespace GUI; static std::vector render_with_image(const Config& config, const colors_t& colors) { std::string path{ Display::detect_distro(config) }; - systemInfo_t systemInfo{}; + modules_t systemInfo{}; std::vector layout{ config.args_layout.empty() ? config.layout : config.args_layout }; int image_width, image_height, channels; diff --git a/src/libs/toml++/Makefile b/src/libs/toml++/Makefile index f200e231..f39d1998 100644 --- a/src/libs/toml++/Makefile +++ b/src/libs/toml++/Makefile @@ -1,7 +1,7 @@ CXX ?= g++ SRC = toml.cpp TARGET = toml.o -CXXFLAGS = -I../../../include -std=c++20 +CXXFLAGS = -I../../../include -fPIE -std=c++20 all: $(TARGET) diff --git a/src/parse.cpp b/src/parse.cpp index 0ae8a785..ecbf064d 100644 --- a/src/parse.cpp +++ b/src/parse.cpp @@ -245,24 +245,25 @@ std::string get_and_color_percentage(const float n1, const float n2, parse_args_ return parse(fmt::format("{}{:.2f}%${{0}}", color, result), _, parse_args); } -std::string getInfoFromName(const systemInfo_t& systemInfo, const std::string_view moduleName, - const std::string_view moduleMemberName) +const std::string getInfoFromName(const moduleMap_t& systemInfo, const std::string_view moduleName) { - if (const auto& it1 = systemInfo.find(moduleName.data()); it1 != systemInfo.end()) + if (const auto& it = systemInfo.find(moduleName.data()); it != systemInfo.end()) { - if (const auto& it2 = it1->second.find(moduleMemberName.data()); it2 != it1->second.end()) - { - const variant& result = it2->second; + // if (const auto& it2 = it1->second.find(moduleMemberName.data()); it2 != it1->second.end()) + // { + // const variant& result = it2->second; - if (std::holds_alternative(result)) - return std::get(result); + // if (std::holds_alternative(result)) + // return std::get(result); - else if (std::holds_alternative(result)) - return fmt::format("{:.2f}", (std::get(result))); + // else if (std::holds_alternative(result)) + // return fmt::format("{:.2f}", (std::get(result))); - else - return fmt::to_string(std::get(result)); - } + // else + // return fmt::to_string(std::get(result)); + // } + + return it->second->handler(); } return "(unknown/invalid module)"; @@ -637,23 +638,23 @@ std::optional parse_info_tag(Parser& parser, parse_args_t& parse_ar if (!evaluate) return {}; - const size_t dot_pos = module.find('.'); - if (dot_pos == module.npos) - { - addValueFromModule(module, parse_args); - const std::string& info = getInfoFromName(parse_args.systemInfo, module, "module-" + module); + // const size_t dot_pos = module.find('.'); + // if (dot_pos == module.npos) + // { + // // addValueFromModule(module, parse_args); + // const std::string& info = getInfoFromName(parse_args.systemInfo, module, "module-" + module); - if (parser.dollar_pos != std::string::npos) - parse_args.pureOutput.replace(parser.dollar_pos, module.length() + "$<>"_len, info); + // if (parser.dollar_pos != std::string::npos) + // parse_args.pureOutput.replace(parser.dollar_pos, module.length() + "$<>"_len, info); - return info; - } + // return info; + // } - const std::string& moduleName = module.substr(0, dot_pos); - const std::string& moduleMemberName = module.substr(dot_pos + 1); - addValueFromModuleMember(moduleName, moduleMemberName, parse_args); + // const std::string& moduleName = module.substr(0, dot_pos); + // const std::string& moduleMemberName = module.substr(dot_pos + 1); + // addValueFromModuleMember(moduleName, moduleMemberName, parse_args); - const std::string& info = getInfoFromName(parse_args.systemInfo, moduleName, moduleMemberName); + const std::string& info = getInfoFromName(parse_args.systemInfo, module); if (parser.dollar_pos != std::string::npos) parse_args.pureOutput.replace(parser.dollar_pos, module.length() + "$<>"_len, info); @@ -738,7 +739,7 @@ std::string parse(Parser& parser, parse_args_t& parse_args, const bool evaluate, return result; } -std::string parse(std::string input, systemInfo_t& systemInfo, std::string& pureOutput, std::vector& layout, +std::string parse(std::string input, moduleMap_t& systemInfo, std::string& pureOutput, std::vector& layout, std::vector& tmp_layout, const Config& config, const colors_t& colors, const bool parsingLayout, bool& no_more_reset) { if (!config.sep_reset.empty() && parsingLayout && !no_more_reset) @@ -776,6 +777,9 @@ std::string parse(std::string input, systemInfo_t& systemInfo, std::string& pure return ret; } +// Re-enable them later +// trying some plugins stuff +#if 0 static std::string get_auto_uptime(const std::uint16_t days, const std::uint16_t hours, const std::uint16_t mins, const std::uint16_t secs, const Config& config) { @@ -878,10 +882,10 @@ static std::string prettify_de_name(const std::string_view de_name) return de_name.data(); } -systemInfo_t queried_gpus; -systemInfo_t queried_disks; -systemInfo_t queried_themes_names; -systemInfo_t queried_themes; +moduleMap_t queried_gpus; +moduleMap_t queried_disks; +moduleMap_t queried_themes_names; +moduleMap_t queried_themes; // clang-format on void addValueFromModuleMember(const std::string& moduleName, const std::string& moduleMemberName, @@ -1097,7 +1101,7 @@ void addValueFromModuleMember(const std::string& moduleName, const std::string& Query::Theme gtk2(2, queried_themes, "gtk2", config); Query::Theme gtk3(3, queried_themes, "gtk3", config); Query::Theme gtk4(4, queried_themes, "gtk4", config); - + if (sysInfo.find(moduleName) == sysInfo.end()) sysInfo.insert({ moduleName, {} }); @@ -1227,7 +1231,7 @@ void addValueFromModuleMember(const std::string& moduleName, const std::string& str += "Hidden, "; if (query_disk.types_disk() & Query::DISK_VOLUME_TYPE_READ_ONLY) str += "Read-only, "; - + if (!str.empty()) str.erase(str.length() - 2); SYSINFO_INSERT(str); @@ -1551,7 +1555,7 @@ void addValueFromModule(const std::string& moduleName, parse_args_t& parse_args) // clang-format on if (query_disk.typefs() != MAGIC_LINE) result += " - " + query_disk.typefs(); - + std::string types_disk {"["}; if (query_disk.types_disk() & Query::DISK_VOLUME_TYPE_EXTERNAL) types_disk += "External, "; @@ -1628,7 +1632,7 @@ void addValueFromModule(const std::string& moduleName, parse_args_t& parse_args) { const std::string& perc = get_and_color_percentage(query_ram.swap_used_amount(), query_ram.swap_total_amount(), parse_args); - + SYSINFO_INSERT(fmt::format("{:.2f} {} / {:.2f} {} {}", byte_units.at(USED).num_bytes, byte_units.at(USED).unit, byte_units.at(TOTAL).num_bytes,byte_units.at(TOTAL).unit, @@ -1672,7 +1676,7 @@ void addValueFromModule(const std::string& moduleName, parse_args_t& parse_args) SYSINFO_INSERT(parse("${\033[100m} ${\033[101m} ${\033[102m} ${\033[103m} ${\033[104m} ${\033[105m} ${\033[106m} ${\033[107m} ${0}", _, parse_args)); } } - + // clang-format off // I really dislike how repetitive this code is else if (hasStart(moduleName, "colors_symbol")) @@ -1726,3 +1730,4 @@ void addValueFromModule(const std::string& moduleName, parse_args_t& parse_args) else die(_("Invalid module name: {}"), moduleName); } +#endif diff --git a/src/query/android/gpu.cpp b/src/query/android/gpu.cpp index 5c4fd7a8..7368bf09 100644 --- a/src/query/android/gpu.cpp +++ b/src/query/android/gpu.cpp @@ -195,7 +195,7 @@ static std::string detect_adreno(const std::string& cpu_model_name) return MAGIC_LINE; } -GPU::GPU(const std::string& id, systemInfo_t& queried_gpus) +GPU::GPU(const std::string& id/*, moduleMap_t& queried_gpus*/) { CPU query_cpu; if (query_cpu.vendor() == "QUALCOMM" || query_cpu.vendor() == "QTI") diff --git a/src/query/android/theme.cpp b/src/query/android/theme.cpp index 5422c4ea..bd874d91 100644 --- a/src/query/android/theme.cpp +++ b/src/query/android/theme.cpp @@ -31,7 +31,7 @@ using namespace Query; -Theme::Theme(const std::uint8_t ver, systemInfo_t& queried_themes, const std::string& theme_name_version, +Theme::Theme(const std::uint8_t ver, moduleMap_t& queried_themes, const std::string& theme_name_version, const Config& config, const bool gsettings_only) : m_queried_themes(queried_themes) { @@ -39,7 +39,7 @@ Theme::Theme(const std::uint8_t ver, systemInfo_t& queried_themes, const std::st = MAGIC_LINE; } -Theme::Theme(systemInfo_t& queried_themes, const Config& config, const bool gsettings_only) : m_queried_themes(queried_themes) +Theme::Theme(moduleMap_t& queried_themes, const Config& config, const bool gsettings_only) : m_queried_themes(queried_themes) { m_theme_infos.cursor = m_theme_infos.gtk_font = m_theme_infos.cursor_size = m_theme_infos.gtk_theme_name = m_theme_infos.gtk_icon_theme = MAGIC_LINE; diff --git a/src/query/linux/disk.cpp b/src/query/linux/disk.cpp index db51cfce..3a3d0217 100644 --- a/src/query/linux/disk.cpp +++ b/src/query/linux/disk.cpp @@ -179,18 +179,8 @@ static std::string format_auto_query_string(std::string str, const struct mntent return str; } -Disk::Disk(const std::string& path, systemInfo_t& queried_paths, parse_args_t& parse_args, const bool auto_module) +Disk::Disk(const std::string& path, parse_args_t& parse_args, const bool auto_module) { - if (queried_paths.find(path) != queried_paths.end() && !is_live_mode) - { - m_disk_infos.device = getInfoFromName(queried_paths, path, "device"); - m_disk_infos.mountdir = getInfoFromName(queried_paths, path, "mountdir"); - m_disk_infos.typefs = getInfoFromName(queried_paths, path, "typefs"); - m_disk_infos.total_amount = std::stod(getInfoFromName(queried_paths, path, "total_amount")); - m_disk_infos.used_amount = std::stod(getInfoFromName(queried_paths, path, "used_amount")); - m_disk_infos.free_amount = std::stod(getInfoFromName(queried_paths, path, "free_amount")); - return; - } if (access(path.data(), F_OK) != 0 && !auto_module) { @@ -222,14 +212,14 @@ Disk::Disk(const std::string& path, systemInfo_t& queried_paths, parse_args_t& p if (!(parse_args.config.auto_disks_types & m_disk_infos.types_disk)) continue; - if (!parse_args.config.auto_disks_show_dupl) - { - const auto& it = std::find(m_queried_devices.begin(), m_queried_devices.end(), pDevice->mnt_fsname); - if (it != m_queried_devices.end()) - continue; + // if (!parse_args.config.auto_disks_show_dupl) + // { + // const auto& it = std::find(m_queried_devices.begin(), m_queried_devices.end(), pDevice->mnt_fsname); + // if (it != m_queried_devices.end()) + // continue; - m_queried_devices.push_back(pDevice->mnt_fsname); - } + // m_queried_devices.push_back(pDevice->mnt_fsname); + // } parse_args.no_more_reset = false; debug("AUTO: pDevice->mnt_dir = {} && pDevice->mnt_fsname = {}", pDevice->mnt_dir, pDevice->mnt_fsname); @@ -274,16 +264,6 @@ Disk::Disk(const std::string& path, systemInfo_t& queried_paths, parse_args_t& p m_disk_infos.used_amount = m_disk_infos.total_amount - m_disk_infos.free_amount; endmntent(mountsFile); - queried_paths.insert( - {path, { - {"total_amount", variant(m_disk_infos.total_amount)}, - {"used_amount", variant(m_disk_infos.used_amount)}, - {"free_amount", variant(m_disk_infos.free_amount)}, - {"typefs", variant(m_disk_infos.typefs)}, - {"mountdir", variant(m_disk_infos.mountdir)}, - {"device", variant(m_disk_infos.device)} - }} - ); } // clang-format off diff --git a/src/query/linux/gpu.cpp b/src/query/linux/gpu.cpp index fce01acf..093c7138 100644 --- a/src/query/linux/gpu.cpp +++ b/src/query/linux/gpu.cpp @@ -76,14 +76,14 @@ static GPU::GPU_t get_gpu_infos(const std::string_view m_vendor_id_s, const std: return ret; } -GPU::GPU(const std::string& id, systemInfo_t& queried_gpus) +GPU::GPU(const std::string& id/*, systemInfo_t& queried_gpus*/) { - if (queried_gpus.find(id) != queried_gpus.end()) - { - m_gpu_infos.name = getInfoFromName(queried_gpus, id, "name"); - m_gpu_infos.vendor = getInfoFromName(queried_gpus, id, "vendor"); - return; - } + // if (queried_gpus.find(id) != queried_gpus.end()) + // { + // m_gpu_infos.name = getInfoFromName(queried_gpus, id, "name"); + // m_gpu_infos.vendor = getInfoFromName(queried_gpus, id, "vendor"); + // return; + // } const std::uint16_t max_iter = 10; std::uint16_t id_iter = std::stoi(id); @@ -109,12 +109,6 @@ GPU::GPU(const std::string& id, systemInfo_t& queried_gpus) m_device_id_s = read_by_syspath(sys_path + "/device/device"); m_gpu_infos = get_gpu_infos(m_vendor_id_s, m_device_id_s); - queried_gpus.insert( - {id, { - {"name", variant(m_gpu_infos.name)}, - {"vendor", variant(m_gpu_infos.vendor)}, - }} - ); } // clang-format off diff --git a/src/query/linux/theme.cpp b/src/query/linux/theme.cpp index 5d2f06ab..a5cb70e8 100644 --- a/src/query/linux/theme.cpp +++ b/src/query/linux/theme.cpp @@ -477,13 +477,13 @@ static void get_gtk_theme(const bool dont_query_dewm, const std::uint8_t ver, co } // clang-format off -Theme::Theme(const std::uint8_t ver, systemInfo_t& queried_themes, +Theme::Theme(const std::uint8_t ver/*, systemInfo_t& queried_themes*/, const std::string& theme_name_version, const Config& config, const bool gsettings_only) - : m_theme_name(theme_name_version), - m_queried_themes(queried_themes) + : m_theme_name(theme_name_version)/*, + m_queried_themes(queried_themes)*/ { - if (queried_themes.find(theme_name_version) != queried_themes.end()) - return; + // if (queried_themes.find(theme_name_version) != queried_themes.end()) + // return; const std::string& wm_name = query_user.wm_name(query_user.m_bDont_query_dewm, query_user.term_name()); const std::string& de_name = query_user.de_name(query_user.m_bDont_query_dewm, query_user.term_name(), wm_name); @@ -505,17 +505,17 @@ Theme::Theme(const std::uint8_t ver, systemInfo_t& queried_themes, if (m_theme_infos.gtk_icon_theme.empty()) m_theme_infos.gtk_icon_theme = MAGIC_LINE; - m_queried_themes.insert( - {m_theme_name, { - {"theme-name", variant(m_theme_infos.gtk_theme_name)}, - {"icon-theme-name", variant(m_theme_infos.gtk_icon_theme)}, - {"font-name", variant(m_theme_infos.gtk_font)}, - }} - ); + // m_queried_themes.insert( + // {m_theme_name, { + // {"theme-name", variant(m_theme_infos.gtk_theme_name)}, + // {"icon-theme-name", variant(m_theme_infos.gtk_icon_theme)}, + // {"font-name", variant(m_theme_infos.gtk_font)}, + // }} + // ); } // only use it for cursor -Theme::Theme(systemInfo_t& queried_themes, const Config& config, const bool gsettings_only) : m_queried_themes(queried_themes) +Theme::Theme(/*systemInfo_t& queried_themes, */const Config& config, const bool gsettings_only)/* : m_queried_themes(queried_themes)*/ { const std::string& wm_name = query_user.wm_name(query_user.m_bDont_query_dewm, query_user.term_name()); const std::string& de_name = query_user.de_name(query_user.m_bDont_query_dewm, query_user.term_name(), wm_name); @@ -550,13 +550,13 @@ Theme::Theme(systemInfo_t& queried_themes, const Config& config, const bool gset } std::string Theme::gtk_theme() noexcept -{ return getInfoFromName(m_queried_themes, m_theme_name, "theme-name"); } +{ return m_theme_infos.gtk_theme_name; } std::string Theme::gtk_icon_theme() noexcept -{ return getInfoFromName(m_queried_themes, m_theme_name, "icon-theme-name"); } +{ return m_theme_infos.gtk_icon_theme; } std::string Theme::gtk_font() noexcept -{ return getInfoFromName(m_queried_themes, m_theme_name, "font-name"); } +{ return m_theme_infos.gtk_font; } std::string& Theme::cursor() noexcept { return m_theme_infos.cursor; } From 09a13b170e515c21728f75e4618c9f2fb44da390 Mon Sep 17 00:00:00 2001 From: BurntRanch <69512353+BurntRanch@users.noreply.github.com> Date: Fri, 20 Jun 2025 01:10:33 +0300 Subject: [PATCH 002/143] plugins: working API example --- .gitignore | 1 - Makefile | 10 ++++++-- include/config.hpp | 7 +++--- include/display.hpp | 3 ++- include/gui.hpp | 6 +++-- include/query.hpp | 6 ++--- include/util.hpp | 5 ++-- src/config.cpp | 18 +++++++------- src/display.cpp | 30 +++++++++-------------- src/gui.cpp | 13 +++++----- src/libs/cufetch/Makefile | 14 +++++++++++ src/libs/cufetch/cufetch.cc | 26 ++++++++++++++++++++ src/main.cpp | 49 +++++++++++++++++++++++++++++++------ src/parse.cpp | 2 +- src/util.cpp | 8 +++--- 15 files changed, 138 insertions(+), 60 deletions(-) create mode 100644 src/libs/cufetch/Makefile create mode 100644 src/libs/cufetch/cufetch.cc diff --git a/.gitignore b/.gitignore index 914ced4e..cc1b2d8d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ build*/ assets/distro_ascii* -cufetch /*.txt pci.ids output/ diff --git a/Makefile b/Makefile index 5c93acc4..d779b3a0 100644 --- a/Makefile +++ b/Makefile @@ -62,7 +62,13 @@ LDFLAGS += -L./$(BUILDDIR)/fmt -lfmt -ldl CXXFLAGS ?= -mtune=generic -march=native CXXFLAGS += -fvisibility=hidden -Iinclude -std=c++20 $(VARS) -DVERSION=\"$(VERSION)\" -DLOCALEDIR=\"$(LOCALEDIR)\" -DICONPREFIX=\"$(ICONPREFIX)\" -all: genver fmt toml json $(TARGET) +all: genver libcufetch fmt toml json $(TARGET) + +libcufetch: +ifeq ($(wildcard $(BUILDDIR)/libcufetch/libcufetch.so),) + mkdir -p $(BUILDDIR)/libcufetch + make -C src/libs/cufetch BUILDDIR=$(BUILDDIR)/libcufetch +endif fmt: ifeq ($(wildcard $(BUILDDIR)/fmt/libfmt.a),) @@ -87,7 +93,7 @@ ifeq ($(wildcard include/version.h),) ./scripts/generateVersion.sh endif -$(TARGET): genver fmt toml json $(OBJ) +$(TARGET): genver fmt toml libcufetch json $(OBJ) mkdir -p $(BUILDDIR) sh ./scripts/generateVersion.sh $(CXX) $(OBJ) $(BUILDDIR)/toml++/toml.o $(BUILDDIR)/json/json.o -o $(BUILDDIR)/$(TARGET) $(LDFLAGS) diff --git a/include/config.hpp b/include/config.hpp index eb80674b..5b8d187d 100644 --- a/include/config.hpp +++ b/include/config.hpp @@ -26,6 +26,7 @@ #ifndef _CONFIG_HPP #define _CONFIG_HPP +#include #define TOML_HEADER_ONLY 0 #include @@ -77,7 +78,7 @@ class Config { public: // Create .config directories and files and load the config file (args or default) - Config(const std::string_view configFile, const std::string_view configDir); + Config(const std::filesystem::path &configFile, const std::filesystem::path &configDir); // Variables of config file in [config] table std::vector layout; @@ -140,13 +141,13 @@ class Config * @param colors The colors struct where we'll put the default config colors. * It doesn't include the colors in config.alias-colors */ - void loadConfigFile(const std::string_view filename, colors_t& colors); + void loadConfigFile(const std::filesystem::path &filename, colors_t& colors); /** * Generate the default config file at path * @param filename The config file path */ - void generateConfig(const std::string_view filename); + void generateConfig(const std::filesystem::path &filename); /** * Add alias values to colors_name and colors_value. diff --git a/include/display.hpp b/include/display.hpp index a3b9efd3..0dcb30ea 100644 --- a/include/display.hpp +++ b/include/display.hpp @@ -31,6 +31,7 @@ #include "config.hpp" #include "platform.hpp" +#include "query.hpp" #if CF_MACOS constexpr std::string_view ascii_logo = @@ -89,7 +90,7 @@ namespace Display * @param path Path to source file */ std::vector render(const Config& config, const colors_t& colors, const bool already_analyzed_path, - const std::string_view path); + const std::filesystem::path &path, moduleMap_t &moduleMap); /* * Display the rendered result (or just display a normal vector of string diff --git a/include/gui.hpp b/include/gui.hpp index 1e5209da..da622d00 100644 --- a/include/gui.hpp +++ b/include/gui.hpp @@ -26,6 +26,7 @@ #ifndef _GUI_HPP #define _GUI_HPP +#include "query.hpp" #if GUI_APP #include "config.hpp" @@ -51,14 +52,15 @@ class Window : public Gtk::Window * @param colors The non-alias colors struct * @param path The logo source path */ - Window(const Config& config, const colors_t& colors, const std::string_view path); + Window(const Config& config, const colors_t& colors, const std::filesystem::path &path, moduleMap_t &moduleMap); // Destroy the window, handled by GTK virtual ~Window(); private: const Config& m_config; const colors_t& m_colors; - const std::string_view m_path; + const std::filesystem::path &m_path; + moduleMap_t &m_moduleMap; bool isImage; Gtk::Overlay m_overlay; diff --git a/include/query.hpp b/include/query.hpp index 37a77f47..0d156954 100644 --- a/include/query.hpp +++ b/include/query.hpp @@ -55,10 +55,10 @@ extern "C" { struct module_t { std::string name; - std::vector> submodules; + std::vector submodules; /* For best performance, use std::move() when adding modules in here. */ std::function handler; - module_t(const std::string &name, const std::vector> &submodules, const std::function handler) : name(name), submodules(submodules), handler(handler) { + module_t(const std::string &name, const std::vector &submodules, const std::function handler) : name(name), submodules(submodules), handler(handler) { } }; @@ -67,7 +67,7 @@ struct parse_args_t; // Map from a modules name to its pointer. using moduleMap_t = - std::unordered_map>; + std::unordered_map; // used in systemInfo_t most of the time using variant = std::variant; diff --git a/include/util.hpp b/include/util.hpp index c8d6cee5..7b5bd026 100644 --- a/include/util.hpp +++ b/include/util.hpp @@ -31,6 +31,7 @@ #include #include +#include #include #include #include @@ -286,7 +287,7 @@ std::string shorten_vendor_name(std::string vendor); * either from $XDG_CONFIG_HOME or from $HOME/.config/ * @return user's config directory */ -std::string getHomeConfigDir(); +std::filesystem::path getHomeConfigDir(); /* * Get the customfetch config directory @@ -294,7 +295,7 @@ std::string getHomeConfigDir(); * from getHomeConfigDir() * @return customfetch's config directory */ -std::string getConfigDir(); +std::filesystem::path getConfigDir(); #if CF_ANDROID /* Get android property name such as "ro.product.marketname" diff --git a/src/config.cpp b/src/config.cpp index 1793dc63..6242cc8c 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -34,33 +34,33 @@ #include "switch_fnv1a.hpp" #include "util.hpp" -Config::Config(const std::string_view configFile, const std::string_view configDir) +Config::Config(const std::filesystem::path &configFile, const std::filesystem::path &configDir) { if (!std::filesystem::exists(configDir)) { - warn(_("customfetch config folder was not found, Creating folders at {}!"), configDir); + warn(_("customfetch config folder was not found, Creating folders at {}!"), configDir.string()); std::filesystem::create_directories(configDir); } if (!std::filesystem::exists(configFile)) { - warn(_("config file {} not found, generating new one"), configFile); + warn(_("config file {} not found, generating new one"), configFile.string()); this->generateConfig(configFile); } } -void Config::loadConfigFile(const std::string_view filename, colors_t& colors) +void Config::loadConfigFile(const std::filesystem::path &filename, colors_t& colors) { try { - this->tbl = toml::parse_file(filename); + this->tbl = toml::parse_file(filename.string()); } catch (const toml::parse_error& err) { die(_("Parsing config file '{}' failed:\n" "{}\n" "\t(error occurred at line {} column {})"), - filename, err.description(), + filename.string(), err.description(), err.source().begin.line, err.source().begin.column); } @@ -230,14 +230,14 @@ void Config::overrideOption(const std::string& opt) value, name); } -void Config::generateConfig(const std::string_view filename) +void Config::generateConfig(const std::filesystem::path &filename) { if (std::filesystem::exists(filename)) { - if (!askUserYorN(false, "WARNING: config file '{}' already exists. Do you want to overwrite it?", filename)) + if (!askUserYorN(false, "WARNING: config file '{}' already exists. Do you want to overwrite it?", filename.string())) std::exit(1); } - auto f = fmt::output_file(filename.data()); + auto f = fmt::output_file(filename.c_str()); f.print("{}", AUTOCONFIG); } diff --git a/src/display.cpp b/src/display.cpp index 4de42ca7..256ed32a 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -97,21 +97,21 @@ std::string Display::detect_distro(const Config& config) static std::vector render_with_image(moduleMap_t& systemInfo, std::vector& layout, const Config& config, const colors_t& colors, - const std::string_view path, const std::uint16_t font_width, + const std::filesystem::path &path, const std::uint16_t font_width, const std::uint16_t font_height) { int image_width, image_height, channels; // load the image and get its width and height - unsigned char* img = stbi_load(path.data(), &image_width, &image_height, &channels, 0); + unsigned char* img = stbi_load(path.c_str(), &image_width, &image_height, &channels, 0); if (!img) - die(_("Unable to load image '{}'"), path); + die(_("Unable to load image '{}'"), path.string()); stbi_image_free(img); if (Display::ascii_logo_fd != -1) { - remove(path.data()); + remove(path.c_str()); close(Display::ascii_logo_fd); } @@ -147,9 +147,9 @@ static std::vector render_with_image(moduleMap_t& systemInfo, std:: if (config.args_image_backend == "kitty") taur_exec({ "kitty", "+kitten", "icat", "--align", (config.logo_position == "top" ? "center" : config.logo_position), - "--place", fmt::format("{}x{}@0x0", width, height), path }); + "--place", fmt::format("{}x{}@0x0", width, height), path.string() }); else if (config.args_image_backend == "viu") - taur_exec({ "viu", "-t", "-w", fmt::to_string(width), "-h", fmt::to_string(height), path }); + taur_exec({ "viu", "-t", "-w", fmt::to_string(width), "-h", fmt::to_string(height), path.string() }); else die(_("The image backend '{}' isn't supported, only 'kitty' and 'viu'.\n" "Please currently use the GUI mode for rendering the image/gif (use -h for more details)"), @@ -225,27 +225,21 @@ const std::string test() { } std::vector Display::render(const Config& config, const colors_t& colors, const bool already_analyzed_file, - const std::string_view path) + const std::filesystem::path &path, moduleMap_t &moduleMap) { - moduleMap_t moduleMap{}; std::vector asciiArt{}, layout{ config.args_layout.empty() ? config.layout : config.args_layout }; - std::shared_ptr module = std::make_shared("test!", std::vector>(), test); - - /* TODO(burntranch): remove test */ - moduleMap.emplace("test.module.123", std::move(module)); - - debug("Display::render path = {}", path); + debug("Display::render path = {}", path.string()); bool isImage = false; std::ifstream file; std::ifstream fileToAnalyze; // both have same path if (!config.args_disable_source) { - file.open(path.data(), std::ios::binary); - fileToAnalyze.open(path.data(), std::ios::binary); + file.open(path.c_str(), std::ios::binary); + fileToAnalyze.open(path.c_str(), std::ios::binary); if (!file.is_open() || !fileToAnalyze.is_open()) - die(_("Could not open logo file '{}'"), path); + die(_("Could not open logo file '{}'"), path.string()); // first check if the file is an image // without even using the same library that "file" uses @@ -311,7 +305,7 @@ std::vector Display::render(const Config& config, const colors_t& c if (Display::ascii_logo_fd != -1) { - remove(path.data()); + remove(path.c_str()); close(Display::ascii_logo_fd); } diff --git a/src/gui.cpp b/src/gui.cpp index 7225a8d7..f5992e15 100644 --- a/src/gui.cpp +++ b/src/gui.cpp @@ -63,7 +63,7 @@ using namespace GUI; static std::vector render_with_image(const Config& config, const colors_t& colors) { std::string path{ Display::detect_distro(config) }; - modules_t systemInfo{}; + moduleMap_t systemInfo{}; std::vector layout{ config.args_layout.empty() ? config.layout : config.args_layout }; int image_width, image_height, channels; @@ -135,15 +135,16 @@ bool Window::set_layout_markup() } else { - m_label.set_markup(fmt::format("{}", fmt::join(Display::render(m_config, m_colors, true, m_path), "\n"))); + m_label.set_markup(fmt::format("{}", fmt::join(Display::render(m_config, m_colors, true, m_path, m_moduleMap), "\n"))); } return true; } -Window::Window(const Config& config, const colors_t& colors, const std::string_view path) : +Window::Window(const Config& config, const colors_t& colors, const std::filesystem::path &path, moduleMap_t &moduleMap) : m_config(config), m_colors(colors), m_path(path), + m_moduleMap(moduleMap), isImage(false) { set_title("customfetch - Higly customizable and fast neofetch like program"); @@ -152,7 +153,7 @@ Window::Window(const Config& config, const colors_t& colors, const std::string_v set_icon_from_file(ICONPREFIX "/customfetch/Thumbnail.png"); debug("Window::Window analyzing file"); - std::ifstream f(path.data()); + std::ifstream f(path.c_str()); std::array buffer; f.read(reinterpret_cast(&buffer.at(0)), buffer.size()); if (is_file_image(buffer.data())) @@ -161,7 +162,7 @@ Window::Window(const Config& config, const colors_t& colors, const std::string_v // useImage can be either a gif or an image if (isImage && !config.args_disable_source) { - const auto& img = Gdk::PixbufAnimation::create_from_file(path.data()); + const auto& img = Gdk::PixbufAnimation::create_from_file(path.c_str()); m_img = Gtk::manage(new Gtk::Image(img)); m_img->set(img); m_img->set_alignment(Gtk::ALIGN_CENTER); @@ -211,7 +212,7 @@ Window::Window(const Config& config, const colors_t& colors, const std::string_v if (Display::ascii_logo_fd != -1) { - ::remove(path.data()); + ::remove(path.c_str()); ::close(Display::ascii_logo_fd); } diff --git a/src/libs/cufetch/Makefile b/src/libs/cufetch/Makefile new file mode 100644 index 00000000..b6e44cec --- /dev/null +++ b/src/libs/cufetch/Makefile @@ -0,0 +1,14 @@ +CXX ?= g++ +CXX_INCLUDES = -I../../../include +CXX_FLAGS = -shared -fPIC + +all: cufetch + +cufetch: cufetch.cc + $(CXX) $(CXX_INCLUDES) $(CXX_FLAGS) cufetch.cc -o libcufetch.so + mv -f libcufetch.so ../../../$(BUILDDIR)/libcufetch.so + +clean: + rm -f *.o *.so *.a ../../../$(BUILDDIR)/cufetch/.*a + +.PHONY: clean all cufetch diff --git a/src/libs/cufetch/cufetch.cc b/src/libs/cufetch/cufetch.cc new file mode 100644 index 00000000..b7af0275 --- /dev/null +++ b/src/libs/cufetch/cufetch.cc @@ -0,0 +1,26 @@ +#include +#include +#include "query.hpp" + +static std::vector modules; + +/* TODO: can we customize the separator perhaps? */ +static char separator = '.'; + +extern "C" { + static void addModule(const module_t &module, const std::string &prefix = "") { + modules.emplace_back(module).name = prefix + module.name; + + for (const module_t &submodule : module.submodules) { + addModule(submodule, module.name + separator); + } + } + + [[gnu::unused]] void cfRegisterModule(const module_t &module) { + addModule(module); + } + + [[gnu::unused]] const std::vector &cfGetModules() { + return modules; + } +} diff --git a/src/main.cpp b/src/main.cpp index a7aa60de..af04664b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include "config.hpp" #include "display.hpp" @@ -540,7 +541,7 @@ static bool str_to_bool(const std::string_view str) // clang-format off // parseargs() but only for parsing the user config path trough args // and so we can directly construct Config -static std::string parse_config_path(int argc, char* argv[], const std::string& configDir) +static std::filesystem::path parse_config_path(int argc, char* argv[], const std::filesystem::path &configDir) { int opt = 0; int option_index = 0; @@ -567,10 +568,10 @@ static std::string parse_config_path(int argc, char* argv[], const std::string& } } - return configDir + "/config.toml"; + return configDir / "config.toml"; } -static bool parseargs(int argc, char* argv[], Config& config, const std::string_view configFile) +static bool parseargs(int argc, char* argv[], Config& config, const std::filesystem::path &configFile) { int opt = 0; int option_index = 0; @@ -775,8 +776,8 @@ int main(int argc, char *argv[]) // clang-format on colors_t colors; - const std::string& configDir = getConfigDir(); - const std::string& configFile = parse_config_path(argc, argv, configDir); + const std::filesystem::path configDir = getConfigDir(); + const std::filesystem::path configFile = parse_config_path(argc, argv, configDir); localize(); @@ -785,6 +786,38 @@ int main(int argc, char *argv[]) return 1; config.loadConfigFile(configFile, colors); + LOAD_LIBRARY("libcufetch.so", die("Failed to load libcufetch!")); + void *cufetch_handle = handle; + + /* TODO(burntranch): track each library and unload them. */ + const std::filesystem::path modDir = configDir / "mods"; + for (const auto &entry : std::filesystem::directory_iterator(modDir)) { + fmt::println("loading mod at {}!", entry.path().string()); + + LOAD_LIBRARY(std::filesystem::absolute(entry.path()).c_str(), warn("Failed to load mod {}!", entry.path().string())) + if (!handle) + continue; + + LOAD_LIB_SYMBOL(void, start, void *) + + start(cufetch_handle); + } + + handle = cufetch_handle; + + LOAD_LIB_SYMBOL(const std::vector &, cfGetModules) + + const std::vector &modules = cfGetModules(); + moduleMap_t moduleMap; + + fmt::println("modules count: {}", modules.size()); + for (const module_t &module : modules) { + if (!module.handler) + continue; + + moduleMap.emplace(module.name, module); + } + is_live_mode = (config.loop_ms > 50); if (config.source_path.empty() || config.source_path == "off") @@ -821,7 +854,7 @@ int main(int argc, char *argv[]) #if GUI_APP const auto& app = Gtk::Application::create("org.toni.customfetch"); - GUI::Window window(config, colors, path); + GUI::Window window(config, colors, path, moduleMap); return app->run(window); #endif // GUI_APP @@ -845,13 +878,13 @@ int main(int argc, char *argv[]) write(STDOUT_FILENO, "\33[H\33[2J", 7); fmt::print("\033[0;0H"); - Display::display(Display::render(config, colors, false, path)); + Display::display(Display::render(config, colors, false, path, moduleMap)); std::this_thread::sleep_for(sleep_ms); } } else { - Display::display(Display::render(config, colors, false, path)); + Display::display(Display::render(config, colors, false, path, moduleMap)); } // enable both of them again diff --git a/src/parse.cpp b/src/parse.cpp index ecbf064d..f62181b7 100644 --- a/src/parse.cpp +++ b/src/parse.cpp @@ -263,7 +263,7 @@ const std::string getInfoFromName(const moduleMap_t& systemInfo, const std::stri // return fmt::to_string(std::get(result)); // } - return it->second->handler(); + return it->second.handler(); } return "(unknown/invalid module)"; diff --git a/src/util.cpp b/src/util.cpp index 24b3746c..241e14a7 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -606,7 +606,7 @@ std::string vendor_from_entry(const size_t vendor_entry_pos, const std::string_v } // clang-format off -std::string getHomeConfigDir() +std::filesystem::path getHomeConfigDir() { const char* dir = std::getenv("XDG_CONFIG_HOME"); if (dir != NULL && dir[0] != '\0' && std::filesystem::exists(dir)) @@ -622,9 +622,9 @@ std::string getHomeConfigDir() if (home == nullptr) die(_("Failed to find $HOME, set it to your home directory!")); - return std::string(home) + "/.config"; + return std::filesystem::path(home) / ".config"; } } -std::string getConfigDir() -{ return getHomeConfigDir() + "/customfetch"; } +std::filesystem::path getConfigDir() +{ return getHomeConfigDir() / "customfetch"; } From a362485f01772c2906a7d0f95c669a3c3c9c1dc7 Mon Sep 17 00:00:00 2001 From: Toni500git Date: Fri, 20 Jun 2025 00:14:28 +0200 Subject: [PATCH 003/143] misc: fix .gitignore --- .gitignore | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index cc1b2d8d..42a5f20c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,17 +1,18 @@ build*/ assets/distro_ascii* +/cufetch /*.txt pci.ids output/ useless_stuff/ -customfetch -customfetch_r -cufetch_r +/customfetch +/customfetch_r +/cufetch_r locale/ usr/ -scripts/ascii_parser.py -scripts/dict_to_files.py -scripts/test* +/scripts/ascii_parser.py +/scripts/dict_to_files.py +/scripts/test* tests/test* !tests/*.cpp From cde69983e1443635768ba306e98b248caf7c08fe Mon Sep 17 00:00:00 2001 From: Toni500git Date: Fri, 20 Jun 2025 00:26:40 +0200 Subject: [PATCH 004/143] clang-format --- include/config.hpp | 54 +++++----- include/display.hpp | 24 ++--- include/gui.hpp | 34 +++--- include/parse.hpp | 35 ++++--- include/platform.hpp | 11 +- include/query.hpp | 93 +++++++++-------- include/util.hpp | 22 ++-- src/config.cpp | 26 ++--- src/display.cpp | 112 ++++++++++---------- src/gui.cpp | 48 ++++----- src/main.cpp | 62 +++++------ src/parse.cpp | 68 ++++++------ src/query/android/battery.cpp | 28 ++--- src/query/android/gpu.cpp | 2 +- src/query/android/system.cpp | 4 +- src/query/android/theme.cpp | 13 +-- src/query/linux/battery.cpp | 30 +++--- src/query/linux/disk.cpp | 87 ++++++++-------- src/query/linux/gpu.cpp | 32 +++--- src/query/linux/ram.cpp | 22 ++-- src/query/linux/system.cpp | 49 ++++----- src/query/linux/theme.cpp | 160 ++++++++++++++--------------- src/query/linux/user.cpp | 28 +++-- src/query/linux/utils/dewm.cpp | 25 +++-- src/query/linux/utils/packages.cpp | 22 ++-- src/query/macos/battery.cpp | 22 ++-- src/query/macos/cpu.cpp | 13 +-- src/query/macos/disk.cpp | 66 ++++++------ src/query/macos/gpu.cpp | 4 +- src/query/macos/ram.cpp | 45 ++++---- src/query/macos/system.cpp | 72 ++++++------- src/query/macos/theme.cpp | 13 +-- src/util.cpp | 42 ++++---- 33 files changed, 689 insertions(+), 679 deletions(-) diff --git a/include/config.hpp b/include/config.hpp index 5b8d187d..5760e080 100644 --- a/include/config.hpp +++ b/include/config.hpp @@ -1,25 +1,25 @@ /* * Copyright 2025 Toni500git - * + * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ @@ -45,10 +45,10 @@ enum types struct override_configs_types { - types value_type; + types value_type; std::string string_value = ""; - bool bool_value = false; - int int_value = 0; + bool bool_value = false; + int int_value = 0; }; // config colors @@ -78,7 +78,7 @@ class Config { public: // Create .config directories and files and load the config file (args or default) - Config(const std::filesystem::path &configFile, const std::filesystem::path &configDir); + Config(const std::filesystem::path& configFile, const std::filesystem::path& configDir); // Variables of config file in [config] table std::vector layout; @@ -106,7 +106,7 @@ class Config // modules specific configs // [auto.disk] std::string auto_disks_fmt; - int auto_disks_types = 0; + int auto_disks_types = 0; bool auto_disks_show_dupl = false; // [os.uptime] @@ -126,12 +126,12 @@ class Config std::vector args_layout; std::string args_custom_distro; std::string args_image_backend; - std::uint16_t m_offset_calc = 0; - bool m_display_distro = true; - bool args_disable_source = false; - bool args_disable_colors = false; - bool args_disallow_commands = false; - bool args_print_logo_only = false; + std::uint16_t m_offset_calc = 0; + bool m_display_distro = true; + bool args_disable_source = false; + bool args_disable_colors = false; + bool args_disallow_commands = false; + bool args_print_logo_only = false; std::unordered_map overrides; @@ -141,13 +141,13 @@ class Config * @param colors The colors struct where we'll put the default config colors. * It doesn't include the colors in config.alias-colors */ - void loadConfigFile(const std::filesystem::path &filename, colors_t& colors); + void loadConfigFile(const std::filesystem::path& filename, colors_t& colors); /** * Generate the default config file at path * @param filename The config file path */ - void generateConfig(const std::filesystem::path &filename); + void generateConfig(const std::filesystem::path& filename); /** * Add alias values to colors_name and colors_value. @@ -162,7 +162,7 @@ class Config * @param str The value to override. * Must have a '=' for separating the name and value to override. * NO spaces between - */ + */ void overrideOption(const std::string& opt); private: @@ -232,7 +232,7 @@ layout = [ "${auto}Kernel: $", "${auto}Uptime: $",)#" #if !CF_ANDROID - R"#( + R"#( "${auto}Theme: $", "${auto}Icons: $", "${auto}Font: $", @@ -240,7 +240,7 @@ layout = [ "${auto}WM: $", "${auto}DE: $",)#" #endif - R"#( + R"#( "$", "${auto}Swap: $", "${auto}CPU: $", diff --git a/include/display.hpp b/include/display.hpp index 0dcb30ea..03009b74 100644 --- a/include/display.hpp +++ b/include/display.hpp @@ -1,25 +1,25 @@ /* * Copyright 2025 Toni500git - * + * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ @@ -90,7 +90,7 @@ namespace Display * @param path Path to source file */ std::vector render(const Config& config, const colors_t& colors, const bool already_analyzed_path, - const std::filesystem::path &path, moduleMap_t &moduleMap); + const std::filesystem::path& path, moduleMap_t& moduleMap); /* * Display the rendered result (or just display a normal vector of string diff --git a/include/gui.hpp b/include/gui.hpp index da622d00..96c07822 100644 --- a/include/gui.hpp +++ b/include/gui.hpp @@ -1,25 +1,25 @@ /* * Copyright 2025 Toni500git - * + * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ @@ -52,16 +52,16 @@ class Window : public Gtk::Window * @param colors The non-alias colors struct * @param path The logo source path */ - Window(const Config& config, const colors_t& colors, const std::filesystem::path &path, moduleMap_t &moduleMap); + Window(const Config& config, const colors_t& colors, const std::filesystem::path& path, moduleMap_t& moduleMap); // Destroy the window, handled by GTK virtual ~Window(); private: - const Config& m_config; - const colors_t& m_colors; - const std::filesystem::path &m_path; - moduleMap_t &m_moduleMap; - bool isImage; + const Config& m_config; + const colors_t& m_colors; + const std::filesystem::path& m_path; + moduleMap_t& m_moduleMap; + bool isImage; Gtk::Overlay m_overlay; Gtk::Box m_box; diff --git a/include/parse.hpp b/include/parse.hpp index 1d13f983..21d9bef3 100644 --- a/include/parse.hpp +++ b/include/parse.hpp @@ -1,25 +1,25 @@ /* * Copyright 2025 Toni500git - * + * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ @@ -32,6 +32,7 @@ #include #include #include + #include "config.hpp" #include "query.hpp" @@ -41,7 +42,7 @@ */ struct parse_args_t { - moduleMap_t& systemInfo; + moduleMap_t& systemInfo; std::string& pureOutput; std::vector& layout; std::vector& tmp_layout; @@ -64,9 +65,9 @@ struct parse_args_t * @param parsingLayout If we are parsing layout or not * @param no_more_reset If we are recursively parsing, e.g we are inside tags */ -std::string parse(std::string input, moduleMap_t& systemInfo, std::string& pureOutput, - std::vector& layout, std::vector& tmp_layout, - const Config& config, const colors_t& colors, const bool parsingLayout, bool& no_more_reset); +std::string parse(std::string input, moduleMap_t& systemInfo, std::string& pureOutput, std::vector& layout, + std::vector& tmp_layout, const Config& config, const colors_t& colors, + const bool parsingLayout, bool& no_more_reset); // parse() for parse_args_t& arguments std::string parse(const std::string& input, parse_args_t& parse_args); @@ -99,7 +100,7 @@ std::string parse(const std::string& input, std::string& _, parse_args_t& parse_ * @param moduleMemberName The module member name */ const std::string getInfoFromName(const moduleMap_t& systemInfo, const std::string_view moduleName, - const std::string_view moduleMemberName); + const std::string_view moduleMemberName); /* * Create a colored percentage from parse() @@ -110,7 +111,7 @@ const std::string getInfoFromName(const moduleMap_t& systemInfo, const std::stri * @return The colored percentage with ending % */ std::string get_and_color_percentage(const float n1, const float n2, parse_args_t& parse_args, - const bool invert = false); + const bool invert = false); template void append_styles(fmt::text_style& current_style, Styles&&... styles) diff --git a/include/platform.hpp b/include/platform.hpp index f6dc7e28..30d9f8ff 100644 --- a/include/platform.hpp +++ b/include/platform.hpp @@ -19,20 +19,23 @@ # define CF_LINUX 0 #endif -#if (defined(__MACOS__) || defined(__MACH__) || defined(TARGET_OS_MAC) || defined(TARGET_OS_OSX) || __is_target_vendor(apple) || __is_target_os(darwin) || __is_target_os(MacOSX)) +#if (defined(__MACOS__) || defined(__MACH__) || defined(TARGET_OS_MAC) || defined(TARGET_OS_OSX) || \ + __is_target_vendor(apple) || __is_target_os(darwin) || __is_target_os(MacOSX)) # define CF_MACOS 1 #else # define CF_MACOS 0 #endif -#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__)) +#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) || defined(__CYGWIN__) || \ + defined(__MINGW32__) || defined(__MINGW64__)) # define CF_WINDOWS 1 #else # define CF_WINDOWS 0 #endif #if !(CF_LINUX || CF_ANDROID || CF_MACOS) || CF_WINDOWS -# warning "Platform currently may not be supported, only Linux, Android and MacOS. Please feel free to report any compilation errors" +# warning \ + "Platform currently may not be supported, only Linux, Android and MacOS. Please feel free to report any compilation errors" #endif -#endif // _PLATFORM_H_ +#endif // _PLATFORM_H_ diff --git a/include/query.hpp b/include/query.hpp index 0d156954..5ff25ea8 100644 --- a/include/query.hpp +++ b/include/query.hpp @@ -1,25 +1,25 @@ /* * Copyright 2025 Toni500git - * + * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ @@ -53,27 +53,33 @@ extern "C" { #include } -struct module_t { - std::string name; - std::vector submodules; /* For best performance, use std::move() when adding modules in here. */ - std::function handler; - - module_t(const std::string &name, const std::vector &submodules, const std::function handler) : name(name), submodules(submodules), handler(handler) { +struct module_t +{ + std::string name; + std::vector submodules; /* For best performance, use std::move() when adding modules in here. */ + std::function handler; + module_t(const std::string& name, const std::vector& submodules, + const std::function handler) + : name(name), submodules(submodules), handler(handler) + { } }; struct parse_args_t; // Map from a modules name to its pointer. -using moduleMap_t = - std::unordered_map; +using moduleMap_t = std::unordered_map; // used in systemInfo_t most of the time using variant = std::variant; inline bool is_live_mode = false; -#define CHECK_INIT(x) if (!x || is_live_mode) {x = true;} else {return;} +#define CHECK_INIT(x) \ + if (!x || is_live_mode) \ + x = true; \ + else \ + return; \ namespace Query { @@ -108,18 +114,18 @@ class System System(); - std::string kernel_name() noexcept; - std::string kernel_version() noexcept; - std::string hostname() noexcept; - std::string arch() noexcept; - std::string& os_pretty_name() noexcept; - std::string& os_name() noexcept; - std::string& os_id() noexcept; - std::string& os_initsys_name(); - std::string& os_initsys_version(); - std::string& os_versionid() noexcept; - std::string& os_version_codename() noexcept; - unsigned long& uptime() noexcept; + std::string kernel_name() noexcept; + std::string kernel_version() noexcept; + std::string hostname() noexcept; + std::string arch() noexcept; + std::string& os_pretty_name() noexcept; + std::string& os_name() noexcept; + std::string& os_id() noexcept; + std::string& os_initsys_name(); + std::string& os_initsys_version(); + std::string& os_versionid() noexcept; + std::string& os_version_codename() noexcept; + unsigned long& uptime() noexcept; // motherboard (host) std::string& host_modelname() noexcept; @@ -186,10 +192,10 @@ class Theme std::string cursor_size{ UNKNOWN }; }; - Theme(const std::uint8_t ver/*, moduleMap_t& queried_themes*/, const std::string& theme_name_version, + Theme(const std::uint8_t ver /*, moduleMap_t& queried_themes*/, const std::string& theme_name_version, const Config& config, const bool gsettings_only = false); - Theme(/*moduleMap_t& queried_themes, */const Config& config, const bool gsettings_only = false); + Theme(/*moduleMap_t& queried_themes, */ const Config& config, const bool gsettings_only = false); std::string gtk_theme() noexcept; std::string gtk_icon_theme() noexcept; @@ -198,9 +204,9 @@ class Theme std::string& cursor_size() noexcept; private: - User query_user; - std::string m_wmde_name; - std::string m_theme_name; + User query_user; + std::string m_wmde_name; + std::string m_theme_name; // moduleMap_t& m_queried_themes; static Theme_t m_theme_infos; }; @@ -255,7 +261,7 @@ class GPU std::string vendor{ MAGIC_LINE }; }; - GPU(const std::string& id/*, moduleMap_t& queried_gpus*/); + GPU(const std::string& id /*, moduleMap_t& queried_gpus*/); std::string& name() noexcept; std::string& vendor() noexcept; @@ -303,8 +309,8 @@ class Disk public: struct Disk_t { - std::string typefs { MAGIC_LINE }; - std::string device { MAGIC_LINE }; + std::string typefs{ MAGIC_LINE }; + std::string device{ MAGIC_LINE }; std::string mountdir{ MAGIC_LINE }; double total_amount = 0; double free_amount = 0; @@ -312,13 +318,12 @@ class Disk int types_disk = 0; }; - Disk(const std::string& path, parse_args_t& parse_args, - const bool auto_module = false); + Disk(const std::string& path, parse_args_t& parse_args, const bool auto_module = false); double& total_amount() noexcept; double& free_amount() noexcept; double& used_amount() noexcept; - int& types_disk() noexcept; + int& types_disk() noexcept; std::string& typefs() noexcept; std::string& device() noexcept; std::string& mountdir() noexcept; @@ -327,7 +332,7 @@ class Disk { return m_disks_formats; } private: - std::vector m_disks_formats/*, m_queried_devices*/; + std::vector m_disks_formats /*, m_queried_devices*/; static Disk_t m_disk_infos; }; diff --git a/include/util.hpp b/include/util.hpp index 7b5bd026..3a563a44 100644 --- a/include/util.hpp +++ b/include/util.hpp @@ -1,25 +1,25 @@ /* * Copyright 2025 Toni500git - * + * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ diff --git a/src/config.cpp b/src/config.cpp index 6242cc8c..1554bc2e 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -1,25 +1,25 @@ /* * Copyright 2025 Toni500git - * + * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ @@ -34,7 +34,7 @@ #include "switch_fnv1a.hpp" #include "util.hpp" -Config::Config(const std::filesystem::path &configFile, const std::filesystem::path &configDir) +Config::Config(const std::filesystem::path& configFile, const std::filesystem::path& configDir) { if (!std::filesystem::exists(configDir)) { @@ -49,7 +49,7 @@ Config::Config(const std::filesystem::path &configFile, const std::filesystem::p } } -void Config::loadConfigFile(const std::filesystem::path &filename, colors_t& colors) +void Config::loadConfigFile(const std::filesystem::path& filename, colors_t& colors) { try { diff --git a/src/display.cpp b/src/display.cpp index 256ed32a..4d1bb301 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -1,46 +1,48 @@ /* * Copyright 2025 Toni500git - * + * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ // Implementation of the system behind displaying/rendering the information #include "display.hpp" -#include "platform.hpp" + #include #include #include #include #include +#include "platform.hpp" + #ifndef GUI_APP # define STB_IMAGE_IMPLEMENTATION #endif #if CF_MACOS -#include +# include #else -#include +# include #endif #include @@ -66,7 +68,7 @@ std::string Display::detect_distro(const Config& config) { - //debug("/etc/os-release = \n{}", read_shell_exec("cat /etc/os-release 2> /dev/null")); + // debug("/etc/os-release = \n{}", read_shell_exec("cat /etc/os-release 2> /dev/null")); if (!config.args_custom_distro.empty()) { @@ -97,7 +99,7 @@ std::string Display::detect_distro(const Config& config) static std::vector render_with_image(moduleMap_t& systemInfo, std::vector& layout, const Config& config, const colors_t& colors, - const std::filesystem::path &path, const std::uint16_t font_width, + const std::filesystem::path& path, const std::uint16_t font_width, const std::uint16_t font_height) { int image_width, image_height, channels; @@ -115,22 +117,22 @@ static std::vector render_with_image(moduleMap_t& systemInfo, std:: close(Display::ascii_logo_fd); } - std::string _; + std::string _; std::vector tmp_layout; - parse_args_t parse_args{ systemInfo, _, layout, tmp_layout, config, colors, true }; + parse_args_t parse_args{ systemInfo, _, layout, tmp_layout, config, colors, true }; for (size_t i = 0; i < layout.size(); ++i) { - layout[i] = parse(layout[i], parse_args); + layout[i] = parse(layout[i], parse_args); parse_args.no_more_reset = false; - #if !GUI_APP +#if !GUI_APP if (!config.args_disable_colors) layout[i].insert(0, NOCOLOR); - #endif +#endif if (!tmp_layout.empty()) { - layout.erase(layout.begin()+i); - layout.insert(layout.begin()+i, tmp_layout.begin(), tmp_layout.end()); + layout.erase(layout.begin() + i); + layout.insert(layout.begin() + i, tmp_layout.begin(), tmp_layout.end()); tmp_layout.clear(); } } @@ -163,8 +165,10 @@ static std::vector render_with_image(moduleMap_t& systemInfo, std:: return layout; } - const unsigned int offset = (config.offset.back() == '%') ? Display::calc_perc(std::stof(config.offset.substr(0,config.offset.size()-1)), width, 0) : - std::stoi(config.offset); + const unsigned int offset = + (config.offset.back() == '%') + ? Display::calc_perc(std::stof(config.offset.substr(0, config.offset.size() - 1)), width, 0) + : std::stoi(config.offset); for (std::string& str : layout) for (size_t _ = 0; _ < width + offset; ++_) @@ -178,8 +182,8 @@ static std::vector render_with_image(moduleMap_t& systemInfo, std:: static bool get_pos(int& y, int& x) { std::array buf; - int ret, i, pow; - char ch; + int ret, i, pow; + char ch; y = 0; x = 0; @@ -220,12 +224,10 @@ static bool get_pos(int& y, int& x) return true; } -const std::string test() { - return "Test!!!"; -} +const std::string test() { return "Test!!!"; } std::vector Display::render(const Config& config, const colors_t& colors, const bool already_analyzed_file, - const std::filesystem::path &path, moduleMap_t &moduleMap) + const std::filesystem::path& path, moduleMap_t& moduleMap) { std::vector asciiArt{}, layout{ config.args_layout.empty() ? config.layout : config.args_layout }; @@ -269,10 +271,10 @@ std::vector Display::render(const Config& config, const colors_t& c debug("{} distro_path = {}", __FUNCTION__, distro_path); // this is just for parse() to auto add the distro colors - std::ifstream distro_file(distro_path); - std::string line, _; + std::ifstream distro_file(distro_path); + std::string line, _; std::vector tmp_layout; - parse_args_t parse_args{ moduleMap, _, layout, tmp_layout, config, colors, false }; + parse_args_t parse_args{ moduleMap, _, layout, tmp_layout, config, colors, false }; while (std::getline(distro_file, line)) { @@ -283,7 +285,7 @@ std::vector Display::render(const Config& config, const colors_t& c std::vector pureAsciiArtLens; int maxLineLength = -1; - + struct winsize win; ioctl(STDOUT_FILENO, TIOCGWINSZ, &win); @@ -323,21 +325,21 @@ std::vector Display::render(const Config& config, const colors_t& c std::string line; while (std::getline(file, line)) { - std::string pureOutput; + std::string pureOutput; std::vector tmp_layout; - parse_args_t parse_args{ moduleMap, pureOutput, layout, tmp_layout, config, colors, false }; + parse_args_t parse_args{ moduleMap, pureOutput, layout, tmp_layout, config, colors, false }; std::string asciiArt_s = parse(line, parse_args); parse_args.no_more_reset = false; - #if !GUI_APP +#if !GUI_APP if (!config.args_disable_colors) asciiArt_s += NOCOLOR; - #else +#else // check parse.cpp const size_t pos = asciiArt_s.rfind("$ Display::render(const Config& config, const colors_t& c if (config.args_print_logo_only) return asciiArt; - std::string _; + std::string _; std::vector tmp_layout; - parse_args_t parse_args{ moduleMap, _, layout, tmp_layout, config, colors, true }; + parse_args_t parse_args{ moduleMap, _, layout, tmp_layout, config, colors, true }; for (size_t i = 0; i < layout.size(); ++i) { - layout[i] = parse(layout[i], parse_args); + layout[i] = parse(layout[i], parse_args); parse_args.no_more_reset = false; - #if !GUI_APP +#if !GUI_APP if (!config.args_disable_colors) layout[i].insert(0, NOCOLOR); - #endif +#endif if (!tmp_layout.empty()) { - layout.erase(layout.begin()+i); - layout.insert(layout.begin()+i, tmp_layout.begin(), tmp_layout.end()); - i += tmp_layout.size()-1; + layout.erase(layout.begin() + i); + layout.insert(layout.begin() + i, tmp_layout.begin(), tmp_layout.end()); + i += tmp_layout.size() - 1; tmp_layout.clear(); } } @@ -383,13 +385,15 @@ std::vector Display::render(const Config& config, const colors_t& c if (config.logo_position == "top" || config.logo_position == "bottom") { if (!asciiArt.empty()) - layout.insert(config.logo_position == "top" ? layout.begin() : layout.end(), - asciiArt.begin(), asciiArt.end()); + layout.insert(config.logo_position == "top" ? layout.begin() : layout.end(), asciiArt.begin(), + asciiArt.end()); return layout; } - const unsigned int offset = (config.offset.back() == '%') ? calc_perc(std::stof(config.offset.substr(0,config.offset.size()-1)), win.ws_col, maxLineLength) : - std::stoi(config.offset); + const unsigned int offset = + (config.offset.back() == '%') + ? calc_perc(std::stof(config.offset.substr(0, config.offset.size() - 1)), win.ws_col, maxLineLength) + : std::stoi(config.offset); size_t i; for (i = 0; i < layout.size(); i++) @@ -414,10 +418,10 @@ std::vector Display::render(const Config& config, const colors_t& c for (size_t j = 0; j < spaces; j++) layout.at(i).insert(origin, " "); - #if !GUI_APP +#if !GUI_APP if (!config.args_disable_colors) layout.at(i) += NOCOLOR; - #endif +#endif } for (; i < asciiArt.size(); i++) diff --git a/src/gui.cpp b/src/gui.cpp index f5992e15..c4b20f0e 100644 --- a/src/gui.cpp +++ b/src/gui.cpp @@ -1,25 +1,25 @@ /* * Copyright 2025 Toni500git - * + * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ @@ -63,7 +63,7 @@ using namespace GUI; static std::vector render_with_image(const Config& config, const colors_t& colors) { std::string path{ Display::detect_distro(config) }; - moduleMap_t systemInfo{}; + moduleMap_t systemInfo{}; std::vector layout{ config.args_layout.empty() ? config.layout : config.args_layout }; int image_width, image_height, channels; @@ -87,10 +87,10 @@ static std::vector render_with_image(const Config& config, const co } // this is just for parse() to auto add the distro colors - std::ifstream file(path, std::ios::binary); - std::string line, _; + std::ifstream file(path, std::ios::binary); + std::string line, _; std::vector tmp_layout; - parse_args_t parse_args{ systemInfo, _, layout, tmp_layout, config, colors, false }; + parse_args_t parse_args{ systemInfo, _, layout, tmp_layout, config, colors, false }; while (std::getline(file, line)) { parse(line, parse_args); @@ -100,13 +100,13 @@ static std::vector render_with_image(const Config& config, const co parse_args.parsingLayout = true; for (size_t i = 0; i < layout.size(); ++i) { - layout[i] = parse(layout[i], parse_args); + layout[i] = parse(layout[i], parse_args); parse_args.no_more_reset = false; if (!tmp_layout.empty()) { - layout.erase(layout.begin()+i); - layout.insert(layout.begin()+i, tmp_layout.begin(), tmp_layout.end()); + layout.erase(layout.begin() + i); + layout.insert(layout.begin() + i, tmp_layout.begin(), tmp_layout.end()); tmp_layout.clear(); } } @@ -116,8 +116,10 @@ static std::vector render_with_image(const Config& config, const co [](const std::string_view str) { return str.find(MAGIC_LINE) != std::string::npos; }), layout.end()); - const unsigned int offset = (config.offset.back() == '%') ? Display::calc_perc(std::stof(config.offset.substr(0,config.offset.size()-1)), image_width, 0) : - std::stoi(config.offset); + const unsigned int offset = + (config.offset.back() == '%') + ? Display::calc_perc(std::stof(config.offset.substr(0, config.offset.size() - 1)), image_width, 0) + : std::stoi(config.offset); for (size_t i = 0; i < layout.size(); i++) for (size_t _ = 0; _ < offset; _++) // I use _ because we don't need it @@ -135,12 +137,13 @@ bool Window::set_layout_markup() } else { - m_label.set_markup(fmt::format("{}", fmt::join(Display::render(m_config, m_colors, true, m_path, m_moduleMap), "\n"))); + m_label.set_markup( + fmt::format("{}", fmt::join(Display::render(m_config, m_colors, true, m_path, m_moduleMap), "\n"))); } return true; } -Window::Window(const Config& config, const colors_t& colors, const std::filesystem::path &path, moduleMap_t &moduleMap) : +Window::Window(const Config& config, const colors_t& colors, const std::filesystem::path& path, moduleMap_t& moduleMap) : m_config(config), m_colors(colors), m_path(path), @@ -188,7 +191,6 @@ Window::Window(const Config& config, const colors_t& colors, const std::filesyst if (is_live_mode) Glib::signal_timeout().connect(sigc::mem_fun(*this, &Window::set_layout_markup), config.loop_ms); - if (config.gui_bg_image != "disable") { if (!std::filesystem::exists(config.gui_bg_image)) diff --git a/src/main.cpp b/src/main.cpp index af04664b..8fe32d4f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,25 +1,25 @@ /* * Copyright 2025 Toni500git - * + * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ @@ -39,8 +39,8 @@ #include "display.hpp" #include "fmt/ranges.h" #include "gui.hpp" -#include "query.hpp" #include "platform.hpp" +#include "query.hpp" #include "switch_fnv1a.hpp" #include "util.hpp" @@ -65,10 +65,11 @@ using namespace std::string_view_literals; // Print the version and some other infos, then exit successfully static void version() { - std::string version{ fmt::format("customfetch {} built from branch {} at {} commit {} ({}).\n" - "Date: {}\n" - "Tag: {}", - VERSION, GIT_BRANCH, GIT_DIRTY, GIT_COMMIT_HASH, GIT_COMMIT_MESSAGE, GIT_COMMIT_DATE, GIT_TAG) }; + std::string version{ fmt::format( + "customfetch {} built from branch {} at {} commit {} ({}).\n" + "Date: {}\n" + "Tag: {}", + VERSION, GIT_BRANCH, GIT_DIRTY, GIT_COMMIT_HASH, GIT_COMMIT_MESSAGE, GIT_COMMIT_DATE, GIT_TAG) }; #if !(USE_DCONF) version += "\n\nNO flags were set\n"; @@ -520,7 +521,7 @@ static void list_logos(const std::string& data_dir) die("failed to access data directory '{}'", data_dir); std::vector list; - for (const auto& logo : std::filesystem::directory_iterator{data_dir}) + for (const auto& logo : std::filesystem::directory_iterator{ data_dir }) { if (logo.is_regular_file()) list.push_back(logo.path().stem()); @@ -787,31 +788,34 @@ int main(int argc, char *argv[]) config.loadConfigFile(configFile, colors); LOAD_LIBRARY("libcufetch.so", die("Failed to load libcufetch!")); - void *cufetch_handle = handle; + void* cufetch_handle = handle; /* TODO(burntranch): track each library and unload them. */ const std::filesystem::path modDir = configDir / "mods"; - for (const auto &entry : std::filesystem::directory_iterator(modDir)) { + for (const auto& entry : std::filesystem::directory_iterator(modDir)) + { fmt::println("loading mod at {}!", entry.path().string()); - - LOAD_LIBRARY(std::filesystem::absolute(entry.path()).c_str(), warn("Failed to load mod {}!", entry.path().string())) + + LOAD_LIBRARY(std::filesystem::absolute(entry.path()).c_str(), + warn("Failed to load mod {}!", entry.path().string())) if (!handle) continue; - LOAD_LIB_SYMBOL(void, start, void *) + LOAD_LIB_SYMBOL(void, start, void*) start(cufetch_handle); } handle = cufetch_handle; - LOAD_LIB_SYMBOL(const std::vector &, cfGetModules) - - const std::vector &modules = cfGetModules(); - moduleMap_t moduleMap; + LOAD_LIB_SYMBOL(const std::vector&, cfGetModules) + + const std::vector& modules = cfGetModules(); + moduleMap_t moduleMap; fmt::println("modules count: {}", modules.size()); - for (const module_t &module : modules) { + for (const module_t& module : modules) + { if (!module.handler) continue; @@ -845,7 +849,7 @@ int main(int argc, char *argv[]) if (!std::filesystem::exists(path) && !config.args_disable_source) { - path = std::filesystem::temp_directory_path() / "customfetch_ascii_logo-XXXXXX"; + path = std::filesystem::temp_directory_path() / "customfetch_ascii_logo-XXXXXX"; Display::ascii_logo_fd = mkstemp(path.data()); if (Display::ascii_logo_fd < 0) die("Failed to create temp path at {}: {}", path, strerror(errno)); @@ -870,7 +874,7 @@ int main(int argc, char *argv[]) if (is_live_mode) { - const std::chrono::milliseconds sleep_ms {config.loop_ms}; + const std::chrono::milliseconds sleep_ms{ config.loop_ms }; while (true) { diff --git a/src/parse.cpp b/src/parse.cpp index f62181b7..7c3bd353 100644 --- a/src/parse.cpp +++ b/src/parse.cpp @@ -1,25 +1,25 @@ /* * Copyright 2025 Toni500git - * + * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ @@ -87,7 +87,7 @@ class Parser const std::string_view src; std::string& pureOutput; size_t dollar_pos = 0; - size_t pos = 0; + size_t pos = 0; }; // declarations of static members in query.hpp @@ -124,13 +124,14 @@ static std::array get_ansi_color(const std::string_view noesc_st { const size_t first_m = noesc_str.rfind('m'); if (first_m == std::string::npos) - die(_("Parser: failed to parse layout/ascii art: missing 'm' while using ANSI color escape code in '{}'"), noesc_str); + die(_("Parser: failed to parse layout/ascii art: missing 'm' while using ANSI color escape code in '{}'"), + noesc_str); - std::string col {noesc_str.data()}; + std::string col{ noesc_str.data() }; col.erase(first_m); // 1;42 - std::string weight {hasStart(col, "1;") ? "bold" : "normal"}; - std::string type {"fgcolor"}; // either fgcolor or bgcolor + std::string weight{ hasStart(col, "1;") ? "bold" : "normal" }; + std::string type{ "fgcolor" }; // either fgcolor or bgcolor if (hasStart(col, "1;") || hasStart(col, "0;")) col.erase(0, 2); @@ -206,8 +207,8 @@ static std::string convert_ansi_escape_rgb(const std::string_view noesc_str) std::string parse(const std::string& input, std::string& _, parse_args_t& parse_args) { - return parse(input, parse_args.systemInfo, _, parse_args.layout, parse_args.tmp_layout, - parse_args.config, parse_args.colors, parse_args.parsingLayout, parse_args.no_more_reset); + return parse(input, parse_args.systemInfo, _, parse_args.layout, parse_args.tmp_layout, parse_args.config, + parse_args.colors, parse_args.parsingLayout, parse_args.no_more_reset); } std::string parse(const std::string& input, parse_args_t& parse_args) @@ -216,8 +217,7 @@ std::string parse(const std::string& input, parse_args_t& parse_args) parse_args.config, parse_args.colors, parse_args.parsingLayout, parse_args.no_more_reset); } -std::string get_and_color_percentage(const float n1, const float n2, parse_args_t& parse_args, - const bool invert) +std::string get_and_color_percentage(const float n1, const float n2, parse_args_t& parse_args, const bool invert) { const Config& config = parse_args.config; const float result = n1 / n2 * static_cast(100); @@ -326,7 +326,7 @@ std::optional parse_color_tag(Parser& parser, parse_args_t& parse_a const colors_t& colors = parse_args.colors; const size_t taglen = color.length() + "${}"_len; - const std::string endspan {!parse_args.firstrun_clr ? "" : ""}; + const std::string endspan{ !parse_args.firstrun_clr ? "" : "" }; if (config.args_disable_colors) { @@ -348,7 +348,7 @@ std::optional parse_color_tag(Parser& parser, parse_args_t& parse_a if (it_name != config.colors_name.end()) { const size_t index = std::distance(config.colors_name.begin(), it_name); - color = config.colors_value.at(index); + color = config.colors_value.at(index); } } @@ -387,7 +387,7 @@ std::optional parse_color_tag(Parser& parser, parse_args_t& parse_a else { std::string str_clr; - #if GUI_APP +#if GUI_APP switch (fnv1a16::hash(color)) { case "black"_fnv1a16: str_clr = colors.gui_black; break; @@ -520,9 +520,9 @@ std::optional parse_color_tag(Parser& parser, parse_args_t& parse_a parse_args.pureOutput.erase(parser.dollar_pos, taglen); return output; } - - // #if !GUI_APP - #else + +// #if !GUI_APP +#else switch (fnv1a16::hash(color)) { case "black"_fnv1a16: str_clr = colors.black; break; @@ -592,8 +592,9 @@ std::optional parse_color_tag(Parser& parser, parse_args_t& parse_a } if (style.has_background() || style.has_foreground()) { - const uint32_t rgb_num = bgcolor ? style.get_background().value.rgb_color : style.get_foreground().value.rgb_color; - fmt::rgb rgb(rgb_num); + const uint32_t rgb_num = + bgcolor ? style.get_background().value.rgb_color : style.get_foreground().value.rgb_color; + fmt::rgb rgb(rgb_num); fmt::detail::ansi_color_escape ansi(rgb, bgcolor ? "\x1B[48;2;" : "\x1B[38;2;"); output += ansi.begin(); } @@ -613,10 +614,9 @@ std::optional parse_color_tag(Parser& parser, parse_args_t& parse_a parse_args.pureOutput.erase(parser.dollar_pos, taglen); return output; } - #endif +#endif - if (!parse_args.parsingLayout && - std::find(auto_colors.begin(), auto_colors.end(), color) == auto_colors.end()) + if (!parse_args.parsingLayout && std::find(auto_colors.begin(), auto_colors.end(), color) == auto_colors.end()) auto_colors.push_back(color); } @@ -740,7 +740,8 @@ std::string parse(Parser& parser, parse_args_t& parse_args, const bool evaluate, } std::string parse(std::string input, moduleMap_t& systemInfo, std::string& pureOutput, std::vector& layout, - std::vector& tmp_layout, const Config& config, const colors_t& colors, const bool parsingLayout, bool& no_more_reset) + std::vector& tmp_layout, const Config& config, const colors_t& colors, + const bool parsingLayout, bool& no_more_reset) { if (!config.sep_reset.empty() && parsingLayout && !no_more_reset) { @@ -752,7 +753,8 @@ std::string parse(std::string input, moduleMap_t& systemInfo, std::string& pureO no_more_reset = true; } - parse_args_t parse_args{ systemInfo, pureOutput, layout, tmp_layout, config, colors, parsingLayout, true, no_more_reset }; + parse_args_t parse_args{ systemInfo, pureOutput, layout, tmp_layout, config, + colors, parsingLayout, true, no_more_reset }; Parser parser{ input, pureOutput }; std::string ret{ parse(parser, parse_args) }; diff --git a/src/query/android/battery.cpp b/src/query/android/battery.cpp index 243ec6a1..c274d88c 100644 --- a/src/query/android/battery.cpp +++ b/src/query/android/battery.cpp @@ -1,25 +1,25 @@ /* * Copyright 2025 Toni500git - * + * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ @@ -46,9 +46,9 @@ static Battery::Battery_t get_battery_infos_termux() const auto& doc = json::jobject::parse(result); - infos.status = doc["plugged"].as_string(); - infos.perc = doc["percentage"]; - infos.temp = doc["temperature"]; + infos.status = doc["plugged"].as_string(); + infos.perc = doc["percentage"]; + infos.temp = doc["temperature"]; switch (fnv1a16::hash(infos.status)) { diff --git a/src/query/android/gpu.cpp b/src/query/android/gpu.cpp index 7368bf09..cf6c3800 100644 --- a/src/query/android/gpu.cpp +++ b/src/query/android/gpu.cpp @@ -195,7 +195,7 @@ static std::string detect_adreno(const std::string& cpu_model_name) return MAGIC_LINE; } -GPU::GPU(const std::string& id/*, moduleMap_t& queried_gpus*/) +GPU::GPU(const std::string& id /*, moduleMap_t& queried_gpus*/) { CPU query_cpu; if (query_cpu.vendor() == "QUALCOMM" || query_cpu.vendor() == "QTI") diff --git a/src/query/android/system.cpp b/src/query/android/system.cpp index 374f0d97..c44796c6 100644 --- a/src/query/android/system.cpp +++ b/src/query/android/system.cpp @@ -29,8 +29,8 @@ #include #include -#include #include +#include #include #include "../linux/utils/packages.hpp" @@ -88,7 +88,7 @@ System::System() if (uname(&m_uname_infos) != 0) die("uname() failed: {}\nCould not get system infos", strerror(errno)); - m_uptime = get_uptime(); + m_uptime = get_uptime(); m_system_infos = get_system_infos(); } diff --git a/src/query/android/theme.cpp b/src/query/android/theme.cpp index bd874d91..a09730aa 100644 --- a/src/query/android/theme.cpp +++ b/src/query/android/theme.cpp @@ -33,16 +33,17 @@ using namespace Query; Theme::Theme(const std::uint8_t ver, moduleMap_t& queried_themes, const std::string& theme_name_version, const Config& config, const bool gsettings_only) - : m_queried_themes(queried_themes) + : m_queried_themes(queried_themes) { - m_theme_infos.cursor = m_theme_infos.gtk_font = m_theme_infos.cursor_size = m_theme_infos.gtk_theme_name = m_theme_infos.gtk_icon_theme - = MAGIC_LINE; + m_theme_infos.cursor = m_theme_infos.gtk_font = m_theme_infos.cursor_size = m_theme_infos.gtk_theme_name = + m_theme_infos.gtk_icon_theme = MAGIC_LINE; } -Theme::Theme(moduleMap_t& queried_themes, const Config& config, const bool gsettings_only) : m_queried_themes(queried_themes) +Theme::Theme(moduleMap_t& queried_themes, const Config& config, const bool gsettings_only) + : m_queried_themes(queried_themes) { - m_theme_infos.cursor = m_theme_infos.gtk_font = m_theme_infos.cursor_size = m_theme_infos.gtk_theme_name = m_theme_infos.gtk_icon_theme - = MAGIC_LINE; + m_theme_infos.cursor = m_theme_infos.gtk_font = m_theme_infos.cursor_size = m_theme_infos.gtk_theme_name = + m_theme_infos.gtk_icon_theme = MAGIC_LINE; } // clang-format off diff --git a/src/query/linux/battery.cpp b/src/query/linux/battery.cpp index ba156688..5cfc1cfc 100644 --- a/src/query/linux/battery.cpp +++ b/src/query/linux/battery.cpp @@ -1,25 +1,25 @@ /* * Copyright 2025 Toni500git - * + * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ @@ -27,8 +27,8 @@ #if CF_LINUX #include -#include #include +#include #include "query.hpp" #include "util.hpp" @@ -39,7 +39,7 @@ static void read_strip_syspath(std::string& str, const std::string_view path) { str = read_by_syspath(path); debug("str = {} || path = {}", str, path); - + // optimization if (str.back() == '\n') str.pop_back(); @@ -53,7 +53,7 @@ static Battery::Battery_t get_battery_infos() if (!std::filesystem::exists("/sys/class/power_supply/")) return infos; - for (const auto& dir_entry : std::filesystem::directory_iterator{"/sys/class/power_supply/"}) + for (const auto& dir_entry : std::filesystem::directory_iterator{ "/sys/class/power_supply/" }) { const std::string& path = dir_entry.path().string() + "/"; debug("battery path = {}", path); @@ -93,7 +93,7 @@ static Battery::Battery_t get_battery_infos() read_strip_syspath(tmp, path + "status"); if (tmp != UNKNOWN) infos.status = tmp; - + read_strip_syspath(tmp, path + "capacity_level"); if (tmp != UNKNOWN) infos.capacity_level = tmp; diff --git a/src/query/linux/disk.cpp b/src/query/linux/disk.cpp index 3a3d0217..394e6e41 100644 --- a/src/query/linux/disk.cpp +++ b/src/query/linux/disk.cpp @@ -1,25 +1,25 @@ /* * Copyright 2025 Toni500git - * + * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ @@ -47,78 +47,79 @@ #if CF_LINUX || CF_ANDROID #include -#include -#include #include + #include +#include +#include #include #include "config.hpp" +#include "parse.hpp" #include "query.hpp" #include "util.hpp" -#include "parse.hpp" using namespace Query; // https://github.com/fastfetch-cli/fastfetch/blob/dev/src/detection/disk/disk_linux.c static bool is_physical_device(const mntent* device) { - #if !CF_ANDROID // On Android, `/dev` is not accessible, so that the following checks always fail +#if !CF_ANDROID // On Android, `/dev` is not accessible, so that the following checks always fail - //Always show the root path + // Always show the root path if (strcmp(device->mnt_dir, "/") == 0) return true; if (strcmp(device->mnt_fsname, "none") == 0) return false; - //DrvFs is a filesystem plugin to WSL that was designed to support interop between WSL and the Windows filesystem. + // DrvFs is a filesystem plugin to WSL that was designed to support interop between WSL and the Windows filesystem. if (strcmp(device->mnt_type, "9p") == 0) return std::string_view(device->mnt_opts).find("aname=drvfs") != std::string_view::npos; - //ZFS pool + // ZFS pool if (strcmp(device->mnt_type, "zfs") == 0) return true; - //Pseudo filesystems don't have a device in /dev + // Pseudo filesystems don't have a device in /dev if (!hasStart(device->mnt_fsname, "/dev/")) return false; - //#731 + // #731 if (strcmp(device->mnt_type, "bcachefs") == 0) return true; - if( - hasStart(device->mnt_fsname + 5, "loop") || //Ignore loop devices - hasStart(device->mnt_fsname + 5, "ram") || //Ignore ram devices - hasStart(device->mnt_fsname + 5, "fd") //Ignore fd devices - ) return false; + if (hasStart(device->mnt_fsname + 5, "loop") || // Ignore loop devices + hasStart(device->mnt_fsname + 5, "ram") || // Ignore ram devices + hasStart(device->mnt_fsname + 5, "fd") // Ignore fd devices + ) + return false; struct stat deviceStat; if (stat(device->mnt_fsname, &deviceStat) != 0) return false; - //Ignore all devices that are not block devices + // Ignore all devices that are not block devices if (!S_ISBLK(deviceStat.st_mode)) return false; - #else +#else - //Pseudo filesystems don't have a device in /dev + // Pseudo filesystems don't have a device in /dev if (!hasStart(device->mnt_fsname, "/dev/")) return false; - if( - hasStart(device->mnt_fsname + 5, "loop") || //Ignore loop devices - hasStart(device->mnt_fsname + 5, "ram") || //Ignore ram devices - hasStart(device->mnt_fsname + 5, "fd") //Ignore fd devices - ) return false; + if (hasStart(device->mnt_fsname + 5, "loop") || // Ignore loop devices + hasStart(device->mnt_fsname + 5, "ram") || // Ignore ram devices + hasStart(device->mnt_fsname + 5, "fd") // Ignore fd devices + ) + return false; // https://source.android.com/docs/core/ota/apex?hl=zh-cn if (hasStart(device->mnt_dir, "/apex/")) return false; - #endif // !CF_ANDROID +#endif // !CF_ANDROID return true; } @@ -129,7 +130,7 @@ static bool is_removable(const mntent* device) return false; // like str.substr(5); - std::string sys_block_partition {fmt::format("/sys/class/block/{}", (device->mnt_fsname + "/dev/"_len))}; + std::string sys_block_partition{ fmt::format("/sys/class/block/{}", (device->mnt_fsname + "/dev/"_len)) }; // check if it's like /dev/sda1 if (sys_block_partition.back() >= '0' && sys_block_partition.back() <= '9') sys_block_partition.pop_back(); @@ -153,7 +154,7 @@ static int get_disk_type(const mntent* device) ret |= DISK_VOLUME_TYPE_READ_ONLY; return ret; -#else // CF_ANDROID +#else // CF_ANDROID if (strcmp(device->mnt_dir, "/") == 0 || strcmp(device->mnt_dir, "/storage/emulated") == 0) return DISK_VOLUME_TYPE_REGULAR; @@ -164,7 +165,7 @@ static int get_disk_type(const mntent* device) #endif } -static std::string format_auto_query_string(std::string str, const struct mntent *device) +static std::string format_auto_query_string(std::string str, const struct mntent* device) { replace_str(str, "%1", device->mnt_dir); replace_str(str, "%2", device->mnt_fsname); @@ -181,13 +182,12 @@ static std::string format_auto_query_string(std::string str, const struct mntent Disk::Disk(const std::string& path, parse_args_t& parse_args, const bool auto_module) { - if (access(path.data(), F_OK) != 0 && !auto_module) { // if user is using $ or $ // then let's just "try" to remove it - m_disk_infos.typefs = MAGIC_LINE; - m_disk_infos.device = MAGIC_LINE; + m_disk_infos.typefs = MAGIC_LINE; + m_disk_infos.device = MAGIC_LINE; m_disk_infos.mountdir = MAGIC_LINE; return; } @@ -224,8 +224,7 @@ Disk::Disk(const std::string& path, parse_args_t& parse_args, const bool auto_mo parse_args.no_more_reset = false; debug("AUTO: pDevice->mnt_dir = {} && pDevice->mnt_fsname = {}", pDevice->mnt_dir, pDevice->mnt_fsname); m_disks_formats.push_back( - parse(format_auto_query_string(parse_args.config.auto_disks_fmt, pDevice), parse_args) - ); + parse(format_auto_query_string(parse_args.config.auto_disks_fmt, pDevice), parse_args)); } endmntent(mountsFile); @@ -259,8 +258,8 @@ Disk::Disk(const std::string& path, parse_args_t& parse_args, const bool auto_mo return; } - m_disk_infos.total_amount = static_cast(fs.f_blocks * fs.f_frsize); - m_disk_infos.free_amount = static_cast(fs.f_bfree * fs.f_frsize); + m_disk_infos.total_amount = static_cast(fs.f_blocks * fs.f_frsize); + m_disk_infos.free_amount = static_cast(fs.f_bfree * fs.f_frsize); m_disk_infos.used_amount = m_disk_infos.total_amount - m_disk_infos.free_amount; endmntent(mountsFile); diff --git a/src/query/linux/gpu.cpp b/src/query/linux/gpu.cpp index 093c7138..f89601a3 100644 --- a/src/query/linux/gpu.cpp +++ b/src/query/linux/gpu.cpp @@ -1,25 +1,25 @@ /* * Copyright 2025 Toni500git - * + * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ @@ -29,11 +29,11 @@ #include #include #include -#include "fmt/format.h" +#include "fmt/format.h" +#include "parse.hpp" #include "query.hpp" #include "util.hpp" -#include "parse.hpp" using namespace Query; @@ -76,7 +76,7 @@ static GPU::GPU_t get_gpu_infos(const std::string_view m_vendor_id_s, const std: return ret; } -GPU::GPU(const std::string& id/*, systemInfo_t& queried_gpus*/) +GPU::GPU(const std::string& id /*, systemInfo_t& queried_gpus*/) { // if (queried_gpus.find(id) != queried_gpus.end()) // { @@ -87,8 +87,8 @@ GPU::GPU(const std::string& id/*, systemInfo_t& queried_gpus*/) const std::uint16_t max_iter = 10; std::uint16_t id_iter = std::stoi(id); - std::string sys_path; - int i = 0; + std::string sys_path; + int i = 0; for (; i <= max_iter; i++) { sys_path = "/sys/class/drm/card" + fmt::to_string(id_iter); diff --git a/src/query/linux/ram.cpp b/src/query/linux/ram.cpp index 006339e7..a99acdcb 100644 --- a/src/query/linux/ram.cpp +++ b/src/query/linux/ram.cpp @@ -1,25 +1,25 @@ /* * Copyright 2025 Toni500git - * + * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ diff --git a/src/query/linux/system.cpp b/src/query/linux/system.cpp index a44213ba..1d127efd 100644 --- a/src/query/linux/system.cpp +++ b/src/query/linux/system.cpp @@ -1,25 +1,25 @@ /* * Copyright 2025 Toni500git - * + * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ @@ -29,19 +29,19 @@ #include #include -#include #include #include #include #include #include +#include #include #include #include "config.hpp" #include "query.hpp" -#include "util.hpp" #include "switch_fnv1a.hpp" +#include "util.hpp" #include "utils/packages.hpp" using namespace Query; @@ -79,7 +79,7 @@ static System::System_t get_system_infos_lsb_releases() System::System_t ret; debug("calling in System {}", __PRETTY_FUNCTION__); - std::string lsb_release_path; + std::string lsb_release_path; constexpr std::array lsb_paths = { "/etc/lsb-release", "/usr/lib/lsb-release" }; for (const std::string_view path : lsb_paths) { @@ -120,8 +120,9 @@ static System::System_t get_system_infos_os_releases() System::System_t ret; debug("calling in System {}", __PRETTY_FUNCTION__); - std::string os_release_path; - constexpr std::array os_paths = { "/etc/os-release", "/usr/lib/os-release", "/usr/share/os-release" }; + std::string os_release_path; + constexpr std::array os_paths = { "/etc/os-release", "/usr/lib/os-release", + "/usr/share/os-release" }; for (const std::string_view path : os_paths) { if (std::filesystem::exists(path)) @@ -134,7 +135,7 @@ static System::System_t get_system_infos_os_releases() std::ifstream os_release_file(os_release_path, std::ios::in); if (!os_release_file.is_open()) { - //error(_("Could not open '{}'\nFailed to get OS infos"), os_release_path); + // error(_("Could not open '{}'\nFailed to get OS infos"), os_release_path); return ret; } @@ -166,7 +167,7 @@ static unsigned long get_uptime() { const std::string& buf = read_by_syspath("/proc/uptime"); if (buf != UNKNOWN) - return std::stoul(buf.substr(0,buf.find('.'))); // 19065.18 190952.06 + return std::stoul(buf.substr(0, buf.find('.'))); // 19065.18 190952.06 struct std::timespec uptime; if (clock_gettime(CLOCK_BOOTTIME, &uptime) != 0) @@ -182,7 +183,7 @@ System::System() if (uname(&m_uname_infos) != 0) die(_("uname() failed: {}\nCould not get system infos"), strerror(errno)); - m_uptime = get_uptime(); + m_uptime = get_uptime(); m_system_infos = get_system_infos_os_releases(); if (m_system_infos.os_name == UNKNOWN || m_system_infos.os_pretty_name == UNKNOWN) m_system_infos = get_system_infos_lsb_releases(); @@ -236,7 +237,7 @@ std::string& System::os_initsys_name() static bool done = false; if (done && !is_live_mode) return m_system_infos.os_initsys_name; - + // there's no way PID 1 doesn't exist. // This will always succeed (because we are on linux) std::ifstream f_initsys("/proc/1/comm", std::ios::binary); @@ -267,12 +268,12 @@ std::string& System::os_initsys_version() return m_system_infos.os_initsys_version; std::string path; - char buf[PATH_MAX]; + char buf[PATH_MAX]; if (realpath(which("init").c_str(), buf)) path = buf; std::ifstream f(path, std::ios::in); - std::string line; + std::string line; const std::string& name = str_tolower(this->os_initsys_name()); switch (fnv1a16::hash(name)) @@ -294,7 +295,7 @@ std::string& System::os_initsys_version() case "openrc"_fnv1a16: { std::string tmp; - while(read_binary_file(f, line)) + while (read_binary_file(f, line)) { if (line == "RC_VERSION") { @@ -316,7 +317,7 @@ std::string& System::pkgs_installed(const Config& config) if (!done || is_live_mode) { m_system_infos.pkgs_installed = get_all_pkgs(config); - done = true; + done = true; } return m_system_infos.pkgs_installed; diff --git a/src/query/linux/theme.cpp b/src/query/linux/theme.cpp index a5cb70e8..cba7115b 100644 --- a/src/query/linux/theme.cpp +++ b/src/query/linux/theme.cpp @@ -1,25 +1,25 @@ /* * Copyright 2025 Toni500git - * + * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ @@ -38,8 +38,8 @@ #include "util.hpp" #if USE_DCONF -# include -# include +#include +#include #endif using namespace Query; @@ -48,9 +48,9 @@ const std::string& configDir = getHomeConfigDir(); static bool get_xsettings_xfce4(const std::string_view property, const std::string_view subproperty, std::string& ret) { - static bool done = false; + static bool done = false; static rapidxml::xml_document<> doc; - static std::string buffer; + static std::string buffer; if (!done) { @@ -59,7 +59,7 @@ static bool get_xsettings_xfce4(const std::string_view property, const std::stri if (!f.is_open()) return false; - buffer.assign(std::istreambuf_iterator{f}, std::istreambuf_iterator()); + buffer.assign(std::istreambuf_iterator{ f }, std::istreambuf_iterator()); buffer.push_back('\0'); doc.parse<0>(&buffer[0]); @@ -67,13 +67,14 @@ static bool get_xsettings_xfce4(const std::string_view property, const std::stri } rapidxml::xml_node<>* node1 = doc.first_node("channel")->first_node("property"); - for (; node1 && std::string_view(node1->first_attribute("name")->value()) != property; node1 = node1->next_sibling("property")); + for (; node1 && std::string_view(node1->first_attribute("name")->value()) != property; + node1 = node1->next_sibling("property")) + ; rapidxml::xml_node<>* node2 = node1->first_node("property"); for (; node2; node2 = node2->next_sibling()) { - if (std::string_view(node2->first_attribute("name")->value()) == subproperty && - node2->first_attribute("value")) + if (std::string_view(node2->first_attribute("name")->value()) == subproperty && node2->first_attribute("value")) { ret = node2->first_attribute("value")->value(); return true; @@ -89,24 +90,23 @@ static bool get_xsettings_xfce4(const std::string_view property, const std::stri // static bool assert_cursor(Theme::Theme_t& theme) { - return - (theme.cursor != MAGIC_LINE && theme.cursor_size != UNKNOWN) || - (!theme.cursor.empty() && !theme.cursor_size.empty()); + return (theme.cursor != MAGIC_LINE && theme.cursor_size != UNKNOWN) || + (!theme.cursor.empty() && !theme.cursor_size.empty()); } static bool get_cursor_xresources(Theme::Theme_t& theme) { const std::string& path = expandVar("~/.Xresources"); - std::ifstream f(path, std::ios::in); + std::ifstream f(path, std::ios::in); if (!f.is_open()) { - theme.cursor = MAGIC_LINE; + theme.cursor = MAGIC_LINE; theme.cursor_size = UNKNOWN; return false; } std::uint16_t iter_index = 0; - std::string line; + std::string line; while (std::getline(f, line) && iter_index < 2) { if (hasStart(line, "Xcursor.theme:")) @@ -130,35 +130,31 @@ static bool get_cursor_dconf(const std::string_view de_name, Theme::Theme_t& the #if USE_DCONF LOAD_LIBRARY("libdconf.so", return false); - LOAD_LIB_SYMBOL(DConfClient *, dconf_client_new, void); - LOAD_LIB_SYMBOL(GVariant *, dconf_client_read, DConfClient *, const char *); - LOAD_LIB_SYMBOL(const gchar *, g_variant_get_string, GVariant *, gsize *); - LOAD_LIB_SYMBOL(gint32, g_variant_get_int32, GVariant *); + LOAD_LIB_SYMBOL(DConfClient*, dconf_client_new, void); + LOAD_LIB_SYMBOL(GVariant*, dconf_client_read, DConfClient*, const char*); + LOAD_LIB_SYMBOL(const gchar*, g_variant_get_string, GVariant*, gsize*); + LOAD_LIB_SYMBOL(gint32, g_variant_get_int32, GVariant*); debug("calling {}", __PRETTY_FUNCTION__); - DConfClient *client = dconf_client_new(); - GVariant *variant; + DConfClient* client = dconf_client_new(); + GVariant* variant; std::string interface; - switch(fnv1a16::hash(str_tolower(de_name.data()))) + switch (fnv1a16::hash(str_tolower(de_name.data()))) { case "cinnamon"_fnv1a16: interface = "/org/cinnamon/desktop/interface/"; break; - case "mate"_fnv1a16: interface = "/org/mate/interface/"; break; + case "mate"_fnv1a16: interface = "/org/mate/interface/"; break; case "gnome"_fnv1a16: case "budgie"_fnv1a16: case "unity"_fnv1a16: - default: - interface = "/org/gnome/desktop/interface/"; + default: interface = "/org/gnome/desktop/interface/"; } - variant = dconf_client_read(client, (interface + "cursor-theme").c_str()); if (variant) theme.cursor = g_variant_get_string(variant, NULL); - - variant = dconf_client_read(client, (interface + "cursor-size").c_str()); if (variant) theme.cursor_size = fmt::to_string(g_variant_get_int32(variant)); @@ -177,22 +173,23 @@ static bool get_cursor_gsettings(const std::string_view de_name, Theme::Theme_t& if (config.slow_query_warnings) { - warn(_("customfetch could not detect a gtk configuration file. customfetch will use the much-slower gsettings.")); - warn(_("If there's a file in a standard location that we aren't detecting, please file an issue on our GitHub.")); + warn(_( + "customfetch could not detect a gtk configuration file. customfetch will use the much-slower gsettings.")); + warn(_( + "If there's a file in a standard location that we aren't detecting, please file an issue on our GitHub.")); info("You can disable this warning by disabling slow-query-warnings in your config.toml file."); } const char* interface; - switch(fnv1a16::hash(str_tolower(de_name.data()))) + switch (fnv1a16::hash(str_tolower(de_name.data()))) { case "cinnamon"_fnv1a16: interface = "org.cinnamon.desktop.interface"; break; - case "mate"_fnv1a16: interface = "org.mate.interface"; break; + case "mate"_fnv1a16: interface = "org.mate.interface"; break; case "gnome"_fnv1a16: case "budgie"_fnv1a16: case "unity"_fnv1a16: - default: - interface = "org.gnome.desktop.interface"; + default: interface = "org.gnome.desktop.interface"; } if (theme.cursor == MAGIC_LINE || theme.cursor.empty()) @@ -206,7 +203,8 @@ static bool get_cursor_gsettings(const std::string_view de_name, Theme::Theme_t& { theme.cursor_size.clear(); read_exec({ "gsettings", "get", interface, "cursor-size" }, theme.cursor_size); - theme.cursor_size.erase(std::remove(theme.cursor_size.begin(), theme.cursor_size.end(), '\''), theme.cursor_size.end()); + theme.cursor_size.erase(std::remove(theme.cursor_size.begin(), theme.cursor_size.end(), '\''), + theme.cursor_size.end()); } return assert_cursor(theme); @@ -218,8 +216,8 @@ static bool get_gtk_cursor_config(const std::string_view path, Theme::Theme_t& t if (!f.is_open()) return false; - std::string line; - std::uint16_t iter_index = 0; + std::string line; + std::uint16_t iter_index = 0; while (std::getline(f, line) && iter_index < 2) { if (hasStart(line, "gtk-cursor-theme-name=")) @@ -267,10 +265,10 @@ static bool get_de_cursor(const std::string_view de_name, Theme::Theme_t& theme) get_xsettings_xfce4("Gtk", "CursorThemeSize", theme.cursor_size); return assert_cursor(theme); - - } break; + } + break; } - + return false; } @@ -280,9 +278,8 @@ static bool get_de_cursor(const std::string_view de_name, Theme::Theme_t& theme) // static bool assert_gtk_theme(Theme::Theme_t& theme) { - return - (theme.gtk_font != MAGIC_LINE && theme.gtk_icon_theme != MAGIC_LINE && theme.gtk_theme_name != MAGIC_LINE) || - (!theme.gtk_font.empty() && !theme.gtk_theme_name.empty() && !theme.gtk_icon_theme.empty()); + return (theme.gtk_font != MAGIC_LINE && theme.gtk_icon_theme != MAGIC_LINE && theme.gtk_theme_name != MAGIC_LINE) || + (!theme.gtk_font.empty() && !theme.gtk_theme_name.empty() && !theme.gtk_icon_theme.empty()); } static bool get_gtk_theme_config(const std::string_view path, Theme::Theme_t& theme) @@ -291,8 +288,8 @@ static bool get_gtk_theme_config(const std::string_view path, Theme::Theme_t& th if (!f.is_open()) return false; - std::string line; - std::uint16_t iter_index = 0; + std::string line; + std::uint16_t iter_index = 0; while (std::getline(f, line) && iter_index < 3) { if (hasStart(line, "gtk-theme-name=")) @@ -313,25 +310,24 @@ static bool get_gtk_theme_dconf(const std::string_view de_name, Theme::Theme_t& #if USE_DCONF LOAD_LIBRARY("libdconf.so", return false); - LOAD_LIB_SYMBOL(DConfClient *, dconf_client_new, void); - LOAD_LIB_SYMBOL(GVariant *, dconf_client_read, DConfClient *client, const char *); - LOAD_LIB_SYMBOL(const gchar *, g_variant_get_string, GVariant *value, gsize *lenght); + LOAD_LIB_SYMBOL(DConfClient*, dconf_client_new, void); + LOAD_LIB_SYMBOL(GVariant*, dconf_client_read, DConfClient * client, const char*); + LOAD_LIB_SYMBOL(const gchar*, g_variant_get_string, GVariant* value, gsize* lenght); debug("calling {}", __PRETTY_FUNCTION__); - DConfClient *client = dconf_client_new(); - GVariant *variant; + DConfClient* client = dconf_client_new(); + GVariant* variant; std::string interface; - switch(fnv1a16::hash(str_tolower(de_name.data()))) + switch (fnv1a16::hash(str_tolower(de_name.data()))) { case "cinnamon"_fnv1a16: interface = "/org/cinnamon/desktop/interface/"; break; - case "mate"_fnv1a16: interface = "/org/mate/interface/"; break; + case "mate"_fnv1a16: interface = "/org/mate/interface/"; break; case "gnome"_fnv1a16: case "budgie"_fnv1a16: case "unity"_fnv1a16: - default: - interface = "/org/gnome/desktop/interface/"; + default: interface = "/org/gnome/desktop/interface/"; } if (theme.gtk_theme_name == MAGIC_LINE || theme.gtk_theme_name.empty()) @@ -379,22 +375,23 @@ static void get_gtk_theme_gsettings(const std::string_view de_name, Theme::Theme if (config.slow_query_warnings) { - warn(_("customfetch could not detect a gtk configuration file. customfetch will use the much-slower gsettings.")); - warn(_("If there's a file in a standard location that we aren't detecting, please file an issue on our GitHub.")); + warn(_( + "customfetch could not detect a gtk configuration file. customfetch will use the much-slower gsettings.")); + warn(_( + "If there's a file in a standard location that we aren't detecting, please file an issue on our GitHub.")); info(_("You can disable this warning by disabling slow-query-warnings in your config.toml file.")); } const char* interface; - switch(fnv1a16::hash(str_tolower(de_name.data()))) + switch (fnv1a16::hash(str_tolower(de_name.data()))) { case "cinnamon"_fnv1a16: interface = "org.cinnamon.desktop.interface"; break; - case "mate"_fnv1a16: interface = "org.mate.interface"; break; + case "mate"_fnv1a16: interface = "org.mate.interface"; break; case "gnome"_fnv1a16: case "budgie"_fnv1a16: case "unity"_fnv1a16: - default: - interface = "org.gnome.desktop.interface"; + default: interface = "org.gnome.desktop.interface"; } if (theme.gtk_theme_name == MAGIC_LINE || theme.gtk_theme_name.empty()) @@ -415,12 +412,15 @@ static void get_gtk_theme_gsettings(const std::string_view de_name, Theme::Theme read_exec({ "gsettings", "get", interface, "font-name" }, theme.gtk_font); } - theme.gtk_theme_name.erase(std::remove(theme.gtk_theme_name.begin(), theme.gtk_theme_name.end(), '\''), theme.gtk_theme_name.end()); - theme.gtk_icon_theme.erase(std::remove(theme.gtk_icon_theme.begin(), theme.gtk_icon_theme.end(), '\''), theme.gtk_icon_theme.end()); + theme.gtk_theme_name.erase(std::remove(theme.gtk_theme_name.begin(), theme.gtk_theme_name.end(), '\''), + theme.gtk_theme_name.end()); + theme.gtk_icon_theme.erase(std::remove(theme.gtk_icon_theme.begin(), theme.gtk_icon_theme.end(), '\''), + theme.gtk_icon_theme.end()); theme.gtk_font.erase(std::remove(theme.gtk_font.begin(), theme.gtk_font.end(), '\''), theme.gtk_font.end()); } -static void get_gtk_theme_from_configs(const std::uint8_t ver, const std::string_view de_name, Theme::Theme_t& theme, const Config& config) +static void get_gtk_theme_from_configs(const std::uint8_t ver, const std::string_view de_name, Theme::Theme_t& theme, + const Config& config) { if (get_gtk_theme_config(fmt::format("{}/gtk-{}.0/settings.ini", configDir, ver), theme)) return; @@ -443,7 +443,8 @@ static void get_gtk_theme_from_configs(const std::uint8_t ver, const std::string get_gtk_theme_gsettings(de_name, theme, config); } -static void get_de_gtk_theme(const std::string_view de_name, const std::uint8_t ver, Theme::Theme_t& theme, const Config& config) +static void get_de_gtk_theme(const std::string_view de_name, const std::uint8_t ver, Theme::Theme_t& theme, + const Config& config) { switch (fnv1a16::hash(str_tolower(de_name.data()))) { @@ -453,15 +454,14 @@ static void get_de_gtk_theme(const std::string_view de_name, const std::uint8_t debug("calling {} and getting info on xfce4", __PRETTY_FUNCTION__); get_xsettings_xfce4("Net", "ThemeName", theme.gtk_theme_name); get_xsettings_xfce4("Net", "IconThemeName", theme.gtk_icon_theme); - get_xsettings_xfce4("Gtk", "FontName", theme.gtk_font); + get_xsettings_xfce4("Gtk", "FontName", theme.gtk_font); if (!assert_gtk_theme(theme)) get_gtk_theme_from_configs(ver, de_name, theme, config); + } + break; - } break; - - default: - get_gtk_theme_from_configs(ver, de_name, theme, config); + default: get_gtk_theme_from_configs(ver, de_name, theme, config); } } @@ -472,7 +472,7 @@ static void get_gtk_theme(const bool dont_query_dewm, const std::uint8_t ver, co get_gtk_theme_gsettings(de_name, theme, config); else if (dont_query_dewm) get_gtk_theme_from_configs(ver, de_name, theme, config); - else + else get_de_gtk_theme(de_name, ver, theme, config); } diff --git a/src/query/linux/user.cpp b/src/query/linux/user.cpp index 32b306cc..68554e14 100644 --- a/src/query/linux/user.cpp +++ b/src/query/linux/user.cpp @@ -1,25 +1,25 @@ /* * Copyright 2025 Toni500git - * + * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ @@ -279,13 +279,11 @@ static std::string get_term_name(std::string& term_ver, const std::string_view o else if (hasStart(term_name, "gnome-terminal")) term_name.erase("gnome-terminal"_len + 1); - // let's try to get the real terminal name // on NixOS, instead of returning the -wrapped name. // tested on gnome-console, kitty, st and alacritty // hope now NixOS users will know the terminal they got, along the version if possible - if (osname.find("NixOS") != osname.npos || - (hasEnding(term_name, "wrapped") && which("nix") != UNKNOWN)) + if (osname.find("NixOS") != osname.npos || (hasEnding(term_name, "wrapped") && which("nix") != UNKNOWN)) { // /nix/store/sha256string-gnome-console-0.31.0/bin/.kgx-wrapped char buf[PATH_MAX]; @@ -386,7 +384,7 @@ static std::string get_term_version(const std::string_view term_name) if (!f.is_open()) goto skip; - std::string buffer(std::istreambuf_iterator{f}, std::istreambuf_iterator{}); + std::string buffer(std::istreambuf_iterator{ f }, std::istreambuf_iterator{}); buffer.push_back('\0'); rapidxml::xml_document<> doc; diff --git a/src/query/linux/utils/dewm.cpp b/src/query/linux/utils/dewm.cpp index 2c3626d1..6cdb3d6f 100644 --- a/src/query/linux/utils/dewm.cpp +++ b/src/query/linux/utils/dewm.cpp @@ -1,25 +1,25 @@ /* * Copyright 2025 Toni500git - * + * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ @@ -43,7 +43,6 @@ * SOFTWARE. */ - #include "dewm.hpp" #include @@ -191,7 +190,7 @@ std::string get_mate_version() return ret; } - std::string buffer(std::istreambuf_iterator{f}, std::istreambuf_iterator{}); + std::string buffer(std::istreambuf_iterator{ f }, std::istreambuf_iterator{}); buffer.push_back('\0'); rapidxml::xml_document<> doc; diff --git a/src/query/linux/utils/packages.cpp b/src/query/linux/utils/packages.cpp index d894ce76..a4607403 100644 --- a/src/query/linux/utils/packages.cpp +++ b/src/query/linux/utils/packages.cpp @@ -1,25 +1,25 @@ /* * Copyright 2025 Toni500git - * + * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ diff --git a/src/query/macos/battery.cpp b/src/query/macos/battery.cpp index c92c5273..c60f9f3a 100644 --- a/src/query/macos/battery.cpp +++ b/src/query/macos/battery.cpp @@ -1,25 +1,25 @@ /* * Copyright 2025 Toni500git - * + * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ diff --git a/src/query/macos/cpu.cpp b/src/query/macos/cpu.cpp index 7bc72ef9..323db80c 100644 --- a/src/query/macos/cpu.cpp +++ b/src/query/macos/cpu.cpp @@ -26,22 +26,23 @@ #include "platform.hpp" #if CF_MACOS -#include -#include #include #include +#include +#include + #include "query.hpp" #include "util.hpp" using namespace Query; -static bool get_sysctl(int name[2], void *ret, size_t *oldlenp) +static bool get_sysctl(int name[2], void* ret, size_t* oldlenp) { return (sysctl(name, 2, ret, oldlenp, NULL, 0) == 0); } -static bool get_sysctl(const char *name, void *ret, size_t *oldlenp) +static bool get_sysctl(const char* name, void* ret, size_t* oldlenp) { return (sysctlbyname(name, ret, oldlenp, NULL, 0) == 0); } @@ -50,7 +51,7 @@ static CPU::CPU_t get_cpu_infos() { CPU::CPU_t ret; debug("calling in CPU {}", __PRETTY_FUNCTION__); - char buf[1024]; + char buf[1024]; size_t len = sizeof(buf); get_sysctl("machdep.cpu.brand_string", &buf, &len); @@ -66,7 +67,7 @@ static CPU::CPU_t get_cpu_infos() ret.nproc = buf; uint64_t freq_cur = 0, freq_max = 0, freq_min; - size_t length = sizeof(freq_cur); + size_t length = sizeof(freq_cur); get_sysctl("hw.cpufrequency_max", &freq_max, &length); get_sysctl("hw.cpufrequency_min", &freq_min, &length); diff --git a/src/query/macos/disk.cpp b/src/query/macos/disk.cpp index 0b52974c..3a6dcec8 100644 --- a/src/query/macos/disk.cpp +++ b/src/query/macos/disk.cpp @@ -1,34 +1,35 @@ /* * Copyright 2025 Toni500git - * + * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #include "platform.hpp" #if CF_MACOS -#include #include +#include + #include "query.hpp" #include "util.hpp" @@ -65,8 +66,7 @@ static int get_disk_type(const int flags) return type; } -Disk::Disk(const std::string& path, systemInfo_t& queried_paths, parse_args_t& parse_args, - const bool auto_module) +Disk::Disk(const std::string& path, systemInfo_t& queried_paths, parse_args_t& parse_args, const bool auto_module) { if (queried_paths.find(path) != queried_paths.end() && !is_live_mode) { @@ -83,8 +83,8 @@ Disk::Disk(const std::string& path, systemInfo_t& queried_paths, parse_args_t& p { // if user is using $ or $ // then let's just "try" to remove it - m_disk_infos.typefs = MAGIC_LINE; - m_disk_infos.device = MAGIC_LINE; + m_disk_infos.typefs = MAGIC_LINE; + m_disk_infos.device = MAGIC_LINE; m_disk_infos.mountdir = MAGIC_LINE; return; } @@ -92,11 +92,11 @@ Disk::Disk(const std::string& path, systemInfo_t& queried_paths, parse_args_t& p if (auto_module) { const int size = getfsstat(NULL, 0, MNT_WAIT); - if (size <= 0) + if (size <= 0) die(_("Failed to get Disk infos")); struct statfs* buf = reinterpret_cast(malloc(sizeof(*buf) * (unsigned)size)); - if (getfsstat(buf, (int) (sizeof(*buf) * (unsigned) size), MNT_NOWAIT) <= 0) + if (getfsstat(buf, (int)(sizeof(*buf) * (unsigned)size), MNT_NOWAIT) <= 0) die(_("Failed to get Disk infos")); for (struct statfs* fs = buf; fs < buf + size; ++fs) @@ -119,8 +119,7 @@ Disk::Disk(const std::string& path, systemInfo_t& queried_paths, parse_args_t& p parse_args.no_more_reset = false; m_disks_formats.push_back( - parse(format_auto_query_string(parse_args.config.auto_disks_fmt, fs), parse_args) - ); + parse(format_auto_query_string(parse_args.config.auto_disks_fmt, fs), parse_args)); } free(buf); @@ -138,24 +137,21 @@ Disk::Disk(const std::string& path, systemInfo_t& queried_paths, parse_args_t& p if (path != fs.f_mntonname && path != fs.f_mntfromname) return; - m_disk_infos.typefs = fs.f_fstypename; - m_disk_infos.device = fs.f_mntfromname; - m_disk_infos.mountdir = fs.f_mntonname; + m_disk_infos.typefs = fs.f_fstypename; + m_disk_infos.device = fs.f_mntfromname; + m_disk_infos.mountdir = fs.f_mntonname; - m_disk_infos.total_amount = static_cast(fs.f_blocks * fs.f_bsize); - m_disk_infos.free_amount = static_cast(fs.f_bfree * fs.f_bsize); + m_disk_infos.total_amount = static_cast(fs.f_blocks * fs.f_bsize); + m_disk_infos.free_amount = static_cast(fs.f_bfree * fs.f_bsize); m_disk_infos.used_amount = m_disk_infos.total_amount - m_disk_infos.free_amount; - queried_paths.insert( - {path, { - {"total_amount", variant(m_disk_infos.total_amount)}, - {"used_amount", variant(m_disk_infos.used_amount)}, - {"free_amount", variant(m_disk_infos.free_amount)}, - {"typefs", variant(m_disk_infos.typefs)}, - {"mountdir", variant(m_disk_infos.mountdir)}, - {"device", variant(m_disk_infos.device)} - }} - ); + queried_paths.insert({ path, + { { "total_amount", variant(m_disk_infos.total_amount) }, + { "used_amount", variant(m_disk_infos.used_amount) }, + { "free_amount", variant(m_disk_infos.free_amount) }, + { "typefs", variant(m_disk_infos.typefs) }, + { "mountdir", variant(m_disk_infos.mountdir) }, + { "device", variant(m_disk_infos.device) } } }); } // clang-format off diff --git a/src/query/macos/gpu.cpp b/src/query/macos/gpu.cpp index c7d79c2e..87344fa5 100644 --- a/src/query/macos/gpu.cpp +++ b/src/query/macos/gpu.cpp @@ -30,9 +30,7 @@ using namespace Query; -GPU::GPU(const std::string& id, systemInfo_t& queried_gpus) -{ -} +GPU::GPU(const std::string& id, systemInfo_t& queried_gpus) {} // clang-format off std::string& GPU::name() noexcept diff --git a/src/query/macos/ram.cpp b/src/query/macos/ram.cpp index 4e901ae5..9a3376fe 100644 --- a/src/query/macos/ram.cpp +++ b/src/query/macos/ram.cpp @@ -1,36 +1,37 @@ /* * Copyright 2025 Toni500git - * + * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #include "platform.hpp" #if CF_MACOS -#include #include #include #include +#include + #include "query.hpp" #include "util.hpp" @@ -40,9 +41,9 @@ using namespace Query; static RAM::RAM_t get_amount() { RAM::RAM_t ret; - uint64_t total = 0, used = 0, page_size = 0; - int name[2] = { CTL_HW, HW_MEMSIZE }; - size_t length = sizeof(total); + uint64_t total = 0, used = 0, page_size = 0; + int name[2] = { CTL_HW, HW_MEMSIZE }; + size_t length = sizeof(total); if (sysctl(name, 2, &total, &length, NULL, 0)) die(_("Failed to get RAM infos")); @@ -51,7 +52,7 @@ static RAM::RAM_t get_amount() sysctl(name, 2, &page_size, &length, NULL, 0); mach_msg_type_number_t count = HOST_VM_INFO64_COUNT; vm_statistics64_data_t vmstat; - if(host_statistics64(mach_host_self(), HOST_VM_INFO64, (host_info64_t) (&vmstat), &count) != KERN_SUCCESS) + if (host_statistics64(mach_host_self(), HOST_VM_INFO64, (host_info64_t)(&vmstat), &count) != KERN_SUCCESS) die(_("Failed to read host_statistics64")); // https://github.com/exelban/stats/blob/master/Modules/RAM/readers.swift#L56 @@ -66,21 +67,21 @@ static RAM::RAM_t get_amount() ) * page_size; ret.total_amount = static_cast(total) / 1024; - ret.used_amount = static_cast(used) / 1024; + ret.used_amount = static_cast(used) / 1024; // I have just now saw fastfetch doesn't have a way to know free memory // why?? ret.free_amount = ret.total_amount - ret.used_amount; struct xsw_usage xsw; - length = sizeof(xsw); + length = sizeof(xsw); name[0] = CTL_VM; name[1] = VM_SWAPUSAGE; - if(sysctl(name, 2, &xsw, &length, NULL, 0) != 0) + if (sysctl(name, 2, &xsw, &length, NULL, 0) != 0) return ret; ret.swap_total_amount = static_cast(xsw.xsu_total); - ret.swap_used_amount = static_cast(xsw.xsu_used); - ret.swap_free_amount = static_cast(xsw.xsu_avail); + ret.swap_used_amount = static_cast(xsw.xsu_used); + ret.swap_free_amount = static_cast(xsw.xsu_avail); return ret; } @@ -88,7 +89,7 @@ static RAM::RAM_t get_amount() RAM::RAM() noexcept { CHECK_INIT(m_bInit); - + m_memory_infos = get_amount(); } diff --git a/src/query/macos/system.cpp b/src/query/macos/system.cpp index 48dc97c6..36e6739b 100644 --- a/src/query/macos/system.cpp +++ b/src/query/macos/system.cpp @@ -1,25 +1,25 @@ /* * Copyright 2025 Toni500git - * + * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ @@ -31,24 +31,24 @@ #include -#include "util.hpp" #include "query.hpp" #include "rapidxml-1.13/rapidxml.hpp" #include "switch_fnv1a.hpp" +#include "util.hpp" using namespace Query; static std::string get_codename(const std::string_view os_version_id) { std::string major; - std::string minor{UNKNOWN}; - size_t pos1 = os_version_id.find('.'); + std::string minor{ UNKNOWN }; + size_t pos1 = os_version_id.find('.'); if (pos1 != os_version_id.npos) { - major = os_version_id.substr(0, pos1); - size_t pos2 = os_version_id.find('.', pos1+1); + major = os_version_id.substr(0, pos1); + size_t pos2 = os_version_id.find('.', pos1 + 1); if (pos2 != os_version_id.npos) - minor = os_version_id.substr(pos1+1, pos2); + minor = os_version_id.substr(pos1 + 1, pos2); } switch (fnv1a16::hash(major)) @@ -69,16 +69,16 @@ static std::string get_codename(const std::string_view os_version_id) case "12"_fnv1a16: return "Sierra"; case "11"_fnv1a16: return "El Capitan"; case "10"_fnv1a16: return "Yosemite"; - case "9"_fnv1a16: return "Mavericks"; - case "8"_fnv1a16: return "Mountain Lion"; - case "7"_fnv1a16: return "Lion"; - case "6"_fnv1a16: return "Snow Leopard"; - case "5"_fnv1a16: return "Leopard"; - case "4"_fnv1a16: return "Tiger"; - case "3"_fnv1a16: return "Panther"; - case "2"_fnv1a16: return "Jaguar"; - case "1"_fnv1a16: return "Puma"; - case "0"_fnv1a16: return "Cheetah"; + case "9"_fnv1a16: return "Mavericks"; + case "8"_fnv1a16: return "Mountain Lion"; + case "7"_fnv1a16: return "Lion"; + case "6"_fnv1a16: return "Snow Leopard"; + case "5"_fnv1a16: return "Leopard"; + case "4"_fnv1a16: return "Tiger"; + case "3"_fnv1a16: return "Panther"; + case "2"_fnv1a16: return "Jaguar"; + case "1"_fnv1a16: return "Puma"; + case "0"_fnv1a16: return "Cheetah"; } } } @@ -89,11 +89,11 @@ static std::string get_codename(const std::string_view os_version_id) static System::System_t get_os_infos() { System::System_t ret; - std::ifstream f("/System/Library/CoreServices/SystemVersion.plist", std::ios::in); + std::ifstream f("/System/Library/CoreServices/SystemVersion.plist", std::ios::in); if (!f.is_open()) die("Couldn't get MacOS base infos"); - std::string buffer(std::istreambuf_iterator{f}, std::istreambuf_iterator{}); + std::string buffer(std::istreambuf_iterator{ f }, std::istreambuf_iterator{}); buffer.push_back('\0'); rapidxml::xml_document<> doc; @@ -102,9 +102,9 @@ static System::System_t get_os_infos() for (; root_node; root_node = root_node->next_sibling()) { - const std::string_view key = root_node->value(); // ProductName - root_node = root_node->next_sibling(); - const std::string_view value = root_node->value(); // macOS + const std::string_view key = root_node->value(); // ProductName + root_node = root_node->next_sibling(); + const std::string_view value = root_node->value(); // macOS if (key == "ProductName") ret.os_name = value; else if (key == "ProductUserVisibleVersion") @@ -127,12 +127,12 @@ System::System() die(_("uname() failed: {}\nCould not get system infos"), strerror(errno)); struct timeval boot_time; - size_t size = sizeof(boot_time); - int name[] = {CTL_KERN, KERN_BOOTTIME}; - if(sysctl(name, 2, &boot_time, &size, NULL, 0) != 0) + size_t size = sizeof(boot_time); + int name[] = { CTL_KERN, KERN_BOOTTIME }; + if (sysctl(name, 2, &boot_time, &size, NULL, 0) != 0) die(_("failed to get uptime")); - m_uptime = time(NULL) - boot_time.tv_sec; + m_uptime = time(NULL) - boot_time.tv_sec; m_system_infos = get_os_infos(); } diff --git a/src/query/macos/theme.cpp b/src/query/macos/theme.cpp index b3be51ae..534bed5e 100644 --- a/src/query/macos/theme.cpp +++ b/src/query/macos/theme.cpp @@ -33,16 +33,17 @@ using namespace Query; Theme::Theme(const std::uint8_t ver, systemInfo_t& queried_themes, const std::string& theme_name_version, const Config& config, const bool gsettings_only) - : m_queried_themes(queried_themes) + : m_queried_themes(queried_themes) { - m_theme_infos.cursor = m_theme_infos.gtk_font = m_theme_infos.cursor_size = m_theme_infos.gtk_theme_name = m_theme_infos.gtk_icon_theme - = MAGIC_LINE; + m_theme_infos.cursor = m_theme_infos.gtk_font = m_theme_infos.cursor_size = m_theme_infos.gtk_theme_name = + m_theme_infos.gtk_icon_theme = MAGIC_LINE; } -Theme::Theme(systemInfo_t& queried_themes, const Config& config, const bool gsettings_only) : m_queried_themes(queried_themes) +Theme::Theme(systemInfo_t& queried_themes, const Config& config, const bool gsettings_only) + : m_queried_themes(queried_themes) { - m_theme_infos.cursor = m_theme_infos.gtk_font = m_theme_infos.cursor_size = m_theme_infos.gtk_theme_name = m_theme_infos.gtk_icon_theme - = MAGIC_LINE; + m_theme_infos.cursor = m_theme_infos.gtk_font = m_theme_infos.cursor_size = m_theme_infos.gtk_theme_name = + m_theme_infos.gtk_icon_theme = MAGIC_LINE; } // clang-format off diff --git a/src/util.cpp b/src/util.cpp index 241e14a7..f8d379ff 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -1,25 +1,25 @@ /* * Copyright 2025 Toni500git - * + * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ @@ -133,7 +133,7 @@ std::string read_by_syspath(const std::string_view path, bool report_error) std::string result; std::getline(f, result); - + if (!result.empty() && result.back() == '\n') result.pop_back(); @@ -209,7 +209,7 @@ bool is_file_image(const unsigned char* bytes) void strip(std::string& input, bool padding_only) { - if (input.empty()) + if (input.empty()) return; if (padding_only) @@ -220,12 +220,8 @@ void strip(std::string& input, bool padding_only) } else { - input.erase( - std::remove_if(input.begin(), input.end(), - [](unsigned char c) { return std::isspace(c); } - ), - input.end() - ); + input.erase(std::remove_if(input.begin(), input.end(), [](unsigned char c) { return std::isspace(c); }), + input.end()); } } @@ -547,11 +543,9 @@ std::string binarySearchPCIArray(const std::string_view vendor_id_s) std::string read_shell_exec(const std::string_view cmd) { - std::array buffer; - std::string result; - std::unique_ptr pipe(popen(cmd.data(), "r"), - [](FILE *f) -> void - { + std::array buffer; + std::string result; + std::unique_ptr pipe(popen(cmd.data(), "r"), [](FILE* f) -> void { // wrapper to ignore the return value from pclose(). // Is needed with newer versions of gnu g++ std::ignore = pclose(f); From f19a37e8aeebc65f27271942f37b710412b08b49 Mon Sep 17 00:00:00 2001 From: Toni500git Date: Fri, 20 Jun 2025 00:43:55 +0200 Subject: [PATCH 005/143] misc: just create the directories --- src/main.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 8fe32d4f..be64b6d8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -792,9 +792,10 @@ int main(int argc, char *argv[]) /* TODO(burntranch): track each library and unload them. */ const std::filesystem::path modDir = configDir / "mods"; - for (const auto& entry : std::filesystem::directory_iterator(modDir)) + std::filesystem::create_directories(modDir); + for (const auto& entry : std::filesystem::directory_iterator{modDir}) { - fmt::println("loading mod at {}!", entry.path().string()); + info("loading mod at {}!", entry.path().string()); LOAD_LIBRARY(std::filesystem::absolute(entry.path()).c_str(), warn("Failed to load mod {}!", entry.path().string())) @@ -813,7 +814,7 @@ int main(int argc, char *argv[]) const std::vector& modules = cfGetModules(); moduleMap_t moduleMap; - fmt::println("modules count: {}", modules.size()); + info("modules count: {}", modules.size()); for (const module_t& module : modules) { if (!module.handler) From c91f5cd25ea0e0c24f17ba97625810d3f9294e3a Mon Sep 17 00:00:00 2001 From: BurntRanch <69512353+BurntRanch@users.noreply.github.com> Date: Fri, 20 Jun 2025 02:00:21 +0300 Subject: [PATCH 006/143] examples: add mod-library example --- examples/mod-library.cc | 77 +++++++++++++++++++++++++++++++++++++++++ src/main.cpp | 8 +++-- 2 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 examples/mod-library.cc diff --git a/examples/mod-library.cc b/examples/mod-library.cc new file mode 100644 index 00000000..350a3dcb --- /dev/null +++ b/examples/mod-library.cc @@ -0,0 +1,77 @@ +/* This is an example for a mod you could install in .config/mods + +Mods are essentially custom(fetch) modules that you can implement yourself and register using libcufetch! +They are to be compiled as shared libraries **with no name mangling!!**, with one start function. Scroll down for more details on the start function. + +To compile this, just run `g++ -shared -fPIC mod-library.cc -o mod-library.so`. To use it, you'll need to put it in your customfetch/mods config directory. +*/ + +#include +#include +#include +#include +#include + +/* ret_type = type of what the function returns + * func = the function name + * ... = the arguments in a function if any + */ +#define LOAD_LIB_SYMBOL(ret_type, func, ...) \ + typedef ret_type (*func##_t)(__VA_ARGS__); \ + func##_t func = reinterpret_cast(dlsym(handle, #func)); + +#define UNLOAD_LIBRARY() dlclose(handle); + +/* ideally you'd import the right header file, I'm putting this here because I want this to be "separated" from customfetch. */ +struct module_t { + std::string name; + std::vector submodules; /* For best performance, use std::move() when adding modules in here. */ + std::function handler; + + module_t(const std::string &name, const std::vector &submodules, const std::function handler) : name(name), submodules(submodules), handler(handler) { + + } +}; + +/* The handler that we'll use for our module, Handlers return const std::string (WILL be changed to const char pointers). */ +const std::string test() { + return "Hello!"; +} + +/* Start function. + +When writing in C++, you MUST put the extern "C" part in the beginning to avoid name mangling. +customfetch will look for a "start" function, but if your compiler mangles the names it will not be able to find it. + +The start function takes in a handle, This handle is going to be the libcufetch library. +You'll need to use dlsym on this handle to get the functions necessary for whatever you're doing. (e.g. cfRegisterModule) + +*/ +extern "C" void start(void *handle) { + if (!handle) { + std::cout << "Exiting because !handle" << std::endl; + return; + } + + /* Load cfRegisterModule, you don't need this macro but it's nice! */ + LOAD_LIB_SYMBOL(void, cfRegisterModule, const module_t &module); + + /* Our goal in this example is to create a `modification.test` module, This will just return "Hello!" and nothing else. */ + /* The way we'll do this is we will create the test module, with no submodules and a handler (that just returns "Hello!"). */ + /* But then we will also create the modification module, which won't do anything other than hold the test module as a submodule. */ + /* We will then register the modification module. We won't register the test module because it is already a submodule and will be implicitly added. */ + + /* Here we create the 'test' submodule. in customfetch there's no practical difference between a parent module and a submodule. So we just define it like any other module. */ + /* We will not register this, it will be implicitly added through its parent module (so we can't directly invoke `test`, we can only invoke `modification.test`) */ + module_t test_module = {"test", {}, test}; + + /* And here we create the 'modification' module. This is what we're actually going to register and it will include the test module as a submodule. */ + /* This module doesn't have a handler, so it can't be used in the config (`modification` won't work). We'll instead use `modification.test` to invoke the test module (which does have a handler). */ + module_t modification_module = { "modification", { std::move(test_module) }, NULL }; + + /* Register the module. */ + /* This will take the modification module, recursively add it and its submodules to the list, and continue until its finished everything. */ + cfRegisterModule(modification_module); + + /* And done, after this customfetch will call our handler whenever our test module is invoked. */ +} diff --git a/src/main.cpp b/src/main.cpp index be64b6d8..dfa5e342 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -795,7 +795,7 @@ int main(int argc, char *argv[]) std::filesystem::create_directories(modDir); for (const auto& entry : std::filesystem::directory_iterator{modDir}) { - info("loading mod at {}!", entry.path().string()); + debug("loading mod at {}!", entry.path().string()); LOAD_LIBRARY(std::filesystem::absolute(entry.path()).c_str(), warn("Failed to load mod {}!", entry.path().string())) @@ -814,9 +814,10 @@ int main(int argc, char *argv[]) const std::vector& modules = cfGetModules(); moduleMap_t moduleMap; - info("modules count: {}", modules.size()); + debug("modules count: {}", modules.size()); for (const module_t& module : modules) { + debug("adding module {} (has handler: {})", module.name, module.handler != NULL); if (!module.handler) continue; @@ -896,5 +897,8 @@ int main(int argc, char *argv[]) if (!config.wrap_lines) enable_cursor(); + handle = cufetch_handle; + UNLOAD_LIBRARY(); + return 0; } From 73c3cbedb239ccb62d0d0c47e7351f19a35651f4 Mon Sep 17 00:00:00 2001 From: BurntRanch <69512353+BurntRanch@users.noreply.github.com> Date: Fri, 20 Jun 2025 15:44:51 +0300 Subject: [PATCH 007/143] plugins: implement system.host, and system.host.name (formerly system.host_name). --- Makefile | 12 +++- core-plugins/Makefile | 14 ++++ core-plugins/linux/system.cc | 120 +++++++++++++++++++++++++++++++++ examples/mod-library.cc | 17 ++--- include/common.hpp | 74 ++++++++++++++++++++ include/query.hpp | 14 +--- include/util.hpp | 55 +-------------- src/libs/cufetch/Makefile | 2 +- src/libs/cufetch/cufetch.cc | 5 +- src/query/linux/utils/dewm.cpp | 1 + src/util.cpp | 1 + 11 files changed, 230 insertions(+), 85 deletions(-) create mode 100644 core-plugins/Makefile create mode 100644 core-plugins/linux/system.cc create mode 100644 include/common.hpp diff --git a/Makefile b/Makefile index d779b3a0..01740bcf 100644 --- a/Makefile +++ b/Makefile @@ -62,7 +62,7 @@ LDFLAGS += -L./$(BUILDDIR)/fmt -lfmt -ldl CXXFLAGS ?= -mtune=generic -march=native CXXFLAGS += -fvisibility=hidden -Iinclude -std=c++20 $(VARS) -DVERSION=\"$(VERSION)\" -DLOCALEDIR=\"$(LOCALEDIR)\" -DICONPREFIX=\"$(ICONPREFIX)\" -all: genver libcufetch fmt toml json $(TARGET) +all: genver libcufetch fmt toml json core-plugins $(TARGET) libcufetch: ifeq ($(wildcard $(BUILDDIR)/libcufetch/libcufetch.so),) @@ -88,12 +88,18 @@ ifeq ($(wildcard $(BUILDDIR)/json/json.o),) make -C src/libs/json BUILDDIR=$(BUILDDIR)/json endif +core-plugins: +ifeq ($(wildcard $(BUILDDIR)/core-plugins/*.so),) + mkdir -p $(BUILDDIR)/core-plugins + make -C core-plugins BUILDDIR=$(BUILDDIR)/core-plugins +endif + genver: ./scripts/generateVersion.sh ifeq ($(wildcard include/version.h),) ./scripts/generateVersion.sh endif -$(TARGET): genver fmt toml libcufetch json $(OBJ) +$(TARGET): genver fmt toml libcufetch json core-plugins $(OBJ) mkdir -p $(BUILDDIR) sh ./scripts/generateVersion.sh $(CXX) $(OBJ) $(BUILDDIR)/toml++/toml.o $(BUILDDIR)/json/json.o -o $(BUILDDIR)/$(TARGET) $(LDFLAGS) @@ -158,4 +164,4 @@ updatever: sed -i "s#$(OLDVERSION)#$(VERSION)#g" $(wildcard .github/workflows/*.yml) compile_flags.txt sed -i "s#Project-Id-Version: $(NAME) $(OLDVERSION)#Project-Id-Version: $(NAME) $(VERSION)#g" po/* -.PHONY: $(TARGET) updatever remove uninstall delete dist distclean fmt toml install all locale +.PHONY: $(TARGET) updatever remove uninstall delete dist distclean fmt toml libcufetch core-plugins install all locale diff --git a/core-plugins/Makefile b/core-plugins/Makefile new file mode 100644 index 00000000..82fa2069 --- /dev/null +++ b/core-plugins/Makefile @@ -0,0 +1,14 @@ +CXX ?= g++ +CXX_INCLUDES = -I../include +CXX_FLAGS = -shared -fPIC + +all: linux-system + +linux-system: linux/system.cc + $(CXX) $(CXX_INCLUDES) $(CXX_FLAGS) linux/system.cc -o linux-system-mod.so + mv -f linux-system-mod.so ../$(BUILDDIR)/linux-system-mod.so + +clean: + rm -f *.o *.so *.a ../$(BUILDDIR)/core-plugin/.*so + +.PHONY: clean all cufetch diff --git a/core-plugins/linux/system.cc b/core-plugins/linux/system.cc new file mode 100644 index 00000000..b2f03406 --- /dev/null +++ b/core-plugins/linux/system.cc @@ -0,0 +1,120 @@ +/* This is an example for a mod you could install in .config/mods + +Mods are essentially custom(fetch) modules that you can implement yourself and register using libcufetch! +They are to be compiled as shared libraries **with no name mangling!!**, with one start function. Scroll down for more details on the start function. + +To compile this, just run `g++ -I../include -shared -fPIC mod-library.cc -o mod-library.so`. To use it, you'll need to put it in your customfetch/mods config directory. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common.hpp" + +#define BOLD_COLOR(x) (fmt::emphasis::bold | fmt::fg(x)) + +/* ret_type = type of what the function returns + * func = the function name + * ... = the arguments in a function if any + */ +#define LOAD_LIB_SYMBOL(ret_type, func, ...) \ + typedef ret_type (*func##_t)(__VA_ARGS__); \ + func##_t func = reinterpret_cast(dlsym(handle, #func)); + +#define UNLOAD_LIBRARY() dlclose(handle); + +std::string read_by_syspath(const std::string_view path) +{ + std::ifstream f(path.data()); + if (!f.is_open()) + { + error(_("Failed to open {}"), path); + + return "(unknown)"; + } + + std::string result; + std::getline(f, result); + + if (!result.empty() && result.back() == '\n') + result.pop_back(); + + return result; +} + +/* The handler that we'll use for our module, Handlers return const std::string (WILL be changed to const char pointers). */ +const std::string host() { + const std::string syspath = "/sys/devices/virtual/dmi/id"; + + std::string board_name; + std::string board_version; + std::string board_vendor; + + if (std::filesystem::exists(syspath + "/board_name")) + { + board_name = read_by_syspath(syspath + "/board_name"); + board_version = read_by_syspath(syspath + "/board_version"); + board_vendor = read_by_syspath(syspath + "/board_vendor"); + + if (board_vendor == "Micro-Star International Co., Ltd.") + board_vendor = "MSI"; + } + else if (std::filesystem::exists(syspath + "/product_name")) + { + board_name = read_by_syspath(syspath + "/product_name"); + + static constexpr std::string_view standard_pc_name = "Standard PC"; + if (board_name.substr(0, standard_pc_name.size()) == standard_pc_name) + { + // everyone does it like "KVM/QEMU Standard PC (...) (host_version)" so why not + board_vendor = "KVM/QEMU"; + board_version = std::string_view('(' + read_by_syspath(syspath + "/product_version") + ')').data(); + } + else + board_version = read_by_syspath(syspath + "/product_version"); + } + + return board_vendor + ' ' + board_name + ' ' + board_version; +} + +const std::string host_name() { + const std::string syspath = "/sys/devices/virtual/dmi/id"; + + std::string board_name; + + if (std::filesystem::exists(syspath + "/board_name")) + { + board_name = read_by_syspath(syspath + "/board_name"); + } + else if (std::filesystem::exists(syspath + "/product_name")) + { + board_name = read_by_syspath(syspath + "/product_name"); + } + + return board_name; +} + +extern "C" void start(void *handle) { + if (!handle) { + std::cout << "Exiting because !handle" << std::endl; + return; + } + + LOAD_LIB_SYMBOL(void, cfRegisterModule, const module_t &module); + + module_t host_name_module = {"name", {}, host_name}; + module_t host_module = {"host", { std::move(host_name_module) }, host}; + + /* Only for compatibility */ + module_t host_name_module_compat = { "host_name", {}, host_name }; + + module_t system_module = { "system", { std::move(host_module), std::move(host_name_module_compat) }, NULL }; + + cfRegisterModule(system_module); +} diff --git a/examples/mod-library.cc b/examples/mod-library.cc index 350a3dcb..6d02683e 100644 --- a/examples/mod-library.cc +++ b/examples/mod-library.cc @@ -3,7 +3,7 @@ Mods are essentially custom(fetch) modules that you can implement yourself and register using libcufetch! They are to be compiled as shared libraries **with no name mangling!!**, with one start function. Scroll down for more details on the start function. -To compile this, just run `g++ -shared -fPIC mod-library.cc -o mod-library.so`. To use it, you'll need to put it in your customfetch/mods config directory. +To compile this, just run `g++ -I../include -shared -fPIC mod-library.cc -o mod-library.so`. To use it, you'll need to put it in your customfetch/mods config directory. */ #include @@ -12,6 +12,8 @@ To compile this, just run `g++ -shared -fPIC mod-library.cc -o mod-library.so`. #include #include +#include "common.hpp" + /* ret_type = type of what the function returns * func = the function name * ... = the arguments in a function if any @@ -22,17 +24,6 @@ To compile this, just run `g++ -shared -fPIC mod-library.cc -o mod-library.so`. #define UNLOAD_LIBRARY() dlclose(handle); -/* ideally you'd import the right header file, I'm putting this here because I want this to be "separated" from customfetch. */ -struct module_t { - std::string name; - std::vector submodules; /* For best performance, use std::move() when adding modules in here. */ - std::function handler; - - module_t(const std::string &name, const std::vector &submodules, const std::function handler) : name(name), submodules(submodules), handler(handler) { - - } -}; - /* The handler that we'll use for our module, Handlers return const std::string (WILL be changed to const char pointers). */ const std::string test() { return "Hello!"; @@ -66,7 +57,7 @@ extern "C" void start(void *handle) { module_t test_module = {"test", {}, test}; /* And here we create the 'modification' module. This is what we're actually going to register and it will include the test module as a submodule. */ - /* This module doesn't have a handler, so it can't be used in the config (`modification` won't work). We'll instead use `modification.test` to invoke the test module (which does have a handler). */ + /* This module doesn't have a handler, so it can't be used in the config (`modification` won't work). We'll instead use `modification.test` in the config (which does have a handler). */ module_t modification_module = { "modification", { std::move(test_module) }, NULL }; /* Register the module. */ diff --git a/include/common.hpp b/include/common.hpp new file mode 100644 index 00000000..3b1bf6e4 --- /dev/null +++ b/include/common.hpp @@ -0,0 +1,74 @@ +#pragma once + +#include +#include +#include +#include +#include + +#if ENABLE_NLS && !CF_MACOS +/* here so it doesn't need to be included elsewhere */ +#include +#include +#define _(str) gettext(str) +#else +#define _(s) (char*)s +#endif + +#define BOLD_COLOR(x) (fmt::emphasis::bold | fmt::fg(x)) + +template +void error(const std::string_view fmt, Args&&... args) noexcept +{ + fmt::print(stderr, BOLD_COLOR(fmt::rgb(fmt::color::red)), "ERROR: {}\033[0m\n", + fmt::format(fmt::runtime(fmt), std::forward(args)...)); +} + +template +void die(const std::string_view fmt, Args&&... args) noexcept +{ + fmt::print(stderr, BOLD_COLOR(fmt::rgb(fmt::color::red)), "FATAL: {}\033[0m\n", + fmt::format(fmt::runtime(fmt), std::forward(args)...)); + std::exit(1); +} + +#if DEBUG +inline bool debug_print = true; +#else +inline bool debug_print = false; +#endif + +template +void debug(const std::string_view fmt, Args&&... args) noexcept +{ + if (debug_print) + fmt::print(BOLD_COLOR((fmt::rgb(fmt::color::hot_pink))), "[DEBUG]:\033[0m {}\n", + fmt::format(fmt::runtime(fmt), std::forward(args)...)); +} + +template +void warn(const std::string_view fmt, Args&&... args) noexcept +{ + fmt::print(BOLD_COLOR((fmt::rgb(fmt::color::yellow))), "WARNING: {}\033[0m\n", + fmt::format(fmt::runtime(fmt), std::forward(args)...)); +} + +template +void info(const std::string_view fmt, Args&&... args) noexcept +{ + fmt::print(BOLD_COLOR((fmt::rgb(fmt::color::cyan))), "INFO: {}\033[0m\n", + fmt::format(fmt::runtime(fmt), std::forward(args)...)); +} + +struct module_t +{ + std::string name; + std::vector submodules; /* For best performance, use std::move() when adding modules in here. */ + std::function handler; + + module_t(const std::string& name, const std::vector& submodules, + const std::function handler) + : name(name), submodules(submodules), handler(handler) + { + } +}; diff --git a/include/query.hpp b/include/query.hpp index 5ff25ea8..3d1abbf6 100644 --- a/include/query.hpp +++ b/include/query.hpp @@ -37,6 +37,7 @@ #include "config.hpp" #include "util.hpp" +#include "common.hpp" extern "C" { #if !CF_MACOS @@ -53,19 +54,6 @@ extern "C" { #include } -struct module_t -{ - std::string name; - std::vector submodules; /* For best performance, use std::move() when adding modules in here. */ - std::function handler; - - module_t(const std::string& name, const std::vector& submodules, - const std::function handler) - : name(name), submodules(submodules), handler(handler) - { - } -}; - struct parse_args_t; // Map from a modules name to its pointer. diff --git a/include/util.hpp b/include/util.hpp index 3a563a44..94d183d5 100644 --- a/include/util.hpp +++ b/include/util.hpp @@ -39,6 +39,7 @@ #include "fmt/base.h" #include "fmt/color.h" #include "platform.hpp" +#include "common.hpp" // clang-format off // Get string literal length @@ -54,15 +55,6 @@ struct byte_units_t double num_bytes; }; -#if ENABLE_NLS && !CF_MACOS -/* here so it doesn't need to be included elsewhere */ -#include -#include -#define _(str) gettext(str) -#else -#define _(s) (char*)s -#endif - constexpr const char NOCOLOR[] = "\033[0m"; constexpr const char NOCOLOR_BOLD[] = "\033[0m\033[1m"; constexpr const char UNKNOWN[] = "(unknown)"; @@ -93,8 +85,6 @@ constexpr const char MAGIC_LINE[] = "(cut this line NOW!! RAHHH)"; #define UNLOAD_LIBRARY() dlclose(handle); -#define BOLD_COLOR(x) (fmt::emphasis::bold | fmt::fg(x)) - /* https://stackoverflow.com/questions/874134/find-out-if-string-ends-with-another-string-in-c#874160 * Check if substring exists at the end * @param fullString The string to lookup @@ -304,49 +294,6 @@ std::filesystem::path getConfigDir(); std::string get_android_property(const std::string_view name); #endif -template -void error(const std::string_view fmt, Args&&... args) noexcept -{ - fmt::print(stderr, BOLD_COLOR(fmt::rgb(fmt::color::red)), "ERROR: {}\033[0m\n", - fmt::format(fmt::runtime(fmt), std::forward(args)...)); -} - -template -void die(const std::string_view fmt, Args&&... args) noexcept -{ - fmt::print(stderr, BOLD_COLOR(fmt::rgb(fmt::color::red)), "FATAL: {}\033[0m\n", - fmt::format(fmt::runtime(fmt), std::forward(args)...)); - std::exit(1); -} - -#if DEBUG -inline bool debug_print = true; -#else -inline bool debug_print = false; -#endif - -template -void debug(const std::string_view fmt, Args&&... args) noexcept -{ - if (debug_print) - fmt::print(BOLD_COLOR((fmt::rgb(fmt::color::hot_pink))), "[DEBUG]:\033[0m {}\n", - fmt::format(fmt::runtime(fmt), std::forward(args)...)); -} - -template -void warn(const std::string_view fmt, Args&&... args) noexcept -{ - fmt::print(BOLD_COLOR((fmt::rgb(fmt::color::yellow))), "WARNING: {}\033[0m\n", - fmt::format(fmt::runtime(fmt), std::forward(args)...)); -} - -template -void info(const std::string_view fmt, Args&&... args) noexcept -{ - fmt::print(BOLD_COLOR((fmt::rgb(fmt::color::cyan))), "INFO: {}\033[0m\n", - fmt::format(fmt::runtime(fmt), std::forward(args)...)); -} - /** Ask the user a yes or no question. * @param def The default result * @param fmt The format string diff --git a/src/libs/cufetch/Makefile b/src/libs/cufetch/Makefile index b6e44cec..87e64053 100644 --- a/src/libs/cufetch/Makefile +++ b/src/libs/cufetch/Makefile @@ -9,6 +9,6 @@ cufetch: cufetch.cc mv -f libcufetch.so ../../../$(BUILDDIR)/libcufetch.so clean: - rm -f *.o *.so *.a ../../../$(BUILDDIR)/cufetch/.*a + rm -f *.o *.so *.a ../../../$(BUILDDIR)/cufetch/.*so .PHONY: clean all cufetch diff --git a/src/libs/cufetch/cufetch.cc b/src/libs/cufetch/cufetch.cc index b7af0275..9aa5a10c 100644 --- a/src/libs/cufetch/cufetch.cc +++ b/src/libs/cufetch/cufetch.cc @@ -1,6 +1,7 @@ #include #include -#include "query.hpp" + +#include "common.hpp" static std::vector modules; @@ -16,10 +17,12 @@ extern "C" { } } + /* Register a module, and its submodules, to customfetch. */ [[gnu::unused]] void cfRegisterModule(const module_t &module) { addModule(module); } + /* Get a list of all modules registered. */ [[gnu::unused]] const std::vector &cfGetModules() { return modules; } diff --git a/src/query/linux/utils/dewm.cpp b/src/query/linux/utils/dewm.cpp index 6cdb3d6f..5747f1df 100644 --- a/src/query/linux/utils/dewm.cpp +++ b/src/query/linux/utils/dewm.cpp @@ -51,6 +51,7 @@ #include "rapidxml-1.13/rapidxml.hpp" #include "switch_fnv1a.hpp" #include "util.hpp" +#include "common.hpp" // https://github.com/fastfetch-cli/fastfetch/blob/a61765c8b1387777be67d967bc2f69031c8ca399/src/detection/displayserver/linux/wmde.c#L19 std::string parse_de_env(void) noexcept diff --git a/src/util.cpp b/src/util.cpp index f8d379ff..5099f7c6 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -49,6 +49,7 @@ #include "fmt/ranges.h" #include "pci.ids.hpp" #include "platform.hpp" +#include "common.hpp" bool hasEnding(const std::string_view fullString, const std::string_view ending) { From 63e41f36d02d3a0a8bb6750fc5d85783e6f7a98f Mon Sep 17 00:00:00 2001 From: Toni500git Date: Fri, 20 Jun 2025 14:56:14 +0200 Subject: [PATCH 008/143] misc: move core-plugins to src --- Makefile | 2 +- {core-plugins => src/core-plugins}/Makefile | 0 {core-plugins => src/core-plugins}/linux/system.cc | 0 3 files changed, 1 insertion(+), 1 deletion(-) rename {core-plugins => src/core-plugins}/Makefile (100%) rename {core-plugins => src/core-plugins}/linux/system.cc (100%) diff --git a/Makefile b/Makefile index 01740bcf..d30e15fb 100644 --- a/Makefile +++ b/Makefile @@ -91,7 +91,7 @@ endif core-plugins: ifeq ($(wildcard $(BUILDDIR)/core-plugins/*.so),) mkdir -p $(BUILDDIR)/core-plugins - make -C core-plugins BUILDDIR=$(BUILDDIR)/core-plugins + make -C src/core-plugins BUILDDIR=$(BUILDDIR)/core-plugins endif genver: ./scripts/generateVersion.sh diff --git a/core-plugins/Makefile b/src/core-plugins/Makefile similarity index 100% rename from core-plugins/Makefile rename to src/core-plugins/Makefile diff --git a/core-plugins/linux/system.cc b/src/core-plugins/linux/system.cc similarity index 100% rename from core-plugins/linux/system.cc rename to src/core-plugins/linux/system.cc From 02ceeab9b739a0c62ddee2df09915a38f6bb5f91 Mon Sep 17 00:00:00 2001 From: BurntRanch <69512353+BurntRanch@users.noreply.github.com> Date: Fri, 20 Jun 2025 16:00:23 +0300 Subject: [PATCH 009/143] plugins: fully implement system module --- src/core-plugins/linux/system.cc | 79 ++++++++++++++++++++++++++------ src/libs/cufetch/cufetch.cc | 2 +- 2 files changed, 66 insertions(+), 15 deletions(-) diff --git a/src/core-plugins/linux/system.cc b/src/core-plugins/linux/system.cc index b2f03406..f2069d2c 100644 --- a/src/core-plugins/linux/system.cc +++ b/src/core-plugins/linux/system.cc @@ -1,16 +1,9 @@ -/* This is an example for a mod you could install in .config/mods - -Mods are essentially custom(fetch) modules that you can implement yourself and register using libcufetch! -They are to be compiled as shared libraries **with no name mangling!!**, with one start function. Scroll down for more details on the start function. - -To compile this, just run `g++ -I../include -shared -fPIC mod-library.cc -o mod-library.so`. To use it, you'll need to put it in your customfetch/mods config directory. -*/ - #include #include #include #include #include +#include #include #include #include @@ -52,9 +45,9 @@ std::string read_by_syspath(const std::string_view path) const std::string host() { const std::string syspath = "/sys/devices/virtual/dmi/id"; - std::string board_name; - std::string board_version; - std::string board_vendor; + std::string board_name = "(unknown)"; + std::string board_version = "(unknown)"; + std::string board_vendor = "(unknown)"; if (std::filesystem::exists(syspath + "/board_name")) { @@ -86,7 +79,7 @@ const std::string host() { const std::string host_name() { const std::string syspath = "/sys/devices/virtual/dmi/id"; - std::string board_name; + std::string board_name = "(unknown)"; if (std::filesystem::exists(syspath + "/board_name")) { @@ -100,6 +93,54 @@ const std::string host_name() { return board_name; } +const std::string host_version() { + const std::string syspath = "/sys/devices/virtual/dmi/id"; + + std::string board_version = "(unknown)"; + + if (std::filesystem::exists(syspath + "/board_name")) + { + board_version = read_by_syspath(syspath + "/board_version"); + } + else if (std::filesystem::exists(syspath + "/product_name")) + { + board_version = read_by_syspath(syspath + "/product_version"); + } + + return board_version; +} + +const std::string host_vendor() { + const std::string syspath = "/sys/devices/virtual/dmi/id"; + + std::string board_vendor = "(unknown)"; + + if (std::filesystem::exists(syspath + "/board_name")) + { + board_vendor = read_by_syspath(syspath + "/board_vendor"); + } + else if (std::filesystem::exists(syspath + "/product_name")) + { + const std::string &board_name = read_by_syspath(syspath + "/product_name"); + static constexpr std::string_view standard_pc_name = "Standard PC"; + if (board_name.substr(0, standard_pc_name.size()) == standard_pc_name) { + board_vendor = "KVM/QEMU"; + } + } + + return board_vendor; +} + +const std::string arch() { + utsname sysinfo; + + if (uname(&sysinfo) != 0) { + die(_("uname() failed: {}\nCould not get system infos"), strerror(errno)); + } + + return sysinfo.machine; +} + extern "C" void start(void *handle) { if (!handle) { std::cout << "Exiting because !handle" << std::endl; @@ -109,12 +150,22 @@ extern "C" void start(void *handle) { LOAD_LIB_SYMBOL(void, cfRegisterModule, const module_t &module); module_t host_name_module = {"name", {}, host_name}; - module_t host_module = {"host", { std::move(host_name_module) }, host}; + module_t host_version_module = {"version", {}, host_version}; + module_t host_vendor_module = {"vendor", {}, host_vendor}; + module_t host_module = {"host", { std::move(host_name_module), std::move(host_version_module), std::move(host_vendor_module) }, host}; /* Only for compatibility */ module_t host_name_module_compat = { "host_name", {}, host_name }; + module_t host_version_module_compat = {"host_version", {}, host_version}; + module_t host_vendor_module_compat = {"host_vendor", {}, host_vendor}; + + module_t arch_module = {"arch", {}, arch}; - module_t system_module = { "system", { std::move(host_module), std::move(host_name_module_compat) }, NULL }; + module_t system_module = { "system", { + std::move(host_module), + std::move(host_name_module_compat), std::move(host_version_module_compat), std::move(host_vendor_module_compat), + std::move(arch_module), + }, NULL }; cfRegisterModule(system_module); } diff --git a/src/libs/cufetch/cufetch.cc b/src/libs/cufetch/cufetch.cc index 9aa5a10c..c46070c3 100644 --- a/src/libs/cufetch/cufetch.cc +++ b/src/libs/cufetch/cufetch.cc @@ -13,7 +13,7 @@ extern "C" { modules.emplace_back(module).name = prefix + module.name; for (const module_t &submodule : module.submodules) { - addModule(submodule, module.name + separator); + addModule(submodule, prefix + module.name + separator); } } From 869c8d1d5f20533fac4369485612408759440a96 Mon Sep 17 00:00:00 2001 From: BurntRanch <69512353+BurntRanch@users.noreply.github.com> Date: Fri, 20 Jun 2025 16:30:03 +0300 Subject: [PATCH 010/143] compile: fix compile issues --- src/core-plugins/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core-plugins/Makefile b/src/core-plugins/Makefile index 82fa2069..d62c6f30 100644 --- a/src/core-plugins/Makefile +++ b/src/core-plugins/Makefile @@ -1,14 +1,14 @@ CXX ?= g++ -CXX_INCLUDES = -I../include +CXX_INCLUDES = -I../../include CXX_FLAGS = -shared -fPIC all: linux-system linux-system: linux/system.cc $(CXX) $(CXX_INCLUDES) $(CXX_FLAGS) linux/system.cc -o linux-system-mod.so - mv -f linux-system-mod.so ../$(BUILDDIR)/linux-system-mod.so + mv -f linux-system-mod.so ../../$(BUILDDIR)/linux-system-mod.so clean: - rm -f *.o *.so *.a ../$(BUILDDIR)/core-plugin/.*so + rm -f *.o *.so *.a ../../$(BUILDDIR)/core-plugin/.*so .PHONY: clean all cufetch From 46cf8e1c4578b7b7c6a048a7e95f997b48e67da4 Mon Sep 17 00:00:00 2001 From: Toni500git Date: Fri, 20 Jun 2025 16:46:12 +0200 Subject: [PATCH 011/143] misc: some improvements to the code make common.hpp a header library file + move and refactor libdl macros --- include/common.hpp | 23 ++++++++++++++++ include/util.hpp | 31 ++------------------- src/core-plugins/Makefile | 2 +- src/core-plugins/linux/system.cc | 46 ++++---------------------------- src/main.cpp | 23 ++++++++-------- src/query/linux/theme.cpp | 12 +++++++-- src/query/linux/user.cpp | 12 +++++++-- src/query/linux/utils/dewm.cpp | 6 ++--- 8 files changed, 66 insertions(+), 89 deletions(-) diff --git a/include/common.hpp b/include/common.hpp index 3b1bf6e4..e1fc4384 100644 --- a/include/common.hpp +++ b/include/common.hpp @@ -17,6 +17,29 @@ #define BOLD_COLOR(x) (fmt::emphasis::bold | fmt::fg(x)) +constexpr const char NOCOLOR[] = "\033[0m"; +constexpr const char NOCOLOR_BOLD[] = "\033[0m\033[1m"; +constexpr const char UNKNOWN[] = "(unknown)"; + +// Usually in neofetch/fastfetch when some infos couldn't be queried, +// they remove it from the display. With customfetch is kinda difficult to know when to remove +// the info to display, since it's all modular with tags, so I have created +// magic line to be sure that I don't cut the wrong line. +// +// Every instance of this string in a layout line, the whole line will be erased. +constexpr const char MAGIC_LINE[] = "(cut this line NOW!! RAHHH)"; + +/* handle = the library handle + * ret_type = type of what the function returns + * func = the function name + * ... = the arguments in a function if any + */ +#define LOAD_LIB_SYMBOL(handle, ret_type, func, ...) \ + typedef ret_type (*func##_t)(__VA_ARGS__); \ + func##_t func = reinterpret_cast(dlsym(handle, #func)); + +#define UNLOAD_LIBRARY(handle) dlclose(handle); + template void error(const std::string_view fmt, Args&&... args) noexcept { diff --git a/include/util.hpp b/include/util.hpp index 94d183d5..d3ebd5dd 100644 --- a/include/util.hpp +++ b/include/util.hpp @@ -55,35 +55,8 @@ struct byte_units_t double num_bytes; }; -constexpr const char NOCOLOR[] = "\033[0m"; -constexpr const char NOCOLOR_BOLD[] = "\033[0m\033[1m"; -constexpr const char UNKNOWN[] = "(unknown)"; - -// Usually in neofetch/fastfetch when some infos couldn't be queried, -// they remove it from the display. With customfetch is kinda difficult to know when to remove -// the info to display, since it's all modular with tags, so I have created -// magic line to be sure that I don't cut the wrong line. -// -// Every instance of this string in a layout line, the whole line will be erased. -constexpr const char MAGIC_LINE[] = "(cut this line NOW!! RAHHH)"; - -/* lib = library to load (string) - * code = code to execute if anything goes wrong - */ -#define LOAD_LIBRARY(lib, code) \ - void* handle = dlopen(lib, RTLD_LAZY); \ - if (!handle) \ - code; - -/* ret_type = type of what the function returns - * func = the function name - * ... = the arguments in a function if any - */ -#define LOAD_LIB_SYMBOL(ret_type, func, ...) \ - typedef ret_type (*func##_t)(__VA_ARGS__); \ - func##_t func = reinterpret_cast(dlsym(handle, #func)); - -#define UNLOAD_LIBRARY() dlclose(handle); +/* lib = library to load (string) */ +#define LOAD_LIBRARY(lib) dlopen(lib, RTLD_LAZY); /* https://stackoverflow.com/questions/874134/find-out-if-string-ends-with-another-string-in-c#874160 * Check if substring exists at the end diff --git a/src/core-plugins/Makefile b/src/core-plugins/Makefile index d62c6f30..63f37de2 100644 --- a/src/core-plugins/Makefile +++ b/src/core-plugins/Makefile @@ -5,7 +5,7 @@ CXX_FLAGS = -shared -fPIC all: linux-system linux-system: linux/system.cc - $(CXX) $(CXX_INCLUDES) $(CXX_FLAGS) linux/system.cc -o linux-system-mod.so + $(CXX) $(CXX_INCLUDES) $(CXX_FLAGS) linux/system.cc ../util.cpp -o linux-system-mod.so mv -f linux-system-mod.so ../../$(BUILDDIR)/linux-system-mod.so clean: diff --git a/src/core-plugins/linux/system.cc b/src/core-plugins/linux/system.cc index f2069d2c..48804614 100644 --- a/src/core-plugins/linux/system.cc +++ b/src/core-plugins/linux/system.cc @@ -9,37 +9,7 @@ #include #include "common.hpp" - -#define BOLD_COLOR(x) (fmt::emphasis::bold | fmt::fg(x)) - -/* ret_type = type of what the function returns - * func = the function name - * ... = the arguments in a function if any - */ -#define LOAD_LIB_SYMBOL(ret_type, func, ...) \ - typedef ret_type (*func##_t)(__VA_ARGS__); \ - func##_t func = reinterpret_cast(dlsym(handle, #func)); - -#define UNLOAD_LIBRARY() dlclose(handle); - -std::string read_by_syspath(const std::string_view path) -{ - std::ifstream f(path.data()); - if (!f.is_open()) - { - error(_("Failed to open {}"), path); - - return "(unknown)"; - } - - std::string result; - std::getline(f, result); - - if (!result.empty() && result.back() == '\n') - result.pop_back(); - - return result; -} +#include "util.hpp" /* The handler that we'll use for our module, Handlers return const std::string (WILL be changed to const char pointers). */ const std::string host() { @@ -79,18 +49,12 @@ const std::string host() { const std::string host_name() { const std::string syspath = "/sys/devices/virtual/dmi/id"; - std::string board_name = "(unknown)"; - if (std::filesystem::exists(syspath + "/board_name")) - { - board_name = read_by_syspath(syspath + "/board_name"); - } + return read_by_syspath(syspath + "/board_name"); else if (std::filesystem::exists(syspath + "/product_name")) - { - board_name = read_by_syspath(syspath + "/product_name"); - } + return read_by_syspath(syspath + "/product_name"); - return board_name; + return UNKNOWN; } const std::string host_version() { @@ -147,7 +111,7 @@ extern "C" void start(void *handle) { return; } - LOAD_LIB_SYMBOL(void, cfRegisterModule, const module_t &module); + LOAD_LIB_SYMBOL(handle, void, cfRegisterModule, const module_t &module); module_t host_name_module = {"name", {}, host_name}; module_t host_version_module = {"version", {}, host_version}; diff --git a/src/main.cpp b/src/main.cpp index dfa5e342..2c94e7b9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -38,6 +38,7 @@ #include "config.hpp" #include "display.hpp" #include "fmt/ranges.h" +#include "fmt/std.h" #include "gui.hpp" #include "platform.hpp" #include "query.hpp" @@ -787,8 +788,9 @@ int main(int argc, char *argv[]) return 1; config.loadConfigFile(configFile, colors); - LOAD_LIBRARY("libcufetch.so", die("Failed to load libcufetch!")); - void* cufetch_handle = handle; + void* cufetch_handle = LOAD_LIBRARY("libcufetch.so") + if (!cufetch_handle) + die("Failed to load libcufetch! {}", dlerror()); /* TODO(burntranch): track each library and unload them. */ const std::filesystem::path modDir = configDir / "mods"; @@ -797,19 +799,19 @@ int main(int argc, char *argv[]) { debug("loading mod at {}!", entry.path().string()); - LOAD_LIBRARY(std::filesystem::absolute(entry.path()).c_str(), - warn("Failed to load mod {}!", entry.path().string())) - if (!handle) + void *handle = LOAD_LIBRARY(std::filesystem::absolute(entry.path()).c_str()); + if (!handle) { + warn("Failed to load mod {}! {}", entry.path(), dlerror()); + dlerror(); continue; + } - LOAD_LIB_SYMBOL(void, start, void*) + LOAD_LIB_SYMBOL(handle, void, start, void*) start(cufetch_handle); } - handle = cufetch_handle; - - LOAD_LIB_SYMBOL(const std::vector&, cfGetModules) + LOAD_LIB_SYMBOL(cufetch_handle, const std::vector&, cfGetModules) const std::vector& modules = cfGetModules(); moduleMap_t moduleMap; @@ -897,8 +899,7 @@ int main(int argc, char *argv[]) if (!config.wrap_lines) enable_cursor(); - handle = cufetch_handle; - UNLOAD_LIBRARY(); + UNLOAD_LIBRARY(cufetch_handle); return 0; } diff --git a/src/query/linux/theme.cpp b/src/query/linux/theme.cpp index cba7115b..5abb23a3 100644 --- a/src/query/linux/theme.cpp +++ b/src/query/linux/theme.cpp @@ -42,6 +42,14 @@ #include #endif +/* ret_type = type of what the function returns + * func = the function name + * ... = the arguments in a function if any + */ +#define LOAD_LIB_SYMBOL(ret_type, func, ...) \ + typedef ret_type (*func##_t)(__VA_ARGS__); \ + func##_t func = reinterpret_cast(dlsym(handle, #func)); + using namespace Query; const std::string& configDir = getHomeConfigDir(); @@ -129,7 +137,7 @@ static bool get_cursor_dconf(const std::string_view de_name, Theme::Theme_t& the { #if USE_DCONF - LOAD_LIBRARY("libdconf.so", return false); + void *handle = LOAD_LIBRARY("libdconf.so", return false); LOAD_LIB_SYMBOL(DConfClient*, dconf_client_new, void); LOAD_LIB_SYMBOL(GVariant*, dconf_client_read, DConfClient*, const char*); LOAD_LIB_SYMBOL(const gchar*, g_variant_get_string, GVariant*, gsize*); @@ -309,7 +317,7 @@ static bool get_gtk_theme_dconf(const std::string_view de_name, Theme::Theme_t& { #if USE_DCONF - LOAD_LIBRARY("libdconf.so", return false); + void *handle = LOAD_LIBRARY("libdconf.so", return false); LOAD_LIB_SYMBOL(DConfClient*, dconf_client_new, void); LOAD_LIB_SYMBOL(GVariant*, dconf_client_read, DConfClient * client, const char*); LOAD_LIB_SYMBOL(const gchar*, g_variant_get_string, GVariant* value, gsize* lenght); diff --git a/src/query/linux/user.cpp b/src/query/linux/user.cpp index 68554e14..d40136cf 100644 --- a/src/query/linux/user.cpp +++ b/src/query/linux/user.cpp @@ -54,6 +54,14 @@ #include "utils/dewm.hpp" #include "utils/term.hpp" +/* ret_type = type of what the function returns + * func = the function name + * ... = the arguments in a function if any + */ +#define LOAD_LIB_SYMBOL(ret_type, func, ...) \ + typedef ret_type (*func##_t)(__VA_ARGS__); \ + func##_t func = reinterpret_cast(dlsym(handle, #func)); + using namespace Query; static std::string get_de_name() @@ -144,7 +152,7 @@ static std::string get_de_version(const std::string_view de_name) static std::string get_wm_wayland_name(std::string& wm_path_exec) { #if __has_include() && __has_include() - LOAD_LIBRARY("libwayland-client.so", return get_wm_name(wm_path_exec);) + void *handle = LOAD_LIBRARY("libwayland-client.so", return get_wm_name(wm_path_exec);) LOAD_LIB_SYMBOL(wl_display*, wl_display_connect, const char* name) LOAD_LIB_SYMBOL(void, wl_display_disconnect, wl_display* display) @@ -166,7 +174,7 @@ static std::string get_wm_wayland_name(std::string& wm_path_exec) char buf[PATH_MAX]; wm_path_exec = realpath(fmt::format("/proc/{}/exe", ucred.pid).c_str(), buf); - UNLOAD_LIBRARY() + UNLOAD_LIBRARY(handle) return prettify_wm_name(ret); #else diff --git a/src/query/linux/utils/dewm.cpp b/src/query/linux/utils/dewm.cpp index 5747f1df..b0a52de8 100644 --- a/src/query/linux/utils/dewm.cpp +++ b/src/query/linux/utils/dewm.cpp @@ -277,10 +277,10 @@ std::string get_cinnamon_version() static std::string get_xfce4_version_lib() { - LOAD_LIBRARY("libxfce4util.so", return UNKNOWN) - LOAD_LIB_SYMBOL(const char*, xfce_version_string, void) + void *handle = LOAD_LIBRARY("libxfce4util.so", return UNKNOWN) + LOAD_LIB_SYMBOL(handle, const char*, xfce_version_string, void) const std::string& ret = xfce_version_string(); - UNLOAD_LIBRARY() + UNLOAD_LIBRARY(handle) return ret; } From 4e874ba373024f9b73a63844caf88fb3fa56c4c9 Mon Sep 17 00:00:00 2001 From: BurntRanch <69512353+BurntRanch@users.noreply.github.com> Date: Fri, 20 Jun 2025 21:34:08 +0300 Subject: [PATCH 012/143] plugins: implement os.name, os.pretty_name, and os.name_id --- src/core-plugins/linux/system.cc | 106 +++++++++++++++++++++++++++++++ src/query/linux/theme.cpp | 10 ++- src/query/linux/user.cpp | 4 +- src/query/linux/utils/dewm.cpp | 5 +- 4 files changed, 121 insertions(+), 4 deletions(-) diff --git a/src/core-plugins/linux/system.cc b/src/core-plugins/linux/system.cc index 48804614..d6a5ea9d 100644 --- a/src/core-plugins/linux/system.cc +++ b/src/core-plugins/linux/system.cc @@ -1,6 +1,11 @@ #include +#include +#include +#include +#include #include #include +#include #include #include #include @@ -105,6 +110,93 @@ const std::string arch() { return sysinfo.machine; } + +static std::ifstream os_release; + +const std::string os_name() { + assert(os_release.is_open()); + os_release.clear(); + os_release.seekg(0, std::ios_base::beg); + + /* 256 - NAME=" */ + char name[250] = "(unknown)\0"; + + char line[256]; + while (os_release.tellg() >= 0) { + os_release.getline(line, 256); + + if (strncmp(line, "NAME=\"", 6) != 0) { + continue; + } + + /* 6 = length of 'NAME="' */ + size_t value_len = strlen(&line[6]) - 1; + assert(value_len < 250); + strncpy(name, &line[6], value_len); + name[value_len] = '\0'; + + break; + } + + return name; +} + +const std::string os_pretty_name() { + assert(os_release.is_open()); + os_release.clear(); + os_release.seekg(0, std::ios_base::beg); + + /* 256 - PRETTY_NAME=" */ + char pretty_name[237] = "(unknown)\0"; + + char line[256]; + while (os_release.tellg() >= 0) { + os_release.getline(line, 256); + + if (strncmp(line, "PRETTY_NAME=\"", 13) != 0) { + continue; + } + + /* 13 = length of 'PRETTY_NAME="' */ + size_t value_len = strlen(&line[13]) - 1; + assert(value_len < 237); + strncpy(pretty_name, &line[13], value_len); + pretty_name[value_len] = '\0'; + + break; + } + + return pretty_name; +} + +const std::string os_name_id() { + assert(os_release.is_open()); + os_release.clear(); + os_release.seekg(0, std::ios_base::beg); + + /* 256 - ID= */ + char name_id[253] = "(unknown)\0"; + + char line[256]; + while (os_release.tellg() >= 0) { + os_release.getline(line, 256); + + if (strncmp(line, "ID=", 3) != 0) { + continue; + } + + /* 3 = length of 'ID=' */ + size_t value_len = strlen(&line[3]); + assert(value_len < 253); + strncpy(name_id, &line[3], value_len); + name_id[value_len] = '\0'; + + break; + } + + return name_id; +} + extern "C" void start(void *handle) { if (!handle) { std::cout << "Exiting because !handle" << std::endl; @@ -132,4 +224,18 @@ extern "C" void start(void *handle) { }, NULL }; cfRegisterModule(system_module); + + /* Keep this fd open for the future */ + os_release = std::ifstream("/etc/os-release"); + + module_t name_module = { "name", {}, os_name }; + module_t pretty_name_module = { "pretty_name", {}, os_pretty_name }; + module_t name_id_module = { "name_id", {}, os_name_id }; + + module_t os_module = { "os", { + std::move(name_module), std::move(pretty_name_module), + std::move(name_id_module), + }, NULL}; + + cfRegisterModule(os_module); } diff --git a/src/query/linux/theme.cpp b/src/query/linux/theme.cpp index 5abb23a3..2c0dfe59 100644 --- a/src/query/linux/theme.cpp +++ b/src/query/linux/theme.cpp @@ -137,7 +137,10 @@ static bool get_cursor_dconf(const std::string_view de_name, Theme::Theme_t& the { #if USE_DCONF - void *handle = LOAD_LIBRARY("libdconf.so", return false); + void *handle = LOAD_LIBRARY("libdconf.so"); + if (!handle) + return false; + LOAD_LIB_SYMBOL(DConfClient*, dconf_client_new, void); LOAD_LIB_SYMBOL(GVariant*, dconf_client_read, DConfClient*, const char*); LOAD_LIB_SYMBOL(const gchar*, g_variant_get_string, GVariant*, gsize*); @@ -317,7 +320,10 @@ static bool get_gtk_theme_dconf(const std::string_view de_name, Theme::Theme_t& { #if USE_DCONF - void *handle = LOAD_LIBRARY("libdconf.so", return false); + void *handle = LOAD_LIBRARY("libdconf.so"); + if (!handle) + return false; + LOAD_LIB_SYMBOL(DConfClient*, dconf_client_new, void); LOAD_LIB_SYMBOL(GVariant*, dconf_client_read, DConfClient * client, const char*); LOAD_LIB_SYMBOL(const gchar*, g_variant_get_string, GVariant* value, gsize* lenght); diff --git a/src/query/linux/user.cpp b/src/query/linux/user.cpp index d40136cf..0560fe4b 100644 --- a/src/query/linux/user.cpp +++ b/src/query/linux/user.cpp @@ -152,7 +152,9 @@ static std::string get_de_version(const std::string_view de_name) static std::string get_wm_wayland_name(std::string& wm_path_exec) { #if __has_include() && __has_include() - void *handle = LOAD_LIBRARY("libwayland-client.so", return get_wm_name(wm_path_exec);) + void *handle = LOAD_LIBRARY("libwayland-client.so") + if (!handle) + return get_wm_name(wm_path_exec); LOAD_LIB_SYMBOL(wl_display*, wl_display_connect, const char* name) LOAD_LIB_SYMBOL(void, wl_display_disconnect, wl_display* display) diff --git a/src/query/linux/utils/dewm.cpp b/src/query/linux/utils/dewm.cpp index b0a52de8..8a08e976 100644 --- a/src/query/linux/utils/dewm.cpp +++ b/src/query/linux/utils/dewm.cpp @@ -277,7 +277,10 @@ std::string get_cinnamon_version() static std::string get_xfce4_version_lib() { - void *handle = LOAD_LIBRARY("libxfce4util.so", return UNKNOWN) + void *handle = LOAD_LIBRARY("libxfce4util.so") + if (!handle) + return UNKNOWN; + LOAD_LIB_SYMBOL(handle, const char*, xfce_version_string, void) const std::string& ret = xfce_version_string(); UNLOAD_LIBRARY(handle) From 52f0ba6554746e51da3f85dfb4b9f2a64b83e782 Mon Sep 17 00:00:00 2001 From: Toni500git Date: Fri, 20 Jun 2025 21:08:01 +0200 Subject: [PATCH 013/143] misc: add some symbols for mods start method --- include/common.hpp | 6 ++++++ src/core-plugins/linux/system.cc | 2 +- src/main.cpp | 4 ++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/include/common.hpp b/include/common.hpp index e1fc4384..33720f64 100644 --- a/include/common.hpp +++ b/include/common.hpp @@ -40,6 +40,12 @@ constexpr const char MAGIC_LINE[] = "(cut this line NOW!! RAHHH)"; #define UNLOAD_LIBRARY(handle) dlclose(handle); +#define APICALL extern "C" +// {fmt} library already has __attribute__((visibility(value))) fallback so let's use that maybeAdd commentMore actions +#define EXPORT FMT_VISIBILITY("default") void +#define MOD_INIT start + + template void error(const std::string_view fmt, Args&&... args) noexcept { diff --git a/src/core-plugins/linux/system.cc b/src/core-plugins/linux/system.cc index d6a5ea9d..357cac10 100644 --- a/src/core-plugins/linux/system.cc +++ b/src/core-plugins/linux/system.cc @@ -197,7 +197,7 @@ const std::string os_name_id() { return name_id; } -extern "C" void start(void *handle) { +APICALL EXPORT MOD_INIT(void *handle) { if (!handle) { std::cout << "Exiting because !handle" << std::endl; return; diff --git a/src/main.cpp b/src/main.cpp index 2c94e7b9..cd553259 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -806,9 +806,9 @@ int main(int argc, char *argv[]) continue; } - LOAD_LIB_SYMBOL(handle, void, start, void*) + LOAD_LIB_SYMBOL(handle, void, MOD_INIT, void*) - start(cufetch_handle); + MOD_INIT(cufetch_handle); } LOAD_LIB_SYMBOL(cufetch_handle, const std::vector&, cfGetModules) From 9c7d0029286d627b2879607fbdc4f26c7ddf89c1 Mon Sep 17 00:00:00 2001 From: Toni500git Date: Fri, 20 Jun 2025 22:35:12 +0200 Subject: [PATCH 014/143] mods: separate $ and $ modules + combine those into a unique .so --- src/core-plugins/Makefile | 17 +- src/core-plugins/linux/linux-core-modules.cc | 52 ++++++ src/core-plugins/linux/linux-core-modules.hh | 14 ++ src/core-plugins/linux/os.cc | 48 ++++++ src/core-plugins/linux/system.cc | 165 +------------------ src/libs/cufetch/cufetch.cc | 1 - 6 files changed, 132 insertions(+), 165 deletions(-) create mode 100644 src/core-plugins/linux/linux-core-modules.cc create mode 100644 src/core-plugins/linux/linux-core-modules.hh create mode 100644 src/core-plugins/linux/os.cc diff --git a/src/core-plugins/Makefile b/src/core-plugins/Makefile index 63f37de2..6250c8f5 100644 --- a/src/core-plugins/Makefile +++ b/src/core-plugins/Makefile @@ -1,14 +1,17 @@ CXX ?= g++ CXX_INCLUDES = -I../../include -CXX_FLAGS = -shared -fPIC +CXX_FLAGS = -ggdb3 -shared -fPIC -fvisibility=hidden -fvisibility-inlines-hidden -DNDEBUG -shared -Wl,-soname,libcufetch-core-modules.so.1 -all: linux-system +SRC = $(wildcard linux/*.cc) +OBJ = $(SRC:.cc=.o) -linux-system: linux/system.cc - $(CXX) $(CXX_INCLUDES) $(CXX_FLAGS) linux/system.cc ../util.cpp -o linux-system-mod.so - mv -f linux-system-mod.so ../../$(BUILDDIR)/linux-system-mod.so +all: linux-core-modules + +linux-core-modules: + $(CXX) $(CXX_INCLUDES) $(CXX_FLAGS) linux/*.cc ../util.cpp -o $@.so + mv -f $@.so ../../$(BUILDDIR)/core-plugins/$@.so clean: - rm -f *.o *.so *.a ../../$(BUILDDIR)/core-plugin/.*so + rm -f *.o *.so *.a ../../$(BUILDDIR)/core-plugins/.*so -.PHONY: clean all cufetch +.PHONY: clean all linux-core-modules diff --git a/src/core-plugins/linux/linux-core-modules.cc b/src/core-plugins/linux/linux-core-modules.cc new file mode 100644 index 00000000..11ac126e --- /dev/null +++ b/src/core-plugins/linux/linux-core-modules.cc @@ -0,0 +1,52 @@ +#include +#include "linux-core-modules.hh" +#include "common.hpp" +#include "util.hpp" + +APICALL EXPORT MOD_INIT(void *handle) +{ + if (!handle) + { + error("Exiting because !handle"); + return; + } + + LOAD_LIB_SYMBOL(handle, void, cfRegisterModule, const module_t& module); + + // *** $ + os_release = fopen("/etc/os-release", "r"); + + module_t os_name_module = { "name", {}, os_name }; + module_t os_pretty_name_module = { "pretty_name", {}, os_pretty_name }; + module_t os_name_id_module = { "name_id", {}, os_name_id }; + + module_t os_module = { "os", { + std::move(os_name_module), + std::move(os_pretty_name_module), + std::move(os_name_id_module), + }, NULL}; + + //fclose(os_release); + cfRegisterModule(os_module); + + // *** $ + module_t host_name_module = {"name", {}, host_name}; + module_t host_version_module = {"version", {}, host_version}; + module_t host_vendor_module = {"vendor", {}, host_vendor}; + module_t host_module = {"host", { std::move(host_name_module), std::move(host_version_module), std::move(host_vendor_module) }, host}; + + /* Only for compatibility */ + module_t host_name_module_compat = { "host_name", {}, host_name }; + module_t host_version_module_compat = {"host_version", {}, host_version}; + module_t host_vendor_module_compat = {"host_vendor", {}, host_vendor}; + + module_t arch_module = {"arch", {}, arch}; + + module_t system_module = { "system", { + std::move(host_module), + std::move(host_name_module_compat), std::move(host_version_module_compat), std::move(host_vendor_module_compat), + std::move(arch_module), + }, NULL }; + + cfRegisterModule(system_module); +} diff --git a/src/core-plugins/linux/linux-core-modules.hh b/src/core-plugins/linux/linux-core-modules.hh new file mode 100644 index 00000000..0331f89f --- /dev/null +++ b/src/core-plugins/linux/linux-core-modules.hh @@ -0,0 +1,14 @@ +#pragma once + +#include + +const std::string arch(); +const std::string host(); +const std::string host_name(); +const std::string host_version(); +const std::string host_vendor(); + +inline std::FILE *os_release; +const std::string os_name(); +const std::string os_pretty_name(); +const std::string os_name_id(); diff --git a/src/core-plugins/linux/os.cc b/src/core-plugins/linux/os.cc new file mode 100644 index 00000000..42dfbcb9 --- /dev/null +++ b/src/core-plugins/linux/os.cc @@ -0,0 +1,48 @@ +#include +#include +#include +#include + +#include "common.hpp" +#include "linux-core-modules.hh" + +static const char *read_value(const char *name, size_t n) +{ + if (!os_release) + return strdup(UNKNOWN); + rewind(os_release); // Reset file pointer to start + + char *buf = strdup(UNKNOWN); // Default value + char *line = NULL; + size_t len = 0; + while (getline(&line, &len, os_release) != -1) + { + if (strncmp(line, name, n) != 0) + continue; + + // Find the first quote after the key + char *start = strchr(line + n, '"'); + if (!start) continue; + start++; + + // Find the closing quote + char *end = strrchr(start, '"'); + if (!end) continue; + + free(buf); + buf = strndup(start, end - start); + break; + } + + free(line); + return buf; +} + +const std::string os_name() +{ return read_value("NAME=", 5); } + +const std::string os_pretty_name() +{ return read_value("PRETTY_NAME=", 12); } + +const std::string os_name_id() +{ return read_value("ID=", 3); } diff --git a/src/core-plugins/linux/system.cc b/src/core-plugins/linux/system.cc index 357cac10..cd0cd9b8 100644 --- a/src/core-plugins/linux/system.cc +++ b/src/core-plugins/linux/system.cc @@ -1,16 +1,7 @@ -#include -#include -#include -#include #include #include -#include -#include -#include -#include #include #include -#include #include #include "common.hpp" @@ -65,36 +56,28 @@ const std::string host_name() { const std::string host_version() { const std::string syspath = "/sys/devices/virtual/dmi/id"; - std::string board_version = "(unknown)"; - if (std::filesystem::exists(syspath + "/board_name")) - { - board_version = read_by_syspath(syspath + "/board_version"); - } + return read_by_syspath(syspath + "/board_version"); else if (std::filesystem::exists(syspath + "/product_name")) - { - board_version = read_by_syspath(syspath + "/product_version"); - } + return read_by_syspath(syspath + "/product_version"); - return board_version; + return UNKNOWN; } const std::string host_vendor() { const std::string syspath = "/sys/devices/virtual/dmi/id"; - std::string board_vendor = "(unknown)"; + std::string board_vendor {UNKNOWN}; if (std::filesystem::exists(syspath + "/board_name")) { - board_vendor = read_by_syspath(syspath + "/board_vendor"); + board_vendor = read_by_syspath(syspath + "/board_vendor"); } else if (std::filesystem::exists(syspath + "/product_name")) { - const std::string &board_name = read_by_syspath(syspath + "/product_name"); - static constexpr std::string_view standard_pc_name = "Standard PC"; - if (board_name.substr(0, standard_pc_name.size()) == standard_pc_name) { + const std::string& board_name = read_by_syspath(syspath + "/product_name"); + if (hasStart(board_name, "Standard PC")) board_vendor = "KVM/QEMU"; - } } return board_vendor; @@ -102,140 +85,8 @@ const std::string host_vendor() { const std::string arch() { utsname sysinfo; - - if (uname(&sysinfo) != 0) { + if (uname(&sysinfo) != 0) die(_("uname() failed: {}\nCould not get system infos"), strerror(errno)); - } return sysinfo.machine; } - - -static std::ifstream os_release; - -const std::string os_name() { - assert(os_release.is_open()); - os_release.clear(); - os_release.seekg(0, std::ios_base::beg); - - /* 256 - NAME=" */ - char name[250] = "(unknown)\0"; - - char line[256]; - while (os_release.tellg() >= 0) { - os_release.getline(line, 256); - - if (strncmp(line, "NAME=\"", 6) != 0) { - continue; - } - - /* 6 = length of 'NAME="' */ - size_t value_len = strlen(&line[6]) - 1; - assert(value_len < 250); - strncpy(name, &line[6], value_len); - name[value_len] = '\0'; - - break; - } - - return name; -} - -const std::string os_pretty_name() { - assert(os_release.is_open()); - os_release.clear(); - os_release.seekg(0, std::ios_base::beg); - - /* 256 - PRETTY_NAME=" */ - char pretty_name[237] = "(unknown)\0"; - - char line[256]; - while (os_release.tellg() >= 0) { - os_release.getline(line, 256); - - if (strncmp(line, "PRETTY_NAME=\"", 13) != 0) { - continue; - } - - /* 13 = length of 'PRETTY_NAME="' */ - size_t value_len = strlen(&line[13]) - 1; - assert(value_len < 237); - strncpy(pretty_name, &line[13], value_len); - pretty_name[value_len] = '\0'; - - break; - } - - return pretty_name; -} - -const std::string os_name_id() { - assert(os_release.is_open()); - os_release.clear(); - os_release.seekg(0, std::ios_base::beg); - - /* 256 - ID= */ - char name_id[253] = "(unknown)\0"; - - char line[256]; - while (os_release.tellg() >= 0) { - os_release.getline(line, 256); - - if (strncmp(line, "ID=", 3) != 0) { - continue; - } - - /* 3 = length of 'ID=' */ - size_t value_len = strlen(&line[3]); - assert(value_len < 253); - strncpy(name_id, &line[3], value_len); - name_id[value_len] = '\0'; - - break; - } - - return name_id; -} - -APICALL EXPORT MOD_INIT(void *handle) { - if (!handle) { - std::cout << "Exiting because !handle" << std::endl; - return; - } - - LOAD_LIB_SYMBOL(handle, void, cfRegisterModule, const module_t &module); - - module_t host_name_module = {"name", {}, host_name}; - module_t host_version_module = {"version", {}, host_version}; - module_t host_vendor_module = {"vendor", {}, host_vendor}; - module_t host_module = {"host", { std::move(host_name_module), std::move(host_version_module), std::move(host_vendor_module) }, host}; - - /* Only for compatibility */ - module_t host_name_module_compat = { "host_name", {}, host_name }; - module_t host_version_module_compat = {"host_version", {}, host_version}; - module_t host_vendor_module_compat = {"host_vendor", {}, host_vendor}; - - module_t arch_module = {"arch", {}, arch}; - - module_t system_module = { "system", { - std::move(host_module), - std::move(host_name_module_compat), std::move(host_version_module_compat), std::move(host_vendor_module_compat), - std::move(arch_module), - }, NULL }; - - cfRegisterModule(system_module); - - /* Keep this fd open for the future */ - os_release = std::ifstream("/etc/os-release"); - - module_t name_module = { "name", {}, os_name }; - module_t pretty_name_module = { "pretty_name", {}, os_pretty_name }; - module_t name_id_module = { "name_id", {}, os_name_id }; - - module_t os_module = { "os", { - std::move(name_module), std::move(pretty_name_module), - std::move(name_id_module), - }, NULL}; - - cfRegisterModule(os_module); -} diff --git a/src/libs/cufetch/cufetch.cc b/src/libs/cufetch/cufetch.cc index c46070c3..eae0f624 100644 --- a/src/libs/cufetch/cufetch.cc +++ b/src/libs/cufetch/cufetch.cc @@ -1,4 +1,3 @@ -#include #include #include "common.hpp" From 14240a0f707ec4b53e26190053539502a0a8aeaa Mon Sep 17 00:00:00 2001 From: Toni500git Date: Sat, 21 Jun 2025 21:32:03 +0200 Subject: [PATCH 015/143] core-plugins: linux: add the complete modules list from system and os --- include/common.hpp | 1 + src/core-plugins/linux/linux-core-modules.cc | 63 ++++++++-- src/core-plugins/linux/linux-core-modules.hh | 29 +++-- src/core-plugins/linux/os.cc | 119 +++++++++++++++++-- src/core-plugins/linux/system.cc | 23 ++-- src/main.cpp | 10 +- 6 files changed, 205 insertions(+), 40 deletions(-) diff --git a/include/common.hpp b/include/common.hpp index 33720f64..99b6131f 100644 --- a/include/common.hpp +++ b/include/common.hpp @@ -45,6 +45,7 @@ constexpr const char MAGIC_LINE[] = "(cut this line NOW!! RAHHH)"; #define EXPORT FMT_VISIBILITY("default") void #define MOD_INIT start +using modfunc = const std::string; template void error(const std::string_view fmt, Args&&... args) noexcept diff --git a/src/core-plugins/linux/linux-core-modules.cc b/src/core-plugins/linux/linux-core-modules.cc index 11ac126e..310e1643 100644 --- a/src/core-plugins/linux/linux-core-modules.cc +++ b/src/core-plugins/linux/linux-core-modules.cc @@ -1,7 +1,6 @@ #include #include "linux-core-modules.hh" #include "common.hpp" -#include "util.hpp" APICALL EXPORT MOD_INIT(void *handle) { @@ -13,28 +12,74 @@ APICALL EXPORT MOD_INIT(void *handle) LOAD_LIB_SYMBOL(handle, void, cfRegisterModule, const module_t& module); - // *** $ + if (uname(&g_uname_infos) != 0) + die(_("uname() failed: {}\nCould not get system infos"), strerror(errno)); + os_release = fopen("/etc/os-release", "r"); - module_t os_name_module = { "name", {}, os_name }; - module_t os_pretty_name_module = { "pretty_name", {}, os_pretty_name }; - module_t os_name_id_module = { "name_id", {}, os_name_id }; + // $ + module_t os_name_pretty_module = {"pretty", {}, os_pretty_name}; + module_t os_name_id_module = {"id", {}, os_name_id}; + module_t os_name_module = { "name", { + std::move(os_name_pretty_module), + std::move(os_name_id_module) + }, os_name }; + + // $ + module_t os_uptime_module = {"uptime", {}, os_uptime}; + + // $ + module_t os_hostname_module = {"hostname", {}, os_hostname}; + + // $ + module_t os_kernel_name_module = {"name", {}, os_kernel_name}; + module_t os_kernel_version_module = {"version", {}, os_kernel_version}; + module_t os_kernel_module = {"kernel", { + std::move(os_kernel_name_module), + std::move(os_kernel_version_module) + }, []() {return os_kernel_name() + ' ' + os_kernel_version();}}; + + // $ + module_t os_initsys_name_module = {"name", {}, os_initsys_name}; + module_t os_initsys_version_module = {"version", {}, os_initsys_version}; + module_t os_initsys_module = {"initsys", { + std::move(os_initsys_name_module), + std::move(os_initsys_version_module), + }, []() {return os_initsys_name() + ' ' + os_initsys_version();}}; + /* Only for compatibility */ + module_t os_pretty_name_module_compat = { "pretty_name", {}, os_pretty_name }; + module_t os_name_id_module_compat = { "name_id", {}, os_name_id }; + module_t os_kernel_name_module_compat = {"kernel_name", {}, os_kernel_name}; + module_t os_kernel_version_module_compat = {"kernel_version", {}, os_kernel_version}; + module_t os_initsys_name_module_compat = {"initsys_name", {}, os_initsys_name}; + module_t os_initsys_version_module_compat = {"initsys_version", {}, os_initsys_version}; + + // $ module_t os_module = { "os", { std::move(os_name_module), - std::move(os_pretty_name_module), - std::move(os_name_id_module), + std::move(os_uptime_module), + std::move(os_kernel_module), + std::move(os_hostname_module), + std::move(os_initsys_module), + + std::move(os_pretty_name_module_compat), + std::move(os_name_id_module_compat), + std::move(os_kernel_name_module_compat), + std::move(os_kernel_version_module_compat), + std::move(os_initsys_name_module_compat), + std::move(os_initsys_version_module_compat), }, NULL}; //fclose(os_release); cfRegisterModule(os_module); - // *** $ + // $ module_t host_name_module = {"name", {}, host_name}; module_t host_version_module = {"version", {}, host_version}; module_t host_vendor_module = {"vendor", {}, host_vendor}; module_t host_module = {"host", { std::move(host_name_module), std::move(host_version_module), std::move(host_vendor_module) }, host}; - + /* Only for compatibility */ module_t host_name_module_compat = { "host_name", {}, host_name }; module_t host_version_module_compat = {"host_version", {}, host_version}; diff --git a/src/core-plugins/linux/linux-core-modules.hh b/src/core-plugins/linux/linux-core-modules.hh index 0331f89f..74d3e974 100644 --- a/src/core-plugins/linux/linux-core-modules.hh +++ b/src/core-plugins/linux/linux-core-modules.hh @@ -1,14 +1,25 @@ #pragma once -#include +#include "common.hpp" +#include -const std::string arch(); -const std::string host(); -const std::string host_name(); -const std::string host_version(); -const std::string host_vendor(); +inline utsname g_uname_infos; + +modfunc arch(); +modfunc host(); +modfunc host_name(); +modfunc host_version(); +modfunc host_vendor(); inline std::FILE *os_release; -const std::string os_name(); -const std::string os_pretty_name(); -const std::string os_name_id(); +modfunc os_name(); +modfunc os_pretty_name(); +modfunc os_name_id(); +modfunc os_version_id(); +modfunc os_version_codename(); +modfunc os_uptime(); +modfunc os_kernel_name(); +modfunc os_kernel_version(); +modfunc os_hostname(); +modfunc os_initsys_name(); +modfunc os_initsys_version(); diff --git a/src/core-plugins/linux/os.cc b/src/core-plugins/linux/os.cc index 42dfbcb9..759db887 100644 --- a/src/core-plugins/linux/os.cc +++ b/src/core-plugins/linux/os.cc @@ -1,15 +1,20 @@ #include #include #include +#include #include +#define FMT_HEADER_ONLY 1 #include "common.hpp" +#include "fmt/format.h" +#include "switch_fnv1a.hpp" +#include "util.hpp" #include "linux-core-modules.hh" static const char *read_value(const char *name, size_t n) { if (!os_release) - return strdup(UNKNOWN); + return UNKNOWN; rewind(os_release); // Reset file pointer to start char *buf = strdup(UNKNOWN); // Default value @@ -38,11 +43,111 @@ static const char *read_value(const char *name, size_t n) return buf; } -const std::string os_name() -{ return read_value("NAME=", 5); } +static unsigned long get_uptime() +{ + const std::string& buf = read_by_syspath("/proc/uptime"); + if (buf != UNKNOWN) + return std::stoul(buf.substr(0, buf.find('.'))); // 19065.18 190952.06 + + struct std::timespec uptime; + if (clock_gettime(CLOCK_BOOTTIME, &uptime) != 0) + return 0; + + return (unsigned long)uptime.tv_sec * 1000 + (unsigned long)uptime.tv_nsec / 1000000; +} + +modfunc os_name() +{ return read_value("NAME=", "NAME="_len); } + +modfunc os_pretty_name() +{ return read_value("PRETTY_NAME=", "PRETTY_NAME="_len); } + +modfunc os_name_id() +{ return read_value("ID=", "ID="_len); } + +modfunc os_version_id() +{ return read_value("VERSION_ID=", "VERSION_ID="_len); } + +modfunc os_version_codename() +{ return read_value("VERSION_CODENAME=", "VERSION_CODENAME="_len); } + +modfunc os_uptime() +{ return fmt::to_string(get_uptime()); } + +modfunc os_kernel_name() +{ return g_uname_infos.sysname; } + +modfunc os_kernel_version() +{ return g_uname_infos.release; } + +modfunc os_hostname() +{ return g_uname_infos.nodename; } + +modfunc os_initsys_name() +{ + // there's no way PID 1 doesn't exist. + // This will always succeed (because we are on linux) + std::ifstream f_initsys("/proc/1/comm", std::ios::binary); + if (!f_initsys.is_open()) + die(_("/proc/1/comm doesn't exist! (what?)")); -const std::string os_pretty_name() -{ return read_value("PRETTY_NAME=", 12); } + std::string initsys; + std::getline(f_initsys, initsys); + size_t pos = 0; + + if ((pos = initsys.find('\0')) != std::string::npos) + initsys.erase(pos); + + if ((pos = initsys.rfind('/')) != std::string::npos) + initsys.erase(0, pos + 1); + + return initsys; +} + +modfunc os_initsys_version() +{ + std::string os_initsys_version; + std::string path; + char buf[PATH_MAX]; + if (realpath(which("init").c_str(), buf)) + path = buf; + + std::ifstream f(path, std::ios::in); + std::string line; + + const std::string& name = str_tolower(os_initsys_name()); + switch (fnv1a16::hash(name)) + { + case "systemd"_fnv1a16: + case "systemctl"_fnv1a16: + { + while (read_binary_file(f, line)) + { + if (hasEnding(line, "running in %ssystem mode (%s)")) + { + os_initsys_version = line.substr("systemd "_len); + os_initsys_version.erase(os_initsys_version.find(' ')); + break; + } + } + } + break; + case "openrc"_fnv1a16: + { + std::string tmp; + while (read_binary_file(f, line)) + { + if (line == "RC_VERSION") + { + os_initsys_version = tmp; + break; + } + tmp = line; + } + } + break; + } + + return os_initsys_version; +} -const std::string os_name_id() -{ return read_value("ID=", 3); } diff --git a/src/core-plugins/linux/system.cc b/src/core-plugins/linux/system.cc index cd0cd9b8..7942cbe0 100644 --- a/src/core-plugins/linux/system.cc +++ b/src/core-plugins/linux/system.cc @@ -1,14 +1,15 @@ -#include #include #include #include #include +#include "linux-core-modules.hh" #include "common.hpp" #include "util.hpp" /* The handler that we'll use for our module, Handlers return const std::string (WILL be changed to const char pointers). */ -const std::string host() { +modfunc host() +{ const std::string syspath = "/sys/devices/virtual/dmi/id"; std::string board_name = "(unknown)"; @@ -42,7 +43,8 @@ const std::string host() { return board_vendor + ' ' + board_name + ' ' + board_version; } -const std::string host_name() { +modfunc host_name() +{ const std::string syspath = "/sys/devices/virtual/dmi/id"; if (std::filesystem::exists(syspath + "/board_name")) @@ -53,7 +55,8 @@ const std::string host_name() { return UNKNOWN; } -const std::string host_version() { +modfunc host_version() +{ const std::string syspath = "/sys/devices/virtual/dmi/id"; if (std::filesystem::exists(syspath + "/board_name")) @@ -64,7 +67,8 @@ const std::string host_version() { return UNKNOWN; } -const std::string host_vendor() { +modfunc host_vendor() +{ const std::string syspath = "/sys/devices/virtual/dmi/id"; std::string board_vendor {UNKNOWN}; @@ -83,10 +87,7 @@ const std::string host_vendor() { return board_vendor; } -const std::string arch() { - utsname sysinfo; - if (uname(&sysinfo) != 0) - die(_("uname() failed: {}\nCould not get system infos"), strerror(errno)); - - return sysinfo.machine; +modfunc arch() +{ + return g_uname_infos.machine; } diff --git a/src/main.cpp b/src/main.cpp index cd553259..89a9c273 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -790,7 +790,7 @@ int main(int argc, char *argv[]) void* cufetch_handle = LOAD_LIBRARY("libcufetch.so") if (!cufetch_handle) - die("Failed to load libcufetch! {}", dlerror()); + die("Failed to load {}", dlerror()); /* TODO(burntranch): track each library and unload them. */ const std::filesystem::path modDir = configDir / "mods"; @@ -800,13 +800,15 @@ int main(int argc, char *argv[]) debug("loading mod at {}!", entry.path().string()); void *handle = LOAD_LIBRARY(std::filesystem::absolute(entry.path()).c_str()); - if (!handle) { - warn("Failed to load mod {}! {}", entry.path(), dlerror()); + if (!handle) + { + // dlerror() is pretty formatted + warn("Failed to load mod {}", dlerror()); dlerror(); continue; } - LOAD_LIB_SYMBOL(handle, void, MOD_INIT, void*) + LOAD_LIB_SYMBOL(handle, void, start, void*) MOD_INIT(cufetch_handle); } From 60f38866f3fac48b41ef390144bd52d40ab2216e Mon Sep 17 00:00:00 2001 From: Toni500git Date: Sat, 21 Jun 2025 22:21:32 +0200 Subject: [PATCH 016/143] makefile: don't create folders for libs --- Makefile | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/Makefile b/Makefile index d30e15fb..e1fe35a6 100644 --- a/Makefile +++ b/Makefile @@ -65,33 +65,29 @@ CXXFLAGS += -fvisibility=hidden -Iinclude -std=c++20 $(VARS) -DVERSION=\" all: genver libcufetch fmt toml json core-plugins $(TARGET) libcufetch: -ifeq ($(wildcard $(BUILDDIR)/libcufetch/libcufetch.so),) - mkdir -p $(BUILDDIR)/libcufetch - make -C src/libs/cufetch BUILDDIR=$(BUILDDIR)/libcufetch +ifeq ($(wildcard $(BUILDDIR)/libcufetch.so),) + make -C src/libs/cufetch BUILDDIR=$(BUILDDIR) endif fmt: -ifeq ($(wildcard $(BUILDDIR)/fmt/libfmt.a),) - mkdir -p $(BUILDDIR)/fmt - make -C src/libs/fmt BUILDDIR=$(BUILDDIR)/fmt +ifeq ($(wildcard $(BUILDDIR)/libfmt.a),) + make -C src/libs/fmt BUILDDIR=$(BUILDDIR) endif toml: -ifeq ($(wildcard $(BUILDDIR)/toml++/toml.o),) - mkdir -p $(BUILDDIR)/toml++ - make -C src/libs/toml++ BUILDDIR=$(BUILDDIR)/toml++ +ifeq ($(wildcard $(BUILDDIR)/toml.o),) + make -C src/libs/toml++ BUILDDIR=$(BUILDDIR) endif json: -ifeq ($(wildcard $(BUILDDIR)/json/json.o),) - mkdir -p $(BUILDDIR)/json - make -C src/libs/json BUILDDIR=$(BUILDDIR)/json +ifeq ($(wildcard $(BUILDDIR)/json.o),) + make -C src/libs/json BUILDDIR=$(BUILDDIR) endif core-plugins: ifeq ($(wildcard $(BUILDDIR)/core-plugins/*.so),) mkdir -p $(BUILDDIR)/core-plugins - make -C src/core-plugins BUILDDIR=$(BUILDDIR)/core-plugins + make -C src/core-plugins BUILDDIR=$(BUILDDIR) endif genver: ./scripts/generateVersion.sh @@ -102,7 +98,7 @@ endif $(TARGET): genver fmt toml libcufetch json core-plugins $(OBJ) mkdir -p $(BUILDDIR) sh ./scripts/generateVersion.sh - $(CXX) $(OBJ) $(BUILDDIR)/toml++/toml.o $(BUILDDIR)/json/json.o -o $(BUILDDIR)/$(TARGET) $(LDFLAGS) + $(CXX) $(OBJ) $(BUILDDIR)/*.o -o $(BUILDDIR)/$(TARGET) $(LDFLAGS) cd $(BUILDDIR)/ && ln -sf $(TARGET) cufetch locale: From 0b562e7842df4b50cbcdc565b8e3743844c25d74 Mon Sep 17 00:00:00 2001 From: Toni500git Date: Sun, 22 Jun 2025 13:34:26 +0200 Subject: [PATCH 017/143] plugins: create cufetchpm --- cufetchpm/Makefile | 59 ++++++++++++++++++++++++++++++++++++++++++ cufetchpm/src/add.cpp | 7 +++++ cufetchpm/src/main.cpp | 23 ++++++++++++++++ 3 files changed, 89 insertions(+) create mode 100644 cufetchpm/Makefile create mode 100644 cufetchpm/src/add.cpp create mode 100644 cufetchpm/src/main.cpp diff --git a/cufetchpm/Makefile b/cufetchpm/Makefile new file mode 100644 index 00000000..6dd3a204 --- /dev/null +++ b/cufetchpm/Makefile @@ -0,0 +1,59 @@ +CXX ?= g++ +PREFIX ?= /usr +MANPREFIX ?= $(PREFIX)/share/man +VARS ?= -DENABLE_NLS=1 + +DEBUG ?= 1 +# https://stackoverflow.com/a/1079861 +# WAY easier way to build debug and release builds +ifeq ($(DEBUG), 1) + BUILDDIR = build/debug + CXXFLAGS := -ggdb3 -Wall -Wextra -Wpedantic -Wno-unused-parameter -DDEBUG=1 -fsanitize=address $(DEBUG_CXXFLAGS) $(CXXFLAGS) + LDFLAGS += -fsanitize=address +else + # Check if an optimization flag is not already set + ifneq ($(filter -O%,$(CXXFLAGS)),) + $(info Keeping the existing optimization flag in CXXFLAGS) + else + CXXFLAGS := -O3 $(CXXFLAGS) + endif + BUILDDIR = build/release +endif + +NAME = cufetchpm +TARGET ?= $(NAME) +OLDVERSION = 0.0.0 +VERSION = 0.0.1 +SRC = $(wildcard src/*.cpp ../src/util.cpp) +OBJ = $(SRC:.cpp=.o) +LDFLAGS += -L./$(BUILDDIR)/fmt -lfmt +CXXFLAGS ?= -mtune=generic -march=native +CXXFLAGS += -fvisibility=hidden -I../include -std=c++20 $(VARS) -DVERSION=\"$(VERSION)\" + +all: fmt toml $(TARGET) + +fmt: +ifeq ($(wildcard $(BUILDDIR)/libfmt.a),) + mkdir -p $(BUILDDIR) + make -C ../src/libs/fmt BUILDDIR=cufetchpm/$(BUILDDIR) +endif + +toml: +ifeq ($(wildcard $(BUILDDIR)/toml.o),) + mkdir -p $(BUILDDIR) + make -C ../src/libs/toml++ BUILDDIR=cufetchpm/$(BUILDDIR) +endif + +$(TARGET): fmt toml $(OBJ) + mkdir -p $(BUILDDIR) + $(CXX) $(OBJ) $(BUILDDIR)/*.o -o $(BUILDDIR)/$(TARGET) $(LDFLAGS) + +clean: + rm -rf $(BUILDDIR)/$(TARGET) $(OBJ) + +distclean: + find .. -type f -name "*.tar.gz" -exec rm -rf "{}" \; + find .. -type f -name "*.o" -exec rm -rf "{}" \; + find .. -type f -name "*.a" -exec rm -rf "{}" \; + +.PHONY: $(TARGET) fmt toml all diff --git a/cufetchpm/src/add.cpp b/cufetchpm/src/add.cpp new file mode 100644 index 00000000..3fc6f4e3 --- /dev/null +++ b/cufetchpm/src/add.cpp @@ -0,0 +1,7 @@ +#include "util.hpp" + +bool download_git(const std::string_view url) +{ + const std::string_view repo = url.substr(url.rfind('/')+1); + return taur_exec({ "git", "clone", url.data(), (getConfigDir() / "mods" / repo).string() }); +} diff --git a/cufetchpm/src/main.cpp b/cufetchpm/src/main.cpp new file mode 100644 index 00000000..33d55f42 --- /dev/null +++ b/cufetchpm/src/main.cpp @@ -0,0 +1,23 @@ +#include +#include +#include "common.hpp" +#include "fmt/base.h" + +bool download_git(const std::string_view url); + +int main (int argc, char *argv[]) +{ + if (argc > 1 && strcmp(argv[1], "add") == 0) + { + if (argc == 2) + die("please insert a git url to clone"); + + if (download_git(argv[2])) + info("plugin downloaded successfully"); + } + else + { + fmt::println("usage: cufetchpm add "); + } + return 0; +} From 466db26c5aa1922e49efab3c3ddcf275fa87b907 Mon Sep 17 00:00:00 2001 From: Toni500git Date: Sun, 22 Jun 2025 17:00:32 +0200 Subject: [PATCH 018/143] core-plugins: linux: add the complete modules list from cpu --- src/core-plugins/linux/cpu.cc | 133 +++++++++++++++++++ src/core-plugins/linux/linux-core-modules.cc | 60 ++++++++- src/core-plugins/linux/linux-core-modules.hh | 13 +- 3 files changed, 199 insertions(+), 7 deletions(-) create mode 100644 src/core-plugins/linux/cpu.cc diff --git a/src/core-plugins/linux/cpu.cc b/src/core-plugins/linux/cpu.cc new file mode 100644 index 00000000..455933e0 --- /dev/null +++ b/src/core-plugins/linux/cpu.cc @@ -0,0 +1,133 @@ +#include +#include +#include "common.hpp" +#include "fmt/format.h" +#include "linux-core-modules.hh" +#include "util.hpp" + +const std::string freq_dir = "/sys/devices/system/cpu/cpu0/cpufreq"; + +static char *trim_whitespace(char *str) +{ + if (!str) return NULL; + + // Trim leading whitespace + while (isspace((unsigned char)*str)) str++; + + // If all spaces + if (*str == '\0') return strdup(""); + + // Trim trailing whitespace + char *end = str + strlen(str) - 1; + while (end > str && isspace((unsigned char)*end)) end--; + + *(end + 1) = '\0'; + return strdup(str); +} + +static char *read_value(const char *name, size_t n, bool do_rewind) +{ + if (!cpuinfo) + return NULL; + if (do_rewind) + rewind(cpuinfo); + + char *line = NULL; + size_t len = 0; + char *value = NULL; + + while (getline(&line, &len, cpuinfo) != -1) + { + if (strncmp(line, name, n) != 0) + continue; + + char *colon = strchr(line, ':'); + if (!colon) + continue; + + value = trim_whitespace(colon + 1); + break; + } + + free(line); + return value; +} + +float cpu_temp() +{ + for (const auto& dir : std::filesystem::directory_iterator{ "/sys/class/hwmon/" }) + { + const std::string& name = read_by_syspath((dir.path() / "name").string()); + debug("name = {}", name); + if (name != "cpu" && name != "k10temp" && name != "coretemp") + continue; + + const std::string& temp_file = (access((dir.path() / "temp1_input").string().c_str(), F_OK) != 0) + ? dir.path() / "device/temp1_input" + : dir.path() / "temp1_input"; + if (access(temp_file.c_str(), F_OK) != 0) + continue; + + const float ret = std::stof(read_by_syspath(temp_file)); + debug("cpu temp ret = {}", ret); + + return ret / 1000.0f; + } + return 0.0f; +} + +modfunc cpu_name() +{ + char *name = read_value("model name", "model name"_len, true); + if (!name) return UNKNOWN; + + char *at = strrchr(name, '@'); + if (!at) return name; + + // sometimes /proc/cpuinfo at model name + // the name will contain the min freq + // happens on intel cpus especially + if (at > name && *(at - 1) == ' ') + *(at - 1) = '\0'; + else + *at = '\0'; + + return name; +} + +modfunc cpu_nproc() +{ + uint nproc = 0; + rewind(cpuinfo); + while (read_value("processor", "processor"_len, false)) + ++nproc; + return fmt::to_string(nproc); +} + +modfunc cpu_freq_cur() +{ + if (access((freq_dir + "/scaling_cur_freq").c_str(), F_OK) != 0) + return "0"; + return fmt::format("{:.2f}", std::stof(read_by_syspath(freq_dir + "/scaling_cur_freq")) / 1000000); +} + +modfunc cpu_freq_max() +{ + if (access((freq_dir + "/scaling_max_freq").c_str(), F_OK) != 0) + return "0"; + return fmt::format("{:.2f}", std::stof(read_by_syspath(freq_dir + "/scaling_max_freq")) / 1000000); +} + +modfunc cpu_freq_min() +{ + if (access((freq_dir + "/scaling_min_freq").c_str(), F_OK) != 0) + return "0"; + return fmt::format("{:.2f}", std::stof(read_by_syspath(freq_dir + "/scaling_min_freq")) / 1000000); +} + +modfunc cpu_freq_bios() +{ + if (access((freq_dir + "/bios_limit").c_str(), F_OK) != 0) + return "0"; + return fmt::format("{:.2f}", std::stof(read_by_syspath(freq_dir + "/bios_limit")) / 1000000); +} diff --git a/src/core-plugins/linux/linux-core-modules.cc b/src/core-plugins/linux/linux-core-modules.cc index 310e1643..047990eb 100644 --- a/src/core-plugins/linux/linux-core-modules.cc +++ b/src/core-plugins/linux/linux-core-modules.cc @@ -1,6 +1,7 @@ #include #include "linux-core-modules.hh" #include "common.hpp" +#include "fmt/format.h" APICALL EXPORT MOD_INIT(void *handle) { @@ -16,8 +17,8 @@ APICALL EXPORT MOD_INIT(void *handle) die(_("uname() failed: {}\nCould not get system infos"), strerror(errno)); os_release = fopen("/etc/os-release", "r"); + cpuinfo = fopen("/proc/cpuinfo", "r"); - // $ module_t os_name_pretty_module = {"pretty", {}, os_pretty_name}; module_t os_name_id_module = {"id", {}, os_name_id}; module_t os_name_module = { "name", { @@ -25,13 +26,9 @@ APICALL EXPORT MOD_INIT(void *handle) std::move(os_name_id_module) }, os_name }; - // $ module_t os_uptime_module = {"uptime", {}, os_uptime}; - - // $ module_t os_hostname_module = {"hostname", {}, os_hostname}; - // $ module_t os_kernel_name_module = {"name", {}, os_kernel_name}; module_t os_kernel_version_module = {"version", {}, os_kernel_version}; module_t os_kernel_module = {"kernel", { @@ -39,7 +36,6 @@ APICALL EXPORT MOD_INIT(void *handle) std::move(os_kernel_version_module) }, []() {return os_kernel_name() + ' ' + os_kernel_version();}}; - // $ module_t os_initsys_name_module = {"name", {}, os_initsys_name}; module_t os_initsys_version_module = {"version", {}, os_initsys_version}; module_t os_initsys_module = {"initsys", { @@ -94,4 +90,56 @@ APICALL EXPORT MOD_INIT(void *handle) }, NULL }; cfRegisterModule(system_module); + + // $ + module_t cpu_name_module = {"name", {}, cpu_name}; + module_t cpu_nproc_module = {"nproc" , {}, cpu_nproc}; + + module_t cpu_freq_cur_module = {"current", {}, cpu_freq_cur}; + module_t cpu_freq_max_module = {"max", {}, cpu_freq_max}; + module_t cpu_freq_min_module = {"min", {}, cpu_freq_min}; + module_t cpu_freq_bios_module = {"bios_limit", {}, cpu_freq_bios}; + module_t cpu_freq_module = {"freq", { + std::move(cpu_freq_cur_module), + std::move(cpu_freq_max_module), + std::move(cpu_freq_min_module), + std::move(cpu_freq_bios_module), + }, cpu_freq_max}; + + module_t cpu_temp_C_module = {"C", {}, []() {return fmt::format("{:.2f}°C", cpu_temp());}}; + module_t cpu_temp_F_module = {"F", {}, []() {return fmt::format("{:.2f}°F", cpu_temp() * 1.8 + 34);}}; + module_t cpu_temp_K_module = {"K", {}, []() {return fmt::format("{:.2f}°K", cpu_temp() + 273.15);}}; + module_t cpu_temp_module = {"temp", { + std::move(cpu_temp_C_module), + std::move(cpu_temp_F_module), + std::move(cpu_temp_K_module), + }, []() {return fmt::format("{:.2f}°C", cpu_temp());}}; + + /* Only for compatibility */ + module_t cpu_freq_cur_module_compat = {"freq_cur", {}, cpu_freq_cur}; + module_t cpu_freq_max_module_compat = {"freq_max", {}, cpu_freq_max}; + module_t cpu_freq_min_module_compat = {"freq_min", {}, cpu_freq_min}; + module_t cpu_freq_bios_module_compat = {"freq_bios_limit", {}, cpu_freq_bios}; + module_t cpu_temp_C_module_compat = {"temp_C", {}, []() {return fmt::format("{:.2f}", cpu_temp());}}; + module_t cpu_temp_F_module_compat = {"temp_F", {}, []() {return fmt::format("{:.2f}", cpu_temp() * 1.8 + 34);}}; + module_t cpu_temp_K_module_compat = {"temp_K", {}, []() {return fmt::format("{:.2f}", cpu_temp() + 273.15);}}; + + module_t cpu_module = {"cpu", { + std::move(cpu_name_module), + std::move(cpu_nproc_module), + std::move(cpu_freq_module), + std::move(cpu_temp_module), + + std::move(cpu_freq_cur_module_compat), + std::move(cpu_freq_max_module_compat), + std::move(cpu_freq_min_module_compat), + std::move(cpu_freq_bios_module_compat), + std::move(cpu_temp_C_module_compat), + std::move(cpu_temp_F_module_compat), + std::move(cpu_temp_K_module_compat), + }, []() { + return fmt::format("{} ({}) @ {} GHz", cpu_name(), cpu_nproc(), cpu_freq_max()); + }}; + + cfRegisterModule(cpu_module); } diff --git a/src/core-plugins/linux/linux-core-modules.hh b/src/core-plugins/linux/linux-core-modules.hh index 74d3e974..60e595db 100644 --- a/src/core-plugins/linux/linux-core-modules.hh +++ b/src/core-plugins/linux/linux-core-modules.hh @@ -3,14 +3,15 @@ #include "common.hpp" #include +// system.cc inline utsname g_uname_infos; - modfunc arch(); modfunc host(); modfunc host_name(); modfunc host_version(); modfunc host_vendor(); +// os.cc inline std::FILE *os_release; modfunc os_name(); modfunc os_pretty_name(); @@ -23,3 +24,13 @@ modfunc os_kernel_version(); modfunc os_hostname(); modfunc os_initsys_name(); modfunc os_initsys_version(); + +// cpu.cc +inline std::FILE *cpuinfo; +modfunc cpu_freq_cur(); +modfunc cpu_freq_max(); +modfunc cpu_freq_min(); +modfunc cpu_freq_bios(); +float cpu_temp(); +modfunc cpu_nproc(); +modfunc cpu_name(); From e653c45c2e4a6e540a3af4bcef3d4bff71bdf628 Mon Sep 17 00:00:00 2001 From: Toni500git Date: Sun, 22 Jun 2025 19:21:25 +0200 Subject: [PATCH 019/143] clang-format --- src/core-plugins/linux/cpu.cc | 38 +++++++++++++++++++------------- src/core-plugins/linux/os.cc | 25 +++++++++++---------- src/core-plugins/linux/system.cc | 20 +++++++++-------- src/libs/cufetch/cufetch.cc | 28 +++++++++++------------ 4 files changed, 60 insertions(+), 51 deletions(-) diff --git a/src/core-plugins/linux/cpu.cc b/src/core-plugins/linux/cpu.cc index 455933e0..4552f452 100644 --- a/src/core-plugins/linux/cpu.cc +++ b/src/core-plugins/linux/cpu.cc @@ -1,5 +1,7 @@ #include + #include + #include "common.hpp" #include "fmt/format.h" #include "linux-core-modules.hh" @@ -7,41 +9,45 @@ const std::string freq_dir = "/sys/devices/system/cpu/cpu0/cpufreq"; -static char *trim_whitespace(char *str) +static char* trim_whitespace(char* str) { - if (!str) return NULL; + if (!str) + return NULL; // Trim leading whitespace - while (isspace((unsigned char)*str)) str++; + while (isspace((unsigned char)*str)) + str++; // If all spaces - if (*str == '\0') return strdup(""); + if (*str == '\0') + return strdup(""); // Trim trailing whitespace - char *end = str + strlen(str) - 1; - while (end > str && isspace((unsigned char)*end)) end--; + char* end = str + strlen(str) - 1; + while (end > str && isspace((unsigned char)*end)) + end--; *(end + 1) = '\0'; return strdup(str); } -static char *read_value(const char *name, size_t n, bool do_rewind) +static char* read_value(const char* name, size_t n, bool do_rewind) { if (!cpuinfo) return NULL; if (do_rewind) rewind(cpuinfo); - char *line = NULL; - size_t len = 0; - char *value = NULL; + char* line = NULL; + size_t len = 0; + char* value = NULL; while (getline(&line, &len, cpuinfo) != -1) { if (strncmp(line, name, n) != 0) continue; - char *colon = strchr(line, ':'); + char* colon = strchr(line, ':'); if (!colon) continue; @@ -78,11 +84,13 @@ float cpu_temp() modfunc cpu_name() { - char *name = read_value("model name", "model name"_len, true); - if (!name) return UNKNOWN; + char* name = read_value("model name", "model name"_len, true); + if (!name) + return UNKNOWN; - char *at = strrchr(name, '@'); - if (!at) return name; + char* at = strrchr(name, '@'); + if (!at) + return name; // sometimes /proc/cpuinfo at model name // the name will contain the min freq diff --git a/src/core-plugins/linux/os.cc b/src/core-plugins/linux/os.cc index 759db887..e8c05e49 100644 --- a/src/core-plugins/linux/os.cc +++ b/src/core-plugins/linux/os.cc @@ -1,38 +1,40 @@ +#include #include #include -#include #include #include #define FMT_HEADER_ONLY 1 #include "common.hpp" #include "fmt/format.h" +#include "linux-core-modules.hh" #include "switch_fnv1a.hpp" #include "util.hpp" -#include "linux-core-modules.hh" -static const char *read_value(const char *name, size_t n) +static const char* read_value(const char* name, size_t n) { if (!os_release) return UNKNOWN; - rewind(os_release); // Reset file pointer to start + rewind(os_release); // Reset file pointer to start - char *buf = strdup(UNKNOWN); // Default value - char *line = NULL; - size_t len = 0; + char* buf = strdup(UNKNOWN); // Default value + char* line = NULL; + size_t len = 0; while (getline(&line, &len, os_release) != -1) { if (strncmp(line, name, n) != 0) continue; // Find the first quote after the key - char *start = strchr(line + n, '"'); - if (!start) continue; + char* start = strchr(line + n, '"'); + if (!start) + continue; start++; // Find the closing quote - char *end = strrchr(start, '"'); - if (!end) continue; + char* end = strrchr(start, '"'); + if (!end) + continue; free(buf); buf = strndup(start, end - start); @@ -150,4 +152,3 @@ modfunc os_initsys_version() return os_initsys_version; } - diff --git a/src/core-plugins/linux/system.cc b/src/core-plugins/linux/system.cc index 7942cbe0..34649738 100644 --- a/src/core-plugins/linux/system.cc +++ b/src/core-plugins/linux/system.cc @@ -1,26 +1,28 @@ -#include #include + +#include #include #include -#include "linux-core-modules.hh" #include "common.hpp" +#include "linux-core-modules.hh" #include "util.hpp" -/* The handler that we'll use for our module, Handlers return const std::string (WILL be changed to const char pointers). */ +/* The handler that we'll use for our module, Handlers return const std::string (WILL be changed to const char + * pointers). */ modfunc host() { const std::string syspath = "/sys/devices/virtual/dmi/id"; - std::string board_name = "(unknown)"; + std::string board_name = "(unknown)"; std::string board_version = "(unknown)"; - std::string board_vendor = "(unknown)"; + std::string board_vendor = "(unknown)"; if (std::filesystem::exists(syspath + "/board_name")) { - board_name = read_by_syspath(syspath + "/board_name"); - board_version = read_by_syspath(syspath + "/board_version"); - board_vendor = read_by_syspath(syspath + "/board_vendor"); + board_name = read_by_syspath(syspath + "/board_name"); + board_version = read_by_syspath(syspath + "/board_version"); + board_vendor = read_by_syspath(syspath + "/board_vendor"); if (board_vendor == "Micro-Star International Co., Ltd.") board_vendor = "MSI"; @@ -71,7 +73,7 @@ modfunc host_vendor() { const std::string syspath = "/sys/devices/virtual/dmi/id"; - std::string board_vendor {UNKNOWN}; + std::string board_vendor{ UNKNOWN }; if (std::filesystem::exists(syspath + "/board_name")) { diff --git a/src/libs/cufetch/cufetch.cc b/src/libs/cufetch/cufetch.cc index eae0f624..15422bfa 100644 --- a/src/libs/cufetch/cufetch.cc +++ b/src/libs/cufetch/cufetch.cc @@ -4,25 +4,23 @@ static std::vector modules; -/* TODO: can we customize the separator perhaps? */ static char separator = '.'; extern "C" { - static void addModule(const module_t &module, const std::string &prefix = "") { - modules.emplace_back(module).name = prefix + module.name; - - for (const module_t &submodule : module.submodules) { - addModule(submodule, prefix + module.name + separator); - } - } +static void addModule(const module_t& module, const std::string& prefix = "") +{ + modules.emplace_back(module).name = prefix + module.name; - /* Register a module, and its submodules, to customfetch. */ - [[gnu::unused]] void cfRegisterModule(const module_t &module) { - addModule(module); + for (const module_t& submodule : module.submodules) + { + addModule(submodule, prefix + module.name + separator); } +} + +/* Register a module, and its submodules, to customfetch. */ +[[gnu::unused]] void cfRegisterModule(const module_t& module) { addModule(module); } + +/* Get a list of all modules registered. */ +[[gnu::unused]] const std::vector& cfGetModules() { return modules; } - /* Get a list of all modules registered. */ - [[gnu::unused]] const std::vector &cfGetModules() { - return modules; - } } From 5fbbd8aa82de7e108bb54552f0d297606b97a39d Mon Sep 17 00:00:00 2001 From: Toni500git Date: Sun, 22 Jun 2025 20:40:05 +0200 Subject: [PATCH 020/143] core-plugins: linux: fix memory leaks --- src/core-plugins/linux/cpu.cc | 88 ++++++++++++++++++++--------------- src/core-plugins/linux/os.cc | 19 ++++---- src/main.cpp | 9 ++++ 3 files changed, 68 insertions(+), 48 deletions(-) diff --git a/src/core-plugins/linux/cpu.cc b/src/core-plugins/linux/cpu.cc index 4552f452..47c43b69 100644 --- a/src/core-plugins/linux/cpu.cc +++ b/src/core-plugins/linux/cpu.cc @@ -9,54 +9,58 @@ const std::string freq_dir = "/sys/devices/system/cpu/cpu0/cpufreq"; -static char* trim_whitespace(char* str) +static void trim(char* str) { - if (!str) - return NULL; - - // Trim leading whitespace - while (isspace((unsigned char)*str)) - str++; - - // If all spaces - if (*str == '\0') - return strdup(""); - - // Trim trailing whitespace - char* end = str + strlen(str) - 1; - while (end > str && isspace((unsigned char)*end)) - end--; - - *(end + 1) = '\0'; - return strdup(str); + if (!str) return; + + // Trim leading space + char *p = str; + while (isspace((unsigned char)*p)) + ++p; + memmove(str, p, strlen(p) + 1); + + // Trim trailing space + p = str + strlen(str) - 1; + while (p >= str && isspace((unsigned char)*p)) + --p; + p[1] = '\0'; } -static char* read_value(const char* name, size_t n, bool do_rewind) +static bool read_value(const char* name, size_t n, bool do_rewind, char* buf, size_t buf_size) { - if (!cpuinfo) - return NULL; + if (!cpuinfo || !buf || !buf_size) + return false; if (do_rewind) rewind(cpuinfo); - char* line = NULL; - size_t len = 0; - char* value = NULL; - + char* line = NULL; + size_t len = 0; + bool found = false; while (getline(&line, &len, cpuinfo) != -1) { - if (strncmp(line, name, n) != 0) + if (strncmp(line, name, n)) continue; - + char* colon = strchr(line, ':'); if (!colon) continue; - value = trim_whitespace(colon + 1); + // Extract and trim value + char* val = colon + 1; + while (isspace((unsigned char)*val)) + ++val; + trim(val); + + // Safe copy to buffer + strncpy(buf, val, buf_size - 1); + buf[buf_size - 1] = '\0'; + + found = true; break; } free(line); - return value; + return found; } float cpu_temp() @@ -84,31 +88,39 @@ float cpu_temp() modfunc cpu_name() { - char* name = read_value("model name", "model name"_len, true); - if (!name) + char name[4096]; + if (!read_value("model name", "model name"_len, true, name, sizeof(name))) return UNKNOWN; - char* at = strrchr(name, '@'); - if (!at) - return name; - // sometimes /proc/cpuinfo at model name // the name will contain the min freq // happens on intel cpus especially + char* at = strrchr(name, '@'); + if (!at) + return name; if (at > name && *(at - 1) == ' ') *(at - 1) = '\0'; else *at = '\0'; + trim(name); return name; } + modfunc cpu_nproc() { uint nproc = 0; rewind(cpuinfo); - while (read_value("processor", "processor"_len, false)) - ++nproc; + + char* line = NULL; + size_t len = 0; + while (getline(&line, &len, cpuinfo) != -1) + { + if (strncmp(line, "processor", "processor"_len) == 0) + nproc++; + } + free(line); return fmt::to_string(nproc); } diff --git a/src/core-plugins/linux/os.cc b/src/core-plugins/linux/os.cc index e8c05e49..64d31f7f 100644 --- a/src/core-plugins/linux/os.cc +++ b/src/core-plugins/linux/os.cc @@ -11,38 +11,37 @@ #include "switch_fnv1a.hpp" #include "util.hpp" -static const char* read_value(const char* name, size_t n) +static std::string read_value(const char* name, size_t n) { if (!os_release) return UNKNOWN; - rewind(os_release); // Reset file pointer to start - char* buf = strdup(UNKNOWN); // Default value - char* line = NULL; - size_t len = 0; + rewind(os_release); + + std::string result{UNKNOWN}; + char* line = nullptr; + size_t len = 0; + while (getline(&line, &len, os_release) != -1) { if (strncmp(line, name, n) != 0) continue; - // Find the first quote after the key char* start = strchr(line + n, '"'); if (!start) continue; start++; - // Find the closing quote char* end = strrchr(start, '"'); if (!end) continue; - free(buf); - buf = strndup(start, end - start); + result.assign(start, end - start); break; } free(line); - return buf; + return result; } static unsigned long get_uptime() diff --git a/src/main.cpp b/src/main.cpp index 89a9c273..a422e397 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -45,6 +45,10 @@ #include "switch_fnv1a.hpp" #include "util.hpp" +#if CF_LINUX +# include "core-plugins/linux/linux-core-modules.hh" +#endif + #if (!__has_include("version.h")) # error "version.h not found, please generate it with ./scripts/generateVersion.sh" #else @@ -901,6 +905,11 @@ int main(int argc, char *argv[]) if (!config.wrap_lines) enable_cursor(); +#if CF_LINUX + if (os_release) fclose(os_release); + if (cpuinfo) fclose(cpuinfo); +#endif + UNLOAD_LIBRARY(cufetch_handle); return 0; From c9cdd9ab23c4da0814e524e866620ee3967a26ac Mon Sep 17 00:00:00 2001 From: BurntRanch <69512353+BurntRanch@users.noreply.github.com> Date: Mon, 23 Jun 2025 00:08:43 +0300 Subject: [PATCH 021/143] compile: fix compile error --- src/display.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/display.cpp b/src/display.cpp index 1aa1fd9a..b5257e48 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -239,7 +239,7 @@ std::vector Display::render(const Config& config, const colors_t& c { file.open(path.string(), std::ios::binary); if (!file.is_open()) - die(_("Could not open logo file '{}'"), path); + die(_("Could not open logo file '{}'"), path.string()); // first check if the file is an image // without even using the same library that "file" uses From 90a320af21666381d6cb0c0161137a5620f7fb28 Mon Sep 17 00:00:00 2001 From: Toni500git Date: Mon, 23 Jun 2025 00:13:27 +0200 Subject: [PATCH 022/143] core-plugins: linux: add some modules list from user wm_name, wm_version, de_name are the remaining ones --- src/core-plugins/Makefile | 2 +- src/core-plugins/linux/linux-core-modules.cc | 55 +++++ src/core-plugins/linux/linux-core-modules.hh | 16 +- src/core-plugins/linux/user.cc | 234 +++++++++++++++++++ src/core-plugins/linux/utils | 1 + src/query/linux/user.cpp | 1 + 6 files changed, 307 insertions(+), 2 deletions(-) create mode 100644 src/core-plugins/linux/user.cc create mode 120000 src/core-plugins/linux/utils diff --git a/src/core-plugins/Makefile b/src/core-plugins/Makefile index 6250c8f5..7c44270b 100644 --- a/src/core-plugins/Makefile +++ b/src/core-plugins/Makefile @@ -8,7 +8,7 @@ OBJ = $(SRC:.cc=.o) all: linux-core-modules linux-core-modules: - $(CXX) $(CXX_INCLUDES) $(CXX_FLAGS) linux/*.cc ../util.cpp -o $@.so + $(CXX) $(CXX_INCLUDES) $(CXX_FLAGS) linux/*.cc linux/utils/*.cpp ../util.cpp -o $@.so mv -f $@.so ../../$(BUILDDIR)/core-plugins/$@.so clean: diff --git a/src/core-plugins/linux/linux-core-modules.cc b/src/core-plugins/linux/linux-core-modules.cc index 047990eb..aba69e8e 100644 --- a/src/core-plugins/linux/linux-core-modules.cc +++ b/src/core-plugins/linux/linux-core-modules.cc @@ -1,10 +1,14 @@ #include +#include +#include #include "linux-core-modules.hh" #include "common.hpp" #include "fmt/format.h" +#include "util.hpp" APICALL EXPORT MOD_INIT(void *handle) { + // INIT STUFF if (!handle) { error("Exiting because !handle"); @@ -16,9 +20,20 @@ APICALL EXPORT MOD_INIT(void *handle) if (uname(&g_uname_infos) != 0) die(_("uname() failed: {}\nCould not get system infos"), strerror(errno)); + if (g_pwd = getpwuid(getuid()), !g_pwd) + die(_("getpwent failed: {}\nCould not get user infos"), std::strerror(errno)); + + term_pid = get_terminal_pid(); + term_name = get_terminal_name(); + if (hasStart(str_tolower(term_name), "login") || hasStart(term_name, "init") || hasStart(term_name, "(init)")) + { + is_tty = true; + term_name = ttyname(STDIN_FILENO); + } os_release = fopen("/etc/os-release", "r"); cpuinfo = fopen("/proc/cpuinfo", "r"); + // MODULES REGISTERING module_t os_name_pretty_module = {"pretty", {}, os_pretty_name}; module_t os_name_id_module = {"id", {}, os_name_id}; module_t os_name_module = { "name", { @@ -142,4 +157,44 @@ APICALL EXPORT MOD_INIT(void *handle) }}; cfRegisterModule(cpu_module); + + // $ + module_t user_name_module = {"name", {}, user_name}; + + module_t user_shell_path_module = {"path", {}, user_shell_path}; + module_t user_shell_name_module = {"name", {}, user_shell_name}; + module_t user_shell_version_module = {"version", {}, user_shell_version}; + module_t user_shell_module = {"shell", { + std::move(user_shell_name_module), + std::move(user_shell_path_module), + std::move(user_shell_version_module), + }, []() {return user_shell_name() + ' ' + user_shell_version();}}; + + module_t user_term_name_module = {"name", {}, user_term_name}; + module_t user_term_version_module = {"version", {}, user_shell_version}; + module_t user_term_module = {"terminal", { + std::move(user_term_version_module), + std::move(user_term_name_module) + }, []() {return user_term_name() + ' ' + user_term_version();}}; + + /* Only for compatibility */ + module_t user_shell_path_module_compat = {"shell_path", {}, user_shell_path}; + module_t user_shell_name_module_compat = {"shell_name", {}, user_shell_name}; + module_t user_shell_version_module_compat = {"shell_version", {}, user_shell_version}; + module_t user_term_name_module_compat = {"terminal_name", {}, user_term_name}; + module_t user_term_version_module_compat = {"terminal_version", {}, user_shell_version}; + + module_t user_module = {"user", { + std::move(user_name_module), + std::move(user_shell_module), + std::move(user_term_module), + + std::move(user_shell_name_module_compat), + std::move(user_shell_path_module_compat), + std::move(user_shell_version_module_compat), + std::move(user_term_version_module_compat), + std::move(user_term_name_module_compat) + }, NULL}; + + cfRegisterModule(user_module); } diff --git a/src/core-plugins/linux/linux-core-modules.hh b/src/core-plugins/linux/linux-core-modules.hh index 60e595db..58ca6a43 100644 --- a/src/core-plugins/linux/linux-core-modules.hh +++ b/src/core-plugins/linux/linux-core-modules.hh @@ -1,6 +1,7 @@ #pragma once #include "common.hpp" +#include #include // system.cc @@ -31,6 +32,19 @@ modfunc cpu_freq_cur(); modfunc cpu_freq_max(); modfunc cpu_freq_min(); modfunc cpu_freq_bios(); -float cpu_temp(); +float cpu_temp(); modfunc cpu_nproc(); modfunc cpu_name(); + +// user.cc +inline struct passwd* g_pwd; +inline bool is_tty = false; +inline std::string term_pid, term_name; +std::string get_terminal_name(); +std::string get_terminal_pid(); +modfunc user_name(); +modfunc user_shell_path(); +modfunc user_shell_name(); +modfunc user_shell_version(); +modfunc user_term_name(); +modfunc user_term_version(); diff --git a/src/core-plugins/linux/user.cc b/src/core-plugins/linux/user.cc new file mode 100644 index 00000000..5472d2a5 --- /dev/null +++ b/src/core-plugins/linux/user.cc @@ -0,0 +1,234 @@ +#include +#include +#include "common.hpp" +#include "fmt/format.h" +#include "linux-core-modules.hh" +#include "switch_fnv1a.hpp" +#include "utils/term.hpp" +#include "util.hpp" + +// clang-format off +static std::string get_term_name_env(bool get_default = false) +{ + if (getenv("SSH_TTY") != NULL) + return getenv("SSH_TTY"); + + if (getenv("KITTY_PID") != NULL || + getenv("KITTY_INSTALLATION_DIR") != NULL || + getenv("KITTY_PUBLIC_KEY") != NULL || + getenv("KITTY_WINDOW_ID") != NULL) + return "kitty"; + + if (getenv("ALACRITTY_SOCKET") != NULL || + getenv("ALACRITTY_LOG") != NULL || + getenv("ALACRITTY_WINDOW_ID") != NULL) + return "alacritty"; + + if (getenv("TERMUX_VERSION") != NULL || + getenv("TERMUX_MAIN_PACKAGE_FORMAT") != NULL) + return "com.termux"; + + if(getenv("KONSOLE_VERSION") != NULL) + return "konsole"; + + if (getenv("GNOME_TERMINAL_SCREEN") != NULL || + getenv("GNOME_TERMINAL_SERVICE") != NULL) + return "gnome-terminal"; + + if (get_default) + { + char *env = getenv("TERM_PROGRAM"); + if (env != NULL) + { + if (hasStart(env, "Apple")) + return "Apple Terminal"; + + return env; + } + + env = getenv("TERM"); + if (env != NULL) + return env; + } + + return UNKNOWN; +} +// clang-format on + + +modfunc user_name() +{ return g_pwd->pw_name; } + +modfunc user_shell_path() +{ return g_pwd->pw_shell; } + +modfunc user_shell_name() +{ + return user_shell_path().substr(user_shell_path().rfind('/') + 1); +} + +modfunc user_shell_version() +{ + const std::string& shell_name = user_shell_name(); + std::string ret; + + if (shell_name == "nu") + ret = read_shell_exec("nu -c \"version | get version\""); + else + ret = read_shell_exec(fmt::format("{} -c 'echo \"${}_VERSION\"'", shell_name, str_toupper(shell_name.data()))); + + strip(ret); + return ret; +} + +std::string get_terminal_pid() +{ + // customfetch -> shell -> terminal + const pid_t ppid = getppid(); + std::ifstream ppid_f(fmt::format("/proc/{}/status", ppid), std::ios::in); + std::string line, term_pid{ "0" }; + while (std::getline(ppid_f, line)) + { + if (hasStart(line, "PPid:")) + { + term_pid = line.substr("PPid:"_len); + strip(term_pid); + break; + } + } + debug("term_pid = {}", term_pid); + + if (std::stoi(term_pid) < 1) + return MAGIC_LINE; + + return term_pid; +} + +std::string get_terminal_name() +{ + if (term_pid == MAGIC_LINE) + return MAGIC_LINE; + + std::ifstream f("/proc/" + term_pid + "/comm", std::ios::in); + std::string term_name; + if (f.is_open()) + std::getline(f, term_name); + else + term_name = get_term_name_env(true); + + return term_name; +} + +modfunc user_term_name() +{ + // st (suckless terminal) + if (term_name == "exe") + term_name = "st"; + // either gnome-console or "gnome-terminal-" + // I hope this is not super stupid + else if (hasStart(term_name, "gnome-console")) + term_name.erase("gnome-console"_len + 1); + else if (hasStart(term_name, "gnome-terminal")) + term_name.erase("gnome-terminal"_len + 1); + + const std::string& osname = os_name(); + // let's try to get the real terminal name + // on NixOS, instead of returning the -wrapped name. + // tested on gnome-console, kitty, st and alacritty + // hope now NixOS users will know the terminal they got, along the version if possible + if (osname.find("NixOS") != osname.npos || (hasEnding(term_name, "wrapped") && which("nix") != UNKNOWN)) + { + // /nix/store/sha256string-gnome-console-0.31.0/bin/.kgx-wrapped + char buf[PATH_MAX]; + std::string tmp_name = realpath(("/proc/" + term_pid + "/exe").c_str(), buf); + + size_t pos; + if ((pos = tmp_name.find('-')) != std::string::npos) + tmp_name.erase(0, pos + 1); // gnome-console-0.31.0/bin/.kgx-wrapped + + if ((pos = tmp_name.find('/')) != std::string::npos) + tmp_name.erase(pos); // gnome-console-0.31.0 + + if ((pos = tmp_name.rfind('-')) != std::string::npos) + tmp_name.erase(pos); // gnome-console EZ + + term_name = tmp_name; + } + + // sometimes may happen that the terminal name from /comm + // at the end has some letfover characters from /cmdline + if (!std::isalnum(term_name.back())) + { + size_t i = term_name.size(); + while (i > 0) + { + char ch = term_name[i - 1]; + // stop when we find an a num or alpha char + // example with "gnome-terminal-" + if (std::isalnum(static_cast(ch))) + break; + term_name.erase(--i, 1); + } + } + + return term_name; +} + +modfunc user_term_version() +{ + const std::string& term_name = user_term_name(); + if (term_name.empty()) + return UNKNOWN; + + bool remove_term_name = true; + std::string ret; + + switch (fnv1a16::hash(str_tolower(term_name.data()))) + { + case "st"_fnv1a16: + if (fast_detect_st_ver(ret)) + remove_term_name = false; + break; + + case "konsole"_fnv1a16: + if (fast_detect_konsole_ver(ret)) + remove_term_name = false; + break; + + case "xterm"_fnv1a16: get_term_version_exec(term_name, ret, true); break; + + default: get_term_version_exec(term_name, ret); + } + + debug("get_term_version ret = {}", ret); + + if (ret.empty()) + return UNKNOWN; + + if (hasStart(ret, "# GNOME")) + { + if (hasStart(ret, "# GNOME Console ")) + ret.erase(0, "# GNOME Console"_len); + else if (hasStart(ret, "# GNOME Terminal ")) + ret.erase(0, "# GNOME Terminal "_len); + debug("gnome ret = {}", ret); + remove_term_name = false; + } + // Xterm(388) + else if (term_name == "xterm") + { + ret.erase(0, term_name.length() + 1); // 388) + ret.pop_back(); // 388 + return ret; + } + + if (remove_term_name) + ret.erase(0, term_name.length() + 1); + + const size_t pos = ret.find(' '); + if (pos != std::string::npos) + ret.erase(pos); + + debug("get_term_version ret after = {}", ret); + return ret; +} diff --git a/src/core-plugins/linux/utils b/src/core-plugins/linux/utils new file mode 120000 index 00000000..eae0d984 --- /dev/null +++ b/src/core-plugins/linux/utils @@ -0,0 +1 @@ +../../query/linux/utils \ No newline at end of file diff --git a/src/query/linux/user.cpp b/src/query/linux/user.cpp index 0560fe4b..599ae8cf 100644 --- a/src/query/linux/user.cpp +++ b/src/query/linux/user.cpp @@ -58,6 +58,7 @@ * func = the function name * ... = the arguments in a function if any */ +#undef LOAD_LIB_SYMBOL #define LOAD_LIB_SYMBOL(ret_type, func, ...) \ typedef ret_type (*func##_t)(__VA_ARGS__); \ func##_t func = reinterpret_cast(dlsym(handle, #func)); From 44f3efaa997079046671f3f97485129036376662 Mon Sep 17 00:00:00 2001 From: Toni500git Date: Mon, 23 Jun 2025 12:13:34 +0200 Subject: [PATCH 023/143] core-plugins: linux: add remaining modules from user --- src/core-plugins/linux/linux-core-modules.cc | 26 ++- src/core-plugins/linux/linux-core-modules.hh | 6 +- src/core-plugins/linux/user.cc | 192 ++++++++++++++++++- 3 files changed, 220 insertions(+), 4 deletions(-) diff --git a/src/core-plugins/linux/linux-core-modules.cc b/src/core-plugins/linux/linux-core-modules.cc index aba69e8e..cfd78022 100644 --- a/src/core-plugins/linux/linux-core-modules.cc +++ b/src/core-plugins/linux/linux-core-modules.cc @@ -177,23 +177,47 @@ APICALL EXPORT MOD_INIT(void *handle) std::move(user_term_name_module) }, []() {return user_term_name() + ' ' + user_term_version();}}; + module_t user_wm_name_module = {"name", {}, user_wm_name}; + module_t user_wm_version_module = {"version", {}, user_wm_version}; + module_t user_wm_module = {"wm", { + std::move(user_wm_version_module), + std::move(user_wm_name_module) + }, []() {return user_wm_name() + ' ' + user_wm_version();}}; + + module_t user_de_name_module = {"name", {}, user_de_name}; + module_t user_de_version_module = {"version", {}, user_de_version}; + module_t user_de_module = {"de", { + std::move(user_de_version_module), + std::move(user_de_name_module) + }, []() {return user_de_name() + ' ' + user_de_version();}}; + /* Only for compatibility */ module_t user_shell_path_module_compat = {"shell_path", {}, user_shell_path}; module_t user_shell_name_module_compat = {"shell_name", {}, user_shell_name}; module_t user_shell_version_module_compat = {"shell_version", {}, user_shell_version}; module_t user_term_name_module_compat = {"terminal_name", {}, user_term_name}; module_t user_term_version_module_compat = {"terminal_version", {}, user_shell_version}; + module_t user_wm_name_module_compat = {"wm_name", {}, user_wm_name}; + module_t user_wm_version_module_compat = {"wm_version", {}, user_wm_version}; + module_t user_de_name_module_compat = {"de_name", {}, user_de_name}; + module_t user_de_version_module_compat = {"de_version", {}, user_de_version}; module_t user_module = {"user", { std::move(user_name_module), std::move(user_shell_module), std::move(user_term_module), + std::move(user_wm_module), + std::move(user_de_module), std::move(user_shell_name_module_compat), std::move(user_shell_path_module_compat), std::move(user_shell_version_module_compat), std::move(user_term_version_module_compat), - std::move(user_term_name_module_compat) + std::move(user_term_name_module_compat), + std::move(user_wm_name_module_compat), + std::move(user_wm_version_module_compat), + std::move(user_de_name_module_compat), + std::move(user_de_version_module_compat), }, NULL}; cfRegisterModule(user_module); diff --git a/src/core-plugins/linux/linux-core-modules.hh b/src/core-plugins/linux/linux-core-modules.hh index 58ca6a43..79719436 100644 --- a/src/core-plugins/linux/linux-core-modules.hh +++ b/src/core-plugins/linux/linux-core-modules.hh @@ -39,7 +39,7 @@ modfunc cpu_name(); // user.cc inline struct passwd* g_pwd; inline bool is_tty = false; -inline std::string term_pid, term_name; +inline std::string term_pid, term_name, wm_name, de_name, wm_path_exec; std::string get_terminal_name(); std::string get_terminal_pid(); modfunc user_name(); @@ -48,3 +48,7 @@ modfunc user_shell_name(); modfunc user_shell_version(); modfunc user_term_name(); modfunc user_term_version(); +modfunc user_wm_name(); +modfunc user_wm_version(); +modfunc user_de_name(); +modfunc user_de_version(); diff --git a/src/core-plugins/linux/user.cc b/src/core-plugins/linux/user.cc index 5472d2a5..b596a69b 100644 --- a/src/core-plugins/linux/user.cc +++ b/src/core-plugins/linux/user.cc @@ -5,8 +5,14 @@ #include "linux-core-modules.hh" #include "switch_fnv1a.hpp" #include "utils/term.hpp" +#include "utils/dewm.hpp" #include "util.hpp" +#if __has_include() && __has_include() +#include +#include +#endif + // clang-format off static std::string get_term_name_env(bool get_default = false) { @@ -53,8 +59,6 @@ static std::string get_term_name_env(bool get_default = false) return UNKNOWN; } -// clang-format on - modfunc user_name() { return g_pwd->pw_name; } @@ -62,6 +66,7 @@ modfunc user_name() modfunc user_shell_path() { return g_pwd->pw_shell; } +// clang-format on modfunc user_shell_name() { return user_shell_path().substr(user_shell_path().rfind('/') + 1); @@ -121,6 +126,9 @@ std::string get_terminal_name() modfunc user_term_name() { + if (is_tty) + return term_name; + // st (suckless terminal) if (term_name == "exe") term_name = "st"; @@ -176,6 +184,9 @@ modfunc user_term_name() modfunc user_term_version() { + if (is_tty) + return ""; + const std::string& term_name = user_term_name(); if (term_name.empty()) return UNKNOWN; @@ -232,3 +243,180 @@ modfunc user_term_version() debug("get_term_version ret after = {}", ret); return ret; } + +std::string get_wm_name(std::string& wm_path_exec) +{ + std::string path, proc_name, wm_name; + const uid_t uid = getuid(); + + for (auto const& dir_entry : std::filesystem::directory_iterator{ "/proc/" }) + { + if (!std::isdigit((dir_entry.path().string().at(6)))) // /proc/5 + continue; + + path = dir_entry.path() / "loginuid"; + std::ifstream f_uid(path, std::ios::binary); + std::string s_uid; + std::getline(f_uid, s_uid); + if (std::stoul(s_uid) != uid) + continue; + + path = dir_entry.path() / "cmdline"; + std::ifstream f_cmdline(path, std::ios::binary); + std::getline(f_cmdline, proc_name); + + size_t pos = 0; + if ((pos = proc_name.find('\0')) != std::string::npos) + proc_name.erase(pos); + + if ((pos = proc_name.rfind('/')) != std::string::npos) + proc_name.erase(0, pos + 1); + + debug("WM proc_name = {}", proc_name); + + if ((wm_name = prettify_wm_name(proc_name)) == MAGIC_LINE) + continue; + + char buf[PATH_MAX]; + wm_path_exec = realpath((dir_entry.path().string() + "/exe").c_str(), buf); + break; + } + + debug("wm_name = {}", wm_name); + if (wm_name.empty()) + return MAGIC_LINE; + + return wm_name; +} + +static std::string get_wm_wayland_name(std::string& wm_path_exec) +{ +#if __has_include() && __has_include() + void *handle = LOAD_LIBRARY("libwayland-client.so") + if (!handle) + return get_wm_name(wm_path_exec); + + LOAD_LIB_SYMBOL(handle, wl_display*, wl_display_connect, const char* name) + LOAD_LIB_SYMBOL(handle, void, wl_display_disconnect, wl_display* display) + LOAD_LIB_SYMBOL(handle, int, wl_display_get_fd, wl_display* display) + + std::string ret = MAGIC_LINE; + + struct wl_display* display = wl_display_connect(NULL); + + struct ucred ucred; + socklen_t len = sizeof(struct ucred); + if (getsockopt(wl_display_get_fd(display), SOL_SOCKET, SO_PEERCRED, &ucred, &len) == -1) + return MAGIC_LINE; + + std::ifstream f(fmt::format("/proc/{}/comm", ucred.pid), std::ios::in); + f >> ret; + wl_display_disconnect(display); + + char buf[PATH_MAX]; + wm_path_exec = realpath(fmt::format("/proc/{}/exe", ucred.pid).c_str(), buf); + + UNLOAD_LIBRARY(handle) + + return prettify_wm_name(ret); +#else + return get_wm_name(wm_path_exec); +#endif +} + +modfunc user_wm_name() +{ + if (!wm_name.empty()) + return wm_name; + if (is_tty) + return MAGIC_LINE; + + const char* env = std::getenv("WAYLAND_DISPLAY"); + if (env != nullptr && env[0] != '\0') + wm_name = get_wm_wayland_name(wm_path_exec); + else + wm_name = get_wm_name(wm_path_exec); + + if (de_name == wm_name) + de_name = MAGIC_LINE; + + return wm_name; +} + +modfunc user_wm_version() +{ + if (is_tty) + return MAGIC_LINE; + user_wm_name(); // populate wm_path_exec if haven't already + std::string wm_version; + if (wm_name == "Xfwm4" && get_fast_xfwm4_version(wm_version, wm_path_exec)) + return wm_version; + + if (wm_name == "dwm") + read_exec({ wm_path_exec.c_str(), "-v" }, wm_version, true); + else + read_exec({ wm_path_exec.c_str(), "--version" }, wm_version); + + if (wm_name == "Xfwm4") + wm_version.erase(0, "\tThis is xfwm4 version "_len); // saying only "xfwm4 4.18.2 etc." no? + else + wm_version.erase(0, wm_name.length() + 1); + + const size_t pos = wm_version.find(' '); + if (pos != std::string::npos) + wm_version.erase(pos); + + return wm_version; +} + +modfunc user_de_name() +{ + if (is_tty || ((de_name != MAGIC_LINE && wm_name != MAGIC_LINE) && de_name == wm_name)) + { + de_name = MAGIC_LINE; + return de_name; + } + + de_name = parse_de_env(); + debug("get_de_name = {}", de_name); + if (hasStart(de_name, "X-")) + de_name.erase(0, 2); + + if (de_name == wm_name) + de_name = MAGIC_LINE; + + return de_name; +} + +modfunc user_de_version() +{ + if (is_tty || de_name == UNKNOWN || de_name == MAGIC_LINE || de_name.empty()) + return UNKNOWN; + + switch (fnv1a16::hash(str_tolower(de_name))) + { + case "mate"_fnv1a16: return get_mate_version(); + case "cinnamon"_fnv1a16: return get_cinnamon_version(); + + case "kde"_fnv1a16: return get_kwin_version(); + + case "xfce"_fnv1a16: + case "xfce4"_fnv1a16: return get_xfce4_version(); + + case "gnome"_fnv1a16: + case "gnome-shell"_fnv1a16: + { + std::string ret; + read_exec({ "gnome-shell", "--version" }, ret); + ret.erase(0, ret.rfind(' ')); + return ret; + } + default: + { + std::string ret; + read_exec({ de_name.data(), "--version" }, ret); + ret.erase(0, ret.rfind(' ')); + return ret; + } + } +} From 9648c5f365a2ba423c7804d00166083617a755c9 Mon Sep 17 00:00:00 2001 From: BurntRanch <69512353+BurntRanch@users.noreply.github.com> Date: Mon, 23 Jun 2025 23:54:52 +0300 Subject: [PATCH 024/143] patch: apply tonis patch --- include/common.hpp | 17 ++--- src/core-plugins/linux/cpu.cc | 12 ++-- src/core-plugins/linux/linux-core-modules.cc | 51 +++++++++----- src/core-plugins/linux/linux-core-modules.hh | 74 +++++++++++--------- src/core-plugins/linux/os.cc | 39 ++++++----- src/core-plugins/linux/ram.cc | 49 +++++++++++++ src/core-plugins/linux/system.cc | 10 +-- src/core-plugins/linux/user.cc | 20 +++--- src/display.cpp | 2 - src/parse.cpp | 22 +----- 10 files changed, 176 insertions(+), 120 deletions(-) create mode 100644 src/core-plugins/linux/ram.cc diff --git a/include/common.hpp b/include/common.hpp index 99b6131f..831f1c06 100644 --- a/include/common.hpp +++ b/include/common.hpp @@ -5,6 +5,7 @@ #include #include #include +#include "platform.hpp" #if ENABLE_NLS && !CF_MACOS /* here so it doesn't need to be included elsewhere */ @@ -29,14 +30,14 @@ constexpr const char UNKNOWN[] = "(unknown)"; // Every instance of this string in a layout line, the whole line will be erased. constexpr const char MAGIC_LINE[] = "(cut this line NOW!! RAHHH)"; -/* handle = the library handle +/* handler = the library handle * ret_type = type of what the function returns * func = the function name * ... = the arguments in a function if any */ -#define LOAD_LIB_SYMBOL(handle, ret_type, func, ...) \ +#define LOAD_LIB_SYMBOL(handler, ret_type, func, ...) \ typedef ret_type (*func##_t)(__VA_ARGS__); \ - func##_t func = reinterpret_cast(dlsym(handle, #func)); + func##_t func = reinterpret_cast(dlsym(handler, #func)); #define UNLOAD_LIBRARY(handle) dlclose(handle); @@ -45,7 +46,7 @@ constexpr const char MAGIC_LINE[] = "(cut this line NOW!! RAHHH)"; #define EXPORT FMT_VISIBILITY("default") void #define MOD_INIT start -using modfunc = const std::string; +#define MODFUNC(name) const std::string name(__attribute__((unused)) const std::string& module = "") template void error(const std::string_view fmt, Args&&... args) noexcept @@ -94,11 +95,5 @@ struct module_t { std::string name; std::vector submodules; /* For best performance, use std::move() when adding modules in here. */ - std::function handler; - - module_t(const std::string& name, const std::vector& submodules, - const std::function handler) - : name(name), submodules(submodules), handler(handler) - { - } + std::function handler; }; diff --git a/src/core-plugins/linux/cpu.cc b/src/core-plugins/linux/cpu.cc index 47c43b69..069ff99f 100644 --- a/src/core-plugins/linux/cpu.cc +++ b/src/core-plugins/linux/cpu.cc @@ -86,7 +86,7 @@ float cpu_temp() return 0.0f; } -modfunc cpu_name() +MODFUNC(cpu_name) { char name[4096]; if (!read_value("model name", "model name"_len, true, name, sizeof(name))) @@ -108,7 +108,7 @@ modfunc cpu_name() } -modfunc cpu_nproc() +MODFUNC(cpu_nproc) { uint nproc = 0; rewind(cpuinfo); @@ -124,28 +124,28 @@ modfunc cpu_nproc() return fmt::to_string(nproc); } -modfunc cpu_freq_cur() +MODFUNC(cpu_freq_cur) { if (access((freq_dir + "/scaling_cur_freq").c_str(), F_OK) != 0) return "0"; return fmt::format("{:.2f}", std::stof(read_by_syspath(freq_dir + "/scaling_cur_freq")) / 1000000); } -modfunc cpu_freq_max() +MODFUNC(cpu_freq_max) { if (access((freq_dir + "/scaling_max_freq").c_str(), F_OK) != 0) return "0"; return fmt::format("{:.2f}", std::stof(read_by_syspath(freq_dir + "/scaling_max_freq")) / 1000000); } -modfunc cpu_freq_min() +MODFUNC(cpu_freq_min) { if (access((freq_dir + "/scaling_min_freq").c_str(), F_OK) != 0) return "0"; return fmt::format("{:.2f}", std::stof(read_by_syspath(freq_dir + "/scaling_min_freq")) / 1000000); } -modfunc cpu_freq_bios() +MODFUNC(cpu_freq_bios) { if (access((freq_dir + "/bios_limit").c_str(), F_OK) != 0) return "0"; diff --git a/src/core-plugins/linux/linux-core-modules.cc b/src/core-plugins/linux/linux-core-modules.cc index cfd78022..7de68785 100644 --- a/src/core-plugins/linux/linux-core-modules.cc +++ b/src/core-plugins/linux/linux-core-modules.cc @@ -1,14 +1,19 @@ #include #include +#include +#include +#include #include #include "linux-core-modules.hh" #include "common.hpp" #include "fmt/format.h" #include "util.hpp" +using unused = const std::string&; + APICALL EXPORT MOD_INIT(void *handle) { - // INIT STUFF + // ------------ INIT STUFF ------------ if (!handle) { error("Exiting because !handle"); @@ -32,8 +37,9 @@ APICALL EXPORT MOD_INIT(void *handle) } os_release = fopen("/etc/os-release", "r"); cpuinfo = fopen("/proc/cpuinfo", "r"); + meminfo = fopen("/proc/meminfo", "r"); - // MODULES REGISTERING + // ------------ MODULES REGISTERING ------------ module_t os_name_pretty_module = {"pretty", {}, os_pretty_name}; module_t os_name_id_module = {"id", {}, os_name_id}; module_t os_name_module = { "name", { @@ -49,14 +55,14 @@ APICALL EXPORT MOD_INIT(void *handle) module_t os_kernel_module = {"kernel", { std::move(os_kernel_name_module), std::move(os_kernel_version_module) - }, []() {return os_kernel_name() + ' ' + os_kernel_version();}}; + }, [](unused) {return os_kernel_name() + ' ' + os_kernel_version();}}; module_t os_initsys_name_module = {"name", {}, os_initsys_name}; module_t os_initsys_version_module = {"version", {}, os_initsys_version}; module_t os_initsys_module = {"initsys", { std::move(os_initsys_name_module), std::move(os_initsys_version_module), - }, []() {return os_initsys_name() + ' ' + os_initsys_version();}}; + }, [](unused) {return os_initsys_name() + ' ' + os_initsys_version();}}; /* Only for compatibility */ module_t os_pretty_name_module_compat = { "pretty_name", {}, os_pretty_name }; @@ -121,23 +127,23 @@ APICALL EXPORT MOD_INIT(void *handle) std::move(cpu_freq_bios_module), }, cpu_freq_max}; - module_t cpu_temp_C_module = {"C", {}, []() {return fmt::format("{:.2f}°C", cpu_temp());}}; - module_t cpu_temp_F_module = {"F", {}, []() {return fmt::format("{:.2f}°F", cpu_temp() * 1.8 + 34);}}; - module_t cpu_temp_K_module = {"K", {}, []() {return fmt::format("{:.2f}°K", cpu_temp() + 273.15);}}; + module_t cpu_temp_C_module = {"C", {}, [](unused) {return fmt::format("{:.2f}°C", cpu_temp());}}; + module_t cpu_temp_F_module = {"F", {}, [](unused) {return fmt::format("{:.2f}°F", cpu_temp() * 1.8 + 34);}}; + module_t cpu_temp_K_module = {"K", {}, [](unused) {return fmt::format("{:.2f}°K", cpu_temp() + 273.15);}}; module_t cpu_temp_module = {"temp", { std::move(cpu_temp_C_module), std::move(cpu_temp_F_module), std::move(cpu_temp_K_module), - }, []() {return fmt::format("{:.2f}°C", cpu_temp());}}; + }, [](unused) {return fmt::format("{:.2f}°C", cpu_temp());}}; /* Only for compatibility */ module_t cpu_freq_cur_module_compat = {"freq_cur", {}, cpu_freq_cur}; module_t cpu_freq_max_module_compat = {"freq_max", {}, cpu_freq_max}; module_t cpu_freq_min_module_compat = {"freq_min", {}, cpu_freq_min}; module_t cpu_freq_bios_module_compat = {"freq_bios_limit", {}, cpu_freq_bios}; - module_t cpu_temp_C_module_compat = {"temp_C", {}, []() {return fmt::format("{:.2f}", cpu_temp());}}; - module_t cpu_temp_F_module_compat = {"temp_F", {}, []() {return fmt::format("{:.2f}", cpu_temp() * 1.8 + 34);}}; - module_t cpu_temp_K_module_compat = {"temp_K", {}, []() {return fmt::format("{:.2f}", cpu_temp() + 273.15);}}; + module_t cpu_temp_C_module_compat = {"temp_C", {}, [](unused) {return fmt::format("{:.2f}", cpu_temp());}}; + module_t cpu_temp_F_module_compat = {"temp_F", {}, [](unused) {return fmt::format("{:.2f}", cpu_temp() * 1.8 + 34);}}; + module_t cpu_temp_K_module_compat = {"temp_K", {}, [](unused) {return fmt::format("{:.2f}", cpu_temp() + 273.15);}}; module_t cpu_module = {"cpu", { std::move(cpu_name_module), @@ -152,7 +158,7 @@ APICALL EXPORT MOD_INIT(void *handle) std::move(cpu_temp_C_module_compat), std::move(cpu_temp_F_module_compat), std::move(cpu_temp_K_module_compat), - }, []() { + }, [](unused) { return fmt::format("{} ({}) @ {} GHz", cpu_name(), cpu_nproc(), cpu_freq_max()); }}; @@ -168,28 +174,28 @@ APICALL EXPORT MOD_INIT(void *handle) std::move(user_shell_name_module), std::move(user_shell_path_module), std::move(user_shell_version_module), - }, []() {return user_shell_name() + ' ' + user_shell_version();}}; + }, [](unused) {return user_shell_name() + " " + user_shell_version();}}; module_t user_term_name_module = {"name", {}, user_term_name}; module_t user_term_version_module = {"version", {}, user_shell_version}; module_t user_term_module = {"terminal", { std::move(user_term_version_module), std::move(user_term_name_module) - }, []() {return user_term_name() + ' ' + user_term_version();}}; + }, [](unused) {return user_term_name() + " " + user_term_version();}}; module_t user_wm_name_module = {"name", {}, user_wm_name}; module_t user_wm_version_module = {"version", {}, user_wm_version}; module_t user_wm_module = {"wm", { std::move(user_wm_version_module), std::move(user_wm_name_module) - }, []() {return user_wm_name() + ' ' + user_wm_version();}}; + }, [](unused) {return user_wm_name() + " " + user_wm_version();}}; module_t user_de_name_module = {"name", {}, user_de_name}; module_t user_de_version_module = {"version", {}, user_de_version}; module_t user_de_module = {"de", { std::move(user_de_version_module), std::move(user_de_name_module) - }, []() {return user_de_name() + ' ' + user_de_version();}}; + }, [](unused) {return user_de_name() + " " + user_de_version();}}; /* Only for compatibility */ module_t user_shell_path_module_compat = {"shell_path", {}, user_shell_path}; @@ -221,4 +227,17 @@ APICALL EXPORT MOD_INIT(void *handle) }, NULL}; cfRegisterModule(user_module); + + // $ + constexpr std::array sorted_valid_prefixes = { "B", "EB", "EiB", "GB", "GiB", "kB", + "KiB", "MB", "MiB", "PB", "PiB", "TB", + "TiB", "YB", "YiB", "ZB", "ZiB" }; + const auto& return_devided_bytes = [&](const double& amount, const std::string& module) -> double { + const std::string& prefix = module.substr(module.find('-') + 1); + if (std::binary_search(sorted_valid_prefixes.begin(), sorted_valid_prefixes.end(), prefix)) + return devide_bytes(amount, prefix).num_bytes; + + return 0; + }; + module_t ram_free_module{"free", {}, NULL}; } diff --git a/src/core-plugins/linux/linux-core-modules.hh b/src/core-plugins/linux/linux-core-modules.hh index 79719436..bfcd8649 100644 --- a/src/core-plugins/linux/linux-core-modules.hh +++ b/src/core-plugins/linux/linux-core-modules.hh @@ -6,35 +6,35 @@ // system.cc inline utsname g_uname_infos; -modfunc arch(); -modfunc host(); -modfunc host_name(); -modfunc host_version(); -modfunc host_vendor(); +MODFUNC(arch); +MODFUNC(host); +MODFUNC(host_name); +MODFUNC(host_version); +MODFUNC(host_vendor); // os.cc inline std::FILE *os_release; -modfunc os_name(); -modfunc os_pretty_name(); -modfunc os_name_id(); -modfunc os_version_id(); -modfunc os_version_codename(); -modfunc os_uptime(); -modfunc os_kernel_name(); -modfunc os_kernel_version(); -modfunc os_hostname(); -modfunc os_initsys_name(); -modfunc os_initsys_version(); +MODFUNC(os_name); +MODFUNC(os_pretty_name); +MODFUNC(os_name_id); +MODFUNC(os_version_id); +MODFUNC(os_version_codename); +MODFUNC(os_uptime); +MODFUNC(os_kernel_name); +MODFUNC(os_kernel_version); +MODFUNC(os_hostname); +MODFUNC(os_initsys_name); +MODFUNC(os_initsys_version); // cpu.cc inline std::FILE *cpuinfo; -modfunc cpu_freq_cur(); -modfunc cpu_freq_max(); -modfunc cpu_freq_min(); -modfunc cpu_freq_bios(); +MODFUNC(cpu_freq_cur); +MODFUNC(cpu_freq_max); +MODFUNC(cpu_freq_min); +MODFUNC(cpu_freq_bios); float cpu_temp(); -modfunc cpu_nproc(); -modfunc cpu_name(); +MODFUNC(cpu_nproc); +MODFUNC(cpu_name); // user.cc inline struct passwd* g_pwd; @@ -42,13 +42,23 @@ inline bool is_tty = false; inline std::string term_pid, term_name, wm_name, de_name, wm_path_exec; std::string get_terminal_name(); std::string get_terminal_pid(); -modfunc user_name(); -modfunc user_shell_path(); -modfunc user_shell_name(); -modfunc user_shell_version(); -modfunc user_term_name(); -modfunc user_term_version(); -modfunc user_wm_name(); -modfunc user_wm_version(); -modfunc user_de_name(); -modfunc user_de_version(); +MODFUNC(user_name); +MODFUNC(user_shell_path); +MODFUNC(user_shell_name); +MODFUNC(user_shell_version); +MODFUNC(user_term_name); +MODFUNC(user_term_version); +MODFUNC(user_wm_name); +MODFUNC(user_wm_version); +MODFUNC(user_de_name); +MODFUNC(user_de_version); + +// ram.cc +inline std::FILE* meminfo; +double ram_free(); +double ram_total(); +double swap_free(); +double swap_total(); + +#undef MODFUNC +#define MODFUNC(name) const std::string name(__attribute__((unused)) const std::string& module) diff --git a/src/core-plugins/linux/os.cc b/src/core-plugins/linux/os.cc index 64d31f7f..5101ced3 100644 --- a/src/core-plugins/linux/os.cc +++ b/src/core-plugins/linux/os.cc @@ -3,6 +3,7 @@ #include #include #include +#include #define FMT_HEADER_ONLY 1 #include "common.hpp" @@ -11,7 +12,7 @@ #include "switch_fnv1a.hpp" #include "util.hpp" -static std::string read_value(const char* name, size_t n) +static std::string read_value(const std::string_view name) { if (!os_release) return UNKNOWN; @@ -24,10 +25,10 @@ static std::string read_value(const char* name, size_t n) while (getline(&line, &len, os_release) != -1) { - if (strncmp(line, name, n) != 0) + if (strncmp(line, name.data(), name.length()) != 0) continue; - char* start = strchr(line + n, '"'); + char* start = strchr(line + name.length(), '"'); if (!start) continue; start++; @@ -57,34 +58,34 @@ static unsigned long get_uptime() return (unsigned long)uptime.tv_sec * 1000 + (unsigned long)uptime.tv_nsec / 1000000; } -modfunc os_name() -{ return read_value("NAME=", "NAME="_len); } +MODFUNC(os_name) +{ return read_value("NAME="); } -modfunc os_pretty_name() -{ return read_value("PRETTY_NAME=", "PRETTY_NAME="_len); } +MODFUNC(os_pretty_name) +{ return read_value("PRETTY_NAME="); } -modfunc os_name_id() -{ return read_value("ID=", "ID="_len); } +MODFUNC(os_name_id) +{ return read_value("ID="); } -modfunc os_version_id() -{ return read_value("VERSION_ID=", "VERSION_ID="_len); } +MODFUNC(os_version_id) +{ return read_value("VERSION_ID="); } -modfunc os_version_codename() -{ return read_value("VERSION_CODENAME=", "VERSION_CODENAME="_len); } +MODFUNC(os_version_codename) +{ return read_value("VERSION_CODENAME="); } -modfunc os_uptime() +MODFUNC(os_uptime) { return fmt::to_string(get_uptime()); } -modfunc os_kernel_name() +MODFUNC(os_kernel_name) { return g_uname_infos.sysname; } -modfunc os_kernel_version() +MODFUNC(os_kernel_version) { return g_uname_infos.release; } -modfunc os_hostname() +MODFUNC(os_hostname) { return g_uname_infos.nodename; } -modfunc os_initsys_name() +MODFUNC(os_initsys_name) { // there's no way PID 1 doesn't exist. // This will always succeed (because we are on linux) @@ -105,7 +106,7 @@ modfunc os_initsys_name() return initsys; } -modfunc os_initsys_version() +MODFUNC(os_initsys_version) { std::string os_initsys_version; std::string path; diff --git a/src/core-plugins/linux/ram.cc b/src/core-plugins/linux/ram.cc new file mode 100644 index 00000000..cdc56472 --- /dev/null +++ b/src/core-plugins/linux/ram.cc @@ -0,0 +1,49 @@ +#include "common.hpp" +#include "linux-core-modules.hh" +#include +#include +#include + +static double read_value(const std::string_view key) +{ + if (!meminfo) + return 0.0; + + std::string result{UNKNOWN}; + char* line = nullptr; + size_t len = 0; + + while (getline(&line, &len, meminfo) != -1) + { + if (strncmp(line, key.data(), key.length()) != 0) + continue; + + // Skip colon and whitespace + char* value = line + 1; + while (isspace(*value)) value++; + + // Find end of numeric value (stop at first non-digit or '.') + char* end = value; + while (*end && (isdigit(*end) || *end == '.')) end++; + + if (value != end) + result.assign(value, end - value); + break; + } + + free(line); + rewind(meminfo); + return std::stod(result); +} + +double ram_free() +{ return read_value("MemAvailable:"); } + +double ram_total() +{ return read_value("MemTotal:"); } + +double swap_free() +{ return read_value("SwapFree:"); } + +double swap_total() +{ return read_value("SwapTotal:"); } diff --git a/src/core-plugins/linux/system.cc b/src/core-plugins/linux/system.cc index 34649738..8b41ea95 100644 --- a/src/core-plugins/linux/system.cc +++ b/src/core-plugins/linux/system.cc @@ -10,7 +10,7 @@ /* The handler that we'll use for our module, Handlers return const std::string (WILL be changed to const char * pointers). */ -modfunc host() +MODFUNC(host) { const std::string syspath = "/sys/devices/virtual/dmi/id"; @@ -45,7 +45,7 @@ modfunc host() return board_vendor + ' ' + board_name + ' ' + board_version; } -modfunc host_name() +MODFUNC(host_name) { const std::string syspath = "/sys/devices/virtual/dmi/id"; @@ -57,7 +57,7 @@ modfunc host_name() return UNKNOWN; } -modfunc host_version() +MODFUNC(host_version) { const std::string syspath = "/sys/devices/virtual/dmi/id"; @@ -69,7 +69,7 @@ modfunc host_version() return UNKNOWN; } -modfunc host_vendor() +MODFUNC(host_vendor) { const std::string syspath = "/sys/devices/virtual/dmi/id"; @@ -89,7 +89,7 @@ modfunc host_vendor() return board_vendor; } -modfunc arch() +MODFUNC(arch) { return g_uname_infos.machine; } diff --git a/src/core-plugins/linux/user.cc b/src/core-plugins/linux/user.cc index b596a69b..3e717835 100644 --- a/src/core-plugins/linux/user.cc +++ b/src/core-plugins/linux/user.cc @@ -60,19 +60,19 @@ static std::string get_term_name_env(bool get_default = false) return UNKNOWN; } -modfunc user_name() +MODFUNC(user_name) { return g_pwd->pw_name; } -modfunc user_shell_path() +MODFUNC(user_shell_path) { return g_pwd->pw_shell; } // clang-format on -modfunc user_shell_name() +MODFUNC(user_shell_name) { return user_shell_path().substr(user_shell_path().rfind('/') + 1); } -modfunc user_shell_version() +MODFUNC(user_shell_version) { const std::string& shell_name = user_shell_name(); std::string ret; @@ -124,7 +124,7 @@ std::string get_terminal_name() return term_name; } -modfunc user_term_name() +MODFUNC(user_term_name) { if (is_tty) return term_name; @@ -182,7 +182,7 @@ modfunc user_term_name() return term_name; } -modfunc user_term_version() +MODFUNC(user_term_version) { if (is_tty) return ""; @@ -324,7 +324,7 @@ static std::string get_wm_wayland_name(std::string& wm_path_exec) #endif } -modfunc user_wm_name() +MODFUNC(user_wm_name) { if (!wm_name.empty()) return wm_name; @@ -343,7 +343,7 @@ modfunc user_wm_name() return wm_name; } -modfunc user_wm_version() +MODFUNC(user_wm_version) { if (is_tty) return MAGIC_LINE; @@ -369,7 +369,7 @@ modfunc user_wm_version() return wm_version; } -modfunc user_de_name() +MODFUNC(user_de_name) { if (is_tty || ((de_name != MAGIC_LINE && wm_name != MAGIC_LINE) && de_name == wm_name)) { @@ -388,7 +388,7 @@ modfunc user_de_name() return de_name; } -modfunc user_de_version() +MODFUNC(user_de_version) { if (is_tty || de_name == UNKNOWN || de_name == MAGIC_LINE || de_name.empty()) return UNKNOWN; diff --git a/src/display.cpp b/src/display.cpp index b5257e48..b93b3b4c 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -224,8 +224,6 @@ static bool get_pos(int& y, int& x) return true; } -const std::string test() { return "Test!!!"; } - std::vector Display::render(const Config& config, const colors_t& colors, const bool already_analyzed_file, const std::filesystem::path& path, moduleMap_t& moduleMap) { diff --git a/src/parse.cpp b/src/parse.cpp index 7c3bd353..ecd310ff 100644 --- a/src/parse.cpp +++ b/src/parse.cpp @@ -245,26 +245,10 @@ std::string get_and_color_percentage(const float n1, const float n2, parse_args_ return parse(fmt::format("{}{:.2f}%${{0}}", color, result), _, parse_args); } -const std::string getInfoFromName(const moduleMap_t& systemInfo, const std::string_view moduleName) +const std::string getInfoFromName(const moduleMap_t& modulesInfo, const std::string& moduleName) { - if (const auto& it = systemInfo.find(moduleName.data()); it != systemInfo.end()) - { - // if (const auto& it2 = it1->second.find(moduleMemberName.data()); it2 != it1->second.end()) - // { - // const variant& result = it2->second; - - // if (std::holds_alternative(result)) - // return std::get(result); - - // else if (std::holds_alternative(result)) - // return fmt::format("{:.2f}", (std::get(result))); - - // else - // return fmt::to_string(std::get(result)); - // } - - return it->second.handler(); - } + if (const auto& it = modulesInfo.find(moduleName); it != modulesInfo.end()) + return it->second.handler(moduleName); return "(unknown/invalid module)"; } From 2161abe7ee596b638cda04db1be5b3e7525c097c Mon Sep 17 00:00:00 2001 From: BurntRanch <69512353+BurntRanch@users.noreply.github.com> Date: Mon, 23 Jun 2025 23:56:46 +0300 Subject: [PATCH 025/143] plugins: add support for arguments --- src/parse.cpp | 56 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/src/parse.cpp b/src/parse.cpp index ecd310ff..c1cbc648 100644 --- a/src/parse.cpp +++ b/src/parse.cpp @@ -247,8 +247,60 @@ std::string get_and_color_percentage(const float n1, const float n2, parse_args_ const std::string getInfoFromName(const moduleMap_t& modulesInfo, const std::string& moduleName) { - if (const auto& it = modulesInfo.find(moduleName); it != modulesInfo.end()) - return it->second.handler(moduleName); + /* copy module name */ + std::string name{moduleName}; + + /* argument that's collected from what's between the parenthesis in "module(...).test" */ + std::string arg; + + /* Position of the open parenthesis, -1 (18 billion smth because it's a size_t) if we aren't in there */ + size_t open_par_pos = -1; + + int i = -1; + + for (const char &c : name) { + i++; + if (c == '(' && open_par_pos == (size_t)-1) { + open_par_pos = i; + continue; + } + + /* we've reached the separator, do some validation. */ + /* TODO(burntranch): get separator from a common header or config that both libcufetch and we read from. */ + if (c == '.') { + if (open_par_pos != (size_t)-1 && arg.back() != ')') + die("Module name `{}` is invalid. Arguments must end in )", moduleName); + + if (open_par_pos != (size_t)-1) { + arg.pop_back(); + name.erase(open_par_pos, arg.length() + 2); + } + + break; + } + + if (open_par_pos != (size_t)-1) + arg += c; + } + + if (const auto& it = modulesInfo.find(name.data()); it != modulesInfo.end()) + { + // if (const auto& it2 = it1->second.find(moduleMemberName.data()); it2 != it1->second.end()) + // { + // const variant& result = it2->second; + + // if (std::holds_alternative(result)) + // return std::get(result); + + // else if (std::holds_alternative(result)) + // return fmt::format("{:.2f}", (std::get(result))); + + // else + // return fmt::to_string(std::get(result)); + // } + + return it->second.handler(arg); + } return "(unknown/invalid module)"; } From feebb68c807fc3f4e28571dde33f423347d7fc70 Mon Sep 17 00:00:00 2001 From: Toni500git Date: Mon, 23 Jun 2025 23:24:07 +0200 Subject: [PATCH 026/143] parse: clang-format --- src/parse.cpp | 47 +++++++++++++++-------------------------------- 1 file changed, 15 insertions(+), 32 deletions(-) diff --git a/src/parse.cpp b/src/parse.cpp index c1cbc648..2e784fab 100644 --- a/src/parse.cpp +++ b/src/parse.cpp @@ -245,37 +245,36 @@ std::string get_and_color_percentage(const float n1, const float n2, parse_args_ return parse(fmt::format("{}{:.2f}%${{0}}", color, result), _, parse_args); } -const std::string getInfoFromName(const moduleMap_t& modulesInfo, const std::string& moduleName) +const std::string getInfoFromName(const moduleMap_t& modulesInfo, std::string moduleName) { - /* copy module name */ - std::string name{moduleName}; - - /* argument that's collected from what's between the parenthesis in "module(...).test" */ - std::string arg; - /* Position of the open parenthesis, -1 (18 billion smth because it's a size_t) if we aren't in there */ size_t open_par_pos = -1; - int i = -1; - for (const char &c : name) { + /* argument that's collected from what's between the parenthesis in "module(...).test" */ + std::string arg; + for (const char& c : moduleName) + { i++; - if (c == '(' && open_par_pos == (size_t)-1) { + if (c == '(' && open_par_pos == (size_t)-1) + { open_par_pos = i; continue; } /* we've reached the separator, do some validation. */ /* TODO(burntranch): get separator from a common header or config that both libcufetch and we read from. */ - if (c == '.') { + if (c == '.') + { if (open_par_pos != (size_t)-1 && arg.back() != ')') - die("Module name `{}` is invalid. Arguments must end in )", moduleName); + die("Module name `{}` is invalid. Arguments must end with )", moduleName); - if (open_par_pos != (size_t)-1) { + if (open_par_pos != (size_t)-1) + { arg.pop_back(); - name.erase(open_par_pos, arg.length() + 2); + moduleName.erase(open_par_pos, arg.length() + 2); } - + break; } @@ -283,24 +282,8 @@ const std::string getInfoFromName(const moduleMap_t& modulesInfo, const std::str arg += c; } - if (const auto& it = modulesInfo.find(name.data()); it != modulesInfo.end()) - { - // if (const auto& it2 = it1->second.find(moduleMemberName.data()); it2 != it1->second.end()) - // { - // const variant& result = it2->second; - - // if (std::holds_alternative(result)) - // return std::get(result); - - // else if (std::holds_alternative(result)) - // return fmt::format("{:.2f}", (std::get(result))); - - // else - // return fmt::to_string(std::get(result)); - // } - + if (const auto& it = modulesInfo.find(moduleName); it != modulesInfo.end()) return it->second.handler(arg); - } return "(unknown/invalid module)"; } From 599c487cd262a8a6b49526949be15d6e817d8c44 Mon Sep 17 00:00:00 2001 From: BurntRanch <69512353+BurntRanch@users.noreply.github.com> Date: Tue, 24 Jun 2025 00:44:44 +0300 Subject: [PATCH 027/143] args: fix os.name_id, add support for arguments --- src/core-plugins/linux/os.cc | 17 +++++++++-------- src/core-plugins/linux/system.cc | 1 + src/parse.cpp | 7 +++++-- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/core-plugins/linux/os.cc b/src/core-plugins/linux/os.cc index 5101ced3..ce5fa73c 100644 --- a/src/core-plugins/linux/os.cc +++ b/src/core-plugins/linux/os.cc @@ -25,18 +25,19 @@ static std::string read_value(const std::string_view name) while (getline(&line, &len, os_release) != -1) { - if (strncmp(line, name.data(), name.length()) != 0) + if (name.length() > len || strncmp(line, name.data(), name.length()) != 0) continue; - char* start = strchr(line + name.length(), '"'); - if (!start) - continue; - start++; + char* start = strchr(line + name.length(), '"'); /* Get first occurence of " */ + if (start) + start++; /* Get after the " */ + else + start = line + name.length(); /* No ", get the start. */ - char* end = strrchr(start, '"'); + char* end = strrchr(start, '"'); /* Get last occurence of " */ if (!end) - continue; - + end = line + strlen(line) - 1; /* Set to the end of the string -- no newline. (I heard Windows has a different newline sequence.. *sigh*) */ + result.assign(start, end - start); break; } diff --git a/src/core-plugins/linux/system.cc b/src/core-plugins/linux/system.cc index 8b41ea95..6845c713 100644 --- a/src/core-plugins/linux/system.cc +++ b/src/core-plugins/linux/system.cc @@ -5,6 +5,7 @@ #include #include "common.hpp" +#include "fmt/base.h" #include "linux-core-modules.hh" #include "util.hpp" diff --git a/src/parse.cpp b/src/parse.cpp index 2e784fab..4e55a258 100644 --- a/src/parse.cpp +++ b/src/parse.cpp @@ -247,6 +247,9 @@ std::string get_and_color_percentage(const float n1, const float n2, parse_args_ const std::string getInfoFromName(const moduleMap_t& modulesInfo, std::string moduleName) { + /* copy module name */ + std::string name{moduleName}; + /* Position of the open parenthesis, -1 (18 billion smth because it's a size_t) if we aren't in there */ size_t open_par_pos = -1; int i = -1; @@ -272,7 +275,7 @@ const std::string getInfoFromName(const moduleMap_t& modulesInfo, std::string mo if (open_par_pos != (size_t)-1) { arg.pop_back(); - moduleName.erase(open_par_pos, arg.length() + 2); + name.erase(open_par_pos, arg.length() + 2); } break; @@ -282,7 +285,7 @@ const std::string getInfoFromName(const moduleMap_t& modulesInfo, std::string mo arg += c; } - if (const auto& it = modulesInfo.find(moduleName); it != modulesInfo.end()) + if (const auto& it = modulesInfo.find(name); it != modulesInfo.end()) return it->second.handler(arg); return "(unknown/invalid module)"; From a5f840ef460c9d8550f8da2061c307cbc4ab7aef Mon Sep 17 00:00:00 2001 From: BurntRanch <69512353+BurntRanch@users.noreply.github.com> Date: Tue, 24 Jun 2025 00:48:21 +0300 Subject: [PATCH 028/143] revert: partially revert last commit --- src/parse.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/parse.cpp b/src/parse.cpp index 4e55a258..2e784fab 100644 --- a/src/parse.cpp +++ b/src/parse.cpp @@ -247,9 +247,6 @@ std::string get_and_color_percentage(const float n1, const float n2, parse_args_ const std::string getInfoFromName(const moduleMap_t& modulesInfo, std::string moduleName) { - /* copy module name */ - std::string name{moduleName}; - /* Position of the open parenthesis, -1 (18 billion smth because it's a size_t) if we aren't in there */ size_t open_par_pos = -1; int i = -1; @@ -275,7 +272,7 @@ const std::string getInfoFromName(const moduleMap_t& modulesInfo, std::string mo if (open_par_pos != (size_t)-1) { arg.pop_back(); - name.erase(open_par_pos, arg.length() + 2); + moduleName.erase(open_par_pos, arg.length() + 2); } break; @@ -285,7 +282,7 @@ const std::string getInfoFromName(const moduleMap_t& modulesInfo, std::string mo arg += c; } - if (const auto& it = modulesInfo.find(name); it != modulesInfo.end()) + if (const auto& it = modulesInfo.find(moduleName); it != modulesInfo.end()) return it->second.handler(arg); return "(unknown/invalid module)"; From b114fc00debedb3d8db467a3d421f0f52e746522 Mon Sep 17 00:00:00 2001 From: Toni500git Date: Tue, 24 Jun 2025 15:14:41 +0200 Subject: [PATCH 029/143] assets: fix some ascii art that have single backslash escape --- assets/ascii/celos.txt | 2 +- assets/ascii/dragonfly.txt | 6 +++--- assets/ascii/dragonfly_old.txt | 8 ++++---- assets/ascii/gnu.txt | 16 ++++++++-------- assets/ascii/grombyang.txt | 8 ++++---- assets/ascii/hydroos.txt | 6 +++--- assets/ascii/netbsd_small.txt | 8 ++++---- assets/ascii/openbsd.txt | 14 +++++++------- assets/ascii/parsix.txt | 2 +- assets/ascii/ubuntu.txt | 12 ++++++------ 10 files changed, 41 insertions(+), 41 deletions(-) diff --git a/assets/ascii/celos.txt b/assets/ascii/celos.txt index d060340f..e8eb627f 100644 --- a/assets/ascii/celos.txt +++ b/assets/ascii/celos.txt @@ -12,7 +12,7 @@ ${black}#################################### ${magenta}MMMMMMMMMMMMMc ${magenta} "MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM: ${magenta} "MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" ${magenta} 'MMMMMMMMM*******************************: -${magenta} \"MMMMMM ${black}##################################### +${magenta} \\"MMMMMM ${black}##################################### ${magenta} ${magenta}`:MMMMMMmmmmmmmmmmmmmmmmmmmmmmmmmmmmm; ${magenta} `"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" ${magenta} `":MMMMMMMMMMMMMMMMMMMMMMMMM;' diff --git a/assets/ascii/dragonfly.txt b/assets/ascii/dragonfly.txt index 0009cb7a..6f863e18 100644 --- a/assets/ascii/dragonfly.txt +++ b/assets/ascii/dragonfly.txt @@ -1,11 +1,11 @@ ${1},--, ${red}| ${1},--, ${1}| `-, ${red},^, ${1},-' | -${1} `, `-, ${yellow}(/ \) ${1},-' ,' -${1} `-, `-,${red}/ \${1},-' ,-' +${1} `, `-, ${yellow}(/ \\) ${1},-' ,' +${1} `-, `-,${red}/ \\${1},-' ,-' ${1} `------${red}( )${1}------' ${1} ,----------${red}( )${1}----------, ${1} | _,-${red}( )${1}-,_ | -${1} `-,__,-' ${red}\ /${1} `-,__,-' +${1} `-,__,-' ${red}\\ /${1} `-,__,-' ${red} | | ${red} | | ${red} | | diff --git a/assets/ascii/dragonfly_old.txt b/assets/ascii/dragonfly_old.txt index 97280531..31867d79 100644 --- a/assets/ascii/dragonfly_old.txt +++ b/assets/ascii/dragonfly_old.txt @@ -1,14 +1,14 @@ ${red} .-. ${yellow} ()${red}I${yellow}() ${red} "==.__:-:__.==" -${red} "==.__/~|~\__.==" +${red} "==.__/~|~\\__.==" ${red} "==._( Y )_.==" - ${white}.-'~~""~=--...,__${red}\/|\/${white}__,...--=~""~~'-. + ${white}.-'~~""~=--...,__${red}\\/|\\/${white}__,...--=~""~~'-. ${white}( ..=${red}\\=${red}/${white}=.. ) ${white} `'-. ,.-"`;${red}/=\\${white};"-.,_ .-'` ${white} `~"-=-~` .-~` ${red}|=|${white} `~-. `~-=-"~` -${white} .-~` /${red}|=|${white}\ `~-. -${white} .~` / ${red}|=|${white} \ `~. +${white} .-~` /${red}|=|${white}\\ `~-. +${white} .~` / ${red}|=|${white} \\ `~. ${white} .-~` .' ${red}|=|${white} `. `~-. ${white} (` _,.-="` ${red} |=|${white} `"=-.,_ `) ${white} `~"~"` ${red} |=|${white} `"~"~` diff --git a/assets/ascii/gnu.txt b/assets/ascii/gnu.txt index e8c0fe3c..285559e6 100644 --- a/assets/ascii/gnu.txt +++ b/assets/ascii/gnu.txt @@ -1,14 +1,14 @@ ${1} _-`````-, ,- '- . ${1} .' .- - | | - -. `. -${1} /.' / `. \ +${1} /.' / `. \\ ${1}:/ : _... ..._ `` : -${1}:: : /._ .`:'_.._\. || : -${1}:: `._ ./ ,` : \ . _.'' . -${1}`:. / | -. \-. \\_ / -${1} \:._ _/ .' .@) \@) ` `\ ,.' -${1} _/,--' .- .\,-.`--`. -${1} ,'/'' (( \ ` ) -${1} /'/' \ `-' ( +${1}:: : /._ .`:'_.._\\. || : +${1}:: `._ ./ ,` : \\ . _.'' . +${1}`:. / | -. \\-. \\_ / +${1} \\:._ _/ .' .@) \\@) ` `\\ ,.' +${1} _/,--' .- .\\,-.`--`. +${1} ,'/'' (( \\ ` ) +${1} /'/' \\ `-' ( ${1} '/'' `._,-----' ${1} ''/' .,---' ${1} ''/' ;: diff --git a/assets/ascii/grombyang.txt b/assets/ascii/grombyang.txt index 51ffd671..05d20873 100644 --- a/assets/ascii/grombyang.txt +++ b/assets/ascii/grombyang.txt @@ -8,10 +8,10 @@ ${blue}eee ${green}`+oooooo: ${blue}eee ${blue}eee ${green}-+oooooo+: ${blue}eee ${blue}ee ${green}`/:oooooooo+: ${blue}ee ${blue}ee ${green}`/+ +++ +: ${blue}ee -${blue}ee ${green}+o+\ ${blue}ee -${blue}eee ${green}+o+\ ${blue}eee -${blue}eee ${green}// \\ooo/ \\\ ${blue}eee -${blue} eee ${green}//++++oooo++++\\\ ${blue}eee +${blue}ee ${green}+o+\\ ${blue}ee +${blue}eee ${green}+o+\\ ${blue}eee +${blue}eee ${green}// \\ooo/ \\\\ ${blue}eee +${blue} eee ${green}//++++oooo++++\\\\ ${blue}eee ${blue} eeee ${green}::::++oooo+::::: ${blue}eeee ${blue} eeeee ${red}Grombyang OS ${blue} eeee ${blue} eeeeeeeeeeeeeeeeeeeeeee diff --git a/assets/ascii/hydroos.txt b/assets/ascii/hydroos.txt index fb1e59eb..f6e45751 100644 --- a/assets/ascii/hydroos.txt +++ b/assets/ascii/hydroos.txt @@ -1,9 +1,9 @@ ${green}${red} ${red} _ _ _ ____ _____ -${red} | | | | | | / __ \ / ____| +${red} | | | | | | / __ \\ / ____| ${red} | |__| |_ _ __| |_ __ ___ | | | | (___ -${red} | __ | | | |/ _` | '__/ _ \| | | |\___ \ +${red} | __ | | | |/ _` | '__/ _ \\| | | |\\___ \\ ${red} | | | | |_| | (_| | | | (_) | |__| |____) | -${red} |_| |_|\__, |\__,_|_| \___/ \____/|_____/ +${red} |_| |_|\\__, |\\__,_|_| \\___/ \\____/|_____/ ${red} __/ | ${red} |___/ diff --git a/assets/ascii/netbsd_small.txt b/assets/ascii/netbsd_small.txt index 360814ae..2ff11e16 100644 --- a/assets/ascii/netbsd_small.txt +++ b/assets/ascii/netbsd_small.txt @@ -1,7 +1,7 @@ -${!#fc6906}${white}\\\\${!#fc6906}\`-______,----__ -${white} \\\\ ${!#fc6906}__,---\`_ -${white} \\\\ ${!#fc6906}\`.____ -${white} \\\\${!#fc6906}-______,----\`- +${!#fc6906}${white}\\\\${!#fc6906}\\`-______,----__ +${white} \\\\ ${!#fc6906}__,---\\`_ +${white} \\\\ ${!#fc6906}\\`.____ +${white} \\\\${!#fc6906}-______,----\\`- ${white} \\\\ ${white} \\\\ ${white} \\\\ diff --git a/assets/ascii/openbsd.txt b/assets/ascii/openbsd.txt index 9448c746..ebae7fc1 100644 --- a/assets/ascii/openbsd.txt +++ b/assets/ascii/openbsd.txt @@ -1,22 +1,22 @@ -${cyan} _ +${yellow}${cyan} _ ${cyan} (_) ${yellow} | . ${yellow} . |L /| . ${cyan} _ -${yellow} _ . |\ _| \--+._/| . ${cyan}(_) -${yellow} / ||\| Y J ) / |/| ./ +${yellow} _ . |\\ _| \\--+._/| . ${cyan}(_) +${yellow} / ||\\| Y J ) / |/| ./ ${yellow} J |)'( | ` F`.'/ ${cyan} _ ${yellow} -\<| F __ .-\< ${cyan}(_) ${yellow} | / .-'${cyan}. ${yellow}`. /${cyan}-. ${yellow}L___ -${yellow} J \\ \< ${cyan}\ ${yellow} | | ${black}O${cyan}\\${yellow}|.-' ${cyan} _ +${yellow} J \\ \< ${cyan}\\ ${yellow} | | ${black}O${cyan}\\${yellow}|.-' ${cyan} _ ${yellow} _J \\ .- \\${cyan}/ ${black}O ${cyan}| ${yellow}| \\ |${yellow}F ${cyan}(_) ${yellow} '-F -\<_. \\ .-' `-' L__ ${yellow}__J _ _. >-' )${red}._. ${yellow}|-' -${yellow} `-|.' /_. ${red}\_| ${yellow} F +${yellow} `-|.' /_. ${red}\\_| ${yellow} F ${yellow} /.- . _.\< ${yellow} /' /.' .' `\\ ${yellow} /L /' |/ _.-'-\\ -${yellow} /'J ___.---'\| -${yellow} |\ .--' V | `. ` +${yellow} /'J ___.---'\\| +${yellow} |\\ .--' V | `. ` ${yellow} |/`. `-. `._) ${yellow} / .-.\\ ${yellow} \\ ( `\\ diff --git a/assets/ascii/parsix.txt b/assets/ascii/parsix.txt index 7bb09876..41a02dec 100644 --- a/assets/ascii/parsix.txt +++ b/assets/ascii/parsix.txt @@ -13,7 +13,7 @@ ${white}-/:::::::::/:${black}`:-. .-:${white}`:///////////- `${white}-::::--${yellow}.-://.${black}---....---${yellow}`:+/:-${white}--::::-` ${yellow}-/+///+o/-${black}.----.${yellow}.:oo+++o+. ${yellow}-+/////+++o:${red}syyyyy.${yellow}o+++++++++: - ${yellow}.+////+++++-${red}+sssssy+${yellow}.++++++++++\ + ${yellow}.+////+++++-${red}+sssssy+${yellow}.++++++++++\\ ${yellow}.+:/++++++.${red}.yssssssy-${yellow}`+++++++++: ${yellow}:/+++++- ${red}+sssssssss ${yellow}-++++++- ${yellow}`--` ${red}+sssssssso ${yellow}`--` diff --git a/assets/ascii/ubuntu.txt b/assets/ascii/ubuntu.txt index 09be9e0d..b213976f 100644 --- a/assets/ascii/ubuntu.txt +++ b/assets/ascii/ubuntu.txt @@ -1,20 +1,20 @@ -${red} .-/+oossssoo+\-. +${red} .-/+oossssoo+\\-. ${red} `:+ssssssssssssssssss+:` ${red} -+ssssssssssssssssssyyssss+- ${red} .ossssssssssssssssss${white}dMMMNy${red}sssso. -${red} /sssssssssss${white}hdmmNNmmyNMMMMh${red}ssssss\ +${red} /sssssssssss${white}hdmmNNmmyNMMMMh${red}ssssss\\ ${red} +sssssssss${white}hm${red}yd${white}MMMMMMMNddddy${red}ssssssss+ -${red} /ssssssss${white}hNMMM${red}yh${white}hyyyyhmNMMMNh${red}ssssssss\ +${red} /ssssssss${white}hNMMM${red}yh${white}hyyyyhmNMMMNh${red}ssssssss\\ ${red}.ssssssss${white}dMMMNh${red}ssssssssss${white}hNMMMd${red}ssssssss. ${red}+ssss${white}hhhyNMMNy${red}ssssssssssss${white}yNMMMy${red}sssssss+ ${red}oss${white}yNMMMNyMMh${red}ssssssssssssss${white}hmmmh${red}ssssssso ${red}oss${white}yNMMMNyMMh${red}sssssssssssssshmmmh${red}ssssssso ${red}+ssss${white}hhhyNMMNy${red}ssssssssssss${white}yNMMMy${red}sssssss+ ${red}.ssssssss${white}dMMMNh${red}ssssssssss${white}hNMMMd${red}ssssssss. -${red} \ssssssss${white}hNMMM${red}yh${white}hyyyyhdNMMMNh${red}ssssssss/ +${red} \\ssssssss${white}hNMMM${red}yh${white}hyyyyhdNMMMNh${red}ssssssss/ ${red} +sssssssss${white}dm${red}yd${white}MMMMMMMMddddy${red}ssssssss+ -${red} \sssssssssss${white}hdmNNNNmyNMMMMh${red}ssssss/ +${red} \\sssssssssss${white}hdmNNNNmyNMMMMh${red}ssssss/ ${red} .ossssssssssssssssss${white}dMMMNy${red}sssso. ${red} -+sssssssssssssssss${white}yyy${red}ssss+- ${red} `:+ssssssssssssssssss+:` -${red} .-\+oossssoo+/-. +${red} .-\\+oossssoo+/-. From 196ed62a52bdf8a890e0a59d4c91a65dbaa98a90 Mon Sep 17 00:00:00 2001 From: Toni500git Date: Tue, 24 Jun 2025 18:24:10 +0200 Subject: [PATCH 030/143] chore: rename systemInfo -> modulesInfo --- include/parse.hpp | 20 ++++++++------------ include/query.hpp | 4 ---- src/display.cpp | 6 ++---- src/gui.cpp | 4 ++-- src/main.cpp | 1 + src/parse.cpp | 44 ++++++++++++++------------------------------ 6 files changed, 27 insertions(+), 52 deletions(-) diff --git a/include/parse.hpp b/include/parse.hpp index 21d9bef3..a6f54367 100644 --- a/include/parse.hpp +++ b/include/parse.hpp @@ -26,11 +26,7 @@ #ifndef _PARSE_HPP #define _PARSE_HPP -#include -#include #include -#include -#include #include #include "config.hpp" @@ -42,7 +38,7 @@ */ struct parse_args_t { - moduleMap_t& systemInfo; + moduleMap_t& modulesInfo; std::string& pureOutput; std::vector& layout; std::vector& tmp_layout; @@ -53,10 +49,10 @@ struct parse_args_t bool no_more_reset = false; }; -/* Parse input, in-place, with data from systemInfo. +/* Parse input, in-place, with data from modulesInfo. * Documentation on formatting is in the flag -w or the customfetch.1 manual. * @param input The string to parse - * @param systemInfo The system infos + * @param modulesInfo The system infos * @param pureOutput The output of the string but without tags * @param layout The layout of customfetch * @param tmp_layout The temponary layout to be used for $ modules @@ -65,7 +61,7 @@ struct parse_args_t * @param parsingLayout If we are parsing layout or not * @param no_more_reset If we are recursively parsing, e.g we are inside tags */ -std::string parse(std::string input, moduleMap_t& systemInfo, std::string& pureOutput, std::vector& layout, +std::string parse(std::string input, moduleMap_t& modulesInfo, std::string& pureOutput, std::vector& layout, std::vector& tmp_layout, const Config& config, const colors_t& colors, const bool parsingLayout, bool& no_more_reset); @@ -75,7 +71,7 @@ std::string parse(const std::string& input, parse_args_t& parse_args); // so we have to create a tmp string just for the sake of the function arguments std::string parse(const std::string& input, std::string& _, parse_args_t& parse_args); -/* Set module members values to a systemInfo_t map. +/* Set module members values to a modulesInfo_t map. * If the name of said module matches any module name, it will be added * else, error out. * @param moduleName The module name @@ -85,7 +81,7 @@ std::string parse(const std::string& input, std::string& _, parse_args_t& parse_ // void addValueFromModuleMember(const std::string& moduleName, const std::string& moduleMemberName, // parse_args_t& parse_args); -/* Set module only values to a systemInfo_t map. +/* Set module only values to a modulesInfo_t map. * If the name of said module matches any module name, it will be added * else, error out. * @param moduleName The module name @@ -95,11 +91,11 @@ std::string parse(const std::string& input, std::string& _, parse_args_t& parse_ /* * Return an info module member value - * @param systemInfo The systemInfo_t map + * @param modulesInfo The modulesInfo_t map * @param moduleName The module name * @param moduleMemberName The module member name */ -const std::string getInfoFromName(const moduleMap_t& systemInfo, const std::string_view moduleName, +const std::string getInfoFromName(const moduleMap_t& modulesInfo, const std::string_view moduleName, const std::string_view moduleMemberName); /* diff --git a/include/query.hpp b/include/query.hpp index 3d1abbf6..727f0547 100644 --- a/include/query.hpp +++ b/include/query.hpp @@ -27,16 +27,12 @@ #define _QUERY_HPP #include -#include -#include -#include #include #include #include #include #include "config.hpp" -#include "util.hpp" #include "common.hpp" extern "C" { diff --git a/src/display.cpp b/src/display.cpp index b93b3b4c..5c0cdacc 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -29,9 +29,7 @@ #include #include -#include #include -#include #include "platform.hpp" @@ -97,7 +95,7 @@ std::string Display::detect_distro(const Config& config) #endif } -static std::vector render_with_image(moduleMap_t& systemInfo, std::vector& layout, +static std::vector render_with_image(moduleMap_t& modulesInfo, std::vector& layout, const Config& config, const colors_t& colors, const std::filesystem::path& path, const std::uint16_t font_width, const std::uint16_t font_height) @@ -119,7 +117,7 @@ static std::vector render_with_image(moduleMap_t& systemInfo, std:: std::string _; std::vector tmp_layout; - parse_args_t parse_args{ systemInfo, _, layout, tmp_layout, config, colors, true }; + parse_args_t parse_args{ modulesInfo, _, layout, tmp_layout, config, colors, true }; for (size_t i = 0; i < layout.size(); ++i) { layout[i] = parse(layout[i], parse_args); diff --git a/src/gui.cpp b/src/gui.cpp index c4b20f0e..37aaa06b 100644 --- a/src/gui.cpp +++ b/src/gui.cpp @@ -63,7 +63,7 @@ using namespace GUI; static std::vector render_with_image(const Config& config, const colors_t& colors) { std::string path{ Display::detect_distro(config) }; - moduleMap_t systemInfo{}; + moduleMap_t modulesInfo{}; std::vector layout{ config.args_layout.empty() ? config.layout : config.args_layout }; int image_width, image_height, channels; @@ -90,7 +90,7 @@ static std::vector render_with_image(const Config& config, const co std::ifstream file(path, std::ios::binary); std::string line, _; std::vector tmp_layout; - parse_args_t parse_args{ systemInfo, _, layout, tmp_layout, config, colors, false }; + parse_args_t parse_args{ modulesInfo, _, layout, tmp_layout, config, colors, false }; while (std::getline(file, line)) { parse(line, parse_args); diff --git a/src/main.cpp b/src/main.cpp index a422e397..918129ac 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -908,6 +908,7 @@ int main(int argc, char *argv[]) #if CF_LINUX if (os_release) fclose(os_release); if (cpuinfo) fclose(cpuinfo); + if (meminfo) fclose(meminfo); #endif UNLOAD_LIBRARY(cufetch_handle); diff --git a/src/parse.cpp b/src/parse.cpp index 2e784fab..0137ac82 100644 --- a/src/parse.cpp +++ b/src/parse.cpp @@ -207,13 +207,13 @@ static std::string convert_ansi_escape_rgb(const std::string_view noesc_str) std::string parse(const std::string& input, std::string& _, parse_args_t& parse_args) { - return parse(input, parse_args.systemInfo, _, parse_args.layout, parse_args.tmp_layout, parse_args.config, + return parse(input, parse_args.modulesInfo, _, parse_args.layout, parse_args.tmp_layout, parse_args.config, parse_args.colors, parse_args.parsingLayout, parse_args.no_more_reset); } std::string parse(const std::string& input, parse_args_t& parse_args) { - return parse(input, parse_args.systemInfo, parse_args.pureOutput, parse_args.layout, parse_args.tmp_layout, + return parse(input, parse_args.modulesInfo, parse_args.pureOutput, parse_args.layout, parse_args.tmp_layout, parse_args.config, parse_args.colors, parse_args.parsingLayout, parse_args.no_more_reset); } @@ -247,16 +247,16 @@ std::string get_and_color_percentage(const float n1, const float n2, parse_args_ const std::string getInfoFromName(const moduleMap_t& modulesInfo, std::string moduleName) { - /* Position of the open parenthesis, -1 (18 billion smth because it's a size_t) if we aren't in there */ - size_t open_par_pos = -1; + /* Position of the open parenthesis */ + int open_par_pos = -1; int i = -1; /* argument that's collected from what's between the parenthesis in "module(...).test" */ std::string arg; - for (const char& c : moduleName) + for (const char c : moduleName) { i++; - if (c == '(' && open_par_pos == (size_t)-1) + if (c == '(' && open_par_pos == -1) { open_par_pos = i; continue; @@ -266,10 +266,10 @@ const std::string getInfoFromName(const moduleMap_t& modulesInfo, std::string mo /* TODO(burntranch): get separator from a common header or config that both libcufetch and we read from. */ if (c == '.') { - if (open_par_pos != (size_t)-1 && arg.back() != ')') + if (open_par_pos != -1 && arg.back() != ')') die("Module name `{}` is invalid. Arguments must end with )", moduleName); - if (open_par_pos != (size_t)-1) + if (open_par_pos != -1) { arg.pop_back(); moduleName.erase(open_par_pos, arg.length() + 2); @@ -278,7 +278,7 @@ const std::string getInfoFromName(const moduleMap_t& modulesInfo, std::string mo break; } - if (open_par_pos != (size_t)-1) + if (open_par_pos != -1) arg += c; } @@ -657,23 +657,7 @@ std::optional parse_info_tag(Parser& parser, parse_args_t& parse_ar if (!evaluate) return {}; - // const size_t dot_pos = module.find('.'); - // if (dot_pos == module.npos) - // { - // // addValueFromModule(module, parse_args); - // const std::string& info = getInfoFromName(parse_args.systemInfo, module, "module-" + module); - - // if (parser.dollar_pos != std::string::npos) - // parse_args.pureOutput.replace(parser.dollar_pos, module.length() + "$<>"_len, info); - - // return info; - // } - - // const std::string& moduleName = module.substr(0, dot_pos); - // const std::string& moduleMemberName = module.substr(dot_pos + 1); - // addValueFromModuleMember(moduleName, moduleMemberName, parse_args); - - const std::string& info = getInfoFromName(parse_args.systemInfo, module); + const std::string& info = getInfoFromName(parse_args.modulesInfo, module); if (parser.dollar_pos != std::string::npos) parse_args.pureOutput.replace(parser.dollar_pos, module.length() + "$<>"_len, info); @@ -758,7 +742,7 @@ std::string parse(Parser& parser, parse_args_t& parse_args, const bool evaluate, return result; } -std::string parse(std::string input, moduleMap_t& systemInfo, std::string& pureOutput, std::vector& layout, +std::string parse(std::string input, moduleMap_t& modulesInfo, std::string& pureOutput, std::vector& layout, std::vector& tmp_layout, const Config& config, const colors_t& colors, const bool parsingLayout, bool& no_more_reset) { @@ -772,7 +756,7 @@ std::string parse(std::string input, moduleMap_t& systemInfo, std::string& pureO no_more_reset = true; } - parse_args_t parse_args{ systemInfo, pureOutput, layout, tmp_layout, config, + parse_args_t parse_args{ modulesInfo, pureOutput, layout, tmp_layout, config, colors, parsingLayout, true, no_more_reset }; Parser parser{ input, pureOutput }; @@ -916,7 +900,7 @@ void addValueFromModuleMember(const std::string& moduleName, const std::string& // just aliases for convention const Config& config = parse_args.config; - systemInfo_t& sysInfo = parse_args.systemInfo; + modulesInfo_t& sysInfo = parse_args.modulesInfo; const auto& moduleMember_hash = fnv1a16::hash(moduleMemberName); const std::uint16_t byte_unit = config.use_SI_unit ? 1000 : 1024; @@ -1474,7 +1458,7 @@ void addValueFromModule(const std::string& moduleName, parse_args_t& parse_args) // just aliases for convention const Config& config = parse_args.config; - systemInfo_t& sysInfo = parse_args.systemInfo; + modulesInfo_t& sysInfo = parse_args.modulesInfo; const std::uint16_t byte_unit = config.use_SI_unit ? 1000 : 1024; From 8f0a3fd81c136914a44c9e7ba02a9afd925bde31 Mon Sep 17 00:00:00 2001 From: Toni500git Date: Tue, 24 Jun 2025 18:41:23 +0200 Subject: [PATCH 031/143] chore: make auto_colors static again --- include/parse.hpp | 2 -- src/display.cpp | 2 -- src/gui.cpp | 1 - src/parse.cpp | 1 + 4 files changed, 1 insertion(+), 5 deletions(-) diff --git a/include/parse.hpp b/include/parse.hpp index a6f54367..de73db64 100644 --- a/include/parse.hpp +++ b/include/parse.hpp @@ -115,6 +115,4 @@ void append_styles(fmt::text_style& current_style, Styles&&... styles) current_style |= (styles | ...); } -inline std::vector auto_colors; - #endif diff --git a/src/display.cpp b/src/display.cpp index 5c0cdacc..25498401 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -371,8 +371,6 @@ std::vector Display::render(const Config& config, const colors_t& c } } - auto_colors.clear(); - // erase each element for each instance of MAGIC_LINE layout.erase(std::remove_if(layout.begin(), layout.end(), [](const std::string_view str) { return str.find(MAGIC_LINE) != std::string::npos; }), diff --git a/src/gui.cpp b/src/gui.cpp index 37aaa06b..d15e6d5b 100644 --- a/src/gui.cpp +++ b/src/gui.cpp @@ -186,7 +186,6 @@ Window::Window(const Config& config, const colors_t& colors, const std::filesyst style_context->lookup_color("theme_fg_color", fg_color); std::string fg_color_str = rgba_to_hexstr(fg_color);*/ - auto_colors.clear(); this->set_layout_markup(); if (is_live_mode) Glib::signal_timeout().connect(sigc::mem_fun(*this, &Window::set_layout_markup), config.loop_ms); diff --git a/src/parse.cpp b/src/parse.cpp index 0137ac82..aadc96a9 100644 --- a/src/parse.cpp +++ b/src/parse.cpp @@ -371,6 +371,7 @@ std::optional parse_color_tag(Parser& parser, parse_args_t& parse_a } } + static std::vector auto_colors; if (hasStart(color, "auto")) { int ver = color.length() > 4 ? std::stoi(color.substr(4)) - 1 : 0; From 3c63a0f618f02200e103f89b74b31f038683b3e9 Mon Sep 17 00:00:00 2001 From: Toni500git Date: Tue, 24 Jun 2025 20:08:59 +0200 Subject: [PATCH 032/143] plugins: make core-plugins the new query directory --- Makefile | 19 ++++++++----------- include/common.hpp | 10 +++++----- .../core-modules.hh | 2 ++ include/query.hpp | 1 + include/util.hpp | 2 +- src/core-plugins/Makefile | 17 ----------------- src/core-plugins/linux/cpu.cc | 2 +- src/core-plugins/linux/linux-core-modules.cc | 4 ++-- src/core-plugins/linux/os.cc | 4 ++-- src/core-plugins/linux/ram.cc | 2 +- src/core-plugins/linux/system.cc | 3 +-- src/core-plugins/linux/user.cc | 2 +- src/display.cpp | 12 ++++++------ src/main.cpp | 10 +++++----- 14 files changed, 36 insertions(+), 54 deletions(-) rename src/core-plugins/linux/linux-core-modules.hh => include/core-modules.hh (93%) delete mode 100644 src/core-plugins/Makefile diff --git a/Makefile b/Makefile index e1fe35a6..9f52a874 100644 --- a/Makefile +++ b/Makefile @@ -56,13 +56,16 @@ NAME = customfetch TARGET ?= $(NAME) OLDVERSION = 0.10.2 VERSION = 1.0.0 -SRC = $(wildcard src/*.cpp src/query/linux/*.cpp src/query/android/*.cpp src/query/macos/*.cpp src/query/linux/utils/*.cpp) -OBJ = $(SRC:.cpp=.o) +SRC_CPP = $(wildcard src/*.cpp src/core-plugins/linux/utils/*.cpp) +SRC_CC = $(wildcard src/core-plugins/linux/*.cc) +OBJ_CPP = $(SRC_CPP:.cpp=.o) +OBJ_CC = $(SRC_CC:.cc=.o) +OBJ = $(OBJ_CPP) $(OBJ_CC) LDFLAGS += -L./$(BUILDDIR)/fmt -lfmt -ldl CXXFLAGS ?= -mtune=generic -march=native CXXFLAGS += -fvisibility=hidden -Iinclude -std=c++20 $(VARS) -DVERSION=\"$(VERSION)\" -DLOCALEDIR=\"$(LOCALEDIR)\" -DICONPREFIX=\"$(ICONPREFIX)\" -all: genver libcufetch fmt toml json core-plugins $(TARGET) +all: genver libcufetch fmt toml json $(TARGET) libcufetch: ifeq ($(wildcard $(BUILDDIR)/libcufetch.so),) @@ -84,18 +87,12 @@ ifeq ($(wildcard $(BUILDDIR)/json.o),) make -C src/libs/json BUILDDIR=$(BUILDDIR) endif -core-plugins: -ifeq ($(wildcard $(BUILDDIR)/core-plugins/*.so),) - mkdir -p $(BUILDDIR)/core-plugins - make -C src/core-plugins BUILDDIR=$(BUILDDIR) -endif - genver: ./scripts/generateVersion.sh ifeq ($(wildcard include/version.h),) ./scripts/generateVersion.sh endif -$(TARGET): genver fmt toml libcufetch json core-plugins $(OBJ) +$(TARGET): genver fmt toml libcufetch json $(OBJ) mkdir -p $(BUILDDIR) sh ./scripts/generateVersion.sh $(CXX) $(OBJ) $(BUILDDIR)/*.o -o $(BUILDDIR)/$(TARGET) $(LDFLAGS) @@ -160,4 +157,4 @@ updatever: sed -i "s#$(OLDVERSION)#$(VERSION)#g" $(wildcard .github/workflows/*.yml) compile_flags.txt sed -i "s#Project-Id-Version: $(NAME) $(OLDVERSION)#Project-Id-Version: $(NAME) $(VERSION)#g" po/* -.PHONY: $(TARGET) updatever remove uninstall delete dist distclean fmt toml libcufetch core-plugins install all locale +.PHONY: $(TARGET) updatever remove uninstall delete dist distclean fmt toml libcufetch install all locale diff --git a/include/common.hpp b/include/common.hpp index 831f1c06..81b5dee9 100644 --- a/include/common.hpp +++ b/include/common.hpp @@ -16,8 +16,6 @@ #define _(s) (char*)s #endif -#define BOLD_COLOR(x) (fmt::emphasis::bold | fmt::fg(x)) - constexpr const char NOCOLOR[] = "\033[0m"; constexpr const char NOCOLOR_BOLD[] = "\033[0m\033[1m"; constexpr const char UNKNOWN[] = "(unknown)"; @@ -43,10 +41,10 @@ constexpr const char MAGIC_LINE[] = "(cut this line NOW!! RAHHH)"; #define APICALL extern "C" // {fmt} library already has __attribute__((visibility(value))) fallback so let's use that maybeAdd commentMore actions -#define EXPORT FMT_VISIBILITY("default") void -#define MOD_INIT start +#define EXPORT FMT_VISIBILITY("default") +#define MOD_INIT void start -#define MODFUNC(name) const std::string name(__attribute__((unused)) const std::string& module = "") +#define BOLD_COLOR(x) (fmt::emphasis::bold | fmt::fg(x)) template void error(const std::string_view fmt, Args&&... args) noexcept @@ -91,6 +89,8 @@ void info(const std::string_view fmt, Args&&... args) noexcept fmt::format(fmt::runtime(fmt), std::forward(args)...)); } +#undef BOLD_COLOR + struct module_t { std::string name; diff --git a/src/core-plugins/linux/linux-core-modules.hh b/include/core-modules.hh similarity index 93% rename from src/core-plugins/linux/linux-core-modules.hh rename to include/core-modules.hh index bfcd8649..6594b088 100644 --- a/src/core-plugins/linux/linux-core-modules.hh +++ b/include/core-modules.hh @@ -4,6 +4,8 @@ #include #include +#define MODFUNC(name) const std::string name(__attribute__((unused)) const std::string& module = "") + // system.cc inline utsname g_uname_infos; MODFUNC(arch); diff --git a/include/query.hpp b/include/query.hpp index 727f0547..6556ea51 100644 --- a/include/query.hpp +++ b/include/query.hpp @@ -28,6 +28,7 @@ #include #include +#include #include #include #include diff --git a/include/util.hpp b/include/util.hpp index d3ebd5dd..fda7ff2a 100644 --- a/include/util.hpp +++ b/include/util.hpp @@ -282,7 +282,7 @@ bool askUserYorN(bool def, const std::string_view fmt, Args&&... args) fmt::print("{}", inputs_str); while (std::getline(std::cin, result) && (result.length() > 1)) - fmt::print(BOLD_COLOR(fmt::rgb(fmt::color::yellow)), "Please answear y or n,{}", inputs_str); + warn("Please answear y or n {}", inputs_str); ctrl_d_handler(std::cin); diff --git a/src/core-plugins/Makefile b/src/core-plugins/Makefile deleted file mode 100644 index 7c44270b..00000000 --- a/src/core-plugins/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -CXX ?= g++ -CXX_INCLUDES = -I../../include -CXX_FLAGS = -ggdb3 -shared -fPIC -fvisibility=hidden -fvisibility-inlines-hidden -DNDEBUG -shared -Wl,-soname,libcufetch-core-modules.so.1 - -SRC = $(wildcard linux/*.cc) -OBJ = $(SRC:.cc=.o) - -all: linux-core-modules - -linux-core-modules: - $(CXX) $(CXX_INCLUDES) $(CXX_FLAGS) linux/*.cc linux/utils/*.cpp ../util.cpp -o $@.so - mv -f $@.so ../../$(BUILDDIR)/core-plugins/$@.so - -clean: - rm -f *.o *.so *.a ../../$(BUILDDIR)/core-plugins/.*so - -.PHONY: clean all linux-core-modules diff --git a/src/core-plugins/linux/cpu.cc b/src/core-plugins/linux/cpu.cc index 069ff99f..9af7a694 100644 --- a/src/core-plugins/linux/cpu.cc +++ b/src/core-plugins/linux/cpu.cc @@ -4,7 +4,7 @@ #include "common.hpp" #include "fmt/format.h" -#include "linux-core-modules.hh" +#include "core-modules.hh" #include "util.hpp" const std::string freq_dir = "/sys/devices/system/cpu/cpu0/cpufreq"; diff --git a/src/core-plugins/linux/linux-core-modules.cc b/src/core-plugins/linux/linux-core-modules.cc index 7de68785..c3903640 100644 --- a/src/core-plugins/linux/linux-core-modules.cc +++ b/src/core-plugins/linux/linux-core-modules.cc @@ -4,14 +4,14 @@ #include #include #include -#include "linux-core-modules.hh" +#include "core-modules.hh" #include "common.hpp" #include "fmt/format.h" #include "util.hpp" using unused = const std::string&; -APICALL EXPORT MOD_INIT(void *handle) +void core_plugins_start(void *handle) { // ------------ INIT STUFF ------------ if (!handle) diff --git a/src/core-plugins/linux/os.cc b/src/core-plugins/linux/os.cc index ce5fa73c..e900d75e 100644 --- a/src/core-plugins/linux/os.cc +++ b/src/core-plugins/linux/os.cc @@ -8,7 +8,7 @@ #define FMT_HEADER_ONLY 1 #include "common.hpp" #include "fmt/format.h" -#include "linux-core-modules.hh" +#include "core-modules.hh" #include "switch_fnv1a.hpp" #include "util.hpp" @@ -37,7 +37,7 @@ static std::string read_value(const std::string_view name) char* end = strrchr(start, '"'); /* Get last occurence of " */ if (!end) end = line + strlen(line) - 1; /* Set to the end of the string -- no newline. (I heard Windows has a different newline sequence.. *sigh*) */ - + result.assign(start, end - start); break; } diff --git a/src/core-plugins/linux/ram.cc b/src/core-plugins/linux/ram.cc index cdc56472..92533f63 100644 --- a/src/core-plugins/linux/ram.cc +++ b/src/core-plugins/linux/ram.cc @@ -1,5 +1,5 @@ #include "common.hpp" -#include "linux-core-modules.hh" +#include "core-modules.hh" #include #include #include diff --git a/src/core-plugins/linux/system.cc b/src/core-plugins/linux/system.cc index 6845c713..107d0573 100644 --- a/src/core-plugins/linux/system.cc +++ b/src/core-plugins/linux/system.cc @@ -5,8 +5,7 @@ #include #include "common.hpp" -#include "fmt/base.h" -#include "linux-core-modules.hh" +#include "core-modules.hh" #include "util.hpp" /* The handler that we'll use for our module, Handlers return const std::string (WILL be changed to const char diff --git a/src/core-plugins/linux/user.cc b/src/core-plugins/linux/user.cc index 3e717835..18782615 100644 --- a/src/core-plugins/linux/user.cc +++ b/src/core-plugins/linux/user.cc @@ -2,7 +2,7 @@ #include #include "common.hpp" #include "fmt/format.h" -#include "linux-core-modules.hh" +#include "core-modules.hh" #include "switch_fnv1a.hpp" #include "utils/term.hpp" #include "utils/dewm.hpp" diff --git a/src/display.cpp b/src/display.cpp index 25498401..1dc42a76 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -59,8 +59,8 @@ #include "fmt/format.h" #include "parse.hpp" #include "platform.hpp" -#include "query.hpp" #include "stb_image.h" +#include "core-modules.hh" #include "utf8/checked.h" #include "util.hpp" @@ -74,14 +74,14 @@ std::string Display::detect_distro(const Config& config) } else { - Query::System system; - std::string format; - - format = fmt::format("{}/ascii/{}.txt", config.data_dir, str_tolower(system.os_id())); + std::string format; + format = fmt::format("{}/ascii/{}.txt", config.data_dir, str_tolower(os_name_id())); + debug("checking path in {}: {}", __func__, format); if (std::filesystem::exists(format)) return format; - format = fmt::format("{}/ascii/{}.txt", config.data_dir, str_tolower(system.os_name())); + format = fmt::format("{}/ascii/{}.txt", config.data_dir, str_tolower(os_name())); + debug("checking path in {}: {}", __func__, format); if (std::filesystem::exists(format)) return format; } diff --git a/src/main.cpp b/src/main.cpp index 918129ac..f2bce1fe 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -23,6 +23,7 @@ * */ +#include #include #include @@ -38,16 +39,13 @@ #include "config.hpp" #include "display.hpp" #include "fmt/ranges.h" -#include "fmt/std.h" #include "gui.hpp" #include "platform.hpp" #include "query.hpp" #include "switch_fnv1a.hpp" #include "util.hpp" -#if CF_LINUX -# include "core-plugins/linux/linux-core-modules.hh" -#endif +#include "core-modules.hh" #if (!__has_include("version.h")) # error "version.h not found, please generate it with ./scripts/generateVersion.sh" @@ -757,6 +755,7 @@ static void localize(void) #endif } +void core_plugins_start(void *handle); int main(int argc, char *argv[]) { @@ -797,6 +796,7 @@ int main(int argc, char *argv[]) die("Failed to load {}", dlerror()); /* TODO(burntranch): track each library and unload them. */ + core_plugins_start(cufetch_handle); const std::filesystem::path modDir = configDir / "mods"; std::filesystem::create_directories(modDir); for (const auto& entry : std::filesystem::directory_iterator{modDir}) @@ -814,7 +814,7 @@ int main(int argc, char *argv[]) LOAD_LIB_SYMBOL(handle, void, start, void*) - MOD_INIT(cufetch_handle); + start(cufetch_handle); } LOAD_LIB_SYMBOL(cufetch_handle, const std::vector&, cfGetModules) From a4562fe405f1d23e475632cc373a3b1e452f91be Mon Sep 17 00:00:00 2001 From: Toni500git Date: Tue, 24 Jun 2025 21:27:40 +0200 Subject: [PATCH 033/143] core-plugins: linux: add some modules from ram let burnt cook up something --- include/core-modules.hh | 2 + include/util.hpp | 4 +- src/core-plugins/linux/linux-core-modules.cc | 37 +++++++++----- src/core-plugins/linux/ram.cc | 8 ++- src/parse.cpp | 52 ++++++++++---------- src/util.cpp | 10 ++-- 6 files changed, 68 insertions(+), 45 deletions(-) diff --git a/include/core-modules.hh b/include/core-modules.hh index 6594b088..08194923 100644 --- a/include/core-modules.hh +++ b/include/core-modules.hh @@ -59,8 +59,10 @@ MODFUNC(user_de_version); inline std::FILE* meminfo; double ram_free(); double ram_total(); +double ram_used(); double swap_free(); double swap_total(); +double swap_used(); #undef MODFUNC #define MODFUNC(name) const std::string name(__attribute__((unused)) const std::string& module) diff --git a/include/util.hpp b/include/util.hpp index fda7ff2a..d615a0bc 100644 --- a/include/util.hpp +++ b/include/util.hpp @@ -115,13 +115,13 @@ void getFileValue(u_short& iterIndex, const std::string_view line, std::string& * @param base Base to devide (1000 = bytes OR 1024 = bibytes) * @param maxprefix The maxinum prefix we can go up to (empty for ignore) */ -byte_units_t auto_devide_bytes(const double num, const std::uint16_t base, const std::string_view maxprefix = ""); +byte_units_t auto_divide_bytes(const double num, const std::uint16_t base, const std::string_view maxprefix = ""); /* Covert bytes (or bibytes) to be accurate to a specific prefix * @param num The number to convert * @param prefix The prefix we want to convert to (GiB, MB, etc.) */ -byte_units_t devide_bytes(const double num, const std::string_view prefix); +byte_units_t divide_bytes(const double num, const std::string_view prefix); /* Check if file is image (static or gif). * Doesn't check for mp4, mp3 or other binary formats diff --git a/src/core-plugins/linux/linux-core-modules.cc b/src/core-plugins/linux/linux-core-modules.cc index c3903640..57ab638b 100644 --- a/src/core-plugins/linux/linux-core-modules.cc +++ b/src/core-plugins/linux/linux-core-modules.cc @@ -11,6 +11,23 @@ using unused = const std::string&; +const std::string amount(const double amount, const std::string& prefix) +{ + constexpr std::array sorted_valid_prefixes = { "B", "EB", "EiB", "GB", "GiB", "kB", + "KiB", "MB", "MiB", "PB", "PiB", "TB", + "TiB", "YB", "YiB", "ZB", "ZiB" }; + + if (prefix.empty()) + { + byte_units_t amount_unit = auto_divide_bytes(amount * 1024, 1024); + return fmt::format("{:.2f} {}", amount_unit.num_bytes, amount_unit.unit); + } + + if (std::binary_search(sorted_valid_prefixes.begin(), sorted_valid_prefixes.end(), prefix)) + return fmt::format("{:.2f}", divide_bytes(amount, prefix).num_bytes); + return "0"; +} + void core_plugins_start(void *handle) { // ------------ INIT STUFF ------------ @@ -229,15 +246,13 @@ void core_plugins_start(void *handle) cfRegisterModule(user_module); // $ - constexpr std::array sorted_valid_prefixes = { "B", "EB", "EiB", "GB", "GiB", "kB", - "KiB", "MB", "MiB", "PB", "PiB", "TB", - "TiB", "YB", "YiB", "ZB", "ZiB" }; - const auto& return_devided_bytes = [&](const double& amount, const std::string& module) -> double { - const std::string& prefix = module.substr(module.find('-') + 1); - if (std::binary_search(sorted_valid_prefixes.begin(), sorted_valid_prefixes.end(), prefix)) - return devide_bytes(amount, prefix).num_bytes; - - return 0; - }; - module_t ram_free_module{"free", {}, NULL}; + module_t ram_free_module = {"free", {}, [&](const std::string& prefix) { return amount(ram_free(), prefix); }}; + module_t ram_used_module = {"used", {}, [&](const std::string& prefix) { return amount(ram_used(), prefix); }}; + module_t ram_total_module = {"total", {}, [&](const std::string& prefix) { return amount(ram_total(), prefix); }}; + module_t ram_module = {"ram", { + std::move(ram_free_module), + std::move(ram_used_module), + std::move(ram_total_module) + }, NULL}; + cfRegisterModule(ram_module); } diff --git a/src/core-plugins/linux/ram.cc b/src/core-plugins/linux/ram.cc index 92533f63..ac9365ad 100644 --- a/src/core-plugins/linux/ram.cc +++ b/src/core-plugins/linux/ram.cc @@ -19,7 +19,7 @@ static double read_value(const std::string_view key) continue; // Skip colon and whitespace - char* value = line + 1; + char* value = line + key.length(); while (isspace(*value)) value++; // Find end of numeric value (stop at first non-digit or '.') @@ -42,8 +42,14 @@ double ram_free() double ram_total() { return read_value("MemTotal:"); } +double ram_used() +{ return ram_total() - ram_free(); } + double swap_free() { return read_value("SwapFree:"); } double swap_total() { return read_value("SwapTotal:"); } + +double swap_used() +{ return swap_total() - swap_free(); } diff --git a/src/parse.cpp b/src/parse.cpp index aadc96a9..e23ebad1 100644 --- a/src/parse.cpp +++ b/src/parse.cpp @@ -909,10 +909,10 @@ void addValueFromModuleMember(const std::string& moduleName, const std::string& "KiB", "MB", "MiB", "PB", "PiB", "TB", "TiB", "YB", "YiB", "ZB", "ZiB" }; - const auto& return_devided_bytes = [&sorted_valid_prefixes, &moduleMemberName](const double& amount) -> double { + const auto& return_divided_bytes = [&sorted_valid_prefixes, &moduleMemberName](const double& amount) -> double { const std::string& prefix = moduleMemberName.substr(moduleMemberName.find('-') + 1); if (std::binary_search(sorted_valid_prefixes.begin(), sorted_valid_prefixes.end(), prefix)) - return devide_bytes(amount, prefix).num_bytes; + return divide_bytes(amount, prefix).num_bytes; return 0; }; @@ -1218,9 +1218,9 @@ void addValueFromModuleMember(const std::string& moduleName, const std::string& if (sysInfo.at(moduleName).find(moduleMemberName) == sysInfo.at(moduleName).end()) { - byte_units.at(TOTAL) = auto_devide_bytes(query_disk.total_amount(), byte_unit); - byte_units.at(USED) = auto_devide_bytes(query_disk.used_amount(), byte_unit); - byte_units.at(FREE) = auto_devide_bytes(query_disk.free_amount(), byte_unit); + byte_units.at(TOTAL) = auto_divide_bytes(query_disk.total_amount(), byte_unit); + byte_units.at(USED) = auto_divide_bytes(query_disk.used_amount(), byte_unit); + byte_units.at(FREE) = auto_divide_bytes(query_disk.free_amount(), byte_unit); switch (moduleMember_hash) { @@ -1270,11 +1270,11 @@ void addValueFromModuleMember(const std::string& moduleName, const std::string& default: if (hasStart(moduleMemberName, "free-")) - SYSINFO_INSERT(return_devided_bytes(query_disk.free_amount())); + SYSINFO_INSERT(return_divided_bytes(query_disk.free_amount())); else if (hasStart(moduleMemberName, "used-")) - SYSINFO_INSERT(return_devided_bytes(query_disk.used_amount())); + SYSINFO_INSERT(return_divided_bytes(query_disk.used_amount())); else if (hasStart(moduleMemberName, "total-")) - SYSINFO_INSERT(return_devided_bytes(query_disk.total_amount())); + SYSINFO_INSERT(return_divided_bytes(query_disk.total_amount())); } } } @@ -1296,9 +1296,9 @@ void addValueFromModuleMember(const std::string& moduleName, const std::string& if (sysInfo.at(moduleName).find(moduleMemberName) == sysInfo.at(moduleName).end()) { // idk, trick the diviser - byte_units.at(FREE) = auto_devide_bytes(query_ram.swap_free_amount() * byte_unit, byte_unit); - byte_units.at(USED) = auto_devide_bytes(query_ram.swap_used_amount() * byte_unit, byte_unit); - byte_units.at(TOTAL) = auto_devide_bytes(query_ram.swap_total_amount() * byte_unit, byte_unit); + byte_units.at(FREE) = auto_divide_bytes(query_ram.swap_free_amount() * byte_unit, byte_unit); + byte_units.at(USED) = auto_divide_bytes(query_ram.swap_used_amount() * byte_unit, byte_unit); + byte_units.at(TOTAL) = auto_divide_bytes(query_ram.swap_total_amount() * byte_unit, byte_unit); switch (moduleMember_hash) { @@ -1328,11 +1328,11 @@ void addValueFromModuleMember(const std::string& moduleName, const std::string& default: if (hasStart(moduleMemberName, "free-")) - SYSINFO_INSERT(return_devided_bytes(query_ram.swap_free_amount())); + SYSINFO_INSERT(return_divided_bytes(query_ram.swap_free_amount())); else if (hasStart(moduleMemberName, "used-")) - SYSINFO_INSERT(return_devided_bytes(query_ram.swap_used_amount())); + SYSINFO_INSERT(return_divided_bytes(query_ram.swap_used_amount())); else if (hasStart(moduleMemberName, "total-")) - SYSINFO_INSERT(return_devided_bytes(query_ram.swap_total_amount())); + SYSINFO_INSERT(return_divided_bytes(query_ram.swap_total_amount())); } } } @@ -1354,9 +1354,9 @@ void addValueFromModuleMember(const std::string& moduleName, const std::string& if (sysInfo.at(moduleName).find(moduleMemberName) == sysInfo.at(moduleName).end()) { // idk, trick the diviser - byte_units.at(USED) = auto_devide_bytes(query_ram.used_amount() * byte_unit, byte_unit); - byte_units.at(TOTAL) = auto_devide_bytes(query_ram.total_amount() * byte_unit, byte_unit); - byte_units.at(FREE) = auto_devide_bytes(query_ram.free_amount() * byte_unit, byte_unit); + byte_units.at(USED) = auto_divide_bytes(query_ram.used_amount() * byte_unit, byte_unit); + byte_units.at(TOTAL) = auto_divide_bytes(query_ram.total_amount() * byte_unit, byte_unit); + byte_units.at(FREE) = auto_divide_bytes(query_ram.free_amount() * byte_unit, byte_unit); switch (moduleMember_hash) { @@ -1386,11 +1386,11 @@ void addValueFromModuleMember(const std::string& moduleName, const std::string& default: if (hasStart(moduleMemberName, "free-")) - SYSINFO_INSERT(return_devided_bytes(query_ram.free_amount())); + SYSINFO_INSERT(return_divided_bytes(query_ram.free_amount())); else if (hasStart(moduleMemberName, "used-")) - SYSINFO_INSERT(return_devided_bytes(query_ram.used_amount())); + SYSINFO_INSERT(return_divided_bytes(query_ram.used_amount())); else if (hasStart(moduleMemberName, "total-")) - SYSINFO_INSERT(return_devided_bytes(query_ram.total_amount())); + SYSINFO_INSERT(return_divided_bytes(query_ram.total_amount())); } } } @@ -1546,8 +1546,8 @@ void addValueFromModule(const std::string& moduleName, parse_args_t& parse_args) if (sysInfo.at(moduleName).find(moduleMemberName) == sysInfo.at(moduleName).end()) { - byte_units.at(TOTAL) = auto_devide_bytes(query_disk.total_amount(), byte_unit); - byte_units.at(USED) = auto_devide_bytes(query_disk.used_amount(), byte_unit); + byte_units.at(TOTAL) = auto_divide_bytes(query_disk.total_amount(), byte_unit); + byte_units.at(USED) = auto_divide_bytes(query_disk.used_amount(), byte_unit); const std::string& perc = get_and_color_percentage(query_disk.used_amount(), query_disk.total_amount(), parse_args); @@ -1597,8 +1597,8 @@ void addValueFromModule(const std::string& moduleName, parse_args_t& parse_args) if (sysInfo.at(moduleName).find(moduleMemberName) == sysInfo.at(moduleName).end()) { // idk, trick the divider - byte_units.at(USED) = auto_devide_bytes(query_ram.used_amount() * byte_unit, byte_unit); - byte_units.at(TOTAL) = auto_devide_bytes(query_ram.total_amount() * byte_unit, byte_unit); + byte_units.at(USED) = auto_divide_bytes(query_ram.used_amount() * byte_unit, byte_unit); + byte_units.at(TOTAL) = auto_divide_bytes(query_ram.total_amount() * byte_unit, byte_unit); const std::string& perc = get_and_color_percentage(query_ram.used_amount(), query_ram.total_amount(), parse_args); @@ -1628,8 +1628,8 @@ void addValueFromModule(const std::string& moduleName, parse_args_t& parse_args) if (sysInfo.at(moduleName).find(moduleMemberName) == sysInfo.at(moduleName).end()) { // idk, trick the divider - byte_units.at(USED) = auto_devide_bytes(query_ram.swap_used_amount() * byte_unit, byte_unit); - byte_units.at(TOTAL) = auto_devide_bytes(query_ram.swap_total_amount() * byte_unit, byte_unit); + byte_units.at(USED) = auto_divide_bytes(query_ram.swap_used_amount() * byte_unit, byte_unit); + byte_units.at(TOTAL) = auto_divide_bytes(query_ram.swap_total_amount() * byte_unit, byte_unit); // clang-format off if (byte_units.at(TOTAL).num_bytes < 1) diff --git a/src/util.cpp b/src/util.cpp index 5099f7c6..1989b366 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -141,7 +141,7 @@ std::string read_by_syspath(const std::string_view path, bool report_error) return result; } -byte_units_t auto_devide_bytes(const double num, const std::uint16_t base, const std::string_view maxprefix) +byte_units_t auto_divide_bytes(const double num, const std::uint16_t base, const std::string_view maxprefix) { double size = num; @@ -168,19 +168,19 @@ byte_units_t auto_devide_bytes(const double num, const std::uint16_t base, const return { prefixes.at(counter).data(), size }; } -byte_units_t devide_bytes(const double num, const std::string_view prefix) +byte_units_t divide_bytes(const double num, const std::string_view prefix) { if (prefix != "B") { // GiB // 012 if (prefix.size() == 3 && prefix.at(1) == 'i') - return auto_devide_bytes(num, 1024, prefix); + return auto_divide_bytes(num, 1024, prefix); else - return auto_devide_bytes(num, 1000, prefix); + return auto_divide_bytes(num, 1000, prefix); } - return auto_devide_bytes(num, 0); + return auto_divide_bytes(num, 0); } bool is_file_image(const unsigned char* bytes) From a178c78337b5d4ff6c57d95447cf8cd1667eca21 Mon Sep 17 00:00:00 2001 From: BurntRanch <69512353+BurntRanch@users.noreply.github.com> Date: Wed, 25 Jun 2025 02:40:45 +0300 Subject: [PATCH 034/143] args: add linked list argument support --- include/common.hpp | 16 +++- include/core-modules.hh | 4 +- src/core-plugins/linux/linux-core-modules.cc | 36 ++++---- src/parse.cpp | 90 +++++++++++++++----- 4 files changed, 104 insertions(+), 42 deletions(-) diff --git a/include/common.hpp b/include/common.hpp index 81b5dee9..50ff8162 100644 --- a/include/common.hpp +++ b/include/common.hpp @@ -91,9 +91,23 @@ void info(const std::string_view fmt, Args&&... args) noexcept #undef BOLD_COLOR +/* A linked list including module arguments. An argument may be specified for any part of the module path (e.g. `disk(/).used(GiB)`, `test(a).hi`) */ +struct moduleArgs_t { + struct moduleArgs_t *prev = nullptr; + + std::string name; + std::string value; + + struct moduleArgs_t *next = nullptr; +}; + +struct callbackInfo_t { + struct moduleArgs_t *moduleArgs; +}; + struct module_t { std::string name; std::vector submodules; /* For best performance, use std::move() when adding modules in here. */ - std::function handler; + std::function handler; }; diff --git a/include/core-modules.hh b/include/core-modules.hh index 08194923..25233c51 100644 --- a/include/core-modules.hh +++ b/include/core-modules.hh @@ -4,7 +4,7 @@ #include #include -#define MODFUNC(name) const std::string name(__attribute__((unused)) const std::string& module = "") +#define MODFUNC(name) const std::string name(__attribute__((unused)) const callbackInfo_t *callbackInfo = nullptr) // system.cc inline utsname g_uname_infos; @@ -65,4 +65,4 @@ double swap_total(); double swap_used(); #undef MODFUNC -#define MODFUNC(name) const std::string name(__attribute__((unused)) const std::string& module) +#define MODFUNC(name) const std::string name(__attribute__((unused)) const callbackInfo_t *callbackInfo) diff --git a/src/core-plugins/linux/linux-core-modules.cc b/src/core-plugins/linux/linux-core-modules.cc index 57ab638b..79f2e45b 100644 --- a/src/core-plugins/linux/linux-core-modules.cc +++ b/src/core-plugins/linux/linux-core-modules.cc @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include "core-modules.hh" @@ -72,14 +73,14 @@ void core_plugins_start(void *handle) module_t os_kernel_module = {"kernel", { std::move(os_kernel_name_module), std::move(os_kernel_version_module) - }, [](unused) {return os_kernel_name() + ' ' + os_kernel_version();}}; + }, [](const callbackInfo_t *) {return os_kernel_name() + ' ' + os_kernel_version();}}; module_t os_initsys_name_module = {"name", {}, os_initsys_name}; module_t os_initsys_version_module = {"version", {}, os_initsys_version}; module_t os_initsys_module = {"initsys", { std::move(os_initsys_name_module), std::move(os_initsys_version_module), - }, [](unused) {return os_initsys_name() + ' ' + os_initsys_version();}}; + }, [](const callbackInfo_t *) {return os_initsys_name() + ' ' + os_initsys_version();}}; /* Only for compatibility */ module_t os_pretty_name_module_compat = { "pretty_name", {}, os_pretty_name }; @@ -144,23 +145,23 @@ void core_plugins_start(void *handle) std::move(cpu_freq_bios_module), }, cpu_freq_max}; - module_t cpu_temp_C_module = {"C", {}, [](unused) {return fmt::format("{:.2f}°C", cpu_temp());}}; - module_t cpu_temp_F_module = {"F", {}, [](unused) {return fmt::format("{:.2f}°F", cpu_temp() * 1.8 + 34);}}; - module_t cpu_temp_K_module = {"K", {}, [](unused) {return fmt::format("{:.2f}°K", cpu_temp() + 273.15);}}; + module_t cpu_temp_C_module = {"C", {}, [](const callbackInfo_t *) {return fmt::format("{:.2f}°C", cpu_temp());}}; + module_t cpu_temp_F_module = {"F", {}, [](const callbackInfo_t *) {return fmt::format("{:.2f}°F", cpu_temp() * 1.8 + 34);}}; + module_t cpu_temp_K_module = {"K", {}, [](const callbackInfo_t *) {return fmt::format("{:.2f}°K", cpu_temp() + 273.15);}}; module_t cpu_temp_module = {"temp", { std::move(cpu_temp_C_module), std::move(cpu_temp_F_module), std::move(cpu_temp_K_module), - }, [](unused) {return fmt::format("{:.2f}°C", cpu_temp());}}; + }, [](const callbackInfo_t *) {return fmt::format("{:.2f}°C", cpu_temp());}}; /* Only for compatibility */ module_t cpu_freq_cur_module_compat = {"freq_cur", {}, cpu_freq_cur}; module_t cpu_freq_max_module_compat = {"freq_max", {}, cpu_freq_max}; module_t cpu_freq_min_module_compat = {"freq_min", {}, cpu_freq_min}; module_t cpu_freq_bios_module_compat = {"freq_bios_limit", {}, cpu_freq_bios}; - module_t cpu_temp_C_module_compat = {"temp_C", {}, [](unused) {return fmt::format("{:.2f}", cpu_temp());}}; - module_t cpu_temp_F_module_compat = {"temp_F", {}, [](unused) {return fmt::format("{:.2f}", cpu_temp() * 1.8 + 34);}}; - module_t cpu_temp_K_module_compat = {"temp_K", {}, [](unused) {return fmt::format("{:.2f}", cpu_temp() + 273.15);}}; + module_t cpu_temp_C_module_compat = {"temp_C", {}, [](const callbackInfo_t *) {return fmt::format("{:.2f}", cpu_temp());}}; + module_t cpu_temp_F_module_compat = {"temp_F", {}, [](const callbackInfo_t *) {return fmt::format("{:.2f}", cpu_temp() * 1.8 + 34);}}; + module_t cpu_temp_K_module_compat = {"temp_K", {}, [](const callbackInfo_t *) {return fmt::format("{:.2f}", cpu_temp() + 273.15);}}; module_t cpu_module = {"cpu", { std::move(cpu_name_module), @@ -175,7 +176,7 @@ void core_plugins_start(void *handle) std::move(cpu_temp_C_module_compat), std::move(cpu_temp_F_module_compat), std::move(cpu_temp_K_module_compat), - }, [](unused) { + }, [](const callbackInfo_t *) { return fmt::format("{} ({}) @ {} GHz", cpu_name(), cpu_nproc(), cpu_freq_max()); }}; @@ -191,28 +192,28 @@ void core_plugins_start(void *handle) std::move(user_shell_name_module), std::move(user_shell_path_module), std::move(user_shell_version_module), - }, [](unused) {return user_shell_name() + " " + user_shell_version();}}; + }, [](const callbackInfo_t *) {return user_shell_name() + " " + user_shell_version();}}; module_t user_term_name_module = {"name", {}, user_term_name}; module_t user_term_version_module = {"version", {}, user_shell_version}; module_t user_term_module = {"terminal", { std::move(user_term_version_module), std::move(user_term_name_module) - }, [](unused) {return user_term_name() + " " + user_term_version();}}; + }, [](const callbackInfo_t *) {return user_term_name() + " " + user_term_version();}}; module_t user_wm_name_module = {"name", {}, user_wm_name}; module_t user_wm_version_module = {"version", {}, user_wm_version}; module_t user_wm_module = {"wm", { std::move(user_wm_version_module), std::move(user_wm_name_module) - }, [](unused) {return user_wm_name() + " " + user_wm_version();}}; + }, [](const callbackInfo_t *) {return user_wm_name() + " " + user_wm_version();}}; module_t user_de_name_module = {"name", {}, user_de_name}; module_t user_de_version_module = {"version", {}, user_de_version}; module_t user_de_module = {"de", { std::move(user_de_version_module), std::move(user_de_name_module) - }, [](unused) {return user_de_name() + " " + user_de_version();}}; + }, [](const callbackInfo_t *) {return user_de_name() + " " + user_de_version();}}; /* Only for compatibility */ module_t user_shell_path_module_compat = {"shell_path", {}, user_shell_path}; @@ -246,9 +247,10 @@ void core_plugins_start(void *handle) cfRegisterModule(user_module); // $ - module_t ram_free_module = {"free", {}, [&](const std::string& prefix) { return amount(ram_free(), prefix); }}; - module_t ram_used_module = {"used", {}, [&](const std::string& prefix) { return amount(ram_used(), prefix); }}; - module_t ram_total_module = {"total", {}, [&](const std::string& prefix) { return amount(ram_total(), prefix); }}; + /* TODO(burntranch): readd prefix support */ + module_t ram_free_module = {"free", {}, [&](const callbackInfo_t *) { return std::to_string(ram_free()); }}; + module_t ram_used_module = {"used", {}, [&](const callbackInfo_t *) { return std::to_string(ram_used()); }}; + module_t ram_total_module = {"total", {}, [&](const callbackInfo_t *) { return std::to_string(ram_total()); }}; module_t ram_module = {"ram", { std::move(ram_free_module), std::move(ram_used_module), diff --git a/src/parse.cpp b/src/parse.cpp index e23ebad1..384b2a1e 100644 --- a/src/parse.cpp +++ b/src/parse.cpp @@ -39,6 +39,7 @@ #include #include +#include "common.hpp" #include "config.hpp" #include "fmt/color.h" #include "fmt/format.h" @@ -245,47 +246,92 @@ std::string get_and_color_percentage(const float n1, const float n2, parse_args_ return parse(fmt::format("{}{:.2f}%${{0}}", color, result), _, parse_args); } -const std::string getInfoFromName(const moduleMap_t& modulesInfo, std::string moduleName) +const std::string getInfoFromName(const moduleMap_t& modulesInfo, const std::string &moduleName) { - /* Position of the open parenthesis */ - int open_par_pos = -1; - int i = -1; + std::string name; + name.reserve(moduleName.size()); + + /* true when we find a '(' */ + bool collecting = false; + + /* current position */ + size_t i = -1; + size_t stripped_char_count = 0; /* amount of chars stripped from `name` */ + + /* position of start, resets every separator */ + size_t start_pos = 0; + + moduleArgs_t *moduleArgs = new moduleArgs_t; /* argument that's collected from what's between the parenthesis in "module(...).test" */ std::string arg; + arg.reserve(moduleName.size()); for (const char c : moduleName) { i++; - if (c == '(' && open_par_pos == -1) + if (c == '(' && !collecting) { - open_par_pos = i; + collecting = true; continue; } - /* we've reached the separator, do some validation. */ - /* TODO(burntranch): get separator from a common header or config that both libcufetch and we read from. */ - if (c == '.') - { - if (open_par_pos != -1 && arg.back() != ')') - die("Module name `{}` is invalid. Arguments must end with )", moduleName); + if ((c == '.' || i + 1 == moduleName.size())) { + if (collecting) { + if (arg.back() != ')' && c != ')') + die("Module name `{}` is invalid. Arguments must end with )", moduleName); + + if (arg.back() == ')') + arg.pop_back(); + + moduleArgs_t *moduleArg = moduleArgs; + while (moduleArg->next != nullptr) { + moduleArg = moduleArg->next; + } - if (open_par_pos != -1) - { - arg.pop_back(); - moduleName.erase(open_par_pos, arg.length() + 2); + moduleArg->name = std::string{name.begin() + start_pos, name.end()}; + moduleArg->value = arg; + moduleArg->next = new moduleArgs_t; + moduleArg->next->prev = moduleArg; + + if (c == '.') { + name.push_back('.'); + stripped_char_count++; + } + } else { + name.push_back(c); } - break; + start_pos = i + 1 - stripped_char_count; + arg = ""; + collecting = false; + + continue; + } + + if (!collecting) { + name.push_back(c); + } else { + stripped_char_count++; + arg.push_back(c); } + } + + std::string result = "(unknown/invalid module)"; + if (const auto& it = modulesInfo.find(name); it != modulesInfo.end()) { + struct callbackInfo_t callbackInfo = { moduleArgs }; - if (open_par_pos != -1) - arg += c; + result = it->second.handler(&callbackInfo); } - if (const auto& it = modulesInfo.find(moduleName); it != modulesInfo.end()) - return it->second.handler(arg); + while (moduleArgs) { + moduleArgs_t *next = moduleArgs->next; - return "(unknown/invalid module)"; + delete moduleArgs; + + moduleArgs = next; + } + + return result; } std::string parse(Parser& parser, parse_args_t& parse_args, const bool evaluate = true, const char until = 0); From efa85e9cbd60e24f0273e60db1f747108fa459fc Mon Sep 17 00:00:00 2001 From: Toni500git Date: Wed, 25 Jun 2025 13:04:30 +0200 Subject: [PATCH 035/143] core-plugins: linux: add modules argument for ram --- src/core-plugins/linux/linux-core-modules.cc | 47 +++++++++--------- src/util.cpp | 52 ++++++++++++-------- 2 files changed, 56 insertions(+), 43 deletions(-) diff --git a/src/core-plugins/linux/linux-core-modules.cc b/src/core-plugins/linux/linux-core-modules.cc index 79f2e45b..99b6adbb 100644 --- a/src/core-plugins/linux/linux-core-modules.cc +++ b/src/core-plugins/linux/linux-core-modules.cc @@ -10,22 +10,26 @@ #include "fmt/format.h" #include "util.hpp" -using unused = const std::string&; +using unused = const callbackInfo_t *; -const std::string amount(const double amount, const std::string& prefix) +const std::string amount(const double amount, moduleArgs_t *moduleArgs, const std::string& name) { constexpr std::array sorted_valid_prefixes = { "B", "EB", "EiB", "GB", "GiB", "kB", "KiB", "MB", "MiB", "PB", "PiB", "TB", "TiB", "YB", "YiB", "ZB", "ZiB" }; - if (prefix.empty()) + if (moduleArgs->value.empty() || !moduleArgs->next) { byte_units_t amount_unit = auto_divide_bytes(amount * 1024, 1024); return fmt::format("{:.2f} {}", amount_unit.num_bytes, amount_unit.unit); } + moduleArgs_t *modArgs = moduleArgs; + for (; modArgs && modArgs->name != name; modArgs = modArgs->next); + const std::string& prefix = modArgs->value; + if (std::binary_search(sorted_valid_prefixes.begin(), sorted_valid_prefixes.end(), prefix)) - return fmt::format("{:.2f}", divide_bytes(amount, prefix).num_bytes); + return fmt::format("{:.5f}", divide_bytes(amount * 1024, prefix).num_bytes); return "0"; } @@ -73,14 +77,14 @@ void core_plugins_start(void *handle) module_t os_kernel_module = {"kernel", { std::move(os_kernel_name_module), std::move(os_kernel_version_module) - }, [](const callbackInfo_t *) {return os_kernel_name() + ' ' + os_kernel_version();}}; + }, [](unused) {return os_kernel_name() + ' ' + os_kernel_version();}}; module_t os_initsys_name_module = {"name", {}, os_initsys_name}; module_t os_initsys_version_module = {"version", {}, os_initsys_version}; module_t os_initsys_module = {"initsys", { std::move(os_initsys_name_module), std::move(os_initsys_version_module), - }, [](const callbackInfo_t *) {return os_initsys_name() + ' ' + os_initsys_version();}}; + }, [](unused) {return os_initsys_name() + ' ' + os_initsys_version();}}; /* Only for compatibility */ module_t os_pretty_name_module_compat = { "pretty_name", {}, os_pretty_name }; @@ -145,23 +149,23 @@ void core_plugins_start(void *handle) std::move(cpu_freq_bios_module), }, cpu_freq_max}; - module_t cpu_temp_C_module = {"C", {}, [](const callbackInfo_t *) {return fmt::format("{:.2f}°C", cpu_temp());}}; - module_t cpu_temp_F_module = {"F", {}, [](const callbackInfo_t *) {return fmt::format("{:.2f}°F", cpu_temp() * 1.8 + 34);}}; - module_t cpu_temp_K_module = {"K", {}, [](const callbackInfo_t *) {return fmt::format("{:.2f}°K", cpu_temp() + 273.15);}}; + module_t cpu_temp_C_module = {"C", {}, [](unused) {return fmt::format("{:.2f}°C", cpu_temp());}}; + module_t cpu_temp_F_module = {"F", {}, [](unused) {return fmt::format("{:.2f}°F", cpu_temp() * 1.8 + 34);}}; + module_t cpu_temp_K_module = {"K", {}, [](unused) {return fmt::format("{:.2f}°K", cpu_temp() + 273.15);}}; module_t cpu_temp_module = {"temp", { std::move(cpu_temp_C_module), std::move(cpu_temp_F_module), std::move(cpu_temp_K_module), - }, [](const callbackInfo_t *) {return fmt::format("{:.2f}°C", cpu_temp());}}; + }, [](unused) {return fmt::format("{:.2f}°C", cpu_temp());}}; /* Only for compatibility */ module_t cpu_freq_cur_module_compat = {"freq_cur", {}, cpu_freq_cur}; module_t cpu_freq_max_module_compat = {"freq_max", {}, cpu_freq_max}; module_t cpu_freq_min_module_compat = {"freq_min", {}, cpu_freq_min}; module_t cpu_freq_bios_module_compat = {"freq_bios_limit", {}, cpu_freq_bios}; - module_t cpu_temp_C_module_compat = {"temp_C", {}, [](const callbackInfo_t *) {return fmt::format("{:.2f}", cpu_temp());}}; - module_t cpu_temp_F_module_compat = {"temp_F", {}, [](const callbackInfo_t *) {return fmt::format("{:.2f}", cpu_temp() * 1.8 + 34);}}; - module_t cpu_temp_K_module_compat = {"temp_K", {}, [](const callbackInfo_t *) {return fmt::format("{:.2f}", cpu_temp() + 273.15);}}; + module_t cpu_temp_C_module_compat = {"temp_C", {}, [](unused) {return fmt::format("{:.2f}", cpu_temp());}}; + module_t cpu_temp_F_module_compat = {"temp_F", {}, [](unused) {return fmt::format("{:.2f}", cpu_temp() * 1.8 + 34);}}; + module_t cpu_temp_K_module_compat = {"temp_K", {}, [](unused) {return fmt::format("{:.2f}", cpu_temp() + 273.15);}}; module_t cpu_module = {"cpu", { std::move(cpu_name_module), @@ -176,7 +180,7 @@ void core_plugins_start(void *handle) std::move(cpu_temp_C_module_compat), std::move(cpu_temp_F_module_compat), std::move(cpu_temp_K_module_compat), - }, [](const callbackInfo_t *) { + }, [](unused) { return fmt::format("{} ({}) @ {} GHz", cpu_name(), cpu_nproc(), cpu_freq_max()); }}; @@ -192,28 +196,28 @@ void core_plugins_start(void *handle) std::move(user_shell_name_module), std::move(user_shell_path_module), std::move(user_shell_version_module), - }, [](const callbackInfo_t *) {return user_shell_name() + " " + user_shell_version();}}; + }, [](unused) {return user_shell_name() + " " + user_shell_version();}}; module_t user_term_name_module = {"name", {}, user_term_name}; module_t user_term_version_module = {"version", {}, user_shell_version}; module_t user_term_module = {"terminal", { std::move(user_term_version_module), std::move(user_term_name_module) - }, [](const callbackInfo_t *) {return user_term_name() + " " + user_term_version();}}; + }, [](unused) {return user_term_name() + " " + user_term_version();}}; module_t user_wm_name_module = {"name", {}, user_wm_name}; module_t user_wm_version_module = {"version", {}, user_wm_version}; module_t user_wm_module = {"wm", { std::move(user_wm_version_module), std::move(user_wm_name_module) - }, [](const callbackInfo_t *) {return user_wm_name() + " " + user_wm_version();}}; + }, [](unused) {return user_wm_name() + " " + user_wm_version();}}; module_t user_de_name_module = {"name", {}, user_de_name}; module_t user_de_version_module = {"version", {}, user_de_version}; module_t user_de_module = {"de", { std::move(user_de_version_module), std::move(user_de_name_module) - }, [](const callbackInfo_t *) {return user_de_name() + " " + user_de_version();}}; + }, [](unused) {return user_de_name() + " " + user_de_version();}}; /* Only for compatibility */ module_t user_shell_path_module_compat = {"shell_path", {}, user_shell_path}; @@ -247,10 +251,9 @@ void core_plugins_start(void *handle) cfRegisterModule(user_module); // $ - /* TODO(burntranch): readd prefix support */ - module_t ram_free_module = {"free", {}, [&](const callbackInfo_t *) { return std::to_string(ram_free()); }}; - module_t ram_used_module = {"used", {}, [&](const callbackInfo_t *) { return std::to_string(ram_used()); }}; - module_t ram_total_module = {"total", {}, [&](const callbackInfo_t *) { return std::to_string(ram_total()); }}; + module_t ram_free_module = {"free", {}, [](const callbackInfo_t *callback) { return amount(ram_free(), callback->moduleArgs, "free"); }}; + module_t ram_used_module = {"used", {}, [](const callbackInfo_t *callback) { return amount(ram_used(), callback->moduleArgs, "used"); }}; + module_t ram_total_module = {"total", {}, [](const callbackInfo_t *callback) { return amount(ram_total(), callback->moduleArgs, "total"); }}; module_t ram_module = {"ram", { std::move(ram_free_module), std::move(ram_used_module), diff --git a/src/util.cpp b/src/util.cpp index 1989b366..c3382c27 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -145,7 +145,7 @@ byte_units_t auto_divide_bytes(const double num, const std::uint16_t base, const { double size = num; - std::array prefixes; + std::array prefixes; if (base == 1024) prefixes = { "B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB" }; else if (base == 1000) @@ -153,34 +153,44 @@ byte_units_t auto_divide_bytes(const double num, const std::uint16_t base, const else prefixes = { "B" }; - std::uint16_t counter = 0; - if (maxprefix.empty()) - { - for (; counter < prefixes.size() && size >= base; ++counter) - size /= base; - } - else + size_t counter = 0; + const auto& max_it = !maxprefix.empty() + ? std::find(prefixes.begin(), prefixes.end(), maxprefix) + : prefixes.end(); + + while (counter + 1 < prefixes.size() && size >= base) { - for (; counter < prefixes.size() && size >= base && prefixes.at(counter) != maxprefix; ++counter) - size /= base; + if (max_it != prefixes.end() && prefixes[counter] == maxprefix) + break; + size /= base; + ++counter; } - return { prefixes.at(counter).data(), size }; + return { prefixes[counter].data(), size }; } byte_units_t divide_bytes(const double num, const std::string_view prefix) { - if (prefix != "B") - { - // GiB - // 012 - if (prefix.size() == 3 && prefix.at(1) == 'i') - return auto_divide_bytes(num, 1024, prefix); - else - return auto_divide_bytes(num, 1000, prefix); - } + if (prefix == "B") + return {"B", num}; + + // GiB + // 012 + const std::uint16_t base = (prefix.size() == 3 && prefix[1] == 'i') ? 1024 : 1000; + std::array prefixes; + if (base == 1024) + prefixes = { "B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB" }; + else if (base == 1000) + prefixes = { "B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" }; + + const auto& it = std::find(prefixes.begin(), prefixes.end(), prefix); + if (it == prefixes.end()) + return {"B", num}; + + const size_t index = std::distance(prefixes.begin(), it); + const double value = num / std::pow(static_cast(base), index); - return auto_divide_bytes(num, 0); + return { prefix.data(), value }; } bool is_file_image(const unsigned char* bytes) From 23fb997cfc76ae3c535a3c6338072aa1c6107826 Mon Sep 17 00:00:00 2001 From: Toni500git Date: Wed, 25 Jun 2025 13:50:24 +0200 Subject: [PATCH 036/143] config: move the struct colors_t into it also move moduleMap_t into parse.hpp --- include/config.hpp | 48 ++++++++++++++++++++++----------------------- include/display.hpp | 3 +-- include/gui.hpp | 4 +--- include/parse.hpp | 13 ++++-------- src/config.cpp | 2 +- src/display.cpp | 17 ++++++++-------- src/gui.cpp | 11 +++++------ src/main.cpp | 10 ++++------ src/parse.cpp | 20 +++++++++++-------- 9 files changed, 60 insertions(+), 68 deletions(-) diff --git a/include/config.hpp b/include/config.hpp index 5760e080..4e64ce27 100644 --- a/include/config.hpp +++ b/include/config.hpp @@ -51,34 +51,34 @@ struct override_configs_types int int_value = 0; }; -// config colors -// those without gui_ prefix are for the terminal -struct colors_t -{ - std::string black; - std::string red; - std::string green; - std::string blue; - std::string cyan; - std::string yellow; - std::string magenta; - std::string white; - - std::string gui_black; - std::string gui_red; - std::string gui_green; - std::string gui_blue; - std::string gui_cyan; - std::string gui_yellow; - std::string gui_magenta; - std::string gui_white; -}; - class Config { public: // Create .config directories and files and load the config file (args or default) Config(const std::filesystem::path& configFile, const std::filesystem::path& configDir); + + // config colors + // those without gui_ prefix are for the terminal + struct colors_t + { + std::string black; + std::string red; + std::string green; + std::string blue; + std::string cyan; + std::string yellow; + std::string magenta; + std::string white; + + std::string gui_black; + std::string gui_red; + std::string gui_green; + std::string gui_blue; + std::string gui_cyan; + std::string gui_yellow; + std::string gui_magenta; + std::string gui_white; + } colors; // Variables of config file in [config] table std::vector layout; @@ -141,7 +141,7 @@ class Config * @param colors The colors struct where we'll put the default config colors. * It doesn't include the colors in config.alias-colors */ - void loadConfigFile(const std::filesystem::path& filename, colors_t& colors); + void loadConfigFile(const std::filesystem::path& filename); /** * Generate the default config file at path diff --git a/include/display.hpp b/include/display.hpp index 03009b74..af7a0124 100644 --- a/include/display.hpp +++ b/include/display.hpp @@ -85,11 +85,10 @@ namespace Display /* * Render the layout along side the source file and return the vector * @param config The config class - * @param colors The colors * @param already_analyzed_path If already checked that the source path is not a binary file * @param path Path to source file */ -std::vector render(const Config& config, const colors_t& colors, const bool already_analyzed_path, +std::vector render(const Config& config, const bool already_analyzed_path, const std::filesystem::path& path, moduleMap_t& moduleMap); /* diff --git a/include/gui.hpp b/include/gui.hpp index 96c07822..df5f1af3 100644 --- a/include/gui.hpp +++ b/include/gui.hpp @@ -49,16 +49,14 @@ class Window : public Gtk::Window /** * Initialize and create everything and parse layout with source path. * @param config The config class - * @param colors The non-alias colors struct * @param path The logo source path */ - Window(const Config& config, const colors_t& colors, const std::filesystem::path& path, moduleMap_t& moduleMap); + Window(const Config& config, const std::filesystem::path& path, moduleMap_t& moduleMap); // Destroy the window, handled by GTK virtual ~Window(); private: const Config& m_config; - const colors_t& m_colors; const std::filesystem::path& m_path; moduleMap_t& m_moduleMap; bool isImage; diff --git a/include/parse.hpp b/include/parse.hpp index de73db64..1ce9e0b4 100644 --- a/include/parse.hpp +++ b/include/parse.hpp @@ -30,7 +30,9 @@ #include #include "config.hpp" -#include "query.hpp" + +// Map from a modules name to its pointer. +using moduleMap_t = std::unordered_map; /* The additional args that parse() needs for getting the necessary infos/configs. * Only used for making the argument passing more clear. @@ -43,7 +45,6 @@ struct parse_args_t std::vector& layout; std::vector& tmp_layout; const Config& config; - const colors_t& colors; bool parsingLayout; bool firstrun_clr = true; bool no_more_reset = false; @@ -62,7 +63,7 @@ struct parse_args_t * @param no_more_reset If we are recursively parsing, e.g we are inside tags */ std::string parse(std::string input, moduleMap_t& modulesInfo, std::string& pureOutput, std::vector& layout, - std::vector& tmp_layout, const Config& config, const colors_t& colors, + std::vector& tmp_layout, const Config& config, const bool parsingLayout, bool& no_more_reset); // parse() for parse_args_t& arguments @@ -109,10 +110,4 @@ const std::string getInfoFromName(const moduleMap_t& modulesInfo, const std::str std::string get_and_color_percentage(const float n1, const float n2, parse_args_t& parse_args, const bool invert = false); -template -void append_styles(fmt::text_style& current_style, Styles&&... styles) -{ - current_style |= (styles | ...); -} - #endif diff --git a/src/config.cpp b/src/config.cpp index 1554bc2e..999d94aa 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -49,7 +49,7 @@ Config::Config(const std::filesystem::path& configFile, const std::filesystem::p } } -void Config::loadConfigFile(const std::filesystem::path& filename, colors_t& colors) +void Config::loadConfigFile(const std::filesystem::path& filename) { try { diff --git a/src/display.cpp b/src/display.cpp index 1dc42a76..61701c9e 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -96,9 +96,8 @@ std::string Display::detect_distro(const Config& config) } static std::vector render_with_image(moduleMap_t& modulesInfo, std::vector& layout, - const Config& config, const colors_t& colors, - const std::filesystem::path& path, const std::uint16_t font_width, - const std::uint16_t font_height) + const Config& config, const std::filesystem::path& path, + const std::uint16_t font_width, const std::uint16_t font_height) { int image_width, image_height, channels; @@ -117,7 +116,7 @@ static std::vector render_with_image(moduleMap_t& modulesInfo, std: std::string _; std::vector tmp_layout; - parse_args_t parse_args{ modulesInfo, _, layout, tmp_layout, config, colors, true }; + parse_args_t parse_args{ modulesInfo, _, layout, tmp_layout, config, true }; for (size_t i = 0; i < layout.size(); ++i) { layout[i] = parse(layout[i], parse_args); @@ -222,7 +221,7 @@ static bool get_pos(int& y, int& x) return true; } -std::vector Display::render(const Config& config, const colors_t& colors, const bool already_analyzed_file, +std::vector Display::render(const Config& config, const bool already_analyzed_file, const std::filesystem::path& path, moduleMap_t& moduleMap) { std::vector asciiArt{}, layout{ config.args_layout.empty() ? config.layout : config.args_layout }; @@ -270,7 +269,7 @@ std::vector Display::render(const Config& config, const colors_t& c std::ifstream distro_file(distro_path); std::string line, _; std::vector tmp_layout; - parse_args_t parse_args{ moduleMap, _, layout, tmp_layout, config, colors, false }; + parse_args_t parse_args{ moduleMap, _, layout, tmp_layout, config, false }; while (std::getline(distro_file, line)) { @@ -298,7 +297,7 @@ std::vector Display::render(const Config& config, const colors_t& c get_pos(y, x); fmt::print("\033[{};{}H", y, x); - return render_with_image(moduleMap, layout, config, colors, path, font_width, font_height); + return render_with_image(moduleMap, layout, config, path, font_width, font_height); } if (Display::ascii_logo_fd != -1) @@ -323,7 +322,7 @@ std::vector Display::render(const Config& config, const colors_t& c { std::string pureOutput; std::vector tmp_layout; - parse_args_t parse_args{ moduleMap, pureOutput, layout, tmp_layout, config, colors, false }; + parse_args_t parse_args{ moduleMap, pureOutput, layout, tmp_layout, config, false }; std::string asciiArt_s = parse(line, parse_args); parse_args.no_more_reset = false; @@ -352,7 +351,7 @@ std::vector Display::render(const Config& config, const colors_t& c std::string _; std::vector tmp_layout; - parse_args_t parse_args{ moduleMap, _, layout, tmp_layout, config, colors, true }; + parse_args_t parse_args{ moduleMap, _, layout, tmp_layout, config, true }; for (size_t i = 0; i < layout.size(); ++i) { layout[i] = parse(layout[i], parse_args); diff --git a/src/gui.cpp b/src/gui.cpp index d15e6d5b..257bbcde 100644 --- a/src/gui.cpp +++ b/src/gui.cpp @@ -60,7 +60,7 @@ using namespace GUI; }*/ // Display::render but only for images on GUI -static std::vector render_with_image(const Config& config, const colors_t& colors) +static std::vector render_with_image(const Config& config) { std::string path{ Display::detect_distro(config) }; moduleMap_t modulesInfo{}; @@ -90,7 +90,7 @@ static std::vector render_with_image(const Config& config, const co std::ifstream file(path, std::ios::binary); std::string line, _; std::vector tmp_layout; - parse_args_t parse_args{ modulesInfo, _, layout, tmp_layout, config, colors, false }; + parse_args_t parse_args{ modulesInfo, _, layout, tmp_layout, config, false }; while (std::getline(file, line)) { parse(line, parse_args); @@ -133,19 +133,18 @@ bool Window::set_layout_markup() if (isImage) { if (!m_config.args_print_logo_only) - m_label.set_markup(fmt::format("{}", fmt::join(render_with_image(m_config, m_colors), "\n"))); + m_label.set_markup(fmt::format("{}", fmt::join(render_with_image(m_config), "\n"))); } else { m_label.set_markup( - fmt::format("{}", fmt::join(Display::render(m_config, m_colors, true, m_path, m_moduleMap), "\n"))); + fmt::format("{}", fmt::join(Display::render(m_config, true, m_path, m_moduleMap), "\n"))); } return true; } -Window::Window(const Config& config, const colors_t& colors, const std::filesystem::path& path, moduleMap_t& moduleMap) : +Window::Window(const Config& config, const std::filesystem::path& path, moduleMap_t& moduleMap) : m_config(config), - m_colors(colors), m_path(path), m_moduleMap(moduleMap), isImage(false) diff --git a/src/main.cpp b/src/main.cpp index f2bce1fe..04965981 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -779,8 +779,6 @@ int main(int argc, char *argv[]) #endif // clang-format on - colors_t colors; - const std::filesystem::path configDir = getConfigDir(); const std::filesystem::path configFile = parse_config_path(argc, argv, configDir); @@ -789,7 +787,7 @@ int main(int argc, char *argv[]) Config config(configFile, configDir); if (!parseargs(argc, argv, config, configFile)) return 1; - config.loadConfigFile(configFile, colors); + config.loadConfigFile(configFile); void* cufetch_handle = LOAD_LIBRARY("libcufetch.so") if (!cufetch_handle) @@ -868,7 +866,7 @@ int main(int argc, char *argv[]) #if GUI_APP const auto& app = Gtk::Application::create("org.toni.customfetch"); - GUI::Window window(config, colors, path, moduleMap); + GUI::Window window(config, path, moduleMap); return app->run(window); #endif // GUI_APP @@ -892,13 +890,13 @@ int main(int argc, char *argv[]) write(STDOUT_FILENO, "\33[H\33[2J", 7); fmt::print("\033[0;0H"); - Display::display(Display::render(config, colors, false, path, moduleMap)); + Display::display(Display::render(config, false, path, moduleMap)); std::this_thread::sleep_for(sleep_ms); } } else { - Display::display(Display::render(config, colors, false, path, moduleMap)); + Display::display(Display::render(config, false, path, moduleMap)); } // enable both of them again diff --git a/src/parse.cpp b/src/parse.cpp index 384b2a1e..b61f8d0f 100644 --- a/src/parse.cpp +++ b/src/parse.cpp @@ -29,8 +29,6 @@ #include #include -#include -#include #include #include #include @@ -121,7 +119,7 @@ std::string _; // @param noesc_str The ansi color without \\e[ or \033[ // @param colors The colors struct we'll look at // @return An array of 3 span tags elements in the follow: color, weight, type -static std::array get_ansi_color(const std::string_view noesc_str, const colors_t& colors) +static std::array get_ansi_color(const std::string_view noesc_str, const Config::colors_t& colors) { const size_t first_m = noesc_str.rfind('m'); if (first_m == std::string::npos) @@ -209,13 +207,13 @@ static std::string convert_ansi_escape_rgb(const std::string_view noesc_str) std::string parse(const std::string& input, std::string& _, parse_args_t& parse_args) { return parse(input, parse_args.modulesInfo, _, parse_args.layout, parse_args.tmp_layout, parse_args.config, - parse_args.colors, parse_args.parsingLayout, parse_args.no_more_reset); + parse_args.parsingLayout, parse_args.no_more_reset); } std::string parse(const std::string& input, parse_args_t& parse_args) { return parse(input, parse_args.modulesInfo, parse_args.pureOutput, parse_args.layout, parse_args.tmp_layout, - parse_args.config, parse_args.colors, parse_args.parsingLayout, parse_args.no_more_reset); + parse_args.config, parse_args.parsingLayout, parse_args.no_more_reset); } std::string get_and_color_percentage(const float n1, const float n2, parse_args_t& parse_args, const bool invert) @@ -376,6 +374,12 @@ std::optional parse_command_tag(Parser& parser, parse_args_t& parse return cmd_output; } +template +static void append_styles(fmt::text_style& current_style, Styles&&... styles) +{ + current_style |= (styles | ...); +} + std::optional parse_color_tag(Parser& parser, parse_args_t& parse_args, const bool evaluate) { if (!parser.try_read('{')) @@ -388,7 +392,7 @@ std::optional parse_color_tag(Parser& parser, parse_args_t& parse_a std::string output; const Config& config = parse_args.config; - const colors_t& colors = parse_args.colors; + const Config::colors_t& colors = parse_args.config.colors; const size_t taglen = color.length() + "${}"_len; const std::string endspan{ !parse_args.firstrun_clr ? "" : "" }; @@ -790,7 +794,7 @@ std::string parse(Parser& parser, parse_args_t& parse_args, const bool evaluate, } std::string parse(std::string input, moduleMap_t& modulesInfo, std::string& pureOutput, std::vector& layout, - std::vector& tmp_layout, const Config& config, const colors_t& colors, + std::vector& tmp_layout, const Config& config, const bool parsingLayout, bool& no_more_reset) { if (!config.sep_reset.empty() && parsingLayout && !no_more_reset) @@ -804,7 +808,7 @@ std::string parse(std::string input, moduleMap_t& modulesInfo, std::string& pure } parse_args_t parse_args{ modulesInfo, pureOutput, layout, tmp_layout, config, - colors, parsingLayout, true, no_more_reset }; + parsingLayout, true, no_more_reset }; Parser parser{ input, pureOutput }; std::string ret{ parse(parser, parse_args) }; From 30d0c0b70c5f3a44c30bf4fb6ccbf8f6102c1577 Mon Sep 17 00:00:00 2001 From: Toni500git Date: Wed, 25 Jun 2025 13:54:07 +0200 Subject: [PATCH 037/143] clang-format src/parse.cpp --- src/parse.cpp | 64 +++++++++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 27 deletions(-) diff --git a/src/parse.cpp b/src/parse.cpp index b61f8d0f..7c8d6e39 100644 --- a/src/parse.cpp +++ b/src/parse.cpp @@ -244,7 +244,7 @@ std::string get_and_color_percentage(const float n1, const float n2, parse_args_ return parse(fmt::format("{}{:.2f}%${{0}}", color, result), _, parse_args); } -const std::string getInfoFromName(const moduleMap_t& modulesInfo, const std::string &moduleName) +const std::string getInfoFromName(const moduleMap_t& modulesInfo, const std::string& moduleName) { std::string name; name.reserve(moduleName.size()); @@ -253,13 +253,13 @@ const std::string getInfoFromName(const moduleMap_t& modulesInfo, const std::str bool collecting = false; /* current position */ - size_t i = -1; + size_t i = -1; size_t stripped_char_count = 0; /* amount of chars stripped from `name` */ /* position of start, resets every separator */ size_t start_pos = 0; - moduleArgs_t *moduleArgs = new moduleArgs_t; + moduleArgs_t* moduleArgs = new moduleArgs_t; /* argument that's collected from what's between the parenthesis in "module(...).test" */ std::string arg; @@ -273,56 +273,67 @@ const std::string getInfoFromName(const moduleMap_t& modulesInfo, const std::str continue; } - if ((c == '.' || i + 1 == moduleName.size())) { - if (collecting) { + if ((c == '.' || i + 1 == moduleName.size())) + { + if (collecting) + { if (arg.back() != ')' && c != ')') die("Module name `{}` is invalid. Arguments must end with )", moduleName); - + if (arg.back() == ')') arg.pop_back(); - moduleArgs_t *moduleArg = moduleArgs; - while (moduleArg->next != nullptr) { + moduleArgs_t* moduleArg = moduleArgs; + while (moduleArg->next != nullptr) + { moduleArg = moduleArg->next; } - moduleArg->name = std::string{name.begin() + start_pos, name.end()}; - moduleArg->value = arg; - moduleArg->next = new moduleArgs_t; + moduleArg->name = std::string{ name.begin() + start_pos, name.end() }; + moduleArg->value = arg; + moduleArg->next = new moduleArgs_t; moduleArg->next->prev = moduleArg; - if (c == '.') { + if (c == '.') + { name.push_back('.'); stripped_char_count++; } - } else { + } + else + { name.push_back(c); } - start_pos = i + 1 - stripped_char_count; - arg = ""; + start_pos = i + 1 - stripped_char_count; + arg = ""; collecting = false; continue; } - if (!collecting) { + if (!collecting) + { name.push_back(c); - } else { + } + else + { stripped_char_count++; arg.push_back(c); } } std::string result = "(unknown/invalid module)"; - if (const auto& it = modulesInfo.find(name); it != modulesInfo.end()) { + if (const auto& it = modulesInfo.find(name); it != modulesInfo.end()) + { struct callbackInfo_t callbackInfo = { moduleArgs }; result = it->second.handler(&callbackInfo); } - while (moduleArgs) { - moduleArgs_t *next = moduleArgs->next; + while (moduleArgs) + { + moduleArgs_t* next = moduleArgs->next; delete moduleArgs; @@ -390,10 +401,10 @@ std::optional parse_color_tag(Parser& parser, parse_args_t& parse_a if (!evaluate) return {}; - std::string output; - const Config& config = parse_args.config; + std::string output; + const Config& config = parse_args.config; const Config::colors_t& colors = parse_args.config.colors; - const size_t taglen = color.length() + "${}"_len; + const size_t taglen = color.length() + "${}"_len; const std::string endspan{ !parse_args.firstrun_clr ? "" : "" }; @@ -793,8 +804,8 @@ std::string parse(Parser& parser, parse_args_t& parse_args, const bool evaluate, return result; } -std::string parse(std::string input, moduleMap_t& modulesInfo, std::string& pureOutput, std::vector& layout, - std::vector& tmp_layout, const Config& config, +std::string parse(std::string input, moduleMap_t& modulesInfo, std::string& pureOutput, + std::vector& layout, std::vector& tmp_layout, const Config& config, const bool parsingLayout, bool& no_more_reset) { if (!config.sep_reset.empty() && parsingLayout && !no_more_reset) @@ -807,8 +818,7 @@ std::string parse(std::string input, moduleMap_t& modulesInfo, std::string& pure no_more_reset = true; } - parse_args_t parse_args{ modulesInfo, pureOutput, layout, tmp_layout, config, - parsingLayout, true, no_more_reset }; + parse_args_t parse_args{ modulesInfo, pureOutput, layout, tmp_layout, config, parsingLayout, true, no_more_reset }; Parser parser{ input, pureOutput }; std::string ret{ parse(parser, parse_args) }; From 2134ffdc88f51ce7081b318f5715b00f27ce36f2 Mon Sep 17 00:00:00 2001 From: Toni500git Date: Wed, 25 Jun 2025 14:41:18 +0200 Subject: [PATCH 038/143] misc: dynamically link libcufetch commit is broken rn, fix comin asap --- Makefile | 5 +++-- include/config.hpp | 1 - include/cufetch.hh | 9 +++++++++ {src/libs/cufetch => libcufetch}/Makefile | 6 +++--- {src/libs/cufetch => libcufetch}/cufetch.cc | 13 +++---------- src/core-plugins/linux/linux-core-modules.cc | 12 +++--------- src/main.cpp | 17 +++++------------ 7 files changed, 26 insertions(+), 37 deletions(-) create mode 100644 include/cufetch.hh rename {src/libs/cufetch => libcufetch}/Makefile (54%) rename {src/libs/cufetch => libcufetch}/cufetch.cc (65%) diff --git a/Makefile b/Makefile index 9f52a874..c0b11de7 100644 --- a/Makefile +++ b/Makefile @@ -61,7 +61,7 @@ SRC_CC = $(wildcard src/core-plugins/linux/*.cc) OBJ_CPP = $(SRC_CPP:.cpp=.o) OBJ_CC = $(SRC_CC:.cc=.o) OBJ = $(OBJ_CPP) $(OBJ_CC) -LDFLAGS += -L./$(BUILDDIR)/fmt -lfmt -ldl +LDFLAGS += -L./$(BUILDDIR) -lcufetch -lfmt -ldl CXXFLAGS ?= -mtune=generic -march=native CXXFLAGS += -fvisibility=hidden -Iinclude -std=c++20 $(VARS) -DVERSION=\"$(VERSION)\" -DLOCALEDIR=\"$(LOCALEDIR)\" -DICONPREFIX=\"$(ICONPREFIX)\" @@ -69,7 +69,8 @@ all: genver libcufetch fmt toml json $(TARGET) libcufetch: ifeq ($(wildcard $(BUILDDIR)/libcufetch.so),) - make -C src/libs/cufetch BUILDDIR=$(BUILDDIR) + mkdir -p $(BUILDDIR) + make -C libcufetch BUILDDIR=$(BUILDDIR) endif fmt: diff --git a/include/config.hpp b/include/config.hpp index 4e64ce27..79ff3e08 100644 --- a/include/config.hpp +++ b/include/config.hpp @@ -184,7 +184,6 @@ class Config if (overridePos != overrides.end() && overrides.at(value.data()).value_type == BOOL) return overrides.at(value.data()).bool_value; - // user wants a str (overridable), we found an override matching the name, and the override is a str. if constexpr (std::is_same()) if (overridePos != overrides.end() && overrides.at(value.data()).value_type == STR) return overrides.at(value.data()).string_value; diff --git a/include/cufetch.hh b/include/cufetch.hh new file mode 100644 index 00000000..2afb99f4 --- /dev/null +++ b/include/cufetch.hh @@ -0,0 +1,9 @@ +#include "common.hpp" + +#include + +/* Register a module, and its submodules, to customfetch. */ +void cfRegisterModule(const module_t& module); + +/* Get a list of all modules registered. */ +const std::vector& cfGetModules(); diff --git a/src/libs/cufetch/Makefile b/libcufetch/Makefile similarity index 54% rename from src/libs/cufetch/Makefile rename to libcufetch/Makefile index 87e64053..31c13b4d 100644 --- a/src/libs/cufetch/Makefile +++ b/libcufetch/Makefile @@ -1,14 +1,14 @@ CXX ?= g++ -CXX_INCLUDES = -I../../../include +CXX_INCLUDES = -I../include CXX_FLAGS = -shared -fPIC all: cufetch cufetch: cufetch.cc $(CXX) $(CXX_INCLUDES) $(CXX_FLAGS) cufetch.cc -o libcufetch.so - mv -f libcufetch.so ../../../$(BUILDDIR)/libcufetch.so + mv -f libcufetch.so ../$(BUILDDIR)/libcufetch.so clean: - rm -f *.o *.so *.a ../../../$(BUILDDIR)/cufetch/.*so + rm -f *.o *.so *.a ../$(BUILDDIR)/libcufetch.so .PHONY: clean all cufetch diff --git a/src/libs/cufetch/cufetch.cc b/libcufetch/cufetch.cc similarity index 65% rename from src/libs/cufetch/cufetch.cc rename to libcufetch/cufetch.cc index 15422bfa..92d68683 100644 --- a/src/libs/cufetch/cufetch.cc +++ b/libcufetch/cufetch.cc @@ -1,26 +1,19 @@ -#include - -#include "common.hpp" +#include "cufetch.hh" static std::vector modules; static char separator = '.'; -extern "C" { static void addModule(const module_t& module, const std::string& prefix = "") { modules.emplace_back(module).name = prefix + module.name; for (const module_t& submodule : module.submodules) - { addModule(submodule, prefix + module.name + separator); - } } /* Register a module, and its submodules, to customfetch. */ -[[gnu::unused]] void cfRegisterModule(const module_t& module) { addModule(module); } +void cfRegisterModule(const module_t& module) { addModule(module); } /* Get a list of all modules registered. */ -[[gnu::unused]] const std::vector& cfGetModules() { return modules; } - -} +const std::vector& cfGetModules() { return modules; } diff --git a/src/core-plugins/linux/linux-core-modules.cc b/src/core-plugins/linux/linux-core-modules.cc index 99b6adbb..593a10ad 100644 --- a/src/core-plugins/linux/linux-core-modules.cc +++ b/src/core-plugins/linux/linux-core-modules.cc @@ -5,6 +5,8 @@ #include #include #include + +#include "cufetch.hh" #include "core-modules.hh" #include "common.hpp" #include "fmt/format.h" @@ -33,17 +35,9 @@ const std::string amount(const double amount, moduleArgs_t *moduleArgs, const st return "0"; } -void core_plugins_start(void *handle) +void core_plugins_start() { // ------------ INIT STUFF ------------ - if (!handle) - { - error("Exiting because !handle"); - return; - } - - LOAD_LIB_SYMBOL(handle, void, cfRegisterModule, const module_t& module); - if (uname(&g_uname_infos) != 0) die(_("uname() failed: {}\nCould not get system infos"), strerror(errno)); diff --git a/src/main.cpp b/src/main.cpp index 04965981..ab4dd4cc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -36,6 +36,7 @@ #include #include +#include "cufetch.hh" #include "config.hpp" #include "display.hpp" #include "fmt/ranges.h" @@ -755,7 +756,7 @@ static void localize(void) #endif } -void core_plugins_start(void *handle); +void core_plugins_start(); int main(int argc, char *argv[]) { @@ -789,12 +790,8 @@ int main(int argc, char *argv[]) return 1; config.loadConfigFile(configFile); - void* cufetch_handle = LOAD_LIBRARY("libcufetch.so") - if (!cufetch_handle) - die("Failed to load {}", dlerror()); - /* TODO(burntranch): track each library and unload them. */ - core_plugins_start(cufetch_handle); + core_plugins_start(); const std::filesystem::path modDir = configDir / "mods"; std::filesystem::create_directories(modDir); for (const auto& entry : std::filesystem::directory_iterator{modDir}) @@ -810,13 +807,11 @@ int main(int argc, char *argv[]) continue; } - LOAD_LIB_SYMBOL(handle, void, start, void*) + //LOAD_LIB_SYMBOL(handle, void, start, void*) - start(cufetch_handle); + //start(); } - LOAD_LIB_SYMBOL(cufetch_handle, const std::vector&, cfGetModules) - const std::vector& modules = cfGetModules(); moduleMap_t moduleMap; @@ -909,7 +904,5 @@ int main(int argc, char *argv[]) if (meminfo) fclose(meminfo); #endif - UNLOAD_LIBRARY(cufetch_handle); - return 0; } From f9e0337f36b0f6774f14128b70410a1ab765eff2 Mon Sep 17 00:00:00 2001 From: Toni500git Date: Thu, 26 Jun 2025 17:34:24 +0200 Subject: [PATCH 039/143] core-plugins: linux: add modules argument for swap and disk --- include/core-modules.hh | 12 +- src/core-plugins/linux/disk.cc | 203 +++++++++++++++++++ src/core-plugins/linux/linux-core-modules.cc | 58 ++++-- src/main.cpp | 12 +- 4 files changed, 265 insertions(+), 20 deletions(-) create mode 100644 src/core-plugins/linux/disk.cc diff --git a/include/core-modules.hh b/include/core-modules.hh index 25233c51..4e1578a5 100644 --- a/include/core-modules.hh +++ b/include/core-modules.hh @@ -55,7 +55,7 @@ MODFUNC(user_wm_version); MODFUNC(user_de_name); MODFUNC(user_de_version); -// ram.cc +// ram.cc and swap.cc inline std::FILE* meminfo; double ram_free(); double ram_total(); @@ -64,5 +64,15 @@ double swap_free(); double swap_total(); double swap_used(); +// disk.cc +inline std::FILE *mountsFile; +MODFUNC(disk_fsname); +MODFUNC(disk_device); +MODFUNC(disk_mountdir); +MODFUNC(disk_types); +double disk_total(const callbackInfo_t *callbackInfo); +double disk_free(const callbackInfo_t *callbackInfo); +double disk_used(const callbackInfo_t *callbackInfo); + #undef MODFUNC #define MODFUNC(name) const std::string name(__attribute__((unused)) const callbackInfo_t *callbackInfo) diff --git a/src/core-plugins/linux/disk.cc b/src/core-plugins/linux/disk.cc new file mode 100644 index 00000000..1f9d1189 --- /dev/null +++ b/src/core-plugins/linux/disk.cc @@ -0,0 +1,203 @@ +#include +#include +#include +#include +#include +#include "common.hpp" +#include "core-modules.hh" +#include "util.hpp" + +enum +{ + DISK_VOLUME_TYPE_HIDDEN = 1 << 2, + DISK_VOLUME_TYPE_REGULAR = 1 << 3, + DISK_VOLUME_TYPE_EXTERNAL = 1 << 4, + DISK_VOLUME_TYPE_READ_ONLY = 1 << 5, +}; + +// https://github.com/fastfetch-cli/fastfetch/blob/dev/src/detection/disk/disk_linux.c +static bool is_physical_device(const mntent* device) +{ +#if !CF_ANDROID // On Android, `/dev` is not accessible, so that the following checks always fail + + // Always show the root path + if (strcmp(device->mnt_dir, "/") == 0) + return true; + + if (strcmp(device->mnt_fsname, "none") == 0) + return false; + + // DrvFs is a filesystem plugin to WSL that was designed to support interop between WSL and the Windows filesystem. + if (strcmp(device->mnt_type, "9p") == 0) + return std::string_view(device->mnt_opts).find("aname=drvfs") != std::string_view::npos; + + // ZFS pool + if (strcmp(device->mnt_type, "zfs") == 0) + return true; + + // Pseudo filesystems don't have a device in /dev + if (!hasStart(device->mnt_fsname, "/dev/")) + return false; + + // #731 + if (strcmp(device->mnt_type, "bcachefs") == 0) + return true; + + if (hasStart(device->mnt_fsname + 5, "loop") || // Ignore loop devices + hasStart(device->mnt_fsname + 5, "ram") || // Ignore ram devices + hasStart(device->mnt_fsname + 5, "fd") // Ignore fd devices + ) + return false; + + struct stat deviceStat; + if (stat(device->mnt_fsname, &deviceStat) != 0) + return false; + + // Ignore all devices that are not block devices + if (!S_ISBLK(deviceStat.st_mode)) + return false; + +#else + + // Pseudo filesystems don't have a device in /dev + if (!hasStart(device->mnt_fsname, "/dev/")) + return false; + + if (hasStart(device->mnt_fsname + 5, "loop") || // Ignore loop devices + hasStart(device->mnt_fsname + 5, "ram") || // Ignore ram devices + hasStart(device->mnt_fsname + 5, "fd") // Ignore fd devices + ) + return false; + + // https://source.android.com/docs/core/ota/apex?hl=zh-cn + if (hasStart(device->mnt_dir, "/apex/")) + return false; + +#endif // !CF_ANDROID + + return true; +} + +static bool is_removable(const mntent* device) +{ + if (!hasStart(device->mnt_fsname, "/dev/")) + return false; + + // like device->mnt_fsname.substr(5); + std::string sys_block_partition{ fmt::format("/sys/class/block/{}", (device->mnt_fsname + "/dev/"_len)) }; + // check if it's like /dev/sda1 + if (sys_block_partition.back() >= '0' && sys_block_partition.back() <= '9') + sys_block_partition.pop_back(); + + return read_by_syspath(sys_block_partition + "/removable") == "1"; +} + +static int get_disk_type(const mntent* device) +{ +#if CF_LINUX + int ret = 0; + + if (hasStart(device->mnt_dir, "/boot") || hasStart(device->mnt_dir, "/efi")) + ret = DISK_VOLUME_TYPE_HIDDEN; + else if (is_removable(device)) + ret = DISK_VOLUME_TYPE_EXTERNAL; + else + ret = DISK_VOLUME_TYPE_REGULAR; + + if (hasmntopt(device, MNTOPT_RO)) + ret |= DISK_VOLUME_TYPE_READ_ONLY; + + return ret; +#else // CF_ANDROID + if (strcmp(device->mnt_dir, "/") == 0 || strcmp(device->mnt_dir, "/storage/emulated") == 0) + return DISK_VOLUME_TYPE_REGULAR; + + if (hasStart(device->mnt_dir, "/mnt/media_rw/")) + return DISK_VOLUME_TYPE_EXTERNAL; + + return DISK_VOLUME_TYPE_HIDDEN; +#endif +} + +static struct mntent* get_disk_info(const callbackInfo_t *callbackInfo) +{ + if (callbackInfo->moduleArgs->name != "disk" || (callbackInfo->moduleArgs->name == "disk" && callbackInfo->moduleArgs->value.empty())) + die("Module disk doesn't have an argmument to the path/device to query"); + + const std::string& path = callbackInfo->moduleArgs->value; + if (access(path.c_str(), F_OK) != 0 || !mountsFile) + return NULL; + + struct mntent* pDevice; + while ((pDevice = getmntent(mountsFile))) + { + debug("pDevice->mnt_dir = {:<50} && pDevice->mnt_fsname = {}", pDevice->mnt_dir, pDevice->mnt_fsname); + if (path == pDevice->mnt_dir || path == pDevice->mnt_fsname) + { + rewind(mountsFile); + return pDevice; + } + } + + rewind(mountsFile); + return NULL; +} + +static bool get_disk_usage_info(const callbackInfo_t *callbackInfo, struct statvfs *fs) +{ + struct mntent* pDevice = get_disk_info(callbackInfo); + const std::string& path = callbackInfo->moduleArgs->value; + const std::string& statpath = (hasStart(path, "/dev") && pDevice) ? pDevice->mnt_dir : path; + + return (statvfs(statpath.c_str(), fs) == 0); +} + +// don't get confused by the name pls +MODFUNC(disk_fsname) +{ return get_disk_info(callbackInfo)->mnt_type; } + +MODFUNC(disk_device) +{ return get_disk_info(callbackInfo)->mnt_fsname; } + +MODFUNC(disk_mountdir) +{ return get_disk_info(callbackInfo)->mnt_dir; } + +MODFUNC(disk_types) +{ + const int types = get_disk_type(get_disk_info(callbackInfo)); + std::string str; + if (types & DISK_VOLUME_TYPE_EXTERNAL) + str += "External, "; + if (types & DISK_VOLUME_TYPE_HIDDEN) + str += "Hidden, "; + if (types & DISK_VOLUME_TYPE_READ_ONLY) + str += "Read-only, "; + + if (!str.empty()) + str.erase(str.length() - 2); + + return str; +} + +double disk_total(const callbackInfo_t *callbackInfo) +{ + struct statvfs fs; + if (!get_disk_usage_info(callbackInfo, &fs)) + return 0; + + return static_cast(fs.f_blocks * fs.f_frsize); +} + +double disk_free(const callbackInfo_t *callbackInfo) +{ + struct statvfs fs; + if (!get_disk_usage_info(callbackInfo, &fs)) + return 0; + + return static_cast(fs.f_bfree * fs.f_frsize); +} + +double disk_used(const callbackInfo_t *callbackInfo) +{ + return disk_total(callbackInfo) - disk_free(callbackInfo); +} diff --git a/src/core-plugins/linux/linux-core-modules.cc b/src/core-plugins/linux/linux-core-modules.cc index 593a10ad..6f9abc3d 100644 --- a/src/core-plugins/linux/linux-core-modules.cc +++ b/src/core-plugins/linux/linux-core-modules.cc @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -14,24 +15,21 @@ using unused = const callbackInfo_t *; -const std::string amount(const double amount, moduleArgs_t *moduleArgs, const std::string& name) +const std::string amount(const double amount, const moduleArgs_t *moduleArgs) { constexpr std::array sorted_valid_prefixes = { "B", "EB", "EiB", "GB", "GiB", "kB", "KiB", "MB", "MiB", "PB", "PiB", "TB", "TiB", "YB", "YiB", "ZB", "ZiB" }; - if (moduleArgs->value.empty() || !moduleArgs->next) + if (!moduleArgs->next || moduleArgs->next->value.empty()) { - byte_units_t amount_unit = auto_divide_bytes(amount * 1024, 1024); + byte_units_t amount_unit = auto_divide_bytes(amount, 1024); return fmt::format("{:.2f} {}", amount_unit.num_bytes, amount_unit.unit); } - moduleArgs_t *modArgs = moduleArgs; - for (; modArgs && modArgs->name != name; modArgs = modArgs->next); - const std::string& prefix = modArgs->value; - + const std::string& prefix = moduleArgs->next->value; if (std::binary_search(sorted_valid_prefixes.begin(), sorted_valid_prefixes.end(), prefix)) - return fmt::format("{:.5f}", divide_bytes(amount * 1024, prefix).num_bytes); + return fmt::format("{:.5f}", divide_bytes(amount, prefix).num_bytes); return "0"; } @@ -54,6 +52,7 @@ void core_plugins_start() os_release = fopen("/etc/os-release", "r"); cpuinfo = fopen("/proc/cpuinfo", "r"); meminfo = fopen("/proc/meminfo", "r"); + mountsFile = setmntent("/proc/mounts", "r"); // ------------ MODULES REGISTERING ------------ module_t os_name_pretty_module = {"pretty", {}, os_pretty_name}; @@ -71,14 +70,14 @@ void core_plugins_start() module_t os_kernel_module = {"kernel", { std::move(os_kernel_name_module), std::move(os_kernel_version_module) - }, [](unused) {return os_kernel_name() + ' ' + os_kernel_version();}}; + }, [](unused) {return os_kernel_name() + " " + os_kernel_version();}}; module_t os_initsys_name_module = {"name", {}, os_initsys_name}; module_t os_initsys_version_module = {"version", {}, os_initsys_version}; module_t os_initsys_module = {"initsys", { std::move(os_initsys_name_module), std::move(os_initsys_version_module), - }, [](unused) {return os_initsys_name() + ' ' + os_initsys_version();}}; + }, [](unused) {return os_initsys_name() + " " + os_initsys_version();}}; /* Only for compatibility */ module_t os_pretty_name_module_compat = { "pretty_name", {}, os_pretty_name }; @@ -245,13 +244,46 @@ void core_plugins_start() cfRegisterModule(user_module); // $ - module_t ram_free_module = {"free", {}, [](const callbackInfo_t *callback) { return amount(ram_free(), callback->moduleArgs, "free"); }}; - module_t ram_used_module = {"used", {}, [](const callbackInfo_t *callback) { return amount(ram_used(), callback->moduleArgs, "used"); }}; - module_t ram_total_module = {"total", {}, [](const callbackInfo_t *callback) { return amount(ram_total(), callback->moduleArgs, "total"); }}; + module_t ram_free_module = {"free", {}, [](const callbackInfo_t *callback) { return amount(ram_free() * 1024, callback->moduleArgs); }}; + module_t ram_used_module = {"used", {}, [](const callbackInfo_t *callback) { return amount(ram_used() * 1024, callback->moduleArgs); }}; + module_t ram_total_module = {"total", {}, [](const callbackInfo_t *callback) { return amount(ram_total() * 1024, callback->moduleArgs); }}; + module_t ram_module = {"ram", { std::move(ram_free_module), std::move(ram_used_module), std::move(ram_total_module) }, NULL}; cfRegisterModule(ram_module); + + // $ + module_t swap_free_module = {"free", {}, [](const callbackInfo_t *callback) { return amount(swap_free() * 1024, callback->moduleArgs); }}; + module_t swap_used_module = {"used", {}, [](const callbackInfo_t *callback) { return amount(swap_used() * 1024, callback->moduleArgs); }}; + module_t swap_total_module = {"total", {}, [](const callbackInfo_t *callback) { return amount(swap_total() * 1024, callback->moduleArgs); }}; + + module_t swap_module = {"swap", { + std::move(swap_free_module), + std::move(swap_used_module), + std::move(swap_total_module) + }, NULL}; + cfRegisterModule(swap_module); + + // $ + module_t disk_fsname_module = {"fs", {}, disk_fsname}; + module_t disk_device_module = {"device", {}, disk_device}; + module_t disk_mountdir_module = {"mountdir", {}, disk_mountdir}; + module_t disk_types_module = {"types", {}, disk_types}; + module_t disk_free_module = {"free", {}, [](const callbackInfo_t *callback) { return amount(disk_free(callback), callback->moduleArgs); }}; + module_t disk_used_module = {"used", {}, [](const callbackInfo_t *callback) { return amount(disk_used(callback), callback->moduleArgs); }}; + module_t disk_total_module = {"total", {}, [](const callbackInfo_t *callback) { return amount(disk_total(callback), callback->moduleArgs); }}; + + module_t disk_module = {"disk", { + std::move(disk_fsname_module), + std::move(disk_device_module), + std::move(disk_mountdir_module), + std::move(disk_types_module), + std::move(disk_free_module), + std::move(disk_used_module), + std::move(disk_total_module), + }, NULL}; + cfRegisterModule(disk_module); } diff --git a/src/main.cpp b/src/main.cpp index ab4dd4cc..56306102 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -407,17 +407,18 @@ Tag References: 1. Information Tag ($<>) Retrieves system information from modules. - Syntax: $ or $ + Syntax: $ or $ Examples: - - $ # Displays login username - - $ # Shows kernel version - - $ # Shows formatted RAM usage + - $ # Displays login username + - $ # Shows kernel name only + - $ # Shows formatted RAM usage Use `--list-modules` to see all available modules and members. 2. Bash Command Tag ($()) Executes shell commands and outputs the result. + Supports full shell syntax including pipes and redirection. Syntax: $(command) @@ -426,8 +427,6 @@ Tag References: - $(date +%F) # Shows current date - $(uname -r | cut -d'-' -f1) # Shows kernel version number only - Supports full shell syntax including pipes and redirection. - 3. Conditional Tag ($[]) Displays different outputs based on conditions. @@ -899,6 +898,7 @@ int main(int argc, char *argv[]) enable_cursor(); #if CF_LINUX + if (mountsFile) fclose(mountsFile); if (os_release) fclose(os_release); if (cpuinfo) fclose(cpuinfo); if (meminfo) fclose(meminfo); From cb2fb2b3ca6781436168c4e5ed43205bbca47758 Mon Sep 17 00:00:00 2001 From: Toni500git Date: Thu, 26 Jun 2025 21:19:28 +0200 Subject: [PATCH 040/143] core-plugins: linux: add modules for battery --- include/core-modules.hh | 9 +++ src/core-plugins/linux/battery.cc | 69 ++++++++++++++++++++ src/core-plugins/linux/linux-core-modules.cc | 37 +++++++++++ 3 files changed, 115 insertions(+) create mode 100644 src/core-plugins/linux/battery.cc diff --git a/include/core-modules.hh b/include/core-modules.hh index 4e1578a5..048cfae9 100644 --- a/include/core-modules.hh +++ b/include/core-modules.hh @@ -74,5 +74,14 @@ double disk_total(const callbackInfo_t *callbackInfo); double disk_free(const callbackInfo_t *callbackInfo); double disk_used(const callbackInfo_t *callbackInfo); +// battery.cc +MODFUNC(battery_modelname); +MODFUNC(battery_perc); +MODFUNC(battery_status); +MODFUNC(battery_capacity_level); +MODFUNC(battery_technology); +MODFUNC(battery_vendor); +double battery_temp(); + #undef MODFUNC #define MODFUNC(name) const std::string name(__attribute__((unused)) const callbackInfo_t *callbackInfo) diff --git a/src/core-plugins/linux/battery.cc b/src/core-plugins/linux/battery.cc new file mode 100644 index 00000000..5f1b1631 --- /dev/null +++ b/src/core-plugins/linux/battery.cc @@ -0,0 +1,69 @@ +#include +#include +#include "common.hpp" +#include "core-modules.hh" +#include "util.hpp" + +static std::string read_strip_syspath(const std::string_view path) +{ + std::string str = read_by_syspath(path); + debug("str = {} || path = {}", str, path); + + // optimization + if (str.back() == '\n') + str.pop_back(); + else if (str != UNKNOWN) + strip(str); + + return str; +} + +static std::string get_battery_info(const std::string& file) +{ + if (access("/sys/class/power_supply/", F_OK) != 0) + return MAGIC_LINE; + + for (const auto& dir_entry : std::filesystem::directory_iterator{ "/sys/class/power_supply/" }) + { + const std::string& path = dir_entry.path().string() + "/"; + debug("battery path = {}", path); + + const std::string& tmp = read_strip_syspath(path + "type"); + if (tmp == UNKNOWN || tmp != "Battery") + continue; + if (read_strip_syspath(path + "scope") == "Device") + continue; + + debug("battery found yeappyy"); + return read_strip_syspath(path + file); + } + + return UNKNOWN; +} + +MODFUNC(battery_modelname) +{ return get_battery_info("model_name"); } + +MODFUNC(battery_perc) +{ return get_battery_info("capacity"); } + +MODFUNC(battery_status) +{ return get_battery_info("status"); } + +MODFUNC(battery_capacity_level) +{ return get_battery_info("capacity_level"); } + +MODFUNC(battery_technology) +{ return get_battery_info("technology"); } + +MODFUNC(battery_vendor) +{ return get_battery_info("manufacturer"); } + +double battery_temp() +{ + const std::string& temp = get_battery_info("temp"); + if (temp != UNKNOWN || temp != MAGIC_LINE) + return std::stod(temp) / 10; + + return 0; +} diff --git a/src/core-plugins/linux/linux-core-modules.cc b/src/core-plugins/linux/linux-core-modules.cc index 6f9abc3d..a4962209 100644 --- a/src/core-plugins/linux/linux-core-modules.cc +++ b/src/core-plugins/linux/linux-core-modules.cc @@ -286,4 +286,41 @@ void core_plugins_start() std::move(disk_total_module), }, NULL}; cfRegisterModule(disk_module); + + // $ + module_t battery_modelname_module = {"name", {}, battery_modelname}; + module_t battery_status_module = {"status", {}, battery_status}; + module_t battery_capacity_level_module = {"capacity_level", {}, battery_capacity_level}; + module_t battery_technology_module = {"technology", {}, battery_technology}; + module_t battery_vendor_module = {"manufacturer", {}, battery_vendor}; + module_t battery_perc_module = {"perc", {}, battery_perc}; + + module_t battery_temp_C_module = {"C", {}, [](unused) {return fmt::format("{:.2f}°C", battery_temp());}}; + module_t battery_temp_F_module = {"F", {}, [](unused) {return fmt::format("{:.2f}°F", battery_temp() * 1.8 + 34);}}; + module_t battery_temp_K_module = {"K", {}, [](unused) {return fmt::format("{:.2f}°K", battery_temp() + 273.15);}}; + module_t battery_temp_module = {"temp", { + std::move(battery_temp_C_module), + std::move(battery_temp_F_module), + std::move(battery_temp_K_module), + }, [](unused) {return fmt::format("{:.2f}°C", battery_temp());}}; + + /* Only for compatibility */ + module_t battery_temp_C_module_compat = {"temp_C", {}, [](unused) {return fmt::format("{:.2f}", battery_temp());}}; + module_t battery_temp_F_module_compat = {"temp_F", {}, [](unused) {return fmt::format("{:.2f}", battery_temp() * 1.8 + 34);}}; + module_t battery_temp_K_module_compat = {"temp_K", {}, [](unused) {return fmt::format("{:.2f}", battery_temp() + 273.15);}}; + + module_t battery_module = {"battery", { + std::move(battery_modelname_module), + std::move(battery_status_module), + std::move(battery_capacity_level_module), + std::move(battery_technology_module), + std::move(battery_vendor_module), + std::move(battery_perc_module), + std::move(battery_temp_module), + + std::move(battery_temp_C_module_compat), + std::move(battery_temp_F_module_compat), + std::move(battery_temp_K_module_compat), + }, NULL}; + cfRegisterModule(battery_module); } From 5ee6cd17e74217462ce8bfdce4e8e38920bc2f03 Mon Sep 17 00:00:00 2001 From: Toni500git Date: Fri, 27 Jun 2025 11:39:28 +0200 Subject: [PATCH 041/143] core-plugins: linux: add modules for gpu theme will be a pain in the ass --- include/core-modules.hh | 4 ++ src/core-plugins/linux/gpu.cc | 63 ++++++++++++++++++++ src/core-plugins/linux/linux-core-modules.cc | 11 ++++ src/query/linux/theme.cpp | 2 +- 4 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 src/core-plugins/linux/gpu.cc diff --git a/include/core-modules.hh b/include/core-modules.hh index 048cfae9..8b905517 100644 --- a/include/core-modules.hh +++ b/include/core-modules.hh @@ -83,5 +83,9 @@ MODFUNC(battery_technology); MODFUNC(battery_vendor); double battery_temp(); +// gpu.cc +MODFUNC(gpu_name); +MODFUNC(gpu_vendor); + #undef MODFUNC #define MODFUNC(name) const std::string name(__attribute__((unused)) const callbackInfo_t *callbackInfo) diff --git a/src/core-plugins/linux/gpu.cc b/src/core-plugins/linux/gpu.cc new file mode 100644 index 00000000..25a36e74 --- /dev/null +++ b/src/core-plugins/linux/gpu.cc @@ -0,0 +1,63 @@ +#include +#include +#include + +#include "core-modules.hh" +#include "fmt/format.h" +#include "util.hpp" + +static std::string get_name(const std::string_view m_vendor_id_s, const std::string_view m_device_id_s) +{ + const std::string& name = binarySearchPCIArray(m_vendor_id_s, m_device_id_s); + debug("GPU binarySearchPCIArray name = {}", name); + const size_t first_bracket = name.find('['); + const size_t last_bracket = name.rfind(']'); + + // remove the chips name "TU106 [GeForce GTX 1650]" + // This should work for AMD and Intel too. + if (first_bracket != std::string::npos && last_bracket != std::string::npos) + return name.substr(first_bracket + 1, last_bracket - first_bracket - 1); + + return name; +} + +static std::string get_vendor(const std::string_view m_vendor_id_s) +{ return binarySearchPCIArray(m_vendor_id_s); } + +static std::string get_gpu_syspath(const std::string& id) +{ + const std::uint16_t max_iter = 10; + std::uint16_t id_iter = std::stoi(id); + std::string sys_path; + int i = 0; + for (; i <= max_iter; i++) + { + sys_path = "/sys/class/drm/card" + fmt::to_string(id_iter); + if (std::filesystem::exists(sys_path + "/device/device") && + std::filesystem::exists(sys_path + "/device/vendor")) + return sys_path; + else + id_iter++; + } + + error(_("Failed to parse GPU infos on the path /sys/class/drm/")); + return UNKNOWN; +} + +MODFUNC(gpu_name) +{ + const std::string& id = (callbackInfo && callbackInfo->moduleArgs->name.length() > 3) + ? callbackInfo->moduleArgs->name.substr(3) + : "0"; + const std::string& sys_path = get_gpu_syspath(id); + return get_name(read_by_syspath(sys_path + "/device/vendor"), read_by_syspath(sys_path + "/device/device")); +} + +MODFUNC(gpu_vendor) +{ + const std::string& id = (callbackInfo && callbackInfo->moduleArgs->name.length() > 3) + ? callbackInfo->moduleArgs->name.substr(3) + : "0"; + const std::string& sys_path = get_gpu_syspath(id); + return get_vendor(read_by_syspath(sys_path + "/device/vendor")); +} diff --git a/src/core-plugins/linux/linux-core-modules.cc b/src/core-plugins/linux/linux-core-modules.cc index a4962209..6734d731 100644 --- a/src/core-plugins/linux/linux-core-modules.cc +++ b/src/core-plugins/linux/linux-core-modules.cc @@ -323,4 +323,15 @@ void core_plugins_start() std::move(battery_temp_K_module_compat), }, NULL}; cfRegisterModule(battery_module); + + // $ + module_t gpu_name_module = {"name", {}, gpu_name}; + module_t gpu_vendor_short_module = {"short", {}, [](const callbackInfo_t *callback) {return shorten_vendor_name(gpu_vendor(callback));}}; + module_t gpu_vendor_module = {"vendor", {std::move(gpu_vendor_short_module)}, gpu_vendor}; + + module_t gpu_module = {"gpu", { + std::move(gpu_name_module), + std::move(gpu_vendor_module) + }, [](const callbackInfo_t *callback) {return shorten_vendor_name(gpu_vendor(callback)) + " " + gpu_name(callback);}}; + cfRegisterModule(gpu_module); } diff --git a/src/query/linux/theme.cpp b/src/query/linux/theme.cpp index 2c0dfe59..00c2055b 100644 --- a/src/query/linux/theme.cpp +++ b/src/query/linux/theme.cpp @@ -31,7 +31,6 @@ #include "config.hpp" #include "fmt/format.h" -#include "parse.hpp" #include "query.hpp" #include "rapidxml-1.13/rapidxml.hpp" #include "switch_fnv1a.hpp" @@ -46,6 +45,7 @@ * func = the function name * ... = the arguments in a function if any */ +#undef LOAD_LIB_SYMBOL #define LOAD_LIB_SYMBOL(ret_type, func, ...) \ typedef ret_type (*func##_t)(__VA_ARGS__); \ func##_t func = reinterpret_cast(dlsym(handle, #func)); From 4c8cbf198aecca2c01b5756173a4b65791014c00 Mon Sep 17 00:00:00 2001 From: Toni500git Date: Fri, 27 Jun 2025 16:56:37 +0200 Subject: [PATCH 042/143] clang-format --- include/common.hpp | 41 +++++++++++--------- include/config.hpp | 2 +- include/core-modules.hh | 39 ++++++++++--------- include/cufetch.hh | 4 +- include/parse.hpp | 4 +- include/query.hpp | 2 +- include/util.hpp | 2 +- src/core-plugins/linux/battery.cc | 2 + src/core-plugins/linux/cpu.cc | 26 ++++++------- src/core-plugins/linux/disk.cc | 21 +++++----- src/core-plugins/linux/linux-core-modules.cc | 17 ++++---- src/core-plugins/linux/os.cc | 19 ++++----- src/core-plugins/linux/ram.cc | 17 ++++---- src/core-plugins/linux/user.cc | 12 +++--- src/display.cpp | 6 +-- src/gui.cpp | 10 ++--- src/main.cpp | 38 +++++++++--------- src/query/android/user.cpp | 2 +- src/query/linux/theme.cpp | 4 +- src/query/linux/utils/dewm.cpp | 2 +- src/util.cpp | 8 ++-- 21 files changed, 146 insertions(+), 132 deletions(-) diff --git a/include/common.hpp b/include/common.hpp index 50ff8162..8fab66aa 100644 --- a/include/common.hpp +++ b/include/common.hpp @@ -1,10 +1,12 @@ #pragma once +#include +#include + #include #include #include -#include -#include + #include "platform.hpp" #if ENABLE_NLS && !CF_MACOS @@ -16,9 +18,9 @@ #define _(s) (char*)s #endif -constexpr const char NOCOLOR[] = "\033[0m"; +constexpr const char NOCOLOR[] = "\033[0m"; constexpr const char NOCOLOR_BOLD[] = "\033[0m\033[1m"; -constexpr const char UNKNOWN[] = "(unknown)"; +constexpr const char UNKNOWN[] = "(unknown)"; // Usually in neofetch/fastfetch when some infos couldn't be queried, // they remove it from the display. With customfetch is kinda difficult to know when to remove @@ -33,8 +35,8 @@ constexpr const char MAGIC_LINE[] = "(cut this line NOW!! RAHHH)"; * func = the function name * ... = the arguments in a function if any */ -#define LOAD_LIB_SYMBOL(handler, ret_type, func, ...) \ - typedef ret_type (*func##_t)(__VA_ARGS__); \ +#define LOAD_LIB_SYMBOL(handler, ret_type, func, ...) \ + typedef ret_type (*func##_t)(__VA_ARGS__); \ func##_t func = reinterpret_cast(dlsym(handler, #func)); #define UNLOAD_LIBRARY(handle) dlclose(handle); @@ -50,14 +52,14 @@ template void error(const std::string_view fmt, Args&&... args) noexcept { fmt::print(stderr, BOLD_COLOR(fmt::rgb(fmt::color::red)), "ERROR: {}\033[0m\n", - fmt::format(fmt::runtime(fmt), std::forward(args)...)); + fmt::format(fmt::runtime(fmt), std::forward(args)...)); } template void die(const std::string_view fmt, Args&&... args) noexcept { fmt::print(stderr, BOLD_COLOR(fmt::rgb(fmt::color::red)), "FATAL: {}\033[0m\n", - fmt::format(fmt::runtime(fmt), std::forward(args)...)); + fmt::format(fmt::runtime(fmt), std::forward(args)...)); std::exit(1); } @@ -72,42 +74,45 @@ void debug(const std::string_view fmt, Args&&... args) noexcept { if (debug_print) fmt::print(BOLD_COLOR((fmt::rgb(fmt::color::hot_pink))), "[DEBUG]:\033[0m {}\n", - fmt::format(fmt::runtime(fmt), std::forward(args)...)); + fmt::format(fmt::runtime(fmt), std::forward(args)...)); } template void warn(const std::string_view fmt, Args&&... args) noexcept { fmt::print(BOLD_COLOR((fmt::rgb(fmt::color::yellow))), "WARNING: {}\033[0m\n", - fmt::format(fmt::runtime(fmt), std::forward(args)...)); + fmt::format(fmt::runtime(fmt), std::forward(args)...)); } template void info(const std::string_view fmt, Args&&... args) noexcept { fmt::print(BOLD_COLOR((fmt::rgb(fmt::color::cyan))), "INFO: {}\033[0m\n", - fmt::format(fmt::runtime(fmt), std::forward(args)...)); + fmt::format(fmt::runtime(fmt), std::forward(args)...)); } #undef BOLD_COLOR -/* A linked list including module arguments. An argument may be specified for any part of the module path (e.g. `disk(/).used(GiB)`, `test(a).hi`) */ -struct moduleArgs_t { - struct moduleArgs_t *prev = nullptr; +/* A linked list including module arguments. An argument may be specified for any part of the module path (e.g. + * `disk(/).used(GiB)`, `test(a).hi`) */ +struct moduleArgs_t +{ + struct moduleArgs_t* prev = nullptr; std::string name; std::string value; - struct moduleArgs_t *next = nullptr; + struct moduleArgs_t* next = nullptr; }; -struct callbackInfo_t { - struct moduleArgs_t *moduleArgs; +struct callbackInfo_t +{ + struct moduleArgs_t* moduleArgs; }; struct module_t { std::string name; std::vector submodules; /* For best performance, use std::move() when adding modules in here. */ - std::function handler; + std::function handler; }; diff --git a/include/config.hpp b/include/config.hpp index 79ff3e08..c4d21d60 100644 --- a/include/config.hpp +++ b/include/config.hpp @@ -56,7 +56,7 @@ class Config public: // Create .config directories and files and load the config file (args or default) Config(const std::filesystem::path& configFile, const std::filesystem::path& configDir); - + // config colors // those without gui_ prefix are for the terminal struct colors_t diff --git a/include/core-modules.hh b/include/core-modules.hh index 8b905517..4a61c2e7 100644 --- a/include/core-modules.hh +++ b/include/core-modules.hh @@ -1,10 +1,11 @@ #pragma once -#include "common.hpp" #include #include -#define MODFUNC(name) const std::string name(__attribute__((unused)) const callbackInfo_t *callbackInfo = nullptr) +#include "common.hpp" + +#define MODFUNC(name) const std::string name(__attribute__((unused)) const callbackInfo_t* callbackInfo = nullptr) // system.cc inline utsname g_uname_infos; @@ -15,7 +16,7 @@ MODFUNC(host_version); MODFUNC(host_vendor); // os.cc -inline std::FILE *os_release; +inline std::FILE* os_release; MODFUNC(os_name); MODFUNC(os_pretty_name); MODFUNC(os_name_id); @@ -29,7 +30,7 @@ MODFUNC(os_initsys_name); MODFUNC(os_initsys_version); // cpu.cc -inline std::FILE *cpuinfo; +inline std::FILE* cpuinfo; MODFUNC(cpu_freq_cur); MODFUNC(cpu_freq_max); MODFUNC(cpu_freq_min); @@ -40,10 +41,10 @@ MODFUNC(cpu_name); // user.cc inline struct passwd* g_pwd; -inline bool is_tty = false; -inline std::string term_pid, term_name, wm_name, de_name, wm_path_exec; -std::string get_terminal_name(); -std::string get_terminal_pid(); +inline bool is_tty = false; +inline std::string term_pid, term_name, wm_name, de_name, wm_path_exec; +std::string get_terminal_name(); +std::string get_terminal_pid(); MODFUNC(user_name); MODFUNC(user_shell_path); MODFUNC(user_shell_name); @@ -57,22 +58,22 @@ MODFUNC(user_de_version); // ram.cc and swap.cc inline std::FILE* meminfo; -double ram_free(); -double ram_total(); -double ram_used(); -double swap_free(); -double swap_total(); -double swap_used(); +double ram_free(); +double ram_total(); +double ram_used(); +double swap_free(); +double swap_total(); +double swap_used(); // disk.cc -inline std::FILE *mountsFile; +inline std::FILE* mountsFile; MODFUNC(disk_fsname); MODFUNC(disk_device); MODFUNC(disk_mountdir); MODFUNC(disk_types); -double disk_total(const callbackInfo_t *callbackInfo); -double disk_free(const callbackInfo_t *callbackInfo); -double disk_used(const callbackInfo_t *callbackInfo); +double disk_total(const callbackInfo_t* callbackInfo); +double disk_free(const callbackInfo_t* callbackInfo); +double disk_used(const callbackInfo_t* callbackInfo); // battery.cc MODFUNC(battery_modelname); @@ -88,4 +89,4 @@ MODFUNC(gpu_name); MODFUNC(gpu_vendor); #undef MODFUNC -#define MODFUNC(name) const std::string name(__attribute__((unused)) const callbackInfo_t *callbackInfo) +#define MODFUNC(name) const std::string name(__attribute__((unused)) const callbackInfo_t* callbackInfo) diff --git a/include/cufetch.hh b/include/cufetch.hh index 2afb99f4..0deb1279 100644 --- a/include/cufetch.hh +++ b/include/cufetch.hh @@ -1,7 +1,7 @@ -#include "common.hpp" - #include +#include "common.hpp" + /* Register a module, and its submodules, to customfetch. */ void cfRegisterModule(const module_t& module); diff --git a/include/parse.hpp b/include/parse.hpp index 1ce9e0b4..c539a64a 100644 --- a/include/parse.hpp +++ b/include/parse.hpp @@ -62,8 +62,8 @@ struct parse_args_t * @param parsingLayout If we are parsing layout or not * @param no_more_reset If we are recursively parsing, e.g we are inside tags */ -std::string parse(std::string input, moduleMap_t& modulesInfo, std::string& pureOutput, std::vector& layout, - std::vector& tmp_layout, const Config& config, +std::string parse(std::string input, moduleMap_t& modulesInfo, std::string& pureOutput, + std::vector& layout, std::vector& tmp_layout, const Config& config, const bool parsingLayout, bool& no_more_reset); // parse() for parse_args_t& arguments diff --git a/include/query.hpp b/include/query.hpp index 6556ea51..8fb19ed4 100644 --- a/include/query.hpp +++ b/include/query.hpp @@ -64,7 +64,7 @@ inline bool is_live_mode = false; if (!x || is_live_mode) \ x = true; \ else \ - return; \ + return; namespace Query { diff --git a/include/util.hpp b/include/util.hpp index d615a0bc..71568948 100644 --- a/include/util.hpp +++ b/include/util.hpp @@ -36,10 +36,10 @@ #include #include +#include "common.hpp" #include "fmt/base.h" #include "fmt/color.h" #include "platform.hpp" -#include "common.hpp" // clang-format off // Get string literal length diff --git a/src/core-plugins/linux/battery.cc b/src/core-plugins/linux/battery.cc index 5f1b1631..63d10457 100644 --- a/src/core-plugins/linux/battery.cc +++ b/src/core-plugins/linux/battery.cc @@ -1,5 +1,7 @@ #include + #include + #include "common.hpp" #include "core-modules.hh" #include "util.hpp" diff --git a/src/core-plugins/linux/cpu.cc b/src/core-plugins/linux/cpu.cc index 9af7a694..6d65fde3 100644 --- a/src/core-plugins/linux/cpu.cc +++ b/src/core-plugins/linux/cpu.cc @@ -3,18 +3,19 @@ #include #include "common.hpp" -#include "fmt/format.h" #include "core-modules.hh" +#include "fmt/format.h" #include "util.hpp" const std::string freq_dir = "/sys/devices/system/cpu/cpu0/cpufreq"; static void trim(char* str) { - if (!str) return; - + if (!str) + return; + // Trim leading space - char *p = str; + char* p = str; while (isspace((unsigned char)*p)) ++p; memmove(str, p, strlen(p) + 1); @@ -33,14 +34,14 @@ static bool read_value(const char* name, size_t n, bool do_rewind, char* buf, si if (do_rewind) rewind(cpuinfo); - char* line = NULL; - size_t len = 0; - bool found = false; + char* line = NULL; + size_t len = 0; + bool found = false; while (getline(&line, &len, cpuinfo) != -1) { if (strncmp(line, name, n)) continue; - + char* colon = strchr(line, ':'); if (!colon) continue; @@ -54,7 +55,7 @@ static bool read_value(const char* name, size_t n, bool do_rewind, char* buf, si // Safe copy to buffer strncpy(buf, val, buf_size - 1); buf[buf_size - 1] = '\0'; - + found = true; break; } @@ -107,14 +108,13 @@ MODFUNC(cpu_name) return name; } - MODFUNC(cpu_nproc) { uint nproc = 0; rewind(cpuinfo); - - char* line = NULL; - size_t len = 0; + + char* line = NULL; + size_t len = 0; while (getline(&line, &len, cpuinfo) != -1) { if (strncmp(line, "processor", "processor"_len) == 0) diff --git a/src/core-plugins/linux/disk.cc b/src/core-plugins/linux/disk.cc index 1f9d1189..8a49ef1e 100644 --- a/src/core-plugins/linux/disk.cc +++ b/src/core-plugins/linux/disk.cc @@ -2,7 +2,9 @@ #include #include #include + #include + #include "common.hpp" #include "core-modules.hh" #include "util.hpp" @@ -119,9 +121,10 @@ static int get_disk_type(const mntent* device) #endif } -static struct mntent* get_disk_info(const callbackInfo_t *callbackInfo) +static struct mntent* get_disk_info(const callbackInfo_t* callbackInfo) { - if (callbackInfo->moduleArgs->name != "disk" || (callbackInfo->moduleArgs->name == "disk" && callbackInfo->moduleArgs->value.empty())) + if (callbackInfo->moduleArgs->name != "disk" || + (callbackInfo->moduleArgs->name == "disk" && callbackInfo->moduleArgs->value.empty())) die("Module disk doesn't have an argmument to the path/device to query"); const std::string& path = callbackInfo->moduleArgs->value; @@ -143,10 +146,10 @@ static struct mntent* get_disk_info(const callbackInfo_t *callbackInfo) return NULL; } -static bool get_disk_usage_info(const callbackInfo_t *callbackInfo, struct statvfs *fs) +static bool get_disk_usage_info(const callbackInfo_t* callbackInfo, struct statvfs* fs) { - struct mntent* pDevice = get_disk_info(callbackInfo); - const std::string& path = callbackInfo->moduleArgs->value; + struct mntent* pDevice = get_disk_info(callbackInfo); + const std::string& path = callbackInfo->moduleArgs->value; const std::string& statpath = (hasStart(path, "/dev") && pDevice) ? pDevice->mnt_dir : path; return (statvfs(statpath.c_str(), fs) == 0); @@ -164,7 +167,7 @@ MODFUNC(disk_mountdir) MODFUNC(disk_types) { - const int types = get_disk_type(get_disk_info(callbackInfo)); + const int types = get_disk_type(get_disk_info(callbackInfo)); std::string str; if (types & DISK_VOLUME_TYPE_EXTERNAL) str += "External, "; @@ -172,14 +175,14 @@ MODFUNC(disk_types) str += "Hidden, "; if (types & DISK_VOLUME_TYPE_READ_ONLY) str += "Read-only, "; - + if (!str.empty()) str.erase(str.length() - 2); return str; } -double disk_total(const callbackInfo_t *callbackInfo) +double disk_total(const callbackInfo_t* callbackInfo) { struct statvfs fs; if (!get_disk_usage_info(callbackInfo, &fs)) @@ -188,7 +191,7 @@ double disk_total(const callbackInfo_t *callbackInfo) return static_cast(fs.f_blocks * fs.f_frsize); } -double disk_free(const callbackInfo_t *callbackInfo) +double disk_free(const callbackInfo_t* callbackInfo) { struct statvfs fs; if (!get_disk_usage_info(callbackInfo, &fs)) diff --git a/src/core-plugins/linux/linux-core-modules.cc b/src/core-plugins/linux/linux-core-modules.cc index 6734d731..7e4e48ee 100644 --- a/src/core-plugins/linux/linux-core-modules.cc +++ b/src/core-plugins/linux/linux-core-modules.cc @@ -1,21 +1,22 @@ #include #include #include + #include #include #include #include #include -#include "cufetch.hh" -#include "core-modules.hh" #include "common.hpp" +#include "core-modules.hh" +#include "cufetch.hh" #include "fmt/format.h" #include "util.hpp" -using unused = const callbackInfo_t *; +using unused = const callbackInfo_t*; -const std::string amount(const double amount, const moduleArgs_t *moduleArgs) +const std::string amount(const double amount, const moduleArgs_t* moduleArgs) { constexpr std::array sorted_valid_prefixes = { "B", "EB", "EiB", "GB", "GiB", "kB", "KiB", "MB", "MiB", "PB", "PiB", "TB", @@ -42,16 +43,16 @@ void core_plugins_start() if (g_pwd = getpwuid(getuid()), !g_pwd) die(_("getpwent failed: {}\nCould not get user infos"), std::strerror(errno)); - term_pid = get_terminal_pid(); + term_pid = get_terminal_pid(); term_name = get_terminal_name(); if (hasStart(str_tolower(term_name), "login") || hasStart(term_name, "init") || hasStart(term_name, "(init)")) { - is_tty = true; + is_tty = true; term_name = ttyname(STDIN_FILENO); } os_release = fopen("/etc/os-release", "r"); - cpuinfo = fopen("/proc/cpuinfo", "r"); - meminfo = fopen("/proc/meminfo", "r"); + cpuinfo = fopen("/proc/cpuinfo", "r"); + meminfo = fopen("/proc/meminfo", "r"); mountsFile = setmntent("/proc/mounts", "r"); // ------------ MODULES REGISTERING ------------ diff --git a/src/core-plugins/linux/os.cc b/src/core-plugins/linux/os.cc index e900d75e..005d2460 100644 --- a/src/core-plugins/linux/os.cc +++ b/src/core-plugins/linux/os.cc @@ -7,8 +7,8 @@ #define FMT_HEADER_ONLY 1 #include "common.hpp" -#include "fmt/format.h" #include "core-modules.hh" +#include "fmt/format.h" #include "switch_fnv1a.hpp" #include "util.hpp" @@ -19,24 +19,25 @@ static std::string read_value(const std::string_view name) rewind(os_release); - std::string result{UNKNOWN}; - char* line = nullptr; - size_t len = 0; + std::string result{ UNKNOWN }; + char* line = nullptr; + size_t len = 0; while (getline(&line, &len, os_release) != -1) { if (name.length() > len || strncmp(line, name.data(), name.length()) != 0) continue; - char* start = strchr(line + name.length(), '"'); /* Get first occurence of " */ + char* start = strchr(line + name.length(), '"'); /* Get first occurence of " */ if (start) - start++; /* Get after the " */ + start++; /* Get after the " */ else - start = line + name.length(); /* No ", get the start. */ + start = line + name.length(); /* No ", get the start. */ - char* end = strrchr(start, '"'); /* Get last occurence of " */ + char* end = strrchr(start, '"'); /* Get last occurence of " */ if (!end) - end = line + strlen(line) - 1; /* Set to the end of the string -- no newline. (I heard Windows has a different newline sequence.. *sigh*) */ + end = line + strlen(line) - 1; /* Set to the end of the string -- no newline. (I heard Windows has a + different newline sequence.. *sigh*) */ result.assign(start, end - start); break; diff --git a/src/core-plugins/linux/ram.cc b/src/core-plugins/linux/ram.cc index ac9365ad..ae0d0bd5 100644 --- a/src/core-plugins/linux/ram.cc +++ b/src/core-plugins/linux/ram.cc @@ -1,17 +1,18 @@ -#include "common.hpp" -#include "core-modules.hh" #include #include #include +#include "common.hpp" +#include "core-modules.hh" + static double read_value(const std::string_view key) { if (!meminfo) return 0.0; - std::string result{UNKNOWN}; - char* line = nullptr; - size_t len = 0; + std::string result{ UNKNOWN }; + char* line = nullptr; + size_t len = 0; while (getline(&line, &len, meminfo) != -1) { @@ -20,11 +21,13 @@ static double read_value(const std::string_view key) // Skip colon and whitespace char* value = line + key.length(); - while (isspace(*value)) value++; + while (isspace(*value)) + value++; // Find end of numeric value (stop at first non-digit or '.') char* end = value; - while (*end && (isdigit(*end) || *end == '.')) end++; + while (*end && (isdigit(*end) || *end == '.')) + end++; if (value != end) result.assign(value, end - value); diff --git a/src/core-plugins/linux/user.cc b/src/core-plugins/linux/user.cc index 18782615..88e97359 100644 --- a/src/core-plugins/linux/user.cc +++ b/src/core-plugins/linux/user.cc @@ -1,12 +1,14 @@ #include + #include + #include "common.hpp" -#include "fmt/format.h" #include "core-modules.hh" +#include "fmt/format.h" #include "switch_fnv1a.hpp" -#include "utils/term.hpp" -#include "utils/dewm.hpp" #include "util.hpp" +#include "utils/dewm.hpp" +#include "utils/term.hpp" #if __has_include() && __has_include() #include @@ -292,7 +294,7 @@ std::string get_wm_name(std::string& wm_path_exec) static std::string get_wm_wayland_name(std::string& wm_path_exec) { #if __has_include() && __has_include() - void *handle = LOAD_LIBRARY("libwayland-client.so") + void* handle = LOAD_LIBRARY("libwayland-client.so"); if (!handle) return get_wm_name(wm_path_exec); @@ -347,7 +349,7 @@ MODFUNC(user_wm_version) { if (is_tty) return MAGIC_LINE; - user_wm_name(); // populate wm_path_exec if haven't already + user_wm_name(); // populate wm_path_exec if haven't already std::string wm_version; if (wm_name == "Xfwm4" && get_fast_xfwm4_version(wm_version, wm_path_exec)) return wm_version; diff --git a/src/display.cpp b/src/display.cpp index 61701c9e..7b657ff0 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -38,9 +38,9 @@ #endif #if CF_MACOS -# include +#include #else -# include +#include #endif #include @@ -55,12 +55,12 @@ #include #include "config.hpp" +#include "core-modules.hh" #include "fmt/core.h" #include "fmt/format.h" #include "parse.hpp" #include "platform.hpp" #include "stb_image.h" -#include "core-modules.hh" #include "utf8/checked.h" #include "util.hpp" diff --git a/src/gui.cpp b/src/gui.cpp index 257bbcde..3dd572fa 100644 --- a/src/gui.cpp +++ b/src/gui.cpp @@ -137,17 +137,13 @@ bool Window::set_layout_markup() } else { - m_label.set_markup( - fmt::format("{}", fmt::join(Display::render(m_config, true, m_path, m_moduleMap), "\n"))); + m_label.set_markup(fmt::format("{}", fmt::join(Display::render(m_config, true, m_path, m_moduleMap), "\n"))); } return true; } -Window::Window(const Config& config, const std::filesystem::path& path, moduleMap_t& moduleMap) : - m_config(config), - m_path(path), - m_moduleMap(moduleMap), - isImage(false) +Window::Window(const Config& config, const std::filesystem::path& path, moduleMap_t& moduleMap) + : m_config(config), m_path(path), m_moduleMap(moduleMap), isImage(false) { set_title("customfetch - Higly customizable and fast neofetch like program"); set_default_size(1000, 600); diff --git a/src/main.cpp b/src/main.cpp index 56306102..ce3e8f2d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -36,8 +36,9 @@ #include #include -#include "cufetch.hh" #include "config.hpp" +#include "core-modules.hh" +#include "cufetch.hh" #include "display.hpp" #include "fmt/ranges.h" #include "gui.hpp" @@ -46,12 +47,10 @@ #include "switch_fnv1a.hpp" #include "util.hpp" -#include "core-modules.hh" - #if (!__has_include("version.h")) -# error "version.h not found, please generate it with ./scripts/generateVersion.sh" +#error "version.h not found, please generate it with ./scripts/generateVersion.sh" #else -# include "version.h" +#include "version.h" #endif // clang-format off @@ -94,7 +93,7 @@ static void version() static void help(bool invalid_opt = false) { constexpr std::string_view help( -R"(Usage: customfetch [OPTIONS]... + R"(Usage: customfetch [OPTIONS]... A command-line, GUI, and Android widget system information tool (like neofetch) focused on customizability and performance. NOTE: Boolean flags [] accept: "true", 1, "enable", or empty. Any other value is treated as false. @@ -399,7 +398,7 @@ system static void explain_how_this_works() { constexpr std::string_view str( -R"( + R"( customfetch is designed for maximum customizability, allowing users to display system information exactly how they want it. The layout and logo is controlled through special tags that can output system info, execute commands, apply conditional logic, add colors, and calculate percentages with some colors. @@ -537,10 +536,7 @@ static void list_logos(const std::string& data_dir) } // Return true if optarg says something true -static bool str_to_bool(const std::string_view str) -{ - return (str == "true" || str == "1" || str == "enable"); -} +static bool str_to_bool(const std::string_view str) { return (str == "true" || str == "1" || str == "enable"); } // clang-format off // parseargs() but only for parsing the user config path trough args @@ -793,11 +789,11 @@ int main(int argc, char *argv[]) core_plugins_start(); const std::filesystem::path modDir = configDir / "mods"; std::filesystem::create_directories(modDir); - for (const auto& entry : std::filesystem::directory_iterator{modDir}) + for (const auto& entry : std::filesystem::directory_iterator{ modDir }) { debug("loading mod at {}!", entry.path().string()); - void *handle = LOAD_LIBRARY(std::filesystem::absolute(entry.path()).c_str()); + void* handle = LOAD_LIBRARY(std::filesystem::absolute(entry.path()).c_str()); if (!handle) { // dlerror() is pretty formatted @@ -806,9 +802,9 @@ int main(int argc, char *argv[]) continue; } - //LOAD_LIB_SYMBOL(handle, void, start, void*) + // LOAD_LIB_SYMBOL(handle, void, start, void*) - //start(); + // start(); } const std::vector& modules = cfGetModules(); @@ -898,10 +894,14 @@ int main(int argc, char *argv[]) enable_cursor(); #if CF_LINUX - if (mountsFile) fclose(mountsFile); - if (os_release) fclose(os_release); - if (cpuinfo) fclose(cpuinfo); - if (meminfo) fclose(meminfo); + if (mountsFile) + fclose(mountsFile); + if (os_release) + fclose(os_release); + if (cpuinfo) + fclose(cpuinfo); + if (meminfo) + fclose(meminfo); #endif return 0; diff --git a/src/query/android/user.cpp b/src/query/android/user.cpp index 21d8d0d1..2ce5919e 100644 --- a/src/query/android/user.cpp +++ b/src/query/android/user.cpp @@ -59,7 +59,7 @@ static std::string get_shell_name(const std::string_view shell_path) User::User() noexcept { CHECK_INIT(m_bInit); - + if (m_pPwd = getpwuid(getuid()), !m_pPwd) die("getpwent failed: {}\nCould not get user infos", std::strerror(errno)); diff --git a/src/query/linux/theme.cpp b/src/query/linux/theme.cpp index 00c2055b..aa764133 100644 --- a/src/query/linux/theme.cpp +++ b/src/query/linux/theme.cpp @@ -137,7 +137,7 @@ static bool get_cursor_dconf(const std::string_view de_name, Theme::Theme_t& the { #if USE_DCONF - void *handle = LOAD_LIBRARY("libdconf.so"); + void* handle = LOAD_LIBRARY("libdconf.so"); if (!handle) return false; @@ -320,7 +320,7 @@ static bool get_gtk_theme_dconf(const std::string_view de_name, Theme::Theme_t& { #if USE_DCONF - void *handle = LOAD_LIBRARY("libdconf.so"); + void* handle = LOAD_LIBRARY("libdconf.so"); if (!handle) return false; diff --git a/src/query/linux/utils/dewm.cpp b/src/query/linux/utils/dewm.cpp index 8a08e976..f9212175 100644 --- a/src/query/linux/utils/dewm.cpp +++ b/src/query/linux/utils/dewm.cpp @@ -48,10 +48,10 @@ #include #include +#include "common.hpp" #include "rapidxml-1.13/rapidxml.hpp" #include "switch_fnv1a.hpp" #include "util.hpp" -#include "common.hpp" // https://github.com/fastfetch-cli/fastfetch/blob/a61765c8b1387777be67d967bc2f69031c8ca399/src/detection/displayserver/linux/wmde.c#L19 std::string parse_de_env(void) noexcept diff --git a/src/util.cpp b/src/util.cpp index c3382c27..5c55e4d9 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -45,11 +45,11 @@ #include #include +#include "common.hpp" #include "fmt/color.h" #include "fmt/ranges.h" #include "pci.ids.hpp" #include "platform.hpp" -#include "common.hpp" bool hasEnding(const std::string_view fullString, const std::string_view ending) { @@ -172,11 +172,11 @@ byte_units_t auto_divide_bytes(const double num, const std::uint16_t base, const byte_units_t divide_bytes(const double num, const std::string_view prefix) { if (prefix == "B") - return {"B", num}; + return { "B", num }; // GiB // 012 - const std::uint16_t base = (prefix.size() == 3 && prefix[1] == 'i') ? 1024 : 1000; + const std::uint16_t base = (prefix.size() == 3 && prefix[1] == 'i') ? 1024 : 1000; std::array prefixes; if (base == 1024) prefixes = { "B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB" }; @@ -185,7 +185,7 @@ byte_units_t divide_bytes(const double num, const std::string_view prefix) const auto& it = std::find(prefixes.begin(), prefixes.end(), prefix); if (it == prefixes.end()) - return {"B", num}; + return { "B", num }; const size_t index = std::distance(prefixes.begin(), it); const double value = num / std::pow(static_cast(base), index); From 987c090f9f0cbb1c0a5e8e7a0b2e63676a9bd870 Mon Sep 17 00:00:00 2001 From: Toni500git Date: Fri, 27 Jun 2025 18:48:48 +0200 Subject: [PATCH 043/143] plugins: implement parse() variant this is MASSIVE milestone --- include/common.hpp | 18 ++++-- include/parse.hpp | 13 ++-- src/core-plugins/linux/linux-core-modules.cc | 63 ++++++++++++++++++++ src/parse.cpp | 17 ++++-- 4 files changed, 94 insertions(+), 17 deletions(-) diff --git a/include/common.hpp b/include/common.hpp index 8fab66aa..a6d18f18 100644 --- a/include/common.hpp +++ b/include/common.hpp @@ -105,14 +105,22 @@ struct moduleArgs_t struct moduleArgs_t* next = nullptr; }; -struct callbackInfo_t -{ - struct moduleArgs_t* moduleArgs; -}; - +struct callbackInfo_t; struct module_t { std::string name; std::vector submodules; /* For best performance, use std::move() when adding modules in here. */ std::function handler; }; + +// Map from a modules name to its pointer. +using moduleMap_t = std::unordered_map; +class Config; +const std::string parse(const std::string& input, const moduleMap_t& modulesInfo, const Config& config); + +struct callbackInfo_t +{ + const moduleArgs_t* moduleArgs; + const moduleMap_t& modulesInfo; + const Config& config; +}; diff --git a/include/parse.hpp b/include/parse.hpp index c539a64a..35c1f021 100644 --- a/include/parse.hpp +++ b/include/parse.hpp @@ -29,6 +29,7 @@ #include #include +#include "common.hpp" #include "config.hpp" // Map from a modules name to its pointer. @@ -40,7 +41,7 @@ using moduleMap_t = std::unordered_map; */ struct parse_args_t { - moduleMap_t& modulesInfo; + const moduleMap_t& modulesInfo; std::string& pureOutput; std::vector& layout; std::vector& tmp_layout; @@ -62,7 +63,7 @@ struct parse_args_t * @param parsingLayout If we are parsing layout or not * @param no_more_reset If we are recursively parsing, e.g we are inside tags */ -std::string parse(std::string input, moduleMap_t& modulesInfo, std::string& pureOutput, +std::string parse(std::string input, const moduleMap_t& modulesInfo, std::string& pureOutput, std::vector& layout, std::vector& tmp_layout, const Config& config, const bool parsingLayout, bool& no_more_reset); @@ -91,13 +92,11 @@ std::string parse(const std::string& input, std::string& _, parse_args_t& parse_ // void addValueFromModule(const std::string& moduleName, parse_args_t& parse_args); /* - * Return an info module member value - * @param modulesInfo The modulesInfo_t map + * Return an info module value + * @param parse_args The parse() like arguments * @param moduleName The module name - * @param moduleMemberName The module member name */ -const std::string getInfoFromName(const moduleMap_t& modulesInfo, const std::string_view moduleName, - const std::string_view moduleMemberName); +const std::string getInfoFromName(const parse_args_t& parse_args, const std::string& moduleName); /* * Create a colored percentage from parse() diff --git a/src/core-plugins/linux/linux-core-modules.cc b/src/core-plugins/linux/linux-core-modules.cc index 7e4e48ee..89558df0 100644 --- a/src/core-plugins/linux/linux-core-modules.cc +++ b/src/core-plugins/linux/linux-core-modules.cc @@ -9,6 +9,7 @@ #include #include "common.hpp" +#include "config.hpp" #include "core-modules.hh" #include "cufetch.hh" #include "fmt/format.h" @@ -335,4 +336,66 @@ void core_plugins_start() std::move(gpu_vendor_module) }, [](const callbackInfo_t *callback) {return shorten_vendor_name(gpu_vendor(callback)) + " " + gpu_name(callback);}}; cfRegisterModule(gpu_module); + + // $ + module_t title_sep_module = { "sep", {}, [](const callbackInfo_t* callback) { + const size_t title_len = + std::string_view(user_name() + "@" + os_hostname()).length(); + + std::string str; + str.reserve(callback->config.title_sep.length() * title_len); + for (size_t i = 0; i < title_len; i++) + str += callback->config.title_sep; + + return str; + } }; + module_t title_module = { "title", { std::move(title_sep_module) }, [](const callbackInfo_t* callback) { + return parse("${auto2}$<user.name>${0}@${auto2}$<os.hostname>", callback->modulesInfo, + callback->config); + } }; + cfRegisterModule(title_module); + + // $<colors> + module_t colros_symbol_module = { + "symbol", + {}, + [](const callbackInfo_t* callback) { + const moduleArgs_t* symbolArg; + for (symbolArg = callback->moduleArgs; symbolArg && symbolArg->name != "symbol"; + symbolArg = symbolArg->next) + ; + if (symbolArg->value.empty()) + die( + _("color symbol palette argument module is empty.\n" + "Must be used like 'colors_symbol(`symbol for printing the color palette`)'")); + + if (symbolArg->prev->name == "light") + return parse( + fmt::format("${{\033[90m}} {0} ${{\033[91m}} {0} ${{\033[92m}} {0} ${{\033[93m}} {0} ${{\033[94m}} " + "{0} ${{\033[95m}} {0} ${{\033[96m}} {0} ${{\033[97m}} {0} ${{0}}", + symbolArg->value), + callback->modulesInfo, callback->config); + else + return parse( + fmt::format("${{\033[30m}} {0} ${{\033[31m}} {0} ${{\033[32m}} {0} ${{\033[33m}} {0} ${{\033[34m}} " + "{0} ${{\033[35m}} {0} ${{\033[36m}} {0} ${{\033[37m}} {0} ${{0}}", + symbolArg->value), + callback->modulesInfo, callback->config); + } + }; + module_t colors_light_module = { "light", { std::move(colros_symbol_module) }, [](const callbackInfo_t* callback) { + return parse( + "${\033[100m} ${\033[101m} ${\033[102m} ${\033[103m} ${\033[104m} " + " ${\033[105m} ${\033[106m} ${\033[107m} ${0}", + callback->modulesInfo, callback->config); + } }; + module_t colors_module = { "colors", + { std::move(colros_symbol_module), std::move(colors_light_module) }, + [](const callbackInfo_t* callback) { + return parse( + "${\033[40m} ${\033[41m} ${\033[42m} ${\033[43m} ${\033[44m} " + "${\033[45m} ${\033[46m} ${\033[47m} ${0}", + callback->modulesInfo, callback->config); + } }; + cfRegisterModule(colors_module); } diff --git a/src/parse.cpp b/src/parse.cpp index 7c8d6e39..0906005a 100644 --- a/src/parse.cpp +++ b/src/parse.cpp @@ -244,7 +244,7 @@ std::string get_and_color_percentage(const float n1, const float n2, parse_args_ return parse(fmt::format("{}{:.2f}%${{0}}", color, result), _, parse_args); } -const std::string getInfoFromName(const moduleMap_t& modulesInfo, const std::string& moduleName) +const std::string getInfoFromName(const parse_args_t& parse_args, const std::string& moduleName) { std::string name; name.reserve(moduleName.size()); @@ -324,9 +324,9 @@ const std::string getInfoFromName(const moduleMap_t& modulesInfo, const std::str } std::string result = "(unknown/invalid module)"; - if (const auto& it = modulesInfo.find(name); it != modulesInfo.end()) + if (const auto& it = parse_args.modulesInfo.find(name); it != parse_args.modulesInfo.end()) { - struct callbackInfo_t callbackInfo = { moduleArgs }; + struct callbackInfo_t callbackInfo = { moduleArgs, parse_args.modulesInfo, parse_args.config }; result = it->second.handler(&callbackInfo); } @@ -719,7 +719,7 @@ std::optional<std::string> parse_info_tag(Parser& parser, parse_args_t& parse_ar if (!evaluate) return {}; - const std::string& info = getInfoFromName(parse_args.modulesInfo, module); + const std::string& info = getInfoFromName(parse_args, module); if (parser.dollar_pos != std::string::npos) parse_args.pureOutput.replace(parser.dollar_pos, module.length() + "$<>"_len, info); @@ -804,7 +804,7 @@ std::string parse(Parser& parser, parse_args_t& parse_args, const bool evaluate, return result; } -std::string parse(std::string input, moduleMap_t& modulesInfo, std::string& pureOutput, +std::string parse(std::string input, const moduleMap_t& modulesInfo, std::string& pureOutput, std::vector<std::string>& layout, std::vector<std::string>& tmp_layout, const Config& config, const bool parsingLayout, bool& no_more_reset) { @@ -843,6 +843,13 @@ std::string parse(std::string input, moduleMap_t& modulesInfo, std::string& pure return ret; } +const std::string parse(const std::string& input, const moduleMap_t& modulesInfo, const Config& config) +{ + std::vector<std::string> nah; + parse_args_t parse_args{ modulesInfo, _, nah, nah, config, true, true, true}; + return parse(input, parse_args); +} + // Re-enable them later // trying some plugins stuff #if 0 From 1b80076931ab2b3a07474e8aa72fbed2392d6e47 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Fri, 27 Jun 2025 19:02:04 +0200 Subject: [PATCH 044/143] core-plugins: linux: finally fix os.uptime this is the moment I've been waiting for --- include/core-modules.hh | 2 +- src/core-plugins/linux/linux-core-modules.cc | 41 +++++++++++++++++++- src/core-plugins/linux/os.cc | 4 +- src/parse.cpp | 21 ---------- 4 files changed, 43 insertions(+), 25 deletions(-) diff --git a/include/core-modules.hh b/include/core-modules.hh index 4a61c2e7..250e0e7d 100644 --- a/include/core-modules.hh +++ b/include/core-modules.hh @@ -22,7 +22,7 @@ MODFUNC(os_pretty_name); MODFUNC(os_name_id); MODFUNC(os_version_id); MODFUNC(os_version_codename); -MODFUNC(os_uptime); +unsigned long os_uptime(); MODFUNC(os_kernel_name); MODFUNC(os_kernel_version); MODFUNC(os_hostname); diff --git a/src/core-plugins/linux/linux-core-modules.cc b/src/core-plugins/linux/linux-core-modules.cc index 89558df0..54985f86 100644 --- a/src/core-plugins/linux/linux-core-modules.cc +++ b/src/core-plugins/linux/linux-core-modules.cc @@ -4,6 +4,7 @@ #include <algorithm> #include <array> +#include <chrono> #include <string> #include <string_view> #include <utility> @@ -35,9 +36,36 @@ const std::string amount(const double amount, const moduleArgs_t* moduleArgs) return "0"; } +static std::string get_auto_uptime(const std::uint16_t days, const std::uint16_t hours, const std::uint16_t mins, + const std::uint16_t secs, const Config& config) +{ + if (days == 0 && hours == 0 && mins == 0) + return fmt::format("{}{}", secs, config.uptime_s_fmt); + + std::string ret; + + if (days > 0) + ret += fmt::format("{}{}, ", days, config.uptime_d_fmt); + + if (hours > 0) + ret += fmt::format("{}{}, ", hours, config.uptime_h_fmt); + + if (mins > 0) + ret += fmt::format("{}{}, ", mins, config.uptime_m_fmt); + + ret.erase(ret.length() - 2); // the last ", " + + return ret; +} + void core_plugins_start() { // ------------ INIT STUFF ------------ + const std::chrono::seconds uptime_secs(os_uptime()); + const std::chrono::minutes& uptime_mins = std::chrono::duration_cast<std::chrono::minutes>(uptime_secs); + const std::chrono::hours& uptime_hours = std::chrono::duration_cast<std::chrono::hours>(uptime_secs); + const size_t uptime_days = uptime_secs.count() / (60 * 60 * 24); + if (uname(&g_uname_infos) != 0) die(_("uname() failed: {}\nCould not get system infos"), strerror(errno)); @@ -64,7 +92,18 @@ void core_plugins_start() std::move(os_name_id_module) }, os_name }; - module_t os_uptime_module = {"uptime", {}, os_uptime}; + module_t os_uptime_s_module = {"secs", {}, [&](unused) {return fmt::to_string(uptime_secs.count() % 60);}}; + module_t os_uptime_m_module = {"mins", {}, [&](unused) {return fmt::to_string(uptime_mins.count() % 60);}}; + module_t os_uptime_h_module = {"hours", {}, [&](unused) {return fmt::to_string(uptime_hours.count() % 24);}}; + module_t os_uptime_d_module = {"days", {}, [&](unused) {return fmt::to_string(uptime_days);}}; + module_t os_uptime_module = {"uptime", { + std::move(os_uptime_s_module), + std::move(os_uptime_m_module), + std::move(os_uptime_h_module), + std::move(os_uptime_d_module), + }, [&](const callbackInfo_t* callback) { return get_auto_uptime(uptime_days, uptime_hours.count() % 24, uptime_mins.count() % 60, + uptime_secs.count() % 60, callback->config); }}; + module_t os_hostname_module = {"hostname", {}, os_hostname}; module_t os_kernel_name_module = {"name", {}, os_kernel_name}; diff --git a/src/core-plugins/linux/os.cc b/src/core-plugins/linux/os.cc index 005d2460..8acc80d8 100644 --- a/src/core-plugins/linux/os.cc +++ b/src/core-plugins/linux/os.cc @@ -75,8 +75,8 @@ MODFUNC(os_version_id) MODFUNC(os_version_codename) { return read_value("VERSION_CODENAME="); } -MODFUNC(os_uptime) -{ return fmt::to_string(get_uptime()); } +unsigned long os_uptime() +{ return get_uptime(); } MODFUNC(os_kernel_name) { return g_uname_infos.sysname; } diff --git a/src/parse.cpp b/src/parse.cpp index 0906005a..9c661b40 100644 --- a/src/parse.cpp +++ b/src/parse.cpp @@ -853,27 +853,6 @@ const std::string parse(const std::string& input, const moduleMap_t& modulesInfo // Re-enable them later // trying some plugins stuff #if 0 -static std::string get_auto_uptime(const std::uint16_t days, const std::uint16_t hours, const std::uint16_t mins, - const std::uint16_t secs, const Config& config) -{ - if (days == 0 && hours == 0 && mins == 0) - return fmt::format("{}{}", secs, config.uptime_s_fmt); - - std::string ret; - - if (days > 0) - ret += fmt::format("{}{}, ", days, config.uptime_d_fmt); - - if (hours > 0) - ret += fmt::format("{}{}, ", hours, config.uptime_h_fmt); - - if (mins > 0) - ret += fmt::format("{}{}, ", mins, config.uptime_m_fmt); - - ret.erase(ret.length() - 2); // the last ", " - - return ret; -} static std::string get_auto_gtk_format(const std::string_view gtk2, const std::string_view gtk3, const std::string_view gtk4) From 9e5f6949cecc3a59b884380e4c3c8d82010b6dda Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Fri, 27 Jun 2025 19:12:23 +0200 Subject: [PATCH 045/143] ops --- Makefile | 2 +- src/core-plugins/linux/linux-core-modules.cc | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index c0b11de7..304b7794 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ USE_DCONF ?= 1 # WAY easier way to build debug and release builds ifeq ($(DEBUG), 1) BUILDDIR = build/debug - CXXFLAGS := -ggdb3 -Wall -Wextra -Wpedantic -Wno-unused-parameter -DDEBUG=1 -fsanitize=address $(DEBUG_CXXFLAGS) $(CXXFLAGS) + CXXFLAGS := -ggdb3 -Wall -Wextra -Wpedantic -Wno-unused-parameter -DDEBUG=1 -fno-omit-frame-pointer -fsanitize=address $(DEBUG_CXXFLAGS) $(CXXFLAGS) LDFLAGS += -fsanitize=address else # Check if an optimization flag is not already set diff --git a/src/core-plugins/linux/linux-core-modules.cc b/src/core-plugins/linux/linux-core-modules.cc index 54985f86..d6bf27b2 100644 --- a/src/core-plugins/linux/linux-core-modules.cc +++ b/src/core-plugins/linux/linux-core-modules.cc @@ -92,16 +92,16 @@ void core_plugins_start() std::move(os_name_id_module) }, os_name }; - module_t os_uptime_s_module = {"secs", {}, [&](unused) {return fmt::to_string(uptime_secs.count() % 60);}}; - module_t os_uptime_m_module = {"mins", {}, [&](unused) {return fmt::to_string(uptime_mins.count() % 60);}}; - module_t os_uptime_h_module = {"hours", {}, [&](unused) {return fmt::to_string(uptime_hours.count() % 24);}}; - module_t os_uptime_d_module = {"days", {}, [&](unused) {return fmt::to_string(uptime_days);}}; + module_t os_uptime_s_module = {"secs", {}, [=](unused) {return fmt::to_string(uptime_secs.count() % 60);}}; + module_t os_uptime_m_module = {"mins", {}, [=](unused) {return fmt::to_string(uptime_mins.count() % 60);}}; + module_t os_uptime_h_module = {"hours", {}, [=](unused) {return fmt::to_string(uptime_hours.count() % 24);}}; + module_t os_uptime_d_module = {"days", {}, [=](unused) {return fmt::to_string(uptime_days);}}; module_t os_uptime_module = {"uptime", { std::move(os_uptime_s_module), std::move(os_uptime_m_module), std::move(os_uptime_h_module), std::move(os_uptime_d_module), - }, [&](const callbackInfo_t* callback) { return get_auto_uptime(uptime_days, uptime_hours.count() % 24, uptime_mins.count() % 60, + }, [=](const callbackInfo_t* callback) { return get_auto_uptime(uptime_days, uptime_hours.count() % 24, uptime_mins.count() % 60, uptime_secs.count() % 60, callback->config); }}; module_t os_hostname_module = {"hostname", {}, os_hostname}; From 43c6d3ec4214a8057b2db83eb8b39034161f3bad Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Fri, 27 Jun 2025 19:25:51 +0200 Subject: [PATCH 046/143] core-plugins: linux: fix colors symbol modules --- src/core-plugins/linux/linux-core-modules.cc | 60 ++++++++++++-------- 1 file changed, 36 insertions(+), 24 deletions(-) diff --git a/src/core-plugins/linux/linux-core-modules.cc b/src/core-plugins/linux/linux-core-modules.cc index d6bf27b2..28ae84c9 100644 --- a/src/core-plugins/linux/linux-core-modules.cc +++ b/src/core-plugins/linux/linux-core-modules.cc @@ -58,6 +58,31 @@ static std::string get_auto_uptime(const std::uint16_t days, const std::uint16_t return ret; } +static std::string get_colors_symbol(const callbackInfo_t* callback, bool is_light) +{ + const moduleArgs_t* symbolArg; + for (symbolArg = callback->moduleArgs; symbolArg && symbolArg->name != "symbol"; + symbolArg = symbolArg->next) + ; + if (symbolArg->value.empty()) + die( + _("color symbol palette argument module is empty.\n" + "Must be used like 'colors_symbol(`symbol for printing the color palette`)'")); + + if (is_light) + return parse( + fmt::format("${{\033[90m}} {0} ${{\033[91m}} {0} ${{\033[92m}} {0} ${{\033[93m}} {0} ${{\033[94m}} " + "{0} ${{\033[95m}} {0} ${{\033[96m}} {0} ${{\033[97m}} {0} ${{0}}", + symbolArg->value), + callback->modulesInfo, callback->config); + else + return parse( + fmt::format("${{\033[30m}} {0} ${{\033[31m}} {0} ${{\033[32m}} {0} ${{\033[33m}} {0} ${{\033[34m}} " + "{0} ${{\033[35m}} {0} ${{\033[36m}} {0} ${{\033[37m}} {0} ${{0}}", + symbolArg->value), + callback->modulesInfo, callback->config); +} + void core_plugins_start() { // ------------ INIT STUFF ------------ @@ -395,41 +420,28 @@ void core_plugins_start() cfRegisterModule(title_module); // $<colors> - module_t colros_symbol_module = { + module_t colors_light_symbol_module = { + "symbol", + {}, + [](const callbackInfo_t* callback) { + return get_colors_symbol(callback, true); + } + }; + module_t colors_symbol_module = { "symbol", {}, [](const callbackInfo_t* callback) { - const moduleArgs_t* symbolArg; - for (symbolArg = callback->moduleArgs; symbolArg && symbolArg->name != "symbol"; - symbolArg = symbolArg->next) - ; - if (symbolArg->value.empty()) - die( - _("color symbol palette argument module is empty.\n" - "Must be used like 'colors_symbol(`symbol for printing the color palette`)'")); - - if (symbolArg->prev->name == "light") - return parse( - fmt::format("${{\033[90m}} {0} ${{\033[91m}} {0} ${{\033[92m}} {0} ${{\033[93m}} {0} ${{\033[94m}} " - "{0} ${{\033[95m}} {0} ${{\033[96m}} {0} ${{\033[97m}} {0} ${{0}}", - symbolArg->value), - callback->modulesInfo, callback->config); - else - return parse( - fmt::format("${{\033[30m}} {0} ${{\033[31m}} {0} ${{\033[32m}} {0} ${{\033[33m}} {0} ${{\033[34m}} " - "{0} ${{\033[35m}} {0} ${{\033[36m}} {0} ${{\033[37m}} {0} ${{0}}", - symbolArg->value), - callback->modulesInfo, callback->config); + return get_colors_symbol(callback, false); } }; - module_t colors_light_module = { "light", { std::move(colros_symbol_module) }, [](const callbackInfo_t* callback) { + module_t colors_light_module = { "light", { std::move(colors_light_symbol_module) }, [](const callbackInfo_t* callback) { return parse( "${\033[100m} ${\033[101m} ${\033[102m} ${\033[103m} ${\033[104m} " " ${\033[105m} ${\033[106m} ${\033[107m} ${0}", callback->modulesInfo, callback->config); } }; module_t colors_module = { "colors", - { std::move(colros_symbol_module), std::move(colors_light_module) }, + { std::move(colors_symbol_module), std::move(colors_light_module) }, [](const callbackInfo_t* callback) { return parse( "${\033[40m} ${\033[41m} ${\033[42m} ${\033[43m} ${\033[44m} " From 93970d34c416a1ac47074cea7d8d51f8af1948ff Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Fri, 27 Jun 2025 19:41:43 +0200 Subject: [PATCH 047/143] plugins: add installation of headers --- CMakeLists.txt | 13 ++++++++++++- Makefile | 4 ++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0d171899..74729e5f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -102,10 +102,16 @@ set(LOCALEDIR "${CMAKE_INSTALL_PREFIX}/share/locale" CACHE PATH "Locale files di set(ICONPREFIX "${CMAKE_INSTALL_PREFIX}/share/pixmaps" CACHE PATH "Icon installation directory") target_compile_definitions(${TARGET_NAME} PRIVATE MANPREFIX="${MANPREFIX}" - APPPREFIX="${APPPREFIX}" + APPPREFIX="${APPPREFIX}" LOCALEDIR="${LOCALEDIR}" ICONPREFIX="${ICONPREFIX}" ) +set(CUFETCH_HEADERS + include/config.hpp + include/common.hpp + include/core-modules.hh + include/cufetch.hh +) # Install executable install(TARGETS ${TARGET_NAME} @@ -124,6 +130,11 @@ install(FILES ${CMAKE_SOURCE_DIR}/LICENSE DESTINATION share/licenses/customfetch COMPONENT documentation) +install(FILES ${CUFETCH_HEADERS} + DESTINATION include/cufetch + COMPONENT development +) + install(DIRECTORY ${CMAKE_SOURCE_DIR}/assets/ascii/ DESTINATION share/customfetch/ascii COMPONENT runtime) diff --git a/Makefile b/Makefile index 304b7794..4a4fbf98 100644 --- a/Makefile +++ b/Makefile @@ -61,6 +61,7 @@ SRC_CC = $(wildcard src/core-plugins/linux/*.cc) OBJ_CPP = $(SRC_CPP:.cpp=.o) OBJ_CC = $(SRC_CC:.cc=.o) OBJ = $(OBJ_CPP) $(OBJ_CC) +HEADERS = include/config.hpp include/common.hpp include/core-modules.hh include/cufetch.hh LDFLAGS += -L./$(BUILDDIR) -lcufetch -lfmt -ldl CXXFLAGS ?= -mtune=generic -march=native CXXFLAGS += -fvisibility=hidden -Iinclude -std=c++20 $(VARS) -DVERSION=\"$(VERSION)\" -DLOCALEDIR=\"$(LOCALEDIR)\" -DICONPREFIX=\"$(ICONPREFIX)\" @@ -137,6 +138,8 @@ install-common: locale cd assets/icons && find . -type f -exec install -Dm 644 "{}" "$(DESTDIR)$(ICONPREFIX)/$(NAME)/{}" \; find examples/ -type f -exec install -Dm 644 "{}" "$(DESTDIR)$(PREFIX)/share/$(NAME)/{}" \; find locale/ -type f -exec install -Dm 644 "{}" "$(DESTDIR)$(PREFIX)/share/{}" \; + mkdir -p $(DESTDIR)$(PREFIX)/include/cufetch/ + find $(HEADERS) -type f -exec install -Dm 644 "{}" "$(DESTDIR)$(PREFIX)/include/cufetch/{}" \; ifeq ($(GUI_APP), 1) mkdir -p $(DESTDIR)$(APPPREFIX) cp -f $(NAME).desktop $(DESTDIR)$(APPPREFIX)/$(NAME).desktop @@ -148,6 +151,7 @@ uninstall: rm -f $(DESTDIR)$(APPPREFIX)/$(NAME).desktop rm -rf $(DESTDIR)$(PREFIX)/share/licenses/$(NAME)/ rm -rf $(DESTDIR)$(PREFIX)/share/$(NAME)/ + rm -rf $(DESTDIR)$(PREFIX)/include/cufetch/ rm -rf $(DESTDIR)$(ICONPREFIX)/$(NAME)/ find $(DESTDIR)$(LOCALEDIR) -type f -path "$(DESTDIR)$(LOCALEDIR)/*/LC_MESSAGES/$(NAME).mo" -exec rm -f {} \; From ac6dc7c1e56b9eba6b2b3a55ebd937c7be3c43d3 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Fri, 27 Jun 2025 21:47:51 +0200 Subject: [PATCH 048/143] libcufetch: move parse and config to libcufetch --- CMakeLists.txt | 54 +++++++++++++++++----- Makefile | 9 ++-- include/util.hpp | 62 +++++++++++++------------- libcufetch/Makefile | 15 ++++--- src/config.cpp => libcufetch/config.cc | 0 src/parse.cpp => libcufetch/parse.cc | 0 src/main.cpp | 4 +- 7 files changed, 90 insertions(+), 54 deletions(-) rename src/config.cpp => libcufetch/config.cc (100%) rename src/parse.cpp => libcufetch/parse.cc (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 74729e5f..98100ba3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,10 +12,10 @@ include_directories(include) file(GLOB SRC "src/*.cpp" - "src/query/linux/*.cpp" + "src/core-plugins/linux/*.cc" "src/query/android/*.cpp" "src/query/macos/*.cpp" - "src/query/linux/utils/*.cpp" + "src/core-plugins/linux/utils/*.cpp" "src/libs/json/json.cpp" "src/libs/toml++/toml.cpp") @@ -69,7 +69,6 @@ if(USE_DCONF) if(DCONF_FOUND) message(STATUS "Found dconf - enabling dconf support") target_compile_definitions(${TARGET_NAME} PRIVATE USE_DCONF=1) - target_link_libraries(${TARGET_NAME} PUBLIC ${DCONF_LIBRARIES}) target_include_directories(${TARGET_NAME} PUBLIC ${DCONF_INCLUDE_DIRS}) target_compile_options(${TARGET_NAME} PUBLIC ${DCONF_CFLAGS_OTHER}) else() @@ -85,8 +84,35 @@ add_library(fmt STATIC "src/libs/fmt/os.cc" "src/libs/fmt/format.cc") +set_target_properties(fmt PROPERTIES POSITION_INDEPENDENT_CODE ON) target_link_libraries(${TARGET_NAME} PUBLIC fmt) +# libcufetch +set(CUFETCH_HEADERS + include/config.hpp + include/common.hpp + include/core-modules.hh + include/cufetch.hh +) + +add_library(cufetch SHARED + libcufetch/config.cc + libcufetch/cufetch.cc + libcufetch/parse.cc +) + +set_target_properties(cufetch PROPERTIES + VERSION 1.0.0 + SOVERSION 1 + OUTPUT_NAME "cufetch" + PUBLIC_HEADER "${CUFETCH_HEADERS}" + POSITION_INDEPENDENT_CODE ON +) + +target_link_libraries(cufetch PUBLIC fmt) +target_link_libraries(${TARGET_NAME} PUBLIC cufetch) + +# locale add_custom_target(locale COMMAND ${CMAKE_SOURCE_DIR}/scripts/make_mo.sh ${CMAKE_SOURCE_DIR}/locale/ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} @@ -106,12 +132,6 @@ target_compile_definitions(${TARGET_NAME} PRIVATE LOCALEDIR="${LOCALEDIR}" ICONPREFIX="${ICONPREFIX}" ) -set(CUFETCH_HEADERS - include/config.hpp - include/common.hpp - include/core-modules.hh - include/cufetch.hh -) # Install executable install(TARGETS ${TARGET_NAME} @@ -130,9 +150,10 @@ install(FILES ${CMAKE_SOURCE_DIR}/LICENSE DESTINATION share/licenses/customfetch COMPONENT documentation) -install(FILES ${CUFETCH_HEADERS} - DESTINATION include/cufetch - COMPONENT development +install(TARGETS cufetch + LIBRARY DESTINATION lib + PUBLIC_HEADER DESTINATION include/cufetch + COMPONENT runtime ) install(DIRECTORY ${CMAKE_SOURCE_DIR}/assets/ascii/ @@ -151,6 +172,15 @@ install(DIRECTORY ${CMAKE_SOURCE_DIR}/locale/ DESTINATION share/locale COMPONENT runtime) +install(CODE " + execute_process( + COMMAND ${CMAKE_COMMAND} -E create_symlink libcufetch.so.1 ${CMAKE_INSTALL_PREFIX}/lib/libcufetch.so + ) + execute_process( + COMMAND ${CMAKE_COMMAND} -E create_symlink libcufetch.so.1.0.0 ${CMAKE_INSTALL_PREFIX}/lib/libcufetch.so.1 + ) +") + install(CODE " execute_process( COMMAND ${CMAKE_SOURCE_DIR}/scripts/make_mo.sh ${CMAKE_SOURCE_DIR}/locale/ diff --git a/Makefile b/Makefile index 4a4fbf98..d972575e 100644 --- a/Makefile +++ b/Makefile @@ -61,10 +61,10 @@ SRC_CC = $(wildcard src/core-plugins/linux/*.cc) OBJ_CPP = $(SRC_CPP:.cpp=.o) OBJ_CC = $(SRC_CC:.cc=.o) OBJ = $(OBJ_CPP) $(OBJ_CC) -HEADERS = include/config.hpp include/common.hpp include/core-modules.hh include/cufetch.hh +HEADERS = config.hpp common.hpp core-modules.hh cufetch.hh LDFLAGS += -L./$(BUILDDIR) -lcufetch -lfmt -ldl CXXFLAGS ?= -mtune=generic -march=native -CXXFLAGS += -fvisibility=hidden -Iinclude -std=c++20 $(VARS) -DVERSION=\"$(VERSION)\" -DLOCALEDIR=\"$(LOCALEDIR)\" -DICONPREFIX=\"$(ICONPREFIX)\" +CXXFLAGS += -fvisibility-inlines-hidden -fvisibility=hidden -Iinclude -std=c++20 $(VARS) -DVERSION=\"$(VERSION)\" -DLOCALEDIR=\"$(LOCALEDIR)\" -DICONPREFIX=\"$(ICONPREFIX)\" all: genver libcufetch fmt toml json $(TARGET) @@ -129,7 +129,7 @@ install: install-common $(TARGET) install $(BUILDDIR)/$(TARGET) -Dm 755 -v $(DESTDIR)$(PREFIX)/bin/$(TARGET) cd $(DESTDIR)$(PREFIX)/bin/ && ln -sf $(TARGET) cufetch -install-common: locale +install-common: libcufetch locale mkdir -p $(DESTDIR)$(MANPREFIX)/man1/ sed -e "s/@VERSION@/$(VERSION)/g" -e "s/@BRANCH@/$(BRANCH)/g" < $(NAME).1 > $(DESTDIR)$(MANPREFIX)/man1/$(NAME).1 chmod 644 $(DESTDIR)$(MANPREFIX)/man1/$(NAME).1 @@ -139,7 +139,8 @@ install-common: locale find examples/ -type f -exec install -Dm 644 "{}" "$(DESTDIR)$(PREFIX)/share/$(NAME)/{}" \; find locale/ -type f -exec install -Dm 644 "{}" "$(DESTDIR)$(PREFIX)/share/{}" \; mkdir -p $(DESTDIR)$(PREFIX)/include/cufetch/ - find $(HEADERS) -type f -exec install -Dm 644 "{}" "$(DESTDIR)$(PREFIX)/include/cufetch/{}" \; + cd include && find $(HEADERS) -type f -exec install -Dm 644 "{}" "$(DESTDIR)$(PREFIX)/include/cufetch/{}" \; + install -Dm 755 $(BUILDDIR)/libcufetch.so $(DESTDIR)$(PREFIX)/lib/libcufetch.so.1 ifeq ($(GUI_APP), 1) mkdir -p $(DESTDIR)$(APPPREFIX) cp -f $(NAME).desktop $(DESTDIR)$(APPPREFIX)/$(NAME).desktop diff --git a/include/util.hpp b/include/util.hpp index 71568948..aa7c2a6e 100644 --- a/include/util.hpp +++ b/include/util.hpp @@ -63,44 +63,44 @@ struct byte_units_t * @param fullString The string to lookup * @param ending The string to check at the end of fullString */ -bool hasEnding(const std::string_view fullString, const std::string_view ending); +EXPORT bool hasEnding(const std::string_view fullString, const std::string_view ending); /* https://stackoverflow.com/questions/874134/find-out-if-string-ends-with-another-string-in-c#874160 * Check if substring exists at the start * @param fullString The string to lookup * @param start The string to check at the start of fullString */ -bool hasStart(const std::string_view fullString, const std::string_view start); +EXPORT bool hasStart(const std::string_view fullString, const std::string_view start); std::vector<std::string> split(const std::string_view text, char delim); /* Get device name from `all_ids` in pci.ids.hpp * @param dev_entry_pos Line position from where the device is located */ -std::string name_from_entry(size_t dev_entry_pos); +EXPORT std::string name_from_entry(size_t dev_entry_pos); /* Get vendor device name from `all_ids` in pci.ids.hpp * @param vendor_entry_pos Line position from where the device is located * @param vendor_id_s The vendor ID (e.g 10de) */ -std::string vendor_from_entry(const size_t vendor_entry_pos, const std::string_view vendor_id_s); +EXPORT std::string vendor_from_entry(const size_t vendor_entry_pos, const std::string_view vendor_id_s); /* Function to perform binary search on the pci vendors array to find a device from a vendor. * @param vendor_id_s The vendor ID (e.g 10de) * @param pci_id_s The device ID (e.g 1f82) */ -std::string binarySearchPCIArray(const std::string_view vendor_id_s, const std::string_view pci_id_s); +EXPORT std::string binarySearchPCIArray(const std::string_view vendor_id_s, const std::string_view pci_id_s); /* Function to perform binary search on the pci vendors array to find a vendor. * @param vendor_id_s The vendor ID (e.g 10de) */ -std::string binarySearchPCIArray(const std::string_view vendor_id_s); +EXPORT std::string binarySearchPCIArray(const std::string_view vendor_id_s); /* http://stackoverflow.com/questions/478898/ddg#478960 * Execute shell command and read its output from stdout. * @param cmd The command to execute */ -std::string read_shell_exec(const std::string_view cmd); +EXPORT std::string read_shell_exec(const std::string_view cmd); /* Get file value from a file and trim quotes and double-quotes * @param iterIndex The iteration index used for getting the necessary value only tot times @@ -108,45 +108,45 @@ std::string read_shell_exec(const std::string_view cmd); * @param str The string to assign the trimmed value, inline * @param amount The amount to be used in the line.substr() (should be used with something like "foobar"_len) */ -void getFileValue(u_short& iterIndex, const std::string_view line, std::string& str, const size_t& amount); +EXPORT void getFileValue(u_short& iterIndex, const std::string_view line, std::string& str, const size_t& amount); /* Covert bytes (or bibytes) to be accurate to the max prefix (maxprefix or YB/YiB) * @param num The number to convert * @param base Base to devide (1000 = bytes OR 1024 = bibytes) * @param maxprefix The maxinum prefix we can go up to (empty for ignore) */ -byte_units_t auto_divide_bytes(const double num, const std::uint16_t base, const std::string_view maxprefix = ""); +EXPORT byte_units_t auto_divide_bytes(const double num, const std::uint16_t base, const std::string_view maxprefix = ""); /* Covert bytes (or bibytes) to be accurate to a specific prefix * @param num The number to convert * @param prefix The prefix we want to convert to (GiB, MB, etc.) */ -byte_units_t divide_bytes(const double num, const std::string_view prefix); +EXPORT byte_units_t divide_bytes(const double num, const std::string_view prefix); /* Check if file is image (static or gif). * Doesn't check for mp4, mp3 or other binary formats * @param bytes The header bytes of the file */ -bool is_file_image(const unsigned char* bytes); +EXPORT bool is_file_image(const unsigned char* bytes); /* Write error message and exit if EOF (or CTRL-D most of the time) * @param cin The std::cin used for getting the input */ -void ctrl_d_handler(const std::istream& cin); +EXPORT void ctrl_d_handler(const std::istream& cin); /* Replace special symbols such as ~ and $ (at the begging) in std::string * @param str The string * @param dont Don't do it * @return The modified string */ -std::string expandVar(std::string ret, bool dont = false); +EXPORT std::string expandVar(std::string ret, bool dont = false); /* Executes commands with execvp() and keep the program running without existing * @param cmd_str The command to execute * @param exitOnFailure Whether to call exit(1) on command failure. * @return true if the command successed, else false */ -bool taur_exec(const std::vector<std::string_view> cmd_str, const bool noerror_print = true); +EXPORT bool taur_exec(const std::vector<std::string_view> cmd_str, const bool noerror_print = true); /* Get a relative path from an enviroment variable (PATH, XDG_DATA_DIRS, ...) * Either path of an executable, directory, etc... @@ -155,22 +155,22 @@ bool taur_exec(const std::vector<std::string_view> cmd_str, const bool noerror_p * @param mode Mode of the file/directory using the enums declared in sys/stat.h * Such as S_IXUSR for executables, S_IFDIR for directories, etc. */ -std::string get_relative_path(const std::string_view relative_path, const std::string_view env, const long long mode); +EXPORT std::string get_relative_path(const std::string_view relative_path, const std::string_view env, const long long mode); /* Simulate behaviour of the command `which` * @param command The command to lookup in the $PATH */ -std::string which(const std::string_view command); +EXPORT std::string which(const std::string_view command); /* Get file path from $XDG_DATA_DIRS * @param file The file to lookup in the env */ -std::string get_data_path(const std::string_view file); +EXPORT std::string get_data_path(const std::string_view file); /* Get directory path from $XDG_DATA_DIRS * @param dir The directory to lookup in the env */ -std::string get_data_dir(const std::string_view dir); +EXPORT std::string get_data_dir(const std::string_view dir); /* Read a binary file and get its current line, * which simulates the behaviour of the command `strings` but one line at the time @@ -192,7 +192,7 @@ std::string get_data_dir(const std::string_view dir); * } * return false; */ -bool read_binary_file(std::ifstream& f, std::string& ret); +EXPORT bool read_binary_file(std::ifstream& f, std::string& ret); /* https://gist.github.com/GenesisFR/cceaf433d5b42dcdddecdddee0657292 * Replace every instances (inplace) of a substring @@ -200,7 +200,7 @@ bool read_binary_file(std::ifstream& f, std::string& ret); * @param from The substring to lookup to be replaced * @param to The substring to replace in instances of `from` */ -void replace_str(std::string& str, const std::string_view from, const std::string_view to); +EXPORT void replace_str(std::string& str, const std::string_view from, const std::string_view to); /* Executes commands with execvp() and read its output * either from stdout or stderr @@ -210,47 +210,47 @@ void replace_str(std::string& str, const std::string_view from, const std::strin * @param noerror_print Print errors (default true) * @return true if the command successed, else false */ -bool read_exec(std::vector<const char*> cmd, std::string& output, bool useStdErr = false, bool noerror_print = true); +EXPORT bool read_exec(std::vector<const char*> cmd, std::string& output, bool useStdErr = false, bool noerror_print = true); /* Make whole string lowercase * @param str The string to use */ -std::string str_tolower(std::string str); +EXPORT std::string str_tolower(std::string str); /* Make whole string uppercase * @param str The string to use */ -std::string str_toupper(std::string str); +EXPORT std::string str_toupper(std::string str); /* Remove all white spaces (' ', '\t', '\n') from string inplace! * @param input The string to strip * @param padding_only Just trim the string */ -void strip(std::string& input, bool padding_only = true); +EXPORT void strip(std::string& input, bool padding_only = true); /* Read file content (usually from /sys) * and return its first (and only) line, else UNKNOWN * @param path The path of the file to read * @param report_error Report error if any */ -std::string read_by_syspath(const std::string_view path, bool report_error = false); +EXPORT std::string read_by_syspath(const std::string_view path, bool report_error = false); /* Convert hex color (#255224) to a fmt::rgb * @param hexstr The hex color string (must have a '#' at the start) */ -fmt::rgb hexStringToColor(const std::string_view hexstr); +EXPORT fmt::rgb hexStringToColor(const std::string_view hexstr); /* Abbreviate the vendors names * @param vendor The vendor name */ -std::string shorten_vendor_name(std::string vendor); +EXPORT std::string shorten_vendor_name(std::string vendor); /* * Get the user config directory * either from $XDG_CONFIG_HOME or from $HOME/.config/ * @return user's config directory */ -std::filesystem::path getHomeConfigDir(); +EXPORT std::filesystem::path getHomeConfigDir(); /* * Get the customfetch config directory @@ -258,13 +258,13 @@ std::filesystem::path getHomeConfigDir(); * from getHomeConfigDir() * @return customfetch's config directory */ -std::filesystem::path getConfigDir(); +EXPORT std::filesystem::path getConfigDir(); #if CF_ANDROID /* Get android property name such as "ro.product.marketname" * @param name The property name */ -std::string get_android_property(const std::string_view name); +EXPORT std::string get_android_property(const std::string_view name); #endif /** Ask the user a yes or no question. @@ -274,7 +274,7 @@ std::string get_android_property(const std::string_view name); * @returns the result, y = true, n = false, only returns def if the result is def */ template <typename... Args> -bool askUserYorN(bool def, const std::string_view fmt, Args&&... args) +EXPORT bool askUserYorN(bool def, const std::string_view fmt, Args&&... args) { const std::string& inputs_str = fmt::format(" [{}]: ", def ? "Y/n" : "y/N"); std::string result; diff --git a/libcufetch/Makefile b/libcufetch/Makefile index 31c13b4d..4776b89f 100644 --- a/libcufetch/Makefile +++ b/libcufetch/Makefile @@ -1,14 +1,19 @@ CXX ?= g++ CXX_INCLUDES = -I../include CXX_FLAGS = -shared -fPIC +SRC = $(wildcard *.cc) +OBJ = $(SRC:.cc=.o) -all: cufetch +all: libcufetch -cufetch: cufetch.cc - $(CXX) $(CXX_INCLUDES) $(CXX_FLAGS) cufetch.cc -o libcufetch.so - mv -f libcufetch.so ../$(BUILDDIR)/libcufetch.so +%.o: %.cc + $(CXX) $(CXX_INCLUDES) $(CXX_FLAGS) -c -o $@ $< + +libcufetch: $(OBJ) + $(CXX) $(OBJ) $(CXX_INCLUDES) $(CXX_FLAGS) -o libcufetch.so -L../$(BUILDDIR)/ -lfmt + mv -f libcufetch.so ../$(BUILDDIR)/$@.so clean: rm -f *.o *.so *.a ../$(BUILDDIR)/libcufetch.so -.PHONY: clean all cufetch +.PHONY: clean all libcufetch diff --git a/src/config.cpp b/libcufetch/config.cc similarity index 100% rename from src/config.cpp rename to libcufetch/config.cc diff --git a/src/parse.cpp b/libcufetch/parse.cc similarity index 100% rename from src/parse.cpp rename to libcufetch/parse.cc diff --git a/src/main.cpp b/src/main.cpp index ce3e8f2d..1a52829d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -802,9 +802,9 @@ int main(int argc, char *argv[]) continue; } - // LOAD_LIB_SYMBOL(handle, void, start, void*) + LOAD_LIB_SYMBOL(handle, void, start, void*) - // start(); + start(handle); } const std::vector<module_t>& modules = cfGetModules(); From 491ef7cb6779ab39b0630f4d907ae2fac0959e18 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Fri, 27 Jun 2025 22:20:35 +0200 Subject: [PATCH 049/143] core-plugins: linux: add some percentage modules --- include/common.hpp | 2 + libcufetch/parse.cc | 7 ++++ src/core-plugins/linux/linux-core-modules.cc | 41 ++++++++++---------- 3 files changed, 30 insertions(+), 20 deletions(-) diff --git a/include/common.hpp b/include/common.hpp index a6d18f18..3c6b0abd 100644 --- a/include/common.hpp +++ b/include/common.hpp @@ -116,7 +116,9 @@ struct module_t // Map from a modules name to its pointer. using moduleMap_t = std::unordered_map<std::string, const module_t&>; class Config; + const std::string parse(const std::string& input, const moduleMap_t& modulesInfo, const Config& config); +const std::string get_and_color_percentage(const float n1, const float n2, const callbackInfo_t* callback, const bool invert); struct callbackInfo_t { diff --git a/libcufetch/parse.cc b/libcufetch/parse.cc index 9c661b40..189f8d7e 100644 --- a/libcufetch/parse.cc +++ b/libcufetch/parse.cc @@ -244,6 +244,13 @@ std::string get_and_color_percentage(const float n1, const float n2, parse_args_ return parse(fmt::format("{}{:.2f}%${{0}}", color, result), _, parse_args); } +const std::string get_and_color_percentage(const float n1, const float n2, const callbackInfo_t* callback, const bool invert) +{ + std::vector<std::string> nah; + parse_args_t parse_args{ callback->modulesInfo, _, nah, nah, callback->config, true, true, true}; + return get_and_color_percentage(n1, n2, parse_args, invert); +} + const std::string getInfoFromName(const parse_args_t& parse_args, const std::string& moduleName) { std::string name; diff --git a/src/core-plugins/linux/linux-core-modules.cc b/src/core-plugins/linux/linux-core-modules.cc index 28ae84c9..9f558ed0 100644 --- a/src/core-plugins/linux/linux-core-modules.cc +++ b/src/core-plugins/linux/linux-core-modules.cc @@ -310,25 +310,33 @@ void core_plugins_start() cfRegisterModule(user_module); // $<ram> - module_t ram_free_module = {"free", {}, [](const callbackInfo_t *callback) { return amount(ram_free() * 1024, callback->moduleArgs); }}; - module_t ram_used_module = {"used", {}, [](const callbackInfo_t *callback) { return amount(ram_used() * 1024, callback->moduleArgs); }}; + module_t ram_free_perc_module = {"perc", {}, [](const callbackInfo_t *callback) {return get_and_color_percentage(ram_free(), ram_total(), callback, true);}}; + module_t ram_used_perc_module = {"perc", {}, [](const callbackInfo_t *callback) {return get_and_color_percentage(ram_used(), ram_total(), callback, false);}}; + module_t ram_free_module = {"free", {std::move(ram_free_perc_module)}, [](const callbackInfo_t *callback) { return amount(ram_free() * 1024, callback->moduleArgs); }}; + module_t ram_used_module = {"used", {std::move(ram_used_perc_module)}, [](const callbackInfo_t *callback) { return amount(ram_used() * 1024, callback->moduleArgs); }}; module_t ram_total_module = {"total", {}, [](const callbackInfo_t *callback) { return amount(ram_total() * 1024, callback->moduleArgs); }}; module_t ram_module = {"ram", { std::move(ram_free_module), std::move(ram_used_module), + std::move(ram_free_perc_module), + std::move(ram_used_perc_module), std::move(ram_total_module) }, NULL}; cfRegisterModule(ram_module); // $<swap> - module_t swap_free_module = {"free", {}, [](const callbackInfo_t *callback) { return amount(swap_free() * 1024, callback->moduleArgs); }}; - module_t swap_used_module = {"used", {}, [](const callbackInfo_t *callback) { return amount(swap_used() * 1024, callback->moduleArgs); }}; + module_t swap_free_perc_module = {"perc", {}, [](const callbackInfo_t *callback) {return get_and_color_percentage(swap_free(), swap_total(), callback, true);}}; + module_t swap_used_perc_module = {"perc", {}, [](const callbackInfo_t *callback) {return get_and_color_percentage(swap_used(), swap_total(), callback, false);}}; + module_t swap_free_module = {"free", {std::move(swap_free_perc_module)}, [](const callbackInfo_t *callback) { return amount(swap_free() * 1024, callback->moduleArgs); }}; + module_t swap_used_module = {"used", {std::move(swap_used_perc_module)}, [](const callbackInfo_t *callback) { return amount(swap_used() * 1024, callback->moduleArgs); }}; module_t swap_total_module = {"total", {}, [](const callbackInfo_t *callback) { return amount(swap_total() * 1024, callback->moduleArgs); }}; module_t swap_module = {"swap", { std::move(swap_free_module), std::move(swap_used_module), + std::move(swap_free_perc_module), + std::move(swap_used_perc_module), std::move(swap_total_module) }, NULL}; cfRegisterModule(swap_module); @@ -338,8 +346,11 @@ void core_plugins_start() module_t disk_device_module = {"device", {}, disk_device}; module_t disk_mountdir_module = {"mountdir", {}, disk_mountdir}; module_t disk_types_module = {"types", {}, disk_types}; - module_t disk_free_module = {"free", {}, [](const callbackInfo_t *callback) { return amount(disk_free(callback), callback->moduleArgs); }}; - module_t disk_used_module = {"used", {}, [](const callbackInfo_t *callback) { return amount(disk_used(callback), callback->moduleArgs); }}; + + module_t disk_free_perc_module = {"perc", {}, [](const callbackInfo_t *callback) {return get_and_color_percentage(disk_free(callback), disk_total(callback), callback, true);}}; + module_t disk_used_perc_module = {"perc", {}, [](const callbackInfo_t *callback) {return get_and_color_percentage(disk_used(callback), disk_total(callback), callback, false);}}; + module_t disk_free_module = {"free", {std::move(disk_free_perc_module)}, [](const callbackInfo_t *callback) { return amount(disk_free(callback), callback->moduleArgs); }}; + module_t disk_used_module = {"used", {std::move(disk_used_perc_module)}, [](const callbackInfo_t *callback) { return amount(disk_used(callback), callback->moduleArgs); }}; module_t disk_total_module = {"total", {}, [](const callbackInfo_t *callback) { return amount(disk_total(callback), callback->moduleArgs); }}; module_t disk_module = {"disk", { @@ -347,6 +358,8 @@ void core_plugins_start() std::move(disk_device_module), std::move(disk_mountdir_module), std::move(disk_types_module), + std::move(disk_free_perc_module), + std::move(disk_used_perc_module), std::move(disk_free_module), std::move(disk_used_module), std::move(disk_total_module), @@ -420,20 +433,8 @@ void core_plugins_start() cfRegisterModule(title_module); // $<colors> - module_t colors_light_symbol_module = { - "symbol", - {}, - [](const callbackInfo_t* callback) { - return get_colors_symbol(callback, true); - } - }; - module_t colors_symbol_module = { - "symbol", - {}, - [](const callbackInfo_t* callback) { - return get_colors_symbol(callback, false); - } - }; + module_t colors_light_symbol_module = { "symbol", {}, [](const callbackInfo_t* callback) { return get_colors_symbol(callback, true); } }; + module_t colors_symbol_module = { "symbol", {}, [](const callbackInfo_t* callback) { return get_colors_symbol(callback, false); }}; module_t colors_light_module = { "light", { std::move(colors_light_symbol_module) }, [](const callbackInfo_t* callback) { return parse( "${\033[100m} ${\033[101m} ${\033[102m} ${\033[103m} ${\033[104m} " From 51742e75a0d2dba5995c67672f707a119c5e3f8c Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Sat, 28 Jun 2025 14:27:51 +0200 Subject: [PATCH 050/143] makefile: force link with fmt static library --- Makefile | 16 ++++++++-------- libcufetch/Makefile | 7 +++++-- src/libs/fmt/Makefile | 3 +-- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/Makefile b/Makefile index d972575e..de00bb5c 100644 --- a/Makefile +++ b/Makefile @@ -62,20 +62,20 @@ OBJ_CPP = $(SRC_CPP:.cpp=.o) OBJ_CC = $(SRC_CC:.cc=.o) OBJ = $(OBJ_CPP) $(OBJ_CC) HEADERS = config.hpp common.hpp core-modules.hh cufetch.hh -LDFLAGS += -L./$(BUILDDIR) -lcufetch -lfmt -ldl +LDFLAGS += -Wl,-Bstatic $(BUILDDIR)/libfmt.a -Wl,-Bdynamic -lcufetch -ldl CXXFLAGS ?= -mtune=generic -march=native CXXFLAGS += -fvisibility-inlines-hidden -fvisibility=hidden -Iinclude -std=c++20 $(VARS) -DVERSION=\"$(VERSION)\" -DLOCALEDIR=\"$(LOCALEDIR)\" -DICONPREFIX=\"$(ICONPREFIX)\" -all: genver libcufetch fmt toml json $(TARGET) +all: genver fmt toml json libcufetch $(TARGET) libcufetch: ifeq ($(wildcard $(BUILDDIR)/libcufetch.so),) - mkdir -p $(BUILDDIR) make -C libcufetch BUILDDIR=$(BUILDDIR) endif fmt: ifeq ($(wildcard $(BUILDDIR)/libfmt.a),) + mkdir -p $(BUILDDIR) make -C src/libs/fmt BUILDDIR=$(BUILDDIR) endif @@ -94,10 +94,10 @@ ifeq ($(wildcard include/version.h),) ./scripts/generateVersion.sh endif -$(TARGET): genver fmt toml libcufetch json $(OBJ) +$(TARGET): genver fmt toml json libcufetch $(OBJ) mkdir -p $(BUILDDIR) sh ./scripts/generateVersion.sh - $(CXX) $(OBJ) $(BUILDDIR)/*.o -o $(BUILDDIR)/$(TARGET) $(LDFLAGS) + $(CXX) -o $(BUILDDIR)/$(TARGET) $(OBJ) $(BUILDDIR)/*.o $(LDFLAGS) cd $(BUILDDIR)/ && ln -sf $(TARGET) cufetch locale: @@ -121,9 +121,9 @@ clean: distclean: rm -rf $(BUILDDIR) ./tests/$(BUILDDIR) $(OBJ) - find . -type f -name "*.tar.gz" -exec rm -rf "{}" \; - find . -type f -name "*.o" -exec rm -rf "{}" \; - find . -type f -name "*.a" -exec rm -rf "{}" \; + find . -type f -name "*.tar.gz" -delete + find . -type f -name "*.o" -delete + find . -type f -name "*.a" -delete install: install-common $(TARGET) install $(BUILDDIR)/$(TARGET) -Dm 755 -v $(DESTDIR)$(PREFIX)/bin/$(TARGET) diff --git a/libcufetch/Makefile b/libcufetch/Makefile index 4776b89f..8ad826ec 100644 --- a/libcufetch/Makefile +++ b/libcufetch/Makefile @@ -3,14 +3,17 @@ CXX_INCLUDES = -I../include CXX_FLAGS = -shared -fPIC SRC = $(wildcard *.cc) OBJ = $(SRC:.cc=.o) +FMT_STATIC = ../$(BUILDDIR)/libfmt.a all: libcufetch %.o: %.cc $(CXX) $(CXX_INCLUDES) $(CXX_FLAGS) -c -o $@ $< -libcufetch: $(OBJ) - $(CXX) $(OBJ) $(CXX_INCLUDES) $(CXX_FLAGS) -o libcufetch.so -L../$(BUILDDIR)/ -lfmt +libcufetch: $(OBJ) $(FMT_STATIC) + $(CXX) $(CXX_FLAGS) $(OBJ) $(CXX_INCLUDES) \ + -Wl,-Bstatic $(FMT_STATIC) -Wl,-Bdynamic \ + -o libcufetch.so mv -f libcufetch.so ../$(BUILDDIR)/$@.so clean: diff --git a/src/libs/fmt/Makefile b/src/libs/fmt/Makefile index c9198c0f..10ae7418 100644 --- a/src/libs/fmt/Makefile +++ b/src/libs/fmt/Makefile @@ -5,7 +5,7 @@ CXX ?= g++ # CXX_DEFINES = -DFMT_LIB_EXPORT -Dfmt_EXPORTS CXX_INCLUDES = -I../../../include -CXX_FLAGS = -O3 -DNDEBUG -fvisibility=hidden -fvisibility-inlines-hidden +CXX_FLAGS = -O3 -DNDEBUG -fvisibility=hidden -fvisibility-inlines-hidden -fPIC all: fmt @@ -15,7 +15,6 @@ fmt: format.cc os.cc ar qc libfmt.a os.cc.o format.cc.o ranlib libfmt.a mv -f libfmt.a ../../../$(BUILDDIR)/libfmt.a - # $(CXX) -fPIC -O3 -DNDEBUG -shared -Wl,-soname,libfmt.so.10 -o libfmt.so format.cc.o os.cc.o clean: rm -f *.o *.so *.a ../../../$(BUILDDIR)/fmt/.*a From 55bef821c9e6d75545d95df412b49cd392bb7f69 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Sat, 28 Jun 2025 16:55:33 +0200 Subject: [PATCH 051/143] plugins: add description in module_t --- include/common.hpp | 16 +- include/util.hpp | 9 + libcufetch/cufetch.cc | 9 +- src/core-plugins/linux/linux-core-modules.cc | 276 ++++++++++--------- 4 files changed, 157 insertions(+), 153 deletions(-) diff --git a/include/common.hpp b/include/common.hpp index 3c6b0abd..2bfc12de 100644 --- a/include/common.hpp +++ b/include/common.hpp @@ -1,23 +1,12 @@ #pragma once -#include <fmt/color.h> -#include <fmt/core.h> +#include "fmt/color.h" +#include "fmt/core.h" #include <functional> #include <string> #include <vector> -#include "platform.hpp" - -#if ENABLE_NLS && !CF_MACOS -/* here so it doesn't need to be included elsewhere */ -#include <libintl.h> -#include <locale.h> -#define _(str) gettext(str) -#else -#define _(s) (char*)s -#endif - constexpr const char NOCOLOR[] = "\033[0m"; constexpr const char NOCOLOR_BOLD[] = "\033[0m\033[1m"; constexpr const char UNKNOWN[] = "(unknown)"; @@ -109,6 +98,7 @@ struct callbackInfo_t; struct module_t { std::string name; + std::string description; std::vector<module_t> submodules; /* For best performance, use std::move() when adding modules in here. */ std::function<const std::string(const callbackInfo_t*)> handler; }; diff --git a/include/util.hpp b/include/util.hpp index aa7c2a6e..29ad8217 100644 --- a/include/util.hpp +++ b/include/util.hpp @@ -55,6 +55,15 @@ struct byte_units_t double num_bytes; }; +#if ENABLE_NLS && !CF_MACOS +/* here so it doesn't need to be included elsewhere */ +#include <libintl.h> +#include <locale.h> +#define _(str) gettext(str) +#else +#define _(s) (char*)s +#endif + /* lib = library to load (string) */ #define LOAD_LIBRARY(lib) dlopen(lib, RTLD_LAZY); diff --git a/libcufetch/cufetch.cc b/libcufetch/cufetch.cc index 92d68683..0917699e 100644 --- a/libcufetch/cufetch.cc +++ b/libcufetch/cufetch.cc @@ -4,12 +4,13 @@ static std::vector<module_t> modules; static char separator = '.'; -static void addModule(const module_t& module, const std::string& prefix = "") +static void addModule(module_t module, const std::string& prefix = "") { - modules.emplace_back(module).name = prefix + module.name; + module.name = prefix + module.name; + modules.push_back(module); // No std::move since we modify name first - for (const module_t& submodule : module.submodules) - addModule(submodule, prefix + module.name + separator); + for (module_t submodule : module.submodules) // Copy submodule to avoid reference issues + addModule(std::move(submodule), prefix + module.name + separator); } /* Register a module, and its submodules, to customfetch. */ diff --git a/src/core-plugins/linux/linux-core-modules.cc b/src/core-plugins/linux/linux-core-modules.cc index 9f558ed0..0c70d23e 100644 --- a/src/core-plugins/linux/linux-core-modules.cc +++ b/src/core-plugins/linux/linux-core-modules.cc @@ -110,18 +110,18 @@ void core_plugins_start() mountsFile = setmntent("/proc/mounts", "r"); // ------------ MODULES REGISTERING ------------ - module_t os_name_pretty_module = {"pretty", {}, os_pretty_name}; - module_t os_name_id_module = {"id", {}, os_name_id}; - module_t os_name_module = { "name", { + module_t os_name_pretty_module = {"pretty", "OS pretty name [Ubuntu 22.04.4 LTS; Arch Linux]", {}, os_pretty_name}; + module_t os_name_id_module = {"id", "OS id name [ubuntu, arch]", {}, os_name_id}; + module_t os_name_module = { "name", "OS basic name [Ubuntu]", { std::move(os_name_pretty_module), std::move(os_name_id_module) }, os_name }; - module_t os_uptime_s_module = {"secs", {}, [=](unused) {return fmt::to_string(uptime_secs.count() % 60);}}; - module_t os_uptime_m_module = {"mins", {}, [=](unused) {return fmt::to_string(uptime_mins.count() % 60);}}; - module_t os_uptime_h_module = {"hours", {}, [=](unused) {return fmt::to_string(uptime_hours.count() % 24);}}; - module_t os_uptime_d_module = {"days", {}, [=](unused) {return fmt::to_string(uptime_days);}}; - module_t os_uptime_module = {"uptime", { + module_t os_uptime_s_module = {"secs", "uptime of the system in seconds [45]", {}, [=](unused) {return fmt::to_string(uptime_secs.count() % 60);}}; + module_t os_uptime_m_module = {"mins", "uptime of the system in minutes [12]", {}, [=](unused) {return fmt::to_string(uptime_mins.count() % 60);}}; + module_t os_uptime_h_module = {"hours", "uptime of the system in hours [34]", {}, [=](unused) {return fmt::to_string(uptime_hours.count() % 24);}}; + module_t os_uptime_d_module = {"days", "uptime of the system in days [2]", {}, [=](unused) {return fmt::to_string(uptime_days);}}; + module_t os_uptime_module = {"uptime", "(auto) uptime of the system [36 mins, 3 hours, 23 days]", { std::move(os_uptime_s_module), std::move(os_uptime_m_module), std::move(os_uptime_h_module), @@ -129,32 +129,32 @@ void core_plugins_start() }, [=](const callbackInfo_t* callback) { return get_auto_uptime(uptime_days, uptime_hours.count() % 24, uptime_mins.count() % 60, uptime_secs.count() % 60, callback->config); }}; - module_t os_hostname_module = {"hostname", {}, os_hostname}; + module_t os_hostname_module = {"hostname", "hostname of the OS [myMainPC]", {}, os_hostname}; - module_t os_kernel_name_module = {"name", {}, os_kernel_name}; - module_t os_kernel_version_module = {"version", {}, os_kernel_version}; - module_t os_kernel_module = {"kernel", { + module_t os_kernel_name_module = {"name", "kernel name [Linux]", {}, os_kernel_name}; + module_t os_kernel_version_module = {"version", "kernel version [6.9.3-zen1-1-zen]", {}, os_kernel_version}; + module_t os_kernel_module = {"kernel", "kernel name and version [Linux 6.9.3-zen1-1-zen]", { std::move(os_kernel_name_module), std::move(os_kernel_version_module) }, [](unused) {return os_kernel_name() + " " + os_kernel_version();}}; - module_t os_initsys_name_module = {"name", {}, os_initsys_name}; - module_t os_initsys_version_module = {"version", {}, os_initsys_version}; - module_t os_initsys_module = {"initsys", { + module_t os_initsys_name_module = {"name", "Init system name [systemd]", {}, os_initsys_name}; + module_t os_initsys_version_module = {"version", "Init system version [256.5-1-arch]", {}, os_initsys_version}; + module_t os_initsys_module = {"initsys", "Init system name and version [systemd 256.5-1-arch]", { std::move(os_initsys_name_module), std::move(os_initsys_version_module), }, [](unused) {return os_initsys_name() + " " + os_initsys_version();}}; /* Only for compatibility */ - module_t os_pretty_name_module_compat = { "pretty_name", {}, os_pretty_name }; - module_t os_name_id_module_compat = { "name_id", {}, os_name_id }; - module_t os_kernel_name_module_compat = {"kernel_name", {}, os_kernel_name}; - module_t os_kernel_version_module_compat = {"kernel_version", {}, os_kernel_version}; - module_t os_initsys_name_module_compat = {"initsys_name", {}, os_initsys_name}; - module_t os_initsys_version_module_compat = {"initsys_version", {}, os_initsys_version}; + module_t os_pretty_name_module_compat = { "pretty_name", "OS name (pretty name) [Ubuntu 22.04.4 LTS; Arch Linux]", {}, os_pretty_name }; + module_t os_name_id_module_compat = { "name_id", "OS name id [ubuntu, arch]", {}, os_name_id }; + module_t os_kernel_name_module_compat = {"kernel_name", "kernel name [Linux]", {}, os_kernel_name}; + module_t os_kernel_version_module_compat = {"kernel_version", "kernel version [6.9.3-zen1-1-zen]", {}, os_kernel_version}; + module_t os_initsys_name_module_compat = {"initsys_name", "Init system name [systemd]", {}, os_initsys_name}; + module_t os_initsys_version_module_compat = {"initsys_version", "Init system version [256.5-1-arch]", {}, os_initsys_version}; // $<os> - module_t os_module = { "os", { + module_t os_module = { "os", "OS modules", { std::move(os_name_module), std::move(os_uptime_module), std::move(os_kernel_module), @@ -168,65 +168,67 @@ void core_plugins_start() std::move(os_initsys_name_module_compat), std::move(os_initsys_version_module_compat), }, NULL}; - - //fclose(os_release); cfRegisterModule(os_module); // $<system> - module_t host_name_module = {"name", {}, host_name}; - module_t host_version_module = {"version", {}, host_version}; - module_t host_vendor_module = {"vendor", {}, host_vendor}; - module_t host_module = {"host", { std::move(host_name_module), std::move(host_version_module), std::move(host_vendor_module) }, host}; - + module_t host_name_module = {"name", "Host (aka. Motherboard) model name [PRO B550M-P GEN3 (MS-7D95)]", {}, host_name}; + module_t host_version_module = {"version", "Host (aka. Motherboard) model version [1.0]", {}, host_version}; + module_t host_vendor_module = {"vendor", "Host (aka. Motherboard) model vendor [Micro-Star International Co., Ltd.]", {}, host_vendor}; + module_t host_module = {"host", "Host (aka. Motherboard) model name with vendor and version [Micro-Star International Co., Ltd. PRO B550M-P GEN3 (MS-7D95) 1.0]", { + std::move(host_name_module), + std::move(host_version_module), + std::move(host_vendor_module) }, + host}; + + module_t arch_module = {"arch", "the architecture of the machine [x86_64, aarch64]", {}, arch}; /* Only for compatibility */ - module_t host_name_module_compat = { "host_name", {}, host_name }; - module_t host_version_module_compat = {"host_version", {}, host_version}; - module_t host_vendor_module_compat = {"host_vendor", {}, host_vendor}; + module_t host_name_module_compat = { "host_name", "Host (aka. Motherboard) model name [PRO B550M-P GEN3 (MS-7D95)]", {}, host_name }; + module_t host_version_module_compat = {"host_version", "Host (aka. Motherboard) model version [1.0]", {}, host_version}; + module_t host_vendor_module_compat = {"host_vendor", "Host (aka. Motherboard) model vendor [Micro-Star International Co., Ltd.]", {}, host_vendor}; - module_t arch_module = {"arch", {}, arch}; - - module_t system_module = { "system", { + module_t system_module = { "system", "System modules", { std::move(host_module), - std::move(host_name_module_compat), std::move(host_version_module_compat), std::move(host_vendor_module_compat), + std::move(host_name_module_compat), + std::move(host_version_module_compat), + std::move(host_vendor_module_compat), std::move(arch_module), }, NULL }; - cfRegisterModule(system_module); // $<cpu> - module_t cpu_name_module = {"name", {}, cpu_name}; - module_t cpu_nproc_module = {"nproc" , {}, cpu_nproc}; - - module_t cpu_freq_cur_module = {"current", {}, cpu_freq_cur}; - module_t cpu_freq_max_module = {"max", {}, cpu_freq_max}; - module_t cpu_freq_min_module = {"min", {}, cpu_freq_min}; - module_t cpu_freq_bios_module = {"bios_limit", {}, cpu_freq_bios}; - module_t cpu_freq_module = {"freq", { + module_t cpu_name_module = {"name", "CPU model name [AMD Ryzen 5 5500]", {}, cpu_name}; + module_t cpu_nproc_module = {"nproc" , "CPU number of virtual processors [12]", {}, cpu_nproc}; + + module_t cpu_freq_cur_module = {"current", "CPU current frequency (in GHz) [3.42]", {}, cpu_freq_cur}; + module_t cpu_freq_max_module = {"max", "CPU maximum frequency (in GHz) [4.90]", {}, cpu_freq_max}; + module_t cpu_freq_min_module = {"min", "CPU minimum frequency (in GHz) [2.45]", {}, cpu_freq_min}; + module_t cpu_freq_bios_module = {"bios_limit", "CPU frequency limited by bios (in GHz) [4.32]", {}, cpu_freq_bios}; + module_t cpu_freq_module = {"freq", "CPU frequency info (GHz)", { std::move(cpu_freq_cur_module), std::move(cpu_freq_max_module), std::move(cpu_freq_min_module), std::move(cpu_freq_bios_module), }, cpu_freq_max}; - module_t cpu_temp_C_module = {"C", {}, [](unused) {return fmt::format("{:.2f}°C", cpu_temp());}}; - module_t cpu_temp_F_module = {"F", {}, [](unused) {return fmt::format("{:.2f}°F", cpu_temp() * 1.8 + 34);}}; - module_t cpu_temp_K_module = {"K", {}, [](unused) {return fmt::format("{:.2f}°K", cpu_temp() + 273.15);}}; - module_t cpu_temp_module = {"temp", { + module_t cpu_temp_C_module = {"C", "CPU temperature in Celsius [40.62]", {}, [](unused) {return fmt::format("{:.2f}°C", cpu_temp());}}; + module_t cpu_temp_F_module = {"F", "CPU temperature in Fahrenheit [105.12]", {}, [](unused) {return fmt::format("{:.2f}°F", cpu_temp() * 1.8 + 34);}}; + module_t cpu_temp_K_module = {"K", "CPU temperature in Kelvin [313.77]", {}, [](unused) {return fmt::format("{:.2f}°K", cpu_temp() + 273.15);}}; + module_t cpu_temp_module = {"temp", "CPU temperature (by the chosen unit) [40.62]", { std::move(cpu_temp_C_module), std::move(cpu_temp_F_module), std::move(cpu_temp_K_module), }, [](unused) {return fmt::format("{:.2f}°C", cpu_temp());}}; /* Only for compatibility */ - module_t cpu_freq_cur_module_compat = {"freq_cur", {}, cpu_freq_cur}; - module_t cpu_freq_max_module_compat = {"freq_max", {}, cpu_freq_max}; - module_t cpu_freq_min_module_compat = {"freq_min", {}, cpu_freq_min}; - module_t cpu_freq_bios_module_compat = {"freq_bios_limit", {}, cpu_freq_bios}; - module_t cpu_temp_C_module_compat = {"temp_C", {}, [](unused) {return fmt::format("{:.2f}", cpu_temp());}}; - module_t cpu_temp_F_module_compat = {"temp_F", {}, [](unused) {return fmt::format("{:.2f}", cpu_temp() * 1.8 + 34);}}; - module_t cpu_temp_K_module_compat = {"temp_K", {}, [](unused) {return fmt::format("{:.2f}", cpu_temp() + 273.15);}}; - - module_t cpu_module = {"cpu", { + module_t cpu_freq_cur_module_compat = {"freq_cur", "CPU current frequency (in GHz) [3.42]", {}, cpu_freq_cur}; + module_t cpu_freq_max_module_compat = {"freq_max", "CPU maximum frequency (in GHz) [4.90]", {}, cpu_freq_max}; + module_t cpu_freq_min_module_compat = {"freq_min", "CPU minimum frequency (in GHz) [2.45]", {}, cpu_freq_min}; + module_t cpu_freq_bios_module_compat = {"freq_bios_limit", "CPU frequency limited by bios (in GHz) [4.32]", {}, cpu_freq_bios}; + module_t cpu_temp_C_module_compat = {"temp_C", "CPU temperature in Celsius [40.62]", {}, [](unused) {return fmt::format("{:.2f}", cpu_temp());}}; + module_t cpu_temp_F_module_compat = {"temp_F", "CPU temperature in Fahrenheit [105.12]", {}, [](unused) {return fmt::format("{:.2f}", cpu_temp() * 1.8 + 34);}}; + module_t cpu_temp_K_module_compat = {"temp_K", "CPU temperature in Kelvin [313.77]", {}, [](unused) {return fmt::format("{:.2f}", cpu_temp() + 273.15);}}; + + module_t cpu_module = {"cpu", "CPU model name with number of virtual processors and max freq [AMD Ryzen 5 5500 (12) @ 4.90 GHz]",{ std::move(cpu_name_module), std::move(cpu_nproc_module), std::move(cpu_freq_module), @@ -242,54 +244,53 @@ void core_plugins_start() }, [](unused) { return fmt::format("{} ({}) @ {} GHz", cpu_name(), cpu_nproc(), cpu_freq_max()); }}; - cfRegisterModule(cpu_module); // $<user> - module_t user_name_module = {"name", {}, user_name}; + module_t user_name_module = {"name", "name you are currently logged in (not real name) [toni69]", {}, user_name}; - module_t user_shell_path_module = {"path", {}, user_shell_path}; - module_t user_shell_name_module = {"name", {}, user_shell_name}; - module_t user_shell_version_module = {"version", {}, user_shell_version}; - module_t user_shell_module = {"shell", { + module_t user_shell_path_module = {"path", "login shell (with path) [/bin/zsh]", {}, user_shell_path}; + module_t user_shell_name_module = {"name", "login shell [zsh]", {}, user_shell_name}; + module_t user_shell_version_module = {"version", "login shell version (may be not correct) [5.9]", {}, user_shell_version}; + module_t user_shell_module = {"shell", "login shell name and version [zsh 5.9]", { std::move(user_shell_name_module), std::move(user_shell_path_module), std::move(user_shell_version_module), }, [](unused) {return user_shell_name() + " " + user_shell_version();}}; - module_t user_term_name_module = {"name", {}, user_term_name}; - module_t user_term_version_module = {"version", {}, user_shell_version}; - module_t user_term_module = {"terminal", { + module_t user_term_name_module = {"name", "terminal name [alacritty]", {}, user_term_name}; + module_t user_term_version_module = {"version", "terminal version [0.13.2]", {}, user_shell_version}; + module_t user_term_module = {"terminal", "terminal name and version [alacritty 0.13.2]", { std::move(user_term_version_module), std::move(user_term_name_module) }, [](unused) {return user_term_name() + " " + user_term_version();}}; - module_t user_wm_name_module = {"name", {}, user_wm_name}; - module_t user_wm_version_module = {"version", {}, user_wm_version}; - module_t user_wm_module = {"wm", { + module_t user_wm_name_module = {"name", "Window Manager current session name [dwm; xfwm4]", {}, user_wm_name}; + module_t user_wm_version_module = {"version", "Window Manager version (may not work correctly) [6.2; 4.18.0]", {}, user_wm_version}; + module_t user_wm_module = {"wm", "Window Manager current session name and version", { std::move(user_wm_version_module), std::move(user_wm_name_module) }, [](unused) {return user_wm_name() + " " + user_wm_version();}}; - module_t user_de_name_module = {"name", {}, user_de_name}; - module_t user_de_version_module = {"version", {}, user_de_version}; - module_t user_de_module = {"de", { + module_t user_de_name_module = {"name", "Desktop Environment current session name [Plasma]", {}, user_de_name}; + module_t user_de_version_module = {"version", "Desktop Environment version (if available)", {}, user_de_version}; + module_t user_de_module = {"de", "Desktop Environment current session name and version", { std::move(user_de_version_module), std::move(user_de_name_module) }, [](unused) {return user_de_name() + " " + user_de_version();}}; /* Only for compatibility */ - module_t user_shell_path_module_compat = {"shell_path", {}, user_shell_path}; - module_t user_shell_name_module_compat = {"shell_name", {}, user_shell_name}; - module_t user_shell_version_module_compat = {"shell_version", {}, user_shell_version}; - module_t user_term_name_module_compat = {"terminal_name", {}, user_term_name}; - module_t user_term_version_module_compat = {"terminal_version", {}, user_shell_version}; - module_t user_wm_name_module_compat = {"wm_name", {}, user_wm_name}; - module_t user_wm_version_module_compat = {"wm_version", {}, user_wm_version}; - module_t user_de_name_module_compat = {"de_name", {}, user_de_name}; - module_t user_de_version_module_compat = {"de_version", {}, user_de_version}; - - module_t user_module = {"user", { + module_t user_shell_path_module_compat = {"shell_path", "login shell (with path) [/bin/zsh]", {}, user_shell_path}; + module_t user_shell_name_module_compat = {"shell_name", "login shell [zsh]", {}, user_shell_name}; + module_t user_shell_version_module_compat = {"shell_version", "login shell version (may be not correct) [5.9]", {}, user_shell_version}; + module_t user_term_name_module_compat = {"terminal_name", "terminal name [alacritty]", {}, user_term_name}; + module_t user_term_version_module_compat = {"terminal_version", "terminal version [0.13.2]", {}, user_shell_version}; + module_t user_wm_name_module_compat = {"wm_name", "Window Manager current session name [dwm; xfwm4]", {}, user_wm_name}; + module_t user_wm_version_module_compat = {"wm_version", "Window Manager version (may not work correctly) [6.2; 4.18.0]", {}, user_wm_version}; + module_t user_de_name_module_compat = {"de_name", "Desktop Environment current session name [Plasma]", {}, user_de_name}; + module_t user_de_version_module_compat = {"de_version", "Desktop Environment version (if available)", {}, user_de_version}; + + module_t user_module = {"user", "User modules", { std::move(user_name_module), std::move(user_shell_module), std::move(user_term_module), @@ -306,17 +307,16 @@ void core_plugins_start() std::move(user_de_name_module_compat), std::move(user_de_version_module_compat), }, NULL}; - cfRegisterModule(user_module); // $<ram> - module_t ram_free_perc_module = {"perc", {}, [](const callbackInfo_t *callback) {return get_and_color_percentage(ram_free(), ram_total(), callback, true);}}; - module_t ram_used_perc_module = {"perc", {}, [](const callbackInfo_t *callback) {return get_and_color_percentage(ram_used(), ram_total(), callback, false);}}; - module_t ram_free_module = {"free", {std::move(ram_free_perc_module)}, [](const callbackInfo_t *callback) { return amount(ram_free() * 1024, callback->moduleArgs); }}; - module_t ram_used_module = {"used", {std::move(ram_used_perc_module)}, [](const callbackInfo_t *callback) { return amount(ram_used() * 1024, callback->moduleArgs); }}; - module_t ram_total_module = {"total", {}, [](const callbackInfo_t *callback) { return amount(ram_total() * 1024, callback->moduleArgs); }}; - - module_t ram_module = {"ram", { + module_t ram_free_perc_module = {"perc", "percentage of available amount of RAM in total [82.31%]", {}, [](const callbackInfo_t *callback) {return get_and_color_percentage(ram_free(), ram_total(), callback, true);}}; + module_t ram_used_perc_module = {"perc", "percentage of used amount of RAM in total [17.69%]", {}, [](const callbackInfo_t *callback) {return get_and_color_percentage(ram_used(), ram_total(), callback, false);}}; + module_t ram_free_module = {"free", "available amount of RAM (auto) [10.46 GiB]", {std::move(ram_free_perc_module)}, [](const callbackInfo_t *callback) { return amount(ram_free() * 1024, callback->moduleArgs); }}; + module_t ram_used_module = {"used", "used amount of RAM (auto) [2.81 GiB]", {std::move(ram_used_perc_module)}, [](const callbackInfo_t *callback) { return amount(ram_used() * 1024, callback->moduleArgs); }}; + module_t ram_total_module = {"total", "total amount of RAM (auto) [15.88 GiB]", {}, [](const callbackInfo_t *callback) { return amount(ram_total() * 1024, callback->moduleArgs); }}; + + module_t ram_module = {"ram", "used and total amount of RAM (auto) with used percentage [2.81 GiB / 15.88 GiB (5.34%)]", { std::move(ram_free_module), std::move(ram_used_module), std::move(ram_free_perc_module), @@ -326,13 +326,13 @@ void core_plugins_start() cfRegisterModule(ram_module); // $<swap> - module_t swap_free_perc_module = {"perc", {}, [](const callbackInfo_t *callback) {return get_and_color_percentage(swap_free(), swap_total(), callback, true);}}; - module_t swap_used_perc_module = {"perc", {}, [](const callbackInfo_t *callback) {return get_and_color_percentage(swap_used(), swap_total(), callback, false);}}; - module_t swap_free_module = {"free", {std::move(swap_free_perc_module)}, [](const callbackInfo_t *callback) { return amount(swap_free() * 1024, callback->moduleArgs); }}; - module_t swap_used_module = {"used", {std::move(swap_used_perc_module)}, [](const callbackInfo_t *callback) { return amount(swap_used() * 1024, callback->moduleArgs); }}; - module_t swap_total_module = {"total", {}, [](const callbackInfo_t *callback) { return amount(swap_total() * 1024, callback->moduleArgs); }}; + module_t swap_free_perc_module = {"perc", "percentage of available amount of the swapfile in total [6.71%]", {}, [](const callbackInfo_t *callback) {return get_and_color_percentage(swap_free(), swap_total(), callback, true);}}; + module_t swap_used_perc_module = {"perc", "percentage of used amount of the swapfile in total [93.29%]", {}, [](const callbackInfo_t *callback) {return get_and_color_percentage(swap_used(), swap_total(), callback, false);}}; + module_t swap_free_module = {"free", "available amount of the swapfile (auto) [34.32 MiB]", {std::move(swap_free_perc_module)}, [](const callbackInfo_t *callback) { return amount(swap_free() * 1024, callback->moduleArgs); }}; + module_t swap_used_module = {"used", "used amount of the swapfile (auto) [477.68 MiB]", {std::move(swap_used_perc_module)}, [](const callbackInfo_t *callback) { return amount(swap_used() * 1024, callback->moduleArgs); }}; + module_t swap_total_module = {"total", "total amount of the swapfile (auto) [512.00 MiB]", {}, [](const callbackInfo_t *callback) { return amount(swap_total() * 1024, callback->moduleArgs); }}; - module_t swap_module = {"swap", { + module_t swap_module = {"swap", "used and total amount of the swapfile (auto) with used percentage [477.68 MiB / 512.00 MiB (88.45%)]", { std::move(swap_free_module), std::move(swap_used_module), std::move(swap_free_perc_module), @@ -342,18 +342,18 @@ void core_plugins_start() cfRegisterModule(swap_module); // $<disk> - module_t disk_fsname_module = {"fs", {}, disk_fsname}; - module_t disk_device_module = {"device", {}, disk_device}; - module_t disk_mountdir_module = {"mountdir", {}, disk_mountdir}; - module_t disk_types_module = {"types", {}, disk_types}; - - module_t disk_free_perc_module = {"perc", {}, [](const callbackInfo_t *callback) {return get_and_color_percentage(disk_free(callback), disk_total(callback), callback, true);}}; - module_t disk_used_perc_module = {"perc", {}, [](const callbackInfo_t *callback) {return get_and_color_percentage(disk_used(callback), disk_total(callback), callback, false);}}; - module_t disk_free_module = {"free", {std::move(disk_free_perc_module)}, [](const callbackInfo_t *callback) { return amount(disk_free(callback), callback->moduleArgs); }}; - module_t disk_used_module = {"used", {std::move(disk_used_perc_module)}, [](const callbackInfo_t *callback) { return amount(disk_used(callback), callback->moduleArgs); }}; - module_t disk_total_module = {"total", {}, [](const callbackInfo_t *callback) { return amount(disk_total(callback), callback->moduleArgs); }}; - - module_t disk_module = {"disk", { + module_t disk_fsname_module = {"fs", "type of filesystem [ext4]", {}, disk_fsname}; + module_t disk_device_module = {"device", "path to device [/dev/sda5]", {}, disk_device}; + module_t disk_mountdir_module = {"mountdir", "path to the device mount point [/]", {}, disk_mountdir}; + module_t disk_types_module = {"types", "an array of type options (pretty format) [Regular, External]", {}, disk_types}; + + module_t disk_free_perc_module = {"perc", "percentage of available amount of the disk in total [17.82%]", {}, [](const callbackInfo_t *callback) {return get_and_color_percentage(disk_free(callback), disk_total(callback), callback, true);}}; + module_t disk_used_perc_module = {"perc", "percentage of used amount of the disk in total [82.18%]", {}, [](const callbackInfo_t *callback) {return get_and_color_percentage(disk_used(callback), disk_total(callback), callback, false);}}; + module_t disk_free_module = {"free", "available amount of disk space (auto) [438.08 GiB]", {std::move(disk_free_perc_module)}, [](const callbackInfo_t *callback) { return amount(disk_free(callback), callback->moduleArgs); }}; + module_t disk_used_module = {"used", "used amount of disk space (auto) [360.02 GiB]", {std::move(disk_used_perc_module)}, [](const callbackInfo_t *callback) { return amount(disk_used(callback), callback->moduleArgs); }}; + module_t disk_total_module = {"total", "total amount of disk space (auto) [100.08 GiB]", {}, [](const callbackInfo_t *callback) { return amount(disk_total(callback), callback->moduleArgs); }}; + + module_t disk_module = {"disk", "used and total amount of disk space (auto) with type of filesystem and used percentage [379.83 GiB / 438.08 GiB (86.70%) - ext4]", { std::move(disk_fsname_module), std::move(disk_device_module), std::move(disk_mountdir_module), @@ -367,28 +367,29 @@ void core_plugins_start() cfRegisterModule(disk_module); // $<battery> - module_t battery_modelname_module = {"name", {}, battery_modelname}; - module_t battery_status_module = {"status", {}, battery_status}; - module_t battery_capacity_level_module = {"capacity_level", {}, battery_capacity_level}; - module_t battery_technology_module = {"technology", {}, battery_technology}; - module_t battery_vendor_module = {"manufacturer", {}, battery_vendor}; - module_t battery_perc_module = {"perc", {}, battery_perc}; - - module_t battery_temp_C_module = {"C", {}, [](unused) {return fmt::format("{:.2f}°C", battery_temp());}}; - module_t battery_temp_F_module = {"F", {}, [](unused) {return fmt::format("{:.2f}°F", battery_temp() * 1.8 + 34);}}; - module_t battery_temp_K_module = {"K", {}, [](unused) {return fmt::format("{:.2f}°K", battery_temp() + 273.15);}}; - module_t battery_temp_module = {"temp", { + module_t battery_modelname_module = {"name", "battery model name", {}, battery_modelname}; + module_t battery_status_module = {"status", "battery current status [Discharging, AC Connected]", {}, battery_status}; + module_t battery_capacity_level_module = {"capacity_level", "battery capacity level [Normal, Critical]", {}, battery_capacity_level}; + module_t battery_technology_module = {"technology", "battery technology [Li-lion]", {}, battery_technology}; + module_t battery_vendor_module = {"manufacturer", "battery manufacturer name", {}, battery_vendor}; + module_t battery_perc_module = {"perc", "battery current percentage", {}, battery_perc}; + + module_t battery_temp_C_module = {"C", "battery temperature in Celsius [e.g. 37.12°C]", {}, [](unused) {return fmt::format("{:.2f}°C", battery_temp());}}; + module_t battery_temp_F_module = {"F", "battery temperature in Fahrenheit [e.g. 98.81°F]", {}, [](unused) {return fmt::format("{:.2f}°F", battery_temp() * 1.8 + 34);}}; + module_t battery_temp_K_module = {"K", "battery temperature in Kelvin [e.g. 310.27°K]", {}, [](unused) {return fmt::format("{:.2f}°K", battery_temp() + 273.15);}}; + + module_t battery_temp_module = {"temp", "battery temperature (by the chosen unit)", { std::move(battery_temp_C_module), std::move(battery_temp_F_module), std::move(battery_temp_K_module), }, [](unused) {return fmt::format("{:.2f}°C", battery_temp());}}; /* Only for compatibility */ - module_t battery_temp_C_module_compat = {"temp_C", {}, [](unused) {return fmt::format("{:.2f}", battery_temp());}}; - module_t battery_temp_F_module_compat = {"temp_F", {}, [](unused) {return fmt::format("{:.2f}", battery_temp() * 1.8 + 34);}}; - module_t battery_temp_K_module_compat = {"temp_K", {}, [](unused) {return fmt::format("{:.2f}", battery_temp() + 273.15);}}; + module_t battery_temp_C_module_compat = {"temp_C", "battery temperature in Celsius (no unit)", {}, [](unused) {return fmt::format("{:.2f}", battery_temp());}}; + module_t battery_temp_F_module_compat = {"temp_F", "battery temperature in Fahrenheit (no unit)", {}, [](unused) {return fmt::format("{:.2f}", battery_temp() * 1.8 + 34);}}; + module_t battery_temp_K_module_compat = {"temp_K", "battery temperature in Kelvin (no unit)", {}, [](unused) {return fmt::format("{:.2f}", battery_temp() + 273.15);}}; - module_t battery_module = {"battery", { + module_t battery_module = {"battery", "battery current percentage and status [50.00% [Discharging]]", { std::move(battery_modelname_module), std::move(battery_status_module), std::move(battery_capacity_level_module), @@ -404,18 +405,21 @@ void core_plugins_start() cfRegisterModule(battery_module); // $<gpu> - module_t gpu_name_module = {"name", {}, gpu_name}; - module_t gpu_vendor_short_module = {"short", {}, [](const callbackInfo_t *callback) {return shorten_vendor_name(gpu_vendor(callback));}}; - module_t gpu_vendor_module = {"vendor", {std::move(gpu_vendor_short_module)}, gpu_vendor}; - - module_t gpu_module = {"gpu", { + module_t gpu_name_module = {"name", "GPU model name [GeForce GTX 1650]", {}, gpu_name}; + module_t gpu_vendor_short_module = {"short", "GPU short vendor name [NVIDIA]", {}, [](const callbackInfo_t *callback) { + return shorten_vendor_name(gpu_vendor(callback)); + }}; + module_t gpu_vendor_module = {"vendor", "GPU vendor name [NVIDIA Corporation]", { + std::move(gpu_vendor_short_module) + }, gpu_vendor}; + module_t gpu_module = {"gpu", "GPU shorter vendor name and model name [NVIDIA GeForce GTX 1650]", { std::move(gpu_name_module), std::move(gpu_vendor_module) }, [](const callbackInfo_t *callback) {return shorten_vendor_name(gpu_vendor(callback)) + " " + gpu_name(callback);}}; cfRegisterModule(gpu_module); // $<title> - module_t title_sep_module = { "sep", {}, [](const callbackInfo_t* callback) { + module_t title_sep_module = { "sep", "separator between the title and the system infos (with the title length) [--------]", {}, [](const callbackInfo_t* callback) { const size_t title_len = std::string_view(user_name() + "@" + os_hostname()).length(); @@ -426,22 +430,22 @@ void core_plugins_start() return str; } }; - module_t title_module = { "title", { std::move(title_sep_module) }, [](const callbackInfo_t* callback) { + module_t title_module = { "title", "user and hostname colored with ${auto2} [toni@arch2]", { std::move(title_sep_module) }, [](const callbackInfo_t* callback) { return parse("${auto2}$<user.name>${0}@${auto2}$<os.hostname>", callback->modulesInfo, callback->config); } }; cfRegisterModule(title_module); // $<colors> - module_t colors_light_symbol_module = { "symbol", {}, [](const callbackInfo_t* callback) { return get_colors_symbol(callback, true); } }; - module_t colors_symbol_module = { "symbol", {}, [](const callbackInfo_t* callback) { return get_colors_symbol(callback, false); }}; - module_t colors_light_module = { "light", { std::move(colors_light_symbol_module) }, [](const callbackInfo_t* callback) { + module_t colors_light_symbol_module = { "symbol", "light color palette with specific symbol", {}, [](const callbackInfo_t* callback) { return get_colors_symbol(callback, true); } }; + module_t colors_symbol_module = { "symbol", "color palette with specific symbol", {}, [](const callbackInfo_t* callback) { return get_colors_symbol(callback, false); }}; + module_t colors_light_module = { "light", "light color palette with background spaces", { std::move(colors_light_symbol_module) }, [](const callbackInfo_t* callback) { return parse( "${\033[100m} ${\033[101m} ${\033[102m} ${\033[103m} ${\033[104m} " " ${\033[105m} ${\033[106m} ${\033[107m} ${0}", callback->modulesInfo, callback->config); } }; - module_t colors_module = { "colors", + module_t colors_module = { "colors", "light color palette with background spaces", { std::move(colors_symbol_module), std::move(colors_light_module) }, [](const callbackInfo_t* callback) { return parse( From c8f461b90ed0c68644a29397cd0bdc13c7c38924 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Sat, 28 Jun 2025 23:26:44 +0200 Subject: [PATCH 052/143] args: refactor --list-modules --- src/main.cpp | 250 +++++++-------------------------------------------- 1 file changed, 34 insertions(+), 216 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 1a52829d..daa72bad 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -40,6 +40,7 @@ #include "core-modules.hh" #include "cufetch.hh" #include "display.hpp" +#include "fmt/base.h" #include "fmt/ranges.h" #include "gui.hpp" #include "platform.hpp" @@ -165,7 +166,7 @@ LIVE MODE: customfetch --distro "arch" --loop-ms 1000 3. Override layout and colors: - customfetch -m "${auto}OS: $<os.name>" --color "magenta=#FF00FF" + customfetch -m "${magenta}OS: $<os.name>" --color "magenta=#FF00FF" For details, see `man customfetch` or run `--how-it-works`. )"); @@ -177,220 +178,36 @@ For details, see `man customfetch` or run `--how-it-works`. // Print all info modules you can put in $<>, then exit successfully static void modules_list() { - constexpr std::string_view list(R"( ---------------------------------------------------------[ MODULE ONLY ]------------------------------------------------------------------------ -Should be used as like as $<module> -NOTE: module "title_sep" as an extended name version called "title_separator" - -Syntax: -# maybe comments of the module -module: - description [example of what it prints] - -ram: - used and total amount of RAM (auto) with used percentage [2.81 GiB / 15.88 GiB (5.34%)] - -swap: - used and total amount of the swapfile (auto) with used percentage [477.68 MiB / 512.00 MiB (88.45%)] - -# note: the module can have either a device path -# or a filesystem path -# e.g disk(/) or disk(/dev/sda5) -disk(/path/to/fs): - used and total amount of disk space (auto) with type of filesystem and used percentage [379.83 GiB / 438.08 GiB (86.70%) - ext4] - -# usually people have 1 GPU in their PC, -# but if you got more than 1 and want to query it, -# you should call gpu module with a number, e.g gpu1 (default gpu0). -# Infos are gotten from `/sys/class/drm/` and on each cardN directory -gpu: - GPU shorter vendor name and model name [NVIDIA GeForce GTX 1650] - -cpu: - CPU model name with number of virtual processors and max freq [AMD Ryzen 5 5500 (12) @ 4.90 GHz] - -battery: - battery current percentage and status [50.00% [Discharging]] - -title: - user and hostname colored with ${auto2} [toni@arch2] - -title_sep: - separator between the title and the system infos (with the title length) [--------] - -colors: - color palette with background spaces - -colors_light: - light color palette with background spaces - -# with `symbol` I mean a symbol to be used for the -# view of the color palette -colors_symbol(symbol): - color palette with specific symbol - -# with `symbol` I mean a symbol to be used for the -# view of the color palette -colors_light_symbol(symbol): - light color palette with specific symbol - ---------------------------------------------------------[ MODULE MEMBERS ]------------------------------------------------------------------------ - -Should be used as like as $<module.member> -NOTE: module members such as "os.pkgs" or "disk.used_perc" have an extended name version - "os.pkgs" == "os.packages" - any module member that has "perc" can be replaced with "percentage" - -Syntax: -# maybe comments of the module -module - member: description [example of what it prints; maybe another] - -os - name: OS name (pretty name) [Ubuntu 22.04.4 LTS; Arch Linux] - name_id: OS name id [ubuntu, arch] - kernel: kernel name and version [Linux 6.9.3-zen1-1-zen] - kernel_name: kernel name [Linux] - kernel_version: kernel version [6.9.3-zen1-1-zen] - version_id: OS version id [22.04.4, 20240101.0.204074] - version_codename: OS version codename [jammy] - pkgs: count of the installed packages by a package manager [1869 (pacman), 4 (flatpak)] - uptime: (auto) uptime of the system [36 mins, 3 hours, 23 days] - uptime_secs: uptime of the system in seconds (should be used along with others uptime_ members) [45] - uptime_mins: uptime of the system in minutes (should be used along with others uptime_ members) [12] - uptime_hours: uptime of the system in hours (should be used along with others uptime_ members) [34] - uptime_days: uptime of the system in days (should be used along with others uptime_ members) [2] - hostname: hostname of the OS [myMainPC] - initsys_name: Init system name [systemd] - initsys_version: Init system version [256.5-1-arch] - -user - name: name you are currently logged in (not real name) [toni69] - shell: login shell name and version [zsh 5.9] - shell_name: login shell [zsh] - shell_path: login shell (with path) [/bin/zsh] - shell_version: login shell version (may be not correct) [5.9] - de_name: Desktop Environment current session name [Plasma] - wm_name: Window Manager current session name [dwm; xfwm4] - wm_version: Window Manager version (may not work correctly) [6.2; 4.18.0] - terminal: terminal name and version [alacritty 0.13.2] - terminal_name: terminal name [alacritty] - terminal_version: terminal version [0.13.2] - -# this module is just for generic theme stuff -# such as indeed cursor -# because it is not GTK-Qt specific -theme - cursor: cursor name with its size (auto add the size if queried) [Bibata-Modern-Ice (16px)] - cursor_name: cursor name [Bibata-Modern-Ice] - cursor_size: cursor size [16] - -# If USE_DCONF flag is set, then we're going to use -# dconf, else backing up to gsettings -theme-gsettings - name: gsettings theme name [Decay-Green] - icons: gsettings icons theme name [Papirus-Dark] - font: gsettings font theme name [Cantarell 10] - cursor: gsettings cursor name with its size (auto add the size if queried) [Bibata-Modern-Ice (16px)] - cursor_name: gsettings cursor name [Bibata-Modern-Ice] - cursor_size: gsettings cursor size [16] - -# the N stands for the gtk version number to query -# so for example if you want to query the gtk3 theme name -# write it like "theme-gtk3.name" -# note: may be slow because of calling "gsettings" if couldn't read from configs. -# Read theme-gsettings module comments -theme-gtkN - name: gtk theme name [Arc-Dark] - icons: gtk icons theme name [Qogir-Dark] - font: gtk font theme name [Noto Sans 10] - -# basically as like as the "theme-gtkN" module above -# but with gtk{2,3,4} and auto format gkt version -# note: may be slow because of calling "gsettings" if couldn't read from configs. -# Read theme-gsettings module comments -theme-gtk-all - name: gtk theme name [Arc-Dark [GTK2/3/4]] - icons: gtk icons theme name [Papirus-Dark [GTK2/3], Qogir [GTK4]] - font: gtk font theme name [Hack Nerd Font 13 [GTK2], Noto Sans 10 [GTK3/4]] - -# note: these members are auto displayed in from B to YB (depending if using SI byte unit or not(IEC)). -# they all (except those that has the same name as the module or that ends with "_perc") -# have variants from -B to -YB and -B to -YiB -# example: if you want to show your 512MiB of used RAM in GiB -# use the `used-GiB` variant (they don't print the unit tho) -ram - used: used amount of RAM (auto) [2.81 GiB] - free: available amount of RAM (auto) [10.46 GiB] - total: total amount of RAM (auto) [15.88 GiB] - used_perc: percentage of used amount of RAM in total [17.69%] - free_perc: percentage of available amount of RAM in total [82.31%] - -# same comments as RAM (above) -swap - used: used amount of the swapfile (auto) [477.68 MiB] - free: available amount of the swapfile (auto) [34.32 MiB] - total: total amount of the swapfile (auto) [512.00 MiB] - used_perc: percentage of used amount of the swapfile in total [93.29%] - free_perc: percentage of available amount of the swapfile in total [6.71%] - -# same comments as RAM (above) -# note: the module can have either a device path -# or a filesystem path -# e.g disk(/) or disk(/dev/sda5) -disk(/path/to/fs) - used: used amount of disk space (auto) [360.02 GiB] - free: available amount of disk space (auto) [438.08 GiB] - total: total amount of disk space (auto) [100.08 GiB] - used_perc: percentage of used amount of the disk in total [82.18%] - free_perc: percentage of available amount of the disk in total [17.82%] - fs: type of filesystem [ext4] - device: path to device [/dev/sda5] - types: an array of type options (pretty format) [Regular, External] - mountdir: path to the device mount point [/] - -# usually people have 1 GPU in their PC, -# but if you got more than 1 and want to query it, -# you should call gpu module with a number, e.g gpu1 (default gpu0). -# Infos are gotten from `/sys/class/drm/` and on each cardN directory -gpu - name: GPU model name [GeForce GTX 1650] - vendor: GPU short vendor name [NVIDIA] - vendor_long: GPU vendor name [NVIDIA Corporation] - -# cpu module has a member called "temp" and it has 3 variant units: -# "temp_C" (Celsius) "temp_F" (Fahrenheit) "temp_K" (Kelvin) -cpu - name: CPU model name [AMD Ryzen 5 5500] - temp: CPU temperature (by the chosen unit) [40.62] - nproc: CPU number of virtual processors [12] - freq_cur: CPU current frequency (in GHz) [3.42] - freq_min: CPU minimum frequency (in GHz) [2.45] - freq_max: CPU maximum frequency (in GHz) [4.90] - freq_bios_limit: CPU frequency limited by bios (in GHz) [4.32] - -# battery module has a member called "temp" and it has 3 variant units: -# "temp_C" (Celsius) "temp_F" (Fahrenheit) "temp_K" (Kelvin) -battery - name: battery model name - temp: battery temperature (by the chosen unit) - perc: battery current percentage - vendor: battery manufacturer name - status: battery current status [Discharging, AC Connected] - technology: battery technology [Li-lion] - capacity_level: battery capacity level [Normal, Critical] - -system - host: Host (aka. Motherboard) model name with vendor and version [Micro-Star International Co., Ltd. PRO B550M-P GEN3 (MS-7D95) 1.0] - host_name: Host (aka. Motherboard) model name [PRO B550M-P GEN3 (MS-7D95)] - host_version: Host (aka. Motherboard) model version [1.0] - host_vendor: Host (aka. Motherboard) model vendor [Micro-Star International Co., Ltd.] - arch: the architecture of the machine [x86_64, aarch64] + for (const module_t& module : cfGetModules()) + { + std::vector<std::string> parts; -)"); + // Split name into parts (e.g., "os.name.pretty" -> ["os", "name", "pretty"]) + size_t start = 0, end = module.name.find('.'); + bool new_module = true; + while (end != std::string::npos) + { + new_module = false; + parts.push_back(module.name.substr(start, end - start)); + start = end + 1; + end = module.name.find('.', start); + } + parts.push_back(module.name.substr(start)); + if (new_module) + fmt::print("\n"); + + // Generate indentation + for (size_t depth = 0; depth < parts.size(); ++depth) + { + if (depth == parts.size() - 1) + fmt::print("{:<6} \t- {}", parts[depth], module.description); + else + fmt::print(" "); + } + + fmt::print("\n"); + } - fmt::print("{}", list); - fmt::print("\n"); std::exit(EXIT_SUCCESS); } @@ -514,7 +331,7 @@ A: Yes! Complex nesting is supported, for example: std::exit(EXIT_SUCCESS); } -// Print a sorted list of ascii logos you can use at a "data-dir" +// Print a modules list of ascii logos you can use at a "data-dir" // @param data_dir The data directory static void list_logos(const std::string& data_dir) { @@ -781,8 +598,6 @@ int main(int argc, char *argv[]) localize(); Config config(configFile, configDir); - if (!parseargs(argc, argv, config, configFile)) - return 1; config.loadConfigFile(configFile); /* TODO(burntranch): track each library and unload them. */ @@ -807,6 +622,9 @@ int main(int argc, char *argv[]) start(handle); } + if (!parseargs(argc, argv, config, configFile)) + return 1; + const std::vector<module_t>& modules = cfGetModules(); moduleMap_t moduleMap; From 1280b92e8a5ad21c5ca389145bc4e8938bbada6e Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Sat, 28 Jun 2025 23:27:50 +0200 Subject: [PATCH 053/143] core-plugins: remove old modules added for compatibility we gonna tell the user to just replace an underscore with a dot --- src/core-plugins/linux/linux-core-modules.cc | 80 +------------------- 1 file changed, 2 insertions(+), 78 deletions(-) diff --git a/src/core-plugins/linux/linux-core-modules.cc b/src/core-plugins/linux/linux-core-modules.cc index 0c70d23e..1890eea3 100644 --- a/src/core-plugins/linux/linux-core-modules.cc +++ b/src/core-plugins/linux/linux-core-modules.cc @@ -145,14 +145,6 @@ void core_plugins_start() std::move(os_initsys_version_module), }, [](unused) {return os_initsys_name() + " " + os_initsys_version();}}; - /* Only for compatibility */ - module_t os_pretty_name_module_compat = { "pretty_name", "OS name (pretty name) [Ubuntu 22.04.4 LTS; Arch Linux]", {}, os_pretty_name }; - module_t os_name_id_module_compat = { "name_id", "OS name id [ubuntu, arch]", {}, os_name_id }; - module_t os_kernel_name_module_compat = {"kernel_name", "kernel name [Linux]", {}, os_kernel_name}; - module_t os_kernel_version_module_compat = {"kernel_version", "kernel version [6.9.3-zen1-1-zen]", {}, os_kernel_version}; - module_t os_initsys_name_module_compat = {"initsys_name", "Init system name [systemd]", {}, os_initsys_name}; - module_t os_initsys_version_module_compat = {"initsys_version", "Init system version [256.5-1-arch]", {}, os_initsys_version}; - // $<os> module_t os_module = { "os", "OS modules", { std::move(os_name_module), @@ -160,13 +152,6 @@ void core_plugins_start() std::move(os_kernel_module), std::move(os_hostname_module), std::move(os_initsys_module), - - std::move(os_pretty_name_module_compat), - std::move(os_name_id_module_compat), - std::move(os_kernel_name_module_compat), - std::move(os_kernel_version_module_compat), - std::move(os_initsys_name_module_compat), - std::move(os_initsys_version_module_compat), }, NULL}; cfRegisterModule(os_module); @@ -174,23 +159,16 @@ void core_plugins_start() module_t host_name_module = {"name", "Host (aka. Motherboard) model name [PRO B550M-P GEN3 (MS-7D95)]", {}, host_name}; module_t host_version_module = {"version", "Host (aka. Motherboard) model version [1.0]", {}, host_version}; module_t host_vendor_module = {"vendor", "Host (aka. Motherboard) model vendor [Micro-Star International Co., Ltd.]", {}, host_vendor}; - module_t host_module = {"host", "Host (aka. Motherboard) model name with vendor and version [Micro-Star International Co., Ltd. PRO B550M-P GEN3 (MS-7D95) 1.0]", { + module_t host_module = {"host", "Host (aka. Motherboard) model name with vendor and version [MSI PRO B550M-P GEN3 (MS-7D95) 1.0]", { std::move(host_name_module), std::move(host_version_module), std::move(host_vendor_module) }, host}; module_t arch_module = {"arch", "the architecture of the machine [x86_64, aarch64]", {}, arch}; - /* Only for compatibility */ - module_t host_name_module_compat = { "host_name", "Host (aka. Motherboard) model name [PRO B550M-P GEN3 (MS-7D95)]", {}, host_name }; - module_t host_version_module_compat = {"host_version", "Host (aka. Motherboard) model version [1.0]", {}, host_version}; - module_t host_vendor_module_compat = {"host_vendor", "Host (aka. Motherboard) model vendor [Micro-Star International Co., Ltd.]", {}, host_vendor}; module_t system_module = { "system", "System modules", { std::move(host_module), - std::move(host_name_module_compat), - std::move(host_version_module_compat), - std::move(host_vendor_module_compat), std::move(arch_module), }, NULL }; cfRegisterModule(system_module); @@ -219,28 +197,11 @@ void core_plugins_start() std::move(cpu_temp_K_module), }, [](unused) {return fmt::format("{:.2f}°C", cpu_temp());}}; - /* Only for compatibility */ - module_t cpu_freq_cur_module_compat = {"freq_cur", "CPU current frequency (in GHz) [3.42]", {}, cpu_freq_cur}; - module_t cpu_freq_max_module_compat = {"freq_max", "CPU maximum frequency (in GHz) [4.90]", {}, cpu_freq_max}; - module_t cpu_freq_min_module_compat = {"freq_min", "CPU minimum frequency (in GHz) [2.45]", {}, cpu_freq_min}; - module_t cpu_freq_bios_module_compat = {"freq_bios_limit", "CPU frequency limited by bios (in GHz) [4.32]", {}, cpu_freq_bios}; - module_t cpu_temp_C_module_compat = {"temp_C", "CPU temperature in Celsius [40.62]", {}, [](unused) {return fmt::format("{:.2f}", cpu_temp());}}; - module_t cpu_temp_F_module_compat = {"temp_F", "CPU temperature in Fahrenheit [105.12]", {}, [](unused) {return fmt::format("{:.2f}", cpu_temp() * 1.8 + 34);}}; - module_t cpu_temp_K_module_compat = {"temp_K", "CPU temperature in Kelvin [313.77]", {}, [](unused) {return fmt::format("{:.2f}", cpu_temp() + 273.15);}}; - module_t cpu_module = {"cpu", "CPU model name with number of virtual processors and max freq [AMD Ryzen 5 5500 (12) @ 4.90 GHz]",{ std::move(cpu_name_module), std::move(cpu_nproc_module), std::move(cpu_freq_module), std::move(cpu_temp_module), - - std::move(cpu_freq_cur_module_compat), - std::move(cpu_freq_max_module_compat), - std::move(cpu_freq_min_module_compat), - std::move(cpu_freq_bios_module_compat), - std::move(cpu_temp_C_module_compat), - std::move(cpu_temp_F_module_compat), - std::move(cpu_temp_K_module_compat), }, [](unused) { return fmt::format("{} ({}) @ {} GHz", cpu_name(), cpu_nproc(), cpu_freq_max()); }}; @@ -279,33 +240,12 @@ void core_plugins_start() std::move(user_de_name_module) }, [](unused) {return user_de_name() + " " + user_de_version();}}; - /* Only for compatibility */ - module_t user_shell_path_module_compat = {"shell_path", "login shell (with path) [/bin/zsh]", {}, user_shell_path}; - module_t user_shell_name_module_compat = {"shell_name", "login shell [zsh]", {}, user_shell_name}; - module_t user_shell_version_module_compat = {"shell_version", "login shell version (may be not correct) [5.9]", {}, user_shell_version}; - module_t user_term_name_module_compat = {"terminal_name", "terminal name [alacritty]", {}, user_term_name}; - module_t user_term_version_module_compat = {"terminal_version", "terminal version [0.13.2]", {}, user_shell_version}; - module_t user_wm_name_module_compat = {"wm_name", "Window Manager current session name [dwm; xfwm4]", {}, user_wm_name}; - module_t user_wm_version_module_compat = {"wm_version", "Window Manager version (may not work correctly) [6.2; 4.18.0]", {}, user_wm_version}; - module_t user_de_name_module_compat = {"de_name", "Desktop Environment current session name [Plasma]", {}, user_de_name}; - module_t user_de_version_module_compat = {"de_version", "Desktop Environment version (if available)", {}, user_de_version}; - module_t user_module = {"user", "User modules", { std::move(user_name_module), std::move(user_shell_module), std::move(user_term_module), std::move(user_wm_module), std::move(user_de_module), - - std::move(user_shell_name_module_compat), - std::move(user_shell_path_module_compat), - std::move(user_shell_version_module_compat), - std::move(user_term_version_module_compat), - std::move(user_term_name_module_compat), - std::move(user_wm_name_module_compat), - std::move(user_wm_version_module_compat), - std::move(user_de_name_module_compat), - std::move(user_de_version_module_compat), }, NULL}; cfRegisterModule(user_module); @@ -319,8 +259,6 @@ void core_plugins_start() module_t ram_module = {"ram", "used and total amount of RAM (auto) with used percentage [2.81 GiB / 15.88 GiB (5.34%)]", { std::move(ram_free_module), std::move(ram_used_module), - std::move(ram_free_perc_module), - std::move(ram_used_perc_module), std::move(ram_total_module) }, NULL}; cfRegisterModule(ram_module); @@ -335,8 +273,6 @@ void core_plugins_start() module_t swap_module = {"swap", "used and total amount of the swapfile (auto) with used percentage [477.68 MiB / 512.00 MiB (88.45%)]", { std::move(swap_free_module), std::move(swap_used_module), - std::move(swap_free_perc_module), - std::move(swap_used_perc_module), std::move(swap_total_module) }, NULL}; cfRegisterModule(swap_module); @@ -358,8 +294,6 @@ void core_plugins_start() std::move(disk_device_module), std::move(disk_mountdir_module), std::move(disk_types_module), - std::move(disk_free_perc_module), - std::move(disk_used_perc_module), std::move(disk_free_module), std::move(disk_used_module), std::move(disk_total_module), @@ -377,18 +311,12 @@ void core_plugins_start() module_t battery_temp_C_module = {"C", "battery temperature in Celsius [e.g. 37.12°C]", {}, [](unused) {return fmt::format("{:.2f}°C", battery_temp());}}; module_t battery_temp_F_module = {"F", "battery temperature in Fahrenheit [e.g. 98.81°F]", {}, [](unused) {return fmt::format("{:.2f}°F", battery_temp() * 1.8 + 34);}}; module_t battery_temp_K_module = {"K", "battery temperature in Kelvin [e.g. 310.27°K]", {}, [](unused) {return fmt::format("{:.2f}°K", battery_temp() + 273.15);}}; - module_t battery_temp_module = {"temp", "battery temperature (by the chosen unit)", { std::move(battery_temp_C_module), std::move(battery_temp_F_module), std::move(battery_temp_K_module), }, [](unused) {return fmt::format("{:.2f}°C", battery_temp());}}; - /* Only for compatibility */ - module_t battery_temp_C_module_compat = {"temp_C", "battery temperature in Celsius (no unit)", {}, [](unused) {return fmt::format("{:.2f}", battery_temp());}}; - module_t battery_temp_F_module_compat = {"temp_F", "battery temperature in Fahrenheit (no unit)", {}, [](unused) {return fmt::format("{:.2f}", battery_temp() * 1.8 + 34);}}; - module_t battery_temp_K_module_compat = {"temp_K", "battery temperature in Kelvin (no unit)", {}, [](unused) {return fmt::format("{:.2f}", battery_temp() + 273.15);}}; - module_t battery_module = {"battery", "battery current percentage and status [50.00% [Discharging]]", { std::move(battery_modelname_module), std::move(battery_status_module), @@ -397,10 +325,6 @@ void core_plugins_start() std::move(battery_vendor_module), std::move(battery_perc_module), std::move(battery_temp_module), - - std::move(battery_temp_C_module_compat), - std::move(battery_temp_F_module_compat), - std::move(battery_temp_K_module_compat), }, NULL}; cfRegisterModule(battery_module); @@ -445,7 +369,7 @@ void core_plugins_start() " ${\033[105m} ${\033[106m} ${\033[107m} ${0}", callback->modulesInfo, callback->config); } }; - module_t colors_module = { "colors", "light color palette with background spaces", + module_t colors_module = { "colors", "color palette with background spaces", { std::move(colors_symbol_module), std::move(colors_light_module) }, [](const callbackInfo_t* callback) { return parse( From 4e178639fd8766d3737da1611823e993c75bdd56 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Sun, 29 Jun 2025 13:47:05 +0200 Subject: [PATCH 054/143] plugins: add finish() for unloading everything --- src/core-plugins/linux/linux-core-modules.cc | 9 +++++ src/main.cpp | 36 +++++++++++--------- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/src/core-plugins/linux/linux-core-modules.cc b/src/core-plugins/linux/linux-core-modules.cc index 1890eea3..c4a48f36 100644 --- a/src/core-plugins/linux/linux-core-modules.cc +++ b/src/core-plugins/linux/linux-core-modules.cc @@ -5,6 +5,7 @@ #include <algorithm> #include <array> #include <chrono> +#include <cstdio> #include <string> #include <string_view> #include <utility> @@ -379,3 +380,11 @@ void core_plugins_start() } }; cfRegisterModule(colors_module); } + +void core_plugins_finish() +{ + if (mountsFile) fclose(mountsFile); + if (os_release) fclose(os_release); + if (meminfo) fclose(meminfo); + if (cpuinfo) fclose(cpuinfo); +} diff --git a/src/main.cpp b/src/main.cpp index daa72bad..a92041ed 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -36,8 +36,8 @@ #include <thread> #include <vector> +#include "common.hpp" #include "config.hpp" -#include "core-modules.hh" #include "cufetch.hh" #include "display.hpp" #include "fmt/base.h" @@ -84,7 +84,8 @@ static void version() #endif #endif - fmt::print("{}\n", version); + fmt::print("{}", version); + fmt::print("\n"); // if only everyone would not return error when querying the program version :( std::exit(EXIT_SUCCESS); @@ -171,7 +172,8 @@ LIVE MODE: For details, see `man customfetch` or run `--how-it-works`. )"); - fmt::print("{}\n", help); + fmt::print("{}", help); + fmt::print("\n"); std::exit(invalid_opt); } @@ -569,6 +571,7 @@ static void localize(void) } void core_plugins_start(); +void core_plugins_finish(); int main(int argc, char *argv[]) { @@ -592,13 +595,14 @@ int main(int argc, char *argv[]) #endif // clang-format on - const std::filesystem::path configDir = getConfigDir(); - const std::filesystem::path configFile = parse_config_path(argc, argv, configDir); + const std::filesystem::path& configDir = getConfigDir(); + const std::filesystem::path& configFile = parse_config_path(argc, argv, configDir); localize(); Config config(configFile, configDir); config.loadConfigFile(configFile); + std::vector<void *> plugins_handle; /* TODO(burntranch): track each library and unload them. */ core_plugins_start(); @@ -612,7 +616,7 @@ int main(int argc, char *argv[]) if (!handle) { // dlerror() is pretty formatted - warn("Failed to load mod {}", dlerror()); + warn("Failed to load mod at {}: {}", entry.path().string(), dlerror()); dlerror(); continue; } @@ -620,6 +624,7 @@ int main(int argc, char *argv[]) LOAD_LIB_SYMBOL(handle, void, start, void*) start(handle); + plugins_handle.push_back(handle); } if (!parseargs(argc, argv, config, configFile)) @@ -711,16 +716,15 @@ int main(int argc, char *argv[]) if (!config.wrap_lines) enable_cursor(); -#if CF_LINUX - if (mountsFile) - fclose(mountsFile); - if (os_release) - fclose(os_release); - if (cpuinfo) - fclose(cpuinfo); - if (meminfo) - fclose(meminfo); -#endif + core_plugins_finish(); + for (void *handle : plugins_handle) + { + LOAD_LIB_SYMBOL(handle, void, finish, void*) + + finish(handle); + UNLOAD_LIBRARY(handle); + } + plugins_handle.clear(); return 0; } From 60dbee4902966e192708c9f45e98e378af270fb1 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Sun, 29 Jun 2025 15:04:07 +0200 Subject: [PATCH 055/143] plugins: some improvement to libcufetch structure --- CMakeLists.txt | 6 +- Makefile | 3 +- include/config.hpp | 4 +- include/core-modules.hh | 2 +- include/{common.hpp => cufetch/common.hh} | 68 +++++++++----------- include/{ => cufetch}/cufetch.hh | 2 +- include/parse.hpp | 2 +- include/query.hpp | 2 +- include/util.hpp | 13 +++- libcufetch/cufetch.cc | 2 +- libcufetch/parse.cc | 2 +- src/core-plugins/linux/battery.cc | 2 +- src/core-plugins/linux/cpu.cc | 2 +- src/core-plugins/linux/disk.cc | 2 +- src/core-plugins/linux/linux-core-modules.cc | 3 +- src/core-plugins/linux/os.cc | 2 +- src/core-plugins/linux/ram.cc | 2 +- src/core-plugins/linux/system.cc | 2 +- src/core-plugins/linux/user.cc | 2 +- src/main.cpp | 10 ++- src/query/linux/utils/dewm.cpp | 2 +- src/util.cpp | 1 - 22 files changed, 68 insertions(+), 68 deletions(-) rename include/{common.hpp => cufetch/common.hh} (77%) rename include/{ => cufetch}/cufetch.hh (88%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 98100ba3..b6f89c65 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -89,10 +89,8 @@ target_link_libraries(${TARGET_NAME} PUBLIC fmt) # libcufetch set(CUFETCH_HEADERS - include/config.hpp - include/common.hpp - include/core-modules.hh - include/cufetch.hh + include/cufetch/common.hh + include/cufetch/cufetch.hh ) add_library(cufetch SHARED diff --git a/Makefile b/Makefile index de00bb5c..fe62e4f3 100644 --- a/Makefile +++ b/Makefile @@ -61,7 +61,6 @@ SRC_CC = $(wildcard src/core-plugins/linux/*.cc) OBJ_CPP = $(SRC_CPP:.cpp=.o) OBJ_CC = $(SRC_CC:.cc=.o) OBJ = $(OBJ_CPP) $(OBJ_CC) -HEADERS = config.hpp common.hpp core-modules.hh cufetch.hh LDFLAGS += -Wl,-Bstatic $(BUILDDIR)/libfmt.a -Wl,-Bdynamic -lcufetch -ldl CXXFLAGS ?= -mtune=generic -march=native CXXFLAGS += -fvisibility-inlines-hidden -fvisibility=hidden -Iinclude -std=c++20 $(VARS) -DVERSION=\"$(VERSION)\" -DLOCALEDIR=\"$(LOCALEDIR)\" -DICONPREFIX=\"$(ICONPREFIX)\" @@ -139,7 +138,7 @@ install-common: libcufetch locale find examples/ -type f -exec install -Dm 644 "{}" "$(DESTDIR)$(PREFIX)/share/$(NAME)/{}" \; find locale/ -type f -exec install -Dm 644 "{}" "$(DESTDIR)$(PREFIX)/share/{}" \; mkdir -p $(DESTDIR)$(PREFIX)/include/cufetch/ - cd include && find $(HEADERS) -type f -exec install -Dm 644 "{}" "$(DESTDIR)$(PREFIX)/include/cufetch/{}" \; + cd include/cufetch && find . -type f -exec install -Dm 644 "{}" "$(DESTDIR)$(PREFIX)/include/cufetch/{}" \; install -Dm 755 $(BUILDDIR)/libcufetch.so $(DESTDIR)$(PREFIX)/lib/libcufetch.so.1 ifeq ($(GUI_APP), 1) mkdir -p $(DESTDIR)$(APPPREFIX) diff --git a/include/config.hpp b/include/config.hpp index c4d21d60..6c884e80 100644 --- a/include/config.hpp +++ b/include/config.hpp @@ -225,7 +225,7 @@ inline constexpr std::string_view AUTOCONFIG = R"#([config] # * if on the android app, click the button "how it works" during widget configuration layout = [ "$<title>", - "$<title_sep>", + "$<title.sep>", "${auto}OS: $<os.name> $<system.arch>", "${auto}Host: $<system.host>", "${auto}Kernel: $<os.kernel>", @@ -247,7 +247,7 @@ layout = [ "${auto}RAM: $<ram>", "", "$<colors>", # normal colors - "$<colors_light>" # light colors + "$<colors.light>" # light colors ] # display ascii-art or image/gif (GUI only) near layout diff --git a/include/core-modules.hh b/include/core-modules.hh index 250e0e7d..95e3abae 100644 --- a/include/core-modules.hh +++ b/include/core-modules.hh @@ -3,7 +3,7 @@ #include <pwd.h> #include <sys/utsname.h> -#include "common.hpp" +#include "cufetch/common.hh" #define MODFUNC(name) const std::string name(__attribute__((unused)) const callbackInfo_t* callbackInfo = nullptr) diff --git a/include/common.hpp b/include/cufetch/common.hh similarity index 77% rename from include/common.hpp rename to include/cufetch/common.hh index 2bfc12de..37534592 100644 --- a/include/common.hpp +++ b/include/cufetch/common.hh @@ -19,69 +19,64 @@ constexpr const char UNKNOWN[] = "(unknown)"; // Every instance of this string in a layout line, the whole line will be erased. constexpr const char MAGIC_LINE[] = "(cut this line NOW!! RAHHH)"; -/* handler = the library handle - * ret_type = type of what the function returns - * func = the function name - * ... = the arguments in a function if any - */ -#define LOAD_LIB_SYMBOL(handler, ret_type, func, ...) \ - typedef ret_type (*func##_t)(__VA_ARGS__); \ - func##_t func = reinterpret_cast<func##_t>(dlsym(handler, #func)); +#define BOLD_COLOR(x) (fmt::emphasis::bold | fmt::fg(fmt::rgb(x))) -#define UNLOAD_LIBRARY(handle) dlclose(handle); - -#define APICALL extern "C" -// {fmt} library already has __attribute__((visibility(value))) fallback so let's use that maybeAdd commentMore actions -#define EXPORT FMT_VISIBILITY("default") -#define MOD_INIT void start - -#define BOLD_COLOR(x) (fmt::emphasis::bold | fmt::fg(x)) +#if DEBUG +inline bool debug_print = true; +#else +inline bool debug_print = false; +#endif template <typename... Args> void error(const std::string_view fmt, Args&&... args) noexcept { - fmt::print(stderr, BOLD_COLOR(fmt::rgb(fmt::color::red)), "ERROR: {}\033[0m\n", + fmt::print(stderr, BOLD_COLOR(fmt::color::red), "ERROR: {}\033[0m\n", fmt::format(fmt::runtime(fmt), std::forward<Args>(args)...)); } template <typename... Args> void die(const std::string_view fmt, Args&&... args) noexcept { - fmt::print(stderr, BOLD_COLOR(fmt::rgb(fmt::color::red)), "FATAL: {}\033[0m\n", + fmt::print(stderr, BOLD_COLOR(fmt::color::red), "FATAL: {}\033[0m\n", fmt::format(fmt::runtime(fmt), std::forward<Args>(args)...)); std::exit(1); } -#if DEBUG -inline bool debug_print = true; -#else -inline bool debug_print = false; -#endif - template <typename... Args> void debug(const std::string_view fmt, Args&&... args) noexcept { if (debug_print) - fmt::print(BOLD_COLOR((fmt::rgb(fmt::color::hot_pink))), "[DEBUG]:\033[0m {}\n", + fmt::print(BOLD_COLOR((fmt::color::hot_pink)), "[DEBUG]:\033[0m {}\n", fmt::format(fmt::runtime(fmt), std::forward<Args>(args)...)); } template <typename... Args> void warn(const std::string_view fmt, Args&&... args) noexcept { - fmt::print(BOLD_COLOR((fmt::rgb(fmt::color::yellow))), "WARNING: {}\033[0m\n", + fmt::print(BOLD_COLOR((fmt::color::yellow)), "WARNING: {}\033[0m\n", fmt::format(fmt::runtime(fmt), std::forward<Args>(args)...)); } template <typename... Args> void info(const std::string_view fmt, Args&&... args) noexcept { - fmt::print(BOLD_COLOR((fmt::rgb(fmt::color::cyan))), "INFO: {}\033[0m\n", + fmt::print(BOLD_COLOR((fmt::color::cyan)), "INFO: {}\033[0m\n", fmt::format(fmt::runtime(fmt), std::forward<Args>(args)...)); } #undef BOLD_COLOR +#define APICALL extern "C" +// {fmt} library already has __attribute__((visibility(value))) fallback so let's use that maybeAdd commentMore actions +#define EXPORT FMT_VISIBILITY("default") +#define MOD_INIT void start + +class Config; +struct module_t; + +// Map from a modules name to its pointer. +using moduleMap_t = std::unordered_map<std::string, const module_t&>; + /* A linked list including module arguments. An argument may be specified for any part of the module path (e.g. * `disk(/).used(GiB)`, `test(a).hi`) */ struct moduleArgs_t @@ -94,7 +89,13 @@ struct moduleArgs_t struct moduleArgs_t* next = nullptr; }; -struct callbackInfo_t; +struct callbackInfo_t +{ + const moduleArgs_t* moduleArgs; + const moduleMap_t& modulesInfo; + const Config& config; +}; + struct module_t { std::string name; @@ -103,16 +104,5 @@ struct module_t std::function<const std::string(const callbackInfo_t*)> handler; }; -// Map from a modules name to its pointer. -using moduleMap_t = std::unordered_map<std::string, const module_t&>; -class Config; - const std::string parse(const std::string& input, const moduleMap_t& modulesInfo, const Config& config); const std::string get_and_color_percentage(const float n1, const float n2, const callbackInfo_t* callback, const bool invert); - -struct callbackInfo_t -{ - const moduleArgs_t* moduleArgs; - const moduleMap_t& modulesInfo; - const Config& config; -}; diff --git a/include/cufetch.hh b/include/cufetch/cufetch.hh similarity index 88% rename from include/cufetch.hh rename to include/cufetch/cufetch.hh index 0deb1279..f7d87132 100644 --- a/include/cufetch.hh +++ b/include/cufetch/cufetch.hh @@ -1,6 +1,6 @@ #include <vector> -#include "common.hpp" +#include "cufetch/common.hh" /* Register a module, and its submodules, to customfetch. */ void cfRegisterModule(const module_t& module); diff --git a/include/parse.hpp b/include/parse.hpp index 35c1f021..1c38c8d1 100644 --- a/include/parse.hpp +++ b/include/parse.hpp @@ -29,7 +29,7 @@ #include <string> #include <vector> -#include "common.hpp" +#include "cufetch/common.hh" #include "config.hpp" // Map from a modules name to its pointer. diff --git a/include/query.hpp b/include/query.hpp index 8fb19ed4..d944fc52 100644 --- a/include/query.hpp +++ b/include/query.hpp @@ -34,7 +34,7 @@ #include <vector> #include "config.hpp" -#include "common.hpp" +#include "cufetch/common.hh" extern "C" { #if !CF_MACOS diff --git a/include/util.hpp b/include/util.hpp index 29ad8217..e584d981 100644 --- a/include/util.hpp +++ b/include/util.hpp @@ -36,7 +36,7 @@ #include <string> #include <vector> -#include "common.hpp" +#include "cufetch/common.hh" #include "fmt/base.h" #include "fmt/color.h" #include "platform.hpp" @@ -67,6 +67,17 @@ struct byte_units_t /* lib = library to load (string) */ #define LOAD_LIBRARY(lib) dlopen(lib, RTLD_LAZY); +/* handler = the library handle + * ret_type = type of what the function returns + * func = the function name + * ... = the arguments in a function if any + */ +#define LOAD_LIB_SYMBOL(handler, ret_type, func, ...) \ + typedef ret_type (*func##_t)(__VA_ARGS__); \ + func##_t func = reinterpret_cast<func##_t>(dlsym(handler, #func)); + +#define UNLOAD_LIBRARY(handle) dlclose(handle); + /* https://stackoverflow.com/questions/874134/find-out-if-string-ends-with-another-string-in-c#874160 * Check if substring exists at the end * @param fullString The string to lookup diff --git a/libcufetch/cufetch.cc b/libcufetch/cufetch.cc index 0917699e..9d564573 100644 --- a/libcufetch/cufetch.cc +++ b/libcufetch/cufetch.cc @@ -1,4 +1,4 @@ -#include "cufetch.hh" +#include "cufetch/cufetch.hh" static std::vector<module_t> modules; diff --git a/libcufetch/parse.cc b/libcufetch/parse.cc index 189f8d7e..2d5a319f 100644 --- a/libcufetch/parse.cc +++ b/libcufetch/parse.cc @@ -37,7 +37,7 @@ #include <string_view> #include <vector> -#include "common.hpp" +#include "cufetch/common.hh" #include "config.hpp" #include "fmt/color.h" #include "fmt/format.h" diff --git a/src/core-plugins/linux/battery.cc b/src/core-plugins/linux/battery.cc index 63d10457..8d428e33 100644 --- a/src/core-plugins/linux/battery.cc +++ b/src/core-plugins/linux/battery.cc @@ -2,7 +2,7 @@ #include <string> -#include "common.hpp" +#include "cufetch/common.hh" #include "core-modules.hh" #include "util.hpp" diff --git a/src/core-plugins/linux/cpu.cc b/src/core-plugins/linux/cpu.cc index 6d65fde3..d3ea5866 100644 --- a/src/core-plugins/linux/cpu.cc +++ b/src/core-plugins/linux/cpu.cc @@ -2,7 +2,7 @@ #include <string> -#include "common.hpp" +#include "cufetch/common.hh" #include "core-modules.hh" #include "fmt/format.h" #include "util.hpp" diff --git a/src/core-plugins/linux/disk.cc b/src/core-plugins/linux/disk.cc index 8a49ef1e..b3dc55c1 100644 --- a/src/core-plugins/linux/disk.cc +++ b/src/core-plugins/linux/disk.cc @@ -5,7 +5,7 @@ #include <cstdio> -#include "common.hpp" +#include "cufetch/common.hh" #include "core-modules.hh" #include "util.hpp" diff --git a/src/core-plugins/linux/linux-core-modules.cc b/src/core-plugins/linux/linux-core-modules.cc index c4a48f36..51f69a02 100644 --- a/src/core-plugins/linux/linux-core-modules.cc +++ b/src/core-plugins/linux/linux-core-modules.cc @@ -10,10 +10,9 @@ #include <string_view> #include <utility> -#include "common.hpp" #include "config.hpp" #include "core-modules.hh" -#include "cufetch.hh" +#include "cufetch/cufetch.hh" #include "fmt/format.h" #include "util.hpp" diff --git a/src/core-plugins/linux/os.cc b/src/core-plugins/linux/os.cc index 8acc80d8..2ead3e05 100644 --- a/src/core-plugins/linux/os.cc +++ b/src/core-plugins/linux/os.cc @@ -6,7 +6,7 @@ #include <string_view> #define FMT_HEADER_ONLY 1 -#include "common.hpp" +#include "cufetch/common.hh" #include "core-modules.hh" #include "fmt/format.h" #include "switch_fnv1a.hpp" diff --git a/src/core-plugins/linux/ram.cc b/src/core-plugins/linux/ram.cc index ae0d0bd5..0755acf2 100644 --- a/src/core-plugins/linux/ram.cc +++ b/src/core-plugins/linux/ram.cc @@ -2,7 +2,7 @@ #include <string> #include <string_view> -#include "common.hpp" +#include "cufetch/common.hh" #include "core-modules.hh" static double read_value(const std::string_view key) diff --git a/src/core-plugins/linux/system.cc b/src/core-plugins/linux/system.cc index 107d0573..065eab01 100644 --- a/src/core-plugins/linux/system.cc +++ b/src/core-plugins/linux/system.cc @@ -4,7 +4,7 @@ #include <string> #include <string_view> -#include "common.hpp" +#include "cufetch/common.hh" #include "core-modules.hh" #include "util.hpp" diff --git a/src/core-plugins/linux/user.cc b/src/core-plugins/linux/user.cc index 88e97359..40b6e593 100644 --- a/src/core-plugins/linux/user.cc +++ b/src/core-plugins/linux/user.cc @@ -2,7 +2,7 @@ #include <fstream> -#include "common.hpp" +#include "cufetch/common.hh" #include "core-modules.hh" #include "fmt/format.h" #include "switch_fnv1a.hpp" diff --git a/src/main.cpp b/src/main.cpp index a92041ed..8542a786 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -36,9 +36,8 @@ #include <thread> #include <vector> -#include "common.hpp" #include "config.hpp" -#include "cufetch.hh" +#include "cufetch/cufetch.hh" #include "display.hpp" #include "fmt/base.h" #include "fmt/ranges.h" @@ -202,7 +201,12 @@ static void modules_list() for (size_t depth = 0; depth < parts.size(); ++depth) { if (depth == parts.size() - 1) - fmt::print("{:<6} \t- {}", parts[depth], module.description); + { + if (new_module) + fmt::print("{} - {}", parts[depth], module.description); + else + fmt::print("{:<6} \t- {}", parts[depth], module.description); + } else fmt::print(" "); } diff --git a/src/query/linux/utils/dewm.cpp b/src/query/linux/utils/dewm.cpp index f9212175..76aec099 100644 --- a/src/query/linux/utils/dewm.cpp +++ b/src/query/linux/utils/dewm.cpp @@ -48,7 +48,7 @@ #include <cstdlib> #include <fstream> -#include "common.hpp" +#include "cufetch/common.hh" #include "rapidxml-1.13/rapidxml.hpp" #include "switch_fnv1a.hpp" #include "util.hpp" diff --git a/src/util.cpp b/src/util.cpp index 5c55e4d9..da0139bc 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -45,7 +45,6 @@ #include <tuple> #include <vector> -#include "common.hpp" #include "fmt/color.h" #include "fmt/ranges.h" #include "pci.ids.hpp" From b2c05380139a92f369de83b9cb8225c33201de08 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Sun, 29 Jun 2025 19:58:45 +0200 Subject: [PATCH 056/143] plugins: split the config codebase --- include/config.hpp | 85 ++--------- include/cufetch/common.hh | 3 +- include/cufetch/config.hh | 81 +++++++++++ include/cufetch/cufetch.hh | 2 + libcufetch/config.cc | 198 +------------------------- libcufetch/parse.cc | 1 - src/config.cpp | 218 +++++++++++++++++++++++++++++ src/main.cpp | 37 ++--- src/query/linux/utils/packages.cpp | 11 +- 9 files changed, 346 insertions(+), 290 deletions(-) create mode 100644 include/cufetch/config.hh create mode 100644 src/config.cpp diff --git a/include/config.hpp b/include/config.hpp index 6c884e80..56d01b72 100644 --- a/include/config.hpp +++ b/include/config.hpp @@ -26,35 +26,15 @@ #ifndef _CONFIG_HPP #define _CONFIG_HPP -#include <filesystem> +#undef TOML_HEADER_ONLY #define TOML_HEADER_ONLY 0 +#include <filesystem> +#include "platform.hpp" +#include "cufetch/config.hh" -#include <cstdint> -#include <type_traits> -#include <unordered_map> - -#include "toml++/toml.hpp" -#include "util.hpp" - -enum types -{ - STR, - BOOL, - INT -}; - -struct override_configs_types -{ - types value_type; - std::string string_value = ""; - bool bool_value = false; - int int_value = 0; -}; - -class Config +class Config : public ConfigBase { -public: - // Create .config directories and files and load the config file (args or default) +public:// Create .config directories and files and load the config file (args or default) Config(const std::filesystem::path& configFile, const std::filesystem::path& configDir); // config colors @@ -133,8 +113,6 @@ class Config bool args_disallow_commands = false; bool args_print_logo_only = false; - std::unordered_map<std::string, override_configs_types> overrides; - /** * Load config file and parse every config variables * @param filename The config file path @@ -165,54 +143,13 @@ class Config */ void overrideOption(const std::string& opt); -private: - // Parsed config from loadConfigFile() - toml::table tbl; - /** - * Get value of config variables - * @param value The config variable "path" (e.g "config.source-path") - * @param fallback Default value if couldn't retrive value - */ - template <typename T> - T getValue(const std::string_view value, const T&& fallback, bool dont_expand_var = false) const - { - const auto& overridePos = overrides.find(value.data()); - - // user wants a bool (overridable), we found an override matching the name, and the override is a bool. - if constexpr (std::is_same<T, bool>()) - if (overridePos != overrides.end() && overrides.at(value.data()).value_type == BOOL) - return overrides.at(value.data()).bool_value; - - if constexpr (std::is_same<T, std::string>()) - if (overridePos != overrides.end() && overrides.at(value.data()).value_type == STR) - return overrides.at(value.data()).string_value; - - if constexpr (std::is_same<T, std::uint16_t>()) - if (overridePos != overrides.end() && overrides.at(value.data()).value_type == INT) - return overrides.at(value.data()).int_value; - - const std::optional<T>& ret = this->tbl.at_path(value).value<T>(); - if constexpr (toml::is_string<T>) // if we want to get a value that's a string - return ret ? expandVar(ret.value(), dont_expand_var) : expandVar(fallback, dont_expand_var); - else - return ret.value_or(fallback); - } - - /** - * getValue() but don't want to specify the template, so it's std::string, - * and because of the name, only used when retriving the colors for terminal and GUI - * @param value The config variable "path" (e.g "config.gui-red") - * @param fallback Default value if couldn't retrive value - */ - std::string getThemeValue(const std::string_view value, const std::string_view fallback) const; - - /** - * Get value of config array of string variables - * @param value The config variable "path" (e.g "config.gui-red") - * @param fallback Default value if couldn't retrive value + * Override a config value from --override + * @param str The value to override. + * Must have a '=' for separating the name and value to override. + * NO spaces between */ - std::vector<std::string> getValueArrayStr(const std::string_view value, const std::vector<std::string>& fallback); + void overrideOption(const std::string& opt, const override_configs_types& option); }; // default config diff --git a/include/cufetch/common.hh b/include/cufetch/common.hh index 37534592..65769c47 100644 --- a/include/cufetch/common.hh +++ b/include/cufetch/common.hh @@ -67,8 +67,7 @@ void info(const std::string_view fmt, Args&&... args) noexcept #undef BOLD_COLOR #define APICALL extern "C" -// {fmt} library already has __attribute__((visibility(value))) fallback so let's use that maybeAdd commentMore actions -#define EXPORT FMT_VISIBILITY("default") +#define EXPORT __attribute__((visibility("default"))) #define MOD_INIT void start class Config; diff --git a/include/cufetch/config.hh b/include/cufetch/config.hh new file mode 100644 index 00000000..1f15693e --- /dev/null +++ b/include/cufetch/config.hh @@ -0,0 +1,81 @@ +#pragma once + +#include <type_traits> +#include <unordered_map> +#include "cufetch/common.hh" + +#ifndef TOML_HEADER_ONLY +# define TOML_HEADER_ONLY 1 +#endif +#include "toml++/toml.hpp" + +enum types +{ + STR, + BOOL, + INT +}; + +struct EXPORT override_configs_types +{ + types value_type; + std::string string_value = ""; + bool bool_value = false; + int int_value = 0; +}; + +class EXPORT ConfigBase +{ +public: + + /** + * Get value of config variables + * @param value The config variable "path" (e.g "config.source-path") + * @param fallback Default value if couldn't retrive value + */ + template <typename T> + T getValue(const std::string_view value, const T&& fallback) const + { + const auto& overridePos = overrides.find(value.data()); + + // user wants a bool (overridable), we found an override matching the name, and the override is a bool. + if constexpr (std::is_convertible<T, bool>()) + if (overridePos != overrides.end() && overrides.at(value.data()).value_type == BOOL) + return overrides.at(value.data()).bool_value; + + if constexpr (std::is_convertible<T, std::string>()) + if (overridePos != overrides.end() && overrides.at(value.data()).value_type == STR) + return overrides.at(value.data()).string_value; + + if constexpr (std::is_convertible<T, int>()) + if (overridePos != overrides.end() && overrides.at(value.data()).value_type == INT) + return overrides.at(value.data()).int_value; + + const std::optional<T>& ret = this->tbl.at_path(value).value<T>(); + return ret.value_or(fallback); + } + + /** + * getValue() but don't want to specify the template, so it's std::string, + * and thus the name, only used when retriving the colors for terminal and GUI + * @param value The config variable "path" (e.g "config.gui-red") + * @param fallback Default value if couldn't retrive value + */ + std::string getThemeValue(const std::string_view value, const std::string_view fallback) const + { + return this->tbl.at_path(value).value<std::string>().value_or(fallback.data()); + } + + /** + * Get value of config array of string variables + * @param value The config variable "path" (e.g "config.gui-red") + * @param fallback Default value if couldn't retrive value + */ + std::vector<std::string> getValueArrayStr(const std::string_view value, const std::vector<std::string>& fallback); + +protected: + std::unordered_map<std::string, override_configs_types> overrides; + + // Parsed config from loadConfigFile() + toml::table tbl; +}; diff --git a/include/cufetch/cufetch.hh b/include/cufetch/cufetch.hh index f7d87132..5cb0b323 100644 --- a/include/cufetch/cufetch.hh +++ b/include/cufetch/cufetch.hh @@ -1,3 +1,5 @@ +#pragma once + #include <vector> #include "cufetch/common.hh" diff --git a/libcufetch/config.cc b/libcufetch/config.cc index 999d94aa..fbed698e 100644 --- a/libcufetch/config.cc +++ b/libcufetch/config.cc @@ -23,138 +23,18 @@ * */ -#include "config.hpp" +#include "cufetch/config.hh" -#include <cstdlib> -#include <filesystem> #include <string> - -#include "fmt/os.h" -#include "query.hpp" -#include "switch_fnv1a.hpp" +#include <vector> #include "util.hpp" -Config::Config(const std::filesystem::path& configFile, const std::filesystem::path& configDir) -{ - if (!std::filesystem::exists(configDir)) - { - warn(_("customfetch config folder was not found, Creating folders at {}!"), configDir.string()); - std::filesystem::create_directories(configDir); - } - - if (!std::filesystem::exists(configFile)) - { - warn(_("config file {} not found, generating new one"), configFile.string()); - this->generateConfig(configFile); - } -} - -void Config::loadConfigFile(const std::filesystem::path& filename) -{ - try - { - this->tbl = toml::parse_file(filename.string()); - } - catch (const toml::parse_error& err) - { - die(_("Parsing config file '{}' failed:\n" - "{}\n" - "\t(error occurred at line {} column {})"), - filename.string(), err.description(), - err.source().begin.line, err.source().begin.column); - } - - // clang-format off - // Idk but with `this->` looks more readable - this->layout = getValueArrayStr("config.layout", {}); - this->percentage_colors = getValueArrayStr("config.percentage-colors", {"green", "yellow", "red"}); - this->slow_query_warnings = getValue<bool>("config.slow-query-warnings", false); - this->sep_reset_after = getValue<bool>("config.sep-reset-after", false); - this->use_SI_unit = getValue<bool>("config.use-SI-byte-unit", false); - this->wrap_lines = getValue<bool>("config.wrap-lines", false); - this->offset = getValue<std::string>("config.offset", "5"); - this->logo_padding_left = getValue<std::uint16_t>("config.logo-padding-left", 0); - this->layout_padding_top = getValue<std::uint16_t>("config.layout-padding-top", 0); - this->logo_padding_top = getValue<std::uint16_t>("config.logo-padding-top", 0); - this->sep_reset = getValue<std::string>("config.sep-reset", ":"); - this->ascii_logo_type = getValue<std::string>("config.ascii-logo-type", ""); - this->source_path = getValue<std::string>("config.source-path", "os"); - this->logo_position = getValue<std::string>("config.logo-position", "left"); - this->data_dir = getValue<std::string>("config.data-dir", get_data_dir("customfetch")); - this->title_sep = getValue<std::string>("config.title-sep", "-"); - this->font = getValue<std::string>("gui.font", "Liberation Mono Normal 12"); - this->gui_bg_image = getValue<std::string>("gui.bg-image", "disable"); - - this->auto_disks_fmt = getValue<std::string>("auto.disk.fmt", "${auto}Disk (%1): $<disk(%1)>", true); - this->auto_disks_show_dupl= getValue<bool>("auto.disk.show-duplicated", false); - - this->uptime_d_fmt = getValue<std::string>("os.uptime.days", " days"); - this->uptime_h_fmt = getValue<std::string>("os.uptime.hours", " hours"); - this->uptime_m_fmt = getValue<std::string>("os.uptime.mins", " mins"); - this->uptime_s_fmt = getValue<std::string>("os.uptime.secs", " secs"); - - this->pkgs_managers= getValueArrayStr("os.pkgs.pkg-managers", {}); - this->pacman_dirs = getValueArrayStr("os.pkgs.pacman-dirs", {"/var/lib/pacman/local"}); - this->dpkg_files = getValueArrayStr("os.pkgs.dpkg-files", {"/var/lib/dpkg/status"}); - this->flatpak_dirs = getValueArrayStr("os.pkgs.flatpak-dirs", {"/var/lib/flatpak/app", "~/.local/share/flatpak/app"}); - this->apk_files = getValueArrayStr("os.pkgs.apk-files", {"/var/lib/apk/db/installed"}); - - colors.black = getThemeValue("config.black", "\033[1;30m"); - colors.red = getThemeValue("config.red", "\033[1;31m"); - colors.green = getThemeValue("config.green", "\033[1;32m"); - colors.yellow = getThemeValue("config.yellow", "\033[1;33m"); - colors.blue = getThemeValue("config.blue", "\033[1;34m"); - colors.magenta = getThemeValue("config.magenta", "\033[1;35m"); - colors.cyan = getThemeValue("config.cyan", "\033[1;36m"); - colors.white = getThemeValue("config.white", "\033[1;37m"); - - colors.gui_black = getThemeValue("gui.black", "!#000005"); - colors.gui_red = getThemeValue("gui.red", "!#ff2000"); - colors.gui_green = getThemeValue("gui.green", "!#00ff00"); - colors.gui_blue = getThemeValue("gui.blue", "!#00aaff"); - colors.gui_cyan = getThemeValue("gui.cyan", "!#00ffff"); - colors.gui_yellow = getThemeValue("gui.yellow", "!#ffff00"); - colors.gui_magenta = getThemeValue("gui.magenta", "!#ff11cc"); - colors.gui_white = getThemeValue("gui.white", "!#ffffff"); - - if (this->percentage_colors.size() < 3) - { - warn(_("the config array percentage-colors doesn't have 3 colors for being used in percentage tag and modules.\n" - "Backing up to green, yellow and red")); - this->percentage_colors = {"green", "yellow", "red"}; - } - - for (const std::string& str : this->getValueArrayStr("auto.disk.display-types", {"external", "regular", "read-only"})) - { - switch (fnv1a16::hash(str)) - { - case "removable"_fnv1a16: // deprecated - case "external"_fnv1a16: - this->auto_disks_types |= Query::DISK_VOLUME_TYPE_EXTERNAL; break; - case "regular"_fnv1a16: - this->auto_disks_types |= Query::DISK_VOLUME_TYPE_REGULAR; break; - case "read-only"_fnv1a16: - this->auto_disks_types |= Query::DISK_VOLUME_TYPE_READ_ONLY; break; - case "hidden"_fnv1a16: - this->auto_disks_types |= Query::DISK_VOLUME_TYPE_HIDDEN; break; - } - } - - for (const std::string& str : this->getValueArrayStr("config.alias-colors", {})) - this->addAliasColors(str); +template int ConfigBase::getValue<int>(const std::string_view, const int&&) const; +template std::string ConfigBase::getValue<std::string>(const std::string_view, const std::string&&) const; +template bool ConfigBase::getValue<bool>(const std::string_view, const bool&&) const; - const char *no_color = std::getenv("NO_COLOR"); - if (no_color != NULL && no_color[0] != '\0') - this->args_disable_colors = true; -} - -std::string Config::getThemeValue(const std::string_view value, const std::string_view fallback) const -{ - return this->tbl.at_path(value).value<std::string>().value_or(fallback.data()); -} - -std::vector<std::string> Config::getValueArrayStr(const std::string_view value, - const std::vector<std::string>& fallback) +std::vector<std::string> ConfigBase::getValueArrayStr(const std::string_view value, + const std::vector<std::string>& fallback) { std::vector<std::string> ret; @@ -177,67 +57,3 @@ std::vector<std::string> Config::getValueArrayStr(const std::string_view else return fallback; } - -void Config::addAliasColors(const std::string& str) -{ - const size_t pos = str.find('='); - if (pos == std::string::npos) - die(_("alias color '{}' does NOT have an equal sign '=' for separating color name and value\n" - "For more check with --help"), str); - - const std::string& name = str.substr(0, pos); - const std::string& value = str.substr(pos + 1); - - this->colors_name.push_back(name); - this->colors_value.push_back(value); -} - -static bool is_str_digital(const std::string& str) -{ - for (size_t i = 0; i < str.size(); ++i) - if (!(str[i] >= '0' && str[i] <= '9')) - return false; - - return true; -} - -void Config::overrideOption(const std::string& opt) -{ - const size_t pos = opt.find('='); - if (pos == std::string::npos) - die(_("override option '{}' does NOT have an equal sign '=' for separating config name and value\n" - "For more check with --help"), opt); - - std::string name {opt.substr(0, pos)}; - const std::string& value = opt.substr(pos + 1); - - // usually the user finds incovinient to write "config.foo" - // for general config options - if (name.find('.') == name.npos) - name.insert(0, "config."); - - if (value == "true") - overrides[name] = {.value_type = BOOL, .bool_value = true}; - else if (value == "false") - overrides[name] = {.value_type = BOOL, .bool_value = false}; - else if ((value[0] == '"' && value.back() == '"') || - (value[0] == '\'' && value.back() == '\'')) - overrides[name] = {.value_type = STR, .string_value = value.substr(1, value.size()-2)}; - else if (is_str_digital(value)) - overrides[name] = {.value_type = INT, .int_value = std::stoi(value)}; - else - die(_("looks like override value '{}' from '{}' is neither a bool, int or string value"), - value, name); -} - -void Config::generateConfig(const std::filesystem::path &filename) -{ - if (std::filesystem::exists(filename)) - { - if (!askUserYorN(false, "WARNING: config file '{}' already exists. Do you want to overwrite it?", filename.string())) - std::exit(1); - } - - auto f = fmt::output_file(filename.c_str()); - f.print("{}", AUTOCONFIG); -} diff --git a/libcufetch/parse.cc b/libcufetch/parse.cc index 2d5a319f..f5f1d645 100644 --- a/libcufetch/parse.cc +++ b/libcufetch/parse.cc @@ -41,7 +41,6 @@ #include "config.hpp" #include "fmt/color.h" #include "fmt/format.h" -#include "fmt/ranges.h" #include "query.hpp" #include "switch_fnv1a.hpp" #include "util.hpp" diff --git a/src/config.cpp b/src/config.cpp new file mode 100644 index 00000000..5b537559 --- /dev/null +++ b/src/config.cpp @@ -0,0 +1,218 @@ +/* + * Copyright 2025 Toni500git + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "config.hpp" + +#include <cstdlib> +#include <filesystem> +#include <string> + +#include "fmt/os.h" +#include "query.hpp" +#include "switch_fnv1a.hpp" +#include "util.hpp" + +Config::Config(const std::filesystem::path& configFile, const std::filesystem::path& configDir) +{ + if (!std::filesystem::exists(configDir)) + { + warn(_("customfetch config folder was not found, Creating folders at {}!"), configDir.string()); + std::filesystem::create_directories(configDir); + } + + if (!std::filesystem::exists(configFile)) + { + warn(_("config file {} not found, generating new one"), configFile.string()); + this->generateConfig(configFile); + } +} + +void Config::loadConfigFile(const std::filesystem::path& filename) +{ + try + { + this->tbl = toml::parse_file(filename.string()); + } + catch (const toml::parse_error& err) + { + die(_("Parsing config file '{}' failed:\n" + "{}\n" + "\t(error occurred at line {} column {})"), + filename.string(), err.description(), + err.source().begin.line, err.source().begin.column); + } + + // clang-format off + // Idk but with `this->` looks more readable + this->layout = getValueArrayStr("config.layout", {}); + this->percentage_colors = getValueArrayStr("config.percentage-colors", {"green", "yellow", "red"}); + this->slow_query_warnings = getValue<bool>("config.slow-query-warnings", false); + this->sep_reset_after = getValue<bool>("config.sep-reset-after", false); + this->use_SI_unit = getValue<bool>("config.use-SI-byte-unit", false); + this->wrap_lines = getValue<bool>("config.wrap-lines", false); + this->logo_padding_left = getValue<std::uint16_t>("config.logo-padding-left", 0); + this->layout_padding_top = getValue<std::uint16_t>("config.layout-padding-top", 0); + this->logo_padding_top = getValue<std::uint16_t>("config.logo-padding-top", 0); + this->offset = expandVar(getValue<std::string>("config.offset", "5")); + this->sep_reset = expandVar(getValue<std::string>("config.sep-reset", ":")); + this->ascii_logo_type = expandVar(getValue<std::string>("config.ascii-logo-type", "")); + this->source_path = expandVar(getValue<std::string>("config.source-path", "os")); + this->logo_position = expandVar(getValue<std::string>("config.logo-position", "left")); + this->data_dir = expandVar(getValue<std::string>("config.data-dir", get_data_dir("customfetch"))); + this->title_sep = expandVar(getValue<std::string>("config.title-sep", "-")); + this->font = expandVar(getValue<std::string>("gui.font", "Liberation Mono Normal 12")); + this->gui_bg_image = expandVar(getValue<std::string>("gui.bg-image", "disable")); + + this->auto_disks_fmt = getValue<std::string>("auto.disk.fmt", "${auto}Disk (%1): $<disk(%1)>"); + this->auto_disks_show_dupl= getValue<bool>("auto.disk.show-duplicated", false); + + this->uptime_d_fmt = expandVar(getValue<std::string>("os.uptime.days", " days")); + this->uptime_h_fmt = expandVar(getValue<std::string>("os.uptime.hours", " hours")); + this->uptime_m_fmt = expandVar(getValue<std::string>("os.uptime.mins", " mins")); + this->uptime_s_fmt = expandVar(getValue<std::string>("os.uptime.secs", " secs")); + + this->pkgs_managers= getValueArrayStr("os.pkgs.pkg-managers", {}); + this->pacman_dirs = getValueArrayStr("os.pkgs.pacman-dirs", {"/var/lib/pacman/local"}); + this->dpkg_files = getValueArrayStr("os.pkgs.dpkg-files", {"/var/lib/dpkg/status"}); + this->flatpak_dirs = getValueArrayStr("os.pkgs.flatpak-dirs", {"/var/lib/flatpak/app", "~/.local/share/flatpak/app"}); + this->apk_files = getValueArrayStr("os.pkgs.apk-files", {"/var/lib/apk/db/installed"}); + + colors.black = getThemeValue("config.black", "\033[1;30m"); + colors.red = getThemeValue("config.red", "\033[1;31m"); + colors.green = getThemeValue("config.green", "\033[1;32m"); + colors.yellow = getThemeValue("config.yellow", "\033[1;33m"); + colors.blue = getThemeValue("config.blue", "\033[1;34m"); + colors.magenta = getThemeValue("config.magenta", "\033[1;35m"); + colors.cyan = getThemeValue("config.cyan", "\033[1;36m"); + colors.white = getThemeValue("config.white", "\033[1;37m"); + + colors.gui_black = getThemeValue("gui.black", "!#000005"); + colors.gui_red = getThemeValue("gui.red", "!#ff2000"); + colors.gui_green = getThemeValue("gui.green", "!#00ff00"); + colors.gui_blue = getThemeValue("gui.blue", "!#00aaff"); + colors.gui_cyan = getThemeValue("gui.cyan", "!#00ffff"); + colors.gui_yellow = getThemeValue("gui.yellow", "!#ffff00"); + colors.gui_magenta = getThemeValue("gui.magenta", "!#ff11cc"); + colors.gui_white = getThemeValue("gui.white", "!#ffffff"); + + if (this->percentage_colors.size() < 3) + { + warn(_("the config array percentage-colors doesn't have 3 colors for being used in percentage tag and modules.\n" + "Backing up to green, yellow and red")); + this->percentage_colors = {"green", "yellow", "red"}; + } + + for (const std::string& str : this->getValueArrayStr("auto.disk.display-types", {"external", "regular", "read-only"})) + { + switch (fnv1a16::hash(str)) + { + case "removable"_fnv1a16: // deprecated + case "external"_fnv1a16: + this->auto_disks_types |= Query::DISK_VOLUME_TYPE_EXTERNAL; break; + case "regular"_fnv1a16: + this->auto_disks_types |= Query::DISK_VOLUME_TYPE_REGULAR; break; + case "read-only"_fnv1a16: + this->auto_disks_types |= Query::DISK_VOLUME_TYPE_READ_ONLY; break; + case "hidden"_fnv1a16: + this->auto_disks_types |= Query::DISK_VOLUME_TYPE_HIDDEN; break; + } + } + + for (const std::string& str : this->getValueArrayStr("config.alias-colors", {})) + this->addAliasColors(str); + + const char *no_color = std::getenv("NO_COLOR"); + if (no_color != NULL && no_color[0] != '\0') + this->args_disable_colors = true; +} + +void Config::addAliasColors(const std::string& str) +{ + const size_t pos = str.find('='); + if (pos == std::string::npos) + die(_("alias color '{}' does NOT have an equal sign '=' for separating color name and value\n" + "For more check with --help"), str); + + const std::string& name = str.substr(0, pos); + const std::string& value = str.substr(pos + 1); + + this->colors_name.push_back(name); + this->colors_value.push_back(value); +} + +static bool is_str_digital(const std::string& str) +{ + for (size_t i = 0; i < str.size(); ++i) + if (!(str[i] >= '0' && str[i] <= '9')) + return false; + + return true; +} + +void Config::overrideOption(const std::string& opt) +{ + const size_t pos = opt.find('='); + if (pos == std::string::npos) + die(_("override option '{}' does NOT have an equal sign '=' for separating config name and value\n" + "For more check with --help"), opt); + + std::string name {opt.substr(0, pos)}; + const std::string& value = opt.substr(pos + 1); + + // usually the user finds incovinient to write "config.foo" + // for general config options + if (name.find('.') == name.npos) + name.insert(0, "config."); + + if (value == "true") + overrides[name] = {.value_type = BOOL, .bool_value = true}; + else if (value == "false") + overrides[name] = {.value_type = BOOL, .bool_value = false}; + else if ((value[0] == '"' && value.back() == '"') || + (value[0] == '\'' && value.back() == '\'')) + overrides[name] = {.value_type = STR, .string_value = value.substr(1, value.size()-2)}; + else if (is_str_digital(value)) + overrides[name] = {.value_type = INT, .int_value = std::stoi(value)}; + else + die(_("looks like override value '{}' from '{}' is neither a bool, int or string value"), + value, name); +} + +void Config::overrideOption(const std::string& opt, const override_configs_types& option) +{ + overrides[opt] = option; +} + +void Config::generateConfig(const std::filesystem::path &filename) +{ + if (std::filesystem::exists(filename)) + { + if (!askUserYorN(false, "WARNING: config file '{}' already exists. Do you want to overwrite it?", filename.string())) + std::exit(1); + } + + auto f = fmt::output_file(filename.c_str()); + f.print("{}", AUTOCONFIG); +} diff --git a/src/main.cpp b/src/main.cpp index 8542a786..e67ee669 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -37,6 +37,7 @@ #include <vector> #include "config.hpp" +#include "cufetch/config.hh" #include "cufetch/cufetch.hh" #include "display.hpp" #include "fmt/base.h" @@ -460,21 +461,21 @@ static bool parseargs(int argc, char* argv[], Config& config, const std::filesys case "list-logos"_fnv1a16: list_logos(config.data_dir+"/ascii"); break; case 'f': - config.overrides["gui.font"] = {.value_type = STR, .string_value = optarg}; break; + config.overrideOption("gui.font", {.value_type = STR, .string_value = optarg}); break; case 'o': - config.overrides["config.offset"] = {.value_type = STR, .string_value = optarg}; break; + config.overrideOption("config.offset", {.value_type = STR, .string_value = optarg}); break; case 'C': // we have already did it in parse_config_path() break; case 'D': - config.overrides["config.data-dir"] = {.value_type = STR, .string_value = optarg}; break; + config.overrideOption("config.data-dir", {.value_type = STR, .string_value = optarg}); break; case 'd': config.args_custom_distro = str_tolower(optarg); break; case 'm': config.args_layout.push_back(optarg); break; case 'p': - config.overrides["config.logo-position"] = {.value_type = STR, .string_value = optarg}; break; + config.overrideOption("config.logo-position", {.value_type = STR, .string_value = optarg}); break; case 's': - config.overrides["config.source-path"] = {.value_type = STR, .string_value = optarg}; break; + config.overrideOption("config.source-path", {.value_type = STR, .string_value = optarg}); break; case 'i': config.args_image_backend = optarg; break; case 'O': @@ -482,7 +483,7 @@ static bool parseargs(int argc, char* argv[], Config& config, const std::filesys case 'N': config.args_disable_colors = true; break; case 'a': - config.overrides["config.ascii-logo-type"] = {.value_type = STR, .string_value = optarg}; break; + config.overrideOption("config.ascii-logo-type", {.value_type = STR, .string_value = optarg}); break; case 'n': config.args_disable_source = true; break; case 'L': @@ -492,13 +493,13 @@ static bool parseargs(int argc, char* argv[], Config& config, const std::filesys config.args_disallow_commands = true; break; case "logo-padding-top"_fnv1a16: - config.overrides["config.logo-padding-top"] = {.value_type = INT, .int_value = std::stoi(optarg)}; break; + config.overrideOption("config.logo-padding-top", {.value_type = INT, .int_value = std::stoi(optarg)}); break; case "logo-padding-left"_fnv1a16: - config.overrides["config.logo-padding-left"] = {.value_type = INT, .int_value = std::stoi(optarg)}; break; + config.overrideOption("config.logo-padding-left", {.value_type = INT, .int_value = std::stoi(optarg)}); break; case "layout-padding-top"_fnv1a16: - config.overrides["config.layout-padding-top"] = {.value_type = INT, .int_value = std::stoi(optarg)}; break; + config.overrideOption("config.layout-padding-top", {.value_type = INT, .int_value = std::stoi(optarg)}); break; case "loop-ms"_fnv1a16: config.loop_ms = std::stoul(optarg); break; @@ -511,13 +512,13 @@ static bool parseargs(int argc, char* argv[], Config& config, const std::filesys break; case "bg-image"_fnv1a16: - config.overrides["gui.bg-image"] = {.value_type = STR, .string_value = optarg}; break; + config.overrideOption("gui.bg-image", {.value_type = STR, .string_value = optarg}); break; case "wrap-lines"_fnv1a16: if (OPTIONAL_ARGUMENT_IS_PRESENT) - config.overrides["config.wrap-lines"] = {.value_type = BOOL, .bool_value = str_to_bool(optarg)}; + config.overrideOption("config.wrap-lines", {.value_type = BOOL, .bool_value = str_to_bool(optarg)}); else - config.overrides["config.wrap-lines"] = {.value_type = BOOL, .bool_value = true}; + config.overrideOption("config.wrap-lines", {.value_type = BOOL, .bool_value = true}); break; case "color"_fnv1a16: @@ -531,16 +532,16 @@ static bool parseargs(int argc, char* argv[], Config& config, const std::filesys exit(EXIT_SUCCESS); case "sep-reset"_fnv1a16: - config.overrides["config.sep-reset"] = {.value_type = STR, .string_value = optarg}; break; + config.overrideOption("config.sep-reset", {.value_type = STR, .string_value = optarg}); break; case "title-sep"_fnv1a16: - config.overrides["config.title-sep"] = {.value_type = STR, .string_value = optarg}; break; + config.overrideOption("config.title-sep", {.value_type = STR, .string_value = optarg}); break; case "sep-reset-after"_fnv1a16: if (OPTIONAL_ARGUMENT_IS_PRESENT) - config.overrides["config.sep-reset-after"] = {.value_type = BOOL, .bool_value = str_to_bool(optarg)}; + config.overrideOption("config.sep-reset-after", {.value_type = BOOL, .bool_value = str_to_bool(optarg)}); else - config.overrides["config.sep-reset-after"] = {.value_type = BOOL, .bool_value = true}; + config.overrideOption("config.sep-reset-after", {.value_type = BOOL, .bool_value = true}); break; default: @@ -625,9 +626,9 @@ int main(int argc, char *argv[]) continue; } - LOAD_LIB_SYMBOL(handle, void, start, void*) + LOAD_LIB_SYMBOL(handle, void, start, void*, const ConfigBase& config) - start(handle); + start(handle, config); plugins_handle.push_back(handle); } diff --git a/src/query/linux/utils/packages.cpp b/src/query/linux/utils/packages.cpp index a4607403..590280c5 100644 --- a/src/query/linux/utils/packages.cpp +++ b/src/query/linux/utils/packages.cpp @@ -25,6 +25,7 @@ #include "packages.hpp" +#include "util.hpp" #include <algorithm> #include <filesystem> #include <fstream> @@ -59,15 +60,15 @@ static size_t get_num_string_file(const std::string_view path, const std::string return ret; } +#define ADD_PKGS_COUNT(pkgman) \ + if (pkgs_count.pkgman > 0) \ + ret += fmt::format("{} ({}), ", pkgs_count.pkgman, #pkgman); + std::string get_all_pkgs(const Config& config) { std::string ret; pkgs_managers_count_t pkgs_count; -#define ADD_PKGS_COUNT(pkgman) \ - if (pkgs_count.pkgman > 0) \ - ret += fmt::format("{} ({}), ", pkgs_count.pkgman, #pkgman); - for (const std::string& name : config.pkgs_managers) { switch (fnv1a16::hash(name)) @@ -105,3 +106,5 @@ std::string get_all_pkgs(const Config& config) return ret; } + +#undef ADD_PKGS_COUNT From dbd1889da240ac31d1d535357de60f2919de21e0 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Mon, 30 Jun 2025 14:28:40 +0200 Subject: [PATCH 057/143] misc: libcufetch: some separations --- include/config.hpp | 122 +--------------------------------- include/core-modules.hh | 2 +- include/cufetch/common.hh | 49 ++------------ include/cufetch/config.hh | 133 +++++++++++++++++++++++++++++++++++-- include/cufetch/cufetch.hh | 39 ++++++++++- include/parse.hpp | 6 +- include/query.hpp | 8 +-- include/util.hpp | 2 +- src/main.cpp | 15 ++++- 9 files changed, 188 insertions(+), 188 deletions(-) diff --git a/include/config.hpp b/include/config.hpp index 56d01b72..ff9d0414 100644 --- a/include/config.hpp +++ b/include/config.hpp @@ -28,130 +28,10 @@ #undef TOML_HEADER_ONLY #define TOML_HEADER_ONLY 0 -#include <filesystem> +#include <string_view> #include "platform.hpp" #include "cufetch/config.hh" -class Config : public ConfigBase -{ -public:// Create .config directories and files and load the config file (args or default) - Config(const std::filesystem::path& configFile, const std::filesystem::path& configDir); - - // config colors - // those without gui_ prefix are for the terminal - struct colors_t - { - std::string black; - std::string red; - std::string green; - std::string blue; - std::string cyan; - std::string yellow; - std::string magenta; - std::string white; - - std::string gui_black; - std::string gui_red; - std::string gui_green; - std::string gui_blue; - std::string gui_cyan; - std::string gui_yellow; - std::string gui_magenta; - std::string gui_white; - } colors; - - // Variables of config file in [config] table - std::vector<std::string> layout; - std::vector<std::string> percentage_colors; - std::vector<std::string> colors_name, colors_value; - std::string source_path; - std::string font; - std::string data_dir; - std::string sep_reset; - std::string title_sep; - std::string gui_bg_image; - std::string ascii_logo_type; - std::string logo_position; - std::string offset; - std::uint16_t logo_padding_left = 0; - std::uint16_t logo_padding_top = 0; - std::uint16_t layout_padding_top = 0; - std::uint32_t loop_ms = 0; - bool sep_reset_after = false; - bool slow_query_warnings = false; - bool use_SI_unit = false; - bool wrap_lines = false; - - // Variables of config file for - // modules specific configs - // [auto.disk] - std::string auto_disks_fmt; - int auto_disks_types = 0; - bool auto_disks_show_dupl = false; - - // [os.uptime] - std::string uptime_d_fmt; - std::string uptime_h_fmt; - std::string uptime_m_fmt; - std::string uptime_s_fmt; - - // [os.pkgs] - std::vector<std::string> pkgs_managers; - std::vector<std::string> pacman_dirs; - std::vector<std::string> flatpak_dirs; - std::vector<std::string> dpkg_files; - std::vector<std::string> apk_files; - - // inner management / argument configs - std::vector<std::string> args_layout; - std::string args_custom_distro; - std::string args_image_backend; - std::uint16_t m_offset_calc = 0; - bool m_display_distro = true; - bool args_disable_source = false; - bool args_disable_colors = false; - bool args_disallow_commands = false; - bool args_print_logo_only = false; - - /** - * Load config file and parse every config variables - * @param filename The config file path - * @param colors The colors struct where we'll put the default config colors. - * It doesn't include the colors in config.alias-colors - */ - void loadConfigFile(const std::filesystem::path& filename); - - /** - * Generate the default config file at path - * @param filename The config file path - */ - void generateConfig(const std::filesystem::path& filename); - - /** - * Add alias values to colors_name and colors_value. - * @param str The alias color to add. - * Must have a '=' for separating color name and value, - * E.g "pink=!#FFC0CB" - */ - void addAliasColors(const std::string& str); - - /** - * Override a config value from --override - * @param str The value to override. - * Must have a '=' for separating the name and value to override. - * NO spaces between - */ - void overrideOption(const std::string& opt); - - /** - * Override a config value from --override - * @param str The value to override. - * Must have a '=' for separating the name and value to override. - * NO spaces between - */ - void overrideOption(const std::string& opt, const override_configs_types& option); -}; - // default config inline constexpr std::string_view AUTOCONFIG = R"#([config] diff --git a/include/core-modules.hh b/include/core-modules.hh index 95e3abae..1c36ceac 100644 --- a/include/core-modules.hh +++ b/include/core-modules.hh @@ -3,7 +3,7 @@ #include <pwd.h> #include <sys/utsname.h> -#include "cufetch/common.hh" +#include "cufetch/cufetch.hh" #define MODFUNC(name) const std::string name(__attribute__((unused)) const callbackInfo_t* callbackInfo = nullptr) diff --git a/include/cufetch/common.hh b/include/cufetch/common.hh index 65769c47..04583cc5 100644 --- a/include/cufetch/common.hh +++ b/include/cufetch/common.hh @@ -3,10 +3,6 @@ #include "fmt/color.h" #include "fmt/core.h" -#include <functional> -#include <string> -#include <vector> - constexpr const char NOCOLOR[] = "\033[0m"; constexpr const char NOCOLOR_BOLD[] = "\033[0m\033[1m"; constexpr const char UNKNOWN[] = "(unknown)"; @@ -19,6 +15,11 @@ constexpr const char UNKNOWN[] = "(unknown)"; // Every instance of this string in a layout line, the whole line will be erased. constexpr const char MAGIC_LINE[] = "(cut this line NOW!! RAHHH)"; +#define APICALL extern "C" +#define EXPORT __attribute__((visibility("default"))) +#define MOD_INIT void start +#define MOD_FINISH void finish + #define BOLD_COLOR(x) (fmt::emphasis::bold | fmt::fg(fmt::rgb(x))) #if DEBUG @@ -65,43 +66,3 @@ void info(const std::string_view fmt, Args&&... args) noexcept } #undef BOLD_COLOR - -#define APICALL extern "C" -#define EXPORT __attribute__((visibility("default"))) -#define MOD_INIT void start - -class Config; -struct module_t; - -// Map from a modules name to its pointer. -using moduleMap_t = std::unordered_map<std::string, const module_t&>; - -/* A linked list including module arguments. An argument may be specified for any part of the module path (e.g. - * `disk(/).used(GiB)`, `test(a).hi`) */ -struct moduleArgs_t -{ - struct moduleArgs_t* prev = nullptr; - - std::string name; - std::string value; - - struct moduleArgs_t* next = nullptr; -}; - -struct callbackInfo_t -{ - const moduleArgs_t* moduleArgs; - const moduleMap_t& modulesInfo; - const Config& config; -}; - -struct module_t -{ - std::string name; - std::string description; - std::vector<module_t> submodules; /* For best performance, use std::move() when adding modules in here. */ - std::function<const std::string(const callbackInfo_t*)> handler; -}; - -const std::string parse(const std::string& input, const moduleMap_t& modulesInfo, const Config& config); -const std::string get_and_color_percentage(const float n1, const float n2, const callbackInfo_t* callback, const bool invert); diff --git a/include/cufetch/config.hh b/include/cufetch/config.hh index 1f15693e..0665098e 100644 --- a/include/cufetch/config.hh +++ b/include/cufetch/config.hh @@ -1,14 +1,14 @@ #pragma once -#include <type_traits> +#include <string> +#include <filesystem> #include <unordered_map> -#include "cufetch/common.hh" -#ifndef TOML_HEADER_ONLY -# define TOML_HEADER_ONLY 1 -#endif +#define TOML_HEADER_ONLY 0 #include "toml++/toml.hpp" +#include "cufetch/common.hh" + enum types { STR, @@ -16,7 +16,7 @@ enum types INT }; -struct EXPORT override_configs_types +struct override_configs_types { types value_type; std::string string_value = ""; @@ -79,3 +79,124 @@ protected: // Parsed config from loadConfigFile() toml::table tbl; }; + +class EXPORT Config : public ConfigBase +{ +public: + // Create .config directories and files and load the config file (args or default) + Config(const std::filesystem::path& configFile, const std::filesystem::path& configDir); + + // config colors + // those without gui_ prefix are for the terminal + struct colors_t + { + std::string black; + std::string red; + std::string green; + std::string blue; + std::string cyan; + std::string yellow; + std::string magenta; + std::string white; + + std::string gui_black; + std::string gui_red; + std::string gui_green; + std::string gui_blue; + std::string gui_cyan; + std::string gui_yellow; + std::string gui_magenta; + std::string gui_white; + } colors; + + // Variables of config file in [config] table + std::vector<std::string> layout; + std::vector<std::string> percentage_colors; + std::vector<std::string> colors_name, colors_value; + std::string source_path; + std::string font; + std::string data_dir; + std::string sep_reset; + std::string title_sep; + std::string gui_bg_image; + std::string ascii_logo_type; + std::string logo_position; + std::string offset; + std::uint16_t logo_padding_left = 0; + std::uint16_t logo_padding_top = 0; + std::uint16_t layout_padding_top = 0; + std::uint32_t loop_ms = 0; + bool sep_reset_after = false; + bool slow_query_warnings = false; + bool use_SI_unit = false; + bool wrap_lines = false; + + // Variables of config file for + // modules specific configs + // [auto.disk] + std::string auto_disks_fmt; + int auto_disks_types = 0; + bool auto_disks_show_dupl = false; + + // [os.uptime] + std::string uptime_d_fmt; + std::string uptime_h_fmt; + std::string uptime_m_fmt; + std::string uptime_s_fmt; + + // [os.pkgs] + std::vector<std::string> pkgs_managers; + std::vector<std::string> pacman_dirs; + std::vector<std::string> flatpak_dirs; + std::vector<std::string> dpkg_files; + std::vector<std::string> apk_files; + + // inner management / argument configs + std::vector<std::string> args_layout; + std::string args_custom_distro; + std::string args_image_backend; + std::uint16_t m_offset_calc = 0; + bool m_display_distro = true; + bool args_disable_source = false; + bool args_disable_colors = false; + bool args_disallow_commands = false; + bool args_print_logo_only = false; + + /** + * Load config file and parse every config variables + * @param filename The config file path + * @param colors The colors struct where we'll put the default config colors. + * It doesn't include the colors in config.alias-colors + */ + void loadConfigFile(const std::filesystem::path& filename); + + /** + * Generate the default config file at path + * @param filename The config file path + */ + void generateConfig(const std::filesystem::path& filename); + + /** + * Add alias values to colors_name and colors_value. + * @param str The alias color to add. + * Must have a '=' for separating color name and value, + * E.g "pink=!#FFC0CB" + */ + void addAliasColors(const std::string& str); + + /** + * Override a config value from --override + * @param str The value to override. + * Must have a '=' for separating the name and value to override. + * NO spaces between + */ + void overrideOption(const std::string& opt); + + /** + * Override a config value from --override + * @param str The value to override. + * Must have a '=' for separating the name and value to override. + * NO spaces between + */ + void overrideOption(const std::string& opt, const override_configs_types& option); +}; diff --git a/include/cufetch/cufetch.hh b/include/cufetch/cufetch.hh index 5cb0b323..b5c5d9bd 100644 --- a/include/cufetch/cufetch.hh +++ b/include/cufetch/cufetch.hh @@ -1,8 +1,45 @@ #pragma once +#include <functional> +#include <string> #include <vector> -#include "cufetch/common.hh" +#include "cufetch/config.hh" + +struct module_t; + +// Map from a modules name to its pointer. +using moduleMap_t = std::unordered_map<std::string, const module_t&>; + +/* A linked list including module arguments. An argument may be specified for any part of the module path (e.g. + * `disk(/).used(GiB)`, `test(a).hi`) */ +struct moduleArgs_t +{ + struct moduleArgs_t* prev = nullptr; + + std::string name; + std::string value; + + struct moduleArgs_t* next = nullptr; +}; + +struct callbackInfo_t +{ + const moduleArgs_t* moduleArgs; + const moduleMap_t& modulesInfo; + const Config& config; +}; + +struct module_t +{ + std::string name; + std::string description; + std::vector<module_t> submodules; /* For best performance, use std::move() when adding modules in here. */ + std::function<const std::string(const callbackInfo_t*)> handler; +}; + +const std::string parse(const std::string& input, const moduleMap_t& modulesInfo, const Config& config); +const std::string get_and_color_percentage(const float n1, const float n2, const callbackInfo_t* callback, const bool invert); /* Register a module, and its submodules, to customfetch. */ void cfRegisterModule(const module_t& module); diff --git a/include/parse.hpp b/include/parse.hpp index 1c38c8d1..970564f6 100644 --- a/include/parse.hpp +++ b/include/parse.hpp @@ -29,11 +29,7 @@ #include <string> #include <vector> -#include "cufetch/common.hh" -#include "config.hpp" - -// Map from a modules name to its pointer. -using moduleMap_t = std::unordered_map<std::string, const module_t&>; +#include "cufetch/cufetch.hh" /* The additional args that parse() needs for getting the necessary infos/configs. * Only used for making the argument passing more clear. diff --git a/include/query.hpp b/include/query.hpp index d944fc52..76a6c353 100644 --- a/include/query.hpp +++ b/include/query.hpp @@ -29,12 +29,10 @@ #include <cstdint> #include <string> #include <fstream> -#include <unordered_map> #include <variant> #include <vector> -#include "config.hpp" -#include "cufetch/common.hh" +#include "parse.hpp" extern "C" { #if !CF_MACOS @@ -51,10 +49,6 @@ extern "C" { #include <unistd.h> } -struct parse_args_t; - -// Map from a modules name to its pointer. -using moduleMap_t = std::unordered_map<std::string, const module_t&>; // used in systemInfo_t most of the time using variant = std::variant<std::string, size_t, double>; diff --git a/include/util.hpp b/include/util.hpp index e584d981..f7add834 100644 --- a/include/util.hpp +++ b/include/util.hpp @@ -65,7 +65,7 @@ struct byte_units_t #endif /* lib = library to load (string) */ -#define LOAD_LIBRARY(lib) dlopen(lib, RTLD_LAZY); +#define LOAD_LIBRARY(lib) dlopen(lib, RTLD_NOW); /* handler = the library handle * ret_type = type of what the function returns diff --git a/src/main.cpp b/src/main.cpp index e67ee669..d61e29dc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -626,7 +626,13 @@ int main(int argc, char *argv[]) continue; } - LOAD_LIB_SYMBOL(handle, void, start, void*, const ConfigBase& config) + LOAD_LIB_SYMBOL(handle, void, start, void*, const ConfigBase& config); + if (dlerror()) + { + warn("Failed to load mod at {}: Missing function 'start'", entry.path().string()); + dlclose(handle); + continue; + } start(handle, config); plugins_handle.push_back(handle); @@ -724,7 +730,12 @@ int main(int argc, char *argv[]) core_plugins_finish(); for (void *handle : plugins_handle) { - LOAD_LIB_SYMBOL(handle, void, finish, void*) + LOAD_LIB_SYMBOL(handle, void, finish, void*); + if (dlerror()) + { + dlclose(handle); + continue; + } finish(handle); UNLOAD_LIBRARY(handle); From ba859d7f4f982eee96ed8286d577ee17aafe3b54 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Mon, 30 Jun 2025 17:38:10 +0200 Subject: [PATCH 058/143] misc: libcufetch: export some function + install statically linked version of {fmt} what a fucking pain in the ass --- Makefile | 3 ++- include/cufetch/cufetch.hh | 8 ++++---- include/{ => cufetch}/fmt/args.h | 0 include/{ => cufetch}/fmt/base.h | 0 include/{ => cufetch}/fmt/chrono.h | 0 include/{ => cufetch}/fmt/color.h | 0 include/{ => cufetch}/fmt/compile.h | 0 include/{ => cufetch}/fmt/core.h | 0 include/{ => cufetch}/fmt/format-inl.h | 0 include/{ => cufetch}/fmt/format.h | 0 include/{ => cufetch}/fmt/os.h | 0 include/{ => cufetch}/fmt/ostream.h | 0 include/{ => cufetch}/fmt/ranges.h | 0 include/{ => cufetch}/fmt/std.h | 0 libcufetch/Makefile | 8 ++++++-- libcufetch/cufetch.cc | 4 ++-- libcufetch/parse.cc | 23 +++++++++++------------ src/display.cpp | 1 - src/libs/fmt/CMakeLists.txt | 3 --- 19 files changed, 25 insertions(+), 25 deletions(-) rename include/{ => cufetch}/fmt/args.h (100%) rename include/{ => cufetch}/fmt/base.h (100%) rename include/{ => cufetch}/fmt/chrono.h (100%) rename include/{ => cufetch}/fmt/color.h (100%) rename include/{ => cufetch}/fmt/compile.h (100%) rename include/{ => cufetch}/fmt/core.h (100%) rename include/{ => cufetch}/fmt/format-inl.h (100%) rename include/{ => cufetch}/fmt/format.h (100%) rename include/{ => cufetch}/fmt/os.h (100%) rename include/{ => cufetch}/fmt/ostream.h (100%) rename include/{ => cufetch}/fmt/ranges.h (100%) rename include/{ => cufetch}/fmt/std.h (100%) diff --git a/Makefile b/Makefile index fe62e4f3..0dd80095 100644 --- a/Makefile +++ b/Makefile @@ -63,7 +63,7 @@ OBJ_CC = $(SRC_CC:.cc=.o) OBJ = $(OBJ_CPP) $(OBJ_CC) LDFLAGS += -Wl,-Bstatic $(BUILDDIR)/libfmt.a -Wl,-Bdynamic -lcufetch -ldl CXXFLAGS ?= -mtune=generic -march=native -CXXFLAGS += -fvisibility-inlines-hidden -fvisibility=hidden -Iinclude -std=c++20 $(VARS) -DVERSION=\"$(VERSION)\" -DLOCALEDIR=\"$(LOCALEDIR)\" -DICONPREFIX=\"$(ICONPREFIX)\" +CXXFLAGS += -fvisibility-inlines-hidden -fvisibility=hidden -Iinclude -Iinclude/cufetch -std=c++20 $(VARS) -DVERSION=\"$(VERSION)\" -DLOCALEDIR=\"$(LOCALEDIR)\" -DICONPREFIX=\"$(ICONPREFIX)\" all: genver fmt toml json libcufetch $(TARGET) @@ -140,6 +140,7 @@ install-common: libcufetch locale mkdir -p $(DESTDIR)$(PREFIX)/include/cufetch/ cd include/cufetch && find . -type f -exec install -Dm 644 "{}" "$(DESTDIR)$(PREFIX)/include/cufetch/{}" \; install -Dm 755 $(BUILDDIR)/libcufetch.so $(DESTDIR)$(PREFIX)/lib/libcufetch.so.1 + install -Dm 755 $(BUILDDIR)/libfmt.a $(DESTDIR)$(PREFIX)/lib/libcufetch-fmt.a ifeq ($(GUI_APP), 1) mkdir -p $(DESTDIR)$(APPPREFIX) cp -f $(NAME).desktop $(DESTDIR)$(APPPREFIX)/$(NAME).desktop diff --git a/include/cufetch/cufetch.hh b/include/cufetch/cufetch.hh index b5c5d9bd..6ef7670a 100644 --- a/include/cufetch/cufetch.hh +++ b/include/cufetch/cufetch.hh @@ -38,11 +38,11 @@ struct module_t std::function<const std::string(const callbackInfo_t*)> handler; }; -const std::string parse(const std::string& input, const moduleMap_t& modulesInfo, const Config& config); -const std::string get_and_color_percentage(const float n1, const float n2, const callbackInfo_t* callback, const bool invert); +APICALL EXPORT const std::string parse(const std::string& input, const moduleMap_t& modulesInfo, const Config& config); +APICALL EXPORT const std::string get_and_color_percentage(const float n1, const float n2, const callbackInfo_t* callback, const bool invert); /* Register a module, and its submodules, to customfetch. */ -void cfRegisterModule(const module_t& module); +APICALL EXPORT void cfRegisterModule(const module_t& module); /* Get a list of all modules registered. */ -const std::vector<module_t>& cfGetModules(); +APICALL EXPORT const std::vector<module_t>& cfGetModules(); diff --git a/include/fmt/args.h b/include/cufetch/fmt/args.h similarity index 100% rename from include/fmt/args.h rename to include/cufetch/fmt/args.h diff --git a/include/fmt/base.h b/include/cufetch/fmt/base.h similarity index 100% rename from include/fmt/base.h rename to include/cufetch/fmt/base.h diff --git a/include/fmt/chrono.h b/include/cufetch/fmt/chrono.h similarity index 100% rename from include/fmt/chrono.h rename to include/cufetch/fmt/chrono.h diff --git a/include/fmt/color.h b/include/cufetch/fmt/color.h similarity index 100% rename from include/fmt/color.h rename to include/cufetch/fmt/color.h diff --git a/include/fmt/compile.h b/include/cufetch/fmt/compile.h similarity index 100% rename from include/fmt/compile.h rename to include/cufetch/fmt/compile.h diff --git a/include/fmt/core.h b/include/cufetch/fmt/core.h similarity index 100% rename from include/fmt/core.h rename to include/cufetch/fmt/core.h diff --git a/include/fmt/format-inl.h b/include/cufetch/fmt/format-inl.h similarity index 100% rename from include/fmt/format-inl.h rename to include/cufetch/fmt/format-inl.h diff --git a/include/fmt/format.h b/include/cufetch/fmt/format.h similarity index 100% rename from include/fmt/format.h rename to include/cufetch/fmt/format.h diff --git a/include/fmt/os.h b/include/cufetch/fmt/os.h similarity index 100% rename from include/fmt/os.h rename to include/cufetch/fmt/os.h diff --git a/include/fmt/ostream.h b/include/cufetch/fmt/ostream.h similarity index 100% rename from include/fmt/ostream.h rename to include/cufetch/fmt/ostream.h diff --git a/include/fmt/ranges.h b/include/cufetch/fmt/ranges.h similarity index 100% rename from include/fmt/ranges.h rename to include/cufetch/fmt/ranges.h diff --git a/include/fmt/std.h b/include/cufetch/fmt/std.h similarity index 100% rename from include/fmt/std.h rename to include/cufetch/fmt/std.h diff --git a/libcufetch/Makefile b/libcufetch/Makefile index 8ad826ec..7c84fa06 100644 --- a/libcufetch/Makefile +++ b/libcufetch/Makefile @@ -13,8 +13,12 @@ all: libcufetch libcufetch: $(OBJ) $(FMT_STATIC) $(CXX) $(CXX_FLAGS) $(OBJ) $(CXX_INCLUDES) \ -Wl,-Bstatic $(FMT_STATIC) -Wl,-Bdynamic \ - -o libcufetch.so - mv -f libcufetch.so ../$(BUILDDIR)/$@.so + -Wl,--export-dynamic \ + -Wl,-soname,libcufetch.so.1 \ + -o libcufetch.so.1.0.0 + ln -sf libcufetch.so.1.0.0 libcufetch.so.1 + ln -sf libcufetch.so.1.0.0 libcufetch.so + mv -f libcufetch.so* ../$(BUILDDIR)/ clean: rm -f *.o *.so *.a ../$(BUILDDIR)/libcufetch.so diff --git a/libcufetch/cufetch.cc b/libcufetch/cufetch.cc index 9d564573..55512fc3 100644 --- a/libcufetch/cufetch.cc +++ b/libcufetch/cufetch.cc @@ -14,7 +14,7 @@ static void addModule(module_t module, const std::string& prefix = "") } /* Register a module, and its submodules, to customfetch. */ -void cfRegisterModule(const module_t& module) { addModule(module); } +APICALL EXPORT void cfRegisterModule(const module_t& module) { addModule(module); } /* Get a list of all modules registered. */ -const std::vector<module_t>& cfGetModules() { return modules; } +APICALL EXPORT const std::vector<module_t>& cfGetModules() { return modules; } diff --git a/libcufetch/parse.cc b/libcufetch/parse.cc index f5f1d645..f6f12dfa 100644 --- a/libcufetch/parse.cc +++ b/libcufetch/parse.cc @@ -38,7 +38,6 @@ #include <vector> #include "cufetch/common.hh" -#include "config.hpp" #include "fmt/color.h" #include "fmt/format.h" #include "query.hpp" @@ -203,13 +202,13 @@ static std::string convert_ansi_escape_rgb(const std::string_view noesc_str) } #endif -std::string parse(const std::string& input, std::string& _, parse_args_t& parse_args) +EXPORT std::string parse(const std::string& input, std::string& _, parse_args_t& parse_args) { return parse(input, parse_args.modulesInfo, _, parse_args.layout, parse_args.tmp_layout, parse_args.config, parse_args.parsingLayout, parse_args.no_more_reset); } -std::string parse(const std::string& input, parse_args_t& parse_args) +EXPORT std::string parse(const std::string& input, parse_args_t& parse_args) { return parse(input, parse_args.modulesInfo, parse_args.pureOutput, parse_args.layout, parse_args.tmp_layout, parse_args.config, parse_args.parsingLayout, parse_args.no_more_reset); @@ -243,13 +242,6 @@ std::string get_and_color_percentage(const float n1, const float n2, parse_args_ return parse(fmt::format("{}{:.2f}%${{0}}", color, result), _, parse_args); } -const std::string get_and_color_percentage(const float n1, const float n2, const callbackInfo_t* callback, const bool invert) -{ - std::vector<std::string> nah; - parse_args_t parse_args{ callback->modulesInfo, _, nah, nah, callback->config, true, true, true}; - return get_and_color_percentage(n1, n2, parse_args, invert); -} - const std::string getInfoFromName(const parse_args_t& parse_args, const std::string& moduleName) { std::string name; @@ -810,7 +802,7 @@ std::string parse(Parser& parser, parse_args_t& parse_args, const bool evaluate, return result; } -std::string parse(std::string input, const moduleMap_t& modulesInfo, std::string& pureOutput, +EXPORT std::string parse(std::string input, const moduleMap_t& modulesInfo, std::string& pureOutput, std::vector<std::string>& layout, std::vector<std::string>& tmp_layout, const Config& config, const bool parsingLayout, bool& no_more_reset) { @@ -849,13 +841,20 @@ std::string parse(std::string input, const moduleMap_t& modulesInfo, std::string return ret; } -const std::string parse(const std::string& input, const moduleMap_t& modulesInfo, const Config& config) +APICALL EXPORT const std::string parse(const std::string& input, const moduleMap_t& modulesInfo, const Config& config) { std::vector<std::string> nah; parse_args_t parse_args{ modulesInfo, _, nah, nah, config, true, true, true}; return parse(input, parse_args); } +APICALL EXPORT const std::string get_and_color_percentage(const float n1, const float n2, const callbackInfo_t* callback, const bool invert) +{ + std::vector<std::string> nah; + parse_args_t parse_args{ callback->modulesInfo, _, nah, nah, callback->config, true, true, true}; + return get_and_color_percentage(n1, n2, parse_args, invert); +} + // Re-enable them later // trying some plugins stuff #if 0 diff --git a/src/display.cpp b/src/display.cpp index 7b657ff0..da1ff3e9 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -54,7 +54,6 @@ #include <iostream> #include <vector> -#include "config.hpp" #include "core-modules.hh" #include "fmt/core.h" #include "fmt/format.h" diff --git a/src/libs/fmt/CMakeLists.txt b/src/libs/fmt/CMakeLists.txt index ab0077d4..1606e886 100644 --- a/src/libs/fmt/CMakeLists.txt +++ b/src/libs/fmt/CMakeLists.txt @@ -5,9 +5,6 @@ if (${CMAKE_VERSION} VERSION_LESS 3.12) cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}) endif () -# https://github.com/Toni500github/customfetch/issues/3 -set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--build-id=none") - # Determine if fmt is built as a subproject (using add_subdirectory) # or if it is the master project. if (NOT DEFINED FMT_MASTER_PROJECT) From 987dee3958ad0ff415e4c5770234061be4bad67e Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Mon, 30 Jun 2025 20:31:27 +0200 Subject: [PATCH 059/143] libcufetch: the handler function shall return 'std::string' instead of 'const std::string' 'const std::string' by value disables move semantics in some compilers and makes code less efficient --- include/core-modules.hh | 4 ++-- include/cufetch/cufetch.hh | 6 +++--- include/parse.hpp | 2 +- libcufetch/parse.cc | 6 +++--- src/core-plugins/linux/linux-core-modules.cc | 3 +-- 5 files changed, 10 insertions(+), 11 deletions(-) diff --git a/include/core-modules.hh b/include/core-modules.hh index 1c36ceac..4cca0e99 100644 --- a/include/core-modules.hh +++ b/include/core-modules.hh @@ -5,7 +5,7 @@ #include "cufetch/cufetch.hh" -#define MODFUNC(name) const std::string name(__attribute__((unused)) const callbackInfo_t* callbackInfo = nullptr) +#define MODFUNC(name) std::string name(__attribute__((unused)) const callbackInfo_t* callbackInfo = nullptr) // system.cc inline utsname g_uname_infos; @@ -89,4 +89,4 @@ MODFUNC(gpu_name); MODFUNC(gpu_vendor); #undef MODFUNC -#define MODFUNC(name) const std::string name(__attribute__((unused)) const callbackInfo_t* callbackInfo) +#define MODFUNC(name) std::string name(__attribute__((unused)) const callbackInfo_t* callbackInfo) diff --git a/include/cufetch/cufetch.hh b/include/cufetch/cufetch.hh index 6ef7670a..0116c7e4 100644 --- a/include/cufetch/cufetch.hh +++ b/include/cufetch/cufetch.hh @@ -35,11 +35,11 @@ struct module_t std::string name; std::string description; std::vector<module_t> submodules; /* For best performance, use std::move() when adding modules in here. */ - std::function<const std::string(const callbackInfo_t*)> handler; + std::function<std::string(const callbackInfo_t*)> handler; }; -APICALL EXPORT const std::string parse(const std::string& input, const moduleMap_t& modulesInfo, const Config& config); -APICALL EXPORT const std::string get_and_color_percentage(const float n1, const float n2, const callbackInfo_t* callback, const bool invert); +APICALL EXPORT std::string parse(const std::string& input, const moduleMap_t& modulesInfo, const Config& config); +APICALL EXPORT std::string get_and_color_percentage(const float n1, const float n2, const callbackInfo_t* callback, const bool invert); /* Register a module, and its submodules, to customfetch. */ APICALL EXPORT void cfRegisterModule(const module_t& module); diff --git a/include/parse.hpp b/include/parse.hpp index 970564f6..7cbca2ea 100644 --- a/include/parse.hpp +++ b/include/parse.hpp @@ -92,7 +92,7 @@ std::string parse(const std::string& input, std::string& _, parse_args_t& parse_ * @param parse_args The parse() like arguments * @param moduleName The module name */ -const std::string getInfoFromName(const parse_args_t& parse_args, const std::string& moduleName); +std::string getInfoFromName(const parse_args_t& parse_args, const std::string& moduleName); /* * Create a colored percentage from parse() diff --git a/libcufetch/parse.cc b/libcufetch/parse.cc index f6f12dfa..b75d816f 100644 --- a/libcufetch/parse.cc +++ b/libcufetch/parse.cc @@ -242,7 +242,7 @@ std::string get_and_color_percentage(const float n1, const float n2, parse_args_ return parse(fmt::format("{}{:.2f}%${{0}}", color, result), _, parse_args); } -const std::string getInfoFromName(const parse_args_t& parse_args, const std::string& moduleName) +std::string getInfoFromName(const parse_args_t& parse_args, const std::string& moduleName) { std::string name; name.reserve(moduleName.size()); @@ -841,14 +841,14 @@ EXPORT std::string parse(std::string input, const moduleMap_t& modulesInfo, std: return ret; } -APICALL EXPORT const std::string parse(const std::string& input, const moduleMap_t& modulesInfo, const Config& config) +APICALL EXPORT std::string parse(const std::string& input, const moduleMap_t& modulesInfo, const Config& config) { std::vector<std::string> nah; parse_args_t parse_args{ modulesInfo, _, nah, nah, config, true, true, true}; return parse(input, parse_args); } -APICALL EXPORT const std::string get_and_color_percentage(const float n1, const float n2, const callbackInfo_t* callback, const bool invert) +APICALL EXPORT std::string get_and_color_percentage(const float n1, const float n2, const callbackInfo_t* callback, const bool invert) { std::vector<std::string> nah; parse_args_t parse_args{ callback->modulesInfo, _, nah, nah, callback->config, true, true, true}; diff --git a/src/core-plugins/linux/linux-core-modules.cc b/src/core-plugins/linux/linux-core-modules.cc index 51f69a02..cb28b887 100644 --- a/src/core-plugins/linux/linux-core-modules.cc +++ b/src/core-plugins/linux/linux-core-modules.cc @@ -10,7 +10,6 @@ #include <string_view> #include <utility> -#include "config.hpp" #include "core-modules.hh" #include "cufetch/cufetch.hh" #include "fmt/format.h" @@ -18,7 +17,7 @@ using unused = const callbackInfo_t*; -const std::string amount(const double amount, const moduleArgs_t* moduleArgs) +std::string amount(const double amount, const moduleArgs_t* moduleArgs) { constexpr std::array<std::string_view, 32> sorted_valid_prefixes = { "B", "EB", "EiB", "GB", "GiB", "kB", "KiB", "MB", "MiB", "PB", "PiB", "TB", From 62df4b738bed85cfef7bb463bc2b885934a0a6d1 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Mon, 30 Jun 2025 20:45:50 +0200 Subject: [PATCH 060/143] libcufetch: revert back to original addModule() --- libcufetch/cufetch.cc | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/libcufetch/cufetch.cc b/libcufetch/cufetch.cc index 55512fc3..5a5b794c 100644 --- a/libcufetch/cufetch.cc +++ b/libcufetch/cufetch.cc @@ -4,13 +4,12 @@ static std::vector<module_t> modules; static char separator = '.'; -static void addModule(module_t module, const std::string& prefix = "") +static void addModule(const module_t& module, const std::string& prefix = "") { - module.name = prefix + module.name; - modules.push_back(module); // No std::move since we modify name first + modules.emplace_back(module).name = prefix + module.name; - for (module_t submodule : module.submodules) // Copy submodule to avoid reference issues - addModule(std::move(submodule), prefix + module.name + separator); + for (const module_t& submodule : module.submodules) + addModule(submodule, prefix + module.name + separator); } /* Register a module, and its submodules, to customfetch. */ From f2ad87512cff9f26761504d977d507e1ec9ed3b2 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Mon, 30 Jun 2025 20:56:51 +0200 Subject: [PATCH 061/143] core-plugins: linux: add os.pkgs --- src/core-plugins/linux/linux-core-modules.cc | 4 ++++ src/core-plugins/linux/os.cc | 6 +----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core-plugins/linux/linux-core-modules.cc b/src/core-plugins/linux/linux-core-modules.cc index cb28b887..db067016 100644 --- a/src/core-plugins/linux/linux-core-modules.cc +++ b/src/core-plugins/linux/linux-core-modules.cc @@ -10,6 +10,7 @@ #include <string_view> #include <utility> +#include "utils/packages.hpp" #include "core-modules.hh" #include "cufetch/cufetch.hh" #include "fmt/format.h" @@ -144,6 +145,8 @@ void core_plugins_start() std::move(os_initsys_version_module), }, [](unused) {return os_initsys_name() + " " + os_initsys_version();}}; + module_t os_pkgs_module = {"pkgs", "Count of system packages", {}, [](const callbackInfo_t* callback){ return get_all_pkgs(callback->config); }}; + // $<os> module_t os_module = { "os", "OS modules", { std::move(os_name_module), @@ -151,6 +154,7 @@ void core_plugins_start() std::move(os_kernel_module), std::move(os_hostname_module), std::move(os_initsys_module), + std::move(os_pkgs_module), }, NULL}; cfRegisterModule(os_module); diff --git a/src/core-plugins/linux/os.cc b/src/core-plugins/linux/os.cc index 2ead3e05..149ad7aa 100644 --- a/src/core-plugins/linux/os.cc +++ b/src/core-plugins/linux/os.cc @@ -5,7 +5,6 @@ #include <string> #include <string_view> -#define FMT_HEADER_ONLY 1 #include "cufetch/common.hh" #include "core-modules.hh" #include "fmt/format.h" @@ -47,7 +46,7 @@ static std::string read_value(const std::string_view name) return result; } -static unsigned long get_uptime() +unsigned long os_uptime() { const std::string& buf = read_by_syspath("/proc/uptime"); if (buf != UNKNOWN) @@ -75,9 +74,6 @@ MODFUNC(os_version_id) MODFUNC(os_version_codename) { return read_value("VERSION_CODENAME="); } -unsigned long os_uptime() -{ return get_uptime(); } - MODFUNC(os_kernel_name) { return g_uname_infos.sysname; } From 26cd038648cb000a52f4cc18ae785c77f0db8a30 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Mon, 30 Jun 2025 21:27:31 +0200 Subject: [PATCH 062/143] build: update cmake --- CMakeLists.txt | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b6f89c65..7d2b58fb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,8 +6,16 @@ cmake_minimum_required(VERSION 3.10) project(customfetch) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -ggdb3 -O0 -DDEBUG=1 -Wall -Wextra -Wpedantic -Wno-unused-parameter") +set(CMAKE_CXX_VISIBILITY_PRESET hidden) +set(CMAKE_VISIBILITY_INLINES_HIDDEN ON) include_directories(include) +include_directories(include/cufetch) + +set_source_files_properties( + "src/libs/toml++/toml.cpp" + PROPERTIES COMPILE_FLAGS "-fvisibility=default" +) file(GLOB SRC @@ -31,10 +39,6 @@ add_executable(${TARGET_NAME} ${SRC}) execute_process(COMMAND ./scripts/generateVersion.sh WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) -target_compile_definitions(${TARGET_NAME} PRIVATE - VERSION="1.0.0" -) - # https://github.com/libcpr/cpr/blob/5f475522597b8f3721e2440daddeced7a969f24c/CMakeLists.txt#L39 macro(add_option OPTION_NAME OPTION_TEXT OPTION_DEFAULT) option(${OPTION_NAME} ${OPTION_TEXT} ${OPTION_DEFAULT}) @@ -89,6 +93,7 @@ target_link_libraries(${TARGET_NAME} PUBLIC fmt) # libcufetch set(CUFETCH_HEADERS + include/cufetch/config.hh include/cufetch/common.hh include/cufetch/cufetch.hh ) @@ -103,7 +108,6 @@ set_target_properties(cufetch PROPERTIES VERSION 1.0.0 SOVERSION 1 OUTPUT_NAME "cufetch" - PUBLIC_HEADER "${CUFETCH_HEADERS}" POSITION_INDEPENDENT_CODE ON ) @@ -125,10 +129,12 @@ set(APPPREFIX "${CMAKE_INSTALL_PREFIX}/share/applications" CACHE PATH "Applicati set(LOCALEDIR "${CMAKE_INSTALL_PREFIX}/share/locale" CACHE PATH "Locale files directory") set(ICONPREFIX "${CMAKE_INSTALL_PREFIX}/share/pixmaps" CACHE PATH "Icon installation directory") target_compile_definitions(${TARGET_NAME} PRIVATE + VERSION="1.0.0" MANPREFIX="${MANPREFIX}" APPPREFIX="${APPPREFIX}" LOCALEDIR="${LOCALEDIR}" ICONPREFIX="${ICONPREFIX}" + $<$<BOOL:${GUI_APP}>:GUI_APP=1> ) # Install executable @@ -148,10 +154,20 @@ install(FILES ${CMAKE_SOURCE_DIR}/LICENSE DESTINATION share/licenses/customfetch COMPONENT documentation) +install(FILES $<TARGET_FILE:fmt> + DESTINATION lib + RENAME libcufetch-fmt.a + COMPONENT runtime +) + install(TARGETS cufetch - LIBRARY DESTINATION lib - PUBLIC_HEADER DESTINATION include/cufetch - COMPONENT runtime + LIBRARY DESTINATION lib + COMPONENT runtime +) + +install(DIRECTORY include/cufetch/ + DESTINATION include/cufetch + COMPONENT development ) install(DIRECTORY ${CMAKE_SOURCE_DIR}/assets/ascii/ From 7827407224eb8817f86cf2b5a5cf9e781eeb117f Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Mon, 30 Jun 2025 21:29:55 +0200 Subject: [PATCH 063/143] misc: remove VENDOR_TEST and DEVICE_TEST holy crap I wonder how much time these were there --- .github/workflows/makefile.yml | 2 +- Makefile | 12 +----------- src/main.cpp | 22 +--------------------- 3 files changed, 3 insertions(+), 33 deletions(-) diff --git a/.github/workflows/makefile.yml b/.github/workflows/makefile.yml index d0a3db03..197eb457 100644 --- a/.github/workflows/makefile.yml +++ b/.github/workflows/makefile.yml @@ -232,7 +232,7 @@ jobs: run: make distclean - name: Compile and install - run: make install DEBUG=1 VENDOR_TEST=1 GUI_APP=0 + run: make install DEBUG=1 GUI_APP=0 - name: Test fastfetch run: fastfetch diff --git a/Makefile b/Makefile index 0dd80095..0cb9ea1a 100644 --- a/Makefile +++ b/Makefile @@ -9,10 +9,8 @@ VARS ?= -DENABLE_NLS=1 DEBUG ?= 1 GUI_APP ?= 0 -VENDOR_TEST ?= 0 -DEVICE_TEST ?= 0 - USE_DCONF ?= 1 + # https://stackoverflow.com/a/1079861 # WAY easier way to build debug and release builds ifeq ($(DEBUG), 1) @@ -29,14 +27,6 @@ else BUILDDIR = build/release endif -ifeq ($(VENDOR_TEST), 1) - VARS += -DVENDOR_TEST=1 -endif - -ifeq ($(DEVICE_TEST), 1) - VARS += -DDEVICE_TEST=1 -endif - ifeq ($(GUI_APP), 1) TARGET = $(NAME)-gui VARS += -DGUI_APP=1 diff --git a/src/main.cpp b/src/main.cpp index d61e29dc..1b51cb2b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -575,31 +575,11 @@ static void localize(void) #endif } +// clang-format on void core_plugins_start(); void core_plugins_finish(); int main(int argc, char *argv[]) { - -#ifdef VENDOR_TEST - // test - fmt::println("=== VENDOR TEST! ==="); - - fmt::println("Intel: {}", binarySearchPCIArray("8086")); - fmt::println("AMD: {}", binarySearchPCIArray("1002")); - fmt::println("NVIDIA: {}", binarySearchPCIArray("10de")); -#endif - -#ifdef DEVICE_TEST - // test - fmt::println("=== DEVICE TEST! ==="); - - fmt::println("an Intel iGPU: {}", binarySearchPCIArray("8086", "0f31")); - fmt::println("RX 7700 XT: {}", binarySearchPCIArray("1002", "747e")); - fmt::println("GTX 1650: {}", binarySearchPCIArray("10de", "1f0a")); - fmt::println("?: {}", binarySearchPCIArray("1414", "0006")); -#endif - - // clang-format on const std::filesystem::path& configDir = getConfigDir(); const std::filesystem::path& configFile = parse_config_path(argc, argv, configDir); From a70e64064a912e21266d3f008e188f2b49b39c4d Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Wed, 2 Jul 2025 19:07:11 +0200 Subject: [PATCH 064/143] libcufetch: move toml++ there and force users to specify the template name of the config to retrive --- include/cufetch/config.hh | 2 +- include/{ => cufetch}/toml++/toml.hpp | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename include/{ => cufetch}/toml++/toml.hpp (100%) diff --git a/include/cufetch/config.hh b/include/cufetch/config.hh index 0665098e..5c1b11e2 100644 --- a/include/cufetch/config.hh +++ b/include/cufetch/config.hh @@ -34,7 +34,7 @@ public: * @param fallback Default value if couldn't retrive value */ template <typename T> - T getValue(const std::string_view value, const T&& fallback) const + T&& getValue(const std::string_view value, const T&& fallback) const { const auto& overridePos = overrides.find(value.data()); diff --git a/include/toml++/toml.hpp b/include/cufetch/toml++/toml.hpp similarity index 100% rename from include/toml++/toml.hpp rename to include/cufetch/toml++/toml.hpp From 89a164e0d20f8ea02b0312ef33657623405e59d4 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Sat, 5 Jul 2025 16:43:02 +0200 Subject: [PATCH 065/143] nvm sorry for the long pause --- include/cufetch/config.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/cufetch/config.hh b/include/cufetch/config.hh index 5c1b11e2..0665098e 100644 --- a/include/cufetch/config.hh +++ b/include/cufetch/config.hh @@ -34,7 +34,7 @@ public: * @param fallback Default value if couldn't retrive value */ template <typename T> - T&& getValue(const std::string_view value, const T&& fallback) const + T getValue(const std::string_view value, const T&& fallback) const { const auto& overridePos = overrides.find(value.data()); From 7a40532d63672ee10b37d2c8d8949cac86735958 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Sat, 5 Jul 2025 17:40:11 +0200 Subject: [PATCH 066/143] misc: rename mods -> plugins references "mod" is kinda too ambiguous and carries a different connotation (like game mods or visual tweaks). Thus rebrading to "Plugin-based Module Loader" makes more sense --- include/cufetch/common.hh | 4 ++-- include/display.hpp | 6 +++--- src/display.cpp | 4 ++-- src/gui.cpp | 1 - src/libs/toml++/Makefile | 2 +- src/main.cpp | 15 +++++++-------- 6 files changed, 15 insertions(+), 17 deletions(-) diff --git a/include/cufetch/common.hh b/include/cufetch/common.hh index 04583cc5..6cbf05ca 100644 --- a/include/cufetch/common.hh +++ b/include/cufetch/common.hh @@ -17,8 +17,8 @@ constexpr const char MAGIC_LINE[] = "(cut this line NOW!! RAHHH)"; #define APICALL extern "C" #define EXPORT __attribute__((visibility("default"))) -#define MOD_INIT void start -#define MOD_FINISH void finish +#define PLUGIN_INIT void start +#define PLUGIN_FINISH void finish #define BOLD_COLOR(x) (fmt::emphasis::bold | fmt::fg(fmt::rgb(x))) diff --git a/include/display.hpp b/include/display.hpp index af7a0124..e2e6330b 100644 --- a/include/display.hpp +++ b/include/display.hpp @@ -29,9 +29,9 @@ #include <string> #include <vector> -#include "config.hpp" +#include "cufetch/config.hh" +#include "cufetch/cufetch.hh" #include "platform.hpp" -#include "query.hpp" #if CF_MACOS constexpr std::string_view ascii_logo = @@ -89,7 +89,7 @@ namespace Display * @param path Path to source file */ std::vector<std::string> render(const Config& config, const bool already_analyzed_path, - const std::filesystem::path& path, moduleMap_t& moduleMap); + const std::filesystem::path& path, const moduleMap_t& moduleMap); /* * Display the rendered result (or just display a normal vector of string diff --git a/src/display.cpp b/src/display.cpp index da1ff3e9..56ff9d45 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -94,7 +94,7 @@ std::string Display::detect_distro(const Config& config) #endif } -static std::vector<std::string> render_with_image(moduleMap_t& modulesInfo, std::vector<std::string>& layout, +static std::vector<std::string> render_with_image(const moduleMap_t& modulesInfo, std::vector<std::string>& layout, const Config& config, const std::filesystem::path& path, const std::uint16_t font_width, const std::uint16_t font_height) { @@ -221,7 +221,7 @@ static bool get_pos(int& y, int& x) } std::vector<std::string> Display::render(const Config& config, const bool already_analyzed_file, - const std::filesystem::path& path, moduleMap_t& moduleMap) + const std::filesystem::path& path, const moduleMap_t& moduleMap) { std::vector<std::string> asciiArt{}, layout{ config.args_layout.empty() ? config.layout : config.args_layout }; diff --git a/src/gui.cpp b/src/gui.cpp index 3dd572fa..f69d5930 100644 --- a/src/gui.cpp +++ b/src/gui.cpp @@ -34,7 +34,6 @@ #include <filesystem> #include <fstream> -#include "config.hpp" #include "display.hpp" #include "fmt/ranges.h" #include "gdkmm/pixbufanimation.h" diff --git a/src/libs/toml++/Makefile b/src/libs/toml++/Makefile index f39d1998..148dc641 100644 --- a/src/libs/toml++/Makefile +++ b/src/libs/toml++/Makefile @@ -1,7 +1,7 @@ CXX ?= g++ SRC = toml.cpp TARGET = toml.o -CXXFLAGS = -I../../../include -fPIE -std=c++20 +CXXFLAGS = -I../../../include/cufetch -fPIE -std=c++20 all: $(TARGET) diff --git a/src/main.cpp b/src/main.cpp index 1b51cb2b..c3c64124 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -36,7 +36,6 @@ #include <thread> #include <vector> -#include "config.hpp" #include "cufetch/config.hh" #include "cufetch/cufetch.hh" #include "display.hpp" @@ -591,25 +590,25 @@ int main(int argc, char *argv[]) /* TODO(burntranch): track each library and unload them. */ core_plugins_start(); - const std::filesystem::path modDir = configDir / "mods"; - std::filesystem::create_directories(modDir); - for (const auto& entry : std::filesystem::directory_iterator{ modDir }) + const std::filesystem::path plguinDir = configDir / "plugins"; + std::filesystem::create_directories(plguinDir); + for (const auto& entry : std::filesystem::directory_iterator{ plguinDir }) { - debug("loading mod at {}!", entry.path().string()); + debug("loading plugin at {}!", entry.path().string()); void* handle = LOAD_LIBRARY(std::filesystem::absolute(entry.path()).c_str()); if (!handle) { // dlerror() is pretty formatted - warn("Failed to load mod at {}: {}", entry.path().string(), dlerror()); + warn("Failed to load plugin at {}: {}", entry.path().string(), dlerror()); dlerror(); continue; } - LOAD_LIB_SYMBOL(handle, void, start, void*, const ConfigBase& config); + LOAD_LIB_SYMBOL(handle, void, start, void*, const ConfigBase&); if (dlerror()) { - warn("Failed to load mod at {}: Missing function 'start'", entry.path().string()); + warn("Failed to load plugin at {}: Missing function 'start'", entry.path().string()); dlclose(handle); continue; } From f6a56cf2bef24f7dbeace3851e534fb018fcedaf Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Sat, 5 Jul 2025 20:11:08 +0200 Subject: [PATCH 067/143] docs: fix some -h incorrections --- src/display.cpp | 11 +++-------- src/main.cpp | 37 ++++++++++++++++++++----------------- 2 files changed, 23 insertions(+), 25 deletions(-) diff --git a/src/display.cpp b/src/display.cpp index 56ff9d45..ee0b23ab 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -393,7 +393,7 @@ std::vector<std::string> Display::render(const Config& config, const bool alread size_t origin = config.logo_padding_left; // The user-specified offset to be put before the logo - for (size_t j = 0; j < config.logo_padding_left; j++) + for (size_t j = 0; j < config.logo_padding_left; ++j) layout.at(i).insert(0, " "); if (i < asciiArt.size()) @@ -416,14 +416,9 @@ std::vector<std::string> Display::render(const Config& config, const bool alread #endif } - for (; i < asciiArt.size(); i++) + for (; i < asciiArt.size(); ++i) { - std::string line; - line.reserve(config.logo_padding_left + asciiArt.at(i).length()); - - for (size_t j = 0; j < config.logo_padding_left; j++) - line += " "; - + std::string line{" ", config.logo_padding_left + asciiArt.at(i).length()}; line += asciiArt.at(i); layout.push_back(line); diff --git a/src/main.cpp b/src/main.cpp index c3c64124..8a083573 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -101,20 +101,20 @@ NOTE: Boolean flags [<BOOL>] accept: "true", 1, "enable", or empty. Any other va GENERAL OPTIONS: -h, --help Print this help menu. - -V, --version Print version and Git branch info. - -C, --config <PATH> Path to the config file (default: ~/.config/customfetch.conf). + -V, --version Print version and other infos about the build. + -C, --config <PATH> Path to the config file (default: ~/.config/customfetch/config.toml). --gen-config [<PATH>] Generate default config file. If PATH is omitted, saves to default location. Prompts before overwriting. LOGO OPTIONS: -n, --no-logo Disable logo display. - -L, --logo-only Print only the logo (skip info layout). + -L, --logo-only Print only the logo (skip layout completely). -s, --source-path <PATH> Path to custom ASCII art/image file. -a, --ascii-logo-type <TYPE> Type of ASCII art (typically "small", "old", or empty for default). - Example: "--ascii-logo-type small" looks for "logo_small.txt". + Example: "-d arch -a older" looks for "arch_older.txt". -D, --data-dir <PATH> Path to data directory containing "ascii/" subfolder with distro logos. -d, --distro <NAME> Use a custom distro logo (case-insensitive, e.g., "windows 11" or "ArCh"). @@ -128,35 +128,35 @@ LAYOUT & FORMATTING: Example: `-m "${auto}OS: $<os.name>" -m "${auto}CPU: $<cpu>"`. -N, --no-color Disable all colors (useful for pipes/scripts). - --wrap-lines=[<BOOL>] Enable line wrapping (default: false). - --title-sep <STRING> String to use for $<title_sep> (default: "-"). + --wrap-lines=[<BOOL>] Enable terminal line wrapping (default: false). + --title-sep <STRING> String to use for $<title.sep> (default: "-"). --sep-reset <STRING> String that resets color (default: ":"). --sep-reset-after=[<BOOL>] Reset color after (default) or before 'sep-reset'. GUI/TERMINAL OPTIONS: -f, --font <STRING> GUI font (format: "FAMILY STYLE SIZE", e.g., "Liberation Mono Normal 12"). - -i, --image-backend <NAME> (Experimental) Terminal image backend ("kitty" or "viu"). + -i, --image-backend <NAME> Terminal image backend ("kitty" or "viu"). --bg-image <PATH> GUI background image path ("disable" to turn off). -ADVANCED/CONFIG: +CONFIG: -O, --override <STRING> Override a config value (non-array). Syntax: "name=value" (no spaces around "="). Example: "auto.disk.fmt='Disk(%1): %6'". - Note: Names without dots (e.g., "sep-reset-after") gets mapped to "config.<name>". + Note: Names without dots (e.g., "sep-reset-after") gets auto-appended to "config.". - --color <STRING> Replace a color globally. Syntax: "name=hex" (no spaces around "="). + --color <STRING> Replace a color globally. Syntax: "name=value" (no spaces around "="). Example: "--color magenta=#FF00FF". - --disallow-command-tag Do not allow command tags $() to be executed in the config or -m args. + --disallow-command-tag Do not allow command tags $() to be executed. This is a safety measure for preventing malicious code to be executed because you didn't want to check the config first. INFORMATIONAL: -l, --list-modules List all available info tag modules (e.g., $<cpu> or $<os.name>). - -w, --how-it-works Explain layout variables and customization. + -w, --how-it-works Explain tags and general customization. --list-logos List available ASCII logos in --data-dir. LIVE MODE: --loop-ms <NUM> Run in live mode, updating every <NUM> milliseconds (min: 50). - Use 0 to disable (default). + Use inferior <NUM> than 50 to disable (default). EXAMPLES: 1. Minimal output with default logo: @@ -208,7 +208,9 @@ static void modules_list() fmt::print("{:<6} \t- {}", parts[depth], module.description); } else + { fmt::print(" "); + } } fmt::print("\n"); @@ -257,7 +259,7 @@ Tag References: Examples: - $[$<user.name>,toni,Welcome back!,Access denied] - $[$(date +%m-%d),12-25,Merry Christmas!,] - - $[$<os.name_id>,arch,${green}I use arch btw,${red}Non-arch user] + - $[$<os.name.id>,arch,${green}I use arch btw,${red}Non-arch user] 4. Color Tag (${}) Applies colors and text formatting. @@ -270,7 +272,7 @@ Tag References: - Special colors: ${auto} (uses logo colors) - Reset styles: ${0} (normal), ${1} (bold reset) - Formatting modifiers (prefix before color): + Formatting modifiers (prefix before hexcolor): - ! = Bold - u = Underline - i = Italic @@ -341,7 +343,7 @@ A: Yes! Complex nesting is supported, for example: // @param data_dir The data directory static void list_logos(const std::string& data_dir) { - debug("data = {}", data_dir); + debug("data-dir = {}", data_dir); if (access(data_dir.c_str(), F_OK) != 0) die("failed to access data directory '{}'", data_dir); @@ -354,7 +356,8 @@ static void list_logos(const std::string& data_dir) std::sort(list.begin(), list.end()); - fmt::print("{}\n", fmt::join(list, "\n")); + fmt::print("{}", fmt::join(list, "\n")); + fmt::print("\n"); std::exit(EXIT_SUCCESS); } From 00bd2ee4ab9701090f5dea9f1476b886632412c1 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Mon, 7 Jul 2025 00:28:24 +0200 Subject: [PATCH 068/143] gui: add gtk css support --- include/config.hpp | 12 ++++----- include/cufetch/config.hh | 1 + include/gui.hpp | 9 +++---- src/config.cpp | 1 + src/gui.cpp | 52 +++++++++++++++++++++++---------------- src/main.cpp | 32 +++++++++++++----------- 6 files changed, 60 insertions(+), 47 deletions(-) diff --git a/include/config.hpp b/include/config.hpp index ff9d0414..06745d01 100644 --- a/include/config.hpp +++ b/include/config.hpp @@ -211,15 +211,9 @@ apk-files = ["/var/lib/apk/db/installed"] # Desktop/Android app options [gui] -# Font to be used -# syntax must be [FAMILY-LIST] [STYLE-OPTIONS] [SIZE] -# e.g "Liberation Mono Normal 12" -# check https://lazka.github.io/pgi-docs/Pango-1.0/classes/FontDescription.html#Pango.FontDescription for more infos -font = "Liberation Mono Normal 12" - # These are the colors you can use in the GUI mode. # They overwrite the terminal colors from above. -# They can only have hexcodes colors +# They can only have hexcodes colors and its modifiers black = "!#000005" red = "!#ff2000" green = "!#00ff00" @@ -233,6 +227,10 @@ white = "!#ffffff" # put "disable" for disabling and use the theme color as background. bg-image = "disable" +# Path to gtk css file to be used. +# put "disable" for disabling. +gtk-css = "disable" + )#"; #endif // _CONFIG_HPP diff --git a/include/cufetch/config.hh b/include/cufetch/config.hh index 0665098e..64d023a5 100644 --- a/include/cufetch/config.hh +++ b/include/cufetch/config.hh @@ -118,6 +118,7 @@ public: std::string data_dir; std::string sep_reset; std::string title_sep; + std::string gui_css_file; std::string gui_bg_image; std::string ascii_logo_type; std::string logo_position; diff --git a/include/gui.hpp b/include/gui.hpp index df5f1af3..5496bfd5 100644 --- a/include/gui.hpp +++ b/include/gui.hpp @@ -26,10 +26,9 @@ #ifndef _GUI_HPP #define _GUI_HPP -#include "query.hpp" #if GUI_APP -#include "config.hpp" +#include "cufetch/cufetch.hh" #include "gdkmm/pixbuf.h" #include "gdkmm/pixbufanimation.h" #include "gtkmm/alignment.h" @@ -51,15 +50,15 @@ class Window : public Gtk::Window * @param config The config class * @param path The logo source path */ - Window(const Config& config, const std::filesystem::path& path, moduleMap_t& moduleMap); + Window(const Config& config, const std::filesystem::path& path, const moduleMap_t& moduleMap); // Destroy the window, handled by GTK virtual ~Window(); private: const Config& m_config; const std::filesystem::path& m_path; - moduleMap_t& m_moduleMap; - bool isImage; + const moduleMap_t& m_moduleMap; + bool m_isImage; Gtk::Overlay m_overlay; Gtk::Box m_box; diff --git a/src/config.cpp b/src/config.cpp index 5b537559..0fa3f69d 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -84,6 +84,7 @@ void Config::loadConfigFile(const std::filesystem::path& filename) this->title_sep = expandVar(getValue<std::string>("config.title-sep", "-")); this->font = expandVar(getValue<std::string>("gui.font", "Liberation Mono Normal 12")); this->gui_bg_image = expandVar(getValue<std::string>("gui.bg-image", "disable")); + this->gui_css_file = expandVar(getValue<std::string>("gui.gtk-css", "disable")); this->auto_disks_fmt = getValue<std::string>("auto.disk.fmt", "${auto}Disk (%1): $<disk(%1)>"); this->auto_disks_show_dupl= getValue<bool>("auto.disk.show-duplicated", false); diff --git a/src/gui.cpp b/src/gui.cpp index f69d5930..32e6f8d8 100644 --- a/src/gui.cpp +++ b/src/gui.cpp @@ -34,17 +34,20 @@ #include <filesystem> #include <fstream> +#include "cufetch/config.hh" #include "display.hpp" #include "fmt/ranges.h" -#include "gdkmm/pixbufanimation.h" -#include "glibmm/main.h" -#include "gtkmm/enums.h" -#include "pangomm/fontdescription.h" #include "parse.hpp" #include "query.hpp" #include "stb_image.h" #include "util.hpp" +#include "gdkmm/pixbufanimation.h" +#include "glibmm/refptr.h" +#include "gtkmm/cssprovider.h" +#include "glibmm/main.h" +#include "gtkmm/enums.h" + using namespace GUI; // https://www.codespeedy.com/convert-rgb-to-hex-color-code-in-cpp/ @@ -129,7 +132,7 @@ static std::vector<std::string> render_with_image(const Config& config) bool Window::set_layout_markup() { - if (isImage) + if (m_isImage) { if (!m_config.args_print_logo_only) m_label.set_markup(fmt::format("{}", fmt::join(render_with_image(m_config), "\n"))); @@ -141,8 +144,8 @@ bool Window::set_layout_markup() return true; } -Window::Window(const Config& config, const std::filesystem::path& path, moduleMap_t& moduleMap) - : m_config(config), m_path(path), m_moduleMap(moduleMap), isImage(false) +Window::Window(const Config& config, const std::filesystem::path& path, const moduleMap_t& moduleMap) + : m_config(config), m_path(path), m_moduleMap(moduleMap), m_isImage(false) { set_title("customfetch - Higly customizable and fast neofetch like program"); set_default_size(1000, 600); @@ -154,10 +157,10 @@ Window::Window(const Config& config, const std::filesystem::path& path, moduleMa std::array<unsigned char, 32> buffer; f.read(reinterpret_cast<char*>(&buffer.at(0)), buffer.size()); if (is_file_image(buffer.data())) - isImage = true; + m_isImage = true; // useImage can be either a gif or an image - if (isImage && !config.args_disable_source) + if (m_isImage && !config.args_disable_source) { const auto& img = Gdk::PixbufAnimation::create_from_file(path.c_str()); m_img = Gtk::manage(new Gtk::Image(img)); @@ -168,18 +171,6 @@ Window::Window(const Config& config, const std::filesystem::path& path, moduleMa m_box.set_orientation(Gtk::ORIENTATION_HORIZONTAL); - // https://stackoverflow.com/a/76372996 - Glib::RefPtr<Pango::Context> context = m_label.get_pango_context(); - Pango::FontDescription font(config.font); - debug("font family = {}", font.get_family().raw()); - debug("font style = {}", fmt::underlying(font.get_style())); - debug("font weight = {}", fmt::underlying(font.get_weight())); - context->set_font_description(font); - - /*Gdk::RGBA fg_color; - style_context->lookup_color("theme_fg_color", fg_color); - std::string fg_color_str = rgba_to_hexstr(fg_color);*/ - this->set_layout_markup(); if (is_live_mode) Glib::signal_timeout().connect(sigc::mem_fun(*this, &Window::set_layout_markup), config.loop_ms); @@ -205,6 +196,25 @@ Window::Window(const Config& config, const std::filesystem::path& path, moduleMa m_overlay.add_overlay(m_bg_image); } + if (config.gui_css_file != "disable") + { + if (!std::filesystem::exists(config.gui_css_file)) + die(_("Path to gtk css file '{}' doesn't exist"), config.gui_css_file); + + Glib::RefPtr<Gtk::CssProvider> css_provider = Gtk::CssProvider::create(); + Glib::RefPtr<Gdk::Screen> screen = Gdk::Screen::get_default(); + try + { + css_provider->load_from_path(config.gui_css_file); + } + catch (const Glib::Error& ex) + { + die(_("Failed to load CSS: {}"), ex.gobj()->message); + } + + m_overlay.get_style_context()->add_provider_for_screen(screen, css_provider, GTK_STYLE_PROVIDER_PRIORITY_USER); + } + if (Display::ascii_logo_fd != -1) { ::remove(path.c_str()); diff --git a/src/main.cpp b/src/main.cpp index 8a083573..8d9321cf 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -434,6 +434,7 @@ static bool parseargs(int argc, char* argv[], Config& config, const std::filesys {"logo-padding-top", required_argument, 0, "logo-padding-top"_fnv1a16}, {"logo-padding-left", required_argument, 0, "logo-padding-left"_fnv1a16}, {"layout-padding-top", required_argument, 0, "layout-padding-top"_fnv1a16}, + {"gtk-css", required_argument, 0, "gtk-css"_fnv1a16}, {"loop-ms", required_argument, 0, "loop-ms"_fnv1a16}, {"bg-image", required_argument, 0, "bg-image"_fnv1a16}, {"color", required_argument, 0, "color"_fnv1a16}, @@ -506,16 +507,21 @@ static bool parseargs(int argc, char* argv[], Config& config, const std::filesys case "loop-ms"_fnv1a16: config.loop_ms = std::stoul(optarg); break; - case "debug"_fnv1a16: - if (OPTIONAL_ARGUMENT_IS_PRESENT) - debug_print = str_to_bool(optarg); - else - debug_print = true; - break; + case "color"_fnv1a16: + config.addAliasColors(optarg); break; + + case "sep-reset"_fnv1a16: + config.overrideOption("config.sep-reset", {.value_type = STR, .string_value = optarg}); break; + + case "title-sep"_fnv1a16: + config.overrideOption("config.title-sep", {.value_type = STR, .string_value = optarg}); break; case "bg-image"_fnv1a16: config.overrideOption("gui.bg-image", {.value_type = STR, .string_value = optarg}); break; + case "gtk-css"_fnv1a16: + config.overrideOption("gui.gtk-css", {.value_type = STR, .string_value = optarg}); break; + case "wrap-lines"_fnv1a16: if (OPTIONAL_ARGUMENT_IS_PRESENT) config.overrideOption("config.wrap-lines", {.value_type = BOOL, .bool_value = str_to_bool(optarg)}); @@ -523,8 +529,12 @@ static bool parseargs(int argc, char* argv[], Config& config, const std::filesys config.overrideOption("config.wrap-lines", {.value_type = BOOL, .bool_value = true}); break; - case "color"_fnv1a16: - config.addAliasColors(optarg); break; + case "debug"_fnv1a16: + if (OPTIONAL_ARGUMENT_IS_PRESENT) + debug_print = str_to_bool(optarg); + else + debug_print = true; + break; case "gen-config"_fnv1a16: if (OPTIONAL_ARGUMENT_IS_PRESENT) @@ -533,12 +543,6 @@ static bool parseargs(int argc, char* argv[], Config& config, const std::filesys config.generateConfig(configFile); exit(EXIT_SUCCESS); - case "sep-reset"_fnv1a16: - config.overrideOption("config.sep-reset", {.value_type = STR, .string_value = optarg}); break; - - case "title-sep"_fnv1a16: - config.overrideOption("config.title-sep", {.value_type = STR, .string_value = optarg}); break; - case "sep-reset-after"_fnv1a16: if (OPTIONAL_ARGUMENT_IS_PRESENT) config.overrideOption("config.sep-reset-after", {.value_type = BOOL, .bool_value = str_to_bool(optarg)}); From af5b3723cce0c1467107c26f6c272a1a35fad958 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Mon, 7 Jul 2025 00:55:47 +0200 Subject: [PATCH 069/143] libcufetch: fix GUI_APP disabled --- Makefile | 2 +- include/cufetch/config.hh | 1 - include/util.hpp | 6 +++++- libcufetch/Makefile | 9 +++++---- src/config.cpp | 1 - src/gui.cpp | 2 +- 6 files changed, 12 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 0cb9ea1a..20a34417 100644 --- a/Makefile +++ b/Makefile @@ -59,7 +59,7 @@ all: genver fmt toml json libcufetch $(TARGET) libcufetch: ifeq ($(wildcard $(BUILDDIR)/libcufetch.so),) - make -C libcufetch BUILDDIR=$(BUILDDIR) + make -C libcufetch BUILDDIR=$(BUILDDIR) GUI_APP=$(GUI_APP) endif fmt: diff --git a/include/cufetch/config.hh b/include/cufetch/config.hh index 64d023a5..5dfd11d2 100644 --- a/include/cufetch/config.hh +++ b/include/cufetch/config.hh @@ -114,7 +114,6 @@ public: std::vector<std::string> percentage_colors; std::vector<std::string> colors_name, colors_value; std::string source_path; - std::string font; std::string data_dir; std::string sep_reset; std::string title_sep; diff --git a/include/util.hpp b/include/util.hpp index f7add834..385f11e5 100644 --- a/include/util.hpp +++ b/include/util.hpp @@ -92,7 +92,11 @@ EXPORT bool hasEnding(const std::string_view fullString, const std::string_view */ EXPORT bool hasStart(const std::string_view fullString, const std::string_view start); -std::vector<std::string> split(const std::string_view text, char delim); +/* Spilt a string into a vector using a delimeter + * @param text The string to split + * @param delim The delimeter used for spliting the text + */ +EXPORT std::vector<std::string> split(const std::string_view text, const char delim); /* Get device name from `all_ids` in pci.ids.hpp * @param dev_entry_pos Line position from where the device is located diff --git a/libcufetch/Makefile b/libcufetch/Makefile index 7c84fa06..71bbfff7 100644 --- a/libcufetch/Makefile +++ b/libcufetch/Makefile @@ -1,9 +1,10 @@ CXX ?= g++ +GUI_APP ?= 0 +SRC = $(wildcard *.cc) +OBJ = $(SRC:.cc=.o) +FMT_STATIC = ../$(BUILDDIR)/libfmt.a CXX_INCLUDES = -I../include -CXX_FLAGS = -shared -fPIC -SRC = $(wildcard *.cc) -OBJ = $(SRC:.cc=.o) -FMT_STATIC = ../$(BUILDDIR)/libfmt.a +CXX_FLAGS = -shared -fPIC -DGUI_APP=$(GUI_APP) all: libcufetch diff --git a/src/config.cpp b/src/config.cpp index 0fa3f69d..2fb2b47c 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -82,7 +82,6 @@ void Config::loadConfigFile(const std::filesystem::path& filename) this->logo_position = expandVar(getValue<std::string>("config.logo-position", "left")); this->data_dir = expandVar(getValue<std::string>("config.data-dir", get_data_dir("customfetch"))); this->title_sep = expandVar(getValue<std::string>("config.title-sep", "-")); - this->font = expandVar(getValue<std::string>("gui.font", "Liberation Mono Normal 12")); this->gui_bg_image = expandVar(getValue<std::string>("gui.bg-image", "disable")); this->gui_css_file = expandVar(getValue<std::string>("gui.gtk-css", "disable")); diff --git a/src/gui.cpp b/src/gui.cpp index 32e6f8d8..0a04b3ab 100644 --- a/src/gui.cpp +++ b/src/gui.cpp @@ -212,7 +212,7 @@ Window::Window(const Config& config, const std::filesystem::path& path, const mo die(_("Failed to load CSS: {}"), ex.gobj()->message); } - m_overlay.get_style_context()->add_provider_for_screen(screen, css_provider, GTK_STYLE_PROVIDER_PRIORITY_USER); + m_box.get_style_context()->add_provider_for_screen(screen, css_provider, GTK_STYLE_PROVIDER_PRIORITY_USER); } if (Display::ascii_logo_fd != -1) From ccd4fe0eab035cbf715b7ce86c12f186a473c321 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Mon, 7 Jul 2025 18:19:46 +0200 Subject: [PATCH 070/143] libcufetch: make it more ConfigBase oriented than Config Thus make it retrive values from getValue and keep our own wrapper for customfetch internally --- Makefile | 2 +- include/config.hpp | 148 ++++++++++++++++- include/cufetch/config.hh | 145 +++-------------- include/cufetch/cufetch.hh | 4 +- include/display.hpp | 2 +- include/gui.hpp | 1 + include/parse.hpp | 4 +- include/query.hpp | 6 +- libcufetch/config.cc | 29 ---- libcufetch/cufetch.cc | 4 +- libcufetch/parse.cc | 121 +++++++------- src/config.cpp | 5 - src/core-plugins/linux/linux-core-modules.cc | 15 +- src/main.cpp | 162 +++++++++++-------- 14 files changed, 347 insertions(+), 301 deletions(-) diff --git a/Makefile b/Makefile index 20a34417..1c62cbfc 100644 --- a/Makefile +++ b/Makefile @@ -106,7 +106,7 @@ usr-dist: $(TARGET) locale rm -rf usr/ clean: - rm -rf $(BUILDDIR)/$(TARGET) $(BUILDDIR)/lib$(NAME).a $(OBJ) + rm -rf $(BUILDDIR)/$(TARGET) $(BUILDDIR)/libcufetch.so $(OBJ) libcufetch/*.o distclean: rm -rf $(BUILDDIR) ./tests/$(BUILDDIR) $(OBJ) diff --git a/include/config.hpp b/include/config.hpp index 06745d01..2a4e3cbb 100644 --- a/include/config.hpp +++ b/include/config.hpp @@ -26,12 +26,158 @@ #ifndef _CONFIG_HPP #define _CONFIG_HPP -#undef TOML_HEADER_ONLY +#undef TOML_HEADER_ONLY #define TOML_HEADER_ONLY 0 + +#include <filesystem> #include <string_view> + #include "platform.hpp" #include "cufetch/config.hh" +class Config : public ConfigBase +{ +public: + // Create .config directories and files and load the config file (args or default) + Config(const std::filesystem::path& configFile, const std::filesystem::path& configDir); + + // config colors + // those without gui_ prefix are for the terminal + struct colors_t + { + std::string black; + std::string red; + std::string green; + std::string blue; + std::string cyan; + std::string yellow; + std::string magenta; + std::string white; + + std::string gui_black; + std::string gui_red; + std::string gui_green; + std::string gui_blue; + std::string gui_cyan; + std::string gui_yellow; + std::string gui_magenta; + std::string gui_white; + } colors; + + // Variables of config file in [config] table + std::vector<std::string> layout; + std::vector<std::string> percentage_colors; + std::vector<std::string> colors_name, colors_value; + std::string source_path; + std::string data_dir; + std::string sep_reset; + std::string title_sep; + std::string gui_css_file; + std::string gui_bg_image; + std::string ascii_logo_type; + std::string logo_position; + std::string offset; + std::uint16_t logo_padding_left = 0; + std::uint16_t logo_padding_top = 0; + std::uint16_t layout_padding_top = 0; + std::uint32_t loop_ms = 0; + bool sep_reset_after = false; + bool slow_query_warnings = false; + bool use_SI_unit = false; + bool wrap_lines = false; + + // Variables of config file for + // modules specific configs + // [auto.disk] + std::string auto_disks_fmt; + int auto_disks_types = 0; + bool auto_disks_show_dupl = false; + + // [os.uptime] + std::string uptime_d_fmt; + std::string uptime_h_fmt; + std::string uptime_m_fmt; + std::string uptime_s_fmt; + + // [os.pkgs] + std::vector<std::string> pkgs_managers; + std::vector<std::string> pacman_dirs; + std::vector<std::string> flatpak_dirs; + std::vector<std::string> dpkg_files; + std::vector<std::string> apk_files; + + // inner management / argument configs + std::vector<std::string> args_layout; + std::string args_custom_distro; + std::string args_image_backend; + std::uint16_t m_offset_calc = 0; + bool m_display_distro = true; + bool args_disable_source = false; + bool args_disable_colors = false; + bool args_disallow_commands = false; + bool args_print_logo_only = false; + + /** + * Load config file and parse every config variables + * @param filename The config file path + * @param colors The colors struct where we'll put the default config colors. + * It doesn't include the colors in config.alias-colors + */ + void loadConfigFile(const std::filesystem::path& filename); + + /** + * Generate the default config file at path + * @param filename The config file path + */ + void generateConfig(const std::filesystem::path& filename); + + /** + * Add alias values to colors_name and colors_value. + * @param str The alias color to add. + * Must have a '=' for separating color name and value, + * E.g "pink=!#FFC0CB" + */ + void addAliasColors(const std::string& str); + + /** + * Override a config value from --override + * @param opt The value to override. + * Must have a '=' for separating the name and value to override. + * NO spaces between + */ + void overrideOption(const std::string& opt); + + /** + * Override a config value from --override + * @param key The value name to override. + * Must have a '=' for separating the name and value to override. + * NO spaces between + * @param value The value that will overwrite + */ + template <typename T> + void overrideOption(const std::string& key, const T& value) + { + override_configs_types o; + if constexpr (std::is_same_v<T, bool>) + { + o.value_type = BOOL; + o.bool_value = value; + } + else if constexpr (std::is_same_v<T, std::string>) + { + o.value_type = STR; + o.string_value = value; + } + else if constexpr (std::is_same_v<T, int> || std::is_same_v<T, std::uint16_t>) + { + o.value_type = INT; + o.int_value = value; + } + overrides[key] = std::move(o); + } + +}; + // default config inline constexpr std::string_view AUTOCONFIG = R"#([config] diff --git a/include/cufetch/config.hh b/include/cufetch/config.hh index 5dfd11d2..9498bdc4 100644 --- a/include/cufetch/config.hh +++ b/include/cufetch/config.hh @@ -1,7 +1,6 @@ #pragma once #include <string> -#include <filesystem> #include <unordered_map> #define TOML_HEADER_ONLY 0 @@ -71,7 +70,28 @@ public: * @param value The config variable "path" (e.g "config.gui-red") * @param fallback Default value if couldn't retrive value */ - std::vector<std::string> getValueArrayStr(const std::string_view value, const std::vector<std::string>& fallback); + std::vector<std::string> getValueArrayStr(const std::string_view value, const std::vector<std::string>& fallback) const + { + std::vector<std::string> ret; + + // https://stackoverflow.com/a/78266628 + if (const toml::array* array_it = tbl.at_path(value).as_array()) + { + array_it->for_each( + [&ret](auto&& el) + { + if (const toml::value<std::string>* str_elem = el.as_string()) + ret.push_back((*str_elem)->data()); + } + ); + + return ret; + } + else + { + return fallback; + } + } protected: std::unordered_map<std::string, override_configs_types> overrides; @@ -79,124 +99,3 @@ protected: // Parsed config from loadConfigFile() toml::table tbl; }; - -class EXPORT Config : public ConfigBase -{ -public: - // Create .config directories and files and load the config file (args or default) - Config(const std::filesystem::path& configFile, const std::filesystem::path& configDir); - - // config colors - // those without gui_ prefix are for the terminal - struct colors_t - { - std::string black; - std::string red; - std::string green; - std::string blue; - std::string cyan; - std::string yellow; - std::string magenta; - std::string white; - - std::string gui_black; - std::string gui_red; - std::string gui_green; - std::string gui_blue; - std::string gui_cyan; - std::string gui_yellow; - std::string gui_magenta; - std::string gui_white; - } colors; - - // Variables of config file in [config] table - std::vector<std::string> layout; - std::vector<std::string> percentage_colors; - std::vector<std::string> colors_name, colors_value; - std::string source_path; - std::string data_dir; - std::string sep_reset; - std::string title_sep; - std::string gui_css_file; - std::string gui_bg_image; - std::string ascii_logo_type; - std::string logo_position; - std::string offset; - std::uint16_t logo_padding_left = 0; - std::uint16_t logo_padding_top = 0; - std::uint16_t layout_padding_top = 0; - std::uint32_t loop_ms = 0; - bool sep_reset_after = false; - bool slow_query_warnings = false; - bool use_SI_unit = false; - bool wrap_lines = false; - - // Variables of config file for - // modules specific configs - // [auto.disk] - std::string auto_disks_fmt; - int auto_disks_types = 0; - bool auto_disks_show_dupl = false; - - // [os.uptime] - std::string uptime_d_fmt; - std::string uptime_h_fmt; - std::string uptime_m_fmt; - std::string uptime_s_fmt; - - // [os.pkgs] - std::vector<std::string> pkgs_managers; - std::vector<std::string> pacman_dirs; - std::vector<std::string> flatpak_dirs; - std::vector<std::string> dpkg_files; - std::vector<std::string> apk_files; - - // inner management / argument configs - std::vector<std::string> args_layout; - std::string args_custom_distro; - std::string args_image_backend; - std::uint16_t m_offset_calc = 0; - bool m_display_distro = true; - bool args_disable_source = false; - bool args_disable_colors = false; - bool args_disallow_commands = false; - bool args_print_logo_only = false; - - /** - * Load config file and parse every config variables - * @param filename The config file path - * @param colors The colors struct where we'll put the default config colors. - * It doesn't include the colors in config.alias-colors - */ - void loadConfigFile(const std::filesystem::path& filename); - - /** - * Generate the default config file at path - * @param filename The config file path - */ - void generateConfig(const std::filesystem::path& filename); - - /** - * Add alias values to colors_name and colors_value. - * @param str The alias color to add. - * Must have a '=' for separating color name and value, - * E.g "pink=!#FFC0CB" - */ - void addAliasColors(const std::string& str); - - /** - * Override a config value from --override - * @param str The value to override. - * Must have a '=' for separating the name and value to override. - * NO spaces between - */ - void overrideOption(const std::string& opt); - - /** - * Override a config value from --override - * @param str The value to override. - * Must have a '=' for separating the name and value to override. - * NO spaces between - */ - void overrideOption(const std::string& opt, const override_configs_types& option); -}; diff --git a/include/cufetch/cufetch.hh b/include/cufetch/cufetch.hh index 0116c7e4..5fa91178 100644 --- a/include/cufetch/cufetch.hh +++ b/include/cufetch/cufetch.hh @@ -27,7 +27,7 @@ struct callbackInfo_t { const moduleArgs_t* moduleArgs; const moduleMap_t& modulesInfo; - const Config& config; + const ConfigBase& config; }; struct module_t @@ -38,7 +38,7 @@ struct module_t std::function<std::string(const callbackInfo_t*)> handler; }; -APICALL EXPORT std::string parse(const std::string& input, const moduleMap_t& modulesInfo, const Config& config); +APICALL EXPORT std::string parse(const std::string& input, const moduleMap_t& modulesInfo, const ConfigBase& config); APICALL EXPORT std::string get_and_color_percentage(const float n1, const float n2, const callbackInfo_t* callback, const bool invert); /* Register a module, and its submodules, to customfetch. */ diff --git a/include/display.hpp b/include/display.hpp index e2e6330b..66ec4d8a 100644 --- a/include/display.hpp +++ b/include/display.hpp @@ -29,7 +29,7 @@ #include <string> #include <vector> -#include "cufetch/config.hh" +#include "config.hpp" #include "cufetch/cufetch.hh" #include "platform.hpp" diff --git a/include/gui.hpp b/include/gui.hpp index 5496bfd5..ed08fe02 100644 --- a/include/gui.hpp +++ b/include/gui.hpp @@ -28,6 +28,7 @@ #if GUI_APP +#include "config.hpp" #include "cufetch/cufetch.hh" #include "gdkmm/pixbuf.h" #include "gdkmm/pixbufanimation.h" diff --git a/include/parse.hpp b/include/parse.hpp index 7cbca2ea..9f7666f2 100644 --- a/include/parse.hpp +++ b/include/parse.hpp @@ -41,7 +41,7 @@ struct parse_args_t std::string& pureOutput; std::vector<std::string>& layout; std::vector<std::string>& tmp_layout; - const Config& config; + const ConfigBase& config; bool parsingLayout; bool firstrun_clr = true; bool no_more_reset = false; @@ -60,7 +60,7 @@ struct parse_args_t * @param no_more_reset If we are recursively parsing, e.g we are inside tags */ std::string parse(std::string input, const moduleMap_t& modulesInfo, std::string& pureOutput, - std::vector<std::string>& layout, std::vector<std::string>& tmp_layout, const Config& config, + std::vector<std::string>& layout, std::vector<std::string>& tmp_layout, const ConfigBase& config, const bool parsingLayout, bool& no_more_reset); // parse() for parse_args_t& arguments diff --git a/include/query.hpp b/include/query.hpp index 76a6c353..d87d4d85 100644 --- a/include/query.hpp +++ b/include/query.hpp @@ -111,7 +111,7 @@ class System std::string& host_vendor() noexcept; std::string& host_version() noexcept; - std::string& pkgs_installed(const Config& config); + std::string& pkgs_installed(const ConfigBase& config); private: static System_t m_system_infos; @@ -172,9 +172,9 @@ class Theme }; Theme(const std::uint8_t ver /*, moduleMap_t& queried_themes*/, const std::string& theme_name_version, - const Config& config, const bool gsettings_only = false); + const ConfigBase& config, const bool gsettings_only = false); - Theme(/*moduleMap_t& queried_themes, */ const Config& config, const bool gsettings_only = false); + Theme(/*moduleMap_t& queried_themes, */ const ConfigBase& config, const bool gsettings_only = false); std::string gtk_theme() noexcept; std::string gtk_icon_theme() noexcept; diff --git a/libcufetch/config.cc b/libcufetch/config.cc index fbed698e..77c12919 100644 --- a/libcufetch/config.cc +++ b/libcufetch/config.cc @@ -25,35 +25,6 @@ #include "cufetch/config.hh" -#include <string> -#include <vector> -#include "util.hpp" - template int ConfigBase::getValue<int>(const std::string_view, const int&&) const; template std::string ConfigBase::getValue<std::string>(const std::string_view, const std::string&&) const; template bool ConfigBase::getValue<bool>(const std::string_view, const bool&&) const; - -std::vector<std::string> ConfigBase::getValueArrayStr(const std::string_view value, - const std::vector<std::string>& fallback) -{ - std::vector<std::string> ret; - - // https://stackoverflow.com/a/78266628 - const auto& array = tbl.at_path(value); - if (const toml::array* array_it = array.as_array()) - { - array_it->for_each( - [&ret, value](auto&& el) - { - if (const toml::value<std::string>* str_elem = el.as_string()) - ret.push_back((*str_elem)->data()); - else - warn(_("an element of the array '{}' is not a string"), value); - } - ); - - return ret; - } - else - return fallback; -} diff --git a/libcufetch/cufetch.cc b/libcufetch/cufetch.cc index 5a5b794c..0c72e638 100644 --- a/libcufetch/cufetch.cc +++ b/libcufetch/cufetch.cc @@ -2,14 +2,12 @@ static std::vector<module_t> modules; -static char separator = '.'; - static void addModule(const module_t& module, const std::string& prefix = "") { modules.emplace_back(module).name = prefix + module.name; for (const module_t& submodule : module.submodules) - addModule(submodule, prefix + module.name + separator); + addModule(submodule, prefix + module.name + "."); } /* Register a module, and its submodules, to customfetch. */ diff --git a/libcufetch/parse.cc b/libcufetch/parse.cc index b75d816f..7c0d4360 100644 --- a/libcufetch/parse.cc +++ b/libcufetch/parse.cc @@ -38,6 +38,7 @@ #include <vector> #include "cufetch/common.hh" +#include "cufetch/config.hh" #include "fmt/color.h" #include "fmt/format.h" #include "query.hpp" @@ -117,7 +118,7 @@ std::string _; // @param noesc_str The ansi color without \\e[ or \033[ // @param colors The colors struct we'll look at // @return An array of 3 span tags elements in the follow: color, weight, type -static std::array<std::string, 3> get_ansi_color(const std::string_view noesc_str, const Config::colors_t& colors) +static std::array<std::string, 3> get_ansi_color(const std::string_view noesc_str, const ConfigBase& config) { const size_t first_m = noesc_str.rfind('m'); if (first_m == std::string::npos) @@ -143,14 +144,14 @@ static std::array<std::string, 3> get_ansi_color(const std::string_view noesc_st // clang-format off switch (col.back()) { - case '0': col = colors.gui_black; break; - case '1': col = colors.gui_red; break; - case '2': col = colors.gui_green; break; - case '3': col = colors.gui_yellow; break; - case '4': col = colors.gui_blue; break; - case '5': col = colors.gui_magenta; break; - case '6': col = colors.gui_cyan; break; - case '7': col = colors.gui_white; break; + case '0': col = config.getThemeValue("gui.black", "!#000005"); break; + case '1': col = config.getThemeValue("gui.red", "!#ff2000"); break; + case '2': col = config.getThemeValue("gui.green", "!#00ff00"); break; + case '3': col = config.getThemeValue("gui.yellow", "!#ffff00"); break; + case '4': col = config.getThemeValue("gui.blue", "!#00aaff"); break; + case '5': col = config.getThemeValue("gui.magenta", "!#ff11cc"); break; + case '6': col = config.getThemeValue("gui.cyan", "!#00ffff"); break; + case '7': col = config.getThemeValue("gui.white", "!#ffffff"); break; } if (col.at(0) != '#') @@ -216,27 +217,27 @@ EXPORT std::string parse(const std::string& input, parse_args_t& parse_args) std::string get_and_color_percentage(const float n1, const float n2, parse_args_t& parse_args, const bool invert) { - const Config& config = parse_args.config; - const float result = n1 / n2 * static_cast<float>(100); + const std::vector<std::string>& percentage_colors = parse_args.config.getValueArrayStr("config.percentage-colors", {"green", "yellow", "red"}); + const float result = n1 / n2 * static_cast<float>(100); std::string color; if (!invert) { if (result <= 45) - color = "${" + config.percentage_colors.at(0) + "}"; + color = "${" + percentage_colors.at(0) + "}"; else if (result <= 80) - color = "${" + config.percentage_colors.at(1) + "}"; + color = "${" + percentage_colors.at(1) + "}"; else - color = "${" + config.percentage_colors.at(2) + "}"; + color = "${" + percentage_colors.at(2) + "}"; } else { if (result <= 45) - color = "${" + config.percentage_colors.at(2) + "}"; + color = "${" + percentage_colors.at(2) + "}"; else if (result <= 80) - color = "${" + config.percentage_colors.at(1) + "}"; + color = "${" + percentage_colors.at(1) + "}"; else - color = "${" + config.percentage_colors.at(0) + "}"; + color = "${" + percentage_colors.at(0) + "}"; } return parse(fmt::format("{}{:.2f}%${{0}}", color, result), _, parse_args); @@ -369,7 +370,7 @@ std::optional<std::string> parse_command_tag(Parser& parser, parse_args_t& parse if (!evaluate) return {}; - if (parse_args.config.args_disallow_commands) + if (parse_args.config.getValue("intern.args.disallow-commands", false)) die(_("Trying to execute command $({}) but --disallow-command-tag is set"), command); const bool removetag = (command.front() == '!'); @@ -399,14 +400,12 @@ std::optional<std::string> parse_color_tag(Parser& parser, parse_args_t& parse_a if (!evaluate) return {}; - std::string output; - const Config& config = parse_args.config; - const Config::colors_t& colors = parse_args.config.colors; - const size_t taglen = color.length() + "${}"_len; + std::string output; + const size_t taglen = color.length() + "${}"_len; + const ConfigBase& config = parse_args.config; + const std::string endspan = !parse_args.firstrun_clr ? "</span>" : ""; - const std::string endspan{ !parse_args.firstrun_clr ? "</span>" : "" }; - - if (config.args_disable_colors) + if (config.getValue("intern.args.disable-colors", false)) { if (parser.dollar_pos != std::string::npos) parse_args.pureOutput.erase(parser.dollar_pos, taglen); @@ -419,14 +418,27 @@ std::optional<std::string> parse_color_tag(Parser& parser, parse_args_t& parse_a if (output[0] == '$') output += ' '; #endif - - if (!config.colors_name.empty()) + + static std::vector<std::string> alias_colors_name, alias_colors_value; + const std::vector<std::string>& alias_colors = config.getValueArrayStr("config.alias-colors", {}); + if (!alias_colors.empty() && (alias_colors_name.empty() && alias_colors_value.empty())) { - const auto& it_name = std::find(config.colors_name.begin(), config.colors_name.end(), color); - if (it_name != config.colors_name.end()) + for (const std::string& str : alias_colors) + { + const size_t pos = str.find('='); + if (pos == std::string::npos) + die(_("alias color '{}' does NOT have an equal sign '=' for separating color name and value\n" + "For more check with --help"), str); + + alias_colors_name.push_back(str.substr(0, pos)); + alias_colors_value.push_back(str.substr(pos + 1)); + } + + const auto& it_name = std::find(alias_colors_name.begin(), alias_colors_name.end(), color); + if (it_name != alias_colors_name.end()) { - const size_t index = std::distance(config.colors_name.begin(), it_name); - color = config.colors_value.at(index); + const size_t index = std::distance(alias_colors_name.begin(), it_name); + color = alias_colors_value.at(index); } } @@ -469,14 +481,14 @@ std::optional<std::string> parse_color_tag(Parser& parser, parse_args_t& parse_a #if GUI_APP switch (fnv1a16::hash(color)) { - case "black"_fnv1a16: str_clr = colors.gui_black; break; - case "red"_fnv1a16: str_clr = colors.gui_red; break; - case "blue"_fnv1a16: str_clr = colors.gui_blue; break; - case "green"_fnv1a16: str_clr = colors.gui_green; break; - case "cyan"_fnv1a16: str_clr = colors.gui_cyan; break; - case "yellow"_fnv1a16: str_clr = colors.gui_yellow; break; - case "magenta"_fnv1a16: str_clr = colors.gui_magenta; break; - case "white"_fnv1a16: str_clr = colors.gui_white; break; + case "black"_fnv1a16: str_clr = config.getThemeValue("gui.black", "!#000005"); break; + case "red"_fnv1a16: str_clr = config.getThemeValue("gui.red", "!#ff2000"); break; + case "green"_fnv1a16: str_clr = config.getThemeValue("gui.green", "!#00ff00"); break; + case "yellow"_fnv1a16: str_clr = config.getThemeValue("gui.yellow", "!#ffff00"); break; + case "blue"_fnv1a16: str_clr = config.getThemeValue("gui.blue", "!#00aaff"); break; + case "magenta"_fnv1a16: str_clr = config.getThemeValue("gui.magenta", "!#ff11cc"); break; + case "cyan"_fnv1a16: str_clr = config.getThemeValue("gui.cyan", "!#00ffff"); break; + case "white"_fnv1a16: str_clr = config.getThemeValue("gui.white", "!#ffffff"); break; default: str_clr = color; break; } @@ -584,7 +596,7 @@ std::optional<std::string> parse_color_tag(Parser& parser, parse_args_t& parse_a } else { - const std::array<std::string, 3>& clrs = get_ansi_color(noesc_str, colors); + const std::array<std::string, 3>& clrs = get_ansi_color(noesc_str, config); const std::string_view color = clrs.at(0); const std::string_view weight = clrs.at(1); const std::string_view type = clrs.at(2); @@ -604,14 +616,14 @@ std::optional<std::string> parse_color_tag(Parser& parser, parse_args_t& parse_a #else switch (fnv1a16::hash(color)) { - case "black"_fnv1a16: str_clr = colors.black; break; - case "red"_fnv1a16: str_clr = colors.red; break; - case "blue"_fnv1a16: str_clr = colors.blue; break; - case "green"_fnv1a16: str_clr = colors.green; break; - case "cyan"_fnv1a16: str_clr = colors.cyan; break; - case "yellow"_fnv1a16: str_clr = colors.yellow; break; - case "magenta"_fnv1a16: str_clr = colors.magenta; break; - case "white"_fnv1a16: str_clr = colors.white; break; + case "black"_fnv1a16: str_clr = config.getThemeValue("config.black", "\033[1;30m"); break; + case "red"_fnv1a16: str_clr = config.getThemeValue("config.red", "\033[1;31m"); break; + case "green"_fnv1a16: str_clr = config.getThemeValue("config.green", "\033[1;32m"); break; + case "yellow"_fnv1a16: str_clr = config.getThemeValue("config.yellow", "\033[1;33m"); break; + case "blue"_fnv1a16: str_clr = config.getThemeValue("config.blue", "\033[1;34m"); break; + case "magenta"_fnv1a16: str_clr = config.getThemeValue("config.magenta", "\033[1;35m"); break; + case "cyan"_fnv1a16: str_clr = config.getThemeValue("config.cyan", "\033[1;36m"); break; + case "white"_fnv1a16: str_clr = config.getThemeValue("config.white", "\033[1;37m"); break; default: str_clr = color; break; } @@ -803,15 +815,16 @@ std::string parse(Parser& parser, parse_args_t& parse_args, const bool evaluate, } EXPORT std::string parse(std::string input, const moduleMap_t& modulesInfo, std::string& pureOutput, - std::vector<std::string>& layout, std::vector<std::string>& tmp_layout, const Config& config, + std::vector<std::string>& layout, std::vector<std::string>& tmp_layout, const ConfigBase& config, const bool parsingLayout, bool& no_more_reset) { - if (!config.sep_reset.empty() && parsingLayout && !no_more_reset) + const std::string& sep_reset = config.getValue<std::string>("config.sep-reset", ":"); + if (!sep_reset.empty() && parsingLayout && !no_more_reset) { - if (config.sep_reset_after) - replace_str(input, config.sep_reset, config.sep_reset + "${0}"); + if (config.getValue("config.sep-reset-after", false)) + replace_str(input, sep_reset, sep_reset + "${0}"); else - replace_str(input, config.sep_reset, "${0}" + config.sep_reset); + replace_str(input, sep_reset, "${0}" + sep_reset); no_more_reset = true; } @@ -841,7 +854,7 @@ EXPORT std::string parse(std::string input, const moduleMap_t& modulesInfo, std: return ret; } -APICALL EXPORT std::string parse(const std::string& input, const moduleMap_t& modulesInfo, const Config& config) +APICALL EXPORT std::string parse(const std::string& input, const moduleMap_t& modulesInfo, const ConfigBase& config) { std::vector<std::string> nah; parse_args_t parse_args{ modulesInfo, _, nah, nah, config, true, true, true}; diff --git a/src/config.cpp b/src/config.cpp index 2fb2b47c..2dd15650 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -200,11 +200,6 @@ void Config::overrideOption(const std::string& opt) value, name); } -void Config::overrideOption(const std::string& opt, const override_configs_types& option) -{ - overrides[opt] = option; -} - void Config::generateConfig(const std::filesystem::path &filename) { if (std::filesystem::exists(filename)) diff --git a/src/core-plugins/linux/linux-core-modules.cc b/src/core-plugins/linux/linux-core-modules.cc index db067016..56376c0e 100644 --- a/src/core-plugins/linux/linux-core-modules.cc +++ b/src/core-plugins/linux/linux-core-modules.cc @@ -13,6 +13,7 @@ #include "utils/packages.hpp" #include "core-modules.hh" #include "cufetch/cufetch.hh" +#include "config.hpp" #include "fmt/format.h" #include "util.hpp" @@ -83,7 +84,7 @@ static std::string get_colors_symbol(const callbackInfo_t* callback, bool is_lig callback->modulesInfo, callback->config); } -void core_plugins_start() +void core_plugins_start(const Config& config) { // ------------ INIT STUFF ------------ const std::chrono::seconds uptime_secs(os_uptime()); @@ -126,8 +127,8 @@ void core_plugins_start() std::move(os_uptime_m_module), std::move(os_uptime_h_module), std::move(os_uptime_d_module), - }, [=](const callbackInfo_t* callback) { return get_auto_uptime(uptime_days, uptime_hours.count() % 24, uptime_mins.count() % 60, - uptime_secs.count() % 60, callback->config); }}; + }, [=](unused) { return get_auto_uptime(uptime_days, uptime_hours.count() % 24, uptime_mins.count() % 60, + uptime_secs.count() % 60, config); }}; module_t os_hostname_module = {"hostname", "hostname of the OS [myMainPC]", {}, os_hostname}; @@ -145,7 +146,7 @@ void core_plugins_start() std::move(os_initsys_version_module), }, [](unused) {return os_initsys_name() + " " + os_initsys_version();}}; - module_t os_pkgs_module = {"pkgs", "Count of system packages", {}, [](const callbackInfo_t* callback){ return get_all_pkgs(callback->config); }}; + module_t os_pkgs_module = {"pkgs", "Count of system packages", {}, [&](unused){ return get_all_pkgs(config); }}; // $<os> module_t os_module = { "os", "OS modules", { @@ -346,14 +347,14 @@ void core_plugins_start() cfRegisterModule(gpu_module); // $<title> - module_t title_sep_module = { "sep", "separator between the title and the system infos (with the title length) [--------]", {}, [](const callbackInfo_t* callback) { + module_t title_sep_module = { "sep", "separator between the title and the system infos (with the title length) [--------]", {}, [&](unused) { const size_t title_len = std::string_view(user_name() + "@" + os_hostname()).length(); std::string str; - str.reserve(callback->config.title_sep.length() * title_len); + str.reserve(config.title_sep.length() * title_len); for (size_t i = 0; i < title_len; i++) - str += callback->config.title_sep; + str += config.title_sep; return str; } }; diff --git a/src/main.cpp b/src/main.cpp index 8d9321cf..af3ae76c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -65,6 +65,9 @@ using namespace std::string_view_literals; +bool display_modules = false; +bool display_list_logos = false; + // Print the version and some other infos, then exit successfully static void version() { @@ -176,49 +179,6 @@ For details, see `man customfetch` or run `--how-it-works`. std::exit(invalid_opt); } -// Print all info modules you can put in $<>, then exit successfully -static void modules_list() -{ - for (const module_t& module : cfGetModules()) - { - std::vector<std::string> parts; - - // Split name into parts (e.g., "os.name.pretty" -> ["os", "name", "pretty"]) - size_t start = 0, end = module.name.find('.'); - bool new_module = true; - while (end != std::string::npos) - { - new_module = false; - parts.push_back(module.name.substr(start, end - start)); - start = end + 1; - end = module.name.find('.', start); - } - parts.push_back(module.name.substr(start)); - if (new_module) - fmt::print("\n"); - - // Generate indentation - for (size_t depth = 0; depth < parts.size(); ++depth) - { - if (depth == parts.size() - 1) - { - if (new_module) - fmt::print("{} - {}", parts[depth], module.description); - else - fmt::print("{:<6} \t- {}", parts[depth], module.description); - } - else - { - fmt::print(" "); - } - } - - fmt::print("\n"); - } - - std::exit(EXIT_SUCCESS); -} - // Print how customfetch works, then exit successfully static void explain_how_this_works() { @@ -358,11 +318,54 @@ static void list_logos(const std::string& data_dir) fmt::print("{}", fmt::join(list, "\n")); fmt::print("\n"); - std::exit(EXIT_SUCCESS); +} + +// Print all info modules you can put in $<>, then exit successfully +static void modules_list() +{ + for (const module_t& module : cfGetModules()) + { + std::vector<std::string> parts; + + // Split name into parts (e.g., "os.name.pretty" -> ["os", "name", "pretty"]) + size_t start = 0, end = module.name.find('.'); + bool new_module = true; + while (end != std::string::npos) + { + new_module = false; + parts.push_back(module.name.substr(start, end - start)); + start = end + 1; + end = module.name.find('.', start); + } + parts.push_back(module.name.substr(start)); + if (new_module) + fmt::print("\n"); + + // Generate indentation + for (size_t depth = 0; depth < parts.size(); ++depth) + { + if (depth == parts.size() - 1) + { + if (new_module) + fmt::print("{} - {}", parts[depth], module.description); + else + fmt::print("{:<6} \t- {}", parts[depth], module.description); + } + else + { + fmt::print(" "); + } + } + + fmt::print("\n"); + } } // Return true if optarg says something true -static bool str_to_bool(const std::string_view str) { return (str == "true" || str == "1" || str == "enable"); } +static bool str_to_bool(const std::string_view str) +{ + return (str == "true" || str == "1" || str == "enable"); +} // clang-format off // parseargs() but only for parsing the user config path trough args @@ -397,7 +400,7 @@ static std::filesystem::path parse_config_path(int argc, char* argv[], const std return configDir / "config.toml"; } -static bool parseargs(int argc, char* argv[], Config& config, const std::filesystem::path &configFile) +static bool parseargs(int argc, char* argv[], Config& config, const std::filesystem::path& configFile) { int opt = 0; int option_index = 0; @@ -458,27 +461,27 @@ static bool parseargs(int argc, char* argv[], Config& config, const std::filesys case 'h': help(); break; case 'l': - modules_list(); break; + display_modules = true; break; case 'w': explain_how_this_works(); break; case "list-logos"_fnv1a16: - list_logos(config.data_dir+"/ascii"); break; + display_list_logos = true; break; case 'f': - config.overrideOption("gui.font", {.value_type = STR, .string_value = optarg}); break; + config.overrideOption("gui.font", optarg); break; case 'o': - config.overrideOption("config.offset", {.value_type = STR, .string_value = optarg}); break; + config.overrideOption("config.offset", optarg); break; case 'C': // we have already did it in parse_config_path() break; case 'D': - config.overrideOption("config.data-dir", {.value_type = STR, .string_value = optarg}); break; + config.overrideOption("config.data-dir", optarg); break; case 'd': config.args_custom_distro = str_tolower(optarg); break; case 'm': config.args_layout.push_back(optarg); break; case 'p': - config.overrideOption("config.logo-position", {.value_type = STR, .string_value = optarg}); break; + config.overrideOption("config.logo-position", optarg); break; case 's': - config.overrideOption("config.source-path", {.value_type = STR, .string_value = optarg}); break; + config.overrideOption("config.source-path", optarg); break; case 'i': config.args_image_backend = optarg; break; case 'O': @@ -486,7 +489,7 @@ static bool parseargs(int argc, char* argv[], Config& config, const std::filesys case 'N': config.args_disable_colors = true; break; case 'a': - config.overrideOption("config.ascii-logo-type", {.value_type = STR, .string_value = optarg}); break; + config.overrideOption("config.ascii-logo-type", optarg); break; case 'n': config.args_disable_source = true; break; case 'L': @@ -496,13 +499,13 @@ static bool parseargs(int argc, char* argv[], Config& config, const std::filesys config.args_disallow_commands = true; break; case "logo-padding-top"_fnv1a16: - config.overrideOption("config.logo-padding-top", {.value_type = INT, .int_value = std::stoi(optarg)}); break; + config.overrideOption("config.logo-padding-top", std::stoi(optarg)); break; case "logo-padding-left"_fnv1a16: - config.overrideOption("config.logo-padding-left", {.value_type = INT, .int_value = std::stoi(optarg)}); break; + config.overrideOption("config.logo-padding-left", std::stoi(optarg)); break; case "layout-padding-top"_fnv1a16: - config.overrideOption("config.layout-padding-top", {.value_type = INT, .int_value = std::stoi(optarg)}); break; + config.overrideOption("config.layout-padding-top", std::stoi(optarg)); break; case "loop-ms"_fnv1a16: config.loop_ms = std::stoul(optarg); break; @@ -511,22 +514,22 @@ static bool parseargs(int argc, char* argv[], Config& config, const std::filesys config.addAliasColors(optarg); break; case "sep-reset"_fnv1a16: - config.overrideOption("config.sep-reset", {.value_type = STR, .string_value = optarg}); break; + config.overrideOption("config.sep-reset", optarg); break; case "title-sep"_fnv1a16: - config.overrideOption("config.title-sep", {.value_type = STR, .string_value = optarg}); break; + config.overrideOption("config.title-sep", optarg); break; case "bg-image"_fnv1a16: - config.overrideOption("gui.bg-image", {.value_type = STR, .string_value = optarg}); break; + config.overrideOption("gui.bg-image", optarg); break; case "gtk-css"_fnv1a16: - config.overrideOption("gui.gtk-css", {.value_type = STR, .string_value = optarg}); break; + config.overrideOption("gui.gtk-css", optarg); break; case "wrap-lines"_fnv1a16: if (OPTIONAL_ARGUMENT_IS_PRESENT) - config.overrideOption("config.wrap-lines", {.value_type = BOOL, .bool_value = str_to_bool(optarg)}); + config.overrideOption("config.wrap-lines", str_to_bool(optarg)); else - config.overrideOption("config.wrap-lines", {.value_type = BOOL, .bool_value = true}); + config.overrideOption("config.wrap-lines", true); break; case "debug"_fnv1a16: @@ -545,9 +548,9 @@ static bool parseargs(int argc, char* argv[], Config& config, const std::filesys case "sep-reset-after"_fnv1a16: if (OPTIONAL_ARGUMENT_IS_PRESENT) - config.overrideOption("config.sep-reset-after", {.value_type = BOOL, .bool_value = str_to_bool(optarg)}); + config.overrideOption("config.sep-reset-after", str_to_bool(optarg)); else - config.overrideOption("config.sep-reset-after", {.value_type = BOOL, .bool_value = true}); + config.overrideOption("config.sep-reset-after", true); break; default: @@ -555,6 +558,13 @@ static bool parseargs(int argc, char* argv[], Config& config, const std::filesys } } + config.overrideOption("intern.args.print-logo-only", config.args_print_logo_only); + config.overrideOption("intern.args.disable-logo", config.args_disable_source); + config.overrideOption("intern.args.disallow-commands", config.args_disallow_commands); + config.overrideOption("intern.args.custom-distro", config.args_custom_distro); + config.overrideOption("intern.args.image-backend", config.args_image_backend); + config.overrideOption("intern.args.disable-colors", config.args_disable_colors); + return true; } @@ -582,8 +592,10 @@ static void localize(void) } // clang-format on -void core_plugins_start(); +void core_plugins_start(const Config& config); void core_plugins_finish(); + + int main(int argc, char *argv[]) { const std::filesystem::path& configDir = getConfigDir(); @@ -592,11 +604,13 @@ int main(int argc, char *argv[]) localize(); Config config(configFile, configDir); + if (!parseargs(argc, argv, config, configFile)) + return 1; config.loadConfigFile(configFile); std::vector<void *> plugins_handle; /* TODO(burntranch): track each library and unload them. */ - core_plugins_start(); + core_plugins_start(config); const std::filesystem::path plguinDir = configDir / "plugins"; std::filesystem::create_directories(plguinDir); for (const auto& entry : std::filesystem::directory_iterator{ plguinDir }) @@ -623,9 +637,17 @@ int main(int argc, char *argv[]) start(handle, config); plugins_handle.push_back(handle); } - - if (!parseargs(argc, argv, config, configFile)) - return 1; + + if (display_modules) + { + modules_list(); + return 0; + } + else if (display_list_logos) + { + list_logos(config.data_dir+"/ascii"); + return 0; + } const std::vector<module_t>& modules = cfGetModules(); moduleMap_t moduleMap; From 099d8b07e0a53efd2914b1b70da9173657b73c00 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Mon, 7 Jul 2025 19:17:22 +0200 Subject: [PATCH 071/143] core-plugins: linux: move main linux-core-modules.cc to parent this file is like the old parse.cpp so it shouldn't be platform dependent --- include/core-modules.hh | 8 +++-- .../linux-core-modules.cc => core-modules.cc} | 31 ++++++++++++------- 2 files changed, 25 insertions(+), 14 deletions(-) rename src/core-plugins/{linux/linux-core-modules.cc => core-modules.cc} (97%) diff --git a/include/core-modules.hh b/include/core-modules.hh index 4cca0e99..0c7365ae 100644 --- a/include/core-modules.hh +++ b/include/core-modules.hh @@ -3,12 +3,12 @@ #include <pwd.h> #include <sys/utsname.h> +#include "platform.hpp" #include "cufetch/cufetch.hh" #define MODFUNC(name) std::string name(__attribute__((unused)) const callbackInfo_t* callbackInfo = nullptr) // system.cc -inline utsname g_uname_infos; MODFUNC(arch); MODFUNC(host); MODFUNC(host_name); @@ -40,7 +40,6 @@ MODFUNC(cpu_nproc); MODFUNC(cpu_name); // user.cc -inline struct passwd* g_pwd; inline bool is_tty = false; inline std::string term_pid, term_name, wm_name, de_name, wm_path_exec; std::string get_terminal_name(); @@ -88,5 +87,10 @@ double battery_temp(); MODFUNC(gpu_name); MODFUNC(gpu_vendor); +#if CF_LINUX +inline struct passwd* g_pwd; +inline utsname g_uname_infos; +#endif + #undef MODFUNC #define MODFUNC(name) std::string name(__attribute__((unused)) const callbackInfo_t* callbackInfo) diff --git a/src/core-plugins/linux/linux-core-modules.cc b/src/core-plugins/core-modules.cc similarity index 97% rename from src/core-plugins/linux/linux-core-modules.cc rename to src/core-plugins/core-modules.cc index 56376c0e..27e87afa 100644 --- a/src/core-plugins/linux/linux-core-modules.cc +++ b/src/core-plugins/core-modules.cc @@ -4,19 +4,21 @@ #include <algorithm> #include <array> -#include <chrono> #include <cstdio> #include <string> #include <string_view> #include <utility> -#include "utils/packages.hpp" #include "core-modules.hh" #include "cufetch/cufetch.hh" #include "config.hpp" #include "fmt/format.h" #include "util.hpp" +#if CF_LINUX +# include "linux/utils/packages.hpp" +#endif + using unused = const callbackInfo_t*; std::string amount(const double amount, const moduleArgs_t* moduleArgs) @@ -87,16 +89,18 @@ static std::string get_colors_symbol(const callbackInfo_t* callback, bool is_lig void core_plugins_start(const Config& config) { // ------------ INIT STUFF ------------ - const std::chrono::seconds uptime_secs(os_uptime()); - const std::chrono::minutes& uptime_mins = std::chrono::duration_cast<std::chrono::minutes>(uptime_secs); - const std::chrono::hours& uptime_hours = std::chrono::duration_cast<std::chrono::hours>(uptime_secs); - const size_t uptime_days = uptime_secs.count() / (60 * 60 * 24); + const size_t uptime_secs = os_uptime(); + const size_t uptime_mins = uptime_secs / (60); + const size_t uptime_hours = uptime_secs / (60 * 60); + const size_t uptime_days = uptime_secs / (60 * 60 * 24); +#if CF_LINUX if (uname(&g_uname_infos) != 0) - die(_("uname() failed: {}\nCould not get system infos"), strerror(errno)); + die(_("uname() failed: {}\nCould not get system infos"), std::strerror(errno)); if (g_pwd = getpwuid(getuid()), !g_pwd) die(_("getpwent failed: {}\nCould not get user infos"), std::strerror(errno)); +#endif term_pid = get_terminal_pid(); term_name = get_terminal_name(); @@ -118,17 +122,17 @@ void core_plugins_start(const Config& config) std::move(os_name_id_module) }, os_name }; - module_t os_uptime_s_module = {"secs", "uptime of the system in seconds [45]", {}, [=](unused) {return fmt::to_string(uptime_secs.count() % 60);}}; - module_t os_uptime_m_module = {"mins", "uptime of the system in minutes [12]", {}, [=](unused) {return fmt::to_string(uptime_mins.count() % 60);}}; - module_t os_uptime_h_module = {"hours", "uptime of the system in hours [34]", {}, [=](unused) {return fmt::to_string(uptime_hours.count() % 24);}}; + module_t os_uptime_s_module = {"secs", "uptime of the system in seconds [45]", {}, [=](unused) {return fmt::to_string(uptime_secs % 60);}}; + module_t os_uptime_m_module = {"mins", "uptime of the system in minutes [12]", {}, [=](unused) {return fmt::to_string(uptime_mins % 60);}}; + module_t os_uptime_h_module = {"hours", "uptime of the system in hours [34]", {}, [=](unused) {return fmt::to_string(uptime_hours % 24);}}; module_t os_uptime_d_module = {"days", "uptime of the system in days [2]", {}, [=](unused) {return fmt::to_string(uptime_days);}}; module_t os_uptime_module = {"uptime", "(auto) uptime of the system [36 mins, 3 hours, 23 days]", { std::move(os_uptime_s_module), std::move(os_uptime_m_module), std::move(os_uptime_h_module), std::move(os_uptime_d_module), - }, [=](unused) { return get_auto_uptime(uptime_days, uptime_hours.count() % 24, uptime_mins.count() % 60, - uptime_secs.count() % 60, config); }}; + }, [=](unused) { return get_auto_uptime(uptime_days, uptime_hours % 24, uptime_mins % 60, + uptime_secs % 60, config); }}; module_t os_hostname_module = {"hostname", "hostname of the OS [myMainPC]", {}, os_hostname}; @@ -386,8 +390,11 @@ void core_plugins_start(const Config& config) void core_plugins_finish() { +#if CF_LINUX if (mountsFile) fclose(mountsFile); if (os_release) fclose(os_release); if (meminfo) fclose(meminfo); if (cpuinfo) fclose(cpuinfo); + if (g_pwd) free(g_pwd); +#endif } From 5a9456b127cdc57659088f685cbaa08190d09530 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Mon, 7 Jul 2025 20:51:43 +0200 Subject: [PATCH 072/143] libcufetch: migrate parse.hpp and let the plugins use `parse_args_t` for `tmp_layout` (maybe bad decision) maybe bad, but atleast I can implement $<auto> and the plugins use `tmp_layout` for multiple line modules. 777 commits... something is telling me to gamble my house --- Makefile | 2 +- include/core-modules.hh | 4 ++ include/cufetch/cufetch.hh | 10 +---- include/cufetch/parse.hh | 59 +++++++++++++++++++++++++++ include/parse.hpp | 69 +------------------------------- libcufetch/parse.cc | 21 ++-------- src/core-plugins/core-modules.cc | 27 +++++-------- src/main.cpp | 7 +--- 8 files changed, 83 insertions(+), 116 deletions(-) create mode 100644 include/cufetch/parse.hh diff --git a/Makefile b/Makefile index 1c62cbfc..da9a40dc 100644 --- a/Makefile +++ b/Makefile @@ -47,7 +47,7 @@ TARGET ?= $(NAME) OLDVERSION = 0.10.2 VERSION = 1.0.0 SRC_CPP = $(wildcard src/*.cpp src/core-plugins/linux/utils/*.cpp) -SRC_CC = $(wildcard src/core-plugins/linux/*.cc) +SRC_CC = $(wildcard src/core-plugins/*.cc src/core-plugins/linux/*.cc) OBJ_CPP = $(SRC_CPP:.cpp=.o) OBJ_CC = $(SRC_CC:.cc=.o) OBJ = $(OBJ_CPP) $(OBJ_CC) diff --git a/include/core-modules.hh b/include/core-modules.hh index 0c7365ae..7aa55c0e 100644 --- a/include/core-modules.hh +++ b/include/core-modules.hh @@ -5,6 +5,7 @@ #include "platform.hpp" #include "cufetch/cufetch.hh" +#include "config.hpp" #define MODFUNC(name) std::string name(__attribute__((unused)) const callbackInfo_t* callbackInfo = nullptr) @@ -94,3 +95,6 @@ inline utsname g_uname_infos; #undef MODFUNC #define MODFUNC(name) std::string name(__attribute__((unused)) const callbackInfo_t* callbackInfo) + +void core_plugins_start(const Config& config); +void core_plugins_finish(); diff --git a/include/cufetch/cufetch.hh b/include/cufetch/cufetch.hh index 5fa91178..ea2965b9 100644 --- a/include/cufetch/cufetch.hh +++ b/include/cufetch/cufetch.hh @@ -4,9 +4,7 @@ #include <string> #include <vector> -#include "cufetch/config.hh" - -struct module_t; +#include "cufetch/parse.hh" // Map from a modules name to its pointer. using moduleMap_t = std::unordered_map<std::string, const module_t&>; @@ -26,8 +24,7 @@ struct moduleArgs_t struct callbackInfo_t { const moduleArgs_t* moduleArgs; - const moduleMap_t& modulesInfo; - const ConfigBase& config; + parse_args_t& parse_args; }; struct module_t @@ -38,9 +35,6 @@ struct module_t std::function<std::string(const callbackInfo_t*)> handler; }; -APICALL EXPORT std::string parse(const std::string& input, const moduleMap_t& modulesInfo, const ConfigBase& config); -APICALL EXPORT std::string get_and_color_percentage(const float n1, const float n2, const callbackInfo_t* callback, const bool invert); - /* Register a module, and its submodules, to customfetch. */ APICALL EXPORT void cfRegisterModule(const module_t& module); diff --git a/include/cufetch/parse.hh b/include/cufetch/parse.hh new file mode 100644 index 00000000..3b0429b5 --- /dev/null +++ b/include/cufetch/parse.hh @@ -0,0 +1,59 @@ +#pragma once + +#include <string> +#include <unordered_map> +#include <vector> + +#include "cufetch/common.hh" +#include "cufetch/config.hh" + +struct module_t; + +// Map from a modules name to its pointer. +using moduleMap_t = std::unordered_map<std::string, const module_t&>; + +/* The additional args that parse() needs for getting the necessary infos/configs. + * Only used for making the argument passing more clear. + * Always pass it non-const and by reference + */ +struct EXPORT parse_args_t +{ + const moduleMap_t& modulesInfo; + std::string& pureOutput; + std::vector<std::string>& layout; + std::vector<std::string>& tmp_layout; + const ConfigBase& config; + bool parsingLayout; + bool firstrun_clr = true; + bool no_more_reset = false; +}; + +/* Parse input, in-place, with data from modulesInfo. + * Documentation on formatting is in the flag -w or the customfetch.1 manual. + * @param input The string to parse + * @param modulesInfo The system infos + * @param pureOutput The output of the string but without tags + * @param layout The layout of customfetch + * @param tmp_layout The temponary layout to be used for multiple-line modules + * @param config The config + * @param colors The colors + * @param parsingLayout If we are parsing layout or not + * @param no_more_reset If we are recursively parsing, e.g we are inside tags + */ +std::string parse(std::string input, const moduleMap_t& modulesInfo, std::string& pureOutput, + std::vector<std::string>& layout, std::vector<std::string>& tmp_layout, const ConfigBase& config, + const bool parsingLayout, bool& no_more_reset); + +// parse() for parse_args_t& arguments +APICALL EXPORT std::string parse(const std::string& input, parse_args_t& parse_args); + +/* + * Create a colored percentage from parse() + * @param n1 The first number + * @param n2 The second number + * @param parse_args The parse() parameters + * @param invert Is the result high number bad or good? + * @return The colored percentage with ending % + */ +APICALL EXPORT std::string get_and_color_percentage(const float n1, const float n2, parse_args_t& parse_args, + const bool invert = false); diff --git a/include/parse.hpp b/include/parse.hpp index 9f7666f2..074f55c3 100644 --- a/include/parse.hpp +++ b/include/parse.hpp @@ -26,83 +26,18 @@ #ifndef _PARSE_HPP #define _PARSE_HPP -#include <string> -#include <vector> +#include "cufetch/parse.hh" -#include "cufetch/cufetch.hh" - -/* The additional args that parse() needs for getting the necessary infos/configs. - * Only used for making the argument passing more clear. - * Always pass it non-const and by reference - */ -struct parse_args_t -{ - const moduleMap_t& modulesInfo; - std::string& pureOutput; - std::vector<std::string>& layout; - std::vector<std::string>& tmp_layout; - const ConfigBase& config; - bool parsingLayout; - bool firstrun_clr = true; - bool no_more_reset = false; -}; - -/* Parse input, in-place, with data from modulesInfo. - * Documentation on formatting is in the flag -w or the customfetch.1 manual. - * @param input The string to parse - * @param modulesInfo The system infos - * @param pureOutput The output of the string but without tags - * @param layout The layout of customfetch - * @param tmp_layout The temponary layout to be used for $<auto> modules - * @param config The config - * @param colors The colors - * @param parsingLayout If we are parsing layout or not - * @param no_more_reset If we are recursively parsing, e.g we are inside tags - */ -std::string parse(std::string input, const moduleMap_t& modulesInfo, std::string& pureOutput, - std::vector<std::string>& layout, std::vector<std::string>& tmp_layout, const ConfigBase& config, - const bool parsingLayout, bool& no_more_reset); - -// parse() for parse_args_t& arguments -std::string parse(const std::string& input, parse_args_t& parse_args); // some times we don't want to use the original pureOutput, // so we have to create a tmp string just for the sake of the function arguments std::string parse(const std::string& input, std::string& _, parse_args_t& parse_args); -/* Set module members values to a modulesInfo_t map. - * If the name of said module matches any module name, it will be added - * else, error out. - * @param moduleName The module name - * @param moduleMemberName The module member name - * @param parse_args The parse() like arguments - */ -// void addValueFromModuleMember(const std::string& moduleName, const std::string& moduleMemberName, -// parse_args_t& parse_args); - -/* Set module only values to a modulesInfo_t map. - * If the name of said module matches any module name, it will be added - * else, error out. - * @param moduleName The module name - * @param parse_args The parse() like arguments - */ -// void addValueFromModule(const std::string& moduleName, parse_args_t& parse_args); - /* * Return an info module value * @param parse_args The parse() like arguments * @param moduleName The module name */ -std::string getInfoFromName(const parse_args_t& parse_args, const std::string& moduleName); +std::string getInfoFromName(parse_args_t& parse_args, const std::string& moduleName); -/* - * Create a colored percentage from parse() - * @param n1 The first number - * @param n2 The second number - * @param parse_args The parse() parameters - * @param invert Is the result high number bad or good? - * @return The colored percentage with ending % - */ -std::string get_and_color_percentage(const float n1, const float n2, parse_args_t& parse_args, - const bool invert = false); #endif diff --git a/libcufetch/parse.cc b/libcufetch/parse.cc index 7c0d4360..902010dc 100644 --- a/libcufetch/parse.cc +++ b/libcufetch/parse.cc @@ -39,6 +39,7 @@ #include "cufetch/common.hh" #include "cufetch/config.hh" +#include "cufetch/cufetch.hh" #include "fmt/color.h" #include "fmt/format.h" #include "query.hpp" @@ -243,7 +244,7 @@ std::string get_and_color_percentage(const float n1, const float n2, parse_args_ return parse(fmt::format("{}{:.2f}%${{0}}", color, result), _, parse_args); } -std::string getInfoFromName(const parse_args_t& parse_args, const std::string& moduleName) +std::string getInfoFromName(parse_args_t& parse_args, const std::string& moduleName) { std::string name; name.reserve(moduleName.size()); @@ -284,9 +285,7 @@ std::string getInfoFromName(const parse_args_t& parse_args, const std::string& m moduleArgs_t* moduleArg = moduleArgs; while (moduleArg->next != nullptr) - { moduleArg = moduleArg->next; - } moduleArg->name = std::string{ name.begin() + start_pos, name.end() }; moduleArg->value = arg; @@ -325,7 +324,7 @@ std::string getInfoFromName(const parse_args_t& parse_args, const std::string& m std::string result = "(unknown/invalid module)"; if (const auto& it = parse_args.modulesInfo.find(name); it != parse_args.modulesInfo.end()) { - struct callbackInfo_t callbackInfo = { moduleArgs, parse_args.modulesInfo, parse_args.config }; + struct callbackInfo_t callbackInfo = { moduleArgs, parse_args }; result = it->second.handler(&callbackInfo); } @@ -854,20 +853,6 @@ EXPORT std::string parse(std::string input, const moduleMap_t& modulesInfo, std: return ret; } -APICALL EXPORT std::string parse(const std::string& input, const moduleMap_t& modulesInfo, const ConfigBase& config) -{ - std::vector<std::string> nah; - parse_args_t parse_args{ modulesInfo, _, nah, nah, config, true, true, true}; - return parse(input, parse_args); -} - -APICALL EXPORT std::string get_and_color_percentage(const float n1, const float n2, const callbackInfo_t* callback, const bool invert) -{ - std::vector<std::string> nah; - parse_args_t parse_args{ callback->modulesInfo, _, nah, nah, callback->config, true, true, true}; - return get_and_color_percentage(n1, n2, parse_args, invert); -} - // Re-enable them later // trying some plugins stuff #if 0 diff --git a/src/core-plugins/core-modules.cc b/src/core-plugins/core-modules.cc index 27e87afa..51aa536b 100644 --- a/src/core-plugins/core-modules.cc +++ b/src/core-plugins/core-modules.cc @@ -77,13 +77,13 @@ static std::string get_colors_symbol(const callbackInfo_t* callback, bool is_lig fmt::format("${{\033[90m}} {0} ${{\033[91m}} {0} ${{\033[92m}} {0} ${{\033[93m}} {0} ${{\033[94m}} " "{0} ${{\033[95m}} {0} ${{\033[96m}} {0} ${{\033[97m}} {0} ${{0}}", symbolArg->value), - callback->modulesInfo, callback->config); + callback->parse_args); else return parse( fmt::format("${{\033[30m}} {0} ${{\033[31m}} {0} ${{\033[32m}} {0} ${{\033[33m}} {0} ${{\033[34m}} " "{0} ${{\033[35m}} {0} ${{\033[36m}} {0} ${{\033[37m}} {0} ${{0}}", symbolArg->value), - callback->modulesInfo, callback->config); + callback->parse_args); } void core_plugins_start(const Config& config) @@ -258,8 +258,8 @@ void core_plugins_start(const Config& config) cfRegisterModule(user_module); // $<ram> - module_t ram_free_perc_module = {"perc", "percentage of available amount of RAM in total [82.31%]", {}, [](const callbackInfo_t *callback) {return get_and_color_percentage(ram_free(), ram_total(), callback, true);}}; - module_t ram_used_perc_module = {"perc", "percentage of used amount of RAM in total [17.69%]", {}, [](const callbackInfo_t *callback) {return get_and_color_percentage(ram_used(), ram_total(), callback, false);}}; + module_t ram_free_perc_module = {"perc", "percentage of available amount of RAM in total [82.31%]", {}, [](const callbackInfo_t *callback) {return get_and_color_percentage(ram_free(), ram_total(), callback->parse_args, true);}}; + module_t ram_used_perc_module = {"perc", "percentage of used amount of RAM in total [17.69%]", {}, [](const callbackInfo_t *callback) {return get_and_color_percentage(ram_used(), ram_total(), callback->parse_args, false);}}; module_t ram_free_module = {"free", "available amount of RAM (auto) [10.46 GiB]", {std::move(ram_free_perc_module)}, [](const callbackInfo_t *callback) { return amount(ram_free() * 1024, callback->moduleArgs); }}; module_t ram_used_module = {"used", "used amount of RAM (auto) [2.81 GiB]", {std::move(ram_used_perc_module)}, [](const callbackInfo_t *callback) { return amount(ram_used() * 1024, callback->moduleArgs); }}; module_t ram_total_module = {"total", "total amount of RAM (auto) [15.88 GiB]", {}, [](const callbackInfo_t *callback) { return amount(ram_total() * 1024, callback->moduleArgs); }}; @@ -272,8 +272,8 @@ void core_plugins_start(const Config& config) cfRegisterModule(ram_module); // $<swap> - module_t swap_free_perc_module = {"perc", "percentage of available amount of the swapfile in total [6.71%]", {}, [](const callbackInfo_t *callback) {return get_and_color_percentage(swap_free(), swap_total(), callback, true);}}; - module_t swap_used_perc_module = {"perc", "percentage of used amount of the swapfile in total [93.29%]", {}, [](const callbackInfo_t *callback) {return get_and_color_percentage(swap_used(), swap_total(), callback, false);}}; + module_t swap_free_perc_module = {"perc", "percentage of available amount of the swapfile in total [6.71%]", {}, [](const callbackInfo_t *callback) {return get_and_color_percentage(swap_free(), swap_total(), callback->parse_args, true);}}; + module_t swap_used_perc_module = {"perc", "percentage of used amount of the swapfile in total [93.29%]", {}, [](const callbackInfo_t *callback) {return get_and_color_percentage(swap_used(), swap_total(), callback->parse_args, false);}}; module_t swap_free_module = {"free", "available amount of the swapfile (auto) [34.32 MiB]", {std::move(swap_free_perc_module)}, [](const callbackInfo_t *callback) { return amount(swap_free() * 1024, callback->moduleArgs); }}; module_t swap_used_module = {"used", "used amount of the swapfile (auto) [477.68 MiB]", {std::move(swap_used_perc_module)}, [](const callbackInfo_t *callback) { return amount(swap_used() * 1024, callback->moduleArgs); }}; module_t swap_total_module = {"total", "total amount of the swapfile (auto) [512.00 MiB]", {}, [](const callbackInfo_t *callback) { return amount(swap_total() * 1024, callback->moduleArgs); }}; @@ -291,8 +291,8 @@ void core_plugins_start(const Config& config) module_t disk_mountdir_module = {"mountdir", "path to the device mount point [/]", {}, disk_mountdir}; module_t disk_types_module = {"types", "an array of type options (pretty format) [Regular, External]", {}, disk_types}; - module_t disk_free_perc_module = {"perc", "percentage of available amount of the disk in total [17.82%]", {}, [](const callbackInfo_t *callback) {return get_and_color_percentage(disk_free(callback), disk_total(callback), callback, true);}}; - module_t disk_used_perc_module = {"perc", "percentage of used amount of the disk in total [82.18%]", {}, [](const callbackInfo_t *callback) {return get_and_color_percentage(disk_used(callback), disk_total(callback), callback, false);}}; + module_t disk_free_perc_module = {"perc", "percentage of available amount of the disk in total [17.82%]", {}, [](const callbackInfo_t *callback) {return get_and_color_percentage(disk_free(callback), disk_total(callback), callback->parse_args, true);}}; + module_t disk_used_perc_module = {"perc", "percentage of used amount of the disk in total [82.18%]", {}, [](const callbackInfo_t *callback) {return get_and_color_percentage(disk_used(callback), disk_total(callback), callback->parse_args, false);}}; module_t disk_free_module = {"free", "available amount of disk space (auto) [438.08 GiB]", {std::move(disk_free_perc_module)}, [](const callbackInfo_t *callback) { return amount(disk_free(callback), callback->moduleArgs); }}; module_t disk_used_module = {"used", "used amount of disk space (auto) [360.02 GiB]", {std::move(disk_used_perc_module)}, [](const callbackInfo_t *callback) { return amount(disk_used(callback), callback->moduleArgs); }}; module_t disk_total_module = {"total", "total amount of disk space (auto) [100.08 GiB]", {}, [](const callbackInfo_t *callback) { return amount(disk_total(callback), callback->moduleArgs); }}; @@ -363,8 +363,7 @@ void core_plugins_start(const Config& config) return str; } }; module_t title_module = { "title", "user and hostname colored with ${auto2} [toni@arch2]", { std::move(title_sep_module) }, [](const callbackInfo_t* callback) { - return parse("${auto2}$<user.name>${0}@${auto2}$<os.hostname>", callback->modulesInfo, - callback->config); + return parse("${auto2}$<user.name>${0}@${auto2}$<os.hostname>", callback->parse_args); } }; cfRegisterModule(title_module); @@ -374,8 +373,7 @@ void core_plugins_start(const Config& config) module_t colors_light_module = { "light", "light color palette with background spaces", { std::move(colors_light_symbol_module) }, [](const callbackInfo_t* callback) { return parse( "${\033[100m} ${\033[101m} ${\033[102m} ${\033[103m} ${\033[104m} " - " ${\033[105m} ${\033[106m} ${\033[107m} ${0}", - callback->modulesInfo, callback->config); + " ${\033[105m} ${\033[106m} ${\033[107m} ${0}", callback->parse_args); } }; module_t colors_module = { "colors", "color palette with background spaces", { std::move(colors_symbol_module), std::move(colors_light_module) }, @@ -383,18 +381,15 @@ void core_plugins_start(const Config& config) return parse( "${\033[40m} ${\033[41m} ${\033[42m} ${\033[43m} ${\033[44m} " "${\033[45m} ${\033[46m} ${\033[47m} ${0}", - callback->modulesInfo, callback->config); + callback->parse_args); } }; cfRegisterModule(colors_module); } void core_plugins_finish() { -#if CF_LINUX if (mountsFile) fclose(mountsFile); if (os_release) fclose(os_release); if (meminfo) fclose(meminfo); if (cpuinfo) fclose(cpuinfo); - if (g_pwd) free(g_pwd); -#endif } diff --git a/src/main.cpp b/src/main.cpp index af3ae76c..b6789850 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -36,8 +36,7 @@ #include <thread> #include <vector> -#include "cufetch/config.hh" -#include "cufetch/cufetch.hh" +#include "core-modules.hh" #include "display.hpp" #include "fmt/base.h" #include "fmt/ranges.h" @@ -592,10 +591,6 @@ static void localize(void) } // clang-format on -void core_plugins_start(const Config& config); -void core_plugins_finish(); - - int main(int argc, char *argv[]) { const std::filesystem::path& configDir = getConfigDir(); From a25674994cd61d34bee193ef6dfb784956f2b665 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Mon, 7 Jul 2025 20:59:34 +0200 Subject: [PATCH 073/143] cmake: fix build broken commit after lucky one, bad sign to gamble dammit --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7d2b58fb..49b16765 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,6 +20,7 @@ set_source_files_properties( file(GLOB SRC "src/*.cpp" + "src/core-plugins/*.cc" "src/core-plugins/linux/*.cc" "src/query/android/*.cpp" "src/query/macos/*.cpp" From 7655c05c008f2ddf68b0a26b954b9386cb3cf514 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Tue, 8 Jul 2025 12:12:02 +0200 Subject: [PATCH 074/143] chore: rename core-plugins -> core-modules --- CMakeLists.txt | 6 +++--- Makefile | 4 ++-- src/{core-plugins => core-modules}/core-modules.cc | 0 src/{core-plugins => core-modules}/linux/battery.cc | 0 src/{core-plugins => core-modules}/linux/cpu.cc | 0 src/{core-plugins => core-modules}/linux/disk.cc | 0 src/{core-plugins => core-modules}/linux/gpu.cc | 0 src/{core-plugins => core-modules}/linux/os.cc | 0 src/{core-plugins => core-modules}/linux/ram.cc | 0 src/{core-plugins => core-modules}/linux/system.cc | 0 src/{core-plugins => core-modules}/linux/user.cc | 0 src/{core-plugins => core-modules}/linux/utils | 0 12 files changed, 5 insertions(+), 5 deletions(-) rename src/{core-plugins => core-modules}/core-modules.cc (100%) rename src/{core-plugins => core-modules}/linux/battery.cc (100%) rename src/{core-plugins => core-modules}/linux/cpu.cc (100%) rename src/{core-plugins => core-modules}/linux/disk.cc (100%) rename src/{core-plugins => core-modules}/linux/gpu.cc (100%) rename src/{core-plugins => core-modules}/linux/os.cc (100%) rename src/{core-plugins => core-modules}/linux/ram.cc (100%) rename src/{core-plugins => core-modules}/linux/system.cc (100%) rename src/{core-plugins => core-modules}/linux/user.cc (100%) rename src/{core-plugins => core-modules}/linux/utils (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 49b16765..2ffedf41 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,11 +20,11 @@ set_source_files_properties( file(GLOB SRC "src/*.cpp" - "src/core-plugins/*.cc" - "src/core-plugins/linux/*.cc" + "src/core-modules/*.cc" + "src/core-modules/linux/*.cc" "src/query/android/*.cpp" "src/query/macos/*.cpp" - "src/core-plugins/linux/utils/*.cpp" + "src/core-modules/linux/utils/*.cpp" "src/libs/json/json.cpp" "src/libs/toml++/toml.cpp") diff --git a/Makefile b/Makefile index da9a40dc..574db160 100644 --- a/Makefile +++ b/Makefile @@ -46,8 +46,8 @@ NAME = customfetch TARGET ?= $(NAME) OLDVERSION = 0.10.2 VERSION = 1.0.0 -SRC_CPP = $(wildcard src/*.cpp src/core-plugins/linux/utils/*.cpp) -SRC_CC = $(wildcard src/core-plugins/*.cc src/core-plugins/linux/*.cc) +SRC_CPP = $(wildcard src/*.cpp src/core-modules/linux/utils/*.cpp) +SRC_CC = $(wildcard src/core-modules/*.cc src/core-modules/linux/*.cc) OBJ_CPP = $(SRC_CPP:.cpp=.o) OBJ_CC = $(SRC_CC:.cc=.o) OBJ = $(OBJ_CPP) $(OBJ_CC) diff --git a/src/core-plugins/core-modules.cc b/src/core-modules/core-modules.cc similarity index 100% rename from src/core-plugins/core-modules.cc rename to src/core-modules/core-modules.cc diff --git a/src/core-plugins/linux/battery.cc b/src/core-modules/linux/battery.cc similarity index 100% rename from src/core-plugins/linux/battery.cc rename to src/core-modules/linux/battery.cc diff --git a/src/core-plugins/linux/cpu.cc b/src/core-modules/linux/cpu.cc similarity index 100% rename from src/core-plugins/linux/cpu.cc rename to src/core-modules/linux/cpu.cc diff --git a/src/core-plugins/linux/disk.cc b/src/core-modules/linux/disk.cc similarity index 100% rename from src/core-plugins/linux/disk.cc rename to src/core-modules/linux/disk.cc diff --git a/src/core-plugins/linux/gpu.cc b/src/core-modules/linux/gpu.cc similarity index 100% rename from src/core-plugins/linux/gpu.cc rename to src/core-modules/linux/gpu.cc diff --git a/src/core-plugins/linux/os.cc b/src/core-modules/linux/os.cc similarity index 100% rename from src/core-plugins/linux/os.cc rename to src/core-modules/linux/os.cc diff --git a/src/core-plugins/linux/ram.cc b/src/core-modules/linux/ram.cc similarity index 100% rename from src/core-plugins/linux/ram.cc rename to src/core-modules/linux/ram.cc diff --git a/src/core-plugins/linux/system.cc b/src/core-modules/linux/system.cc similarity index 100% rename from src/core-plugins/linux/system.cc rename to src/core-modules/linux/system.cc diff --git a/src/core-plugins/linux/user.cc b/src/core-modules/linux/user.cc similarity index 100% rename from src/core-plugins/linux/user.cc rename to src/core-modules/linux/user.cc diff --git a/src/core-plugins/linux/utils b/src/core-modules/linux/utils similarity index 100% rename from src/core-plugins/linux/utils rename to src/core-modules/linux/utils From 44b9218a842657f5fa8bfafd88a4c7d3928666ee Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Tue, 8 Jul 2025 16:10:02 +0200 Subject: [PATCH 075/143] core-modules: linux: add auto module --- include/core-modules.hh | 9 ++++ libcufetch/Makefile | 2 +- src/core-modules/core-modules.cc | 33 ++++++++++++- src/core-modules/linux/disk.cc | 82 ++++++++++++++++++++++++++------ 4 files changed, 110 insertions(+), 16 deletions(-) diff --git a/include/core-modules.hh b/include/core-modules.hh index 7aa55c0e..0a27cb5c 100644 --- a/include/core-modules.hh +++ b/include/core-modules.hh @@ -66,11 +66,20 @@ double swap_total(); double swap_used(); // disk.cc +enum +{ + DISK_VOLUME_TYPE_HIDDEN = 1 << 2, + DISK_VOLUME_TYPE_REGULAR = 1 << 3, + DISK_VOLUME_TYPE_EXTERNAL = 1 << 4, + DISK_VOLUME_TYPE_READ_ONLY = 1 << 5, +}; + inline std::FILE* mountsFile; MODFUNC(disk_fsname); MODFUNC(disk_device); MODFUNC(disk_mountdir); MODFUNC(disk_types); +MODFUNC(auto_disk); double disk_total(const callbackInfo_t* callbackInfo); double disk_free(const callbackInfo_t* callbackInfo); double disk_used(const callbackInfo_t* callbackInfo); diff --git a/libcufetch/Makefile b/libcufetch/Makefile index 71bbfff7..664f2429 100644 --- a/libcufetch/Makefile +++ b/libcufetch/Makefile @@ -4,7 +4,7 @@ SRC = $(wildcard *.cc) OBJ = $(SRC:.cc=.o) FMT_STATIC = ../$(BUILDDIR)/libfmt.a CXX_INCLUDES = -I../include -CXX_FLAGS = -shared -fPIC -DGUI_APP=$(GUI_APP) +CXX_FLAGS = -ggdb3 -shared -fPIC -DGUI_APP=$(GUI_APP) all: libcufetch diff --git a/src/core-modules/core-modules.cc b/src/core-modules/core-modules.cc index 51aa536b..7749aa37 100644 --- a/src/core-modules/core-modules.cc +++ b/src/core-modules/core-modules.cc @@ -86,6 +86,32 @@ static std::string get_colors_symbol(const callbackInfo_t* callback, bool is_lig callback->parse_args); } +MODFUNC(disk_fmt) +{ + const callbackInfo_t *callback = callbackInfo; + const double used = disk_used(callback); + const double total = disk_total(callback); + const std::string& perc = + get_and_color_percentage(used, total, callback->parse_args, false); + + // clang-format off + std::string result {fmt::format("{} / {} {}", + amount(used, callback->moduleArgs), + amount(total, callback->moduleArgs), + parse("${0}(" + perc + ")", callback->parse_args)) + }; + // clang-format on + const std::string& fsname = disk_fsname(callback); + if (fsname != MAGIC_LINE) + result += " - " + fsname; + + const std::string& types = disk_types(callback); + if (!types.empty()) + result += " [" + types + "]"; + + return result; +} + void core_plugins_start(const Config& config) { // ------------ INIT STUFF ------------ @@ -305,7 +331,7 @@ void core_plugins_start(const Config& config) std::move(disk_free_module), std::move(disk_used_module), std::move(disk_total_module), - }, NULL}; + }, disk_fmt}; cfRegisterModule(disk_module); // $<battery> @@ -350,6 +376,11 @@ void core_plugins_start(const Config& config) }, [](const callbackInfo_t *callback) {return shorten_vendor_name(gpu_vendor(callback)) + " " + gpu_name(callback);}}; cfRegisterModule(gpu_module); + // $<auto> + module_t auto_disk_module = {"disk", "Query all disks based on auto.disk.display-types", {}, auto_disk}; + module_t auto_module = {"auto", "", {std::move(auto_disk_module)}, NULL}; + cfRegisterModule(auto_module); + // $<title> module_t title_sep_module = { "sep", "separator between the title and the system infos (with the title length) [--------]", {}, [&](unused) { const size_t title_len = diff --git a/src/core-modules/linux/disk.cc b/src/core-modules/linux/disk.cc index b3dc55c1..f9896d5c 100644 --- a/src/core-modules/linux/disk.cc +++ b/src/core-modules/linux/disk.cc @@ -7,16 +7,10 @@ #include "cufetch/common.hh" #include "core-modules.hh" +#include "cufetch/config.hh" +#include "switch_fnv1a.hpp" #include "util.hpp" -enum -{ - DISK_VOLUME_TYPE_HIDDEN = 1 << 2, - DISK_VOLUME_TYPE_REGULAR = 1 << 3, - DISK_VOLUME_TYPE_EXTERNAL = 1 << 4, - DISK_VOLUME_TYPE_READ_ONLY = 1 << 5, -}; - // https://github.com/fastfetch-cli/fastfetch/blob/dev/src/detection/disk/disk_linux.c static bool is_physical_device(const mntent* device) { @@ -121,6 +115,21 @@ static int get_disk_type(const mntent* device) #endif } +static std::string format_auto_query_string(std::string str, const struct mntent* device) +{ + replace_str(str, "%1", device->mnt_dir); + replace_str(str, "%2", device->mnt_fsname); + replace_str(str, "%3", device->mnt_type); + + replace_str(str, "%4", fmt::format("$<disk({}).total>", device->mnt_dir)); + replace_str(str, "%5", fmt::format("$<disk({}).free>", device->mnt_dir)); + replace_str(str, "%6", fmt::format("$<disk({}).used>", device->mnt_dir)); + replace_str(str, "%7", fmt::format("$<disk({}).used_perc>", device->mnt_dir)); + replace_str(str, "%8", fmt::format("$<disk({}).free_perc>", device->mnt_dir)); + + return str; +} + static struct mntent* get_disk_info(const callbackInfo_t* callbackInfo) { if (callbackInfo->moduleArgs->name != "disk" || @@ -129,21 +138,18 @@ static struct mntent* get_disk_info(const callbackInfo_t* callbackInfo) const std::string& path = callbackInfo->moduleArgs->value; if (access(path.c_str(), F_OK) != 0 || !mountsFile) - return NULL; + die("Failed to query disk at path: '{}", path); struct mntent* pDevice; while ((pDevice = getmntent(mountsFile))) { debug("pDevice->mnt_dir = {:<50} && pDevice->mnt_fsname = {}", pDevice->mnt_dir, pDevice->mnt_fsname); if (path == pDevice->mnt_dir || path == pDevice->mnt_fsname) - { - rewind(mountsFile); - return pDevice; - } + break; } rewind(mountsFile); - return NULL; + return pDevice; } static bool get_disk_usage_info(const callbackInfo_t* callbackInfo, struct statvfs* fs) @@ -182,6 +188,54 @@ MODFUNC(disk_types) return str; } +MODFUNC(auto_disk) +{ + static std::vector<std::string> queried_devices; + const ConfigBase& config = callbackInfo->parse_args.config; + const std::string& auto_disks_fmt = config.getValue<std::string>("auto.disk.fmt", "${auto}Disk (%1): $<disk(%1)>"); + int auto_disks_types = 0; + for (const std::string& str : config.getValueArrayStr("auto.disk.display-types", {"external", "regular", "read-only"})) + { + switch (fnv1a16::hash(str)) + { + case "removable"_fnv1a16: // deprecated + case "external"_fnv1a16: + auto_disks_types |= DISK_VOLUME_TYPE_EXTERNAL; break; + case "regular"_fnv1a16: + auto_disks_types |= DISK_VOLUME_TYPE_REGULAR; break; + case "read-only"_fnv1a16: + auto_disks_types |= DISK_VOLUME_TYPE_READ_ONLY; break; + case "hidden"_fnv1a16: + auto_disks_types |= DISK_VOLUME_TYPE_HIDDEN; break; + } + } + + long old_position = ftell(mountsFile); + if (old_position == -1L) + die("Failed to get initial file position"); + + struct mntent* pDevice; + while ((pDevice = getmntent(mountsFile))) + { + if (!is_physical_device(pDevice)) + continue; + + if (!(auto_disks_types & get_disk_type(pDevice))) + continue; + + old_position = ftell(mountsFile); + if (old_position == -1L) + break; + + debug("AUTO: pDevice->mnt_dir = {} && pDevice->mnt_fsname = {}", pDevice->mnt_dir, pDevice->mnt_fsname); + callbackInfo->parse_args.no_more_reset = false; + callbackInfo->parse_args.tmp_layout.push_back(parse(format_auto_query_string(auto_disks_fmt, pDevice), callbackInfo->parse_args)); + if (fseek(mountsFile, old_position, SEEK_SET) == -1) + die("Failed to seek back to saved position"); + } + return ""; +} + double disk_total(const callbackInfo_t* callbackInfo) { struct statvfs fs; From 282479550f77063dfe5b935229877ab3d191996c Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Tue, 8 Jul 2025 23:59:57 +0200 Subject: [PATCH 076/143] core-modules: linux: add theme module (some things still to be added) ughhhhhhhhhhhhhh so damn painful --- include/core-modules.hh | 15 +- libcufetch/parse.cc | 39 --- src/core-modules/core-modules.cc | 53 +++- src/core-modules/linux/os.cc | 2 +- src/core-modules/linux/theme.cc | 460 +++++++++++++++++++++++++++++++ src/core-modules/linux/user.cc | 55 +++- src/display.cpp | 4 +- 7 files changed, 564 insertions(+), 64 deletions(-) create mode 100644 src/core-modules/linux/theme.cc diff --git a/include/core-modules.hh b/include/core-modules.hh index 0a27cb5c..32ff3223 100644 --- a/include/core-modules.hh +++ b/include/core-modules.hh @@ -7,7 +7,7 @@ #include "cufetch/cufetch.hh" #include "config.hpp" -#define MODFUNC(name) std::string name(__attribute__((unused)) const callbackInfo_t* callbackInfo = nullptr) +#define MODFUNC(name) std::string name(__attribute__((unused)) const callbackInfo_t* callbackInfo) // system.cc MODFUNC(arch); @@ -97,13 +97,20 @@ double battery_temp(); MODFUNC(gpu_name); MODFUNC(gpu_vendor); +// theme.cc +MODFUNC(theme_gtk_name); +MODFUNC(theme_gtk_icon); +MODFUNC(theme_gtk_font); +MODFUNC(theme_cursor_name); +MODFUNC(theme_cursor_size); +MODFUNC(theme_gsettings_name); +MODFUNC(theme_gsettings_icon); +MODFUNC(theme_gsettings_font); + #if CF_LINUX inline struct passwd* g_pwd; inline utsname g_uname_infos; #endif -#undef MODFUNC -#define MODFUNC(name) std::string name(__attribute__((unused)) const callbackInfo_t* callbackInfo) - void core_plugins_start(const Config& config); void core_plugins_finish(); diff --git a/libcufetch/parse.cc b/libcufetch/parse.cc index 902010dc..cb6d4450 100644 --- a/libcufetch/parse.cc +++ b/libcufetch/parse.cc @@ -898,45 +898,6 @@ static std::string get_auto_gtk_format(const std::string_view gtk2, const std::s return MAGIC_LINE; } -static std::string prettify_term_name(const std::string_view term_name) -{ - switch (fnv1a16::hash(str_tolower(term_name.data()))) - { - case "gnome-terminal"_fnv1a16: - case "gnome terminal"_fnv1a16: return "GNOME Terminal"; - - case "gnome-console"_fnv1a16: - case "gnome console"_fnv1a16: return "GNOME console"; - } - return term_name.data(); -} - -static std::string prettify_de_name(const std::string_view de_name) -{ - switch (fnv1a16::hash(str_tolower(de_name.data()))) - { - case "kde"_fnv1a16: - case "plasma"_fnv1a16: - case "plasmashell"_fnv1a16: - case "plasmawayland"_fnv1a16: return "KDE Plasma"; - - case "gnome"_fnv1a16: - case "gnome-shell"_fnv1a16: return "GNOME"; - - case "xfce"_fnv1a16: - case "xfce4"_fnv1a16: - case "xfce4-session"_fnv1a16: return "Xfce4"; - - case "mate"_fnv1a16: - case "mate-session"_fnv1a16: return "Mate"; - - case "lxqt"_fnv1a16: - case "lxqt-session"_fnv1a16: return "LXQt"; - } - - return de_name.data(); -} - moduleMap_t queried_gpus; moduleMap_t queried_disks; moduleMap_t queried_themes_names; diff --git a/src/core-modules/core-modules.cc b/src/core-modules/core-modules.cc index 7749aa37..0c0b0354 100644 --- a/src/core-modules/core-modules.cc +++ b/src/core-modules/core-modules.cc @@ -167,14 +167,14 @@ void core_plugins_start(const Config& config) module_t os_kernel_module = {"kernel", "kernel name and version [Linux 6.9.3-zen1-1-zen]", { std::move(os_kernel_name_module), std::move(os_kernel_version_module) - }, [](unused) {return os_kernel_name() + " " + os_kernel_version();}}; + }, [](unused _) {return os_kernel_name(_) + " " + os_kernel_version(_);}}; module_t os_initsys_name_module = {"name", "Init system name [systemd]", {}, os_initsys_name}; module_t os_initsys_version_module = {"version", "Init system version [256.5-1-arch]", {}, os_initsys_version}; module_t os_initsys_module = {"initsys", "Init system name and version [systemd 256.5-1-arch]", { std::move(os_initsys_name_module), std::move(os_initsys_version_module), - }, [](unused) {return os_initsys_name() + " " + os_initsys_version();}}; + }, [](unused _) {return os_initsys_name(_) + " " + os_initsys_version(_);}}; module_t os_pkgs_module = {"pkgs", "Count of system packages", {}, [&](unused){ return get_all_pkgs(config); }}; @@ -236,8 +236,8 @@ void core_plugins_start(const Config& config) std::move(cpu_nproc_module), std::move(cpu_freq_module), std::move(cpu_temp_module), - }, [](unused) { - return fmt::format("{} ({}) @ {} GHz", cpu_name(), cpu_nproc(), cpu_freq_max()); + }, [](unused _) { + return fmt::format("{} ({}) @ {} GHz", cpu_name(_), cpu_nproc(_), cpu_freq_max(_)); }}; cfRegisterModule(cpu_module); @@ -251,28 +251,28 @@ void core_plugins_start(const Config& config) std::move(user_shell_name_module), std::move(user_shell_path_module), std::move(user_shell_version_module), - }, [](unused) {return user_shell_name() + " " + user_shell_version();}}; + }, [](unused _) {return user_shell_name(_) + " " + user_shell_version(_);}}; module_t user_term_name_module = {"name", "terminal name [alacritty]", {}, user_term_name}; module_t user_term_version_module = {"version", "terminal version [0.13.2]", {}, user_shell_version}; module_t user_term_module = {"terminal", "terminal name and version [alacritty 0.13.2]", { std::move(user_term_version_module), std::move(user_term_name_module) - }, [](unused) {return user_term_name() + " " + user_term_version();}}; + }, [](unused _) {return user_term_name(_) + " " + user_term_version(_);}}; module_t user_wm_name_module = {"name", "Window Manager current session name [dwm; xfwm4]", {}, user_wm_name}; module_t user_wm_version_module = {"version", "Window Manager version (may not work correctly) [6.2; 4.18.0]", {}, user_wm_version}; module_t user_wm_module = {"wm", "Window Manager current session name and version", { std::move(user_wm_version_module), std::move(user_wm_name_module) - }, [](unused) {return user_wm_name() + " " + user_wm_version();}}; + }, [](unused _) {return user_wm_name(_) + " " + user_wm_version(_);}}; module_t user_de_name_module = {"name", "Desktop Environment current session name [Plasma]", {}, user_de_name}; module_t user_de_version_module = {"version", "Desktop Environment version (if available)", {}, user_de_version}; module_t user_de_module = {"de", "Desktop Environment current session name and version", { std::move(user_de_version_module), std::move(user_de_name_module) - }, [](unused) {return user_de_name() + " " + user_de_version();}}; + }, [](unused _) {return user_de_name(_) + " " + user_de_version(_);}}; module_t user_module = {"user", "User modules", { std::move(user_name_module), @@ -362,6 +362,39 @@ void core_plugins_start(const Config& config) }, NULL}; cfRegisterModule(battery_module); + // $<theme> + module_t theme_gtk_name_module = {"name", "", {}, theme_gtk_name}; + module_t theme_gtk_font_module = {"font", "", {}, theme_gtk_font}; + module_t theme_gtk_icon_module = {"icon", "", {}, theme_gtk_icon}; + module_t theme_gtk_module = {"gtk", "", { + std::move(theme_gtk_name_module), + std::move(theme_gtk_font_module), + std::move(theme_gtk_icon_module) + }, NULL}; + + module_t theme_gsettings_name_module = {"name", "", {}, theme_gsettings_name}; + module_t theme_gsettings_font_module = {"font", "", {}, theme_gsettings_font}; + module_t theme_gsettings_icon_module = {"icon", "", {}, theme_gsettings_icon}; + module_t theme_gsettings_module = {"gsettings", "", { + std::move(theme_gsettings_name_module), + std::move(theme_gsettings_font_module), + std::move(theme_gsettings_icon_module) + }, NULL}; + + module_t theme_cursor_name_module = {"name", "", {}, theme_cursor_name}; + module_t theme_cursor_size_module = {"size", "", {}, theme_cursor_size}; + module_t theme_cursor_module = {"cursor", "", { + std::move(theme_cursor_size_module), + std::move(theme_cursor_name_module), + }, NULL}; + + module_t theme_module = {"theme", "", { + std::move(theme_gtk_module), + std::move(theme_gsettings_module), + std::move(theme_cursor_module), + }, NULL}; + cfRegisterModule(theme_module); + // $<gpu> module_t gpu_name_module = {"name", "GPU model name [GeForce GTX 1650]", {}, gpu_name}; module_t gpu_vendor_short_module = {"short", "GPU short vendor name [NVIDIA]", {}, [](const callbackInfo_t *callback) { @@ -382,9 +415,9 @@ void core_plugins_start(const Config& config) cfRegisterModule(auto_module); // $<title> - module_t title_sep_module = { "sep", "separator between the title and the system infos (with the title length) [--------]", {}, [&](unused) { + module_t title_sep_module = { "sep", "separator between the title and the system infos (with the title length) [--------]", {}, [&](unused _) { const size_t title_len = - std::string_view(user_name() + "@" + os_hostname()).length(); + std::string_view(user_name(_) + "@" + os_hostname(_)).length(); std::string str; str.reserve(config.title_sep.length() * title_len); diff --git a/src/core-modules/linux/os.cc b/src/core-modules/linux/os.cc index 149ad7aa..68bd60e8 100644 --- a/src/core-modules/linux/os.cc +++ b/src/core-modules/linux/os.cc @@ -115,7 +115,7 @@ MODFUNC(os_initsys_version) std::ifstream f(path, std::ios::in); std::string line; - const std::string& name = str_tolower(os_initsys_name()); + const std::string& name = str_tolower(os_initsys_name(callbackInfo)); switch (fnv1a16::hash(name)) { case "systemd"_fnv1a16: diff --git a/src/core-modules/linux/theme.cc b/src/core-modules/linux/theme.cc new file mode 100644 index 00000000..8f5ea87b --- /dev/null +++ b/src/core-modules/linux/theme.cc @@ -0,0 +1,460 @@ +#include "platform.hpp" +#if CF_LINUX + +#include <fstream> +#include <functional> +#include <array> +#include <algorithm> +#include <cstdint> + +#include "core-modules.hh" +#include "fmt/format.h" +#include "rapidxml-1.13/rapidxml.hpp" +#include "switch_fnv1a.hpp" +#include "util.hpp" + +#if USE_DCONF +#include <client/dconf-client.h> +#include <glib/gvariant.h> +#endif + +using ThemeInfo = std::array<std::string, 3>; // [theme, icon_theme, font] +using CursorInfo = std::array<std::string, 2>; // [name, size] + +enum +{ + THEME_NAME, + THEME_ICON, + THEME_FONT +}; + +enum +{ + CURSOR_NAME, + CURSOR_SIZE +}; + +const std::string& configDir = getHomeConfigDir(); + +static std::string get_xsettings_xfce4(const std::string_view property, const std::string_view subproperty) +{ + static bool done = false; + static rapidxml::xml_document<> doc; + static std::string buffer; + + if (!done) + { + const std::string& path = configDir + "/xfce4/xfconf/xfce-perchannel-xml/xsettings.xml"; + std::ifstream f(path, std::ios::in); + if (!f.is_open()) + return UNKNOWN; + + buffer.assign(std::istreambuf_iterator<char>{ f }, std::istreambuf_iterator<char>()); + buffer.push_back('\0'); + + doc.parse<0>(&buffer[0]); + done = true; + } + + rapidxml::xml_node<>* node1 = doc.first_node("channel")->first_node("property"); + for (; node1 && std::string_view(node1->first_attribute("name")->value()) != property; + node1 = node1->next_sibling("property")) + ; + + rapidxml::xml_node<>* node2 = node1->first_node("property"); + for (; node2; node2 = node2->next_sibling()) + { + if (std::string_view(node2->first_attribute("name")->value()) == subproperty && node2->first_attribute("value")) + return node2->first_attribute("value")->value(); + } + + return UNKNOWN; +} + +// +// +// 1. Cursor +// +static CursorInfo get_cursor_xresources() +{ + const std::string& path = expandVar("~/.Xresources"); + std::ifstream f(path, std::ios::in); + if (!f.is_open()) + return {UNKNOWN, UNKNOWN}; + + std::string cursor_name, cursor_size; + std::uint16_t iter_index = 0; + std::string line; + while (std::getline(f, line) && iter_index < 2) + { + if (hasStart(line, "Xcursor.theme:")) + { + getFileValue(iter_index, line, cursor_name, "Xcursor.theme:"_len); + strip(cursor_name); + } + + else if (hasStart(line, "Xcursor.size:")) + { + getFileValue(iter_index, line, cursor_size, "Xcursor.size:"_len); + strip(cursor_size); + } + } + + return {cursor_name, cursor_size}; +} + +static CursorInfo get_cursor_dconf(const std::string_view de_name) +{ + std::string cursor{UNKNOWN}, cursor_size{UNKNOWN}; +#if USE_DCONF + void* handle = LOAD_LIBRARY("libdconf.so"); + if (!handle) + return {UNKNOWN, UNKNOWN}; + + LOAD_LIB_SYMBOL(handle, DConfClient*, dconf_client_new, void); + LOAD_LIB_SYMBOL(handle, GVariant*, dconf_client_read, DConfClient*, const char*); + LOAD_LIB_SYMBOL(handle, const gchar*, g_variant_get_string, GVariant*, gsize*); + LOAD_LIB_SYMBOL(handle, gint32, g_variant_get_int32, GVariant*); + + debug("calling {}", __PRETTY_FUNCTION__); + DConfClient* client = dconf_client_new(); + GVariant* variant; + + std::string interface; + switch (fnv1a16::hash(str_tolower(de_name.data()))) + { + case "cinnamon"_fnv1a16: interface = "/org/cinnamon/desktop/interface/"; break; + case "mate"_fnv1a16: interface = "/org/mate/interface/"; break; + default: interface = "/org/gnome/desktop/interface/"; + } + + variant = dconf_client_read(client, (interface + "cursor-theme").c_str()); + if (variant) + cursor = g_variant_get_string(variant, NULL); + + variant = dconf_client_read(client, (interface + "cursor-size").c_str()); + if (variant) + cursor_size = fmt::to_string(g_variant_get_int32(variant)); +#endif + return {cursor, cursor_size}; +} + +static CursorInfo get_cursor_gsettings(const std::string_view de_name) +{ + const CursorInfo& dconf = get_cursor_dconf(de_name); + if (dconf != CursorInfo{UNKNOWN, UNKNOWN}) + return dconf; + const char* interface; + switch (fnv1a16::hash(str_tolower(de_name.data()))) + { + case "cinnamon"_fnv1a16: interface = "org.cinnamon.desktop.interface"; break; + case "mate"_fnv1a16: interface = "org.mate.interface"; break; + default: interface = "org.gnome.desktop.interface"; + } + + std::string cursor{UNKNOWN}; + read_exec({ "gsettings", "get", interface, "cursor-theme" }, cursor); + cursor.erase(std::remove(cursor.begin(), cursor.end(), '\''), cursor.end()); + + std::string cursor_size{UNKNOWN}; + read_exec({ "gsettings", "get", interface, "cursor-size" }, cursor_size); + cursor_size.erase(std::remove(cursor_size.begin(), cursor_size.end(), '\''), cursor_size.end()); + + return {cursor, cursor_size}; +} + +static CursorInfo get_gtk_cursor_config(const std::string_view path) +{ + std::string cursor{UNKNOWN}, cursor_size{UNKNOWN}; + std::ifstream f(path.data(), std::ios::in); + if (!f.is_open()) + return {cursor, cursor_size}; + + std::string line; + std::uint16_t iter_index = 0; + while (std::getline(f, line) && iter_index < 2) + { + if (hasStart(line, "gtk-cursor-theme-name=")) + getFileValue(iter_index, line, cursor, "gtk-cursor-theme-name="_len); + + else if (hasStart(line, "gtk-cursor-theme-size=")) + getFileValue(iter_index, line, cursor_size, "gtk-cursor-theme-size="_len); + } + + return {cursor, cursor_size}; +} + +static CursorInfo get_cursor_from_gtk_configs(const std::uint8_t ver) +{ + const std::array<std::string, 6> paths = { + fmt::format("{}/gtk-{}.0/settings.ini", configDir, ver), + fmt::format("{}/gtk-{}.0/gtkrc", configDir, ver), + fmt::format("{}/gtkrc-{}.0", configDir, ver), + fmt::format("{}/.gtkrc-{}.0", std::getenv("HOME"), ver), + fmt::format("{}/.gtkrc-{}.0-kde", std::getenv("HOME"), ver), + fmt::format("{}/.gtkrc-{}.0-kde4", std::getenv("HOME"), ver) + }; + + for (const std::string& path : paths) + { + const CursorInfo& result = get_gtk_cursor_config(path); + if (result != CursorInfo{UNKNOWN, UNKNOWN}) + return result; + } + return {UNKNOWN, UNKNOWN}; +} + +static CursorInfo get_de_cursor(const std::string_view de_name) +{ + switch (fnv1a16::hash(str_tolower(de_name.data()))) + { + case "xfce"_fnv1a16: + case "xfce4"_fnv1a16: + { + debug("getting info on xfce4"); + return {get_xsettings_xfce4("Gtk", "CursorThemeName"), get_xsettings_xfce4("Gtk", "CursorThemeSize")}; + } + } + return {UNKNOWN, UNKNOWN}; +} + +// +// +// 2. GTK theme +// +static ThemeInfo get_gtk_theme_config(const std::string_view path) +{ + std::string theme{UNKNOWN}, icon_theme{UNKNOWN}, font{UNKNOWN}; + std::ifstream f(path.data(), std::ios::in); + if (!f.is_open()) + return {theme, icon_theme, font}; + + std::string line; + std::uint16_t iter_index = 0; + while (std::getline(f, line) && iter_index < 3) + { + if (hasStart(line, "gtk-theme-name=")) + getFileValue(iter_index, line, theme, "gtk-theme-name="_len); + + else if (hasStart(line, "gtk-icon-theme-name=")) + getFileValue(iter_index, line, icon_theme, "gtk-icon-theme-name="_len); + + else if (hasStart(line, "gtk-font-name=")) + getFileValue(iter_index, line, font, "gtk-font-name="_len); + } + + return {theme, icon_theme, font}; +} + +static ThemeInfo get_gtk_theme_dconf(const std::string_view de_name) +{ + std::string theme{UNKNOWN}, icon_theme{UNKNOWN}, font{UNKNOWN}; +#if USE_DCONF + void* handle = LOAD_LIBRARY("libdconf.so"); + if (!handle) + return {theme, icon_theme, font}; + + LOAD_LIB_SYMBOL(handle, DConfClient*, dconf_client_new, void); + LOAD_LIB_SYMBOL(handle, GVariant*, dconf_client_read, DConfClient * client, const char*); + LOAD_LIB_SYMBOL(handle, const gchar*, g_variant_get_string, GVariant* value, gsize* lenght); + + debug("calling {}", __PRETTY_FUNCTION__); + DConfClient* client = dconf_client_new(); + GVariant* variant; + + std::string interface; + switch (fnv1a16::hash(str_tolower(de_name.data()))) + { + case "cinnamon"_fnv1a16: interface = "/org/cinnamon/desktop/interface/"; break; + case "mate"_fnv1a16: interface = "/org/mate/interface/"; break; + default: interface = "/org/gnome/desktop/interface/"; + } + + variant = dconf_client_read(client, (interface + "gtk-theme").c_str()); + if (variant) + theme = g_variant_get_string(variant, NULL); + + variant = dconf_client_read(client, (interface + "icon-theme").c_str()); + if (variant) + icon_theme = g_variant_get_string(variant, NULL); + + variant = dconf_client_read(client, (interface + "font-name").c_str()); + if (variant) + font = g_variant_get_string(variant, NULL); + +#endif + return {theme, icon_theme, font}; +} + +static ThemeInfo get_gtk_theme_gsettings(const std::string_view de_name) +{ + const ThemeInfo& dconf = get_gtk_theme_dconf(de_name); + if (dconf != ThemeInfo{UNKNOWN, UNKNOWN, UNKNOWN}) + return dconf; + + std::string theme{UNKNOWN}, icon_theme{UNKNOWN}, font{UNKNOWN}; + const char* interface; + switch (fnv1a16::hash(str_tolower(de_name.data()))) + { + case "cinnamon"_fnv1a16: interface = "org.cinnamon.desktop.interface"; break; + case "mate"_fnv1a16: interface = "org.mate.interface"; break; + default: interface = "org.gnome.desktop.interface"; + } + + read_exec({ "gsettings", "get", interface, "gtk-theme" }, theme); + theme.erase(std::remove(theme.begin(), theme.end(), '\''), theme.end()); + + read_exec({ "gsettings", "get", interface, "icon-theme" }, icon_theme); + icon_theme.erase(std::remove(icon_theme.begin(), icon_theme.end(), '\''), icon_theme.end()); + + read_exec({ "gsettings", "get", interface, "font-name" }, font); + font.erase(std::remove(font.begin(), font.end(), '\''), font.end()); + + return {theme, icon_theme, font}; +} + +static ThemeInfo get_gtk_theme_from_configs(const std::uint8_t ver, const std::string_view de_name) +{ + const std::array<std::string, 6> paths = { + fmt::format("{}/gtk-{}.0/settings.ini", configDir, ver), + fmt::format("{}/gtk-{}.0/gtkrc", configDir, ver), + fmt::format("{}/gtkrc-{}.0", configDir, ver), + fmt::format("{}/.gtkrc-{}.0", std::getenv("HOME"), ver), + fmt::format("{}/.gtkrc-{}.0-kde", std::getenv("HOME"), ver), + fmt::format("{}/.gtkrc-{}.0-kde4", std::getenv("HOME"), ver) + }; + + for (const auto& path : paths) + { + const ThemeInfo& result = get_gtk_theme_config(path); + if (result != ThemeInfo{UNKNOWN, UNKNOWN, UNKNOWN}) + return result; + } + return get_gtk_theme_gsettings(de_name); +} + +static ThemeInfo get_de_gtk_theme(const std::string_view de_name, const std::uint8_t ver) +{ + switch (fnv1a16::hash(str_tolower(de_name.data()))) + { + case "xfce"_fnv1a16: + case "xfce4"_fnv1a16: + { + debug("getting info on xfce4"); + return { + get_xsettings_xfce4("Net", "ThemeName"), + get_xsettings_xfce4("Net", "IconThemeName"), + get_xsettings_xfce4("Gtk", "FontName") + }; + } + } + return get_gtk_theme_from_configs(ver, de_name); +} + +const std::string& wmde_name = (de_name != MAGIC_LINE && de_name == wm_name) || de_name == MAGIC_LINE + ? wm_name + : de_name; + +MODFUNC(theme_gtk_name) +{ + const ThemeInfo& result = is_tty + ? get_gtk_theme_from_configs(3, wmde_name) + : get_de_gtk_theme(wmde_name, 3); + + return result[THEME_NAME] == UNKNOWN ? MAGIC_LINE : result[THEME_NAME]; +} + +MODFUNC(theme_gtk_icon) +{ + const ThemeInfo& result = is_tty + ? get_gtk_theme_from_configs(3, wmde_name) + : get_de_gtk_theme(wmde_name, 3); + + return result[THEME_ICON] == UNKNOWN ? MAGIC_LINE : result[THEME_ICON]; +} + +MODFUNC(theme_gtk_font) +{ + const ThemeInfo& result = is_tty + ? get_gtk_theme_from_configs(3, wmde_name) + : get_de_gtk_theme(wmde_name, 3); + + return result[THEME_FONT] == UNKNOWN ? MAGIC_LINE : result[THEME_FONT]; +} + +MODFUNC(theme_gsettings_name) +{ + const ThemeInfo& result = get_gtk_theme_gsettings(de_name); + return result[THEME_NAME] == UNKNOWN ? MAGIC_LINE : result[THEME_NAME]; +} + +MODFUNC(theme_gsettings_icon) +{ + const ThemeInfo& result = get_gtk_theme_gsettings(de_name); + return result[THEME_ICON] == UNKNOWN ? MAGIC_LINE : result[THEME_ICON]; +} + +MODFUNC(theme_gsettings_font) +{ + const ThemeInfo& result = get_gtk_theme_gsettings(de_name); + return result[THEME_FONT] == UNKNOWN ? MAGIC_LINE : result[THEME_FONT]; +} + +const std::array<std::function<CursorInfo()>, 6> funcs{ + std::function<CursorInfo()>{[]() { return get_de_cursor(wmde_name); }}, + std::function<CursorInfo()>{[]() { return get_cursor_from_gtk_configs(4); }}, + std::function<CursorInfo()>{[]() { return get_cursor_from_gtk_configs(3); }}, + std::function<CursorInfo()>{[]() { return get_cursor_from_gtk_configs(2); }}, + std::function<CursorInfo()>{[]() { return get_cursor_xresources(); }}, + std::function<CursorInfo()>{[]() { return get_cursor_gsettings(wmde_name); }} + }; + +MODFUNC(theme_cursor_name) +{ + CursorInfo result; + + for (const auto& method : funcs) + { + result = method(); + if (result != CursorInfo{UNKNOWN, UNKNOWN}) + break; + } + + if (result[CURSOR_NAME] == UNKNOWN) + return MAGIC_LINE; + + std::string& cursor_name = result[CURSOR_NAME]; + size_t pos = 0; + if ((pos = cursor_name.rfind("cursor")) != std::string::npos) + cursor_name.erase(pos); + if ((pos = cursor_name.rfind('_')) != std::string::npos) + cursor_name.erase(pos - 1); + + return cursor_name; +} + +MODFUNC(theme_cursor_size) +{ + CursorInfo result; + + for (const auto& method : funcs) + { + result = method(); + if (result != CursorInfo{UNKNOWN, UNKNOWN}) + break; + } + + if (result[CURSOR_SIZE] == UNKNOWN) + return MAGIC_LINE; + + std::string& cursor_size = result[CURSOR_SIZE]; + size_t pos = 0; + if ((pos = cursor_size.rfind("cursor")) != std::string::npos) + cursor_size.erase(pos); + if ((pos = cursor_size.rfind('_')) != std::string::npos) + cursor_size.erase(pos - 1); + + return cursor_size; +} + +#endif // CF_LINUX diff --git a/src/core-modules/linux/user.cc b/src/core-modules/linux/user.cc index 40b6e593..013bad34 100644 --- a/src/core-modules/linux/user.cc +++ b/src/core-modules/linux/user.cc @@ -15,6 +15,45 @@ #include <wayland-client.h> #endif +static std::string prettify_de_name(const std::string_view de_name) +{ + switch (fnv1a16::hash(str_tolower(de_name.data()))) + { + case "kde"_fnv1a16: + case "plasma"_fnv1a16: + case "plasmashell"_fnv1a16: + case "plasmawayland"_fnv1a16: return "KDE Plasma"; + + case "gnome"_fnv1a16: + case "gnome-shell"_fnv1a16: return "GNOME"; + + case "xfce"_fnv1a16: + case "xfce4"_fnv1a16: + case "xfce4-session"_fnv1a16: return "Xfce4"; + + case "mate"_fnv1a16: + case "mate-session"_fnv1a16: return "Mate"; + + case "lxqt"_fnv1a16: + case "lxqt-session"_fnv1a16: return "LXQt"; + } + + return de_name.data(); +} + +static std::string prettify_term_name(const std::string_view term_name) +{ + switch (fnv1a16::hash(str_tolower(term_name.data()))) + { + case "gnome-terminal"_fnv1a16: + case "gnome terminal"_fnv1a16: return "GNOME Terminal"; + + case "gnome-console"_fnv1a16: + case "gnome console"_fnv1a16: return "GNOME console"; + } + return term_name.data(); +} + // clang-format off static std::string get_term_name_env(bool get_default = false) { @@ -71,12 +110,12 @@ MODFUNC(user_shell_path) // clang-format on MODFUNC(user_shell_name) { - return user_shell_path().substr(user_shell_path().rfind('/') + 1); + return user_shell_path(callbackInfo).substr(user_shell_path(callbackInfo).rfind('/') + 1); } MODFUNC(user_shell_version) { - const std::string& shell_name = user_shell_name(); + const std::string& shell_name = user_shell_name(callbackInfo); std::string ret; if (shell_name == "nu") @@ -141,7 +180,7 @@ MODFUNC(user_term_name) else if (hasStart(term_name, "gnome-terminal")) term_name.erase("gnome-terminal"_len + 1); - const std::string& osname = os_name(); + const std::string& osname = os_name(callbackInfo); // let's try to get the real terminal name // on NixOS, instead of returning the -wrapped name. // tested on gnome-console, kitty, st and alacritty @@ -189,7 +228,7 @@ MODFUNC(user_term_version) if (is_tty) return ""; - const std::string& term_name = user_term_name(); + const std::string& term_name = user_term_name(callbackInfo); if (term_name.empty()) return UNKNOWN; @@ -243,7 +282,7 @@ MODFUNC(user_term_version) ret.erase(pos); debug("get_term_version ret after = {}", ret); - return ret; + return prettify_term_name(ret); } std::string get_wm_name(std::string& wm_path_exec) @@ -349,7 +388,7 @@ MODFUNC(user_wm_version) { if (is_tty) return MAGIC_LINE; - user_wm_name(); // populate wm_path_exec if haven't already + user_wm_name(callbackInfo); // populate wm_path_exec if haven't already std::string wm_version; if (wm_name == "Xfwm4" && get_fast_xfwm4_version(wm_version, wm_path_exec)) return wm_version; @@ -368,7 +407,7 @@ MODFUNC(user_wm_version) if (pos != std::string::npos) wm_version.erase(pos); - return wm_version; + return prettify_wm_name(wm_version); } MODFUNC(user_de_name) @@ -387,7 +426,7 @@ MODFUNC(user_de_name) if (de_name == wm_name) de_name = MAGIC_LINE; - return de_name; + return prettify_de_name(de_name); } MODFUNC(user_de_version) diff --git a/src/display.cpp b/src/display.cpp index ee0b23ab..7792924f 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -74,12 +74,12 @@ std::string Display::detect_distro(const Config& config) else { std::string format; - format = fmt::format("{}/ascii/{}.txt", config.data_dir, str_tolower(os_name_id())); + format = fmt::format("{}/ascii/{}.txt", config.data_dir, str_tolower(os_name_id(nullptr))); debug("checking path in {}: {}", __func__, format); if (std::filesystem::exists(format)) return format; - format = fmt::format("{}/ascii/{}.txt", config.data_dir, str_tolower(os_name())); + format = fmt::format("{}/ascii/{}.txt", config.data_dir, str_tolower(os_name(nullptr))); debug("checking path in {}: {}", __func__, format); if (std::filesystem::exists(format)) return format; From d8bcb0c325c8e04400fa4daebaed45832dbaecb4 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Wed, 9 Jul 2025 14:40:37 +0200 Subject: [PATCH 077/143] core-modules: linux: add remaining theme modules --- include/core-modules.hh | 5 + libcufetch/parse.cc | 41 ---- src/core-modules/core-modules.cc | 21 +- src/core-modules/linux/theme.cc | 332 +++++++++++++++++++------------ 4 files changed, 226 insertions(+), 173 deletions(-) diff --git a/include/core-modules.hh b/include/core-modules.hh index 32ff3223..2fd23780 100644 --- a/include/core-modules.hh +++ b/include/core-modules.hh @@ -103,9 +103,14 @@ MODFUNC(theme_gtk_icon); MODFUNC(theme_gtk_font); MODFUNC(theme_cursor_name); MODFUNC(theme_cursor_size); +MODFUNC(theme_gtk_all_name); +MODFUNC(theme_gtk_all_icon); +MODFUNC(theme_gtk_all_font); MODFUNC(theme_gsettings_name); MODFUNC(theme_gsettings_icon); MODFUNC(theme_gsettings_font); +MODFUNC(theme_gsettings_cursor_name); +MODFUNC(theme_gsettings_cursor_size); #if CF_LINUX inline struct passwd* g_pwd; diff --git a/libcufetch/parse.cc b/libcufetch/parse.cc index cb6d4450..bdde2d8b 100644 --- a/libcufetch/parse.cc +++ b/libcufetch/parse.cc @@ -857,47 +857,6 @@ EXPORT std::string parse(std::string input, const moduleMap_t& modulesInfo, std: // trying some plugins stuff #if 0 -static std::string get_auto_gtk_format(const std::string_view gtk2, const std::string_view gtk3, - const std::string_view gtk4) -{ - if ((gtk2 != MAGIC_LINE && gtk3 != MAGIC_LINE && gtk4 != MAGIC_LINE)) - { - if (gtk2 == gtk3 && gtk2 == gtk4) - return fmt::format("{} [GTK2/3/4]", gtk4); - else if (gtk2 == gtk3) - return fmt::format("{} [GTK2/3], {} [GTK4]", gtk2, gtk4); - else if (gtk4 == gtk3) - return fmt::format("{} [GTK2], {} [GTK3/4]", gtk2, gtk4); - else - return fmt::format("{} [GTK2], {} [GTK3], {} [GTK4]", gtk2, gtk3, gtk4); - } - - else if (gtk3 != MAGIC_LINE && gtk4 != MAGIC_LINE) - { - if (gtk3 == gtk4) - return fmt::format("{} [GTK3/4]", gtk4); - else - return fmt::format("{} [GTK3], {} [GTK4]", gtk3, gtk4); - } - - else if (gtk2 != MAGIC_LINE && gtk3 != MAGIC_LINE) - { - if (gtk2 == gtk3) - return fmt::format("{} [GTK2/3]", gtk3); - else - return fmt::format("{} [GTK2], {} [GTK3]", gtk2, gtk3); - } - - else if (gtk4 != MAGIC_LINE) - return fmt::format("{} [GTK4]", gtk4); - else if (gtk3 != MAGIC_LINE) - return fmt::format("{} [GTK3]", gtk3); - else if (gtk2 != MAGIC_LINE) - return fmt::format("{} [GTK2]", gtk2); - - return MAGIC_LINE; -} - moduleMap_t queried_gpus; moduleMap_t queried_disks; moduleMap_t queried_themes_names; diff --git a/src/core-modules/core-modules.cc b/src/core-modules/core-modules.cc index 0c0b0354..13d8a9b9 100644 --- a/src/core-modules/core-modules.cc +++ b/src/core-modules/core-modules.cc @@ -363,22 +363,39 @@ void core_plugins_start(const Config& config) cfRegisterModule(battery_module); // $<theme> + module_t theme_gtk_all_name_module = {"name", "", {}, theme_gtk_all_name}; + module_t theme_gtk_all_font_module = {"font", "", {}, theme_gtk_all_font}; + module_t theme_gtk_all_icon_module = {"icon", "", {}, theme_gtk_all_icon}; + module_t theme_gtk_all_module = {"all", "", { + std::move(theme_gtk_all_name_module), + std::move(theme_gtk_all_font_module), + std::move(theme_gtk_all_icon_module) + }, NULL}; + module_t theme_gtk_name_module = {"name", "", {}, theme_gtk_name}; module_t theme_gtk_font_module = {"font", "", {}, theme_gtk_font}; module_t theme_gtk_icon_module = {"icon", "", {}, theme_gtk_icon}; module_t theme_gtk_module = {"gtk", "", { std::move(theme_gtk_name_module), std::move(theme_gtk_font_module), - std::move(theme_gtk_icon_module) + std::move(theme_gtk_icon_module), + std::move(theme_gtk_all_module) }, NULL}; module_t theme_gsettings_name_module = {"name", "", {}, theme_gsettings_name}; module_t theme_gsettings_font_module = {"font", "", {}, theme_gsettings_font}; module_t theme_gsettings_icon_module = {"icon", "", {}, theme_gsettings_icon}; + module_t theme_gsettings_cursor_name_module = {"name", "", {}, theme_gsettings_cursor_name}; + module_t theme_gsettings_cursor_size_module = {"size", "", {}, theme_gsettings_cursor_size}; + module_t theme_gsettings_cursor_module = {"cursor", "", { + std::move(theme_gsettings_cursor_size_module), + std::move(theme_gsettings_cursor_name_module), + }, NULL}; module_t theme_gsettings_module = {"gsettings", "", { std::move(theme_gsettings_name_module), std::move(theme_gsettings_font_module), - std::move(theme_gsettings_icon_module) + std::move(theme_gsettings_icon_module), + std::move(theme_gsettings_cursor_module) }, NULL}; module_t theme_cursor_name_module = {"name", "", {}, theme_cursor_name}; diff --git a/src/core-modules/linux/theme.cc b/src/core-modules/linux/theme.cc index 8f5ea87b..4827e263 100644 --- a/src/core-modules/linux/theme.cc +++ b/src/core-modules/linux/theme.cc @@ -1,11 +1,12 @@ +#include "cufetch/cufetch.hh" #include "platform.hpp" #if CF_LINUX -#include <fstream> -#include <functional> -#include <array> #include <algorithm> +#include <array> #include <cstdint> +#include <fstream> +#include <functional> #include "core-modules.hh" #include "fmt/format.h" @@ -18,8 +19,8 @@ #include <glib/gvariant.h> #endif -using ThemeInfo = std::array<std::string, 3>; // [theme, icon_theme, font] -using CursorInfo = std::array<std::string, 2>; // [name, size] +using ThemeInfo = std::array<std::string, 3>; // [theme, icon_theme, font] +using CursorInfo = std::array<std::string, 2>; // [name, size] enum { @@ -34,7 +35,14 @@ enum CURSOR_SIZE }; -const std::string& configDir = getHomeConfigDir(); +const std::string& configDir = getHomeConfigDir(); +const std::string gsetting_interface = (user_de_name(NULL) == "cinnamon") ? "org.cinnamon.desktop.interface" + : (de_name == "mate") ? "org.mate.interface" + : "org.gnome.desktop.interface"; + +const std::string dconf_interface = (user_de_name(NULL) == "cinnamon") ? "/org/cinnamon/desktop/interface" + : (de_name == "mate") ? "/org/mate/interface" + : "/org/gnome/desktop/interface"; static std::string get_xsettings_xfce4(const std::string_view property, const std::string_view subproperty) { @@ -71,18 +79,59 @@ static std::string get_xsettings_xfce4(const std::string_view property, const st return UNKNOWN; } +static std::string get_auto_gtk_format(const std::string_view gtk2, const std::string_view gtk3, + const std::string_view gtk4) +{ + if ((gtk2 != MAGIC_LINE && gtk3 != MAGIC_LINE && gtk4 != MAGIC_LINE)) + { + if (gtk2 == gtk3 && gtk2 == gtk4) + return fmt::format("{} [GTK2/3/4]", gtk4); + else if (gtk2 == gtk3) + return fmt::format("{} [GTK2/3], {} [GTK4]", gtk2, gtk4); + else if (gtk4 == gtk3) + return fmt::format("{} [GTK2], {} [GTK3/4]", gtk2, gtk4); + else + return fmt::format("{} [GTK2], {} [GTK3], {} [GTK4]", gtk2, gtk3, gtk4); + } + + else if (gtk3 != MAGIC_LINE && gtk4 != MAGIC_LINE) + { + if (gtk3 == gtk4) + return fmt::format("{} [GTK3/4]", gtk4); + else + return fmt::format("{} [GTK3], {} [GTK4]", gtk3, gtk4); + } + + else if (gtk2 != MAGIC_LINE && gtk3 != MAGIC_LINE) + { + if (gtk2 == gtk3) + return fmt::format("{} [GTK2/3]", gtk3); + else + return fmt::format("{} [GTK2], {} [GTK3]", gtk2, gtk3); + } + + else if (gtk4 != MAGIC_LINE) + return fmt::format("{} [GTK4]", gtk4); + else if (gtk3 != MAGIC_LINE) + return fmt::format("{} [GTK3]", gtk3); + else if (gtk2 != MAGIC_LINE) + return fmt::format("{} [GTK2]", gtk2); + + return MAGIC_LINE; +} + // // // 1. Cursor // static CursorInfo get_cursor_xresources() { + std::string cursor_name{ UNKNOWN }, cursor_size{ UNKNOWN }; const std::string& path = expandVar("~/.Xresources"); std::ifstream f(path, std::ios::in); if (!f.is_open()) - return {UNKNOWN, UNKNOWN}; + return { cursor_name, cursor_size }; - std::string cursor_name, cursor_size; std::uint16_t iter_index = 0; std::string line; while (std::getline(f, line) && iter_index < 2) @@ -100,16 +149,16 @@ static CursorInfo get_cursor_xresources() } } - return {cursor_name, cursor_size}; + return { cursor_name, cursor_size }; } -static CursorInfo get_cursor_dconf(const std::string_view de_name) +static CursorInfo get_cursor_dconf() { - std::string cursor{UNKNOWN}, cursor_size{UNKNOWN}; + std::string cursor{ UNKNOWN }, cursor_size{ UNKNOWN }; #if USE_DCONF void* handle = LOAD_LIBRARY("libdconf.so"); if (!handle) - return {UNKNOWN, UNKNOWN}; + return { UNKNOWN, UNKNOWN }; LOAD_LIB_SYMBOL(handle, DConfClient*, dconf_client_new, void); LOAD_LIB_SYMBOL(handle, GVariant*, dconf_client_read, DConfClient*, const char*); @@ -120,55 +169,44 @@ static CursorInfo get_cursor_dconf(const std::string_view de_name) DConfClient* client = dconf_client_new(); GVariant* variant; - std::string interface; - switch (fnv1a16::hash(str_tolower(de_name.data()))) - { - case "cinnamon"_fnv1a16: interface = "/org/cinnamon/desktop/interface/"; break; - case "mate"_fnv1a16: interface = "/org/mate/interface/"; break; - default: interface = "/org/gnome/desktop/interface/"; - } - - variant = dconf_client_read(client, (interface + "cursor-theme").c_str()); + variant = dconf_client_read(client, (dconf_interface + "cursor-theme").c_str()); if (variant) cursor = g_variant_get_string(variant, NULL); - variant = dconf_client_read(client, (interface + "cursor-size").c_str()); + variant = dconf_client_read(client, (dconf_interface + "cursor-size").c_str()); if (variant) cursor_size = fmt::to_string(g_variant_get_int32(variant)); #endif - return {cursor, cursor_size}; + return { cursor, cursor_size }; } -static CursorInfo get_cursor_gsettings(const std::string_view de_name) +static CursorInfo get_cursor_gsettings() { - const CursorInfo& dconf = get_cursor_dconf(de_name); - if (dconf != CursorInfo{UNKNOWN, UNKNOWN}) + const CursorInfo& dconf = get_cursor_dconf(); + if (dconf != CursorInfo{ UNKNOWN, UNKNOWN }) return dconf; - const char* interface; - switch (fnv1a16::hash(str_tolower(de_name.data()))) - { - case "cinnamon"_fnv1a16: interface = "org.cinnamon.desktop.interface"; break; - case "mate"_fnv1a16: interface = "org.mate.interface"; break; - default: interface = "org.gnome.desktop.interface"; - } - std::string cursor{UNKNOWN}; - read_exec({ "gsettings", "get", interface, "cursor-theme" }, cursor); + std::string cursor; + read_exec({ "gsettings", "get", gsetting_interface.c_str(), "cursor-theme" }, cursor); cursor.erase(std::remove(cursor.begin(), cursor.end(), '\''), cursor.end()); - std::string cursor_size{UNKNOWN}; - read_exec({ "gsettings", "get", interface, "cursor-size" }, cursor_size); + std::string cursor_size; + read_exec({ "gsettings", "get", gsetting_interface.c_str(), "cursor-size" }, cursor_size); cursor_size.erase(std::remove(cursor_size.begin(), cursor_size.end(), '\''), cursor_size.end()); - return {cursor, cursor_size}; + if (cursor.empty()) + cursor = UNKNOWN; + if (cursor_size.empty()) + cursor_size = UNKNOWN; + return { cursor, cursor_size }; } static CursorInfo get_gtk_cursor_config(const std::string_view path) { - std::string cursor{UNKNOWN}, cursor_size{UNKNOWN}; + std::string cursor{ UNKNOWN }, cursor_size{ UNKNOWN }; std::ifstream f(path.data(), std::ios::in); if (!f.is_open()) - return {cursor, cursor_size}; + return { cursor, cursor_size }; std::string line; std::uint16_t iter_index = 0; @@ -181,27 +219,25 @@ static CursorInfo get_gtk_cursor_config(const std::string_view path) getFileValue(iter_index, line, cursor_size, "gtk-cursor-theme-size="_len); } - return {cursor, cursor_size}; + return { cursor, cursor_size }; } static CursorInfo get_cursor_from_gtk_configs(const std::uint8_t ver) { - const std::array<std::string, 6> paths = { - fmt::format("{}/gtk-{}.0/settings.ini", configDir, ver), - fmt::format("{}/gtk-{}.0/gtkrc", configDir, ver), - fmt::format("{}/gtkrc-{}.0", configDir, ver), - fmt::format("{}/.gtkrc-{}.0", std::getenv("HOME"), ver), - fmt::format("{}/.gtkrc-{}.0-kde", std::getenv("HOME"), ver), - fmt::format("{}/.gtkrc-{}.0-kde4", std::getenv("HOME"), ver) - }; + const std::array<std::string, 6> paths = { fmt::format("{}/gtk-{}.0/settings.ini", configDir, ver), + fmt::format("{}/gtk-{}.0/gtkrc", configDir, ver), + fmt::format("{}/gtkrc-{}.0", configDir, ver), + fmt::format("{}/.gtkrc-{}.0", std::getenv("HOME"), ver), + fmt::format("{}/.gtkrc-{}.0-kde", std::getenv("HOME"), ver), + fmt::format("{}/.gtkrc-{}.0-kde4", std::getenv("HOME"), ver) }; for (const std::string& path : paths) { const CursorInfo& result = get_gtk_cursor_config(path); - if (result != CursorInfo{UNKNOWN, UNKNOWN}) + if (result != CursorInfo{ UNKNOWN, UNKNOWN }) return result; } - return {UNKNOWN, UNKNOWN}; + return { UNKNOWN, UNKNOWN }; } static CursorInfo get_de_cursor(const std::string_view de_name) @@ -212,10 +248,10 @@ static CursorInfo get_de_cursor(const std::string_view de_name) case "xfce4"_fnv1a16: { debug("getting info on xfce4"); - return {get_xsettings_xfce4("Gtk", "CursorThemeName"), get_xsettings_xfce4("Gtk", "CursorThemeSize")}; + return { get_xsettings_xfce4("Gtk", "CursorThemeName"), get_xsettings_xfce4("Gtk", "CursorThemeSize") }; } } - return {UNKNOWN, UNKNOWN}; + return { UNKNOWN, UNKNOWN }; } // @@ -224,10 +260,10 @@ static CursorInfo get_de_cursor(const std::string_view de_name) // static ThemeInfo get_gtk_theme_config(const std::string_view path) { - std::string theme{UNKNOWN}, icon_theme{UNKNOWN}, font{UNKNOWN}; + std::string theme{ UNKNOWN }, icon_theme{ UNKNOWN }, font{ UNKNOWN }; std::ifstream f(path.data(), std::ios::in); if (!f.is_open()) - return {theme, icon_theme, font}; + return { theme, icon_theme, font }; std::string line; std::uint16_t iter_index = 0; @@ -243,16 +279,16 @@ static ThemeInfo get_gtk_theme_config(const std::string_view path) getFileValue(iter_index, line, font, "gtk-font-name="_len); } - return {theme, icon_theme, font}; + return { theme, icon_theme, font }; } -static ThemeInfo get_gtk_theme_dconf(const std::string_view de_name) +static ThemeInfo get_gtk_theme_dconf() { - std::string theme{UNKNOWN}, icon_theme{UNKNOWN}, font{UNKNOWN}; + std::string theme{ UNKNOWN }, icon_theme{ UNKNOWN }, font{ UNKNOWN }; #if USE_DCONF void* handle = LOAD_LIBRARY("libdconf.so"); if (!handle) - return {theme, icon_theme, font}; + return { theme, icon_theme, font }; LOAD_LIB_SYMBOL(handle, DConfClient*, dconf_client_new, void); LOAD_LIB_SYMBOL(handle, GVariant*, dconf_client_read, DConfClient * client, const char*); @@ -262,75 +298,64 @@ static ThemeInfo get_gtk_theme_dconf(const std::string_view de_name) DConfClient* client = dconf_client_new(); GVariant* variant; - std::string interface; - switch (fnv1a16::hash(str_tolower(de_name.data()))) - { - case "cinnamon"_fnv1a16: interface = "/org/cinnamon/desktop/interface/"; break; - case "mate"_fnv1a16: interface = "/org/mate/interface/"; break; - default: interface = "/org/gnome/desktop/interface/"; - } - - variant = dconf_client_read(client, (interface + "gtk-theme").c_str()); + variant = dconf_client_read(client, (dconf_interface + "gtk-theme").c_str()); if (variant) theme = g_variant_get_string(variant, NULL); - variant = dconf_client_read(client, (interface + "icon-theme").c_str()); + variant = dconf_client_read(client, (dconf_interface + "icon-theme").c_str()); if (variant) icon_theme = g_variant_get_string(variant, NULL); - variant = dconf_client_read(client, (interface + "font-name").c_str()); + variant = dconf_client_read(client, (dconf_interface + "font-name").c_str()); if (variant) font = g_variant_get_string(variant, NULL); #endif - return {theme, icon_theme, font}; + return { theme, icon_theme, font }; } -static ThemeInfo get_gtk_theme_gsettings(const std::string_view de_name) +static ThemeInfo get_gtk_theme_gsettings() { - const ThemeInfo& dconf = get_gtk_theme_dconf(de_name); - if (dconf != ThemeInfo{UNKNOWN, UNKNOWN, UNKNOWN}) + const ThemeInfo& dconf = get_gtk_theme_dconf(); + if (dconf != ThemeInfo{ UNKNOWN, UNKNOWN, UNKNOWN }) return dconf; - std::string theme{UNKNOWN}, icon_theme{UNKNOWN}, font{UNKNOWN}; - const char* interface; - switch (fnv1a16::hash(str_tolower(de_name.data()))) - { - case "cinnamon"_fnv1a16: interface = "org.cinnamon.desktop.interface"; break; - case "mate"_fnv1a16: interface = "org.mate.interface"; break; - default: interface = "org.gnome.desktop.interface"; - } + std::string theme, icon_theme, font; - read_exec({ "gsettings", "get", interface, "gtk-theme" }, theme); + read_exec({ "gsettings", "get", gsetting_interface.c_str(), "gtk-theme" }, theme); theme.erase(std::remove(theme.begin(), theme.end(), '\''), theme.end()); - read_exec({ "gsettings", "get", interface, "icon-theme" }, icon_theme); + read_exec({ "gsettings", "get", gsetting_interface.c_str(), "icon-theme" }, icon_theme); icon_theme.erase(std::remove(icon_theme.begin(), icon_theme.end(), '\''), icon_theme.end()); - read_exec({ "gsettings", "get", interface, "font-name" }, font); + read_exec({ "gsettings", "get", gsetting_interface.c_str(), "font-name" }, font); font.erase(std::remove(font.begin(), font.end(), '\''), font.end()); - return {theme, icon_theme, font}; + if (theme.empty()) + theme = UNKNOWN; + if (icon_theme.empty()) + icon_theme = UNKNOWN; + if (font.empty()) + font = UNKNOWN; + return { theme, icon_theme, font }; } -static ThemeInfo get_gtk_theme_from_configs(const std::uint8_t ver, const std::string_view de_name) +static ThemeInfo get_gtk_theme_from_configs(const std::uint8_t ver) { - const std::array<std::string, 6> paths = { - fmt::format("{}/gtk-{}.0/settings.ini", configDir, ver), - fmt::format("{}/gtk-{}.0/gtkrc", configDir, ver), - fmt::format("{}/gtkrc-{}.0", configDir, ver), - fmt::format("{}/.gtkrc-{}.0", std::getenv("HOME"), ver), - fmt::format("{}/.gtkrc-{}.0-kde", std::getenv("HOME"), ver), - fmt::format("{}/.gtkrc-{}.0-kde4", std::getenv("HOME"), ver) - }; + const std::array<std::string, 6> paths = { fmt::format("{}/gtk-{}.0/settings.ini", configDir, ver), + fmt::format("{}/gtk-{}.0/gtkrc", configDir, ver), + fmt::format("{}/gtkrc-{}.0", configDir, ver), + fmt::format("{}/.gtkrc-{}.0", std::getenv("HOME"), ver), + fmt::format("{}/.gtkrc-{}.0-kde", std::getenv("HOME"), ver), + fmt::format("{}/.gtkrc-{}.0-kde4", std::getenv("HOME"), ver) }; for (const auto& path : paths) { const ThemeInfo& result = get_gtk_theme_config(path); - if (result != ThemeInfo{UNKNOWN, UNKNOWN, UNKNOWN}) + if (result != ThemeInfo{ UNKNOWN, UNKNOWN, UNKNOWN }) return result; } - return get_gtk_theme_gsettings(de_name); + return get_gtk_theme_gsettings(); } static ThemeInfo get_de_gtk_theme(const std::string_view de_name, const std::uint8_t ver) @@ -341,73 +366,120 @@ static ThemeInfo get_de_gtk_theme(const std::string_view de_name, const std::uin case "xfce4"_fnv1a16: { debug("getting info on xfce4"); - return { - get_xsettings_xfce4("Net", "ThemeName"), - get_xsettings_xfce4("Net", "IconThemeName"), - get_xsettings_xfce4("Gtk", "FontName") - }; + return { get_xsettings_xfce4("Net", "ThemeName"), get_xsettings_xfce4("Net", "IconThemeName"), + get_xsettings_xfce4("Gtk", "FontName") }; } } - return get_gtk_theme_from_configs(ver, de_name); + return get_gtk_theme_from_configs(ver); } -const std::string& wmde_name = (de_name != MAGIC_LINE && de_name == wm_name) || de_name == MAGIC_LINE - ? wm_name - : de_name; +const std::string& wmde_name = + (de_name != MAGIC_LINE && de_name == wm_name) || de_name == MAGIC_LINE ? wm_name : de_name; MODFUNC(theme_gtk_name) { - const ThemeInfo& result = is_tty - ? get_gtk_theme_from_configs(3, wmde_name) - : get_de_gtk_theme(wmde_name, 3); + const moduleArgs_t *moduleArg = callbackInfo->moduleArgs; + for (; moduleArg && moduleArg->name != "gtk"; moduleArg = moduleArg->next); + if (!moduleArg) + die("GTK version not provided"); + int ver = std::stoi(moduleArg->value); + + const ThemeInfo& result = is_tty ? get_gtk_theme_from_configs(ver) : get_de_gtk_theme(wmde_name, ver); return result[THEME_NAME] == UNKNOWN ? MAGIC_LINE : result[THEME_NAME]; } MODFUNC(theme_gtk_icon) { - const ThemeInfo& result = is_tty - ? get_gtk_theme_from_configs(3, wmde_name) - : get_de_gtk_theme(wmde_name, 3); + const moduleArgs_t *moduleArg = callbackInfo->moduleArgs; + for (; moduleArg && moduleArg->name != "gtk"; moduleArg = moduleArg->next); + if (!moduleArg) + die("GTK version not provided"); + int ver = std::stoi(moduleArg->value); + + const ThemeInfo& result = is_tty ? get_gtk_theme_from_configs(ver) : get_de_gtk_theme(wmde_name, ver); return result[THEME_ICON] == UNKNOWN ? MAGIC_LINE : result[THEME_ICON]; } MODFUNC(theme_gtk_font) { - const ThemeInfo& result = is_tty - ? get_gtk_theme_from_configs(3, wmde_name) - : get_de_gtk_theme(wmde_name, 3); + const moduleArgs_t *moduleArg = callbackInfo->moduleArgs; + for (; moduleArg && moduleArg->name != "gtk"; moduleArg = moduleArg->next); + if (!moduleArg) + die("GTK version not provided"); + int ver = std::stoi(moduleArg->value); + + const ThemeInfo& result = is_tty ? get_gtk_theme_from_configs(ver) : get_de_gtk_theme(wmde_name, ver); return result[THEME_FONT] == UNKNOWN ? MAGIC_LINE : result[THEME_FONT]; } +MODFUNC(theme_gtk_all_name) +{ + const ThemeInfo& result_gtk2 = is_tty ? get_gtk_theme_from_configs(2) : get_de_gtk_theme(wmde_name, 2); + const ThemeInfo& result_gtk3 = is_tty ? get_gtk_theme_from_configs(3) : get_de_gtk_theme(wmde_name, 3); + const ThemeInfo& result_gtk4 = is_tty ? get_gtk_theme_from_configs(4) : get_de_gtk_theme(wmde_name, 4); + + return get_auto_gtk_format(result_gtk2[THEME_NAME], result_gtk3[THEME_NAME], result_gtk4[THEME_NAME]); +} + +MODFUNC(theme_gtk_all_icon) +{ + const ThemeInfo& result_gtk2 = is_tty ? get_gtk_theme_from_configs(2) : get_de_gtk_theme(wmde_name, 2); + const ThemeInfo& result_gtk3 = is_tty ? get_gtk_theme_from_configs(3) : get_de_gtk_theme(wmde_name, 3); + const ThemeInfo& result_gtk4 = is_tty ? get_gtk_theme_from_configs(4) : get_de_gtk_theme(wmde_name, 4); + + return get_auto_gtk_format(result_gtk2[THEME_ICON], result_gtk3[THEME_ICON], result_gtk4[THEME_ICON]); +} + +MODFUNC(theme_gtk_all_font) +{ + const ThemeInfo& result_gtk2 = is_tty ? get_gtk_theme_from_configs(2) : get_de_gtk_theme(wmde_name, 2); + const ThemeInfo& result_gtk3 = is_tty ? get_gtk_theme_from_configs(3) : get_de_gtk_theme(wmde_name, 3); + const ThemeInfo& result_gtk4 = is_tty ? get_gtk_theme_from_configs(4) : get_de_gtk_theme(wmde_name, 4); + + return get_auto_gtk_format(result_gtk2[THEME_FONT], result_gtk3[THEME_FONT], result_gtk4[THEME_FONT]); +} + MODFUNC(theme_gsettings_name) { - const ThemeInfo& result = get_gtk_theme_gsettings(de_name); + const ThemeInfo& result = get_gtk_theme_gsettings(); return result[THEME_NAME] == UNKNOWN ? MAGIC_LINE : result[THEME_NAME]; } MODFUNC(theme_gsettings_icon) { - const ThemeInfo& result = get_gtk_theme_gsettings(de_name); + const ThemeInfo& result = get_gtk_theme_gsettings(); return result[THEME_ICON] == UNKNOWN ? MAGIC_LINE : result[THEME_ICON]; } MODFUNC(theme_gsettings_font) { - const ThemeInfo& result = get_gtk_theme_gsettings(de_name); + const ThemeInfo& result = get_gtk_theme_gsettings(); return result[THEME_FONT] == UNKNOWN ? MAGIC_LINE : result[THEME_FONT]; } +MODFUNC(theme_gsettings_cursor_name) +{ + const CursorInfo& result = get_cursor_gsettings(); + return result[CURSOR_NAME] == UNKNOWN ? MAGIC_LINE : result[CURSOR_NAME]; +} + +MODFUNC(theme_gsettings_cursor_size) +{ + const CursorInfo& result = get_cursor_gsettings(); + return result[CURSOR_SIZE] == UNKNOWN ? MAGIC_LINE : result[CURSOR_SIZE]; +} + const std::array<std::function<CursorInfo()>, 6> funcs{ - std::function<CursorInfo()>{[]() { return get_de_cursor(wmde_name); }}, - std::function<CursorInfo()>{[]() { return get_cursor_from_gtk_configs(4); }}, - std::function<CursorInfo()>{[]() { return get_cursor_from_gtk_configs(3); }}, - std::function<CursorInfo()>{[]() { return get_cursor_from_gtk_configs(2); }}, - std::function<CursorInfo()>{[]() { return get_cursor_xresources(); }}, - std::function<CursorInfo()>{[]() { return get_cursor_gsettings(wmde_name); }} - }; + std::function<CursorInfo()>{ []() { return get_de_cursor(wmde_name); } }, + std::function<CursorInfo()>{ []() { return get_cursor_from_gtk_configs(4); } }, + std::function<CursorInfo()>{ []() { return get_cursor_from_gtk_configs(3); } }, + std::function<CursorInfo()>{ []() { return get_cursor_from_gtk_configs(2); } }, + std::function<CursorInfo()>{ []() { return get_cursor_xresources(); } }, + std::function<CursorInfo()>{ []() { return get_cursor_gsettings(); } } +}; MODFUNC(theme_cursor_name) { @@ -416,7 +488,7 @@ MODFUNC(theme_cursor_name) for (const auto& method : funcs) { result = method(); - if (result != CursorInfo{UNKNOWN, UNKNOWN}) + if (result != CursorInfo{ UNKNOWN, UNKNOWN }) break; } @@ -424,7 +496,7 @@ MODFUNC(theme_cursor_name) return MAGIC_LINE; std::string& cursor_name = result[CURSOR_NAME]; - size_t pos = 0; + size_t pos = 0; if ((pos = cursor_name.rfind("cursor")) != std::string::npos) cursor_name.erase(pos); if ((pos = cursor_name.rfind('_')) != std::string::npos) @@ -440,7 +512,7 @@ MODFUNC(theme_cursor_size) for (const auto& method : funcs) { result = method(); - if (result != CursorInfo{UNKNOWN, UNKNOWN}) + if (result != CursorInfo{ UNKNOWN, UNKNOWN }) break; } @@ -448,7 +520,7 @@ MODFUNC(theme_cursor_size) return MAGIC_LINE; std::string& cursor_size = result[CURSOR_SIZE]; - size_t pos = 0; + size_t pos = 0; if ((pos = cursor_size.rfind("cursor")) != std::string::npos) cursor_size.erase(pos); if ((pos = cursor_size.rfind('_')) != std::string::npos) @@ -457,4 +529,4 @@ MODFUNC(theme_cursor_size) return cursor_size; } -#endif // CF_LINUX +#endif // CF_LINUX From 53f157b3d407a8c619a4a3e832c75a3ea7ea1bce Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Wed, 9 Jul 2025 14:44:49 +0200 Subject: [PATCH 078/143] chore: remove old disabled block of code in parse.cc --- libcufetch/parse.cc | 854 -------------------------------------------- 1 file changed, 854 deletions(-) diff --git a/libcufetch/parse.cc b/libcufetch/parse.cc index bdde2d8b..fe62ded2 100644 --- a/libcufetch/parse.cc +++ b/libcufetch/parse.cc @@ -852,857 +852,3 @@ EXPORT std::string parse(std::string input, const moduleMap_t& modulesInfo, std: return ret; } - -// Re-enable them later -// trying some plugins stuff -#if 0 - -moduleMap_t queried_gpus; -moduleMap_t queried_disks; -moduleMap_t queried_themes_names; -moduleMap_t queried_themes; - -// clang-format on -void addValueFromModuleMember(const std::string& moduleName, const std::string& moduleMemberName, - parse_args_t& parse_args) -{ -#define SYSINFO_INSERT(x) sysInfo.at(moduleName).insert({ moduleMemberName, variant(x) }) - - // just aliases for convention - const Config& config = parse_args.config; - modulesInfo_t& sysInfo = parse_args.modulesInfo; - - const auto& moduleMember_hash = fnv1a16::hash(moduleMemberName); - const std::uint16_t byte_unit = config.use_SI_unit ? 1000 : 1024; - constexpr std::array<std::string_view, 32> sorted_valid_prefixes = { "B", "EB", "EiB", "GB", "GiB", "kB", - "KiB", "MB", "MiB", "PB", "PiB", "TB", - "TiB", "YB", "YiB", "ZB", "ZiB" }; - - const auto& return_divided_bytes = [&sorted_valid_prefixes, &moduleMemberName](const double& amount) -> double { - const std::string& prefix = moduleMemberName.substr(moduleMemberName.find('-') + 1); - if (std::binary_search(sorted_valid_prefixes.begin(), sorted_valid_prefixes.end(), prefix)) - return divide_bytes(amount, prefix).num_bytes; - - return 0; - }; - - if (moduleName == "os") - { - Query::System query_system; - - const std::chrono::seconds uptime_secs(query_system.uptime()); - const std::chrono::minutes& uptime_mins = std::chrono::duration_cast<std::chrono::minutes>(uptime_secs); - const std::chrono::hours& uptime_hours = std::chrono::duration_cast<std::chrono::hours>(uptime_secs); - - // let's support a little of C++17 without any `#if __cpluscplus` stuff - const std::uint16_t uptime_days = uptime_secs.count() / (60 * 60 * 24); - - if (sysInfo.find(moduleName) == sysInfo.end()) - sysInfo.insert({ moduleName, {} }); - - if (sysInfo.at(moduleName).find(moduleMemberName) == sysInfo.at(moduleName).end()) - { - switch (moduleMember_hash) - { - case "name"_fnv1a16: SYSINFO_INSERT(query_system.os_pretty_name()); break; - case "name_id"_fnv1a16: SYSINFO_INSERT(query_system.os_id()); break; - - case "uptime"_fnv1a16: - SYSINFO_INSERT(get_auto_uptime(uptime_days, uptime_hours.count() % 24, uptime_mins.count() % 60, - uptime_secs.count() % 60, config)); - break; - - case "uptime_secs"_fnv1a16: SYSINFO_INSERT(static_cast<size_t>(uptime_secs.count() % 60)); break; - case "uptime_mins"_fnv1a16: SYSINFO_INSERT(static_cast<size_t>(uptime_mins.count() % 60)); break; - case "uptime_hours"_fnv1a16: SYSINFO_INSERT(static_cast<size_t>(uptime_hours.count()) % 24); break; - case "uptime_days"_fnv1a16: SYSINFO_INSERT(static_cast<size_t>(uptime_days)); break; - - case "kernel"_fnv1a16: - SYSINFO_INSERT(query_system.kernel_name() + ' ' + query_system.kernel_version()); - break; - - case "kernel_name"_fnv1a16: SYSINFO_INSERT(query_system.kernel_name()); break; - case "kernel_version"_fnv1a16: SYSINFO_INSERT(query_system.kernel_version()); break; - case "packages"_fnv1a16: - case "pkgs"_fnv1a16: SYSINFO_INSERT(query_system.pkgs_installed(config)); break; - case "initsys_name"_fnv1a16: SYSINFO_INSERT(query_system.os_initsys_name()); break; - case "initsys_version"_fnv1a16: SYSINFO_INSERT(query_system.os_initsys_version()); break; - case "hostname"_fnv1a16: SYSINFO_INSERT(query_system.hostname()); break; - case "version_codename"_fnv1a16: SYSINFO_INSERT(query_system.os_version_codename()); break; - case "version_id"_fnv1a16: SYSINFO_INSERT(query_system.os_versionid()); break; - } - } - } - - else if (moduleName == "system") - { - Query::System query_system; - - if (sysInfo.find(moduleName) == sysInfo.end()) - sysInfo.insert({ moduleName, {} }); - - if (sysInfo.at(moduleName).find(moduleMemberName) == sysInfo.at(moduleName).end()) - { - switch (moduleMember_hash) - { - case "host"_fnv1a16: - SYSINFO_INSERT(query_system.host_vendor() + ' ' + query_system.host_modelname() + ' ' + - query_system.host_version()); - break; - - case "host_name"_fnv1a16: SYSINFO_INSERT(query_system.host_modelname()); break; - case "host_vendor"_fnv1a16: SYSINFO_INSERT(query_system.host_vendor()); break; - case "host_version"_fnv1a16: SYSINFO_INSERT(query_system.host_version()); break; - case "arch"_fnv1a16: SYSINFO_INSERT(query_system.arch()); break; - } - } - } - - // clang-format on - else if (moduleName == "user") - { - Query::User query_user; - - if (sysInfo.find(moduleName) == sysInfo.end()) - sysInfo.insert({ moduleName, {} }); - - if (sysInfo.at(moduleName).find(moduleMemberName) == sysInfo.at(moduleName).end()) - { - switch (moduleMember_hash) - { - case "name"_fnv1a16: SYSINFO_INSERT(query_user.name()); break; - - case "shell"_fnv1a16: - SYSINFO_INSERT(query_user.shell_name() + ' ' + query_user.shell_version(query_user.shell_name())); - break; - - case "shell_name"_fnv1a16: SYSINFO_INSERT(query_user.shell_name()); break; - case "shell_path"_fnv1a16: SYSINFO_INSERT(query_user.shell_path()); break; - case "shell_version"_fnv1a16: SYSINFO_INSERT(query_user.shell_version(query_user.shell_name())); break; - - case "de_name"_fnv1a16: - SYSINFO_INSERT(prettify_de_name( - query_user.de_name(query_user.m_bDont_query_dewm, query_user.term_name(), - query_user.wm_name(query_user.m_bDont_query_dewm, query_user.term_name())))); - break; - - case "de_version"_fnv1a16: - SYSINFO_INSERT(query_user.de_version( - query_user.de_name(query_user.m_bDont_query_dewm, query_user.term_name(), - query_user.wm_name(query_user.m_bDont_query_dewm, query_user.term_name())))); - break; - - case "wm_name"_fnv1a16: - SYSINFO_INSERT(query_user.wm_name(query_user.m_bDont_query_dewm, query_user.term_name())); - break; - - case "wm_version"_fnv1a16: - SYSINFO_INSERT(query_user.wm_version(query_user.m_bDont_query_dewm, query_user.term_name())); - break; - - case "terminal"_fnv1a16: - SYSINFO_INSERT(prettify_term_name(query_user.term_name()) + ' ' + - query_user.term_version(query_user.term_name())); - break; - - case "terminal_name"_fnv1a16: SYSINFO_INSERT(prettify_term_name(query_user.term_name())); break; - case "terminal_version"_fnv1a16: SYSINFO_INSERT(query_user.term_version(query_user.term_name())); break; - } - } - } - - else if (moduleName == "theme") - { - Query::Theme query_theme(queried_themes, config, false); - - if (sysInfo.find(moduleName) == sysInfo.end()) - sysInfo.insert({ moduleName, {} }); - - if (sysInfo.at(moduleName).find(moduleMemberName) == sysInfo.at(moduleName).end()) - { - switch (moduleMember_hash) - { - case "cursor"_fnv1a16: - if (query_theme.cursor_size() == UNKNOWN) - SYSINFO_INSERT(query_theme.cursor()); - else - SYSINFO_INSERT(fmt::format("{} ({}px)", query_theme.cursor(), query_theme.cursor_size())); - break; - - case "cursor_name"_fnv1a16: SYSINFO_INSERT(query_theme.cursor()); break; - case "cursor_size"_fnv1a16: SYSINFO_INSERT(query_theme.cursor_size()); break; - } - } - } - - else if (moduleName == "theme-gsettings") - { - if (sysInfo.find(moduleName) == sysInfo.end()) - sysInfo.insert({ moduleName, {} }); - - if (sysInfo.at(moduleName).find(moduleMemberName) == sysInfo.at(moduleName).end()) - { - if (hasStart(moduleMemberName, "cursor")) - { - Query::Theme query_cursor(queried_themes, config, true); - switch (moduleMember_hash) - { - case "cursor"_fnv1a16: - if (query_cursor.cursor_size() == UNKNOWN) - SYSINFO_INSERT(query_cursor.cursor()); - else - SYSINFO_INSERT(fmt::format("{} ({}px)", query_cursor.cursor(), query_cursor.cursor_size())); - break; - case "cursor_name"_fnv1a16: SYSINFO_INSERT(query_cursor.cursor()); break; - case "cursor_size"_fnv1a16: SYSINFO_INSERT(query_cursor.cursor_size()); break; - } - } - else - { - Query::Theme query_theme(0, queried_themes, "gsettings", config, true); - switch (moduleMember_hash) - { - case "name"_fnv1a16: SYSINFO_INSERT(query_theme.gtk_theme()); break; - case "icons"_fnv1a16: SYSINFO_INSERT(query_theme.gtk_icon_theme()); break; - case "font"_fnv1a16: SYSINFO_INSERT(query_theme.gtk_font()); break; - } - } - } - } - - // clang-format off - else if (moduleName == "theme-gtk-all") - { - Query::Theme gtk2(2, queried_themes, "gtk2", config); - Query::Theme gtk3(3, queried_themes, "gtk3", config); - Query::Theme gtk4(4, queried_themes, "gtk4", config); - - if (sysInfo.find(moduleName) == sysInfo.end()) - sysInfo.insert({ moduleName, {} }); - - if (sysInfo.at(moduleName).find(moduleMemberName) == sysInfo.at(moduleName).end()) - { - switch (moduleMember_hash) - { - case "name"_fnv1a16: SYSINFO_INSERT(get_auto_gtk_format(gtk2.gtk_theme(), gtk3.gtk_theme(), gtk4.gtk_theme())); break; - case "icons"_fnv1a16: SYSINFO_INSERT(get_auto_gtk_format(gtk2.gtk_icon_theme(), gtk3.gtk_icon_theme(), gtk4.gtk_icon_theme())); break; - case "font"_fnv1a16: SYSINFO_INSERT(get_auto_gtk_format(gtk2.gtk_font(), gtk3.gtk_font(), gtk4.gtk_font())); break; - } - } - } - - else if (hasStart(moduleName, "theme-gtk")) - { - const std::uint8_t ver = - static_cast<std::uint8_t>(moduleName.length() > 9 ? std::stoi(moduleName.substr(9)) : 0); - - if (ver <= 0) - die(_("seems theme-gtk module name '{}' doesn't have a version number to query.\n" - "Syntax should be like 'theme_gtkN' which N stands for the version of gtk to query (single number)"), - moduleName); - - Query::Theme query_theme(ver, queried_themes, fmt::format("gtk{}", ver), config); - - if (sysInfo.find(moduleName) == sysInfo.end()) - sysInfo.insert({ moduleName, {} }); - - if (sysInfo.at(moduleName).find(moduleMemberName) == sysInfo.at(moduleName).end()) - { - switch (moduleMember_hash) - { - case "name"_fnv1a16: SYSINFO_INSERT(query_theme.gtk_theme()); break; - case "icons"_fnv1a16: SYSINFO_INSERT(query_theme.gtk_icon_theme()); break; - case "font"_fnv1a16: SYSINFO_INSERT(query_theme.gtk_font()); break; - } - } - } - - // clang-format on - else if (moduleName == "cpu") - { - Query::CPU query_cpu; - - if (sysInfo.find(moduleName) == sysInfo.end()) - sysInfo.insert({ moduleName, {} }); - - if (sysInfo.at(moduleName).find(moduleMemberName) == sysInfo.at(moduleName).end()) - { - switch (moduleMember_hash) - { - case "name"_fnv1a16: SYSINFO_INSERT(query_cpu.name()); break; - case "nproc"_fnv1a16: SYSINFO_INSERT(query_cpu.nproc()); break; - case "freq_cur"_fnv1a16: SYSINFO_INSERT(query_cpu.freq_cur()); break; - case "freq_max"_fnv1a16: SYSINFO_INSERT(query_cpu.freq_max()); break; - case "freq_min"_fnv1a16: SYSINFO_INSERT(query_cpu.freq_min()); break; - case "freq_bios_limit"_fnv1a16: SYSINFO_INSERT(query_cpu.freq_bios_limit()); break; - - case "temp_C"_fnv1a16: SYSINFO_INSERT(query_cpu.temp()); break; - case "temp_F"_fnv1a16: SYSINFO_INSERT(query_cpu.temp() * 1.8 + 34); break; - case "temp_K"_fnv1a16: SYSINFO_INSERT(query_cpu.temp() + 273.15); break; - } - } - } - - else if (hasStart(moduleName, "gpu")) - { - const std::string& id = moduleName.length() > 3 ? moduleName.substr(3) : "0"; - - Query::GPU query_gpu(id, queried_gpus); - - if (sysInfo.find(moduleName) == sysInfo.end()) - sysInfo.insert({ moduleName, {} }); - - if (sysInfo.at(moduleName).find(moduleMemberName) == sysInfo.at(moduleName).end()) - { - switch (moduleMember_hash) - { - case "name"_fnv1a16: SYSINFO_INSERT(query_gpu.name()); break; - case "vendor"_fnv1a16: SYSINFO_INSERT(shorten_vendor_name(query_gpu.vendor())); break; - case "vendor_long"_fnv1a16: SYSINFO_INSERT(query_gpu.vendor()); break; - } - } - } - - else if (hasStart(moduleName, "disk")) - { - if (moduleName.length() < "disk()"_len) - die(_("invalid disk module name '{}', must be disk(/path/to/fs) e.g: disk(/)"), moduleName); - - enum - { - USED = 0, - TOTAL, - FREE - }; - std::string path{ moduleName.data() }; - path.erase(0, 5); // disk( - path.pop_back(); // ) - debug("disk path = {}", path); - - Query::Disk query_disk(path, queried_disks, parse_args); - std::array<byte_units_t, 3> byte_units; - - if (sysInfo.find(moduleName) == sysInfo.end()) - sysInfo.insert({ moduleName, {} }); - - if (sysInfo.at(moduleName).find(moduleMemberName) == sysInfo.at(moduleName).end()) - { - byte_units.at(TOTAL) = auto_divide_bytes(query_disk.total_amount(), byte_unit); - byte_units.at(USED) = auto_divide_bytes(query_disk.used_amount(), byte_unit); - byte_units.at(FREE) = auto_divide_bytes(query_disk.free_amount(), byte_unit); - - switch (moduleMember_hash) - { - case "fs"_fnv1a16: SYSINFO_INSERT(query_disk.typefs()); break; - case "device"_fnv1a16: SYSINFO_INSERT(query_disk.device()); break; - case "mountdir"_fnv1a16: SYSINFO_INSERT(query_disk.mountdir()); break; - - case "types"_fnv1a16: - { - std::string str; - if (query_disk.types_disk() & Query::DISK_VOLUME_TYPE_EXTERNAL) - str += "External, "; - if (query_disk.types_disk() & Query::DISK_VOLUME_TYPE_HIDDEN) - str += "Hidden, "; - if (query_disk.types_disk() & Query::DISK_VOLUME_TYPE_READ_ONLY) - str += "Read-only, "; - - if (!str.empty()) - str.erase(str.length() - 2); - SYSINFO_INSERT(str); - - } break; - - case "used"_fnv1a16: - SYSINFO_INSERT(fmt::format("{:.2f} {}", byte_units.at(USED).num_bytes, byte_units.at(USED).unit)); - break; - - case "total"_fnv1a16: - SYSINFO_INSERT(fmt::format("{:.2f} {}", byte_units.at(TOTAL).num_bytes, byte_units.at(TOTAL).unit)); - break; - - case "free"_fnv1a16: - SYSINFO_INSERT(fmt::format("{:.2f} {}", byte_units.at(FREE).num_bytes, byte_units.at(FREE).unit)); - break; - - case "free_percentage"_fnv1a16: - case "free_perc"_fnv1a16: - SYSINFO_INSERT(get_and_color_percentage(query_disk.free_amount(), query_disk.total_amount(), - parse_args, true)); - break; - - case "used_percentage"_fnv1a16: - case "used_perc"_fnv1a16: - SYSINFO_INSERT( - get_and_color_percentage(query_disk.used_amount(), query_disk.total_amount(), parse_args)); - break; - - default: - if (hasStart(moduleMemberName, "free-")) - SYSINFO_INSERT(return_divided_bytes(query_disk.free_amount())); - else if (hasStart(moduleMemberName, "used-")) - SYSINFO_INSERT(return_divided_bytes(query_disk.used_amount())); - else if (hasStart(moduleMemberName, "total-")) - SYSINFO_INSERT(return_divided_bytes(query_disk.total_amount())); - } - } - } - - else if (moduleName == "swap") - { - Query::RAM query_ram; - enum - { - USED = 0, - TOTAL, - FREE, - }; - std::array<byte_units_t, 3> byte_units; - - if (sysInfo.find(moduleName) == sysInfo.end()) - sysInfo.insert({ moduleName, {} }); - - if (sysInfo.at(moduleName).find(moduleMemberName) == sysInfo.at(moduleName).end()) - { - // idk, trick the diviser - byte_units.at(FREE) = auto_divide_bytes(query_ram.swap_free_amount() * byte_unit, byte_unit); - byte_units.at(USED) = auto_divide_bytes(query_ram.swap_used_amount() * byte_unit, byte_unit); - byte_units.at(TOTAL) = auto_divide_bytes(query_ram.swap_total_amount() * byte_unit, byte_unit); - - switch (moduleMember_hash) - { - case "free"_fnv1a16: - SYSINFO_INSERT(fmt::format("{:.2f} {}", byte_units.at(FREE).num_bytes, byte_units.at(FREE).unit)); - break; - - case "total"_fnv1a16: - SYSINFO_INSERT(fmt::format("{:.2f} {}", byte_units.at(TOTAL).num_bytes, byte_units.at(TOTAL).unit)); - break; - - case "used"_fnv1a16: - SYSINFO_INSERT(fmt::format("{:.2f} {}", byte_units.at(USED).num_bytes, byte_units.at(USED).unit)); - break; - - case "free_percentage"_fnv1a16: - case "free_perc"_fnv1a16: - SYSINFO_INSERT(get_and_color_percentage(query_ram.swap_free_amount(), query_ram.swap_total_amount(), - parse_args, true)); - break; - - case "used_percentage"_fnv1a16: - case "used_perc"_fnv1a16: - SYSINFO_INSERT(get_and_color_percentage(query_ram.swap_used_amount(), query_ram.swap_total_amount(), - parse_args)); - break; - - default: - if (hasStart(moduleMemberName, "free-")) - SYSINFO_INSERT(return_divided_bytes(query_ram.swap_free_amount())); - else if (hasStart(moduleMemberName, "used-")) - SYSINFO_INSERT(return_divided_bytes(query_ram.swap_used_amount())); - else if (hasStart(moduleMemberName, "total-")) - SYSINFO_INSERT(return_divided_bytes(query_ram.swap_total_amount())); - } - } - } - - else if (moduleName == "ram") - { - Query::RAM query_ram; - enum - { - USED = 0, - TOTAL, - FREE, - }; - std::array<byte_units_t, 3> byte_units; - - if (sysInfo.find(moduleName) == sysInfo.end()) - sysInfo.insert({ moduleName, {} }); - - if (sysInfo.at(moduleName).find(moduleMemberName) == sysInfo.at(moduleName).end()) - { - // idk, trick the diviser - byte_units.at(USED) = auto_divide_bytes(query_ram.used_amount() * byte_unit, byte_unit); - byte_units.at(TOTAL) = auto_divide_bytes(query_ram.total_amount() * byte_unit, byte_unit); - byte_units.at(FREE) = auto_divide_bytes(query_ram.free_amount() * byte_unit, byte_unit); - - switch (moduleMember_hash) - { - case "used"_fnv1a16: - SYSINFO_INSERT(fmt::format("{:.2f} {}", byte_units.at(USED).num_bytes, byte_units.at(USED).unit)); - break; - - case "total"_fnv1a16: - SYSINFO_INSERT(fmt::format("{:.2f} {}", byte_units.at(TOTAL).num_bytes, byte_units.at(TOTAL).unit)); - break; - - case "free"_fnv1a16: - SYSINFO_INSERT(fmt::format("{:.2f} {}", byte_units.at(FREE).num_bytes, byte_units.at(FREE).unit)); - break; - - case "free_percentage"_fnv1a16: - case "free_perc"_fnv1a16: - SYSINFO_INSERT( - get_and_color_percentage(query_ram.free_amount(), query_ram.total_amount(), parse_args, true)); - break; - - case "used_percentage"_fnv1a16: - case "used_perc"_fnv1a16: - SYSINFO_INSERT( - get_and_color_percentage(query_ram.used_amount(), query_ram.total_amount(), parse_args)); - break; - - default: - if (hasStart(moduleMemberName, "free-")) - SYSINFO_INSERT(return_divided_bytes(query_ram.free_amount())); - else if (hasStart(moduleMemberName, "used-")) - SYSINFO_INSERT(return_divided_bytes(query_ram.used_amount())); - else if (hasStart(moduleMemberName, "total-")) - SYSINFO_INSERT(return_divided_bytes(query_ram.total_amount())); - } - } - } - - else if (moduleName == "battery") - { - Query::Battery query_battery; - - if (sysInfo.find(moduleName) == sysInfo.end()) - sysInfo.insert({ moduleName, {} }); - - if (sysInfo.at(moduleName).find(moduleMemberName) == sysInfo.at(moduleName).end()) - { - switch (moduleMember_hash) - { - case "percentage"_fnv1a16: - case "perc"_fnv1a16: - SYSINFO_INSERT(get_and_color_percentage(query_battery.perc(), 100, parse_args, true)); - break; - - case "vendor"_fnv1a16: - case "manufacturer"_fnv1a16: SYSINFO_INSERT(query_battery.vendor()); break; - case "technology"_fnv1a16: SYSINFO_INSERT(query_battery.technology()); break; - case "name"_fnv1a16: SYSINFO_INSERT(query_battery.modelname()); break; - case "status"_fnv1a16: SYSINFO_INSERT(query_battery.status()); break; - case "capacity_level"_fnv1a16: SYSINFO_INSERT(query_battery.capacity_level()); break; - - case "temp_C"_fnv1a16: SYSINFO_INSERT(query_battery.temp()); break; - case "temp_F"_fnv1a16: SYSINFO_INSERT(query_battery.temp() * 1.8 + 34); break; - case "temp_K"_fnv1a16: SYSINFO_INSERT(query_battery.temp() + 273.15); break; - } - } - } - - else if (moduleName == "auto") - { - if (sysInfo.find(moduleName) == sysInfo.end()) - sysInfo.insert({ moduleName, {} }); - - if (sysInfo.at(moduleName).find(moduleMemberName) == sysInfo.at(moduleName).end()) - { - switch (moduleMember_hash) - { - case "disk"_fnv1a16: - Query::Disk query_disks("", queried_disks, parse_args, true); - for (const std::string& str : query_disks.disks_formats()) - { - parse_args.tmp_layout.push_back(str); - SYSINFO_INSERT(str); - } - break; - } - } - } - - else - die(_("Invalid module name: {}"), moduleName); - -#undef SYSINFO_INSERT -} - -void addValueFromModule(const std::string& moduleName, parse_args_t& parse_args) -{ - const std::string& moduleMemberName = "module-" + moduleName; -#define SYSINFO_INSERT(x) sysInfo.at(moduleName).insert({ moduleMemberName, variant(x) }) - - // just aliases for convention - const Config& config = parse_args.config; - modulesInfo_t& sysInfo = parse_args.modulesInfo; - - const std::uint16_t byte_unit = config.use_SI_unit ? 1000 : 1024; - - if (moduleName == "title") - { - if (sysInfo.find(moduleName) == sysInfo.end()) - sysInfo.insert({ moduleName, {} }); - - if (sysInfo.at(moduleName).find(moduleMemberName) == sysInfo.at(moduleName).end()) - { - SYSINFO_INSERT(parse("${auto2}$<user.name>${0}@${auto2}$<os.hostname>", _, parse_args)); - } - } - - else if (moduleName == "title_sep" || moduleName == "title_separator") - { - if (sysInfo.find(moduleName) == sysInfo.end()) - sysInfo.insert({ moduleName, {} }); - - if (sysInfo.at(moduleName).find(moduleMemberName) == sysInfo.at(moduleName).end()) - { - // no need to parse anything - Query::User query_user; - Query::System query_system; - const size_t& title_len = - std::string_view(query_user.name() + '@' + query_system.hostname()).length(); - - std::string str; - str.reserve(config.title_sep.length() * title_len); - for (size_t i = 0; i < title_len; i++) - str += config.title_sep; - - SYSINFO_INSERT(str); - } - } - - else if (moduleName == "cpu") - { - if (sysInfo.find(moduleName) == sysInfo.end()) - sysInfo.insert({ moduleName, {} }); - - if (sysInfo.at(moduleName).find(moduleMemberName) == sysInfo.at(moduleName).end()) - { - Query::CPU query_cpu; - SYSINFO_INSERT( - fmt::format("{} ({}) @ {:.2f} GHz", query_cpu.name(), query_cpu.nproc(), query_cpu.freq_max())); - } - } - - else if (hasStart(moduleName, "gpu")) - { - const std::string& id = (moduleName.length() > 3 ? moduleName.substr(3) : "0"); - - if (sysInfo.find(moduleName) == sysInfo.end()) - sysInfo.insert({ moduleName, {} }); - - if (sysInfo.at(moduleName).find(moduleMemberName) == sysInfo.at(moduleName).end()) - { - Query::GPU query_gpu(id, queried_gpus); - SYSINFO_INSERT(shorten_vendor_name(query_gpu.vendor()) + " " + query_gpu.name()); - } - } - - else if (hasStart(moduleName, "disk")) - { - if (moduleName.length() < "disk()"_len) - die(_("invalid disk module name '{}', must be disk(/path/to/fs) e.g: disk(/)"), moduleName); - - enum - { - USED = 0, - TOTAL, - }; - std::string path = moduleName; - path.erase(0, 5); // disk( - path.pop_back(); // ) - debug("disk path = {}", path); - - Query::Disk query_disk(path, queried_disks, parse_args); - std::array<byte_units_t, 2> byte_units; - - if (sysInfo.find(moduleName) == sysInfo.end()) - sysInfo.insert({ moduleName, {} }); - - if (sysInfo.at(moduleName).find(moduleMemberName) == sysInfo.at(moduleName).end()) - { - byte_units.at(TOTAL) = auto_divide_bytes(query_disk.total_amount(), byte_unit); - byte_units.at(USED) = auto_divide_bytes(query_disk.used_amount(), byte_unit); - - const std::string& perc = - get_and_color_percentage(query_disk.used_amount(), query_disk.total_amount(), parse_args); - - // clang-format off - std::string result {fmt::format("{:.2f} {} / {:.2f} {} {}", - byte_units.at(USED).num_bytes, byte_units.at(USED).unit, - byte_units.at(TOTAL).num_bytes,byte_units.at(TOTAL).unit, - parse("${0}(" + perc + ")", _, parse_args) - )}; - // clang-format on - if (query_disk.typefs() != MAGIC_LINE) - result += " - " + query_disk.typefs(); - - std::string types_disk {"["}; - if (query_disk.types_disk() & Query::DISK_VOLUME_TYPE_EXTERNAL) - types_disk += "External, "; - if (query_disk.types_disk() & Query::DISK_VOLUME_TYPE_HIDDEN) - types_disk += "Hidden, "; - if (query_disk.types_disk() & Query::DISK_VOLUME_TYPE_READ_ONLY) - types_disk += "Read-only, "; - - if (types_disk.size() > 3) - { - // ", " - types_disk.erase(types_disk.size() - 2); - result += " " + types_disk + "]"; - } - - SYSINFO_INSERT(result); - } - } - - else if (moduleName == "ram") - { - Query::RAM query_ram; - enum - { - USED = 0, - TOTAL, - }; - std::array<byte_units_t, 2> byte_units; - - if (sysInfo.find(moduleName) == sysInfo.end()) - sysInfo.insert({ moduleName, {} }); - - if (sysInfo.at(moduleName).find(moduleMemberName) == sysInfo.at(moduleName).end()) - { - // idk, trick the divider - byte_units.at(USED) = auto_divide_bytes(query_ram.used_amount() * byte_unit, byte_unit); - byte_units.at(TOTAL) = auto_divide_bytes(query_ram.total_amount() * byte_unit, byte_unit); - - const std::string& perc = - get_and_color_percentage(query_ram.used_amount(), query_ram.total_amount(), parse_args); - - // clang-format off - SYSINFO_INSERT(fmt::format("{:.2f} {} / {:.2f} {} {}", - byte_units.at(USED).num_bytes, byte_units.at(USED).unit, - byte_units.at(TOTAL).num_bytes,byte_units.at(TOTAL).unit, - parse("${0}(" + perc + ")", _, parse_args))); - // clang-format on - } - } - - else if (moduleName == "swap") - { - Query::RAM query_ram; - enum - { - USED = 0, - TOTAL, - }; - std::array<byte_units_t, 2> byte_units; - - if (sysInfo.find(moduleName) == sysInfo.end()) - sysInfo.insert({ moduleName, {} }); - - if (sysInfo.at(moduleName).find(moduleMemberName) == sysInfo.at(moduleName).end()) - { - // idk, trick the divider - byte_units.at(USED) = auto_divide_bytes(query_ram.swap_used_amount() * byte_unit, byte_unit); - byte_units.at(TOTAL) = auto_divide_bytes(query_ram.swap_total_amount() * byte_unit, byte_unit); - - // clang-format off - if (byte_units.at(TOTAL).num_bytes < 1) - SYSINFO_INSERT("Disabled"); - else - { - const std::string& perc = get_and_color_percentage(query_ram.swap_used_amount(), query_ram.swap_total_amount(), - parse_args); - - SYSINFO_INSERT(fmt::format("{:.2f} {} / {:.2f} {} {}", - byte_units.at(USED).num_bytes, byte_units.at(USED).unit, - byte_units.at(TOTAL).num_bytes,byte_units.at(TOTAL).unit, - parse("${0}(" + perc + ")", _, parse_args))); - } - // clang-format on - } - } - - else if (moduleName == "battery") - { - Query::Battery query_battery; - if (sysInfo.find(moduleName) == sysInfo.end()) - sysInfo.insert({ moduleName, {} }); - - if (sysInfo.at(moduleName).find(moduleMemberName) == sysInfo.at(moduleName).end()) - { - SYSINFO_INSERT(fmt::format("{} [{}]", get_and_color_percentage(query_battery.perc(), 100, parse_args, true), - query_battery.status())); - } - } - - else if (moduleName == "colors") - { - if (sysInfo.find(moduleName) == sysInfo.end()) - sysInfo.insert({ moduleName, {} }); - - if (sysInfo.at(moduleName).find(moduleMemberName) == sysInfo.at(moduleName).end()) - { - SYSINFO_INSERT(parse("${\033[40m} ${\033[41m} ${\033[42m} ${\033[43m} ${\033[44m} ${\033[45m} ${\033[46m} ${\033[47m} ${0}", _, parse_args)); - } - } - - else if (moduleName == "colors_light") - { - if (sysInfo.find(moduleName) == sysInfo.end()) - sysInfo.insert({ moduleName, {} }); - - if (sysInfo.at(moduleName).find(moduleMemberName) == sysInfo.at(moduleName).end()) - { - SYSINFO_INSERT(parse("${\033[100m} ${\033[101m} ${\033[102m} ${\033[103m} ${\033[104m} ${\033[105m} ${\033[106m} ${\033[107m} ${0}", _, parse_args)); - } - } - - // clang-format off - // I really dislike how repetitive this code is - else if (hasStart(moduleName, "colors_symbol")) - { - if (sysInfo.find(moduleName) == sysInfo.end()) - sysInfo.insert({ moduleName, {} }); - - if (sysInfo.at(moduleName).find(moduleMemberName) == sysInfo.at(moduleName).end()) - { - if (moduleName.length() <= "colors_symbol()"_len) - die(_("color palette module member '{}' in invalid.\n" - "Must be used like 'colors_symbol(`symbol for printing the color palette`)'.\n" - "e.g 'colors_symbol(@)' or 'colors_symbol(string)'"), - moduleName); - - std::string symbol = moduleName; - symbol.erase(0, "colors_symbol("_len); - symbol.pop_back(); - debug("symbol = {}", symbol); - - SYSINFO_INSERT( - parse(fmt::format("${{\033[30m}} {0} ${{\033[31m}} {0} ${{\033[32m}} {0} ${{\033[33m}} {0} ${{\033[34m}} {0} ${{\033[35m}} {0} ${{\033[36m}} {0} ${{\033[37m}} {0} ${{0}}", - symbol), _, parse_args)); - } - } - - else if (hasStart(moduleName, "colors_light_symbol")) - { - if (sysInfo.find(moduleName) == sysInfo.end()) - sysInfo.insert({ moduleName, {} }); - - if (sysInfo.at(moduleName).find(moduleMemberName) == sysInfo.at(moduleName).end()) - { - if (moduleName.length() <= "colors_light_symbol()"_len) - die(_("light color palette module member '{}' in invalid.\n" - "Must be used like 'colors_light_symbol(`symbol for printing the color palette`)'.\n" - "e.g 'colors_light_symbol(@)' or 'colors_light_symbol(string)'"), - moduleName); - - std::string symbol = moduleName; - symbol.erase(0, "colors_light_symbol("_len); - symbol.pop_back(); - debug("symbol = {}", symbol); - - SYSINFO_INSERT( - parse(fmt::format("${{\033[90m}} {0} ${{\033[91m}} {0} ${{\033[92m}} {0} ${{\033[93m}} {0} ${{\033[94m}} {0} ${{\033[95m}} {0} ${{\033[96m}} {0} ${{\033[97m}} {0} ${{0}}", - symbol), _, parse_args)); - } - } - - else - die(_("Invalid module name: {}"), moduleName); -} -#endif From b8b863965a6eb563551433db1f4232560400ee88 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Wed, 9 Jul 2025 20:33:11 +0200 Subject: [PATCH 079/143] core-modules: android: add some modules support patch by @BurntRanch --- src/core-modules/android/os.cc | 46 ++++++++++++++++++++++++++ src/core-modules/android/system.cc | 53 ++++++++++++++++++++++++++++++ src/core-modules/core-modules.cc | 4 ++- src/core-modules/linux/system.cc | 5 +++ 4 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 src/core-modules/android/os.cc create mode 100644 src/core-modules/android/system.cc diff --git a/src/core-modules/android/os.cc b/src/core-modules/android/os.cc new file mode 100644 index 00000000..aacd3b9d --- /dev/null +++ b/src/core-modules/android/os.cc @@ -0,0 +1,46 @@ +#include <cassert> +#include <cstdio> +#include <cstring> +#include <string> + +#include "core-modules.hh" +#include "fmt/format.h" +#include "platform.hpp" +#include "util.hpp" + +#if CF_ANDROID +MODFUNC(os_name) +{ return "Android"; } + +MODFUNC(os_pretty_name) +{ return "Android " + os_version_codename(NULL) + " " + os_version_id(NULL); } + +MODFUNC(os_name_id) +{ return "android"; } + +MODFUNC(os_version_id) +{ return get_android_property("ro.build.version.release"); } + +MODFUNC(os_version_codename) +{ return get_android_property("ro.build.version.codename"); } + +MODFUNC(os_kernel_name) +{ return g_uname_infos.sysname; } + +MODFUNC(os_kernel_version) +{ return g_uname_infos.release; } + +MODFUNC(os_hostname) +{ return g_uname_infos.nodename; } + +MODFUNC(os_initsys_name) +{ + return "init"; +} + +MODFUNC(os_initsys_version) +{ + return ""; +} + +#endif diff --git a/src/core-modules/android/system.cc b/src/core-modules/android/system.cc new file mode 100644 index 00000000..8c80de78 --- /dev/null +++ b/src/core-modules/android/system.cc @@ -0,0 +1,53 @@ +#include "platform.hpp" + +#if CF_ANDROID +#include <sys/utsname.h> + +#include <string> +#include <string_view> + +#include "cufetch/common.hh" +#include "core-modules.hh" +#include "util.hpp" + +static constexpr std::array<std::string_view, 8> vendors_prop_names = { + "ro.product.marketname", "ro.vendor.product.display", "ro.config.devicename", "ro.config.marketing_name", + "ro.product.vendor.model", "ro.product.oppo_model", "ro.oppo.market.name", "ro.product.brand" + }; + +/* The handler that we'll use for our module, Handlers return const std::string (WILL be changed to const char + * pointers). */ +MODFUNC(host) +{ + return host_vendor(NULL) + ' ' + host_name(NULL) + ' ' + host_version(NULL); +} + +MODFUNC(host_name) +{ + std::string model_name; + for (const std::string_view name : vendors_prop_names) + { + model_name = get_android_property(name); + if (!model_name.empty()) + return model_name; + } + + return UNKNOWN; +} + +MODFUNC(host_version) +{ + return get_android_property("ro.product.model"); +} + +MODFUNC(host_vendor) +{ + return get_android_property("ro.product.manufacturer"); +} + +MODFUNC(arch) +{ + return g_uname_infos.machine; +} + +#endif diff --git a/src/core-modules/core-modules.cc b/src/core-modules/core-modules.cc index 13d8a9b9..8e09c994 100644 --- a/src/core-modules/core-modules.cc +++ b/src/core-modules/core-modules.cc @@ -120,10 +120,12 @@ void core_plugins_start(const Config& config) const size_t uptime_hours = uptime_secs / (60 * 60); const size_t uptime_days = uptime_secs / (60 * 60 * 24); -#if CF_LINUX +#if CF_LINUX || CF_ANDROID if (uname(&g_uname_infos) != 0) die(_("uname() failed: {}\nCould not get system infos"), std::strerror(errno)); +#endif +#if CF_LINUX if (g_pwd = getpwuid(getuid()), !g_pwd) die(_("getpwent failed: {}\nCould not get user infos"), std::strerror(errno)); #endif diff --git a/src/core-modules/linux/system.cc b/src/core-modules/linux/system.cc index 065eab01..c0b6b97b 100644 --- a/src/core-modules/linux/system.cc +++ b/src/core-modules/linux/system.cc @@ -1,3 +1,6 @@ +#include "platform.hpp" + +#if CF_LINUX #include <sys/utsname.h> #include <filesystem> @@ -93,3 +96,5 @@ MODFUNC(arch) { return g_uname_infos.machine; } + +#endif From 296b1d924c56b88b17463043fb37298548e6b376 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Wed, 9 Jul 2025 21:12:24 +0200 Subject: [PATCH 080/143] core-modules: android: add more modules support --- include/core-modules.hh | 2 + src/core-modules/android/gpu.cc | 185 +++++++++++ src/core-modules/android/os.cc | 22 +- src/core-modules/android/system.cc | 13 +- src/core-modules/android/theme.cc | 21 ++ src/core-modules/android/user.cc | 56 ++++ src/core-modules/core-modules.cc | 4 + src/core-modules/linux/cpu.cc | 488 ++++++++++++++++++++++++++++- src/core-modules/linux/system.cc | 8 +- 9 files changed, 771 insertions(+), 28 deletions(-) create mode 100644 src/core-modules/android/gpu.cc create mode 100644 src/core-modules/android/theme.cc create mode 100644 src/core-modules/android/user.cc diff --git a/include/core-modules.hh b/include/core-modules.hh index 2fd23780..b34d6988 100644 --- a/include/core-modules.hh +++ b/include/core-modules.hh @@ -39,6 +39,8 @@ MODFUNC(cpu_freq_bios); float cpu_temp(); MODFUNC(cpu_nproc); MODFUNC(cpu_name); +MODFUNC(android_cpu_vendor); +MODFUNC(android_cpu_model_name); // user.cc inline bool is_tty = false; diff --git a/src/core-modules/android/gpu.cc b/src/core-modules/android/gpu.cc new file mode 100644 index 00000000..f679a072 --- /dev/null +++ b/src/core-modules/android/gpu.cc @@ -0,0 +1,185 @@ +#include "platform.hpp" +#if CF_ANDROID + +#include <string> + +#include "core-modules.hh" +#include "cufetch/common.hh" +#include "switch_fnv1a.hpp" + +// https://en.wikipedia.org/wiki/List_of_Qualcomm_Snapdragon_systems_on_chips +static std::string detect_adreno(const std::string& cpu_model_name) +{ + switch (fnv1a16::hash(cpu_model_name)) + { + case "MSM8225Q"_fnv1a16: + case "MSM8625Q"_fnv1a16: return "Adreno (TM) 203"; + + case "MSM8210"_fnv1a16: + case "MSM8610"_fnv1a16: + case "MSM8212"_fnv1a16: + case "MSM8612"_fnv1a16: return "Adreno (TM) 302"; + + case "MSM8905"_fnv1a16: + case "MSM8208"_fnv1a16: + case "MSM8909"_fnv1a16: + case "MSM8909AA"_fnv1a16: return "Adreno (TM) 304"; + + case "APQ8026"_fnv1a16: + case "MSM8226"_fnv1a16: + case "MSM8926"_fnv1a16: + case "APQ8028"_fnv1a16: + case "MSM8228"_fnv1a16: + case "MSM8628"_fnv1a16: + case "MSM8928"_fnv1a16: + case "MSM8230"_fnv1a16: + case "MSM8630"_fnv1a16: + case "MSM8930"_fnv1a16: + case "MSM8930AA"_fnv1a16: + case "APQ8030AB"_fnv1a16: + case "MSM8230AB"_fnv1a16: + case "MSM8630AB"_fnv1a16: + case "MSM8930AB"_fnv1a16: return "Adreno (TM) 305"; + + case "APQ8016"_fnv1a16: + case "MSM8916"_fnv1a16: return "Adreno (TM) 306"; + + case "QM215"_fnv1a16: + case "MSM8917"_fnv1a16: + case "MSM8920"_fnv1a16: return "Adreno (TM) 308"; + + case "APQ8064M"_fnv1a16: + case "APQ8064T"_fnv1a16: + case "APQ8064AB"_fnv1a16: return "Adreno (TM) 320"; + + case "APQ8074AA"_fnv1a16: + case "MSM8274AA"_fnv1a16: + case "MSM8674AA"_fnv1a16: + case "MSM8974AA"_fnv1a16: + case "MSM8274AB"_fnv1a16: return "Adreno (TM) 330"; + + case "MSM8936"_fnv1a16: + case "MSM8939"_fnv1a16: + case "MSM8952"_fnv1a16: + case "MSM8929"_fnv1a16: return "Adreno (TM) 405"; + + case "MSM8992"_fnv1a16: return "Adreno (TM) 418"; + case "APQ8084"_fnv1a16: return "Adreno (TM) 420"; + case "MSM8994"_fnv1a16: return "Adreno (TM) 430"; + + case "SDM429"_fnv1a16: return "Adreno (TM) 504"; + + case "SDM439"_fnv1a16: + case "SDM450"_fnv1a16: + case "MSM8937"_fnv1a16: + case "MSM8940"_fnv1a16: return "Adreno (TM) 505"; + + case "MSM8953"_fnv1a16: + case "SDM632"_fnv1a16: return "Adreno (TM) 506"; + case "SDM630"_fnv1a16: return "Adreno (TM) 508"; + case "SDM636"_fnv1a16: return "Adreno (TM) 509"; + + case "MSM8956"_fnv1a16: + case "MSM8976"_fnv1a16: return "Adreno (TM) 510"; + + case "SDM660"_fnv1a16: return "Adreno (TM) 512"; + case "MSM8996"_fnv1a16: return "Adreno (TM) 530"; + case "MSM8998"_fnv1a16: return "Adreno (TM) 540"; + + case "SM6225"_fnv1a16: + case "SM6115"_fnv1a16: + case "SM6125"_fnv1a16: + case "SM6115-AC"_fnv1a16: + case "SM6225-AD"_fnv1a16: + case "SM4250-AA"_fnv1a16: return "Adreno (TM) 610"; + + case "SM4635"_fnv1a16: return "Adreno (TM) 611"; + case "SM6150"_fnv1a16: + case "SM6150-AC"_fnv1a16: return "Adreno (TM) 612"; + case "SM4450"_fnv1a16: return "Adreno (TM) 613"; + case "SDM670"_fnv1a16: return "Adreno (TM) 615"; + + case "SDM710"_fnv1a16: + case "SDM712"_fnv1a16: return "Adreno (TM) 616"; + + case "SM7125"_fnv1a16: + case "SM7150-AA"_fnv1a16: + case "SM7150-AB"_fnv1a16: + case "SM7150-AC"_fnv1a16: return "Adreno (TM) 618"; + + case "SM4375"_fnv1a16: + case "SM4350"_fnv1a16: + case "SM6375"_fnv1a16: + case "SM7225"_fnv1a16: + case "SM6375-AC"_fnv1a16: + case "SM4350-AC"_fnv1a16: return "Adreno (TM) 619"; + + case "SM6350"_fnv1a16: return "Adreno (TM) 619L"; + + case "SM7250-AA"_fnv1a16: + case "SM7250-AB"_fnv1a16: + case "SM7250-AC"_fnv1a16: return "Adreno (TM) 620"; + + case "SDM845"_fnv1a16: return "Adreno (TM) 630"; + + case "SM8150"_fnv1a16: + case "SM8150-AC"_fnv1a16: + case "SM8150P"_fnv1a16: return "Adreno (TM) 640"; + + case "SM7350-AB"_fnv1a16: return "Adreno (TM) 642"; + + case "SM7325"_fnv1a16: + case "SM7325-AF"_fnv1a16: + case "SM7325-AE"_fnv1a16: return "Adreno (TM) 642L"; + case "SM7450-AB"_fnv1a16: return "Adreno (TM) 644"; + + case "SM8250"_fnv1a16: + case "SM8250-AB"_fnv1a16: + case "SM8250-AC"_fnv1a16: return "Adreno (TM) 650"; + + case "SM8350"_fnv1a16: + case "SM8350-AC"_fnv1a16: return "Adreno (TM) 660"; + + case "SM7435-AB"_fnv1a16: + case "SM6475-AB"_fnv1a16: + case "SM6450"_fnv1a16: return "Adreno (TM) 710"; + + case "SM7550-AB"_fnv1a16: return "Adreno (TM) 720"; + case "SM7475-AB"_fnv1a16: return "Adreno (TM) 725"; + + case "SM8450"_fnv1a16: + case "SM8475"_fnv1a16: + case "SM8425-100-AC"_fnv1a16: return "Adreno (TM) 730"; + + case "SM7675-AB"_fnv1a16: return "Adreno (TM) 732"; + case "SM8635"_fnv1a16: return "Adreno (TM) 735"; + + case "SM8550"_fnv1a16: + case "SM8550-AB"_fnv1a16: + case "SM8550-AC"_fnv1a16: return "Adreno (TM) 740"; + + case "SM8650-AB"_fnv1a16: + case "SM8650-AC"_fnv1a16: return "Adreno (TM) 750"; + + case "SM7635"_fnv1a16: return "Adreno (TM) 810"; + case "SM8750-AB"_fnv1a16: return "Adreno (TM) 830"; + } + + return MAGIC_LINE; +} + +MODFUNC(gpu_name) +{ + const std::string& vendor = android_cpu_vendor(nullptr); + if (vendor == "QUALCOMM" || vendor == "QTI") + return detect_adreno(android_cpu_model_name(nullptr)); + + return MAGIC_LINE; +} + +MODFUNC(gpu_vendor) +{ + return android_cpu_vendor(nullptr); +} + +#endif diff --git a/src/core-modules/android/os.cc b/src/core-modules/android/os.cc index aacd3b9d..37d2f593 100644 --- a/src/core-modules/android/os.cc +++ b/src/core-modules/android/os.cc @@ -1,14 +1,9 @@ -#include <cassert> -#include <cstdio> -#include <cstring> -#include <string> +#include "platform.hpp" +#if CF_ANDROID #include "core-modules.hh" -#include "fmt/format.h" -#include "platform.hpp" #include "util.hpp" -#if CF_ANDROID MODFUNC(os_name) { return "Android"; } @@ -34,13 +29,18 @@ MODFUNC(os_hostname) { return g_uname_infos.nodename; } MODFUNC(os_initsys_name) -{ - return "init"; -} +{ return "init"; } MODFUNC(os_initsys_version) +{ return ""; } + +unsigned long os_uptime() { - return ""; + struct std::timespec uptime; + if (clock_gettime(CLOCK_BOOTTIME, &uptime) != 0) + return 0; + + return (uint64_t)uptime.tv_sec + (uint64_t)uptime.tv_nsec / 1000000; } #endif diff --git a/src/core-modules/android/system.cc b/src/core-modules/android/system.cc index 8c80de78..f075ebc6 100644 --- a/src/core-modules/android/system.cc +++ b/src/core-modules/android/system.cc @@ -1,8 +1,6 @@ #include "platform.hpp" #if CF_ANDROID -#include <sys/utsname.h> - #include <string> #include <string_view> @@ -15,19 +13,16 @@ static constexpr std::array<std::string_view, 8> vendors_prop_names = { "ro.product.vendor.model", "ro.product.oppo_model", "ro.oppo.market.name", "ro.product.brand" }; -/* The handler that we'll use for our module, Handlers return const std::string (WILL be changed to const char - * pointers). */ MODFUNC(host) { - return host_vendor(NULL) + ' ' + host_name(NULL) + ' ' + host_version(NULL); + return host_vendor(NULL) + " " + host_name(NULL) + " " + host_version(NULL); } MODFUNC(host_name) { - std::string model_name; for (const std::string_view name : vendors_prop_names) { - model_name = get_android_property(name); + const std::string& model_name = get_android_property(name); if (!model_name.empty()) return model_name; } @@ -46,8 +41,6 @@ MODFUNC(host_vendor) } MODFUNC(arch) -{ - return g_uname_infos.machine; -} +{ return g_uname_infos.machine; } #endif diff --git a/src/core-modules/android/theme.cc b/src/core-modules/android/theme.cc new file mode 100644 index 00000000..3b003ab8 --- /dev/null +++ b/src/core-modules/android/theme.cc @@ -0,0 +1,21 @@ +#include "platform.hpp" +#if !CF_ANDROID + +#include "core-modules.hh" +#include "cufetch/common.hh" + +MODFUNC(theme_gtk_name) { return MAGIC_LINE; } +MODFUNC(theme_gtk_icon) { return MAGIC_LINE; } +MODFUNC(theme_gtk_font) { return MAGIC_LINE; } +MODFUNC(theme_cursor_name) { return MAGIC_LINE; } +MODFUNC(theme_cursor_size) { return MAGIC_LINE; } +MODFUNC(theme_gtk_all_name) { return MAGIC_LINE; } +MODFUNC(theme_gtk_all_icon) { return MAGIC_LINE; } +MODFUNC(theme_gtk_all_font) { return MAGIC_LINE; } +MODFUNC(theme_gsettings_name) { return MAGIC_LINE; } +MODFUNC(theme_gsettings_icon) { return MAGIC_LINE; } +MODFUNC(theme_gsettings_font) { return MAGIC_LINE; } +MODFUNC(theme_gsettings_cursor_name) { return MAGIC_LINE; } +MODFUNC(theme_gsettings_cursor_size) { return MAGIC_LINE; } + +#endif // !CF_ANDROID diff --git a/src/core-modules/android/user.cc b/src/core-modules/android/user.cc new file mode 100644 index 00000000..abe83147 --- /dev/null +++ b/src/core-modules/android/user.cc @@ -0,0 +1,56 @@ +#include "platform.hpp" +#if CF_ANDROID + +#include <linux/limits.h> +#include <string> + +#include "core-modules.hh" +#include "util.hpp" + +MODFUNC(user_name) +{ return g_pwd->pw_name; } + +MODFUNC(user_shell_path) +{ + char buf[PATH_MAX]; + return realpath(fmt::format("/proc/{}/exe", getppid()).c_str(), buf); +} + +MODFUNC(user_shell_name) +{ + return user_shell_path(callbackInfo).substr(user_shell_path(callbackInfo).rfind('/') + 1); +} + +MODFUNC(user_shell_version) +{ + const std::string& shell_name = user_shell_name(callbackInfo); + std::string ret; + + if (shell_name == "nu") + ret = read_shell_exec("nu -c \"version | get version\""); + else + ret = read_shell_exec(fmt::format("{} -c 'echo \"${}_VERSION\"'", shell_name, str_toupper(shell_name.data()))); + + strip(ret); + return ret; +} + +MODFUNC(user_term_name) +{ return "Termux"; } + +MODFUNC(user_term_version) +{ return getenv("TERMUX_VERSION"); } + +MODFUNC(user_wm_name) +{ return MAGIC_LINE; } + +MODFUNC(user_wm_version) +{ return MAGIC_LINE; } + +MODFUNC(user_de_name) +{ return MAGIC_LINE; } + +MODFUNC(user_de_version) +{ return MAGIC_LINE; } + +#endif diff --git a/src/core-modules/core-modules.cc b/src/core-modules/core-modules.cc index 8e09c994..930d507c 100644 --- a/src/core-modules/core-modules.cc +++ b/src/core-modules/core-modules.cc @@ -142,6 +142,10 @@ void core_plugins_start(const Config& config) meminfo = fopen("/proc/meminfo", "r"); mountsFile = setmntent("/proc/mounts", "r"); +#if CF_ANDROID + is_tty = true; +#endif + // ------------ MODULES REGISTERING ------------ module_t os_name_pretty_module = {"pretty", "OS pretty name [Ubuntu 22.04.4 LTS; Arch Linux]", {}, os_pretty_name}; module_t os_name_id_module = {"id", "OS id name [ubuntu, arch]", {}, os_name_id}; diff --git a/src/core-modules/linux/cpu.cc b/src/core-modules/linux/cpu.cc index d3ea5866..28f3fdcb 100644 --- a/src/core-modules/linux/cpu.cc +++ b/src/core-modules/linux/cpu.cc @@ -1,3 +1,6 @@ +#include <cstring> +#include "platform.hpp" +#if CF_ANDROID || CF_LINUX #include <unistd.h> #include <string> @@ -5,10 +8,459 @@ #include "cufetch/common.hh" #include "core-modules.hh" #include "fmt/format.h" +#include "switch_fnv1a.hpp" #include "util.hpp" const std::string freq_dir = "/sys/devices/system/cpu/cpu0/cpufreq"; +#if CF_ANDROID +// https://en.wikipedia.org/wiki/List_of_Qualcomm_Snapdragon_systems_on_chips +// by Toni500git +static std::string detect_qualcomm(const std::string& model_name) +{ + switch (fnv1a16::hash(str_toupper(model_name))) + { + case "SM8750-AB"_fnv1a16: return "Snapdragon 8 Elite"; + case "SM8635"_fnv1a16: return "Snapdragon 8s Gen 3"; + case "SM8650-AC"_fnv1a16: return "Snapdragon 8 Gen 3 for Galaxy"; + case "SM8650"_fnv1a16: return "Snapdragon 8 Gen 3"; + case "SM8550-AC"_fnv1a16: return "Snapdragon 8 Gen 2 for Galaxy"; + case "SM8550"_fnv1a16: return "Snapdragon 8 Gen 2"; + case "SM8475"_fnv1a16: return "Snapdragon 8+ Gen 1"; + case "SM8450"_fnv1a16: return "Snapdragon 8 Gen 1"; + + case "SM7450-AB"_fnv1a16: return "Snapdragon 7 Gen 1"; + case "SM7475-AB"_fnv1a16: return "Snapdragon 7+ Gen 2"; + case "SM7435-AB"_fnv1a16: return "Snapdragon 7s Gen 2"; + case "SM7550-AB"_fnv1a16: return "Snapdragon 7 Gen 3"; + case "SM7675-AB"_fnv1a16: return "Snapdragon 7+ Gen 3"; + case "SM7635"_fnv1a16: return "Snapdragon 7s Gen 3"; + + case "SM6375-AC"_fnv1a16: return "Snapdragon 6s Gen 3"; + case "SM6475-AB"_fnv1a16: return "Snapdragon 6 Gen 3"; + case "SM6115-AC"_fnv1a16: return "Snapdragon 6s Gen 1"; + case "SM6450"_fnv1a16: return "Snapdragon 6 Gen 1"; + + case "SM4635"_fnv1a16: return "Snapdragon 4s Gen 2"; + case "SM4450"_fnv1a16: return "Snapdragon 4 Gen 2"; + case "SM4375"_fnv1a16: return "Snapdragon 4 Gen 1"; + + // adding fastfetch's many missing chips names + case "MSM8225Q"_fnv1a16: + case "MSM8625Q"_fnv1a16: + case "MSM8210"_fnv1a16: + case "MSM8610"_fnv1a16: + case "MSM8212"_fnv1a16: + case "MSM8612"_fnv1a16: return "Snapdragon 200"; + + case "MSM8905"_fnv1a16: return "205"; // Qualcomm 205 + case "MSM8208"_fnv1a16: return "Snapdragon 208"; + case "MSM8909"_fnv1a16: return "Snapdragon 210"; + case "MSM8909AA"_fnv1a16: return "Snapdragon 212"; + case "QM215"_fnv1a16: return "215"; + + // holy crap + case "APQ8026"_fnv1a16: + case "MSM8226"_fnv1a16: + case "MSM8926"_fnv1a16: + case "APQ8028"_fnv1a16: + case "MSM8228"_fnv1a16: + case "MSM8628"_fnv1a16: + case "MSM8928"_fnv1a16: + case "MSM8230"_fnv1a16: + case "MSM8630"_fnv1a16: + case "MSM8930"_fnv1a16: + case "MSM8930AA"_fnv1a16: + case "APQ8030AB"_fnv1a16: + case "MSM8230AB"_fnv1a16: + case "MSM8630AB"_fnv1a16: + case "MSM8930AB"_fnv1a16: return "Snapdragon 400"; + + case "APQ8016"_fnv1a16: + case "MSM8916"_fnv1a16: return "Snapdragon 410"; + case "MSM8929"_fnv1a16: return "Snapdragon 415"; + case "MSM8917"_fnv1a16: return "Snapdragon 425"; + case "MSM8920"_fnv1a16: return "Snapdragon 427"; + case "MSM8937"_fnv1a16: return "Snapdragon 430"; + case "MSM8940"_fnv1a16: return "Snapdragon 435"; + case "SDM429"_fnv1a16: return "Snapdragon 429"; + case "SDM439"_fnv1a16: return "Snapdragon 439"; + case "SDM450"_fnv1a16: return "Snapdragon 450"; + case "SM4250-AA"_fnv1a16: return "Snapdragon 460"; + case "SM4350"_fnv1a16: return "Snapdragon 480"; + case "SM4350-AC"_fnv1a16: return "Snapdragon 480+"; + + case "APQ8064-1AA"_fnv1a16: + case "APQ8064M"_fnv1a16: + case "APQ8064T"_fnv1a16: + case "APQ8064AB"_fnv1a16: return "Snapdragon 600"; + + case "MSM8936"_fnv1a16: return "Snapdragon 610"; + case "MSM8939"_fnv1a16: return "Snapdragon 615"; + case "MSM8952"_fnv1a16: return "Snapdragon 617"; + case "MSM8953"_fnv1a16: return "Snapdragon 625"; + case "SDM630"_fnv1a16: return "Snapdragon 630"; + case "SDM632"_fnv1a16: return "Snapdragon 632"; + case "SDM636"_fnv1a16: return "Snapdragon 636"; + case "MSM8956"_fnv1a16: return "Snapdragon 650"; + case "MSM8976"_fnv1a16: return "Snapdragon 652"; + case "SDA660"_fnv1a16: + case "SDM660"_fnv1a16: return "Snapdragon 660"; + case "SM6115"_fnv1a16: return "Snapdragon 662"; + case "SM6125"_fnv1a16: return "Snapdragon 665"; + case "SDM670"_fnv1a16: return "Snapdragon 670"; + case "SM6150"_fnv1a16: return "Snapdragon 675"; + case "SM6150-AC"_fnv1a16: return "Snapdragon 678"; + case "SM6225"_fnv1a16: return "Snapdragon 680"; + case "SM6225-AD"_fnv1a16: return "Snapdragon 685"; + case "SM6350"_fnv1a16: return "Snapdragon 690"; + case "SM6375"_fnv1a16: return "Snapdragon 695"; + + case "SDM710"_fnv1a16: return "Snapdragon 710"; + case "SDM712"_fnv1a16: return "Snapdragon 712"; + case "SM7125"_fnv1a16: return "Snapdragon 720G"; + case "SM7150-AA"_fnv1a16: return "Snapdragon 730"; + case "SM7150-AB"_fnv1a16: return "Snapdragon 730G"; + case "SM7150-AC"_fnv1a16: return "Snapdragon 732G"; + case "SM7225"_fnv1a16: return "Snapdragon 750G"; + case "SM7250-AA"_fnv1a16: return "Snapdragon 765"; + case "SM7250-AB"_fnv1a16: return "Snapdragon 765G"; + case "SM7250-AC"_fnv1a16: return "Snapdragon 768G"; + case "SM7325"_fnv1a16: return "Snapdragon 778G"; + case "SM7325-AE"_fnv1a16: return "Snapdragon 778G+"; + case "SM7350-AB"_fnv1a16: return "Snapdragon 780G"; + case "SM7325-AF"_fnv1a16: return "Snapdragon 782G"; + + case "APQ8074AA"_fnv1a16: + case "MSM8274AA"_fnv1a16: + case "MSM8674AA"_fnv1a16: + case "MSM8974AA"_fnv1a16: + case "MSM8274AB"_fnv1a16: return "Snapdragon 800"; + + case "APQ8084"_fnv1a16: return "Snapdragon 805"; + case "MSM8992"_fnv1a16: return "Snapdragon 808"; + case "MSM8994"_fnv1a16: return "Snapdragon 810"; + case "MSM8996"_fnv1a16: return "Snapdragon 820"; + case "MSM8998"_fnv1a16: return "Snapdragon 835"; + case "SDM845"_fnv1a16: return "Snapdragon 845"; + case "SM8150"_fnv1a16: return "Snapdragon 855"; + case "SM8150P"_fnv1a16: + case "SM8150-AC"_fnv1a16: return "Snapdragon 855+"; // both 855+ and 860 + case "SM8250"_fnv1a16: return "Snapdragon 865"; + case "SM8250-AB"_fnv1a16: return "Snapdragon 865+"; + case "SM8250-AC"_fnv1a16: return "Snapdragon 870"; + case "SM8350"_fnv1a16: return "Snapdragon 888"; + case "SM8350-AC"_fnv1a16: return "Snapdragon 888+"; + } + + return model_name; +} + +// https://en.wikipedia.org/wiki/Exynos#Current_Exynos_SoCs_(2020%E2%80%93present) +// by BurntRanch +static std::string detect_exynos(const std::string& model_name) +{ + switch (fnv1a16::hash(str_toupper(model_name))) + { + case "S5E3830"_fnv1a16: return "Exynos 850"; + case "S5E8805"_fnv1a16: return "Exynos 880"; + + case "S5E9630"_fnv1a16: return "Exynos 980"; + case "S5E9830"_fnv1a16: return "Exynos 990"; + + case "S5E9815"_fnv1a16: return "Exynos 1080"; + case "S5E8825"_fnv1a16: return "Exynos 1280"; + case "S5E8535"_fnv1a16: return "Exynos 1330"; + case "S5E8835"_fnv1a16: return "Exynos 1380"; + case "S5E8845"_fnv1a16: return "Exynos 1480"; + case "S5E8855"_fnv1a16: + return "Exynos 1580"; + /* TODO: alot of SoCs with no ID mentioned on Wikipedia.. */ + + case "S5E9840"_fnv1a16: return "Exynos 2100"; + case "S5E9925"_fnv1a16: return "Exynos 2200"; + case "S5E9945"_fnv1a16: return "Exynos 2400[e]"; + + case "S5PC110"_fnv1a16: return "Exynos 3 Single 3110"; + case "S5E3470"_fnv1a16: return "Exynos 3 Quad 3470"; + /* TODO: ASSUMPTION!! I could not find the full part number for this, I'm making an assumption here. */ + case "S5E3475"_fnv1a16: return "Exynos 3 Quad 3475"; + + case "S5E4210"_fnv1a16: + case "S5PC210"_fnv1a16: return "Exynos 4 Dual 4210"; + + case "S5E4212"_fnv1a16: return "Exynos 4 Dual 4212"; + + case "S55E4210"_fnv1a16: + case "S5PC220"_fnv1a16: + return "Exynos 4 Quad 4412"; + + /* TODO: Exynos 4 Quad 4415 */ + + case "S5E5250"_fnv1a16: + case "S5PC520"_fnv1a16: return "Exynos 5 Dual 5250"; + + case "S5E5260"_fnv1a16: return "Exynos 5 Hexa 5260"; + case "S5E5410"_fnv1a16: return "Exynos 5 Octa 5410"; + case "S5E5420"_fnv1a16: return "Exynos 5 Octa 5420"; + + /* 5800 for chromebooks */ + case "S5E5422"_fnv1a16: return "Exynos 5 Octa 5422/5800"; + + case "S5E5430"_fnv1a16: return "Exynos 5 Octa 5430"; + case "S5E5433"_fnv1a16: return "Exynos 7 Octa 5433"; + case "SC57270"_fnv1a16: return "Exynos 7 Dual 7270"; + case "S5E7420"_fnv1a16: return "Exynos 7 Octa 7420"; + case "S5E7570"_fnv1a16: + return "Exynos 7 Quad 7570"; + /* TODO: Exynos 7 Quad/Octa 7578/7580 */ + + case "S5E7870"_fnv1a16: return "Exynos 7 Octa 7870"; + case "S5E7872"_fnv1a16: return "Exynos 5 7872"; + case "S5E7880"_fnv1a16: return "Exynos 7880"; + case "S5E7884"_fnv1a16: return "Exynos 7884/7885"; + case "S5E7904"_fnv1a16: return "Exynos 7904"; + case "S5E8890"_fnv1a16: return "Exynos 8 Octa 8890"; + case "S5E8895"_fnv1a16: return "Exynos 8895"; + case "S5E9609"_fnv1a16: return "Exynos 9609"; + case "S5E9610"_fnv1a16: return "Exynos 9610"; + case "S5E9611"_fnv1a16: return "Exynos 9611"; + case "S5E9810"_fnv1a16: return "Exynos 9810"; + case "S5E9820"_fnv1a16: return "Exynos 9820"; + case "S5E9825"_fnv1a16: + return "Exynos 9825"; + /* TODO: Exynos 3 Dual 3250 */ + + case "SC59110XSC"_fnv1a16: return "Exynos 9110"; + case "SC55515XBD"_fnv1a16: return "Exynos W920"; + case "SC55515XBE"_fnv1a16: return "Exynos W930"; + case "SC55535AHA"_fnv1a16: return "Exynos W1000"; + } + + return model_name; +} + +// https://en.wikipedia.org/wiki/List_of_MediaTek_systems_on_chips +// by Toni500git +// i need some coffee..... +// wayland crashed and had to restart from Dimensity 1000 series......... +static std::string detect_mediatek(const std::string& model_name) +{ + switch (fnv1a16::hash(model_name)) + { + // Helio series + // Helio X series + case "MT6795"_fnv1a16: + case "MT6795M"_fnv1a16: + case "MT6795T"_fnv1a16: return "Helio X10"; + + case "MT6797"_fnv1a16: return "Helio X20"; + case "MT6797D"_fnv1a16: return "Helio X23"; + case "MT6797X"_fnv1a16: return "Helio X27"; + case "MT6799"_fnv1a16: return "Helio X30"; + + // Helio A series + case "MT6761V/WE"_fnv1a16: return "Helio A20"; + case "MT6761V/WBB"_fnv1a16: + case "MT6761V/WAB"_fnv1a16: return "Helio A22"; + case "MT6762V/WD"_fnv1a16: + case "MT6762V/WB"_fnv1a16: return "Helio A25"; + + // Helio P series + case "MT6755"_fnv1a16: + case "MT6755M"_fnv1a16: return "Helio P10"; + case "MT6755T"_fnv1a16: return "Helio P15"; + case "MT6755S"_fnv1a16: return "Helio P18"; + case "MT6757"_fnv1a16: return "Helio P20"; + case "MT6762"_fnv1a16: return "Helio P22"; + case "MT6763"_fnv1a16: return "Helio P23"; + case "MT6763T"_fnv1a16: return "Helio P23T"; + case "MT6757CD"_fnv1a16: return "Helio P25"; + case "MT6757T"_fnv1a16: return "Helio P25T"; + case "MT6758"_fnv1a16: return "Helio P30"; + case "MT6765"_fnv1a16: return "Helio P35"; + case "MT6771"_fnv1a16: return "Helio P60"; + case "MT6768"_fnv1a16: return "Helio P65"; + case "MT6771V/CT"_fnv1a16: return "Helio P70"; + case "MT6779V/CU"_fnv1a16: return "Helio P90"; + case "MT6779V/CV"_fnv1a16: return "Helio P95"; + + // Helio G series + case "MT6762G"_fnv1a16: return "Helio G25"; + case "MT6765G"_fnv1a16: return "Helio G35"; + case "MT6765V/XAA"_fnv1a16: return "Helio G36"; + case "MT6765V/XBA"_fnv1a16: return "Helio G36"; + case "MT6765H"_fnv1a16: return "Helio G37"; + case "MT6765V"_fnv1a16: return "Helio G50"; + case "MT6769V/CB"_fnv1a16: return "Helio G70"; + + case "MT6769T"_fnv1a16: + case "MT6769V/CT"_fnv1a16: + case "MT6769V/CU"_fnv1a16: return "Helio G80"; + + case "MT6769J"_fnv1a16: return "Helio G81"; + case "MT6769Z"_fnv1a16: return "Helio G85"; + case "MT6769V/CZ"_fnv1a16: return "Helio G85"; + case "MT6769H"_fnv1a16: return "Helio G88"; + case "MT6785V/CC"_fnv1a16: return "Helio G90T"; + case "MT6769G"_fnv1a16: return "Helio G91"; + case "MT6769I"_fnv1a16: return "Helio G92"; + case "MT6785V/CD"_fnv1a16: return "Helio G95"; + case "MT6781"_fnv1a16: return "Helio G96"; + case "MT6781V/CD"_fnv1a16: return "Helio G96"; + case "MT6789H"_fnv1a16: return "Helio G100"; + + case "MT6789"_fnv1a16: + case "MT6789G"_fnv1a16: + case "MT6789U"_fnv1a16: + case "MT6789V/CD"_fnv1a16: + case "MT8781"_fnv1a16: + case "MT8781V/CA"_fnv1a16: + case "MT8781V/NB"_fnv1a16: return "Helio G99"; + + // Dimensity Series + // Dimensity 700 Series + case "MT6833"_fnv1a16: + case "MT6833G"_fnv1a16: + case "MT6833V/ZA"_fnv1a16: + case "MT6833V/NZA"_fnv1a16: return "Dimensity 700"; + + case "MT6853V/ZA"_fnv1a16: + case "MT6853V/NZA"_fnv1a16: return "Dimensity 720"; + + // Dimensity 800 Series + case "MT6873"_fnv1a16: return "Dimensity 800"; + case "MT6853T"_fnv1a16: return "Dimensity 800U"; + case "MT6853V/TNZA"_fnv1a16: return "Dimensity 800U"; + case "MT6875"_fnv1a16: return "Dimensity 820"; + + case "MT6833P"_fnv1a16: + case "MT6833GP"_fnv1a16: + case "MT6833V/PNZA"_fnv1a16: return "Dimensity 810"; + + // Dimensity 900 Series + case "MT6877V/ZA"_fnv1a16: return "Dimensity 900"; + case "MT6855"_fnv1a16: + case "MT6855V/AZA"_fnv1a16: return "Dimensity 930"; + + // case "MT6877"_fnv1a16: + case "MT6877T"_fnv1a16: + case "MT6877V/TZA"_fnv1a16: return "Dimensity 920"; + + // Dimensity 1000 Series + case "MT6883Z/CZA"_fnv1a16: return "Dimensity 1000C"; + case "MT6885Z/CZA"_fnv1a16: return "Dimensity 1000L"; + case "MT6889"_fnv1a16: return "Dimensity 1000"; + case "MT6889Z/CZA"_fnv1a16: return "Dimensity 1000+"; + + case "MT6879"_fnv1a16: + case "MT6879V/ZA"_fnv1a16: + case "MT6879V_T/ZA"_fnv1a16: return "Dimensity 1050"; + + case "MT6877"_fnv1a16: return "Dimensity 1080 / Dimensity 920"; + case "MT6877V/TTZA"_fnv1a16: + case "MT6877V_T/TTZA"_fnv1a16: return "Dimensity 1080"; + + case "MT6891"_fnv1a16: + case "MT6891Z/CZA"_fnv1a16: + case "MT6891Z_Z/CZA"_fnv1a16: + case "MT6891Z_T/CZA"_fnv1a16: return "Dimensity 1100"; + + case "MT6893"_fnv1a16: + case "MT6893Z/CZA"_fnv1a16: + case "MT6893Z_A/CZA"_fnv1a16: return "Dimensity 1200"; + + case "MT6893Z_Z/CZA"_fnv1a16: + case "MT6893Z_T/CZA"_fnv1a16: return "Dimensity 1300"; + + // Dimensity 6000 Series + // note: Dimensity 6020 == Dimensity 700 + // Dimensity 6080 == Dimensity 810 + case "MT6835"_fnv1a16: + case "MT6835V/ZA"_fnv1a16: + case "MT8755V/TZB"_fnv1a16: return "Dimensity 6100+"; + case "MT6835T"_fnv1a16: return "Dimensity 6300"; + + // Dimensity 7000 Series + // note: Dimensity 7020 == Dimensity 930 + // Dimensity 7030 == Dimensity 1050 + // Dimensity 7050 == Dimensity 1080 + // Dimensity 7300 == Dimensity 7300X + case "MT6855V/ATZA"_fnv1a16: return "Dimensity 7025"; + case "MT6886V/TCZA"_fnv1a16: return "Dimensity 7350"; + + case "MT6886"_fnv1a16: + case "MT6886V_A/CZA"_fnv1a16: + case "MT6886V_B/CZA"_fnv1a16: return "Dimensity 7200"; + + case "MT6878"_fnv1a16: + case "MT6878V/ZA"_fnv1a16: + case "MT6878V_A/ZA"_fnv1a16: return "Dimensity 7300"; + + // Dimensity 8000 Series + // note: Dimensity 8020 == Dimensity 1100 + // Dimensity 8050 == Dimensity 1300 + case "MT6895"_fnv1a16: return "Dimensity 8000 / Dimensity 8100"; + case "MT6895Z/CZA"_fnv1a16: return "Dimensity 8000"; + + // case "MT6895"_fnv1a16: + case "MT6895Z/TCZA"_fnv1a16: + case "MT6895Z_A/TCZA"_fnv1a16: + case "MT6895Z_B/TCZA"_fnv1a16: + case "MT6895ZB"_fnv1a16: + case "MT8795"_fnv1a16: + case "MT8795Z/TNZA"_fnv1a16: return "Dimensity 8100"; + + // case "MT6896"_fnv1a16: + case "MT6896Z/CZA"_fnv1a16: + case "MT6896Z_B/CZA"_fnv1a16: return "Dimensity 8200"; + + case "MT6896"_fnv1a16: return "Dimensity 8200 / Dimensity 8250"; + case "MT6896Z_C/CZA"_fnv1a16: return "Dimensity 8250"; + + // case "MT6897"_fnv1a16: + case "MT8792Z/NB"_fnv1a16: return "Dimensity 8300"; + + case "MT6897"_fnv1a16: return "Dimensity 8300 / Dimensity 8350"; + case "MT6897Z_A/ZA"_fnv1a16: return "Dimensity 8350"; + + case "MT6899"_fnv1a16: + case "MT6899Z_A/ZA"_fnv1a16: return "Dimensity 8400"; + + // Dimensity 9000 Series + case "MT6983"_fnv1a16: + case "MT6983Z/CZA"_fnv1a16: + case "MT8798"_fnv1a16: + case "MT8798Z/CNZA"_fnv1a16: return "Dimensity 9000"; + + // case "MT6983"_fnv1a16: + // case "MT8798"_fnv1a16: + case "MT6983W/CZA"_fnv1a16: + case "MT8798Z/TNZA"_fnv1a16: return "Dimensity 9000+"; + + case "MT6985"_fnv1a16: + case "MT6985W/CZA"_fnv1a16: return "Dimensity 9200"; + + // case "MT6985"_fnv1a16: + case "MT6985W/TCZA"_fnv1a16: return "Dimensity 9200+"; + + case "MT6989"_fnv1a16: + case "MT6989W/CZA"_fnv1a16: + case "MT8796"_fnv1a16: + case "MT8796W/CNZA"_fnv1a16: return "Dimensity 9300"; + + // case "MT6989"_fnv1a16: + case "MT6989W/TCZA"_fnv1a16: return "Dimensity 9300+"; + + case "MT6991"_fnv1a16: + case "MT6991Z/CZA"_fnv1a16: + case "MT6991W/CZA"_fnv1a16: return "Dimensity 9400"; + } + + return model_name; +} +#endif // CF_ANDROID + static void trim(char* str) { if (!str) @@ -87,12 +539,44 @@ float cpu_temp() return 0.0f; } +#if CF_ANDROID +MODFUNC(android_cpu_model_name) +{ return get_android_property("ro.soc.model"); } + +MODFUNC(android_cpu_vendor) +{ + if (android_cpu_model_name(nullptr).empty()) + return "MTK"; + + std::string vendor = get_android_property("ro.soc.manufacturer"); + if (vendor.empty()) + vendor = get_android_property("ro.product.product.manufacturer"); + + return vendor; +} +#endif + MODFUNC(cpu_name) { char name[4096]; +#if CF_LINUX if (!read_value("model name", "model name"_len, true, name, sizeof(name))) return UNKNOWN; - +#elif CF_ANDROID + if (!read_value("model name", "model name"_len, true, name, sizeof(name))) + { + const std::string& vendor = android_cpu_vendor(nullptr); + const std::string& model_name = android_cpu_model_name(nullptr); + if (vendor == "QTI" || vendor == "QUALCOMM") + strcpy(name, fmt::format("Qualcomm {} [{}]", detect_qualcomm(model_name), model_name).c_str()); + else if (vendor == "Samsung") + strcpy(name, fmt::format("Samsung {} [{}]", detect_exynos(model_name), model_name).c_str()); + else if (vendor == "MTK") + strcpy(name, fmt::format("Mediatek {} [{}]", detect_mediatek(model_name), model_name).c_str()); + else + strcpy(name, (vendor + " " + model_name).c_str()); + } +#endif // sometimes /proc/cpuinfo at model name // the name will contain the min freq // happens on intel cpus especially @@ -151,3 +635,5 @@ MODFUNC(cpu_freq_bios) return "0"; return fmt::format("{:.2f}", std::stof(read_by_syspath(freq_dir + "/bios_limit")) / 1000000); } + +#endif diff --git a/src/core-modules/linux/system.cc b/src/core-modules/linux/system.cc index c0b6b97b..88dc604b 100644 --- a/src/core-modules/linux/system.cc +++ b/src/core-modules/linux/system.cc @@ -11,15 +11,11 @@ #include "core-modules.hh" #include "util.hpp" -/* The handler that we'll use for our module, Handlers return const std::string (WILL be changed to const char - * pointers). */ MODFUNC(host) { const std::string syspath = "/sys/devices/virtual/dmi/id"; - std::string board_name = "(unknown)"; - std::string board_version = "(unknown)"; - std::string board_vendor = "(unknown)"; + std::string board_name{UNKNOWN}, board_version{UNKNOWN}, board_vendor{UNKNOWN}; if (std::filesystem::exists(syspath + "/board_name")) { @@ -45,7 +41,7 @@ MODFUNC(host) board_version = read_by_syspath(syspath + "/product_version"); } - return board_vendor + ' ' + board_name + ' ' + board_version; + return board_vendor + " " + board_name + " " + board_version; } MODFUNC(host_name) From c6552e9886721c570bce4e5e1c4e653b96d27155 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Wed, 9 Jul 2025 21:58:56 +0200 Subject: [PATCH 081/143] core-modules: add platform.hpp checks --- src/core-modules/android/theme.cc | 4 ++-- src/core-modules/linux/battery.cc | 5 +++++ src/core-modules/linux/cpu.cc | 2 +- src/core-modules/linux/disk.cc | 5 +++++ src/core-modules/linux/gpu.cc | 5 +++++ src/core-modules/linux/os.cc | 5 +++++ src/core-modules/linux/ram.cc | 5 +++++ src/core-modules/linux/system.cc | 2 +- src/core-modules/linux/theme.cc | 1 - src/core-modules/linux/user.cc | 5 +++++ 10 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/core-modules/android/theme.cc b/src/core-modules/android/theme.cc index 3b003ab8..bc9cac80 100644 --- a/src/core-modules/android/theme.cc +++ b/src/core-modules/android/theme.cc @@ -1,5 +1,5 @@ #include "platform.hpp" -#if !CF_ANDROID +#if CF_ANDROID #include "core-modules.hh" #include "cufetch/common.hh" @@ -18,4 +18,4 @@ MODFUNC(theme_gsettings_font) { return MAGIC_LINE; } MODFUNC(theme_gsettings_cursor_name) { return MAGIC_LINE; } MODFUNC(theme_gsettings_cursor_size) { return MAGIC_LINE; } -#endif // !CF_ANDROID +#endif // CF_ANDROID diff --git a/src/core-modules/linux/battery.cc b/src/core-modules/linux/battery.cc index 8d428e33..191140d1 100644 --- a/src/core-modules/linux/battery.cc +++ b/src/core-modules/linux/battery.cc @@ -1,3 +1,6 @@ +#include "platform.hpp" +#if CF_LINUX + #include <unistd.h> #include <string> @@ -69,3 +72,5 @@ double battery_temp() return 0; } + +#endif diff --git a/src/core-modules/linux/cpu.cc b/src/core-modules/linux/cpu.cc index 28f3fdcb..87e8efa4 100644 --- a/src/core-modules/linux/cpu.cc +++ b/src/core-modules/linux/cpu.cc @@ -1,9 +1,9 @@ -#include <cstring> #include "platform.hpp" #if CF_ANDROID || CF_LINUX #include <unistd.h> #include <string> +#include <cstring> #include "cufetch/common.hh" #include "core-modules.hh" diff --git a/src/core-modules/linux/disk.cc b/src/core-modules/linux/disk.cc index f9896d5c..1dac351b 100644 --- a/src/core-modules/linux/disk.cc +++ b/src/core-modules/linux/disk.cc @@ -1,3 +1,6 @@ +#include "platform.hpp" +#if CF_LINUX || CF_ANDROID + #include <mntent.h> #include <sys/stat.h> #include <sys/statvfs.h> @@ -258,3 +261,5 @@ double disk_used(const callbackInfo_t *callbackInfo) { return disk_total(callbackInfo) - disk_free(callbackInfo); } + +#endif diff --git a/src/core-modules/linux/gpu.cc b/src/core-modules/linux/gpu.cc index 25a36e74..4f816abf 100644 --- a/src/core-modules/linux/gpu.cc +++ b/src/core-modules/linux/gpu.cc @@ -1,3 +1,6 @@ +#include "platform.hpp" +#if CF_LINUX + #include <cstdint> #include <filesystem> #include <string> @@ -61,3 +64,5 @@ MODFUNC(gpu_vendor) const std::string& sys_path = get_gpu_syspath(id); return get_vendor(read_by_syspath(sys_path + "/device/vendor")); } + +#endif diff --git a/src/core-modules/linux/os.cc b/src/core-modules/linux/os.cc index 68bd60e8..41596060 100644 --- a/src/core-modules/linux/os.cc +++ b/src/core-modules/linux/os.cc @@ -1,3 +1,6 @@ +#include "platform.hpp" +#if CF_LINUX + #include <cassert> #include <cstdio> #include <cstring> @@ -150,3 +153,5 @@ MODFUNC(os_initsys_version) return os_initsys_version; } + +#endif diff --git a/src/core-modules/linux/ram.cc b/src/core-modules/linux/ram.cc index 0755acf2..292196f7 100644 --- a/src/core-modules/linux/ram.cc +++ b/src/core-modules/linux/ram.cc @@ -1,3 +1,6 @@ +#include "platform.hpp" +#if CF_LINUX || CF_ANDROID + #include <cstdio> #include <string> #include <string_view> @@ -56,3 +59,5 @@ double swap_total() double swap_used() { return swap_total() - swap_free(); } + +#endif diff --git a/src/core-modules/linux/system.cc b/src/core-modules/linux/system.cc index 88dc604b..27368f29 100644 --- a/src/core-modules/linux/system.cc +++ b/src/core-modules/linux/system.cc @@ -1,6 +1,6 @@ #include "platform.hpp" - #if CF_LINUX + #include <sys/utsname.h> #include <filesystem> diff --git a/src/core-modules/linux/theme.cc b/src/core-modules/linux/theme.cc index 4827e263..9dea17b9 100644 --- a/src/core-modules/linux/theme.cc +++ b/src/core-modules/linux/theme.cc @@ -1,4 +1,3 @@ -#include "cufetch/cufetch.hh" #include "platform.hpp" #if CF_LINUX diff --git a/src/core-modules/linux/user.cc b/src/core-modules/linux/user.cc index 013bad34..452769de 100644 --- a/src/core-modules/linux/user.cc +++ b/src/core-modules/linux/user.cc @@ -1,3 +1,6 @@ +#include "platform.hpp" +#if CF_LINUX + #include <unistd.h> #include <fstream> @@ -461,3 +464,5 @@ MODFUNC(user_de_version) } } } + +#endif From bfd3ab00b94d799f87b2a2d11247686a5434cafa Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Wed, 9 Jul 2025 23:00:48 +0200 Subject: [PATCH 082/143] core-modules: add {ram,swap,battery} auto formats --- src/core-modules/core-modules.cc | 48 ++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/src/core-modules/core-modules.cc b/src/core-modules/core-modules.cc index 930d507c..a7c6f3fb 100644 --- a/src/core-modules/core-modules.cc +++ b/src/core-modules/core-modules.cc @@ -112,6 +112,48 @@ MODFUNC(disk_fmt) return result; } +MODFUNC(ram_fmt) +{ + const callbackInfo_t *callback = callbackInfo; + const double used = ram_used(); + const double total = ram_total(); + const std::string& perc = + get_and_color_percentage(used, total, callback->parse_args, false); + + // clang-format off + return fmt::format("{} / {} {}", + amount(used, callback->moduleArgs), + amount(total, callback->moduleArgs), + parse("${0}(" + perc + ")", callback->parse_args)) + ; + // clang-format on +} + +MODFUNC(swap_fmt) +{ + const callbackInfo_t *callback = callbackInfo; + const double used = swap_used(); + const double total = swap_total(); + if (used < 1) + return "Disabled"; + + const std::string& perc = + get_and_color_percentage(used, total, callback->parse_args, false); + + // clang-format off + return fmt::format("{} / {} {}", + amount(used, callback->moduleArgs), + amount(total, callback->moduleArgs), + parse("${0}(" + perc + ")", callback->parse_args)) + ; + // clang-format on +} + +MODFUNC(battery_fmt) +{ + return fmt::format("{} [{}]", get_and_color_percentage(std::stod(battery_perc(callbackInfo)), 100, callbackInfo->parse_args, true), battery_status(callbackInfo)); +} + void core_plugins_start(const Config& config) { // ------------ INIT STUFF ------------ @@ -300,7 +342,7 @@ void core_plugins_start(const Config& config) std::move(ram_free_module), std::move(ram_used_module), std::move(ram_total_module) - }, NULL}; + }, ram_fmt}; cfRegisterModule(ram_module); // $<swap> @@ -314,7 +356,7 @@ void core_plugins_start(const Config& config) std::move(swap_free_module), std::move(swap_used_module), std::move(swap_total_module) - }, NULL}; + }, swap_fmt}; cfRegisterModule(swap_module); // $<disk> @@ -365,7 +407,7 @@ void core_plugins_start(const Config& config) std::move(battery_vendor_module), std::move(battery_perc_module), std::move(battery_temp_module), - }, NULL}; + }, battery_fmt}; cfRegisterModule(battery_module); // $<theme> From be2f8475685f0ac82ee21fa8a19f1e3912e7f27d Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Wed, 9 Jul 2025 23:02:11 +0200 Subject: [PATCH 083/143] config: update layout 100% of commits until this will be broken --- include/config.hpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/config.hpp b/include/config.hpp index 2a4e3cbb..03238ed1 100644 --- a/include/config.hpp +++ b/include/config.hpp @@ -195,12 +195,12 @@ layout = [ "${auto}Uptime: $<os.uptime>",)#" #if !CF_ANDROID R"#( - "${auto}Theme: $<theme-gtk-all.name>", - "${auto}Icons: $<theme-gtk-all.icons>", - "${auto}Font: $<theme-gtk-all.font>", + "${auto}Theme: $<theme.gtk.all.name>", + "${auto}Icons: $<theme.gtk.all.icons>", + "${auto}Font: $<theme.gtk.all.font>", "${auto}Cursor: $<theme.cursor>", - "${auto}WM: $<user.wm_name>", - "${auto}DE: $<user.de_name>",)#" + "${auto}WM: $<user.wm.name>", + "${auto}DE: $<user.de.name>",)#" #endif R"#( "$<auto.disk>", From c7af2474d72d6aca61db5dd93afbdb148def40cd Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Wed, 9 Jul 2025 23:46:38 +0200 Subject: [PATCH 084/143] makefile: fix linking --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 574db160..d69e8815 100644 --- a/Makefile +++ b/Makefile @@ -51,7 +51,7 @@ SRC_CC = $(wildcard src/core-modules/*.cc src/core-modules/linux/*.cc) OBJ_CPP = $(SRC_CPP:.cpp=.o) OBJ_CC = $(SRC_CC:.cc=.o) OBJ = $(OBJ_CPP) $(OBJ_CC) -LDFLAGS += -Wl,-Bstatic $(BUILDDIR)/libfmt.a -Wl,-Bdynamic -lcufetch -ldl +LDFLAGS += -L$(BUILDDIR) -Wl,-Bstatic $(BUILDDIR)/libfmt.a -Wl,-Bdynamic -lcufetch -ldl CXXFLAGS ?= -mtune=generic -march=native CXXFLAGS += -fvisibility-inlines-hidden -fvisibility=hidden -Iinclude -Iinclude/cufetch -std=c++20 $(VARS) -DVERSION=\"$(VERSION)\" -DLOCALEDIR=\"$(LOCALEDIR)\" -DICONPREFIX=\"$(ICONPREFIX)\" From 604e1bd2108c1f6a9b4bd6e72cab831e895c96a0 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Thu, 10 Jul 2025 00:04:43 +0200 Subject: [PATCH 085/143] workflow: add 'plugins' branch --- .github/workflows/makefile.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/makefile.yml b/.github/workflows/makefile.yml index 197eb457..e0817281 100644 --- a/.github/workflows/makefile.yml +++ b/.github/workflows/makefile.yml @@ -2,9 +2,9 @@ name: Makefile CI (Test customfetch) on: push: - branches: [ "main" ] + branches: [ "main", "plugins" ] pull_request: - branches: [ "main" ] + branches: [ "main", "plugins" ] jobs: build-deb: From 26539ea4c2601ca3b1e89a71b174aa8c90c1defa Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Thu, 10 Jul 2025 00:10:36 +0200 Subject: [PATCH 086/143] build: workflow: fix some things please don't check the actions tab........ it's 2am trying to fix ts, fuck me --- .github/workflows/makefile.yml | 42 ++++++++++++++--------------- Makefile | 14 +++++++--- include/fmt | 1 + include/query.hpp | 2 ++ include/toml++ | 1 + libcufetch/Makefile | 46 ++++++++++++++++++++++---------- libcufetch/util.cc | 1 + src/core-modules/core-modules.cc | 11 +++++--- src/display.cpp | 2 +- src/libs/toml++/Makefile | 2 +- src/query/macos/disk.cpp | 2 +- src/query/macos/gpu.cpp | 2 +- src/query/macos/theme.cpp | 4 +-- 13 files changed, 82 insertions(+), 48 deletions(-) create mode 120000 include/fmt create mode 120000 include/toml++ create mode 120000 libcufetch/util.cc diff --git a/.github/workflows/makefile.yml b/.github/workflows/makefile.yml index e0817281..8451fe60 100644 --- a/.github/workflows/makefile.yml +++ b/.github/workflows/makefile.yml @@ -284,24 +284,24 @@ jobs: name: customfetch-macos path: ./build/debug/customfetch - test-suitcase: - runs-on: ubuntu-22.04 - permissions: - contents: read - - steps: - - uses: actions/checkout@v4 - - - name: Install Packages - run: | - sudo apt-get purge firefox # Slows down the installation alot, fuck snap - sudo apt-get update && sudo apt upgrade -y - sudo apt-get install neofetch tree build-essential g++-11 libwayland-dev gettext libgtk-3-dev pkg-config libdconf-dev libglib2.0-dev libgtkmm-3.0-dev libarchive-tools -y - - - name: Clean - run: make distclean - - - name: Compile and install - run: | - cd tests && make - find . -type f -executable -exec {} \; + # test-suitcase: + # runs-on: ubuntu-22.04 + # permissions: + # contents: read + # + # steps: + # - uses: actions/checkout@v4 + # + # - name: Install Packages + # run: | + # sudo apt-get purge firefox # Slows down the installation alot, fuck snap + # sudo apt-get update && sudo apt upgrade -y + # sudo apt-get install neofetch tree build-essential g++-11 libwayland-dev gettext libgtk-3-dev pkg-config libdconf-dev libglib2.0-dev libgtkmm-3.0-dev libarchive-tools -y + # + # - name: Clean + # run: make distclean + # + # - name: Compile and install + # run: | + # cd tests && make + # find . -type f -executable -exec {} \; diff --git a/Makefile b/Makefile index d69e8815..43bbc884 100644 --- a/Makefile +++ b/Makefile @@ -42,22 +42,28 @@ ifeq ($(USE_DCONF), 1) endif endif +# is macos? +ifeq ($(shell uname -s),Darwin) + SRC_CC := + SRC_CPP := $(wildcard src/*.cpp src/query/macos/*.cpp) +endif + NAME = customfetch TARGET ?= $(NAME) OLDVERSION = 0.10.2 VERSION = 1.0.0 -SRC_CPP = $(wildcard src/*.cpp src/core-modules/linux/utils/*.cpp) -SRC_CC = $(wildcard src/core-modules/*.cc src/core-modules/linux/*.cc) +SRC_CPP ?= $(wildcard src/*.cpp src/core-modules/linux/utils/*.cpp) +SRC_CC ?= $(wildcard src/core-modules/*.cc src/core-modules/linux/*.cc src/core-modules/android/*.cc) OBJ_CPP = $(SRC_CPP:.cpp=.o) OBJ_CC = $(SRC_CC:.cc=.o) OBJ = $(OBJ_CPP) $(OBJ_CC) -LDFLAGS += -L$(BUILDDIR) -Wl,-Bstatic $(BUILDDIR)/libfmt.a -Wl,-Bdynamic -lcufetch -ldl +LDFLAGS += -Wl,-rpath,$(BUILDDIR) -L$(BUILDDIR) $(BUILDDIR)/libfmt.a -lcufetch -ldl CXXFLAGS ?= -mtune=generic -march=native CXXFLAGS += -fvisibility-inlines-hidden -fvisibility=hidden -Iinclude -Iinclude/cufetch -std=c++20 $(VARS) -DVERSION=\"$(VERSION)\" -DLOCALEDIR=\"$(LOCALEDIR)\" -DICONPREFIX=\"$(ICONPREFIX)\" all: genver fmt toml json libcufetch $(TARGET) -libcufetch: +libcufetch: fmt toml ifeq ($(wildcard $(BUILDDIR)/libcufetch.so),) make -C libcufetch BUILDDIR=$(BUILDDIR) GUI_APP=$(GUI_APP) endif diff --git a/include/fmt b/include/fmt new file mode 120000 index 00000000..49d413e3 --- /dev/null +++ b/include/fmt @@ -0,0 +1 @@ +cufetch/fmt \ No newline at end of file diff --git a/include/query.hpp b/include/query.hpp index d87d4d85..e9dd59dd 100644 --- a/include/query.hpp +++ b/include/query.hpp @@ -32,6 +32,8 @@ #include <variant> #include <vector> +#include "cufetch/cufetch.hh" +#include "platform.hpp" #include "parse.hpp" extern "C" { diff --git a/include/toml++ b/include/toml++ new file mode 120000 index 00000000..c7e6a8cb --- /dev/null +++ b/include/toml++ @@ -0,0 +1 @@ +cufetch/toml++ \ No newline at end of file diff --git a/libcufetch/Makefile b/libcufetch/Makefile index 664f2429..9be2e9f1 100644 --- a/libcufetch/Makefile +++ b/libcufetch/Makefile @@ -1,25 +1,43 @@ +UNAME_S := $(shell uname -s) + +# is macos? +ifeq ($(UNAME_S),Darwin) + LIBNAME := libcufetch.dylib + INSTALL_NAME := -Wl,-install_name,@rpath/$(LIBNAME) + SHARED_FLAG := -dynamiclib + SONAME_FLAGS := +else + LIBNAME := libcufetch.so.1.0.0 + INSTALL_NAME := -Wl,-soname,libcufetch.so.1 + SHARED_FLAG := -shared + SONAME_FLAGS := -Wl,--export-dynamic +endif + CXX ?= g++ GUI_APP ?= 0 SRC = $(wildcard *.cc) -OBJ = $(SRC:.cc=.o) +OBJ = $(SRC:.cc=.o) ../$(BUILDDIR)/toml.o FMT_STATIC = ../$(BUILDDIR)/libfmt.a -CXX_INCLUDES = -I../include -CXX_FLAGS = -ggdb3 -shared -fPIC -DGUI_APP=$(GUI_APP) +CXXFLAGS += -ggdb3 -I../include -fPIC -DGUI_APP=$(GUI_APP) +OUTPUT := ../$(BUILDDIR)/$(LIBNAME) -all: libcufetch +all: $(OUTPUT) + @if [ "$(UNAME_S)" = "Linux" ]; then \ + ln -sf libcufetch.so.1.0.0 ../build/debug/libcufetch.so.1; \ + ln -sf libcufetch.so.1.0.0 ../build/debug/libcufetch.so; \ + elif [ "$(UNAME_S)" = "Darwin" ]; then \ + ln -sf libcufetch.dylib ../build/debug/libcufetch.1.dylib; \ + ln -sf libcufetch.dylib ../build/debug/libcufetch.1.0.0.dylib; \ + fi %.o: %.cc - $(CXX) $(CXX_INCLUDES) $(CXX_FLAGS) -c -o $@ $< + $(CXX) $(CXXFLAGS) -c -o $@ $< -libcufetch: $(OBJ) $(FMT_STATIC) - $(CXX) $(CXX_FLAGS) $(OBJ) $(CXX_INCLUDES) \ - -Wl,-Bstatic $(FMT_STATIC) -Wl,-Bdynamic \ - -Wl,--export-dynamic \ - -Wl,-soname,libcufetch.so.1 \ - -o libcufetch.so.1.0.0 - ln -sf libcufetch.so.1.0.0 libcufetch.so.1 - ln -sf libcufetch.so.1.0.0 libcufetch.so - mv -f libcufetch.so* ../$(BUILDDIR)/ +$(OUTPUT): $(OBJ) $(FMT_STATIC) + $(CXX) $(SHARED_FLAG) $(CXXFLAGS) $(OBJ) \ + $(FMT_STATIC) \ + $(SONAME_FLAGS) $(INSTALL_NAME) \ + -o $@ clean: rm -f *.o *.so *.a ../$(BUILDDIR)/libcufetch.so diff --git a/libcufetch/util.cc b/libcufetch/util.cc new file mode 120000 index 00000000..0b83e603 --- /dev/null +++ b/libcufetch/util.cc @@ -0,0 +1 @@ +../src/util.cpp \ No newline at end of file diff --git a/src/core-modules/core-modules.cc b/src/core-modules/core-modules.cc index a7c6f3fb..68233097 100644 --- a/src/core-modules/core-modules.cc +++ b/src/core-modules/core-modules.cc @@ -1,5 +1,6 @@ +#include "platform.hpp" + #include <dlfcn.h> -#include <mntent.h> #include <unistd.h> #include <algorithm> @@ -15,8 +16,10 @@ #include "fmt/format.h" #include "util.hpp" -#if CF_LINUX -# include "linux/utils/packages.hpp" +#include "linux/utils/packages.hpp" + +#if !CF_MACOS +# include <mntent.h> #endif using unused = const callbackInfo_t*; @@ -179,10 +182,12 @@ void core_plugins_start(const Config& config) is_tty = true; term_name = ttyname(STDIN_FILENO); } +#if !CF_MACOS os_release = fopen("/etc/os-release", "r"); cpuinfo = fopen("/proc/cpuinfo", "r"); meminfo = fopen("/proc/meminfo", "r"); mountsFile = setmntent("/proc/mounts", "r"); +#endif #if CF_ANDROID is_tty = true; diff --git a/src/display.cpp b/src/display.cpp index 7792924f..a1057295 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -418,7 +418,7 @@ std::vector<std::string> Display::render(const Config& config, const bool alread for (; i < asciiArt.size(); ++i) { - std::string line{" ", config.logo_padding_left + asciiArt.at(i).length()}; + std::string line(config.logo_padding_left + asciiArt.at(i).length(), ' '); line += asciiArt.at(i); layout.push_back(line); diff --git a/src/libs/toml++/Makefile b/src/libs/toml++/Makefile index 148dc641..49c6da04 100644 --- a/src/libs/toml++/Makefile +++ b/src/libs/toml++/Makefile @@ -1,7 +1,7 @@ CXX ?= g++ SRC = toml.cpp TARGET = toml.o -CXXFLAGS = -I../../../include/cufetch -fPIE -std=c++20 +CXXFLAGS = -I../../../include/cufetch -fPIC -std=c++20 all: $(TARGET) diff --git a/src/query/macos/disk.cpp b/src/query/macos/disk.cpp index 3a6dcec8..a41e7348 100644 --- a/src/query/macos/disk.cpp +++ b/src/query/macos/disk.cpp @@ -66,7 +66,7 @@ static int get_disk_type(const int flags) return type; } -Disk::Disk(const std::string& path, systemInfo_t& queried_paths, parse_args_t& parse_args, const bool auto_module) +Disk::Disk(const std::string& path, modulesInfo_t& queried_paths, parse_args_t& parse_args, const bool auto_module) { if (queried_paths.find(path) != queried_paths.end() && !is_live_mode) { diff --git a/src/query/macos/gpu.cpp b/src/query/macos/gpu.cpp index 87344fa5..e9bfffd2 100644 --- a/src/query/macos/gpu.cpp +++ b/src/query/macos/gpu.cpp @@ -30,7 +30,7 @@ using namespace Query; -GPU::GPU(const std::string& id, systemInfo_t& queried_gpus) {} +GPU::GPU(const std::string& id, modulesInfo_t& queried_gpus) {} // clang-format off std::string& GPU::name() noexcept diff --git a/src/query/macos/theme.cpp b/src/query/macos/theme.cpp index 534bed5e..9f2b07cf 100644 --- a/src/query/macos/theme.cpp +++ b/src/query/macos/theme.cpp @@ -31,7 +31,7 @@ using namespace Query; -Theme::Theme(const std::uint8_t ver, systemInfo_t& queried_themes, const std::string& theme_name_version, +Theme::Theme(const std::uint8_t ver, modulesInfo_t& queried_themes, const std::string& theme_name_version, const Config& config, const bool gsettings_only) : m_queried_themes(queried_themes) { @@ -39,7 +39,7 @@ Theme::Theme(const std::uint8_t ver, systemInfo_t& queried_themes, const std::st m_theme_infos.gtk_icon_theme = MAGIC_LINE; } -Theme::Theme(systemInfo_t& queried_themes, const Config& config, const bool gsettings_only) +Theme::Theme(modulesInfo_t& queried_themes, const Config& config, const bool gsettings_only) : m_queried_themes(queried_themes) { m_theme_infos.cursor = m_theme_infos.gtk_font = m_theme_infos.cursor_size = m_theme_infos.gtk_theme_name = From 44361a1a2c607c2b5e303362205b797be04cdbb7 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Thu, 10 Jul 2025 15:52:50 +0200 Subject: [PATCH 087/143] misc: fix some things --- .github/workflows/makefile.yml | 70 +++++++++++++++++----------------- include/config.hpp | 4 +- libcufetch/Makefile | 8 ++-- src/display.cpp | 2 +- src/main.cpp | 5 ++- 5 files changed, 45 insertions(+), 44 deletions(-) diff --git a/.github/workflows/makefile.yml b/.github/workflows/makefile.yml index 8451fe60..351c778a 100644 --- a/.github/workflows/makefile.yml +++ b/.github/workflows/makefile.yml @@ -248,41 +248,41 @@ jobs: - name: Test customfetch run: ./build/debug/customfetch --wrap-lines - build-macos: - runs-on: macos-latest - permissions: - contents: read - - steps: - - uses: actions/checkout@v4 - - - name: Install the packages - run: HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 brew install --overwrite fastfetch neofetch tree llvm@19 - - - name: uname -a && clang++ --version - run: uname -a && echo "\n" && $(brew --prefix llvm@19)/bin/clang++ --version - - - name: Clean - run: make distclean - - - name: Compile - run: make DEBUG=1 GUI_APP=0 CXX=$(brew --prefix llvm@19)/bin/clang++ - - - name: Test neofetch - run: neofetch - - - name: Test fastfetch - run: fastfetch - - - name: Test customfetch - run: ./build/debug/customfetch -D assets - - - name: Upload to github artifacts - uses: actions/upload-artifact@v4 - with: - if-no-files-found: error - name: customfetch-macos - path: ./build/debug/customfetch + # build-macos: + # runs-on: macos-latest + # permissions: + # contents: read + # + # steps: + # - uses: actions/checkout@v4 + # + # - name: Install the packages + # run: HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 brew install --overwrite fastfetch neofetch tree llvm@19 + # + # - name: uname -a && clang++ --version + # run: uname -a && echo "\n" && $(brew --prefix llvm@19)/bin/clang++ --version + # + # - name: Clean + # run: make distclean + # + # - name: Compile + # run: make DEBUG=1 GUI_APP=0 CXX=$(brew --prefix llvm@19)/bin/clang++ + # + # - name: Test neofetch + # run: neofetch + # + # - name: Test fastfetch + # run: fastfetch + # + # - name: Test customfetch + # run: ./build/debug/customfetch -D assets + # + # - name: Upload to github artifacts + # uses: actions/upload-artifact@v4 + # with: + # if-no-files-found: error + # name: customfetch-macos + # path: ./build/debug/customfetch # test-suitcase: # runs-on: ubuntu-22.04 diff --git a/include/config.hpp b/include/config.hpp index 03238ed1..8f81eeb9 100644 --- a/include/config.hpp +++ b/include/config.hpp @@ -163,12 +163,12 @@ class Config : public ConfigBase o.value_type = BOOL; o.bool_value = value; } - else if constexpr (std::is_same_v<T, std::string>) + else if constexpr (std::is_convertible_v<T, std::string>) { o.value_type = STR; o.string_value = value; } - else if constexpr (std::is_same_v<T, int> || std::is_same_v<T, std::uint16_t>) + else if constexpr (std::is_convertible_v<T, int>) { o.value_type = INT; o.int_value = value; diff --git a/libcufetch/Makefile b/libcufetch/Makefile index 9be2e9f1..2a59630c 100644 --- a/libcufetch/Makefile +++ b/libcufetch/Makefile @@ -23,11 +23,11 @@ OUTPUT := ../$(BUILDDIR)/$(LIBNAME) all: $(OUTPUT) @if [ "$(UNAME_S)" = "Linux" ]; then \ - ln -sf libcufetch.so.1.0.0 ../build/debug/libcufetch.so.1; \ - ln -sf libcufetch.so.1.0.0 ../build/debug/libcufetch.so; \ + ln -sf libcufetch.so.1.0.0 ../$(BUILDDIR)/libcufetch.so.1; \ + ln -sf libcufetch.so.1.0.0 ../$(BUILDDIR)/libcufetch.so; \ elif [ "$(UNAME_S)" = "Darwin" ]; then \ - ln -sf libcufetch.dylib ../build/debug/libcufetch.1.dylib; \ - ln -sf libcufetch.dylib ../build/debug/libcufetch.1.0.0.dylib; \ + ln -sf libcufetch.dylib ../$(BUILDDIR)/libcufetch.1.dylib; \ + ln -sf libcufetch.dylib ../$(BUILDDIR)/libcufetch.1.0.0.dylib; \ fi %.o: %.cc diff --git a/src/display.cpp b/src/display.cpp index a1057295..85e7f1a6 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -418,7 +418,7 @@ std::vector<std::string> Display::render(const Config& config, const bool alread for (; i < asciiArt.size(); ++i) { - std::string line(config.logo_padding_left + asciiArt.at(i).length(), ' '); + std::string line(config.logo_padding_left, ' '); line += asciiArt.at(i); layout.push_back(line); diff --git a/src/main.cpp b/src/main.cpp index b6789850..5fc62856 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -96,7 +96,7 @@ static void version() static void help(bool invalid_opt = false) { constexpr std::string_view help( - R"(Usage: customfetch [OPTIONS]... + R"(Usage: customfetch [OPTIONS]... A command-line, GUI, and Android widget system information tool (like neofetch) focused on customizability and performance. NOTE: Boolean flags [<BOOL>] accept: "true", 1, "enable", or empty. Any other value is treated as false. @@ -113,7 +113,7 @@ LOGO OPTIONS: -n, --no-logo Disable logo display. -L, --logo-only Print only the logo (skip layout completely). -s, --source-path <PATH> Path to custom ASCII art/image file. - + -a, --ascii-logo-type <TYPE> Type of ASCII art (typically "small", "old", or empty for default). Example: "-d arch -a older" looks for "arch_older.txt". @@ -130,6 +130,7 @@ LAYOUT & FORMATTING: Example: `-m "${auto}OS: $<os.name>" -m "${auto}CPU: $<cpu>"`. -N, --no-color Disable all colors (useful for pipes/scripts). + --layout-padding-top <NUM> Layout padding from top (default: 0). --wrap-lines=[<BOOL>] Enable terminal line wrapping (default: false). --title-sep <STRING> String to use for $<title.sep> (default: "-"). --sep-reset <STRING> String that resets color (default: ":"). From 907d56737ce92a15e7e6430fb732f4136bb414c9 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Sat, 12 Jul 2025 16:21:16 +0200 Subject: [PATCH 088/143] misc: fix some things --- Makefile | 2 +- src/display.cpp | 1 + src/gui.cpp | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 43bbc884..a37b19a0 100644 --- a/Makefile +++ b/Makefile @@ -57,7 +57,7 @@ SRC_CC ?= $(wildcard src/core-modules/*.cc src/core-modules/linux/*.cc src/cor OBJ_CPP = $(SRC_CPP:.cpp=.o) OBJ_CC = $(SRC_CC:.cc=.o) OBJ = $(OBJ_CPP) $(OBJ_CC) -LDFLAGS += -Wl,-rpath,$(BUILDDIR) -L$(BUILDDIR) $(BUILDDIR)/libfmt.a -lcufetch -ldl +LDFLAGS += -L$(BUILDDIR) $(BUILDDIR)/libfmt.a -lcufetch -ldl CXXFLAGS ?= -mtune=generic -march=native CXXFLAGS += -fvisibility-inlines-hidden -fvisibility=hidden -Iinclude -Iinclude/cufetch -std=c++20 $(VARS) -DVERSION=\"$(VERSION)\" -DLOCALEDIR=\"$(LOCALEDIR)\" -DICONPREFIX=\"$(ICONPREFIX)\" diff --git a/src/display.cpp b/src/display.cpp index 85e7f1a6..ba20311e 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -129,6 +129,7 @@ static std::vector<std::string> render_with_image(const moduleMap_t& modulesInfo { layout.erase(layout.begin() + i); layout.insert(layout.begin() + i, tmp_layout.begin(), tmp_layout.end()); + i += tmp_layout.size() - 1; tmp_layout.clear(); } } diff --git a/src/gui.cpp b/src/gui.cpp index 0a04b3ab..6c263540 100644 --- a/src/gui.cpp +++ b/src/gui.cpp @@ -109,6 +109,7 @@ static std::vector<std::string> render_with_image(const Config& config) { layout.erase(layout.begin() + i); layout.insert(layout.begin() + i, tmp_layout.begin(), tmp_layout.end()); + i += tmp_layout.size() - 1; tmp_layout.clear(); } } From 8cf19c2b7db3f716c67b8e3192ca10edf0d6e8ae Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Sat, 12 Jul 2025 20:39:25 +0200 Subject: [PATCH 089/143] core-modules: android: add battery module support (final one) --- src/core-modules/android/battery.cc | 119 ++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 src/core-modules/android/battery.cc diff --git a/src/core-modules/android/battery.cc b/src/core-modules/android/battery.cc new file mode 100644 index 00000000..e03259d5 --- /dev/null +++ b/src/core-modules/android/battery.cc @@ -0,0 +1,119 @@ +#include "platform.hpp" +#if CF_ANDROID + +#include <string> +#include <string_view> +#include <vector> + +#include "cufetch/fmt/format.h" +#include "core-modules.hh" +#include "switch_fnv1a.hpp" +#include "cufetch/common.hh" +#include "json.h" +#include "util.hpp" + +static json::jobject doc; +static std::vector<std::string> dumpsys; + +static bool assert_doc() +{ + if (doc.size() <= 0) + { + std::string result; + if (!read_exec({ "/data/data/com.termux/files/usr/libexec/termux-api", "BatteryStatus" }, result)) + return false; + if (!json::jobject::tryparse(result.c_str(), doc)) + return false; + } + return true; +} + +static bool assert_dumpsys() +{ + if (dumpsys.size() <= 0) + { + std::string result; + if (!read_exec({ "/system/bin/dumpsys", "battery" }, result)) + return false; + dumpsys = split(result, '\n'); + if (dumpsys[0] != "Current Battery Service state:") + return false; + } + return true; +} + +static std::string read_value_dumpsys(const std::string_view name, const bool is_status = false) +{ + if (!assert_dumpsys()) + return MAGIC_LINE; + + for (size_t i = 1; i < dumpsys.size(); ++i) + { + const size_t pos = dumpsys.at(i).rfind(':'); + const std::string& key = dumpsys.at(i).substr(2, pos); + const std::string& value = dumpsys.at(i).substr(pos + 2); + + if (is_status) + { + if (key.find("powered") != key.npos && value == "true") + return key; + } + + else if (key == name) + return value; + } + + return MAGIC_LINE; +} + +MODFUNC(battery_modelname) +{ return MAGIC_LINE; } + +MODFUNC(battery_vendor) +{ return MAGIC_LINE; } + +MODFUNC(battery_capacity_level) +{ return MAGIC_LINE; } + +MODFUNC(battery_status) +{ + if (!assert_doc()) + return read_value_dumpsys("powered", true); + + switch (fnv1a16::hash(doc["plugged"].as_string())) + { + case "PLUGGED_AC"_fnv1a16: return "AC Connected, " + str_tolower(doc["status"].as_string()); + case "PLUGGED_USB"_fnv1a16: return "USB Connected, " + str_tolower(doc["status"].as_string()); + case "PLUGGED_WIRELESS"_fnv1a16: return "Wireless Connected, "+ str_tolower(doc["status"].as_string()); + default: return "Discharging"; + } +} + +MODFUNC(battery_technology) +{ + if (!assert_doc()) + return read_value_dumpsys("technology"); + return MAGIC_LINE; +} + +MODFUNC(battery_perc) +{ + if (!assert_doc()) + { + double level = std::stod(read_value_dumpsys("level")); + double scale = std::stod(read_value_dumpsys("scale")); + if (level > 0 && scale > 0) + return fmt::to_string(level * 100 / scale); + } + + return doc["percentage"]; +} + +double battery_temp() +{ + if (!assert_doc()) + return std::stod(read_value_dumpsys("temperature")) / 10; + return doc["temperature"]; +} + +#endif From 0749c1d5276bcaee7d34ddfbb9d77dbcd97eaf50 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Sat, 12 Jul 2025 22:33:50 +0200 Subject: [PATCH 090/143] core-modules: macos: init some modules support --- include/core-modules.hh | 8 +- src/core-modules/android/battery.cc | 10 ++- src/core-modules/core-modules.cc | 4 - src/core-modules/macos/cpu.cc | 72 ++++++++++++++++ src/core-modules/macos/os.cc | 125 ++++++++++++++++++++++++++++ 5 files changed, 205 insertions(+), 14 deletions(-) create mode 100644 src/core-modules/macos/cpu.cc create mode 100644 src/core-modules/macos/os.cc diff --git a/include/core-modules.hh b/include/core-modules.hh index b34d6988..875a4d44 100644 --- a/include/core-modules.hh +++ b/include/core-modules.hh @@ -3,7 +3,6 @@ #include <pwd.h> #include <sys/utsname.h> -#include "platform.hpp" #include "cufetch/cufetch.hh" #include "config.hpp" @@ -17,6 +16,7 @@ MODFUNC(host_version); MODFUNC(host_vendor); // os.cc +inline utsname g_uname_infos; inline std::FILE* os_release; MODFUNC(os_name); MODFUNC(os_pretty_name); @@ -43,6 +43,7 @@ MODFUNC(android_cpu_vendor); MODFUNC(android_cpu_model_name); // user.cc +inline struct passwd* g_pwd; inline bool is_tty = false; inline std::string term_pid, term_name, wm_name, de_name, wm_path_exec; std::string get_terminal_name(); @@ -114,10 +115,5 @@ MODFUNC(theme_gsettings_font); MODFUNC(theme_gsettings_cursor_name); MODFUNC(theme_gsettings_cursor_size); -#if CF_LINUX -inline struct passwd* g_pwd; -inline utsname g_uname_infos; -#endif - void core_plugins_start(const Config& config); void core_plugins_finish(); diff --git a/src/core-modules/android/battery.cc b/src/core-modules/android/battery.cc index e03259d5..788e1ac6 100644 --- a/src/core-modules/android/battery.cc +++ b/src/core-modules/android/battery.cc @@ -80,12 +80,14 @@ MODFUNC(battery_status) if (!assert_doc()) return read_value_dumpsys("powered", true); + std::string charge_status{ str_tolower(doc["status"].as_string()) }; + charge_status.at(0) = toupper(charge_status.at(0)); switch (fnv1a16::hash(doc["plugged"].as_string())) { - case "PLUGGED_AC"_fnv1a16: return "AC Connected, " + str_tolower(doc["status"].as_string()); - case "PLUGGED_USB"_fnv1a16: return "USB Connected, " + str_tolower(doc["status"].as_string()); - case "PLUGGED_WIRELESS"_fnv1a16: return "Wireless Connected, "+ str_tolower(doc["status"].as_string()); - default: return "Discharging"; + case "PLUGGED_AC"_fnv1a16: return "AC Connected, " + charge_status; + case "PLUGGED_USB"_fnv1a16: return "USB Connected, " + charge_status; + case "PLUGGED_WIRELESS"_fnv1a16: return "Wireless Connected, "+ charge_status; + default: return charge_status; } } diff --git a/src/core-modules/core-modules.cc b/src/core-modules/core-modules.cc index 68233097..19eab13c 100644 --- a/src/core-modules/core-modules.cc +++ b/src/core-modules/core-modules.cc @@ -165,15 +165,11 @@ void core_plugins_start(const Config& config) const size_t uptime_hours = uptime_secs / (60 * 60); const size_t uptime_days = uptime_secs / (60 * 60 * 24); -#if CF_LINUX || CF_ANDROID if (uname(&g_uname_infos) != 0) die(_("uname() failed: {}\nCould not get system infos"), std::strerror(errno)); -#endif -#if CF_LINUX if (g_pwd = getpwuid(getuid()), !g_pwd) die(_("getpwent failed: {}\nCould not get user infos"), std::strerror(errno)); -#endif term_pid = get_terminal_pid(); term_name = get_terminal_name(); diff --git a/src/core-modules/macos/cpu.cc b/src/core-modules/macos/cpu.cc new file mode 100644 index 00000000..c36439d2 --- /dev/null +++ b/src/core-modules/macos/cpu.cc @@ -0,0 +1,72 @@ +#include "platform.hpp" +#if CF_MACOS + +#include <sys/sysctl.h> +#include <unistd.h> + +#include <cstdint> +#include <string> +#include <ratio> +#include <string> + +#include "core-modules.hh" + +static bool get_sysctl(int name[2], void* ret, size_t* oldlenp) +{ + return (sysctl(name, 2, ret, oldlenp, NULL, 0) == 0); +} + +static bool get_sysctl(const char* name, void* ret, size_t* oldlenp) +{ + return (sysctlbyname(name, ret, oldlenp, NULL, 0) == 0); +} + +MODFUNC(cpu_name) +{ + char buf[1024]; + size_t len = sizeof(buf); + get_sysctl("machdep.cpu.brand_string", &buf, &len); + return buf; +} + +MODFUNC(cpu_nproc) +{ + char buf[1024]; + size_t len = sizeof(buf); + if (!get_sysctl("hw.logicalcpu_max", &buf, &len)) + get_sysctl("hw.ncpu", &buf, &len); + return buf; +} + +MODFUNC(cpu_freq_cur) +{ + std::uint64_t freq = 0; + size_t length = sizeof(freq); + if (!get_sysctl("hw.cpufrequency", &freq, &length)) + get_sysctl({ CTL_HW, HW_CPU_FREQ }, &freq, &length); + + return fmt::to_string(static_cast<double>(freq) / std::giga().num); +} + +MODFUNC(cpu_freq_min) +{ + std::uint64_t freq = 0; + size_t length = sizeof(freq); + get_sysctl("hw.cpufrequency_min", &freq, &length); + + return fmt::to_string(static_cast<double>(freq) / std::giga().num); +} + +MODFUNC(cpu_freq_max) +{ + std::uint64_t freq = 0; + size_t length = sizeof(freq); + get_sysctl("hw.cpufrequency_max", &freq, &length); + + return fmt::to_string(static_cast<double>(freq) / std::giga().num); +} + +MODFUNC(cpu_freq_bios) +{ return MAGIC_LINE; } + +#endif diff --git a/src/core-modules/macos/os.cc b/src/core-modules/macos/os.cc new file mode 100644 index 00000000..383ee546 --- /dev/null +++ b/src/core-modules/macos/os.cc @@ -0,0 +1,125 @@ +#include <fstream> +#include <string> +#include "core-modules.hh" +#include "cufetch/common.hh" +#include "rapidxml-1.13/rapidxml.hpp" +#include "switch_fnv1a.hpp" + +std::ifstream f("/System/Library/CoreServices/SystemVersion.plist", std::ios::in); +std::string buffer(std::istreambuf_iterator<char>{ f }, std::istreambuf_iterator<char>{}); +rapidxml::xml_document<> doc; + +static std::string get_codename(const std::string_view os_version_id) +{ + std::string major; + std::string minor{ UNKNOWN }; + size_t pos1 = os_version_id.find('.'); + if (pos1 != os_version_id.npos) + { + major = os_version_id.substr(0, pos1); + size_t pos2 = os_version_id.find('.', pos1 + 1); + if (pos2 != os_version_id.npos) + minor = os_version_id.substr(pos1 + 1, pos2); + } + + switch (fnv1a16::hash(major)) + { + case "15"_fnv1a16: return "Sequoia"; + case "14"_fnv1a16: return "Sonoma"; + case "13"_fnv1a16: return "Ventura"; + case "12"_fnv1a16: return "Monterey"; + case "11"_fnv1a16: return "Big Sur"; + case "10"_fnv1a16: + { + switch (fnv1a16::hash(minor)) + { + case "16"_fnv1a16: return "Big Sur"; + case "15"_fnv1a16: return "Catalina"; + case "14"_fnv1a16: return "Mojave"; + case "13"_fnv1a16: return "High Sierra"; + case "12"_fnv1a16: return "Sierra"; + case "11"_fnv1a16: return "El Capitan"; + case "10"_fnv1a16: return "Yosemite"; + case "9"_fnv1a16: return "Mavericks"; + case "8"_fnv1a16: return "Mountain Lion"; + case "7"_fnv1a16: return "Lion"; + case "6"_fnv1a16: return "Snow Leopard"; + case "5"_fnv1a16: return "Leopard"; + case "4"_fnv1a16: return "Tiger"; + case "3"_fnv1a16: return "Panther"; + case "2"_fnv1a16: return "Jaguar"; + case "1"_fnv1a16: return "Puma"; + case "0"_fnv1a16: return "Cheetah"; + } + } + } + + return UNKNOWN; +} + +static void assert_doc() +{ + if (!doc.first_node("plist")) + { + buffer.push_back('\0'); + doc.parse<0>(&buffer[0]); + } +} + +static std::string get_plist_value(const std::string_view name) +{ + assert_doc(); + rapidxml::xml_node<>* root_node = doc.first_node("plist")->first_node("dict")->first_node("key"); + for (; root_node; root_node = root_node->next_sibling()) + { + const std::string_view key = root_node->value(); // <key>ProductName</key> + root_node = root_node->next_sibling(); + const std::string_view value = root_node->value(); // <string>macOS</string> + if (key == name) + return value.data(); + } + return UNKNOWN; +} + +MODFUNC(os_name) +{ return get_plist_value("ProductName"); } + +MODFUNC(os_version_id) +{ return get_plist_value("ProductUserVisibleVersion"); } + +MODFUNC(os_version_codename) +{ return get_codename(os_version_id(nullptr)); } + +MODFUNC(os_pretty_name) +{ + const std::string& codename = os_version_codename(nullptr); + if (codename != UNKNOWN) + return os_name(nullptr) + " " + os_version_id(nullptr) + " (" + codename + ")"; + return os_name(nullptr) + " " + os_version_id(nullptr); +} + +MODFUNC(os_kernel_name) +{ return g_uname_infos.sysname; } + +MODFUNC(os_kernel_version) +{ return g_uname_infos.release; } + +MODFUNC(os_hostname) +{ return g_uname_infos.nodename; } + +MODFUNC(os_initsys_name) +{ return MAGIC_LINE; } + +MODFUNC(os_initsys_version) +{ return UNKNOWN; } + +unsigned long os_uptime() +{ + struct timeval boot_time; + size_t size = sizeof(boot_time); + int name[] = { CTL_KERN, KERN_BOOTTIME }; + if (sysctl(name, 2, &boot_time, &size, NULL, 0) != 0) + die(_("failed to get uptime")); + + return time(NULL) - boot_time.tv_sec; +} From 97196fa83f32f2eb7a3a0ec539be842397d7f50c Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Sun, 13 Jul 2025 12:47:58 +0200 Subject: [PATCH 091/143] core-modules: macos: add ram module support --- src/core-modules/linux/os.cc | 1 - src/core-modules/macos/disk.cc | 43 ++++++++++++++++++ src/core-modules/macos/os.cc | 5 +++ src/core-modules/macos/ram.cc | 79 +++++++++++++++++++++++++++++++++ src/core-modules/macos/theme.cc | 21 +++++++++ 5 files changed, 148 insertions(+), 1 deletion(-) create mode 100644 src/core-modules/macos/disk.cc create mode 100644 src/core-modules/macos/ram.cc create mode 100644 src/core-modules/macos/theme.cc diff --git a/src/core-modules/linux/os.cc b/src/core-modules/linux/os.cc index 41596060..bbbbca19 100644 --- a/src/core-modules/linux/os.cc +++ b/src/core-modules/linux/os.cc @@ -10,7 +10,6 @@ #include "cufetch/common.hh" #include "core-modules.hh" -#include "fmt/format.h" #include "switch_fnv1a.hpp" #include "util.hpp" diff --git a/src/core-modules/macos/disk.cc b/src/core-modules/macos/disk.cc new file mode 100644 index 00000000..2e9bd03e --- /dev/null +++ b/src/core-modules/macos/disk.cc @@ -0,0 +1,43 @@ +#include "platform.hpp" +#if CF_MACOS + +#include <sys/statfs.h> +#include <sys/types.h> +#include <sys/param.h> +#include <sys/mount.h> + +#include <cstring> +#include <string> + +static std::string format_auto_query_string(std::string str, const struct statfs* fs) +{ + replace_str(str, "%1", fs->f_mntonname); + replace_str(str, "%2", fs->f_mntfromname); + replace_str(str, "%3", fs->f_fstypename); + + replace_str(str, "%4", fmt::format("$<disk({}).total>", fs->f_mntonname)); + replace_str(str, "%5", fmt::format("$<disk({}).free>", fs->f_mntonname)); + replace_str(str, "%6", fmt::format("$<disk({}).used>", fs->f_mntonname)); + replace_str(str, "%7", fmt::format("$<disk({}).used_perc>", fs->f_mntonname)); + replace_str(str, "%8", fmt::format("$<disk({}).free_perc>", fs->f_mntonname)); + + return str; +} + +static int get_disk_type(const int flags) +{ + int type = 0; + if (flags & MNT_DONTBROWSE) + type = DISK_VOLUME_TYPE_HIDDEN; + else if (flags & MNT_REMOVABLE || !(flags & MNT_LOCAL)) + type = DISK_VOLUME_TYPE_EXTERNAL; + else + type = DISK_VOLUME_TYPE_REGULAR; + + if (flags & MNT_RDONLY) + type |= DISK_VOLUME_TYPE_READ_ONLY; + + return type; +} + +#endif diff --git a/src/core-modules/macos/os.cc b/src/core-modules/macos/os.cc index 383ee546..226852a5 100644 --- a/src/core-modules/macos/os.cc +++ b/src/core-modules/macos/os.cc @@ -1,3 +1,6 @@ +#include "platform.hpp" +#if CF_MACOS + #include <fstream> #include <string> #include "core-modules.hh" @@ -123,3 +126,5 @@ unsigned long os_uptime() return time(NULL) - boot_time.tv_sec; } + +#endif diff --git a/src/core-modules/macos/ram.cc b/src/core-modules/macos/ram.cc new file mode 100644 index 00000000..0c810341 --- /dev/null +++ b/src/core-modules/macos/ram.cc @@ -0,0 +1,79 @@ +#include "platform.hpp" +#if CF_MACOS + +#include <mach/mach.h> +#include <sys/sysctl.h> +#include <unistd.h> + +#include <cstdint> + +#include "core-modules.hh" + +struct xsw_usage xsw; +const uint64_t xsw_length{sizeof(xsw)}; + +static bool populate_xsw() +{ + int name[2] = { CTL_VM, VM_SWAPUSAGE }; + return (sysctl(name, 2, &xsw, &xsw_length, NULL, 0) != 0); +} + +double ram_total() +{ + int name[2] = { CTL_HW, HW_MEMSIZE }; + uint64_t amount = 0; + size_t length = sizeof(amount); + if (sysctl(name, 2, &amount, &length, NULL, 0) != 0) + return 0.0; + return static_cast<double>(amount) / 1024; +} + +double ram_used() +{ + int name[2] = { CTL_HW, HW_PAGESIZE }; + uint64_t amount = 0, page_size = 0; + size_t length = sizeof(amount); + mach_msg_type_number_t count = HOST_VM_INFO64_COUNT; + vm_statistics64_data_t vmstat; + + sysctl(name, 2, &page_size, &length, NULL, 0); + if (host_statistics64(mach_host_self(), HOST_VM_INFO64, (host_info64_t)(&vmstat), &count) != KERN_SUCCESS) + return 0.0; + + return static_cast<double>( + ((uint64_t) + + vmstat.active_count + + vmstat.inactive_count + + vmstat.speculative_count + + vmstat.wire_count + + vmstat.compressor_page_count + - vmstat.purgeable_count + - vmstat.external_page_count + ) * page_size) / 1024; +} + +double ram_free() +{ return ram_total() - ram_used(); } + +double swap_used() +{ + if (!populate_xsw()) + return 0.0; + return xsw.xsu_used; +} + +double swap_free() +{ + if (!populate_xsw()) + return 0.0; + return xsw.xsu_avail; +} + +double swap_total() +{ + if (!populate_xsw()) + return 0.0; + return xsw.xsu_total; +} + +#endif diff --git a/src/core-modules/macos/theme.cc b/src/core-modules/macos/theme.cc new file mode 100644 index 00000000..8548401a --- /dev/null +++ b/src/core-modules/macos/theme.cc @@ -0,0 +1,21 @@ +#include "platform.hpp" +#if CF_MACOS + +#include "core-modules.hh" +#include "cufetch/common.hh" + +MODFUNC(theme_gtk_name) { return MAGIC_LINE; } +MODFUNC(theme_gtk_icon) { return MAGIC_LINE; } +MODFUNC(theme_gtk_font) { return MAGIC_LINE; } +MODFUNC(theme_cursor_name) { return MAGIC_LINE; } +MODFUNC(theme_cursor_size) { return MAGIC_LINE; } +MODFUNC(theme_gtk_all_name) { return MAGIC_LINE; } +MODFUNC(theme_gtk_all_icon) { return MAGIC_LINE; } +MODFUNC(theme_gtk_all_font) { return MAGIC_LINE; } +MODFUNC(theme_gsettings_name) { return MAGIC_LINE; } +MODFUNC(theme_gsettings_icon) { return MAGIC_LINE; } +MODFUNC(theme_gsettings_font) { return MAGIC_LINE; } +MODFUNC(theme_gsettings_cursor_name) { return MAGIC_LINE; } +MODFUNC(theme_gsettings_cursor_size) { return MAGIC_LINE; } + +#endif // CF_MACOS From c9780f12ae073c9d29769a6513189a0249d51978 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Sun, 13 Jul 2025 12:55:01 +0200 Subject: [PATCH 092/143] misc: rename query -> core-modules --- CMakeLists.txt | 6 +++--- Makefile | 10 ++-------- src/core-modules/linux/utils | 1 - .../dewm.cpp => core-modules/linux/utils/dewm.cc} | 0 .../dewm.hpp => core-modules/linux/utils/dewm.hh} | 0 .../linux/utils/packages.cc} | 0 .../linux/utils/packages.hh} | 0 .../term.cpp => core-modules/linux/utils/term.cc} | 0 .../term.hpp => core-modules/linux/utils/term.hh} | 0 9 files changed, 5 insertions(+), 12 deletions(-) delete mode 120000 src/core-modules/linux/utils rename src/{query/linux/utils/dewm.cpp => core-modules/linux/utils/dewm.cc} (100%) rename src/{query/linux/utils/dewm.hpp => core-modules/linux/utils/dewm.hh} (100%) rename src/{query/linux/utils/packages.cpp => core-modules/linux/utils/packages.cc} (100%) rename src/{query/linux/utils/packages.hpp => core-modules/linux/utils/packages.hh} (100%) rename src/{query/linux/utils/term.cpp => core-modules/linux/utils/term.cc} (100%) rename src/{query/linux/utils/term.hpp => core-modules/linux/utils/term.hh} (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2ffedf41..d36c3f01 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,9 +22,9 @@ file(GLOB "src/*.cpp" "src/core-modules/*.cc" "src/core-modules/linux/*.cc" - "src/query/android/*.cpp" - "src/query/macos/*.cpp" - "src/core-modules/linux/utils/*.cpp" + "src/core-modules/android/*.cc" + "src/core-modules/macos/*.cc" + "src/core-modules/linux/utils/*.cc" "src/libs/json/json.cpp" "src/libs/toml++/toml.cpp") diff --git a/Makefile b/Makefile index a37b19a0..010040e9 100644 --- a/Makefile +++ b/Makefile @@ -42,18 +42,12 @@ ifeq ($(USE_DCONF), 1) endif endif -# is macos? -ifeq ($(shell uname -s),Darwin) - SRC_CC := - SRC_CPP := $(wildcard src/*.cpp src/query/macos/*.cpp) -endif - NAME = customfetch TARGET ?= $(NAME) OLDVERSION = 0.10.2 VERSION = 1.0.0 -SRC_CPP ?= $(wildcard src/*.cpp src/core-modules/linux/utils/*.cpp) -SRC_CC ?= $(wildcard src/core-modules/*.cc src/core-modules/linux/*.cc src/core-modules/android/*.cc) +SRC_CPP = $(wildcard src/*.cpp) +SRC_CC = $(wildcard src/core-modules/*.cc src/core-modules/linux/*.cc src/core-modules/android/*.cc src/core-modules/macos/*.cc) OBJ_CPP = $(SRC_CPP:.cpp=.o) OBJ_CC = $(SRC_CC:.cc=.o) OBJ = $(OBJ_CPP) $(OBJ_CC) diff --git a/src/core-modules/linux/utils b/src/core-modules/linux/utils deleted file mode 120000 index eae0d984..00000000 --- a/src/core-modules/linux/utils +++ /dev/null @@ -1 +0,0 @@ -../../query/linux/utils \ No newline at end of file diff --git a/src/query/linux/utils/dewm.cpp b/src/core-modules/linux/utils/dewm.cc similarity index 100% rename from src/query/linux/utils/dewm.cpp rename to src/core-modules/linux/utils/dewm.cc diff --git a/src/query/linux/utils/dewm.hpp b/src/core-modules/linux/utils/dewm.hh similarity index 100% rename from src/query/linux/utils/dewm.hpp rename to src/core-modules/linux/utils/dewm.hh diff --git a/src/query/linux/utils/packages.cpp b/src/core-modules/linux/utils/packages.cc similarity index 100% rename from src/query/linux/utils/packages.cpp rename to src/core-modules/linux/utils/packages.cc diff --git a/src/query/linux/utils/packages.hpp b/src/core-modules/linux/utils/packages.hh similarity index 100% rename from src/query/linux/utils/packages.hpp rename to src/core-modules/linux/utils/packages.hh diff --git a/src/query/linux/utils/term.cpp b/src/core-modules/linux/utils/term.cc similarity index 100% rename from src/query/linux/utils/term.cpp rename to src/core-modules/linux/utils/term.cc diff --git a/src/query/linux/utils/term.hpp b/src/core-modules/linux/utils/term.hh similarity index 100% rename from src/query/linux/utils/term.hpp rename to src/core-modules/linux/utils/term.hh From ad98ce4c0334e4ef76f6a1908738d6d235a07098 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Sun, 13 Jul 2025 12:55:49 +0200 Subject: [PATCH 093/143] nuke the 'query' directory in favour of 'core-modules' --- src/query/android/battery.cpp | 142 ------- src/query/android/gpu.cpp | 219 ----------- src/query/android/system.cpp | 154 -------- src/query/android/theme.cpp | 65 ---- src/query/android/user.cpp | 115 ------ src/query/linux/battery.cpp | 134 ------- src/query/linux/cpu.cpp | 700 ---------------------------------- src/query/linux/disk.cpp | 290 -------------- src/query/linux/gpu.cpp | 121 ------ src/query/linux/ram.cpp | 137 ------- src/query/linux/system.cpp | 326 ---------------- src/query/linux/theme.cpp | 581 ---------------------------- src/query/linux/user.cpp | 678 -------------------------------- src/query/macos/battery.cpp | 59 --- src/query/macos/cpu.cpp | 118 ------ src/query/macos/disk.cpp | 179 --------- src/query/macos/gpu.cpp | 42 -- src/query/macos/ram.cpp | 115 ------ src/query/macos/system.cpp | 188 --------- src/query/macos/theme.cpp | 65 ---- 20 files changed, 4428 deletions(-) delete mode 100644 src/query/android/battery.cpp delete mode 100644 src/query/android/gpu.cpp delete mode 100644 src/query/android/system.cpp delete mode 100644 src/query/android/theme.cpp delete mode 100644 src/query/android/user.cpp delete mode 100644 src/query/linux/battery.cpp delete mode 100644 src/query/linux/cpu.cpp delete mode 100644 src/query/linux/disk.cpp delete mode 100644 src/query/linux/gpu.cpp delete mode 100644 src/query/linux/ram.cpp delete mode 100644 src/query/linux/system.cpp delete mode 100644 src/query/linux/theme.cpp delete mode 100644 src/query/linux/user.cpp delete mode 100644 src/query/macos/battery.cpp delete mode 100644 src/query/macos/cpu.cpp delete mode 100644 src/query/macos/disk.cpp delete mode 100644 src/query/macos/gpu.cpp delete mode 100644 src/query/macos/ram.cpp delete mode 100644 src/query/macos/system.cpp delete mode 100644 src/query/macos/theme.cpp diff --git a/src/query/android/battery.cpp b/src/query/android/battery.cpp deleted file mode 100644 index c274d88c..00000000 --- a/src/query/android/battery.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright 2025 Toni500git - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote - * products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "platform.hpp" -#if CF_ANDROID - -#include <cctype> -#include <string> -#include <vector> - -#include "json.h" -#include "query.hpp" -#include "switch_fnv1a.hpp" -#include "util.hpp" - -using namespace Query; - -static Battery::Battery_t get_battery_infos_termux() -{ - Battery::Battery_t infos; - std::string result, _; - if (!read_exec({ "/data/data/com.termux/files/usr/libexec/termux-api", "BatteryStatus" }, result)) - return infos; - - const auto& doc = json::jobject::parse(result); - - infos.status = doc["plugged"].as_string(); - infos.perc = doc["percentage"]; - infos.temp = doc["temperature"]; - - switch (fnv1a16::hash(infos.status)) - { - case "PLUGGED_AC"_fnv1a16: infos.status = "AC Connected, "; break; - case "PLUGGED_USB"_fnv1a16: infos.status = "USB Connected, "; break; - case "PLUGGED_WIRELESS"_fnv1a16: infos.status = "Wireless Connected, "; break; - default: infos.status.clear(); - } - - // CHARGING or DISCHARGING - std::string charge_status{ str_tolower(doc["status"].as_string()) }; - charge_status.at(0) = toupper(charge_status.at(0)); - infos.status += charge_status; - - return infos; -} - -static Battery::Battery_t get_battery_infos_dumpsys() -{ - Battery::Battery_t infos; - std::string result, _; - if (!read_exec({ "/system/bin/dumpsys", "battery" }, result)) - return infos; - - const std::vector<std::string>& vec = split(result, '\n'); - if (vec.at(0) != "Current Battery Service state:") - return infos; - - double level = 0, scale = 0; - for (size_t i = 1; i < vec.size(); ++i) - { - const size_t pos = vec.at(i).rfind(':'); - const std::string& key = vec.at(i).substr(2, pos); - const std::string& value = vec.at(i).substr(pos + 2); - - switch (fnv1a16::hash(key)) - { - case "level"_fnv1a16: level = std::stod(value); break; - case "scale"_fnv1a16: scale = std::stod(value); break; - - case "AC powered"_fnv1a16: - case "USB powered"_fnv1a16: - case "Dock powered"_fnv1a16: - case "Wireless powered"_fnv1a16: - if (value == "true") - infos.status = key; - break; - - case "temperature"_fnv1a16: infos.temp = std::stod(value) / 10; break; - case "technology"_fnv1a16: infos.technology = value; - } - } - - if (level > 0 && scale > 0) - infos.perc = level * 100 / scale; - - return infos; -} - -Battery::Battery() -{ - CHECK_INIT(m_bInit); - - m_battery_infos = get_battery_infos_termux(); - if (m_battery_infos.status == MAGIC_LINE || m_battery_infos.temp <= 0) - m_battery_infos = get_battery_infos_dumpsys(); -} - -// clang-format off -std::string& Battery::modelname() noexcept -{ return m_battery_infos.modelname; } - -std::string& Battery::status() noexcept -{ return m_battery_infos.status; } - -std::string& Battery::vendor() noexcept -{ return m_battery_infos.vendor; } - -std::string& Battery::technology() noexcept -{ return m_battery_infos.technology; } - -std::string& Battery::capacity_level() noexcept -{ return m_battery_infos.capacity_level; } - -double& Battery::perc() noexcept -{ return m_battery_infos.perc; } - -double& Battery::temp() noexcept -{ return m_battery_infos.temp; } - -#endif // CF_ANDROID diff --git a/src/query/android/gpu.cpp b/src/query/android/gpu.cpp deleted file mode 100644 index cf6c3800..00000000 --- a/src/query/android/gpu.cpp +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright 2025 Toni500git - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote - * products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "platform.hpp" -#if CF_ANDROID - -#include <string> - -#include "query.hpp" -#include "switch_fnv1a.hpp" -#include "util.hpp" - -using namespace Query; - -// https://en.wikipedia.org/wiki/List_of_Qualcomm_Snapdragon_systems_on_chips -static std::string detect_adreno(const std::string& cpu_model_name) -{ - switch (fnv1a16::hash(cpu_model_name)) - { - case "MSM8225Q"_fnv1a16: - case "MSM8625Q"_fnv1a16: return "Adreno (TM) 203"; - - case "MSM8210"_fnv1a16: - case "MSM8610"_fnv1a16: - case "MSM8212"_fnv1a16: - case "MSM8612"_fnv1a16: return "Adreno (TM) 302"; - - case "MSM8905"_fnv1a16: - case "MSM8208"_fnv1a16: - case "MSM8909"_fnv1a16: - case "MSM8909AA"_fnv1a16: return "Adreno (TM) 304"; - - case "APQ8026"_fnv1a16: - case "MSM8226"_fnv1a16: - case "MSM8926"_fnv1a16: - case "APQ8028"_fnv1a16: - case "MSM8228"_fnv1a16: - case "MSM8628"_fnv1a16: - case "MSM8928"_fnv1a16: - case "MSM8230"_fnv1a16: - case "MSM8630"_fnv1a16: - case "MSM8930"_fnv1a16: - case "MSM8930AA"_fnv1a16: - case "APQ8030AB"_fnv1a16: - case "MSM8230AB"_fnv1a16: - case "MSM8630AB"_fnv1a16: - case "MSM8930AB"_fnv1a16: return "Adreno (TM) 305"; - - case "APQ8016"_fnv1a16: - case "MSM8916"_fnv1a16: return "Adreno (TM) 306"; - - case "QM215"_fnv1a16: - case "MSM8917"_fnv1a16: - case "MSM8920"_fnv1a16: return "Adreno (TM) 308"; - - case "APQ8064M"_fnv1a16: - case "APQ8064T"_fnv1a16: - case "APQ8064AB"_fnv1a16: return "Adreno (TM) 320"; - - case "APQ8074AA"_fnv1a16: - case "MSM8274AA"_fnv1a16: - case "MSM8674AA"_fnv1a16: - case "MSM8974AA"_fnv1a16: - case "MSM8274AB"_fnv1a16: return "Adreno (TM) 330"; - - case "MSM8936"_fnv1a16: - case "MSM8939"_fnv1a16: - case "MSM8952"_fnv1a16: - case "MSM8929"_fnv1a16: return "Adreno (TM) 405"; - - case "MSM8992"_fnv1a16: return "Adreno (TM) 418"; - case "APQ8084"_fnv1a16: return "Adreno (TM) 420"; - case "MSM8994"_fnv1a16: return "Adreno (TM) 430"; - - case "SDM429"_fnv1a16: return "Adreno (TM) 504"; - - case "SDM439"_fnv1a16: - case "SDM450"_fnv1a16: - case "MSM8937"_fnv1a16: - case "MSM8940"_fnv1a16: return "Adreno (TM) 505"; - - case "MSM8953"_fnv1a16: - case "SDM632"_fnv1a16: return "Adreno (TM) 506"; - case "SDM630"_fnv1a16: return "Adreno (TM) 508"; - case "SDM636"_fnv1a16: return "Adreno (TM) 509"; - - case "MSM8956"_fnv1a16: - case "MSM8976"_fnv1a16: return "Adreno (TM) 510"; - - case "SDM660"_fnv1a16: return "Adreno (TM) 512"; - case "MSM8996"_fnv1a16: return "Adreno (TM) 530"; - case "MSM8998"_fnv1a16: return "Adreno (TM) 540"; - - case "SM6225"_fnv1a16: - case "SM6115"_fnv1a16: - case "SM6125"_fnv1a16: - case "SM6115-AC"_fnv1a16: - case "SM6225-AD"_fnv1a16: - case "SM4250-AA"_fnv1a16: return "Adreno (TM) 610"; - - case "SM4635"_fnv1a16: return "Adreno (TM) 611"; - case "SM6150"_fnv1a16: - case "SM6150-AC"_fnv1a16: return "Adreno (TM) 612"; - case "SM4450"_fnv1a16: return "Adreno (TM) 613"; - case "SDM670"_fnv1a16: return "Adreno (TM) 615"; - - case "SDM710"_fnv1a16: - case "SDM712"_fnv1a16: return "Adreno (TM) 616"; - - case "SM7125"_fnv1a16: - case "SM7150-AA"_fnv1a16: - case "SM7150-AB"_fnv1a16: - case "SM7150-AC"_fnv1a16: return "Adreno (TM) 618"; - - case "SM4375"_fnv1a16: - case "SM4350"_fnv1a16: - case "SM6375"_fnv1a16: - case "SM7225"_fnv1a16: - case "SM6375-AC"_fnv1a16: - case "SM4350-AC"_fnv1a16: return "Adreno (TM) 619"; - - case "SM6350"_fnv1a16: return "Adreno (TM) 619L"; - - case "SM7250-AA"_fnv1a16: - case "SM7250-AB"_fnv1a16: - case "SM7250-AC"_fnv1a16: return "Adreno (TM) 620"; - - case "SDM845"_fnv1a16: return "Adreno (TM) 630"; - - case "SM8150"_fnv1a16: - case "SM8150-AC"_fnv1a16: - case "SM8150P"_fnv1a16: return "Adreno (TM) 640"; - - case "SM7350-AB"_fnv1a16: return "Adreno (TM) 642"; - - case "SM7325"_fnv1a16: - case "SM7325-AF"_fnv1a16: - case "SM7325-AE"_fnv1a16: return "Adreno (TM) 642L"; - case "SM7450-AB"_fnv1a16: return "Adreno (TM) 644"; - - case "SM8250"_fnv1a16: - case "SM8250-AB"_fnv1a16: - case "SM8250-AC"_fnv1a16: return "Adreno (TM) 650"; - - case "SM8350"_fnv1a16: - case "SM8350-AC"_fnv1a16: return "Adreno (TM) 660"; - - case "SM7435-AB"_fnv1a16: - case "SM6475-AB"_fnv1a16: - case "SM6450"_fnv1a16: return "Adreno (TM) 710"; - - case "SM7550-AB"_fnv1a16: return "Adreno (TM) 720"; - case "SM7475-AB"_fnv1a16: return "Adreno (TM) 725"; - - case "SM8450"_fnv1a16: - case "SM8475"_fnv1a16: - case "SM8425-100-AC"_fnv1a16: return "Adreno (TM) 730"; - - case "SM7675-AB"_fnv1a16: return "Adreno (TM) 732"; - case "SM8635"_fnv1a16: return "Adreno (TM) 735"; - - case "SM8550"_fnv1a16: - case "SM8550-AB"_fnv1a16: - case "SM8550-AC"_fnv1a16: return "Adreno (TM) 740"; - - case "SM8650-AB"_fnv1a16: - case "SM8650-AC"_fnv1a16: return "Adreno (TM) 750"; - - case "SM7635"_fnv1a16: return "Adreno (TM) 810"; - case "SM8750-AB"_fnv1a16: return "Adreno (TM) 830"; - } - - return MAGIC_LINE; -} - -GPU::GPU(const std::string& id /*, moduleMap_t& queried_gpus*/) -{ - CPU query_cpu; - if (query_cpu.vendor() == "QUALCOMM" || query_cpu.vendor() == "QTI") - { - m_gpu_infos.vendor = "Qualcomm"; - m_gpu_infos.name = detect_adreno(query_cpu.modelname()); - } - else - { - m_gpu_infos.name = m_gpu_infos.vendor = MAGIC_LINE; - } -} - -// clang-format off -std::string& GPU::name() noexcept -{ return m_gpu_infos.name; } - -std::string& GPU::vendor() noexcept -{ return m_gpu_infos.vendor; } - -#endif diff --git a/src/query/android/system.cpp b/src/query/android/system.cpp deleted file mode 100644 index c44796c6..00000000 --- a/src/query/android/system.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright 2025 Toni500git - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote - * products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "platform.hpp" -#if CF_ANDROID - -#include <sys/stat.h> -#include <unistd.h> - -#include <array> -#include <ctime> -#include <string_view> - -#include "../linux/utils/packages.hpp" -#include "query.hpp" -#include "util.hpp" - -using namespace Query; - -static System::System_t get_system_infos() -{ - System::System_t ret; - - ret.os_name = "Android"; - ret.os_id = "android"; - ret.os_version_id = get_android_property("ro.build.version.release"); - ret.os_version_codename = get_android_property("ro.build.version.codename"); - ret.os_pretty_name = "Android " + ret.os_version_codename + " " + ret.os_version_id; - - constexpr std::array<std::string_view, 8> vendors_prop_names = { - "ro.product.marketname", "ro.vendor.product.display", "ro.config.devicename", "ro.config.marketing_name", - "ro.product.vendor.model", "ro.product.oppo_model", "ro.oppo.market.name", "ro.product.brand" - }; - for (const std::string_view name : vendors_prop_names) - { - if (ret.host_modelname.empty() || ret.host_modelname == UNKNOWN) - ret.host_modelname = get_android_property(name); - else - break; - } - ret.host_vendor = get_android_property("ro.product.manufacturer"); - ret.host_version = get_android_property("ro.product.model"); - - if (access("/system/bin/init", F_OK) == 0) - { - ret.os_initsys_name = "init"; - ret.os_initsys_version.clear(); - } - - return ret; -} - -static unsigned long get_uptime() -{ - struct std::timespec uptime; - if (clock_gettime(CLOCK_BOOTTIME, &uptime) != 0) - return 0; - - return (uint64_t)uptime.tv_sec + (uint64_t)uptime.tv_nsec / 1000000; -} - -System::System() -{ - CHECK_INIT(m_bInit); - - if (uname(&m_uname_infos) != 0) - die("uname() failed: {}\nCould not get system infos", strerror(errno)); - - m_uptime = get_uptime(); - m_system_infos = get_system_infos(); -} - -// clang-format off -std::string System::kernel_name() noexcept -{ return m_uname_infos.sysname; } - -std::string System::kernel_version() noexcept -{ return m_uname_infos.release; } - -std::string System::hostname() noexcept -{ return m_uname_infos.nodename; } - -std::string System::arch() noexcept -{ return m_uname_infos.machine; } - -unsigned long& System::uptime() noexcept -{ return m_uptime; } - -std::string& System::os_pretty_name() noexcept -{ return m_system_infos.os_pretty_name; } - -std::string& System::os_name() noexcept -{ return m_system_infos.os_name; } - -std::string& System::os_id() noexcept -{ return m_system_infos.os_id; } - -std::string& System::os_versionid() noexcept -{ return m_system_infos.os_version_id; } - -std::string& System::os_version_codename() noexcept -{ return m_system_infos.os_version_codename; } - -std::string& System::host_modelname() noexcept -{ return m_system_infos.host_modelname; } - -std::string& System::host_vendor() noexcept -{ return m_system_infos.host_vendor; } - -std::string& System::host_version() noexcept -{ return m_system_infos.host_version; } - -std::string& System::os_initsys_name() -{ return m_system_infos.os_initsys_name; } - -std::string& System::os_initsys_version() -{ return m_system_infos.os_initsys_version; } - -std::string& System::pkgs_installed(const Config& config) -{ - static bool done = false; - if (!done) - { - m_system_infos.pkgs_installed = get_all_pkgs(config); - - done = true; - } - - return m_system_infos.pkgs_installed; -} - -#endif diff --git a/src/query/android/theme.cpp b/src/query/android/theme.cpp deleted file mode 100644 index a09730aa..00000000 --- a/src/query/android/theme.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2025 Toni500git - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote - * products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "platform.hpp" -#if CF_ANDROID - -#include "query.hpp" -#include "util.hpp" - -using namespace Query; - -Theme::Theme(const std::uint8_t ver, moduleMap_t& queried_themes, const std::string& theme_name_version, - const Config& config, const bool gsettings_only) - : m_queried_themes(queried_themes) -{ - m_theme_infos.cursor = m_theme_infos.gtk_font = m_theme_infos.cursor_size = m_theme_infos.gtk_theme_name = - m_theme_infos.gtk_icon_theme = MAGIC_LINE; -} - -Theme::Theme(moduleMap_t& queried_themes, const Config& config, const bool gsettings_only) - : m_queried_themes(queried_themes) -{ - m_theme_infos.cursor = m_theme_infos.gtk_font = m_theme_infos.cursor_size = m_theme_infos.gtk_theme_name = - m_theme_infos.gtk_icon_theme = MAGIC_LINE; -} - -// clang-format off -std::string Theme::gtk_theme() noexcept -{ return m_theme_infos.gtk_theme_name; } - -std::string Theme::gtk_icon_theme() noexcept -{ return m_theme_infos.gtk_icon_theme; } - -std::string Theme::gtk_font() noexcept -{ return m_theme_infos.gtk_font; } - -std::string& Theme::cursor() noexcept -{ return m_theme_infos.cursor; } - -std::string& Theme::cursor_size() noexcept -{ return m_theme_infos.cursor_size; } - -#endif diff --git a/src/query/android/user.cpp b/src/query/android/user.cpp deleted file mode 100644 index 2ce5919e..00000000 --- a/src/query/android/user.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright 2025 Toni500git - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote - * products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "platform.hpp" -#if CF_ANDROID - -#include <linux/limits.h> -#include <unistd.h> - -#include <cstdlib> -#include <string> - -#include "fmt/format.h" -#include "query.hpp" -#include "util.hpp" - -using namespace Query; - -static std::string get_shell_version(const std::string_view shell_name) -{ - std::string ret; - - if (shell_name == "nu") - ret = read_shell_exec("nu -c \"version | get version\""); - else - ret = read_shell_exec(fmt::format("{} -c 'echo \"${}_VERSION\"'", shell_name, str_toupper(shell_name.data()))); - - strip(ret); - return ret; -} - -static std::string get_shell_name(const std::string_view shell_path) -{ - return shell_path.substr(shell_path.rfind('/') + 1).data(); -} - -User::User() noexcept -{ - CHECK_INIT(m_bInit); - - if (m_pPwd = getpwuid(getuid()), !m_pPwd) - die("getpwent failed: {}\nCould not get user infos", std::strerror(errno)); - - char buf[PATH_MAX]; - if (getenv("TERMUX_VERSION") || getenv("TERMUX_MAIN_PACKAGE_FORMAT")) - { - m_users_infos.shell_path = realpath(fmt::format("/proc/{}/exe", getppid()).c_str(), buf); - m_users_infos.shell_name = get_shell_name(m_users_infos.shell_path); - m_users_infos.shell_version = get_shell_version(m_users_infos.shell_name); - m_users_infos.term_name = "Termux"; - m_users_infos.term_version = getenv("TERMUX_VERSION"); - } - else - { - m_users_infos.shell_path = m_pPwd->pw_shell; - } - - m_users_infos.wm_name = m_users_infos.wm_version = m_users_infos.de_name = m_users_infos.de_version = - m_users_infos.m_wm_path = MAGIC_LINE; -} - -// clang-format off -std::string User::name() noexcept -{ return m_pPwd->pw_name; } - -std::string User::shell_path() noexcept -{ return m_users_infos.shell_path; } - -std::string& User::shell_name() noexcept -{ return m_users_infos.shell_name; } - -std::string& User::shell_version(const std::string_view shell_name) -{ return m_users_infos.shell_version; } - -std::string& User::term_name() -{ return m_users_infos.term_name; } - -std::string& User::term_version(const std::string_view term_name) -{ return m_users_infos.term_version; } - -std::string& User::wm_name(bool dont_query_dewm, const std::string_view term_name) -{ return m_users_infos.wm_name; } - -std::string& User::wm_version(bool dont_query_dewm, const std::string_view term_name) -{ return m_users_infos.wm_version; } - -std::string& User::de_name(bool dont_query_dewm, const std::string_view term_name, const std::string_view wm_name) -{ return m_users_infos.de_name; } - -std::string& User::de_version(const std::string_view de_name) -{ return m_users_infos.de_version; } - -#endif diff --git a/src/query/linux/battery.cpp b/src/query/linux/battery.cpp deleted file mode 100644 index 5cfc1cfc..00000000 --- a/src/query/linux/battery.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright 2025 Toni500git - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote - * products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "platform.hpp" -#if CF_LINUX - -#include <cstdlib> -#include <filesystem> -#include <string> - -#include "query.hpp" -#include "util.hpp" - -using namespace Query; - -static void read_strip_syspath(std::string& str, const std::string_view path) -{ - str = read_by_syspath(path); - debug("str = {} || path = {}", str, path); - - // optimization - if (str.back() == '\n') - str.pop_back(); - else if (str != UNKNOWN) - strip(str); -} - -static Battery::Battery_t get_battery_infos() -{ - Battery::Battery_t infos; - if (!std::filesystem::exists("/sys/class/power_supply/")) - return infos; - - for (const auto& dir_entry : std::filesystem::directory_iterator{ "/sys/class/power_supply/" }) - { - const std::string& path = dir_entry.path().string() + "/"; - debug("battery path = {}", path); - std::string tmp; - - read_strip_syspath(tmp, path + "type"); - if (tmp == UNKNOWN || tmp != "Battery") - continue; - - read_strip_syspath(tmp, path + "scope"); - if (tmp == "Device") - continue; - - debug("battery found yeappyy"); - read_strip_syspath(tmp, path + "capacity"); - if (tmp != UNKNOWN) - infos.perc = std::stod(tmp); - else - continue; - - read_strip_syspath(tmp, path + "temp"); - if (tmp != UNKNOWN) - infos.temp = std::stod(tmp) / 10; - - read_strip_syspath(tmp, path + "manufacturer"); - if (tmp != UNKNOWN) - infos.vendor = tmp; - - read_strip_syspath(tmp, path + "model_name"); - if (tmp != UNKNOWN) - infos.modelname = tmp; - - read_strip_syspath(tmp, path + "technology"); - if (tmp != UNKNOWN) - infos.technology = tmp; - - read_strip_syspath(tmp, path + "status"); - if (tmp != UNKNOWN) - infos.status = tmp; - - read_strip_syspath(tmp, path + "capacity_level"); - if (tmp != UNKNOWN) - infos.capacity_level = tmp; - } - - return infos; -} - -Battery::Battery() -{ - CHECK_INIT(m_bInit); - - m_battery_infos = get_battery_infos(); -} - -// clang-format off -std::string& Battery::modelname() noexcept -{ return m_battery_infos.modelname; } - -std::string& Battery::status() noexcept -{ return m_battery_infos.status; } - -std::string& Battery::vendor() noexcept -{ return m_battery_infos.vendor; } - -std::string& Battery::technology() noexcept -{ return m_battery_infos.technology; } - -std::string& Battery::capacity_level() noexcept -{ return m_battery_infos.capacity_level; } - -double& Battery::perc() noexcept -{ return m_battery_infos.perc; } - -double& Battery::temp() noexcept -{ return m_battery_infos.temp; } - -#endif // CF_LINUX diff --git a/src/query/linux/cpu.cpp b/src/query/linux/cpu.cpp deleted file mode 100644 index cf5ca425..00000000 --- a/src/query/linux/cpu.cpp +++ /dev/null @@ -1,700 +0,0 @@ -/* - * Copyright 2025 Toni500git - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote - * products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "platform.hpp" -#if CF_ANDROID || CF_LINUX - -#include <sys/types.h> - -#include <array> -#include <cstdlib> -#include <filesystem> -#include <fstream> -#include <string> -#include <string_view> - -#include "fmt/format.h" -#include "query.hpp" -#include "switch_fnv1a.hpp" -#include "util.hpp" - -using namespace Query; - -#if CF_ANDROID -// https://en.wikipedia.org/wiki/List_of_Qualcomm_Snapdragon_systems_on_chips -// by Toni500git -static std::string detect_qualcomm(const std::string& model_name) -{ - switch (fnv1a16::hash(str_toupper(model_name))) - { - case "SM8750-AB"_fnv1a16: return "Snapdragon 8 Elite"; - case "SM8635"_fnv1a16: return "Snapdragon 8s Gen 3"; - case "SM8650-AC"_fnv1a16: return "Snapdragon 8 Gen 3 for Galaxy"; - case "SM8650"_fnv1a16: return "Snapdragon 8 Gen 3"; - case "SM8550-AC"_fnv1a16: return "Snapdragon 8 Gen 2 for Galaxy"; - case "SM8550"_fnv1a16: return "Snapdragon 8 Gen 2"; - case "SM8475"_fnv1a16: return "Snapdragon 8+ Gen 1"; - case "SM8450"_fnv1a16: return "Snapdragon 8 Gen 1"; - - case "SM7450-AB"_fnv1a16: return "Snapdragon 7 Gen 1"; - case "SM7475-AB"_fnv1a16: return "Snapdragon 7+ Gen 2"; - case "SM7435-AB"_fnv1a16: return "Snapdragon 7s Gen 2"; - case "SM7550-AB"_fnv1a16: return "Snapdragon 7 Gen 3"; - case "SM7675-AB"_fnv1a16: return "Snapdragon 7+ Gen 3"; - case "SM7635"_fnv1a16: return "Snapdragon 7s Gen 3"; - - case "SM6375-AC"_fnv1a16: return "Snapdragon 6s Gen 3"; - case "SM6475-AB"_fnv1a16: return "Snapdragon 6 Gen 3"; - case "SM6115-AC"_fnv1a16: return "Snapdragon 6s Gen 1"; - case "SM6450"_fnv1a16: return "Snapdragon 6 Gen 1"; - - case "SM4635"_fnv1a16: return "Snapdragon 4s Gen 2"; - case "SM4450"_fnv1a16: return "Snapdragon 4 Gen 2"; - case "SM4375"_fnv1a16: return "Snapdragon 4 Gen 1"; - - // adding fastfetch's many missing chips names - case "MSM8225Q"_fnv1a16: - case "MSM8625Q"_fnv1a16: - case "MSM8210"_fnv1a16: - case "MSM8610"_fnv1a16: - case "MSM8212"_fnv1a16: - case "MSM8612"_fnv1a16: return "Snapdragon 200"; - - case "MSM8905"_fnv1a16: return "205"; // Qualcomm 205 - case "MSM8208"_fnv1a16: return "Snapdragon 208"; - case "MSM8909"_fnv1a16: return "Snapdragon 210"; - case "MSM8909AA"_fnv1a16: return "Snapdragon 212"; - case "QM215"_fnv1a16: return "215"; - - // holy crap - case "APQ8026"_fnv1a16: - case "MSM8226"_fnv1a16: - case "MSM8926"_fnv1a16: - case "APQ8028"_fnv1a16: - case "MSM8228"_fnv1a16: - case "MSM8628"_fnv1a16: - case "MSM8928"_fnv1a16: - case "MSM8230"_fnv1a16: - case "MSM8630"_fnv1a16: - case "MSM8930"_fnv1a16: - case "MSM8930AA"_fnv1a16: - case "APQ8030AB"_fnv1a16: - case "MSM8230AB"_fnv1a16: - case "MSM8630AB"_fnv1a16: - case "MSM8930AB"_fnv1a16: return "Snapdragon 400"; - - case "APQ8016"_fnv1a16: - case "MSM8916"_fnv1a16: return "Snapdragon 410"; - case "MSM8929"_fnv1a16: return "Snapdragon 415"; - case "MSM8917"_fnv1a16: return "Snapdragon 425"; - case "MSM8920"_fnv1a16: return "Snapdragon 427"; - case "MSM8937"_fnv1a16: return "Snapdragon 430"; - case "MSM8940"_fnv1a16: return "Snapdragon 435"; - case "SDM429"_fnv1a16: return "Snapdragon 429"; - case "SDM439"_fnv1a16: return "Snapdragon 439"; - case "SDM450"_fnv1a16: return "Snapdragon 450"; - case "SM4250-AA"_fnv1a16: return "Snapdragon 460"; - case "SM4350"_fnv1a16: return "Snapdragon 480"; - case "SM4350-AC"_fnv1a16: return "Snapdragon 480+"; - - case "APQ8064-1AA"_fnv1a16: - case "APQ8064M"_fnv1a16: - case "APQ8064T"_fnv1a16: - case "APQ8064AB"_fnv1a16: return "Snapdragon 600"; - - case "MSM8936"_fnv1a16: return "Snapdragon 610"; - case "MSM8939"_fnv1a16: return "Snapdragon 615"; - case "MSM8952"_fnv1a16: return "Snapdragon 617"; - case "MSM8953"_fnv1a16: return "Snapdragon 625"; - case "SDM630"_fnv1a16: return "Snapdragon 630"; - case "SDM632"_fnv1a16: return "Snapdragon 632"; - case "SDM636"_fnv1a16: return "Snapdragon 636"; - case "MSM8956"_fnv1a16: return "Snapdragon 650"; - case "MSM8976"_fnv1a16: return "Snapdragon 652"; - case "SDA660"_fnv1a16: - case "SDM660"_fnv1a16: return "Snapdragon 660"; - case "SM6115"_fnv1a16: return "Snapdragon 662"; - case "SM6125"_fnv1a16: return "Snapdragon 665"; - case "SDM670"_fnv1a16: return "Snapdragon 670"; - case "SM6150"_fnv1a16: return "Snapdragon 675"; - case "SM6150-AC"_fnv1a16: return "Snapdragon 678"; - case "SM6225"_fnv1a16: return "Snapdragon 680"; - case "SM6225-AD"_fnv1a16: return "Snapdragon 685"; - case "SM6350"_fnv1a16: return "Snapdragon 690"; - case "SM6375"_fnv1a16: return "Snapdragon 695"; - - case "SDM710"_fnv1a16: return "Snapdragon 710"; - case "SDM712"_fnv1a16: return "Snapdragon 712"; - case "SM7125"_fnv1a16: return "Snapdragon 720G"; - case "SM7150-AA"_fnv1a16: return "Snapdragon 730"; - case "SM7150-AB"_fnv1a16: return "Snapdragon 730G"; - case "SM7150-AC"_fnv1a16: return "Snapdragon 732G"; - case "SM7225"_fnv1a16: return "Snapdragon 750G"; - case "SM7250-AA"_fnv1a16: return "Snapdragon 765"; - case "SM7250-AB"_fnv1a16: return "Snapdragon 765G"; - case "SM7250-AC"_fnv1a16: return "Snapdragon 768G"; - case "SM7325"_fnv1a16: return "Snapdragon 778G"; - case "SM7325-AE"_fnv1a16: return "Snapdragon 778G+"; - case "SM7350-AB"_fnv1a16: return "Snapdragon 780G"; - case "SM7325-AF"_fnv1a16: return "Snapdragon 782G"; - - case "APQ8074AA"_fnv1a16: - case "MSM8274AA"_fnv1a16: - case "MSM8674AA"_fnv1a16: - case "MSM8974AA"_fnv1a16: - case "MSM8274AB"_fnv1a16: return "Snapdragon 800"; - - case "APQ8084"_fnv1a16: return "Snapdragon 805"; - case "MSM8992"_fnv1a16: return "Snapdragon 808"; - case "MSM8994"_fnv1a16: return "Snapdragon 810"; - case "MSM8996"_fnv1a16: return "Snapdragon 820"; - case "MSM8998"_fnv1a16: return "Snapdragon 835"; - case "SDM845"_fnv1a16: return "Snapdragon 845"; - case "SM8150"_fnv1a16: return "Snapdragon 855"; - case "SM8150P"_fnv1a16: - case "SM8150-AC"_fnv1a16: return "Snapdragon 855+"; // both 855+ and 860 - case "SM8250"_fnv1a16: return "Snapdragon 865"; - case "SM8250-AB"_fnv1a16: return "Snapdragon 865+"; - case "SM8250-AC"_fnv1a16: return "Snapdragon 870"; - case "SM8350"_fnv1a16: return "Snapdragon 888"; - case "SM8350-AC"_fnv1a16: return "Snapdragon 888+"; - } - - return model_name; -} - -// https://en.wikipedia.org/wiki/Exynos#Current_Exynos_SoCs_(2020%E2%80%93present) -// by BurntRanch -static std::string detect_exynos(const std::string& model_name) -{ - switch (fnv1a16::hash(str_toupper(model_name))) - { - case "S5E3830"_fnv1a16: return "Exynos 850"; - case "S5E8805"_fnv1a16: return "Exynos 880"; - - case "S5E9630"_fnv1a16: return "Exynos 980"; - case "S5E9830"_fnv1a16: return "Exynos 990"; - - case "S5E9815"_fnv1a16: return "Exynos 1080"; - case "S5E8825"_fnv1a16: return "Exynos 1280"; - case "S5E8535"_fnv1a16: return "Exynos 1330"; - case "S5E8835"_fnv1a16: return "Exynos 1380"; - case "S5E8845"_fnv1a16: return "Exynos 1480"; - case "S5E8855"_fnv1a16: - return "Exynos 1580"; - /* TODO: alot of SoCs with no ID mentioned on Wikipedia.. */ - - case "S5E9840"_fnv1a16: return "Exynos 2100"; - case "S5E9925"_fnv1a16: return "Exynos 2200"; - case "S5E9945"_fnv1a16: return "Exynos 2400[e]"; - - case "S5PC110"_fnv1a16: return "Exynos 3 Single 3110"; - case "S5E3470"_fnv1a16: return "Exynos 3 Quad 3470"; - /* TODO: ASSUMPTION!! I could not find the full part number for this, I'm making an assumption here. */ - case "S5E3475"_fnv1a16: return "Exynos 3 Quad 3475"; - - case "S5E4210"_fnv1a16: - case "S5PC210"_fnv1a16: return "Exynos 4 Dual 4210"; - - case "S5E4212"_fnv1a16: return "Exynos 4 Dual 4212"; - - case "S55E4210"_fnv1a16: - case "S5PC220"_fnv1a16: - return "Exynos 4 Quad 4412"; - - /* TODO: Exynos 4 Quad 4415 */ - - case "S5E5250"_fnv1a16: - case "S5PC520"_fnv1a16: return "Exynos 5 Dual 5250"; - - case "S5E5260"_fnv1a16: return "Exynos 5 Hexa 5260"; - case "S5E5410"_fnv1a16: return "Exynos 5 Octa 5410"; - case "S5E5420"_fnv1a16: return "Exynos 5 Octa 5420"; - - /* 5800 for chromebooks */ - case "S5E5422"_fnv1a16: return "Exynos 5 Octa 5422/5800"; - - case "S5E5430"_fnv1a16: return "Exynos 5 Octa 5430"; - case "S5E5433"_fnv1a16: return "Exynos 7 Octa 5433"; - case "SC57270"_fnv1a16: return "Exynos 7 Dual 7270"; - case "S5E7420"_fnv1a16: return "Exynos 7 Octa 7420"; - case "S5E7570"_fnv1a16: - return "Exynos 7 Quad 7570"; - /* TODO: Exynos 7 Quad/Octa 7578/7580 */ - - case "S5E7870"_fnv1a16: return "Exynos 7 Octa 7870"; - case "S5E7872"_fnv1a16: return "Exynos 5 7872"; - case "S5E7880"_fnv1a16: return "Exynos 7880"; - case "S5E7884"_fnv1a16: return "Exynos 7884/7885"; - case "S5E7904"_fnv1a16: return "Exynos 7904"; - case "S5E8890"_fnv1a16: return "Exynos 8 Octa 8890"; - case "S5E8895"_fnv1a16: return "Exynos 8895"; - case "S5E9609"_fnv1a16: return "Exynos 9609"; - case "S5E9610"_fnv1a16: return "Exynos 9610"; - case "S5E9611"_fnv1a16: return "Exynos 9611"; - case "S5E9810"_fnv1a16: return "Exynos 9810"; - case "S5E9820"_fnv1a16: return "Exynos 9820"; - case "S5E9825"_fnv1a16: - return "Exynos 9825"; - /* TODO: Exynos 3 Dual 3250 */ - - case "SC59110XSC"_fnv1a16: return "Exynos 9110"; - case "SC55515XBD"_fnv1a16: return "Exynos W920"; - case "SC55515XBE"_fnv1a16: return "Exynos W930"; - case "SC55535AHA"_fnv1a16: return "Exynos W1000"; - } - - return model_name; -} - -// https://en.wikipedia.org/wiki/List_of_MediaTek_systems_on_chips -// by Toni500git -// i need some coffee..... -// wayland crashed and had to restart from Dimensity 1000 series......... -static std::string detect_mediatek(const std::string& model_name) -{ - switch (fnv1a16::hash(model_name)) - { - // Helio series - // Helio X series - case "MT6795"_fnv1a16: - case "MT6795M"_fnv1a16: - case "MT6795T"_fnv1a16: return "Helio X10"; - - case "MT6797"_fnv1a16: return "Helio X20"; - case "MT6797D"_fnv1a16: return "Helio X23"; - case "MT6797X"_fnv1a16: return "Helio X27"; - case "MT6799"_fnv1a16: return "Helio X30"; - - // Helio A series - case "MT6761V/WE"_fnv1a16: return "Helio A20"; - case "MT6761V/WBB"_fnv1a16: - case "MT6761V/WAB"_fnv1a16: return "Helio A22"; - case "MT6762V/WD"_fnv1a16: - case "MT6762V/WB"_fnv1a16: return "Helio A25"; - - // Helio P series - case "MT6755"_fnv1a16: - case "MT6755M"_fnv1a16: return "Helio P10"; - case "MT6755T"_fnv1a16: return "Helio P15"; - case "MT6755S"_fnv1a16: return "Helio P18"; - case "MT6757"_fnv1a16: return "Helio P20"; - case "MT6762"_fnv1a16: return "Helio P22"; - case "MT6763"_fnv1a16: return "Helio P23"; - case "MT6763T"_fnv1a16: return "Helio P23T"; - case "MT6757CD"_fnv1a16: return "Helio P25"; - case "MT6757T"_fnv1a16: return "Helio P25T"; - case "MT6758"_fnv1a16: return "Helio P30"; - case "MT6765"_fnv1a16: return "Helio P35"; - case "MT6771"_fnv1a16: return "Helio P60"; - case "MT6768"_fnv1a16: return "Helio P65"; - case "MT6771V/CT"_fnv1a16: return "Helio P70"; - case "MT6779V/CU"_fnv1a16: return "Helio P90"; - case "MT6779V/CV"_fnv1a16: return "Helio P95"; - - // Helio G series - case "MT6762G"_fnv1a16: return "Helio G25"; - case "MT6765G"_fnv1a16: return "Helio G35"; - case "MT6765V/XAA"_fnv1a16: return "Helio G36"; - case "MT6765V/XBA"_fnv1a16: return "Helio G36"; - case "MT6765H"_fnv1a16: return "Helio G37"; - case "MT6765V"_fnv1a16: return "Helio G50"; - case "MT6769V/CB"_fnv1a16: return "Helio G70"; - - case "MT6769T"_fnv1a16: - case "MT6769V/CT"_fnv1a16: - case "MT6769V/CU"_fnv1a16: return "Helio G80"; - - case "MT6769J"_fnv1a16: return "Helio G81"; - case "MT6769Z"_fnv1a16: return "Helio G85"; - case "MT6769V/CZ"_fnv1a16: return "Helio G85"; - case "MT6769H"_fnv1a16: return "Helio G88"; - case "MT6785V/CC"_fnv1a16: return "Helio G90T"; - case "MT6769G"_fnv1a16: return "Helio G91"; - case "MT6769I"_fnv1a16: return "Helio G92"; - case "MT6785V/CD"_fnv1a16: return "Helio G95"; - case "MT6781"_fnv1a16: return "Helio G96"; - case "MT6781V/CD"_fnv1a16: return "Helio G96"; - case "MT6789H"_fnv1a16: return "Helio G100"; - - case "MT6789"_fnv1a16: - case "MT6789G"_fnv1a16: - case "MT6789U"_fnv1a16: - case "MT6789V/CD"_fnv1a16: - case "MT8781"_fnv1a16: - case "MT8781V/CA"_fnv1a16: - case "MT8781V/NB"_fnv1a16: return "Helio G99"; - - // Dimensity Series - // Dimensity 700 Series - case "MT6833"_fnv1a16: - case "MT6833G"_fnv1a16: - case "MT6833V/ZA"_fnv1a16: - case "MT6833V/NZA"_fnv1a16: return "Dimensity 700"; - - case "MT6853V/ZA"_fnv1a16: - case "MT6853V/NZA"_fnv1a16: return "Dimensity 720"; - - // Dimensity 800 Series - case "MT6873"_fnv1a16: return "Dimensity 800"; - case "MT6853T"_fnv1a16: return "Dimensity 800U"; - case "MT6853V/TNZA"_fnv1a16: return "Dimensity 800U"; - case "MT6875"_fnv1a16: return "Dimensity 820"; - - case "MT6833P"_fnv1a16: - case "MT6833GP"_fnv1a16: - case "MT6833V/PNZA"_fnv1a16: return "Dimensity 810"; - - // Dimensity 900 Series - case "MT6877V/ZA"_fnv1a16: return "Dimensity 900"; - case "MT6855"_fnv1a16: - case "MT6855V/AZA"_fnv1a16: return "Dimensity 930"; - - // case "MT6877"_fnv1a16: - case "MT6877T"_fnv1a16: - case "MT6877V/TZA"_fnv1a16: return "Dimensity 920"; - - // Dimensity 1000 Series - case "MT6883Z/CZA"_fnv1a16: return "Dimensity 1000C"; - case "MT6885Z/CZA"_fnv1a16: return "Dimensity 1000L"; - case "MT6889"_fnv1a16: return "Dimensity 1000"; - case "MT6889Z/CZA"_fnv1a16: return "Dimensity 1000+"; - - case "MT6879"_fnv1a16: - case "MT6879V/ZA"_fnv1a16: - case "MT6879V_T/ZA"_fnv1a16: return "Dimensity 1050"; - - case "MT6877"_fnv1a16: return "Dimensity 1080 / Dimensity 920"; - case "MT6877V/TTZA"_fnv1a16: - case "MT6877V_T/TTZA"_fnv1a16: return "Dimensity 1080"; - - case "MT6891"_fnv1a16: - case "MT6891Z/CZA"_fnv1a16: - case "MT6891Z_Z/CZA"_fnv1a16: - case "MT6891Z_T/CZA"_fnv1a16: return "Dimensity 1100"; - - case "MT6893"_fnv1a16: - case "MT6893Z/CZA"_fnv1a16: - case "MT6893Z_A/CZA"_fnv1a16: return "Dimensity 1200"; - - case "MT6893Z_Z/CZA"_fnv1a16: - case "MT6893Z_T/CZA"_fnv1a16: return "Dimensity 1300"; - - // Dimensity 6000 Series - // note: Dimensity 6020 == Dimensity 700 - // Dimensity 6080 == Dimensity 810 - case "MT6835"_fnv1a16: - case "MT6835V/ZA"_fnv1a16: - case "MT8755V/TZB"_fnv1a16: return "Dimensity 6100+"; - case "MT6835T"_fnv1a16: return "Dimensity 6300"; - - // Dimensity 7000 Series - // note: Dimensity 7020 == Dimensity 930 - // Dimensity 7030 == Dimensity 1050 - // Dimensity 7050 == Dimensity 1080 - // Dimensity 7300 == Dimensity 7300X - case "MT6855V/ATZA"_fnv1a16: return "Dimensity 7025"; - case "MT6886V/TCZA"_fnv1a16: return "Dimensity 7350"; - - case "MT6886"_fnv1a16: - case "MT6886V_A/CZA"_fnv1a16: - case "MT6886V_B/CZA"_fnv1a16: return "Dimensity 7200"; - - case "MT6878"_fnv1a16: - case "MT6878V/ZA"_fnv1a16: - case "MT6878V_A/ZA"_fnv1a16: return "Dimensity 7300"; - - // Dimensity 8000 Series - // note: Dimensity 8020 == Dimensity 1100 - // Dimensity 8050 == Dimensity 1300 - case "MT6895"_fnv1a16: return "Dimensity 8000 / Dimensity 8100"; - case "MT6895Z/CZA"_fnv1a16: return "Dimensity 8000"; - - // case "MT6895"_fnv1a16: - case "MT6895Z/TCZA"_fnv1a16: - case "MT6895Z_A/TCZA"_fnv1a16: - case "MT6895Z_B/TCZA"_fnv1a16: - case "MT6895ZB"_fnv1a16: - case "MT8795"_fnv1a16: - case "MT8795Z/TNZA"_fnv1a16: return "Dimensity 8100"; - - // case "MT6896"_fnv1a16: - case "MT6896Z/CZA"_fnv1a16: - case "MT6896Z_B/CZA"_fnv1a16: return "Dimensity 8200"; - - case "MT6896"_fnv1a16: return "Dimensity 8200 / Dimensity 8250"; - case "MT6896Z_C/CZA"_fnv1a16: return "Dimensity 8250"; - - // case "MT6897"_fnv1a16: - case "MT8792Z/NB"_fnv1a16: return "Dimensity 8300"; - - case "MT6897"_fnv1a16: return "Dimensity 8300 / Dimensity 8350"; - case "MT6897Z_A/ZA"_fnv1a16: return "Dimensity 8350"; - - case "MT6899"_fnv1a16: - case "MT6899Z_A/ZA"_fnv1a16: return "Dimensity 8400"; - - // Dimensity 9000 Series - case "MT6983"_fnv1a16: - case "MT6983Z/CZA"_fnv1a16: - case "MT8798"_fnv1a16: - case "MT8798Z/CNZA"_fnv1a16: return "Dimensity 9000"; - - // case "MT6983"_fnv1a16: - // case "MT8798"_fnv1a16: - case "MT6983W/CZA"_fnv1a16: - case "MT8798Z/TNZA"_fnv1a16: return "Dimensity 9000+"; - - case "MT6985"_fnv1a16: - case "MT6985W/CZA"_fnv1a16: return "Dimensity 9200"; - - // case "MT6985"_fnv1a16: - case "MT6985W/TCZA"_fnv1a16: return "Dimensity 9200+"; - - case "MT6989"_fnv1a16: - case "MT6989W/CZA"_fnv1a16: - case "MT8796"_fnv1a16: - case "MT8796W/CNZA"_fnv1a16: return "Dimensity 9300"; - - // case "MT6989"_fnv1a16: - case "MT6989W/TCZA"_fnv1a16: return "Dimensity 9300+"; - - case "MT6991"_fnv1a16: - case "MT6991Z/CZA"_fnv1a16: - case "MT6991W/CZA"_fnv1a16: return "Dimensity 9400"; - } - - return model_name; -} -#endif // CF_ANDROID - -static std::string get_from_text(std::string& line) -{ - std::string amount = line.substr(line.find(':') + 1); - strip(amount); - return amount; -} - -static CPU::CPU_t get_cpu_infos() -{ - CPU::CPU_t ret; - debug("calling in CPU {}", __PRETTY_FUNCTION__); - constexpr std::string_view cpuinfo_path = "/proc/cpuinfo"; - std::ifstream file(cpuinfo_path.data()); - if (!file.is_open()) - { - error(_("Could not open {}"), cpuinfo_path); - return ret; - } - - std::string line; - float cpu_mhz = -1; - while (std::getline(file, line)) - { - if (hasStart(line, "model name")) - ret.name = get_from_text(line); - - else if (hasStart(line, "processor")) - ret.nproc = get_from_text(line); - - else if (hasStart(line, "cpu MHz")) - { - double tmp = std::stof(get_from_text(line)); - if (tmp > cpu_mhz) - cpu_mhz = tmp; - } - } - -#if CF_ANDROID - if (ret.name == UNKNOWN) - { - ret.modelname = get_android_property("ro.soc.model"); - if (ret.modelname.empty()) - { - ret.vendor = "MTK"; - ret.modelname = get_android_property("ro.mediatek.platform"); - } - if (ret.vendor.empty()) - { - ret.vendor = get_android_property("ro.soc.manufacturer"); - if (ret.vendor.empty()) - ret.vendor = get_android_property("ro.product.product.manufacturer"); - } - - if ((ret.vendor == "QTI" || ret.vendor == "QUALCOMM") && - (hasStart(ret.modelname, "SM") || hasStart(ret.modelname, "APQ") || hasStart(ret.modelname, "MSM") || - hasStart(ret.modelname, "SDM") || hasStart(ret.modelname, "QM"))) - ret.name = fmt::format("Qualcomm {} [{}]", detect_qualcomm(ret.modelname), ret.modelname); - else if (ret.vendor == "Samsung") - ret.name = fmt::format("Samsung {} [{}]", detect_exynos(ret.modelname), ret.modelname); - else if (ret.vendor == "MTK") - ret.name = fmt::format("Mediatek {} [{}]", detect_mediatek(ret.modelname), ret.modelname); - else - ret.name = ret.vendor + " " + ret.modelname; - } -#endif - - // sometimes /proc/cpuinfo at model name - // the name will contain the min freq - // happens on intel cpus especially - const size_t pos = ret.name.rfind('@'); - if (pos != std::string::npos) - ret.name.erase(pos - 1); - - cpu_mhz /= 1000; - ret.freq_max_cpuinfo = cpu_mhz; - - // add 1 to the nproc - ret.nproc = fmt::to_string(std::stoi(ret.nproc) + 1); - - const std::string freq_dir = "/sys/devices/system/cpu/cpu0/cpufreq"; - if (std::filesystem::exists(freq_dir)) - { - std::ifstream cpu_bios_limit_f(freq_dir + "/bios_limit"); - std::ifstream cpu_scaling_cur_f(freq_dir + "/scaling_cur_freq"); - std::ifstream cpu_scaling_max_f(freq_dir + "/scaling_max_freq"); - std::ifstream cpu_scaling_min_f(freq_dir + "/scaling_min_freq"); - - std::string freq_bios_limit, freq_cpu_scaling_cur, freq_cpu_scaling_max, freq_cpu_scaling_min; - - std::getline(cpu_bios_limit_f, freq_bios_limit); - std::getline(cpu_scaling_cur_f, freq_cpu_scaling_cur); - std::getline(cpu_scaling_max_f, freq_cpu_scaling_max); - std::getline(cpu_scaling_min_f, freq_cpu_scaling_min); - - ret.freq_bios_limit = freq_bios_limit.empty() ? 0 : (std::stof(freq_bios_limit) / 1000000); - ret.freq_cur = freq_cpu_scaling_cur.empty() ? 0 : (std::stof(freq_cpu_scaling_cur) / 1000000); - ret.freq_max = freq_cpu_scaling_max.empty() ? 0 : (std::stof(freq_cpu_scaling_max) / 1000000); - ret.freq_min = freq_cpu_scaling_min.empty() ? 0 : (std::stof(freq_cpu_scaling_min) / 1000000); - } - - return ret; -} - -static double get_cpu_temp() -{ -#if CF_ANDROID - // https://github.com/kamgurgul/cpu-info/blob/master/shared/src/androidMain/kotlin/com/kgurgul/cpuinfo/data/provider/TemperatureProvider.android.kt#L119 - constexpr std::array<std::string_view, 20> temp_paths = { - "/sys/devices/system/cpu/cpu0/cpufreq/cpu_temp", - "/sys/devices/system/cpu/cpu0/cpufreq/FakeShmoo_cpu_temp", - "/sys/class/thermal/thermal_zone0/temp", - "/sys/class/i2c-adapter/i2c-4/4-004c/temperature", - "/sys/devices/platform/tegra-i2c.3/i2c-4/4-004c/temperature", - "/sys/devices/platform/omap/omap_temp_sensor.0/temperature", - "/sys/devices/platform/tegra_tmon/temp1_input", - "/sys/kernel/debug/tegra_thermal/temp_tj", - "/sys/devices/platform/s5p-tmu/temperature", - "/sys/class/thermal/thermal_zone1/temp", - "/sys/class/hwmon/hwmon0/device/temp1_input", - "/sys/devices/virtual/thermal/thermal_zone1/temp", - "/sys/devices/virtual/thermal/thermal_zone0/temp", - "/sys/class/thermal/thermal_zone3/temp", - "/sys/class/thermal/thermal_zone4/temp", - "/sys/class/hwmon/hwmonX/temp1_input", - "/sys/devices/platform/s5p-tmu/curr_temp", - "/sys/htc/cpu_temp", - "/sys/devices/platform/tegra-i2c.3/i2c-4/4-004c/ext_temperature", - "/sys/devices/platform/tegra-tsensor/tsensor_temperature", - }; - for (const std::string_view path : temp_paths) - { - debug("checking {}", path); - if (!std::filesystem::exists(path)) - continue; - - const double ret = std::stod(read_by_syspath(path)) / 1000.0; - debug("cpu temp ret = {}", ret); - - if (ret >= -1.0 && ret <= 250.0) - return ret; - } -#else - for (const auto& dir : std::filesystem::directory_iterator{ "/sys/class/hwmon/" }) - { - const std::string& name = read_by_syspath((dir.path() / "name").string()); - debug("name = {}", name); - if (name != "cpu" && name != "k10temp" && name != "coretemp") - continue; - - const std::string& temp_file = std::filesystem::exists(dir.path() / "temp1_input") - ? dir.path() / "temp1_input" - : dir.path() / "device/temp1_input"; - if (!std::filesystem::exists(temp_file)) - continue; - - const double ret = std::stod(read_by_syspath(temp_file)); - debug("cpu temp ret = {}", ret); - - return ret / 1000.0; - } -#endif - - return 0.0; -} - -CPU::CPU() noexcept -{ - CHECK_INIT(m_bInit); - - m_cpu_infos = get_cpu_infos(); -} - -// clang-format off -std::string& CPU::name() noexcept -{ return m_cpu_infos.name; } - -std::string& CPU::nproc() noexcept -{ return m_cpu_infos.nproc; } - -std::string& CPU::vendor() noexcept -{ return m_cpu_infos.vendor; } - -std::string& CPU::modelname() noexcept -{ return m_cpu_infos.modelname; } - -double& CPU::freq_bios_limit() noexcept -{ return m_cpu_infos.freq_bios_limit; } - -double& CPU::freq_cur() noexcept -{ return m_cpu_infos.freq_cur; } - -double& CPU::freq_max() noexcept -{ return (m_cpu_infos.freq_max <= 0) ? m_cpu_infos.freq_max_cpuinfo : m_cpu_infos.freq_max; } - -double& CPU::freq_min() noexcept -{ return m_cpu_infos.freq_min; } - -double& CPU::temp() noexcept -{ - static bool done = false; - if (!done) - m_cpu_infos.temp = get_cpu_temp(); - done = true; - - return m_cpu_infos.temp; -} - -#endif // CF_ANDROID || CF_LINUX diff --git a/src/query/linux/disk.cpp b/src/query/linux/disk.cpp deleted file mode 100644 index 394e6e41..00000000 --- a/src/query/linux/disk.cpp +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Copyright 2025 Toni500git - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote - * products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -/* - * Copyright (c) 2021-2023 Linus Dierheimer - * Copyright (c) 2022-2024 Carter Li - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "platform.hpp" -#if CF_LINUX || CF_ANDROID - -#include <mntent.h> -#include <unistd.h> - -#include <algorithm> -#include <cstdio> -#include <cstring> -#include <string_view> - -#include "config.hpp" -#include "parse.hpp" -#include "query.hpp" -#include "util.hpp" - -using namespace Query; - -// https://github.com/fastfetch-cli/fastfetch/blob/dev/src/detection/disk/disk_linux.c -static bool is_physical_device(const mntent* device) -{ -#if !CF_ANDROID // On Android, `/dev` is not accessible, so that the following checks always fail - - // Always show the root path - if (strcmp(device->mnt_dir, "/") == 0) - return true; - - if (strcmp(device->mnt_fsname, "none") == 0) - return false; - - // DrvFs is a filesystem plugin to WSL that was designed to support interop between WSL and the Windows filesystem. - if (strcmp(device->mnt_type, "9p") == 0) - return std::string_view(device->mnt_opts).find("aname=drvfs") != std::string_view::npos; - - // ZFS pool - if (strcmp(device->mnt_type, "zfs") == 0) - return true; - - // Pseudo filesystems don't have a device in /dev - if (!hasStart(device->mnt_fsname, "/dev/")) - return false; - - // #731 - if (strcmp(device->mnt_type, "bcachefs") == 0) - return true; - - if (hasStart(device->mnt_fsname + 5, "loop") || // Ignore loop devices - hasStart(device->mnt_fsname + 5, "ram") || // Ignore ram devices - hasStart(device->mnt_fsname + 5, "fd") // Ignore fd devices - ) - return false; - - struct stat deviceStat; - if (stat(device->mnt_fsname, &deviceStat) != 0) - return false; - - // Ignore all devices that are not block devices - if (!S_ISBLK(deviceStat.st_mode)) - return false; - -#else - - // Pseudo filesystems don't have a device in /dev - if (!hasStart(device->mnt_fsname, "/dev/")) - return false; - - if (hasStart(device->mnt_fsname + 5, "loop") || // Ignore loop devices - hasStart(device->mnt_fsname + 5, "ram") || // Ignore ram devices - hasStart(device->mnt_fsname + 5, "fd") // Ignore fd devices - ) - return false; - - // https://source.android.com/docs/core/ota/apex?hl=zh-cn - if (hasStart(device->mnt_dir, "/apex/")) - return false; - -#endif // !CF_ANDROID - - return true; -} - -static bool is_removable(const mntent* device) -{ - if (!hasStart(device->mnt_fsname, "/dev/")) - return false; - - // like str.substr(5); - std::string sys_block_partition{ fmt::format("/sys/class/block/{}", (device->mnt_fsname + "/dev/"_len)) }; - // check if it's like /dev/sda1 - if (sys_block_partition.back() >= '0' && sys_block_partition.back() <= '9') - sys_block_partition.pop_back(); - - return read_by_syspath(sys_block_partition + "/removable") == "1"; -} - -static int get_disk_type(const mntent* device) -{ -#if CF_LINUX - int ret = 0; - - if (hasStart(device->mnt_dir, "/boot") || hasStart(device->mnt_dir, "/efi")) - ret = DISK_VOLUME_TYPE_HIDDEN; - else if (is_removable(device)) - ret = DISK_VOLUME_TYPE_EXTERNAL; - else - ret = DISK_VOLUME_TYPE_REGULAR; - - if (hasmntopt(device, MNTOPT_RO)) - ret |= DISK_VOLUME_TYPE_READ_ONLY; - - return ret; -#else // CF_ANDROID - if (strcmp(device->mnt_dir, "/") == 0 || strcmp(device->mnt_dir, "/storage/emulated") == 0) - return DISK_VOLUME_TYPE_REGULAR; - - if (hasStart(device->mnt_dir, "/mnt/media_rw/")) - return DISK_VOLUME_TYPE_EXTERNAL; - - return DISK_VOLUME_TYPE_HIDDEN; -#endif -} - -static std::string format_auto_query_string(std::string str, const struct mntent* device) -{ - replace_str(str, "%1", device->mnt_dir); - replace_str(str, "%2", device->mnt_fsname); - replace_str(str, "%3", device->mnt_type); - - replace_str(str, "%4", fmt::format("$<disk({}).total>", device->mnt_dir)); - replace_str(str, "%5", fmt::format("$<disk({}).free>", device->mnt_dir)); - replace_str(str, "%6", fmt::format("$<disk({}).used>", device->mnt_dir)); - replace_str(str, "%7", fmt::format("$<disk({}).used_perc>", device->mnt_dir)); - replace_str(str, "%8", fmt::format("$<disk({}).free_perc>", device->mnt_dir)); - - return str; -} - -Disk::Disk(const std::string& path, parse_args_t& parse_args, const bool auto_module) -{ - if (access(path.data(), F_OK) != 0 && !auto_module) - { - // if user is using $<disk(path)> or $<disk(path).fs> - // then let's just "try" to remove it - m_disk_infos.typefs = MAGIC_LINE; - m_disk_infos.device = MAGIC_LINE; - m_disk_infos.mountdir = MAGIC_LINE; - return; - } - - FILE* mountsFile = setmntent("/proc/mounts", "r"); - if (mountsFile == NULL) - { - perror("setmntent"); - error(_("setmntent() failed. Could not get disk info")); - return; - } - - if (auto_module) - { - struct mntent* pDevice; - while ((pDevice = getmntent(mountsFile))) - { - if (!is_physical_device(pDevice)) - continue; - - m_disk_infos.types_disk = get_disk_type(pDevice); - if (!(parse_args.config.auto_disks_types & m_disk_infos.types_disk)) - continue; - - // if (!parse_args.config.auto_disks_show_dupl) - // { - // const auto& it = std::find(m_queried_devices.begin(), m_queried_devices.end(), pDevice->mnt_fsname); - // if (it != m_queried_devices.end()) - // continue; - - // m_queried_devices.push_back(pDevice->mnt_fsname); - // } - - parse_args.no_more_reset = false; - debug("AUTO: pDevice->mnt_dir = {} && pDevice->mnt_fsname = {}", pDevice->mnt_dir, pDevice->mnt_fsname); - m_disks_formats.push_back( - parse(format_auto_query_string(parse_args.config.auto_disks_fmt, pDevice), parse_args)); - } - - endmntent(mountsFile); - return; - } - - struct mntent* pDevice; - while ((pDevice = getmntent(mountsFile))) - { - debug("pDevice->mnt_dir = {} && pDevice->mnt_fsname = {}", pDevice->mnt_dir, pDevice->mnt_fsname); - if (path == pDevice->mnt_dir || path == pDevice->mnt_fsname) - { - m_disk_infos.types_disk = get_disk_type(pDevice); - if (!(parse_args.config.auto_disks_types & m_disk_infos.types_disk)) - continue; - - m_disk_infos.typefs = pDevice->mnt_type; - m_disk_infos.device = pDevice->mnt_fsname; - m_disk_infos.mountdir = pDevice->mnt_dir; - break; - } - } - - const std::string& statpath = (hasStart(path, "/dev") && pDevice) ? pDevice->mnt_dir : path; - - struct statvfs fs; - if (statvfs(statpath.c_str(), &fs) != 0) - { - perror("statvfs"); - error(_("Failed to get disk info at {}"), statpath); - return; - } - - m_disk_infos.total_amount = static_cast<double>(fs.f_blocks * fs.f_frsize); - m_disk_infos.free_amount = static_cast<double>(fs.f_bfree * fs.f_frsize); - m_disk_infos.used_amount = m_disk_infos.total_amount - m_disk_infos.free_amount; - - endmntent(mountsFile); -} - -// clang-format off -double& Disk::total_amount() noexcept -{ return m_disk_infos.total_amount; } - -double& Disk::used_amount() noexcept -{ return m_disk_infos.used_amount; } - -double& Disk::free_amount() noexcept -{ return m_disk_infos.free_amount; } - -int& Disk::types_disk() noexcept -{ return m_disk_infos.types_disk; } - -std::string& Disk::typefs() noexcept -{ return m_disk_infos.typefs; } - -std::string& Disk::mountdir() noexcept -{ return m_disk_infos.mountdir; } - -std::string& Disk::device() noexcept -{ return m_disk_infos.device; } - -#endif // CF_LINUX || CF_ANDROID diff --git a/src/query/linux/gpu.cpp b/src/query/linux/gpu.cpp deleted file mode 100644 index f89601a3..00000000 --- a/src/query/linux/gpu.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 2025 Toni500git - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote - * products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "platform.hpp" -#if CF_LINUX - -#include <cstdint> -#include <filesystem> -#include <string> - -#include "fmt/format.h" -#include "parse.hpp" -#include "query.hpp" -#include "util.hpp" - -using namespace Query; - -static std::string get_name(const std::string_view m_vendor_id_s, const std::string_view m_device_id_s) -{ - std::string name = binarySearchPCIArray(m_vendor_id_s, m_device_id_s); - debug("GPU binarySearchPCIArray name = {}", name); - const size_t first_bracket = name.find('['); - const size_t last_bracket = name.rfind(']'); - - // remove the chips name "TU106 [GeForce GTX 1650]" - // This should work for AMD and Intel too. - if (first_bracket != std::string::npos && last_bracket != std::string::npos) - name = name.substr(first_bracket + 1, last_bracket - first_bracket - 1); - - // name = this->vendor() + ' ' + name; - - // replace_str(name, "NVIDIA Corporation", "NVIDIA"); - // replace_str(name, "Advanced Micro Devices Inc.", "AMD"); - // replace_str(name, "Intel Corporation", "Intel"); - - return name; -} - -static std::string get_vendor(const std::string_view m_vendor_id_s) -{ return binarySearchPCIArray(m_vendor_id_s); } - -static GPU::GPU_t get_gpu_infos(const std::string_view m_vendor_id_s, const std::string_view m_device_id_s) -{ - debug("calling GPU {}", __func__); - GPU::GPU_t ret; - - debug("GPU m_vendor_id_s = {} || m_device_id_s = {}", m_vendor_id_s, m_device_id_s); - if (m_device_id_s == UNKNOWN || m_vendor_id_s == UNKNOWN) - return ret; - - ret.name = get_name(m_vendor_id_s, m_device_id_s); - ret.vendor = get_vendor(m_vendor_id_s); - - return ret; -} - -GPU::GPU(const std::string& id /*, systemInfo_t& queried_gpus*/) -{ - // if (queried_gpus.find(id) != queried_gpus.end()) - // { - // m_gpu_infos.name = getInfoFromName(queried_gpus, id, "name"); - // m_gpu_infos.vendor = getInfoFromName(queried_gpus, id, "vendor"); - // return; - // } - - const std::uint16_t max_iter = 10; - std::uint16_t id_iter = std::stoi(id); - std::string sys_path; - int i = 0; - for (; i <= max_iter; i++) - { - sys_path = "/sys/class/drm/card" + fmt::to_string(id_iter); - if (std::filesystem::exists(sys_path + "/device/device") && - std::filesystem::exists(sys_path + "/device/vendor")) - break; - else - id_iter++; - } - - if (i >= max_iter) - { - error(_("Failed to parse GPU infos on the path /sys/class/drm/")); - return; - } - - m_vendor_id_s = read_by_syspath(sys_path + "/device/vendor"); - m_device_id_s = read_by_syspath(sys_path + "/device/device"); - - m_gpu_infos = get_gpu_infos(m_vendor_id_s, m_device_id_s); -} - -// clang-format off -std::string& GPU::name() noexcept -{ return m_gpu_infos.name; } - -std::string& GPU::vendor() noexcept -{ return m_gpu_infos.vendor; } - -#endif diff --git a/src/query/linux/ram.cpp b/src/query/linux/ram.cpp deleted file mode 100644 index a99acdcb..00000000 --- a/src/query/linux/ram.cpp +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright 2025 Toni500git - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote - * products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "platform.hpp" -#if CF_LINUX || CF_ANDROID - -#include <fstream> - -#include "query.hpp" -#include "util.hpp" - -using namespace Query; - -/*enum { - SHMEM = 0, - FREE, - BUFFER, - CACHED, - SRECLAIMABLE -};*/ - -static size_t get_from_text(std::string& line, u_short& iter_index, const std::uint16_t len) -{ - std::string amount = line.substr(len + 1); - strip(amount); - ++iter_index; - return std::stoi(amount); -} - -static RAM::RAM_t get_amount() noexcept -{ - debug("calling in RAM {}", __PRETTY_FUNCTION__); - constexpr std::string_view meminfo_path = "/proc/meminfo"; - RAM::RAM_t memory_infos; - - // std::array<size_t, 5> extra_mem_info; - std::ifstream file(meminfo_path.data()); - if (!file.is_open()) - { - error(_("Could not open {}\nFailed to get RAM infos"), meminfo_path); - return memory_infos; - } - - std::string line; - std::uint16_t iter_index = 0; - while (std::getline(file, line) && iter_index < 4) - { - if (hasStart(line, "MemAvailable:")) - memory_infos.free_amount = get_from_text(line, iter_index, "MemAvailable:"_len); - - else if (hasStart(line, "MemTotal:")) - memory_infos.total_amount = get_from_text(line, iter_index, "MemTotal:"_len); - - else if (hasStart(line, "SwapFree:")) - memory_infos.swap_free_amount = get_from_text(line, iter_index, "SwapFree:"_len); - - else if (hasStart(line, "SwapTotal:")) - memory_infos.swap_total_amount = get_from_text(line, iter_index, "SwapTotal:"_len); - - /*if (line.find("Shmem:") != std::string::npos) - extra_mem_info.at(SHMEM) = get_from_text(line); - - if (line.find("MemFree:") != std::string::npos) - extra_mem_info.at(FREE) = get_from_text(line); - - if (line.find("Buffers:") != std::string::npos) - extra_mem_info.at(BUFFER) = get_from_text(line); - - if (line.find("Cached:") != std::string::npos) - extra_mem_info.at(CACHED) = get_from_text(line); - - if (line.find("SReclaimable:") != std::string::npos) - extra_mem_info.at(SRECLAIMABLE) = get_from_text(line);*/ - } - - // https://github.com/dylanaraps/neofetch/wiki/Frequently-Asked-Questions#linux-is-neofetchs-memory-output-correct - memory_infos.used_amount = - memory_infos.total_amount - - memory_infos.free_amount; // + extra_mem_info.at(SHMEM) - extra_mem_info.at(FREE) - extra_mem_info.at(BUFFER) - - // extra_mem_info.at(CACHED) - extra_mem_info.at(SRECLAIMABLE); - - memory_infos.swap_used_amount = - memory_infos.swap_total_amount - - memory_infos.swap_free_amount; - - return memory_infos; -} - -RAM::RAM() noexcept -{ - CHECK_INIT(m_bInit); - - m_memory_infos = get_amount(); -} - -// clang-format off -double& RAM::free_amount() noexcept -{ return m_memory_infos.free_amount; } - -double& RAM::total_amount() noexcept -{ return m_memory_infos.total_amount; } - -double& RAM::used_amount() noexcept -{ return m_memory_infos.used_amount; } - -double& RAM::swap_total_amount() noexcept -{ return m_memory_infos.swap_total_amount; } - -double& RAM::swap_used_amount() noexcept -{ return m_memory_infos.swap_used_amount; } - -double& RAM::swap_free_amount() noexcept -{ return m_memory_infos.swap_free_amount; } - -#endif // CF_LINUX || CF_ANDROID diff --git a/src/query/linux/system.cpp b/src/query/linux/system.cpp deleted file mode 100644 index 1d127efd..00000000 --- a/src/query/linux/system.cpp +++ /dev/null @@ -1,326 +0,0 @@ -/* - * Copyright 2025 Toni500git - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote - * products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "platform.hpp" -#if CF_LINUX - -#include <linux/limits.h> -#include <unistd.h> - -#include <array> -#include <cerrno> -#include <cstdint> -#include <cstdlib> -#include <cstring> -#include <ctime> -#include <filesystem> -#include <string> - -#include "config.hpp" -#include "query.hpp" -#include "switch_fnv1a.hpp" -#include "util.hpp" -#include "utils/packages.hpp" - -using namespace Query; - -static void get_host_paths(System::System_t& paths) -{ - const std::string syspath = "/sys/devices/virtual/dmi/id"; - - if (std::filesystem::exists(syspath + "/board_name")) - { - paths.host_modelname = read_by_syspath(syspath + "/board_name"); - paths.host_version = read_by_syspath(syspath + "/board_version"); - paths.host_vendor = read_by_syspath(syspath + "/board_vendor"); - - if (paths.host_vendor == "Micro-Star International Co., Ltd.") - paths.host_vendor = "MSI"; - } - - else if (std::filesystem::exists(syspath + "/product_name")) - { - paths.host_modelname = read_by_syspath(syspath + "/product_name"); - if (hasStart(paths.host_modelname, "Standard PC")) - { - // everyone does it like "KVM/QEMU Standard PC (...) (host_version)" so why not - paths.host_vendor = "KVM/QEMU"; - paths.host_version = std::string_view('(' + read_by_syspath(syspath + "/product_version") + ')').data(); - } - else - paths.host_version = read_by_syspath(syspath + "/product_version"); - } -} - -static System::System_t get_system_infos_lsb_releases() -{ - System::System_t ret; - - debug("calling in System {}", __PRETTY_FUNCTION__); - std::string lsb_release_path; - constexpr std::array<std::string_view, 3> lsb_paths = { "/etc/lsb-release", "/usr/lib/lsb-release" }; - for (const std::string_view path : lsb_paths) - { - if (std::filesystem::exists(path)) - { - lsb_release_path = path; - break; - } - } - - std::ifstream os_release_file(lsb_release_path, std::ios::in); - if (!os_release_file.is_open()) - { - error(_("Failed to get OS infos"), lsb_release_path); - return ret; - } - - // get OS /etc/lsb-release infos - std::uint16_t iter_index = 0; - std::string line; - while (std::getline(os_release_file, line) && iter_index < 3) - { - if (hasStart(line, "DISTRIB_DESCRIPTION=")) - getFileValue(iter_index, line, ret.os_pretty_name, "DISTRIB_DESCRIPTION="_len); - - else if (hasStart(line, "DISTRIB_ID=")) - getFileValue(iter_index, line, ret.os_id, "DISTRIB_ID="_len); - - else if (hasStart(line, "DISTRIB_CODENAME=")) - getFileValue(iter_index, line, ret.os_version_codename, "DISTRIB_CODENAME="_len); - } - - return ret; -} - -static System::System_t get_system_infos_os_releases() -{ - System::System_t ret; - - debug("calling in System {}", __PRETTY_FUNCTION__); - std::string os_release_path; - constexpr std::array<std::string_view, 3> os_paths = { "/etc/os-release", "/usr/lib/os-release", - "/usr/share/os-release" }; - for (const std::string_view path : os_paths) - { - if (std::filesystem::exists(path)) - { - os_release_path = path; - break; - } - } - - std::ifstream os_release_file(os_release_path, std::ios::in); - if (!os_release_file.is_open()) - { - // error(_("Could not open '{}'\nFailed to get OS infos"), os_release_path); - return ret; - } - - // get OS /etc/os-release infos - std::uint16_t iter_index = 0; - std::string line; - while (std::getline(os_release_file, line) && iter_index < 5) - { - if (hasStart(line, "PRETTY_NAME=")) - getFileValue(iter_index, line, ret.os_pretty_name, "PRETTY_NAME="_len); - - else if (hasStart(line, "NAME=")) - getFileValue(iter_index, line, ret.os_name, "NAME="_len); - - else if (hasStart(line, "ID=")) - getFileValue(iter_index, line, ret.os_id, "ID="_len); - - else if (hasStart(line, "VERSION_ID=")) - getFileValue(iter_index, line, ret.os_version_id, "VERSION_ID="_len); - - else if (hasStart(line, "VERSION_CODENAME=")) - getFileValue(iter_index, line, ret.os_version_codename, "VERSION_CODENAME="_len); - } - - return ret; -} - -static unsigned long get_uptime() -{ - const std::string& buf = read_by_syspath("/proc/uptime"); - if (buf != UNKNOWN) - return std::stoul(buf.substr(0, buf.find('.'))); // 19065.18 190952.06 - - struct std::timespec uptime; - if (clock_gettime(CLOCK_BOOTTIME, &uptime) != 0) - return 0; - - return (unsigned long)uptime.tv_sec * 1000 + (unsigned long)uptime.tv_nsec / 1000000; -} - -System::System() -{ - CHECK_INIT(m_bInit); - - if (uname(&m_uname_infos) != 0) - die(_("uname() failed: {}\nCould not get system infos"), strerror(errno)); - - m_uptime = get_uptime(); - m_system_infos = get_system_infos_os_releases(); - if (m_system_infos.os_name == UNKNOWN || m_system_infos.os_pretty_name == UNKNOWN) - m_system_infos = get_system_infos_lsb_releases(); - - get_host_paths(m_system_infos); -} - -// clang-format off -std::string System::kernel_name() noexcept -{ return m_uname_infos.sysname; } - -std::string System::kernel_version() noexcept -{ return m_uname_infos.release; } - -std::string System::hostname() noexcept -{ return m_uname_infos.nodename; } - -std::string System::arch() noexcept -{ return m_uname_infos.machine; } - -unsigned long& System::uptime() noexcept -{ return m_uptime; } - -std::string& System::os_pretty_name() noexcept -{ return m_system_infos.os_pretty_name; } - -std::string& System::os_name() noexcept -{ return m_system_infos.os_name; } - -std::string& System::os_id() noexcept -{ return m_system_infos.os_id; } - -std::string& System::os_versionid() noexcept -{ return m_system_infos.os_version_id; } - -std::string& System::os_version_codename() noexcept -{ return m_system_infos.os_version_codename; } - -std::string& System::host_modelname() noexcept -{ return m_system_infos.host_modelname; } - -std::string& System::host_vendor() noexcept -{ return m_system_infos.host_vendor; } - -std::string& System::host_version() noexcept -{ return m_system_infos.host_version; } - -// clang-format on -std::string& System::os_initsys_name() -{ - static bool done = false; - if (done && !is_live_mode) - return m_system_infos.os_initsys_name; - - // there's no way PID 1 doesn't exist. - // This will always succeed (because we are on linux) - std::ifstream f_initsys("/proc/1/comm", std::ios::binary); - if (!f_initsys.is_open()) - die(_("/proc/1/comm doesn't exist! (what?)")); - - std::string initsys; - std::getline(f_initsys, initsys); - size_t pos = 0; - - if ((pos = initsys.find('\0')) != std::string::npos) - initsys.erase(pos); - - if ((pos = initsys.rfind('/')) != std::string::npos) - initsys.erase(0, pos + 1); - - m_system_infos.os_initsys_name = initsys; - - done = true; - - return m_system_infos.os_initsys_name; -} - -std::string& System::os_initsys_version() -{ - static bool done = false; - if (done && !is_live_mode) - return m_system_infos.os_initsys_version; - - std::string path; - char buf[PATH_MAX]; - if (realpath(which("init").c_str(), buf)) - path = buf; - - std::ifstream f(path, std::ios::in); - std::string line; - - const std::string& name = str_tolower(this->os_initsys_name()); - switch (fnv1a16::hash(name)) - { - case "systemd"_fnv1a16: - case "systemctl"_fnv1a16: - { - while (read_binary_file(f, line)) - { - if (hasEnding(line, "running in %ssystem mode (%s)")) - { - m_system_infos.os_initsys_version = line.substr("systemd "_len); - m_system_infos.os_initsys_version.erase(m_system_infos.os_initsys_version.find(' ')); - break; - } - } - } - break; - case "openrc"_fnv1a16: - { - std::string tmp; - while (read_binary_file(f, line)) - { - if (line == "RC_VERSION") - { - m_system_infos.os_initsys_version = tmp; - break; - } - tmp = line; - } - } - break; - } - done = true; - return m_system_infos.os_initsys_version; -} - -std::string& System::pkgs_installed(const Config& config) -{ - static bool done = false; - if (!done || is_live_mode) - { - m_system_infos.pkgs_installed = get_all_pkgs(config); - done = true; - } - - return m_system_infos.pkgs_installed; -} - -#endif diff --git a/src/query/linux/theme.cpp b/src/query/linux/theme.cpp deleted file mode 100644 index aa764133..00000000 --- a/src/query/linux/theme.cpp +++ /dev/null @@ -1,581 +0,0 @@ -/* - * Copyright 2025 Toni500git - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote - * products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "platform.hpp" -#if CF_LINUX - -#include <algorithm> -#include <cstdint> - -#include "config.hpp" -#include "fmt/format.h" -#include "query.hpp" -#include "rapidxml-1.13/rapidxml.hpp" -#include "switch_fnv1a.hpp" -#include "util.hpp" - -#if USE_DCONF -#include <client/dconf-client.h> -#include <glib/gvariant.h> -#endif - -/* ret_type = type of what the function returns - * func = the function name - * ... = the arguments in a function if any - */ -#undef LOAD_LIB_SYMBOL -#define LOAD_LIB_SYMBOL(ret_type, func, ...) \ - typedef ret_type (*func##_t)(__VA_ARGS__); \ - func##_t func = reinterpret_cast<func##_t>(dlsym(handle, #func)); - -using namespace Query; - -const std::string& configDir = getHomeConfigDir(); - -static bool get_xsettings_xfce4(const std::string_view property, const std::string_view subproperty, std::string& ret) -{ - static bool done = false; - static rapidxml::xml_document<> doc; - static std::string buffer; - - if (!done) - { - const std::string& path = configDir + "/xfce4/xfconf/xfce-perchannel-xml/xsettings.xml"; - std::ifstream f(path, std::ios::in); - if (!f.is_open()) - return false; - - buffer.assign(std::istreambuf_iterator<char>{ f }, std::istreambuf_iterator<char>()); - buffer.push_back('\0'); - - doc.parse<0>(&buffer[0]); - done = true; - } - - rapidxml::xml_node<>* node1 = doc.first_node("channel")->first_node("property"); - for (; node1 && std::string_view(node1->first_attribute("name")->value()) != property; - node1 = node1->next_sibling("property")) - ; - - rapidxml::xml_node<>* node2 = node1->first_node("property"); - for (; node2; node2 = node2->next_sibling()) - { - if (std::string_view(node2->first_attribute("name")->value()) == subproperty && node2->first_attribute("value")) - { - ret = node2->first_attribute("value")->value(); - return true; - } - } - - return false; -} - -// -// -// 1. Cursor -// -static bool assert_cursor(Theme::Theme_t& theme) -{ - return (theme.cursor != MAGIC_LINE && theme.cursor_size != UNKNOWN) || - (!theme.cursor.empty() && !theme.cursor_size.empty()); -} - -static bool get_cursor_xresources(Theme::Theme_t& theme) -{ - const std::string& path = expandVar("~/.Xresources"); - std::ifstream f(path, std::ios::in); - if (!f.is_open()) - { - theme.cursor = MAGIC_LINE; - theme.cursor_size = UNKNOWN; - return false; - } - - std::uint16_t iter_index = 0; - std::string line; - while (std::getline(f, line) && iter_index < 2) - { - if (hasStart(line, "Xcursor.theme:")) - { - getFileValue(iter_index, line, theme.cursor, "Xcursor.theme:"_len); - strip(theme.cursor); - } - - else if (hasStart(line, "Xcursor.size:")) - { - getFileValue(iter_index, line, theme.cursor_size, "Xcursor.size:"_len); - strip(theme.cursor_size); - } - } - - return assert_cursor(theme); -} - -static bool get_cursor_dconf(const std::string_view de_name, Theme::Theme_t& theme) -{ -#if USE_DCONF - - void* handle = LOAD_LIBRARY("libdconf.so"); - if (!handle) - return false; - - LOAD_LIB_SYMBOL(DConfClient*, dconf_client_new, void); - LOAD_LIB_SYMBOL(GVariant*, dconf_client_read, DConfClient*, const char*); - LOAD_LIB_SYMBOL(const gchar*, g_variant_get_string, GVariant*, gsize*); - LOAD_LIB_SYMBOL(gint32, g_variant_get_int32, GVariant*); - - debug("calling {}", __PRETTY_FUNCTION__); - DConfClient* client = dconf_client_new(); - GVariant* variant; - - std::string interface; - switch (fnv1a16::hash(str_tolower(de_name.data()))) - { - case "cinnamon"_fnv1a16: interface = "/org/cinnamon/desktop/interface/"; break; - case "mate"_fnv1a16: interface = "/org/mate/interface/"; break; - - case "gnome"_fnv1a16: - case "budgie"_fnv1a16: - case "unity"_fnv1a16: - default: interface = "/org/gnome/desktop/interface/"; - } - - variant = dconf_client_read(client, (interface + "cursor-theme").c_str()); - if (variant) - theme.cursor = g_variant_get_string(variant, NULL); - - variant = dconf_client_read(client, (interface + "cursor-size").c_str()); - if (variant) - theme.cursor_size = fmt::to_string(g_variant_get_int32(variant)); - - return assert_cursor(theme); -#else - return false; -#endif -} - -static bool get_cursor_gsettings(const std::string_view de_name, Theme::Theme_t& theme, const Config& config) -{ - debug("calling {}", __PRETTY_FUNCTION__); - if (get_cursor_dconf(de_name, theme)) - return true; - - if (config.slow_query_warnings) - { - warn(_( - "customfetch could not detect a gtk configuration file. customfetch will use the much-slower gsettings.")); - warn(_( - "If there's a file in a standard location that we aren't detecting, please file an issue on our GitHub.")); - info("You can disable this warning by disabling slow-query-warnings in your config.toml file."); - } - - const char* interface; - switch (fnv1a16::hash(str_tolower(de_name.data()))) - { - case "cinnamon"_fnv1a16: interface = "org.cinnamon.desktop.interface"; break; - case "mate"_fnv1a16: interface = "org.mate.interface"; break; - - case "gnome"_fnv1a16: - case "budgie"_fnv1a16: - case "unity"_fnv1a16: - default: interface = "org.gnome.desktop.interface"; - } - - if (theme.cursor == MAGIC_LINE || theme.cursor.empty()) - { - theme.cursor.clear(); - read_exec({ "gsettings", "get", interface, "cursor-theme" }, theme.cursor); - theme.cursor.erase(std::remove(theme.cursor.begin(), theme.cursor.end(), '\''), theme.cursor.end()); - } - - if (theme.cursor_size == UNKNOWN || theme.cursor_size.empty()) - { - theme.cursor_size.clear(); - read_exec({ "gsettings", "get", interface, "cursor-size" }, theme.cursor_size); - theme.cursor_size.erase(std::remove(theme.cursor_size.begin(), theme.cursor_size.end(), '\''), - theme.cursor_size.end()); - } - - return assert_cursor(theme); -} - -static bool get_gtk_cursor_config(const std::string_view path, Theme::Theme_t& theme) -{ - std::ifstream f(path.data(), std::ios::in); - if (!f.is_open()) - return false; - - std::string line; - std::uint16_t iter_index = 0; - while (std::getline(f, line) && iter_index < 2) - { - if (hasStart(line, "gtk-cursor-theme-name=")) - getFileValue(iter_index, line, theme.cursor, "gtk-cursor-theme-name="_len); - - else if (hasStart(line, "gtk-cursor-theme-size=")) - getFileValue(iter_index, line, theme.cursor_size, "gtk-cursor-theme-size="_len); - } - - return assert_cursor(theme); -} - -static bool get_cursor_from_gtk_configs(const std::uint8_t ver, Theme::Theme_t& theme) -{ - if (get_gtk_cursor_config(fmt::format("{}/gtk-{}.0/settings.ini", configDir, ver), theme)) - return true; - - if (get_gtk_cursor_config(fmt::format("{}/gtk-{}.0/gtkrc", configDir, ver), theme)) - return true; - - if (get_gtk_cursor_config(fmt::format("{}/gtkrc-{}.0", configDir, ver), theme)) - return true; - - if (get_gtk_cursor_config(fmt::format("{}/.gtkrc-{}.0", std::getenv("HOME"), ver), theme)) - return true; - - if (get_gtk_cursor_config(fmt::format("{}/.gtkrc-{}.0-kde", std::getenv("HOME"), ver), theme)) - return true; - - if (get_gtk_cursor_config(fmt::format("{}/.gtkrc-{}.0-kde4", std::getenv("HOME"), ver), theme)) - return true; - - return false; -} - -static bool get_de_cursor(const std::string_view de_name, Theme::Theme_t& theme) -{ - switch (fnv1a16::hash(str_tolower(de_name.data()))) - { - case "xfce"_fnv1a16: - case "xfce4"_fnv1a16: - { - debug("calling {} and getting info on xfce4", __PRETTY_FUNCTION__); - get_xsettings_xfce4("Gtk", "CursorThemeName", theme.cursor); - get_xsettings_xfce4("Gtk", "CursorThemeSize", theme.cursor_size); - - return assert_cursor(theme); - } - break; - } - - return false; -} - -// -// -// 2. GTK theme -// -static bool assert_gtk_theme(Theme::Theme_t& theme) -{ - return (theme.gtk_font != MAGIC_LINE && theme.gtk_icon_theme != MAGIC_LINE && theme.gtk_theme_name != MAGIC_LINE) || - (!theme.gtk_font.empty() && !theme.gtk_theme_name.empty() && !theme.gtk_icon_theme.empty()); -} - -static bool get_gtk_theme_config(const std::string_view path, Theme::Theme_t& theme) -{ - std::ifstream f(path.data(), std::ios::in); - if (!f.is_open()) - return false; - - std::string line; - std::uint16_t iter_index = 0; - while (std::getline(f, line) && iter_index < 3) - { - if (hasStart(line, "gtk-theme-name=")) - getFileValue(iter_index, line, theme.gtk_theme_name, "gtk-theme-name="_len); - - else if (hasStart(line, "gtk-icon-theme-name=")) - getFileValue(iter_index, line, theme.gtk_icon_theme, "gtk-icon-theme-name="_len); - - else if (hasStart(line, "gtk-font-name=")) - getFileValue(iter_index, line, theme.gtk_font, "gtk-font-name="_len); - } - - return assert_gtk_theme(theme); -} - -static bool get_gtk_theme_dconf(const std::string_view de_name, Theme::Theme_t& theme) -{ -#if USE_DCONF - - void* handle = LOAD_LIBRARY("libdconf.so"); - if (!handle) - return false; - - LOAD_LIB_SYMBOL(DConfClient*, dconf_client_new, void); - LOAD_LIB_SYMBOL(GVariant*, dconf_client_read, DConfClient * client, const char*); - LOAD_LIB_SYMBOL(const gchar*, g_variant_get_string, GVariant* value, gsize* lenght); - - debug("calling {}", __PRETTY_FUNCTION__); - DConfClient* client = dconf_client_new(); - GVariant* variant; - - std::string interface; - switch (fnv1a16::hash(str_tolower(de_name.data()))) - { - case "cinnamon"_fnv1a16: interface = "/org/cinnamon/desktop/interface/"; break; - case "mate"_fnv1a16: interface = "/org/mate/interface/"; break; - - case "gnome"_fnv1a16: - case "budgie"_fnv1a16: - case "unity"_fnv1a16: - default: interface = "/org/gnome/desktop/interface/"; - } - - if (theme.gtk_theme_name == MAGIC_LINE || theme.gtk_theme_name.empty()) - { - variant = dconf_client_read(client, (interface + "gtk-theme").c_str()); - if (variant) - theme.gtk_theme_name = g_variant_get_string(variant, NULL); - } - - if (theme.gtk_icon_theme == MAGIC_LINE || theme.gtk_icon_theme.empty()) - { - variant = dconf_client_read(client, (interface + "icon-theme").c_str()); - if (variant) - theme.gtk_icon_theme = g_variant_get_string(variant, NULL); - } - - if (theme.gtk_font == MAGIC_LINE || theme.gtk_font.empty()) - { - variant = dconf_client_read(client, (interface + "font-name").c_str()); - if (variant) - theme.gtk_font = g_variant_get_string(variant, NULL); - } - - return assert_gtk_theme(theme); - -#else - return false; -#endif -} - -static void get_gtk_theme_gsettings(const std::string_view de_name, Theme::Theme_t& theme, const Config& config) -{ - debug("calling {}", __PRETTY_FUNCTION__); - - if (theme.gtk_theme_name == MAGIC_LINE || theme.gtk_theme_name.empty()) - { - const char* gtk_theme_env = std::getenv("GTK_THEME"); - - if (gtk_theme_env) - theme.gtk_theme_name = gtk_theme_env; - } - - if (get_gtk_theme_dconf(de_name, theme)) - return; - - if (config.slow_query_warnings) - { - warn(_( - "customfetch could not detect a gtk configuration file. customfetch will use the much-slower gsettings.")); - warn(_( - "If there's a file in a standard location that we aren't detecting, please file an issue on our GitHub.")); - info(_("You can disable this warning by disabling slow-query-warnings in your config.toml file.")); - } - - const char* interface; - switch (fnv1a16::hash(str_tolower(de_name.data()))) - { - case "cinnamon"_fnv1a16: interface = "org.cinnamon.desktop.interface"; break; - case "mate"_fnv1a16: interface = "org.mate.interface"; break; - - case "gnome"_fnv1a16: - case "budgie"_fnv1a16: - case "unity"_fnv1a16: - default: interface = "org.gnome.desktop.interface"; - } - - if (theme.gtk_theme_name == MAGIC_LINE || theme.gtk_theme_name.empty()) - { - theme.gtk_theme_name.clear(); - read_exec({ "gsettings", "get", interface, "gtk-theme" }, theme.gtk_theme_name); - } - - if (theme.gtk_icon_theme == MAGIC_LINE || theme.gtk_icon_theme.empty()) - { - theme.gtk_icon_theme.clear(); - read_exec({ "gsettings", "get", interface, "icon-theme" }, theme.gtk_icon_theme); - } - - if (theme.gtk_font == MAGIC_LINE || theme.gtk_font.empty()) - { - theme.gtk_font.clear(); - read_exec({ "gsettings", "get", interface, "font-name" }, theme.gtk_font); - } - - theme.gtk_theme_name.erase(std::remove(theme.gtk_theme_name.begin(), theme.gtk_theme_name.end(), '\''), - theme.gtk_theme_name.end()); - theme.gtk_icon_theme.erase(std::remove(theme.gtk_icon_theme.begin(), theme.gtk_icon_theme.end(), '\''), - theme.gtk_icon_theme.end()); - theme.gtk_font.erase(std::remove(theme.gtk_font.begin(), theme.gtk_font.end(), '\''), theme.gtk_font.end()); -} - -static void get_gtk_theme_from_configs(const std::uint8_t ver, const std::string_view de_name, Theme::Theme_t& theme, - const Config& config) -{ - if (get_gtk_theme_config(fmt::format("{}/gtk-{}.0/settings.ini", configDir, ver), theme)) - return; - - if (get_gtk_theme_config(fmt::format("{}/gtk-{}.0/gtkrc", configDir, ver), theme)) - return; - - if (get_gtk_theme_config(fmt::format("{}/gtkrc-{}.0", configDir, ver), theme)) - return; - - if (get_gtk_theme_config(fmt::format("{}/.gtkrc-{}.0", std::getenv("HOME"), ver), theme)) - return; - - if (get_gtk_theme_config(fmt::format("{}/.gtkrc-{}.0-kde", std::getenv("HOME"), ver), theme)) - return; - - if (get_gtk_theme_config(fmt::format("{}/.gtkrc-{}.0-kde4", std::getenv("HOME"), ver), theme)) - return; - - get_gtk_theme_gsettings(de_name, theme, config); -} - -static void get_de_gtk_theme(const std::string_view de_name, const std::uint8_t ver, Theme::Theme_t& theme, - const Config& config) -{ - switch (fnv1a16::hash(str_tolower(de_name.data()))) - { - case "xfce"_fnv1a16: - case "xfce4"_fnv1a16: - { - debug("calling {} and getting info on xfce4", __PRETTY_FUNCTION__); - get_xsettings_xfce4("Net", "ThemeName", theme.gtk_theme_name); - get_xsettings_xfce4("Net", "IconThemeName", theme.gtk_icon_theme); - get_xsettings_xfce4("Gtk", "FontName", theme.gtk_font); - - if (!assert_gtk_theme(theme)) - get_gtk_theme_from_configs(ver, de_name, theme, config); - } - break; - - default: get_gtk_theme_from_configs(ver, de_name, theme, config); - } -} - -static void get_gtk_theme(const bool dont_query_dewm, const std::uint8_t ver, const std::string_view de_name, - Theme::Theme_t& theme, const Config& config, const bool gsettings_only) -{ - if (gsettings_only) - get_gtk_theme_gsettings(de_name, theme, config); - else if (dont_query_dewm) - get_gtk_theme_from_configs(ver, de_name, theme, config); - else - get_de_gtk_theme(de_name, ver, theme, config); -} - -// clang-format off -Theme::Theme(const std::uint8_t ver/*, systemInfo_t& queried_themes*/, - const std::string& theme_name_version, const Config& config, const bool gsettings_only) - : m_theme_name(theme_name_version)/*, - m_queried_themes(queried_themes)*/ -{ - // if (queried_themes.find(theme_name_version) != queried_themes.end()) - // return; - - const std::string& wm_name = query_user.wm_name(query_user.m_bDont_query_dewm, query_user.term_name()); - const std::string& de_name = query_user.de_name(query_user.m_bDont_query_dewm, query_user.term_name(), wm_name); - - if (((de_name != MAGIC_LINE && wm_name != MAGIC_LINE) && - de_name == wm_name) || de_name == MAGIC_LINE) - m_wmde_name = wm_name; - else - m_wmde_name = de_name; - - get_gtk_theme(query_user.m_bDont_query_dewm, ver, m_wmde_name, m_theme_infos, config, gsettings_only); - - if (m_theme_infos.gtk_theme_name.empty()) - m_theme_infos.gtk_theme_name = MAGIC_LINE; - - if (m_theme_infos.gtk_font.empty()) - m_theme_infos.gtk_font = MAGIC_LINE; - - if (m_theme_infos.gtk_icon_theme.empty()) - m_theme_infos.gtk_icon_theme = MAGIC_LINE; - - // m_queried_themes.insert( - // {m_theme_name, { - // {"theme-name", variant(m_theme_infos.gtk_theme_name)}, - // {"icon-theme-name", variant(m_theme_infos.gtk_icon_theme)}, - // {"font-name", variant(m_theme_infos.gtk_font)}, - // }} - // ); -} - -// only use it for cursor -Theme::Theme(/*systemInfo_t& queried_themes, */const Config& config, const bool gsettings_only)/* : m_queried_themes(queried_themes)*/ -{ - const std::string& wm_name = query_user.wm_name(query_user.m_bDont_query_dewm, query_user.term_name()); - const std::string& de_name = query_user.de_name(query_user.m_bDont_query_dewm, query_user.term_name(), wm_name); - - if (((de_name != MAGIC_LINE && wm_name != MAGIC_LINE) && - de_name == wm_name) || de_name == MAGIC_LINE) - m_wmde_name = wm_name; - else - m_wmde_name = de_name; - - if (gsettings_only) { get_cursor_gsettings(m_wmde_name, m_theme_infos, config); } - else if (get_de_cursor(m_wmde_name, m_theme_infos)){} - else if (get_cursor_from_gtk_configs(4, m_theme_infos)){} - else if (get_cursor_from_gtk_configs(3, m_theme_infos)){} - else if (get_cursor_from_gtk_configs(2, m_theme_infos)){} - else if (get_cursor_xresources(m_theme_infos)){} - else get_cursor_gsettings(m_wmde_name, m_theme_infos, config); - - if (m_theme_infos.cursor.empty()) - m_theme_infos.cursor = MAGIC_LINE; - else - { - size_t pos = 0; - if ((pos = m_theme_infos.cursor.rfind("cursor")) != std::string::npos) - m_theme_infos.cursor.erase(pos); - - if ((pos = m_theme_infos.cursor.rfind('_')) != std::string::npos) - m_theme_infos.cursor.erase(pos - 1); - - } - -} - -std::string Theme::gtk_theme() noexcept -{ return m_theme_infos.gtk_theme_name; } - -std::string Theme::gtk_icon_theme() noexcept -{ return m_theme_infos.gtk_icon_theme; } - -std::string Theme::gtk_font() noexcept -{ return m_theme_infos.gtk_font; } - -std::string& Theme::cursor() noexcept -{ return m_theme_infos.cursor; } - -std::string& Theme::cursor_size() noexcept -{ return m_theme_infos.cursor_size; } - -#endif // CF_LINUX diff --git a/src/query/linux/user.cpp b/src/query/linux/user.cpp deleted file mode 100644 index 599ae8cf..00000000 --- a/src/query/linux/user.cpp +++ /dev/null @@ -1,678 +0,0 @@ -/* - * Copyright 2025 Toni500git - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote - * products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "platform.hpp" -#if CF_LINUX || CF_MACOS - -#include <dlfcn.h> -#include <unistd.h> - -#include <cctype> -#include <cstdlib> -#include <cstring> -#include <filesystem> -#include <fstream> -#include <string> - -#if __has_include(<sys/socket.h>) && __has_include(<wayland-client.h>) -#include <sys/socket.h> -#include <wayland-client.h> -#endif - -// #if __has_include(<sys/socket.h>) && __has_include(<X11/Xlib.h>) -// # include <X11/Xlib.h> -// #endif - -#include "query.hpp" -#if CF_MACOS -#include "rapidxml-1.13/rapidxml.hpp" -#endif -#include "switch_fnv1a.hpp" -#include "util.hpp" -#include "utils/dewm.hpp" -#include "utils/term.hpp" - -/* ret_type = type of what the function returns - * func = the function name - * ... = the arguments in a function if any - */ -#undef LOAD_LIB_SYMBOL -#define LOAD_LIB_SYMBOL(ret_type, func, ...) \ - typedef ret_type (*func##_t)(__VA_ARGS__); \ - func##_t func = reinterpret_cast<func##_t>(dlsym(handle, #func)); - -using namespace Query; - -static std::string get_de_name() -{ - std::string ret = parse_de_env(); - debug("get_de_name = {}", ret); - if (hasStart(ret, "X-")) - ret.erase(0, 2); - - return ret; -} - -static std::string get_wm_name(std::string& wm_path_exec) -{ - std::string path, proc_name, wm_name; - const uid_t uid = getuid(); - - for (auto const& dir_entry : std::filesystem::directory_iterator{ "/proc/" }) - { - if (!std::isdigit((dir_entry.path().string().at(6)))) // /proc/5 - continue; - - path = dir_entry.path() / "loginuid"; - std::ifstream f_uid(path, std::ios::binary); - std::string s_uid; - std::getline(f_uid, s_uid); - if (std::stoul(s_uid) != uid) - continue; - - path = dir_entry.path() / "cmdline"; - std::ifstream f_cmdline(path, std::ios::binary); - std::getline(f_cmdline, proc_name); - - size_t pos = 0; - if ((pos = proc_name.find('\0')) != std::string::npos) - proc_name.erase(pos); - - if ((pos = proc_name.rfind('/')) != std::string::npos) - proc_name.erase(0, pos + 1); - - debug("WM proc_name = {}", proc_name); - - if ((wm_name = prettify_wm_name(proc_name)) == MAGIC_LINE) - continue; - - char buf[PATH_MAX]; - wm_path_exec = realpath((dir_entry.path().string() + "/exe").c_str(), buf); - break; - } - - debug("wm_name = {}", wm_name); - if (wm_name.empty()) - return MAGIC_LINE; - - return wm_name; -} - -static std::string get_de_version(const std::string_view de_name) -{ - switch (fnv1a16::hash(str_tolower(de_name.data()))) - { - case "mate"_fnv1a16: return get_mate_version(); - case "cinnamon"_fnv1a16: return get_cinnamon_version(); - - case "kde"_fnv1a16: return get_kwin_version(); - - case "xfce"_fnv1a16: - case "xfce4"_fnv1a16: return get_xfce4_version(); - - case "gnome"_fnv1a16: - case "gnome-shell"_fnv1a16: - { - std::string ret; - read_exec({ "gnome-shell", "--version" }, ret); - ret.erase(0, ret.rfind(' ')); - return ret; - } - default: - { - std::string ret; - read_exec({ de_name.data(), "--version" }, ret); - ret.erase(0, ret.rfind(' ')); - return ret; - } - } -} - -static std::string get_wm_wayland_name(std::string& wm_path_exec) -{ -#if __has_include(<sys/socket.h>) && __has_include(<wayland-client.h>) - void *handle = LOAD_LIBRARY("libwayland-client.so") - if (!handle) - return get_wm_name(wm_path_exec); - - LOAD_LIB_SYMBOL(wl_display*, wl_display_connect, const char* name) - LOAD_LIB_SYMBOL(void, wl_display_disconnect, wl_display* display) - LOAD_LIB_SYMBOL(int, wl_display_get_fd, wl_display* display) - - std::string ret = MAGIC_LINE; - - struct wl_display* display = wl_display_connect(NULL); - - struct ucred ucred; - socklen_t len = sizeof(struct ucred); - if (getsockopt(wl_display_get_fd(display), SOL_SOCKET, SO_PEERCRED, &ucred, &len) == -1) - return MAGIC_LINE; - - std::ifstream f(fmt::format("/proc/{}/comm", ucred.pid), std::ios::in); - f >> ret; - wl_display_disconnect(display); - - char buf[PATH_MAX]; - wm_path_exec = realpath(fmt::format("/proc/{}/exe", ucred.pid).c_str(), buf); - - UNLOAD_LIBRARY(handle) - - return prettify_wm_name(ret); -#else - return get_wm_name(wm_path_exec); -#endif -} - -static std::string get_shell_version(const std::string_view shell_name) -{ - std::string ret; - - if (shell_name == "nu") - ret = read_shell_exec("nu -c \"version | get version\""); - else - ret = read_shell_exec(fmt::format("{} -c 'echo \"${}_VERSION\"'", shell_name, str_toupper(shell_name.data()))); - - strip(ret); - return ret; -} - -static std::string get_shell_name(const std::string_view shell_path) -{ - return shell_path.substr(shell_path.rfind('/') + 1).data(); -} - -// clang-format off -static std::string get_term_name_env(bool get_default = false) -{ - if (getenv("SSH_TTY") != NULL) - return getenv("SSH_TTY"); - - if (getenv("KITTY_PID") != NULL || - getenv("KITTY_INSTALLATION_DIR") != NULL || - getenv("KITTY_PUBLIC_KEY") != NULL || - getenv("KITTY_WINDOW_ID") != NULL) - return "kitty"; - - if (getenv("ALACRITTY_SOCKET") != NULL || - getenv("ALACRITTY_LOG") != NULL || - getenv("ALACRITTY_WINDOW_ID") != NULL) - return "alacritty"; - - if (getenv("TERMUX_VERSION") != NULL || - getenv("TERMUX_MAIN_PACKAGE_FORMAT") != NULL) - return "com.termux"; - - if(getenv("KONSOLE_VERSION") != NULL) - return "konsole"; - - if (getenv("GNOME_TERMINAL_SCREEN") != NULL || - getenv("GNOME_TERMINAL_SERVICE") != NULL) - return "gnome-terminal"; - - if (get_default) - { - char *env = getenv("TERM_PROGRAM"); - if (env != NULL) - { - if (hasStart(env, "Apple")) - return "Apple Terminal"; - - return env; - } - - env = getenv("TERM"); - if (env != NULL) - return env; - } - - return UNKNOWN; -} -// clang-format on - -#if CF_LINUX -static std::string get_term_name(std::string& term_ver, const std::string_view osname) -{ - // customfetch -> shell -> terminal - const pid_t ppid = getppid(); - std::ifstream ppid_f(fmt::format("/proc/{}/status", ppid), std::ios::in); - std::string line, term_pid{ "0" }; - while (std::getline(ppid_f, line)) - { - if (hasStart(line, "PPid:")) - { - term_pid = line.substr("PPid:"_len); - strip(term_pid); - break; - } - } - debug("term_pid = {}", term_pid); - - if (std::stoi(term_pid) < 1) - return MAGIC_LINE; - - std::ifstream f("/proc/" + term_pid + "/comm", std::ios::in); - std::string term_name; - if (f.is_open()) - std::getline(f, term_name); - else - term_name = get_term_name_env(true); - - // st (suckless terminal) - if (term_name == "exe") - term_name = "st"; - - // either gnome-console or "gnome-terminal-" - // I hope this is not super stupid - if (hasStart(term_name, "gnome-console")) - term_name.erase("gnome-console"_len + 1); - else if (hasStart(term_name, "gnome-terminal")) - term_name.erase("gnome-terminal"_len + 1); - - // let's try to get the real terminal name - // on NixOS, instead of returning the -wrapped name. - // tested on gnome-console, kitty, st and alacritty - // hope now NixOS users will know the terminal they got, along the version if possible - if (osname.find("NixOS") != osname.npos || (hasEnding(term_name, "wrapped") && which("nix") != UNKNOWN)) - { - // /nix/store/sha256string-gnome-console-0.31.0/bin/.kgx-wrapped - char buf[PATH_MAX]; - std::string tmp_name = realpath(("/proc/" + term_pid + "/exe").c_str(), buf); - - size_t pos; - if ((pos = tmp_name.find('-')) != std::string::npos) - tmp_name.erase(0, pos + 1); // gnome-console-0.31.0/bin/.kgx-wrapped - - if ((pos = tmp_name.find('/')) != std::string::npos) - tmp_name.erase(pos); // gnome-console-0.31.0 - - if ((pos = tmp_name.rfind('-')) != std::string::npos) - { - term_ver = tmp_name.substr(pos + 1); - tmp_name.erase(pos); // gnome-console EZ - } - - term_name = tmp_name; - } - - // sometimes may happen that the terminal name from /comm - // at the end has some letfover characters from /cmdline - if (!std::isalnum(term_name.back())) - { - size_t i = term_name.size(); - while (i > 0) - { - char ch = term_name[i - 1]; - // stop when we find an a num or alpha char - // example with "gnome-terminal-" - if (std::isalnum(static_cast<unsigned char>(ch))) - break; - term_name.erase(--i, 1); - } - } - - return term_name; -} -#elif CF_MACOS -#include <libproc.h> -#include <sys/proc_info.h> -#include <sys/sysctl.h> - -pid_t get_ppid(pid_t pid) -{ - struct kinfo_proc info; - size_t len = sizeof(info); - int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid }; - if (sysctl(mib, 4, &info, &len, NULL, 0) == -1) - return -1; - return info.kp_eproc.e_ppid; -} - -static std::string get_term_name(std::string& term_ver, const std::string_view osname) -{ - std::string term{ get_term_name_env() }; - if (term != UNKNOWN) - return term; - - // customfetch -> shell -> terminal - pid_t terminal_pid = 0; - pid_t current = getpid(); - while ((current = get_ppid(current)) > 1) - { - terminal_pid = current; - debug("Terminal PID: {}", terminal_pid); - } - - char pathbuf[PROC_PIDPATHINFO_MAXSIZE]; - if (proc_pidpath(terminal_pid, pathbuf, sizeof(pathbuf)) <= 0) - return UNKNOWN; - - std::string path{ pathbuf }; - if (hasEnding(path, "Terminal.app/Contents/MacOS/Terminal")) - return "Apple Terminal"; - - size_t pos = path.rfind('/'); - if (pos != path.npos) - path.erase(0, pos + 1); - - return path; -} -#endif - -static std::string get_term_version(const std::string_view term_name) -{ - if (term_name.empty()) - return UNKNOWN; - - bool remove_term_name = true; - std::string ret; - -#if CF_MACOS - if (term_name == "Apple Terminal") - { - std::ifstream f("/System/Applications/Utilities/Terminal.app/Contents/version.plist", std::ios::in); - if (!f.is_open()) - goto skip; - - std::string buffer(std::istreambuf_iterator<char>{ f }, std::istreambuf_iterator<char>{}); - buffer.push_back('\0'); - - rapidxml::xml_document<> doc; - doc.parse<0>(&buffer[0]); - rapidxml::xml_node<>* root_node = doc.first_node("plist")->first_node("dict")->first_node("key"); - - for (; root_node; root_node = root_node->next_sibling()) - { - const std::string_view key = root_node->value(); // <key>ProductName</key> - root_node = root_node->next_sibling(); - const std::string_view value = root_node->value(); // <string>macOS</string> - if (key == "CFBundleVersion") - return value.data(); - } - } - -skip: -#endif - - switch (fnv1a16::hash(str_tolower(term_name.data()))) - { - case "st"_fnv1a16: - if (fast_detect_st_ver(ret)) - remove_term_name = false; - break; - - case "konsole"_fnv1a16: - if (fast_detect_konsole_ver(ret)) - remove_term_name = false; - break; - - case "xterm"_fnv1a16: get_term_version_exec(term_name, ret, true); break; - - default: get_term_version_exec(term_name, ret); - } - - debug("get_term_version ret = {}", ret); - - if (ret.empty()) - return UNKNOWN; - - if (hasStart(ret, "# GNOME")) - { - if (hasStart(ret, "# GNOME Console ")) - ret.erase(0, "# GNOME Console"_len); - else if (hasStart(ret, "# GNOME Terminal ")) - ret.erase(0, "# GNOME Terminal "_len); - debug("gnome ret = {}", ret); - remove_term_name = false; - } - // Xterm(388) - else if (term_name == "xterm") - { - ret.erase(0, term_name.length() + 1); // 388) - ret.pop_back(); // 388 - return ret; - } - - if (remove_term_name) - ret.erase(0, term_name.length() + 1); - - const size_t pos = ret.find(' '); - if (pos != std::string::npos) - ret.erase(pos); - - debug("get_term_version ret after = {}", ret); - return ret; -} - -User::User() noexcept -{ - CHECK_INIT(m_bInit); - - if (m_pPwd = getpwuid(getuid()), !m_pPwd) - die(_("getpwent failed: {}\nCould not get user infos"), std::strerror(errno)); -} - -// clang-format off -std::string User::name() noexcept -{ return m_pPwd->pw_name; } - -std::string User::shell_path() noexcept -{ return m_pPwd->pw_shell; } - -// clang-format on -// Be ready to loose some brain cells from now on -std::string& User::shell_name() noexcept -{ - static bool done = false; - if (!done) - { - m_users_infos.shell_name = get_shell_name(this->shell_path()); - done = true; - } - - return m_users_infos.shell_name; -} - -std::string& User::shell_version(const std::string_view shell_name) -{ - if (m_users_infos.shell_name.empty()) - { - m_users_infos.shell_version = UNKNOWN; - return m_users_infos.shell_version; - } - - static bool done = false; - if (!done) - { - m_users_infos.shell_version = get_shell_version(shell_name); - done = true; - } - - return m_users_infos.shell_version; -} - -std::string& User::wm_name(bool dont_query_dewm, const std::string_view term_name) -{ - if (dont_query_dewm || hasStart(term_name, "/dev") || CF_MACOS) - { - m_users_infos.wm_name = MAGIC_LINE; - return m_users_infos.wm_name; - } - - static bool done = false; - debug("CALLING {} || done = {} && de_name = {} && wm_name = {}", __func__, done, m_users_infos.de_name, - m_users_infos.wm_name); - - if (!done) - { - const char* env = std::getenv("WAYLAND_DISPLAY"); - if (env != nullptr && env[0] != '\0') - m_users_infos.wm_name = get_wm_wayland_name(m_users_infos.m_wm_path); - else - m_users_infos.wm_name = get_wm_name(m_users_infos.m_wm_path); - - if (m_users_infos.de_name == m_users_infos.wm_name) - m_users_infos.de_name = MAGIC_LINE; - - done = true; - } - - return m_users_infos.wm_name; -} - -std::string& User::wm_version(bool dont_query_dewm, const std::string_view term_name) -{ - if (dont_query_dewm || hasStart(term_name, "/dev") || CF_MACOS) - { - m_users_infos.wm_name = MAGIC_LINE; - return m_users_infos.wm_name; - } - - static bool done = false; - if (!done) - { - m_users_infos.wm_version.clear(); - if (m_users_infos.wm_name == "Xfwm4" && - get_fast_xfwm4_version(m_users_infos.wm_version, m_users_infos.m_wm_path)) - { - done = true; - goto _return; - } - - if (m_users_infos.wm_name == "dwm") - read_exec({ m_users_infos.m_wm_path.c_str(), "-v" }, m_users_infos.wm_version, true); - else - read_exec({ m_users_infos.m_wm_path.c_str(), "--version" }, m_users_infos.wm_version); - - if (m_users_infos.wm_name == "Xfwm4") - m_users_infos.wm_version.erase(0, "\tThis is xfwm4 version "_len); // saying only "xfwm4 4.18.2 etc." no? - else - m_users_infos.wm_version.erase(0, m_users_infos.wm_name.length() + 1); - - const size_t pos = m_users_infos.wm_version.find(' '); - if (pos != std::string::npos) - m_users_infos.wm_version.erase(pos); - - done = true; - } - -_return: - return m_users_infos.wm_version; -} - -std::string& User::de_name(bool dont_query_dewm, const std::string_view term_name, const std::string_view wm_name) -{ - // first let's see if we are not in a tty or if the user doesn't want to - // if so don't even try to get the DE or WM names - // they waste times - if (dont_query_dewm || hasStart(term_name, "/dev") || CF_MACOS) - { - m_users_infos.de_name = MAGIC_LINE; - return m_users_infos.de_name; - } - - static bool done = false; - debug("CALLING {} || done = {} && de_name = {} && wm_name = {}", __func__, done, m_users_infos.de_name, - m_users_infos.wm_name); - - if (!done) - { - if ((m_users_infos.de_name != MAGIC_LINE && wm_name != MAGIC_LINE) && m_users_infos.de_name == wm_name) - { - m_users_infos.de_name = MAGIC_LINE; - done = true; - return m_users_infos.de_name; - } - - m_users_infos.de_name = get_de_name(); - if (m_users_infos.de_name == m_users_infos.wm_name) - m_users_infos.de_name = MAGIC_LINE; - - done = true; - } - - return m_users_infos.de_name; -} - -std::string& User::de_version(const std::string_view de_name) -{ - if (m_bDont_query_dewm || de_name == UNKNOWN || de_name == MAGIC_LINE || de_name.empty() || CF_MACOS) - { - m_users_infos.de_version = UNKNOWN; - return m_users_infos.de_version; - } - - static bool done = false; - if (!done) - { - m_users_infos.de_version = get_de_version(str_tolower(de_name.data())); - done = true; - } - - return m_users_infos.de_version; -} - -std::string& User::term_name() -{ - static bool done = false; - if (done || is_live_mode) - return m_users_infos.term_name; - - Query::System query_sys; - m_users_infos.term_name = get_term_name(m_users_infos.term_version, query_sys.os_name()); - if (hasStart(str_tolower(m_users_infos.term_name), "login") || hasStart(m_users_infos.term_name, "init") || - hasStart(m_users_infos.term_name, "(init)")) - { - m_users_infos.term_name = ttyname(STDIN_FILENO); - m_users_infos.term_version = "NO VERSIONS ABOSULETY"; // lets not make it unknown - m_bDont_query_dewm = true; - } - - done = true; - - return m_users_infos.term_name; -} - -std::string& User::term_version(const std::string_view term_name) -{ - static bool done = false; - if (done || is_live_mode) - return m_users_infos.term_version; - - if (m_users_infos.term_version == "NO VERSIONS ABOSULETY") - { - m_users_infos.term_version.clear(); - goto done; - } - else if (m_users_infos.term_version != MAGIC_LINE) - goto done; - - m_users_infos.term_version = get_term_version(term_name); -done: - done = true; - - return m_users_infos.term_version; -} - -#endif // CF_LINUX diff --git a/src/query/macos/battery.cpp b/src/query/macos/battery.cpp deleted file mode 100644 index c60f9f3a..00000000 --- a/src/query/macos/battery.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2025 Toni500git - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote - * products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "platform.hpp" -#if CF_MACOS - -#include "query.hpp" -using namespace Query; - -Battery::Battery() -{ - CHECK_INIT(m_bInit); -} - -// clang-format off -std::string& Battery::modelname() noexcept -{ return m_battery_infos.modelname; } - -std::string& Battery::status() noexcept -{ return m_battery_infos.status; } - -std::string& Battery::vendor() noexcept -{ return m_battery_infos.vendor; } - -std::string& Battery::technology() noexcept -{ return m_battery_infos.technology; } - -std::string& Battery::capacity_level() noexcept -{ return m_battery_infos.capacity_level; } - -double& Battery::perc() noexcept -{ return m_battery_infos.perc; } - -double& Battery::temp() noexcept -{ return m_battery_infos.temp; } - -#endif // CF_LINUX diff --git a/src/query/macos/cpu.cpp b/src/query/macos/cpu.cpp deleted file mode 100644 index 323db80c..00000000 --- a/src/query/macos/cpu.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright 2025 Toni500git - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote - * products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "platform.hpp" -#if CF_MACOS - -#include <sys/sysctl.h> -#include <unistd.h> - -#include <ratio> -#include <string> - -#include "query.hpp" -#include "util.hpp" - -using namespace Query; - -static bool get_sysctl(int name[2], void* ret, size_t* oldlenp) -{ - return (sysctl(name, 2, ret, oldlenp, NULL, 0) == 0); -} - -static bool get_sysctl(const char* name, void* ret, size_t* oldlenp) -{ - return (sysctlbyname(name, ret, oldlenp, NULL, 0) == 0); -} - -static CPU::CPU_t get_cpu_infos() -{ - CPU::CPU_t ret; - debug("calling in CPU {}", __PRETTY_FUNCTION__); - char buf[1024]; - size_t len = sizeof(buf); - - get_sysctl("machdep.cpu.brand_string", &buf, &len); - ret.name = buf; - - if (!(get_sysctl("machdep.cpu.vendor", &buf, &len)) && hasStart(ret.name, "Apple")) - ret.vendor = "Apple"; - else - ret.vendor = buf; - - if (!get_sysctl("hw.logicalcpu_max", &buf, &len)) - get_sysctl("hw.ncpu", &buf, &len); - ret.nproc = buf; - - uint64_t freq_cur = 0, freq_max = 0, freq_min; - size_t length = sizeof(freq_cur); - get_sysctl("hw.cpufrequency_max", &freq_max, &length); - get_sysctl("hw.cpufrequency_min", &freq_min, &length); - - if (!get_sysctl("hw.cpufrequency", &freq_cur, &length)) - get_sysctl((int[]){ CTL_HW, HW_CPU_FREQ }, &freq_cur, &length); - - ret.freq_cur = static_cast<double>(freq_cur) / std::giga().num; - ret.freq_max = static_cast<double>(freq_max) / std::giga().num; - ret.freq_min = static_cast<double>(freq_min) / std::giga().num; - return ret; -} - -CPU::CPU() noexcept -{ - CHECK_INIT(m_bInit); - - m_cpu_infos = get_cpu_infos(); -} - -// clang-format off -std::string& CPU::name() noexcept -{ return m_cpu_infos.name; } - -std::string& CPU::nproc() noexcept -{ return m_cpu_infos.nproc; } - -std::string& CPU::vendor() noexcept -{ return m_cpu_infos.vendor; } - -std::string& CPU::modelname() noexcept -{ return m_cpu_infos.modelname; } - -double& CPU::temp() noexcept -{ return m_cpu_infos.temp; } - -double& CPU::freq_bios_limit() noexcept -{ return m_cpu_infos.freq_bios_limit; } - -double& CPU::freq_cur() noexcept -{ return m_cpu_infos.freq_cur; } - -double& CPU::freq_max() noexcept -{ return (m_cpu_infos.freq_max <= 0) ? m_cpu_infos.freq_max_cpuinfo : m_cpu_infos.freq_max; } - -double& CPU::freq_min() noexcept -{ return m_cpu_infos.freq_min; } - -#endif // CF_MACOS diff --git a/src/query/macos/disk.cpp b/src/query/macos/disk.cpp deleted file mode 100644 index a41e7348..00000000 --- a/src/query/macos/disk.cpp +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright 2025 Toni500git - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote - * products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "platform.hpp" -#if CF_MACOS - -#include <sys/types.h> - -#include <cstring> - -#include "query.hpp" -#include "util.hpp" - -using namespace Query; - -static std::string format_auto_query_string(std::string str, const struct statfs* fs) -{ - replace_str(str, "%1", fs->f_mntonname); - replace_str(str, "%2", fs->f_mntfromname); - replace_str(str, "%3", fs->f_fstypename); - - replace_str(str, "%4", fmt::format("$<disk({}).total>", fs->f_mntonname)); - replace_str(str, "%5", fmt::format("$<disk({}).free>", fs->f_mntonname)); - replace_str(str, "%6", fmt::format("$<disk({}).used>", fs->f_mntonname)); - replace_str(str, "%7", fmt::format("$<disk({}).used_perc>", fs->f_mntonname)); - replace_str(str, "%8", fmt::format("$<disk({}).free_perc>", fs->f_mntonname)); - - return str; -} - -static int get_disk_type(const int flags) -{ - int type = 0; - if (flags & MNT_DONTBROWSE) - type = DISK_VOLUME_TYPE_HIDDEN; - else if (flags & MNT_REMOVABLE || !(flags & MNT_LOCAL)) - type = DISK_VOLUME_TYPE_EXTERNAL; - else - type = DISK_VOLUME_TYPE_REGULAR; - - if (flags & MNT_RDONLY) - type |= DISK_VOLUME_TYPE_READ_ONLY; - - return type; -} - -Disk::Disk(const std::string& path, modulesInfo_t& queried_paths, parse_args_t& parse_args, const bool auto_module) -{ - if (queried_paths.find(path) != queried_paths.end() && !is_live_mode) - { - m_disk_infos.device = getInfoFromName(queried_paths, path, "device"); - m_disk_infos.mountdir = getInfoFromName(queried_paths, path, "mountdir"); - m_disk_infos.typefs = getInfoFromName(queried_paths, path, "typefs"); - m_disk_infos.total_amount = std::stod(getInfoFromName(queried_paths, path, "total_amount")); - m_disk_infos.used_amount = std::stod(getInfoFromName(queried_paths, path, "used_amount")); - m_disk_infos.free_amount = std::stod(getInfoFromName(queried_paths, path, "free_amount")); - return; - } - - if (access(path.data(), F_OK) != 0 && !auto_module) - { - // if user is using $<disk(path)> or $<disk(path).fs> - // then let's just "try" to remove it - m_disk_infos.typefs = MAGIC_LINE; - m_disk_infos.device = MAGIC_LINE; - m_disk_infos.mountdir = MAGIC_LINE; - return; - } - - if (auto_module) - { - const int size = getfsstat(NULL, 0, MNT_WAIT); - if (size <= 0) - die(_("Failed to get Disk infos")); - - struct statfs* buf = reinterpret_cast<struct statfs*>(malloc(sizeof(*buf) * (unsigned)size)); - if (getfsstat(buf, (int)(sizeof(*buf) * (unsigned)size), MNT_NOWAIT) <= 0) - die(_("Failed to get Disk infos")); - - for (struct statfs* fs = buf; fs < buf + size; ++fs) - { - if (strcmp(fs->f_mntonname, "/") != 0 && !hasStart(fs->f_mntfromname, "/dev/")) - continue; - - m_disk_infos.types_disk = get_disk_type(fs->f_flags); - if (!(parse_args.config.auto_disks_types & m_disk_infos.types_disk)) - continue; - - if (!parse_args.config.auto_disks_show_dupl) - { - const auto& it = std::find(m_queried_devices.begin(), m_queried_devices.end(), fs->f_mntfromname); - if (it != m_queried_devices.end()) - continue; - - m_queried_devices.push_back(fs->f_mntfromname); - } - - parse_args.no_more_reset = false; - m_disks_formats.push_back( - parse(format_auto_query_string(parse_args.config.auto_disks_fmt, fs), parse_args)); - } - - free(buf); - return; - } - - struct statfs fs; - if (statfs(path.c_str(), &fs) != 0) - { - perror("statvfs"); - error(_("Failed to get disk info at {}"), path); - return; - } - - if (path != fs.f_mntonname && path != fs.f_mntfromname) - return; - - m_disk_infos.typefs = fs.f_fstypename; - m_disk_infos.device = fs.f_mntfromname; - m_disk_infos.mountdir = fs.f_mntonname; - - m_disk_infos.total_amount = static_cast<double>(fs.f_blocks * fs.f_bsize); - m_disk_infos.free_amount = static_cast<double>(fs.f_bfree * fs.f_bsize); - m_disk_infos.used_amount = m_disk_infos.total_amount - m_disk_infos.free_amount; - - queried_paths.insert({ path, - { { "total_amount", variant(m_disk_infos.total_amount) }, - { "used_amount", variant(m_disk_infos.used_amount) }, - { "free_amount", variant(m_disk_infos.free_amount) }, - { "typefs", variant(m_disk_infos.typefs) }, - { "mountdir", variant(m_disk_infos.mountdir) }, - { "device", variant(m_disk_infos.device) } } }); -} - -// clang-format off -double& Disk::total_amount() noexcept -{ return m_disk_infos.total_amount; } - -double& Disk::used_amount() noexcept -{ return m_disk_infos.used_amount; } - -double& Disk::free_amount() noexcept -{ return m_disk_infos.free_amount; } - -int& Disk::types_disk() noexcept -{ return m_disk_infos.types_disk; } - -std::string& Disk::typefs() noexcept -{ return m_disk_infos.typefs; } - -std::string& Disk::mountdir() noexcept -{ return m_disk_infos.mountdir; } - -std::string& Disk::device() noexcept -{ return m_disk_infos.device; } - -#endif // CF_MACOS diff --git a/src/query/macos/gpu.cpp b/src/query/macos/gpu.cpp deleted file mode 100644 index e9bfffd2..00000000 --- a/src/query/macos/gpu.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2025 Toni500git - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote - * products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "platform.hpp" -#if CF_MACOS - -#include "query.hpp" - -using namespace Query; - -GPU::GPU(const std::string& id, modulesInfo_t& queried_gpus) {} - -// clang-format off -std::string& GPU::name() noexcept -{ return m_gpu_infos.name; } - -std::string& GPU::vendor() noexcept -{ return m_gpu_infos.vendor; } - -#endif diff --git a/src/query/macos/ram.cpp b/src/query/macos/ram.cpp deleted file mode 100644 index 9a3376fe..00000000 --- a/src/query/macos/ram.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright 2025 Toni500git - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote - * products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "platform.hpp" -#if CF_MACOS - -#include <mach/mach.h> -#include <sys/sysctl.h> -#include <unistd.h> - -#include <cstdint> - -#include "query.hpp" -#include "util.hpp" - -using namespace Query; - -// https://github.com/fastfetch-cli/fastfetch/blob/dev/src/detection/memory/memory_apple.c -static RAM::RAM_t get_amount() -{ - RAM::RAM_t ret; - uint64_t total = 0, used = 0, page_size = 0; - int name[2] = { CTL_HW, HW_MEMSIZE }; - size_t length = sizeof(total); - if (sysctl(name, 2, &total, &length, NULL, 0)) - die(_("Failed to get RAM infos")); - - name[0] = CTL_HW; - name[1] = HW_PAGESIZE; - sysctl(name, 2, &page_size, &length, NULL, 0); - mach_msg_type_number_t count = HOST_VM_INFO64_COUNT; - vm_statistics64_data_t vmstat; - if (host_statistics64(mach_host_self(), HOST_VM_INFO64, (host_info64_t)(&vmstat), &count) != KERN_SUCCESS) - die(_("Failed to read host_statistics64")); - - // https://github.com/exelban/stats/blob/master/Modules/RAM/readers.swift#L56 - used = ((uint64_t) - + vmstat.active_count - + vmstat.inactive_count - + vmstat.speculative_count - + vmstat.wire_count - + vmstat.compressor_page_count - - vmstat.purgeable_count - - vmstat.external_page_count - ) * page_size; - - ret.total_amount = static_cast<double>(total) / 1024; - ret.used_amount = static_cast<double>(used) / 1024; - // I have just now saw fastfetch doesn't have a way to know free memory - // why?? - ret.free_amount = ret.total_amount - ret.used_amount; - - struct xsw_usage xsw; - length = sizeof(xsw); - name[0] = CTL_VM; - name[1] = VM_SWAPUSAGE; - if (sysctl(name, 2, &xsw, &length, NULL, 0) != 0) - return ret; - - ret.swap_total_amount = static_cast<double>(xsw.xsu_total); - ret.swap_used_amount = static_cast<double>(xsw.xsu_used); - ret.swap_free_amount = static_cast<double>(xsw.xsu_avail); - - return ret; -} - -RAM::RAM() noexcept -{ - CHECK_INIT(m_bInit); - - m_memory_infos = get_amount(); -} - -// clang-format off -double& RAM::free_amount() noexcept -{ return m_memory_infos.free_amount; } - -double& RAM::total_amount() noexcept -{ return m_memory_infos.total_amount; } - -double& RAM::used_amount() noexcept -{ return m_memory_infos.used_amount; } - -double& RAM::swap_total_amount() noexcept -{ return m_memory_infos.swap_total_amount; } - -double& RAM::swap_used_amount() noexcept -{ return m_memory_infos.swap_used_amount; } - -double& RAM::swap_free_amount() noexcept -{ return m_memory_infos.swap_free_amount; } - -#endif // CF_MACOS diff --git a/src/query/macos/system.cpp b/src/query/macos/system.cpp deleted file mode 100644 index 36e6739b..00000000 --- a/src/query/macos/system.cpp +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright 2025 Toni500git - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote - * products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "platform.hpp" -#if CF_MACOS - -#include <sys/sysctl.h> -#include <sys/time.h> - -#include <string_view> - -#include "query.hpp" -#include "rapidxml-1.13/rapidxml.hpp" -#include "switch_fnv1a.hpp" -#include "util.hpp" - -using namespace Query; - -static std::string get_codename(const std::string_view os_version_id) -{ - std::string major; - std::string minor{ UNKNOWN }; - size_t pos1 = os_version_id.find('.'); - if (pos1 != os_version_id.npos) - { - major = os_version_id.substr(0, pos1); - size_t pos2 = os_version_id.find('.', pos1 + 1); - if (pos2 != os_version_id.npos) - minor = os_version_id.substr(pos1 + 1, pos2); - } - - switch (fnv1a16::hash(major)) - { - case "15"_fnv1a16: return "Sequoia"; - case "14"_fnv1a16: return "Sonoma"; - case "13"_fnv1a16: return "Ventura"; - case "12"_fnv1a16: return "Monterey"; - case "11"_fnv1a16: return "Big Sur"; - case "10"_fnv1a16: - { - switch (fnv1a16::hash(minor)) - { - case "16"_fnv1a16: return "Big Sur"; - case "15"_fnv1a16: return "Catalina"; - case "14"_fnv1a16: return "Mojave"; - case "13"_fnv1a16: return "High Sierra"; - case "12"_fnv1a16: return "Sierra"; - case "11"_fnv1a16: return "El Capitan"; - case "10"_fnv1a16: return "Yosemite"; - case "9"_fnv1a16: return "Mavericks"; - case "8"_fnv1a16: return "Mountain Lion"; - case "7"_fnv1a16: return "Lion"; - case "6"_fnv1a16: return "Snow Leopard"; - case "5"_fnv1a16: return "Leopard"; - case "4"_fnv1a16: return "Tiger"; - case "3"_fnv1a16: return "Panther"; - case "2"_fnv1a16: return "Jaguar"; - case "1"_fnv1a16: return "Puma"; - case "0"_fnv1a16: return "Cheetah"; - } - } - } - - return UNKNOWN; -} - -static System::System_t get_os_infos() -{ - System::System_t ret; - std::ifstream f("/System/Library/CoreServices/SystemVersion.plist", std::ios::in); - if (!f.is_open()) - die("Couldn't get MacOS base infos"); - - std::string buffer(std::istreambuf_iterator<char>{ f }, std::istreambuf_iterator<char>{}); - buffer.push_back('\0'); - - rapidxml::xml_document<> doc; - doc.parse<0>(&buffer[0]); - rapidxml::xml_node<>* root_node = doc.first_node("plist")->first_node("dict")->first_node("key"); - - for (; root_node; root_node = root_node->next_sibling()) - { - const std::string_view key = root_node->value(); // <key>ProductName</key> - root_node = root_node->next_sibling(); - const std::string_view value = root_node->value(); // <string>macOS</string> - if (key == "ProductName") - ret.os_name = value; - else if (key == "ProductUserVisibleVersion") - ret.os_version_id = value; - } - ret.os_pretty_name = ret.os_name + " " + ret.os_version_id; - - ret.os_version_codename = get_codename(ret.os_version_id); - if (ret.os_version_codename != UNKNOWN) - ret.os_pretty_name += " (" + ret.os_version_codename + ")"; - - return ret; -} - -System::System() -{ - CHECK_INIT(m_bInit); - - if (uname(&m_uname_infos) != 0) - die(_("uname() failed: {}\nCould not get system infos"), strerror(errno)); - - struct timeval boot_time; - size_t size = sizeof(boot_time); - int name[] = { CTL_KERN, KERN_BOOTTIME }; - if (sysctl(name, 2, &boot_time, &size, NULL, 0) != 0) - die(_("failed to get uptime")); - - m_uptime = time(NULL) - boot_time.tv_sec; - m_system_infos = get_os_infos(); -} - -// clang-format off -std::string System::kernel_name() noexcept -{ return m_uname_infos.sysname; } - -std::string System::kernel_version() noexcept -{ return m_uname_infos.release; } - -std::string System::hostname() noexcept -{ return m_uname_infos.nodename; } - -std::string System::arch() noexcept -{ return m_uname_infos.machine; } - -unsigned long& System::uptime() noexcept -{ return m_uptime; } - -std::string& System::os_pretty_name() noexcept -{ return m_system_infos.os_pretty_name; } - -std::string& System::os_name() noexcept -{ return m_system_infos.os_name; } - -std::string& System::os_id() noexcept -{ return m_system_infos.os_id; } - -std::string& System::os_versionid() noexcept -{ return m_system_infos.os_version_id; } - -std::string& System::os_version_codename() noexcept -{ return m_system_infos.os_version_codename; } - -std::string& System::host_modelname() noexcept -{ return m_system_infos.host_modelname; } - -std::string& System::host_vendor() noexcept -{ return m_system_infos.host_vendor; } - -std::string& System::host_version() noexcept -{ return m_system_infos.host_version; } - -std::string& System::os_initsys_name() -{ return m_system_infos.os_initsys_name; } - -std::string& System::os_initsys_version() -{ return m_system_infos.os_initsys_version; } - -std::string& System::pkgs_installed(const Config& config) -{ return m_system_infos.pkgs_installed; } - -#endif // !CF_MACOS diff --git a/src/query/macos/theme.cpp b/src/query/macos/theme.cpp deleted file mode 100644 index 9f2b07cf..00000000 --- a/src/query/macos/theme.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2025 Toni500git - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote - * products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "platform.hpp" -#if CF_MACOS - -#include "query.hpp" -#include "util.hpp" - -using namespace Query; - -Theme::Theme(const std::uint8_t ver, modulesInfo_t& queried_themes, const std::string& theme_name_version, - const Config& config, const bool gsettings_only) - : m_queried_themes(queried_themes) -{ - m_theme_infos.cursor = m_theme_infos.gtk_font = m_theme_infos.cursor_size = m_theme_infos.gtk_theme_name = - m_theme_infos.gtk_icon_theme = MAGIC_LINE; -} - -Theme::Theme(modulesInfo_t& queried_themes, const Config& config, const bool gsettings_only) - : m_queried_themes(queried_themes) -{ - m_theme_infos.cursor = m_theme_infos.gtk_font = m_theme_infos.cursor_size = m_theme_infos.gtk_theme_name = - m_theme_infos.gtk_icon_theme = MAGIC_LINE; -} - -// clang-format off -std::string Theme::gtk_theme() noexcept -{ return m_theme_infos.gtk_theme_name; } - -std::string Theme::gtk_icon_theme() noexcept -{ return m_theme_infos.gtk_icon_theme; } - -std::string Theme::gtk_font() noexcept -{ return m_theme_infos.gtk_font; } - -std::string& Theme::cursor() noexcept -{ return m_theme_infos.cursor; } - -std::string& Theme::cursor_size() noexcept -{ return m_theme_infos.cursor_size; } - -#endif From 34d914ca335dc5115b1f662590c11e124fa3f2f2 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Sun, 13 Jul 2025 13:28:20 +0200 Subject: [PATCH 094/143] misc: remove query.hpp --- Makefile | 2 +- include/query.hpp | 354 ----------------------- include/util.hpp | 2 + libcufetch/parse.cc | 22 -- src/config.cpp | 21 -- src/core-modules/core-modules.cc | 2 +- src/core-modules/linux/user.cc | 4 +- src/core-modules/linux/utils/dewm.cc | 2 +- src/core-modules/linux/utils/packages.cc | 2 +- src/core-modules/linux/utils/term.cc | 2 +- src/gui.cpp | 3 - src/main.cpp | 1 - 12 files changed, 9 insertions(+), 408 deletions(-) delete mode 100644 include/query.hpp diff --git a/Makefile b/Makefile index 010040e9..9fc5732f 100644 --- a/Makefile +++ b/Makefile @@ -47,7 +47,7 @@ TARGET ?= $(NAME) OLDVERSION = 0.10.2 VERSION = 1.0.0 SRC_CPP = $(wildcard src/*.cpp) -SRC_CC = $(wildcard src/core-modules/*.cc src/core-modules/linux/*.cc src/core-modules/android/*.cc src/core-modules/macos/*.cc) +SRC_CC = $(wildcard src/core-modules/*.cc src/core-modules/linux/*.cc src/core-modules/linux/utils/*.cc src/core-modules/android/*.cc src/core-modules/macos/*.cc) OBJ_CPP = $(SRC_CPP:.cpp=.o) OBJ_CC = $(SRC_CC:.cc=.o) OBJ = $(OBJ_CPP) $(OBJ_CC) diff --git a/include/query.hpp b/include/query.hpp deleted file mode 100644 index e9dd59dd..00000000 --- a/include/query.hpp +++ /dev/null @@ -1,354 +0,0 @@ -/* - * Copyright 2025 Toni500git - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote - * products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef _QUERY_HPP -#define _QUERY_HPP - -#include <cstdint> -#include <string> -#include <fstream> -#include <variant> -#include <vector> - -#include "cufetch/cufetch.hh" -#include "platform.hpp" -#include "parse.hpp" - -extern "C" { -#if !CF_MACOS -# include <mntent.h> -# include <sys/statfs.h> -#else -# include <sys/param.h> -# include <sys/mount.h> -#endif -#include <pwd.h> -#include <sys/stat.h> -#include <sys/statvfs.h> -#include <sys/utsname.h> -#include <unistd.h> -} - -// used in systemInfo_t most of the time -using variant = std::variant<std::string, size_t, double>; - -inline bool is_live_mode = false; - -#define CHECK_INIT(x) \ - if (!x || is_live_mode) \ - x = true; \ - else \ - return; - -namespace Query -{ - -enum -{ - DISK_VOLUME_TYPE_HIDDEN = 1 << 2, - DISK_VOLUME_TYPE_REGULAR = 1 << 3, - DISK_VOLUME_TYPE_EXTERNAL = 1 << 4, - DISK_VOLUME_TYPE_READ_ONLY = 1 << 5, -}; - -class System -{ -public: - struct System_t - { - std::string os_pretty_name{ UNKNOWN }; - std::string os_name{ UNKNOWN }; - std::string os_id{ UNKNOWN }; - std::string os_version_id{ UNKNOWN }; - std::string os_version_codename{ UNKNOWN }; - std::string os_initsys_name{ UNKNOWN }; - std::string os_initsys_version{ UNKNOWN }; - - std::string host_modelname{ UNKNOWN }; - std::string host_version{ UNKNOWN }; - std::string host_vendor{ UNKNOWN }; - - std::string pkgs_installed{ UNKNOWN }; - }; - - System(); - - std::string kernel_name() noexcept; - std::string kernel_version() noexcept; - std::string hostname() noexcept; - std::string arch() noexcept; - std::string& os_pretty_name() noexcept; - std::string& os_name() noexcept; - std::string& os_id() noexcept; - std::string& os_initsys_name(); - std::string& os_initsys_version(); - std::string& os_versionid() noexcept; - std::string& os_version_codename() noexcept; - unsigned long& uptime() noexcept; - - // motherboard (host) - std::string& host_modelname() noexcept; - std::string& host_vendor() noexcept; - std::string& host_version() noexcept; - - std::string& pkgs_installed(const ConfigBase& config); - -private: - static System_t m_system_infos; - static bool m_bInit; - static struct utsname m_uname_infos; - static unsigned long m_uptime; -}; - -class User -{ -public: - struct User_t - { - std::string shell_path{ MAGIC_LINE }; - std::string shell_name{ MAGIC_LINE }; - std::string shell_version{ UNKNOWN }; - std::string wm_name{ MAGIC_LINE }; - std::string wm_version{ UNKNOWN }; - std::string de_name{ MAGIC_LINE }; - std::string de_version{ UNKNOWN }; - std::string term_name{ MAGIC_LINE }; - std::string term_version{ MAGIC_LINE }; - // private: - std::string m_wm_path; - }; - - User() noexcept; - - std::string name() noexcept; - std::string shell_path() noexcept; - std::string& shell_name() noexcept; - std::string& shell_version(const std::string_view shell_name); - std::string& wm_name(bool dont_query_dewm, const std::string_view term_name); - std::string& wm_version(bool dont_query_dewm, const std::string_view term_name); - std::string& de_name(bool dont_query_dewm, const std::string_view term_name, const std::string_view wm_name); - std::string& de_version(const std::string_view de_name); - std::string& term_name(); - std::string& term_version(const std::string_view term_name); - - static bool m_bDont_query_dewm; - -private: - static bool m_bInit; - static User_t m_users_infos; - static struct passwd* m_pPwd; -}; - -class Theme -{ -public: - struct Theme_t - { - std::string gtk_theme_name{ MAGIC_LINE }; - std::string gtk_icon_theme{ MAGIC_LINE }; - std::string gtk_font{ MAGIC_LINE }; - std::string cursor{ MAGIC_LINE }; - std::string cursor_size{ UNKNOWN }; - }; - - Theme(const std::uint8_t ver /*, moduleMap_t& queried_themes*/, const std::string& theme_name_version, - const ConfigBase& config, const bool gsettings_only = false); - - Theme(/*moduleMap_t& queried_themes, */ const ConfigBase& config, const bool gsettings_only = false); - - std::string gtk_theme() noexcept; - std::string gtk_icon_theme() noexcept; - std::string gtk_font() noexcept; - std::string& cursor() noexcept; - std::string& cursor_size() noexcept; - -private: - User query_user; - std::string m_wmde_name; - std::string m_theme_name; - // moduleMap_t& m_queried_themes; - static Theme_t m_theme_infos; -}; - -class CPU -{ -public: - struct CPU_t - { - std::string name{ MAGIC_LINE }; - std::string nproc{ MAGIC_LINE }; - - double freq_max = 0; - double freq_min = 0; - double freq_cur = 0; - double freq_bios_limit = 0; - double temp = 0; - - // private: - double freq_max_cpuinfo = 0; - // only in Android - std::string modelname; - std::string vendor; - }; - - CPU() noexcept; - - std::string& name() noexcept; - std::string& nproc() noexcept; - - // only in Android - std::string& vendor() noexcept; - std::string& modelname() noexcept; - - double& freq_max() noexcept; - double& freq_min() noexcept; - double& freq_cur() noexcept; - double& freq_bios_limit() noexcept; - double& temp() noexcept; - -private: - static bool m_bInit; - static CPU_t m_cpu_infos; -}; - -class GPU -{ -public: - struct GPU_t - { - std::string name{ MAGIC_LINE }; - std::string vendor{ MAGIC_LINE }; - }; - - GPU(const std::string& id /*, moduleMap_t& queried_gpus*/); - - std::string& name() noexcept; - std::string& vendor() noexcept; - -private: - uint16_t m_vendor_id; - uint16_t m_device_id; - std::string m_vendor_id_s; - std::string m_device_id_s; - - static GPU_t m_gpu_infos; -}; - -class Battery -{ -public: - struct Battery_t - { - std::string modelname{ MAGIC_LINE }; - std::string vendor{ MAGIC_LINE }; - std::string status{ MAGIC_LINE }; - std::string technology{ UNKNOWN }; - std::string capacity_level{ UNKNOWN }; - double temp = 0; - double perc = 0; - }; - - Battery(); - - std::string& modelname() noexcept; - std::string& vendor() noexcept; - std::string& status() noexcept; - std::string& technology() noexcept; - std::string& capacity_level() noexcept; - double& perc() noexcept; - double& temp() noexcept; - -private: - static bool m_bInit; - static Battery_t m_battery_infos; -}; - -class Disk -{ -public: - struct Disk_t - { - std::string typefs{ MAGIC_LINE }; - std::string device{ MAGIC_LINE }; - std::string mountdir{ MAGIC_LINE }; - double total_amount = 0; - double free_amount = 0; - double used_amount = 0; - int types_disk = 0; - }; - - Disk(const std::string& path, parse_args_t& parse_args, const bool auto_module = false); - - double& total_amount() noexcept; - double& free_amount() noexcept; - double& used_amount() noexcept; - int& types_disk() noexcept; - std::string& typefs() noexcept; - std::string& device() noexcept; - std::string& mountdir() noexcept; - - std::vector<std::string>& disks_formats() noexcept - { return m_disks_formats; } - -private: - std::vector<std::string> m_disks_formats /*, m_queried_devices*/; - static Disk_t m_disk_infos; -}; - -class RAM -{ -public: - struct RAM_t - { - double total_amount = 0; - double free_amount = 0; - double used_amount = 0; - double swap_free_amount = 0; - double swap_used_amount = 0; - double swap_total_amount = 0; - }; - - RAM() noexcept; - - double& total_amount() noexcept; - double& free_amount() noexcept; - double& used_amount() noexcept; - double& swap_free_amount() noexcept; - double& swap_used_amount() noexcept; - double& swap_total_amount() noexcept; - -private: - static bool m_bInit; - static RAM_t m_memory_infos; -}; - -} // namespace Query - -// inline Query::System query_system; -// inline Query::CPU query_cpu; -// inline Query::GPU query_gpu; -// inline Query::RAM query_ram; - -#endif diff --git a/include/util.hpp b/include/util.hpp index 385f11e5..82919a34 100644 --- a/include/util.hpp +++ b/include/util.hpp @@ -78,6 +78,8 @@ struct byte_units_t #define UNLOAD_LIBRARY(handle) dlclose(handle); +inline bool is_live_mode = false; + /* https://stackoverflow.com/questions/874134/find-out-if-string-ends-with-another-string-in-c#874160 * Check if substring exists at the end * @param fullString The string to lookup diff --git a/libcufetch/parse.cc b/libcufetch/parse.cc index fe62ded2..ec6563f9 100644 --- a/libcufetch/parse.cc +++ b/libcufetch/parse.cc @@ -42,7 +42,6 @@ #include "cufetch/cufetch.hh" #include "fmt/color.h" #include "fmt/format.h" -#include "query.hpp" #include "switch_fnv1a.hpp" #include "util.hpp" @@ -89,27 +88,6 @@ class Parser size_t pos = 0; }; -// declarations of static members in query.hpp -Query::System::System_t Query::System::m_system_infos; -Query::Theme::Theme_t Query::Theme::m_theme_infos; -Query::User::User_t Query::User::m_users_infos; -Query::Battery::Battery_t Query::Battery::m_battery_infos; -Query::CPU::CPU_t Query::CPU::m_cpu_infos; -Query::RAM::RAM_t Query::RAM::m_memory_infos; -Query::GPU::GPU_t Query::GPU::m_gpu_infos; -Query::Disk::Disk_t Query::Disk::m_disk_infos; - -struct utsname Query::System::m_uname_infos; -struct passwd* Query::User::m_pPwd; -unsigned long Query::System::m_uptime; - -bool Query::System::m_bInit = false; -bool Query::RAM::m_bInit = false; -bool Query::CPU::m_bInit = false; -bool Query::User::m_bInit = false; -bool Query::Battery::m_bInit = false; -bool Query::User::m_bDont_query_dewm = false; - // useless useful tmp string for parse() without using the original // pureOutput std::string _; diff --git a/src/config.cpp b/src/config.cpp index 2dd15650..10cf6c13 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -30,8 +30,6 @@ #include <string> #include "fmt/os.h" -#include "query.hpp" -#include "switch_fnv1a.hpp" #include "util.hpp" Config::Config(const std::filesystem::path& configFile, const std::filesystem::path& configDir) @@ -85,9 +83,6 @@ void Config::loadConfigFile(const std::filesystem::path& filename) this->gui_bg_image = expandVar(getValue<std::string>("gui.bg-image", "disable")); this->gui_css_file = expandVar(getValue<std::string>("gui.gtk-css", "disable")); - this->auto_disks_fmt = getValue<std::string>("auto.disk.fmt", "${auto}Disk (%1): $<disk(%1)>"); - this->auto_disks_show_dupl= getValue<bool>("auto.disk.show-duplicated", false); - this->uptime_d_fmt = expandVar(getValue<std::string>("os.uptime.days", " days")); this->uptime_h_fmt = expandVar(getValue<std::string>("os.uptime.hours", " hours")); this->uptime_m_fmt = expandVar(getValue<std::string>("os.uptime.mins", " mins")); @@ -124,22 +119,6 @@ void Config::loadConfigFile(const std::filesystem::path& filename) this->percentage_colors = {"green", "yellow", "red"}; } - for (const std::string& str : this->getValueArrayStr("auto.disk.display-types", {"external", "regular", "read-only"})) - { - switch (fnv1a16::hash(str)) - { - case "removable"_fnv1a16: // deprecated - case "external"_fnv1a16: - this->auto_disks_types |= Query::DISK_VOLUME_TYPE_EXTERNAL; break; - case "regular"_fnv1a16: - this->auto_disks_types |= Query::DISK_VOLUME_TYPE_REGULAR; break; - case "read-only"_fnv1a16: - this->auto_disks_types |= Query::DISK_VOLUME_TYPE_READ_ONLY; break; - case "hidden"_fnv1a16: - this->auto_disks_types |= Query::DISK_VOLUME_TYPE_HIDDEN; break; - } - } - for (const std::string& str : this->getValueArrayStr("config.alias-colors", {})) this->addAliasColors(str); diff --git a/src/core-modules/core-modules.cc b/src/core-modules/core-modules.cc index 19eab13c..7b5b72a2 100644 --- a/src/core-modules/core-modules.cc +++ b/src/core-modules/core-modules.cc @@ -16,7 +16,7 @@ #include "fmt/format.h" #include "util.hpp" -#include "linux/utils/packages.hpp" +#include "linux/utils/packages.hh" #if !CF_MACOS # include <mntent.h> diff --git a/src/core-modules/linux/user.cc b/src/core-modules/linux/user.cc index 452769de..a0b32b04 100644 --- a/src/core-modules/linux/user.cc +++ b/src/core-modules/linux/user.cc @@ -10,8 +10,8 @@ #include "fmt/format.h" #include "switch_fnv1a.hpp" #include "util.hpp" -#include "utils/dewm.hpp" -#include "utils/term.hpp" +#include "utils/dewm.hh" +#include "utils/term.hh" #if __has_include(<sys/socket.h>) && __has_include(<wayland-client.h>) #include <sys/socket.h> diff --git a/src/core-modules/linux/utils/dewm.cc b/src/core-modules/linux/utils/dewm.cc index 76aec099..d6f42d7c 100644 --- a/src/core-modules/linux/utils/dewm.cc +++ b/src/core-modules/linux/utils/dewm.cc @@ -43,7 +43,7 @@ * SOFTWARE. */ -#include "dewm.hpp" +#include "dewm.hh" #include <cstdlib> #include <fstream> diff --git a/src/core-modules/linux/utils/packages.cc b/src/core-modules/linux/utils/packages.cc index 590280c5..2515be93 100644 --- a/src/core-modules/linux/utils/packages.cc +++ b/src/core-modules/linux/utils/packages.cc @@ -23,7 +23,7 @@ * */ -#include "packages.hpp" +#include "packages.hh" #include "util.hpp" #include <algorithm> diff --git a/src/core-modules/linux/utils/term.cc b/src/core-modules/linux/utils/term.cc index 5b1e55b7..721b655a 100644 --- a/src/core-modules/linux/utils/term.cc +++ b/src/core-modules/linux/utils/term.cc @@ -18,7 +18,7 @@ * SOFTWARE. */ -#include "term.hpp" +#include "term.hh" #include <fstream> diff --git a/src/gui.cpp b/src/gui.cpp index 6c263540..2dab3ded 100644 --- a/src/gui.cpp +++ b/src/gui.cpp @@ -34,11 +34,8 @@ #include <filesystem> #include <fstream> -#include "cufetch/config.hh" #include "display.hpp" #include "fmt/ranges.h" -#include "parse.hpp" -#include "query.hpp" #include "stb_image.h" #include "util.hpp" diff --git a/src/main.cpp b/src/main.cpp index 5fc62856..b3c1688b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -42,7 +42,6 @@ #include "fmt/ranges.h" #include "gui.hpp" #include "platform.hpp" -#include "query.hpp" #include "switch_fnv1a.hpp" #include "util.hpp" From 58c14d4b64aecab68065095dfea256219a2f3d86 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Sun, 13 Jul 2025 16:27:06 +0200 Subject: [PATCH 095/143] Merge PR #8 into 'plugins' Author: saberr26 <salahhachmi06@gmail.com> Co-Author: Toni500git <toni500minecraft@gmail.com> --- include/boxd.hpp | 12 ++ include/config.hpp | 20 ++- include/utf8/checked.h | 8 +- libcufetch/parse.cc | 4 + src/boxd.cpp | 329 +++++++++++++++++++++++++++++++++++++++++ src/config.cpp | 3 + src/display.cpp | 92 +++++++----- src/gui.cpp | 12 +- src/main.cpp | 16 +- 9 files changed, 446 insertions(+), 50 deletions(-) create mode 100644 include/boxd.hpp create mode 100644 src/boxd.cpp diff --git a/include/boxd.hpp b/include/boxd.hpp new file mode 100644 index 00000000..a56220e5 --- /dev/null +++ b/include/boxd.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include <string> +#include <vector> +#include "config.hpp" + +// Flexible Unicode box-drawing helper. +// Given a parsed layout (one string per row) and config options, +// expands $fill macros and adds borders/column padding. +// Returns the final list of strings ready to be printed. +std::vector<std::string> apply_box_drawing(std::vector<std::string> layout, + const Config& config) noexcept; diff --git a/include/config.hpp b/include/config.hpp index 8f81eeb9..6bf784a4 100644 --- a/include/config.hpp +++ b/include/config.hpp @@ -13,7 +13,7 @@ * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote * products derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR @@ -31,13 +31,21 @@ #include <filesystem> #include <string_view> +#include <string> +#include <vector> #include "platform.hpp" #include "cufetch/config.hh" +struct box_chars_t { + std::string horizontal; + std::string vertical; +}; + class Config : public ConfigBase { public: + int box_extra_padding = 0; // additional spaces added to every column // Create .config directories and files and load the config file (args or default) Config(const std::filesystem::path& configFile, const std::filesystem::path& configDir); @@ -85,6 +93,8 @@ class Config : public ConfigBase bool slow_query_warnings = false; bool use_SI_unit = false; bool wrap_lines = false; + bool box_drawing_enabled = false; // New member + box_chars_t box_chars; // New member // Variables of config file for // modules specific configs @@ -180,7 +190,6 @@ class Config : public ConfigBase // default config inline constexpr std::string_view AUTOCONFIG = R"#([config] - # For more information on how customfetch works and the layout, # Read either: # * -w or --how-it-works @@ -298,6 +307,13 @@ alias-colors = ["purple=magenta"] # 3rd color for bad percentage-colors = ["green", "yellow", "red"] +# Box drawing glyphs +box-drawing-enabled = false + +# The character to be used in $<fill> +# in horizontal +box-drawing-char = "─" + # $<auto.disk> config [auto.disk] # Format for displaying the auto detected disks infos diff --git a/include/utf8/checked.h b/include/utf8/checked.h index 13311551..41e25960 100644 --- a/include/utf8/checked.h +++ b/include/utf8/checked.h @@ -265,7 +265,13 @@ namespace utf8 // The iterator class template <typename octet_iterator> - class iterator : public std::iterator <std::bidirectional_iterator_tag, uint32_t> { + class iterator { + public: + using iterator_category = std::bidirectional_iterator_tag; + using value_type = uint32_t; + using difference_type = std::ptrdiff_t; + using pointer = uint32_t*; + using reference = uint32_t&; octet_iterator it; octet_iterator range_start; octet_iterator range_end; diff --git a/libcufetch/parse.cc b/libcufetch/parse.cc index ec6563f9..4c80126f 100644 --- a/libcufetch/parse.cc +++ b/libcufetch/parse.cc @@ -703,6 +703,10 @@ std::optional<std::string> parse_info_tag(Parser& parser, parse_args_t& parse_ar const std::string& module = parse(parser, parse_args, evaluate, '>'); + if (module == "pin" || module == "fill" || module == "room" || module == "endroom") { + return "$<" + module + ">"; + } + if (!evaluate) return {}; diff --git a/src/boxd.cpp b/src/boxd.cpp new file mode 100644 index 00000000..96a24db8 --- /dev/null +++ b/src/boxd.cpp @@ -0,0 +1,329 @@ +#include "boxd.hpp" + +#include <algorithm> +#include <codecvt> +#include <cwchar> +#include <locale> +#include <string> +#include <vector> + +#include "utf8/checked.h" // i fixed the warnings here btw +#include "util.hpp" + +namespace +{ +// the concept of our "room" begans here: +// this Holds the calculated dimensions for a room, ensuring all lines align correctly. +struct RoomLayoutInfo +{ + // The column position where the content after the separator should start. + size_t pin_position = 0; + // The total visual width of the entire room, from the start of the line to the end. + size_t total_width = 0; +}; + +struct Room +{ + std::vector<std::string> lines; + RoomLayoutInfo layout_info; +}; + +// trim whitespace ..etc +static void trim_ws(std::string& s) +{ + static constexpr const char* WS = " \t\n\r\f\v"; + const size_t start = s.find_first_not_of(WS); + if (start == std::string::npos) + { + s.clear(); + return; + } + const size_t end = s.find_last_not_of(WS); + s = s.substr(start, end - start + 1); +} + +/** + * @brief Calculates the visual width of a UTF-8 string in a terminal. + * This function handles multi-byte characters, emojis, and NerdFont glyphs + * that may occupy more than one column. It converts the string to a wide string + * and uses wcswidth for an accurate measurement. + * @param s The UTF-8 string to measure. + * @return The number of columns the string will occupy. + */ +static size_t get_visual_width(const std::string& s) +{ + if (s.empty()) + { + return 0; + } + + // Set the locale to ensure wcswidth works correctly with the system's character set. + // An empty string for the locale uses the environment's default settings(your terminal usally). + std::setlocale(LC_ALL, ""); + + std::wstring_convert<std::codecvt_utf8<wchar_t>> conv; + std::wstring wstr; + try + { + wstr = conv.from_bytes(s); + } + catch (const std::range_error&) + { + // Fallback for invalid UTF-8: return byte length + return s.length(); + } + + // wcswidth calculates the number of columns required for a wide-character string. + // It returns -1 for non-printable characters. + int width = wcswidth(wstr.c_str(), wstr.length()); + + if (width == -1) + { + // Fallback for strings containing non-printable characters (e.g., control codes). + return s.length(); // A simple fallback, just in case + } + + return static_cast<size_t>(width); +} + +// cleans ansi escape codes (e.g., for colors) from a string. +static std::string strip_ansi(const std::string& str) +{ + std::string result; + result.reserve(str.size()); + bool in_escape = false; + + for (size_t i = 0; i < str.size(); ++i) + { + if (str[i] == '\033' && i + 1 < str.size() && str[i + 1] == '[') + { + in_escape = true; + i++; + continue; + } + if (in_escape) + { + if (std::isalpha(str[i])) + { // Terminal codes end with a letter, usually 'm' + in_escape = false; + } + continue; + } + result += str[i]; + } + return result; +} + +// this one cleans both ansi codes and layout markers like $<pin> and $<fill>. +static std::string strip_ansi_and_markers(const std::string& str) +{ + std::string result = strip_ansi(str); + + auto erase_substr = [&](const std::string& sub) { + size_t pos; + while ((pos = result.find(sub)) != std::string::npos) + { + result.erase(pos, sub.length()); + } + }; + + erase_substr("$<pin>"); + erase_substr("$<fill>"); + + return result; +} + +/** + * @brief Calculates room dimensions based on content, handling variable-width characters. + * + * This function robustly determines the required width of the room and the alignment + * point for $<pin> markers by finding the maximum left and right parts independently. + * + * @param room_lines The lines of content within a $<room> block. + * @return A RoomLayoutInfo struct with the calculated pin_position and total_width. + */ +RoomLayoutInfo calculate_room_layout(const std::vector<std::string>& room_lines) +{ + RoomLayoutInfo info; + size_t max_left_width = 0; + size_t max_right_width = 0; + size_t max_non_pinned_width = 0; + + // Finds the max widths for left/right parts of pinned lines, and for non-pinned lines + for (const auto& line : room_lines) + { + size_t pin_pos = line.find("$<pin>"); + if (pin_pos != std::string::npos) + { + std::string left_part = line.substr(0, pin_pos); + std::string right_part = line.substr(pin_pos + 6); // length of "$<pin>" + + max_left_width = std::max(max_left_width, get_visual_width(strip_ansi_and_markers(left_part))); + max_right_width = std::max(max_right_width, get_visual_width(strip_ansi_and_markers(right_part))); + } + else + { + // For lines without a pin (like borders), their width contributes to the total room width. + max_non_pinned_width = std::max(max_non_pinned_width, get_visual_width(strip_ansi_and_markers(line))); + } + } + + // The pin position is determined by the widest left part. This is where the right content will start. + info.pin_position = max_left_width; + + // The total width is the maximum of either the widest non-pinned line (e.g., a border) + // or the combined width of the widest left and right parts of the pinned lines. + info.total_width = std::max(max_non_pinned_width, max_left_width + max_right_width); + + return info; +} + +/** + * @brief Formats a single line from a room, applying padding and fills. + * + * This function uses the pre-calculated layout info to correctly align content + * and expand $<fill> markers to the full width of the room. + * + * @param line The raw line to process. + * @param config The application configuration (for box characters). + * @param layout_info The pre-calculated dimensions of the room. + * @return The fully formatted and aligned string. + */ +std::string process_room_line(std::string line, const Config& config, const RoomLayoutInfo& layout_info) +{ + // handle $<pin> alignment + size_t pin_pos = line.find("$<pin>"); + if (pin_pos != std::string::npos) + { + std::string left_part = line.substr(0, pin_pos); + std::string right_part = line.substr(pin_pos + 6); // length of "$<pin>" + + size_t left_width = get_visual_width(strip_ansi_and_markers(left_part)); + size_t right_width = get_visual_width(strip_ansi_and_markers(right_part)); + + // calculate padding to align the separator (the end of the left part). + size_t left_padding = (layout_info.pin_position > left_width) ? (layout_info.pin_position - left_width) : 0; + + // calculate padding to align the right edge of the box. + size_t current_line_width_if_packed = layout_info.pin_position + right_width; + size_t right_padding = (layout_info.total_width > current_line_width_if_packed) + ? (layout_info.total_width - current_line_width_if_packed) + : 0; + + // Reconstruct the line. The padding is inserted between the left and right parts. + line = left_part + std::string(left_padding, ' ') + std::string(right_padding, ' ') + right_part; + } + + // handle $<fill> expansion + size_t fill_count = 0; + size_t search_pos = 0; + while ((search_pos = line.find("$<fill>", search_pos)) != std::string::npos) + { + fill_count++; + search_pos += 7; // length of "$<fill>" + } + + if (fill_count > 0) + { + std::string line_no_fills = line; + size_t pos; + while ((pos = line_no_fills.find("$<fill>")) != std::string::npos) + { + line_no_fills.erase(pos, 7); + } + + size_t static_width = get_visual_width(strip_ansi(line_no_fills)); + + size_t total_fill_needed = + (layout_info.total_width > static_width) ? (layout_info.total_width - static_width) : 0; + size_t fill_per_marker = total_fill_needed / fill_count; + size_t remainder = total_fill_needed % fill_count; + + for (size_t i = 0; i < fill_count; ++i) + { + size_t current_fill_pos = line.find("$<fill>"); + if (current_fill_pos == std::string::npos) + break; // Should not happen!!! + + size_t current_fill_size = fill_per_marker + (i < remainder ? 1 : 0); + + std::string fill_str; + if (!config.box_chars.horizontal.empty()) + { + for (size_t j = 0; j < current_fill_size; ++j) + { + fill_str += config.box_chars.horizontal; + } + } + line.replace(current_fill_pos, 7, fill_str); + } + } + + return line; +} + +} // namespace + +// Main function to process the entire layout, finding and formatting $<room> blocks. +std::vector<std::string> apply_box_drawing(std::vector<std::string> layout, const Config& config) noexcept +{ + if (!config.box_drawing_enabled) + { + return layout; + } + + std::vector<std::string> final_layout; + + for (size_t i = 0; i < layout.size(); ++i) + { + std::string current_line = layout[i]; + trim_ws(current_line); + + if (current_line.find("$<room>") != std::string::npos) + { + Room current_room; + size_t room_end_idx = i; + bool room_found = false; + + // Find the corresponding $<endroom> + for (size_t j = i + 1; j < layout.size(); ++j) + { + std::string inner_line = layout[j]; + trim_ws(inner_line); + if (inner_line.find("$<endroom>") != std::string::npos) + { + room_end_idx = j; + room_found = true; + break; + } + current_room.lines.push_back(layout[j]); + } + + if (room_found) + { + // Calculate layout dimensions for the entire room first. + current_room.layout_info = calculate_room_layout(current_room.lines); + + // Then process each line using those consistent dimensions. + for (const auto& line : current_room.lines) + { + final_layout.push_back(process_room_line(line, config, current_room.layout_info)); + } + + // Skip the main loop past the processed room block. + i = room_end_idx; + } + else + { + // No $<endroom> found, treat $<room> as literal text. + final_layout.push_back(layout[i]); + } + } + else + { + final_layout.push_back(layout[i]); + } + } + + return final_layout; +} diff --git a/src/config.cpp b/src/config.cpp index 10cf6c13..5783b124 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -94,6 +94,9 @@ void Config::loadConfigFile(const std::filesystem::path& filename) this->flatpak_dirs = getValueArrayStr("os.pkgs.flatpak-dirs", {"/var/lib/flatpak/app", "~/.local/share/flatpak/app"}); this->apk_files = getValueArrayStr("os.pkgs.apk-files", {"/var/lib/apk/db/installed"}); + this->box_drawing_enabled = getValue<bool>("config.box-drawing-enabled", false); + this->box_chars.horizontal = getValue<std::string>("config.box-drawing-char", "─"); + colors.black = getThemeValue("config.black", "\033[1;30m"); colors.red = getThemeValue("config.red", "\033[1;31m"); colors.green = getThemeValue("config.green", "\033[1;32m"); diff --git a/src/display.cpp b/src/display.cpp index ba20311e..da298775 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -23,8 +23,6 @@ * */ -// Implementation of the system behind displaying/rendering the information - #include "display.hpp" #include <cstddef> @@ -34,7 +32,7 @@ #include "platform.hpp" #ifndef GUI_APP -# define STB_IMAGE_IMPLEMENTATION +#define STB_IMAGE_IMPLEMENTATION #endif #if CF_MACOS @@ -49,11 +47,13 @@ #include <algorithm> #include <array> +#include <cwchar> #include <filesystem> #include <fstream> #include <iostream> #include <vector> +#include "boxd.hpp" #include "core-modules.hh" #include "fmt/core.h" #include "fmt/format.h" @@ -63,6 +63,27 @@ #include "utf8/checked.h" #include "util.hpp" +size_t get_visual_width(const std::string& input) +{ + if (input.empty()) + { + return 0; + } + std::wstring wstr; + try + { + utf8::utf8to16(input.begin(), input.end(), std::back_inserter(wstr)); + } + catch (const utf8::exception&) + { + return input.length(); // Fallback on invalid UTF-8 + } + + int width = wcswidth(wstr.c_str(), wstr.length()); + + return (width < 0) ? input.length() : static_cast<size_t>(width); +} + std::string Display::detect_distro(const Config& config) { // debug("/etc/os-release = \n{}", read_shell_exec("cat /etc/os-release 2> /dev/null")); @@ -98,7 +119,7 @@ static std::vector<std::string> render_with_image(const moduleMap_t& modulesInfo const Config& config, const std::filesystem::path& path, const std::uint16_t font_width, const std::uint16_t font_height) { - int image_width, image_height, channels; + int image_width{}, image_height{}, channels{}; // load the image and get its width and height unsigned char* img = stbi_load(path.c_str(), &image_width, &image_height, &channels, 0); @@ -134,12 +155,10 @@ static std::vector<std::string> render_with_image(const moduleMap_t& modulesInfo } } - // erase each element for each instance of MAGIC_LINE layout.erase(std::remove_if(layout.begin(), layout.end(), [](const std::string_view str) { return str.find(MAGIC_LINE) != std::string::npos; }), layout.end()); - // took math from neofetch in get_term_size() and get_image_size(). seems to work nice const size_t width = image_width / font_width; const size_t height = image_height / font_height; @@ -289,6 +308,7 @@ std::vector<std::string> Display::render(const Config& config, const bool alread // clear screen write(STDOUT_FILENO, "\33[H\33[2J", 7); + // took math from neofetch in get_term_size() and get_image_size(). seems to work nice const std::uint16_t font_width = win.ws_xpixel / win.ws_col; const std::uint16_t font_height = win.ws_ypixel / win.ws_row; @@ -330,14 +350,14 @@ std::vector<std::string> Display::render(const Config& config, const bool alread if (!config.args_disable_colors) asciiArt_s += NOCOLOR; #else - // check parse.cpp + const size_t pos = asciiArt_s.rfind("$ </"); if (pos != std::string::npos) asciiArt_s.replace(pos, 2, "$"); #endif asciiArt.push_back(asciiArt_s); - const size_t pureOutputLen = utf8::distance(pureOutput.begin(), pureOutput.end()); + const size_t pureOutputLen = get_visual_width(pureOutput); if (static_cast<int>(pureOutputLen) > maxLineLength) maxLineLength = static_cast<int>(pureOutputLen); @@ -346,11 +366,12 @@ std::vector<std::string> Display::render(const Config& config, const bool alread debug("asciiArt_s = {}", asciiArt_s); } - if (config.args_print_logo_only) + if (config.args_print_logo_only || layout.empty()) return asciiArt; - std::string _; + std::vector<std::string> parsed_layout; std::vector<std::string> tmp_layout; + std::string _; parse_args_t parse_args{ moduleMap, _, layout, tmp_layout, config, true }; for (size_t i = 0; i < layout.size(); ++i) { @@ -370,6 +391,10 @@ std::vector<std::string> Display::render(const Config& config, const bool alread } } + // Box Drawing + if (config.box_drawing_enabled) + layout = apply_box_drawing(std::move(layout), config); + // erase each element for each instance of MAGIC_LINE layout.erase(std::remove_if(layout.begin(), layout.end(), [](const std::string_view str) { return str.find(MAGIC_LINE) != std::string::npos; }), @@ -383,38 +408,39 @@ std::vector<std::string> Display::render(const Config& config, const bool alread return layout; } - const unsigned int offset = + std::vector<std::string> final_render; + const unsigned int offset_val = (config.offset.back() == '%') - ? calc_perc(std::stof(config.offset.substr(0, config.offset.size() - 1)), win.ws_col, maxLineLength) - : std::stoi(config.offset); + ? calc_perc(std::stof(config.offset.substr(0, config.offset.size() - 1)), win.ws_col, maxLineLength) + : std::stoi(config.offset); + const std::string offset_str(offset_val, ' '); size_t i; - for (i = 0; i < layout.size(); i++) + for (i = 0; i < layout.size(); ++i) { - size_t origin = config.logo_padding_left; - - // The user-specified offset to be put before the logo - for (size_t j = 0; j < config.logo_padding_left; ++j) - layout.at(i).insert(0, " "); + std::string current_row; if (i < asciiArt.size()) { - layout.at(i).insert(origin, asciiArt.at(i)); - origin += asciiArt.at(i).length(); + current_row.append(config.logo_padding_left, ' '); + current_row.append(asciiArt[i]); + size_t pure_width = (i < pureAsciiArtLens.size()) ? pureAsciiArtLens[i] : 0; + size_t padding_needed = (maxLineLength > static_cast<int>(pure_width)) ? (maxLineLength - pure_width) : 0; + current_row.append(padding_needed, ' '); + } + else + { + current_row.append(config.logo_padding_left + maxLineLength, ' '); } - const size_t spaces = (maxLineLength + (config.args_disable_source ? 1 : offset)) - - (i < asciiArt.size() ? pureAsciiArtLens.at(i) : 0); - - debug("spaces: {}", spaces); + current_row.append(offset_str); - for (size_t j = 0; j < spaces; j++) - layout.at(i).insert(origin, " "); + if (i < layout.size()) + { + current_row.append(layout[i]); + } -#if !GUI_APP - if (!config.args_disable_colors) - layout.at(i) += NOCOLOR; -#endif + final_render.push_back(current_row); } for (; i < asciiArt.size(); ++i) @@ -422,10 +448,10 @@ std::vector<std::string> Display::render(const Config& config, const bool alread std::string line(config.logo_padding_left, ' '); line += asciiArt.at(i); - layout.push_back(line); + final_render.push_back(line); } - return layout; + return final_render; } void Display::display(const std::vector<std::string>& renderResult) diff --git a/src/gui.cpp b/src/gui.cpp index 2dab3ded..1e880853 100644 --- a/src/gui.cpp +++ b/src/gui.cpp @@ -34,17 +34,17 @@ #include <filesystem> #include <fstream> -#include "display.hpp" -#include "fmt/ranges.h" -#include "stb_image.h" -#include "util.hpp" - #include "gdkmm/pixbufanimation.h" #include "glibmm/refptr.h" #include "gtkmm/cssprovider.h" #include "glibmm/main.h" #include "gtkmm/enums.h" +#include "display.hpp" +#include "fmt/ranges.h" +#include "stb_image.h" +#include "util.hpp" + using namespace GUI; // https://www.codespeedy.com/convert-rgb-to-hex-color-code-in-cpp/ @@ -200,7 +200,7 @@ Window::Window(const Config& config, const std::filesystem::path& path, const mo die(_("Path to gtk css file '{}' doesn't exist"), config.gui_css_file); Glib::RefPtr<Gtk::CssProvider> css_provider = Gtk::CssProvider::create(); - Glib::RefPtr<Gdk::Screen> screen = Gdk::Screen::get_default(); + Glib::RefPtr<Gdk::Screen> screen = Gdk::Screen::get_default(); try { css_provider->load_from_path(config.gui_css_file); diff --git a/src/main.cpp b/src/main.cpp index b3c1688b..71e2efcf 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -63,7 +63,7 @@ using namespace std::string_view_literals; -bool display_modules = false; +bool display_modules = false; bool display_list_logos = false; // Print the version and some other infos, then exit successfully @@ -328,7 +328,7 @@ static void modules_list() // Split name into parts (e.g., "os.name.pretty" -> ["os", "name", "pretty"]) size_t start = 0, end = module.name.find('.'); - bool new_module = true; + bool new_module = true; while (end != std::string::npos) { new_module = false; @@ -360,13 +360,13 @@ static void modules_list() } } +// clang-format off // Return true if optarg says something true static bool str_to_bool(const std::string_view str) { return (str == "true" || str == "1" || str == "enable"); } -// clang-format off // parseargs() but only for parsing the user config path trough args // and so we can directly construct Config static std::filesystem::path parse_config_path(int argc, char* argv[], const std::filesystem::path &configDir) @@ -591,7 +591,7 @@ static void localize(void) } // clang-format on -int main(int argc, char *argv[]) +int main(int argc, char* argv[]) { const std::filesystem::path& configDir = getConfigDir(); const std::filesystem::path& configFile = parse_config_path(argc, argv, configDir); @@ -602,7 +602,7 @@ int main(int argc, char *argv[]) if (!parseargs(argc, argv, config, configFile)) return 1; config.loadConfigFile(configFile); - std::vector<void *> plugins_handle; + std::vector<void*> plugins_handle; /* TODO(burntranch): track each library and unload them. */ core_plugins_start(config); @@ -632,7 +632,7 @@ int main(int argc, char *argv[]) start(handle, config); plugins_handle.push_back(handle); } - + if (display_modules) { modules_list(); @@ -640,7 +640,7 @@ int main(int argc, char *argv[]) } else if (display_list_logos) { - list_logos(config.data_dir+"/ascii"); + list_logos(config.data_dir + "/ascii"); return 0; } @@ -731,7 +731,7 @@ int main(int argc, char *argv[]) enable_cursor(); core_plugins_finish(); - for (void *handle : plugins_handle) + for (void* handle : plugins_handle) { LOAD_LIB_SYMBOL(handle, void, finish, void*); if (dlerror()) From cea56b22d21119381711b21fb29998aa4a80bf59 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Sun, 13 Jul 2025 19:17:21 +0200 Subject: [PATCH 096/143] display: fix crash when --no-logo --- src/display.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/display.cpp b/src/display.cpp index da298775..dc4913bc 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -298,7 +298,7 @@ std::vector<std::string> Display::render(const Config& config, const bool alread } std::vector<size_t> pureAsciiArtLens; - int maxLineLength = -1; + size_t maxLineLength = 0; struct winsize win; ioctl(STDOUT_FILENO, TIOCGWINSZ, &win); @@ -359,8 +359,8 @@ std::vector<std::string> Display::render(const Config& config, const bool alread asciiArt.push_back(asciiArt_s); const size_t pureOutputLen = get_visual_width(pureOutput); - if (static_cast<int>(pureOutputLen) > maxLineLength) - maxLineLength = static_cast<int>(pureOutputLen); + if (pureOutputLen > maxLineLength) + maxLineLength = pureOutputLen; pureAsciiArtLens.push_back(pureOutputLen); debug("asciiArt_s = {}", asciiArt_s); @@ -425,7 +425,7 @@ std::vector<std::string> Display::render(const Config& config, const bool alread current_row.append(config.logo_padding_left, ' '); current_row.append(asciiArt[i]); size_t pure_width = (i < pureAsciiArtLens.size()) ? pureAsciiArtLens[i] : 0; - size_t padding_needed = (maxLineLength > static_cast<int>(pure_width)) ? (maxLineLength - pure_width) : 0; + size_t padding_needed = (maxLineLength > pure_width) ? (maxLineLength - pure_width) : 0; current_row.append(padding_needed, ' '); } else From 433e19d77ccfb53b36933a1a78883652fe3c4b5e Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Mon, 14 Jul 2025 13:12:11 +0200 Subject: [PATCH 097/143] args: exit --loop-ms with 'q' and increase from 50 to 200 ms --- src/core-modules/linux/os.cc | 5 ++-- src/main.cpp | 46 +++++++++++++++++++++++++++++++++--- 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/src/core-modules/linux/os.cc b/src/core-modules/linux/os.cc index bbbbca19..2dca84f9 100644 --- a/src/core-modules/linux/os.cc +++ b/src/core-modules/linux/os.cc @@ -37,8 +37,7 @@ static std::string read_value(const std::string_view name) char* end = strrchr(start, '"'); /* Get last occurence of " */ if (!end) - end = line + strlen(line) - 1; /* Set to the end of the string -- no newline. (I heard Windows has a - different newline sequence.. *sigh*) */ + end = line + strlen(line) - 1; /* Set to the end of the string -- no newline. */ result.assign(start, end - start); break; @@ -117,7 +116,7 @@ MODFUNC(os_initsys_version) std::ifstream f(path, std::ios::in); std::string line; - const std::string& name = str_tolower(os_initsys_name(callbackInfo)); + const std::string& name = str_tolower(os_initsys_name(nullptr)); switch (fnv1a16::hash(name)) { case "systemd"_fnv1a16: diff --git a/src/main.cpp b/src/main.cpp index 71e2efcf..a660880e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -26,6 +26,8 @@ #include <dlfcn.h> #include <getopt.h> #include <unistd.h> +#include <termios.h> +#include <stdlib.h> #include <algorithm> #include <cerrno> @@ -66,6 +68,32 @@ using namespace std::string_view_literals; bool display_modules = false; bool display_list_logos = false; +struct termios orig_termios; + +static void disable_raw_mode() +{ + tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios); +} + +static void enable_raw_mode() +{ + tcgetattr(STDIN_FILENO, &orig_termios); + atexit(disable_raw_mode); + + struct termios raw = orig_termios; + raw.c_lflag &= ~(ECHO | ICANON); // Disable echo and canonical mode + tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw); +} + +static int kbhit() +{ + struct timeval tv = {0L, 0L}; + fd_set fds; + FD_ZERO(&fds); + FD_SET(STDIN_FILENO, &fds); + return select(STDIN_FILENO + 1, &fds, NULL, NULL, &tv) > 0; +} + // Print the version and some other infos, then exit successfully static void version() { @@ -158,7 +186,7 @@ GUI/TERMINAL OPTIONS: LIVE MODE: --loop-ms <NUM> Run in live mode, updating every <NUM> milliseconds (min: 50). - Use inferior <NUM> than 50 to disable (default). + Use inferior <NUM> than 200 to disable. Press 'q' to exit. EXAMPLES: 1. Minimal output with default logo: @@ -657,7 +685,7 @@ int main(int argc, char* argv[]) moduleMap.emplace(module.name, module); } - is_live_mode = (config.loop_ms > 50); + is_live_mode = (config.loop_ms >= 200); if (config.source_path.empty() || config.source_path == "off") config.args_disable_source = true; @@ -700,7 +728,6 @@ int main(int argc, char* argv[]) if (!config.wrap_lines) { // https://en.cppreference.com/w/c/program/exit - // if something goes wrong like a segfault, then re-enable the cursor again std::atexit(enable_cursor); // hide cursor and disable line wrapping @@ -709,10 +736,23 @@ int main(int argc, char* argv[]) if (is_live_mode) { + enable_raw_mode(); const std::chrono::milliseconds sleep_ms{ config.loop_ms }; while (true) { + if (kbhit()) + { + char c; + read(STDIN_FILENO, &c, 1); + if (c == 'q' || c == 'Q') + { + info("exiting...\n"); + disable_raw_mode(); + break; + } + } + // clear screen and go to position 0, 0 write(STDOUT_FILENO, "\33[H\33[2J", 7); fmt::print("\033[0;0H"); From 23c3f01fa8259ffc4c2d41b63dcd04f7f9dacb32 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Mon, 14 Jul 2025 13:37:56 +0200 Subject: [PATCH 098/143] core-modules: move prettify* functions from linux/user.cc to core-modules.cc --- src/core-modules/core-modules.cc | 44 ++++++++++++++++++++++++++++++-- src/core-modules/linux/user.cc | 43 ++----------------------------- src/main.cpp | 2 +- 3 files changed, 45 insertions(+), 44 deletions(-) diff --git a/src/core-modules/core-modules.cc b/src/core-modules/core-modules.cc index 7b5b72a2..9d00d829 100644 --- a/src/core-modules/core-modules.cc +++ b/src/core-modules/core-modules.cc @@ -13,6 +13,7 @@ #include "core-modules.hh" #include "cufetch/cufetch.hh" #include "config.hpp" +#include "switch_fnv1a.hpp" #include "fmt/format.h" #include "util.hpp" @@ -89,6 +90,45 @@ static std::string get_colors_symbol(const callbackInfo_t* callback, bool is_lig callback->parse_args); } +static std::string prettify_de_name(const std::string_view de_name) +{ + switch (fnv1a16::hash(str_tolower(de_name.data()))) + { + case "kde"_fnv1a16: + case "plasma"_fnv1a16: + case "plasmashell"_fnv1a16: + case "plasmawayland"_fnv1a16: return "KDE Plasma"; + + case "gnome"_fnv1a16: + case "gnome-shell"_fnv1a16: return "GNOME"; + + case "xfce"_fnv1a16: + case "xfce4"_fnv1a16: + case "xfce4-session"_fnv1a16: return "Xfce4"; + + case "mate"_fnv1a16: + case "mate-session"_fnv1a16: return "Mate"; + + case "lxqt"_fnv1a16: + case "lxqt-session"_fnv1a16: return "LXQt"; + } + + return de_name.data(); +} + +static std::string prettify_term_name(const std::string_view term_name) +{ + switch (fnv1a16::hash(str_tolower(term_name.data()))) + { + case "gnome-terminal"_fnv1a16: + case "gnome terminal"_fnv1a16: return "GNOME Terminal"; + + case "gnome-console"_fnv1a16: + case "gnome console"_fnv1a16: return "GNOME console"; + } + return term_name.data(); +} + MODFUNC(disk_fmt) { const callbackInfo_t *callback = callbackInfo; @@ -302,7 +342,7 @@ void core_plugins_start(const Config& config) std::move(user_shell_version_module), }, [](unused _) {return user_shell_name(_) + " " + user_shell_version(_);}}; - module_t user_term_name_module = {"name", "terminal name [alacritty]", {}, user_term_name}; + module_t user_term_name_module = {"name", "terminal name [alacritty]", {}, [](unused _){ return prettify_term_name(user_term_name(_));}}; module_t user_term_version_module = {"version", "terminal version [0.13.2]", {}, user_shell_version}; module_t user_term_module = {"terminal", "terminal name and version [alacritty 0.13.2]", { std::move(user_term_version_module), @@ -316,7 +356,7 @@ void core_plugins_start(const Config& config) std::move(user_wm_name_module) }, [](unused _) {return user_wm_name(_) + " " + user_wm_version(_);}}; - module_t user_de_name_module = {"name", "Desktop Environment current session name [Plasma]", {}, user_de_name}; + module_t user_de_name_module = {"name", "Desktop Environment current session name [Plasma]", {}, [](unused _){ return prettify_de_name(user_de_name(_)); }}; module_t user_de_version_module = {"version", "Desktop Environment version (if available)", {}, user_de_version}; module_t user_de_module = {"de", "Desktop Environment current session name and version", { std::move(user_de_version_module), diff --git a/src/core-modules/linux/user.cc b/src/core-modules/linux/user.cc index a0b32b04..6079c182 100644 --- a/src/core-modules/linux/user.cc +++ b/src/core-modules/linux/user.cc @@ -18,45 +18,6 @@ #include <wayland-client.h> #endif -static std::string prettify_de_name(const std::string_view de_name) -{ - switch (fnv1a16::hash(str_tolower(de_name.data()))) - { - case "kde"_fnv1a16: - case "plasma"_fnv1a16: - case "plasmashell"_fnv1a16: - case "plasmawayland"_fnv1a16: return "KDE Plasma"; - - case "gnome"_fnv1a16: - case "gnome-shell"_fnv1a16: return "GNOME"; - - case "xfce"_fnv1a16: - case "xfce4"_fnv1a16: - case "xfce4-session"_fnv1a16: return "Xfce4"; - - case "mate"_fnv1a16: - case "mate-session"_fnv1a16: return "Mate"; - - case "lxqt"_fnv1a16: - case "lxqt-session"_fnv1a16: return "LXQt"; - } - - return de_name.data(); -} - -static std::string prettify_term_name(const std::string_view term_name) -{ - switch (fnv1a16::hash(str_tolower(term_name.data()))) - { - case "gnome-terminal"_fnv1a16: - case "gnome terminal"_fnv1a16: return "GNOME Terminal"; - - case "gnome-console"_fnv1a16: - case "gnome console"_fnv1a16: return "GNOME console"; - } - return term_name.data(); -} - // clang-format off static std::string get_term_name_env(bool get_default = false) { @@ -285,7 +246,7 @@ MODFUNC(user_term_version) ret.erase(pos); debug("get_term_version ret after = {}", ret); - return prettify_term_name(ret); + return ret; } std::string get_wm_name(std::string& wm_path_exec) @@ -429,7 +390,7 @@ MODFUNC(user_de_name) if (de_name == wm_name) de_name = MAGIC_LINE; - return prettify_de_name(de_name); + return de_name; } MODFUNC(user_de_version) diff --git a/src/main.cpp b/src/main.cpp index a660880e..7ace44fd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -98,7 +98,7 @@ static int kbhit() static void version() { std::string version{ fmt::format( - "customfetch {} built from branch {} at {} commit {} ({}).\n" + "customfetch {} built from branch '{}' at {} commit '{}' ({}).\n" "Date: {}\n" "Tag: {}", VERSION, GIT_BRANCH, GIT_DIRTY, GIT_COMMIT_HASH, GIT_COMMIT_MESSAGE, GIT_COMMIT_DATE, GIT_TAG) }; From bee76ba5f6e5d256a142c95a919c2fa0d9f6b54f Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Mon, 14 Jul 2025 15:16:26 +0200 Subject: [PATCH 099/143] Revert "Merge PR #8 into 'plugins'" This reverts commit 58c14d4b64aecab68065095dfea256219a2f3d86. Too unstable and breaks utf8 ASCII arts such as `darkos.txt` or `nixos.txt` --- include/boxd.hpp | 12 -- include/config.hpp | 20 +-- libcufetch/parse.cc | 4 - src/boxd.cpp | 329 -------------------------------------------- src/config.cpp | 3 - src/display.cpp | 92 +++++-------- 6 files changed, 35 insertions(+), 425 deletions(-) delete mode 100644 include/boxd.hpp delete mode 100644 src/boxd.cpp diff --git a/include/boxd.hpp b/include/boxd.hpp deleted file mode 100644 index a56220e5..00000000 --- a/include/boxd.hpp +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#include <string> -#include <vector> -#include "config.hpp" - -// Flexible Unicode box-drawing helper. -// Given a parsed layout (one string per row) and config options, -// expands $fill macros and adds borders/column padding. -// Returns the final list of strings ready to be printed. -std::vector<std::string> apply_box_drawing(std::vector<std::string> layout, - const Config& config) noexcept; diff --git a/include/config.hpp b/include/config.hpp index 6bf784a4..8f81eeb9 100644 --- a/include/config.hpp +++ b/include/config.hpp @@ -13,7 +13,7 @@ * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote * products derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR @@ -31,21 +31,13 @@ #include <filesystem> #include <string_view> -#include <string> -#include <vector> #include "platform.hpp" #include "cufetch/config.hh" -struct box_chars_t { - std::string horizontal; - std::string vertical; -}; - class Config : public ConfigBase { public: - int box_extra_padding = 0; // additional spaces added to every column // Create .config directories and files and load the config file (args or default) Config(const std::filesystem::path& configFile, const std::filesystem::path& configDir); @@ -93,8 +85,6 @@ class Config : public ConfigBase bool slow_query_warnings = false; bool use_SI_unit = false; bool wrap_lines = false; - bool box_drawing_enabled = false; // New member - box_chars_t box_chars; // New member // Variables of config file for // modules specific configs @@ -190,6 +180,7 @@ class Config : public ConfigBase // default config inline constexpr std::string_view AUTOCONFIG = R"#([config] + # For more information on how customfetch works and the layout, # Read either: # * -w or --how-it-works @@ -307,13 +298,6 @@ alias-colors = ["purple=magenta"] # 3rd color for bad percentage-colors = ["green", "yellow", "red"] -# Box drawing glyphs -box-drawing-enabled = false - -# The character to be used in $<fill> -# in horizontal -box-drawing-char = "─" - # $<auto.disk> config [auto.disk] # Format for displaying the auto detected disks infos diff --git a/libcufetch/parse.cc b/libcufetch/parse.cc index 4c80126f..ec6563f9 100644 --- a/libcufetch/parse.cc +++ b/libcufetch/parse.cc @@ -703,10 +703,6 @@ std::optional<std::string> parse_info_tag(Parser& parser, parse_args_t& parse_ar const std::string& module = parse(parser, parse_args, evaluate, '>'); - if (module == "pin" || module == "fill" || module == "room" || module == "endroom") { - return "$<" + module + ">"; - } - if (!evaluate) return {}; diff --git a/src/boxd.cpp b/src/boxd.cpp deleted file mode 100644 index 96a24db8..00000000 --- a/src/boxd.cpp +++ /dev/null @@ -1,329 +0,0 @@ -#include "boxd.hpp" - -#include <algorithm> -#include <codecvt> -#include <cwchar> -#include <locale> -#include <string> -#include <vector> - -#include "utf8/checked.h" // i fixed the warnings here btw -#include "util.hpp" - -namespace -{ -// the concept of our "room" begans here: -// this Holds the calculated dimensions for a room, ensuring all lines align correctly. -struct RoomLayoutInfo -{ - // The column position where the content after the separator should start. - size_t pin_position = 0; - // The total visual width of the entire room, from the start of the line to the end. - size_t total_width = 0; -}; - -struct Room -{ - std::vector<std::string> lines; - RoomLayoutInfo layout_info; -}; - -// trim whitespace ..etc -static void trim_ws(std::string& s) -{ - static constexpr const char* WS = " \t\n\r\f\v"; - const size_t start = s.find_first_not_of(WS); - if (start == std::string::npos) - { - s.clear(); - return; - } - const size_t end = s.find_last_not_of(WS); - s = s.substr(start, end - start + 1); -} - -/** - * @brief Calculates the visual width of a UTF-8 string in a terminal. - * This function handles multi-byte characters, emojis, and NerdFont glyphs - * that may occupy more than one column. It converts the string to a wide string - * and uses wcswidth for an accurate measurement. - * @param s The UTF-8 string to measure. - * @return The number of columns the string will occupy. - */ -static size_t get_visual_width(const std::string& s) -{ - if (s.empty()) - { - return 0; - } - - // Set the locale to ensure wcswidth works correctly with the system's character set. - // An empty string for the locale uses the environment's default settings(your terminal usally). - std::setlocale(LC_ALL, ""); - - std::wstring_convert<std::codecvt_utf8<wchar_t>> conv; - std::wstring wstr; - try - { - wstr = conv.from_bytes(s); - } - catch (const std::range_error&) - { - // Fallback for invalid UTF-8: return byte length - return s.length(); - } - - // wcswidth calculates the number of columns required for a wide-character string. - // It returns -1 for non-printable characters. - int width = wcswidth(wstr.c_str(), wstr.length()); - - if (width == -1) - { - // Fallback for strings containing non-printable characters (e.g., control codes). - return s.length(); // A simple fallback, just in case - } - - return static_cast<size_t>(width); -} - -// cleans ansi escape codes (e.g., for colors) from a string. -static std::string strip_ansi(const std::string& str) -{ - std::string result; - result.reserve(str.size()); - bool in_escape = false; - - for (size_t i = 0; i < str.size(); ++i) - { - if (str[i] == '\033' && i + 1 < str.size() && str[i + 1] == '[') - { - in_escape = true; - i++; - continue; - } - if (in_escape) - { - if (std::isalpha(str[i])) - { // Terminal codes end with a letter, usually 'm' - in_escape = false; - } - continue; - } - result += str[i]; - } - return result; -} - -// this one cleans both ansi codes and layout markers like $<pin> and $<fill>. -static std::string strip_ansi_and_markers(const std::string& str) -{ - std::string result = strip_ansi(str); - - auto erase_substr = [&](const std::string& sub) { - size_t pos; - while ((pos = result.find(sub)) != std::string::npos) - { - result.erase(pos, sub.length()); - } - }; - - erase_substr("$<pin>"); - erase_substr("$<fill>"); - - return result; -} - -/** - * @brief Calculates room dimensions based on content, handling variable-width characters. - * - * This function robustly determines the required width of the room and the alignment - * point for $<pin> markers by finding the maximum left and right parts independently. - * - * @param room_lines The lines of content within a $<room> block. - * @return A RoomLayoutInfo struct with the calculated pin_position and total_width. - */ -RoomLayoutInfo calculate_room_layout(const std::vector<std::string>& room_lines) -{ - RoomLayoutInfo info; - size_t max_left_width = 0; - size_t max_right_width = 0; - size_t max_non_pinned_width = 0; - - // Finds the max widths for left/right parts of pinned lines, and for non-pinned lines - for (const auto& line : room_lines) - { - size_t pin_pos = line.find("$<pin>"); - if (pin_pos != std::string::npos) - { - std::string left_part = line.substr(0, pin_pos); - std::string right_part = line.substr(pin_pos + 6); // length of "$<pin>" - - max_left_width = std::max(max_left_width, get_visual_width(strip_ansi_and_markers(left_part))); - max_right_width = std::max(max_right_width, get_visual_width(strip_ansi_and_markers(right_part))); - } - else - { - // For lines without a pin (like borders), their width contributes to the total room width. - max_non_pinned_width = std::max(max_non_pinned_width, get_visual_width(strip_ansi_and_markers(line))); - } - } - - // The pin position is determined by the widest left part. This is where the right content will start. - info.pin_position = max_left_width; - - // The total width is the maximum of either the widest non-pinned line (e.g., a border) - // or the combined width of the widest left and right parts of the pinned lines. - info.total_width = std::max(max_non_pinned_width, max_left_width + max_right_width); - - return info; -} - -/** - * @brief Formats a single line from a room, applying padding and fills. - * - * This function uses the pre-calculated layout info to correctly align content - * and expand $<fill> markers to the full width of the room. - * - * @param line The raw line to process. - * @param config The application configuration (for box characters). - * @param layout_info The pre-calculated dimensions of the room. - * @return The fully formatted and aligned string. - */ -std::string process_room_line(std::string line, const Config& config, const RoomLayoutInfo& layout_info) -{ - // handle $<pin> alignment - size_t pin_pos = line.find("$<pin>"); - if (pin_pos != std::string::npos) - { - std::string left_part = line.substr(0, pin_pos); - std::string right_part = line.substr(pin_pos + 6); // length of "$<pin>" - - size_t left_width = get_visual_width(strip_ansi_and_markers(left_part)); - size_t right_width = get_visual_width(strip_ansi_and_markers(right_part)); - - // calculate padding to align the separator (the end of the left part). - size_t left_padding = (layout_info.pin_position > left_width) ? (layout_info.pin_position - left_width) : 0; - - // calculate padding to align the right edge of the box. - size_t current_line_width_if_packed = layout_info.pin_position + right_width; - size_t right_padding = (layout_info.total_width > current_line_width_if_packed) - ? (layout_info.total_width - current_line_width_if_packed) - : 0; - - // Reconstruct the line. The padding is inserted between the left and right parts. - line = left_part + std::string(left_padding, ' ') + std::string(right_padding, ' ') + right_part; - } - - // handle $<fill> expansion - size_t fill_count = 0; - size_t search_pos = 0; - while ((search_pos = line.find("$<fill>", search_pos)) != std::string::npos) - { - fill_count++; - search_pos += 7; // length of "$<fill>" - } - - if (fill_count > 0) - { - std::string line_no_fills = line; - size_t pos; - while ((pos = line_no_fills.find("$<fill>")) != std::string::npos) - { - line_no_fills.erase(pos, 7); - } - - size_t static_width = get_visual_width(strip_ansi(line_no_fills)); - - size_t total_fill_needed = - (layout_info.total_width > static_width) ? (layout_info.total_width - static_width) : 0; - size_t fill_per_marker = total_fill_needed / fill_count; - size_t remainder = total_fill_needed % fill_count; - - for (size_t i = 0; i < fill_count; ++i) - { - size_t current_fill_pos = line.find("$<fill>"); - if (current_fill_pos == std::string::npos) - break; // Should not happen!!! - - size_t current_fill_size = fill_per_marker + (i < remainder ? 1 : 0); - - std::string fill_str; - if (!config.box_chars.horizontal.empty()) - { - for (size_t j = 0; j < current_fill_size; ++j) - { - fill_str += config.box_chars.horizontal; - } - } - line.replace(current_fill_pos, 7, fill_str); - } - } - - return line; -} - -} // namespace - -// Main function to process the entire layout, finding and formatting $<room> blocks. -std::vector<std::string> apply_box_drawing(std::vector<std::string> layout, const Config& config) noexcept -{ - if (!config.box_drawing_enabled) - { - return layout; - } - - std::vector<std::string> final_layout; - - for (size_t i = 0; i < layout.size(); ++i) - { - std::string current_line = layout[i]; - trim_ws(current_line); - - if (current_line.find("$<room>") != std::string::npos) - { - Room current_room; - size_t room_end_idx = i; - bool room_found = false; - - // Find the corresponding $<endroom> - for (size_t j = i + 1; j < layout.size(); ++j) - { - std::string inner_line = layout[j]; - trim_ws(inner_line); - if (inner_line.find("$<endroom>") != std::string::npos) - { - room_end_idx = j; - room_found = true; - break; - } - current_room.lines.push_back(layout[j]); - } - - if (room_found) - { - // Calculate layout dimensions for the entire room first. - current_room.layout_info = calculate_room_layout(current_room.lines); - - // Then process each line using those consistent dimensions. - for (const auto& line : current_room.lines) - { - final_layout.push_back(process_room_line(line, config, current_room.layout_info)); - } - - // Skip the main loop past the processed room block. - i = room_end_idx; - } - else - { - // No $<endroom> found, treat $<room> as literal text. - final_layout.push_back(layout[i]); - } - } - else - { - final_layout.push_back(layout[i]); - } - } - - return final_layout; -} diff --git a/src/config.cpp b/src/config.cpp index 5783b124..10cf6c13 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -94,9 +94,6 @@ void Config::loadConfigFile(const std::filesystem::path& filename) this->flatpak_dirs = getValueArrayStr("os.pkgs.flatpak-dirs", {"/var/lib/flatpak/app", "~/.local/share/flatpak/app"}); this->apk_files = getValueArrayStr("os.pkgs.apk-files", {"/var/lib/apk/db/installed"}); - this->box_drawing_enabled = getValue<bool>("config.box-drawing-enabled", false); - this->box_chars.horizontal = getValue<std::string>("config.box-drawing-char", "─"); - colors.black = getThemeValue("config.black", "\033[1;30m"); colors.red = getThemeValue("config.red", "\033[1;31m"); colors.green = getThemeValue("config.green", "\033[1;32m"); diff --git a/src/display.cpp b/src/display.cpp index dc4913bc..12bc18cf 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -23,6 +23,8 @@ * */ +// Implementation of the system behind displaying/rendering the information + #include "display.hpp" #include <cstddef> @@ -32,7 +34,7 @@ #include "platform.hpp" #ifndef GUI_APP -#define STB_IMAGE_IMPLEMENTATION +# define STB_IMAGE_IMPLEMENTATION #endif #if CF_MACOS @@ -47,13 +49,11 @@ #include <algorithm> #include <array> -#include <cwchar> #include <filesystem> #include <fstream> #include <iostream> #include <vector> -#include "boxd.hpp" #include "core-modules.hh" #include "fmt/core.h" #include "fmt/format.h" @@ -63,27 +63,6 @@ #include "utf8/checked.h" #include "util.hpp" -size_t get_visual_width(const std::string& input) -{ - if (input.empty()) - { - return 0; - } - std::wstring wstr; - try - { - utf8::utf8to16(input.begin(), input.end(), std::back_inserter(wstr)); - } - catch (const utf8::exception&) - { - return input.length(); // Fallback on invalid UTF-8 - } - - int width = wcswidth(wstr.c_str(), wstr.length()); - - return (width < 0) ? input.length() : static_cast<size_t>(width); -} - std::string Display::detect_distro(const Config& config) { // debug("/etc/os-release = \n{}", read_shell_exec("cat /etc/os-release 2> /dev/null")); @@ -119,7 +98,7 @@ static std::vector<std::string> render_with_image(const moduleMap_t& modulesInfo const Config& config, const std::filesystem::path& path, const std::uint16_t font_width, const std::uint16_t font_height) { - int image_width{}, image_height{}, channels{}; + int image_width, image_height, channels; // load the image and get its width and height unsigned char* img = stbi_load(path.c_str(), &image_width, &image_height, &channels, 0); @@ -155,10 +134,12 @@ static std::vector<std::string> render_with_image(const moduleMap_t& modulesInfo } } + // erase each element for each instance of MAGIC_LINE layout.erase(std::remove_if(layout.begin(), layout.end(), [](const std::string_view str) { return str.find(MAGIC_LINE) != std::string::npos; }), layout.end()); + // took math from neofetch in get_term_size() and get_image_size(). seems to work nice const size_t width = image_width / font_width; const size_t height = image_height / font_height; @@ -308,7 +289,6 @@ std::vector<std::string> Display::render(const Config& config, const bool alread // clear screen write(STDOUT_FILENO, "\33[H\33[2J", 7); - // took math from neofetch in get_term_size() and get_image_size(). seems to work nice const std::uint16_t font_width = win.ws_xpixel / win.ws_col; const std::uint16_t font_height = win.ws_ypixel / win.ws_row; @@ -350,14 +330,14 @@ std::vector<std::string> Display::render(const Config& config, const bool alread if (!config.args_disable_colors) asciiArt_s += NOCOLOR; #else - + // check parse.cpp const size_t pos = asciiArt_s.rfind("$ </"); if (pos != std::string::npos) asciiArt_s.replace(pos, 2, "$"); #endif asciiArt.push_back(asciiArt_s); - const size_t pureOutputLen = get_visual_width(pureOutput); + const size_t pureOutputLen = utf8::distance(pureOutput.begin(), pureOutput.end()); if (pureOutputLen > maxLineLength) maxLineLength = pureOutputLen; @@ -366,12 +346,11 @@ std::vector<std::string> Display::render(const Config& config, const bool alread debug("asciiArt_s = {}", asciiArt_s); } - if (config.args_print_logo_only || layout.empty()) + if (config.args_print_logo_only) return asciiArt; - std::vector<std::string> parsed_layout; - std::vector<std::string> tmp_layout; std::string _; + std::vector<std::string> tmp_layout; parse_args_t parse_args{ moduleMap, _, layout, tmp_layout, config, true }; for (size_t i = 0; i < layout.size(); ++i) { @@ -391,10 +370,6 @@ std::vector<std::string> Display::render(const Config& config, const bool alread } } - // Box Drawing - if (config.box_drawing_enabled) - layout = apply_box_drawing(std::move(layout), config); - // erase each element for each instance of MAGIC_LINE layout.erase(std::remove_if(layout.begin(), layout.end(), [](const std::string_view str) { return str.find(MAGIC_LINE) != std::string::npos; }), @@ -408,39 +383,38 @@ std::vector<std::string> Display::render(const Config& config, const bool alread return layout; } - std::vector<std::string> final_render; - const unsigned int offset_val = + const unsigned int offset = (config.offset.back() == '%') - ? calc_perc(std::stof(config.offset.substr(0, config.offset.size() - 1)), win.ws_col, maxLineLength) - : std::stoi(config.offset); - const std::string offset_str(offset_val, ' '); + ? calc_perc(std::stof(config.offset.substr(0, config.offset.size() - 1)), win.ws_col, maxLineLength) + : std::stoi(config.offset); size_t i; - for (i = 0; i < layout.size(); ++i) + for (i = 0; i < layout.size(); i++) { - std::string current_row; + size_t origin = config.logo_padding_left; + + // The user-specified offset to be put before the logo + for (size_t j = 0; j < config.logo_padding_left; ++j) + layout.at(i).insert(0, " "); if (i < asciiArt.size()) { - current_row.append(config.logo_padding_left, ' '); - current_row.append(asciiArt[i]); - size_t pure_width = (i < pureAsciiArtLens.size()) ? pureAsciiArtLens[i] : 0; - size_t padding_needed = (maxLineLength > pure_width) ? (maxLineLength - pure_width) : 0; - current_row.append(padding_needed, ' '); - } - else - { - current_row.append(config.logo_padding_left + maxLineLength, ' '); + layout.at(i).insert(origin, asciiArt.at(i)); + origin += asciiArt.at(i).length(); } - current_row.append(offset_str); + const size_t spaces = (maxLineLength + (config.args_disable_source ? 1 : offset)) - + (i < asciiArt.size() ? pureAsciiArtLens.at(i) : 0); - if (i < layout.size()) - { - current_row.append(layout[i]); - } + debug("spaces: {}", spaces); - final_render.push_back(current_row); + for (size_t j = 0; j < spaces; j++) + layout.at(i).insert(origin, " "); + +#if !GUI_APP + if (!config.args_disable_colors) + layout.at(i) += NOCOLOR; +#endif } for (; i < asciiArt.size(); ++i) @@ -448,10 +422,10 @@ std::vector<std::string> Display::render(const Config& config, const bool alread std::string line(config.logo_padding_left, ' '); line += asciiArt.at(i); - final_render.push_back(line); + layout.push_back(line); } - return final_render; + return layout; } void Display::display(const std::vector<std::string>& renderResult) From 86ee0668bedf40d3f17dc9f6fca2ee400959d145 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Wed, 16 Jul 2025 17:56:24 +0200 Subject: [PATCH 100/143] core-modules: macos: add almost all modules --- include/cufetch/common.hh | 1 + src/core-modules/android/system.cc | 6 +- src/core-modules/linux/user.cc | 4 +- src/core-modules/macos/battery.cc | 28 +++ src/core-modules/macos/cpu.cc | 5 +- src/core-modules/macos/disk.cc | 92 +++++++++- src/core-modules/macos/gpu.cc | 13 ++ src/core-modules/macos/os.cc | 6 + src/core-modules/macos/ram.cc | 8 +- src/core-modules/macos/system.cc | 262 +++++++++++++++++++++++++++++ 10 files changed, 413 insertions(+), 12 deletions(-) create mode 100644 src/core-modules/macos/battery.cc create mode 100644 src/core-modules/macos/gpu.cc create mode 100644 src/core-modules/macos/system.cc diff --git a/include/cufetch/common.hh b/include/cufetch/common.hh index 6cbf05ca..c5270b1e 100644 --- a/include/cufetch/common.hh +++ b/include/cufetch/common.hh @@ -1,5 +1,6 @@ #pragma once +#include <cstdlib> #include "fmt/color.h" #include "fmt/core.h" diff --git a/src/core-modules/android/system.cc b/src/core-modules/android/system.cc index f075ebc6..5857bc18 100644 --- a/src/core-modules/android/system.cc +++ b/src/core-modules/android/system.cc @@ -8,9 +8,9 @@ #include "core-modules.hh" #include "util.hpp" -static constexpr std::array<std::string_view, 8> vendors_prop_names = { - "ro.product.marketname", "ro.vendor.product.display", "ro.config.devicename", "ro.config.marketing_name", - "ro.product.vendor.model", "ro.product.oppo_model", "ro.oppo.market.name", "ro.product.brand" +static constexpr std::array<std::string_view, 9> vendors_prop_names = { + "ro.product.marketname", "ro.vendor.product.display", "ro.vivo.market.name", "ro.config.devicename", + "ro.config.marketing_name", "ro.product.vendor.model", "ro.product.oppo_model", "ro.oppo.market.name", "ro.product.brand" }; MODFUNC(host) diff --git a/src/core-modules/linux/user.cc b/src/core-modules/linux/user.cc index 6079c182..37cb89e8 100644 --- a/src/core-modules/linux/user.cc +++ b/src/core-modules/linux/user.cc @@ -1,5 +1,5 @@ #include "platform.hpp" -#if CF_LINUX +#if CF_LINUX || CF_MACOS #include <unistd.h> @@ -117,7 +117,7 @@ std::string get_terminal_pid() std::string get_terminal_name() { if (term_pid == MAGIC_LINE) - return MAGIC_LINE; + return get_term_name_env(true); std::ifstream f("/proc/" + term_pid + "/comm", std::ios::in); std::string term_name; diff --git a/src/core-modules/macos/battery.cc b/src/core-modules/macos/battery.cc new file mode 100644 index 00000000..42df846c --- /dev/null +++ b/src/core-modules/macos/battery.cc @@ -0,0 +1,28 @@ +#include "platform.hpp" +#if CF_MACOS + +#include "core-modules.hh" +#include "cufetch/common.hh" + +MODFUNC(battery_modelname) +{ return MAGIC_LINE; } + +MODFUNC(battery_vendor) +{ return MAGIC_LINE; } + +MODFUNC(battery_capacity_level) +{ return MAGIC_LINE; } + +MODFUNC(battery_technology) +{ return MAGIC_LINE; } + +MODFUNC(battery_status) +{ return MAGIC_LINE; } + +MODFUNC(battery_perc) +{ return MAGIC_LINE; } + +double battery_temp() +{ return 0; } + +#endif diff --git a/src/core-modules/macos/cpu.cc b/src/core-modules/macos/cpu.cc index c36439d2..cd0ad83a 100644 --- a/src/core-modules/macos/cpu.cc +++ b/src/core-modules/macos/cpu.cc @@ -21,6 +21,9 @@ static bool get_sysctl(const char* name, void* ret, size_t* oldlenp) return (sysctlbyname(name, ret, oldlenp, NULL, 0) == 0); } +float cpu_temp() +{ return 0; } + MODFUNC(cpu_name) { char buf[1024]; @@ -43,7 +46,7 @@ MODFUNC(cpu_freq_cur) std::uint64_t freq = 0; size_t length = sizeof(freq); if (!get_sysctl("hw.cpufrequency", &freq, &length)) - get_sysctl({ CTL_HW, HW_CPU_FREQ }, &freq, &length); + get_sysctl((int[2]){ CTL_HW, HW_CPU_FREQ }, &freq, &length); return fmt::to_string(static_cast<double>(freq) / std::giga().num); } diff --git a/src/core-modules/macos/disk.cc b/src/core-modules/macos/disk.cc index 2e9bd03e..47561bd7 100644 --- a/src/core-modules/macos/disk.cc +++ b/src/core-modules/macos/disk.cc @@ -1,12 +1,15 @@ #include "platform.hpp" #if CF_MACOS -#include <sys/statfs.h> +#include "cufetch/common.hh" +#include "fmt/format.h" +#include "util.hpp" +#include "core-modules.hh" + #include <sys/types.h> #include <sys/param.h> #include <sys/mount.h> -#include <cstring> #include <string> static std::string format_auto_query_string(std::string str, const struct statfs* fs) @@ -40,4 +43,89 @@ static int get_disk_type(const int flags) return type; } +static bool get_disk_info(const callbackInfo_t* callbackInfo, struct statfs *fs) +{ + if (callbackInfo->moduleArgs->name != "disk" || + (callbackInfo->moduleArgs->name == "disk" && callbackInfo->moduleArgs->value.empty())) + die("Module disk doesn't have an argmument to the path/device to query"); + + const std::string& path = callbackInfo->moduleArgs->value; + return (statfs(path.c_str(), fs) != 0); +} + + +MODFUNC(disk_fsname) +{ + struct statfs fs; + if (!get_disk_info(callbackInfo, &fs)) + return MAGIC_LINE; + + return fs.f_fstypename; +} + +MODFUNC(disk_device) +{ + struct statfs fs; + if (!get_disk_info(callbackInfo, &fs)) + return MAGIC_LINE; + + return fs.f_mntfromname; +} + +MODFUNC(disk_mountdir) +{ + struct statfs fs; + if (!get_disk_info(callbackInfo, &fs)) + return MAGIC_LINE; + + return fs.f_mntonname; +} + +MODFUNC(auto_disk) +{ return MAGIC_LINE; } + +MODFUNC(disk_types) +{ + struct statfs fs; + if (!get_disk_info(callbackInfo, &fs)) + return MAGIC_LINE; + + const int types = get_disk_type(fs.f_flags); + std::string str; + if (types & DISK_VOLUME_TYPE_EXTERNAL) + str += "External, "; + if (types & DISK_VOLUME_TYPE_HIDDEN) + str += "Hidden, "; + if (types & DISK_VOLUME_TYPE_READ_ONLY) + str += "Read-only, "; + + if (!str.empty()) + str.erase(str.length() - 2); + + return str; +} + +double disk_total(const callbackInfo_t* callbackInfo) +{ + struct statfs fs; + if (!get_disk_info(callbackInfo, &fs)) + return 0; + + return static_cast<double>(fs.f_blocks * fs.f_bsize); +} + +double disk_free(const callbackInfo_t* callbackInfo) +{ + struct statfs fs; + if (!get_disk_info(callbackInfo, &fs)) + return 0; + + return static_cast<double>(fs.f_bfree * fs.f_bsize); +} + +double disk_used(const callbackInfo_t *callbackInfo) +{ + return disk_total(callbackInfo) - disk_free(callbackInfo); +} + #endif diff --git a/src/core-modules/macos/gpu.cc b/src/core-modules/macos/gpu.cc new file mode 100644 index 00000000..0a9413d7 --- /dev/null +++ b/src/core-modules/macos/gpu.cc @@ -0,0 +1,13 @@ +#include "platform.hpp" +#if CF_MACOS + +#include "core-modules.hh" +#include "cufetch/common.hh" + +MODFUNC(gpu_name) +{ return MAGIC_LINE; } + +MODFUNC(gpu_vendor) +{ return "Intel"; } + +#endif diff --git a/src/core-modules/macos/os.cc b/src/core-modules/macos/os.cc index 226852a5..82ba08f0 100644 --- a/src/core-modules/macos/os.cc +++ b/src/core-modules/macos/os.cc @@ -1,12 +1,15 @@ #include "platform.hpp" #if CF_MACOS +#include <sys/sysctl.h> #include <fstream> #include <string> + #include "core-modules.hh" #include "cufetch/common.hh" #include "rapidxml-1.13/rapidxml.hpp" #include "switch_fnv1a.hpp" +#include "util.hpp" std::ifstream f("/System/Library/CoreServices/SystemVersion.plist", std::ios::in); std::string buffer(std::istreambuf_iterator<char>{ f }, std::istreambuf_iterator<char>{}); @@ -87,6 +90,9 @@ static std::string get_plist_value(const std::string_view name) MODFUNC(os_name) { return get_plist_value("ProductName"); } +MODFUNC(os_name_id) +{ return "macos"; } + MODFUNC(os_version_id) { return get_plist_value("ProductUserVisibleVersion"); } diff --git a/src/core-modules/macos/ram.cc b/src/core-modules/macos/ram.cc index 0c810341..2e599bfd 100644 --- a/src/core-modules/macos/ram.cc +++ b/src/core-modules/macos/ram.cc @@ -9,8 +9,8 @@ #include "core-modules.hh" -struct xsw_usage xsw; -const uint64_t xsw_length{sizeof(xsw)}; +xsw_usage xsw; +size_t xsw_length{sizeof(xsw)}; static bool populate_xsw() { @@ -25,7 +25,7 @@ double ram_total() size_t length = sizeof(amount); if (sysctl(name, 2, &amount, &length, NULL, 0) != 0) return 0.0; - return static_cast<double>(amount) / 1024; + return static_cast<double>(amount); } double ram_used() @@ -49,7 +49,7 @@ double ram_used() + vmstat.compressor_page_count - vmstat.purgeable_count - vmstat.external_page_count - ) * page_size) / 1024; + ) * page_size); } double ram_free() diff --git a/src/core-modules/macos/system.cc b/src/core-modules/macos/system.cc new file mode 100644 index 00000000..f18020e6 --- /dev/null +++ b/src/core-modules/macos/system.cc @@ -0,0 +1,262 @@ +#include "platform.hpp" +#if CF_MACOS + +#include <sys/sysctl.h> + +#include "core-modules.hh" +#include "cufetch/common.hh" +#include "switch_fnv1a.hpp" +#include "util.hpp" + +#include <string> +#include <regex> // -100000000 runtime/compile-time +#include <string_view> + +static bool get_sysctl(const char* name, void* ret, size_t* oldlenp) +{ + return (sysctlbyname(name, ret, oldlenp, NULL, 0) == 0); +} + +// https://github.com/fastfetch-cli/fastfetch/blob/a734f18fd56014f5c0b9fb388727b778e2bc05d1/src/detection/host/host_mac.c#L4 +const char* get_host_from_family(const std::string_view host_family) +{ + // Macbook Pro: https://support.apple.com/en-us/HT201300 + // Macbook Air: https://support.apple.com/en-us/HT201862 + // Mac mini: https://support.apple.com/en-us/HT201894 + // iMac: https://support.apple.com/en-us/HT201634 + // Mac Pro: https://support.apple.com/en-us/HT202888 + // Mac Studio: https://support.apple.com/en-us/HT213073 + + if (hasStart(host_family, "MacBookPro")) + { + const std::string_view version = host_family.substr("MacBookPro"_len); + switch (fnv1a16::hash(version.data())) + { + case "18,3"_fnv1a16: + case "18,4"_fnv1a16: return "MacBook Pro (14-inch, 2021)"; + case "18,1"_fnv1a16: + case "18,2"_fnv1a16: return "MacBook Pro (16-inch, 2021)"; + case "17,1"_fnv1a16: return "MacBook Pro (13-inch, M1, 2020)"; + case "16,3"_fnv1a16: return "MacBook Pro (13-inch, 2020, Two Thunderbolt 3 ports)"; + case "16,2"_fnv1a16: return "MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports)"; + case "16,4"_fnv1a16: + case "16,1"_fnv1a16: return "MacBook Pro (16-inch, 2019)"; + case "15,4"_fnv1a16: return "MacBook Pro (13-inch, 2019, Two Thunderbolt 3 ports)"; + case "15,3"_fnv1a16: return "MacBook Pro (15-inch, 2019)"; + case "15,2"_fnv1a16: return "MacBook Pro (13-inch, 2018/2019, Four Thunderbolt 3 ports)"; + case "15,1"_fnv1a16: return "MacBook Pro (15-inch, 2018/2019)"; + case "14,3"_fnv1a16: return "MacBook Pro (15-inch, 2017)"; + case "14,2"_fnv1a16: return "MacBook Pro (13-inch, 2017, Four Thunderbolt 3 ports)"; + case "14,1"_fnv1a16: return "MacBook Pro (13-inch, 2017, Two Thunderbolt 3 ports)"; + case "13,3"_fnv1a16: return "MacBook Pro (15-inch, 2016)"; + case "13,2"_fnv1a16: return "MacBook Pro (13-inch, 2016, Four Thunderbolt 3 ports)"; + case "13,1"_fnv1a16: return "MacBook Pro (13-inch, 2016, Two Thunderbolt 3 ports)"; + case "12,1"_fnv1a16: return "MacBook Pro (Retina, 13-inch, Early 2015)"; + case "11,4"_fnv1a16: + case "11,5"_fnv1a16: return "MacBook Pro (Retina, 15-inch, Mid 2015)"; + case "11,2"_fnv1a16: + case "11,3"_fnv1a16: return "MacBook Pro (Retina, 15-inch, Late 2013/Mid 2014)"; + case "11,1"_fnv1a16: return "MacBook Pro (Retina, 13-inch, Late 2013/Mid 2014)"; + case "10,2"_fnv1a16: return "MacBook Pro (Retina, 13-inch, Late 2012/Early 2013)"; + case "10,1"_fnv1a16: return "MacBook Pro (Retina, 15-inch, Mid 2012/Early 2013)"; + case "9,2"_fnv1a16: return "MacBook Pro (13-inch, Mid 2012)"; + case "9,1"_fnv1a16: return "MacBook Pro (15-inch, Mid 2012)"; + case "8,3"_fnv1a16: return "MacBook Pro (17-inch, 2011)"; + case "8,2"_fnv1a16: return "MacBook Pro (15-inch, 2011)"; + case "8,1"_fnv1a16: return "MacBook Pro (13-inch, 2011)"; + case "7,1"_fnv1a16: return "MacBook Pro (13-inch, Mid 2010)"; + case "6,2"_fnv1a16: return "MacBook Pro (15-inch, Mid 2010)"; + case "6,1"_fnv1a16: return "MacBook Pro (17-inch, Mid 2010)"; + case "5,5"_fnv1a16: return "MacBook Pro (13-inch, Mid 2009)"; + case "5,3"_fnv1a16: return "MacBook Pro (15-inch, Mid 2009)"; + case "5,2"_fnv1a16: return "MacBook Pro (17-inch, Mid/Early 2009)"; + case "5,1"_fnv1a16: return "MacBook Pro (15-inch, Late 2008)"; + case "4,1"_fnv1a16: return "MacBook Pro (17/15-inch, Early 2008)"; + } + } + else if (hasStart(host_family, "MacBookAir")) + { + const std::string_view version = host_family.substr("MacBookAir"_len); + switch (fnv1a16::hash(version.data())) + { + case "10,1"_fnv1a16: return "MacBook Air (M1, 2020)"; + case "9,1"_fnv1a16: return "MacBook Air (Retina, 13-inch, 2020)"; + case "8,2"_fnv1a16: return "MacBook Air (Retina, 13-inch, 2019)"; + case "8,1"_fnv1a16: return "MacBook Air (Retina, 13-inch, 2018)"; + case "7,2"_fnv1a16: return "MacBook Air (13-inch, Early 2015/2017)"; + case "7,1"_fnv1a16: return "MacBook Air (11-inch, Early 2015)"; + case "6,2"_fnv1a16: return "MacBook Air (13-inch, Mid 2013/Early 2014)"; + case "6,1"_fnv1a16: return "MacBook Air (11-inch, Mid 2013/Early 2014)"; + case "5,2"_fnv1a16: return "MacBook Air (13-inch, Mid 2012)"; + case "5,1"_fnv1a16: return "MacBook Air (11-inch, Mid 2012)"; + case "4,2"_fnv1a16: return "MacBook Air (13-inch, Mid 2011)"; + case "4,1"_fnv1a16: return "MacBook Air (11-inch, Mid 2011)"; + case "3,2"_fnv1a16: return "MacBook Air (13-inch, Late 2010)"; + case "3,1"_fnv1a16: return "MacBook Air (11-inch, Late 2010)"; + case "2,1"_fnv1a16: return "MacBook Air (Mid 2009)"; + } + } + else if (hasStart(host_family, "Macmini")) + { + const std::string_view version = host_family.substr("Macmini"_len); + switch (fnv1a16::hash(version.data())) + { + case "9,1"_fnv1a16: return "Mac mini (M1, 2020)"; + case "8,1"_fnv1a16: return "Mac mini (2018)"; + case "7,1"_fnv1a16: return "Mac mini (Mid 2014)"; + case "6,1"_fnv1a16: + case "6,2"_fnv1a16: return "Mac mini (Late 2012)"; + case "5,1"_fnv1a16: + case "5,2"_fnv1a16: return "Mac mini (Mid 2011)"; + case "4,1"_fnv1a16: return "Mac mini (Mid 2010)"; + case "3,1"_fnv1a16: return "Mac mini (Early/Late 2009)"; + } + } + else if (hasStart(host_family, "MacBook")) + { + const std::string_view version = host_family.substr("MacBook"_len); + switch (fnv1a16::hash(version.data())) + { + case "10,1"_fnv1a16: return "MacBook (Retina, 12-inch, 2017)"; + case "9,1"_fnv1a16: return "MacBook (Retina, 12-inch, Early 2016)"; + case "8,1"_fnv1a16: return "MacBook (Retina, 12-inch, Early 2015)"; + case "7,1"_fnv1a16: return "MacBook (13-inch, Mid 2010)"; + case "6,1"_fnv1a16: return "MacBook (13-inch, Late 2009)"; + case "5,2"_fnv1a16: return "MacBook (13-inch, Early/Mid 2009)"; + } + } + else if (hasStart(host_family, "MacPro")) + { + const std::string_view version = host_family.substr("MacPro"_len); + switch (fnv1a16::hash(version.data())) + { + case "7,1"_fnv1a16: return "Mac Pro (2019)"; + case "6,1"_fnv1a16: return "Mac Pro (Late 2013)"; + case "5,1"_fnv1a16: return "Mac Pro (Mid 2010 - Mid 2012)"; + case "4,1"_fnv1a16: return "Mac Pro (Early 2009)"; + } + } + else if (hasStart(host_family, "Mac")) + { + const std::string_view version = host_family.substr("Mac"_len); + switch (fnv1a16::hash(version.data())) + { + case "16,13"_fnv1a16: return "MacBook Air (15-inch, M4, 2025)"; + case "16,12"_fnv1a16: return "MacBook Air (13-inch, M4, 2025)"; + case "16,11"_fnv1a16: + case "16,10"_fnv1a16: return "Mac Mini (2024)"; + case "16,9"_fnv1a16: return "Mac Studio (M4 Max, 2025)"; + case "16,3"_fnv1a16: return "iMac (24-inch, 2024, Four Thunderbolt / USB 4 ports)"; + case "16,2"_fnv1a16: return "iMac (24-inch, 2024, Two Thunderbolt / USB 4 ports)"; + case "16,1"_fnv1a16: return "MacBook Pro (14-inch, 2024, Three Thunderbolt 4 ports)"; + case "16,6"_fnv1a16: + case "16,8"_fnv1a16: return "MacBook Pro (14-inch, 2024, Three Thunderbolt 5 ports)"; + case "16,7"_fnv1a16: + case "16,5"_fnv1a16: return "MacBook Pro (16-inch, 2024, Three Thunderbolt 5 ports)"; + case "15,14"_fnv1a16: return "Mac Studio (M3 Ultra, 2025)"; + case "15,13"_fnv1a16: return "MacBook Air (15-inch, M3, 2024)"; + case "15,12"_fnv1a16: return "MacBook Air (13-inch, M3, 2024)"; + case "15,3"_fnv1a16: return "MacBook Pro (14-inch, Nov 2023, Two Thunderbolt / USB 4 ports)"; + case "15,4"_fnv1a16: return "iMac (24-inch, 2023, Two Thunderbolt / USB 4 ports)"; + case "15,5"_fnv1a16: return "iMac (24-inch, 2023, Two Thunderbolt / USB 4 ports, Two USB 3 ports)"; + case "15,6"_fnv1a16: + case "15,8"_fnv1a16: + case "15,10"_fnv1a16: return "MacBook Pro (14-inch, Nov 2023, Three Thunderbolt 4 ports)"; + case "15,7"_fnv1a16: + case "15,9"_fnv1a16: + case "15,11"_fnv1a16: return "MacBook Pro (16-inch, Nov 2023, Three Thunderbolt 4 ports)"; + case "14,15"_fnv1a16: return "MacBook Air (15-inch, M2, 2023)"; + case "14,14"_fnv1a16: return "Mac Studio (M2 Ultra, 2023, Two Thunderbolt 4 front ports)"; + case "14,13"_fnv1a16: return "Mac Studio (M2 Max, 2023, Two USB-C front ports)"; + case "14,8"_fnv1a16: return "Mac Pro (2023)"; + case "14,6"_fnv1a16: + case "14,10"_fnv1a16: return "MacBook Pro (16-inch, 2023)"; + case "14,5"_fnv1a16: + case "14,9"_fnv1a16: return "MacBook Pro (14-inch, 2023)"; + case "14,3"_fnv1a16: return "Mac mini (M2, 2023, Two Thunderbolt 4 ports)"; + case "14,12"_fnv1a16: return "Mac mini (M2, 2023, Four Thunderbolt 4 ports)"; + case "14,7"_fnv1a16: return "MacBook Pro (13-inch, M2, 2022)"; + case "14,2"_fnv1a16: return "MacBook Air (M2, 2022)"; + case "13,1"_fnv1a16: return "Mac Studio (M1 Max, 2022, Two USB-C front ports)"; + case "13,2"_fnv1a16: return "Mac Studio (M1 Ultra, 2022, Two Thunderbolt 4 front ports)"; + } + } + else if (hasStart(host_family, "iMac")) + { + const std::string_view version = host_family.substr("iMac"_len); + switch (fnv1a16::hash(version.data())) + { + case "21,1"_fnv1a16: return "iMac (24-inch, M1, 2021, Two Thunderbolt / USB 4 ports, Two USB 3 ports)"; + case "21,2"_fnv1a16: return "iMac (24-inch, M1, 2021, Two Thunderbolt / USB 4 ports)"; + case "20,1"_fnv1a16: + case "20,2"_fnv1a16: return "iMac (Retina 5K, 27-inch, 2020)"; + case "19,1"_fnv1a16: return "iMac (Retina 5K, 27-inch, 2019)"; + case "19,2"_fnv1a16: return "iMac (Retina 4K, 21.5-inch, 2019)"; + case "Pro1,1"_fnv1a16: return "iMac Pro (2017)"; + case "18,3"_fnv1a16: return "iMac (Retina 5K, 27-inch, 2017)"; + case "18,2"_fnv1a16: return "iMac (Retina 4K, 21.5-inch, 2017)"; + case "18,1"_fnv1a16: return "iMac (21.5-inch, 2017)"; + case "17,1"_fnv1a16: return "iMac (Retina 5K, 27-inch, Late 2015)"; + case "16,2"_fnv1a16: return "iMac (Retina 4K, 21.5-inch, Late 2015)"; + case "16,1"_fnv1a16: return "iMac (21.5-inch, Late 2015)"; + case "15,1"_fnv1a16: return "iMac (Retina 5K, 27-inch, Late 2014 - Mid 2015)"; + case "14,4"_fnv1a16: return "iMac (21.5-inch, Mid 2014)"; + case "14,2"_fnv1a16: return "iMac (27-inch, Late 2013)"; + case "14,1"_fnv1a16: return "iMac (21.5-inch, Late 2013)"; + case "13,2"_fnv1a16: return "iMac (27-inch, Late 2012)"; + case "13,1"_fnv1a16: return "iMac (21.5-inch, Late 2012)"; + case "12,2"_fnv1a16: return "iMac (27-inch, Mid 2011)"; + case "12,1"_fnv1a16: return "iMac (21.5-inch, Mid 2011)"; + case "11,3"_fnv1a16: return "iMac (27-inch, Mid 2010)"; + case "11,2"_fnv1a16: return "iMac (21.5-inch, Mid 2010)"; + case "10,1"_fnv1a16: return "iMac (27/21.5-inch, Late 2009)"; + case "9,1"_fnv1a16: return "iMac (24/20-inch, Early 2009)"; + } + } + + return UNKNOWN; +} + +MODFUNC(host_vendor) +{ return "Apple"; } + +MODFUNC(host_name) +{ + char buf[4096]; + size_t len = sizeof(buf); + if (!get_sysctl("hw.model", buf, &len)) + return MAGIC_LINE; + + const std::string_view host = get_host_from_family(buf); + return host.substr(0, host.find('(') - 1).data(); +} + +MODFUNC(host_version) +{ + char buf[4096]; + size_t len = sizeof(buf); + if (!get_sysctl("hw.model", buf, &len)) + return UNKNOWN; + + const std::string& host = get_host_from_family(buf); + std::regex year_regex(R"(\b(19|20)\d{2}\b)"); // Matches 1900–2099 + std::smatch match; + if (std::regex_search(host, match, year_regex)) + return match.str(0); + return UNKNOWN; +} + +MODFUNC(host) +{ + char buf[4096]; + size_t len = sizeof(buf); + if (!get_sysctl("hw.model", buf, &len)) + return MAGIC_LINE; + + return get_host_from_family(buf); +} + +MODFUNC(arch) +{ return g_uname_infos.machine; } + +#endif From 64f43ea167a8d8225e8358d543c456db6ea01e1d Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Wed, 16 Jul 2025 18:20:01 +0200 Subject: [PATCH 101/143] core-modules: macos: fix system.host.name and user.wm.name --- src/core-modules/linux/user.cc | 2 ++ src/core-modules/macos/system.cc | 8 ++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/core-modules/linux/user.cc b/src/core-modules/linux/user.cc index 37cb89e8..18eb491a 100644 --- a/src/core-modules/linux/user.cc +++ b/src/core-modules/linux/user.cc @@ -254,6 +254,7 @@ std::string get_wm_name(std::string& wm_path_exec) std::string path, proc_name, wm_name; const uid_t uid = getuid(); +#if !CF_MACOS for (auto const& dir_entry : std::filesystem::directory_iterator{ "/proc/" }) { if (!std::isdigit((dir_entry.path().string().at(6)))) // /proc/5 @@ -286,6 +287,7 @@ std::string get_wm_name(std::string& wm_path_exec) wm_path_exec = realpath((dir_entry.path().string() + "/exe").c_str(), buf); break; } +#endif debug("wm_name = {}", wm_name); if (wm_name.empty()) diff --git a/src/core-modules/macos/system.cc b/src/core-modules/macos/system.cc index f18020e6..03be2158 100644 --- a/src/core-modules/macos/system.cc +++ b/src/core-modules/macos/system.cc @@ -18,7 +18,7 @@ static bool get_sysctl(const char* name, void* ret, size_t* oldlenp) } // https://github.com/fastfetch-cli/fastfetch/blob/a734f18fd56014f5c0b9fb388727b778e2bc05d1/src/detection/host/host_mac.c#L4 -const char* get_host_from_family(const std::string_view host_family) +const std::string get_host_from_family(const std::string_view host_family) { // Macbook Pro: https://support.apple.com/en-us/HT201300 // Macbook Air: https://support.apple.com/en-us/HT201862 @@ -127,7 +127,7 @@ const char* get_host_from_family(const std::string_view host_family) } else if (hasStart(host_family, "MacPro")) { - const std::string_view version = host_family.substr("MacPro"_len); + const std::string_view version = host_family.substr("MacPro"_leMac Pro (2019)n); switch (fnv1a16::hash(version.data())) { case "7,1"_fnv1a16: return "Mac Pro (2019)"; @@ -227,8 +227,8 @@ MODFUNC(host_name) if (!get_sysctl("hw.model", buf, &len)) return MAGIC_LINE; - const std::string_view host = get_host_from_family(buf); - return host.substr(0, host.find('(') - 1).data(); + const std::string host = get_host_from_family(buf); + return host.substr(0, host.find('(') - 1); } MODFUNC(host_version) From 28931289bc2a1f4f9c71f7d6ec4cec3bea26758d Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Thu, 17 Jul 2025 17:51:51 +0200 Subject: [PATCH 102/143] clang-format --- include/config.hpp | 9 +- include/core-modules.hh | 6 +- include/cufetch/common.hh | 1 + include/cufetch/config.hh | 18 +-- include/parse.hpp | 1 - src/core-modules/android/battery.cc | 6 +- src/core-modules/android/system.cc | 9 +- src/core-modules/android/user.cc | 3 +- src/core-modules/core-modules.cc | 49 ++++--- src/core-modules/linux/battery.cc | 2 +- src/core-modules/linux/cpu.cc | 6 +- src/core-modules/linux/disk.cc | 26 ++-- src/core-modules/linux/os.cc | 2 +- src/core-modules/linux/ram.cc | 2 +- src/core-modules/linux/system.cc | 4 +- src/core-modules/linux/theme.cc | 21 +-- src/core-modules/linux/user.cc | 4 +- src/core-modules/linux/utils/dewm.hh | 27 ++-- src/core-modules/linux/utils/packages.cc | 2 +- src/core-modules/linux/utils/packages.hh | 22 +-- src/core-modules/linux/utils/term.hh | 2 +- src/core-modules/macos/cpu.cc | 13 +- src/core-modules/macos/disk.cc | 17 ++- src/core-modules/macos/os.cc | 5 +- src/core-modules/macos/ram.cc | 12 +- src/core-modules/macos/system.cc | 162 +++++++++++------------ 26 files changed, 212 insertions(+), 219 deletions(-) diff --git a/include/config.hpp b/include/config.hpp index 8f81eeb9..cafdd77f 100644 --- a/include/config.hpp +++ b/include/config.hpp @@ -26,14 +26,14 @@ #ifndef _CONFIG_HPP #define _CONFIG_HPP -#undef TOML_HEADER_ONLY +#undef TOML_HEADER_ONLY #define TOML_HEADER_ONLY 0 #include <filesystem> #include <string_view> -#include "platform.hpp" #include "cufetch/config.hh" +#include "platform.hpp" class Config : public ConfigBase { @@ -165,17 +165,16 @@ class Config : public ConfigBase } else if constexpr (std::is_convertible_v<T, std::string>) { - o.value_type = STR; + o.value_type = STR; o.string_value = value; } else if constexpr (std::is_convertible_v<T, int>) { o.value_type = INT; - o.int_value = value; + o.int_value = value; } overrides[key] = std::move(o); } - }; // default config diff --git a/include/core-modules.hh b/include/core-modules.hh index 875a4d44..91649ca3 100644 --- a/include/core-modules.hh +++ b/include/core-modules.hh @@ -3,8 +3,8 @@ #include <pwd.h> #include <sys/utsname.h> -#include "cufetch/cufetch.hh" #include "config.hpp" +#include "cufetch/cufetch.hh" #define MODFUNC(name) std::string name(__attribute__((unused)) const callbackInfo_t* callbackInfo) @@ -16,7 +16,7 @@ MODFUNC(host_version); MODFUNC(host_vendor); // os.cc -inline utsname g_uname_infos; +inline utsname g_uname_infos; inline std::FILE* os_release; MODFUNC(os_name); MODFUNC(os_pretty_name); @@ -36,7 +36,7 @@ MODFUNC(cpu_freq_cur); MODFUNC(cpu_freq_max); MODFUNC(cpu_freq_min); MODFUNC(cpu_freq_bios); -float cpu_temp(); +float cpu_temp(); MODFUNC(cpu_nproc); MODFUNC(cpu_name); MODFUNC(android_cpu_vendor); diff --git a/include/cufetch/common.hh b/include/cufetch/common.hh index c5270b1e..66870749 100644 --- a/include/cufetch/common.hh +++ b/include/cufetch/common.hh @@ -1,6 +1,7 @@ #pragma once #include <cstdlib> + #include "fmt/color.h" #include "fmt/core.h" diff --git a/include/cufetch/config.hh b/include/cufetch/config.hh index 9498bdc4..8c3df6da 100644 --- a/include/cufetch/config.hh +++ b/include/cufetch/config.hh @@ -4,9 +4,8 @@ #include <unordered_map> #define TOML_HEADER_ONLY 0 -#include "toml++/toml.hpp" - #include "cufetch/common.hh" +#include "toml++/toml.hpp" enum types { @@ -26,7 +25,6 @@ struct override_configs_types class EXPORT ConfigBase { public: - /** * Get value of config variables * @param value The config variable "path" (e.g "config.source-path") @@ -70,20 +68,18 @@ public: * @param value The config variable "path" (e.g "config.gui-red") * @param fallback Default value if couldn't retrive value */ - std::vector<std::string> getValueArrayStr(const std::string_view value, const std::vector<std::string>& fallback) const + std::vector<std::string> getValueArrayStr(const std::string_view value, + const std::vector<std::string>& fallback) const { std::vector<std::string> ret; // https://stackoverflow.com/a/78266628 if (const toml::array* array_it = tbl.at_path(value).as_array()) { - array_it->for_each( - [&ret](auto&& el) - { - if (const toml::value<std::string>* str_elem = el.as_string()) - ret.push_back((*str_elem)->data()); - } - ); + array_it->for_each([&ret](auto&& el) { + if (const toml::value<std::string>* str_elem = el.as_string()) + ret.push_back((*str_elem)->data()); + }); return ret; } diff --git a/include/parse.hpp b/include/parse.hpp index 074f55c3..b4912e54 100644 --- a/include/parse.hpp +++ b/include/parse.hpp @@ -39,5 +39,4 @@ std::string parse(const std::string& input, std::string& _, parse_args_t& parse_ */ std::string getInfoFromName(parse_args_t& parse_args, const std::string& moduleName); - #endif diff --git a/src/core-modules/android/battery.cc b/src/core-modules/android/battery.cc index 788e1ac6..279fd93b 100644 --- a/src/core-modules/android/battery.cc +++ b/src/core-modules/android/battery.cc @@ -5,14 +5,14 @@ #include <string_view> #include <vector> -#include "cufetch/fmt/format.h" #include "core-modules.hh" -#include "switch_fnv1a.hpp" #include "cufetch/common.hh" +#include "cufetch/fmt/format.h" #include "json.h" +#include "switch_fnv1a.hpp" #include "util.hpp" -static json::jobject doc; +static json::jobject doc; static std::vector<std::string> dumpsys; static bool assert_doc() diff --git a/src/core-modules/android/system.cc b/src/core-modules/android/system.cc index 5857bc18..e3d674eb 100644 --- a/src/core-modules/android/system.cc +++ b/src/core-modules/android/system.cc @@ -4,14 +4,15 @@ #include <string> #include <string_view> -#include "cufetch/common.hh" #include "core-modules.hh" +#include "cufetch/common.hh" #include "util.hpp" static constexpr std::array<std::string_view, 9> vendors_prop_names = { - "ro.product.marketname", "ro.vendor.product.display", "ro.vivo.market.name", "ro.config.devicename", - "ro.config.marketing_name", "ro.product.vendor.model", "ro.product.oppo_model", "ro.oppo.market.name", "ro.product.brand" - }; + "ro.product.marketname", "ro.vendor.product.display", "ro.vivo.market.name", + "ro.config.devicename", "ro.config.marketing_name", "ro.product.vendor.model", + "ro.product.oppo_model", "ro.oppo.market.name", "ro.product.brand" +}; MODFUNC(host) { diff --git a/src/core-modules/android/user.cc b/src/core-modules/android/user.cc index abe83147..e8eca565 100644 --- a/src/core-modules/android/user.cc +++ b/src/core-modules/android/user.cc @@ -2,6 +2,7 @@ #if CF_ANDROID #include <linux/limits.h> + #include <string> #include "core-modules.hh" @@ -24,7 +25,7 @@ MODFUNC(user_shell_name) MODFUNC(user_shell_version) { const std::string& shell_name = user_shell_name(callbackInfo); - std::string ret; + std::string ret; if (shell_name == "nu") ret = read_shell_exec("nu -c \"version | get version\""); diff --git a/src/core-modules/core-modules.cc b/src/core-modules/core-modules.cc index 9d00d829..0d3ee7bd 100644 --- a/src/core-modules/core-modules.cc +++ b/src/core-modules/core-modules.cc @@ -1,4 +1,4 @@ -#include "platform.hpp" +#include "core-modules.hh" #include <dlfcn.h> #include <unistd.h> @@ -10,17 +10,16 @@ #include <string_view> #include <utility> -#include "core-modules.hh" -#include "cufetch/cufetch.hh" #include "config.hpp" -#include "switch_fnv1a.hpp" +#include "cufetch/cufetch.hh" #include "fmt/format.h" -#include "util.hpp" - #include "linux/utils/packages.hh" +#include "platform.hpp" +#include "switch_fnv1a.hpp" +#include "util.hpp" #if !CF_MACOS -# include <mntent.h> +#include <mntent.h> #endif using unused = const callbackInfo_t*; @@ -68,8 +67,7 @@ static std::string get_auto_uptime(const std::uint16_t days, const std::uint16_t static std::string get_colors_symbol(const callbackInfo_t* callback, bool is_light) { const moduleArgs_t* symbolArg; - for (symbolArg = callback->moduleArgs; symbolArg && symbolArg->name != "symbol"; - symbolArg = symbolArg->next) + for (symbolArg = callback->moduleArgs; symbolArg && symbolArg->name != "symbol"; symbolArg = symbolArg->next) ; if (symbolArg->value.empty()) die( @@ -131,11 +129,10 @@ static std::string prettify_term_name(const std::string_view term_name) MODFUNC(disk_fmt) { - const callbackInfo_t *callback = callbackInfo; - const double used = disk_used(callback); - const double total = disk_total(callback); - const std::string& perc = - get_and_color_percentage(used, total, callback->parse_args, false); + const callbackInfo_t* callback = callbackInfo; + const double used = disk_used(callback); + const double total = disk_total(callback); + const std::string& perc = get_and_color_percentage(used, total, callback->parse_args, false); // clang-format off std::string result {fmt::format("{} / {} {}", @@ -147,7 +144,7 @@ MODFUNC(disk_fmt) const std::string& fsname = disk_fsname(callback); if (fsname != MAGIC_LINE) result += " - " + fsname; - + const std::string& types = disk_types(callback); if (!types.empty()) result += " [" + types + "]"; @@ -157,11 +154,10 @@ MODFUNC(disk_fmt) MODFUNC(ram_fmt) { - const callbackInfo_t *callback = callbackInfo; - const double used = ram_used(); - const double total = ram_total(); - const std::string& perc = - get_and_color_percentage(used, total, callback->parse_args, false); + const callbackInfo_t* callback = callbackInfo; + const double used = ram_used(); + const double total = ram_total(); + const std::string& perc = get_and_color_percentage(used, total, callback->parse_args, false); // clang-format off return fmt::format("{} / {} {}", @@ -174,14 +170,13 @@ MODFUNC(ram_fmt) MODFUNC(swap_fmt) { - const callbackInfo_t *callback = callbackInfo; - const double used = swap_used(); - const double total = swap_total(); + const callbackInfo_t* callback = callbackInfo; + const double used = swap_used(); + const double total = swap_total(); if (used < 1) return "Disabled"; - const std::string& perc = - get_and_color_percentage(used, total, callback->parse_args, false); + const std::string& perc = get_and_color_percentage(used, total, callback->parse_args, false); // clang-format off return fmt::format("{} / {} {}", @@ -194,7 +189,9 @@ MODFUNC(swap_fmt) MODFUNC(battery_fmt) { - return fmt::format("{} [{}]", get_and_color_percentage(std::stod(battery_perc(callbackInfo)), 100, callbackInfo->parse_args, true), battery_status(callbackInfo)); + return fmt::format( + "{} [{}]", get_and_color_percentage(std::stod(battery_perc(callbackInfo)), 100, callbackInfo->parse_args, true), + battery_status(callbackInfo)); } void core_plugins_start(const Config& config) diff --git a/src/core-modules/linux/battery.cc b/src/core-modules/linux/battery.cc index 191140d1..bf1464fc 100644 --- a/src/core-modules/linux/battery.cc +++ b/src/core-modules/linux/battery.cc @@ -5,8 +5,8 @@ #include <string> -#include "cufetch/common.hh" #include "core-modules.hh" +#include "cufetch/common.hh" #include "util.hpp" static std::string read_strip_syspath(const std::string_view path) diff --git a/src/core-modules/linux/cpu.cc b/src/core-modules/linux/cpu.cc index 87e8efa4..4f0fc98c 100644 --- a/src/core-modules/linux/cpu.cc +++ b/src/core-modules/linux/cpu.cc @@ -2,11 +2,11 @@ #if CF_ANDROID || CF_LINUX #include <unistd.h> -#include <string> #include <cstring> +#include <string> -#include "cufetch/common.hh" #include "core-modules.hh" +#include "cufetch/common.hh" #include "fmt/format.h" #include "switch_fnv1a.hpp" #include "util.hpp" @@ -565,7 +565,7 @@ MODFUNC(cpu_name) #elif CF_ANDROID if (!read_value("model name", "model name"_len, true, name, sizeof(name))) { - const std::string& vendor = android_cpu_vendor(nullptr); + const std::string& vendor = android_cpu_vendor(nullptr); const std::string& model_name = android_cpu_model_name(nullptr); if (vendor == "QTI" || vendor == "QUALCOMM") strcpy(name, fmt::format("Qualcomm {} [{}]", detect_qualcomm(model_name), model_name).c_str()); diff --git a/src/core-modules/linux/disk.cc b/src/core-modules/linux/disk.cc index 1dac351b..4665d8c5 100644 --- a/src/core-modules/linux/disk.cc +++ b/src/core-modules/linux/disk.cc @@ -8,8 +8,8 @@ #include <cstdio> -#include "cufetch/common.hh" #include "core-modules.hh" +#include "cufetch/common.hh" #include "cufetch/config.hh" #include "switch_fnv1a.hpp" #include "util.hpp" @@ -194,22 +194,19 @@ MODFUNC(disk_types) MODFUNC(auto_disk) { static std::vector<std::string> queried_devices; - const ConfigBase& config = callbackInfo->parse_args.config; + const ConfigBase& config = callbackInfo->parse_args.config; const std::string& auto_disks_fmt = config.getValue<std::string>("auto.disk.fmt", "${auto}Disk (%1): $<disk(%1)>"); - int auto_disks_types = 0; - for (const std::string& str : config.getValueArrayStr("auto.disk.display-types", {"external", "regular", "read-only"})) + int auto_disks_types = 0; + for (const std::string& str : + config.getValueArrayStr("auto.disk.display-types", { "external", "regular", "read-only" })) { switch (fnv1a16::hash(str)) { - case "removable"_fnv1a16: // deprecated - case "external"_fnv1a16: - auto_disks_types |= DISK_VOLUME_TYPE_EXTERNAL; break; - case "regular"_fnv1a16: - auto_disks_types |= DISK_VOLUME_TYPE_REGULAR; break; - case "read-only"_fnv1a16: - auto_disks_types |= DISK_VOLUME_TYPE_READ_ONLY; break; - case "hidden"_fnv1a16: - auto_disks_types |= DISK_VOLUME_TYPE_HIDDEN; break; + case "removable"_fnv1a16: // deprecated + case "external"_fnv1a16: auto_disks_types |= DISK_VOLUME_TYPE_EXTERNAL; break; + case "regular"_fnv1a16: auto_disks_types |= DISK_VOLUME_TYPE_REGULAR; break; + case "read-only"_fnv1a16: auto_disks_types |= DISK_VOLUME_TYPE_READ_ONLY; break; + case "hidden"_fnv1a16: auto_disks_types |= DISK_VOLUME_TYPE_HIDDEN; break; } } @@ -232,7 +229,8 @@ MODFUNC(auto_disk) debug("AUTO: pDevice->mnt_dir = {} && pDevice->mnt_fsname = {}", pDevice->mnt_dir, pDevice->mnt_fsname); callbackInfo->parse_args.no_more_reset = false; - callbackInfo->parse_args.tmp_layout.push_back(parse(format_auto_query_string(auto_disks_fmt, pDevice), callbackInfo->parse_args)); + callbackInfo->parse_args.tmp_layout.push_back( + parse(format_auto_query_string(auto_disks_fmt, pDevice), callbackInfo->parse_args)); if (fseek(mountsFile, old_position, SEEK_SET) == -1) die("Failed to seek back to saved position"); } diff --git a/src/core-modules/linux/os.cc b/src/core-modules/linux/os.cc index 2dca84f9..ff92006c 100644 --- a/src/core-modules/linux/os.cc +++ b/src/core-modules/linux/os.cc @@ -8,8 +8,8 @@ #include <string> #include <string_view> -#include "cufetch/common.hh" #include "core-modules.hh" +#include "cufetch/common.hh" #include "switch_fnv1a.hpp" #include "util.hpp" diff --git a/src/core-modules/linux/ram.cc b/src/core-modules/linux/ram.cc index 292196f7..1df20de2 100644 --- a/src/core-modules/linux/ram.cc +++ b/src/core-modules/linux/ram.cc @@ -5,8 +5,8 @@ #include <string> #include <string_view> -#include "cufetch/common.hh" #include "core-modules.hh" +#include "cufetch/common.hh" static double read_value(const std::string_view key) { diff --git a/src/core-modules/linux/system.cc b/src/core-modules/linux/system.cc index 27368f29..823ae028 100644 --- a/src/core-modules/linux/system.cc +++ b/src/core-modules/linux/system.cc @@ -7,15 +7,15 @@ #include <string> #include <string_view> -#include "cufetch/common.hh" #include "core-modules.hh" +#include "cufetch/common.hh" #include "util.hpp" MODFUNC(host) { const std::string syspath = "/sys/devices/virtual/dmi/id"; - std::string board_name{UNKNOWN}, board_version{UNKNOWN}, board_vendor{UNKNOWN}; + std::string board_name{ UNKNOWN }, board_version{ UNKNOWN }, board_vendor{ UNKNOWN }; if (std::filesystem::exists(syspath + "/board_name")) { diff --git a/src/core-modules/linux/theme.cc b/src/core-modules/linux/theme.cc index 9dea17b9..60fb827f 100644 --- a/src/core-modules/linux/theme.cc +++ b/src/core-modules/linux/theme.cc @@ -39,9 +39,9 @@ const std::string gsetting_interface = (user_de_name(NULL) == "cinnamon") ? "or : (de_name == "mate") ? "org.mate.interface" : "org.gnome.desktop.interface"; -const std::string dconf_interface = (user_de_name(NULL) == "cinnamon") ? "/org/cinnamon/desktop/interface" - : (de_name == "mate") ? "/org/mate/interface" - : "/org/gnome/desktop/interface"; +const std::string dconf_interface = (user_de_name(NULL) == "cinnamon") ? "/org/cinnamon/desktop/interface" + : (de_name == "mate") ? "/org/mate/interface" + : "/org/gnome/desktop/interface"; static std::string get_xsettings_xfce4(const std::string_view property, const std::string_view subproperty) { @@ -377,8 +377,9 @@ const std::string& wmde_name = MODFUNC(theme_gtk_name) { - const moduleArgs_t *moduleArg = callbackInfo->moduleArgs; - for (; moduleArg && moduleArg->name != "gtk"; moduleArg = moduleArg->next); + const moduleArgs_t* moduleArg = callbackInfo->moduleArgs; + for (; moduleArg && moduleArg->name != "gtk"; moduleArg = moduleArg->next) + ; if (!moduleArg) die("GTK version not provided"); int ver = std::stoi(moduleArg->value); @@ -390,8 +391,9 @@ MODFUNC(theme_gtk_name) MODFUNC(theme_gtk_icon) { - const moduleArgs_t *moduleArg = callbackInfo->moduleArgs; - for (; moduleArg && moduleArg->name != "gtk"; moduleArg = moduleArg->next); + const moduleArgs_t* moduleArg = callbackInfo->moduleArgs; + for (; moduleArg && moduleArg->name != "gtk"; moduleArg = moduleArg->next) + ; if (!moduleArg) die("GTK version not provided"); int ver = std::stoi(moduleArg->value); @@ -403,8 +405,9 @@ MODFUNC(theme_gtk_icon) MODFUNC(theme_gtk_font) { - const moduleArgs_t *moduleArg = callbackInfo->moduleArgs; - for (; moduleArg && moduleArg->name != "gtk"; moduleArg = moduleArg->next); + const moduleArgs_t* moduleArg = callbackInfo->moduleArgs; + for (; moduleArg && moduleArg->name != "gtk"; moduleArg = moduleArg->next) + ; if (!moduleArg) die("GTK version not provided"); int ver = std::stoi(moduleArg->value); diff --git a/src/core-modules/linux/user.cc b/src/core-modules/linux/user.cc index 18eb491a..39c1e0b2 100644 --- a/src/core-modules/linux/user.cc +++ b/src/core-modules/linux/user.cc @@ -5,8 +5,8 @@ #include <fstream> -#include "cufetch/common.hh" #include "core-modules.hh" +#include "cufetch/common.hh" #include "fmt/format.h" #include "switch_fnv1a.hpp" #include "util.hpp" @@ -80,7 +80,7 @@ MODFUNC(user_shell_name) MODFUNC(user_shell_version) { const std::string& shell_name = user_shell_name(callbackInfo); - std::string ret; + std::string ret; if (shell_name == "nu") ret = read_shell_exec("nu -c \"version | get version\""); diff --git a/src/core-modules/linux/utils/dewm.hh b/src/core-modules/linux/utils/dewm.hh index 002f6f17..3af8fa59 100644 --- a/src/core-modules/linux/utils/dewm.hh +++ b/src/core-modules/linux/utils/dewm.hh @@ -1,32 +1,31 @@ /* * Copyright 2025 Toni500git - * + * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef _DEWM_HPP #define _DEWM_HPP - #include <string> #include <string_view> @@ -36,6 +35,6 @@ std::string get_mate_version(); std::string get_xfce4_version(); std::string get_cinnamon_version(); std::string get_kwin_version(); -bool get_fast_xfwm4_version(std::string& ret, const std::string& exec_path); +bool get_fast_xfwm4_version(std::string& ret, const std::string& exec_path); -#endif // _DEWM_HPP +#endif // _DEWM_HPP diff --git a/src/core-modules/linux/utils/packages.cc b/src/core-modules/linux/utils/packages.cc index 2515be93..a323fe32 100644 --- a/src/core-modules/linux/utils/packages.cc +++ b/src/core-modules/linux/utils/packages.cc @@ -25,13 +25,13 @@ #include "packages.hh" -#include "util.hpp" #include <algorithm> #include <filesystem> #include <fstream> #include <string> #include "switch_fnv1a.hpp" +#include "util.hpp" static size_t get_num_count_dir(const std::string_view path) { diff --git a/src/core-modules/linux/utils/packages.hh b/src/core-modules/linux/utils/packages.hh index 84d162fd..8266f803 100644 --- a/src/core-modules/linux/utils/packages.hh +++ b/src/core-modules/linux/utils/packages.hh @@ -1,25 +1,25 @@ /* * Copyright 2025 Toni500git - * + * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ diff --git a/src/core-modules/linux/utils/term.hh b/src/core-modules/linux/utils/term.hh index 6365a407..82e51fe5 100644 --- a/src/core-modules/linux/utils/term.hh +++ b/src/core-modules/linux/utils/term.hh @@ -8,4 +8,4 @@ void get_term_version_exec(const std::string_view term, std::string& ret, bool _ bool fast_detect_konsole_ver(std::string& ret); bool fast_detect_st_ver(std::string& ret); -#endif // _TERM_HPP +#endif // _TERM_HPP diff --git a/src/core-modules/macos/cpu.cc b/src/core-modules/macos/cpu.cc index cd0ad83a..bc7f00e8 100644 --- a/src/core-modules/macos/cpu.cc +++ b/src/core-modules/macos/cpu.cc @@ -5,7 +5,6 @@ #include <unistd.h> #include <cstdint> -#include <string> #include <ratio> #include <string> @@ -43,8 +42,8 @@ MODFUNC(cpu_nproc) MODFUNC(cpu_freq_cur) { - std::uint64_t freq = 0; - size_t length = sizeof(freq); + std::uint64_t freq = 0; + size_t length = sizeof(freq); if (!get_sysctl("hw.cpufrequency", &freq, &length)) get_sysctl((int[2]){ CTL_HW, HW_CPU_FREQ }, &freq, &length); @@ -53,8 +52,8 @@ MODFUNC(cpu_freq_cur) MODFUNC(cpu_freq_min) { - std::uint64_t freq = 0; - size_t length = sizeof(freq); + std::uint64_t freq = 0; + size_t length = sizeof(freq); get_sysctl("hw.cpufrequency_min", &freq, &length); return fmt::to_string(static_cast<double>(freq) / std::giga().num); @@ -62,8 +61,8 @@ MODFUNC(cpu_freq_min) MODFUNC(cpu_freq_max) { - std::uint64_t freq = 0; - size_t length = sizeof(freq); + std::uint64_t freq = 0; + size_t length = sizeof(freq); get_sysctl("hw.cpufrequency_max", &freq, &length); return fmt::to_string(static_cast<double>(freq) / std::giga().num); diff --git a/src/core-modules/macos/disk.cc b/src/core-modules/macos/disk.cc index 47561bd7..63df0da1 100644 --- a/src/core-modules/macos/disk.cc +++ b/src/core-modules/macos/disk.cc @@ -1,17 +1,17 @@ #include "platform.hpp" #if CF_MACOS -#include "cufetch/common.hh" -#include "fmt/format.h" -#include "util.hpp" -#include "core-modules.hh" - -#include <sys/types.h> -#include <sys/param.h> #include <sys/mount.h> +#include <sys/param.h> +#include <sys/types.h> #include <string> +#include "core-modules.hh" +#include "cufetch/common.hh" +#include "fmt/format.h" +#include "util.hpp" + static std::string format_auto_query_string(std::string str, const struct statfs* fs) { replace_str(str, "%1", fs->f_mntonname); @@ -43,7 +43,7 @@ static int get_disk_type(const int flags) return type; } -static bool get_disk_info(const callbackInfo_t* callbackInfo, struct statfs *fs) +static bool get_disk_info(const callbackInfo_t* callbackInfo, struct statfs* fs) { if (callbackInfo->moduleArgs->name != "disk" || (callbackInfo->moduleArgs->name == "disk" && callbackInfo->moduleArgs->value.empty())) @@ -53,7 +53,6 @@ static bool get_disk_info(const callbackInfo_t* callbackInfo, struct statfs *fs) return (statfs(path.c_str(), fs) != 0); } - MODFUNC(disk_fsname) { struct statfs fs; diff --git a/src/core-modules/macos/os.cc b/src/core-modules/macos/os.cc index 82ba08f0..00a3e1c3 100644 --- a/src/core-modules/macos/os.cc +++ b/src/core-modules/macos/os.cc @@ -2,6 +2,7 @@ #if CF_MACOS #include <sys/sysctl.h> + #include <fstream> #include <string> @@ -11,8 +12,8 @@ #include "switch_fnv1a.hpp" #include "util.hpp" -std::ifstream f("/System/Library/CoreServices/SystemVersion.plist", std::ios::in); -std::string buffer(std::istreambuf_iterator<char>{ f }, std::istreambuf_iterator<char>{}); +std::ifstream f("/System/Library/CoreServices/SystemVersion.plist", std::ios::in); +std::string buffer(std::istreambuf_iterator<char>{ f }, std::istreambuf_iterator<char>{}); rapidxml::xml_document<> doc; static std::string get_codename(const std::string_view os_version_id) diff --git a/src/core-modules/macos/ram.cc b/src/core-modules/macos/ram.cc index 2e599bfd..f76a75a1 100644 --- a/src/core-modules/macos/ram.cc +++ b/src/core-modules/macos/ram.cc @@ -10,7 +10,7 @@ #include "core-modules.hh" xsw_usage xsw; -size_t xsw_length{sizeof(xsw)}; +size_t xsw_length{ sizeof(xsw) }; static bool populate_xsw() { @@ -30,13 +30,13 @@ double ram_total() double ram_used() { - int name[2] = { CTL_HW, HW_PAGESIZE }; - uint64_t amount = 0, page_size = 0; - size_t length = sizeof(amount); - mach_msg_type_number_t count = HOST_VM_INFO64_COUNT; + int name[2] = { CTL_HW, HW_PAGESIZE }; + uint64_t amount = 0, page_size = 0; + size_t length = sizeof(amount); + mach_msg_type_number_t count = HOST_VM_INFO64_COUNT; vm_statistics64_data_t vmstat; - sysctl(name, 2, &page_size, &length, NULL, 0); + sysctl(name, 2, &page_size, &length, NULL, 0); if (host_statistics64(mach_host_self(), HOST_VM_INFO64, (host_info64_t)(&vmstat), &count) != KERN_SUCCESS) return 0.0; diff --git a/src/core-modules/macos/system.cc b/src/core-modules/macos/system.cc index 03be2158..f3056523 100644 --- a/src/core-modules/macos/system.cc +++ b/src/core-modules/macos/system.cc @@ -3,15 +3,15 @@ #include <sys/sysctl.h> +#include <regex> // -100000000 runtime/compile-time +#include <string> +#include <string_view> + #include "core-modules.hh" #include "cufetch/common.hh" #include "switch_fnv1a.hpp" #include "util.hpp" -#include <string> -#include <regex> // -100000000 runtime/compile-time -#include <string_view> - static bool get_sysctl(const char* name, void* ret, size_t* oldlenp) { return (sysctlbyname(name, ret, oldlenp, NULL, 0) == 0); @@ -59,19 +59,19 @@ const std::string get_host_from_family(const std::string_view host_family) case "11,1"_fnv1a16: return "MacBook Pro (Retina, 13-inch, Late 2013/Mid 2014)"; case "10,2"_fnv1a16: return "MacBook Pro (Retina, 13-inch, Late 2012/Early 2013)"; case "10,1"_fnv1a16: return "MacBook Pro (Retina, 15-inch, Mid 2012/Early 2013)"; - case "9,2"_fnv1a16: return "MacBook Pro (13-inch, Mid 2012)"; - case "9,1"_fnv1a16: return "MacBook Pro (15-inch, Mid 2012)"; - case "8,3"_fnv1a16: return "MacBook Pro (17-inch, 2011)"; - case "8,2"_fnv1a16: return "MacBook Pro (15-inch, 2011)"; - case "8,1"_fnv1a16: return "MacBook Pro (13-inch, 2011)"; - case "7,1"_fnv1a16: return "MacBook Pro (13-inch, Mid 2010)"; - case "6,2"_fnv1a16: return "MacBook Pro (15-inch, Mid 2010)"; - case "6,1"_fnv1a16: return "MacBook Pro (17-inch, Mid 2010)"; - case "5,5"_fnv1a16: return "MacBook Pro (13-inch, Mid 2009)"; - case "5,3"_fnv1a16: return "MacBook Pro (15-inch, Mid 2009)"; - case "5,2"_fnv1a16: return "MacBook Pro (17-inch, Mid/Early 2009)"; - case "5,1"_fnv1a16: return "MacBook Pro (15-inch, Late 2008)"; - case "4,1"_fnv1a16: return "MacBook Pro (17/15-inch, Early 2008)"; + case "9,2"_fnv1a16: return "MacBook Pro (13-inch, Mid 2012)"; + case "9,1"_fnv1a16: return "MacBook Pro (15-inch, Mid 2012)"; + case "8,3"_fnv1a16: return "MacBook Pro (17-inch, 2011)"; + case "8,2"_fnv1a16: return "MacBook Pro (15-inch, 2011)"; + case "8,1"_fnv1a16: return "MacBook Pro (13-inch, 2011)"; + case "7,1"_fnv1a16: return "MacBook Pro (13-inch, Mid 2010)"; + case "6,2"_fnv1a16: return "MacBook Pro (15-inch, Mid 2010)"; + case "6,1"_fnv1a16: return "MacBook Pro (17-inch, Mid 2010)"; + case "5,5"_fnv1a16: return "MacBook Pro (13-inch, Mid 2009)"; + case "5,3"_fnv1a16: return "MacBook Pro (15-inch, Mid 2009)"; + case "5,2"_fnv1a16: return "MacBook Pro (17-inch, Mid/Early 2009)"; + case "5,1"_fnv1a16: return "MacBook Pro (15-inch, Late 2008)"; + case "4,1"_fnv1a16: return "MacBook Pro (17/15-inch, Early 2008)"; } } else if (hasStart(host_family, "MacBookAir")) @@ -80,20 +80,20 @@ const std::string get_host_from_family(const std::string_view host_family) switch (fnv1a16::hash(version.data())) { case "10,1"_fnv1a16: return "MacBook Air (M1, 2020)"; - case "9,1"_fnv1a16: return "MacBook Air (Retina, 13-inch, 2020)"; - case "8,2"_fnv1a16: return "MacBook Air (Retina, 13-inch, 2019)"; - case "8,1"_fnv1a16: return "MacBook Air (Retina, 13-inch, 2018)"; - case "7,2"_fnv1a16: return "MacBook Air (13-inch, Early 2015/2017)"; - case "7,1"_fnv1a16: return "MacBook Air (11-inch, Early 2015)"; - case "6,2"_fnv1a16: return "MacBook Air (13-inch, Mid 2013/Early 2014)"; - case "6,1"_fnv1a16: return "MacBook Air (11-inch, Mid 2013/Early 2014)"; - case "5,2"_fnv1a16: return "MacBook Air (13-inch, Mid 2012)"; - case "5,1"_fnv1a16: return "MacBook Air (11-inch, Mid 2012)"; - case "4,2"_fnv1a16: return "MacBook Air (13-inch, Mid 2011)"; - case "4,1"_fnv1a16: return "MacBook Air (11-inch, Mid 2011)"; - case "3,2"_fnv1a16: return "MacBook Air (13-inch, Late 2010)"; - case "3,1"_fnv1a16: return "MacBook Air (11-inch, Late 2010)"; - case "2,1"_fnv1a16: return "MacBook Air (Mid 2009)"; + case "9,1"_fnv1a16: return "MacBook Air (Retina, 13-inch, 2020)"; + case "8,2"_fnv1a16: return "MacBook Air (Retina, 13-inch, 2019)"; + case "8,1"_fnv1a16: return "MacBook Air (Retina, 13-inch, 2018)"; + case "7,2"_fnv1a16: return "MacBook Air (13-inch, Early 2015/2017)"; + case "7,1"_fnv1a16: return "MacBook Air (11-inch, Early 2015)"; + case "6,2"_fnv1a16: return "MacBook Air (13-inch, Mid 2013/Early 2014)"; + case "6,1"_fnv1a16: return "MacBook Air (11-inch, Mid 2013/Early 2014)"; + case "5,2"_fnv1a16: return "MacBook Air (13-inch, Mid 2012)"; + case "5,1"_fnv1a16: return "MacBook Air (11-inch, Mid 2012)"; + case "4,2"_fnv1a16: return "MacBook Air (13-inch, Mid 2011)"; + case "4,1"_fnv1a16: return "MacBook Air (11-inch, Mid 2011)"; + case "3,2"_fnv1a16: return "MacBook Air (13-inch, Late 2010)"; + case "3,1"_fnv1a16: return "MacBook Air (11-inch, Late 2010)"; + case "2,1"_fnv1a16: return "MacBook Air (Mid 2009)"; } } else if (hasStart(host_family, "Macmini")) @@ -118,16 +118,16 @@ const std::string get_host_from_family(const std::string_view host_family) switch (fnv1a16::hash(version.data())) { case "10,1"_fnv1a16: return "MacBook (Retina, 12-inch, 2017)"; - case "9,1"_fnv1a16: return "MacBook (Retina, 12-inch, Early 2016)"; - case "8,1"_fnv1a16: return "MacBook (Retina, 12-inch, Early 2015)"; - case "7,1"_fnv1a16: return "MacBook (13-inch, Mid 2010)"; - case "6,1"_fnv1a16: return "MacBook (13-inch, Late 2009)"; - case "5,2"_fnv1a16: return "MacBook (13-inch, Early/Mid 2009)"; + case "9,1"_fnv1a16: return "MacBook (Retina, 12-inch, Early 2016)"; + case "8,1"_fnv1a16: return "MacBook (Retina, 12-inch, Early 2015)"; + case "7,1"_fnv1a16: return "MacBook (13-inch, Mid 2010)"; + case "6,1"_fnv1a16: return "MacBook (13-inch, Late 2009)"; + case "5,2"_fnv1a16: return "MacBook (13-inch, Early/Mid 2009)"; } } else if (hasStart(host_family, "MacPro")) { - const std::string_view version = host_family.substr("MacPro"_leMac Pro (2019)n); + const std::string_view version = host_family.substr("MacPro"_leMac Pro(2019) n); switch (fnv1a16::hash(version.data())) { case "7,1"_fnv1a16: return "Mac Pro (2019)"; @@ -145,20 +145,20 @@ const std::string get_host_from_family(const std::string_view host_family) case "16,12"_fnv1a16: return "MacBook Air (13-inch, M4, 2025)"; case "16,11"_fnv1a16: case "16,10"_fnv1a16: return "Mac Mini (2024)"; - case "16,9"_fnv1a16: return "Mac Studio (M4 Max, 2025)"; - case "16,3"_fnv1a16: return "iMac (24-inch, 2024, Four Thunderbolt / USB 4 ports)"; - case "16,2"_fnv1a16: return "iMac (24-inch, 2024, Two Thunderbolt / USB 4 ports)"; - case "16,1"_fnv1a16: return "MacBook Pro (14-inch, 2024, Three Thunderbolt 4 ports)"; + case "16,9"_fnv1a16: return "Mac Studio (M4 Max, 2025)"; + case "16,3"_fnv1a16: return "iMac (24-inch, 2024, Four Thunderbolt / USB 4 ports)"; + case "16,2"_fnv1a16: return "iMac (24-inch, 2024, Two Thunderbolt / USB 4 ports)"; + case "16,1"_fnv1a16: return "MacBook Pro (14-inch, 2024, Three Thunderbolt 4 ports)"; case "16,6"_fnv1a16: - case "16,8"_fnv1a16: return "MacBook Pro (14-inch, 2024, Three Thunderbolt 5 ports)"; + case "16,8"_fnv1a16: return "MacBook Pro (14-inch, 2024, Three Thunderbolt 5 ports)"; case "16,7"_fnv1a16: - case "16,5"_fnv1a16: return "MacBook Pro (16-inch, 2024, Three Thunderbolt 5 ports)"; + case "16,5"_fnv1a16: return "MacBook Pro (16-inch, 2024, Three Thunderbolt 5 ports)"; case "15,14"_fnv1a16: return "Mac Studio (M3 Ultra, 2025)"; case "15,13"_fnv1a16: return "MacBook Air (15-inch, M3, 2024)"; case "15,12"_fnv1a16: return "MacBook Air (13-inch, M3, 2024)"; - case "15,3"_fnv1a16: return "MacBook Pro (14-inch, Nov 2023, Two Thunderbolt / USB 4 ports)"; - case "15,4"_fnv1a16: return "iMac (24-inch, 2023, Two Thunderbolt / USB 4 ports)"; - case "15,5"_fnv1a16: return "iMac (24-inch, 2023, Two Thunderbolt / USB 4 ports, Two USB 3 ports)"; + case "15,3"_fnv1a16: return "MacBook Pro (14-inch, Nov 2023, Two Thunderbolt / USB 4 ports)"; + case "15,4"_fnv1a16: return "iMac (24-inch, 2023, Two Thunderbolt / USB 4 ports)"; + case "15,5"_fnv1a16: return "iMac (24-inch, 2023, Two Thunderbolt / USB 4 ports, Two USB 3 ports)"; case "15,6"_fnv1a16: case "15,8"_fnv1a16: case "15,10"_fnv1a16: return "MacBook Pro (14-inch, Nov 2023, Three Thunderbolt 4 ports)"; @@ -168,17 +168,17 @@ const std::string get_host_from_family(const std::string_view host_family) case "14,15"_fnv1a16: return "MacBook Air (15-inch, M2, 2023)"; case "14,14"_fnv1a16: return "Mac Studio (M2 Ultra, 2023, Two Thunderbolt 4 front ports)"; case "14,13"_fnv1a16: return "Mac Studio (M2 Max, 2023, Two USB-C front ports)"; - case "14,8"_fnv1a16: return "Mac Pro (2023)"; + case "14,8"_fnv1a16: return "Mac Pro (2023)"; case "14,6"_fnv1a16: case "14,10"_fnv1a16: return "MacBook Pro (16-inch, 2023)"; case "14,5"_fnv1a16: - case "14,9"_fnv1a16: return "MacBook Pro (14-inch, 2023)"; - case "14,3"_fnv1a16: return "Mac mini (M2, 2023, Two Thunderbolt 4 ports)"; + case "14,9"_fnv1a16: return "MacBook Pro (14-inch, 2023)"; + case "14,3"_fnv1a16: return "Mac mini (M2, 2023, Two Thunderbolt 4 ports)"; case "14,12"_fnv1a16: return "Mac mini (M2, 2023, Four Thunderbolt 4 ports)"; - case "14,7"_fnv1a16: return "MacBook Pro (13-inch, M2, 2022)"; - case "14,2"_fnv1a16: return "MacBook Air (M2, 2022)"; - case "13,1"_fnv1a16: return "Mac Studio (M1 Max, 2022, Two USB-C front ports)"; - case "13,2"_fnv1a16: return "Mac Studio (M1 Ultra, 2022, Two Thunderbolt 4 front ports)"; + case "14,7"_fnv1a16: return "MacBook Pro (13-inch, M2, 2022)"; + case "14,2"_fnv1a16: return "MacBook Air (M2, 2022)"; + case "13,1"_fnv1a16: return "Mac Studio (M1 Max, 2022, Two USB-C front ports)"; + case "13,2"_fnv1a16: return "Mac Studio (M1 Ultra, 2022, Two Thunderbolt 4 front ports)"; } } else if (hasStart(host_family, "iMac")) @@ -186,31 +186,31 @@ const std::string get_host_from_family(const std::string_view host_family) const std::string_view version = host_family.substr("iMac"_len); switch (fnv1a16::hash(version.data())) { - case "21,1"_fnv1a16: return "iMac (24-inch, M1, 2021, Two Thunderbolt / USB 4 ports, Two USB 3 ports)"; - case "21,2"_fnv1a16: return "iMac (24-inch, M1, 2021, Two Thunderbolt / USB 4 ports)"; + case "21,1"_fnv1a16: return "iMac (24-inch, M1, 2021, Two Thunderbolt / USB 4 ports, Two USB 3 ports)"; + case "21,2"_fnv1a16: return "iMac (24-inch, M1, 2021, Two Thunderbolt / USB 4 ports)"; case "20,1"_fnv1a16: - case "20,2"_fnv1a16: return "iMac (Retina 5K, 27-inch, 2020)"; - case "19,1"_fnv1a16: return "iMac (Retina 5K, 27-inch, 2019)"; - case "19,2"_fnv1a16: return "iMac (Retina 4K, 21.5-inch, 2019)"; + case "20,2"_fnv1a16: return "iMac (Retina 5K, 27-inch, 2020)"; + case "19,1"_fnv1a16: return "iMac (Retina 5K, 27-inch, 2019)"; + case "19,2"_fnv1a16: return "iMac (Retina 4K, 21.5-inch, 2019)"; case "Pro1,1"_fnv1a16: return "iMac Pro (2017)"; - case "18,3"_fnv1a16: return "iMac (Retina 5K, 27-inch, 2017)"; - case "18,2"_fnv1a16: return "iMac (Retina 4K, 21.5-inch, 2017)"; - case "18,1"_fnv1a16: return "iMac (21.5-inch, 2017)"; - case "17,1"_fnv1a16: return "iMac (Retina 5K, 27-inch, Late 2015)"; - case "16,2"_fnv1a16: return "iMac (Retina 4K, 21.5-inch, Late 2015)"; - case "16,1"_fnv1a16: return "iMac (21.5-inch, Late 2015)"; - case "15,1"_fnv1a16: return "iMac (Retina 5K, 27-inch, Late 2014 - Mid 2015)"; - case "14,4"_fnv1a16: return "iMac (21.5-inch, Mid 2014)"; - case "14,2"_fnv1a16: return "iMac (27-inch, Late 2013)"; - case "14,1"_fnv1a16: return "iMac (21.5-inch, Late 2013)"; - case "13,2"_fnv1a16: return "iMac (27-inch, Late 2012)"; - case "13,1"_fnv1a16: return "iMac (21.5-inch, Late 2012)"; - case "12,2"_fnv1a16: return "iMac (27-inch, Mid 2011)"; - case "12,1"_fnv1a16: return "iMac (21.5-inch, Mid 2011)"; - case "11,3"_fnv1a16: return "iMac (27-inch, Mid 2010)"; - case "11,2"_fnv1a16: return "iMac (21.5-inch, Mid 2010)"; - case "10,1"_fnv1a16: return "iMac (27/21.5-inch, Late 2009)"; - case "9,1"_fnv1a16: return "iMac (24/20-inch, Early 2009)"; + case "18,3"_fnv1a16: return "iMac (Retina 5K, 27-inch, 2017)"; + case "18,2"_fnv1a16: return "iMac (Retina 4K, 21.5-inch, 2017)"; + case "18,1"_fnv1a16: return "iMac (21.5-inch, 2017)"; + case "17,1"_fnv1a16: return "iMac (Retina 5K, 27-inch, Late 2015)"; + case "16,2"_fnv1a16: return "iMac (Retina 4K, 21.5-inch, Late 2015)"; + case "16,1"_fnv1a16: return "iMac (21.5-inch, Late 2015)"; + case "15,1"_fnv1a16: return "iMac (Retina 5K, 27-inch, Late 2014 - Mid 2015)"; + case "14,4"_fnv1a16: return "iMac (21.5-inch, Mid 2014)"; + case "14,2"_fnv1a16: return "iMac (27-inch, Late 2013)"; + case "14,1"_fnv1a16: return "iMac (21.5-inch, Late 2013)"; + case "13,2"_fnv1a16: return "iMac (27-inch, Late 2012)"; + case "13,1"_fnv1a16: return "iMac (21.5-inch, Late 2012)"; + case "12,2"_fnv1a16: return "iMac (27-inch, Mid 2011)"; + case "12,1"_fnv1a16: return "iMac (21.5-inch, Mid 2011)"; + case "11,3"_fnv1a16: return "iMac (27-inch, Mid 2010)"; + case "11,2"_fnv1a16: return "iMac (21.5-inch, Mid 2010)"; + case "10,1"_fnv1a16: return "iMac (27/21.5-inch, Late 2009)"; + case "9,1"_fnv1a16: return "iMac (24/20-inch, Early 2009)"; } } @@ -222,7 +222,7 @@ MODFUNC(host_vendor) MODFUNC(host_name) { - char buf[4096]; + char buf[4096]; size_t len = sizeof(buf); if (!get_sysctl("hw.model", buf, &len)) return MAGIC_LINE; @@ -233,14 +233,14 @@ MODFUNC(host_name) MODFUNC(host_version) { - char buf[4096]; + char buf[4096]; size_t len = sizeof(buf); if (!get_sysctl("hw.model", buf, &len)) return UNKNOWN; const std::string& host = get_host_from_family(buf); - std::regex year_regex(R"(\b(19|20)\d{2}\b)"); // Matches 1900–2099 - std::smatch match; + std::regex year_regex(R"(\b(19|20)\d{2}\b)"); // Matches 1900–2099 + std::smatch match; if (std::regex_search(host, match, year_regex)) return match.str(0); return UNKNOWN; @@ -248,7 +248,7 @@ MODFUNC(host_version) MODFUNC(host) { - char buf[4096]; + char buf[4096]; size_t len = sizeof(buf); if (!get_sysctl("hw.model", buf, &len)) return MAGIC_LINE; From 8a69f64bcdc0557e20ccbacc634bec5c2fc6a958 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Thu, 17 Jul 2025 17:52:39 +0200 Subject: [PATCH 103/143] libcufetch (chore): remove debug infos and add hidden visibility --- libcufetch/Makefile | 8 ++++---- src/libs/toml++/Makefile | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libcufetch/Makefile b/libcufetch/Makefile index 2a59630c..13bad660 100644 --- a/libcufetch/Makefile +++ b/libcufetch/Makefile @@ -15,11 +15,11 @@ endif CXX ?= g++ GUI_APP ?= 0 -SRC = $(wildcard *.cc) -OBJ = $(SRC:.cc=.o) ../$(BUILDDIR)/toml.o -FMT_STATIC = ../$(BUILDDIR)/libfmt.a -CXXFLAGS += -ggdb3 -I../include -fPIC -DGUI_APP=$(GUI_APP) +SRC = $(wildcard *.cc) +OBJ = $(SRC:.cc=.o) ../$(BUILDDIR)/toml.o +FMT_STATIC = ../$(BUILDDIR)/libfmt.a OUTPUT := ../$(BUILDDIR)/$(LIBNAME) +CXXFLAGS += -fvisibility-inlines-hidden -fvisibility=hidden -I../include -fPIC -DGUI_APP=$(GUI_APP) all: $(OUTPUT) @if [ "$(UNAME_S)" = "Linux" ]; then \ diff --git a/src/libs/toml++/Makefile b/src/libs/toml++/Makefile index 49c6da04..e3714d25 100644 --- a/src/libs/toml++/Makefile +++ b/src/libs/toml++/Makefile @@ -1,7 +1,7 @@ CXX ?= g++ SRC = toml.cpp TARGET = toml.o -CXXFLAGS = -I../../../include/cufetch -fPIC -std=c++20 +CXXFLAGS = -I../../../include/cufetch -fvisibility-inlines-hidden -fvisibility=hidden -fPIC -std=c++20 all: $(TARGET) From fffa32d54c3e459500cdba06d7c5daf89d64cd74 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Thu, 17 Jul 2025 18:00:38 +0200 Subject: [PATCH 104/143] libcufetch (chore): rename include/cufetch -> include/libcufetch --- CMakeLists.txt | 12 ++++++------ Makefile | 6 +++--- cufetchpm/compile_flags.txt | 10 ++++++++++ cufetchpm/src/main.cpp | 3 ++- include/config.hpp | 2 +- include/core-modules.hh | 2 +- include/display.hpp | 2 +- include/fmt | 2 +- include/gui.hpp | 2 +- include/{cufetch => libcufetch}/common.hh | 0 include/{cufetch => libcufetch}/config.hh | 2 +- include/{cufetch => libcufetch}/cufetch.hh | 2 +- include/{cufetch => libcufetch}/fmt/args.h | 0 include/{cufetch => libcufetch}/fmt/base.h | 0 include/{cufetch => libcufetch}/fmt/chrono.h | 0 include/{cufetch => libcufetch}/fmt/color.h | 0 include/{cufetch => libcufetch}/fmt/compile.h | 0 include/{cufetch => libcufetch}/fmt/core.h | 0 include/{cufetch => libcufetch}/fmt/format-inl.h | 0 include/{cufetch => libcufetch}/fmt/format.h | 0 include/{cufetch => libcufetch}/fmt/os.h | 0 include/{cufetch => libcufetch}/fmt/ostream.h | 0 include/{cufetch => libcufetch}/fmt/ranges.h | 0 include/{cufetch => libcufetch}/fmt/std.h | 0 include/{cufetch => libcufetch}/parse.hh | 4 ++-- include/{cufetch => libcufetch}/toml++/toml.hpp | 0 include/parse.hpp | 2 +- include/toml++ | 2 +- include/util.hpp | 2 +- libcufetch/config.cc | 2 +- libcufetch/cufetch.cc | 2 +- libcufetch/parse.cc | 6 +++--- src/core-modules/android/battery.cc | 4 ++-- src/core-modules/android/gpu.cc | 2 +- src/core-modules/android/system.cc | 2 +- src/core-modules/android/theme.cc | 2 +- src/core-modules/core-modules.cc | 2 +- src/core-modules/linux/battery.cc | 2 +- src/core-modules/linux/cpu.cc | 2 +- src/core-modules/linux/disk.cc | 4 ++-- src/core-modules/linux/os.cc | 2 +- src/core-modules/linux/ram.cc | 2 +- src/core-modules/linux/system.cc | 2 +- src/core-modules/linux/user.cc | 2 +- src/core-modules/linux/utils/dewm.cc | 2 +- src/core-modules/macos/battery.cc | 2 +- src/core-modules/macos/disk.cc | 2 +- src/core-modules/macos/gpu.cc | 2 +- src/core-modules/macos/os.cc | 2 +- src/core-modules/macos/system.cc | 2 +- src/core-modules/macos/theme.cc | 2 +- src/libs/toml++/Makefile | 2 +- 52 files changed, 60 insertions(+), 49 deletions(-) create mode 100644 cufetchpm/compile_flags.txt rename include/{cufetch => libcufetch}/common.hh (100%) rename include/{cufetch => libcufetch}/config.hh (98%) rename include/{cufetch => libcufetch}/cufetch.hh (97%) rename include/{cufetch => libcufetch}/fmt/args.h (100%) rename include/{cufetch => libcufetch}/fmt/base.h (100%) rename include/{cufetch => libcufetch}/fmt/chrono.h (100%) rename include/{cufetch => libcufetch}/fmt/color.h (100%) rename include/{cufetch => libcufetch}/fmt/compile.h (100%) rename include/{cufetch => libcufetch}/fmt/core.h (100%) rename include/{cufetch => libcufetch}/fmt/format-inl.h (100%) rename include/{cufetch => libcufetch}/fmt/format.h (100%) rename include/{cufetch => libcufetch}/fmt/os.h (100%) rename include/{cufetch => libcufetch}/fmt/ostream.h (100%) rename include/{cufetch => libcufetch}/fmt/ranges.h (100%) rename include/{cufetch => libcufetch}/fmt/std.h (100%) rename include/{cufetch => libcufetch}/parse.hh (97%) rename include/{cufetch => libcufetch}/toml++/toml.hpp (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index d36c3f01..11326852 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,7 @@ set(CMAKE_CXX_VISIBILITY_PRESET hidden) set(CMAKE_VISIBILITY_INLINES_HIDDEN ON) include_directories(include) -include_directories(include/cufetch) +include_directories(include/libcufetch) set_source_files_properties( "src/libs/toml++/toml.cpp" @@ -94,9 +94,9 @@ target_link_libraries(${TARGET_NAME} PUBLIC fmt) # libcufetch set(CUFETCH_HEADERS - include/cufetch/config.hh - include/cufetch/common.hh - include/cufetch/cufetch.hh + include/libcufetch/config.hh + include/libcufetch/common.hh + include/libcufetch/cufetch.hh ) add_library(cufetch SHARED @@ -166,8 +166,8 @@ install(TARGETS cufetch COMPONENT runtime ) -install(DIRECTORY include/cufetch/ - DESTINATION include/cufetch +install(DIRECTORY include/libcufetch/ + DESTINATION include/libcufetch COMPONENT development ) diff --git a/Makefile b/Makefile index 9fc5732f..75f2177f 100644 --- a/Makefile +++ b/Makefile @@ -53,7 +53,7 @@ OBJ_CC = $(SRC_CC:.cc=.o) OBJ = $(OBJ_CPP) $(OBJ_CC) LDFLAGS += -L$(BUILDDIR) $(BUILDDIR)/libfmt.a -lcufetch -ldl CXXFLAGS ?= -mtune=generic -march=native -CXXFLAGS += -fvisibility-inlines-hidden -fvisibility=hidden -Iinclude -Iinclude/cufetch -std=c++20 $(VARS) -DVERSION=\"$(VERSION)\" -DLOCALEDIR=\"$(LOCALEDIR)\" -DICONPREFIX=\"$(ICONPREFIX)\" +CXXFLAGS += -fvisibility-inlines-hidden -fvisibility=hidden -Iinclude -Iinclude/libcufetch -std=c++20 $(VARS) -DVERSION=\"$(VERSION)\" -DLOCALEDIR=\"$(LOCALEDIR)\" -DICONPREFIX=\"$(ICONPREFIX)\" all: genver fmt toml json libcufetch $(TARGET) @@ -127,8 +127,8 @@ install-common: libcufetch locale cd assets/icons && find . -type f -exec install -Dm 644 "{}" "$(DESTDIR)$(ICONPREFIX)/$(NAME)/{}" \; find examples/ -type f -exec install -Dm 644 "{}" "$(DESTDIR)$(PREFIX)/share/$(NAME)/{}" \; find locale/ -type f -exec install -Dm 644 "{}" "$(DESTDIR)$(PREFIX)/share/{}" \; - mkdir -p $(DESTDIR)$(PREFIX)/include/cufetch/ - cd include/cufetch && find . -type f -exec install -Dm 644 "{}" "$(DESTDIR)$(PREFIX)/include/cufetch/{}" \; + mkdir -p $(DESTDIR)$(PREFIX)/include/libcufetch/ + cd include/libcufetch && find . -type f -exec install -Dm 644 "{}" "$(DESTDIR)$(PREFIX)/include/libcufetch/{}" \; install -Dm 755 $(BUILDDIR)/libcufetch.so $(DESTDIR)$(PREFIX)/lib/libcufetch.so.1 install -Dm 755 $(BUILDDIR)/libfmt.a $(DESTDIR)$(PREFIX)/lib/libcufetch-fmt.a ifeq ($(GUI_APP), 1) diff --git a/cufetchpm/compile_flags.txt b/cufetchpm/compile_flags.txt new file mode 100644 index 00000000..de766316 --- /dev/null +++ b/cufetchpm/compile_flags.txt @@ -0,0 +1,10 @@ +-I../include +-Wall +-Wextra +-Wpedantic +-std=c++20 +-DVERSION="1.0.0" +-DGUI_APP=1 +-DUSE_DCONF=1 +-DDEBUG=1 +-DENABLE_NLS=1 diff --git a/cufetchpm/src/main.cpp b/cufetchpm/src/main.cpp index 33d55f42..5071f959 100644 --- a/cufetchpm/src/main.cpp +++ b/cufetchpm/src/main.cpp @@ -1,6 +1,7 @@ #include <cstring> #include <string_view> -#include "common.hpp" + +#include "libcufetch/common.hpp" #include "fmt/base.h" bool download_git(const std::string_view url); diff --git a/include/config.hpp b/include/config.hpp index cafdd77f..0a4818a8 100644 --- a/include/config.hpp +++ b/include/config.hpp @@ -32,7 +32,7 @@ #include <filesystem> #include <string_view> -#include "cufetch/config.hh" +#include "libcufetch/config.hh" #include "platform.hpp" class Config : public ConfigBase diff --git a/include/core-modules.hh b/include/core-modules.hh index 91649ca3..1cb8d881 100644 --- a/include/core-modules.hh +++ b/include/core-modules.hh @@ -4,7 +4,7 @@ #include <sys/utsname.h> #include "config.hpp" -#include "cufetch/cufetch.hh" +#include "libcufetch/cufetch.hh" #define MODFUNC(name) std::string name(__attribute__((unused)) const callbackInfo_t* callbackInfo) diff --git a/include/display.hpp b/include/display.hpp index 66ec4d8a..d0169116 100644 --- a/include/display.hpp +++ b/include/display.hpp @@ -30,7 +30,7 @@ #include <vector> #include "config.hpp" -#include "cufetch/cufetch.hh" +#include "libcufetch/cufetch.hh" #include "platform.hpp" #if CF_MACOS diff --git a/include/fmt b/include/fmt index 49d413e3..5e93c20b 120000 --- a/include/fmt +++ b/include/fmt @@ -1 +1 @@ -cufetch/fmt \ No newline at end of file +libcufetch/fmt \ No newline at end of file diff --git a/include/gui.hpp b/include/gui.hpp index ed08fe02..c41b1915 100644 --- a/include/gui.hpp +++ b/include/gui.hpp @@ -29,7 +29,7 @@ #if GUI_APP #include "config.hpp" -#include "cufetch/cufetch.hh" +#include "libcufetch/cufetch.hh" #include "gdkmm/pixbuf.h" #include "gdkmm/pixbufanimation.h" #include "gtkmm/alignment.h" diff --git a/include/cufetch/common.hh b/include/libcufetch/common.hh similarity index 100% rename from include/cufetch/common.hh rename to include/libcufetch/common.hh diff --git a/include/cufetch/config.hh b/include/libcufetch/config.hh similarity index 98% rename from include/cufetch/config.hh rename to include/libcufetch/config.hh index 8c3df6da..d16c2735 100644 --- a/include/cufetch/config.hh +++ b/include/libcufetch/config.hh @@ -4,7 +4,7 @@ #include <unordered_map> #define TOML_HEADER_ONLY 0 -#include "cufetch/common.hh" +#include "libcufetch/common.hh" #include "toml++/toml.hpp" enum types diff --git a/include/cufetch/cufetch.hh b/include/libcufetch/cufetch.hh similarity index 97% rename from include/cufetch/cufetch.hh rename to include/libcufetch/cufetch.hh index ea2965b9..ec1f4f60 100644 --- a/include/cufetch/cufetch.hh +++ b/include/libcufetch/cufetch.hh @@ -4,7 +4,7 @@ #include <string> #include <vector> -#include "cufetch/parse.hh" +#include "libcufetch/parse.hh" // Map from a modules name to its pointer. using moduleMap_t = std::unordered_map<std::string, const module_t&>; diff --git a/include/cufetch/fmt/args.h b/include/libcufetch/fmt/args.h similarity index 100% rename from include/cufetch/fmt/args.h rename to include/libcufetch/fmt/args.h diff --git a/include/cufetch/fmt/base.h b/include/libcufetch/fmt/base.h similarity index 100% rename from include/cufetch/fmt/base.h rename to include/libcufetch/fmt/base.h diff --git a/include/cufetch/fmt/chrono.h b/include/libcufetch/fmt/chrono.h similarity index 100% rename from include/cufetch/fmt/chrono.h rename to include/libcufetch/fmt/chrono.h diff --git a/include/cufetch/fmt/color.h b/include/libcufetch/fmt/color.h similarity index 100% rename from include/cufetch/fmt/color.h rename to include/libcufetch/fmt/color.h diff --git a/include/cufetch/fmt/compile.h b/include/libcufetch/fmt/compile.h similarity index 100% rename from include/cufetch/fmt/compile.h rename to include/libcufetch/fmt/compile.h diff --git a/include/cufetch/fmt/core.h b/include/libcufetch/fmt/core.h similarity index 100% rename from include/cufetch/fmt/core.h rename to include/libcufetch/fmt/core.h diff --git a/include/cufetch/fmt/format-inl.h b/include/libcufetch/fmt/format-inl.h similarity index 100% rename from include/cufetch/fmt/format-inl.h rename to include/libcufetch/fmt/format-inl.h diff --git a/include/cufetch/fmt/format.h b/include/libcufetch/fmt/format.h similarity index 100% rename from include/cufetch/fmt/format.h rename to include/libcufetch/fmt/format.h diff --git a/include/cufetch/fmt/os.h b/include/libcufetch/fmt/os.h similarity index 100% rename from include/cufetch/fmt/os.h rename to include/libcufetch/fmt/os.h diff --git a/include/cufetch/fmt/ostream.h b/include/libcufetch/fmt/ostream.h similarity index 100% rename from include/cufetch/fmt/ostream.h rename to include/libcufetch/fmt/ostream.h diff --git a/include/cufetch/fmt/ranges.h b/include/libcufetch/fmt/ranges.h similarity index 100% rename from include/cufetch/fmt/ranges.h rename to include/libcufetch/fmt/ranges.h diff --git a/include/cufetch/fmt/std.h b/include/libcufetch/fmt/std.h similarity index 100% rename from include/cufetch/fmt/std.h rename to include/libcufetch/fmt/std.h diff --git a/include/cufetch/parse.hh b/include/libcufetch/parse.hh similarity index 97% rename from include/cufetch/parse.hh rename to include/libcufetch/parse.hh index 3b0429b5..52f86c7b 100644 --- a/include/cufetch/parse.hh +++ b/include/libcufetch/parse.hh @@ -4,8 +4,8 @@ #include <unordered_map> #include <vector> -#include "cufetch/common.hh" -#include "cufetch/config.hh" +#include "libcufetch/common.hh" +#include "libcufetch/config.hh" struct module_t; diff --git a/include/cufetch/toml++/toml.hpp b/include/libcufetch/toml++/toml.hpp similarity index 100% rename from include/cufetch/toml++/toml.hpp rename to include/libcufetch/toml++/toml.hpp diff --git a/include/parse.hpp b/include/parse.hpp index b4912e54..ded8f4d9 100644 --- a/include/parse.hpp +++ b/include/parse.hpp @@ -26,7 +26,7 @@ #ifndef _PARSE_HPP #define _PARSE_HPP -#include "cufetch/parse.hh" +#include "libcufetch/parse.hh" // some times we don't want to use the original pureOutput, // so we have to create a tmp string just for the sake of the function arguments diff --git a/include/toml++ b/include/toml++ index c7e6a8cb..ff05b4aa 120000 --- a/include/toml++ +++ b/include/toml++ @@ -1 +1 @@ -cufetch/toml++ \ No newline at end of file +libcufetch/toml++ \ No newline at end of file diff --git a/include/util.hpp b/include/util.hpp index 82919a34..cee4153c 100644 --- a/include/util.hpp +++ b/include/util.hpp @@ -36,7 +36,7 @@ #include <string> #include <vector> -#include "cufetch/common.hh" +#include "libcufetch/common.hh" #include "fmt/base.h" #include "fmt/color.h" #include "platform.hpp" diff --git a/libcufetch/config.cc b/libcufetch/config.cc index 77c12919..5dd06710 100644 --- a/libcufetch/config.cc +++ b/libcufetch/config.cc @@ -23,7 +23,7 @@ * */ -#include "cufetch/config.hh" +#include "libcufetch/config.hh" template int ConfigBase::getValue<int>(const std::string_view, const int&&) const; template std::string ConfigBase::getValue<std::string>(const std::string_view, const std::string&&) const; diff --git a/libcufetch/cufetch.cc b/libcufetch/cufetch.cc index 0c72e638..039ef503 100644 --- a/libcufetch/cufetch.cc +++ b/libcufetch/cufetch.cc @@ -1,4 +1,4 @@ -#include "cufetch/cufetch.hh" +#include "libcufetch/cufetch.hh" static std::vector<module_t> modules; diff --git a/libcufetch/parse.cc b/libcufetch/parse.cc index ec6563f9..a7be701d 100644 --- a/libcufetch/parse.cc +++ b/libcufetch/parse.cc @@ -37,9 +37,9 @@ #include <string_view> #include <vector> -#include "cufetch/common.hh" -#include "cufetch/config.hh" -#include "cufetch/cufetch.hh" +#include "libcufetch/common.hh" +#include "libcufetch/config.hh" +#include "libcufetch/cufetch.hh" #include "fmt/color.h" #include "fmt/format.h" #include "switch_fnv1a.hpp" diff --git a/src/core-modules/android/battery.cc b/src/core-modules/android/battery.cc index 279fd93b..e95b1cb6 100644 --- a/src/core-modules/android/battery.cc +++ b/src/core-modules/android/battery.cc @@ -6,8 +6,8 @@ #include <vector> #include "core-modules.hh" -#include "cufetch/common.hh" -#include "cufetch/fmt/format.h" +#include "libcufetch/common.hh" +#include "libcufetch/fmt/format.h" #include "json.h" #include "switch_fnv1a.hpp" #include "util.hpp" diff --git a/src/core-modules/android/gpu.cc b/src/core-modules/android/gpu.cc index f679a072..d2bdf042 100644 --- a/src/core-modules/android/gpu.cc +++ b/src/core-modules/android/gpu.cc @@ -4,7 +4,7 @@ #include <string> #include "core-modules.hh" -#include "cufetch/common.hh" +#include "libcufetch/common.hh" #include "switch_fnv1a.hpp" // https://en.wikipedia.org/wiki/List_of_Qualcomm_Snapdragon_systems_on_chips diff --git a/src/core-modules/android/system.cc b/src/core-modules/android/system.cc index e3d674eb..a9dbc85e 100644 --- a/src/core-modules/android/system.cc +++ b/src/core-modules/android/system.cc @@ -5,7 +5,7 @@ #include <string_view> #include "core-modules.hh" -#include "cufetch/common.hh" +#include "libcufetch/common.hh" #include "util.hpp" static constexpr std::array<std::string_view, 9> vendors_prop_names = { diff --git a/src/core-modules/android/theme.cc b/src/core-modules/android/theme.cc index bc9cac80..ef6b867c 100644 --- a/src/core-modules/android/theme.cc +++ b/src/core-modules/android/theme.cc @@ -2,7 +2,7 @@ #if CF_ANDROID #include "core-modules.hh" -#include "cufetch/common.hh" +#include "libcufetch/common.hh" MODFUNC(theme_gtk_name) { return MAGIC_LINE; } MODFUNC(theme_gtk_icon) { return MAGIC_LINE; } diff --git a/src/core-modules/core-modules.cc b/src/core-modules/core-modules.cc index 0d3ee7bd..333f32df 100644 --- a/src/core-modules/core-modules.cc +++ b/src/core-modules/core-modules.cc @@ -11,7 +11,7 @@ #include <utility> #include "config.hpp" -#include "cufetch/cufetch.hh" +#include "libcufetch/cufetch.hh" #include "fmt/format.h" #include "linux/utils/packages.hh" #include "platform.hpp" diff --git a/src/core-modules/linux/battery.cc b/src/core-modules/linux/battery.cc index bf1464fc..19292657 100644 --- a/src/core-modules/linux/battery.cc +++ b/src/core-modules/linux/battery.cc @@ -6,7 +6,7 @@ #include <string> #include "core-modules.hh" -#include "cufetch/common.hh" +#include "libcufetch/common.hh" #include "util.hpp" static std::string read_strip_syspath(const std::string_view path) diff --git a/src/core-modules/linux/cpu.cc b/src/core-modules/linux/cpu.cc index 4f0fc98c..3dba2744 100644 --- a/src/core-modules/linux/cpu.cc +++ b/src/core-modules/linux/cpu.cc @@ -6,7 +6,7 @@ #include <string> #include "core-modules.hh" -#include "cufetch/common.hh" +#include "libcufetch/common.hh" #include "fmt/format.h" #include "switch_fnv1a.hpp" #include "util.hpp" diff --git a/src/core-modules/linux/disk.cc b/src/core-modules/linux/disk.cc index 4665d8c5..e91a9943 100644 --- a/src/core-modules/linux/disk.cc +++ b/src/core-modules/linux/disk.cc @@ -9,8 +9,8 @@ #include <cstdio> #include "core-modules.hh" -#include "cufetch/common.hh" -#include "cufetch/config.hh" +#include "libcufetch/common.hh" +#include "libcufetch/config.hh" #include "switch_fnv1a.hpp" #include "util.hpp" diff --git a/src/core-modules/linux/os.cc b/src/core-modules/linux/os.cc index ff92006c..65854a9f 100644 --- a/src/core-modules/linux/os.cc +++ b/src/core-modules/linux/os.cc @@ -9,7 +9,7 @@ #include <string_view> #include "core-modules.hh" -#include "cufetch/common.hh" +#include "libcufetch/common.hh" #include "switch_fnv1a.hpp" #include "util.hpp" diff --git a/src/core-modules/linux/ram.cc b/src/core-modules/linux/ram.cc index 1df20de2..d3e93a20 100644 --- a/src/core-modules/linux/ram.cc +++ b/src/core-modules/linux/ram.cc @@ -6,7 +6,7 @@ #include <string_view> #include "core-modules.hh" -#include "cufetch/common.hh" +#include "libcufetch/common.hh" static double read_value(const std::string_view key) { diff --git a/src/core-modules/linux/system.cc b/src/core-modules/linux/system.cc index 823ae028..e8a0d9ad 100644 --- a/src/core-modules/linux/system.cc +++ b/src/core-modules/linux/system.cc @@ -8,7 +8,7 @@ #include <string_view> #include "core-modules.hh" -#include "cufetch/common.hh" +#include "libcufetch/common.hh" #include "util.hpp" MODFUNC(host) diff --git a/src/core-modules/linux/user.cc b/src/core-modules/linux/user.cc index 39c1e0b2..80b0c2ca 100644 --- a/src/core-modules/linux/user.cc +++ b/src/core-modules/linux/user.cc @@ -6,7 +6,7 @@ #include <fstream> #include "core-modules.hh" -#include "cufetch/common.hh" +#include "libcufetch/common.hh" #include "fmt/format.h" #include "switch_fnv1a.hpp" #include "util.hpp" diff --git a/src/core-modules/linux/utils/dewm.cc b/src/core-modules/linux/utils/dewm.cc index d6f42d7c..7f88f25f 100644 --- a/src/core-modules/linux/utils/dewm.cc +++ b/src/core-modules/linux/utils/dewm.cc @@ -48,7 +48,7 @@ #include <cstdlib> #include <fstream> -#include "cufetch/common.hh" +#include "libcufetch/common.hh" #include "rapidxml-1.13/rapidxml.hpp" #include "switch_fnv1a.hpp" #include "util.hpp" diff --git a/src/core-modules/macos/battery.cc b/src/core-modules/macos/battery.cc index 42df846c..29e95b54 100644 --- a/src/core-modules/macos/battery.cc +++ b/src/core-modules/macos/battery.cc @@ -2,7 +2,7 @@ #if CF_MACOS #include "core-modules.hh" -#include "cufetch/common.hh" +#include "libcufetch/common.hh" MODFUNC(battery_modelname) { return MAGIC_LINE; } diff --git a/src/core-modules/macos/disk.cc b/src/core-modules/macos/disk.cc index 63df0da1..db76b854 100644 --- a/src/core-modules/macos/disk.cc +++ b/src/core-modules/macos/disk.cc @@ -8,7 +8,7 @@ #include <string> #include "core-modules.hh" -#include "cufetch/common.hh" +#include "libcufetch/common.hh" #include "fmt/format.h" #include "util.hpp" diff --git a/src/core-modules/macos/gpu.cc b/src/core-modules/macos/gpu.cc index 0a9413d7..f8bbf69b 100644 --- a/src/core-modules/macos/gpu.cc +++ b/src/core-modules/macos/gpu.cc @@ -2,7 +2,7 @@ #if CF_MACOS #include "core-modules.hh" -#include "cufetch/common.hh" +#include "libcufetch/common.hh" MODFUNC(gpu_name) { return MAGIC_LINE; } diff --git a/src/core-modules/macos/os.cc b/src/core-modules/macos/os.cc index 00a3e1c3..3ead54ab 100644 --- a/src/core-modules/macos/os.cc +++ b/src/core-modules/macos/os.cc @@ -7,7 +7,7 @@ #include <string> #include "core-modules.hh" -#include "cufetch/common.hh" +#include "libcufetch/common.hh" #include "rapidxml-1.13/rapidxml.hpp" #include "switch_fnv1a.hpp" #include "util.hpp" diff --git a/src/core-modules/macos/system.cc b/src/core-modules/macos/system.cc index f3056523..b7364854 100644 --- a/src/core-modules/macos/system.cc +++ b/src/core-modules/macos/system.cc @@ -8,7 +8,7 @@ #include <string_view> #include "core-modules.hh" -#include "cufetch/common.hh" +#include "libcufetch/common.hh" #include "switch_fnv1a.hpp" #include "util.hpp" diff --git a/src/core-modules/macos/theme.cc b/src/core-modules/macos/theme.cc index 8548401a..3a6475ec 100644 --- a/src/core-modules/macos/theme.cc +++ b/src/core-modules/macos/theme.cc @@ -2,7 +2,7 @@ #if CF_MACOS #include "core-modules.hh" -#include "cufetch/common.hh" +#include "libcufetch/common.hh" MODFUNC(theme_gtk_name) { return MAGIC_LINE; } MODFUNC(theme_gtk_icon) { return MAGIC_LINE; } diff --git a/src/libs/toml++/Makefile b/src/libs/toml++/Makefile index e3714d25..315489ce 100644 --- a/src/libs/toml++/Makefile +++ b/src/libs/toml++/Makefile @@ -1,7 +1,7 @@ CXX ?= g++ SRC = toml.cpp TARGET = toml.o -CXXFLAGS = -I../../../include/cufetch -fvisibility-inlines-hidden -fvisibility=hidden -fPIC -std=c++20 +CXXFLAGS = -I../../../include/ -fvisibility-inlines-hidden -fvisibility=hidden -fPIC -std=c++20 all: $(TARGET) From 66c935101b74fbe290b542ffe5e235b1d9fec464 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Sat, 19 Jul 2025 22:42:29 +0200 Subject: [PATCH 105/143] cufetchpm: some WIP --- cufetchpm/Makefile | 4 +- cufetchpm/compile_flags.txt | 1 + cufetchpm/include/manifest.hpp | 58 +++++++++++++++++++++++++++++ cufetchpm/include/pluginManager.hpp | 28 ++++++++++++++ cufetchpm/include/stateManager.hpp | 19 ++++++++++ cufetchpm/src/add.cpp | 7 ---- cufetchpm/src/main.cpp | 19 +--------- cufetchpm/src/manifest.cpp | 35 +++++++++++++++++ cufetchpm/src/pluginManager.cpp | 38 +++++++++++++++++++ cufetchpm/src/stateManager.cpp | 32 ++++++++++++++++ include/util.hpp | 13 +++++++ src/util.cpp | 24 +++++++++++- 12 files changed, 250 insertions(+), 28 deletions(-) create mode 100644 cufetchpm/include/manifest.hpp create mode 100644 cufetchpm/include/pluginManager.hpp create mode 100644 cufetchpm/include/stateManager.hpp delete mode 100644 cufetchpm/src/add.cpp create mode 100644 cufetchpm/src/manifest.cpp create mode 100644 cufetchpm/src/pluginManager.cpp create mode 100644 cufetchpm/src/stateManager.cpp diff --git a/cufetchpm/Makefile b/cufetchpm/Makefile index 6dd3a204..66807bf2 100644 --- a/cufetchpm/Makefile +++ b/cufetchpm/Makefile @@ -24,11 +24,11 @@ NAME = cufetchpm TARGET ?= $(NAME) OLDVERSION = 0.0.0 VERSION = 0.0.1 -SRC = $(wildcard src/*.cpp ../src/util.cpp) +SRC = $(wildcard src/*.cpp src/manager/*.cpp ../src/util.cpp) OBJ = $(SRC:.cpp=.o) LDFLAGS += -L./$(BUILDDIR)/fmt -lfmt CXXFLAGS ?= -mtune=generic -march=native -CXXFLAGS += -fvisibility=hidden -I../include -std=c++20 $(VARS) -DVERSION=\"$(VERSION)\" +CXXFLAGS += -fvisibility=hidden -I../include -Iinclude -std=c++20 $(VARS) -DVERSION=\"$(VERSION)\" all: fmt toml $(TARGET) diff --git a/cufetchpm/compile_flags.txt b/cufetchpm/compile_flags.txt index de766316..f98794d5 100644 --- a/cufetchpm/compile_flags.txt +++ b/cufetchpm/compile_flags.txt @@ -1,4 +1,5 @@ -I../include +-Iinclude -Wall -Wextra -Wpedantic diff --git a/cufetchpm/include/manifest.hpp b/cufetchpm/include/manifest.hpp new file mode 100644 index 00000000..bdff6a69 --- /dev/null +++ b/cufetchpm/include/manifest.hpp @@ -0,0 +1,58 @@ +#include <optional> +#include <string> +#include <string_view> +#include <utility> +#include <vector> +#include "libcufetch/common.hh" +#include "toml++/toml.hpp" + +struct manifest_t +{ + std::string name; + std::string license; + std::string description; + std::string output_dir; + std::vector<std::string> authors; + std::vector<std::string> build; +}; + +const char* const MANIFEST_NAME = "cufetchpm.toml"; + +class CManifest { +public: + CManifest(const std::string_view path); + CManifest(toml::table&& tbl) : m_tbl(tbl){} + CManifest(const toml::table& tbl) : m_tbl(std::move(tbl)){} + CManifest &operator=(CManifest &&) = default; + CManifest &operator=(const CManifest &) = default; + ~CManifest() = default; + + manifest_t get_plugin(const std::string_view name); +private: + toml::table m_tbl; + bool m_is_state = true; + + template <typename T> + T getValue(const std::string_view name, const std::string_view value) const + { + const std::optional<T>& ret = m_tbl[name][value].value<T>(); + return ret.value_or(UNKNOWN); + } + + std::vector<std::string> getValueArrayStr(const std::string_view name, const std::string_view value) const + { + std::vector<std::string> ret; + + // https://stackoverflow.com/a/78266628 + if (const toml::array* array_it = m_tbl[name][value].as_array()) + { + array_it->for_each([&ret](auto&& el) { + if (const toml::value<std::string>* str_elem = el.as_string()) + ret.push_back((*str_elem)->data()); + }); + + return ret; + } + return {}; + } +}; diff --git a/cufetchpm/include/pluginManager.hpp b/cufetchpm/include/pluginManager.hpp new file mode 100644 index 00000000..529f720a --- /dev/null +++ b/cufetchpm/include/pluginManager.hpp @@ -0,0 +1,28 @@ +#include <array> +#include <filesystem> +#include <string> +#include <string_view> +#include <utility> + +#include "stateManager.hpp" +#include "toml++/toml.hpp" +#include "util.hpp" + +constexpr std::array<std::string_view, 1> dependencies = {"git"}; + +class PluginManager +{ +public: + PluginManager(const StateManager& state) : m_state(state){} + PluginManager(StateManager&& state) : m_state(std::move(state)){} + + void create_cache_dir(); + void add_repo_plugins(const std::string& repo); + bool add_plugin(const std::string&); + bool has_deps(); + +private: + const StateManager& m_state; + const std::filesystem::path m_cache_path{getHomeCacheDir()/"cufetchpm"/"plugins"}; + toml::table m_manifest; +}; diff --git a/cufetchpm/include/stateManager.hpp b/cufetchpm/include/stateManager.hpp new file mode 100644 index 00000000..86bc5843 --- /dev/null +++ b/cufetchpm/include/stateManager.hpp @@ -0,0 +1,19 @@ +#include <filesystem> + +#include "toml++/toml.hpp" +#include "util.hpp" + +class StateManager +{ +public: + StateManager(); + StateManager(StateManager&&) = default; + StateManager(const StateManager&) = default; + ~StateManager() = default; + + toml::table get_state() { return m_state; } + +private: + const std::filesystem::path m_path{getConfigDir()/"plugins"/"state.toml"}; + toml::table m_state; +}; diff --git a/cufetchpm/src/add.cpp b/cufetchpm/src/add.cpp deleted file mode 100644 index 3fc6f4e3..00000000 --- a/cufetchpm/src/add.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "util.hpp" - -bool download_git(const std::string_view url) -{ - const std::string_view repo = url.substr(url.rfind('/')+1); - return taur_exec({ "git", "clone", url.data(), (getConfigDir() / "mods" / repo).string() }); -} diff --git a/cufetchpm/src/main.cpp b/cufetchpm/src/main.cpp index 5071f959..7670069a 100644 --- a/cufetchpm/src/main.cpp +++ b/cufetchpm/src/main.cpp @@ -1,24 +1,7 @@ #include <cstring> #include <string_view> -#include "libcufetch/common.hpp" #include "fmt/base.h" +#include "libcufetch/common.hh" bool download_git(const std::string_view url); - -int main (int argc, char *argv[]) -{ - if (argc > 1 && strcmp(argv[1], "add") == 0) - { - if (argc == 2) - die("please insert a git url to clone"); - - if (download_git(argv[2])) - info("plugin downloaded successfully"); - } - else - { - fmt::println("usage: cufetchpm add <url>"); - } - return 0; -} diff --git a/cufetchpm/src/manifest.cpp b/cufetchpm/src/manifest.cpp new file mode 100644 index 00000000..f6e89bb3 --- /dev/null +++ b/cufetchpm/src/manifest.cpp @@ -0,0 +1,35 @@ +#include "manifest.hpp" + +#include "libcufetch/common.hh" +#include "util.hpp" + +CManifest::CManifest(const std::string_view path) : m_is_state(false) +{ + try + { + this->m_tbl = toml::parse_file(path); + } + catch (const toml::parse_error& err) + { + die(_("Failed to parse state file at '{}':\n" + "{}\n" + "\t(error occurred at line {} column {})"), + path, err.description(), + err.source().begin.line, err.source().begin.column); + } +} + +manifest_t CManifest::get_plugin(const std::string_view name) +{ + if (!m_tbl[name].is_table()) + die("Couldn't find such plugin '{}' in manifest", name); + + return { + name.data(), + getValue<std::string>(name, "license"), + getValue<std::string>(name, "description"), + getValue<std::string>(name, "output-dir"), + getValueArrayStr(name, "authors"), + getValueArrayStr(name, "build"), + }; +} diff --git a/cufetchpm/src/pluginManager.cpp b/cufetchpm/src/pluginManager.cpp new file mode 100644 index 00000000..131d916a --- /dev/null +++ b/cufetchpm/src/pluginManager.cpp @@ -0,0 +1,38 @@ +#include "pluginManager.hpp" +#include <cstdio> +#include <filesystem> +#include <string> +#include <string_view> +#include <vector> +#include "libcufetch/common.hh" +#include "libcufetch/fmt/ranges.h" +#include "util.hpp" + +bool PluginManager::has_deps() +{ + for (const std::string_view bin : dependencies) // expand in the future + { + if (which(bin) == UNKNOWN) + return false; + } + + return true; +} + +void PluginManager::create_cache_dir() +{ + if (!std::filesystem::exists(m_cache_path)) + std::filesystem::create_directories(m_cache_path); +} + +void PluginManager::add_repo_plugins(const std::string& repo) +{ + if (!has_deps()) + die("Not all dependencies have been installed. You'll need to install {}", fmt::join(dependencies, ", ")); + + const std::filesystem::path& working_dir = (m_cache_path/std::tmpnam(nullptr)); + std::filesystem::create_directories(working_dir); + + if (!taur_exec({"git", "clone", "--recursive", repo, working_dir.string()}, false)) + die("Failed to clone at directory '{}'", working_dir.string()); +} diff --git a/cufetchpm/src/stateManager.cpp b/cufetchpm/src/stateManager.cpp new file mode 100644 index 00000000..4e22f4e7 --- /dev/null +++ b/cufetchpm/src/stateManager.cpp @@ -0,0 +1,32 @@ +#include <filesystem> + +#include "fmt/os.h" +#include "libcufetch/common.hh" +#include "stateManager.hpp" + +StateManager::StateManager() +{ + if (!std::filesystem::exists(m_path)) + { + auto f = fmt::output_file(m_path.string(), fmt::file::WRONLY | fmt::file::TRUNC | fmt::file::CREATE); + f.print(R"( +# AUTOGENERATED FILE. DO NOT EDIT THIS FILE. +# YOU GONNA MESS SHIT UP. unless you know what you doing ofc + )"); + f.close(); + } + + try + { + if (m_state.empty()) + m_state = toml::parse_file(m_path.string()); + } + catch (const toml::parse_error& err) + { + die(_("Failed to parse state file at '{}':\n" + "{}\n" + "\t(error occurred at line {} column {})"), + m_path.string(), err.description(), + err.source().begin.line, err.source().begin.column); + } +} diff --git a/include/util.hpp b/include/util.hpp index cee4153c..fe7df8cf 100644 --- a/include/util.hpp +++ b/include/util.hpp @@ -286,6 +286,19 @@ EXPORT std::filesystem::path getHomeConfigDir(); */ EXPORT std::filesystem::path getConfigDir(); +/* + * Get the user cache directory + * either from $XDG_CACHE_HOME or from $HOME/.cache/ + * @return user's cache directory + */ +EXPORT std::filesystem::path getHomeCacheDir(); + +/* + * Get the customfetch cache directory + * @return customfetch's cache directory + */ +EXPORT std::filesystem::path getCacheDir(); + #if CF_ANDROID /* Get android property name such as "ro.product.marketname" * @param name The property name diff --git a/src/util.cpp b/src/util.cpp index da0139bc..e171c67c 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -609,7 +609,6 @@ std::string vendor_from_entry(const size_t vendor_entry_pos, const std::string_v return description.substr(first, (last - first + 1)); } -// clang-format off std::filesystem::path getHomeConfigDir() { const char* dir = std::getenv("XDG_CONFIG_HOME"); @@ -632,3 +631,26 @@ std::filesystem::path getHomeConfigDir() std::filesystem::path getConfigDir() { return getHomeConfigDir() / "customfetch"; } + +std::filesystem::path getHomeCacheDir() +{ + const char* dir = std::getenv("XDG_CACHE_HOME"); + if (dir != NULL && dir[0] != '\0' && std::filesystem::exists(dir)) + { + std::string str_dir(dir); + if (str_dir.back() == '/') + str_dir.pop_back(); + return str_dir; + } + else + { + const char* home = std::getenv("HOME"); + if (home == nullptr) + die(_("Failed to find $HOME, set it to your home directory!")); + + return std::filesystem::path(home) / ".cache"; + } +} + +std::filesystem::path getCacheDir() +{ return getHomeCacheDir() / "customfetch"; } From f617d117f8e231f9505cd5e67cc07fc5d81a00b2 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Sun, 20 Jul 2025 22:37:02 +0200 Subject: [PATCH 106/143] cufetchpm: bring more functionality --- Makefile | 12 +- cufetchpm/Makefile | 16 +- cufetchpm/compile_flags.txt | 1 + cufetchpm/include/manifest.hpp | 9 +- cufetchpm/include/pluginManager.hpp | 27 +- cufetchpm/include/stateManager.hpp | 7 +- cufetchpm/src/main.cpp | 16 +- cufetchpm/src/manifest.cpp | 35 +- cufetchpm/src/pluginManager.cpp | 81 ++- cufetchpm/src/stateManager.cpp | 3 +- src/libs/tiny-process-library/CMakeLists.txt | 52 ++ src/libs/tiny-process-library/LICENSE | 22 + src/libs/tiny-process-library/Makefile | 36 ++ src/libs/tiny-process-library/process.cpp | 55 ++ src/libs/tiny-process-library/process.hpp | 184 +++++++ .../tiny-process-library/process_unix.cpp | 521 ++++++++++++++++++ src/libs/tiny-process-library/process_win.cpp | 424 ++++++++++++++ 17 files changed, 1468 insertions(+), 33 deletions(-) create mode 100644 src/libs/tiny-process-library/CMakeLists.txt create mode 100644 src/libs/tiny-process-library/LICENSE create mode 100644 src/libs/tiny-process-library/Makefile create mode 100644 src/libs/tiny-process-library/process.cpp create mode 100644 src/libs/tiny-process-library/process.hpp create mode 100644 src/libs/tiny-process-library/process_unix.cpp create mode 100644 src/libs/tiny-process-library/process_win.cpp diff --git a/Makefile b/Makefile index 75f2177f..bb25881b 100644 --- a/Makefile +++ b/Makefile @@ -51,11 +51,12 @@ SRC_CC = $(wildcard src/core-modules/*.cc src/core-modules/linux/*.cc src/cor OBJ_CPP = $(SRC_CPP:.cpp=.o) OBJ_CC = $(SRC_CC:.cc=.o) OBJ = $(OBJ_CPP) $(OBJ_CC) -LDFLAGS += -L$(BUILDDIR) $(BUILDDIR)/libfmt.a -lcufetch -ldl +LDFLAGS += -L$(BUILDDIR) +LDLIBS += $(BUILDDIR)/libfmt.a $(BUILDDIR)/libtiny-process-library.a -lcufetch -ldl CXXFLAGS ?= -mtune=generic -march=native CXXFLAGS += -fvisibility-inlines-hidden -fvisibility=hidden -Iinclude -Iinclude/libcufetch -std=c++20 $(VARS) -DVERSION=\"$(VERSION)\" -DLOCALEDIR=\"$(LOCALEDIR)\" -DICONPREFIX=\"$(ICONPREFIX)\" -all: genver fmt toml json libcufetch $(TARGET) +all: genver fmt toml tpl json libcufetch $(TARGET) libcufetch: fmt toml ifeq ($(wildcard $(BUILDDIR)/libcufetch.so),) @@ -73,6 +74,11 @@ ifeq ($(wildcard $(BUILDDIR)/toml.o),) make -C src/libs/toml++ BUILDDIR=$(BUILDDIR) endif +tpl: +ifeq ($(wildcard $(BUILDDIR)/libtiny-process-library.a),) + make -C src/libs/tiny-process-library BUILDDIR=$(BUILDDIR) +endif + json: ifeq ($(wildcard $(BUILDDIR)/json.o),) make -C src/libs/json BUILDDIR=$(BUILDDIR) @@ -86,7 +92,7 @@ endif $(TARGET): genver fmt toml json libcufetch $(OBJ) mkdir -p $(BUILDDIR) sh ./scripts/generateVersion.sh - $(CXX) -o $(BUILDDIR)/$(TARGET) $(OBJ) $(BUILDDIR)/*.o $(LDFLAGS) + $(CXX) -o $(BUILDDIR)/$(TARGET) $(OBJ) $(BUILDDIR)/*.o $(LDFLAGS) $(LDLIBS) cd $(BUILDDIR)/ && ln -sf $(TARGET) cufetch locale: diff --git a/cufetchpm/Makefile b/cufetchpm/Makefile index 66807bf2..16acc667 100644 --- a/cufetchpm/Makefile +++ b/cufetchpm/Makefile @@ -26,11 +26,11 @@ OLDVERSION = 0.0.0 VERSION = 0.0.1 SRC = $(wildcard src/*.cpp src/manager/*.cpp ../src/util.cpp) OBJ = $(SRC:.cpp=.o) -LDFLAGS += -L./$(BUILDDIR)/fmt -lfmt +LDLIBS += $(BUILDDIR)/libfmt.a $(BUILDDIR)/libtiny-process-library.a CXXFLAGS ?= -mtune=generic -march=native -CXXFLAGS += -fvisibility=hidden -I../include -Iinclude -std=c++20 $(VARS) -DVERSION=\"$(VERSION)\" +CXXFLAGS += -fvisibility=hidden -I../include -I../src/libs/ -Iinclude -std=c++20 $(VARS) -DVERSION=\"$(VERSION)\" -all: fmt toml $(TARGET) +all: fmt toml tpl $(TARGET) fmt: ifeq ($(wildcard $(BUILDDIR)/libfmt.a),) @@ -44,9 +44,15 @@ ifeq ($(wildcard $(BUILDDIR)/toml.o),) make -C ../src/libs/toml++ BUILDDIR=cufetchpm/$(BUILDDIR) endif -$(TARGET): fmt toml $(OBJ) +tpl: +ifeq ($(wildcard $(BUILDDIR)/libtiny-process-library.a),) mkdir -p $(BUILDDIR) - $(CXX) $(OBJ) $(BUILDDIR)/*.o -o $(BUILDDIR)/$(TARGET) $(LDFLAGS) + make -C ../src/libs/tiny-process-library BUILDDIR=cufetchpm/$(BUILDDIR) +endif + +$(TARGET): fmt toml tpl $(OBJ) + mkdir -p $(BUILDDIR) + $(CXX) $(OBJ) $(BUILDDIR)/*.o -o $(BUILDDIR)/$(TARGET) $(LDFLAGS) $(LDLIBS) clean: rm -rf $(BUILDDIR)/$(TARGET) $(OBJ) diff --git a/cufetchpm/compile_flags.txt b/cufetchpm/compile_flags.txt index f98794d5..3ca034d4 100644 --- a/cufetchpm/compile_flags.txt +++ b/cufetchpm/compile_flags.txt @@ -1,4 +1,5 @@ -I../include +-I../src/libs/ -Iinclude -Wall -Wextra diff --git a/cufetchpm/include/manifest.hpp b/cufetchpm/include/manifest.hpp index bdff6a69..e61bc555 100644 --- a/cufetchpm/include/manifest.hpp +++ b/cufetchpm/include/manifest.hpp @@ -1,3 +1,6 @@ +#ifndef _MANIFEST_HPP_ +#define _MANIFEST_HPP_ + #include <optional> #include <string> #include <string_view> @@ -13,7 +16,7 @@ struct manifest_t std::string description; std::string output_dir; std::vector<std::string> authors; - std::vector<std::string> build; + std::vector<std::string> build_steps; }; const char* const MANIFEST_NAME = "cufetchpm.toml"; @@ -28,6 +31,8 @@ class CManifest { ~CManifest() = default; manifest_t get_plugin(const std::string_view name); + std::vector<manifest_t> get_all_plugins(); + private: toml::table m_tbl; bool m_is_state = true; @@ -56,3 +61,5 @@ class CManifest { return {}; } }; + +#endif // !_MANIFEST_HPP_; diff --git a/cufetchpm/include/pluginManager.hpp b/cufetchpm/include/pluginManager.hpp index 529f720a..77fa2ece 100644 --- a/cufetchpm/include/pluginManager.hpp +++ b/cufetchpm/include/pluginManager.hpp @@ -1,3 +1,6 @@ +#ifndef _PLUGIN_MANAGER_HPP_ +#define _PLUGIN_MANAGER_HPP_ + #include <array> #include <filesystem> #include <string> @@ -8,7 +11,25 @@ #include "toml++/toml.hpp" #include "util.hpp" -constexpr std::array<std::string_view, 1> dependencies = {"git"}; +constexpr std::array<std::string_view, 1> dependencies = {"git"}; // expand in the future, maybe + +#define BOLD_COLOR(x) (fmt::emphasis::bold | fmt::fg(fmt::rgb(x))) + +template <typename... Args> +void success(const std::string_view fmt, Args&&... args) noexcept +{ + fmt::print(BOLD_COLOR((fmt::color::green)), "SUCCESS:\033[0m {}\n", + fmt::format(fmt::runtime(fmt), std::forward<Args>(args)...)); +} + +template <typename... Args> +void status(const std::string_view fmt, Args&&... args) noexcept +{ + fmt::print(BOLD_COLOR((fmt::color::cadet_blue)), "status:\033[0m {} ...\n", + fmt::format(fmt::runtime(fmt), std::forward<Args>(args)...)); +} + +#undef BOLD_COLOR class PluginManager { @@ -16,7 +37,6 @@ class PluginManager PluginManager(const StateManager& state) : m_state(state){} PluginManager(StateManager&& state) : m_state(std::move(state)){} - void create_cache_dir(); void add_repo_plugins(const std::string& repo); bool add_plugin(const std::string&); bool has_deps(); @@ -26,3 +46,6 @@ class PluginManager const std::filesystem::path m_cache_path{getHomeCacheDir()/"cufetchpm"/"plugins"}; toml::table m_manifest; }; + + +#endif diff --git a/cufetchpm/include/stateManager.hpp b/cufetchpm/include/stateManager.hpp index 86bc5843..4ec5b57b 100644 --- a/cufetchpm/include/stateManager.hpp +++ b/cufetchpm/include/stateManager.hpp @@ -1,3 +1,6 @@ +#ifndef _STATE_MANAGER_HPP_ +#define _STATE_MANAGER_HPP_ + #include <filesystem> #include "toml++/toml.hpp" @@ -14,6 +17,8 @@ class StateManager toml::table get_state() { return m_state; } private: - const std::filesystem::path m_path{getConfigDir()/"plugins"/"state.toml"}; + const std::filesystem::path m_path{getHomeCacheDir()/"cufetchpm"/"state.toml"}; toml::table m_state; }; + +#endif diff --git a/cufetchpm/src/main.cpp b/cufetchpm/src/main.cpp index 7670069a..1724d090 100644 --- a/cufetchpm/src/main.cpp +++ b/cufetchpm/src/main.cpp @@ -1,7 +1,11 @@ -#include <cstring> -#include <string_view> +#include "stateManager.hpp" +#include "pluginManager.hpp" -#include "fmt/base.h" -#include "libcufetch/common.hh" - -bool download_git(const std::string_view url); +int main (int argc, char *argv[]) +{ + std::filesystem::create_directories({getHomeCacheDir()/"cufetchpm"/"plugins"}); + StateManager state; + PluginManager man(state); + man.add_repo_plugins(argv[2]); + return 0; +} diff --git a/cufetchpm/src/manifest.cpp b/cufetchpm/src/manifest.cpp index f6e89bb3..6d831a57 100644 --- a/cufetchpm/src/manifest.cpp +++ b/cufetchpm/src/manifest.cpp @@ -1,8 +1,15 @@ #include "manifest.hpp" +#include <algorithm> +#include <cctype> +#include <vector> #include "libcufetch/common.hh" #include "util.hpp" +static bool validManifestName(const std::string_view n) { + return std::ranges::all_of(n, [](const unsigned char c) { return (isalnum(c) || c == '-' || c == '_' || c == '='); }); +} + CManifest::CManifest(const std::string_view path) : m_is_state(false) { try @@ -19,6 +26,32 @@ CManifest::CManifest(const std::string_view path) : m_is_state(false) } } +std::vector<manifest_t> CManifest::get_all_plugins() +{ + std::vector<manifest_t> plugins; + for (auto const& [name, _] : m_tbl) + { + if (name.str() == "repository") + continue; + + if (!validManifestName(name.str())) + { + warn("Plugin '{}' has an invalid name. Only alphanumeric and '-', '_', '=' are allowed in the name", name.str()); + continue; + } + + plugins.push_back({ + name.data(), + getValue<std::string>(name, "license"), + getValue<std::string>(name, "description"), + getValue<std::string>(name, "output-dir"), + getValueArrayStr(name, "authors"), + getValueArrayStr(name, "build-steps"), + }); + } + return plugins; +} + manifest_t CManifest::get_plugin(const std::string_view name) { if (!m_tbl[name].is_table()) @@ -30,6 +63,6 @@ manifest_t CManifest::get_plugin(const std::string_view name) getValue<std::string>(name, "description"), getValue<std::string>(name, "output-dir"), getValueArrayStr(name, "authors"), - getValueArrayStr(name, "build"), + getValueArrayStr(name, "build-steps"), }; } diff --git a/cufetchpm/src/pluginManager.cpp b/cufetchpm/src/pluginManager.cpp index 131d916a..1d1474fc 100644 --- a/cufetchpm/src/pluginManager.cpp +++ b/cufetchpm/src/pluginManager.cpp @@ -1,38 +1,95 @@ #include "pluginManager.hpp" #include <cstdio> +#include <cstdlib> #include <filesystem> +#include <random> #include <string> #include <string_view> #include <vector> + +#include "tiny-process-library/process.hpp" +#include "fmt/format.h" +#include "manifest.hpp" #include "libcufetch/common.hh" -#include "libcufetch/fmt/ranges.h" -#include "util.hpp" +//#include "fmt/ranges.h" + +using namespace TinyProcessLib; + +std::random_device rd; +std::mt19937 gen(rd()); +std::uniform_int_distribution<> dist(0, 999999); bool PluginManager::has_deps() { - for (const std::string_view bin : dependencies) // expand in the future + for (const std::string_view bin : dependencies) { - if (which(bin) == UNKNOWN) + Process proc(fmt::format("command -v {}", bin), + "", + [](const char*, size_t) {}, // discard stdout + [](const char*, size_t) {}); // discard stderr + if (proc.get_exit_status() != 0) return false; } return true; } -void PluginManager::create_cache_dir() -{ - if (!std::filesystem::exists(m_cache_path)) - std::filesystem::create_directories(m_cache_path); -} - void PluginManager::add_repo_plugins(const std::string& repo) { if (!has_deps()) - die("Not all dependencies have been installed. You'll need to install {}", fmt::join(dependencies, ", ")); + die("Not all dependencies have been installed. You'll need to install git"); // fmt::join(dependencies, ", ")); - const std::filesystem::path& working_dir = (m_cache_path/std::tmpnam(nullptr)); + std::string repo_name; + { + size_t pos = repo.rfind('/'); + if (pos == repo.npos) + die("Is the url valid? Please give us a valid repository url"); + repo_name = repo.substr(pos + 1); + if (hasEnding(repo_name, ".git")) + repo_name.erase(repo_name.length() - ".git"_len); + } + + if (std::filesystem::exists(m_cache_path / repo_name)) + { + warn("Repository '{}' already exists in '{}'", repo_name, (m_cache_path / repo_name).string()); + return; + } + + const std::filesystem::path& working_dir = m_cache_path / ("plugin_" + std::to_string(dist(gen))); std::filesystem::create_directories(working_dir); + status("Cloning repository '{}' at '{}'", repo, working_dir.string()); if (!taur_exec({"git", "clone", "--recursive", repo, working_dir.string()}, false)) + { + std::filesystem::remove_all(working_dir); die("Failed to clone at directory '{}'", working_dir.string()); + } + success("Successfully cloned. Changing current directory"); + + std::filesystem::current_path(working_dir); + CManifest manifest(MANIFEST_NAME); + + status("Querying all plugins declared from the manifest"); + const std::vector<manifest_t>& plugins = manifest.get_all_plugins(); + if (plugins.empty()) + { + std::filesystem::remove_all(working_dir); + die("Looks like there are no plugins to build with '{}'", repo_name); + } + success("Queried the plugins"); + + for (const manifest_t& plugin : plugins) + { + status("Trying to build plugin '{}'", plugin.name); + for (const std::string& bs : plugin.build_steps) + { + Process process(bs, "", nullptr); + if (process.get_exit_status() != 0) + { + std::filesystem::remove_all(working_dir); + die("Failed to build plugin '{}' from '{}'", plugin.name, repo); + } + } + success("Successfully built '{}'", plugin.name); + } } diff --git a/cufetchpm/src/stateManager.cpp b/cufetchpm/src/stateManager.cpp index 4e22f4e7..5aae0aa8 100644 --- a/cufetchpm/src/stateManager.cpp +++ b/cufetchpm/src/stateManager.cpp @@ -9,8 +9,7 @@ StateManager::StateManager() if (!std::filesystem::exists(m_path)) { auto f = fmt::output_file(m_path.string(), fmt::file::WRONLY | fmt::file::TRUNC | fmt::file::CREATE); - f.print(R"( -# AUTOGENERATED FILE. DO NOT EDIT THIS FILE. + f.print(R"(# AUTOGENERATED FILE. DO NOT EDIT THIS FILE. # YOU GONNA MESS SHIT UP. unless you know what you doing ofc )"); f.close(); diff --git a/src/libs/tiny-process-library/CMakeLists.txt b/src/libs/tiny-process-library/CMakeLists.txt new file mode 100644 index 00000000..22a26a33 --- /dev/null +++ b/src/libs/tiny-process-library/CMakeLists.txt @@ -0,0 +1,52 @@ +cmake_minimum_required(VERSION 3.10) + +project(tiny-process-library) + +add_library(tiny-process-library process.cpp) +add_library(tiny-process-library::tiny-process-library ALIAS tiny-process-library) + +if(MSVC) + target_compile_definitions(tiny-process-library PRIVATE /D_CRT_SECURE_NO_WARNINGS) +else() + target_compile_options(tiny-process-library PRIVATE -std=c++11 -Wall -Wextra) +endif() + +if(WIN32) + set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) + target_sources(tiny-process-library PRIVATE process_win.cpp) + #If compiled using MSYS2, use sh to run commands + if(MSYS) + target_compile_definitions(tiny-process-library PUBLIC MSYS_PROCESS_USE_SH) + endif() +else() + target_sources(tiny-process-library PRIVATE process_unix.cpp) +endif() + +find_package(Threads REQUIRED) + +target_link_libraries(tiny-process-library Threads::Threads) +target_include_directories(tiny-process-library PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> + $<INSTALL_INTERFACE:include>) + +# if tiny-process-library is not a sub-project: +if(CMAKE_SOURCE_DIR STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}") + if(MSVC) + add_definitions(/D_CRT_SECURE_NO_WARNINGS) + else() + add_compile_options(-std=c++11 -Wall -Wextra) + endif() + + install(TARGETS tiny-process-library + EXPORT ${PROJECT_NAME}-config + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib + RUNTIME DESTINATION bin) + + install(EXPORT ${PROJECT_NAME}-config + FILE ${PROJECT_NAME}-config.cmake + NAMESPACE ${PROJECT_NAME}:: + DESTINATION lib/cmake/${PROJECT_NAME} + ) + + install(FILES process.hpp DESTINATION include) +endif() diff --git a/src/libs/tiny-process-library/LICENSE b/src/libs/tiny-process-library/LICENSE new file mode 100644 index 00000000..955aa68b --- /dev/null +++ b/src/libs/tiny-process-library/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015-2020 Ole Christian Eidheim + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/src/libs/tiny-process-library/Makefile b/src/libs/tiny-process-library/Makefile new file mode 100644 index 00000000..1b728ab4 --- /dev/null +++ b/src/libs/tiny-process-library/Makefile @@ -0,0 +1,36 @@ +CXX ?= g++ +CXX_INCLUDES = -I../../../include +CXX_FLAGS = -O3 -DNDEBUG -fvisibility=hidden -fvisibility-inlines-hidden -fPIC + +UNAME_S := $(shell uname -s) + +ifeq ($(UNAME_S),Windows) + CXXFLAGS += -D_CRT_SECURE_NO_WARNINGS + SRC += process_win.cpp + # Check if we're in MSYS environment + ifneq (,$(findstring MSYS,$(shell uname -o))) + CXXFLAGS += -DMSYS_PROCESS_USE_SH + endif + LIBNAME = tiny-process-library.lib +else + CXXFLAGS += -std=c++11 -Wall -Wextra + SRC += process_unix.cpp + LIBNAME = libtiny-process-library.a +endif + +SRC += process.cpp +OBJ = $(SRC:.cpp=.o) + +all: $(LIBNAME) + +$(LIBNAME): $(OBJ) + ar rcs $@ $^ + mv -f $(LIBNAME) ../../../$(BUILDDIR)/$(LIBNAME) + +%.o: %.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + +clean: + rm -f $(OBJ) $(LIBNAME) + +.PHONY: all clean diff --git a/src/libs/tiny-process-library/process.cpp b/src/libs/tiny-process-library/process.cpp new file mode 100644 index 00000000..a68e5181 --- /dev/null +++ b/src/libs/tiny-process-library/process.cpp @@ -0,0 +1,55 @@ +#include "process.hpp" + +namespace TinyProcessLib { + +Process::Process(const std::vector<string_type> &arguments, const string_type &path, + std::function<void(const char *bytes, size_t n)> read_stdout, + std::function<void(const char *bytes, size_t n)> read_stderr, + bool open_stdin, const Config &config) noexcept + : closed(true), read_stdout(std::move(read_stdout)), read_stderr(std::move(read_stderr)), open_stdin(open_stdin), config(config) { + open(arguments, path); + async_read(); +} + +Process::Process(const string_type &command, const string_type &path, + std::function<void(const char *bytes, size_t n)> read_stdout, + std::function<void(const char *bytes, size_t n)> read_stderr, + bool open_stdin, const Config &config) noexcept + : closed(true), read_stdout(std::move(read_stdout)), read_stderr(std::move(read_stderr)), open_stdin(open_stdin), config(config) { + open(command, path); + async_read(); +} + +Process::Process(const std::vector<string_type> &arguments, const string_type &path, + const environment_type &environment, + std::function<void(const char *bytes, size_t n)> read_stdout, + std::function<void(const char *bytes, size_t n)> read_stderr, + bool open_stdin, const Config &config) noexcept + : closed(true), read_stdout(std::move(read_stdout)), read_stderr(std::move(read_stderr)), open_stdin(open_stdin), config(config) { + open(arguments, path, &environment); + async_read(); +} + +Process::Process(const string_type &command, const string_type &path, + const environment_type &environment, + std::function<void(const char *bytes, size_t n)> read_stdout, + std::function<void(const char *bytes, size_t n)> read_stderr, + bool open_stdin, const Config &config) noexcept + : closed(true), read_stdout(std::move(read_stdout)), read_stderr(std::move(read_stderr)), open_stdin(open_stdin), config(config) { + open(command, path, &environment); + async_read(); +} + +Process::~Process() noexcept { + close_fds(); +} + +Process::id_type Process::get_id() const noexcept { + return data.id; +} + +bool Process::write(const std::string &str) { + return write(str.c_str(), str.size()); +} + +} // namespace TinyProcessLib diff --git a/src/libs/tiny-process-library/process.hpp b/src/libs/tiny-process-library/process.hpp new file mode 100644 index 00000000..351c6c1b --- /dev/null +++ b/src/libs/tiny-process-library/process.hpp @@ -0,0 +1,184 @@ +#ifndef TINY_PROCESS_LIBRARY_HPP_ +#define TINY_PROCESS_LIBRARY_HPP_ +#include <functional> +#include <memory> +#include <mutex> +#include <string> +#include <thread> +#include <unordered_map> +#include <vector> +#ifndef _WIN32 +#include <sys/wait.h> +#endif + +namespace TinyProcessLib { +/// Additional parameters to Process constructors. +struct Config { + /// Buffer size for reading stdout and stderr. Default is 131072 (128 kB). + std::size_t buffer_size = 131072; + /// Set to true to inherit file descriptors from parent process. Default is false. + /// On Windows: has no effect unless read_stdout==nullptr, read_stderr==nullptr and open_stdin==false. + bool inherit_file_descriptors = false; + + /// If set, invoked when process stdout is closed. + /// This call goes after last call to read_stdout(). + std::function<void()> on_stdout_close = nullptr; + /// If set, invoked when process stderr is closed. + /// This call goes after last call to read_stderr(). + std::function<void()> on_stderr_close = nullptr; + + /// On Windows only: controls how the process is started, mimics STARTUPINFO's wShowWindow. + /// See: https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/ns-processthreadsapi-startupinfoa + /// and https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-showwindow + enum class ShowWindow { + hide = 0, + show_normal = 1, + show_minimized = 2, + maximize = 3, + show_maximized = 3, + show_no_activate = 4, + show = 5, + minimize = 6, + show_min_no_active = 7, + show_na = 8, + restore = 9, + show_default = 10, + force_minimize = 11 + }; + /// On Windows only: controls how the window is shown. + ShowWindow show_window{ShowWindow::show_default}; + + /// Set to true to break out of flatpak sandbox by prepending all commands with `/usr/bin/flatpak-spawn --host` + /// which will execute the command line on the host system. + /// Requires the flatpak `org.freedesktop.Flatpak` portal to be opened for the current sandbox. + /// See https://docs.flatpak.org/en/latest/flatpak-command-reference.html#flatpak-spawn. + bool flatpak_spawn_host = false; +}; + +/// Platform independent class for creating processes. +/// Note on Windows: it seems not possible to specify which pipes to redirect. +/// Thus, at the moment, if read_stdout==nullptr, read_stderr==nullptr and open_stdin==false, +/// the stdout, stderr and stdin are sent to the parent process instead. +class Process { +public: +#ifdef _WIN32 + typedef unsigned long id_type; // Process id type + typedef void *fd_type; // File descriptor type +#ifdef UNICODE + typedef std::wstring string_type; +#else + typedef std::string string_type; +#endif +#else + typedef pid_t id_type; + typedef int fd_type; + typedef std::string string_type; +#endif + typedef std::unordered_map<string_type, string_type> environment_type; + +private: + class Data { + public: + Data() noexcept; + id_type id; +#ifdef _WIN32 + void *handle{nullptr}; +#endif + int exit_status{-1}; + }; + +public: + /// Starts a process with the environment of the calling process. + Process(const std::vector<string_type> &arguments, const string_type &path = string_type(), + std::function<void(const char *bytes, size_t n)> read_stdout = nullptr, + std::function<void(const char *bytes, size_t n)> read_stderr = nullptr, + bool open_stdin = false, + const Config &config = {}) noexcept; + /// Starts a process with the environment of the calling process. + Process(const string_type &command, const string_type &path = string_type(), + std::function<void(const char *bytes, size_t n)> read_stdout = nullptr, + std::function<void(const char *bytes, size_t n)> read_stderr = nullptr, + bool open_stdin = false, + const Config &config = {}) noexcept; + + /// Starts a process with specified environment. + Process(const std::vector<string_type> &arguments, + const string_type &path, + const environment_type &environment, + std::function<void(const char *bytes, size_t n)> read_stdout = nullptr, + std::function<void(const char *bytes, size_t n)> read_stderr = nullptr, + bool open_stdin = false, + const Config &config = {}) noexcept; + /// Starts a process with specified environment. + Process(const string_type &command, + const string_type &path, + const environment_type &environment, + std::function<void(const char *bytes, size_t n)> read_stdout = nullptr, + std::function<void(const char *bytes, size_t n)> read_stderr = nullptr, + bool open_stdin = false, + const Config &config = {}) noexcept; +#ifndef _WIN32 + /// Starts a process with the environment of the calling process. + /// Supported on Unix-like systems only. + /// Since the command line is not known to the Process object itself, + /// this overload does not support the flatpak_spawn_host configuration. + Process(const std::function<void()> &function, + std::function<void(const char *bytes, size_t n)> read_stdout = nullptr, + std::function<void(const char *bytes, size_t n)> read_stderr = nullptr, + bool open_stdin = false, + const Config &config = {}); +#endif + ~Process() noexcept; + + /// Get the process id of the started process. + id_type get_id() const noexcept; + /// Wait until process is finished, and return exit status. + int get_exit_status() noexcept; + /// If process is finished, returns true and sets the exit status. Returns false otherwise. + bool try_get_exit_status(int &exit_status) noexcept; + /// Write to stdin. + bool write(const char *bytes, size_t n); + /// Write to stdin. Convenience function using write(const char *, size_t). + bool write(const std::string &str); + /// Close stdin. If the process takes parameters from stdin, use this to notify that all parameters have been sent. + void close_stdin() noexcept; + + /// Kill the process. force=true is only supported on Unix-like systems. + void kill(bool force = false) noexcept; + /// Kill a given process id. Use kill(bool force) instead if possible. force=true is only supported on Unix-like systems. + static void kill(id_type id, bool force = false) noexcept; +#ifndef _WIN32 + /// Send the signal signum to the process. + void signal(int signum) noexcept; +#endif + +private: + Data data; + bool closed; + std::mutex close_mutex; + std::function<void(const char *bytes, size_t n)> read_stdout; + std::function<void(const char *bytes, size_t n)> read_stderr; +#ifndef _WIN32 + std::thread stdout_stderr_thread; +#else + std::thread stdout_thread, stderr_thread; +#endif + bool open_stdin; + std::mutex stdin_mutex; + + Config config; + + std::unique_ptr<fd_type> stdout_fd, stderr_fd, stdin_fd; + + id_type open(const std::vector<string_type> &arguments, const string_type &path, const environment_type *environment = nullptr) noexcept; + id_type open(const string_type &command, const string_type &path, const environment_type *environment = nullptr) noexcept; +#ifndef _WIN32 + id_type open(const std::function<void()> &function) noexcept; +#endif + void async_read() noexcept; + void close_fds() noexcept; +}; + +} // namespace TinyProcessLib + +#endif // TINY_PROCESS_LIBRARY_HPP_ diff --git a/src/libs/tiny-process-library/process_unix.cpp b/src/libs/tiny-process-library/process_unix.cpp new file mode 100644 index 00000000..e2cd8fa0 --- /dev/null +++ b/src/libs/tiny-process-library/process_unix.cpp @@ -0,0 +1,521 @@ +#include "process.hpp" +#include <algorithm> +#include <bitset> +#include <cstdlib> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <poll.h> +#include <set> +#include <signal.h> +#include <stdexcept> +#include <string.h> +#include <unistd.h> + +namespace TinyProcessLib { + +static int portable_execvpe(const char *file, char *const argv[], char *const envp[]) { +#ifdef __GLIBC__ + // Prefer native implementation. + return execvpe(file, argv, envp); +#else + if(!file || !*file) { + errno = ENOENT; + return -1; + } + + if(strchr(file, '/') != nullptr) { + // If file contains a slash, no search is needed. + return execve(file, argv, envp); + } + + const char *path = getenv("PATH"); + char cspath[PATH_MAX + 1] = {}; + if(!path) { + // If env variable is not set, use static path string. + confstr(_CS_PATH, cspath, sizeof(cspath)); + path = cspath; + } + + const size_t path_len = strlen(path); + const size_t file_len = strlen(file); + + if(file_len > NAME_MAX) { + errno = ENAMETOOLONG; + return -1; + } + + // Indicates whether we encountered EACCESS at least once. + bool eacces = false; + + const char *curr = nullptr; + const char *next = nullptr; + + for(curr = path; *curr; curr = *next ? next + 1 : next) { + next = strchr(curr, ':'); + if(!next) { + next = path + path_len; + } + + const size_t sz = (next - curr); + if(sz > PATH_MAX) { + // Path is too long. Proceed to next path in list. + continue; + } + + char exe_path[PATH_MAX + 1 + NAME_MAX + 1]; // 1 byte for slash + 1 byte for \0 + memcpy(exe_path, curr, sz); + exe_path[sz] = '/'; + memcpy(exe_path + sz + 1, file, file_len); + exe_path[sz + 1 + file_len] = '\0'; + + execve(exe_path, argv, envp); + + switch(errno) { + case EACCES: + eacces = true; + case ENOENT: + case ESTALE: + case ENOTDIR: + case ENODEV: + case ETIMEDOUT: + // The errors above indicate that the executable was not found. + // The list of errors replicates one from glibc. + // In this case we proceed to next path in list. + break; + + default: + // Other errors indicate that executable was found but failed + // to execute. In this case we return error. + return -1; + } + } + + if(eacces) { + // If search failed, and at least one iteration reported EACCESS, it means + // that the needed executable exists but does not have suitable permissions. + // In this case we report EACEESS for user. + errno = EACCES; + } + // Otherwise we just keep last encountered errno. + return -1; +#endif +} + +Process::Data::Data() noexcept : id(-1) { +} + +Process::Process(const std::function<void()> &function, + std::function<void(const char *, size_t)> read_stdout, + std::function<void(const char *, size_t)> read_stderr, + bool open_stdin, const Config &config) + : closed(true), read_stdout(std::move(read_stdout)), read_stderr(std::move(read_stderr)), open_stdin(open_stdin), config(config) { + if(config.flatpak_spawn_host) + throw std::invalid_argument("Cannot break out of a flatpak sandbox with this overload."); + open(function); + async_read(); +} + +Process::id_type Process::open(const std::function<void()> &function) noexcept { + if(open_stdin) + stdin_fd = std::unique_ptr<fd_type>(new fd_type); + if(read_stdout) + stdout_fd = std::unique_ptr<fd_type>(new fd_type); + if(read_stderr) + stderr_fd = std::unique_ptr<fd_type>(new fd_type); + + int stdin_p[2], stdout_p[2], stderr_p[2]; + + if(stdin_fd && pipe(stdin_p) != 0) + return -1; + if(stdout_fd && pipe(stdout_p) != 0) { + if(stdin_fd) { + close(stdin_p[0]); + close(stdin_p[1]); + } + return -1; + } + if(stderr_fd && pipe(stderr_p) != 0) { + if(stdin_fd) { + close(stdin_p[0]); + close(stdin_p[1]); + } + if(stdout_fd) { + close(stdout_p[0]); + close(stdout_p[1]); + } + return -1; + } + + id_type pid = fork(); + + if(pid < 0) { + if(stdin_fd) { + close(stdin_p[0]); + close(stdin_p[1]); + } + if(stdout_fd) { + close(stdout_p[0]); + close(stdout_p[1]); + } + if(stderr_fd) { + close(stderr_p[0]); + close(stderr_p[1]); + } + return pid; + } + else if(pid == 0) { + if(stdin_fd) + dup2(stdin_p[0], 0); + if(stdout_fd) + dup2(stdout_p[1], 1); + if(stderr_fd) + dup2(stderr_p[1], 2); + if(stdin_fd) { + close(stdin_p[0]); + close(stdin_p[1]); + } + if(stdout_fd) { + close(stdout_p[0]); + close(stdout_p[1]); + } + if(stderr_fd) { + close(stderr_p[0]); + close(stderr_p[1]); + } + + if(!config.inherit_file_descriptors) { + // Optimization on some systems: using 8 * 1024 (Debian's default _SC_OPEN_MAX) as fd_max limit + int fd_max = std::min(8192, static_cast<int>(sysconf(_SC_OPEN_MAX))); // Truncation is safe + if(fd_max < 0) + fd_max = 8192; + for(int fd = 3; fd < fd_max; fd++) + close(fd); + } + + setpgid(0, 0); + // TODO: See here on how to emulate tty for colors: http://stackoverflow.com/questions/1401002/trick-an-application-into-thinking-its-stdin-is-interactive-not-a-pipe + // TODO: One solution is: echo "command;exit"|script -q /dev/null + + if(function) + function(); + + _exit(EXIT_FAILURE); + } + + if(stdin_fd) + close(stdin_p[0]); + if(stdout_fd) + close(stdout_p[1]); + if(stderr_fd) + close(stderr_p[1]); + + if(stdin_fd) + *stdin_fd = stdin_p[1]; + if(stdout_fd) + *stdout_fd = stdout_p[0]; + if(stderr_fd) + *stderr_fd = stderr_p[0]; + + closed = false; + data.id = pid; + return pid; +} + +Process::id_type Process::open(const std::vector<string_type> &arguments, const string_type &path, const environment_type *environment) noexcept { + return open([this, &arguments, &path, &environment] { + if(arguments.empty()) + exit(127); + + std::vector<const char *> argv_ptrs; + + if(config.flatpak_spawn_host) { + // break out of sandbox, execute on host + argv_ptrs.reserve(arguments.size() + 3); + argv_ptrs.emplace_back("/usr/bin/flatpak-spawn"); + argv_ptrs.emplace_back("--host"); + } + else + argv_ptrs.reserve(arguments.size() + 1); + + for(auto &argument : arguments) + argv_ptrs.emplace_back(argument.c_str()); + argv_ptrs.emplace_back(nullptr); + + if(!path.empty()) { + if(chdir(path.c_str()) != 0) + exit(1); + } + + if(!environment) + execvp(argv_ptrs[0], const_cast<char *const *>(argv_ptrs.data())); + else { + std::vector<std::string> env_strs; + std::vector<const char *> env_ptrs; + env_strs.reserve(environment->size()); + env_ptrs.reserve(environment->size() + 1); + for(const auto &e : *environment) { + env_strs.emplace_back(e.first + '=' + e.second); + env_ptrs.emplace_back(env_strs.back().c_str()); + } + env_ptrs.emplace_back(nullptr); + + portable_execvpe(argv_ptrs[0], const_cast<char *const *>(argv_ptrs.data()), const_cast<char *const *>(env_ptrs.data())); + } + }); +} + +Process::id_type Process::open(const std::string &command, const std::string &path, const environment_type *environment) noexcept { + return open([this, &command, &path, &environment] { + auto command_c_str = command.c_str(); + std::string cd_path_and_command; + if(!path.empty()) { + auto path_escaped = path; + size_t pos = 0; + // Based on https://www.reddit.com/r/cpp/comments/3vpjqg/a_new_platform_independent_process_library_for_c11/cxsxyb7 + while((pos = path_escaped.find('\'', pos)) != std::string::npos) { + path_escaped.replace(pos, 1, "'\\''"); + pos += 4; + } + cd_path_and_command = "cd '" + path_escaped + "' && " + command; // To avoid resolving symbolic links + command_c_str = cd_path_and_command.c_str(); + } + + if(!environment) { + if(config.flatpak_spawn_host) + // break out of sandbox, execute on host + execl("/usr/bin/flatpak-spawn", "/usr/bin/flatpak-spawn", "--host", "/bin/sh", "-c", command_c_str, nullptr); + else + execl("/bin/sh", "/bin/sh", "-c", command_c_str, nullptr); + } + else { + std::vector<std::string> env_strs; + std::vector<const char *> env_ptrs; + env_strs.reserve(environment->size()); + env_ptrs.reserve(environment->size() + 1); + for(const auto &e : *environment) { + env_strs.emplace_back(e.first + '=' + e.second); + env_ptrs.emplace_back(env_strs.back().c_str()); + } + env_ptrs.emplace_back(nullptr); + if(config.flatpak_spawn_host) + // break out of sandbox, execute on host + execle("/usr/bin/flatpak-spawn", "/usr/bin/flatpak-spawn", "--host", "/bin/sh", "-c", command_c_str, nullptr, env_ptrs.data()); + else + execle("/bin/sh", "/bin/sh", "-c", command_c_str, nullptr, env_ptrs.data()); + } + }); +} + +void Process::async_read() noexcept { + if(data.id <= 0 || (!stdout_fd && !stderr_fd)) + return; + + stdout_stderr_thread = std::thread([this] { + std::vector<pollfd> pollfds; + std::bitset<2> fd_is_stdout; + if(stdout_fd) { + fd_is_stdout.set(pollfds.size()); + pollfds.emplace_back(); + pollfds.back().fd = fcntl(*stdout_fd, F_SETFL, fcntl(*stdout_fd, F_GETFL) | O_NONBLOCK) == 0 ? *stdout_fd : -1; + pollfds.back().events = POLLIN; + } + if(stderr_fd) { + pollfds.emplace_back(); + pollfds.back().fd = fcntl(*stderr_fd, F_SETFL, fcntl(*stderr_fd, F_GETFL) | O_NONBLOCK) == 0 ? *stderr_fd : -1; + pollfds.back().events = POLLIN; + } + auto buffer = std::unique_ptr<char[]>(new char[config.buffer_size]); + bool any_open = !pollfds.empty(); + while(any_open && (poll(pollfds.data(), static_cast<nfds_t>(pollfds.size()), -1) > 0 || errno == EINTR)) { + any_open = false; + for(size_t i = 0; i < pollfds.size(); ++i) { + if(pollfds[i].fd >= 0) { + if(pollfds[i].revents & POLLIN) { + const ssize_t n = read(pollfds[i].fd, buffer.get(), config.buffer_size); + if(n > 0) { + if(fd_is_stdout[i]) + read_stdout(buffer.get(), static_cast<size_t>(n)); + else + read_stderr(buffer.get(), static_cast<size_t>(n)); + } + else if(n == 0 || (n < 0 && errno != EINTR && errno != EAGAIN && errno != EWOULDBLOCK)) { + if(fd_is_stdout[i]) { + if(config.on_stdout_close) + config.on_stdout_close(); + } + else { + if(config.on_stderr_close) + config.on_stderr_close(); + } + pollfds[i].fd = -1; + continue; + } + } + else if(pollfds[i].revents & (POLLERR | POLLHUP | POLLNVAL)) { + if(fd_is_stdout[i]) { + if(config.on_stdout_close) + config.on_stdout_close(); + } + else { + if(config.on_stderr_close) + config.on_stderr_close(); + } + pollfds[i].fd = -1; + continue; + } + any_open = true; + } + } + } + }); +} + +int Process::get_exit_status() noexcept { + if(data.id <= 0) + return -1; + + int exit_status; + id_type pid; + do { + pid = waitpid(data.id, &exit_status, 0); + } while(pid < 0 && errno == EINTR); + + if(pid < 0 && errno == ECHILD) { + // PID doesn't exist anymore, return previously sampled exit status (or -1) + return data.exit_status; + } + else { + // Store exit status for future calls + if(exit_status >= 256) + exit_status = exit_status >> 8; + data.exit_status = exit_status; + } + + { + std::lock_guard<std::mutex> lock(close_mutex); + closed = true; + } + close_fds(); + + return exit_status; +} + +bool Process::try_get_exit_status(int &exit_status) noexcept { + if(data.id <= 0) { + exit_status = -1; + return true; + } + + const id_type pid = waitpid(data.id, &exit_status, WNOHANG); + if(pid < 0 && errno == ECHILD) { + // PID doesn't exist anymore, set previously sampled exit status (or -1) + exit_status = data.exit_status; + return true; + } + else if(pid <= 0) { + // Process still running (p==0) or error + return false; + } + else { + // store exit status for future calls + if(exit_status >= 256) + exit_status = exit_status >> 8; + data.exit_status = exit_status; + } + + { + std::lock_guard<std::mutex> lock(close_mutex); + closed = true; + } + close_fds(); + + return true; +} + +void Process::close_fds() noexcept { + if(stdout_stderr_thread.joinable()) + stdout_stderr_thread.join(); + + if(stdin_fd) + close_stdin(); + if(stdout_fd) { + if(data.id > 0) + close(*stdout_fd); + stdout_fd.reset(); + } + if(stderr_fd) { + if(data.id > 0) + close(*stderr_fd); + stderr_fd.reset(); + } +} + +bool Process::write(const char *bytes, size_t n) { + if(!open_stdin) + throw std::invalid_argument("Can't write to an unopened stdin pipe. Please set open_stdin=true when constructing the process."); + + std::lock_guard<std::mutex> lock(stdin_mutex); + if(stdin_fd) { + while(n != 0) { + const ssize_t ret = ::write(*stdin_fd, bytes, n); + if(ret < 0) { + if(errno == EINTR) + continue; + else + return false; + } + bytes += static_cast<size_t>(ret); + n -= static_cast<size_t>(ret); + } + return true; + } + return false; +} + +void Process::close_stdin() noexcept { + std::lock_guard<std::mutex> lock(stdin_mutex); + if(stdin_fd) { + if(data.id > 0) + close(*stdin_fd); + stdin_fd.reset(); + } +} + +void Process::kill(bool force) noexcept { + std::lock_guard<std::mutex> lock(close_mutex); + if(data.id > 0 && !closed) { + if(force) { + ::kill(-data.id, SIGTERM); + ::kill(data.id, SIGTERM); // Based on comment in https://gitlab.com/eidheim/tiny-process-library/-/merge_requests/29#note_1146144166 + } + else { + ::kill(-data.id, SIGINT); + ::kill(data.id, SIGINT); + } + } +} + +void Process::kill(id_type id, bool force) noexcept { + if(id <= 0) + return; + + if(force) { + ::kill(-id, SIGTERM); + ::kill(id, SIGTERM); + } + else { + ::kill(-id, SIGINT); + ::kill(id, SIGINT); + } +} + +void Process::signal(int signum) noexcept { + std::lock_guard<std::mutex> lock(close_mutex); + if(data.id > 0 && !closed) { + ::kill(-data.id, signum); + ::kill(data.id, signum); + } +} + +} // namespace TinyProcessLib diff --git a/src/libs/tiny-process-library/process_win.cpp b/src/libs/tiny-process-library/process_win.cpp new file mode 100644 index 00000000..dd1c3b5e --- /dev/null +++ b/src/libs/tiny-process-library/process_win.cpp @@ -0,0 +1,424 @@ +#include "process.hpp" +// clang-format off +#include <windows.h> +// clang-format on +#include <cstring> +#include <stdexcept> +#include <tlhelp32.h> + +namespace TinyProcessLib { + +Process::Data::Data() noexcept : id(0) {} + +// Simple HANDLE wrapper to close it automatically from the destructor. +class Handle { +public: + Handle() noexcept : handle(INVALID_HANDLE_VALUE) {} + ~Handle() noexcept { + close(); + } + void close() noexcept { + if(handle != INVALID_HANDLE_VALUE) + CloseHandle(handle); + } + HANDLE detach() noexcept { + HANDLE old_handle = handle; + handle = INVALID_HANDLE_VALUE; + return old_handle; + } + operator HANDLE() const noexcept { return handle; } + HANDLE *operator&() noexcept { return &handle; } + +private: + HANDLE handle; +}; + +template <class Char> +struct CharSet; + +template <> +struct CharSet<char> { + static constexpr const char *whitespace = " \t\n\v\""; + static constexpr char space = ' '; + static constexpr char doublequote = '"'; + static constexpr char backslash = '\\'; +}; + +template <> +struct CharSet<wchar_t> { + static constexpr const wchar_t *whitespace = L" \t\n\v\""; + static constexpr wchar_t space = L' '; + static constexpr wchar_t doublequote = L'"'; + static constexpr wchar_t backslash = L'\\'; +}; + +// Based on blog post https://learn.microsoft.com/en-us/archive/blogs/twistylittlepassagesallalike/everyone-quotes-command-line-arguments-the-wrong-way +template <class Char> +static std::basic_string<Char> join_arguments(const std::vector<std::basic_string<Char>> &args) { + using charset = CharSet<Char>; + + std::basic_string<Char> ret; + + for(const auto &arg : args) { + if(!ret.empty()) + ret.push_back(charset::space); + + if(!arg.empty() && arg.find_first_of(charset::whitespace) == arg.npos) { + ret.append(arg); + continue; + } + + ret.push_back(charset::doublequote); + + for(auto it = arg.begin();; ++it) { + size_t n_backslashes = 0; + + while(it != arg.end() && *it == charset::backslash) { + ++it; + ++n_backslashes; + } + + if(it == arg.end()) { + // Escape all backslashes, but let the terminating double quotation mark + // we add below be interpreted as a metacharacter. + ret.append(n_backslashes * 2, charset::backslash); + break; + } + else if(*it == charset::doublequote) { + // Escape all backslashes and the following double quotation mark. + ret.append(n_backslashes * 2 + 1, charset::backslash); + ret.push_back(*it); + } + else { + // Backslashes aren't special here. + ret.append(n_backslashes, charset::backslash); + ret.push_back(*it); + } + } + + ret.push_back(charset::doublequote); + } + + return ret; +} + +// Based on the discussion thread: https://www.reddit.com/r/cpp/comments/3vpjqg/a_new_platform_independent_process_library_for_c11/cxq1wsj +std::mutex create_process_mutex; + +Process::id_type Process::open(const std::vector<string_type> &arguments, const string_type &path, const environment_type *environment) noexcept { + return open(join_arguments(arguments), path, environment); +} + +// Based on the example at https://msdn.microsoft.com/en-us/library/windows/desktop/ms682499(v=vs.85).aspx. +Process::id_type Process::open(const string_type &command, const string_type &path, const environment_type *environment) noexcept { + if(open_stdin) + stdin_fd = std::unique_ptr<fd_type>(new fd_type(nullptr)); + if(read_stdout) + stdout_fd = std::unique_ptr<fd_type>(new fd_type(nullptr)); + if(read_stderr) + stderr_fd = std::unique_ptr<fd_type>(new fd_type(nullptr)); + + Handle stdin_rd_p; + Handle stdin_wr_p; + Handle stdout_rd_p; + Handle stdout_wr_p; + Handle stderr_rd_p; + Handle stderr_wr_p; + + SECURITY_ATTRIBUTES security_attributes; + + security_attributes.nLength = sizeof(SECURITY_ATTRIBUTES); + security_attributes.bInheritHandle = TRUE; + security_attributes.lpSecurityDescriptor = nullptr; + + std::lock_guard<std::mutex> lock(create_process_mutex); + if(stdin_fd) { + if(!CreatePipe(&stdin_rd_p, &stdin_wr_p, &security_attributes, 0) || + !SetHandleInformation(stdin_wr_p, HANDLE_FLAG_INHERIT, 0)) + return 0; + } + if(stdout_fd) { + if(!CreatePipe(&stdout_rd_p, &stdout_wr_p, &security_attributes, 0) || + !SetHandleInformation(stdout_rd_p, HANDLE_FLAG_INHERIT, 0)) { + return 0; + } + } + if(stderr_fd) { + if(!CreatePipe(&stderr_rd_p, &stderr_wr_p, &security_attributes, 0) || + !SetHandleInformation(stderr_rd_p, HANDLE_FLAG_INHERIT, 0)) { + return 0; + } + } + + PROCESS_INFORMATION process_info; + STARTUPINFO startup_info; + + ZeroMemory(&process_info, sizeof(PROCESS_INFORMATION)); + + ZeroMemory(&startup_info, sizeof(STARTUPINFO)); + startup_info.cb = sizeof(STARTUPINFO); + startup_info.hStdInput = stdin_rd_p; + startup_info.hStdOutput = stdout_wr_p; + startup_info.hStdError = stderr_wr_p; + if(stdin_fd || stdout_fd || stderr_fd) + startup_info.dwFlags |= STARTF_USESTDHANDLES; + + if(config.show_window != Config::ShowWindow::show_default) { + startup_info.dwFlags |= STARTF_USESHOWWINDOW; + startup_info.wShowWindow = static_cast<WORD>(config.show_window); + } + + auto process_command = command; +#ifdef MSYS_PROCESS_USE_SH + size_t pos = 0; + while((pos = process_command.find('\\', pos)) != string_type::npos) { + process_command.replace(pos, 1, "\\\\\\\\"); + pos += 4; + } + pos = 0; + while((pos = process_command.find('\"', pos)) != string_type::npos) { + process_command.replace(pos, 1, "\\\""); + pos += 2; + } + process_command.insert(0, "sh -c \""); + process_command += "\""; +#endif + + DWORD creation_flags = stdin_fd || stdout_fd || stderr_fd ? CREATE_NO_WINDOW : 0; // CREATE_NO_WINDOW cannot be used when stdout or stderr is redirected to parent process + string_type environment_str; + if(environment) { +#ifdef UNICODE + for(const auto &e : *environment) + environment_str += e.first + L'=' + e.second + L'\0'; + if(!environment_str.empty()) + environment_str += L'\0'; + creation_flags |= CREATE_UNICODE_ENVIRONMENT; +#else + for(const auto &e : *environment) + environment_str += e.first + '=' + e.second + '\0'; + if(!environment_str.empty()) + environment_str += '\0'; +#endif + } + BOOL bSuccess = CreateProcess(nullptr, process_command.empty() ? nullptr : &process_command[0], nullptr, nullptr, + stdin_fd || stdout_fd || stderr_fd || config.inherit_file_descriptors, // Cannot be false when stdout, stderr or stdin is used + creation_flags, + environment_str.empty() ? nullptr : &environment_str[0], + path.empty() ? nullptr : path.c_str(), + &startup_info, &process_info); + + if(!bSuccess) + return 0; + else + CloseHandle(process_info.hThread); + + if(stdin_fd) + *stdin_fd = stdin_wr_p.detach(); + if(stdout_fd) + *stdout_fd = stdout_rd_p.detach(); + if(stderr_fd) + *stderr_fd = stderr_rd_p.detach(); + + closed = false; + data.id = process_info.dwProcessId; + data.handle = process_info.hProcess; + return process_info.dwProcessId; +} + +void Process::async_read() noexcept { + if(data.id == 0) + return; + + if(stdout_fd) { + stdout_thread = std::thread([this]() { + DWORD n; + std::unique_ptr<char[]> buffer(new char[config.buffer_size]); + for(;;) { + BOOL bSuccess = ReadFile(*stdout_fd, static_cast<CHAR *>(buffer.get()), static_cast<DWORD>(config.buffer_size), &n, nullptr); + if(!bSuccess || n == 0) { + if(config.on_stdout_close) + config.on_stdout_close(); + break; + } + read_stdout(buffer.get(), static_cast<size_t>(n)); + } + }); + } + if(stderr_fd) { + stderr_thread = std::thread([this]() { + DWORD n; + std::unique_ptr<char[]> buffer(new char[config.buffer_size]); + for(;;) { + BOOL bSuccess = ReadFile(*stderr_fd, static_cast<CHAR *>(buffer.get()), static_cast<DWORD>(config.buffer_size), &n, nullptr); + if(!bSuccess || n == 0) { + if(config.on_stderr_close) + config.on_stderr_close(); + break; + } + read_stderr(buffer.get(), static_cast<size_t>(n)); + } + }); + } +} + +int Process::get_exit_status() noexcept { + if(data.id == 0) + return -1; + + if(!data.handle) + return data.exit_status; + + WaitForSingleObject(data.handle, INFINITE); + + DWORD exit_status; + if(!GetExitCodeProcess(data.handle, &exit_status)) + data.exit_status = -1; // Store exit status for future calls + else + data.exit_status = static_cast<int>(exit_status); // Store exit status for future calls + + { + std::lock_guard<std::mutex> lock(close_mutex); + CloseHandle(data.handle); + data.handle = nullptr; + closed = true; + } + close_fds(); + + return data.exit_status; +} + +bool Process::try_get_exit_status(int &exit_status) noexcept { + if(data.id == 0) { + exit_status = -1; + return true; + } + + if(!data.handle) { + exit_status = data.exit_status; + return true; + } + + DWORD wait_status = WaitForSingleObject(data.handle, 0); + if(wait_status == WAIT_TIMEOUT) + return false; + + DWORD exit_status_tmp; + if(!GetExitCodeProcess(data.handle, &exit_status_tmp)) + exit_status = -1; + else + exit_status = static_cast<int>(exit_status_tmp); + data.exit_status = exit_status; // Store exit status for future calls + + { + std::lock_guard<std::mutex> lock(close_mutex); + CloseHandle(data.handle); + data.handle = nullptr; + closed = true; + } + close_fds(); + + return true; +} + +void Process::close_fds() noexcept { + if(stdout_thread.joinable()) + stdout_thread.join(); + if(stderr_thread.joinable()) + stderr_thread.join(); + + if(stdin_fd) + close_stdin(); + if(stdout_fd) { + if(*stdout_fd != nullptr) + CloseHandle(*stdout_fd); + stdout_fd.reset(); + } + if(stderr_fd) { + if(*stderr_fd != nullptr) + CloseHandle(*stderr_fd); + stderr_fd.reset(); + } +} + +bool Process::write(const char *bytes, size_t n) { + if(!open_stdin) + throw std::invalid_argument("Can't write to an unopened stdin pipe. Please set open_stdin=true when constructing the process."); + + std::lock_guard<std::mutex> lock(stdin_mutex); + if(stdin_fd) { + DWORD written; + BOOL bSuccess = WriteFile(*stdin_fd, bytes, static_cast<DWORD>(n), &written, nullptr); + if(!bSuccess || written == 0) { + return false; + } + else { + return true; + } + } + return false; +} + +void Process::close_stdin() noexcept { + std::lock_guard<std::mutex> lock(stdin_mutex); + if(stdin_fd) { + if(*stdin_fd != nullptr) + CloseHandle(*stdin_fd); + stdin_fd.reset(); + } +} + +// Based on http://stackoverflow.com/a/1173396 +void Process::kill(bool /*force*/) noexcept { + std::lock_guard<std::mutex> lock(close_mutex); + if(data.id > 0 && !closed) { + HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + if(snapshot) { + PROCESSENTRY32 process; + ZeroMemory(&process, sizeof(process)); + process.dwSize = sizeof(process); + if(Process32First(snapshot, &process)) { + do { + if(process.th32ParentProcessID == data.id) { + HANDLE process_handle = OpenProcess(PROCESS_TERMINATE, FALSE, process.th32ProcessID); + if(process_handle) { + TerminateProcess(process_handle, 2); + CloseHandle(process_handle); + } + } + } while(Process32Next(snapshot, &process)); + } + CloseHandle(snapshot); + } + TerminateProcess(data.handle, 2); + } +} + +// Based on http://stackoverflow.com/a/1173396 +void Process::kill(id_type id, bool /*force*/) noexcept { + if(id == 0) + return; + + HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + if(snapshot) { + PROCESSENTRY32 process; + ZeroMemory(&process, sizeof(process)); + process.dwSize = sizeof(process); + if(Process32First(snapshot, &process)) { + do { + if(process.th32ParentProcessID == id) { + HANDLE process_handle = OpenProcess(PROCESS_TERMINATE, FALSE, process.th32ProcessID); + if(process_handle) { + TerminateProcess(process_handle, 2); + CloseHandle(process_handle); + } + } + } while(Process32Next(snapshot, &process)); + } + CloseHandle(snapshot); + } + HANDLE process_handle = OpenProcess(PROCESS_TERMINATE, FALSE, id); + if(process_handle) + TerminateProcess(process_handle, 2); +} + +} // namespace TinyProcessLib From 1600cf179159d1d2d6b8582c2ca5c4f7ac5fa8c7 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Sun, 20 Jul 2025 23:11:14 +0200 Subject: [PATCH 107/143] misc: ditch selfmade command execute functions in favour of tiny-proccess-library follow up of parent commit this library is cross-platform and easier so --- cufetchpm/src/pluginManager.cpp | 2 +- include/tiny-process-library/process.hpp | 184 +++++++++++++++++++++ include/util.hpp | 15 +- libcufetch/parse.cc | 4 +- src/core-modules/android/user.cc | 7 +- src/core-modules/linux/user.cc | 7 +- src/display.cpp | 5 +- src/libs/tiny-process-library/process.hpp | 185 +--------------------- src/util.cpp | 138 ++-------------- 9 files changed, 218 insertions(+), 329 deletions(-) create mode 100644 include/tiny-process-library/process.hpp mode change 100644 => 120000 src/libs/tiny-process-library/process.hpp diff --git a/cufetchpm/src/pluginManager.cpp b/cufetchpm/src/pluginManager.cpp index 1d1474fc..cb6177ca 100644 --- a/cufetchpm/src/pluginManager.cpp +++ b/cufetchpm/src/pluginManager.cpp @@ -59,7 +59,7 @@ void PluginManager::add_repo_plugins(const std::string& repo) std::filesystem::create_directories(working_dir); status("Cloning repository '{}' at '{}'", repo, working_dir.string()); - if (!taur_exec({"git", "clone", "--recursive", repo, working_dir.string()}, false)) + if (Process({"git", "clone", "--recursive", repo, working_dir.string()}).get_exit_status() != 0) { std::filesystem::remove_all(working_dir); die("Failed to clone at directory '{}'", working_dir.string()); diff --git a/include/tiny-process-library/process.hpp b/include/tiny-process-library/process.hpp new file mode 100644 index 00000000..351c6c1b --- /dev/null +++ b/include/tiny-process-library/process.hpp @@ -0,0 +1,184 @@ +#ifndef TINY_PROCESS_LIBRARY_HPP_ +#define TINY_PROCESS_LIBRARY_HPP_ +#include <functional> +#include <memory> +#include <mutex> +#include <string> +#include <thread> +#include <unordered_map> +#include <vector> +#ifndef _WIN32 +#include <sys/wait.h> +#endif + +namespace TinyProcessLib { +/// Additional parameters to Process constructors. +struct Config { + /// Buffer size for reading stdout and stderr. Default is 131072 (128 kB). + std::size_t buffer_size = 131072; + /// Set to true to inherit file descriptors from parent process. Default is false. + /// On Windows: has no effect unless read_stdout==nullptr, read_stderr==nullptr and open_stdin==false. + bool inherit_file_descriptors = false; + + /// If set, invoked when process stdout is closed. + /// This call goes after last call to read_stdout(). + std::function<void()> on_stdout_close = nullptr; + /// If set, invoked when process stderr is closed. + /// This call goes after last call to read_stderr(). + std::function<void()> on_stderr_close = nullptr; + + /// On Windows only: controls how the process is started, mimics STARTUPINFO's wShowWindow. + /// See: https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/ns-processthreadsapi-startupinfoa + /// and https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-showwindow + enum class ShowWindow { + hide = 0, + show_normal = 1, + show_minimized = 2, + maximize = 3, + show_maximized = 3, + show_no_activate = 4, + show = 5, + minimize = 6, + show_min_no_active = 7, + show_na = 8, + restore = 9, + show_default = 10, + force_minimize = 11 + }; + /// On Windows only: controls how the window is shown. + ShowWindow show_window{ShowWindow::show_default}; + + /// Set to true to break out of flatpak sandbox by prepending all commands with `/usr/bin/flatpak-spawn --host` + /// which will execute the command line on the host system. + /// Requires the flatpak `org.freedesktop.Flatpak` portal to be opened for the current sandbox. + /// See https://docs.flatpak.org/en/latest/flatpak-command-reference.html#flatpak-spawn. + bool flatpak_spawn_host = false; +}; + +/// Platform independent class for creating processes. +/// Note on Windows: it seems not possible to specify which pipes to redirect. +/// Thus, at the moment, if read_stdout==nullptr, read_stderr==nullptr and open_stdin==false, +/// the stdout, stderr and stdin are sent to the parent process instead. +class Process { +public: +#ifdef _WIN32 + typedef unsigned long id_type; // Process id type + typedef void *fd_type; // File descriptor type +#ifdef UNICODE + typedef std::wstring string_type; +#else + typedef std::string string_type; +#endif +#else + typedef pid_t id_type; + typedef int fd_type; + typedef std::string string_type; +#endif + typedef std::unordered_map<string_type, string_type> environment_type; + +private: + class Data { + public: + Data() noexcept; + id_type id; +#ifdef _WIN32 + void *handle{nullptr}; +#endif + int exit_status{-1}; + }; + +public: + /// Starts a process with the environment of the calling process. + Process(const std::vector<string_type> &arguments, const string_type &path = string_type(), + std::function<void(const char *bytes, size_t n)> read_stdout = nullptr, + std::function<void(const char *bytes, size_t n)> read_stderr = nullptr, + bool open_stdin = false, + const Config &config = {}) noexcept; + /// Starts a process with the environment of the calling process. + Process(const string_type &command, const string_type &path = string_type(), + std::function<void(const char *bytes, size_t n)> read_stdout = nullptr, + std::function<void(const char *bytes, size_t n)> read_stderr = nullptr, + bool open_stdin = false, + const Config &config = {}) noexcept; + + /// Starts a process with specified environment. + Process(const std::vector<string_type> &arguments, + const string_type &path, + const environment_type &environment, + std::function<void(const char *bytes, size_t n)> read_stdout = nullptr, + std::function<void(const char *bytes, size_t n)> read_stderr = nullptr, + bool open_stdin = false, + const Config &config = {}) noexcept; + /// Starts a process with specified environment. + Process(const string_type &command, + const string_type &path, + const environment_type &environment, + std::function<void(const char *bytes, size_t n)> read_stdout = nullptr, + std::function<void(const char *bytes, size_t n)> read_stderr = nullptr, + bool open_stdin = false, + const Config &config = {}) noexcept; +#ifndef _WIN32 + /// Starts a process with the environment of the calling process. + /// Supported on Unix-like systems only. + /// Since the command line is not known to the Process object itself, + /// this overload does not support the flatpak_spawn_host configuration. + Process(const std::function<void()> &function, + std::function<void(const char *bytes, size_t n)> read_stdout = nullptr, + std::function<void(const char *bytes, size_t n)> read_stderr = nullptr, + bool open_stdin = false, + const Config &config = {}); +#endif + ~Process() noexcept; + + /// Get the process id of the started process. + id_type get_id() const noexcept; + /// Wait until process is finished, and return exit status. + int get_exit_status() noexcept; + /// If process is finished, returns true and sets the exit status. Returns false otherwise. + bool try_get_exit_status(int &exit_status) noexcept; + /// Write to stdin. + bool write(const char *bytes, size_t n); + /// Write to stdin. Convenience function using write(const char *, size_t). + bool write(const std::string &str); + /// Close stdin. If the process takes parameters from stdin, use this to notify that all parameters have been sent. + void close_stdin() noexcept; + + /// Kill the process. force=true is only supported on Unix-like systems. + void kill(bool force = false) noexcept; + /// Kill a given process id. Use kill(bool force) instead if possible. force=true is only supported on Unix-like systems. + static void kill(id_type id, bool force = false) noexcept; +#ifndef _WIN32 + /// Send the signal signum to the process. + void signal(int signum) noexcept; +#endif + +private: + Data data; + bool closed; + std::mutex close_mutex; + std::function<void(const char *bytes, size_t n)> read_stdout; + std::function<void(const char *bytes, size_t n)> read_stderr; +#ifndef _WIN32 + std::thread stdout_stderr_thread; +#else + std::thread stdout_thread, stderr_thread; +#endif + bool open_stdin; + std::mutex stdin_mutex; + + Config config; + + std::unique_ptr<fd_type> stdout_fd, stderr_fd, stdin_fd; + + id_type open(const std::vector<string_type> &arguments, const string_type &path, const environment_type *environment = nullptr) noexcept; + id_type open(const string_type &command, const string_type &path, const environment_type *environment = nullptr) noexcept; +#ifndef _WIN32 + id_type open(const std::function<void()> &function) noexcept; +#endif + void async_read() noexcept; + void close_fds() noexcept; +}; + +} // namespace TinyProcessLib + +#endif // TINY_PROCESS_LIBRARY_HPP_ diff --git a/include/util.hpp b/include/util.hpp index fe7df8cf..1e220687 100644 --- a/include/util.hpp +++ b/include/util.hpp @@ -122,12 +122,6 @@ EXPORT std::string binarySearchPCIArray(const std::string_view vendor_id_s, cons */ EXPORT std::string binarySearchPCIArray(const std::string_view vendor_id_s); -/* http://stackoverflow.com/questions/478898/ddg#478960 - * Execute shell command and read its output from stdout. - * @param cmd The command to execute - */ -EXPORT std::string read_shell_exec(const std::string_view cmd); - /* Get file value from a file and trim quotes and double-quotes * @param iterIndex The iteration index used for getting the necessary value only tot times * @param line The string used in std::getline @@ -167,13 +161,6 @@ EXPORT void ctrl_d_handler(const std::istream& cin); */ EXPORT std::string expandVar(std::string ret, bool dont = false); -/* Executes commands with execvp() and keep the program running without existing - * @param cmd_str The command to execute - * @param exitOnFailure Whether to call exit(1) on command failure. - * @return true if the command successed, else false - */ -EXPORT bool taur_exec(const std::vector<std::string_view> cmd_str, const bool noerror_print = true); - /* Get a relative path from an enviroment variable (PATH, XDG_DATA_DIRS, ...) * Either path of an executable, directory, etc... * @param relative_path The path we would search in the env @@ -236,7 +223,7 @@ EXPORT void replace_str(std::string& str, const std::string_view from, const std * @param noerror_print Print errors (default true) * @return true if the command successed, else false */ -EXPORT bool read_exec(std::vector<const char*> cmd, std::string& output, bool useStdErr = false, bool noerror_print = true); +EXPORT bool read_exec(std::vector<std::string> cmd, std::string& output, bool useStdErr = false, bool noerror_print = true); /* Make whole string lowercase * @param str The string to use diff --git a/libcufetch/parse.cc b/libcufetch/parse.cc index a7be701d..d3cad751 100644 --- a/libcufetch/parse.cc +++ b/libcufetch/parse.cc @@ -37,6 +37,7 @@ #include <string_view> #include <vector> +#include "tiny-process-library/process.hpp" #include "libcufetch/common.hh" #include "libcufetch/config.hh" #include "libcufetch/cufetch.hh" @@ -354,7 +355,8 @@ std::optional<std::string> parse_command_tag(Parser& parser, parse_args_t& parse if (removetag) command.erase(0, 1); - const std::string& cmd_output = read_shell_exec(command); + std::string cmd_output; + TinyProcessLib::Process proc(command, "", [&](const char* bytes, size_t n){cmd_output.assign(bytes, n);}); if (!parse_args.parsingLayout && !removetag && parser.dollar_pos != std::string::npos) parse_args.pureOutput.replace(parser.dollar_pos, command.length() + "$()"_len, cmd_output); diff --git a/src/core-modules/android/user.cc b/src/core-modules/android/user.cc index e8eca565..c6e0a75a 100644 --- a/src/core-modules/android/user.cc +++ b/src/core-modules/android/user.cc @@ -5,9 +5,12 @@ #include <string> +#include "tiny-process-library/process.hpp" #include "core-modules.hh" #include "util.hpp" +using namespace TinyProcessLib; + MODFUNC(user_name) { return g_pwd->pw_name; } @@ -28,9 +31,9 @@ MODFUNC(user_shell_version) std::string ret; if (shell_name == "nu") - ret = read_shell_exec("nu -c \"version | get version\""); + Process("nu -c \"version | get version\"", "", [&](const char *bytes, size_t n){ ret.assign(bytes, n); }); else - ret = read_shell_exec(fmt::format("{} -c 'echo \"${}_VERSION\"'", shell_name, str_toupper(shell_name.data()))); + Process(fmt::format("{} -c 'echo \"${}_VERSION\"'", shell_name, str_toupper(shell_name.data())), "", [&](const char *bytes, size_t n){ ret.assign(bytes, n); }); strip(ret); return ret; diff --git a/src/core-modules/linux/user.cc b/src/core-modules/linux/user.cc index 80b0c2ca..7f46d2e2 100644 --- a/src/core-modules/linux/user.cc +++ b/src/core-modules/linux/user.cc @@ -5,6 +5,7 @@ #include <fstream> +#include "tiny-process-library/process.hpp" #include "core-modules.hh" #include "libcufetch/common.hh" #include "fmt/format.h" @@ -18,6 +19,8 @@ #include <wayland-client.h> #endif +using namespace TinyProcessLib; + // clang-format off static std::string get_term_name_env(bool get_default = false) { @@ -83,9 +86,9 @@ MODFUNC(user_shell_version) std::string ret; if (shell_name == "nu") - ret = read_shell_exec("nu -c \"version | get version\""); + Process("nu -c \"version | get version\"", "", [&](const char *bytes, size_t n){ ret.assign(bytes, n); }); else - ret = read_shell_exec(fmt::format("{} -c 'echo \"${}_VERSION\"'", shell_name, str_toupper(shell_name.data()))); + Process(fmt::format("{} -c 'echo \"${}_VERSION\"'", shell_name, str_toupper(shell_name.data())), "", [&](const char *bytes, size_t n){ ret.assign(bytes, n); }); strip(ret); return ret; diff --git a/src/display.cpp b/src/display.cpp index 12bc18cf..72dfdc6a 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -62,6 +62,7 @@ #include "stb_image.h" #include "utf8/checked.h" #include "util.hpp" +#include "tiny-process-library/process.hpp" std::string Display::detect_distro(const Config& config) { @@ -144,11 +145,11 @@ static std::vector<std::string> render_with_image(const moduleMap_t& modulesInfo const size_t height = image_height / font_height; if (config.args_image_backend == "kitty") - taur_exec({ "kitty", "+kitten", "icat", + TinyProcessLib::Process({ "kitty", "+kitten", "icat", "--align", (config.logo_position == "top" ? "center" : config.logo_position), "--place", fmt::format("{}x{}@0x0", width, height), path.string() }); else if (config.args_image_backend == "viu") - taur_exec({ "viu", "-t", "-w", fmt::to_string(width), "-h", fmt::to_string(height), path.string() }); + TinyProcessLib::Process({ "viu", "-t", "-w", fmt::to_string(width), "-h", fmt::to_string(height), path.string() }); else die(_("The image backend '{}' isn't supported, only 'kitty' and 'viu'.\n" "Please currently use the GUI mode for rendering the image/gif (use -h for more details)"), diff --git a/src/libs/tiny-process-library/process.hpp b/src/libs/tiny-process-library/process.hpp deleted file mode 100644 index 351c6c1b..00000000 --- a/src/libs/tiny-process-library/process.hpp +++ /dev/null @@ -1,184 +0,0 @@ -#ifndef TINY_PROCESS_LIBRARY_HPP_ -#define TINY_PROCESS_LIBRARY_HPP_ -#include <functional> -#include <memory> -#include <mutex> -#include <string> -#include <thread> -#include <unordered_map> -#include <vector> -#ifndef _WIN32 -#include <sys/wait.h> -#endif - -namespace TinyProcessLib { -/// Additional parameters to Process constructors. -struct Config { - /// Buffer size for reading stdout and stderr. Default is 131072 (128 kB). - std::size_t buffer_size = 131072; - /// Set to true to inherit file descriptors from parent process. Default is false. - /// On Windows: has no effect unless read_stdout==nullptr, read_stderr==nullptr and open_stdin==false. - bool inherit_file_descriptors = false; - - /// If set, invoked when process stdout is closed. - /// This call goes after last call to read_stdout(). - std::function<void()> on_stdout_close = nullptr; - /// If set, invoked when process stderr is closed. - /// This call goes after last call to read_stderr(). - std::function<void()> on_stderr_close = nullptr; - - /// On Windows only: controls how the process is started, mimics STARTUPINFO's wShowWindow. - /// See: https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/ns-processthreadsapi-startupinfoa - /// and https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-showwindow - enum class ShowWindow { - hide = 0, - show_normal = 1, - show_minimized = 2, - maximize = 3, - show_maximized = 3, - show_no_activate = 4, - show = 5, - minimize = 6, - show_min_no_active = 7, - show_na = 8, - restore = 9, - show_default = 10, - force_minimize = 11 - }; - /// On Windows only: controls how the window is shown. - ShowWindow show_window{ShowWindow::show_default}; - - /// Set to true to break out of flatpak sandbox by prepending all commands with `/usr/bin/flatpak-spawn --host` - /// which will execute the command line on the host system. - /// Requires the flatpak `org.freedesktop.Flatpak` portal to be opened for the current sandbox. - /// See https://docs.flatpak.org/en/latest/flatpak-command-reference.html#flatpak-spawn. - bool flatpak_spawn_host = false; -}; - -/// Platform independent class for creating processes. -/// Note on Windows: it seems not possible to specify which pipes to redirect. -/// Thus, at the moment, if read_stdout==nullptr, read_stderr==nullptr and open_stdin==false, -/// the stdout, stderr and stdin are sent to the parent process instead. -class Process { -public: -#ifdef _WIN32 - typedef unsigned long id_type; // Process id type - typedef void *fd_type; // File descriptor type -#ifdef UNICODE - typedef std::wstring string_type; -#else - typedef std::string string_type; -#endif -#else - typedef pid_t id_type; - typedef int fd_type; - typedef std::string string_type; -#endif - typedef std::unordered_map<string_type, string_type> environment_type; - -private: - class Data { - public: - Data() noexcept; - id_type id; -#ifdef _WIN32 - void *handle{nullptr}; -#endif - int exit_status{-1}; - }; - -public: - /// Starts a process with the environment of the calling process. - Process(const std::vector<string_type> &arguments, const string_type &path = string_type(), - std::function<void(const char *bytes, size_t n)> read_stdout = nullptr, - std::function<void(const char *bytes, size_t n)> read_stderr = nullptr, - bool open_stdin = false, - const Config &config = {}) noexcept; - /// Starts a process with the environment of the calling process. - Process(const string_type &command, const string_type &path = string_type(), - std::function<void(const char *bytes, size_t n)> read_stdout = nullptr, - std::function<void(const char *bytes, size_t n)> read_stderr = nullptr, - bool open_stdin = false, - const Config &config = {}) noexcept; - - /// Starts a process with specified environment. - Process(const std::vector<string_type> &arguments, - const string_type &path, - const environment_type &environment, - std::function<void(const char *bytes, size_t n)> read_stdout = nullptr, - std::function<void(const char *bytes, size_t n)> read_stderr = nullptr, - bool open_stdin = false, - const Config &config = {}) noexcept; - /// Starts a process with specified environment. - Process(const string_type &command, - const string_type &path, - const environment_type &environment, - std::function<void(const char *bytes, size_t n)> read_stdout = nullptr, - std::function<void(const char *bytes, size_t n)> read_stderr = nullptr, - bool open_stdin = false, - const Config &config = {}) noexcept; -#ifndef _WIN32 - /// Starts a process with the environment of the calling process. - /// Supported on Unix-like systems only. - /// Since the command line is not known to the Process object itself, - /// this overload does not support the flatpak_spawn_host configuration. - Process(const std::function<void()> &function, - std::function<void(const char *bytes, size_t n)> read_stdout = nullptr, - std::function<void(const char *bytes, size_t n)> read_stderr = nullptr, - bool open_stdin = false, - const Config &config = {}); -#endif - ~Process() noexcept; - - /// Get the process id of the started process. - id_type get_id() const noexcept; - /// Wait until process is finished, and return exit status. - int get_exit_status() noexcept; - /// If process is finished, returns true and sets the exit status. Returns false otherwise. - bool try_get_exit_status(int &exit_status) noexcept; - /// Write to stdin. - bool write(const char *bytes, size_t n); - /// Write to stdin. Convenience function using write(const char *, size_t). - bool write(const std::string &str); - /// Close stdin. If the process takes parameters from stdin, use this to notify that all parameters have been sent. - void close_stdin() noexcept; - - /// Kill the process. force=true is only supported on Unix-like systems. - void kill(bool force = false) noexcept; - /// Kill a given process id. Use kill(bool force) instead if possible. force=true is only supported on Unix-like systems. - static void kill(id_type id, bool force = false) noexcept; -#ifndef _WIN32 - /// Send the signal signum to the process. - void signal(int signum) noexcept; -#endif - -private: - Data data; - bool closed; - std::mutex close_mutex; - std::function<void(const char *bytes, size_t n)> read_stdout; - std::function<void(const char *bytes, size_t n)> read_stderr; -#ifndef _WIN32 - std::thread stdout_stderr_thread; -#else - std::thread stdout_thread, stderr_thread; -#endif - bool open_stdin; - std::mutex stdin_mutex; - - Config config; - - std::unique_ptr<fd_type> stdout_fd, stderr_fd, stdin_fd; - - id_type open(const std::vector<string_type> &arguments, const string_type &path, const environment_type *environment = nullptr) noexcept; - id_type open(const string_type &command, const string_type &path, const environment_type *environment = nullptr) noexcept; -#ifndef _WIN32 - id_type open(const std::function<void()> &function) noexcept; -#endif - void async_read() noexcept; - void close_fds() noexcept; -}; - -} // namespace TinyProcessLib - -#endif // TINY_PROCESS_LIBRARY_HPP_ diff --git a/src/libs/tiny-process-library/process.hpp b/src/libs/tiny-process-library/process.hpp new file mode 120000 index 00000000..d1d4e409 --- /dev/null +++ b/src/libs/tiny-process-library/process.hpp @@ -0,0 +1 @@ +../../../include/tiny-process-library/process.hpp \ No newline at end of file diff --git a/src/util.cpp b/src/util.cpp index e171c67c..7d805a02 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -32,21 +32,19 @@ #include <algorithm> #include <array> -#include <cerrno> #include <cstdint> #include <cstring> #include <filesystem> #include <fstream> #include <iostream> -#include <memory> #include <sstream> #include <string> #include <string_view> -#include <tuple> #include <vector> -#include "fmt/color.h" +#include "tiny-process-library/process.hpp" #include "fmt/ranges.h" +#include "fmt/color.h" #include "pci.ids.hpp" #include "platform.hpp" @@ -356,107 +354,25 @@ void replace_str(std::string& str, const std::string_view from, const std::strin } } -bool read_exec(std::vector<const char*> cmd, std::string& output, bool useStdErr, bool noerror_print) +bool read_exec(std::vector<std::string> cmd, std::string& output, bool useStdErr, bool noerror_print) { debug("{} cmd = {}", __func__, cmd); - std::array<int, 2> pipeout; - - if (pipe(pipeout.data()) < 0) - die(_("pipe() failed: {}"), strerror(errno)); - - const pid_t pid = fork(); - - // we wait for the command to finish then start executing the rest - if (pid > 0) - { - close(pipeout.at(1)); - - int status; - waitpid(pid, &status, 0); // Wait for the child to finish - - if (WIFEXITED(status) && (WEXITSTATUS(status) == 0 || useStdErr)) - { - // read stdout - debug("reading stdout"); - char c; - while (read(pipeout.at(0), &c, 1) == 1) - output += c; - - close(pipeout.at(0)); - if (!output.empty() && output.back() == '\n') - output.pop_back(); - - return true; - } - else - { - if (!noerror_print) - error(_("Failed to execute the command: {}"), fmt::join(cmd, " ")); - } - } - else if (pid == 0) - { - int nullFile = open("/dev/null", O_WRONLY | O_CLOEXEC); - dup2(pipeout.at(1), useStdErr ? STDERR_FILENO : STDOUT_FILENO); - dup2(nullFile, useStdErr ? STDOUT_FILENO : STDERR_FILENO); - - setenv("LANG", "C", 1); - cmd.push_back(nullptr); - execvp(cmd.at(0), const_cast<char* const*>(cmd.data())); - - die(_("An error has occurred with execvp: {}"), strerror(errno)); - } - else - { - close(pipeout.at(0)); - close(pipeout.at(1)); - die(_("fork() failed: {}"), strerror(errno)); - } + TinyProcessLib::Process proc(cmd, "", [&](const char *bytes, size_t n) { + if (!useStdErr) + output += std::string(bytes, n); + }, [&](const char *bytes, size_t n) { + if (useStdErr) + output += std::string(bytes, n); + else if (!noerror_print) + error(_("Failed to execute the command: {}"), fmt::join(cmd, " ")); + }); - close(pipeout.at(0)); - close(pipeout.at(1)); + if (!output.empty() && output.back() == '\n') + output.pop_back(); - return false; + return proc.get_exit_status() == 0; } -bool taur_exec(const std::vector<std::string_view> cmd_str, const bool noerror_print) -{ - std::vector<const char*> cmd; - for (const std::string_view str : cmd_str) - cmd.push_back(str.data()); - - int pid = fork(); - - if (pid < 0) - { - die(_("fork() failed: {}"), strerror(errno)); - } - - if (pid == 0) - { - debug("running {}", cmd); - cmd.push_back(nullptr); - execvp(cmd.at(0), const_cast<char* const*>(cmd.data())); - - // execvp() returns instead of exiting when failed - die(_("An error has occurred: {}: {}"), cmd.at(0), strerror(errno)); - } - else if (pid > 0) - { // we wait for the command to finish then start executing the rest - int status; - waitpid(pid, &status, 0); // Wait for the child to finish - - if (WIFEXITED(status) && WEXITSTATUS(status) == 0) - return true; - else - { - if (!noerror_print) - error(_("Failed to execute the command: {}"), fmt::join(cmd, " ")); - } - } - - return false; -} std::string str_tolower(std::string str) { for (char& x : str) @@ -551,30 +467,6 @@ std::string binarySearchPCIArray(const std::string_view vendor_id_s) return vendor_from_entry(vendors_location, vendor_id); } -std::string read_shell_exec(const std::string_view cmd) -{ - std::array<char, 4096> buffer; - std::string result; - std::unique_ptr<FILE, void (*)(FILE*)> pipe(popen(cmd.data(), "r"), [](FILE* f) -> void { - // wrapper to ignore the return value from pclose(). - // Is needed with newer versions of gnu g++ - std::ignore = pclose(f); - }); - - if (!pipe) - die(_("popen() failed: {}"), std::strerror(errno)); - - result.reserve(buffer.size()); - while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) - result += buffer.data(); - - // why there is a '\n' at the end?? - if (!result.empty() && result.back() == '\n') - result.pop_back(); - - return result; -} - std::string name_from_entry(size_t dev_entry_pos) { dev_entry_pos += 6; // Offset from the first character to the actual name that we want (xxxx <device name>) From 66b478468f58153215ceb74e19d7b974ab36bf9a Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Mon, 21 Jul 2025 00:02:42 +0200 Subject: [PATCH 108/143] misc: don't hide all toml++ symbols --- src/libs/toml++/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/toml++/Makefile b/src/libs/toml++/Makefile index 315489ce..57598d16 100644 --- a/src/libs/toml++/Makefile +++ b/src/libs/toml++/Makefile @@ -1,12 +1,12 @@ CXX ?= g++ SRC = toml.cpp TARGET = toml.o -CXXFLAGS = -I../../../include/ -fvisibility-inlines-hidden -fvisibility=hidden -fPIC -std=c++20 +CXXFLAGS = -I../../../include/ -fvisibility-inlines-hidden -fvisibility=default -fPIC -std=c++20 all: $(TARGET) $(TARGET): - ${CXX} $(SRC) $(CXXFLAGS) -c -o ../../../$(BUILDDIR)/$@ + $(CXX) $(SRC) $(CXXFLAGS) -c -o ../../../$(BUILDDIR)/$@ clean: rm -rf ../../../$(BUILDDIR)/toml++/$(TARGET) From 44760193ef003166009fe1682ee62dcb1b0095f0 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Mon, 21 Jul 2025 00:07:28 +0200 Subject: [PATCH 109/143] build: fix --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index bb25881b..6a894e0a 100644 --- a/Makefile +++ b/Makefile @@ -89,7 +89,7 @@ ifeq ($(wildcard include/version.h),) ./scripts/generateVersion.sh endif -$(TARGET): genver fmt toml json libcufetch $(OBJ) +$(TARGET): genver fmt toml json tpl libcufetch $(OBJ) mkdir -p $(BUILDDIR) sh ./scripts/generateVersion.sh $(CXX) -o $(BUILDDIR)/$(TARGET) $(OBJ) $(BUILDDIR)/*.o $(LDFLAGS) $(LDLIBS) From e3666f3162c9e9f68b85a7b8a1914938ad3cdae8 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Tue, 22 Jul 2025 13:55:05 +0200 Subject: [PATCH 110/143] build: add some lto flags + fix build for debian packages --- Makefile | 4 ++-- include/tiny-process-library/process.hpp | 2 +- libcufetch/Makefile | 2 +- src/libs/fmt/Makefile | 2 +- src/libs/json/Makefile | 2 +- src/libs/tiny-process-library/Makefile | 2 +- src/libs/toml++/Makefile | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index 6a894e0a..02292f45 100644 --- a/Makefile +++ b/Makefile @@ -51,10 +51,10 @@ SRC_CC = $(wildcard src/core-modules/*.cc src/core-modules/linux/*.cc src/cor OBJ_CPP = $(SRC_CPP:.cpp=.o) OBJ_CC = $(SRC_CC:.cc=.o) OBJ = $(OBJ_CPP) $(OBJ_CC) -LDFLAGS += -L$(BUILDDIR) +LDFLAGS += -L$(BUILDDIR) -flto=auto -ffat-lto-objects LDLIBS += $(BUILDDIR)/libfmt.a $(BUILDDIR)/libtiny-process-library.a -lcufetch -ldl CXXFLAGS ?= -mtune=generic -march=native -CXXFLAGS += -fvisibility-inlines-hidden -fvisibility=hidden -Iinclude -Iinclude/libcufetch -std=c++20 $(VARS) -DVERSION=\"$(VERSION)\" -DLOCALEDIR=\"$(LOCALEDIR)\" -DICONPREFIX=\"$(ICONPREFIX)\" +CXXFLAGS += -flto=auto -ffat-lto-objects -fvisibility-inlines-hidden -fvisibility=hidden -Iinclude -Iinclude/libcufetch -std=c++20 $(VARS) -DVERSION=\"$(VERSION)\" -DLOCALEDIR=\"$(LOCALEDIR)\" -DICONPREFIX=\"$(ICONPREFIX)\" all: genver fmt toml tpl json libcufetch $(TARGET) diff --git a/include/tiny-process-library/process.hpp b/include/tiny-process-library/process.hpp index 351c6c1b..49999e6d 100644 --- a/include/tiny-process-library/process.hpp +++ b/include/tiny-process-library/process.hpp @@ -128,7 +128,7 @@ class Process { bool open_stdin = false, const Config &config = {}); #endif - ~Process() noexcept; + __attribute__((visibility("default"))) ~Process() noexcept; /// Get the process id of the started process. id_type get_id() const noexcept; diff --git a/libcufetch/Makefile b/libcufetch/Makefile index 13bad660..85e97149 100644 --- a/libcufetch/Makefile +++ b/libcufetch/Makefile @@ -19,7 +19,7 @@ SRC = $(wildcard *.cc) OBJ = $(SRC:.cc=.o) ../$(BUILDDIR)/toml.o FMT_STATIC = ../$(BUILDDIR)/libfmt.a OUTPUT := ../$(BUILDDIR)/$(LIBNAME) -CXXFLAGS += -fvisibility-inlines-hidden -fvisibility=hidden -I../include -fPIC -DGUI_APP=$(GUI_APP) +CXXFLAGS += -flto=auto -ffat-lto-objects -fvisibility-inlines-hidden -fvisibility=hidden -I../include -fPIC -DGUI_APP=$(GUI_APP) all: $(OUTPUT) @if [ "$(UNAME_S)" = "Linux" ]; then \ diff --git a/src/libs/fmt/Makefile b/src/libs/fmt/Makefile index 10ae7418..d2fc9b23 100644 --- a/src/libs/fmt/Makefile +++ b/src/libs/fmt/Makefile @@ -5,7 +5,7 @@ CXX ?= g++ # CXX_DEFINES = -DFMT_LIB_EXPORT -Dfmt_EXPORTS CXX_INCLUDES = -I../../../include -CXX_FLAGS = -O3 -DNDEBUG -fvisibility=hidden -fvisibility-inlines-hidden -fPIC +CXX_FLAGS = -O3 -DNDEBUG -flto=auto -ffat-lto-objects -fvisibility=hidden -fvisibility-inlines-hidden -fPIC all: fmt diff --git a/src/libs/json/Makefile b/src/libs/json/Makefile index b18adcf3..8c0110e6 100644 --- a/src/libs/json/Makefile +++ b/src/libs/json/Makefile @@ -1,7 +1,7 @@ CXX ?= g++ SRC = json.cpp TARGET = json.o -CXXFLAGS = -I../../../include -std=c++20 +CXXFLAGS = -I../../../include -flto=auto -ffat-lto-objects -std=c++20 -fPIC all: $(TARGET) diff --git a/src/libs/tiny-process-library/Makefile b/src/libs/tiny-process-library/Makefile index 1b728ab4..bca0fe83 100644 --- a/src/libs/tiny-process-library/Makefile +++ b/src/libs/tiny-process-library/Makefile @@ -1,6 +1,6 @@ CXX ?= g++ CXX_INCLUDES = -I../../../include -CXX_FLAGS = -O3 -DNDEBUG -fvisibility=hidden -fvisibility-inlines-hidden -fPIC +CXX_FLAGS = -O3 -DNDEBUG -flto=auto -ffat-lto-objects -fvisibility=hidden -fvisibility-inlines-hidden -fPIC UNAME_S := $(shell uname -s) diff --git a/src/libs/toml++/Makefile b/src/libs/toml++/Makefile index 57598d16..d75d4d6a 100644 --- a/src/libs/toml++/Makefile +++ b/src/libs/toml++/Makefile @@ -1,7 +1,7 @@ CXX ?= g++ SRC = toml.cpp TARGET = toml.o -CXXFLAGS = -I../../../include/ -fvisibility-inlines-hidden -fvisibility=default -fPIC -std=c++20 +CXXFLAGS = -I../../../include/ -flto=auto -ffat-lto-objects -fvisibility-inlines-hidden -fvisibility=default -fPIC -std=c++20 all: $(TARGET) From 9d5fbaa3ee14be317eb36bb924efe5547d30b344 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Tue, 22 Jul 2025 14:07:49 +0200 Subject: [PATCH 111/143] core-modules: linux: fix ram/swap query + use MAGIC_LINE for themes --- include/config.hpp | 2 +- src/core-modules/linux/ram.cc | 2 +- src/core-modules/linux/theme.cc | 62 ++++++++++++++++----------------- 3 files changed, 33 insertions(+), 33 deletions(-) diff --git a/include/config.hpp b/include/config.hpp index 0a4818a8..3a258131 100644 --- a/include/config.hpp +++ b/include/config.hpp @@ -195,7 +195,7 @@ layout = [ #if !CF_ANDROID R"#( "${auto}Theme: $<theme.gtk.all.name>", - "${auto}Icons: $<theme.gtk.all.icons>", + "${auto}Icons: $<theme.gtk.all.icon>", "${auto}Font: $<theme.gtk.all.font>", "${auto}Cursor: $<theme.cursor>", "${auto}WM: $<user.wm.name>", diff --git a/src/core-modules/linux/ram.cc b/src/core-modules/linux/ram.cc index d3e93a20..aa262fb2 100644 --- a/src/core-modules/linux/ram.cc +++ b/src/core-modules/linux/ram.cc @@ -39,7 +39,7 @@ static double read_value(const std::string_view key) free(line); rewind(meminfo); - return std::stod(result); + return std::stod(result) * 1024.0f; } double ram_free() diff --git a/src/core-modules/linux/theme.cc b/src/core-modules/linux/theme.cc index 60fb827f..0abec032 100644 --- a/src/core-modules/linux/theme.cc +++ b/src/core-modules/linux/theme.cc @@ -54,7 +54,7 @@ static std::string get_xsettings_xfce4(const std::string_view property, const st const std::string& path = configDir + "/xfce4/xfconf/xfce-perchannel-xml/xsettings.xml"; std::ifstream f(path, std::ios::in); if (!f.is_open()) - return UNKNOWN; + return MAGIC_LINE; buffer.assign(std::istreambuf_iterator<char>{ f }, std::istreambuf_iterator<char>()); buffer.push_back('\0'); @@ -75,7 +75,7 @@ static std::string get_xsettings_xfce4(const std::string_view property, const st return node2->first_attribute("value")->value(); } - return UNKNOWN; + return MAGIC_LINE; } static std::string get_auto_gtk_format(const std::string_view gtk2, const std::string_view gtk3, @@ -125,7 +125,7 @@ static std::string get_auto_gtk_format(const std::string_view gtk2, const std::s // static CursorInfo get_cursor_xresources() { - std::string cursor_name{ UNKNOWN }, cursor_size{ UNKNOWN }; + std::string cursor_name{ MAGIC_LINE }, cursor_size{ MAGIC_LINE }; const std::string& path = expandVar("~/.Xresources"); std::ifstream f(path, std::ios::in); if (!f.is_open()) @@ -153,11 +153,11 @@ static CursorInfo get_cursor_xresources() static CursorInfo get_cursor_dconf() { - std::string cursor{ UNKNOWN }, cursor_size{ UNKNOWN }; + std::string cursor{ MAGIC_LINE }, cursor_size{ MAGIC_LINE }; #if USE_DCONF void* handle = LOAD_LIBRARY("libdconf.so"); if (!handle) - return { UNKNOWN, UNKNOWN }; + return { MAGIC_LINE, MAGIC_LINE }; LOAD_LIB_SYMBOL(handle, DConfClient*, dconf_client_new, void); LOAD_LIB_SYMBOL(handle, GVariant*, dconf_client_read, DConfClient*, const char*); @@ -182,7 +182,7 @@ static CursorInfo get_cursor_dconf() static CursorInfo get_cursor_gsettings() { const CursorInfo& dconf = get_cursor_dconf(); - if (dconf != CursorInfo{ UNKNOWN, UNKNOWN }) + if (dconf != CursorInfo{ MAGIC_LINE, MAGIC_LINE }) return dconf; std::string cursor; @@ -194,15 +194,15 @@ static CursorInfo get_cursor_gsettings() cursor_size.erase(std::remove(cursor_size.begin(), cursor_size.end(), '\''), cursor_size.end()); if (cursor.empty()) - cursor = UNKNOWN; + cursor = MAGIC_LINE; if (cursor_size.empty()) - cursor_size = UNKNOWN; + cursor_size = MAGIC_LINE; return { cursor, cursor_size }; } static CursorInfo get_gtk_cursor_config(const std::string_view path) { - std::string cursor{ UNKNOWN }, cursor_size{ UNKNOWN }; + std::string cursor{ MAGIC_LINE }, cursor_size{ MAGIC_LINE }; std::ifstream f(path.data(), std::ios::in); if (!f.is_open()) return { cursor, cursor_size }; @@ -233,10 +233,10 @@ static CursorInfo get_cursor_from_gtk_configs(const std::uint8_t ver) for (const std::string& path : paths) { const CursorInfo& result = get_gtk_cursor_config(path); - if (result != CursorInfo{ UNKNOWN, UNKNOWN }) + if (result != CursorInfo{ MAGIC_LINE, MAGIC_LINE }) return result; } - return { UNKNOWN, UNKNOWN }; + return { MAGIC_LINE, MAGIC_LINE }; } static CursorInfo get_de_cursor(const std::string_view de_name) @@ -250,7 +250,7 @@ static CursorInfo get_de_cursor(const std::string_view de_name) return { get_xsettings_xfce4("Gtk", "CursorThemeName"), get_xsettings_xfce4("Gtk", "CursorThemeSize") }; } } - return { UNKNOWN, UNKNOWN }; + return { MAGIC_LINE, MAGIC_LINE }; } // @@ -259,7 +259,7 @@ static CursorInfo get_de_cursor(const std::string_view de_name) // static ThemeInfo get_gtk_theme_config(const std::string_view path) { - std::string theme{ UNKNOWN }, icon_theme{ UNKNOWN }, font{ UNKNOWN }; + std::string theme{ MAGIC_LINE }, icon_theme{ MAGIC_LINE }, font{ MAGIC_LINE }; std::ifstream f(path.data(), std::ios::in); if (!f.is_open()) return { theme, icon_theme, font }; @@ -283,7 +283,7 @@ static ThemeInfo get_gtk_theme_config(const std::string_view path) static ThemeInfo get_gtk_theme_dconf() { - std::string theme{ UNKNOWN }, icon_theme{ UNKNOWN }, font{ UNKNOWN }; + std::string theme{ MAGIC_LINE }, icon_theme{ MAGIC_LINE }, font{ MAGIC_LINE }; #if USE_DCONF void* handle = LOAD_LIBRARY("libdconf.so"); if (!handle) @@ -316,7 +316,7 @@ static ThemeInfo get_gtk_theme_dconf() static ThemeInfo get_gtk_theme_gsettings() { const ThemeInfo& dconf = get_gtk_theme_dconf(); - if (dconf != ThemeInfo{ UNKNOWN, UNKNOWN, UNKNOWN }) + if (dconf != ThemeInfo{ MAGIC_LINE, MAGIC_LINE, MAGIC_LINE }) return dconf; std::string theme, icon_theme, font; @@ -331,11 +331,11 @@ static ThemeInfo get_gtk_theme_gsettings() font.erase(std::remove(font.begin(), font.end(), '\''), font.end()); if (theme.empty()) - theme = UNKNOWN; + theme = MAGIC_LINE; if (icon_theme.empty()) - icon_theme = UNKNOWN; + icon_theme = MAGIC_LINE; if (font.empty()) - font = UNKNOWN; + font = MAGIC_LINE; return { theme, icon_theme, font }; } @@ -351,7 +351,7 @@ static ThemeInfo get_gtk_theme_from_configs(const std::uint8_t ver) for (const auto& path : paths) { const ThemeInfo& result = get_gtk_theme_config(path); - if (result != ThemeInfo{ UNKNOWN, UNKNOWN, UNKNOWN }) + if (result != ThemeInfo{ MAGIC_LINE, MAGIC_LINE, MAGIC_LINE }) return result; } return get_gtk_theme_gsettings(); @@ -386,7 +386,7 @@ MODFUNC(theme_gtk_name) const ThemeInfo& result = is_tty ? get_gtk_theme_from_configs(ver) : get_de_gtk_theme(wmde_name, ver); - return result[THEME_NAME] == UNKNOWN ? MAGIC_LINE : result[THEME_NAME]; + return result[THEME_NAME]; } MODFUNC(theme_gtk_icon) @@ -400,7 +400,7 @@ MODFUNC(theme_gtk_icon) const ThemeInfo& result = is_tty ? get_gtk_theme_from_configs(ver) : get_de_gtk_theme(wmde_name, ver); - return result[THEME_ICON] == UNKNOWN ? MAGIC_LINE : result[THEME_ICON]; + return result[THEME_ICON]; } MODFUNC(theme_gtk_font) @@ -414,7 +414,7 @@ MODFUNC(theme_gtk_font) const ThemeInfo& result = is_tty ? get_gtk_theme_from_configs(ver) : get_de_gtk_theme(wmde_name, ver); - return result[THEME_FONT] == UNKNOWN ? MAGIC_LINE : result[THEME_FONT]; + return result[THEME_FONT]; } MODFUNC(theme_gtk_all_name) @@ -447,31 +447,31 @@ MODFUNC(theme_gtk_all_font) MODFUNC(theme_gsettings_name) { const ThemeInfo& result = get_gtk_theme_gsettings(); - return result[THEME_NAME] == UNKNOWN ? MAGIC_LINE : result[THEME_NAME]; + return result[THEME_NAME]; } MODFUNC(theme_gsettings_icon) { const ThemeInfo& result = get_gtk_theme_gsettings(); - return result[THEME_ICON] == UNKNOWN ? MAGIC_LINE : result[THEME_ICON]; + return result[THEME_ICON]; } MODFUNC(theme_gsettings_font) { const ThemeInfo& result = get_gtk_theme_gsettings(); - return result[THEME_FONT] == UNKNOWN ? MAGIC_LINE : result[THEME_FONT]; + return result[THEME_FONT]; } MODFUNC(theme_gsettings_cursor_name) { const CursorInfo& result = get_cursor_gsettings(); - return result[CURSOR_NAME] == UNKNOWN ? MAGIC_LINE : result[CURSOR_NAME]; + return result[CURSOR_NAME]; } MODFUNC(theme_gsettings_cursor_size) { const CursorInfo& result = get_cursor_gsettings(); - return result[CURSOR_SIZE] == UNKNOWN ? MAGIC_LINE : result[CURSOR_SIZE]; + return result[CURSOR_SIZE]; } const std::array<std::function<CursorInfo()>, 6> funcs{ @@ -490,11 +490,11 @@ MODFUNC(theme_cursor_name) for (const auto& method : funcs) { result = method(); - if (result != CursorInfo{ UNKNOWN, UNKNOWN }) + if (result != CursorInfo{ MAGIC_LINE, MAGIC_LINE }) break; } - if (result[CURSOR_NAME] == UNKNOWN) + if (result[CURSOR_NAME] == MAGIC_LINE) return MAGIC_LINE; std::string& cursor_name = result[CURSOR_NAME]; @@ -514,11 +514,11 @@ MODFUNC(theme_cursor_size) for (const auto& method : funcs) { result = method(); - if (result != CursorInfo{ UNKNOWN, UNKNOWN }) + if (result != CursorInfo{ MAGIC_LINE, MAGIC_LINE }) break; } - if (result[CURSOR_SIZE] == UNKNOWN) + if (result[CURSOR_SIZE] == MAGIC_LINE) return MAGIC_LINE; std::string& cursor_size = result[CURSOR_SIZE]; From ef9558abe25fd172a0535173736d5172beeadd75 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Tue, 22 Jul 2025 19:54:23 +0200 Subject: [PATCH 112/143] chore: move external libraries headers into 'libs' also small fix for tiny-process-library --- CMakeLists.txt | 1 + Makefile | 2 +- include/fmt | 1 - include/libs/fmt | 1 + include/{ => libs}/json.h | 0 include/{ => libs}/rapidxml-1.13/rapidxml.hpp | 0 include/{ => libs}/rapidxml-1.13/rapidxml_iterators.hpp | 0 include/{ => libs}/rapidxml-1.13/rapidxml_print.hpp | 0 include/{ => libs}/rapidxml-1.13/rapidxml_utils.hpp | 0 include/{ => libs}/stb_image.h | 0 include/{ => libs}/switch_fnv1a.hpp | 0 include/{ => libs}/tiny-process-library/process.hpp | 0 include/libs/toml++ | 1 + include/{ => libs}/utf8/checked.h | 0 include/{ => libs}/utf8/core.h | 0 include/toml++ | 1 - libcufetch/Makefile | 2 +- src/libs/fmt/Makefile | 7 +++---- src/libs/json/Makefile | 4 ++-- src/libs/tiny-process-library/Makefile | 3 +-- src/libs/toml++/Makefile | 2 +- 21 files changed, 12 insertions(+), 13 deletions(-) delete mode 120000 include/fmt create mode 120000 include/libs/fmt rename include/{ => libs}/json.h (100%) rename include/{ => libs}/rapidxml-1.13/rapidxml.hpp (100%) rename include/{ => libs}/rapidxml-1.13/rapidxml_iterators.hpp (100%) rename include/{ => libs}/rapidxml-1.13/rapidxml_print.hpp (100%) rename include/{ => libs}/rapidxml-1.13/rapidxml_utils.hpp (100%) rename include/{ => libs}/stb_image.h (100%) rename include/{ => libs}/switch_fnv1a.hpp (100%) rename include/{ => libs}/tiny-process-library/process.hpp (100%) create mode 120000 include/libs/toml++ rename include/{ => libs}/utf8/checked.h (100%) rename include/{ => libs}/utf8/core.h (100%) delete mode 120000 include/toml++ diff --git a/CMakeLists.txt b/CMakeLists.txt index 11326852..d9aa9920 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,7 @@ set(CMAKE_VISIBILITY_INLINES_HIDDEN ON) include_directories(include) include_directories(include/libcufetch) +include_directories(include/libs) set_source_files_properties( "src/libs/toml++/toml.cpp" diff --git a/Makefile b/Makefile index 02292f45..f239fdab 100644 --- a/Makefile +++ b/Makefile @@ -54,7 +54,7 @@ OBJ = $(OBJ_CPP) $(OBJ_CC) LDFLAGS += -L$(BUILDDIR) -flto=auto -ffat-lto-objects LDLIBS += $(BUILDDIR)/libfmt.a $(BUILDDIR)/libtiny-process-library.a -lcufetch -ldl CXXFLAGS ?= -mtune=generic -march=native -CXXFLAGS += -flto=auto -ffat-lto-objects -fvisibility-inlines-hidden -fvisibility=hidden -Iinclude -Iinclude/libcufetch -std=c++20 $(VARS) -DVERSION=\"$(VERSION)\" -DLOCALEDIR=\"$(LOCALEDIR)\" -DICONPREFIX=\"$(ICONPREFIX)\" +CXXFLAGS += -flto=auto -ffat-lto-objects -fvisibility-inlines-hidden -fvisibility=hidden -Iinclude -Iinclude/libcufetch -Iinclude/libs -std=c++20 $(VARS) -DVERSION=\"$(VERSION)\" -DLOCALEDIR=\"$(LOCALEDIR)\" -DICONPREFIX=\"$(ICONPREFIX)\" all: genver fmt toml tpl json libcufetch $(TARGET) diff --git a/include/fmt b/include/fmt deleted file mode 120000 index 5e93c20b..00000000 --- a/include/fmt +++ /dev/null @@ -1 +0,0 @@ -libcufetch/fmt \ No newline at end of file diff --git a/include/libs/fmt b/include/libs/fmt new file mode 120000 index 00000000..1149671d --- /dev/null +++ b/include/libs/fmt @@ -0,0 +1 @@ +../libcufetch/fmt \ No newline at end of file diff --git a/include/json.h b/include/libs/json.h similarity index 100% rename from include/json.h rename to include/libs/json.h diff --git a/include/rapidxml-1.13/rapidxml.hpp b/include/libs/rapidxml-1.13/rapidxml.hpp similarity index 100% rename from include/rapidxml-1.13/rapidxml.hpp rename to include/libs/rapidxml-1.13/rapidxml.hpp diff --git a/include/rapidxml-1.13/rapidxml_iterators.hpp b/include/libs/rapidxml-1.13/rapidxml_iterators.hpp similarity index 100% rename from include/rapidxml-1.13/rapidxml_iterators.hpp rename to include/libs/rapidxml-1.13/rapidxml_iterators.hpp diff --git a/include/rapidxml-1.13/rapidxml_print.hpp b/include/libs/rapidxml-1.13/rapidxml_print.hpp similarity index 100% rename from include/rapidxml-1.13/rapidxml_print.hpp rename to include/libs/rapidxml-1.13/rapidxml_print.hpp diff --git a/include/rapidxml-1.13/rapidxml_utils.hpp b/include/libs/rapidxml-1.13/rapidxml_utils.hpp similarity index 100% rename from include/rapidxml-1.13/rapidxml_utils.hpp rename to include/libs/rapidxml-1.13/rapidxml_utils.hpp diff --git a/include/stb_image.h b/include/libs/stb_image.h similarity index 100% rename from include/stb_image.h rename to include/libs/stb_image.h diff --git a/include/switch_fnv1a.hpp b/include/libs/switch_fnv1a.hpp similarity index 100% rename from include/switch_fnv1a.hpp rename to include/libs/switch_fnv1a.hpp diff --git a/include/tiny-process-library/process.hpp b/include/libs/tiny-process-library/process.hpp similarity index 100% rename from include/tiny-process-library/process.hpp rename to include/libs/tiny-process-library/process.hpp diff --git a/include/libs/toml++ b/include/libs/toml++ new file mode 120000 index 00000000..f28312c2 --- /dev/null +++ b/include/libs/toml++ @@ -0,0 +1 @@ +../libcufetch/toml++ \ No newline at end of file diff --git a/include/utf8/checked.h b/include/libs/utf8/checked.h similarity index 100% rename from include/utf8/checked.h rename to include/libs/utf8/checked.h diff --git a/include/utf8/core.h b/include/libs/utf8/core.h similarity index 100% rename from include/utf8/core.h rename to include/libs/utf8/core.h diff --git a/include/toml++ b/include/toml++ deleted file mode 120000 index ff05b4aa..00000000 --- a/include/toml++ +++ /dev/null @@ -1 +0,0 @@ -libcufetch/toml++ \ No newline at end of file diff --git a/libcufetch/Makefile b/libcufetch/Makefile index 85e97149..2b2583f0 100644 --- a/libcufetch/Makefile +++ b/libcufetch/Makefile @@ -19,7 +19,7 @@ SRC = $(wildcard *.cc) OBJ = $(SRC:.cc=.o) ../$(BUILDDIR)/toml.o FMT_STATIC = ../$(BUILDDIR)/libfmt.a OUTPUT := ../$(BUILDDIR)/$(LIBNAME) -CXXFLAGS += -flto=auto -ffat-lto-objects -fvisibility-inlines-hidden -fvisibility=hidden -I../include -fPIC -DGUI_APP=$(GUI_APP) +CXXFLAGS += -flto=auto -ffat-lto-objects -fvisibility-inlines-hidden -fvisibility=hidden -I../include -I../include/libs -fPIC -DGUI_APP=$(GUI_APP) all: $(OUTPUT) @if [ "$(UNAME_S)" = "Linux" ]; then \ diff --git a/src/libs/fmt/Makefile b/src/libs/fmt/Makefile index d2fc9b23..5708ef6b 100644 --- a/src/libs/fmt/Makefile +++ b/src/libs/fmt/Makefile @@ -4,14 +4,13 @@ CXX ?= g++ # CXX_DEFINES = -DFMT_LIB_EXPORT -Dfmt_EXPORTS -CXX_INCLUDES = -I../../../include -CXX_FLAGS = -O3 -DNDEBUG -flto=auto -ffat-lto-objects -fvisibility=hidden -fvisibility-inlines-hidden -fPIC +CXXFLAGS = -I../../../include/libs -O3 -DNDEBUG -flto=auto -ffat-lto-objects -fvisibility=hidden -fvisibility-inlines-hidden -fPIC all: fmt fmt: format.cc os.cc - $(CXX) $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -c format.cc -o format.cc.o - $(CXX) $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -c os.cc -o os.cc.o + $(CXX) $(CXX_DEFINES) $(CXXFLAGS) -c format.cc -o format.cc.o + $(CXX) $(CXX_DEFINES) $(CXXFLAGS) -c os.cc -o os.cc.o ar qc libfmt.a os.cc.o format.cc.o ranlib libfmt.a mv -f libfmt.a ../../../$(BUILDDIR)/libfmt.a diff --git a/src/libs/json/Makefile b/src/libs/json/Makefile index 8c0110e6..d32f39db 100644 --- a/src/libs/json/Makefile +++ b/src/libs/json/Makefile @@ -1,12 +1,12 @@ CXX ?= g++ SRC = json.cpp TARGET = json.o -CXXFLAGS = -I../../../include -flto=auto -ffat-lto-objects -std=c++20 -fPIC +CXXFLAGS = -I../../../include/libs -flto=auto -ffat-lto-objects -std=c++20 -fPIC all: $(TARGET) $(TARGET): - ${CXX} $(SRC) $(CXXFLAGS) -c -o ../../../$(BUILDDIR)/$@ + $(CXX) $(SRC) $(CXXFLAGS) -c -o ../../../$(BUILDDIR)/$@ clean: rm -rf ../../$(BUILDDIR)/json/$(TARGET) diff --git a/src/libs/tiny-process-library/Makefile b/src/libs/tiny-process-library/Makefile index bca0fe83..40748d0b 100644 --- a/src/libs/tiny-process-library/Makefile +++ b/src/libs/tiny-process-library/Makefile @@ -1,6 +1,5 @@ CXX ?= g++ -CXX_INCLUDES = -I../../../include -CXX_FLAGS = -O3 -DNDEBUG -flto=auto -ffat-lto-objects -fvisibility=hidden -fvisibility-inlines-hidden -fPIC +CXXFLAGS = -I../../../include/libs/tiny-process-library -O3 -DNDEBUG -flto=auto -ffat-lto-objects -fvisibility=default -fvisibility-inlines-hidden -fPIC UNAME_S := $(shell uname -s) diff --git a/src/libs/toml++/Makefile b/src/libs/toml++/Makefile index d75d4d6a..95837dba 100644 --- a/src/libs/toml++/Makefile +++ b/src/libs/toml++/Makefile @@ -1,7 +1,7 @@ CXX ?= g++ SRC = toml.cpp TARGET = toml.o -CXXFLAGS = -I../../../include/ -flto=auto -ffat-lto-objects -fvisibility-inlines-hidden -fvisibility=default -fPIC -std=c++20 +CXXFLAGS = -I../../../include/libs -flto=auto -ffat-lto-objects -fvisibility-inlines-hidden -fvisibility=default -fPIC -std=c++20 all: $(TARGET) From 4695cd8d7915d4e82afeddc615f22852406263ab Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Wed, 23 Jul 2025 15:26:14 +0200 Subject: [PATCH 113/143] build: fix cmake + add patch for android in tiny-process-library --- CMakeLists.txt | 31 +++++++++++ src/libs/tiny-process-library/CMakeLists.txt | 52 ------------------- src/libs/tiny-process-library/process.hpp | 2 +- .../tiny-process-library/process_unix.cpp | 14 +++++ 4 files changed, 46 insertions(+), 53 deletions(-) delete mode 100644 src/libs/tiny-process-library/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index d9aa9920..f472ebc3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,6 +15,7 @@ include_directories(include/libs) set_source_files_properties( "src/libs/toml++/toml.cpp" + "src/libs/tiny-process-library/process.cpp" PROPERTIES COMPILE_FLAGS "-fvisibility=default" ) @@ -93,6 +94,36 @@ add_library(fmt STATIC set_target_properties(fmt PROPERTIES POSITION_INDEPENDENT_CODE ON) target_link_libraries(${TARGET_NAME} PUBLIC fmt) +# tiny-process-library (integrated from its own CMakeLists.txt) +add_library(tiny-process-library STATIC + "src/libs/tiny-process-library/process.cpp") +add_library(tiny-process-library::tiny-process-library ALIAS tiny-process-library) + +if(MSVC) + target_compile_definitions(tiny-process-library PRIVATE /D_CRT_SECURE_NO_WARNINGS) +else() + target_compile_options(tiny-process-library PRIVATE -std=c++11 -Wall -Wextra) +endif() + +if(WIN32) + set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) + target_sources(tiny-process-library PRIVATE "src/libs/tiny-process-library/process_win.cpp") + # If compiled using MSYS2, use sh to run commands + if(MSYS) + target_compile_definitions(tiny-process-library PUBLIC MSYS_PROCESS_USE_SH) + endif() +else() + target_sources(tiny-process-library PRIVATE "src/libs/tiny-process-library/process_unix.cpp") +endif() + +find_package(Threads REQUIRED) +target_link_libraries(tiny-process-library Threads::Threads) +target_include_directories(tiny-process-library PUBLIC + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src/libs/tiny-process-library> + $<INSTALL_INTERFACE:include> +) +target_link_libraries(${TARGET_NAME} PUBLIC tiny-process-library) + # libcufetch set(CUFETCH_HEADERS include/libcufetch/config.hh diff --git a/src/libs/tiny-process-library/CMakeLists.txt b/src/libs/tiny-process-library/CMakeLists.txt deleted file mode 100644 index 22a26a33..00000000 --- a/src/libs/tiny-process-library/CMakeLists.txt +++ /dev/null @@ -1,52 +0,0 @@ -cmake_minimum_required(VERSION 3.10) - -project(tiny-process-library) - -add_library(tiny-process-library process.cpp) -add_library(tiny-process-library::tiny-process-library ALIAS tiny-process-library) - -if(MSVC) - target_compile_definitions(tiny-process-library PRIVATE /D_CRT_SECURE_NO_WARNINGS) -else() - target_compile_options(tiny-process-library PRIVATE -std=c++11 -Wall -Wextra) -endif() - -if(WIN32) - set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) - target_sources(tiny-process-library PRIVATE process_win.cpp) - #If compiled using MSYS2, use sh to run commands - if(MSYS) - target_compile_definitions(tiny-process-library PUBLIC MSYS_PROCESS_USE_SH) - endif() -else() - target_sources(tiny-process-library PRIVATE process_unix.cpp) -endif() - -find_package(Threads REQUIRED) - -target_link_libraries(tiny-process-library Threads::Threads) -target_include_directories(tiny-process-library PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> - $<INSTALL_INTERFACE:include>) - -# if tiny-process-library is not a sub-project: -if(CMAKE_SOURCE_DIR STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}") - if(MSVC) - add_definitions(/D_CRT_SECURE_NO_WARNINGS) - else() - add_compile_options(-std=c++11 -Wall -Wextra) - endif() - - install(TARGETS tiny-process-library - EXPORT ${PROJECT_NAME}-config - ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib - RUNTIME DESTINATION bin) - - install(EXPORT ${PROJECT_NAME}-config - FILE ${PROJECT_NAME}-config.cmake - NAMESPACE ${PROJECT_NAME}:: - DESTINATION lib/cmake/${PROJECT_NAME} - ) - - install(FILES process.hpp DESTINATION include) -endif() diff --git a/src/libs/tiny-process-library/process.hpp b/src/libs/tiny-process-library/process.hpp index d1d4e409..f3906d31 120000 --- a/src/libs/tiny-process-library/process.hpp +++ b/src/libs/tiny-process-library/process.hpp @@ -1 +1 @@ -../../../include/tiny-process-library/process.hpp \ No newline at end of file +../../../include/libs/tiny-process-library/process.hpp \ No newline at end of file diff --git a/src/libs/tiny-process-library/process_unix.cpp b/src/libs/tiny-process-library/process_unix.cpp index e2cd8fa0..da4242ce 100644 --- a/src/libs/tiny-process-library/process_unix.cpp +++ b/src/libs/tiny-process-library/process_unix.cpp @@ -32,9 +32,23 @@ static int portable_execvpe(const char *file, char *const argv[], char *const en const char *path = getenv("PATH"); char cspath[PATH_MAX + 1] = {}; if(!path) { +// small patch for android +#ifndef __ANDROID__ // If env variable is not set, use static path string. confstr(_CS_PATH, cspath, sizeof(cspath)); path = cspath; +#else + // we are certainly on termux, thus android, + // and it doesn't have _CS_PATH, so here's a fix/workaround + char *prefix = getenv("PREFIX"); + if (prefix) { + strncat(prefix, "/bin", 6); + path = prefix; + } + else { + path = "/data/data/com.termux/files/usr/bin"; + } +#endif } const size_t path_len = strlen(path); From 17db8ca58ba88e819868293342203e260b451251 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Wed, 23 Jul 2025 17:16:17 +0200 Subject: [PATCH 114/143] clang-format --- .clang-format | 9 ++++--- compile_flags.txt | 1 + include/gui.hpp | 2 +- include/util.hpp | 2 +- src/core-modules/android/battery.cc | 12 +++++---- src/core-modules/android/gpu.cc | 5 ++-- src/core-modules/android/os.cc | 1 + src/core-modules/android/system.cc | 17 +++++------- src/core-modules/android/user.cc | 16 +++++++----- src/core-modules/core-modules.cc | 14 ++++++---- src/core-modules/linux/battery.cc | 1 + src/core-modules/linux/cpu.cc | 2 +- src/core-modules/linux/disk.cc | 2 ++ src/core-modules/linux/ram.cc | 1 + src/core-modules/linux/user.cc | 9 ++++--- src/core-modules/linux/utils/dewm.cc | 2 +- src/core-modules/macos/battery.cc | 1 + src/core-modules/macos/cpu.cc | 6 ++--- src/core-modules/macos/disk.cc | 2 +- src/core-modules/macos/os.cc | 39 ++++++++++++++-------------- src/display.cpp | 4 +-- src/gui.cpp | 7 +++-- src/main.cpp | 8 +++--- src/util.cpp | 25 ++++++++++-------- 24 files changed, 100 insertions(+), 88 deletions(-) diff --git a/.clang-format b/.clang-format index bbcb3665..61c2e565 100644 --- a/.clang-format +++ b/.clang-format @@ -3,8 +3,8 @@ BasedOnStyle: Google # Align assignments and similar statements -AlignConsecutiveAssignments: true -AlignConsecutiveDeclarations: true +AlignConsecutiveAssignments: Consecutive +AlignConsecutiveDeclarations: Consecutive # Align the * in declarations DerivePointerAlignment: false @@ -23,7 +23,7 @@ BreakBeforeBraces: Custom BraceWrapping: AfterCaseLabel: true AfterClass: true - AfterControlStatement: true + AfterControlStatement: Always AfterEnum: true AfterFunction: true AfterNamespace: true @@ -32,6 +32,7 @@ BraceWrapping: BeforeCatch: true BeforeElse: true IndentBraces: false + SplitEmptyFunction: false # Control spaces around various constructs #SpacesInParens: Custom @@ -61,7 +62,7 @@ NamespaceIndentation: None ReflowComments: true # Additional settings to match Source SDK 2013 style -AllowShortIfStatementsOnASingleLine: false +AllowShortIfStatementsOnASingleLine: Never AllowShortLoopsOnASingleLine: false AllowShortFunctionsOnASingleLine: All diff --git a/compile_flags.txt b/compile_flags.txt index aadd9066..c08552c6 100644 --- a/compile_flags.txt +++ b/compile_flags.txt @@ -1,4 +1,5 @@ -I./include +-I./include/libs -Wall -Wextra -Wpedantic diff --git a/include/gui.hpp b/include/gui.hpp index c41b1915..0f855720 100644 --- a/include/gui.hpp +++ b/include/gui.hpp @@ -29,7 +29,6 @@ #if GUI_APP #include "config.hpp" -#include "libcufetch/cufetch.hh" #include "gdkmm/pixbuf.h" #include "gdkmm/pixbufanimation.h" #include "gtkmm/alignment.h" @@ -39,6 +38,7 @@ #include "gtkmm/label.h" #include "gtkmm/overlay.h" #include "gtkmm/window.h" +#include "libcufetch/cufetch.hh" namespace GUI { diff --git a/include/util.hpp b/include/util.hpp index 1e220687..97d16a30 100644 --- a/include/util.hpp +++ b/include/util.hpp @@ -36,9 +36,9 @@ #include <string> #include <vector> -#include "libcufetch/common.hh" #include "fmt/base.h" #include "fmt/color.h" +#include "libcufetch/common.hh" #include "platform.hpp" // clang-format off diff --git a/src/core-modules/android/battery.cc b/src/core-modules/android/battery.cc index e95b1cb6..70df0624 100644 --- a/src/core-modules/android/battery.cc +++ b/src/core-modules/android/battery.cc @@ -6,9 +6,9 @@ #include <vector> #include "core-modules.hh" +#include "json.h" #include "libcufetch/common.hh" #include "libcufetch/fmt/format.h" -#include "json.h" #include "switch_fnv1a.hpp" #include "util.hpp" @@ -66,6 +66,7 @@ static std::string read_value_dumpsys(const std::string_view name, const bool is return MAGIC_LINE; } +// clang-format off MODFUNC(battery_modelname) { return MAGIC_LINE; } @@ -75,6 +76,7 @@ MODFUNC(battery_vendor) MODFUNC(battery_capacity_level) { return MAGIC_LINE; } +// clang-format on MODFUNC(battery_status) { if (!assert_doc()) @@ -84,10 +86,10 @@ MODFUNC(battery_status) charge_status.at(0) = toupper(charge_status.at(0)); switch (fnv1a16::hash(doc["plugged"].as_string())) { - case "PLUGGED_AC"_fnv1a16: return "AC Connected, " + charge_status; - case "PLUGGED_USB"_fnv1a16: return "USB Connected, " + charge_status; - case "PLUGGED_WIRELESS"_fnv1a16: return "Wireless Connected, "+ charge_status; - default: return charge_status; + case "PLUGGED_AC"_fnv1a16: return "AC Connected, " + charge_status; + case "PLUGGED_USB"_fnv1a16: return "USB Connected, " + charge_status; + case "PLUGGED_WIRELESS"_fnv1a16: return "Wireless Connected, " + charge_status; + default: return charge_status; } } diff --git a/src/core-modules/android/gpu.cc b/src/core-modules/android/gpu.cc index d2bdf042..0668cdcf 100644 --- a/src/core-modules/android/gpu.cc +++ b/src/core-modules/android/gpu.cc @@ -168,6 +168,7 @@ static std::string detect_adreno(const std::string& cpu_model_name) return MAGIC_LINE; } +// clang-format off MODFUNC(gpu_name) { const std::string& vendor = android_cpu_vendor(nullptr); @@ -178,8 +179,6 @@ MODFUNC(gpu_name) } MODFUNC(gpu_vendor) -{ - return android_cpu_vendor(nullptr); -} +{ return android_cpu_vendor(nullptr); } #endif diff --git a/src/core-modules/android/os.cc b/src/core-modules/android/os.cc index 37d2f593..149bab12 100644 --- a/src/core-modules/android/os.cc +++ b/src/core-modules/android/os.cc @@ -4,6 +4,7 @@ #include "core-modules.hh" #include "util.hpp" +// clang-format off MODFUNC(os_name) { return "Android"; } diff --git a/src/core-modules/android/system.cc b/src/core-modules/android/system.cc index a9dbc85e..e3b6d4b1 100644 --- a/src/core-modules/android/system.cc +++ b/src/core-modules/android/system.cc @@ -14,11 +14,6 @@ static constexpr std::array<std::string_view, 9> vendors_prop_names = { "ro.product.oppo_model", "ro.oppo.market.name", "ro.product.brand" }; -MODFUNC(host) -{ - return host_vendor(NULL) + " " + host_name(NULL) + " " + host_version(NULL); -} - MODFUNC(host_name) { for (const std::string_view name : vendors_prop_names) @@ -31,15 +26,15 @@ MODFUNC(host_name) return UNKNOWN; } +// clang-format off MODFUNC(host_version) -{ - return get_android_property("ro.product.model"); -} +{ return get_android_property("ro.product.model"); } MODFUNC(host_vendor) -{ - return get_android_property("ro.product.manufacturer"); -} +{ return get_android_property("ro.product.manufacturer"); } + +MODFUNC(host) +{ return host_vendor(NULL) + " " + host_name(NULL) + " " + host_version(NULL); } MODFUNC(arch) { return g_uname_infos.machine; } diff --git a/src/core-modules/android/user.cc b/src/core-modules/android/user.cc index c6e0a75a..79220458 100644 --- a/src/core-modules/android/user.cc +++ b/src/core-modules/android/user.cc @@ -5,15 +5,12 @@ #include <string> -#include "tiny-process-library/process.hpp" #include "core-modules.hh" +#include "tiny-process-library/process.hpp" #include "util.hpp" using namespace TinyProcessLib; -MODFUNC(user_name) -{ return g_pwd->pw_name; } - MODFUNC(user_shell_path) { char buf[PATH_MAX]; @@ -31,15 +28,20 @@ MODFUNC(user_shell_version) std::string ret; if (shell_name == "nu") - Process("nu -c \"version | get version\"", "", [&](const char *bytes, size_t n){ ret.assign(bytes, n); }); + Process("nu -c \"version | get version\"", "", [&](const char* bytes, size_t n) { ret.assign(bytes, n); }); else - Process(fmt::format("{} -c 'echo \"${}_VERSION\"'", shell_name, str_toupper(shell_name.data())), "", [&](const char *bytes, size_t n){ ret.assign(bytes, n); }); + Process(fmt::format("{} -c 'echo \"${}_VERSION\"'", shell_name, str_toupper(shell_name.data())), "", + [&](const char* bytes, size_t n) { ret.assign(bytes, n); }); strip(ret); return ret; } -MODFUNC(user_term_name) +// clang-format off +MMODFUNC(user_name) +{ return g_pwd->pw_name; } + +ODFUNC(user_term_name) { return "Termux"; } MODFUNC(user_term_version) diff --git a/src/core-modules/core-modules.cc b/src/core-modules/core-modules.cc index 333f32df..92831794 100644 --- a/src/core-modules/core-modules.cc +++ b/src/core-modules/core-modules.cc @@ -11,8 +11,8 @@ #include <utility> #include "config.hpp" -#include "libcufetch/cufetch.hh" #include "fmt/format.h" +#include "libcufetch/cufetch.hh" #include "linux/utils/packages.hh" #include "platform.hpp" #include "switch_fnv1a.hpp" @@ -555,8 +555,12 @@ void core_plugins_start(const Config& config) void core_plugins_finish() { - if (mountsFile) fclose(mountsFile); - if (os_release) fclose(os_release); - if (meminfo) fclose(meminfo); - if (cpuinfo) fclose(cpuinfo); + if (mountsFile) + fclose(mountsFile); + if (os_release) + fclose(os_release); + if (meminfo) + fclose(meminfo); + if (cpuinfo) + fclose(cpuinfo); } diff --git a/src/core-modules/linux/battery.cc b/src/core-modules/linux/battery.cc index 19292657..ee274e3b 100644 --- a/src/core-modules/linux/battery.cc +++ b/src/core-modules/linux/battery.cc @@ -46,6 +46,7 @@ static std::string get_battery_info(const std::string& file) return UNKNOWN; } +// clang-format off MODFUNC(battery_modelname) { return get_battery_info("model_name"); } diff --git a/src/core-modules/linux/cpu.cc b/src/core-modules/linux/cpu.cc index 3dba2744..8abcd80e 100644 --- a/src/core-modules/linux/cpu.cc +++ b/src/core-modules/linux/cpu.cc @@ -6,8 +6,8 @@ #include <string> #include "core-modules.hh" -#include "libcufetch/common.hh" #include "fmt/format.h" +#include "libcufetch/common.hh" #include "switch_fnv1a.hpp" #include "util.hpp" diff --git a/src/core-modules/linux/disk.cc b/src/core-modules/linux/disk.cc index e91a9943..07fe5fd6 100644 --- a/src/core-modules/linux/disk.cc +++ b/src/core-modules/linux/disk.cc @@ -164,6 +164,7 @@ static bool get_disk_usage_info(const callbackInfo_t* callbackInfo, struct statv return (statvfs(statpath.c_str(), fs) == 0); } +// clang-format off // don't get confused by the name pls MODFUNC(disk_fsname) { return get_disk_info(callbackInfo)->mnt_type; } @@ -174,6 +175,7 @@ MODFUNC(disk_device) MODFUNC(disk_mountdir) { return get_disk_info(callbackInfo)->mnt_dir; } +// clang-format on MODFUNC(disk_types) { const int types = get_disk_type(get_disk_info(callbackInfo)); diff --git a/src/core-modules/linux/ram.cc b/src/core-modules/linux/ram.cc index aa262fb2..9577f4f7 100644 --- a/src/core-modules/linux/ram.cc +++ b/src/core-modules/linux/ram.cc @@ -42,6 +42,7 @@ static double read_value(const std::string_view key) return std::stod(result) * 1024.0f; } +// clang-format off double ram_free() { return read_value("MemAvailable:"); } diff --git a/src/core-modules/linux/user.cc b/src/core-modules/linux/user.cc index 7f46d2e2..29d055cb 100644 --- a/src/core-modules/linux/user.cc +++ b/src/core-modules/linux/user.cc @@ -5,11 +5,11 @@ #include <fstream> -#include "tiny-process-library/process.hpp" #include "core-modules.hh" -#include "libcufetch/common.hh" #include "fmt/format.h" +#include "libcufetch/common.hh" #include "switch_fnv1a.hpp" +#include "tiny-process-library/process.hpp" #include "util.hpp" #include "utils/dewm.hh" #include "utils/term.hh" @@ -86,9 +86,10 @@ MODFUNC(user_shell_version) std::string ret; if (shell_name == "nu") - Process("nu -c \"version | get version\"", "", [&](const char *bytes, size_t n){ ret.assign(bytes, n); }); + Process("nu -c \"version | get version\"", "", [&](const char* bytes, size_t n) { ret.assign(bytes, n); }); else - Process(fmt::format("{} -c 'echo \"${}_VERSION\"'", shell_name, str_toupper(shell_name.data())), "", [&](const char *bytes, size_t n){ ret.assign(bytes, n); }); + Process(fmt::format("{} -c 'echo \"${}_VERSION\"'", shell_name, str_toupper(shell_name.data())), "", + [&](const char* bytes, size_t n) { ret.assign(bytes, n); }); strip(ret); return ret; diff --git a/src/core-modules/linux/utils/dewm.cc b/src/core-modules/linux/utils/dewm.cc index 7f88f25f..09eb2b93 100644 --- a/src/core-modules/linux/utils/dewm.cc +++ b/src/core-modules/linux/utils/dewm.cc @@ -277,7 +277,7 @@ std::string get_cinnamon_version() static std::string get_xfce4_version_lib() { - void *handle = LOAD_LIBRARY("libxfce4util.so") + void* handle = LOAD_LIBRARY("libxfce4util.so"); if (!handle) return UNKNOWN; diff --git a/src/core-modules/macos/battery.cc b/src/core-modules/macos/battery.cc index 29e95b54..0ecff735 100644 --- a/src/core-modules/macos/battery.cc +++ b/src/core-modules/macos/battery.cc @@ -4,6 +4,7 @@ #include "core-modules.hh" #include "libcufetch/common.hh" +// clang-format off MODFUNC(battery_modelname) { return MAGIC_LINE; } diff --git a/src/core-modules/macos/cpu.cc b/src/core-modules/macos/cpu.cc index bc7f00e8..bb2850c1 100644 --- a/src/core-modules/macos/cpu.cc +++ b/src/core-modules/macos/cpu.cc @@ -20,8 +20,7 @@ static bool get_sysctl(const char* name, void* ret, size_t* oldlenp) return (sysctlbyname(name, ret, oldlenp, NULL, 0) == 0); } -float cpu_temp() -{ return 0; } +float cpu_temp() { return 0; } MODFUNC(cpu_name) { @@ -68,7 +67,6 @@ MODFUNC(cpu_freq_max) return fmt::to_string(static_cast<double>(freq) / std::giga().num); } -MODFUNC(cpu_freq_bios) -{ return MAGIC_LINE; } +MODFUNC(cpu_freq_bios) { return MAGIC_LINE; } #endif diff --git a/src/core-modules/macos/disk.cc b/src/core-modules/macos/disk.cc index db76b854..f1be7d7f 100644 --- a/src/core-modules/macos/disk.cc +++ b/src/core-modules/macos/disk.cc @@ -8,8 +8,8 @@ #include <string> #include "core-modules.hh" -#include "libcufetch/common.hh" #include "fmt/format.h" +#include "libcufetch/common.hh" #include "util.hpp" static std::string format_auto_query_string(std::string str, const struct statfs* fs) diff --git a/src/core-modules/macos/os.cc b/src/core-modules/macos/os.cc index 3ead54ab..e1e5fcef 100644 --- a/src/core-modules/macos/os.cc +++ b/src/core-modules/macos/os.cc @@ -88,6 +88,26 @@ static std::string get_plist_value(const std::string_view name) return UNKNOWN; } +MODFUNC(os_pretty_name) +{ + const std::string& codename = os_version_codename(nullptr); + if (codename != UNKNOWN) + return os_name(nullptr) + " " + os_version_id(nullptr) + " (" + codename + ")"; + return os_name(nullptr) + " " + os_version_id(nullptr); +} + +unsigned long os_uptime() +{ + struct timeval boot_time; + size_t size = sizeof(boot_time); + int name[] = { CTL_KERN, KERN_BOOTTIME }; + if (sysctl(name, 2, &boot_time, &size, NULL, 0) != 0) + die(_("failed to get uptime")); + + return time(NULL) - boot_time.tv_sec; +} + +// clang-format off MODFUNC(os_name) { return get_plist_value("ProductName"); } @@ -100,14 +120,6 @@ MODFUNC(os_version_id) MODFUNC(os_version_codename) { return get_codename(os_version_id(nullptr)); } -MODFUNC(os_pretty_name) -{ - const std::string& codename = os_version_codename(nullptr); - if (codename != UNKNOWN) - return os_name(nullptr) + " " + os_version_id(nullptr) + " (" + codename + ")"; - return os_name(nullptr) + " " + os_version_id(nullptr); -} - MODFUNC(os_kernel_name) { return g_uname_infos.sysname; } @@ -123,15 +135,4 @@ MODFUNC(os_initsys_name) MODFUNC(os_initsys_version) { return UNKNOWN; } -unsigned long os_uptime() -{ - struct timeval boot_time; - size_t size = sizeof(boot_time); - int name[] = { CTL_KERN, KERN_BOOTTIME }; - if (sysctl(name, 2, &boot_time, &size, NULL, 0) != 0) - die(_("failed to get uptime")); - - return time(NULL) - boot_time.tv_sec; -} - #endif diff --git a/src/display.cpp b/src/display.cpp index 72dfdc6a..7f6ab76a 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -34,7 +34,7 @@ #include "platform.hpp" #ifndef GUI_APP -# define STB_IMAGE_IMPLEMENTATION +#define STB_IMAGE_IMPLEMENTATION #endif #if CF_MACOS @@ -60,9 +60,9 @@ #include "parse.hpp" #include "platform.hpp" #include "stb_image.h" +#include "tiny-process-library/process.hpp" #include "utf8/checked.h" #include "util.hpp" -#include "tiny-process-library/process.hpp" std::string Display::detect_distro(const Config& config) { diff --git a/src/gui.cpp b/src/gui.cpp index 1e880853..899a7e9d 100644 --- a/src/gui.cpp +++ b/src/gui.cpp @@ -34,14 +34,13 @@ #include <filesystem> #include <fstream> +#include "display.hpp" +#include "fmt/ranges.h" #include "gdkmm/pixbufanimation.h" +#include "glibmm/main.h" #include "glibmm/refptr.h" #include "gtkmm/cssprovider.h" -#include "glibmm/main.h" #include "gtkmm/enums.h" - -#include "display.hpp" -#include "fmt/ranges.h" #include "stb_image.h" #include "util.hpp" diff --git a/src/main.cpp b/src/main.cpp index 7ace44fd..06d0650c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -25,9 +25,9 @@ #include <dlfcn.h> #include <getopt.h> -#include <unistd.h> -#include <termios.h> #include <stdlib.h> +#include <termios.h> +#include <unistd.h> #include <algorithm> #include <cerrno> @@ -87,8 +87,8 @@ static void enable_raw_mode() static int kbhit() { - struct timeval tv = {0L, 0L}; - fd_set fds; + struct timeval tv = { 0L, 0L }; + fd_set fds; FD_ZERO(&fds); FD_SET(STDIN_FILENO, &fds); return select(STDIN_FILENO + 1, &fds, NULL, NULL, &tv) > 0; diff --git a/src/util.cpp b/src/util.cpp index 7d805a02..2532d0e4 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -42,11 +42,11 @@ #include <string_view> #include <vector> -#include "tiny-process-library/process.hpp" -#include "fmt/ranges.h" #include "fmt/color.h" +#include "fmt/ranges.h" #include "pci.ids.hpp" #include "platform.hpp" +#include "tiny-process-library/process.hpp" bool hasEnding(const std::string_view fullString, const std::string_view ending) { @@ -357,15 +357,18 @@ void replace_str(std::string& str, const std::string_view from, const std::strin bool read_exec(std::vector<std::string> cmd, std::string& output, bool useStdErr, bool noerror_print) { debug("{} cmd = {}", __func__, cmd); - TinyProcessLib::Process proc(cmd, "", [&](const char *bytes, size_t n) { - if (!useStdErr) - output += std::string(bytes, n); - }, [&](const char *bytes, size_t n) { - if (useStdErr) - output += std::string(bytes, n); - else if (!noerror_print) - error(_("Failed to execute the command: {}"), fmt::join(cmd, " ")); - }); + TinyProcessLib::Process proc( + cmd, "", + [&](const char* bytes, size_t n) { + if (!useStdErr) + output += std::string(bytes, n); + }, + [&](const char* bytes, size_t n) { + if (useStdErr) + output += std::string(bytes, n); + else if (!noerror_print) + error(_("Failed to execute the command: {}"), fmt::join(cmd, " ")); + }); if (!output.empty() && output.back() == '\n') output.pop_back(); From 946a1908f97ea95e36d6e40978e94de6be1a0b68 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Thu, 24 Jul 2025 00:11:43 +0200 Subject: [PATCH 115/143] cufetchpm: actually build projects and add to state.toml + (almost)final version of the manifest --- cufetchpm/Makefile | 2 +- cufetchpm/compile_flags.txt | 1 + cufetchpm/include/manifest.hpp | 45 ++++++++++++++++++------- cufetchpm/include/pluginManager.hpp | 17 +++++----- cufetchpm/include/stateManager.hpp | 4 ++- cufetchpm/src/main.cpp | 10 +++--- cufetchpm/src/manifest.cpp | 51 +++++++++++++++-------------- cufetchpm/src/pluginManager.cpp | 38 ++++++++++++--------- cufetchpm/src/stateManager.cpp | 46 ++++++++++++++++++++++++-- 9 files changed, 143 insertions(+), 71 deletions(-) diff --git a/cufetchpm/Makefile b/cufetchpm/Makefile index 16acc667..6a567db3 100644 --- a/cufetchpm/Makefile +++ b/cufetchpm/Makefile @@ -28,7 +28,7 @@ SRC = $(wildcard src/*.cpp src/manager/*.cpp ../src/util.cpp) OBJ = $(SRC:.cpp=.o) LDLIBS += $(BUILDDIR)/libfmt.a $(BUILDDIR)/libtiny-process-library.a CXXFLAGS ?= -mtune=generic -march=native -CXXFLAGS += -fvisibility=hidden -I../include -I../src/libs/ -Iinclude -std=c++20 $(VARS) -DVERSION=\"$(VERSION)\" +CXXFLAGS += -fvisibility=hidden -I../include -I../include/libs/ -Iinclude -std=c++20 $(VARS) -DVERSION=\"$(VERSION)\" all: fmt toml tpl $(TARGET) diff --git a/cufetchpm/compile_flags.txt b/cufetchpm/compile_flags.txt index 3ca034d4..abd51790 100644 --- a/cufetchpm/compile_flags.txt +++ b/cufetchpm/compile_flags.txt @@ -1,4 +1,5 @@ -I../include +-I../include/libs -I../src/libs/ -Iinclude -Wall diff --git a/cufetchpm/include/manifest.hpp b/cufetchpm/include/manifest.hpp index e61bc555..f4dba504 100644 --- a/cufetchpm/include/manifest.hpp +++ b/cufetchpm/include/manifest.hpp @@ -6,36 +6,57 @@ #include <string_view> #include <utility> #include <vector> + #include "libcufetch/common.hh" #include "toml++/toml.hpp" -struct manifest_t +struct plugin_t { + // The plugin name. std::string name; - std::string license; + + // The plugin description. std::string description; + + // The plugin build directory, + // where we'll retrive the built plugin std::string output_dir; + + // The plugin multiple SPDX License Identifier (MIT, GPL-2.0, ...) + // NOTE: it doesn't actually check if they are correct or not. + std::vector<std::string> licenses; + + // Which plugins can be conflicting by name / modules. + // TODO: choose if check either name or git url. + std::vector<std::string> conflicts; + + // The plugin authors. std::vector<std::string> authors; + + // A list of commands to be executed for building the plugin. + // Kinda like a Makefile target instructions. + // Each command will be executed from a different shell session. std::vector<std::string> build_steps; + + // A list of root modules that the plugin will be used for querying its modules + std::vector<std::string> prefixes; }; const char* const MANIFEST_NAME = "cufetchpm.toml"; -class CManifest { +class CManifest +{ public: CManifest(const std::string_view path); - CManifest(toml::table&& tbl) : m_tbl(tbl){} - CManifest(const toml::table& tbl) : m_tbl(std::move(tbl)){} - CManifest &operator=(CManifest &&) = default; - CManifest &operator=(const CManifest &) = default; - ~CManifest() = default; + CManifest(toml::table&& tbl) : m_tbl(std::move(tbl)) {} + CManifest(const toml::table& tbl) : m_tbl(tbl) {} - manifest_t get_plugin(const std::string_view name); - std::vector<manifest_t> get_all_plugins(); + plugin_t get_plugin(const std::string_view name); + std::vector<plugin_t> get_all_plugins(); private: toml::table m_tbl; - bool m_is_state = true; + bool m_is_state = true; template <typename T> T getValue(const std::string_view name, const std::string_view value) const @@ -62,4 +83,4 @@ class CManifest { } }; -#endif // !_MANIFEST_HPP_; +#endif // !_MANIFEST_HPP_; diff --git a/cufetchpm/include/pluginManager.hpp b/cufetchpm/include/pluginManager.hpp index 77fa2ece..3195e359 100644 --- a/cufetchpm/include/pluginManager.hpp +++ b/cufetchpm/include/pluginManager.hpp @@ -11,7 +11,7 @@ #include "toml++/toml.hpp" #include "util.hpp" -constexpr std::array<std::string_view, 1> dependencies = {"git"}; // expand in the future, maybe +constexpr std::array<std::string_view, 1> dependencies = { "git" }; // expand in the future, maybe #define BOLD_COLOR(x) (fmt::emphasis::bold | fmt::fg(fmt::rgb(x))) @@ -19,14 +19,14 @@ template <typename... Args> void success(const std::string_view fmt, Args&&... args) noexcept { fmt::print(BOLD_COLOR((fmt::color::green)), "SUCCESS:\033[0m {}\n", - fmt::format(fmt::runtime(fmt), std::forward<Args>(args)...)); + fmt::format(fmt::runtime(fmt), std::forward<Args>(args)...)); } template <typename... Args> void status(const std::string_view fmt, Args&&... args) noexcept { fmt::print(BOLD_COLOR((fmt::color::cadet_blue)), "status:\033[0m {} ...\n", - fmt::format(fmt::runtime(fmt), std::forward<Args>(args)...)); + fmt::format(fmt::runtime(fmt), std::forward<Args>(args)...)); } #undef BOLD_COLOR @@ -34,18 +34,17 @@ void status(const std::string_view fmt, Args&&... args) noexcept class PluginManager { public: - PluginManager(const StateManager& state) : m_state(state){} - PluginManager(StateManager&& state) : m_state(std::move(state)){} + PluginManager(const StateManager& state) : m_state(state) {} + PluginManager(StateManager&& state) : m_state(std::move(state)) {} void add_repo_plugins(const std::string& repo); bool add_plugin(const std::string&); bool has_deps(); private: - const StateManager& m_state; - const std::filesystem::path m_cache_path{getHomeCacheDir()/"cufetchpm"/"plugins"}; - toml::table m_manifest; + StateManager m_state; + const std::filesystem::path m_cache_path{ getHomeCacheDir() / "cufetchpm" / "plugins" }; + toml::table m_manifest; }; - #endif diff --git a/cufetchpm/include/stateManager.hpp b/cufetchpm/include/stateManager.hpp index 4ec5b57b..eda16503 100644 --- a/cufetchpm/include/stateManager.hpp +++ b/cufetchpm/include/stateManager.hpp @@ -3,6 +3,7 @@ #include <filesystem> +#include "manifest.hpp" #include "toml++/toml.hpp" #include "util.hpp" @@ -14,10 +15,11 @@ class StateManager StateManager(const StateManager&) = default; ~StateManager() = default; + void add_new_plugin(const plugin_t& manifest); toml::table get_state() { return m_state; } private: - const std::filesystem::path m_path{getHomeCacheDir()/"cufetchpm"/"state.toml"}; + const std::filesystem::path m_path{ getHomeCacheDir() / "cufetchpm" / "state.toml" }; toml::table m_state; }; diff --git a/cufetchpm/src/main.cpp b/cufetchpm/src/main.cpp index 1724d090..924a9e36 100644 --- a/cufetchpm/src/main.cpp +++ b/cufetchpm/src/main.cpp @@ -1,11 +1,11 @@ -#include "stateManager.hpp" #include "pluginManager.hpp" +#include "stateManager.hpp" -int main (int argc, char *argv[]) +int main(int argc, char* argv[]) { - std::filesystem::create_directories({getHomeCacheDir()/"cufetchpm"/"plugins"}); - StateManager state; - PluginManager man(state); + std::filesystem::create_directories({ getHomeCacheDir() / "cufetchpm" / "plugins" }); + StateManager state; + PluginManager man(std::move(state)); man.add_repo_plugins(argv[2]); return 0; } diff --git a/cufetchpm/src/manifest.cpp b/cufetchpm/src/manifest.cpp index 6d831a57..49a0ea40 100644 --- a/cufetchpm/src/manifest.cpp +++ b/cufetchpm/src/manifest.cpp @@ -1,4 +1,5 @@ #include "manifest.hpp" + #include <algorithm> #include <cctype> #include <vector> @@ -6,8 +7,10 @@ #include "libcufetch/common.hh" #include "util.hpp" -static bool validManifestName(const std::string_view n) { - return std::ranges::all_of(n, [](const unsigned char c) { return (isalnum(c) || c == '-' || c == '_' || c == '='); }); +static bool validManifestName(const std::string_view n) +{ + return std::ranges::all_of(n, + [](const unsigned char c) { return (isalnum(c) || c == '-' || c == '_' || c == '='); }); } CManifest::CManifest(const std::string_view path) : m_is_state(false) @@ -21,14 +24,13 @@ CManifest::CManifest(const std::string_view path) : m_is_state(false) die(_("Failed to parse state file at '{}':\n" "{}\n" "\t(error occurred at line {} column {})"), - path, err.description(), - err.source().begin.line, err.source().begin.column); + path, err.description(), err.source().begin.line, err.source().begin.column); } } -std::vector<manifest_t> CManifest::get_all_plugins() +std::vector<plugin_t> CManifest::get_all_plugins() { - std::vector<manifest_t> plugins; + std::vector<plugin_t> plugins; for (auto const& [name, _] : m_tbl) { if (name.str() == "repository") @@ -36,33 +38,34 @@ std::vector<manifest_t> CManifest::get_all_plugins() if (!validManifestName(name.str())) { - warn("Plugin '{}' has an invalid name. Only alphanumeric and '-', '_', '=' are allowed in the name", name.str()); + warn("Plugin '{}' has an invalid name. Only alphanumeric and '-', '_', '=' are allowed in the name", + name.str()); continue; } - plugins.push_back({ - name.data(), - getValue<std::string>(name, "license"), - getValue<std::string>(name, "description"), - getValue<std::string>(name, "output-dir"), - getValueArrayStr(name, "authors"), - getValueArrayStr(name, "build-steps"), - }); + plugins.push_back({ .name = name.data(), + .description = getValue<std::string>(name, "description"), + .output_dir = getValue<std::string>(name, "license"), + .licenses = getValueArrayStr(name, "licenses"), + .conflicts = getValueArrayStr(name, "conflicts"), + .authors = getValueArrayStr(name, "authors"), + .build_steps = getValueArrayStr(name, "build-steps"), + .prefixes = getValueArrayStr(name, "prefixes") }); } return plugins; } -manifest_t CManifest::get_plugin(const std::string_view name) +plugin_t CManifest::get_plugin(const std::string_view name) { if (!m_tbl[name].is_table()) die("Couldn't find such plugin '{}' in manifest", name); - return { - name.data(), - getValue<std::string>(name, "license"), - getValue<std::string>(name, "description"), - getValue<std::string>(name, "output-dir"), - getValueArrayStr(name, "authors"), - getValueArrayStr(name, "build-steps"), - }; + return { .name = name.data(), + .description = getValue<std::string>(name, "description"), + .output_dir = getValue<std::string>(name, "license"), + .licenses = getValueArrayStr(name, "licenses"), + .conflicts = getValueArrayStr(name, "conflicts"), + .authors = getValueArrayStr(name, "authors"), + .build_steps = getValueArrayStr(name, "build-steps"), + .prefixes = getValueArrayStr(name, "prefixes") }; } diff --git a/cufetchpm/src/pluginManager.cpp b/cufetchpm/src/pluginManager.cpp index cb6177ca..5f41759b 100644 --- a/cufetchpm/src/pluginManager.cpp +++ b/cufetchpm/src/pluginManager.cpp @@ -1,4 +1,5 @@ #include "pluginManager.hpp" + #include <cstdio> #include <cstdlib> #include <filesystem> @@ -7,25 +8,21 @@ #include <string_view> #include <vector> -#include "tiny-process-library/process.hpp" #include "fmt/format.h" -#include "manifest.hpp" #include "libcufetch/common.hh" -//#include "fmt/ranges.h" +#include "manifest.hpp" +#include "tiny-process-library/process.hpp" +// #include "fmt/ranges.h" using namespace TinyProcessLib; -std::random_device rd; -std::mt19937 gen(rd()); -std::uniform_int_distribution<> dist(0, 999999); - bool PluginManager::has_deps() { for (const std::string_view bin : dependencies) { Process proc(fmt::format("command -v {}", bin), "", - [](const char*, size_t) {}, // discard stdout + [](const char*, size_t) {}, // discard stdout [](const char*, size_t) {}); // discard stderr if (proc.get_exit_status() != 0) return false; @@ -37,7 +34,7 @@ bool PluginManager::has_deps() void PluginManager::add_repo_plugins(const std::string& repo) { if (!has_deps()) - die("Not all dependencies have been installed. You'll need to install git"); // fmt::join(dependencies, ", ")); + die("Not all dependencies have been installed. You'll need to install git"); // fmt::join(dependencies, ", ")); std::string repo_name; { @@ -55,11 +52,15 @@ void PluginManager::add_repo_plugins(const std::string& repo) return; } + static std::random_device rd; + static std::mt19937 gen(rd()); + static std::uniform_int_distribution<> dist(100000, 999999); + const std::filesystem::path& working_dir = m_cache_path / ("plugin_" + std::to_string(dist(gen))); std::filesystem::create_directories(working_dir); status("Cloning repository '{}' at '{}'", repo, working_dir.string()); - if (Process({"git", "clone", "--recursive", repo, working_dir.string()}).get_exit_status() != 0) + if (Process({ "git", "clone", "--recursive", repo, working_dir.string() }).get_exit_status() != 0) { std::filesystem::remove_all(working_dir); die("Failed to clone at directory '{}'", working_dir.string()); @@ -70,7 +71,7 @@ void PluginManager::add_repo_plugins(const std::string& repo) CManifest manifest(MANIFEST_NAME); status("Querying all plugins declared from the manifest"); - const std::vector<manifest_t>& plugins = manifest.get_all_plugins(); + const std::vector<plugin_t>& plugins = manifest.get_all_plugins(); if (plugins.empty()) { std::filesystem::remove_all(working_dir); @@ -78,18 +79,23 @@ void PluginManager::add_repo_plugins(const std::string& repo) } success("Queried the plugins"); - for (const manifest_t& plugin : plugins) + for (const plugin_t& plugin : plugins) { status("Trying to build plugin '{}'", plugin.name); for (const std::string& bs : plugin.build_steps) { - Process process(bs, "", nullptr); - if (process.get_exit_status() != 0) - { + if (Process(bs, "").get_exit_status() != 0) + { std::filesystem::remove_all(working_dir); die("Failed to build plugin '{}' from '{}'", plugin.name, repo); } } - success("Successfully built '{}'", plugin.name); + success("Successfully built '{}' into '{}'", plugin.name, plugin.output_dir); + m_state.add_new_plugin(plugin); } + + const std::filesystem::path& new_plugin_path = (m_cache_path / repo_name); + success("Plugins Successfully built! Moving it to '{}'...", new_plugin_path.string()); + std::filesystem::create_directories(new_plugin_path); + std::filesystem::rename(working_dir, new_plugin_path); } diff --git a/cufetchpm/src/stateManager.cpp b/cufetchpm/src/stateManager.cpp index 5aae0aa8..28798711 100644 --- a/cufetchpm/src/stateManager.cpp +++ b/cufetchpm/src/stateManager.cpp @@ -1,8 +1,26 @@ +#include "stateManager.hpp" + #include <filesystem> +#include <fstream> +#include <sstream> #include "fmt/os.h" #include "libcufetch/common.hh" -#include "stateManager.hpp" + +// https://github.com/hyprwm/Hyprland/blob/2d2a5bebff72c73cd27db3b9e954b8fa2a7623e8/hyprpm/src/core/DataState.cpp#L24 +static bool writeState(const std::string& str, const std::string& to) +{ + // create temp file in a safe temp root + const std::filesystem::path& temp_state = (std::filesystem::temp_directory_path() / ".temp-state"); + std::ofstream of(temp_state, std::ios::trunc); + if (!of.good()) + return false; + + of << str; + of.close(); + + return std::filesystem::copy_file(temp_state, to, std::filesystem::copy_options::overwrite_existing); +} StateManager::StateManager() { @@ -25,7 +43,29 @@ StateManager::StateManager() die(_("Failed to parse state file at '{}':\n" "{}\n" "\t(error occurred at line {} column {})"), - m_path.string(), err.description(), - err.source().begin.line, err.source().begin.column); + m_path.string(), err.description(), err.source().begin.line, err.source().begin.column); } } + +void StateManager::add_new_plugin(const plugin_t& manifest) +{ + toml::array authors_arr, licenses_arr; + for (const std::string& str : manifest.authors) + authors_arr.push_back(str); + for (const std::string& str : manifest.licenses) + licenses_arr.push_back(str); + + toml::table plugin_state_entry{ { "description", manifest.description }, + { "authors", authors_arr }, + { "license", licenses_arr }, + { "output-dir", manifest.output_dir } }; + + // Add or replace plugin entry + m_state.insert_or_assign(manifest.name, plugin_state_entry); + + std::stringstream ss; + ss << m_state; + + if (!writeState(ss.str(), m_path)) + die("Failed to write plugin state of '{}'", manifest.name); +} From 7425e00d01da321adc661b44472f569d2d44879a Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Thu, 24 Jul 2025 22:25:37 +0200 Subject: [PATCH 116/143] cufetchpm: symlink built libraries into configDir()/plugins/<manifest.repo.name> --- cufetchpm/include/manifest.hpp | 57 ++++++++++++++++++------ cufetchpm/include/pluginManager.hpp | 7 ++- cufetchpm/src/manifest.cpp | 54 +++++++++++++---------- cufetchpm/src/pluginManager.cpp | 68 +++++++++++++++++------------ src/main.cpp | 10 ++--- 5 files changed, 123 insertions(+), 73 deletions(-) diff --git a/cufetchpm/include/manifest.hpp b/cufetchpm/include/manifest.hpp index f4dba504..fcb0d940 100644 --- a/cufetchpm/include/manifest.hpp +++ b/cufetchpm/include/manifest.hpp @@ -13,6 +13,7 @@ struct plugin_t { // The plugin name. + // It must be conform to the function is_valid_name() std::string name; // The plugin description. @@ -26,8 +27,7 @@ struct plugin_t // NOTE: it doesn't actually check if they are correct or not. std::vector<std::string> licenses; - // Which plugins can be conflicting by name / modules. - // TODO: choose if check either name or git url. + // Which plugins can be conflicting by name / modules, using the git url. std::vector<std::string> conflicts; // The plugin authors. @@ -38,34 +38,63 @@ struct plugin_t // Each command will be executed from a different shell session. std::vector<std::string> build_steps; - // A list of root modules that the plugin will be used for querying its modules + // A list of registered root modules that the plugin will be used for querying its submodules. + // For example: 'github.followers' the root module is indeed 'github' and 'followers' is the submodule. std::vector<std::string> prefixes; }; -const char* const MANIFEST_NAME = "cufetchpm.toml"; +struct manifest_t +{ + // The repository name. + // It must be conform to the function is_valid_name() + std::string name; + + // The repository git/homepage url + std::string url; + + // An array of all the plugins that are declared in the manifest + std::vector<plugin_t> plugins; +}; + +constexpr char const MANIFEST_NAME[] = "cufetchpm.toml"; class CManifest { public: CManifest(const std::string_view path); - CManifest(toml::table&& tbl) : m_tbl(std::move(tbl)) {} - CManifest(const toml::table& tbl) : m_tbl(tbl) {} + CManifest(toml::table&& tbl) : m_tbl(std::move(tbl)) { parse_manifest(); } + CManifest(const toml::table& tbl) : m_tbl(tbl) { parse_manifest(); } + + plugin_t get_plugin(const std::string_view name); - plugin_t get_plugin(const std::string_view name); - std::vector<plugin_t> get_all_plugins(); + const std::string& get_repo_name() + { return m_repo.name; } + + const std::string& get_repo_url() + { return m_repo.url; } + + const std::vector<plugin_t>& get_all_plugins() + { return m_repo.plugins; } private: - toml::table m_tbl; - bool m_is_state = true; + toml::table m_tbl; + manifest_t m_repo; + + void parse_manifest(); + + std::string getStrValue(const std::string_view name, const std::string_view key) const + { + const std::optional<std::string>& ret = m_tbl[name][key].value<std::string>(); + return ret.value_or(UNKNOWN); + } - template <typename T> - T getValue(const std::string_view name, const std::string_view value) const + std::string getStrValue(const std::string_view path) const { - const std::optional<T>& ret = m_tbl[name][value].value<T>(); + const std::optional<std::string>& ret = m_tbl.at_path(path).value<std::string>(); return ret.value_or(UNKNOWN); } - std::vector<std::string> getValueArrayStr(const std::string_view name, const std::string_view value) const + std::vector<std::string> getStrArrayValue(const std::string_view name, const std::string_view value) const { std::vector<std::string> ret; diff --git a/cufetchpm/include/pluginManager.hpp b/cufetchpm/include/pluginManager.hpp index 3195e359..c93b9459 100644 --- a/cufetchpm/include/pluginManager.hpp +++ b/cufetchpm/include/pluginManager.hpp @@ -8,7 +8,6 @@ #include <utility> #include "stateManager.hpp" -#include "toml++/toml.hpp" #include "util.hpp" constexpr std::array<std::string_view, 1> dependencies = { "git" }; // expand in the future, maybe @@ -42,9 +41,9 @@ class PluginManager bool has_deps(); private: - StateManager m_state; - const std::filesystem::path m_cache_path{ getHomeCacheDir() / "cufetchpm" / "plugins" }; - toml::table m_manifest; + StateManager m_state; + std::filesystem::path m_config_path{ getConfigDir() / "plugins" }; + std::filesystem::path m_cache_path{ getHomeCacheDir() / "cufetchpm" / "plugins" }; }; #endif diff --git a/cufetchpm/src/manifest.cpp b/cufetchpm/src/manifest.cpp index 49a0ea40..8ebdf3d1 100644 --- a/cufetchpm/src/manifest.cpp +++ b/cufetchpm/src/manifest.cpp @@ -7,13 +7,13 @@ #include "libcufetch/common.hh" #include "util.hpp" -static bool validManifestName(const std::string_view n) +static bool is_valid_name(const std::string_view n) { return std::ranges::all_of(n, [](const unsigned char c) { return (isalnum(c) || c == '-' || c == '_' || c == '='); }); } -CManifest::CManifest(const std::string_view path) : m_is_state(false) +CManifest::CManifest(const std::string_view path) { try { @@ -21,38 +21,46 @@ CManifest::CManifest(const std::string_view path) : m_is_state(false) } catch (const toml::parse_error& err) { - die(_("Failed to parse state file at '{}':\n" + die(_("Failed to parse manifest file at '{}':\n" "{}\n" "\t(error occurred at line {} column {})"), path, err.description(), err.source().begin.line, err.source().begin.column); } + + parse_manifest(); } -std::vector<plugin_t> CManifest::get_all_plugins() +void CManifest::parse_manifest() { - std::vector<plugin_t> plugins; - for (auto const& [name, _] : m_tbl) + m_repo.name = getStrValue("repository", "name"); + m_repo.url = getStrValue("repository", "url"); + if (m_repo.name == UNKNOWN) + die("Couldn't find manifest repository name"); + if (!is_valid_name(m_repo.name)) + die("Manifest repository name '{}' is invalid. Only alphanumeric and '-', '_', '=' are allowed in the name", + m_repo.name); + + for (const auto& [name, _] : m_tbl) { if (name.str() == "repository") continue; - if (!validManifestName(name.str())) + if (!is_valid_name(name.str())) { warn("Plugin '{}' has an invalid name. Only alphanumeric and '-', '_', '=' are allowed in the name", name.str()); continue; } - plugins.push_back({ .name = name.data(), - .description = getValue<std::string>(name, "description"), - .output_dir = getValue<std::string>(name, "license"), - .licenses = getValueArrayStr(name, "licenses"), - .conflicts = getValueArrayStr(name, "conflicts"), - .authors = getValueArrayStr(name, "authors"), - .build_steps = getValueArrayStr(name, "build-steps"), - .prefixes = getValueArrayStr(name, "prefixes") }); + m_repo.plugins.push_back({ .name = name.data(), + .description = getStrValue(name, "description"), + .output_dir = getStrValue(name, "output-dir"), + .licenses = getStrArrayValue(name, "licenses"), + .conflicts = getStrArrayValue(name, "conflicts"), + .authors = getStrArrayValue(name, "authors"), + .build_steps = getStrArrayValue(name, "build-steps"), + .prefixes = getStrArrayValue(name, "prefixes") }); } - return plugins; } plugin_t CManifest::get_plugin(const std::string_view name) @@ -61,11 +69,11 @@ plugin_t CManifest::get_plugin(const std::string_view name) die("Couldn't find such plugin '{}' in manifest", name); return { .name = name.data(), - .description = getValue<std::string>(name, "description"), - .output_dir = getValue<std::string>(name, "license"), - .licenses = getValueArrayStr(name, "licenses"), - .conflicts = getValueArrayStr(name, "conflicts"), - .authors = getValueArrayStr(name, "authors"), - .build_steps = getValueArrayStr(name, "build-steps"), - .prefixes = getValueArrayStr(name, "prefixes") }; + .description = getStrValue(name, "description"), + .output_dir = getStrValue(name, "output-dir"), + .licenses = getStrArrayValue(name, "licenses"), + .conflicts = getStrArrayValue(name, "conflicts"), + .authors = getStrArrayValue(name, "authors"), + .build_steps = getStrArrayValue(name, "build-steps"), + .prefixes = getStrArrayValue(name, "prefixes") }; } diff --git a/cufetchpm/src/pluginManager.cpp b/cufetchpm/src/pluginManager.cpp index 5f41759b..cfc4a579 100644 --- a/cufetchpm/src/pluginManager.cpp +++ b/cufetchpm/src/pluginManager.cpp @@ -36,50 +36,45 @@ void PluginManager::add_repo_plugins(const std::string& repo) if (!has_deps()) die("Not all dependencies have been installed. You'll need to install git"); // fmt::join(dependencies, ", ")); - std::string repo_name; - { - size_t pos = repo.rfind('/'); - if (pos == repo.npos) - die("Is the url valid? Please give us a valid repository url"); - repo_name = repo.substr(pos + 1); - if (hasEnding(repo_name, ".git")) - repo_name.erase(repo_name.length() - ".git"_len); - } - - if (std::filesystem::exists(m_cache_path / repo_name)) - { - warn("Repository '{}' already exists in '{}'", repo_name, (m_cache_path / repo_name).string()); - return; - } - static std::random_device rd; static std::mt19937 gen(rd()); static std::uniform_int_distribution<> dist(100000, 999999); + // create temponary directory const std::filesystem::path& working_dir = m_cache_path / ("plugin_" + std::to_string(dist(gen))); std::filesystem::create_directories(working_dir); + // and lets clone the repository status("Cloning repository '{}' at '{}'", repo, working_dir.string()); if (Process({ "git", "clone", "--recursive", repo, working_dir.string() }).get_exit_status() != 0) { std::filesystem::remove_all(working_dir); die("Failed to clone at directory '{}'", working_dir.string()); } - success("Successfully cloned. Changing current directory"); + success("Successfully cloned. Changing current directory to '{}'", working_dir.string()); + // cd to the working directory and parse its manifest std::filesystem::current_path(working_dir); CManifest manifest(MANIFEST_NAME); - status("Querying all plugins declared from the manifest"); - const std::vector<plugin_t>& plugins = manifest.get_all_plugins(); - if (plugins.empty()) + // though lets check if we have already installed the plugin in the cache + const std::filesystem::path& repo_path = (m_cache_path / manifest.get_repo_name()); + if (std::filesystem::exists(repo_path)) + { + warn("Repository '{}' already exists in '{}'", manifest.get_repo_name(), repo_path.string()); + return; + } + + // So we don't have any plugins in the manifest uh + if (manifest.get_all_plugins().empty()) { std::filesystem::remove_all(working_dir); - die("Looks like there are no plugins to build with '{}'", repo_name); + die("Looks like there are no plugins to build with '{}'", manifest.get_repo_name()); } - success("Queried the plugins"); - for (const plugin_t& plugin : plugins) + // build each plugin from the manifest + // and add the infos to the state.toml + for (const plugin_t& plugin : manifest.get_all_plugins()) { status("Trying to build plugin '{}'", plugin.name); for (const std::string& bs : plugin.build_steps) @@ -94,8 +89,27 @@ void PluginManager::add_repo_plugins(const std::string& repo) m_state.add_new_plugin(plugin); } - const std::filesystem::path& new_plugin_path = (m_cache_path / repo_name); - success("Plugins Successfully built! Moving it to '{}'...", new_plugin_path.string()); - std::filesystem::create_directories(new_plugin_path); - std::filesystem::rename(working_dir, new_plugin_path); + // we built all plugins. let's rename the working directory to its actual manifest name, + success("Repository plugins successfully built! Moving to '{}'...", repo_path.string()); + std::filesystem::create_directories(repo_path); + std::filesystem::rename(working_dir, repo_path); + + // and then we symlink each plugin built library from its output-dir + const std::filesystem::path& plugin_config_path = (m_config_path / manifest.get_repo_name()); + std::filesystem::create_directories(plugin_config_path); + status("Linking each built plugin to '{}'", plugin_config_path.string()); + for (const plugin_t& plugin : manifest.get_all_plugins()) + { + if (!std::filesystem::exists(plugin.output_dir)) + die("Plugin '{}' output-dir '{}' doesn't exist", plugin.name, plugin.output_dir); + for (const auto& library : std::filesystem::directory_iterator{ plugin.output_dir }) + { + if (library.is_regular_file() || library.is_symlink()) + std::filesystem::create_symlink(std::filesystem::canonical(library), + plugin_config_path / library.path().filename()); + else + error("Built library '{}' is not a regular file", library.path().string()); + } + } + success("Enjoy the new plugins from {}", manifest.get_repo_name()); } diff --git a/src/main.cpp b/src/main.cpp index 06d0650c..d7f66620 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -634,9 +634,9 @@ int main(int argc, char* argv[]) /* TODO(burntranch): track each library and unload them. */ core_plugins_start(config); - const std::filesystem::path plguinDir = configDir / "plugins"; - std::filesystem::create_directories(plguinDir); - for (const auto& entry : std::filesystem::directory_iterator{ plguinDir }) + const std::filesystem::path pluginDir = configDir / "plugins"; + std::filesystem::create_directories(pluginDir); + for (const auto& entry : std::filesystem::recursive_directory_iterator{ pluginDir }) { debug("loading plugin at {}!", entry.path().string()); @@ -644,7 +644,7 @@ int main(int argc, char* argv[]) if (!handle) { // dlerror() is pretty formatted - warn("Failed to load plugin at {}: {}", entry.path().string(), dlerror()); + warn("Failed to load plugin at '{}': {}", entry.path().string(), dlerror()); dlerror(); continue; } @@ -652,7 +652,7 @@ int main(int argc, char* argv[]) LOAD_LIB_SYMBOL(handle, void, start, void*, const ConfigBase&); if (dlerror()) { - warn("Failed to load plugin at {}: Missing function 'start'", entry.path().string()); + warn("Failed to load plugin at '{}': Missing function 'start'", entry.path().string()); dlclose(handle); continue; } From 44b1b4620172223324f2abc7d17803e1cd0c3894 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Thu, 24 Jul 2025 23:53:43 +0200 Subject: [PATCH 117/143] cufetchpm: add arguments (ultra WIP) --- cufetchpm/include/pluginManager.hpp | 3 +- cufetchpm/src/main.cpp | 71 +++++++++++++++++++++++++++++ src/main.cpp | 2 +- 3 files changed, 73 insertions(+), 3 deletions(-) diff --git a/cufetchpm/include/pluginManager.hpp b/cufetchpm/include/pluginManager.hpp index c93b9459..b4403005 100644 --- a/cufetchpm/include/pluginManager.hpp +++ b/cufetchpm/include/pluginManager.hpp @@ -1,7 +1,6 @@ #ifndef _PLUGIN_MANAGER_HPP_ #define _PLUGIN_MANAGER_HPP_ -#include <array> #include <filesystem> #include <string> #include <string_view> @@ -10,7 +9,7 @@ #include "stateManager.hpp" #include "util.hpp" -constexpr std::array<std::string_view, 1> dependencies = { "git" }; // expand in the future, maybe +constexpr std::string_view dependencies[] = { "git" }; // expand in the future, maybe #define BOLD_COLOR(x) (fmt::emphasis::bold | fmt::fg(fmt::rgb(x))) diff --git a/cufetchpm/src/main.cpp b/cufetchpm/src/main.cpp index 924a9e36..391a7f3f 100644 --- a/cufetchpm/src/main.cpp +++ b/cufetchpm/src/main.cpp @@ -1,8 +1,79 @@ +#include <getopt.h> + #include "pluginManager.hpp" #include "stateManager.hpp" +#if (!__has_include("version.h")) +#error "version.h not found, please generate it with ./scripts/generateVersion.sh" +#else +#include "version.h" +#endif + +static void version() +{ + fmt::print( + "cufetchpm {} built from branch '{}' at {} commit '{}' ({}).\n" + "Date: {}\n" + "Tag: {}\n", + VERSION, GIT_BRANCH, GIT_DIRTY, GIT_COMMIT_HASH, GIT_COMMIT_MESSAGE, GIT_COMMIT_DATE, GIT_TAG); + + // if only everyone would not return error when querying the program version :( + std::exit(EXIT_SUCCESS); +} + +static void help(int invalid_opt = false) +{ + constexpr std::string_view help( + R"(Usage: cufetchpm [OPERATION] [ARGUMENTS] [OPTIONS]... +Manage plugins for customfetch. +NOTE: the operations must be the first argument to pass + + -h, --help Print this help menu. + -V, --version Print version and other infos about the build. + +OPERATIONS: + add - Add a new plugin repository. Takes as an argument the git url to be cloned. +)"); + + fmt::print("{}", help); + fmt::print("\n"); + std::exit(invalid_opt); +} + +static bool parseargs(int argc, char* argv[]) +{ + int opt = 0; + int option_index = 0; + const char *optstring = "-Vh"; + static const struct option opts[] = { + {"version", no_argument, 0, 'V'}, + {"help", no_argument, 0, 'h'}, + + {0,0,0,0} + }; + + /* parse operation */ + optind = 0; + while ((opt = getopt_long(argc, argv, optstring, opts, &option_index)) != -1) + { + switch (opt) + { + case 0: break; + case '?': help(EXIT_FAILURE); break; + + case 'V': version(); break; + case 'h': help(); break; + default: return false; + } + } + + return true; +} int main(int argc, char* argv[]) { + if (!parseargs(argc, argv)) + return -1; + std::filesystem::create_directories({ getHomeCacheDir() / "cufetchpm" / "plugins" }); StateManager state; PluginManager man(std::move(state)); diff --git a/src/main.cpp b/src/main.cpp index d7f66620..f1aa728e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -124,7 +124,7 @@ static void help(bool invalid_opt = false) { constexpr std::string_view help( R"(Usage: customfetch [OPTIONS]... -A command-line, GUI, and Android widget system information tool (like neofetch) focused on customizability and performance. +A command-line, GUI app, and Android widget system information tool (like neofetch) focused on customizability and performance. NOTE: Boolean flags [<BOOL>] accept: "true", 1, "enable", or empty. Any other value is treated as false. From 59c57c039e0a6a770be3ec9e43ecef22bb54f2c9 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Fri, 25 Jul 2025 12:47:43 +0200 Subject: [PATCH 118/143] args: migrate GNU getopt to getopt_port --- Makefile | 9 +- cufetchpm/Makefile | 10 +- cufetchpm/src/main.cpp | 4 +- include/libs/getopt_port/getopt.h | 59 ++++++++ src/libs/getopt_port/Makefile | 14 ++ src/libs/getopt_port/getopt.c | 239 ++++++++++++++++++++++++++++++ src/main.cpp | 2 +- 7 files changed, 330 insertions(+), 7 deletions(-) create mode 100644 include/libs/getopt_port/getopt.h create mode 100644 src/libs/getopt_port/Makefile create mode 100644 src/libs/getopt_port/getopt.c diff --git a/Makefile b/Makefile index f239fdab..0f24705e 100644 --- a/Makefile +++ b/Makefile @@ -56,7 +56,7 @@ LDLIBS += $(BUILDDIR)/libfmt.a $(BUILDDIR)/libtiny-process-library.a -lcufetch CXXFLAGS ?= -mtune=generic -march=native CXXFLAGS += -flto=auto -ffat-lto-objects -fvisibility-inlines-hidden -fvisibility=hidden -Iinclude -Iinclude/libcufetch -Iinclude/libs -std=c++20 $(VARS) -DVERSION=\"$(VERSION)\" -DLOCALEDIR=\"$(LOCALEDIR)\" -DICONPREFIX=\"$(ICONPREFIX)\" -all: genver fmt toml tpl json libcufetch $(TARGET) +all: genver fmt toml tpl getopt-port json libcufetch $(TARGET) libcufetch: fmt toml ifeq ($(wildcard $(BUILDDIR)/libcufetch.so),) @@ -79,6 +79,11 @@ ifeq ($(wildcard $(BUILDDIR)/libtiny-process-library.a),) make -C src/libs/tiny-process-library BUILDDIR=$(BUILDDIR) endif +getopt-port: +ifeq ($(wildcard $(BUILDDIR)/getopt.o),) + make -C src/libs/getopt_port BUILDDIR=$(BUILDDIR) +endif + json: ifeq ($(wildcard $(BUILDDIR)/json.o),) make -C src/libs/json BUILDDIR=$(BUILDDIR) @@ -89,7 +94,7 @@ ifeq ($(wildcard include/version.h),) ./scripts/generateVersion.sh endif -$(TARGET): genver fmt toml json tpl libcufetch $(OBJ) +$(TARGET): genver fmt toml tpl getopt-port json libcufetch $(OBJ) mkdir -p $(BUILDDIR) sh ./scripts/generateVersion.sh $(CXX) -o $(BUILDDIR)/$(TARGET) $(OBJ) $(BUILDDIR)/*.o $(LDFLAGS) $(LDLIBS) diff --git a/cufetchpm/Makefile b/cufetchpm/Makefile index 6a567db3..0570921c 100644 --- a/cufetchpm/Makefile +++ b/cufetchpm/Makefile @@ -30,7 +30,7 @@ LDLIBS += $(BUILDDIR)/libfmt.a $(BUILDDIR)/libtiny-process-library.a CXXFLAGS ?= -mtune=generic -march=native CXXFLAGS += -fvisibility=hidden -I../include -I../include/libs/ -Iinclude -std=c++20 $(VARS) -DVERSION=\"$(VERSION)\" -all: fmt toml tpl $(TARGET) +all: fmt toml getopt-port tpl $(TARGET) fmt: ifeq ($(wildcard $(BUILDDIR)/libfmt.a),) @@ -44,13 +44,19 @@ ifeq ($(wildcard $(BUILDDIR)/toml.o),) make -C ../src/libs/toml++ BUILDDIR=cufetchpm/$(BUILDDIR) endif +getopt-port: +ifeq ($(wildcard $(BUILDDIR)/getopt.o),) + mkdir -p $(BUILDDIR) + make -C ../src/libs/getopt_port BUILDDIR=$(BUILDDIR) +endif + tpl: ifeq ($(wildcard $(BUILDDIR)/libtiny-process-library.a),) mkdir -p $(BUILDDIR) make -C ../src/libs/tiny-process-library BUILDDIR=cufetchpm/$(BUILDDIR) endif -$(TARGET): fmt toml tpl $(OBJ) +$(TARGET): fmt toml getopt-port tpl $(OBJ) mkdir -p $(BUILDDIR) $(CXX) $(OBJ) $(BUILDDIR)/*.o -o $(BUILDDIR)/$(TARGET) $(LDFLAGS) $(LDLIBS) diff --git a/cufetchpm/src/main.cpp b/cufetchpm/src/main.cpp index 391a7f3f..7a4cce57 100644 --- a/cufetchpm/src/main.cpp +++ b/cufetchpm/src/main.cpp @@ -1,5 +1,3 @@ -#include <getopt.h> - #include "pluginManager.hpp" #include "stateManager.hpp" #if (!__has_include("version.h")) @@ -8,6 +6,8 @@ #include "version.h" #endif +#include "getopt_port/getopt.h" + static void version() { fmt::print( diff --git a/include/libs/getopt_port/getopt.h b/include/libs/getopt_port/getopt.h new file mode 100644 index 00000000..166ab261 --- /dev/null +++ b/include/libs/getopt_port/getopt.h @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (c) 2012-2023, Kim Grasman <kim.grasman@gmail.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Kim Grasman nor the + * names of contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL KIM GRASMAN BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ + +#ifndef INCLUDED_GETOPT_PORT_H +#define INCLUDED_GETOPT_PORT_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#define no_argument 1 +#define required_argument 2 +#define optional_argument 3 + +extern char* optarg; +extern int optind, opterr, optopt; + +struct option { + const char* name; + int has_arg; + int* flag; + int val; +}; + +int getopt(int argc, char* const argv[], const char* optstring); + +int getopt_long(int argc, char* const argv[], + const char* optstring, const struct option* longopts, int* longindex); + +#if defined(__cplusplus) +} +#endif + +#endif // INCLUDED_GETOPT_PORT_H diff --git a/src/libs/getopt_port/Makefile b/src/libs/getopt_port/Makefile new file mode 100644 index 00000000..65ed3499 --- /dev/null +++ b/src/libs/getopt_port/Makefile @@ -0,0 +1,14 @@ +CC ?= cc +SRC = getopt.c +TARGET = getopt.o +CFLAGS = -I../../../include/libs -flto=auto -ffat-lto-objects -fvisibility=hidden -fPIC + +all: $(TARGET) + +$(TARGET): + $(CC) $(SRC) $(CFLAGS) -c -o ../../../$(BUILDDIR)/$@ + +clean: + rm -rf ../../../$(BUILDDIR)/getopt_port/$(TARGET) + +.PHONY: $(TARGET) clean all diff --git a/src/libs/getopt_port/getopt.c b/src/libs/getopt_port/getopt.c new file mode 100644 index 00000000..6bac813e --- /dev/null +++ b/src/libs/getopt_port/getopt.c @@ -0,0 +1,239 @@ +/******************************************************************************* + * Copyright (c) 2012-2023, Kim Grasman <kim.grasman@gmail.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Kim Grasman nor the + * names of contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL KIM GRASMAN BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ + +#include "getopt.h" + +#include <stddef.h> +#include <string.h> + +char* optarg; +int optopt; +/* The variable optind [...] shall be initialized to 1 by the system. */ +int optind = 1; +int opterr; + +static char* optcursor = NULL; + +/* Implemented based on [1] and [2] for optional arguments. + optopt is handled FreeBSD-style, per [3]. + Other GNU and FreeBSD extensions are purely accidental. + +[1] http://pubs.opengroup.org/onlinepubs/000095399/functions/getopt.html +[2] http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html +[3] http://www.freebsd.org/cgi/man.cgi?query=getopt&sektion=3&manpath=FreeBSD+9.0-RELEASE +*/ +int getopt(int argc, char* const argv[], const char* optstring) { + int optchar = -1; + const char* optdecl = NULL; + + optarg = NULL; + opterr = 0; + optopt = 0; + + /* Unspecified, but we need it to avoid overrunning the argv bounds. */ + if (optind >= argc) + goto no_more_optchars; + + /* If, when getopt() is called argv[optind] is a null pointer, getopt() + shall return -1 without changing optind. */ + if (argv[optind] == NULL) + goto no_more_optchars; + + /* If, when getopt() is called *argv[optind] is not the character '-', + getopt() shall return -1 without changing optind. */ + if (*argv[optind] != '-') + goto no_more_optchars; + + /* If, when getopt() is called argv[optind] points to the string "-", + getopt() shall return -1 without changing optind. */ + if (strcmp(argv[optind], "-") == 0) + goto no_more_optchars; + + /* If, when getopt() is called argv[optind] points to the string "--", + getopt() shall return -1 after incrementing optind. */ + if (strcmp(argv[optind], "--") == 0) { + ++optind; + goto no_more_optchars; + } + + if (optcursor == NULL || *optcursor == '\0') + optcursor = argv[optind] + 1; + + optchar = *optcursor; + + /* FreeBSD: The variable optopt saves the last known option character + returned by getopt(). */ + optopt = optchar; + + /* The getopt() function shall return the next option character (if one is + found) from argv that matches a character in optstring, if there is + one that matches. */ + optdecl = strchr(optstring, optchar); + if (optdecl) { + /* [I]f a character is followed by a colon, the option takes an + argument. */ + if (optdecl[1] == ':') { + optarg = ++optcursor; + if (*optarg == '\0') { + /* GNU extension: Two colons mean an option takes an + optional arg; if there is text in the current argv-element + (i.e., in the same word as the option name itself, for example, + "-oarg"), then it is returned in optarg, otherwise optarg is set + to zero. */ + if (optdecl[2] != ':') { + /* If the option was the last character in the string pointed to by + an element of argv, then optarg shall contain the next element + of argv, and optind shall be incremented by 2. If the resulting + value of optind is greater than argc, this indicates a missing + option-argument, and getopt() shall return an error indication. + + Otherwise, optarg shall point to the string following the + option character in that element of argv, and optind shall be + incremented by 1. + */ + if (++optind < argc) { + optarg = argv[optind]; + } else { + /* If it detects a missing option-argument, it shall return the + colon character ( ':' ) if the first character of optstring + was a colon, or a question-mark character ( '?' ) otherwise. + */ + optarg = NULL; + optchar = (optstring[0] == ':') ? ':' : '?'; + } + } else { + optarg = NULL; + } + } + + optcursor = NULL; + } + } else { + /* If getopt() encounters an option character that is not contained in + optstring, it shall return the question-mark ( '?' ) character. */ + optchar = '?'; + } + + if (optcursor == NULL || *++optcursor == '\0') + ++optind; + + return optchar; + +no_more_optchars: + optcursor = NULL; + return -1; +} + +/* Implementation based on [1]. + +[1] http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html +*/ +int getopt_long(int argc, char* const argv[], const char* optstring, + const struct option* longopts, int* longindex) { + const struct option* o = longopts; + const struct option* match = NULL; + int num_matches = 0; + size_t argument_name_length = 0; + size_t option_length = 0; + const char* current_argument = NULL; + int retval = -1; + + optarg = NULL; + optopt = 0; + + if (optind >= argc) + return -1; + + if (strlen(argv[optind]) < 3 || strncmp(argv[optind], "--", 2) != 0) + return getopt(argc, argv, optstring); + + /* It's an option; starts with -- and is longer than two chars. */ + current_argument = argv[optind] + 2; + argument_name_length = strcspn(current_argument, "="); + for (; o->name; ++o) { + /* Check for exact match first. */ + option_length = strlen(o->name); + if (option_length == argument_name_length && + strncmp(o->name, current_argument, option_length) == 0) { + match = o; + num_matches = 1; + break; + } + + /* If not exact, count the number of abbreviated matches. */ + if (strncmp(o->name, current_argument, argument_name_length) == 0) { + match = o; + ++num_matches; + } + } + + if (num_matches == 1) { + /* If longindex is not NULL, it points to a variable which is set to the + index of the long option relative to longopts. */ + if (longindex) + *longindex = (int)(match - longopts); + + /* If flag is NULL, then getopt_long() shall return val. + Otherwise, getopt_long() returns 0, and flag shall point to a variable + which shall be set to val if the option is found, but left unchanged if + the option is not found. */ + if (match->flag) + *(match->flag) = match->val; + + retval = match->flag ? 0 : match->val; + + if (match->has_arg != no_argument) { + optarg = strchr(argv[optind], '='); + if (optarg != NULL) + ++optarg; + + if (match->has_arg == required_argument) { + /* Only scan the next argv for required arguments. Behavior is not + specified, but has been observed with Ubuntu and Mac OSX. */ + if (optarg == NULL && ++optind < argc) { + optarg = argv[optind]; + } + + if (optarg == NULL) + retval = ':'; + } + } else if (strchr(argv[optind], '=')) { + /* An argument was provided to a non-argument option. + I haven't seen this specified explicitly, but both GNU and BSD-based + implementations show this behavior. + */ + retval = '?'; + } + } else { + /* Unknown option or ambiguous match. */ + retval = '?'; + } + + ++optind; + return retval; +} diff --git a/src/main.cpp b/src/main.cpp index f1aa728e..ee1deb92 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -24,7 +24,6 @@ */ #include <dlfcn.h> -#include <getopt.h> #include <stdlib.h> #include <termios.h> #include <unistd.h> @@ -38,6 +37,7 @@ #include <thread> #include <vector> +#include "getopt_port/getopt.h" #include "core-modules.hh" #include "display.hpp" #include "fmt/base.h" From c724d912a82ecff38ccd901840e94e32ed33789d Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Fri, 25 Jul 2025 13:20:33 +0200 Subject: [PATCH 119/143] args: fix buggy getopt_port ?? --- include/libs/getopt_port/getopt.h | 6 +++--- src/main.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/libs/getopt_port/getopt.h b/include/libs/getopt_port/getopt.h index 166ab261..ac2f991b 100644 --- a/include/libs/getopt_port/getopt.h +++ b/include/libs/getopt_port/getopt.h @@ -33,9 +33,9 @@ extern "C" { #endif -#define no_argument 1 -#define required_argument 2 -#define optional_argument 3 +#define no_argument 0 +#define required_argument 1 +#define optional_argument 2 extern char* optarg; extern int optind, opterr, optopt; diff --git a/src/main.cpp b/src/main.cpp index ee1deb92..2a3a31b9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -473,7 +473,7 @@ static bool parseargs(int argc, char* argv[], Config& config, const std::filesys }; /* parse operation */ - optind = 0; + optind = 1; while ((opt = getopt_long(argc, argv, optstring, opts, &option_index)) != -1) { switch (opt) From c8b451eeb7e274fde140025b61a17230f4bb5356 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Fri, 25 Jul 2025 14:51:46 +0200 Subject: [PATCH 120/143] cufetchpm: add more infos to the state.toml --- cufetchpm/Makefile | 2 +- cufetchpm/include/manifest.hpp | 6 ++-- cufetchpm/include/stateManager.hpp | 1 + cufetchpm/src/main.cpp | 11 ++++--- cufetchpm/src/pluginManager.cpp | 4 +-- cufetchpm/src/stateManager.cpp | 53 ++++++++++++++++++++++++++++-- 6 files changed, 65 insertions(+), 12 deletions(-) diff --git a/cufetchpm/Makefile b/cufetchpm/Makefile index 0570921c..c8ad69b3 100644 --- a/cufetchpm/Makefile +++ b/cufetchpm/Makefile @@ -47,7 +47,7 @@ endif getopt-port: ifeq ($(wildcard $(BUILDDIR)/getopt.o),) mkdir -p $(BUILDDIR) - make -C ../src/libs/getopt_port BUILDDIR=$(BUILDDIR) + make -C ../src/libs/getopt_port BUILDDIR=cufetchpm/$(BUILDDIR) endif tpl: diff --git a/cufetchpm/include/manifest.hpp b/cufetchpm/include/manifest.hpp index fcb0d940..0fed1072 100644 --- a/cufetchpm/include/manifest.hpp +++ b/cufetchpm/include/manifest.hpp @@ -67,13 +67,13 @@ class CManifest plugin_t get_plugin(const std::string_view name); - const std::string& get_repo_name() + const std::string& get_repo_name() const { return m_repo.name; } - const std::string& get_repo_url() + const std::string& get_repo_url() const { return m_repo.url; } - const std::vector<plugin_t>& get_all_plugins() + const std::vector<plugin_t>& get_all_plugins() const { return m_repo.plugins; } private: diff --git a/cufetchpm/include/stateManager.hpp b/cufetchpm/include/stateManager.hpp index eda16503..1db6c8c9 100644 --- a/cufetchpm/include/stateManager.hpp +++ b/cufetchpm/include/stateManager.hpp @@ -15,6 +15,7 @@ class StateManager StateManager(const StateManager&) = default; ~StateManager() = default; + void add_new_repo(const CManifest& manifest); void add_new_plugin(const plugin_t& manifest); toml::table get_state() { return m_state; } diff --git a/cufetchpm/src/main.cpp b/cufetchpm/src/main.cpp index 7a4cce57..d0ae689c 100644 --- a/cufetchpm/src/main.cpp +++ b/cufetchpm/src/main.cpp @@ -27,11 +27,13 @@ static void help(int invalid_opt = false) Manage plugins for customfetch. NOTE: the operations must be the first argument to pass +OPERATIONS: + add - Add a new plugin repository. Takes as an argument the git url to be cloned. + +GENERAL OPTIONS -h, --help Print this help menu. -V, --version Print version and other infos about the build. -OPERATIONS: - add - Add a new plugin repository. Takes as an argument the git url to be cloned. )"); fmt::print("{}", help); @@ -41,6 +43,7 @@ NOTE: the operations must be the first argument to pass static bool parseargs(int argc, char* argv[]) { + // clang-format off int opt = 0; int option_index = 0; const char *optstring = "-Vh"; @@ -51,8 +54,8 @@ static bool parseargs(int argc, char* argv[]) {0,0,0,0} }; - /* parse operation */ - optind = 0; + // clang-format on + optind = 1; while ((opt = getopt_long(argc, argv, optstring, opts, &option_index)) != -1) { switch (opt) diff --git a/cufetchpm/src/pluginManager.cpp b/cufetchpm/src/pluginManager.cpp index cfc4a579..2eced668 100644 --- a/cufetchpm/src/pluginManager.cpp +++ b/cufetchpm/src/pluginManager.cpp @@ -38,7 +38,7 @@ void PluginManager::add_repo_plugins(const std::string& repo) static std::random_device rd; static std::mt19937 gen(rd()); - static std::uniform_int_distribution<> dist(100000, 999999); + static std::uniform_int_distribution<> dist(0, 999999); // create temponary directory const std::filesystem::path& working_dir = m_cache_path / ("plugin_" + std::to_string(dist(gen))); @@ -86,8 +86,8 @@ void PluginManager::add_repo_plugins(const std::string& repo) } } success("Successfully built '{}' into '{}'", plugin.name, plugin.output_dir); - m_state.add_new_plugin(plugin); } + m_state.add_new_repo(manifest); // we built all plugins. let's rename the working directory to its actual manifest name, success("Repository plugins successfully built! Moving to '{}'...", repo_path.string()); diff --git a/cufetchpm/src/stateManager.cpp b/cufetchpm/src/stateManager.cpp index 28798711..60e8d6f6 100644 --- a/cufetchpm/src/stateManager.cpp +++ b/cufetchpm/src/stateManager.cpp @@ -3,9 +3,11 @@ #include <filesystem> #include <fstream> #include <sstream> +#include <utility> #include "fmt/os.h" #include "libcufetch/common.hh" +#include "manifest.hpp" // https://github.com/hyprwm/Hyprland/blob/2d2a5bebff72c73cd27db3b9e954b8fa2a7623e8/hyprpm/src/core/DataState.cpp#L24 static bool writeState(const std::string& str, const std::string& to) @@ -22,6 +24,25 @@ static bool writeState(const std::string& str, const std::string& to) return std::filesystem::copy_file(temp_state, to, std::filesystem::copy_options::overwrite_existing); } +// Ensures a sub-table exists for a given key. Returns a reference to the sub-table. +static toml::table& ensure_table(toml::table& parent, std::string_view key) +{ + if (toml::node* node = parent[key].node()) + if (auto* tbl = node->as_table()) + return *tbl; + + auto [it, inserted] = parent.insert(key, toml::table{}); + return *it->second.as_table(); +} + +static toml::array vector_to_array(const std::vector<std::string> vec) +{ + toml::array ret; + for (const std::string& str : vec) + ret.push_back(str); + return ret; +} + StateManager::StateManager() { if (!std::filesystem::exists(m_path)) @@ -47,6 +68,34 @@ StateManager::StateManager() } } +void StateManager::add_new_repo(const CManifest& manifest) +{ + toml::table& repositories = ensure_table(m_state, "repositories"); + toml::table& repo = ensure_table(repositories, manifest.get_repo_name()); + repo.insert_or_assign("url", manifest.get_repo_url()); + + toml::array plugins_arr; + for (const plugin_t& plugin : manifest.get_all_plugins()) + { + toml::table entry{ { "name", plugin.name }, + { "description", plugin.description }, + { "authors", vector_to_array(plugin.authors) }, + { "licenses", vector_to_array(plugin.licenses) }, + { "output-dir", plugin.output_dir }, + { "conflicts", vector_to_array(plugin.conflicts) }, + { "prefixes", vector_to_array(plugin.prefixes) } }; + + plugins_arr.push_back(std::move(entry)); + } + + repo.insert_or_assign("plugins", std::move(plugins_arr)); + std::stringstream ss; + ss << m_state; + + if (!writeState(ss.str(), m_path)) + die("Failed to write plugin state of repository '{}'", manifest.get_repo_name()); +} + void StateManager::add_new_plugin(const plugin_t& manifest) { toml::array authors_arr, licenses_arr; @@ -57,11 +106,11 @@ void StateManager::add_new_plugin(const plugin_t& manifest) toml::table plugin_state_entry{ { "description", manifest.description }, { "authors", authors_arr }, - { "license", licenses_arr }, + { "licenses", licenses_arr }, { "output-dir", manifest.output_dir } }; // Add or replace plugin entry - m_state.insert_or_assign(manifest.name, plugin_state_entry); + m_state.insert_or_assign(manifest.name, std::move(plugin_state_entry)); std::stringstream ss; ss << m_state; From 767080e1680389c663269eddfaa4f469c1a2fb3c Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Fri, 25 Jul 2025 16:49:46 +0200 Subject: [PATCH 121/143] cufetchpm: ask to overwrite existing plugin in config dir chore: rename std::filesystem -> fs --- cufetchpm/include/pluginManager.hpp | 6 ++-- cufetchpm/include/stateManager.hpp | 4 ++- cufetchpm/src/main.cpp | 2 +- cufetchpm/src/pluginManager.cpp | 52 +++++++++++++++++------------ cufetchpm/src/stateManager.cpp | 20 +++++------ 5 files changed, 48 insertions(+), 36 deletions(-) diff --git a/cufetchpm/include/pluginManager.hpp b/cufetchpm/include/pluginManager.hpp index b4403005..cd77dee6 100644 --- a/cufetchpm/include/pluginManager.hpp +++ b/cufetchpm/include/pluginManager.hpp @@ -9,6 +9,8 @@ #include "stateManager.hpp" #include "util.hpp" +namespace fs = std::filesystem; + constexpr std::string_view dependencies[] = { "git" }; // expand in the future, maybe #define BOLD_COLOR(x) (fmt::emphasis::bold | fmt::fg(fmt::rgb(x))) @@ -41,8 +43,8 @@ class PluginManager private: StateManager m_state; - std::filesystem::path m_config_path{ getConfigDir() / "plugins" }; - std::filesystem::path m_cache_path{ getHomeCacheDir() / "cufetchpm" / "plugins" }; + fs::path m_config_path{ getConfigDir() / "plugins" }; + fs::path m_cache_path{ getHomeCacheDir() / "cufetchpm" / "plugins" }; }; #endif diff --git a/cufetchpm/include/stateManager.hpp b/cufetchpm/include/stateManager.hpp index 1db6c8c9..698174d9 100644 --- a/cufetchpm/include/stateManager.hpp +++ b/cufetchpm/include/stateManager.hpp @@ -7,6 +7,8 @@ #include "toml++/toml.hpp" #include "util.hpp" +namespace fs = std::filesystem; + class StateManager { public: @@ -20,7 +22,7 @@ class StateManager toml::table get_state() { return m_state; } private: - const std::filesystem::path m_path{ getHomeCacheDir() / "cufetchpm" / "state.toml" }; + const fs::path m_path{ getHomeCacheDir() / "cufetchpm" / "state.toml" }; toml::table m_state; }; diff --git a/cufetchpm/src/main.cpp b/cufetchpm/src/main.cpp index d0ae689c..a38651c2 100644 --- a/cufetchpm/src/main.cpp +++ b/cufetchpm/src/main.cpp @@ -77,7 +77,7 @@ int main(int argc, char* argv[]) if (!parseargs(argc, argv)) return -1; - std::filesystem::create_directories({ getHomeCacheDir() / "cufetchpm" / "plugins" }); + fs::create_directories({ getHomeCacheDir() / "cufetchpm" / "plugins" }); StateManager state; PluginManager man(std::move(state)); man.add_repo_plugins(argv[2]); diff --git a/cufetchpm/src/pluginManager.cpp b/cufetchpm/src/pluginManager.cpp index 2eced668..f60d8ca3 100644 --- a/cufetchpm/src/pluginManager.cpp +++ b/cufetchpm/src/pluginManager.cpp @@ -12,6 +12,7 @@ #include "libcufetch/common.hh" #include "manifest.hpp" #include "tiny-process-library/process.hpp" +#include "util.hpp" // #include "fmt/ranges.h" using namespace TinyProcessLib; @@ -20,10 +21,9 @@ bool PluginManager::has_deps() { for (const std::string_view bin : dependencies) { - Process proc(fmt::format("command -v {}", bin), - "", - [](const char*, size_t) {}, // discard stdout - [](const char*, size_t) {}); // discard stderr + Process proc( + fmt::format("command -v {}", bin), "", [](const char*, size_t) {}, // discard stdout + [](const char*, size_t) {}); // discard stderr if (proc.get_exit_status() != 0) return false; } @@ -41,34 +41,35 @@ void PluginManager::add_repo_plugins(const std::string& repo) static std::uniform_int_distribution<> dist(0, 999999); // create temponary directory - const std::filesystem::path& working_dir = m_cache_path / ("plugin_" + std::to_string(dist(gen))); - std::filesystem::create_directories(working_dir); + const fs::path& working_dir = m_cache_path / ("plugin_" + std::to_string(dist(gen))); + fs::create_directories(working_dir); // and lets clone the repository status("Cloning repository '{}' at '{}'", repo, working_dir.string()); if (Process({ "git", "clone", "--recursive", repo, working_dir.string() }).get_exit_status() != 0) { - std::filesystem::remove_all(working_dir); + fs::remove_all(working_dir); die("Failed to clone at directory '{}'", working_dir.string()); } success("Successfully cloned. Changing current directory to '{}'", working_dir.string()); // cd to the working directory and parse its manifest - std::filesystem::current_path(working_dir); + fs::current_path(working_dir); CManifest manifest(MANIFEST_NAME); // though lets check if we have already installed the plugin in the cache - const std::filesystem::path& repo_path = (m_cache_path / manifest.get_repo_name()); - if (std::filesystem::exists(repo_path)) + const fs::path& repo_cache_path = (m_cache_path / manifest.get_repo_name()); + const fs::path& plugin_config_path = (m_config_path / manifest.get_repo_name()); + if (fs::exists(repo_cache_path)) { - warn("Repository '{}' already exists in '{}'", manifest.get_repo_name(), repo_path.string()); + warn("Repository '{}' already exists in '{}'", manifest.get_repo_name(), repo_cache_path.string()); return; } // So we don't have any plugins in the manifest uh if (manifest.get_all_plugins().empty()) { - std::filesystem::remove_all(working_dir); + fs::remove_all(working_dir); die("Looks like there are no plugins to build with '{}'", manifest.get_repo_name()); } @@ -81,7 +82,7 @@ void PluginManager::add_repo_plugins(const std::string& repo) { if (Process(bs, "").get_exit_status() != 0) { - std::filesystem::remove_all(working_dir); + fs::remove_all(working_dir); die("Failed to build plugin '{}' from '{}'", plugin.name, repo); } } @@ -90,23 +91,30 @@ void PluginManager::add_repo_plugins(const std::string& repo) m_state.add_new_repo(manifest); // we built all plugins. let's rename the working directory to its actual manifest name, - success("Repository plugins successfully built! Moving to '{}'...", repo_path.string()); - std::filesystem::create_directories(repo_path); - std::filesystem::rename(working_dir, repo_path); + success("Repository plugins successfully built! Moving to '{}'...", repo_cache_path.string()); + fs::create_directories(repo_cache_path); + fs::rename(working_dir, repo_cache_path); // and then we symlink each plugin built library from its output-dir - const std::filesystem::path& plugin_config_path = (m_config_path / manifest.get_repo_name()); - std::filesystem::create_directories(plugin_config_path); + fs::create_directories(plugin_config_path); status("Linking each built plugin to '{}'", plugin_config_path.string()); for (const plugin_t& plugin : manifest.get_all_plugins()) { - if (!std::filesystem::exists(plugin.output_dir)) + if (!fs::exists(plugin.output_dir)) die("Plugin '{}' output-dir '{}' doesn't exist", plugin.name, plugin.output_dir); - for (const auto& library : std::filesystem::directory_iterator{ plugin.output_dir }) + for (const auto& library : fs::directory_iterator{ plugin.output_dir }) { + const fs::path& library_config_path = plugin_config_path / library.path().filename(); + if (fs::exists(library_config_path)) + { + if (askUserYorN(false, "Library plugin '{}' already exists. Replace it?", library_config_path.string())) + fs::remove_all(library_config_path); + else + continue; + } + if (library.is_regular_file() || library.is_symlink()) - std::filesystem::create_symlink(std::filesystem::canonical(library), - plugin_config_path / library.path().filename()); + fs::create_symlink(fs::canonical(library), library_config_path); else error("Built library '{}' is not a regular file", library.path().string()); } diff --git a/cufetchpm/src/stateManager.cpp b/cufetchpm/src/stateManager.cpp index 60e8d6f6..3c67bd32 100644 --- a/cufetchpm/src/stateManager.cpp +++ b/cufetchpm/src/stateManager.cpp @@ -13,15 +13,15 @@ static bool writeState(const std::string& str, const std::string& to) { // create temp file in a safe temp root - const std::filesystem::path& temp_state = (std::filesystem::temp_directory_path() / ".temp-state"); - std::ofstream of(temp_state, std::ios::trunc); + const fs::path& temp_state = (fs::temp_directory_path() / ".temp-state"); + std::ofstream of(temp_state, std::ios::trunc); if (!of.good()) return false; of << str; of.close(); - return std::filesystem::copy_file(temp_state, to, std::filesystem::copy_options::overwrite_existing); + return fs::copy_file(temp_state, to, fs::copy_options::overwrite_existing); } // Ensures a sub-table exists for a given key. Returns a reference to the sub-table. @@ -45,7 +45,7 @@ static toml::array vector_to_array(const std::vector<std::string> vec) StateManager::StateManager() { - if (!std::filesystem::exists(m_path)) + if (!fs::exists(m_path)) { auto f = fmt::output_file(m_path.string(), fmt::file::WRONLY | fmt::file::TRUNC | fmt::file::CREATE); f.print(R"(# AUTOGENERATED FILE. DO NOT EDIT THIS FILE. @@ -78,12 +78,12 @@ void StateManager::add_new_repo(const CManifest& manifest) for (const plugin_t& plugin : manifest.get_all_plugins()) { toml::table entry{ { "name", plugin.name }, - { "description", plugin.description }, - { "authors", vector_to_array(plugin.authors) }, - { "licenses", vector_to_array(plugin.licenses) }, - { "output-dir", plugin.output_dir }, - { "conflicts", vector_to_array(plugin.conflicts) }, - { "prefixes", vector_to_array(plugin.prefixes) } }; + { "description", plugin.description }, + { "authors", vector_to_array(plugin.authors) }, + { "licenses", vector_to_array(plugin.licenses) }, + { "output-dir", plugin.output_dir }, + { "conflicts", vector_to_array(plugin.conflicts) }, + { "prefixes", vector_to_array(plugin.prefixes) } }; plugins_arr.push_back(std::move(entry)); } From cdf4b5e0175680dc2bc077cce53f38cd84e191b7 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Fri, 25 Jul 2025 18:46:49 +0200 Subject: [PATCH 122/143] cufetchpm: add "functional" install arg --- cufetchpm/src/main.cpp | 58 +++++++++++++++++++++++++++++++-- cufetchpm/src/pluginManager.cpp | 1 + 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/cufetchpm/src/main.cpp b/cufetchpm/src/main.cpp index a38651c2..84ec2e1a 100644 --- a/cufetchpm/src/main.cpp +++ b/cufetchpm/src/main.cpp @@ -1,5 +1,9 @@ +#include <cstring> +#include "libcufetch/common.hh" +#include "libs/switch_fnv1a.hpp" #include "pluginManager.hpp" #include "stateManager.hpp" + #if (!__has_include("version.h")) #error "version.h not found, please generate it with ./scripts/generateVersion.sh" #else @@ -8,6 +12,18 @@ #include "getopt_port/getopt.h" +enum { + INSTALL, + REMOVE, + LIST +}; + +static struct operations_t +{ + int name; + std::vector<std::string> args; +} op; + static void version() { fmt::print( @@ -28,7 +44,7 @@ Manage plugins for customfetch. NOTE: the operations must be the first argument to pass OPERATIONS: - add - Add a new plugin repository. Takes as an argument the git url to be cloned. + install - Install a new plugin repository. Takes as an argument the git url to be cloned. GENERAL OPTIONS -h, --help Print this help menu. @@ -56,6 +72,28 @@ static bool parseargs(int argc, char* argv[]) // clang-format on optind = 1; + for (int i = 1; i < argc; ++i) + { + if (strncmp(argv[i], "install", 7) == 0 || strncmp(argv[i], "i", 1) == 0) + { + op.name = INSTALL; + optind++; + break; + } + if (strncmp(argv[i], "list", 4) == 0|| strncmp(argv[i], "l", 1) == 0) + { + op.name = LIST; + optind++; + break; + } + if (strncmp(argv[i], "remove", 6) == 0 || strncmp(argv[i], "r", 1) == 0) + { + op.name = REMOVE; + optind++; + break; + } + } + while ((opt = getopt_long(argc, argv, optstring, opts, &option_index)) != -1) { switch (opt) @@ -69,6 +107,9 @@ static bool parseargs(int argc, char* argv[]) } } + for (int i = optind; i < argc; ++i) + op.args.push_back(argv[i]); + return true; } @@ -79,7 +120,18 @@ int main(int argc, char* argv[]) fs::create_directories({ getHomeCacheDir() / "cufetchpm" / "plugins" }); StateManager state; - PluginManager man(std::move(state)); - man.add_repo_plugins(argv[2]); + PluginManager plugin_manager(std::move(state)); + switch (op.name) + { + case INSTALL: + { + if (op.args.size() != 1) + die("Please provide a singular git url repository"); + plugin_manager.add_repo_plugins(op.args[0]); break; + } + default: + warn("Not yet implemented"); + } + return 0; } diff --git a/cufetchpm/src/pluginManager.cpp b/cufetchpm/src/pluginManager.cpp index f60d8ca3..5e6a92cb 100644 --- a/cufetchpm/src/pluginManager.cpp +++ b/cufetchpm/src/pluginManager.cpp @@ -63,6 +63,7 @@ void PluginManager::add_repo_plugins(const std::string& repo) if (fs::exists(repo_cache_path)) { warn("Repository '{}' already exists in '{}'", manifest.get_repo_name(), repo_cache_path.string()); + fs::remove_all(working_dir); return; } From abaab30b4dd261770e26c83ba69e24fc32c4d8d3 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Sat, 26 Jul 2025 01:44:44 +0200 Subject: [PATCH 123/143] cufetchpm: move state.toml to the config directory plugins: only load plugins that have a supported OS library extension --- cufetchpm/include/manifest.hpp | 4 +-- cufetchpm/include/pluginManager.hpp | 6 ++-- cufetchpm/include/stateManager.hpp | 4 +-- cufetchpm/src/main.cpp | 51 ++++++++++++++++------------- cufetchpm/src/stateManager.cpp | 19 ++++++----- include/util.hpp | 8 +++++ src/main.cpp | 3 ++ 7 files changed, 57 insertions(+), 38 deletions(-) diff --git a/cufetchpm/include/manifest.hpp b/cufetchpm/include/manifest.hpp index 0fed1072..04805c57 100644 --- a/cufetchpm/include/manifest.hpp +++ b/cufetchpm/include/manifest.hpp @@ -77,8 +77,8 @@ class CManifest { return m_repo.plugins; } private: - toml::table m_tbl; - manifest_t m_repo; + toml::table m_tbl; + manifest_t m_repo; void parse_manifest(); diff --git a/cufetchpm/include/pluginManager.hpp b/cufetchpm/include/pluginManager.hpp index cd77dee6..a5d0adab 100644 --- a/cufetchpm/include/pluginManager.hpp +++ b/cufetchpm/include/pluginManager.hpp @@ -42,9 +42,9 @@ class PluginManager bool has_deps(); private: - StateManager m_state; - fs::path m_config_path{ getConfigDir() / "plugins" }; - fs::path m_cache_path{ getHomeCacheDir() / "cufetchpm" / "plugins" }; + StateManager m_state; + fs::path m_config_path{ getConfigDir() / "plugins" }; + fs::path m_cache_path{ getHomeCacheDir() / "cufetchpm" / "plugins" }; }; #endif diff --git a/cufetchpm/include/stateManager.hpp b/cufetchpm/include/stateManager.hpp index 698174d9..8635fe0d 100644 --- a/cufetchpm/include/stateManager.hpp +++ b/cufetchpm/include/stateManager.hpp @@ -22,8 +22,8 @@ class StateManager toml::table get_state() { return m_state; } private: - const fs::path m_path{ getHomeCacheDir() / "cufetchpm" / "state.toml" }; - toml::table m_state; + const fs::path m_path{ getConfigDir() / "plugins" / "state.toml" }; + toml::table m_state; }; #endif diff --git a/cufetchpm/src/main.cpp b/cufetchpm/src/main.cpp index 84ec2e1a..34ffa644 100644 --- a/cufetchpm/src/main.cpp +++ b/cufetchpm/src/main.cpp @@ -1,6 +1,6 @@ #include <cstring> + #include "libcufetch/common.hh" -#include "libs/switch_fnv1a.hpp" #include "pluginManager.hpp" #include "stateManager.hpp" @@ -12,17 +12,18 @@ #include "getopt_port/getopt.h" -enum { +static int op = 0; +enum +{ INSTALL, REMOVE, LIST }; -static struct operations_t +static struct operations_install_t { - int name; std::vector<std::string> args; -} op; +} install_op; static void version() { @@ -44,7 +45,7 @@ Manage plugins for customfetch. NOTE: the operations must be the first argument to pass OPERATIONS: - install - Install a new plugin repository. Takes as an argument the git url to be cloned. + install - Install a new plugin repository. Takes as an argument the git url to be cloned. GENERAL OPTIONS -h, --help Print this help menu. @@ -76,19 +77,19 @@ static bool parseargs(int argc, char* argv[]) { if (strncmp(argv[i], "install", 7) == 0 || strncmp(argv[i], "i", 1) == 0) { - op.name = INSTALL; + op = INSTALL; optind++; break; } - if (strncmp(argv[i], "list", 4) == 0|| strncmp(argv[i], "l", 1) == 0) + if (strncmp(argv[i], "list", 4) == 0 || strncmp(argv[i], "l", 1) == 0) { - op.name = LIST; + op = LIST; optind++; break; } if (strncmp(argv[i], "remove", 6) == 0 || strncmp(argv[i], "r", 1) == 0) { - op.name = REMOVE; + op = REMOVE; optind++; break; } @@ -107,8 +108,12 @@ static bool parseargs(int argc, char* argv[]) } } - for (int i = optind; i < argc; ++i) - op.args.push_back(argv[i]); + switch (op) + { + case INSTALL: + for (int i = optind; i < argc; ++i) + install_op.args.push_back(argv[i]); + } return true; } @@ -119,18 +124,18 @@ int main(int argc, char* argv[]) return -1; fs::create_directories({ getHomeCacheDir() / "cufetchpm" / "plugins" }); - StateManager state; - PluginManager plugin_manager(std::move(state)); - switch (op.name) + switch (op) { - case INSTALL: - { - if (op.args.size() != 1) - die("Please provide a singular git url repository"); - plugin_manager.add_repo_plugins(op.args[0]); break; - } - default: - warn("Not yet implemented"); + case INSTALL: + { + if (install_op.args.size() != 1) + die("Please provide a singular git url repository"); + StateManager state; + PluginManager plugin_manager(std::move(state)); + plugin_manager.add_repo_plugins(install_op.args[0]); + break; + } + default: warn("Not yet implemented"); } return 0; diff --git a/cufetchpm/src/stateManager.cpp b/cufetchpm/src/stateManager.cpp index 3c67bd32..8007d816 100644 --- a/cufetchpm/src/stateManager.cpp +++ b/cufetchpm/src/stateManager.cpp @@ -35,7 +35,7 @@ static toml::table& ensure_table(toml::table& parent, std::string_view key) return *it->second.as_table(); } -static toml::array vector_to_array(const std::vector<std::string> vec) +static toml::array vector_to_array(const std::vector<std::string>& vec) { toml::array ret; for (const std::string& str : vec) @@ -48,7 +48,7 @@ StateManager::StateManager() if (!fs::exists(m_path)) { auto f = fmt::output_file(m_path.string(), fmt::file::WRONLY | fmt::file::TRUNC | fmt::file::CREATE); - f.print(R"(# AUTOGENERATED FILE. DO NOT EDIT THIS FILE. + f.print(R"(# AUTO-GENERATED FILE. DO NOT EDIT THIS FILE. # YOU GONNA MESS SHIT UP. unless you know what you doing ofc )"); f.close(); @@ -77,19 +77,22 @@ void StateManager::add_new_repo(const CManifest& manifest) toml::array plugins_arr; for (const plugin_t& plugin : manifest.get_all_plugins()) { - toml::table entry{ { "name", plugin.name }, + // will be inserted in alphabetical order + toml::table entry{ { "name", plugin.name }, { "description", plugin.description }, - { "authors", vector_to_array(plugin.authors) }, - { "licenses", vector_to_array(plugin.licenses) }, - { "output-dir", plugin.output_dir }, - { "conflicts", vector_to_array(plugin.conflicts) }, - { "prefixes", vector_to_array(plugin.prefixes) } }; + { "output-dir", plugin.output_dir }, + { "authors", vector_to_array(plugin.authors) }, + { "licenses", vector_to_array(plugin.licenses) }, + { "conflicts", vector_to_array(plugin.conflicts) }, + { "prefixes", vector_to_array(plugin.prefixes) } }; plugins_arr.push_back(std::move(entry)); } repo.insert_or_assign("plugins", std::move(plugins_arr)); std::stringstream ss; + ss << R"(# AUTO-GENERATED FILE. DO NOT EDIT THIS FILE. + # YOU GONNA MESS SHIT UP. unless you know what you doing ofc")"; ss << m_state; if (!writeState(ss.str(), m_path)) diff --git a/include/util.hpp b/include/util.hpp index 97d16a30..221e2db6 100644 --- a/include/util.hpp +++ b/include/util.hpp @@ -78,6 +78,14 @@ struct byte_units_t #define UNLOAD_LIBRARY(handle) dlclose(handle); +#if CF_WINDOWS + constexpr char LIBRARY_EXTENSION[] = ".dll"; +#elif CF_MACOS + constexpr char LIBRARY_EXTENSION[] = ".dylib"; +#else + constexpr char LIBRARY_EXTENSION[] = ".so"; +#endif + inline bool is_live_mode = false; /* https://stackoverflow.com/questions/874134/find-out-if-string-ends-with-another-string-in-c#874160 diff --git a/src/main.cpp b/src/main.cpp index 2a3a31b9..a345925d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -638,6 +638,9 @@ int main(int argc, char* argv[]) std::filesystem::create_directories(pluginDir); for (const auto& entry : std::filesystem::recursive_directory_iterator{ pluginDir }) { + if (entry.is_regular_file() && entry.path().has_extension() && entry.path().extension() == LIBRARY_EXTENSION){} + else {continue;} + debug("loading plugin at {}!", entry.path().string()); void* handle = LOAD_LIBRARY(std::filesystem::absolute(entry.path()).c_str()); From 0d87c43ac666f288b22816f59ba235bbdb085974 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Sat, 26 Jul 2025 15:36:29 +0200 Subject: [PATCH 124/143] cufetchpm: args: make it like the git CLI --- cufetchpm/src/main.cpp | 176 ++++++++++++++++++++++++++++++----------- 1 file changed, 129 insertions(+), 47 deletions(-) diff --git a/cufetchpm/src/main.cpp b/cufetchpm/src/main.cpp index 34ffa644..3be3149d 100644 --- a/cufetchpm/src/main.cpp +++ b/cufetchpm/src/main.cpp @@ -1,4 +1,4 @@ -#include <cstring> +#include <cstdlib> #include "libcufetch/common.hh" #include "pluginManager.hpp" @@ -12,20 +12,16 @@ #include "getopt_port/getopt.h" -static int op = 0; -enum +enum Ops { + NONE, INSTALL, - REMOVE, LIST -}; +} op = NONE; -static struct operations_install_t -{ - std::vector<std::string> args; -} install_op; +static std::vector<std::string> arguments; -static void version() +void version() { fmt::print( "cufetchpm {} built from branch '{}' at {} commit '{}' ({}).\n" @@ -37,27 +33,106 @@ static void version() std::exit(EXIT_SUCCESS); } -static void help(int invalid_opt = false) +void help(int invalid_opt = false) { - constexpr std::string_view help( - R"(Usage: cufetchpm [OPERATION] [ARGUMENTS] [OPTIONS]... + fmt::print(R"(Usage: cufetchpm <command> [options] Manage plugins for customfetch. NOTE: the operations must be the first argument to pass -OPERATIONS: - install - Install a new plugin repository. Takes as an argument the git url to be cloned. +Commands: + install [options] <repo> Install a new plugin repository. Takes as an argument the git url to be cloned. -GENERAL OPTIONS +Global options: -h, --help Print this help menu. -V, --version Print version and other infos about the build. )"); - fmt::print("{}", help); - fmt::print("\n"); std::exit(invalid_opt); } +void help_install(int invalid_opt = false) +{ + fmt::print(R"(Usage: cufetchpm install [options] <repo> + +Options: + -f, --force Force installation + -h, --help Show help for install +)"); + + std::exit(invalid_opt); +} + +void help_list(int invalid_opt = false) +{ + fmt::print(R"(Usage: cufetchpm list [options] + +Options: + -v, --verbose Show detailed info + -h, --help Show help for list +)"); + + std::exit(invalid_opt); +} + +bool parse_install_args(int argc, char* argv[]) +{ + bool force = false; + + // clang-format off + const struct option long_opts[] = { + {"force", no_argument, nullptr, 'f'}, + {"help", no_argument, nullptr, 'h'}, + {0, 0, 0, 0} + }; + // clang-format on + + int opt; + while ((opt = getopt_long(argc, argv, "-fh", long_opts, nullptr)) != -1) + { + switch (opt) + { + case 'f': force = true; break; + case 'h': help_install(EXIT_SUCCESS); break; + case '?': help_install(EXIT_FAILURE); break; + } + } + + for (int i = optind; i < argc; ++i) + arguments.emplace_back(argv[i]); + + if (arguments.empty()) + die("install: no repositories given"); + + return true; +} + +bool parse_list_args(int argc, char* argv[]) +{ + bool verbose = false; + + // clang-format off + const struct option long_opts[] = { + {"verbose", no_argument, nullptr, 'v'}, + {"help", no_argument, nullptr, 'h'}, + {0, 0, 0, 0} + }; + // clang-format on + + int opt; + while ((opt = getopt_long(argc, argv, "-vh", long_opts, nullptr)) != -1) + { + switch (opt) + { + case 'v': verbose = true; break; + case 'h': help_list(EXIT_SUCCESS); break; + case '?': help_list(EXIT_FAILURE); break; + } + } + + return true; +} + static bool parseargs(int argc, char* argv[]) { // clang-format off @@ -73,28 +148,6 @@ static bool parseargs(int argc, char* argv[]) // clang-format on optind = 1; - for (int i = 1; i < argc; ++i) - { - if (strncmp(argv[i], "install", 7) == 0 || strncmp(argv[i], "i", 1) == 0) - { - op = INSTALL; - optind++; - break; - } - if (strncmp(argv[i], "list", 4) == 0 || strncmp(argv[i], "l", 1) == 0) - { - op = LIST; - optind++; - break; - } - if (strncmp(argv[i], "remove", 6) == 0 || strncmp(argv[i], "r", 1) == 0) - { - op = REMOVE; - optind++; - break; - } - } - while ((opt = getopt_long(argc, argv, optstring, opts, &option_index)) != -1) { switch (opt) @@ -108,11 +161,40 @@ static bool parseargs(int argc, char* argv[]) } } - switch (op) + if (optind >= argc) + help(EXIT_FAILURE); // no subcommand + + std::string_view cmd = argv[optind]; + int sub_argc = argc - optind - 1; + char** sub_argv = argv + optind + 1; + if (cmd == "install" || cmd == "i") { - case INSTALL: - for (int i = optind; i < argc; ++i) - install_op.args.push_back(argv[i]); + op = INSTALL; + optind = 0; + return parse_install_args(sub_argc, sub_argv); + } + else if (cmd == "list" || cmd == "l") + { + op = LIST; + optind = 0; + return parse_list_args(sub_argc, sub_argv); + } + else if (cmd == "help") + { + if (sub_argc >= 1) + { + std::string_view target = sub_argv[0]; + if (target == "install") + help_install(); + else if (target == "list") + help_list(); + else + die("Unknown subcommand '{}'", cmd); + } + else + { + help(EXIT_FAILURE); + } } return true; @@ -128,14 +210,14 @@ int main(int argc, char* argv[]) { case INSTALL: { - if (install_op.args.size() != 1) + if (arguments.size() < 1) die("Please provide a singular git url repository"); StateManager state; PluginManager plugin_manager(std::move(state)); - plugin_manager.add_repo_plugins(install_op.args[0]); + plugin_manager.add_repo_plugins(arguments[0]); break; } - default: warn("Not yet implemented"); + default: warn("uh?"); } return 0; From f24959113df2c2029c735bdbd00c9dc4056630ea Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Sat, 26 Jul 2025 18:29:02 +0200 Subject: [PATCH 125/143] cufetchpm: support install multiple targets + add listing support --- cufetchpm/include/manifest.hpp | 30 +++++------ cufetchpm/include/pluginManager.hpp | 8 +++ cufetchpm/include/stateManager.hpp | 9 ++-- cufetchpm/src/main.cpp | 77 ++++++++++++++++++++--------- cufetchpm/src/manifest.cpp | 46 +++++++++++++++++ cufetchpm/src/pluginManager.cpp | 6 ++- cufetchpm/src/stateManager.cpp | 61 ++++++++++++++++++++--- 7 files changed, 184 insertions(+), 53 deletions(-) diff --git a/cufetchpm/include/manifest.hpp b/cufetchpm/include/manifest.hpp index 04805c57..c6825265 100644 --- a/cufetchpm/include/manifest.hpp +++ b/cufetchpm/include/manifest.hpp @@ -1,13 +1,11 @@ #ifndef _MANIFEST_HPP_ #define _MANIFEST_HPP_ -#include <optional> #include <string> #include <string_view> #include <utility> #include <vector> -#include "libcufetch/common.hh" #include "toml++/toml.hpp" struct plugin_t @@ -58,6 +56,13 @@ struct manifest_t constexpr char const MANIFEST_NAME[] = "cufetchpm.toml"; +namespace ManifestSpace { +std::string getStrValue(const toml::table& tbl, const std::string_view name, const std::string_view key); +std::string getStrValue(const toml::table& tbl, const std::string_view path); +std::vector<std::string> getStrArrayValue(const toml::table& tbl, const std::string_view name, const std::string_view value); +std::vector<std::string> getStrArrayValue(const toml::table& tbl, const std::string_view path); +} + class CManifest { public: @@ -81,34 +86,21 @@ class CManifest manifest_t m_repo; void parse_manifest(); + void parse_manifest_state(); std::string getStrValue(const std::string_view name, const std::string_view key) const { - const std::optional<std::string>& ret = m_tbl[name][key].value<std::string>(); - return ret.value_or(UNKNOWN); + return ManifestSpace::getStrValue(m_tbl, name, key); } std::string getStrValue(const std::string_view path) const { - const std::optional<std::string>& ret = m_tbl.at_path(path).value<std::string>(); - return ret.value_or(UNKNOWN); + return ManifestSpace::getStrValue(m_tbl, path); } std::vector<std::string> getStrArrayValue(const std::string_view name, const std::string_view value) const { - std::vector<std::string> ret; - - // https://stackoverflow.com/a/78266628 - if (const toml::array* array_it = m_tbl[name][value].as_array()) - { - array_it->for_each([&ret](auto&& el) { - if (const toml::value<std::string>* str_elem = el.as_string()) - ret.push_back((*str_elem)->data()); - }); - - return ret; - } - return {}; + return ManifestSpace::getStrArrayValue(m_tbl, name, value); } }; diff --git a/cufetchpm/include/pluginManager.hpp b/cufetchpm/include/pluginManager.hpp index a5d0adab..36229b7b 100644 --- a/cufetchpm/include/pluginManager.hpp +++ b/cufetchpm/include/pluginManager.hpp @@ -13,6 +13,13 @@ namespace fs = std::filesystem; constexpr std::string_view dependencies[] = { "git" }; // expand in the future, maybe +inline struct operations_t +{ + bool install_force = false; + bool list_verbose = false; + std::vector<std::string> arguments; +} options; + #define BOLD_COLOR(x) (fmt::emphasis::bold | fmt::fg(fmt::rgb(x))) template <typename... Args> @@ -38,6 +45,7 @@ class PluginManager PluginManager(StateManager&& state) : m_state(std::move(state)) {} void add_repo_plugins(const std::string& repo); + void build_plugins(const fs::path& working_dir); bool add_plugin(const std::string&); bool has_deps(); diff --git a/cufetchpm/include/stateManager.hpp b/cufetchpm/include/stateManager.hpp index 8635fe0d..3878cd90 100644 --- a/cufetchpm/include/stateManager.hpp +++ b/cufetchpm/include/stateManager.hpp @@ -17,9 +17,12 @@ class StateManager StateManager(const StateManager&) = default; ~StateManager() = default; - void add_new_repo(const CManifest& manifest); - void add_new_plugin(const plugin_t& manifest); - toml::table get_state() { return m_state; } + void add_new_repo(const CManifest& manifest); + void add_new_plugin(const plugin_t& manifest); + std::vector<manifest_t> get_all_repos(); + + const toml::table& get_state() const + { return m_state; } private: const fs::path m_path{ getConfigDir() / "plugins" / "state.toml" }; diff --git a/cufetchpm/src/main.cpp b/cufetchpm/src/main.cpp index 3be3149d..3d292bca 100644 --- a/cufetchpm/src/main.cpp +++ b/cufetchpm/src/main.cpp @@ -1,5 +1,8 @@ #include <cstdlib> +#include <filesystem> +#include "fmt/base.h" +#include "fmt/ranges.h" #include "libcufetch/common.hh" #include "pluginManager.hpp" #include "stateManager.hpp" @@ -19,8 +22,6 @@ enum Ops LIST } op = NONE; -static std::vector<std::string> arguments; - void version() { fmt::print( @@ -37,14 +38,14 @@ void help(int invalid_opt = false) { fmt::print(R"(Usage: cufetchpm <command> [options] Manage plugins for customfetch. -NOTE: the operations must be the first argument to pass Commands: - install [options] <repo> Install a new plugin repository. Takes as an argument the git url to be cloned. + install [options] <repo/path>... Install one or more plugin sources from a Git repo or local path. + help <command> Show help for a specific command. Global options: - -h, --help Print this help menu. - -V, --version Print version and other infos about the build. + -h, --help Show this help message. + -V, --version Show version and build information. )"); @@ -53,11 +54,17 @@ Global options: void help_install(int invalid_opt = false) { - fmt::print(R"(Usage: cufetchpm install [options] <repo> + fmt::print(R"(Usage: cufetchpm install [options] <repo/path>... + +Install one or more plugin sources. If a given argument exists on disk, +it is treated as a local directory. Otherwise, it is treated as a Git +repository URL and will be cloned. + +All plugins found within the source will be installed. Options: - -f, --force Force installation - -h, --help Show help for install + -f, --force Force installation, even if already installed. + -h, --help Show help for this command. )"); std::exit(invalid_opt); @@ -66,10 +73,11 @@ void help_install(int invalid_opt = false) void help_list(int invalid_opt = false) { fmt::print(R"(Usage: cufetchpm list [options] +List all installed plugins. Options: - -v, --verbose Show detailed info - -h, --help Show help for list + -v, --verbose Show detailed plugin information. + -h, --help Show help for this command. )"); std::exit(invalid_opt); @@ -77,8 +85,6 @@ void help_list(int invalid_opt = false) bool parse_install_args(int argc, char* argv[]) { - bool force = false; - // clang-format off const struct option long_opts[] = { {"force", no_argument, nullptr, 'f'}, @@ -92,25 +98,23 @@ bool parse_install_args(int argc, char* argv[]) { switch (opt) { - case 'f': force = true; break; + case 'f': options.install_force = true; break; case 'h': help_install(EXIT_SUCCESS); break; case '?': help_install(EXIT_FAILURE); break; } } for (int i = optind; i < argc; ++i) - arguments.emplace_back(argv[i]); + options.arguments.emplace_back(argv[i]); - if (arguments.empty()) - die("install: no repositories given"); + if (options.arguments.empty()) + die("install: no repositories/paths given"); return true; } bool parse_list_args(int argc, char* argv[]) { - bool verbose = false; - // clang-format off const struct option long_opts[] = { {"verbose", no_argument, nullptr, 'v'}, @@ -124,7 +128,7 @@ bool parse_list_args(int argc, char* argv[]) { switch (opt) { - case 'v': verbose = true; break; + case 'v': options.list_verbose = true; break; case 'h': help_list(EXIT_SUCCESS); break; case '?': help_list(EXIT_FAILURE); break; } @@ -206,15 +210,42 @@ int main(int argc, char* argv[]) return -1; fs::create_directories({ getHomeCacheDir() / "cufetchpm" / "plugins" }); + fs::create_directories({ getConfigDir() / "plugins" }); + StateManager state; switch (op) { case INSTALL: { - if (arguments.size() < 1) + if (options.arguments.size() < 1) die("Please provide a singular git url repository"); - StateManager state; PluginManager plugin_manager(std::move(state)); - plugin_manager.add_repo_plugins(arguments[0]); + for (const std::string& arg : options.arguments) + { + if (arg.find("://") == arg.npos && fs::exists(arg)) + plugin_manager.build_plugins(arg); + else + plugin_manager.add_repo_plugins(arg); + } + break; + } + case LIST: + { + for (const manifest_t& manifest : state.get_all_repos()) + { + fmt::println("\033[1;32mRepository:\033[0m {}", manifest.name); + fmt::println("\033[1;33mURL:\033[0m {}", manifest.url); + fmt::println("\033[1;34mPlugins:"); + for (const plugin_t& plugin : manifest.plugins) + { + fmt::println("\033[1;34m - {}\033[0m", plugin.name); + fmt::println("\t\033[1;35mDescription:\033[0m {}", plugin.description); + fmt::println("\t\033[1;36mAuthor(s):\033[0m {}", fmt::join(plugin.authors, ", ")); + fmt::println("\t\033[1;38;2;220;220;220mLicense(s):\033[0m {}", fmt::join(plugin.licenses, ", ")); + fmt::println("\t\033[1;38;2;144;238;144mPrefixe(s):\033[0m {}", fmt::join(plugin.prefixes, ", ")); + fmt::print("\n"); + } + fmt::print("\033[0m"); + } break; } default: warn("uh?"); diff --git a/cufetchpm/src/manifest.cpp b/cufetchpm/src/manifest.cpp index 8ebdf3d1..58171d89 100644 --- a/cufetchpm/src/manifest.cpp +++ b/cufetchpm/src/manifest.cpp @@ -13,6 +13,52 @@ static bool is_valid_name(const std::string_view n) [](const unsigned char c) { return (isalnum(c) || c == '-' || c == '_' || c == '='); }); } +std::string ManifestSpace::getStrValue(const toml::table& tbl, const std::string_view name, const std::string_view key) +{ + const std::optional<std::string>& ret = tbl[name][key].value<std::string>(); + return ret.value_or(UNKNOWN); +} + +std::string ManifestSpace::getStrValue(const toml::table& tbl, const std::string_view path) +{ + const std::optional<std::string>& ret = tbl.at_path(path).value<std::string>(); + return ret.value_or(UNKNOWN); +} + +std::vector<std::string> ManifestSpace::getStrArrayValue(const toml::table& tbl, const std::string_view path) +{ + std::vector<std::string> ret; + + // https://stackoverflow.com/a/78266628 + if (const toml::array* array_it = tbl.at_path(path).as_array()) + { + array_it->for_each([&ret](auto&& el) { + if (const toml::value<std::string>* str_elem = el.as_string()) + ret.push_back((*str_elem)->data()); + }); + + return ret; + } + return {}; +} + +std::vector<std::string> ManifestSpace::getStrArrayValue(const toml::table& tbl, const std::string_view name, const std::string_view value) +{ + std::vector<std::string> ret; + + // https://stackoverflow.com/a/78266628 + if (const toml::array* array_it = tbl[name][value].as_array()) + { + array_it->for_each([&ret](auto&& el) { + if (const toml::value<std::string>* str_elem = el.as_string()) + ret.push_back((*str_elem)->data()); + }); + + return ret; + } + return {}; +} + CManifest::CManifest(const std::string_view path) { try diff --git a/cufetchpm/src/pluginManager.cpp b/cufetchpm/src/pluginManager.cpp index 5e6a92cb..0e81e957 100644 --- a/cufetchpm/src/pluginManager.cpp +++ b/cufetchpm/src/pluginManager.cpp @@ -52,7 +52,11 @@ void PluginManager::add_repo_plugins(const std::string& repo) die("Failed to clone at directory '{}'", working_dir.string()); } success("Successfully cloned. Changing current directory to '{}'", working_dir.string()); + build_plugins(working_dir); +} +void PluginManager::build_plugins(const fs::path& working_dir) +{ // cd to the working directory and parse its manifest fs::current_path(working_dir); CManifest manifest(MANIFEST_NAME); @@ -84,7 +88,7 @@ void PluginManager::add_repo_plugins(const std::string& repo) if (Process(bs, "").get_exit_status() != 0) { fs::remove_all(working_dir); - die("Failed to build plugin '{}' from '{}'", plugin.name, repo); + die("Failed to build plugin '{}'", plugin.name); } } success("Successfully built '{}' into '{}'", plugin.name, plugin.output_dir); diff --git a/cufetchpm/src/stateManager.cpp b/cufetchpm/src/stateManager.cpp index 8007d816..55b41122 100644 --- a/cufetchpm/src/stateManager.cpp +++ b/cufetchpm/src/stateManager.cpp @@ -5,10 +5,13 @@ #include <sstream> #include <utility> +#include "fmt/base.h" #include "fmt/os.h" #include "libcufetch/common.hh" #include "manifest.hpp" +using namespace ManifestSpace; + // https://github.com/hyprwm/Hyprland/blob/2d2a5bebff72c73cd27db3b9e954b8fa2a7623e8/hyprpm/src/core/DataState.cpp#L24 static bool writeState(const std::string& str, const std::string& to) { @@ -78,13 +81,13 @@ void StateManager::add_new_repo(const CManifest& manifest) for (const plugin_t& plugin : manifest.get_all_plugins()) { // will be inserted in alphabetical order - toml::table entry{ { "name", plugin.name }, + toml::table entry{ { "name", plugin.name }, { "description", plugin.description }, - { "output-dir", plugin.output_dir }, - { "authors", vector_to_array(plugin.authors) }, - { "licenses", vector_to_array(plugin.licenses) }, - { "conflicts", vector_to_array(plugin.conflicts) }, - { "prefixes", vector_to_array(plugin.prefixes) } }; + { "output-dir", plugin.output_dir }, + { "authors", vector_to_array(plugin.authors) }, + { "licenses", vector_to_array(plugin.licenses) }, + { "conflicts", vector_to_array(plugin.conflicts) }, + { "prefixes", vector_to_array(plugin.prefixes) } }; plugins_arr.push_back(std::move(entry)); } @@ -92,7 +95,8 @@ void StateManager::add_new_repo(const CManifest& manifest) repo.insert_or_assign("plugins", std::move(plugins_arr)); std::stringstream ss; ss << R"(# AUTO-GENERATED FILE. DO NOT EDIT THIS FILE. - # YOU GONNA MESS SHIT UP. unless you know what you doing ofc")"; +# YOU GONNA MESS SHIT UP. unless you know what you doing ofc)"; + ss << "\n"; ss << m_state; if (!writeState(ss.str(), m_path)) @@ -121,3 +125,46 @@ void StateManager::add_new_plugin(const plugin_t& manifest) if (!writeState(ss.str(), m_path)) die("Failed to write plugin state of '{}'", manifest.name); } + +std::vector<manifest_t> StateManager::get_all_repos() +{ + std::vector<manifest_t> manifests; + + const toml::table* repositories = m_state["repositories"].as_table(); + if (!repositories) + return manifests; + + for (const auto& [repo_name, repo_node] : *repositories) + { + const toml::table* repo_tbl = repo_node.as_table(); + if (!repo_tbl) + continue; + + manifest_t manifest; + manifest.name = repo_name.str(); + manifest.url = getStrValue(*repo_tbl, "url"); + + if (const toml::array* plugins = repo_tbl->get_as<toml::array>("plugins")) + { + for (const auto& plugin_node : *plugins) + { + const toml::table* plugin_tbl = plugin_node.as_table(); + if (!plugin_tbl) + continue; + + plugin_t plugin; + plugin.name = getStrValue(*plugin_tbl, "name"); + plugin.description = getStrValue(*plugin_tbl, "description"); + plugin.output_dir = getStrValue(*plugin_tbl, "output-dir"); + plugin.authors = getStrArrayValue(*plugin_tbl, "authors"); + plugin.licenses = getStrArrayValue(*plugin_tbl, "licenses"); + + manifest.plugins.push_back(std::move(plugin)); + } + } + + manifests.push_back(std::move(manifest)); + } + + return manifests; +} From 1a5cc06b1df7722bd2ee0dd171cb87bafa14d4e8 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Mon, 28 Jul 2025 22:48:06 +0200 Subject: [PATCH 126/143] cufetchpm: args: add list --verbose --- cufetchpm/src/main.cpp | 50 ++++++++++++++++++++++----------- cufetchpm/src/manifest.cpp | 3 +- cufetchpm/src/pluginManager.cpp | 8 +++--- cufetchpm/src/stateManager.cpp | 8 +++--- 4 files changed, 43 insertions(+), 26 deletions(-) diff --git a/cufetchpm/src/main.cpp b/cufetchpm/src/main.cpp index 3d292bca..fde2600c 100644 --- a/cufetchpm/src/main.cpp +++ b/cufetchpm/src/main.cpp @@ -36,12 +36,12 @@ void version() void help(int invalid_opt = false) { - fmt::print(R"(Usage: cufetchpm <command> [options] + fmt::print(R"(Usage: cufetchpm <COMMAND> [OPTIONS]... Manage plugins for customfetch. Commands: - install [options] <repo/path>... Install one or more plugin sources from a Git repo or local path. - help <command> Show help for a specific command. + install [OPTIONS] <repo/path>... Install one or more plugin sources from a Git repo or local path. + help <COMMAND> Show help for a specific command. Global options: -h, --help Show this help message. @@ -217,11 +217,11 @@ int main(int argc, char* argv[]) case INSTALL: { if (options.arguments.size() < 1) - die("Please provide a singular git url repository"); + die("Please provide a git url repository"); PluginManager plugin_manager(std::move(state)); for (const std::string& arg : options.arguments) { - if (arg.find("://") == arg.npos && fs::exists(arg)) + if (fs::exists(arg)) plugin_manager.build_plugins(arg); else plugin_manager.add_repo_plugins(arg); @@ -230,21 +230,37 @@ int main(int argc, char* argv[]) } case LIST: { - for (const manifest_t& manifest : state.get_all_repos()) + if (options.list_verbose) { - fmt::println("\033[1;32mRepository:\033[0m {}", manifest.name); - fmt::println("\033[1;33mURL:\033[0m {}", manifest.url); - fmt::println("\033[1;34mPlugins:"); - for (const plugin_t& plugin : manifest.plugins) + for (const manifest_t& manifest : state.get_all_repos()) { - fmt::println("\033[1;34m - {}\033[0m", plugin.name); - fmt::println("\t\033[1;35mDescription:\033[0m {}", plugin.description); - fmt::println("\t\033[1;36mAuthor(s):\033[0m {}", fmt::join(plugin.authors, ", ")); - fmt::println("\t\033[1;38;2;220;220;220mLicense(s):\033[0m {}", fmt::join(plugin.licenses, ", ")); - fmt::println("\t\033[1;38;2;144;238;144mPrefixe(s):\033[0m {}", fmt::join(plugin.prefixes, ", ")); - fmt::print("\n"); + fmt::println("\033[1;32mRepository:\033[0m {}", manifest.name); + fmt::println("\033[1;33mURL:\033[0m {}", manifest.url); + fmt::println("\033[1;34mPlugins:"); + for (const plugin_t& plugin : manifest.plugins) + { + fmt::println("\033[1;34m - {}\033[0m", plugin.name); + fmt::println("\t\033[1;35mDescription:\033[0m {}", plugin.description); + fmt::println("\t\033[1;36mAuthor(s):\033[0m {}", fmt::join(plugin.authors, ", ")); + fmt::println("\t\033[1;38;2;220;220;220mLicense(s):\033[0m {}", + fmt::join(plugin.licenses, ", ")); + fmt::println("\t\033[1;38;2;144;238;144mPrefixe(s):\033[0m {}", + fmt::join(plugin.prefixes, ", ")); + fmt::print("\n"); + } + fmt::print("\033[0m"); + } + } + else + { + for (const manifest_t& manifest : state.get_all_repos()) + { + fmt::println("\033[1;32mRepository:\033[0m {} (\033[1;33m{}\033[0m)", manifest.name, manifest.url); + fmt::println("\033[1;34mPlugins:"); + for (const plugin_t& plugin : manifest.plugins) + fmt::println(" \033[1;34m{} - \033[1;35m{}\n", plugin.name, plugin.description); + fmt::print("\033[0m"); } - fmt::print("\033[0m"); } break; } diff --git a/cufetchpm/src/manifest.cpp b/cufetchpm/src/manifest.cpp index 58171d89..ae509dc1 100644 --- a/cufetchpm/src/manifest.cpp +++ b/cufetchpm/src/manifest.cpp @@ -42,7 +42,8 @@ std::vector<std::string> ManifestSpace::getStrArrayValue(const toml::table& tbl, return {}; } -std::vector<std::string> ManifestSpace::getStrArrayValue(const toml::table& tbl, const std::string_view name, const std::string_view value) +std::vector<std::string> ManifestSpace::getStrArrayValue(const toml::table& tbl, const std::string_view name, + const std::string_view value) { std::vector<std::string> ret; diff --git a/cufetchpm/src/pluginManager.cpp b/cufetchpm/src/pluginManager.cpp index 0e81e957..38ae3e36 100644 --- a/cufetchpm/src/pluginManager.cpp +++ b/cufetchpm/src/pluginManager.cpp @@ -96,13 +96,13 @@ void PluginManager::build_plugins(const fs::path& working_dir) m_state.add_new_repo(manifest); // we built all plugins. let's rename the working directory to its actual manifest name, - success("Repository plugins successfully built! Moving to '{}'...", repo_cache_path.string()); + success("Repository plugins successfully built! Renaming to '{}'...", repo_cache_path.string()); fs::create_directories(repo_cache_path); fs::rename(working_dir, repo_cache_path); - // and then we symlink each plugin built library from its output-dir + // and then we move each plugin built library from its output-dir fs::create_directories(plugin_config_path); - status("Linking each built plugin to '{}'", plugin_config_path.string()); + status("Moving each built plugin to '{}'", plugin_config_path.string()); for (const plugin_t& plugin : manifest.get_all_plugins()) { if (!fs::exists(plugin.output_dir)) @@ -119,7 +119,7 @@ void PluginManager::build_plugins(const fs::path& working_dir) } if (library.is_regular_file() || library.is_symlink()) - fs::create_symlink(fs::canonical(library), library_config_path); + fs::rename(fs::canonical(library), library_config_path); else error("Built library '{}' is not a regular file", library.path().string()); } diff --git a/cufetchpm/src/stateManager.cpp b/cufetchpm/src/stateManager.cpp index 55b41122..96b9561b 100644 --- a/cufetchpm/src/stateManager.cpp +++ b/cufetchpm/src/stateManager.cpp @@ -153,11 +153,11 @@ std::vector<manifest_t> StateManager::get_all_repos() continue; plugin_t plugin; - plugin.name = getStrValue(*plugin_tbl, "name"); + plugin.name = getStrValue(*plugin_tbl, "name"); plugin.description = getStrValue(*plugin_tbl, "description"); - plugin.output_dir = getStrValue(*plugin_tbl, "output-dir"); - plugin.authors = getStrArrayValue(*plugin_tbl, "authors"); - plugin.licenses = getStrArrayValue(*plugin_tbl, "licenses"); + plugin.output_dir = getStrValue(*plugin_tbl, "output-dir"); + plugin.authors = getStrArrayValue(*plugin_tbl, "authors"); + plugin.licenses = getStrArrayValue(*plugin_tbl, "licenses"); manifest.plugins.push_back(std::move(plugin)); } From e234b1c6335b4ea0caa37c1c8a795c6f191991c8 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Wed, 30 Jul 2025 15:38:50 +0200 Subject: [PATCH 127/143] cufetchpm: stateManager: add new entry 'libraries' in plugins also fix some install -f bugs and other stuff I forgot --- cufetchpm/include/manifest.hpp | 12 ++++--- cufetchpm/include/pluginManager.hpp | 6 ++-- cufetchpm/include/stateManager.hpp | 37 +++++++++++++++++++-- cufetchpm/src/pluginManager.cpp | 51 ++++++++++++++++++++++------- cufetchpm/src/stateManager.cpp | 38 ++++----------------- 5 files changed, 91 insertions(+), 53 deletions(-) diff --git a/cufetchpm/include/manifest.hpp b/cufetchpm/include/manifest.hpp index c6825265..17411b8b 100644 --- a/cufetchpm/include/manifest.hpp +++ b/cufetchpm/include/manifest.hpp @@ -56,12 +56,14 @@ struct manifest_t constexpr char const MANIFEST_NAME[] = "cufetchpm.toml"; -namespace ManifestSpace { -std::string getStrValue(const toml::table& tbl, const std::string_view name, const std::string_view key); -std::string getStrValue(const toml::table& tbl, const std::string_view path); -std::vector<std::string> getStrArrayValue(const toml::table& tbl, const std::string_view name, const std::string_view value); +namespace ManifestSpace +{ +std::string getStrValue(const toml::table& tbl, const std::string_view name, const std::string_view key); +std::string getStrValue(const toml::table& tbl, const std::string_view path); +std::vector<std::string> getStrArrayValue(const toml::table& tbl, const std::string_view name, + const std::string_view value); std::vector<std::string> getStrArrayValue(const toml::table& tbl, const std::string_view path); -} +} // namespace ManifestSpace class CManifest { diff --git a/cufetchpm/include/pluginManager.hpp b/cufetchpm/include/pluginManager.hpp index 36229b7b..7341b9f6 100644 --- a/cufetchpm/include/pluginManager.hpp +++ b/cufetchpm/include/pluginManager.hpp @@ -41,8 +41,8 @@ void status(const std::string_view fmt, Args&&... args) noexcept class PluginManager { public: - PluginManager(const StateManager& state) : m_state(state) {} - PluginManager(StateManager&& state) : m_state(std::move(state)) {} + PluginManager(const StateManager& state_manager) : m_state_manager(state_manager) {} + PluginManager(StateManager&& state_manager) : m_state_manager(std::move(state_manager)) {} void add_repo_plugins(const std::string& repo); void build_plugins(const fs::path& working_dir); @@ -50,7 +50,7 @@ class PluginManager bool has_deps(); private: - StateManager m_state; + StateManager m_state_manager; fs::path m_config_path{ getConfigDir() / "plugins" }; fs::path m_cache_path{ getHomeCacheDir() / "cufetchpm" / "plugins" }; }; diff --git a/cufetchpm/include/stateManager.hpp b/cufetchpm/include/stateManager.hpp index 3878cd90..f288b25f 100644 --- a/cufetchpm/include/stateManager.hpp +++ b/cufetchpm/include/stateManager.hpp @@ -9,6 +9,7 @@ namespace fs = std::filesystem; +bool writeState(const std::string& str, const std::string& to); class StateManager { public: @@ -17,10 +18,13 @@ class StateManager StateManager(const StateManager&) = default; ~StateManager() = default; - void add_new_repo(const CManifest& manifest); - void add_new_plugin(const plugin_t& manifest); + void add_new_repo(const CManifest& manifest); std::vector<manifest_t> get_all_repos(); + template <typename T> + void insert_or_assign_at_plugin(const std::string_view repo_name, const std::string_view plugin_name, + const std::string_view key, T&& value); + const toml::table& get_state() const { return m_state; } @@ -29,4 +33,33 @@ class StateManager toml::table m_state; }; +template <typename T> +void StateManager::insert_or_assign_at_plugin(const std::string_view repo_name, const std::string_view plugin_name, + const std::string_view key, T&& value) +{ + auto* repo_plugins_arr = m_state["repositories"][repo_name]["plugins"].as_array(); + if (!repo_plugins_arr) + die("Couldn't find an array of plugins from repository '{}'", repo_name); + + for (auto&& plugins_node : *repo_plugins_arr) + { + auto* plugin_tbl = plugins_node.as_table(); + if (!plugin_tbl) + continue; + const std::string& name = ManifestSpace::getStrValue(*plugin_tbl, "name"); + if (name != plugin_name) + continue; + + (*plugin_tbl).insert_or_assign(key, std::forward<T>(value)); + std::stringstream ss; + ss << "AUTO-GENERATED FILE. DO NOT EDIT THIS FILE.\n"; + ss << "# YOU GONNA MESS SHIT UP. unless you know what you doing ofc\n"; + ss << m_state; + + if (!writeState(ss.str(), m_path)) + die("Failed to write plugin state of repository '{}'", repo_name); + break; + } +} + #endif diff --git a/cufetchpm/src/pluginManager.cpp b/cufetchpm/src/pluginManager.cpp index 38ae3e36..3abb1843 100644 --- a/cufetchpm/src/pluginManager.cpp +++ b/cufetchpm/src/pluginManager.cpp @@ -62,13 +62,18 @@ void PluginManager::build_plugins(const fs::path& working_dir) CManifest manifest(MANIFEST_NAME); // though lets check if we have already installed the plugin in the cache - const fs::path& repo_cache_path = (m_cache_path / manifest.get_repo_name()); - const fs::path& plugin_config_path = (m_config_path / manifest.get_repo_name()); + const fs::path& repo_cache_path = (m_cache_path / manifest.get_repo_name()); + const fs::path& plugins_config_path = (m_config_path / manifest.get_repo_name()); if (fs::exists(repo_cache_path)) { - warn("Repository '{}' already exists in '{}'", manifest.get_repo_name(), repo_cache_path.string()); - fs::remove_all(working_dir); - return; + if (!options.install_force) + { + warn("Repository '{}' already exists in '{}'", manifest.get_repo_name(), repo_cache_path.string()); + fs::remove_all(working_dir); + return; + } + + fs::remove_all(repo_cache_path); } // So we don't have any plugins in the manifest uh @@ -93,7 +98,7 @@ void PluginManager::build_plugins(const fs::path& working_dir) } success("Successfully built '{}' into '{}'", plugin.name, plugin.output_dir); } - m_state.add_new_repo(manifest); + m_state_manager.add_new_repo(manifest); // we built all plugins. let's rename the working directory to its actual manifest name, success("Repository plugins successfully built! Renaming to '{}'...", repo_cache_path.string()); @@ -101,28 +106,50 @@ void PluginManager::build_plugins(const fs::path& working_dir) fs::rename(working_dir, repo_cache_path); // and then we move each plugin built library from its output-dir - fs::create_directories(plugin_config_path); - status("Moving each built plugin to '{}'", plugin_config_path.string()); + // and we'll declare all plugins we have moved. + fs::create_directories(plugins_config_path); + status("Moving each built plugin to '{}'", plugins_config_path.string()); for (const plugin_t& plugin : manifest.get_all_plugins()) { + // ugh, devs fault. Report this error to them if (!fs::exists(plugin.output_dir)) - die("Plugin '{}' output-dir '{}' doesn't exist", plugin.name, plugin.output_dir); + { + error("Plugin '{}' output-dir '{}' doesn't exist", plugin.name, plugin.output_dir); + continue; + } + + toml::array built_libraries; for (const auto& library : fs::directory_iterator{ plugin.output_dir }) { - const fs::path& library_config_path = plugin_config_path / library.path().filename(); + // ~/.config/customfetch/plugins/<plugin-directory>/<plugin-filename> + const fs::path& library_config_path = plugins_config_path / library.path().filename(); if (fs::exists(library_config_path)) { - if (askUserYorN(false, "Library plugin '{}' already exists. Replace it?", library_config_path.string())) + if (askUserYorN(false, "Plugin '{}' already exists. Replace it?", library_config_path.string())) fs::remove_all(library_config_path); else continue; } if (library.is_regular_file() || library.is_symlink()) - fs::rename(fs::canonical(library), library_config_path); + { + std::error_code er; + fs::rename(fs::canonical(library), library_config_path, er); + if (er) + { + error("Failed to move '{}' to '{}': {}", fs::canonical(library).string(), + library_config_path.string(), er.message()); + continue; + } + built_libraries.push_back(library_config_path.string()); + } else + { error("Built library '{}' is not a regular file", library.path().string()); + } } + m_state_manager.insert_or_assign_at_plugin(manifest.get_repo_name(), plugin.name, "libraries", + std::move(built_libraries)); } success("Enjoy the new plugins from {}", manifest.get_repo_name()); } diff --git a/cufetchpm/src/stateManager.cpp b/cufetchpm/src/stateManager.cpp index 96b9561b..4e65fc85 100644 --- a/cufetchpm/src/stateManager.cpp +++ b/cufetchpm/src/stateManager.cpp @@ -3,6 +3,7 @@ #include <filesystem> #include <fstream> #include <sstream> +#include <string_view> #include <utility> #include "fmt/base.h" @@ -13,7 +14,7 @@ using namespace ManifestSpace; // https://github.com/hyprwm/Hyprland/blob/2d2a5bebff72c73cd27db3b9e954b8fa2a7623e8/hyprpm/src/core/DataState.cpp#L24 -static bool writeState(const std::string& str, const std::string& to) +bool writeState(const std::string& str, const std::string& to) { // create temp file in a safe temp root const fs::path& temp_state = (fs::temp_directory_path() / ".temp-state"); @@ -38,6 +39,7 @@ static toml::table& ensure_table(toml::table& parent, std::string_view key) return *it->second.as_table(); } +// Converts a vector of strings to a toml::array static toml::array vector_to_array(const std::vector<std::string>& vec) { toml::array ret; @@ -83,7 +85,6 @@ void StateManager::add_new_repo(const CManifest& manifest) // will be inserted in alphabetical order toml::table entry{ { "name", plugin.name }, { "description", plugin.description }, - { "output-dir", plugin.output_dir }, { "authors", vector_to_array(plugin.authors) }, { "licenses", vector_to_array(plugin.licenses) }, { "conflicts", vector_to_array(plugin.conflicts) }, @@ -94,46 +95,21 @@ void StateManager::add_new_repo(const CManifest& manifest) repo.insert_or_assign("plugins", std::move(plugins_arr)); std::stringstream ss; - ss << R"(# AUTO-GENERATED FILE. DO NOT EDIT THIS FILE. -# YOU GONNA MESS SHIT UP. unless you know what you doing ofc)"; - ss << "\n"; + ss << "AUTO-GENERATED FILE. DO NOT EDIT THIS FILE.\n"; + ss << "# YOU GONNA MESS SHIT UP. unless you know what you doing ofc\n"; ss << m_state; if (!writeState(ss.str(), m_path)) die("Failed to write plugin state of repository '{}'", manifest.get_repo_name()); } -void StateManager::add_new_plugin(const plugin_t& manifest) -{ - toml::array authors_arr, licenses_arr; - for (const std::string& str : manifest.authors) - authors_arr.push_back(str); - for (const std::string& str : manifest.licenses) - licenses_arr.push_back(str); - - toml::table plugin_state_entry{ { "description", manifest.description }, - { "authors", authors_arr }, - { "licenses", licenses_arr }, - { "output-dir", manifest.output_dir } }; - - // Add or replace plugin entry - m_state.insert_or_assign(manifest.name, std::move(plugin_state_entry)); - - std::stringstream ss; - ss << m_state; - - if (!writeState(ss.str(), m_path)) - die("Failed to write plugin state of '{}'", manifest.name); -} - std::vector<manifest_t> StateManager::get_all_repos() { - std::vector<manifest_t> manifests; - const toml::table* repositories = m_state["repositories"].as_table(); if (!repositories) - return manifests; + return {}; + std::vector<manifest_t> manifests; for (const auto& [repo_name, repo_node] : *repositories) { const toml::table* repo_tbl = repo_node.as_table(); From 00e44e8672116210d2a16841e02e42c2b48f670a Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Wed, 30 Jul 2025 18:13:49 +0200 Subject: [PATCH 128/143] build (makefile): let the user decide the std (min. c++17) + fix some little warnings --- Makefile | 17 ++++++++++------- cufetchpm/Makefile | 7 ++++--- include/libcufetch/cufetch.hh | 7 +++++++ include/libcufetch/parse.hh | 7 +++++++ src/config.cpp | 8 ++++---- src/libs/fmt/Makefile | 3 ++- src/libs/json/Makefile | 3 ++- src/libs/tiny-process-library/Makefile | 3 ++- src/libs/toml++/Makefile | 3 ++- 9 files changed, 40 insertions(+), 18 deletions(-) diff --git a/Makefile b/Makefile index 0f24705e..7acdf507 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,7 @@ APPPREFIX ?= $(PREFIX)/share/applications LOCALEDIR ?= $(PREFIX)/share/locale ICONPREFIX ?= $(PREFIX)/share/pixmaps VARS ?= -DENABLE_NLS=1 +CXXSTD ?= c++20 DEBUG ?= 1 GUI_APP ?= 0 @@ -15,7 +16,8 @@ USE_DCONF ?= 1 # WAY easier way to build debug and release builds ifeq ($(DEBUG), 1) BUILDDIR = build/debug - CXXFLAGS := -ggdb3 -Wall -Wextra -Wpedantic -Wno-unused-parameter -DDEBUG=1 -fno-omit-frame-pointer -fsanitize=address $(DEBUG_CXXFLAGS) $(CXXFLAGS) + CXXFLAGS := -ggdb3 -Wall -Wextra -pedantic -Wno-unused-parameter -fsanitize=address \ + -DDEBUG=1 -fno-omit-frame-pointer -O1 -fno-lto $(DEBUG_CXXFLAGS) $(CXXFLAGS) LDFLAGS += -fsanitize=address else # Check if an optimization flag is not already set @@ -24,6 +26,7 @@ else else CXXFLAGS := -O3 $(CXXFLAGS) endif + CXXFLAGS += -flto=auto -ffat-lto-objects BUILDDIR = build/release endif @@ -54,29 +57,29 @@ OBJ = $(OBJ_CPP) $(OBJ_CC) LDFLAGS += -L$(BUILDDIR) -flto=auto -ffat-lto-objects LDLIBS += $(BUILDDIR)/libfmt.a $(BUILDDIR)/libtiny-process-library.a -lcufetch -ldl CXXFLAGS ?= -mtune=generic -march=native -CXXFLAGS += -flto=auto -ffat-lto-objects -fvisibility-inlines-hidden -fvisibility=hidden -Iinclude -Iinclude/libcufetch -Iinclude/libs -std=c++20 $(VARS) -DVERSION=\"$(VERSION)\" -DLOCALEDIR=\"$(LOCALEDIR)\" -DICONPREFIX=\"$(ICONPREFIX)\" +CXXFLAGS += -fvisibility-inlines-hidden -fvisibility=hidden -Iinclude -Iinclude/libcufetch -Iinclude/libs -std=$(CXXSTD) $(VARS) -DVERSION=\"$(VERSION)\" -DLOCALEDIR=\"$(LOCALEDIR)\" -DICONPREFIX=\"$(ICONPREFIX)\" all: genver fmt toml tpl getopt-port json libcufetch $(TARGET) libcufetch: fmt toml ifeq ($(wildcard $(BUILDDIR)/libcufetch.so),) - make -C libcufetch BUILDDIR=$(BUILDDIR) GUI_APP=$(GUI_APP) + make -C libcufetch BUILDDIR=$(BUILDDIR) GUI_APP=$(GUI_APP) CXXSTD=$(CXXSTD) endif fmt: ifeq ($(wildcard $(BUILDDIR)/libfmt.a),) mkdir -p $(BUILDDIR) - make -C src/libs/fmt BUILDDIR=$(BUILDDIR) + make -C src/libs/fmt BUILDDIR=$(BUILDDIR) CXXSTD=$(CXXSTD) endif toml: ifeq ($(wildcard $(BUILDDIR)/toml.o),) - make -C src/libs/toml++ BUILDDIR=$(BUILDDIR) + make -C src/libs/toml++ BUILDDIR=$(BUILDDIR) CXXSTD=$(CXXSTD) endif tpl: ifeq ($(wildcard $(BUILDDIR)/libtiny-process-library.a),) - make -C src/libs/tiny-process-library BUILDDIR=$(BUILDDIR) + make -C src/libs/tiny-process-library BUILDDIR=$(BUILDDIR) CXXSTD=$(CXXSTD) endif getopt-port: @@ -86,7 +89,7 @@ endif json: ifeq ($(wildcard $(BUILDDIR)/json.o),) - make -C src/libs/json BUILDDIR=$(BUILDDIR) + make -C src/libs/json BUILDDIR=$(BUILDDIR) CXXSTD=$(CXXSTD) endif genver: ./scripts/generateVersion.sh diff --git a/cufetchpm/Makefile b/cufetchpm/Makefile index c8ad69b3..ce623dc0 100644 --- a/cufetchpm/Makefile +++ b/cufetchpm/Makefile @@ -2,6 +2,7 @@ CXX ?= g++ PREFIX ?= /usr MANPREFIX ?= $(PREFIX)/share/man VARS ?= -DENABLE_NLS=1 +CXXSTD ?= c++20 DEBUG ?= 1 # https://stackoverflow.com/a/1079861 @@ -35,13 +36,13 @@ all: fmt toml getopt-port tpl $(TARGET) fmt: ifeq ($(wildcard $(BUILDDIR)/libfmt.a),) mkdir -p $(BUILDDIR) - make -C ../src/libs/fmt BUILDDIR=cufetchpm/$(BUILDDIR) + make -C ../src/libs/fmt BUILDDIR=cufetchpm/$(BUILDDIR) CXXSTD=$(CXXSTD) endif toml: ifeq ($(wildcard $(BUILDDIR)/toml.o),) mkdir -p $(BUILDDIR) - make -C ../src/libs/toml++ BUILDDIR=cufetchpm/$(BUILDDIR) + make -C ../src/libs/toml++ BUILDDIR=cufetchpm/$(BUILDDIR) CXXSTD=$(CXXSTD) endif getopt-port: @@ -53,7 +54,7 @@ endif tpl: ifeq ($(wildcard $(BUILDDIR)/libtiny-process-library.a),) mkdir -p $(BUILDDIR) - make -C ../src/libs/tiny-process-library BUILDDIR=cufetchpm/$(BUILDDIR) + make -C ../src/libs/tiny-process-library BUILDDIR=cufetchpm/$(BUILDDIR) CXXSTD=$(CXXSTD) endif $(TARGET): fmt toml getopt-port tpl $(OBJ) diff --git a/include/libcufetch/cufetch.hh b/include/libcufetch/cufetch.hh index ec1f4f60..8f4625ae 100644 --- a/include/libcufetch/cufetch.hh +++ b/include/libcufetch/cufetch.hh @@ -35,6 +35,13 @@ struct module_t std::function<std::string(const callbackInfo_t*)> handler; }; +// C ABI is needed to prevent symbol mangling, but we don't actually need C compatibility, +// so we ignore this warning about return types that are potentially incompatible with C. +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wreturn-type-c-linkage" +#endif + /* Register a module, and its submodules, to customfetch. */ APICALL EXPORT void cfRegisterModule(const module_t& module); diff --git a/include/libcufetch/parse.hh b/include/libcufetch/parse.hh index 52f86c7b..9e35973b 100644 --- a/include/libcufetch/parse.hh +++ b/include/libcufetch/parse.hh @@ -7,6 +7,13 @@ #include "libcufetch/common.hh" #include "libcufetch/config.hh" +// C ABI is needed to prevent symbol mangling, but we don't actually need C compatibility, +// so we ignore this warning about return types that are potentially incompatible with C. +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wreturn-type-c-linkage" +#endif + struct module_t; // Map from a modules name to its pointer. diff --git a/src/config.cpp b/src/config.cpp index 10cf6c13..b56f9532 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -166,14 +166,14 @@ void Config::overrideOption(const std::string& opt) name.insert(0, "config."); if (value == "true") - overrides[name] = {.value_type = BOOL, .bool_value = true}; + overrides[name] = {BOOL, "", true, 0}; else if (value == "false") - overrides[name] = {.value_type = BOOL, .bool_value = false}; + overrides[name] = {BOOL, "", false, 0}; else if ((value[0] == '"' && value.back() == '"') || (value[0] == '\'' && value.back() == '\'')) - overrides[name] = {.value_type = STR, .string_value = value.substr(1, value.size()-2)}; + overrides[name] = {STR, value.substr(1, value.size()-2), false, 0}; else if (is_str_digital(value)) - overrides[name] = {.value_type = INT, .int_value = std::stoi(value)}; + overrides[name] = {INT, "", false, std::stoi(value)}; else die(_("looks like override value '{}' from '{}' is neither a bool, int or string value"), value, name); diff --git a/src/libs/fmt/Makefile b/src/libs/fmt/Makefile index 5708ef6b..4e5eccb7 100644 --- a/src/libs/fmt/Makefile +++ b/src/libs/fmt/Makefile @@ -3,8 +3,9 @@ # cmd: cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF CXX ?= g++ +CXXSTD ?= c++20 # CXX_DEFINES = -DFMT_LIB_EXPORT -Dfmt_EXPORTS -CXXFLAGS = -I../../../include/libs -O3 -DNDEBUG -flto=auto -ffat-lto-objects -fvisibility=hidden -fvisibility-inlines-hidden -fPIC +CXXFLAGS = -I../../../include/libs -O3 -std=$(CXXSTD) -DNDEBUG -flto=auto -ffat-lto-objects -fvisibility=hidden -fvisibility-inlines-hidden -fPIC all: fmt diff --git a/src/libs/json/Makefile b/src/libs/json/Makefile index d32f39db..f251844d 100644 --- a/src/libs/json/Makefile +++ b/src/libs/json/Makefile @@ -1,7 +1,8 @@ CXX ?= g++ SRC = json.cpp TARGET = json.o -CXXFLAGS = -I../../../include/libs -flto=auto -ffat-lto-objects -std=c++20 -fPIC +CXXSTD ?= c++20 +CXXFLAGS = -I../../../include/libs -flto=auto -ffat-lto-objects -std=$(CXXSTD) -fPIC all: $(TARGET) diff --git a/src/libs/tiny-process-library/Makefile b/src/libs/tiny-process-library/Makefile index 40748d0b..69bf9644 100644 --- a/src/libs/tiny-process-library/Makefile +++ b/src/libs/tiny-process-library/Makefile @@ -1,5 +1,6 @@ CXX ?= g++ -CXXFLAGS = -I../../../include/libs/tiny-process-library -O3 -DNDEBUG -flto=auto -ffat-lto-objects -fvisibility=default -fvisibility-inlines-hidden -fPIC +CXXSTD ?= c++20 +CXXFLAGS = -I../../../include/libs/tiny-process-library -std=$(CXXSTD) -O3 -DNDEBUG -flto=auto -ffat-lto-objects -fvisibility=default -fvisibility-inlines-hidden -fPIC UNAME_S := $(shell uname -s) diff --git a/src/libs/toml++/Makefile b/src/libs/toml++/Makefile index 95837dba..d5d3a662 100644 --- a/src/libs/toml++/Makefile +++ b/src/libs/toml++/Makefile @@ -1,7 +1,8 @@ CXX ?= g++ +CXXSTD ?= c++20 SRC = toml.cpp TARGET = toml.o -CXXFLAGS = -I../../../include/libs -flto=auto -ffat-lto-objects -fvisibility-inlines-hidden -fvisibility=default -fPIC -std=c++20 +CXXFLAGS = -I../../../include/libs -flto=auto -ffat-lto-objects -fvisibility-inlines-hidden -fvisibility=default -fPIC -std=$(CXXSTD) all: $(TARGET) From 0b33fbec610f07241a3deaffbedfcdb3fb59724d Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Thu, 31 Jul 2025 18:06:44 +0200 Subject: [PATCH 129/143] misc: move compile-time strings into 'texts.hpp' + cufetchpm: add new 'gen-manifest' command --- cufetchpm/src/main.cpp | 53 ++--- include/config.hpp | 204 ----------------- include/texts.hpp | 491 +++++++++++++++++++++++++++++++++++++++++ src/config.cpp | 1 + src/main.cpp | 197 +---------------- 5 files changed, 516 insertions(+), 430 deletions(-) create mode 100644 include/texts.hpp diff --git a/cufetchpm/src/main.cpp b/cufetchpm/src/main.cpp index fde2600c..35fc9392 100644 --- a/cufetchpm/src/main.cpp +++ b/cufetchpm/src/main.cpp @@ -1,11 +1,13 @@ #include <cstdlib> #include <filesystem> -#include "fmt/base.h" #include "fmt/ranges.h" #include "libcufetch/common.hh" +#include "fmt/os.h" +#include "fmt/compile.h" #include "pluginManager.hpp" #include "stateManager.hpp" +#include "texts.hpp" #if (!__has_include("version.h")) #error "version.h not found, please generate it with ./scripts/generateVersion.sh" @@ -19,7 +21,8 @@ enum Ops { NONE, INSTALL, - LIST + LIST, + GEN_MANIFEST, } op = NONE; void version() @@ -36,49 +39,21 @@ void version() void help(int invalid_opt = false) { - fmt::print(R"(Usage: cufetchpm <COMMAND> [OPTIONS]... -Manage plugins for customfetch. - -Commands: - install [OPTIONS] <repo/path>... Install one or more plugin sources from a Git repo or local path. - help <COMMAND> Show help for a specific command. - -Global options: - -h, --help Show this help message. - -V, --version Show version and build information. - -)"); + fmt::print(FMT_COMPILE("{}"), cufetchpm_help); std::exit(invalid_opt); } void help_install(int invalid_opt = false) { - fmt::print(R"(Usage: cufetchpm install [options] <repo/path>... - -Install one or more plugin sources. If a given argument exists on disk, -it is treated as a local directory. Otherwise, it is treated as a Git -repository URL and will be cloned. - -All plugins found within the source will be installed. - -Options: - -f, --force Force installation, even if already installed. - -h, --help Show help for this command. -)"); + fmt::print(FMT_COMPILE("{}"), cufetchpm_help_install); std::exit(invalid_opt); } void help_list(int invalid_opt = false) { - fmt::print(R"(Usage: cufetchpm list [options] -List all installed plugins. - -Options: - -v, --verbose Show detailed plugin information. - -h, --help Show help for this command. -)"); + fmt::print(FMT_COMPILE("{}"), cufetchpm_help_list); std::exit(invalid_opt); } @@ -183,6 +158,11 @@ static bool parseargs(int argc, char* argv[]) optind = 0; return parse_list_args(sub_argc, sub_argv); } + else if (cmd == "gen-manifest") + { + op = GEN_MANIFEST; + optind = 0; + } else if (cmd == "help") { if (sub_argc >= 1) @@ -264,6 +244,13 @@ int main(int argc, char* argv[]) } break; } + case GEN_MANIFEST: + { + auto f = fmt::output_file("cufetchpm.toml", fmt::file::CREATE | fmt::file::WRONLY); + f.print("{}", AUTO_MANIFEST); + f.close(); + break; + } default: warn("uh?"); } diff --git a/include/config.hpp b/include/config.hpp index 3a258131..21c60a8c 100644 --- a/include/config.hpp +++ b/include/config.hpp @@ -30,10 +30,7 @@ #define TOML_HEADER_ONLY 0 #include <filesystem> -#include <string_view> - #include "libcufetch/config.hh" -#include "platform.hpp" class Config : public ConfigBase { @@ -177,205 +174,4 @@ class Config : public ConfigBase } }; -// default config -inline constexpr std::string_view AUTOCONFIG = R"#([config] - -# For more information on how customfetch works and the layout, -# Read either: -# * -w or --how-it-works -# * the manual customfetch.1 -# * if on the android app, click the button "how it works" during widget configuration -layout = [ - "$<title>", - "$<title.sep>", - "${auto}OS: $<os.name> $<system.arch>", - "${auto}Host: $<system.host>", - "${auto}Kernel: $<os.kernel>", - "${auto}Uptime: $<os.uptime>",)#" -#if !CF_ANDROID - R"#( - "${auto}Theme: $<theme.gtk.all.name>", - "${auto}Icons: $<theme.gtk.all.icon>", - "${auto}Font: $<theme.gtk.all.font>", - "${auto}Cursor: $<theme.cursor>", - "${auto}WM: $<user.wm.name>", - "${auto}DE: $<user.de.name>",)#" -#endif - R"#( - "$<auto.disk>", - "${auto}Swap: $<swap>", - "${auto}CPU: $<cpu>", - "${auto}GPU: $<gpu>", - "${auto}RAM: $<ram>", - "", - "$<colors>", # normal colors - "$<colors.light>" # light colors -] - -# display ascii-art or image/gif (GUI only) near layout -# put "os" for displaying the OS ascii-art -# or the "/path/to/file" for displaying custom files -# or "off" for disabling ascii-art or image displaying -source-path = "os" - -# Path to where we'll take all the distros/OSs ascii arts. -# note: it MUST contain an "ascii" subdirectory -data-dir = "/usr/share/customfetch" - -# The type of ASCII art to apply ("small", "old"). -# Basically will add "_<type>" to the logo filename. -# It will return the regular linux ascii art if it doesn't exist. -# Leave empty it for regular. -ascii-logo-type = "" - -# A char (or string) to use in $<title_sep> -title-sep = "-" - -# A separator (or string) that when encountered, will automatically -# reset color, aka. automatically add ${0} (only in layout) -# Make it empty for disabling -sep-reset = ":" - -# Should we reset color after or before the separator? -# true = after ("test ->${0} ") -# false = before ("test ${0}-> ") -sep-reset-after = false - -# Where the logo should be displayed. -# Values: "top" or "left" or "bottom" -logo-position = "left" - -# Offset between the ascii art and the layout -# Can also be rapresented as a %, but super unstable sometimes. -offset = "5" - -# Padding between the start and the ascii art -logo-padding-left = 0 - -# Padding of the ascii art from the top -logo-padding-top = 0 - -# Padding of the layout from the top -layout-padding-top = 0 - -# Usually in neofetch/fastfetch, when your terminal size is too small, -# to render some text in 1 line, they don't wrap those lines, instead they truncate them. -# Enable/Disable if you want this -wrap-lines = false - -# Used in disk, ram and swap modules. -# If true, we're going to use the SI standard byte unit (1kB == 1000 bytes) -# Else if false, we using the IEC byte unit (1KiB == 1024 bibytes) -# Really nerdy stuff -use-SI-byte-unit = false - -# Warn against tradeoffs between slower queries for availability -# e.g. falling back to gsettings when we can't find the config file for GTK -slow-query-warnings = false - -# Colors in the terminal (for Desktop/Android app, use the ones under [gui]) -black = "\e[1;30m" -red = "\e[1;31m" -green = "\e[1;32m" -yellow = "\e[1;33m" -blue = "\e[1;34m" -magenta = "\e[1;35m" -cyan = "\e[1;36m" -white = "\e[1;37m" - -# Alias colors. Basically more color variables. -# They can be used as like as the color tag. -# This is as like as using the --add-color argument -# Syntax must be "name=value", e.g "purple=magenta" or "orange=!#F08000" -alias-colors = ["purple=magenta"] - -# Colors to be used in percentage tag and modules members. -# They are used as if you're using the color tag. -# It's an array just for "convenience" -# 1st color for good -# 2nd color for normal -# 3rd color for bad -percentage-colors = ["green", "yellow", "red"] - -# $<auto.disk> config -[auto.disk] -# Format for displaying the auto detected disks infos -# %1 = mount directory -# %2 = device path -# %3 = type of filesystem -# %4 = total amount of storage -# %5 = free amount of storage -# %6 = used amount of storage -# %7 = percentage of used storage -# %8 = percentage of free storage -fmt = "${auto}Disk (%1): $<disk(%1)>" - -# Only print disks that matches the description -# of the following types: -# regular = Regular disks (internel M.2 SSD, ...) (won't be specified) -# external = External disks (USB, SATA, ...) -# read-only = Disks with read-only filesystems -# hidden = Disks that are not really mounted by the user -display-types = ["regular", "external", "read-only"] - -# In some OSes such as NixOS or Android, there might be some directories that are bind mounted. -# Bind mounted directories create an additional view of an existing directory, -# and `statfs()` on the mount point will return the filesystem statistics of the original directory. -show-duplicated = false - -# $<os.uptime> config -[os.uptime] -# how to display the name of the uptime -# e.g: hours = "hrs" -> "Uptime: 3hrs" -days = " days" -hours = " hours" -mins = " mins" -secs = " secs" - -# $<os.pkgs> config -[os.pkgs] -# Ordered list of which packages installed count should be displayed in $<os.pkgs> -# remember to not enter the same name twice, else the world will finish -# Choices: pacman, flatpak, dpkg, apk -# -# Pro-tip: if your package manager isn't listed here, yet, -# use the bash command tag in the layout -# e.g "Packages: $(pacman -Q | wc -l) (pacman)" -pkg-managers = ["pacman", "dpkg", "flatpak"] - -# Distros and package manager specific -# package manager paths for getting the packages count from path. -# They are arrays so you can add multiple paths. -# -# If you don't know what these ares, leave them by default settings -pacman-dirs = ["/var/lib/pacman/local/"] -dpkg-files = ["/var/lib/dpkg/status", "/data/data/com.termux/files/usr/var/lib/dpkg/status"] -flatpak-dirs = ["/var/lib/flatpak/app/", "~/.local/share/flatpak/app/"] -apk-files = ["/var/lib/apk/db/installed"] - -# Desktop/Android app options -[gui] - -# These are the colors you can use in the GUI mode. -# They overwrite the terminal colors from above. -# They can only have hexcodes colors and its modifiers -black = "!#000005" -red = "!#ff2000" -green = "!#00ff00" -blue = "!#00aaff" -cyan = "!#00ffff" -yellow = "!#ffff00" -magenta = "!#f881ff" -white = "!#ffffff" - -# Path to image as a background. -# put "disable" for disabling and use the theme color as background. -bg-image = "disable" - -# Path to gtk css file to be used. -# put "disable" for disabling. -gtk-css = "disable" - -)#"; - #endif // _CONFIG_HPP diff --git a/include/texts.hpp b/include/texts.hpp new file mode 100644 index 00000000..e642eaa9 --- /dev/null +++ b/include/texts.hpp @@ -0,0 +1,491 @@ +#ifndef _TEXTS_HPP_ +#define _TEXTS_HPP_ + +#include "platform.hpp" +#include <string_view> + +// cufetchpm +inline constexpr std::string_view cufetchpm_help = (R"(Usage: cufetchpm <COMMAND> [OPTIONS]... +Manage plugins for customfetch. + +Commands: + help <COMMAND> Show help for a specific command. + install [OPTIONS] <repo/path>... Install one or more plugin sources from a Git repo or local path. + list List of information about all plugins installed through state.toml + gen-manifest Auto generate an example manifest "cufetchpm.toml" that'll you need to modify it yourself + +Global options: + -h, --help Show this help message. + -V, --version Show version and build information. + +)"); + +inline constexpr std::string_view cufetchpm_help_install = (R"(Usage: cufetchpm install [options] <repo/path>... + +Install one or more plugin sources. If a given argument exists on disk, +it is treated as a local directory. Otherwise, it is treated as a Git +repository URL and will be cloned. + +All plugins found within the source will be installed. + +Options: + -f, --force Force installation, even if already installed. + -h, --help Show help for this command. +)"); + +inline constexpr std::string_view cufetchpm_help_list = (R"(Usage: cufetchpm list [options] +List all installed plugins. + +Options: + -v, --verbose Show detailed plugin information. + -h, --help Show help for this command. +)"); + +// customfetch + +inline constexpr std::string_view customfetch_help = (R"(Usage: customfetch [OPTIONS]... +A command-line, GUI app, and Android widget system information tool (like neofetch) focused on customizability and performance. + +NOTE: Boolean flags [<BOOL>] accept: "true", 1, "enable", or empty. Any other value is treated as false. + +GENERAL OPTIONS: + -h, --help Print this help menu. + -V, --version Print version and other infos about the build. + -C, --config <PATH> Path to the config file (default: ~/.config/customfetch/config.toml). + + --gen-config [<PATH>] Generate default config file. If PATH is omitted, saves to default location. + Prompts before overwriting. + +LOGO OPTIONS: + -n, --no-logo Disable logo display. + -L, --logo-only Print only the logo (skip layout completely). + -s, --source-path <PATH> Path to custom ASCII art/image file. + + -a, --ascii-logo-type <TYPE> + Type of ASCII art (typically "small", "old", or empty for default). + Example: "-d arch -a older" looks for "arch_older.txt". + + -D, --data-dir <PATH> Path to data directory containing "ascii/" subfolder with distro logos. + -d, --distro <NAME> Use a custom distro logo (case-insensitive, e.g., "windows 11" or "ArCh"). + -p, --logo-position <POS> Logo position: "top" (default), "left", or "bottom". + -o, --offset <NUM> Space between logo and layout (default: 5). + --logo-padding-top <NUM> Logo padding from top (default: 0). + --logo-padding-left <NUM> Logo padding from left (default: 0). + +LAYOUT & FORMATTING: + -m, --layout-line <STRING> Override config layout with custom line(s). + Example: `-m "${auto}OS: $<os.name>" -m "${auto}CPU: $<cpu>"`. + + -N, --no-color Disable all colors (useful for pipes/scripts). + --layout-padding-top <NUM> Layout padding from top (default: 0). + --wrap-lines=[<BOOL>] Enable terminal line wrapping (default: false). + --title-sep <STRING> String to use for $<title.sep> (default: "-"). + --sep-reset <STRING> String that resets color (default: ":"). + --sep-reset-after=[<BOOL>] Reset color after (default) or before 'sep-reset'. + +GUI/TERMINAL OPTIONS: + -f, --font <STRING> GUI font (format: "FAMILY STYLE SIZE", e.g., "Liberation Mono Normal 12"). + -i, --image-backend <NAME> Terminal image backend ("kitty" or "viu"). + --bg-image <PATH> GUI background image path ("disable" to turn off). + +CONFIG: + -O, --override <STRING> Override a config value (non-array). Syntax: "name=value" (no spaces around "="). + Example: "auto.disk.fmt='Disk(%1): %6'". + Note: Names without dots (e.g., "sep-reset-after") gets auto-appended to "config.". + + --color <STRING> Replace a color globally. Syntax: "name=value" (no spaces around "="). + Example: "--color magenta=#FF00FF". + + --disallow-command-tag Do not allow command tags $() to be executed. + This is a safety measure for preventing malicious code to be executed because you didn't want to check the config first. + +INFORMATIONAL: + -l, --list-modules List all available info tag modules (e.g., $<cpu> or $<os.name>). + -w, --how-it-works Explain tags and general customization. + --list-logos List available ASCII logos in --data-dir. + +LIVE MODE: + --loop-ms <NUM> Run in live mode, updating every <NUM> milliseconds (min: 50). + Use inferior <NUM> than 200 to disable. Press 'q' to exit. + +EXAMPLES: + 1. Minimal output with default logo: + customfetch --no-color + + 2. Custom distro logo with live updates: + customfetch --distro "arch" --loop-ms 1000 + + 3. Override layout and colors: + customfetch -m "${magenta}OS: $<os.name>" --color "magenta=#FF00FF" + +For details, see `man customfetch` or run `--how-it-works`. +)"); + +constexpr std::string_view explain_customfetch = (R"( +customfetch is designed for maximum customizability, allowing users to display system information exactly how they want it. +The layout and logo is controlled through special tags that can output system info, execute commands, apply conditional logic, add colors, and calculate percentages with some colors. + +Tag References: +1. Information Tag ($<>) + Retrieves system information from modules. + + Syntax: $<module.submodule.sub...> or $<module> + + Examples: + - $<user.name> # Displays login username + - $<os.kernel.name> # Shows kernel name only + - $<ram> # Shows formatted RAM usage + + Use `--list-modules` to see all available modules and members. + +2. Bash Command Tag ($()) + Executes shell commands and outputs the result. + Supports full shell syntax including pipes and redirection. + + Syntax: $(command) + + Examples: + - $(echo "hello") # Outputs: hello + - $(date +%F) # Shows current date + - $(uname -r | cut -d'-' -f1) # Shows kernel version number only + +3. Conditional Tag ($[]) + Displays different outputs based on conditions. + + Syntax: $[condition,comparison,true_output,false_output] + + Examples: + - $[$<user.name>,toni,Welcome back!,Access denied] + - $[$(date +%m-%d),12-25,Merry Christmas!,] + - $[$<os.name.id>,arch,${green}I use arch btw,${red}Non-arch user] + +4. Color Tag (${}) + Applies colors and text formatting. + + Basic syntax: ${color} or ${modifiers#RRGGBB} + + Color options: + - Named colors from config + - Hex colors: ${#ff00cc} + - Special colors: ${auto} (uses logo colors) + - Reset styles: ${0} (normal), ${1} (bold reset) + + Formatting modifiers (prefix before hexcolor): + - ! = Bold + - u = Underline + - i = Italic + - s = Strikethrough + - l = Blink (terminal only) + - b = Background color + + Advanced GUI-only modifiers: + - o = Overline + - a(value) = Foreground alpha (1-65536 or 0%-100%) + - L(value) = Underline style (none/single/double/low/error) + - U(color) = Underline color (hex) + - B(color) = Background color (hex) + - S(color) = Strikethrough color (hex) + - O(color) = Overline color (hex) + - A(value) = Background alpha (1-65536 or 0%-100%) + - w(value) = Font weight (light/normal/bold/ultrabold or 100-1000) + + Examples: +GUI App only: + ${oU(#ff0000)L(double)}Error # Double red underline + ${a(50%)#00ff00}Semi-transparent green + Cross-platform: + ${\e[1;33m}Bold yellow + ${b#222222}${white}White on gray + ${auto3}The 3rd logo color + + Notes: + - customfetch will try to convert ANSI escape codes to GUI app equivalent + - customfetch will ignore GUI-specific modifiers on terminal. + - if you're using the GUI app and want to display a custom logo that's an image, all the auto colors will be the same colors as the distro ones. + +5. Percentage Tag ($%%) + Calculates and displays colored percentages. + + Syntax: $%value,total% or $%!value,total% (inverted colors) + + Examples: + - $%$<ram.used>,$<ram.total>% + - $%!50,100% (shows red if low) + - $%$(cat /sys/class/power_supply/BAT0/capacity),100% + +Pro Tip: +- Combine tags for powerful formatting: + ${u#5522dd}$[$(date +%H),12,Good ${yellow}morning,Good ${#ff8800}afternoon] + +FAQ: +Q: Why do special characters (&, <) break the GUI display? +A: Escape these characters with \\ (e.g replace "<" with "\\<" from both config and ASCII art): + This doesn't affect terminal output. + +Q: How can I use cbonsai as ASCII art? +A: 1. Create a text file containing: $(!cbonsai -p) + 2. Use: customfetch -s "/path/to/file.txt" + 3. Adjust offset for proper alignment + +Q: Does customfetch support nested tags? +A: Yes! Complex nesting is supported, for example: + $<disk($<disk($[1,1,$(echo -n $<disk(/).mountdir>),23]).mountdir>)> +)"); + +// default customfetch config +inline constexpr std::string_view AUTOCONFIG = R"#([config] + +# For more information on how customfetch works and the layout, +# Read either: +# * -w or --how-it-works +# * the manual customfetch.1 +# * if on the android app, click the button "how it works" during widget configuration +layout = [ + "$<title>", + "$<title.sep>", + "${auto}OS: $<os.name> $<system.arch>", + "${auto}Host: $<system.host>", + "${auto}Kernel: $<os.kernel>", + "${auto}Uptime: $<os.uptime>",)#" +#if !CF_ANDROID + R"#( + "${auto}Theme: $<theme.gtk.all.name>", + "${auto}Icons: $<theme.gtk.all.icon>", + "${auto}Font: $<theme.gtk.all.font>", + "${auto}Cursor: $<theme.cursor>", + "${auto}WM: $<user.wm.name>", + "${auto}DE: $<user.de.name>",)#" +#endif + R"#( + "$<auto.disk>", + "${auto}Swap: $<swap>", + "${auto}CPU: $<cpu>", + "${auto}GPU: $<gpu>", + "${auto}RAM: $<ram>", + "", + "$<colors>", # normal colors + "$<colors.light>" # light colors +] + +# display ascii-art or image/gif (GUI only) near layout +# put "os" for displaying the OS ascii-art +# or the "/path/to/file" for displaying custom files +# or "off" for disabling ascii-art or image displaying +source-path = "os" + +# Path to where we'll take all the distros/OSs ascii arts. +# note: it MUST contain an "ascii" subdirectory +data-dir = "/usr/share/customfetch" + +# The type of ASCII art to apply ("small", "old"). +# Basically will add "_<type>" to the logo filename. +# It will return the regular linux ascii art if it doesn't exist. +# Leave empty it for regular. +ascii-logo-type = "" + +# A char (or string) to use in $<title_sep> +title-sep = "-" + +# A separator (or string) that when encountered, will automatically +# reset color, aka. automatically add ${0} (only in layout) +# Make it empty for disabling +sep-reset = ":" + +# Should we reset color after or before the separator? +# true = after ("test ->${0} ") +# false = before ("test ${0}-> ") +sep-reset-after = false + +# Where the logo should be displayed. +# Values: "top" or "left" or "bottom" +logo-position = "left" + +# Offset between the ascii art and the layout +# Can also be rapresented as a %, but super unstable sometimes. +offset = "5" + +# Padding between the start and the ascii art +logo-padding-left = 0 + +# Padding of the ascii art from the top +logo-padding-top = 0 + +# Padding of the layout from the top +layout-padding-top = 0 + +# Usually in neofetch/fastfetch, when your terminal size is too small, +# to render some text in 1 line, they don't wrap those lines, instead they truncate them. +# Enable/Disable if you want this +wrap-lines = false + +# Used in disk, ram and swap modules. +# If true, we're going to use the SI standard byte unit (1kB == 1000 bytes) +# Else if false, we using the IEC byte unit (1KiB == 1024 bibytes) +# Really nerdy stuff +use-SI-byte-unit = false + +# Warn against tradeoffs between slower queries for availability +# e.g. falling back to gsettings when we can't find the config file for GTK +slow-query-warnings = false + +# Colors in the terminal (for Desktop/Android app, use the ones under [gui]) +black = "\e[1;30m" +red = "\e[1;31m" +green = "\e[1;32m" +yellow = "\e[1;33m" +blue = "\e[1;34m" +magenta = "\e[1;35m" +cyan = "\e[1;36m" +white = "\e[1;37m" + +# Alias colors. Basically more color variables. +# They can be used as like as the color tag. +# This is as like as using the --add-color argument +# Syntax must be "name=value", e.g "purple=magenta" or "orange=!#F08000" +alias-colors = ["purple=magenta"] + +# Colors to be used in percentage tag and modules members. +# They are used as if you're using the color tag. +# It's an array just for "convenience" +# 1st color for good +# 2nd color for normal +# 3rd color for bad +percentage-colors = ["green", "yellow", "red"] + +# $<auto.disk> config +[auto.disk] +# Format for displaying the auto detected disks infos +# %1 = mount directory +# %2 = device path +# %3 = type of filesystem +# %4 = total amount of storage +# %5 = free amount of storage +# %6 = used amount of storage +# %7 = percentage of used storage +# %8 = percentage of free storage +fmt = "${auto}Disk (%1): $<disk(%1)>" + +# Only print disks that matches the description +# of the following types: +# regular = Regular disks (internel M.2 SSD, ...) (won't be specified) +# external = External disks (USB, SATA, ...) +# read-only = Disks with read-only filesystems +# hidden = Disks that are not really mounted by the user +display-types = ["regular", "external", "read-only"] + +# In some OSes such as NixOS or Android, there might be some directories that are bind mounted. +# Bind mounted directories create an additional view of an existing directory, +# and `statfs()` on the mount point will return the filesystem statistics of the original directory. +show-duplicated = false + +# $<os.uptime> config +[os.uptime] +# how to display the name of the uptime +# e.g: hours = "hrs" -> "Uptime: 3hrs" +days = " days" +hours = " hours" +mins = " mins" +secs = " secs" + +# $<os.pkgs> config +[os.pkgs] +# Ordered list of which packages installed count should be displayed in $<os.pkgs> +# remember to not enter the same name twice, else the world will finish +# Choices: pacman, flatpak, dpkg, apk +# +# Pro-tip: if your package manager isn't listed here, yet, +# use the bash command tag in the layout +# e.g "Packages: $(pacman -Q | wc -l) (pacman)" +pkg-managers = ["pacman", "dpkg", "flatpak"] + +# Distros and package manager specific +# package manager paths for getting the packages count from path. +# They are arrays so you can add multiple paths. +# +# If you don't know what these ares, leave them by default settings +pacman-dirs = ["/var/lib/pacman/local/"] +dpkg-files = ["/var/lib/dpkg/status", "/data/data/com.termux/files/usr/var/lib/dpkg/status"] +flatpak-dirs = ["/var/lib/flatpak/app/", "~/.local/share/flatpak/app/"] +apk-files = ["/var/lib/apk/db/installed"] + +# Desktop/Android app options +[gui] + +# These are the colors you can use in the GUI mode. +# They overwrite the terminal colors from above. +# They can only have hexcodes colors and its modifiers +black = "!#000005" +red = "!#ff2000" +green = "!#00ff00" +blue = "!#00aaff" +cyan = "!#00ffff" +yellow = "!#ffff00" +magenta = "!#f881ff" +white = "!#ffffff" + +# Path to image as a background. +# put "disable" for disabling and use the theme color as background. +bg-image = "disable" + +# Path to gtk css file to be used. +# put "disable" for disabling. +gtk-css = "disable" + +)#"; + +inline constexpr std::string_view AUTO_MANIFEST = R"([repository] +# The repositry name. +# It must contain only alpha-numeric characters and symbols such as '-' or '_' +name = "repo_name" + +# The repository git clone / homepage url. +url = "https://github.com/user/repo" + +# Platform-dependent packages required to build all plugins in this repository. +# NOTE: This will ONLY tell the user which packages are missing; +# it will not actually install them. +# +# Use the "all" key for dependencies common to every platform. +# Current platforms: all, linux, macos, android +[dependencies] +all = ["pkg-config", "cmake"] +linux = ["wayland-protocols", "xorg-dev"] +android = ["ndk-build"] +macos = ["brew:gtk+3"] + +# From now on, each table that is neiter "repository" nor "dependencies" will be treated as a plugin entry. +# The tables' names still must conform alpha-numeric characters and symbols such as '-' or '_' +[test-plugin] + +# The plugin description. +description = "Test plugin" + +# The plugin authors. +authors = ["user1", "friend_user1"] + +# The plugin SPDX License Identifiers (not validated) +licenses = ["MIT", "GPL-2.0"] + +# A list of registered root modules the plugin can provide. +prefixes = ["github", "git"] + +# What platforms are supported by the plugin (case-sensitive). +# Use just ["all"] for cross-platform plugins. +# Current platforms: all, linux, macos, android +platforms = ["all"] + +# The directory where the final plugin output shall be seen. +# It will be evaluated/checked after building the plugin library. +# The path is relative to the repository root unless absolute. +output-dir = "build/plugin-dir/" + +# A list of commands to be executed for building the plugin. +# Kinda like a Makefile target instructions. +# Each command runs independently (not in a shared shell). Use absolute paths or repeat exports if needed. +build-steps = [ + "make -C ./test-plugin-entry/", + "mkdir -p ./build/plugin-dir/", + "mv ./test-plugin-entry/library.so ./build/plugin-dir/library.so" +])"; + +#endif // !_TEXTS_HPP_ diff --git a/src/config.cpp b/src/config.cpp index b56f9532..97cd3fba 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -29,6 +29,7 @@ #include <filesystem> #include <string> +#include "texts.hpp" #include "fmt/os.h" #include "util.hpp" diff --git a/src/main.cpp b/src/main.cpp index a345925d..dad55a6d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -37,6 +37,8 @@ #include <thread> #include <vector> +#include "libcufetch/fmt/compile.h" +#include "texts.hpp" #include "getopt_port/getopt.h" #include "core-modules.hh" #include "display.hpp" @@ -122,86 +124,7 @@ static void version() // Print the args help menu, then exit with code depending if it's from invalid or -h arg static void help(bool invalid_opt = false) { - constexpr std::string_view help( - R"(Usage: customfetch [OPTIONS]... -A command-line, GUI app, and Android widget system information tool (like neofetch) focused on customizability and performance. - -NOTE: Boolean flags [<BOOL>] accept: "true", 1, "enable", or empty. Any other value is treated as false. - -GENERAL OPTIONS: - -h, --help Print this help menu. - -V, --version Print version and other infos about the build. - -C, --config <PATH> Path to the config file (default: ~/.config/customfetch/config.toml). - - --gen-config [<PATH>] Generate default config file. If PATH is omitted, saves to default location. - Prompts before overwriting. - -LOGO OPTIONS: - -n, --no-logo Disable logo display. - -L, --logo-only Print only the logo (skip layout completely). - -s, --source-path <PATH> Path to custom ASCII art/image file. - - -a, --ascii-logo-type <TYPE> - Type of ASCII art (typically "small", "old", or empty for default). - Example: "-d arch -a older" looks for "arch_older.txt". - - -D, --data-dir <PATH> Path to data directory containing "ascii/" subfolder with distro logos. - -d, --distro <NAME> Use a custom distro logo (case-insensitive, e.g., "windows 11" or "ArCh"). - -p, --logo-position <POS> Logo position: "top" (default), "left", or "bottom". - -o, --offset <NUM> Space between logo and layout (default: 5). - --logo-padding-top <NUM> Logo padding from top (default: 0). - --logo-padding-left <NUM> Logo padding from left (default: 0). - -LAYOUT & FORMATTING: - -m, --layout-line <STRING> Override config layout with custom line(s). - Example: `-m "${auto}OS: $<os.name>" -m "${auto}CPU: $<cpu>"`. - - -N, --no-color Disable all colors (useful for pipes/scripts). - --layout-padding-top <NUM> Layout padding from top (default: 0). - --wrap-lines=[<BOOL>] Enable terminal line wrapping (default: false). - --title-sep <STRING> String to use for $<title.sep> (default: "-"). - --sep-reset <STRING> String that resets color (default: ":"). - --sep-reset-after=[<BOOL>] Reset color after (default) or before 'sep-reset'. - -GUI/TERMINAL OPTIONS: - -f, --font <STRING> GUI font (format: "FAMILY STYLE SIZE", e.g., "Liberation Mono Normal 12"). - -i, --image-backend <NAME> Terminal image backend ("kitty" or "viu"). - --bg-image <PATH> GUI background image path ("disable" to turn off). - -CONFIG: - -O, --override <STRING> Override a config value (non-array). Syntax: "name=value" (no spaces around "="). - Example: "auto.disk.fmt='Disk(%1): %6'". - Note: Names without dots (e.g., "sep-reset-after") gets auto-appended to "config.". - - --color <STRING> Replace a color globally. Syntax: "name=value" (no spaces around "="). - Example: "--color magenta=#FF00FF". - - --disallow-command-tag Do not allow command tags $() to be executed. - This is a safety measure for preventing malicious code to be executed because you didn't want to check the config first. - -INFORMATIONAL: - -l, --list-modules List all available info tag modules (e.g., $<cpu> or $<os.name>). - -w, --how-it-works Explain tags and general customization. - --list-logos List available ASCII logos in --data-dir. - -LIVE MODE: - --loop-ms <NUM> Run in live mode, updating every <NUM> milliseconds (min: 50). - Use inferior <NUM> than 200 to disable. Press 'q' to exit. - -EXAMPLES: - 1. Minimal output with default logo: - customfetch --no-color - - 2. Custom distro logo with live updates: - customfetch --distro "arch" --loop-ms 1000 - - 3. Override layout and colors: - customfetch -m "${magenta}OS: $<os.name>" --color "magenta=#FF00FF" - -For details, see `man customfetch` or run `--how-it-works`. -)"); - - fmt::print("{}", help); + fmt::print(FMT_COMPILE("{}"), customfetch_help); fmt::print("\n"); std::exit(invalid_opt); } @@ -209,119 +132,7 @@ For details, see `man customfetch` or run `--how-it-works`. // Print how customfetch works, then exit successfully static void explain_how_this_works() { - constexpr std::string_view str( - R"( -customfetch is designed for maximum customizability, allowing users to display system information exactly how they want it. -The layout and logo is controlled through special tags that can output system info, execute commands, apply conditional logic, add colors, and calculate percentages with some colors. - -Tag References: -1. Information Tag ($<>) - Retrieves system information from modules. - - Syntax: $<module.submodule.sub...> or $<module> - - Examples: - - $<user.name> # Displays login username - - $<os.kernel.name> # Shows kernel name only - - $<ram> # Shows formatted RAM usage - - Use `--list-modules` to see all available modules and members. - -2. Bash Command Tag ($()) - Executes shell commands and outputs the result. - Supports full shell syntax including pipes and redirection. - - Syntax: $(command) - - Examples: - - $(echo "hello") # Outputs: hello - - $(date +%F) # Shows current date - - $(uname -r | cut -d'-' -f1) # Shows kernel version number only - -3. Conditional Tag ($[]) - Displays different outputs based on conditions. - - Syntax: $[condition,comparison,true_output,false_output] - - Examples: - - $[$<user.name>,toni,Welcome back!,Access denied] - - $[$(date +%m-%d),12-25,Merry Christmas!,] - - $[$<os.name.id>,arch,${green}I use arch btw,${red}Non-arch user] - -4. Color Tag (${}) - Applies colors and text formatting. - - Basic syntax: ${color} or ${modifiers#RRGGBB} - - Color options: - - Named colors from config - - Hex colors: ${#ff00cc} - - Special colors: ${auto} (uses logo colors) - - Reset styles: ${0} (normal), ${1} (bold reset) - - Formatting modifiers (prefix before hexcolor): - - ! = Bold - - u = Underline - - i = Italic - - s = Strikethrough - - l = Blink (terminal only) - - b = Background color - - Advanced GUI-only modifiers: - - o = Overline - - a(value) = Foreground alpha (1-65536 or 0%-100%) - - L(value) = Underline style (none/single/double/low/error) - - U(color) = Underline color (hex) - - B(color) = Background color (hex) - - S(color) = Strikethrough color (hex) - - O(color) = Overline color (hex) - - A(value) = Background alpha (1-65536 or 0%-100%) - - w(value) = Font weight (light/normal/bold/ultrabold or 100-1000) - - Examples: - GUI App only: - ${oU(#ff0000)L(double)}Error # Double red underline - ${a(50%)#00ff00}Semi-transparent green - Cross-platform: - ${\e[1;33m}Bold yellow - ${b#222222}${white}White on gray - ${auto3}The 3rd logo color - - Notes: - - customfetch will try to convert ANSI escape codes to GUI app equivalent - - customfetch will ignore GUI-specific modifiers on terminal. - - if you're using the GUI app and want to display a custom logo that's an image, all the auto colors will be the same colors as the distro ones. - -5. Percentage Tag ($%%) - Calculates and displays colored percentages. - - Syntax: $%value,total% or $%!value,total% (inverted colors) - - Examples: - - $%$<ram.used>,$<ram.total>% - - $%!50,100% (shows red if low) - - $%$(cat /sys/class/power_supply/BAT0/capacity),100% - -Pro Tip: -- Combine tags for powerful formatting: - ${u#5522dd}$[$(date +%H),12,Good ${yellow}morning,Good ${#ff8800}afternoon] - -FAQ: -Q: Why do special characters (&, <) break the GUI display? -A: Escape these characters with \\ (e.g replace "<" with "\\<" from both config and ASCII art): - This doesn't affect terminal output. - -Q: How can I use cbonsai as ASCII art? -A: 1. Create a text file containing: $(!cbonsai -p) - 2. Use: customfetch -s "/path/to/file.txt" - 3. Adjust offset for proper alignment - -Q: Does customfetch support nested tags? -A: Yes! Complex nesting is supported, for example: - $<disk($<disk($[1,1,$(echo -n $<disk(/).mountdir>),23]).mountdir>)> -)"); - - fmt::print("{}", str); + fmt::print(FMT_COMPILE("{}"), explain_customfetch); fmt::print("\n"); std::exit(EXIT_SUCCESS); } From 9e5653e0152e476712bc1b887d264df3a863c376 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Thu, 31 Jul 2025 18:22:45 +0200 Subject: [PATCH 130/143] cufetchpm: manifest: add supported platforms check and dependencies --- cufetchpm/include/manifest.hpp | 24 +++++++++++++++- cufetchpm/include/pluginManager.hpp | 4 +-- cufetchpm/src/main.cpp | 4 +-- cufetchpm/src/manifest.cpp | 37 +++++++++++++++++-------- cufetchpm/src/pluginManager.cpp | 43 +++++++++++++++++++++++++---- 5 files changed, 89 insertions(+), 23 deletions(-) diff --git a/cufetchpm/include/manifest.hpp b/cufetchpm/include/manifest.hpp index 17411b8b..c62c1fa4 100644 --- a/cufetchpm/include/manifest.hpp +++ b/cufetchpm/include/manifest.hpp @@ -6,8 +6,17 @@ #include <utility> #include <vector> +#include "platform.hpp" #include "toml++/toml.hpp" +#if CF_LINUX +constexpr char PLATFORM[] = "linux"; +#elif CF_MACOS +constexpr char PLATFORM[] = "macos"; +#elif CF_ANDROID +constexpr char PLATFORM[] = "android"; +#endif + struct plugin_t { // The plugin name. @@ -26,6 +35,7 @@ struct plugin_t std::vector<std::string> licenses; // Which plugins can be conflicting by name / modules, using the git url. + // right now not used. std::vector<std::string> conflicts; // The plugin authors. @@ -39,6 +49,10 @@ struct plugin_t // A list of registered root modules that the plugin will be used for querying its submodules. // For example: 'github.followers' the root module is indeed 'github' and 'followers' is the submodule. std::vector<std::string> prefixes; + + // Platforms that are supported by the plugin. + // Make it a string and put 'all' for being cross-platform. + std::vector<std::string> platforms; }; struct manifest_t @@ -47,11 +61,16 @@ struct manifest_t // It must be conform to the function is_valid_name() std::string name; - // The repository git/homepage url + // The repository git url std::string url; // An array of all the plugins that are declared in the manifest std::vector<plugin_t> plugins; + + // An array for storing the dependencies for 'all' and current platforms. + // first -> platform string name + // seconds -> platform dependencies vector names + std::vector<std::string> dependencies; }; constexpr char const MANIFEST_NAME[] = "cufetchpm.toml"; @@ -83,6 +102,9 @@ class CManifest const std::vector<plugin_t>& get_all_plugins() const { return m_repo.plugins; } + const std::vector<std::string>& get_dependencies() const + { return m_repo.dependencies; } + private: toml::table m_tbl; manifest_t m_repo; diff --git a/cufetchpm/include/pluginManager.hpp b/cufetchpm/include/pluginManager.hpp index 7341b9f6..6035e320 100644 --- a/cufetchpm/include/pluginManager.hpp +++ b/cufetchpm/include/pluginManager.hpp @@ -11,7 +11,7 @@ namespace fs = std::filesystem; -constexpr std::string_view dependencies[] = { "git" }; // expand in the future, maybe +inline const std::vector<std::string> core_dependencies = { "git" }; // expand in the future, maybe inline struct operations_t { @@ -47,7 +47,7 @@ class PluginManager void add_repo_plugins(const std::string& repo); void build_plugins(const fs::path& working_dir); bool add_plugin(const std::string&); - bool has_deps(); + bool has_deps(const std::vector<std::string>& dependencies); private: StateManager m_state_manager; diff --git a/cufetchpm/src/main.cpp b/cufetchpm/src/main.cpp index 35fc9392..2762b505 100644 --- a/cufetchpm/src/main.cpp +++ b/cufetchpm/src/main.cpp @@ -1,10 +1,10 @@ #include <cstdlib> #include <filesystem> +#include "fmt/compile.h" +#include "fmt/os.h" #include "fmt/ranges.h" #include "libcufetch/common.hh" -#include "fmt/os.h" -#include "fmt/compile.h" #include "pluginManager.hpp" #include "stateManager.hpp" #include "texts.hpp" diff --git a/cufetchpm/src/manifest.cpp b/cufetchpm/src/manifest.cpp index ae509dc1..2bececfa 100644 --- a/cufetchpm/src/manifest.cpp +++ b/cufetchpm/src/manifest.cpp @@ -87,9 +87,28 @@ void CManifest::parse_manifest() die("Manifest repository name '{}' is invalid. Only alphanumeric and '-', '_', '=' are allowed in the name", m_repo.name); + if (auto deps = m_tbl["dependencies"].as_table()) + { + // Collect "all" dependencies + if (auto arr = (*deps)["all"].as_array()) + { + for (auto&& pkg : *arr) + if (auto s = pkg.value<std::string>()) + m_repo.dependencies.push_back(*s); + } + + // Collect platform-specific dependencies + if (auto arr = (*deps)[PLATFORM].as_array()) + { + for (auto&& pkg : *arr) + if (auto s = pkg.value<std::string>()) + m_repo.dependencies.push_back(*s); + } + } + for (const auto& [name, _] : m_tbl) { - if (name.str() == "repository") + if (name.str() == "repository" || name.str() == "dependencies") continue; if (!is_valid_name(name.str())) @@ -99,21 +118,14 @@ void CManifest::parse_manifest() continue; } - m_repo.plugins.push_back({ .name = name.data(), - .description = getStrValue(name, "description"), - .output_dir = getStrValue(name, "output-dir"), - .licenses = getStrArrayValue(name, "licenses"), - .conflicts = getStrArrayValue(name, "conflicts"), - .authors = getStrArrayValue(name, "authors"), - .build_steps = getStrArrayValue(name, "build-steps"), - .prefixes = getStrArrayValue(name, "prefixes") }); + m_repo.plugins.push_back(get_plugin(name)); } } plugin_t CManifest::get_plugin(const std::string_view name) { - if (!m_tbl[name].is_table()) - die("Couldn't find such plugin '{}' in manifest", name); + // if (!m_tbl[name].is_table()) + // die("Couldn't find such plugin '{}' in manifest", name); return { .name = name.data(), .description = getStrValue(name, "description"), @@ -122,5 +134,6 @@ plugin_t CManifest::get_plugin(const std::string_view name) .conflicts = getStrArrayValue(name, "conflicts"), .authors = getStrArrayValue(name, "authors"), .build_steps = getStrArrayValue(name, "build-steps"), - .prefixes = getStrArrayValue(name, "prefixes") }; + .prefixes = getStrArrayValue(name, "prefixes"), + .platforms = getStrArrayValue(name, "platforms") }; } diff --git a/cufetchpm/src/pluginManager.cpp b/cufetchpm/src/pluginManager.cpp index 3abb1843..1853eaf4 100644 --- a/cufetchpm/src/pluginManager.cpp +++ b/cufetchpm/src/pluginManager.cpp @@ -1,5 +1,6 @@ #include "pluginManager.hpp" +#include <algorithm> #include <cstdio> #include <cstdlib> #include <filesystem> @@ -9,17 +10,17 @@ #include <vector> #include "fmt/format.h" +#include "fmt/ranges.h" #include "libcufetch/common.hh" #include "manifest.hpp" #include "tiny-process-library/process.hpp" #include "util.hpp" -// #include "fmt/ranges.h" using namespace TinyProcessLib; -bool PluginManager::has_deps() +bool PluginManager::has_deps(const std::vector<std::string>& dependencies) { - for (const std::string_view bin : dependencies) + for (const std::string& bin : dependencies) { Process proc( fmt::format("command -v {}", bin), "", [](const char*, size_t) {}, // discard stdout @@ -33,8 +34,8 @@ bool PluginManager::has_deps() void PluginManager::add_repo_plugins(const std::string& repo) { - if (!has_deps()) - die("Not all dependencies have been installed. You'll need to install git"); // fmt::join(dependencies, ", ")); + if (!has_deps(core_dependencies)) + die("Some core dependencies are not installed. You'll need to install: {}", fmt::join(core_dependencies, ", ")); static std::random_device rd; static std::mt19937 gen(rd()); @@ -57,6 +58,8 @@ void PluginManager::add_repo_plugins(const std::string& repo) void PluginManager::build_plugins(const fs::path& working_dir) { + std::vector<std::string> non_supported_plugins; + // cd to the working directory and parse its manifest fs::current_path(working_dir); CManifest manifest(MANIFEST_NAME); @@ -83,10 +86,33 @@ void PluginManager::build_plugins(const fs::path& working_dir) die("Looks like there are no plugins to build with '{}'", manifest.get_repo_name()); } + if (!has_deps(manifest.get_dependencies())) + { + fs::remove_all(working_dir); + die("Some dependencies for repository '{}' are not installed. The repository requires the following: {}", + manifest.get_repo_name(), fmt::join(manifest.get_dependencies(), ", ")); + } + // build each plugin from the manifest // and add the infos to the state.toml for (const plugin_t& plugin : manifest.get_all_plugins()) { + bool found_platform = false; + + if (plugin.platforms[0] != "all") + { + for (const std::string& plugin_platform : plugin.platforms) + if (plugin_platform == PLATFORM) + found_platform = true; + + if (!found_platform) + { + warn("Plugin '{}' doesn't support the platform '{}'. Skipping", plugin.name, PLATFORM); + non_supported_plugins.push_back(plugin.name); + continue; + } + } + status("Trying to build plugin '{}'", plugin.name); for (const std::string& bs : plugin.build_steps) { @@ -111,6 +137,11 @@ void PluginManager::build_plugins(const fs::path& working_dir) status("Moving each built plugin to '{}'", plugins_config_path.string()); for (const plugin_t& plugin : manifest.get_all_plugins()) { + // already told before + if (std::find(non_supported_plugins.begin(), non_supported_plugins.end(), plugin.name) != + non_supported_plugins.end()) + continue; + // ugh, devs fault. Report this error to them if (!fs::exists(plugin.output_dir)) { @@ -123,7 +154,7 @@ void PluginManager::build_plugins(const fs::path& working_dir) { // ~/.config/customfetch/plugins/<plugin-directory>/<plugin-filename> const fs::path& library_config_path = plugins_config_path / library.path().filename(); - if (fs::exists(library_config_path)) + if (fs::exists(library_config_path) && !options.install_force) { if (askUserYorN(false, "Plugin '{}' already exists. Replace it?", library_config_path.string())) fs::remove_all(library_config_path); From 6216cb44810403f9ba17e3817e2c4ee557c61682 Mon Sep 17 00:00:00 2001 From: Toni500github <88878648+Toni500github@users.noreply.github.com> Date: Thu, 31 Jul 2025 21:00:02 +0200 Subject: [PATCH 131/143] workflow: fix cmake.yml --- .github/workflows/cmake.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index d5c8d6d6..c93d6dfd 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -2,9 +2,9 @@ name: CMake CI (Test customfetch) on: push: - branches: [ "main" ] + branches: [ "main", "plugins" ] pull_request: - branches: [ "main" ] + branches: [ "main", "plugins" ] jobs: build-ubuntu_22-04: @@ -45,7 +45,7 @@ jobs: printf "getting 0x5353 hexcode\n" && grep -nri "5353" /sys/class/ || true - name: Test customfetch - run: customfetch --wrap-lines + run: LD_LIBRARY_PATH="./build:$LD_LIBRARY_PATH" customfetch --wrap-lines - name: Upload to github artifacts uses: actions/upload-artifact@v4 @@ -83,7 +83,7 @@ jobs: run: neofetch - name: Test customfetch - run: customfetch-gui --version + run: LD_LIBRARY_PATH="./build:$LD_LIBRARY_PATH" customfetch-gui --version - name: Upload to github artifacts uses: actions/upload-artifact@v4 @@ -136,7 +136,7 @@ jobs: printf "/etc/os-release\n" && cat /etc/os-release - name: Test customfetch - run: customfetch --wrap-lines + run: LD_LIBRARY_PATH="./build:$LD_LIBRARY_PATH" customfetch --wrap-lines build-macos: runs-on: macos-latest @@ -169,7 +169,7 @@ jobs: run: fastfetch - name: Test customfetch - run: ./build/customfetch -D assets + run: LD_LIBRARY_PATH="./build:$LD_LIBRARY_PATH" ./build/customfetch -D assets - name: Upload to github artifacts uses: actions/upload-artifact@v4 From 34bcff83b863f72311f92b930e58ea65a4c9ba67 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Thu, 31 Jul 2025 21:05:57 +0200 Subject: [PATCH 132/143] misc: add missing license notice in source files --- cufetchpm/include/manifest.hpp | 25 +++++++++++++++++++++++++ cufetchpm/include/pluginManager.hpp | 25 +++++++++++++++++++++++++ cufetchpm/include/stateManager.hpp | 25 +++++++++++++++++++++++++ cufetchpm/src/main.cpp | 25 +++++++++++++++++++++++++ cufetchpm/src/manifest.cpp | 25 +++++++++++++++++++++++++ cufetchpm/src/pluginManager.cpp | 25 +++++++++++++++++++++++++ cufetchpm/src/stateManager.cpp | 25 +++++++++++++++++++++++++ include/core-modules.hh | 25 +++++++++++++++++++++++++ include/libcufetch/common.hh | 25 +++++++++++++++++++++++++ include/platform.hpp | 25 +++++++++++++++++++++++++ include/texts.hpp | 25 +++++++++++++++++++++++++ src/core-modules/android/battery.cc | 25 +++++++++++++++++++++++++ src/core-modules/android/gpu.cc | 25 +++++++++++++++++++++++++ src/core-modules/android/os.cc | 25 +++++++++++++++++++++++++ src/core-modules/android/system.cc | 25 +++++++++++++++++++++++++ src/core-modules/android/theme.cc | 25 +++++++++++++++++++++++++ src/core-modules/android/user.cc | 25 +++++++++++++++++++++++++ src/core-modules/core-modules.cc | 25 +++++++++++++++++++++++++ src/core-modules/linux/battery.cc | 25 +++++++++++++++++++++++++ src/core-modules/linux/disk.cc | 25 +++++++++++++++++++++++++ src/core-modules/linux/gpu.cc | 25 +++++++++++++++++++++++++ src/core-modules/linux/ram.cc | 25 +++++++++++++++++++++++++ src/core-modules/linux/system.cc | 25 +++++++++++++++++++++++++ src/core-modules/linux/theme.cc | 25 +++++++++++++++++++++++++ src/core-modules/linux/user.cc | 25 +++++++++++++++++++++++++ src/core-modules/linux/utils/term.hh | 25 +++++++++++++++++++++++++ src/core-modules/macos/battery.cc | 25 +++++++++++++++++++++++++ src/core-modules/macos/cpu.cc | 25 +++++++++++++++++++++++++ src/core-modules/macos/disk.cc | 25 +++++++++++++++++++++++++ src/core-modules/macos/gpu.cc | 25 +++++++++++++++++++++++++ src/core-modules/macos/os.cc | 25 +++++++++++++++++++++++++ src/core-modules/macos/ram.cc | 25 +++++++++++++++++++++++++ src/core-modules/macos/system.cc | 25 +++++++++++++++++++++++++ src/core-modules/macos/theme.cc | 25 +++++++++++++++++++++++++ tests/test_util.cpp | 25 +++++++++++++++++++++++++ 35 files changed, 875 insertions(+) diff --git a/cufetchpm/include/manifest.hpp b/cufetchpm/include/manifest.hpp index c62c1fa4..ad90e503 100644 --- a/cufetchpm/include/manifest.hpp +++ b/cufetchpm/include/manifest.hpp @@ -1,3 +1,28 @@ +/* + * Copyright 2025 Toni500git + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + #ifndef _MANIFEST_HPP_ #define _MANIFEST_HPP_ diff --git a/cufetchpm/include/pluginManager.hpp b/cufetchpm/include/pluginManager.hpp index 6035e320..6f2c1019 100644 --- a/cufetchpm/include/pluginManager.hpp +++ b/cufetchpm/include/pluginManager.hpp @@ -1,3 +1,28 @@ +/* + * Copyright 2025 Toni500git + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + #ifndef _PLUGIN_MANAGER_HPP_ #define _PLUGIN_MANAGER_HPP_ diff --git a/cufetchpm/include/stateManager.hpp b/cufetchpm/include/stateManager.hpp index f288b25f..ac87b0f9 100644 --- a/cufetchpm/include/stateManager.hpp +++ b/cufetchpm/include/stateManager.hpp @@ -1,3 +1,28 @@ +/* + * Copyright 2025 Toni500git + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + #ifndef _STATE_MANAGER_HPP_ #define _STATE_MANAGER_HPP_ diff --git a/cufetchpm/src/main.cpp b/cufetchpm/src/main.cpp index 2762b505..75b07b01 100644 --- a/cufetchpm/src/main.cpp +++ b/cufetchpm/src/main.cpp @@ -1,3 +1,28 @@ +/* + * Copyright 2025 Toni500git + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + #include <cstdlib> #include <filesystem> diff --git a/cufetchpm/src/manifest.cpp b/cufetchpm/src/manifest.cpp index 2bececfa..e7f199ac 100644 --- a/cufetchpm/src/manifest.cpp +++ b/cufetchpm/src/manifest.cpp @@ -1,3 +1,28 @@ +/* + * Copyright 2025 Toni500git + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + #include "manifest.hpp" #include <algorithm> diff --git a/cufetchpm/src/pluginManager.cpp b/cufetchpm/src/pluginManager.cpp index 1853eaf4..ceea8cd1 100644 --- a/cufetchpm/src/pluginManager.cpp +++ b/cufetchpm/src/pluginManager.cpp @@ -1,3 +1,28 @@ +/* + * Copyright 2025 Toni500git + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + #include "pluginManager.hpp" #include <algorithm> diff --git a/cufetchpm/src/stateManager.cpp b/cufetchpm/src/stateManager.cpp index 4e65fc85..161ca1a3 100644 --- a/cufetchpm/src/stateManager.cpp +++ b/cufetchpm/src/stateManager.cpp @@ -1,3 +1,28 @@ +/* + * Copyright 2025 Toni500git + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + #include "stateManager.hpp" #include <filesystem> diff --git a/include/core-modules.hh b/include/core-modules.hh index 1cb8d881..18951027 100644 --- a/include/core-modules.hh +++ b/include/core-modules.hh @@ -1,3 +1,28 @@ +/* + * Copyright 2025 Toni500git + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + #pragma once #include <pwd.h> diff --git a/include/libcufetch/common.hh b/include/libcufetch/common.hh index 66870749..0468d620 100644 --- a/include/libcufetch/common.hh +++ b/include/libcufetch/common.hh @@ -1,3 +1,28 @@ +/* + * Copyright 2025 Toni500git + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + #pragma once #include <cstdlib> diff --git a/include/platform.hpp b/include/platform.hpp index 30d9f8ff..4656d13a 100644 --- a/include/platform.hpp +++ b/include/platform.hpp @@ -1,3 +1,28 @@ +/* + * Copyright 2025 Toni500git + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + #ifndef _PLATFORM_H_ #define _PLATFORM_H_ diff --git a/include/texts.hpp b/include/texts.hpp index e642eaa9..6f9ed221 100644 --- a/include/texts.hpp +++ b/include/texts.hpp @@ -1,3 +1,28 @@ +/* + * Copyright 2025 Toni500git + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + #ifndef _TEXTS_HPP_ #define _TEXTS_HPP_ diff --git a/src/core-modules/android/battery.cc b/src/core-modules/android/battery.cc index 70df0624..1a63add9 100644 --- a/src/core-modules/android/battery.cc +++ b/src/core-modules/android/battery.cc @@ -1,3 +1,28 @@ +/* + * Copyright 2025 Toni500git + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + #include "platform.hpp" #if CF_ANDROID diff --git a/src/core-modules/android/gpu.cc b/src/core-modules/android/gpu.cc index 0668cdcf..c6d0a395 100644 --- a/src/core-modules/android/gpu.cc +++ b/src/core-modules/android/gpu.cc @@ -1,3 +1,28 @@ +/* + * Copyright 2025 Toni500git + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + #include "platform.hpp" #if CF_ANDROID diff --git a/src/core-modules/android/os.cc b/src/core-modules/android/os.cc index 149bab12..0da4ae4d 100644 --- a/src/core-modules/android/os.cc +++ b/src/core-modules/android/os.cc @@ -1,3 +1,28 @@ +/* + * Copyright 2025 Toni500git + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + #include "platform.hpp" #if CF_ANDROID diff --git a/src/core-modules/android/system.cc b/src/core-modules/android/system.cc index e3b6d4b1..197c0598 100644 --- a/src/core-modules/android/system.cc +++ b/src/core-modules/android/system.cc @@ -1,3 +1,28 @@ +/* + * Copyright 2025 Toni500git + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + #include "platform.hpp" #if CF_ANDROID diff --git a/src/core-modules/android/theme.cc b/src/core-modules/android/theme.cc index ef6b867c..9fc2e589 100644 --- a/src/core-modules/android/theme.cc +++ b/src/core-modules/android/theme.cc @@ -1,3 +1,28 @@ +/* + * Copyright 2025 Toni500git + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + #include "platform.hpp" #if CF_ANDROID diff --git a/src/core-modules/android/user.cc b/src/core-modules/android/user.cc index 79220458..8d3f9ed7 100644 --- a/src/core-modules/android/user.cc +++ b/src/core-modules/android/user.cc @@ -1,3 +1,28 @@ +/* + * Copyright 2025 Toni500git + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + #include "platform.hpp" #if CF_ANDROID diff --git a/src/core-modules/core-modules.cc b/src/core-modules/core-modules.cc index 92831794..5ca079ce 100644 --- a/src/core-modules/core-modules.cc +++ b/src/core-modules/core-modules.cc @@ -1,3 +1,28 @@ +/* + * Copyright 2025 Toni500git + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + #include "core-modules.hh" #include <dlfcn.h> diff --git a/src/core-modules/linux/battery.cc b/src/core-modules/linux/battery.cc index ee274e3b..eab5aa8c 100644 --- a/src/core-modules/linux/battery.cc +++ b/src/core-modules/linux/battery.cc @@ -1,3 +1,28 @@ +/* + * Copyright 2025 Toni500git + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + #include "platform.hpp" #if CF_LINUX diff --git a/src/core-modules/linux/disk.cc b/src/core-modules/linux/disk.cc index 07fe5fd6..765e0c3c 100644 --- a/src/core-modules/linux/disk.cc +++ b/src/core-modules/linux/disk.cc @@ -1,3 +1,28 @@ +/* + * Copyright 2025 Toni500git + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + #include "platform.hpp" #if CF_LINUX || CF_ANDROID diff --git a/src/core-modules/linux/gpu.cc b/src/core-modules/linux/gpu.cc index 4f816abf..e3aee59d 100644 --- a/src/core-modules/linux/gpu.cc +++ b/src/core-modules/linux/gpu.cc @@ -1,3 +1,28 @@ +/* + * Copyright 2025 Toni500git + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + #include "platform.hpp" #if CF_LINUX diff --git a/src/core-modules/linux/ram.cc b/src/core-modules/linux/ram.cc index 9577f4f7..27f8873e 100644 --- a/src/core-modules/linux/ram.cc +++ b/src/core-modules/linux/ram.cc @@ -1,3 +1,28 @@ +/* + * Copyright 2025 Toni500git + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + #include "platform.hpp" #if CF_LINUX || CF_ANDROID diff --git a/src/core-modules/linux/system.cc b/src/core-modules/linux/system.cc index e8a0d9ad..adf73019 100644 --- a/src/core-modules/linux/system.cc +++ b/src/core-modules/linux/system.cc @@ -1,3 +1,28 @@ +/* + * Copyright 2025 Toni500git + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + #include "platform.hpp" #if CF_LINUX diff --git a/src/core-modules/linux/theme.cc b/src/core-modules/linux/theme.cc index 0abec032..de6eb50d 100644 --- a/src/core-modules/linux/theme.cc +++ b/src/core-modules/linux/theme.cc @@ -1,3 +1,28 @@ +/* + * Copyright 2025 Toni500git + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + #include "platform.hpp" #if CF_LINUX diff --git a/src/core-modules/linux/user.cc b/src/core-modules/linux/user.cc index 29d055cb..89acba32 100644 --- a/src/core-modules/linux/user.cc +++ b/src/core-modules/linux/user.cc @@ -1,3 +1,28 @@ +/* + * Copyright 2025 Toni500git + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + #include "platform.hpp" #if CF_LINUX || CF_MACOS diff --git a/src/core-modules/linux/utils/term.hh b/src/core-modules/linux/utils/term.hh index 82e51fe5..47397aee 100644 --- a/src/core-modules/linux/utils/term.hh +++ b/src/core-modules/linux/utils/term.hh @@ -1,3 +1,28 @@ +/* + * Copyright 2025 Toni500git + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + #ifndef _TERM_HPP #define _TERM_HPP diff --git a/src/core-modules/macos/battery.cc b/src/core-modules/macos/battery.cc index 0ecff735..36775e26 100644 --- a/src/core-modules/macos/battery.cc +++ b/src/core-modules/macos/battery.cc @@ -1,3 +1,28 @@ +/* + * Copyright 2025 Toni500git + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + #include "platform.hpp" #if CF_MACOS diff --git a/src/core-modules/macos/cpu.cc b/src/core-modules/macos/cpu.cc index bb2850c1..0bc25a5f 100644 --- a/src/core-modules/macos/cpu.cc +++ b/src/core-modules/macos/cpu.cc @@ -1,3 +1,28 @@ +/* + * Copyright 2025 Toni500git + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + #include "platform.hpp" #if CF_MACOS diff --git a/src/core-modules/macos/disk.cc b/src/core-modules/macos/disk.cc index f1be7d7f..1a3efaf7 100644 --- a/src/core-modules/macos/disk.cc +++ b/src/core-modules/macos/disk.cc @@ -1,3 +1,28 @@ +/* + * Copyright 2025 Toni500git + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + #include "platform.hpp" #if CF_MACOS diff --git a/src/core-modules/macos/gpu.cc b/src/core-modules/macos/gpu.cc index f8bbf69b..54f40c18 100644 --- a/src/core-modules/macos/gpu.cc +++ b/src/core-modules/macos/gpu.cc @@ -1,3 +1,28 @@ +/* + * Copyright 2025 Toni500git + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + #include "platform.hpp" #if CF_MACOS diff --git a/src/core-modules/macos/os.cc b/src/core-modules/macos/os.cc index e1e5fcef..1245027e 100644 --- a/src/core-modules/macos/os.cc +++ b/src/core-modules/macos/os.cc @@ -1,3 +1,28 @@ +/* + * Copyright 2025 Toni500git + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + #include "platform.hpp" #if CF_MACOS diff --git a/src/core-modules/macos/ram.cc b/src/core-modules/macos/ram.cc index f76a75a1..24e8c4c7 100644 --- a/src/core-modules/macos/ram.cc +++ b/src/core-modules/macos/ram.cc @@ -1,3 +1,28 @@ +/* + * Copyright 2025 Toni500git + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + #include "platform.hpp" #if CF_MACOS diff --git a/src/core-modules/macos/system.cc b/src/core-modules/macos/system.cc index b7364854..681e99b1 100644 --- a/src/core-modules/macos/system.cc +++ b/src/core-modules/macos/system.cc @@ -1,3 +1,28 @@ +/* + * Copyright 2025 Toni500git + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + #include "platform.hpp" #if CF_MACOS diff --git a/src/core-modules/macos/theme.cc b/src/core-modules/macos/theme.cc index 3a6475ec..1c137f8a 100644 --- a/src/core-modules/macos/theme.cc +++ b/src/core-modules/macos/theme.cc @@ -1,3 +1,28 @@ +/* + * Copyright 2025 Toni500git + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + #include "platform.hpp" #if CF_MACOS diff --git a/tests/test_util.cpp b/tests/test_util.cpp index ae622cb5..a5affefd 100644 --- a/tests/test_util.cpp +++ b/tests/test_util.cpp @@ -1,3 +1,28 @@ +/* + * Copyright 2025 Toni500git + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + #include <string> #include "util.hpp" From eb316fc1c65115e798b391ddc0613160be637608 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Thu, 31 Jul 2025 21:42:58 +0200 Subject: [PATCH 133/143] misc: fix macos build --- CMakeLists.txt | 13 ++++++++----- include/texts.hpp | 8 +++++--- src/core-modules/macos/system.cc | 2 +- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f472ebc3..62ae53fb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,13 +43,13 @@ execute_process(COMMAND ./scripts/generateVersion.sh WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) # https://github.com/libcpr/cpr/blob/5f475522597b8f3721e2440daddeced7a969f24c/CMakeLists.txt#L39 -macro(add_option OPTION_NAME OPTION_TEXT OPTION_DEFAULT) +macro(add_option OPTION_NAME OPTION_TEXT OPTION_DEFAULT DEFINE_OPTION) option(${OPTION_NAME} ${OPTION_TEXT} ${OPTION_DEFAULT}) if(DEFINED ENV{${OPTION_NAME}}) # Allow overriding the option through an environment variable set(${OPTION_NAME} $ENV{${OPTION_NAME}}) endif() - if(${OPTION_NAME}) + if(${OPTION_NAME} AND DEFINE_OPTION) add_definitions(-D${OPTION_NAME}) endif() message(STATUS " ${OPTION_NAME}: ${${OPTION_NAME}}") @@ -57,9 +57,9 @@ endmacro() message(STATUS "Set flags:") message(STATUS "=================") -add_option(GUI_APP "Build GTK3 application" 0) -add_option(USE_DCONF "Compile customfetch with dconf support" 1) -add_option(VARS "Add additional flags at CXXFLAGS" "") +add_option(GUI_APP "Build GTK3 application" 0 1) +add_option(USE_DCONF "Compile customfetch with dconf support" 1 0) +add_option(VARS "Add additional flags at CXXFLAGS" "" 1) message(STATUS "=================") if(GUI_APP) @@ -135,6 +135,8 @@ add_library(cufetch SHARED libcufetch/config.cc libcufetch/cufetch.cc libcufetch/parse.cc + src/libs/toml++/toml.cpp + src/util.cpp ) set_target_properties(cufetch PROPERTIES @@ -144,6 +146,7 @@ set_target_properties(cufetch PROPERTIES POSITION_INDEPENDENT_CODE ON ) +target_link_libraries(cufetch PUBLIC tiny-process-library) target_link_libraries(cufetch PUBLIC fmt) target_link_libraries(${TARGET_NAME} PUBLIC cufetch) diff --git a/include/texts.hpp b/include/texts.hpp index 6f9ed221..a17fb4ad 100644 --- a/include/texts.hpp +++ b/include/texts.hpp @@ -176,9 +176,9 @@ Tag References: 3. Conditional Tag ($[]) Displays different outputs based on conditions. - + Syntax: $[condition,comparison,true_output,false_output] - + Examples: - $[$<user.name>,toni,Welcome back!,Access denied] - $[$(date +%m-%d),12-25,Merry Christmas!,] @@ -271,7 +271,9 @@ layout = [ "${auto}OS: $<os.name> $<system.arch>", "${auto}Host: $<system.host>", "${auto}Kernel: $<os.kernel>", - "${auto}Uptime: $<os.uptime>",)#" + "${auto}Uptime: $<os.uptime>", + "${auto}Terminal: $<user.terminal>", + "${auto}Shell: $<user.shell>",)#" #if !CF_ANDROID R"#( "${auto}Theme: $<theme.gtk.all.name>", diff --git a/src/core-modules/macos/system.cc b/src/core-modules/macos/system.cc index 681e99b1..c6f074c9 100644 --- a/src/core-modules/macos/system.cc +++ b/src/core-modules/macos/system.cc @@ -152,7 +152,7 @@ const std::string get_host_from_family(const std::string_view host_family) } else if (hasStart(host_family, "MacPro")) { - const std::string_view version = host_family.substr("MacPro"_leMac Pro(2019) n); + const std::string_view version = host_family.substr("MacPro"_len); switch (fnv1a16::hash(version.data())) { case "7,1"_fnv1a16: return "Mac Pro (2019)"; From 906244a2b458267aed3f62ad349d7f52f80676a9 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Thu, 31 Jul 2025 21:53:29 +0200 Subject: [PATCH 134/143] cmake: fix build on linux why it didn't broke on macos?? --- CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 62ae53fb..7c6829db 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -116,6 +116,10 @@ else() target_sources(tiny-process-library PRIVATE "src/libs/tiny-process-library/process_unix.cpp") endif() +set_target_properties(tiny-process-library PROPERTIES + POSITION_INDEPENDENT_CODE ON +) + find_package(Threads REQUIRED) target_link_libraries(tiny-process-library Threads::Threads) target_include_directories(tiny-process-library PUBLIC From 780f9ee6f5ac98b3bde19bc42bdd1f1a7d471106 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Thu, 31 Jul 2025 23:51:27 +0200 Subject: [PATCH 135/143] build: auto-enable and detect LTO flags + some other fixes --- CMakeLists.txt | 30 ++++++++++++++++-- Makefile | 43 ++++++++++++++++---------- libcufetch/Makefile | 9 +++--- src/libs/fmt/Makefile | 2 +- src/libs/getopt_port/Makefile | 2 +- src/libs/json/Makefile | 2 +- src/libs/tiny-process-library/Makefile | 6 ++-- src/libs/toml++/Makefile | 2 +- 8 files changed, 65 insertions(+), 31 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7c6829db..8b8a8236 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,15 +28,37 @@ file(GLOB "src/core-modules/macos/*.cc" "src/core-modules/linux/utils/*.cc" "src/libs/json/json.cpp" - "src/libs/toml++/toml.cpp") + "src/libs/toml++/toml.cpp" + "src/libs/getopt_port/getopt.c") + +function(enable_lto target) + if (NOT TARGET ${target}) + message(FATAL_ERROR "enable_lto called on non-existent target: ${target}") + endif() + + if (CMAKE_BUILD_TYPE STREQUAL "Release") + if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + # GCC supports -ffat-lto-objects for archives + target_compile_options(${target} PRIVATE -flto=auto -ffat-lto-objects) + target_link_options(${target} PRIVATE -flto=auto) + elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang") + # Use ThinLTO on Clang (better incremental builds) + target_compile_options(${target} PRIVATE -flto=thin) + target_link_options(${target} PRIVATE -flto=thin) + else() + message(WARNING "LTO not configured for compiler: ${CMAKE_CXX_COMPILER_ID}") + endif() + endif() +endfunction() if(GUI_APP) - set(TARGET_NAME customfetch-gui) + set(TARGET_NAME customfetch-gui) else() - set(TARGET_NAME customfetch) + set(TARGET_NAME customfetch) endif() add_executable(${TARGET_NAME} ${SRC}) +enable_lto(${TARGET_NAME}) # Get git info hash and branch execute_process(COMMAND ./scripts/generateVersion.sh @@ -92,6 +114,7 @@ add_library(fmt STATIC "src/libs/fmt/format.cc") set_target_properties(fmt PROPERTIES POSITION_INDEPENDENT_CODE ON) +enable_lto(fmt) target_link_libraries(${TARGET_NAME} PUBLIC fmt) # tiny-process-library (integrated from its own CMakeLists.txt) @@ -126,6 +149,7 @@ target_include_directories(tiny-process-library PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src/libs/tiny-process-library> $<INSTALL_INTERFACE:include> ) +enable_lto(tiny-process-library) target_link_libraries(${TARGET_NAME} PUBLIC tiny-process-library) # libcufetch diff --git a/Makefile b/Makefile index 7acdf507..82fb3297 100644 --- a/Makefile +++ b/Makefile @@ -12,13 +12,24 @@ DEBUG ?= 1 GUI_APP ?= 0 USE_DCONF ?= 1 +COMPILER := $(shell $(CXX) --version | head -n1) + +ifeq ($(findstring GCC,$(COMPILER)),GCC) + export LTO_FLAGS = -flto=auto -ffat-lto-objects +else ifeq ($(findstring clang,$(COMPILER)),clang) + export LTO_FLAGS = -flto=thin +else + $(warning Unknown compiler: $(COMPILER). No LTO flags applied.) +endif + # https://stackoverflow.com/a/1079861 # WAY easier way to build debug and release builds ifeq ($(DEBUG), 1) - BUILDDIR = build/debug - CXXFLAGS := -ggdb3 -Wall -Wextra -pedantic -Wno-unused-parameter -fsanitize=address \ - -DDEBUG=1 -fno-omit-frame-pointer -O1 -fno-lto $(DEBUG_CXXFLAGS) $(CXXFLAGS) - LDFLAGS += -fsanitize=address + BUILDDIR := build/debug + LTO_FLAGS = -fno-lto + CXXFLAGS := -ggdb3 -Wall -Wextra -pedantic -Wno-unused-parameter -fsanitize=address \ + -DDEBUG=1 -fno-omit-frame-pointer -O1 $(DEBUG_CXXFLAGS) $(CXXFLAGS) + LDFLAGS += -fsanitize=address -fno-lto else # Check if an optimization flag is not already set ifneq ($(filter -O%,$(CXXFLAGS)),) @@ -26,8 +37,8 @@ else else CXXFLAGS := -O3 $(CXXFLAGS) endif - CXXFLAGS += -flto=auto -ffat-lto-objects - BUILDDIR = build/release + LDFLAGS += $(LTO_FLAGS) + BUILDDIR := build/release endif ifeq ($(GUI_APP), 1) @@ -54,42 +65,42 @@ SRC_CC = $(wildcard src/core-modules/*.cc src/core-modules/linux/*.cc src/cor OBJ_CPP = $(SRC_CPP:.cpp=.o) OBJ_CC = $(SRC_CC:.cc=.o) OBJ = $(OBJ_CPP) $(OBJ_CC) -LDFLAGS += -L$(BUILDDIR) -flto=auto -ffat-lto-objects +LDFLAGS += -L$(BUILDDIR) LDLIBS += $(BUILDDIR)/libfmt.a $(BUILDDIR)/libtiny-process-library.a -lcufetch -ldl CXXFLAGS ?= -mtune=generic -march=native -CXXFLAGS += -fvisibility-inlines-hidden -fvisibility=hidden -Iinclude -Iinclude/libcufetch -Iinclude/libs -std=$(CXXSTD) $(VARS) -DVERSION=\"$(VERSION)\" -DLOCALEDIR=\"$(LOCALEDIR)\" -DICONPREFIX=\"$(ICONPREFIX)\" +CXXFLAGS += $(LTO_FLAGS) -fvisibility-inlines-hidden -fvisibility=hidden -Iinclude -Iinclude/libcufetch -Iinclude/libs -std=$(CXXSTD) $(VARS) -DVERSION=\"$(VERSION)\" -DLOCALEDIR=\"$(LOCALEDIR)\" -DICONPREFIX=\"$(ICONPREFIX)\" all: genver fmt toml tpl getopt-port json libcufetch $(TARGET) -libcufetch: fmt toml +libcufetch: tpl fmt toml ifeq ($(wildcard $(BUILDDIR)/libcufetch.so),) - make -C libcufetch BUILDDIR=$(BUILDDIR) GUI_APP=$(GUI_APP) CXXSTD=$(CXXSTD) + $(MAKE) -C libcufetch BUILDDIR=$(BUILDDIR) GUI_APP=$(GUI_APP) CXXSTD=$(CXXSTD) endif fmt: ifeq ($(wildcard $(BUILDDIR)/libfmt.a),) mkdir -p $(BUILDDIR) - make -C src/libs/fmt BUILDDIR=$(BUILDDIR) CXXSTD=$(CXXSTD) + $(MAKE) -C src/libs/fmt BUILDDIR=$(BUILDDIR) CXXSTD=$(CXXSTD) endif toml: ifeq ($(wildcard $(BUILDDIR)/toml.o),) - make -C src/libs/toml++ BUILDDIR=$(BUILDDIR) CXXSTD=$(CXXSTD) + $(MAKE) -C src/libs/toml++ BUILDDIR=$(BUILDDIR) CXXSTD=$(CXXSTD) endif tpl: ifeq ($(wildcard $(BUILDDIR)/libtiny-process-library.a),) - make -C src/libs/tiny-process-library BUILDDIR=$(BUILDDIR) CXXSTD=$(CXXSTD) + $(MAKE) -C src/libs/tiny-process-library BUILDDIR=$(BUILDDIR) CXXSTD=$(CXXSTD) endif getopt-port: ifeq ($(wildcard $(BUILDDIR)/getopt.o),) - make -C src/libs/getopt_port BUILDDIR=$(BUILDDIR) + $(MAKE) -C src/libs/getopt_port BUILDDIR=$(BUILDDIR) endif json: ifeq ($(wildcard $(BUILDDIR)/json.o),) - make -C src/libs/json BUILDDIR=$(BUILDDIR) CXXSTD=$(CXXSTD) + $(MAKE) -C src/libs/json BUILDDIR=$(BUILDDIR) CXXSTD=$(CXXSTD) endif genver: ./scripts/generateVersion.sh @@ -115,7 +126,7 @@ endif usr-dist: $(TARGET) locale mkdir -p $(PWD)/usr - make install DESTDIR=$(PWD) PREFIX=/usr + $(MAKE) install DESTDIR=$(PWD) PREFIX=/usr $(TAR) -zcf $(NAME)-v$(VERSION).tar.gz usr/ rm -rf usr/ diff --git a/libcufetch/Makefile b/libcufetch/Makefile index 2b2583f0..8cd38a23 100644 --- a/libcufetch/Makefile +++ b/libcufetch/Makefile @@ -17,9 +17,9 @@ CXX ?= g++ GUI_APP ?= 0 SRC = $(wildcard *.cc) OBJ = $(SRC:.cc=.o) ../$(BUILDDIR)/toml.o -FMT_STATIC = ../$(BUILDDIR)/libfmt.a +LDLIBS := ../$(BUILDDIR)/libfmt.a ../$(BUILDDIR)/libtiny-process-library.a OUTPUT := ../$(BUILDDIR)/$(LIBNAME) -CXXFLAGS += -flto=auto -ffat-lto-objects -fvisibility-inlines-hidden -fvisibility=hidden -I../include -I../include/libs -fPIC -DGUI_APP=$(GUI_APP) +CXXFLAGS += -fvisibility-inlines-hidden -fvisibility=hidden -I../include -I../include/libs -fPIC -DGUI_APP=$(GUI_APP) all: $(OUTPUT) @if [ "$(UNAME_S)" = "Linux" ]; then \ @@ -33,11 +33,10 @@ all: $(OUTPUT) %.o: %.cc $(CXX) $(CXXFLAGS) -c -o $@ $< -$(OUTPUT): $(OBJ) $(FMT_STATIC) +$(OUTPUT): $(OBJ) $(LDLIBS) $(CXX) $(SHARED_FLAG) $(CXXFLAGS) $(OBJ) \ - $(FMT_STATIC) \ $(SONAME_FLAGS) $(INSTALL_NAME) \ - -o $@ + -o $@ $(LDLIBS) clean: rm -f *.o *.so *.a ../$(BUILDDIR)/libcufetch.so diff --git a/src/libs/fmt/Makefile b/src/libs/fmt/Makefile index 4e5eccb7..1d291a58 100644 --- a/src/libs/fmt/Makefile +++ b/src/libs/fmt/Makefile @@ -5,7 +5,7 @@ CXX ?= g++ CXXSTD ?= c++20 # CXX_DEFINES = -DFMT_LIB_EXPORT -Dfmt_EXPORTS -CXXFLAGS = -I../../../include/libs -O3 -std=$(CXXSTD) -DNDEBUG -flto=auto -ffat-lto-objects -fvisibility=hidden -fvisibility-inlines-hidden -fPIC +CXXFLAGS = -I../../../include/libs -O3 -std=$(CXXSTD) -DNDEBUG $(LTO_FLAGS) -fvisibility=hidden -fvisibility-inlines-hidden -fPIC all: fmt diff --git a/src/libs/getopt_port/Makefile b/src/libs/getopt_port/Makefile index 65ed3499..d369ff97 100644 --- a/src/libs/getopt_port/Makefile +++ b/src/libs/getopt_port/Makefile @@ -1,7 +1,7 @@ CC ?= cc SRC = getopt.c TARGET = getopt.o -CFLAGS = -I../../../include/libs -flto=auto -ffat-lto-objects -fvisibility=hidden -fPIC +CFLAGS = -I../../../include/libs $(LTO_FLAGS) -fvisibility=hidden -fPIC all: $(TARGET) diff --git a/src/libs/json/Makefile b/src/libs/json/Makefile index f251844d..4adb0147 100644 --- a/src/libs/json/Makefile +++ b/src/libs/json/Makefile @@ -2,7 +2,7 @@ CXX ?= g++ SRC = json.cpp TARGET = json.o CXXSTD ?= c++20 -CXXFLAGS = -I../../../include/libs -flto=auto -ffat-lto-objects -std=$(CXXSTD) -fPIC +CXXFLAGS = -I../../../include/libs $(LTO_FLAGS) -std=$(CXXSTD) -fPIC all: $(TARGET) diff --git a/src/libs/tiny-process-library/Makefile b/src/libs/tiny-process-library/Makefile index 69bf9644..688e74fb 100644 --- a/src/libs/tiny-process-library/Makefile +++ b/src/libs/tiny-process-library/Makefile @@ -1,6 +1,6 @@ CXX ?= g++ CXXSTD ?= c++20 -CXXFLAGS = -I../../../include/libs/tiny-process-library -std=$(CXXSTD) -O3 -DNDEBUG -flto=auto -ffat-lto-objects -fvisibility=default -fvisibility-inlines-hidden -fPIC +CXXFLAGS = -I../../../include/libs/tiny-process-library -std=$(CXXSTD) -O3 -DNDEBUG $(LTO_FLAGS) -fvisibility=default -fvisibility-inlines-hidden -fPIC UNAME_S := $(shell uname -s) @@ -13,12 +13,12 @@ ifeq ($(UNAME_S),Windows) endif LIBNAME = tiny-process-library.lib else - CXXFLAGS += -std=c++11 -Wall -Wextra + CXXFLAGS += -Wall -Wextra SRC += process_unix.cpp LIBNAME = libtiny-process-library.a endif -SRC += process.cpp +SRC += process.cpp OBJ = $(SRC:.cpp=.o) all: $(LIBNAME) diff --git a/src/libs/toml++/Makefile b/src/libs/toml++/Makefile index d5d3a662..811bdc39 100644 --- a/src/libs/toml++/Makefile +++ b/src/libs/toml++/Makefile @@ -2,7 +2,7 @@ CXX ?= g++ CXXSTD ?= c++20 SRC = toml.cpp TARGET = toml.o -CXXFLAGS = -I../../../include/libs -flto=auto -ffat-lto-objects -fvisibility-inlines-hidden -fvisibility=default -fPIC -std=$(CXXSTD) +CXXFLAGS = -I../../../include/libs $(LTO_FLAGS) -fvisibility-inlines-hidden -fvisibility=default -fPIC -std=$(CXXSTD) all: $(TARGET) From 0104997d21f965ad06a9ec591dff89c602abb9cb Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Thu, 31 Jul 2025 23:52:08 +0200 Subject: [PATCH 136/143] misc: fix crash with really big 'all_ids' string in pci.ids.hpp --- include/pci.ids.hpp | 4 ++-- src/util.cpp | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/include/pci.ids.hpp b/include/pci.ids.hpp index 581ee461..f84a10e0 100644 --- a/include/pci.ids.hpp +++ b/include/pci.ids.hpp @@ -39893,13 +39893,13 @@ C ff Unassigned class )"; } -inline const std::string& all_ids = get_pci_ids(); +extern const std::string& all_ids; inline constexpr std::array<std::string_view, 2424> pci_vendors_array = get_pci_vendors_array(); inline constexpr std::array<int, 2424> pci_vendors_location_array = get_pci_vendors_location_array(); #else -inline const std::string& all_ids = {}; +extern const std::string& all_ids; inline constexpr std::array<std::string_view, 2424> pci_vendors_array = {}; inline constexpr std::array<int, 2424> pci_vendors_location_array = {}; diff --git a/src/util.cpp b/src/util.cpp index 2532d0e4..382ab6a2 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -48,6 +48,12 @@ #include "platform.hpp" #include "tiny-process-library/process.hpp" +#if !CF_ANDROID +const std::string& all_ids = get_pci_ids(); +#else +const std::string& all_ids = ""; +#endif + bool hasEnding(const std::string_view fullString, const std::string_view ending) { if (ending.length() > fullString.length()) From 2439698c8f61f9387fc5cd2d0e6f9939c69498e0 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Fri, 1 Aug 2025 00:19:49 +0200 Subject: [PATCH 137/143] build: fix again --- Makefile | 2 +- include/libcufetch/cufetch.hh | 3 --- libcufetch/Makefile | 2 +- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 82fb3297..921e3c89 100644 --- a/Makefile +++ b/Makefile @@ -72,7 +72,7 @@ CXXFLAGS += $(LTO_FLAGS) -fvisibility-inlines-hidden -fvisibility=hidden all: genver fmt toml tpl getopt-port json libcufetch $(TARGET) -libcufetch: tpl fmt toml +libcufetch: fmt tpl toml ifeq ($(wildcard $(BUILDDIR)/libcufetch.so),) $(MAKE) -C libcufetch BUILDDIR=$(BUILDDIR) GUI_APP=$(GUI_APP) CXXSTD=$(CXXSTD) endif diff --git a/include/libcufetch/cufetch.hh b/include/libcufetch/cufetch.hh index 8f4625ae..6b827e1a 100644 --- a/include/libcufetch/cufetch.hh +++ b/include/libcufetch/cufetch.hh @@ -6,9 +6,6 @@ #include "libcufetch/parse.hh" -// Map from a modules name to its pointer. -using moduleMap_t = std::unordered_map<std::string, const module_t&>; - /* A linked list including module arguments. An argument may be specified for any part of the module path (e.g. * `disk(/).used(GiB)`, `test(a).hi`) */ struct moduleArgs_t diff --git a/libcufetch/Makefile b/libcufetch/Makefile index 8cd38a23..0fe2fbba 100644 --- a/libcufetch/Makefile +++ b/libcufetch/Makefile @@ -19,7 +19,7 @@ SRC = $(wildcard *.cc) OBJ = $(SRC:.cc=.o) ../$(BUILDDIR)/toml.o LDLIBS := ../$(BUILDDIR)/libfmt.a ../$(BUILDDIR)/libtiny-process-library.a OUTPUT := ../$(BUILDDIR)/$(LIBNAME) -CXXFLAGS += -fvisibility-inlines-hidden -fvisibility=hidden -I../include -I../include/libs -fPIC -DGUI_APP=$(GUI_APP) +CXXFLAGS += -fvisibility-inlines-hidden -fvisibility=hidden -std=$(CXXSTD) -I../include -I../include/libs -fPIC -DGUI_APP=$(GUI_APP) all: $(OUTPUT) @if [ "$(UNAME_S)" = "Linux" ]; then \ From 75f8634237159557e9bac0059c2d4970a32dab18 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Fri, 1 Aug 2025 20:37:00 +0200 Subject: [PATCH 138/143] cufetchpm: args: add enable/disable plugins --- cufetchpm/src/main.cpp | 182 +++++++++++++++++++++++++++++++++-------- include/texts.hpp | 8 +- 2 files changed, 155 insertions(+), 35 deletions(-) diff --git a/cufetchpm/src/main.cpp b/cufetchpm/src/main.cpp index 75b07b01..eb55382c 100644 --- a/cufetchpm/src/main.cpp +++ b/cufetchpm/src/main.cpp @@ -30,6 +30,7 @@ #include "fmt/os.h" #include "fmt/ranges.h" #include "libcufetch/common.hh" +#include "manifest.hpp" #include "pluginManager.hpp" #include "stateManager.hpp" #include "texts.hpp" @@ -47,6 +48,8 @@ enum Ops NONE, INSTALL, LIST, + ENABLE, + DISABLE, GEN_MANIFEST, } op = NONE; @@ -137,6 +140,34 @@ bool parse_list_args(int argc, char* argv[]) return true; } +bool parse_switch_plugin_args(int argc, char* argv[]) +{ + // clang-format off + const struct option long_opts[] = { + {"help", no_argument, nullptr, 'h'}, + {0, 0, 0, 0} + }; + // clang-format on + + int opt; + while ((opt = getopt_long(argc, argv, "-h", long_opts, nullptr)) != -1) + { + switch (opt) + { + case 'h': help(EXIT_SUCCESS); break; + case '?': help_install(EXIT_FAILURE); break; + } + } + + for (int i = optind; i < argc; ++i) + options.arguments.emplace_back(argv[i]); + + if (options.arguments.empty()) + die("Please provide a source/plugin to enable/disable"); + + return true; +} + static bool parseargs(int argc, char* argv[]) { // clang-format off @@ -188,6 +219,18 @@ static bool parseargs(int argc, char* argv[]) op = GEN_MANIFEST; optind = 0; } + else if (cmd == "enable") + { + op = ENABLE; + optind = 0; + return parse_switch_plugin_args(sub_argc, sub_argv); + } + else if (cmd == "disable") + { + op = DISABLE; + optind = 0; + return parse_switch_plugin_args(sub_argc, sub_argv); + } else if (cmd == "help") { if (sub_argc >= 1) @@ -198,7 +241,7 @@ static bool parseargs(int argc, char* argv[]) else if (target == "list") help_list(); else - die("Unknown subcommand '{}'", cmd); + die("Couldn't find help text for subcommand '{}'", cmd); } else { @@ -209,6 +252,100 @@ static bool parseargs(int argc, char* argv[]) return true; } +void switch_plugin(StateManager&& state, bool switch_) +{ + const char* switch_str = switch_ ? "Enabl" : "Disabl"; // e/ed/ing + const toml::table& tbl = state.get_state(); + + for (const std::string& arg : options.arguments) + { + const size_t pos = arg.find('/'); + if (pos == arg.npos) + die("Plugin to {}e '{}' doesn't have a slash '/' to separate source and plugin", switch_str, arg); + + const std::string& source = arg.substr(0, pos); + const std::string& plugin = arg.substr(pos + 1); + + const auto* source_tbl = tbl["repositories"][source].as_table(); + if (!source_tbl) + die("Couldn't find source '{}'", source); + if (const auto* plugins_arr_tbl = source_tbl->get_as<toml::array>("plugins")) + { + for (const auto& plugin_node : *plugins_arr_tbl) + { + const toml::table* plugin_tbl = plugin_node.as_table(); + if (!plugin_tbl || ManifestSpace::getStrValue(*plugin_tbl, "name") != plugin) + continue; + + for (const fs::path path : ManifestSpace::getStrArrayValue(*plugin_tbl, "libraries")) + { + fs::path base_path = path; + if (base_path.extension() == ".disabled") + base_path.replace_extension(); // normalize to enabled form + + const fs::path& enabled_path = base_path; + const fs::path& disabled_path = base_path.string() + ".disabled"; + + fs::path current_path; + if (fs::exists(enabled_path)) + current_path = enabled_path; + else if (fs::exists(disabled_path)) + current_path = disabled_path; + else + { + warn("Plugin library '{}' not found. Skipping", base_path.string()); + continue; + } + + const fs::path& target_path = switch_ ? enabled_path : disabled_path; + if (current_path == target_path) + { + warn("{} is already {}ed", arg, switch_str); + continue; + } + + fs::rename(current_path, target_path); + info("{}ed {}!", switch_str, arg); + } + } + } + } +} + +void list_all_plugins(StateManager&& state) +{ + if (options.list_verbose) + { + for (const manifest_t& manifest : state.get_all_repos()) + { + fmt::println("\033[1;32mRepository:\033[0m {}", manifest.name); + fmt::println("\033[1;33mURL:\033[0m {}", manifest.url); + fmt::println("\033[1;34mPlugins:"); + for (const plugin_t& plugin : manifest.plugins) + { + fmt::println("\033[1;34m - {}\033[0m", plugin.name); + fmt::println("\t\033[1;35mDescription:\033[0m {}", plugin.description); + fmt::println("\t\033[1;36mAuthor(s):\033[0m {}", fmt::join(plugin.authors, ", ")); + fmt::println("\t\033[1;38;2;220;220;220mLicense(s):\033[0m {}", fmt::join(plugin.licenses, ", ")); + fmt::println("\t\033[1;38;2;144;238;144mPrefixe(s):\033[0m {}", fmt::join(plugin.prefixes, ", ")); + fmt::print("\n"); + } + fmt::print("\033[0m"); + } + } + else + { + for (const manifest_t& manifest : state.get_all_repos()) + { + fmt::println("\033[1;32mRepository:\033[0m {} (\033[1;33m{}\033[0m)", manifest.name, manifest.url); + fmt::println("\033[1;34mPlugins:"); + for (const plugin_t& plugin : manifest.plugins) + fmt::println(" \033[1;34m{} - \033[1;35m{}\n", plugin.name, plugin.description); + fmt::print("\033[0m"); + } + } +} + int main(int argc, char* argv[]) { if (!parseargs(argc, argv)) @@ -235,38 +372,7 @@ int main(int argc, char* argv[]) } case LIST: { - if (options.list_verbose) - { - for (const manifest_t& manifest : state.get_all_repos()) - { - fmt::println("\033[1;32mRepository:\033[0m {}", manifest.name); - fmt::println("\033[1;33mURL:\033[0m {}", manifest.url); - fmt::println("\033[1;34mPlugins:"); - for (const plugin_t& plugin : manifest.plugins) - { - fmt::println("\033[1;34m - {}\033[0m", plugin.name); - fmt::println("\t\033[1;35mDescription:\033[0m {}", plugin.description); - fmt::println("\t\033[1;36mAuthor(s):\033[0m {}", fmt::join(plugin.authors, ", ")); - fmt::println("\t\033[1;38;2;220;220;220mLicense(s):\033[0m {}", - fmt::join(plugin.licenses, ", ")); - fmt::println("\t\033[1;38;2;144;238;144mPrefixe(s):\033[0m {}", - fmt::join(plugin.prefixes, ", ")); - fmt::print("\n"); - } - fmt::print("\033[0m"); - } - } - else - { - for (const manifest_t& manifest : state.get_all_repos()) - { - fmt::println("\033[1;32mRepository:\033[0m {} (\033[1;33m{}\033[0m)", manifest.name, manifest.url); - fmt::println("\033[1;34mPlugins:"); - for (const plugin_t& plugin : manifest.plugins) - fmt::println(" \033[1;34m{} - \033[1;35m{}\n", plugin.name, plugin.description); - fmt::print("\033[0m"); - } - } + list_all_plugins(std::move(state)); break; } case GEN_MANIFEST: @@ -276,6 +382,16 @@ int main(int argc, char* argv[]) f.close(); break; } + case ENABLE: + { + switch_plugin(std::move(state), true); + break; + } + case DISABLE: + { + switch_plugin(std::move(state), false); + break; + } default: warn("uh?"); } diff --git a/include/texts.hpp b/include/texts.hpp index a17fb4ad..a4f0f9f4 100644 --- a/include/texts.hpp +++ b/include/texts.hpp @@ -32,10 +32,14 @@ // cufetchpm inline constexpr std::string_view cufetchpm_help = (R"(Usage: cufetchpm <COMMAND> [OPTIONS]... Manage plugins for customfetch. +Terms: + - SOURCE: the Git repositry or local path where all the plugins and manifest are stored. Commands: help <COMMAND> Show help for a specific command. - install [OPTIONS] <repo/path>... Install one or more plugin sources from a Git repo or local path. + install [OPTIONS] <SOURCE>... Install one or more plugin sources from a Git repo or local path. + enable <SOURCE/PLUGIN>... Enable one or more plugins from given source (e.g "source1/pluginA") + disable <SOURCE/PLUGIN>... Disnable one or more plugins from given source (e.g "source2/pluginB") list List of information about all plugins installed through state.toml gen-manifest Auto generate an example manifest "cufetchpm.toml" that'll you need to modify it yourself @@ -45,7 +49,7 @@ Global options: )"); -inline constexpr std::string_view cufetchpm_help_install = (R"(Usage: cufetchpm install [options] <repo/path>... +inline constexpr std::string_view cufetchpm_help_install = (R"(Usage: cufetchpm install [options] <source>... Install one or more plugin sources. If a given argument exists on disk, it is treated as a local directory. Otherwise, it is treated as a Git From 4b927d0f20958ddca3fd8e1ba61759e78fd7a028 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Sat, 2 Aug 2025 00:36:54 +0200 Subject: [PATCH 139/143] cufetchpm: args: add uninstall command also change ~/.cache/cufetchpm/plugins -> ~/.cache/cufetchpm/ fix crash if `platforms` is empty --- cufetchpm/include/pluginManager.hpp | 5 +++-- cufetchpm/include/stateManager.hpp | 3 ++- cufetchpm/src/main.cpp | 30 ++++++++++++++++++++++------- cufetchpm/src/manifest.cpp | 2 +- cufetchpm/src/pluginManager.cpp | 30 ++++++++++++++++++++++------- cufetchpm/src/stateManager.cpp | 16 ++++++++++++++- include/texts.hpp | 22 ++++++++++++++++----- 7 files changed, 84 insertions(+), 24 deletions(-) diff --git a/cufetchpm/include/pluginManager.hpp b/cufetchpm/include/pluginManager.hpp index 6f2c1019..fc9fef3d 100644 --- a/cufetchpm/include/pluginManager.hpp +++ b/cufetchpm/include/pluginManager.hpp @@ -69,15 +69,16 @@ class PluginManager PluginManager(const StateManager& state_manager) : m_state_manager(state_manager) {} PluginManager(StateManager&& state_manager) : m_state_manager(std::move(state_manager)) {} - void add_repo_plugins(const std::string& repo); + void add_source_repo_plugins(const std::string& repo); void build_plugins(const fs::path& working_dir); bool add_plugin(const std::string&); + void remove_plugins_source(const std::string& source_name); bool has_deps(const std::vector<std::string>& dependencies); private: StateManager m_state_manager; fs::path m_config_path{ getConfigDir() / "plugins" }; - fs::path m_cache_path{ getHomeCacheDir() / "cufetchpm" / "plugins" }; + fs::path m_cache_path{ getHomeCacheDir() / "cufetchpm" }; }; #endif diff --git a/cufetchpm/include/stateManager.hpp b/cufetchpm/include/stateManager.hpp index ac87b0f9..a5d25a95 100644 --- a/cufetchpm/include/stateManager.hpp +++ b/cufetchpm/include/stateManager.hpp @@ -44,6 +44,7 @@ class StateManager ~StateManager() = default; void add_new_repo(const CManifest& manifest); + void remove_repo(const std::string& repo); std::vector<manifest_t> get_all_repos(); template <typename T> @@ -77,7 +78,7 @@ void StateManager::insert_or_assign_at_plugin(const std::string_view repo_name, (*plugin_tbl).insert_or_assign(key, std::forward<T>(value)); std::stringstream ss; - ss << "AUTO-GENERATED FILE. DO NOT EDIT THIS FILE.\n"; + ss << "# AUTO-GENERATED FILE. DO NOT EDIT THIS FILE.\n"; ss << "# YOU GONNA MESS SHIT UP. unless you know what you doing ofc\n"; ss << m_state; diff --git a/cufetchpm/src/main.cpp b/cufetchpm/src/main.cpp index eb55382c..59517247 100644 --- a/cufetchpm/src/main.cpp +++ b/cufetchpm/src/main.cpp @@ -50,6 +50,7 @@ enum Ops LIST, ENABLE, DISABLE, + UNINSTALL, GEN_MANIFEST, } op = NONE; @@ -140,7 +141,7 @@ bool parse_list_args(int argc, char* argv[]) return true; } -bool parse_switch_plugin_args(int argc, char* argv[]) +bool parse_general_command_args(int argc, char* argv[]) { // clang-format off const struct option long_opts[] = { @@ -223,13 +224,19 @@ static bool parseargs(int argc, char* argv[]) { op = ENABLE; optind = 0; - return parse_switch_plugin_args(sub_argc, sub_argv); + return parse_general_command_args(sub_argc, sub_argv); } else if (cmd == "disable") { op = DISABLE; optind = 0; - return parse_switch_plugin_args(sub_argc, sub_argv); + return parse_general_command_args(sub_argc, sub_argv); + } + else if (cmd == "uninstall") + { + op = UNINSTALL; + optind = 0; + return parse_general_command_args(sub_argc, sub_argv); } else if (cmd == "help") { @@ -277,9 +284,8 @@ void switch_plugin(StateManager&& state, bool switch_) if (!plugin_tbl || ManifestSpace::getStrValue(*plugin_tbl, "name") != plugin) continue; - for (const fs::path path : ManifestSpace::getStrArrayValue(*plugin_tbl, "libraries")) + for (fs::path base_path : ManifestSpace::getStrArrayValue(*plugin_tbl, "libraries")) { - fs::path base_path = path; if (base_path.extension() == ".disabled") base_path.replace_extension(); // normalize to enabled form @@ -351,7 +357,7 @@ int main(int argc, char* argv[]) if (!parseargs(argc, argv)) return -1; - fs::create_directories({ getHomeCacheDir() / "cufetchpm" / "plugins" }); + fs::create_directories({ getHomeCacheDir() / "cufetchpm" }); fs::create_directories({ getConfigDir() / "plugins" }); StateManager state; switch (op) @@ -366,7 +372,7 @@ int main(int argc, char* argv[]) if (fs::exists(arg)) plugin_manager.build_plugins(arg); else - plugin_manager.add_repo_plugins(arg); + plugin_manager.add_source_repo_plugins(arg); } break; } @@ -392,6 +398,16 @@ int main(int argc, char* argv[]) switch_plugin(std::move(state), false); break; } + case UNINSTALL: + { + if (options.arguments.size() < 1) + die("Please provide a plugin source to uninstall"); + + PluginManager plugin_manager(std::move(state)); + for (const std::string& arg : options.arguments) + plugin_manager.remove_plugins_source(arg); + break; + } default: warn("uh?"); } diff --git a/cufetchpm/src/manifest.cpp b/cufetchpm/src/manifest.cpp index e7f199ac..e39e7d92 100644 --- a/cufetchpm/src/manifest.cpp +++ b/cufetchpm/src/manifest.cpp @@ -112,7 +112,7 @@ void CManifest::parse_manifest() die("Manifest repository name '{}' is invalid. Only alphanumeric and '-', '_', '=' are allowed in the name", m_repo.name); - if (auto deps = m_tbl["dependencies"].as_table()) + if (auto* deps = m_tbl["dependencies"].as_table()) { // Collect "all" dependencies if (auto arr = (*deps)["all"].as_array()) diff --git a/cufetchpm/src/pluginManager.cpp b/cufetchpm/src/pluginManager.cpp index ceea8cd1..5be15973 100644 --- a/cufetchpm/src/pluginManager.cpp +++ b/cufetchpm/src/pluginManager.cpp @@ -32,6 +32,7 @@ #include <random> #include <string> #include <string_view> +#include <system_error> #include <vector> #include "fmt/format.h" @@ -57,7 +58,7 @@ bool PluginManager::has_deps(const std::vector<std::string>& dependencies) return true; } -void PluginManager::add_repo_plugins(const std::string& repo) +void PluginManager::add_source_repo_plugins(const std::string& repo) { if (!has_deps(core_dependencies)) die("Some core dependencies are not installed. You'll need to install: {}", fmt::join(core_dependencies, ", ")); @@ -91,7 +92,6 @@ void PluginManager::build_plugins(const fs::path& working_dir) // though lets check if we have already installed the plugin in the cache const fs::path& repo_cache_path = (m_cache_path / manifest.get_repo_name()); - const fs::path& plugins_config_path = (m_config_path / manifest.get_repo_name()); if (fs::exists(repo_cache_path)) { if (!options.install_force) @@ -124,7 +124,7 @@ void PluginManager::build_plugins(const fs::path& working_dir) { bool found_platform = false; - if (plugin.platforms[0] != "all") + if (!plugin.platforms.empty() && plugin.platforms.at(0) != "all") { for (const std::string& plugin_platform : plugin.platforms) if (plugin_platform == PLATFORM) @@ -158,8 +158,9 @@ void PluginManager::build_plugins(const fs::path& working_dir) // and then we move each plugin built library from its output-dir // and we'll declare all plugins we have moved. - fs::create_directories(plugins_config_path); - status("Moving each built plugin to '{}'", plugins_config_path.string()); + const fs::path& manifest_config_path = (m_config_path / manifest.get_repo_name()); + fs::create_directories(manifest_config_path); + status("Moving each built plugin to '{}'", manifest_config_path.string()); for (const plugin_t& plugin : manifest.get_all_plugins()) { // already told before @@ -177,8 +178,8 @@ void PluginManager::build_plugins(const fs::path& working_dir) toml::array built_libraries; for (const auto& library : fs::directory_iterator{ plugin.output_dir }) { - // ~/.config/customfetch/plugins/<plugin-directory>/<plugin-filename> - const fs::path& library_config_path = plugins_config_path / library.path().filename(); + // ~/.config/customfetch/plugins/<manifest-directory>/<plugin-filename> + const fs::path& library_config_path = manifest_config_path / library.path().filename(); if (fs::exists(library_config_path) && !options.install_force) { if (askUserYorN(false, "Plugin '{}' already exists. Replace it?", library_config_path.string())) @@ -209,3 +210,18 @@ void PluginManager::build_plugins(const fs::path& working_dir) } success("Enjoy the new plugins from {}", manifest.get_repo_name()); } + +void PluginManager::remove_plugins_source(const std::string& source_name) +{ + std::error_code ec; + fs::remove_all(m_cache_path / source_name, ec); + if (ec) + warn("Failed to remove plugin source cache path '{}'", (m_cache_path / source_name).string()); + + fs::remove_all(m_config_path / source_name, ec); + if (ec) + warn("Failed to remove plugin source config path '{}'", (m_config_path / source_name).string()); + + m_state_manager.remove_repo(source_name); + success("Removed plugin source '{}'", source_name); +} diff --git a/cufetchpm/src/stateManager.cpp b/cufetchpm/src/stateManager.cpp index 161ca1a3..9671684a 100644 --- a/cufetchpm/src/stateManager.cpp +++ b/cufetchpm/src/stateManager.cpp @@ -120,7 +120,7 @@ void StateManager::add_new_repo(const CManifest& manifest) repo.insert_or_assign("plugins", std::move(plugins_arr)); std::stringstream ss; - ss << "AUTO-GENERATED FILE. DO NOT EDIT THIS FILE.\n"; + ss << "# AUTO-GENERATED FILE. DO NOT EDIT THIS FILE.\n"; ss << "# YOU GONNA MESS SHIT UP. unless you know what you doing ofc\n"; ss << m_state; @@ -169,3 +169,17 @@ std::vector<manifest_t> StateManager::get_all_repos() return manifests; } + +void StateManager::remove_repo(const std::string& repo) +{ + toml::table& repo_tbl = *m_state["repositories"].as_table(); + if (!repo_tbl.contains(repo)) + return; + + repo_tbl.erase(repo); + std::stringstream ss; + ss << m_state; + + if (!writeState(ss.str(), m_path)) + die("Failed to write plugin state of repository '{}'", repo); +} diff --git a/include/texts.hpp b/include/texts.hpp index a4f0f9f4..2162038e 100644 --- a/include/texts.hpp +++ b/include/texts.hpp @@ -32,16 +32,28 @@ // cufetchpm inline constexpr std::string_view cufetchpm_help = (R"(Usage: cufetchpm <COMMAND> [OPTIONS]... Manage plugins for customfetch. + Terms: - - SOURCE: the Git repositry or local path where all the plugins and manifest are stored. + SOURCE: + - With 'install': a Git repository URL or local path containing plugins and a manifest. + - With 'enable'/'disable': the name of a source already installed (as listed in state.toml). + +Examples: + Install from GitHub: + cufetchpm install https://github.com/user/customfetch-plugins-github + Disable a plugin from an installed source: + cufetchpm disable customfetch-plugins-github/github-user-fetch + Uninstall an entire source: + cufetchpm uninstall customfetch-plugins-github Commands: help <COMMAND> Show help for a specific command. install [OPTIONS] <SOURCE>... Install one or more plugin sources from a Git repo or local path. - enable <SOURCE/PLUGIN>... Enable one or more plugins from given source (e.g "source1/pluginA") - disable <SOURCE/PLUGIN>... Disnable one or more plugins from given source (e.g "source2/pluginB") - list List of information about all plugins installed through state.toml - gen-manifest Auto generate an example manifest "cufetchpm.toml" that'll you need to modify it yourself + uninstall <SOURCE>... Uninstall one or more installed plugin sources. + enable <SOURCE/PLUGIN>... Enable one or more plugins from an installed source. + disable <SOURCE/PLUGIN>... Disable one or more plugins from an installed source. + list Show all plugins installed via state.toml. + gen-manifest Generate a template 'cufetchpm.toml' file. Global options: -h, --help Show this help message. From d22d9e644d04014b7fac132afeb2a73a7e088281 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Mon, 4 Aug 2025 17:28:13 +0200 Subject: [PATCH 140/143] cufetchpm: pluginManager: make the 'build-steps' be executed on single shared shell cufetchpm: args: enforce the POSIX behaviour of gathering cmdline options --- Makefile | 2 +- cufetchpm/Makefile | 5 +++-- cufetchpm/src/main.cpp | 8 ++++---- cufetchpm/src/pluginManager.cpp | 12 ++++++------ include/texts.hpp | 19 ++++++++++--------- 5 files changed, 24 insertions(+), 22 deletions(-) diff --git a/Makefile b/Makefile index 921e3c89..95909899 100644 --- a/Makefile +++ b/Makefile @@ -28,7 +28,7 @@ ifeq ($(DEBUG), 1) BUILDDIR := build/debug LTO_FLAGS = -fno-lto CXXFLAGS := -ggdb3 -Wall -Wextra -pedantic -Wno-unused-parameter -fsanitize=address \ - -DDEBUG=1 -fno-omit-frame-pointer -O1 $(DEBUG_CXXFLAGS) $(CXXFLAGS) + -DDEBUG=1 -fno-omit-frame-pointer $(DEBUG_CXXFLAGS) $(CXXFLAGS) LDFLAGS += -fsanitize=address -fno-lto else # Check if an optimization flag is not already set diff --git a/cufetchpm/Makefile b/cufetchpm/Makefile index ce623dc0..4b2cf7bc 100644 --- a/cufetchpm/Makefile +++ b/cufetchpm/Makefile @@ -9,8 +9,9 @@ DEBUG ?= 1 # WAY easier way to build debug and release builds ifeq ($(DEBUG), 1) BUILDDIR = build/debug - CXXFLAGS := -ggdb3 -Wall -Wextra -Wpedantic -Wno-unused-parameter -DDEBUG=1 -fsanitize=address $(DEBUG_CXXFLAGS) $(CXXFLAGS) - LDFLAGS += -fsanitize=address + CXXFLAGS := -ggdb3 -Wall -Wextra -pedantic -Wno-unused-parameter -fsanitize=address \ + -DDEBUG=1 -fno-omit-frame-pointer $(DEBUG_CXXFLAGS) $(CXXFLAGS) + LDFLAGS += -fsanitize=address -fno-lto else # Check if an optimization flag is not already set ifneq ($(filter -O%,$(CXXFLAGS)),) diff --git a/cufetchpm/src/main.cpp b/cufetchpm/src/main.cpp index 59517247..5d79a492 100644 --- a/cufetchpm/src/main.cpp +++ b/cufetchpm/src/main.cpp @@ -98,7 +98,7 @@ bool parse_install_args(int argc, char* argv[]) // clang-format on int opt; - while ((opt = getopt_long(argc, argv, "-fh", long_opts, nullptr)) != -1) + while ((opt = getopt_long(argc, argv, "+fh", long_opts, nullptr)) != -1) { switch (opt) { @@ -128,7 +128,7 @@ bool parse_list_args(int argc, char* argv[]) // clang-format on int opt; - while ((opt = getopt_long(argc, argv, "-vh", long_opts, nullptr)) != -1) + while ((opt = getopt_long(argc, argv, "+vh", long_opts, nullptr)) != -1) { switch (opt) { @@ -151,7 +151,7 @@ bool parse_general_command_args(int argc, char* argv[]) // clang-format on int opt; - while ((opt = getopt_long(argc, argv, "-h", long_opts, nullptr)) != -1) + while ((opt = getopt_long(argc, argv, "+h", long_opts, nullptr)) != -1) { switch (opt) { @@ -174,7 +174,7 @@ static bool parseargs(int argc, char* argv[]) // clang-format off int opt = 0; int option_index = 0; - const char *optstring = "-Vh"; + const char *optstring = "+Vh"; static const struct option opts[] = { {"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, diff --git a/cufetchpm/src/pluginManager.cpp b/cufetchpm/src/pluginManager.cpp index 5be15973..4cf39d69 100644 --- a/cufetchpm/src/pluginManager.cpp +++ b/cufetchpm/src/pluginManager.cpp @@ -139,14 +139,14 @@ void PluginManager::build_plugins(const fs::path& working_dir) } status("Trying to build plugin '{}'", plugin.name); - for (const std::string& bs : plugin.build_steps) + // make the shell stop at the first failure + Process process({"bash", "-c", fmt::format("set -e; {}", fmt::join(plugin.build_steps, " && "))}, ""); + if (process.get_exit_status() != 0) { - if (Process(bs, "").get_exit_status() != 0) - { - fs::remove_all(working_dir); - die("Failed to build plugin '{}'", plugin.name); - } + fs::remove_all(working_dir); + die("Failed to build plugin '{}'", plugin.name); } + success("Successfully built '{}' into '{}'", plugin.name, plugin.output_dir); } m_state_manager.add_new_repo(manifest); diff --git a/include/texts.hpp b/include/texts.hpp index 2162038e..c5a2662a 100644 --- a/include/texts.hpp +++ b/include/texts.hpp @@ -35,11 +35,11 @@ Manage plugins for customfetch. Terms: SOURCE: - - With 'install': a Git repository URL or local path containing plugins and a manifest. - - With 'enable'/'disable': the name of a source already installed (as listed in state.toml). + - With install: a Git repository URL or local path containing plugins and a manifest. + - With enable OR disable: the name of a source already installed (as listed in state.toml). Examples: - Install from GitHub: + Install a source from GitHub: cufetchpm install https://github.com/user/customfetch-plugins-github Disable a plugin from an installed source: cufetchpm disable customfetch-plugins-github/github-user-fetch @@ -494,7 +494,7 @@ url = "https://github.com/user/repo" all = ["pkg-config", "cmake"] linux = ["wayland-protocols", "xorg-dev"] android = ["ndk-build"] -macos = ["brew:gtk+3"] +macos = ["gtk+3"] # From now on, each table that is neiter "repository" nor "dependencies" will be treated as a plugin entry. # The tables' names still must conform alpha-numeric characters and symbols such as '-' or '_' @@ -523,12 +523,13 @@ platforms = ["all"] output-dir = "build/plugin-dir/" # A list of commands to be executed for building the plugin. -# Kinda like a Makefile target instructions. -# Each command runs independently (not in a shared shell). Use absolute paths or repeat exports if needed. +# All commands are executed in a single shared shell session, +# so environment variables, `cd`, and other shell state persist across steps. +# Commands are executed in order and stop at the first failure. build-steps = [ - "make -C ./test-plugin-entry/", - "mkdir -p ./build/plugin-dir/", - "mv ./test-plugin-entry/library.so ./build/plugin-dir/library.so" + "make -C ./test-plugin-entry/", + "mkdir -p ./build/plugin-dir/", + "mv ./test-plugin-entry/library.so ./build/plugin-dir/library.so" ])"; #endif // !_TEXTS_HPP_ From 83147d2c3509b680a828e46099943624d91d49cd Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Tue, 5 Aug 2025 14:42:09 +0200 Subject: [PATCH 141/143] workflow: makefile: enable macos build --- .github/workflows/makefile.yml | 70 +++++++++++++++++----------------- Makefile | 2 +- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/.github/workflows/makefile.yml b/.github/workflows/makefile.yml index 351c778a..8451fe60 100644 --- a/.github/workflows/makefile.yml +++ b/.github/workflows/makefile.yml @@ -248,41 +248,41 @@ jobs: - name: Test customfetch run: ./build/debug/customfetch --wrap-lines - # build-macos: - # runs-on: macos-latest - # permissions: - # contents: read - # - # steps: - # - uses: actions/checkout@v4 - # - # - name: Install the packages - # run: HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 brew install --overwrite fastfetch neofetch tree llvm@19 - # - # - name: uname -a && clang++ --version - # run: uname -a && echo "\n" && $(brew --prefix llvm@19)/bin/clang++ --version - # - # - name: Clean - # run: make distclean - # - # - name: Compile - # run: make DEBUG=1 GUI_APP=0 CXX=$(brew --prefix llvm@19)/bin/clang++ - # - # - name: Test neofetch - # run: neofetch - # - # - name: Test fastfetch - # run: fastfetch - # - # - name: Test customfetch - # run: ./build/debug/customfetch -D assets - # - # - name: Upload to github artifacts - # uses: actions/upload-artifact@v4 - # with: - # if-no-files-found: error - # name: customfetch-macos - # path: ./build/debug/customfetch + build-macos: + runs-on: macos-latest + permissions: + contents: read + + steps: + - uses: actions/checkout@v4 + + - name: Install the packages + run: HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 brew install --overwrite fastfetch neofetch tree llvm@19 + + - name: uname -a && clang++ --version + run: uname -a && echo "\n" && $(brew --prefix llvm@19)/bin/clang++ --version + + - name: Clean + run: make distclean + + - name: Compile + run: make DEBUG=1 GUI_APP=0 CXX=$(brew --prefix llvm@19)/bin/clang++ + + - name: Test neofetch + run: neofetch + + - name: Test fastfetch + run: fastfetch + + - name: Test customfetch + run: ./build/debug/customfetch -D assets + + - name: Upload to github artifacts + uses: actions/upload-artifact@v4 + with: + if-no-files-found: error + name: customfetch-macos + path: ./build/debug/customfetch # test-suitcase: # runs-on: ubuntu-22.04 diff --git a/Makefile b/Makefile index 95909899..e8c169d3 100644 --- a/Makefile +++ b/Makefile @@ -29,7 +29,7 @@ ifeq ($(DEBUG), 1) LTO_FLAGS = -fno-lto CXXFLAGS := -ggdb3 -Wall -Wextra -pedantic -Wno-unused-parameter -fsanitize=address \ -DDEBUG=1 -fno-omit-frame-pointer $(DEBUG_CXXFLAGS) $(CXXFLAGS) - LDFLAGS += -fsanitize=address -fno-lto + LDFLAGS += -fsanitize=address -fno-lto -Wl,-rpath,$(BUILDDIR) else # Check if an optimization flag is not already set ifneq ($(filter -O%,$(CXXFLAGS)),) From 2e803b8ab9bf0d44f661d07dbf46851b716854fe Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Tue, 5 Aug 2025 22:46:14 +0200 Subject: [PATCH 142/143] update README.md --- README.md | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 2b91b82f..a0f45b54 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ </p> <h2></h2> <!-- add a separating line --> <p align="center"> - A system information fetch tool (or neofetch-like program), which its focus point is the performance and <b>customizability</b> + A modular information fetching (neofetch-like) tool, which its focus point is the performance and <b>customizability</b> </p> <p align="center"> @@ -34,8 +34,8 @@ ## Key Features * Run customfetch as a **terminal** or **GTK3 application** or even as an [android widget](https://github.com/Toni500github/customfetch-android-app) -* Really easy to customize (check [Config (with explanation)](#config-with-explanation) section) -* Fast (maybe) as [fastfetch](https://github.com/fastfetch-cli/fastfetch) +* Really easy to [customize](#How-to-customize) +* Incredibly extensible information fetchings via external plugins * Super lightweight, 3.3MB max (GTK3 application) # Dependencies @@ -73,7 +73,7 @@ yay -S customfetch-gui-bin ## General Distros (Manual installation) Download the latest `.tar.gz` tarball file in [releases](https://github.com/Toni500github/customfetch/releases/latest) \ -It contains the `/usr` directory where you'll install it in your distro. Useful for package managers too +It contains the `/usr` directory where you'll install it in your distro. Useful for package managers too. ## Arch and based (AUR) (source) ```bash @@ -96,7 +96,7 @@ yay -S customfetch-gui-git ## Compile from (source) (unstable) ```bash # clone the git dir -git clone https://github.com/Toni500github/customfetch +git clone --depth=1 https://github.com/Toni500github/customfetch cd customfetch # DEBUG=0 for release build @@ -107,7 +107,7 @@ make install DEBUG=0 GUI_APP=0 customfetch ``` -## Config (with explanation) +## How to customize Read the manual `customfetch.1` or execute customfetch with the arg `-w` for knowing more about the configuration in customfetch.\ This is only an explaination about tags and preview, that can be always found in the documentation. @@ -122,7 +122,7 @@ Here's an example using my config # The array for displaying the system infos layout = [ "$<title>", - "$<title_sep>", + "$<title.sep>", "${auto}OS: $<os.name> $<system.arch>", "${auto}Host: $<system.host>", "${auto}Kernel: $<os.kernel>", @@ -130,12 +130,12 @@ layout = [ "${auto}Terminal: $<user.terminal>", "${auto}Shell: $<user.shell>", "${auto}Packages: $<os.pkgs>", - "${auto}Theme: $<theme-gtk-all.name>", - "${auto}Icons: $<theme-gtk-all.icons>", - "${auto}Font: $<theme-gtk-all.font>", + "${auto}Theme: $<theme.gtk.all.name>", + "${auto}Icons: $<theme.gtk.all.icons>", + "${auto}Font: $<theme.gtk.all.font>", "${auto}Cursor: $<theme.cursor>", - "${auto}WM: $<user.wm_name> $<user.wm_version>", - "${auto}DE: $<user.de_name> $<user.de_version>", + "${auto}WM: $<user.wm.name> $<user.wm.version>", + "${auto}DE: $<user.de.name> $<user.de.version>", "$<auto.disk>", "${auto}Swap: $<swap>", "${auto}CPU: $<cpu>", @@ -143,7 +143,7 @@ layout = [ "${auto}RAM: $<ram>", "", "$<colors>", # normal colors palette - "$<colors_light>" # light colors palette + "$<colors.light>" # light colors palette ] @@ -151,16 +151,16 @@ layout = [ In the config we got an array variable called "layout". That's the variable where you customize how the infos should be displayed.\ There are 5 tags: -* `$<module.member>` - Used for printing the system info value of a member of a module. -* `${color}` - Used for displaying text in a specific color. +* `$<info.module>` - Used for printing the value of a module or its submembers. +* `${color}` - Used for displaying text in a specific color after it. * `$(bash command)` - Used to execute bash commands and print the output. * `$[something,equalToSomethingElse,iftrue,ifalse]` - Conditional tag to display different outputs based on the comparison. * `$%n1,n2%` - Used to print the percentage and print with colors They can be used in the ascii art text file and layout, but how to use them? -* **The info tag (`$<>`)** will print a value of a member of a module\ - e.g `$<user.name>` will print the username, `$<os.kernel_version>` will print the kernel version and so on.\ +* **The info tag (`$<>`)** will print a value of a member of a module.\ + e.g `$<user.name>` will print the username, `$<os.kernel.version>` will print the kernel version and so on.\ All the modules and their members are listed in the `--list-modules` argument * **The bash command tag (`$()`)** let's you execute bash commands and print the output\ @@ -214,8 +214,8 @@ They can be used in the ascii art text file and layout, but how to use them? Any `$` or brackets can be escaped with a backslash `\`. You need to escape backslashes too :(\ **NOTE:** For having compatibility with the GUI app, you need to escape `<` (EXCEPT if you are using in a info tag, like `$<os.name>`) and `&`\ -e.g `the number 50 is \< than 100 \& 98` -Won't affect the printing in terminal +e.g `the number 50 is \\< than 100 \\&\\& 98` +Won't affect the printing in terminal. ## Star History @@ -228,8 +228,8 @@ Won't affect the printing in terminal </a> # TODOs -* ~~release v1.0.0~~ -Empty so far! +* release v2.0.0 +* work on the android app (later) # Thanks I would like to thanks: From c88ba8d496dc5dbc0b492b658fb69f3905e32172 Mon Sep 17 00:00:00 2001 From: Toni500git <toni500minecraft@gmail.com> Date: Wed, 6 Aug 2025 15:12:15 +0200 Subject: [PATCH 143/143] misc: load first external modules and then the core ones --- src/main.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 5a0b2259..6e050f0f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -444,10 +444,8 @@ int main(int argc, char* argv[]) if (!parseargs(argc, argv, config, configFile)) return 1; config.loadConfigFile(configFile); - std::vector<void*> plugins_handle; - /* TODO(burntranch): track each library and unload them. */ - core_plugins_start(config); + std::vector<void*> plugins_handle; const std::filesystem::path pluginDir = configDir / "plugins"; std::filesystem::create_directories(pluginDir); for (const auto& entry : std::filesystem::recursive_directory_iterator{ pluginDir }) @@ -478,6 +476,10 @@ int main(int argc, char* argv[]) plugins_handle.push_back(handle); } + // The "conflicting" modules won't be overwritten by the main ones. + // First the external modules, then the core ones. + core_plugins_start(config); + if (display_modules) { modules_list();