├── fmanager ├── samples ├── libcpp-file-manager.a ├── CMakeLists.txt ├── README.md ├── sample.cpp └── FileManager.hpp ├── CMakeLists.txt ├── LICENSE ├── .github └── workflows │ └── build-filemanager.yml ├── include └── FileManager.hpp ├── README.md └── src └── FileManager.cpp /fmanager: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krshrimali/CPP-File-Manager/master/fmanager -------------------------------------------------------------------------------- /samples/libcpp-file-manager.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krshrimali/CPP-File-Manager/master/samples/libcpp-file-manager.a -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.0.0) 2 | project(cpp-file-manager VERSION 0.1.0) 3 | set(CMAKE_CXX_STANDARD 17) 4 | set(CMAKE_EXPORT_COMPILE_COMMANDS ON) 5 | 6 | include(CTest) 7 | enable_testing() 8 | 9 | include_directories("include") 10 | add_library(cpp-file-manager src/FileManager.cpp) 11 | 12 | set(CPACK_PROJECT_NAME ${PROJECT_NAME}) 13 | set(CPACK_PROJECT_VERSION ${PROJECT_VERSION}) 14 | include(CPack) 15 | -------------------------------------------------------------------------------- /samples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.0.0) 2 | project(cpp-file-manager-samples VERSION 0.1.0) 3 | set(CMAKE_CXX_STANDARD 17) 4 | set(CMAKE_EXPORT_COMPILE_COMMANDS ON) 5 | 6 | include(CTest) 7 | enable_testing() 8 | 9 | include_directories("../include") 10 | add_executable(fmanager sample.cpp) 11 | target_link_libraries(fmanager ${CMAKE_CURRENT_SOURCE_DIR}/libcpp-file-manager.a) 12 | add_definitions(-DNDEBUG) 13 | 14 | set(CPACK_PROJECT_NAME ${PROJECT_NAME}) 15 | set(CPACK_PROJECT_VERSION ${PROJECT_VERSION}) 16 | include(CPack) 17 | -------------------------------------------------------------------------------- /samples/README.md: -------------------------------------------------------------------------------- 1 | ## Usage 2 | 3 | This directory contains sample file on using the `FileManager`. Follow these steps: 4 | 5 | ```bash 6 | mkdir build/ && cd build 7 | cmake .. && make && ./fmanager -h 8 | ``` 9 | 10 | **Tree file generated of this project** 11 | 12 | ``` 13 | |-- README.md 14 | |-- src 15 | |-- FileManager.cpp 16 | |-- samples 17 | |-- FileManager.hpp 18 | |-- README.md 19 | |-- sample.cpp 20 | |-- libcpp-file-manager.a 21 | |-- build 22 | |-- CMakeLists.txt 23 | |-- .git 24 | |-- CMakeLists.txt 25 | |-- include 26 | |-- FileManager.hpp 27 | |-- .github 28 | ``` 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Himanshu Singh 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.github/workflows/build-filemanager.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow to help you get started with Actions 2 | 3 | name: File Manager Buffet Codes 4 | 5 | # Controls when the action will run. Triggers the workflow on push or pull request 6 | # events but only for the master branch 7 | on: 8 | pull_request: 9 | push: 10 | branches: 11 | - master 12 | - develop 13 | 14 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 15 | jobs: 16 | # This workflow contains a single job called "build" 17 | build: 18 | # The type of runner that the job will run on 19 | runs-on: ubuntu-latest 20 | 21 | # Steps represent a sequence of tasks that will be executed as part of the job 22 | steps: 23 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 24 | - uses: actions/checkout@v2 25 | 26 | - name: setup-system 27 | run: sudo apt-get install libboost-all-dev 28 | 29 | - name: cmake-build 30 | run: mkdir build && cd build && cmake .. && make && cp *.a ../samples/ 31 | 32 | - name: cmake-samples 33 | run: cd samples && mkdir build && cd build && cmake .. && make && ./fmanager -p ../../ -t -d .git,build -e .pyc && cat tree.txt 34 | -------------------------------------------------------------------------------- /samples/sample.cpp: -------------------------------------------------------------------------------- 1 | #include "FileManager.hpp" 2 | #include 3 | #include 4 | #include 5 | 6 | const char *program_name = "fmanager"; // Use for printing usage 7 | 8 | void print_usage() { 9 | printf("Usage: %s options\n", program_name); 10 | printf(" -h --help Print usage.\n" 11 | " -p --path filePath Input path (to be iterated).\n" 12 | " -l --list_files Call the list files function.\n" 13 | " -t --tree Call the tree function.\n" 14 | " -d --ignore_dirs dir1,dir2 Ignore dirs while creating tree\n" 15 | " -e --ignore_extensions ext1,ext2 Ignore extensions while creating " 16 | "tree\n" 17 | " -s --separator Separator you want for your tree " 18 | "output\n"); 19 | exit(-1); 20 | } 21 | 22 | std::vector split(std::string s, std::string delimiter) { 23 | size_t pos = 0; 24 | std::vector output; 25 | while ((pos = s.find(delimiter)) != std::string::npos) { 26 | std::string token = s.substr(0, pos); 27 | output.push_back(token); 28 | s.erase(0, pos + delimiter.length()); 29 | } 30 | output.push_back(s); 31 | return output; 32 | } 33 | 34 | int main(int argc, char **argv) { 35 | const char *short_options = "hp:s:ltd:e:"; 36 | const struct option long_options[] = {{"help", 0, nullptr, 'h'}, 37 | {"path", 1, nullptr, 'p'}, 38 | {"separator", 1, nullptr, 's'}, 39 | {"list_files", 0, nullptr, 'l'}, 40 | {"tree", 0, nullptr, 't'}, 41 | {"ignore_dirs", 1, nullptr, 'd'}, 42 | {"ignore_extensions", 1, nullptr, 'e'}, 43 | {nullptr, 0, nullptr, 0}}; 44 | 45 | std::string path = ""; 46 | std::string separator = ""; 47 | bool list_files = true; 48 | bool draw_tree = false; 49 | int opt; 50 | std::vector ignore_dirs = {}; 51 | std::vector ignore_extensions = {}; 52 | 53 | do { 54 | opt = getopt_long(argc, argv, short_options, long_options, NULL); 55 | switch (opt) { 56 | case 'h': /* -h or --help */ 57 | // Print usage information 58 | print_usage(); 59 | break; 60 | case 'p': /* -p or --path */ 61 | path = optarg; 62 | break; 63 | case 'l': /* -l or --list_files */ 64 | list_files = true; 65 | break; 66 | case 't': /* -t or --tree */ 67 | draw_tree = true; 68 | break; 69 | case 'd': /* -d or --ignore_dirs */ 70 | ignore_dirs = split(optarg, ","); 71 | break; 72 | case 'e': /* -e or --ignore_extensions */ 73 | ignore_extensions = split(optarg, ","); 74 | break; 75 | case 's': 76 | separator = optarg; 77 | break; 78 | case -1: /* Done with options */ 79 | break; 80 | default: /* Unexpected */ 81 | abort(); 82 | } 83 | } while (opt != -1); 84 | 85 | if (path == "") { 86 | // By default use the current folder as the path 87 | path = "."; 88 | } 89 | 90 | FileManager *file; 91 | if (separator != "") { 92 | file = new FileManager(path, separator); 93 | } else { 94 | file = new FileManager(path); 95 | } 96 | // file.info(); // Prints the path you entered to the console 97 | if (list_files) { 98 | for (auto const &item : file->list_files()) { 99 | std::cout << item.rname << std::endl; 100 | } 101 | } 102 | if (draw_tree) { 103 | file->writeToFile(/*ignore_folders=*/ignore_dirs, 104 | /*ignore_extensions=*/ignore_extensions); 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /include/FileManager.hpp: -------------------------------------------------------------------------------- 1 | // FileManager class 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | class FileManager { 11 | // FileManager Class 12 | // Public Methods: 13 | // 1. clear(): clears the memory allocated for folder path (a.k.a corePath) 14 | // 2. clear(string): replaces the core path with the given path 15 | // 3. info(): Prints the core path to the console. 16 | // 4. list_files(vector extensions, bool ignore_extensions): Use this 17 | // to list files in the path given while creating the constructor. Pass 18 | // extensions and ignore_extensions as true/false to ignore the given 19 | // extensions or not. 20 | // 5. writeToFile(vector ignore_dirs, vector 21 | // ignore_extensions): Use this to create a tree like format (iterative till 22 | // the leaf nodes) for the given directory/path. Pass list of dirs you want to 23 | // ignore in ignore_dirs, and list of extensions you want to ignore in 24 | // ignore_extensions (e.g. ".jpg", ".png" and not "jpg", "png") 25 | public: 26 | // This struct helps us to keep track of important information of the file 27 | // name - absolute path (e.g: /home/BuffetCodes/Documents/FileManager.cpp) 28 | // rname - just the name of the file or directory (e.g: FileManager.cpp) 29 | // is_dir - set to true if the entity is a directory, else false 30 | struct file_info { 31 | std::string name; 32 | std::string rname; 33 | bool is_dir; 34 | }; 35 | 36 | // FileManager constructor 37 | // Pass the path you want to operate this FileManager with. 38 | // You can change the path using: .clear(string newPath) 39 | FileManager(std::string path) { this->corePath = path; } 40 | 41 | // Pass the separator along with your path 42 | FileManager(std::string path, const std::string &separator) { 43 | this->separator = separator; 44 | this->corePath = path; 45 | } 46 | 47 | // This will clear the corePath string variable. 48 | void clear(); 49 | // This will change the corePath string variable to new path. 50 | void clear(std::string); 51 | // This will print the corePath (a.k.a the path) to the console 52 | void info(); 53 | // This function will list files in the path given during creating the object 54 | // or while changing path using clear(newPath) Arguments (not keyword args) 55 | // ========== 56 | // 1. extensions (std::vector, default value = {}): Just list the 57 | // extensions you either want to ignore or you just want to list. 58 | // 2. ignore_extensions (bool, default value = false): If true, the extensions 59 | // passed in the list of extensions will be ignored and nost listed. If false, 60 | // the extensions passed will be listed only. Returns 61 | // ========== 62 | // A vector of file_info struct (see the documentation of file_info to see how 63 | // to access it's elements) 64 | std::vector list_files(std::vector extensions = {}, 65 | bool ignore_extensions = false); 66 | // This function will write a tree like structure to file named "tree.txt" in 67 | // the same folder from where the binary file is called. Arguments (not 68 | // keyword args) 69 | // ========== 70 | // 1. ignore_dirs (std::vector, default value = {}): The list of 71 | // dirs you want to ignore in the tree. These directories will not be expanded 72 | // or iterated, the name will be listed though. 73 | // 2. ignore_extensions (std::vector, default value = {}): The 74 | // list of extensions you want to ignore. The extensions you want to pass 75 | // should have "." (dot), like {".jpg", ".png"} 76 | void writeToFile(std::vector ignore_dirs = {}, 77 | std::vector ignore_extensions = {}); 78 | 79 | void set_separator(const std::string &); 80 | std::string get_separator(); 81 | bool exists(const std::string &path); 82 | 83 | private: 84 | // These are the private methods, documentation will be added later. (TODO) 85 | // In case you are interested, navigate to src/ folder from the GitHub repo to 86 | // see the definitions 87 | 88 | std::string corePath; 89 | std::string separator = "|--"; 90 | void writeToFileIterated(std::ofstream &, int, std::vector, 91 | std::vector); 92 | bool itemInList(std::string, std::vector); 93 | file_info make_file_info(std::string, std::string, bool); 94 | void __print_all(); 95 | bool __check_path_if_exists(const std::string &); 96 | }; 97 | -------------------------------------------------------------------------------- /samples/FileManager.hpp: -------------------------------------------------------------------------------- 1 | // FileManager class 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | class FileManager { 11 | // FileManager Class 12 | // Public Methods: 13 | // 1. clear(): clears the memory allocated for folder path (a.k.a corePath) 14 | // 2. clear(string): replaces the core path with the given path 15 | // 3. info(): Prints the core path to the console. 16 | // 4. list_files(vector extensions, bool ignore_extensions): Use this 17 | // to list files in the path given while creating the constructor. Pass 18 | // extensions and ignore_extensions as true/false to ignore the given 19 | // extensions or not. 20 | // 5. writeToFile(vector ignore_dirs, vector 21 | // ignore_extensions): Use this to create a tree like format (iterative till 22 | // the leaf nodes) for the given directory/path. Pass list of dirs you want to 23 | // ignore in ignore_dirs, and list of extensions you want to ignore in 24 | // ignore_extensions (e.g. ".jpg", ".png" and not "jpg", "png") 25 | public: 26 | // This struct helps us to keep track of important information of the file 27 | // name - absolute path (e.g: /home/BuffetCodes/Documents/FileManager.cpp) 28 | // rname - just the name of the file or directory (e.g: FileManager.cpp) 29 | // is_dir - set to true if the entity is a directory, else false 30 | struct file_info { 31 | std::string name; 32 | std::string rname; 33 | bool is_dir; 34 | }; 35 | 36 | // FileManager constructor 37 | // Pass the path you want to operate this FileManager with. 38 | // You can change the path using: .clear(string newPath) 39 | FileManager(std::string path) { this->corePath = path; } 40 | 41 | // Pass the separator along with your path 42 | FileManager(std::string path, const std::string &separator) { 43 | this->separator = separator; 44 | this->corePath = path; 45 | } 46 | 47 | // This will clear the corePath string variable. 48 | void clear(); 49 | // This will change the corePath string variable to new path. 50 | void clear(std::string); 51 | // This will print the corePath (a.k.a the path) to the console 52 | void info(); 53 | // This function will list files in the path given during creating the object 54 | // or while changing path using clear(newPath) Arguments (not keyword args) 55 | // ========== 56 | // 1. extensions (std::vector, default value = {}): Just list the 57 | // extensions you either want to ignore or you just want to list. 58 | // 2. ignore_extensions (bool, default value = false): If true, the extensions 59 | // passed in the list of extensions will be ignored and nost listed. If false, 60 | // the extensions passed will be listed only. Returns 61 | // ========== 62 | // A vector of file_info struct (see the documentation of file_info to see how 63 | // to access it's elements) 64 | std::vector list_files(std::vector extensions = {}, 65 | bool ignore_extensions = false); 66 | // This function will write a tree like structure to file named "tree.txt" in 67 | // the same folder from where the binary file is called. Arguments (not 68 | // keyword args) 69 | // ========== 70 | // 1. ignore_dirs (std::vector, default value = {}): The list of 71 | // dirs you want to ignore in the tree. These directories will not be expanded 72 | // or iterated, the name will be listed though. 73 | // 2. ignore_extensions (std::vector, default value = {}): The 74 | // list of extensions you want to ignore. The extensions you want to pass 75 | // should have "." (dot), like {".jpg", ".png"} 76 | void writeToFile(std::vector ignore_dirs = {}, 77 | std::vector ignore_extensions = {}); 78 | 79 | void set_separator(const std::string &); 80 | std::string get_separator(); 81 | bool exists(const std::string &path); 82 | 83 | private: 84 | // These are the private methods, documentation will be added later. (TODO) 85 | // In case you are interested, navigate to src/ folder from the GitHub repo to 86 | // see the definitions 87 | 88 | std::string corePath; 89 | std::string separator = "|--"; 90 | void writeToFileIterated(std::ofstream &, int, std::vector, 91 | std::vector); 92 | bool itemInList(std::string, std::vector); 93 | file_info make_file_info(std::string, std::string, bool); 94 | void __print_all(); 95 | bool __check_path_if_exists(const std::string &); 96 | }; 97 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CPP-File-Manager 2 | 3 | C++ File Manager allows you to list files in C++, ignore extensions (or just list specified extensions) and write the whole directory structure into a fancy tree-like structure which can be integrated in Markdown files. This is the first release. Please file issues with `[FEATURE REQUEST]` in the title, and we'll be happy to take a look at it. 4 | 5 | The C++ File Manager provides the following functions to users: 6 | 7 | 1. `clear()` - Clears the memory allocated to corePath. 8 | 2. `clear(std::string new_path)` - Assigns a new path to the corePath variable. 9 | 3. `info()` - Prints the corePath assigned to the FileManager object to the console. 10 | 4. `list_files(std::vector extensions, bool ignore_extensions)` - Lists the files and directories in corePath. The first argument is *extensions* which is a vector of file extensions to be ignored. These extensions are ignored only when the second argument i.e. `ignore_extensions` is set to `true`. 11 | 5. `writeToFile(std::vector ignore_dirs, std::vector ignore_extension)` - Writes the tree structure for the files and directories in corePath into a `.txt` file. This functions iterates till the innermost files of all the directories. The first argument `ignore_dirs` contains a vector of directories to be ignored in the tree structures. Similarly, the second argument `ignore_extensions` contains a vector of files extensions to be ignored in the final tree structure. 12 | 13 | ## Usage 14 | 15 | ### Using Binary 16 | 17 | The **fmanager** binary has the following options : 18 | 19 | ``` 20 | -h --help Print usage. 21 | -p --path filePath Input path (to be iterated). 22 | -l --list_files Call the list files function. 23 | -t --tree Call the tree function. 24 | -d --ignore_dirs dir1,dir2 Ignore dirs while creating tree 25 | -e --ignore_extensions ext1,ext2 Ignore extensions while creating tree 26 | -s --separator Separator you want for your tree output 27 | ``` 28 | 29 | **Listing files in a directory** 30 | 31 | Command: `fmanager -p samples` 32 | 33 | By default, it will list files in the given directory (here `samples`). Output will look like this: 34 | 35 | ```bash 36 | Got path: samples 37 | sample.cpp 38 | README.md 39 | libcpp-file-manager.a 40 | CMakeLists.txt 41 | FileManager.hpp 42 | ``` 43 | 44 | **Building tree of the given directory and ignoring directories and extensions** 45 | 46 | `./fmanager -p ./ -t -d include,.git -e .cpp`\ 47 | _OR_ \ 48 | `./fmanager --path ./ --tree --ignore_dirs include,.git --ignore_extensions .cpp` 49 | 50 | ``` 51 | Got path: ./ 52 | tree.txt 53 | CMakeLists.txt 54 | samples 55 | src 56 | .github 57 | README.md 58 | .git 59 | include 60 | ``` 61 | 62 | The `tree.txt` file stores the following directory structure: 63 | 64 | ``` 65 | |-- tree.txt 66 | |-- CMakeLists.txt 67 | |-- samples 68 | |-- libcpp-file-manager.a 69 | |-- CMakeLists.txt 70 | |-- README.md 71 | |-- FileManager.hpp 72 | |-- src 73 | |-- .github 74 | |-- workflows 75 | |-- build-filemanager.yml 76 | |-- README.md 77 | |-- .git 78 | |-- include 79 | ``` 80 | 81 | In case you want to change the separator from default (`|--`) to something like `-` or `*`, do: 82 | 83 | ```bash 84 | ./fmanager -s '-' -t 85 | ./fmanager --separator '-' --tree 86 | ``` 87 | 88 | The generated `tree.txt` will now contain `-` instead of `|--`: 89 | 90 | ``` 91 | - tree.txt 92 | - CMakeLists.txt 93 | ... 94 | ``` 95 | 96 | ### Using the library in your C++ Code 97 | 98 | To be able to use `FileManager` library, head over to the latest release and download `.a` (library file) and `.hpp` (header file). Copy these files in your current folder (or wherever you desire, just remember the path). To compile, use: 99 | 100 | ```bash 101 | g++ filename.cpp -L . -lcpp-file-manager -o out 102 | ``` 103 | 104 | Here are a few steps on using the library in your code: 105 | 106 | 1. Create an object of `Filemanager` class and initialize it with a path: 107 | 108 | ``` 109 | std::string path = "/home/BuffetCodes/Documents/CPP-File-Manager"; // Change this with your path, either relative or absolute 110 | FileManager file(path); 111 | ``` 112 | 113 | 2. The `file.list_files()` function returns a vector containing names of files/directories with additional information. We can iterate through it as follows: 114 | 115 | ```cpp 116 | // The type returned is a struct, head over to the header file for more details on it 117 | for (auto const& item: file.list_files()) { 118 | // Use item.rname if you want "just" the name of the file or folder 119 | // item.name returns absolute path (with respect to the path given) 120 | // item.is_dir returns true if it's a directory, else false 121 | std::cout << item.name << "\n"; 122 | } 123 | ``` 124 | 125 | The output will be as follows: 126 | 127 | ``` 128 | ./tree.txt 129 | ./CMakeLists.txt 130 | ./samples 131 | ./src 132 | ./.github 133 | ./README.md 134 | ./.git 135 | ./include 136 | ``` 137 | 138 | 3. The `file.writeToFile()` call, creates a text file `tree.txt` representing the directory structure: 139 | 140 | ```cpp 141 | std::vector ignore_dirs = {".git", ".github", ".vscode", "build"}; 142 | std::vector ignore_extensions = {".pyc", ".swp"}; 143 | file.writeToFile(/*ignore_folders=*/ ignore_dirs, /*ignore_extensions=*/ ignore_extensions); 144 | ``` 145 | 146 | ## Build 147 | 148 | The current release (1.0) only supports GNU/Linux Systems. Please head to the relevant opened issues to see the progress on Windows and MacOS. Use the following steps to build from source: 149 | 150 | ```bash 151 | git clone https://github.com/BuffetCodes/CPP-File-Manager.git && cd CPP-File-Manager 152 | mkdir build && cd build 153 | cmake .. && make 154 | ``` 155 | 156 | The library file: `libcpp-file-manager.a` will be generated in `build/` directory. Copy the header file in `include/` and library file from `build/` directory to your folder to use it. Or, just head over to the `samples` folder in this project on how to compile using `CMake` or `g++`. 157 | -------------------------------------------------------------------------------- /src/FileManager.cpp: -------------------------------------------------------------------------------- 1 | // TODOs:: Need better debugging option 2 | 3 | #include "FileManager.hpp" 4 | 5 | void FileManager::clear() { 6 | #ifdef DEBUG 7 | std::cout << "Clearing the core path\n"; 8 | #endif 9 | corePath.clear(); 10 | } 11 | 12 | void FileManager::clear(std::string newPath) { 13 | #ifdef DEBUG 14 | std::cout << "Clearing file manager with new path " + newPath + "\n"; 15 | #endif 16 | corePath = newPath; 17 | } 18 | 19 | void FileManager::__print_all() { 20 | // for (const auto& val: vals_map) { 21 | // std::cout << "Current path is set to: " << corePath << "\n"; 22 | // } 23 | std::cout << "Current path is set to: " << corePath << "\n"; 24 | } 25 | 26 | void FileManager::info() { 27 | // std::cout << "Current path is set to: " << corePath << "\n"; 28 | __print_all(); 29 | } 30 | 31 | bool FileManager::exists(const std::string &path) { return __check_path_if_exists(path); } 32 | 33 | bool FileManager::__check_path_if_exists(const std::string &path) { 34 | return opendir(path.c_str()) != nullptr; 35 | } 36 | 37 | FileManager::file_info FileManager::make_file_info(std::string filename, std::string relative_filename, 38 | bool is_dir) { 39 | // f.name is the absolute name 40 | // f.rname is name of the folder/file 41 | // f.is_dir is set to true if it's a directory, else false 42 | file_info f; 43 | f.name = filename; 44 | f.rname = relative_filename; 45 | f.is_dir = is_dir; 46 | return f; 47 | } 48 | 49 | std::vector 50 | FileManager::list_files(std::vector extensions, 51 | bool ignore_extensions) { 52 | // This returns the list of files present in the folder: corePath 53 | // TODO: Add tests, check if corePath is not empty 54 | // Converting #ifdef DEBUG and #endif to a macro 55 | std::vector list_files; 56 | std::string base_name; 57 | 58 | if (*corePath.rbegin() != '/') 59 | base_name = corePath + "/"; 60 | else 61 | base_name = corePath; 62 | #ifdef DEBUG 63 | std::cout << "Listing files and dirs in: " << corePath << "\n"; 64 | #endif 65 | DIR *dir; 66 | struct dirent *ent; 67 | bool is_dir; 68 | if (exists(base_name)) { 69 | dir = opendir(base_name.c_str()); 70 | while ((ent = readdir(dir)) != NULL) { 71 | bool include = false; 72 | std::string relative_filename = ent->d_name; 73 | if (relative_filename == "." || relative_filename == "..") { 74 | continue; 75 | } 76 | std::string filename = base_name + relative_filename; 77 | if (opendir(filename.c_str()) == NULL) { 78 | #ifdef DEBUG 79 | std::cout << filename << " is not a directory" << std::endl; 80 | #endif 81 | // Check extension 82 | const char *const_relative_filename = relative_filename.c_str(); 83 | auto pos = std::strrchr(const_relative_filename, '.'); 84 | // std::string::size_type pos = relative_filename.find("."); 85 | // if (pos != std::string::npos) { 86 | if (pos) { 87 | // std::string file_extension = relative_filename.substr(pos); 88 | std::string file_extension = 89 | relative_filename.substr(pos - relative_filename.c_str()); 90 | if (extensions.size() == 0) 91 | include = true; 92 | if (itemInList(file_extension, extensions) != ignore_extensions) { 93 | #ifdef DEBUG 94 | std::cout << "File: " << filename 95 | << " with extension: " << file_extension 96 | << " is being ignored.\n"; 97 | #endif 98 | // TODO: We can set include to ignore_extensions here 99 | include = true; 100 | } 101 | } 102 | 103 | is_dir = false; 104 | } else { 105 | #ifdef DEBUG 106 | std::cout << filename << " is a directory" << std::endl; 107 | #endif 108 | is_dir = true; 109 | include = true; 110 | } 111 | if (include) { 112 | list_files.push_back( 113 | make_file_info(filename, relative_filename, is_dir)); 114 | } 115 | } 116 | closedir(dir); 117 | } else { 118 | std::cout << "Could not open directory " << base_name.c_str() << std::endl; 119 | } 120 | return list_files; 121 | } 122 | 123 | std::string spaces(int s) { 124 | std::string out; 125 | for (size_t i = 0; i < s; i++) { 126 | out += " "; 127 | } 128 | return out; 129 | } 130 | 131 | void FileManager::writeToFileIterated( 132 | std::ofstream &file, int depth, std::vector ignore_dirs, 133 | std::vector extensions_to_ignore) { 134 | std::vector out_dir = this->list_files(extensions_to_ignore, true); 135 | ++depth; 136 | for (auto const &iterating_entry : out_dir) { 137 | if (!iterating_entry.is_dir) { 138 | // it's a file 139 | file << spaces(depth) + separator + " " + iterating_entry.rname + "\n"; 140 | } else { 141 | // It's a directory 142 | file << spaces(depth) + separator + " " + iterating_entry.rname + "\n"; 143 | if (itemInList(iterating_entry.rname, ignore_dirs)) { 144 | #ifdef DEBUG 145 | std::cout << "Ignoring dir: " << iterating_entry.name << "\n"; 146 | #endif 147 | continue; 148 | } 149 | this->clear(iterating_entry.name); 150 | this->writeToFileIterated(file, depth, ignore_dirs, extensions_to_ignore); 151 | } 152 | } 153 | } 154 | 155 | bool FileManager::itemInList(std::string item, std::vector list) { 156 | if (list.size() == 0) { 157 | #ifdef DEBUG 158 | std::cout 159 | << "Nothing passed in ignore_dirs, returning false by default then." 160 | << std::endl; 161 | #endif 162 | return false; 163 | } 164 | 165 | for (auto const &_item : list) { 166 | if (_item == item) { 167 | return true; 168 | } 169 | } 170 | return false; 171 | } 172 | 173 | void FileManager::writeToFile(std::vector ignore_dirs, 174 | std::vector ignore_extensions) { 175 | std::vector out = this->list_files(ignore_extensions, true); 176 | if (out.size() == 0) { 177 | #ifdef DEBUG 178 | std::cout << "We got no files in the folder, enable DEBUG flag to see what " 179 | "happened.\n"; 180 | #endif 181 | return; 182 | } 183 | std::ofstream file; 184 | file.open("tree.txt"); 185 | if (!file.is_open()) { 186 | std::cout << "Unable to open the file, please check\n"; 187 | return; 188 | } 189 | int depth = 0; 190 | for (auto const &entry : out) { 191 | if (!entry.is_dir) { 192 | // entry is a file 193 | file << separator + " " + entry.rname + '\n'; 194 | // file << "|-- " + entry.rname + "\n"; 195 | } else { 196 | // entry is a directory 197 | file << separator + " " + entry.rname + '\n'; 198 | // file << "|-- " + entry.rname + "\n"; 199 | #ifdef DEBUG 200 | std::cout << "Checking " << entry.rname << " against build" << std::endl; 201 | #endif 202 | if (itemInList(entry.rname, ignore_dirs)) { 203 | #ifdef DEBUG 204 | std::cout << "Ignoring dir: " << entry.name << "\n"; 205 | #endif 206 | continue; 207 | } else { 208 | this->clear(entry.name); 209 | this->writeToFileIterated(file, depth, ignore_dirs, ignore_extensions); 210 | } 211 | } 212 | } 213 | #ifdef DEBUG 214 | std::cout << "Done!\n"; 215 | #endif 216 | file.close(); 217 | } 218 | 219 | void FileManager::set_separator(const std::string &new_separator) { 220 | this->separator = new_separator; 221 | } 222 | 223 | std::string FileManager::get_separator() { return this->separator; } 224 | --------------------------------------------------------------------------------