Why not and or

This commit is contained in:
aristocratos 2021-06-21 22:52:55 +02:00
parent 3a783ae4a5
commit c222805383
9 changed files with 148 additions and 138 deletions

View file

@ -43,12 +43,12 @@ tab-size = 4
#if defined(__linux__)
#define LINUX
#elif defined(__unix__) || !defined(__APPLE__) && defined(__MACH__)
#elif defined(__unix__) or not defined(__APPLE__) and defined(__MACH__)
#include <sys/param.h>
#if defined(BSD)
#error BSD support not yet implemented!
#endif
#elif defined(__APPLE__) && defined(__MACH__)
#elif defined(__APPLE__) and defined(__MACH__)
#include <TargetConditionals.h>
#if TARGET_OS_MAC == 1
#define OSX
@ -92,6 +92,7 @@ namespace Global {
bool quitting = false;
bool arg_tty = false;
bool arg_low_color = false;
}
@ -100,31 +101,35 @@ void argumentParser(int argc, char **argv){
string argument;
for(int i = 1; i < argc; i++) {
argument = argv[i];
if (argument == "-v" || argument == "--version") {
if (argument == "-v" or argument == "--version") {
cout << "btop version: " << Global::Version << endl;
exit(0);
}
else if (argument == "-h" || argument == "--help") {
else if (argument == "-h" or argument == "--help") {
cout << "usage: btop [-h] [-v] [-/+t] [--debug]\n\n"
<< "optional arguments:\n"
<< " -h, --help show this help message and exit\n"
<< " -v, --version show version info and exit\n"
<< " -t, --tty_on force (ON) tty mode, max 16 colors and tty friendly graph symbols\n"
<< " +t, --tty_off force (OFF) tty mode\n"
<< " --debug start with loglevel set to DEBUG, overriding value set in config\n"
<< " -h, --help show this help message and exit\n"
<< " -v, --version show version info and exit\n"
<< " -lc, --low-color disable truecolor, converts 24-bit colors to 256-color\n"
<< " -t, --tty_on force (ON) tty mode, max 16 colors and tty friendly graph symbols\n"
<< " +t, --tty_off force (OFF) tty mode\n"
<< " --debug start with loglevel set to DEBUG, overriding value set in config\n"
<< endl;
exit(0);
}
else if (argument == "--debug")
Global::debug = true;
else if (argument == "-t" || argument == "--tty_on") {
else if (argument == "-t" or argument == "--tty_on") {
Config::set("tty_mode", true);
Global::arg_tty = true;
}
else if (argument == "+t" || argument == "--tty_off") {
else if (argument == "+t" or argument == "--tty_off") {
Config::set("tty_mode", false);
Global::arg_tty = true;
}
else if (argument == "-lc" or argument == "--low-color") {
Global::arg_low_color = true;
}
else {
cout << " Unknown argument: " << argument << "\n" <<
" Use -h or --help for help." << endl;
@ -137,7 +142,7 @@ void clean_quit(int sig){
if (Global::quitting) return;
if (Term::initialized) {
Term::restore();
if (!Global::debuginit) cout << Term::normal_screen << Term::show_cursor << flush;
if (not Global::debuginit) cout << Term::normal_screen << Term::show_cursor << flush;
}
Global::quitting = true;
Config::write();
@ -148,14 +153,14 @@ void clean_quit(int sig){
void sleep_now(){
if (Term::initialized) {
Term::restore();
if (!Global::debuginit) cout << Term::normal_screen << Term::show_cursor << flush;
if (not Global::debuginit) cout << Term::normal_screen << Term::show_cursor << flush;
}
std::raise(SIGSTOP);
}
void resume_now(){
Term::init();
if (!Global::debuginit) cout << Term::alt_screen << Term::hide_cursor << flush;
if (not Global::debuginit) cout << Term::alt_screen << Term::hide_cursor << flush;
}
void _exit_handler() { clean_quit(-1); }
@ -178,16 +183,22 @@ void _signal_handler(int sig) {
void banner_gen() {
size_t z = 0;
string b_color, bg, fg, oc, letter;
auto& truecolor = Config::getB("truecolor");
auto& lowcolor = Config::getB("lowcolor");
int bg_i;
Global::banner.clear();
Global::banner_width = 0;
auto tty_mode = (Config::getB("tty_mode"));
for (auto line: Global::Banner_src) {
if (auto w = ulen(line[1]); w > Global::banner_width) Global::banner_width = w;
fg = Theme::hex_to_color(line[0], !truecolor);
bg_i = 120 - z * 12;
bg = Theme::dec_to_color(bg_i, bg_i, bg_i, !truecolor);
if (tty_mode) {
fg = (z > 2) ? "\x1b[31m" : "\x1b[91m";
bg = (z > 2) ? "\x1b[90m" : "\x1b[37m";
}
else {
fg = Theme::hex_to_color(line[0], lowcolor);
bg_i = 120 - z * 12;
bg = Theme::dec_to_color(bg_i, bg_i, bg_i, lowcolor);
}
for (size_t i = 0; i < line[1].size(); i += 3) {
if (line[1][i] == ' ') {
letter = ' ';
@ -196,7 +207,7 @@ void banner_gen() {
else
letter = line[1].substr(i, 3);
if (tty_mode && letter != "" && letter != " ") letter = "";
// if (tty_mode and letter != "█" and letter != " ") letter = "░";
b_color = (letter == "") ? fg : bg;
if (b_color != oc) Global::banner += b_color;
Global::banner += letter;
@ -204,8 +215,9 @@ void banner_gen() {
}
if (++z < Global::Banner_src.size()) Global::banner += Mv::l(ulen(line[1])) + Mv::d(1);
}
Global::banner += Mv::r(18 - Global::Version.size()) + Fx::i + Theme::dec_to_color(0,0,0, !truecolor, "bg") +
Theme::dec_to_color(150, 150, 150, !truecolor) + "v" + Global::Version + Fx::ui;
Global::banner += Mv::r(18 - Global::Version.size())
+ (tty_mode ? "\x1b[0;40;37m" : Theme::dec_to_color(0,0,0, lowcolor, "bg") + Theme::dec_to_color(150, 150, 150, lowcolor))
+ Fx::i + "v" + Global::Version + Fx::ui;
}
//* Threading test function
@ -246,13 +258,13 @@ int main(int argc, char **argv){
//? Setup paths for config, log and themes
for (auto env : {"XDG_CONFIG_HOME", "HOME"}) {
if (getenv(env) != NULL && access(getenv(env), W_OK) != -1) {
if (getenv(env) != NULL and access(getenv(env), W_OK) != -1) {
Config::conf_dir = fs::path(getenv(env)) / (((string)env == "HOME") ? ".config/btop" : "btop");
break;
}
}
if (!Config::conf_dir.empty()) {
if (std::error_code ec; !fs::is_directory(Config::conf_dir) && !fs::create_directories(Config::conf_dir, ec)) {
if (not Config::conf_dir.empty()) {
if (std::error_code ec; not fs::is_directory(Config::conf_dir) and not fs::create_directories(Config::conf_dir, ec)) {
cout << "WARNING: Could not create or access btop config directory. Logging and config saving disabled." << endl;
cout << "Make sure your $HOME environment variable is correctly set to fix this." << endl;
}
@ -260,17 +272,17 @@ int main(int argc, char **argv){
Config::conf_file = Config::conf_dir / "btop.conf";
Logger::logfile = Config::conf_dir / "btop.log";
Theme::user_theme_dir = Config::conf_dir / "themes";
if (!fs::exists(Theme::user_theme_dir) && !fs::create_directory(Theme::user_theme_dir, ec)) Theme::user_theme_dir.clear();
if (not fs::exists(Theme::user_theme_dir) and not fs::create_directory(Theme::user_theme_dir, ec)) Theme::user_theme_dir.clear();
}
}
if (std::error_code ec; !Global::self_path.empty()) {
if (std::error_code ec; not Global::self_path.empty()) {
Theme::theme_dir = fs::canonical(Global::self_path / "../share/btop/themes", ec);
if (ec || access(Theme::theme_dir.c_str(), R_OK) == -1) Theme::theme_dir.clear();
if (ec or access(Theme::theme_dir.c_str(), R_OK) == -1) Theme::theme_dir.clear();
}
if (Theme::theme_dir.empty()) {
for (auto theme_path : {"/usr/local/share/btop/themes", "/usr/share/btop/themes"}) {
if (fs::exists(fs::path(theme_path)) && access(theme_path, R_OK) != -1) {
if (fs::exists(fs::path(theme_path)) and access(theme_path, R_OK) != -1) {
Theme::theme_dir = fs::path(theme_path);
break;
}
@ -281,15 +293,17 @@ int main(int argc, char **argv){
{ vector<string> load_errors;
Config::load(Config::conf_file, load_errors);
Config::set("lowcolor", (Global::arg_low_color ? true : not Config::getB("truecolor")));
if (Global::debug) Logger::set("DEBUG");
else Logger::set(Config::getS("log_level"));
Logger::debug("Logger set to DEBUG");
Logger::info("Logger set to " + Config::getS("log_level"));
for (auto& err_str : load_errors) Logger::warning(err_str);
}
if (!string(getenv("LANG")).ends_with("UTF-8") && !string(getenv("LANG")).ends_with("utf-8")) {
if (not string(getenv("LANG")).ends_with("UTF-8") and not string(getenv("LANG")).ends_with("utf-8")) {
string err_msg = "No UTF-8 locale was detected! Symbols might not look as intended.\n"
"Make sure your $LANG evironment variable is set and with a UTF-8 locale.";
Logger::warning(err_msg);
@ -297,19 +311,19 @@ int main(int argc, char **argv){
}
//? Initialize terminal and set options
if (!Term::init()) {
if (not Term::init()) {
string err_msg = "No tty detected!\nbtop++ needs an interactive shell to run.";
Logger::error(err_msg);
cout << "ERROR: " << err_msg << endl;
clean_quit(1);
}
Logger::debug("Running on " + Term::current_tty);
if (!Global::arg_tty && Config::getB("force_tty")) {
Logger::info("Running on " + Term::current_tty);
if (not Global::arg_tty and Config::getB("force_tty")) {
Config::set("tty_mode", true);
Logger::info("Forcing tty mode: setting 16 color mode and using tty friendly graph symbols");
}
else if (!Global::arg_tty && Term::current_tty.starts_with("/dev/tty")) {
else if (not Global::arg_tty and Term::current_tty.starts_with("/dev/tty")) {
Config::set("tty_mode", true);
Logger::info("Real tty detected, setting 16 color mode and using tty friendly graph symbols");
}
@ -340,7 +354,7 @@ int main(int argc, char **argv){
// cout << Theme("main_bg") << Term::clear << flush;
// bool thread_test = false;
if (!Global::debuginit) cout << Term::alt_screen << Term::hide_cursor << flush;
if (not Global::debuginit) cout << Term::alt_screen << Term::hide_cursor << flush;
cout << Theme::c("main_fg") << Theme::c("main_bg") << Term::clear << endl;
@ -473,12 +487,12 @@ int main(int argc, char **argv){
cout << Mv::d(1) << "Time: " << ktavg.front() << " μs. Avg: " << accumulate(ktavg.begin(), ktavg.end(), 0) / ktavg.size() << " μs. " << flush;
// if (flip) y--;
// else y++;
// if (y == 100 || y == 0) flip = !flip;
// if (y == 100 or y == 0) flip = not flip;
if (Input::poll()) {
if (Input::get() == "space") Input::wait(true);
else break;
}
sleep_ms(100);
sleep_ms(50);
}
Input::get();
@ -516,7 +530,7 @@ int main(int argc, char **argv){
// while (outputs.size() < 10){
// for (int i : iota(0, 10)){
// if (runners[i].valid() && runners[i].wait_for(std::chrono::milliseconds(10)) == future_status::ready) {
// if (runners[i].valid() and runners[i].wait_for(std::chrono::milliseconds(10)) == future_status::ready) {
// outputs[i] = runners[i].get();
// cout << "Thread " << i << " : " << outputs[i] << endl;
// }
@ -576,21 +590,21 @@ int main(int argc, char **argv){
+ Mv::restore;
for (auto& p : plist){
if (!Config::getB("proc_tree")) {
if (not Config::getB("proc_tree")) {
ostring += Mv::r(1) + greyscale[lc] + rjust(to_string(p.pid), 8) + " " + ljust(p.name, 16) + " " + ljust(p.cmd, Term::width - 66, true) + " "
+ rjust(to_string(p.threads), 5) + " " + ljust(p.user, 10) + " " + rjust(floating_humanizer(p.mem, true), 5) + string(11, ' ')
+ (p.cpu_p < 10 || p.cpu_p >= 100 ? rjust(to_string(p.cpu_p), 3) + " " : rjust(to_string(p.cpu_p), 4))
+ (p.cpu_p < 10 or p.cpu_p >= 100 ? rjust(to_string(p.cpu_p), 3) + " " : rjust(to_string(p.cpu_p), 4))
+ "\n";
}
else {
string cmd_cond;
if (!p.cmd.empty()) {
if (not p.cmd.empty()) {
cmd_cond = p.cmd.substr(0, std::min(p.cmd.find(' '), p.cmd.size()));
cmd_cond = cmd_cond.substr(std::min(cmd_cond.find_last_of('/') + 1, cmd_cond.size()));
}
ostring += Mv::r(1) + (Config::getB("tty_mode") ? " " : greyscale[lc]) + ljust(p.prefix + to_string(p.pid) + " " + p.name + " " + (!cmd_cond.empty() && cmd_cond != p.name ? "(" + cmd_cond + ")" : ""), Term::width - 40, true) + " "
ostring += Mv::r(1) + (Config::getB("tty_mode") ? "" : greyscale[lc]) + ljust(p.prefix + to_string(p.pid) + " " + p.name + " " + (not cmd_cond.empty() and cmd_cond != p.name ? "(" + cmd_cond + ")" : ""), Term::width - 40, true) + " "
+ rjust(to_string(p.threads), 5) + " " + ljust(p.user, 10) + " " + rjust(floating_humanizer(p.mem, true), 5) + string(11, ' ')
+ (p.cpu_p < 10 || p.cpu_p >= 100 ? rjust(to_string(p.cpu_p), 3) + " " : rjust(to_string(p.cpu_p), 4))
+ (p.cpu_p < 10 or p.cpu_p >= 100 ? rjust(to_string(p.cpu_p), 3) + " " : rjust(to_string(p.cpu_p), 4))
+ "\n";
}
if (lc++ > Term::height - 21) break;
@ -613,7 +627,7 @@ int main(int argc, char **argv){
else { key.clear() ; continue; }
if (filtering) {
if (key == "enter") filtering = false;
else if (key == "backspace") {if (!filter.empty()) filter = uresize(filter, ulen(filter) - 1);}
else if (key == "backspace" and not filter.empty()) filter = uresize(filter, ulen(filter) - 1);
else if (key == "space") filter.push_back(' ');
else if (ulen(key) == 1 ) filter.append(key);
else { key.clear(); continue; }

View file

@ -211,6 +211,7 @@ namespace Config {
{"show_battery", true},
{"tty_mode", false},
{"force_tty", false},
{"lowcolor", false},
};
unordered_flat_map<string, bool> boolsTmp;
@ -222,7 +223,7 @@ namespace Config {
bool _locked(const string& name){
atomic_wait(writelock);
if (!write_new && rng::find_if(descriptions, [&name](const auto& a){ return a.at(0) == name; }) != descriptions.end())
if (not write_new and rng::find_if(descriptions, [&name](const auto& a){ return a.at(0) == name; }) != descriptions.end())
write_new = true;
return locked.load();
}
@ -262,10 +263,10 @@ namespace Config {
void flip(string name){
if (_locked(name)) {
if (boolsTmp.contains(name)) boolsTmp.at(name) = !boolsTmp.at(name);
else boolsTmp.insert_or_assign(name, (!bools.at(name)));
if (boolsTmp.contains(name)) boolsTmp.at(name) = not boolsTmp.at(name);
else boolsTmp.insert_or_assign(name, (not bools.at(name)));
}
else bools.at(name) = !bools.at(name);
else bools.at(name) = not bools.at(name);
}
void lock(){
@ -297,7 +298,7 @@ namespace Config {
void load(fs::path conf_file, vector<string>& load_errors){
if (conf_file.empty())
return;
else if (!fs::exists(conf_file)) {
else if (not fs::exists(conf_file)) {
write_new = true;
return;
}
@ -308,9 +309,9 @@ namespace Config {
valid_names.push_back(n[0]);
string v_string;
getline(cread, v_string, '\n');
if (!v_string.ends_with(Global::Version))
if (not v_string.ends_with(Global::Version))
write_new = true;
while (!cread.eof()) {
while (not cread.eof()) {
cread >> std::ws;
if (cread.peek() == '#') {
cread.ignore(SSmax, '\n');
@ -318,21 +319,21 @@ namespace Config {
}
string name, value;
getline(cread, name, '=');
if (!v_contains(valid_names, name)) {
if (not v_contains(valid_names, name)) {
cread.ignore(SSmax, '\n');
continue;
}
if (bools.contains(name)) {
cread >> value;
if (!isbool(value))
if (not isbool(value))
load_errors.push_back("Got an invalid bool value for config name: " + name);
else
bools.at(name) = stobool(value);
}
else if (ints.contains(name)) {
cread >> value;
if (!isint(value))
if (not isint(value))
load_errors.push_back("Got an invalid integer value for config name: " + name);
else
ints.at(name) = stoi(value);
@ -345,9 +346,9 @@ namespace Config {
}
else cread >> value;
if (name == "log_level" && !v_contains(Logger::log_levels, value))
if (name == "log_level" and not v_contains(Logger::log_levels, value))
load_errors.push_back("Invalid log_level: " + value);
else if (name == "graph_symbol" && !v_contains(valid_graph_symbols, value))
else if (name == "graph_symbol" and not v_contains(valid_graph_symbols, value))
load_errors.push_back("Invalid graph symbol identifier: " + value);
else
strings.at(name) = value;
@ -356,12 +357,12 @@ namespace Config {
cread.ignore(SSmax, '\n');
}
cread.close();
if (!load_errors.empty()) write_new = true;
if (not load_errors.empty()) write_new = true;
}
}
void write(){
if (conf_file.empty() || !write_new) return;
if (conf_file.empty() or not write_new) return;
Logger::debug("Writing new config file");
std::ofstream cwrite(conf_file, std::ios::trunc);
if (cwrite.good()) {

View file

@ -27,8 +27,7 @@ tab-size = 4
#include <btop_theme.hpp>
#include <btop_tools.hpp>
using robin_hood::unordered_flat_map, std::round, std::views::iota,
std::string_literals::operator""s, std::clamp, std::array, std::floor;
using std::round, std::views::iota, std::string_literals::operator""s, std::clamp, std::array, std::floor;
namespace rng = std::ranges;
@ -103,7 +102,7 @@ namespace Draw {
string createBox(BoxConf c){
string out;
string lcolor = (c.line_color.empty()) ? Theme::c("div_line") : c.line_color;
string numbering = (c.num == 0) ? "" : Theme::c("hi_fg") + Symbols::superscript[c.num];
string numbering = (c.num == 0) ? "" : Theme::c("hi_fg") + (Config::getB("tty_mode") ? std::to_string(c.num) : Symbols::superscript[c.num]);
out = Fx::reset + lcolor;
@ -126,11 +125,11 @@ namespace Draw {
Mv::to(c.y + c.height - 1, c.x + c.width - 1) + Symbols::right_down;
//* Draw titles if defined
if (!c.title.empty()){
if (not c.title.empty()){
out += Mv::to(c.y, c.x + 2) + Symbols::title_left + Fx::b + numbering + Theme::c("title") + c.title +
Fx::ub + lcolor + Symbols::title_right;
}
if (!c.title2.empty()){
if (not c.title2.empty()){
out += Mv::to(c.y + c.height - 1, c.x + 2) + Symbols::title_left + Theme::c("title") + c.title2 +
Fx::ub + lcolor + Symbols::title_right;
}
@ -150,7 +149,7 @@ namespace Draw {
string Meter::operator()(int value) {
if (width < 1) return "";
value = clamp(value, 0, 100);
if (!cache.at(value).empty()) return cache.at(value);
if (not cache.at(value).empty()) return cache.at(value);
string& out = cache.at(value);
for (int i : iota(1, width + 1)) {
int y = round((double)i * 100.0 / width);
@ -167,20 +166,20 @@ namespace Draw {
void Graph::_create(const vector<long long>& data, int data_offset) {
const bool mult = (data.size() - data_offset > 1);
if (mult && (data.size() - data_offset) % 2 != 0) data_offset--;
if (mult and (data.size() - data_offset) % 2 != 0) data_offset--;
auto& graph_symbol = Symbols::graph_symbols.at(symbol + '_' + (invert ? "down" : "up"));
array<int, 2> result;
const float mod = (height == 1) ? 0.3 : 0.1;
long long data_value = 0;
if (mult && data_offset > 0) {
if (mult and data_offset > 0) {
last = data[data_offset - 1];
if (max_value > 0) last = clamp((last + offset) * 100 / max_value, 0ll, 100ll);
}
//? Horizontal iteration over values in <data>
for (int i : iota(data_offset, (int)data.size())) {
if (tty_mode && mult && i % 2 != 0) continue;
else if (!tty_mode) current = !current;
if (tty_mode and mult and i % 2 != 0) continue;
else if (not tty_mode) current = not current;
if (i == -1) { data_value = 0; last = 0; }
else data_value = data[i];
if (max_value > 0) data_value = clamp((data_value + offset) * 100 / max_value, 0ll, 100ll);
@ -197,13 +196,13 @@ namespace Draw {
result[ai++] = 0;
else {
result[ai++] = round((float)(value - cur_low) * 4 / (cur_high - cur_low) + mod);
if (no_zero && horizon == height - 1 && i != -1 && result[ai] == 0) result[ai] = 1;
if (no_zero and horizon == height - 1 and i != -1 and result[ai] == 0) result[ai] = 1;
}
}
//? Generate braille symbol from 5x5 2D vector
graphs[current][horizon] += (height == 1 && result[0] + result[1] == 0) ? Mv::r(1) : graph_symbol[(result[0] * 5 + result[1])];
graphs[current][horizon] += (height == 1 and result[0] + result[1] == 0) ? Mv::r(1) : graph_symbol[(result[0] * 5 + result[1])];
}
if (mult && i > data_offset) last = data_value;
if (mult and i > data_offset) last = data_value;
}
last = data_value;
@ -227,13 +226,13 @@ namespace Draw {
this->invert = invert; this->offset = offset;
this->no_zero = no_zero;
this->color_gradient = color_gradient;
if (Config::getB("tty_mode") || symbol == "tty") {
if (Config::getB("tty_mode") or symbol == "tty") {
tty_mode = true;
this->symbol = "tty";
}
else if (symbol != "default" && v_contains(Config::valid_graph_symbols, symbol)) this->symbol = symbol;
else if (symbol != "default") this->symbol = symbol;
else this->symbol = Config::getS("graph_symbol");
if (max_value == 0 && offset > 0) max_value = 100;
if (max_value == 0 and offset > 0) max_value = 100;
this->max_value = max_value;
int value_width = ceil((float)data.size() / 2);
int data_offset = 0;
@ -252,7 +251,7 @@ namespace Draw {
if (data_same) return out;
//? Make room for new characters on graph
bool select_graph = (tty_mode ? current : !current);
bool select_graph = (tty_mode ? current : not current);
for (int i : iota(0, height)) {
if (graphs[select_graph][i].starts_with(Fx::e)) graphs[current][i].erase(0, 4);
else graphs[select_graph][i].erase(0, 3);

View file

@ -78,10 +78,10 @@ namespace Draw {
public:
//* Set graph options and initialize with data
void operator()(int width, int height, string color_gradient, const vector<long long>& data, string symbol = "default", bool invert = false, bool no_zero = false, long long max_value = 0, long long offset = 0);
void operator()(int width, int height, string color_gradient, const vector<long long>& data, string symbol="default", bool invert=false, bool no_zero=false, long long max_value=0, long long offset=0);
//* Add last value from back of <data> and return string representation of graph
string& operator()(const vector<long long>& data, bool data_same = false);
string& operator()(const vector<long long>& data, bool data_same=false);
//* Return string representation of graph
string& operator()();

View file

@ -90,8 +90,8 @@ namespace Input {
//* Get a key or mouse action from input
string get(bool clear){
string key;
while (cin.rdbuf()->in_avail() > 0 && key.size() < 100) key += cin.get();
if (!clear && !key.empty()){
while (cin.rdbuf()->in_avail() > 0 and key.size() < 100) key += cin.get();
if (not clear and not key.empty()){
if (key.substr(0,2) == Fx::e) key.erase(0, 1);
if (Key_escapes.contains(key)) key = Key_escapes.at(key);
else if (ulen(key) > 1) key = "";

View file

@ -94,7 +94,7 @@ namespace Proc {
//* Generate process tree list
void _tree_gen(proc_info& cur_proc, vector<proc_info>& in_procs, vector<proc_info>& out_procs, int cur_depth, bool collapsed, string& prefix){
auto cur_pos = out_procs.size();
if (!collapsed)
if (not collapsed)
out_procs.push_back(cur_proc);
int children = 0;
@ -109,7 +109,7 @@ namespace Proc {
}
if (collapsed) return;
if (out_procs.size() > cur_pos + 1 && !out_procs.back().prefix.ends_with("] ")) {
if (out_procs.size() > cur_pos + 1 and not out_procs.back().prefix.ends_with("] ")) {
out_procs.back().prefix.resize(out_procs.back().prefix.size() - 8);
out_procs.back().prefix += " └─ ";
}
@ -138,13 +138,13 @@ namespace Proc {
(void)tree;
//* Update uid_user map if /etc/passwd changed since last run
if (!passwd_path.empty() && fs::last_write_time(passwd_path) != passwd_time) {
if (not passwd_path.empty() and fs::last_write_time(passwd_path) != passwd_time) {
string r_uid, r_user;
passwd_time = fs::last_write_time(passwd_path);
uid_user.clear();
pread.open(passwd_path);
if (pread.good()) {
while (!pread.eof()){
while (not pread.eof()){
getline(pread, r_user, ':');
pread.ignore(SSmax, ':');
getline(pread, r_uid, ':');
@ -176,13 +176,13 @@ namespace Proc {
bool new_cache = false;
string pid_str = d.path().filename();
if (d.is_directory() && isdigit(pid_str[0])) {
if (d.is_directory() and isdigit(pid_str[0])) {
npids++;
proc_info new_proc (stoul(pid_str));
pid_list.push_back(new_proc.pid);
//* Cache program name, command and username
if (!cache.contains(new_proc.pid)) {
if (not cache.contains(new_proc.pid)) {
string name, cmd, user;
new_cache = true;
pread.open(d.path() / "comm");
@ -197,14 +197,14 @@ namespace Proc {
string tmpstr = "";
while(getline(pread, tmpstr, '\0')) cmd += tmpstr + " ";
pread.close();
if (!cmd.empty()) cmd.pop_back();
if (not cmd.empty()) cmd.pop_back();
}
else continue;
pread.open(d.path() / "status");
if (pread.good()) {
string uid;
while (!pread.eof()){
while (not pread.eof()){
string line;
getline(pread, line, ':');
if (line == "Uid") {
@ -216,18 +216,18 @@ namespace Proc {
}
}
pread.close();
user = (!uid.empty() && uid_user.contains(uid)) ? uid_user.at(uid) : uid;
user = (not uid.empty() and uid_user.contains(uid)) ? uid_user.at(uid) : uid;
}
else continue;
cache[new_proc.pid] = {name, cmd, user};
}
//* Match filter if defined
if (!filter.empty()
&& pid_str.find(filter) == string::npos
&& cache[new_proc.pid].name.find(filter) == string::npos
&& cache[new_proc.pid].cmd.find(filter) == string::npos
&& cache[new_proc.pid].user.find(filter) == string::npos) {
if (not filter.empty()
and pid_str.find(filter) == string::npos
and cache[new_proc.pid].name.find(filter) == string::npos
and cache[new_proc.pid].cmd.find(filter) == string::npos
and cache[new_proc.pid].user.find(filter) == string::npos) {
if (new_cache) cache.erase(new_proc.pid);
continue;
}
@ -336,14 +336,14 @@ namespace Proc {
}
//* When sorting with "cpu lazy" push processes over threshold cpu usage to the front regardless of cumulative usage
if (sorting == "cpu lazy" && !tree && !reverse) {
if (sorting == "cpu lazy" and not tree and not reverse) {
double max = 10.0, target = 30.0;
for (size_t i = 0, offset = 0; i < procs.size(); i++) {
if (i <= 5 && procs[i].cpu_p > max)
if (i <= 5 and procs[i].cpu_p > max)
max = procs[i].cpu_p;
else if (i == 6)
target = (max > 30.0) ? max : 10.0;
if (i == offset && procs[i].cpu_p > 30.0)
if (i == offset and procs[i].cpu_p > 30.0)
offset++;
else if
(procs[i].cpu_p > target) rotate(procs.begin() + offset, procs.begin() + i, procs.begin() + i + 1);
@ -366,7 +366,7 @@ namespace Proc {
//* Clear dead processes from cache at a regular interval
if (++counter >= 10000 || ((int)cache.size() > npids + 100)) {
if (++counter >= 10000 or ((int)cache.size() > npids + 100)) {
counter = 0;
unordered_flat_map<uint, p_cache> r_cache;
r_cache.reserve(pid_list.size());
@ -383,7 +383,7 @@ namespace Proc {
//* Initialize needed variables for collect
void init(){
proc_path = (fs::is_directory(fs::path("/proc")) && access("/proc", R_OK) != -1) ? "/proc" : "";
proc_path = (fs::is_directory(fs::path("/proc")) and access("/proc", R_OK) != -1) ? "/proc" : "";
if (proc_path.empty()) {
string errmsg = "Proc filesystem not found or no permission to read from it!";
Logger::error(errmsg);

View file

@ -85,7 +85,7 @@ namespace Theme {
};
const unordered_flat_map<string, string> TTY_theme = {
{ "main_bg", "\x1b[40m" },
{ "main_bg", "\x1b[0;40m" },
{ "main_fg", "\x1b[37m" },
{ "title", "\x1b[97m" },
{ "hi_fg", "\x1b[31m" },
@ -132,7 +132,7 @@ namespace Theme {
namespace {
//* Convert 24-bit colors to 256 colors using 6x6x6 color cube
int truecolor_to_256(int r, int g, int b){
if (round((double)r / 11) == round((double)g / 11) && round((double)g / 11) == round((double)b / 11)) {
if (round((double)r / 11) == round((double)g / 11) and round((double)g / 11) == round((double)b / 11)) {
return 232 + round((double)r / 11);
} else {
return round((double)r / 51) * 36 + round((double)g / 51) * 6 + round((double)b / 51) + 16;
@ -143,7 +143,7 @@ namespace Theme {
string hex_to_color(string hexa, bool t_to_256, string depth){
if (hexa.size() > 1){
hexa.erase(0, 1);
for (auto& c : hexa) if (!isxdigit(c)) {
for (auto& c : hexa) if (not isxdigit(c)) {
Logger::error("Invalid hex value: " + hexa);
return "";
}
@ -210,7 +210,7 @@ namespace Theme {
array<int, 3> hex_to_dec(string hexa){
if (hexa.size() > 1){
hexa.erase(0, 1);
for (auto& c : hexa) if (!isxdigit(c)) return array<int, 3>{-1, -1, -1};
for (auto& c : hexa) if (not isxdigit(c)) return array<int, 3>{-1, -1, -1};
if (hexa.size() == 2){
int h_int = stoi(hexa, 0, 16);
@ -231,10 +231,10 @@ namespace Theme {
void generateColors(unordered_flat_map<string, string> source){
vector<string> t_rgb;
string depth;
bool t_to_256 = !Config::getB("truecolor");
bool t_to_256 = Config::getB("lowcolor");
colors.clear(); rgbs.clear();
for (auto& [name, color] : Default_theme) {
depth = (name.ends_with("bg") && name != "meter_bg") ? "bg" : "fg";
depth = (name.ends_with("bg") and name != "meter_bg") ? "bg" : "fg";
if (source.contains(name)) {
if (source.at(name)[0] == '#') {
colors[name] = hex_to_color(source.at(name), t_to_256, depth);
@ -262,9 +262,9 @@ namespace Theme {
void generateGradients(){
gradients.clear();
array<string, 101> c_gradient;
bool t_to_256 = !Config::getB("truecolor");
bool t_to_256 = Config::getB("lowcolor");
for (auto& [name, source_arr] : rgbs) {
if (!name.ends_with("_start")) continue;
if (not name.ends_with("_start")) continue;
array<array<int, 3>, 101> dec_arr;
dec_arr[0][0] = -1;
string wname = rtrim(name, "_start");
@ -298,32 +298,25 @@ namespace Theme {
}
}
//* Set colors and generate gradients for the TTY theme
void generateTTYColors(){
rgbs.clear();
colors = TTY_theme;
gradients.clear();
for (auto& c : colors) {
if (!c.first.ends_with("_start")) continue;
if (not c.first.ends_with("_start")) continue;
string base_name = rtrim(c.first, "_start");
string section = "_start";
int split = colors.at(base_name + "_mid").empty() ? 50 : 33;
for (int i : iota(0, 101)) {
gradients[base_name][i] = colors.at(base_name + section);
if (i == split) {
if (split == 50 || split == 66)
section = "_end";
else {
section = "_mid";
split *= 2;
}
section = (split == 33) ? "_mid" : "_end";
split *= 2;
}
}
}
}
auto loadFile(string filename){
@ -334,13 +327,16 @@ namespace Theme {
}
void updateThemes(){
themes.clear();
themes.push_back("Default");
themes.push_back("TTY");
}
//* Set current theme using <source> map
void set(string theme){
if (theme == "TTY" || Config::getB("tty_mode"))
if (theme == "TTY" or Config::getB("tty_mode"))
generateTTYColors();
else {
generateColors((theme == "Default" ? Default_theme : loadFile(theme)));

View file

@ -63,7 +63,7 @@ namespace Fx {
const regex color_regex("\033\\[\\d+;?\\d?;?\\d*;?\\d*;?\\d*(m){1}");
string uncolor(string& s){
string uncolor(const string& s){
return regex_replace(s, color_regex, "");
}
}
@ -129,7 +129,7 @@ namespace Term {
bool refresh(){
struct winsize w;
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
if (width != w.ws_col || height != w.ws_row) {
if (width != w.ws_col or height != w.ws_row) {
width = w.ws_col;
height = w.ws_row;
resized = true;
@ -138,7 +138,7 @@ namespace Term {
}
bool init(){
if (!initialized){
if (not initialized){
initialized = (bool)isatty(STDIN_FILENO);
if (initialized) {
tcgetattr(STDIN_FILENO, &initial_settings);
@ -206,11 +206,11 @@ namespace Tools {
}
bool isbool(string& str){
return (str == "true") || (str == "false") || (str == "True") || (str == "False");
return (str == "true") or (str == "false") or (str == "True") or (str == "False");
}
bool stobool(string& str){
return (str == "true" || str == "True");
return (str == "true" or str == "True");
}
bool isint(string& str){
@ -241,7 +241,7 @@ namespace Tools {
| rng::views::transform([](auto &&rng) {
return string_view(&*rng.begin(), rng::distance(rng));
})) {
if (!s.empty()) out.emplace_back(s);
if (not s.empty()) out.emplace_back(s);
}
return out;
}
@ -251,23 +251,23 @@ namespace Tools {
}
string ljust(string str, const size_t x, bool utf, bool escape, bool lim){
if (utf || escape) {
if (!escape && lim && ulen(str) > x) str = uresize(str, x);
if (utf or escape) {
if (not escape and lim and ulen(str) > x) str = uresize(str, x);
return str + string(max((int)(x - ulen(str, escape)), 0), ' ');
}
else {
if (lim && str.size() > x) str.resize(x);
if (lim and str.size() > x) str.resize(x);
return str + string(max((int)(x - str.size()), 0), ' ');
}
}
string rjust(string str, const size_t x, bool utf, bool escape, bool lim){
if (utf || escape) {
if (!escape && lim && ulen(str) > x) str = uresize(str, x);
if (utf or escape) {
if (not escape and lim and ulen(str) > x) str = uresize(str, x);
return string(max((int)(x - ulen(str, escape)), 0), ' ') + str;
}
else {
if (lim && str.size() > x) str.resize(x);
if (lim and str.size() > x) str.resize(x);
return string(max((int)(x - str.size()), 0), ' ') + str;
}
}
@ -280,7 +280,7 @@ namespace Tools {
while ((pos = oldstr.find(' ')) != string::npos){
newstr.append(oldstr.substr(0, pos));
size_t x = 0;
while (pos + x < oldstr.size() && oldstr.at(pos + x) == ' ') x++;
while (pos + x < oldstr.size() and oldstr.at(pos + x) == ' ') x++;
newstr.append(Mv::r(x));
oldstr.remove_prefix(pos + x);
}
@ -320,8 +320,8 @@ namespace Tools {
}
if (out.empty()) {
out = to_string(value);
if (out.size() == 4 && start > 0) { out.pop_back(); out.insert(2, ".");}
else if (out.size() == 3 && start > 0) out.insert(1, ".");
if (out.size() == 4 and start > 0) { out.pop_back(); out.insert(2, ".");}
else if (out.size() == 3 and start > 0) out.insert(1, ".");
else if (out.size() >= 2) out.resize(out.size() - 2);
}
if (shorten){
@ -395,16 +395,16 @@ namespace Logger {
}
void log_write(uint level, string& msg){
if (loglevel < level || logfile.empty()) return;
if (loglevel < level or logfile.empty()) return;
atomic_wait_set(busy, true);
std::error_code ec;
if (fs::exists(logfile) && fs::file_size(logfile, ec) > 1024 << 10 && !ec) {
if (fs::exists(logfile) and fs::file_size(logfile, ec) > 1024 << 10 and not ec) {
auto old_log = logfile;
old_log += ".1";
if (fs::exists(old_log)) fs::remove(old_log, ec);
if (!ec) fs::rename(logfile, old_log, ec);
if (not ec) fs::rename(logfile, old_log, ec);
}
if (!ec) {
if (not ec) {
std::ofstream lwrite(logfile, std::ios::app);
if (first) { first = false; lwrite << "\n" << strf_time(tdf) << "===> btop++ v." << Global::Version << "\n";}
lwrite << strf_time(tdf) << log_levels.at(level) << ": " << msg << "\n";

View file

@ -60,7 +60,7 @@ namespace Fx {
extern const std::regex color_regex;
//* Return a string with all colors and text styling removed
string uncolor(string& s);
string uncolor(const string& s);
}
//* Collection of escape codes and functions for cursor manipulation