diff --git a/include/util.hpp b/include/util.hpp index 3c51b67..ba91709 100644 --- a/include/util.hpp +++ b/include/util.hpp @@ -23,6 +23,8 @@ struct byte_units_t float num_bytes; }; +constexpr const char NOCOLOR[] = "\033[0m"; +constexpr const char NOCOLOR_BOLD[] = "\033[0m\033[1m"; constexpr const char UNKNOWN[] = "(unknown)"; // magic line to be sure that I don't cut the wrong line @@ -55,17 +57,17 @@ std::string vendor_from_entry(size_t vendor_entry_pos, const std::string_view v std::string binarySearchPCIArray(const std::string_view vendor_id, const std::string_view pci_id); std::string binarySearchPCIArray(const std::string_view vendor_id); std::string shell_exec(const std::string_view cmd); -void getFileValue(u_short& iterIndex, const std::string& line, std::string& str, const size_t& amount); +void getFileValue(u_short& iterIndex, const std::string_view line, std::string& str, const size_t& amount); byte_units_t auto_devide_bytes(const size_t num); bool is_file_image(const unsigned char* bytes); void ctrl_d_handler(const std::istream& cin); std::string expandVar(std::string ret); std::string which(const std::string& command); bool read_binary_file(std::ifstream& f, std::string& ret); -void replace_str(std::string& str, const std::string& from, const std::string& to); +void replace_str(std::string& str, const std::string_view from, const std::string_view to); bool read_exec(std::vector cmd, std::string& output, bool useStdErr = false, bool noerror_print = true); -std::string str_tolower(std::string str); -std::string str_toupper(std::string str); +std::string str_tolower(std::string_view str); +std::string str_toupper(std::string_view str); void strip(std::string& input); std::string read_by_syspath(const std::string_view path); fmt::rgb hexStringToColor(const std::string_view hexstr); diff --git a/src/display.cpp b/src/display.cpp index 699c42a..38bc12f 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -96,7 +96,7 @@ std::vector Display::render(const Config& config, const colors_t& c { std::string pureOutput; std::string asciiArt_s = parse(line, systemInfo, pureOutput, config, colors, false); - asciiArt_s += config.gui ? "" : "\033[0m"; + asciiArt_s += config.gui ? "" : NOCOLOR; if (config.gui) { @@ -171,7 +171,7 @@ std::vector Display::render(const Config& config, const colors_t& c for (size_t j = 0; j < spaces; j++) layouts.at(i).insert(origin, " "); - layouts.at(i) += config.gui ? "" : "\033[0m"; + layouts.at(i) += config.gui ? "" : NOCOLOR; } for (; i < asciiArt.size(); i++) diff --git a/src/parse.cpp b/src/parse.cpp index edef38a..7a8096a 100644 --- a/src/parse.cpp +++ b/src/parse.cpp @@ -34,7 +34,7 @@ bool Query::RAM::m_bInit = false; bool Query::CPU::m_bInit = false; bool Query::User::m_bInit = false; -static std::array get_ansi_color(const std::string& str, const colors_t& colors) +static std::array get_ansi_color(const std::string_view str, const colors_t& colors) { if (hasStart(str, "38") || hasStart(str, "48")) die("Can't convert \\e[38; or \\e[48; codes in GUI. Please use #hexcode colors instead."); @@ -43,7 +43,7 @@ static std::array get_ansi_color(const std::string& str, const c if (first_m == std::string::npos) die("Parser: failed to parse layout/ascii art: missing m while using ANSI color escape code"); - std::string col = str; + std::string col = str.data(); col.erase(first_m); // 1;42 std::string weight = hasStart(col, "1;") ? "bold" : "normal"; std::string type = "fgcolor"; // either fgcolor or bgcolor @@ -123,6 +123,12 @@ std::string parse(const std::string_view input, systemInfo_t& systemInfo, std::s size_t dollarSignIndex = 0; size_t oldDollarSignIndex = 0; bool start = false; + + // we only use it in GUI mode, + // prevent issue where in the ascii art, + // theres at first either ${1} or ${0} + // and that's a problem with pango markup + bool firstrun_noclr = (parsingLaoyut ? false : true); static std::vector auto_colors; if (!config.sep_reset.empty() && parsingLaoyut) @@ -192,7 +198,7 @@ std::string parse(const std::string_view input, systemInfo_t& systemInfo, std::s if (static_cast(endBracketIndex) == -1) die("PARSER: Opened tag is not closed at index {} in string {}", dollarSignIndex, output); - std::string strToRemove = fmt::format("${}{}{}", opentag, command, type); + const std::string& strToRemove = fmt::format("${}{}{}", opentag, command, type); size_t start_pos = pureOutput.find(strToRemove); if (start_pos != std::string::npos) pureOutput.erase(start_pos, strToRemove.length()); @@ -204,7 +210,7 @@ std::string parse(const std::string_view input, systemInfo_t& systemInfo, std::s break; case '>': { - const size_t dot_pos = command.find('.'); + const size_t& dot_pos = command.find('.'); if (dot_pos == std::string::npos) die("module name '{}' doesn't have a dot '.' for separiting module name and submodule", command); @@ -217,6 +223,13 @@ std::string parse(const std::string_view input, systemInfo_t& systemInfo, std::s } break; case '}': // please pay very attention when reading this unreadable and godawful code + { + // if at end there a '$', it will make the end output "$" and so it will confuse addValueFromModule() + // and so let's make it "$ ". + // this geniunenly stupid + if (config.gui && output.back() == '$') + output += ' '; + if (!config.m_arg_colors_name.empty()) { const auto& it_name = std::find(config.m_arg_colors_name.begin(), config.m_arg_colors_name.end(), command); @@ -232,7 +245,7 @@ std::string parse(const std::string_view input, systemInfo_t& systemInfo, std::s command = config.m_arg_colors_value.at(it_value); goto jump; } - + if (command == *it_name) command = config.m_arg_colors_value.at(it_value); } @@ -248,9 +261,14 @@ std::string parse(const std::string_view input, systemInfo_t& systemInfo, std::s if (auto_colors.empty()) { if (is_image) - auto_colors.push_back(config.gui ? "white" : "\033[0m\033[1m"); + auto_colors.push_back(config.gui ? "white" : NOCOLOR_BOLD); else - auto_colors.push_back(config.gui ? "" : "\033[0m\033[1m"); + { + if (firstrun_noclr) + auto_colors.push_back(config.gui ? "" : NOCOLOR_BOLD); + else + auto_colors.push_back(config.gui ? "" : NOCOLOR_BOLD); + } } command = auto_colors.at(ver); @@ -258,23 +276,30 @@ std::string parse(const std::string_view input, systemInfo_t& systemInfo, std::s jump: if (command == "1") - output = - output.replace(dollarSignIndex, (endBracketIndex + 1) - dollarSignIndex, - config.gui ? "" : "\033[0m\033[1m"); + { + if (firstrun_noclr && !parsingLaoyut) + output = + output.replace(dollarSignIndex, (endBracketIndex + 1) - dollarSignIndex, + config.gui ? "" : NOCOLOR_BOLD); + else + output = + output.replace(dollarSignIndex, (endBracketIndex + 1) - dollarSignIndex, + config.gui ? "" : NOCOLOR_BOLD); + } else if (command == "0") - output = output.replace(dollarSignIndex, (endBracketIndex + 1) - dollarSignIndex, - config.gui ? "" : "\033[0m"); + { + if (firstrun_noclr && !parsingLaoyut) + output = output.replace(dollarSignIndex, (endBracketIndex + 1) - dollarSignIndex, + config.gui ? "" : NOCOLOR); + else + output = output.replace(dollarSignIndex, (endBracketIndex + 1) - dollarSignIndex, + config.gui ? "" : NOCOLOR); + } else { std::string str_clr; if (config.gui) { - // if at end there a '$', it will make the end output "$" and so it will confuse addValueFromModule() - // and so let's make it "$ " - // this geniunenly stupid - if (output.back() == '$') - output += ' '; - switch (fnv1a16::hash(command)) { case "black"_fnv1a16: str_clr = check_gui_ansi_clr(colors.gui_black); break; @@ -287,28 +312,28 @@ std::string parse(const std::string_view input, systemInfo_t& systemInfo, std::s case "white"_fnv1a16: str_clr = check_gui_ansi_clr(colors.gui_white); break; default: str_clr = command; break; } - + if (str_clr[0] == '!' && str_clr[1] == '#') { - //debug("output.substr(endBracketIndex + 1) = {}", output.substr(endBracketIndex + 1)); output = output.replace(dollarSignIndex, output.length() - dollarSignIndex, fmt::format("{}", str_clr.substr(1), output.substr(endBracketIndex + 1))); } - + else if (str_clr[0] == '#') { output = output.replace(dollarSignIndex, output.length() - dollarSignIndex, fmt::format("{}", str_clr, output.substr(endBracketIndex + 1))); } - + else if (hasStart(str_clr, "\\e") || hasStart(str_clr, "\033")) // "\\e" is for checking in the ascii_art, \033 in the config { const std::array clrs = get_ansi_color( (hasStart(str_clr, "\033") ? str_clr.substr(2) : str_clr.substr(3)), colors); + const std::string_view color = clrs.at(0); const std::string_view weight = clrs.at(1); const std::string_view type = clrs.at(2); @@ -319,6 +344,8 @@ std::string parse(const std::string_view input, systemInfo_t& systemInfo, std::s else error("PARSER: failed to parse line with color '{}'", str_clr); + + firstrun_noclr = false; } else @@ -376,6 +403,11 @@ std::string parse(const std::string_view input, systemInfo_t& systemInfo, std::s std::find(auto_colors.begin(), auto_colors.end(), command) == auto_colors.end()) auto_colors.push_back(command); } + + if (config.gui && firstrun_noclr && !parsingLaoyut) + output += ""; + } + break; } } diff --git a/src/util.cpp b/src/util.cpp index 6a7d884..7d74f67 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -201,7 +201,7 @@ void strip(std::string& input) * @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& line, std::string& str, const size_t& amount) +void getFileValue(u_short& iterIndex, const std::string_view line, std::string& str, const size_t& amount) { str = line.substr(amount); str.erase(std::remove(str.begin(), str.end(), '\"'), str.end()); @@ -264,13 +264,13 @@ bool read_binary_file(std::ifstream& f, std::string& ret) std::string which(const std::string& command) { - const std::string& env = std::getenv("PATH"); + const std::string_view env = std::getenv("PATH"); struct stat sb; std::string fullPath; for (const std::string& dir : split(env, ':')) { - fullPath = dir + "/" + command; + fullPath = dir + '/' + command; if ((stat(fullPath.c_str(), &sb) == 0) && sb.st_mode & S_IXUSR) return fullPath; } @@ -279,7 +279,7 @@ std::string which(const std::string& command) } // https://gist.github.com/GenesisFR/cceaf433d5b42dcdddecdddee0657292 -void replace_str(std::string& str, const std::string& from, const std::string& to) +void replace_str(std::string& str, const std::string_view from, const std::string_view to) { size_t start_pos = 0; while ((start_pos = str.find(from, start_pos)) != std::string::npos) @@ -350,20 +350,20 @@ bool read_exec(std::vector cmd, std::string& output, bool useStdErr return false; } -std::string str_tolower(std::string str) +std::string str_tolower(std::string_view str) { - for (char& x : str) + for (char x : str) x = std::tolower(x); - return str; + return str.data(); } -std::string str_toupper(std::string str) +std::string str_toupper(std::string_view str) { - for (char& x : str) + for (char x : str) x = std::toupper(x); - return str; + return str.data(); } // Function to perform binary search on the pci vendors array to find a device from a vendor.