diff options
author | Asit Dhal <dhal.asitk@gmail.com> | 2020-06-21 21:17:34 (GMT) |
---|---|---|
committer | Kyle Edwards <kyle.edwards@kitware.com> | 2020-06-25 18:43:30 (GMT) |
commit | d4812a955b679ca4426192db4276cd4e1c1bd373 (patch) | |
tree | ce97b1b98c26db58c2905e7d36214c7159c414d9 /Source | |
parent | aae35feea2048e6ffe4d47a068aa5246c89bd606 (diff) | |
download | CMake-d4812a955b679ca4426192db4276cd4e1c1bd373.zip CMake-d4812a955b679ca4426192db4276cd4e1c1bd373.tar.gz CMake-d4812a955b679ca4426192db4276cd4e1c1bd373.tar.bz2 |
cmake-install: implement default directory permissions
provide an argument for default directory permissions in cmake --install
Fixes: #20700
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmakemain.cxx | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index 75280fb..9fa6705 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -3,11 +3,13 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include <algorithm> #include <cassert> #include <cctype> #include <climits> #include <cstring> #include <iostream> +#include <sstream> #include <string> #include <vector> @@ -517,6 +519,121 @@ int do_build(int ac, char const* const* av) #endif } +bool parse_default_directory_permissions(const std::string& permissions, + std::string& parsedPermissionsVar) +{ + std::vector<std::string> parsedPermissions; + enum Doing + { + DoingNone, + DoingOwner, + DoingGroup, + DoingWorld, + DoingOwnerAssignment, + DoingGroupAssignment, + DoingWorldAssignment, + }; + Doing doing = DoingNone; + + auto uniquePushBack = [&parsedPermissions](const std::string& e) { + if (std::find(parsedPermissions.begin(), parsedPermissions.end(), e) == + parsedPermissions.end()) { + parsedPermissions.push_back(e); + } + }; + + for (auto const& e : permissions) { + switch (doing) { + case DoingNone: + if (e == 'u') { + doing = DoingOwner; + } else if (e == 'g') { + doing = DoingGroup; + } else if (e == 'o') { + doing = DoingWorld; + } else { + return false; + } + break; + case DoingOwner: + if (e == '=') { + doing = DoingOwnerAssignment; + } else { + return false; + } + break; + case DoingGroup: + if (e == '=') { + doing = DoingGroupAssignment; + } else { + return false; + } + break; + case DoingWorld: + if (e == '=') { + doing = DoingWorldAssignment; + } else { + return false; + } + break; + case DoingOwnerAssignment: + if (e == 'r') { + uniquePushBack("OWNER_READ"); + } else if (e == 'w') { + uniquePushBack("OWNER_WRITE"); + } else if (e == 'x') { + uniquePushBack("OWNER_EXECUTE"); + } else if (e == ',') { + doing = DoingNone; + } else { + return false; + } + break; + case DoingGroupAssignment: + if (e == 'r') { + uniquePushBack("GROUP_READ"); + } else if (e == 'w') { + uniquePushBack("GROUP_WRITE"); + } else if (e == 'x') { + uniquePushBack("GROUP_EXECUTE"); + } else if (e == ',') { + doing = DoingNone; + } else { + return false; + } + break; + case DoingWorldAssignment: + if (e == 'r') { + uniquePushBack("WORLD_READ"); + } else if (e == 'w') { + uniquePushBack("WORLD_WRITE"); + } else if (e == 'x') { + uniquePushBack("WORLD_EXECUTE"); + } else if (e == ',') { + doing = DoingNone; + } else { + return false; + } + break; + } + } + if (doing != DoingOwnerAssignment && doing != DoingGroupAssignment && + doing != DoingWorldAssignment) { + return false; + } + + std::ostringstream oss; + for (auto i = 0u; i < parsedPermissions.size(); i++) { + if (i != 0) { + oss << ";"; + } + oss << parsedPermissions[i]; + } + + parsedPermissionsVar = oss.str(); + return true; +} + int do_install(int ac, char const* const* av) { #ifdef CMAKE_BOOTSTRAP @@ -527,6 +644,7 @@ int do_install(int ac, char const* const* av) std::string config; std::string component; + std::string defaultDirectoryPermissions; std::string prefix; std::string dir; bool strip = false; @@ -539,6 +657,7 @@ int do_install(int ac, char const* const* av) DoingConfig, DoingComponent, DoingPrefix, + DoingDefaultDirectoryPermissions, }; Doing doing = DoingDir; @@ -557,6 +676,8 @@ int do_install(int ac, char const* const* av) (strcmp(av[i], "-v") == 0)) { verbose = true; doing = DoingNone; + } else if (strcmp(av[i], "--default-directory-permissions") == 0) { + doing = DoingDefaultDirectoryPermissions; } else { switch (doing) { case DoingDir: @@ -575,6 +696,10 @@ int do_install(int ac, char const* const* av) prefix = av[i]; doing = DoingNone; break; + case DoingDefaultDirectoryPermissions: + defaultDirectoryPermissions = av[i]; + doing = DoingNone; + break; default: std::cerr << "Unknown argument " << av[i] << std::endl; dir.clear(); @@ -591,6 +716,8 @@ int do_install(int ac, char const* const* av) " <dir> = Project binary directory to install.\n" " --config <cfg> = For multi-configuration tools, choose <cfg>.\n" " --component <comp> = Component-based install. Only install <comp>.\n" + " --default-directory-permissions <permission> \n" + " Default install permission. Use default permission <permission>.\n" " --prefix <prefix> = The installation prefix CMAKE_INSTALL_PREFIX.\n" " --strip = Performing install/strip.\n" " -v --verbose = Enable verbose output.\n" @@ -631,6 +758,18 @@ int do_install(int ac, char const* const* av) args.emplace_back("-DCMAKE_INSTALL_CONFIG_NAME=" + config); } + if (!defaultDirectoryPermissions.empty()) { + std::string parsedPermissionsVar; + if (!parse_default_directory_permissions(defaultDirectoryPermissions, + parsedPermissionsVar)) { + std::cerr << "--default-directory-permissions is in incorrect format" + << std::endl; + return 1; + } + args.emplace_back("-DCMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS=" + + parsedPermissionsVar); + } + args.emplace_back("-P"); args.emplace_back(dir + "/cmake_install.cmake"); |