From c8b93b9db6aa9668ea9ea9099e5298ed3ee77721 Mon Sep 17 00:00:00 2001 From: AJIOB Date: Fri, 11 Sep 2026 20:57:04 +0300 Subject: [PATCH] Source: Reduce string allocations --- Source/CPack/IFW/cmCPackIFWInstaller.cxx | 29 ++++----- Source/CPack/IFW/cmCPackIFWPackage.cxx | 34 ++++++----- Source/CPack/cmCPackDebGenerator.cxx | 24 ++++---- Source/CPack/cmCPackNSISGenerator.cxx | 77 +++++++++++------------- Source/CTest/cmCTestBuildCommand.cxx | 41 ++++++------- Source/CTest/cmCTestConfigureCommand.cxx | 57 ++++++++---------- Source/CTest/cmCTestMemCheckHandler.cxx | 33 +++++----- Source/CTest/cmCTestRunTest.cxx | 41 +++++-------- Source/CTest/cmCTestSubmitHandler.cxx | 55 ++++++++--------- Source/cmCommonTargetGenerator.cxx | 66 ++++++++++---------- Source/cmConfigureFileCommand.cxx | 22 +++---- Source/cmExecProgramCommand.cxx | 23 +++---- Source/cmExecuteProcessCommand.cxx | 9 +-- Source/cmExtraCodeBlocksGenerator.cxx | 26 +++----- Source/cmFileCopier.cxx | 16 ++--- Source/cmInstallTargetGenerator.cxx | 17 ++---- Source/cmInstallTargetsCommand.cxx | 5 +- Source/cmMathCommand.cxx | 19 +++--- Source/cmRulePlaceholderExpander.cxx | 52 +++++++--------- Source/cmWriteFileCommand.cxx | 11 ++-- 20 files changed, 296 insertions(+), 361 deletions(-) diff --git a/Source/CPack/IFW/cmCPackIFWInstaller.cxx b/Source/CPack/IFW/cmCPackIFWInstaller.cxx index da373dba8b..717eb55217 100644 --- a/Source/CPack/IFW/cmCPackIFWInstaller.cxx +++ b/Source/CPack/IFW/cmCPackIFWInstaller.cxx @@ -409,8 +409,8 @@ protected: if (this->file) { std::string content(data, data + length); content = cmTrimWhitespace(content); - std::string source = this->basePath + "/" + content; - std::string destination = this->path + "/" + content; + std::string source = cmStrCat(this->basePath, '/', content); + std::string destination = cmStrCat(this->path, '/', content); if (!cmSystemTools::CopyFileIfDifferent(source, destination)) { this->hasErrors = true; } @@ -454,7 +454,7 @@ void cmCPackIFWInstaller::GenerateInstallerFile() std::string srcName = cmSystemTools::GetFilenameName(this->Logo); std::string suffix = cmSystemTools::GetFilenameLastExtension(srcName); std::string name = "cm_logo" + suffix; - std::string path = this->Directory + "/config/" + name; + std::string path = cmStrCat(this->Directory, "/config/", name); cmsys::SystemTools::CopyFileIfDifferent(this->Logo, path); xout.Element("Logo", name); } @@ -462,7 +462,7 @@ void cmCPackIFWInstaller::GenerateInstallerFile() // Banner if (!this->Banner.empty()) { std::string name = cmSystemTools::GetFilenameName(this->Banner); - std::string path = this->Directory + "/config/" + name; + std::string path = cmStrCat(this->Directory, "/config/", name); cmsys::SystemTools::CopyFileIfDifferent(this->Banner, path); xout.Element("Banner", name); } @@ -470,7 +470,7 @@ void cmCPackIFWInstaller::GenerateInstallerFile() // Watermark if (!this->Watermark.empty()) { std::string name = cmSystemTools::GetFilenameName(this->Watermark); - std::string path = this->Directory + "/config/" + name; + std::string path = cmStrCat(this->Directory, "/config/", name); cmsys::SystemTools::CopyFileIfDifferent(this->Watermark, path); xout.Element("Watermark", name); } @@ -478,7 +478,7 @@ void cmCPackIFWInstaller::GenerateInstallerFile() // Background if (!this->Background.empty()) { std::string name = cmSystemTools::GetFilenameName(this->Background); - std::string path = this->Directory + "/config/" + name; + std::string path = cmStrCat(this->Directory, "/config/", name); cmsys::SystemTools::CopyFileIfDifferent(this->Background, path); xout.Element("Background", name); } @@ -491,7 +491,7 @@ void cmCPackIFWInstaller::GenerateInstallerFile() cmSystemTools::GetFilenameName(this->InstallerApplicationIcon); std::string suffix = cmSystemTools::GetFilenameLastExtension(srcName); std::string name = "cm_appicon" + suffix; - std::string path = this->Directory + "/config/" + name; + std::string path = cmStrCat(this->Directory, "/config/", name); cmsys::SystemTools::CopyFileIfDifferent(this->InstallerApplicationIcon, path); // The actual file is looked up by attaching a '.icns' (macOS), @@ -506,7 +506,7 @@ void cmCPackIFWInstaller::GenerateInstallerFile() cmSystemTools::GetFilenameName(this->InstallerWindowIcon); std::string suffix = cmSystemTools::GetFilenameLastExtension(srcName); std::string name = "cm_winicon" + suffix; - std::string path = this->Directory + "/config/" + name; + std::string path = cmStrCat(this->Directory, "/config/", name); cmsys::SystemTools::CopyFileIfDifferent(this->InstallerWindowIcon, path); xout.Element("InstallerWindowIcon", name); } @@ -549,7 +549,7 @@ void cmCPackIFWInstaller::GenerateInstallerFile() // Control script (copy to config dir) if (!this->ControlScript.empty()) { std::string name = cmSystemTools::GetFilenameName(this->ControlScript); - std::string path = this->Directory + "/config/" + name; + std::string path = cmStrCat(this->Directory, "/config/", name); cmsys::SystemTools::CopyFileIfDifferent(this->ControlScript, path); xout.Element("ControlScript", name); } @@ -589,7 +589,7 @@ void cmCPackIFWInstaller::GenerateInstallerFile() // Stylesheet (copy to config dir) if (!this->StyleSheet.empty()) { std::string name = cmSystemTools::GetFilenameName(this->StyleSheet); - std::string path = this->Directory + "/config/" + name; + std::string path = cmStrCat(this->Directory, "/config/", name); cmsys::SystemTools::CopyFileIfDifferent(this->StyleSheet, path); xout.Element("StyleSheet", name); } @@ -645,7 +645,7 @@ void cmCPackIFWInstaller::GenerateInstallerFile() xout.StartElement("ProductImage"); auto const& srcImg = this->ProductImages[i]; std::string name = cmSystemTools::GetFilenameName(srcImg); - std::string dstImg = this->Directory + "/config/" + name; + std::string dstImg = cmStrCat(this->Directory, "/config/", name); cmsys::SystemTools::CopyFileIfDifferent(srcImg, dstImg); xout.Element("Image", name); if (hasProductImageUrl) { @@ -663,7 +663,7 @@ void cmCPackIFWInstaller::GenerateInstallerFile() for (size_t i = 0; i < this->Resources.size(); i++) { if (parser.ParseResource(i)) { std::string name = cmSystemTools::GetFilenameName(this->Resources[i]); - std::string path = this->Directory + "/resources/" + name; + std::string path = cmStrCat(this->Directory, "/resources/", name); cmsys::SystemTools::CopyFileIfDifferent(this->Resources[i], path); resources.push_back(std::move(name)); } else { @@ -690,8 +690,9 @@ void cmCPackIFWInstaller::GeneratePackageFiles() // Check package group if (cmValue option = this->GetOption("CPACK_IFW_PACKAGE_GROUP")) { package.ConfigureFromGroup(*option); - std::string forcedOption = "CPACK_IFW_COMPONENT_GROUP_" + - cmsys::SystemTools::UpperCase(*option) + "_FORCED_INSTALLATION"; + std::string forcedOption = cmStrCat( + "CPACK_IFW_COMPONENT_GROUP_", cmsys::SystemTools::UpperCase(*option), + "_FORCED_INSTALLATION"); if (!this->GetOption(forcedOption)) { package.ForcedInstallation = "true"; } diff --git a/Source/CPack/IFW/cmCPackIFWPackage.cxx b/Source/CPack/IFW/cmCPackIFWPackage.cxx index 5c101e9c36..1d7a97d54c 100644 --- a/Source/CPack/IFW/cmCPackIFWPackage.cxx +++ b/Source/CPack/IFW/cmCPackIFWPackage.cxx @@ -126,9 +126,9 @@ std::string cmCPackIFWPackage::GetComponentName(cmCPackComponent* component) if (!component) { return ""; } - cmValue option = - this->GetOption("CPACK_IFW_COMPONENT_" + - cmsys::SystemTools::UpperCase(component->Name) + "_NAME"); + cmValue option = this->GetOption( + cmStrCat("CPACK_IFW_COMPONENT_", + cmsys::SystemTools::UpperCase(component->Name), "_NAME")); return option ? *option : component->Name; } @@ -195,8 +195,9 @@ int cmCPackIFWPackage::ConfigureFromComponent(cmCPackComponent* component) // Restore default configuration this->DefaultConfiguration(); - std::string prefix = "CPACK_IFW_COMPONENT_" + - cmsys::SystemTools::UpperCase(component->Name) + "_"; + std::string prefix = + cmStrCat("CPACK_IFW_COMPONENT_", + cmsys::SystemTools::UpperCase(component->Name), '_'); // Display name this->DisplayName[""] = component->DisplayName; @@ -283,8 +284,9 @@ int cmCPackIFWPackage::ConfigureFromGroup(cmCPackComponentGroup* group) // Restore default configuration this->DefaultConfiguration(); - std::string prefix = "CPACK_IFW_COMPONENT_GROUP_" + - cmsys::SystemTools::UpperCase(group->Name) + "_"; + std::string prefix = + cmStrCat("CPACK_IFW_COMPONENT_GROUP_", + cmsys::SystemTools::UpperCase(group->Name), '_'); this->DisplayName[""] = group->DisplayName; this->Description[""] = group->Description; @@ -344,8 +346,8 @@ int cmCPackIFWPackage::ConfigureFromGroup(std::string const& groupName) // Group configuration cmCPackComponentGroup group; - std::string prefix = - "CPACK_COMPONENT_GROUP_" + cmsys::SystemTools::UpperCase(groupName) + "_"; + std::string prefix = cmStrCat("CPACK_COMPONENT_GROUP_", + cmsys::SystemTools::UpperCase(groupName), '_'); if (cmValue option = this->GetOption(prefix + "DISPLAY_NAME")) { group.DisplayName = *option; @@ -544,9 +546,11 @@ void cmCPackIFWPackage::GeneratePackageFile() // Lazy directory initialization if (this->Directory.empty()) { if (this->Installer) { - this->Directory = this->Installer->Directory + "/packages/" + this->Name; + this->Directory = + cmStrCat(this->Installer->Directory, "/packages/", this->Name); } else if (this->Generator) { - this->Directory = this->Generator->toplevel + "/packages/" + this->Name; + this->Directory = + cmStrCat(this->Generator->toplevel, "/packages/", this->Name); } } @@ -597,7 +601,7 @@ void cmCPackIFWPackage::GeneratePackageFile() // Script (copy to meta dir) if (!this->Script.empty()) { std::string name = cmSystemTools::GetFilenameName(this->Script); - std::string path = this->Directory + "/meta/" + name; + std::string path = cmStrCat(this->Directory, "/meta/", name); cmsys::SystemTools::CopyFileIfDifferent(this->Script, path); xout.Element("Script", name); } @@ -606,7 +610,7 @@ void cmCPackIFWPackage::GeneratePackageFile() std::vector userInterfaces = this->UserInterfaces; for (std::string& userInterface : userInterfaces) { std::string name = cmSystemTools::GetFilenameName(userInterface); - std::string path = this->Directory + "/meta/" + name; + std::string path = cmStrCat(this->Directory, "/meta/", name); cmsys::SystemTools::CopyFileIfDifferent(userInterface, path); userInterface = name; } @@ -622,7 +626,7 @@ void cmCPackIFWPackage::GeneratePackageFile() std::vector translations = this->Translations; for (std::string& translation : translations) { std::string name = cmSystemTools::GetFilenameName(translation); - std::string path = this->Directory + "/meta/" + name; + std::string path = cmStrCat(this->Directory, "/meta/", name); cmsys::SystemTools::CopyFileIfDifferent(translation, path); translation = name; } @@ -697,7 +701,7 @@ void cmCPackIFWPackage::GeneratePackageFile() std::vector licenses = this->Licenses; for (size_t i = 1; i < licenses.size(); i += 2) { std::string name = cmSystemTools::GetFilenameName(licenses[i]); - std::string path = this->Directory + "/meta/" + name; + std::string path = cmStrCat(this->Directory, "/meta/", name); cmsys::SystemTools::CopyFileIfDifferent(licenses[i], path); licenses[i] = name; } diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx index 63e58a4ed9..289866b44f 100644 --- a/Source/CPack/cmCPackDebGenerator.cxx +++ b/Source/CPack/cmCPackDebGenerator.cxx @@ -202,7 +202,7 @@ void DebGenerator::generateControlFile() const bool DebGenerator::generateDataTar() const { std::string filename_data_tar = - this->WorkDir + "/data.tar" + this->CompressionSuffix; + cmStrCat(this->WorkDir, "/data.tar", this->CompressionSuffix); cmGeneratedFileStream fileStream_data_tar; fileStream_data_tar.Open(filename_data_tar, false, true); if (!fileStream_data_tar) { @@ -317,7 +317,7 @@ std::string DebGenerator::generateMD5File() const "Problem computing the md5 of " << file << std::endl); } - output += " " + file + "\n"; + output = cmStrCat(std::move(output), " ", file, '\n'); // debian md5sums entries are like this: // 014f3604694729f3bf19263bac599765 usr/bin/ccmake // thus strip the full path (with the trailing slash) @@ -333,7 +333,7 @@ std::string DebGenerator::generateMD5File() const bool DebGenerator::generateControlTar(std::string const& md5Filename) const { std::string filename_control_tar = - this->WorkDir + "/control.tar" + this->CompressionSuffix; + cmStrCat(this->WorkDir, "/control.tar", this->CompressionSuffix); cmGeneratedFileStream fileStream_control_tar; fileStream_control_tar.Open(filename_control_tar, false, true); @@ -466,7 +466,7 @@ bool DebGenerator::generateControlTar(std::string const& md5Filename) const cmList controlExtraList{ this->ControlExtra }; for (std::string const& i : controlExtraList) { std::string filenamename = cmsys::SystemTools::GetFilenameName(i); - std::string localcopy = this->WorkDir + "/" + filenamename; + std::string localcopy = cmStrCat(this->WorkDir, '/', filenamename); if (this->PermissionStrictPolicy) { control_tar.SetPermissions( @@ -500,7 +500,8 @@ bool DebGenerator::generateDeb() const // difference is that debian uses the BSD ar style archive whereas most // Linux distro have a GNU ar. // See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=161593 for more info - std::string const outputPath = this->TopLevelDir + "/" + this->OutputName; + std::string const outputPath = + cmStrCat(this->TopLevelDir, '/', this->OutputName); std::string const tlDir = this->WorkDir + "/"; cmGeneratedFileStream debStream; debStream.Open(outputPath, false, true); @@ -581,13 +582,14 @@ int cmCPackDebGenerator::PackageOnePack(std::string const& initialTopLevel, std::string localToplevel(initialTopLevel); std::string packageFileName( cmSystemTools::GetParentDirectory(this->toplevel)); - std::string outputFileName(*this->GetOption("CPACK_PACKAGE_FILE_NAME") + - "-" + packageName + this->GetOutputExtension()); + std::string outputFileName( + cmStrCat(*this->GetOption("CPACK_PACKAGE_FILE_NAME"), '-', packageName, + this->GetOutputExtension())); - localToplevel += "/" + sanitizedPkgDirName; + localToplevel = cmStrCat(std::move(localToplevel), '/', sanitizedPkgDirName); /* replace the TEMP DIRECTORY with the component one */ this->SetOption("CPACK_TEMPORARY_DIRECTORY", localToplevel); - packageFileName += "/" + outputFileName; + packageFileName = cmStrCat(std::move(packageFileName), '/', outputFileName); /* replace proposed CPACK_OUTPUT_FILE_NAME */ this->SetOption("CPACK_OUTPUT_FILE_NAME", outputFileName); /* replace the TEMPORARY package file name */ @@ -672,12 +674,12 @@ int cmCPackDebGenerator::PackageComponentsAllInOne( // if must be here otherwise non component paths have a trailing / while // components don't if (!compInstDirName.empty()) { - localToplevel += "/" + compInstDirName; + localToplevel = cmStrCat(std::move(localToplevel), '/', compInstDirName); } /* replace the TEMP DIRECTORY with the component one */ this->SetOption("CPACK_TEMPORARY_DIRECTORY", localToplevel); - packageFileName += "/" + outputFileName; + packageFileName = cmStrCat(std::move(packageFileName), '/', outputFileName); /* replace proposed CPACK_OUTPUT_FILE_NAME */ this->SetOption("CPACK_OUTPUT_FILE_NAME", outputFileName); /* replace the TEMPORARY package file name */ diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx index 551a93e7ef..af41f48416 100644 --- a/Source/CPack/cmCPackNSISGenerator.cxx +++ b/Source/CPack/cmCPackNSISGenerator.cxx @@ -301,9 +301,8 @@ int cmCPackNSISGenerator::PackageFiles() installTypes[installType.second.Index - 1] = &installType.second; } for (cmCPackInstallationType* installType : installTypes) { - installTypesCode += "InstType \""; - installTypesCode += installType->DisplayName; - installTypesCode += "\"\n"; + installTypesCode = cmStrCat(std::move(installTypesCode), "InstType \"", + installType->DisplayName, "\"\n"); } // Create installation groups first @@ -315,10 +314,11 @@ int cmCPackNSISGenerator::PackageFiles() // Add the group description, if any. if (!group.second.Description.empty()) { - groupDescriptions += " !insertmacro MUI_DESCRIPTION_TEXT ${" + - group.first + "} \"" + - cmCPackNSISGenerator::TranslateNewlines(group.second.Description) + - "\"\n"; + groupDescriptions = cmStrCat( + std::move(groupDescriptions), + " !insertmacro MUI_DESCRIPTION_TEXT ${", group.first, "} \"", + cmCPackNSISGenerator::TranslateNewlines(group.second.Description), + "\"\n"); } } @@ -338,18 +338,20 @@ int cmCPackNSISGenerator::PackageFiles() } // Add this component to the various section lists. - sectionList += R"( !insertmacro "${MacroName}" ")"; - sectionList += comp.first; - sectionList += "\"\n"; - selectedVarsList += "Var " + comp.first + "_selected\n"; - selectedVarsList += "Var " + comp.first + "_was_installed\n"; + sectionList = + cmStrCat(std::move(sectionList), R"( !insertmacro "${MacroName}" ")", + comp.first, "\"\n"); + selectedVarsList = + cmStrCat(std::move(selectedVarsList), "Var ", comp.first, + "_selected\nVar ", comp.first, "_was_installed\n"); // Add the component description, if any. if (!comp.second.Description.empty()) { - componentDescriptions += " !insertmacro MUI_DESCRIPTION_TEXT ${" + - comp.first + "} \"" + - cmCPackNSISGenerator::TranslateNewlines(comp.second.Description) + - "\"\n"; + componentDescriptions = cmStrCat( + std::move(componentDescriptions), + " !insertmacro MUI_DESCRIPTION_TEXT ${", comp.first, "} \"", + cmCPackNSISGenerator::TranslateNewlines(comp.second.Description), + "\"\n"); } } @@ -360,9 +362,10 @@ int cmCPackNSISGenerator::PackageFiles() this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_MUI_COMPONENTS_DESC", "!define MUI_COMPONENTSPAGE_NODESC"); } else { - componentDescriptions = "!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN\n" + - componentDescriptions + groupDescriptions + - "!insertmacro MUI_FUNCTION_DESCRIPTION_END\n"; + componentDescriptions = + cmStrCat("!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN\n", + std::move(componentDescriptions), groupDescriptions, + "!insertmacro MUI_FUNCTION_DESCRIPTION_END\n"); this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_MUI_COMPONENTS_DESC", componentDescriptions); } @@ -499,7 +502,7 @@ int cmCPackNSISGenerator::InitializeInternal() return 0; } - std::string nsisCmd = "\"" + nsisPath + "\" " NSIS_OPT "VERSION"; + std::string nsisCmd = cmStrCat('"', nsisPath, "\" " NSIS_OPT "VERSION"); cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Test NSIS version: " << nsisCmd << std::endl); std::string output; @@ -718,15 +721,10 @@ std::string cmCPackNSISGenerator::CreateComponentDescription( cmCPackComponent* component, std::ostream& macrosOut) { // Basic description of the component - std::string componentCode = "Section "; - if (component->IsDisabledByDefault) { - componentCode += "/o "; - } - componentCode += "\""; - if (component->IsHidden) { - componentCode += "-"; - } - componentCode += component->DisplayName + "\" " + component->Name + "\n"; + std::string componentCode = + cmStrCat("Section ", component->IsDisabledByDefault ? "/o " : "", '"', + component->IsHidden ? "-" : "", component->DisplayName, "\" ", + component->Name, '\n'); if (component->IsRequired) { componentCode += " SectionIn RO\n"; } else if (!component->InstallationTypes.empty()) { @@ -735,7 +733,8 @@ std::string cmCPackNSISGenerator::CreateComponentDescription( component->InstallationTypes) { out << " " << installType->Index; } - componentCode += " SectionIn" + out.str() + "\n"; + componentCode = + cmStrCat(std::move(componentCode), " SectionIn", out.str(), '\n'); } std::string const componentOutputDir = @@ -868,8 +867,9 @@ std::string cmCPackNSISGenerator::CreateComponentDescription( /* clang-format on */ componentCode += out.str(); } else { - componentCode += " File /r \"${INST_DIR}\\" + - this->GetSanitizedDirOrFileName(component->Name) + "\\*.*\"\n"; + componentCode = + cmStrCat(std::move(componentCode), " File /r \"${INST_DIR}\\", + this->GetSanitizedDirOrFileName(component->Name), "\\*.*\"\n"); } componentCode += "SectionEnd\n"; @@ -967,15 +967,10 @@ std::string cmCPackNSISGenerator::CreateComponentGroupDescription( return {}; } - std::string code = "SectionGroup "; - if (group->IsExpandedByDefault) { - code += "/e "; - } - if (group->IsBold) { - code += "\"!" + group->DisplayName + "\" " + group->Name + "\n"; - } else { - code += "\"" + group->DisplayName + "\" " + group->Name + "\n"; - } + std::string code = + cmStrCat("SectionGroup ", group->IsExpandedByDefault ? "/e " : "", + group->IsBold ? "\"!" : "\"", group->DisplayName, "\" ", + group->Name, '\n'); for (cmCPackComponentGroup* g : group->Subgroups) { code += this->CreateComponentGroupDescription(g, macrosOut); diff --git a/Source/CTest/cmCTestBuildCommand.cxx b/Source/CTest/cmCTestBuildCommand.cxx index f55ef65f30..3c4fa75384 100644 --- a/Source/CTest/cmCTestBuildCommand.cxx +++ b/Source/CTest/cmCTestBuildCommand.cxx @@ -149,37 +149,32 @@ std::unique_ptr cmCTestBuildCommand::InitializeHandler( } std::string buildCommand = - cmStrCat('"', cmSystemTools::GetCMakeCommand(), '"'); - buildCommand += " --build . --preset \""; - buildCommand += effectivePreset; - buildCommand += "\""; + cmStrCat('"', cmSystemTools::GetCMakeCommand(), + "\" --build . --preset \"", effectivePreset, '"'); if (!presetsFile.empty()) { - buildCommand += " --presets-file \""; - buildCommand += presetsFile; - buildCommand += "\""; + buildCommand = cmStrCat(std::move(buildCommand), " --presets-file \"", + presetsFile, '"'); } if (!cmakeBuildConfiguration.empty()) { - buildCommand += " --config \""; - buildCommand += cmakeBuildConfiguration; - buildCommand += "\""; + buildCommand = cmStrCat(std::move(buildCommand), " --config \"", + cmakeBuildConfiguration, '"'); } if (!cmakeBuildTarget.empty()) { - buildCommand += " --target \""; - buildCommand += cmakeBuildTarget; - buildCommand += "\""; + buildCommand = cmStrCat(std::move(buildCommand), " --target \"", + cmakeBuildTarget, '"'); } if (!args.ParallelLevel.empty()) { - buildCommand += " --parallel "; - buildCommand += args.ParallelLevel; + buildCommand = + cmStrCat(std::move(buildCommand), " --parallel ", args.ParallelLevel); } if (!cmakeBuildAdditionalFlags.empty()) { - buildCommand += " -- "; - buildCommand += cmakeBuildAdditionalFlags; + buildCommand = + cmStrCat(std::move(buildCommand), " -- ", cmakeBuildAdditionalFlags); } cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, @@ -197,9 +192,9 @@ std::unique_ptr cmCTestBuildCommand::InitializeHandler( auto globalGenerator = mf.GetCMakeInstance()->CreateGlobalGenerator(*cmakeGeneratorName); if (!globalGenerator) { - std::string e = cmStrCat("could not create generator named \"", - *cmakeGeneratorName, '"'); - mf.IssueMessage(MessageType::FATAL_ERROR, e); + mf.IssueMessage(MessageType::FATAL_ERROR, + cmStrCat("could not create generator named \"", + *cmakeGeneratorName, '"')); cmSystemTools::SetFatalErrorOccurred(); return nullptr; } @@ -217,14 +212,14 @@ std::unique_ptr cmCTestBuildCommand::InitializeHandler( this->CTest->SetCTestConfiguration("MakeCommand", buildCommand, args.Quiet); } else { - std::ostringstream ostr; + std::string error; /* clang-format off */ - ostr << "has no project to build. If this is a " + error = "has no project to build. If this is a " "\"built with CMake\" project, verify that CTEST_CMAKE_GENERATOR " "is set. Otherwise, set CTEST_BUILD_COMMAND to build the project " "with a custom command line."; /* clang-format on */ - status.SetError(ostr.str()); + status.SetError(error); return nullptr; } } diff --git a/Source/CTest/cmCTestConfigureCommand.cxx b/Source/CTest/cmCTestConfigureCommand.cxx index c137d48c94..cdfe3a599b 100644 --- a/Source/CTest/cmCTestConfigureCommand.cxx +++ b/Source/CTest/cmCTestConfigureCommand.cxx @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -43,22 +44,20 @@ bool ConstructConfigureCommand(cmExecutionStatus& status, cmMakefile& mf, std::string const presetsFile, std::string& configureCommand) { - configureCommand = cmStrCat('"', cmSystemTools::GetCMakeCommand(), '"'); - configureCommand += " \"-S"; - configureCommand += cmSystemTools::CollapseFullPath(sourceDirectory); - configureCommand += "\""; + configureCommand = + cmStrCat('"', cmSystemTools::GetCMakeCommand(), "\" \"-S", + cmSystemTools::CollapseFullPath(sourceDirectory), '"'); if (!buildDirectory.empty()) { - configureCommand += " \"-B"; - configureCommand += cmSystemTools::CollapseFullPath(buildDirectory); - configureCommand += "\""; + configureCommand = + cmStrCat(std::move(configureCommand), " \"-B", + cmSystemTools::CollapseFullPath(buildDirectory), '"'); } cmValue cmakeGenerator = mf.GetDefinition("CTEST_CMAKE_GENERATOR"); if (cmNonempty(cmakeGenerator)) { - configureCommand += " \"-G"; - configureCommand += cmakeGenerator; - configureCommand += "\""; + configureCommand = + cmStrCat(std::move(configureCommand), " \"-G", cmakeGenerator, '"'); } bool presetProvidesBuildDir = false; @@ -86,16 +85,12 @@ bool ConstructConfigureCommand(cmExecutionStatus& status, cmMakefile& mf, auto const* expandedPreset = resolveResult.Preset; - configureCommand += " \"--preset\""; - configureCommand += " \""; - configureCommand += presetName; - configureCommand += "\""; + configureCommand = cmStrCat(std::move(configureCommand), + R"( "--preset" ")", presetName, '"'); if (!presetsFile.empty()) { - configureCommand += " \"--presets-file\""; - configureCommand += " \""; - configureCommand += presetsFile; - configureCommand += "\""; + configureCommand = cmStrCat(std::move(configureCommand), + R"( "--presets-file" ")", presetsFile, '"'); } if (!expandedPreset->BinaryDir.empty()) { @@ -149,25 +144,22 @@ bool ConstructConfigureCommand(cmExecutionStatus& status, cmMakefile& mf, } initialCache.Close(); - configureCommand += " \"-C"; - configureCommand += initialCacheFile; - configureCommand += "\""; + configureCommand = + cmStrCat(std::move(configureCommand), " \"-C", initialCacheFile, '"'); } cmValue cmakeGeneratorPlatform = mf.GetDefinition("CTEST_CMAKE_GENERATOR_PLATFORM"); if (cmNonempty(cmakeGeneratorPlatform)) { - configureCommand += " \"-A"; - configureCommand += *cmakeGeneratorPlatform; - configureCommand += "\""; + configureCommand = cmStrCat(std::move(configureCommand), " \"-A", + *cmakeGeneratorPlatform, '"'); } cmValue cmakeGeneratorToolset = mf.GetDefinition("CTEST_CMAKE_GENERATOR_TOOLSET"); if (cmNonempty(cmakeGeneratorToolset)) { - configureCommand += " \"-T"; - configureCommand += *cmakeGeneratorToolset; - configureCommand += "\""; + configureCommand = cmStrCat(std::move(configureCommand), " \"-T", + *cmakeGeneratorToolset, '"'); } // Append OPTIONS to the configure command. @@ -183,16 +175,15 @@ bool ConstructConfigureCommand(cmExecutionStatus& status, cmMakefile& mf, auto const optionsList = cmList(options); for (std::string const& option : optionsList) { - configureCommand += " \""; - configureCommand += option; - configureCommand += "\""; + configureCommand = + cmStrCat(std::move(configureCommand), " \"", option, '"'); } cmValue cmakeBuildType = mf.GetDefinition("CTEST_CONFIGURATION_TYPE"); if (!multiConfig && !buildTypeInOptions && cmNonempty(cmakeBuildType)) { - configureCommand += " \"-DCMAKE_BUILD_TYPE:STRING="; - configureCommand += cmakeBuildType; - configureCommand += "\""; + configureCommand = + cmStrCat(std::move(configureCommand), + " \"-DCMAKE_BUILD_TYPE:STRING=", cmakeBuildType, '"'); } return true; diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx index 11b2ec6c10..c691c5a598 100644 --- a/Source/CTest/cmCTestMemCheckHandler.cxx +++ b/Source/CTest/cmCTestMemCheckHandler.cxx @@ -18,6 +18,7 @@ #include "cmCTest.h" #include "cmDuration.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmXMLParser.h" #include "cmXMLWriter.h" @@ -165,9 +166,7 @@ void cmCTestMemCheckHandler::GenerateTestCommand( arg.replace(pos, 2, index); } args.push_back(arg); - memcheckcommand += " \""; - memcheckcommand += arg; - memcheckcommand += "\""; + memcheckcommand = cmStrCat(std::move(memcheckcommand), " \"", arg, '"'); if (nextArgIsDir) { nextArgIsDir = false; @@ -188,15 +187,14 @@ void cmCTestMemCheckHandler::GenerateTestCommand( if (!memTesterEnvironmentVariable.empty()) { // If we are using env to pass options, append all the options to // this string with space separation. - memTesterEnvironmentVariable += " " + arg; + memTesterEnvironmentVariable = + cmStrCat(std::move(memTesterEnvironmentVariable), ' ', arg); } // for regular options just add them to args and memcheckcommand // which is just used for display else { args.push_back(arg); - memcheckcommand += " \""; - memcheckcommand += arg; - memcheckcommand += "\""; + memcheckcommand = cmStrCat(std::move(memcheckcommand), " \"", arg, '"'); } } // if this is an env option type, then add the env string as a single @@ -206,7 +204,8 @@ void cmCTestMemCheckHandler::GenerateTestCommand( if (pos != std::string::npos) { memTesterEnvironmentVariable.replace(pos, 2, index); } - memcheckcommand += " " + memTesterEnvironmentVariable; + memcheckcommand = + cmStrCat(std::move(memcheckcommand), ' ', memTesterEnvironmentVariable); args.push_back(memTesterEnvironmentVariable); } @@ -339,7 +338,7 @@ void cmCTestMemCheckHandler::GenerateCTestXML(cmXMLWriter& xml) xml.StartElement("TestList"); cmCTestMemCheckHandler::TestResultsVector::size_type cc; for (cmCTestTestResult const& result : this->TestResults) { - std::string testPath = result.Path + "/" + result.Name; + std::string testPath = cmStrCat(result.Path, '/', result.Name); xml.Element("Test", this->CTest->GetShortPathToFile(testPath)); } xml.EndElement(); // TestList @@ -746,10 +745,9 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking() } // Quote log_path with single quotes; see // https://bugs.chromium.org/p/chromium/issues/detail?id=467936 - std::string outputFile = - envVar + "=log_path='" + this->MemoryTesterOutputFile + "'"; this->MemoryTesterEnvironmentVariable = - outputFile + suppressionsOption + extraOptions; + cmStrCat(envVar, "=log_path='", this->MemoryTesterOutputFile, '\'', + suppressionsOption, extraOptions); break; } default: @@ -1290,16 +1288,15 @@ void cmCTestMemCheckHandler::PostProcessBoundsCheckerTest( { cmsys::ifstream ifs(ofile.c_str()); if (!ifs) { - std::string log = "Cannot read memory tester output file: " + ofile; - cmCTestLog(this->CTest, ERROR_MESSAGE, log << std::endl); + cmCTestLog(this->CTest, ERROR_MESSAGE, + cmStrCat("Cannot read memory tester output file: ", ofile) + << std::endl); return; } - res.Output += BOUNDS_CHECKER_MARKER; - res.Output += "\n"; + res.Output = cmStrCat(std::move(res.Output), BOUNDS_CHECKER_MARKER, '\n'); std::string line; while (cmSystemTools::GetLineFromStream(ifs, line)) { - res.Output += line; - res.Output += "\n"; + res.Output = cmStrCat(std::move(res.Output), line, '\n'); } } cmSystemTools::Delay(1000); diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx index 71c4f6d73f..e8a1fdf2a4 100644 --- a/Source/CTest/cmCTestRunTest.cxx +++ b/Source/CTest/cmCTestRunTest.cxx @@ -83,8 +83,7 @@ void cmCTestRunTest::CheckOutput(std::string const& line) } } - this->ProcessOutput += line; - this->ProcessOutput += "\n"; + this->ProcessOutput = cmStrCat(std::move(this->ProcessOutput), line, '\n'); // Check for TIMEOUT_AFTER_MATCH property. if (!this->TestProperties->TimeoutRegularExpressions.empty()) { @@ -136,10 +135,9 @@ cmCTestRunTest::EndTestResult cmCTestRunTest::EndTest(size_t completed, if (!found) { reason = "Required regular expression not found. Regex=["; for (auto& pass : this->TestProperties->RequiredRegularExpressions) { - reason += pass.second; - reason += "\n"; + reason = cmStrCat(std::move(reason), pass.second, '\n'); } - reason += "]"; + reason += ']'; forceFail = true; } } @@ -265,16 +263,15 @@ cmCTestRunTest::EndTestResult cmCTestRunTest::EndTest(size_t completed, std::max(this->CTest->GetMaxTestNameWidth(), testName.size()); testName.resize(maxTestNameWidth + 4, '.'); - output += testName; - output += outputStream.str(); + output = cmStrCat(std::move(output), testName, outputStream.str()); outputStream.str(""); outputStream.clear(); outputStream << output; cmCTestLog(this->CTest, HANDLER_TEST_PROGRESS_OUTPUT, "\n"); // flush } if (completed == total) { - std::string testName = this->GetTestPrefix(completed, total) + - this->TestProperties->Name + "\n"; + std::string testName = cmStrCat(this->GetTestPrefix(completed, total), + this->TestProperties->Name, '\n'); cmCTestLog(this->CTest, HANDLER_TEST_PROGRESS_OUTPUT, testName); } } @@ -384,7 +381,7 @@ cmCTestRunTest::EndTestResult cmCTestRunTest::EndTest(size_t completed, std::string const stampDir = this->CTest->GetStampDir(); cmSystemTools::MakeDirectory(stampDir); std::string const stampFile = - stampDir + "/" + this->TestProperties->GetStampFile(); + cmStrCat(stampDir, '/', this->TestProperties->GetStampFile()); cmSystemTools::Touch(stampFile, true); } // If the test does not need to rerun push the current TestResult onto the @@ -564,9 +561,9 @@ bool cmCTestRunTest::StartTest(size_t completed, size_t total) std::string runIterationSuffix{}; if (this->NumberOfRunsTotal > 1) { - runIterationSuffix = " (run " + - std::to_string(1 + this->NumberOfRunsTotal - this->NumberOfRunsLeft) + - "/" + std::to_string(this->NumberOfRunsTotal) + ")"; + runIterationSuffix = + cmStrCat(" (run ", 1 + this->NumberOfRunsTotal - this->NumberOfRunsLeft, + '/', this->NumberOfRunsTotal, ')'); } if (!this->CTest->GetTestProgressOutput()) { cmCTestLog( @@ -576,8 +573,8 @@ bool cmCTestRunTest::StartTest(size_t completed, size_t total) << this->TestProperties->Index << ": " << this->TestProperties->Name << runIterationSuffix << std::endl); } else { - std::string testName = this->GetTestPrefix(completed, total) + - this->TestProperties->Name + "\n"; + std::string testName = cmStrCat(this->GetTestPrefix(completed, total), + this->TestProperties->Name, '\n'); cmCTestLog(this->CTest, HANDLER_TEST_PROGRESS_OUTPUT, testName); } @@ -624,7 +621,7 @@ bool cmCTestRunTest::StartTest(size_t completed, size_t total) if (!this->FailedDependencies.empty()) { std::string msg = "Failed test dependencies:"; for (std::string const& failedDep : this->FailedDependencies) { - msg += " " + failedDep; + msg = cmStrCat(std::move(msg), ' ', failedDep); } *this->TestHandler->LogFile << msg << std::endl; cmCTestLog(this->CTest, HANDLER_OUTPUT, msg << std::endl); @@ -722,15 +719,11 @@ void cmCTestRunTest::ComputeArguments() // Prepends memcheck args to our command string this->TestHandler->GenerateTestCommand(this->Arguments, this->Index); for (std::string const& arg : this->Arguments) { - testCommand += " \""; - testCommand += arg; - testCommand += "\""; + testCommand = cmStrCat(std::move(testCommand), " \"", arg, '"'); } for (; j != this->TestProperties->Args.end(); ++j) { - testCommand += " \""; - testCommand += *j; - testCommand += "\""; + testCommand = cmStrCat(std::move(testCommand), " \"", *j, '"'); this->Arguments.push_back(*j); } // Append passthrough arguments from ctest command line (after --) @@ -759,9 +752,7 @@ void cmCTestRunTest::ComputeArguments() realArguments.end()); testCommand = cmSystemTools::ConvertToOutputPath(this->ActualCommand); - for (std::string const& arg : this->Arguments) { - testCommand += cmStrCat(" \"", arg, '"'); - } + testCommand += cmWrap(" \"", this->Arguments, "\"", ""); this->TestResult.Environment.clear(); } this->TestResult.FullCommandLine = testCommand; diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx index 189bdebee9..38624a61aa 100644 --- a/Source/CTest/cmCTestSubmitHandler.cxx +++ b/Source/CTest/cmCTestSubmitHandler.cxx @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -245,21 +246,19 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP( // Provide extra arguments to CDash so that it can initialize and // return a buildid. cmCTestCurl ctest_curl(this->CTest); - upload_as += "&build="; - upload_as += - ctest_curl.Escape(this->CTest->GetCTestConfiguration("BuildName")); - upload_as += "&site="; - upload_as += - ctest_curl.Escape(this->CTest->GetCTestConfiguration("Site")); - upload_as += "&stamp="; - upload_as += ctest_curl.Escape(this->CTest->GetCurrentTag()); - upload_as += "-"; - upload_as += ctest_curl.Escape(this->CTest->GetTestGroupString()); + upload_as = cmStrCat( + std::move(upload_as), "&build=", + ctest_curl.Escape(this->CTest->GetCTestConfiguration("BuildName")), + "&site=", + ctest_curl.Escape(this->CTest->GetCTestConfiguration("Site")), + "&stamp=", ctest_curl.Escape(this->CTest->GetCurrentTag()), '-', + ctest_curl.Escape(this->CTest->GetTestGroupString())); if (cmake* cm = this->CMake) { cmValue subproject = cm->GetState()->GetGlobalProperty("SubProject"); if (subproject) { - upload_as += "&subproject="; - upload_as += ctest_curl.Escape(*subproject); + upload_as = + cmStrCat(std::move(upload_as), + "&subproject=", ctest_curl.Escape(*subproject)); } } } @@ -275,13 +274,12 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP( this->CTest->GenerateDoneFile(); } - upload_as += "&MD5="; - if (this->InternalTest) { - upload_as += "ffffffffffffffffffffffffffffffff"; + upload_as += "&MD5=ffffffffffffffffffffffffffffffff"; } else { cmCryptoHash hasher(cmCryptoHash::AlgoMD5); - upload_as += hasher.HashFile(local_file); + upload_as = + cmStrCat(std::move(upload_as), "&MD5=", hasher.HashFile(local_file)); } if (!cmSystemTools::FileExists(local_file)) { @@ -729,8 +727,8 @@ int cmCTestSubmitHandler::ProcessHandler() this->HTTPProxyType = 1; this->HTTPProxy = proxy; if (getenv("HTTP_PROXY_PORT")) { - this->HTTPProxy += ":"; - this->HTTPProxy += getenv("HTTP_PROXY_PORT"); + this->HTTPProxy = + cmStrCat(std::move(this->HTTPProxy), ':', getenv("HTTP_PROXY_PORT")); } if (char const* proxy_type = getenv("HTTP_PROXY_TYPE")) { std::string type = proxy_type; @@ -747,8 +745,8 @@ int cmCTestSubmitHandler::ProcessHandler() this->HTTPProxyAuth = getenv("HTTP_PROXY_USER"); } if (getenv("HTTP_PROXY_PASSWD")) { - this->HTTPProxyAuth += ":"; - this->HTTPProxyAuth += getenv("HTTP_PROXY_PASSWD"); + this->HTTPProxyAuth = cmStrCat(std::move(this->HTTPProxyAuth), ':', + getenv("HTTP_PROXY_PASSWD")); } } @@ -779,9 +777,9 @@ int cmCTestSubmitHandler::ProcessHandler() if (this->CTest->AddIfExists(cmCTest::PartCoverage, "Coverage.xml")) { std::vector gfiles; std::string gpath = - buildDirectory + "/Testing/" + this->CTest->GetCurrentTag(); + cmStrCat(buildDirectory, "/Testing/", this->CTest->GetCurrentTag()); std::string::size_type glen = gpath.size() + 1; - gpath = gpath + "/CoverageLog*"; + gpath += "/CoverageLog*"; cmCTestOptionalLog(this->CTest, DEBUG, "Globbing for: " << gpath << std::endl, this->Quiet); if (cmSystemTools::SimpleGlob(gpath, gfiles, 1)) { @@ -848,9 +846,9 @@ int cmCTestSubmitHandler::ProcessHandler() std::string url = this->CTest->GetSubmitURL(); cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " SubmitURL: " << url << '\n', this->Quiet); - if (!this->SubmitUsingHTTP(buildDirectory + "/Testing/" + - this->CTest->GetCurrentTag(), - files, prefix, url)) { + if (!this->SubmitUsingHTTP( + cmStrCat(buildDirectory, "/Testing/", this->CTest->GetCurrentTag()), + files, prefix, url)) { cmCTestLog(this->CTest, ERROR_MESSAGE, " Problems when submitting via HTTP\n"); ofs << " Problems when submitting via HTTP\n"; @@ -877,10 +875,9 @@ std::string cmCTestSubmitHandler::GetSubmitResultsPrefix() { std::string buildname = cmCTest::SafeBuildIdField(this->CTest->GetCTestConfiguration("BuildName")); - std::string name = this->CTest->GetCTestConfiguration("Site") + "___" + - buildname + "___" + this->CTest->GetCurrentTag() + "-" + - this->CTest->GetTestGroupString() + "___XML___"; - return name; + return cmStrCat(this->CTest->GetCTestConfiguration("Site"), "___", buildname, + "___", this->CTest->GetCurrentTag(), '-', + this->CTest->GetTestGroupString(), "___XML___"); } void cmCTestSubmitHandler::SelectParts(std::set const& parts) diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx index f9c8409544..acd3740a0d 100644 --- a/Source/cmCommonTargetGenerator.cxx +++ b/Source/cmCommonTargetGenerator.cxx @@ -343,14 +343,13 @@ std::string cmCommonTargetGenerator::ComputeTargetCompilePDB( // A trailing slash tells the toolchain to add its default file name. compilePdbPath = this->GeneratorTarget->GetSupportDirectory(); if (this->GlobalCommonGenerator->IsMultiConfig()) { - compilePdbPath += "/"; - compilePdbPath += config; + compilePdbPath = cmStrCat(std::move(compilePdbPath), '/', config); } - compilePdbPath += "/"; + compilePdbPath += '/'; if (this->GeneratorTarget->GetType() == cm::TargetType::STATIC_LIBRARY) { // Match VS default for static libs: `$(IntDir)$(ProjectName).pdb`. - compilePdbPath += this->GeneratorTarget->GetName(); - compilePdbPath += ".pdb"; + compilePdbPath = cmStrCat(std::move(compilePdbPath), + this->GeneratorTarget->GetName(), ".pdb"); } } @@ -496,8 +495,6 @@ std::string cmCommonTargetGenerator::GenerateCodeCheckRules( compilerLauncher.clear(); } if (cmNonempty(iwyu)) { - code_check += " --iwyu="; - // Only add --driver-mode if it is not already specified, as adding // it unconditionally might override a user-specified driver-mode if (iwyu.find("--driver-mode=") == std::string::npos) { @@ -511,12 +508,14 @@ std::string cmCommonTargetGenerator::GenerateCodeCheckRules( driverMode = lang == "C" ? "gcc" : "g++"; } - code_check += - this->GeneratorTarget->GetLocalGenerator()->EscapeForShell( - cmStrCat(iwyu, ";--driver-mode=", driverMode)); + code_check = + cmStrCat(std::move(code_check), " --iwyu=", + this->GeneratorTarget->GetLocalGenerator()->EscapeForShell( + cmStrCat(iwyu, ";--driver-mode=", driverMode))); } else { - code_check += - this->GeneratorTarget->GetLocalGenerator()->EscapeForShell(iwyu); + code_check = cmStrCat( + std::move(code_check), " --iwyu=", + this->GeneratorTarget->GetLocalGenerator()->EscapeForShell(iwyu)); } } if (cmNonempty(tidy)) { @@ -577,36 +576,35 @@ std::string cmCommonTargetGenerator::GenerateCodeCheckRules( this->GeneratorTarget->GetLocalGenerator()->GetMakefile(); std::string extraPvsArgs; if (lang == "CXX") { - extraPvsArgs += + extraPvsArgs = cmStrCat(";--cxx;", mf->GetDefinition("CMAKE_CXX_COMPILER")); } else if (lang == "C") { - extraPvsArgs += + extraPvsArgs = cmStrCat(";--cc;", mf->GetDefinition("CMAKE_C_COMPILER")); } // cocompile args - code_check += " --pvs-studio="; - code_check += this->GeneratorTarget->GetLocalGenerator()->EscapeForShell( - cmStrCat(pvs, extraPvsArgs)); - code_check += " --object="; - code_check += + code_check = cmStrCat( + std::move(code_check), " --pvs-studio=", + this->GeneratorTarget->GetLocalGenerator()->EscapeForShell( + cmStrCat(pvs, extraPvsArgs)), + " --object=", this->GeneratorTarget->GetLocalGenerator()->ConvertToOutputFormat( cmSystemTools::CollapseFullPath( cmStrCat(this->GeneratorTarget->GetObjectDirectory(config), '/', this->GeneratorTarget->GetObjectName(&source))), - cmOutputConverter::SHELL); + cmOutputConverter::SHELL)); } if (cmNonempty(cpplint)) { - code_check += " --cpplint="; - code_check += - this->GeneratorTarget->GetLocalGenerator()->EscapeForShell(cpplint); + code_check = cmStrCat( + std::move(code_check), " --cpplint=", + this->GeneratorTarget->GetLocalGenerator()->EscapeForShell(cpplint)); } if (cmNonempty(cppcheck)) { - code_check += " --cppcheck="; - code_check += - this->GeneratorTarget->GetLocalGenerator()->EscapeForShell(cppcheck); + code_check = cmStrCat( + std::move(code_check), " --cppcheck=", + this->GeneratorTarget->GetLocalGenerator()->EscapeForShell(cppcheck)); } if (cmNonempty(icstat)) { - code_check += " --icstat="; // Unless specified otherwise via CMAKE__ICSTAT, // populate the icstat command line using default options // for its mandatory parameters. @@ -620,16 +618,18 @@ std::string cmCommonTargetGenerator::GenerateCodeCheckRules( std::string const dbFile{ "cstat.db" }; dbParam = cmStrCat(";--db=", dbFile); } - std::string analyzeCmd{ ";analyze" }; - code_check += this->GeneratorTarget->GetLocalGenerator()->EscapeForShell( - cmStrCat(icstat, checksParam, dbParam, analyzeCmd)); + cm::string_view const analyzeCmd{ ";analyze" }; + code_check = + cmStrCat(std::move(code_check), " --icstat=", + this->GeneratorTarget->GetLocalGenerator()->EscapeForShell( + cmStrCat(icstat, checksParam, dbParam, analyzeCmd))); } if (cmNonempty(tidy) || (cmNonempty(cpplint)) || (cmNonempty(cppcheck)) || cmNonempty(pvs) || cmNonempty(icstat)) { - code_check += " --source="; - code_check += + code_check = cmStrCat( + std::move(code_check), " --source=", this->GeneratorTarget->GetLocalGenerator()->ConvertToOutputFormat( - source.GetFullPath(), cmOutputConverter::SHELL); + source.GetFullPath(), cmOutputConverter::SHELL)); } code_check += " -- "; return code_check; diff --git a/Source/cmConfigureFileCommand.cxx b/Source/cmConfigureFileCommand.cxx index 8848a4c609..d0623118df 100644 --- a/Source/cmConfigureFileCommand.cxx +++ b/Source/cmConfigureFileCommand.cxx @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -45,14 +46,14 @@ bool cmConfigureFileCommand(std::vector const& args, // If the output location is already a directory put the file in it. if (cmSystemTools::FileIsDirectory(outputFile)) { - outputFile += "/"; - outputFile += cmSystemTools::GetFilenameName(inFile); + outputFile = cmStrCat(std::move(outputFile), '/', + cmSystemTools::GetFilenameName(inFile)); } if (!status.GetMakefile().CanIWriteThisFile(outputFile)) { - std::string e = "attempted to configure a file: " + outputFile + - " into a source directory."; - status.SetError(e); + status.SetError( + cmStrCat("attempted to configure a file: ", std::move(outputFile), + " into a source directory.")); cmSystemTools::SetFatalErrorOccurred(); return false; } @@ -148,15 +149,14 @@ bool cmConfigureFileCommand(std::vector const& args, } else if (doing == Doing::DoingFilePermissions) { filePermissionOptions.push_back(args[i]); } else { - unknown_args += " "; - unknown_args += args[i]; - unknown_args += "\n"; + unknown_args = cmStrCat(std::move(unknown_args), ' ', args[i], '\n'); } } if (!unknown_args.empty()) { - std::string msg = cmStrCat( - "configure_file called with unknown argument(s):\n", unknown_args); - status.GetMakefile().IssueDiagnostic(cmDiagnostics::CMD_AUTHOR, msg); + status.GetMakefile().IssueDiagnostic( + cmDiagnostics::CMD_AUTHOR, + cmStrCat("configure_file called with unknown argument(s):\n", + unknown_args)); } if (useSourcePermissions && noSourcePermissions) { diff --git a/Source/cmExecProgramCommand.cxx b/Source/cmExecProgramCommand.cxx index 5f09bb636c..d343298e9d 100644 --- a/Source/cmExecProgramCommand.cxx +++ b/Source/cmExecProgramCommand.cxx @@ -3,6 +3,7 @@ #include "cmExecProgramCommand.h" #include +#include #include "cmsys/Process.h" @@ -68,8 +69,7 @@ bool cmExecProgramCommand(std::vector const& args, haveoutput_variable = false; doingargs = true; } else if (doingargs) { - arguments += arg; - arguments += " "; + arguments = cmStrCat(std::move(arguments), arg, ' '); count++; } } @@ -156,13 +156,12 @@ bool RunCommand(std::string command, std::string& output, int& retVal, std::string cmd = quoted.match(1); std::string args = quoted.match(2); if (!cmSystemTools::FileExists(cmd)) { - shortCmd = cmd; + shortCmd = std::move(cmd); } else if (!cmSystemTools::GetShortPath(cmd, shortCmd)) { cmSystemTools::Error("GetShortPath failed for " + cmd); return false; } - shortCmd += " "; - shortCmd += args; + shortCmd = cmStrCat(std::move(shortCmd), ' ', std::move(args)); command = shortCmd; } else { @@ -247,13 +246,13 @@ bool RunCommand(std::string command, std::string& output, int& retVal, break; case cmsysProcess_State_Exception: retVal = -1; - msg += "\nProcess terminated due to: "; - msg += cmsysProcess_GetExceptionString(cp); + msg = cmStrCat(std::move(msg), "\nProcess terminated due to: ", + cmsysProcess_GetExceptionString(cp)); break; case cmsysProcess_State_Error: retVal = -1; - msg += "\nProcess failed because: "; - msg += cmsysProcess_GetErrorString(cp); + msg = cmStrCat(std::move(msg), "\nProcess failed because: ", + cmsysProcess_GetErrorString(cp)); break; case cmsysProcess_State_Expired: retVal = -1; @@ -263,11 +262,9 @@ bool RunCommand(std::string command, std::string& output, int& retVal, if (!msg.empty()) { #if defined(_WIN32) && !defined(__CYGWIN__) // Old Windows process execution printed this info. - msg += "\n\nfor command: "; - msg += command; + msg = cmStrCat(std::move(msg), "\n\nfor command: ", command); if (dir) { - msg += "\nin dir: "; - msg += dir; + msg = cmStrCat(std::move(msg), "\nin dir: ", dir); } msg += "\n"; if (verbose) { diff --git a/Source/cmExecuteProcessCommand.cxx b/Source/cmExecuteProcessCommand.cxx index 9a2c7c0ca3..10563d0218 100644 --- a/Source/cmExecuteProcessCommand.cxx +++ b/Source/cmExecuteProcessCommand.cxx @@ -310,8 +310,8 @@ bool cmExecuteProcessCommand(std::vector const& args, } else { error = " called with '"; } - error += echo_output; - error += "' expected STDERR|STDOUT|NONE"; + error = cmStrCat(std::move(error), std::move(echo_output), + "' expected STDERR|STDOUT|NONE"); if (!echo_output_from_variable) { error += " for COMMAND_ECHO."; } @@ -322,10 +322,7 @@ bool cmExecuteProcessCommand(std::vector const& args, if (echo_stdout || echo_stderr) { std::string command; for (auto const& cmd : arguments.Commands) { - command += "'"; - command += cmJoin(cmd, "' '"); - command += "'"; - command += "\n"; + command = cmStrCat(std::move(command), '\'', cmJoin(cmd, "' '"), "'\n"); } if (echo_stdout) { std::cout << command; diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx index 13b87b9327..8844a09915 100644 --- a/Source/cmExtraCodeBlocksGenerator.cxx +++ b/Source/cmExtraCodeBlocksGenerator.cxx @@ -723,8 +723,7 @@ std::string cmExtraCodeBlocksGenerator::BuildMakeCommand( { std::string command = make; if (!makeFlags.empty()) { - command += " "; - command += makeFlags; + command = cmStrCat(std::move(command), ' ', makeFlags); } std::string generator = this->GlobalGenerator->GetName(); @@ -733,29 +732,20 @@ std::string cmExtraCodeBlocksGenerator::BuildMakeCommand( // These need to be escaped, see // https://gitlab.kitware.com/cmake/cmake/-/issues/13952 std::string makefileName = cmSystemTools::ConvertToOutputPath(makefile); - command += " /NOLOGO /f "; - command += makefileName; - command += " VERBOSE=1 "; - command += target; + command = cmStrCat(std::move(command), " /NOLOGO /f ", makefileName, + " VERBOSE=1 ", target); } else if (generator == "MinGW Makefiles") { // no escaping of spaces in this case, see // https://gitlab.kitware.com/cmake/cmake/-/issues/10014 std::string const& makefileName = makefile; - command += " -f \""; - command += makefileName; - command += "\" "; - command += " VERBOSE=1 "; - command += target; + command = cmStrCat(std::move(command), " -f \"", makefileName, "\" ", + " VERBOSE=1 ", target); } else if (generator == "Ninja") { - command += " -v "; - command += target; + command = cmStrCat(std::move(command), " -v ", target); } else { std::string makefileName = cmSystemTools::ConvertToOutputPath(makefile); - command += " -f \""; - command += makefileName; - command += "\" "; - command += " VERBOSE=1 "; - command += target; + command = cmStrCat(std::move(command), " -f \"", makefileName, "\" ", + " VERBOSE=1 ", target); } return command; } diff --git a/Source/cmFileCopier.cxx b/Source/cmFileCopier.cxx index 28e4b601e4..dfe8f8ad12 100644 --- a/Source/cmFileCopier.cxx +++ b/Source/cmFileCopier.cxx @@ -24,6 +24,7 @@ #endif #include +#include using namespace cmFSPermissions; @@ -386,12 +387,10 @@ bool cmFileCopier::Run(std::vector const& args) std::string file; if (!f.empty() && !cmSystemTools::FileIsFullPath(f)) { if (!this->FilesFromDir.empty()) { - file = this->FilesFromDir; + file = cmStrCat(this->FilesFromDir, '/', f); } else { - file = this->Makefile->GetCurrentSourceDirectory(); + file = cmStrCat(this->Makefile->GetCurrentSourceDirectory(), '/', f); } - file += "/"; - file += f; } else if (!this->FilesFromDir.empty()) { this->Status.SetError("option FILES_FROM_DIR requires all files " "to be specified as relative paths."); @@ -412,22 +411,19 @@ bool cmFileCopier::Run(std::vector const& args) if (!this->FilesFromDir.empty()) { std::string dir = cmSystemTools::GetFilenamePath(f); if (!dir.empty()) { - toFile += "/"; - toFile += dir; + toFile = cmStrCat(std::move(toFile), '/', dir); } } std::string const& toName = this->ToName(fromName); if (!toName.empty()) { - toFile += "/"; - toFile += toName; + toFile = cmStrCat(std::move(toFile), '/', toName); } // Construct the full path to the source file. The file name may // have been changed above. std::string fromFile = fromDir; if (!fromName.empty()) { - fromFile += "/"; - fromFile += fromName; + fromFile = cmStrCat(std::move(fromFile), '/', std::move(fromName)); } if (!this->Install(fromFile, toFile)) { diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx index 8fa751a018..07116e4195 100644 --- a/Source/cmInstallTargetGenerator.cxx +++ b/Source/cmInstallTargetGenerator.cxx @@ -43,12 +43,9 @@ std::string computeInstallObjectDir(cmGeneratorTarget* gt, { std::string objectDir = "objects"; if (!config.empty()) { - objectDir += "-"; - objectDir += config; + objectDir = cmStrCat(std::move(objectDir), '-', config); } - objectDir += "/"; - objectDir += gt->GetName(); - return objectDir; + return cmStrCat(std::move(objectDir), '/', gt->GetName()); } void computeFilesToInstall( @@ -208,7 +205,8 @@ void cmInstallTargetGenerator::GenerateScriptForConfig( } else { char const* no_rename = nullptr; if (!files.FromDir.empty()) { - literalArgs += " FILES_FROM_DIR \"" + files.FromDir + "\""; + literalArgs = cmStrCat(std::move(literalArgs), " FILES_FROM_DIR \"", + files.FromDir, '"'); } this->AddInstallRule(os, dest, files.Type, files.From, optional, this->FilePermissions.c_str(), no_dir_permissions, @@ -336,13 +334,10 @@ cmInstallTargetGenerator::Files cmInstallTargetGenerator::GetFiles( // Install the whole app bundle directory. files.Type = cmInstallType_DIRECTORY; files.UseSourcePermissions = true; - from1 += "."; - from1 += ext; + from1 = cmStrCat(std::move(from1), '.', ext); // Tweaks apply to the binary inside the bundle. - to1 += "."; - to1 += ext; - to1 += "/"; + to1 = cmStrCat(std::move(to1), '.', ext, '/'); if (!mf->PlatformIsAppleEmbedded()) { to1 += "Contents/MacOS/"; } diff --git a/Source/cmInstallTargetsCommand.cxx b/Source/cmInstallTargetsCommand.cxx index 791fd5e2ed..239d4a2656 100644 --- a/Source/cmInstallTargetsCommand.cxx +++ b/Source/cmInstallTargetsCommand.cxx @@ -9,6 +9,7 @@ #include "cmExecutionStatus.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" +#include "cmStringAlgorithms.h" #include "cmTarget.h" bool cmInstallTargetsCommand(std::vector const& args, @@ -49,8 +50,8 @@ bool cmInstallTargetsCommand(std::vector const& args, ti->second.SetRuntimeInstallPath(runtimeDir); ti->second.SetHaveInstallRule(true); } else { - std::string str = "Cannot find target: \"" + *s + "\" to install."; - status.SetError(str); + status.SetError( + cmStrCat("Cannot find target: \"", *s, "\" to install.")); return false; } } diff --git a/Source/cmMathCommand.cxx b/Source/cmMathCommand.cxx index 5fe91ae3a1..d14145732d 100644 --- a/Source/cmMathCommand.cxx +++ b/Source/cmMathCommand.cxx @@ -48,8 +48,7 @@ bool cmMathCommand(std::vector const& args, args, status, -1, std::numeric_limits::min(), std::numeric_limits::max(), "decrementing"_s); } - std::string e = "does not recognize sub-command " + subCommand; - status.SetError(e); + status.SetError(cmStrCat("does not recognize sub-command ", subCommand)); return false; } @@ -87,21 +86,19 @@ bool HandleExprCommand(std::vector const& args, } else if (argument == "HEXADECIMAL") { outputFormat = NumericFormat::HEXADECIMAL; } else { - std::string error = messageHint + "value \"" + argument + - "\" for option \"" + option + "\" is invalid."; - status.SetError(error); + status.SetError(cmStrCat(messageHint, "value \"", argument, + "\" for option \"", option, + "\" is invalid.")); return false; } } else { - std::string error = - messageHint + "missing argument for option \"" + option + "\"."; - status.SetError(error); + status.SetError(cmStrCat(messageHint, "missing argument for option \"", + option, "\".")); return false; } } else { - std::string error = - messageHint + "option \"" + option + "\" is unknown."; - status.SetError(error); + status.SetError( + cmStrCat(messageHint, "option \"", option, "\" is unknown.")); return false; } } diff --git a/Source/cmRulePlaceholderExpander.cxx b/Source/cmRulePlaceholderExpander.cxx index 70a736b4cb..1c7000144b 100644 --- a/Source/cmRulePlaceholderExpander.cxx +++ b/Source/cmRulePlaceholderExpander.cxx @@ -211,9 +211,7 @@ std::string cmRulePlaceholderExpander::ExpandVariable( if (variable == "TARGET_QUOTED") { std::string targetQuoted = this->ReplaceValues->Target; if (!targetQuoted.empty() && targetQuoted.front() != '\"') { - targetQuoted = '\"'; - targetQuoted += this->ReplaceValues->Target; - targetQuoted += '\"'; + targetQuoted = cmStrCat('"', this->ReplaceValues->Target, '"'); } return targetQuoted; } @@ -330,24 +328,22 @@ std::string cmRulePlaceholderExpander::ExpandVariable( if (compIt != this->Compilers.end()) { std::string const& compilerPath = - this->VariableMappings["CMAKE_" + compIt->second + "_COMPILER"]; + this->VariableMappings[cmStrCat("CMAKE_", compIt->second, "_COMPILER")]; std::string ret = this->ConvertToOutputForExisting(compilerPath); - std::string const& compilerArg1 = - this->VariableMappings["CMAKE_" + compIt->second + "_COMPILER_ARG1"]; - std::string const& compilerTarget = - this->VariableMappings["CMAKE_" + compIt->second + "_COMPILER_TARGET"]; - std::string const& compilerOptionTarget = - this->VariableMappings["CMAKE_" + compIt->second + - "_COMPILE_OPTIONS_TARGET"]; + std::string const& compilerArg1 = this->VariableMappings[cmStrCat( + "CMAKE_", compIt->second, "_COMPILER_ARG1")]; + std::string const& compilerTarget = this->VariableMappings[cmStrCat( + "CMAKE_", compIt->second, "_COMPILER_TARGET")]; + std::string const& compilerOptionTarget = this->VariableMappings[cmStrCat( + "CMAKE_", compIt->second, "_COMPILE_OPTIONS_TARGET")]; std::string const& compilerExternalToolchain = - this->VariableMappings["CMAKE_" + compIt->second + - "_COMPILER_EXTERNAL_TOOLCHAIN"]; + this->VariableMappings[cmStrCat("CMAKE_", compIt->second, + "_COMPILER_EXTERNAL_TOOLCHAIN")]; std::string const& compilerOptionExternalToolchain = - this->VariableMappings["CMAKE_" + compIt->second + - "_COMPILE_OPTIONS_EXTERNAL_TOOLCHAIN"]; - std::string const& compilerOptionSysroot = - this->VariableMappings["CMAKE_" + compIt->second + - "_COMPILE_OPTIONS_SYSROOT"]; + this->VariableMappings[cmStrCat("CMAKE_", compIt->second, + "_COMPILE_OPTIONS_EXTERNAL_TOOLCHAIN")]; + std::string const& compilerOptionSysroot = this->VariableMappings[cmStrCat( + "CMAKE_", compIt->second, "_COMPILE_OPTIONS_SYSROOT")]; if (compIt->second == this->ReplaceValues->Language && this->ReplaceValues->Launcher) { @@ -360,20 +356,17 @@ std::string cmRulePlaceholderExpander::ExpandVariable( // if there are required arguments to the compiler add it // to the compiler string if (!compilerArg1.empty()) { - ret += " "; - ret += compilerArg1; + ret = cmStrCat(std::move(ret), ' ', compilerArg1); } if (!compilerTarget.empty() && !compilerOptionTarget.empty()) { - ret += " "; - ret += compilerOptionTarget; - ret += compilerTarget; + ret = + cmStrCat(std::move(ret), ' ', compilerOptionTarget, compilerTarget); } if (!compilerExternalToolchain.empty() && !compilerOptionExternalToolchain.empty()) { - ret += " "; - ret += compilerOptionExternalToolchain; - ret += - this->OutputConverter->EscapeForShell(compilerExternalToolchain, true); + ret = cmStrCat(std::move(ret), ' ', compilerOptionExternalToolchain, + this->OutputConverter->EscapeForShell( + compilerExternalToolchain, true)); } std::string sysroot; // Some platforms may use separate sysroots for compiling and linking. @@ -384,9 +377,8 @@ std::string cmRulePlaceholderExpander::ExpandVariable( sysroot = this->CompilerSysroot; } if (!sysroot.empty() && !compilerOptionSysroot.empty()) { - ret += " "; - ret += compilerOptionSysroot; - ret += this->OutputConverter->EscapeForShell(sysroot, true); + ret = cmStrCat(std::move(ret), ' ', compilerOptionSysroot, + this->OutputConverter->EscapeForShell(sysroot, true)); } return ret; } diff --git a/Source/cmWriteFileCommand.cxx b/Source/cmWriteFileCommand.cxx index 54e1e4d480..cd5826f8f6 100644 --- a/Source/cmWriteFileCommand.cxx +++ b/Source/cmWriteFileCommand.cxx @@ -42,9 +42,8 @@ bool cmWriteFileCommand(std::vector const& args, } if (!mf.CanIWriteThisFile(fileName)) { - std::string e = - "attempted to write a file: " + fileName + " into a source directory."; - status.SetError(e); + status.SetError(cmStrCat("attempted to write a file: ", fileName, + " into a source directory.")); cmSystemTools::SetFatalErrorOccurred(); return false; } @@ -73,10 +72,8 @@ bool cmWriteFileCommand(std::vector const& args, cmsys::ofstream file(fileName.c_str(), overwrite ? std::ios::out : std::ios::app); if (!file) { - std::string error = - cmStrCat("Internal CMake error when trying to open file: ", fileName, - " for writing."); - status.SetError(error); + status.SetError(cmStrCat("Internal CMake error when trying to open file: ", + fileName, " for writing.")); return false; } file << message << '\n';