summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Source/CTest/cmCTestBZR.cxx31
-rw-r--r--Source/CTest/cmCTestCVS.cxx18
-rw-r--r--Source/CTest/cmCTestGIT.cxx130
-rw-r--r--Source/CTest/cmCTestHG.cxx35
-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/cmCTestVC.cxx45
-rw-r--r--Source/CTest/cmCTestVC.h9
-rw-r--r--Source/cmProcessTools.cxx82
-rw-r--r--Source/cmProcessTools.h8
-rw-r--r--Source/cmcmd.cxx33
13 files changed, 233 insertions, 264 deletions
diff --git a/Source/CTest/cmCTestBZR.cxx b/Source/CTest/cmCTestBZR.cxx
index 246e811..36df344 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.
- const char* bzr = this->CommandLineTool.c_str();
- const char* bzr_info[] = { bzr, "info", nullptr };
+ std::string bzr = this->CommandLineTool;
+ std::vector<std::string> bzr_info = { bzr, "info" };
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.
- const char* bzr_revno[] = { bzr, "revno", nullptr };
+ std::vector<std::string> bzr_revno = { bzr, "revno" };
std::string rev;
RevnoParser rout(this, "revno-out> ", rev);
OutputLogger rerr(this->Log, "revno-err> ");
@@ -372,22 +372,18 @@ bool cmCTestBZR::UpdateImpl()
// TODO: if(this->CTest->GetTestModel() == cmCTest::NIGHTLY)
// Use "bzr pull" to update the working tree.
- std::vector<char const*> bzr_update;
- bzr_update.push_back(this->CommandLineTool.c_str());
+ std::vector<std::string> bzr_update;
+ bzr_update.push_back(this->CommandLineTool);
bzr_update.push_back("pull");
- for (std::string const& arg : args) {
- bzr_update.push_back(arg.c_str());
- }
-
- bzr_update.push_back(this->URL.c_str());
+ cm::append(bzr_update, args);
- bzr_update.push_back(nullptr);
+ bzr_update.push_back(this->URL);
// 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.data(), &out, &err);
+ return this->RunUpdateCommand(bzr_update, &out, &err);
}
bool cmCTestBZR::LoadRevisions()
@@ -408,10 +404,9 @@ bool cmCTestBZR::LoadRevisions()
}
// Run "bzr log" to get all global revisions of interest.
- const char* bzr = this->CommandLineTool.c_str();
- const char* bzr_log[] = {
- bzr, "log", "-v", "-r", revs.c_str(), "--xml", this->URL.c_str(), nullptr
- };
+ std::string bzr = this->CommandLineTool;
+ std::vector<std::string> bzr_log = { bzr, "log", "-v", "-r",
+ revs, "--xml", this->URL };
{
LogParser out(this, "log-out> ");
OutputLogger err(this->Log, "log-err> ");
@@ -467,8 +462,8 @@ private:
bool cmCTestBZR::LoadModifications()
{
// Run "bzr status" which reports local modifications.
- const char* bzr = this->CommandLineTool.c_str();
- const char* bzr_status[] = { bzr, "status", "-SV", nullptr };
+ std::string bzr = this->CommandLineTool;
+ std::vector<std::string> bzr_status = { bzr, "status", "-SV" };
StatusParser out(this, "status-out> ");
OutputLogger err(this->Log, "status-err> ");
this->RunChild(bzr_status, &out, &err);
diff --git a/Source/CTest/cmCTestCVS.cxx b/Source/CTest/cmCTestCVS.cxx
index 95e898c..ef95b25 100644
--- a/Source/CTest/cmCTestCVS.cxx
+++ b/Source/CTest/cmCTestCVS.cxx
@@ -5,6 +5,7 @@
#include <utility>
#include <cm/string_view>
+#include <cmext/algorithm>
#include "cmsys/FStream.hxx"
#include "cmsys/RegularExpression.hxx"
@@ -89,18 +90,15 @@ bool cmCTestCVS::UpdateImpl()
}
// Run "cvs update" to update the work tree.
- std::vector<char const*> cvs_update;
- cvs_update.push_back(this->CommandLineTool.c_str());
+ std::vector<std::string> cvs_update;
+ cvs_update.push_back(this->CommandLineTool);
cvs_update.push_back("-z3");
cvs_update.push_back("update");
- for (std::string const& arg : args) {
- cvs_update.push_back(arg.c_str());
- }
- cvs_update.push_back(nullptr);
+ cm::append(cvs_update, args);
UpdateParser out(this, "up-out> ");
UpdateParser err(this, "up-err> ");
- return this->RunUpdateCommand(cvs_update.data(), &out, &err);
+ return this->RunUpdateCommand(cvs_update, &out, &err);
}
class cmCTestCVS::LogParser : public cmCTestVC::LineParser
@@ -221,10 +219,8 @@ 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.
- const char* cvs = this->CommandLineTool.c_str();
- const char* cvs_log[] = {
- cvs, "log", "-N", branchFlag, file.c_str(), nullptr
- };
+ std::string cvs = this->CommandLineTool;
+ std::vector<std::string> cvs_log = { cvs, "log", "-N", branchFlag, file };
LogParser out(this, "log-out> ", revisions);
OutputLogger err(this->Log, "log-err> ");
diff --git a/Source/CTest/cmCTestGIT.cxx b/Source/CTest/cmCTestGIT.cxx
index 5f8cb74..ca8659e 100644
--- a/Source/CTest/cmCTestGIT.cxx
+++ b/Source/CTest/cmCTestGIT.cxx
@@ -9,8 +9,9 @@
#include <utility>
#include <vector>
+#include <cmext/algorithm>
+
#include "cmsys/FStream.hxx"
-#include "cmsys/Process.h"
#include "cmCTest.h"
#include "cmCTestVC.h"
@@ -18,6 +19,7 @@
#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,
@@ -58,9 +60,9 @@ private:
std::string cmCTestGIT::GetWorkingRevision()
{
// Run plumbing "git rev-list" to get work tree revision.
- const char* git = this->CommandLineTool.c_str();
- const char* git_rev_list[] = { git, "rev-list", "-n", "1",
- "HEAD", "--", nullptr };
+ std::string git = this->CommandLineTool;
+ std::vector<std::string> git_rev_list = { git, "rev-list", "-n",
+ "1", "HEAD", "--" };
std::string rev;
OneLineParser out(this, "rl-out> ", rev);
OutputLogger err(this->Log, "rl-err> ");
@@ -92,13 +94,13 @@ std::string cmCTestGIT::FindGitDir()
std::string git_dir;
// Run "git rev-parse --git-dir" to locate the real .git directory.
- const char* git = this->CommandLineTool.c_str();
- char const* git_rev_parse[] = { git, "rev-parse", "--git-dir", nullptr };
+ std::string git = this->CommandLineTool;
+ std::vector<std::string> git_rev_parse = { git, "rev-parse", "--git-dir" };
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, nullptr,
- cmProcessOutput::UTF8)) {
+ if (this->RunChild(git_rev_parse, &rev_parse_out, &rev_parse_err,
+ std::string{}, cmProcessOutput::UTF8)) {
git_dir = git_dir_line;
}
if (git_dir.empty()) {
@@ -117,11 +119,10 @@ std::string cmCTestGIT::FindGitDir()
std::string cygpath_exe =
cmStrCat(cmSystemTools::GetFilenamePath(git), "/cygpath.exe");
if (cmSystemTools::FileExists(cygpath_exe)) {
- char const* cygpath[] = { cygpath_exe.c_str(), "-w", git_dir.c_str(),
- 0 };
+ std::vector<std::string> cygpath = { cygpath_exe, "-w", git_dir };
OneLineParser cygpath_out(this, "cygpath-out> ", git_dir_line);
OutputLogger cygpath_err(this->Log, "cygpath-err> ");
- if (this->RunChild(cygpath, &cygpath_out, &cygpath_err, nullptr,
+ if (this->RunChild(cygpath, &cygpath_out, &cygpath_err, std::string{},
cmProcessOutput::UTF8)) {
git_dir = git_dir_line;
}
@@ -136,12 +137,12 @@ std::string cmCTestGIT::FindTopDir()
std::string top_dir = this->SourceDirectory;
// Run "git rev-parse --show-cdup" to locate the top of the tree.
- const char* git = this->CommandLineTool.c_str();
- char const* git_rev_parse[] = { git, "rev-parse", "--show-cdup", nullptr };
+ std::string git = this->CommandLineTool;
+ std::vector<std::string> git_rev_parse = { git, "rev-parse", "--show-cdup" };
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, nullptr,
+ if (this->RunChild(git_rev_parse, &rev_parse_out, &rev_parse_err, "",
cmProcessOutput::UTF8) &&
!cdup.empty()) {
top_dir += "/";
@@ -153,10 +154,10 @@ std::string cmCTestGIT::FindTopDir()
bool cmCTestGIT::UpdateByFetchAndReset()
{
- const char* git = this->CommandLineTool.c_str();
+ std::string git = this->CommandLineTool;
// Use "git fetch" to get remote commits.
- std::vector<char const*> git_fetch;
+ std::vector<std::string> git_fetch;
git_fetch.push_back(git);
git_fetch.push_back("fetch");
@@ -166,17 +167,12 @@ bool cmCTestGIT::UpdateByFetchAndReset()
opts = this->CTest->GetCTestConfiguration("GITUpdateOptions");
}
std::vector<std::string> args = cmSystemTools::ParseArguments(opts);
- for (std::string const& arg : args) {
- git_fetch.push_back(arg.c_str());
- }
-
- // Sentinel argument.
- git_fetch.push_back(nullptr);
+ cm::append(git_fetch, args);
// Fetch upstream refs.
OutputLogger fetch_out(this->Log, "fetch-out> ");
OutputLogger fetch_err(this->Log, "fetch-err> ");
- if (!this->RunUpdateCommand(git_fetch.data(), &fetch_out, &fetch_err)) {
+ if (!this->RunUpdateCommand(git_fetch, &fetch_out, &fetch_err)) {
return false;
}
@@ -207,25 +203,22 @@ bool cmCTestGIT::UpdateByFetchAndReset()
}
// Reset the local branch to point at that tracked from upstream.
- char const* git_reset[] = { git, "reset", "--hard", sha1.c_str(), nullptr };
+ std::vector<std::string> git_reset = { git, "reset", "--hard", sha1 };
OutputLogger reset_out(this->Log, "reset-out> ");
OutputLogger reset_err(this->Log, "reset-err> ");
- return this->RunChild(&git_reset[0], &reset_out, &reset_err);
+ return this->RunChild(git_reset, &reset_out, &reset_err);
}
bool cmCTestGIT::UpdateByCustom(std::string const& custom)
{
cmList git_custom_command{ custom, cmList::EmptyElements::Yes };
- 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);
+ std::vector<std::string> git_custom;
+ git_custom.reserve(git_custom_command.size());
+ cm::append(git_custom, git_custom_command);
OutputLogger custom_out(this->Log, "custom-out> ");
OutputLogger custom_err(this->Log, "custom-err> ");
- return this->RunUpdateCommand(git_custom.data(), &custom_out, &custom_err);
+ return this->RunUpdateCommand(git_custom, &custom_out, &custom_err);
}
bool cmCTestGIT::UpdateInternal()
@@ -244,13 +237,14 @@ bool cmCTestGIT::UpdateImpl()
}
std::string top_dir = this->FindTopDir();
- const char* git = this->CommandLineTool.c_str();
- const char* recursive = "--recursive";
- const char* sync_recursive = "--recursive";
+ std::string git = this->CommandLineTool;
+ std::string recursive = "--recursive";
+ std::string sync_recursive = "--recursive";
// Git < 1.6.5 did not support submodule --recursive
+ bool support_recursive = true;
if (this->GetGitVersion() < cmCTestGITVersion(1, 6, 5, 0)) {
- recursive = nullptr;
+ support_recursive = false;
// 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";
@@ -258,8 +252,9 @@ 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)) {
- sync_recursive = nullptr;
+ support_sync_recursive = false;
// 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";
@@ -274,35 +269,39 @@ bool cmCTestGIT::UpdateImpl()
std::string init_submodules =
this->CTest->GetCTestConfiguration("GITInitSubmodules");
if (cmIsOn(init_submodules)) {
- char const* git_submodule_init[] = { git, "submodule", "init", nullptr };
+ std::vector<std::string> git_submodule_init = { git, "submodule", "init" };
ret = this->RunChild(git_submodule_init, &submodule_out, &submodule_err,
- top_dir.c_str());
+ top_dir);
if (!ret) {
return false;
}
}
- char const* git_submodule_sync[] = { git, "submodule", "sync",
- sync_recursive, nullptr };
+ std::vector<std::string> git_submodule_sync = { git, "submodule", "sync" };
+ if (support_sync_recursive) {
+ git_submodule_sync.push_back(sync_recursive);
+ }
ret = this->RunChild(git_submodule_sync, &submodule_out, &submodule_err,
- top_dir.c_str());
+ top_dir);
if (!ret) {
return false;
}
- char const* git_submodule[] = { git, "submodule", "update", recursive,
- nullptr };
+ std::vector<std::string> git_submodule = { git, "submodule", "update" };
+ if (support_recursive) {
+ git_submodule.push_back(recursive);
+ }
return this->RunChild(git_submodule, &submodule_out, &submodule_err,
- top_dir.c_str());
+ top_dir);
}
unsigned int cmCTestGIT::GetGitVersion()
{
if (!this->CurrentGitVersion) {
- const char* git = this->CommandLineTool.c_str();
- char const* git_version[] = { git, "--version", nullptr };
+ std::string git = this->CommandLineTool;
+ std::vector<std::string> git_version = { git, "--version" };
std::string version;
OneLineParser version_out(this, "version-out> ", version);
OutputLogger version_err(this->Log, "version-err> ");
@@ -605,50 +604,49 @@ bool cmCTestGIT::LoadRevisions()
{
// Use 'git rev-list ... | git diff-tree ...' to get revisions.
std::string range = this->OldRevision + ".." + this->NewRevision;
- 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
+ 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"
};
this->Log << cmCTestGIT::ComputeCommandLine(git_rev_list) << " | "
<< cmCTestGIT::ComputeCommandLine(git_diff_tree) << "\n";
- cmsysProcess* cp = cmsysProcess_New();
- cmsysProcess_AddCommand(cp, git_rev_list);
- cmsysProcess_AddCommand(cp, git_diff_tree);
- cmsysProcess_SetWorkingDirectory(cp, this->SourceDirectory.c_str());
+ cmUVProcessChainBuilder builder;
+ builder.AddCommand(git_rev_list)
+ .AddCommand(git_diff_tree)
+ .SetWorkingDirectory(this->SourceDirectory);
CommitParser out(this, "dt-out> ");
OutputLogger err(this->Log, "dt-err> ");
- cmCTestGIT::RunProcess(cp, &out, &err, cmProcessOutput::UTF8);
+ cmCTestGIT::RunProcess(builder, &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()
{
- const char* git = this->CommandLineTool.c_str();
+ std::string git = this->CommandLineTool;
// Use 'git update-index' to refresh the index w.r.t. the work tree.
- const char* git_update_index[] = { git, "update-index", "--refresh",
- nullptr };
+ std::vector<std::string> git_update_index = { git, "update-index",
+ "--refresh" };
OutputLogger ui_out(this->Log, "ui-out> ");
OutputLogger ui_err(this->Log, "ui-err> ");
- this->RunChild(git_update_index, &ui_out, &ui_err, nullptr,
+ this->RunChild(git_update_index, &ui_out, &ui_err, "",
cmProcessOutput::UTF8);
// Use 'git diff-index' to get modified files.
- const char* git_diff_index[] = { git, "diff-index", "-z",
- "HEAD", "--", nullptr };
+ std::vector<std::string> git_diff_index = { git, "diff-index", "-z", "HEAD",
+ "--" };
DiffParser out(this, "di-out> ");
OutputLogger err(this->Log, "di-err> ");
- this->RunChild(git_diff_index, &out, &err, nullptr, cmProcessOutput::UTF8);
+ this->RunChild(git_diff_index, &out, &err, "", 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 02837ba..e1a945d 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.
- const char* hg = this->CommandLineTool.c_str();
- const char* hg_identify[] = { hg, "identify", "-i", nullptr };
+ std::string hg = this->CommandLineTool;
+ std::vector<std::string> hg_identify = { hg, "identify", "-i" };
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.
{
- const char* hg = this->CommandLineTool.c_str();
- const char* hg_pull[] = { hg, "pull", "-v", nullptr };
+ std::string hg = this->CommandLineTool;
+ std::vector<std::string> hg_pull = { hg, "pull", "-v" };
OutputLogger out(this->Log, "pull-out> ");
OutputLogger err(this->Log, "pull-err> ");
- this->RunChild(&hg_pull[0], &out, &err);
+ this->RunChild(hg_pull, &out, &err);
}
// TODO: if(this->CTest->GetTestModel() == cmCTest::NIGHTLY)
- std::vector<char const*> hg_update;
+ std::vector<std::string> hg_update;
hg_update.push_back(this->CommandLineTool.c_str());
hg_update.push_back("update");
hg_update.push_back("-v");
@@ -147,16 +147,11 @@ bool cmCTestHG::UpdateImpl()
opts = this->CTest->GetCTestConfiguration("HGUpdateOptions");
}
std::vector<std::string> args = cmSystemTools::ParseArguments(opts);
- for (std::string const& arg : args) {
- hg_update.push_back(arg.c_str());
- }
-
- // Sentinel argument.
- hg_update.push_back(nullptr);
+ cm::append(hg_update, args);
OutputLogger out(this->Log, "update-out> ");
OutputLogger err(this->Log, "update-err> ");
- return this->RunUpdateCommand(hg_update.data(), &out, &err);
+ return this->RunUpdateCommand(hg_update, &out, &err);
}
class cmCTestHG::LogParser
@@ -277,8 +272,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;
- const char* hg = this->CommandLineTool.c_str();
- const char* hgXMLTemplate = "<logentry\n"
+ std::string hg = this->CommandLineTool;
+ std::string hgXMLTemplate = "<logentry\n"
" revision=\"{node|short}\">\n"
" <author>{author|person}</author>\n"
" <email>{author|email}</email>\n"
@@ -288,10 +283,8 @@ bool cmCTestHG::LoadRevisions()
" <file_adds>{file_adds}</file_adds>\n"
" <file_dels>{file_dels}</file_dels>\n"
"</logentry>\n";
- const char* hg_log[] = {
- hg, "log", "--removed", "-r", range.c_str(),
- "--template", hgXMLTemplate, nullptr
- };
+ std::vector<std::string> hg_log = { hg, "log", "--removed", "-r",
+ range, "--template", hgXMLTemplate };
LogParser out(this, "log-out> ");
out.Process("<?xml version=\"1.0\"?>\n"
@@ -305,8 +298,8 @@ bool cmCTestHG::LoadRevisions()
bool cmCTestHG::LoadModifications()
{
// Use 'hg status' to get modified files.
- const char* hg = this->CommandLineTool.c_str();
- const char* hg_status[] = { hg, "status", nullptr };
+ std::string hg = this->CommandLineTool;
+ std::vector<std::string> hg_status = { hg, "status" };
StatusParser out(this, "status-out> ");
OutputLogger err(this->Log, "status-err> ");
this->RunChild(hg_status, &out, &err);
diff --git a/Source/CTest/cmCTestP4.cxx b/Source/CTest/cmCTestP4.cxx
index 0e002b9..5d71b84 100644
--- a/Source/CTest/cmCTestP4.cxx
+++ b/Source/CTest/cmCTestP4.cxx
@@ -149,17 +149,16 @@ cmCTestP4::User cmCTestP4::GetUserData(const std::string& username)
auto it = this->Users.find(username);
if (it == this->Users.end()) {
- std::vector<char const*> p4_users;
+ std::vector<std::string> 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.c_str());
- p4_users.push_back(nullptr);
+ p4_users.push_back(username);
UserParser out(this, "users-out> ");
OutputLogger err(this->Log, "users-err> ");
- this->RunChild(p4_users.data(), &out, &err);
+ this->RunChild(p4_users, &out, &err);
// The user should now be added to the map. Search again.
it = this->Users.find(username);
@@ -303,10 +302,10 @@ private:
}
};
-void cmCTestP4::SetP4Options(std::vector<char const*>& CommandOptions)
+void cmCTestP4::SetP4Options(std::vector<std::string>& CommandOptions)
{
if (this->P4Options.empty()) {
- const char* p4 = this->CommandLineTool.c_str();
+ std::string p4 = this->CommandLineTool;
this->P4Options.emplace_back(p4);
// The CTEST_P4_CLIENT variable sets the P4 client used when issuing
@@ -328,15 +327,12 @@ void cmCTestP4::SetP4Options(std::vector<char const*>& CommandOptions)
cm::append(this->P4Options, cmSystemTools::ParseArguments(opts));
}
- CommandOptions.clear();
- for (std::string const& o : this->P4Options) {
- CommandOptions.push_back(o.c_str());
- }
+ CommandOptions = this->P4Options;
}
std::string cmCTestP4::GetWorkingRevision()
{
- std::vector<char const*> p4_identify;
+ std::vector<std::string> p4_identify;
this->SetP4Options(p4_identify);
p4_identify.push_back("changes");
@@ -345,14 +341,13 @@ std::string cmCTestP4::GetWorkingRevision()
p4_identify.push_back("-t");
std::string source = this->SourceDirectory + "/...#have";
- p4_identify.push_back(source.c_str());
- p4_identify.push_back(nullptr);
+ p4_identify.push_back(source);
std::string rev;
IdentifyParser out(this, "p4_changes-out> ", rev);
OutputLogger err(this->Log, "p4_changes-err> ");
- bool result = this->RunChild(p4_identify.data(), &out, &err);
+ bool result = this->RunChild(p4_identify, &out, &err);
// If there was a problem contacting the server return "<unknown>"
if (!result) {
@@ -388,7 +383,7 @@ bool cmCTestP4::NoteNewRevision()
bool cmCTestP4::LoadRevisions()
{
- std::vector<char const*> p4_changes;
+ std::vector<std::string> p4_changes;
this->SetP4Options(p4_changes);
// Use 'p4 changes ...@old,new' to get a list of changelists
@@ -409,38 +404,36 @@ bool cmCTestP4::LoadRevisions()
.append(this->NewRevision);
p4_changes.push_back("changes");
- p4_changes.push_back(range.c_str());
- p4_changes.push_back(nullptr);
+ p4_changes.push_back(range);
ChangesParser out(this, "p4_changes-out> ");
OutputLogger err(this->Log, "p4_changes-err> ");
this->ChangeLists.clear();
- this->RunChild(p4_changes.data(), &out, &err);
+ this->RunChild(p4_changes, &out, &err);
if (this->ChangeLists.empty()) {
return true;
}
// p4 describe -s ...@1111111,2222222
- std::vector<char const*> p4_describe;
+ std::vector<std::string> 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.c_str());
- p4_describe.push_back(nullptr);
+ p4_describe.push_back(i);
DescribeParser outDescribe(this, "p4_describe-out> ");
OutputLogger errDescribe(this->Log, "p4_describe-err> ");
- this->RunChild(p4_describe.data(), &outDescribe, &errDescribe);
+ this->RunChild(p4_describe, &outDescribe, &errDescribe);
}
return true;
}
bool cmCTestP4::LoadModifications()
{
- std::vector<char const*> p4_diff;
+ std::vector<std::string> p4_diff;
this->SetP4Options(p4_diff);
p4_diff.push_back("diff");
@@ -448,12 +441,11 @@ 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.c_str());
- p4_diff.push_back(nullptr);
+ p4_diff.push_back(source);
DiffParser out(this, "p4_diff-out> ");
OutputLogger err(this->Log, "p4_diff-err> ");
- this->RunChild(p4_diff.data(), &out, &err);
+ this->RunChild(p4_diff, &out, &err);
return true;
}
@@ -461,17 +453,14 @@ bool cmCTestP4::UpdateCustom(const std::string& custom)
{
cmList p4_custom_command{ custom, cmList::EmptyElements::Yes };
- 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);
+ std::vector<std::string> p4_custom;
+ p4_custom.reserve(p4_custom_command.size());
+ cm::append(p4_custom, p4_custom_command);
OutputLogger custom_out(this->Log, "p4_customsync-out> ");
OutputLogger custom_err(this->Log, "p4_customsync-err> ");
- return this->RunUpdateCommand(p4_custom.data(), &custom_out, &custom_err);
+ return this->RunUpdateCommand(p4_custom, &custom_out, &custom_err);
}
bool cmCTestP4::UpdateImpl()
@@ -488,7 +477,7 @@ bool cmCTestP4::UpdateImpl()
return false;
}
- std::vector<char const*> p4_sync;
+ std::vector<std::string> p4_sync;
this->SetP4Options(p4_sync);
p4_sync.push_back("sync");
@@ -499,9 +488,7 @@ bool cmCTestP4::UpdateImpl()
opts = this->CTest->GetCTestConfiguration("P4UpdateOptions");
}
std::vector<std::string> args = cmSystemTools::ParseArguments(opts);
- for (std::string const& arg : args) {
- p4_sync.push_back(arg.c_str());
- }
+ cm::append(p4_sync, args);
std::string source = this->SourceDirectory + "/...";
@@ -515,11 +502,10 @@ bool cmCTestP4::UpdateImpl()
source.append("@\"").append(date).append("\"");
}
- p4_sync.push_back(source.c_str());
- p4_sync.push_back(nullptr);
+ p4_sync.push_back(source);
OutputLogger out(this->Log, "p4_sync-out> ");
OutputLogger err(this->Log, "p4_sync-err> ");
- return this->RunUpdateCommand(p4_sync.data(), &out, &err);
+ return this->RunUpdateCommand(p4_sync, &out, &err);
}
diff --git a/Source/CTest/cmCTestP4.h b/Source/CTest/cmCTestP4.h
index 1889520..827caa1 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<char const*>& options);
+ void SetP4Options(std::vector<std::string>& options);
std::string GetWorkingRevision();
bool NoteOldRevision() override;
diff --git a/Source/CTest/cmCTestSVN.cxx b/Source/CTest/cmCTestSVN.cxx
index 91a1177..14bc510 100644
--- a/Source/CTest/cmCTestSVN.cxx
+++ b/Source/CTest/cmCTestSVN.cxx
@@ -33,7 +33,7 @@ cmCTestSVN::~cmCTestSVN() = default;
void cmCTestSVN::CleanupImpl()
{
- std::vector<const char*> svn_cleanup;
+ std::vector<std::string> 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<const char*> svn_info;
+ std::vector<std::string> svn_info;
svn_info.push_back("info");
- svn_info.push_back(svninfo.LocalPath.c_str());
+ svn_info.push_back(svninfo.LocalPath);
std::string rev;
InfoParser out(this, "info-out> ", rev, svninfo);
OutputLogger err(this->Log, "info-err> ");
@@ -251,26 +251,24 @@ bool cmCTestSVN::UpdateImpl()
args.push_back("-r{" + this->GetNightlyTime() + " +0000}");
}
- std::vector<char const*> svn_update;
+ std::vector<std::string> svn_update;
svn_update.push_back("update");
- for (std::string const& arg : args) {
- svn_update.push_back(arg.c_str());
- }
+ cm::append(svn_update, args);
UpdateParser out(this, "up-out> ");
OutputLogger err(this->Log, "up-err> ");
return this->RunSVNCommand(svn_update, &out, &err);
}
-bool cmCTestSVN::RunSVNCommand(std::vector<char const*> const& parameters,
+bool cmCTestSVN::RunSVNCommand(std::vector<std::string> const& parameters,
OutputParser* out, OutputParser* err)
{
if (parameters.empty()) {
return false;
}
- std::vector<char const*> args;
- args.push_back(this->CommandLineTool.c_str());
+ std::vector<std::string> args;
+ args.push_back(this->CommandLineTool);
cm::append(args, parameters);
args.push_back("--non-interactive");
@@ -278,16 +276,12 @@ bool cmCTestSVN::RunSVNCommand(std::vector<char const*> const& parameters,
std::vector<std::string> parsedUserOptions =
cmSystemTools::ParseArguments(userOptions);
- for (std::string const& opt : parsedUserOptions) {
- args.push_back(opt.c_str());
- }
-
- args.push_back(nullptr);
+ cm::append(args, parsedUserOptions);
- if (strcmp(parameters[0], "update") == 0) {
- return this->RunUpdateCommand(args.data(), out, err);
+ if (parameters[0] == "update") {
+ return this->RunUpdateCommand(args, out, err);
}
- return this->RunChild(args.data(), out, err);
+ return this->RunChild(args, out, err);
}
class cmCTestSVN::LogParser
@@ -393,7 +387,7 @@ bool cmCTestSVN::LoadRevisions(SVNInfo& svninfo)
}
// Run "svn log" to get all global revisions of interest.
- std::vector<const char*> svn_log;
+ std::vector<std::string> svn_log;
svn_log.push_back("log");
svn_log.push_back("--xml");
svn_log.push_back("-v");
@@ -472,7 +466,7 @@ private:
bool cmCTestSVN::LoadModifications()
{
// Run "svn status" which reports local modifications.
- std::vector<const char*> svn_status;
+ std::vector<std::string> svn_status;
svn_status.push_back("status");
StatusParser out(this, "status-out> ");
OutputLogger err(this->Log, "status-err> ");
@@ -534,7 +528,7 @@ bool cmCTestSVN::LoadRepositories()
this->RootInfo = &(this->Repositories.back());
// Run "svn status" to get the list of external repositories
- std::vector<const char*> svn_status;
+ std::vector<std::string> 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 370d176..1485dc0 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<char const*> const& parameters,
+ bool RunSVNCommand(std::vector<std::string> const& parameters,
OutputParser* out, OutputParser* err);
// Information about an SVN repository (root repository or external)
diff --git a/Source/CTest/cmCTestVC.cxx b/Source/CTest/cmCTestVC.cxx
index 609ccba..cbbb5a5 100644
--- a/Source/CTest/cmCTestVC.cxx
+++ b/Source/CTest/cmCTestVC.cxx
@@ -7,10 +7,9 @@
#include <sstream>
#include <vector>
-#include "cmsys/Process.h"
-
#include "cmCTest.h"
#include "cmSystemTools.h"
+#include "cmUVProcessChain.h"
#include "cmValue.h"
#include "cmXMLWriter.h"
@@ -55,18 +54,12 @@ 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(vc_co.data(), &out, &err, parent.c_str());
+ bool result = this->RunChild(args, &out, &err, parent);
this->Log << "--- End Initial Checkout ---\n";
if (!result) {
cmCTestLog(this->CTest, ERROR_MESSAGE,
@@ -75,35 +68,35 @@ bool cmCTestVC::InitialCheckout(const std::string& command)
return result;
}
-bool cmCTestVC::RunChild(char const* const* cmd, OutputParser* out,
- OutputParser* err, const char* workDir,
- Encoding encoding)
+bool cmCTestVC::RunChild(const std::vector<std::string>& cmd,
+ OutputParser* out, OutputParser* err,
+ std::string workDir, Encoding encoding)
{
this->Log << cmCTestVC::ComputeCommandLine(cmd) << "\n";
- 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;
+ 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;
}
-std::string cmCTestVC::ComputeCommandLine(char const* const* cmd)
+std::string cmCTestVC::ComputeCommandLine(const std::vector<std::string>& cmd)
{
std::ostringstream line;
const char* sep = "";
- for (const char* const* arg = cmd; *arg; ++arg) {
- line << sep << "\"" << *arg << "\"";
+ for (auto const& arg : cmd) {
+ line << sep << "\"" << arg << "\"";
sep = " ";
}
return line.str();
}
-bool cmCTestVC::RunUpdateCommand(char const* const* cmd, OutputParser* out,
- OutputParser* err, Encoding encoding)
+bool cmCTestVC::RunUpdateCommand(const std::vector<std::string>& cmd,
+ OutputParser* out, OutputParser* err,
+ Encoding encoding)
{
// Report the command line.
this->UpdateCommandLine = this->ComputeCommandLine(cmd);
@@ -113,7 +106,7 @@ bool cmCTestVC::RunUpdateCommand(char const* const* cmd, OutputParser* out,
}
// Run the command.
- return this->RunChild(cmd, out, err, nullptr, encoding);
+ return this->RunChild(cmd, out, err, "", encoding);
}
std::string cmCTestVC::GetNightlyTime()
diff --git a/Source/CTest/cmCTestVC.h b/Source/CTest/cmCTestVC.h
index 7b03d10..dd5456d 100644
--- a/Source/CTest/cmCTestVC.h
+++ b/Source/CTest/cmCTestVC.h
@@ -6,6 +6,7 @@
#include <iosfwd>
#include <string>
+#include <vector>
#include "cmProcessOutput.h"
#include "cmProcessTools.h"
@@ -108,15 +109,15 @@ protected:
};
/** Convert a list of arguments to a human-readable command line. */
- static std::string ComputeCommandLine(char const* const* cmd);
+ static std::string ComputeCommandLine(const std::vector<std::string>& cmd);
/** Run a command line and send output to given parsers. */
- bool RunChild(char const* const* cmd, OutputParser* out, OutputParser* err,
- const char* workDir = nullptr,
+ bool RunChild(const std::vector<std::string>& cmd, OutputParser* out,
+ OutputParser* err, std::string workDir = {},
Encoding encoding = cmProcessOutput::Auto);
/** Run VC update command line and send output to given parsers. */
- bool RunUpdateCommand(char const* const* cmd, OutputParser* out,
+ bool RunUpdateCommand(const std::vector<std::string>& cmd, OutputParser* out,
OutputParser* err = nullptr,
Encoding encoding = cmProcessOutput::Auto);
diff --git a/Source/cmProcessTools.cxx b/Source/cmProcessTools.cxx
index 9e7854b..1dd1dce 100644
--- a/Source/cmProcessTools.cxx
+++ b/Source/cmProcessTools.cxx
@@ -2,48 +2,68 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmProcessTools.h"
+#include <algorithm>
+#include <iterator>
#include <ostream>
-#include "cmsys/Process.h"
+#include <cm3p/uv.h>
#include "cmProcessOutput.h"
+#include "cmUVHandlePtr.h"
+#include "cmUVStream.h"
-void cmProcessTools::RunProcess(struct cmsysProcess_s* cp, OutputParser* out,
- OutputParser* err, Encoding encoding)
+std::vector<cmUVProcessChain::Status> cmProcessTools::RunProcess(
+ cmUVProcessChainBuilder& builder, OutputParser* out, OutputParser* err,
+ Encoding encoding)
{
- cmsysProcess_Execute(cp);
- char* data = nullptr;
- int length = 0;
- int p;
cmProcessOutput processOutput(encoding);
+
+ builder.SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT)
+ .SetBuiltinStream(cmUVProcessChainBuilder::Stream_ERROR);
+
+ auto chain = builder.Start();
+
std::string strdata;
- while ((out || err) &&
- (p = cmsysProcess_WaitForData(cp, &data, &length, nullptr))) {
- if (out && p == cmsysProcess_Pipe_STDOUT) {
- processOutput.DecodeText(data, length, strdata, 1);
- if (!out->Process(strdata.c_str(), static_cast<int>(strdata.size()))) {
- out = nullptr;
+ cm::uv_pipe_ptr outputPipe;
+ outputPipe.init(chain.GetLoop(), 0);
+ uv_pipe_open(outputPipe, chain.OutputStream());
+ auto outputHandle = cmUVStreamRead(
+ outputPipe,
+ [&out, &processOutput, &strdata](std::vector<char> data) {
+ if (out) {
+ processOutput.DecodeText(data.data(), data.size(), strdata, 1);
+ if (!out->Process(strdata.c_str(), static_cast<int>(strdata.size()))) {
+ out = nullptr;
+ }
}
- } else if (err && p == cmsysProcess_Pipe_STDERR) {
- processOutput.DecodeText(data, length, strdata, 2);
- if (!err->Process(strdata.c_str(), static_cast<int>(strdata.size()))) {
- err = nullptr;
+ },
+ [&out]() { out = nullptr; });
+ cm::uv_pipe_ptr errorPipe;
+ errorPipe.init(chain.GetLoop(), 0);
+ uv_pipe_open(errorPipe, chain.ErrorStream());
+ auto errorHandle = cmUVStreamRead(
+ errorPipe,
+ [&err, &processOutput, &strdata](std::vector<char> data) {
+ if (err) {
+ processOutput.DecodeText(data.data(), data.size(), strdata, 2);
+ if (!err->Process(strdata.c_str(), static_cast<int>(strdata.size()))) {
+ err = nullptr;
+ }
}
- }
+ },
+ [&err]() { err = nullptr; });
+ while (out || err || !chain.Finished()) {
+ uv_run(&chain.GetLoop(), UV_RUN_ONCE);
}
- if (out) {
- processOutput.DecodeText(std::string(), strdata, 1);
- if (!strdata.empty()) {
- out->Process(strdata.c_str(), static_cast<int>(strdata.size()));
- }
- }
- if (err) {
- processOutput.DecodeText(std::string(), strdata, 2);
- if (!strdata.empty()) {
- err->Process(strdata.c_str(), static_cast<int>(strdata.size()));
- }
- }
- cmsysProcess_WaitForExit(cp, nullptr);
+
+ std::vector<cmUVProcessChain::Status> result;
+ auto status = chain.GetStatus();
+ std::transform(
+ status.begin(), status.end(), std::back_inserter(result),
+ [](const cmUVProcessChain::Status* s) -> cmUVProcessChain::Status {
+ return *s;
+ });
+ return result;
}
cmProcessTools::LineParser::LineParser(char sep, bool ignoreCR)
diff --git a/Source/cmProcessTools.h b/Source/cmProcessTools.h
index 74ec5e0..2bdabea 100644
--- a/Source/cmProcessTools.h
+++ b/Source/cmProcessTools.h
@@ -7,8 +7,10 @@
#include <cstring>
#include <iosfwd>
#include <string>
+#include <vector>
#include "cmProcessOutput.h"
+#include "cmUVProcessChain.h"
/** \class cmProcessTools
* \brief Helper classes for process output parsing
@@ -81,7 +83,7 @@ public:
};
/** Run a process and send output to given parsers. */
- static void RunProcess(struct cmsysProcess_s* cp, OutputParser* out,
- OutputParser* err = nullptr,
- Encoding encoding = cmProcessOutput::Auto);
+ static std::vector<cmUVProcessChain::Status> RunProcess(
+ cmUVProcessChainBuilder& builder, OutputParser* out,
+ OutputParser* err = nullptr, Encoding encoding = cmProcessOutput::Auto);
};
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index 2ac9d8e..1263bb2 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -28,6 +28,7 @@
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTransformDepfile.h"
+#include "cmUVHandlePtr.h"
#include "cmUVProcessChain.h"
#include "cmUVStream.h"
#include "cmUtils.hxx"
@@ -295,14 +296,8 @@ int CLCompileAndDependencies(const std::vector<std::string>& args)
}
}
- std::unique_ptr<cmsysProcess, void (*)(cmsysProcess*)> cp(
- cmsysProcess_New(), cmsysProcess_Delete);
- std::vector<const char*> argv(command.size() + 1);
- std::transform(command.begin(), command.end(), argv.begin(),
- [](std::string const& s) { return s.c_str(); });
- argv.back() = nullptr;
- cmsysProcess_SetCommand(cp.get(), argv.data());
- cmsysProcess_SetWorkingDirectory(cp.get(), currentBinaryDir.c_str());
+ cmUVProcessChainBuilder builder;
+ builder.AddCommand(command).SetWorkingDirectory(currentBinaryDir);
cmsys::ofstream fout(depFile.c_str());
if (!fout) {
@@ -313,22 +308,18 @@ int CLCompileAndDependencies(const std::vector<std::string>& args)
CLOutputLogger errLogger(std::cerr);
// Start the process.
- cmProcessTools::RunProcess(cp.get(), &includeParser, &errLogger);
+ auto result =
+ cmProcessTools::RunProcess(builder, &includeParser, &errLogger);
+ auto const& subStatus = result.front();
int status = 0;
// handle status of process
- switch (cmsysProcess_GetState(cp.get())) {
- case cmsysProcess_State_Exited:
- status = cmsysProcess_GetExitValue(cp.get());
- break;
- case cmsysProcess_State_Exception:
- status = 1;
- break;
- case cmsysProcess_State_Error:
- status = 2;
- break;
- default:
- break;
+ if (subStatus.SpawnResult != 0) {
+ status = 2;
+ } else if (subStatus.TermSignal != 0) {
+ status = 1;
+ } else {
+ status = subStatus.ExitStatus;
}
if (status != 0) {