|
|
|
|
@@ -221,11 +221,17 @@ static time_t windows_filetime_to_posix_time(const FILETIME& ft)
|
|
|
|
|
|
|
|
|
|
#ifdef KWSYS_WINDOWS_DIRS
|
|
|
|
|
# include <wctype.h>
|
|
|
|
|
# ifdef _MSC_VER
|
|
|
|
|
typedef KWSYS_NAMESPACE::SystemTools::mode_t mode_t;
|
|
|
|
|
# endif
|
|
|
|
|
|
|
|
|
|
inline int Mkdir(const std::string& dir)
|
|
|
|
|
inline int Mkdir(const std::string& dir, const mode_t* mode)
|
|
|
|
|
{
|
|
|
|
|
return _wmkdir(
|
|
|
|
|
KWSYS_NAMESPACE::Encoding::ToWindowsExtendedPath(dir).c_str());
|
|
|
|
|
int ret =
|
|
|
|
|
_wmkdir(KWSYS_NAMESPACE::Encoding::ToWindowsExtendedPath(dir).c_str());
|
|
|
|
|
if (ret == 0 && mode)
|
|
|
|
|
KWSYS_NAMESPACE::SystemTools::SetPermissions(dir, *mode);
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
inline int Rmdir(const std::string& dir)
|
|
|
|
|
{
|
|
|
|
|
@@ -295,9 +301,9 @@ inline void Realpath(const std::string& path, std::string& resolved_path,
|
|
|
|
|
|
|
|
|
|
# include <fcntl.h>
|
|
|
|
|
# include <unistd.h>
|
|
|
|
|
inline int Mkdir(const std::string& dir)
|
|
|
|
|
inline int Mkdir(const std::string& dir, const mode_t* mode)
|
|
|
|
|
{
|
|
|
|
|
return mkdir(dir.c_str(), 00777);
|
|
|
|
|
return mkdir(dir.c_str(), mode ? *mode : 00777);
|
|
|
|
|
}
|
|
|
|
|
inline int Rmdir(const std::string& dir)
|
|
|
|
|
{
|
|
|
|
|
@@ -912,16 +918,17 @@ bool SystemTools::MakeDirectory(const std::string& path, const mode_t* mode)
|
|
|
|
|
std::string::size_type pos = 0;
|
|
|
|
|
std::string topdir;
|
|
|
|
|
while ((pos = dir.find('/', pos)) != std::string::npos) {
|
|
|
|
|
topdir = dir.substr(0, pos);
|
|
|
|
|
// all underlying functions use C strings, so temporarily
|
|
|
|
|
// end the string here
|
|
|
|
|
dir[pos] = '\0';
|
|
|
|
|
|
|
|
|
|
if (Mkdir(topdir) == 0 && mode != nullptr) {
|
|
|
|
|
SystemTools::SetPermissions(topdir, *mode);
|
|
|
|
|
}
|
|
|
|
|
Mkdir(dir, mode);
|
|
|
|
|
dir[pos] = '/';
|
|
|
|
|
|
|
|
|
|
++pos;
|
|
|
|
|
}
|
|
|
|
|
topdir = dir;
|
|
|
|
|
if (Mkdir(topdir) != 0) {
|
|
|
|
|
if (Mkdir(topdir, mode) != 0) {
|
|
|
|
|
// There is a bug in the Borland Run time library which makes MKDIR
|
|
|
|
|
// return EACCES when it should return EEXISTS
|
|
|
|
|
// if it is some other error besides directory exists
|
|
|
|
|
@@ -933,8 +940,6 @@ bool SystemTools::MakeDirectory(const std::string& path, const mode_t* mode)
|
|
|
|
|
) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
} else if (mode != nullptr) {
|
|
|
|
|
SystemTools::SetPermissions(topdir, *mode);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
@@ -1010,38 +1015,40 @@ void SystemToolsStatic::ReplaceString(std::string& source, const char* replace,
|
|
|
|
|
# define KWSYS_ST_KEY_WOW64_64KEY 0x0100
|
|
|
|
|
# endif
|
|
|
|
|
|
|
|
|
|
static bool SystemToolsParseRegistryKey(const std::string& key,
|
|
|
|
|
HKEY& primaryKey, std::string& second,
|
|
|
|
|
std::string& valuename)
|
|
|
|
|
static bool hasPrefix(const std::string& s, const char* pattern,
|
|
|
|
|
std::string::size_type spos)
|
|
|
|
|
{
|
|
|
|
|
std::string primary = key;
|
|
|
|
|
size_t plen = strlen(pattern);
|
|
|
|
|
if (spos != plen)
|
|
|
|
|
return false;
|
|
|
|
|
return s.compare(0, plen, pattern) == 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
size_t start = primary.find('\\');
|
|
|
|
|
static bool SystemToolsParseRegistryKey(const std::string& key,
|
|
|
|
|
HKEY& primaryKey, std::wstring& second,
|
|
|
|
|
std::string* valuename)
|
|
|
|
|
{
|
|
|
|
|
size_t start = key.find('\\');
|
|
|
|
|
if (start == std::string::npos) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
size_t valuenamepos = primary.find(';');
|
|
|
|
|
if (valuenamepos != std::string::npos) {
|
|
|
|
|
valuename = primary.substr(valuenamepos + 1);
|
|
|
|
|
size_t valuenamepos = key.find(';');
|
|
|
|
|
if (valuenamepos != std::string::npos && valuename) {
|
|
|
|
|
*valuename = key.substr(valuenamepos + 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
second = primary.substr(start + 1, valuenamepos - start - 1);
|
|
|
|
|
primary = primary.substr(0, start);
|
|
|
|
|
second = Encoding::ToWide(key.substr(start + 1, valuenamepos - start - 1));
|
|
|
|
|
|
|
|
|
|
if (primary == "HKEY_CURRENT_USER") {
|
|
|
|
|
if (hasPrefix(key, "HKEY_CURRENT_USER", start)) {
|
|
|
|
|
primaryKey = HKEY_CURRENT_USER;
|
|
|
|
|
}
|
|
|
|
|
if (primary == "HKEY_CURRENT_CONFIG") {
|
|
|
|
|
} else if (hasPrefix(key, "HKEY_CURRENT_CONFIG", start)) {
|
|
|
|
|
primaryKey = HKEY_CURRENT_CONFIG;
|
|
|
|
|
}
|
|
|
|
|
if (primary == "HKEY_CLASSES_ROOT") {
|
|
|
|
|
} else if (hasPrefix(key, "HKEY_CLASSES_ROOT", start)) {
|
|
|
|
|
primaryKey = HKEY_CLASSES_ROOT;
|
|
|
|
|
}
|
|
|
|
|
if (primary == "HKEY_LOCAL_MACHINE") {
|
|
|
|
|
} else if (hasPrefix(key, "HKEY_LOCAL_MACHINE", start)) {
|
|
|
|
|
primaryKey = HKEY_LOCAL_MACHINE;
|
|
|
|
|
}
|
|
|
|
|
if (primary == "HKEY_USERS") {
|
|
|
|
|
} else if (hasPrefix(key, "HKEY_USERS", start)) {
|
|
|
|
|
primaryKey = HKEY_USERS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -1073,14 +1080,13 @@ bool SystemTools::GetRegistrySubKeys(const std::string& key,
|
|
|
|
|
KeyWOW64 view)
|
|
|
|
|
{
|
|
|
|
|
HKEY primaryKey = HKEY_CURRENT_USER;
|
|
|
|
|
std::string second;
|
|
|
|
|
std::string valuename;
|
|
|
|
|
if (!SystemToolsParseRegistryKey(key, primaryKey, second, valuename)) {
|
|
|
|
|
std::wstring second;
|
|
|
|
|
if (!SystemToolsParseRegistryKey(key, primaryKey, second, nullptr)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HKEY hKey;
|
|
|
|
|
if (RegOpenKeyExW(primaryKey, Encoding::ToWide(second).c_str(), 0,
|
|
|
|
|
if (RegOpenKeyExW(primaryKey, second.c_str(), 0,
|
|
|
|
|
SystemToolsMakeRegistryMode(KEY_READ, view),
|
|
|
|
|
&hKey) != ERROR_SUCCESS) {
|
|
|
|
|
return false;
|
|
|
|
|
@@ -1120,14 +1126,14 @@ bool SystemTools::ReadRegistryValue(const std::string& key, std::string& value,
|
|
|
|
|
{
|
|
|
|
|
bool valueset = false;
|
|
|
|
|
HKEY primaryKey = HKEY_CURRENT_USER;
|
|
|
|
|
std::string second;
|
|
|
|
|
std::wstring second;
|
|
|
|
|
std::string valuename;
|
|
|
|
|
if (!SystemToolsParseRegistryKey(key, primaryKey, second, valuename)) {
|
|
|
|
|
if (!SystemToolsParseRegistryKey(key, primaryKey, second, &valuename)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HKEY hKey;
|
|
|
|
|
if (RegOpenKeyExW(primaryKey, Encoding::ToWide(second).c_str(), 0,
|
|
|
|
|
if (RegOpenKeyExW(primaryKey, second.c_str(), 0,
|
|
|
|
|
SystemToolsMakeRegistryMode(KEY_READ, view),
|
|
|
|
|
&hKey) != ERROR_SUCCESS) {
|
|
|
|
|
return false;
|
|
|
|
|
@@ -1174,16 +1180,16 @@ bool SystemTools::WriteRegistryValue(const std::string& key,
|
|
|
|
|
const std::string& value, KeyWOW64 view)
|
|
|
|
|
{
|
|
|
|
|
HKEY primaryKey = HKEY_CURRENT_USER;
|
|
|
|
|
std::string second;
|
|
|
|
|
std::wstring second;
|
|
|
|
|
std::string valuename;
|
|
|
|
|
if (!SystemToolsParseRegistryKey(key, primaryKey, second, valuename)) {
|
|
|
|
|
if (!SystemToolsParseRegistryKey(key, primaryKey, second, &valuename)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HKEY hKey;
|
|
|
|
|
DWORD dwDummy;
|
|
|
|
|
wchar_t lpClass[] = L"";
|
|
|
|
|
if (RegCreateKeyExW(primaryKey, Encoding::ToWide(second).c_str(), 0, lpClass,
|
|
|
|
|
if (RegCreateKeyExW(primaryKey, second.c_str(), 0, lpClass,
|
|
|
|
|
REG_OPTION_NON_VOLATILE,
|
|
|
|
|
SystemToolsMakeRegistryMode(KEY_WRITE, view), nullptr,
|
|
|
|
|
&hKey, &dwDummy) != ERROR_SUCCESS) {
|
|
|
|
|
@@ -1218,14 +1224,14 @@ bool SystemTools::WriteRegistryValue(const std::string&, const std::string&,
|
|
|
|
|
bool SystemTools::DeleteRegistryValue(const std::string& key, KeyWOW64 view)
|
|
|
|
|
{
|
|
|
|
|
HKEY primaryKey = HKEY_CURRENT_USER;
|
|
|
|
|
std::string second;
|
|
|
|
|
std::wstring second;
|
|
|
|
|
std::string valuename;
|
|
|
|
|
if (!SystemToolsParseRegistryKey(key, primaryKey, second, valuename)) {
|
|
|
|
|
if (!SystemToolsParseRegistryKey(key, primaryKey, second, &valuename)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HKEY hKey;
|
|
|
|
|
if (RegOpenKeyExW(primaryKey, Encoding::ToWide(second).c_str(), 0,
|
|
|
|
|
if (RegOpenKeyExW(primaryKey, second.c_str(), 0,
|
|
|
|
|
SystemToolsMakeRegistryMode(KEY_WRITE, view),
|
|
|
|
|
&hKey) != ERROR_SUCCESS) {
|
|
|
|
|
return false;
|
|
|
|
|
@@ -1866,7 +1872,7 @@ std::string SystemTools::CropString(const std::string& s, size_t max_len)
|
|
|
|
|
|
|
|
|
|
size_t middle = max_len / 2;
|
|
|
|
|
|
|
|
|
|
n += s.substr(0, middle);
|
|
|
|
|
n.assign(s, 0, middle);
|
|
|
|
|
n += s.substr(s.size() - (max_len - middle));
|
|
|
|
|
|
|
|
|
|
if (max_len > 2) {
|
|
|
|
|
@@ -2064,8 +2070,10 @@ void SystemTools::ConvertToUnixSlashes(std::string& path)
|
|
|
|
|
#ifdef HAVE_GETPWNAM
|
|
|
|
|
else if (pathCString[0] == '~') {
|
|
|
|
|
std::string::size_type idx = path.find_first_of("/\0");
|
|
|
|
|
std::string user = path.substr(1, idx - 1);
|
|
|
|
|
passwd* pw = getpwnam(user.c_str());
|
|
|
|
|
char oldch = path[idx];
|
|
|
|
|
path[idx] = '\0';
|
|
|
|
|
passwd* pw = getpwnam(path.c_str() + 1);
|
|
|
|
|
path[idx] = oldch;
|
|
|
|
|
if (pw) {
|
|
|
|
|
path.replace(0, idx, pw->pw_dir);
|
|
|
|
|
}
|
|
|
|
|
@@ -3131,17 +3139,17 @@ bool SystemTools::SplitProgramPath(const std::string& in_name,
|
|
|
|
|
std::string& dir, std::string& file, bool)
|
|
|
|
|
{
|
|
|
|
|
dir = in_name;
|
|
|
|
|
file = "";
|
|
|
|
|
file.clear();
|
|
|
|
|
SystemTools::ConvertToUnixSlashes(dir);
|
|
|
|
|
|
|
|
|
|
if (!SystemTools::FileIsDirectory(dir)) {
|
|
|
|
|
std::string::size_type slashPos = dir.rfind("/");
|
|
|
|
|
if (slashPos != std::string::npos) {
|
|
|
|
|
file = dir.substr(slashPos + 1);
|
|
|
|
|
dir = dir.substr(0, slashPos);
|
|
|
|
|
dir.resize(slashPos);
|
|
|
|
|
} else {
|
|
|
|
|
file = dir;
|
|
|
|
|
dir = "";
|
|
|
|
|
dir.clear();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!(dir.empty()) && !SystemTools::FileIsDirectory(dir)) {
|
|
|
|
|
@@ -3268,7 +3276,7 @@ void SystemTools::CheckTranslationPath(std::string& path)
|
|
|
|
|
// Now convert any path found in the table back to the one desired:
|
|
|
|
|
for (auto const& pair : SystemTools::Statics->TranslationMap) {
|
|
|
|
|
// We need to check of the path is a substring of the other path
|
|
|
|
|
if (path.find(pair.first) == 0) {
|
|
|
|
|
if (path.compare(0, pair.first.size(), pair.first) == 0) {
|
|
|
|
|
path = path.replace(0, pair.first.size(), pair.second);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -3540,7 +3548,7 @@ void SystemTools::SplitPath(const std::string& p,
|
|
|
|
|
// Expand home directory references if requested.
|
|
|
|
|
if (expand_home_dir && !root.empty() && root[0] == '~') {
|
|
|
|
|
std::string homedir;
|
|
|
|
|
root = root.substr(0, root.size() - 1);
|
|
|
|
|
root.resize(root.size() - 1);
|
|
|
|
|
if (root.size() == 1) {
|
|
|
|
|
#if defined(_WIN32) && !defined(__CYGWIN__)
|
|
|
|
|
if (!SystemTools::GetEnv("USERPROFILE", homedir))
|
|
|
|
|
@@ -3685,18 +3693,19 @@ std::string SystemTools::GetFilenamePath(const std::string& filename)
|
|
|
|
|
SystemTools::ConvertToUnixSlashes(fn);
|
|
|
|
|
|
|
|
|
|
std::string::size_type slash_pos = fn.rfind("/");
|
|
|
|
|
if (slash_pos != std::string::npos) {
|
|
|
|
|
std::string ret = fn.substr(0, slash_pos);
|
|
|
|
|
if (ret.size() == 2 && ret[1] == ':') {
|
|
|
|
|
return ret + '/';
|
|
|
|
|
}
|
|
|
|
|
if (ret.empty()) {
|
|
|
|
|
return "/";
|
|
|
|
|
}
|
|
|
|
|
return ret;
|
|
|
|
|
} else {
|
|
|
|
|
if (slash_pos == 0) {
|
|
|
|
|
return "/";
|
|
|
|
|
}
|
|
|
|
|
if (slash_pos == 2 && fn[1] == ':') {
|
|
|
|
|
// keep the / after a drive letter
|
|
|
|
|
fn.resize(3);
|
|
|
|
|
return fn;
|
|
|
|
|
}
|
|
|
|
|
if (slash_pos == std::string::npos) {
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
fn.resize(slash_pos);
|
|
|
|
|
return fn;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@@ -3726,7 +3735,8 @@ std::string SystemTools::GetFilenameExtension(const std::string& filename)
|
|
|
|
|
std::string name = SystemTools::GetFilenameName(filename);
|
|
|
|
|
std::string::size_type dot_pos = name.find('.');
|
|
|
|
|
if (dot_pos != std::string::npos) {
|
|
|
|
|
return name.substr(dot_pos);
|
|
|
|
|
name.erase(0, dot_pos);
|
|
|
|
|
return name;
|
|
|
|
|
} else {
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
@@ -3741,7 +3751,8 @@ std::string SystemTools::GetFilenameLastExtension(const std::string& filename)
|
|
|
|
|
std::string name = SystemTools::GetFilenameName(filename);
|
|
|
|
|
std::string::size_type dot_pos = name.rfind('.');
|
|
|
|
|
if (dot_pos != std::string::npos) {
|
|
|
|
|
return name.substr(dot_pos);
|
|
|
|
|
name.erase(0, dot_pos);
|
|
|
|
|
return name;
|
|
|
|
|
} else {
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
@@ -3757,10 +3768,9 @@ std::string SystemTools::GetFilenameWithoutExtension(
|
|
|
|
|
std::string name = SystemTools::GetFilenameName(filename);
|
|
|
|
|
std::string::size_type dot_pos = name.find('.');
|
|
|
|
|
if (dot_pos != std::string::npos) {
|
|
|
|
|
return name.substr(0, dot_pos);
|
|
|
|
|
} else {
|
|
|
|
|
return name;
|
|
|
|
|
name.resize(dot_pos);
|
|
|
|
|
}
|
|
|
|
|
return name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@@ -3774,10 +3784,9 @@ std::string SystemTools::GetFilenameWithoutLastExtension(
|
|
|
|
|
std::string name = SystemTools::GetFilenameName(filename);
|
|
|
|
|
std::string::size_type dot_pos = name.rfind('.');
|
|
|
|
|
if (dot_pos != std::string::npos) {
|
|
|
|
|
return name.substr(0, dot_pos);
|
|
|
|
|
} else {
|
|
|
|
|
return name;
|
|
|
|
|
name.resize(dot_pos);
|
|
|
|
|
}
|
|
|
|
|
return name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool SystemTools::FileHasSignature(const char* filename, const char* signature,
|
|
|
|
|
@@ -3999,7 +4008,8 @@ bool SystemTools::GetShortPath(const std::string& path, std::string& shortPath)
|
|
|
|
|
|
|
|
|
|
// if the path passed in has quotes around it, first remove the quotes
|
|
|
|
|
if (!path.empty() && path[0] == '"' && path.back() == '"') {
|
|
|
|
|
tempPath = path.substr(1, path.length() - 2);
|
|
|
|
|
tempPath.resize(path.length() - 1);
|
|
|
|
|
tempPath.erase(0, 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::wstring wtempPath = Encoding::ToWide(tempPath);
|
|
|
|
|
@@ -4218,8 +4228,8 @@ bool SystemTools::IsSubDirectory(const std::string& cSubdir,
|
|
|
|
|
if (subdir[expectedSlashPosition] != '/') {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
std::string s = subdir.substr(0, dir.size());
|
|
|
|
|
return SystemTools::ComparePath(s, dir);
|
|
|
|
|
subdir.resize(dir.size());
|
|
|
|
|
return SystemTools::ComparePath(subdir, dir);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SystemTools::Delay(unsigned int msec)
|
|
|
|
|
@@ -4580,8 +4590,8 @@ std::string SystemTools::DecodeURL(const std::string& url)
|
|
|
|
|
std::string ret;
|
|
|
|
|
for (size_t i = 0; i < url.length(); i++) {
|
|
|
|
|
if (urlByteRe.find(url.substr(i, 3))) {
|
|
|
|
|
ret +=
|
|
|
|
|
static_cast<char>(strtoul(url.substr(i + 1, 2).c_str(), nullptr, 16));
|
|
|
|
|
char bytes[] = { url[i + 1], url[i + 2], '\0' };
|
|
|
|
|
ret += static_cast<char>(strtoul(bytes, nullptr, 16));
|
|
|
|
|
i += 2;
|
|
|
|
|
} else {
|
|
|
|
|
ret += url[i];
|
|
|
|
|
|