|
|
@ -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"); |
|
|
|
|
|
|
|