diff options
Diffstat (limited to 'Source/cmFileCommand.cxx')
| -rw-r--r-- | Source/cmFileCommand.cxx | 100 |
1 files changed, 67 insertions, 33 deletions
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index 7101e22..550ad6e 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -1394,8 +1394,10 @@ size_t cmWriteToFileCallback(void* ptr, size_t size, size_t nmemb, void* data) { int realsize = static_cast<int>(size * nmemb); cmsys::ofstream* fout = static_cast<cmsys::ofstream*>(data); - const char* chPtr = static_cast<char*>(ptr); - fout->write(chPtr, realsize); + if (fout) { + const char* chPtr = static_cast<char*>(ptr); + fout->write(chPtr, realsize); + } return realsize; } @@ -1551,15 +1553,14 @@ bool HandleDownloadCommand(std::vector<std::string> const& args, { #if !defined(CMAKE_BOOTSTRAP) auto i = args.begin(); - if (args.size() < 3) { - status.SetError("DOWNLOAD must be called with at least three arguments."); + if (args.size() < 2) { + status.SetError("DOWNLOAD must be called with at least two arguments."); return false; } ++i; // Get rid of subcommand std::string url = *i; ++i; - std::string file = *i; - ++i; + std::string file; long timeout = 0; long inactivity_timeout = 0; @@ -1690,6 +1691,8 @@ bool HandleDownloadCommand(std::vector<std::string> const& args, return false; } curl_headers.push_back(*i); + } else if (file.empty()) { + file = *i; } else { // Do not return error for compatibility reason. std::string err = cmStrCat("Unexpected argument: ", *i); @@ -1697,11 +1700,18 @@ bool HandleDownloadCommand(std::vector<std::string> const& args, } ++i; } + // Can't calculate hash if we don't save the file. + // TODO Incrementally calculate hash in the write callback as the file is + // being downloaded so this check can be relaxed. + if (file.empty() && hash) { + status.SetError("DOWNLOAD cannot calculate hash if file is not saved."); + return false; + } // If file exists already, and caller specified an expected md5 or sha, // and the existing file already has the expected hash, then simply // return. // - if (cmSystemTools::FileExists(file) && hash.get()) { + if (!file.empty() && cmSystemTools::FileExists(file) && hash.get()) { std::string msg; std::string actualHash = hash->HashFile(file); if (actualHash == expectedHash) { @@ -1716,20 +1726,26 @@ bool HandleDownloadCommand(std::vector<std::string> const& args, // Make sure parent directory exists so we can write to the file // as we receive downloaded bits from curl... // - std::string dir = cmSystemTools::GetFilenamePath(file); - if (!dir.empty() && !cmSystemTools::FileExists(dir) && - !cmSystemTools::MakeDirectory(dir)) { - std::string errstring = "DOWNLOAD error: cannot create directory '" + dir + - "' - Specify file by full path name and verify that you " - "have directory creation and file write privileges."; - status.SetError(errstring); - return false; + if (!file.empty()) { + std::string dir = cmSystemTools::GetFilenamePath(file); + if (!dir.empty() && !cmSystemTools::FileExists(dir) && + !cmSystemTools::MakeDirectory(dir)) { + std::string errstring = "DOWNLOAD error: cannot create directory '" + + dir + + "' - Specify file by full path name and verify that you " + "have directory creation and file write privileges."; + status.SetError(errstring); + return false; + } } - cmsys::ofstream fout(file.c_str(), std::ios::binary); - if (!fout) { - status.SetError("DOWNLOAD cannot open file for write."); - return false; + cmsys::ofstream fout; + if (!file.empty()) { + fout.open(file.c_str(), std::ios::binary); + if (!fout) { + status.SetError("DOWNLOAD cannot open file for write."); + return false; + } } # if defined(_WIN32) @@ -1791,7 +1807,8 @@ bool HandleDownloadCommand(std::vector<std::string> const& args, cmFileCommandVectorOfChar chunkDebug; - res = ::curl_easy_setopt(curl, CURLOPT_WRITEDATA, &fout); + res = ::curl_easy_setopt(curl, CURLOPT_WRITEDATA, + file.empty() ? nullptr : &fout); check_curl_result(res, "DOWNLOAD cannot set write data: "); res = ::curl_easy_setopt(curl, CURLOPT_DEBUGDATA, &chunkDebug); @@ -1865,8 +1882,10 @@ bool HandleDownloadCommand(std::vector<std::string> const& args, // Explicitly flush/close so we can measure the md5 accurately. // - fout.flush(); - fout.close(); + if (!file.empty()) { + fout.flush(); + fout.close(); + } // Verify MD5 sum if requested: // @@ -2221,6 +2240,7 @@ bool HandleUploadCommand(std::vector<std::string> const& args, } void AddEvaluationFile(const std::string& inputName, + const std::string& targetName, const std::string& outputExpr, const std::string& condition, bool inputIsContent, cmExecutionStatus& status) @@ -2236,7 +2256,8 @@ void AddEvaluationFile(const std::string& inputName, conditionGe.Parse(condition); status.GetMakefile().AddEvaluationFile( - inputName, std::move(outputCge), std::move(conditionCge), inputIsContent); + inputName, targetName, std::move(outputCge), std::move(conditionCge), + inputIsContent); } bool HandleGenerateCommand(std::vector<std::string> const& args, @@ -2250,23 +2271,36 @@ bool HandleGenerateCommand(std::vector<std::string> const& args, status.SetError("Incorrect arguments to GENERATE subcommand."); return false; } + std::string condition; - if (args.size() > 5) { - if (args[5] != "CONDITION") { + std::string target; + + for (std::size_t i = 5; i < args.size();) { + const std::string& arg = args[i++]; + + if (args.size() - i == 0) { status.SetError("Incorrect arguments to GENERATE subcommand."); return false; } - if (args.size() != 7) { - status.SetError("Incorrect arguments to GENERATE subcommand."); + + const std::string& value = args[i++]; + + if (value.empty()) { + status.SetError( + arg + " of sub-command GENERATE must not be empty if specified."); return false; } - condition = args[6]; - if (condition.empty()) { - status.SetError("CONDITION of sub-command GENERATE must not be empty if " - "specified."); + + if (arg == "CONDITION") { + condition = value; + } else if (arg == "TARGET") { + target = value; + } else { + status.SetError("Unknown argument to GENERATE subcommand."); return false; } } + std::string output = args[2]; const bool inputIsContent = args[3] != "INPUT"; if (inputIsContent && args[3] != "CONTENT") { @@ -2275,7 +2309,7 @@ bool HandleGenerateCommand(std::vector<std::string> const& args, } std::string input = args[4]; - AddEvaluationFile(input, output, condition, inputIsContent, status); + AddEvaluationFile(input, target, output, condition, inputIsContent, status); return true; } @@ -2918,7 +2952,7 @@ bool HandleConfigureCommand(std::vector<std::string> const& args, } fout.SetCopyIfDifferent(true); - // copy intput to output and expand variables from input at the same time + // copy input to output and expand variables from input at the same time std::stringstream sin(input, std::ios::in); std::string inLine; std::string outLine; |
