From 28751f93698b446828ffe2c6df8ee2d33faa3a57 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 19 Jan 2022 22:23:28 +0100 Subject: [PATCH] Added string manipulation routines. Added tree sorting. --- Makefile | 2 +- include/Display.hpp | 16 +++++++++++++++ include/TreeNodeDiskUsage.hpp | 17 +++++++++++++++- src/Display.cpp | 30 +++++++++++++++++++++++++++ src/TreeNodeDiskUsage.cpp | 28 ++++++++++++++++++-------- src/main.cpp | 38 +++++++++++++++++++++++++++++++---- 6 files changed, 117 insertions(+), 14 deletions(-) diff --git a/Makefile b/Makefile index 638b750..86b5464 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ OBJECTS = $(SOURCES:$(SRC_PATH)/%.$(SRC_EXT)=$(BUILD_PATH)/%.o) DEPS = $(OBJECTS:.o=.d) # flags # -COMPILE_FLAGS = -Wall -Wextra -g -std=gnu++0x +COMPILE_FLAGS = -Wall -Wextra -std=gnu++0x -O3 # -g INCLUDES = -I include/ -I /usr/local/include # Space-separated pkg-config libraries used by this project LIBS = diff --git a/include/Display.hpp b/include/Display.hpp index b241a3f..49d0cce 100644 --- a/include/Display.hpp +++ b/include/Display.hpp @@ -2,6 +2,7 @@ #define H_Display #include +#include #include #include @@ -24,6 +25,12 @@ class Display /// Sets the line i to str. /!\ Warning : the line will be truncated at its max length of Cols(). void SetLine(unsigned int i, std::string const& str); + /// Sets the line i to str and centers it horizontally on the screen. /!\ Warning : the line will be truncated at its max length of Cols(). + void SetLineCentered(unsigned int i, std::string const& str, char fillChar = ' '); + + /// Sets the line i to str and justifies it to the right of the screen. /!\ Warning : the line will be truncated at its max length of Cols(). + void SetLineRjustified(unsigned int i, std::string const& str, char fillChar = ' '); + /// Get reference to "pixel" at row i, column j. char & GetPixel(unsigned int i, unsigned int j); @@ -52,6 +59,15 @@ class Display std::vector lines;// "bla ". If the string is longer than width, it is truncated. +std::string LeftJustify(std::string const& str, unsigned int width, char fillChar = ' '); + +/// Returns a centered string containing str, with fillChar used to fill the blank space : "bla", 7 -> " bla ". If the string is longer than width, it is truncated. +std::string CenterString(std::string const& str, unsigned int width, char fillChar = ' '); + +/// Returns a right-justified string containing str, with fillChar used to fill the blank space : "bla", 7 -> " bla". If the string is longer than width, it is truncated. +std::string RightJustify(std::string const& str, unsigned int width, char fillChar = ' '); + /// Creates a progress bar std::string GenerateProgressBar(unsigned int width, unsigned int current, unsigned int total, bool showPercentage = true, std::string const& fillChar = "\u25A0"); diff --git a/include/TreeNodeDiskUsage.hpp b/include/TreeNodeDiskUsage.hpp index 8cdc954..d06d677 100644 --- a/include/TreeNodeDiskUsage.hpp +++ b/include/TreeNodeDiskUsage.hpp @@ -4,9 +4,12 @@ #include #include #include +#include #include #include +#include + #define PRINT_VAR(x); std::cout << #x << "\t= " << (x) << "\n"; /// \struct PathFilters Stores the filters on paths. @@ -27,7 +30,7 @@ class TreeNodeDiskUsage bool MatchesFilter() const; /// Builds the whole tree - void BuildTree(); + void BuildTree(bool verbose = false, unsigned int screenWidth = 80); /// Prints the tree to the standard output only including the names of the nodes void PrintTree(unsigned int maxDepth = 0xFFFFFFFF, unsigned int depth = 0) const; @@ -46,6 +49,17 @@ class TreeNodeDiskUsage /// Returns the path of the node : /path/to/node.bla std::string GetNodePath() const; + + /// Sorts the children of the node by size in descending order. Non-recursive. + void SortBySizeDesc(); + + /// Sorts the children of the node by name in ascending order. Non-recursive. + void SortByNameAsc(); + + /// Operator used to sort the nodes by size in descending order. Returns true when a.totalSize > b.totalSize. + static bool SortOperatorSizeDesc(TreeNodeDiskUsage const& a, TreeNodeDiskUsage const& b); + /// Operator used to sort the nodes by size in descending order. Returns true when a.totalSize > b.totalSize. + static bool SortOperatorNameAsc(TreeNodeDiskUsage const& a, TreeNodeDiskUsage const& b); protected: /// Cleans the path to remove double slashes, trailing slashes and leading and trailing whitespaces. @@ -74,6 +88,7 @@ class TreeNodeDiskUsage bool isFolder; //d_name); } closedir(d); } @@ -90,10 +93,13 @@ void TreeNodeDiskUsage::PrintTree(unsigned int maxDepth, unsigned int depth) con if(depth > maxDepth) return; + std::string paddedPath = path; for(unsigned int i = 0 ; i < depth ; i++) - std::cout << " "; - //std::cout << path << "\n"; - std::cout << path << "\t" << totalSize << "\t" << totalSizeOnDisk << "\n"; + paddedPath = " " + paddedPath; + + unsigned int screenWidth = Display::GetTerminalSize().ws_col; + std::cout << std::setw(2*screenWidth/5) << std::left << paddedPath + << std::setw(screenWidth/6) << std::right << totalSize << std::setw(screenWidth/6) << totalSizeOnDisk << std::setw(screenWidth/6) << totalElements << "\n"; if(isFolder) for(unsigned int i = 0 ; i < children.size() ; i++) children[i].PrintTree(maxDepth, depth+1); @@ -124,6 +130,12 @@ std::string TreeNodeDiskUsage::GetNodeName() const return path.substr(lastSepPos+1, path.size()-lastSepPos-1); } +void TreeNodeDiskUsage::SortBySizeDesc() { std::sort(children.begin(), children.end(), TreeNodeDiskUsage::SortOperatorSizeDesc); } +void TreeNodeDiskUsage::SortByNameAsc() { std::sort(children.begin(), children.end(), TreeNodeDiskUsage::SortOperatorNameAsc); } + +bool TreeNodeDiskUsage::SortOperatorSizeDesc(TreeNodeDiskUsage const& a, TreeNodeDiskUsage const& b) { return a.totalSize > b.totalSize; } +bool TreeNodeDiskUsage::SortOperatorNameAsc(TreeNodeDiskUsage const& a, TreeNodeDiskUsage const& b) { return a.GetNodeName() < b.GetNodeName(); } + void TreeNodeDiskUsage::SanitizePath() { // Special cases handling diff --git a/src/main.cpp b/src/main.cpp index 5ac2950..0763309 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7,18 +7,44 @@ using std::cout; using std::cerr; using std::endl; +//#define D_UNIT_TESTS + +#ifdef D_UNIT_TESTS void runTests(int argc, char *argv[]); +#endif int main(int argc, char *argv[]) { + #ifdef D_UNIT_TESTS + runTests(argc, argv); + #else + + std::string rootpath = "."; + + // Parse arguments if(argc > 1) - runTests(argc, argv); - else - cerr << "Error : No path given !\n"; + { + rootpath = argv[1]; + } + + Display display; + + // Scan root path + TreeNodeDiskUsage tree(rootpath); + cout << "Scanning folder \"" << rootpath << "\" ...\n"; + tree.BuildTree(true, display.Cols()); + cout << endl; + + // DEBUG + tree.PrintTree(1); + tree.SortBySizeDesc(); tree.PrintTree(1); + tree.SortByNameAsc(); tree.PrintTree(1); + #endif // D_UNIT_TESTS return 0; } +#ifdef D_UNIT_TESTS void runTests(int /* argc */, char *argv[]) { if(0) @@ -144,6 +170,9 @@ void runTests(int /* argc */, char *argv[]) d.SetLine(11, "------------------------- Inverted -------------------------"); d.HighlightLine(11, true); d.SetLine(12, " That's normal, bro. Really !"); + d.SetLineCentered(13, "Bonjour tout le monde."); + d.SetLineCentered(14, "Tralala c'est moi la pute.", '-'); + d.SetLineRjustified(15, "Tralala c'est moi la pute, mais a droite de l'ecran.", '-'); Display::ClearScreen(); d.DrawScreenLines(); @@ -188,4 +217,5 @@ void runTests(int /* argc */, char *argv[]) } } } -} \ No newline at end of file +} +#endif // D_UNIT_TESTS \ No newline at end of file