diff --git a/AdvancedCppV2/Presentation/exercises/files/CMakeLists.txt b/AdvancedCppV2/Presentation/exercises/files/CMakeLists.txt new file mode 100644 index 0000000..2b7e44c --- /dev/null +++ b/AdvancedCppV2/Presentation/exercises/files/CMakeLists.txt @@ -0,0 +1,14 @@ +cmake_minimum_required(VERSION 3.2) + +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +project(Files) + +set(SRC_LIST + main.cpp +) + +add_executable(${PROJECT_NAME} ${SRC_LIST}) +target_compile_options(${PROJECT_NAME} PUBLIC -Wall -Werror -Wpedantic -Wextra) +target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_SOURCE_DIR}) \ No newline at end of file diff --git a/AdvancedCppV2/Presentation/exercises/files/README.md b/AdvancedCppV2/Presentation/exercises/files/README.md new file mode 100644 index 0000000..9f875bc --- /dev/null +++ b/AdvancedCppV2/Presentation/exercises/files/README.md @@ -0,0 +1,33 @@ +## Linux compilation + + > mkdir build + > cd build + > cmake -DCMAKE_BUILD_TYPE=Debug .. + > make + +## Exercise + +Open project `files`. Write a program which modify files under `project` directory: + +- Change permision for all .exe files to `rwxrw-rw-`. +- Change permision for all .cpp and .hpp files to `rw-r--r--`. + +You should get output like this: + +```Bash +File: "fileA.cpp" | Permissions: rw------- +File: "fileA.hpp" | Permissions: rw------- +File: "fileB.cpp" | Permissions: rw------- +File: "fileB.hpp" | Permissions: rw------- +File: "fileC.cpp" | Permissions: rw------- +File: "fileC.hpp" | Permissions: rw------- +File: "project.exe" | Permissions: rw------- + +File: "fileA.cpp" | Permissions: rw-r--r-- +File: "fileA.hpp" | Permissions: rw-r--r-- +File: "fileB.cpp" | Permissions: rw-r--r-- +File: "fileB.hpp" | Permissions: rw-r--r-- +File: "fileC.cpp" | Permissions: rw-r--r-- +File: "fileC.hpp" | Permissions: rw-r--r-- +File: "project.exe" | Permissions: rwxrw-rw- +``` \ No newline at end of file diff --git a/AdvancedCppV2/Presentation/exercises/files/main.cpp b/AdvancedCppV2/Presentation/exercises/files/main.cpp new file mode 100644 index 0000000..52702a3 --- /dev/null +++ b/AdvancedCppV2/Presentation/exercises/files/main.cpp @@ -0,0 +1,52 @@ +#include +#include + +namespace fs = std::filesystem; + +void printPerms(fs::perms p) { + std::cout << ((p & fs::perms::owner_read) != fs::perms::none ? "r" : "-") + << ((p & fs::perms::owner_write) != fs::perms::none ? "w" : "-") + << ((p & fs::perms::owner_exec) != fs::perms::none ? "x" : "-") + << ((p & fs::perms::group_read) != fs::perms::none ? "r" : "-") + << ((p & fs::perms::group_write) != fs::perms::none ? "w" : "-") + << ((p & fs::perms::group_exec) != fs::perms::none ? "x" : "-") + << ((p & fs::perms::others_read) != fs::perms::none ? "r" : "-") + << ((p & fs::perms::others_write) != fs::perms::none ? "w" : "-") + << ((p & fs::perms::others_exec) != fs::perms::none ? "x" : "-") + << '\n'; +} + +void printPermissionsForDir() { + for (const auto& entry : fs::directory_iterator(fs::current_path().string() + "/project")) { + if (fs::is_regular_file(entry.path())) { + std::cout << "File: " + << std::left << std::setw(20) + << entry.path().filename() + << " | Permissions: "; + printPerms(fs::status(entry.path()).permissions()); + } + } + std::cout << std::string(80, '_') << "\n\n"; +} + +void changePermissions() { +} + +int main() { + printPermissionsForDir(); + changePermissions(); + printPermissionsForDir(); + + // Part 2 unncoment later + /* + auto print_last_write_time = [](std::filesystem::file_time_type const& ftime) { + std::time_t time = std::chrono::system_clock::to_time_t( + std::chrono::file_clock::to_sys(ftime)); + std::cout << "File write time is " << std::asctime(std::localtime(&time)); + }; + std::cout << "Last modified file is: " << *last_modify << '\n'; + print_last_write_time(std::filesystem::last_write_time(*last_modify)); + std::cout << "files which were longest unmodified: \n"; + // Print it here + */ +} \ No newline at end of file diff --git a/AdvancedCppV2/Presentation/exercises/files/project/fileA.cpp b/AdvancedCppV2/Presentation/exercises/files/project/fileA.cpp new file mode 100644 index 0000000..02a351d --- /dev/null +++ b/AdvancedCppV2/Presentation/exercises/files/project/fileA.cpp @@ -0,0 +1 @@ +Hello FileA \ No newline at end of file diff --git a/AdvancedCppV2/Presentation/exercises/files/project/fileA.hpp b/AdvancedCppV2/Presentation/exercises/files/project/fileA.hpp new file mode 100644 index 0000000..02a351d --- /dev/null +++ b/AdvancedCppV2/Presentation/exercises/files/project/fileA.hpp @@ -0,0 +1 @@ +Hello FileA \ No newline at end of file diff --git a/AdvancedCppV2/Presentation/exercises/files/project/fileB.cpp b/AdvancedCppV2/Presentation/exercises/files/project/fileB.cpp new file mode 100644 index 0000000..3b294f1 --- /dev/null +++ b/AdvancedCppV2/Presentation/exercises/files/project/fileB.cpp @@ -0,0 +1 @@ +Hello FileB \ No newline at end of file diff --git a/AdvancedCppV2/Presentation/exercises/files/project/fileB.hpp b/AdvancedCppV2/Presentation/exercises/files/project/fileB.hpp new file mode 100644 index 0000000..3b294f1 --- /dev/null +++ b/AdvancedCppV2/Presentation/exercises/files/project/fileB.hpp @@ -0,0 +1 @@ +Hello FileB \ No newline at end of file diff --git a/AdvancedCppV2/Presentation/exercises/files/project/fileC.cpp b/AdvancedCppV2/Presentation/exercises/files/project/fileC.cpp new file mode 100644 index 0000000..2834d09 --- /dev/null +++ b/AdvancedCppV2/Presentation/exercises/files/project/fileC.cpp @@ -0,0 +1 @@ +Hello FileC \ No newline at end of file diff --git a/AdvancedCppV2/Presentation/exercises/files/project/fileC.hpp b/AdvancedCppV2/Presentation/exercises/files/project/fileC.hpp new file mode 100644 index 0000000..2834d09 --- /dev/null +++ b/AdvancedCppV2/Presentation/exercises/files/project/fileC.hpp @@ -0,0 +1 @@ +Hello FileC \ No newline at end of file diff --git a/AdvancedCppV2/Presentation/exercises/files/solutions/main.cpp b/AdvancedCppV2/Presentation/exercises/files/solutions/main.cpp new file mode 100644 index 0000000..8dab3b6 --- /dev/null +++ b/AdvancedCppV2/Presentation/exercises/files/solutions/main.cpp @@ -0,0 +1,58 @@ +#include +#include +#include + +namespace fs = std::filesystem; + +void printPerms(fs::perms p) { + std::cout << ((p & fs::perms::owner_read) != fs::perms::none ? "r" : "-") + << ((p & fs::perms::owner_write) != fs::perms::none ? "w" : "-") + << ((p & fs::perms::owner_exec) != fs::perms::none ? "x" : "-") + << ((p & fs::perms::group_read) != fs::perms::none ? "r" : "-") + << ((p & fs::perms::group_write) != fs::perms::none ? "w" : "-") + << ((p & fs::perms::group_exec) != fs::perms::none ? "x" : "-") + << ((p & fs::perms::others_read) != fs::perms::none ? "r" : "-") + << ((p & fs::perms::others_write) != fs::perms::none ? "w" : "-") + << ((p & fs::perms::others_exec) != fs::perms::none ? "x" : "-") + << '\n'; +} + +void printPermissionsForDir() { + for (const auto& entry : fs::directory_iterator(fs::current_path() / "../project")) { + if (fs::is_regular_file(entry.path())) { + std::cout << "File: " + << std::left << std::setw(20) + << entry.path().filename() + << " | Permissions: "; + printPerms(fs::status(entry.path()).permissions()); + } + } + std::cout << std::string(80, '_') << "\n\n"; +} + +void changePermissions() { + for (auto& entry : fs::directory_iterator(fs::current_path() / "../project")) { + if (!entry.is_regular_file()) { + continue; + } + + if (entry.path().extension() == ".exe") { + fs::permissions(entry.path(), fs::perms::owner_all | + fs::perms::group_read | + fs::perms::group_write | + fs::perms::others_read | + fs::perms::others_write); + } else if (entry.path().extension() == ".cpp" || entry.path().extension() == ".hpp") { + fs::permissions(entry.path(), fs::perms::owner_read | + fs::perms::owner_write | + fs::perms::group_read | + fs::perms::others_read); + } + } +} + +int main() { + printPermissionsForDir(); + changePermissions(); + printPermissionsForDir(); +} \ No newline at end of file diff --git a/AdvancedCppV2/Presentation/exercises/files/solutions/main2.cpp b/AdvancedCppV2/Presentation/exercises/files/solutions/main2.cpp new file mode 100644 index 0000000..2d7e083 --- /dev/null +++ b/AdvancedCppV2/Presentation/exercises/files/solutions/main2.cpp @@ -0,0 +1,62 @@ +#include +#include +#include +#include +#include +#include + +namespace fs = std::filesystem; + +int main() { + // Answer 1 + auto print_last_write_time = [](std::filesystem::file_time_type const& ftime) { + std::time_t time = std::chrono::system_clock::to_time_t( + std::chrono::file_clock::to_sys(ftime)); + std::cout << "File write time is " << std::asctime(std::localtime(&time)); + }; + + // Need to copy paths to vector, because directory_iterator is input type! + // directory_iterator is a LegacyInputIterator that iterates over the directory_entry + std::vector paths; + std::transform(fs::directory_iterator(fs::current_path().string() + "/project"), + {}, + std::back_inserter(paths), + [](const auto& entry) { return entry.path(); }); + + const auto last_modify = std::min_element( + cbegin(paths), + cend(paths), + [&](const auto& lhs, const auto& rhs) { + const auto lhs_time = std::filesystem::last_write_time(lhs); + const auto rhs_time = std::filesystem::last_write_time(rhs); + return lhs_time > rhs_time; + }); + + std::cout << "Last modified file is: " << *last_modify << '\n'; + print_last_write_time(std::filesystem::last_write_time(*last_modify)); + + // Answer 2 + auto time_compare = [](const fs::path& lhs, const fs::path& rhs) { + const auto lhs_time = std::filesystem::last_write_time(lhs); + const auto rhs_time = std::filesystem::last_write_time(rhs); + return lhs_time == rhs_time ? lhs < rhs : lhs_time < rhs_time; + }; + + std::set lastModifiedFiles( + fs::directory_iterator(fs::current_path() / "../project"), + {}, + time_compare); + + std::cout << "files which were longest unmodified: \n"; + std::transform(std::cbegin(lastModifiedFiles), + std::next(std::cbegin(lastModifiedFiles), 3), + std::ostream_iterator(std::cout), + [](const auto& path) { + std::stringstream ss; + std::time_t time = std::chrono::system_clock::to_time_t( + std::chrono::file_clock::to_sys(std::filesystem::last_write_time(path))); + ss << "File: " << path << " | last modify time: " << std::asctime(std::localtime(&time)); + + return ss.str(); + }); +} \ No newline at end of file