summaryrefslogtreecommitdiff
path: root/Source/CTest/cmCTestLaunch.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/CTest/cmCTestLaunch.cxx')
-rw-r--r--Source/CTest/cmCTestLaunch.cxx214
1 files changed, 94 insertions, 120 deletions
diff --git a/Source/CTest/cmCTestLaunch.cxx b/Source/CTest/cmCTestLaunch.cxx
index 5b213518a..647f5fff9 100644
--- a/Source/CTest/cmCTestLaunch.cxx
+++ b/Source/CTest/cmCTestLaunch.cxx
@@ -2,36 +2,36 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestLaunch.h"
-#include "cmConfigure.h"
+#include <cstdlib>
+#include <cstring>
+#include <iostream>
#include "cmsys/FStream.hxx"
#include "cmsys/Process.h"
#include "cmsys/RegularExpression.hxx"
-#include <iostream>
-#include <stdlib.h>
-#include <string.h>
#include "cmCryptoHash.h"
#include "cmGeneratedFileStream.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmProcessOutput.h"
+#include "cmState.h"
#include "cmStateSnapshot.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmXMLWriter.h"
-#include "cm_auto_ptr.hxx"
#include "cmake.h"
#ifdef _WIN32
-#include <fcntl.h> // for _O_BINARY
-#include <io.h> // for _setmode
-#include <stdio.h> // for std{out,err} and fileno
+# include <fcntl.h> // for _O_BINARY
+# include <io.h> // for _setmode
+# include <stdio.h> // for std{out,err} and fileno
#endif
cmCTestLaunch::cmCTestLaunch(int argc, const char* const* argv)
{
this->Passthru = true;
- this->Process = CM_NULLPTR;
+ this->Process = nullptr;
this->ExitCode = 1;
this->CWD = cmSystemTools::GetCurrentWorkingDirectory();
@@ -129,7 +129,7 @@ bool cmCTestLaunch::ParseArguments(int argc, const char* const* argv)
return true;
}
this->RealArgC = 0;
- this->RealArgV = CM_NULLPTR;
+ this->RealArgV = nullptr;
std::cerr << "No launch/command separator ('--') found!\n";
return false;
}
@@ -147,7 +147,7 @@ void cmCTestLaunch::HandleRealArg(const char* arg)
return;
}
#endif
- this->RealArgs.push_back(arg);
+ this->RealArgs.emplace_back(arg);
}
void cmCTestLaunch::ComputeFileNames()
@@ -171,21 +171,14 @@ void cmCTestLaunch::ComputeFileNames()
cmCryptoHash md5(cmCryptoHash::AlgoMD5);
md5.Initialize();
md5.Append(this->CWD);
- for (std::vector<std::string>::const_iterator ai = this->RealArgs.begin();
- ai != this->RealArgs.end(); ++ai) {
- md5.Append(*ai);
+ for (std::string const& realArg : this->RealArgs) {
+ md5.Append(realArg);
}
this->LogHash = md5.FinalizeHex();
// We store stdout and stderr in temporary log files.
- this->LogOut = this->LogDir;
- this->LogOut += "launch-";
- this->LogOut += this->LogHash;
- this->LogOut += "-out.txt";
- this->LogErr = this->LogDir;
- this->LogErr += "launch-";
- this->LogErr += this->LogHash;
- this->LogErr += "-err.txt";
+ this->LogOut = cmStrCat(this->LogDir, "launch-", this->LogHash, "-out.txt");
+ this->LogErr = cmStrCat(this->LogDir, "launch-", this->LogHash, "-err.txt");
}
void cmCTestLaunch::RunChild()
@@ -224,11 +217,11 @@ void cmCTestLaunch::RunChild()
// Record child stdout and stderr if necessary.
if (!this->Passthru) {
- char* data = CM_NULLPTR;
+ char* data = nullptr;
int length = 0;
cmProcessOutput processOutput;
std::string strdata;
- while (int p = cmsysProcess_WaitForData(cp, &data, &length, CM_NULLPTR)) {
+ 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());
@@ -254,7 +247,7 @@ void cmCTestLaunch::RunChild()
}
// Wait for the real command to finish.
- cmsysProcess_WaitForExit(cp, CM_NULLPTR);
+ cmsysProcess_WaitForExit(cp, nullptr);
this->ExitCode = cmsysProcess_GetExitValue(cp);
}
@@ -284,11 +277,8 @@ void cmCTestLaunch::LoadLabels()
}
// Labels are listed in per-target files.
- std::string fname = this->OptionBuildDir;
- fname += cmake::GetCMakeFilesDirectory();
- fname += "/";
- fname += this->OptionTargetName;
- fname += ".dir/Labels.txt";
+ std::string fname = cmStrCat(this->OptionBuildDir, "/CMakeFiles/",
+ this->OptionTargetName, ".dir/Labels.txt");
// We are interested in per-target labels for this source file.
std::string source = this->OptionSource;
@@ -310,7 +300,7 @@ void cmCTestLaunch::LoadLabels()
if (line[0] == ' ') {
// Label lines appear indented by one space.
if (inTarget || inSource) {
- this->Labels.insert(line.c_str() + 1);
+ this->Labels.insert(line.substr(1));
}
} else if (!this->OptionSource.empty() && !inSource) {
// Non-indented lines specify a source file name. The first one
@@ -342,36 +332,34 @@ bool cmCTestLaunch::IsError() const
void cmCTestLaunch::WriteXML()
{
// Name the xml file.
- std::string logXML = this->LogDir;
- logXML += this->IsError() ? "error-" : "warning-";
- logXML += this->LogHash;
- logXML += ".xml";
+ std::string logXML =
+ cmStrCat(this->LogDir, this->IsError() ? "error-" : "warning-",
+ this->LogHash, ".xml");
// Use cmGeneratedFileStream to atomically create the report file.
- cmGeneratedFileStream fxml(logXML.c_str());
+ cmGeneratedFileStream fxml(logXML);
cmXMLWriter xml(fxml, 2);
- xml.StartElement("Failure");
- xml.Attribute("type", this->IsError() ? "Error" : "Warning");
- this->WriteXMLAction(xml);
- this->WriteXMLCommand(xml);
- this->WriteXMLResult(xml);
- this->WriteXMLLabels(xml);
- xml.EndElement(); // Failure
+ cmXMLElement e2(xml, "Failure");
+ e2.Attribute("type", this->IsError() ? "Error" : "Warning");
+ this->WriteXMLAction(e2);
+ this->WriteXMLCommand(e2);
+ this->WriteXMLResult(e2);
+ this->WriteXMLLabels(e2);
}
-void cmCTestLaunch::WriteXMLAction(cmXMLWriter& xml)
+void cmCTestLaunch::WriteXMLAction(cmXMLElement& e2)
{
- xml.Comment("Meta-information about the build action");
- xml.StartElement("Action");
+ e2.Comment("Meta-information about the build action");
+ cmXMLElement e3(e2, "Action");
// TargetName
if (!this->OptionTargetName.empty()) {
- xml.Element("TargetName", this->OptionTargetName);
+ e3.Element("TargetName", this->OptionTargetName);
}
// Language
if (!this->OptionLanguage.empty()) {
- xml.Element("Language", this->OptionLanguage);
+ e3.Element("Language", this->OptionLanguage);
}
// SourceFile
@@ -380,23 +368,22 @@ void cmCTestLaunch::WriteXMLAction(cmXMLWriter& xml)
cmSystemTools::ConvertToUnixSlashes(source);
// If file is in source tree use its relative location.
- if (cmSystemTools::FileIsFullPath(this->SourceDir.c_str()) &&
- cmSystemTools::FileIsFullPath(source.c_str()) &&
+ if (cmSystemTools::FileIsFullPath(this->SourceDir) &&
+ cmSystemTools::FileIsFullPath(source) &&
cmSystemTools::IsSubDirectory(source, this->SourceDir)) {
- source =
- cmSystemTools::RelativePath(this->SourceDir.c_str(), source.c_str());
+ source = cmSystemTools::RelativePath(this->SourceDir, source);
}
- xml.Element("SourceFile", source);
+ e3.Element("SourceFile", source);
}
// OutputFile
if (!this->OptionOutput.empty()) {
- xml.Element("OutputFile", this->OptionOutput);
+ e3.Element("OutputFile", this->OptionOutput);
}
// OutputType
- const char* outputType = CM_NULLPTR;
+ const char* outputType = nullptr;
if (!this->OptionTargetType.empty()) {
if (this->OptionTargetType == "EXECUTABLE") {
outputType = "executable";
@@ -411,106 +398,99 @@ void cmCTestLaunch::WriteXMLAction(cmXMLWriter& xml)
outputType = "object file";
}
if (outputType) {
- xml.Element("OutputType", outputType);
+ e3.Element("OutputType", outputType);
}
-
- xml.EndElement(); // Action
}
-void cmCTestLaunch::WriteXMLCommand(cmXMLWriter& xml)
+void cmCTestLaunch::WriteXMLCommand(cmXMLElement& e2)
{
- xml.Comment("Details of command");
- xml.StartElement("Command");
+ e2.Comment("Details of command");
+ cmXMLElement e3(e2, "Command");
if (!this->CWD.empty()) {
- xml.Element("WorkingDirectory", this->CWD);
+ e3.Element("WorkingDirectory", this->CWD);
}
- for (std::vector<std::string>::const_iterator ai = this->RealArgs.begin();
- ai != this->RealArgs.end(); ++ai) {
- xml.Element("Argument", *ai);
+ for (std::string const& realArg : this->RealArgs) {
+ e3.Element("Argument", realArg);
}
- xml.EndElement(); // Command
}
-void cmCTestLaunch::WriteXMLResult(cmXMLWriter& xml)
+void cmCTestLaunch::WriteXMLResult(cmXMLElement& e2)
{
- xml.Comment("Result of command");
- xml.StartElement("Result");
+ e2.Comment("Result of command");
+ cmXMLElement e3(e2, "Result");
// StdOut
- xml.StartElement("StdOut");
- this->DumpFileToXML(xml, this->LogOut);
- xml.EndElement(); // StdOut
+ this->DumpFileToXML(e3, "StdOut", this->LogOut);
// StdErr
- xml.StartElement("StdErr");
- this->DumpFileToXML(xml, this->LogErr);
- xml.EndElement(); // StdErr
+ this->DumpFileToXML(e3, "StdErr", this->LogErr);
// ExitCondition
- xml.StartElement("ExitCondition");
+ cmXMLElement e4(e3, "ExitCondition");
cmsysProcess* cp = this->Process;
switch (cmsysProcess_GetState(cp)) {
case cmsysProcess_State_Starting:
- xml.Content("No process has been executed");
+ e4.Content("No process has been executed");
break;
case cmsysProcess_State_Executing:
- xml.Content("The process is still executing");
+ e4.Content("The process is still executing");
break;
case cmsysProcess_State_Disowned:
- xml.Content("Disowned");
+ e4.Content("Disowned");
break;
case cmsysProcess_State_Killed:
- xml.Content("Killed by parent");
+ e4.Content("Killed by parent");
break;
case cmsysProcess_State_Expired:
- xml.Content("Killed when timeout expired");
+ e4.Content("Killed when timeout expired");
break;
case cmsysProcess_State_Exited:
- xml.Content(this->ExitCode);
+ e4.Content(this->ExitCode);
break;
case cmsysProcess_State_Exception:
- xml.Content("Terminated abnormally: ");
- xml.Content(cmsysProcess_GetExceptionString(cp));
+ e4.Content("Terminated abnormally: ");
+ e4.Content(cmsysProcess_GetExceptionString(cp));
break;
case cmsysProcess_State_Error:
- xml.Content("Error administrating child process: ");
- xml.Content(cmsysProcess_GetErrorString(cp));
+ e4.Content("Error administrating child process: ");
+ e4.Content(cmsysProcess_GetErrorString(cp));
break;
- };
- xml.EndElement(); // ExitCondition
-
- xml.EndElement(); // Result
+ }
}
-void cmCTestLaunch::WriteXMLLabels(cmXMLWriter& xml)
+void cmCTestLaunch::WriteXMLLabels(cmXMLElement& e2)
{
this->LoadLabels();
if (!this->Labels.empty()) {
- xml.Comment("Interested parties");
- xml.StartElement("Labels");
- for (std::set<std::string>::const_iterator li = this->Labels.begin();
- li != this->Labels.end(); ++li) {
- xml.Element("Label", *li);
+ e2.Comment("Interested parties");
+ cmXMLElement e3(e2, "Labels");
+ for (std::string const& label : this->Labels) {
+ e3.Element("Label", label);
}
- xml.EndElement(); // Labels
}
}
-void cmCTestLaunch::DumpFileToXML(cmXMLWriter& xml, std::string const& fname)
+void cmCTestLaunch::DumpFileToXML(cmXMLElement& e3, const char* tag,
+ std::string const& fname)
{
cmsys::ifstream fin(fname.c_str(), std::ios::in | std::ios::binary);
std::string line;
const char* sep = "";
+ cmXMLElement e4(e3, tag);
while (cmSystemTools::GetLineFromStream(fin, line)) {
if (MatchesFilterPrefix(line)) {
continue;
}
-
- xml.Content(sep);
- xml.Content(line);
+ if (this->Match(line, this->RegexWarningSuppress)) {
+ line = cmStrCat("[CTest: warning suppressed] ", line);
+ } else if (this->Match(line, this->RegexWarning)) {
+ line = cmStrCat("[CTest: warning matched] ", line);
+ }
+ e4.Content(sep);
+ e4.Content(line);
sep = "\n";
}
}
@@ -545,9 +525,9 @@ void cmCTestLaunch::LoadScrapeRules()
// Common compiler warning formats. These are much simpler than the
// full log-scraping expressions because we do not need to extract
// file and line information.
- this->RegexWarning.push_back("(^|[ :])[Ww][Aa][Rr][Nn][Ii][Nn][Gg]");
- this->RegexWarning.push_back("(^|[ :])[Rr][Ee][Mm][Aa][Rr][Kk]");
- this->RegexWarning.push_back("(^|[ :])[Nn][Oo][Tt][Ee]");
+ this->RegexWarning.emplace_back("(^|[ :])[Ww][Aa][Rr][Nn][Ii][Nn][Gg]");
+ this->RegexWarning.emplace_back("(^|[ :])[Rr][Ee][Mm][Aa][Rr][Kk]");
+ this->RegexWarning.emplace_back("(^|[ :])[Nn][Oo][Tt][Ee]");
// Load custom match rules given to us by CTest.
this->LoadScrapeRules("Warning", this->RegexWarning);
@@ -557,15 +537,12 @@ void cmCTestLaunch::LoadScrapeRules()
void cmCTestLaunch::LoadScrapeRules(
const char* purpose, std::vector<cmsys::RegularExpression>& regexps)
{
- std::string fname = this->LogDir;
- fname += "Custom";
- fname += purpose;
- fname += ".txt";
+ std::string fname = cmStrCat(this->LogDir, "Custom", purpose, ".txt");
cmsys::ifstream fin(fname.c_str(), std::ios::in | std::ios::binary);
std::string line;
cmsys::RegularExpression rex;
while (cmSystemTools::GetLineFromStream(fin, line)) {
- if (rex.compile(line.c_str())) {
+ if (rex.compile(line)) {
regexps.push_back(rex);
}
}
@@ -595,9 +572,8 @@ bool cmCTestLaunch::ScrapeLog(std::string const& fname)
bool cmCTestLaunch::Match(std::string const& line,
std::vector<cmsys::RegularExpression>& regexps)
{
- for (std::vector<cmsys::RegularExpression>::iterator ri = regexps.begin();
- ri != regexps.end(); ++ri) {
- if (ri->find(line.c_str())) {
+ for (cmsys::RegularExpression& r : regexps) {
+ if (r.find(line)) {
return true;
}
}
@@ -607,7 +583,7 @@ bool cmCTestLaunch::Match(std::string const& line,
bool cmCTestLaunch::MatchesFilterPrefix(std::string const& line) const
{
return !this->OptionFilterPrefix.empty() &&
- cmSystemTools::StringStartsWith(line, this->OptionFilterPrefix.c_str());
+ cmHasPrefix(line, this->OptionFilterPrefix);
}
int cmCTestLaunch::Main(int argc, const char* const argv[])
@@ -623,17 +599,15 @@ int cmCTestLaunch::Main(int argc, const char* const argv[])
void cmCTestLaunch::LoadConfig()
{
- cmake cm(cmake::RoleScript);
+ cmake cm(cmake::RoleScript, cmState::CTest);
cm.SetHomeDirectory("");
cm.SetHomeOutputDirectory("");
cm.GetCurrentSnapshot().SetDefaultDefinitions();
cmGlobalGenerator gg(&cm);
- CM_AUTO_PTR<cmMakefile> mf(new cmMakefile(&gg, cm.GetCurrentSnapshot()));
- std::string fname = this->LogDir;
- fname += "CTestLaunchConfig.cmake";
- if (cmSystemTools::FileExists(fname.c_str()) &&
- mf->ReadListFile(fname.c_str())) {
- this->SourceDir = mf->GetSafeDefinition("CTEST_SOURCE_DIRECTORY");
+ cmMakefile mf(&gg, cm.GetCurrentSnapshot());
+ std::string fname = cmStrCat(this->LogDir, "CTestLaunchConfig.cmake");
+ if (cmSystemTools::FileExists(fname) && mf.ReadListFile(fname)) {
+ this->SourceDir = mf.GetSafeDefinition("CTEST_SOURCE_DIRECTORY");
cmSystemTools::ConvertToUnixSlashes(this->SourceDir);
}
}