summaryrefslogtreecommitdiffstats
path: root/Source/cmFileCommand.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmFileCommand.cxx')
-rw-r--r--Source/cmFileCommand.cxx453
1 files changed, 376 insertions, 77 deletions
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index 1325cec..579e715 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -20,7 +20,8 @@
#include "cmTimestamp.h"
#if defined(CMAKE_BUILD_WITH_CMAKE)
-#include "cm_curl.h"
+#include "cmCurl.h"
+#include "cmFileLockResult.h"
#endif
#undef GetCurrentDirectory
@@ -33,6 +34,7 @@
#include <cmsys/Glob.hxx>
#include <cmsys/RegularExpression.hxx>
#include <cmsys/FStream.hxx>
+#include <cmsys/Encoding.hxx>
// Table of permissions flags.
#if defined(_WIN32) && !defined(__CYGWIN__)
@@ -61,6 +63,35 @@ static mode_t mode_setuid = S_ISUID;
static mode_t mode_setgid = S_ISGID;
#endif
+#if defined(WIN32) && defined(CMAKE_ENCODING_UTF8)
+// libcurl doesn't support file:// urls for unicode filenames on Windows.
+// Convert string from UTF-8 to ACP if this is a file:// URL.
+static std::string fix_file_url_windows(const std::string& url)
+{
+ std::string ret = url;
+ if(strncmp(url.c_str(), "file://", 7) == 0)
+ {
+ cmsys_stl::wstring wurl = cmsys::Encoding::ToWide(url);
+ if(!wurl.empty())
+ {
+ int mblen = WideCharToMultiByte(CP_ACP, 0, wurl.c_str(), -1,
+ NULL, 0, NULL, NULL);
+ if(mblen > 0)
+ {
+ std::vector<char> chars(mblen);
+ mblen = WideCharToMultiByte(CP_ACP, 0, wurl.c_str(), -1,
+ &chars[0], mblen, NULL, NULL);
+ if(mblen > 0)
+ {
+ ret = &chars[0];
+ }
+ }
+ }
+ }
+ return ret;
+}
+#endif
+
// cmLibraryCommand
bool cmFileCommand
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
@@ -172,6 +203,10 @@ bool cmFileCommand
{
return this->HandleGenerateCommand(args);
}
+ else if ( subCommand == "LOCK" )
+ {
+ return this->HandleLockCommand(args);
+ }
std::string e = "does not recognize sub-command "+subCommand;
this->SetError(e);
@@ -220,8 +255,6 @@ bool cmFileCommand::HandleWriteCommand(std::vector<std::string> const& args,
cmSystemTools::SetPermissions(fileName.c_str(),
#if defined( _MSC_VER ) || defined( __MINGW32__ )
mode | S_IWRITE
-#elif defined( __BORLANDC__ )
- mode | S_IWUSR
#else
mode | S_IWUSR | S_IWGRP
#endif
@@ -303,14 +336,14 @@ bool cmFileCommand::HandleReadCommand(std::vector<std::string> const& args)
// is there a limit?
long sizeLimit = -1;
- if (limitArg.GetString().size() > 0)
+ if (!limitArg.GetString().empty())
{
sizeLimit = atoi(limitArg.GetCString());
}
// is there an offset?
long offset = 0;
- if (offsetArg.GetString().size() > 0)
+ if (!offsetArg.GetString().empty())
{
offset = atoi(offsetArg.GetCString());
}
@@ -371,7 +404,7 @@ bool cmFileCommand::HandleHashCommand(std::vector<std::string> const& args)
#if defined(CMAKE_BUILD_WITH_CMAKE)
if(args.size() != 3)
{
- cmOStringStream e;
+ std::ostringstream e;
e << args[0] << " requires a file name and output variable";
this->SetError(e.str());
return false;
@@ -386,14 +419,14 @@ bool cmFileCommand::HandleHashCommand(std::vector<std::string> const& args)
this->Makefile->AddDefinition(args[2], out.c_str());
return true;
}
- cmOStringStream e;
+ std::ostringstream e;
e << args[0] << " failed to read file \"" << args[1] << "\": "
<< cmSystemTools::GetLastSystemError();
this->SetError(e.str());
}
return false;
#else
- cmOStringStream e;
+ std::ostringstream e;
e << args[0] << " not available during bootstrap";
this->SetError(e.str().c_str());
return false;
@@ -439,7 +472,13 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
bool have_regex = false;
bool newline_consume = false;
bool hex_conversion_enabled = true;
- bool utf8_encoding = false;
+ enum { encoding_none = cmsys::FStream::BOM_None,
+ encoding_utf8 = cmsys::FStream::BOM_UTF8,
+ encoding_utf16le = cmsys::FStream::BOM_UTF16LE,
+ encoding_utf16be = cmsys::FStream::BOM_UTF16BE,
+ encoding_utf32le = cmsys::FStream::BOM_UTF32LE,
+ encoding_utf32be = cmsys::FStream::BOM_UTF32BE};
+ int encoding = encoding_none;
int arg_mode = arg_none;
for(unsigned int i=3; i < args.size(); ++i)
{
@@ -486,7 +525,7 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
if(sscanf(args[i].c_str(), "%d", &limit_input) != 1 ||
limit_input < 0)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "STRINGS option LIMIT_INPUT value \""
<< args[i] << "\" is not an unsigned integer.";
this->SetError(e.str());
@@ -499,7 +538,7 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
if(sscanf(args[i].c_str(), "%d", &limit_output) != 1 ||
limit_output < 0)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "STRINGS option LIMIT_OUTPUT value \""
<< args[i] << "\" is not an unsigned integer.";
this->SetError(e.str());
@@ -512,7 +551,7 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
int count;
if(sscanf(args[i].c_str(), "%d", &count) != 1 || count < 0)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "STRINGS option LIMIT_COUNT value \""
<< args[i] << "\" is not an unsigned integer.";
this->SetError(e.str());
@@ -526,7 +565,7 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
int len;
if(sscanf(args[i].c_str(), "%d", &len) != 1 || len < 0)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "STRINGS option LENGTH_MINIMUM value \""
<< args[i] << "\" is not an unsigned integer.";
this->SetError(e.str());
@@ -540,7 +579,7 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
int len;
if(sscanf(args[i].c_str(), "%d", &len) != 1 || len < 0)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "STRINGS option LENGTH_MAXIMUM value \""
<< args[i] << "\" is not an unsigned integer.";
this->SetError(e.str());
@@ -553,7 +592,7 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
{
if(!regex.compile(args[i].c_str()))
{
- cmOStringStream e;
+ std::ostringstream e;
e << "STRINGS option REGEX value \""
<< args[i] << "\" could not be compiled.";
this->SetError(e.str());
@@ -566,11 +605,27 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
{
if(args[i] == "UTF-8")
{
- utf8_encoding = true;
+ encoding = encoding_utf8;
+ }
+ else if(args[i] == "UTF-16LE")
+ {
+ encoding = encoding_utf16le;
+ }
+ else if(args[i] == "UTF-16BE")
+ {
+ encoding = encoding_utf16be;
+ }
+ else if(args[i] == "UTF-32LE")
+ {
+ encoding = encoding_utf32le;
+ }
+ else if(args[i] == "UTF-32BE")
+ {
+ encoding = encoding_utf32be;
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "STRINGS option ENCODING \""
<< args[i] << "\" not recognized.";
this->SetError(e.str());
@@ -580,7 +635,7 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "STRINGS given unknown argument \""
<< args[i] << "\"";
this->SetError(e.str());
@@ -608,12 +663,29 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
#endif
if(!fin)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "STRINGS file \"" << fileName << "\" cannot be read.";
this->SetError(e.str());
return false;
}
+ //If BOM is found and encoding was not specified, use the BOM
+ int bom_found = cmsys::FStream::ReadBOM(fin);
+ if(encoding == encoding_none && bom_found != cmsys::FStream::BOM_None)
+ {
+ encoding = bom_found;
+ }
+
+ unsigned int bytes_rem = 0;
+ if(encoding == encoding_utf16le || encoding == encoding_utf16be)
+ {
+ bytes_rem = 1;
+ }
+ if(encoding == encoding_utf32le || encoding == encoding_utf32be)
+ {
+ bytes_rem = 3;
+ }
+
// Parse strings out of the file.
int output_size = 0;
std::vector<std::string> strings;
@@ -625,6 +697,25 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
std::string current_str;
int c = fin.get();
+ for(unsigned int i=0; i<bytes_rem; ++i)
+ {
+ int c1 = fin.get();
+ if(!fin)
+ {
+ fin.putback(static_cast<char>(c1));
+ break;
+ }
+ c = (c << 8) | c1;
+ }
+ if(encoding == encoding_utf16le)
+ {
+ c = ((c & 0xFF) << 8) | ((c & 0xFF00) >> 8);
+ }
+ else if(encoding == encoding_utf32le)
+ {
+ c = (((c & 0xFF) << 24) | ((c & 0xFF00) << 8) |
+ ((c & 0xFF0000) >> 8) | ((c & 0xFF000000) >> 24));
+ }
if(c == '\r')
{
@@ -640,7 +731,7 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
// c is guaranteed to fit in char by the above if...
current_str += static_cast<char>(c);
}
- else if(utf8_encoding)
+ else if(encoding == encoding_utf8)
{
// Check for UTF-8 encoded string (up to 4 octets)
static const unsigned char utf8_check_table[3][2] =
@@ -712,7 +803,7 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
// A non-string character has been found. Check if the current
// string matches the requirements. We require that the length
// be at least one no matter what the user specified.
- if(s.length() >= minlen && s.length() >= 1 &&
+ if(s.length() >= minlen && !s.empty() &&
(!have_regex || regex.find(s.c_str())))
{
output_size += static_cast<int>(s.size()) + 1;
@@ -866,7 +957,7 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args,
{
std::string expr = this->Makefile->GetCurrentDirectory();
// Handle script mode
- if ( expr.size() > 0 )
+ if (!expr.empty())
{
expr += "/" + *i;
g.FindFiles(expr);
@@ -1004,7 +1095,7 @@ cmFileCommand::HandleDifferentCommand(std::vector<std::string> const& args)
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "DIFFERENT given unknown argument " << args[i];
this->SetError(e.str());
return false;
@@ -1119,7 +1210,7 @@ protected:
{
if(permissions && !cmSystemTools::SetPermissions(toFile, permissions))
{
- cmOStringStream e;
+ std::ostringstream e;
e << this->Name << " cannot set permissions on \"" << toFile << "\"";
this->FileCommand->SetError(e.str());
return false;
@@ -1143,7 +1234,7 @@ protected:
else if(arg == "SETGID") { permissions |= mode_setgid; }
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << this->Name << " given invalid permission \"" << arg << "\".";
this->FileCommand->SetError(e.str());
return false;
@@ -1170,7 +1261,7 @@ protected:
virtual bool ReportMissing(const char* fromFile)
{
// The input file does not exist and installation is not optional.
- cmOStringStream e;
+ std::ostringstream e;
e << this->Name << " cannot find \"" << fromFile << "\".";
this->FileCommand->SetError(e.str());
return false;
@@ -1203,14 +1294,14 @@ protected:
void NotBeforeMatch(std::string const& arg)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "option " << arg << " may not appear before PATTERN or REGEX.";
this->FileCommand->SetError(e.str());
this->Doing = DoingError;
}
void NotAfterMatch(std::string const& arg)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "option " << arg << " may not appear after PATTERN or REGEX.";
this->FileCommand->SetError(e.str());
this->Doing = DoingError;
@@ -1248,7 +1339,7 @@ bool cmFileCopier::Parse(std::vector<std::string> const& args)
if(!this->CheckKeyword(args[i]) &&
!this->CheckValue(args[i]))
{
- cmOStringStream e;
+ std::ostringstream e;
e << "called with unknown argument \"" << args[i] << "\".";
this->FileCommand->SetError(e.str());
return false;
@@ -1264,7 +1355,7 @@ bool cmFileCopier::Parse(std::vector<std::string> const& args)
// Require a destination.
if(this->Destination.empty())
{
- cmOStringStream e;
+ std::ostringstream e;
e << this->Name << " given no DESTINATION";
this->FileCommand->SetError(e.str());
return false;
@@ -1444,7 +1535,7 @@ bool cmFileCopier::CheckValue(std::string const& arg)
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "could not compile PATTERN \"" << arg << "\".";
this->FileCommand->SetError(e.str());
this->Doing = DoingError;
@@ -1460,7 +1551,7 @@ bool cmFileCopier::CheckValue(std::string const& arg)
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "could not compile REGEX \"" << arg << "\".";
this->FileCommand->SetError(e.str());
this->Doing = DoingError;
@@ -1504,7 +1595,7 @@ bool cmFileCopier::Run(std::vector<std::string> const& args)
{
// Split the input file into its directory and name components.
std::vector<std::string> fromPathComponents;
- cmSystemTools::SplitPath(files[i].c_str(), fromPathComponents);
+ cmSystemTools::SplitPath(files[i], fromPathComponents);
std::string fromName = *(fromPathComponents.end()-1);
std::string fromDir = cmSystemTools::JoinPath(fromPathComponents.begin(),
fromPathComponents.end()-1);
@@ -1540,7 +1631,7 @@ bool cmFileCopier::Install(const char* fromFile, const char* toFile)
{
if(!*fromFile)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "INSTALL encountered an empty string input file name.";
this->FileCommand->SetError(e.str());
return false;
@@ -1581,7 +1672,7 @@ bool cmFileCopier::InstallSymlink(const char* fromFile, const char* toFile)
std::string symlinkTarget;
if(!cmSystemTools::ReadSymlink(fromFile, symlinkTarget))
{
- cmOStringStream e;
+ std::ostringstream e;
e << this->Name << " cannot read symlink \"" << fromFile
<< "\" to duplicate at \"" << toFile << "\".";
this->FileCommand->SetError(e.str());
@@ -1612,9 +1703,9 @@ bool cmFileCopier::InstallSymlink(const char* fromFile, const char* toFile)
cmSystemTools::RemoveFile(toFile);
// Create the symlink.
- if(!cmSystemTools::CreateSymlink(symlinkTarget.c_str(), toFile))
+ if(!cmSystemTools::CreateSymlink(symlinkTarget, toFile))
{
- cmOStringStream e;
+ std::ostringstream e;
e << this->Name << " cannot duplicate symlink \"" << fromFile
<< "\" at \"" << toFile << "\".";
this->FileCommand->SetError(e.str());
@@ -1646,7 +1737,7 @@ bool cmFileCopier::InstallFile(const char* fromFile, const char* toFile,
// Copy the file.
if(copy && !cmSystemTools::CopyAFile(fromFile, toFile, true))
{
- cmOStringStream e;
+ std::ostringstream e;
e << this->Name << " cannot copy file \"" << fromFile
<< "\" to \"" << toFile << "\".";
this->FileCommand->SetError(e.str());
@@ -1665,7 +1756,7 @@ bool cmFileCopier::InstallFile(const char* fromFile, const char* toFile,
}
if (!cmSystemTools::CopyFileTime(fromFile, toFile))
{
- cmOStringStream e;
+ std::ostringstream e;
e << this->Name << " cannot set modification time on \""
<< toFile << "\"";
this->FileCommand->SetError(e.str());
@@ -1697,7 +1788,7 @@ bool cmFileCopier::InstallDirectory(const char* source,
// Make sure the destination directory exists.
if(!cmSystemTools::MakeDirectory(destination))
{
- cmOStringStream e;
+ std::ostringstream e;
e << this->Name << " cannot make directory \"" << destination << "\": "
<< cmSystemTools::GetLastSystemError();
this->FileCommand->SetError(e.str());
@@ -2042,7 +2133,7 @@ bool cmFileInstaller::CheckKeyword(std::string const& arg)
else if(arg == "COMPONENTS" || arg == "CONFIGURATIONS" ||
arg == "PROPERTIES")
{
- cmOStringStream e;
+ std::ostringstream e;
e << "INSTALL called with old-style " << arg << " argument. "
<< "This script was generated with an older version of CMake. "
<< "Re-run this cmake version on your build tree.";
@@ -2110,7 +2201,7 @@ bool cmFileInstaller
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "Option TYPE given unknown value \"" << stype << "\".";
this->FileCommand->SetError(e.str());
return false;
@@ -2203,7 +2294,7 @@ bool cmFileInstaller::HandleInstallDestination()
return false;
}
}
- if ( !cmSystemTools::FileIsDirectory(destination.c_str()) )
+ if ( !cmSystemTools::FileIsDirectory(destination) )
{
std::string errstring = "INSTALL destination: " + destination +
" is not a directory.";
@@ -2255,7 +2346,7 @@ cmFileCommand::HandleRPathChangeCommand(std::vector<std::string> const& args)
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "RPATH_CHANGE given unknown argument " << args[i];
this->SetError(e.str());
return false;
@@ -2278,7 +2369,7 @@ cmFileCommand::HandleRPathChangeCommand(std::vector<std::string> const& args)
}
if(!cmSystemTools::FileExists(file, true))
{
- cmOStringStream e;
+ std::ostringstream e;
e << "RPATH_CHANGE given FILE \"" << file << "\" that does not exist.";
this->SetError(e.str());
return false;
@@ -2290,7 +2381,7 @@ cmFileCommand::HandleRPathChangeCommand(std::vector<std::string> const& args)
bool changed;
if(!cmSystemTools::ChangeRPath(file, oldRPath, newRPath, &emsg, &changed))
{
- cmOStringStream e;
+ std::ostringstream e;
e << "RPATH_CHANGE could not write new RPATH:\n"
<< " " << newRPath << "\n"
<< "to the file:\n"
@@ -2340,7 +2431,7 @@ cmFileCommand::HandleRPathRemoveCommand(std::vector<std::string> const& args)
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "RPATH_REMOVE given unknown argument " << args[i];
this->SetError(e.str());
return false;
@@ -2353,7 +2444,7 @@ cmFileCommand::HandleRPathRemoveCommand(std::vector<std::string> const& args)
}
if(!cmSystemTools::FileExists(file, true))
{
- cmOStringStream e;
+ std::ostringstream e;
e << "RPATH_REMOVE given FILE \"" << file << "\" that does not exist.";
this->SetError(e.str());
return false;
@@ -2365,7 +2456,7 @@ cmFileCommand::HandleRPathRemoveCommand(std::vector<std::string> const& args)
bool removed;
if(!cmSystemTools::RemoveRPath(file, &emsg, &removed))
{
- cmOStringStream e;
+ std::ostringstream e;
e << "RPATH_REMOVE could not remove RPATH from file:\n"
<< " " << file << "\n"
<< emsg;
@@ -2421,7 +2512,7 @@ cmFileCommand::HandleRPathCheckCommand(std::vector<std::string> const& args)
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "RPATH_CHECK given unknown argument " << args[i];
this->SetError(e.str());
return false;
@@ -2522,7 +2613,7 @@ bool cmFileCommand::HandleRename(std::vector<std::string> const& args)
if(!cmSystemTools::RenameFile(oldname.c_str(), newname.c_str()))
{
std::string err = cmSystemTools::GetLastSystemError();
- cmOStringStream e;
+ std::ostringstream e;
e << "RENAME failed to rename\n"
<< " " << oldname << "\n"
<< "to\n"
@@ -2553,14 +2644,14 @@ bool cmFileCommand::HandleRemove(std::vector<std::string> const& args,
fileName += "/" + *i;
}
- if(cmSystemTools::FileIsDirectory(fileName.c_str()) &&
- !cmSystemTools::FileIsSymlink(fileName.c_str()) && recurse)
+ if(cmSystemTools::FileIsDirectory(fileName) &&
+ !cmSystemTools::FileIsSymlink(fileName) && recurse)
{
- cmSystemTools::RemoveADirectory(fileName.c_str());
+ cmSystemTools::RemoveADirectory(fileName);
}
else
{
- cmSystemTools::RemoveFile(fileName.c_str());
+ cmSystemTools::RemoveFile(fileName);
}
}
return true;
@@ -2584,7 +2675,7 @@ bool cmFileCommand::HandleCMakePathCommand(std::vector<std::string>
#else
char pathSep = ':';
#endif
- std::vector<cmsys::String> path = cmSystemTools::SplitString(i->c_str(),
+ std::vector<cmsys::String> path = cmSystemTools::SplitString(*i,
pathSep);
i++;
const char* var = i->c_str();
@@ -2689,7 +2780,7 @@ namespace {
if (updated)
{
- cmOStringStream oss;
+ std::ostringstream oss;
oss << "[" << this->Text << " " << this->CurrentPercentage
<< "% complete]";
status = oss.str();
@@ -2959,9 +3050,9 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
msg = "returning early; file already exists with expected ";
msg += hashMatchMSG;
msg += "\"";
- if(statusVar.size())
+ if(!statusVar.empty())
{
- cmOStringStream result;
+ std::ostringstream result;
result << (int)0 << ";\"" << msg;
this->Makefile->AddDefinition(statusVar,
result.str().c_str());
@@ -2990,6 +3081,10 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
return false;
}
+#if defined(WIN32) && defined(CMAKE_ENCODING_UTF8)
+ url = fix_file_url_windows(url);
+#endif
+
::CURL *curl;
::curl_global_init(CURL_GLOBAL_DEFAULT);
curl = ::curl_easy_init();
@@ -3031,10 +3126,11 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
}
// check to see if a CAINFO file has been specified
// command arg comes first
- if(cainfo && *cainfo)
+ std::string const& cainfo_err = cmCurlSetCAInfo(curl, cainfo);
+ if (!cainfo_err.empty())
{
- res = ::curl_easy_setopt(curl, CURLOPT_CAINFO, cainfo);
- check_curl_result(res, "Unable to set TLS/SSL Verify CAINFO: ");
+ this->SetError(cainfo_err);
+ return false;
}
cmFileCommandVectorOfChar chunkDebug;
@@ -3048,7 +3144,7 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
res = ::curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
check_curl_result(res, "DOWNLOAD cannot set follow-redirect option: ");
- if(verboseLog.size())
+ if(!verboseLog.empty())
{
res = ::curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
check_curl_result(res, "DOWNLOAD cannot set verbose: ");
@@ -3094,9 +3190,9 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
g_curl.release();
::curl_easy_cleanup(curl);
- if(statusVar.size())
+ if(!statusVar.empty())
{
- cmOStringStream result;
+ std::ostringstream result;
result << (int)res << ";\"" << ::curl_easy_strerror(res) << "\"";
this->Makefile->AddDefinition(statusVar,
result.str().c_str());
@@ -3114,7 +3210,7 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
if (hash.get())
{
std::string actualHash = hash->HashFile(file);
- if (actualHash.size() == 0)
+ if (actualHash.empty())
{
this->SetError("DOWNLOAD cannot compute hash on downloaded file");
return false;
@@ -3122,7 +3218,7 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
if (expectedHash != actualHash)
{
- cmOStringStream oss;
+ std::ostringstream oss;
oss << "DOWNLOAD HASH mismatch" << std::endl
<< " for file: [" << file << "]" << std::endl
<< " expected hash: [" << expectedHash << "]" << std::endl
@@ -3135,14 +3231,14 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
}
}
- if(chunkDebug.size())
+ if(!chunkDebug.empty())
{
chunkDebug.push_back(0);
if(CURLE_OPERATION_TIMEOUTED == res)
{
std::string output = &*chunkDebug.begin();
- if(verboseLog.size())
+ if(!verboseLog.empty())
{
this->Makefile->AddDefinition(verboseLog,
&*chunkDebug.begin());
@@ -3241,7 +3337,7 @@ cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
// Open file for reading:
//
- FILE *fin = cmsys::SystemTools::Fopen(filename.c_str(), "rb");
+ FILE *fin = cmsys::SystemTools::Fopen(filename, "rb");
if(!fin)
{
std::string errStr = "UPLOAD cannot open file '";
@@ -3250,7 +3346,11 @@ cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
return false;
}
- unsigned long file_size = cmsys::SystemTools::FileLength(filename.c_str());
+ unsigned long file_size = cmsys::SystemTools::FileLength(filename);
+
+#if defined(WIN32) && defined(CMAKE_ENCODING_UTF8)
+ url = fix_file_url_windows(url);
+#endif
::CURL *curl;
::curl_global_init(CURL_GLOBAL_DEFAULT);
@@ -3294,7 +3394,7 @@ cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
res = ::curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
check_curl_result(res, "UPLOAD cannot set follow-redirect option: ");
- if(logVar.size())
+ if(!logVar.empty())
{
res = ::curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
check_curl_result(res, "UPLOAD cannot set verbose: ");
@@ -3349,9 +3449,9 @@ cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
g_curl.release();
::curl_easy_cleanup(curl);
- if(statusVar.size())
+ if(!statusVar.empty())
{
- cmOStringStream result;
+ std::ostringstream result;
result << (int)res << ";\"" << ::curl_easy_strerror(res) << "\"";
this->Makefile->AddDefinition(statusVar,
result.str().c_str());
@@ -3362,11 +3462,11 @@ cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
fclose(fin);
fin = NULL;
- if(logVar.size())
+ if(!logVar.empty())
{
std::string log;
- if(chunkResponse.size())
+ if(!chunkResponse.empty())
{
chunkResponse.push_back(0);
log += "Response:\n";
@@ -3374,7 +3474,7 @@ cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
log += "\n";
}
- if(chunkDebug.size())
+ if(!chunkDebug.empty())
{
chunkDebug.push_back(0);
log += "Debug:\n";
@@ -3466,6 +3566,205 @@ bool cmFileCommand::HandleGenerateCommand(
}
//----------------------------------------------------------------------------
+bool cmFileCommand::HandleLockCommand(
+ std::vector<std::string> const& args)
+{
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+ // Default values
+ bool directory = false;
+ bool release = false;
+ enum Guard {
+ GUARD_FUNCTION,
+ GUARD_FILE,
+ GUARD_PROCESS
+ };
+ Guard guard = GUARD_PROCESS;
+ std::string resultVariable;
+ unsigned long timeout = static_cast<unsigned long>(-1);
+
+ // Parse arguments
+ if(args.size() < 2)
+ {
+ this->Makefile->IssueMessage(
+ cmake::FATAL_ERROR,
+ "sub-command LOCK requires at least two arguments.");
+ return false;
+ }
+
+ std::string path = args[1];
+ for (unsigned i = 2; i < args.size(); ++i)
+ {
+ if (args[i] == "DIRECTORY")
+ {
+ directory = true;
+ }
+ else if (args[i] == "RELEASE")
+ {
+ release = true;
+ }
+ else if (args[i] == "GUARD")
+ {
+ ++i;
+ const char* merr = "expected FUNCTION, FILE or PROCESS after GUARD";
+ if (i >= args.size())
+ {
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, merr);
+ return false;
+ }
+ else
+ {
+ if (args[i] == "FUNCTION")
+ {
+ guard = GUARD_FUNCTION;
+ }
+ else if (args[i] == "FILE")
+ {
+ guard = GUARD_FILE;
+ }
+ else if (args[i] == "PROCESS")
+ {
+ guard = GUARD_PROCESS;
+ }
+ else
+ {
+ std::ostringstream e;
+ e << merr << ", but got:\n \"" << args[i] << "\".";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+ }
+ }
+ }
+ else if (args[i] == "RESULT_VARIABLE")
+ {
+ ++i;
+ if (i >= args.size())
+ {
+ this->Makefile->IssueMessage(
+ cmake::FATAL_ERROR,
+ "expected variable name after RESULT_VARIABLE");
+ return false;
+ }
+ resultVariable = args[i];
+ }
+ else if (args[i] == "TIMEOUT")
+ {
+ ++i;
+ if (i >= args.size())
+ {
+ this->Makefile->IssueMessage(
+ cmake::FATAL_ERROR,
+ "expected timeout value after TIMEOUT");
+ return false;
+ }
+ long scanned;
+ if(!cmSystemTools::StringToLong(args[i].c_str(), &scanned)
+ || scanned < 0)
+ {
+ std::ostringstream e;
+ e << "TIMEOUT value \"" << args[i] << "\" is not an unsigned integer.";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+ }
+ timeout = static_cast<unsigned long>(scanned);
+ }
+ else
+ {
+ std::ostringstream e;
+ e << "expected DIRECTORY, RELEASE, GUARD, RESULT_VARIABLE or TIMEOUT\n";
+ e << "but got: \"" << args[i] << "\".";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+ }
+ }
+
+ if (directory)
+ {
+ path += "/cmake.lock";
+ }
+
+ if (!cmsys::SystemTools::FileIsFullPath(path))
+ {
+ path = this->Makefile->GetCurrentDirectory() + ("/" + path);
+ }
+
+ // Unify path (remove '//', '/../', ...)
+ path = cmSystemTools::CollapseFullPath(path);
+
+ // Create file and directories if needed
+ std::string parentDir = cmSystemTools::GetParentDirectory(path);
+ if (!cmSystemTools::MakeDirectory(parentDir))
+ {
+ std::ostringstream e;
+ e << "directory\n \"" << parentDir << "\"\ncreation failed ";
+ e << "(check permissions).";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+ FILE *file = cmsys::SystemTools::Fopen(path, "w");
+ if (!file)
+ {
+ std::ostringstream e;
+ e << "file\n \"" << path << "\"\ncreation failed (check permissions).";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+ fclose(file);
+
+ // Actual lock/unlock
+ cmFileLockPool& lockPool = this->Makefile->GetLocalGenerator()->
+ GetGlobalGenerator()->GetFileLockPool();
+
+ cmFileLockResult fileLockResult(cmFileLockResult::MakeOk());
+ if (release)
+ {
+ fileLockResult = lockPool.Release(path);
+ }
+ else
+ {
+ switch (guard)
+ {
+ case GUARD_FUNCTION:
+ fileLockResult = lockPool.LockFunctionScope(path, timeout);
+ break;
+ case GUARD_FILE:
+ fileLockResult = lockPool.LockFileScope(path, timeout);
+ break;
+ case GUARD_PROCESS:
+ fileLockResult = lockPool.LockProcessScope(path, timeout);
+ break;
+ default:
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+ }
+
+ const std::string result = fileLockResult.GetOutputMessage();
+
+ if (resultVariable.empty() && !fileLockResult.IsOk())
+ {
+ std::ostringstream e;
+ e << "error locking file\n \"" << path << "\"\n" << result << ".";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+
+ if (!resultVariable.empty())
+ {
+ this->Makefile->AddDefinition(resultVariable, result.c_str());
+ }
+
+ return true;
+#else
+ static_cast<void>(args);
+ this->SetError("sub-command LOCK not implemented in bootstrap cmake");
+ return false;
+#endif
+}
+
+//----------------------------------------------------------------------------
bool cmFileCommand::HandleTimestampCommand(
std::vector<std::string> const& args)
{