#include "common.h" #include #include #include const int HIST_MAX = 20; void htmlencode(std::string& data) { std::string tmp; tmp.reserve(data.size() + 20); for (size_t i = 0; i != data.size(); i++) { switch (data[i]) { case '&': tmp += "&"; break; case '\"': tmp += """; break; case '\'': tmp += "'"; break; case '<': tmp += "<"; break; case '>': tmp += ">"; break; default: tmp += data[i]; break; } } data.swap(tmp); } void show_histogram(const Caches& cc, std::string Cache::*ptr, const std::string& caption, bool html, bool sort_by_val) { std::map histogram; std::vector> pairs; for (auto el : cc) histogram[el.*ptr]++; std::copy(histogram.begin(), histogram.end(), std::back_inserter(pairs)); if (sort_by_val) sort(pairs.begin(), pairs.end(), [&](std::pair& a, std::pair& b) { return a.second > b.second; }); else sort(pairs.begin(), pairs.end(), [&](std::pair& a, std::pair& b) { return a.first < b.first; }); if (html) { int max; if (sort_by_val) max = pairs[0].second; else max = std::max_element(pairs.begin(), pairs.end(), [&](std::pair& a, std::pair& b) { return a.second < b.second; })->second; int i = 0; std::cout << "

" << caption << "

\n"; std::cout << "
\n"; for (auto own : pairs) { htmlencode(own.first); if (own.first.empty()) own.first = "[unknown]"; if (i < HIST_MAX) std::cout << "
" << own.first << ": " << own.second << "
\n"; else if (i == HIST_MAX) { std::cout << "
\n"; std::cout << "
"; std::cout << " \n \n
\n
\n"; std::cout << own.first << " (" << own.second << ")"; } if (i > HIST_MAX) std::cout << ", " << own.first << " (" << own.second << ")"; i++; } if (i < HIST_MAX) std::cout << "\n"; else std::cout << "
\n
\n
\n"; } else { std::cout << caption << '\n'; for (auto own : pairs) std::cout << own.first << ": " << own.second << '\n'; } } static bool same_day(const std::tm& a, const std::tm& b) { return (a.tm_year == b.tm_year && a.tm_mon == b.tm_mon && a.tm_mday == b.tm_mday); } static void next_day(std::tm& a) { a.tm_mday++; mktime(&a); } int find_streak(const std::multimap& cc, std::tm& start) { int max_str = 0; int cur_str = 0; std::tm cur_tm; cur_tm.tm_year = 0; std::tm cur_start_tm = cur_tm; start = cur_tm; for (auto i : cc) { if (same_day(cur_tm, *std::localtime(&i.first))) continue; next_day(cur_tm); if (same_day(cur_tm, *std::localtime(&i.first))) { cur_str++; continue; } if (max_str < cur_str) { max_str = cur_str; start = cur_start_tm; } cur_str = 1; cur_tm = cur_start_tm = *std::localtime(&i.first); if (max_str == 0) { max_str = 1; start = cur_tm; } } if (max_str < cur_str) { max_str = cur_str; start = cur_start_tm; } return max_str; } long int get_num(char c, char* opt) { try { if (std::stoi(opt) > 0) { return std::stoi(opt); } else { std::cout << "Option \"-" << c << "\" requires a valid number as an argument\n"; std::exit(EXIT_FAILURE); } } catch (...) { std::cout << "Option \"-" << c << "\" requires a valid number as an argument\n"; std::exit(EXIT_FAILURE); } }