summaryrefslogtreecommitdiffstats
path: root/Source/CTest
diff options
context:
space:
mode:
Diffstat (limited to 'Source/CTest')
-rw-r--r--Source/CTest/cmCTestBZR.cxx31
-rw-r--r--Source/CTest/cmCTestBuildAndTestHandler.cxx15
-rw-r--r--Source/CTest/cmCTestBuildHandler.cxx291
-rw-r--r--Source/CTest/cmCTestBuildHandler.h6
-rw-r--r--Source/CTest/cmCTestCVS.cxx18
-rw-r--r--Source/CTest/cmCTestConfigureHandler.cxx2
-rw-r--r--Source/CTest/cmCTestCoverageHandler.cxx109
-rw-r--r--Source/CTest/cmCTestGIT.cxx130
-rw-r--r--Source/CTest/cmCTestHG.cxx35
-rw-r--r--Source/CTest/cmCTestLaunch.cxx121
-rw-r--r--Source/CTest/cmCTestLaunch.h5
-rw-r--r--Source/CTest/cmCTestLaunchReporter.cxx50
-rw-r--r--Source/CTest/cmCTestLaunchReporter.h4
-rw-r--r--Source/CTest/cmCTestP4.cxx66
-rw-r--r--Source/CTest/cmCTestP4.h2
-rw-r--r--Source/CTest/cmCTestSVN.cxx36
-rw-r--r--Source/CTest/cmCTestSVN.h2
-rw-r--r--Source/CTest/cmCTestScriptHandler.cxx84
-rw-r--r--Source/CTest/cmCTestVC.cxx45
-rw-r--r--Source/CTest/cmCTestVC.h9
20 files changed, 579 insertions, 482 deletions
diff --git a/Source/CTest/cmCTestBZR.cxx b/Source/CTest/cmCTestBZR.cxx
index 36df344..246e811 100644
--- a/Source/CTest/cmCTestBZR.cxx
+++ b/Source/CTest/cmCTestBZR.cxx
@@ -135,14 +135,14 @@ private:
std::string cmCTestBZR::LoadInfo()
{
// Run "bzr info" to get the repository info from the work tree.
- std::string bzr = this->CommandLineTool;
- std::vector<std::string> bzr_info = { bzr, "info" };
+ const char* bzr = this->CommandLineTool.c_str();
+ const char* bzr_info[] = { bzr, "info", nullptr };
InfoParser iout(this, "info-out> ");
OutputLogger ierr(this->Log, "info-err> ");
this->RunChild(bzr_info, &iout, &ierr);
// Run "bzr revno" to get the repository revision number from the work tree.
- std::vector<std::string> bzr_revno = { bzr, "revno" };
+ const char* bzr_revno[] = { bzr, "revno", nullptr };
std::string rev;
RevnoParser rout(this, "revno-out> ", rev);
OutputLogger rerr(this->Log, "revno-err> ");
@@ -372,18 +372,22 @@ bool cmCTestBZR::UpdateImpl()
// TODO: if(this->CTest->GetTestModel() == cmCTest::NIGHTLY)
// Use "bzr pull" to update the working tree.
- std::vector<std::string> bzr_update;
- bzr_update.push_back(this->CommandLineTool);
+ std::vector<char const*> bzr_update;
+ bzr_update.push_back(this->CommandLineTool.c_str());
bzr_update.push_back("pull");
- cm::append(bzr_update, args);
+ for (std::string const& arg : args) {
+ bzr_update.push_back(arg.c_str());
+ }
+
+ bzr_update.push_back(this->URL.c_str());
- bzr_update.push_back(this->URL);
+ bzr_update.push_back(nullptr);
// For some reason bzr uses stderr to display the update status.
OutputLogger out(this->Log, "pull-out> ");
UpdateParser err(this, "pull-err> ");
- return this->RunUpdateCommand(bzr_update, &out, &err);
+ return this->RunUpdateCommand(bzr_update.data(), &out, &err);
}
bool cmCTestBZR::LoadRevisions()
@@ -404,9 +408,10 @@ bool cmCTestBZR::LoadRevisions()
}
// Run "bzr log" to get all global revisions of interest.
- std::string bzr = this->CommandLineTool;
- std::vector<std::string> bzr_log = { bzr, "log", "-v", "-r",
- revs, "--xml", this->URL };
+ const char* bzr = this->CommandLineTool.c_str();
+ const char* bzr_log[] = {
+ bzr, "log", "-v", "-r", revs.c_str(), "--xml", this->URL.c_str(), nullptr
+ };
{
LogParser out(this, "log-out> ");
OutputLogger err(this->Log, "log-err> ");
@@ -462,8 +467,8 @@ private:
bool cmCTestBZR::LoadModifications()
{
// Run "bzr status" which reports local modifications.
- std::string bzr = this->CommandLineTool;
- std::vector<std::string> bzr_status = { bzr, "status", "-SV" };
+ const char* bzr = this->CommandLineTool.c_str();
+ const char* bzr_status[] = { bzr, "status", "-SV", nullptr };
StatusParser out(this, "status-out> ");
OutputLogger err(this->Log, "status-err> ");
this->RunChild(bzr_status, &out, &err);
diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx
index bb6ccc3..5feb953 100644
--- a/Source/CTest/cmCTestBuildAndTestHandler.cxx
+++ b/Source/CTest/cmCTestBuildAndTestHandler.cxx
@@ -7,6 +7,8 @@
#include <cstring>
#include <ratio>
+#include "cmsys/Process.h"
+
#include "cmBuildOptions.h"
#include "cmCTest.h"
#include "cmCTestTestHandler.h"
@@ -306,11 +308,12 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
return 1;
}
- std::vector<std::string> testCommand;
- testCommand.push_back(fullPath);
+ std::vector<const char*> testCommand;
+ testCommand.push_back(fullPath.c_str());
for (std::string const& testCommandArg : this->TestCommandArgs) {
- testCommand.push_back(testCommandArg);
+ testCommand.push_back(testCommandArg.c_str());
}
+ testCommand.push_back(nullptr);
std::string outs;
int retval = 0;
// run the test from the this->BuildRunDir if set
@@ -346,10 +349,10 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
}
}
- bool runTestRes = this->CTest->RunTest(testCommand, &outs, &retval, nullptr,
- remainingTime, nullptr);
+ int runTestRes = this->CTest->RunTest(testCommand, &outs, &retval, nullptr,
+ remainingTime, nullptr);
- if (!runTestRes || retval != 0) {
+ if (runTestRes != cmsysProcess_State_Exited || retval != 0) {
out << "Test command failed: " << testCommand[0] << "\n";
retval = 1;
}
diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx
index 859798e..00ecf42 100644
--- a/Source/CTest/cmCTestBuildHandler.cxx
+++ b/Source/CTest/cmCTestBuildHandler.cxx
@@ -3,17 +3,15 @@
#include "cmCTestBuildHandler.h"
#include <cstdlib>
-#include <memory>
#include <ratio>
#include <set>
#include <utility>
#include <cmext/algorithm>
-#include <cm3p/uv.h>
-
#include "cmsys/Directory.hxx"
#include "cmsys/FStream.hxx"
+#include "cmsys/Process.h"
#include "cmCTest.h"
#include "cmCTestLaunchReporter.h"
@@ -26,9 +24,6 @@
#include "cmStringAlgorithms.h"
#include "cmStringReplaceHelper.h"
#include "cmSystemTools.h"
-#include "cmUVHandlePtr.h"
-#include "cmUVProcessChain.h"
-#include "cmUVStream.h"
#include "cmValue.h"
#include "cmXMLWriter.h"
@@ -425,7 +420,7 @@ int cmCTestBuildHandler::ProcessHandler()
cmStringReplaceHelper colorRemover("\x1b\\[[0-9;]*m", "", nullptr);
this->ColorRemover = &colorRemover;
int retVal = 0;
- bool res = true;
+ int res = cmsysProcess_State_Exited;
if (!this->CTest->GetShowOnly()) {
res = this->RunMakeCommand(makeCommand, &retVal, buildDirectory.c_str(), 0,
ofs);
@@ -480,7 +475,7 @@ int cmCTestBuildHandler::ProcessHandler()
}
this->GenerateXMLFooter(xml, elapsed_build_time);
- if (!res || retVal || this->TotalErrors > 0) {
+ if (res != cmsysProcess_State_Exited || retVal || this->TotalErrors > 0) {
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Error(s) when building project" << std::endl);
}
@@ -769,10 +764,10 @@ void cmCTestBuildHandler::LaunchHelper::WriteScrapeMatchers(
}
}
-bool cmCTestBuildHandler::RunMakeCommand(const std::string& command,
- int* retVal, const char* dir,
- int timeout, std::ostream& ofs,
- Encoding encoding)
+int cmCTestBuildHandler::RunMakeCommand(const std::string& command,
+ int* retVal, const char* dir,
+ int timeout, std::ostream& ofs,
+ Encoding encoding)
{
// First generate the command and arguments
std::vector<std::string> args = cmSystemTools::ParseArguments(command);
@@ -781,9 +776,19 @@ bool cmCTestBuildHandler::RunMakeCommand(const std::string& command,
return false;
}
+ std::vector<const char*> argv;
+ argv.reserve(args.size() + 1);
+ for (std::string const& arg : args) {
+ argv.push_back(arg.c_str());
+ }
+ argv.push_back(nullptr);
+
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"Run command:", this->Quiet);
- for (auto const& arg : args) {
+ for (char const* arg : argv) {
+ if (!arg) {
+ break;
+ }
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
" \"" << arg << "\"", this->Quiet);
}
@@ -795,20 +800,21 @@ bool cmCTestBuildHandler::RunMakeCommand(const std::string& command,
static_cast<void>(launchHelper);
// Now create process object
- cmUVProcessChainBuilder builder;
- builder.AddCommand(args)
- .SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT)
- .SetBuiltinStream(cmUVProcessChainBuilder::Stream_ERROR);
- if (dir) {
- builder.SetWorkingDirectory(dir);
- }
- auto chain = builder.Start();
+ cmsysProcess* cp = cmsysProcess_New();
+ cmsysProcess_SetCommand(cp, argv.data());
+ cmsysProcess_SetWorkingDirectory(cp, dir);
+ cmsysProcess_SetOption(cp, cmsysProcess_Option_HideWindow, 1);
+ cmsysProcess_SetTimeout(cp, timeout);
+ cmsysProcess_Execute(cp);
// Initialize tick's
std::string::size_type tick = 0;
- static constexpr std::string::size_type tick_len = 1024;
+ const std::string::size_type tick_len = 1024;
+ char* data;
+ int length;
cmProcessOutput processOutput(encoding);
+ std::string strdata;
cmCTestOptionalLog(
this->CTest, HANDLER_PROGRESS_OUTPUT,
" Each symbol represents "
@@ -830,65 +836,39 @@ bool cmCTestBuildHandler::RunMakeCommand(const std::string& command,
this->WarningQuotaReached = false;
this->ErrorQuotaReached = false;
- cm::uv_timer_ptr timer;
- bool timedOut = false;
- timer.init(chain.GetLoop(), &timedOut);
- if (timeout > 0) {
- timer.start(
- [](uv_timer_t* t) {
- auto* timedOutPtr = static_cast<bool*>(t->data);
- *timedOutPtr = true;
- },
- timeout * 1000, 0);
- }
-
// For every chunk of data
- cm::uv_pipe_ptr outputStream;
- bool outFinished = false;
- cm::uv_pipe_ptr errorStream;
- bool errFinished = false;
- auto startRead = [this, &chain, &processOutput, &tick,
- &ofs](cm::uv_pipe_ptr& pipe, int stream,
- t_BuildProcessingQueueType& queue, bool& finished,
- int id) -> std::unique_ptr<cmUVStreamReadHandle> {
- pipe.init(chain.GetLoop(), 0);
- uv_pipe_open(pipe, stream);
- return cmUVStreamRead(
- pipe,
- [this, &processOutput, &queue, id, &tick, &ofs](std::vector<char> data) {
- // Replace '\0' with '\n', since '\0' does not really make sense. This
- // is for Visual Studio output
- for (auto& c : data) {
- if (c == 0) {
- c = '\n';
- }
- }
+ int res;
+ while ((res = cmsysProcess_WaitForData(cp, &data, &length, nullptr))) {
+ // Replace '\0' with '\n', since '\0' does not really make sense. This is
+ // for Visual Studio output
+ for (int cc = 0; cc < length; ++cc) {
+ if (data[cc] == 0) {
+ data[cc] = '\n';
+ }
+ }
- // Process the chunk of data
- std::string strdata;
- processOutput.DecodeText(data.data(), data.size(), strdata, id);
- this->ProcessBuffer(strdata.c_str(), strdata.size(), tick, tick_len,
- ofs, &queue);
- },
- [this, &processOutput, &queue, id, &tick, &ofs, &finished]() {
- std::string strdata;
- processOutput.DecodeText(std::string(), strdata, id);
- if (!strdata.empty()) {
- this->ProcessBuffer(strdata.c_str(), strdata.size(), tick, tick_len,
- ofs, &queue);
- }
- finished = true;
- });
- };
- auto outputHandle = startRead(outputStream, chain.OutputStream(),
- this->BuildProcessingQueue, outFinished, 1);
- auto errorHandle =
- startRead(errorStream, chain.ErrorStream(),
- this->BuildProcessingErrorQueue, errFinished, 2);
-
- while (!timedOut && !(outFinished && errFinished && chain.Finished())) {
- uv_run(&chain.GetLoop(), UV_RUN_ONCE);
+ // Process the chunk of data
+ if (res == cmsysProcess_Pipe_STDERR) {
+ processOutput.DecodeText(data, length, strdata, 1);
+ this->ProcessBuffer(strdata.c_str(), strdata.size(), tick, tick_len, ofs,
+ &this->BuildProcessingErrorQueue);
+ } else {
+ processOutput.DecodeText(data, length, strdata, 2);
+ this->ProcessBuffer(strdata.c_str(), strdata.size(), tick, tick_len, ofs,
+ &this->BuildProcessingQueue);
+ }
+ }
+ processOutput.DecodeText(std::string(), strdata, 1);
+ if (!strdata.empty()) {
+ this->ProcessBuffer(strdata.c_str(), strdata.size(), tick, tick_len, ofs,
+ &this->BuildProcessingErrorQueue);
}
+ processOutput.DecodeText(std::string(), strdata, 2);
+ if (!strdata.empty()) {
+ this->ProcessBuffer(strdata.c_str(), strdata.size(), tick, tick_len, ofs,
+ &this->BuildProcessingQueue);
+ }
+
this->ProcessBuffer(nullptr, 0, tick, tick_len, ofs,
&this->BuildProcessingQueue);
this->ProcessBuffer(nullptr, 0, tick, tick_len, ofs,
@@ -899,93 +879,90 @@ bool cmCTestBuildHandler::RunMakeCommand(const std::string& command,
<< std::endl,
this->Quiet);
- if (chain.Finished()) {
- auto const& status = chain.GetStatus(0);
- auto exception = status.GetException();
- switch (exception.first) {
- case cmUVProcessChain::ExceptionCode::None:
- if (retVal) {
- *retVal = static_cast<int>(status.ExitStatus);
- cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
- "Command exited with the value: " << *retVal
- << std::endl,
- this->Quiet);
- // if a non zero return value
- if (*retVal) {
- // If there was an error running command, report that on the
- // dashboard.
- if (this->UseCTestLaunch) {
- // For launchers, do not record this top-level error if other
- // more granular build errors have already been captured.
- bool launcherXMLFound = false;
- cmsys::Directory launchDir;
- launchDir.Load(this->CTestLaunchDir);
- unsigned long n = launchDir.GetNumberOfFiles();
- for (unsigned long i = 0; i < n; ++i) {
- const char* fname = launchDir.GetFile(i);
- if (cmHasLiteralSuffix(fname, ".xml")) {
- launcherXMLFound = true;
- break;
- }
- }
- if (!launcherXMLFound) {
- cmCTestLaunchReporter reporter;
- reporter.RealArgs = args;
- reporter.ComputeFileNames();
- reporter.ExitCode = *retVal;
- reporter.Status = status;
- // Use temporary BuildLog file to populate this error for
- // CDash.
- ofs.flush();
- reporter.LogOut = this->LogFileNames["Build"];
- reporter.LogOut += ".tmp";
- reporter.WriteXML();
- }
- } else {
- cmCTestBuildErrorWarning errorwarning;
- errorwarning.LineNumber = 0;
- errorwarning.LogLine = 1;
- errorwarning.Text = cmStrCat(
- "*** WARNING non-zero return value in ctest from: ", args[0]);
- errorwarning.PreContext.clear();
- errorwarning.PostContext.clear();
- errorwarning.Error = false;
- this->ErrorsAndWarnings.push_back(std::move(errorwarning));
- this->TotalWarnings++;
+ // Properly handle output of the build command
+ cmsysProcess_WaitForExit(cp, nullptr);
+ int result = cmsysProcess_GetState(cp);
+
+ if (result == cmsysProcess_State_Exited) {
+ if (retVal) {
+ *retVal = cmsysProcess_GetExitValue(cp);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Command exited with the value: " << *retVal
+ << std::endl,
+ this->Quiet);
+ // if a non zero return value
+ if (*retVal) {
+ // If there was an error running command, report that on the
+ // dashboard.
+ if (this->UseCTestLaunch) {
+ // For launchers, do not record this top-level error if other
+ // more granular build errors have already been captured.
+ bool launcherXMLFound = false;
+ cmsys::Directory launchDir;
+ launchDir.Load(this->CTestLaunchDir);
+ unsigned long n = launchDir.GetNumberOfFiles();
+ for (unsigned long i = 0; i < n; ++i) {
+ const char* fname = launchDir.GetFile(i);
+ if (cmHasLiteralSuffix(fname, ".xml")) {
+ launcherXMLFound = true;
+ break;
}
}
+ if (!launcherXMLFound) {
+ cmCTestLaunchReporter reporter;
+ reporter.RealArgs = args;
+ reporter.ComputeFileNames();
+ reporter.ExitCode = *retVal;
+ reporter.Process = cp;
+ // Use temporary BuildLog file to populate this error for CDash.
+ ofs.flush();
+ reporter.LogOut = this->LogFileNames["Build"];
+ reporter.LogOut += ".tmp";
+ reporter.WriteXML();
+ }
+ } else {
+ cmCTestBuildErrorWarning errorwarning;
+ errorwarning.LineNumber = 0;
+ errorwarning.LogLine = 1;
+ errorwarning.Text = cmStrCat(
+ "*** WARNING non-zero return value in ctest from: ", argv[0]);
+ errorwarning.PreContext.clear();
+ errorwarning.PostContext.clear();
+ errorwarning.Error = false;
+ this->ErrorsAndWarnings.push_back(std::move(errorwarning));
+ this->TotalWarnings++;
}
- break;
- case cmUVProcessChain::ExceptionCode::Spawn: {
- // If there was an error running command, report that on the dashboard.
- cmCTestBuildErrorWarning errorwarning;
- errorwarning.LineNumber = 0;
- errorwarning.LogLine = 1;
- errorwarning.Text =
- cmStrCat("*** ERROR executing: ", exception.second);
- errorwarning.PreContext.clear();
- errorwarning.PostContext.clear();
- errorwarning.Error = true;
- this->ErrorsAndWarnings.push_back(std::move(errorwarning));
- this->TotalErrors++;
- cmCTestLog(this->CTest, ERROR_MESSAGE,
- "There was an error: " << exception.second << std::endl);
- } break;
- default:
- if (retVal) {
- *retVal = status.TermSignal;
- cmCTestOptionalLog(
- this->CTest, WARNING,
- "There was an exception: " << *retVal << std::endl, this->Quiet);
- }
- break;
+ }
}
- } else {
+ } else if (result == cmsysProcess_State_Exception) {
+ if (retVal) {
+ *retVal = cmsysProcess_GetExitException(cp);
+ cmCTestOptionalLog(this->CTest, WARNING,
+ "There was an exception: " << *retVal << std::endl,
+ this->Quiet);
+ }
+ } else if (result == cmsysProcess_State_Expired) {
cmCTestOptionalLog(this->CTest, WARNING,
"There was a timeout" << std::endl, this->Quiet);
+ } else if (result == cmsysProcess_State_Error) {
+ // If there was an error running command, report that on the dashboard.
+ cmCTestBuildErrorWarning errorwarning;
+ errorwarning.LineNumber = 0;
+ errorwarning.LogLine = 1;
+ errorwarning.Text =
+ cmStrCat("*** ERROR executing: ", cmsysProcess_GetErrorString(cp));
+ errorwarning.PreContext.clear();
+ errorwarning.PostContext.clear();
+ errorwarning.Error = true;
+ this->ErrorsAndWarnings.push_back(std::move(errorwarning));
+ this->TotalErrors++;
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "There was an error: " << cmsysProcess_GetErrorString(cp)
+ << std::endl);
}
- return true;
+ cmsysProcess_Delete(cp);
+ return result;
}
// ######################################################################
diff --git a/Source/CTest/cmCTestBuildHandler.h b/Source/CTest/cmCTestBuildHandler.h
index 90945b1..e33294d 100644
--- a/Source/CTest/cmCTestBuildHandler.h
+++ b/Source/CTest/cmCTestBuildHandler.h
@@ -53,9 +53,9 @@ private:
//! Run command specialized for make and configure. Returns process status
// and retVal is return value or exception.
- bool RunMakeCommand(const std::string& command, int* retVal, const char* dir,
- int timeout, std::ostream& ofs,
- Encoding encoding = cmProcessOutput::Auto);
+ int RunMakeCommand(const std::string& command, int* retVal, const char* dir,
+ int timeout, std::ostream& ofs,
+ Encoding encoding = cmProcessOutput::Auto);
enum
{
diff --git a/Source/CTest/cmCTestCVS.cxx b/Source/CTest/cmCTestCVS.cxx
index ef95b25..95e898c 100644
--- a/Source/CTest/cmCTestCVS.cxx
+++ b/Source/CTest/cmCTestCVS.cxx
@@ -5,7 +5,6 @@
#include <utility>
#include <cm/string_view>
-#include <cmext/algorithm>
#include "cmsys/FStream.hxx"
#include "cmsys/RegularExpression.hxx"
@@ -90,15 +89,18 @@ bool cmCTestCVS::UpdateImpl()
}
// Run "cvs update" to update the work tree.
- std::vector<std::string> cvs_update;
- cvs_update.push_back(this->CommandLineTool);
+ std::vector<char const*> cvs_update;
+ cvs_update.push_back(this->CommandLineTool.c_str());
cvs_update.push_back("-z3");
cvs_update.push_back("update");
- cm::append(cvs_update, args);
+ for (std::string const& arg : args) {
+ cvs_update.push_back(arg.c_str());
+ }
+ cvs_update.push_back(nullptr);
UpdateParser out(this, "up-out> ");
UpdateParser err(this, "up-err> ");
- return this->RunUpdateCommand(cvs_update, &out, &err);
+ return this->RunUpdateCommand(cvs_update.data(), &out, &err);
}
class cmCTestCVS::LogParser : public cmCTestVC::LineParser
@@ -219,8 +221,10 @@ void cmCTestCVS::LoadRevisions(std::string const& file, const char* branchFlag,
cmCTestLog(this->CTest, HANDLER_OUTPUT, "." << std::flush);
// Run "cvs log" to get revisions of this file on this branch.
- std::string cvs = this->CommandLineTool;
- std::vector<std::string> cvs_log = { cvs, "log", "-N", branchFlag, file };
+ const char* cvs = this->CommandLineTool.c_str();
+ const char* cvs_log[] = {
+ cvs, "log", "-N", branchFlag, file.c_str(), nullptr
+ };
LogParser out(this, "log-out> ", revisions);
OutputLogger err(this->Log, "log-err> ");
diff --git a/Source/CTest/cmCTestConfigureHandler.cxx b/Source/CTest/cmCTestConfigureHandler.cxx
index dd8952f..914930e 100644
--- a/Source/CTest/cmCTestConfigureHandler.cxx
+++ b/Source/CTest/cmCTestConfigureHandler.cxx
@@ -45,7 +45,7 @@ int cmCTestConfigureHandler::ProcessHandler()
auto elapsed_time_start = std::chrono::steady_clock::now();
std::string output;
int retVal = 0;
- bool res = false;
+ int res = 0;
if (!this->CTest->GetShowOnly()) {
cmGeneratedFileStream os;
if (!this->StartResultingXML(cmCTest::PartConfigure, "Configure", os)) {
diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx
index f9f9add..2874be7 100644
--- a/Source/CTest/cmCTestCoverageHandler.cxx
+++ b/Source/CTest/cmCTestCoverageHandler.cxx
@@ -9,7 +9,6 @@
#include <cstring>
#include <iomanip>
#include <iterator>
-#include <memory>
#include <ratio>
#include <sstream>
#include <type_traits>
@@ -19,6 +18,7 @@
#include "cmsys/FStream.hxx"
#include "cmsys/Glob.hxx"
+#include "cmsys/Process.h"
#include "cmsys/RegularExpression.hxx"
#include "cmCTest.h"
@@ -33,7 +33,6 @@
#include "cmParsePHPCoverage.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-#include "cmUVProcessChain.h"
#include "cmWorkingDirectory.h"
#include "cmXMLWriter.h"
@@ -41,6 +40,85 @@ class cmMakefile;
#define SAFEDIV(x, y) (((y) != 0) ? ((x) / (y)) : (0))
+class cmCTestRunProcess
+{
+public:
+ cmCTestRunProcess()
+ {
+ this->Process = cmsysProcess_New();
+ this->PipeState = -1;
+ this->TimeOut = cmDuration(-1);
+ }
+ ~cmCTestRunProcess()
+ {
+ if (this->PipeState != -1 && this->PipeState != cmsysProcess_Pipe_None &&
+ this->PipeState != cmsysProcess_Pipe_Timeout) {
+ this->WaitForExit();
+ }
+ cmsysProcess_Delete(this->Process);
+ }
+ cmCTestRunProcess(const cmCTestRunProcess&) = delete;
+ cmCTestRunProcess& operator=(const cmCTestRunProcess&) = delete;
+ void SetCommand(const char* command)
+ {
+ this->CommandLineStrings.clear();
+ this->CommandLineStrings.emplace_back(command);
+ }
+ void AddArgument(const char* arg)
+ {
+ if (arg) {
+ this->CommandLineStrings.emplace_back(arg);
+ }
+ }
+ void SetWorkingDirectory(const char* dir) { this->WorkingDirectory = dir; }
+ void SetTimeout(cmDuration t) { this->TimeOut = t; }
+ bool StartProcess()
+ {
+ std::vector<const char*> args;
+ args.reserve(this->CommandLineStrings.size());
+ for (std::string const& cl : this->CommandLineStrings) {
+ args.push_back(cl.c_str());
+ }
+ args.push_back(nullptr); // null terminate
+ cmsysProcess_SetCommand(this->Process, args.data());
+ if (!this->WorkingDirectory.empty()) {
+ cmsysProcess_SetWorkingDirectory(this->Process,
+ this->WorkingDirectory.c_str());
+ }
+
+ cmsysProcess_SetOption(this->Process, cmsysProcess_Option_HideWindow, 1);
+ if (this->TimeOut >= cmDuration::zero()) {
+ cmsysProcess_SetTimeout(this->Process, this->TimeOut.count());
+ }
+ cmsysProcess_Execute(this->Process);
+ this->PipeState = cmsysProcess_GetState(this->Process);
+ // if the process is running or exited return true
+ return this->PipeState == cmsysProcess_State_Executing ||
+ this->PipeState == cmsysProcess_State_Exited;
+ }
+ void SetStdoutFile(const char* fname)
+ {
+ cmsysProcess_SetPipeFile(this->Process, cmsysProcess_Pipe_STDOUT, fname);
+ }
+ void SetStderrFile(const char* fname)
+ {
+ cmsysProcess_SetPipeFile(this->Process, cmsysProcess_Pipe_STDERR, fname);
+ }
+ int WaitForExit(double* timeout = nullptr)
+ {
+ this->PipeState = cmsysProcess_WaitForExit(this->Process, timeout);
+ return this->PipeState;
+ }
+ int GetProcessState() const { return this->PipeState; }
+
+private:
+ int PipeState;
+ cmsysProcess* Process;
+ std::vector<std::string> CommandLineStrings;
+ std::string WorkingDirectory;
+ cmDuration TimeOut;
+};
+
cmCTestCoverageHandler::cmCTestCoverageHandler() = default;
void cmCTestCoverageHandler::Initialize()
@@ -1862,35 +1940,34 @@ int cmCTestCoverageHandler::RunBullseyeCommand(
cmCTestLog(this->CTest, ERROR_MESSAGE, "Cannot find :" << cmd << "\n");
return 0;
}
- std::vector<std::string> args{ cmd };
if (arg) {
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"Run : " << program << " " << arg << "\n", this->Quiet);
- args.emplace_back(arg);
} else {
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"Run : " << program << "\n", this->Quiet);
}
// create a process object and start it
- cmUVProcessChainBuilder builder;
+ cmCTestRunProcess runCoverageSrc;
+ runCoverageSrc.SetCommand(program.c_str());
+ runCoverageSrc.AddArgument(arg);
std::string stdoutFile =
cmStrCat(cont->BinaryDir, "/Testing/Temporary/",
this->GetCTestInstance()->GetCurrentTag(), '-', cmd);
std::string stderrFile = stdoutFile;
stdoutFile += ".stdout";
stderrFile += ".stderr";
- std::unique_ptr<FILE, int (*)(FILE*)> stdoutHandle(
- cmsys::SystemTools::Fopen(stdoutFile, "w"), fclose);
- std::unique_ptr<FILE, int (*)(FILE*)> stderrHandle(
- cmsys::SystemTools::Fopen(stderrFile, "w"), fclose);
- builder.AddCommand(args)
- .SetExternalStream(cmUVProcessChainBuilder::Stream_OUTPUT,
- stdoutHandle.get())
- .SetExternalStream(cmUVProcessChainBuilder::Stream_ERROR,
- stderrHandle.get());
+ runCoverageSrc.SetStdoutFile(stdoutFile.c_str());
+ runCoverageSrc.SetStderrFile(stderrFile.c_str());
+ if (!runCoverageSrc.StartProcess()) {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Could not run : " << program << " " << arg << "\n"
+ << "kwsys process state : "
+ << runCoverageSrc.GetProcessState());
+ return 0;
+ }
// since we set the output file names wait for it to end
- auto chain = builder.Start();
- chain.Wait();
+ runCoverageSrc.WaitForExit();
outputFile = stdoutFile;
return 1;
}
diff --git a/Source/CTest/cmCTestGIT.cxx b/Source/CTest/cmCTestGIT.cxx
index ca8659e..5f8cb74 100644
--- a/Source/CTest/cmCTestGIT.cxx
+++ b/Source/CTest/cmCTestGIT.cxx
@@ -9,9 +9,8 @@
#include <utility>
#include <vector>
-#include <cmext/algorithm>
-
#include "cmsys/FStream.hxx"
+#include "cmsys/Process.h"
#include "cmCTest.h"
#include "cmCTestVC.h"
@@ -19,7 +18,6 @@
#include "cmProcessOutput.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-#include "cmUVProcessChain.h"
#include "cmValue.h"
static unsigned int cmCTestGITVersion(unsigned int epic, unsigned int major,
@@ -60,9 +58,9 @@ private:
std::string cmCTestGIT::GetWorkingRevision()
{
// Run plumbing "git rev-list" to get work tree revision.
- std::string git = this->CommandLineTool;
- std::vector<std::string> git_rev_list = { git, "rev-list", "-n",
- "1", "HEAD", "--" };
+ const char* git = this->CommandLineTool.c_str();
+ const char* git_rev_list[] = { git, "rev-list", "-n", "1",
+ "HEAD", "--", nullptr };
std::string rev;
OneLineParser out(this, "rl-out> ", rev);
OutputLogger err(this->Log, "rl-err> ");
@@ -94,13 +92,13 @@ std::string cmCTestGIT::FindGitDir()
std::string git_dir;
// Run "git rev-parse --git-dir" to locate the real .git directory.
- std::string git = this->CommandLineTool;
- std::vector<std::string> git_rev_parse = { git, "rev-parse", "--git-dir" };
+ const char* git = this->CommandLineTool.c_str();
+ char const* git_rev_parse[] = { git, "rev-parse", "--git-dir", nullptr };
std::string git_dir_line;
OneLineParser rev_parse_out(this, "rev-parse-out> ", git_dir_line);
OutputLogger rev_parse_err(this->Log, "rev-parse-err> ");
- if (this->RunChild(git_rev_parse, &rev_parse_out, &rev_parse_err,
- std::string{}, cmProcessOutput::UTF8)) {
+ if (this->RunChild(git_rev_parse, &rev_parse_out, &rev_parse_err, nullptr,
+ cmProcessOutput::UTF8)) {
git_dir = git_dir_line;
}
if (git_dir.empty()) {
@@ -119,10 +117,11 @@ std::string cmCTestGIT::FindGitDir()
std::string cygpath_exe =
cmStrCat(cmSystemTools::GetFilenamePath(git), "/cygpath.exe");
if (cmSystemTools::FileExists(cygpath_exe)) {
- std::vector<std::string> cygpath = { cygpath_exe, "-w", git_dir };
+ char const* cygpath[] = { cygpath_exe.c_str(), "-w", git_dir.c_str(),
+ 0 };
OneLineParser cygpath_out(this, "cygpath-out> ", git_dir_line);
OutputLogger cygpath_err(this->Log, "cygpath-err> ");
- if (this->RunChild(cygpath, &cygpath_out, &cygpath_err, std::string{},
+ if (this->RunChild(cygpath, &cygpath_out, &cygpath_err, nullptr,
cmProcessOutput::UTF8)) {
git_dir = git_dir_line;
}
@@ -137,12 +136,12 @@ std::string cmCTestGIT::FindTopDir()
std::string top_dir = this->SourceDirectory;
// Run "git rev-parse --show-cdup" to locate the top of the tree.
- std::string git = this->CommandLineTool;
- std::vector<std::string> git_rev_parse = { git, "rev-parse", "--show-cdup" };
+ const char* git = this->CommandLineTool.c_str();
+ char const* git_rev_parse[] = { git, "rev-parse", "--show-cdup", nullptr };
std::string cdup;
OneLineParser rev_parse_out(this, "rev-parse-out> ", cdup);
OutputLogger rev_parse_err(this->Log, "rev-parse-err> ");
- if (this->RunChild(git_rev_parse, &rev_parse_out, &rev_parse_err, "",
+ if (this->RunChild(git_rev_parse, &rev_parse_out, &rev_parse_err, nullptr,
cmProcessOutput::UTF8) &&
!cdup.empty()) {
top_dir += "/";
@@ -154,10 +153,10 @@ std::string cmCTestGIT::FindTopDir()
bool cmCTestGIT::UpdateByFetchAndReset()
{
- std::string git = this->CommandLineTool;
+ const char* git = this->CommandLineTool.c_str();
// Use "git fetch" to get remote commits.
- std::vector<std::string> git_fetch;
+ std::vector<char const*> git_fetch;
git_fetch.push_back(git);
git_fetch.push_back("fetch");
@@ -167,12 +166,17 @@ bool cmCTestGIT::UpdateByFetchAndReset()
opts = this->CTest->GetCTestConfiguration("GITUpdateOptions");
}
std::vector<std::string> args = cmSystemTools::ParseArguments(opts);
- cm::append(git_fetch, args);
+ for (std::string const& arg : args) {
+ git_fetch.push_back(arg.c_str());
+ }
+
+ // Sentinel argument.
+ git_fetch.push_back(nullptr);
// Fetch upstream refs.
OutputLogger fetch_out(this->Log, "fetch-out> ");
OutputLogger fetch_err(this->Log, "fetch-err> ");
- if (!this->RunUpdateCommand(git_fetch, &fetch_out, &fetch_err)) {
+ if (!this->RunUpdateCommand(git_fetch.data(), &fetch_out, &fetch_err)) {
return false;
}
@@ -203,22 +207,25 @@ bool cmCTestGIT::UpdateByFetchAndReset()
}
// Reset the local branch to point at that tracked from upstream.
- std::vector<std::string> git_reset = { git, "reset", "--hard", sha1 };
+ char const* git_reset[] = { git, "reset", "--hard", sha1.c_str(), nullptr };
OutputLogger reset_out(this->Log, "reset-out> ");
OutputLogger reset_err(this->Log, "reset-err> ");
- return this->RunChild(git_reset, &reset_out, &reset_err);
+ return this->RunChild(&git_reset[0], &reset_out, &reset_err);
}
bool cmCTestGIT::UpdateByCustom(std::string const& custom)
{
cmList git_custom_command{ custom, cmList::EmptyElements::Yes };
- std::vector<std::string> git_custom;
- git_custom.reserve(git_custom_command.size());
- cm::append(git_custom, git_custom_command);
+ std::vector<char const*> git_custom;
+ git_custom.reserve(git_custom_command.size() + 1);
+ for (std::string const& i : git_custom_command) {
+ git_custom.push_back(i.c_str());
+ }
+ git_custom.push_back(nullptr);
OutputLogger custom_out(this->Log, "custom-out> ");
OutputLogger custom_err(this->Log, "custom-err> ");
- return this->RunUpdateCommand(git_custom, &custom_out, &custom_err);
+ return this->RunUpdateCommand(git_custom.data(), &custom_out, &custom_err);
}
bool cmCTestGIT::UpdateInternal()
@@ -237,14 +244,13 @@ bool cmCTestGIT::UpdateImpl()
}
std::string top_dir = this->FindTopDir();
- std::string git = this->CommandLineTool;
- std::string recursive = "--recursive";
- std::string sync_recursive = "--recursive";
+ const char* git = this->CommandLineTool.c_str();
+ const char* recursive = "--recursive";
+ const char* sync_recursive = "--recursive";
// Git < 1.6.5 did not support submodule --recursive
- bool support_recursive = true;
if (this->GetGitVersion() < cmCTestGITVersion(1, 6, 5, 0)) {
- support_recursive = false;
+ recursive = nullptr;
// No need to require >= 1.6.5 if there are no submodules.
if (cmSystemTools::FileExists(top_dir + "/.gitmodules")) {
this->Log << "Git < 1.6.5 cannot update submodules recursively\n";
@@ -252,9 +258,8 @@ bool cmCTestGIT::UpdateImpl()
}
// Git < 1.8.1 did not support sync --recursive
- bool support_sync_recursive = true;
if (this->GetGitVersion() < cmCTestGITVersion(1, 8, 1, 0)) {
- support_sync_recursive = false;
+ sync_recursive = nullptr;
// No need to require >= 1.8.1 if there are no submodules.
if (cmSystemTools::FileExists(top_dir + "/.gitmodules")) {
this->Log << "Git < 1.8.1 cannot synchronize submodules recursively\n";
@@ -269,39 +274,35 @@ bool cmCTestGIT::UpdateImpl()
std::string init_submodules =
this->CTest->GetCTestConfiguration("GITInitSubmodules");
if (cmIsOn(init_submodules)) {
- std::vector<std::string> git_submodule_init = { git, "submodule", "init" };
+ char const* git_submodule_init[] = { git, "submodule", "init", nullptr };
ret = this->RunChild(git_submodule_init, &submodule_out, &submodule_err,
- top_dir);
+ top_dir.c_str());
if (!ret) {
return false;
}
}
- std::vector<std::string> git_submodule_sync = { git, "submodule", "sync" };
- if (support_sync_recursive) {
- git_submodule_sync.push_back(sync_recursive);
- }
+ char const* git_submodule_sync[] = { git, "submodule", "sync",
+ sync_recursive, nullptr };
ret = this->RunChild(git_submodule_sync, &submodule_out, &submodule_err,
- top_dir);
+ top_dir.c_str());
if (!ret) {
return false;
}
- std::vector<std::string> git_submodule = { git, "submodule", "update" };
- if (support_recursive) {
- git_submodule.push_back(recursive);
- }
+ char const* git_submodule[] = { git, "submodule", "update", recursive,
+ nullptr };
return this->RunChild(git_submodule, &submodule_out, &submodule_err,
- top_dir);
+ top_dir.c_str());
}
unsigned int cmCTestGIT::GetGitVersion()
{
if (!this->CurrentGitVersion) {
- std::string git = this->CommandLineTool;
- std::vector<std::string> git_version = { git, "--version" };
+ const char* git = this->CommandLineTool.c_str();
+ char const* git_version[] = { git, "--version", nullptr };
std::string version;
OneLineParser version_out(this, "version-out> ", version);
OutputLogger version_err(this->Log, "version-err> ");
@@ -604,49 +605,50 @@ bool cmCTestGIT::LoadRevisions()
{
// Use 'git rev-list ... | git diff-tree ...' to get revisions.
std::string range = this->OldRevision + ".." + this->NewRevision;
- std::string git = this->CommandLineTool;
- std::vector<std::string> git_rev_list = { git, "rev-list", "--reverse",
- range, "--" };
- std::vector<std::string> git_diff_tree = {
- git, "diff-tree", "--stdin", "--always",
- "-z", "-r", "--pretty=raw", "--encoding=utf-8"
+ const char* git = this->CommandLineTool.c_str();
+ const char* git_rev_list[] = { git, "rev-list", "--reverse",
+ range.c_str(), "--", nullptr };
+ const char* git_diff_tree[] = {
+ git, "diff-tree", "--stdin", "--always", "-z",
+ "-r", "--pretty=raw", "--encoding=utf-8", nullptr
};
this->Log << cmCTestGIT::ComputeCommandLine(git_rev_list) << " | "
<< cmCTestGIT::ComputeCommandLine(git_diff_tree) << "\n";
- cmUVProcessChainBuilder builder;
- builder.AddCommand(git_rev_list)
- .AddCommand(git_diff_tree)
- .SetWorkingDirectory(this->SourceDirectory);
+ cmsysProcess* cp = cmsysProcess_New();
+ cmsysProcess_AddCommand(cp, git_rev_list);
+ cmsysProcess_AddCommand(cp, git_diff_tree);
+ cmsysProcess_SetWorkingDirectory(cp, this->SourceDirectory.c_str());
CommitParser out(this, "dt-out> ");
OutputLogger err(this->Log, "dt-err> ");
- cmCTestGIT::RunProcess(builder, &out, &err, cmProcessOutput::UTF8);
+ cmCTestGIT::RunProcess(cp, &out, &err, cmProcessOutput::UTF8);
// Send one extra zero-byte to terminate the last record.
out.Process("", 1);
+ cmsysProcess_Delete(cp);
return true;
}
bool cmCTestGIT::LoadModifications()
{
- std::string git = this->CommandLineTool;
+ const char* git = this->CommandLineTool.c_str();
// Use 'git update-index' to refresh the index w.r.t. the work tree.
- std::vector<std::string> git_update_index = { git, "update-index",
- "--refresh" };
+ const char* git_update_index[] = { git, "update-index", "--refresh",
+ nullptr };
OutputLogger ui_out(this->Log, "ui-out> ");
OutputLogger ui_err(this->Log, "ui-err> ");
- this->RunChild(git_update_index, &ui_out, &ui_err, "",
+ this->RunChild(git_update_index, &ui_out, &ui_err, nullptr,
cmProcessOutput::UTF8);
// Use 'git diff-index' to get modified files.
- std::vector<std::string> git_diff_index = { git, "diff-index", "-z", "HEAD",
- "--" };
+ const char* git_diff_index[] = { git, "diff-index", "-z",
+ "HEAD", "--", nullptr };
DiffParser out(this, "di-out> ");
OutputLogger err(this->Log, "di-err> ");
- this->RunChild(git_diff_index, &out, &err, "", cmProcessOutput::UTF8);
+ this->RunChild(git_diff_index, &out, &err, nullptr, cmProcessOutput::UTF8);
for (Change const& c : out.Changes) {
this->DoModification(PathModified, c.Path);
diff --git a/Source/CTest/cmCTestHG.cxx b/Source/CTest/cmCTestHG.cxx
index e1a945d..02837ba 100644
--- a/Source/CTest/cmCTestHG.cxx
+++ b/Source/CTest/cmCTestHG.cxx
@@ -95,8 +95,8 @@ private:
std::string cmCTestHG::GetWorkingRevision()
{
// Run plumbing "hg identify" to get work tree revision.
- std::string hg = this->CommandLineTool;
- std::vector<std::string> hg_identify = { hg, "identify", "-i" };
+ const char* hg = this->CommandLineTool.c_str();
+ const char* hg_identify[] = { hg, "identify", "-i", nullptr };
std::string rev;
IdentifyParser out(this, "rev-out> ", rev);
OutputLogger err(this->Log, "rev-err> ");
@@ -127,16 +127,16 @@ bool cmCTestHG::UpdateImpl()
{
// Use "hg pull" followed by "hg update" to update the working tree.
{
- std::string hg = this->CommandLineTool;
- std::vector<std::string> hg_pull = { hg, "pull", "-v" };
+ const char* hg = this->CommandLineTool.c_str();
+ const char* hg_pull[] = { hg, "pull", "-v", nullptr };
OutputLogger out(this->Log, "pull-out> ");
OutputLogger err(this->Log, "pull-err> ");
- this->RunChild(hg_pull, &out, &err);
+ this->RunChild(&hg_pull[0], &out, &err);
}
// TODO: if(this->CTest->GetTestModel() == cmCTest::NIGHTLY)
- std::vector<std::string> hg_update;
+ std::vector<char const*> hg_update;
hg_update.push_back(this->CommandLineTool.c_str());
hg_update.push_back("update");
hg_update.push_back("-v");
@@ -147,11 +147,16 @@ bool cmCTestHG::UpdateImpl()
opts = this->CTest->GetCTestConfiguration("HGUpdateOptions");
}
std::vector<std::string> args = cmSystemTools::ParseArguments(opts);
- cm::append(hg_update, args);
+ for (std::string const& arg : args) {
+ hg_update.push_back(arg.c_str());
+ }
+
+ // Sentinel argument.
+ hg_update.push_back(nullptr);
OutputLogger out(this->Log, "update-out> ");
OutputLogger err(this->Log, "update-err> ");
- return this->RunUpdateCommand(hg_update, &out, &err);
+ return this->RunUpdateCommand(hg_update.data(), &out, &err);
}
class cmCTestHG::LogParser
@@ -272,8 +277,8 @@ bool cmCTestHG::LoadRevisions()
// the project has spaces in the path. Also, they may not have
// proper XML escapes.
std::string range = this->OldRevision + ":" + this->NewRevision;
- std::string hg = this->CommandLineTool;
- std::string hgXMLTemplate = "<logentry\n"
+ const char* hg = this->CommandLineTool.c_str();
+ const char* hgXMLTemplate = "<logentry\n"
" revision=\"{node|short}\">\n"
" <author>{author|person}</author>\n"
" <email>{author|email}</email>\n"
@@ -283,8 +288,10 @@ bool cmCTestHG::LoadRevisions()
" <file_adds>{file_adds}</file_adds>\n"
" <file_dels>{file_dels}</file_dels>\n"
"</logentry>\n";
- std::vector<std::string> hg_log = { hg, "log", "--removed", "-r",
- range, "--template", hgXMLTemplate };
+ const char* hg_log[] = {
+ hg, "log", "--removed", "-r", range.c_str(),
+ "--template", hgXMLTemplate, nullptr
+ };
LogParser out(this, "log-out> ");
out.Process("<?xml version=\"1.0\"?>\n"
@@ -298,8 +305,8 @@ bool cmCTestHG::LoadRevisions()
bool cmCTestHG::LoadModifications()
{
// Use 'hg status' to get modified files.
- std::string hg = this->CommandLineTool;
- std::vector<std::string> hg_status = { hg, "status" };
+ const char* hg = this->CommandLineTool.c_str();
+ const char* hg_status[] = { hg, "status", nullptr };
StatusParser out(this, "status-out> ");
OutputLogger err(this->Log, "status-err> ");
this->RunChild(hg_status, &out, &err);
diff --git a/Source/CTest/cmCTestLaunch.cxx b/Source/CTest/cmCTestLaunch.cxx
index 9669d76..4a33869 100644
--- a/Source/CTest/cmCTestLaunch.cxx
+++ b/Source/CTest/cmCTestLaunch.cxx
@@ -2,15 +2,11 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestLaunch.h"
-#include <cstdio>
#include <cstring>
#include <iostream>
-#include <memory>
-#include <utility>
-
-#include <cm3p/uv.h>
#include "cmsys/FStream.hxx"
+#include "cmsys/Process.h"
#include "cmsys/RegularExpression.hxx"
#include "cmCTestLaunchReporter.h"
@@ -21,9 +17,6 @@
#include "cmStateSnapshot.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-#include "cmUVHandlePtr.h"
-#include "cmUVProcessChain.h"
-#include "cmUVStream.h"
#include "cmake.h"
#ifdef _WIN32
@@ -35,6 +28,8 @@
cmCTestLaunch::cmCTestLaunch(int argc, const char* const* argv)
{
+ this->Process = nullptr;
+
if (!this->ParseArguments(argc, argv)) {
return;
}
@@ -45,9 +40,13 @@ cmCTestLaunch::cmCTestLaunch(int argc, const char* const* argv)
this->ScrapeRulesLoaded = false;
this->HaveOut = false;
this->HaveErr = false;
+ this->Process = cmsysProcess_New();
}
-cmCTestLaunch::~cmCTestLaunch() = default;
+cmCTestLaunch::~cmCTestLaunch()
+{
+ cmsysProcess_Delete(this->Process);
+}
bool cmCTestLaunch::ParseArguments(int argc, const char* const* argv)
{
@@ -114,12 +113,15 @@ bool cmCTestLaunch::ParseArguments(int argc, const char* const* argv)
// Extract the real command line.
if (arg0) {
- for (int i = 0; i < argc - arg0; ++i) {
- this->RealArgV.emplace_back((argv + arg0)[i]);
- this->HandleRealArg((argv + arg0)[i]);
+ this->RealArgC = argc - arg0;
+ this->RealArgV = argv + arg0;
+ for (int i = 0; i < this->RealArgC; ++i) {
+ this->HandleRealArg(this->RealArgV[i]);
}
return true;
}
+ this->RealArgC = 0;
+ this->RealArgV = nullptr;
std::cerr << "No launch/command separator ('--') found!\n";
return false;
}
@@ -149,19 +151,17 @@ void cmCTestLaunch::RunChild()
}
// Prepare to run the real command.
- cmUVProcessChainBuilder builder;
- builder.AddCommand(this->RealArgV);
+ cmsysProcess* cp = this->Process;
+ cmsysProcess_SetCommand(cp, this->RealArgV);
cmsys::ofstream fout;
cmsys::ofstream ferr;
if (this->Reporter.Passthru) {
// In passthru mode we just share the output pipes.
- builder.SetExternalStream(cmUVProcessChainBuilder::Stream_OUTPUT, stdout)
- .SetExternalStream(cmUVProcessChainBuilder::Stream_ERROR, stderr);
+ cmsysProcess_SetPipeShared(cp, cmsysProcess_Pipe_STDOUT, 1);
+ cmsysProcess_SetPipeShared(cp, cmsysProcess_Pipe_STDERR, 1);
} else {
// In full mode we record the child output pipes to log files.
- builder.SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT)
- .SetBuiltinStream(cmUVProcessChainBuilder::Stream_ERROR);
fout.open(this->Reporter.LogOut.c_str(), std::ios::out | std::ios::binary);
ferr.open(this->Reporter.LogErr.c_str(), std::ios::out | std::ios::binary);
}
@@ -174,65 +174,51 @@ void cmCTestLaunch::RunChild()
#endif
// Run the real command.
- auto chain = builder.Start();
+ cmsysProcess_Execute(cp);
// Record child stdout and stderr if necessary.
- cm::uv_pipe_ptr outPipe;
- cm::uv_pipe_ptr errPipe;
- bool outFinished = true;
- bool errFinished = true;
- cmProcessOutput processOutput;
- std::unique_ptr<cmUVStreamReadHandle> outputHandle;
- std::unique_ptr<cmUVStreamReadHandle> errorHandle;
if (!this->Reporter.Passthru) {
- auto beginRead = [&chain, &processOutput](
- cm::uv_pipe_ptr& pipe, int stream, std::ostream& out,
- cmsys::ofstream& file, bool& haveData, bool& finished,
- int id) -> std::unique_ptr<cmUVStreamReadHandle> {
- pipe.init(chain.GetLoop(), 0);
- uv_pipe_open(pipe, stream);
- finished = false;
- return cmUVStreamRead(
- pipe,
- [&processOutput, &out, &file, id, &haveData](std::vector<char> data) {
- std::string strdata;
- processOutput.DecodeText(data.data(), data.size(), strdata, id);
- file.write(strdata.c_str(), strdata.size());
- out.write(strdata.c_str(), strdata.size());
- haveData = true;
- },
- [&processOutput, &out, &file, &finished, id]() {
- std::string strdata;
- processOutput.DecodeText(std::string(), strdata, id);
- if (!strdata.empty()) {
- file.write(strdata.c_str(), strdata.size());
- out.write(strdata.c_str(), strdata.size());
- }
- finished = true;
- });
- };
- outputHandle = beginRead(outPipe, chain.OutputStream(), std::cout, fout,
- this->HaveOut, outFinished, 1);
- errorHandle = beginRead(errPipe, chain.ErrorStream(), std::cerr, ferr,
- this->HaveErr, errFinished, 2);
+ char* data = nullptr;
+ int length = 0;
+ cmProcessOutput processOutput;
+ std::string strdata;
+ while (int p = cmsysProcess_WaitForData(cp, &data, &length, nullptr)) {
+ if (p == cmsysProcess_Pipe_STDOUT) {
+ processOutput.DecodeText(data, length, strdata, 1);
+ fout.write(strdata.c_str(), strdata.size());
+ std::cout.write(strdata.c_str(), strdata.size());
+ this->HaveOut = true;
+ } else if (p == cmsysProcess_Pipe_STDERR) {
+ processOutput.DecodeText(data, length, strdata, 2);
+ ferr.write(strdata.c_str(), strdata.size());
+ std::cerr.write(strdata.c_str(), strdata.size());
+ this->HaveErr = true;
+ }
+ }
+ processOutput.DecodeText(std::string(), strdata, 1);
+ if (!strdata.empty()) {
+ fout.write(strdata.c_str(), strdata.size());
+ std::cout.write(strdata.c_str(), strdata.size());
+ }
+ processOutput.DecodeText(std::string(), strdata, 2);
+ if (!strdata.empty()) {
+ ferr.write(strdata.c_str(), strdata.size());
+ std::cerr.write(strdata.c_str(), strdata.size());
+ }
}
// Wait for the real command to finish.
- while (!(chain.Finished() && outFinished && errFinished)) {
- uv_run(&chain.GetLoop(), UV_RUN_ONCE);
- }
- this->Reporter.Status = chain.GetStatus(0);
- if (this->Reporter.Status.GetException().first ==
- cmUVProcessChain::ExceptionCode::Spawn) {
- this->Reporter.ExitCode = 1;
- } else {
- this->Reporter.ExitCode =
- static_cast<int>(this->Reporter.Status.ExitStatus);
- }
+ cmsysProcess_WaitForExit(cp, nullptr);
+ this->Reporter.ExitCode = cmsysProcess_GetExitValue(cp);
}
int cmCTestLaunch::Run()
{
+ if (!this->Process) {
+ std::cerr << "Could not allocate cmsysProcess instance!\n";
+ return -1;
+ }
+
this->RunChild();
if (this->CheckResults()) {
@@ -240,6 +226,7 @@ int cmCTestLaunch::Run()
}
this->LoadConfig();
+ this->Reporter.Process = this->Process;
this->Reporter.WriteXML();
return this->Reporter.ExitCode;
diff --git a/Source/CTest/cmCTestLaunch.h b/Source/CTest/cmCTestLaunch.h
index ef21a26..c5a6476 100644
--- a/Source/CTest/cmCTestLaunch.h
+++ b/Source/CTest/cmCTestLaunch.h
@@ -43,12 +43,15 @@ private:
bool ParseArguments(int argc, const char* const* argv);
// The real command line appearing after launcher arguments.
- std::vector<std::string> RealArgV;
+ int RealArgC;
+ const char* const* RealArgV;
// The real command line after response file expansion.
std::vector<std::string> RealArgs;
void HandleRealArg(const char* arg);
+ struct cmsysProcess_s* Process;
+
// Whether or not any data have been written to stdout or stderr.
bool HaveOut;
bool HaveErr;
diff --git a/Source/CTest/cmCTestLaunchReporter.cxx b/Source/CTest/cmCTestLaunchReporter.cxx
index 4b4e5c5..149ba5d 100644
--- a/Source/CTest/cmCTestLaunchReporter.cxx
+++ b/Source/CTest/cmCTestLaunchReporter.cxx
@@ -2,9 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestLaunchReporter.h"
-#include <utility>
-
#include "cmsys/FStream.hxx"
+#include "cmsys/Process.h"
#include "cmsys/RegularExpression.hxx"
#include "cmCryptoHash.h"
@@ -23,7 +22,6 @@
cmCTestLaunchReporter::cmCTestLaunchReporter()
{
this->Passthru = true;
- this->Status.Finished = true;
this->ExitCode = 1;
this->CWD = cmSystemTools::GetCurrentWorkingDirectory();
@@ -233,23 +231,35 @@ void cmCTestLaunchReporter::WriteXMLResult(cmXMLElement& e2)
// ExitCondition
cmXMLElement e4(e3, "ExitCondition");
- if (this->Status.Finished) {
- auto exception = this->Status.GetException();
- switch (exception.first) {
- case cmUVProcessChain::ExceptionCode::None:
- e4.Content(this->ExitCode);
- break;
- case cmUVProcessChain::ExceptionCode::Spawn:
- e4.Content("Error administrating child process: ");
- e4.Content(exception.second);
- break;
- default:
- e4.Content("Terminated abnormally: ");
- e4.Content(exception.second);
- break;
- }
- } else {
- e4.Content("Killed when timeout expired");
+ cmsysProcess* cp = this->Process;
+ switch (cmsysProcess_GetState(cp)) {
+ case cmsysProcess_State_Starting:
+ e4.Content("No process has been executed");
+ break;
+ case cmsysProcess_State_Executing:
+ e4.Content("The process is still executing");
+ break;
+ case cmsysProcess_State_Disowned:
+ e4.Content("Disowned");
+ break;
+ case cmsysProcess_State_Killed:
+ e4.Content("Killed by parent");
+ break;
+
+ case cmsysProcess_State_Expired:
+ e4.Content("Killed when timeout expired");
+ break;
+ case cmsysProcess_State_Exited:
+ e4.Content(this->ExitCode);
+ break;
+ case cmsysProcess_State_Exception:
+ e4.Content("Terminated abnormally: ");
+ e4.Content(cmsysProcess_GetExceptionString(cp));
+ break;
+ case cmsysProcess_State_Error:
+ e4.Content("Error administrating child process: ");
+ e4.Content(cmsysProcess_GetErrorString(cp));
+ break;
}
}
diff --git a/Source/CTest/cmCTestLaunchReporter.h b/Source/CTest/cmCTestLaunchReporter.h
index 2bb78f8..4be0d9b 100644
--- a/Source/CTest/cmCTestLaunchReporter.h
+++ b/Source/CTest/cmCTestLaunchReporter.h
@@ -10,8 +10,6 @@
#include "cmsys/RegularExpression.hxx"
-#include "cmUVProcessChain.h"
-
class cmXMLElement;
/** \class cmCTestLaunchReporter
@@ -50,7 +48,7 @@ public:
void ComputeFileNames();
bool Passthru;
- cmUVProcessChain::Status Status;
+ struct cmsysProcess_s* Process;
int ExitCode;
// Temporary log files for stdout and stderr of real command.
diff --git a/Source/CTest/cmCTestP4.cxx b/Source/CTest/cmCTestP4.cxx
index 5d71b84..0e002b9 100644
--- a/Source/CTest/cmCTestP4.cxx
+++ b/Source/CTest/cmCTestP4.cxx
@@ -149,16 +149,17 @@ cmCTestP4::User cmCTestP4::GetUserData(const std::string& username)
auto it = this->Users.find(username);
if (it == this->Users.end()) {
- std::vector<std::string> p4_users;
+ std::vector<char const*> p4_users;
this->SetP4Options(p4_users);
p4_users.push_back("users");
p4_users.push_back("-m");
p4_users.push_back("1");
- p4_users.push_back(username);
+ p4_users.push_back(username.c_str());
+ p4_users.push_back(nullptr);
UserParser out(this, "users-out> ");
OutputLogger err(this->Log, "users-err> ");
- this->RunChild(p4_users, &out, &err);
+ this->RunChild(p4_users.data(), &out, &err);
// The user should now be added to the map. Search again.
it = this->Users.find(username);
@@ -302,10 +303,10 @@ private:
}
};
-void cmCTestP4::SetP4Options(std::vector<std::string>& CommandOptions)
+void cmCTestP4::SetP4Options(std::vector<char const*>& CommandOptions)
{
if (this->P4Options.empty()) {
- std::string p4 = this->CommandLineTool;
+ const char* p4 = this->CommandLineTool.c_str();
this->P4Options.emplace_back(p4);
// The CTEST_P4_CLIENT variable sets the P4 client used when issuing
@@ -327,12 +328,15 @@ void cmCTestP4::SetP4Options(std::vector<std::string>& CommandOptions)
cm::append(this->P4Options, cmSystemTools::ParseArguments(opts));
}
- CommandOptions = this->P4Options;
+ CommandOptions.clear();
+ for (std::string const& o : this->P4Options) {
+ CommandOptions.push_back(o.c_str());
+ }
}
std::string cmCTestP4::GetWorkingRevision()
{
- std::vector<std::string> p4_identify;
+ std::vector<char const*> p4_identify;
this->SetP4Options(p4_identify);
p4_identify.push_back("changes");
@@ -341,13 +345,14 @@ std::string cmCTestP4::GetWorkingRevision()
p4_identify.push_back("-t");
std::string source = this->SourceDirectory + "/...#have";
- p4_identify.push_back(source);
+ p4_identify.push_back(source.c_str());
+ p4_identify.push_back(nullptr);
std::string rev;
IdentifyParser out(this, "p4_changes-out> ", rev);
OutputLogger err(this->Log, "p4_changes-err> ");
- bool result = this->RunChild(p4_identify, &out, &err);
+ bool result = this->RunChild(p4_identify.data(), &out, &err);
// If there was a problem contacting the server return "<unknown>"
if (!result) {
@@ -383,7 +388,7 @@ bool cmCTestP4::NoteNewRevision()
bool cmCTestP4::LoadRevisions()
{
- std::vector<std::string> p4_changes;
+ std::vector<char const*> p4_changes;
this->SetP4Options(p4_changes);
// Use 'p4 changes ...@old,new' to get a list of changelists
@@ -404,36 +409,38 @@ bool cmCTestP4::LoadRevisions()
.append(this->NewRevision);
p4_changes.push_back("changes");
- p4_changes.push_back(range);
+ p4_changes.push_back(range.c_str());
+ p4_changes.push_back(nullptr);
ChangesParser out(this, "p4_changes-out> ");
OutputLogger err(this->Log, "p4_changes-err> ");
this->ChangeLists.clear();
- this->RunChild(p4_changes, &out, &err);
+ this->RunChild(p4_changes.data(), &out, &err);
if (this->ChangeLists.empty()) {
return true;
}
// p4 describe -s ...@1111111,2222222
- std::vector<std::string> p4_describe;
+ std::vector<char const*> p4_describe;
for (std::string const& i : cmReverseRange(this->ChangeLists)) {
this->SetP4Options(p4_describe);
p4_describe.push_back("describe");
p4_describe.push_back("-s");
- p4_describe.push_back(i);
+ p4_describe.push_back(i.c_str());
+ p4_describe.push_back(nullptr);
DescribeParser outDescribe(this, "p4_describe-out> ");
OutputLogger errDescribe(this->Log, "p4_describe-err> ");
- this->RunChild(p4_describe, &outDescribe, &errDescribe);
+ this->RunChild(p4_describe.data(), &outDescribe, &errDescribe);
}
return true;
}
bool cmCTestP4::LoadModifications()
{
- std::vector<std::string> p4_diff;
+ std::vector<char const*> p4_diff;
this->SetP4Options(p4_diff);
p4_diff.push_back("diff");
@@ -441,11 +448,12 @@ bool cmCTestP4::LoadModifications()
// Ideally we would use -Od but not all clients support it
p4_diff.push_back("-dn");
std::string source = this->SourceDirectory + "/...";
- p4_diff.push_back(source);
+ p4_diff.push_back(source.c_str());
+ p4_diff.push_back(nullptr);
DiffParser out(this, "p4_diff-out> ");
OutputLogger err(this->Log, "p4_diff-err> ");
- this->RunChild(p4_diff, &out, &err);
+ this->RunChild(p4_diff.data(), &out, &err);
return true;
}
@@ -453,14 +461,17 @@ bool cmCTestP4::UpdateCustom(const std::string& custom)
{
cmList p4_custom_command{ custom, cmList::EmptyElements::Yes };
- std::vector<std::string> p4_custom;
- p4_custom.reserve(p4_custom_command.size());
- cm::append(p4_custom, p4_custom_command);
+ std::vector<char const*> p4_custom;
+ p4_custom.reserve(p4_custom_command.size() + 1);
+ for (std::string const& i : p4_custom_command) {
+ p4_custom.push_back(i.c_str());
+ }
+ p4_custom.push_back(nullptr);
OutputLogger custom_out(this->Log, "p4_customsync-out> ");
OutputLogger custom_err(this->Log, "p4_customsync-err> ");
- return this->RunUpdateCommand(p4_custom, &custom_out, &custom_err);
+ return this->RunUpdateCommand(p4_custom.data(), &custom_out, &custom_err);
}
bool cmCTestP4::UpdateImpl()
@@ -477,7 +488,7 @@ bool cmCTestP4::UpdateImpl()
return false;
}
- std::vector<std::string> p4_sync;
+ std::vector<char const*> p4_sync;
this->SetP4Options(p4_sync);
p4_sync.push_back("sync");
@@ -488,7 +499,9 @@ bool cmCTestP4::UpdateImpl()
opts = this->CTest->GetCTestConfiguration("P4UpdateOptions");
}
std::vector<std::string> args = cmSystemTools::ParseArguments(opts);
- cm::append(p4_sync, args);
+ for (std::string const& arg : args) {
+ p4_sync.push_back(arg.c_str());
+ }
std::string source = this->SourceDirectory + "/...";
@@ -502,10 +515,11 @@ bool cmCTestP4::UpdateImpl()
source.append("@\"").append(date).append("\"");
}
- p4_sync.push_back(source);
+ p4_sync.push_back(source.c_str());
+ p4_sync.push_back(nullptr);
OutputLogger out(this->Log, "p4_sync-out> ");
OutputLogger err(this->Log, "p4_sync-err> ");
- return this->RunUpdateCommand(p4_sync, &out, &err);
+ return this->RunUpdateCommand(p4_sync.data(), &out, &err);
}
diff --git a/Source/CTest/cmCTestP4.h b/Source/CTest/cmCTestP4.h
index 827caa1..1889520 100644
--- a/Source/CTest/cmCTestP4.h
+++ b/Source/CTest/cmCTestP4.h
@@ -39,7 +39,7 @@ private:
std::vector<std::string> P4Options;
User GetUserData(const std::string& username);
- void SetP4Options(std::vector<std::string>& options);
+ void SetP4Options(std::vector<char const*>& options);
std::string GetWorkingRevision();
bool NoteOldRevision() override;
diff --git a/Source/CTest/cmCTestSVN.cxx b/Source/CTest/cmCTestSVN.cxx
index 14bc510..91a1177 100644
--- a/Source/CTest/cmCTestSVN.cxx
+++ b/Source/CTest/cmCTestSVN.cxx
@@ -33,7 +33,7 @@ cmCTestSVN::~cmCTestSVN() = default;
void cmCTestSVN::CleanupImpl()
{
- std::vector<std::string> svn_cleanup;
+ std::vector<const char*> svn_cleanup;
svn_cleanup.push_back("cleanup");
OutputLogger out(this->Log, "cleanup-out> ");
OutputLogger err(this->Log, "cleanup-err> ");
@@ -88,9 +88,9 @@ static bool cmCTestSVNPathStarts(std::string const& p1, std::string const& p2)
std::string cmCTestSVN::LoadInfo(SVNInfo& svninfo)
{
// Run "svn info" to get the repository info from the work tree.
- std::vector<std::string> svn_info;
+ std::vector<const char*> svn_info;
svn_info.push_back("info");
- svn_info.push_back(svninfo.LocalPath);
+ svn_info.push_back(svninfo.LocalPath.c_str());
std::string rev;
InfoParser out(this, "info-out> ", rev, svninfo);
OutputLogger err(this->Log, "info-err> ");
@@ -251,24 +251,26 @@ bool cmCTestSVN::UpdateImpl()
args.push_back("-r{" + this->GetNightlyTime() + " +0000}");
}
- std::vector<std::string> svn_update;
+ std::vector<char const*> svn_update;
svn_update.push_back("update");
- cm::append(svn_update, args);
+ for (std::string const& arg : args) {
+ svn_update.push_back(arg.c_str());
+ }
UpdateParser out(this, "up-out> ");
OutputLogger err(this->Log, "up-err> ");
return this->RunSVNCommand(svn_update, &out, &err);
}
-bool cmCTestSVN::RunSVNCommand(std::vector<std::string> const& parameters,
+bool cmCTestSVN::RunSVNCommand(std::vector<char const*> const& parameters,
OutputParser* out, OutputParser* err)
{
if (parameters.empty()) {
return false;
}
- std::vector<std::string> args;
- args.push_back(this->CommandLineTool);
+ std::vector<char const*> args;
+ args.push_back(this->CommandLineTool.c_str());
cm::append(args, parameters);
args.push_back("--non-interactive");
@@ -276,12 +278,16 @@ bool cmCTestSVN::RunSVNCommand(std::vector<std::string> const& parameters,
std::vector<std::string> parsedUserOptions =
cmSystemTools::ParseArguments(userOptions);
- cm::append(args, parsedUserOptions);
+ for (std::string const& opt : parsedUserOptions) {
+ args.push_back(opt.c_str());
+ }
+
+ args.push_back(nullptr);
- if (parameters[0] == "update") {
- return this->RunUpdateCommand(args, out, err);
+ if (strcmp(parameters[0], "update") == 0) {
+ return this->RunUpdateCommand(args.data(), out, err);
}
- return this->RunChild(args, out, err);
+ return this->RunChild(args.data(), out, err);
}
class cmCTestSVN::LogParser
@@ -387,7 +393,7 @@ bool cmCTestSVN::LoadRevisions(SVNInfo& svninfo)
}
// Run "svn log" to get all global revisions of interest.
- std::vector<std::string> svn_log;
+ std::vector<const char*> svn_log;
svn_log.push_back("log");
svn_log.push_back("--xml");
svn_log.push_back("-v");
@@ -466,7 +472,7 @@ private:
bool cmCTestSVN::LoadModifications()
{
// Run "svn status" which reports local modifications.
- std::vector<std::string> svn_status;
+ std::vector<const char*> svn_status;
svn_status.push_back("status");
StatusParser out(this, "status-out> ");
OutputLogger err(this->Log, "status-err> ");
@@ -528,7 +534,7 @@ bool cmCTestSVN::LoadRepositories()
this->RootInfo = &(this->Repositories.back());
// Run "svn status" to get the list of external repositories
- std::vector<std::string> svn_status;
+ std::vector<const char*> svn_status;
svn_status.push_back("status");
ExternalParser out(this, "external-out> ");
OutputLogger err(this->Log, "external-err> ");
diff --git a/Source/CTest/cmCTestSVN.h b/Source/CTest/cmCTestSVN.h
index 1485dc0..370d176 100644
--- a/Source/CTest/cmCTestSVN.h
+++ b/Source/CTest/cmCTestSVN.h
@@ -33,7 +33,7 @@ private:
bool NoteNewRevision() override;
bool UpdateImpl() override;
- bool RunSVNCommand(std::vector<std::string> const& parameters,
+ bool RunSVNCommand(std::vector<char const*> const& parameters,
OutputParser* out, OutputParser* err);
// Information about an SVN repository (root repository or external)
diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx
index 48f8f6d..461ad1a 100644
--- a/Source/CTest/cmCTestScriptHandler.cxx
+++ b/Source/CTest/cmCTestScriptHandler.cxx
@@ -11,9 +11,8 @@
#include <cm/memory>
-#include <cm3p/uv.h>
-
#include "cmsys/Directory.hxx"
+#include "cmsys/Process.h"
#include "cmCTest.h"
#include "cmCTestBuildCommand.h"
@@ -41,8 +40,6 @@
#include "cmStateSnapshot.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-#include "cmUVHandlePtr.h"
-#include "cmUVProcessChain.h"
#include "cmValue.h"
#include "cmake.h"
@@ -151,65 +148,66 @@ int cmCTestScriptHandler::ExecuteScript(const std::string& total_script_arg)
// now pass through all the other arguments
std::vector<std::string>& initArgs =
this->CTest->GetInitialCommandLineArguments();
+ //*** need to make sure this does not have the current script ***
+ for (size_t i = 1; i < initArgs.size(); ++i) {
+ argv.push_back(initArgs[i].c_str());
+ }
+ argv.push_back(nullptr);
// Now create process object
- cmUVProcessChainBuilder builder;
- builder.AddCommand(initArgs)
- .SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT)
- .SetBuiltinStream(cmUVProcessChainBuilder::Stream_ERROR);
- auto process = builder.Start();
- cm::uv_pipe_ptr outPipe;
- outPipe.init(process.GetLoop(), 0);
- uv_pipe_open(outPipe, process.OutputStream());
- cm::uv_pipe_ptr errPipe;
- errPipe.init(process.GetLoop(), 0);
- uv_pipe_open(errPipe, process.ErrorStream());
+ cmsysProcess* cp = cmsysProcess_New();
+ cmsysProcess_SetCommand(cp, argv.data());
+ // cmsysProcess_SetWorkingDirectory(cp, dir);
+ cmsysProcess_SetOption(cp, cmsysProcess_Option_HideWindow, 1);
+ // cmsysProcess_SetTimeout(cp, timeout);
+ cmsysProcess_Execute(cp);
std::vector<char> out;
std::vector<char> err;
std::string line;
- auto pipe =
- cmSystemTools::WaitForLine(&process.GetLoop(), outPipe, errPipe, line,
- std::chrono::seconds(100), out, err);
- while (pipe != cmSystemTools::WaitForLineResult::None) {
+ int pipe =
+ cmSystemTools::WaitForLine(cp, line, std::chrono::seconds(100), out, err);
+ while (pipe != cmsysProcess_Pipe_None) {
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"Output: " << line << "\n");
- if (pipe == cmSystemTools::WaitForLineResult::STDERR) {
+ if (pipe == cmsysProcess_Pipe_STDERR) {
cmCTestLog(this->CTest, ERROR_MESSAGE, line << "\n");
- } else if (pipe == cmSystemTools::WaitForLineResult::STDOUT) {
+ } else if (pipe == cmsysProcess_Pipe_STDOUT) {
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, line << "\n");
}
- pipe =
- cmSystemTools::WaitForLine(&process.GetLoop(), outPipe, errPipe, line,
- std::chrono::seconds(100), out, err);
+ pipe = cmSystemTools::WaitForLine(cp, line, std::chrono::seconds(100), out,
+ err);
}
// Properly handle output of the build command
- process.Wait();
- auto const& status = process.GetStatus(0);
- auto result = status.GetException();
+ cmsysProcess_WaitForExit(cp, nullptr);
+ int result = cmsysProcess_GetState(cp);
int retVal = 0;
bool failed = false;
- switch (result.first) {
- case cmUVProcessChain::ExceptionCode::None:
- retVal = static_cast<int>(status.ExitStatus);
- break;
- case cmUVProcessChain::ExceptionCode::Spawn:
- cmCTestLog(this->CTest, ERROR_MESSAGE,
- "\tError executing ctest: " << result.second << std::endl);
- failed = true;
- break;
- default:
- retVal = status.TermSignal;
- cmCTestLog(this->CTest, ERROR_MESSAGE,
- "\tThere was an exception: " << result.second << " " << retVal
- << std::endl);
- failed = true;
+ if (result == cmsysProcess_State_Exited) {
+ retVal = cmsysProcess_GetExitValue(cp);
+ } else if (result == cmsysProcess_State_Exception) {
+ retVal = cmsysProcess_GetExitException(cp);
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "\tThere was an exception: "
+ << cmsysProcess_GetExceptionString(cp) << " " << retVal
+ << std::endl);
+ failed = true;
+ } else if (result == cmsysProcess_State_Expired) {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "\tThere was a timeout" << std::endl);
+ failed = true;
+ } else if (result == cmsysProcess_State_Error) {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "\tError executing ctest: " << cmsysProcess_GetErrorString(cp)
+ << std::endl);
+ failed = true;
}
+ cmsysProcess_Delete(cp);
if (failed) {
std::ostringstream message;
message << "Error running command: [";
- message << static_cast<int>(result.first) << "] ";
+ message << result << "] ";
for (const char* arg : argv) {
if (arg) {
message << arg << " ";
diff --git a/Source/CTest/cmCTestVC.cxx b/Source/CTest/cmCTestVC.cxx
index cbbb5a5..609ccba 100644
--- a/Source/CTest/cmCTestVC.cxx
+++ b/Source/CTest/cmCTestVC.cxx
@@ -7,9 +7,10 @@
#include <sstream>
#include <vector>
+#include "cmsys/Process.h"
+
#include "cmCTest.h"
#include "cmSystemTools.h"
-#include "cmUVProcessChain.h"
#include "cmValue.h"
#include "cmXMLWriter.h"
@@ -54,12 +55,18 @@ bool cmCTestVC::InitialCheckout(const std::string& command)
// Construct the initial checkout command line.
std::vector<std::string> args = cmSystemTools::ParseArguments(command);
+ std::vector<char const*> vc_co;
+ vc_co.reserve(args.size() + 1);
+ for (std::string const& arg : args) {
+ vc_co.push_back(arg.c_str());
+ }
+ vc_co.push_back(nullptr);
// Run the initial checkout command and log its output.
this->Log << "--- Begin Initial Checkout ---\n";
OutputLogger out(this->Log, "co-out> ");
OutputLogger err(this->Log, "co-err> ");
- bool result = this->RunChild(args, &out, &err, parent);
+ bool result = this->RunChild(vc_co.data(), &out, &err, parent.c_str());
this->Log << "--- End Initial Checkout ---\n";
if (!result) {
cmCTestLog(this->CTest, ERROR_MESSAGE,
@@ -68,35 +75,35 @@ bool cmCTestVC::InitialCheckout(const std::string& command)
return result;
}
-bool cmCTestVC::RunChild(const std::vector<std::string>& cmd,
- OutputParser* out, OutputParser* err,
- std::string workDir, Encoding encoding)
+bool cmCTestVC::RunChild(char const* const* cmd, OutputParser* out,
+ OutputParser* err, const char* workDir,
+ Encoding encoding)
{
this->Log << cmCTestVC::ComputeCommandLine(cmd) << "\n";
- cmUVProcessChainBuilder builder;
- if (workDir.empty()) {
- workDir = this->SourceDirectory;
- }
- builder.AddCommand(cmd).SetWorkingDirectory(workDir);
- auto status = cmCTestVC::RunProcess(builder, out, err, encoding);
- return status.front().SpawnResult == 0 && status.front().ExitStatus == 0;
+ cmsysProcess* cp = cmsysProcess_New();
+ cmsysProcess_SetCommand(cp, cmd);
+ workDir = workDir ? workDir : this->SourceDirectory.c_str();
+ cmsysProcess_SetWorkingDirectory(cp, workDir);
+ cmCTestVC::RunProcess(cp, out, err, encoding);
+ int result = cmsysProcess_GetExitValue(cp);
+ cmsysProcess_Delete(cp);
+ return result == 0;
}
-std::string cmCTestVC::ComputeCommandLine(const std::vector<std::string>& cmd)
+std::string cmCTestVC::ComputeCommandLine(char const* const* cmd)
{
std::ostringstream line;
const char* sep = "";
- for (auto const& arg : cmd) {
- line << sep << "\"" << arg << "\"";
+ for (const char* const* arg = cmd; *arg; ++arg) {
+ line << sep << "\"" << *arg << "\"";
sep = " ";
}
return line.str();
}
-bool cmCTestVC::RunUpdateCommand(const std::vector<std::string>& cmd,
- OutputParser* out, OutputParser* err,
- Encoding encoding)
+bool cmCTestVC::RunUpdateCommand(char const* const* cmd, OutputParser* out,
+ OutputParser* err, Encoding encoding)
{
// Report the command line.
this->UpdateCommandLine = this->ComputeCommandLine(cmd);
@@ -106,7 +113,7 @@ bool cmCTestVC::RunUpdateCommand(const std::vector<std::string>& cmd,
}
// Run the command.
- return this->RunChild(cmd, out, err, "", encoding);
+ return this->RunChild(cmd, out, err, nullptr, encoding);
}
std::string cmCTestVC::GetNightlyTime()
diff --git a/Source/CTest/cmCTestVC.h b/Source/CTest/cmCTestVC.h
index dd5456d..7b03d10 100644
--- a/Source/CTest/cmCTestVC.h
+++ b/Source/CTest/cmCTestVC.h
@@ -6,7 +6,6 @@
#include <iosfwd>
#include <string>
-#include <vector>
#include "cmProcessOutput.h"
#include "cmProcessTools.h"
@@ -109,15 +108,15 @@ protected:
};
/** Convert a list of arguments to a human-readable command line. */
- static std::string ComputeCommandLine(const std::vector<std::string>& cmd);
+ static std::string ComputeCommandLine(char const* const* cmd);
/** Run a command line and send output to given parsers. */
- bool RunChild(const std::vector<std::string>& cmd, OutputParser* out,
- OutputParser* err, std::string workDir = {},
+ bool RunChild(char const* const* cmd, OutputParser* out, OutputParser* err,
+ const char* workDir = nullptr,
Encoding encoding = cmProcessOutput::Auto);
/** Run VC update command line and send output to given parsers. */
- bool RunUpdateCommand(const std::vector<std::string>& cmd, OutputParser* out,
+ bool RunUpdateCommand(char const* const* cmd, OutputParser* out,
OutputParser* err = nullptr,
Encoding encoding = cmProcessOutput::Auto);