diff options
Diffstat (limited to 'Source/CTest')
51 files changed, 681 insertions, 669 deletions
diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx index 9ad9669..e7fb4c7 100644 --- a/Source/CTest/cmCTestBuildAndTestHandler.cxx +++ b/Source/CTest/cmCTestBuildAndTestHandler.cxx @@ -7,6 +7,7 @@ #include "cmGlobalGenerator.h" #include "cmMakefile.h" #include "cmState.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmWorkingDirectory.h" #include "cmake.h" @@ -76,6 +77,11 @@ int cmCTestBuildAndTestHandler::RunCMake(std::string* outstring, if (config) { args.push_back("-DCMAKE_BUILD_TYPE:STRING=" + std::string(config)); } + if (!this->BuildMakeProgram.empty() && + (this->BuildGenerator.find("Make") != std::string::npos || + this->BuildGenerator.find("Ninja") != std::string::npos)) { + args.push_back("-DCMAKE_MAKE_PROGRAM:FILEPATH=" + this->BuildMakeProgram); + } for (std::string const& opt : this->BuildOptions) { args.push_back(opt); @@ -284,9 +290,8 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring) std::vector<std::string> extraPaths; // if this->ExecutableDirectory is set try that as well if (!this->ExecutableDirectory.empty()) { - std::string tempPath = this->ExecutableDirectory; - tempPath += "/"; - tempPath += this->TestCommand; + std::string tempPath = + cmStrCat(this->ExecutableDirectory, '/', this->TestCommand); extraPaths.push_back(tempPath); } std::vector<std::string> failed; diff --git a/Source/CTest/cmCTestBuildCommand.cxx b/Source/CTest/cmCTestBuildCommand.cxx index 2eacaf1..cb22fa6 100644 --- a/Source/CTest/cmCTestBuildCommand.cxx +++ b/Source/CTest/cmCTestBuildCommand.cxx @@ -7,6 +7,7 @@ #include "cmGlobalGenerator.h" #include "cmMakefile.h" #include "cmMessageType.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmake.h" @@ -90,9 +91,8 @@ cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler() this->Makefile->GetCMakeInstance()->CreateGlobalGenerator( cmakeGeneratorName); if (!this->GlobalGenerator) { - std::string e = "could not create generator named \""; - e += cmakeGeneratorName; - e += "\""; + std::string e = cmStrCat("could not create generator named \"", + cmakeGeneratorName, '"'); this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e); cmSystemTools::SetFatalErrorOccured(); return nullptr; @@ -154,17 +154,15 @@ bool cmCTestBuildCommand::InitialPass(std::vector<std::string> const& args, { bool ret = cmCTestHandlerCommand::InitialPass(args, status); if (this->Values[ctb_NUMBER_ERRORS] && *this->Values[ctb_NUMBER_ERRORS]) { - std::ostringstream str; - str << this->Handler->GetTotalErrors(); - this->Makefile->AddDefinition(this->Values[ctb_NUMBER_ERRORS], - str.str().c_str()); + this->Makefile->AddDefinition( + this->Values[ctb_NUMBER_ERRORS], + std::to_string(this->Handler->GetTotalErrors())); } if (this->Values[ctb_NUMBER_WARNINGS] && *this->Values[ctb_NUMBER_WARNINGS]) { - std::ostringstream str; - str << this->Handler->GetTotalWarnings(); - this->Makefile->AddDefinition(this->Values[ctb_NUMBER_WARNINGS], - str.str().c_str()); + this->Makefile->AddDefinition( + this->Values[ctb_NUMBER_WARNINGS], + std::to_string(this->Handler->GetTotalWarnings())); } return ret; } diff --git a/Source/CTest/cmCTestBuildCommand.h b/Source/CTest/cmCTestBuildCommand.h index 77b0549..a62c301 100644 --- a/Source/CTest/cmCTestBuildCommand.h +++ b/Source/CTest/cmCTestBuildCommand.h @@ -6,13 +6,16 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cmCTestHandlerCommand.h" +#include "cmCommand.h" #include <string> +#include <utility> #include <vector> +#include "cm_memory.hxx" + class cmCTestBuildHandler; class cmCTestGenericHandler; -class cmCommand; class cmExecutionStatus; class cmGlobalGenerator; @@ -30,12 +33,12 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override + std::unique_ptr<cmCommand> Clone() override { - cmCTestBuildCommand* ni = new cmCTestBuildCommand; + auto ni = cm::make_unique<cmCTestBuildCommand>(); ni->CTest = this->CTest; ni->CTestScriptHandler = this->CTestScriptHandler; - return ni; + return std::unique_ptr<cmCommand>(std::move(ni)); } /** diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx index c8e4fa1..147286e 100644 --- a/Source/CTest/cmCTestBuildHandler.cxx +++ b/Source/CTest/cmCTestBuildHandler.cxx @@ -9,6 +9,8 @@ #include "cmGeneratedFileStream.h" #include "cmMakefile.h" #include "cmProcessOutput.h" +#include "cmStringAlgorithms.h" +#include "cmStringReplaceHelper.h" #include "cmSystemTools.h" #include "cmXMLWriter.h" @@ -246,13 +248,11 @@ void cmCTestBuildHandler::PopulateCustomVectors(cmMakefile* mf) // Record the user-specified custom warning rules. if (const char* customWarningMatchers = mf->GetDefinition("CTEST_CUSTOM_WARNING_MATCH")) { - cmSystemTools::ExpandListArgument(customWarningMatchers, - this->ReallyCustomWarningMatches); + cmExpandList(customWarningMatchers, this->ReallyCustomWarningMatches); } if (const char* customWarningExceptions = mf->GetDefinition("CTEST_CUSTOM_WARNING_EXCEPTION")) { - cmSystemTools::ExpandListArgument(customWarningExceptions, - this->ReallyCustomWarningExceptions); + cmExpandList(customWarningExceptions, this->ReallyCustomWarningExceptions); } } @@ -327,7 +327,7 @@ int cmCTestBuildHandler::ProcessHandler() std::string const& useLaunchers = this->CTest->GetCTestConfiguration("UseLaunchers"); - this->UseCTestLaunch = cmSystemTools::IsOn(useLaunchers); + this->UseCTestLaunch = cmIsOn(useLaunchers); // Create a last build log cmGeneratedFileStream ofs; @@ -384,11 +384,8 @@ int cmCTestBuildHandler::ProcessHandler() if (this->CTest->GetCTestConfiguration("SourceDirectory").size() > 20) { std::string srcdir = this->CTest->GetCTestConfiguration("SourceDirectory") + "/"; - std::string srcdirrep; for (cc = srcdir.size() - 2; cc > 0; cc--) { if (srcdir[cc] == '/') { - srcdirrep = srcdir.substr(cc); - srcdirrep = "/..." + srcdirrep; srcdir = srcdir.substr(0, cc + 1); break; } @@ -398,11 +395,8 @@ int cmCTestBuildHandler::ProcessHandler() if (this->CTest->GetCTestConfiguration("BuildDirectory").size() > 20) { std::string bindir = this->CTest->GetCTestConfiguration("BuildDirectory") + "/"; - std::string bindirrep; for (cc = bindir.size() - 2; cc > 0; cc--) { if (bindir[cc] == '/') { - bindirrep = bindir.substr(cc); - bindirrep = "/..." + bindirrep; bindir = bindir.substr(0, cc + 1); break; } @@ -415,6 +409,9 @@ int cmCTestBuildHandler::ProcessHandler() // Remember start build time this->StartBuild = this->CTest->CurrentTime(); this->StartBuildTime = std::chrono::system_clock::now(); + + cmStringReplaceHelper colorRemover("\x1b\\[[0-9;]*m", "", nullptr); + this->ColorRemover = &colorRemover; int retVal = 0; int res = cmsysProcess_State_Exited; if (!this->CTest->GetShowOnly()) { @@ -572,8 +569,7 @@ void cmCTestBuildHandler::GenerateXMLLogScraped(cmXMLWriter& xml) std::string srcdir = this->CTest->GetCTestConfiguration("SourceDirectory"); // make sure the source dir is in the correct case on windows // via a call to collapse full path. - srcdir = cmSystemTools::CollapseFullPath(srcdir); - srcdir += "/"; + srcdir = cmStrCat(cmSystemTools::CollapseFullPath(srcdir), '/'); for (it = ew.begin(); it != ew.end() && (numErrorsAllowed || numWarningsAllowed); it++) { cmCTestBuildErrorWarning* cm = &(*it); @@ -704,10 +700,8 @@ cmCTestBuildHandler::LaunchHelper::LaunchHelper(cmCTestBuildHandler* handler) } else { // Compute a directory in which to store launcher fragments. std::string& launchDir = this->Handler->CTestLaunchDir; - launchDir = this->CTest->GetBinaryDir(); - launchDir += "/Testing/"; - launchDir += tag; - launchDir += "/Build"; + launchDir = + cmStrCat(this->CTest->GetBinaryDir(), "/Testing/", tag, "/Build"); // Clean out any existing launcher fragments. cmSystemTools::RemoveADirectory(launchDir); @@ -716,8 +710,7 @@ cmCTestBuildHandler::LaunchHelper::LaunchHelper(cmCTestBuildHandler* handler) // Enable launcher fragments. cmSystemTools::MakeDirectory(launchDir); this->WriteLauncherConfig(); - std::string launchEnv = "CTEST_LAUNCH_LOGS="; - launchEnv += launchDir; + std::string launchEnv = cmStrCat("CTEST_LAUNCH_LOGS=", launchDir); cmSystemTools::PutEnv(launchEnv); } } @@ -743,8 +736,8 @@ void cmCTestBuildHandler::LaunchHelper::WriteLauncherConfig() this->Handler->ReallyCustomWarningExceptions); // Give some testing configuration information to the launcher. - std::string fname = this->Handler->CTestLaunchDir; - fname += "/CTestLaunchConfig.cmake"; + std::string fname = + cmStrCat(this->Handler->CTestLaunchDir, "/CTestLaunchConfig.cmake"); cmGeneratedFileStream fout(fname); std::string srcdir = this->CTest->GetCTestConfiguration("SourceDirectory"); fout << "set(CTEST_SOURCE_DIRECTORY \"" << srcdir << "\")\n"; @@ -756,10 +749,8 @@ void cmCTestBuildHandler::LaunchHelper::WriteScrapeMatchers( if (matchers.empty()) { return; } - std::string fname = this->Handler->CTestLaunchDir; - fname += "/Custom"; - fname += purpose; - fname += ".txt"; + std::string fname = + cmStrCat(this->Handler->CTestLaunchDir, "/Custom", purpose, ".txt"); cmGeneratedFileStream fout(fname); for (std::string const& m : matchers) { fout << m << "\n"; @@ -898,9 +889,8 @@ int cmCTestBuildHandler::RunMakeCommand(const std::string& command, // dashboard. cmCTestBuildErrorWarning errorwarning; errorwarning.LogLine = 1; - errorwarning.Text = - "*** WARNING non-zero return value in ctest from: "; - errorwarning.Text += argv[0]; + errorwarning.Text = cmStrCat( + "*** WARNING non-zero return value in ctest from: ", argv[0]); errorwarning.PreContext.clear(); errorwarning.PostContext.clear(); errorwarning.Error = false; @@ -922,8 +912,8 @@ int cmCTestBuildHandler::RunMakeCommand(const std::string& command, // If there was an error running command, report that on the dashboard. cmCTestBuildErrorWarning errorwarning; errorwarning.LogLine = 1; - errorwarning.Text = "*** ERROR executing: "; - errorwarning.Text += cmsysProcess_GetErrorString(cp); + errorwarning.Text = + cmStrCat("*** ERROR executing: ", cmsysProcess_GetErrorString(cp)); errorwarning.PreContext.clear(); errorwarning.PostContext.clear(); errorwarning.Error = true; @@ -1084,7 +1074,12 @@ int cmCTestBuildHandler::ProcessSingleLine(const char* data) return b_REGULAR_LINE; } - cmCTestOptionalLog(this->CTest, DEBUG, "Line: [" << data << "]" << std::endl, + // Ignore ANSI color codes when checking for errors and warnings. + std::string input(data); + std::string line; + this->ColorRemover->Replace(input, line); + + cmCTestOptionalLog(this->CTest, DEBUG, "Line: [" << line << "]" << std::endl, this->Quiet); int warningLine = 0; @@ -1096,10 +1091,10 @@ int cmCTestBuildHandler::ProcessSingleLine(const char* data) // Errors int wrxCnt = 0; for (cmsys::RegularExpression& rx : this->ErrorMatchRegex) { - if (rx.find(data)) { + if (rx.find(line.c_str())) { errorLine = 1; cmCTestOptionalLog(this->CTest, DEBUG, - " Error Line: " << data << " (matches: " + " Error Line: " << line << " (matches: " << this->CustomErrorMatches[wrxCnt] << ")" << std::endl, this->Quiet); @@ -1110,11 +1105,11 @@ int cmCTestBuildHandler::ProcessSingleLine(const char* data) // Error exceptions wrxCnt = 0; for (cmsys::RegularExpression& rx : this->ErrorExceptionRegex) { - if (rx.find(data)) { + if (rx.find(line.c_str())) { errorLine = 0; cmCTestOptionalLog(this->CTest, DEBUG, " Not an error Line: " - << data << " (matches: " + << line << " (matches: " << this->CustomErrorExceptions[wrxCnt] << ")" << std::endl, this->Quiet); @@ -1127,11 +1122,11 @@ int cmCTestBuildHandler::ProcessSingleLine(const char* data) // Warnings int wrxCnt = 0; for (cmsys::RegularExpression& rx : this->WarningMatchRegex) { - if (rx.find(data)) { + if (rx.find(line.c_str())) { warningLine = 1; cmCTestOptionalLog(this->CTest, DEBUG, " Warning Line: " - << data << " (matches: " + << line << " (matches: " << this->CustomWarningMatches[wrxCnt] << ")" << std::endl, this->Quiet); @@ -1143,11 +1138,11 @@ int cmCTestBuildHandler::ProcessSingleLine(const char* data) wrxCnt = 0; // Warning exceptions for (cmsys::RegularExpression& rx : this->WarningExceptionRegex) { - if (rx.find(data)) { + if (rx.find(line.c_str())) { warningLine = 0; cmCTestOptionalLog(this->CTest, DEBUG, " Not a warning Line: " - << data << " (matches: " + << line << " (matches: " << this->CustomWarningExceptions[wrxCnt] << ")" << std::endl, this->Quiet); diff --git a/Source/CTest/cmCTestBuildHandler.h b/Source/CTest/cmCTestBuildHandler.h index 722c590..87f1534 100644 --- a/Source/CTest/cmCTestBuildHandler.h +++ b/Source/CTest/cmCTestBuildHandler.h @@ -18,6 +18,7 @@ #include <vector> class cmMakefile; +class cmStringReplaceHelper; class cmXMLWriter; /** \class cmCTestBuildHandler @@ -143,6 +144,9 @@ private: int MaxErrors; int MaxWarnings; + // Used to remove ANSI color codes before checking for errors and warnings. + cmStringReplaceHelper* ColorRemover; + bool UseCTestLaunch; std::string CTestLaunchDir; class LaunchHelper; diff --git a/Source/CTest/cmCTestCVS.cxx b/Source/CTest/cmCTestCVS.cxx index 9c03839..560c169 100644 --- a/Source/CTest/cmCTestCVS.cxx +++ b/Source/CTest/cmCTestCVS.cxx @@ -4,8 +4,10 @@ #include "cmCTest.h" #include "cmProcessTools.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmXMLWriter.h" +#include "cm_string_view.hxx" #include "cmsys/FStream.hxx" #include "cmsys/RegularExpression.hxx" @@ -204,8 +206,7 @@ std::string cmCTestCVS::ComputeBranchFlag(std::string const& dir) if (tagStream && cmSystemTools::GetLineFromStream(tagStream, tagLine) && tagLine.size() > 1 && tagLine[0] == 'T') { // Use the branch specified in the tag file. - std::string flag = "-r"; - flag += tagLine.substr(1); + std::string flag = cmStrCat("-r", cm::string_view(tagLine).substr(1)); return flag; } // Use the default branch. diff --git a/Source/CTest/cmCTestConfigureCommand.cxx b/Source/CTest/cmCTestConfigureCommand.cxx index 74a932a..320c184 100644 --- a/Source/CTest/cmCTestConfigureCommand.cxx +++ b/Source/CTest/cmCTestConfigureCommand.cxx @@ -6,6 +6,7 @@ #include "cmCTestConfigureHandler.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmake.h" @@ -25,7 +26,7 @@ cmCTestGenericHandler* cmCTestConfigureCommand::InitializeHandler() std::vector<std::string> options; if (this->Values[ctc_OPTIONS]) { - cmSystemTools::ExpandListArgument(this->Values[ctc_OPTIONS], options); + cmExpandList(this->Values[ctc_OPTIONS], options); } if (this->CTest->GetCTestConfiguration("BuildDirectory").empty()) { @@ -75,9 +76,8 @@ cmCTestGenericHandler* cmCTestConfigureCommand::InitializeHandler() delete gg; } - std::string cmakeConfigureCommand = "\""; - cmakeConfigureCommand += cmSystemTools::GetCMakeCommand(); - cmakeConfigureCommand += "\""; + std::string cmakeConfigureCommand = + cmStrCat('"', cmSystemTools::GetCMakeCommand(), '"'); for (std::string const& option : options) { cmakeConfigureCommand += " \""; diff --git a/Source/CTest/cmCTestConfigureCommand.h b/Source/CTest/cmCTestConfigureCommand.h index 0cbcbfa..4677c83 100644 --- a/Source/CTest/cmCTestConfigureCommand.h +++ b/Source/CTest/cmCTestConfigureCommand.h @@ -6,11 +6,14 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cmCTestHandlerCommand.h" +#include "cmCommand.h" #include <string> +#include <utility> + +#include "cm_memory.hxx" class cmCTestGenericHandler; -class cmCommand; /** \class cmCTestConfigure * \brief Run a ctest script @@ -25,12 +28,12 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override + std::unique_ptr<cmCommand> Clone() override { - cmCTestConfigureCommand* ni = new cmCTestConfigureCommand; + auto ni = cm::make_unique<cmCTestConfigureCommand>(); ni->CTest = this->CTest; ni->CTestScriptHandler = this->CTestScriptHandler; - return ni; + return std::unique_ptr<cmCommand>(std::move(ni)); } /** diff --git a/Source/CTest/cmCTestCoverageCommand.h b/Source/CTest/cmCTestCoverageCommand.h index 1ae2d86..08f31f7 100644 --- a/Source/CTest/cmCTestCoverageCommand.h +++ b/Source/CTest/cmCTestCoverageCommand.h @@ -6,12 +6,15 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cmCTestHandlerCommand.h" +#include "cmCommand.h" #include <set> #include <string> +#include <utility> + +#include "cm_memory.hxx" class cmCTestGenericHandler; -class cmCommand; /** \class cmCTestCoverage * \brief Run a ctest script @@ -26,12 +29,12 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override + std::unique_ptr<cmCommand> Clone() override { - cmCTestCoverageCommand* ni = new cmCTestCoverageCommand; + auto ni = cm::make_unique<cmCTestCoverageCommand>(); ni->CTest = this->CTest; ni->CTestScriptHandler = this->CTestScriptHandler; - return ni; + return std::unique_ptr<cmCommand>(std::move(ni)); } /** diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx index f6028c4..772fa47 100644 --- a/Source/CTest/cmCTestCoverageHandler.cxx +++ b/Source/CTest/cmCTestCoverageHandler.cxx @@ -13,6 +13,7 @@ #include "cmParseGTMCoverage.h" #include "cmParseJacocoCoverage.h" #include "cmParsePHPCoverage.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmWorkingDirectory.h" #include "cmXMLWriter.h" @@ -129,10 +130,9 @@ void cmCTestCoverageHandler::Initialize() void cmCTestCoverageHandler::CleanCoverageLogFiles(std::ostream& log) { - std::string logGlob = this->CTest->GetCTestConfiguration("BuildDirectory"); - logGlob += "/Testing/"; - logGlob += this->CTest->GetCurrentTag(); - logGlob += "/CoverageLog*"; + std::string logGlob = + cmStrCat(this->CTest->GetCTestConfiguration("BuildDirectory"), "/Testing/", + this->CTest->GetCurrentTag(), "/CoverageLog*"); cmsys::Glob gl; gl.FindFiles(logGlob); std::vector<std::string> const& files = gl.GetFiles(); @@ -1181,7 +1181,7 @@ int cmCTestCoverageHandler::HandleGCovCoverage( // gcov 4.7 can have output lines saying "No executable lines" and // "Removing 'filename.gcov'"... Don't log those as "errors." if (line != "No executable lines" && - !cmSystemTools::StringStartsWith(line.c_str(), "Removing ")) { + !cmHasLiteralPrefix(line, "Removing ")) { cmCTestLog(this->CTest, ERROR_MESSAGE, "Unknown gcov output line: [" << line << "]" << std::endl); @@ -1455,8 +1455,7 @@ int cmCTestCoverageHandler::HandleLCovCoverage( std::vector<std::string> lcovFiles; dir = this->CTest->GetBinaryDir(); std::string daGlob; - daGlob = dir; - daGlob += "/*.LCOV"; + daGlob = cmStrCat(dir, "/*.LCOV"); cmCTestOptionalLog( this->CTest, HANDLER_VERBOSE_OUTPUT, " looking for LCOV files in: " << daGlob << std::endl, this->Quiet); @@ -1597,12 +1596,10 @@ void cmCTestCoverageHandler::FindGCovFiles(std::vector<std::string>& files) cmCTestOptionalLog( this->CTest, HANDLER_VERBOSE_OUTPUT, " globbing for coverage in: " << lm.first << std::endl, this->Quiet); - std::string daGlob = lm.first; - daGlob += "/*.da"; + std::string daGlob = cmStrCat(lm.first, "/*.da"); gl.FindFiles(daGlob); cmAppend(files, gl.GetFiles()); - daGlob = lm.first; - daGlob += "/*.gcda"; + daGlob = cmStrCat(lm.first, "/*.gcda"); gl.FindFiles(daGlob); cmAppend(files, gl.GetFiles()); } @@ -1631,8 +1628,7 @@ bool cmCTestCoverageHandler::FindLCovFiles(std::vector<std::string>& files) // DPI file should appear in build directory std::string daGlob; - daGlob = buildDir; - daGlob += "/*.dpi"; + daGlob = cmStrCat(buildDir, "/*.dpi"); cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " looking for dpi files in: " << daGlob << std::endl, this->Quiet); @@ -1945,10 +1941,9 @@ int cmCTestCoverageHandler::RunBullseyeCommand( cmCTestRunProcess runCoverageSrc; runCoverageSrc.SetCommand(program.c_str()); runCoverageSrc.AddArgument(arg); - std::string stdoutFile = cont->BinaryDir + "/Testing/Temporary/"; - stdoutFile += this->GetCTestInstance()->GetCurrentTag(); - stdoutFile += "-"; - stdoutFile += cmd; + std::string stdoutFile = + cmStrCat(cont->BinaryDir, "/Testing/Temporary/", + this->GetCTestInstance()->GetCurrentTag(), '-', cmd); std::string stderrFile = stdoutFile; stdoutFile += ".stdout"; stderrFile += ".stderr"; @@ -2037,9 +2032,7 @@ int cmCTestCoverageHandler::RunBullseyeSourceSummary( coveredFileNames.insert(file); if (!cmSystemTools::FileIsFullPath(sourceFile)) { // file will be relative to the binary dir - file = cont->BinaryDir; - file += "/"; - file += sourceFile; + file = cmStrCat(cont->BinaryDir, '/', sourceFile); } file = cmSystemTools::CollapseFullPath(file); bool shouldIDoCoverage = @@ -2221,9 +2214,8 @@ int cmCTestCoverageHandler::GetLabelId(std::string const& label) void cmCTestCoverageHandler::LoadLabels() { - std::string fileList = this->CTest->GetBinaryDir(); - fileList += "/CMakeFiles"; - fileList += "/TargetDirectories.txt"; + std::string fileList = + cmStrCat(this->CTest->GetBinaryDir(), "/CMakeFiles/TargetDirectories.txt"); cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " target directory list [" << fileList << "]\n", this->Quiet); @@ -2237,8 +2229,7 @@ void cmCTestCoverageHandler::LoadLabels() void cmCTestCoverageHandler::LoadLabels(const char* dir) { LabelSet& dirLabels = this->TargetDirs[dir]; - std::string fname = dir; - fname += "/Labels.txt"; + std::string fname = cmStrCat(dir, "/Labels.txt"); cmsys::ifstream fin(fname.c_str()); if (!fin) { return; diff --git a/Source/CTest/cmCTestCurl.cxx b/Source/CTest/cmCTestCurl.cxx index cc63e45..40f5918 100644 --- a/Source/CTest/cmCTestCurl.cxx +++ b/Source/CTest/cmCTestCurl.cxx @@ -5,6 +5,7 @@ #include "cmAlgorithms.h" #include "cmCTest.h" #include "cmCurl.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include <ostream> @@ -127,9 +128,7 @@ bool cmCTestCurl::UploadFile(std::string const& local_file, return false; } // set the url - std::string upload_url = url; - upload_url += "?"; - upload_url += fields; + std::string upload_url = cmStrCat(url, '?', fields); ::curl_easy_setopt(this->Curl, CURLOPT_URL, upload_url.c_str()); // now specify which file to upload ::curl_easy_setopt(this->Curl, CURLOPT_INFILE, ftpfile); diff --git a/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h b/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h index 9425ece..84250cb 100644 --- a/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h +++ b/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h @@ -6,11 +6,14 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cmCTestCommand.h" +#include "cmCommand.h" #include <string> +#include <utility> #include <vector> -class cmCommand; +#include "cm_memory.hxx" + class cmExecutionStatus; /** \class cmCTestEmptyBinaryDirectory @@ -27,13 +30,12 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override + std::unique_ptr<cmCommand> Clone() override { - cmCTestEmptyBinaryDirectoryCommand* ni = - new cmCTestEmptyBinaryDirectoryCommand; + auto ni = cm::make_unique<cmCTestEmptyBinaryDirectoryCommand>(); ni->CTest = this->CTest; ni->CTestScriptHandler = this->CTestScriptHandler; - return ni; + return std::unique_ptr<cmCommand>(std::move(ni)); } /** diff --git a/Source/CTest/cmCTestGIT.cxx b/Source/CTest/cmCTestGIT.cxx index 9d9761c..f7319ef 100644 --- a/Source/CTest/cmCTestGIT.cxx +++ b/Source/CTest/cmCTestGIT.cxx @@ -10,11 +10,11 @@ #include <time.h> #include <vector> -#include "cmAlgorithms.h" #include "cmCTest.h" #include "cmCTestVC.h" #include "cmProcessOutput.h" #include "cmProcessTools.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" static unsigned int cmCTestGITVersion(unsigned int epic, unsigned int major, @@ -111,8 +111,8 @@ std::string cmCTestGIT::FindGitDir() else if (git_dir[0] == '/') { // Cygwin Git reports a full path that Cygwin understands, but we // are a Windows application. Run "cygpath" to get Windows path. - std::string cygpath_exe = cmSystemTools::GetFilenamePath(git); - cygpath_exe += "/cygpath.exe"; + 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 }; @@ -211,8 +211,7 @@ bool cmCTestGIT::UpdateByFetchAndReset() bool cmCTestGIT::UpdateByCustom(std::string const& custom) { - std::vector<std::string> git_custom_command; - cmSystemTools::ExpandListArgument(custom, git_custom_command, true); + std::vector<std::string> git_custom_command = cmExpandedList(custom, true); std::vector<char const*> git_custom; git_custom.reserve(git_custom_command.size() + 1); for (std::string const& i : git_custom_command) { @@ -270,7 +269,7 @@ bool cmCTestGIT::UpdateImpl() std::string init_submodules = this->CTest->GetCTestConfiguration("GITInitSubmodules"); - if (cmSystemTools::IsOn(init_submodules)) { + if (cmIsOn(init_submodules)) { char const* git_submodule_init[] = { git, "submodule", "init", nullptr }; ret = this->RunChild(git_submodule_init, &submodule_out, &submodule_err, top_dir.c_str()); diff --git a/Source/CTest/cmCTestHandlerCommand.cxx b/Source/CTest/cmCTestHandlerCommand.cxx index adf9553..6add717 100644 --- a/Source/CTest/cmCTestHandlerCommand.cxx +++ b/Source/CTest/cmCTestHandlerCommand.cxx @@ -4,6 +4,7 @@ #include "cmCTest.h" #include "cmCTestGenericHandler.h" +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmSystemTools.h" @@ -13,8 +14,6 @@ #include <sstream> #include <stdlib.h> -class cmExecutionStatus; - cmCTestHandlerCommand::cmCTestHandlerCommand() { const size_t INIT_SIZE = 100; @@ -86,7 +85,7 @@ private: } bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& /*unused*/) + cmExecutionStatus& status) { // save error state and restore it if needed SaveRestoreErrorState errorState; @@ -113,20 +112,20 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args, foundBadArgument = true; } } - bool capureCMakeError = (this->Values[ct_CAPTURE_CMAKE_ERROR] && - *this->Values[ct_CAPTURE_CMAKE_ERROR]); + bool captureCMakeError = (this->Values[ct_CAPTURE_CMAKE_ERROR] && + *this->Values[ct_CAPTURE_CMAKE_ERROR]); // now that arguments are parsed check to see if there is a // CAPTURE_CMAKE_ERROR specified let the errorState object know. - if (capureCMakeError) { + if (captureCMakeError) { errorState.CaptureCMakeError(); } // if we found a bad argument then exit before running command if (foundBadArgument) { // store the cmake error - if (capureCMakeError) { + if (captureCMakeError) { this->Makefile->AddDefinition(this->Values[ct_CAPTURE_CMAKE_ERROR], "-1"); - std::string const err = this->GetName() + " " + this->GetError(); + std::string const err = this->GetName() + " " + status.GetError(); if (!cmSystemTools::FindLastString(err.c_str(), "unknown error.")) { cmCTestLog(this->CTest, ERROR_MESSAGE, err << " error from command\n"); } @@ -192,11 +191,11 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args, cmCTestLog(this->CTest, ERROR_MESSAGE, "Cannot instantiate test handler " << this->GetName() << std::endl); - if (capureCMakeError) { + if (captureCMakeError) { this->Makefile->AddDefinition(this->Values[ct_CAPTURE_CMAKE_ERROR], "-1"); - const char* err = this->GetError(); - if (err && !cmSystemTools::FindLastString(err, "unknown error.")) { + std::string const& err = status.GetError(); + if (!cmSystemTools::FindLastString(err.c_str(), "unknown error.")) { cmCTestLog(this->CTest, ERROR_MESSAGE, err << " error from command\n"); } return true; @@ -216,11 +215,11 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args, this->SetError("failed to change directory to " + this->CTest->GetCTestConfiguration("BuildDirectory") + " : " + std::strerror(workdir.GetLastResult())); - if (capureCMakeError) { + if (captureCMakeError) { this->Makefile->AddDefinition(this->Values[ct_CAPTURE_CMAKE_ERROR], "-1"); cmCTestLog(this->CTest, ERROR_MESSAGE, - this->GetName() << " " << this->GetError() << "\n"); + this->GetName() << " " << status.GetError() << "\n"); // return success because failure is recorded in CAPTURE_CMAKE_ERROR return true; } @@ -229,21 +228,19 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args, int res = handler->ProcessHandler(); if (this->Values[ct_RETURN_VALUE] && *this->Values[ct_RETURN_VALUE]) { - std::ostringstream str; - str << res; this->Makefile->AddDefinition(this->Values[ct_RETURN_VALUE], - str.str().c_str()); + std::to_string(res)); } this->ProcessAdditionalValues(handler); // log the error message if there was an error - if (capureCMakeError) { + if (captureCMakeError) { const char* returnString = "0"; if (cmSystemTools::GetErrorOccuredFlag()) { returnString = "-1"; - const char* err = this->GetError(); + std::string const& err = status.GetError(); // print out the error if it is not "unknown error" which means // there was no message - if (err && !cmSystemTools::FindLastString(err, "unknown error.")) { + if (!cmSystemTools::FindLastString(err.c_str(), "unknown error.")) { cmCTestLog(this->CTest, ERROR_MESSAGE, err); } } diff --git a/Source/CTest/cmCTestLaunch.cxx b/Source/CTest/cmCTestLaunch.cxx index a96513e..ac52581 100644 --- a/Source/CTest/cmCTestLaunch.cxx +++ b/Source/CTest/cmCTestLaunch.cxx @@ -6,7 +6,6 @@ #include "cmsys/Process.h" #include "cmsys/RegularExpression.hxx" #include <iostream> -#include <memory> // IWYU pragma: keep #include <stdlib.h> #include <string.h> @@ -17,6 +16,7 @@ #include "cmProcessOutput.h" #include "cmState.h" #include "cmStateSnapshot.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmXMLWriter.h" #include "cmake.h" @@ -176,14 +176,8 @@ void cmCTestLaunch::ComputeFileNames() 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() @@ -282,11 +276,8 @@ void cmCTestLaunch::LoadLabels() } // Labels are listed in per-target files. - std::string fname = this->OptionBuildDir; - fname += "/CMakeFiles"; - 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; @@ -340,10 +331,9 @@ 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); @@ -494,9 +484,9 @@ void cmCTestLaunch::DumpFileToXML(cmXMLElement& e3, const char* tag, continue; } if (this->Match(line, this->RegexWarningSuppress)) { - line = "[CTest: warning suppressed] " + line; + line = cmStrCat("[CTest: warning suppressed] ", line); } else if (this->Match(line, this->RegexWarning)) { - line = "[CTest: warning matched] " + line; + line = cmStrCat("[CTest: warning matched] ", line); } e4.Content(sep); e4.Content(line); @@ -546,10 +536,7 @@ 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; @@ -595,7 +582,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[]) @@ -617,8 +604,7 @@ void cmCTestLaunch::LoadConfig() cm.GetCurrentSnapshot().SetDefaultDefinitions(); cmGlobalGenerator gg(&cm); cmMakefile mf(&gg, cm.GetCurrentSnapshot()); - std::string fname = this->LogDir; - fname += "CTestLaunchConfig.cmake"; + 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); diff --git a/Source/CTest/cmCTestMemCheckCommand.cxx b/Source/CTest/cmCTestMemCheckCommand.cxx index 7dad1ce..804efa5 100644 --- a/Source/CTest/cmCTestMemCheckCommand.cxx +++ b/Source/CTest/cmCTestMemCheckCommand.cxx @@ -2,7 +2,6 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCTestMemCheckCommand.h" -#include <sstream> #include <string> #include <vector> @@ -45,9 +44,9 @@ void cmCTestMemCheckCommand::ProcessAdditionalValues( cmCTestGenericHandler* handler) { if (this->Values[ctm_DEFECT_COUNT] && *this->Values[ctm_DEFECT_COUNT]) { - std::ostringstream str; - str << static_cast<cmCTestMemCheckHandler*>(handler)->GetDefectCount(); - this->Makefile->AddDefinition(this->Values[ctm_DEFECT_COUNT], - str.str().c_str()); + this->Makefile->AddDefinition( + this->Values[ctm_DEFECT_COUNT], + std::to_string( + static_cast<cmCTestMemCheckHandler*>(handler)->GetDefectCount())); } } diff --git a/Source/CTest/cmCTestMemCheckCommand.h b/Source/CTest/cmCTestMemCheckCommand.h index b6b3c40..837a687 100644 --- a/Source/CTest/cmCTestMemCheckCommand.h +++ b/Source/CTest/cmCTestMemCheckCommand.h @@ -5,10 +5,14 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include <utility> + +#include "cm_memory.hxx" + #include "cmCTestTestCommand.h" +#include "cmCommand.h" class cmCTestGenericHandler; -class cmCommand; /** \class cmCTestMemCheck * \brief Run a ctest script @@ -23,12 +27,12 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override + std::unique_ptr<cmCommand> Clone() override { - cmCTestMemCheckCommand* ni = new cmCTestMemCheckCommand; + auto ni = cm::make_unique<cmCTestMemCheckCommand>(); ni->CTest = this->CTest; ni->CTestScriptHandler = this->CTestScriptHandler; - return ni; + return std::unique_ptr<cmCommand>(std::move(ni)); } protected: diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx index b09e7bb..259240f 100644 --- a/Source/CTest/cmCTestMemCheckHandler.cxx +++ b/Source/CTest/cmCTestMemCheckHandler.cxx @@ -1074,10 +1074,7 @@ void cmCTestMemCheckHandler::AppendMemTesterOutput(cmCTestTestResult& res, void cmCTestMemCheckHandler::TestOutputFileNames( int test, std::vector<std::string>& files) { - std::string index; - std::ostringstream stream; - stream << test; - index = stream.str(); + std::string index = std::to_string(test); std::string ofile = this->MemoryTesterOutputFile; std::string::size_type pos = ofile.find("??"); ofile.replace(pos, 2, index); diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx index 1b71f2a..af1980a 100644 --- a/Source/CTest/cmCTestMultiProcessHandler.cxx +++ b/Source/CTest/cmCTestMultiProcessHandler.cxx @@ -10,6 +10,7 @@ #include "cmDuration.h" #include "cmListFileCache.h" #include "cmRange.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmWorkingDirectory.h" @@ -29,11 +30,13 @@ #include <iostream> #include <list> #include <math.h> +#include <memory> #include <sstream> #include <stack> #include <stdlib.h> #include <unordered_map> #include <utility> +#include <vector> namespace cmsys { class RegularExpression; @@ -108,8 +111,7 @@ void cmCTestMultiProcessHandler::SetTestLoad(unsigned long load) std::string fake_load_value; if (cmSystemTools::GetEnv("__CTEST_FAKE_LOAD_AVERAGE_FOR_TESTING", fake_load_value)) { - if (!cmSystemTools::StringToULong(fake_load_value.c_str(), - &this->FakeLoadForTesting)) { + if (!cmStrToULong(fake_load_value, &this->FakeLoadForTesting)) { cmSystemTools::Error("Failed to parse fake load value: " + fake_load_value); } @@ -171,8 +173,7 @@ bool cmCTestMultiProcessHandler::StartTestProcess(int test) // Find any failed dependencies for this test. We assume the more common // scenario has no failed tests, so make it the outer loop. for (std::string const& f : *this->Failed) { - if (this->Properties[test]->RequireSuccessDepends.find(f) != - this->Properties[test]->RequireSuccessDepends.end()) { + if (cmContains(this->Properties[test]->RequireSuccessDepends, f)) { testRun->AddFailedDependency(f); } } @@ -188,10 +189,13 @@ bool cmCTestMultiProcessHandler::StartTestProcess(int test) std::strerror(workdir.GetLastResult())); } else { if (testRun->StartTest(this->Completed, this->Total)) { + // Ownership of 'testRun' has moved to another structure. + // When the test finishes, FinishTestProcess will be called. return true; } } + // Pass ownership of 'testRun'. this->FinishTestProcess(testRun, false); return false; } @@ -273,7 +277,7 @@ bool cmCTestMultiProcessHandler::StartTest(int test) { // Check for locked resources for (std::string const& i : this->Properties[test]->LockedResources) { - if (this->LockedResources.find(i) != this->LockedResources.end()) { + if (cmContains(this->LockedResources, i)) { return false; } } @@ -619,9 +623,7 @@ void cmCTestMultiProcessHandler::CreateParallelTestCostList() // In parallel test runs add previously failed tests to the front // of the cost list and queue other tests for further sorting for (auto const& t : this->Tests) { - if (std::find(this->LastTestsFailed.begin(), this->LastTestsFailed.end(), - this->Properties[t.first]->Name) != - this->LastTestsFailed.end()) { + if (cmContains(this->LastTestsFailed, this->Properties[t.first]->Name)) { // If the test failed last time, it should be run first. this->SortedTests.push_back(t.first); alreadySortedTests.insert(t.first); @@ -660,7 +662,7 @@ void cmCTestMultiProcessHandler::CreateParallelTestCostList() TestComparator(this)); for (auto const& j : sortedCopy) { - if (alreadySortedTests.find(j) == alreadySortedTests.end()) { + if (!cmContains(alreadySortedTests, j)) { this->SortedTests.push_back(j); alreadySortedTests.insert(j); } @@ -692,7 +694,7 @@ void cmCTestMultiProcessHandler::CreateSerialTestCostList() TestSet alreadySortedTests; for (int test : presortedList) { - if (alreadySortedTests.find(test) != alreadySortedTests.end()) { + if (cmContains(alreadySortedTests, test)) { continue; } @@ -700,8 +702,7 @@ void cmCTestMultiProcessHandler::CreateSerialTestCostList() GetAllTestDependencies(test, dependencies); for (int testDependency : dependencies) { - if (alreadySortedTests.find(testDependency) == - alreadySortedTests.end()) { + if (!cmContains(alreadySortedTests, testDependency)) { alreadySortedTests.insert(testDependency); this->SortedTests.push_back(testDependency); } @@ -821,6 +822,11 @@ static Json::Value DumpCTestProperties( "FAIL_REGULAR_EXPRESSION", DumpRegExToJsonArray(testProperties.ErrorRegularExpressions))); } + if (!testProperties.SkipRegularExpressions.empty()) { + properties.append(DumpCTestProperty( + "SKIP_REGULAR_EXPRESSION", + DumpRegExToJsonArray(testProperties.SkipRegularExpressions))); + } if (!testProperties.FixturesCleanup.empty()) { properties.append(DumpCTestProperty( "FIXTURES_CLEANUP", DumpToJsonArray(testProperties.FixturesCleanup))); diff --git a/Source/CTest/cmCTestP4.cxx b/Source/CTest/cmCTestP4.cxx index 2eb8dba..64354e8 100644 --- a/Source/CTest/cmCTestP4.cxx +++ b/Source/CTest/cmCTestP4.cxx @@ -7,6 +7,7 @@ #include "cmCTestVC.h" #include "cmProcessTools.h" #include "cmRange.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmsys/RegularExpression.hxx" @@ -459,8 +460,7 @@ bool cmCTestP4::LoadModifications() bool cmCTestP4::UpdateCustom(const std::string& custom) { - std::vector<std::string> p4_custom_command; - cmSystemTools::ExpandListArgument(custom, p4_custom_command, true); + std::vector<std::string> p4_custom_command = cmExpandedList(custom, true); std::vector<char const*> p4_custom; p4_custom.reserve(p4_custom_command.size() + 1); diff --git a/Source/CTest/cmCTestReadCustomFilesCommand.h b/Source/CTest/cmCTestReadCustomFilesCommand.h index ba25c51..db2ac5e 100644 --- a/Source/CTest/cmCTestReadCustomFilesCommand.h +++ b/Source/CTest/cmCTestReadCustomFilesCommand.h @@ -6,11 +6,14 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cmCTestCommand.h" +#include "cmCommand.h" #include <string> +#include <utility> #include <vector> -class cmCommand; +#include "cm_memory.hxx" + class cmExecutionStatus; /** \class cmCTestReadCustomFiles @@ -27,11 +30,11 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override + std::unique_ptr<cmCommand> Clone() override { - cmCTestReadCustomFilesCommand* ni = new cmCTestReadCustomFilesCommand; + auto ni = cm::make_unique<cmCTestReadCustomFilesCommand>(); ni->CTest = this->CTest; - return ni; + return std::unique_ptr<cmCommand>(std::move(ni)); } /** diff --git a/Source/CTest/cmCTestRunScriptCommand.cxx b/Source/CTest/cmCTestRunScriptCommand.cxx index a7e47d3..f59ca57 100644 --- a/Source/CTest/cmCTestRunScriptCommand.cxx +++ b/Source/CTest/cmCTestRunScriptCommand.cxx @@ -5,8 +5,6 @@ #include "cmCTestScriptHandler.h" #include "cmMakefile.h" -#include <sstream> - class cmExecutionStatus; bool cmCTestRunScriptCommand::InitialPass(std::vector<std::string> const& args, @@ -41,9 +39,7 @@ bool cmCTestRunScriptCommand::InitialPass(std::vector<std::string> const& args, int ret; cmCTestScriptHandler::RunScript(this->CTest, this->Makefile, args[i].c_str(), !np, &ret); - std::ostringstream str; - str << ret; - this->Makefile->AddDefinition(returnVariable, str.str().c_str()); + this->Makefile->AddDefinition(returnVariable, std::to_string(ret)); } } return true; diff --git a/Source/CTest/cmCTestRunScriptCommand.h b/Source/CTest/cmCTestRunScriptCommand.h index 9d8b4b5..6961f6e 100644 --- a/Source/CTest/cmCTestRunScriptCommand.h +++ b/Source/CTest/cmCTestRunScriptCommand.h @@ -6,11 +6,14 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cmCTestCommand.h" +#include "cmCommand.h" #include <string> +#include <utility> #include <vector> -class cmCommand; +#include "cm_memory.hxx" + class cmExecutionStatus; /** \class cmCTestRunScript @@ -27,12 +30,12 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override + std::unique_ptr<cmCommand> Clone() override { - cmCTestRunScriptCommand* ni = new cmCTestRunScriptCommand; + auto ni = cm::make_unique<cmCTestRunScriptCommand>(); ni->CTest = this->CTest; ni->CTestScriptHandler = this->CTestScriptHandler; - return ni; + return std::unique_ptr<cmCommand>(std::move(ni)); } /** diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx index 31976b9..23c6b0d 100644 --- a/Source/CTest/cmCTestRunTest.cxx +++ b/Source/CTest/cmCTestRunTest.cxx @@ -6,12 +6,12 @@ #include "cmCTestMemCheckHandler.h" #include "cmCTestMultiProcessHandler.h" #include "cmProcess.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmWorkingDirectory.h" #include "cmsys/RegularExpression.hxx" #include <chrono> -#include <cmAlgorithms.h> #include <cstdint> #include <cstring> #include <iomanip> @@ -20,6 +20,8 @@ #include <stdio.h> #include <utility> +#include "cm_memory.hxx" + cmCTestRunTest::cmCTestRunTest(cmCTestMultiProcessHandler& multiHandler) : MultiTestHandler(multiHandler) { @@ -76,6 +78,7 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started) } std::int64_t retVal = this->TestProcess->GetExitValue(); bool forceFail = false; + bool forceSkip = false; bool skipped = false; bool outputTestErrorsToConsole = false; if (!this->TestProperties->RequiredRegularExpressions.empty() && @@ -84,49 +87,62 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started) for (auto& pass : this->TestProperties->RequiredRegularExpressions) { if (pass.first.find(this->ProcessOutput)) { found = true; - reason = "Required regular expression found."; + reason = cmStrCat("Required regular expression found. Regex=[", + pass.second, ']'); break; } } if (!found) { - reason = "Required regular expression not found."; + reason = "Required regular expression not found. Regex=["; + for (auto& pass : this->TestProperties->RequiredRegularExpressions) { + reason += pass.second; + reason += "\n"; + } + reason += "]"; forceFail = true; } - reason += "Regex=["; - for (auto& pass : this->TestProperties->RequiredRegularExpressions) { - reason += pass.second; - reason += "\n"; - } - reason += "]"; } if (!this->TestProperties->ErrorRegularExpressions.empty() && this->FailedDependencies.empty()) { - for (auto& pass : this->TestProperties->ErrorRegularExpressions) { - if (pass.first.find(this->ProcessOutput)) { - reason = "Error regular expression found in output."; - reason += " Regex=["; - reason += pass.second; - reason += "]"; + for (auto& fail : this->TestProperties->ErrorRegularExpressions) { + if (fail.first.find(this->ProcessOutput)) { + reason = cmStrCat("Error regular expression found in output. Regex=[", + fail.second, ']'); forceFail = true; break; } } } + if (!this->TestProperties->SkipRegularExpressions.empty() && + this->FailedDependencies.empty()) { + for (auto& skip : this->TestProperties->SkipRegularExpressions) { + if (skip.first.find(this->ProcessOutput)) { + reason = cmStrCat("Skip regular expression found in output. Regex=[", + skip.second, ']'); + forceSkip = true; + break; + } + } + } std::ostringstream outputStream; if (res == cmProcess::State::Exited) { bool success = !forceFail && (retVal == 0 || !this->TestProperties->RequiredRegularExpressions.empty()); - if (this->TestProperties->SkipReturnCode >= 0 && - this->TestProperties->SkipReturnCode == retVal) { + if ((this->TestProperties->SkipReturnCode >= 0 && + this->TestProperties->SkipReturnCode == retVal) || + forceSkip) { this->TestResult.Status = cmCTestTestHandler::NOT_RUN; std::ostringstream s; - s << "SKIP_RETURN_CODE=" << this->TestProperties->SkipReturnCode; + if (forceSkip) { + s << "SKIP_REGULAR_EXPRESSION_MATCHED"; + } else { + s << "SKIP_RETURN_CODE=" << this->TestProperties->SkipReturnCode; + } this->TestResult.CompletionStatus = s.str(); cmCTestLog(this->CTest, HANDLER_OUTPUT, "***Skipped "); skipped = true; - } else if ((success && !this->TestProperties->WillFail) || - (!success && this->TestProperties->WillFail)) { + } else if (success != this->TestProperties->WillFail) { this->TestResult.Status = cmCTestTestHandler::COMPLETED; outputStream << " Passed "; } else { @@ -481,12 +497,11 @@ bool cmCTestRunTest::StartTest(size_t completed, size_t total) this->TestProcess = cm::make_unique<cmProcess>(*this); std::string msg; if (this->CTest->GetConfigType().empty()) { - msg = "Test not available without configuration."; - msg += " (Missing \"-C <config>\"?)"; + msg = "Test not available without configuration. (Missing \"-C " + "<config>\"?)"; } else { - msg = "Test not available in configuration \""; - msg += this->CTest->GetConfigType(); - msg += "\"."; + msg = cmStrCat("Test not available in configuration \"", + this->CTest->GetConfigType(), "\"."); } *this->TestHandler->LogFile << msg << std::endl; cmCTestLog(this->CTest, ERROR_MESSAGE, msg << std::endl); @@ -666,7 +681,7 @@ bool cmCTestRunTest::ForkProcess(cmDuration testTimeOut, bool explicitTimeout, this->TestProcess->SetTimeout(timeout); -#ifdef CMAKE_BUILD_WITH_CMAKE +#ifndef CMAKE_BOOTSTRAP cmSystemTools::SaveRestoreEnvironment sre; #endif diff --git a/Source/CTest/cmCTestRunTest.h b/Source/CTest/cmCTestRunTest.h index 38cc417..43dfe8e 100644 --- a/Source/CTest/cmCTestRunTest.h +++ b/Source/CTest/cmCTestRunTest.h @@ -5,6 +5,7 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include <memory> #include <set> #include <stddef.h> #include <string> @@ -12,7 +13,7 @@ #include "cmCTestTestHandler.h" #include "cmDuration.h" -#include "cmProcess.h" // IWYU pragma: keep (for unique_ptr) +#include "cmProcess.h" class cmCTest; class cmCTestMultiProcessHandler; diff --git a/Source/CTest/cmCTestSVN.cxx b/Source/CTest/cmCTestSVN.cxx index c834686..dc1472b 100644 --- a/Source/CTest/cmCTestSVN.cxx +++ b/Source/CTest/cmCTestSVN.cxx @@ -6,6 +6,7 @@ #include "cmCTest.h" #include "cmCTestVC.h" #include "cmProcessTools.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmXMLParser.h" #include "cmXMLWriter.h" @@ -143,9 +144,8 @@ bool cmCTestSVN::NoteNewRevision() // the repository root. if (!svninfo.Root.empty() && cmCTestSVNPathStarts(svninfo.URL, svninfo.Root)) { - svninfo.Base = - cmCTest::DecodeURL(svninfo.URL.substr(svninfo.Root.size())); - svninfo.Base += "/"; + svninfo.Base = cmStrCat( + cmCTest::DecodeURL(svninfo.URL.substr(svninfo.Root.size())), '/'); } this->Log << "Repository '" << svninfo.LocalPath << "' Base = " << svninfo.Base << "\n"; diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx index a739f44..81966dd 100644 --- a/Source/CTest/cmCTestScriptHandler.cxx +++ b/Source/CTest/cmCTestScriptHandler.cxx @@ -4,13 +4,8 @@ #include "cmsys/Directory.hxx" #include "cmsys/Process.h" -#include <map> -#include <ratio> -#include <sstream> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <utility> + +#include "cm_memory.hxx" #include "cmCTest.h" #include "cmCTestBuildCommand.h" @@ -27,49 +22,35 @@ #include "cmCTestTestCommand.h" #include "cmCTestUpdateCommand.h" #include "cmCTestUploadCommand.h" +#include "cmCommand.h" #include "cmDuration.h" -#include "cmFunctionBlocker.h" #include "cmGeneratedFileStream.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" #include "cmState.h" #include "cmStateDirectory.h" #include "cmStateSnapshot.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmake.h" +#include <map> +#include <memory> +#include <ratio> +#include <sstream> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <utility> + #ifdef _WIN32 # include <windows.h> #else # include <unistd.h> #endif -class cmExecutionStatus; -struct cmListFileFunction; - #define CTEST_INITIAL_CMAKE_OUTPUT_FILE_NAME "CTestInitialCMakeOutput.log" -// used to keep elapsed time up to date -class cmCTestScriptFunctionBlocker : public cmFunctionBlocker -{ -public: - bool IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile& mf, - cmExecutionStatus& /*status*/) override; - // virtual bool ShouldRemove(const cmListFileFunction& lff, cmMakefile &mf); - // virtual void ScopeEnded(cmMakefile &mf); - - cmCTestScriptHandler* CTestScriptHandler; -}; - -// simply update the time and don't block anything -bool cmCTestScriptFunctionBlocker::IsFunctionBlocked( - const cmListFileFunction& /*lff*/, cmMakefile& /*mf*/, - cmExecutionStatus& /*status*/) -{ - this->CTestScriptHandler->UpdateElapsedTime(); - return false; -} - cmCTestScriptHandler::cmCTestScriptHandler() { this->Backup = false; @@ -163,16 +144,16 @@ void cmCTestScriptHandler::UpdateElapsedTime() auto itime = cmDurationTo<unsigned int>(std::chrono::steady_clock::now() - this->ScriptStartTime); auto timeString = std::to_string(itime); - this->Makefile->AddDefinition("CTEST_ELAPSED_TIME", timeString.c_str()); + this->Makefile->AddDefinition("CTEST_ELAPSED_TIME", timeString); } } -void cmCTestScriptHandler::AddCTestCommand(std::string const& name, - cmCTestCommand* command) +void cmCTestScriptHandler::AddCTestCommand( + std::string const& name, std::unique_ptr<cmCTestCommand> command) { command->CTest = this->CTest; command->CTestScriptHandler = this; - this->CMake->GetState()->AddBuiltinCommand(name, command); + this->CMake->GetState()->AddBuiltinCommand(name, std::move(command)); } int cmCTestScriptHandler::ExecuteScript(const std::string& total_script_arg) @@ -295,21 +276,28 @@ void cmCTestScriptHandler::CreateCMake() } }); - this->AddCTestCommand("ctest_build", new cmCTestBuildCommand); - this->AddCTestCommand("ctest_configure", new cmCTestConfigureCommand); - this->AddCTestCommand("ctest_coverage", new cmCTestCoverageCommand); + this->AddCTestCommand("ctest_build", cm::make_unique<cmCTestBuildCommand>()); + this->AddCTestCommand("ctest_configure", + cm::make_unique<cmCTestConfigureCommand>()); + this->AddCTestCommand("ctest_coverage", + cm::make_unique<cmCTestCoverageCommand>()); this->AddCTestCommand("ctest_empty_binary_directory", - new cmCTestEmptyBinaryDirectoryCommand); - this->AddCTestCommand("ctest_memcheck", new cmCTestMemCheckCommand); + cm::make_unique<cmCTestEmptyBinaryDirectoryCommand>()); + this->AddCTestCommand("ctest_memcheck", + cm::make_unique<cmCTestMemCheckCommand>()); this->AddCTestCommand("ctest_read_custom_files", - new cmCTestReadCustomFilesCommand); - this->AddCTestCommand("ctest_run_script", new cmCTestRunScriptCommand); - this->AddCTestCommand("ctest_sleep", new cmCTestSleepCommand); - this->AddCTestCommand("ctest_start", new cmCTestStartCommand); - this->AddCTestCommand("ctest_submit", new cmCTestSubmitCommand); - this->AddCTestCommand("ctest_test", new cmCTestTestCommand); - this->AddCTestCommand("ctest_update", new cmCTestUpdateCommand); - this->AddCTestCommand("ctest_upload", new cmCTestUploadCommand); + cm::make_unique<cmCTestReadCustomFilesCommand>()); + this->AddCTestCommand("ctest_run_script", + cm::make_unique<cmCTestRunScriptCommand>()); + this->AddCTestCommand("ctest_sleep", cm::make_unique<cmCTestSleepCommand>()); + this->AddCTestCommand("ctest_start", cm::make_unique<cmCTestStartCommand>()); + this->AddCTestCommand("ctest_submit", + cm::make_unique<cmCTestSubmitCommand>()); + this->AddCTestCommand("ctest_test", cm::make_unique<cmCTestTestCommand>()); + this->AddCTestCommand("ctest_update", + cm::make_unique<cmCTestUpdateCommand>()); + this->AddCTestCommand("ctest_upload", + cm::make_unique<cmCTestUploadCommand>()); } // this sets up some variables for the script to use, creates the required @@ -340,31 +328,29 @@ int cmCTestScriptHandler::ReadInScript(const std::string& total_script_arg) this->CreateCMake(); // set a variable with the path to the current script - this->Makefile->AddDefinition( - "CTEST_SCRIPT_DIRECTORY", cmSystemTools::GetFilenamePath(script).c_str()); - this->Makefile->AddDefinition( - "CTEST_SCRIPT_NAME", cmSystemTools::GetFilenameName(script).c_str()); + this->Makefile->AddDefinition("CTEST_SCRIPT_DIRECTORY", + cmSystemTools::GetFilenamePath(script)); + this->Makefile->AddDefinition("CTEST_SCRIPT_NAME", + cmSystemTools::GetFilenameName(script)); this->Makefile->AddDefinition("CTEST_EXECUTABLE_NAME", - cmSystemTools::GetCTestCommand().c_str()); + cmSystemTools::GetCTestCommand()); this->Makefile->AddDefinition("CMAKE_EXECUTABLE_NAME", - cmSystemTools::GetCMakeCommand().c_str()); - this->Makefile->AddDefinition("CTEST_RUN_CURRENT_SCRIPT", true); + cmSystemTools::GetCMakeCommand()); + this->Makefile->AddDefinitionBool("CTEST_RUN_CURRENT_SCRIPT", true); this->SetRunCurrentScript(true); this->UpdateElapsedTime(); // add the script arg if defined if (!script_arg.empty()) { - this->Makefile->AddDefinition("CTEST_SCRIPT_ARG", script_arg.c_str()); + this->Makefile->AddDefinition("CTEST_SCRIPT_ARG", script_arg); } #if defined(__CYGWIN__) this->Makefile->AddDefinition("CMAKE_LEGACY_CYGWIN_WIN32", "0"); #endif - // always add a function blocker to update the elapsed time - cmCTestScriptFunctionBlocker* f = new cmCTestScriptFunctionBlocker(); - f->CTestScriptHandler = this; - this->Makefile->AddFunctionBlocker(f); + // set a callback function to update the elapsed time + this->Makefile->OnExecuteCommand([this] { this->UpdateElapsedTime(); }); /* Execute CTestScriptMode.cmake, which loads CMakeDetermineSystem and CMakeSystemSpecificInformation, so @@ -384,7 +370,7 @@ int cmCTestScriptHandler::ReadInScript(const std::string& total_script_arg) const std::map<std::string, std::string>& defs = this->CTest->GetDefinitions(); for (auto const& d : defs) { - this->Makefile->AddDefinition(d.first, d.second.c_str()); + this->Makefile->AddDefinition(d.first, d.second); } // finally read in the script @@ -465,12 +451,13 @@ int cmCTestScriptHandler::ExtractVariables() // make sure the required info is here if (this->SourceDir.empty() || this->BinaryDir.empty() || this->CTestCmd.empty()) { - std::string msg = "CTEST_SOURCE_DIRECTORY = "; - msg += (!this->SourceDir.empty()) ? this->SourceDir.c_str() : "(Null)"; - msg += "\nCTEST_BINARY_DIRECTORY = "; - msg += (!this->BinaryDir.empty()) ? this->BinaryDir.c_str() : "(Null)"; - msg += "\nCTEST_COMMAND = "; - msg += (!this->CTestCmd.empty()) ? this->CTestCmd.c_str() : "(Null)"; + std::string msg = + cmStrCat("CTEST_SOURCE_DIRECTORY = ", + (!this->SourceDir.empty()) ? this->SourceDir.c_str() : "(Null)", + "\nCTEST_BINARY_DIRECTORY = ", + (!this->BinaryDir.empty()) ? this->BinaryDir.c_str() : "(Null)", + "\nCTEST_COMMAND = ", + (!this->CTestCmd.empty()) ? this->CTestCmd.c_str() : "(Null)"); cmSystemTools::Error( "Some required settings in the configuration file were missing:\n" + msg); @@ -509,7 +496,7 @@ void cmCTestScriptHandler::SleepInSeconds(unsigned int secondsToWait) int cmCTestScriptHandler::RunConfigurationScript( const std::string& total_script_arg, bool pscope) { -#ifdef CMAKE_BUILD_WITH_CMAKE +#ifndef CMAKE_BOOTSTRAP cmSystemTools::SaveRestoreEnvironment sre; #endif @@ -557,8 +544,7 @@ int cmCTestScriptHandler::RunCurrentScript() // set any environment variables if (!this->CTestEnv.empty()) { - std::vector<std::string> envArgs; - cmSystemTools::ExpandListArgument(this->CTestEnv, envArgs); + std::vector<std::string> envArgs = cmExpandedList(this->CTestEnv); cmSystemTools::AppendEnv(envArgs); } @@ -624,10 +610,8 @@ int cmCTestScriptHandler::BackupDirectories() int retVal; // compute the backup names - this->BackupSourceDir = this->SourceDir; - this->BackupSourceDir += "_CMakeBackup"; - this->BackupBinaryDir = this->BinaryDir; - this->BackupBinaryDir += "_CMakeBackup"; + this->BackupSourceDir = cmStrCat(this->SourceDir, "_CMakeBackup"); + this->BackupBinaryDir = cmStrCat(this->BinaryDir, "_CMakeBackup"); // backup the binary and src directories if requested if (this->Backup) { @@ -664,12 +648,9 @@ int cmCTestScriptHandler::PerformExtraUpdates() // do an initial cvs update as required command = this->UpdateCmd; for (std::string const& eu : this->ExtraUpdates) { - std::vector<std::string> cvsArgs; - cmSystemTools::ExpandListArgument(eu, cvsArgs); + std::vector<std::string> cvsArgs = cmExpandedList(eu); if (cvsArgs.size() == 2) { - std::string fullCommand = command; - fullCommand += " update "; - fullCommand += cvsArgs[1]; + std::string fullCommand = cmStrCat(command, " update ", cvsArgs[1]); output.clear(); retVal = 0; cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, @@ -678,8 +659,8 @@ int cmCTestScriptHandler::PerformExtraUpdates() fullCommand, &output, &output, &retVal, cvsArgs[0].c_str(), this->HandlerVerbose, cmDuration::zero() /*this->TimeOut*/); if (!res || retVal != 0) { - cmSystemTools::Error("Unable to perform extra updates:\n" + eu + - "\nWith output:\n" + output); + cmSystemTools::Error(cmStrCat("Unable to perform extra updates:\n", eu, + "\nWith output:\n", output)); return 0; } } @@ -770,9 +751,7 @@ int cmCTestScriptHandler::RunConfigurationDashboard() int cmakeFailed = 0; std::string cmakeFailedOuput; if (!this->CMakeCmd.empty()) { - command = this->CMakeCmd; - command += " \""; - command += this->SourceDir; + command = cmStrCat(this->CMakeCmd, " \"", this->SourceDir); output.clear(); command += "\""; retVal = 0; @@ -808,8 +787,7 @@ int cmCTestScriptHandler::RunConfigurationDashboard() } // run ctest, it may be more than one command in here - std::vector<std::string> ctestCommands; - cmSystemTools::ExpandListArgument(this->CTestCmd, ctestCommands); + std::vector<std::string> ctestCommands = cmExpandedList(this->CTestCmd); // for each variable/argument do a putenv for (std::string const& ctestCommand : ctestCommands) { command = ctestCommand; @@ -853,8 +831,7 @@ int cmCTestScriptHandler::RunConfigurationDashboard() bool cmCTestScriptHandler::WriteInitialCache(const char* directory, const char* text) { - std::string cacheFile = directory; - cacheFile += "/CMakeCache.txt"; + std::string cacheFile = cmStrCat(directory, "/CMakeCache.txt"); cmGeneratedFileStream fout(cacheFile); if (!fout) { return false; @@ -919,8 +896,7 @@ bool cmCTestScriptHandler::EmptyBinaryDirectory(const char* sname) } // try to avoid deleting directories that we shouldn't - std::string check = sname; - check += "/CMakeCache.txt"; + std::string check = cmStrCat(sname, "/CMakeCache.txt"); if (!cmSystemTools::FileExists(check)) { return false; @@ -949,7 +925,7 @@ bool cmCTestScriptHandler::TryToRemoveBinaryDirectoryOnce( continue; } - std::string fullPath = directoryPath + std::string("/") + path; + std::string fullPath = cmStrCat(directoryPath, "/", path); bool isDirectory = cmSystemTools::FileIsDirectory(fullPath) && !cmSystemTools::FileIsSymlink(fullPath); diff --git a/Source/CTest/cmCTestScriptHandler.h b/Source/CTest/cmCTestScriptHandler.h index d93b5f8..b2e8cbf 100644 --- a/Source/CTest/cmCTestScriptHandler.h +++ b/Source/CTest/cmCTestScriptHandler.h @@ -9,6 +9,7 @@ #include "cmDuration.h" #include <chrono> +#include <memory> #include <string> #include <vector> @@ -131,7 +132,8 @@ private: int RunConfigurationDashboard(); // Add ctest command - void AddCTestCommand(std::string const& name, cmCTestCommand* command); + void AddCTestCommand(std::string const& name, + std::unique_ptr<cmCTestCommand> command); // Try to remove the binary directory once static bool TryToRemoveBinaryDirectoryOnce(const std::string& directoryPath); diff --git a/Source/CTest/cmCTestSleepCommand.h b/Source/CTest/cmCTestSleepCommand.h index 5cd185a..7b17081 100644 --- a/Source/CTest/cmCTestSleepCommand.h +++ b/Source/CTest/cmCTestSleepCommand.h @@ -6,11 +6,14 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cmCTestCommand.h" +#include "cmCommand.h" #include <string> +#include <utility> #include <vector> -class cmCommand; +#include "cm_memory.hxx" + class cmExecutionStatus; /** \class cmCTestSleep @@ -27,12 +30,12 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override + std::unique_ptr<cmCommand> Clone() override { - cmCTestSleepCommand* ni = new cmCTestSleepCommand; + auto ni = cm::make_unique<cmCTestSleepCommand>(); ni->CTest = this->CTest; ni->CTestScriptHandler = this->CTestScriptHandler; - return ni; + return std::unique_ptr<cmCommand>(std::move(ni)); } /** diff --git a/Source/CTest/cmCTestStartCommand.cxx b/Source/CTest/cmCTestStartCommand.cxx index 67ff2db..e4a1844 100644 --- a/Source/CTest/cmCTestStartCommand.cxx +++ b/Source/CTest/cmCTestStartCommand.cxx @@ -33,14 +33,16 @@ bool cmCTestStartCommand::InitialPass(std::vector<std::string> const& args, const char* bld_dir = nullptr; while (cnt < args.size()) { - if (args[cnt] == "TRACK") { + if (args[cnt] == "GROUP" || args[cnt] == "TRACK") { cnt++; if (cnt >= args.size() || args[cnt] == "APPEND" || args[cnt] == "QUIET") { - this->SetError("TRACK argument missing track name"); + std::ostringstream e; + e << args[cnt - 1] << " argument missing group name"; + this->SetError(e.str()); return false; } - this->CTest->SetSpecificTrack(args[cnt].c_str()); + this->CTest->SetSpecificGroup(args[cnt].c_str()); cnt++; } else if (args[cnt] == "APPEND") { cnt++; @@ -113,10 +115,10 @@ bool cmCTestStartCommand::InitialPass(std::vector<std::string> const& args, << " Build directory: " << bld_dir << std::endl, this->Quiet); } - const char* track = this->CTest->GetSpecificTrack(); - if (track) { + const char* group = this->CTest->GetSpecificGroup(); + if (group) { cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, - " Track: " << track << std::endl, this->Quiet); + " Group: " << group << std::endl, this->Quiet); } // Log startup actions. diff --git a/Source/CTest/cmCTestStartCommand.h b/Source/CTest/cmCTestStartCommand.h index 542f27c..7c71f36 100644 --- a/Source/CTest/cmCTestStartCommand.h +++ b/Source/CTest/cmCTestStartCommand.h @@ -6,12 +6,15 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cmCTestCommand.h" +#include "cmCommand.h" #include <iosfwd> #include <string> +#include <utility> #include <vector> -class cmCommand; +#include "cm_memory.hxx" + class cmExecutionStatus; /** \class cmCTestStart @@ -27,14 +30,14 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override + std::unique_ptr<cmCommand> Clone() override { - cmCTestStartCommand* ni = new cmCTestStartCommand; + auto ni = cm::make_unique<cmCTestStartCommand>(); ni->CTest = this->CTest; ni->CTestScriptHandler = this->CTestScriptHandler; ni->CreateNewTag = this->CreateNewTag; ni->Quiet = this->Quiet; - return ni; + return std::unique_ptr<cmCommand>(std::move(ni)); } /** diff --git a/Source/CTest/cmCTestSubmitCommand.cxx b/Source/CTest/cmCTestSubmitCommand.cxx index afc3e67..d16aac0 100644 --- a/Source/CTest/cmCTestSubmitCommand.cxx +++ b/Source/CTest/cmCTestSubmitCommand.cxx @@ -4,11 +4,16 @@ #include "cmCTest.h" #include "cmCTestSubmitHandler.h" +#include "cmCommand.h" #include "cmMakefile.h" #include "cmMessageType.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include <sstream> +#include <utility> + +#include "cm_memory.hxx" class cmExecutionStatus; @@ -27,12 +32,12 @@ cmCTestSubmitCommand::cmCTestSubmitCommand() /** * This is a virtual constructor for the command. */ -cmCommand* cmCTestSubmitCommand::Clone() +std::unique_ptr<cmCommand> cmCTestSubmitCommand::Clone() { - cmCTestSubmitCommand* ni = new cmCTestSubmitCommand; + auto ni = cm::make_unique<cmCTestSubmitCommand>(); ni->CTest = this->CTest; ni->CTestScriptHandler = this->CTestScriptHandler; - return ni; + return std::unique_ptr<cmCommand>(std::move(ni)); } cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler() @@ -63,16 +68,14 @@ cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler() const char* notesFilesVariable = this->Makefile->GetDefinition("CTEST_NOTES_FILES"); if (notesFilesVariable) { - std::vector<std::string> notesFiles; - cmSystemTools::ExpandListArgument(notesFilesVariable, notesFiles); + std::vector<std::string> notesFiles = cmExpandedList(notesFilesVariable); this->CTest->GenerateNotesFile(notesFiles); } const char* extraFilesVariable = this->Makefile->GetDefinition("CTEST_EXTRA_SUBMIT_FILES"); if (extraFilesVariable) { - std::vector<std::string> extraFiles; - cmSystemTools::ExpandListArgument(extraFilesVariable, extraFiles); + std::vector<std::string> extraFiles = cmExpandedList(extraFilesVariable); if (!this->CTest->SubmitExtraFiles(extraFiles)) { this->SetError("problem submitting extra files."); return nullptr; @@ -139,7 +142,7 @@ bool cmCTestSubmitCommand::InitialPass(std::vector<std::string> const& args, if (this->Values[cts_BUILD_ID] && *this->Values[cts_BUILD_ID]) { this->Makefile->AddDefinition(this->Values[cts_BUILD_ID], - this->CTest->GetBuildID().c_str()); + this->CTest->GetBuildID()); } return ret; diff --git a/Source/CTest/cmCTestSubmitCommand.h b/Source/CTest/cmCTestSubmitCommand.h index 1e27046..5bbcd39 100644 --- a/Source/CTest/cmCTestSubmitCommand.h +++ b/Source/CTest/cmCTestSubmitCommand.h @@ -8,12 +8,13 @@ #include "cmCTest.h" #include "cmCTestHandlerCommand.h" +#include <memory> #include <set> #include <string> #include <vector> -class cmCTestGenericHandler; class cmCommand; +class cmCTestGenericHandler; class cmExecutionStatus; /** \class cmCTestSubmit @@ -26,7 +27,7 @@ class cmCTestSubmitCommand : public cmCTestHandlerCommand { public: cmCTestSubmitCommand(); - cmCommand* Clone() override; + std::unique_ptr<cmCommand> Clone() override; bool InitialPass(std::vector<std::string> const& args, cmExecutionStatus& status) override; diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx index 54c4bae..a178b44 100644 --- a/Source/CTest/cmCTestSubmitHandler.cxx +++ b/Source/CTest/cmCTestSubmitHandler.cxx @@ -19,6 +19,7 @@ #include "cmDuration.h" #include "cmGeneratedFileStream.h" #include "cmState.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmXMLParser.h" #include "cmake.h" @@ -154,8 +155,7 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP( /* In windows, this will init the winsock stuff */ ::curl_global_init(CURL_GLOBAL_ALL); std::string curlopt(this->CTest->GetCTestConfiguration("CurlOptions")); - std::vector<std::string> args; - cmSystemTools::ExpandListArgument(curlopt, args); + std::vector<std::string> args = cmExpandedList(curlopt); bool verifyPeerOff = false; bool verifyHostOff = false; for (std::string const& arg : args) { @@ -224,7 +224,7 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP( std::string local_file = file; bool initialize_cdash_buildid = false; if (!cmSystemTools::FileExists(local_file)) { - local_file = localprefix + "/" + file; + local_file = cmStrCat(localprefix, "/", file); // If this file exists within the local Testing directory we assume // that it will be associated with the current build in CDash. initialize_cdash_buildid = true; @@ -236,9 +236,9 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP( << remote_file << std::endl; std::string ofile = cmSystemTools::EncodeURL(remote_file); - std::string upload_as = url + - ((url.find('?') == std::string::npos) ? '?' : '&') + - "FileName=" + ofile; + std::string upload_as = + cmStrCat(url, ((url.find('?') == std::string::npos) ? '?' : '&'), + "FileName=", ofile); if (initialize_cdash_buildid) { // Provide extra arguments to CDash so that it can initialize and @@ -279,7 +279,7 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP( upload_as += "&MD5="; - if (cmSystemTools::IsOn(this->GetOption("InternalTest"))) { + if (cmIsOn(this->GetOption("InternalTest"))) { upload_as += "bad_md5sum"; } else { upload_as += @@ -498,8 +498,7 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file, cmCTestCurl curl(this->CTest); curl.SetQuiet(this->Quiet); std::string curlopt(this->CTest->GetCTestConfiguration("CurlOptions")); - std::vector<std::string> args; - cmSystemTools::ExpandListArgument(curlopt, args); + std::vector<std::string> args = cmExpandedList(curlopt); curl.SetCurlOptions(args); curl.SetTimeOutSeconds(SUBMIT_TIMEOUT_IN_SECONDS_DEFAULT); curl.SetHttpHeaders(this->HttpHeaders); @@ -516,7 +515,7 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file, "Only http and https are supported for CDASH_UPLOAD\n"); return -1; } - bool internalTest = cmSystemTools::IsOn(this->GetOption("InternalTest")); + bool internalTest = cmIsOn(this->GetOption("InternalTest")); // Get RETRY_COUNT and RETRY_DELAY values if they were set. std::string retryDelayString = this->GetOption("RetryDelay") == nullptr @@ -528,8 +527,7 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file, auto retryDelay = std::chrono::seconds(0); if (!retryDelayString.empty()) { unsigned long retryDelayValue = 0; - if (!cmSystemTools::StringToULong(retryDelayString.c_str(), - &retryDelayValue)) { + if (!cmStrToULong(retryDelayString, &retryDelayValue)) { cmCTestLog(this->CTest, WARNING, "Invalid value for 'RETRY_DELAY' : " << retryDelayString << std::endl); @@ -539,7 +537,7 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file, } unsigned long retryCount = 0; if (!retryCountString.empty()) { - if (!cmSystemTools::StringToULong(retryCountString.c_str(), &retryCount)) { + if (!cmStrToULong(retryCountString, &retryCount)) { cmCTestLog(this->CTest, WARNING, "Invalid value for 'RETRY_DELAY' : " << retryCountString << std::endl); @@ -569,6 +567,11 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file, << curl.Escape(this->CTest->GetCTestConfiguration("BuildName")) << "&" << "site=" << curl.Escape(this->CTest->GetCTestConfiguration("Site")) << "&" + << "group=" << curl.Escape(this->CTest->GetTestModelString()) + << "&" + // For now, we send both "track" and "group" to CDash in case we're + // submitting to an older instance that still expects the prior + // terminology. << "track=" << curl.Escape(this->CTest->GetTestModelString()) << "&" << "starttime=" << timeNow << "&" << "endtime=" << timeNow << "&" @@ -837,10 +840,10 @@ int cmCTestSubmitHandler::ProcessHandler() } cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "Submit files\n", this->Quiet); - const char* specificTrack = this->CTest->GetSpecificTrack(); - if (specificTrack) { + const char* specificGroup = this->CTest->GetSpecificGroup(); + if (specificGroup) { cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, - " Send to track: " << specificTrack << std::endl, + " Send to group: " << specificGroup << std::endl, this->Quiet); } this->SetLogFile(&ofs); diff --git a/Source/CTest/cmCTestTestCommand.cxx b/Source/CTest/cmCTestTestCommand.cxx index cfd5e3d..24de5b4 100644 --- a/Source/CTest/cmCTestTestCommand.cxx +++ b/Source/CTest/cmCTestTestCommand.cxx @@ -7,7 +7,7 @@ #include "cmCTestTestHandler.h" #include "cmDuration.h" #include "cmMakefile.h" -#include "cmSystemTools.h" +#include "cmStringAlgorithms.h" #include <chrono> #include <sstream> @@ -110,15 +110,14 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler() unsigned long testLoad; const char* ctestTestLoad = this->Makefile->GetDefinition("CTEST_TEST_LOAD"); if (this->Values[ctt_TEST_LOAD] && *this->Values[ctt_TEST_LOAD]) { - if (!cmSystemTools::StringToULong(this->Values[ctt_TEST_LOAD], - &testLoad)) { + if (!cmStrToULong(this->Values[ctt_TEST_LOAD], &testLoad)) { testLoad = 0; cmCTestLog(this->CTest, WARNING, "Invalid value for 'TEST_LOAD' : " << this->Values[ctt_TEST_LOAD] << std::endl); } } else if (ctestTestLoad && *ctestTestLoad) { - if (!cmSystemTools::StringToULong(ctestTestLoad, &testLoad)) { + if (!cmStrToULong(ctestTestLoad, &testLoad)) { testLoad = 0; cmCTestLog(this->CTest, WARNING, "Invalid value for 'CTEST_TEST_LOAD' : " << ctestTestLoad diff --git a/Source/CTest/cmCTestTestCommand.h b/Source/CTest/cmCTestTestCommand.h index 11c0db9..d74136c 100644 --- a/Source/CTest/cmCTestTestCommand.h +++ b/Source/CTest/cmCTestTestCommand.h @@ -6,11 +6,14 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cmCTestHandlerCommand.h" +#include "cmCommand.h" #include <string> +#include <utility> + +#include "cm_memory.hxx" class cmCTestGenericHandler; -class cmCommand; /** \class cmCTestTest * \brief Run a ctest script @@ -25,12 +28,12 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override + std::unique_ptr<cmCommand> Clone() override { - cmCTestTestCommand* ni = new cmCTestTestCommand; + auto ni = cm::make_unique<cmCTestTestCommand>(); ni->CTest = this->CTest; ni->CTestScriptHandler = this->CTestScriptHandler; - return ni; + return std::unique_ptr<cmCommand>(std::move(ni)); } /** diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx index 0ed56c8..9181daa 100644 --- a/Source/CTest/cmCTestTestHandler.cxx +++ b/Source/CTest/cmCTestTestHandler.cxx @@ -11,12 +11,14 @@ #include <functional> #include <iomanip> #include <iterator> -#include <memory> // IWYU pragma: keep #include <set> #include <sstream> #include <stdio.h> #include <stdlib.h> #include <time.h> +#include <utility> + +#include "cm_memory.hxx" #include "cmAlgorithms.h" #include "cmCTest.h" @@ -28,6 +30,7 @@ #include "cmMakefile.h" #include "cmState.h" #include "cmStateSnapshot.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmWorkingDirectory.h" #include "cmXMLWriter.h" @@ -43,11 +46,11 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override + std::unique_ptr<cmCommand> Clone() override { - cmCTestSubdirCommand* c = new cmCTestSubdirCommand; + auto c = cm::make_unique<cmCTestSubdirCommand>(); c->TestHandler = this->TestHandler; - return c; + return std::unique_ptr<cmCommand>(std::move(c)); } /** @@ -74,9 +77,7 @@ bool cmCTestSubdirCommand::InitialPass(std::vector<std::string> const& args, if (cmSystemTools::FileIsFullPath(arg)) { fname = arg; } else { - fname = cwd; - fname += "/"; - fname += arg; + fname = cmStrCat(cwd, '/', arg); } if (!cmSystemTools::FileIsDirectory(fname)) { @@ -107,8 +108,7 @@ bool cmCTestSubdirCommand::InitialPass(std::vector<std::string> const& args, readit = this->Makefile->ReadDependentFile(fname); } if (!readit) { - std::string m = "Could not find include file: "; - m += fname; + std::string m = cmStrCat("Could not find include file: ", fname); this->SetError(m); return false; } @@ -122,11 +122,11 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override + std::unique_ptr<cmCommand> Clone() override { - cmCTestAddSubdirectoryCommand* c = new cmCTestAddSubdirectoryCommand; + auto c = cm::make_unique<cmCTestAddSubdirectoryCommand>(); c->TestHandler = this->TestHandler; - return c; + return std::unique_ptr<cmCommand>(std::move(c)); } /** @@ -147,9 +147,8 @@ bool cmCTestAddSubdirectoryCommand::InitialPass( return false; } - std::string fname = cmSystemTools::GetCurrentWorkingDirectory(); - fname += "/"; - fname += args[0]; + std::string fname = + cmStrCat(cmSystemTools::GetCurrentWorkingDirectory(), '/', args[0]); if (!cmSystemTools::FileExists(fname)) { // No subdirectory? So what... @@ -173,8 +172,7 @@ bool cmCTestAddSubdirectoryCommand::InitialPass( readit = this->Makefile->ReadDependentFile(fname); } if (!readit) { - std::string m = "Could not find include file: "; - m += fname; + std::string m = cmStrCat("Could not find include file: ", fname); this->SetError(m); return false; } @@ -187,11 +185,11 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override + std::unique_ptr<cmCommand> Clone() override { - cmCTestAddTestCommand* c = new cmCTestAddTestCommand; + auto c = cm::make_unique<cmCTestAddTestCommand>(); c->TestHandler = this->TestHandler; - return c; + return std::unique_ptr<cmCommand>(std::move(c)); } /** @@ -220,11 +218,11 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override + std::unique_ptr<cmCommand> Clone() override { - cmCTestSetTestsPropertiesCommand* c = new cmCTestSetTestsPropertiesCommand; + auto c = cm::make_unique<cmCTestSetTestsPropertiesCommand>(); c->TestHandler = this->TestHandler; - return c; + return std::unique_ptr<cmCommand>(std::move(c)); } /** @@ -249,12 +247,11 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override + std::unique_ptr<cmCommand> Clone() override { - cmCTestSetDirectoryPropertiesCommand* c = - new cmCTestSetDirectoryPropertiesCommand; + auto c = cm::make_unique<cmCTestSetDirectoryPropertiesCommand>(); c->TestHandler = this->TestHandler; - return c; + return std::unique_ptr<cmCommand>(std::move(c)); } /** @@ -422,54 +419,11 @@ int cmCTestTestHandler::PostProcessHandler() return 1; } -// clearly it would be nice if this were broken up into a few smaller -// functions and commented... int cmCTestTestHandler::ProcessHandler() { - // Update internal data structure from generic one - this->SetTestsToRunInformation(this->GetOption("TestsToRunInformation")); - this->SetUseUnion(cmSystemTools::IsOn(this->GetOption("UseUnion"))); - if (cmSystemTools::IsOn(this->GetOption("ScheduleRandom"))) { - this->CTest->SetScheduleType("Random"); - } - if (this->GetOption("ParallelLevel")) { - this->CTest->SetParallelLevel(atoi(this->GetOption("ParallelLevel"))); - } - - const char* val; - val = this->GetOption("LabelRegularExpression"); - if (val) { - this->UseIncludeLabelRegExpFlag = true; - this->IncludeLabelRegExp = val; - } - val = this->GetOption("ExcludeLabelRegularExpression"); - if (val) { - this->UseExcludeLabelRegExpFlag = true; - this->ExcludeLabelRegExp = val; - } - val = this->GetOption("IncludeRegularExpression"); - if (val) { - this->UseIncludeRegExp(); - this->SetIncludeRegExp(val); - } - val = this->GetOption("ExcludeRegularExpression"); - if (val) { - this->UseExcludeRegExp(); - this->SetExcludeRegExp(val); - } - val = this->GetOption("ExcludeFixtureRegularExpression"); - if (val) { - this->ExcludeFixtureRegExp = val; - } - val = this->GetOption("ExcludeFixtureSetupRegularExpression"); - if (val) { - this->ExcludeFixtureSetupRegExp = val; - } - val = this->GetOption("ExcludeFixtureCleanupRegularExpression"); - if (val) { - this->ExcludeFixtureCleanupRegExp = val; + if (!this->ProcessOptions()) { + return -1; } - this->SetRerunFailed(cmSystemTools::IsOn(this->GetOption("RerunFailed"))); this->TestResults.clear(); @@ -489,7 +443,6 @@ int cmCTestTestHandler::ProcessHandler() std::vector<std::string> passed; std::vector<std::string> failed; - int total; // start the real time clock auto clock_start = std::chrono::steady_clock::now(); @@ -498,9 +451,7 @@ int cmCTestTestHandler::ProcessHandler() auto clock_finish = std::chrono::steady_clock::now(); - total = int(passed.size()) + int(failed.size()); - - if (total == 0) { + if (passed.size() + failed.size() == 0) { if (!this->CTest->GetShowOnly() && !this->CTest->ShouldPrintLabels()) { cmCTestLog(this->CTest, ERROR_MESSAGE, "No tests were found!!!" << std::endl); @@ -518,105 +469,192 @@ int cmCTestTestHandler::ProcessHandler() } } - typedef std::set<cmCTestTestHandler::cmCTestTestResult, - cmCTestTestResultLess> - SetOfTests; SetOfTests resultsSet(this->TestResults.begin(), this->TestResults.end()); std::vector<cmCTestTestHandler::cmCTestTestResult> disabledTests; for (cmCTestTestResult const& ft : resultsSet) { - if (cmHasLiteralPrefix(ft.CompletionStatus, "SKIP_RETURN_CODE=") || + if (cmHasLiteralPrefix(ft.CompletionStatus, "SKIP_") || ft.CompletionStatus == "Disabled") { disabledTests.push_back(ft); } } - float percent = float(passed.size()) * 100.0f / float(total); - if (!failed.empty() && percent > 99) { - percent = 99; - } + cmDuration durationInSecs = clock_finish - clock_start; + this->LogTestSummary(passed, failed, durationInSecs); - std::string passColorCode; - std::string failedColorCode; - if (failed.empty()) { - passColorCode = this->CTest->GetColorCode(cmCTest::Color::GREEN); - } else { - failedColorCode = this->CTest->GetColorCode(cmCTest::Color::RED); - } + this->LogDisabledTests(disabledTests); + + this->LogFailedTests(failed, resultsSet); + } + + if (!this->GenerateXML()) { + return 1; + } + + if (!this->PostProcessHandler()) { + this->LogFile = nullptr; + return -1; + } + + if (!failed.empty()) { + this->LogFile = nullptr; + return -1; + } + this->LogFile = nullptr; + return 0; +} + +bool cmCTestTestHandler::ProcessOptions() +{ + // Update internal data structure from generic one + this->SetTestsToRunInformation(this->GetOption("TestsToRunInformation")); + this->SetUseUnion(cmIsOn(this->GetOption("UseUnion"))); + if (cmIsOn(this->GetOption("ScheduleRandom"))) { + this->CTest->SetScheduleType("Random"); + } + if (this->GetOption("ParallelLevel")) { + this->CTest->SetParallelLevel(atoi(this->GetOption("ParallelLevel"))); + } + + const char* val; + val = this->GetOption("LabelRegularExpression"); + if (val) { + this->UseIncludeLabelRegExpFlag = true; + this->IncludeLabelRegExp = val; + } + val = this->GetOption("ExcludeLabelRegularExpression"); + if (val) { + this->UseExcludeLabelRegExpFlag = true; + this->ExcludeLabelRegExp = val; + } + val = this->GetOption("IncludeRegularExpression"); + if (val) { + this->UseIncludeRegExp(); + this->SetIncludeRegExp(val); + } + val = this->GetOption("ExcludeRegularExpression"); + if (val) { + this->UseExcludeRegExp(); + this->SetExcludeRegExp(val); + } + val = this->GetOption("ExcludeFixtureRegularExpression"); + if (val) { + this->ExcludeFixtureRegExp = val; + } + val = this->GetOption("ExcludeFixtureSetupRegularExpression"); + if (val) { + this->ExcludeFixtureSetupRegExp = val; + } + val = this->GetOption("ExcludeFixtureCleanupRegularExpression"); + if (val) { + this->ExcludeFixtureCleanupRegExp = val; + } + this->SetRerunFailed(cmIsOn(this->GetOption("RerunFailed"))); + + return true; +} + +void cmCTestTestHandler::LogTestSummary(const std::vector<std::string>& passed, + const std::vector<std::string>& failed, + const cmDuration& durationInSecs) +{ + std::size_t total = passed.size() + failed.size(); + + float percent = float(passed.size()) * 100.0f / float(total); + if (!failed.empty() && percent > 99) { + percent = 99; + } + + std::string passColorCode; + std::string failedColorCode; + if (failed.empty()) { + passColorCode = this->CTest->GetColorCode(cmCTest::Color::GREEN); + } else { + failedColorCode = this->CTest->GetColorCode(cmCTest::Color::RED); + } + cmCTestLog(this->CTest, HANDLER_OUTPUT, + std::endl + << passColorCode << std::lround(percent) << "% tests passed" + << this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR) + << ", " << failedColorCode << failed.size() << " tests failed" + << this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR) + << " out of " << total << std::endl); + if ((!this->CTest->GetLabelsForSubprojects().empty() && + this->CTest->GetSubprojectSummary())) { + this->PrintLabelOrSubprojectSummary(true); + } + if (this->CTest->GetLabelSummary()) { + this->PrintLabelOrSubprojectSummary(false); + } + char realBuf[1024]; + sprintf(realBuf, "%6.2f sec", durationInSecs.count()); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, + "\nTotal Test time (real) = " << realBuf << "\n", + this->Quiet); +} + +void cmCTestTestHandler::LogDisabledTests( + const std::vector<cmCTestTestResult>& disabledTests) +{ + if (!disabledTests.empty()) { + cmGeneratedFileStream ofs; cmCTestLog(this->CTest, HANDLER_OUTPUT, std::endl - << passColorCode << std::lround(percent) << "% tests passed" - << this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR) - << ", " << failedColorCode << failed.size() << " tests failed" - << this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR) - << " out of " << total << std::endl); - if ((!this->CTest->GetLabelsForSubprojects().empty() && - this->CTest->GetSubprojectSummary())) { - this->PrintLabelOrSubprojectSummary(true); - } - if (this->CTest->GetLabelSummary()) { - this->PrintLabelOrSubprojectSummary(false); - } - char realBuf[1024]; - cmDuration durationInSecs = clock_finish - clock_start; - sprintf(realBuf, "%6.2f sec", durationInSecs.count()); - cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, - "\nTotal Test time (real) = " << realBuf << "\n", - this->Quiet); - - if (!disabledTests.empty()) { - cmGeneratedFileStream ofs; - cmCTestLog(this->CTest, HANDLER_OUTPUT, - std::endl - << "The following tests did not run:" << std::endl); - this->StartLogFile("TestsDisabled", ofs); + << "The following tests did not run:" << std::endl); + this->StartLogFile("TestsDisabled", ofs); - const char* disabled_reason; - cmCTestLog(this->CTest, HANDLER_OUTPUT, - this->CTest->GetColorCode(cmCTest::Color::BLUE)); - for (cmCTestTestResult const& dt : disabledTests) { - ofs << dt.TestCount << ":" << dt.Name << std::endl; - if (dt.CompletionStatus == "Disabled") { - disabled_reason = "Disabled"; - } else { - disabled_reason = "Skipped"; - } - cmCTestLog(this->CTest, HANDLER_OUTPUT, - "\t" << std::setw(3) << dt.TestCount << " - " << dt.Name - << " (" << disabled_reason << ")" << std::endl); + const char* disabled_reason; + cmCTestLog(this->CTest, HANDLER_OUTPUT, + this->CTest->GetColorCode(cmCTest::Color::BLUE)); + for (cmCTestTestResult const& dt : disabledTests) { + ofs << dt.TestCount << ":" << dt.Name << std::endl; + if (dt.CompletionStatus == "Disabled") { + disabled_reason = "Disabled"; + } else { + disabled_reason = "Skipped"; } cmCTestLog(this->CTest, HANDLER_OUTPUT, - this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR)); + "\t" << std::setw(3) << dt.TestCount << " - " << dt.Name + << " (" << disabled_reason << ")" << std::endl); } + cmCTestLog(this->CTest, HANDLER_OUTPUT, + this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR)); + } +} - if (!failed.empty()) { - cmGeneratedFileStream ofs; - cmCTestLog(this->CTest, HANDLER_OUTPUT, - std::endl - << "The following tests FAILED:" << std::endl); - this->StartLogFile("TestsFailed", ofs); - - for (cmCTestTestResult const& ft : resultsSet) { - if (ft.Status != cmCTestTestHandler::COMPLETED && - !cmHasLiteralPrefix(ft.CompletionStatus, "SKIP_RETURN_CODE=") && - ft.CompletionStatus != "Disabled") { - ofs << ft.TestCount << ":" << ft.Name << std::endl; - auto testColor = cmCTest::Color::RED; - if (this->GetTestStatus(ft) == "Not Run") { - testColor = cmCTest::Color::YELLOW; - } - cmCTestLog( - this->CTest, HANDLER_OUTPUT, - "\t" << this->CTest->GetColorCode(testColor) << std::setw(3) - << ft.TestCount << " - " << ft.Name << " (" - << this->GetTestStatus(ft) << ")" - << this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR) - << std::endl); +void cmCTestTestHandler::LogFailedTests(const std::vector<std::string>& failed, + const SetOfTests& resultsSet) +{ + if (!failed.empty()) { + cmGeneratedFileStream ofs; + cmCTestLog(this->CTest, HANDLER_OUTPUT, + std::endl + << "The following tests FAILED:" << std::endl); + this->StartLogFile("TestsFailed", ofs); + + for (cmCTestTestResult const& ft : resultsSet) { + if (ft.Status != cmCTestTestHandler::COMPLETED && + !cmHasLiteralPrefix(ft.CompletionStatus, "SKIP_") && + ft.CompletionStatus != "Disabled") { + ofs << ft.TestCount << ":" << ft.Name << std::endl; + auto testColor = cmCTest::Color::RED; + if (this->GetTestStatus(ft) == "Not Run") { + testColor = cmCTest::Color::YELLOW; } + cmCTestLog( + this->CTest, HANDLER_OUTPUT, + "\t" << this->CTest->GetColorCode(testColor) << std::setw(3) + << ft.TestCount << " - " << ft.Name << " (" + << this->GetTestStatus(ft) << ")" + << this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR) + << std::endl); } } } +} +bool cmCTestTestHandler::GenerateXML() +{ if (this->CTest->GetProduceXML()) { cmGeneratedFileStream xmlfile; if (!this->StartResultingXML( @@ -627,23 +665,13 @@ int cmCTestTestHandler::ProcessHandler() << (this->MemCheck ? "memory check" : "testing") << " XML file" << std::endl); this->LogFile = nullptr; - return 1; + return false; } cmXMLWriter xml(xmlfile); this->GenerateDartOutput(xml); } - if (!this->PostProcessHandler()) { - this->LogFile = nullptr; - return -1; - } - - if (!failed.empty()) { - this->LogFile = nullptr; - return -1; - } - this->LogFile = nullptr; - return 0; + return true; } void cmCTestTestHandler::PrintLabelOrSubprojectSummary(bool doSubProject) @@ -667,8 +695,7 @@ void cmCTestTestHandler::PrintLabelOrSubprojectSummary(bool doSubProject) } // if we are doing sub projects and this label is one, then use it // if we are not doing sub projects and the label is not one use it - if ((doSubProject && isSubprojectLabel) || - (!doSubProject && !isSubprojectLabel)) { + if (doSubProject == isSubprojectLabel) { if (l.size() > maxlen) { maxlen = l.size(); } @@ -683,7 +710,7 @@ void cmCTestTestHandler::PrintLabelOrSubprojectSummary(bool doSubProject) cmCTestTestProperties& p = *result.Properties; for (std::string const& l : p.Labels) { // only use labels found in labels - if (labels.find(l) != labels.end()) { + if (cmContains(labels, l)) { labelTimes[l] += result.ExecutionTime.count() * result.Properties->Processors; ++labelCounts[l]; @@ -825,17 +852,14 @@ void cmCTestTestHandler::ComputeTestList() if (this->UseUnion) { // if it is not in the list and not in the regexp then skip - if ((!this->TestsToRun.empty() && - std::find(this->TestsToRun.begin(), this->TestsToRun.end(), cnt) == - this->TestsToRun.end()) && + if ((!this->TestsToRun.empty() && !cmContains(this->TestsToRun, cnt)) && !tp.IsInBasedOnREOptions) { continue; } } else { // is this test in the list of tests to run? If not then skip it if ((!this->TestsToRun.empty() && - std::find(this->TestsToRun.begin(), this->TestsToRun.end(), - inREcnt) == this->TestsToRun.end()) || + !cmContains(this->TestsToRun, inREcnt)) || !tp.IsInBasedOnREOptions) { continue; } @@ -864,9 +888,7 @@ void cmCTestTestHandler::ComputeTestListForRerunFailed() cnt++; // if this test is not in our list of tests to run, then skip it. - if ((!this->TestsToRun.empty() && - std::find(this->TestsToRun.begin(), this->TestsToRun.end(), cnt) == - this->TestsToRun.end())) { + if (!this->TestsToRun.empty() && !cmContains(this->TestsToRun, cnt)) { continue; } @@ -987,8 +1009,7 @@ void cmCTestTestHandler::UpdateForFixtures(ListOfTests& tests) const sIt != setupRange.second; ++sIt) { const std::string& setupTestName = sIt->second->Name; tests[i].RequireSuccessDepends.insert(setupTestName); - if (std::find(tests[i].Depends.begin(), tests[i].Depends.end(), - setupTestName) == tests[i].Depends.end()) { + if (!cmContains(tests[i].Depends, setupTestName)) { tests[i].Depends.push_back(setupTestName); } } @@ -1095,8 +1116,7 @@ void cmCTestTestHandler::UpdateForFixtures(ListOfTests& tests) const const std::vector<size_t>& indices = cIt->second; for (size_t index : indices) { const std::string& reqTestName = tests[index].Name; - if (std::find(p.Depends.begin(), p.Depends.end(), reqTestName) == - p.Depends.end()) { + if (!cmContains(p.Depends, reqTestName)) { p.Depends.push_back(reqTestName); } } @@ -1109,8 +1129,7 @@ void cmCTestTestHandler::UpdateForFixtures(ListOfTests& tests) const const std::vector<size_t>& indices = cIt->second; for (size_t index : indices) { const std::string& setupTestName = tests[index].Name; - if (std::find(p.Depends.begin(), p.Depends.end(), setupTestName) == - p.Depends.end()) { + if (!cmContains(p.Depends, setupTestName)) { p.Depends.push_back(setupTestName); } } @@ -1527,50 +1546,32 @@ void cmCTestTestHandler::AddConfigurations( attemptedConfigs.emplace_back(); if (!ctest->GetConfigType().empty()) { - tempPath = filepath; - tempPath += ctest->GetConfigType(); - tempPath += "/"; - tempPath += filename; + tempPath = cmStrCat(filepath, ctest->GetConfigType(), '/', filename); attempted.push_back(tempPath); attemptedConfigs.push_back(ctest->GetConfigType()); // If the file is an OSX bundle then the configtype // will be at the start of the path - tempPath = ctest->GetConfigType(); - tempPath += "/"; - tempPath += filepath; - tempPath += filename; + tempPath = cmStrCat(ctest->GetConfigType(), '/', filepath, filename); attempted.push_back(tempPath); attemptedConfigs.push_back(ctest->GetConfigType()); } else { // no config specified - try some options... - tempPath = filepath; - tempPath += "Release/"; - tempPath += filename; + tempPath = cmStrCat(filepath, "Release/", filename); attempted.push_back(tempPath); attemptedConfigs.emplace_back("Release"); - tempPath = filepath; - tempPath += "Debug/"; - tempPath += filename; + tempPath = cmStrCat(filepath, "Debug/", filename); attempted.push_back(tempPath); attemptedConfigs.emplace_back("Debug"); - tempPath = filepath; - tempPath += "MinSizeRel/"; - tempPath += filename; + tempPath = cmStrCat(filepath, "MinSizeRel/", filename); attempted.push_back(tempPath); attemptedConfigs.emplace_back("MinSizeRel"); - tempPath = filepath; - tempPath += "RelWithDebInfo/"; - tempPath += filename; + tempPath = cmStrCat(filepath, "RelWithDebInfo/", filename); attempted.push_back(tempPath); attemptedConfigs.emplace_back("RelWithDebInfo"); - tempPath = filepath; - tempPath += "Deployment/"; - tempPath += filename; + tempPath = cmStrCat(filepath, "Deployment/", filename); attempted.push_back(tempPath); attemptedConfigs.emplace_back("Deployment"); - tempPath = filepath; - tempPath += "Development/"; - tempPath += filename; + tempPath = cmStrCat(filepath, "Development/", filename); attempted.push_back(tempPath); attemptedConfigs.emplace_back("Deployment"); } @@ -1624,8 +1625,8 @@ std::string cmCTestTestHandler::FindExecutable( // then try with the exe extension else { failed.push_back(attempted[ai]); - tempPath = attempted[ai]; - tempPath += cmSystemTools::GetExecutableExtension(); + tempPath = + cmStrCat(attempted[ai], cmSystemTools::GetExecutableExtension()); if (cmSystemTools::FileExists(tempPath) && !cmSystemTools::FileIsDirectory(tempPath)) { fullPath = cmSystemTools::CollapseFullPath(tempPath); @@ -1682,36 +1683,34 @@ void cmCTestTestHandler::GetListOfTests() cm.GetCurrentSnapshot().SetDefaultDefinitions(); cmGlobalGenerator gg(&cm); cmMakefile mf(&gg, cm.GetCurrentSnapshot()); - mf.AddDefinition("CTEST_CONFIGURATION_TYPE", - this->CTest->GetConfigType().c_str()); + mf.AddDefinition("CTEST_CONFIGURATION_TYPE", this->CTest->GetConfigType()); // Add handler for ADD_TEST - cmCTestAddTestCommand* newCom1 = new cmCTestAddTestCommand; + auto newCom1 = cm::make_unique<cmCTestAddTestCommand>(); newCom1->TestHandler = this; - cm.GetState()->AddBuiltinCommand("add_test", newCom1); + cm.GetState()->AddBuiltinCommand("add_test", std::move(newCom1)); // Add handler for SUBDIRS - cmCTestSubdirCommand* newCom2 = new cmCTestSubdirCommand; + auto newCom2 = cm::make_unique<cmCTestSubdirCommand>(); newCom2->TestHandler = this; - cm.GetState()->AddBuiltinCommand("subdirs", newCom2); + cm.GetState()->AddBuiltinCommand("subdirs", std::move(newCom2)); // Add handler for ADD_SUBDIRECTORY - cmCTestAddSubdirectoryCommand* newCom3 = new cmCTestAddSubdirectoryCommand; + auto newCom3 = cm::make_unique<cmCTestAddSubdirectoryCommand>(); newCom3->TestHandler = this; - cm.GetState()->AddBuiltinCommand("add_subdirectory", newCom3); + cm.GetState()->AddBuiltinCommand("add_subdirectory", std::move(newCom3)); // Add handler for SET_TESTS_PROPERTIES - cmCTestSetTestsPropertiesCommand* newCom4 = - new cmCTestSetTestsPropertiesCommand; + auto newCom4 = cm::make_unique<cmCTestSetTestsPropertiesCommand>(); newCom4->TestHandler = this; - cm.GetState()->AddBuiltinCommand("set_tests_properties", newCom4); + cm.GetState()->AddBuiltinCommand("set_tests_properties", std::move(newCom4)); // Add handler for SET_DIRECTORY_PROPERTIES cm.GetState()->RemoveBuiltinCommand("set_directory_properties"); - cmCTestSetDirectoryPropertiesCommand* newCom5 = - new cmCTestSetDirectoryPropertiesCommand; + auto newCom5 = cm::make_unique<cmCTestSetDirectoryPropertiesCommand>(); newCom5->TestHandler = this; - cm.GetState()->AddBuiltinCommand("set_directory_properties", newCom5); + cm.GetState()->AddBuiltinCommand("set_directory_properties", + std::move(newCom5)); const char* testFilename; if (cmSystemTools::FileExists("CTestTestfile.cmake")) { @@ -2150,7 +2149,7 @@ bool cmCTestTestHandler::SetTestsProperties( if (key == "_BACKTRACE_TRIPLES") { std::vector<std::string> triples; // allow empty args in the triples - cmSystemTools::ExpandListArgument(val, triples, true); + cmExpandList(val, triples, true); // Ensure we have complete triples otherwise the data is corrupt. if (triples.size() % 3 == 0) { @@ -2163,8 +2162,7 @@ bool cmCTestTestHandler::SetTestsProperties( cmListFileContext fc; fc.FilePath = triples[i - 3]; long line = 0; - if (!cmSystemTools::StringToLong(triples[i - 2].c_str(), - &line)) { + if (!cmStrToLong(triples[i - 2], &line)) { line = 0; } fc.Line = line; @@ -2174,38 +2172,34 @@ bool cmCTestTestHandler::SetTestsProperties( } } if (key == "WILL_FAIL") { - rt.WillFail = cmSystemTools::IsOn(val); + rt.WillFail = cmIsOn(val); } if (key == "DISABLED") { - rt.Disabled = cmSystemTools::IsOn(val); + rt.Disabled = cmIsOn(val); } if (key == "ATTACHED_FILES") { - cmSystemTools::ExpandListArgument(val, rt.AttachedFiles); + cmExpandList(val, rt.AttachedFiles); } if (key == "ATTACHED_FILES_ON_FAIL") { - cmSystemTools::ExpandListArgument(val, rt.AttachOnFail); + cmExpandList(val, rt.AttachOnFail); } if (key == "RESOURCE_LOCK") { - std::vector<std::string> lval; - cmSystemTools::ExpandListArgument(val, lval); + std::vector<std::string> lval = cmExpandedList(val); rt.LockedResources.insert(lval.begin(), lval.end()); } if (key == "FIXTURES_SETUP") { - std::vector<std::string> lval; - cmSystemTools::ExpandListArgument(val, lval); + std::vector<std::string> lval = cmExpandedList(val); rt.FixturesSetup.insert(lval.begin(), lval.end()); } if (key == "FIXTURES_CLEANUP") { - std::vector<std::string> lval; - cmSystemTools::ExpandListArgument(val, lval); + std::vector<std::string> lval = cmExpandedList(val); rt.FixturesCleanup.insert(lval.begin(), lval.end()); } if (key == "FIXTURES_REQUIRED") { - std::vector<std::string> lval; - cmSystemTools::ExpandListArgument(val, lval); + std::vector<std::string> lval = cmExpandedList(val); rt.FixturesRequired.insert(lval.begin(), lval.end()); } @@ -2217,18 +2211,23 @@ bool cmCTestTestHandler::SetTestsProperties( rt.Cost = static_cast<float>(atof(val.c_str())); } if (key == "REQUIRED_FILES") { - cmSystemTools::ExpandListArgument(val, rt.RequiredFiles); + cmExpandList(val, rt.RequiredFiles); } if (key == "RUN_SERIAL") { - rt.RunSerial = cmSystemTools::IsOn(val); + rt.RunSerial = cmIsOn(val); } if (key == "FAIL_REGULAR_EXPRESSION") { - std::vector<std::string> lval; - cmSystemTools::ExpandListArgument(val, lval); + std::vector<std::string> lval = cmExpandedList(val); for (std::string const& cr : lval) { rt.ErrorRegularExpressions.emplace_back(cr, cr); } } + if (key == "SKIP_REGULAR_EXPRESSION") { + std::vector<std::string> lval = cmExpandedList(val); + for (std::string const& cr : lval) { + rt.SkipRegularExpressions.emplace_back(cr, cr); + } + } if (key == "PROCESSORS") { rt.Processors = atoi(val.c_str()); if (rt.Processors < 1) { @@ -2236,7 +2235,7 @@ bool cmCTestTestHandler::SetTestsProperties( } } if (key == "PROCESSOR_AFFINITY") { - rt.WantAffinity = cmSystemTools::IsOn(val); + rt.WantAffinity = cmIsOn(val); } if (key == "SKIP_RETURN_CODE") { rt.SkipReturnCode = atoi(val.c_str()); @@ -2245,14 +2244,13 @@ bool cmCTestTestHandler::SetTestsProperties( } } if (key == "DEPENDS") { - cmSystemTools::ExpandListArgument(val, rt.Depends); + cmExpandList(val, rt.Depends); } if (key == "ENVIRONMENT") { - cmSystemTools::ExpandListArgument(val, rt.Environment); + cmExpandList(val, rt.Environment); } if (key == "LABELS") { - std::vector<std::string> Labels; - cmSystemTools::ExpandListArgument(val, Labels); + std::vector<std::string> Labels = cmExpandedList(val); rt.Labels.insert(rt.Labels.end(), Labels.begin(), Labels.end()); // sort the array std::sort(rt.Labels.begin(), rt.Labels.end()); @@ -2272,8 +2270,7 @@ bool cmCTestTestHandler::SetTestsProperties( } } if (key == "PASS_REGULAR_EXPRESSION") { - std::vector<std::string> lval; - cmSystemTools::ExpandListArgument(val, lval); + std::vector<std::string> lval = cmExpandedList(val); for (std::string const& cr : lval) { rt.RequiredRegularExpressions.emplace_back(cr, cr); } @@ -2282,16 +2279,14 @@ bool cmCTestTestHandler::SetTestsProperties( rt.Directory = val; } if (key == "TIMEOUT_AFTER_MATCH") { - std::vector<std::string> propArgs; - cmSystemTools::ExpandListArgument(val, propArgs); + std::vector<std::string> propArgs = cmExpandedList(val); if (propArgs.size() != 2) { cmCTestLog(this->CTest, WARNING, "TIMEOUT_AFTER_MATCH expects two arguments, found " << propArgs.size() << std::endl); } else { rt.AlternateTimeout = cmDuration(atof(propArgs[0].c_str())); - std::vector<std::string> lval; - cmSystemTools::ExpandListArgument(propArgs[1], lval); + std::vector<std::string> lval = cmExpandedList(propArgs[1]); for (std::string const& cr : lval) { rt.TimeoutRegularExpressions.emplace_back(cr, cr); } @@ -2333,8 +2328,7 @@ bool cmCTestTestHandler::SetDirectoryProperties( std::string cwd = cmSystemTools::GetCurrentWorkingDirectory(); if (cwd == rt.Directory) { if (key == "LABELS") { - std::vector<std::string> DirectoryLabels; - cmSystemTools::ExpandListArgument(val, DirectoryLabels); + std::vector<std::string> DirectoryLabels = cmExpandedList(val); rt.Labels.insert(rt.Labels.end(), DirectoryLabels.begin(), DirectoryLabels.end()); diff --git a/Source/CTest/cmCTestTestHandler.h b/Source/CTest/cmCTestTestHandler.h index 7f3f5e4..9345185 100644 --- a/Source/CTest/cmCTestTestHandler.h +++ b/Source/CTest/cmCTestTestHandler.h @@ -118,6 +118,8 @@ public: std::vector<std::pair<cmsys::RegularExpression, std::string>> RequiredRegularExpressions; std::vector<std::pair<cmsys::RegularExpression, std::string>> + SkipRegularExpressions; + std::vector<std::pair<cmsys::RegularExpression, std::string>> TimeoutRegularExpressions; std::map<std::string, std::string> Measurements; bool IsInBasedOnREOptions; @@ -189,12 +191,25 @@ public: typedef std::vector<cmCTestTestProperties> ListOfTests; protected: + typedef std::set<cmCTestTestHandler::cmCTestTestResult, + cmCTestTestResultLess> + SetOfTests; + // compute a final test list virtual int PreProcessHandler(); virtual int PostProcessHandler(); virtual void GenerateTestCommand(std::vector<std::string>& args, int test); int ExecuteCommands(std::vector<std::string>& vec); + bool ProcessOptions(); + void LogTestSummary(const std::vector<std::string>& passed, + const std::vector<std::string>& failed, + const cmDuration& durationInSecs); + void LogDisabledTests(const std::vector<cmCTestTestResult>& disabledTests); + void LogFailedTests(const std::vector<std::string>& failed, + const SetOfTests& resultsSet); + bool GenerateXML(); + void WriteTestResultHeader(cmXMLWriter& xml, cmCTestTestResult const& result); void WriteTestResultFooter(cmXMLWriter& xml, diff --git a/Source/CTest/cmCTestUpdateCommand.h b/Source/CTest/cmCTestUpdateCommand.h index 3b2f3e1..55c4b80 100644 --- a/Source/CTest/cmCTestUpdateCommand.h +++ b/Source/CTest/cmCTestUpdateCommand.h @@ -6,11 +6,14 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cmCTestHandlerCommand.h" +#include "cmCommand.h" #include <string> +#include <utility> + +#include "cm_memory.hxx" class cmCTestGenericHandler; -class cmCommand; /** \class cmCTestUpdate * \brief Run a ctest script @@ -25,12 +28,12 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override + std::unique_ptr<cmCommand> Clone() override { - cmCTestUpdateCommand* ni = new cmCTestUpdateCommand; + auto ni = cm::make_unique<cmCTestUpdateCommand>(); ni->CTest = this->CTest; ni->CTestScriptHandler = this->CTestScriptHandler; - return ni; + return std::unique_ptr<cmCommand>(std::move(ni)); } /** diff --git a/Source/CTest/cmCTestUpdateHandler.cxx b/Source/CTest/cmCTestUpdateHandler.cxx index 5cfc4a7..a6a3542 100644 --- a/Source/CTest/cmCTestUpdateHandler.cxx +++ b/Source/CTest/cmCTestUpdateHandler.cxx @@ -2,7 +2,6 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCTestUpdateHandler.h" -#include "cmAlgorithms.h" #include "cmCLocaleEnvironmentScope.h" #include "cmCTest.h" #include "cmCTestBZR.h" @@ -13,14 +12,16 @@ #include "cmCTestSVN.h" #include "cmCTestVC.h" #include "cmGeneratedFileStream.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmVersion.h" #include "cmXMLWriter.h" #include <chrono> -#include <memory> // IWYU pragma: keep #include <sstream> +#include "cm_memory.hxx" + static const char* cmCTestUpdateHandlerUpdateStrings[] = { "Unknown", "CVS", "SVN", "BZR", "GIT", "HG", "P4" }; @@ -266,33 +267,27 @@ int cmCTestUpdateHandler::DetectVCS(const char* dir) if (cmSystemTools::FileExists(sourceDirectory)) { return cmCTestUpdateHandler::e_SVN; } - sourceDirectory = dir; - sourceDirectory += "/CVS"; + sourceDirectory = cmStrCat(dir, "/CVS"); if (cmSystemTools::FileExists(sourceDirectory)) { return cmCTestUpdateHandler::e_CVS; } - sourceDirectory = dir; - sourceDirectory += "/.bzr"; + sourceDirectory = cmStrCat(dir, "/.bzr"); if (cmSystemTools::FileExists(sourceDirectory)) { return cmCTestUpdateHandler::e_BZR; } - sourceDirectory = dir; - sourceDirectory += "/.git"; + sourceDirectory = cmStrCat(dir, "/.git"); if (cmSystemTools::FileExists(sourceDirectory)) { return cmCTestUpdateHandler::e_GIT; } - sourceDirectory = dir; - sourceDirectory += "/.hg"; + sourceDirectory = cmStrCat(dir, "/.hg"); if (cmSystemTools::FileExists(sourceDirectory)) { return cmCTestUpdateHandler::e_HG; } - sourceDirectory = dir; - sourceDirectory += "/.p4"; + sourceDirectory = cmStrCat(dir, "/.p4"); if (cmSystemTools::FileExists(sourceDirectory)) { return cmCTestUpdateHandler::e_P4; } - sourceDirectory = dir; - sourceDirectory += "/.p4config"; + sourceDirectory = cmStrCat(dir, "/.p4config"); if (cmSystemTools::FileExists(sourceDirectory)) { return cmCTestUpdateHandler::e_P4; } diff --git a/Source/CTest/cmCTestUploadCommand.h b/Source/CTest/cmCTestUploadCommand.h index 0d3b06e..2bb072f 100644 --- a/Source/CTest/cmCTestUploadCommand.h +++ b/Source/CTest/cmCTestUploadCommand.h @@ -6,12 +6,15 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cmCTestHandlerCommand.h" +#include "cmCommand.h" #include <set> #include <string> +#include <utility> + +#include "cm_memory.hxx" class cmCTestGenericHandler; -class cmCommand; /** \class cmCTestUpload * \brief Run a ctest script @@ -25,12 +28,12 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override + std::unique_ptr<cmCommand> Clone() override { - cmCTestUploadCommand* ni = new cmCTestUploadCommand; + auto ni = cm::make_unique<cmCTestUploadCommand>(); ni->CTest = this->CTest; ni->CTestScriptHandler = this->CTestScriptHandler; - return ni; + return std::unique_ptr<cmCommand>(std::move(ni)); } /** diff --git a/Source/CTest/cmCTestVC.cxx b/Source/CTest/cmCTestVC.cxx index eea41cf..773886d 100644 --- a/Source/CTest/cmCTestVC.cxx +++ b/Source/CTest/cmCTestVC.cxx @@ -3,6 +3,7 @@ #include "cmCTestVC.h" #include "cmCTest.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmXMLWriter.h" @@ -152,8 +153,7 @@ bool cmCTestVC::Update() // if update version only is on then do not actually update, // just note the current version and finish - if (!cmSystemTools::IsOn( - this->CTest->GetCTestConfiguration("UpdateVersionOnly"))) { + if (!cmIsOn(this->CTest->GetCTestConfiguration("UpdateVersionOnly"))) { result = this->NoteOldRevision() && result; this->Log << "--- Begin Update ---\n"; result = this->UpdateImpl() && result; diff --git a/Source/CTest/cmParseBlanketJSCoverage.cxx b/Source/CTest/cmParseBlanketJSCoverage.cxx index 63d6a15..b74decb 100644 --- a/Source/CTest/cmParseBlanketJSCoverage.cxx +++ b/Source/CTest/cmParseBlanketJSCoverage.cxx @@ -110,7 +110,8 @@ cmParseBlanketJSCoverage::cmParseBlanketJSCoverage( { } -bool cmParseBlanketJSCoverage::LoadCoverageData(std::vector<std::string> files) +bool cmParseBlanketJSCoverage::LoadCoverageData( + std::vector<std::string> const& files) { cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Found " << files.size() << " Files" << std::endl, diff --git a/Source/CTest/cmParseBlanketJSCoverage.h b/Source/CTest/cmParseBlanketJSCoverage.h index 696121f..cd1b225 100644 --- a/Source/CTest/cmParseBlanketJSCoverage.h +++ b/Source/CTest/cmParseBlanketJSCoverage.h @@ -29,7 +29,7 @@ class cmParseBlanketJSCoverage public: cmParseBlanketJSCoverage(cmCTestCoverageHandlerContainer& cont, cmCTest* ctest); - bool LoadCoverageData(std::vector<std::string> files); + bool LoadCoverageData(std::vector<std::string> const& files); // Read the JSON output bool ReadJSONFile(std::string const& file); diff --git a/Source/CTest/cmParseCacheCoverage.cxx b/Source/CTest/cmParseCacheCoverage.cxx index ca1fe70..cd2bb1a 100644 --- a/Source/CTest/cmParseCacheCoverage.cxx +++ b/Source/CTest/cmParseCacheCoverage.cxx @@ -2,6 +2,7 @@ #include "cmCTest.h" #include "cmCTestCoverageHandler.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmsys/Directory.hxx" @@ -30,9 +31,7 @@ bool cmParseCacheCoverage::LoadCoverageData(const char* d) for (i = 0; i < numf; i++) { std::string file = dir.GetFile(i); if (file != "." && file != ".." && !cmSystemTools::FileIsDirectory(file)) { - std::string path = d; - path += "/"; - path += file; + std::string path = cmStrCat(d, '/', file); if (cmSystemTools::GetFilenameLastExtension(path) == ".cmcov") { if (!this->ReadCMCovFile(path.c_str())) { return false; diff --git a/Source/CTest/cmParseCoberturaCoverage.cxx b/Source/CTest/cmParseCoberturaCoverage.cxx index 848a034..e0186c9 100644 --- a/Source/CTest/cmParseCoberturaCoverage.cxx +++ b/Source/CTest/cmParseCoberturaCoverage.cxx @@ -2,6 +2,7 @@ #include "cmCTest.h" #include "cmCTestCoverageHandler.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmXMLParser.h" @@ -75,7 +76,7 @@ protected: // Check if this is a path that is relative to our source or // binary directories. for (std::string const& filePath : FilePaths) { - finalpath = filePath + "/" + filename; + finalpath = cmStrCat(filePath, "/", filename); if (cmSystemTools::FileExists(finalpath)) { this->CurFileName = finalpath; break; @@ -86,7 +87,7 @@ protected: cmsys::ifstream fin(this->CurFileName.c_str()); if (this->CurFileName.empty() || !fin) { this->CurFileName = - this->Coverage.BinaryDir + "/" + atts[tagCount + 1]; + cmStrCat(this->Coverage.BinaryDir, "/", atts[tagCount + 1]); fin.open(this->CurFileName.c_str()); if (!fin) { cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, diff --git a/Source/CTest/cmParseGTMCoverage.cxx b/Source/CTest/cmParseGTMCoverage.cxx index 0722753..621ca79 100644 --- a/Source/CTest/cmParseGTMCoverage.cxx +++ b/Source/CTest/cmParseGTMCoverage.cxx @@ -1,8 +1,8 @@ #include "cmParseGTMCoverage.h" -#include "cmAlgorithms.h" #include "cmCTest.h" #include "cmCTestCoverageHandler.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmsys/Directory.hxx" @@ -31,9 +31,7 @@ bool cmParseGTMCoverage::LoadCoverageData(const char* d) for (i = 0; i < numf; i++) { std::string file = dir.GetFile(i); if (file != "." && file != ".." && !cmSystemTools::FileIsDirectory(file)) { - std::string path = d; - path += "/"; - path += file; + std::string path = cmStrCat(d, '/', file); if (cmSystemTools::GetFilenameLastExtension(path) == ".mcov") { if (!this->ReadMCovFile(path.c_str())) { return false; diff --git a/Source/CTest/cmParseJacocoCoverage.cxx b/Source/CTest/cmParseJacocoCoverage.cxx index b78142a..374acad 100644 --- a/Source/CTest/cmParseJacocoCoverage.cxx +++ b/Source/CTest/cmParseJacocoCoverage.cxx @@ -2,6 +2,7 @@ #include "cmCTest.h" #include "cmCTestCoverageHandler.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmXMLParser.h" @@ -103,9 +104,7 @@ protected: std::string const& baseDir) { // Search for the file in the baseDir and its subdirectories. - std::string packageGlob = baseDir; - packageGlob += "/"; - packageGlob += fileName; + std::string packageGlob = cmStrCat(baseDir, '/', fileName); cmsys::Glob gl; gl.RecurseOn(); gl.RecurseThroughSymlinksOn(); @@ -118,7 +117,7 @@ protected: // Check if any of the locations found match our package. for (std::string const& f : files) { std::string dir = cmsys::SystemTools::GetParentDirectory(f); - if (cmsys::SystemTools::StringEndsWith(dir, this->PackageName.c_str())) { + if (cmHasSuffix(dir, this->PackageName)) { cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Found package directory for " << fileName << ": " << dir << std::endl, diff --git a/Source/CTest/cmParseMumpsCoverage.cxx b/Source/CTest/cmParseMumpsCoverage.cxx index 4a81ee4..afd7dc3 100644 --- a/Source/CTest/cmParseMumpsCoverage.cxx +++ b/Source/CTest/cmParseMumpsCoverage.cxx @@ -2,6 +2,7 @@ #include "cmCTest.h" #include "cmCTestCoverageHandler.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmsys/FStream.hxx" @@ -107,8 +108,7 @@ bool cmParseMumpsCoverage::LoadPackages(const char* d) { cmsys::Glob glob; glob.RecurseOn(); - std::string pat = d; - pat += "/*.m"; + std::string pat = cmStrCat(d, "/*.m"); glob.FindFiles(pat); for (std::string& file : glob.GetFiles()) { std::string name = cmSystemTools::GetFilenameName(file); diff --git a/Source/CTest/cmParsePHPCoverage.cxx b/Source/CTest/cmParsePHPCoverage.cxx index a6e65c9..870e222 100644 --- a/Source/CTest/cmParsePHPCoverage.cxx +++ b/Source/CTest/cmParsePHPCoverage.cxx @@ -2,6 +2,7 @@ #include "cmCTest.h" #include "cmCTestCoverageHandler.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmsys/Directory.hxx" @@ -210,9 +211,7 @@ bool cmParsePHPCoverage::ReadPHPCoverageDirectory(const char* d) for (i = 0; i < numf; i++) { std::string file = dir.GetFile(i); if (file != "." && file != ".." && !cmSystemTools::FileIsDirectory(file)) { - std::string path = d; - path += "/"; - path += file; + std::string path = cmStrCat(d, '/', file); if (!this->ReadPHPData(path.c_str())) { return false; } diff --git a/Source/CTest/cmProcess.cxx b/Source/CTest/cmProcess.cxx index 7a3b82e..61d2ed3 100644 --- a/Source/CTest/cmProcess.cxx +++ b/Source/CTest/cmProcess.cxx @@ -7,6 +7,7 @@ #include "cmCTestRunTest.h" #include "cmCTestTestHandler.h" #include "cmGetPipes.h" +#include "cmStringAlgorithms.h" #include "cmsys/Process.h" #include <iostream> @@ -694,8 +695,7 @@ std::string cmProcess::GetExitExceptionString() # endif # endif default: - exception_str = "Signal "; - exception_str += std::to_string(this->Signal); + exception_str = cmStrCat("Signal ", this->Signal); } #endif return exception_str; |