diff options
Diffstat (limited to 'Source')
317 files changed, 5907 insertions, 7023 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 7cd07a8..2ff6c8c 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -493,8 +493,6 @@ set(SRCS cmCreateTestSourceList.h cmDefinePropertyCommand.cxx cmDefinePropertyCommand.h - cmDisallowedCommand.cxx - cmDisallowedCommand.h cmEnableLanguageCommand.cxx cmEnableLanguageCommand.h cmEnableTestingCommand.cxx @@ -656,6 +654,8 @@ set(SRCS cmTargetLinkDirectoriesCommand.h cmTargetLinkLibrariesCommand.cxx cmTargetLinkLibrariesCommand.h + cmTargetPrecompileHeadersCommand.cxx + cmTargetPrecompileHeadersCommand.h cmTargetPropCommandBase.cxx cmTargetPropCommandBase.h cmTargetSourcesCommand.cxx diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 9a76073..46f7cce 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,7 +1,7 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 15) -set(CMake_VERSION_PATCH 20190819) +set(CMake_VERSION_PATCH 20190903) #set(CMake_VERSION_RC 0) set(CMake_VERSION_IS_DIRTY 0) diff --git a/Source/CPack/IFW/cmCPackIFWCommon.cxx b/Source/CPack/IFW/cmCPackIFWCommon.cxx index 5b1ccbd..f9ce822 100644 --- a/Source/CPack/IFW/cmCPackIFWCommon.cxx +++ b/Source/CPack/IFW/cmCPackIFWCommon.cxx @@ -78,8 +78,7 @@ bool cmCPackIFWCommon::IsVersionEqual(const char* version) void cmCPackIFWCommon::ExpandListArgument( const std::string& arg, std::map<std::string, std::string>& argsOut) { - std::vector<std::string> args; - cmExpandList(arg, args, false); + std::vector<std::string> args = cmExpandedList(arg, false); if (args.empty()) { return; } @@ -100,8 +99,7 @@ void cmCPackIFWCommon::ExpandListArgument( void cmCPackIFWCommon::ExpandListArgument( const std::string& arg, std::multimap<std::string, std::string>& argsOut) { - std::vector<std::string> args; - cmExpandList(arg, args, false); + std::vector<std::string> args = cmExpandedList(arg, false); if (args.empty()) { return; } diff --git a/Source/CPack/IFW/cmCPackIFWGenerator.cxx b/Source/CPack/IFW/cmCPackIFWGenerator.cxx index f0fb37a..d1ffcef 100644 --- a/Source/CPack/IFW/cmCPackIFWGenerator.cxx +++ b/Source/CPack/IFW/cmCPackIFWGenerator.cxx @@ -35,29 +35,35 @@ int cmCPackIFWGenerator::PackageFiles() this->Installer.GeneratePackageFiles(); std::string ifwTLD = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); - std::string ifwTmpFile = ifwTLD; - ifwTmpFile += "/IFWOutput.log"; + std::string ifwTmpFile = cmStrCat(ifwTLD, "/IFWOutput.log"); // Run repogen if (!this->Installer.RemoteRepositories.empty()) { - std::string ifwCmd = this->RepoGen; + std::vector<std::string> ifwCmd; + std::string ifwArg; + + ifwCmd.emplace_back(this->RepoGen); if (this->IsVersionLess("2.0.0")) { - ifwCmd += " -c " + this->toplevel + "/config/config.xml"; + ifwCmd.emplace_back("-c"); + ifwCmd.emplace_back(this->toplevel + "/config/config.xml"); } - ifwCmd += " -p " + this->toplevel + "/packages"; + ifwCmd.emplace_back("-p"); + ifwCmd.emplace_back(this->toplevel + "/packages"); if (!this->PkgsDirsVector.empty()) { for (std::string const& it : this->PkgsDirsVector) { - ifwCmd += " -p " + it; + ifwCmd.emplace_back("-p"); + ifwCmd.emplace_back(it); } } if (!this->RepoDirsVector.empty()) { if (!this->IsVersionLess("3.1")) { for (std::string const& rd : this->RepoDirsVector) { - ifwCmd += " --repository " + rd; + ifwCmd.emplace_back("--repository"); + ifwCmd.emplace_back(rd); } } else { cmCPackIFWLogger(WARNING, @@ -70,18 +76,21 @@ int cmCPackIFWGenerator::PackageFiles() } if (!this->OnlineOnly && !this->DownloadedPackages.empty()) { - ifwCmd += " -i "; + ifwCmd.emplace_back("-i"); std::set<cmCPackIFWPackage*>::iterator it = this->DownloadedPackages.begin(); - ifwCmd += (*it)->Name; + ifwArg = (*it)->Name; ++it; while (it != this->DownloadedPackages.end()) { - ifwCmd += "," + (*it)->Name; + ifwArg += "," + (*it)->Name; ++it; } + ifwCmd.emplace_back(ifwArg); } - ifwCmd += " " + this->toplevel + "/repository"; - cmCPackIFWLogger(VERBOSE, "Execute: " << ifwCmd << std::endl); + ifwCmd.emplace_back(this->toplevel + "/repository"); + cmCPackIFWLogger(VERBOSE, + "Execute: " << cmSystemTools::PrintSingleCommand(ifwCmd) + << std::endl); std::string output; int retVal = 1; cmCPackIFWLogger(OUTPUT, "- Generate repository" << std::endl); @@ -90,14 +99,15 @@ int cmCPackIFWGenerator::PackageFiles() cmDuration::zero()); if (!res || retVal) { cmGeneratedFileStream ofs(ifwTmpFile); - ofs << "# Run command: " << ifwCmd << std::endl + ofs << "# Run command: " << cmSystemTools::PrintSingleCommand(ifwCmd) + << std::endl << "# Output:" << std::endl << output << std::endl; - cmCPackIFWLogger(ERROR, - "Problem running IFW command: " - << ifwCmd << std::endl - << "Please check " << ifwTmpFile << " for errors" - << std::endl); + cmCPackIFWLogger( + ERROR, + "Problem running IFW command: " + << cmSystemTools::PrintSingleCommand(ifwCmd) << std::endl + << "Please check \"" << ifwTmpFile << "\" for errors" << std::endl); return 0; } @@ -105,46 +115,55 @@ int cmCPackIFWGenerator::PackageFiles() !this->Repository.PatchUpdatesXml()) { cmCPackIFWLogger(WARNING, "Problem patch IFW \"Updates\" " - << "file: " - << this->toplevel + "/repository/Updates.xml" - << std::endl); + << "file: \"" << this->toplevel + << "/repository/Updates.xml\"" << std::endl); } cmCPackIFWLogger(OUTPUT, - "- repository: " << this->toplevel - << "/repository generated" << std::endl); + "- repository: \"" << this->toplevel + << "/repository\" generated" + << std::endl); } // Run binary creator { - std::string ifwCmd = this->BinCreator; - ifwCmd += " -c " + this->toplevel + "/config/config.xml"; + std::vector<std::string> ifwCmd; + std::string ifwArg; + + ifwCmd.emplace_back(this->BinCreator); + + ifwCmd.emplace_back("-c"); + ifwCmd.emplace_back(this->toplevel + "/config/config.xml"); if (!this->Installer.Resources.empty()) { - ifwCmd += " -r "; + ifwCmd.emplace_back("-r"); std::vector<std::string>::iterator it = this->Installer.Resources.begin(); std::string path = this->toplevel + "/resources/"; - ifwCmd += path + *it; + ifwArg = path + *it; ++it; while (it != this->Installer.Resources.end()) { - ifwCmd += "," + path + *it; + ifwArg += "," + path + *it; ++it; } + ifwCmd.emplace_back(ifwArg); } - ifwCmd += " -p " + this->toplevel + "/packages"; + ifwCmd.emplace_back("-p"); + ifwCmd.emplace_back(this->toplevel + "/packages"); if (!this->PkgsDirsVector.empty()) { for (std::string const& it : this->PkgsDirsVector) { - ifwCmd += " -p " + it; + ifwCmd.emplace_back("-p"); + ifwCmd.emplace_back(it); } } if (!this->RepoDirsVector.empty()) { if (!this->IsVersionLess("3.1")) { for (std::string const& rd : this->RepoDirsVector) { - ifwCmd += " --repository " + rd; + ifwCmd.emplace_back("--repository"); + ifwCmd.emplace_back(rd); } } else { cmCPackIFWLogger(WARNING, @@ -157,44 +176,48 @@ int cmCPackIFWGenerator::PackageFiles() } if (this->OnlineOnly) { - ifwCmd += " --online-only"; + ifwCmd.emplace_back("--online-only"); } else if (!this->DownloadedPackages.empty() && !this->Installer.RemoteRepositories.empty()) { - ifwCmd += " -e "; + ifwCmd.emplace_back("-e"); std::set<cmCPackIFWPackage*>::iterator it = this->DownloadedPackages.begin(); - ifwCmd += (*it)->Name; + ifwArg = (*it)->Name; ++it; while (it != this->DownloadedPackages.end()) { - ifwCmd += "," + (*it)->Name; + ifwArg += "," + (*it)->Name; ++it; } + ifwCmd.emplace_back(ifwArg); } else if (!this->DependentPackages.empty()) { - ifwCmd += " -i "; + ifwCmd.emplace_back("-i"); + ifwArg.clear(); // Binary std::set<cmCPackIFWPackage*>::iterator bit = this->BinaryPackages.begin(); while (bit != this->BinaryPackages.end()) { - ifwCmd += (*bit)->Name + ","; + ifwArg += (*bit)->Name + ","; ++bit; } // Depend DependenceMap::iterator it = this->DependentPackages.begin(); - ifwCmd += it->second.Name; + ifwArg += it->second.Name; ++it; while (it != this->DependentPackages.end()) { - ifwCmd += "," + it->second.Name; + ifwArg += "," + it->second.Name; ++it; } + ifwCmd.emplace_back(ifwArg); } // TODO: set correct name for multipackages if (!this->packageFileNames.empty()) { - ifwCmd += " " + this->packageFileNames[0]; + ifwCmd.emplace_back(this->packageFileNames[0]); } else { - ifwCmd += " installer"; - ifwCmd += this->OutputExtension; + ifwCmd.emplace_back("installer" + this->OutputExtension); } - cmCPackIFWLogger(VERBOSE, "Execute: " << ifwCmd << std::endl); + cmCPackIFWLogger(VERBOSE, + "Execute: " << cmSystemTools::PrintSingleCommand(ifwCmd) + << std::endl); std::string output; int retVal = 1; cmCPackIFWLogger(OUTPUT, "- Generate package" << std::endl); @@ -203,14 +226,15 @@ int cmCPackIFWGenerator::PackageFiles() cmDuration::zero()); if (!res || retVal) { cmGeneratedFileStream ofs(ifwTmpFile); - ofs << "# Run command: " << ifwCmd << std::endl + ofs << "# Run command: " << cmSystemTools::PrintSingleCommand(ifwCmd) + << std::endl << "# Output:" << std::endl << output << std::endl; - cmCPackIFWLogger(ERROR, - "Problem running IFW command: " - << ifwCmd << std::endl - << "Please check " << ifwTmpFile << " for errors" - << std::endl); + cmCPackIFWLogger( + ERROR, + "Problem running IFW command: " + << cmSystemTools::PrintSingleCommand(ifwCmd) << std::endl + << "Please check \"" << ifwTmpFile << "\" for errors" << std::endl); return 0; } } @@ -317,8 +341,7 @@ int cmCPackIFWGenerator::InitializeInternal() // Repositories if (const char* RepoAllStr = this->GetOption("CPACK_IFW_REPOSITORIES_ALL")) { - std::vector<std::string> RepoAllVector; - cmExpandList(RepoAllStr, RepoAllVector); + std::vector<std::string> RepoAllVector = cmExpandedList(RepoAllStr); for (std::string const& r : RepoAllVector) { this->GetRepository(r); } diff --git a/Source/CPack/IFW/cmCPackIFWInstaller.cxx b/Source/CPack/IFW/cmCPackIFWInstaller.cxx index 5313dd0..b4bfea7 100644 --- a/Source/CPack/IFW/cmCPackIFWInstaller.cxx +++ b/Source/CPack/IFW/cmCPackIFWInstaller.cxx @@ -193,8 +193,8 @@ void cmCPackIFWInstaller::ConfigureFromOptions() this->TargetDir = optIFW_TARGET_DIRECTORY; } else if (const char* optPACKAGE_INSTALL_DIRECTORY = this->GetOption("CPACK_PACKAGE_INSTALL_DIRECTORY")) { - this->TargetDir = "@ApplicationsDir@/"; - this->TargetDir += optPACKAGE_INSTALL_DIRECTORY; + this->TargetDir = + cmStrCat("@ApplicationsDir@/", optPACKAGE_INSTALL_DIRECTORY); } else { this->TargetDir = "@RootDir@/usr/local"; } diff --git a/Source/CPack/IFW/cmCPackIFWPackage.cxx b/Source/CPack/IFW/cmCPackIFWPackage.cxx index 7407c49..fb75145 100644 --- a/Source/CPack/IFW/cmCPackIFWPackage.cxx +++ b/Source/CPack/IFW/cmCPackIFWPackage.cxx @@ -431,8 +431,7 @@ int cmCPackIFWPackage::ConfigureFromPrefix(const std::string& prefix) if (this->IsSetToEmpty(option)) { this->AlienAutoDependOn.clear(); } else if (const char* value = this->GetOption(option)) { - std::vector<std::string> depsOn; - cmExpandList(value, depsOn); + std::vector<std::string> depsOn = cmExpandedList(value); for (std::string const& d : depsOn) { DependenceStruct dep(d); if (this->Generator->Packages.count(dep.Name)) { diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx index 51d284f..b0b2df2 100644 --- a/Source/CPack/WiX/cmCPackWIXGenerator.cxx +++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx @@ -2,6 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCPackWIXGenerator.h" +#include "cmAlgorithms.h" #include "cmCPackComponentGroup.h" #include "cmCPackLog.h" #include "cmCryptoHash.h" @@ -10,6 +11,7 @@ #include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmUuid.h" +#include "cm_string_view.hxx" #include <algorithm> #include "cmWIXDirectoriesSourceWriter.h" @@ -226,8 +228,7 @@ bool cmCPackWIXGenerator::InitializeWiXConfiguration() const char* patchFilePath = GetOption("CPACK_WIX_PATCH_FILE"); if (patchFilePath) { - std::vector<std::string> patchFilePaths; - cmExpandList(patchFilePath, patchFilePaths); + std::vector<std::string> patchFilePaths = cmExpandedList(patchFilePath); for (std::string const& p : patchFilePaths) { if (!this->Patch->LoadFragments(p)) { @@ -310,9 +311,8 @@ void cmCPackWIXGenerator::AppendUserSuppliedExtraObjects(std::ostream& stream) if (!cpackWixExtraObjects) return; - std::vector<std::string> expandedExtraObjects; - - cmExpandList(cpackWixExtraObjects, expandedExtraObjects); + std::vector<std::string> expandedExtraObjects = + cmExpandedList(cpackWixExtraObjects); for (std::string const& obj : expandedExtraObjects) { stream << " " << QuotePath(obj); @@ -518,9 +518,7 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles() for (auto const& i : this->Components) { cmCPackComponent const& component = i.second; - std::string componentPath = toplevel; - componentPath += "/"; - componentPath += component.Name; + std::string componentPath = cmStrCat(toplevel, '/', component.Name); std::string const componentFeatureId = "CM_C_" + component.Name; @@ -942,9 +940,7 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitions( shortcut.workingDirectoryId = directoryId; shortcuts.insert(cmWIXShortcuts::START_MENU, id, shortcut); - if (!desktopExecutables.empty() && - std::find(desktopExecutables.begin(), desktopExecutables.end(), - executableName) != desktopExecutables.end()) { + if (cmContains(desktopExecutables, executableName)) { shortcuts.insert(cmWIXShortcuts::DESKTOP, id, shortcut); } } @@ -1088,8 +1084,7 @@ std::string cmCPackWIXGenerator::CreateHashedId( cmCryptoHash sha1(cmCryptoHash::AlgoSHA1); std::string const hash = sha1.HashString(path); - std::string identifier; - identifier += hash.substr(0, 7) + "_"; + std::string identifier = cmStrCat(cm::string_view(hash).substr(0, 7), '_'); const size_t maxFileNameLength = 52; if (normalizedFilename.length() > maxFileNameLength) { @@ -1134,8 +1129,7 @@ void cmCPackWIXGenerator::CollectExtensions(std::string const& variableName, if (!variableContent) return; - std::vector<std::string> list; - cmExpandList(variableContent, list); + std::vector<std::string> list = cmExpandedList(variableContent); extensions.insert(list.begin(), list.end()); } @@ -1146,8 +1140,7 @@ void cmCPackWIXGenerator::AddCustomFlags(std::string const& variableName, if (!variableContent) return; - std::vector<std::string> list; - cmExpandList(variableContent, list); + std::vector<std::string> list = cmExpandedList(variableContent); for (std::string const& i : list) { stream << " " << QuotePath(i); diff --git a/Source/CPack/cmCPackArchiveGenerator.cxx b/Source/CPack/cmCPackArchiveGenerator.cxx index 98fb29d..6c9c6b9 100644 --- a/Source/CPack/cmCPackArchiveGenerator.cxx +++ b/Source/CPack/cmCPackArchiveGenerator.cxx @@ -6,6 +6,7 @@ #include "cmCPackGenerator.h" #include "cmCPackLog.h" #include "cmGeneratedFileStream.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmWorkingDirectory.h" @@ -71,8 +72,7 @@ int cmCPackArchiveGenerator::addOneComponentToArchive( } std::string filePrefix; if (this->IsOn("CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY")) { - filePrefix = this->GetOption("CPACK_PACKAGE_FILE_NAME"); - filePrefix += "/"; + filePrefix = cmStrCat(this->GetOption("CPACK_PACKAGE_FILE_NAME"), '/'); } const char* installPrefix = this->GetOption("CPACK_PACKAGING_INSTALL_PREFIX"); diff --git a/Source/CPack/cmCPackBundleGenerator.cxx b/Source/CPack/cmCPackBundleGenerator.cxx index 213ce92..4d5f43f 100644 --- a/Source/CPack/cmCPackBundleGenerator.cxx +++ b/Source/CPack/cmCPackBundleGenerator.cxx @@ -41,9 +41,8 @@ int cmCPackBundleGenerator::InitializeInternal() const char* cmCPackBundleGenerator::GetPackagingInstallPrefix() { - this->InstallPrefix = "/"; - this->InstallPrefix += this->GetOption("CPACK_BUNDLE_NAME"); - this->InstallPrefix += ".app/Contents/Resources"; + this->InstallPrefix = cmStrCat('/', this->GetOption("CPACK_BUNDLE_NAME"), + ".app/Contents/Resources"); return this->InstallPrefix.c_str(); } @@ -90,11 +89,10 @@ int cmCPackBundleGenerator::ConstructBundle() // The staging directory contains everything that will end-up inside the // final disk image ... - std::ostringstream staging; - staging << toplevel; + std::string const staging = toplevel; std::ostringstream contents; - contents << staging.str() << "/" << cpack_bundle_name << ".app/" + contents << staging << "/" << cpack_bundle_name << ".app/" << "Contents"; std::ostringstream application; @@ -191,9 +189,8 @@ int cmCPackBundleGenerator::SignBundle(const std::string& src_dir) if (!cpack_apple_cert_app.empty()) { std::string output; std::string bundle_path; - bundle_path = src_dir + "/"; - bundle_path += this->GetOption("CPACK_BUNDLE_NAME"); - bundle_path += ".app"; + bundle_path = + cmStrCat(src_dir, '/', this->GetOption("CPACK_BUNDLE_NAME"), ".app"); // A list of additional files to sign, ie. frameworks and plugins. const std::string sign_parameter = @@ -206,8 +203,7 @@ int cmCPackBundleGenerator::SignBundle(const std::string& src_dir) ? this->GetOption("CPACK_BUNDLE_APPLE_CODESIGN_FILES") : ""; - std::vector<std::string> relFiles; - cmExpandList(sign_files, relFiles); + std::vector<std::string> relFiles = cmExpandedList(sign_files); // sign the files supplied by the user, ie. frameworks. for (auto const& file : relFiles) { diff --git a/Source/CPack/cmCPackComponentGroup.cxx b/Source/CPack/cmCPackComponentGroup.cxx index f888a5f..9e05d86 100644 --- a/Source/CPack/cmCPackComponentGroup.cxx +++ b/Source/CPack/cmCPackComponentGroup.cxx @@ -2,6 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCPackComponentGroup.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include <string> @@ -14,9 +15,7 @@ unsigned long cmCPackComponent::GetInstalledSize( } for (std::string const& file : this->Files) { - std::string path = installDir; - path += '/'; - path += file; + std::string path = cmStrCat(installDir, '/', file); this->TotalSize += cmSystemTools::FileLength(path); } diff --git a/Source/CPack/cmCPackCygwinBinaryGenerator.cxx b/Source/CPack/cmCPackCygwinBinaryGenerator.cxx index 49a9f15..553a677 100644 --- a/Source/CPack/cmCPackCygwinBinaryGenerator.cxx +++ b/Source/CPack/cmCPackCygwinBinaryGenerator.cxx @@ -28,13 +28,11 @@ int cmCPackCygwinBinaryGenerator::InitializeInternal() int cmCPackCygwinBinaryGenerator::PackageFiles() { - std::string packageName = this->GetOption("CPACK_PACKAGE_NAME"); - packageName += "-"; - packageName += this->GetOption("CPACK_PACKAGE_VERSION"); + std::string packageName = + cmStrCat(this->GetOption("CPACK_PACKAGE_NAME"), '-', + this->GetOption("CPACK_PACKAGE_VERSION")); packageName = cmsys::SystemTools::LowerCase(packageName); - std::string manifest = "/usr/share/doc/"; - manifest += packageName; - manifest += "/MANIFEST"; + std::string manifest = cmStrCat("/usr/share/doc/", packageName, "/MANIFEST"); std::string manifestFile = this->GetOption("CPACK_TEMPORARY_DIRECTORY"); // Create a MANIFEST file that contains all of the files in // the tar file diff --git a/Source/CPack/cmCPackCygwinSourceGenerator.cxx b/Source/CPack/cmCPackCygwinSourceGenerator.cxx index 889f29a..8cae9b4 100644 --- a/Source/CPack/cmCPackCygwinSourceGenerator.cxx +++ b/Source/CPack/cmCPackCygwinSourceGenerator.cxx @@ -37,8 +37,7 @@ int cmCPackCygwinSourceGenerator::PackageFiles() { // Create a tar file of the sources std::string packageDirFileName = - this->GetOption("CPACK_TEMPORARY_DIRECTORY"); - packageDirFileName += ".tar.bz2"; + cmStrCat(this->GetOption("CPACK_TEMPORARY_DIRECTORY"), ".tar.bz2"); packageFileNames[0] = packageDirFileName; std::string output; // skip one parent up to the cmCPackTarBZip2Generator @@ -94,8 +93,8 @@ int cmCPackCygwinSourceGenerator::PackageFiles() << this->GetOption("CPACK_TOPLEVEL_DIRECTORY") << "]\n"); return 0; } - std::string outerTarFile = this->GetOption("CPACK_TEMPORARY_DIRECTORY"); - outerTarFile += "-"; + std::string outerTarFile = + cmStrCat(this->GetOption("CPACK_TEMPORARY_DIRECTORY"), '-'); const char* patch = this->GetOption("CPACK_CYGWIN_PATCH_NUMBER"); if (!patch) { cmCPackLogger(cmCPackLog::LOG_WARNING, @@ -106,19 +105,18 @@ int cmCPackCygwinSourceGenerator::PackageFiles() outerTarFile += patch; outerTarFile += "-src.tar.bz2"; std::string tmpDir = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); - std::string buildScript = tmpDir; - buildScript += "/"; - buildScript += cmSystemTools::GetFilenameName( - this->GetOption("CPACK_CYGWIN_BUILD_SCRIPT")); - std::string patchFile = tmpDir; - patchFile += "/"; - patchFile += - cmSystemTools::GetFilenameName(this->GetOption("CPACK_CYGWIN_PATCH_FILE")); + std::string buildScript = + cmStrCat(tmpDir, '/', + cmSystemTools::GetFilenameName( + this->GetOption("CPACK_CYGWIN_BUILD_SCRIPT"))); + std::string patchFile = + cmStrCat(tmpDir, '/', + cmSystemTools::GetFilenameName( + this->GetOption("CPACK_CYGWIN_PATCH_FILE"))); std::string file = cmSystemTools::GetFilenameName(compressOutFile); - std::string sourceTar = cmSystemTools::GetFilenamePath(compressOutFile); - sourceTar += "/"; - sourceTar += file; + std::string sourceTar = + cmStrCat(cmSystemTools::GetFilenamePath(compressOutFile), '/', file); /* reset list of file to be packaged */ files.clear(); // a source release in cygwin should have the build script used @@ -140,8 +138,8 @@ int cmCPackCygwinSourceGenerator::PackageFiles() const char* cmCPackCygwinSourceGenerator::GetPackagingInstallPrefix() { - this->InstallPrefix = "/"; - this->InstallPrefix += this->GetOption("CPACK_PACKAGE_FILE_NAME"); + this->InstallPrefix = + cmStrCat('/', this->GetOption("CPACK_PACKAGE_FILE_NAME")); return this->InstallPrefix.c_str(); } diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx index 7c2f21a..cefbc90 100644 --- a/Source/CPack/cmCPackDebGenerator.cxx +++ b/Source/CPack/cmCPackDebGenerator.cxx @@ -149,8 +149,7 @@ void DebGenerator::generateControlFile() const unsigned long totalSize = 0; { - std::string dirName = TemporaryDir; - dirName += '/'; + std::string dirName = cmStrCat(TemporaryDir, '/'); for (std::string const& file : PackageFiles) { totalSize += cmSystemTools::FileLength(file); } @@ -248,8 +247,7 @@ std::string DebGenerator::generateMD5File() const cmGeneratedFileStream out(md5filename); - std::string topLevelWithTrailingSlash = TemporaryDir; - topLevelWithTrailingSlash += '/'; + std::string topLevelWithTrailingSlash = cmStrCat(TemporaryDir, '/'); for (std::string const& file : PackageFiles) { // hash only regular files if (cmSystemTools::FileIsDirectory(file) || @@ -378,8 +376,7 @@ bool DebGenerator::generateControlTar(std::string const& md5Filename) const // default control_tar.ClearPermissions(); - std::vector<std::string> controlExtraList; - cmExpandList(ControlExtra, controlExtraList); + std::vector<std::string> controlExtraList = cmExpandedList(ControlExtra); for (std::string const& i : controlExtraList) { std::string filenamename = cmsys::SystemTools::GetFilenameName(i); std::string localcopy = WorkDir + "/" + filenamename; @@ -469,8 +466,7 @@ int cmCPackDebGenerator::PackageOnePack(std::string const& initialTopLevel, // Tell CPackDeb.cmake the name of the component GROUP. this->SetOption("CPACK_DEB_PACKAGE_COMPONENT", packageName.c_str()); // Tell CPackDeb.cmake the path where the component is. - std::string component_path = "/"; - component_path += packageName; + std::string component_path = cmStrCat('/', packageName); this->SetOption("CPACK_DEB_PACKAGE_COMPONENT_PART_PATH", component_path.c_str()); if (!this->ReadListFile("Internal/CPack/CPackDeb.cmake")) { @@ -500,9 +496,8 @@ int cmCPackDebGenerator::PackageOnePack(std::string const& initialTopLevel, retval = 0; } // add the generated package to package file names list - packageFileName = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); - packageFileName += "/"; - packageFileName += this->GetOption("GEN_CPACK_OUTPUT_FILE_NAME"); + packageFileName = cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), '/', + this->GetOption("GEN_CPACK_OUTPUT_FILE_NAME")); packageFileNames.push_back(std::move(packageFileName)); if (this->IsOn("GEN_CPACK_DEBIAN_DEBUGINFO_PACKAGE")) { @@ -524,9 +519,9 @@ int cmCPackDebGenerator::PackageOnePack(std::string const& initialTopLevel, retval = 0; } // add the generated package to package file names list - packageFileName = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); - packageFileName += "/"; - packageFileName += this->GetOption("GEN_CPACK_DBGSYM_OUTPUT_FILE_NAME"); + packageFileName = + cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), '/', + this->GetOption("GEN_CPACK_DBGSYM_OUTPUT_FILE_NAME")); packageFileNames.push_back(std::move(packageFileName)); } @@ -614,8 +609,7 @@ int cmCPackDebGenerator::PackageComponentsAllInOne( if (!compInstDirName.empty()) { // Tell CPackDeb.cmake the path where the component is. - std::string component_path = "/"; - component_path += compInstDirName; + std::string component_path = cmStrCat('/', compInstDirName); this->SetOption("CPACK_DEB_PACKAGE_COMPONENT_PART_PATH", component_path.c_str()); } @@ -644,9 +638,8 @@ int cmCPackDebGenerator::PackageComponentsAllInOne( retval = 0; } // add the generated package to package file names list - packageFileName = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); - packageFileName += "/"; - packageFileName += this->GetOption("GEN_CPACK_OUTPUT_FILE_NAME"); + packageFileName = cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), '/', + this->GetOption("GEN_CPACK_OUTPUT_FILE_NAME")); packageFileNames.push_back(std::move(packageFileName)); return retval; } diff --git a/Source/CPack/cmCPackDragNDropGenerator.cxx b/Source/CPack/cmCPackDragNDropGenerator.cxx index 85faa61..ca06b81 100644 --- a/Source/CPack/cmCPackDragNDropGenerator.cxx +++ b/Source/CPack/cmCPackDragNDropGenerator.cxx @@ -128,8 +128,8 @@ int cmCPackDragNDropGenerator::InitializeInternal() return 0; } - std::vector<std::string> languages; - cmExpandList(this->GetOption("CPACK_DMG_SLA_LANGUAGES"), languages); + std::vector<std::string> languages = + cmExpandedList(this->GetOption("CPACK_DMG_SLA_LANGUAGES")); if (languages.empty()) { cmCPackLogger(cmCPackLog::LOG_ERROR, "CPACK_DMG_SLA_LANGUAGES set but empty" << std::endl); @@ -196,9 +196,7 @@ int cmCPackDragNDropGenerator::PackageFiles() full_package_name += std::string(GetOutputExtension()); packageFileNames.push_back(full_package_name); - std::string src_dir = toplevel; - src_dir += "/"; - src_dir += package_file; + std::string src_dir = cmStrCat(toplevel, '/', package_file); if (0 == this->CreateDMG(src_dir, full_package_name)) { return 0; @@ -409,8 +407,8 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, } // Create a temporary read-write disk image ... - std::string temp_image = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); - temp_image += "/temp.dmg"; + std::string temp_image = + cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), "/temp.dmg"); std::string create_error; std::ostringstream temp_image_command; @@ -522,8 +520,8 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, if (!cpack_license_file.empty() || !slaDirectory.empty()) { // Use old hardcoded style if sla_dir is not set bool oldStyle = slaDirectory.empty(); - std::string sla_r = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); - sla_r += "/sla.r"; + std::string sla_r = + cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), "/sla.r"); std::vector<std::string> languages; if (!oldStyle) { @@ -649,8 +647,8 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, if (temp_image_format != "UDZO") { temp_image_format = "UDZO"; // convert to UDZO to enable unflatten/flatten - std::string temp_udzo = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); - temp_udzo += "/temp-udzo.dmg"; + std::string temp_udzo = cmStrCat( + this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), "/temp-udzo.dmg"); std::ostringstream udco_image_command; udco_image_command << this->GetOption("CPACK_COMMAND_HDIUTIL"); diff --git a/Source/CPack/cmCPackFreeBSDGenerator.cxx b/Source/CPack/cmCPackFreeBSDGenerator.cxx index b90a27c..a35977c 100644 --- a/Source/CPack/cmCPackFreeBSDGenerator.cxx +++ b/Source/CPack/cmCPackFreeBSDGenerator.cxx @@ -228,8 +228,8 @@ void cmCPackFreeBSDGenerator::write_manifest_fields( manifest << ManifestKeyValue( "desc", var_lookup("CPACK_FREEBSD_PACKAGE_DESCRIPTION")); manifest << ManifestKeyValue("www", var_lookup("CPACK_FREEBSD_PACKAGE_WWW")); - std::vector<std::string> licenses; - cmExpandList(var_lookup("CPACK_FREEBSD_PACKAGE_LICENSE"), licenses); + std::vector<std::string> licenses = + cmExpandedList(var_lookup("CPACK_FREEBSD_PACKAGE_LICENSE")); std::string licenselogic("single"); if (licenses.empty()) { cmSystemTools::SetFatalErrorOccured(); @@ -238,12 +238,12 @@ void cmCPackFreeBSDGenerator::write_manifest_fields( } manifest << ManifestKeyValue("licenselogic", licenselogic); manifest << (ManifestKeyListValue("licenses") << licenses); - std::vector<std::string> categories; - cmExpandList(var_lookup("CPACK_FREEBSD_PACKAGE_CATEGORIES"), categories); + std::vector<std::string> categories = + cmExpandedList(var_lookup("CPACK_FREEBSD_PACKAGE_CATEGORIES")); manifest << (ManifestKeyListValue("categories") << categories); manifest << ManifestKeyValue("prefix", var_lookup("CMAKE_INSTALL_PREFIX")); - std::vector<std::string> deps; - cmExpandList(var_lookup("CPACK_FREEBSD_PACKAGE_DEPS"), deps); + std::vector<std::string> deps = + cmExpandedList(var_lookup("CPACK_FREEBSD_PACKAGE_DEPS")); if (!deps.empty()) { manifest << (ManifestKeyDepsValue("deps") << deps); } diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx index 065aadf..a96c1c8 100644 --- a/Source/CPack/cmCPackGenerator.cxx +++ b/Source/CPack/cmCPackGenerator.cxx @@ -73,8 +73,8 @@ int cmCPackGenerator::PrepareNames() } } - std::string tempDirectory = this->GetOption("CPACK_PACKAGE_DIRECTORY"); - tempDirectory += "/_CPack_Packages/"; + std::string tempDirectory = + cmStrCat(this->GetOption("CPACK_PACKAGE_DIRECTORY"), "/_CPack_Packages/"); const char* toplevelTag = this->GetOption("CPACK_TOPLEVEL_TAG"); if (toplevelTag) { tempDirectory += toplevelTag; @@ -197,8 +197,7 @@ int cmCPackGenerator::InstallProject() } if (setDestDir) { - std::string destDir = "DESTDIR="; - destDir += tempInstallDirectory; + std::string destDir = cmStrCat("DESTDIR=", tempInstallDirectory); cmSystemTools::PutEnv(destDir); } else { // Make sure there is no destdir @@ -211,8 +210,8 @@ int cmCPackGenerator::InstallProject() const char* default_dir_install_permissions = this->GetOption("CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS"); if (default_dir_install_permissions && *default_dir_install_permissions) { - std::vector<std::string> items; - cmExpandList(default_dir_install_permissions, items); + std::vector<std::string> items = + cmExpandedList(default_dir_install_permissions); for (const auto& arg : items) { if (!cmFSPermissions::stringToModeT(arg, default_dir_mode_v)) { cmCPackLogger(cmCPackLog::LOG_ERROR, @@ -271,11 +270,11 @@ int cmCPackGenerator::InstallProjectViaInstallCommands( (void)setDestDir; const char* installCommands = this->GetOption("CPACK_INSTALL_COMMANDS"); if (installCommands && *installCommands) { - std::string tempInstallDirectoryEnv = "CMAKE_INSTALL_PREFIX="; - tempInstallDirectoryEnv += tempInstallDirectory; + std::string tempInstallDirectoryEnv = + cmStrCat("CMAKE_INSTALL_PREFIX=", tempInstallDirectory); cmSystemTools::PutEnv(tempInstallDirectoryEnv); - std::vector<std::string> installCommandsVector; - cmExpandList(installCommands, installCommandsVector); + std::vector<std::string> installCommandsVector = + cmExpandedList(installCommands); for (std::string const& ic : installCommandsVector) { cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << ic << std::endl); std::string output; @@ -284,8 +283,8 @@ int cmCPackGenerator::InstallProjectViaInstallCommands( ic, &output, &output, &retVal, nullptr, this->GeneratorVerbose, cmDuration::zero()); if (!resB || retVal) { - std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); - tmpFile += "/InstallOutput.log"; + std::string tmpFile = cmStrCat( + this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), "/InstallOutput.log"); cmGeneratedFileStream ofs(tmpFile); ofs << "# Run command: " << ic << std::endl << "# Output:" << std::endl @@ -311,8 +310,8 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories( std::vector<cmsys::RegularExpression> ignoreFilesRegex; const char* cpackIgnoreFiles = this->GetOption("CPACK_IGNORE_FILES"); if (cpackIgnoreFiles) { - std::vector<std::string> ignoreFilesRegexString; - cmExpandList(cpackIgnoreFiles, ignoreFilesRegexString); + std::vector<std::string> ignoreFilesRegexString = + cmExpandedList(cpackIgnoreFiles); for (std::string const& ifr : ignoreFilesRegexString) { cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Create ignore files regex for: " << ifr << std::endl); @@ -322,8 +321,8 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories( const char* installDirectories = this->GetOption("CPACK_INSTALLED_DIRECTORIES"); if (installDirectories && *installDirectories) { - std::vector<std::string> installDirectoriesVector; - cmExpandList(installDirectories, installDirectoriesVector); + std::vector<std::string> installDirectoriesVector = + cmExpandedList(installDirectories); if (installDirectoriesVector.size() % 2 != 0) { cmCPackLogger( cmCPackLog::LOG_ERROR, @@ -343,8 +342,7 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories( std::string top = *it; it++; std::string subdir = *it; - std::string findExpr = top; - findExpr += "/*"; + std::string findExpr = cmStrCat(top, "/*"); cmCPackLogger(cmCPackLog::LOG_OUTPUT, "- Install directory: " << top << std::endl); gl.RecurseOn(); @@ -372,8 +370,8 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories( if (skip) { continue; } - std::string filePath = tempDir; - filePath += "/" + subdir + "/" + cmSystemTools::RelativePath(top, gf); + std::string filePath = cmStrCat(tempDir, '/', subdir, '/', + cmSystemTools::RelativePath(top, gf)); cmCPackLogger(cmCPackLog::LOG_DEBUG, "Copy file: " << inFile << " -> " << filePath << std::endl); @@ -398,8 +396,7 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories( /* rebuild symlinks in the installed tree */ if (!symlinkedFiles.empty()) { std::string curDir = cmSystemTools::GetCurrentWorkingDirectory(); - std::string goToDir = tempDir; - goToDir += "/" + subdir; + std::string goToDir = cmStrCat(tempDir, '/', subdir); cmCPackLogger(cmCPackLog::LOG_DEBUG, "Change dir to: " << goToDir << std::endl); cmWorkingDirectory workdir(goToDir); @@ -463,8 +460,7 @@ int cmCPackGenerator::InstallProjectViaInstallScript( if (cmakeScripts && *cmakeScripts) { cmCPackLogger(cmCPackLog::LOG_OUTPUT, "- Install scripts: " << cmakeScripts << std::endl); - std::vector<std::string> cmakeScriptsVector; - cmExpandList(cmakeScripts, cmakeScriptsVector); + std::vector<std::string> cmakeScriptsVector = cmExpandedList(cmakeScripts); for (std::string const& installScript : cmakeScriptsVector) { cmCPackLogger(cmCPackLog::LOG_OUTPUT, @@ -528,8 +524,8 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( << std::endl); return 0; } - std::vector<std::string> cmakeProjectsVector; - cmExpandList(cmakeProjects, cmakeProjectsVector); + std::vector<std::string> cmakeProjectsVector = + cmExpandedList(cmakeProjects); std::vector<std::string>::iterator it; for (it = cmakeProjectsVector.begin(); it != cmakeProjectsVector.end(); ++it) { @@ -573,8 +569,8 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( cmSystemTools::UpperCase(project.Component) + "_INSTALL_TYPES"; const char* installTypes = this->GetOption(installTypesVar); if (installTypes && *installTypes) { - std::vector<std::string> installTypesVector; - cmExpandList(installTypes, installTypesVector); + std::vector<std::string> installTypesVector = + cmExpandedList(installTypes); for (std::string const& installType : installTypesVector) { project.InstallationTypes.push_back( this->GetInstallationType(project.ProjectName, installType)); @@ -690,8 +686,8 @@ int cmCPackGenerator::RunPreinstallTarget( buildCommand, &output, &output, &retVal, installDirectory.c_str(), this->GeneratorVerbose, cmDuration::zero()); if (!resB || retVal) { - std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); - tmpFile += "/PreinstallOutput.log"; + std::string tmpFile = cmStrCat( + this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), "/PreinstallOutput.log"); cmGeneratedFileStream ofs(tmpFile); ofs << "# Run command: " << buildCommand << std::endl << "# Directory: " << installDirectory << std::endl @@ -939,10 +935,8 @@ int cmCPackGenerator::InstallCMakeProject( GetComponentInstallDirNameSuffix(component); if (nullptr != this->GetOption(absoluteDestFileComponent)) { std::string absoluteDestFilesListComponent = - this->GetOption(absoluteDestFileComponent); - absoluteDestFilesListComponent += ";"; - absoluteDestFilesListComponent += - mf.GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES"); + cmStrCat(this->GetOption(absoluteDestFileComponent), ';', + mf.GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES")); this->SetOption(absoluteDestFileComponent, absoluteDestFilesListComponent.c_str()); } else { @@ -1034,8 +1028,7 @@ int cmCPackGenerator::DoPackage() cmCPackLogger(cmCPackLog::LOG_DEBUG, "Find files" << std::endl); cmsys::Glob gl; - std::string findExpr = tempDirectory; - findExpr += "/*"; + std::string findExpr = cmStrCat(tempDirectory, "/*"); gl.RecurseOn(); gl.SetRecurseListDirs(true); gl.SetRecurseThroughSymlinks(false); @@ -1231,8 +1224,7 @@ const char* cmCPackGenerator::GetInstallPath() if (cmsys::SystemTools::GetEnv("ProgramFiles", prgfiles)) { this->InstallPath = prgfiles; } else if (cmsys::SystemTools::GetEnv("SystemDrive", sysDrive)) { - this->InstallPath = sysDrive; - this->InstallPath += "/Program Files"; + this->InstallPath = cmStrCat(sysDrive, "/Program Files"); } else { this->InstallPath = "c:/Program Files"; } @@ -1528,8 +1520,8 @@ cmCPackComponent* cmCPackGenerator::GetComponent( // Determine the installation types. const char* installTypes = this->GetOption(macroPrefix + "_INSTALL_TYPES"); if (installTypes && *installTypes) { - std::vector<std::string> installTypesVector; - cmExpandList(installTypes, installTypesVector); + std::vector<std::string> installTypesVector = + cmExpandedList(installTypes); for (std::string const& installType : installTypesVector) { component->InstallationTypes.push_back( this->GetInstallationType(projectName, installType)); @@ -1539,8 +1531,7 @@ cmCPackComponent* cmCPackGenerator::GetComponent( // Determine the component dependencies. const char* depends = this->GetOption(macroPrefix + "_DEPENDS"); if (depends && *depends) { - std::vector<std::string> dependsVector; - cmExpandList(depends, dependsVector); + std::vector<std::string> dependsVector = cmExpandedList(depends); for (std::string const& depend : dependsVector) { cmCPackComponent* child = GetComponent(projectName, depend); component->Dependencies.push_back(child); diff --git a/Source/CPack/cmCPackLog.cxx b/Source/CPack/cmCPackLog.cxx index a3ca4b5..ca675fd 100644 --- a/Source/CPack/cmCPackLog.cxx +++ b/Source/CPack/cmCPackLog.cxx @@ -83,7 +83,7 @@ void cmCPackLog::Log(int tag, const char* file, int line, const char* msg, if (!tagString.empty()) { tagString += ","; } - tagString = "VERBOSE"; + tagString += "VERBOSE"; } } if (tag & LOG_WARNING) { @@ -93,7 +93,7 @@ void cmCPackLog::Log(int tag, const char* file, int line, const char* msg, if (!tagString.empty()) { tagString += ","; } - tagString = "WARNING"; + tagString += "WARNING"; } } if (tag & LOG_ERROR) { @@ -103,7 +103,7 @@ void cmCPackLog::Log(int tag, const char* file, int line, const char* msg, if (!tagString.empty()) { tagString += ","; } - tagString = "ERROR"; + tagString += "ERROR"; } } if (tag & LOG_DEBUG && this->Debug) { @@ -113,7 +113,7 @@ void cmCPackLog::Log(int tag, const char* file, int line, const char* msg, if (!tagString.empty()) { tagString += ","; } - tagString = "DEBUG"; + tagString += "DEBUG"; } useFileAndLine = true; } @@ -124,7 +124,7 @@ void cmCPackLog::Log(int tag, const char* file, int line, const char* msg, if (!tagString.empty()) { tagString += ","; } - tagString = "VERBOSE"; + tagString += "VERBOSE"; } } if (this->Quiet) { diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx index 961a9d4..8098edf 100644 --- a/Source/CPack/cmCPackNSISGenerator.cxx +++ b/Source/CPack/cmCPackNSISGenerator.cxx @@ -2,6 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCPackNSISGenerator.h" +#include "cmAlgorithms.h" #include "cmCPackComponentGroup.h" #include "cmCPackGenerator.h" #include "cmCPackLog.h" @@ -55,8 +56,7 @@ int cmCPackNSISGenerator::PackageFiles() } std::string nsisFileName = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); - std::string tmpFile = nsisFileName; - tmpFile += "/NSISOutput.log"; + std::string tmpFile = cmStrCat(nsisFileName, "/NSISOutput.log"); std::string nsisInstallOptions = nsisFileName + "/NSIS.InstallOptions.ini"; nsisFileName += "/project.nsi"; std::ostringstream str; @@ -141,39 +141,34 @@ int cmCPackNSISGenerator::PackageFiles() installerIconCode.c_str()); } if (this->IsSet("CPACK_PACKAGE_ICON")) { - std::string installerIconCode = "!define MUI_HEADERIMAGE_BITMAP \""; - installerIconCode += this->GetOption("CPACK_PACKAGE_ICON"); - installerIconCode += "\"\n"; + std::string installerIconCode = + cmStrCat("!define MUI_HEADERIMAGE_BITMAP \"", + this->GetOption("CPACK_PACKAGE_ICON"), "\"\n"); this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_ICON_CODE", installerIconCode.c_str()); } if (this->IsSet("CPACK_NSIS_MUI_WELCOMEFINISHPAGE_BITMAP")) { - std::string installerBitmapCode = - "!define MUI_WELCOMEFINISHPAGE_BITMAP \""; - installerBitmapCode += - this->GetOption("CPACK_NSIS_MUI_WELCOMEFINISHPAGE_BITMAP"); - installerBitmapCode += "\"\n"; + std::string installerBitmapCode = cmStrCat( + "!define MUI_WELCOMEFINISHPAGE_BITMAP \"", + this->GetOption("CPACK_NSIS_MUI_WELCOMEFINISHPAGE_BITMAP"), "\"\n"); this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_MUI_WELCOMEFINISH_CODE", installerBitmapCode.c_str()); } if (this->IsSet("CPACK_NSIS_MUI_UNWELCOMEFINISHPAGE_BITMAP")) { - std::string installerBitmapCode = - "!define MUI_UNWELCOMEFINISHPAGE_BITMAP \""; - installerBitmapCode += - this->GetOption("CPACK_NSIS_MUI_UNWELCOMEFINISHPAGE_BITMAP"); - installerBitmapCode += "\"\n"; + std::string installerBitmapCode = cmStrCat( + "!define MUI_UNWELCOMEFINISHPAGE_BITMAP \"", + this->GetOption("CPACK_NSIS_MUI_UNWELCOMEFINISHPAGE_BITMAP"), "\"\n"); this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_MUI_UNWELCOMEFINISH_CODE", installerBitmapCode.c_str()); } if (this->IsSet("CPACK_NSIS_MUI_FINISHPAGE_RUN")) { - std::string installerRunCode = "!define MUI_FINISHPAGE_RUN \"$INSTDIR\\"; - installerRunCode += this->GetOption("CPACK_NSIS_EXECUTABLES_DIRECTORY"); - installerRunCode += "\\"; - installerRunCode += this->GetOption("CPACK_NSIS_MUI_FINISHPAGE_RUN"); - installerRunCode += "\"\n"; + std::string installerRunCode = + cmStrCat("!define MUI_FINISHPAGE_RUN \"$INSTDIR\\", + this->GetOption("CPACK_NSIS_EXECUTABLES_DIRECTORY"), '\\', + this->GetOption("CPACK_NSIS_MUI_FINISHPAGE_RUN"), "\"\n"); this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_MUI_FINISHPAGE_RUN_CODE", installerRunCode.c_str()); } @@ -296,9 +291,9 @@ int cmCPackNSISGenerator::PackageFiles() this->ConfigureFile(nsisInInstallOptions, nsisInstallOptions); this->ConfigureFile(nsisInFileName, nsisFileName); - std::string nsisCmd = "\""; - nsisCmd += this->GetOption("CPACK_INSTALLER_PROGRAM"); - nsisCmd += "\" \"" + nsisFileName + "\""; + std::string nsisCmd = + cmStrCat('"', this->GetOption("CPACK_INSTALLER_PROGRAM"), "\" \"", + nsisFileName, '"'); cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << nsisCmd << std::endl); std::string output; int retVal = 1; @@ -414,8 +409,7 @@ int cmCPackNSISGenerator::InitializeInternal() if (!resS || retVal || (!versionRex.find(output) && !versionRexCVS.find(output))) { const char* topDir = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); - std::string tmpFile = topDir ? topDir : "."; - tmpFile += "/NSISOutput.log"; + std::string tmpFile = cmStrCat(topDir ? topDir : ".", "/NSISOutput.log"); cmGeneratedFileStream ofs(tmpFile); ofs << "# Run command: " << nsisCmd << std::endl << "# Output:" << std::endl @@ -477,8 +471,8 @@ int cmCPackNSISGenerator::InitializeInternal() cmCPackLogger(cmCPackLog::LOG_DEBUG, "The cpackPackageExecutables: " << cpackPackageExecutables << "." << std::endl); - std::vector<std::string> cpackPackageExecutablesVector; - cmExpandList(cpackPackageExecutables, cpackPackageExecutablesVector); + std::vector<std::string> cpackPackageExecutablesVector = + cmExpandedList(cpackPackageExecutables); if (cpackPackageExecutablesVector.size() % 2 != 0) { cmCPackLogger( cmCPackLog::LOG_ERROR, @@ -500,10 +494,7 @@ int cmCPackNSISGenerator::InitializeInternal() << ".lnk\"" << std::endl; // see if CPACK_CREATE_DESKTOP_LINK_ExeName is on // if so add a desktop link - if (!cpackPackageDesktopLinksVector.empty() && - std::find(cpackPackageDesktopLinksVector.begin(), - cpackPackageDesktopLinksVector.end(), - execName) != cpackPackageDesktopLinksVector.end()) { + if (cmContains(cpackPackageDesktopLinksVector, execName)) { str << " StrCmp \"$INSTALL_DESKTOP\" \"1\" 0 +2\n"; str << " CreateShortCut \"$DESKTOP\\" << linkName << R"(.lnk" "$INSTDIR\)" << cpackNsisExecutablesDirectory << "\\" @@ -533,8 +524,8 @@ void cmCPackNSISGenerator::CreateMenuLinks(std::ostream& str, } cmCPackLogger(cmCPackLog::LOG_DEBUG, "The cpackMenuLinks: " << cpackMenuLinks << "." << std::endl); - std::vector<std::string> cpackMenuLinksVector; - cmExpandList(cpackMenuLinks, cpackMenuLinksVector); + std::vector<std::string> cpackMenuLinksVector = + cmExpandedList(cpackMenuLinks); if (cpackMenuLinksVector.size() % 2 != 0) { cmCPackLogger( cmCPackLog::LOG_ERROR, @@ -575,8 +566,7 @@ void cmCPackNSISGenerator::CreateMenuLinks(std::ostream& str, } // see if CPACK_CREATE_DESKTOP_LINK_ExeName is on // if so add a desktop link - std::string desktop = "CPACK_CREATE_DESKTOP_LINK_"; - desktop += linkName; + std::string desktop = cmStrCat("CPACK_CREATE_DESKTOP_LINK_", linkName); if (this->IsSet(desktop)) { str << " StrCmp \"$INSTALL_DESKTOP\" \"1\" 0 +2\n"; str << " CreateShortCut \"$DESKTOP\\" << linkName @@ -658,8 +648,8 @@ std::string cmCPackNSISGenerator::CreateComponentDescription( if (component->IsDownloaded) { if (component->ArchiveFile.empty()) { // Compute the name of the archive. - std::string packagesDir = this->GetOption("CPACK_TEMPORARY_DIRECTORY"); - packagesDir += ".dummy"; + std::string packagesDir = + cmStrCat(this->GetOption("CPACK_TEMPORARY_DIRECTORY"), ".dummy"); std::ostringstream out; out << cmSystemTools::GetFilenameWithoutLastExtension(packagesDir) << "-" << component->Name << ".zip"; @@ -673,8 +663,8 @@ std::string cmCPackNSISGenerator::CreateComponentDescription( if (userUploadDirectory && *userUploadDirectory) { uploadDirectory = userUploadDirectory; } else { - uploadDirectory = this->GetOption("CPACK_PACKAGE_DIRECTORY"); - uploadDirectory += "/CPackUploads"; + uploadDirectory = + cmStrCat(this->GetOption("CPACK_PACKAGE_DIRECTORY"), "/CPackUploads"); } if (!cmSystemTools::FileExists(uploadDirectory)) { if (!cmSystemTools::MakeDirectory(uploadDirectory)) { @@ -711,15 +701,13 @@ std::string cmCPackNSISGenerator::CreateComponentDescription( } // The directory where this component's files reside - std::string dirName = this->GetOption("CPACK_TEMPORARY_DIRECTORY"); - dirName += '/'; - dirName += component->Name; - dirName += '/'; + std::string dirName = cmStrCat( + this->GetOption("CPACK_TEMPORARY_DIRECTORY"), '/', component->Name, '/'); // Build the list of files to go into this archive, and determine the // size of the installed component. - std::string zipListFileName = this->GetOption("CPACK_TEMPORARY_DIRECTORY"); - zipListFileName += "/winZip.filelist"; + std::string zipListFileName = cmStrCat( + this->GetOption("CPACK_TEMPORARY_DIRECTORY"), "/winZip.filelist"); bool needQuotesInFile = cmIsOn(this->GetOption("CPACK_ZIP_NEED_QUOTES")); unsigned long totalSize = 0; { // the scope is needed for cmGeneratedFileStream @@ -749,8 +737,8 @@ std::string cmCPackNSISGenerator::CreateComponentDescription( cmd, &output, &output, &retVal, dirName.c_str(), cmSystemTools::OUTPUT_NONE, cmDuration::zero()); if (!res || retVal) { - std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); - tmpFile += "/CompressZip.log"; + std::string tmpFile = cmStrCat( + this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), "/CompressZip.log"); cmGeneratedFileStream ofs(tmpFile); ofs << "# Run command: " << cmd << std::endl << "# Output:" << std::endl diff --git a/Source/CPack/cmCPackOSXX11Generator.cxx b/Source/CPack/cmCPackOSXX11Generator.cxx index 7cc48f4..992299a 100644 --- a/Source/CPack/cmCPackOSXX11Generator.cxx +++ b/Source/CPack/cmCPackOSXX11Generator.cxx @@ -29,8 +29,8 @@ int cmCPackOSXX11Generator::PackageFiles() << "." << std::endl); std::ostringstream str; std::ostringstream deleteStr; - std::vector<std::string> cpackPackageExecutablesVector; - cmExpandList(cpackPackageExecutables, cpackPackageExecutablesVector); + std::vector<std::string> cpackPackageExecutablesVector = + cmExpandedList(cpackPackageExecutables); if (cpackPackageExecutablesVector.size() % 2 != 0) { cmCPackLogger( cmCPackLog::LOG_ERROR, @@ -55,16 +55,14 @@ int cmCPackOSXX11Generator::PackageFiles() diskImageDirectory + "/.background"; // App bundle directories - std::string packageDirFileName = toplevel; - packageDirFileName += "/"; - packageDirFileName += this->GetOption("CPACK_PACKAGE_FILE_NAME"); - packageDirFileName += ".app"; + std::string packageDirFileName = cmStrCat( + toplevel, '/', this->GetOption("CPACK_PACKAGE_FILE_NAME"), ".app"); std::string contentsDirectory = packageDirFileName + "/Contents"; std::string resourcesDirectory = contentsDirectory + "/Resources"; std::string appDirectory = contentsDirectory + "/MacOS"; std::string scriptDirectory = resourcesDirectory + "/Scripts"; - std::string resourceFileName = this->GetOption("CPACK_PACKAGE_FILE_NAME"); - resourceFileName += ".rsrc"; + std::string resourceFileName = + cmStrCat(this->GetOption("CPACK_PACKAGE_FILE_NAME"), ".rsrc"); const char* dir = resourcesDirectory.c_str(); const char* appdir = appDirectory.c_str(); @@ -113,13 +111,10 @@ int cmCPackOSXX11Generator::PackageFiles() } // Two of the files need to have execute permission, so ensure they do: - std::string runTimeScript = dir; - runTimeScript += "/"; - runTimeScript += "RuntimeScript"; + std::string runTimeScript = cmStrCat(dir, "/RuntimeScript"); - std::string appScriptName = appdir; - appScriptName += "/"; - appScriptName += this->GetOption("CPACK_PACKAGE_FILE_NAME"); + std::string appScriptName = + cmStrCat(appdir, '/', this->GetOption("CPACK_PACKAGE_FILE_NAME")); mode_t mode; if (cmsys::SystemTools::GetPermissions(runTimeScript.c_str(), mode)) { @@ -139,8 +134,8 @@ int cmCPackOSXX11Generator::PackageFiles() } std::string output; - std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); - tmpFile += "/hdiutilOutput.log"; + std::string tmpFile = cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), + "/hdiutilOutput.log"); std::ostringstream dmgCmd; dmgCmd << "\"" << this->GetOption("CPACK_INSTALLER_PROGRAM_DISK_IMAGE") << "\" create -ov -fs HFS+ -format UDZO -srcfolder \"" @@ -228,9 +223,8 @@ bool cmCPackOSXX11Generator::CopyCreateResourceFile(const std::string& name) return false; } - std::string destFileName = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); - destFileName += "/Resources/"; - destFileName += name + ext; + std::string destFileName = cmStrCat( +this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), "/Resources/", name, ext ); cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Configure file: " @@ -245,9 +239,7 @@ bool cmCPackOSXX11Generator::CopyResourcePlistFile( const std::string& name, const std::string& dir, const char* outputFileName /* = 0 */, bool copyOnly /* = false */) { - std::string inFName = "Internal/CPack/CPack."; - inFName += name; - inFName += ".in"; + std::string inFName = cmStrCat("Internal/CPack/CPack.", name, ".in"); std::string inFileName = this->FindTemplate(inFName.c_str()); if (inFileName.empty()) { cmCPackLogger(cmCPackLog::LOG_ERROR, @@ -259,9 +251,7 @@ bool cmCPackOSXX11Generator::CopyResourcePlistFile( outputFileName = name.c_str(); } - std::string destFileName = dir; - destFileName += "/"; - destFileName += outputFileName; + std::string destFileName = cmStrCat(dir, '/', outputFileName); cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Configure file: " << inFileName << " to " << destFileName @@ -272,8 +262,8 @@ bool cmCPackOSXX11Generator::CopyResourcePlistFile( const char* cmCPackOSXX11Generator::GetPackagingInstallPrefix() { - this->InstallPrefix = "/"; - this->InstallPrefix += this->GetOption("CPACK_PACKAGE_FILE_NAME"); - this->InstallPrefix += ".app/Contents/Resources"; + this->InstallPrefix = + cmStrCat('/', this->GetOption("CPACK_PACKAGE_FILE_NAME"), + ".app/Contents/Resources"); return this->InstallPrefix.c_str(); } diff --git a/Source/CPack/cmCPackPKGGenerator.cxx b/Source/CPack/cmCPackPKGGenerator.cxx index d361921..3e1a51b 100644 --- a/Source/CPack/cmCPackPKGGenerator.cxx +++ b/Source/CPack/cmCPackPKGGenerator.cxx @@ -7,6 +7,7 @@ #include "cmCPackComponentGroup.h" #include "cmCPackGenerator.h" #include "cmCPackLog.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmXMLWriter.h" @@ -34,8 +35,8 @@ std::string cmCPackPKGGenerator::GetPackageName( const cmCPackComponent& component) { if (component.ArchiveFile.empty()) { - std::string packagesDir = this->GetOption("CPACK_TEMPORARY_DIRECTORY"); - packagesDir += ".dummy"; + std::string packagesDir = + cmStrCat(this->GetOption("CPACK_TEMPORARY_DIRECTORY"), ".dummy"); std::ostringstream out; out << cmSystemTools::GetFilenameWithoutLastExtension(packagesDir) << "-" << component.Name << ".pkg"; @@ -56,8 +57,8 @@ void cmCPackPKGGenerator::WriteDistributionFile(const char* metapackageFile) return; } - std::string distributionFile = metapackageFile; - distributionFile += "/Contents/distribution.dist"; + std::string distributionFile = + cmStrCat(metapackageFile, "/Contents/distribution.dist"); // Create the choice outline, which provides a tree-based view of // the components in their groups. @@ -144,12 +145,9 @@ void cmCPackPKGGenerator::CreateChoice(const cmCPackComponentGroup& group, void cmCPackPKGGenerator::CreateChoice(const cmCPackComponent& component, cmXMLWriter& xout) { - std::string packageId = "com."; - packageId += this->GetOption("CPACK_PACKAGE_VENDOR"); - packageId += '.'; - packageId += this->GetOption("CPACK_PACKAGE_NAME"); - packageId += '.'; - packageId += component.Name; + std::string packageId = + cmStrCat("com.", this->GetOption("CPACK_PACKAGE_VENDOR"), '.', + this->GetOption("CPACK_PACKAGE_NAME"), '.', component.Name); xout.StartElement("choice"); xout.Attribute("id", component.Name + "Choice"); @@ -192,14 +190,13 @@ void cmCPackPKGGenerator::CreateChoice(const cmCPackComponent& component, // Create a description of the package associated with this // component. - std::string relativePackageLocation = "Contents/Packages/"; - relativePackageLocation += this->GetPackageName(component); + std::string relativePackageLocation = + cmStrCat("Contents/Packages/", this->GetPackageName(component)); // Determine the installed size of the package. - std::string dirName = this->GetOption("CPACK_TEMPORARY_DIRECTORY"); - dirName += '/'; - dirName += component.Name; - dirName += this->GetOption("CPACK_PACKAGING_INSTALL_PREFIX"); + std::string dirName = + cmStrCat(this->GetOption("CPACK_TEMPORARY_DIRECTORY"), '/', component.Name, + this->GetOption("CPACK_PACKAGING_INSTALL_PREFIX")); unsigned long installedSize = component.GetInstalledSizeInKbytes(dirName); xout.StartElement("pkg-ref"); @@ -282,9 +279,7 @@ bool cmCPackPKGGenerator::CopyCreateResourceFile(const std::string& name, return false; } - std::string destFileName = dirName; - destFileName += '/'; - destFileName += name + ext; + std::string destFileName = cmStrCat(dirName, '/', name, ext); // Set this so that distribution.dist gets the right name (without // the path). @@ -305,9 +300,7 @@ bool cmCPackPKGGenerator::CopyResourcePlistFile(const std::string& name, outName = name.c_str(); } - std::string inFName = "Internal/CPack/CPack."; - inFName += name; - inFName += ".in"; + std::string inFName = cmStrCat("Internal/CPack/CPack.", name, ".in"); std::string inFileName = this->FindTemplate(inFName.c_str()); if (inFileName.empty()) { cmCPackLogger(cmCPackLog::LOG_ERROR, @@ -315,9 +308,8 @@ bool cmCPackPKGGenerator::CopyResourcePlistFile(const std::string& name, return false; } - std::string destFileName = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); - destFileName += "/"; - destFileName += outName; + std::string destFileName = + cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), '/', outName); cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Configure file: " << inFileName << " to " << destFileName @@ -330,9 +322,7 @@ int cmCPackPKGGenerator::CopyInstallScript(const std::string& resdir, const std::string& script, const std::string& name) { - std::string dst = resdir; - dst += "/"; - dst += name; + std::string dst = cmStrCat(resdir, '/', name); cmSystemTools::CopyFileAlways(script, dst); cmSystemTools::SetPermissions(dst.c_str(), 0777); cmCPackLogger(cmCPackLog::LOG_VERBOSE, diff --git a/Source/CPack/cmCPackPackageMakerGenerator.cxx b/Source/CPack/cmCPackPackageMakerGenerator.cxx index 3d93c48..5dc36ab 100644 --- a/Source/CPack/cmCPackPackageMakerGenerator.cxx +++ b/Source/CPack/cmCPackPackageMakerGenerator.cxx @@ -15,6 +15,7 @@ #include "cmCPackLog.h" #include "cmDuration.h" #include "cmGeneratedFileStream.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmXMLWriter.h" @@ -47,8 +48,8 @@ int cmCPackPackageMakerGenerator::PackageFiles() this->GetOption("CPACK_TEMPORARY_DIRECTORY"); if (this->Components.empty()) { packageDirFileName += ".pkg"; - resDir = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); - resDir += "/Resources"; + resDir = + cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), "/Resources"); } else { packageDirFileName += ".mpkg"; if (!cmsys::SystemTools::MakeDirectory(packageDirFileName.c_str())) { @@ -58,8 +59,7 @@ int cmCPackPackageMakerGenerator::PackageFiles() return 0; } - resDir = packageDirFileName; - resDir += "/Contents"; + resDir = cmStrCat(packageDirFileName, "/Contents"); if (!cmsys::SystemTools::MakeDirectory(resDir.c_str())) { cmCPackLogger(cmCPackLog::LOG_ERROR, "unable to create package subdirectory " << resDir @@ -155,8 +155,8 @@ int cmCPackPackageMakerGenerator::PackageFiles() if (!this->Components.empty()) { // Create the directory where component packages will be built. - std::string basePackageDir = packageDirFileName; - basePackageDir += "/Contents/Packages"; + std::string basePackageDir = + cmStrCat(packageDirFileName, "/Contents/Packages"); if (!cmsys::SystemTools::MakeDirectory(basePackageDir.c_str())) { cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem creating component packages directory: " @@ -172,8 +172,8 @@ int cmCPackPackageMakerGenerator::PackageFiles() if (userUploadDirectory && *userUploadDirectory) { uploadDirectory = userUploadDirectory; } else { - uploadDirectory = this->GetOption("CPACK_PACKAGE_DIRECTORY"); - uploadDirectory += "/CPackUploads"; + uploadDirectory = + cmStrCat(this->GetOption("CPACK_PACKAGE_DIRECTORY"), "/CPackUploads"); } // Create packages for each component @@ -232,9 +232,7 @@ int cmCPackPackageMakerGenerator::PackageFiles() packageFile += '/'; packageFile += GetPackageName(compIt->second); - std::string packageDir = toplevel; - packageDir += '/'; - packageDir += compIt->first; + std::string packageDir = cmStrCat(toplevel, '/', compIt->first); if (!this->GenerateComponentPackage( packageFile.c_str(), packageDir.c_str(), compIt->second)) { return 0; @@ -283,8 +281,8 @@ int cmCPackPackageMakerGenerator::PackageFiles() WriteDistributionFile(packageDirFileName.c_str()); } - std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); - tmpFile += "/hdiutilOutput.log"; + std::string tmpFile = cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), + "/hdiutilOutput.log"); std::ostringstream dmgCmd; dmgCmd << "\"" << this->GetOption("CPACK_INSTALLER_PROGRAM_DISK_IMAGE") << "\" create -ov -fs HFS+ -format UDZO -srcfolder \"" @@ -461,8 +459,8 @@ int cmCPackPackageMakerGenerator::InitializeInternal() bool cmCPackPackageMakerGenerator::RunPackageMaker(const char* command, const char* packageFile) { - std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); - tmpFile += "/PackageMakerOutput.log"; + std::string tmpFile = cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), + "/PackageMakerOutput.log"); cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << command << std::endl); std::string output; @@ -517,8 +515,9 @@ bool cmCPackPackageMakerGenerator::GenerateComponentPackage( this->PackageMakerVersion < 3.0) { // Create Description.plist and Info.plist files for normal Mac OS // X packages, which work on Mac OS X 10.3 and newer. - std::string descriptionFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); - descriptionFile += '/' + component.Name + "-Description.plist"; + std::string descriptionFile = + cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), '/', + component.Name, "-Description.plist"); cmsys::ofstream out(descriptionFile.c_str()); cmXMLWriter xout(out); xout.StartDocument(); @@ -539,12 +538,10 @@ bool cmCPackPackageMakerGenerator::GenerateComponentPackage( out.close(); // Create the Info.plist file for this component - std::string moduleVersionSuffix = "."; - moduleVersionSuffix += component.Name; + std::string moduleVersionSuffix = cmStrCat('.', component.Name); this->SetOption("CPACK_MODULE_VERSION_SUFFIX", moduleVersionSuffix.c_str()); - std::string infoFileName = component.Name; - infoFileName += "-Info.plist"; + std::string infoFileName = cmStrCat(component.Name, "-Info.plist"); if (!this->CopyResourcePlistFile("Info.plist", infoFileName.c_str())) { return false; } @@ -561,12 +558,9 @@ bool cmCPackPackageMakerGenerator::GenerateComponentPackage( // like normal packages, and can be downloaded by the installer // on-the-fly in Mac OS X 10.5 or newer. Thus, we need to create // flat packages when the packages will be downloaded on the fly. - std::string pkgId = "com."; - pkgId += this->GetOption("CPACK_PACKAGE_VENDOR"); - pkgId += '.'; - pkgId += this->GetOption("CPACK_PACKAGE_NAME"); - pkgId += '.'; - pkgId += component.Name; + std::string pkgId = + cmStrCat("com.", this->GetOption("CPACK_PACKAGE_VENDOR"), '.', + this->GetOption("CPACK_PACKAGE_NAME"), '.', component.Name); pkgCmd << "\"" << this->GetOption("CPACK_INSTALLER_PROGRAM") << "\" --root \"" << packageDir << "\"" diff --git a/Source/CPack/cmCPackProductBuildGenerator.cxx b/Source/CPack/cmCPackProductBuildGenerator.cxx index 94b5b5f..800af28 100644 --- a/Source/CPack/cmCPackProductBuildGenerator.cxx +++ b/Source/CPack/cmCPackProductBuildGenerator.cxx @@ -10,6 +10,7 @@ #include "cmCPackLog.h" #include "cmDuration.h" #include "cmGeneratedFileStream.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" cmCPackProductBuildGenerator::cmCPackProductBuildGenerator() @@ -28,8 +29,8 @@ int cmCPackProductBuildGenerator::PackageFiles() this->GetOption("CPACK_TEMPORARY_DIRECTORY"); // Create the directory where component packages will be built. - std::string basePackageDir = packageDirFileName; - basePackageDir += "/Contents/Packages"; + std::string basePackageDir = + cmStrCat(packageDirFileName, "/Contents/Packages"); if (!cmsys::SystemTools::MakeDirectory(basePackageDir.c_str())) { cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem creating component packages directory: " @@ -41,9 +42,7 @@ int cmCPackProductBuildGenerator::PackageFiles() std::map<std::string, cmCPackComponent>::iterator compIt; for (compIt = this->Components.begin(); compIt != this->Components.end(); ++compIt) { - std::string packageDir = toplevel; - packageDir += '/'; - packageDir += compIt->first; + std::string packageDir = cmStrCat(toplevel, '/', compIt->first); if (!this->GenerateComponentPackage(basePackageDir, GetPackageName(compIt->second), packageDir, &compIt->second)) { @@ -138,8 +137,8 @@ int cmCPackProductBuildGenerator::InitializeInternal() bool cmCPackProductBuildGenerator::RunProductBuild(const std::string& command) { - std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); - tmpFile += "/ProductBuildOutput.log"; + std::string tmpFile = cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), + "/ProductBuildOutput.log"); cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << command << std::endl); std::string output; @@ -166,9 +165,7 @@ bool cmCPackProductBuildGenerator::GenerateComponentPackage( const std::string& packageFileDir, const std::string& packageFileName, const std::string& packageDir, const cmCPackComponent* component) { - std::string packageFile = packageFileDir; - packageFile += '/'; - packageFile += packageFileName; + std::string packageFile = cmStrCat(packageFileDir, '/', packageFileName); cmCPackLogger(cmCPackLog::LOG_OUTPUT, "- Building component package: " << packageFile @@ -206,10 +203,8 @@ bool cmCPackProductBuildGenerator::GenerateComponentPackage( // The command that will be used to run ProductBuild std::ostringstream pkgCmd; - std::string pkgId = "com."; - pkgId += this->GetOption("CPACK_PACKAGE_VENDOR"); - pkgId += '.'; - pkgId += this->GetOption("CPACK_PACKAGE_NAME"); + std::string pkgId = cmStrCat("com.", this->GetOption("CPACK_PACKAGE_VENDOR"), + '.', this->GetOption("CPACK_PACKAGE_NAME")); if (component) { pkgId += '.'; pkgId += component->Name; diff --git a/Source/CPack/cmCPackRPMGenerator.cxx b/Source/CPack/cmCPackRPMGenerator.cxx index 9ffebf5..0f621cc 100644 --- a/Source/CPack/cmCPackRPMGenerator.cxx +++ b/Source/CPack/cmCPackRPMGenerator.cxx @@ -82,8 +82,7 @@ int cmCPackRPMGenerator::PackageOnePack(std::string const& initialToplevel, // Tell CPackRPM.cmake the name of the component NAME. this->SetOption("CPACK_RPM_PACKAGE_COMPONENT", packageName.c_str()); // Tell CPackRPM.cmake the path where the component is. - std::string component_path = "/"; - component_path += packageName; + std::string component_path = cmStrCat('/', packageName); this->SetOption("CPACK_RPM_PACKAGE_COMPONENT_PART_PATH", component_path.c_str()); if (!this->ReadListFile("Internal/CPack/CPackRPM.cmake")) { @@ -376,8 +375,7 @@ int cmCPackRPMGenerator::PackageComponentsAllInOne( if (!compInstDirName.empty()) { // Tell CPackRPM.cmake the path where the component is. - std::string component_path = "/"; - component_path += compInstDirName; + std::string component_path = cmStrCat('/', compInstDirName); this->SetOption("CPACK_RPM_PACKAGE_COMPONENT_PART_PATH", component_path.c_str()); } diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx index 3cf0c10..69dac88 100644 --- a/Source/CPack/cpack.cxx +++ b/Source/CPack/cpack.cxx @@ -1,20 +1,6 @@ /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ -#include "cmsys/CommandLineArguments.hxx" -#include "cmsys/Encoding.hxx" -#include <iostream> -#include <map> -#include <sstream> -#include <stddef.h> -#include <string> -#include <utility> -#include <vector> - -#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP) -# include "cmsys/ConsoleBuf.hxx" -#endif - #include "cmCPackGenerator.h" #include "cmCPackGeneratorFactory.h" #include "cmCPackLog.h" @@ -29,6 +15,21 @@ #include "cmSystemTools.h" #include "cmake.h" +#include "cmsys/CommandLineArguments.hxx" +#include "cmsys/Encoding.hxx" + +#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP) +# include "cmsys/ConsoleBuf.hxx" +#endif + +#include <iostream> +#include <map> +#include <sstream> +#include <stddef.h> +#include <string> +#include <utility> +#include <vector> + namespace { const char* cmDocumentationName[][2] = { { nullptr, " cpack - Packaging driver provided by CMake." }, @@ -229,8 +230,8 @@ int main(int argc, char const* const* argv) bool cpackConfigFileSpecified = true; if (cpackConfigFile.empty()) { - cpackConfigFile = cmSystemTools::GetCurrentWorkingDirectory(); - cpackConfigFile += "/CPackConfig.cmake"; + cpackConfigFile = cmStrCat(cmSystemTools::GetCurrentWorkingDirectory(), + "/CPackConfig.cmake"); cpackConfigFileSpecified = false; } @@ -332,8 +333,7 @@ int main(int argc, char const* const* argv) cmCPack_Log(&log, cmCPackLog::LOG_ERROR, "CPack generator not specified" << std::endl); } else { - std::vector<std::string> generatorsVector; - cmExpandList(genList, generatorsVector); + std::vector<std::string> generatorsVector = cmExpandedList(genList); for (std::string const& gen : generatorsVector) { cmMakefile::ScopePushPop raii(&globalMF); cmMakefile* mf = &globalMF; diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx index 3aea1f4..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" @@ -289,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 e71eafe..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,16 +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()); + 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()); + this->Makefile->AddDefinition( + this->Values[ctb_NUMBER_WARNINGS], + std::to_string(this->Handler->GetTotalWarnings())); } return ret; } diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx index 2365a66..147286e 100644 --- a/Source/CTest/cmCTestBuildHandler.cxx +++ b/Source/CTest/cmCTestBuildHandler.cxx @@ -10,6 +10,7 @@ #include "cmMakefile.h" #include "cmProcessOutput.h" #include "cmStringAlgorithms.h" +#include "cmStringReplaceHelper.h" #include "cmSystemTools.h" #include "cmXMLWriter.h" @@ -408,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()) { @@ -565,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); @@ -697,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); @@ -709,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); } } @@ -736,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"; @@ -749,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"; @@ -891,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; @@ -915,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; @@ -1077,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; @@ -1089,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); @@ -1103,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); @@ -1120,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); @@ -1136,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 eb7ecb5..320c184 100644 --- a/Source/CTest/cmCTestConfigureCommand.cxx +++ b/Source/CTest/cmCTestConfigureCommand.cxx @@ -76,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/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx index 2a68544..772fa47 100644 --- a/Source/CTest/cmCTestCoverageHandler.cxx +++ b/Source/CTest/cmCTestCoverageHandler.cxx @@ -130,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(); @@ -1456,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); @@ -1598,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()); } @@ -1632,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); @@ -1946,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"; @@ -2038,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 = @@ -2222,8 +2214,8 @@ int cmCTestCoverageHandler::GetLabelId(std::string const& label) void cmCTestCoverageHandler::LoadLabels() { - std::string fileList = this->CTest->GetBinaryDir(); - fileList += "/CMakeFiles/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/cmCTestGIT.cxx b/Source/CTest/cmCTestGIT.cxx index b832018..f7319ef 100644 --- a/Source/CTest/cmCTestGIT.cxx +++ b/Source/CTest/cmCTestGIT.cxx @@ -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; - cmExpandList(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) { diff --git a/Source/CTest/cmCTestHandlerCommand.cxx b/Source/CTest/cmCTestHandlerCommand.cxx index 8ceca08..6add717 100644 --- a/Source/CTest/cmCTestHandlerCommand.cxx +++ b/Source/CTest/cmCTestHandlerCommand.cxx @@ -228,9 +228,8 @@ 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()); + this->Makefile->AddDefinition(this->Values[ct_RETURN_VALUE], + std::to_string(res)); } this->ProcessAdditionalValues(handler); // log the error message if there was an error diff --git a/Source/CTest/cmCTestLaunch.cxx b/Source/CTest/cmCTestLaunch.cxx index 4708a71..ac52581 100644 --- a/Source/CTest/cmCTestLaunch.cxx +++ b/Source/CTest/cmCTestLaunch.cxx @@ -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,10 +276,8 @@ void cmCTestLaunch::LoadLabels() } // Labels are listed in per-target files. - std::string fname = this->OptionBuildDir; - fname += "/CMakeFiles/"; - 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; @@ -339,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); @@ -545,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; @@ -616,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 d7d42bf..804efa5 100644 --- a/Source/CTest/cmCTestMemCheckCommand.cxx +++ b/Source/CTest/cmCTestMemCheckCommand.cxx @@ -2,7 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCTestMemCheckCommand.h" -#include <sstream> +#include <string> #include <vector> #include "cmCTest.h" @@ -44,8 +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()); + this->Makefile->AddDefinition( + this->Values[ctm_DEFECT_COUNT], + std::to_string( + static_cast<cmCTestMemCheckHandler*>(handler)->GetDefectCount())); } } 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 ae965ea..af1980a 100644 --- a/Source/CTest/cmCTestMultiProcessHandler.cxx +++ b/Source/CTest/cmCTestMultiProcessHandler.cxx @@ -173,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); } } @@ -190,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; } @@ -275,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; } } @@ -621,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); @@ -662,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); } @@ -694,7 +694,7 @@ void cmCTestMultiProcessHandler::CreateSerialTestCostList() TestSet alreadySortedTests; for (int test : presortedList) { - if (alreadySortedTests.find(test) != alreadySortedTests.end()) { + if (cmContains(alreadySortedTests, test)) { continue; } @@ -702,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); } @@ -862,8 +861,8 @@ static Json::Value DumpCTestProperties( DumpCTestProperty("PROCESSORS", testProperties.Processors)); } if (!testProperties.RequiredFiles.empty()) { - properties["REQUIRED_FILES"] = - DumpToJsonArray(testProperties.RequiredFiles); + properties.append(DumpCTestProperty( + "REQUIRED_FILES", DumpToJsonArray(testProperties.RequiredFiles))); } if (!testProperties.LockedResources.empty()) { properties.append(DumpCTestProperty( diff --git a/Source/CTest/cmCTestP4.cxx b/Source/CTest/cmCTestP4.cxx index 80eb8d9..64354e8 100644 --- a/Source/CTest/cmCTestP4.cxx +++ b/Source/CTest/cmCTestP4.cxx @@ -460,8 +460,7 @@ bool cmCTestP4::LoadModifications() bool cmCTestP4::UpdateCustom(const std::string& custom) { - std::vector<std::string> p4_custom_command; - cmExpandList(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/cmCTestRunScriptCommand.cxx b/Source/CTest/cmCTestRunScriptCommand.cxx index c03cffd..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()); + this->Makefile->AddDefinition(returnVariable, std::to_string(ret)); } } return true; diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx index fb91322..23c6b0d 100644 --- a/Source/CTest/cmCTestRunTest.cxx +++ b/Source/CTest/cmCTestRunTest.cxx @@ -6,6 +6,7 @@ #include "cmCTestMemCheckHandler.h" #include "cmCTestMultiProcessHandler.h" #include "cmProcess.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmWorkingDirectory.h" @@ -86,16 +87,13 @@ 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 += " Regex=["; - reason += pass.second; - reason += "]"; + reason = cmStrCat("Required regular expression found. Regex=[", + pass.second, ']'); break; } } if (!found) { - reason = "Required regular expression not found."; - reason += " Regex=["; + reason = "Required regular expression not found. Regex=["; for (auto& pass : this->TestProperties->RequiredRegularExpressions) { reason += pass.second; reason += "\n"; @@ -108,10 +106,8 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started) this->FailedDependencies.empty()) { for (auto& fail : this->TestProperties->ErrorRegularExpressions) { if (fail.first.find(this->ProcessOutput)) { - reason = "Error regular expression found in output."; - reason += " Regex=["; - reason += fail.second; - reason += "]"; + reason = cmStrCat("Error regular expression found in output. Regex=[", + fail.second, ']'); forceFail = true; break; } @@ -121,10 +117,8 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started) this->FailedDependencies.empty()) { for (auto& skip : this->TestProperties->SkipRegularExpressions) { if (skip.first.find(this->ProcessOutput)) { - reason = "Skip regular expression found in output."; - reason += " Regex=["; - reason += skip.second; - reason += "]"; + reason = cmStrCat("Skip regular expression found in output. Regex=[", + skip.second, ']'); forceSkip = true; break; } @@ -148,8 +142,7 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started) 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 { @@ -504,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); 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 1c40a58..81966dd 100644 --- a/Source/CTest/cmCTestScriptHandler.cxx +++ b/Source/CTest/cmCTestScriptHandler.cxx @@ -451,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); @@ -543,8 +544,7 @@ int cmCTestScriptHandler::RunCurrentScript() // set any environment variables if (!this->CTestEnv.empty()) { - std::vector<std::string> envArgs; - cmExpandList(this->CTestEnv, envArgs); + std::vector<std::string> envArgs = cmExpandedList(this->CTestEnv); cmSystemTools::AppendEnv(envArgs); } @@ -610,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) { @@ -650,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; - cmExpandList(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, @@ -756,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; @@ -794,8 +787,7 @@ int cmCTestScriptHandler::RunConfigurationDashboard() } // run ctest, it may be more than one command in here - std::vector<std::string> ctestCommands; - cmExpandList(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; @@ -839,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; @@ -905,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; 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/cmCTestSubmitCommand.cxx b/Source/CTest/cmCTestSubmitCommand.cxx index ec1e9bb..d16aac0 100644 --- a/Source/CTest/cmCTestSubmitCommand.cxx +++ b/Source/CTest/cmCTestSubmitCommand.cxx @@ -68,16 +68,14 @@ cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler() const char* notesFilesVariable = this->Makefile->GetDefinition("CTEST_NOTES_FILES"); if (notesFilesVariable) { - std::vector<std::string> notesFiles; - cmExpandList(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; - cmExpandList(extraFilesVariable, extraFiles); + std::vector<std::string> extraFiles = cmExpandedList(extraFilesVariable); if (!this->CTest->SubmitExtraFiles(extraFiles)) { this->SetError("problem submitting extra files."); return nullptr; diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx index a30999b..a178b44 100644 --- a/Source/CTest/cmCTestSubmitHandler.cxx +++ b/Source/CTest/cmCTestSubmitHandler.cxx @@ -155,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; - cmExpandList(curlopt, args); + std::vector<std::string> args = cmExpandedList(curlopt); bool verifyPeerOff = false; bool verifyHostOff = false; for (std::string const& arg : args) { @@ -499,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; - cmExpandList(curlopt, args); + std::vector<std::string> args = cmExpandedList(curlopt); curl.SetCurlOptions(args); curl.SetTimeOutSeconds(SUBMIT_TIMEOUT_IN_SECONDS_DEFAULT); curl.SetHttpHeaders(this->HttpHeaders); @@ -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/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx index 797d47e..9181daa 100644 --- a/Source/CTest/cmCTestTestHandler.cxx +++ b/Source/CTest/cmCTestTestHandler.cxx @@ -20,6 +20,7 @@ #include "cm_memory.hxx" +#include "cmAlgorithms.h" #include "cmCTest.h" #include "cmCTestMultiProcessHandler.h" #include "cmCommand.h" @@ -76,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)) { @@ -109,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; } @@ -149,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... @@ -175,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; } @@ -699,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(); } @@ -715,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]; @@ -857,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; } @@ -896,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; } @@ -1019,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); } } @@ -1127,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); } } @@ -1141,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); } } @@ -1559,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"); } @@ -1656,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); @@ -2215,26 +2184,22 @@ bool cmCTestTestHandler::SetTestsProperties( cmExpandList(val, rt.AttachOnFail); } if (key == "RESOURCE_LOCK") { - std::vector<std::string> lval; - cmExpandList(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; - cmExpandList(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; - cmExpandList(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; - cmExpandList(val, lval); + std::vector<std::string> lval = cmExpandedList(val); rt.FixturesRequired.insert(lval.begin(), lval.end()); } @@ -2252,15 +2217,13 @@ bool cmCTestTestHandler::SetTestsProperties( rt.RunSerial = cmIsOn(val); } if (key == "FAIL_REGULAR_EXPRESSION") { - std::vector<std::string> lval; - cmExpandList(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; - cmExpandList(val, lval); + std::vector<std::string> lval = cmExpandedList(val); for (std::string const& cr : lval) { rt.SkipRegularExpressions.emplace_back(cr, cr); } @@ -2287,8 +2250,7 @@ bool cmCTestTestHandler::SetTestsProperties( cmExpandList(val, rt.Environment); } if (key == "LABELS") { - std::vector<std::string> Labels; - cmExpandList(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()); @@ -2308,8 +2270,7 @@ bool cmCTestTestHandler::SetTestsProperties( } } if (key == "PASS_REGULAR_EXPRESSION") { - std::vector<std::string> lval; - cmExpandList(val, lval); + std::vector<std::string> lval = cmExpandedList(val); for (std::string const& cr : lval) { rt.RequiredRegularExpressions.emplace_back(cr, cr); } @@ -2318,16 +2279,14 @@ bool cmCTestTestHandler::SetTestsProperties( rt.Directory = val; } if (key == "TIMEOUT_AFTER_MATCH") { - std::vector<std::string> propArgs; - cmExpandList(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; - cmExpandList(propArgs[1], lval); + std::vector<std::string> lval = cmExpandedList(propArgs[1]); for (std::string const& cr : lval) { rt.TimeoutRegularExpressions.emplace_back(cr, cr); } @@ -2369,8 +2328,7 @@ bool cmCTestTestHandler::SetDirectoryProperties( std::string cwd = cmSystemTools::GetCurrentWorkingDirectory(); if (cwd == rt.Directory) { if (key == "LABELS") { - std::vector<std::string> DirectoryLabels; - cmExpandList(val, DirectoryLabels); + std::vector<std::string> DirectoryLabels = cmExpandedList(val); rt.Labels.insert(rt.Labels.end(), DirectoryLabels.begin(), DirectoryLabels.end()); diff --git a/Source/CTest/cmCTestUpdateHandler.cxx b/Source/CTest/cmCTestUpdateHandler.cxx index d80b5a5..a6a3542 100644 --- a/Source/CTest/cmCTestUpdateHandler.cxx +++ b/Source/CTest/cmCTestUpdateHandler.cxx @@ -12,6 +12,7 @@ #include "cmCTestSVN.h" #include "cmCTestVC.h" #include "cmGeneratedFileStream.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmVersion.h" #include "cmXMLWriter.h" @@ -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/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/cmParseGTMCoverage.cxx b/Source/CTest/cmParseGTMCoverage.cxx index 881bf2d..621ca79 100644 --- a/Source/CTest/cmParseGTMCoverage.cxx +++ b/Source/CTest/cmParseGTMCoverage.cxx @@ -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 5f1e712..374acad 100644 --- a/Source/CTest/cmParseJacocoCoverage.cxx +++ b/Source/CTest/cmParseJacocoCoverage.cxx @@ -104,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(); 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; diff --git a/Source/Checks/cm_cxx17_check.cpp b/Source/Checks/cm_cxx17_check.cpp index 593d9b2..29863b1 100644 --- a/Source/Checks/cm_cxx17_check.cpp +++ b/Source/Checks/cm_cxx17_check.cpp @@ -1,6 +1,7 @@ #include <cstdio> #include <iterator> #include <memory> +#include <optional> #include <unordered_map> #ifdef _MSC_VER @@ -27,5 +28,7 @@ int main() IDispatchPtr disp(ptr); #endif - return *u + *ai + *(bi - 1) + (3 - static_cast<int>(ci)); + std::optional<int> oi = 0; + + return *u + *ai + *(bi - 1) + (3 - static_cast<int>(ci)) + oi.value(); } diff --git a/Source/CursesDialog/CMakeLists.txt b/Source/CursesDialog/CMakeLists.txt index c51b0dd..270b07e 100644 --- a/Source/CursesDialog/CMakeLists.txt +++ b/Source/CursesDialog/CMakeLists.txt @@ -23,6 +23,10 @@ include_directories(${CURSES_INCLUDE_PATH}) add_executable(ccmake ${CURSES_SRCS} ) target_link_libraries(ccmake CMakeLib) if(CMAKE_USE_SYSTEM_FORM) + find_path(CURSES_FORM_INCLUDE_DIR NAMES form.h HINTS ${CURSES_INCLUDE_PATH} ${CURSES_INCLUDE_PATH}/ncurses) + if(CURSES_FORM_INCLUDE_DIR) + target_include_directories(ccmake PRIVATE ${CURSES_FORM_INCLUDE_DIR}) + endif() target_link_libraries(ccmake ${CURSES_FORM_LIBRARY} ${CURSES_LIBRARY} diff --git a/Source/CursesDialog/ccmake.cxx b/Source/CursesDialog/ccmake.cxx index 7caed0c..ce32898 100644 --- a/Source/CursesDialog/ccmake.cxx +++ b/Source/CursesDialog/ccmake.cxx @@ -56,7 +56,8 @@ void onsig(int /*unused*/) cbreak(); /* nl- or cr not needed */ keypad(stdscr, true); /* Use key symbols as KEY_DOWN */ refresh(); - int x, y; + int x; + int y; getmaxyx(stdscr, y, x); cmCursesForm::CurrentForm->Render(1, 1, x, y); cmCursesForm::CurrentForm->UpdateStatusBar(); @@ -127,7 +128,8 @@ int main(int argc, char const* const* argv) signal(SIGWINCH, onsig); - int x, y; + int x; + int y; getmaxyx(stdscr, y, x); if (x < cmCursesMainForm::MIN_WIDTH || y < cmCursesMainForm::MIN_HEIGHT) { endwin(); diff --git a/Source/CursesDialog/cmCursesCacheEntryComposite.cxx b/Source/CursesDialog/cmCursesCacheEntryComposite.cxx index f7e3920..f450a1c 100644 --- a/Source/CursesDialog/cmCursesCacheEntryComposite.cxx +++ b/Source/CursesDialog/cmCursesCacheEntryComposite.cxx @@ -71,8 +71,7 @@ cmCursesCacheEntryComposite::cmCursesCacheEntryComposite( cmCursesOptionsWidget* ow = new cmCursesOptionsWidget(this->EntryWidth, 1, 1, 1); this->Entry = ow; - std::vector<std::string> options; - cmExpandList(stringsProp, options); + std::vector<std::string> options = cmExpandedList(stringsProp); for (auto const& opt : options) { ow->AddOption(opt); } diff --git a/Source/CursesDialog/cmCursesLongMessageForm.cxx b/Source/CursesDialog/cmCursesLongMessageForm.cxx index 4e887d6..95026d5 100644 --- a/Source/CursesDialog/cmCursesLongMessageForm.cxx +++ b/Source/CursesDialog/cmCursesLongMessageForm.cxx @@ -38,7 +38,8 @@ cmCursesLongMessageForm::~cmCursesLongMessageForm() void cmCursesLongMessageForm::UpdateStatusBar() { - int x, y; + int x; + int y; getmaxyx(stdscr, y, x); char bar[cmCursesMainForm::MAX_WIDTH]; @@ -81,7 +82,8 @@ void cmCursesLongMessageForm::UpdateStatusBar() void cmCursesLongMessageForm::PrintKeys() { - int x, y; + int x; + int y; getmaxyx(stdscr, y, x); if (x < cmCursesMainForm::MIN_WIDTH || y < cmCursesMainForm::MIN_HEIGHT) { return; @@ -98,7 +100,8 @@ void cmCursesLongMessageForm::PrintKeys() void cmCursesLongMessageForm::Render(int /*left*/, int /*top*/, int /*width*/, int /*height*/) { - int x, y; + int x; + int y; getmaxyx(stdscr, y, x); if (this->Form) { diff --git a/Source/CursesDialog/cmCursesMainForm.cxx b/Source/CursesDialog/cmCursesMainForm.cxx index 9ac80b8..1b25716 100644 --- a/Source/CursesDialog/cmCursesMainForm.cxx +++ b/Source/CursesDialog/cmCursesMainForm.cxx @@ -48,8 +48,8 @@ cmCursesMainForm::cmCursesMainForm(std::vector<std::string> args, cmSystemTools::GetCMakeCursesCommand()); // create the arguments for the cmake object - std::string whereCMake = cmSystemTools::GetProgramPath(this->Args[0]); - whereCMake += "/cmake"; + std::string whereCMake = + cmStrCat(cmSystemTools::GetProgramPath(this->Args[0]), "/cmake"); this->Args[0] = whereCMake; this->CMakeInstance->SetArgs(this->Args); this->SearchString = ""; @@ -320,7 +320,8 @@ void cmCursesMainForm::Render(int left, int top, int width, int height) void cmCursesMainForm::PrintKeys(int process /* = 0 */) { - int x, y; + int x; + int y; getmaxyx(stdscr, y, x); if (x < cmCursesMainForm::MIN_WIDTH || x < this->InitialWidth || y < cmCursesMainForm::MIN_HEIGHT) { @@ -391,7 +392,8 @@ void cmCursesMainForm::PrintKeys(int process /* = 0 */) // on the status bar. Designed for a width of 80 chars. void cmCursesMainForm::UpdateStatusBar(const char* message) { - int x, y; + int x; + int y; getmaxyx(stdscr, y, x); // If window size is too small, display error and return if (x < cmCursesMainForm::MIN_WIDTH || x < this->InitialWidth || @@ -509,7 +511,8 @@ void cmCursesMainForm::UpdateProgress(const std::string& msg, float prog) int cmCursesMainForm::Configure(int noconfigure) { - int xi, yi; + int xi; + int yi; getmaxyx(stdscr, yi, xi); curses_move(1, 1); @@ -552,7 +555,8 @@ int cmCursesMainForm::Configure(int noconfigure) if (cmSystemTools::GetErrorOccuredFlag()) { this->OkToGenerate = false; } - int xx, yy; + int xx; + int yy; getmaxyx(stdscr, yy, xx); cmCursesLongMessageForm* msgs = new cmCursesLongMessageForm(this->Errors, @@ -581,7 +585,8 @@ int cmCursesMainForm::Configure(int noconfigure) int cmCursesMainForm::Generate() { - int xi, yi; + int xi; + int yi; getmaxyx(stdscr, yi, xi); curses_move(1, 1); @@ -610,7 +615,8 @@ int cmCursesMainForm::Generate() } // reset error condition cmSystemTools::ResetErrorOccuredFlag(); - int xx, yy; + int xx; + int yy; getmaxyx(stdscr, yy, xx); const char* title = "Messages during last pass."; if (cmSystemTools::GetErrorOccuredFlag()) { @@ -707,7 +713,8 @@ void cmCursesMainForm::FixValue(cmStateEnums::CacheEntryType type, void cmCursesMainForm::HandleInput() { - int x = 0, y = 0; + int x = 0; + int y = 0; if (!this->Form) { return; diff --git a/Source/CursesDialog/cmCursesOptionsWidget.cxx b/Source/CursesDialog/cmCursesOptionsWidget.cxx index a8c4933..eb773ad 100644 --- a/Source/CursesDialog/cmCursesOptionsWidget.cxx +++ b/Source/CursesDialog/cmCursesOptionsWidget.cxx @@ -23,6 +23,9 @@ cmCursesOptionsWidget::cmCursesOptionsWidget(int width, int height, int left, bool cmCursesOptionsWidget::HandleInput(int& key, cmCursesMainForm* /*fm*/, WINDOW* w) { + if (this->Options.empty()) { + return false; + } switch (key) { case 10: // 10 == enter case KEY_ENTER: diff --git a/Source/CursesDialog/cmCursesStringWidget.cxx b/Source/CursesDialog/cmCursesStringWidget.cxx index 5e2a329..26724e7 100644 --- a/Source/CursesDialog/cmCursesStringWidget.cxx +++ b/Source/CursesDialog/cmCursesStringWidget.cxx @@ -64,7 +64,8 @@ void cmCursesStringWidget::OnType(int& key, cmCursesMainForm* fm, bool cmCursesStringWidget::HandleInput(int& key, cmCursesMainForm* fm, WINDOW* w) { - int x, y; + int x; + int y; FORM* form = fm->GetForm(); // when not in edit mode, edit mode is entered by pressing enter or i (vim @@ -179,7 +180,8 @@ const char* cmCursesStringWidget::GetValue() bool cmCursesStringWidget::PrintKeys() { - int x, y; + int x; + int y; getmaxyx(stdscr, y, x); if (x < cmCursesMainForm::MIN_WIDTH || y < cmCursesMainForm::MIN_HEIGHT) { return false; diff --git a/Source/QtDialog/FirstConfigure.cxx b/Source/QtDialog/FirstConfigure.cxx index 364a378..d9a8aff 100644 --- a/Source/QtDialog/FirstConfigure.cxx +++ b/Source/QtDialog/FirstConfigure.cxx @@ -2,6 +2,7 @@ #include "FirstConfigure.h" #include "Compilers.h" +#include "cmStringAlgorithms.h" #include <QComboBox> #include <QRadioButton> @@ -183,10 +184,9 @@ void StartCompilerSetup::onGeneratorChanged(QString const& name) if (GeneratorsSupportingPlatform.contains(name)) { // Change the label title to include the default platform - std::string label = "Optional platform for generator"; - label += "(if empty, generator uses: "; - label += this->GeneratorDefaultPlatform[name].toStdString(); - label += ")"; + std::string label = + cmStrCat("Optional platform for generator(if empty, generator uses: ", + this->GeneratorDefaultPlatform[name].toStdString(), ')'); this->PlatformLabel->setText(tr(label.c_str())); // Regenerate the list of supported platform diff --git a/Source/QtDialog/QCMakeCacheView.cxx b/Source/QtDialog/QCMakeCacheView.cxx index 78a2710..5e8636a 100644 --- a/Source/QtDialog/QCMakeCacheView.cxx +++ b/Source/QtDialog/QCMakeCacheView.cxx @@ -210,7 +210,8 @@ void QCMakeCacheModel::clear() void QCMakeCacheModel::setProperties(const QCMakePropertyList& props) { - QSet<QCMakeProperty> newProps, newProps2; + QSet<QCMakeProperty> newProps; + QSet<QCMakeProperty> newProps2; if (this->ShowNewProperties) { newProps = props.toSet(); diff --git a/Source/cmAddCustomCommandCommand.cxx b/Source/cmAddCustomCommandCommand.cxx index e502a64..d2330e1 100644 --- a/Source/cmAddCustomCommandCommand.cxx +++ b/Source/cmAddCustomCommandCommand.cxx @@ -14,6 +14,7 @@ #include "cmMessageType.h" #include "cmPolicies.h" #include "cmSourceFile.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" @@ -33,10 +34,18 @@ bool cmAddCustomCommandCommand(std::vector<std::string> const& args, } cmMakefile& mf = status.GetMakefile(); - std::string source, target, main_dependency, working, depfile, job_pool; + std::string source; + std::string target; + std::string main_dependency; + std::string working; + std::string depfile; + std::string job_pool; std::string comment_buffer; const char* comment = nullptr; - std::vector<std::string> depends, outputs, output, byproducts; + std::vector<std::string> depends; + std::vector<std::string> outputs; + std::vector<std::string> output; + std::vector<std::string> byproducts; bool verbatim = false; bool append = false; bool uses_terminal = false; @@ -194,8 +203,7 @@ bool cmAddCustomCommandCommand(std::vector<std::string> const& args, // and later references "${CMAKE_CURRENT_SOURCE_DIR}/out.txt". // This is fairly obscure so we can wait for someone to // complain. - filename = mf.GetCurrentBinaryDirectory(); - filename += "/"; + filename = cmStrCat(mf.GetCurrentBinaryDirectory(), '/'); } filename += copy; cmSystemTools::ConvertToUnixSlashes(filename); diff --git a/Source/cmAddCustomTargetCommand.cxx b/Source/cmAddCustomTargetCommand.cxx index f812ab5..caea510 100644 --- a/Source/cmAddCustomTargetCommand.cxx +++ b/Source/cmAddCustomTargetCommand.cxx @@ -12,6 +12,7 @@ #include "cmMakefile.h" #include "cmMessageType.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" @@ -43,7 +44,8 @@ bool cmAddCustomTargetCommand(std::vector<std::string> const& args, cmCustomCommandLines commandLines; // Accumulate dependencies. - std::vector<std::string> depends, byproducts; + std::vector<std::string> depends; + std::vector<std::string> byproducts; std::string working_directory; bool verbatim = false; bool uses_terminal = false; @@ -121,8 +123,7 @@ bool cmAddCustomTargetCommand(std::vector<std::string> const& args, case doing_byproducts: { std::string filename; if (!cmSystemTools::FileIsFullPath(copy)) { - filename = mf.GetCurrentBinaryDirectory(); - filename += "/"; + filename = cmStrCat(mf.GetCurrentBinaryDirectory(), '/'); } filename += copy; cmSystemTools::ConvertToUnixSlashes(filename); diff --git a/Source/cmAddExecutableCommand.cxx b/Source/cmAddExecutableCommand.cxx index 59d6be3..f1264d5 100644 --- a/Source/cmAddExecutableCommand.cxx +++ b/Source/cmAddExecutableCommand.cxx @@ -93,9 +93,7 @@ bool cmAddExecutableCommand(std::vector<std::string> const& args, return false; } if (args.size() != 3) { - std::ostringstream e; - e << "ALIAS requires exactly one target argument."; - status.SetError(e.str()); + status.SetError("ALIAS requires exactly one target argument."); return false; } diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx index 46fc61d..c067aea 100644 --- a/Source/cmAddLibraryCommand.cxx +++ b/Source/cmAddLibraryCommand.cxx @@ -49,9 +49,8 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args, std::string libType = *s; if (libType == "STATIC") { if (type == cmStateEnums::INTERFACE_LIBRARY) { - std::ostringstream e; - e << "INTERFACE library specified with conflicting STATIC type."; - status.SetError(e.str()); + status.SetError( + "INTERFACE library specified with conflicting STATIC type."); return false; } ++s; @@ -59,9 +58,8 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args, haveSpecifiedType = true; } else if (libType == "SHARED") { if (type == cmStateEnums::INTERFACE_LIBRARY) { - std::ostringstream e; - e << "INTERFACE library specified with conflicting SHARED type."; - status.SetError(e.str()); + status.SetError( + "INTERFACE library specified with conflicting SHARED type."); return false; } ++s; @@ -69,9 +67,8 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args, haveSpecifiedType = true; } else if (libType == "MODULE") { if (type == cmStateEnums::INTERFACE_LIBRARY) { - std::ostringstream e; - e << "INTERFACE library specified with conflicting MODULE type."; - status.SetError(e.str()); + status.SetError( + "INTERFACE library specified with conflicting MODULE type."); return false; } ++s; @@ -79,9 +76,8 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args, haveSpecifiedType = true; } else if (libType == "OBJECT") { if (type == cmStateEnums::INTERFACE_LIBRARY) { - std::ostringstream e; - e << "INTERFACE library specified with conflicting OBJECT type."; - status.SetError(e.str()); + status.SetError( + "INTERFACE library specified with conflicting OBJECT type."); return false; } ++s; @@ -89,9 +85,8 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args, haveSpecifiedType = true; } else if (libType == "UNKNOWN") { if (type == cmStateEnums::INTERFACE_LIBRARY) { - std::ostringstream e; - e << "INTERFACE library specified with conflicting UNKNOWN type."; - status.SetError(e.str()); + status.SetError( + "INTERFACE library specified with conflicting UNKNOWN type."); return false; } ++s; @@ -99,30 +94,26 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args, haveSpecifiedType = true; } else if (libType == "ALIAS") { if (type == cmStateEnums::INTERFACE_LIBRARY) { - std::ostringstream e; - e << "INTERFACE library specified with conflicting ALIAS type."; - status.SetError(e.str()); + status.SetError( + "INTERFACE library specified with conflicting ALIAS type."); return false; } ++s; isAlias = true; } else if (libType == "INTERFACE") { if (haveSpecifiedType) { - std::ostringstream e; - e << "INTERFACE library specified with conflicting/multiple types."; - status.SetError(e.str()); + status.SetError( + "INTERFACE library specified with conflicting/multiple types."); return false; } if (isAlias) { - std::ostringstream e; - e << "INTERFACE library specified with conflicting ALIAS type."; - status.SetError(e.str()); + status.SetError( + "INTERFACE library specified with conflicting ALIAS type."); return false; } if (excludeFromAll) { - std::ostringstream e; - e << "INTERFACE library may not be used with EXCLUDE_FROM_ALL."; - status.SetError(e.str()); + status.SetError( + "INTERFACE library may not be used with EXCLUDE_FROM_ALL."); return false; } ++s; @@ -130,9 +121,8 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args, haveSpecifiedType = true; } else if (*s == "EXCLUDE_FROM_ALL") { if (type == cmStateEnums::INTERFACE_LIBRARY) { - std::ostringstream e; - e << "INTERFACE library may not be used with EXCLUDE_FROM_ALL."; - status.SetError(e.str()); + status.SetError( + "INTERFACE library may not be used with EXCLUDE_FROM_ALL."); return false; } ++s; @@ -144,9 +134,8 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args, ++s; importGlobal = true; } else if (type == cmStateEnums::INTERFACE_LIBRARY && *s == "GLOBAL") { - std::ostringstream e; - e << "GLOBAL option may only be used with IMPORTED libraries."; - status.SetError(e.str()); + status.SetError( + "GLOBAL option may only be used with IMPORTED libraries."); return false; } else { break; @@ -155,15 +144,12 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args, if (type == cmStateEnums::INTERFACE_LIBRARY) { if (s != args.end()) { - std::ostringstream e; - e << "INTERFACE library requires no source arguments."; - status.SetError(e.str()); + status.SetError("INTERFACE library requires no source arguments."); return false; } if (importGlobal && !importTarget) { - std::ostringstream e; - e << "INTERFACE library specified as GLOBAL, but not as IMPORTED."; - status.SetError(e.str()); + status.SetError( + "INTERFACE library specified as GLOBAL, but not as IMPORTED."); return false; } } @@ -192,9 +178,7 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args, return false; } if (args.size() != 3) { - std::ostringstream e; - e << "ALIAS requires exactly one target argument."; - status.SetError(e.str()); + status.SetError("ALIAS requires exactly one target argument."); return false; } diff --git a/Source/cmAddSubDirectoryCommand.cxx b/Source/cmAddSubDirectoryCommand.cxx index 50c682f..17bdc4a 100644 --- a/Source/cmAddSubDirectoryCommand.cxx +++ b/Source/cmAddSubDirectoryCommand.cxx @@ -8,6 +8,7 @@ #include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmRange.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" bool cmAddSubDirectoryCommand(std::vector<std::string> const& args, @@ -45,14 +46,11 @@ bool cmAddSubDirectoryCommand(std::vector<std::string> const& args, if (cmSystemTools::FileIsFullPath(srcArg)) { srcPath = srcArg; } else { - srcPath = mf.GetCurrentSourceDirectory(); - srcPath += "/"; - srcPath += srcArg; + srcPath = cmStrCat(mf.GetCurrentSourceDirectory(), '/', srcArg); } if (!cmSystemTools::FileIsDirectory(srcPath)) { - std::string error = "given source \""; - error += srcArg; - error += "\" which is not an existing directory."; + std::string error = cmStrCat("given source \"", srcArg, + "\" which is not an existing directory."); status.SetError(error); return false; } @@ -95,9 +93,7 @@ bool cmAddSubDirectoryCommand(std::vector<std::string> const& args, if (cmSystemTools::FileIsFullPath(binArg)) { binPath = binArg; } else { - binPath = mf.GetCurrentBinaryDirectory(); - binPath += "/"; - binPath += binArg; + binPath = cmStrCat(mf.GetCurrentBinaryDirectory(), '/', binArg); } } binPath = cmSystemTools::CollapseFullPath(binPath); diff --git a/Source/cmAffinity.cxx b/Source/cmAffinity.cxx index 588b2f2..09b0298 100644 --- a/Source/cmAffinity.cxx +++ b/Source/cmAffinity.cxx @@ -12,6 +12,8 @@ # define CM_HAVE_CPU_AFFINITY # include <pthread.h> # include <sched.h> +// On some platforms CPU_ZERO needs memset but sched.h forgets string.h +# include <string.h> // IWYU pragma: keep # if defined(__FreeBSD__) # include <pthread_np.h> # include <sys/cpuset.h> diff --git a/Source/cmAlgorithms.h b/Source/cmAlgorithms.h index d7ea483..59aa86f 100644 --- a/Source/cmAlgorithms.h +++ b/Source/cmAlgorithms.h @@ -14,6 +14,16 @@ #include <utility> #include <vector> +template <std::size_t N> +struct cmOverloadPriority : cmOverloadPriority<N - 1> +{ +}; + +template <> +struct cmOverloadPriority<0> +{ +}; + template <typename FwdIt> FwdIt cmRotate(FwdIt first, FwdIt middle, FwdIt last) { @@ -30,6 +40,34 @@ void cmEraseIf(Container& cont, Predicate pred) cont.erase(std::remove_if(cont.begin(), cont.end(), pred), cont.end()); } +template <typename Range, typename Key> +auto cmContainsImpl(Range const& range, Key const& key, cmOverloadPriority<2>) + -> decltype(range.exists(key)) +{ + return range.exists(key); +} + +template <typename Range, typename Key> +auto cmContainsImpl(Range const& range, Key const& key, cmOverloadPriority<1>) + -> decltype(range.find(key) != range.end()) +{ + return range.find(key) != range.end(); +} + +template <typename Range, typename Key> +bool cmContainsImpl(Range const& range, Key const& key, cmOverloadPriority<0>) +{ + using std::begin; + using std::end; + return std::find(begin(range), end(range), key) != end(range); +} + +template <typename Range, typename Key> +bool cmContains(Range const& range, Key const& key) +{ + return cmContainsImpl(range, key, cmOverloadPriority<2>{}); +} + namespace ContainerAlgorithms { template <typename T> @@ -176,7 +214,7 @@ ForwardIterator cmRemoveDuplicates(ForwardIterator first, ForwardIterator last) ForwardIterator result = first; while (first != last) { - if (uniq.find(first) == uniq.end()) { + if (!cmContains(uniq, first)) { if (result != first) { *result = std::move(*first); } diff --git a/Source/cmArchiveWrite.cxx b/Source/cmArchiveWrite.cxx index 359d57a..a063fd9 100644 --- a/Source/cmArchiveWrite.cxx +++ b/Source/cmArchiveWrite.cxx @@ -3,12 +3,14 @@ #include "cmArchiveWrite.h" #include "cmLocale.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cm_get_date.h" #include "cm_libarchive.h" #include "cmsys/Directory.hxx" #include "cmsys/Encoding.hxx" #include "cmsys/FStream.hxx" + #include <iostream> #include <sstream> #include <string.h> @@ -85,22 +87,22 @@ cmArchiveWrite::cmArchiveWrite(std::ostream& os, Compress c, switch (c) { case CompressNone: if (archive_write_add_filter_none(this->Archive) != ARCHIVE_OK) { - this->Error = "archive_write_add_filter_none: "; - this->Error += cm_archive_error_string(this->Archive); + this->Error = cmStrCat("archive_write_add_filter_none: ", + cm_archive_error_string(this->Archive)); return; } break; case CompressCompress: if (archive_write_add_filter_compress(this->Archive) != ARCHIVE_OK) { - this->Error = "archive_write_add_filter_compress: "; - this->Error += cm_archive_error_string(this->Archive); + this->Error = cmStrCat("archive_write_add_filter_compress: ", + cm_archive_error_string(this->Archive)); return; } break; case CompressGZip: { if (archive_write_add_filter_gzip(this->Archive) != ARCHIVE_OK) { - this->Error = "archive_write_add_filter_gzip: "; - this->Error += cm_archive_error_string(this->Archive); + this->Error = cmStrCat("archive_write_add_filter_gzip: ", + cm_archive_error_string(this->Archive)); return; } std::string source_date_epoch; @@ -110,60 +112,60 @@ cmArchiveWrite::cmArchiveWrite(std::ostream& os, Compress c, // The next best thing is to omit the timestamp entirely. if (archive_write_set_filter_option(this->Archive, "gzip", "timestamp", nullptr) != ARCHIVE_OK) { - this->Error = "archive_write_set_filter_option: "; - this->Error += cm_archive_error_string(this->Archive); + this->Error = cmStrCat("archive_write_set_filter_option: ", + cm_archive_error_string(this->Archive)); return; } } } break; case CompressBZip2: if (archive_write_add_filter_bzip2(this->Archive) != ARCHIVE_OK) { - this->Error = "archive_write_add_filter_bzip2: "; - this->Error += cm_archive_error_string(this->Archive); + this->Error = cmStrCat("archive_write_add_filter_bzip2: ", + cm_archive_error_string(this->Archive)); return; } break; case CompressLZMA: if (archive_write_add_filter_lzma(this->Archive) != ARCHIVE_OK) { - this->Error = "archive_write_add_filter_lzma: "; - this->Error += cm_archive_error_string(this->Archive); + this->Error = cmStrCat("archive_write_add_filter_lzma: ", + cm_archive_error_string(this->Archive)); return; } break; case CompressXZ: if (archive_write_add_filter_xz(this->Archive) != ARCHIVE_OK) { - this->Error = "archive_write_add_filter_xz: "; - this->Error += cm_archive_error_string(this->Archive); + this->Error = cmStrCat("archive_write_add_filter_xz: ", + cm_archive_error_string(this->Archive)); return; } break; case CompressZstd: if (archive_write_add_filter_zstd(this->Archive) != ARCHIVE_OK) { - this->Error = "archive_write_add_filter_zstd: "; - this->Error += cm_archive_error_string(this->Archive); + this->Error = cmStrCat("archive_write_add_filter_zstd: ", + cm_archive_error_string(this->Archive)); return; } break; } #if !defined(_WIN32) || defined(__CYGWIN__) if (archive_read_disk_set_standard_lookup(this->Disk) != ARCHIVE_OK) { - this->Error = "archive_read_disk_set_standard_lookup: "; - this->Error += cm_archive_error_string(this->Archive); + this->Error = cmStrCat("archive_read_disk_set_standard_lookup: ", + cm_archive_error_string(this->Archive)); return; } #endif if (archive_write_set_format_by_name(this->Archive, format.c_str()) != ARCHIVE_OK) { - this->Error = "archive_write_set_format_by_name: "; - this->Error += cm_archive_error_string(this->Archive); + this->Error = cmStrCat("archive_write_set_format_by_name: ", + cm_archive_error_string(this->Archive)); return; } // do not pad the last block!! if (archive_write_set_bytes_in_last_block(this->Archive, 1)) { - this->Error = "archive_write_set_bytes_in_last_block: "; - this->Error += cm_archive_error_string(this->Archive); + this->Error = cmStrCat("archive_write_set_bytes_in_last_block: ", + cm_archive_error_string(this->Archive)); return; } @@ -171,8 +173,8 @@ cmArchiveWrite::cmArchiveWrite(std::ostream& os, Compress c, this->Archive, this, nullptr, reinterpret_cast<archive_write_callback*>(&Callback::Write), nullptr) != ARCHIVE_OK) { - this->Error = "archive_write_open: "; - this->Error += cm_archive_error_string(this->Archive); + this->Error = + cmStrCat("archive_write_open: ", cm_archive_error_string(this->Archive)); return; } } @@ -205,8 +207,7 @@ bool cmArchiveWrite::AddPath(const char* path, size_t skip, const char* prefix, } cmsys::Directory d; if (d.Load(path)) { - std::string next = path; - next += "/"; + std::string next = cmStrCat(path, '/'); std::string::size_type end = next.size(); unsigned long n = d.GetNumberOfFiles(); for (unsigned long i = 0; i < n; ++i) { @@ -237,8 +238,7 @@ bool cmArchiveWrite::AddFile(const char* file, size_t skip, const char* prefix) static_cast<void>(localeRAII); // Meta-data. - std::string dest = prefix ? prefix : ""; - dest += out; + std::string dest = cmStrCat(prefix ? prefix : "", out); if (this->Verbose) { std::cout << dest << "\n"; } @@ -247,10 +247,8 @@ bool cmArchiveWrite::AddFile(const char* file, size_t skip, const char* prefix) cm_archive_entry_copy_pathname(e, dest); if (archive_read_disk_entry_from_file(this->Disk, e, -1, nullptr) != ARCHIVE_OK) { - this->Error = "Unable to read from file '"; - this->Error += file; - this->Error += "': "; - this->Error += cm_archive_error_string(this->Disk); + this->Error = cmStrCat("Unable to read from file '", file, + "': ", cm_archive_error_string(this->Disk)); return false; } if (!this->MTime.empty()) { @@ -258,9 +256,7 @@ bool cmArchiveWrite::AddFile(const char* file, size_t skip, const char* prefix) time(&now); time_t t = cm_get_date(now, this->MTime.c_str()); if (t == -1) { - this->Error = "unable to parse mtime '"; - this->Error += this->MTime; - this->Error += "'"; + this->Error = cmStrCat("unable to parse mtime '", this->MTime, '\''); return false; } archive_entry_set_mtime(e, t, 0); @@ -310,8 +306,8 @@ bool cmArchiveWrite::AddFile(const char* file, size_t skip, const char* prefix) } if (archive_write_header(this->Archive, e) != ARCHIVE_OK) { - this->Error = "archive_write_header: "; - this->Error += cm_archive_error_string(this->Archive); + this->Error = cmStrCat("archive_write_header: ", + cm_archive_error_string(this->Archive)); return false; } @@ -329,10 +325,8 @@ bool cmArchiveWrite::AddData(const char* file, size_t size) { cmsys::ifstream fin(file, std::ios::in | std::ios::binary); if (!fin) { - this->Error = "Error opening \""; - this->Error += file; - this->Error += "\": "; - this->Error += cmSystemTools::GetLastSystemError(); + this->Error = cmStrCat("Error opening \"", file, + "\": ", cmSystemTools::GetLastSystemError()); return false; } @@ -350,17 +344,15 @@ bool cmArchiveWrite::AddData(const char* file, size_t size) break; } if (archive_write_data(this->Archive, buffer, nnext) != nnext_s) { - this->Error = "archive_write_data: "; - this->Error += cm_archive_error_string(this->Archive); + this->Error = cmStrCat("archive_write_data: ", + cm_archive_error_string(this->Archive)); return false; } nleft -= nnext; } if (nleft > 0) { - this->Error = "Error reading \""; - this->Error += file; - this->Error += "\": "; - this->Error += cmSystemTools::GetLastSystemError(); + this->Error = cmStrCat("Error reading \"", file, + "\": ", cmSystemTools::GetLastSystemError()); return false; } return true; diff --git a/Source/cmAuxSourceDirectoryCommand.cxx b/Source/cmAuxSourceDirectoryCommand.cxx index 83199b4..7bf19d0 100644 --- a/Source/cmAuxSourceDirectoryCommand.cxx +++ b/Source/cmAuxSourceDirectoryCommand.cxx @@ -27,9 +27,7 @@ bool cmAuxSourceDirectoryCommand(std::vector<std::string> const& args, std::string const& templateDirectory = args[0]; std::string tdir; if (!cmSystemTools::FileIsFullPath(templateDirectory)) { - tdir = mf.GetCurrentSourceDirectory(); - tdir += "/"; - tdir += templateDirectory; + tdir = cmStrCat(mf.GetCurrentSourceDirectory(), '/', templateDirectory); } else { tdir = templateDirectory; } @@ -56,9 +54,7 @@ bool cmAuxSourceDirectoryCommand(std::vector<std::string> const& args, // Process only source files auto cm = mf.GetCMakeInstance(); if (!base.empty() && cm->IsSourceExtension(ext)) { - std::string fullname = templateDirectory; - fullname += "/"; - fullname += file; + std::string fullname = cmStrCat(templateDirectory, '/', file); // add the file as a class file so // depends can be done cmSourceFile* sf = mf.GetOrCreateSource(fullname); diff --git a/Source/cmBinUtilsMacOSMachOLinker.cxx b/Source/cmBinUtilsMacOSMachOLinker.cxx index 0c73ac8..7ff8584 100644 --- a/Source/cmBinUtilsMacOSMachOLinker.cxx +++ b/Source/cmBinUtilsMacOSMachOLinker.cxx @@ -59,7 +59,8 @@ bool cmBinUtilsMacOSMachOLinker::ScanDependencies( bool cmBinUtilsMacOSMachOLinker::ScanDependencies( std::string const& file, std::string const& executablePath) { - std::vector<std::string> libs, rpaths; + std::vector<std::string> libs; + std::vector<std::string> rpaths; if (!this->Tool->GetFileInfo(file, libs, rpaths)) { return false; } diff --git a/Source/cmBreakCommand.cxx b/Source/cmBreakCommand.cxx index d07898f..95db689 100644 --- a/Source/cmBreakCommand.cxx +++ b/Source/cmBreakCommand.cxx @@ -10,14 +10,14 @@ #include "cmPolicies.h" // cmBreakCommand -bool cmBreakCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) +bool cmBreakCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { - if (!this->Makefile->IsLoopBlock()) { + if (!status.GetMakefile().IsLoopBlock()) { bool issueMessage = true; std::ostringstream e; MessageType messageType = MessageType::AUTHOR_WARNING; - switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0055)) { + switch (status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0055)) { case cmPolicies::WARN: e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0055) << "\n"; break; @@ -34,7 +34,7 @@ bool cmBreakCommand::InitialPass(std::vector<std::string> const& args, if (issueMessage) { e << "A BREAK command was found outside of a proper " "FOREACH or WHILE loop scope."; - this->Makefile->IssueMessage(messageType, e.str()); + status.GetMakefile().IssueMessage(messageType, e.str()); if (messageType == MessageType::FATAL_ERROR) { return false; } @@ -47,7 +47,7 @@ bool cmBreakCommand::InitialPass(std::vector<std::string> const& args, bool issueMessage = true; std::ostringstream e; MessageType messageType = MessageType::AUTHOR_WARNING; - switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0055)) { + switch (status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0055)) { case cmPolicies::WARN: e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0055) << "\n"; break; @@ -63,7 +63,7 @@ bool cmBreakCommand::InitialPass(std::vector<std::string> const& args, if (issueMessage) { e << "The BREAK command does not accept any arguments."; - this->Makefile->IssueMessage(messageType, e.str()); + status.GetMakefile().IssueMessage(messageType, e.str()); if (messageType == MessageType::FATAL_ERROR) { return false; } diff --git a/Source/cmBreakCommand.h b/Source/cmBreakCommand.h index e6f218e..e6ce6fe 100644 --- a/Source/cmBreakCommand.h +++ b/Source/cmBreakCommand.h @@ -8,34 +8,14 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmBreakCommand +/** * \brief Break from an enclosing foreach or while loop * * cmBreakCommand returns from an enclosing foreach or while loop */ -class cmBreakCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmBreakCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; +bool cmBreakCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmBuildNameCommand.cxx b/Source/cmBuildNameCommand.cxx index ddff686..df94f1d 100644 --- a/Source/cmBuildNameCommand.cxx +++ b/Source/cmBuildNameCommand.cxx @@ -5,21 +5,20 @@ #include "cmsys/RegularExpression.hxx" #include <algorithm> +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmStateTypes.h" #include "cmSystemTools.h" -class cmExecutionStatus; - -// cmBuildNameCommand -bool cmBuildNameCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmBuildNameCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.empty()) { - this->SetError("called with incorrect number of arguments"); + status.SetError("called with incorrect number of arguments"); return false; } - const char* cacheValue = this->Makefile->GetDefinition(args[0]); + cmMakefile& mf = status.GetMakefile(); + const char* cacheValue = mf.GetDefinition(args[0]); if (cacheValue) { // do we need to correct the value? cmsys::RegularExpression reg("[()/]"); @@ -28,14 +27,14 @@ bool cmBuildNameCommand::InitialPass(std::vector<std::string> const& args, std::replace(cv.begin(), cv.end(), '/', '_'); std::replace(cv.begin(), cv.end(), '(', '_'); std::replace(cv.begin(), cv.end(), ')', '_'); - this->Makefile->AddCacheDefinition(args[0], cv.c_str(), "Name of build.", - cmStateEnums::STRING); + mf.AddCacheDefinition(args[0], cv.c_str(), "Name of build.", + cmStateEnums::STRING); } return true; } std::string buildname = "WinNT"; - if (this->Makefile->GetDefinition("UNIX")) { + if (mf.GetDefinition("UNIX")) { buildname.clear(); cmSystemTools::RunSingleCommand("uname -a", &buildname, &buildname); if (!buildname.empty()) { @@ -47,14 +46,14 @@ bool cmBuildNameCommand::InitialPass(std::vector<std::string> const& args, } } std::string compiler = "${CMAKE_CXX_COMPILER}"; - this->Makefile->ExpandVariablesInString(compiler); + mf.ExpandVariablesInString(compiler); buildname += "-"; buildname += cmSystemTools::GetFilenameName(compiler); std::replace(buildname.begin(), buildname.end(), '/', '_'); std::replace(buildname.begin(), buildname.end(), '(', '_'); std::replace(buildname.begin(), buildname.end(), ')', '_'); - this->Makefile->AddCacheDefinition(args[0], buildname.c_str(), - "Name of build.", cmStateEnums::STRING); + mf.AddCacheDefinition(args[0], buildname.c_str(), "Name of build.", + cmStateEnums::STRING); return true; } diff --git a/Source/cmBuildNameCommand.h b/Source/cmBuildNameCommand.h index bd2d146..37a7268 100644 --- a/Source/cmBuildNameCommand.h +++ b/Source/cmBuildNameCommand.h @@ -8,21 +8,9 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -class cmBuildNameCommand : public cmCommand -{ -public: - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmBuildNameCommand>(); - } - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; +bool cmBuildNameCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmCMakeHostSystemInformationCommand.cxx b/Source/cmCMakeHostSystemInformationCommand.cxx index b4cd2a5..974b984 100644 --- a/Source/cmCMakeHostSystemInformationCommand.cxx +++ b/Source/cmCMakeHostSystemInformationCommand.cxx @@ -2,8 +2,9 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCMakeHostSystemInformationCommand.h" -#include <sstream> +#include <stddef.h> +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmsys/SystemInformation.hxx" @@ -16,16 +17,22 @@ # define HAVE_VS_SETUP_HELPER #endif -class cmExecutionStatus; +namespace { +bool GetValue(cmExecutionStatus& status, cmsys::SystemInformation& info, + std::string const& key, std::string& value); +std::string ValueToString(size_t value); +std::string ValueToString(const char* value); +std::string ValueToString(std::string const& value); +} // cmCMakeHostSystemInformation -bool cmCMakeHostSystemInformationCommand::InitialPass( - std::vector<std::string> const& args, cmExecutionStatus&) +bool cmCMakeHostSystemInformationCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { size_t current_index = 0; if (args.size() < (current_index + 2) || args[current_index] != "RESULT") { - this->SetError("missing RESULT specification."); + status.SetError("missing RESULT specification."); return false; } @@ -33,7 +40,7 @@ bool cmCMakeHostSystemInformationCommand::InitialPass( current_index += 2; if (args.size() < (current_index + 2) || args[current_index] != "QUERY") { - this->SetError("missing QUERY specification"); + status.SetError("missing QUERY specification"); return false; } @@ -49,89 +56,91 @@ bool cmCMakeHostSystemInformationCommand::InitialPass( result_list += ";"; } std::string value; - if (!this->GetValue(info, key, value)) { + if (!GetValue(status, info, key, value)) { return false; } result_list += value; } - this->Makefile->AddDefinition(variable, result_list); + status.GetMakefile().AddDefinition(variable, result_list); return true; } -bool cmCMakeHostSystemInformationCommand::GetValue( - cmsys::SystemInformation& info, std::string const& key, std::string& value) +namespace { + +bool GetValue(cmExecutionStatus& status, cmsys::SystemInformation& info, + std::string const& key, std::string& value) { if (key == "NUMBER_OF_LOGICAL_CORES") { - value = this->ValueToString(info.GetNumberOfLogicalCPU()); + value = ValueToString(info.GetNumberOfLogicalCPU()); } else if (key == "NUMBER_OF_PHYSICAL_CORES") { - value = this->ValueToString(info.GetNumberOfPhysicalCPU()); + value = ValueToString(info.GetNumberOfPhysicalCPU()); } else if (key == "HOSTNAME") { - value = this->ValueToString(info.GetHostname()); + value = ValueToString(info.GetHostname()); } else if (key == "FQDN") { - value = this->ValueToString(info.GetFullyQualifiedDomainName()); + value = ValueToString(info.GetFullyQualifiedDomainName()); } else if (key == "TOTAL_VIRTUAL_MEMORY") { - value = this->ValueToString(info.GetTotalVirtualMemory()); + value = ValueToString(info.GetTotalVirtualMemory()); } else if (key == "AVAILABLE_VIRTUAL_MEMORY") { - value = this->ValueToString(info.GetAvailableVirtualMemory()); + value = ValueToString(info.GetAvailableVirtualMemory()); } else if (key == "TOTAL_PHYSICAL_MEMORY") { - value = this->ValueToString(info.GetTotalPhysicalMemory()); + value = ValueToString(info.GetTotalPhysicalMemory()); } else if (key == "AVAILABLE_PHYSICAL_MEMORY") { - value = this->ValueToString(info.GetAvailablePhysicalMemory()); + value = ValueToString(info.GetAvailablePhysicalMemory()); } else if (key == "IS_64BIT") { - value = this->ValueToString(info.Is64Bits()); + value = ValueToString(info.Is64Bits()); } else if (key == "HAS_FPU") { - value = this->ValueToString( + value = ValueToString( info.DoesCPUSupportFeature(cmsys::SystemInformation::CPU_FEATURE_FPU)); } else if (key == "HAS_MMX") { - value = this->ValueToString( + value = ValueToString( info.DoesCPUSupportFeature(cmsys::SystemInformation::CPU_FEATURE_MMX)); } else if (key == "HAS_MMX_PLUS") { - value = this->ValueToString(info.DoesCPUSupportFeature( + value = ValueToString(info.DoesCPUSupportFeature( cmsys::SystemInformation::CPU_FEATURE_MMX_PLUS)); } else if (key == "HAS_SSE") { - value = this->ValueToString( + value = ValueToString( info.DoesCPUSupportFeature(cmsys::SystemInformation::CPU_FEATURE_SSE)); } else if (key == "HAS_SSE2") { - value = this->ValueToString( + value = ValueToString( info.DoesCPUSupportFeature(cmsys::SystemInformation::CPU_FEATURE_SSE2)); } else if (key == "HAS_SSE_FP") { - value = this->ValueToString(info.DoesCPUSupportFeature( + value = ValueToString(info.DoesCPUSupportFeature( cmsys::SystemInformation::CPU_FEATURE_SSE_FP)); } else if (key == "HAS_SSE_MMX") { - value = this->ValueToString(info.DoesCPUSupportFeature( + value = ValueToString(info.DoesCPUSupportFeature( cmsys::SystemInformation::CPU_FEATURE_SSE_MMX)); } else if (key == "HAS_AMD_3DNOW") { - value = this->ValueToString(info.DoesCPUSupportFeature( + value = ValueToString(info.DoesCPUSupportFeature( cmsys::SystemInformation::CPU_FEATURE_AMD_3DNOW)); } else if (key == "HAS_AMD_3DNOW_PLUS") { - value = this->ValueToString(info.DoesCPUSupportFeature( + value = ValueToString(info.DoesCPUSupportFeature( cmsys::SystemInformation::CPU_FEATURE_AMD_3DNOW_PLUS)); } else if (key == "HAS_IA64") { - value = this->ValueToString( + value = ValueToString( info.DoesCPUSupportFeature(cmsys::SystemInformation::CPU_FEATURE_IA64)); } else if (key == "HAS_SERIAL_NUMBER") { - value = this->ValueToString(info.DoesCPUSupportFeature( + value = ValueToString(info.DoesCPUSupportFeature( cmsys::SystemInformation::CPU_FEATURE_SERIALNUMBER)); } else if (key == "PROCESSOR_NAME") { - value = this->ValueToString(info.GetExtendedProcessorName()); + value = ValueToString(info.GetExtendedProcessorName()); } else if (key == "PROCESSOR_DESCRIPTION") { value = info.GetCPUDescription(); } else if (key == "PROCESSOR_SERIAL_NUMBER") { - value = this->ValueToString(info.GetProcessorSerialNumber()); + value = ValueToString(info.GetProcessorSerialNumber()); } else if (key == "OS_NAME") { - value = this->ValueToString(info.GetOSName()); + value = ValueToString(info.GetOSName()); } else if (key == "OS_RELEASE") { - value = this->ValueToString(info.GetOSRelease()); + value = ValueToString(info.GetOSRelease()); } else if (key == "OS_VERSION") { - value = this->ValueToString(info.GetOSVersion()); + value = ValueToString(info.GetOSVersion()); } else if (key == "OS_PLATFORM") { - value = this->ValueToString(info.GetOSPlatform()); + value = ValueToString(info.GetOSPlatform()); #ifdef HAVE_VS_SETUP_HELPER } else if (key == "VS_15_DIR") { // If generating for the VS 15 IDE, use the same instance. - cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator(); + cmGlobalGenerator* gg = status.GetMakefile().GetGlobalGenerator(); if (cmHasLiteralPrefix(gg->GetName(), "Visual Studio 15 ")) { cmGlobalVisualStudioVersionedGenerator* vs15gen = static_cast<cmGlobalVisualStudioVersionedGenerator*>(gg); @@ -147,7 +156,7 @@ bool cmCMakeHostSystemInformationCommand::GetValue( } } else if (key == "VS_16_DIR") { // If generating for the VS 16 IDE, use the same instance. - cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator(); + cmGlobalGenerator* gg = status.GetMakefile().GetGlobalGenerator(); if (cmHasLiteralPrefix(gg->GetName(), "Visual Studio 16 ")) { cmGlobalVisualStudioVersionedGenerator* vs16gen = static_cast<cmGlobalVisualStudioVersionedGenerator*>(gg); @@ -164,30 +173,26 @@ bool cmCMakeHostSystemInformationCommand::GetValue( #endif } else { std::string e = "does not recognize <key> " + key; - this->SetError(e); + status.SetError(e); return false; } return true; } -std::string cmCMakeHostSystemInformationCommand::ValueToString( - size_t value) const +std::string ValueToString(size_t value) { - std::ostringstream tmp; - tmp << value; - return tmp.str(); + return std::to_string(value); } -std::string cmCMakeHostSystemInformationCommand::ValueToString( - const char* value) const +std::string ValueToString(const char* value) { std::string safe_string = value ? value : ""; return safe_string; } -std::string cmCMakeHostSystemInformationCommand::ValueToString( - std::string const& value) const +std::string ValueToString(std::string const& value) { return value; } +} diff --git a/Source/cmCMakeHostSystemInformationCommand.h b/Source/cmCMakeHostSystemInformationCommand.h index 8ea2d55..79e3f27 100644 --- a/Source/cmCMakeHostSystemInformationCommand.h +++ b/Source/cmCMakeHostSystemInformationCommand.h @@ -5,50 +5,18 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include <stddef.h> #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -namespace cmsys { -class SystemInformation; -} // namespace cmsys -/** \class cmCMakeHostSystemInformationCommand +/** * \brief Query host system specific information * * cmCMakeHostSystemInformationCommand queries system information of * the system on which CMake runs. */ -class cmCMakeHostSystemInformationCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmCMakeHostSystemInformationCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; - -private: - bool GetValue(cmsys::SystemInformation& info, std::string const& key, - std::string& value); - - std::string ValueToString(size_t value) const; - std::string ValueToString(const char* value) const; - std::string ValueToString(std::string const& value) const; -}; +bool cmCMakeHostSystemInformationCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmCMakeMinimumRequired.cxx b/Source/cmCMakeMinimumRequired.cxx index f2eae38..f93c266 100644 --- a/Source/cmCMakeMinimumRequired.cxx +++ b/Source/cmCMakeMinimumRequired.cxx @@ -5,26 +5,32 @@ #include <sstream> #include <stdio.h> +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmSystemTools.h" #include "cmVersion.h" -class cmExecutionStatus; +namespace { +bool EnforceUnknownArguments(std::string const& version_max, + std::vector<std::string> const& unknown_arguments, + cmExecutionStatus& status); +} // cmCMakeMinimumRequired -bool cmCMakeMinimumRequired::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmCMakeMinimumRequired(std::vector<std::string> const& args, + cmExecutionStatus& status) { // Process arguments. std::string version_string; bool doing_version = false; + std::vector<std::string> unknown_arguments; for (std::string const& arg : args) { if (arg == "VERSION") { doing_version = true; } else if (arg == "FATAL_ERROR") { if (doing_version) { - this->SetError("called with no value for VERSION."); + status.SetError("called with no value for VERSION."); return false; } doing_version = false; @@ -32,17 +38,17 @@ bool cmCMakeMinimumRequired::InitialPass(std::vector<std::string> const& args, doing_version = false; version_string = arg; } else { - this->UnknownArguments.push_back(arg); + unknown_arguments.push_back(arg); } } if (doing_version) { - this->SetError("called with no value for VERSION."); + status.SetError("called with no value for VERSION."); return false; } // Make sure there was a version to check. if (version_string.empty()) { - return this->EnforceUnknownArguments(std::string()); + return EnforceUnknownArguments(std::string(), unknown_arguments, status); } // Separate the <min> version and any trailing ...<max> component. @@ -56,12 +62,13 @@ bool cmCMakeMinimumRequired::InitialPass(std::vector<std::string> const& args, std::ostringstream e; e << "VERSION \"" << version_string << R"(" does not have a version on both sides of "...".)"; - this->SetError(e.str()); + status.SetError(e.str()); return false; } // Save the required version string. - this->Makefile->AddDefinition("CMAKE_MINIMUM_REQUIRED_VERSION", version_min); + status.GetMakefile().AddDefinition("CMAKE_MINIMUM_REQUIRED_VERSION", + version_min); // Get the current version number. unsigned int current_major = cmVersion::GetMajorVersion(); @@ -79,7 +86,7 @@ bool cmCMakeMinimumRequired::InitialPass(std::vector<std::string> const& args, &required_minor, &required_patch, &required_tweak) < 2) { std::ostringstream e; e << "could not parse VERSION \"" << version_min << "\"."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } @@ -95,32 +102,34 @@ bool cmCMakeMinimumRequired::InitialPass(std::vector<std::string> const& args, e << "CMake " << version_min << " or higher is required. You are running version " << cmVersion::GetCMakeVersion(); - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + status.GetMakefile().IssueMessage(MessageType::FATAL_ERROR, e.str()); cmSystemTools::SetFatalErrorOccured(); return true; } // The version is not from the future, so enforce unknown arguments. - if (!this->EnforceUnknownArguments(version_max)) { + if (!EnforceUnknownArguments(version_max, unknown_arguments, status)) { return false; } if (required_major < 2 || (required_major == 2 && required_minor < 4)) { - this->Makefile->IssueMessage( + status.GetMakefile().IssueMessage( MessageType::AUTHOR_WARNING, "Compatibility with CMake < 2.4 is not supported by CMake >= 3.0."); - this->Makefile->SetPolicyVersion("2.4", version_max); + status.GetMakefile().SetPolicyVersion("2.4", version_max); } else { - this->Makefile->SetPolicyVersion(version_min, version_max); + status.GetMakefile().SetPolicyVersion(version_min, version_max); } return true; } -bool cmCMakeMinimumRequired::EnforceUnknownArguments( - std::string const& version_max) +namespace { +bool EnforceUnknownArguments(std::string const& version_max, + std::vector<std::string> const& unknown_arguments, + cmExecutionStatus& status) { - if (this->UnknownArguments.empty()) { + if (unknown_arguments.empty()) { return true; } @@ -149,7 +158,8 @@ bool cmCMakeMinimumRequired::EnforceUnknownArguments( } std::ostringstream e; - e << "called with unknown argument \"" << this->UnknownArguments[0] << "\"."; - this->SetError(e.str()); + e << "called with unknown argument \"" << unknown_arguments[0] << "\"."; + status.SetError(e.str()); return false; } +} diff --git a/Source/cmCMakeMinimumRequired.h b/Source/cmCMakeMinimumRequired.h index 3881133..53f78f6 100644 --- a/Source/cmCMakeMinimumRequired.h +++ b/Source/cmCMakeMinimumRequired.h @@ -8,38 +8,14 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmCMakeMinimumRequired +/** * \brief cmake_minimum_required command * * cmCMakeMinimumRequired implements the cmake_minimum_required CMake command */ -class cmCMakeMinimumRequired : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmCMakeMinimumRequired>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; - -private: - std::vector<std::string> UnknownArguments; - bool EnforceUnknownArguments(std::string const& version_max); -}; +bool cmCMakeMinimumRequired(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmCMakePolicyCommand.cxx b/Source/cmCMakePolicyCommand.cxx index ce046fc..9b1aea9 100644 --- a/Source/cmCMakePolicyCommand.cxx +++ b/Source/cmCMakePolicyCommand.cxx @@ -4,88 +4,101 @@ #include <sstream> +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmPolicies.h" #include "cmState.h" #include "cmStateTypes.h" -class cmExecutionStatus; +namespace { +bool HandleSetMode(std::vector<std::string> const& args, + cmExecutionStatus& status); +bool HandleGetMode(std::vector<std::string> const& args, + cmExecutionStatus& status); +bool HandleVersionMode(std::vector<std::string> const& args, + cmExecutionStatus& status); +bool HandleGetWarningMode(std::vector<std::string> const& args, + cmExecutionStatus& status); +} // cmCMakePolicyCommand -bool cmCMakePolicyCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmCMakePolicyCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.empty()) { - this->SetError("requires at least one argument."); + status.SetError("requires at least one argument."); return false; } if (args[0] == "SET") { - return this->HandleSetMode(args); + return HandleSetMode(args, status); } if (args[0] == "GET") { - return this->HandleGetMode(args); + return HandleGetMode(args, status); } if (args[0] == "PUSH") { if (args.size() > 1) { - this->SetError("PUSH may not be given additional arguments."); + status.SetError("PUSH may not be given additional arguments."); return false; } - this->Makefile->PushPolicy(); + status.GetMakefile().PushPolicy(); return true; } if (args[0] == "POP") { if (args.size() > 1) { - this->SetError("POP may not be given additional arguments."); + status.SetError("POP may not be given additional arguments."); return false; } - this->Makefile->PopPolicy(); + status.GetMakefile().PopPolicy(); return true; } if (args[0] == "VERSION") { - return this->HandleVersionMode(args); + return HandleVersionMode(args, status); } if (args[0] == "GET_WARNING") { - return this->HandleGetWarningMode(args); + return HandleGetWarningMode(args, status); } std::ostringstream e; e << "given unknown first argument \"" << args[0] << "\""; - this->SetError(e.str()); + status.SetError(e.str()); return false; } -bool cmCMakePolicyCommand::HandleSetMode(std::vector<std::string> const& args) +namespace { + +bool HandleSetMode(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() != 3) { - this->SetError("SET must be given exactly 2 additional arguments."); + status.SetError("SET must be given exactly 2 additional arguments."); return false; } - cmPolicies::PolicyStatus status; + cmPolicies::PolicyStatus policyStatus; if (args[2] == "OLD") { - status = cmPolicies::OLD; + policyStatus = cmPolicies::OLD; } else if (args[2] == "NEW") { - status = cmPolicies::NEW; + policyStatus = cmPolicies::NEW; } else { std::ostringstream e; e << "SET given unrecognized policy status \"" << args[2] << "\""; - this->SetError(e.str()); + status.SetError(e.str()); return false; } - if (!this->Makefile->SetPolicy(args[1].c_str(), status)) { - this->SetError("SET failed to set policy."); + if (!status.GetMakefile().SetPolicy(args[1].c_str(), policyStatus)) { + status.SetError("SET failed to set policy."); return false; } if (args[1] == "CMP0001" && - (status == cmPolicies::WARN || status == cmPolicies::OLD)) { - if (!(this->Makefile->GetState()->GetInitializedCacheValue( + (policyStatus == cmPolicies::WARN || policyStatus == cmPolicies::OLD)) { + if (!(status.GetMakefile().GetState()->GetInitializedCacheValue( "CMAKE_BACKWARDS_COMPATIBILITY"))) { // Set it to 2.4 because that is the last version where the // variable had meaning. - this->Makefile->AddCacheDefinition( + status.GetMakefile().AddCacheDefinition( "CMAKE_BACKWARDS_COMPATIBILITY", "2.4", "For backwards compatibility, what version of CMake " "commands and " @@ -96,14 +109,15 @@ bool cmCMakePolicyCommand::HandleSetMode(std::vector<std::string> const& args) return true; } -bool cmCMakePolicyCommand::HandleGetMode(std::vector<std::string> const& args) +bool HandleGetMode(std::vector<std::string> const& args, + cmExecutionStatus& status) { bool parent_scope = false; if (args.size() == 4 && args[3] == "PARENT_SCOPE") { // Undocumented PARENT_SCOPE option for use within CMake. parent_scope = true; } else if (args.size() != 3) { - this->SetError("GET must be given exactly 2 additional arguments."); + status.SetError("GET must be given exactly 2 additional arguments."); return false; } @@ -117,25 +131,25 @@ bool cmCMakePolicyCommand::HandleGetMode(std::vector<std::string> const& args) std::ostringstream e; e << "GET given policy \"" << id << "\" which is not known to this " << "version of CMake."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } // Lookup the policy setting. - cmPolicies::PolicyStatus status = - this->Makefile->GetPolicyStatus(pid, parent_scope); - switch (status) { + cmPolicies::PolicyStatus policyStatus = + status.GetMakefile().GetPolicyStatus(pid, parent_scope); + switch (policyStatus) { case cmPolicies::OLD: // Report that the policy is set to OLD. - this->Makefile->AddDefinition(var, "OLD"); + status.GetMakefile().AddDefinition(var, "OLD"); break; case cmPolicies::WARN: // Report that the policy is not set. - this->Makefile->AddDefinition(var, ""); + status.GetMakefile().AddDefinition(var, ""); break; case cmPolicies::NEW: // Report that the policy is set to NEW. - this->Makefile->AddDefinition(var, "NEW"); + status.GetMakefile().AddDefinition(var, "NEW"); break; case cmPolicies::REQUIRED_IF_USED: case cmPolicies::REQUIRED_ALWAYS: @@ -146,22 +160,22 @@ bool cmCMakePolicyCommand::HandleGetMode(std::vector<std::string> const& args) << "The call to cmake_policy(GET " << id << " ...) at which this " << "error appears requests the policy, and this version of CMake " << "requires that the policy be set to NEW before it is checked."; - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + status.GetMakefile().IssueMessage(MessageType::FATAL_ERROR, e.str()); } } return true; } -bool cmCMakePolicyCommand::HandleVersionMode( - std::vector<std::string> const& args) +bool HandleVersionMode(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() <= 1) { - this->SetError("VERSION not given an argument"); + status.SetError("VERSION not given an argument"); return false; } if (args.size() >= 3) { - this->SetError("VERSION given too many arguments"); + status.SetError("VERSION given too many arguments"); return false; } std::string const& version_string = args[1]; @@ -177,19 +191,19 @@ bool cmCMakePolicyCommand::HandleVersionMode( std::ostringstream e; e << "VERSION \"" << version_string << R"(" does not have a version on both sides of "...".)"; - this->SetError(e.str()); + status.SetError(e.str()); return false; } - this->Makefile->SetPolicyVersion(version_min, version_max); + status.GetMakefile().SetPolicyVersion(version_min, version_max); return true; } -bool cmCMakePolicyCommand::HandleGetWarningMode( - std::vector<std::string> const& args) +bool HandleGetWarningMode(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() != 3) { - this->SetError( + status.SetError( "GET_WARNING must be given exactly 2 additional arguments."); return false; } @@ -204,12 +218,13 @@ bool cmCMakePolicyCommand::HandleGetWarningMode( std::ostringstream e; e << "GET_WARNING given policy \"" << id << "\" which is not known to this version of CMake."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } // Lookup the policy warning. - this->Makefile->AddDefinition(var, cmPolicies::GetPolicyWarning(pid)); + status.GetMakefile().AddDefinition(var, cmPolicies::GetPolicyWarning(pid)); return true; } +} diff --git a/Source/cmCMakePolicyCommand.h b/Source/cmCMakePolicyCommand.h index 919402c..ba9397d 100644 --- a/Source/cmCMakePolicyCommand.h +++ b/Source/cmCMakePolicyCommand.h @@ -8,41 +8,15 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmCMakePolicyCommand +/** * \brief Set how CMake should handle policies * * cmCMakePolicyCommand sets how CMake should deal with backwards * compatibility policies. */ -class cmCMakePolicyCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmCMakePolicyCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; - -private: - bool HandleSetMode(std::vector<std::string> const& args); - bool HandleGetMode(std::vector<std::string> const& args); - bool HandleVersionMode(std::vector<std::string> const& args); - bool HandleGetWarningMode(std::vector<std::string> const& args); -}; +bool cmCMakePolicyCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx index d06ec20..f0c1845 100644 --- a/Source/cmCPluginAPI.cxx +++ b/Source/cmCPluginAPI.cxx @@ -690,9 +690,7 @@ void CCONV cmSourceFileSetName(void* arg, const char* name, const char* dir, // Next, try the various source extensions for (std::string const& ext : sourceExts) { - hname = pathname; - hname += "."; - hname += ext; + hname = cmStrCat(pathname, '.', ext); if (cmSystemTools::FileExists(hname)) { sf->SourceExtension = ext; sf->FullPath = hname; @@ -702,9 +700,7 @@ void CCONV cmSourceFileSetName(void* arg, const char* name, const char* dir, // Finally, try the various header extensions for (std::string const& ext : headerExts) { - hname = pathname; - hname += "."; - hname += ext; + hname = cmStrCat(pathname, '.', ext); if (cmSystemTools::FileExists(hname)) { sf->SourceExtension = ext; sf->FullPath = hname; diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index e7a16b5..f51ed0b 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -155,7 +155,7 @@ struct cmCTest::Private bool TomorrowTag = false; int TestModel = cmCTest::EXPERIMENTAL; - std::string SpecificTrack; + std::string SpecificGroup; cmDuration TimeOut = cmDuration::zero(); @@ -508,10 +508,10 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command) day != lctime->tm_mday) { tag.clear(); } - std::string track; - if (cmSystemTools::GetLineFromStream(tfin, track) && + std::string group; + if (cmSystemTools::GetLineFromStream(tfin, group) && !this->Impl->Parts[PartStart] && !command) { - this->Impl->SpecificTrack = track; + this->Impl->SpecificGroup = group; } std::string model; if (cmSystemTools::GetLineFromStream(tfin, model) && @@ -564,13 +564,13 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command) } } } else { - std::string track; + std::string group; std::string modelStr; int model = cmCTest::UNKNOWN; if (tfin) { cmSystemTools::GetLineFromStream(tfin, tag); - cmSystemTools::GetLineFromStream(tfin, track); + cmSystemTools::GetLineFromStream(tfin, group); if (cmSystemTools::GetLineFromStream(tfin, modelStr)) { model = GetTestModelFromString(modelStr.c_str()); } @@ -605,15 +605,15 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command) quiet); } - if (!this->Impl->SpecificTrack.empty() && - track != this->Impl->SpecificTrack) { + if (!this->Impl->SpecificGroup.empty() && + group != this->Impl->SpecificGroup) { cmCTestOptionalLog(this, WARNING, - "Track given in TAG does not match " - "track given in ctest_start()" + "Group given in TAG does not match " + "group given in ctest_start()" << std::endl, quiet); } else { - this->Impl->SpecificTrack = track; + this->Impl->SpecificGroup = group; } cmCTestOptionalLog(this, OUTPUT, @@ -641,12 +641,10 @@ bool cmCTest::InitializeFromCommand(cmCTestStartCommand* command) cmMakefile* mf = command->GetMakefile(); std::string fname; - std::string src_dir_fname = src_dir; - src_dir_fname += "/CTestConfig.cmake"; + std::string src_dir_fname = cmStrCat(src_dir, "/CTestConfig.cmake"); cmSystemTools::ConvertToUnixSlashes(src_dir_fname); - std::string bld_dir_fname = bld_dir; - bld_dir_fname += "/CTestConfig.cmake"; + std::string bld_dir_fname = cmStrCat(bld_dir, "/CTestConfig.cmake"); cmSystemTools::ConvertToUnixSlashes(bld_dir_fname); if (cmSystemTools::FileExists(bld_dir_fname)) { @@ -662,8 +660,7 @@ bool cmCTest::InitializeFromCommand(cmCTestStartCommand* command) command->ShouldBeQuiet()); bool readit = mf->ReadDependentFile(fname); if (!readit) { - std::string m = "Could not find include file: "; - m += fname; + std::string m = cmStrCat("Could not find include file: ", fname); command->SetError(m); return false; } @@ -856,8 +853,7 @@ bool cmCTest::AddIfExists(Part part, const char* file) if (this->CTestFileExists(file)) { this->AddSubmitFile(part, file); } else { - std::string name = file; - name += ".gz"; + std::string name = cmStrCat(file, ".gz"); if (this->CTestFileExists(name)) { this->AddSubmitFile(part, file); } else { @@ -1021,8 +1017,8 @@ int cmCTest::ProcessSteps() std::string cmCTest::GetTestModelString() { - if (!this->Impl->SpecificTrack.empty()) { - return this->Impl->SpecificTrack; + if (!this->Impl->SpecificGroup.empty()) { + return this->Impl->SpecificGroup; } switch (this->Impl->TestModel) { case cmCTest::NIGHTLY: @@ -1222,9 +1218,7 @@ int cmCTest::RunTest(std::vector<const char*> argv, std::string* output, timeout != cmCTest::MaxDuration() && timeout > cmDuration::zero()) { args.emplace_back("--test-timeout"); - std::ostringstream msg; - msg << cmDurationTo<unsigned int>(timeout); - args.push_back(msg.str()); + args.push_back(std::to_string(cmDurationTo<unsigned int>(timeout))); } args.emplace_back(i); } @@ -1320,15 +1314,15 @@ int cmCTest::RunTest(std::vector<const char*> argv, std::string* output, OutputTestErrors(tempOutput); } *retVal = cmsysProcess_GetExitException(cp); - std::string outerr = "\n*** Exception executing: "; - outerr += cmsysProcess_GetExceptionString(cp); + std::string outerr = cmStrCat("\n*** Exception executing: ", + cmsysProcess_GetExceptionString(cp)); if (output) { *output += outerr; } cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, outerr << std::endl); } else if (result == cmsysProcess_State_Error) { - std::string outerr = "\n*** ERROR executing: "; - outerr += cmsysProcess_GetErrorString(cp); + std::string outerr = + cmStrCat("\n*** ERROR executing: ", cmsysProcess_GetErrorString(cp)); if (output) { *output += outerr; } @@ -1452,8 +1446,7 @@ void cmCTest::AddSiteProperties(cmXMLWriter& xml) if (labels) { xml.StartElement("Labels"); std::string l = labels; - std::vector<std::string> args; - cmExpandList(l, args); + std::vector<std::string> args = cmExpandedList(l); for (std::string const& i : args) { xml.Element("Label", i); } @@ -1485,8 +1478,7 @@ std::vector<std::string> cmCTest::GetLabelsForSubprojects() { std::string labelsForSubprojects = this->GetCTestConfiguration("LabelsForSubprojects"); - std::vector<std::string> subprojects; - cmExpandList(labelsForSubprojects, subprojects); + std::vector<std::string> subprojects = cmExpandedList(labelsForSubprojects); // sort the array std::sort(subprojects.begin(), subprojects.end()); @@ -1908,9 +1900,15 @@ bool cmCTest::HandleCommandLineArguments(size_t& i, this->Impl->Debug = true; this->Impl->ShowLineNumbers = true; } + if (this->CheckArgument(arg, "--group") && i < args.size() - 1) { + i++; + this->Impl->SpecificGroup = args[i]; + } + // This is an undocumented / deprecated option. + // "Track" has been renamed to "Group". if (this->CheckArgument(arg, "--track") && i < args.size() - 1) { i++; - this->Impl->SpecificTrack = args[i]; + this->Impl->SpecificGroup = args[i]; } if (this->CheckArgument(arg, "--show-line-numbers")) { this->Impl->ShowLineNumbers = true; @@ -2129,6 +2127,11 @@ bool cmCTest::ColoredOutputSupportedByConsole() return false; #else // On UNIX we need a non-dumb tty. + std::string clicolor_force; + if (cmSystemTools::GetEnv("CLICOLOR_FORCE", clicolor_force) && + !clicolor_force.empty() && clicolor_force != "0") { + return true; + } return ConsoleIsNotDumb(); #endif } @@ -2499,8 +2502,7 @@ int cmCTest::ReadCustomConfigurationFileTree(const char* dir, cmMakefile* mf) "* Read custom CTest configuration directory: " << dir << std::endl); - std::string fname = dir; - fname += "/CTestCustom.cmake"; + std::string fname = cmStrCat(dir, "/CTestCustom.cmake"); cmCTestLog(this, DEBUG, "* Check for file: " << fname << std::endl); if (cmSystemTools::FileExists(fname)) { cmCTestLog(this, DEBUG, @@ -2520,8 +2522,7 @@ int cmCTest::ReadCustomConfigurationFileTree(const char* dir, cmMakefile* mf) } } - std::string rexpr = dir; - rexpr += "/CTestCustom.ctest"; + std::string rexpr = cmStrCat(dir, "/CTestCustom.ctest"); cmCTestLog(this, DEBUG, "* Check for file: " << rexpr << std::endl); if (!found && cmSystemTools::FileExists(rexpr)) { cmsys::Glob gl; @@ -2673,8 +2674,7 @@ std::string cmCTest::GetSubmitURL() std::string site = this->GetCTestConfiguration("DropSite"); std::string location = this->GetCTestConfiguration("DropLocation"); - url = method.empty() ? "http" : method; - url += "://"; + url = cmStrCat(method.empty() ? "http" : method, "://"); if (!user.empty()) { url += user; if (!password.empty()) { @@ -2769,21 +2769,21 @@ std::vector<std::string>& cmCTest::GetInitialCommandLineArguments() return this->Impl->InitialCommandLineArguments; } -const char* cmCTest::GetSpecificTrack() +const char* cmCTest::GetSpecificGroup() { - if (this->Impl->SpecificTrack.empty()) { + if (this->Impl->SpecificGroup.empty()) { return nullptr; } - return this->Impl->SpecificTrack.c_str(); + return this->Impl->SpecificGroup.c_str(); } -void cmCTest::SetSpecificTrack(const char* track) +void cmCTest::SetSpecificGroup(const char* group) { - if (!track) { - this->Impl->SpecificTrack.clear(); + if (!group) { + this->Impl->SpecificGroup.clear(); return; } - this->Impl->SpecificTrack = track; + this->Impl->SpecificGroup = group; } void cmCTest::SetFailover(bool failover) diff --git a/Source/cmCTest.h b/Source/cmCTest.h index 7f66378..7fe3455 100644 --- a/Source/cmCTest.h +++ b/Source/cmCTest.h @@ -404,9 +404,9 @@ public: std::vector<std::string>& GetInitialCommandLineArguments(); - /** Set the track to submit to */ - void SetSpecificTrack(const char* track); - const char* GetSpecificTrack(); + /** Set the group to submit to */ + void SetSpecificGroup(const char* group); + const char* GetSpecificGroup(); void SetFailover(bool failover); bool GetFailover() const; diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx index 6b61f1b..cf28cdb 100644 --- a/Source/cmCacheManager.cxx +++ b/Source/cmCacheManager.cxx @@ -26,8 +26,7 @@ cmCacheManager::cmCacheManager() void cmCacheManager::CleanCMakeFiles(const std::string& path) { - std::string glob = path; - glob += "/CMakeFiles/*.cmake"; + std::string glob = cmStrCat(path, "/CMakeFiles/*.cmake"); cmsys::Glob globIt; globIt.FindFiles(glob); std::vector<std::string> files = globIt.GetFiles(); @@ -38,8 +37,7 @@ bool cmCacheManager::LoadCache(const std::string& path, bool internal, std::set<std::string>& excludes, std::set<std::string>& includes) { - std::string cacheFile = path; - cacheFile += "/CMakeCache.txt"; + std::string cacheFile = cmStrCat(path, "/CMakeCache.txt"); // clear the old cache, if we are reading in internal values if (internal) { this->Cache.clear(); @@ -104,12 +102,10 @@ bool cmCacheManager::LoadCache(const std::string& path, bool internal, // not visible in the gui if (!internal) { e.Type = cmStateEnums::INTERNAL; - helpString = "DO NOT EDIT, "; - helpString += entryKey; - helpString += " loaded from external file. " - "To change this value edit this file: "; - helpString += path; - helpString += "/CMakeCache.txt"; + helpString = cmStrCat("DO NOT EDIT, ", entryKey, + " loaded from external file. " + "To change this value edit this file: ", + path, "/CMakeCache.txt"); e.SetProperty("HELPSTRING", helpString.c_str()); } if (!this->ReadPropertyEntry(entryKey, e)) { @@ -214,14 +210,11 @@ void cmCacheManager::WritePropertyEntries(std::ostream& os, CacheIterator i, { for (const char** p = cmCacheManager::PersistentProperties; *p; ++p) { if (const char* value = i.GetProperty(*p)) { - std::string helpstring = *p; - helpstring += " property for variable: "; - helpstring += i.GetName(); + std::string helpstring = + cmStrCat(*p, " property for variable: ", i.GetName()); cmCacheManager::OutputHelpString(os, helpstring); - std::string key = i.GetName(); - key += "-"; - key += *p; + std::string key = cmStrCat(i.GetName(), '-', *p); cmCacheManager::OutputKey(os, key); os << ":INTERNAL="; cmCacheManager::OutputValue(os, value); @@ -234,8 +227,7 @@ void cmCacheManager::WritePropertyEntries(std::ostream& os, CacheIterator i, bool cmCacheManager::SaveCache(const std::string& path, cmMessenger* messenger) { - std::string cacheFile = path; - cacheFile += "/CMakeCache.txt"; + std::string cacheFile = cmStrCat(path, "/CMakeCache.txt"); cmGeneratedFileStream fout(cacheFile); fout.SetCopyIfDifferent(true); if (!fout) { @@ -356,8 +348,7 @@ bool cmCacheManager::SaveCache(const std::string& path, cmMessenger* messenger) } fout << "\n"; fout.Close(); - std::string checkCacheFile = path; - checkCacheFile += "/CMakeFiles"; + std::string checkCacheFile = cmStrCat(path, "/CMakeFiles"); cmSystemTools::MakeDirectory(checkCacheFile); checkCacheFile += "/cmake.check_cache"; cmsys::ofstream checkCache(checkCacheFile.c_str()); @@ -473,15 +464,14 @@ void cmCacheManager::OutputNewlineTruncationWarning(std::ostream& fout, { if (value.find('\n') != std::string::npos) { if (messenger) { - std::string message = "Value of "; - message += key; - message += " contained a newline; truncating"; + std::string message = + cmStrCat("Value of ", key, " contained a newline; truncating"); messenger->IssueMessage(MessageType::WARNING, message); } - std::string comment = "WARNING: Value of "; - comment += key; - comment += " contained a newline and was truncated. Original value:"; + std::string comment = + cmStrCat("WARNING: Value of ", key, + " contained a newline and was truncated. Original value:"); OutputWarningComment(fout, comment, true); OutputWarningComment(fout, value, false); @@ -551,8 +541,7 @@ void cmCacheManager::AddCacheEntry(const std::string& key, const char* value, // make sure we only use unix style paths if (type == cmStateEnums::FILEPATH || type == cmStateEnums::PATH) { if (e.Value.find(';') != std::string::npos) { - std::vector<std::string> paths; - cmExpandList(e.Value, paths); + std::vector<std::string> paths = cmExpandedList(e.Value); const char* sep = ""; e.Value = ""; for (std::string& i : paths) { diff --git a/Source/cmCommandArgumentParserHelper.cxx b/Source/cmCommandArgumentParserHelper.cxx index 5583520..b368b3a 100644 --- a/Source/cmCommandArgumentParserHelper.cxx +++ b/Source/cmCommandArgumentParserHelper.cxx @@ -88,9 +88,7 @@ const char* cmCommandArgumentParserHelper::ExpandVariable(const char* var) return nullptr; } if (this->FileLine >= 0 && strcmp(var, "CMAKE_CURRENT_LIST_LINE") == 0) { - std::ostringstream ostr; - ostr << this->FileLine; - return this->AddString(ostr.str()); + return this->AddString(std::to_string(this->FileLine)); } const char* value = this->Makefile->GetDefinition(var); if (!value) { @@ -124,9 +122,7 @@ const char* cmCommandArgumentParserHelper::ExpandVariableForAt(const char* var) // - this->ReplaceAtSyntax is false // - this->ReplaceAtSyntax is true, but this->RemoveEmpty is false, // and the variable was not defined - std::string ref = "@"; - ref += var; - ref += "@"; + std::string ref = cmStrCat('@', var, '@'); return this->AddString(ref); } diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx index 8565e1c..702b743 100644 --- a/Source/cmCommands.cxx +++ b/Source/cmCommands.cxx @@ -78,6 +78,7 @@ #include "cmTargetCompileOptionsCommand.h" #include "cmTargetIncludeDirectoriesCommand.h" #include "cmTargetLinkLibrariesCommand.h" +#include "cmTargetPrecompileHeadersCommand.h" #include "cmTargetSourcesCommand.h" #include "cmTryCompileCommand.h" #include "cmTryRunCommand.h" @@ -116,18 +117,13 @@ void GetScriptingCommands(cmState* state) { - state->AddBuiltinCommand("break", cm::make_unique<cmBreakCommand>()); - state->AddBuiltinCommand("cmake_minimum_required", - cm::make_unique<cmCMakeMinimumRequired>()); - state->AddBuiltinCommand("cmake_policy", - cm::make_unique<cmCMakePolicyCommand>()); - state->AddBuiltinCommand("configure_file", - cm::make_unique<cmConfigureFileCommand>()); - state->AddBuiltinCommand("continue", cm::make_unique<cmContinueCommand>()); - state->AddBuiltinCommand("exec_program", - cm::make_unique<cmExecProgramCommand>()); - state->AddBuiltinCommand("execute_process", - cm::make_unique<cmExecuteProcessCommand>()); + state->AddBuiltinCommand("break", cmBreakCommand); + state->AddBuiltinCommand("cmake_minimum_required", cmCMakeMinimumRequired); + state->AddBuiltinCommand("cmake_policy", cmCMakePolicyCommand); + state->AddBuiltinCommand("configure_file", cmConfigureFileCommand); + state->AddBuiltinCommand("continue", cmContinueCommand); + state->AddBuiltinCommand("exec_program", cmExecProgramCommand); + state->AddBuiltinCommand("execute_process", cmExecuteProcessCommand); state->AddBuiltinCommand("file", cmFileCommand); state->AddBuiltinCommand("find_file", cm::make_unique<cmFindFileCommand>()); state->AddBuiltinCommand("find_library", @@ -137,42 +133,34 @@ void GetScriptingCommands(cmState* state) state->AddBuiltinCommand("find_path", cm::make_unique<cmFindPathCommand>()); state->AddBuiltinCommand("find_program", cm::make_unique<cmFindProgramCommand>()); - state->AddBuiltinCommand("foreach", cm::make_unique<cmForEachCommand>()); - state->AddBuiltinCommand("function", cm::make_unique<cmFunctionCommand>()); - state->AddBuiltinCommand("get_cmake_property", - cm::make_unique<cmGetCMakePropertyCommand>()); + state->AddBuiltinCommand("foreach", cmForEachCommand); + state->AddBuiltinCommand("function", cmFunctionCommand); + state->AddBuiltinCommand("get_cmake_property", cmGetCMakePropertyCommand); state->AddBuiltinCommand("get_directory_property", - cm::make_unique<cmGetDirectoryPropertyCommand>()); + cmGetDirectoryPropertyCommand); state->AddBuiltinCommand("get_filename_component", - cm::make_unique<cmGetFilenameComponentCommand>()); - state->AddBuiltinCommand("get_property", - cm::make_unique<cmGetPropertyCommand>()); + cmGetFilenameComponentCommand); + state->AddBuiltinCommand("get_property", cmGetPropertyCommand); state->AddBuiltinCommand("if", cmIfCommand); - state->AddBuiltinCommand("include", cm::make_unique<cmIncludeCommand>()); - state->AddBuiltinCommand("include_guard", - cm::make_unique<cmIncludeGuardCommand>()); - state->AddBuiltinCommand("list", cm::make_unique<cmListCommand>()); - state->AddBuiltinCommand("macro", cm::make_unique<cmMacroCommand>()); - state->AddBuiltinCommand("make_directory", - cm::make_unique<cmMakeDirectoryCommand>()); - state->AddBuiltinCommand("mark_as_advanced", - cm::make_unique<cmMarkAsAdvancedCommand>()); - state->AddBuiltinCommand("math", cm::make_unique<cmMathCommand>()); - state->AddBuiltinCommand("message", cm::make_unique<cmMessageCommand>()); - state->AddBuiltinCommand("option", cm::make_unique<cmOptionCommand>()); - state->AddBuiltinCommand("cmake_parse_arguments", - cm::make_unique<cmParseArgumentsCommand>()); + state->AddBuiltinCommand("include", cmIncludeCommand); + state->AddBuiltinCommand("include_guard", cmIncludeGuardCommand); + state->AddBuiltinCommand("list", cmListCommand); + state->AddBuiltinCommand("macro", cmMacroCommand); + state->AddBuiltinCommand("make_directory", cmMakeDirectoryCommand); + state->AddBuiltinCommand("mark_as_advanced", cmMarkAsAdvancedCommand); + state->AddBuiltinCommand("math", cmMathCommand); + state->AddBuiltinCommand("message", cmMessageCommand); + state->AddBuiltinCommand("option", cmOptionCommand); + state->AddBuiltinCommand("cmake_parse_arguments", cmParseArgumentsCommand); state->AddBuiltinCommand("return", cmReturnCommand); - state->AddBuiltinCommand("separate_arguments", - cm::make_unique<cmSeparateArgumentsCommand>()); - state->AddBuiltinCommand("set", cm::make_unique<cmSetCommand>()); + state->AddBuiltinCommand("separate_arguments", cmSeparateArgumentsCommand); + state->AddBuiltinCommand("set", cmSetCommand); state->AddBuiltinCommand("set_directory_properties", - cm::make_unique<cmSetDirectoryPropertiesCommand>()); - state->AddBuiltinCommand("set_property", - cm::make_unique<cmSetPropertyCommand>()); - state->AddBuiltinCommand("site_name", cm::make_unique<cmSiteNameCommand>()); - state->AddBuiltinCommand("string", cm::make_unique<cmStringCommand>()); - state->AddBuiltinCommand("unset", cm::make_unique<cmUnsetCommand>()); + cmSetDirectoryPropertiesCommand); + state->AddBuiltinCommand("set_property", cmSetPropertyCommand); + state->AddBuiltinCommand("site_name", cmSiteNameCommand); + state->AddBuiltinCommand("string", cmStringCommand); + state->AddBuiltinCommand("unset", cmUnsetCommand); state->AddBuiltinCommand("while", cmWhileCommand); state->AddUnexpectedCommand( @@ -211,21 +199,17 @@ void GetScriptingCommands(cmState* state) "match the opening WHILE command."); #if !defined(CMAKE_BOOTSTRAP) - state->AddBuiltinCommand( - "cmake_host_system_information", - cm::make_unique<cmCMakeHostSystemInformationCommand>()); - state->AddBuiltinCommand("remove", cm::make_unique<cmRemoveCommand>()); - state->AddBuiltinCommand("variable_watch", - cm::make_unique<cmVariableWatchCommand>()); - state->AddBuiltinCommand("write_file", - cm::make_unique<cmWriteFileCommand>()); + state->AddBuiltinCommand("cmake_host_system_information", + cmCMakeHostSystemInformationCommand); + state->AddBuiltinCommand("remove", cmRemoveCommand); + state->AddBuiltinCommand("variable_watch", cmVariableWatchCommand); + state->AddBuiltinCommand("write_file", cmWriteFileCommand); state->AddDisallowedCommand( - "build_name", cm::make_unique<cmBuildNameCommand>(), cmPolicies::CMP0036, + "build_name", cmBuildNameCommand, cmPolicies::CMP0036, "The build_name command should not be called; see CMP0036."); state->AddDisallowedCommand( - "use_mangled_mesa", cm::make_unique<cmUseMangledMesaCommand>(), - cmPolicies::CMP0030, + "use_mangled_mesa", cmUseMangledMesaCommand, cmPolicies::CMP0030, "The use_mangled_mesa command should not be called; see CMP0030."); #endif @@ -293,6 +277,9 @@ void GetProjectCommands(cmState* state) state->AddBuiltinCommand("try_compile", cm::make_unique<cmTryCompileCommand>()); state->AddBuiltinCommand("try_run", cm::make_unique<cmTryRunCommand>()); + state->AddBuiltinCommand( + "target_precompile_headers", + cm::make_unique<cmTargetPrecompileHeadersCommand>()); #if !defined(CMAKE_BOOTSTRAP) state->AddBuiltinCommand("add_compile_definitions", @@ -326,29 +313,24 @@ void GetProjectCommands(cmState* state) cm::make_unique<cmSourceGroupCommand>()); state->AddDisallowedCommand( - "export_library_dependencies", - cm::make_unique<cmExportLibraryDependenciesCommand>(), cmPolicies::CMP0033, + "export_library_dependencies", cmExportLibraryDependenciesCommand, + cmPolicies::CMP0033, "The export_library_dependencies command should not be called; " "see CMP0033."); state->AddDisallowedCommand( - "load_command", cm::make_unique<cmLoadCommandCommand>(), - cmPolicies::CMP0031, + "load_command", cmLoadCommandCommand, cmPolicies::CMP0031, "The load_command command should not be called; see CMP0031."); state->AddDisallowedCommand( - "output_required_files", cm::make_unique<cmOutputRequiredFilesCommand>(), - cmPolicies::CMP0032, + "output_required_files", cmOutputRequiredFilesCommand, cmPolicies::CMP0032, "The output_required_files command should not be called; see CMP0032."); state->AddDisallowedCommand( - "subdir_depends", cm::make_unique<cmSubdirDependsCommand>(), - cmPolicies::CMP0029, + "subdir_depends", cmSubdirDependsCommand, cmPolicies::CMP0029, "The subdir_depends command should not be called; see CMP0029."); state->AddDisallowedCommand( - "utility_source", cm::make_unique<cmUtilitySourceCommand>(), - cmPolicies::CMP0034, + "utility_source", cmUtilitySourceCommand, cmPolicies::CMP0034, "The utility_source command should not be called; see CMP0034."); state->AddDisallowedCommand( - "variable_requires", cm::make_unique<cmVariableRequiresCommand>(), - cmPolicies::CMP0035, + "variable_requires", cmVariableRequiresCommand, cmPolicies::CMP0035, "The variable_requires command should not be called; see CMP0035."); #endif } diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx index 61880c2..49db505 100644 --- a/Source/cmCommonTargetGenerator.cxx +++ b/Source/cmCommonTargetGenerator.cxx @@ -59,10 +59,11 @@ void cmCommonTargetGenerator::AddModuleDefinitionFlag( // Append the flag and value. Use ConvertToLinkReference to help // vs6's "cl -link" pass it to the linker. - std::string flag = defFileFlag; - flag += this->LocalCommonGenerator->ConvertToOutputFormat( - linkLineComputer->ConvertToLinkReference(mdi->DefFile), - cmOutputConverter::SHELL); + std::string flag = + cmStrCat(defFileFlag, + this->LocalCommonGenerator->ConvertToOutputFormat( + linkLineComputer->ConvertToLinkReference(mdi->DefFile), + cmOutputConverter::SHELL)); this->LocalCommonGenerator->AppendFlags(flags, flag); } @@ -155,9 +156,8 @@ std::vector<std::string> cmCommonTargetGenerator::GetLinkedTargetDirectories() && linkee->GetType() != cmStateEnums::INTERFACE_LIBRARY && emitted.insert(linkee).second) { cmLocalGenerator* lg = linkee->GetLocalGenerator(); - std::string di = lg->GetCurrentBinaryDirectory(); - di += "/"; - di += lg->GetTargetDirectory(linkee); + std::string di = cmStrCat(lg->GetCurrentBinaryDirectory(), '/', + lg->GetTargetDirectory(linkee)); dirs.push_back(std::move(di)); } } @@ -210,11 +210,7 @@ void cmCommonTargetGenerator::AppendOSXVerFlag(std::string& flags, const char* name, bool so) { // Lookup the flag to specify the version. - std::string fvar = "CMAKE_"; - fvar += lang; - fvar += "_OSX_"; - fvar += name; - fvar += "_VERSION_FLAG"; + std::string fvar = cmStrCat("CMAKE_", lang, "_OSX_", name, "_VERSION_FLAG"); const char* flag = this->Makefile->GetDefinition(fvar); // Skip if no such flag. diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx index a187f99..a39425c 100644 --- a/Source/cmComputeLinkDepends.cxx +++ b/Source/cmComputeLinkDepends.cxx @@ -319,8 +319,7 @@ int cmComputeLinkDepends::AddLinkEntry(cmLinkItem const& item) this->BFSQueue.push(qe); } else { // Look for an old-style <item>_LIB_DEPENDS variable. - std::string var = entry.Item; - var += "_LIB_DEPENDS"; + std::string var = cmStrCat(entry.Item, "_LIB_DEPENDS"); if (const char* val = this->Makefile->GetDefinition(var)) { // The item dependencies are known. Follow them. BFSEntry qe = { index, val }; @@ -437,8 +436,7 @@ void cmComputeLinkDepends::AddVarLinkEntries(int depender_index, // This is called to add the dependencies named by // <item>_LIB_DEPENDS. The variable contains a semicolon-separated // list. The list contains link-type;item pairs and just items. - std::vector<std::string> deplist; - cmExpandList(value, deplist); + std::vector<std::string> deplist = cmExpandedList(value); // Look for entries meant for this configuration. std::vector<cmLinkItem> actual_libs; @@ -461,8 +459,7 @@ void cmComputeLinkDepends::AddVarLinkEntries(int depender_index, // the export_library_dependencies command from CMake 2.4 and // lower. if (!haveLLT) { - std::string var = d; - var += "_LINK_TYPE"; + std::string var = cmStrCat(d, "_LINK_TYPE"); if (const char* val = this->Makefile->GetDefinition(var)) { if (strcmp(val, "debug") == 0) { llt = DEBUG_LibraryType; diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index 4273383..dd8d246 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -2,6 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmComputeLinkInformation.h" +#include "cmAlgorithms.h" #include "cmComputeLinkDepends.h" #include "cmGeneratorTarget.h" #include "cmGlobalGenerator.h" @@ -278,9 +279,8 @@ cmComputeLinkInformation::cmComputeLinkInformation( this->LoaderFlag = nullptr; if (!this->Target->IsDLLPlatform() && this->Target->GetType() == cmStateEnums::MODULE_LIBRARY) { - std::string loader_flag_var = "CMAKE_SHARED_MODULE_LOADER_"; - loader_flag_var += this->LinkLanguage; - loader_flag_var += "_FLAG"; + std::string loader_flag_var = + cmStrCat("CMAKE_SHARED_MODULE_LOADER_", this->LinkLanguage, "_FLAG"); this->LoaderFlag = this->Makefile->GetDefinition(loader_flag_var); } @@ -292,10 +292,20 @@ cmComputeLinkInformation::cmComputeLinkInformation( this->LibLinkFlag = this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_FLAG"); } - this->LibLinkFileFlag = - this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_FILE_FLAG"); - this->LibLinkSuffix = - this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_SUFFIX"); + if (const char* flag = this->Makefile->GetDefinition( + "CMAKE_" + this->LinkLanguage + "_LINK_LIBRARY_FILE_FLAG")) { + this->LibLinkFileFlag = flag; + } else { + this->LibLinkFileFlag = + this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_FILE_FLAG"); + } + if (const char* suffix = this->Makefile->GetDefinition( + "CMAKE_" + this->LinkLanguage + "_LINK_LIBRARY_SUFFIX")) { + this->LibLinkSuffix = suffix; + } else { + this->LibLinkSuffix = + this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_SUFFIX"); + } // Get options needed to specify RPATHs. this->RuntimeUseChrpath = false; @@ -303,11 +313,8 @@ cmComputeLinkInformation::cmComputeLinkInformation( const char* tType = ((this->Target->GetType() == cmStateEnums::EXECUTABLE) ? "EXECUTABLE" : "SHARED_LIBRARY"); - std::string rtVar = "CMAKE_"; - rtVar += tType; - rtVar += "_RUNTIME_"; - rtVar += this->LinkLanguage; - rtVar += "_FLAG"; + std::string rtVar = + cmStrCat("CMAKE_", tType, "_RUNTIME_", this->LinkLanguage, "_FLAG"); std::string rtSepVar = rtVar + "_SEP"; this->RuntimeFlag = this->Makefile->GetSafeDefinition(rtVar); this->RuntimeSep = this->Makefile->GetSafeDefinition(rtSepVar); @@ -317,19 +324,15 @@ cmComputeLinkInformation::cmComputeLinkInformation( this->RuntimeUseChrpath = this->Target->IsChrpathUsed(config); // Get options needed to help find dependent libraries. - std::string rlVar = "CMAKE_"; - rlVar += tType; - rlVar += "_RPATH_LINK_"; - rlVar += this->LinkLanguage; - rlVar += "_FLAG"; + std::string rlVar = + cmStrCat("CMAKE_", tType, "_RPATH_LINK_", this->LinkLanguage, "_FLAG"); this->RPathLinkFlag = this->Makefile->GetSafeDefinition(rlVar); } // Check if we need to include the runtime search path at link time. { - std::string var = "CMAKE_SHARED_LIBRARY_LINK_"; - var += this->LinkLanguage; - var += "_WITH_RUNTIME_PATH"; + std::string var = cmStrCat("CMAKE_SHARED_LIBRARY_LINK_", + this->LinkLanguage, "_WITH_RUNTIME_PATH"); this->LinkWithRuntimePath = this->Makefile->IsOn(var); } @@ -546,14 +549,11 @@ void cmComputeLinkInformation::AddImplicitLinkInfo(std::string const& lang) { // Add libraries for this language that are not implied by the // linker language. - std::string libVar = "CMAKE_"; - libVar += lang; - libVar += "_IMPLICIT_LINK_LIBRARIES"; + std::string libVar = cmStrCat("CMAKE_", lang, "_IMPLICIT_LINK_LIBRARIES"); if (const char* libs = this->Makefile->GetDefinition(libVar)) { - std::vector<std::string> libsVec; - cmExpandList(libs, libsVec); + std::vector<std::string> libsVec = cmExpandedList(libs); for (std::string const& i : libsVec) { - if (this->ImplicitLinkLibs.find(i) == this->ImplicitLinkLibs.end()) { + if (!cmContains(this->ImplicitLinkLibs, i)) { this->AddItem(i, nullptr); } } @@ -561,12 +561,9 @@ void cmComputeLinkInformation::AddImplicitLinkInfo(std::string const& lang) // Add linker search paths for this language that are not // implied by the linker language. - std::string dirVar = "CMAKE_"; - dirVar += lang; - dirVar += "_IMPLICIT_LINK_DIRECTORIES"; + std::string dirVar = cmStrCat("CMAKE_", lang, "_IMPLICIT_LINK_DIRECTORIES"); if (const char* dirs = this->Makefile->GetDefinition(dirVar)) { - std::vector<std::string> dirsVec; - cmExpandList(dirs, dirsVec); + std::vector<std::string> dirsVec = cmExpandedList(dirs); this->OrderLinkerSearchPath->AddLanguageDirectories(dirsVec); } } @@ -759,19 +756,15 @@ void cmComputeLinkInformation::ComputeLinkTypeInfo() break; } if (target_type_str) { - std::string static_link_type_flag_var = "CMAKE_"; - static_link_type_flag_var += target_type_str; - static_link_type_flag_var += "_LINK_STATIC_"; - static_link_type_flag_var += this->LinkLanguage; - static_link_type_flag_var += "_FLAGS"; + std::string static_link_type_flag_var = + cmStrCat("CMAKE_", target_type_str, "_LINK_STATIC_", this->LinkLanguage, + "_FLAGS"); static_link_type_flag = this->Makefile->GetDefinition(static_link_type_flag_var); - std::string shared_link_type_flag_var = "CMAKE_"; - shared_link_type_flag_var += target_type_str; - shared_link_type_flag_var += "_LINK_DYNAMIC_"; - shared_link_type_flag_var += this->LinkLanguage; - shared_link_type_flag_var += "_FLAGS"; + std::string shared_link_type_flag_var = + cmStrCat("CMAKE_", target_type_str, "_LINK_DYNAMIC_", this->LinkLanguage, + "_FLAGS"); shared_link_type_flag = this->Makefile->GetDefinition(shared_link_type_flag_var); } @@ -810,16 +803,14 @@ void cmComputeLinkInformation::ComputeItemParserInfo() LinkUnknown); if (const char* linkSuffixes = mf->GetDefinition("CMAKE_EXTRA_LINK_EXTENSIONS")) { - std::vector<std::string> linkSuffixVec; - cmExpandList(linkSuffixes, linkSuffixVec); + std::vector<std::string> linkSuffixVec = cmExpandedList(linkSuffixes); for (std::string const& i : linkSuffixVec) { this->AddLinkExtension(i.c_str(), LinkUnknown); } } if (const char* sharedSuffixes = mf->GetDefinition("CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES")) { - std::vector<std::string> sharedSuffixVec; - cmExpandList(sharedSuffixes, sharedSuffixVec); + std::vector<std::string> sharedSuffixVec = cmExpandedList(sharedSuffixes); for (std::string const& i : sharedSuffixVec) { this->AddLinkExtension(i.c_str(), LinkShared); } @@ -847,8 +838,7 @@ void cmComputeLinkInformation::ComputeItemParserInfo() reg += "([^/:]*)"; // Create a regex to match any library name. - std::string reg_any = reg; - reg_any += libext; + std::string reg_any = cmStrCat(reg, libext); #ifdef CM_COMPUTE_LINK_INFO_DEBUG fprintf(stderr, "any regex [%s]\n", reg_any.c_str()); #endif @@ -856,9 +846,8 @@ void cmComputeLinkInformation::ComputeItemParserInfo() // Create a regex to match static library names. if (!this->StaticLinkExtensions.empty()) { - std::string reg_static = reg; - reg_static += - this->CreateExtensionRegex(this->StaticLinkExtensions, LinkStatic); + std::string reg_static = cmStrCat( + reg, this->CreateExtensionRegex(this->StaticLinkExtensions, LinkStatic)); #ifdef CM_COMPUTE_LINK_INFO_DEBUG fprintf(stderr, "static regex [%s]\n", reg_static.c_str()); #endif @@ -998,8 +987,8 @@ void cmComputeLinkInformation::AddTargetItem(std::string const& item, // For compatibility with CMake 2.4 include the item's directory in // the linker search path. if (this->OldLinkDirMode && !target->IsFrameworkOnApple() && - this->OldLinkDirMask.find(cmSystemTools::GetFilenamePath(item)) == - this->OldLinkDirMask.end()) { + !cmContains(this->OldLinkDirMask, + cmSystemTools::GetFilenamePath(item))) { this->OldLinkDirItems.push_back(item); } @@ -1052,8 +1041,8 @@ void cmComputeLinkInformation::AddFullItem(std::string const& item) // For compatibility with CMake 2.4 include the item's directory in // the linker search path. if (this->OldLinkDirMode && - this->OldLinkDirMask.find(cmSystemTools::GetFilenamePath(item)) == - this->OldLinkDirMask.end()) { + !cmContains(this->OldLinkDirMask, + cmSystemTools::GetFilenamePath(item))) { this->OldLinkDirItems.push_back(item); } @@ -1072,7 +1061,7 @@ bool cmComputeLinkInformation::CheckImplicitDirItem(std::string const& item) // Check if this item is in an implicit link directory. std::string dir = cmSystemTools::GetFilenamePath(item); - if (this->ImplicitLinkDirs.find(dir) == this->ImplicitLinkDirs.end()) { + if (!cmContains(this->ImplicitLinkDirs, dir)) { // Only libraries in implicit link directories are converted to // pathless items. return false; @@ -1214,9 +1203,7 @@ void cmComputeLinkInformation::AddUserItem(std::string const& item, } // Create an option to ask the linker to search for the library. - std::string out = this->LibLinkFlag; - out += lib; - out += this->LibLinkSuffix; + std::string out = cmStrCat(this->LibLinkFlag, lib, this->LibLinkSuffix); this->Items.emplace_back(out, false); // Here we could try to find the library the linker will find and @@ -1238,12 +1225,7 @@ void cmComputeLinkInformation::AddFrameworkItem(std::string const& item) std::string fw_path = this->SplitFramework.match(1); std::string fw = this->SplitFramework.match(2); - std::string full_fw = fw_path; - full_fw += "/"; - full_fw += fw; - full_fw += ".framework"; - full_fw += "/"; - full_fw += fw; + std::string full_fw = cmStrCat(fw_path, '/', fw, ".framework/", fw); // Add the directory portion to the framework search path. this->AddFrameworkPath(fw_path); @@ -1292,9 +1274,8 @@ void cmComputeLinkInformation::ComputeFrameworkInfo() } // Get language-specific implicit directories. - std::string implicitDirVar = "CMAKE_"; - implicitDirVar += this->LinkLanguage; - implicitDirVar += "_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES"; + std::string implicitDirVar = cmStrCat( + "CMAKE_", this->LinkLanguage, "_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES"); if (const char* implicitDirs = this->Makefile->GetDefinition(implicitDirVar)) { cmExpandList(implicitDirs, implicitDirVec); @@ -1367,8 +1348,7 @@ void cmComputeLinkInformation::HandleBadFullItem(std::string const& item, switch (this->Target->GetPolicyStatusCMP0008()) { case cmPolicies::WARN: { // Print the warning at most once for this item. - std::string wid = "CMP0008-WARNING-GIVEN-"; - wid += item; + std::string wid = cmStrCat("CMP0008-WARNING-GIVEN-", item); if (!this->CMakeInstance->GetState()->GetGlobalPropertyAsBool(wid)) { this->CMakeInstance->GetState()->SetGlobalProperty(wid, "1"); std::ostringstream w; @@ -1529,9 +1509,8 @@ void cmComputeLinkInformation::LoadImplicitLinkInfo() } // Get language-specific implicit directories. - std::string implicitDirVar = "CMAKE_"; - implicitDirVar += this->LinkLanguage; - implicitDirVar += "_IMPLICIT_LINK_DIRECTORIES"; + std::string implicitDirVar = + cmStrCat("CMAKE_", this->LinkLanguage, "_IMPLICIT_LINK_DIRECTORIES"); if (const char* implicitDirs = this->Makefile->GetDefinition(implicitDirVar)) { cmExpandList(implicitDirs, implicitDirVec); @@ -1542,9 +1521,8 @@ void cmComputeLinkInformation::LoadImplicitLinkInfo() // Get language-specific implicit libraries. std::vector<std::string> implicitLibVec; - std::string implicitLibVar = "CMAKE_"; - implicitLibVar += this->LinkLanguage; - implicitLibVar += "_IMPLICIT_LINK_LIBRARIES"; + std::string implicitLibVar = + cmStrCat("CMAKE_", this->LinkLanguage, "_IMPLICIT_LINK_LIBRARIES"); if (const char* implicitLibs = this->Makefile->GetDefinition(implicitLibVar)) { cmExpandList(implicitLibs, implicitLibVec); @@ -1668,8 +1646,7 @@ static void cmCLI_ExpandListUnique(const char* str, std::vector<std::string>& out, std::set<std::string>& emitted) { - std::vector<std::string> tmp; - cmExpandList(str, tmp); + std::vector<std::string> tmp = cmExpandedList(str); for (std::string const& i : tmp) { if (emitted.insert(i).second) { out.push_back(i); @@ -1748,9 +1725,7 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs, d = d.substr(rootPath.size()); } else if (stagePath && *stagePath && d.find(stagePath) == 0) { std::string suffix = d.substr(strlen(stagePath)); - d = installPrefix; - d += "/"; - d += suffix; + d = cmStrCat(installPrefix, '/', suffix); cmSystemTools::ConvertToUnixSlashes(d); } else if (use_relative_build_rpath) { // If expansion of the $ORIGIN token is supported and permitted per @@ -1781,9 +1756,7 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs, d = d.substr(rootPath.size()); } else if (stagePath && *stagePath && d.find(stagePath) == 0) { std::string suffix = d.substr(strlen(stagePath)); - d = installPrefix; - d += "/"; - d += suffix; + d = cmStrCat(installPrefix, '/', suffix); cmSystemTools::ConvertToUnixSlashes(d); } if (emitted.insert(d).second) { diff --git a/Source/cmConditionEvaluator.cxx b/Source/cmConditionEvaluator.cxx index 3de3253..21df278 100644 --- a/Source/cmConditionEvaluator.cxx +++ b/Source/cmConditionEvaluator.cxx @@ -3,7 +3,6 @@ #include "cmConditionEvaluator.h" #include "cmsys/RegularExpression.hxx" -#include <algorithm> #include <functional> #include <sstream> #include <stdio.h> @@ -669,10 +668,9 @@ bool cmConditionEvaluator::HandleLevel2(cmArgumentList& newArgs, def2 = this->Makefile.GetDefinition(argP2->GetValue()); if (def2) { - std::vector<std::string> list; - cmExpandList(def2, list, true); + std::vector<std::string> list = cmExpandedList(def2, true); - result = std::find(list.begin(), list.end(), def) != list.end(); + result = cmContains(list, def); } this->HandleBinaryOp(result, reducible, arg, newArgs, argP1, argP2); diff --git a/Source/cmConfigure.cmake.h.in b/Source/cmConfigure.cmake.h.in index 19b1cd4..4de1c5d 100644 --- a/Source/cmConfigure.cmake.h.in +++ b/Source/cmConfigure.cmake.h.in @@ -26,4 +26,8 @@ #define CM_FALLTHROUGH cmsys_FALLTHROUGH +#if defined(_WIN32) && !defined(NOMINMAX) +# define NOMINMAX +#endif + #endif diff --git a/Source/cmConfigureFileCommand.cxx b/Source/cmConfigureFileCommand.cxx index 0917d11..7e37f32 100644 --- a/Source/cmConfigureFileCommand.cxx +++ b/Source/cmConfigureFileCommand.cxx @@ -4,76 +4,78 @@ #include <sstream> +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmMessageType.h" +#include "cmNewLineStyle.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" -class cmExecutionStatus; - // cmConfigureFileCommand -bool cmConfigureFileCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmConfigureFileCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() < 2) { - this->SetError("called with incorrect number of arguments, expected 2"); + status.SetError("called with incorrect number of arguments, expected 2"); return false; } std::string const& inFile = args[0]; - this->InputFile = cmSystemTools::CollapseFullPath( - inFile, this->Makefile->GetCurrentSourceDirectory()); + const std::string inputFile = cmSystemTools::CollapseFullPath( + inFile, status.GetMakefile().GetCurrentSourceDirectory()); // If the input location is a directory, error out. - if (cmSystemTools::FileIsDirectory(this->InputFile)) { + if (cmSystemTools::FileIsDirectory(inputFile)) { std::ostringstream e; /* clang-format off */ e << "input location\n" - << " " << this->InputFile << "\n" + << " " << inputFile << "\n" << "is a directory but a file was expected."; /* clang-format on */ - this->SetError(e.str()); + status.SetError(e.str()); return false; } std::string const& outFile = args[1]; - this->OutputFile = cmSystemTools::CollapseFullPath( - outFile, this->Makefile->GetCurrentBinaryDirectory()); + std::string outputFile = cmSystemTools::CollapseFullPath( + outFile, status.GetMakefile().GetCurrentBinaryDirectory()); // If the output location is already a directory put the file in it. - if (cmSystemTools::FileIsDirectory(this->OutputFile)) { - this->OutputFile += "/"; - this->OutputFile += cmSystemTools::GetFilenameName(inFile); + if (cmSystemTools::FileIsDirectory(outputFile)) { + outputFile += "/"; + outputFile += cmSystemTools::GetFilenameName(inFile); } - if (!this->Makefile->CanIWriteThisFile(this->OutputFile)) { - std::string e = "attempted to configure a file: " + this->OutputFile + + if (!status.GetMakefile().CanIWriteThisFile(outputFile)) { + std::string e = "attempted to configure a file: " + outputFile + " into a source directory."; - this->SetError(e); + status.SetError(e); cmSystemTools::SetFatalErrorOccured(); return false; } std::string errorMessage; - if (!this->NewLineStyle.ReadFromArguments(args, errorMessage)) { - this->SetError(errorMessage); + cmNewLineStyle newLineStyle; + if (!newLineStyle.ReadFromArguments(args, errorMessage)) { + status.SetError(errorMessage); return false; } - this->CopyOnly = false; - this->EscapeQuotes = false; + bool copyOnly = false; + bool escapeQuotes = false; std::string unknown_args; - this->AtOnly = false; + bool atOnly = false; for (unsigned int i = 2; i < args.size(); ++i) { if (args[i] == "COPYONLY") { - this->CopyOnly = true; - if (this->NewLineStyle.IsValid()) { - this->SetError("COPYONLY could not be used in combination " - "with NEWLINE_STYLE"); + copyOnly = true; + if (newLineStyle.IsValid()) { + status.SetError("COPYONLY could not be used in combination " + "with NEWLINE_STYLE"); return false; } } else if (args[i] == "ESCAPE_QUOTES") { - this->EscapeQuotes = true; + escapeQuotes = true; } else if (args[i] == "@ONLY") { - this->AtOnly = true; + atOnly = true; } else if (args[i] == "IMMEDIATE") { /* Ignore legacy option. */ } else if (args[i] == "NEWLINE_STYLE" || args[i] == "LF" || @@ -87,22 +89,16 @@ bool cmConfigureFileCommand::InitialPass(std::vector<std::string> const& args, } } if (!unknown_args.empty()) { - std::string msg = "configure_file called with unknown argument(s):\n"; - msg += unknown_args; - this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, msg); + std::string msg = cmStrCat( + "configure_file called with unknown argument(s):\n", unknown_args); + status.GetMakefile().IssueMessage(MessageType::AUTHOR_WARNING, msg); } - if (!this->ConfigureFile()) { - this->SetError("Problem configuring file"); + if (!status.GetMakefile().ConfigureFile( + inputFile, outputFile, copyOnly, atOnly, escapeQuotes, newLineStyle)) { + status.SetError("Problem configuring file"); return false; } return true; } - -int cmConfigureFileCommand::ConfigureFile() -{ - return this->Makefile->ConfigureFile(this->InputFile, this->OutputFile, - this->CopyOnly, this->AtOnly, - this->EscapeQuotes, this->NewLineStyle); -} diff --git a/Source/cmConfigureFileCommand.h b/Source/cmConfigureFileCommand.h index b3a99d7..c7f95b8 100644 --- a/Source/cmConfigureFileCommand.h +++ b/Source/cmConfigureFileCommand.h @@ -8,38 +8,8 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" -#include "cmNewLineStyle.h" - class cmExecutionStatus; -class cmConfigureFileCommand : public cmCommand -{ -public: - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmConfigureFileCommand>(); - } - - /** - * This is called when the command is first encountered in - * the input file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; - -private: - int ConfigureFile(); - - cmNewLineStyle NewLineStyle; - - std::string InputFile; - std::string OutputFile; - bool CopyOnly = false; - bool EscapeQuotes = false; - bool AtOnly = false; -}; - +bool cmConfigureFileCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmContinueCommand.cxx b/Source/cmContinueCommand.cxx index 48f1f41..bb63dff 100644 --- a/Source/cmContinueCommand.cxx +++ b/Source/cmContinueCommand.cxx @@ -8,13 +8,14 @@ #include "cmSystemTools.h" // cmContinueCommand -bool cmContinueCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) +bool cmContinueCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { - if (!this->Makefile->IsLoopBlock()) { - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, - "A CONTINUE command was found outside of a " - "proper FOREACH or WHILE loop scope."); + if (!status.GetMakefile().IsLoopBlock()) { + status.GetMakefile().IssueMessage( + MessageType::FATAL_ERROR, + "A CONTINUE command was found outside of a " + "proper FOREACH or WHILE loop scope."); cmSystemTools::SetFatalErrorOccured(); return true; } @@ -22,9 +23,10 @@ bool cmContinueCommand::InitialPass(std::vector<std::string> const& args, status.SetContinueInvoked(); if (!args.empty()) { - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, - "The CONTINUE command does not accept any " - "arguments."); + status.GetMakefile().IssueMessage( + MessageType::FATAL_ERROR, + "The CONTINUE command does not accept any " + "arguments."); cmSystemTools::SetFatalErrorOccured(); return true; } diff --git a/Source/cmContinueCommand.h b/Source/cmContinueCommand.h index a85010a..ff903aa 100644 --- a/Source/cmContinueCommand.h +++ b/Source/cmContinueCommand.h @@ -8,34 +8,14 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmContinueCommand +/** * \brief Continue from an enclosing foreach or while loop * * cmContinueCommand returns from an enclosing foreach or while loop */ -class cmContinueCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmContinueCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; +bool cmContinueCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx index e5e1ecf..3687056 100644 --- a/Source/cmCoreTryCompile.cxx +++ b/Source/cmCoreTryCompile.cxx @@ -674,8 +674,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv, if (const char* varListStr = this->Makefile->GetDefinition( kCMAKE_TRY_COMPILE_PLATFORM_VARIABLES)) { - std::vector<std::string> varList; - cmExpandList(varListStr, varList); + std::vector<std::string> varList = cmExpandedList(varListStr); vars.insert(varList.begin(), varList.end()); } @@ -1045,16 +1044,14 @@ void cmCoreTryCompile::FindOutputFile(const std::string& targetName, this->Makefile->GetDefinition("CMAKE_TRY_COMPILE_CONFIGURATION"); // if a config was specified try that first if (config && config[0]) { - std::string tmp = "/"; - tmp += config; + std::string tmp = cmStrCat('/', config); searchDirs.push_back(std::move(tmp)); } searchDirs.emplace_back("/Debug"); #if defined(__APPLE__) std::string app = "/" + targetName + ".app"; if (config && config[0]) { - std::string tmp = "/"; - tmp += config + app; + std::string tmp = cmStrCat('/', config, app); searchDirs.push_back(std::move(tmp)); } std::string tmp = "/Debug" + app; @@ -1064,9 +1061,7 @@ void cmCoreTryCompile::FindOutputFile(const std::string& targetName, searchDirs.emplace_back("/Development"); for (std::string const& sdir : searchDirs) { - std::string command = this->BinaryDirectory; - command += sdir; - command += tmpOutputFile; + std::string command = cmStrCat(this->BinaryDirectory, sdir, tmpOutputFile); if (cmSystemTools::FileExists(command)) { this->OutputFile = cmSystemTools::CollapseFullPath(command); return; diff --git a/Source/cmCreateTestSourceList.cxx b/Source/cmCreateTestSourceList.cxx index 427db72..4a1825f 100644 --- a/Source/cmCreateTestSourceList.cxx +++ b/Source/cmCreateTestSourceList.cxx @@ -6,6 +6,7 @@ #include "cmMakefile.h" #include "cmSourceFile.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" class cmExecutionStatus; @@ -31,17 +32,14 @@ bool cmCreateTestSourceList::InitialPass(std::vector<std::string> const& args, this->SetError("incorrect arguments to EXTRA_INCLUDE"); return false; } - extraInclude = "#include \""; - extraInclude += *i; - extraInclude += "\"\n"; + extraInclude = cmStrCat("#include \"", *i, "\"\n"); } else if (*i == "FUNCTION") { ++i; if (i == args.end()) { this->SetError("incorrect arguments to FUNCTION"); return false; } - function = *i; - function += "(&ac, &av);\n"; + function = cmStrCat(*i, "(&ac, &av);\n"); } else { tests.push_back(*i); } @@ -60,9 +58,8 @@ bool cmCreateTestSourceList::InitialPass(std::vector<std::string> const& args, "You must specify a file extension for the test driver file."); return false; } - std::string driver = this->Makefile->GetCurrentBinaryDirectory(); - driver += "/"; - driver += *i; + std::string driver = + cmStrCat(this->Makefile->GetCurrentBinaryDirectory(), '/', *i); ++i; std::string configFile = cmSystemTools::GetCMakeRoot(); diff --git a/Source/cmCurl.cxx b/Source/cmCurl.cxx index 0004f66..233790e 100644 --- a/Source/cmCurl.cxx +++ b/Source/cmCurl.cxx @@ -7,6 +7,7 @@ # define CMAKE_FIND_CAFILE # include "cmSystemTools.h" #endif +#include "cmStringAlgorithms.h" // curl versions before 7.21.5 did not provide this error code #if defined(LIBCURL_VERSION_NUM) && LIBCURL_VERSION_NUM < 0x071505 @@ -72,8 +73,8 @@ std::string cmCurlSetNETRCOption(::CURL* curl, const std::string& netrc_level, } else if (netrc_level == "IGNORED") { curl_netrc_level = CURL_NETRC_IGNORED; } else { - e = "NETRC accepts OPTIONAL, IGNORED or REQUIRED but got: "; - e += netrc_level; + e = cmStrCat("NETRC accepts OPTIONAL, IGNORED or REQUIRED but got: ", + netrc_level); return e; } } diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx index 20f0ef2..82cc037 100644 --- a/Source/cmCustomCommandGenerator.cxx +++ b/Source/cmCustomCommandGenerator.cxx @@ -169,9 +169,7 @@ std::string escapeForShellOldStyle(const std::string& str) std::string temp = str; if (temp.find(" ") != std::string::npos && temp.find("\"") == std::string::npos) { - result = "\""; - result += str; - result += "\""; + result = cmStrCat('"', str, '"'); return result; } return str; diff --git a/Source/cmDefinitions.cxx b/Source/cmDefinitions.cxx index cc38d84..e688890 100644 --- a/Source/cmDefinitions.cxx +++ b/Source/cmDefinitions.cxx @@ -17,7 +17,7 @@ cmDefinitions::Def const& cmDefinitions::GetInternal(const std::string& key, { assert(begin != end); { - auto it = begin->Map.find(key); + auto it = begin->Map.find(cm::String::borrow(key)); if (it != begin->Map.end()) { it->second.Used = true; return it->second; @@ -39,7 +39,7 @@ const std::string* cmDefinitions::Get(const std::string& key, StackIter begin, StackIter end) { Def const& def = cmDefinitions::GetInternal(key, begin, end, false); - return def.Exists ? &def.Value : nullptr; + return def.Value ? def.Value.str_if_stable() : nullptr; } void cmDefinitions::Raise(const std::string& key, StackIter begin, @@ -52,7 +52,7 @@ bool cmDefinitions::HasKey(const std::string& key, StackIter begin, StackIter end) { for (StackIter it = begin; it != end; ++it) { - if (it->Map.find(key) != it->Map.end()) { + if (it->Map.find(cm::String::borrow(key)) != it->Map.end()) { return true; } } @@ -68,11 +68,11 @@ cmDefinitions cmDefinitions::MakeClosure(StackIter begin, StackIter end) for (auto const& mi : it->Map) { // Use this key if it is not already set or unset. if (closure.Map.find(mi.first) == closure.Map.end() && - undefined.find(mi.first) == undefined.end()) { - if (mi.second.Exists) { + undefined.find(mi.first.view()) == undefined.end()) { + if (mi.second.Value) { closure.Map.insert(mi); } else { - undefined.emplace(mi.first); + undefined.emplace(mi.first.view()); } } } @@ -90,8 +90,8 @@ std::vector<std::string> cmDefinitions::ClosureKeys(StackIter begin, defined.reserve(defined.size() + it->Map.size()); for (auto const& mi : it->Map) { // Use this key if it is not already set or unset. - if (bound.emplace(mi.first).second && mi.second.Exists) { - defined.push_back(mi.first); + if (bound.emplace(mi.first.view()).second && mi.second.Value) { + defined.push_back(*mi.first.str_if_stable()); } } } @@ -116,7 +116,7 @@ std::vector<std::string> cmDefinitions::UnusedKeys() const // Consider local definitions. for (auto const& mi : this->Map) { if (!mi.second.Used) { - keys.push_back(mi.first); + keys.push_back(*mi.first.str_if_stable()); } } return keys; diff --git a/Source/cmDefinitions.h b/Source/cmDefinitions.h index 787471a..b4d6419 100644 --- a/Source/cmDefinitions.h +++ b/Source/cmDefinitions.h @@ -8,7 +8,9 @@ #include "cm_string_view.hxx" #include "cmLinkedTree.h" +#include "cmString.hxx" +#include <functional> #include <string> #include <unordered_map> #include <vector> @@ -57,16 +59,14 @@ private: Def() = default; Def(cm::string_view value) : Value(value) - , Exists(true) { } - std::string Value; - bool Exists = false; + cm::String Value; bool Used = false; }; static Def NoDef; - std::unordered_map<std::string, Def> Map; + std::unordered_map<cm::String, Def> Map; static Def const& GetInternal(const std::string& key, StackIter begin, StackIter end, bool raise); diff --git a/Source/cmDepends.cxx b/Source/cmDepends.cxx index 6623d94..06a442b 100644 --- a/Source/cmDepends.cxx +++ b/Source/cmDepends.cxx @@ -236,18 +236,15 @@ void cmDepends::SetIncludePathFromLanguage(const std::string& lang) { // Look for the new per "TARGET_" variant first: const char* includePath = nullptr; - std::string includePathVar = "CMAKE_"; - includePathVar += lang; - includePathVar += "_TARGET_INCLUDE_PATH"; + std::string includePathVar = + cmStrCat("CMAKE_", lang, "_TARGET_INCLUDE_PATH"); cmMakefile* mf = this->LocalGenerator->GetMakefile(); includePath = mf->GetDefinition(includePathVar); if (includePath) { cmExpandList(includePath, this->IncludePath); } else { // Fallback to the old directory level variable if no per-target var: - includePathVar = "CMAKE_"; - includePathVar += lang; - includePathVar += "_INCLUDE_PATH"; + includePathVar = cmStrCat("CMAKE_", lang, "_INCLUDE_PATH"); includePath = mf->GetDefinition(includePathVar); if (includePath) { cmExpandList(includePath, this->IncludePath); diff --git a/Source/cmDependsC.cxx b/Source/cmDependsC.cxx index 6eefe82..0f9f166 100644 --- a/Source/cmDependsC.cxx +++ b/Source/cmDependsC.cxx @@ -36,15 +36,12 @@ cmDependsC::cmDependsC(cmLocalGenerator* lg, const std::string& targetDir, std::string scanRegex = "^.*$"; std::string complainRegex = "^$"; { - std::string scanRegexVar = "CMAKE_"; - scanRegexVar += lang; - scanRegexVar += "_INCLUDE_REGEX_SCAN"; + std::string scanRegexVar = cmStrCat("CMAKE_", lang, "_INCLUDE_REGEX_SCAN"); if (const char* sr = mf->GetDefinition(scanRegexVar)) { scanRegex = sr; } - std::string complainRegexVar = "CMAKE_"; - complainRegexVar += lang; - complainRegexVar += "_INCLUDE_REGEX_COMPLAIN"; + std::string complainRegexVar = + cmStrCat("CMAKE_", lang, "_INCLUDE_REGEX_COMPLAIN"); if (const char* cr = mf->GetDefinition(complainRegexVar)) { complainRegex = cr; } @@ -54,17 +51,15 @@ cmDependsC::cmDependsC(cmLocalGenerator* lg, const std::string& targetDir, this->IncludeRegexScan.compile(scanRegex); this->IncludeRegexComplain.compile(complainRegex); this->IncludeRegexLineString = INCLUDE_REGEX_LINE_MARKER INCLUDE_REGEX_LINE; - this->IncludeRegexScanString = INCLUDE_REGEX_SCAN_MARKER; - this->IncludeRegexScanString += scanRegex; - this->IncludeRegexComplainString = INCLUDE_REGEX_COMPLAIN_MARKER; - this->IncludeRegexComplainString += complainRegex; + this->IncludeRegexScanString = + cmStrCat(INCLUDE_REGEX_SCAN_MARKER, scanRegex); + this->IncludeRegexComplainString = + cmStrCat(INCLUDE_REGEX_COMPLAIN_MARKER, complainRegex); this->SetupTransforms(); - this->CacheFileName = this->TargetDirectory; - this->CacheFileName += "/"; - this->CacheFileName += lang; - this->CacheFileName += ".includecache"; + this->CacheFileName = + cmStrCat(this->TargetDirectory, '/', lang, ".includecache"); this->ReadCacheFile(); } diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx index 63d1c4d..6c77db9 100644 --- a/Source/cmDependsFortran.cxx +++ b/Source/cmDependsFortran.cxx @@ -180,8 +180,7 @@ bool cmDependsFortran::Finalize(std::ostream& makeDepends, } // Store the list of modules provided by this target. - std::string fiName = this->TargetDirectory; - fiName += "/fortran.internal"; + std::string fiName = cmStrCat(this->TargetDirectory, "/fortran.internal"); cmGeneratedFileStream fiStream(fiName); fiStream << "# The fortran modules provided by this target.\n"; fiStream << "provides\n"; @@ -192,23 +191,18 @@ bool cmDependsFortran::Finalize(std::ostream& makeDepends, // Create a script to clean the modules. if (!provides.empty()) { - std::string fcName = this->TargetDirectory; - fcName += "/cmake_clean_Fortran.cmake"; + std::string fcName = + cmStrCat(this->TargetDirectory, "/cmake_clean_Fortran.cmake"); cmGeneratedFileStream fcStream(fcName); fcStream << "# Remove fortran modules provided by this target.\n"; fcStream << "FILE(REMOVE"; std::string currentBinDir = this->LocalGenerator->GetCurrentBinaryDirectory(); for (std::string const& i : provides) { - std::string mod_upper = mod_dir; - mod_upper += "/"; - std::string mod_lower = mod_dir; - mod_lower += "/"; + std::string mod_upper = cmStrCat(mod_dir, '/'); + std::string mod_lower = cmStrCat(mod_dir, '/'); cmFortranModuleAppendUpperLower(i, mod_upper, mod_lower); - std::string stamp = stamp_dir; - stamp += "/"; - stamp += i; - stamp += ".stamp"; + std::string stamp = cmStrCat(stamp_dir, '/', i, ".stamp"); fcStream << "\n"; fcStream << " \"" << this->MaybeConvertToRelativePath(currentBinDir, mod_lower) @@ -315,10 +309,7 @@ void cmDependsFortran::ConsiderModule(const std::string& name, if (required != this->Internal->TargetRequires.end() && required->second.empty()) { // The module is provided by a CMake target. It will have a stamp file. - std::string stampFile = stampDir; - stampFile += "/"; - stampFile += name; - stampFile += ".stamp"; + std::string stampFile = cmStrCat(stampDir, '/', name, ".stamp"); required->second = stampFile; } } @@ -392,16 +383,11 @@ bool cmDependsFortran::WriteDependenciesReal(std::string const& obj, // Always use lower case for the mod stamp file name. The // cmake_copy_f90_mod will call back to this class, which will // try various cases for the real mod file name. - std::string modFile = mod_dir; - modFile += "/"; - modFile += i; + std::string modFile = cmStrCat(mod_dir, '/', i); modFile = this->LocalGenerator->ConvertToOutputFormat( this->MaybeConvertToRelativePath(binDir, modFile), cmOutputConverter::SHELL); - std::string stampFile = stamp_dir; - stampFile += "/"; - stampFile += i; - stampFile += ".stamp"; + std::string stampFile = cmStrCat(stamp_dir, '/', i, ".stamp"); stampFile = this->MaybeConvertToRelativePath(binDir, stampFile); std::string const stampFileForShell = this->LocalGenerator->ConvertToOutputFormat(stampFile, @@ -435,8 +421,7 @@ bool cmDependsFortran::WriteDependenciesReal(std::string const& obj, // Make sure the module timestamp rule is evaluated by the time // the target finishes building. - std::string driver = this->TargetDirectory; - driver += "/build"; + std::string driver = cmStrCat(this->TargetDirectory, "/build"); driver = cmSystemTools::ConvertToOutputPath( this->MaybeConvertToRelativePath(binDir, driver)); makeDepends << driver << ": " << obj_m << ".provides.build\n"; @@ -456,18 +441,14 @@ bool cmDependsFortran::FindModule(std::string const& name, std::string& module) std::string fullName; for (std::string const& ip : this->IncludePath) { // Try the lower-case name. - fullName = ip; - fullName += "/"; - fullName += mod_lower; + fullName = cmStrCat(ip, '/', mod_lower); if (cmSystemTools::FileExists(fullName, true)) { module = fullName; return true; } // Try the upper-case name. - fullName = ip; - fullName += "/"; - fullName += mod_upper; + fullName = cmStrCat(ip, '/', mod_upper); if (cmSystemTools::FileExists(fullName, true)) { module = fullName; return true; diff --git a/Source/cmDisallowedCommand.cxx b/Source/cmDisallowedCommand.cxx deleted file mode 100644 index aa1f90b..0000000 --- a/Source/cmDisallowedCommand.cxx +++ /dev/null @@ -1,29 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing for details. */ -#include "cmDisallowedCommand.h" - -#include "cmMakefile.h" -#include "cmMessageType.h" - -class cmExecutionStatus; - -bool cmDisallowedCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) -{ - switch (this->Makefile->GetPolicyStatus(this->Policy)) { - case cmPolicies::WARN: - this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, - cmPolicies::GetPolicyWarning(this->Policy)); - break; - case cmPolicies::OLD: - break; - case cmPolicies::REQUIRED_IF_USED: - case cmPolicies::REQUIRED_ALWAYS: - case cmPolicies::NEW: - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, this->Message); - return true; - } - - this->Command->SetExecutionStatus(this->GetExecutionStatus()); - return this->Command->InitialPass(args, status); -} diff --git a/Source/cmDisallowedCommand.h b/Source/cmDisallowedCommand.h deleted file mode 100644 index e07f255..0000000 --- a/Source/cmDisallowedCommand.h +++ /dev/null @@ -1,47 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing for details. */ -#ifndef cmDisallowedCommand_h -#define cmDisallowedCommand_h - -#include "cmConfigure.h" // IWYU pragma: keep - -#include <string> -#include <utility> -#include <vector> - -#include "cm_memory.hxx" - -#include "cmCommand.h" -#include "cmPolicies.h" - -class cmExecutionStatus; - -class cmDisallowedCommand : public cmCommand -{ -public: - cmDisallowedCommand(std::unique_ptr<cmCommand> command, - cmPolicies::PolicyID policy, const char* message) - : Command(std::move(command)) - , Policy(policy) - , Message(message) - { - } - - ~cmDisallowedCommand() override = default; - - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmDisallowedCommand>(this->Command->Clone(), - this->Policy, this->Message); - } - - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; - -private: - std::unique_ptr<cmCommand> Command; - cmPolicies::PolicyID Policy; - const char* Message; -}; - -#endif diff --git a/Source/cmExecProgramCommand.cxx b/Source/cmExecProgramCommand.cxx index bc1d173..7f41640 100644 --- a/Source/cmExecProgramCommand.cxx +++ b/Source/cmExecProgramCommand.cxx @@ -5,18 +5,26 @@ #include "cmsys/Process.h" #include <stdio.h> +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmProcessOutput.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" -class cmExecutionStatus; +typedef cmProcessOutput::Encoding Encoding; + +namespace { +bool RunCommand(std::string command, std::string& output, int& retVal, + const char* directory = nullptr, bool verbose = true, + Encoding encoding = cmProcessOutput::Auto); +} // cmExecProgramCommand -bool cmExecProgramCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmExecProgramCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.empty()) { - this->SetError("called with incorrect number of arguments"); + status.SetError("called with incorrect number of arguments"); return false; } std::string arguments; @@ -34,7 +42,7 @@ bool cmExecProgramCommand::InitialPass(std::vector<std::string> const& args, haveoutput_variable = true; } else if (haveoutput_variable) { if (!output_variable.empty()) { - this->SetError("called with incorrect number of arguments"); + status.SetError("called with incorrect number of arguments"); return false; } output_variable = arg; @@ -47,7 +55,7 @@ bool cmExecProgramCommand::InitialPass(std::vector<std::string> const& args, havereturn_variable = true; } else if (havereturn_variable) { if (!return_variable.empty()) { - this->SetError("called with incorrect number of arguments"); + status.SetError("called with incorrect number of arguments"); return false; } return_variable = arg; @@ -67,9 +75,8 @@ bool cmExecProgramCommand::InitialPass(std::vector<std::string> const& args, std::string command; if (!arguments.empty()) { - command = cmSystemTools::ConvertToRunCommandPath(args[0]); - command += " "; - command += arguments; + command = cmStrCat(cmSystemTools::ConvertToRunCommandPath(args[0]), ' ', + arguments); } else { command = args[0]; } @@ -82,11 +89,9 @@ bool cmExecProgramCommand::InitialPass(std::vector<std::string> const& args, bool result = true; if (args.size() - count == 2) { cmSystemTools::MakeDirectory(args[1]); - result = cmExecProgramCommand::RunCommand(command, output, retVal, - args[1].c_str(), verbose); + result = RunCommand(command, output, retVal, args[1].c_str(), verbose); } else { - result = cmExecProgramCommand::RunCommand(command, output, retVal, nullptr, - verbose); + result = RunCommand(command, output, retVal, nullptr, verbose); } if (!result) { retVal = -1; @@ -103,21 +108,21 @@ bool cmExecProgramCommand::InitialPass(std::vector<std::string> const& args, } std::string coutput = std::string(output, first, last - first + 1); - this->Makefile->AddDefinition(output_variable, coutput); + status.GetMakefile().AddDefinition(output_variable, coutput); } if (!return_variable.empty()) { char buffer[100]; sprintf(buffer, "%d", retVal); - this->Makefile->AddDefinition(return_variable, buffer); + status.GetMakefile().AddDefinition(return_variable, buffer); } return true; } -bool cmExecProgramCommand::RunCommand(std::string command, std::string& output, - int& retVal, const char* dir, - bool verbose, Encoding encoding) +namespace { +bool RunCommand(std::string command, std::string& output, int& retVal, + const char* dir, bool verbose, Encoding encoding) { if (cmSystemTools::GetRunCommandOutput()) { verbose = false; @@ -187,10 +192,7 @@ bool cmExecProgramCommand::RunCommand(std::string command, std::string& output, #else std::string commandInDir; if (dir) { - commandInDir = "cd \""; - commandInDir += dir; - commandInDir += "\" && "; - commandInDir += command; + commandInDir = cmStrCat("cd \"", dir, "\" && ", command); } else { commandInDir = command; } @@ -284,3 +286,4 @@ bool cmExecProgramCommand::RunCommand(std::string command, std::string& output, return true; } +} diff --git a/Source/cmExecProgramCommand.h b/Source/cmExecProgramCommand.h index 70f833a..7c751e1 100644 --- a/Source/cmExecProgramCommand.h +++ b/Source/cmExecProgramCommand.h @@ -8,43 +8,16 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" -#include "cmProcessOutput.h" - class cmExecutionStatus; -/** \class cmExecProgramCommand +/** * \brief Command that adds a target to the build system. * * cmExecProgramCommand adds an extra target to the build system. * This is useful when you would like to add special * targets like "install,", "clean," and so on. */ -class cmExecProgramCommand : public cmCommand -{ -public: - typedef cmProcessOutput::Encoding Encoding; - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmExecProgramCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; - -private: - static bool RunCommand(std::string command, std::string& output, int& retVal, - const char* directory = nullptr, bool verbose = true, - Encoding encoding = cmProcessOutput::Auto); -}; +bool cmExecProgramCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmExecuteProcessCommand.cxx b/Source/cmExecuteProcessCommand.cxx index 465f4b3..acf2a83 100644 --- a/Source/cmExecuteProcessCommand.cxx +++ b/Source/cmExecuteProcessCommand.cxx @@ -8,20 +8,21 @@ #include <algorithm> #include <ctype.h> /* isspace */ #include <iostream> +#include <memory> #include <stdio.h> #include <vector> #include "cmAlgorithms.h" #include "cmArgumentParser.h" +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmProcessOutput.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" -class cmExecutionStatus; - -static bool cmExecuteProcessCommandIsWhitespace(char c) +namespace { +bool cmExecuteProcessCommandIsWhitespace(char c) { return (isspace(static_cast<int>(c)) || c == '\n' || c == '\r'); } @@ -30,13 +31,14 @@ void cmExecuteProcessCommandFixText(std::vector<char>& output, bool strip_trailing_whitespace); void cmExecuteProcessCommandAppend(std::vector<char>& output, const char* data, int length); +} // cmExecuteProcessCommand -bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmExecuteProcessCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.empty()) { - this->SetError("called with incorrect number of arguments"); + status.SetError("called with incorrect number of arguments"); return false; } @@ -87,31 +89,31 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args, parser.Parse(args, &unparsedArguments, &keywordsMissingValue); if (!keywordsMissingValue.empty()) { - this->SetError(" called with no value for " + - keywordsMissingValue.front() + "."); + status.SetError(" called with no value for " + + keywordsMissingValue.front() + "."); return false; } if (!unparsedArguments.empty()) { - this->SetError(" given unknown argument \"" + unparsedArguments.front() + - "\"."); + status.SetError(" given unknown argument \"" + unparsedArguments.front() + + "\"."); return false; } - if (!this->Makefile->CanIWriteThisFile(arguments.OutputFile)) { - this->SetError("attempted to output into a file: " + arguments.OutputFile + - " into a source directory."); + if (!status.GetMakefile().CanIWriteThisFile(arguments.OutputFile)) { + status.SetError("attempted to output into a file: " + + arguments.OutputFile + " into a source directory."); cmSystemTools::SetFatalErrorOccured(); return false; } // Check for commands given. if (arguments.Commands.empty()) { - this->SetError(" called with no COMMAND argument."); + status.SetError(" called with no COMMAND argument."); return false; } for (std::vector<std::string> const& cmd : arguments.Commands) { if (cmd.empty()) { - this->SetError(" given COMMAND argument with no value."); + status.SetError(" given COMMAND argument with no value."); return false; } } @@ -120,7 +122,7 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args, double timeout = -1; if (!arguments.Timeout.empty()) { if (sscanf(arguments.Timeout.c_str(), "%lg", &timeout) != 1) { - this->SetError(" called with TIMEOUT value that could not be parsed."); + status.SetError(" called with TIMEOUT value that could not be parsed."); return false; } } @@ -180,8 +182,8 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args, bool echo_stdout = false; bool echo_stderr = false; bool echo_output_from_variable = true; - std::string echo_output = - this->Makefile->GetSafeDefinition("CMAKE_EXECUTE_PROCESS_COMMAND_ECHO"); + std::string echo_output = status.GetMakefile().GetSafeDefinition( + "CMAKE_EXECUTE_PROCESS_COMMAND_ECHO"); if (!arguments.CommandEcho.empty()) { echo_output_from_variable = false; echo_output = arguments.CommandEcho; @@ -204,7 +206,7 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args, if (!echo_output_from_variable) { error += " for COMMAND_ECHO."; } - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, error); + status.GetMakefile().IssueMessage(MessageType::FATAL_ERROR, error); return true; } } @@ -278,11 +280,13 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args, // Store the output obtained. if (!arguments.OutputVariable.empty() && !tempOutput.empty()) { - this->Makefile->AddDefinition(arguments.OutputVariable, tempOutput.data()); + status.GetMakefile().AddDefinition(arguments.OutputVariable, + tempOutput.data()); } if (!merge_output && !arguments.ErrorVariable.empty() && !tempError.empty()) { - this->Makefile->AddDefinition(arguments.ErrorVariable, tempError.data()); + status.GetMakefile().AddDefinition(arguments.ErrorVariable, + tempError.data()); } // Store the result of running the process. @@ -292,19 +296,19 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args, int v = cmsysProcess_GetExitValue(cp); char buf[16]; sprintf(buf, "%d", v); - this->Makefile->AddDefinition(arguments.ResultVariable, buf); + status.GetMakefile().AddDefinition(arguments.ResultVariable, buf); } break; case cmsysProcess_State_Exception: - this->Makefile->AddDefinition(arguments.ResultVariable, - cmsysProcess_GetExceptionString(cp)); + status.GetMakefile().AddDefinition( + arguments.ResultVariable, cmsysProcess_GetExceptionString(cp)); break; case cmsysProcess_State_Error: - this->Makefile->AddDefinition(arguments.ResultVariable, - cmsysProcess_GetErrorString(cp)); + status.GetMakefile().AddDefinition(arguments.ResultVariable, + cmsysProcess_GetErrorString(cp)); break; case cmsysProcess_State_Expired: - this->Makefile->AddDefinition(arguments.ResultVariable, - "Process terminated due to timeout"); + status.GetMakefile().AddDefinition( + arguments.ResultVariable, "Process terminated due to timeout"); break; } } @@ -332,20 +336,20 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args, break; } } - this->Makefile->AddDefinition(arguments.ResultsVariable, - cmJoin(res, ";")); + status.GetMakefile().AddDefinition(arguments.ResultsVariable, + cmJoin(res, ";")); } break; case cmsysProcess_State_Exception: - this->Makefile->AddDefinition(arguments.ResultsVariable, - cmsysProcess_GetExceptionString(cp)); + status.GetMakefile().AddDefinition( + arguments.ResultsVariable, cmsysProcess_GetExceptionString(cp)); break; case cmsysProcess_State_Error: - this->Makefile->AddDefinition(arguments.ResultsVariable, - cmsysProcess_GetErrorString(cp)); + status.GetMakefile().AddDefinition(arguments.ResultsVariable, + cmsysProcess_GetErrorString(cp)); break; case cmsysProcess_State_Expired: - this->Makefile->AddDefinition(arguments.ResultsVariable, - "Process terminated due to timeout"); + status.GetMakefile().AddDefinition( + arguments.ResultsVariable, "Process terminated due to timeout"); break; } } @@ -353,6 +357,7 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args, return true; } +namespace { void cmExecuteProcessCommandFixText(std::vector<char>& output, bool strip_trailing_whitespace) { @@ -398,3 +403,4 @@ void cmExecuteProcessCommandAppend(std::vector<char>& output, const char* data, #endif cmAppend(output, data, data + length); } +} diff --git a/Source/cmExecuteProcessCommand.h b/Source/cmExecuteProcessCommand.h index 1d5445f..9c4b600 100644 --- a/Source/cmExecuteProcessCommand.h +++ b/Source/cmExecuteProcessCommand.h @@ -8,35 +8,15 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmExecuteProcessCommand +/** * \brief Command that adds a target to the build system. * * cmExecuteProcessCommand is a CMake language interface to the KWSys * Process Execution implementation. */ -class cmExecuteProcessCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmExecuteProcessCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; +bool cmExecuteProcessCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmExportBuildAndroidMKGenerator.cxx b/Source/cmExportBuildAndroidMKGenerator.cxx index 22cc0bc..561e830 100644 --- a/Source/cmExportBuildAndroidMKGenerator.cxx +++ b/Source/cmExportBuildAndroidMKGenerator.cxx @@ -2,10 +2,10 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmExportBuildAndroidMKGenerator.h" -#include <algorithm> #include <sstream> #include <utility> +#include "cmAlgorithms.h" #include "cmGeneratorTarget.h" #include "cmLinkItem.h" #include "cmMakefile.h" @@ -41,8 +41,7 @@ void cmExportBuildAndroidMKGenerator::GenerateImportTargetCode( std::ostream& os, cmGeneratorTarget const* target, cmStateEnums::TargetType /*targetType*/) { - std::string targetName = this->Namespace; - targetName += target->GetExportName(); + std::string targetName = cmStrCat(this->Namespace, target->GetExportName()); os << "include $(CLEAR_VARS)\n"; os << "LOCAL_MODULE := "; os << targetName << "\n"; @@ -144,8 +143,7 @@ void cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties( } } else if (property.first == "INTERFACE_INCLUDE_DIRECTORIES") { std::string includes = property.second; - std::vector<std::string> includeList; - cmExpandList(includes, includeList); + std::vector<std::string> includeList = cmExpandedList(includes); os << "LOCAL_EXPORT_C_INCLUDES := "; std::string end; for (std::string const& i : includeList) { @@ -155,8 +153,8 @@ void cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties( os << "\n"; } else if (property.first == "INTERFACE_LINK_OPTIONS") { os << "LOCAL_EXPORT_LDFLAGS := "; - std::vector<std::string> linkFlagsList; - cmExpandList(property.second, linkFlagsList); + std::vector<std::string> linkFlagsList = + cmExpandedList(property.second); os << cmJoin(linkFlagsList, " ") << "\n"; } else { os << "# " << property.first << " " << (property.second) << "\n"; @@ -167,8 +165,7 @@ void cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties( // Tell the NDK build system if prebuilt static libraries use C++. if (target->GetType() == cmStateEnums::STATIC_LIBRARY) { cmLinkImplementation const* li = target->GetLinkImplementation(config); - if (std::find(li->Languages.begin(), li->Languages.end(), "CXX") != - li->Languages.end()) { + if (cmContains(li->Languages, "CXX")) { os << "LOCAL_HAS_CPP := true\n"; } } diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx index 33806f2..9f0396b 100644 --- a/Source/cmExportBuildFileGenerator.cxx +++ b/Source/cmExportBuildFileGenerator.cxx @@ -16,7 +16,6 @@ #include "cmTargetExport.h" #include "cmake.h" -#include <algorithm> #include <map> #include <set> #include <sstream> @@ -92,6 +91,9 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os) this->PopulateInterfaceProperty("INTERFACE_COMPILE_OPTIONS", gte, cmGeneratorExpression::BuildInterface, properties, missingTargets); + this->PopulateInterfaceProperty("INTERFACE_PRECOMPILE_HEADERS", gte, + cmGeneratorExpression::BuildInterface, + properties, missingTargets); this->PopulateInterfaceProperty("INTERFACE_AUTOUIC_OPTIONS", gte, cmGeneratorExpression::BuildInterface, properties, missingTargets); @@ -203,8 +205,7 @@ void cmExportBuildFileGenerator::SetImportLocationProperty( cmMakefile* mf = target->Makefile; if (target->GetType() == cmStateEnums::OBJECT_LIBRARY) { - std::string prop = "IMPORTED_OBJECTS"; - prop += suffix; + std::string prop = cmStrCat("IMPORTED_OBJECTS", suffix); // Compute all the object files inside this target and setup // IMPORTED_OBJECTS as a list of object files @@ -222,8 +223,7 @@ void cmExportBuildFileGenerator::SetImportLocationProperty( } else { // Add the main target file. { - std::string prop = "IMPORTED_LOCATION"; - prop += suffix; + std::string prop = cmStrCat("IMPORTED_LOCATION", suffix); std::string value; if (target->IsAppBundleOnApple()) { value = @@ -237,8 +237,7 @@ void cmExportBuildFileGenerator::SetImportLocationProperty( // Add the import library for windows DLLs. if (target->HasImportLibrary(config)) { - std::string prop = "IMPORTED_IMPLIB"; - prop += suffix; + std::string prop = cmStrCat("IMPORTED_IMPLIB", suffix); std::string value = target->GetFullPath(config, cmStateEnums::ImportLibraryArtifact); if (mf->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")) { @@ -306,7 +305,7 @@ cmExportBuildFileGenerator::FindBuildExportInfo(cmGlobalGenerator* gg, const cmExportBuildFileGenerator* exportSet = exp.second; std::vector<std::string> targets; exportSet->GetTargets(targets); - if (std::find(targets.begin(), targets.end(), name) != targets.end()) { + if (cmContains(targets, name)) { exportFiles.push_back(exp.first); ns = exportSet->GetNamespace(); } diff --git a/Source/cmExportCommand.cxx b/Source/cmExportCommand.cxx index a849aa2..4046f91 100644 --- a/Source/cmExportCommand.cxx +++ b/Source/cmExportCommand.cxx @@ -5,11 +5,11 @@ #include "cm_static_string_view.hxx" #include "cmsys/RegularExpression.hxx" -#include <algorithm> #include <map> #include <sstream> #include <utility> +#include "cmAlgorithms.h" #include "cmArgumentParser.h" #include "cmExportBuildAndroidMKGenerator.h" #include "cmExportBuildFileGenerator.h" @@ -133,9 +133,7 @@ bool cmExportCommand::InitialPass(std::vector<std::string> const& args, } ExportSet = it->second; } else if (!arguments.Targets.empty() || - std::find(keywordsMissingValue.begin(), - keywordsMissingValue.end(), - "TARGETS") != keywordsMissingValue.end()) { + cmContains(keywordsMissingValue, "TARGETS")) { for (std::string const& currentTarget : arguments.Targets) { if (this->Makefile->IsAlias(currentTarget)) { std::ostringstream e; @@ -301,8 +299,7 @@ void cmExportCommand::StorePackageRegistryWin(std::string const& package, const char* content, const char* hash) { - std::string key = "Software\\Kitware\\CMake\\Packages\\"; - key += package; + std::string key = cmStrCat("Software\\Kitware\\CMake\\Packages\\", package); HKEY hKey; LONG err = RegCreateKeyExW(HKEY_CURRENT_USER, cmsys::Encoding::ToWide(key).c_str(), 0, @@ -336,9 +333,7 @@ void cmExportCommand::StorePackageRegistryDir(std::string const& package, B_OK) { return; } - std::string fname = dir; - fname += "/cmake/packages/"; - fname += package; + std::string fname = cmStrCat(dir, "/cmake/packages/", package); # else std::string fname; if (!cmSystemTools::GetEnv("HOME", fname)) { diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index 35d8668..70f98bf 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -499,8 +499,7 @@ void getPropertyContents(cmGeneratorTarget const* tgt, const std::string& prop, if (!p) { return; } - std::vector<std::string> content; - cmExpandList(p, content); + std::vector<std::string> content = cmExpandedList(p); ifaceProperties.insert(content.begin(), content.end()); } @@ -584,8 +583,8 @@ void cmExportFileGenerator::GenerateInterfaceProperties( const ImportPropertyMap& properties) { if (!properties.empty()) { - std::string targetName = this->Namespace; - targetName += target->GetExportName(); + std::string targetName = + cmStrCat(this->Namespace, target->GetExportName()); os << "set_target_properties(" << targetName << " PROPERTIES\n"; for (auto const& property : properties) { os << " " << property.first << " " @@ -841,19 +840,16 @@ void cmExportFileGenerator::SetImportDetailProperties( "IMPORTED_LINK_DEPENDENT_LIBRARIES", iface->SharedDeps, properties, dummy); if (iface->Multiplicity > 0) { - std::string prop = "IMPORTED_LINK_INTERFACE_MULTIPLICITY"; - prop += suffix; - std::ostringstream m; - m << iface->Multiplicity; - properties[prop] = m.str(); + std::string prop = + cmStrCat("IMPORTED_LINK_INTERFACE_MULTIPLICITY", suffix); + properties[prop] = std::to_string(iface->Multiplicity); } } // Add information if this target is a managed target if (target->GetManagedType(config) != cmGeneratorTarget::ManagedType::Native) { - std::string prop = "IMPORTED_COMMON_LANGUAGE_RUNTIME"; - prop += suffix; + std::string prop = cmStrCat("IMPORTED_COMMON_LANGUAGE_RUNTIME", suffix); std::string propval; if (auto* p = target->GetProperty("COMMON_LANGUAGE_RUNTIME")) { propval = p; @@ -904,8 +900,7 @@ void cmExportFileGenerator::SetImportLinkProperty( } // Store the property. - std::string prop = propName; - prop += suffix; + std::string prop = cmStrCat(propName, suffix); properties[prop] = link_entries; } @@ -1182,8 +1177,7 @@ void cmExportFileGenerator::GenerateImportedFileChecksCode( const std::set<std::string>& importedLocations) { // Construct the imported target name. - std::string targetName = this->Namespace; - targetName += target->GetExportName(); + std::string targetName = cmStrCat(this->Namespace, target->GetExportName()); os << "list(APPEND _IMPORT_CHECK_TARGETS " << targetName << " )\n" diff --git a/Source/cmExportInstallAndroidMKGenerator.cxx b/Source/cmExportInstallAndroidMKGenerator.cxx index 9bc8089..1b536c9 100644 --- a/Source/cmExportInstallAndroidMKGenerator.cxx +++ b/Source/cmExportInstallAndroidMKGenerator.cxx @@ -11,6 +11,7 @@ #include "cmInstallExportGenerator.h" #include "cmInstallTargetGenerator.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" #include "cmTargetExport.h" @@ -58,8 +59,7 @@ void cmExportInstallAndroidMKGenerator::GenerateImportTargetCode( std::ostream& os, cmGeneratorTarget const* target, cmStateEnums::TargetType /*targetType*/) { - std::string targetName = this->Namespace; - targetName += target->GetExportName(); + std::string targetName = cmStrCat(this->Namespace, target->GetExportName()); os << "include $(CLEAR_VARS)\n"; os << "LOCAL_MODULE := "; os << targetName << "\n"; diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx index 4bc2d1b..e7f301e 100644 --- a/Source/cmExportInstallFileGenerator.cxx +++ b/Source/cmExportInstallFileGenerator.cxx @@ -30,9 +30,7 @@ cmExportInstallFileGenerator::cmExportInstallFileGenerator( std::string cmExportInstallFileGenerator::GetConfigImportFileGlob() { - std::string glob = this->FileBase; - glob += "-*"; - glob += this->FileExt; + std::string glob = cmStrCat(this->FileBase, "-*", this->FileExt); return glob; } @@ -277,10 +275,7 @@ bool cmExportInstallFileGenerator::GenerateImportFileConfig( } // Construct the name of the file to generate. - std::string fileName = this->FileDir; - fileName += "/"; - fileName += this->FileBase; - fileName += "-"; + std::string fileName = cmStrCat(this->FileDir, '/', this->FileBase, '-'); if (!config.empty()) { fileName += cmSystemTools::LowerCase(config); } else { @@ -392,8 +387,7 @@ void cmExportInstallFileGenerator::SetImportLocationProperty( if (itgen->IsImportLibrary()) { // Construct the property name. - std::string prop = "IMPORTED_IMPLIB"; - prop += suffix; + std::string prop = cmStrCat("IMPORTED_IMPLIB", suffix); // Append the installed file name. value += cmInstallTargetGenerator::GetInstallFilename( @@ -404,8 +398,7 @@ void cmExportInstallFileGenerator::SetImportLocationProperty( importedLocations.insert(prop); } else if (itgen->GetTarget()->GetType() == cmStateEnums::OBJECT_LIBRARY) { // Construct the property name. - std::string prop = "IMPORTED_OBJECTS"; - prop += suffix; + std::string prop = cmStrCat("IMPORTED_OBJECTS", suffix); // Compute all the object files inside this target and setup // IMPORTED_OBJECTS as a list of object files @@ -420,8 +413,7 @@ void cmExportInstallFileGenerator::SetImportLocationProperty( importedLocations.insert(prop); } else { // Construct the property name. - std::string prop = "IMPORTED_LOCATION"; - prop += suffix; + std::string prop = cmStrCat("IMPORTED_LOCATION", suffix); // Append the installed file name. if (target->IsAppBundleOnApple()) { @@ -458,10 +450,10 @@ void cmExportInstallFileGenerator::HandleMissingTarget( { const std::string name = dependee->GetName(); cmGlobalGenerator* gg = dependee->GetLocalGenerator()->GetGlobalGenerator(); - std::vector<std::string> namespaces = this->FindNamespaces(gg, name); - int targetOccurrences = static_cast<int>(namespaces.size()); - if (targetOccurrences == 1) { - std::string missingTarget = namespaces[0]; + auto exportInfo = this->FindNamespaces(gg, name); + std::vector<std::string> const& exportFiles = exportInfo.first; + if (exportFiles.size() == 1) { + std::string missingTarget = exportInfo.second; missingTarget += dependee->GetExportName(); link_libs += missingTarget; @@ -469,14 +461,16 @@ void cmExportInstallFileGenerator::HandleMissingTarget( } else { // All exported targets should be known here and should be unique. // This is probably user-error. - this->ComplainAboutMissingTarget(depender, dependee, targetOccurrences); + this->ComplainAboutMissingTarget(depender, dependee, exportFiles); } } -std::vector<std::string> cmExportInstallFileGenerator::FindNamespaces( - cmGlobalGenerator* gg, const std::string& name) +std::pair<std::vector<std::string>, std::string> +cmExportInstallFileGenerator::FindNamespaces(cmGlobalGenerator* gg, + const std::string& name) { - std::vector<std::string> namespaces; + std::vector<std::string> exportFiles; + std::string ns; const cmExportSetMap& exportSets = gg->GetExportSets(); for (auto const& expIt : exportSets) { @@ -496,27 +490,33 @@ std::vector<std::string> cmExportInstallFileGenerator::FindNamespaces( std::vector<cmInstallExportGenerator const*> const* installs = exportSet->GetInstallations(); for (cmInstallExportGenerator const* install : *installs) { - namespaces.push_back(install->GetNamespace()); + exportFiles.push_back(install->GetDestinationFile()); + ns = install->GetNamespace(); } } } - return namespaces; + return std::make_pair(exportFiles, ns); } void cmExportInstallFileGenerator::ComplainAboutMissingTarget( - cmGeneratorTarget* depender, cmGeneratorTarget* dependee, int occurrences) + cmGeneratorTarget* depender, cmGeneratorTarget* dependee, + std::vector<std::string> const& exportFiles) { std::ostringstream e; e << "install(EXPORT \"" << this->IEGen->GetExportSet()->GetName() << "\" ...) " << "includes target \"" << depender->GetName() << "\" which requires target \"" << dependee->GetName() << "\" "; - if (occurrences == 0) { - e << "that is not in the export set."; + if (exportFiles.empty()) { + e << "that is not in any export set."; } else { - e << "that is not in this export set, but " << occurrences - << " times in others."; + e << "that is not in this export set, but in multiple other export sets: " + << cmJoin(exportFiles, ", ") << ".\n"; + e << "An exported target cannot depend upon another target which is " + "exported multiple times. Consider consolidating the exports of the " + "\"" + << dependee->GetName() << "\" target to a single export."; } cmSystemTools::Error(e.str()); } diff --git a/Source/cmExportInstallFileGenerator.h b/Source/cmExportInstallFileGenerator.h index cbd6507..fcd1aca 100644 --- a/Source/cmExportInstallFileGenerator.h +++ b/Source/cmExportInstallFileGenerator.h @@ -12,6 +12,7 @@ #include <map> #include <set> #include <string> +#include <utility> #include <vector> class cmGeneratorTarget; @@ -70,10 +71,10 @@ protected: void ComplainAboutMissingTarget(cmGeneratorTarget* depender, cmGeneratorTarget* dependee, - int occurrences); + std::vector<std::string> const& exportFiles); - std::vector<std::string> FindNamespaces(cmGlobalGenerator* gg, - const std::string& name); + std::pair<std::vector<std::string>, std::string> FindNamespaces( + cmGlobalGenerator* gg, const std::string& name); /** Generate the relative import prefix. */ virtual void GenerateImportPrefix(std::ostream&); diff --git a/Source/cmExportLibraryDependenciesCommand.cxx b/Source/cmExportLibraryDependenciesCommand.cxx index 8f2fff5..bab394a 100644 --- a/Source/cmExportLibraryDependenciesCommand.cxx +++ b/Source/cmExportLibraryDependenciesCommand.cxx @@ -8,17 +8,17 @@ #include "cm_memory.hxx" +#include "cmExecutionStatus.h" #include "cmGeneratedFileStream.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" #include "cmTargetLinkLibraryType.h" #include "cmake.h" -class cmExecutionStatus; - static void FinalAction(cmMakefile& makefile, std::string const& filename, bool append) { @@ -61,8 +61,7 @@ static void FinalAction(cmMakefile& makefile, std::string const& filename, } // Construct the dependency variable name. - std::string targetEntry = target.GetName(); - targetEntry += "_LIB_DEPENDS"; + std::string targetEntry = cmStrCat(target.GetName(), "_LIB_DEPENDS"); // Construct the dependency variable value with the direct link // dependencies. @@ -71,8 +70,7 @@ static void FinalAction(cmMakefile& makefile, std::string const& filename, cmTarget::LinkLibraryVectorType const& libs = target.GetOriginalLinkLibraries(); for (cmTarget::LibraryID const& li : libs) { - std::string ltVar = li.first; - ltVar += "_LINK_TYPE"; + std::string ltVar = cmStrCat(li.first, "_LINK_TYPE"); std::string ltValue; switch (li.second) { case GENERAL_LibraryType: @@ -141,19 +139,20 @@ static void FinalAction(cmMakefile& makefile, std::string const& filename, fout << "endif()\n"; } -bool cmExportLibraryDependenciesCommand::InitialPass( - std::vector<std::string> const& args, cmExecutionStatus&) +bool cmExportLibraryDependenciesCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.empty()) { - this->SetError("called with incorrect number of arguments"); + status.SetError("called with incorrect number of arguments"); return false; } std::string const& filename = args[0]; bool const append = args.size() > 1 && args[1] == "APPEND"; - this->Makefile->AddFinalAction([filename, append](cmMakefile& makefile) { - FinalAction(makefile, filename, append); - }); + status.GetMakefile().AddFinalAction( + [filename, append](cmMakefile& makefile) { + FinalAction(makefile, filename, append); + }); return true; } diff --git a/Source/cmExportLibraryDependenciesCommand.h b/Source/cmExportLibraryDependenciesCommand.h index 4817162..230c906 100644 --- a/Source/cmExportLibraryDependenciesCommand.h +++ b/Source/cmExportLibraryDependenciesCommand.h @@ -8,21 +8,9 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -class cmExportLibraryDependenciesCommand : public cmCommand -{ -public: - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmExportLibraryDependenciesCommand>(); - } - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; +bool cmExportLibraryDependenciesCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmExportTryCompileFileGenerator.cxx b/Source/cmExportTryCompileFileGenerator.cxx index f77fd3a..5631d60 100644 --- a/Source/cmExportTryCompileFileGenerator.cxx +++ b/Source/cmExportTryCompileFileGenerator.cxx @@ -103,8 +103,7 @@ void cmExportTryCompileFileGenerator::PopulateProperties( std::string evalResult = this->FindTargets(p, target, std::string(), emitted); - std::vector<std::string> depends; - cmExpandList(evalResult, depends); + std::vector<std::string> depends = cmExpandedList(evalResult); for (std::string const& li : depends) { cmGeneratorTarget* tgt = target->GetLocalGenerator()->FindGeneratorTargetToUse(li); diff --git a/Source/cmExprParserHelper.cxx b/Source/cmExprParserHelper.cxx index 80c78a3..c01e959 100644 --- a/Source/cmExprParserHelper.cxx +++ b/Source/cmExprParserHelper.cxx @@ -3,6 +3,7 @@ #include "cmExprParserHelper.h" #include "cmExprLexer.h" +#include "cmStringAlgorithms.h" #include <iostream> #include <sstream> @@ -41,16 +42,13 @@ int cmExprParserHelper::ParseString(const char* str, int verb) try { int res = cmExpr_yyparse(yyscanner); if (res != 0) { - std::string e = "cannot parse the expression: \"" + InputBuffer + "\": "; - e += ErrorString; - e += "."; + std::string e = cmStrCat("cannot parse the expression: \"", InputBuffer, + "\": ", ErrorString, '.'); this->SetError(std::move(e)); } } catch (std::runtime_error const& fail) { - std::string e = - "cannot evaluate the expression: \"" + InputBuffer + "\": "; - e += fail.what(); - e += "."; + std::string e = cmStrCat("cannot evaluate the expression: \"", InputBuffer, + "\": ", fail.what(), '.'); this->SetError(std::move(e)); } catch (std::out_of_range const&) { std::string e = "cannot evaluate the expression: \"" + InputBuffer + diff --git a/Source/cmExternalMakefileProjectGenerator.cxx b/Source/cmExternalMakefileProjectGenerator.cxx index ac54811..83a0ba6 100644 --- a/Source/cmExternalMakefileProjectGenerator.cxx +++ b/Source/cmExternalMakefileProjectGenerator.cxx @@ -2,6 +2,8 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmExternalMakefileProjectGenerator.h" +#include "cmStringAlgorithms.h" + #include <utility> class cmMakefile; @@ -18,8 +20,7 @@ std::string cmExternalMakefileProjectGenerator::CreateFullGeneratorName( std::string fullName; if (!globalGenerator.empty()) { if (!extraGenerator.empty()) { - fullName = extraGenerator; - fullName += " - "; + fullName = cmStrCat(extraGenerator, " - "); } fullName += globalGenerator; } diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx index 79ecf45..487d0de 100644 --- a/Source/cmExtraCodeBlocksGenerator.cxx +++ b/Source/cmExtraCodeBlocksGenerator.cxx @@ -74,10 +74,9 @@ void cmExtraCodeBlocksGenerator::CreateProjectFile( std::string outputDir = lgs[0]->GetCurrentBinaryDirectory(); std::string projectName = lgs[0]->GetProjectName(); - std::string filename = outputDir + "/"; - filename += projectName + ".cbp"; - std::string sessionFilename = outputDir + "/"; - sessionFilename += projectName + ".layout"; + std::string filename = cmStrCat(outputDir, '/', projectName, ".cbp"); + std::string sessionFilename = + cmStrCat(outputDir, '/', projectName, ".layout"); this->CreateNewProjectFile(lgs, filename); } @@ -319,8 +318,7 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile( cmGeneratorTarget* gt = target; this->AppendTarget(xml, targetName, gt, make, lg, compiler, makeArgs); - std::string fastTarget = targetName; - fastTarget += "/fast"; + std::string fastTarget = cmStrCat(targetName, "/fast"); this->AppendTarget(xml, fastTarget, gt, make, lg, compiler, makeArgs); } break; @@ -367,7 +365,7 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile( // check whether it is a C/C++/CUDA implementation file bool isCFile = false; - std::string lang = s->GetLanguage(); + std::string lang = s->GetOrDetermineLanguage(); if (lang == "C" || lang == "CXX" || lang == "CUDA") { std::string const& srcext = s->GetExtension(); isCFile = cm->IsSourceExtension(srcext); @@ -413,15 +411,13 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile( // A very similar version of that code exists also in the CodeLite // project generator. for (std::string const& fileName : cFiles) { - std::string headerBasename = cmSystemTools::GetFilenamePath(fileName); - headerBasename += "/"; - headerBasename += cmSystemTools::GetFilenameWithoutExtension(fileName); + std::string headerBasename = + cmStrCat(cmSystemTools::GetFilenamePath(fileName), '/', + cmSystemTools::GetFilenameWithoutExtension(fileName)); // check if there's a matching header around for (std::string const& ext : headerExts) { - std::string hname = headerBasename; - hname += "."; - hname += ext; + std::string hname = cmStrCat(headerBasename, '.', ext); // if it's already in the set, don't check if it exists on disk if (allFiles.find(hname) != allFiles.end()) { break; @@ -466,12 +462,9 @@ std::string cmExtraCodeBlocksGenerator::CreateDummyTargetFile( // this file doesn't seem to be used by C::B in custom makefile mode, // but we generate a unique file for each OBJECT library so in case // C::B uses it in some way, the targets don't interfere with each other. - std::string filename = lg->GetCurrentBinaryDirectory(); - filename += "/"; - filename += lg->GetTargetDirectory(target); - filename += "/"; - filename += target->GetName(); - filename += ".objlib"; + std::string filename = cmStrCat(lg->GetCurrentBinaryDirectory(), '/', + lg->GetTargetDirectory(target), '/', + target->GetName(), ".objlib"); cmGeneratedFileStream fout(filename); if (fout) { /* clang-format off */ @@ -491,8 +484,8 @@ void cmExtraCodeBlocksGenerator::AppendTarget( const std::string& compiler, const std::string& makeFlags) { cmMakefile const* makefile = lg->GetMakefile(); - std::string makefileName = lg->GetCurrentBinaryDirectory(); - makefileName += "/Makefile"; + std::string makefileName = + cmStrCat(lg->GetCurrentBinaryDirectory(), "/Makefile"); xml.StartElement("Target"); xml.Attribute("title", targetName); diff --git a/Source/cmExtraCodeLiteGenerator.cxx b/Source/cmExtraCodeLiteGenerator.cxx index 70e9a36..7f71a2c 100644 --- a/Source/cmExtraCodeLiteGenerator.cxx +++ b/Source/cmExtraCodeLiteGenerator.cxx @@ -68,8 +68,8 @@ void cmExtraCodeLiteGenerator::Generate() workspaceOutputDir = lg->GetCurrentBinaryDirectory(); workspaceProjectName = lg->GetProjectName(); workspaceSourcePath = lg->GetSourceDirectory(); - workspaceFileName = workspaceOutputDir + "/"; - workspaceFileName += workspaceProjectName + ".workspace"; + workspaceFileName = + cmStrCat(workspaceOutputDir, '/', workspaceProjectName, ".workspace"); this->WorkspacePath = lg->GetCurrentBinaryDirectory(); break; } @@ -299,15 +299,13 @@ void cmExtraCodeLiteGenerator::FindMatchingHeaderfiles( // A very similar version of that code exists also in the CodeBlocks // project generator. for (auto const& sit : cFiles) { - std::string headerBasename = cmSystemTools::GetFilenamePath(sit.first); - headerBasename += "/"; - headerBasename += cmSystemTools::GetFilenameWithoutExtension(sit.first); + std::string headerBasename = + cmStrCat(cmSystemTools::GetFilenamePath(sit.first), '/', + cmSystemTools::GetFilenameWithoutExtension(sit.first)); // check if there's a matching header around for (std::string const& ext : headerExts) { - std::string hname = headerBasename; - hname += "."; - hname += ext; + std::string hname = cmStrCat(headerBasename, '.', ext); // if it's already in the set, don't check if it exists on disk std::set<std::string>::const_iterator headerIt = otherFiles.find(hname); if (headerIt != otherFiles.end()) { diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx index 9ac355c..6c94aae 100644 --- a/Source/cmExtraEclipseCDT4Generator.cxx +++ b/Source/cmExtraEclipseCDT4Generator.cxx @@ -240,8 +240,7 @@ void cmExtraEclipseCDT4Generator::AddEnvVar(std::ostream& out, std::string envVarValue; const bool envVarSet = cmSystemTools::GetEnv(envVar, envVarValue); - std::string cacheEntryName = "CMAKE_ECLIPSE_ENVVAR_"; - cacheEntryName += envVar; + std::string cacheEntryName = cmStrCat("CMAKE_ECLIPSE_ENVVAR_", envVar); const std::string* cacheValue = lg->GetState()->GetInitializedCacheValue(cacheEntryName); @@ -416,8 +415,7 @@ void cmExtraEclipseCDT4Generator::CreateProjectFile() if (const char* extraNaturesProp = mf->GetState()->GetGlobalProperty("ECLIPSE_EXTRA_NATURES")) { - std::vector<std::string> extraNatures; - cmExpandList(extraNaturesProp, extraNatures); + std::vector<std::string> extraNatures = cmExpandedList(extraNaturesProp); for (std::string const& n : extraNatures) { xml.Element("nature", n); } @@ -464,9 +462,7 @@ void cmExtraEclipseCDT4Generator::WriteGroups( cmXMLWriter& xml) { for (cmSourceGroup const& sg : sourceGroups) { - std::string linkName3 = linkName; - linkName3 += "/"; - linkName3 += sg.GetFullName(); + std::string linkName3 = cmStrCat(linkName, '/', sg.GetFullName()); std::replace(linkName3.begin(), linkName3.end(), '\\', '/'); @@ -481,9 +477,8 @@ void cmExtraEclipseCDT4Generator::WriteGroups( std::string const& fullPath = file->GetFullPath(); if (!cmSystemTools::FileIsDirectory(fullPath)) { - std::string linkName4 = linkName3; - linkName4 += "/"; - linkName4 += cmSystemTools::GetFilenameName(fullPath); + std::string linkName4 = + cmStrCat(linkName3, '/', cmSystemTools::GetFilenameName(fullPath)); cmExtraEclipseCDT4Generator::AppendLinkedResource( xml, linkName4, cmExtraEclipseCDT4Generator::GetEclipsePath(fullPath), LinkToFile); @@ -503,8 +498,7 @@ void cmExtraEclipseCDT4Generator::CreateLinksForTargets(cmXMLWriter& xml) const std::vector<cmGeneratorTarget*>& targets = lg->GetGeneratorTargets(); for (cmGeneratorTarget* target : targets) { - std::string linkName2 = linkName; - linkName2 += "/"; + std::string linkName2 = cmStrCat(linkName, '/'); switch (target->GetType()) { case cmStateEnums::EXECUTABLE: case cmStateEnums::STATIC_LIBRARY: @@ -566,8 +560,7 @@ void cmExtraEclipseCDT4Generator::CreateLinksToSubprojects( // .project itself if ((baseDir != linkSourceDirectory) && !cmSystemTools::IsSubDirectory(baseDir, linkSourceDirectory)) { - std::string linkName = "[Subprojects]/"; - linkName += it.first; + std::string linkName = cmStrCat("[Subprojects]/", it.first); cmExtraEclipseCDT4Generator::AppendLinkedResource( xml, linkName, cmExtraEclipseCDT4Generator::GetEclipsePath(linkSourceDirectory), @@ -803,8 +796,7 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const mf->GetDefinition("CMAKE_EXTRA_GENERATOR_C_SYSTEM_DEFINED_MACROS"); if (this->CEnabled && cDefs) { // Expand the list. - std::vector<std::string> defs; - cmExpandList(cDefs, defs, true); + std::vector<std::string> defs = cmExpandedList(cDefs, true); // the list must contain only definition-value pairs: if ((defs.size() % 2) == 0) { @@ -836,8 +828,7 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const mf->GetDefinition("CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_DEFINED_MACROS"); if (this->CXXEnabled && cxxDefs) { // Expand the list. - std::vector<std::string> defs; - cmExpandList(cxxDefs, defs, true); + std::vector<std::string> defs = cmExpandedList(cxxDefs, true); // the list must contain only definition-value pairs: if ((defs.size() % 2) == 0) { @@ -887,16 +878,14 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const if (this->CEnabled && !compiler.empty()) { std::string systemIncludeDirs = mf->GetSafeDefinition("CMAKE_EXTRA_GENERATOR_C_SYSTEM_INCLUDE_DIRS"); - std::vector<std::string> dirs; - cmExpandList(systemIncludeDirs, dirs); + std::vector<std::string> dirs = cmExpandedList(systemIncludeDirs); this->AppendIncludeDirectories(xml, dirs, emmited); } compiler = mf->GetSafeDefinition("CMAKE_CXX_COMPILER"); if (this->CXXEnabled && !compiler.empty()) { std::string systemIncludeDirs = mf->GetSafeDefinition("CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_INCLUDE_DIRS"); - std::vector<std::string> dirs; - cmExpandList(systemIncludeDirs, dirs); + std::vector<std::string> dirs = cmExpandedList(systemIncludeDirs); this->AppendIncludeDirectories(xml, dirs, emmited); } @@ -970,28 +959,21 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const : "[lib] "); cmExtraEclipseCDT4Generator::AppendTarget(xml, targetName, make, makeArgs, subdir, prefix); - std::string fastTarget = targetName; - fastTarget += "/fast"; + std::string fastTarget = cmStrCat(targetName, "/fast"); cmExtraEclipseCDT4Generator::AppendTarget(xml, fastTarget, make, makeArgs, subdir, prefix); // Add Build and Clean targets in the virtual folder of targets: if (this->SupportsVirtualFolders) { - std::string virtDir = "[Targets]/"; - virtDir += prefix; - virtDir += targetName; - std::string buildArgs = "-C \""; - buildArgs += lgen->GetBinaryDirectory(); - buildArgs += "\" "; - buildArgs += makeArgs; + std::string virtDir = cmStrCat("[Targets]/", prefix, targetName); + std::string buildArgs = + cmStrCat("-C \"", lgen->GetBinaryDirectory(), "\" ", makeArgs); cmExtraEclipseCDT4Generator::AppendTarget( xml, "Build", make, buildArgs, virtDir, "", targetName.c_str()); - std::string cleanArgs = "-E chdir \""; - cleanArgs += lgen->GetCurrentBinaryDirectory(); - cleanArgs += "\" \""; - cleanArgs += cmSystemTools::GetCMakeCommand(); - cleanArgs += "\" -P \""; + std::string cleanArgs = + cmStrCat("-E chdir \"", lgen->GetCurrentBinaryDirectory(), + "\" \"", cmSystemTools::GetCMakeCommand(), "\" -P \""); cmGeneratorTarget* gt = target; cleanArgs += lgen->GetTargetDirectory(gt); cleanArgs += "/cmake_clean.cmake\""; diff --git a/Source/cmExtraKateGenerator.cxx b/Source/cmExtraKateGenerator.cxx index 877f109..2bfbb0d 100644 --- a/Source/cmExtraKateGenerator.cxx +++ b/Source/cmExtraKateGenerator.cxx @@ -9,6 +9,7 @@ #include "cmMakefile.h" #include "cmSourceFile.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include <ostream> @@ -53,8 +54,7 @@ void cmExtraKateGenerator::Generate() void cmExtraKateGenerator::CreateKateProjectFile( const cmLocalGenerator* lg) const { - std::string filename = lg->GetBinaryDirectory(); - filename += "/.kateproject"; + std::string filename = cmStrCat(lg->GetBinaryDirectory(), "/.kateproject"); cmGeneratedFileStream fout(filename); if (!fout) { return; @@ -164,8 +164,7 @@ void cmExtraKateGenerator::WriteTargets(const cmLocalGenerator* lg, case cmStateEnums::OBJECT_LIBRARY: { this->AppendTarget(fout, targetName, make, makeArgs, currentDir, homeOutputDir); - std::string fastTarget = targetName; - fastTarget += "/fast"; + std::string fastTarget = cmStrCat(targetName, "/fast"); this->AppendTarget(fout, fastTarget, make, makeArgs, currentDir, homeOutputDir); @@ -208,10 +207,8 @@ void cmExtraKateGenerator::AppendTarget(cmGeneratedFileStream& fout, void cmExtraKateGenerator::CreateDummyKateProjectFile( const cmLocalGenerator* lg) const { - std::string filename = lg->GetBinaryDirectory(); - filename += "/"; - filename += this->ProjectName; - filename += ".kateproject"; + std::string filename = + cmStrCat(lg->GetBinaryDirectory(), '/', this->ProjectName, ".kateproject"); cmGeneratedFileStream fout(filename); if (!fout) { return; @@ -224,20 +221,17 @@ void cmExtraKateGenerator::CreateDummyKateProjectFile( std::string cmExtraKateGenerator::GenerateFilesString( const cmLocalGenerator* lg) const { - std::string s = lg->GetSourceDirectory(); - s += "/.git"; + std::string s = cmStrCat(lg->GetSourceDirectory(), "/.git"); if (cmSystemTools::FileExists(s)) { return "\"git\": 1 "; } - s = lg->GetSourceDirectory(); - s += "/.svn"; + s = cmStrCat(lg->GetSourceDirectory(), "/.svn"); if (cmSystemTools::FileExists(s)) { return "\"svn\": 1 "; } - s = lg->GetSourceDirectory(); - s += "/"; + s = cmStrCat(lg->GetSourceDirectory(), '/'); std::set<std::string> files; std::string tmp; diff --git a/Source/cmExtraSublimeTextGenerator.cxx b/Source/cmExtraSublimeTextGenerator.cxx index 6c17279..6f4472b 100644 --- a/Source/cmExtraSublimeTextGenerator.cxx +++ b/Source/cmExtraSublimeTextGenerator.cxx @@ -134,8 +134,7 @@ void cmExtraSublimeTextGenerator::CreateNewProjectFile( // End of build_systems fout << "\n\t]"; std::string systemName = mf->GetSafeDefinition("CMAKE_SYSTEM_NAME"); - std::vector<std::string> tokens; - cmExpandList(this->EnvSettings, tokens); + std::vector<std::string> tokens = cmExpandedList(this->EnvSettings); if (!this->EnvSettings.empty()) { fout << ","; @@ -219,8 +218,7 @@ void cmExtraSublimeTextGenerator::AppendAllTargets( this->AppendTarget(fout, targetName, lg, target, make.c_str(), makefile, compiler.c_str(), sourceFileFlags, false); - std::string fastTarget = targetName; - fastTarget += "/fast"; + std::string fastTarget = cmStrCat(targetName, "/fast"); this->AppendTarget(fout, fastTarget, lg, target, make.c_str(), makefile, compiler.c_str(), sourceFileFlags, false); @@ -311,8 +309,7 @@ void cmExtraSublimeTextGenerator::AppendTarget( std::string cmExtraSublimeTextGenerator::BuildMakeCommand( const std::string& make, const char* makefile, const std::string& target) { - std::string command = "\""; - command += make + "\""; + std::string command = cmStrCat('"', make, '"'); std::string generator = this->GlobalGenerator->GetName(); if (generator == "NMake Makefiles") { std::string makefileName = cmSystemTools::ConvertToOutputPath(makefile); @@ -345,7 +342,7 @@ std::string cmExtraSublimeTextGenerator::ComputeFlagsForObject( cmSourceFile* source, cmLocalGenerator* lg, cmGeneratorTarget* gtgt) { std::string flags; - std::string language = source->GetLanguage(); + std::string language = source->GetOrDetermineLanguage(); if (language.empty()) { language = "C"; } @@ -380,7 +377,7 @@ std::string cmExtraSublimeTextGenerator::ComputeDefines( { std::set<std::string> defines; cmMakefile* makefile = lg->GetMakefile(); - const std::string& language = source->GetLanguage(); + const std::string& language = source->GetOrDetermineLanguage(); const std::string& config = makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"); cmGeneratorExpressionInterpreter genexInterpreter(lg, config, target, language); @@ -393,8 +390,8 @@ std::string cmExtraSublimeTextGenerator::ComputeDefines( defines, genexInterpreter.Evaluate(compile_defs, COMPILE_DEFINITIONS)); } - std::string defPropName = "COMPILE_DEFINITIONS_"; - defPropName += cmSystemTools::UpperCase(config); + std::string defPropName = + cmStrCat("COMPILE_DEFINITIONS_", cmSystemTools::UpperCase(config)); if (const char* config_compile_defs = source->GetProperty(defPropName)) { lg->AppendDefines( defines, @@ -413,7 +410,7 @@ std::string cmExtraSublimeTextGenerator::ComputeIncludes( { std::vector<std::string> includes; cmMakefile* makefile = lg->GetMakefile(); - const std::string& language = source->GetLanguage(); + const std::string& language = source->GetOrDetermineLanguage(); const std::string& config = makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"); cmGeneratorExpressionInterpreter genexInterpreter(lg, config, target, language); diff --git a/Source/cmFLTKWrapUICommand.cxx b/Source/cmFLTKWrapUICommand.cxx index ccd6be9..2150051 100644 --- a/Source/cmFLTKWrapUICommand.cxx +++ b/Source/cmFLTKWrapUICommand.cxx @@ -21,12 +21,11 @@ static void FinalAction(cmMakefile& makefile, std::string const& name) // they didn;t then print a warning and add then anyhow cmTarget* target = makefile.FindLocalNonAliasTarget(name); if (!target) { - std::string msg = - "FLTK_WRAP_UI was called with a target that was never created: "; - msg += name; - msg += ". The problem was found while processing the source directory: "; - msg += makefile.GetCurrentSourceDirectory(); - msg += ". This FLTK_WRAP_UI call will be ignored."; + std::string msg = cmStrCat( + "FLTK_WRAP_UI was called with a target that was never created: ", name, + ". The problem was found while processing the source directory: ", + makefile.GetCurrentSourceDirectory(), + ". This FLTK_WRAP_UI call will be ignored."); cmSystemTools::Message(msg, "Warning"); } } diff --git a/Source/cmFileAPI.cxx b/Source/cmFileAPI.cxx index aee42d7..5d9181a 100644 --- a/Source/cmFileAPI.cxx +++ b/Source/cmFileAPI.cxx @@ -407,9 +407,7 @@ const char* cmFileAPI::ObjectKindName(ObjectKind kind) std::string cmFileAPI::ObjectName(Object const& o) { - std::string name = ObjectKindName(o.Kind); - name += "-v"; - name += std::to_string(o.Version); + std::string name = cmStrCat(ObjectKindName(o.Kind), "-v", o.Version); return name; } diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx index e4b7670..eff32ea 100644 --- a/Source/cmFileAPICodemodel.cxx +++ b/Source/cmFileAPICodemodel.cxx @@ -582,6 +582,12 @@ Json::Value CodemodelConfig::DumpTarget(cmGeneratorTarget* gt, { Target t(gt, this->Config); std::string prefix = "target-" + gt->GetName(); + for (char& c : prefix) { + // CMP0037 OLD behavior allows slashes in target names. Remove them. + if (c == '/' || c == '\\') { + c = '_'; + } + } if (!this->Config.empty()) { prefix += "-" + this->Config; } @@ -837,7 +843,7 @@ CompileData Target::BuildCompileData(cmSourceFile* sf) { CompileData fd; - fd.Language = sf->GetLanguage(); + fd.Language = sf->GetOrDetermineLanguage(); if (fd.Language.empty()) { return fd; } diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index 4f7eaea..5589537 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -97,8 +97,8 @@ bool HandleWriteImpl(std::vector<std::string> const& args, bool append, std::string fileName = *i; if (!cmsys::SystemTools::FileIsFullPath(*i)) { - fileName = status.GetMakefile().GetCurrentSourceDirectory(); - fileName += "/" + *i; + fileName = + cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', *i); } i++; @@ -134,20 +134,18 @@ bool HandleWriteImpl(std::vector<std::string> const& args, bool append, cmsys::ofstream file(fileName.c_str(), append ? std::ios::app : std::ios::out); if (!file) { - std::string error = "failed to open for writing ("; - error += cmSystemTools::GetLastSystemError(); - error += "):\n "; - error += fileName; + std::string error = + cmStrCat("failed to open for writing (", + cmSystemTools::GetLastSystemError(), "):\n ", fileName); status.SetError(error); return false; } std::string message = cmJoin(cmMakeRange(i, args.end()), std::string()); file << message; if (!file) { - std::string error = "write failed ("; - error += cmSystemTools::GetLastSystemError(); - error += "):\n "; - error += fileName; + std::string error = + cmStrCat("write failed (", cmSystemTools::GetLastSystemError(), "):\n ", + fileName); status.SetError(error); return false; } @@ -198,8 +196,8 @@ bool HandleReadCommand(std::vector<std::string> const& args, std::string fileName = fileNameArg; if (!cmsys::SystemTools::FileIsFullPath(fileName)) { - fileName = status.GetMakefile().GetCurrentSourceDirectory(); - fileName += "/" + fileNameArg; + fileName = cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', + fileNameArg); } // Open the specified file. @@ -212,10 +210,9 @@ bool HandleReadCommand(std::vector<std::string> const& args, #endif if (!file) { - std::string error = "failed to open for reading ("; - error += cmSystemTools::GetLastSystemError(); - error += "):\n "; - error += fileName; + std::string error = + cmStrCat("failed to open for reading (", + cmSystemTools::GetLastSystemError(), "):\n ", fileName); status.SetError(error); return false; } @@ -315,8 +312,8 @@ bool HandleStringsCommand(std::vector<std::string> const& args, // Get the file to read. std::string fileName = args[1]; if (!cmsys::SystemTools::FileIsFullPath(fileName)) { - fileName = status.GetMakefile().GetCurrentSourceDirectory(); - fileName += "/" + args[1]; + fileName = + cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', args[1]); } // Get the variable in which to store the results. @@ -468,8 +465,8 @@ bool HandleStringsCommand(std::vector<std::string> const& args, if (hex_conversion_enabled) { // TODO: should work without temp file, but just on a memory buffer std::string binaryFileName = - status.GetMakefile().GetCurrentBinaryDirectory(); - binaryFileName += "/CMakeFiles/FileCommandStringsBinaryFile"; + cmStrCat(status.GetMakefile().GetCurrentBinaryDirectory(), + "/CMakeFiles/FileCommandStringsBinaryFile"); if (cmHexFileConverter::TryConvert(fileName, binaryFileName)) { fileName = binaryFileName; } @@ -872,8 +869,8 @@ bool HandleMakeDirectoryCommand(std::vector<std::string> const& args, { const std::string* cdir = &arg; if (!cmsys::SystemTools::FileIsFullPath(arg)) { - expr = status.GetMakefile().GetCurrentSourceDirectory(); - expr += "/" + arg; + expr = + cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', arg); cdir = &expr; } if (!status.GetMakefile().CanIWriteThisFile(*cdir)) { @@ -903,8 +900,8 @@ bool HandleTouchImpl(std::vector<std::string> const& args, bool create, { std::string tfile = arg; if (!cmsys::SystemTools::FileIsFullPath(tfile)) { - tfile = status.GetMakefile().GetCurrentSourceDirectory(); - tfile += "/" + arg; + tfile = + cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', arg); } if (!status.GetMakefile().CanIWriteThisFile(tfile)) { std::string e = @@ -1074,11 +1071,8 @@ bool HandleRPathChangeCommand(std::vector<std::string> const& args, } if (success) { if (changed) { - std::string message = "Set runtime path of \""; - message += file; - message += "\" to \""; - message += newRPath; - message += "\""; + std::string message = + cmStrCat("Set runtime path of \"", file, "\" to \"", newRPath, '"'); status.GetMakefile().DisplayStatus(message, -1); } ft.Store(file); @@ -1136,9 +1130,8 @@ bool HandleRPathRemoveCommand(std::vector<std::string> const& args, } if (success) { if (removed) { - std::string message = "Removed runtime path from \""; - message += file; - message += "\""; + std::string message = + cmStrCat("Removed runtime path from \"", file, '"'); status.GetMakefile().DisplayStatus(message, -1); } ft.Store(file); @@ -1307,13 +1300,13 @@ bool HandleRename(std::vector<std::string> const& args, // Compute full path for old and new names. std::string oldname = args[1]; if (!cmsys::SystemTools::FileIsFullPath(oldname)) { - oldname = status.GetMakefile().GetCurrentSourceDirectory(); - oldname += "/" + args[1]; + oldname = + cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', args[1]); } std::string newname = args[2]; if (!cmsys::SystemTools::FileIsFullPath(newname)) { - newname = status.GetMakefile().GetCurrentSourceDirectory(); - newname += "/" + args[2]; + newname = + cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', args[2]); } if (!cmSystemTools::RenameFile(oldname, newname)) { @@ -1349,8 +1342,8 @@ bool HandleRemoveImpl(std::vector<std::string> const& args, bool recurse, continue; } if (!cmsys::SystemTools::FileIsFullPath(fileName)) { - fileName = status.GetMakefile().GetCurrentSourceDirectory(); - fileName += "/" + arg; + fileName = + cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', arg); } if (cmSystemTools::FileIsDirectory(fileName) && @@ -1704,8 +1697,7 @@ bool HandleDownloadCommand(std::vector<std::string> const& args, std::string::size_type pos = i->find("="); if (pos == std::string::npos) { std::string err = - "DOWNLOAD EXPECTED_HASH expects ALGO=value but got: "; - err += *i; + cmStrCat("DOWNLOAD EXPECTED_HASH expects ALGO=value but got: ", *i); status.SetError(err); return false; } @@ -1713,8 +1705,8 @@ bool HandleDownloadCommand(std::vector<std::string> const& args, expectedHash = cmSystemTools::LowerCase(i->substr(pos + 1)); hash = std::unique_ptr<cmCryptoHash>(cmCryptoHash::New(algo)); if (!hash) { - std::string err = "DOWNLOAD EXPECTED_HASH given unknown ALGO: "; - err += algo; + std::string err = + cmStrCat("DOWNLOAD EXPECTED_HASH given unknown ALGO: ", algo); status.SetError(err); return false; } @@ -1735,8 +1727,7 @@ bool HandleDownloadCommand(std::vector<std::string> const& args, curl_headers.push_back(*i); } else { // Do not return error for compatibility reason. - std::string err = "Unexpected argument: "; - err += *i; + std::string err = cmStrCat("Unexpected argument: ", *i); status.GetMakefile().IssueMessage(MessageType::AUTHOR_WARNING, err); } ++i; @@ -1749,9 +1740,8 @@ bool HandleDownloadCommand(std::vector<std::string> const& args, std::string msg; std::string actualHash = hash->HashFile(file); if (actualHash == expectedHash) { - msg = "returning early; file already exists with expected "; - msg += hashMatchMSG; - msg += "\""; + msg = cmStrCat("returning early; file already exists with expected ", + hashMatchMSG, '"'); if (!statusVar.empty()) { std::ostringstream result; result << 0 << ";\"" << msg; @@ -2050,8 +2040,7 @@ bool HandleUploadCommand(std::vector<std::string> const& args, curl_headers.push_back(*i); } else { // Do not return error for compatibility reason. - std::string err = "Unexpected argument: "; - err += *i; + std::string err = cmStrCat("Unexpected argument: ", *i); status.GetMakefile().IssueMessage(MessageType::AUTHOR_WARNING, err); } @@ -2062,8 +2051,8 @@ bool HandleUploadCommand(std::vector<std::string> const& args, // FILE* fin = cmsys::SystemTools::Fopen(filename, "rb"); if (!fin) { - std::string errStr = "UPLOAD cannot open file '"; - errStr += filename + "' for reading."; + std::string errStr = + cmStrCat("UPLOAD cannot open file '", filename, "' for reading."); status.SetError(errStr); return false; } @@ -2759,7 +2748,9 @@ bool HandleGetRuntimeDependenciesCommand(std::vector<std::string> const& args, return false; } - std::vector<std::string> deps, unresolvedDeps, conflictingDeps; + std::vector<std::string> deps; + std::vector<std::string> unresolvedDeps; + std::vector<std::string> conflictingDeps; for (auto const& val : archive.GetResolvedPaths()) { bool unique = true; auto it = val.second.begin(); diff --git a/Source/cmFileCopier.cxx b/Source/cmFileCopier.cxx index 1d66050..e00e726 100644 --- a/Source/cmFileCopier.cxx +++ b/Source/cmFileCopier.cxx @@ -91,7 +91,8 @@ bool cmFileCopier::SetPermissions(const std::string& toFile, if (!cmSystemTools::SetPermissions(toFile, permissions)) { std::ostringstream e; - e << this->Name << " cannot set permissions on \"" << toFile << "\""; + e << this->Name << " cannot set permissions on \"" << toFile + << "\": " << cmSystemTools::GetLastSystemError() << "."; this->Status.SetError(e.str()); return false; } @@ -121,7 +122,8 @@ bool cmFileCopier::ReportMissing(const std::string& fromFile) { // The input file does not exist and installation is not optional. std::ostringstream e; - e << this->Name << " cannot find \"" << fromFile << "\"."; + e << this->Name << " cannot find \"" << fromFile + << "\": " << cmSystemTools::GetLastSystemError() << "."; this->Status.SetError(e.str()); return false; } @@ -171,8 +173,8 @@ bool cmFileCopier::GetDefaultDirectoryPermissions(mode_t** mode) const char* default_dir_install_permissions = this->Makefile->GetDefinition( "CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS"); if (default_dir_install_permissions && *default_dir_install_permissions) { - std::vector<std::string> items; - cmExpandList(default_dir_install_permissions, items); + std::vector<std::string> items = + cmExpandedList(default_dir_install_permissions); for (const auto& arg : items) { if (!this->CheckPermissions(arg, **mode)) { this->Status.SetError( @@ -312,8 +314,8 @@ bool cmFileCopier::CheckValue(std::string const& arg) if (arg.empty() || cmSystemTools::FileIsFullPath(arg)) { this->Destination = arg; } else { - this->Destination = this->Makefile->GetCurrentBinaryDirectory(); - this->Destination += "/" + arg; + this->Destination = + cmStrCat(this->Makefile->GetCurrentBinaryDirectory(), '/', arg); } this->Doing = DoingNone; break; @@ -321,8 +323,8 @@ bool cmFileCopier::CheckValue(std::string const& arg) if (cmSystemTools::FileIsFullPath(arg)) { this->FilesFromDir = arg; } else { - this->FilesFromDir = this->Makefile->GetCurrentSourceDirectory(); - this->FilesFromDir += "/" + arg; + this->FilesFromDir = + cmStrCat(this->Makefile->GetCurrentSourceDirectory(), '/', arg); } cmSystemTools::ConvertToUnixSlashes(this->FilesFromDir); this->Doing = DoingNone; @@ -332,9 +334,8 @@ bool cmFileCopier::CheckValue(std::string const& arg) // leading slash and trailing end-of-string in the matched // string to make sure the pattern matches only whole file // names. - std::string regex = "/"; - regex += cmsys::Glob::PatternToRegex(arg, false); - regex += "$"; + std::string regex = + cmStrCat('/', cmsys::Glob::PatternToRegex(arg, false), '$'); this->MatchRules.emplace_back(regex); this->CurrentMatchRule = &*(this->MatchRules.end() - 1); if (this->CurrentMatchRule->Regex.is_valid()) { @@ -445,9 +446,8 @@ bool cmFileCopier::Install(const std::string& fromFile, const std::string& toFile) { if (fromFile.empty()) { - std::ostringstream e; - e << "INSTALL encountered an empty string input file name."; - this->Status.SetError(e.str()); + this->Status.SetError( + "INSTALL encountered an empty string input file name."); return false; } @@ -514,7 +514,8 @@ bool cmFileCopier::InstallSymlinkChain(std::string& fromFile, if (!cmSystemTools::CreateSymlink(symlinkTarget, toFile)) { std::ostringstream e; - e << this->Name << " cannot create symlink \"" << toFile << "\"."; + e << this->Name << " cannot create symlink \"" << toFile + << "\": " << cmSystemTools::GetLastSystemError() << "."; this->Status.SetError(e.str()); return false; } @@ -535,7 +536,8 @@ bool cmFileCopier::InstallSymlink(const std::string& fromFile, if (!cmSystemTools::ReadSymlink(fromFile, symlinkTarget)) { std::ostringstream e; e << this->Name << " cannot read symlink \"" << fromFile - << "\" to duplicate at \"" << toFile << "\"."; + << "\" to duplicate at \"" << toFile + << "\": " << cmSystemTools::GetLastSystemError() << "."; this->Status.SetError(e.str()); return false; } @@ -566,7 +568,8 @@ bool cmFileCopier::InstallSymlink(const std::string& fromFile, if (!cmSystemTools::CreateSymlink(symlinkTarget, toFile)) { std::ostringstream e; e << this->Name << " cannot duplicate symlink \"" << fromFile - << "\" at \"" << toFile << "\"."; + << "\" at \"" << toFile + << "\": " << cmSystemTools::GetLastSystemError() << "."; this->Status.SetError(e.str()); return false; } @@ -595,7 +598,7 @@ bool cmFileCopier::InstallFile(const std::string& fromFile, if (copy && !cmSystemTools::CopyAFile(fromFile, toFile, true)) { std::ostringstream e; e << this->Name << " cannot copy file \"" << fromFile << "\" to \"" - << toFile << "\"."; + << toFile << "\": " << cmSystemTools::GetLastSystemError() << "."; this->Status.SetError(e.str()); return false; } @@ -611,7 +614,7 @@ bool cmFileCopier::InstallFile(const std::string& fromFile, if (!cmFileTimes::Copy(fromFile, toFile)) { std::ostringstream e; e << this->Name << " cannot set modification time on \"" << toFile - << "\""; + << "\": " << cmSystemTools::GetLastSystemError() << "."; this->Status.SetError(e.str()); return false; } @@ -648,7 +651,7 @@ bool cmFileCopier::InstallDirectory(const std::string& source, if (!cmSystemTools::MakeDirectory(destination, default_dir_mode)) { std::ostringstream e; e << this->Name << " cannot make directory \"" << destination - << "\": " << cmSystemTools::GetLastSystemError(); + << "\": " << cmSystemTools::GetLastSystemError() << "."; this->Status.SetError(e.str()); return false; } @@ -694,12 +697,8 @@ bool cmFileCopier::InstallDirectory(const std::string& source, for (unsigned long fileNum = 0; fileNum < numFiles; ++fileNum) { if (!(strcmp(dir.GetFile(fileNum), ".") == 0 || strcmp(dir.GetFile(fileNum), "..") == 0)) { - std::string fromPath = source; - fromPath += "/"; - fromPath += dir.GetFile(fileNum); - std::string toPath = destination; - toPath += "/"; - toPath += dir.GetFile(fileNum); + std::string fromPath = cmStrCat(source, '/', dir.GetFile(fileNum)); + std::string toPath = cmStrCat(destination, '/', dir.GetFile(fileNum)); if (!this->Install(fromPath, toPath)) { return false; } diff --git a/Source/cmFileInstaller.cxx b/Source/cmFileInstaller.cxx index 6a95b92..a773738 100644 --- a/Source/cmFileInstaller.cxx +++ b/Source/cmFileInstaller.cxx @@ -59,8 +59,8 @@ void cmFileInstaller::ReportCopy(const std::string& toFile, Type type, bool copy) { if (!this->MessageNever && (copy || !this->MessageLazy)) { - std::string message = (copy ? "Installing: " : "Up-to-date: "); - message += toFile; + std::string message = + cmStrCat((copy ? "Installing: " : "Up-to-date: "), toFile); this->Makefile->DisplayStatus(message, -1); } if (type != TypeDir) { @@ -311,11 +311,11 @@ bool cmFileInstaller::HandleInstallDestination() if (ch2 == '/') { // looks like a network path. std::string message = - "called with network path DESTINATION. This " - "does not make sense when using DESTDIR. Specify local " - "absolute path or remove DESTDIR environment variable." - "\nDESTINATION=\n"; - message += destination; + cmStrCat("called with network path DESTINATION. This " + "does not make sense when using DESTDIR. Specify local " + "absolute path or remove DESTDIR environment variable." + "\nDESTINATION=\n", + destination); this->Status.SetError(message); return false; } diff --git a/Source/cmFileTimeCache.cxx b/Source/cmFileTimeCache.cxx index 24d6bf6..0d1dae5 100644 --- a/Source/cmFileTimeCache.cxx +++ b/Source/cmFileTimeCache.cxx @@ -38,7 +38,8 @@ bool cmFileTimeCache::Compare(std::string const& f1, std::string const& f2, int* result) { // Get the modification time for each file. - cmFileTime ft1, ft2; + cmFileTime ft1; + cmFileTime ft2; if (this->Load(f1, ft1) && this->Load(f2, ft2)) { // Compare the two modification times. *result = ft1.Compare(ft2); @@ -52,7 +53,8 @@ bool cmFileTimeCache::Compare(std::string const& f1, std::string const& f2, bool cmFileTimeCache::DifferS(std::string const& f1, std::string const& f2) { // Get the modification time for each file. - cmFileTime ft1, ft2; + cmFileTime ft1; + cmFileTime ft2; if (this->Load(f1, ft1) && this->Load(f2, ft2)) { // Compare the two modification times. return ft1.DifferS(ft2); diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx index 9bacfc4..cdc5f63 100644 --- a/Source/cmFindBase.cxx +++ b/Source/cmFindBase.cxx @@ -145,7 +145,7 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn) // look for old style // FIND_*(VAR name path1 path2 ...) - if (!newStyle) { + if (!newStyle && !this->Names.empty()) { // All the short-hand arguments have been recorded as names. std::vector<std::string> shortArgs = this->Names; this->Names.clear(); // clear out any values in Names @@ -189,9 +189,7 @@ void cmFindBase::FillCMakeEnvironmentPath() cmSearchPath& paths = this->LabeledPaths[PathLabel::CMakeEnvironment]; // Add CMAKE_*_PATH environment variables - std::string var = "CMAKE_"; - var += this->CMakePathName; - var += "_PATH"; + std::string var = cmStrCat("CMAKE_", this->CMakePathName, "_PATH"); paths.AddEnvPrefixPath("CMAKE_PREFIX_PATH"); paths.AddEnvPath(var); @@ -223,9 +221,7 @@ void cmFindBase::FillCMakeVariablePath() // Add CMake variables of the same name as the previous environment // variables CMAKE_*_PATH to be used most of the time with -D // command line options - std::string var = "CMAKE_"; - var += this->CMakePathName; - var += "_PATH"; + std::string var = cmStrCat("CMAKE_", this->CMakePathName, "_PATH"); paths.AddCMakePrefixPath("CMAKE_PREFIX_PATH"); paths.AddCMakePath(var); @@ -257,9 +253,7 @@ void cmFindBase::FillCMakeSystemVariablePath() { cmSearchPath& paths = this->LabeledPaths[PathLabel::CMakeSystem]; - std::string var = "CMAKE_SYSTEM_"; - var += this->CMakePathName; - var += "_PATH"; + std::string var = cmStrCat("CMAKE_SYSTEM_", this->CMakePathName, "_PATH"); paths.AddCMakePrefixPath("CMAKE_SYSTEM_PREFIX_PATH"); paths.AddCMakePath(var); diff --git a/Source/cmFindCommon.cxx b/Source/cmFindCommon.cxx index c5209c4..9425f99 100644 --- a/Source/cmFindCommon.cxx +++ b/Source/cmFindCommon.cxx @@ -92,8 +92,8 @@ void cmFindCommon::InitializeSearchPathGroups() void cmFindCommon::SelectDefaultRootPathMode() { // Check the policy variable for this find command type. - std::string findRootPathVar = "CMAKE_FIND_ROOT_PATH_MODE_"; - findRootPathVar += this->CMakePathName; + std::string findRootPathVar = + cmStrCat("CMAKE_FIND_ROOT_PATH_MODE_", this->CMakePathName); std::string rootPathMode = this->Makefile->GetSafeDefinition(findRootPathVar); if (rootPathMode == "NEVER") { @@ -229,8 +229,7 @@ void cmFindCommon::RerootPaths(std::vector<std::string>& paths) rootedDir = up; } else if (!up.empty() && up[0] != '~') { // Start with the new root. - rootedDir = r; - rootedDir += "/"; + rootedDir = cmStrCat(r, '/'); // Append the original path with its old root removed. rootedDir += cmSystemTools::SplitPathRootComponent(up); diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx index dc160b5..924a14e 100644 --- a/Source/cmFindLibraryCommand.cxx +++ b/Source/cmFindLibraryCommand.cxx @@ -312,8 +312,7 @@ void cmFindLibraryHelper::AddName(std::string const& name) entry.Raw = name; // Build a regular expression to match library names. - std::string regex = "^"; - regex += this->PrefixRegexStr; + std::string regex = cmStrCat('^', this->PrefixRegexStr); this->RegexFromLiteral(regex, name); regex += this->SuffixRegexStr; if (this->OpenBSD) { @@ -349,8 +348,7 @@ bool cmFindLibraryHelper::CheckDirectoryForName(std::string const& path, // one cannot tell just from the library name whether it is a static // library or an import library). if (name.TryRaw) { - this->TestPath = path; - this->TestPath += name.Raw; + this->TestPath = cmStrCat(path, name.Raw); if (cmSystemTools::FileExists(this->TestPath, true)) { this->BestPath = cmSystemTools::CollapseFullPath(this->TestPath); cmSystemTools::ConvertToUnixSlashes(this->BestPath); @@ -375,8 +373,7 @@ bool cmFindLibraryHelper::CheckDirectoryForName(std::string const& path, std::string const& testName = origName; #endif if (name.Regex.find(testName)) { - this->TestPath = path; - this->TestPath += origName; + this->TestPath = cmStrCat(path, origName); if (!cmSystemTools::FileIsDirectory(this->TestPath)) { // This is a matching file. Check if it is better than the // best name found so far. Earlier prefixes are preferred, @@ -466,9 +463,7 @@ std::string cmFindLibraryCommand::FindFrameworkLibraryNamesPerDir() // Search for all names in each search path. for (std::string const& d : this->SearchPaths) { for (std::string const& n : this->Names) { - fwPath = d; - fwPath += n; - fwPath += ".framework"; + fwPath = cmStrCat(d, n, ".framework"); if (cmSystemTools::FileIsDirectory(fwPath)) { return cmSystemTools::CollapseFullPath(fwPath); } @@ -485,9 +480,7 @@ std::string cmFindLibraryCommand::FindFrameworkLibraryDirsPerName() // Search for each name in all search paths. for (std::string const& n : this->Names) { for (std::string const& d : this->SearchPaths) { - fwPath = d; - fwPath += n; - fwPath += ".framework"; + fwPath = cmStrCat(d, n, ".framework"); if (cmSystemTools::FileIsDirectory(fwPath)) { return cmSystemTools::CollapseFullPath(fwPath); } diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index ae93eff..9132760 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -408,19 +408,16 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args, if (this->Version.empty() || components.empty()) { // Check whether we are recursing inside "Find<name>.cmake" within // another find_package(<name>) call. - std::string mod = this->Name; - mod += "_FIND_MODULE"; + std::string mod = cmStrCat(this->Name, "_FIND_MODULE"); if (this->Makefile->IsOn(mod)) { if (this->Version.empty()) { // Get version information from the outer call if necessary. // Requested version string. - std::string ver = this->Name; - ver += "_FIND_VERSION"; + std::string ver = cmStrCat(this->Name, "_FIND_VERSION"); this->Version = this->Makefile->GetSafeDefinition(ver); // Whether an exact version is required. - std::string exact = this->Name; - exact += "_FIND_VERSION_EXACT"; + std::string exact = cmStrCat(this->Name, "_FIND_VERSION_EXACT"); this->VersionExact = this->Makefile->IsOn(exact); } if (components.empty()) { @@ -458,8 +455,8 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args, } } - std::string disableFindPackageVar = "CMAKE_DISABLE_FIND_PACKAGE_"; - disableFindPackageVar += this->Name; + std::string disableFindPackageVar = + cmStrCat("CMAKE_DISABLE_FIND_PACKAGE_", this->Name); if (this->Makefile->IsOn(disableFindPackageVar)) { if (this->Required) { std::ostringstream e; @@ -589,8 +586,7 @@ bool cmFindPackageCommand::FindPackageUsingModuleMode() bool cmFindPackageCommand::FindPackageUsingConfigMode() { - this->Variable = this->Name; - this->Variable += "_DIR"; + this->Variable = cmStrCat(this->Name, "_DIR"); // Add the default name. if (this->Names.empty()) { @@ -600,12 +596,10 @@ bool cmFindPackageCommand::FindPackageUsingConfigMode() // Add the default configs. if (this->Configs.empty()) { for (std::string const& n : this->Names) { - std::string config = n; - config += "Config.cmake"; + std::string config = cmStrCat(n, "Config.cmake"); this->Configs.push_back(config); - config = cmSystemTools::LowerCase(n); - config += "-config.cmake"; + config = cmStrCat(cmSystemTools::LowerCase(n), "-config.cmake"); this->Configs.push_back(std::move(config)); } } @@ -634,24 +628,21 @@ void cmFindPackageCommand::SetModuleVariables(const std::string& components) if (this->Quiet) { // Tell the module that is about to be read that it should find // quietly. - std::string quietly = this->Name; - quietly += "_FIND_QUIETLY"; + std::string quietly = cmStrCat(this->Name, "_FIND_QUIETLY"); this->AddFindDefinition(quietly, "1"); } if (this->Required) { // Tell the module that is about to be read that it should report // a fatal error if the package is not found. - std::string req = this->Name; - req += "_FIND_REQUIRED"; + std::string req = cmStrCat(this->Name, "_FIND_REQUIRED"); this->AddFindDefinition(req, "1"); } if (!this->Version.empty()) { // Tell the module that is about to be read what version of the // package has been requested. - std::string ver = this->Name; - ver += "_FIND_VERSION"; + std::string ver = cmStrCat(this->Name, "_FIND_VERSION"); this->AddFindDefinition(ver, this->Version.c_str()); char buf[64]; sprintf(buf, "%u", this->VersionMajor); @@ -666,8 +657,7 @@ void cmFindPackageCommand::SetModuleVariables(const std::string& components) this->AddFindDefinition(ver + "_COUNT", buf); // Tell the module whether an exact version has been requested. - std::string exact = this->Name; - exact += "_FIND_VERSION_EXACT"; + std::string exact = cmStrCat(this->Name, "_FIND_VERSION_EXACT"); this->AddFindDefinition(exact, this->VersionExact ? "1" : "0"); } } @@ -700,9 +690,7 @@ void cmFindPackageCommand::RestoreFindDefinitions() bool cmFindPackageCommand::FindModule(bool& found) { - std::string module = "Find"; - module += this->Name; - module += ".cmake"; + std::string module = cmStrCat("Find", this->Name, ".cmake"); bool system = false; std::string mfile = this->Makefile->GetModulesFile(module, system); if (!mfile.empty()) { @@ -731,8 +719,7 @@ bool cmFindPackageCommand::FindModule(bool& found) // Load the module we found, and set "<name>_FIND_MODULE" to true // while inside it. found = true; - std::string var = this->Name; - var += "_FIND_MODULE"; + std::string var = cmStrCat(this->Name, "_FIND_MODULE"); this->Makefile->AddDefinition(var, "1"); bool result = this->ReadListFile(mfile, DoPolicyScope); this->Makefile->RemoveDefinition(var); @@ -785,10 +772,8 @@ bool cmFindPackageCommand::HandlePackageMode( } } - std::string foundVar = this->Name; - foundVar += "_FOUND"; - std::string notFoundMessageVar = this->Name; - notFoundMessageVar += "_NOT_FOUND_MESSAGE"; + std::string foundVar = cmStrCat(this->Name, "_FOUND"); + std::string notFoundMessageVar = cmStrCat(this->Name, "_NOT_FOUND_MESSAGE"); std::string notFoundMessage; // If the directory for the config file was found, try to read the file. @@ -878,9 +863,8 @@ bool cmFindPackageCommand::HandlePackageMode( } else { std::string requestedVersionString; if (!this->Version.empty()) { - requestedVersionString = " (requested version "; - requestedVersionString += this->Version; - requestedVersionString += ")"; + requestedVersionString = + cmStrCat(" (requested version ", this->Version, ')'); } if (this->UseConfigFiles) { @@ -962,18 +946,17 @@ bool cmFindPackageCommand::HandlePackageMode( this->Makefile->AddDefinition(foundVar, found ? "1" : "0"); // Set a variable naming the configuration file that was found. - std::string fileVar = this->Name; - fileVar += "_CONFIG"; + std::string fileVar = cmStrCat(this->Name, "_CONFIG"); if (found) { this->Makefile->AddDefinition(fileVar, this->FileFound); } else { this->Makefile->RemoveDefinition(fileVar); } - std::string consideredConfigsVar = this->Name; - consideredConfigsVar += "_CONSIDERED_CONFIGS"; - std::string consideredVersionsVar = this->Name; - consideredVersionsVar += "_CONSIDERED_VERSIONS"; + std::string consideredConfigsVar = + cmStrCat(this->Name, "_CONSIDERED_CONFIGS"); + std::string consideredVersionsVar = + cmStrCat(this->Name, "_CONSIDERED_VERSIONS"); std::string consideredConfigFiles; std::string consideredVersions; @@ -1035,9 +1018,8 @@ bool cmFindPackageCommand::FindConfig() init = this->Variable + "-NOTFOUND"; } std::string help = - "The directory containing a CMake configuration file for "; - help += this->Name; - help += "."; + cmStrCat("The directory containing a CMake configuration file for ", + this->Name, '.'); // We force the value since we do not get here if it was already set. this->Makefile->AddCacheDefinition(this->Variable, init.c_str(), help.c_str(), cmStateEnums::PATH, true); @@ -1084,9 +1066,7 @@ bool cmFindPackageCommand::ReadListFile(const std::string& f, if (this->Makefile->ReadDependentFile(f, noPolicyScope)) { return true; } - std::string e = "Error reading CMake code from \""; - e += f; - e += "\"."; + std::string e = cmStrCat("Error reading CMake code from \"", f, "\"."); this->SetError(e); return false; } @@ -1138,12 +1118,11 @@ void cmFindPackageCommand::AppendToFoundProperty(bool found) void cmFindPackageCommand::AppendSuccessInformation() { { - std::string transitivePropName = "_CMAKE_"; - transitivePropName += this->Name + "_TRANSITIVE_DEPENDENCY"; + std::string transitivePropName = + cmStrCat("_CMAKE_", this->Name, "_TRANSITIVE_DEPENDENCY"); this->Makefile->GetState()->SetGlobalProperty(transitivePropName, "False"); } - std::string found = this->Name; - found += "_FOUND"; + std::string found = cmStrCat(this->Name, "_FOUND"); std::string upperFound = cmSystemTools::UpperCase(found); const char* upperResult = this->Makefile->GetDefinition(upperFound); @@ -1154,28 +1133,23 @@ void cmFindPackageCommand::AppendSuccessInformation() // Record whether the find was quiet or not, so this can be used // e.g. in FeatureSummary.cmake - std::string quietInfoPropName = "_CMAKE_"; - quietInfoPropName += this->Name; - quietInfoPropName += "_QUIET"; + std::string quietInfoPropName = cmStrCat("_CMAKE_", this->Name, "_QUIET"); this->Makefile->GetState()->SetGlobalProperty( quietInfoPropName, this->Quiet ? "TRUE" : "FALSE"); // set a global property to record the required version of this package - std::string versionInfoPropName = "_CMAKE_"; - versionInfoPropName += this->Name; - versionInfoPropName += "_REQUIRED_VERSION"; + std::string versionInfoPropName = + cmStrCat("_CMAKE_", this->Name, "_REQUIRED_VERSION"); std::string versionInfo; if (!this->Version.empty()) { - versionInfo = this->VersionExact ? "==" : ">="; - versionInfo += " "; - versionInfo += this->Version; + versionInfo = + cmStrCat(this->VersionExact ? "==" : ">=", ' ', this->Version); } this->Makefile->GetState()->SetGlobalProperty(versionInfoPropName, versionInfo.c_str()); if (this->Required) { - std::string requiredInfoPropName = "_CMAKE_"; - requiredInfoPropName += this->Name; - requiredInfoPropName += "_TYPE"; + std::string requiredInfoPropName = + cmStrCat("_CMAKE_", this->Name, "_TYPE"); this->Makefile->GetState()->SetGlobalProperty(requiredInfoPropName, "REQUIRED"); } @@ -1285,9 +1259,7 @@ void cmFindPackageCommand::FillPrefixesUserRegistry() char dir[B_PATH_NAME_LENGTH]; if (find_directory(B_USER_SETTINGS_DIRECTORY, -1, false, dir, sizeof(dir)) == B_OK) { - std::string fname = dir; - fname += "/cmake/packages/"; - fname += Name; + std::string fname = cmStrCat(dir, "/cmake/packages/", Name); this->LoadPackageRegistryDir(fname, this->LabeledPaths[PathLabel::UserRegistry]); } @@ -1428,9 +1400,7 @@ void cmFindPackageCommand::LoadPackageRegistryDir(std::string const& dir, std::string fname; for (unsigned long i = 0; i < files.GetNumberOfFiles(); ++i) { - fname = dir; - fname += "/"; - fname += files.GetFile(i); + fname = cmStrCat(dir, '/', files.GetFile(i)); if (!cmSystemTools::FileIsDirectory(fname)) { // Hold this file hostage until it behaves. @@ -1545,9 +1515,7 @@ bool cmFindPackageCommand::FindConfigFile(std::string const& dir, } for (std::string const& c : this->Configs) { - file = dir; - file += "/"; - file += c; + file = cmStrCat(dir, '/', c); if (this->DebugMode) { fprintf(stderr, "Checking file [%s]\n", file.c_str()); } @@ -1573,16 +1541,14 @@ bool cmFindPackageCommand::CheckVersion(std::string const& config_file) std::string version_file_base = config_file.substr(0, pos); // Look for foo-config-version.cmake - std::string version_file = version_file_base; - version_file += "-version.cmake"; + std::string version_file = cmStrCat(version_file_base, "-version.cmake"); if (!haveResult && cmSystemTools::FileExists(version_file, true)) { result = this->CheckVersionFile(version_file, version); haveResult = true; } // Look for fooConfigVersion.cmake - version_file = version_file_base; - version_file += "Version.cmake"; + version_file = cmStrCat(version_file_base, "Version.cmake"); if (!haveResult && cmSystemTools::FileExists(version_file, true)) { result = this->CheckVersionFile(version_file, version); haveResult = true; @@ -1690,8 +1656,7 @@ bool cmFindPackageCommand::CheckVersionFile(std::string const& version_file, void cmFindPackageCommand::StoreVersionFound() { // Store the whole version string. - std::string ver = this->Name; - ver += "_VERSION"; + std::string ver = cmStrCat(this->Name, "_VERSION"); if (this->VersionFound.empty()) { this->Makefile->RemoveDefinition(ver); } else { @@ -2039,8 +2004,7 @@ private: bool Search(std::string const& parent, cmFileList& lister) override { // Glob the set of matching files. - std::string expr = parent; - expr += this->Pattern; + std::string expr = cmStrCat(parent, this->Pattern); cmsys::Glob g; if (!g.FindFiles(expr)) { return false; diff --git a/Source/cmFindPathCommand.cxx b/Source/cmFindPathCommand.cxx index 38ff2ed..41f5e51 100644 --- a/Source/cmFindPathCommand.cxx +++ b/Source/cmFindPathCommand.cxx @@ -6,6 +6,7 @@ #include "cmMakefile.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" class cmExecutionStatus; @@ -88,12 +89,8 @@ std::string cmFindPathCommand::FindHeaderInFramework(std::string const& file, frameWorkName.clear(); } if (!frameWorkName.empty()) { - std::string fpath = dir; - fpath += frameWorkName; - fpath += ".framework"; - std::string intPath = fpath; - intPath += "/Headers/"; - intPath += fileName; + std::string fpath = cmStrCat(dir, frameWorkName, ".framework"); + std::string intPath = cmStrCat(fpath, "/Headers/", fileName); if (cmSystemTools::FileExists(intPath)) { if (this->IncludeFileInPath) { return intPath; @@ -104,9 +101,7 @@ std::string cmFindPathCommand::FindHeaderInFramework(std::string const& file, } // if it is not found yet or not a framework header, then do a glob search // for all frameworks in the directory: dir/*.framework/Headers/<file> - std::string glob = dir; - glob += "*.framework/Headers/"; - glob += file; + std::string glob = cmStrCat(dir, "*.framework/Headers/", file); cmsys::Glob globIt; globIt.FindFiles(glob); std::vector<std::string> files = globIt.GetFiles(); @@ -126,8 +121,7 @@ std::string cmFindPathCommand::FindNormalHeader() std::string tryPath; for (std::string const& n : this->Names) { for (std::string const& sp : this->SearchPaths) { - tryPath = sp; - tryPath += n; + tryPath = cmStrCat(sp, n); if (cmSystemTools::FileExists(tryPath)) { if (this->IncludeFileInPath) { return tryPath; diff --git a/Source/cmFindProgramCommand.cxx b/Source/cmFindProgramCommand.cxx index 8fcf1ac..a2db65c 100644 --- a/Source/cmFindProgramCommand.cxx +++ b/Source/cmFindProgramCommand.cxx @@ -75,8 +75,7 @@ struct cmFindProgramHelper if (!ext.empty() && cmHasSuffix(name, ext)) { continue; } - this->TestNameExt = name; - this->TestNameExt += ext; + this->TestNameExt = cmStrCat(name, ext); this->TestPath = cmSystemTools::CollapseFullPath(this->TestNameExt, path); diff --git a/Source/cmForEachCommand.cxx b/Source/cmForEachCommand.cxx index 9c6f1b4..f0633aa 100644 --- a/Source/cmForEachCommand.cxx +++ b/Source/cmForEachCommand.cxx @@ -20,6 +20,9 @@ #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +namespace { +bool HandleInMode(std::vector<std::string> const& args, cmMakefile& makefile); + class cmForEachFunctionBlocker : public cmFunctionBlocker { public: @@ -102,20 +105,21 @@ bool cmForEachFunctionBlocker::Replay( mf.AddDefinition(this->Args[0], oldDef); return true; } +} -bool cmForEachCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmForEachCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.empty()) { - this->SetError("called with incorrect number of arguments"); + status.SetError("called with incorrect number of arguments"); return false; } if (args.size() > 1 && args[1] == "IN") { - return this->HandleInMode(args); + return HandleInMode(args, status.GetMakefile()); } // create a function blocker - auto fb = cm::make_unique<cmForEachFunctionBlocker>(this->Makefile); + auto fb = cm::make_unique<cmForEachFunctionBlocker>(&status.GetMakefile()); if (args.size() > 1) { if (args[1] == "RANGE") { int start = 0; @@ -145,7 +149,7 @@ bool cmForEachCommand::InitialPass(std::vector<std::string> const& args, std::ostringstream str; str << "called with incorrect range specification: start "; str << start << ", stop " << stop << ", step " << step; - this->SetError(str.str()); + status.SetError(str.str()); return false; } std::vector<std::string> range; @@ -169,14 +173,15 @@ bool cmForEachCommand::InitialPass(std::vector<std::string> const& args, } else { fb->Args = args; } - this->Makefile->AddFunctionBlocker(std::move(fb)); + status.GetMakefile().AddFunctionBlocker(std::move(fb)); return true; } -bool cmForEachCommand::HandleInMode(std::vector<std::string> const& args) +namespace { +bool HandleInMode(std::vector<std::string> const& args, cmMakefile& makefile) { - auto fb = cm::make_unique<cmForEachFunctionBlocker>(this->Makefile); + auto fb = cm::make_unique<cmForEachFunctionBlocker>(&makefile); fb->Args.push_back(args[0]); enum Doing @@ -194,7 +199,7 @@ bool cmForEachCommand::HandleInMode(std::vector<std::string> const& args) } else if (args[i] == "ITEMS") { doing = DoingItems; } else if (doing == DoingLists) { - const char* value = this->Makefile->GetDefinition(args[i]); + const char* value = makefile.GetDefinition(args[i]); if (value && *value) { cmExpandList(value, fb->Args, true); } @@ -202,12 +207,13 @@ bool cmForEachCommand::HandleInMode(std::vector<std::string> const& args) std::ostringstream e; e << "Unknown argument:\n" << " " << args[i] << "\n"; - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + makefile.IssueMessage(MessageType::FATAL_ERROR, e.str()); return true; } } - this->Makefile->AddFunctionBlocker(std::move(fb)); + makefile.AddFunctionBlocker(std::move(fb)); return true; } +} diff --git a/Source/cmForEachCommand.h b/Source/cmForEachCommand.h index 135abf0..1feb965 100644 --- a/Source/cmForEachCommand.h +++ b/Source/cmForEachCommand.h @@ -8,33 +8,9 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; /// Starts foreach() ... endforeach() block -class cmForEachCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmForEachCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; - -private: - bool HandleInMode(std::vector<std::string> const& args); -}; - +bool cmForEachCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmFortranParserImpl.cxx b/Source/cmFortranParserImpl.cxx index e8b1da8..ad377de 100644 --- a/Source/cmFortranParserImpl.cxx +++ b/Source/cmFortranParserImpl.cxx @@ -1,6 +1,8 @@ /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmFortranParser.h" + +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include <assert.h> @@ -22,9 +24,7 @@ bool cmFortranParser_s::FindIncludeFile(const char* dir, } // Check for the file in the directory containing the including // file. - std::string fullName = dir; - fullName += "/"; - fullName += includeName; + std::string fullName = cmStrCat(dir, '/', includeName); if (cmSystemTools::FileExists(fullName, true)) { fileName = fullName; return true; @@ -32,9 +32,7 @@ bool cmFortranParser_s::FindIncludeFile(const char* dir, // Search the include path for the file. for (std::string const& i : this->IncludePath) { - fullName = i; - fullName += "/"; - fullName += includeName; + fullName = cmStrCat(i, '/', includeName); if (cmSystemTools::FileExists(fullName, true)) { fileName = fullName; return true; diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx index 610f516..9420541 100644 --- a/Source/cmFunctionCommand.cxx +++ b/Source/cmFunctionCommand.cxx @@ -5,6 +5,7 @@ #include <sstream> #include <utility> +#include "cm_memory.hxx" #include "cm_static_string_view.hxx" #include "cm_string_view.hxx" @@ -18,6 +19,7 @@ #include "cmState.h" #include "cmStringAlgorithms.h" +namespace { // define the class for function commands class cmFunctionHelperCommand { @@ -34,6 +36,7 @@ public: cmPolicies::PolicyMap Policies; std::string FilePath; }; +} bool cmFunctionHelperCommand::operator()( std::vector<cmListFileArgument> const& args, @@ -48,9 +51,9 @@ bool cmFunctionHelperCommand::operator()( // make sure the number of arguments passed is at least the number // required by the signature if (expandedArgs.size() < this->Args.size() - 1) { - std::string errorMsg = - "Function invoked with incorrect arguments for function named: "; - errorMsg += this->Args[0]; + std::string errorMsg = cmStrCat( + "Function invoked with incorrect arguments for function named: ", + this->Args[0]); inStatus.SetError(errorMsg); return false; } @@ -59,9 +62,7 @@ bool cmFunctionHelperCommand::operator()( this->Policies); // set the value of argc - std::ostringstream strStream; - strStream << expandedArgs.size(); - makefile.AddDefinition("ARGC", strStream.str()); + makefile.AddDefinition("ARGC", std::to_string(expandedArgs.size())); makefile.MarkVariableAsUsed("ARGC"); // set the values for ARGV0 ARGV1 ... @@ -145,11 +146,11 @@ bool cmFunctionFunctionBlocker::Replay( return true; } -bool cmFunctionCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmFunctionCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.empty()) { - this->SetError("called with incorrect number of arguments"); + status.SetError("called with incorrect number of arguments"); return false; } @@ -157,7 +158,7 @@ bool cmFunctionCommand::InitialPass(std::vector<std::string> const& args, { auto fb = cm::make_unique<cmFunctionFunctionBlocker>(); cmAppend(fb->Args, args); - this->Makefile->AddFunctionBlocker(std::move(fb)); + status.GetMakefile().AddFunctionBlocker(std::move(fb)); } return true; } diff --git a/Source/cmFunctionCommand.h b/Source/cmFunctionCommand.h index b334525..d6b549c 100644 --- a/Source/cmFunctionCommand.h +++ b/Source/cmFunctionCommand.h @@ -8,30 +8,10 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; /// Starts function() ... endfunction() block -class cmFunctionCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmFunctionCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; +bool cmFunctionCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmGeneratorExpressionDAGChecker.h b/Source/cmGeneratorExpressionDAGChecker.h index 6d7d6ef..b72a40f 100644 --- a/Source/cmGeneratorExpressionDAGChecker.h +++ b/Source/cmGeneratorExpressionDAGChecker.h @@ -29,7 +29,8 @@ class cmGeneratorTarget; SELECT(F, EvaluatingCompileFeatures, COMPILE_FEATURES) \ SELECT(F, EvaluatingLinkOptions, LINK_OPTIONS) \ SELECT(F, EvaluatingLinkDirectories, LINK_DIRECTORIES) \ - SELECT(F, EvaluatingLinkDepends, LINK_DEPENDS) + SELECT(F, EvaluatingLinkDepends, LINK_DEPENDS) \ + SELECT(F, EvaluatingPrecompileHeaders, PRECOMPILE_HEADERS) #define CM_FOR_EACH_TRANSITIVE_PROPERTY(F) \ CM_FOR_EACH_TRANSITIVE_PROPERTY_IMPL(F, CM_SELECT_BOTH) diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx index 9f761ed..667f4a0 100644 --- a/Source/cmGeneratorExpressionNode.cxx +++ b/Source/cmGeneratorExpressionNode.cxx @@ -19,11 +19,11 @@ #include "cmState.h" #include "cmStateSnapshot.h" #include "cmStateTypes.h" +#include "cmString.hxx" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" #include "cm_static_string_view.hxx" -#include "cm_string_view.hxx" #include "cmake.h" #include "cmsys/RegularExpression.hxx" @@ -275,7 +275,8 @@ static const struct InListNode : public cmGeneratorExpressionNode const GeneratorExpressionContent* /*content*/, cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override { - std::vector<std::string> values, checkValues; + std::vector<std::string> values; + std::vector<std::string> checkValues; bool check = false; switch (context->LG->GetPolicyStatus(cmPolicies::CMP0085)) { case cmPolicies::WARN: @@ -306,10 +307,7 @@ static const struct InListNode : public cmGeneratorExpressionNode break; } - return std::find(values.cbegin(), values.cend(), parameters.front()) == - values.cend() - ? "0" - : "1"; + return cmContains(values, parameters.front()) ? "1" : "0"; } } inListNode; @@ -347,7 +345,8 @@ static const struct FilterNode : public cmGeneratorExpressionNode return {}; } - std::vector<std::string> values, result; + std::vector<std::string> values; + std::vector<std::string> result; cmExpandList(parameters.front(), values, true); std::copy_if(values.cbegin(), values.cend(), std::back_inserter(result), @@ -376,8 +375,7 @@ static const struct RemoveDuplicatesNode : public cmGeneratorExpressionNode "$<REMOVE_DUPLICATES:...> expression requires one parameter"); } - std::vector<std::string> values; - cmExpandList(parameters.front(), values, true); + std::vector<std::string> values = cmExpandedList(parameters.front(), true); auto valuesEnd = cmRemoveDuplicates(values); auto valuesBegin = values.cbegin(); @@ -685,10 +683,10 @@ struct CompilerIdNode : public cmGeneratorExpressionNode if (cmsysString_strcasecmp(param.c_str(), compilerId.c_str()) == 0) { switch (context->LG->GetPolicyStatus(cmPolicies::CMP0044)) { case cmPolicies::WARN: { - std::ostringstream e; - e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0044); context->LG->GetCMakeInstance()->IssueMessage( - MessageType::AUTHOR_WARNING, e.str(), context->Backtrace); + MessageType::AUTHOR_WARNING, + cmPolicies::GetPolicyWarning(cmPolicies::CMP0044), + context->Backtrace); CM_FALLTHROUGH; } case cmPolicies::OLD: @@ -910,14 +908,13 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode // for this (possibly mapped) config. // Check if there is a proper config mapping for the tested config. std::vector<std::string> mappedConfigs; - std::string mapProp = "MAP_IMPORTED_CONFIG_"; - mapProp += cmSystemTools::UpperCase(context->Config); + std::string mapProp = cmStrCat( + "MAP_IMPORTED_CONFIG_", cmSystemTools::UpperCase(context->Config)); if (const char* mapValue = context->CurrentTarget->GetProperty(mapProp)) { cmExpandList(cmSystemTools::UpperCase(mapValue), mappedConfigs); - return std::find(mappedConfigs.begin(), mappedConfigs.end(), - cmSystemTools::UpperCase(parameters.front())) != - mappedConfigs.end() + return cmContains(mappedConfigs, + cmSystemTools::UpperCase(parameters.front())) ? "1" : "0"; } @@ -941,8 +938,7 @@ static const struct JoinNode : public cmGeneratorExpressionNode const GeneratorExpressionContent* /*content*/, cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override { - std::vector<std::string> list; - cmExpandList(parameters.front(), list); + std::vector<std::string> list = cmExpandedList(parameters.front()); return cmJoin(list, parameters[1]); } } joinNode; @@ -1109,7 +1105,8 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode static cmsys::RegularExpression propertyNameValidator("^[A-Za-z0-9_]+$"); cmGeneratorTarget const* target = nullptr; - std::string targetName, propertyName; + std::string targetName; + std::string propertyName; if (parameters.size() == 2) { targetName = parameters[0]; @@ -1510,8 +1507,7 @@ static const struct CompileFeaturesNode : public cmGeneratorExpressionNode const char* standardDefault = context->LG->GetMakefile()->GetDefinition( "CMAKE_" + lit.first + "_STANDARD_DEFAULT"); for (std::string const& it : lit.second) { - if (std::find(langAvailable.begin(), langAvailable.end(), it) == - langAvailable.end()) { + if (!cmContains(langAvailable, it)) { return "0"; } if (standardDefault && !*standardDefault) { @@ -1697,9 +1693,8 @@ struct TargetFilesystemArtifactResultCreator<ArtifactSonameTag> "SHARED libraries."); return std::string(); } - std::string result = target->GetDirectory(context->Config); - result += "/"; - result += target->GetSOName(context->Config); + std::string result = cmStrCat(target->GetDirectory(context->Config), '/', + target->GetSOName(context->Config)); return result; } }; @@ -1738,9 +1733,8 @@ struct TargetFilesystemArtifactResultCreator<ArtifactPdbTag> return std::string(); } - std::string result = target->GetPDBDirectory(context->Config); - result += "/"; - result += target->GetPDBName(context->Config); + std::string result = cmStrCat(target->GetPDBDirectory(context->Config), + '/', target->GetPDBName(context->Config)); return result; } }; @@ -2213,8 +2207,7 @@ static const struct ShellPathNode : public cmGeneratorExpressionNode const GeneratorExpressionContent* content, cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override { - std::vector<std::string> listIn; - cmExpandList(parameters.front(), listIn); + std::vector<std::string> listIn = cmExpandedList(parameters.front()); if (listIn.empty()) { reportError(context, content->GetOriginalExpression(), "\"\" is not an absolute path."); diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 4dd1e5b..cc37232 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -21,6 +21,7 @@ #include "cmCustomCommand.h" #include "cmCustomCommandGenerator.h" #include "cmCustomCommandLines.h" +#include "cmGeneratedFileStream.h" #include "cmGeneratorExpression.h" #include "cmGeneratorExpressionContext.h" #include "cmGeneratorExpressionDAGChecker.h" @@ -39,6 +40,7 @@ #include "cmTarget.h" #include "cmTargetLinkLibraryType.h" #include "cmTargetPropertyComputer.h" +#include "cm_string_view.hxx" #include "cmake.h" class cmMessenger; @@ -277,6 +279,7 @@ cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg) , DebugCompileDefinitionsDone(false) , DebugLinkOptionsDone(false) , DebugLinkDirectoriesDone(false) + , DebugPrecompileHeadersDone(false) , DebugSourcesDone(false) , LinkImplementationLanguageIsContextDependent(true) , UtilityItemsDone(false) @@ -311,6 +314,10 @@ cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg) t->GetLinkDirectoriesBacktraces(), this->LinkDirectoriesEntries); + CreatePropertyGeneratorExpressions(t->GetPrecompileHeadersEntries(), + t->GetPrecompileHeadersBacktraces(), + this->PrecompileHeadersEntries); + CreatePropertyGeneratorExpressions(t->GetSourceEntries(), t->GetSourceBacktraces(), this->SourceEntries, true); @@ -326,6 +333,7 @@ cmGeneratorTarget::~cmGeneratorTarget() cmDeleteAll(this->CompileDefinitionsEntries); cmDeleteAll(this->LinkOptionsEntries); cmDeleteAll(this->LinkDirectoriesEntries); + cmDeleteAll(this->PrecompileHeadersEntries); cmDeleteAll(this->SourceEntries); cmDeleteAll(this->LinkInformation); } @@ -526,7 +534,9 @@ std::string cmGeneratorTarget::GetFilePrefix( return prefix ? prefix : std::string(); } - std::string prefix, suffix, base; + std::string prefix; + std::string suffix; + std::string base; this->GetFullNameInternal(config, artifact, prefix, base, suffix); return prefix; } @@ -539,7 +549,9 @@ std::string cmGeneratorTarget::GetFileSuffix( return suffix ? suffix : std::string(); } - std::string prefix, suffix, base; + std::string prefix; + std::string suffix; + std::string base; this->GetFullNameInternal(config, artifact, prefix, base, suffix); return suffix; } @@ -548,8 +560,8 @@ std::string cmGeneratorTarget::GetFilePostfix(const std::string& config) const { const char* postfix = nullptr; if (!config.empty()) { - std::string configProp = cmSystemTools::UpperCase(config); - configProp += "_POSTFIX"; + std::string configProp = + cmStrCat(cmSystemTools::UpperCase(config), "_POSTFIX"); postfix = this->GetProperty(configProp); // Mac application bundles and frameworks have no postfix. if (!this->IsImported() && postfix && @@ -789,9 +801,8 @@ const char* cmGeneratorTarget::GetFeature(const std::string& feature, const std::string& config) const { if (!config.empty()) { - std::string featureConfig = feature; - featureConfig += "_"; - featureConfig += cmSystemTools::UpperCase(config); + std::string featureConfig = + cmStrCat(feature, '_', cmSystemTools::UpperCase(config)); if (const char* value = this->GetProperty(featureConfig)) { return value; } @@ -1401,8 +1412,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths( cmStringRange sourceEntries = this->Target->GetSourceEntries(); for (std::string const& entry : sourceEntries) { - std::vector<std::string> items; - cmExpandList(entry, items); + std::vector<std::string> items = cmExpandedList(entry); for (std::string const& item : items) { if (cmHasLiteralPrefix(item, "$<TARGET_OBJECTS:") && item.back() == '>') { @@ -1421,9 +1431,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths( cmExpandList(debugProp, debugProperties); } - bool debugSources = !this->DebugSourcesDone && - std::find(debugProperties.begin(), debugProperties.end(), "SOURCES") != - debugProperties.end(); + bool debugSources = + !this->DebugSourcesDone && cmContains(debugProperties, "SOURCES"); if (this->LocalGenerator->GetGlobalGenerator()->GetConfigureDoneCMP0026()) { this->DebugSourcesDone = true; @@ -1591,7 +1600,7 @@ void cmGeneratorTarget::ComputeKindedSources(KindedSources& files, kind = SourceKindHeader; } else if (sf->GetPropertyAsBool("EXTERNAL_OBJECT")) { kind = SourceKindExternalObject; - } else if (!sf->GetLanguage().empty()) { + } else if (!sf->GetOrDetermineLanguage().empty()) { kind = SourceKindObjectSource; } else if (ext == "def") { kind = SourceKindModuleDefinition; @@ -1700,8 +1709,7 @@ std::string cmGeneratorTarget::GetCompilePDBName( // Check for a per-configuration output directory target property. std::string configUpper = cmSystemTools::UpperCase(config); - std::string configProp = "COMPILE_PDB_NAME_"; - configProp += configUpper; + std::string configProp = cmStrCat("COMPILE_PDB_NAME_", configUpper); const char* config_name = this->GetProperty(configProp); if (config_name && *config_name) { return prefix + config_name + ".pdb"; @@ -1773,9 +1781,8 @@ bool cmGeneratorTarget::NeedRelinkBeforeInstall( // Check for rpath support on this platform. std::string ll = this->GetLinkerLanguage(config); if (!ll.empty()) { - std::string flagVar = "CMAKE_SHARED_LIBRARY_RUNTIME_"; - flagVar += ll; - flagVar += "_FLAG"; + std::string flagVar = + cmStrCat("CMAKE_SHARED_LIBRARY_RUNTIME_", ll, "_FLAG"); if (!this->Makefile->IsSet(flagVar)) { // There is no rpath support on this platform so nothing needs // relinking. @@ -1853,9 +1860,8 @@ bool cmGeneratorTarget::IsChrpathUsed(const std::string& config) const // binaries. std::string ll = this->GetLinkerLanguage(config); if (!ll.empty()) { - std::string sepVar = "CMAKE_SHARED_LIBRARY_RUNTIME_"; - sepVar += ll; - sepVar += "_FLAG_SEP"; + std::string sepVar = + cmStrCat("CMAKE_SHARED_LIBRARY_RUNTIME_", ll, "_FLAG_SEP"); const char* sep = this->Makefile->GetDefinition(sepVar); if (sep && *sep) { // TODO: Add ELF check to ABI detection and get rid of @@ -2052,9 +2058,8 @@ bool shouldAddContentLevel(cmGeneratorTarget::BundleDirectoryLevel level) std::string cmGeneratorTarget::GetAppBundleDirectory( const std::string& config, BundleDirectoryLevel level) const { - std::string fpath = - this->GetFullName(config, cmStateEnums::RuntimeBinaryArtifact); - fpath += "."; + std::string fpath = cmStrCat( + this->GetFullName(config, cmStateEnums::RuntimeBinaryArtifact), '.'); const char* ext = this->GetProperty("BUNDLE_EXTENSION"); if (!ext) { ext = "app"; @@ -2079,9 +2084,8 @@ bool cmGeneratorTarget::IsBundleOnApple() const std::string cmGeneratorTarget::GetCFBundleDirectory( const std::string& config, BundleDirectoryLevel level) const { - std::string fpath; - fpath += this->GetOutputName(config, cmStateEnums::RuntimeBinaryArtifact); - fpath += "."; + std::string fpath = cmStrCat( + this->GetOutputName(config, cmStateEnums::RuntimeBinaryArtifact), '.'); const char* ext = this->GetProperty("BUNDLE_EXTENSION"); if (!ext) { if (this->IsXCTestOnApple()) { @@ -2104,9 +2108,8 @@ std::string cmGeneratorTarget::GetCFBundleDirectory( std::string cmGeneratorTarget::GetFrameworkDirectory( const std::string& config, BundleDirectoryLevel level) const { - std::string fpath; - fpath += this->GetOutputName(config, cmStateEnums::RuntimeBinaryArtifact); - fpath += "."; + std::string fpath = cmStrCat( + this->GetOutputName(config, cmStateEnums::RuntimeBinaryArtifact), '.'); const char* ext = this->GetProperty("BUNDLE_EXTENSION"); if (!ext) { ext = "framework"; @@ -2163,8 +2166,7 @@ std::string cmGeneratorTarget::GetInstallNameDirForInstallTree() const if (this->CanGenerateInstallNameDir(INSTALL_NAME_FOR_INSTALL)) { if (install_name_dir && *install_name_dir) { - dir = install_name_dir; - dir += "/"; + dir = cmStrCat(install_name_dir, '/'); } } if (!install_name_dir) { @@ -2205,8 +2207,7 @@ const std::string* cmGeneratorTarget::GetExportMacro() const if (const char* custom_export_name = this->GetProperty("DEFINE_SYMBOL")) { this->ExportMacro = custom_export_name; } else { - std::string in = this->GetName(); - in += "_EXPORTS"; + std::string in = cmStrCat(this->GetName(), "_EXPORTS"); this->ExportMacro = cmSystemTools::MakeCidentifier(in); } return &this->ExportMacro; @@ -2427,8 +2428,7 @@ std::string cmGeneratorTarget::GetMacContentDirectory( const std::string& config, cmStateEnums::ArtifactType artifact) const { // Start with the output directory for the target. - std::string fpath = this->GetDirectory(config, artifact); - fpath += "/"; + std::string fpath = cmStrCat(this->GetDirectory(config, artifact), '/'); BundleDirectoryLevel level = ContentLevel; if (this->IsFrameworkOnApple()) { // additional files with a framework go into the version specific @@ -2464,10 +2464,9 @@ cmGeneratorTarget::CompileInfo const* cmGeneratorTarget::GetCompileInfo( } if (this->GetType() > cmStateEnums::OBJECT_LIBRARY) { - std::string msg = "cmTarget::GetCompileInfo called for "; - msg += this->GetName(); - msg += " which has type "; - msg += cmState::GetTargetTypeName(this->GetType()); + std::string msg = cmStrCat("cmTarget::GetCompileInfo called for ", + this->GetName(), " which has type ", + cmState::GetTargetTypeName(this->GetType())); this->LocalGenerator->IssueMessage(MessageType::INTERNAL_ERROR, msg); return nullptr; } @@ -2647,7 +2646,7 @@ cmTargetTraceDependencies::cmTargetTraceDependencies(cmGeneratorTarget* target) for (cmSourceFile* sf : sources) { const std::set<cmGeneratorTarget const*> tgts = this->GlobalGenerator->GetFilenameTargetDepends(sf); - if (tgts.find(this->GeneratorTarget) != tgts.end()) { + if (cmContains(tgts, this->GeneratorTarget)) { std::ostringstream e; e << "Evaluation output file\n \"" << sf->GetFullPath() << "\"\ndepends on the sources of a target it is used in. This " @@ -2681,8 +2680,7 @@ void cmTargetTraceDependencies::Trace() // Queue dependencies added explicitly by the user. if (const char* additionalDeps = sf->GetProperty("OBJECT_DEPENDS")) { - std::vector<std::string> objDeps; - cmExpandList(additionalDeps, objDeps); + std::vector<std::string> objDeps = cmExpandedList(additionalDeps); for (std::string& objDep : objDeps) { if (cmSystemTools::FileIsFullPath(objDep)) { objDep = cmSystemTools::CollapseFullPath(objDep); @@ -2895,8 +2893,8 @@ void cmGeneratorTarget::GetAppleArchs(const std::string& config, { const char* archs = nullptr; if (!config.empty()) { - std::string defVarName = "OSX_ARCHITECTURES_"; - defVarName += cmSystemTools::UpperCase(config); + std::string defVarName = + cmStrCat("OSX_ARCHITECTURES_", cmSystemTools::UpperCase(config)); archs = this->GetProperty(defVarName); } if (!archs) { @@ -3072,8 +3070,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories( } bool debugIncludes = !this->DebugIncludesDone && - std::find(debugProperties.begin(), debugProperties.end(), - "INCLUDE_DIRECTORIES") != debugProperties.end(); + cmContains(debugProperties, "INCLUDE_DIRECTORIES"); if (this->GlobalGenerator->GetConfigureDoneCMP0026()) { this->DebugIncludesDone = true; @@ -3183,8 +3180,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileOptions( } bool debugOptions = !this->DebugCompileOptionsDone && - std::find(debugProperties.begin(), debugProperties.end(), - "COMPILE_OPTIONS") != debugProperties.end(); + cmContains(debugProperties, "COMPILE_OPTIONS"); if (this->GlobalGenerator->GetConfigureDoneCMP0026()) { this->DebugCompileOptionsDone = true; @@ -3230,8 +3226,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileFeatures( } bool debugFeatures = !this->DebugCompileFeaturesDone && - std::find(debugProperties.begin(), debugProperties.end(), - "COMPILE_FEATURES") != debugProperties.end(); + cmContains(debugProperties, "COMPILE_FEATURES"); if (this->GlobalGenerator->GetConfigureDoneCMP0026()) { this->DebugCompileFeaturesDone = true; @@ -3279,8 +3274,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileDefinitions( } bool debugDefines = !this->DebugCompileDefinitionsDone && - std::find(debugProperties.begin(), debugProperties.end(), - "COMPILE_DEFINITIONS") != debugProperties.end(); + cmContains(debugProperties, "COMPILE_DEFINITIONS"); if (this->GlobalGenerator->GetConfigureDoneCMP0026()) { this->DebugCompileDefinitionsDone = true; @@ -3300,10 +3294,9 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileDefinitions( if (configProp) { switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0043)) { case cmPolicies::WARN: { - std::ostringstream e; - e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0043); - this->LocalGenerator->IssueMessage(MessageType::AUTHOR_WARNING, - e.str()); + this->LocalGenerator->IssueMessage( + MessageType::AUTHOR_WARNING, + cmPolicies::GetPolicyWarning(cmPolicies::CMP0043)); CM_FALLTHROUGH; } case cmPolicies::OLD: { @@ -3326,6 +3319,152 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileDefinitions( return list; } +std::vector<BT<std::string>> cmGeneratorTarget::GetPrecompileHeaders( + const std::string& config, const std::string& language) const +{ + std::unordered_set<std::string> uniqueOptions; + + cmGeneratorExpressionDAGChecker dagChecker(this, "PRECOMPILE_HEADERS", + nullptr, nullptr); + + std::vector<std::string> debugProperties; + const char* debugProp = + this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES"); + if (debugProp) { + cmExpandList(debugProp, debugProperties); + } + + bool debugDefines = !this->DebugPrecompileHeadersDone && + std::find(debugProperties.begin(), debugProperties.end(), + "PRECOMPILE_HEADERS") != debugProperties.end(); + + if (this->GlobalGenerator->GetConfigureDoneCMP0026()) { + this->DebugPrecompileHeadersDone = true; + } + + std::vector<EvaluatedTargetPropertyEntry> entries = + EvaluateTargetPropertyEntries(this, config, language, &dagChecker, + this->PrecompileHeadersEntries); + + AddInterfaceEntries(this, config, "INTERFACE_PRECOMPILE_HEADERS", language, + &dagChecker, entries); + + std::vector<BT<std::string>> list; + processOptions(this, entries, list, uniqueOptions, debugDefines, + "precompile headers", OptionsParse::None); + + return list; +} + +std::string cmGeneratorTarget::GetPchHeader(const std::string& config, + const std::string& language) const +{ + if (language != "C" && language != "CXX") { + return std::string(); + } + if (this->GetPropertyAsBool("DISABLE_PRECOMPILE_HEADERS")) { + return std::string(); + } + const auto inserted = + this->PchHeaders.insert(std::make_pair(language + config, "")); + if (inserted.second) { + const std::vector<BT<std::string>> headers = + this->GetPrecompileHeaders(config, language); + if (headers.empty()) { + return std::string(); + } + std::string& filename = inserted.first->second; + + if (this->GetGlobalGenerator()->IsMultiConfig()) { + filename = + cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(), "/"); + } else { + // For GCC we need to have the header file .h[xx] + // next to the .h[xx].gch file + filename = this->ObjectDirectory; + } + + filename = cmStrCat(filename, "CMakeFiles/", this->GetName(), + ".dir/cmake_pch", ((language == "C") ? ".h" : ".hxx")); + + const std::string filename_tmp = cmStrCat(filename, ".tmp"); + { + auto pchPrologue = this->Makefile->GetDefinition("CMAKE_PCH_PROLOGUE"); + auto pchEpilogue = this->Makefile->GetDefinition("CMAKE_PCH_EPILOGUE"); + + cmGeneratedFileStream file( + filename_tmp, false, + this->GetGlobalGenerator()->GetMakefileEncoding()); + file << "/* generated by CMake */\n\n"; + if (pchPrologue) { + file << pchPrologue << "\n"; + } + if (this->GetGlobalGenerator()->IsXcode()) { + file << "#ifndef CMAKE_SKIP_PRECOMPILE_HEADERS\n"; + } + if (language == "CXX") { + file << "#ifdef __cplusplus\n"; + } + for (auto const& header_bt : headers) { + if (header_bt.Value.empty()) { + continue; + } + if (header_bt.Value[0] == '<' || header_bt.Value[0] == '"') { + file << "#include " << header_bt.Value << "\n"; + } else { + file << "#include \"" << header_bt.Value << "\"\n"; + } + } + if (language == "CXX") { + file << "#endif // __cplusplus\n"; + } + if (this->GetGlobalGenerator()->IsXcode()) { + file << "#endif // CMAKE_SKIP_PRECOMPILE_HEADERS\n"; + } + if (pchEpilogue) { + file << pchEpilogue << "\n"; + } + } + cmSystemTools::CopyFileIfDifferent(filename_tmp, filename); + cmSystemTools::RemoveFile(filename_tmp); + } + return inserted.first->second; +} + +std::string cmGeneratorTarget::GetPchSource(const std::string& config, + const std::string& language) const +{ + if (language != "C" && language != "CXX") { + return std::string(); + } + const auto inserted = + this->PchSources.insert(std::make_pair(language + config, "")); + if (inserted.second) { + const std::string pchHeader = this->GetPchHeader(config, language); + if (pchHeader.empty()) { + return std::string(); + } + std::string& filename = inserted.first->second; + filename = cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(), + "/CMakeFiles/", this->GetName(), ".dir/cmake_pch"); + + // For GCC the source extension will be tranformed into .h[xx].gch + if (!this->Makefile->IsOn("CMAKE_LINK_PCH")) { + filename += ((language == "C") ? ".h.c" : ".hxx.cxx"); + } else { + filename += ((language == "C") ? ".c" : ".cxx"); + } + const std::string filename_tmp = cmStrCat(filename, ".tmp"); + { + cmGeneratedFileStream file(filename_tmp); + file << "/* generated by CMake */\n"; + } + cmSystemTools::CopyFileIfDifferent(filename_tmp, filename); + cmSystemTools::RemoveFile(filename_tmp); + } + return inserted.first->second; +} + void cmGeneratorTarget::GetLinkOptions(std::vector<std::string>& result, const std::string& config, const std::string& language) const @@ -3353,9 +3492,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkOptions( cmExpandList(debugProp, debugProperties); } - bool debugOptions = !this->DebugLinkOptionsDone && - std::find(debugProperties.begin(), debugProperties.end(), - "LINK_OPTIONS") != debugProperties.end(); + bool debugOptions = + !this->DebugLinkOptionsDone && cmContains(debugProperties, "LINK_OPTIONS"); if (this->GlobalGenerator->GetConfigureDoneCMP0026()) { this->DebugLinkOptionsDone = true; @@ -3375,8 +3513,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkOptions( // actual linker wrapper const std::string wrapper(this->Makefile->GetSafeDefinition( "CMAKE_" + language + "_LINKER_WRAPPER_FLAG")); - std::vector<std::string> wrapperFlag; - cmExpandList(wrapper, wrapperFlag); + std::vector<std::string> wrapperFlag = cmExpandedList(wrapper); const std::string wrapperSep(this->Makefile->GetSafeDefinition( "CMAKE_" + language + "_LINKER_WRAPPER_FLAG_SEP")); bool concatFlagAndArgs = true; @@ -3497,8 +3634,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetStaticLibraryLinkOptions( std::vector<EvaluatedTargetPropertyEntry> entries; if (const char* linkOptions = this->GetProperty("STATIC_LIBRARY_OPTIONS")) { - std::vector<std::string> options; - cmExpandList(linkOptions, options); + std::vector<std::string> options = cmExpandedList(linkOptions); for (const auto& option : options) { std::unique_ptr<TargetPropertyEntry> entry( CreateTargetPropertyEntry(option)); @@ -3612,8 +3748,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkDirectories( } bool debugDirectories = !this->DebugLinkDirectoriesDone && - std::find(debugProperties.begin(), debugProperties.end(), - "LINK_DIRECTORIES") != debugProperties.end(); + cmContains(debugProperties, "LINK_DIRECTORIES"); if (this->GlobalGenerator->GetConfigureDoneCMP0026()) { this->DebugLinkDirectoriesDone = true; @@ -3653,8 +3788,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkDepends( std::vector<EvaluatedTargetPropertyEntry> entries; if (const char* linkDepends = this->GetProperty("LINK_DEPENDS")) { - std::vector<std::string> depends; - cmExpandList(linkDepends, depends); + std::vector<std::string> depends = cmExpandedList(linkDepends); for (const auto& depend : depends) { std::unique_ptr<TargetPropertyEntry> entry( CreateTargetPropertyEntry(depend)); @@ -3697,33 +3831,25 @@ void cmGeneratorTarget::ComputeTargetManifest(const std::string& config) const // Add each name. std::string f; if (!targetNames.Output.empty()) { - f = dir; - f += "/"; - f += targetNames.Output; + f = cmStrCat(dir, '/', targetNames.Output); gg->AddToManifest(f); } if (!targetNames.SharedObject.empty()) { - f = dir; - f += "/"; - f += targetNames.SharedObject; + f = cmStrCat(dir, '/', targetNames.SharedObject); gg->AddToManifest(f); } if (!targetNames.Real.empty()) { - f = dir; - f += "/"; - f += targetNames.Real; + f = cmStrCat(dir, '/', targetNames.Real); gg->AddToManifest(f); } if (!targetNames.PDB.empty()) { - f = dir; - f += "/"; - f += targetNames.PDB; + f = cmStrCat(dir, '/', targetNames.PDB); gg->AddToManifest(f); } if (!targetNames.ImportLibrary.empty()) { - f = this->GetDirectory(config, cmStateEnums::ImportLibraryArtifact); - f += "/"; - f += targetNames.ImportLibrary; + f = + cmStrCat(this->GetDirectory(config, cmStateEnums::ImportLibraryArtifact), + '/', targetNames.ImportLibrary); gg->AddToManifest(f); } } @@ -3763,11 +3889,10 @@ std::string cmGeneratorTarget::NormalGetFullPath( const std::string& config, cmStateEnums::ArtifactType artifact, bool realname) const { - std::string fpath = this->GetDirectory(config, artifact); - fpath += "/"; + std::string fpath = cmStrCat(this->GetDirectory(config, artifact), '/'); if (this->IsAppBundleOnApple()) { - fpath = this->BuildBundleDirectory(fpath, config, FullLevel); - fpath += "/"; + fpath = + cmStrCat(this->BuildBundleDirectory(fpath, config, FullLevel), '/'); } // Add the full name of the target. @@ -3794,8 +3919,8 @@ std::string cmGeneratorTarget::NormalGetRealName( // TODO: Split cmTarget into a class hierarchy to get compile-time // enforcement of the limited imported target API. if (this->IsImported()) { - std::string msg = "NormalGetRealName called on imported target: "; - msg += this->GetName(); + std::string msg = cmStrCat("NormalGetRealName called on imported target: ", + this->GetName()); this->LocalGenerator->IssueMessage(MessageType::INTERNAL_ERROR, msg); } @@ -3816,8 +3941,8 @@ cmGeneratorTarget::Names cmGeneratorTarget::GetLibraryNames( // TODO: Split cmTarget into a class hierarchy to get compile-time // enforcement of the limited imported target API. if (this->IsImported()) { - std::string msg = "GetLibraryNames called on imported target: "; - msg += this->GetName(); + std::string msg = + cmStrCat("GetLibraryNames called on imported target: ", this->GetName()); this->LocalGenerator->IssueMessage(MessageType::INTERNAL_ERROR, msg); } @@ -3893,8 +4018,8 @@ cmGeneratorTarget::Names cmGeneratorTarget::GetExecutableNames( // TODO: Split cmTarget into a class hierarchy to get compile-time // enforcement of the limited imported target API. if (this->IsImported()) { - std::string msg = "GetExecutableNames called on imported target: "; - msg += this->GetName(); + std::string msg = cmStrCat( + "GetExecutableNames called on imported target: ", this->GetName()); this->LocalGenerator->IssueMessage(MessageType::INTERNAL_ERROR, msg); } @@ -4015,15 +4140,14 @@ void cmGeneratorTarget::GetFullNameInternal( // frameworks have directory prefix but no suffix std::string fw_prefix; if (this->IsFrameworkOnApple()) { - fw_prefix = this->GetFrameworkDirectory(config, ContentLevel); - fw_prefix += "/"; + fw_prefix = + cmStrCat(this->GetFrameworkDirectory(config, ContentLevel), '/'); targetPrefix = fw_prefix.c_str(); targetSuffix = nullptr; } if (this->IsCFBundleOnApple()) { - fw_prefix = this->GetCFBundleDirectory(config, FullLevel); - fw_prefix += "/"; + fw_prefix = cmStrCat(this->GetCFBundleDirectory(config, FullLevel), '/'); targetPrefix = fw_prefix.c_str(); targetSuffix = nullptr; } @@ -4207,8 +4331,7 @@ void cmGeneratorTarget::ConstructSourceFileFlags() const // Process public headers to mark the source files. if (const char* files = this->GetProperty("PUBLIC_HEADER")) { - std::vector<std::string> relFiles; - cmExpandList(files, relFiles); + std::vector<std::string> relFiles = cmExpandedList(files); for (std::string const& relFile : relFiles) { if (cmSourceFile* sf = this->Makefile->GetSource(relFile)) { SourceFileFlags& flags = this->SourceFlagsMap[sf]; @@ -4221,8 +4344,7 @@ void cmGeneratorTarget::ConstructSourceFileFlags() const // Process private headers after public headers so that they take // precedence if a file is listed in both. if (const char* files = this->GetProperty("PRIVATE_HEADER")) { - std::vector<std::string> relFiles; - cmExpandList(files, relFiles); + std::vector<std::string> relFiles = cmExpandedList(files); for (std::string const& relFile : relFiles) { if (cmSourceFile* sf = this->Makefile->GetSource(relFile)) { SourceFileFlags& flags = this->SourceFlagsMap[sf]; @@ -4234,8 +4356,7 @@ void cmGeneratorTarget::ConstructSourceFileFlags() const // Mark sources listed as resources. if (const char* files = this->GetProperty("RESOURCE")) { - std::vector<std::string> relFiles; - cmExpandList(files, relFiles); + std::vector<std::string> relFiles = cmExpandedList(files); for (std::string const& relFile : relFiles) { if (cmSourceFile* sf = this->Makefile->GetSource(relFile)) { SourceFileFlags& flags = this->SourceFlagsMap[sf]; @@ -4377,10 +4498,9 @@ void checkPropertyConsistency(cmGeneratorTarget const* depender, return; } - std::vector<std::string> props; - cmExpandList(prop, props); - std::string pdir = cmSystemTools::GetCMakeRoot(); - pdir += "/Help/prop_tgt/"; + std::vector<std::string> props = cmExpandedList(prop); + std::string pdir = + cmStrCat(cmSystemTools::GetCMakeRoot(), "/Help/prop_tgt/"); for (std::string const& p : props) { std::string pname = cmSystemTools::HelpFileName(p); @@ -4526,8 +4646,8 @@ void cmGeneratorTarget::CheckPropertyCompatibility( } std::sort(props.begin(), props.end()); - std::string propsString = cmJoin(cmMakeRange(props).retreat(1), ", "); - propsString += " and the " + props.back(); + std::string propsString = cmStrCat( + cmJoin(cmMakeRange(props).retreat(1), ", "), " and the ", props.back()); std::ostringstream e; e << "Property \"" << prop << "\" appears in both the " << propsString @@ -4784,9 +4904,7 @@ PropertyType checkInterfacePropertyCompatibility(cmGeneratorTarget const* tgt, PropertyType propContent = getTypedProperty<PropertyType>(tgt, p); std::vector<std::string> headPropKeys = tgt->GetPropertyKeys(); - const bool explicitlySet = - std::find(headPropKeys.begin(), headPropKeys.end(), p) != - headPropKeys.end(); + const bool explicitlySet = cmContains(headPropKeys, p); const bool impliedByUse = tgt->IsNullImpliedByLinkLibraries(p); assert((impliedByUse ^ explicitlySet) || (!impliedByUse && !explicitlySet)); @@ -4799,8 +4917,7 @@ PropertyType checkInterfacePropertyCompatibility(cmGeneratorTarget const* tgt, } bool propInitialized = explicitlySet; - std::string report = " * Target \""; - report += tgt->GetName(); + std::string report = cmStrCat(" * Target \"", tgt->GetName()); if (explicitlySet) { report += "\" has property content \""; report += valueAsString<PropertyType>(propContent); @@ -4826,8 +4943,7 @@ PropertyType checkInterfacePropertyCompatibility(cmGeneratorTarget const* tgt, std::vector<std::string> propKeys = theTarget->GetPropertyKeys(); - const bool ifaceIsSet = std::find(propKeys.begin(), propKeys.end(), - interfaceProperty) != propKeys.end(); + const bool ifaceIsSet = cmContains(propKeys, interfaceProperty); PropertyType ifacePropContent = getTypedProperty<PropertyType>( theTarget, interfaceProperty, genexInterpreter.get()); @@ -5057,9 +5173,8 @@ std::string cmGeneratorTarget::CreateFortranModuleDirectory( mod_dir = target_mod_dir; } else { // Interpret relative to the current output directory. - mod_dir = this->LocalGenerator->GetCurrentBinaryDirectory(); - mod_dir += "/"; - mod_dir += target_mod_dir; + mod_dir = cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(), + '/', target_mod_dir); } // Make sure the module output directory exists. @@ -5112,9 +5227,8 @@ void cmGeneratorTarget::ReportPropertyOrigin( cmExpandList(debugProp, debugProperties); } - bool debugOrigin = !this->DebugCompatiblePropertiesDone[p] && - std::find(debugProperties.begin(), debugProperties.end(), p) != - debugProperties.end(); + bool debugOrigin = + !this->DebugCompatiblePropertiesDone[p] && cmContains(debugProperties, p); if (this->GlobalGenerator->GetConfigureDoneCMP0026()) { this->DebugCompatiblePropertiesDone[p] = true; @@ -5123,12 +5237,9 @@ void cmGeneratorTarget::ReportPropertyOrigin( return; } - std::string areport = compatibilityType; - areport += std::string(" of property \"") + p + "\" for target \""; - areport += std::string(this->GetName()); - areport += "\" (result: \""; - areport += result; - areport += "\"):\n" + report; + std::string areport = + cmStrCat(compatibilityType, " of property \"", p, "\" for target \"", + this->GetName(), "\" (result: \"", result, "\"):\n", report); this->LocalGenerator->GetCMakeInstance()->IssueMessage(MessageType::LOG, areport); @@ -5268,8 +5379,7 @@ void cmGeneratorTarget::ComputeLinkInterface( // How many repetitions are needed if this library has cyclic // dependencies? - std::string propName = "LINK_INTERFACE_MULTIPLICITY"; - propName += suffix; + std::string propName = cmStrCat("LINK_INTERFACE_MULTIPLICITY", suffix); if (const char* config_reps = this->GetProperty(propName)) { sscanf(config_reps, "%u", &iface.Multiplicity); } else if (const char* reps = @@ -5355,10 +5465,9 @@ cmGeneratorTarget::OutputInfo const* cmGeneratorTarget::GetOutputInfo( // Only libraries and executables have well-defined output files. if (!this->HaveWellDefinedOutputFiles()) { - std::string msg = "cmGeneratorTarget::GetOutputInfo called for "; - msg += this->GetName(); - msg += " which has type "; - msg += cmState::GetTargetTypeName(this->GetType()); + std::string msg = cmStrCat("cmGeneratorTarget::GetOutputInfo called for ", + this->GetName(), " which has type ", + cmState::GetTargetTypeName(this->GetType())); this->LocalGenerator->IssueMessage(MessageType::INTERNAL_ERROR, msg); return nullptr; } @@ -5607,8 +5716,7 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries( // shared lib or executable. // Lookup the per-configuration property. - linkIfaceProp = "LINK_INTERFACE_LIBRARIES"; - linkIfaceProp += suffix; + linkIfaceProp = cmStrCat("LINK_INTERFACE_LIBRARIES", suffix); explicitLibraries = this->GetProperty(linkIfaceProp); // If not set, try the generic property. @@ -5744,8 +5852,7 @@ const cmLinkInterface* cmGeneratorTarget::GetImportLinkInterface( this->ExpandLinkItems(info->LibrariesProp, info->Libraries, config, headTarget, usage_requirements_only, iface.Libraries, iface.HadHeadSensitiveCondition); - std::vector<std::string> deps; - cmExpandList(info->SharedDeps, deps); + std::vector<std::string> deps = cmExpandedList(info->SharedDeps); this->LookupLinkItems(deps, cmListFileBacktrace(), iface.SharedDeps); } @@ -5814,8 +5921,7 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config, if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY) { if (!propertyLibs) { - linkProp = "IMPORTED_LINK_INTERFACE_LIBRARIES"; - linkProp += suffix; + linkProp = cmStrCat("IMPORTED_LINK_INTERFACE_LIBRARIES", suffix); propertyLibs = this->GetProperty(linkProp); } @@ -5843,8 +5949,7 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config, if (loc) { info.Location = loc; } else { - std::string impProp = "IMPORTED_LOCATION"; - impProp += suffix; + std::string impProp = cmStrCat("IMPORTED_LOCATION", suffix); if (const char* config_location = this->GetProperty(impProp)) { info.Location = config_location; } else if (const char* location = this->GetProperty("IMPORTED_LOCATION")) { @@ -5854,8 +5959,7 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config, // Get the soname. if (this->GetType() == cmStateEnums::SHARED_LIBRARY) { - std::string soProp = "IMPORTED_SONAME"; - soProp += suffix; + std::string soProp = cmStrCat("IMPORTED_SONAME", suffix); if (const char* config_soname = this->GetProperty(soProp)) { info.SOName = config_soname; } else if (const char* soname = this->GetProperty("IMPORTED_SONAME")) { @@ -5865,8 +5969,7 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config, // Get the "no-soname" mark. if (this->GetType() == cmStateEnums::SHARED_LIBRARY) { - std::string soProp = "IMPORTED_NO_SONAME"; - soProp += suffix; + std::string soProp = cmStrCat("IMPORTED_NO_SONAME", suffix); if (const char* config_no_soname = this->GetProperty(soProp)) { info.NoSOName = cmIsOn(config_no_soname); } else if (const char* no_soname = @@ -5880,8 +5983,7 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config, info.ImportLibrary = imp; } else if (this->GetType() == cmStateEnums::SHARED_LIBRARY || this->IsExecutableWithExports()) { - std::string impProp = "IMPORTED_IMPLIB"; - impProp += suffix; + std::string impProp = cmStrCat("IMPORTED_IMPLIB", suffix); if (const char* config_implib = this->GetProperty(impProp)) { info.ImportLibrary = config_implib; } else if (const char* implib = this->GetProperty("IMPORTED_IMPLIB")) { @@ -5891,8 +5993,8 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config, // Get the link dependencies. { - std::string linkProp = "IMPORTED_LINK_DEPENDENT_LIBRARIES"; - linkProp += suffix; + std::string linkProp = + cmStrCat("IMPORTED_LINK_DEPENDENT_LIBRARIES", suffix); if (const char* config_libs = this->GetProperty(linkProp)) { info.SharedDeps = config_libs; } else if (const char* libs = @@ -5903,8 +6005,8 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config, // Get the link languages. if (this->LinkLanguagePropagatesToDependents()) { - std::string linkProp = "IMPORTED_LINK_INTERFACE_LANGUAGES"; - linkProp += suffix; + std::string linkProp = + cmStrCat("IMPORTED_LINK_INTERFACE_LANGUAGES", suffix); if (const char* config_libs = this->GetProperty(linkProp)) { info.Languages = config_libs; } else if (const char* libs = @@ -5925,8 +6027,8 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config, // Get the cyclic repetition count. if (this->GetType() == cmStateEnums::STATIC_LIBRARY) { - std::string linkProp = "IMPORTED_LINK_INTERFACE_MULTIPLICITY"; - linkProp += suffix; + std::string linkProp = + cmStrCat("IMPORTED_LINK_INTERFACE_MULTIPLICITY", suffix); if (const char* config_reps = this->GetProperty(linkProp)) { sscanf(config_reps, "%u", &info.Multiplicity); } else if (const char* reps = @@ -6033,8 +6135,7 @@ void cmGeneratorTarget::GetObjectLibrariesCMP0026( // behavior of CMP0024 and CMP0026 only. cmStringRange rng = this->Target->GetSourceEntries(); for (std::string const& entry : rng) { - std::vector<std::string> files; - cmExpandList(entry, files); + std::vector<std::string> files = cmExpandedList(entry); for (std::string const& li : files) { if (cmHasLiteralPrefix(li, "$<TARGET_OBJECTS:") && li.back() == '>') { std::string objLibName = li.substr(17, li.size() - 18); @@ -6107,7 +6208,7 @@ void cmGeneratorTarget::GetLanguages(std::set<std::string>& languages, std::vector<cmSourceFile*> sourceFiles; this->GetSourceFiles(sourceFiles, config); for (cmSourceFile* src : sourceFiles) { - const std::string& lang = src->GetLanguage(); + const std::string& lang = src->GetOrDetermineLanguage(); if (!lang.empty()) { languages.insert(lang); } @@ -6226,8 +6327,7 @@ cmGeneratorTarget::GetLinkImplementationLibrariesInternal( bool cmGeneratorTarget::IsNullImpliedByLinkLibraries( const std::string& p) const { - return this->LinkImplicitNullProperties.find(p) != - this->LinkImplicitNullProperties.end(); + return cmContains(this->LinkImplicitNullProperties, p); } void cmGeneratorTarget::ComputeLinkImplementationLibraries( @@ -6405,8 +6505,8 @@ bool cmGeneratorTarget::GetImplibGNUtoMS(std::string const& config, { if (this->HasImplibGNUtoMS(config) && gnuName.size() > 6 && gnuName.substr(gnuName.size() - 6) == ".dll.a") { - out = gnuName.substr(0, gnuName.size() - 6); - out += newExt ? newExt : ".lib"; + out = cmStrCat(cm::string_view(gnuName).substr(0, gnuName.size() - 6), + newExt ? newExt : ".lib"); return true; } return false; @@ -6441,9 +6541,8 @@ bool cmGeneratorTarget::NeedImportLibraryName(std::string const& config) const std::string cmGeneratorTarget::GetSupportDirectory() const { - std::string dir = this->LocalGenerator->GetCurrentBinaryDirectory(); - dir += "/CMakeFiles/"; - dir += this->GetName(); + std::string dir = cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(), + "/CMakeFiles/", this->GetName()); #if defined(__VMS) dir += "_dir"; #else diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index 3874738..4701071 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -455,6 +455,14 @@ public: std::vector<BT<std::string>> GetLinkDepends( std::string const& config, std::string const& language) const; + std::vector<BT<std::string>> GetPrecompileHeaders( + const std::string& config, const std::string& language) const; + + std::string GetPchHeader(const std::string& config, + const std::string& language) const; + std::string GetPchSource(const std::string& config, + const std::string& language) const; + bool IsSystemIncludeDirectory(const std::string& dir, const std::string& config, const std::string& language) const; @@ -867,8 +875,11 @@ private: std::vector<TargetPropertyEntry*> CompileDefinitionsEntries; std::vector<TargetPropertyEntry*> LinkOptionsEntries; std::vector<TargetPropertyEntry*> LinkDirectoriesEntries; + std::vector<TargetPropertyEntry*> PrecompileHeadersEntries; std::vector<TargetPropertyEntry*> SourceEntries; mutable std::set<std::string> LinkImplicitNullProperties; + mutable std::map<std::string, std::string> PchHeaders; + mutable std::map<std::string, std::string> PchSources; void ExpandLinkItems(std::string const& prop, std::string const& value, std::string const& config, @@ -922,6 +933,7 @@ private: mutable bool DebugCompileDefinitionsDone; mutable bool DebugLinkOptionsDone; mutable bool DebugLinkDirectoriesDone; + mutable bool DebugPrecompileHeadersDone; mutable bool DebugSourcesDone; mutable bool LinkImplementationLanguageIsContextDependent; mutable bool UtilityItemsDone; diff --git a/Source/cmGetCMakePropertyCommand.cxx b/Source/cmGetCMakePropertyCommand.cxx index 38fee28..ff4e312 100644 --- a/Source/cmGetCMakePropertyCommand.cxx +++ b/Source/cmGetCMakePropertyCommand.cxx @@ -4,19 +4,18 @@ #include <set> +#include "cmExecutionStatus.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" #include "cmState.h" #include "cmStringAlgorithms.h" -class cmExecutionStatus; - // cmGetCMakePropertyCommand -bool cmGetCMakePropertyCommand::InitialPass( - std::vector<std::string> const& args, cmExecutionStatus&) +bool cmGetCMakePropertyCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() < 2) { - this->SetError("called with incorrect number of arguments"); + status.SetError("called with incorrect number of arguments"); return false; } @@ -24,29 +23,29 @@ bool cmGetCMakePropertyCommand::InitialPass( std::string output = "NOTFOUND"; if (args[1] == "VARIABLES") { - if (const char* varsProp = this->Makefile->GetProperty("VARIABLES")) { + if (const char* varsProp = status.GetMakefile().GetProperty("VARIABLES")) { output = varsProp; } } else if (args[1] == "MACROS") { output.clear(); - if (const char* macrosProp = this->Makefile->GetProperty("MACROS")) { + if (const char* macrosProp = status.GetMakefile().GetProperty("MACROS")) { output = macrosProp; } } else if (args[1] == "COMPONENTS") { const std::set<std::string>* components = - this->Makefile->GetGlobalGenerator()->GetInstallComponents(); + status.GetMakefile().GetGlobalGenerator()->GetInstallComponents(); output = cmJoin(*components, ";"); } else { const char* prop = nullptr; if (!args[1].empty()) { - prop = this->Makefile->GetState()->GetGlobalProperty(args[1]); + prop = status.GetMakefile().GetState()->GetGlobalProperty(args[1]); } if (prop) { output = prop; } } - this->Makefile->AddDefinition(variable, output); + status.GetMakefile().AddDefinition(variable, output); return true; } diff --git a/Source/cmGetCMakePropertyCommand.h b/Source/cmGetCMakePropertyCommand.h index 7790a6b..7a6728c 100644 --- a/Source/cmGetCMakePropertyCommand.h +++ b/Source/cmGetCMakePropertyCommand.h @@ -8,26 +8,9 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -class cmGetCMakePropertyCommand : public cmCommand -{ -public: - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmGetCMakePropertyCommand>(); - } - - /** - * This is called when the command is first encountered in - * the input file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; +bool cmGetCMakePropertyCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmGetDirectoryPropertyCommand.cxx b/Source/cmGetDirectoryPropertyCommand.cxx index 98ccb0a..d078a7a 100644 --- a/Source/cmGetDirectoryPropertyCommand.cxx +++ b/Source/cmGetDirectoryPropertyCommand.cxx @@ -2,20 +2,25 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmGetDirectoryPropertyCommand.h" +#include "cmExecutionStatus.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmPolicies.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" -class cmExecutionStatus; +namespace { +void StoreResult(cmMakefile& makefile, std::string const& variable, + const char* prop); +} // cmGetDirectoryPropertyCommand -bool cmGetDirectoryPropertyCommand::InitialPass( - std::vector<std::string> const& args, cmExecutionStatus&) +bool cmGetDirectoryPropertyCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() < 2) { - this->SetError("called with incorrect number of arguments"); + status.SetError("called with incorrect number of arguments"); return false; } @@ -24,29 +29,27 @@ bool cmGetDirectoryPropertyCommand::InitialPass( ++i; // get the directory argument if there is one - cmMakefile* dir = this->Makefile; + cmMakefile* dir = &status.GetMakefile(); if (*i == "DIRECTORY") { ++i; if (i == args.end()) { - this->SetError( + status.SetError( "DIRECTORY argument provided without subsequent arguments"); return false; } std::string sd = *i; // make sure the start dir is a full path if (!cmSystemTools::FileIsFullPath(sd)) { - sd = this->Makefile->GetCurrentSourceDirectory(); - sd += "/"; - sd += *i; + sd = cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', *i); } // The local generators are associated with collapsed paths. sd = cmSystemTools::CollapseFullPath(sd); // lookup the makefile from the directory name - dir = this->Makefile->GetGlobalGenerator()->FindMakefile(sd); + dir = status.GetMakefile().GetGlobalGenerator()->FindMakefile(sd); if (!dir) { - this->SetError( + status.SetError( "DIRECTORY argument provided but requested directory not found. " "This could be because the directory argument was invalid or, " "it is valid but has not been processed yet."); @@ -61,26 +64,27 @@ bool cmGetDirectoryPropertyCommand::InitialPass( if (*i == "DEFINITION") { ++i; if (i == args.end()) { - this->SetError("A request for a variable definition was made without " - "providing the name of the variable to get."); + status.SetError("A request for a variable definition was made without " + "providing the name of the variable to get."); return false; } std::string const& output = dir->GetSafeDefinition(*i); - this->Makefile->AddDefinition(variable, output); + status.GetMakefile().AddDefinition(variable, output); return true; } const char* prop = nullptr; if (!i->empty()) { if (*i == "DEFINITIONS") { - switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0059)) { + switch (status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0059)) { case cmPolicies::WARN: - this->Makefile->IssueMessage( + status.GetMakefile().IssueMessage( MessageType::AUTHOR_WARNING, cmPolicies::GetPolicyWarning(cmPolicies::CMP0059)); CM_FALLTHROUGH; case cmPolicies::OLD: - this->StoreResult(variable, this->Makefile->GetDefineFlagsCMP0059()); + StoreResult(status.GetMakefile(), variable, + status.GetMakefile().GetDefineFlagsCMP0059()); return true; case cmPolicies::NEW: case cmPolicies::REQUIRED_ALWAYS: @@ -90,12 +94,14 @@ bool cmGetDirectoryPropertyCommand::InitialPass( } prop = dir->GetProperty(*i); } - this->StoreResult(variable, prop); + StoreResult(status.GetMakefile(), variable, prop); return true; } -void cmGetDirectoryPropertyCommand::StoreResult(std::string const& variable, - const char* prop) +namespace { +void StoreResult(cmMakefile& makefile, std::string const& variable, + const char* prop) { - this->Makefile->AddDefinition(variable, prop ? prop : ""); + makefile.AddDefinition(variable, prop ? prop : ""); +} } diff --git a/Source/cmGetDirectoryPropertyCommand.h b/Source/cmGetDirectoryPropertyCommand.h index 63a198a..f356ea5 100644 --- a/Source/cmGetDirectoryPropertyCommand.h +++ b/Source/cmGetDirectoryPropertyCommand.h @@ -8,29 +8,9 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -class cmGetDirectoryPropertyCommand : public cmCommand -{ -public: - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmGetDirectoryPropertyCommand>(); - } - - /** - * This is called when the command is first encountered in - * the input file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; - -private: - void StoreResult(const std::string& variable, const char* prop); -}; +bool cmGetDirectoryPropertyCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmGetFilenameComponentCommand.cxx b/Source/cmGetFilenameComponentCommand.cxx index d56af3d..7d91a75 100644 --- a/Source/cmGetFilenameComponentCommand.cxx +++ b/Source/cmGetFilenameComponentCommand.cxx @@ -2,26 +2,25 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmGetFilenameComponentCommand.h" +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" -class cmExecutionStatus; - // cmGetFilenameComponentCommand -bool cmGetFilenameComponentCommand::InitialPass( - std::vector<std::string> const& args, cmExecutionStatus&) +bool cmGetFilenameComponentCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() < 3) { - this->SetError("called with incorrect number of arguments"); + status.SetError("called with incorrect number of arguments"); return false; } // Check and see if the value has been stored in the cache // already, if so use that value if (args.size() >= 4 && args.back() == "CACHE") { - const char* cacheValue = this->Makefile->GetDefinition(args.front()); + const char* cacheValue = status.GetMakefile().GetDefinition(args.front()); if (cacheValue && !cmIsNOTFOUND(cacheValue)) { return true; } @@ -33,7 +32,7 @@ bool cmGetFilenameComponentCommand::InitialPass( // Check the registry as the target application would view it. cmSystemTools::KeyWOW64 view = cmSystemTools::KeyWOW64_32; cmSystemTools::KeyWOW64 other_view = cmSystemTools::KeyWOW64_64; - if (this->Makefile->PlatformIs64Bit()) { + if (status.GetMakefile().PlatformIs64Bit()) { view = cmSystemTools::KeyWOW64_64; other_view = cmSystemTools::KeyWOW64_32; } @@ -97,7 +96,7 @@ bool cmGetFilenameComponentCommand::InitialPass( // If the path given is relative, evaluate it relative to the // current source directory unless the user passes a different // base directory. - std::string baseDir = this->Makefile->GetCurrentSourceDirectory(); + std::string baseDir = status.GetMakefile().GetCurrentSourceDirectory(); for (unsigned int i = 3; i < args.size(); ++i) { if (args[i] == "BASE_DIR") { ++i; @@ -114,24 +113,24 @@ bool cmGetFilenameComponentCommand::InitialPass( } } else { std::string err = "unknown component " + args[2]; - this->SetError(err); + status.SetError(err); return false; } if (args.size() >= 4 && args.back() == "CACHE") { if (!programArgs.empty() && !storeArgs.empty()) { - this->Makefile->AddCacheDefinition( + status.GetMakefile().AddCacheDefinition( storeArgs, programArgs.c_str(), "", args[2] == "PATH" ? cmStateEnums::FILEPATH : cmStateEnums::STRING); } - this->Makefile->AddCacheDefinition( + status.GetMakefile().AddCacheDefinition( args.front(), result.c_str(), "", args[2] == "PATH" ? cmStateEnums::FILEPATH : cmStateEnums::STRING); } else { if (!programArgs.empty() && !storeArgs.empty()) { - this->Makefile->AddDefinition(storeArgs, programArgs); + status.GetMakefile().AddDefinition(storeArgs, programArgs); } - this->Makefile->AddDefinition(args.front(), result); + status.GetMakefile().AddDefinition(args.front(), result); } return true; diff --git a/Source/cmGetFilenameComponentCommand.h b/Source/cmGetFilenameComponentCommand.h index 1780b96..db5293b 100644 --- a/Source/cmGetFilenameComponentCommand.h +++ b/Source/cmGetFilenameComponentCommand.h @@ -8,35 +8,15 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmGetFilenameComponentCommand +/** * \brief Get a specific component of a filename. * * cmGetFilenameComponentCommand is a utility command used to get the path, * name, extension or name without extension of a full filename. */ -class cmGetFilenameComponentCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmGetFilenameComponentCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; +bool cmGetFilenameComponentCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmGetPropertyCommand.cxx b/Source/cmGetPropertyCommand.cxx index de462ed..e8e87e7 100644 --- a/Source/cmGetPropertyCommand.cxx +++ b/Source/cmGetPropertyCommand.cxx @@ -4,6 +4,7 @@ #include <sstream> +#include "cmExecutionStatus.h" #include "cmGlobalGenerator.h" #include "cmInstalledFile.h" #include "cmListFileCache.h" @@ -14,30 +15,70 @@ #include "cmPropertyDefinition.h" #include "cmSourceFile.h" #include "cmState.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" #include "cmTargetPropertyComputer.h" #include "cmTest.h" #include "cmake.h" -class cmExecutionStatus; class cmMessenger; -cmGetPropertyCommand::cmGetPropertyCommand() +namespace { +enum OutType { - this->InfoType = OutValue; + OutValue, + OutDefined, + OutBriefDoc, + OutFullDoc, + OutSet +}; + +// Implementation of result storage. +bool StoreResult(OutType infoType, cmMakefile& makefile, + const std::string& variable, const char* value); + +// Implementation of each property type. +bool HandleGlobalMode(cmExecutionStatus& status, const std::string& name, + OutType infoType, const std::string& variable, + const std::string& propertyName); +bool HandleDirectoryMode(cmExecutionStatus& status, const std::string& name, + OutType infoType, const std::string& variable, + const std::string& propertyName); +bool HandleTargetMode(cmExecutionStatus& status, const std::string& name, + OutType infoType, const std::string& variable, + const std::string& propertyName); +bool HandleSourceMode(cmExecutionStatus& status, const std::string& name, + OutType infoType, const std::string& variable, + const std::string& propertyName); +bool HandleTestMode(cmExecutionStatus& status, const std::string& name, + OutType infoType, const std::string& variable, + const std::string& propertyName); +bool HandleVariableMode(cmExecutionStatus& status, const std::string& name, + OutType infoType, const std::string& variable, + const std::string& propertyName); +bool HandleCacheMode(cmExecutionStatus& status, const std::string& name, + OutType infoType, const std::string& variable, + const std::string& propertyName); +bool HandleInstallMode(cmExecutionStatus& status, const std::string& name, + OutType infoType, const std::string& variable, + const std::string& propertyName); } -bool cmGetPropertyCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmGetPropertyCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { + OutType infoType = OutValue; if (args.size() < 3) { - this->SetError("called with incorrect number of arguments"); + status.SetError("called with incorrect number of arguments"); return false; } // The cmake variable in which to store the result. - this->Variable = args[0]; + const std::string variable = args[0]; + + std::string name; + std::string propertyName; // Get the scope from which to get the property. cmProperty::ScopeType scope; @@ -62,7 +103,7 @@ bool cmGetPropertyCommand::InitialPass(std::vector<std::string> const& args, e << "given invalid scope " << args[1] << ". " << "Valid scopes are " << "GLOBAL, DIRECTORY, TARGET, SOURCE, TEST, VARIABLE, CACHE, INSTALL."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } @@ -80,86 +121,92 @@ bool cmGetPropertyCommand::InitialPass(std::vector<std::string> const& args, doing = DoingProperty; } else if (args[i] == "BRIEF_DOCS") { doing = DoingNone; - this->InfoType = OutBriefDoc; + infoType = OutBriefDoc; } else if (args[i] == "FULL_DOCS") { doing = DoingNone; - this->InfoType = OutFullDoc; + infoType = OutFullDoc; } else if (args[i] == "SET") { doing = DoingNone; - this->InfoType = OutSet; + infoType = OutSet; } else if (args[i] == "DEFINED") { doing = DoingNone; - this->InfoType = OutDefined; + infoType = OutDefined; } else if (doing == DoingName) { doing = DoingNone; - this->Name = args[i]; + name = args[i]; } else if (doing == DoingProperty) { doing = DoingNone; - this->PropertyName = args[i]; + propertyName = args[i]; } else { std::ostringstream e; e << "given invalid argument \"" << args[i] << "\"."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } } // Make sure a property name was found. - if (this->PropertyName.empty()) { - this->SetError("not given a PROPERTY <name> argument."); + if (propertyName.empty()) { + status.SetError("not given a PROPERTY <name> argument."); return false; } // Compute requested output. - if (this->InfoType == OutBriefDoc) { + if (infoType == OutBriefDoc) { // Lookup brief documentation. std::string output; if (cmPropertyDefinition const* def = - this->Makefile->GetState()->GetPropertyDefinition(this->PropertyName, - scope)) { + status.GetMakefile().GetState()->GetPropertyDefinition(propertyName, + scope)) { output = def->GetShortDescription(); } else { output = "NOTFOUND"; } - this->Makefile->AddDefinition(this->Variable, output); - } else if (this->InfoType == OutFullDoc) { + status.GetMakefile().AddDefinition(variable, output); + } else if (infoType == OutFullDoc) { // Lookup full documentation. std::string output; if (cmPropertyDefinition const* def = - this->Makefile->GetState()->GetPropertyDefinition(this->PropertyName, - scope)) { + status.GetMakefile().GetState()->GetPropertyDefinition(propertyName, + scope)) { output = def->GetFullDescription(); } else { output = "NOTFOUND"; } - this->Makefile->AddDefinition(this->Variable, output); - } else if (this->InfoType == OutDefined) { + status.GetMakefile().AddDefinition(variable, output); + } else if (infoType == OutDefined) { // Lookup if the property is defined - if (this->Makefile->GetState()->GetPropertyDefinition(this->PropertyName, - scope)) { - this->Makefile->AddDefinition(this->Variable, "1"); + if (status.GetMakefile().GetState()->GetPropertyDefinition(propertyName, + scope)) { + status.GetMakefile().AddDefinition(variable, "1"); } else { - this->Makefile->AddDefinition(this->Variable, "0"); + status.GetMakefile().AddDefinition(variable, "0"); } } else { // Dispatch property getting. switch (scope) { case cmProperty::GLOBAL: - return this->HandleGlobalMode(); + return HandleGlobalMode(status, name, infoType, variable, + propertyName); case cmProperty::DIRECTORY: - return this->HandleDirectoryMode(); + return HandleDirectoryMode(status, name, infoType, variable, + propertyName); case cmProperty::TARGET: - return this->HandleTargetMode(); + return HandleTargetMode(status, name, infoType, variable, + propertyName); case cmProperty::SOURCE_FILE: - return this->HandleSourceMode(); + return HandleSourceMode(status, name, infoType, variable, + propertyName); case cmProperty::TEST: - return this->HandleTestMode(); + return HandleTestMode(status, name, infoType, variable, propertyName); case cmProperty::VARIABLE: - return this->HandleVariableMode(); + return HandleVariableMode(status, name, infoType, variable, + propertyName); case cmProperty::CACHE: - return this->HandleCacheMode(); + return HandleCacheMode(status, name, infoType, variable, propertyName); case cmProperty::INSTALL: - return this->HandleInstallMode(); + return HandleInstallMode(status, name, infoType, variable, + propertyName); case cmProperty::CACHED_VARIABLE: break; // should never happen @@ -169,58 +216,64 @@ bool cmGetPropertyCommand::InitialPass(std::vector<std::string> const& args, return true; } -bool cmGetPropertyCommand::StoreResult(const char* value) +namespace { + +bool StoreResult(OutType infoType, cmMakefile& makefile, + const std::string& variable, const char* value) { - if (this->InfoType == OutSet) { - this->Makefile->AddDefinition(this->Variable, value ? "1" : "0"); - } else // if(this->InfoType == OutValue) + if (infoType == OutSet) { + makefile.AddDefinition(variable, value ? "1" : "0"); + } else // if(infoType == OutValue) { if (value) { - this->Makefile->AddDefinition(this->Variable, value); + makefile.AddDefinition(variable, value); } else { - this->Makefile->RemoveDefinition(this->Variable); + makefile.RemoveDefinition(variable); } } return true; } -bool cmGetPropertyCommand::HandleGlobalMode() +bool HandleGlobalMode(cmExecutionStatus& status, const std::string& name, + OutType infoType, const std::string& variable, + const std::string& propertyName) { - if (!this->Name.empty()) { - this->SetError("given name for GLOBAL scope."); + if (!name.empty()) { + status.SetError("given name for GLOBAL scope."); return false; } // Get the property. - cmake* cm = this->Makefile->GetCMakeInstance(); - return this->StoreResult( - cm->GetState()->GetGlobalProperty(this->PropertyName)); + cmake* cm = status.GetMakefile().GetCMakeInstance(); + return StoreResult(infoType, status.GetMakefile(), variable, + cm->GetState()->GetGlobalProperty(propertyName)); } -bool cmGetPropertyCommand::HandleDirectoryMode() +bool HandleDirectoryMode(cmExecutionStatus& status, const std::string& name, + OutType infoType, const std::string& variable, + const std::string& propertyName) { // Default to the current directory. - cmMakefile* mf = this->Makefile; + cmMakefile* mf = &status.GetMakefile(); // Lookup the directory if given. - if (!this->Name.empty()) { + if (!name.empty()) { // Construct the directory name. Interpret relative paths with // respect to the current directory. - std::string dir = this->Name; + std::string dir = name; if (!cmSystemTools::FileIsFullPath(dir)) { - dir = this->Makefile->GetCurrentSourceDirectory(); - dir += "/"; - dir += this->Name; + dir = + cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', name); } // The local generators are associated with collapsed paths. dir = cmSystemTools::CollapseFullPath(dir); // Lookup the generator. - mf = this->Makefile->GetGlobalGenerator()->FindMakefile(dir); + mf = status.GetMakefile().GetGlobalGenerator()->FindMakefile(dir); if (!mf) { // Could not find the directory. - this->SetError( + status.SetError( "DIRECTORY scope provided but requested directory was not found. " "This could be because the directory argument was invalid or, " "it is valid but has not been processed yet."); @@ -228,14 +281,15 @@ bool cmGetPropertyCommand::HandleDirectoryMode() } } - if (this->PropertyName == "DEFINITIONS") { + if (propertyName == "DEFINITIONS") { switch (mf->GetPolicyStatus(cmPolicies::CMP0059)) { case cmPolicies::WARN: mf->IssueMessage(MessageType::AUTHOR_WARNING, cmPolicies::GetPolicyWarning(cmPolicies::CMP0059)); CM_FALLTHROUGH; case cmPolicies::OLD: - return this->StoreResult(mf->GetDefineFlagsCMP0059()); + return StoreResult(infoType, status.GetMakefile(), variable, + mf->GetDefineFlagsCMP0059()); case cmPolicies::NEW: case cmPolicies::REQUIRED_ALWAYS: case cmPolicies::REQUIRED_IF_USED: @@ -244,124 +298,142 @@ bool cmGetPropertyCommand::HandleDirectoryMode() } // Get the property. - return this->StoreResult(mf->GetProperty(this->PropertyName)); + return StoreResult(infoType, status.GetMakefile(), variable, + mf->GetProperty(propertyName)); } -bool cmGetPropertyCommand::HandleTargetMode() +bool HandleTargetMode(cmExecutionStatus& status, const std::string& name, + OutType infoType, const std::string& variable, + const std::string& propertyName) { - if (this->Name.empty()) { - this->SetError("not given name for TARGET scope."); + if (name.empty()) { + status.SetError("not given name for TARGET scope."); return false; } - if (cmTarget* target = this->Makefile->FindTargetToUse(this->Name)) { - if (this->PropertyName == "ALIASED_TARGET") { - if (this->Makefile->IsAlias(this->Name)) { - return this->StoreResult(target->GetName().c_str()); + if (cmTarget* target = status.GetMakefile().FindTargetToUse(name)) { + if (propertyName == "ALIASED_TARGET") { + if (status.GetMakefile().IsAlias(name)) { + return StoreResult(infoType, status.GetMakefile(), variable, + target->GetName().c_str()); } - return this->StoreResult(nullptr); + return StoreResult(infoType, status.GetMakefile(), variable, nullptr); } const char* prop_cstr = nullptr; - cmListFileBacktrace bt = this->Makefile->GetBacktrace(); - cmMessenger* messenger = this->Makefile->GetMessenger(); + cmListFileBacktrace bt = status.GetMakefile().GetBacktrace(); + cmMessenger* messenger = status.GetMakefile().GetMessenger(); if (cmTargetPropertyComputer::PassesWhitelist( - target->GetType(), this->PropertyName, messenger, bt)) { - prop_cstr = - target->GetComputedProperty(this->PropertyName, messenger, bt); + target->GetType(), propertyName, messenger, bt)) { + prop_cstr = target->GetComputedProperty(propertyName, messenger, bt); if (!prop_cstr) { - prop_cstr = target->GetProperty(this->PropertyName); + prop_cstr = target->GetProperty(propertyName); } } - return this->StoreResult(prop_cstr); + return StoreResult(infoType, status.GetMakefile(), variable, prop_cstr); } std::ostringstream e; - e << "could not find TARGET " << this->Name + e << "could not find TARGET " << name << ". Perhaps it has not yet been created."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } -bool cmGetPropertyCommand::HandleSourceMode() +bool HandleSourceMode(cmExecutionStatus& status, const std::string& name, + OutType infoType, const std::string& variable, + const std::string& propertyName) { - if (this->Name.empty()) { - this->SetError("not given name for SOURCE scope."); + if (name.empty()) { + status.SetError("not given name for SOURCE scope."); return false; } // Get the source file. - if (cmSourceFile* sf = this->Makefile->GetOrCreateSource(this->Name)) { - return this->StoreResult(sf->GetPropertyForUser(this->PropertyName)); + if (cmSourceFile* sf = status.GetMakefile().GetOrCreateSource(name)) { + return StoreResult(infoType, status.GetMakefile(), variable, + sf->GetPropertyForUser(propertyName)); } std::ostringstream e; - e << "given SOURCE name that could not be found or created: " << this->Name; - this->SetError(e.str()); + e << "given SOURCE name that could not be found or created: " << name; + status.SetError(e.str()); return false; } -bool cmGetPropertyCommand::HandleTestMode() +bool HandleTestMode(cmExecutionStatus& status, const std::string& name, + OutType infoType, const std::string& variable, + const std::string& propertyName) { - if (this->Name.empty()) { - this->SetError("not given name for TEST scope."); + if (name.empty()) { + status.SetError("not given name for TEST scope."); return false; } // Loop over all tests looking for matching names. - if (cmTest* test = this->Makefile->GetTest(this->Name)) { - return this->StoreResult(test->GetProperty(this->PropertyName)); + if (cmTest* test = status.GetMakefile().GetTest(name)) { + return StoreResult(infoType, status.GetMakefile(), variable, + test->GetProperty(propertyName)); } // If not found it is an error. std::ostringstream e; - e << "given TEST name that does not exist: " << this->Name; - this->SetError(e.str()); + e << "given TEST name that does not exist: " << name; + status.SetError(e.str()); return false; } -bool cmGetPropertyCommand::HandleVariableMode() +bool HandleVariableMode(cmExecutionStatus& status, const std::string& name, + OutType infoType, const std::string& variable, + const std::string& propertyName) { - if (!this->Name.empty()) { - this->SetError("given name for VARIABLE scope."); + if (!name.empty()) { + status.SetError("given name for VARIABLE scope."); return false; } - return this->StoreResult(this->Makefile->GetDefinition(this->PropertyName)); + return StoreResult(infoType, status.GetMakefile(), variable, + status.GetMakefile().GetDefinition(propertyName)); } -bool cmGetPropertyCommand::HandleCacheMode() +bool HandleCacheMode(cmExecutionStatus& status, const std::string& name, + OutType infoType, const std::string& variable, + const std::string& propertyName) { - if (this->Name.empty()) { - this->SetError("not given name for CACHE scope."); + if (name.empty()) { + status.SetError("not given name for CACHE scope."); return false; } const char* value = nullptr; - if (this->Makefile->GetState()->GetCacheEntryValue(this->Name)) { - value = this->Makefile->GetState()->GetCacheEntryProperty( - this->Name, this->PropertyName); + if (status.GetMakefile().GetState()->GetCacheEntryValue(name)) { + value = status.GetMakefile().GetState()->GetCacheEntryProperty( + name, propertyName); } - this->StoreResult(value); + StoreResult(infoType, status.GetMakefile(), variable, value); return true; } -bool cmGetPropertyCommand::HandleInstallMode() +bool HandleInstallMode(cmExecutionStatus& status, const std::string& name, + OutType infoType, const std::string& variable, + const std::string& propertyName) { - if (this->Name.empty()) { - this->SetError("not given name for INSTALL scope."); + if (name.empty()) { + status.SetError("not given name for INSTALL scope."); return false; } // Get the installed file. - cmake* cm = this->Makefile->GetCMakeInstance(); + cmake* cm = status.GetMakefile().GetCMakeInstance(); if (cmInstalledFile* file = - cm->GetOrCreateInstalledFile(this->Makefile, this->Name)) { + cm->GetOrCreateInstalledFile(&status.GetMakefile(), name)) { std::string value; - bool isSet = file->GetProperty(this->PropertyName, value); + bool isSet = file->GetProperty(propertyName, value); - return this->StoreResult(isSet ? value.c_str() : nullptr); + return StoreResult(infoType, status.GetMakefile(), variable, + isSet ? value.c_str() : nullptr); } std::ostringstream e; - e << "given INSTALL name that could not be found or created: " << this->Name; - this->SetError(e.str()); + e << "given INSTALL name that could not be found or created: " << name; + status.SetError(e.str()); return false; } +} diff --git a/Source/cmGetPropertyCommand.h b/Source/cmGetPropertyCommand.h index 50e4014..cc600f4 100644 --- a/Source/cmGetPropertyCommand.h +++ b/Source/cmGetPropertyCommand.h @@ -8,55 +8,9 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -class cmGetPropertyCommand : public cmCommand -{ -public: - cmGetPropertyCommand(); - - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmGetPropertyCommand>(); - } - - /** - * This is called when the command is first encountered in - * the input file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; - -private: - enum OutType - { - OutValue, - OutDefined, - OutBriefDoc, - OutFullDoc, - OutSet - }; - std::string Variable; - std::string Name; - std::string PropertyName; - OutType InfoType; - - // Implementation of result storage. - bool StoreResult(const char* value); - - // Implementation of each property type. - bool HandleGlobalMode(); - bool HandleDirectoryMode(); - bool HandleTargetMode(); - bool HandleSourceMode(); - bool HandleTestMode(); - bool HandleVariableMode(); - bool HandleCacheMode(); - bool HandleInstallMode(); -}; +bool cmGetPropertyCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmGetSourceFilePropertyCommand.cxx b/Source/cmGetSourceFilePropertyCommand.cxx index a16076d..5c1c8a5 100644 --- a/Source/cmGetSourceFilePropertyCommand.cxx +++ b/Source/cmGetSourceFilePropertyCommand.cxx @@ -24,10 +24,6 @@ bool cmGetSourceFilePropertyCommand::InitialPass( sf = this->Makefile->CreateSource(file); } if (sf) { - if (args[2] == "LANGUAGE") { - this->Makefile->AddDefinition(var, sf->GetLanguage()); - return true; - } const char* prop = nullptr; if (!args[2].empty()) { prop = sf->GetPropertyForUser(args[2]); diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx index fc9ae01..e7b20ed 100644 --- a/Source/cmGhsMultiTargetGenerator.cxx +++ b/Source/cmGhsMultiTargetGenerator.cxx @@ -75,8 +75,8 @@ void cmGhsMultiTargetGenerator::Generate() break; } case cmStateEnums::SHARED_LIBRARY: { - std::string msg = "add_library(<name> SHARED ...) not supported: "; - msg += this->Name; + std::string msg = + cmStrCat("add_library(<name> SHARED ...) not supported: ", this->Name); cmSystemTools::Message(msg); return; } @@ -87,8 +87,8 @@ void cmGhsMultiTargetGenerator::Generate() break; } case cmStateEnums::MODULE_LIBRARY: { - std::string msg = "add_library(<name> MODULE ...) not supported: "; - msg += this->Name; + std::string msg = + cmStrCat("add_library(<name> MODULE ...) not supported: ", this->Name); cmSystemTools::Message(msg); return; } @@ -123,10 +123,9 @@ void cmGhsMultiTargetGenerator::Generate() void cmGhsMultiTargetGenerator::GenerateTarget() { // Open the target file in copy-if-different mode. - std::string fproj = this->LocalGenerator->GetCurrentBinaryDirectory(); - fproj += "/"; - fproj += this->Name; - fproj += cmGlobalGhsMultiGenerator::FILE_EXTENSION; + std::string fproj = + cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(), '/', + this->Name, cmGlobalGhsMultiGenerator::FILE_EXTENSION); cmGeneratedFileStream fout(fproj); fout.SetCopyIfDifferent(true); @@ -347,12 +346,11 @@ void cmGhsMultiTargetGenerator::WriteBuildEventsHelper( for (cmCustomCommand const& cc : ccv) { cmCustomCommandGenerator ccg(cc, this->ConfigName, this->LocalGenerator); // Open the filestream for this custom command - std::string fname = this->LocalGenerator->GetCurrentBinaryDirectory(); - fname += - "/" + this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget); - fname += "/" + this->Name + "_" + name; - fname += std::to_string(cmdcount++); - fname += this->CmdWindowsShell ? ".bat" : ".sh"; + std::string fname = + cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(), '/', + this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget), + '/', this->Name, '_', name, cmdcount++, + this->CmdWindowsShell ? ".bat" : ".sh"); cmGeneratedFileStream f(fname); f.SetCopyIfDifferent(true); this->WriteCustomCommandsHelper(f, ccg); @@ -395,8 +393,7 @@ void cmGhsMultiTargetGenerator::WriteCustomCommandsHelper( // Echo the custom command's comment text. const char* comment = ccg.GetComment(); if (comment && *comment) { - std::string echocmd = "echo "; - echocmd += comment; + std::string echocmd = cmStrCat("echo ", comment); cmdLines.push_back(std::move(echocmd)); } @@ -468,8 +465,7 @@ void cmGhsMultiTargetGenerator::WriteSourceProperty( { const char* prop = sf->GetProperty(propName); if (prop) { - std::vector<std::string> list; - cmExpandList(prop, list); + std::vector<std::string> list = cmExpandedList(prop); for (auto& p : list) { fout << " " << propFlag << p << std::endl; } @@ -569,14 +565,11 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj) // Open the filestream in copy-if-different mode. std::string gname = sg; cmsys::SystemTools::ReplaceString(gname, "\\", "_"); - std::string lpath = - this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget); - lpath += "/"; - lpath += gname; - lpath += cmGlobalGhsMultiGenerator::FILE_EXTENSION; - std::string fpath = this->LocalGenerator->GetCurrentBinaryDirectory(); - fpath += "/"; - fpath += lpath; + std::string lpath = cmStrCat( + this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget), '/', + gname, cmGlobalGhsMultiGenerator::FILE_EXTENSION); + std::string fpath = cmStrCat( + this->LocalGenerator->GetCurrentBinaryDirectory(), '/', lpath); cmGeneratedFileStream* f = new cmGeneratedFileStream(fpath); f->SetCopyIfDifferent(true); gfiles.push_back(f); @@ -668,14 +661,12 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj) this->LocalGenerator); // Open the filestream for this custom command - std::string fname = - this->LocalGenerator->GetCurrentBinaryDirectory(); - fname += "/" + - this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget); - fname += "/" + this->Name + "_cc"; - fname += std::to_string(cmdcount++) + "_"; - fname += (sf->GetLocation()).GetName(); - fname += this->CmdWindowsShell ? ".bat" : ".sh"; + std::string fname = cmStrCat( + this->LocalGenerator->GetCurrentBinaryDirectory(), '/', + this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget), + '/', this->Name, "_cc", cmdcount++, '_', + (sf->GetLocation()).GetName(), + this->CmdWindowsShell ? ".bat" : ".sh"); cmGeneratedFileStream f(fname); f.SetCopyIfDifferent(true); this->WriteCustomCommandsHelper(f, ccg); diff --git a/Source/cmGlobVerificationManager.cxx b/Source/cmGlobVerificationManager.cxx index 9fb4170..72451b2 100644 --- a/Source/cmGlobVerificationManager.cxx +++ b/Source/cmGlobVerificationManager.cxx @@ -7,6 +7,7 @@ #include "cmGeneratedFileStream.h" #include "cmListFileCache.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmVersion.h" @@ -16,8 +17,7 @@ bool cmGlobVerificationManager::SaveVerificationScript(const std::string& path) return true; } - std::string scriptFile = path; - scriptFile += "/CMakeFiles"; + std::string scriptFile = cmStrCat(path, "/CMakeFiles"); std::string stampFile = scriptFile; cmSystemTools::MakeDirectory(scriptFile); scriptFile += "/VerifyGlobs.cmake"; diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 80fd234..4342e9f 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -205,9 +205,7 @@ void cmGlobalGenerator::ResolveLanguageCompiler(const std::string& lang, cmMakefile* mf, bool optional) const { - std::string langComp = "CMAKE_"; - langComp += lang; - langComp += "_COMPILER"; + std::string langComp = cmStrCat("CMAKE_", lang, "_COMPILER"); if (!mf->GetDefinition(langComp)) { if (!optional) { @@ -368,8 +366,7 @@ bool cmGlobalGenerator::IsExportedTargetsFile( if (it == this->BuildExportSets.end()) { return false; } - return this->BuildExportExportSets.find(filename) == - this->BuildExportExportSets.end(); + return !cmContains(this->BuildExportExportSets, filename); } // Find the make program for the generator, required for try compiles @@ -409,9 +406,7 @@ bool cmGlobalGenerator::FindMakeProgram(cmMakefile* mf) std::string saveFile = file; cmSystemTools::GetShortPath(makeProgram, makeProgram); cmSystemTools::SplitProgramPath(makeProgram, dir, file); - makeProgram = dir; - makeProgram += "/"; - makeProgram += saveFile; + makeProgram = cmStrCat(dir, '/', saveFile); mf->AddCacheDefinition("CMAKE_MAKE_PROGRAM", makeProgram.c_str(), "make program", cmStateEnums::FILEPATH); } @@ -497,7 +492,7 @@ void cmGlobalGenerator::EnableLanguage( if (lang == "NONE") { this->SetLanguageEnabled("NONE", mf); } else { - if (this->LanguagesReady.find(lang) == this->LanguagesReady.end()) { + if (!cmContains(this->LanguagesReady, lang)) { std::ostringstream e; e << "The test project needs language " << lang << " which is not enabled."; @@ -513,8 +508,8 @@ void cmGlobalGenerator::EnableLanguage( bool fatalError = false; mf->AddDefinitionBool("RUN_CONFIGURE", true); - std::string rootBin = this->CMakeInstance->GetHomeOutputDirectory(); - rootBin += "/CMakeFiles"; + std::string rootBin = + cmStrCat(this->CMakeInstance->GetHomeOutputDirectory(), "/CMakeFiles"); // If the configuration files path has been set, // then we are in a try compile and need to copy the enable language @@ -593,8 +588,7 @@ void cmGlobalGenerator::EnableLanguage( mf->ReadListFile(systemFile); // load the CMakeSystem.cmake from the binary directory // this file is configured by the CMakeDetermineSystem.cmake file - fpath = rootBin; - fpath += "/CMakeSystem.cmake"; + fpath = cmStrCat(rootBin, "/CMakeSystem.cmake"); mf->ReadListFile(fpath); } @@ -660,14 +654,9 @@ void cmGlobalGenerator::EnableLanguage( this->SetLanguageEnabled("NONE", mf); continue; } - std::string loadedLang = "CMAKE_"; - loadedLang += lang; - loadedLang += "_COMPILER_LOADED"; + std::string loadedLang = cmStrCat("CMAKE_", lang, "_COMPILER_LOADED"); if (!mf->GetDefinition(loadedLang)) { - fpath = rootBin; - fpath += "/CMake"; - fpath += lang; - fpath += "Compiler.cmake"; + fpath = cmStrCat(rootBin, "/CMake", lang, "Compiler.cmake"); // If the existing build tree was already configured with this // version of CMake then try to load the configured file first @@ -694,9 +683,8 @@ void cmGlobalGenerator::EnableLanguage( } // if the CMake(LANG)Compiler.cmake file was not found then // load CMakeDetermine(LANG)Compiler.cmake - std::string determineCompiler = "CMakeDetermine"; - determineCompiler += lang; - determineCompiler += "Compiler.cmake"; + std::string determineCompiler = + cmStrCat("CMakeDetermine", lang, "Compiler.cmake"); std::string determineFile = mf->GetModulesFile(determineCompiler); if (!mf->ReadListFile(determineFile)) { cmSystemTools::Error("Could not find cmake module file: " + @@ -712,27 +700,19 @@ void cmGlobalGenerator::EnableLanguage( // put ${CMake_(LANG)_COMPILER_ENV_VAR}=${CMAKE_(LANG)_COMPILER // into the environment, in case user scripts want to run // configure, or sub cmakes - std::string compilerName = "CMAKE_"; - compilerName += lang; - compilerName += "_COMPILER"; - std::string compilerEnv = "CMAKE_"; - compilerEnv += lang; - compilerEnv += "_COMPILER_ENV_VAR"; + std::string compilerName = cmStrCat("CMAKE_", lang, "_COMPILER"); + std::string compilerEnv = + cmStrCat("CMAKE_", lang, "_COMPILER_ENV_VAR"); const std::string& envVar = mf->GetRequiredDefinition(compilerEnv); const std::string& envVarValue = mf->GetRequiredDefinition(compilerName); - std::string env = envVar; - env += "="; - env += envVarValue; + std::string env = cmStrCat(envVar, '=', envVarValue); cmSystemTools::PutEnv(env); } // if determineLanguage was called then load the file it // configures CMake(LANG)Compiler.cmake - fpath = rootBin; - fpath += "/CMake"; - fpath += lang; - fpath += "Compiler.cmake"; + fpath = cmStrCat(rootBin, "/CMake", lang, "Compiler.cmake"); if (!mf->ReadListFile(fpath)) { cmSystemTools::Error("Could not find cmake module file: " + fpath); } @@ -763,12 +743,8 @@ void cmGlobalGenerator::EnableLanguage( } // Check that the compiler was found. - std::string compilerName = "CMAKE_"; - compilerName += lang; - compilerName += "_COMPILER"; - std::string compilerEnv = "CMAKE_"; - compilerEnv += lang; - compilerEnv += "_COMPILER_ENV_VAR"; + std::string compilerName = cmStrCat("CMAKE_", lang, "_COMPILER"); + std::string compilerEnv = cmStrCat("CMAKE_", lang, "_COMPILER_ENV_VAR"); std::ostringstream noCompiler; const char* compilerFile = mf->GetDefinition(compilerName); if (!compilerFile || !*compilerFile || cmIsNOTFOUND(compilerFile)) { @@ -802,10 +778,8 @@ void cmGlobalGenerator::EnableLanguage( if (!optional) { // The compiler was not found and it is not optional. Remove // CMake(LANG)Compiler.cmake so we try again next time CMake runs. - std::string compilerLangFile = rootBin; - compilerLangFile += "/CMake"; - compilerLangFile += lang; - compilerLangFile += "Compiler.cmake"; + std::string compilerLangFile = + cmStrCat(rootBin, "/CMake", lang, "Compiler.cmake"); cmSystemTools::RemoveFile(compilerLangFile); if (!this->CMakeInstance->GetIsInTryCompile()) { this->PrintCompilerAdvice(noCompiler, lang, @@ -816,13 +790,10 @@ void cmGlobalGenerator::EnableLanguage( } } - std::string langLoadedVar = "CMAKE_"; - langLoadedVar += lang; - langLoadedVar += "_INFORMATION_LOADED"; + std::string langLoadedVar = + cmStrCat("CMAKE_", lang, "_INFORMATION_LOADED"); if (!mf->GetDefinition(langLoadedVar)) { - fpath = "CMake"; - fpath += lang; - fpath += "Information.cmake"; + fpath = cmStrCat("CMake", lang, "Information.cmake"); std::string informationFile = mf->GetModulesFile(fpath); if (informationFile.empty()) { cmSystemTools::Error("Could not find cmake module file: " + fpath); @@ -843,33 +814,27 @@ void cmGlobalGenerator::EnableLanguage( // If the language is untested then test it now with a try compile. if (needTestLanguage[lang]) { if (!this->CMakeInstance->GetIsInTryCompile()) { - std::string testLang = "CMakeTest"; - testLang += lang; - testLang += "Compiler.cmake"; + std::string testLang = cmStrCat("CMakeTest", lang, "Compiler.cmake"); std::string ifpath = mf->GetModulesFile(testLang); if (!mf->ReadListFile(ifpath)) { cmSystemTools::Error("Could not find cmake module file: " + testLang); } - std::string compilerWorks = "CMAKE_"; - compilerWorks += lang; - compilerWorks += "_COMPILER_WORKS"; + std::string compilerWorks = + cmStrCat("CMAKE_", lang, "_COMPILER_WORKS"); // if the compiler did not work, then remove the // CMake(LANG)Compiler.cmake file so that it will get tested the // next time cmake is run if (!mf->IsOn(compilerWorks)) { - std::string compilerLangFile = rootBin; - compilerLangFile += "/CMake"; - compilerLangFile += lang; - compilerLangFile += "Compiler.cmake"; + std::string compilerLangFile = + cmStrCat(rootBin, "/CMake", lang, "Compiler.cmake"); cmSystemTools::RemoveFile(compilerLangFile); } } // end if in try compile } // end need test language // Store the shared library flags so that we can satisfy CMP0018 - std::string sharedLibFlagsVar = "CMAKE_SHARED_LIBRARY_"; - sharedLibFlagsVar += lang; - sharedLibFlagsVar += "_FLAGS"; + std::string sharedLibFlagsVar = + cmStrCat("CMAKE_SHARED_LIBRARY_", lang, "_FLAGS"); this->LanguageToOriginalSharedLibFlags[lang] = mf->GetSafeDefinition(sharedLibFlagsVar); @@ -880,10 +845,9 @@ void cmGlobalGenerator::EnableLanguage( // Now load files that can override any settings on the platform or for // the project First load the project compatibility file if it is in // cmake - std::string projectCompatibility = cmSystemTools::GetCMakeRoot(); - projectCompatibility += "/Modules/"; - projectCompatibility += mf->GetSafeDefinition("PROJECT_NAME"); - projectCompatibility += "Compatibility.cmake"; + std::string projectCompatibility = + cmStrCat(cmSystemTools::GetCMakeRoot(), "/Modules/", + mf->GetSafeDefinition("PROJECT_NAME"), "Compatibility.cmake"); if (cmSystemTools::FileExists(projectCompatibility)) { mf->ReadListFile(projectCompatibility); } @@ -920,12 +884,9 @@ void cmGlobalGenerator::CheckCompilerIdCompatibility( cmMakefile* mf, std::string const& lang) const { std::string compilerIdVar = "CMAKE_" + lang + "_COMPILER_ID"; - const char* compilerId = mf->GetDefinition(compilerIdVar); - if (!compilerId) { - return; - } + std::string const compilerId = mf->GetSafeDefinition(compilerIdVar); - if (strcmp(compilerId, "AppleClang") == 0) { + if (compilerId == "AppleClang") { switch (mf->GetPolicyStatus(cmPolicies::CMP0025)) { case cmPolicies::WARN: if (!this->CMakeInstance->GetIsInTryCompile() && @@ -955,7 +916,7 @@ void cmGlobalGenerator::CheckCompilerIdCompatibility( } } - if (strcmp(compilerId, "QCC") == 0) { + if (compilerId == "QCC") { switch (mf->GetPolicyStatus(cmPolicies::CMP0047)) { case cmPolicies::WARN: if (!this->CMakeInstance->GetIsInTryCompile() && @@ -991,7 +952,7 @@ void cmGlobalGenerator::CheckCompilerIdCompatibility( } } - if (strcmp(compilerId, "XLClang") == 0) { + if (compilerId == "XLClang") { switch (mf->GetPolicyStatus(cmPolicies::CMP0089)) { case cmPolicies::WARN: if (!this->CMakeInstance->GetIsInTryCompile() && @@ -1096,8 +1057,7 @@ void cmGlobalGenerator::SetLanguageEnabledMaps(const std::string& l, { // use LanguageToLinkerPreference to detect whether this functions has // run before - if (this->LanguageToLinkerPreference.find(l) != - this->LanguageToLinkerPreference.end()) { + if (cmContains(this->LanguageToLinkerPreference, l)) { return; } @@ -1120,8 +1080,8 @@ void cmGlobalGenerator::SetLanguageEnabledMaps(const std::string& l, } if (preference < 0) { - std::string msg = linkerPrefVar; - msg += " is negative, adjusting it to 0"; + std::string msg = + cmStrCat(linkerPrefVar, " is negative, adjusting it to 0"); cmSystemTools::Message(msg, "Warning"); preference = 0; } @@ -1147,8 +1107,7 @@ void cmGlobalGenerator::SetLanguageEnabledMaps(const std::string& l, std::string ignoreExtensionsVar = std::string("CMAKE_") + std::string(l) + std::string("_IGNORE_EXTENSIONS"); std::string ignoreExts = mf->GetSafeDefinition(ignoreExtensionsVar); - std::vector<std::string> extensionList; - cmExpandList(ignoreExts, extensionList); + std::vector<std::string> extensionList = cmExpandedList(ignoreExts); for (std::string const& i : extensionList) { this->IgnoreExtensions[i] = true; } @@ -1160,8 +1119,7 @@ void cmGlobalGenerator::FillExtensionToLanguageMap(const std::string& l, std::string extensionsVar = std::string("CMAKE_") + std::string(l) + std::string("_SOURCE_FILE_EXTENSIONS"); const std::string& exts = mf->GetSafeDefinition(extensionsVar); - std::vector<std::string> extensionList; - cmExpandList(exts, extensionList); + std::vector<std::string> extensionList = cmExpandedList(exts); for (std::string const& i : extensionList) { this->ExtensionToLanguage[i] = l; } @@ -1276,9 +1234,8 @@ void cmGlobalGenerator::Configure() msg << "Configuring incomplete, errors occurred!"; const char* logs[] = { "CMakeOutput.log", "CMakeError.log", nullptr }; for (const char** log = logs; *log; ++log) { - std::string f = this->CMakeInstance->GetHomeOutputDirectory(); - f += "/CMakeFiles/"; - f += *log; + std::string f = cmStrCat(this->CMakeInstance->GetHomeOutputDirectory(), + "/CMakeFiles/", *log); if (cmSystemTools::FileExists(f)) { msg << "\nSee also \"" << f << "\"."; } @@ -1604,8 +1561,8 @@ void cmGlobalGenerator::FinalizeTargetCompileInfo() mf->GetConfigurations(configs); for (std::string const& c : configs) { - std::string defPropName = "COMPILE_DEFINITIONS_"; - defPropName += cmSystemTools::UpperCase(c); + std::string defPropName = + cmStrCat("COMPILE_DEFINITIONS_", cmSystemTools::UpperCase(c)); t->AppendProperty(defPropName, mf->GetProperty(defPropName)); } } @@ -1619,8 +1576,8 @@ void cmGlobalGenerator::FinalizeTargetCompileInfo() "CMAKE_" + li + "_STANDARD_INCLUDE_DIRECTORIES"; std::string const& standardIncludesStr = mf->GetSafeDefinition(standardIncludesVar); - std::vector<std::string> standardIncludesVec; - cmExpandList(standardIncludesStr, standardIncludesVec); + std::vector<std::string> standardIncludesVec = + cmExpandedList(standardIncludesStr); standardIncludesSet.insert(standardIncludesVec.begin(), standardIncludesVec.end()); } @@ -1712,11 +1669,10 @@ void cmGlobalGenerator::CheckTargetProperties() if (state->GetCacheEntryPropertyAsBool(varName, "ADVANCED")) { varName += " (ADVANCED)"; } - std::string text = notFoundMap[varName]; - text += "\n linked by target \""; - text += target.second.GetName(); - text += "\" in directory "; - text += this->Makefiles[i]->GetCurrentSourceDirectory(); + std::string text = + cmStrCat(notFoundMap[varName], "\n linked by target \"", + target.second.GetName(), "\" in directory ", + this->Makefiles[i]->GetCurrentSourceDirectory()); notFoundMap[varName] = text; } } @@ -1738,9 +1694,10 @@ void cmGlobalGenerator::CheckTargetProperties() if (state->GetCacheEntryPropertyAsBool(varName, "ADVANCED")) { varName += " (ADVANCED)"; } - std::string text = notFoundMap[varName]; - text += "\n used as include directory in directory "; - text += this->Makefiles[i]->GetCurrentSourceDirectory(); + std::string text = + cmStrCat(notFoundMap[varName], + "\n used as include directory in directory ", + this->Makefiles[i]->GetCurrentSourceDirectory()); notFoundMap[varName] = text; } } @@ -1839,8 +1796,8 @@ int cmGlobalGenerator::Build( output += "\n"; if (workdir.Failed()) { cmSystemTools::SetRunCommandHideConsole(hideconsole); - std::string err = "Failed to change directory: "; - err += std::strerror(workdir.GetLastResult()); + std::string err = cmStrCat("Failed to change directory: ", + std::strerror(workdir.GetLastResult())); cmSystemTools::Error(err); output += err; output += "\n"; @@ -1945,8 +1902,8 @@ std::string cmGlobalGenerator::GenerateCMakeBuildCommand( const std::string& native, bool ignoreErrors) { std::string makeCommand = cmSystemTools::GetCMakeCommand(); - makeCommand = cmSystemTools::ConvertToOutputPath(makeCommand); - makeCommand += " --build ."; + makeCommand = + cmStrCat(cmSystemTools::ConvertToOutputPath(makeCommand), " --build ."); if (!config.empty()) { makeCommand += " --config \""; makeCommand += config; @@ -2049,8 +2006,8 @@ void cmGlobalGenerator::SetConfiguredFilesPath(cmGlobalGenerator* gen) if (!gen->ConfiguredFilesPath.empty()) { this->ConfiguredFilesPath = gen->ConfiguredFilesPath; } else { - this->ConfiguredFilesPath = gen->CMakeInstance->GetHomeOutputDirectory(); - this->ConfiguredFilesPath += "/CMakeFiles"; + this->ConfiguredFilesPath = + cmStrCat(gen->CMakeInstance->GetHomeOutputDirectory(), "/CMakeFiles"); } } @@ -2150,7 +2107,7 @@ void cmGlobalGenerator::AddAlias(const std::string& name, bool cmGlobalGenerator::IsAlias(const std::string& name) const { - return this->AliasTargets.find(name) != this->AliasTargets.end(); + return cmContains(this->AliasTargets, name); } void cmGlobalGenerator::IndexTarget(cmTarget* t) @@ -2320,8 +2277,8 @@ void cmGlobalGenerator::AddGlobalTarget_Package( std::vector<GlobalTargetInfo>& targets) { cmMakefile* mf = this->Makefiles[0]; - std::string configFile = mf->GetCurrentBinaryDirectory(); - configFile += "/CPackConfig.cmake"; + std::string configFile = + cmStrCat(mf->GetCurrentBinaryDirectory(), "/CPackConfig.cmake"); if (!cmSystemTools::FileExists(configFile)) { return; } @@ -2369,8 +2326,8 @@ void cmGlobalGenerator::AddGlobalTarget_PackageSource( } cmMakefile* mf = this->Makefiles[0]; - std::string configFile = mf->GetCurrentBinaryDirectory(); - configFile += "/CPackSourceConfig.cmake"; + std::string configFile = + cmStrCat(mf->GetCurrentBinaryDirectory(), "/CPackSourceConfig.cmake"); if (!cmSystemTools::FileExists(configFile)) { return; } @@ -2649,8 +2606,7 @@ cmTarget cmGlobalGenerator::CreateGlobalTarget(GlobalTargetInfo const& gti, std::string cmGlobalGenerator::GenerateRuleFile( std::string const& output) const { - std::string ruleFile = output; - ruleFile += ".rule"; + std::string ruleFile = cmStrCat(output, ".rule"); const char* dir = this->GetCMakeCFGIntDir(); if (dir && dir[0] == '$') { cmSystemTools::ReplaceString(ruleFile, dir, "/CMakeFiles"); @@ -2700,8 +2656,7 @@ bool cmGlobalGenerator::IsReservedTarget(std::string const& name) "clean", "edit_cache", "rebuild_cache", "ZERO_CHECK" }; - return std::find(cm::cbegin(reservedTargets), cm::cend(reservedTargets), - name) != cm::cend(reservedTargets); + return cmContains(reservedTargets, name); } void cmGlobalGenerator::SetExternalMakefileProjectGenerator( @@ -2849,8 +2804,7 @@ void cmGlobalGenerator::CheckRuleHashes() { #if !defined(CMAKE_BOOTSTRAP) std::string home = this->GetCMakeInstance()->GetHomeOutputDirectory(); - std::string pfile = home; - pfile += "/CMakeFiles/CMakeRuleHashes.txt"; + std::string pfile = cmStrCat(home, "/CMakeFiles/CMakeRuleHashes.txt"); this->CheckRuleHashes(pfile, home); this->WriteRuleHashes(pfile); #endif @@ -2926,8 +2880,8 @@ void cmGlobalGenerator::WriteRuleHashes(std::string const& pfile) void cmGlobalGenerator::WriteSummary() { // Record all target directories in a central location. - std::string fname = this->CMakeInstance->GetHomeOutputDirectory(); - fname += "/CMakeFiles/TargetDirectories.txt"; + std::string fname = cmStrCat(this->CMakeInstance->GetHomeOutputDirectory(), + "/CMakeFiles/TargetDirectories.txt"); cmGeneratedFileStream fout(fname); for (cmLocalGenerator* lg : this->LocalGenerators) { @@ -2945,8 +2899,7 @@ void cmGlobalGenerator::WriteSummary(cmGeneratorTarget* target) { // Place the labels file in a per-target support directory. std::string dir = target->GetSupportDirectory(); - std::string file = dir; - file += "/Labels.txt"; + std::string file = cmStrCat(dir, "/Labels.txt"); std::string json_file = dir + "/Labels.json"; #ifndef CMAKE_BOOTSTRAP @@ -3114,8 +3067,8 @@ bool cmGlobalGenerator::GenerateCPackPropertiesFile() std::vector<std::string> configs; std::string config = mf->GetConfigurations(configs, false); - std::string path = this->CMakeInstance->GetHomeOutputDirectory(); - path += "/CPackProperties.cmake"; + std::string path = cmStrCat(this->CMakeInstance->GetHomeOutputDirectory(), + "/CPackProperties.cmake"); if (!cmSystemTools::FileExists(path) && installedFiles.empty()) { return true; diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx index 5aae546..0b45f4b 100644 --- a/Source/cmGlobalGhsMultiGenerator.cxx +++ b/Source/cmGlobalGhsMultiGenerator.cxx @@ -2,6 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmGlobalGhsMultiGenerator.h" +#include "cmAlgorithms.h" #include "cmDocumentationEntry.h" #include "cmGeneratedFileStream.h" #include "cmGeneratorTarget.h" @@ -56,11 +57,9 @@ void cmGlobalGhsMultiGenerator::ComputeTargetObjectDirectory( cmGeneratorTarget* gt) const { // Compute full path to object file directory for this target. - std::string dir; - dir += gt->LocalGenerator->GetCurrentBinaryDirectory(); - dir += "/"; - dir += gt->LocalGenerator->GetTargetDirectory(gt); - dir += "/"; + std::string dir = + cmStrCat(gt->LocalGenerator->GetCurrentBinaryDirectory(), '/', + gt->LocalGenerator->GetTargetDirectory(gt), '/'); gt->ObjectDirectory = dir; } @@ -77,10 +76,9 @@ bool cmGlobalGhsMultiGenerator::SetGeneratorToolset(std::string const& ts, } if (ts.empty()) { std::string message; - message = - "Green Hills MULTI: -T <toolset> not specified; defaulting to \""; - message += tsp; - message += "\""; + message = cmStrCat( + "Green Hills MULTI: -T <toolset> not specified; defaulting to \"", tsp, + '"'); cmSystemTools::Message(message); /* store the full toolset for later use @@ -98,12 +96,11 @@ bool cmGlobalGhsMultiGenerator::SetGeneratorToolset(std::string const& ts, /* check if the toolset changed from last generate */ if (prevTool != nullptr && (gbuild != prevTool)) { - std::string message = "toolset build tool: "; - message += gbuild; - message += "\nDoes not match the previously used build tool: "; - message += prevTool; - message += "\nEither remove the CMakeCache.txt file and CMakeFiles " - "directory or choose a different binary directory."; + std::string message = + cmStrCat("toolset build tool: ", gbuild, + "\nDoes not match the previously used build tool: ", prevTool, + "\nEither remove the CMakeCache.txt file and CMakeFiles " + "directory or choose a different binary directory."); cmSystemTools::Error(message); return false; } @@ -142,19 +139,17 @@ bool cmGlobalGhsMultiGenerator::SetGeneratorPlatform(std::string const& p, if (cmIsOff(osdir) && platform.find("integrity") != std::string::npos) { if (!this->CMakeInstance->GetIsInTryCompile()) { /* required OS location is not found */ - std::string m = - "Green Hills MULTI: GHS_OS_DIR not specified; No OS found in \""; - m += mf->GetSafeDefinition("GHS_OS_ROOT"); - m += "\""; + std::string m = cmStrCat( + "Green Hills MULTI: GHS_OS_DIR not specified; No OS found in \"", + mf->GetSafeDefinition("GHS_OS_ROOT"), '"'); cmSystemTools::Message(m); } osdir = "GHS_OS_DIR-NOT-SPECIFIED"; } else if (!this->CMakeInstance->GetIsInTryCompile() && cmIsOff(this->OsDir) && !cmIsOff(osdir)) { /* OS location was updated by auto-selection */ - std::string m = "Green Hills MULTI: GHS_OS_DIR not specified; found \""; - m += osdir; - m += "\""; + std::string m = cmStrCat( + "Green Hills MULTI: GHS_OS_DIR not specified; found \"", osdir, '"'); cmSystemTools::Message(m); } this->OsDir = osdir; @@ -168,10 +163,9 @@ bool cmGlobalGhsMultiGenerator::SetGeneratorPlatform(std::string const& p, mf->AddCacheDefinition("GHS_BSP_NAME", bspName.c_str(), "Name of GHS target platform.", cmStateEnums::STRING, true); - std::string m = - "Green Hills MULTI: GHS_BSP_NAME not specified; defaulting to \""; - m += bspName; - m += "\""; + std::string m = cmStrCat( + "Green Hills MULTI: GHS_BSP_NAME not specified; defaulting to \"", + bspName, '"'); cmSystemTools::Message(m); } @@ -402,8 +396,8 @@ void cmGlobalGhsMultiGenerator::WriteProjectLine( void cmGlobalGhsMultiGenerator::WriteTargets(cmLocalGenerator* root) { - std::string rootBinaryDir = root->GetCurrentBinaryDirectory(); - rootBinaryDir += "/CMakeFiles"; + std::string rootBinaryDir = + cmStrCat(root->GetCurrentBinaryDirectory(), "/CMakeFiles"); // All known targets for (cmGeneratorTarget const* target : this->ProjectTargets) { @@ -478,8 +472,8 @@ void cmGlobalGhsMultiGenerator::WriteAllTarget( cmSystemTools::Error(message); } else { // determine the targets for ALL target - std::string rootBinaryDir = root->GetCurrentBinaryDirectory(); - rootBinaryDir += "/CMakeFiles"; + std::string rootBinaryDir = + cmStrCat(root->GetCurrentBinaryDirectory(), "/CMakeFiles"); for (cmGeneratorTarget const* target : build) { if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY || target->GetType() == cmStateEnums::MODULE_LIBRARY || @@ -537,11 +531,8 @@ void cmGlobalGhsMultiGenerator::OutputTopLevelProject( * with target projects. This avoid the issue where the project has * the same name as the executable target. */ - fname = root->GetCurrentBinaryDirectory(); - fname += "/"; - fname += root->GetProjectName(); - fname += ".top"; - fname += FILE_EXTENSION; + fname = cmStrCat(root->GetCurrentBinaryDirectory(), '/', + root->GetProjectName(), ".top", FILE_EXTENSION); cmGeneratedFileStream top(fname); top.SetCopyIfDifferent(true); @@ -586,16 +577,14 @@ cmGlobalGhsMultiGenerator::GenerateBuildCommand( /* if multiple top-projects are found in build directory * then prefer projectName top-project. */ - auto p = std::find(files.begin(), files.end(), proj); - if (p == files.end()) { + if (!cmContains(files, proj)) { proj = files.at(0); } } makeCommand.Add("-top", proj); if (!targetNames.empty()) { - if (std::find(targetNames.begin(), targetNames.end(), "clean") != - targetNames.end()) { + if (cmContains(targetNames, "clean")) { makeCommand.Add("-clean"); } else { for (const auto& tname : targetNames) { @@ -621,8 +610,8 @@ void cmGlobalGhsMultiGenerator::WriteMacros(std::ostream& fout, char const* ghsGpjMacros = this->GetCMakeInstance()->GetCacheDefinition("GHS_GPJ_MACROS"); if (nullptr != ghsGpjMacros) { - std::vector<std::string> expandedList; - cmExpandList(std::string(ghsGpjMacros), expandedList); + std::vector<std::string> expandedList = + cmExpandedList(std::string(ghsGpjMacros)); for (std::string const& arg : expandedList) { fout << "macro " << arg << std::endl; } @@ -644,10 +633,7 @@ void cmGlobalGhsMultiGenerator::WriteHighLevelDirectives( this->GetCMakeInstance()->GetCacheDefinition("CMAKE_GENERATOR_PLATFORM"); const char* p = this->GetCMakeInstance()->GetCacheDefinition("GHS_TARGET_PLATFORM"); - tgt = (a ? a : ""); - tgt += "_"; - tgt += (p ? p : ""); - tgt += ".tgt"; + tgt = cmStrCat((a ? a : ""), '_', (p ? p : ""), ".tgt"); } fout << "primaryTarget=" << tgt << std::endl; diff --git a/Source/cmGlobalMSYSMakefileGenerator.cxx b/Source/cmGlobalMSYSMakefileGenerator.cxx index 483d4ab..ae9d5a7 100644 --- a/Source/cmGlobalMSYSMakefileGenerator.cxx +++ b/Source/cmGlobalMSYSMakefileGenerator.cxx @@ -24,8 +24,7 @@ cmGlobalMSYSMakefileGenerator::cmGlobalMSYSMakefileGenerator(cmake* cm) std::string cmGlobalMSYSMakefileGenerator::FindMinGW( std::string const& makeloc) { - std::string fstab = makeloc; - fstab += "/../etc/fstab"; + std::string fstab = cmStrCat(makeloc, "/../etc/fstab"); cmsys::ifstream fin(fstab.c_str()); std::string path; std::string mount; @@ -34,8 +33,7 @@ std::string cmGlobalMSYSMakefileGenerator::FindMinGW( fin >> path; fin >> mount; if (mount == "/mingw") { - mingwBin = path; - mingwBin += "/bin"; + mingwBin = cmStrCat(path, "/bin"); } } return mingwBin; diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 29caa16..062eccb 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -571,8 +571,7 @@ void cmGlobalNinjaGenerator::CheckNinjaFeatures() bool cmGlobalNinjaGenerator::CheckLanguages( std::vector<std::string> const& languages, cmMakefile* mf) const { - if (std::find(languages.begin(), languages.end(), "Fortran") != - languages.end()) { + if (cmContains(languages, "Fortran")) { return this->CheckFortran(mf); } return true; @@ -705,11 +704,9 @@ void cmGlobalNinjaGenerator::ComputeTargetObjectDirectory( cmGeneratorTarget* gt) const { // Compute full path to object file directory for this target. - std::string dir; - dir += gt->LocalGenerator->GetCurrentBinaryDirectory(); - dir += "/"; - dir += gt->LocalGenerator->GetTargetDirectory(gt); - dir += "/"; + std::string dir = + cmStrCat(gt->LocalGenerator->GetCurrentBinaryDirectory(), '/', + gt->LocalGenerator->GetTargetDirectory(gt), '/'); gt->ObjectDirectory = dir; } @@ -719,9 +716,8 @@ bool cmGlobalNinjaGenerator::OpenBuildFileStream() { // Compute Ninja's build file path. std::string buildFilePath = - this->GetCMakeInstance()->GetHomeOutputDirectory(); - buildFilePath += "/"; - buildFilePath += cmGlobalNinjaGenerator::NINJA_BUILD_FILE; + cmStrCat(this->GetCMakeInstance()->GetHomeOutputDirectory(), '/', + cmGlobalNinjaGenerator::NINJA_BUILD_FILE); // Get a stream where to generate things. if (!this->BuildFileStream) { @@ -758,9 +754,8 @@ bool cmGlobalNinjaGenerator::OpenRulesFileStream() { // Compute Ninja's build file path. std::string rulesFilePath = - this->GetCMakeInstance()->GetHomeOutputDirectory(); - rulesFilePath += "/"; - rulesFilePath += cmGlobalNinjaGenerator::NINJA_RULES_FILE; + cmStrCat(this->GetCMakeInstance()->GetHomeOutputDirectory(), '/', + cmGlobalNinjaGenerator::NINJA_RULES_FILE); // Get a stream where to generate things. if (!this->RulesFileStream) { @@ -1315,13 +1310,13 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os) { cmNinjaRule rule("RERUN_CMAKE"); - rule.Command = CMakeCmd(); - rule.Command += " -S"; - rule.Command += lg->ConvertToOutputFormat(lg->GetSourceDirectory(), - cmOutputConverter::SHELL); - rule.Command += " -B"; - rule.Command += lg->ConvertToOutputFormat(lg->GetBinaryDirectory(), - cmOutputConverter::SHELL); + rule.Command = + cmStrCat(CMakeCmd(), " -S", + lg->ConvertToOutputFormat(lg->GetSourceDirectory(), + cmOutputConverter::SHELL), + " -B", + lg->ConvertToOutputFormat(lg->GetBinaryDirectory(), + cmOutputConverter::SHELL)); rule.Description = "Re-running CMake..."; rule.Comment = "Rule for re-running cmake."; rule.Generator = true; @@ -1349,10 +1344,10 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os) if (this->SupportsManifestRestat() && cm->DoWriteGlobVerifyTarget()) { { cmNinjaRule rule("VERIFY_GLOBS"); - rule.Command = CMakeCmd(); - rule.Command += " -P "; - rule.Command += lg->ConvertToOutputFormat(cm->GetGlobVerifyScript(), - cmOutputConverter::SHELL); + rule.Command = + cmStrCat(CMakeCmd(), " -P ", + lg->ConvertToOutputFormat(cm->GetGlobVerifyScript(), + cmOutputConverter::SHELL)); rule.Description = "Re-checking globbed directories..."; rule.Comment = "Rule for re-checking globbed directories."; rule.Generator = true; @@ -1458,9 +1453,8 @@ bool cmGlobalNinjaGenerator::WriteTargetCleanAdditional(std::ostream& os) { cmLocalGenerator* lgr = this->LocalGenerators.at(0); std::string cleanScriptRel = "CMakeFiles/clean_additional.cmake"; - std::string cleanScriptAbs = lgr->GetBinaryDirectory(); - cleanScriptAbs += '/'; - cleanScriptAbs += cleanScriptRel; + std::string cleanScriptAbs = + cmStrCat(lgr->GetBinaryDirectory(), '/', cleanScriptRel); // Check if there are additional files to clean if (this->AdditionalCleanFiles.empty()) { @@ -1490,10 +1484,10 @@ bool cmGlobalNinjaGenerator::WriteTargetCleanAdditional(std::ostream& os) // Write rule { cmNinjaRule rule("CLEAN_ADDITIONAL"); - rule.Command = CMakeCmd(); - rule.Command += " -P "; - rule.Command += lgr->ConvertToOutputFormat( - this->NinjaOutputPath(cleanScriptRel), cmOutputConverter::SHELL); + rule.Command = cmStrCat( + CMakeCmd(), " -P ", + lgr->ConvertToOutputFormat(this->NinjaOutputPath(cleanScriptRel), + cmOutputConverter::SHELL)); rule.Description = "Cleaning additional files..."; rule.Comment = "Rule for cleaning additional files."; WriteRule(*this->RulesFileStream, rule); diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index d311c1e..22c304e 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.cxx +++ b/Source/cmGlobalUnixMakefileGenerator3.cxx @@ -108,11 +108,9 @@ void cmGlobalUnixMakefileGenerator3::ComputeTargetObjectDirectory( cmGeneratorTarget* gt) const { // Compute full path to object file directory for this target. - std::string dir; - dir += gt->LocalGenerator->GetCurrentBinaryDirectory(); - dir += "/"; - dir += gt->LocalGenerator->GetTargetDirectory(gt); - dir += "/"; + std::string dir = + cmStrCat(gt->LocalGenerator->GetCurrentBinaryDirectory(), '/', + gt->LocalGenerator->GetTargetDirectory(gt), '/'); gt->ObjectDirectory = dir; } @@ -147,8 +145,8 @@ void cmGlobalUnixMakefileGenerator3::Generate() pmi.second.WriteProgressVariables(total, current); } for (cmLocalGenerator* lg : this->LocalGenerators) { - std::string markFileName = lg->GetCurrentBinaryDirectory(); - markFileName += "/CMakeFiles/progress.marks"; + std::string markFileName = + cmStrCat(lg->GetCurrentBinaryDirectory(), "/CMakeFiles/progress.marks"); cmGeneratedFileStream markFile(markFileName); markFile << this->CountProgressMarksInAll(lg) << "\n"; } @@ -196,8 +194,8 @@ void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2() // because the check-build-system step compares the makefile time to // see if the build system must be regenerated. std::string makefileName = - this->GetCMakeInstance()->GetHomeOutputDirectory(); - makefileName += "/CMakeFiles/Makefile2"; + cmStrCat(this->GetCMakeInstance()->GetHomeOutputDirectory(), + "/CMakeFiles/Makefile2"); cmGeneratedFileStream makefileStream(makefileName, false, this->GetMakefileEncoding()); if (!makefileStream) { @@ -255,16 +253,15 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile() // because the check-build-system step compares the makefile time to // see if the build system must be regenerated. std::string cmakefileName = - this->GetCMakeInstance()->GetHomeOutputDirectory(); - cmakefileName += "/CMakeFiles/Makefile.cmake"; + cmStrCat(this->GetCMakeInstance()->GetHomeOutputDirectory(), + "/CMakeFiles/Makefile.cmake"); cmGeneratedFileStream cmakefileStream(cmakefileName); if (!cmakefileStream) { return; } std::string makefileName = - this->GetCMakeInstance()->GetHomeOutputDirectory(); - makefileName += "/Makefile"; + cmStrCat(this->GetCMakeInstance()->GetHomeOutputDirectory(), "/Makefile"); // get a local generator for some useful methods cmLocalUnixMakefileGenerator3* lg = @@ -316,8 +313,9 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile() cmakefileStream << " )\n\n"; // Build the path to the cache check file. - std::string check = this->GetCMakeInstance()->GetHomeOutputDirectory(); - check += "/CMakeFiles/cmake.check_cache"; + std::string check = + cmStrCat(this->GetCMakeInstance()->GetHomeOutputDirectory(), + "/CMakeFiles/cmake.check_cache"); // Set the corresponding makefile in the cmake file. cmakefileStream << "# The corresponding makefile is:\n" @@ -347,8 +345,8 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile() std::string tmpStr; for (cmLocalGenerator* localGen : this->LocalGenerators) { lg = static_cast<cmLocalUnixMakefileGenerator3*>(localGen); - tmpStr = lg->GetCurrentBinaryDirectory(); - tmpStr += "/CMakeFiles/CMakeDirectoryInformation.cmake"; + tmpStr = cmStrCat(lg->GetCurrentBinaryDirectory(), + "/CMakeFiles/CMakeDirectoryInformation.cmake"); cmakefileStream << " \"" << lg->MaybeConvertToRelativePath(binDir, tmpStr) << "\"\n"; @@ -380,8 +378,8 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefileLanguageRules( (tgt->GetType() == cmStateEnums::OBJECT_LIBRARY) || (tgt->GetType() == cmStateEnums::UTILITY)) { cmGeneratorTarget* gt = tgt; - std::string tname = lg->GetRelativeTargetDirectory(gt); - tname += "/DependInfo.cmake"; + std::string tname = + cmStrCat(lg->GetRelativeTargetDirectory(gt), "/DependInfo.cmake"); cmSystemTools::ConvertToUnixSlashes(tname); cmakefileStream << " \"" << tname << "\"\n"; } @@ -396,9 +394,8 @@ void cmGlobalUnixMakefileGenerator3::WriteDirectoryRule2( std::vector<std::string> const& commands) { // Get the relative path to the subdirectory from the top. - std::string makeTarget = lg->GetCurrentBinaryDirectory(); - makeTarget += '/'; - makeTarget += pass; + std::string makeTarget = + cmStrCat(lg->GetCurrentBinaryDirectory(), '/', pass); // The directory-level rule should depend on the target-level rules // for all targets in the directory. @@ -415,9 +412,8 @@ void cmGlobalUnixMakefileGenerator3::WriteDirectoryRule2( if ((!check_all || !gtarget->GetPropertyAsBool("EXCLUDE_FROM_ALL")) && (!check_relink || gtarget->NeedRelinkBeforeInstall(lg->GetConfigName()))) { - std::string tname = lg->GetRelativeTargetDirectory(gtarget); - tname += "/"; - tname += pass; + std::string tname = + cmStrCat(lg->GetRelativeTargetDirectory(gtarget), '/', pass); depends.push_back(std::move(tname)); } } @@ -426,9 +422,8 @@ void cmGlobalUnixMakefileGenerator3::WriteDirectoryRule2( // The directory-level rule should depend on the directory-level // rules of the subdirectories. for (cmStateSnapshot const& c : lg->GetStateSnapshot().GetChildren()) { - std::string subdir = c.GetDirectory().GetCurrentBinary(); - subdir += '/'; - subdir += pass; + std::string subdir = + cmStrCat(c.GetDirectory().GetCurrentBinary(), '/', pass); depends.push_back(std::move(subdir)); } @@ -441,13 +436,9 @@ void cmGlobalUnixMakefileGenerator3::WriteDirectoryRule2( // Write the rule. std::string doc; if (lg->IsRootMakefile()) { - doc = "The main recursive \""; - doc += pass; - doc += "\" target."; + doc = cmStrCat("The main recursive \"", pass, "\" target."); } else { - doc = "Recursive \""; - doc += pass; - doc += "\" directory target."; + doc = cmStrCat("Recursive \"", pass, "\" directory target."); } lg->WriteMakeRule(ruleFileStream, doc.c_str(), makeTarget, depends, commands, true); @@ -578,8 +569,7 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules( // Write the rule. commands.clear(); - std::string tmp = "CMakeFiles/"; - tmp += "Makefile2"; + std::string tmp = "CMakeFiles/Makefile2"; commands.push_back(lg->GetRecursiveMakeCall(tmp, name)); depends.clear(); if (regenerate) { @@ -591,14 +581,11 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules( // Add a fast rule to build the target std::string localName = lg->GetRelativeTargetDirectory(gtarget); std::string makefileName; - makefileName = localName; - makefileName += "/build.make"; + makefileName = cmStrCat(localName, "/build.make"); depends.clear(); commands.clear(); - std::string makeTargetName = localName; - makeTargetName += "/build"; - localName = name; - localName += "/fast"; + std::string makeTargetName = cmStrCat(localName, "/build"); + localName = cmStrCat(name, "/fast"); commands.push_back( lg->GetRecursiveMakeCall(makefileName, makeTargetName)); lg->WriteMakeRule(ruleFileStream, "fast build rule for target.", @@ -607,10 +594,9 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules( // Add a local name for the rule to relink the target before // installation. if (gtarget->NeedRelinkBeforeInstall(lg->GetConfigName())) { - makeTargetName = lg->GetRelativeTargetDirectory(gtarget); - makeTargetName += "/preinstall"; - localName = name; - localName += "/preinstall"; + makeTargetName = + cmStrCat(lg->GetRelativeTargetDirectory(gtarget), "/preinstall"); + localName = cmStrCat(name, "/preinstall"); depends.clear(); commands.clear(); commands.push_back( @@ -654,20 +640,17 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2( std::string makefileName; // Add a rule to build the target by name. localName = lg->GetRelativeTargetDirectory(gtarget); - makefileName = localName; - makefileName += "/build.make"; + makefileName = cmStrCat(localName, "/build.make"); lg->WriteDivider(ruleFileStream); ruleFileStream << "# Target rules for target " << localName << "\n\n"; commands.clear(); - makeTargetName = localName; - makeTargetName += "/depend"; + makeTargetName = cmStrCat(localName, "/depend"); commands.push_back( lg->GetRecursiveMakeCall(makefileName, makeTargetName)); - makeTargetName = localName; - makeTargetName += "/build"; + makeTargetName = cmStrCat(localName, "/build"); commands.push_back( lg->GetRecursiveMakeCall(makefileName, makeTargetName)); @@ -676,8 +659,7 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2( depends.clear(); cmLocalUnixMakefileGenerator3::EchoProgress progress; - progress.Dir = lg->GetBinaryDirectory(); - progress.Dir += "/CMakeFiles"; + progress.Dir = cmStrCat(lg->GetBinaryDirectory(), "/CMakeFiles"); { std::ostringstream progressArg; const char* sep = ""; @@ -720,8 +702,7 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2( progCmd << " " << this->CountProgressMarksInTarget(gtarget, emitted); commands.push_back(progCmd.str()); } - std::string tmp = "CMakeFiles/"; - tmp += "Makefile2"; + std::string tmp = "CMakeFiles/Makefile2"; commands.push_back(lg->GetRecursiveMakeCall(tmp, localName)); { std::ostringstream progCmd; @@ -736,8 +717,7 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2( if (regenerate) { depends.emplace_back("cmake_check_build_system"); } - localName = lg->GetRelativeTargetDirectory(gtarget); - localName += "/rule"; + localName = cmStrCat(lg->GetRelativeTargetDirectory(gtarget), "/rule"); lg->WriteMakeRule(ruleFileStream, "Build rule for subdir invocation for target.", localName, depends, commands, true); @@ -751,8 +731,8 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2( // Add rules to prepare the target for installation. if (gtarget->NeedRelinkBeforeInstall(lg->GetConfigName())) { - localName = lg->GetRelativeTargetDirectory(gtarget); - localName += "/preinstall"; + localName = + cmStrCat(lg->GetRelativeTargetDirectory(gtarget), "/preinstall"); depends.clear(); commands.clear(); commands.push_back(lg->GetRecursiveMakeCall(makefileName, localName)); @@ -771,8 +751,7 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2( // add the clean rule localName = lg->GetRelativeTargetDirectory(gtarget); - makeTargetName = localName; - makeTargetName += "/clean"; + makeTargetName = cmStrCat(localName, "/clean"); depends.clear(); commands.clear(); commands.push_back( @@ -891,9 +870,9 @@ void cmGlobalUnixMakefileGenerator3::AppendGlobalTargetDepends( } cmLocalUnixMakefileGenerator3* lg3 = static_cast<cmLocalUnixMakefileGenerator3*>(dep->GetLocalGenerator()); - std::string tgtName = - lg3->GetRelativeTargetDirectory(const_cast<cmGeneratorTarget*>(dep)); - tgtName += "/all"; + std::string tgtName = cmStrCat( + lg3->GetRelativeTargetDirectory(const_cast<cmGeneratorTarget*>(dep)), + "/all"); depends.push_back(tgtName); } } @@ -936,8 +915,7 @@ void cmGlobalUnixMakefileGenerator3::WriteHelpRule( (type == cmStateEnums::UTILITY)) { std::string const& name = target->GetName(); if (emittedTargets.insert(name).second) { - path = "... "; - path += name; + path = cmStrCat("... ", name); lg->AppendEcho(commands, path); } } @@ -945,8 +923,7 @@ void cmGlobalUnixMakefileGenerator3::WriteHelpRule( } } for (std::string const& o : lg->GetLocalHelp()) { - path = "... "; - path += o; + path = cmStrCat("... ", o); lg->AppendEcho(commands, path); } lg->WriteMakeRule(ruleFileStream, "Help Target", "help", no_depends, diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx index 02d25fb..48b17c0 100644 --- a/Source/cmGlobalVisualStudio10Generator.cxx +++ b/Source/cmGlobalVisualStudio10Generator.cxx @@ -678,9 +678,9 @@ std::string cmGlobalVisualStudio10Generator::FindMSBuildCommand() std::string mskey; // Search in standard location. - mskey = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MSBuild\\ToolsVersions\\"; - mskey += this->GetToolsVersion(); - mskey += ";MSBuildToolsPath"; + mskey = cmStrCat( + "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MSBuild\\ToolsVersions\\", + this->GetToolsVersion(), ";MSBuildToolsPath"); if (cmSystemTools::ReadRegistryValue(mskey.c_str(), msbuild, cmSystemTools::KeyWOW64_32)) { cmSystemTools::ConvertToUnixSlashes(msbuild); @@ -720,8 +720,8 @@ bool cmGlobalVisualStudio10Generator::FindVCTargetsPath(cmMakefile* mf) // In a try-compile we are given the outer CMakeFiles directory. wd = this->ConfiguredFilesPath; } else { - wd = this->GetCMakeInstance()->GetHomeOutputDirectory(); - wd += "/CMakeFiles"; + wd = cmStrCat(this->GetCMakeInstance()->GetHomeOutputDirectory(), + "/CMakeFiles"); } wd += "/"; wd += cmVersion::GetCMakeVersion(); @@ -905,8 +905,7 @@ cmGlobalVisualStudio10Generator::GenerateBuildCommand( { std::string slnFile; if (!projectDir.empty()) { - slnFile = projectDir; - slnFile += "/"; + slnFile = cmStrCat(projectDir, '/'); } slnFile += projectName; slnFile += ".sln"; @@ -953,8 +952,7 @@ cmGlobalVisualStudio10Generator::GenerateBuildCommand( makeCommand.Add(std::string(projectName) + ".sln"); makeCommand.Add("/t:Clean"); } else { - std::string targetProject(tname); - targetProject += ".vcxproj"; + std::string targetProject = cmStrCat(tname, ".vcxproj"); if (targetProject.find('/') == std::string::npos) { // it might be in a subdir if (cmSlnProjectEntry const* proj = slnData.GetProjectByName(tname)) { @@ -1037,13 +1035,12 @@ std::string cmGlobalVisualStudio10Generator::GenerateRuleFile( { // The VS 10 generator needs to create the .rule files on disk. // Hide them away under the CMakeFiles directory. - std::string ruleDir = this->GetCMakeInstance()->GetHomeOutputDirectory(); - ruleDir += "/CMakeFiles/"; - ruleDir += cmSystemTools::ComputeStringMD5( - cmSystemTools::GetFilenamePath(output).c_str()); - std::string ruleFile = ruleDir + "/"; - ruleFile += cmSystemTools::GetFilenameName(output); - ruleFile += ".rule"; + std::string ruleDir = cmStrCat( + this->GetCMakeInstance()->GetHomeOutputDirectory(), "/CMakeFiles/", + cmSystemTools::ComputeStringMD5( + cmSystemTools::GetFilenamePath(output).c_str())); + std::string ruleFile = + cmStrCat(ruleDir, '/', cmSystemTools::GetFilenameName(output), ".rule"); return ruleFile; } diff --git a/Source/cmGlobalVisualStudio71Generator.cxx b/Source/cmGlobalVisualStudio71Generator.cxx index e0d86ca..e8e9ece 100644 --- a/Source/cmGlobalVisualStudio71Generator.cxx +++ b/Source/cmGlobalVisualStudio71Generator.cxx @@ -145,10 +145,8 @@ void cmGlobalVisualStudio71Generator::WriteProjectDepends( for (std::string const& name : depends) { std::string guid = this->GetGUID(name); if (guid.empty()) { - std::string m = "Target: "; - m += target->GetName(); - m += " depends on unknown target: "; - m += name; + std::string m = cmStrCat("Target: ", target->GetName(), + " depends on unknown target: ", name); cmSystemTools::Error(m); } fout << "\t\t{" << guid << "} = {" << guid << "}\n"; diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx index 7136746..26ceedd 100644 --- a/Source/cmGlobalVisualStudio7Generator.cxx +++ b/Source/cmGlobalVisualStudio7Generator.cxx @@ -66,8 +66,9 @@ const std::string& cmGlobalVisualStudio7Generator::GetIntelProjectVersion() // Compute the version of the Intel plugin to the VS IDE. // If the key does not exist then use a default guess. std::string intelVersion; - std::string vskey = this->GetRegistryBase(); - vskey += "\\Packages\\" CM_INTEL_PLUGIN_GUID ";ProductVersion"; + std::string vskey = + cmStrCat(this->GetRegistryBase(), + "\\Packages\\" CM_INTEL_PLUGIN_GUID ";ProductVersion"); cmSystemTools::ReadRegistryValue(vskey, intelVersion, cmSystemTools::KeyWOW64_32); unsigned int intelVersionNumber = ~0u; @@ -153,8 +154,9 @@ std::string cmGlobalVisualStudio7Generator::FindDevEnvCommand() } // Search where VS15Preview places it. - vskey = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\SxS\\VS7;"; - vskey += this->GetIDEVersion(); + vskey = cmStrCat( + "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\SxS\\VS7;", + this->GetIDEVersion()); if (cmSystemTools::ReadRegistryValue(vskey.c_str(), vscmd, cmSystemTools::KeyWOW64_32)) { cmSystemTools::ConvertToUnixSlashes(vscmd); @@ -294,10 +296,8 @@ void cmGlobalVisualStudio7Generator::OutputSLNFile( return; } this->CurrentProject = root->GetProjectName(); - std::string fname = root->GetCurrentBinaryDirectory(); - fname += "/"; - fname += root->GetProjectName(); - fname += ".sln"; + std::string fname = cmStrCat(root->GetCurrentBinaryDirectory(), '/', + root->GetProjectName(), ".sln"); cmGeneratedFileStream fout(fname.c_str()); fout.SetCopyIfDifferent(true); if (!fout) { @@ -511,8 +511,8 @@ void cmGlobalVisualStudio7Generator::WriteSLNGlobalSections( extensibilityAddInsOverridden = true; } fout << "\tGlobalSection(" << name << ") = " << sectionType << "\n"; - std::vector<std::string> keyValuePairs; - cmExpandList(root->GetMakefile()->GetProperty(it), keyValuePairs); + std::vector<std::string> keyValuePairs = + cmExpandedList(root->GetMakefile()->GetProperty(it)); for (std::string const& itPair : keyValuePairs) { const std::string::size_type posEqual = itPair.find('='); if (posEqual != std::string::npos) { @@ -554,12 +554,10 @@ std::string cmGlobalVisualStudio7Generator::WriteUtilityDepend( { std::vector<std::string> configs; target->Target->GetMakefile()->GetConfigurations(configs); - std::string pname = target->GetName(); - pname += "_UTILITY"; - std::string fname = target->GetLocalGenerator()->GetCurrentBinaryDirectory(); - fname += "/"; - fname += pname; - fname += ".vcproj"; + std::string pname = cmStrCat(target->GetName(), "_UTILITY"); + std::string fname = + cmStrCat(target->GetLocalGenerator()->GetCurrentBinaryDirectory(), '/', + pname, ".vcproj"); cmGeneratedFileStream fout(fname.c_str()); fout.SetCopyIfDifferent(true); std::string guid = this->GetGUID(pname.c_str()); @@ -616,9 +614,8 @@ std::string cmGlobalVisualStudio7Generator::GetGUID(std::string const& name) return std::string(storedGUID); } // Compute a GUID that is deterministic but unique to the build tree. - std::string input = this->CMakeInstance->GetState()->GetBinaryDirectory(); - input += "|"; - input += name; + std::string input = + cmStrCat(this->CMakeInstance->GetState()->GetBinaryDirectory(), '|', name); cmUuid uuidGenerator; diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx index 20deafe..b0c065f 100644 --- a/Source/cmGlobalVisualStudio8Generator.cxx +++ b/Source/cmGlobalVisualStudio8Generator.cxx @@ -26,9 +26,9 @@ std::string cmGlobalVisualStudio8Generator::FindDevEnvCommand() { // First look for VCExpress. std::string vsxcmd; - std::string vsxkey = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\"; - vsxkey += this->GetIDEVersion(); - vsxkey += ";InstallDir"; + std::string vsxkey = + cmStrCat("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\", + this->GetIDEVersion(), ";InstallDir"); if (cmSystemTools::ReadRegistryValue(vsxkey.c_str(), vsxcmd, cmSystemTools::KeyWOW64_32)) { cmSystemTools::ConvertToUnixSlashes(vsxcmd); @@ -116,20 +116,17 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget() // Create a list of all stamp files for this project. std::vector<std::string> stamps; - std::string stampList = "CMakeFiles/"; - stampList += cmGlobalVisualStudio8Generator::GetGenerateStampList(); + std::string stampList = cmStrCat( + "CMakeFiles/", cmGlobalVisualStudio8Generator::GetGenerateStampList()); { std::string stampListFile = - generators[0]->GetMakefile()->GetCurrentBinaryDirectory(); - stampListFile += "/"; - stampListFile += stampList; + cmStrCat(generators[0]->GetMakefile()->GetCurrentBinaryDirectory(), '/', + stampList); std::string stampFile; cmGeneratedFileStream fout(stampListFile.c_str()); for (cmLocalGenerator const* gi : generators) { - stampFile = gi->GetMakefile()->GetCurrentBinaryDirectory(); - stampFile += "/"; - stampFile += "CMakeFiles/"; - stampFile += "generate.stamp"; + stampFile = cmStrCat(gi->GetMakefile()->GetCurrentBinaryDirectory(), + "/CMakeFiles/generate.stamp"); fout << stampFile << "\n"; stamps.push_back(stampFile); } @@ -176,11 +173,9 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget() // Create a rule to re-run CMake. cmCustomCommandLine commandLine; commandLine.push_back(cmSystemTools::GetCMakeCommand()); - std::string argS = "-S"; - argS += lg->GetSourceDirectory(); + std::string argS = cmStrCat("-S", lg->GetSourceDirectory()); commandLine.push_back(argS); - std::string argB = "-B"; - argB += lg->GetBinaryDirectory(); + std::string argB = cmStrCat("-B", lg->GetBinaryDirectory()); commandLine.push_back(argB); commandLine.push_back("--check-stamp-list"); commandLine.push_back(stampList.c_str()); diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx index 5c057c6..6e0b804 100644 --- a/Source/cmGlobalVisualStudioGenerator.cxx +++ b/Source/cmGlobalVisualStudioGenerator.cxx @@ -104,6 +104,9 @@ const char* cmGlobalVisualStudioGenerator::GetIDEVersion() const void cmGlobalVisualStudioGenerator::WriteSLNHeader(std::ostream& fout) { + char utf8bom[] = { char(0xEF), char(0xBB), char(0xBF) }; + fout.write(utf8bom, 3); + switch (this->Version) { case cmGlobalVisualStudioGenerator::VS9: fout << "Microsoft Visual Studio Solution File, Format Version 10.00\n"; @@ -224,8 +227,8 @@ void cmGlobalVisualStudioGenerator::AddExtraIDETargets() void cmGlobalVisualStudioGenerator::ComputeTargetObjectDirectory( cmGeneratorTarget* gt) const { - std::string dir = gt->LocalGenerator->GetCurrentBinaryDirectory(); - dir += "/"; + std::string dir = + cmStrCat(gt->LocalGenerator->GetCurrentBinaryDirectory(), '/'); std::string tgtDir = gt->LocalGenerator->GetTargetDirectory(gt); if (!tgtDir.empty()) { dir += tgtDir; @@ -258,8 +261,8 @@ void cmGlobalVisualStudioGenerator::ConfigureCMakeVisualStudioMacros() std::string dir = this->GetUserMacrosDirectory(); if (!dir.empty()) { - std::string src = cmSystemTools::GetCMakeRoot(); - src += "/Templates/" CMAKE_VSMACROS_FILENAME; + std::string src = cmStrCat(cmSystemTools::GetCMakeRoot(), + "/Templates/" CMAKE_VSMACROS_FILENAME); std::string dst = dir + "/CMakeMacros/" CMAKE_VSMACROS_FILENAME; @@ -306,10 +309,9 @@ void cmGlobalVisualStudioGenerator::CallVisualStudioMacro( if (vsSolutionFile) { topLevelSlnName = vsSolutionFile; } else { - topLevelSlnName = mf->GetCurrentBinaryDirectory(); - topLevelSlnName += "/"; - topLevelSlnName += this->LocalGenerators[0]->GetProjectName(); - topLevelSlnName += ".sln"; + topLevelSlnName = + cmStrCat(mf->GetCurrentBinaryDirectory(), '/', + this->LocalGenerators[0]->GetProjectName(), ".sln"); } if (m == MacroReload) { @@ -553,9 +555,9 @@ bool IsVisualStudioMacrosFileRegistered(const std::string& macrosFile, if (ERROR_SUCCESS == result) { // Iterate the subkeys and look for the values of interest in each subkey: wchar_t subkeyname[256]; - DWORD cch_subkeyname = sizeof(subkeyname) * sizeof(subkeyname[0]); + DWORD cch_subkeyname = cm::size(subkeyname); wchar_t keyclass[256]; - DWORD cch_keyclass = sizeof(keyclass) * sizeof(keyclass[0]); + DWORD cch_keyclass = cm::size(keyclass); FILETIME lastWriteTime; lastWriteTime.dwHighDateTime = 0; lastWriteTime.dwLowDateTime = 0; @@ -569,8 +571,8 @@ bool IsVisualStudioMacrosFileRegistered(const std::string& macrosFile, if (ERROR_SUCCESS == result) { DWORD valueType = REG_SZ; wchar_t data1[256]; - DWORD cch_data1 = sizeof(data1) * sizeof(data1[0]); - RegQueryValueExW(hsubkey, L"Path", 0, &valueType, (LPBYTE)&data1[0], + DWORD cch_data1 = sizeof(data1); + RegQueryValueExW(hsubkey, L"Path", 0, &valueType, (LPBYTE)data1, &cch_data1); DWORD data2 = 0; @@ -618,8 +620,8 @@ bool IsVisualStudioMacrosFileRegistered(const std::string& macrosFile, } ++index; - cch_subkeyname = sizeof(subkeyname) * sizeof(subkeyname[0]); - cch_keyclass = sizeof(keyclass) * sizeof(keyclass[0]); + cch_subkeyname = cm::size(subkeyname); + cch_keyclass = cm::size(keyclass); lastWriteTime.dwHighDateTime = 0; lastWriteTime.dwLowDateTime = 0; } @@ -634,9 +636,7 @@ bool IsVisualStudioMacrosFileRegistered(const std::string& macrosFile, // follow the expected naming scheme. Expected naming scheme is that // the subkeys of OtherProjects7 is 0 to n-1, so it's ok to use "n" // as the name of the next subkey. - std::ostringstream ossNext; - ossNext << index; - nextAvailableSubKeyName = ossNext.str(); + nextAvailableSubKeyName = std::to_string(index); keyname = regKeyBase + "\\RecordingProject7"; hkey = NULL; @@ -646,9 +646,8 @@ bool IsVisualStudioMacrosFileRegistered(const std::string& macrosFile, if (ERROR_SUCCESS == result) { DWORD valueType = REG_SZ; wchar_t data1[256]; - DWORD cch_data1 = sizeof(data1) * sizeof(data1[0]); - RegQueryValueExW(hkey, L"Path", 0, &valueType, (LPBYTE)&data1[0], - &cch_data1); + DWORD cch_data1 = sizeof(data1); + RegQueryValueExW(hkey, L"Path", 0, &valueType, (LPBYTE)data1, &cch_data1); DWORD data2 = 0; DWORD cch_data2 = sizeof(data2); diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h index cbab329..e4cd73f 100644 --- a/Source/cmGlobalVisualStudioGenerator.h +++ b/Source/cmGlobalVisualStudioGenerator.h @@ -110,6 +110,13 @@ public: bool IsIncludeExternalMSProjectSupported() const override { return true; } + /** Get encoding used by generator for generated source files + */ + codecvt::Encoding GetMakefileEncoding() const override + { + return codecvt::ANSI; + } + class TargetSet : public std::set<cmGeneratorTarget const*> { }; diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 1882f89..427ab44 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -349,13 +349,10 @@ cmGlobalXCodeGenerator::GenerateBuildCommand( if (!projectName.empty()) { makeCommand.Add("-project"); - std::string projectArg = projectName; - projectArg += ".xcode"; - projectArg += "proj"; + std::string projectArg = cmStrCat(projectName, ".xcodeproj"); makeCommand.Add(projectArg); } - if (std::find(targetNames.begin(), targetNames.end(), "clean") != - targetNames.end()) { + if (cmContains(targetNames, "clean")) { makeCommand.Add("clean"); makeCommand.Add("-target", "ALL_BUILD"); } else { @@ -476,8 +473,8 @@ void cmGlobalXCodeGenerator::SetGenerationRoot(cmLocalGenerator* root) this->CurrentLocalGenerator->GetCurrentBinaryDirectory(), this->ProjectOutputDirectoryComponents); - this->CurrentXCodeHackMakefile = root->GetCurrentBinaryDirectory(); - this->CurrentXCodeHackMakefile += "/CMakeScripts"; + this->CurrentXCodeHackMakefile = + cmStrCat(root->GetCurrentBinaryDirectory(), "/CMakeScripts"); cmSystemTools::MakeDirectory(this->CurrentXCodeHackMakefile); this->CurrentXCodeHackMakefile += "/XCODE_DEPEND_HELPER.make"; } @@ -487,8 +484,7 @@ std::string cmGlobalXCodeGenerator::PostBuildMakeTarget( { std::string target = tName; std::replace(target.begin(), target.end(), ' ', '_'); - std::string out = "PostBuild." + target; - out += "." + configName; + std::string out = cmStrCat("PostBuild.", target, '.', configName); return out; } @@ -596,8 +592,8 @@ void cmGlobalXCodeGenerator::CreateReRunCMakeFile( lfiles.emplace_back(cm->GetGlobVerifyStamp()); } - this->CurrentReRunCMakeMakefile = root->GetCurrentBinaryDirectory(); - this->CurrentReRunCMakeMakefile += "/CMakeScripts"; + this->CurrentReRunCMakeMakefile = + cmStrCat(root->GetCurrentBinaryDirectory(), "/CMakeScripts"); cmSystemTools::MakeDirectory(this->CurrentReRunCMakeMakefile); this->CurrentReRunCMakeMakefile += "/ReRunCMake.make"; cmGeneratedFileStream makefileStream(this->CurrentReRunCMakeMakefile); @@ -615,10 +611,8 @@ void cmGlobalXCodeGenerator::CreateReRunCMakeFile( } makefileStream << "\n"; - std::string checkCache = root->GetBinaryDirectory(); - checkCache += "/"; - checkCache += "CMakeFiles/"; - checkCache += "cmake.check_cache"; + std::string checkCache = + cmStrCat(root->GetBinaryDirectory(), "/CMakeFiles/cmake.check_cache"); if (cm->DoWriteGlobVerifyTarget()) { makefileStream << ".NOTPARALLEL:\n\n"; @@ -881,8 +875,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFile( const char* extraFileAttributes = sf->GetProperty("XCODE_FILE_ATTRIBUTES"); if (extraFileAttributes) { // Expand the list of attributes. - std::vector<std::string> attributes; - cmExpandList(extraFileAttributes, attributes); + std::vector<std::string> attributes = cmExpandedList(extraFileAttributes); // Store the attributes. for (const auto& attribute : attributes) { @@ -900,11 +893,10 @@ void cmGlobalXCodeGenerator::AddXCodeProjBuildRule( cmGeneratorTarget* target, std::vector<cmSourceFile*>& sources) const { std::string listfile = - target->GetLocalGenerator()->GetCurrentSourceDirectory(); - listfile += "/CMakeLists.txt"; + cmStrCat(target->GetLocalGenerator()->GetCurrentSourceDirectory(), + "/CMakeLists.txt"); cmSourceFile* srcCMakeLists = target->Makefile->GetOrCreateSource(listfile); - if (std::find(sources.begin(), sources.end(), srcCMakeLists) == - sources.end()) { + if (!cmContains(sources, srcCMakeLists)) { sources.push_back(srcCMakeLists); } } @@ -1398,12 +1390,9 @@ void cmGlobalXCodeGenerator::ForceLinkerLanguage(cmGeneratorTarget* gtgt) // linker language. This should convince Xcode to choose the proper // language. cmMakefile* mf = gtgt->Target->GetMakefile(); - std::string fname = gtgt->GetLocalGenerator()->GetCurrentBinaryDirectory(); - fname += "/CMakeFiles/"; - fname += gtgt->GetName(); - fname += "-CMakeForceLinker"; - fname += "."; - fname += cmSystemTools::LowerCase(llang); + std::string fname = cmStrCat( + gtgt->GetLocalGenerator()->GetCurrentBinaryDirectory(), "/CMakeFiles/", + gtgt->GetName(), "-CMakeForceLinker.", cmSystemTools::LowerCase(llang)); { cmGeneratedFileStream fout(fname); fout << "\n"; @@ -1416,10 +1405,8 @@ void cmGlobalXCodeGenerator::ForceLinkerLanguage(cmGeneratorTarget* gtgt) bool cmGlobalXCodeGenerator::IsHeaderFile(cmSourceFile* sf) { - const std::vector<std::string>& hdrExts = - this->CMakeInstance->GetHeaderExtensions(); - return (std::find(hdrExts.begin(), hdrExts.end(), sf->GetExtension()) != - hdrExts.end()); + return cmContains(this->CMakeInstance->GetHeaderExtensions(), + sf->GetExtension()); } cmXCodeObject* cmGlobalXCodeGenerator::CreateBuildPhase( @@ -1460,15 +1447,11 @@ void cmGlobalXCodeGenerator::CreateCustomCommands( cmd[0].push_back(cmSystemTools::GetCMakeCommand()); cmd[0].push_back("-E"); cmd[0].push_back("cmake_symlink_library"); - std::string str_file = "$<TARGET_FILE:"; - str_file += gtgt->GetName(); - str_file += ">"; - std::string str_so_file = "$<TARGET_SONAME_FILE:"; - str_so_file += gtgt->GetName(); - str_so_file += ">"; - std::string str_link_file = "$<TARGET_LINKER_FILE:"; - str_link_file += gtgt->GetName(); - str_link_file += ">"; + std::string str_file = cmStrCat("$<TARGET_FILE:", gtgt->GetName(), '>'); + std::string str_so_file = + cmStrCat("$<TARGET_SONAME_FILE:", gtgt->GetName(), '>'); + std::string str_link_file = + cmStrCat("$<TARGET_LINKER_FILE:", gtgt->GetName(), '>'); cmd[0].push_back(str_file); cmd[0].push_back(str_so_file); cmd[0].push_back(str_link_file); @@ -1635,15 +1618,11 @@ void cmGlobalXCodeGenerator::AddCommandsToBuildPhase( cmXCodeObject* buildphase, cmGeneratorTarget* target, std::vector<cmCustomCommand> const& commands, const char* name) { - std::string dir = this->CurrentLocalGenerator->GetCurrentBinaryDirectory(); - dir += "/CMakeScripts"; + std::string dir = cmStrCat( + this->CurrentLocalGenerator->GetCurrentBinaryDirectory(), "/CMakeScripts"); cmSystemTools::MakeDirectory(dir); - std::string makefile = dir; - makefile += "/"; - makefile += target->GetName(); - makefile += "_"; - makefile += name; - makefile += ".make"; + std::string makefile = + cmStrCat(dir, '/', target->GetName(), '_', name, ".make"); for (const auto& currentConfig : this->CurrentConfigurationTypes) { this->CreateCustomRulesMakefile(makefile.c_str(), target, commands, @@ -1652,12 +1631,10 @@ void cmGlobalXCodeGenerator::AddCommandsToBuildPhase( std::string cdir = this->CurrentLocalGenerator->GetCurrentBinaryDirectory(); cdir = this->ConvertToRelativeForMake(cdir); - std::string makecmd = "make -C "; - makecmd += cdir; - makecmd += " -f "; - makecmd += this->ConvertToRelativeForMake((makefile + "$CONFIGURATION")); - makecmd += " OBJDIR=$(basename \"$OBJECT_FILE_DIR_normal\")"; - makecmd += " all"; + std::string makecmd = + cmStrCat("make -C ", cdir, " -f ", + this->ConvertToRelativeForMake((makefile + "$CONFIGURATION")), + " OBJDIR=$(basename \"$OBJECT_FILE_DIR_normal\") all"); buildphase->AddAttribute("shellScript", this->CreateString(makecmd)); buildphase->AddAttribute("showEnvVarsInLog", this->CreateString("0")); } @@ -1666,8 +1643,7 @@ void cmGlobalXCodeGenerator::CreateCustomRulesMakefile( const char* makefileBasename, cmGeneratorTarget* target, std::vector<cmCustomCommand> const& commands, const std::string& configName) { - std::string makefileName = makefileBasename; - makefileName += configName; + std::string makefileName = cmStrCat(makefileBasename, configName); cmGeneratedFileStream makefileStream(makefileName); if (!makefileStream) { return; @@ -1730,9 +1706,10 @@ void cmGlobalXCodeGenerator::CreateCustomRulesMakefile( makefileStream << "\n"; if (const char* comment = ccg.GetComment()) { - std::string echo_cmd = "echo "; - echo_cmd += (this->CurrentLocalGenerator->EscapeForShell( - comment, ccg.GetCC().GetEscapeAllowMakeVars())); + std::string echo_cmd = + cmStrCat("echo ", + (this->CurrentLocalGenerator->EscapeForShell( + comment, ccg.GetCC().GetEscapeAllowMakeVars()))); makefileStream << "\t" << echo_cmd << "\n"; } @@ -1880,8 +1857,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt, targetLinkFlags); } if (!configName.empty()) { - std::string linkFlagsVar = "LINK_FLAGS_"; - linkFlagsVar += cmSystemTools::UpperCase(configName); + std::string linkFlagsVar = + cmStrCat("LINK_FLAGS_", cmSystemTools::UpperCase(configName)); if (const char* linkFlags = gtgt->GetProperty(linkFlagsVar)) { this->CurrentLocalGenerator->AppendFlags(extraLinkOptions, linkFlags); } @@ -2133,8 +2110,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt, for (auto& include : includes) { if (this->NameResolvesToFramework(include)) { - std::string frameworkDir = include; - frameworkDir += "/../"; + std::string frameworkDir = cmStrCat(include, "/../"); frameworkDir = cmSystemTools::CollapseFullPath(frameworkDir); if (emitted.insert(frameworkDir).second) { std::string incpath = this->XCodeEscapePath(frameworkDir); @@ -2398,6 +2374,16 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt, buildSettings->AddAttribute("DYLIB_COMPATIBILITY_VERSION", this->CreateString(vso.str())); } + + // Precompile Headers + std::string pchHeader = gtgt->GetPchHeader(configName, llang); + if (!pchHeader.empty()) { + buildSettings->AddAttribute("GCC_PREFIX_HEADER", + this->CreateString(pchHeader)); + buildSettings->AddAttribute("GCC_PRECOMPILE_PREFIX_HEADER", + this->CreateString("YES")); + } + // put this last so it can override existing settings // Convert "XCODE_ATTRIBUTE_*" properties directly. { @@ -2487,11 +2473,9 @@ std::string cmGlobalXCodeGenerator::AddConfigurations(cmXCodeObject* target, cmXCodeObject* buildConfigurations = this->CreateObject(cmXCodeObject::OBJECT_LIST); configlist->AddAttribute("buildConfigurations", buildConfigurations); - std::string comment = "Build configuration list for "; - comment += cmXCodeObject::PBXTypeNames[target->GetIsA()]; - comment += " \""; - comment += gtgt->GetName(); - comment += "\""; + std::string comment = cmStrCat("Build configuration list for ", + cmXCodeObject::PBXTypeNames[target->GetIsA()], + " \"", gtgt->GetName(), '"'); configlist->SetComment(comment); target->AddAttribute("buildConfigurationList", this->CreateObjectReference(configlist)); @@ -2619,9 +2603,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeTarget( } std::string fullName; if (gtgt->GetType() == cmStateEnums::OBJECT_LIBRARY) { - fullName = "lib"; - fullName += gtgt->GetName(); - fullName += ".a"; + fullName = cmStrCat("lib", gtgt->GetName(), ".a"); } else { fullName = gtgt->GetFullName(defConfig); } @@ -2658,8 +2640,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::FindXCodeTarget( std::string cmGlobalXCodeGenerator::GetOrCreateId(const std::string& name, const std::string& id) { - std::string guidStoreName = name; - guidStoreName += "_GUID_CMAKE"; + std::string guidStoreName = cmStrCat(name, "_GUID_CMAKE"); const char* storedGUID = this->CMakeInstance->GetCacheDefinition(guidStoreName); @@ -2714,9 +2695,7 @@ void cmGlobalXCodeGenerator::AppendOrAddBuildSetting(cmXCodeObject* settings, if (!attr) { settings->AddAttribute(attribute, this->CreateString(value)); } else { - std::string oldValue = attr->GetString(); - oldValue += " "; - oldValue += value; + std::string oldValue = cmStrCat(attr->GetString(), ' ', value); attr->SetString(oldValue); } } @@ -2860,6 +2839,8 @@ bool cmGlobalXCodeGenerator::CreateGroups( continue; } + generator->AddPchDependencies(gtgt, ""); + auto addSourceToGroup = [this, mf, gtgt, &sourceGroups](std::string const& source) { cmSourceGroup* sourceGroup = mf->FindSourceGroup(source, sourceGroups); @@ -2881,8 +2862,8 @@ bool cmGlobalXCodeGenerator::CreateGroups( // Add CMakeLists.txt file for user convenience. { std::string listfile = - gtgt->GetLocalGenerator()->GetCurrentSourceDirectory(); - listfile += "/CMakeLists.txt"; + cmStrCat(gtgt->GetLocalGenerator()->GetCurrentSourceDirectory(), + "/CMakeLists.txt"); cmSourceFile* sf = gtgt->Makefile->GetOrCreateSource(listfile); addSourceToGroup(sf->GetFullPath()); } @@ -2924,12 +2905,10 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateOrGetPBXGroup( std::string target; const std::string targetFolder = gtgt->GetEffectiveFolderName(); if (!targetFolder.empty()) { - target = targetFolder; - target += "/"; + target = cmStrCat(targetFolder, '/'); } target += gtgt->GetName(); - s = target + "/"; - s += sg->GetFullName(); + s = cmStrCat(target, '/', sg->GetFullName()); std::map<std::string, cmXCodeObject*>::iterator it = this->GroupNameMap.find(s); if (it != this->GroupNameMap.end()) { @@ -2973,8 +2952,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateOrGetPBXGroup( // It's a recursive folder structure, let's find the real parent group if (sg->GetFullName() != sg->GetName()) { - std::string curr_folder = target; - curr_folder += "/"; + std::string curr_folder = cmStrCat(target, '/'); for (auto const& folder : cmTokenize(sg->GetFullName(), "\\")) { curr_folder += folder; std::map<std::string, cmXCodeObject*>::iterator i_folder = @@ -3039,8 +3017,7 @@ bool cmGlobalXCodeGenerator::CreateXCodeObjects( this->RootObject = this->CreateObject(cmXCodeObject::PBXProject); this->RootObject->SetComment("Project object"); - std::string project_id = "PROJECT_"; - project_id += root->GetProjectName(); + std::string project_id = cmStrCat("PROJECT_", root->GetProjectName()); this->RootObject->SetId( this->GetOrCreateId(project_id, this->RootObject->GetId())); @@ -3091,10 +3068,8 @@ bool cmGlobalXCodeGenerator::CreateXCodeObjects( } configlist->AddAttribute("buildConfigurations", buildConfigurations); - std::string comment = "Build configuration list for PBXProject"; - comment += " \""; - comment += this->CurrentProject; - comment += "\""; + std::string comment = cmStrCat("Build configuration list for PBXProject \"", + this->CurrentProject, '"'); configlist->SetComment(comment); configlist->AddAttribute("defaultConfigurationIsVisible", this->CreateString("0")); @@ -3143,8 +3118,7 @@ bool cmGlobalXCodeGenerator::CreateXCodeObjects( this->CreateString(swiftVersion)); } - std::string symroot = root->GetCurrentBinaryDirectory(); - symroot += "/build"; + std::string symroot = cmStrCat(root->GetCurrentBinaryDirectory(), "/build"); buildSettings->AddAttribute("SYMROOT", this->CreateString(symroot)); for (auto& config : configs) { @@ -3201,15 +3175,9 @@ std::string cmGlobalXCodeGenerator::GetObjectsDirectory( const std::string& projName, const std::string& configName, const cmGeneratorTarget* t, const std::string& variant) const { - std::string dir = t->GetLocalGenerator()->GetCurrentBinaryDirectory(); - dir += "/"; - dir += projName; - dir += ".build/"; - dir += configName; - dir += "/"; - dir += t->GetName(); - dir += ".build/"; - dir += variant; + std::string dir = cmStrCat( + t->GetLocalGenerator()->GetCurrentBinaryDirectory(), '/', projName, + ".build/", configName, '/', t->GetName(), ".build/", variant); return dir; } @@ -3334,12 +3302,10 @@ void cmGlobalXCodeGenerator::CreateXCodeDependHackTarget( for (auto objLib : objlibs) { const std::string objLibName = objLib->GetName(); - std::string d = + std::string d = cmStrCat( this->GetObjectsDirectory(this->CurrentProject, configName, objLib, - OBJECT_LIBRARY_ARTIFACT_DIR); - d += "lib"; - d += objLibName; - d += ".a"; + OBJECT_LIBRARY_ARTIFACT_DIR), + "lib", objLibName, ".a"); std::string dependency = this->ConvertToRelativeForMake(d); makefileStream << "\\\n\t" << dependency; @@ -3356,10 +3322,8 @@ void cmGlobalXCodeGenerator::CreateXCodeDependHackTarget( std::string universal = this->GetObjectsDirectory( this->CurrentProject, configName, gt, "$(OBJDIR)/"); for (const auto& architecture : this->Architectures) { - std::string universalFile = universal; - universalFile += architecture; - universalFile += "/"; - universalFile += gt->GetFullName(configName); + std::string universalFile = cmStrCat(universal, architecture, '/', + gt->GetFullName(configName)); makefileStream << "\t/bin/rm -f " << this->ConvertToRelativeForMake(universalFile) << "\n"; @@ -3387,10 +3351,8 @@ void cmGlobalXCodeGenerator::OutputXCodeProject( if (!this->CreateXCodeObjects(root, generators)) { return; } - std::string xcodeDir = root->GetCurrentBinaryDirectory(); - xcodeDir += "/"; - xcodeDir += root->GetProjectName(); - xcodeDir += ".xcodeproj"; + std::string xcodeDir = cmStrCat(root->GetCurrentBinaryDirectory(), '/', + root->GetProjectName(), ".xcodeproj"); cmSystemTools::MakeDirectory(xcodeDir); std::string xcodeProjFile = xcodeDir + "/project.pbxproj"; cmGeneratedFileStream fout(xcodeProjFile); @@ -3464,12 +3426,12 @@ bool cmGlobalXCodeGenerator::OutputXCodeSharedSchemes( void cmGlobalXCodeGenerator::OutputXCodeWorkspaceSettings( const std::string& xcProjDir, bool hasGeneratedSchemes) { - std::string xcodeSharedDataDir = xcProjDir; - xcodeSharedDataDir += "/project.xcworkspace/xcshareddata"; + std::string xcodeSharedDataDir = + cmStrCat(xcProjDir, "/project.xcworkspace/xcshareddata"); cmSystemTools::MakeDirectory(xcodeSharedDataDir); - std::string workspaceSettingsFile = xcodeSharedDataDir; - workspaceSettingsFile += "/WorkspaceSettings.xcsettings"; + std::string workspaceSettingsFile = + cmStrCat(xcodeSharedDataDir, "/WorkspaceSettings.xcsettings"); cmGeneratedFileStream fout(workspaceSettingsFile); fout.SetCopyIfDifferent(true); @@ -3575,9 +3537,7 @@ std::string cmGlobalXCodeGenerator::RelativeToBinary(const std::string& p) std::string cmGlobalXCodeGenerator::XCodeEscapePath(const std::string& p) { if (p.find(' ') != std::string::npos) { - std::string t = "\""; - t += p; - t += "\""; + std::string t = cmStrCat('"', p, '"'); return t; } return p; @@ -3599,9 +3559,7 @@ std::string cmGlobalXCodeGenerator::LookupFlags( const std::string& varNameSuffix, const std::string& default_flags) { if (!varNameLang.empty()) { - std::string varName = varNamePrefix; - varName += varNameLang; - varName += varNameSuffix; + std::string varName = cmStrCat(varNamePrefix, varNameLang, varNameSuffix); if (const char* varValue = this->CurrentMakefile->GetDefinition(varName)) { if (*varValue) { return varValue; @@ -3621,8 +3579,7 @@ void cmGlobalXCodeGenerator::AppendDefines(BuildObjectListOrString& defs, } // Expand the list of definitions. - std::vector<std::string> defines; - cmExpandList(defines_list, defines); + std::vector<std::string> defines = cmExpandedList(defines_list); // Store the definitions in the string. this->AppendDefines(defs, defines, dflag); @@ -3636,8 +3593,7 @@ void cmGlobalXCodeGenerator::AppendDefines( std::string def; for (auto const& define : defines) { // Start with -D if requested. - def = dflag ? "-D" : ""; - def += define; + def = cmStrCat(dflag ? "-D" : "", define); // Append the flag with needed escapes. std::string tmp; @@ -3698,10 +3654,9 @@ void cmGlobalXCodeGenerator::AppendFlag(std::string& flags, std::string cmGlobalXCodeGenerator::ComputeInfoPListLocation( cmGeneratorTarget* target) { - std::string plist = target->GetLocalGenerator()->GetCurrentBinaryDirectory(); - plist += "/CMakeFiles/"; - plist += target->GetName(); - plist += ".dir/Info.plist"; + std::string plist = + cmStrCat(target->GetLocalGenerator()->GetCurrentBinaryDirectory(), + "/CMakeFiles/", target->GetName(), ".dir/Info.plist"); return plist; } @@ -3748,10 +3703,10 @@ void cmGlobalXCodeGenerator::ComputeTargetObjectDirectory( cmGeneratorTarget* gt) const { std::string configName = this->GetCMakeCFGIntDir(); - std::string dir = this->GetObjectsDirectory( - "$(PROJECT_NAME)", configName, gt, "$(OBJECT_FILE_DIR_normal:base)/"); - dir += this->ObjectDirArch; - dir += "/"; + std::string dir = + cmStrCat(this->GetObjectsDirectory("$(PROJECT_NAME)", configName, gt, + "$(OBJECT_FILE_DIR_normal:base)/"), + this->ObjectDirArch, '/'); gt->ObjectDirectory = dir; } diff --git a/Source/cmGraphVizWriter.cxx b/Source/cmGraphVizWriter.cxx index 7d0ef83..9b58f61 100644 --- a/Source/cmGraphVizWriter.cxx +++ b/Source/cmGraphVizWriter.cxx @@ -74,7 +74,8 @@ std::map<std::string, LinkLibraryScopeType> getScopedLinkLibrariesFromTarget( { char sep = ';'; std::map<std::string, LinkLibraryScopeType> tokens; - size_t start = 0, end = 0; + size_t start = 0; + size_t end = 0; const char* pInterfaceLinkLibraries = Target->GetProperty("INTERFACE_LINK_LIBRARIES"); @@ -234,8 +235,8 @@ void cmGraphVizWriter::ReadSettings( this->TargetsToIgnoreRegex.clear(); if (!ignoreTargetsRegexes.empty()) { - std::vector<std::string> ignoreTargetsRegExVector; - cmExpandList(ignoreTargetsRegexes, ignoreTargetsRegExVector); + std::vector<std::string> ignoreTargetsRegExVector = + cmExpandedList(ignoreTargetsRegexes); for (std::string const& currentRegexString : ignoreTargetsRegExVector) { cmsys::RegularExpression currentRegex; if (!currentRegex.compile(currentRegexString)) { @@ -266,10 +267,8 @@ void cmGraphVizWriter::WriteTargetDependersFiles(const std::string& fileName) continue; } - std::string currentFilename = fileName; - currentFilename += "."; - currentFilename += ptr.first; - currentFilename += ".dependers"; + std::string currentFilename = + cmStrCat(fileName, '.', ptr.first, ".dependers"); cmGeneratedFileStream str(currentFilename); if (!str) { @@ -311,9 +310,7 @@ void cmGraphVizWriter::WritePerTargetFiles(const std::string& fileName) std::set<std::string> insertedConnections; std::set<std::string> insertedNodes; - std::string currentFilename = fileName; - currentFilename += "."; - currentFilename += ptr.first; + std::string currentFilename = cmStrCat(fileName, '.', ptr.first); cmGeneratedFileStream str(currentFilename); if (!str) { return; @@ -401,9 +398,7 @@ void cmGraphVizWriter::WriteConnections( continue; } - std::string connectionName = myNodeName; - connectionName += "-"; - connectionName += libNameIt->second; + std::string connectionName = cmStrCat(myNodeName, '-', libNameIt->second); if (insertedConnections.find(connectionName) == insertedConnections.end()) { insertedConnections.insert(connectionName); @@ -463,9 +458,8 @@ void cmGraphVizWriter::WriteDependerConnections( this->TargetNamesNodes.find(tptr.first); if (dependerNodeNameIt != this->TargetNamesNodes.end()) { - std::string connectionName = dependerNodeNameIt->second; - connectionName += "-"; - connectionName += myNodeName; + std::string connectionName = + cmStrCat(dependerNodeNameIt->second, '-', myNodeName); if (insertedConnections.find(connectionName) == insertedConnections.end()) { diff --git a/Source/cmIfCommand.cxx b/Source/cmIfCommand.cxx index 7b49ae7..f719041 100644 --- a/Source/cmIfCommand.cxx +++ b/Source/cmIfCommand.cxx @@ -14,6 +14,7 @@ #include "cmMakefile.h" #include "cmMessageType.h" #include "cmOutputConverter.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmake.h" @@ -127,8 +128,8 @@ bool cmIfFunctionBlocker::Replay(std::vector<cmListFileFunction> functions, conditionEvaluator.IsTrue(expandedArguments, errorString, messType); if (!errorString.empty()) { - std::string err = cmIfCommandError(expandedArguments); - err += errorString; + std::string err = + cmStrCat(cmIfCommandError(expandedArguments), errorString); cmListFileBacktrace bt = mf.GetBacktrace(func); mf.GetCMakeInstance()->IssueMessage(messType, err, bt); if (messType == MessageType::FATAL_ERROR) { @@ -184,8 +185,8 @@ bool cmIfCommand(std::vector<cmListFileArgument> const& args, conditionEvaluator.IsTrue(expandedArguments, errorString, status); if (!errorString.empty()) { - std::string err = "if " + cmIfCommandError(expandedArguments); - err += errorString; + std::string err = + cmStrCat("if ", cmIfCommandError(expandedArguments), errorString); if (status == MessageType::FATAL_ERROR) { makefile.IssueMessage(MessageType::FATAL_ERROR, err); cmSystemTools::SetFatalErrorOccured(); diff --git a/Source/cmIncludeCommand.cxx b/Source/cmIncludeCommand.cxx index 0d608bb..14264f4 100644 --- a/Source/cmIncludeCommand.cxx +++ b/Source/cmIncludeCommand.cxx @@ -4,21 +4,21 @@ #include <sstream> +#include "cmExecutionStatus.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmPolicies.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" -class cmExecutionStatus; - // cmIncludeCommand -bool cmIncludeCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmIncludeCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.empty() || args.size() > 4) { - this->SetError("called with wrong number of arguments. " - "include() only takes one file."); + status.SetError("called with wrong number of arguments. " + "include() only takes one file."); return false; } bool optional = false; @@ -29,20 +29,20 @@ bool cmIncludeCommand::InitialPass(std::vector<std::string> const& args, for (unsigned int i = 1; i < args.size(); i++) { if (args[i] == "OPTIONAL") { if (optional) { - this->SetError("called with invalid arguments: OPTIONAL used twice"); + status.SetError("called with invalid arguments: OPTIONAL used twice"); return false; } optional = true; } else if (args[i] == "RESULT_VARIABLE") { if (!resultVarName.empty()) { - this->SetError("called with invalid arguments: " - "only one result variable allowed"); + status.SetError("called with invalid arguments: " + "only one result variable allowed"); return false; } if (++i < args.size()) { resultVarName = args[i]; } else { - this->SetError("called with no value for RESULT_VARIABLE."); + status.SetError("called with no value for RESULT_VARIABLE."); return false; } } else if (args[i] == "NO_POLICY_SCOPE") { @@ -50,39 +50,39 @@ bool cmIncludeCommand::InitialPass(std::vector<std::string> const& args, } else if (i > 1) // compat.: in previous cmake versions the second // parameter was ignored if it wasn't "OPTIONAL" { - std::string errorText = "called with invalid argument: "; - errorText += args[i]; - this->SetError(errorText); + std::string errorText = + cmStrCat("called with invalid argument: ", args[i]); + status.SetError(errorText); return false; } } if (fname.empty()) { - this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, - "include() given empty file name (ignored)."); + status.GetMakefile().IssueMessage( + MessageType::AUTHOR_WARNING, + "include() given empty file name (ignored)."); return true; } if (!cmSystemTools::FileIsFullPath(fname)) { // Not a path. Maybe module. - std::string module = fname; - module += ".cmake"; - std::string mfile = this->Makefile->GetModulesFile(module); + std::string module = cmStrCat(fname, ".cmake"); + std::string mfile = status.GetMakefile().GetModulesFile(module); if (!mfile.empty()) { fname = mfile; } } std::string fname_abs = cmSystemTools::CollapseFullPath( - fname, this->Makefile->GetCurrentSourceDirectory()); + fname, status.GetMakefile().GetCurrentSourceDirectory()); - cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator(); + cmGlobalGenerator* gg = status.GetMakefile().GetGlobalGenerator(); if (gg->IsExportedTargetsFile(fname_abs)) { const char* modal = nullptr; std::ostringstream e; MessageType messageType = MessageType::AUTHOR_WARNING; - switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0024)) { + switch (status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0024)) { case cmPolicies::WARN: e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0024) << "\n"; modal = "should"; @@ -102,7 +102,7 @@ bool cmIncludeCommand::InitialPass(std::vector<std::string> const& args, << " not be used as the argument to the " "include() command. Use ALIAS targets instead to refer to targets " "by alternative names.\n"; - this->Makefile->IssueMessage(messageType, e.str()); + status.GetMakefile().IssueMessage(messageType, e.str()); if (messageType == MessageType::FATAL_ERROR) { return false; } @@ -112,27 +112,28 @@ bool cmIncludeCommand::InitialPass(std::vector<std::string> const& args, } std::string listFile = cmSystemTools::CollapseFullPath( - fname, this->Makefile->GetCurrentSourceDirectory()); + fname, status.GetMakefile().GetCurrentSourceDirectory()); if (optional && !cmSystemTools::FileExists(listFile)) { if (!resultVarName.empty()) { - this->Makefile->AddDefinition(resultVarName, "NOTFOUND"); + status.GetMakefile().AddDefinition(resultVarName, "NOTFOUND"); } return true; } - bool readit = this->Makefile->ReadDependentFile(listFile, noPolicyScope); + bool readit = + status.GetMakefile().ReadDependentFile(listFile, noPolicyScope); // add the location of the included file if a result variable was given if (!resultVarName.empty()) { - this->Makefile->AddDefinition(resultVarName, - readit ? fname_abs.c_str() : "NOTFOUND"); + status.GetMakefile().AddDefinition( + resultVarName, readit ? fname_abs.c_str() : "NOTFOUND"); } if (!optional && !readit && !cmSystemTools::GetFatalErrorOccured()) { - std::string m = "could not find load file:\n" - " "; - m += fname; - this->SetError(m); + std::string m = cmStrCat("could not find load file:\n" + " ", + fname); + status.SetError(m); return false; } return true; diff --git a/Source/cmIncludeCommand.h b/Source/cmIncludeCommand.h index 94d3fbd..b0dd779 100644 --- a/Source/cmIncludeCommand.h +++ b/Source/cmIncludeCommand.h @@ -8,35 +8,15 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmIncludeCommand +/** * \brief cmIncludeCommand defines a list of distant * files that can be "included" in the current list file. * In almost every sense, this is identical to a C/C++ * #include command. Arguments are first expended as usual. */ -class cmIncludeCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmIncludeCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; +bool cmIncludeCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmIncludeDirectoryCommand.cxx b/Source/cmIncludeDirectoryCommand.cxx index eb10aa8..876bd95 100644 --- a/Source/cmIncludeDirectoryCommand.cxx +++ b/Source/cmIncludeDirectoryCommand.cxx @@ -122,9 +122,8 @@ void cmIncludeDirectoryCommand::NormalizeInclude(std::string& inc) if (!cmSystemTools::FileIsFullPath(inc)) { if (!cmGeneratorExpression::StartsWithGeneratorExpression(inc)) { - std::string tmp = this->Makefile->GetCurrentSourceDirectory(); - tmp += "/"; - tmp += inc; + std::string tmp = + cmStrCat(this->Makefile->GetCurrentSourceDirectory(), '/', inc); inc = tmp; } } diff --git a/Source/cmIncludeGuardCommand.cxx b/Source/cmIncludeGuardCommand.cxx index e560910..ccb4496 100644 --- a/Source/cmIncludeGuardCommand.cxx +++ b/Source/cmIncludeGuardCommand.cxx @@ -50,11 +50,11 @@ bool CheckIncludeGuardIsSet(cmMakefile* mf, std::string const& includeGuardVar) } // anonymous namespace // cmIncludeGuardCommand -bool cmIncludeGuardCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) +bool cmIncludeGuardCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() > 1) { - this->SetError( + status.SetError( "given an invalid number of arguments. The command takes at " "most 1 argument."); return false; @@ -69,15 +69,15 @@ bool cmIncludeGuardCommand::InitialPass(std::vector<std::string> const& args, } else if (arg == "GLOBAL") { scope = GLOBAL; } else { - this->SetError("given an invalid scope: " + arg); + status.SetError("given an invalid scope: " + arg); return false; } } std::string includeGuardVar = GetIncludeGuardVariableName( - this->Makefile->GetDefinition("CMAKE_CURRENT_LIST_FILE")); + status.GetMakefile().GetDefinition("CMAKE_CURRENT_LIST_FILE")); - cmMakefile* const mf = this->Makefile; + cmMakefile* const mf = &status.GetMakefile(); switch (scope) { case VARIABLE: diff --git a/Source/cmIncludeGuardCommand.h b/Source/cmIncludeGuardCommand.h index 4306c4c..b86b760 100644 --- a/Source/cmIncludeGuardCommand.h +++ b/Source/cmIncludeGuardCommand.h @@ -8,35 +8,15 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmIncludeGuardCommand +/** * \brief cmIncludeGuardCommand identical to C++ #pragma_once command * Can work in 3 modes: GLOBAL (works on global properties), * DIRECTORY(use directory property), VARIABLE(unnamed overload without * arguments) define an ordinary variable to be used as include guard checker */ -class cmIncludeGuardCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmIncludeGuardCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; +bool cmIncludeGuardCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx index 51689a2..9a78c49 100644 --- a/Source/cmInstallCommand.cxx +++ b/Source/cmInstallCommand.cxx @@ -137,8 +137,7 @@ bool cmInstallCommand::InitialPass(std::vector<std::string> const& args, } // Unknown mode. - std::string e = "called with unknown mode "; - e += args[0]; + std::string e = cmStrCat("called with unknown mode ", args[0]); this->SetError(e); return false; } @@ -188,9 +187,8 @@ bool cmInstallCommand::HandleScriptMode(std::vector<std::string> const& args) doing_script = false; std::string script = arg; if (!cmSystemTools::FileIsFullPath(script)) { - script = this->Makefile->GetCurrentSourceDirectory(); - script += "/"; - script += arg; + script = + cmStrCat(this->Makefile->GetCurrentSourceDirectory(), '/', arg); } if (cmSystemTools::FileIsDirectory(script)) { this->SetError("given a directory as value of SCRIPT argument."); @@ -370,10 +368,9 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) !objectArgs.GetType().empty() || !frameworkArgs.GetType().empty() || !bundleArgs.GetType().empty() || !privateHeaderArgs.GetType().empty() || !publicHeaderArgs.GetType().empty() || !resourceArgs.GetType().empty()) { - std::ostringstream e; - e << "TARGETS given TYPE option. The TYPE option may only be specified in " - " install(FILES) and install(DIRECTORIES)."; - this->SetError(e.str()); + this->SetError( + "TARGETS given TYPE option. The TYPE option may only be specified in " + " install(FILES) and install(DIRECTORIES)."); return false; } @@ -672,8 +669,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) if (createInstallGeneratorsForTargetFileSets && !namelinkOnly) { const char* files = target.GetProperty("PRIVATE_HEADER"); if ((files) && (*files)) { - std::vector<std::string> relFiles; - cmExpandList(files, relFiles); + std::vector<std::string> relFiles = cmExpandedList(files); std::vector<std::string> absFiles; if (!this->MakeFilesFullPath("PRIVATE_HEADER", relFiles, absFiles)) { return false; @@ -687,8 +683,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) files = target.GetProperty("PUBLIC_HEADER"); if ((files) && (*files)) { - std::vector<std::string> relFiles; - cmExpandList(files, relFiles); + std::vector<std::string> relFiles = cmExpandedList(files); std::vector<std::string> absFiles; if (!this->MakeFilesFullPath("PUBLIC_HEADER", relFiles, absFiles)) { return false; @@ -702,8 +697,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) files = target.GetProperty("RESOURCE"); if ((files) && (*files)) { - std::vector<std::string> relFiles; - cmExpandList(files, relFiles); + std::vector<std::string> relFiles = cmExpandedList(files); std::vector<std::string> absFiles; if (!this->MakeFilesFullPath("RESOURCE", relFiles, absFiles)) { return false; @@ -1123,9 +1117,8 @@ bool cmInstallCommand::HandleDirectoryMode( std::string dir = args[i]; std::string::size_type gpos = cmGeneratorExpression::Find(dir); if (gpos != 0 && !cmSystemTools::FileIsFullPath(dir)) { - dir = this->Makefile->GetCurrentSourceDirectory(); - dir += "/"; - dir += args[i]; + dir = + cmStrCat(this->Makefile->GetCurrentSourceDirectory(), '/', args[i]); } // Make sure the name is a directory. @@ -1424,8 +1417,7 @@ bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args) // Construct the file name. if (fname.empty()) { - fname = exp; - fname += ".cmake"; + fname = cmStrCat(exp, ".cmake"); if (fname.find_first_of(":/\\") != std::string::npos) { std::ostringstream e; @@ -1482,9 +1474,8 @@ bool cmInstallCommand::MakeFilesFullPath( std::string file = relFile; std::string::size_type gpos = cmGeneratorExpression::Find(file); if (gpos != 0 && !cmSystemTools::FileIsFullPath(file)) { - file = this->Makefile->GetCurrentSourceDirectory(); - file += "/"; - file += relFile; + file = + cmStrCat(this->Makefile->GetCurrentSourceDirectory(), '/', relFile); } // Make sure the file is not a directory. diff --git a/Source/cmInstallExportAndroidMKGenerator.cxx b/Source/cmInstallExportAndroidMKGenerator.cxx index 55d3685..e8de029 100644 --- a/Source/cmInstallExportAndroidMKGenerator.cxx +++ b/Source/cmInstallExportAndroidMKGenerator.cxx @@ -53,9 +53,7 @@ void cmInstallExportAndroidMKGenerator::GenerateScript(std::ostream& os) cmSystemTools::MakeDirectory(this->TempDir.c_str()); // Construct a temporary location for the file. - this->MainImportFile = this->TempDir; - this->MainImportFile += "/"; - this->MainImportFile += this->FileName; + this->MainImportFile = cmStrCat(this->TempDir, '/', this->FileName); // Generate the import file for this export set. this->EFGen->SetExportFile(this->MainImportFile.c_str()); @@ -103,11 +101,10 @@ void cmInstallExportAndroidMKGenerator::GenerateScriptActions( std::ostream& os, Indent const& indent) { // Remove old per-configuration export files if the main changes. - std::string installedDir = "$ENV{DESTDIR}"; - installedDir += this->ConvertToAbsoluteDestination(this->Destination); - installedDir += "/"; - std::string installedFile = installedDir; - installedFile += this->FileName; + std::string installedDir = + cmStrCat("$ENV{DESTDIR}", + this->ConvertToAbsoluteDestination(this->Destination), '/'); + std::string installedFile = cmStrCat(installedDir, this->FileName); os << indent << "if(EXISTS \"" << installedFile << "\")\n"; Indent indentN = indent.Next(); Indent indentNN = indentN.Next(); diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx index d4562de..0b3617b 100644 --- a/Source/cmInstallExportGenerator.cxx +++ b/Source/cmInstallExportGenerator.cxx @@ -14,6 +14,7 @@ #include "cmExportSet.h" #include "cmInstallType.h" #include "cmLocalGenerator.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" cmInstallExportGenerator::cmInstallExportGenerator( @@ -56,8 +57,8 @@ void cmInstallExportGenerator::ComputeTempDir() { // Choose a temporary directory in which to generate the import // files to be installed. - this->TempDir = this->LocalGenerator->GetCurrentBinaryDirectory(); - this->TempDir += "/CMakeFiles/Export"; + this->TempDir = cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(), + "/CMakeFiles/Export"); if (this->Destination.empty()) { return; } @@ -135,9 +136,7 @@ void cmInstallExportGenerator::GenerateScript(std::ostream& os) cmSystemTools::MakeDirectory(this->TempDir); // Construct a temporary location for the file. - this->MainImportFile = this->TempDir; - this->MainImportFile += "/"; - this->MainImportFile += this->FileName; + this->MainImportFile = cmStrCat(this->TempDir, '/', this->FileName); // Generate the import file for this export set. this->EFGen->SetExportFile(this->MainImportFile.c_str()); @@ -185,11 +184,10 @@ void cmInstallExportGenerator::GenerateScriptActions(std::ostream& os, Indent indent) { // Remove old per-configuration export files if the main changes. - std::string installedDir = "$ENV{DESTDIR}"; - installedDir += this->ConvertToAbsoluteDestination(this->Destination); - installedDir += "/"; - std::string installedFile = installedDir; - installedFile += this->FileName; + std::string installedDir = + cmStrCat("$ENV{DESTDIR}", + this->ConvertToAbsoluteDestination(this->Destination), '/'); + std::string installedFile = cmStrCat(installedDir, this->FileName); os << indent << "if(EXISTS \"" << installedFile << "\")\n"; Indent indentN = indent.Next(); Indent indentNN = indentN.Next(); @@ -217,3 +215,8 @@ void cmInstallExportGenerator::GenerateScriptActions(std::ostream& os, false, this->FilePermissions.c_str(), nullptr, nullptr, nullptr, indent); } + +std::string cmInstallExportGenerator::GetDestinationFile() const +{ + return this->Destination + '/' + this->FileName; +} diff --git a/Source/cmInstallExportGenerator.h b/Source/cmInstallExportGenerator.h index c4d252c..e680066 100644 --- a/Source/cmInstallExportGenerator.h +++ b/Source/cmInstallExportGenerator.h @@ -41,6 +41,7 @@ public: const std::string& GetNamespace() const { return this->Namespace; } std::string const& GetDestination() const { return this->Destination; } + std::string GetDestinationFile() const; protected: void GenerateScript(std::ostream& os) override; diff --git a/Source/cmInstallFilesCommand.cxx b/Source/cmInstallFilesCommand.cxx index 4522669..11687a8 100644 --- a/Source/cmInstallFilesCommand.cxx +++ b/Source/cmInstallFilesCommand.cxx @@ -8,6 +8,7 @@ #include "cmInstallGenerator.h" #include "cmMakefile.h" #include "cmRange.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" class cmExecutionStatus; @@ -135,12 +136,8 @@ static std::string FindInstallSource(cmMakefile& makefile, const char* name) } // This is a relative path. - std::string tb = makefile.GetCurrentBinaryDirectory(); - tb += "/"; - tb += name; - std::string ts = makefile.GetCurrentSourceDirectory(); - ts += "/"; - ts += name; + std::string tb = cmStrCat(makefile.GetCurrentBinaryDirectory(), '/', name); + std::string ts = cmStrCat(makefile.GetCurrentSourceDirectory(), '/', name); if (cmSystemTools::FileExists(tb)) { // The file exists in the binary tree. Use it. diff --git a/Source/cmInstallProgramsCommand.cxx b/Source/cmInstallProgramsCommand.cxx index 6ec02e7..3eca0e0 100644 --- a/Source/cmInstallProgramsCommand.cxx +++ b/Source/cmInstallProgramsCommand.cxx @@ -7,6 +7,7 @@ #include "cmInstallFilesGenerator.h" #include "cmInstallGenerator.h" #include "cmMakefile.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" class cmExecutionStatus; @@ -110,12 +111,8 @@ static std::string FindInstallSource(cmMakefile& makefile, const char* name) } // This is a relative path. - std::string tb = makefile.GetCurrentBinaryDirectory(); - tb += "/"; - tb += name; - std::string ts = makefile.GetCurrentSourceDirectory(); - ts += "/"; - ts += name; + std::string tb = cmStrCat(makefile.GetCurrentBinaryDirectory(), '/', name); + std::string ts = cmStrCat(makefile.GetCurrentSourceDirectory(), '/', name); if (cmSystemTools::FileExists(tb)) { // The file exists in the binary tree. Use it. diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx index ed1c80a..7bbef35 100644 --- a/Source/cmInstallTargetGenerator.cxx +++ b/Source/cmInstallTargetGenerator.cxx @@ -87,19 +87,18 @@ void cmInstallTargetGenerator::GenerateScriptForConfig( std::string fromDirConfig; if (this->Target->NeedRelinkBeforeInstall(config)) { fromDirConfig = - this->Target->GetLocalGenerator()->GetCurrentBinaryDirectory(); - fromDirConfig += "/CMakeFiles/CMakeRelink.dir/"; + cmStrCat(this->Target->GetLocalGenerator()->GetCurrentBinaryDirectory(), + "/CMakeFiles/CMakeRelink.dir/"); } else { cmStateEnums::ArtifactType artifact = this->ImportLibrary ? cmStateEnums::ImportLibraryArtifact : cmStateEnums::RuntimeBinaryArtifact; - fromDirConfig = this->Target->GetDirectory(config, artifact); - fromDirConfig += "/"; + fromDirConfig = + cmStrCat(this->Target->GetDirectory(config, artifact), '/'); } - std::string toDir = - this->ConvertToAbsoluteDestination(this->GetDestination(config)); - toDir += "/"; + std::string toDir = cmStrCat( + this->ConvertToAbsoluteDestination(this->GetDestination(config)), '/'); // Compute the list of files to install for this target. std::vector<std::string> filesFrom; @@ -593,8 +592,8 @@ void cmInstallTargetGenerator::AddInstallNamePatchRule( // on the installed file. if (for_build != for_install) { // Prepare to refer to the install-tree install_name. - new_id = for_install; - new_id += this->GetInstallFilename(this->Target, config, NameSO); + new_id = cmStrCat( + for_install, this->GetInstallFilename(this->Target, config, NameSO)); } } @@ -688,7 +687,8 @@ void cmInstallTargetGenerator::AddChrpathPatchRule( std::string installNameTool = mf->GetSafeDefinition("CMAKE_INSTALL_NAME_TOOL"); - std::vector<std::string> oldRuntimeDirs, newRuntimeDirs; + std::vector<std::string> oldRuntimeDirs; + std::vector<std::string> newRuntimeDirs; cli->GetRPath(oldRuntimeDirs, false); cli->GetRPath(newRuntimeDirs, true); diff --git a/Source/cmJsonObjects.cxx b/Source/cmJsonObjects.cxx index b8eed13..4948b01 100644 --- a/Source/cmJsonObjects.cxx +++ b/Source/cmJsonObjects.cxx @@ -264,7 +264,7 @@ static Json::Value DumpSourceFilesList( std::unordered_map<LanguageData, std::vector<std::string>> fileGroups; for (cmSourceFile* file : files) { LanguageData fileData; - fileData.Language = file->GetLanguage(); + fileData.Language = file->GetOrDetermineLanguage(); if (!fileData.Language.empty()) { const LanguageData& ld = languageDataMap.at(fileData.Language); cmLocalGenerator* lg = target->GetLocalGenerator(); diff --git a/Source/cmLDConfigLDConfigTool.cxx b/Source/cmLDConfigLDConfigTool.cxx index d5cc621..b68dbbd 100644 --- a/Source/cmLDConfigLDConfigTool.cxx +++ b/Source/cmLDConfigLDConfigTool.cxx @@ -33,8 +33,7 @@ bool cmLDConfigLDConfigTool::GetLDConfigPaths(std::vector<std::string>& paths) } } - std::vector<std::string> ldConfigCommand; - cmExpandList(ldConfigPath, ldConfigCommand); + std::vector<std::string> ldConfigCommand = cmExpandedList(ldConfigPath); ldConfigCommand.emplace_back("-v"); ldConfigCommand.emplace_back("-N"); // Don't rebuild the cache. ldConfigCommand.emplace_back("-X"); // Don't update links. diff --git a/Source/cmLinkDirectoriesCommand.cxx b/Source/cmLinkDirectoriesCommand.cxx index a278925..57b69c8 100644 --- a/Source/cmLinkDirectoriesCommand.cxx +++ b/Source/cmLinkDirectoriesCommand.cxx @@ -75,9 +75,8 @@ void cmLinkDirectoriesCommand::AddLinkDir( break; } if (convertToAbsolute) { - std::string tmp = this->Makefile->GetCurrentSourceDirectory(); - tmp += "/"; - tmp += unixPath; + std::string tmp = + cmStrCat(this->Makefile->GetCurrentSourceDirectory(), '/', unixPath); unixPath = tmp; } } diff --git a/Source/cmLinkItem.h b/Source/cmLinkItem.h index d71ff49..2d9378b 100644 --- a/Source/cmLinkItem.h +++ b/Source/cmLinkItem.h @@ -5,12 +5,12 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include <algorithm> #include <map> #include <ostream> #include <string> #include <vector> +#include "cmAlgorithms.h" #include "cmListFileCache.h" #include "cmSystemTools.h" #include "cmTargetLinkLibraryType.h" @@ -120,8 +120,7 @@ inline cmTargetLinkLibraryType CMP0003_ComputeLinkType( // Check if any entry in the list matches this configuration. std::string configUpper = cmSystemTools::UpperCase(config); - if (std::find(debugConfigs.begin(), debugConfigs.end(), configUpper) != - debugConfigs.end()) { + if (cmContains(debugConfigs, configUpper)) { return DEBUG_LibraryType; } // The current configuration is not a debug configuration. diff --git a/Source/cmLinkLineDeviceComputer.cxx b/Source/cmLinkLineDeviceComputer.cxx index 53b68eb..96af388 100644 --- a/Source/cmLinkLineDeviceComputer.cxx +++ b/Source/cmLinkLineDeviceComputer.cxx @@ -3,12 +3,11 @@ #include "cmLinkLineDeviceComputer.h" -#include <algorithm> #include <set> #include <sstream> #include <utility> -#include <vector> +#include "cmAlgorithms.h" #include "cmComputeLinkInformation.h" #include "cmGeneratorTarget.h" #include "cmGlobalGenerator.h" @@ -186,14 +185,10 @@ bool requireDeviceLinking(cmGeneratorTarget& target, cmLocalGenerator& lg, // Determine if we have any dependencies that require // us to do a device link step - const std::string cuda_lang("CUDA"); cmGeneratorTarget::LinkClosure const* closure = target.GetLinkClosure(config); - bool closureHasCUDA = - (std::find(closure->Languages.begin(), closure->Languages.end(), - cuda_lang) != closure->Languages.end()); - if (closureHasCUDA) { + if (cmContains(closure->Languages, "CUDA")) { cmComputeLinkInformation* pcli = target.GetLinkInformation(config); if (pcli) { cmLinkLineDeviceComputer deviceLinkComputer( diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx index cbb1d3a..91dea58 100644 --- a/Source/cmListCommand.cxx +++ b/Source/cmListCommand.cxx @@ -16,8 +16,10 @@ #include <vector> #include "cm_memory.hxx" +#include "cm_static_string_view.hxx" #include "cmAlgorithms.h" +#include "cmExecutionStatus.h" #include "cmGeneratorExpression.h" #include "cmMakefile.h" #include "cmMessageType.h" @@ -25,81 +27,21 @@ #include "cmRange.h" #include "cmStringAlgorithms.h" #include "cmStringReplaceHelper.h" +#include "cmSubcommandTable.h" #include "cmSystemTools.h" -class cmExecutionStatus; - -bool cmListCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) -{ - if (args.size() < 2) { - this->SetError("must be called with at least two arguments."); - return false; - } - - const std::string& subCommand = args[0]; - if (subCommand == "LENGTH") { - return this->HandleLengthCommand(args); - } - if (subCommand == "GET") { - return this->HandleGetCommand(args); - } - if (subCommand == "APPEND") { - return this->HandleAppendCommand(args); - } - if (subCommand == "PREPEND") { - return this->HandlePrependCommand(args); - } - if (subCommand == "POP_BACK") { - return this->HandlePopBackCommand(args); - } - if (subCommand == "POP_FRONT") { - return this->HandlePopFrontCommand(args); - } - if (subCommand == "FIND") { - return this->HandleFindCommand(args); - } - if (subCommand == "INSERT") { - return this->HandleInsertCommand(args); - } - if (subCommand == "JOIN") { - return this->HandleJoinCommand(args); - } - if (subCommand == "REMOVE_AT") { - return this->HandleRemoveAtCommand(args); - } - if (subCommand == "REMOVE_ITEM") { - return this->HandleRemoveItemCommand(args); - } - if (subCommand == "REMOVE_DUPLICATES") { - return this->HandleRemoveDuplicatesCommand(args); - } - if (subCommand == "TRANSFORM") { - return this->HandleTransformCommand(args); - } - if (subCommand == "SORT") { - return this->HandleSortCommand(args); - } - if (subCommand == "SUBLIST") { - return this->HandleSublistCommand(args); - } - if (subCommand == "REVERSE") { - return this->HandleReverseCommand(args); - } - if (subCommand == "FILTER") { - return this->HandleFilterCommand(args); - } +namespace { - std::string e = "does not recognize sub-command " + subCommand; - this->SetError(e); - return false; -} +bool FilterRegex(std::vector<std::string> const& args, bool includeMatches, + std::string const& listName, + std::vector<std::string>& varArgsExpanded, + cmExecutionStatus& status); -bool cmListCommand::GetListString(std::string& listString, - const std::string& var) +bool GetListString(std::string& listString, const std::string& var, + const cmMakefile& makefile) { // get the old value - const char* cacheValue = this->Makefile->GetDefinition(var); + const char* cacheValue = makefile.GetDefinition(var); if (!cacheValue) { return false; } @@ -107,11 +49,11 @@ bool cmListCommand::GetListString(std::string& listString, return true; } -bool cmListCommand::GetList(std::vector<std::string>& list, - const std::string& var) +bool GetList(std::vector<std::string>& list, const std::string& var, + const cmMakefile& makefile) { std::string listString; - if (!this->GetListString(listString, var)) { + if (!GetListString(listString, var, makefile)) { return false; } // if the size of the list @@ -121,11 +63,11 @@ bool cmListCommand::GetList(std::vector<std::string>& list, // expand the variable into a list cmExpandList(listString, list, true); // if no empty elements then just return - if (std::find(list.begin(), list.end(), std::string()) == list.end()) { + if (!cmContains(list, std::string())) { return true; } // if we have empty elements we need to check policy CMP0007 - switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0007)) { + switch (makefile.GetPolicyStatus(cmPolicies::CMP0007)) { case cmPolicies::WARN: { // Default is to warn and use old behavior // OLD behavior is to allow compatibility, so recall @@ -133,11 +75,10 @@ bool cmListCommand::GetList(std::vector<std::string>& list, // empty values list.clear(); cmExpandList(listString, list); - std::string warn = cmPolicies::GetPolicyWarning(cmPolicies::CMP0007); - warn += " List has value = ["; - warn += listString; - warn += "]."; - this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, warn); + std::string warn = + cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0007), + " List has value = [", listString, "]."); + makefile.IssueMessage(MessageType::AUTHOR_WARNING, warn); return true; } case cmPolicies::OLD: @@ -151,7 +92,7 @@ bool cmListCommand::GetList(std::vector<std::string>& list, return true; case cmPolicies::REQUIRED_IF_USED: case cmPolicies::REQUIRED_ALWAYS: - this->Makefile->IssueMessage( + makefile.IssueMessage( MessageType::FATAL_ERROR, cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0007)); return false; @@ -159,10 +100,11 @@ bool cmListCommand::GetList(std::vector<std::string>& list, return true; } -bool cmListCommand::HandleLengthCommand(std::vector<std::string> const& args) +bool HandleLengthCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() != 3) { - this->SetError("sub-command LENGTH requires two arguments."); + status.SetError("sub-command LENGTH requires two arguments."); return false; } @@ -172,19 +114,20 @@ bool cmListCommand::HandleLengthCommand(std::vector<std::string> const& args) // do not check the return value here // if the list var is not found varArgsExpanded will have size 0 // and we will return 0 - this->GetList(varArgsExpanded, listName); + GetList(varArgsExpanded, listName, status.GetMakefile()); size_t length = varArgsExpanded.size(); char buffer[1024]; sprintf(buffer, "%d", static_cast<int>(length)); - this->Makefile->AddDefinition(variableName, buffer); + status.GetMakefile().AddDefinition(variableName, buffer); return true; } -bool cmListCommand::HandleGetCommand(std::vector<std::string> const& args) +bool HandleGetCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() < 4) { - this->SetError("sub-command GET requires at least three arguments."); + status.SetError("sub-command GET requires at least three arguments."); return false; } @@ -192,13 +135,13 @@ bool cmListCommand::HandleGetCommand(std::vector<std::string> const& args) const std::string& variableName = args.back(); // expand the variable std::vector<std::string> varArgsExpanded; - if (!this->GetList(varArgsExpanded, listName)) { - this->Makefile->AddDefinition(variableName, "NOTFOUND"); + if (!GetList(varArgsExpanded, listName, status.GetMakefile())) { + status.GetMakefile().AddDefinition(variableName, "NOTFOUND"); return true; } // FIXME: Add policy to make non-existing lists an error like empty lists. if (varArgsExpanded.empty()) { - this->SetError("GET given empty list"); + status.SetError("GET given empty list"); return false; } @@ -217,17 +160,18 @@ bool cmListCommand::HandleGetCommand(std::vector<std::string> const& args) std::ostringstream str; str << "index: " << item << " out of range (-" << nitem << ", " << nitem - 1 << ")"; - this->SetError(str.str()); + status.SetError(str.str()); return false; } value += varArgsExpanded[item]; } - this->Makefile->AddDefinition(variableName, value); + status.GetMakefile().AddDefinition(variableName, value); return true; } -bool cmListCommand::HandleAppendCommand(std::vector<std::string> const& args) +bool HandleAppendCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { assert(args.size() >= 2); @@ -236,10 +180,11 @@ bool cmListCommand::HandleAppendCommand(std::vector<std::string> const& args) return true; } + cmMakefile& makefile = status.GetMakefile(); std::string const& listName = args[1]; // expand the variable std::string listString; - this->GetListString(listString, listName); + GetListString(listString, listName, makefile); // If `listString` or `args` is empty, no need to append `;`, // then index is going to be `1` and points to the end-of-string ";" @@ -247,11 +192,12 @@ bool cmListCommand::HandleAppendCommand(std::vector<std::string> const& args) std::string::size_type(listString.empty() || args.empty()); listString += &";"[offset] + cmJoin(cmMakeRange(args).advance(2), ";"); - this->Makefile->AddDefinition(listName, listString); + makefile.AddDefinition(listName, listString); return true; } -bool cmListCommand::HandlePrependCommand(std::vector<std::string> const& args) +bool HandlePrependCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { assert(args.size() >= 2); @@ -260,10 +206,11 @@ bool cmListCommand::HandlePrependCommand(std::vector<std::string> const& args) return true; } + cmMakefile& makefile = status.GetMakefile(); std::string const& listName = args[1]; // expand the variable std::string listString; - this->GetListString(listString, listName); + GetListString(listString, listName, makefile); // If `listString` or `args` is empty, no need to append `;`, // then `offset` is going to be `1` and points to the end-of-string ";" @@ -272,22 +219,24 @@ bool cmListCommand::HandlePrependCommand(std::vector<std::string> const& args) listString.insert(0, cmJoin(cmMakeRange(args).advance(2), ";") + &";"[offset]); - this->Makefile->AddDefinition(listName, listString); + makefile.AddDefinition(listName, listString); return true; } -bool cmListCommand::HandlePopBackCommand(std::vector<std::string> const& args) +bool HandlePopBackCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { assert(args.size() >= 2); + cmMakefile& makefile = status.GetMakefile(); auto ai = args.cbegin(); ++ai; // Skip subcommand name std::string const& listName = *ai++; std::vector<std::string> varArgsExpanded; - if (!this->GetList(varArgsExpanded, listName)) { + if (!GetList(varArgsExpanded, listName, makefile)) { // Can't get the list definition... undefine any vars given after. for (; ai != args.cend(); ++ai) { - this->Makefile->RemoveDefinition(*ai); + makefile.RemoveDefinition(*ai); } return true; } @@ -300,40 +249,42 @@ bool cmListCommand::HandlePopBackCommand(std::vector<std::string> const& args) // Ok, assign elements to be removed to the given variables for (; !varArgsExpanded.empty() && ai != args.cend(); ++ai) { assert(!ai->empty()); - this->Makefile->AddDefinition(*ai, varArgsExpanded.back()); + makefile.AddDefinition(*ai, varArgsExpanded.back()); varArgsExpanded.pop_back(); } // Undefine the rest variables if the list gets empty earlier... for (; ai != args.cend(); ++ai) { - this->Makefile->RemoveDefinition(*ai); + makefile.RemoveDefinition(*ai); } } - this->Makefile->AddDefinition(listName, cmJoin(varArgsExpanded, ";")); + makefile.AddDefinition(listName, cmJoin(varArgsExpanded, ";")); } else if (ai != args.cend()) { // The list is empty, but some args were given // Need to *undefine* 'em all, cuz there are no items to assign... for (; ai != args.cend(); ++ai) { - this->Makefile->RemoveDefinition(*ai); + makefile.RemoveDefinition(*ai); } } return true; } -bool cmListCommand::HandlePopFrontCommand(std::vector<std::string> const& args) +bool HandlePopFrontCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { assert(args.size() >= 2); + cmMakefile& makefile = status.GetMakefile(); auto ai = args.cbegin(); ++ai; // Skip subcommand name std::string const& listName = *ai++; std::vector<std::string> varArgsExpanded; - if (!this->GetList(varArgsExpanded, listName)) { + if (!GetList(varArgsExpanded, listName, makefile)) { // Can't get the list definition... undefine any vars given after. for (; ai != args.cend(); ++ai) { - this->Makefile->RemoveDefinition(*ai); + makefile.RemoveDefinition(*ai); } return true; } @@ -347,32 +298,33 @@ bool cmListCommand::HandlePopFrontCommand(std::vector<std::string> const& args) auto vi = varArgsExpanded.begin(); for (; vi != varArgsExpanded.end() && ai != args.cend(); ++ai, ++vi) { assert(!ai->empty()); - this->Makefile->AddDefinition(*ai, *vi); + makefile.AddDefinition(*ai, *vi); } varArgsExpanded.erase(varArgsExpanded.begin(), vi); // Undefine the rest variables if the list gets empty earlier... for (; ai != args.cend(); ++ai) { - this->Makefile->RemoveDefinition(*ai); + makefile.RemoveDefinition(*ai); } } - this->Makefile->AddDefinition(listName, cmJoin(varArgsExpanded, ";")); + makefile.AddDefinition(listName, cmJoin(varArgsExpanded, ";")); } else if (ai != args.cend()) { // The list is empty, but some args were given // Need to *undefine* 'em all, cuz there are no items to assign... for (; ai != args.cend(); ++ai) { - this->Makefile->RemoveDefinition(*ai); + makefile.RemoveDefinition(*ai); } } return true; } -bool cmListCommand::HandleFindCommand(std::vector<std::string> const& args) +bool HandleFindCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() != 4) { - this->SetError("sub-command FIND requires three arguments."); + status.SetError("sub-command FIND requires three arguments."); return false; } @@ -380,28 +332,29 @@ bool cmListCommand::HandleFindCommand(std::vector<std::string> const& args) const std::string& variableName = args.back(); // expand the variable std::vector<std::string> varArgsExpanded; - if (!this->GetList(varArgsExpanded, listName)) { - this->Makefile->AddDefinition(variableName, "-1"); + if (!GetList(varArgsExpanded, listName, status.GetMakefile())) { + status.GetMakefile().AddDefinition(variableName, "-1"); return true; } std::vector<std::string>::iterator it = std::find(varArgsExpanded.begin(), varArgsExpanded.end(), args[2]); if (it != varArgsExpanded.end()) { - std::ostringstream indexStream; - indexStream << std::distance(varArgsExpanded.begin(), it); - this->Makefile->AddDefinition(variableName, indexStream.str()); + status.GetMakefile().AddDefinition( + variableName, + std::to_string(std::distance(varArgsExpanded.begin(), it))); return true; } - this->Makefile->AddDefinition(variableName, "-1"); + status.GetMakefile().AddDefinition(variableName, "-1"); return true; } -bool cmListCommand::HandleInsertCommand(std::vector<std::string> const& args) +bool HandleInsertCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() < 4) { - this->SetError("sub-command INSERT requires at least three arguments."); + status.SetError("sub-command INSERT requires at least three arguments."); return false; } @@ -410,11 +363,12 @@ bool cmListCommand::HandleInsertCommand(std::vector<std::string> const& args) // expand the variable int item = atoi(args[2].c_str()); std::vector<std::string> varArgsExpanded; - if ((!this->GetList(varArgsExpanded, listName) || varArgsExpanded.empty()) && + if ((!GetList(varArgsExpanded, listName, status.GetMakefile()) || + varArgsExpanded.empty()) && item != 0) { std::ostringstream str; str << "index: " << item << " out of range (0, 0)"; - this->SetError(str.str()); + status.SetError(str.str()); return false; } @@ -427,7 +381,7 @@ bool cmListCommand::HandleInsertCommand(std::vector<std::string> const& args) std::ostringstream str; str << "index: " << item << " out of range (-" << varArgsExpanded.size() << ", " << varArgsExpanded.size() << ")"; - this->SetError(str.str()); + status.SetError(str.str()); return false; } } @@ -436,17 +390,18 @@ bool cmListCommand::HandleInsertCommand(std::vector<std::string> const& args) args.end()); std::string value = cmJoin(varArgsExpanded, ";"); - this->Makefile->AddDefinition(listName, value); + status.GetMakefile().AddDefinition(listName, value); return true; } -bool cmListCommand::HandleJoinCommand(std::vector<std::string> const& args) +bool HandleJoinCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() != 4) { std::ostringstream error; error << "sub-command JOIN requires three arguments (" << args.size() - 1 << " found)."; - this->SetError(error.str()); + status.SetError(error.str()); return false; } @@ -456,30 +411,30 @@ bool cmListCommand::HandleJoinCommand(std::vector<std::string> const& args) // expand the variable std::vector<std::string> varArgsExpanded; - if (!this->GetList(varArgsExpanded, listName)) { - this->Makefile->AddDefinition(variableName, ""); + if (!GetList(varArgsExpanded, listName, status.GetMakefile())) { + status.GetMakefile().AddDefinition(variableName, ""); return true; } std::string value = cmJoin(cmMakeRange(varArgsExpanded.begin(), varArgsExpanded.end()), glue); - this->Makefile->AddDefinition(variableName, value); + status.GetMakefile().AddDefinition(variableName, value); return true; } -bool cmListCommand::HandleRemoveItemCommand( - std::vector<std::string> const& args) +bool HandleRemoveItemCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() < 3) { - this->SetError("sub-command REMOVE_ITEM requires two or more arguments."); + status.SetError("sub-command REMOVE_ITEM requires two or more arguments."); return false; } const std::string& listName = args[1]; // expand the variable std::vector<std::string> varArgsExpanded; - if (!this->GetList(varArgsExpanded, listName)) { + if (!GetList(varArgsExpanded, listName, status.GetMakefile())) { return true; } @@ -493,44 +448,45 @@ bool cmListCommand::HandleRemoveItemCommand( cmRemoveMatching(varArgsExpanded, cmMakeRange(remBegin, remEnd)); std::vector<std::string>::const_iterator argsBegin = varArgsExpanded.begin(); std::string value = cmJoin(cmMakeRange(argsBegin, argsEnd), ";"); - this->Makefile->AddDefinition(listName, value); + status.GetMakefile().AddDefinition(listName, value); return true; } -bool cmListCommand::HandleReverseCommand(std::vector<std::string> const& args) +bool HandleReverseCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { assert(args.size() >= 2); if (args.size() > 2) { - this->SetError("sub-command REVERSE only takes one argument."); + status.SetError("sub-command REVERSE only takes one argument."); return false; } const std::string& listName = args[1]; // expand the variable std::vector<std::string> varArgsExpanded; - if (!this->GetList(varArgsExpanded, listName)) { + if (!GetList(varArgsExpanded, listName, status.GetMakefile())) { return true; } std::string value = cmJoin(cmReverseRange(varArgsExpanded), ";"); - this->Makefile->AddDefinition(listName, value); + status.GetMakefile().AddDefinition(listName, value); return true; } -bool cmListCommand::HandleRemoveDuplicatesCommand( - std::vector<std::string> const& args) +bool HandleRemoveDuplicatesCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { assert(args.size() >= 2); if (args.size() > 2) { - this->SetError("sub-command REMOVE_DUPLICATES only takes one argument."); + status.SetError("sub-command REMOVE_DUPLICATES only takes one argument."); return false; } const std::string& listName = args[1]; // expand the variable std::vector<std::string> varArgsExpanded; - if (!this->GetList(varArgsExpanded, listName)) { + if (!GetList(varArgsExpanded, listName, status.GetMakefile())) { return true; } @@ -539,12 +495,11 @@ bool cmListCommand::HandleRemoveDuplicatesCommand( std::vector<std::string>::const_iterator argsBegin = varArgsExpanded.begin(); std::string value = cmJoin(cmMakeRange(argsBegin, argsEnd), ";"); - this->Makefile->AddDefinition(listName, value); + status.GetMakefile().AddDefinition(listName, value); return true; } // Helpers for list(TRANSFORM <list> ...) -namespace { using transform_type = std::function<std::string(const std::string&)>; class transform_error : public std::runtime_error @@ -695,7 +650,8 @@ public: } this->Indexes.resize(size); - auto start = this->Start, step = this->Step; + auto start = this->Start; + auto step = this->Step; std::generate(this->Indexes.begin(), this->Indexes.end(), [&start, step]() -> int { auto r = start; @@ -759,13 +715,12 @@ public: private: cmStringReplaceHelper ReplaceHelper; }; -} -bool cmListCommand::HandleTransformCommand( - std::vector<std::string> const& args) +bool HandleTransformCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() < 3) { - this->SetError( + status.SetError( "sub-command TRANSFORM requires an action to be specified."); return false; } @@ -888,7 +843,7 @@ bool cmListCommand::HandleTransformCommand( if (descriptor == descriptors.end()) { std::ostringstream error; error << " sub-command TRANSFORM, " << args[index] << " invalid action."; - this->SetError(error.str()); + status.SetError(error.str()); return false; } @@ -898,7 +853,7 @@ bool cmListCommand::HandleTransformCommand( std::ostringstream error; error << "sub-command TRANSFORM, action " << descriptor->Name << " expects " << descriptor->Arity << " argument(s)."; - this->SetError(error.str()); + status.SetError(error.str()); return false; } @@ -911,16 +866,18 @@ bool cmListCommand::HandleTransformCommand( if (command.Name == "REPLACE") { try { - command.Action = - cm::make_unique<TransformReplace>(command.Arguments, this->Makefile); + command.Action = cm::make_unique<TransformReplace>( + command.Arguments, &status.GetMakefile()); } catch (const transform_error& e) { - this->SetError(e.what()); + status.SetError(e.what()); return false; } } - const std::string REGEX{ "REGEX" }, AT{ "AT" }, FOR{ "FOR" }, - OUTPUT_VARIABLE{ "OUTPUT_VARIABLE" }; + const std::string REGEX{ "REGEX" }; + const std::string AT{ "AT" }; + const std::string FOR{ "FOR" }; + const std::string OUTPUT_VARIABLE{ "OUTPUT_VARIABLE" }; // handle optional arguments while (args.size() > index) { @@ -929,15 +886,15 @@ bool cmListCommand::HandleTransformCommand( std::ostringstream error; error << "sub-command TRANSFORM, selector already specified (" << command.Selector->Tag << ")."; - this->SetError(error.str()); + status.SetError(error.str()); return false; } // REGEX selector if (args[index] == REGEX) { if (args.size() == ++index) { - this->SetError("sub-command TRANSFORM, selector REGEX expects " - "'regular expression' argument."); + status.SetError("sub-command TRANSFORM, selector REGEX expects " + "'regular expression' argument."); return false; } @@ -947,7 +904,7 @@ bool cmListCommand::HandleTransformCommand( error << "sub-command TRANSFORM, selector REGEX failed to compile " "regex \""; error << args[index] << "\"."; - this->SetError(error.str()); + status.SetError(error.str()); return false; } @@ -977,7 +934,7 @@ bool cmListCommand::HandleTransformCommand( } if (indexes.empty()) { - this->SetError( + status.SetError( "sub-command TRANSFORM, selector AT expects at least one " "numeric value."); return false; @@ -992,12 +949,15 @@ bool cmListCommand::HandleTransformCommand( // FOR selector if (args[index] == FOR) { if (args.size() <= ++index + 1) { - this->SetError("sub-command TRANSFORM, selector FOR expects, at least," - " two arguments."); + status.SetError( + "sub-command TRANSFORM, selector FOR expects, at least," + " two arguments."); return false; } - int start = 0, stop = 0, step = 1; + int start = 0; + int stop = 0; + int step = 1; bool valid = true; try { std::size_t pos; @@ -1018,8 +978,8 @@ bool cmListCommand::HandleTransformCommand( valid = false; } if (!valid) { - this->SetError("sub-command TRANSFORM, selector FOR expects, " - "at least, two numeric values."); + status.SetError("sub-command TRANSFORM, selector FOR expects, " + "at least, two numeric values."); return false; } // try to read a third numeric value for step @@ -1040,8 +1000,8 @@ bool cmListCommand::HandleTransformCommand( } if (step < 0) { - this->SetError("sub-command TRANSFORM, selector FOR expects " - "non negative numeric value for <step>."); + status.SetError("sub-command TRANSFORM, selector FOR expects " + "non negative numeric value for <step>."); } command.Selector = @@ -1053,8 +1013,8 @@ bool cmListCommand::HandleTransformCommand( // output variable if (args[index] == OUTPUT_VARIABLE) { if (args.size() == ++index) { - this->SetError("sub-command TRANSFORM, OUTPUT_VARIABLE " - "expects variable name argument."); + status.SetError("sub-command TRANSFORM, OUTPUT_VARIABLE " + "expects variable name argument."); return false; } @@ -1066,14 +1026,14 @@ bool cmListCommand::HandleTransformCommand( error << "sub-command TRANSFORM, '" << cmJoin(cmMakeRange(args).advance(index), " ") << "': unexpected argument(s)."; - this->SetError(error.str()); + status.SetError(error.str()); return false; } // expand the list variable std::vector<std::string> varArgsExpanded; - if (!this->GetList(varArgsExpanded, command.ListName)) { - this->Makefile->AddDefinition(command.OutputName, ""); + if (!GetList(varArgsExpanded, command.ListName, status.GetMakefile())) { + status.GetMakefile().AddDefinition(command.OutputName, ""); return true; } @@ -1085,12 +1045,12 @@ bool cmListCommand::HandleTransformCommand( try { command.Selector->Transform(varArgsExpanded, descriptor->Transform); } catch (const transform_error& e) { - this->SetError(e.what()); + status.SetError(e.what()); return false; } - this->Makefile->AddDefinition(command.OutputName, - cmJoin(varArgsExpanded, ";")); + status.GetMakefile().AddDefinition(command.OutputName, + cmJoin(varArgsExpanded, ";")); return true; } @@ -1170,11 +1130,12 @@ protected: bool descending; }; -bool cmListCommand::HandleSortCommand(std::vector<std::string> const& args) +bool HandleSortCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { assert(args.size() >= 2); if (args.size() > 8) { - this->SetError("sub-command SORT only takes up to six arguments."); + status.SetError("sub-command SORT only takes up to six arguments."); return false; } @@ -1191,7 +1152,7 @@ bool cmListCommand::HandleSortCommand(std::vector<std::string> const& args) if (sortCompare != cmStringSorter::Compare::UNINITIALIZED) { std::string error = cmStrCat(messageHint, "option \"", option, "\" has been specified multiple times."); - this->SetError(error); + status.SetError(error); return false; } if (argumentIndex < args.size()) { @@ -1204,19 +1165,19 @@ bool cmListCommand::HandleSortCommand(std::vector<std::string> const& args) std::string error = cmStrCat(messageHint, "value \"", argument, "\" for option \"", option, "\" is invalid."); - this->SetError(error); + status.SetError(error); return false; } } else { - this->SetError(cmStrCat(messageHint, "missing argument for option \"", - option, "\".")); + status.SetError(cmStrCat(messageHint, "missing argument for option \"", + option, "\".")); return false; } } else if (option == "CASE") { if (sortCaseSensitivity != cmStringSorter::CaseSensitivity::UNINITIALIZED) { - this->SetError(cmStrCat(messageHint, "option \"", option, - "\" has been specified multiple times.")); + status.SetError(cmStrCat(messageHint, "option \"", option, + "\" has been specified multiple times.")); return false; } if (argumentIndex < args.size()) { @@ -1226,21 +1187,21 @@ bool cmListCommand::HandleSortCommand(std::vector<std::string> const& args) } else if (argument == "INSENSITIVE") { sortCaseSensitivity = cmStringSorter::CaseSensitivity::INSENSITIVE; } else { - this->SetError(cmStrCat(messageHint, "value \"", argument, - "\" for option \"", option, - "\" is invalid.")); + status.SetError(cmStrCat(messageHint, "value \"", argument, + "\" for option \"", option, + "\" is invalid.")); return false; } } else { - this->SetError(cmStrCat(messageHint, "missing argument for option \"", - option, "\".")); + status.SetError(cmStrCat(messageHint, "missing argument for option \"", + option, "\".")); return false; } } else if (option == "ORDER") { if (sortOrder != cmStringSorter::Order::UNINITIALIZED) { - this->SetError(cmStrCat(messageHint, "option \"", option, - "\" has been specified multiple times.")); + status.SetError(cmStrCat(messageHint, "option \"", option, + "\" has been specified multiple times.")); return false; } if (argumentIndex < args.size()) { @@ -1250,18 +1211,18 @@ bool cmListCommand::HandleSortCommand(std::vector<std::string> const& args) } else if (argument == "DESCENDING") { sortOrder = cmStringSorter::Order::DESCENDING; } else { - this->SetError(cmStrCat(messageHint, "value \"", argument, - "\" for option \"", option, - "\" is invalid.")); + status.SetError(cmStrCat(messageHint, "value \"", argument, + "\" for option \"", option, + "\" is invalid.")); return false; } } else { - this->SetError(cmStrCat(messageHint, "missing argument for option \"", - option, "\".")); + status.SetError(cmStrCat(messageHint, "missing argument for option \"", + option, "\".")); return false; } } else { - this->SetError( + status.SetError( cmStrCat(messageHint, "option \"", option, "\" is unknown.")); return false; } @@ -1280,7 +1241,7 @@ bool cmListCommand::HandleSortCommand(std::vector<std::string> const& args) const std::string& listName = args[1]; // expand the variable std::vector<std::string> varArgsExpanded; - if (!this->GetList(varArgsExpanded, listName)) { + if (!GetList(varArgsExpanded, listName, status.GetMakefile())) { return true; } @@ -1294,17 +1255,18 @@ bool cmListCommand::HandleSortCommand(std::vector<std::string> const& args) } std::string value = cmJoin(varArgsExpanded, ";"); - this->Makefile->AddDefinition(listName, value); + status.GetMakefile().AddDefinition(listName, value); return true; } -bool cmListCommand::HandleSublistCommand(std::vector<std::string> const& args) +bool HandleSublistCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() != 5) { std::ostringstream error; error << "sub-command SUBLIST requires four arguments (" << args.size() - 1 << " found)."; - this->SetError(error.str()); + status.SetError(error.str()); return false; } @@ -1313,8 +1275,9 @@ bool cmListCommand::HandleSublistCommand(std::vector<std::string> const& args) // expand the variable std::vector<std::string> varArgsExpanded; - if (!this->GetList(varArgsExpanded, listName) || varArgsExpanded.empty()) { - this->Makefile->AddDefinition(variableName, ""); + if (!GetList(varArgsExpanded, listName, status.GetMakefile()) || + varArgsExpanded.empty()) { + status.GetMakefile().AddDefinition(variableName, ""); return true; } @@ -1327,13 +1290,13 @@ bool cmListCommand::HandleSublistCommand(std::vector<std::string> const& args) std::ostringstream error; error << "begin index: " << start << " is out of range 0 - " << varArgsExpanded.size() - 1; - this->SetError(error.str()); + status.SetError(error.str()); return false; } if (length < -1) { std::ostringstream error; error << "length: " << length << " should be -1 or greater"; - this->SetError(error.str()); + status.SetError(error.str()); return false; } @@ -1343,22 +1306,24 @@ bool cmListCommand::HandleSublistCommand(std::vector<std::string> const& args) : size_type(start + length); std::vector<std::string> sublist(varArgsExpanded.begin() + start, varArgsExpanded.begin() + end); - this->Makefile->AddDefinition(variableName, cmJoin(sublist, ";")); + status.GetMakefile().AddDefinition(variableName, cmJoin(sublist, ";")); return true; } -bool cmListCommand::HandleRemoveAtCommand(std::vector<std::string> const& args) +bool HandleRemoveAtCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() < 3) { - this->SetError("sub-command REMOVE_AT requires at least " - "two arguments."); + status.SetError("sub-command REMOVE_AT requires at least " + "two arguments."); return false; } const std::string& listName = args[1]; // expand the variable std::vector<std::string> varArgsExpanded; - if (!this->GetList(varArgsExpanded, listName) || varArgsExpanded.empty()) { + if (!GetList(varArgsExpanded, listName, status.GetMakefile()) || + varArgsExpanded.empty()) { std::ostringstream str; str << "index: "; for (size_t i = 1; i < args.size(); ++i) { @@ -1368,7 +1333,7 @@ bool cmListCommand::HandleRemoveAtCommand(std::vector<std::string> const& args) } } str << " out of range (0, 0)"; - this->SetError(str.str()); + status.SetError(str.str()); return false; } @@ -1384,7 +1349,7 @@ bool cmListCommand::HandleRemoveAtCommand(std::vector<std::string> const& args) std::ostringstream str; str << "index: " << item << " out of range (-" << nitem << ", " << nitem - 1 << ")"; - this->SetError(str.str()); + status.SetError(str.str()); return false; } removed.push_back(static_cast<size_t>(item)); @@ -1400,24 +1365,26 @@ bool cmListCommand::HandleRemoveAtCommand(std::vector<std::string> const& args) std::vector<std::string>::const_iterator argsBegin = varArgsExpanded.begin(); std::string value = cmJoin(cmMakeRange(argsBegin, argsEnd), ";"); - this->Makefile->AddDefinition(listName, value); + status.GetMakefile().AddDefinition(listName, value); return true; } -bool cmListCommand::HandleFilterCommand(std::vector<std::string> const& args) +bool HandleFilterCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() < 2) { - this->SetError("sub-command FILTER requires a list to be specified."); + status.SetError("sub-command FILTER requires a list to be specified."); return false; } if (args.size() < 3) { - this->SetError("sub-command FILTER requires an operator to be specified."); + status.SetError( + "sub-command FILTER requires an operator to be specified."); return false; } if (args.size() < 4) { - this->SetError("sub-command FILTER requires a mode to be specified."); + status.SetError("sub-command FILTER requires a mode to be specified."); return false; } @@ -1428,28 +1395,29 @@ bool cmListCommand::HandleFilterCommand(std::vector<std::string> const& args) } else if (op == "EXCLUDE") { includeMatches = false; } else { - this->SetError("sub-command FILTER does not recognize operator " + op); + status.SetError("sub-command FILTER does not recognize operator " + op); return false; } const std::string& listName = args[1]; // expand the variable std::vector<std::string> varArgsExpanded; - if (!this->GetList(varArgsExpanded, listName)) { + if (!GetList(varArgsExpanded, listName, status.GetMakefile())) { return true; } const std::string& mode = args[3]; if (mode == "REGEX") { if (args.size() != 5) { - this->SetError("sub-command FILTER, mode REGEX " - "requires five arguments."); + status.SetError("sub-command FILTER, mode REGEX " + "requires five arguments."); return false; } - return this->FilterRegex(args, includeMatches, listName, varArgsExpanded); + return FilterRegex(args, includeMatches, listName, varArgsExpanded, + status); } - this->SetError("sub-command FILTER does not recognize mode " + mode); + status.SetError("sub-command FILTER does not recognize mode " + mode); return false; } @@ -1472,19 +1440,18 @@ private: const bool includeMatches; }; -bool cmListCommand::FilterRegex(std::vector<std::string> const& args, - bool includeMatches, - std::string const& listName, - std::vector<std::string>& varArgsExpanded) +bool FilterRegex(std::vector<std::string> const& args, bool includeMatches, + std::string const& listName, + std::vector<std::string>& varArgsExpanded, + cmExecutionStatus& status) { const std::string& pattern = args[4]; cmsys::RegularExpression regex(pattern); if (!regex.is_valid()) { - std::string error = "sub-command FILTER, mode REGEX "; - error += "failed to compile regex \""; - error += pattern; - error += "\"."; - this->SetError(error); + std::string error = + cmStrCat("sub-command FILTER, mode REGEX failed to compile regex \"", + pattern, "\"."); + status.SetError(error); return false; } @@ -1494,6 +1461,39 @@ bool cmListCommand::FilterRegex(std::vector<std::string> const& args, std::remove_if(argsBegin, argsEnd, MatchesRegex(regex, includeMatches)); std::string value = cmJoin(cmMakeRange(argsBegin, newArgsEnd), ";"); - this->Makefile->AddDefinition(listName, value); + status.GetMakefile().AddDefinition(listName, value); return true; } + +} // namespace + +bool cmListCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) +{ + if (args.size() < 2) { + status.SetError("must be called with at least two arguments."); + return false; + } + + static cmSubcommandTable const subcommand{ + { "LENGTH"_s, HandleLengthCommand }, + { "GET"_s, HandleGetCommand }, + { "APPEND"_s, HandleAppendCommand }, + { "PREPEND"_s, HandlePrependCommand }, + { "POP_BACK"_s, HandlePopBackCommand }, + { "POP_FRONT"_s, HandlePopFrontCommand }, + { "FIND"_s, HandleFindCommand }, + { "INSERT"_s, HandleInsertCommand }, + { "JOIN"_s, HandleJoinCommand }, + { "REMOVE_AT"_s, HandleRemoveAtCommand }, + { "REMOVE_ITEM"_s, HandleRemoveItemCommand }, + { "REMOVE_DUPLICATES"_s, HandleRemoveDuplicatesCommand }, + { "TRANSFORM"_s, HandleTransformCommand }, + { "SORT"_s, HandleSortCommand }, + { "SUBLIST"_s, HandleSublistCommand }, + { "REVERSE"_s, HandleReverseCommand }, + { "FILTER"_s, HandleFilterCommand }, + }; + + return subcommand(args[0], args, status); +} diff --git a/Source/cmListCommand.h b/Source/cmListCommand.h index 70c7f4e..274d9fd 100644 --- a/Source/cmListCommand.h +++ b/Source/cmListCommand.h @@ -8,58 +8,13 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmListCommand +/** * \brief Common list operations * */ -class cmListCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmListCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; - -protected: - bool HandleLengthCommand(std::vector<std::string> const& args); - bool HandleGetCommand(std::vector<std::string> const& args); - bool HandleAppendCommand(std::vector<std::string> const& args); - bool HandlePrependCommand(std::vector<std::string> const& args); - bool HandlePopBackCommand(std::vector<std::string> const& args); - bool HandlePopFrontCommand(std::vector<std::string> const& args); - bool HandleFindCommand(std::vector<std::string> const& args); - bool HandleInsertCommand(std::vector<std::string> const& args); - bool HandleJoinCommand(std::vector<std::string> const& args); - bool HandleRemoveAtCommand(std::vector<std::string> const& args); - bool HandleRemoveItemCommand(std::vector<std::string> const& args); - bool HandleRemoveDuplicatesCommand(std::vector<std::string> const& args); - bool HandleTransformCommand(std::vector<std::string> const& args); - bool HandleSortCommand(std::vector<std::string> const& args); - bool HandleSublistCommand(std::vector<std::string> const& args); - bool HandleReverseCommand(std::vector<std::string> const& args); - bool HandleFilterCommand(std::vector<std::string> const& args); - bool FilterRegex(std::vector<std::string> const& args, bool includeMatches, - std::string const& listName, - std::vector<std::string>& varArgsExpanded); - - bool GetList(std::vector<std::string>& list, const std::string& var); - bool GetListString(std::string& listString, const std::string& var); -}; +bool cmListCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx index 7ef475a..ff3ecd9 100644 --- a/Source/cmListFileCache.cxx +++ b/Source/cmListFileCache.cxx @@ -483,8 +483,7 @@ std::vector<BT<std::string>> ExpandListWithBacktrace( std::string const& list, cmListFileBacktrace const& bt) { std::vector<BT<std::string>> result; - std::vector<std::string> tmp; - cmExpandList(list, tmp); + std::vector<std::string> tmp = cmExpandedList(list); result.reserve(tmp.size()); for (std::string& i : tmp) { result.emplace_back(std::move(i), bt); diff --git a/Source/cmLoadCommandCommand.cxx b/Source/cmLoadCommandCommand.cxx index 5ae660a..f650eb1 100644 --- a/Source/cmLoadCommandCommand.cxx +++ b/Source/cmLoadCommandCommand.cxx @@ -14,13 +14,14 @@ #include "cmCPluginAPI.cxx" #include "cmCPluginAPI.h" +#include "cmCommand.h" #include "cmDynamicLoader.h" +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmState.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" -class cmExecutionStatus; - #ifdef __QNX__ # include <malloc.h> /* for malloc/free on QNX */ #endif @@ -174,8 +175,8 @@ bool cmLoadedCommand::InitialPass(std::vector<std::string> const& args, } // namespace // cmLoadCommandCommand -bool cmLoadCommandCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmLoadCommandCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.empty()) { return true; @@ -183,16 +184,14 @@ bool cmLoadCommandCommand::InitialPass(std::vector<std::string> const& args, // Construct a variable to report what file was loaded, if any. // Start by removing the definition in case of failure. - std::string reportVar = "CMAKE_LOADED_COMMAND_"; - reportVar += args[0]; - this->Makefile->RemoveDefinition(reportVar); + std::string reportVar = cmStrCat("CMAKE_LOADED_COMMAND_", args[0]); + status.GetMakefile().RemoveDefinition(reportVar); // the file must exist - std::string moduleName = - this->Makefile->GetRequiredDefinition("CMAKE_SHARED_MODULE_PREFIX"); - moduleName += "cm" + args[0]; - moduleName += - this->Makefile->GetRequiredDefinition("CMAKE_SHARED_MODULE_SUFFIX"); + std::string moduleName = cmStrCat( + status.GetMakefile().GetRequiredDefinition("CMAKE_SHARED_MODULE_PREFIX"), + "cm", args[0], + status.GetMakefile().GetRequiredDefinition("CMAKE_SHARED_MODULE_SUFFIX")); // search for the file std::vector<std::string> path; @@ -210,7 +209,7 @@ bool cmLoadCommandCommand::InitialPass(std::vector<std::string> const& args, if (fullPath.empty()) { std::ostringstream e; e << "Attempt to load command failed from file \"" << moduleName << "\""; - this->SetError(e.str()); + status.SetError(e.str()); return false; } @@ -218,40 +217,38 @@ bool cmLoadCommandCommand::InitialPass(std::vector<std::string> const& args, cmsys::DynamicLoader::LibraryHandle lib = cmDynamicLoader::OpenLibrary(fullPath.c_str()); if (!lib) { - std::string err = "Attempt to load the library "; - err += fullPath + " failed."; + std::string err = + cmStrCat("Attempt to load the library ", fullPath, " failed."); const char* error = cmsys::DynamicLoader::LastError(); if (error) { err += " Additional error info is:\n"; err += error; } - this->SetError(err); + status.SetError(err); return false; } // Report what file was loaded for this command. - this->Makefile->AddDefinition(reportVar, fullPath); + status.GetMakefile().AddDefinition(reportVar, fullPath); // find the init function std::string initFuncName = args[0] + "Init"; CM_INIT_FUNCTION initFunction = reinterpret_cast<CM_INIT_FUNCTION>( cmsys::DynamicLoader::GetSymbolAddress(lib, initFuncName)); if (!initFunction) { - initFuncName = "_"; - initFuncName += args[0]; - initFuncName += "Init"; + initFuncName = cmStrCat('_', args[0], "Init"); initFunction = reinterpret_cast<CM_INIT_FUNCTION>( cmsys::DynamicLoader::GetSymbolAddress(lib, initFuncName)); } // if the symbol is found call it to set the name on the // function blocker if (initFunction) { - this->Makefile->GetState()->AddScriptedCommand( + status.GetMakefile().GetState()->AddScriptedCommand( args[0], cmLegacyCommandWrapper(cm::make_unique<cmLoadedCommand>(initFunction))); return true; } - this->SetError("Attempt to load command failed. " - "No init function found."); + status.SetError("Attempt to load command failed. " + "No init function found."); return false; } diff --git a/Source/cmLoadCommandCommand.h b/Source/cmLoadCommandCommand.h index d81cefb..f5fd754 100644 --- a/Source/cmLoadCommandCommand.h +++ b/Source/cmLoadCommandCommand.h @@ -8,21 +8,9 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -class cmLoadCommandCommand : public cmCommand -{ -public: - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmLoadCommandCommand>(); - } - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; +bool cmLoadCommandCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmLocalCommonGenerator.cxx b/Source/cmLocalCommonGenerator.cxx index 75ad2a6..7c36bdc 100644 --- a/Source/cmLocalCommonGenerator.cxx +++ b/Source/cmLocalCommonGenerator.cxx @@ -8,6 +8,7 @@ #include "cmGeneratorTarget.h" #include "cmMakefile.h" #include "cmOutputConverter.h" +#include "cmStringAlgorithms.h" class cmGlobalGenerator; @@ -51,9 +52,9 @@ std::string cmLocalCommonGenerator::GetTargetFortranFlags( this->Makefile->GetSafeDefinition("CMAKE_Fortran_MODDIR_DEFAULT"); } if (!mod_dir.empty()) { - std::string modflag = - this->Makefile->GetRequiredDefinition("CMAKE_Fortran_MODDIR_FLAG"); - modflag += mod_dir; + std::string modflag = cmStrCat( + this->Makefile->GetRequiredDefinition("CMAKE_Fortran_MODDIR_FLAG"), + mod_dir); this->AppendFlags(flags, modflag); } @@ -65,8 +66,9 @@ std::string cmLocalCommonGenerator::GetTargetFortranFlags( std::vector<std::string> includes; this->GetIncludeDirectories(includes, target, "C", config); for (std::string const& id : includes) { - std::string flg = modpath_flag; - flg += this->ConvertToOutputFormat(id, cmOutputConverter::SHELL); + std::string flg = + cmStrCat(modpath_flag, + this->ConvertToOutputFormat(id, cmOutputConverter::SHELL)); this->AppendFlags(flags, flg); } } diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 159791e..7177694 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -18,6 +18,7 @@ #include "cmRulePlaceholderExpander.h" #include "cmSourceFile.h" #include "cmSourceFileLocation.h" +#include "cmSourceFileLocationKind.h" #include "cmState.h" #include "cmStateDirectory.h" #include "cmStateTypes.h" @@ -26,6 +27,7 @@ #include "cmTarget.h" #include "cmTestGenerator.h" #include "cmVersion.h" +#include "cm_string_view.hxx" #include "cmake.h" #include "cmsys/RegularExpression.hxx" @@ -36,6 +38,7 @@ #include <algorithm> #include <assert.h> +#include <functional> #include <initializer_list> #include <iterator> #include <memory> @@ -283,9 +286,9 @@ void cmLocalGenerator::GenerateTestFiles() const std::string& config = this->Makefile->GetConfigurations(configurationTypes, false); - std::string file = this->StateSnapshot.GetDirectory().GetCurrentBinary(); - file += "/"; - file += "CTestTestfile.cmake"; + std::string file = + cmStrCat(this->StateSnapshot.GetDirectory().GetCurrentBinary(), + "/CTestTestfile.cmake"); cmGeneratedFileStream fout(file); fout.SetCopyIfDifferent(true); @@ -310,8 +313,7 @@ void cmLocalGenerator::GenerateTestFiles() const char* testIncludeFiles = this->Makefile->GetProperty("TEST_INCLUDE_FILES"); if (testIncludeFiles) { - std::vector<std::string> includesList; - cmExpandList(testIncludeFiles, includesList); + std::vector<std::string> includesList = cmExpandedList(testIncludeFiles); for (std::string const& i : includesList) { fout << "include(\"" << i << "\")" << std::endl; } @@ -901,8 +903,7 @@ void cmLocalGenerator::AddCompileOptions(std::string& flags, ge.Parse(jmcExprGen); std::string isJMCEnabled = cge->Evaluate(this, config); if (cmIsOn(isJMCEnabled)) { - std::vector<std::string> optVec; - cmExpandList(jmc, optVec); + std::vector<std::string> optVec = cmExpandedList(jmc); this->AppendCompileOptions(flags, optVec); } } @@ -996,8 +997,7 @@ std::vector<BT<std::string>> cmLocalGenerator::GetIncludeDirectoriesImplicit( // directly. In this case adding -I/usr/include can hide SDK headers so we // must still exclude it. if ((lang == "C" || lang == "CXX" || lang == "CUDA") && - std::find(impDirVec.begin(), impDirVec.end(), "/usr/include") == - impDirVec.end() && + !cmContains(impDirVec, "/usr/include") && std::find_if(impDirVec.begin(), impDirVec.end(), [](std::string const& d) { return cmHasLiteralSuffix(d, "/usr/include"); @@ -1018,15 +1018,13 @@ std::vector<BT<std::string>> cmLocalGenerator::GetIncludeDirectoriesImplicit( &lang](std::string const& dir) { return ( // Do not exclude directories that are not in an excluded set. - ((implicitSet.find(cmSystemTools::GetRealPath(dir)) == - implicitSet.end()) && - (implicitExclude.find(dir) == implicitExclude.end())) + ((!cmContains(implicitSet, cmSystemTools::GetRealPath(dir))) && + (!cmContains(implicitExclude, dir))) // Do not exclude entries of the CPATH environment variable even though // they are implicitly searched by the compiler. They are meant to be // user-specified directories that can be re-ordered or converted to // -isystem without breaking real compiler builtin headers. - || ((lang == "C" || lang == "CXX") && - (this->EnvCPATH.find(dir) != this->EnvCPATH.end()))); + || ((lang == "C" || lang == "CXX") && cmContains(this->EnvCPATH, dir))); }; // Get the target-specific include directories. @@ -1036,8 +1034,8 @@ std::vector<BT<std::string>> cmLocalGenerator::GetIncludeDirectoriesImplicit( // Support putting all the in-project include directories first if // it is requested by the project. if (this->Makefile->IsOn("CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE")) { - std::string const &topSourceDir = this->GetState()->GetSourceDirectory(), - &topBinaryDir = this->GetState()->GetBinaryDirectory(); + std::string const& topSourceDir = this->GetState()->GetSourceDirectory(); + std::string const& topBinaryDir = this->GetState()->GetBinaryDirectory(); for (BT<std::string> const& udr : userDirs) { // Emit this directory only if it is a subdirectory of the // top-level source or binary tree. @@ -1073,8 +1071,7 @@ std::vector<BT<std::string>> cmLocalGenerator::GetIncludeDirectoriesImplicit( if (!stripImplicitDirs) { // Append implicit directories that were requested by the user only for (BT<std::string> const& udr : userDirs) { - if (implicitSet.find(cmSystemTools::GetRealPath(udr.Value)) != - implicitSet.end()) { + if (cmContains(implicitSet, cmSystemTools::GetRealPath(udr.Value))) { emitBT(udr); } } @@ -1164,12 +1161,10 @@ void cmLocalGenerator::GetTargetFlags( CM_FALLTHROUGH; case cmStateEnums::SHARED_LIBRARY: { if (linkLanguage != "Swift") { - linkFlags = this->Makefile->GetSafeDefinition(libraryLinkVariable); - linkFlags += " "; + linkFlags = cmStrCat( + this->Makefile->GetSafeDefinition(libraryLinkVariable), ' '); if (!buildType.empty()) { - std::string build = libraryLinkVariable; - build += "_"; - build += buildType; + std::string build = cmStrCat(libraryLinkVariable, '_', buildType); linkFlags += this->Makefile->GetSafeDefinition(build); linkFlags += " "; } @@ -1351,8 +1346,7 @@ static std::string GetFrameworkFlags(const std::string& lang, // will already have added a -F for the framework for (std::string const& include : includes) { if (lg->GetGlobalGenerator()->NameResolvesToFramework(include)) { - std::string frameworkDir = include; - frameworkDir += "/../"; + std::string frameworkDir = cmStrCat(include, "/../"); frameworkDir = cmSystemTools::CollapseFullPath(frameworkDir); emitted.insert(frameworkDir); } @@ -1572,6 +1566,17 @@ void cmLocalGenerator::AddLanguageFlags(std::string& flags, this->AddConfigVariableFlags(flags, cmStrCat("CMAKE_", lang, "_FLAGS"), config); + if (lang == "Swift") { + if (const char* v = target->GetProperty("Swift_LANGUAGE_VERSION")) { + if (cmSystemTools::VersionCompare( + cmSystemTools::OP_GREATER_EQUAL, + this->Makefile->GetDefinition("CMAKE_Swift_COMPILER_VERSION"), + "4.2")) { + this->AppendFlags(flags, "-swift-version " + std::string(v)); + } + } + } + // Add MSVC runtime library flags. This is activated by the presence // of a default selection whether or not it is overridden by a property. const char* msvcRuntimeLibraryDefault = @@ -1728,9 +1733,8 @@ bool cmLocalGenerator::GetRealDependency(const std::string& inName, // Treat the name as relative to the source directory in which it // was given. - dep = this->StateSnapshot.GetDirectory().GetCurrentSource(); - dep += "/"; - dep += inName; + dep = cmStrCat(this->StateSnapshot.GetDirectory().GetCurrentSource(), '/', + inName); return true; } @@ -1776,8 +1780,7 @@ void cmLocalGenerator::AddCompilerRequirementFlag( "CMAKE_" + lang + "_EXTENSION_COMPILE_OPTION"; if (const char* opt = target->Target->GetMakefile()->GetDefinition(option_flag)) { - std::vector<std::string> optVec; - cmExpandList(opt, optVec); + std::vector<std::string> optVec = cmExpandedList(opt); for (std::string const& i : optVec) { this->AppendFlagEscape(flags, i); } @@ -1805,8 +1808,7 @@ void cmLocalGenerator::AddCompilerRequirementFlag( "does not know the compile flags to use to enable it."; this->IssueMessage(MessageType::FATAL_ERROR, e.str()); } else { - std::vector<std::string> optVec; - cmExpandList(opt, optVec); + std::vector<std::string> optVec = cmExpandedList(opt); for (std::string const& i : optVec) { this->AppendFlagEscape(flags, i); } @@ -1866,8 +1868,7 @@ void cmLocalGenerator::AddCompilerRequirementFlag( std::string const& opt = target->Target->GetMakefile()->GetRequiredDefinition(option_flag); - std::vector<std::string> optVec; - cmExpandList(opt, optVec); + std::vector<std::string> optVec = cmExpandedList(opt); for (std::string const& i : optVec) { this->AppendFlagEscape(flags, i); } @@ -1883,8 +1884,7 @@ void cmLocalGenerator::AddCompilerRequirementFlag( if (const char* opt = target->Target->GetMakefile()->GetDefinition(option_flag)) { - std::vector<std::string> optVec; - cmExpandList(opt, optVec); + std::vector<std::string> optVec = cmExpandedList(opt); for (std::string const& i : optVec) { this->AppendFlagEscape(flags, i); } @@ -2079,8 +2079,7 @@ void cmLocalGenerator::AddPositionIndependentFlags(std::string& flags, cmStrCat("CMAKE_", lang, "_COMPILE_OPTIONS_PIC")); } if (!picFlags.empty()) { - std::vector<std::string> options; - cmExpandList(picFlags, options); + std::vector<std::string> options = cmExpandedList(picFlags); for (std::string const& o : options) { this->AppendFlagEscape(flags, o); } @@ -2127,6 +2126,82 @@ void cmLocalGenerator::AppendFlagEscape(std::string& flags, this->AppendFlags(flags, this->EscapeForShell(rawFlag)); } +void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target, + const std::string& config) +{ + const std::string lang = target->GetLinkerLanguage(config); + const std::string buildType = cmSystemTools::UpperCase(config); + const std::string pchSource = target->GetPchSource(config, lang); + const std::string pchHeader = target->GetPchHeader(config, lang); + + if (pchSource.empty() || pchHeader.empty()) { + return; + } + + const std::string createOptVar = + cmStrCat("CMAKE_", lang, "_COMPILE_OPTIONS_CREATE_PCH"); + std::string createOptionList = + this->Makefile->GetSafeDefinition(createOptVar); + + const std::string useOptVar = + cmStrCat("CMAKE_", lang, "_COMPILE_OPTIONS_USE_PCH"); + std::string useOptionList = this->Makefile->GetSafeDefinition(useOptVar); + + const std::string pchExtension = + this->Makefile->GetSafeDefinition("CMAKE_PCH_EXTENSION"); + + if (createOptionList.empty() || useOptionList.empty() || + pchExtension.empty()) { + return; + } + + auto pch_sf = this->Makefile->GetOrCreateSource( + pchSource, false, cmSourceFileLocationKind::Known); + std::string pchFile = pchHeader; + + if (!this->GetGlobalGenerator()->IsXcode()) { + // Exclude the pch files from linking + if (this->Makefile->IsOn("CMAKE_LINK_PCH")) { + cmSystemTools::ReplaceString(pchFile, (lang == "C" ? ".h" : ".hxx"), + pchExtension); + pch_sf->SetProperty("OBJECT_OUTPUTS", pchFile.c_str()); + } else { + pchFile += pchExtension; + pch_sf->SetProperty("PCH_EXTENSION", pchExtension.c_str()); + } + + target->AddSource(pchSource, true); + + for (auto& str : { std::ref(useOptionList), std::ref(createOptionList) }) { + cmSystemTools::ReplaceString(str, "<PCH_HEADER>", pchHeader); + cmSystemTools::ReplaceString(str, "<PCH_FILE>", pchFile); + } + } + + pch_sf->SetProperty("COMPILE_OPTIONS", createOptionList.c_str()); + + std::vector<cmSourceFile*> sources; + target->GetSourceFiles(sources, buildType); + for (cmSourceFile* sf : sources) { + if (pch_sf == sf || sf->GetLanguage() != lang) { + continue; + } + + if (sf->GetPropertyAsBool("SKIP_PRECOMPILE_HEADERS")) { + if (this->GetGlobalGenerator()->IsXcode()) { + sf->SetProperty("COMPILE_DEFINITIONS", + "CMAKE_SKIP_PRECOMPILE_HEADERS"); + } + continue; + } + + if (!this->GetGlobalGenerator()->IsXcode()) { + sf->SetProperty("OBJECT_DEPENDS", pchFile.c_str()); + sf->SetProperty("COMPILE_OPTIONS", useOptionList.c_str()); + } + } +} + void cmLocalGenerator::AppendIPOLinkerFlags(std::string& flags, cmGeneratorTarget* target, const std::string& config, @@ -2151,8 +2226,7 @@ void cmLocalGenerator::AppendIPOLinkerFlags(std::string& flags, return; } - std::vector<std::string> flagsList; - cmExpandList(rawFlagsList, flagsList); + std::vector<std::string> flagsList = cmExpandedList(rawFlagsList); for (std::string const& o : flagsList) { this->AppendFlagEscape(flags, o); } @@ -2187,8 +2261,7 @@ void cmLocalGenerator::AppendPositionIndependentLinkerFlags( return; } - std::vector<std::string> flagsList; - cmExpandList(pieFlags, flagsList); + std::vector<std::string> flagsList = cmExpandedList(pieFlags); for (const auto& flag : flagsList) { this->AppendFlagEscape(flags, flag); } @@ -2204,8 +2277,7 @@ void cmLocalGenerator::AppendCompileOptions(std::string& options, } // Expand the list of options. - std::vector<std::string> options_vec; - cmExpandList(options_list, options_vec); + std::vector<std::string> options_vec = cmExpandedList(options_list); this->AppendCompileOptions(options, options_vec, regex); } @@ -2239,8 +2311,7 @@ void cmLocalGenerator::AppendIncludeDirectories( } // Expand the list of includes. - std::vector<std::string> includes_vec; - cmExpandList(includes_list, includes_vec); + std::vector<std::string> includes_vec = cmExpandedList(includes_list); this->AppendIncludeDirectories(includes, includes_vec, sourceFile); } @@ -2367,8 +2438,7 @@ void cmLocalGenerator::AppendFeatureOptions(std::string& flags, const char* optionList = this->Makefile->GetDefinition( cmStrCat("CMAKE_", lang, "_COMPILE_OPTIONS_", feature)); if (optionList != nullptr) { - std::vector<std::string> options; - cmExpandList(optionList, options); + std::vector<std::string> options = cmExpandedList(optionList); for (std::string const& o : options) { this->AppendFlagEscape(flags, o); } @@ -2523,8 +2593,8 @@ static bool cmLocalGeneratorShortenObjectName(std::string& objName, objName.find('/', objName.size() - max_len + 32); if (pos != std::string::npos) { cmCryptoHash md5(cmCryptoHash::AlgoMD5); - std::string md5name = md5.HashString(objName.substr(0, pos)); - md5name += objName.substr(pos); + std::string md5name = cmStrCat(md5.HashString(objName.substr(0, pos)), + cm::string_view(objName).substr(pos)); objName = md5name; // The object name is now short enough. @@ -2724,6 +2794,11 @@ std::string cmLocalGenerator::GetObjectFileNameWithoutTarget( } } + const char* pchExtension = source.GetProperty("PCH_EXTENSION"); + if (pchExtension) { + customOutputExtension = pchExtension; + } + // Remove the source extension if it is to be replaced. if (replaceExt || customOutputExtension) { keptSourceExtension = false; diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 455e491..f63fe0f 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -124,6 +124,8 @@ public: virtual void AppendFlags(std::string& flags, const char* newFlags) const; virtual void AppendFlagEscape(std::string& flags, const std::string& rawFlag) const; + void AddPchDependencies(cmGeneratorTarget* target, + const std::string& config); void AppendIPOLinkerFlags(std::string& flags, cmGeneratorTarget* target, const std::string& config, const std::string& lang); diff --git a/Source/cmLocalGhsMultiGenerator.cxx b/Source/cmLocalGhsMultiGenerator.cxx index bf25f98..b00dda1 100644 --- a/Source/cmLocalGhsMultiGenerator.cxx +++ b/Source/cmLocalGhsMultiGenerator.cxx @@ -7,6 +7,7 @@ #include "cmGlobalGenerator.h" #include "cmSourceFile.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include <algorithm> @@ -23,9 +24,7 @@ cmLocalGhsMultiGenerator::~cmLocalGhsMultiGenerator() = default; std::string cmLocalGhsMultiGenerator::GetTargetDirectory( cmGeneratorTarget const* target) const { - std::string dir; - dir += target->GetName(); - dir += ".dir"; + std::string dir = cmStrCat(target->GetName(), ".dir"); return dir; } @@ -63,11 +62,8 @@ void cmLocalGhsMultiGenerator::ComputeObjectFilenames( std::map<cmSourceFile const*, std::string>& mapping, cmGeneratorTarget const* gt) { - std::string dir_max; - dir_max += this->GetCurrentBinaryDirectory(); - dir_max += "/"; - dir_max += this->GetTargetDirectory(gt); - dir_max += "/"; + std::string dir_max = cmStrCat(this->GetCurrentBinaryDirectory(), '/', + this->GetTargetDirectory(gt), '/'); // Count the number of object files with each name. Note that // filesystem may not be case sensitive. @@ -75,9 +71,10 @@ void cmLocalGhsMultiGenerator::ComputeObjectFilenames( for (auto const& si : mapping) { cmSourceFile const* sf = si.first; - std::string objectNameLower = cmSystemTools::LowerCase( - cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath())); - objectNameLower += this->GlobalGenerator->GetLanguageOutputExtension(*sf); + std::string objectNameLower = cmStrCat( + cmSystemTools::LowerCase( + cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath())), + this->GlobalGenerator->GetLanguageOutputExtension(*sf)); counts[objectNameLower] += 1; } @@ -85,9 +82,9 @@ void cmLocalGhsMultiGenerator::ComputeObjectFilenames( // object name computation. for (auto& si : mapping) { cmSourceFile const* sf = si.first; - std::string objectName = - cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath()); - objectName += this->GlobalGenerator->GetLanguageOutputExtension(*sf); + std::string objectName = cmStrCat( + cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath()), + this->GlobalGenerator->GetLanguageOutputExtension(*sf)); if (counts[cmSystemTools::LowerCase(objectName)] > 1) { const_cast<cmGeneratorTarget*>(gt)->AddExplicitObjectName(sf); diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx index ec35551..e28b876 100644 --- a/Source/cmLocalNinjaGenerator.cxx +++ b/Source/cmLocalNinjaGenerator.cxx @@ -103,8 +103,7 @@ void cmLocalNinjaGenerator::Generate() std::string cmLocalNinjaGenerator::GetTargetDirectory( cmGeneratorTarget const* target) const { - std::string dir = "CMakeFiles/"; - dir += target->GetName(); + std::string dir = cmStrCat("CMakeFiles/", target->GetName()); #if defined(__VMS) dir += "_dir"; #else @@ -222,8 +221,7 @@ void cmLocalNinjaGenerator::WritePools(std::ostream& os) if (jobpools) { cmGlobalNinjaGenerator::WriteComment( os, "Pools defined by global property JOB_POOLS"); - std::vector<std::string> pools; - cmExpandList(jobpools, pools); + std::vector<std::string> pools = cmExpandedList(jobpools); for (std::string const& pool : pools) { const std::string::size_type eq = pool.find('='); unsigned int jobs; @@ -301,8 +299,7 @@ std::string cmLocalNinjaGenerator::WriteCommandScript( if (target) { scriptPath = target->GetSupportDirectory(); } else { - scriptPath = this->GetCurrentBinaryDirectory(); - scriptPath += "/CMakeFiles"; + scriptPath = cmStrCat(this->GetCurrentBinaryDirectory(), "/CMakeFiles"); } cmSystemTools::MakeDirectory(scriptPath); scriptPath += '/'; @@ -556,7 +553,8 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatements() ++j; for (; j != i->second.end(); ++j) { - std::vector<std::string> jDeps, depsIntersection; + std::vector<std::string> jDeps; + std::vector<std::string> depsIntersection; this->GetGlobalNinjaGenerator()->AppendTargetDependsClosure(*j, jDeps); std::sort(jDeps.begin(), jDeps.end()); std::set_intersection(ccTargetDeps.begin(), ccTargetDeps.end(), diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index b4ed033..106e506 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -164,11 +164,8 @@ void cmLocalUnixMakefileGenerator3::GetLocalObjectFiles( gt->GetObjectSources( objectSources, this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE")); // Compute full path to object file directory for this target. - std::string dir; - dir += gt->LocalGenerator->GetCurrentBinaryDirectory(); - dir += "/"; - dir += this->GetTargetDirectory(gt); - dir += "/"; + std::string dir = cmStrCat(gt->LocalGenerator->GetCurrentBinaryDirectory(), + '/', this->GetTargetDirectory(gt), '/'); // Compute the name of each object file. for (cmSourceFile const* sf : objectSources) { bool hasSourceExtension = true; @@ -365,14 +362,12 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefileTargets( emitted.insert(target->GetName()); // for subdirs add a rule to build this specific target by name. - localName = this->GetRelativeTargetDirectory(target); - localName += "/rule"; + localName = cmStrCat(this->GetRelativeTargetDirectory(target), "/rule"); commands.clear(); depends.clear(); // Build the target for this pass. - std::string makefile2 = "CMakeFiles/"; - makefile2 += "Makefile2"; + std::string makefile2 = "CMakeFiles/Makefile2"; commands.push_back(this->GetRecursiveMakeCall(makefile2, localName)); this->CreateCDCommand(commands, this->GetBinaryDirectory(), this->GetCurrentBinaryDirectory()); @@ -388,13 +383,12 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefileTargets( } // Add a fast rule to build the target - std::string makefileName = this->GetRelativeTargetDirectory(target); - makefileName += "/build.make"; + std::string makefileName = + cmStrCat(this->GetRelativeTargetDirectory(target), "/build.make"); // make sure the makefile name is suitable for a makefile - std::string makeTargetName = this->GetRelativeTargetDirectory(target); - makeTargetName += "/build"; - localName = target->GetName(); - localName += "/fast"; + std::string makeTargetName = + cmStrCat(this->GetRelativeTargetDirectory(target), "/build"); + localName = cmStrCat(target->GetName(), "/fast"); depends.clear(); commands.clear(); commands.push_back( @@ -407,10 +401,9 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefileTargets( // Add a local name for the rule to relink the target before // installation. if (target->NeedRelinkBeforeInstall(this->ConfigName)) { - makeTargetName = this->GetRelativeTargetDirectory(target); - makeTargetName += "/preinstall"; - localName = target->GetName(); - localName += "/preinstall"; + makeTargetName = + cmStrCat(this->GetRelativeTargetDirectory(target), "/preinstall"); + localName = cmStrCat(target->GetName(), "/preinstall"); depends.clear(); commands.clear(); commands.push_back( @@ -427,8 +420,9 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefileTargets( void cmLocalUnixMakefileGenerator3::WriteDirectoryInformationFile() { - std::string infoFileName = this->GetCurrentBinaryDirectory(); - infoFileName += "/CMakeFiles/CMakeDirectoryInformation.cmake"; + std::string infoFileName = + cmStrCat(this->GetCurrentBinaryDirectory(), + "/CMakeFiles/CMakeDirectoryInformation.cmake"); // Open the output file. cmGeneratedFileStream infoFileStream(infoFileName); @@ -484,9 +478,8 @@ void cmLocalUnixMakefileGenerator3::WriteDirectoryInformationFile() std::string cmLocalUnixMakefileGenerator3::ConvertToFullPath( const std::string& localPath) { - std::string dir = this->GetCurrentBinaryDirectory(); - dir += "/"; - dir += localPath; + std::string dir = + cmStrCat(this->GetCurrentBinaryDirectory(), '/', localPath); return dir; } @@ -767,19 +760,18 @@ void cmLocalUnixMakefileGenerator3::WriteSpecialTargetsBottom( std::vector<std::string> commands; cmake* cm = this->GlobalGenerator->GetCMakeInstance(); if (cm->DoWriteGlobVerifyTarget()) { - std::string rescanRule = "$(CMAKE_COMMAND) -P "; - rescanRule += this->ConvertToOutputFormat(cm->GetGlobVerifyScript(), - cmOutputConverter::SHELL); + std::string rescanRule = + cmStrCat("$(CMAKE_COMMAND) -P ", + this->ConvertToOutputFormat(cm->GetGlobVerifyScript(), + cmOutputConverter::SHELL)); commands.push_back(rescanRule); } - std::string cmakefileName = "CMakeFiles/"; - cmakefileName += "Makefile.cmake"; - std::string runRule = - "$(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)"; - runRule += " --check-build-system "; - runRule += - this->ConvertToOutputFormat(cmakefileName, cmOutputConverter::SHELL); - runRule += " 0"; + std::string cmakefileName = "CMakeFiles/Makefile.cmake"; + std::string runRule = cmStrCat( + "$(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) " + "--check-build-system ", + this->ConvertToOutputFormat(cmakefileName, cmOutputConverter::SHELL), + " 0"); std::vector<std::string> no_depends; commands.push_back(std::move(runRule)); @@ -820,8 +812,8 @@ void cmLocalUnixMakefileGenerator3::WriteConvenienceRule( std::string cmLocalUnixMakefileGenerator3::GetRelativeTargetDirectory( cmGeneratorTarget* target) { - std::string dir = this->HomeRelativeOutputPath; - dir += this->GetTargetDirectory(target); + std::string dir = + cmStrCat(this->HomeRelativeOutputPath, this->GetTargetDirectory(target)); return dir; } @@ -1044,10 +1036,8 @@ void cmLocalUnixMakefileGenerator3::AppendCleanCommand( cmGeneratorTarget* target, const char* filename) { std::string currentBinDir = this->GetCurrentBinaryDirectory(); - std::string cleanfile = currentBinDir; - cleanfile += "/"; - cleanfile += this->GetTargetDirectory(target); - cleanfile += "/cmake_clean"; + std::string cleanfile = cmStrCat( + currentBinDir, '/', this->GetTargetDirectory(target), "/cmake_clean"); if (filename) { cleanfile += "_"; cleanfile += filename; @@ -1067,11 +1057,12 @@ void cmLocalUnixMakefileGenerator3::AppendCleanCommand( fout << ")\n"; } { - std::string remove = "$(CMAKE_COMMAND) -P "; - remove += this->ConvertToOutputFormat( - this->MaybeConvertToRelativePath(this->GetCurrentBinaryDirectory(), - cleanfile), - cmOutputConverter::SHELL); + std::string remove = + cmStrCat("$(CMAKE_COMMAND) -P ", + this->ConvertToOutputFormat( + this->MaybeConvertToRelativePath( + this->GetCurrentBinaryDirectory(), cleanfile), + cmOutputConverter::SHELL)); commands.push_back(std::move(remove)); } @@ -1114,8 +1105,8 @@ void cmLocalUnixMakefileGenerator3::AppendDirectoryCleanCommand( this->GetGlobalGenerator()->GetLocalGenerators().at(0); std::string const& binaryDir = rootLG->GetCurrentBinaryDirectory(); std::string const& currentBinaryDir = this->GetCurrentBinaryDirectory(); - std::string cleanfile = currentBinaryDir; - cleanfile += "/CMakeFiles/cmake_directory_clean.cmake"; + std::string cleanfile = + cmStrCat(currentBinaryDir, "/CMakeFiles/cmake_directory_clean.cmake"); // Write clean script { std::string cleanfilePath = cmSystemTools::CollapseFullPath(cleanfile); @@ -1134,10 +1125,11 @@ void cmLocalUnixMakefileGenerator3::AppendDirectoryCleanCommand( } // Create command { - std::string remove = "$(CMAKE_COMMAND) -P "; - remove += this->ConvertToOutputFormat( - rootLG->MaybeConvertToRelativePath(binaryDir, cleanfile), - cmOutputConverter::SHELL); + std::string remove = + cmStrCat("$(CMAKE_COMMAND) -P ", + this->ConvertToOutputFormat( + rootLG->MaybeConvertToRelativePath(binaryDir, cleanfile), + cmOutputConverter::SHELL)); commands.push_back(std::move(remove)); } } @@ -1183,12 +1175,12 @@ void cmLocalUnixMakefileGenerator3::AppendEcho( std::string cmd; if (color_name.empty() && !progress) { // Use the native echo command. - cmd = "@echo "; - cmd += this->EscapeForShell(line, false, true); + cmd = cmStrCat("@echo ", this->EscapeForShell(line, false, true)); } else { // Use cmake to echo the text in color. - cmd = "@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) "; - cmd += color_name; + cmd = cmStrCat( + "@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) ", + color_name); if (progress) { cmd += "--progress-dir="; cmd += this->ConvertToOutputFormat( @@ -1224,8 +1216,7 @@ void cmLocalUnixMakefileGenerator3::AppendEcho( std::string cmLocalUnixMakefileGenerator3::CreateMakeVariable( std::string const& s, std::string const& s2) { - std::string unmodified = s; - unmodified += s2; + std::string unmodified = cmStrCat(s, s2); // if there is no restriction on the length of make variables // and there are no "." characters in the string, then return the // unmodified combination. @@ -1343,8 +1334,9 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies( // may have changed. In this case discard all old dependencies. bool needRescanDirInfo = false; { - std::string dirInfoFile = this->GetCurrentBinaryDirectory(); - dirInfoFile += "/CMakeFiles/CMakeDirectoryInformation.cmake"; + std::string dirInfoFile = + cmStrCat(this->GetCurrentBinaryDirectory(), + "/CMakeFiles/CMakeDirectoryInformation.cmake"); int result; if (!ftc->Compare(internalDependFile, dirInfoFile, &result) || result < 0) { @@ -1386,8 +1378,8 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies( // The dependencies must be regenerated. std::string targetName = cmSystemTools::GetFilenameName(targetDir); targetName = targetName.substr(0, targetName.length() - 4); - std::string message = "Scanning dependencies of target "; - message += targetName; + std::string message = + cmStrCat("Scanning dependencies of target ", targetName); cmSystemTools::MakefileColorEcho(cmsysTerminal_Color_ForegroundMagenta | cmsysTerminal_Color_ForegroundBold, message.c_str(), true, color); @@ -1408,8 +1400,9 @@ bool cmLocalUnixMakefileGenerator3::ScanDependencies( cmMakefile* mf = this->Makefile; bool haveDirectoryInfo = false; { - std::string dirInfoFile = this->GetCurrentBinaryDirectory(); - dirInfoFile += "/CMakeFiles/CMakeDirectoryInformation.cmake"; + std::string dirInfoFile = + cmStrCat(this->GetCurrentBinaryDirectory(), + "/CMakeFiles/CMakeDirectoryInformation.cmake"); if (mf->ReadListFile(dirInfoFile) && !cmSystemTools::GetErrorOccuredFlag()) { haveDirectoryInfo = true; @@ -1462,8 +1455,8 @@ bool cmLocalUnixMakefileGenerator3::ScanDependencies( this->WriteDisclaimer(internalRuleFileStream); // for each language we need to scan, scan it - std::vector<std::string> langs; - cmExpandList(mf->GetSafeDefinition("CMAKE_DEPENDS_LANGUAGES"), langs); + std::vector<std::string> langs = + cmExpandedList(mf->GetSafeDefinition("CMAKE_DEPENDS_LANGUAGES")); for (std::string const& lang : langs) { // construct the checker // Create the scanner for this language @@ -1507,8 +1500,7 @@ void cmLocalUnixMakefileGenerator3::CheckMultipleOutputs(bool verbose) } // Convert the string to a list and preserve empty entries. - std::vector<std::string> pairs; - cmExpandList(pairs_string, pairs, true); + std::vector<std::string> pairs = cmExpandedList(pairs_string, true); for (std::vector<std::string>::const_iterator i = pairs.begin(); i != pairs.end() && (i + 1) != pairs.end();) { const std::string& depender = *i++; @@ -1621,8 +1613,8 @@ void cmLocalUnixMakefileGenerator3::WriteLocalAllRules( std::vector<std::string> commands; // Write the all rule. - std::string recursiveTarget = this->GetCurrentBinaryDirectory(); - recursiveTarget += "/all"; + std::string recursiveTarget = + cmStrCat(this->GetCurrentBinaryDirectory(), "/all"); bool regenerate = !this->GlobalGenerator->GlobalSettingIsOn("CMAKE_SUPPRESS_REGENERATION"); @@ -1630,8 +1622,8 @@ void cmLocalUnixMakefileGenerator3::WriteLocalAllRules( depends.emplace_back("cmake_check_build_system"); } - std::string progressDir = this->GetBinaryDirectory(); - progressDir += "/CMakeFiles"; + std::string progressDir = + cmStrCat(this->GetBinaryDirectory(), "/CMakeFiles"); { std::ostringstream progCmd; progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; @@ -1662,8 +1654,7 @@ void cmLocalUnixMakefileGenerator3::WriteLocalAllRules( commands, true); // Write the clean rule. - recursiveTarget = this->GetCurrentBinaryDirectory(); - recursiveTarget += "/clean"; + recursiveTarget = cmStrCat(this->GetCurrentBinaryDirectory(), "/clean"); commands.clear(); depends.clear(); commands.push_back(this->GetRecursiveMakeCall(mf2Dir, recursiveTarget)); @@ -1678,8 +1669,7 @@ void cmLocalUnixMakefileGenerator3::WriteLocalAllRules( depends, commands, true); // Write the preinstall rule. - recursiveTarget = this->GetCurrentBinaryDirectory(); - recursiveTarget += "/preinstall"; + recursiveTarget = cmStrCat(this->GetCurrentBinaryDirectory(), "/preinstall"); commands.clear(); depends.clear(); const char* noall = @@ -1706,20 +1696,19 @@ void cmLocalUnixMakefileGenerator3::WriteLocalAllRules( commands.clear(); cmake* cm = this->GlobalGenerator->GetCMakeInstance(); if (cm->DoWriteGlobVerifyTarget()) { - std::string rescanRule = "$(CMAKE_COMMAND) -P "; - rescanRule += this->ConvertToOutputFormat(cm->GetGlobVerifyScript(), - cmOutputConverter::SHELL); + std::string rescanRule = + cmStrCat("$(CMAKE_COMMAND) -P ", + this->ConvertToOutputFormat(cm->GetGlobVerifyScript(), + cmOutputConverter::SHELL)); commands.push_back(rescanRule); } - std::string cmakefileName = "CMakeFiles/"; - cmakefileName += "Makefile.cmake"; + std::string cmakefileName = "CMakeFiles/Makefile.cmake"; { - std::string runRule = - "$(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)"; - runRule += " --check-build-system "; - runRule += - this->ConvertToOutputFormat(cmakefileName, cmOutputConverter::SHELL); - runRule += " 1"; + std::string runRule = cmStrCat( + "$(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) " + "--check-build-system ", + this->ConvertToOutputFormat(cmakefileName, cmOutputConverter::SHELL), + " 1"); commands.push_back(std::move(runRule)); } this->CreateCDCommand(commands, this->GetBinaryDirectory(), @@ -1737,8 +1726,7 @@ void cmLocalUnixMakefileGenerator3::ClearDependencies(cmMakefile* mf, if (!infoDef) { return; } - std::vector<std::string> files; - cmExpandList(infoDef, files); + std::vector<std::string> files = cmExpandedList(infoDef); // Each depend information file corresponds to a target. Clear the // dependencies for that target. @@ -1840,9 +1828,8 @@ void cmLocalUnixMakefileGenerator3::WriteDependLanguageInfo( cmakefileStream << " )\n"; // Tell the dependency scanner what compiler is used. - std::string cidVar = "CMAKE_"; - cidVar += implicitLang.first; - cidVar += "_COMPILER_ID"; + std::string cidVar = + cmStrCat("CMAKE_", implicitLang.first, "_COMPILER_ID"); const char* cid = this->Makefile->GetDefinition(cidVar); if (cid && *cid) { cmakefileStream << "set(CMAKE_" << implicitLang.first @@ -1933,10 +1920,9 @@ std::string cmLocalUnixMakefileGenerator3::GetRecursiveMakeCall( const std::string& makefile, const std::string& tgt) { // Call make on the given file. - std::string cmd; - cmd += "$(MAKE) -f "; - cmd += this->ConvertToOutputFormat(makefile, cmOutputConverter::SHELL); - cmd += " "; + std::string cmd = cmStrCat( + "$(MAKE) -f ", + this->ConvertToOutputFormat(makefile, cmOutputConverter::SHELL), ' '); cmGlobalUnixMakefileGenerator3* gg = static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator); @@ -2067,8 +2053,7 @@ std::string cmLocalUnixMakefileGenerator3::ConvertToQuotedOutputPath( std::string cmLocalUnixMakefileGenerator3::GetTargetDirectory( cmGeneratorTarget const* target) const { - std::string dir = "CMakeFiles/"; - dir += target->GetName(); + std::string dir = cmStrCat("CMakeFiles/", target->GetName()); #if defined(__VMS) dir += "_dir"; #else @@ -2111,13 +2096,12 @@ void cmLocalUnixMakefileGenerator3::CreateCDCommand( // On Windows we must perform each step separately and then change // back because the shell keeps the working directory between // commands. - std::string cmd = cd_cmd; - cmd += this->ConvertToOutputForExisting(tgtDir); + std::string cmd = + cmStrCat(cd_cmd, this->ConvertToOutputForExisting(tgtDir)); commands.insert(commands.begin(), cmd); // Change back to the starting directory. - cmd = cd_cmd; - cmd += this->ConvertToOutputForExisting(relDir); + cmd = cmStrCat(cd_cmd, this->ConvertToOutputForExisting(relDir)); commands.push_back(std::move(cmd)); } else { // On UNIX we must construct a single shell command to change diff --git a/Source/cmLocalVisualStudio10Generator.cxx b/Source/cmLocalVisualStudio10Generator.cxx index d45c335..6d7b359 100644 --- a/Source/cmLocalVisualStudio10Generator.cxx +++ b/Source/cmLocalVisualStudio10Generator.cxx @@ -121,8 +121,7 @@ void cmLocalVisualStudio10Generator::ReadAndStoreExternalGUID( return; } - std::string guidStoreName = name; - guidStoreName += "_GUID_CMAKE"; + std::string guidStoreName = cmStrCat(name, "_GUID_CMAKE"); // save the GUID in the cache this->GlobalGenerator->GetCMakeInstance()->AddCacheEntry( guidStoreName.c_str(), parser.GUID.c_str(), "Stored GUID", diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 893e14e..795cee4 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -97,10 +97,8 @@ void cmLocalVisualStudio7Generator::FixGlobalTargets() cmCustomCommandLines force_commands; force_commands.push_back(force_command); std::string no_main_dependency; - std::string force = this->GetCurrentBinaryDirectory(); - force += "/CMakeFiles/"; - force += l->GetName(); - force += "_force"; + std::string force = cmStrCat(this->GetCurrentBinaryDirectory(), + "/CMakeFiles/", l->GetName(), "_force"); if (cmSourceFile* file = this->Makefile->AddCustomCommandToOutput( force.c_str(), no_depends, no_main_dependency, force_commands, " ", 0, true)) { @@ -143,8 +141,8 @@ void cmLocalVisualStudio7Generator::WriteStampFiles() { // Touch a timestamp file used to determine when the project file is // out of date. - std::string stampName = this->GetCurrentBinaryDirectory(); - stampName += "/CMakeFiles"; + std::string stampName = + cmStrCat(this->GetCurrentBinaryDirectory(), "/CMakeFiles"); cmSystemTools::MakeDirectory(stampName.c_str()); stampName += "/generate.stamp"; cmsys::ofstream stamp(stampName.c_str()); @@ -156,8 +154,7 @@ void cmLocalVisualStudio7Generator::WriteStampFiles() // dependencies. If any file listed in it is newer than itself then // CMake must rerun. Otherwise the project files are up to date and // the stamp file can just be touched. - std::string depName = stampName; - depName += ".depend"; + std::string depName = cmStrCat(stampName, ".depend"); cmsys::ofstream depFile(depName.c_str()); depFile << "# CMake generation dependency list for this directory.\n"; @@ -197,9 +194,7 @@ void cmLocalVisualStudio7Generator::CreateSingleVCProj( target->Target->SetProperty("GENERATOR_FILE_NAME", lname.c_str()); // create the dsp.cmake file std::string fname; - fname = this->GetCurrentBinaryDirectory(); - fname += "/"; - fname += lname; + fname = cmStrCat(this->GetCurrentBinaryDirectory(), '/', lname); if (this->FortranProject) { fname += ".vfproj"; } else { @@ -226,9 +221,8 @@ cmSourceFile* cmLocalVisualStudio7Generator::CreateVCProjBuildRule() return nullptr; } - std::string makefileIn = this->GetCurrentSourceDirectory(); - makefileIn += "/"; - makefileIn += "CMakeLists.txt"; + std::string makefileIn = + cmStrCat(this->GetCurrentSourceDirectory(), "/CMakeLists.txt"); makefileIn = cmSystemTools::CollapseFullPath(makefileIn); if (cmSourceFile* file = this->Makefile->GetSource(makefileIn)) { if (file->GetCustomCommand()) { @@ -251,20 +245,15 @@ cmSourceFile* cmLocalVisualStudio7Generator::CreateVCProjBuildRule() std::unique(listFiles.begin(), listFiles.end()); listFiles.erase(new_end, listFiles.end()); - std::string stampName = this->GetCurrentBinaryDirectory(); - stampName += "/"; - stampName += "CMakeFiles/"; - stampName += "generate.stamp"; + std::string stampName = + cmStrCat(this->GetCurrentBinaryDirectory(), "/CMakeFiles/generate.stamp"); cmCustomCommandLine commandLine; commandLine.push_back(cmSystemTools::GetCMakeCommand()); - std::string comment = "Building Custom Rule "; - comment += makefileIn; + std::string comment = cmStrCat("Building Custom Rule ", makefileIn); std::string args; - args = "-S"; - args += this->GetSourceDirectory(); + args = cmStrCat("-S", this->GetSourceDirectory()); commandLine.push_back(args); - args = "-B"; - args += this->GetBinaryDirectory(); + args = cmStrCat("-B", this->GetBinaryDirectory()); commandLine.push_back(args); commandLine.push_back("--check-stamp-file"); commandLine.push_back(stampName); @@ -719,9 +708,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration( this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE")); // Add a definition for the configuration name. - std::string configDefine = "CMAKE_INTDIR=\""; - configDefine += configName; - configDefine += "\""; + std::string configDefine = cmStrCat("CMAKE_INTDIR=\"", configName, '"'); targetOptions.AddDefine(configDefine); // Add the export symbol definition for shared library objects. @@ -731,9 +718,8 @@ void cmLocalVisualStudio7Generator::WriteConfiguration( // The intermediate directory name consists of a directory for the // target and a subdirectory for the configuration name. - std::string intermediateDir = this->GetTargetDirectory(target); - intermediateDir += "/"; - intermediateDir += configName; + std::string intermediateDir = + cmStrCat(this->GetTargetDirectory(target), '/', configName); if (target->GetType() < cmStateEnums::UTILITY) { std::string const& outDir = @@ -954,8 +940,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool( extraLinkOptions += targetLinkFlags; } std::string configTypeUpper = cmSystemTools::UpperCase(configName); - std::string linkFlagsConfig = "LINK_FLAGS_"; - linkFlagsConfig += configTypeUpper; + std::string linkFlagsConfig = cmStrCat("LINK_FLAGS_", configTypeUpper); targetLinkFlags = target->GetProperty(linkFlagsConfig.c_str()); if (targetLinkFlags) { extraLinkOptions += " "; @@ -987,12 +972,9 @@ void cmLocalVisualStudio7Generator::OutputBuildTool( case cmStateEnums::UNKNOWN_LIBRARY: break; case cmStateEnums::OBJECT_LIBRARY: { - std::string libpath = this->GetTargetDirectory(target); - libpath += "/"; - libpath += configName; - libpath += "/"; - libpath += target->GetName(); - libpath += ".lib"; + std::string libpath = + cmStrCat(this->GetTargetDirectory(target), '/', configName, '/', + target->GetName(), ".lib"); const char* tool = this->FortranProject ? "VFLibrarianTool" : "VCLibrarianTool"; fout << "\t\t\t<Tool\n" @@ -1003,9 +985,8 @@ void cmLocalVisualStudio7Generator::OutputBuildTool( } case cmStateEnums::STATIC_LIBRARY: { std::string targetNameFull = target->GetFullName(configName); - std::string libpath = target->GetDirectory(configName); - libpath += "/"; - libpath += targetNameFull; + std::string libpath = + cmStrCat(target->GetDirectory(configName), '/', targetNameFull); const char* tool = "VCLibrarianTool"; if (this->FortranProject) { tool = "VFLibrarianTool"; @@ -1047,9 +1028,8 @@ void cmLocalVisualStudio7Generator::OutputBuildTool( // Compute the variable name to lookup standard libraries for this // language. - std::string standardLibsVar = "CMAKE_"; - standardLibsVar += linkLanguage; - standardLibsVar += "_STANDARD_LIBRARIES"; + std::string standardLibsVar = + cmStrCat("CMAKE_", linkLanguage, "_STANDARD_LIBRARIES"); const char* tool = "VCLinkerTool"; if (this->FortranProject) { tool = "VFLinkerTool"; @@ -1069,9 +1049,8 @@ void cmLocalVisualStudio7Generator::OutputBuildTool( fout << " "; this->Internal->OutputLibraries(fout, cli.GetItems()); fout << "\"\n"; - temp = target->GetDirectory(configName); - temp += "/"; - temp += targetNames.Output; + temp = + cmStrCat(target->GetDirectory(configName), '/', targetNames.Output); fout << "\t\t\t\tOutputFile=\"" << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"\n"; this->WriteTargetVersionAttribute(fout, target); @@ -1079,9 +1058,8 @@ void cmLocalVisualStudio7Generator::OutputBuildTool( fout << "\t\t\t\tAdditionalLibraryDirectories=\""; this->OutputLibraryDirectories(fout, cli.GetDirectories()); fout << "\"\n"; - temp = target->GetPDBDirectory(configName); - temp += "/"; - temp += targetNames.PDB; + temp = + cmStrCat(target->GetPDBDirectory(configName), '/', targetNames.PDB); fout << "\t\t\t\tProgramDatabaseFile=\"" << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"\n"; if (targetOptions.IsDebug()) { @@ -1094,17 +1072,14 @@ void cmLocalVisualStudio7Generator::OutputBuildTool( fout << "\t\t\t\tSubSystem=\"8\"\n"; } } - std::string stackVar = "CMAKE_"; - stackVar += linkLanguage; - stackVar += "_STACK_SIZE"; + std::string stackVar = cmStrCat("CMAKE_", linkLanguage, "_STACK_SIZE"); const char* stackVal = this->Makefile->GetDefinition(stackVar.c_str()); if (stackVal) { fout << "\t\t\t\tStackReserveSize=\"" << stackVal << "\"\n"; } - temp = - target->GetDirectory(configName, cmStateEnums::ImportLibraryArtifact); - temp += "/"; - temp += targetNames.ImportLibrary; + temp = cmStrCat( + target->GetDirectory(configName, cmStateEnums::ImportLibraryArtifact), + '/', targetNames.ImportLibrary); fout << "\t\t\t\tImportLibrary=\"" << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\""; if (this->FortranProject) { @@ -1128,9 +1103,8 @@ void cmLocalVisualStudio7Generator::OutputBuildTool( // Compute the variable name to lookup standard libraries for this // language. - std::string standardLibsVar = "CMAKE_"; - standardLibsVar += linkLanguage; - standardLibsVar += "_STANDARD_LIBRARIES"; + std::string standardLibsVar = + cmStrCat("CMAKE_", linkLanguage, "_STANDARD_LIBRARIES"); const char* tool = "VCLinkerTool"; if (this->FortranProject) { tool = "VFLinkerTool"; @@ -1150,9 +1124,8 @@ void cmLocalVisualStudio7Generator::OutputBuildTool( fout << " "; this->Internal->OutputLibraries(fout, cli.GetItems()); fout << "\"\n"; - temp = target->GetDirectory(configName); - temp += "/"; - temp += targetNames.Output; + temp = + cmStrCat(target->GetDirectory(configName), '/', targetNames.Output); fout << "\t\t\t\tOutputFile=\"" << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"\n"; this->WriteTargetVersionAttribute(fout, target); @@ -1188,17 +1161,14 @@ void cmLocalVisualStudio7Generator::OutputBuildTool( fout << "\t\t\t\tSubSystem=\"" << (isWin32Executable ? "2" : "1") << "\"\n"; } - std::string stackVar = "CMAKE_"; - stackVar += linkLanguage; - stackVar += "_STACK_SIZE"; + std::string stackVar = cmStrCat("CMAKE_", linkLanguage, "_STACK_SIZE"); const char* stackVal = this->Makefile->GetDefinition(stackVar.c_str()); if (stackVal) { fout << "\t\t\t\tStackReserveSize=\"" << stackVal << "\""; } - temp = - target->GetDirectory(configName, cmStateEnums::ImportLibraryArtifact); - temp += "/"; - temp += targetNames.ImportLibrary; + temp = cmStrCat( + target->GetDirectory(configName, cmStateEnums::ImportLibraryArtifact), + '/', targetNames.ImportLibrary); fout << "\t\t\t\tImportLibrary=\"" << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"/>\n"; break; @@ -1350,6 +1320,8 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout, const std::string& libName, cmGeneratorTarget* target) { + this->AddPchDependencies(target, ""); + std::vector<std::string> configs; this->Makefile->GetConfigurations(configs); @@ -1507,8 +1479,7 @@ cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo( fc.CompileDefs = genexInterpreter.Evaluate(cdefs, COMPILE_DEFINITIONS); needfc = true; } - std::string defPropName = "COMPILE_DEFINITIONS_"; - defPropName += configUpper; + std::string defPropName = cmStrCat("COMPILE_DEFINITIONS_", configUpper); if (const char* ccdefs = sf.GetProperty(defPropName)) { fc.CompileDefsConfig = genexInterpreter.Evaluate(ccdefs, COMPILE_DEFINITIONS); @@ -1523,8 +1494,7 @@ cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo( // Check for extra object-file dependencies. if (const char* deps = sf.GetProperty("OBJECT_DEPENDS")) { - std::vector<std::string> depends; - cmExpandList(deps, depends); + std::vector<std::string> depends = cmExpandedList(deps); const char* sep = ""; for (std::vector<std::string>::iterator j = depends.begin(); j != depends.end(); ++j) { @@ -1538,9 +1508,8 @@ cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo( const std::string& linkLanguage = gt->GetLinkerLanguage(config.c_str()); // If HEADER_FILE_ONLY is set, we must suppress this generation in // the project file - fc.ExcludedFromBuild = sf.GetPropertyAsBool("HEADER_FILE_ONLY") || - std::find(acs.Configs.begin(), acs.Configs.end(), ci) == - acs.Configs.end(); + fc.ExcludedFromBuild = + sf.GetPropertyAsBool("HEADER_FILE_ONLY") || !cmContains(acs.Configs, ci); if (fc.ExcludedFromBuild) { needfc = true; } @@ -1584,13 +1553,9 @@ std::string cmLocalVisualStudio7Generator::ComputeLongestObjectDirectory( // Compute the maximum length full path to the intermediate // files directory for any configuration. This is used to construct // object file names that do not produce paths that are too long. - std::string dir_max; - dir_max += this->GetCurrentBinaryDirectory(); - dir_max += "/"; - dir_max += this->GetTargetDirectory(target); - dir_max += "/"; - dir_max += config_max; - dir_max += "/"; + std::string dir_max = + cmStrCat(this->GetCurrentBinaryDirectory(), '/', + this->GetTargetDirectory(target), '/', config_max, '/'); return dir_max; } @@ -2140,8 +2105,7 @@ void cmLocalVisualStudio7Generator::ReadAndStoreExternalGUID( if (parser.GUID.empty()) { return; } - std::string guidStoreName = name; - guidStoreName += "_GUID_CMAKE"; + std::string guidStoreName = cmStrCat(name, "_GUID_CMAKE"); // save the GUID in the cache this->GlobalGenerator->GetCMakeInstance()->AddCacheEntry( guidStoreName.c_str(), parser.GUID.c_str(), "Stored GUID", @@ -2151,9 +2115,7 @@ void cmLocalVisualStudio7Generator::ReadAndStoreExternalGUID( std::string cmLocalVisualStudio7Generator::GetTargetDirectory( cmGeneratorTarget const* target) const { - std::string dir; - dir += target->GetName(); - dir += ".dir"; + std::string dir = cmStrCat(target->GetName(), ".dir"); return dir; } diff --git a/Source/cmLocalXCodeGenerator.cxx b/Source/cmLocalXCodeGenerator.cxx index 9c36627..5a06d4a 100644 --- a/Source/cmLocalXCodeGenerator.cxx +++ b/Source/cmLocalXCodeGenerator.cxx @@ -65,9 +65,8 @@ void cmLocalXCodeGenerator::ComputeObjectFilenames( std::map<std::string, int> counts; for (auto& si : mapping) { cmSourceFile const* sf = si.first; - std::string objectName = - cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath()); - objectName += ".o"; + std::string objectName = cmStrCat( + cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath()), ".o"); std::string objectNameLower = cmSystemTools::LowerCase(objectName); counts[objectNameLower] += 1; diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx index 8689c8f..201cc13 100644 --- a/Source/cmMacroCommand.cxx +++ b/Source/cmMacroCommand.cxx @@ -2,7 +2,6 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmMacroCommand.h" -#include <sstream> #include <stdio.h> #include <utility> @@ -21,6 +20,8 @@ #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +namespace { + // define the class for macro commands class cmMacroHelperCommand { @@ -52,8 +53,8 @@ bool cmMacroHelperCommand::operator()( // required by the signature if (expandedArgs.size() < this->Args.size() - 1) { std::string errorMsg = - "Macro invoked with incorrect arguments for macro named: "; - errorMsg += this->Args[0]; + cmStrCat("Macro invoked with incorrect arguments for macro named: ", + this->Args[0]); inStatus.SetError(errorMsg); return false; } @@ -62,9 +63,7 @@ bool cmMacroHelperCommand::operator()( this->Policies); // set the value of argc - std::ostringstream argcDefStream; - argcDefStream << expandedArgs.size(); - std::string argcDef = argcDefStream.str(); + std::string argcDef = std::to_string(expandedArgs.size()); std::vector<std::string>::const_iterator eit = expandedArgs.begin() + (this->Args.size() - 1); @@ -178,12 +177,13 @@ bool cmMacroFunctionBlocker::Replay(std::vector<cmListFileFunction> functions, mf.GetState()->AddScriptedCommand(this->Args[0], std::move(f)); return true; } +} -bool cmMacroCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmMacroCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.empty()) { - this->SetError("called with incorrect number of arguments"); + status.SetError("called with incorrect number of arguments"); return false; } @@ -191,7 +191,7 @@ bool cmMacroCommand::InitialPass(std::vector<std::string> const& args, { auto fb = cm::make_unique<cmMacroFunctionBlocker>(); cmAppend(fb->Args, args); - this->Makefile->AddFunctionBlocker(std::move(fb)); + status.GetMakefile().AddFunctionBlocker(std::move(fb)); } return true; } diff --git a/Source/cmMacroCommand.h b/Source/cmMacroCommand.h index 0d7083a..25091ea 100644 --- a/Source/cmMacroCommand.h +++ b/Source/cmMacroCommand.h @@ -8,30 +8,10 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; /// Starts macro() ... endmacro() block -class cmMacroCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmMacroCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; +bool cmMacroCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmMakeDirectoryCommand.cxx b/Source/cmMakeDirectoryCommand.cxx index aff4ca6..cdde6f9 100644 --- a/Source/cmMakeDirectoryCommand.cxx +++ b/Source/cmMakeDirectoryCommand.cxx @@ -2,23 +2,22 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmMakeDirectoryCommand.h" +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmSystemTools.h" -class cmExecutionStatus; - // cmMakeDirectoryCommand -bool cmMakeDirectoryCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmMakeDirectoryCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() != 1) { - this->SetError("called with incorrect number of arguments"); + status.SetError("called with incorrect number of arguments"); return false; } - if (!this->Makefile->CanIWriteThisFile(args[0])) { + if (!status.GetMakefile().CanIWriteThisFile(args[0])) { std::string e = "attempted to create a directory: " + args[0] + " into a source directory."; - this->SetError(e); + status.SetError(e); cmSystemTools::SetFatalErrorOccured(); return false; } diff --git a/Source/cmMakeDirectoryCommand.h b/Source/cmMakeDirectoryCommand.h index b1fb49b..2474383 100644 --- a/Source/cmMakeDirectoryCommand.h +++ b/Source/cmMakeDirectoryCommand.h @@ -8,13 +8,9 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmMakeDirectoryCommand +/** * \brief Specify auxiliary source code directories. * * cmMakeDirectoryCommand specifies source code directories @@ -23,23 +19,7 @@ class cmExecutionStatus; * A side effect of this command is to create a subdirectory in the build * directory structure. */ -class cmMakeDirectoryCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmMakeDirectoryCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; +bool cmMakeDirectoryCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 992fc1b..f101cdc 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -23,6 +23,7 @@ #include "cmExpandedCommandArgument.h" // IWYU pragma: keep #include "cmFileLockPool.h" #include "cmFunctionBlocker.h" +#include "cmGeneratedFileStream.h" #include "cmGeneratorExpression.h" #include "cmGeneratorExpressionEvaluationFile.h" #include "cmGlobalGenerator.h" @@ -321,7 +322,13 @@ void cmMakefile::PrintCommandTrace(const cmListFileFunction& lff) const msg << " "; } msg << ")"; - cmSystemTools::Message(msg.str()); + + auto& f = this->GetCMakeInstance()->GetTraceFile(); + if (f) { + f << msg.str() << '\n'; + } else { + cmSystemTools::Message(msg.str()); + } } // Helper class to make sure the call stack is valid. @@ -422,9 +429,8 @@ bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff, } } else { if (!cmSystemTools::GetFatalErrorOccured()) { - std::string error = "Unknown CMake command \""; - error += lff.Name.Original; - error += "\"."; + std::string error = + cmStrCat("Unknown CMake command \"", lff.Name.Original, "\"."); this->IssueMessage(MessageType::FATAL_ERROR, error); result = false; cmSystemTools::SetFatalErrorOccured(); @@ -1181,9 +1187,8 @@ cmTarget* cmMakefile::AddUtilityCommand( // Store the custom command in the target. if (!commandLines.empty() || !depends.empty()) { - std::string force = this->GetCurrentBinaryDirectory(); - force += "/CMakeFiles/"; - force += utilityName; + std::string force = + cmStrCat(this->GetCurrentBinaryDirectory(), "/CMakeFiles/", utilityName); std::vector<std::string> forced; forced.push_back(force); std::string no_main_dependency; @@ -1347,8 +1352,7 @@ bool cmMakefile::ParseDefineFlag(std::string const& def, bool remove) if (remove) { if (const char* cdefs = this->GetProperty("COMPILE_DEFINITIONS")) { // Expand the list. - std::vector<std::string> defs; - cmExpandList(cdefs, defs); + std::vector<std::string> defs = cmExpandedList(cdefs); // Recompose the list without the definition. std::vector<std::string>::const_iterator defEnd = @@ -1389,8 +1393,8 @@ void cmMakefile::InitializeFromParent(cmMakefile* parent) std::vector<std::string> configs; this->GetConfigurations(configs); for (std::string const& config : configs) { - std::string defPropName = "COMPILE_DEFINITIONS_"; - defPropName += cmSystemTools::UpperCase(config); + std::string defPropName = + cmStrCat("COMPILE_DEFINITIONS_", cmSystemTools::UpperCase(config)); const char* prop = parent->GetProperty(defPropName); this->SetProperty(defPropName, prop); } @@ -1483,8 +1487,8 @@ public: , ReportError(true) { std::string currentStart = - this->Makefile->StateSnapshot.GetDirectory().GetCurrentSource(); - currentStart += "/CMakeLists.txt"; + cmStrCat(this->Makefile->StateSnapshot.GetDirectory().GetCurrentSource(), + "/CMakeLists.txt"); this->Makefile->StateSnapshot.SetListFile(currentStart); this->Makefile->StateSnapshot = this->Makefile->StateSnapshot.GetState()->CreatePolicyScopeSnapshot( @@ -1527,9 +1531,8 @@ private: void cmMakefile::Configure() { - std::string currentStart = - this->StateSnapshot.GetDirectory().GetCurrentSource(); - currentStart += "/CMakeLists.txt"; + std::string currentStart = cmStrCat( + this->StateSnapshot.GetDirectory().GetCurrentSource(), "/CMakeLists.txt"); // Add the bottom of all backtraces within this directory. // We will never pop this scope because it should be available @@ -1539,8 +1542,8 @@ void cmMakefile::Configure() BuildsystemFileScope scope(this); // make sure the CMakeFiles dir is there - std::string filesDir = this->StateSnapshot.GetDirectory().GetCurrentBinary(); - filesDir += "/CMakeFiles"; + std::string filesDir = cmStrCat( + this->StateSnapshot.GetDirectory().GetCurrentBinary(), "/CMakeFiles"); cmSystemTools::MakeDirectory(filesDir); assert(cmSystemTools::FileExists(currentStart, true)); @@ -1582,7 +1585,7 @@ void cmMakefile::Configure() allowedCommands.insert("message"); isProblem = false; for (cmListFileFunction const& func : listFile.Functions) { - if (allowedCommands.find(func.Name.Lower) == allowedCommands.end()) { + if (!cmContains(allowedCommands, func.Name.Lower)) { isProblem = true; break; } @@ -1651,8 +1654,7 @@ void cmMakefile::ConfigureSubDirectory(cmMakefile* mf) mf->InitializeFromParent(this); std::string currentStart = mf->GetCurrentSourceDirectory(); if (this->GetCMakeInstance()->GetDebugOutput()) { - std::string msg = " Entering "; - msg += currentStart; + std::string msg = cmStrCat(" Entering ", currentStart); cmSystemTools::Message(msg); } @@ -1694,8 +1696,8 @@ void cmMakefile::ConfigureSubDirectory(cmMakefile* mf) mf->Configure(); if (this->GetCMakeInstance()->GetDebugOutput()) { - std::string msg = " Returning to "; - msg += this->GetCurrentSourceDirectory(); + std::string msg = + cmStrCat(" Returning to ", this->GetCurrentSourceDirectory()); cmSystemTools::Message(msg); } } @@ -1902,8 +1904,7 @@ void cmMakefile::LogUnused(const char* reason, const std::string& name) const if (!this->ExecutionStatusStack.empty()) { path = this->GetExecutionContext().FilePath; } else { - path = this->GetCurrentSourceDirectory(); - path += "/CMakeLists.txt"; + path = cmStrCat(this->GetCurrentSourceDirectory(), "/CMakeLists.txt"); } if (this->CheckSystemVars || this->IsProjectFile(path.c_str())) { @@ -1951,8 +1952,7 @@ void cmMakefile::AddGlobalLinkInformation(cmTarget& target) } if (const char* linkLibsProp = this->GetProperty("LINK_LIBRARIES")) { - std::vector<std::string> linkLibs; - cmExpandList(linkLibsProp, linkLibs); + std::vector<std::string> linkLibs = cmExpandedList(linkLibsProp); for (std::vector<std::string>::iterator j = linkLibs.begin(); j != linkLibs.end(); ++j) { @@ -2279,8 +2279,7 @@ void cmMakefile::ExpandVariablesCMP0019() } if (const char* linkLibsProp = this->GetProperty("LINK_LIBRARIES")) { - std::vector<std::string> linkLibs; - cmExpandList(linkLibsProp, linkLibs); + std::vector<std::string> linkLibs = cmExpandedList(linkLibsProp); for (std::vector<std::string>::iterator l = linkLibs.begin(); l != linkLibs.end(); ++l) { @@ -2595,8 +2594,8 @@ const std::string& cmMakefile::ExpandVariablesInString( } // ...otherwise, see if there's a difference that needs to be warned about. else if (compareResults && (newResult != source || newError != mtype)) { - std::string msg = cmPolicies::GetPolicyWarning(cmPolicies::CMP0053); - msg += "\n"; + std::string msg = + cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0053), '\n'); std::string msg_input = original; cmSystemTools::ReplaceString(msg_input, "\n", "\n "); @@ -2811,9 +2810,7 @@ MessageType cmMakefile::ExpandVariablesInStringNew( switch (var.domain) { case NORMAL: if (filename && lookup == lineVar) { - std::ostringstream ostr; - ostr << line; - varresult = ostr.str(); + varresult = std::to_string(line); } else { value = this->GetDefinition(lookup); } @@ -3198,8 +3195,7 @@ bool cmMakefile::ExpandArguments( if (i.Delim == cmListFileArgument::Quoted) { outArgs.emplace_back(value, true); } else { - std::vector<std::string> stringArgs; - cmExpandList(value, stringArgs); + std::vector<std::string> stringArgs = cmExpandedList(value); for (std::string const& stringArg : stringArgs) { outArgs.emplace_back(stringArg, false); } @@ -3246,9 +3242,7 @@ void cmMakefile::SetScriptModeFile(std::string const& scriptfile) void cmMakefile::SetArgcArgv(const std::vector<std::string>& args) { - std::ostringstream strStream; - strStream << args.size(); - this->AddDefinition("CMAKE_ARGC", strStream.str()); + this->AddDefinition("CMAKE_ARGC", std::to_string(args.size())); // this->MarkVariableAsUsed("CMAKE_ARGC"); for (unsigned int t = 0; t < args.size(); ++t) { @@ -3556,8 +3550,7 @@ std::string cmMakefile::GetModulesFile(const std::string& filename, // Always search in CMAKE_MODULE_PATH: const char* cmakeModulePath = this->GetDefinition("CMAKE_MODULE_PATH"); if (cmakeModulePath) { - std::vector<std::string> modulePath; - cmExpandList(cmakeModulePath, modulePath); + std::vector<std::string> modulePath = cmExpandedList(cmakeModulePath); // Look through the possible module directories. for (std::string itempl : modulePath) { @@ -3572,9 +3565,8 @@ std::string cmMakefile::GetModulesFile(const std::string& filename, } // Always search in the standard modules location. - moduleInCMakeRoot = cmSystemTools::GetCMakeRoot(); - moduleInCMakeRoot += "/Modules/"; - moduleInCMakeRoot += filename; + moduleInCMakeRoot = + cmStrCat(cmSystemTools::GetCMakeRoot(), "/Modules/", filename); cmSystemTools::ConvertToUnixSlashes(moduleInCMakeRoot); if (!cmSystemTools::FileExists(moduleInCMakeRoot)) { moduleInCMakeRoot.clear(); @@ -3740,8 +3732,7 @@ int cmMakefile::ConfigureFile(const std::string& infile, } else { newLineCharacters = "\n"; } - std::string tempOutputFile = soutfile; - tempOutputFile += ".tmp"; + std::string tempOutputFile = cmStrCat(soutfile, ".tmp"); cmsys::ofstream fout(tempOutputFile.c_str(), omode); if (!fout) { cmSystemTools::Error("Could not open file for write in copy operation " + @@ -3888,9 +3879,7 @@ void cmMakefile::AddCMakeDependFilesFromUser() if (cmSystemTools::FileIsFullPath(dep)) { this->AddCMakeDependFile(dep); } else { - std::string f = this->GetCurrentSourceDirectory(); - f += "/"; - f += dep; + std::string f = cmStrCat(this->GetCurrentSourceDirectory(), '/', dep); this->AddCMakeDependFile(f); } } @@ -4011,7 +4000,7 @@ cmTarget* cmMakefile::FindTargetToUse(const std::string& name, bool cmMakefile::IsAlias(const std::string& name) const { - if (this->AliasTargets.find(name) != this->AliasTargets.end()) { + if (cmContains(this->AliasTargets, name)) { return true; } return this->GetGlobalGenerator()->IsAlias(name); @@ -4376,10 +4365,8 @@ bool cmMakefile::AddRequiredTargetFeature(cmTarget* target, return false; } - std::vector<std::string> availableFeatures; - cmExpandList(features, availableFeatures); - if (std::find(availableFeatures.begin(), availableFeatures.end(), feature) == - availableFeatures.end()) { + std::vector<std::string> availableFeatures = cmExpandedList(features); + if (!cmContains(availableFeatures, feature)) { std::ostringstream e; e << "The compiler feature \"" << feature << "\" is not known to " << lang << " compiler\n\"" @@ -4501,10 +4488,10 @@ bool cmMakefile::HaveCStandardAvailable(cmTarget const* target, const char* defaultCStandard = this->GetDefinition("CMAKE_C_STANDARD_DEFAULT"); if (!defaultCStandard) { - std::ostringstream e; - e << "CMAKE_C_STANDARD_DEFAULT is not set. COMPILE_FEATURES support " - "not fully configured for this compiler."; - this->IssueMessage(MessageType::INTERNAL_ERROR, e.str()); + this->IssueMessage( + MessageType::INTERNAL_ERROR, + "CMAKE_C_STANDARD_DEFAULT is not set. COMPILE_FEATURES support " + "not fully configured for this compiler."); // Return true so the caller does not try to lookup the default standard. return true; } @@ -4585,10 +4572,10 @@ bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target, const char* defaultCxxStandard = this->GetDefinition("CMAKE_CXX_STANDARD_DEFAULT"); if (!defaultCxxStandard) { - std::ostringstream e; - e << "CMAKE_CXX_STANDARD_DEFAULT is not set. COMPILE_FEATURES support " - "not fully configured for this compiler."; - this->IssueMessage(MessageType::INTERNAL_ERROR, e.str()); + this->IssueMessage( + MessageType::INTERNAL_ERROR, + "CMAKE_CXX_STANDARD_DEFAULT is not set. COMPILE_FEATURES support " + "not fully configured for this compiler."); // Return true so the caller does not try to lookup the default standard. return true; } @@ -4646,33 +4633,28 @@ void cmMakefile::CheckNeededCxxLanguage(const std::string& feature, { if (const char* propCxx98 = this->GetDefinition("CMAKE_CXX98_COMPILE_FEATURES")) { - std::vector<std::string> props; - cmExpandList(propCxx98, props); - needCxx98 = std::find(props.begin(), props.end(), feature) != props.end(); + std::vector<std::string> props = cmExpandedList(propCxx98); + needCxx98 = cmContains(props, feature); } if (const char* propCxx11 = this->GetDefinition("CMAKE_CXX11_COMPILE_FEATURES")) { - std::vector<std::string> props; - cmExpandList(propCxx11, props); - needCxx11 = std::find(props.begin(), props.end(), feature) != props.end(); + std::vector<std::string> props = cmExpandedList(propCxx11); + needCxx11 = cmContains(props, feature); } if (const char* propCxx14 = this->GetDefinition("CMAKE_CXX14_COMPILE_FEATURES")) { - std::vector<std::string> props; - cmExpandList(propCxx14, props); - needCxx14 = std::find(props.begin(), props.end(), feature) != props.end(); + std::vector<std::string> props = cmExpandedList(propCxx14); + needCxx14 = cmContains(props, feature); } if (const char* propCxx17 = this->GetDefinition("CMAKE_CXX17_COMPILE_FEATURES")) { - std::vector<std::string> props; - cmExpandList(propCxx17, props); - needCxx17 = std::find(props.begin(), props.end(), feature) != props.end(); + std::vector<std::string> props = cmExpandedList(propCxx17); + needCxx17 = cmContains(props, feature); } if (const char* propCxx20 = this->GetDefinition("CMAKE_CXX20_COMPILE_FEATURES")) { - std::vector<std::string> props; - cmExpandList(propCxx20, props); - needCxx20 = std::find(props.begin(), props.end(), feature) != props.end(); + std::vector<std::string> props = cmExpandedList(propCxx20); + needCxx20 = cmContains(props, feature); } } @@ -4770,21 +4752,18 @@ void cmMakefile::CheckNeededCLanguage(const std::string& feature, { if (const char* propC90 = this->GetDefinition("CMAKE_C90_COMPILE_FEATURES")) { - std::vector<std::string> props; - cmExpandList(propC90, props); - needC90 = std::find(props.begin(), props.end(), feature) != props.end(); + std::vector<std::string> props = cmExpandedList(propC90); + needC90 = cmContains(props, feature); } if (const char* propC99 = this->GetDefinition("CMAKE_C99_COMPILE_FEATURES")) { - std::vector<std::string> props; - cmExpandList(propC99, props); - needC99 = std::find(props.begin(), props.end(), feature) != props.end(); + std::vector<std::string> props = cmExpandedList(propC99); + needC99 = cmContains(props, feature); } if (const char* propC11 = this->GetDefinition("CMAKE_C11_COMPILE_FEATURES")) { - std::vector<std::string> props; - cmExpandList(propC11, props); - needC11 = std::find(props.begin(), props.end(), feature) != props.end(); + std::vector<std::string> props = cmExpandedList(propC11); + needC11 = cmContains(props, feature); } } diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index a6d1757..dcc4e77 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -1002,7 +1002,8 @@ private: cmPolicies::PolicyMap const& pm = cmPolicies::PolicyMap()); void PopPolicy(); void PopSnapshot(bool reportError = true); - friend class cmCMakePolicyCommand; + friend bool cmCMakePolicyCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); class IncludeScope; friend class IncludeScope; diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index 097ce45..bebd5c4 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -40,6 +40,8 @@ cmMakefileExecutableTargetGenerator::cmMakefileExecutableTargetGenerator( this->OSXBundleGenerator = cm::make_unique<cmOSXBundleGenerator>(target, this->ConfigName); this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders); + + this->LocalGenerator->AddPchDependencies(target, this->ConfigName); } cmMakefileExecutableTargetGenerator::~cmMakefileExecutableTargetGenerator() = @@ -111,14 +113,13 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule( cmLocalUnixMakefileGenerator3::EchoProgress progress; this->MakeEchoProgress(progress); // Add the link message. - std::string buildEcho = "Linking "; - buildEcho += linkLanguage; - buildEcho += " device code "; - buildEcho += this->LocalGenerator->ConvertToOutputFormat( - this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), - this->DeviceLinkObject), - cmOutputConverter::SHELL); + std::string buildEcho = + cmStrCat("Linking ", linkLanguage, " device code ", + this->LocalGenerator->ConvertToOutputFormat( + this->LocalGenerator->MaybeConvertToRelativePath( + this->LocalGenerator->GetCurrentBinaryDirectory(), + this->DeviceLinkObject), + cmOutputConverter::SHELL)); this->LocalGenerator->AppendEcho( commands, buildEcho, cmLocalUnixMakefileGenerator3::EchoLink, &progress); } @@ -130,9 +131,8 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule( // Add flags to create an executable. // Add symbol export flags if necessary. if (this->GeneratorTarget->IsExecutableWithExports()) { - std::string export_flag_var = "CMAKE_EXE_EXPORTS_"; - export_flag_var += linkLanguage; - export_flag_var += "_FLAG"; + std::string export_flag_var = + cmStrCat("CMAKE_EXE_EXPORTS_", linkLanguage, "_FLAG"); this->LocalGenerator->AppendFlags( linkFlags, this->Makefile->GetDefinition(export_flag_var)); } @@ -234,8 +234,7 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule( const char* val = this->LocalGenerator->GetRuleLauncher( this->GeneratorTarget, "RULE_LAUNCH_LINK"); if (val && *val) { - launcher = val; - launcher += " "; + launcher = cmStrCat(val, ' '); } std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander( @@ -300,8 +299,8 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) outpath += '/'; std::string outpathImp; if (relink) { - outpath = this->Makefile->GetCurrentBinaryDirectory(); - outpath += "/CMakeFiles/CMakeRelink.dir"; + outpath = cmStrCat(this->Makefile->GetCurrentBinaryDirectory(), + "/CMakeFiles/CMakeRelink.dir"); cmSystemTools::MakeDirectory(outpath); outpath += '/'; if (!targetNames.ImportLibrary.empty()) { @@ -371,10 +370,8 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) cmLocalUnixMakefileGenerator3::EchoProgress progress; this->MakeEchoProgress(progress); // Add the link message. - std::string buildEcho = "Linking "; - buildEcho += linkLanguage; - buildEcho += " executable "; - buildEcho += targetOutPath; + std::string buildEcho = + cmStrCat("Linking ", linkLanguage, " executable ", targetOutPath); this->LocalGenerator->AppendEcho( commands, buildEcho, cmLocalUnixMakefileGenerator3::EchoLink, &progress); } @@ -397,9 +394,8 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) // Add symbol export flags if necessary. if (this->GeneratorTarget->IsExecutableWithExports()) { - std::string export_flag_var = "CMAKE_EXE_EXPORTS_"; - export_flag_var += linkLanguage; - export_flag_var += "_FLAG"; + std::string export_flag_var = + cmStrCat("CMAKE_EXE_EXPORTS_", linkLanguage, "_FLAG"); this->LocalGenerator->AppendFlags( linkFlags, this->Makefile->GetDefinition(export_flag_var)); } @@ -491,9 +487,8 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) if (this->GeneratorTarget->IsExecutableWithExports()) { // If a separate rule for creating an import library is specified // add it now. - std::string implibRuleVar = "CMAKE_"; - implibRuleVar += linkLanguage; - implibRuleVar += "_CREATE_IMPORT_LIBRARY"; + std::string implibRuleVar = + cmStrCat("CMAKE_", linkLanguage, "_CREATE_IMPORT_LIBRARY"); if (const char* rule = this->Makefile->GetDefinition(implibRuleVar)) { cmExpandList(rule, real_link_commands); } @@ -590,10 +585,10 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) vars.Manifests = manifests.c_str(); if (this->GeneratorTarget->GetPropertyAsBool("LINK_WHAT_YOU_USE")) { - std::string cmakeCommand = this->LocalGenerator->ConvertToOutputFormat( - cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL); - cmakeCommand += " -E __run_co_compile --lwyu="; - cmakeCommand += targetOutPathReal; + std::string cmakeCommand = + cmStrCat(this->LocalGenerator->ConvertToOutputFormat( + cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL), + " -E __run_co_compile --lwyu=", targetOutPathReal); real_link_commands.push_back(std::move(cmakeCommand)); } @@ -602,8 +597,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) const char* val = this->LocalGenerator->GetRuleLauncher( this->GeneratorTarget, "RULE_LAUNCH_LINK"); if (val && *val) { - launcher = val; - launcher += " "; + launcher = cmStrCat(val, ' '); } std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander( @@ -639,10 +633,9 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) // Add a rule to create necessary symlinks for the library. if (targetOutPath != targetOutPathReal) { - std::string symlink = "$(CMAKE_COMMAND) -E cmake_symlink_executable "; - symlink += targetOutPathReal; - symlink += " "; - symlink += targetOutPath; + std::string symlink = + cmStrCat("$(CMAKE_COMMAND) -E cmake_symlink_executable ", + targetOutPathReal, ' ', targetOutPath); commands1.push_back(std::move(symlink)); this->LocalGenerator->CreateCDCommand( commands1, this->Makefile->GetCurrentBinaryDirectory(), diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index 45c74cb..4244402 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -42,6 +42,8 @@ cmMakefileLibraryTargetGenerator::cmMakefileLibraryTargetGenerator( this->OSXBundleGenerator = cm::make_unique<cmOSXBundleGenerator>(target, this->ConfigName); this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders); + + this->LocalGenerator->AddPchDependencies(target, this->ConfigName); } cmMakefileLibraryTargetGenerator::~cmMakefileLibraryTargetGenerator() = @@ -163,9 +165,8 @@ void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink) std::string linkLanguage = this->GeneratorTarget->GetLinkerLanguage(this->ConfigName); - std::string linkRuleVar = "CMAKE_"; - linkRuleVar += linkLanguage; - linkRuleVar += "_CREATE_SHARED_LIBRARY"; + std::string linkRuleVar = + cmStrCat("CMAKE_", linkLanguage, "_CREATE_SHARED_LIBRARY"); std::string extraFlags; this->GetTargetLinkFlags(extraFlags, linkLanguage); @@ -198,9 +199,8 @@ void cmMakefileLibraryTargetGenerator::WriteModuleLibraryRules(bool relink) std::string linkLanguage = this->GeneratorTarget->GetLinkerLanguage(this->ConfigName); - std::string linkRuleVar = "CMAKE_"; - linkRuleVar += linkLanguage; - linkRuleVar += "_CREATE_SHARED_MODULE"; + std::string linkRuleVar = + cmStrCat("CMAKE_", linkLanguage, "_CREATE_SHARED_MODULE"); std::string extraFlags; this->GetTargetLinkFlags(extraFlags, linkLanguage); @@ -221,9 +221,8 @@ void cmMakefileLibraryTargetGenerator::WriteFrameworkRules(bool relink) { std::string linkLanguage = this->GeneratorTarget->GetLinkerLanguage(this->ConfigName); - std::string linkRuleVar = "CMAKE_"; - linkRuleVar += linkLanguage; - linkRuleVar += "_CREATE_MACOSX_FRAMEWORK"; + std::string linkRuleVar = + cmStrCat("CMAKE_", linkLanguage, "_CREATE_MACOSX_FRAMEWORK"); std::string extraFlags; this->GetTargetLinkFlags(extraFlags, linkLanguage); @@ -264,12 +263,13 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules( cmLocalUnixMakefileGenerator3::EchoProgress progress; this->MakeEchoProgress(progress); // Add the link message. - std::string buildEcho = "Linking " + linkLanguage + " device code "; - buildEcho += this->LocalGenerator->ConvertToOutputFormat( - this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), - this->DeviceLinkObject), - cmOutputConverter::SHELL); + std::string buildEcho = + cmStrCat("Linking ", linkLanguage, " device code ", + this->LocalGenerator->ConvertToOutputFormat( + this->LocalGenerator->MaybeConvertToRelativePath( + this->LocalGenerator->GetCurrentBinaryDirectory(), + this->DeviceLinkObject), + cmOutputConverter::SHELL)); this->LocalGenerator->AppendEcho( commands, buildEcho, cmLocalUnixMakefileGenerator3::EchoLink, &progress); } @@ -360,8 +360,7 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules( const char* val = this->LocalGenerator->GetRuleLauncher( this->GeneratorTarget, "RULE_LAUNCH_LINK"); if (val && *val) { - launcher = val; - launcher += " "; + launcher = cmStrCat(val, ' '); } std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander( @@ -472,8 +471,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules( outpath); outpath += '/'; } else if (relink) { - outpath = this->Makefile->GetCurrentBinaryDirectory(); - outpath += "/CMakeFiles/CMakeRelink.dir"; + outpath = cmStrCat(this->Makefile->GetCurrentBinaryDirectory(), + "/CMakeFiles/CMakeRelink.dir"); cmSystemTools::MakeDirectory(outpath); outpath += '/'; if (!this->TargetNames.ImportLibrary.empty()) { @@ -536,8 +535,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules( cmLocalUnixMakefileGenerator3::EchoProgress progress; this->MakeEchoProgress(progress); // Add the link message. - std::string buildEcho = "Linking "; - buildEcho += linkLanguage; + std::string buildEcho = cmStrCat("Linking ", linkLanguage); switch (this->GeneratorTarget->GetType()) { case cmStateEnums::STATIC_LIBRARY: buildEcho += " static library "; @@ -641,9 +639,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules( std::string::size_type archiveCommandLimit = std::string::npos; if (this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY) { haveStaticLibraryRule = this->Makefile->IsDefinitionSet(linkRuleVar); - std::string arCreateVar = "CMAKE_"; - arCreateVar += linkLanguage; - arCreateVar += "_ARCHIVE_CREATE"; + std::string arCreateVar = + cmStrCat("CMAKE_", linkLanguage, "_ARCHIVE_CREATE"); arCreateVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable( arCreateVar, linkLanguage, this->ConfigName); @@ -651,9 +648,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules( if (const char* rule = this->Makefile->GetDefinition(arCreateVar)) { cmExpandList(rule, archiveCreateCommands); } - std::string arAppendVar = "CMAKE_"; - arAppendVar += linkLanguage; - arAppendVar += "_ARCHIVE_APPEND"; + std::string arAppendVar = + cmStrCat("CMAKE_", linkLanguage, "_ARCHIVE_APPEND"); arAppendVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable( arAppendVar, linkLanguage, this->ConfigName); @@ -661,9 +657,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules( if (const char* rule = this->Makefile->GetDefinition(arAppendVar)) { cmExpandList(rule, archiveAppendCommands); } - std::string arFinishVar = "CMAKE_"; - arFinishVar += linkLanguage; - arFinishVar += "_ARCHIVE_FINISH"; + std::string arFinishVar = + cmStrCat("CMAKE_", linkLanguage, "_ARCHIVE_FINISH"); arFinishVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable( arFinishVar, linkLanguage, this->ConfigName); @@ -821,8 +816,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules( const char* val = this->LocalGenerator->GetRuleLauncher( this->GeneratorTarget, "RULE_LAUNCH_LINK"); if (val && *val) { - launcher = val; - launcher += " "; + launcher = cmStrCat(val, ' '); } std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander( @@ -882,10 +876,10 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules( cmExpandList(linkRule, real_link_commands); if (this->GeneratorTarget->GetPropertyAsBool("LINK_WHAT_YOU_USE") && (this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY)) { - std::string cmakeCommand = this->LocalGenerator->ConvertToOutputFormat( - cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL); - cmakeCommand += " -E __run_co_compile --lwyu="; - cmakeCommand += targetOutPathReal; + std::string cmakeCommand = cmStrCat( + this->LocalGenerator->ConvertToOutputFormat( + cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL), + " -E __run_co_compile --lwyu=", targetOutPathReal); real_link_commands.push_back(std::move(cmakeCommand)); } @@ -921,12 +915,9 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules( // Frameworks are handled by cmOSXBundleGenerator. if (targetOutPath != targetOutPathReal && !this->GeneratorTarget->IsFrameworkOnApple()) { - std::string symlink = "$(CMAKE_COMMAND) -E cmake_symlink_library "; - symlink += targetOutPathReal; - symlink += " "; - symlink += targetOutPathSO; - symlink += " "; - symlink += targetOutPath; + std::string symlink = + cmStrCat("$(CMAKE_COMMAND) -E cmake_symlink_library ", targetOutPathReal, + ' ', targetOutPathSO, ' ', targetOutPath); commands1.push_back(std::move(symlink)); this->LocalGenerator->CreateCDCommand( commands1, this->Makefile->GetCurrentBinaryDirectory(), diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index f35df32..90d8ea9 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -90,8 +90,8 @@ void cmMakefileTargetGenerator::GetTargetLinkFlags( this->LocalGenerator->AppendFlags( flags, this->GeneratorTarget->GetProperty("LINK_FLAGS")); - std::string linkFlagsConfig = "LINK_FLAGS_"; - linkFlagsConfig += cmSystemTools::UpperCase(this->ConfigName); + std::string linkFlagsConfig = + cmStrCat("LINK_FLAGS_", cmSystemTools::UpperCase(this->ConfigName)); this->LocalGenerator->AppendFlags( flags, this->GeneratorTarget->GetProperty(linkFlagsConfig)); @@ -114,14 +114,13 @@ void cmMakefileTargetGenerator::CreateRuleFile() cmSystemTools::MakeDirectory(this->TargetBuildDirectoryFull); // Construct the rule file name. - this->BuildFileName = this->TargetBuildDirectory; - this->BuildFileName += "/build.make"; - this->BuildFileNameFull = this->TargetBuildDirectoryFull; - this->BuildFileNameFull += "/build.make"; + this->BuildFileName = cmStrCat(this->TargetBuildDirectory, "/build.make"); + this->BuildFileNameFull = + cmStrCat(this->TargetBuildDirectoryFull, "/build.make"); // Construct the rule file name. - this->ProgressFileNameFull = this->TargetBuildDirectoryFull; - this->ProgressFileNameFull += "/progress.make"; + this->ProgressFileNameFull = + cmStrCat(this->TargetBuildDirectoryFull, "/progress.make"); // reset the progress count this->NumberOfProgressActions = 0; @@ -131,10 +130,10 @@ void cmMakefileTargetGenerator::CreateRuleFile() this->BuildFileStream = new cmGeneratedFileStream(this->BuildFileNameFull, false, this->GlobalGenerator->GetMakefileEncoding()); - this->BuildFileStream->SetCopyIfDifferent(true); if (!this->BuildFileStream) { return; } + this->BuildFileStream->SetCopyIfDifferent(true); this->LocalGenerator->WriteDisclaimer(*this->BuildFileStream); if (this->GlobalGenerator->AllowDeleteOnError()) { std::vector<std::string> no_depends; @@ -240,10 +239,15 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules() this->GeneratorTarget->GetExtraSources(extraSources, config); this->OSXBundleGenerator->GenerateMacOSXContentStatements( extraSources, this->MacOSXContentGenerator); + const char* pchExtension = + this->Makefile->GetDefinition("CMAKE_PCH_EXTENSION"); std::vector<cmSourceFile const*> externalObjects; this->GeneratorTarget->GetExternalObjects(externalObjects, config); for (cmSourceFile const* sf : externalObjects) { - this->ExternalObjects.push_back(sf->GetFullPath()); + auto const& objectFileName = sf->GetFullPath(); + if (!cmSystemTools::StringEndsWith(objectFileName, pchExtension)) { + this->ExternalObjects.push_back(objectFileName); + } } std::vector<cmSourceFile const*> objectSources; this->GeneratorTarget->GetObjectSources(objectSources, config); @@ -260,8 +264,8 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules() : ""); // Include the dependencies for the target. - std::string dependFileNameFull = this->TargetBuildDirectoryFull; - dependFileNameFull += "/depend.make"; + std::string dependFileNameFull = + cmStrCat(this->TargetBuildDirectoryFull, "/depend.make"); *this->BuildFileStream << "# Include any dependencies generated for this target.\n" << this->GlobalGenerator->IncludeDirective << " " << root @@ -295,15 +299,15 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules() // Open the flags file. This should be copy-if-different because the // rules may depend on this file itself. - this->FlagFileNameFull = this->TargetBuildDirectoryFull; - this->FlagFileNameFull += "/flags.make"; + this->FlagFileNameFull = + cmStrCat(this->TargetBuildDirectoryFull, "/flags.make"); this->FlagFileStream = new cmGeneratedFileStream(this->FlagFileNameFull, false, this->GlobalGenerator->GetMakefileEncoding()); - this->FlagFileStream->SetCopyIfDifferent(true); if (!this->FlagFileStream) { return; } + this->FlagFileStream->SetCopyIfDifferent(true); this->LocalGenerator->WriteDisclaimer(*this->FlagFileStream); // Include the flags for the target. @@ -325,9 +329,7 @@ void cmMakefileTargetGenerator::WriteTargetLanguageFlags() // put the compiler in the rules.make file so that if it changes // things rebuild for (std::string const& language : languages) { - std::string compiler = "CMAKE_"; - compiler += language; - compiler += "_COMPILER"; + std::string compiler = cmStrCat("CMAKE_", language, "_COMPILER"); *this->FlagFileStream << "# compile " << language << " with " << this->Makefile->GetSafeDefinition(compiler) << "\n"; @@ -362,9 +364,8 @@ void cmMakefileTargetGenerator::MacOSXContentGeneratorType::operator()( std::string const& input = source.GetFullPath(); // Get the output file location. - std::string output = macdir; - output += "/"; - output += cmSystemTools::GetFilenameName(input); + std::string output = + cmStrCat(macdir, '/', cmSystemTools::GetFilenameName(input)); this->Generator->CleanFiles.insert( this->Generator->LocalGenerator->MaybeConvertToRelativePath( this->Generator->LocalGenerator->GetCurrentBinaryDirectory(), output)); @@ -375,16 +376,16 @@ void cmMakefileTargetGenerator::MacOSXContentGeneratorType::operator()( std::vector<std::string> depends; std::vector<std::string> commands; depends.push_back(input); - std::string copyEcho = "Copying OS X content "; - copyEcho += output; + std::string copyEcho = cmStrCat("Copying OS X content ", output); this->Generator->LocalGenerator->AppendEcho( commands, copyEcho, cmLocalUnixMakefileGenerator3::EchoBuild); - std::string copyCommand = "$(CMAKE_COMMAND) -E copy "; - copyCommand += this->Generator->LocalGenerator->ConvertToOutputFormat( - input, cmOutputConverter::SHELL); - copyCommand += " "; - copyCommand += this->Generator->LocalGenerator->ConvertToOutputFormat( - output, cmOutputConverter::SHELL); + std::string copyCommand = + cmStrCat("$(CMAKE_COMMAND) -E copy ", + this->Generator->LocalGenerator->ConvertToOutputFormat( + input, cmOutputConverter::SHELL), + ' ', + this->Generator->LocalGenerator->ConvertToOutputFormat( + output, cmOutputConverter::SHELL)); commands.push_back(std::move(copyCommand)); this->Generator->LocalGenerator->WriteMakeRule( *this->Generator->BuildFileStream, nullptr, output, depends, commands, @@ -407,9 +408,8 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles( std::string const& objectName = this->GeneratorTarget->GetObjectName(&source); std::string obj = - this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget); - obj += "/"; - obj += objectName; + cmStrCat(this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget), + '/', objectName); // Avoid generating duplicate rules. if (this->ObjectFiles.find(obj) == this->ObjectFiles.end()) { @@ -445,9 +445,8 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles( this->WriteObjectBuildFile(obj, lang, source, depends); // The object file should be checked for dependency integrity. - std::string objFullPath = this->LocalGenerator->GetCurrentBinaryDirectory(); - objFullPath += "/"; - objFullPath += obj; + std::string objFullPath = + cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(), '/', obj); objFullPath = cmSystemTools::CollapseFullPath(objFullPath); std::string srcFullPath = cmSystemTools::CollapseFullPath(source.GetFullPath()); @@ -467,17 +466,15 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile( // generate the depend scanning rule this->WriteObjectDependRules(source, depends); - std::string relativeObj = this->LocalGenerator->GetHomeRelativeOutputPath(); - relativeObj += obj; + std::string relativeObj = + cmStrCat(this->LocalGenerator->GetHomeRelativeOutputPath(), obj); // Write the build rule. // Build the set of compiler flags. std::string flags; // Add language-specific flags. - std::string langFlags = "$("; - langFlags += lang; - langFlags += "_FLAGS)"; + std::string langFlags = cmStrCat("$(", lang, "_FLAGS)"); this->LocalGenerator->AppendFlags(flags, langFlags); std::string config = this->LocalGenerator->GetConfigName(); @@ -539,8 +536,7 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile( << "_DEFINES = " << evaluatedDefs << "\n" << "\n"; } - std::string defPropName = "COMPILE_DEFINITIONS_"; - defPropName += configUpper; + std::string defPropName = cmStrCat("COMPILE_DEFINITIONS_", configUpper); if (const char* config_compile_defs = source.GetProperty(defPropName)) { const std::string& evaluatedDefs = genexInterpreter.Evaluate(config_compile_defs, COMPILE_DEFINITIONS); @@ -564,10 +560,8 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile( if (!this->NoRuleMessages) { cmLocalUnixMakefileGenerator3::EchoProgress progress; this->MakeEchoProgress(progress); - std::string buildEcho = "Building "; - buildEcho += lang; - buildEcho += " object "; - buildEcho += relativeObj; + std::string buildEcho = + cmStrCat("Building ", lang, " object ", relativeObj); this->LocalGenerator->AppendEcho(commands, buildEcho, cmLocalUnixMakefileGenerator3::EchoBuild, &progress); @@ -587,9 +581,8 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile( targetFullPathReal = this->GeneratorTarget->GetFullPath( this->ConfigName, cmStateEnums::RuntimeBinaryArtifact, true); targetFullPathPDB = - this->GeneratorTarget->GetPDBDirectory(this->ConfigName); - targetFullPathPDB += "/"; - targetFullPathPDB += this->GeneratorTarget->GetPDBName(this->ConfigName); + cmStrCat(this->GeneratorTarget->GetPDBDirectory(this->ConfigName), '/', + this->GeneratorTarget->GetPDBName(this->ConfigName)); } targetOutPathReal = this->LocalGenerator->ConvertToOutputFormat( @@ -638,9 +631,7 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile( vars.ObjectFileDir = objectFileDir.c_str(); vars.Flags = flags.c_str(); - std::string definesString = "$("; - definesString += lang; - definesString += "_DEFINES)"; + std::string definesString = cmStrCat("$(", lang, "_DEFINES)"); this->LocalGenerator->JoinDefines(defines, definesString, lang); @@ -781,8 +772,7 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile( // If compiler launcher was specified and not consumed above, it // goes to the beginning of the command line. if (!compileCommands.empty() && !compilerLauncher.empty()) { - std::vector<std::string> args; - cmExpandList(compilerLauncher, args, true); + std::vector<std::string> args = cmExpandedList(compilerLauncher, true); if (!args.empty()) { args[0] = this->LocalGenerator->ConvertToOutputFormat( args[0], cmOutputConverter::SHELL); @@ -798,8 +788,7 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile( const char* val = this->LocalGenerator->GetRuleLauncher( this->GeneratorTarget, "RULE_LAUNCH_COMPILE"); if (val && *val) { - launcher = val; - launcher += " "; + launcher = cmStrCat(val, ' '); } } @@ -846,20 +835,17 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile( std::string relativeObjI = relativeObjBase + ".i"; std::string objI = objBase + ".i"; - std::string preprocessEcho = "Preprocessing "; - preprocessEcho += lang; - preprocessEcho += " source to "; - preprocessEcho += objI; + std::string preprocessEcho = + cmStrCat("Preprocessing ", lang, " source to ", objI); this->LocalGenerator->AppendEcho( commands, preprocessEcho, cmLocalUnixMakefileGenerator3::EchoBuild); - std::string preprocessRuleVar = "CMAKE_"; - preprocessRuleVar += lang; - preprocessRuleVar += "_CREATE_PREPROCESSED_SOURCE"; + std::string preprocessRuleVar = + cmStrCat("CMAKE_", lang, "_CREATE_PREPROCESSED_SOURCE"); if (const char* preprocessRule = this->Makefile->GetDefinition(preprocessRuleVar)) { - std::vector<std::string> preprocessCommands; - cmExpandList(preprocessRule, preprocessCommands); + std::vector<std::string> preprocessCommands = + cmExpandedList(preprocessRule); std::string shellObjI = this->LocalGenerator->ConvertToOutputFormat( objI, cmOutputConverter::SHELL); @@ -878,8 +864,9 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile( this->LocalGenerator->GetBinaryDirectory()); cmAppend(commands, preprocessCommands); } else { - std::string cmd = "$(CMAKE_COMMAND) -E cmake_unimplemented_variable "; - cmd += preprocessRuleVar; + std::string cmd = + cmStrCat("$(CMAKE_COMMAND) -E cmake_unimplemented_variable ", + preprocessRuleVar); commands.push_back(std::move(cmd)); } @@ -893,20 +880,17 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile( std::string relativeObjS = relativeObjBase + ".s"; std::string objS = objBase + ".s"; - std::string assemblyEcho = "Compiling "; - assemblyEcho += lang; - assemblyEcho += " source to assembly "; - assemblyEcho += objS; + std::string assemblyEcho = + cmStrCat("Compiling ", lang, " source to assembly ", objS); this->LocalGenerator->AppendEcho( commands, assemblyEcho, cmLocalUnixMakefileGenerator3::EchoBuild); - std::string assemblyRuleVar = "CMAKE_"; - assemblyRuleVar += lang; - assemblyRuleVar += "_CREATE_ASSEMBLY_SOURCE"; + std::string assemblyRuleVar = + cmStrCat("CMAKE_", lang, "_CREATE_ASSEMBLY_SOURCE"); if (const char* assemblyRule = this->Makefile->GetDefinition(assemblyRuleVar)) { - std::vector<std::string> assemblyCommands; - cmExpandList(assemblyRule, assemblyCommands); + std::vector<std::string> assemblyCommands = + cmExpandedList(assemblyRule); std::string shellObjS = this->LocalGenerator->ConvertToOutputFormat( objS, cmOutputConverter::SHELL); @@ -924,8 +908,9 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile( this->LocalGenerator->GetBinaryDirectory()); cmAppend(commands, assemblyCommands); } else { - std::string cmd = "$(CMAKE_COMMAND) -E cmake_unimplemented_variable "; - cmd += assemblyRuleVar; + std::string cmd = + cmStrCat("$(CMAKE_COMMAND) -E cmake_unimplemented_variable ", + assemblyRuleVar); commands.push_back(std::move(cmd)); } @@ -942,9 +927,9 @@ void cmMakefileTargetGenerator::WriteTargetCleanRules() std::vector<std::string> commands; // Construct the clean target name. - std::string cleanTarget = - this->LocalGenerator->GetRelativeTargetDirectory(this->GeneratorTarget); - cleanTarget += "/clean"; + std::string cleanTarget = cmStrCat( + this->LocalGenerator->GetRelativeTargetDirectory(this->GeneratorTarget), + "/clean"); // Construct the clean command. this->LocalGenerator->AppendCleanCommand(commands, this->CleanFiles, @@ -1028,15 +1013,14 @@ void cmMakefileTargetGenerator::WriteTargetDependRules() // must write the targets depend info file std::string dir = this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget); - this->InfoFileNameFull = dir; - this->InfoFileNameFull += "/DependInfo.cmake"; + this->InfoFileNameFull = cmStrCat(dir, "/DependInfo.cmake"); this->InfoFileNameFull = this->LocalGenerator->ConvertToFullPath(this->InfoFileNameFull); this->InfoFileStream = new cmGeneratedFileStream(this->InfoFileNameFull); - this->InfoFileStream->SetCopyIfDifferent(true); - if (!*this->InfoFileStream) { + if (!this->InfoFileStream) { return; } + this->InfoFileStream->SetCopyIfDifferent(true); this->LocalGenerator->WriteDependLanguageInfo(*this->InfoFileStream, this->GeneratorTarget); @@ -1088,9 +1072,9 @@ void cmMakefileTargetGenerator::WriteTargetDependRules() std::vector<std::string> commands; // Construct the name of the dependency generation target. - std::string depTarget = - this->LocalGenerator->GetRelativeTargetDirectory(this->GeneratorTarget); - depTarget += "/depend"; + std::string depTarget = cmStrCat( + this->LocalGenerator->GetRelativeTargetDirectory(this->GeneratorTarget), + "/depend"); // Add a command to call CMake to scan dependencies. CMake will // touch the corresponding depends file after scanning dependencies. @@ -1235,8 +1219,8 @@ void cmMakefileTargetGenerator::GenerateCustomRuleFile( void cmMakefileTargetGenerator::MakeEchoProgress( cmLocalUnixMakefileGenerator3::EchoProgress& progress) const { - progress.Dir = this->LocalGenerator->GetBinaryDirectory(); - progress.Dir += "/CMakeFiles"; + progress.Dir = + cmStrCat(this->LocalGenerator->GetBinaryDirectory(), "/CMakeFiles"); std::ostringstream progressArg; progressArg << "$(CMAKE_PROGRESS_" << this->NumberOfProgressActions << ")"; progress.Arg = progressArg.str(); @@ -1259,7 +1243,14 @@ void cmMakefileTargetGenerator::WriteObjectsVariable( if (!lineContinue) { lineContinue = "\\"; } + + const char* pchExtension = + this->Makefile->GetDefinition("CMAKE_PCH_EXTENSION"); + for (std::string const& obj : this->Objects) { + if (cmSystemTools::StringEndsWith(obj, pchExtension)) { + continue; + } *this->BuildFileStream << " " << lineContinue << "\n"; *this->BuildFileStream << cmLocalUnixMakefileGenerator3::ConvertToQuotedOutputPath( @@ -1352,10 +1343,16 @@ private: void cmMakefileTargetGenerator::WriteObjectsStrings( std::vector<std::string>& objStrings, std::string::size_type limit) { + const char* pchExtension = + this->Makefile->GetDefinition("CMAKE_PCH_EXTENSION"); + cmMakefileTargetGeneratorObjectStrings helper( objStrings, this->LocalGenerator, this->LocalGenerator->GetStateSnapshot().GetDirectory(), limit); for (std::string const& obj : this->Objects) { + if (cmSystemTools::StringEndsWith(obj, pchExtension)) { + continue; + } helper.Feed(obj); } for (std::string const& obj : this->ExternalObjects) { @@ -1370,8 +1367,8 @@ void cmMakefileTargetGenerator::WriteTargetDriverRule( // Compute the name of the driver target. std::string dir = this->LocalGenerator->GetRelativeTargetDirectory(this->GeneratorTarget); - std::string buildTargetRuleName = dir; - buildTargetRuleName += relink ? "/preinstall" : "/build"; + std::string buildTargetRuleName = + cmStrCat(dir, relink ? "/preinstall" : "/build"); buildTargetRuleName = this->LocalGenerator->MaybeConvertToRelativePath( this->LocalGenerator->GetBinaryDirectory(), buildTargetRuleName); @@ -1426,8 +1423,7 @@ void cmMakefileTargetGenerator::AppendObjectDepends( std::string const& relPath = this->LocalGenerator->GetHomeRelativeOutputPath(); for (std::string const& obj : this->Objects) { - std::string objTarget = relPath; - objTarget += obj; + std::string objTarget = cmStrCat(relPath, obj); depends.push_back(std::move(objTarget)); } @@ -1473,9 +1469,9 @@ std::string cmMakefileTargetGenerator::GetLinkRule( { std::string linkRule = this->Makefile->GetRequiredDefinition(linkRuleVar); if (this->GeneratorTarget->HasImplibGNUtoMS(this->ConfigName)) { - std::string ruleVar = "CMAKE_"; - ruleVar += this->GeneratorTarget->GetLinkerLanguage(this->ConfigName); - ruleVar += "_GNUtoMS_RULE"; + std::string ruleVar = cmStrCat( + "CMAKE_", this->GeneratorTarget->GetLinkerLanguage(this->ConfigName), + "_GNUtoMS_RULE"); if (const char* rule = this->Makefile->GetDefinition(ruleVar)) { linkRule += rule; } @@ -1496,9 +1492,8 @@ void cmMakefileTargetGenerator::CreateLinkScript( std::vector<std::string>& makefile_depends) { // Create the link script file. - std::string linkScriptName = this->TargetBuildDirectoryFull; - linkScriptName += "/"; - linkScriptName += name; + std::string linkScriptName = + cmStrCat(this->TargetBuildDirectoryFull, '/', name); cmGeneratedFileStream linkScriptStream(linkScriptName); linkScriptStream.SetCopyIfDifferent(true); for (std::string const& link_command : link_commands) { @@ -1510,12 +1505,13 @@ void cmMakefileTargetGenerator::CreateLinkScript( } // Create the makefile command to invoke the link script. - std::string link_command = "$(CMAKE_COMMAND) -E cmake_link_script "; - link_command += this->LocalGenerator->ConvertToOutputFormat( - this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), linkScriptName), - cmOutputConverter::SHELL); - link_command += " --verbose=$(VERBOSE)"; + std::string link_command = cmStrCat( + "$(CMAKE_COMMAND) -E cmake_link_script ", + this->LocalGenerator->ConvertToOutputFormat( + this->LocalGenerator->MaybeConvertToRelativePath( + this->LocalGenerator->GetCurrentBinaryDirectory(), linkScriptName), + cmOutputConverter::SHELL), + " --verbose=$(VERBOSE)"); makefile_commands.push_back(std::move(link_command)); makefile_depends.push_back(std::move(linkScriptName)); } @@ -1580,9 +1576,8 @@ std::string cmMakefileTargetGenerator::CreateResponseFile( std::vector<std::string>& makefile_depends) { // Create the response file. - std::string responseFileNameFull = this->TargetBuildDirectoryFull; - responseFileNameFull += "/"; - responseFileNameFull += name; + std::string responseFileNameFull = + cmStrCat(this->TargetBuildDirectoryFull, '/', name); cmGeneratedFileStream responseStream(responseFileNameFull); responseStream.SetCopyIfDifferent(true); responseStream << options << "\n"; @@ -1592,9 +1587,8 @@ std::string cmMakefileTargetGenerator::CreateResponseFile( makefile_depends.push_back(std::move(responseFileNameFull)); // Construct the name to be used on the command line. - std::string responseFileName = this->TargetBuildDirectory; - responseFileName += "/"; - responseFileName += name; + std::string responseFileName = + cmStrCat(this->TargetBuildDirectory, '/', name); return responseFileName; } @@ -1626,10 +1620,9 @@ void cmMakefileTargetGenerator::CreateLinkLibs( if (useResponseFile && linkLibs.find_first_not_of(' ') != std::string::npos) { // Lookup the response file reference flag. - std::string responseFlagVar = "CMAKE_"; - responseFlagVar += - this->GeneratorTarget->GetLinkerLanguage(this->ConfigName); - responseFlagVar += "_RESPONSE_FILE_LINK_FLAG"; + std::string responseFlagVar = cmStrCat( + "CMAKE_", this->GeneratorTarget->GetLinkerLanguage(this->ConfigName), + "_RESPONSE_FILE_LINK_FLAG"); const char* responseFlag = this->Makefile->GetDefinition(responseFlagVar); if (!responseFlag) { responseFlag = "@"; @@ -1640,9 +1633,9 @@ void cmMakefileTargetGenerator::CreateLinkLibs( this->CreateResponseFile("linklibs.rsp", linkLibs, makefile_depends); // Reference the response file. - linkLibs = responseFlag; - linkLibs += this->LocalGenerator->ConvertToOutputFormat( - link_rsp, cmOutputConverter::SHELL); + linkLibs = cmStrCat(responseFlag, + this->LocalGenerator->ConvertToOutputFormat( + link_rsp, cmOutputConverter::SHELL)); } } @@ -1664,10 +1657,9 @@ void cmMakefileTargetGenerator::CreateObjectLists( this->WriteObjectsStrings(object_strings, responseFileLimit); // Lookup the response file reference flag. - std::string responseFlagVar = "CMAKE_"; - responseFlagVar += - this->GeneratorTarget->GetLinkerLanguage(this->ConfigName); - responseFlagVar += "_RESPONSE_FILE_LINK_FLAG"; + std::string responseFlagVar = cmStrCat( + "CMAKE_", this->GeneratorTarget->GetLinkerLanguage(this->ConfigName), + "_RESPONSE_FILE_LINK_FLAG"); const char* responseFlag = this->Makefile->GetDefinition(responseFlagVar); if (!responseFlag) { responseFlag = "@"; @@ -1700,20 +1692,16 @@ void cmMakefileTargetGenerator::CreateObjectLists( buildObjs = objStrings[0]; } } else { - buildObjs = "$("; - buildObjs += variableName; - buildObjs += ") $("; - buildObjs += variableNameExternal; - buildObjs += ")"; + buildObjs = + cmStrCat("$(", variableName, ") $(", variableNameExternal, ')'); } } void cmMakefileTargetGenerator::AddIncludeFlags(std::string& flags, const std::string& lang) { - std::string responseVar = "CMAKE_"; - responseVar += lang; - responseVar += "_USE_RESPONSE_FILE_FOR_INCLUDES"; + std::string responseVar = + cmStrCat("CMAKE_", lang, "_USE_RESPONSE_FILE_FOR_INCLUDES"); bool useResponseFile = this->Makefile->IsOn(responseVar); std::vector<std::string> includes; @@ -1736,9 +1724,7 @@ void cmMakefileTargetGenerator::AddIncludeFlags(std::string& flags, if (responseFlag.empty()) { responseFlag = "@"; } - std::string name = "includes_"; - name += lang; - name += ".rsp"; + std::string name = cmStrCat("includes_", lang, ".rsp"); std::string arg = std::move(responseFlag) + this->CreateResponseFile(name.c_str(), includeFlags, this->FlagFileDepends[lang]); @@ -1757,14 +1743,14 @@ void cmMakefileTargetGenerator::GenDefFile( return; } std::string cmd = cmSystemTools::GetCMakeCommand(); - cmd = - this->LocalGenerator->ConvertToOutputFormat(cmd, cmOutputConverter::SHELL); - cmd += " -E __create_def "; - cmd += this->LocalGenerator->ConvertToOutputFormat( - this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), mdi->DefFile), - cmOutputConverter::SHELL); - cmd += " "; + cmd = cmStrCat( + this->LocalGenerator->ConvertToOutputFormat(cmd, cmOutputConverter::SHELL), + " -E __create_def ", + this->LocalGenerator->ConvertToOutputFormat( + this->LocalGenerator->MaybeConvertToRelativePath( + this->LocalGenerator->GetCurrentBinaryDirectory(), mdi->DefFile), + cmOutputConverter::SHELL), + ' '); std::string objlist_file = mdi->DefFile + ".objs"; cmd += this->LocalGenerator->ConvertToOutputFormat( this->LocalGenerator->MaybeConvertToRelativePath( diff --git a/Source/cmMakefileUtilityTargetGenerator.cxx b/Source/cmMakefileUtilityTargetGenerator.cxx index 8ed6be5..556191f 100644 --- a/Source/cmMakefileUtilityTargetGenerator.cxx +++ b/Source/cmMakefileUtilityTargetGenerator.cxx @@ -25,6 +25,8 @@ cmMakefileUtilityTargetGenerator::cmMakefileUtilityTargetGenerator( this->OSXBundleGenerator = cm::make_unique<cmOSXBundleGenerator>(target, this->ConfigName); this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders); + + this->LocalGenerator->AddPchDependencies(target, this->ConfigName); } cmMakefileUtilityTargetGenerator::~cmMakefileUtilityTargetGenerator() = diff --git a/Source/cmMarkAsAdvancedCommand.cxx b/Source/cmMarkAsAdvancedCommand.cxx index 45c59b9..ca46e14 100644 --- a/Source/cmMarkAsAdvancedCommand.cxx +++ b/Source/cmMarkAsAdvancedCommand.cxx @@ -2,20 +2,19 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmMarkAsAdvancedCommand.h" +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmState.h" #include "cmStateTypes.h" #include "cmSystemTools.h" #include "cmake.h" -class cmExecutionStatus; - // cmMarkAsAdvancedCommand -bool cmMarkAsAdvancedCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmMarkAsAdvancedCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.empty()) { - this->SetError("called with incorrect number of arguments"); + status.SetError("called with incorrect number of arguments"); return false; } @@ -31,9 +30,9 @@ bool cmMarkAsAdvancedCommand::InitialPass(std::vector<std::string> const& args, } for (; i < args.size(); ++i) { std::string const& variable = args[i]; - cmState* state = this->Makefile->GetState(); + cmState* state = status.GetMakefile().GetState(); if (!state->GetCacheEntryValue(variable)) { - this->Makefile->GetCMakeInstance()->AddCacheEntry( + status.GetMakefile().GetCMakeInstance()->AddCacheEntry( variable, nullptr, nullptr, cmStateEnums::UNINITIALIZED); overwrite = true; } diff --git a/Source/cmMarkAsAdvancedCommand.h b/Source/cmMarkAsAdvancedCommand.h index e367c46..de7bf08 100644 --- a/Source/cmMarkAsAdvancedCommand.h +++ b/Source/cmMarkAsAdvancedCommand.h @@ -8,34 +8,14 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmMarkAsAdvancedCommand +/** * \brief mark_as_advanced command * * cmMarkAsAdvancedCommand implements the mark_as_advanced CMake command */ -class cmMarkAsAdvancedCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmMarkAsAdvancedCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; +bool cmMarkAsAdvancedCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmMathCommand.cxx b/Source/cmMathCommand.cxx index 48b9a27..83c22aa 100644 --- a/Source/cmMathCommand.cxx +++ b/Source/cmMathCommand.cxx @@ -2,6 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmMathCommand.h" +#include "cmExecutionStatus.h" #include "cmExprParserHelper.h" #include "cmMakefile.h" #include "cmMessageType.h" @@ -9,28 +10,33 @@ #include <stdio.h> -class cmExecutionStatus; +namespace { +bool HandleExprCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); +} -bool cmMathCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmMathCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.empty()) { - this->SetError("must be called with at least one argument."); + status.SetError("must be called with at least one argument."); return false; } const std::string& subCommand = args[0]; if (subCommand == "EXPR") { - return this->HandleExprCommand(args); + return HandleExprCommand(args, status); } std::string e = "does not recognize sub-command " + subCommand; - this->SetError(e); + status.SetError(e); return false; } -bool cmMathCommand::HandleExprCommand(std::vector<std::string> const& args) +namespace { +bool HandleExprCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if ((args.size() != 3) && (args.size() != 5)) { - this->SetError("EXPR called with incorrect arguments."); + status.SetError("EXPR called with incorrect arguments."); return false; } @@ -46,7 +52,7 @@ bool cmMathCommand::HandleExprCommand(std::vector<std::string> const& args) size_t argumentIndex = 3; NumericFormat outputFormat = NumericFormat::UNINITIALIZED; - this->Makefile->AddDefinition(outputVariable, "ERROR"); + status.GetMakefile().AddDefinition(outputVariable, "ERROR"); if (argumentIndex < args.size()) { const std::string messageHint = "sub-command EXPR "; @@ -61,19 +67,19 @@ bool cmMathCommand::HandleExprCommand(std::vector<std::string> const& args) } else { std::string error = messageHint + "value \"" + argument + "\" for option \"" + option + "\" is invalid."; - this->SetError(error); + status.SetError(error); return false; } } else { std::string error = messageHint + "missing argument for option \"" + option + "\"."; - this->SetError(error); + status.SetError(error); return false; } } else { std::string error = messageHint + "option \"" + option + "\" is unknown."; - this->SetError(error); + status.SetError(error); return false; } } @@ -84,7 +90,7 @@ bool cmMathCommand::HandleExprCommand(std::vector<std::string> const& args) cmExprParserHelper helper; if (!helper.ParseString(expression.c_str(), 0)) { - this->SetError(helper.GetError()); + status.SetError(helper.GetError()); return false; } @@ -104,9 +110,10 @@ bool cmMathCommand::HandleExprCommand(std::vector<std::string> const& args) std::string const& w = helper.GetWarning(); if (!w.empty()) { - this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, w); + status.GetMakefile().IssueMessage(MessageType::AUTHOR_WARNING, w); } - this->Makefile->AddDefinition(outputVariable, buffer); + status.GetMakefile().AddDefinition(outputVariable, buffer); return true; } +} diff --git a/Source/cmMathCommand.h b/Source/cmMathCommand.h index 23633d3..ac1957c 100644 --- a/Source/cmMathCommand.h +++ b/Source/cmMathCommand.h @@ -8,33 +8,10 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; /// Mathematical expressions: math(EXPR ...) command. -class cmMathCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmMathCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; - -protected: - bool HandleExprCommand(std::vector<std::string> const& args); -}; +bool cmMathCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmMessageCommand.cxx b/Source/cmMessageCommand.cxx index dec32fa..39b40b8 100644 --- a/Source/cmMessageCommand.cxx +++ b/Source/cmMessageCommand.cxx @@ -2,6 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmMessageCommand.h" +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmMessenger.h" @@ -12,14 +13,12 @@ #include <cassert> -class cmExecutionStatus; - // cmLibraryCommand -bool cmMessageCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmMessageCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.empty()) { - this->SetError("called with incorrect number of arguments"); + status.SetError("called with incorrect number of arguments"); return false; } auto i = args.cbegin(); @@ -41,12 +40,13 @@ bool cmMessageCommand::InitialPass(std::vector<std::string> const& args, level = cmake::LogLevel::LOG_WARNING; ++i; } else if (*i == "AUTHOR_WARNING") { - if (this->Makefile->IsSet("CMAKE_SUPPRESS_DEVELOPER_ERRORS") && - !this->Makefile->IsOn("CMAKE_SUPPRESS_DEVELOPER_ERRORS")) { + if (status.GetMakefile().IsSet("CMAKE_SUPPRESS_DEVELOPER_ERRORS") && + !status.GetMakefile().IsOn("CMAKE_SUPPRESS_DEVELOPER_ERRORS")) { fatal = true; type = MessageType::AUTHOR_ERROR; level = cmake::LogLevel::LOG_ERROR; - } else if (!this->Makefile->IsOn("CMAKE_SUPPRESS_DEVELOPER_WARNINGS")) { + } else if (!status.GetMakefile().IsOn( + "CMAKE_SUPPRESS_DEVELOPER_WARNINGS")) { type = MessageType::AUTHOR_WARNING; level = cmake::LogLevel::LOG_WARNING; } else { @@ -66,12 +66,12 @@ bool cmMessageCommand::InitialPass(std::vector<std::string> const& args, level = cmake::LogLevel::LOG_TRACE; ++i; } else if (*i == "DEPRECATION") { - if (this->Makefile->IsOn("CMAKE_ERROR_DEPRECATED")) { + if (status.GetMakefile().IsOn("CMAKE_ERROR_DEPRECATED")) { fatal = true; type = MessageType::DEPRECATION_ERROR; level = cmake::LogLevel::LOG_ERROR; - } else if ((!this->Makefile->IsSet("CMAKE_WARN_DEPRECATED") || - this->Makefile->IsOn("CMAKE_WARN_DEPRECATED"))) { + } else if (!status.GetMakefile().IsSet("CMAKE_WARN_DEPRECATED") || + status.GetMakefile().IsOn("CMAKE_WARN_DEPRECATED")) { type = MessageType::DEPRECATION_WARNING; level = cmake::LogLevel::LOG_WARNING; } else { @@ -89,7 +89,7 @@ bool cmMessageCommand::InitialPass(std::vector<std::string> const& args, assert("Message log level expected to be set" && level != cmake::LogLevel::LOG_UNDEFINED); - auto desiredLevel = this->Makefile->GetCMakeInstance()->GetLogLevel(); + auto desiredLevel = status.GetMakefile().GetCMakeInstance()->GetLogLevel(); assert("Expected a valid log level here" && desiredLevel != cmake::LogLevel::LOG_UNDEFINED); @@ -104,7 +104,7 @@ bool cmMessageCommand::InitialPass(std::vector<std::string> const& args, // Check if any indentation has requested: // `CMAKE_MESSAGE_INDENT` is a list of "padding" pieces // to be joined and prepended to the message lines. - auto indent = cmJoin(cmExpandedList(this->Makefile->GetSafeDefinition( + auto indent = cmJoin(cmExpandedList(status.GetMakefile().GetSafeDefinition( "CMAKE_MESSAGE_INDENT")), ""); // Make every line of the `message` indented @@ -118,8 +118,8 @@ bool cmMessageCommand::InitialPass(std::vector<std::string> const& args, case cmake::LogLevel::LOG_ERROR: case cmake::LogLevel::LOG_WARNING: // we've overridden the message type, above, so display it directly - this->Makefile->GetMessenger()->DisplayMessage( - type, message, this->Makefile->GetBacktrace()); + status.GetMakefile().GetMessenger()->DisplayMessage( + type, message, status.GetMakefile().GetBacktrace()); break; case cmake::LogLevel::LOG_NOTICE: @@ -130,7 +130,7 @@ bool cmMessageCommand::InitialPass(std::vector<std::string> const& args, case cmake::LogLevel::LOG_VERBOSE: case cmake::LogLevel::LOG_DEBUG: case cmake::LogLevel::LOG_TRACE: - this->Makefile->DisplayStatus(message, -1); + status.GetMakefile().DisplayStatus(message, -1); break; default: diff --git a/Source/cmMessageCommand.h b/Source/cmMessageCommand.h index ef89d59..7d544c4 100644 --- a/Source/cmMessageCommand.h +++ b/Source/cmMessageCommand.h @@ -8,33 +8,13 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmMessageCommand +/** * \brief Displays a message to the user * */ -class cmMessageCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmMessageCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; +bool cmMessageCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 4ebeb60..0e3aa3a 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -59,6 +59,8 @@ cmNinjaNormalTargetGenerator::cmNinjaNormalTargetGenerator( this->OSXBundleGenerator = cm::make_unique<cmOSXBundleGenerator>(target, this->GetConfigName()); this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders); + + GetLocalGenerator()->AddPchDependencies(target, this->GetConfigName()); } cmNinjaNormalTargetGenerator::~cmNinjaNormalTargetGenerator() = default; @@ -87,6 +89,7 @@ void cmNinjaNormalTargetGenerator::Generate() this->WriteLinkStatement(); } + // Find ADDITIONAL_CLEAN_FILES this->AdditionalCleanFiles(); } @@ -218,8 +221,7 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkRule(bool useResponseFile) const char* val = this->GetLocalGenerator()->GetRuleLauncher( this->GetGeneratorTarget(), "RULE_LAUNCH_LINK"); if (val && *val) { - launcher = val; - launcher += " "; + launcher = cmStrCat(val, ' '); } std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander( @@ -239,16 +241,10 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkRule(bool useResponseFile) rule.Command = this->GetLocalGenerator()->BuildCommandLine(linkCmds); // Write the linker rule with response file if needed. - rule.Comment = "Rule for linking "; - rule.Comment += this->TargetLinkLanguage; - rule.Comment += " "; - rule.Comment += this->GetVisibleTypeName(); - rule.Comment += "."; - rule.Description = "Linking "; - rule.Description += this->TargetLinkLanguage; - rule.Description += " "; - rule.Description += this->GetVisibleTypeName(); - rule.Description += " $TARGET_FILE"; + rule.Comment = cmStrCat("Rule for linking ", this->TargetLinkLanguage, ' ', + this->GetVisibleTypeName(), '.'); + rule.Description = cmStrCat("Linking ", this->TargetLinkLanguage, ' ', + this->GetVisibleTypeName(), " $TARGET_FILE"); rule.Restat = "$RESTAT"; this->GetGlobalGenerator()->AddRule(rule); @@ -282,8 +278,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile) std::string responseFlag; - std::string cmakeVarLang = "CMAKE_"; - cmakeVarLang += this->TargetLinkLanguage; + std::string cmakeVarLang = cmStrCat("CMAKE_", this->TargetLinkLanguage); // build response file name std::string cmakeLinkVar = cmakeVarLang + "_RESPONSE_FILE_LINK_FLAG"; @@ -357,8 +352,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile) const char* val = this->GetLocalGenerator()->GetRuleLauncher( this->GetGeneratorTarget(), "RULE_LAUNCH_LINK"); if (val && *val) { - launcher = val; - launcher += " "; + launcher = cmStrCat(val, ' '); } std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander( @@ -380,16 +374,10 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile) rule.Command = this->GetLocalGenerator()->BuildCommandLine(linkCmds); // Write the linker rule with response file if needed. - rule.Comment = "Rule for linking "; - rule.Comment += this->TargetLinkLanguage; - rule.Comment += " "; - rule.Comment += this->GetVisibleTypeName(); - rule.Comment += "."; - rule.Description = "Linking "; - rule.Description += this->TargetLinkLanguage; - rule.Description += " "; - rule.Description += this->GetVisibleTypeName(); - rule.Description += " $TARGET_FILE"; + rule.Comment = cmStrCat("Rule for linking ", this->TargetLinkLanguage, ' ', + this->GetVisibleTypeName(), '.'); + rule.Description = cmStrCat("Linking ", this->TargetLinkLanguage, ' ', + this->GetVisibleTypeName(), " $TARGET_FILE"); rule.Restat = "$RESTAT"; this->GetGlobalGenerator()->AddRule(rule); } @@ -467,19 +455,19 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd() if (linkCmd) { std::string linkCmdStr = linkCmd; if (this->GetGeneratorTarget()->HasImplibGNUtoMS(this->ConfigName)) { - std::string ruleVar = "CMAKE_"; - ruleVar += this->GeneratorTarget->GetLinkerLanguage(this->ConfigName); - ruleVar += "_GNUtoMS_RULE"; + std::string ruleVar = cmStrCat( + "CMAKE_", this->GeneratorTarget->GetLinkerLanguage(this->ConfigName), + "_GNUtoMS_RULE"); if (const char* rule = this->Makefile->GetDefinition(ruleVar)) { linkCmdStr += rule; } } cmExpandList(linkCmdStr, linkCmds); if (this->GetGeneratorTarget()->GetPropertyAsBool("LINK_WHAT_YOU_USE")) { - std::string cmakeCommand = + std::string cmakeCommand = cmStrCat( this->GetLocalGenerator()->ConvertToOutputFormat( - cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL); - cmakeCommand += " -E __run_co_compile --lwyu="; + cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL), + " -E __run_co_compile --lwyu="); cmGeneratorTarget& gt = *this->GetGeneratorTarget(); const std::string cfgName = this->GetConfigName(); std::string targetOutputReal = this->ConvertToNinjaPath( @@ -502,9 +490,8 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd() } // TODO: Use ARCHIVE_APPEND for archives over a certain size. { - std::string linkCmdVar = "CMAKE_"; - linkCmdVar += this->TargetLinkLanguage; - linkCmdVar += "_ARCHIVE_CREATE"; + std::string linkCmdVar = + cmStrCat("CMAKE_", this->TargetLinkLanguage, "_ARCHIVE_CREATE"); linkCmdVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable( linkCmdVar, this->TargetLinkLanguage, this->GetConfigName()); @@ -513,9 +500,8 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd() cmExpandList(linkCmd, linkCmds); } { - std::string linkCmdVar = "CMAKE_"; - linkCmdVar += this->TargetLinkLanguage; - linkCmdVar += "_ARCHIVE_FINISH"; + std::string linkCmdVar = + cmStrCat("CMAKE_", this->TargetLinkLanguage, "_ARCHIVE_FINISH"); linkCmdVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable( linkCmdVar, this->TargetLinkLanguage, this->GetConfigName()); @@ -590,10 +576,8 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement() // Compute the comment. cmNinjaBuild build(this->LanguageLinkerDeviceRule()); - build.Comment = "Link the "; - build.Comment += this->GetVisibleTypeName(); - build.Comment += " "; - build.Comment += targetOutputReal; + build.Comment = + cmStrCat("Link the ", this->GetVisibleTypeName(), ' ', targetOutputReal); cmNinjaVars& vars = build.Variables; @@ -728,13 +712,9 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() outpath); // Calculate the output path - targetOutput = outpath; - targetOutput += "/"; - targetOutput += this->TargetNames.Output; + targetOutput = cmStrCat(outpath, '/', this->TargetNames.Output); targetOutput = this->ConvertToNinjaPath(targetOutput); - targetOutputReal = outpath; - targetOutputReal += "/"; - targetOutputReal += this->TargetNames.Real; + targetOutputReal = cmStrCat(outpath, '/', this->TargetNames.Real); targetOutputReal = this->ConvertToNinjaPath(targetOutputReal); } else if (gt->IsFrameworkOnApple()) { // Create the library framework. @@ -757,10 +737,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() cmNinjaVars& vars = linkBuild.Variables; // Compute the comment. - linkBuild.Comment = "Link the "; - linkBuild.Comment += this->GetVisibleTypeName(); - linkBuild.Comment += " "; - linkBuild.Comment += targetOutputReal; + linkBuild.Comment = + cmStrCat("Link the ", this->GetVisibleTypeName(), ' ', targetOutputReal); // Compute outputs. linkBuild.Outputs.push_back(targetOutputReal); @@ -967,7 +945,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() >->GetPostBuildCommands() }; - std::vector<std::string> preLinkCmdLines, postBuildCmdLines; + std::vector<std::string> preLinkCmdLines; + std::vector<std::string> postBuildCmdLines; std::vector<std::string>* cmdLineLists[3] = { &preLinkCmdLines, &preLinkCmdLines, &postBuildCmdLines }; @@ -989,11 +968,11 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() std::string cmakeCommand = this->GetLocalGenerator()->ConvertToOutputFormat( cmSystemTools::GetCMakeCommand(), cmOutputConverter::SHELL); - std::string cmd = cmakeCommand; - cmd += " -E __create_def "; - cmd += this->GetLocalGenerator()->ConvertToOutputFormat( - mdi->DefFile, cmOutputConverter::SHELL); - cmd += " "; + std::string cmd = + cmStrCat(cmakeCommand, " -E __create_def ", + this->GetLocalGenerator()->ConvertToOutputFormat( + mdi->DefFile, cmOutputConverter::SHELL), + ' '); std::string obj_list_file = mdi->DefFile + ".objs"; cmd += this->GetLocalGenerator()->ConvertToOutputFormat( obj_list_file, cmOutputConverter::SHELL); @@ -1038,8 +1017,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() symlinkVars["POST_BUILD"] = postBuildCmdLine; } - std::string cmakeVarLang = "CMAKE_"; - cmakeVarLang += this->TargetLinkLanguage; + std::string cmakeVarLang = cmStrCat("CMAKE_", this->TargetLinkLanguage); // build response file name std::string cmakeLinkVar = cmakeVarLang + "_RESPONSE_FILE_LINK_FLAG"; diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 64b2bf6..29e8b74 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -219,8 +219,8 @@ std::string cmNinjaTargetGenerator::ComputeDefines(cmSourceFile const* source, defines, genexInterpreter.Evaluate(compile_defs, COMPILE_DEFINITIONS)); } - std::string defPropName = "COMPILE_DEFINITIONS_"; - defPropName += cmSystemTools::UpperCase(config); + std::string defPropName = + cmStrCat("COMPILE_DEFINITIONS_", cmSystemTools::UpperCase(config)); if (const char* config_compile_defs = source->GetProperty(defPropName)) { this->LocalGenerator->AppendDefines( defines, @@ -374,10 +374,10 @@ std::string cmNinjaTargetGenerator::GetDyndepFilePath( std::string cmNinjaTargetGenerator::GetTargetDependInfoPath( std::string const& lang) const { - std::string path = this->Makefile->GetCurrentBinaryDirectory(); - path += "/"; - path += this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget); - path += "/" + lang + "DependInfo.json"; + std::string path = + cmStrCat(this->Makefile->GetCurrentBinaryDirectory(), '/', + this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget), + '/', lang, "DependInfo.json"); return path; } @@ -416,9 +416,9 @@ bool cmNinjaTargetGenerator::SetMsvcTargetPdbVariable(cmNinjaVars& vars) const this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY || this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY || this->GeneratorTarget->GetType() == cmStateEnums::MODULE_LIBRARY) { - pdbPath = this->GeneratorTarget->GetPDBDirectory(this->GetConfigName()); - pdbPath += "/"; - pdbPath += this->GeneratorTarget->GetPDBName(this->GetConfigName()); + pdbPath = cmStrCat( + this->GeneratorTarget->GetPDBDirectory(this->GetConfigName()), '/', + this->GeneratorTarget->GetPDBName(this->GetConfigName())); } vars["TARGET_PDB"] = this->GetLocalGenerator()->ConvertToOutputFormat( @@ -488,8 +488,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang) const char* val = this->GetLocalGenerator()->GetRuleLauncher( this->GetGeneratorTarget(), "RULE_LAUNCH_COMPILE"); if (val && *val) { - launcher = val; - launcher += " "; + launcher = cmStrCat(val, ' '); } std::string const cmakeCmd = @@ -529,12 +528,8 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang) // If using a response file, move defines, includes, and flags into it. if (!responseFlag.empty()) { rule.RspFile = "$RSP_FILE"; - rule.RspContent = " "; - rule.RspContent += ppVars.Defines; - rule.RspContent += " "; - rule.RspContent += ppVars.Includes; - rule.RspContent += " "; - rule.RspContent += ppFlags; + rule.RspContent = + cmStrCat(' ', ppVars.Defines, ' ', ppVars.Includes, ' ', ppFlags); ppFlags = responseFlag + rule.RspFile; ppVars.Defines = ""; ppVars.Includes = ""; @@ -546,8 +541,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang) std::vector<std::string> ppCmds; { // Lookup the explicit preprocessing rule. - std::string ppVar = "CMAKE_" + lang; - ppVar += "_PREPROCESS_SOURCE"; + std::string ppVar = cmStrCat("CMAKE_", lang, "_PREPROCESS_SOURCE"); cmExpandList(this->GetMakefile()->GetRequiredDefinition(ppVar), ppCmds); } @@ -559,12 +553,9 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang) // Run CMake dependency scanner on preprocessed output. { - std::string ccmd = cmakeCmd; - ccmd += " -E cmake_ninja_depends --tdi="; - ccmd += tdi; - ccmd += " --lang="; - ccmd += lang; - ccmd += " --pp=$out --dep=$DEP_FILE"; + std::string ccmd = + cmStrCat(cmakeCmd, " -E cmake_ninja_depends --tdi=", tdi, + " --lang=", lang, " --pp=$out --dep=$DEP_FILE"); if (needDyndep) { ccmd += " --obj=$OBJ_FILE --ddi=$DYNDEP_INTERMEDIATE_FILE"; } @@ -573,12 +564,8 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang) rule.Command = this->GetLocalGenerator()->BuildCommandLine(ppCmds); // Write the rule for preprocessing file of the given language. - rule.Comment = "Rule for preprocessing "; - rule.Comment += lang; - rule.Comment += " files."; - rule.Description = "Building "; - rule.Description += lang; - rule.Description += " preprocessed $out"; + rule.Comment = cmStrCat("Rule for preprocessing ", lang, " files."); + rule.Description = cmStrCat("Building ", lang, " preprocessed $out"); this->GetGlobalGenerator()->AddRule(rule); } @@ -595,24 +582,16 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang) { std::vector<std::string> ddCmds; { - std::string ccmd = cmakeCmd; - ccmd += " -E cmake_ninja_dyndep --tdi="; - ccmd += tdi; - ccmd += " --lang="; - ccmd += lang; - ccmd += " --dd=$out "; - ccmd += "@"; - ccmd += rule.RspFile; + std::string ccmd = + cmStrCat(cmakeCmd, " -E cmake_ninja_dyndep --tdi=", tdi, + " --lang=", lang, " --dd=$out @", rule.RspFile); ddCmds.emplace_back(std::move(ccmd)); } rule.Command = this->GetLocalGenerator()->BuildCommandLine(ddCmds); } - rule.Comment = "Rule to generate ninja dyndep files for "; - rule.Comment += lang; - rule.Comment += "."; - rule.Description = "Generating "; - rule.Description += lang; - rule.Description += " dyndep file $out"; + rule.Comment = + cmStrCat("Rule to generate ninja dyndep files for ", lang, '.'); + rule.Description = cmStrCat("Generating ", lang, " dyndep file $out"); this->GetGlobalGenerator()->AddRule(rule); } @@ -620,12 +599,8 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang) // If using a response file, move defines, includes, and flags into it. if (!responseFlag.empty()) { rule.RspFile = "$RSP_FILE"; - rule.RspContent = " "; - rule.RspContent += vars.Defines; - rule.RspContent += " "; - rule.RspContent += vars.Includes; - rule.RspContent += " "; - rule.RspContent += flags; + rule.RspContent = + cmStrCat(' ', vars.Defines, ' ', vars.Includes, ' ', flags); flags = responseFlag + rule.RspFile; vars.Defines = ""; vars.Includes = ""; @@ -648,11 +623,10 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang) const std::string cl = mf->GetDefinition("CMAKE_C_COMPILER") ? mf->GetSafeDefinition("CMAKE_C_COMPILER") : mf->GetSafeDefinition("CMAKE_CXX_COMPILER"); - cldeps = "\""; - cldeps += cmSystemTools::GetCMClDepsCommand(); - cldeps += "\" " + lang + " " + vars.Source + " $DEP_FILE $out \""; - cldeps += mf->GetSafeDefinition("CMAKE_CL_SHOWINCLUDES_PREFIX"); - cldeps += "\" \"" + cl + "\" "; + cldeps = cmStrCat('"', cmSystemTools::GetCMClDepsCommand(), "\" ", lang, + ' ', vars.Source, " $DEP_FILE $out \"", + mf->GetSafeDefinition("CMAKE_CL_SHOWINCLUDES_PREFIX"), + "\" \"", cl, "\" "); } } else { rule.DepType = "gcc"; @@ -715,8 +689,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang) const char* cppcheck = this->GeneratorTarget->GetProperty(cppcheck_prop); if ((iwyu && *iwyu) || (tidy && *tidy) || (cpplint && *cpplint) || (cppcheck && *cppcheck)) { - std::string run_iwyu = cmakeCmd; - run_iwyu += " -E __run_co_compile"; + std::string run_iwyu = cmStrCat(cmakeCmd, " -E __run_co_compile"); if (!compilerLauncher.empty()) { // In __run_co_compile case the launcher command is supplied // via --launcher=<maybe-list> and consumed @@ -752,8 +725,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang) // If compiler launcher was specified and not consumed above, it // goes to the beginning of the command line. if (!compileCmds.empty() && !compilerLauncher.empty()) { - std::vector<std::string> args; - cmExpandList(compilerLauncher, args, true); + std::vector<std::string> args = cmExpandedList(compilerLauncher, true); if (!args.empty()) { args[0] = this->LocalGenerator->ConvertToOutputFormat( args[0], cmOutputConverter::SHELL); @@ -777,12 +749,8 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang) rule.Command = this->GetLocalGenerator()->BuildCommandLine(compileCmds); // Write the rule for compiling file of the given language. - rule.Comment = "Rule for compiling "; - rule.Comment += lang; - rule.Comment += " files."; - rule.Description = "Building "; - rule.Description += lang; - rule.Description += " object $out"; + rule.Comment = cmStrCat("Rule for compiling ", lang, " files."); + rule.Description = cmStrCat("Building ", lang, " object $out"); this->GetGlobalGenerator()->AddRule(rule); } @@ -822,10 +790,16 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements() extraSources, this->MacOSXContentGenerator.get()); } { + const char* pchExtension = + GetMakefile()->GetDefinition("CMAKE_PCH_EXTENSION"); + std::vector<cmSourceFile const*> externalObjects; this->GeneratorTarget->GetExternalObjects(externalObjects, config); for (cmSourceFile const* sf : externalObjects) { - this->Objects.push_back(this->GetSourceFilePath(sf)); + const auto objectFileName = this->GetSourceFilePath(sf); + if (!cmSystemTools::StringEndsWith(objectFileName, pchExtension)) { + this->Objects.push_back(objectFileName); + } } } @@ -864,11 +838,9 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements() if (orderOnlyDeps.empty()) { // Any path that always exists will work here. It would be nice to // use just "." but that is not supported by Ninja < 1.7. - std::string tgtDir; - tgtDir += this->LocalGenerator->GetCurrentBinaryDirectory(); - tgtDir += "/"; - tgtDir += - this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget); + std::string tgtDir = cmStrCat( + this->LocalGenerator->GetCurrentBinaryDirectory(), '/', + this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget)); orderOnlyDeps.push_back(this->ConvertToNinjaPath(tgtDir)); } @@ -945,8 +917,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( std::string const objectFileDir = cmSystemTools::GetFilenamePath(objectFileName); - std::string cmakeVarLang = "CMAKE_"; - cmakeVarLang += language; + std::string cmakeVarLang = cmStrCat("CMAKE_", language); // build response file name std::string cmakeLinkVar = cmakeVarLang + "_RESPONSE_FILE_FLAG"; @@ -967,9 +938,8 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( if (!this->NeedDepTypeMSVC(language)) { bool replaceExt(false); if (!language.empty()) { - std::string repVar = "CMAKE_"; - repVar += language; - repVar += "_DEPFILE_EXTENSION_REPLACE"; + std::string repVar = + cmStrCat("CMAKE_", language, "_DEPFILE_EXTENSION_REPLACE"); replaceExt = this->Makefile->IsOn(repVar); } if (!replaceExt) { @@ -991,8 +961,12 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( vars["FLAGS"], vars["DEFINES"], vars["INCLUDES"]); objBuild.Outputs.push_back(objectFileName); - // Add this object to the list of object files. - this->Objects.push_back(objectFileName); + const char* pchExtension = + this->GetMakefile()->GetDefinition("CMAKE_PCH_EXTENSION"); + if (!cmSystemTools::StringEndsWith(objectFileName, pchExtension)) { + // Add this object to the list of object files. + this->Objects.push_back(objectFileName); + } objBuild.ExplicitDeps.push_back(sourceFileName); @@ -1383,9 +1357,8 @@ void cmNinjaTargetGenerator::MacOSXContentGeneratorType::operator()( input = this->Generator->GetGlobalGenerator()->ConvertToNinjaPath(input); // Get the output file location. - std::string output = macdir; - output += "/"; - output += cmSystemTools::GetFilenameName(input); + std::string output = + cmStrCat(macdir, '/', cmSystemTools::GetFilenameName(input)); output = this->Generator->GetGlobalGenerator()->ConvertToNinjaPath(output); // Write a build statement to copy the content into the bundle. diff --git a/Source/cmNinjaUtilityTargetGenerator.cxx b/Source/cmNinjaUtilityTargetGenerator.cxx index 8fca4c0..eea4c93 100644 --- a/Source/cmNinjaUtilityTargetGenerator.cxx +++ b/Source/cmNinjaUtilityTargetGenerator.cxx @@ -13,6 +13,7 @@ #include "cmOutputConverter.h" #include "cmSourceFile.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include <algorithm> @@ -36,14 +37,15 @@ void cmNinjaUtilityTargetGenerator::Generate() cmLocalNinjaGenerator* lg = this->GetLocalGenerator(); cmGeneratorTarget* genTarget = this->GetGeneratorTarget(); - std::string utilCommandName = lg->GetCurrentBinaryDirectory(); - utilCommandName += "/CMakeFiles/"; - utilCommandName += this->GetTargetName() + ".util"; + std::string utilCommandName = + cmStrCat(lg->GetCurrentBinaryDirectory(), "/CMakeFiles/", + this->GetTargetName(), ".util"); utilCommandName = this->ConvertToNinjaPath(utilCommandName); cmNinjaBuild phonyBuild("phony"); std::vector<std::string> commands; - cmNinjaDeps deps, util_outputs(1, utilCommandName); + cmNinjaDeps deps; + cmNinjaDeps util_outputs(1, utilCommandName); bool uses_terminal = false; { @@ -134,6 +136,9 @@ void cmNinjaUtilityTargetGenerator::Generate() gg->WriteBuild(this->GetBuildFileStream(), phonyBuild); } + // Find ADDITIONAL_CLEAN_FILES + this->AdditionalCleanFiles(); + // Add an alias for the logical target name regardless of what directory // contains it. Skip this for GLOBAL_TARGET because they are meant to // be per-directory and have one at the top-level anyway. diff --git a/Source/cmOSXBundleGenerator.cxx b/Source/cmOSXBundleGenerator.cxx index 47a8df4..6175c1e 100644 --- a/Source/cmOSXBundleGenerator.cxx +++ b/Source/cmOSXBundleGenerator.cxx @@ -6,6 +6,7 @@ #include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" @@ -40,20 +41,20 @@ void cmOSXBundleGenerator::CreateAppBundle(const std::string& targetName, } // Compute bundle directory names. - std::string out = outpath; - out += "/"; - out += this->GT->GetAppBundleDirectory(this->ConfigName, - cmGeneratorTarget::FullLevel); + std::string out = + cmStrCat(outpath, '/', + this->GT->GetAppBundleDirectory(this->ConfigName, + cmGeneratorTarget::FullLevel)); cmSystemTools::MakeDirectory(out); this->Makefile->AddCMakeOutputFile(out); // Configure the Info.plist file. Note that it needs the executable name // to be set. - std::string plist = outpath; - plist += "/"; - plist += this->GT->GetAppBundleDirectory(this->ConfigName, - cmGeneratorTarget::ContentLevel); - plist += "/Info.plist"; + std::string plist = + cmStrCat(outpath, '/', + this->GT->GetAppBundleDirectory(this->ConfigName, + cmGeneratorTarget::ContentLevel), + "/Info.plist"); this->LocalGenerator->GenerateAppleInfoPList(this->GT, targetName, plist); this->Makefile->AddCMakeOutputFile(plist); outpath = out; @@ -69,10 +70,11 @@ void cmOSXBundleGenerator::CreateFramework(const std::string& targetName, assert(this->MacContentFolders); // Compute the location of the top-level foo.framework directory. - std::string contentdir = outpath + "/" + - this->GT->GetFrameworkDirectory(this->ConfigName, - cmGeneratorTarget::ContentLevel); - contentdir += "/"; + std::string contentdir = + cmStrCat(outpath, '/', + this->GT->GetFrameworkDirectory(this->ConfigName, + cmGeneratorTarget::ContentLevel), + '/'); std::string newoutpath = outpath + "/" + this->GT->GetFrameworkDirectory(this->ConfigName, @@ -102,8 +104,7 @@ void cmOSXBundleGenerator::CreateFramework(const std::string& targetName, std::string newName; // Make foo.framework/Versions - std::string versions = contentdir; - versions += "Versions"; + std::string versions = cmStrCat(contentdir, "Versions"); cmSystemTools::MakeDirectory(versions); // Make foo.framework/Versions/version @@ -111,17 +112,14 @@ void cmOSXBundleGenerator::CreateFramework(const std::string& targetName, // Current -> version oldName = frameworkVersion; - newName = versions; - newName += "/Current"; + newName = cmStrCat(versions, "/Current"); cmSystemTools::RemoveFile(newName); cmSystemTools::CreateSymlink(oldName, newName); this->Makefile->AddCMakeOutputFile(newName); // foo -> Versions/Current/foo - oldName = "Versions/Current/"; - oldName += name; - newName = contentdir; - newName += name; + oldName = cmStrCat("Versions/Current/", name); + newName = cmStrCat(contentdir, name); cmSystemTools::RemoveFile(newName); cmSystemTools::CreateSymlink(oldName, newName); this->Makefile->AddCMakeOutputFile(newName); @@ -130,8 +128,7 @@ void cmOSXBundleGenerator::CreateFramework(const std::string& targetName, if (this->MacContentFolders->find("Resources") != this->MacContentFolders->end()) { oldName = "Versions/Current/Resources"; - newName = contentdir; - newName += "Resources"; + newName = cmStrCat(contentdir, "Resources"); cmSystemTools::RemoveFile(newName); cmSystemTools::CreateSymlink(oldName, newName); this->Makefile->AddCMakeOutputFile(newName); @@ -141,8 +138,7 @@ void cmOSXBundleGenerator::CreateFramework(const std::string& targetName, if (this->MacContentFolders->find("Headers") != this->MacContentFolders->end()) { oldName = "Versions/Current/Headers"; - newName = contentdir; - newName += "Headers"; + newName = cmStrCat(contentdir, "Headers"); cmSystemTools::RemoveFile(newName); cmSystemTools::CreateSymlink(oldName, newName); this->Makefile->AddCMakeOutputFile(newName); @@ -152,8 +148,7 @@ void cmOSXBundleGenerator::CreateFramework(const std::string& targetName, if (this->MacContentFolders->find("PrivateHeaders") != this->MacContentFolders->end()) { oldName = "Versions/Current/PrivateHeaders"; - newName = contentdir; - newName += "PrivateHeaders"; + newName = cmStrCat(contentdir, "PrivateHeaders"); cmSystemTools::RemoveFile(newName); cmSystemTools::CreateSymlink(oldName, newName); this->Makefile->AddCMakeOutputFile(newName); @@ -168,19 +163,20 @@ void cmOSXBundleGenerator::CreateCFBundle(const std::string& targetName, } // Compute bundle directory names. - std::string out = root; - out += "/"; - out += this->GT->GetCFBundleDirectory(this->ConfigName, - cmGeneratorTarget::FullLevel); + std::string out = + cmStrCat(root, '/', + this->GT->GetCFBundleDirectory(this->ConfigName, + cmGeneratorTarget::FullLevel)); cmSystemTools::MakeDirectory(out); this->Makefile->AddCMakeOutputFile(out); // Configure the Info.plist file. Note that it needs the executable name // to be set. - std::string plist = root + "/" + - this->GT->GetCFBundleDirectory(this->ConfigName, - cmGeneratorTarget::ContentLevel); - plist += "/Info.plist"; + std::string plist = + cmStrCat(root, '/', + this->GT->GetCFBundleDirectory(this->ConfigName, + cmGeneratorTarget::ContentLevel), + "/Info.plist"); std::string name = cmSystemTools::GetFilenameName(targetName); this->LocalGenerator->GenerateAppleInfoPList(this->GT, name, plist); this->Makefile->AddCMakeOutputFile(plist); @@ -208,10 +204,10 @@ std::string cmOSXBundleGenerator::InitMacOSXContentDirectory( { // Construct the full path to the content subdirectory. - std::string macdir = this->GT->GetMacContentDirectory( - this->ConfigName, cmStateEnums::RuntimeBinaryArtifact); - macdir += "/"; - macdir += pkgloc; + std::string macdir = + cmStrCat(this->GT->GetMacContentDirectory( + this->ConfigName, cmStateEnums::RuntimeBinaryArtifact), + '/', pkgloc); cmSystemTools::MakeDirectory(macdir); // Record use of this content location. Only the first level diff --git a/Source/cmOptionCommand.cxx b/Source/cmOptionCommand.cxx index a30f487..a0a0989 100644 --- a/Source/cmOptionCommand.cxx +++ b/Source/cmOptionCommand.cxx @@ -4,6 +4,7 @@ #include <sstream> +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmPolicies.h" @@ -12,27 +13,26 @@ #include "cmStateTypes.h" #include "cmStringAlgorithms.h" -class cmExecutionStatus; - // cmOptionCommand -bool cmOptionCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmOptionCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { const bool argError = (args.size() < 2) || (args.size() > 3); if (argError) { - std::string m = "called with incorrect number of arguments: "; - m += cmJoin(args, " "); - this->SetError(m); + std::string m = cmStrCat("called with incorrect number of arguments: ", + cmJoin(args, " ")); + status.SetError(m); return false; } // Determine the state of the option policy bool checkAndWarn = false; { - auto status = this->Makefile->GetPolicyStatus(cmPolicies::CMP0077); + auto policyStatus = + status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0077); const auto* existsBeforeSet = - this->Makefile->GetStateSnapshot().GetDefinition(args[0]); - switch (status) { + status.GetMakefile().GetStateSnapshot().GetDefinition(args[0]); + switch (policyStatus) { case cmPolicies::WARN: checkAndWarn = (existsBeforeSet != nullptr); break; @@ -53,7 +53,7 @@ bool cmOptionCommand::InitialPass(std::vector<std::string> const& args, // See if a cache variable with this name already exists // If so just make sure the doc state is correct - cmState* state = this->Makefile->GetState(); + cmState* state = status.GetMakefile().GetState(); const char* existingValue = state->GetCacheEntryValue(args[0]); if (existingValue && (state->GetCacheEntryType(args[0]) != cmStateEnums::UNINITIALIZED)) { @@ -67,12 +67,12 @@ bool cmOptionCommand::InitialPass(std::vector<std::string> const& args, initialValue = args[2]; } bool init = cmIsOn(initialValue); - this->Makefile->AddCacheDefinition(args[0], init ? "ON" : "OFF", - args[1].c_str(), cmStateEnums::BOOL); + status.GetMakefile().AddCacheDefinition(args[0], init ? "ON" : "OFF", + args[1].c_str(), cmStateEnums::BOOL); if (checkAndWarn) { const auto* existsAfterSet = - this->Makefile->GetStateSnapshot().GetDefinition(args[0]); + status.GetMakefile().GetStateSnapshot().GetDefinition(args[0]); if (!existsAfterSet) { std::ostringstream w; w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0077) @@ -80,7 +80,7 @@ bool cmOptionCommand::InitialPass(std::vector<std::string> const& args, "For compatibility with older versions of CMake, option " "is clearing the normal variable '" << args[0] << "'."; - this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, w.str()); + status.GetMakefile().IssueMessage(MessageType::AUTHOR_WARNING, w.str()); } } return true; diff --git a/Source/cmOptionCommand.h b/Source/cmOptionCommand.h index eddab03..cbd1cb8 100644 --- a/Source/cmOptionCommand.h +++ b/Source/cmOptionCommand.h @@ -8,34 +8,13 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmOptionCommand +/** * \brief Provide an option to the user * * cmOptionCommand provides an option for the user to select */ -class cmOptionCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmOptionCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; - +bool cmOptionCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmOrderDirectories.cxx b/Source/cmOrderDirectories.cxx index 2d055ff..21a17e8 100644 --- a/Source/cmOrderDirectories.cxx +++ b/Source/cmOrderDirectories.cxx @@ -6,6 +6,7 @@ #include "cmGeneratorTarget.h" #include "cmGlobalGenerator.h" #include "cmMessageType.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmake.h" @@ -117,9 +118,7 @@ bool cmOrderDirectoriesConstraint::FileMayConflict(std::string const& dir, std::string const& name) { // Check if the file exists on disk. - std::string file = dir; - file += "/"; - file += name; + std::string file = cmStrCat(dir, '/', name); if (cmSystemTools::FileExists(file, true)) { // The file conflicts only if it is not the same as the original // file due to a symlink or hardlink. @@ -229,8 +228,7 @@ bool cmOrderDirectoriesConstraintLibrary::FindConflict(std::string const& dir) std::string ext = this->OD->RemoveLibraryExtension.match(2); for (std::string const& LinkExtension : this->OD->LinkExtensions) { if (LinkExtension != ext) { - std::string fname = lib; - fname += LinkExtension; + std::string fname = cmStrCat(lib, LinkExtension); if (this->FileMayConflict(dir, fname)) { return true; } diff --git a/Source/cmOutputRequiredFilesCommand.cxx b/Source/cmOutputRequiredFilesCommand.cxx index de47ce0..3d8ebc3 100644 --- a/Source/cmOutputRequiredFilesCommand.cxx +++ b/Source/cmOutputRequiredFilesCommand.cxx @@ -5,9 +5,12 @@ #include "cmsys/FStream.hxx" #include "cmsys/RegularExpression.hxx" #include <map> +#include <set> +#include <stdio.h> #include <utility> #include "cmAlgorithms.h" +#include "cmExecutionStatus.h" #include "cmGeneratorExpression.h" #include "cmMakefile.h" #include "cmSourceFile.h" @@ -15,8 +18,7 @@ #include "cmSystemTools.h" #include "cmTarget.h" -class cmExecutionStatus; - +namespace { /** \class cmDependInformation * \brief Store dependency information for a single source file. * @@ -122,8 +124,7 @@ public: std::string incDirs = cmGeneratorExpression::Preprocess( incDirProp, cmGeneratorExpression::StripAllGeneratorExpressions); - std::vector<std::string> includes; - cmExpandList(incDirs, includes); + std::vector<std::string> includes = cmExpandedList(incDirs); for (std::string& path : includes) { this->Makefile->ExpandVariablesInString(path); @@ -193,10 +194,8 @@ protected: // see if the include matches the regular expression if (!this->IncludeFileRegularExpression.find(includeFile)) { if (this->Verbose) { - std::string message = "Skipping "; - message += includeFile; - message += " for file "; - message += info->FullPath; + std::string message = + cmStrCat("Skipping ", includeFile, " for file ", info->FullPath); cmSystemTools::Error(message); } continue; @@ -455,43 +454,47 @@ protected: DirectoryToFileToPathMapType DirectoryToFileToPathMap; }; +void ListDependencies(cmDependInformation const* info, FILE* fout, + std::set<cmDependInformation const*>* visited); +} + // cmOutputRequiredFilesCommand -bool cmOutputRequiredFilesCommand::InitialPass( - std::vector<std::string> const& args, cmExecutionStatus&) +bool cmOutputRequiredFilesCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() != 2) { - this->SetError("called with incorrect number of arguments"); + status.SetError("called with incorrect number of arguments"); return false; } // store the arg for final pass - this->File = args[0]; - this->OutputFile = args[1]; + const std::string& file = args[0]; + const std::string& outputFile = args[1]; // compute the list of files cmLBDepend md; - md.SetMakefile(this->Makefile); - md.AddSearchPath(this->Makefile->GetCurrentSourceDirectory()); + md.SetMakefile(&status.GetMakefile()); + md.AddSearchPath(status.GetMakefile().GetCurrentSourceDirectory()); // find the depends for a file - const cmDependInformation* info = md.FindDependencies(this->File.c_str()); + const cmDependInformation* info = md.FindDependencies(file.c_str()); if (info) { // write them out - FILE* fout = cmsys::SystemTools::Fopen(this->OutputFile, "w"); + FILE* fout = cmsys::SystemTools::Fopen(outputFile, "w"); if (!fout) { - this->SetError(cmStrCat("Can not open output file: ", this->OutputFile)); + status.SetError(cmStrCat("Can not open output file: ", outputFile)); return false; } std::set<cmDependInformation const*> visited; - this->ListDependencies(info, fout, &visited); + ListDependencies(info, fout, &visited); fclose(fout); } return true; } -void cmOutputRequiredFilesCommand::ListDependencies( - cmDependInformation const* info, FILE* fout, - std::set<cmDependInformation const*>* visited) +namespace { +void ListDependencies(cmDependInformation const* info, FILE* fout, + std::set<cmDependInformation const*>* visited) { // add info to the visited set visited->insert(info); @@ -506,7 +509,8 @@ void cmOutputRequiredFilesCommand::ListDependencies( fprintf(fout, "%s\n", d->FullPath.c_str()); } } - this->ListDependencies(d, fout, visited); + ListDependencies(d, fout, visited); } } } +} diff --git a/Source/cmOutputRequiredFilesCommand.h b/Source/cmOutputRequiredFilesCommand.h index faffabd..4c11894 100644 --- a/Source/cmOutputRequiredFilesCommand.h +++ b/Source/cmOutputRequiredFilesCommand.h @@ -5,34 +5,12 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include <set> -#include <stdio.h> #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - -class cmDependInformation; class cmExecutionStatus; -class cmOutputRequiredFilesCommand : public cmCommand -{ -public: - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmOutputRequiredFilesCommand>(); - } - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; - - void ListDependencies(cmDependInformation const* info, FILE* fout, - std::set<cmDependInformation const*>* visited); - -private: - std::string File; - std::string OutputFile; -}; +bool cmOutputRequiredFilesCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmParseArgumentsCommand.cxx b/Source/cmParseArgumentsCommand.cxx index 5e7e2f3..aad9f74 100644 --- a/Source/cmParseArgumentsCommand.cxx +++ b/Source/cmParseArgumentsCommand.cxx @@ -8,6 +8,7 @@ #include <utility> #include "cmArgumentParser.h" +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmRange.h" @@ -15,8 +16,6 @@ #include "cmSystemTools.h" #include "cm_string_view.hxx" -class cmExecutionStatus; - static std::string EscapeArg(const std::string& arg) { // replace ";" with "\;" so output argument lists will split correctly @@ -105,25 +104,25 @@ static void PassParsedArguments( } } -bool cmParseArgumentsCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmParseArgumentsCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { // cmake_parse_arguments(prefix options single multi <ARGN>) // 1 2 3 4 // or // cmake_parse_arguments(PARSE_ARGV N prefix options single multi) if (args.size() < 4) { - this->SetError("must be called with at least 4 arguments."); + status.SetError("must be called with at least 4 arguments."); return false; } - std::vector<std::string>::const_iterator argIter = args.begin(), - argEnd = args.end(); + std::vector<std::string>::const_iterator argIter = args.begin(); + std::vector<std::string>::const_iterator argEnd = args.end(); bool parseFromArgV = false; unsigned long argvStart = 0; if (*argIter == "PARSE_ARGV") { if (args.size() != 6) { - this->Makefile->IssueMessage( + status.GetMakefile().IssueMessage( MessageType::FATAL_ERROR, "PARSE_ARGV must be called with exactly 6 arguments."); cmSystemTools::SetFatalErrorOccured(); @@ -132,9 +131,9 @@ bool cmParseArgumentsCommand::InitialPass(std::vector<std::string> const& args, parseFromArgV = true; argIter++; // move past PARSE_ARGV if (!cmStrToULong(*argIter, &argvStart)) { - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, - "PARSE_ARGV index '" + *argIter + - "' is not an unsigned integer"); + status.GetMakefile().IssueMessage(MessageType::FATAL_ERROR, + "PARSE_ARGV index '" + *argIter + + "' is not an unsigned integer"); cmSystemTools::SetFatalErrorOccured(); return true; } @@ -154,14 +153,13 @@ bool cmParseArgumentsCommand::InitialPass(std::vector<std::string> const& args, // anything else is put into a vector of unparsed strings std::vector<std::string> unparsed; - auto const duplicateKey = [this](std::string const& key) { - this->GetMakefile()->IssueMessage( + auto const duplicateKey = [&status](std::string const& key) { + status.GetMakefile().IssueMessage( MessageType::WARNING, "keyword defined more than once: " + key); }; // the second argument is a (cmake) list of options without argument - std::vector<std::string> list; - cmExpandList(*argIter++, list); + std::vector<std::string> list = cmExpandedList(*argIter++); parser.Bind(list, options, duplicateKey); // the third argument is a (cmake) list of single argument options @@ -183,23 +181,24 @@ bool cmParseArgumentsCommand::InitialPass(std::vector<std::string> const& args, } } else { // in the PARSE_ARGV move read the arguments from ARGC and ARGV# - std::string argc = this->Makefile->GetSafeDefinition("ARGC"); + std::string argc = status.GetMakefile().GetSafeDefinition("ARGC"); unsigned long count; if (!cmStrToULong(argc, &count)) { - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, - "PARSE_ARGV called with ARGC='" + argc + - "' that is not an unsigned integer"); + status.GetMakefile().IssueMessage(MessageType::FATAL_ERROR, + "PARSE_ARGV called with ARGC='" + + argc + + "' that is not an unsigned integer"); cmSystemTools::SetFatalErrorOccured(); return true; } for (unsigned long i = argvStart; i < count; ++i) { std::ostringstream argName; argName << "ARGV" << i; - const char* arg = this->Makefile->GetDefinition(argName.str()); + const char* arg = status.GetMakefile().GetDefinition(argName.str()); if (!arg) { - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, - "PARSE_ARGV called with " + - argName.str() + " not set"); + status.GetMakefile().IssueMessage(MessageType::FATAL_ERROR, + "PARSE_ARGV called with " + + argName.str() + " not set"); cmSystemTools::SetFatalErrorOccured(); return true; } @@ -212,7 +211,8 @@ bool cmParseArgumentsCommand::InitialPass(std::vector<std::string> const& args, parser.Parse(list, &unparsed, &keywordsMissingValues); PassParsedArguments( - prefix, *this->Makefile, options, singleValArgs, multiValArgs, unparsed, + prefix, status.GetMakefile(), options, singleValArgs, multiValArgs, + unparsed, options_set(keywordsMissingValues.begin(), keywordsMissingValues.end()), parseFromArgV); diff --git a/Source/cmParseArgumentsCommand.h b/Source/cmParseArgumentsCommand.h index 692ea64..b2e436d 100644 --- a/Source/cmParseArgumentsCommand.h +++ b/Source/cmParseArgumentsCommand.h @@ -8,32 +8,9 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmParseArgumentsCommand - * - */ -class cmParseArgumentsCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmParseArgumentsCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; +bool cmParseArgumentsCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx index 96d9843..f8c5ada 100644 --- a/Source/cmProjectCommand.cxx +++ b/Source/cmProjectCommand.cxx @@ -102,11 +102,10 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, } doing = DoingLanguages; if (!languages.empty()) { - std::string msg = + std::string msg = cmStrCat( "the following parameters must be specified after LANGUAGES " - "keyword: "; - msg += cmJoin(languages, ", "); - msg += '.'; + "keyword: ", + cmJoin(languages, ", "), '.'); this->Makefile->IssueMessage(MessageType::WARNING, msg); } } else if (args[i] == "VERSION") { @@ -368,9 +367,9 @@ bool cmProjectCommand::IncludeByVariable(const std::string& variable) return true; } - std::string m = "could not find file:\n" - " "; - m += include; + std::string m = cmStrCat("could not find file:\n" + " ", + include); this->SetError(m); return false; } diff --git a/Source/cmQTWrapCPPCommand.cxx b/Source/cmQTWrapCPPCommand.cxx index f5852a9..ba82813 100644 --- a/Source/cmQTWrapCPPCommand.cxx +++ b/Source/cmQTWrapCPPCommand.cxx @@ -6,6 +6,7 @@ #include "cmMakefile.h" #include "cmRange.h" #include "cmSourceFile.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include <utility> @@ -37,10 +38,8 @@ bool cmQTWrapCPPCommand::InitialPass(std::vector<std::string> const& args, // Compute the name of the file to generate. std::string srcName = cmSystemTools::GetFilenameWithoutLastExtension(arg); - std::string newName = this->Makefile->GetCurrentBinaryDirectory(); - newName += "/moc_"; - newName += srcName; - newName += ".cxx"; + std::string newName = cmStrCat( + this->Makefile->GetCurrentBinaryDirectory(), "/moc_", srcName, ".cxx"); cmSourceFile* sf = this->Makefile->GetOrCreateSource(newName, true); if (curr) { sf->SetProperty("ABSTRACT", curr->GetProperty("ABSTRACT")); diff --git a/Source/cmQTWrapUICommand.cxx b/Source/cmQTWrapUICommand.cxx index 361d7b3..8bc914f 100644 --- a/Source/cmQTWrapUICommand.cxx +++ b/Source/cmQTWrapUICommand.cxx @@ -6,6 +6,7 @@ #include "cmMakefile.h" #include "cmRange.h" #include "cmSourceFile.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include <utility> @@ -41,18 +42,12 @@ bool cmQTWrapUICommand::InitialPass(std::vector<std::string> const& args, // Compute the name of the files to generate. std::string srcName = cmSystemTools::GetFilenameWithoutLastExtension(arg); - std::string hName = this->Makefile->GetCurrentBinaryDirectory(); - hName += "/"; - hName += srcName; - hName += ".h"; - std::string cxxName = this->Makefile->GetCurrentBinaryDirectory(); - cxxName += "/"; - cxxName += srcName; - cxxName += ".cxx"; - std::string mocName = this->Makefile->GetCurrentBinaryDirectory(); - mocName += "/moc_"; - mocName += srcName; - mocName += ".cxx"; + std::string hName = cmStrCat(this->Makefile->GetCurrentBinaryDirectory(), + '/', srcName, ".h"); + std::string cxxName = cmStrCat( + this->Makefile->GetCurrentBinaryDirectory(), '/', srcName, ".cxx"); + std::string mocName = cmStrCat( + this->Makefile->GetCurrentBinaryDirectory(), "/moc_", srcName, ".cxx"); // Compute the name of the ui file from which to generate others. std::string uiName; diff --git a/Source/cmQtAutoGen.cxx b/Source/cmQtAutoGen.cxx index 3026b33..d890f8e 100644 --- a/Source/cmQtAutoGen.cxx +++ b/Source/cmQtAutoGen.cxx @@ -12,6 +12,7 @@ #include <algorithm> #include <array> +#include <initializer_list> #include <sstream> #include <utility> @@ -21,7 +22,7 @@ /// @arg valueOpts list of options that accept a value void MergeOptions(std::vector<std::string>& baseOpts, std::vector<std::string> const& newOpts, - std::vector<std::string> const& valueOpts, bool isQt5) + std::initializer_list<cm::string_view> valueOpts, bool isQt5) { typedef std::vector<std::string>::iterator Iter; typedef std::vector<std::string>::const_iterator CIter; @@ -53,9 +54,7 @@ void MergeOptions(std::vector<std::string>& baseOpts, } } // Test if this is a value option and change the existing value - if (!optName.empty() && - (std::find(valueOpts.begin(), valueOpts.end(), optName) != - valueOpts.end())) { + if (!optName.empty() && cmContains(valueOpts, optName)) { const Iter existItNext(existIt + 1); const CIter fitNext(fit + 1); if ((existItNext != baseOpts.end()) && (fitNext != fitEnd)) { @@ -77,102 +76,74 @@ void MergeOptions(std::vector<std::string>& baseOpts, unsigned int const cmQtAutoGen::ParallelMax = 64; std::string const cmQtAutoGen::ListSep = "<<<S>>>"; -std::string const& cmQtAutoGen::GeneratorName(GenT genType) +cm::string_view cmQtAutoGen::GeneratorName(GenT genType) { - static const std::string AutoGen("AutoGen"); - static const std::string AutoMoc("AutoMoc"); - static const std::string AutoUic("AutoUic"); - static const std::string AutoRcc("AutoRcc"); - switch (genType) { case GenT::GEN: - return AutoGen; + return "AutoGen"; case GenT::MOC: - return AutoMoc; + return "AutoMoc"; case GenT::UIC: - return AutoUic; + return "AutoUic"; case GenT::RCC: - return AutoRcc; + return "AutoRcc"; } - return AutoGen; + return "AutoGen"; } -std::string const& cmQtAutoGen::GeneratorNameUpper(GenT genType) +cm::string_view cmQtAutoGen::GeneratorNameUpper(GenT genType) { - static const std::string AUTOGEN("AUTOGEN"); - static const std::string AUTOMOC("AUTOMOC"); - static const std::string AUTOUIC("AUTOUIC"); - static const std::string AUTORCC("AUTORCC"); - switch (genType) { case GenT::GEN: - return AUTOGEN; + return "AUTOGEN"; case GenT::MOC: - return AUTOMOC; + return "AUTOMOC"; case GenT::UIC: - return AUTOUIC; + return "AUTOUIC"; case GenT::RCC: - return AUTORCC; + return "AUTORCC"; } - return AUTOGEN; + return "AUTOGEN"; } std::string cmQtAutoGen::Tools(bool moc, bool uic, bool rcc) { - std::string res; - std::vector<std::string> lst; + std::array<cm::string_view, 3> lst; + decltype(lst)::size_type num = 0; if (moc) { - lst.emplace_back("AUTOMOC"); + lst.at(num++) = "AUTOMOC"; } if (uic) { - lst.emplace_back("AUTOUIC"); + lst.at(num++) = "AUTOUIC"; } if (rcc) { - lst.emplace_back("AUTORCC"); + lst.at(num++) = "AUTORCC"; } - switch (lst.size()) { + switch (num) { case 1: - res += lst.at(0); - break; + return std::string(lst[0]); case 2: - res += lst.at(0); - res += " and "; - res += lst.at(1); - break; + return cmStrCat(lst[0], " and ", lst[1]); case 3: - res += lst.at(0); - res += ", "; - res += lst.at(1); - res += " and "; - res += lst.at(2); - break; + return cmStrCat(lst[0], ", ", lst[1], " and ", lst[2]); default: break; } - return res; + return std::string(); } -std::string cmQtAutoGen::Quoted(std::string const& text) +std::string cmQtAutoGen::Quoted(cm::string_view text) { - const std::array<std::pair<const char*, const char*>, 9> replaces = { - { { "\\", "\\\\" }, - { "\"", "\\\"" }, - { "\a", "\\a" }, - { "\b", "\\b" }, - { "\f", "\\f" }, - { "\n", "\\n" }, - { "\r", "\\r" }, - { "\t", "\\t" }, - { "\v", "\\v" } } - }; + static std::initializer_list<std::pair<const char*, const char*>> const + replacements = { { "\\", "\\\\" }, { "\"", "\\\"" }, { "\a", "\\a" }, + { "\b", "\\b" }, { "\f", "\\f" }, { "\n", "\\n" }, + { "\r", "\\r" }, { "\t", "\\t" }, { "\v", "\\v" } }; - std::string res = text; - for (auto const& pair : replaces) { + std::string res(text); + for (auto const& pair : replacements) { cmSystemTools::ReplaceString(res, pair.first, pair.second); } - res = '"' + res; - res += '"'; - return res; + return cmStrCat('"', res, '"'); } std::string cmQtAutoGen::QuotedCommand(std::vector<std::string> const& command) @@ -193,37 +164,31 @@ std::string cmQtAutoGen::QuotedCommand(std::vector<std::string> const& command) return res; } -std::string cmQtAutoGen::SubDirPrefix(std::string const& filename) +std::string cmQtAutoGen::SubDirPrefix(cm::string_view filename) { - std::string::size_type slash_pos = filename.rfind('/'); - if (slash_pos == std::string::npos) { + auto slashPos = filename.rfind('/'); + if (slashPos == cm::string_view::npos) { return std::string(); } - return filename.substr(0, slash_pos + 1); + return std::string(filename.substr(0, slashPos + 1)); } -std::string cmQtAutoGen::AppendFilenameSuffix(std::string const& filename, - std::string const& suffix) +std::string cmQtAutoGen::AppendFilenameSuffix(cm::string_view filename, + cm::string_view suffix) { - std::string res; - auto pos = filename.rfind('.'); - if (pos != std::string::npos) { - const auto it_dot = filename.begin() + pos; - res.assign(filename.begin(), it_dot); - res.append(suffix); - res.append(it_dot, filename.end()); - } else { - res = filename; - res.append(suffix); + auto dotPos = filename.rfind('.'); + if (dotPos == cm::string_view::npos) { + return cmStrCat(filename, suffix); } - return res; + return cmStrCat(filename.substr(0, dotPos), suffix, + filename.substr(dotPos, filename.size() - dotPos)); } void cmQtAutoGen::UicMergeOptions(std::vector<std::string>& baseOpts, std::vector<std::string> const& newOpts, bool isQt5) { - static std::vector<std::string> const valueOpts = { + static std::initializer_list<cm::string_view> const valueOpts = { "tr", "translate", "postfix", "generator", "include", // Since Qt 5.3 "g" @@ -235,9 +200,9 @@ void cmQtAutoGen::RccMergeOptions(std::vector<std::string>& baseOpts, std::vector<std::string> const& newOpts, bool isQt5) { - static std::vector<std::string> const valueOpts = { "name", "root", - "compress", - "threshold" }; + static std::initializer_list<cm::string_view> const valueOpts = { + "name", "root", "compress", "threshold" + }; MergeOptions(baseOpts, newOpts, valueOpts, isQt5); } @@ -294,9 +259,8 @@ static bool RccListParseOutput(std::string const& rccStdOut, std::string::size_type pos = eline.find(searchString); if (pos == std::string::npos) { - error = "rcc lists unparsable output:\n"; - error += cmQtAutoGen::Quoted(eline); - error += "\n"; + error = cmStrCat("rcc lists unparsable output:\n", + cmQtAutoGen::Quoted(eline), '\n'); return false; } pos += searchString.length(); @@ -325,9 +289,8 @@ bool cmQtAutoGen::RccLister::list(std::string const& qrcFile, error.clear(); if (!cmSystemTools::FileExists(qrcFile, true)) { - error = "The resource file "; - error += Quoted(qrcFile); - error += " does not exist."; + error = + cmStrCat("The resource file ", Quoted(qrcFile), " does not exist."); return false; } @@ -353,9 +316,8 @@ bool cmQtAutoGen::RccLister::list(std::string const& qrcFile, // Log command if (verbose) { - std::string msg = - cmStrCat("Running command:\n", QuotedCommand(cmd), '\n'); - cmSystemTools::Stdout(msg); + cmSystemTools::Stdout( + cmStrCat("Running command:\n", QuotedCommand(cmd), '\n')); } result = cmSystemTools::RunSingleCommand( @@ -363,16 +325,13 @@ bool cmQtAutoGen::RccLister::list(std::string const& qrcFile, cmSystemTools::OUTPUT_NONE, cmDuration::zero(), cmProcessOutput::Auto); } if (!result || retVal) { - error = "The rcc list process failed for "; - error += Quoted(qrcFile); - error += "\n"; + error = + cmStrCat("The rcc list process failed for ", Quoted(qrcFile), '\n'); if (!rccStdOut.empty()) { - error += rccStdOut; - error += "\n"; + error += cmStrCat(rccStdOut, '\n'); } if (!rccStdErr.empty()) { - error += rccStdErr; - error += "\n"; + error += cmStrCat(rccStdErr, '\n'); } return false; } @@ -391,9 +350,8 @@ bool cmQtAutoGen::RccLister::list(std::string const& qrcFile, osst << ifs.rdbuf(); qrcContents = osst.str(); } else { - error = "The resource file "; - error += Quoted(qrcFile); - error += " is not readable\n"; + error = cmStrCat("The resource file ", Quoted(qrcFile), + " is not readable\n"); return false; } } diff --git a/Source/cmQtAutoGen.h b/Source/cmQtAutoGen.h index 619fff1..939ceb3 100644 --- a/Source/cmQtAutoGen.h +++ b/Source/cmQtAutoGen.h @@ -5,6 +5,8 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include "cm_string_view.hxx" + #include <memory> #include <string> #include <vector> @@ -66,24 +68,24 @@ public: public: /// @brief Returns the generator name - static std::string const& GeneratorName(GenT genType); + static cm::string_view GeneratorName(GenT genType); /// @brief Returns the generator name in upper case - static std::string const& GeneratorNameUpper(GenT genType); + static cm::string_view GeneratorNameUpper(GenT genType); /// @brief Returns a string with the requested tool names static std::string Tools(bool moc, bool uic, bool rcc); /// @brief Returns the string escaped and enclosed in quotes - static std::string Quoted(std::string const& text); + static std::string Quoted(cm::string_view text); static std::string QuotedCommand(std::vector<std::string> const& command); /// @brief Returns the parent directory of the file with a "/" suffix - static std::string SubDirPrefix(std::string const& filename); + static std::string SubDirPrefix(cm::string_view filename); /// @brief Appends the suffix to the filename before the last dot - static std::string AppendFilenameSuffix(std::string const& filename, - std::string const& suffix); + static std::string AppendFilenameSuffix(cm::string_view filename, + cm::string_view suffix); /// @brief Merges newOpts into baseOpts static void UicMergeOptions(std::vector<std::string>& baseOpts, diff --git a/Source/cmQtAutoGenGlobalInitializer.cxx b/Source/cmQtAutoGenGlobalInitializer.cxx index 21de8c6..abc69d0 100644 --- a/Source/cmQtAutoGenGlobalInitializer.cxx +++ b/Source/cmQtAutoGenGlobalInitializer.cxx @@ -211,11 +211,8 @@ cmQtAutoGenGlobalInitializer::GetCompilerFeatures( // Check if the executable exists if (!cmSystemTools::FileExists(executable, true)) { - error = "The \""; - error += generator; - error += "\" executable "; - error += cmQtAutoGen::Quoted(executable); - error += " does not exist."; + error = cmStrCat("The \"", generator, "\" executable ", + cmQtAutoGen::Quoted(executable), " does not exist."); return cmQtAutoGen::CompilerFeaturesHandle(); } @@ -231,15 +228,10 @@ cmQtAutoGenGlobalInitializer::GetCompilerFeatures( command, &stdOut, &stdErr, &retVal, nullptr, cmSystemTools::OUTPUT_NONE, cmDuration::zero(), cmProcessOutput::Auto); if (!runResult) { - error = "Test run of \""; - error += generator; - error += "\" executable "; - error += cmQtAutoGen::Quoted(executable) + " failed.\n"; - error += cmQtAutoGen::QuotedCommand(command); - error += "\n"; - error += stdOut; - error += "\n"; - error += stdErr; + error = cmStrCat("Test run of \"", generator, "\" executable ", + cmQtAutoGen::Quoted(executable), " failed.\n", + cmQtAutoGen::QuotedCommand(command), '\n', stdOut, '\n', + stdErr); return cmQtAutoGen::CompilerFeaturesHandle(); } } diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx index d21fc61..bd96c08 100644 --- a/Source/cmQtAutoGenInitializer.cxx +++ b/Source/cmQtAutoGenInitializer.cxx @@ -29,8 +29,8 @@ #include "cmsys/SystemInformation.hxx" #include <algorithm> -#include <array> #include <deque> +#include <initializer_list> #include <map> #include <set> #include <string> @@ -293,19 +293,15 @@ bool cmQtAutoGenInitializer::InitCustomTargets() std::string(), makefile->GetCurrentBinaryDirectory()); // Info directory - this->Dir.Info = cbd; - this->Dir.Info += "/CMakeFiles/"; - this->Dir.Info += this->Target->GetName(); - this->Dir.Info += "_autogen.dir"; + this->Dir.Info = + cmStrCat(cbd, "/CMakeFiles/", this->Target->GetName(), "_autogen.dir"); cmSystemTools::ConvertToUnixSlashes(this->Dir.Info); // Build directory this->Dir.Build = this->Target->GetSafeProperty("AUTOGEN_BUILD_DIR"); if (this->Dir.Build.empty()) { - this->Dir.Build = cbd; - this->Dir.Build += '/'; - this->Dir.Build += this->Target->GetName(); - this->Dir.Build += "_autogen"; + this->Dir.Build = + cmStrCat(cbd, '/', this->Target->GetName(), "_autogen"); } cmSystemTools::ConvertToUnixSlashes(this->Dir.Build); // Cleanup build directory @@ -316,8 +312,7 @@ bool cmQtAutoGenInitializer::InitCustomTargets() cmSystemTools::ConvertToUnixSlashes(this->Dir.Work); // Include directory - this->Dir.Include = this->Dir.Build; - this->Dir.Include += "/include"; + this->Dir.Include = cmStrCat(this->Dir.Build, "/include"); if (this->MultiConfig) { this->Dir.Include += "_$<CONFIG>"; } @@ -325,9 +320,7 @@ bool cmQtAutoGenInitializer::InitCustomTargets() if (this->MultiConfig) { for (std::string const& cfg : this->ConfigsList) { std::string& dir = this->Dir.ConfigInclude[cfg]; - dir = this->Dir.Build; - dir += "/include_"; - dir += cfg; + dir = cmStrCat(this->Dir.Build, "/include_", cfg); } } } @@ -345,8 +338,7 @@ bool cmQtAutoGenInitializer::InitCustomTargets() } // Autogen target name - this->AutogenTarget.Name = this->Target->GetName(); - this->AutogenTarget.Name += "_autogen"; + this->AutogenTarget.Name = cmStrCat(this->Target->GetName(), "_autogen"); // Autogen target parallel processing this->AutogenTarget.Parallel = @@ -359,11 +351,11 @@ bool cmQtAutoGenInitializer::InitCustomTargets() // Autogen target info and settings files { - this->AutogenTarget.InfoFile = this->Dir.Info; - this->AutogenTarget.InfoFile += "/AutogenInfo.cmake"; + this->AutogenTarget.InfoFile = + cmStrCat(this->Dir.Info, "/AutogenInfo.cmake"); - this->AutogenTarget.SettingsFile = this->Dir.Info; - this->AutogenTarget.SettingsFile += "/AutogenOldSettings.txt"; + this->AutogenTarget.SettingsFile = + cmStrCat(this->Dir.Info, "/AutogenOldSettings.txt"); if (this->MultiConfig) { for (std::string const& cfg : this->ConfigsList) { @@ -376,8 +368,8 @@ bool cmQtAutoGenInitializer::InitCustomTargets() this->AddCleanFile(this->AutogenTarget.SettingsFile); } - this->AutogenTarget.ParseCacheFile = this->Dir.Info; - this->AutogenTarget.ParseCacheFile += "/ParseCache.txt"; + this->AutogenTarget.ParseCacheFile = + cmStrCat(this->Dir.Info, "/ParseCache.txt"); this->AddCleanFile(this->AutogenTarget.ParseCacheFile); } @@ -389,8 +381,7 @@ bool cmQtAutoGenInitializer::InitCustomTargets() std::string const deps = this->Target->GetSafeProperty("AUTOGEN_TARGET_DEPENDS"); if (!deps.empty()) { - std::vector<std::string> extraDeps; - cmExpandList(deps, extraDeps); + std::vector<std::string> extraDeps = cmExpandedList(deps); for (std::string const& depName : extraDeps) { // Allow target and file dependencies auto* depTarget = makefile->FindTargetToUse(depName); @@ -405,13 +396,13 @@ bool cmQtAutoGenInitializer::InitCustomTargets() // CMAKE_AUTOMOC_RELAXED_MODE deprecation warning if (this->Moc.Enabled) { - if (cmIsOn(makefile->GetDefinition("CMAKE_AUTOMOC_RELAXED_MODE"))) { - std::string msg = "AUTOMOC: CMAKE_AUTOMOC_RELAXED_MODE is " - "deprecated an will be removed in the future. "; - msg += "Consider disabling it and converting the target "; - msg += this->Target->GetName(); - msg += " to regular mode."; - makefile->IssueMessage(MessageType::AUTHOR_WARNING, msg); + if (makefile->IsOn("CMAKE_AUTOMOC_RELAXED_MODE")) { + makefile->IssueMessage( + MessageType::AUTHOR_WARNING, + cmStrCat("AUTOMOC: CMAKE_AUTOMOC_RELAXED_MODE is " + "deprecated an will be removed in the future. Consider " + "disabling it and converting the target ", + this->Target->GetName(), " to regular mode.")); } } } @@ -450,8 +441,8 @@ bool cmQtAutoGenInitializer::InitMoc() cmLocalGenerator* localGen = this->Target->GetLocalGenerator(); // Mocs compilation file - this->Moc.MocsCompilation = this->Dir.Build; - this->Moc.MocsCompilation += "/mocs_compilation.cpp"; + this->Moc.MocsCompilation = + cmStrCat(this->Dir.Build, "/mocs_compilation.cpp"); // Moc predefs command if (this->Target->GetPropertyAsBool("AUTOMOC_COMPILER_PREDEFINES") && @@ -705,7 +696,7 @@ bool cmQtAutoGenInitializer::InitScanFiles() std::vector<MUFileHandle> extraHeaders; extraHeaders.reserve(this->AutogenTarget.Sources.size() * 2); // Header search suffixes and extensions - std::array<std::string, 2> const suffixes{ { "", "_p" } }; + static std::initializer_list<cm::string_view> const suffixes{ "", "_p" }; auto const& exts = cm->GetHeaderExtensions(); // Scan through sources for (auto const& pair : this->AutogenTarget.Sources) { @@ -717,7 +708,7 @@ bool cmQtAutoGenInitializer::InitScanFiles() cmStrCat(cmQtAutoGen::SubDirPrefix(srcPath), cmSystemTools::GetFilenameWithoutLastExtension(srcPath)); for (auto const& suffix : suffixes) { - std::string const suffixedPath = basePath + suffix; + std::string const suffixedPath = cmStrCat(basePath, suffix); for (auto const& ext : exts) { std::string fullPath = cmStrCat(suffixedPath, '.', ext); @@ -804,8 +795,7 @@ bool cmQtAutoGenInitializer::InitScanFiles() std::string const uicOpts = sf->GetSafeProperty(kw.AUTOUIC_OPTIONS); if (!uicOpts.empty()) { this->Uic.FileFiles.push_back(std::move(realPath)); - std::vector<std::string> optsVec; - cmExpandList(uicOpts, optsVec); + std::vector<std::string> optsVec = cmExpandedList(uicOpts); this->Uic.FileOptions.push_back(std::move(optsVec)); } } else { @@ -824,33 +814,31 @@ bool cmQtAutoGenInitializer::InitScanFiles() this->AutogenTarget.DependFiles.insert(muf->RealPath); } } else if (this->CMP0071Warn) { - std::string msg = - cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0071), '\n'); - std::string property; + cm::string_view property; if (this->Moc.Enabled && this->Uic.Enabled) { - property = kw.SKIP_AUTOGEN; + property = "SKIP_AUTOGEN"; } else if (this->Moc.Enabled) { - property = kw.SKIP_AUTOMOC; + property = "SKIP_AUTOMOC"; } else if (this->Uic.Enabled) { - property = kw.SKIP_AUTOUIC; + property = "SKIP_AUTOUIC"; } - msg += "For compatibility, CMake is excluding the GENERATED source " - "file(s):\n"; + std::string files; for (MUFile* muf : this->AutogenTarget.FilesGenerated) { - msg += " "; - msg += Quoted(muf->RealPath); - msg += '\n'; + files += cmStrCat(" ", Quoted(muf->RealPath), '\n'); } - msg += "from processing by "; - msg += cmQtAutoGen::Tools(this->Moc.Enabled, this->Uic.Enabled, false); - msg += ". If any of the files should be processed, set CMP0071 to NEW. " - "If any of the files should not be processed, " - "explicitly exclude them by setting the source file property "; - msg += property; - msg += ":\n set_property(SOURCE file.h PROPERTY "; - msg += property; - msg += " ON)\n"; - makefile->IssueMessage(MessageType::AUTHOR_WARNING, msg); + makefile->IssueMessage( + MessageType::AUTHOR_WARNING, + cmStrCat( + cmPolicies::GetPolicyWarning(cmPolicies::CMP0071), '\n', + "For compatibility, CMake is excluding the GENERATED source " + "file(s):\n", + files, "from processing by ", + cmQtAutoGen::Tools(this->Moc.Enabled, this->Uic.Enabled, false), + ". If any of the files should be processed, set CMP0071 to NEW. " + "If any of the files should not be processed, " + "explicitly exclude them by setting the source file property ", + property, ":\n set_property(SOURCE file.h PROPERTY ", property, + " ON)\n")); } } @@ -858,9 +846,8 @@ bool cmQtAutoGenInitializer::InitScanFiles() if (!this->Rcc.Qrcs.empty()) { const bool modernQt = (this->QtVersion.Major >= 5); // Target rcc options - std::vector<std::string> optionsTarget; - cmExpandList(this->Target->GetSafeProperty(kw.AUTORCC_OPTIONS), - optionsTarget); + std::vector<std::string> optionsTarget = + cmExpandedList(this->Target->GetSafeProperty(kw.AUTORCC_OPTIONS)); // Check if file name is unique for (Qrc& qrc : this->Rcc.Qrcs) { @@ -878,23 +865,16 @@ bool cmQtAutoGenInitializer::InitScanFiles() for (Qrc& qrc : this->Rcc.Qrcs) { qrc.PathChecksum = fpathCheckSum.getPart(qrc.QrcFile); // RCC output file name - qrc.RccFile = cmStrCat(this->Dir.Build + "/", qrc.PathChecksum, - "/qrc_", qrc.QrcName, ".cpp"); + qrc.RccFile = cmStrCat(this->Dir.Build, '/', qrc.PathChecksum, "/qrc_", + qrc.QrcName, ".cpp"); { - std::string base = cmStrCat(this->Dir.Info, "/RCC", qrc.QrcName); - if (!qrc.Unique) { - base += qrc.PathChecksum; - } - - qrc.LockFile = base; - qrc.LockFile += ".lock"; - - qrc.InfoFile = base; - qrc.InfoFile += "Info.cmake"; - - qrc.SettingsFile = base; - qrc.SettingsFile += "Settings.txt"; - + cm::string_view const baseSuffix = + qrc.Unique ? cm::string_view() : cm::string_view(qrc.PathChecksum); + std::string const base = + cmStrCat(this->Dir.Info, "/RCC", qrc.QrcName, baseSuffix); + qrc.LockFile = cmStrCat(base, ".lock"); + qrc.InfoFile = cmStrCat(base, "Info.cmake"); + qrc.SettingsFile = cmStrCat(base, "Settings.txt"); if (this->MultiConfig) { for (std::string const& cfg : this->ConfigsList) { qrc.ConfigSettingsFile[cfg] = @@ -914,7 +894,7 @@ bool cmQtAutoGenInitializer::InitScanFiles() // Replace '-' with '_'. The former is not valid for symbol names. std::replace(name.begin(), name.end(), '-', '_'); if (!qrc.Unique) { - name += cmStrCat("_", qrc.PathChecksum); + name += cmStrCat('_', qrc.PathChecksum); } std::vector<std::string> nameOpts; nameOpts.emplace_back("-name"); @@ -971,10 +951,8 @@ bool cmQtAutoGenInitializer::InitAutogenTarget() } tools += "UIC"; } - autogenComment = "Automatic "; - autogenComment += tools; - autogenComment += " for target "; - autogenComment += this->Target->GetName(); + autogenComment = + cmStrCat("Automatic ", tools, " for target ", this->Target->GetName()); } // Compose command lines @@ -1145,12 +1123,9 @@ bool cmQtAutoGenInitializer::InitRccTargets() // Create custom rcc target std::string ccName; { - ccName = this->Target->GetName(); - ccName += "_arcc_"; - ccName += qrc.QrcName; + ccName = cmStrCat(this->Target->GetName(), "_arcc_", qrc.QrcName); if (!qrc.Unique) { - ccName += "_"; - ccName += qrc.PathChecksum; + ccName += cmStrCat('_', qrc.PathChecksum); } cmTarget* autoRccTarget = makefile->AddUtilityCommand( @@ -1292,7 +1267,7 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo() if (muf->MocIt || muf->UicIt) { headers.emplace_back(muf->RealPath); headersFlags.emplace_back( - cmStrCat(muf->MocIt ? "M" : "m", muf->UicIt ? "U" : "u")); + cmStrCat(muf->MocIt ? 'M' : 'm', muf->UicIt ? 'U' : 'u')); } } } @@ -1301,19 +1276,17 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo() cmFilePathChecksum const fpathCheckSum(makefile); std::unordered_set<std::string> emitted; for (std::string const& hdr : headers) { - std::string basePath = + std::string const basePath = cmStrCat(fpathCheckSum.getPart(hdr), "/moc_", cmSystemTools::GetFilenameWithoutLastExtension(hdr)); - for (int ii = 1; ii != 1024; ++ii) { - std::string path = basePath; - if (ii > 1) { - path += cmStrCat("_", ii); - } - path += ".cpp"; + std::string suffix; + for (int ii = 0; ii != 1024; ++ii) { + std::string path = cmStrCat(basePath, suffix, ".cpp"); if (emitted.emplace(path).second) { headersBuildPaths.emplace_back(std::move(path)); break; } + suffix = cmStrCat('_', ii + 1); } } } @@ -1347,7 +1320,7 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo() if (muf->MocIt || muf->UicIt) { sources.emplace_back(muf->RealPath); sourcesFlags.emplace_back( - cmStrCat(muf->MocIt ? "M" : "m", muf->UicIt ? "U" : "u")); + cmStrCat(muf->MocIt ? 'M' : 'm', muf->UicIt ? 'U' : 'u')); } } } @@ -1472,7 +1445,7 @@ bool cmQtAutoGenInitializer::AddGeneratedSource(std::string const& filename, } bool cmQtAutoGenInitializer::AddToSourceGroup(std::string const& fileName, - std::string const& genNameUpper) + cm::string_view genNameUpper) { cmMakefile* makefile = this->Target->Target->GetMakefile(); cmSourceGroup* sourceGroup = nullptr; @@ -1482,13 +1455,14 @@ bool cmQtAutoGenInitializer::AddToSourceGroup(std::string const& fileName, std::string groupName; { // Prefer generator specific source group name - std::array<std::string, 2> props{ { genNameUpper + "_SOURCE_GROUP", - "AUTOGEN_SOURCE_GROUP" } }; - for (std::string& prop : props) { + std::initializer_list<std::string> const props{ + cmStrCat(genNameUpper, "_SOURCE_GROUP"), "AUTOGEN_SOURCE_GROUP" + }; + for (std::string const& prop : props) { const char* propName = makefile->GetState()->GetGlobalProperty(prop); if ((propName != nullptr) && (*propName != '\0')) { groupName = propName; - property = std::move(prop); + property = prop; break; } } @@ -1530,11 +1504,16 @@ static std::vector<cmQtAutoGen::IntegerVersion> GetKnownQtVersions( cmGeneratorTarget const* target) { // Qt version variable prefixes - static std::array<std::string, 3> const prefixes{ { "Qt6Core", "Qt5Core", - "QT" } }; + static std::initializer_list< + std::pair<cm::string_view, cm::string_view>> const keys{ + { "Qt6Core_VERSION_MAJOR", "Qt6Core_VERSION_MINOR" }, + { "Qt5Core_VERSION_MAJOR", "Qt5Core_VERSION_MINOR" }, + { "QT_VERSION_MAJOR", "QT_VERSION_MINOR" }, + }; std::vector<cmQtAutoGen::IntegerVersion> result; - result.reserve(prefixes.size() * 2); + result.reserve(keys.size() * 2); + // Adds a version to the result (nullptr safe) auto addVersion = [&result](const char* major, const char* minor) { cmQtAutoGen::IntegerVersion ver(CharPtrToUInt(major), @@ -1543,18 +1522,19 @@ static std::vector<cmQtAutoGen::IntegerVersion> GetKnownQtVersions( result.emplace_back(ver); } }; + cmMakefile* makefile = target->Target->GetMakefile(); // Read versions from variables - for (const std::string& prefix : prefixes) { - addVersion(makefile->GetDefinition(prefix + "_VERSION_MAJOR"), - makefile->GetDefinition(prefix + "_VERSION_MINOR")); + for (auto const& keyPair : keys) { + addVersion(makefile->GetDefinition(std::string(keyPair.first)), + makefile->GetDefinition(std::string(keyPair.second))); } // Read versions from directory properties - for (const std::string& prefix : prefixes) { - addVersion(makefile->GetProperty(prefix + "_VERSION_MAJOR"), - makefile->GetProperty(prefix + "_VERSION_MINOR")); + for (auto const& keyPair : keys) { + addVersion(makefile->GetProperty(std::string(keyPair.first)), + makefile->GetProperty(std::string(keyPair.second))); } return result; @@ -1598,7 +1578,7 @@ bool cmQtAutoGenInitializer::GetQtExecutable(GenVarsT& genVars, // Custom executable { - std::string const prop = genVars.GenNameUpper + "_EXECUTABLE"; + std::string const prop = cmStrCat(genVars.GenNameUpper, "_EXECUTABLE"); std::string const val = this->Target->Target->GetSafeProperty(prop); if (!val.empty()) { // Evaluate generator expression @@ -1625,15 +1605,15 @@ bool cmQtAutoGenInitializer::GetQtExecutable(GenVarsT& genVars, // Find executable target { // Find executable target name - std::string targetName; + cm::string_view prefix; if (this->QtVersion.Major == 4) { - targetName = "Qt4::"; + prefix = "Qt4::"; } else if (this->QtVersion.Major == 5) { - targetName = "Qt5::"; + prefix = "Qt5::"; } else if (this->QtVersion.Major == 6) { - targetName = "Qt6::"; + prefix = "Qt6::"; } - targetName += executable; + std::string const targetName = cmStrCat(prefix, executable); // Find target cmLocalGenerator* localGen = this->Target->GetLocalGenerator(); diff --git a/Source/cmQtAutoGenInitializer.h b/Source/cmQtAutoGenInitializer.h index 7d72cad..65666a6 100644 --- a/Source/cmQtAutoGenInitializer.h +++ b/Source/cmQtAutoGenInitializer.h @@ -63,7 +63,7 @@ public: bool Enabled = false; // Generator type/name GenT Gen; - std::string const& GenNameUpper; + cm::string_view GenNameUpper; // Executable std::string ExecutableTargetName; cmGeneratorTarget* ExecutableTarget = nullptr; @@ -145,7 +145,7 @@ private: bool AddGeneratedSource(std::string const& filename, GenVarsT const& genVars, bool prepend = false); bool AddToSourceGroup(std::string const& fileName, - std::string const& genNameUpper); + cm::string_view genNameUpper); void AddCleanFile(std::string const& fileName); bool GetQtExecutable(GenVarsT& genVars, const std::string& executable, diff --git a/Source/cmQtAutoGenerator.cxx b/Source/cmQtAutoGenerator.cxx index 0e8fa9a..3bcc1c9 100644 --- a/Source/cmQtAutoGenerator.cxx +++ b/Source/cmQtAutoGenerator.cxx @@ -58,18 +58,16 @@ void cmQtAutoGenerator::Logger::SetColorOutput(bool value) ColorOutput_ = value; } -std::string cmQtAutoGenerator::Logger::HeadLine(std::string const& title) +std::string cmQtAutoGenerator::Logger::HeadLine(cm::string_view title) { - return cmStrCat(title, "\n", std::string(title.size(), '-'), "\n"); + return cmStrCat(title, '\n', std::string(title.size(), '-'), '\n'); } void cmQtAutoGenerator::Logger::Info(GenT genType, - std::string const& message) const + cm::string_view message) const { - std::string msg = cmStrCat(GeneratorName(genType), ": ", message); - if (msg.back() != '\n') { - msg.push_back('\n'); - } + std::string msg = cmStrCat(GeneratorName(genType), ": ", message, + cmHasSuffix(message, '\n') ? "" : "\n"); { std::lock_guard<std::mutex> lock(Mutex_); cmSystemTools::Stdout(msg); @@ -77,23 +75,18 @@ void cmQtAutoGenerator::Logger::Info(GenT genType, } void cmQtAutoGenerator::Logger::Warning(GenT genType, - std::string const& message) const + cm::string_view message) const { std::string msg; if (message.find('\n') == std::string::npos) { // Single line message - msg += GeneratorName(genType); - msg += " warning: "; + msg = cmStrCat(GeneratorName(genType), " warning: ", message, + cmHasSuffix(message, '\n') ? "\n" : "\n\n"); } else { // Multi line message - msg += HeadLine(GeneratorName(genType) + " warning"); - } - // Message - msg += message; - if (msg.back() != '\n') { - msg.push_back('\n'); + msg = cmStrCat(HeadLine(cmStrCat(GeneratorName(genType), " warning")), + message, cmHasSuffix(message, '\n') ? "\n" : "\n\n"); } - msg.push_back('\n'); { std::lock_guard<std::mutex> lock(Mutex_); cmSystemTools::Stdout(msg); @@ -101,22 +94,18 @@ void cmQtAutoGenerator::Logger::Warning(GenT genType, } void cmQtAutoGenerator::Logger::WarningFile(GenT genType, - std::string const& filename, - std::string const& message) const + cm::string_view filename, + cm::string_view message) const { - Warning(genType, cmStrCat(" ", Quoted(filename), "\n", message)); + Warning(genType, cmStrCat(" ", Quoted(filename), '\n', message)); } void cmQtAutoGenerator::Logger::Error(GenT genType, - std::string const& message) const + cm::string_view message) const { - std::string msg = HeadLine(GeneratorName(genType) + " error"); - // Message - msg += message; - if (msg.back() != '\n') { - msg.push_back('\n'); - } - msg.push_back('\n'); + std::string msg = + cmStrCat(HeadLine(cmStrCat(GeneratorName(genType), " error")), message, + cmHasSuffix(message, '\n') ? "\n" : "\n\n"); { std::lock_guard<std::mutex> lock(Mutex_); cmSystemTools::Stderr(msg); @@ -124,36 +113,22 @@ void cmQtAutoGenerator::Logger::Error(GenT genType, } void cmQtAutoGenerator::Logger::ErrorFile(GenT genType, - std::string const& filename, - std::string const& message) const + cm::string_view filename, + cm::string_view message) const { Error(genType, cmStrCat(" ", Quoted(filename), '\n', message)); } void cmQtAutoGenerator::Logger::ErrorCommand( - GenT genType, std::string const& message, + GenT genType, cm::string_view message, std::vector<std::string> const& command, std::string const& output) const { - std::string msg; - msg.push_back('\n'); - msg += HeadLine(GeneratorName(genType) + " subprocess error"); - msg += message; - if (msg.back() != '\n') { - msg.push_back('\n'); - } - msg.push_back('\n'); - msg += HeadLine("Command"); - msg += QuotedCommand(command); - if (msg.back() != '\n') { - msg.push_back('\n'); - } - msg.push_back('\n'); - msg += HeadLine("Output"); - msg += output; - if (msg.back() != '\n') { - msg.push_back('\n'); - } - msg.push_back('\n'); + std::string msg = cmStrCat( + '\n', HeadLine(cmStrCat(GeneratorName(genType), " subprocess error")), + message, cmHasSuffix(message, '\n') ? "\n" : "\n\n"); + msg += cmStrCat(HeadLine("Command"), QuotedCommand(command), "\n\n"); + msg += cmStrCat(HeadLine("Output"), output, + cmHasSuffix(output, '\n') ? "\n" : "\n\n"); { std::lock_guard<std::mutex> lock(Mutex_); cmSystemTools::Stderr(msg); @@ -298,8 +273,7 @@ bool cmQtAutoGenerator::Run(std::string const& infoFile, std::string cmQtAutoGenerator::SettingsFind(std::string const& content, const char* key) { - std::string prefix(key); - prefix += ':'; + std::string prefix = cmStrCat(key, ':'); std::string::size_type pos = content.find(prefix); if (pos != std::string::npos) { pos += prefix.size(); diff --git a/Source/cmQtAutoGenerator.h b/Source/cmQtAutoGenerator.h index ff4c4c9..4b8b0b7 100644 --- a/Source/cmQtAutoGenerator.h +++ b/Source/cmQtAutoGenerator.h @@ -7,6 +7,7 @@ #include "cmFileTime.h" #include "cmQtAutoGen.h" +#include "cm_string_view.hxx" #include <mutex> #include <string> @@ -41,21 +42,21 @@ public: bool ColorOutput() const { return this->ColorOutput_; } void SetColorOutput(bool value); // -- Log info - void Info(GenT genType, std::string const& message) const; + void Info(GenT genType, cm::string_view message) const; // -- Log warning - void Warning(GenT genType, std::string const& message) const; - void WarningFile(GenT genType, std::string const& filename, - std::string const& message) const; + void Warning(GenT genType, cm::string_view message) const; + void WarningFile(GenT genType, cm::string_view filename, + cm::string_view message) const; // -- Log error - void Error(GenT genType, std::string const& message) const; - void ErrorFile(GenT genType, std::string const& filename, - std::string const& message) const; - void ErrorCommand(GenT genType, std::string const& message, + void Error(GenT genType, cm::string_view message) const; + void ErrorFile(GenT genType, cm::string_view filename, + cm::string_view message) const; + void ErrorCommand(GenT genType, cm::string_view message, std::vector<std::string> const& command, std::string const& output) const; private: - static std::string HeadLine(std::string const& title); + static std::string HeadLine(cm::string_view title); private: mutable std::mutex Mutex_; diff --git a/Source/cmQtAutoMocUic.cxx b/Source/cmQtAutoMocUic.cxx index 2cbf113..84359f2 100644 --- a/Source/cmQtAutoMocUic.cxx +++ b/Source/cmQtAutoMocUic.cxx @@ -3,10 +3,9 @@ #include "cmQtAutoMocUic.h" #include <algorithm> -#include <array> +#include <initializer_list> #include <list> #include <set> -#include <sstream> #include <utility> #include "cm_memory.hxx" @@ -233,22 +232,21 @@ bool cmQtAutoMocUic::UicSettingsT::skipped(std::string const& fileName) const } void cmQtAutoMocUic::JobT::LogError(GenT genType, - std::string const& message) const + cm::string_view message) const { Gen()->AbortError(); Gen()->Log().Error(genType, message); } -void cmQtAutoMocUic::JobT::LogFileError(GenT genType, - std::string const& filename, - std::string const& message) const +void cmQtAutoMocUic::JobT::LogFileError(GenT genType, cm::string_view filename, + cm::string_view message) const { Gen()->AbortError(); Gen()->Log().ErrorFile(genType, filename, message); } void cmQtAutoMocUic::JobT::LogCommandError( - GenT genType, std::string const& message, + GenT genType, cm::string_view message, std::vector<std::string> const& command, std::string const& output) const { Gen()->AbortError(); @@ -262,16 +260,14 @@ bool cmQtAutoMocUic::JobT::RunProcess(GenT genType, { // Log command if (Log().Verbose()) { - std::string msg; - if ((infoMessage != nullptr) && !infoMessage->empty()) { - msg = *infoMessage; - if (msg.back() != '\n') { - msg += '\n'; - } + cm::string_view info; + if (infoMessage != nullptr) { + info = *infoMessage; } - msg += QuotedCommand(command); - msg += '\n'; - Log().Info(genType, msg); + Log().Info(genType, + cmStrCat(info, + info.empty() || cmHasSuffix(info, '\n') ? "" : "\n", + QuotedCommand(command), '\n')); } return cmWorkerPool::JobT::RunProcess(result, command, BaseConst().AutogenBuildDir); @@ -302,10 +298,11 @@ void cmQtAutoMocUic::JobMocPredefsT::Process() } // Execute command if (!RunProcess(GenT::MOC, result, cmd, reason.get())) { - std::string msg = - cmStrCat("The content generation command for ", - Quoted(predefsFileRel), " failed.\n", result.ErrorMessage); - LogCommandError(GenT::MOC, msg, cmd, result.StdOut); + LogCommandError(GenT::MOC, + cmStrCat("The content generation command for ", + Quoted(predefsFileRel), " failed.\n", + result.ErrorMessage), + cmd, result.StdOut); return; } } @@ -313,9 +310,8 @@ void cmQtAutoMocUic::JobMocPredefsT::Process() // (Re)write predefs file only on demand if (cmQtAutoGenerator::FileDiffers(predefsFileAbs, result.StdOut)) { if (!cmQtAutoGenerator::FileWrite(predefsFileAbs, result.StdOut)) { - std::string msg = - cmStrCat("Writing ", Quoted(predefsFileRel), " failed."); - LogFileError(GenT::MOC, predefsFileAbs, msg); + LogFileError(GenT::MOC, predefsFileAbs, + cmStrCat("Writing ", Quoted(predefsFileRel), " failed.")); return; } } else { @@ -324,9 +320,9 @@ void cmQtAutoMocUic::JobMocPredefsT::Process() Log().Info(GenT::MOC, "Touching " + Quoted(predefsFileRel)); } if (!cmSystemTools::Touch(predefsFileAbs, false)) { - std::string msg = - cmStrCat("Touching ", Quoted(predefsFileAbs), " failed."); - LogFileError(GenT::MOC, predefsFileAbs, msg); + LogFileError( + GenT::MOC, predefsFileAbs, + cmStrCat("Touching ", Quoted(predefsFileAbs), " failed.")); return; } } @@ -344,9 +340,8 @@ bool cmQtAutoMocUic::JobMocPredefsT::Update(std::string* reason) const // Test if the file exists if (!MocEval().PredefsTime.Load(MocConst().PredefsFileAbs)) { if (reason != nullptr) { - *reason = "Generating "; - *reason += Quoted(MocConst().PredefsFileRel); - *reason += ", because it doesn't exist."; + *reason = cmStrCat("Generating ", Quoted(MocConst().PredefsFileRel), + ", because it doesn't exist."); } return true; } @@ -354,9 +349,8 @@ bool cmQtAutoMocUic::JobMocPredefsT::Update(std::string* reason) const // Test if the settings changed if (MocConst().SettingsChanged) { if (reason != nullptr) { - *reason = "Generating "; - *reason += Quoted(MocConst().PredefsFileRel); - *reason += ", because the moc settings changed."; + *reason = cmStrCat("Generating ", Quoted(MocConst().PredefsFileRel), + ", because the moc settings changed."); } return true; } @@ -368,11 +362,8 @@ bool cmQtAutoMocUic::JobMocPredefsT::Update(std::string* reason) const if (execTime.Load(exec)) { if (MocEval().PredefsTime.Older(execTime)) { if (reason != nullptr) { - *reason = "Generating "; - *reason += Quoted(MocConst().PredefsFileRel); - *reason += " because it is older than "; - *reason += Quoted(exec); - *reason += "."; + *reason = cmStrCat("Generating ", Quoted(MocConst().PredefsFileRel), + " because it is older than ", Quoted(exec), '.'); } return true; } @@ -659,14 +650,12 @@ bool cmQtAutoMocUic::JobEvaluateT::MocEvalSource( // Check if this source needs to be moc processed but doesn't. if (!sourceIncludesDotMoc && !parseData.Macro.empty() && !(relaxedMode && sourceIncludesMocUnderscore)) { - { - std::string emsg = - cmStrCat("The file contains a ", Quoted(parseData.Macro), - " macro, but does not include ", Quoted(sourceBase + ".moc"), - "!\nConsider to\n - add #include \"", sourceBase, - ".moc\"\n - enable SKIP_AUTOMOC for this file"); - LogFileError(GenT::MOC, sourceFile.FileName, emsg); - } + LogFileError(GenT::MOC, sourceFile.FileName, + cmStrCat("The file contains a ", Quoted(parseData.Macro), + " macro, but does not include ", + Quoted(sourceBase + ".moc"), + "!\nConsider to\n - add #include \"", sourceBase, + ".moc\"\n - enable SKIP_AUTOMOC for this file")); return false; } @@ -675,14 +664,12 @@ bool cmQtAutoMocUic::JobEvaluateT::MocEvalSource( std::string const headerBase = incKey.Dir + incKey.Base; SourceFileHandleT header = MocFindIncludedHeader(sourceDir, headerBase); if (!header) { - { - std::string msg = "The file includes the moc file "; - msg += Quoted(incKey.Key); - msg += ",\nbut the header could not be found " - "in the following locations\n"; - msg += MocMessageTestHeaders(headerBase); - LogFileError(GenT::MOC, sourceFile.FileName, msg); - } + LogFileError(GenT::MOC, sourceFile.FileName, + cmStrCat("The file includes the moc file ", + Quoted(incKey.Key), + ",\nbut the header could not be found " + "in the following locations\n", + MocMessageTestHeaders(headerBase))); return false; } // The include might be handled differently in relaxed mode @@ -693,18 +680,19 @@ bool cmQtAutoMocUic::JobEvaluateT::MocEvalSource( // be generated from <BASE>.cpp instead of <BASE>.h, because otherwise // it won't build. But warn, since this is not how it is supposed to be // used. This is for KDE4 compatibility. - { - // Issue a warning - std::string msg = cmStrCat( - "The file contains a ", Quoted(parseData.Macro), - " macro, but does not include ", Quoted(sourceBase + ".moc"), - ".\nInstead it includes ", Quoted(incKey.Key), - ".\nRunning moc on the source\n ", Quoted(sourceFile.FileName), - "!\nBetter include ", Quoted(sourceBase + ".moc"), - " for compatibility with regular mode.\n", - "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n"); - Log().WarningFile(GenT::MOC, sourceFile.FileName, msg); - } + + // Issue a warning + Log().WarningFile( + GenT::MOC, sourceFile.FileName, + cmStrCat("The file contains a ", Quoted(parseData.Macro), + " macro, but does not include ", Quoted(sourceBase + ".moc"), + ".\nInstead it includes ", Quoted(incKey.Key), + ".\nRunning moc on the source\n ", + Quoted(sourceFile.FileName), "!\nBetter include ", + Quoted(sourceBase + ".moc"), + " for compatibility with regular mode.\n", + "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n")); + // Create mapping if (!MocRegisterIncluded(incKey.Key, source, source, false)) { return false; @@ -740,13 +728,13 @@ bool cmQtAutoMocUic::JobEvaluateT::MocEvalSource( std::string const headerBase = incKey.Dir + incKey.Base; SourceFileHandleT header = MocFindIncludedHeader(sourceDir, headerBase); if (!header) { - std::string msg = "The file includes the moc file "; - msg += Quoted(incKey.Key); - msg += ",\nwhich seems to be the moc file from a different source " - "file.\nCMAKE_AUTOMOC_RELAXED_MODE: Also a matching header" - "could not be found in the following locations\n"; - msg += MocMessageTestHeaders(headerBase); - LogFileError(GenT::MOC, sourceFile.FileName, msg); + LogFileError( + GenT::MOC, sourceFile.FileName, + cmStrCat("The file includes the moc file ", Quoted(incKey.Key), + ",\nwhich seems to be the moc file from a different source " + "file.\nCMAKE_AUTOMOC_RELAXED_MODE: Also a matching header" + "could not be found in the following locations\n", + MocMessageTestHeaders(headerBase))); return false; } // Check if header is skipped @@ -755,23 +743,25 @@ bool cmQtAutoMocUic::JobEvaluateT::MocEvalSource( } // Issue a warning if (ownMoc && parseData.Macro.empty()) { - std::string msg = cmStrCat( - "The file includes the moc file ", Quoted(incKey.Key), - ", but does not contain a\n", MocConst().MacrosString(), - " macro.\nRunning moc on the header\n ", Quoted(header->FileName), - "!\nBetter include ", Quoted("moc_" + incKey.Base + ".cpp"), - " for a compatibility with regular mode.\n", - "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n"); - Log().WarningFile(GenT::MOC, sourceFile.FileName, msg); + Log().WarningFile( + GenT::MOC, sourceFile.FileName, + cmStrCat("The file includes the moc file ", Quoted(incKey.Key), + ", but does not contain a\n", MocConst().MacrosString(), + " macro.\nRunning moc on the header\n ", + Quoted(header->FileName), "!\nBetter include ", + Quoted("moc_" + incKey.Base + ".cpp"), + " for a compatibility with regular mode.\n", + "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n")); } else { - std::string msg = cmStrCat( - "The file includes the moc file ", Quoted(incKey.Key), - " instead of ", Quoted("moc_" + incKey.Base + ".cpp"), - ".\nRunning moc on the header\n ", Quoted(header->FileName), - "!\nBetter include ", Quoted("moc_" + incKey.Base + ".cpp"), - " for compatibility with regular mode.\n", - "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n"); - Log().WarningFile(GenT::MOC, sourceFile.FileName, msg); + Log().WarningFile( + GenT::MOC, sourceFile.FileName, + cmStrCat("The file includes the moc file ", Quoted(incKey.Key), + " instead of ", Quoted("moc_" + incKey.Base + ".cpp"), + ".\nRunning moc on the header\n ", + Quoted(header->FileName), "!\nBetter include ", + Quoted("moc_" + incKey.Base + ".cpp"), + " for compatibility with regular mode.\n", + "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n")); } // Create mapping if (!MocRegisterIncluded(incKey.Key, source, std::move(header), true)) { @@ -785,21 +775,22 @@ bool cmQtAutoMocUic::JobEvaluateT::MocEvalSource( bool const ownMoc = (incKey.Base == sourceBase); if (!ownMoc) { // Don't allow <BASE>.moc include other than own in regular mode - std::string msg = "The file includes the moc file "; - msg += Quoted(incKey.Key); - msg += ",\nwhich seems to be the moc file from a different " - "source file.\nThis is not supported. Include "; - msg += Quoted(sourceBase + ".moc"); - msg += " to run moc on this source file."; - LogFileError(GenT::MOC, sourceFile.FileName, msg); + LogFileError( + GenT::MOC, sourceFile.FileName, + cmStrCat("The file includes the moc file ", Quoted(incKey.Key), + ",\nwhich seems to be the moc file from a different " + "source file.\nThis is not supported. Include ", + Quoted(sourceBase + ".moc"), + " to run moc on this source file.")); return false; } // Accept but issue a warning if moc isn't required if (parseData.Macro.empty()) { - std::string msg = cmStrCat( - "The file includes the moc file ", Quoted(incKey.Key), - ", but does not contain a ", MocConst().MacrosString(), " macro."); - Log().WarningFile(GenT::MOC, sourceFile.FileName, msg); + Log().WarningFile(GenT::MOC, sourceFile.FileName, + cmStrCat("The file includes the moc file ", + Quoted(incKey.Key), + ", but does not contain a ", + MocConst().MacrosString(), " macro.")); } // Create mapping if (!MocRegisterIncluded(incKey.Key, source, source, false)) { @@ -870,19 +861,16 @@ cmQtAutoMocUic::SourceFileHandleT cmQtAutoMocUic::JobEvaluateT::MocFindHeader( } std::string cmQtAutoMocUic::JobEvaluateT::MocMessageTestHeaders( - std::string const& fileBase) const + cm::string_view fileBase) const { - std::ostringstream res; - { - std::string exts = - cmStrCat(".{", cmJoin(BaseConst().HeaderExtensions, ","), - '}'); // Compose result string - res << " " << fileBase << exts << '\n'; - for (std::string const& path : MocConst().IncludePaths) { - res << " " << path << '/' << fileBase << exts << '\n'; - } + std::string const exts = + cmStrCat(".{", cmJoin(BaseConst().HeaderExtensions, ","), '}'); + // Compose result string + std::string res = cmStrCat(" ", fileBase, exts, '\n'); + for (std::string const& path : MocConst().IncludePaths) { + res += cmStrCat(" ", path, '/', fileBase, exts, '\n'); } - return res.str(); + return res; } bool cmQtAutoMocUic::JobEvaluateT::MocRegisterIncluded( @@ -894,26 +882,24 @@ bool cmQtAutoMocUic::JobEvaluateT::MocRegisterIncluded( if (handle) { // Check if the output file would be generated from different source files if (handle->SourceFile != sourceFileHandle) { - std::string msg = cmStrCat("The source files\n ", - Quoted(includerFileHandle->FileName), '\n'); + std::string files = + cmStrCat(" ", Quoted(includerFileHandle->FileName), '\n'); for (auto const& item : handle->IncluderFiles) { - msg += " "; - msg += Quoted(item->FileName); - msg += '\n'; - } - msg += "contain the same include string "; - msg += Quoted(includeString); - msg += ", but\nthe moc file would be generated from different " - "source files\n "; - msg += Quoted(sourceFileHandle->FileName); - msg += " and\n "; - msg += Quoted(handle->SourceFile->FileName); - msg += ".\nConsider to\n" - " - not include the \"moc_<NAME>.cpp\" file\n" - " - add a directory prefix to a \"<NAME>.moc\" include " - "(e.g \"sub/<NAME>.moc\")\n" - " - rename the source file(s)\n"; - LogError(GenT::MOC, msg); + files += cmStrCat(" ", Quoted(item->FileName), '\n'); + } + LogError( + GenT::MOC, + cmStrCat("The source files\n", files, + "contain the same include string ", Quoted(includeString), + ", but\nthe moc file would be generated from different " + "source files\n ", + Quoted(sourceFileHandle->FileName), " and\n ", + Quoted(handle->SourceFile->FileName), + ".\nConsider to\n" + " - not include the \"moc_<NAME>.cpp\" file\n" + " - add a directory prefix to a \"<NAME>.moc\" include " + "(e.g \"sub/<NAME>.moc\")\n" + " - rename the source file(s)\n")); return false; } @@ -927,7 +913,7 @@ bool cmQtAutoMocUic::JobEvaluateT::MocRegisterIncluded( handle->IncludeString = includeString; handle->IncluderFiles.emplace_back(std::move(includerFileHandle)); handle->SourceFile = std::move(sourceFileHandle); - handle->OutputFile += Gen()->AbsoluteIncludePath(includeString); + handle->OutputFile = Gen()->AbsoluteIncludePath(includeString); // Register mapping in sources/headers map MocRegisterMapping(handle, sourceIsHeader); @@ -963,7 +949,7 @@ bool cmQtAutoMocUic::JobEvaluateT::UicEval(SourceFileMapT const& fileMap) } bool cmQtAutoMocUic::JobEvaluateT::UicEvalFile( - SourceFileHandleT sourceFileHandle) + SourceFileHandleT const& sourceFileHandle) { SourceFileT const& sourceFile = *sourceFileHandle; auto const& Include = sourceFile.ParseData->Uic.Include; @@ -981,7 +967,7 @@ bool cmQtAutoMocUic::JobEvaluateT::UicEvalFile( } // Register mapping if (!UicRegisterMapping(incKey.Key, std::move(uiFileHandle), - std::move(sourceFileHandle))) { + sourceFileHandle)) { return false; } } @@ -999,26 +985,25 @@ bool cmQtAutoMocUic::JobEvaluateT::UicRegisterMapping( MappingHandleT const& handle = it->second; if (handle->SourceFile != uiFileHandle) { // The output file already gets generated - from a different .ui file! - std::string msg = cmStrCat("The source files\n ", - Quoted(includerFileHandle->FileName), '\n'); + std::string files = + cmStrCat(" ", Quoted(includerFileHandle->FileName), '\n'); for (auto const& item : handle->IncluderFiles) { - msg += " "; - msg += Quoted(item->FileName); - msg += '\n'; - } - msg += "contain the same include string "; - msg += Quoted(includeString); - msg += ", but\nthe uic file would be generated from different " - "user interface files\n "; - msg += Quoted(uiFileHandle->FileName); - msg += " and\n "; - msg += Quoted(handle->SourceFile->FileName); - msg += ".\nConsider to\n" - " - add a directory prefix to a \"ui_<NAME>.h\" include " - "(e.g \"sub/ui_<NAME>.h\")\n" - " - rename the <NAME>.ui file(s) and adjust the \"ui_<NAME>.h\" " - "include(s)\n"; - LogError(GenT::UIC, msg); + files += cmStrCat(" ", Quoted(item->FileName), '\n'); + } + LogError( + GenT::UIC, + cmStrCat( + "The source files\n", files, "contain the same include string ", + Quoted(includeString), + ", but\nthe uic file would be generated from different " + "user interface files\n ", + Quoted(uiFileHandle->FileName), " and\n ", + Quoted(handle->SourceFile->FileName), + ".\nConsider to\n" + " - add a directory prefix to a \"ui_<NAME>.h\" include " + "(e.g \"sub/ui_<NAME>.h\")\n" + " - rename the <NAME>.ui file(s) and adjust the \"ui_<NAME>.h\" " + "include(s)\n")); return false; } // Add includer file to existing mapping @@ -1029,7 +1014,7 @@ bool cmQtAutoMocUic::JobEvaluateT::UicRegisterMapping( handle->IncludeString = includeString; handle->IncluderFiles.emplace_back(std::move(includerFileHandle)); handle->SourceFile = std::move(uiFileHandle); - handle->OutputFile += Gen()->AbsoluteIncludePath(includeString); + handle->OutputFile = Gen()->AbsoluteIncludePath(includeString); // Register mapping Includes.emplace(includeString, std::move(handle)); } @@ -1086,16 +1071,15 @@ cmQtAutoMocUic::JobEvaluateT::UicFindIncludedUi( // Log error { - std::string msg = - cmStrCat("The file includes the uic file ", Quoted(incKey.Key), - ",\nbut the user interface file ", Quoted(searchFileName), - "\ncould not be found in the following locations\n"); + std::string files; for (std::string const& testFile : testFiles) { - msg += " "; - msg += Quoted(testFile); - msg += '\n'; + files += cmStrCat(" ", Quoted(testFile), '\n'); } - LogFileError(GenT::UIC, sourceFile, msg); + LogFileError( + GenT::UIC, sourceFile, + cmStrCat("The file includes the uic file ", Quoted(incKey.Key), + ",\nbut the user interface file ", Quoted(searchFileName), + "\ncould not be found in the following locations\n", files)); } return SourceFileHandleT(); @@ -1172,10 +1156,9 @@ bool cmQtAutoMocUic::JobGenerateT::MocUpdate(MappingT const& mapping, cmFileTime outputFileTime; if (!outputFileTime.Load(outputFile)) { if (reason != nullptr) { - *reason = "Generating "; - *reason += Quoted(outputFile); - *reason += ", because it doesn't exist, from "; - *reason += Quoted(sourceFile); + *reason = + cmStrCat("Generating ", Quoted(outputFile), + ", because it doesn't exist, from ", Quoted(sourceFile)); } return true; } @@ -1183,10 +1166,9 @@ bool cmQtAutoMocUic::JobGenerateT::MocUpdate(MappingT const& mapping, // Test if any setting changed if (MocConst().SettingsChanged) { if (reason != nullptr) { - *reason = "Generating "; - *reason += Quoted(outputFile); - *reason += ", because the uic settings changed, from "; - *reason += Quoted(sourceFile); + *reason = cmStrCat("Generating ", Quoted(outputFile), + ", because the uic settings changed, from ", + Quoted(sourceFile)); } return true; } @@ -1194,10 +1176,9 @@ bool cmQtAutoMocUic::JobGenerateT::MocUpdate(MappingT const& mapping, // Test if the source file is newer if (outputFileTime.Older(mapping.SourceFile->FileTime)) { if (reason != nullptr) { - *reason = "Generating "; - *reason += Quoted(outputFile); - *reason += ", because it's older than its source file, from "; - *reason += Quoted(sourceFile); + *reason = cmStrCat("Generating ", Quoted(outputFile), + ", because it's older than its source file, from ", + Quoted(sourceFile)); } return true; } @@ -1206,12 +1187,9 @@ bool cmQtAutoMocUic::JobGenerateT::MocUpdate(MappingT const& mapping, if (!MocConst().PredefsFileAbs.empty()) { if (outputFileTime.Older(MocEval().PredefsTime)) { if (reason != nullptr) { - *reason = "Generating "; - *reason += Quoted(outputFile); - *reason += ", because it's older than "; - *reason += Quoted(MocConst().PredefsFileAbs); - *reason += ", from "; - *reason += Quoted(sourceFile); + *reason = cmStrCat( + "Generating ", Quoted(outputFile), ", because it's older than ", + Quoted(MocConst().PredefsFileAbs), ", from ", Quoted(sourceFile)); } return true; } @@ -1220,10 +1198,9 @@ bool cmQtAutoMocUic::JobGenerateT::MocUpdate(MappingT const& mapping, // Test if the moc executable is newer if (outputFileTime.Older(MocConst().ExecutableTime)) { if (reason != nullptr) { - *reason = "Generating "; - *reason += Quoted(outputFile); - *reason += ", because it's older than the moc executable, from "; - *reason += Quoted(sourceFile); + *reason = cmStrCat("Generating ", Quoted(outputFile), + ", because it's older than the moc executable, from ", + Quoted(sourceFile)); } return true; } @@ -1243,12 +1220,10 @@ bool cmQtAutoMocUic::JobGenerateT::MocUpdate(MappingT const& mapping, // Test if dependency file is older if (outputFileTime.Older(depMatch.second)) { if (reason != nullptr) { - *reason = "Generating "; - *reason += Quoted(outputFile); - *reason += ", because it's older than its dependency file "; - *reason += Quoted(depMatch.first); - *reason += ", from "; - *reason += Quoted(sourceFile); + *reason = + cmStrCat("Generating ", Quoted(outputFile), + ", because it's older than its dependency file ", + Quoted(depMatch.first), ", from ", Quoted(sourceFile)); } return true; } @@ -1272,9 +1247,7 @@ cmQtAutoMocUic::JobGenerateT::MocFindDependency( } // Search in include directories for (std::string const& includePath : MocConst().IncludePaths) { - ResPair res{ includePath, {} }; - res.first += '/'; - res.first += includeString; + ResPair res{ cmStrCat(includePath, '/', includeString), {} }; if (res.second.Load(res.first)) { return res; } @@ -1313,10 +1286,9 @@ bool cmQtAutoMocUic::JobGenerateT::UicUpdate(MappingT const& mapping, cmFileTime outputFileTime; if (!outputFileTime.Load(outputFile)) { if (reason != nullptr) { - *reason = "Generating "; - *reason += Quoted(outputFile); - *reason += ", because it doesn't exist, from "; - *reason += Quoted(sourceFile); + *reason = + cmStrCat("Generating ", Quoted(outputFile), + ", because it doesn't exist, from ", Quoted(sourceFile)); } return true; } @@ -1324,10 +1296,9 @@ bool cmQtAutoMocUic::JobGenerateT::UicUpdate(MappingT const& mapping, // Test if the uic settings changed if (UicConst().SettingsChanged) { if (reason != nullptr) { - *reason = "Generating "; - *reason += Quoted(outputFile); - *reason += ", because the uic settings changed, from "; - *reason += Quoted(sourceFile); + *reason = cmStrCat("Generating ", Quoted(outputFile), + ", because the uic settings changed, from ", + Quoted(sourceFile)); } return true; } @@ -1335,10 +1306,9 @@ bool cmQtAutoMocUic::JobGenerateT::UicUpdate(MappingT const& mapping, // Test if the source file is newer if (outputFileTime.Older(mapping.SourceFile->FileTime)) { if (reason != nullptr) { - *reason = "Generating "; - *reason += Quoted(outputFile); - *reason += " because it's older than the source file "; - *reason += Quoted(sourceFile); + *reason = cmStrCat("Generating ", Quoted(outputFile), + " because it's older than the source file ", + Quoted(sourceFile)); } return true; } @@ -1346,10 +1316,9 @@ bool cmQtAutoMocUic::JobGenerateT::UicUpdate(MappingT const& mapping, // Test if the uic executable is newer if (outputFileTime.Older(UicConst().ExecutableTime)) { if (reason != nullptr) { - *reason = "Generating "; - *reason += Quoted(outputFile); - *reason += ", because it's older than the uic executable, from "; - *reason += Quoted(sourceFile); + *reason = cmStrCat("Generating ", Quoted(outputFile), + ", because it's older than the uic executable, from ", + Quoted(sourceFile)); } return true; } @@ -1385,21 +1354,19 @@ void cmQtAutoMocUic::JobMocT::Process() } } else { // Moc command failed - std::string msg = - cmStrCat("The moc process failed to compile\n ", Quoted(sourceFile), - "\ninto\n ", Quoted(outputFile)); - if (Mapping->IncluderFiles.empty()) { - msg += ".\n"; - } else { - msg += "\nincluded by\n"; + std::string includers; + if (!Mapping->IncluderFiles.empty()) { + includers = "included by\n"; for (auto const& item : Mapping->IncluderFiles) { - msg += " "; - msg += Quoted(item->FileName); - msg += '\n'; + includers += cmStrCat(" ", Quoted(item->FileName), '\n'); } } - msg += result.ErrorMessage; - LogCommandError(GenT::MOC, msg, cmd, result.StdOut); + LogCommandError(GenT::MOC, + cmStrCat("The moc process failed to compile\n ", + Quoted(sourceFile), "\ninto\n ", + Quoted(outputFile), '\n', includers, + result.ErrorMessage), + cmd, result.StdOut); } } @@ -1433,16 +1400,16 @@ void cmQtAutoMocUic::JobUicT::Process() } } else { // Uic command failed - std::string msg = - cmStrCat("The uic process failed to compile\n ", Quoted(sourceFile), - "\ninto\n ", Quoted(outputFile), "\nincluded by\n"); + std::string includers; for (auto const& item : Mapping->IncluderFiles) { - msg += " "; - msg += Quoted(item->FileName); - msg += '\n'; + includers += cmStrCat(" ", Quoted(item->FileName), '\n'); } - msg += result.ErrorMessage; - LogCommandError(GenT::UIC, msg, cmd, result.StdOut); + LogCommandError(GenT::UIC, + cmStrCat("The uic process failed to compile\n ", + Quoted(sourceFile), "\ninto\n ", + Quoted(outputFile), "\nincluded by\n", includers, + result.ErrorMessage), + cmd, result.StdOut); } } @@ -1455,19 +1422,14 @@ void cmQtAutoMocUic::JobMocsCompilationT::Process() if (MocEval().CompFiles.empty()) { // Placeholder content content += "// No files found that require moc or the moc files are " - "included\n"; - content += "enum some_compilers { need_more_than_nothing };\n"; + "included\n" + "enum some_compilers { need_more_than_nothing };\n"; } else { // Valid content - char const clampB = BaseConst().MultiConfig ? '<' : '"'; - char const clampE = BaseConst().MultiConfig ? '>' : '"'; - for (std::string const& mocfile : MocEval().CompFiles) { - content += "#include "; - content += clampB; - content += mocfile; - content += clampE; - content += '\n'; - } + const bool mc = BaseConst().MultiConfig; + cm::string_view const wrapFront = mc ? "#include <" : "#include \""; + cm::string_view const wrapBack = mc ? ">\n" : "\"\n"; + content += cmWrap(wrapFront, MocEval().CompFiles, wrapBack, ""); } std::string const& compAbs = MocConst().CompFileAbs; @@ -1503,22 +1465,21 @@ cmQtAutoMocUic::~cmQtAutoMocUic() = default; bool cmQtAutoMocUic::Init(cmMakefile* makefile) { // Utility lambdas - auto InfoGet = [makefile](const char* key) { - return makefile->GetSafeDefinition(key); + auto InfoGet = [makefile](cm::string_view key) { + return makefile->GetSafeDefinition(std::string(key)); }; - auto InfoGetBool = [makefile](const char* key) { - return makefile->IsOn(key); + auto InfoGetBool = [makefile](cm::string_view key) { + return makefile->IsOn(std::string(key)); }; - auto InfoGetList = [makefile](const char* key) -> std::vector<std::string> { - std::vector<std::string> list; - cmExpandList(makefile->GetSafeDefinition(key), list); - return list; + auto InfoGetList = + [makefile](cm::string_view key) -> std::vector<std::string> { + return cmExpandedList(makefile->GetSafeDefinition(std::string(key))); }; auto InfoGetLists = - [makefile](const char* key) -> std::vector<std::vector<std::string>> { + [makefile](cm::string_view key) -> std::vector<std::vector<std::string>> { std::vector<std::vector<std::string>> lists; { - std::string const value = makefile->GetSafeDefinition(key); + std::string const value = makefile->GetSafeDefinition(std::string(key)); std::string::size_type pos = 0; while (pos < value.size()) { std::string::size_type next = value.find(ListSep, pos); @@ -1536,39 +1497,30 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile) } return lists; }; - auto InfoGetConfig = [makefile, this](const char* key) -> std::string { - const char* valueConf = nullptr; - { - std::string keyConf = cmStrCat(key, '_', InfoConfig()); - valueConf = makefile->GetDefinition(keyConf); + auto InfoGetConfig = [makefile, this](cm::string_view key) -> std::string { + if (const char* valueConf = + makefile->GetDefinition(cmStrCat(key, '_', InfoConfig()))) { + return std::string(valueConf); } - if (valueConf == nullptr) { - return makefile->GetSafeDefinition(key); - } - return std::string(valueConf); + return makefile->GetSafeDefinition(std::string(key)); }; auto InfoGetConfigList = - [&InfoGetConfig](const char* key) -> std::vector<std::string> { - std::vector<std::string> list; - cmExpandList(InfoGetConfig(key), list); - return list; + [&InfoGetConfig](cm::string_view key) -> std::vector<std::string> { + return cmExpandedList(InfoGetConfig(key)); }; - auto LogInfoError = [this](std::string const& msg) -> bool { - std::ostringstream err; - err << "In " << Quoted(this->InfoFile()) << ":\n" << msg; - this->Log().Error(GenT::GEN, err.str()); + auto LogInfoError = [this](cm::string_view msg) -> bool { + this->Log().Error(GenT::GEN, + cmStrCat("In ", Quoted(this->InfoFile()), ":\n", msg)); return false; }; - auto MatchSizes = [&LogInfoError](const char* keyA, const char* keyB, + auto MatchSizes = [&LogInfoError](cm::string_view keyA, cm::string_view keyB, std::size_t sizeA, std::size_t sizeB) -> bool { if (sizeA == sizeB) { return true; } - std::ostringstream err; - err << "Lists sizes mismatch " << keyA << '(' << sizeA << ") " << keyB - << '(' << sizeB << ')'; - return LogInfoError(err.str()); + return LogInfoError(cmStrCat("Lists sizes mismatch ", keyA, '(', sizeA, + ") ", keyB, '(', sizeB, ')')); }; // -- Read info file @@ -1610,10 +1562,9 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile) return LogInfoError("CMake executable file name missing."); } if (!BaseConst_.CMakeExecutableTime.Load(BaseConst_.CMakeExecutable)) { - std::string error = - cmStrCat("The CMake executable ", Quoted(BaseConst_.CMakeExecutable), - " does not exist."); - return LogInfoError(error); + return LogInfoError(cmStrCat("The CMake executable ", + Quoted(BaseConst_.CMakeExecutable), + " does not exist.")); } BaseConst_.ParseCacheFile = InfoGetConfig("AM_PARSE_CACHE_FILE"); if (BaseConst_.ParseCacheFile.empty()) { @@ -1640,10 +1591,9 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile) MocConst_.Enabled = true; // Load the executable file time if (!MocConst_.ExecutableTime.Load(MocConst_.Executable)) { - std::string error = - cmStrCat("The moc executable ", Quoted(MocConst_.Executable), - " does not exist."); - return LogInfoError(error); + return LogInfoError(cmStrCat("The moc executable ", + Quoted(MocConst_.Executable), + " does not exist.")); } for (std::string& sfl : InfoGetList("AM_MOC_SKIP")) { MocConst_.SkipList.insert(std::move(sfl)); @@ -1659,12 +1609,11 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile) { auto addFilter = [this, &LogInfoError](std::string const& key, std::string const& exp) -> bool { - auto filterErr = [&LogInfoError, &key, &exp](const char* err) -> bool { - std::ostringstream ferr; - ferr << "AUTOMOC_DEPEND_FILTERS: " << err << '\n'; - ferr << " Key: " << Quoted(key) << '\n'; - ferr << " Exp: " << Quoted(exp) << '\n'; - return LogInfoError(ferr.str()); + auto filterErr = [&LogInfoError, &key, + &exp](cm::string_view err) -> bool { + return LogInfoError(cmStrCat("AUTOMOC_DEPEND_FILTERS: ", err, '\n', + " Key: ", Quoted(key), '\n', + " Exp: ", Quoted(exp), '\n')); }; if (key.empty()) { return filterErr("Key is empty"); @@ -1708,10 +1657,9 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile) UicConst_.Enabled = true; // Load the executable file time if (!UicConst_.ExecutableTime.Load(UicConst_.Executable)) { - std::string error = - cmStrCat("The uic executable ", Quoted(UicConst_.Executable), - " does not exist."); - return LogInfoError(error); + return LogInfoError(cmStrCat("The uic executable ", + Quoted(UicConst_.Executable), + " does not exist.")); } for (std::string& sfl : InfoGetList("AM_UIC_SKIP")) { UicConst_.SkipList.insert(std::move(sfl)); @@ -1719,8 +1667,8 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile) UicConst_.SearchPaths = InfoGetList("AM_UIC_SEARCH_PATHS"); UicConst_.TargetOptions = InfoGetConfigList("AM_UIC_TARGET_OPTIONS"); { - const char* keyFiles = "AM_UIC_OPTIONS_FILES"; - const char* keyOpts = "AM_UIC_OPTIONS_OPTIONS"; + cm::string_view const keyFiles = "AM_UIC_OPTIONS_FILES"; + cm::string_view const keyOpts = "AM_UIC_OPTIONS_OPTIONS"; auto sources = InfoGetList(keyFiles); auto options = InfoGetLists(keyOpts); if (!MatchSizes(keyFiles, keyOpts, sources.size(), options.size())) { @@ -1762,7 +1710,8 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile) // Headers { // Get file lists - const char *keyFiles = "AM_HEADERS", *keyFlags = "AM_HEADERS_FLAGS"; + cm::string_view const keyFiles = "AM_HEADERS"; + cm::string_view const keyFlags = "AM_HEADERS_FLAGS"; std::vector<std::string> files = InfoGetList(keyFiles); std::vector<std::string> flags = InfoGetList(keyFlags); std::vector<std::string> builds; @@ -1770,7 +1719,7 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile) return false; } if (MocConst().Enabled) { - const char* keyPaths = "AM_HEADERS_BUILD_PATHS"; + cm::string_view const keyPaths = "AM_HEADERS_BUILD_PATHS"; builds = InfoGetList(keyPaths); if (!MatchSizes(keyFiles, keyPaths, files.size(), builds.size())) { return false; @@ -1797,7 +1746,8 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile) // Sources { - const char *keyFiles = "AM_SOURCES", *keyFlags = "AM_SOURCES_FLAGS"; + cm::string_view const keyFiles = "AM_SOURCES"; + cm::string_view const keyFlags = "AM_SOURCES_FLAGS"; std::vector<std::string> files = InfoGetList(keyFiles); std::vector<std::string> flags = InfoGetList(keyFlags); if (!MatchSizes(keyFiles, keyFlags, files.size(), flags.size())) { @@ -1825,12 +1775,12 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile) // Moc predefs file if (!MocConst_.PredefsCmd.empty()) { - MocConst_.PredefsFileRel = "moc_predefs"; if (BaseConst_.MultiConfig) { - MocConst_.PredefsFileRel += '_'; - MocConst_.PredefsFileRel += InfoConfig(); + MocConst_.PredefsFileRel = + cmStrCat("moc_predefs_", InfoConfig(), ".h"); + } else { + MocConst_.PredefsFileRel = "moc_predefs.h"; } - MocConst_.PredefsFileRel += ".h"; MocConst_.PredefsFileAbs = AbsoluteBuildPath(MocConst().PredefsFileRel); } @@ -1843,14 +1793,14 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile) MocConst_.IncludePaths.reserve(includes.size()); // Append project directories only { - std::array<std::string const*, 2> const movePaths = { - { &BaseConst().ProjectBinaryDir, &BaseConst().ProjectSourceDir } + std::initializer_list<cm::string_view> const movePaths = { + BaseConst().ProjectBinaryDir, BaseConst().ProjectSourceDir }; - for (std::string const* ppath : movePaths) { + for (cm::string_view const& ppath : movePaths) { std::list<std::string>::iterator it = includes.begin(); while (it != includes.end()) { std::string const& path = *it; - if (cmHasPrefix(path, *ppath)) { + if (cmHasPrefix(path, ppath)) { MocConst_.IncludePaths.push_back(path); it = includes.erase(it); } else { @@ -1962,22 +1912,19 @@ void cmQtAutoMocUic::SettingsFileRead() // Compose current settings strings { cmCryptoHash cryptoHash(cmCryptoHash::AlgoSHA256); - std::string const sep(";"); - auto cha = [&cryptoHash, &sep](std::string const& value) { + auto cha = [&cryptoHash](cm::string_view value) { cryptoHash.Append(value); - cryptoHash.Append(sep); + cryptoHash.Append(";"); }; if (MocConst_.Enabled) { cryptoHash.Initialize(); cha(MocConst().Executable); - for (auto const& value : MocConst().AllOptions) { - cha(value); - } + std::for_each(MocConst().AllOptions.begin(), MocConst().AllOptions.end(), + cha); cha(BaseConst().IncludeProjectDirsBefore ? "TRUE" : "FALSE"); - for (auto const& value : MocConst().PredefsCmd) { - cha(value); - } + std::for_each(MocConst().PredefsCmd.begin(), MocConst().PredefsCmd.end(), + cha); for (auto const& filter : MocConst().DependFilters) { cha(filter.Key); } @@ -1990,14 +1937,11 @@ void cmQtAutoMocUic::SettingsFileRead() if (UicConst().Enabled) { cryptoHash.Initialize(); cha(UicConst().Executable); - for (auto const& value : UicConst().TargetOptions) { - cha(value); - } + std::for_each(UicConst().TargetOptions.begin(), + UicConst().TargetOptions.end(), cha); for (const auto& item : UicConst().Options) { cha(item.first); - for (auto const& svalue : item.second) { - cha(svalue); - } + std::for_each(item.second.begin(), item.second.end(), cha); } SettingsStringUic_ = cryptoHash.FinalizeHex(); } @@ -2045,13 +1989,10 @@ bool cmQtAutoMocUic::SettingsFileWrite() // Compose settings file content std::string content; { - auto SettingAppend = [&content](const char* key, - std::string const& value) { + auto SettingAppend = [&content](cm::string_view key, + cm::string_view value) { if (!value.empty()) { - content += key; - content += ':'; - content += value; - content += '\n'; + content += cmStrCat(key, ':', value, '\n'); } }; SettingAppend("moc", SettingsStringMoc_); @@ -2072,7 +2013,7 @@ bool cmQtAutoMocUic::SettingsFileWrite() void cmQtAutoMocUic::ParseCacheRead() { - const char* reason = nullptr; + cm::string_view reason; // Don't read the cache if it is invalid if (!BaseEval().ParseCacheTime.Load(BaseConst().ParseCacheFile)) { reason = "Refreshing parse cache because it doesn't exist."; @@ -2084,7 +2025,7 @@ void cmQtAutoMocUic::ParseCacheRead() "Refreshing parse cache because it is older than the CMake executable."; } - if (reason != nullptr) { + if (!reason.empty()) { // Don't read but refresh the complete parse cache if (Log().Verbose()) { Log().Info(GenT::GEN, reason); @@ -2133,19 +2074,13 @@ void cmQtAutoMocUic::Abort(bool error) } std::string cmQtAutoMocUic::AbsoluteBuildPath( - std::string const& relativePath) const + cm::string_view relativePath) const { - std::string res(BaseConst().AutogenBuildDir); - res += '/'; - res += relativePath; - return res; + return cmStrCat(BaseConst().AutogenBuildDir, '/', relativePath); } std::string cmQtAutoMocUic::AbsoluteIncludePath( - std::string const& relativePath) const + cm::string_view relativePath) const { - std::string res(BaseConst().AutogenIncludeDir); - res += '/'; - res += relativePath; - return res; + return cmStrCat(BaseConst().AutogenIncludeDir, '/', relativePath); } diff --git a/Source/cmQtAutoMocUic.h b/Source/cmQtAutoMocUic.h index dc18328..f676c57 100644 --- a/Source/cmQtAutoMocUic.h +++ b/Source/cmQtAutoMocUic.h @@ -9,6 +9,7 @@ #include "cmQtAutoGen.h" #include "cmQtAutoGenerator.h" #include "cmWorkerPool.h" +#include "cm_string_view.hxx" #include "cmsys/RegularExpression.hxx" #include <atomic> @@ -333,10 +334,10 @@ public: UicEvalT& UicEval() const { return Gen()->UicEval(); } // -- Error logging with automatic abort - void LogError(GenT genType, std::string const& message) const; - void LogFileError(GenT genType, std::string const& filename, - std::string const& message) const; - void LogCommandError(GenT genType, std::string const& message, + void LogError(GenT genType, cm::string_view message) const; + void LogFileError(GenT genType, cm::string_view filename, + cm::string_view message) const; + void LogCommandError(GenT genType, cm::string_view message, std::vector<std::string> const& command, std::string const& output) const; @@ -429,7 +430,7 @@ public: SourceFileHandleT MocFindIncludedHeader( std::string const& includerDir, std::string const& includeBase) const; SourceFileHandleT MocFindHeader(std::string const& basePath) const; - std::string MocMessageTestHeaders(std::string const& fileBase) const; + std::string MocMessageTestHeaders(cm::string_view fileBase) const; bool MocRegisterIncluded(std::string const& includeString, SourceFileHandleT includerFileHandle, SourceFileHandleT sourceFileHandle, @@ -439,7 +440,7 @@ public: // -- Uic bool UicEval(SourceFileMapT const& fileMap); - bool UicEvalFile(SourceFileHandleT sourceFileHandle); + bool UicEvalFile(SourceFileHandleT const& sourceFileHandle); SourceFileHandleT UicFindIncludedUi(std::string const& sourceFile, std::string const& sourceDir, IncludeKeyT const& incKey) const; @@ -531,8 +532,8 @@ public: void AbortSuccess() { Abort(false); } // -- Utility - std::string AbsoluteBuildPath(std::string const& relativePath) const; - std::string AbsoluteIncludePath(std::string const& relativePath) const; + std::string AbsoluteBuildPath(cm::string_view relativePath) const; + std::string AbsoluteIncludePath(cm::string_view relativePath) const; template <class JOBTYPE> void CreateParseJobs(SourceFileMapT const& sourceMap); diff --git a/Source/cmQtAutoRcc.cxx b/Source/cmQtAutoRcc.cxx index ea3cad9..e931346 100644 --- a/Source/cmQtAutoRcc.cxx +++ b/Source/cmQtAutoRcc.cxx @@ -1,9 +1,6 @@ /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmQtAutoRcc.h" -#include "cmQtAutoGen.h" - -#include <sstream> #include "cmAlgorithms.h" #include "cmCryptoHash.h" @@ -11,10 +8,12 @@ #include "cmFileLockResult.h" #include "cmMakefile.h" #include "cmProcessOutput.h" +#include "cmQtAutoGen.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cm_string_view.hxx" -// -- Class methods +#include <algorithm> cmQtAutoRcc::cmQtAutoRcc() = default; @@ -23,37 +22,27 @@ cmQtAutoRcc::~cmQtAutoRcc() = default; bool cmQtAutoRcc::Init(cmMakefile* makefile) { // -- Utility lambdas - auto InfoGet = [makefile](std::string const& key) { - return makefile->GetSafeDefinition(key); + auto InfoGet = [makefile](cm::string_view key) { + return makefile->GetSafeDefinition(std::string(key)); }; auto InfoGetList = - [makefile](std::string const& key) -> std::vector<std::string> { - std::vector<std::string> list; - cmExpandList(makefile->GetSafeDefinition(key), list); - return list; + [makefile](cm::string_view key) -> std::vector<std::string> { + return cmExpandedList(makefile->GetSafeDefinition(std::string(key))); }; - auto InfoGetConfig = [makefile, - this](std::string const& key) -> std::string { - const char* valueConf = nullptr; - { - std::string keyConf = cmStrCat(key, '_', InfoConfig()); - valueConf = makefile->GetDefinition(keyConf); + auto InfoGetConfig = [makefile, this](cm::string_view key) -> std::string { + if (const char* valueConf = + makefile->GetDefinition(cmStrCat(key, '_', InfoConfig()))) { + return std::string(valueConf); } - if (valueConf == nullptr) { - return makefile->GetSafeDefinition(key); - } - return std::string(valueConf); + return makefile->GetSafeDefinition(std::string(key)); }; auto InfoGetConfigList = - [&InfoGetConfig](std::string const& key) -> std::vector<std::string> { - std::vector<std::string> list; - cmExpandList(InfoGetConfig(key), list); - return list; + [&InfoGetConfig](cm::string_view key) -> std::vector<std::string> { + return cmExpandedList(InfoGetConfig(key)); }; - auto LogInfoError = [this](std::string const& msg) -> bool { - std::ostringstream err; - err << "In " << Quoted(this->InfoFile()) << ":\n" << msg; - this->Log().Error(GenT::RCC, err.str()); + auto LogInfoError = [this](cm::string_view msg) -> bool { + this->Log().Error(GenT::RCC, + cmStrCat("In ", Quoted(this->InfoFile()), ":\n", msg)); return false; }; @@ -80,9 +69,8 @@ bool cmQtAutoRcc::Init(cmMakefile* makefile) // - Rcc executable RccExecutable_ = InfoGet("ARCC_RCC_EXECUTABLE"); if (!RccExecutableTime_.Load(RccExecutable_)) { - std::string error = cmStrCat("The rcc executable ", Quoted(RccExecutable_), - " does not exist."); - return LogInfoError(error); + return LogInfoError(cmStrCat("The rcc executable ", Quoted(RccExecutable_), + " does not exist.")); } RccListOptions_ = InfoGetList("ARCC_RCC_LIST_OPTIONS"); @@ -122,17 +110,12 @@ bool cmQtAutoRcc::Init(cmMakefile* makefile) // Init derived information // ------------------------ - RccFilePublic_ = AutogenBuildDir_; - RccFilePublic_ += '/'; - RccFilePublic_ += RccPathChecksum_; - RccFilePublic_ += '/'; - RccFilePublic_ += RccFileName_; + RccFilePublic_ = + cmStrCat(AutogenBuildDir_, '/', RccPathChecksum_, '/', RccFileName_); // Compute rcc output file name if (IsMultiConfig()) { - RccFileOutput_ = IncludeDir_; - RccFileOutput_ += '/'; - RccFileOutput_ += MultiConfigOutput(); + RccFileOutput_ = cmStrCat(IncludeDir_, '/', MultiConfigOutput()); } else { RccFileOutput_ = RccFilePublic_; } @@ -175,36 +158,27 @@ bool cmQtAutoRcc::Process() std::string cmQtAutoRcc::MultiConfigOutput() const { - static std::string const suffix = "_CMAKE_"; - std::string res = cmStrCat(RccPathChecksum_, '/', - AppendFilenameSuffix(RccFileName_, suffix)); - return res; + return cmStrCat(RccPathChecksum_, '/', + AppendFilenameSuffix(RccFileName_, "_CMAKE_")); } bool cmQtAutoRcc::SettingsFileRead() { // Compose current settings strings { - cmCryptoHash crypt(cmCryptoHash::AlgoSHA256); - std::string const sep(" ~~~ "); - { - std::string str; - str += RccExecutable_; - str += sep; - str += cmJoin(RccListOptions_, ";"); - str += sep; - str += QrcFile_; - str += sep; - str += RccPathChecksum_; - str += sep; - str += RccFileName_; - str += sep; - str += cmJoin(Options_, ";"); - str += sep; - str += cmJoin(Inputs_, ";"); - str += sep; - SettingsString_ = crypt.HashString(str); - } + cmCryptoHash cryptoHash(cmCryptoHash::AlgoSHA256); + auto cha = [&cryptoHash](cm::string_view value) { + cryptoHash.Append(value); + cryptoHash.Append(";"); + }; + cha(RccExecutable_); + std::for_each(RccListOptions_.begin(), RccListOptions_.end(), cha); + cha(QrcFile_); + cha(RccPathChecksum_); + cha(RccFileName_); + std::for_each(Options_.begin(), Options_.end(), cha); + std::for_each(Inputs_.begin(), Inputs_.end(), cha); + SettingsString_ = cryptoHash.FinalizeHex(); } // Make sure the settings file exists @@ -289,21 +263,17 @@ bool cmQtAutoRcc::TestQrcRccFiles(bool& generate) { // Test if the rcc input file exists if (!QrcFileTime_.Load(QrcFile_)) { - std::string error; - error = "The resources file "; - error += Quoted(QrcFile_); - error += " does not exist"; - Log().ErrorFile(GenT::RCC, QrcFile_, error); + Log().ErrorFile( + GenT::RCC, QrcFile_, + cmStrCat("The resources file ", Quoted(QrcFile_), " does not exist")); return false; } // Test if the rcc output file exists if (!RccFileTime_.Load(RccFileOutput_)) { if (Log().Verbose()) { - Reason = "Generating "; - Reason += Quoted(RccFileOutput_); - Reason += ", because it doesn't exist, from "; - Reason += Quoted(QrcFile_); + Reason = cmStrCat("Generating ", Quoted(RccFileOutput_), + ", because it doesn't exist, from ", Quoted(QrcFile_)); } generate = true; return true; @@ -312,10 +282,9 @@ bool cmQtAutoRcc::TestQrcRccFiles(bool& generate) // Test if the settings changed if (SettingsChanged_) { if (Log().Verbose()) { - Reason = "Generating "; - Reason += Quoted(RccFileOutput_); - Reason += ", because the rcc settings changed, from "; - Reason += Quoted(QrcFile_); + Reason = cmStrCat("Generating ", Quoted(RccFileOutput_), + ", because the rcc settings changed, from ", + Quoted(QrcFile_)); } generate = true; return true; @@ -324,12 +293,9 @@ bool cmQtAutoRcc::TestQrcRccFiles(bool& generate) // Test if the rcc output file is older than the .qrc file if (RccFileTime_.Older(QrcFileTime_)) { if (Log().Verbose()) { - Reason = "Generating "; - Reason += Quoted(RccFileOutput_); - Reason += ", because it is older than "; - Reason += Quoted(QrcFile_); - Reason += ", from "; - Reason += Quoted(QrcFile_); + Reason = cmStrCat("Generating ", Quoted(RccFileOutput_), + ", because it is older than ", Quoted(QrcFile_), + ", from ", Quoted(QrcFile_)); } generate = true; return true; @@ -338,10 +304,9 @@ bool cmQtAutoRcc::TestQrcRccFiles(bool& generate) // Test if the rcc output file is older than the rcc executable if (RccFileTime_.Older(RccExecutableTime_)) { if (Log().Verbose()) { - Reason = "Generating "; - Reason += Quoted(RccFileOutput_); - Reason += ", because it is older than the rcc executable, from "; - Reason += Quoted(QrcFile_); + Reason = cmStrCat("Generating ", Quoted(RccFileOutput_), + ", because it is older than the rcc executable, from ", + Quoted(QrcFile_)); } generate = true; return true; @@ -367,22 +332,17 @@ bool cmQtAutoRcc::TestResources(bool& generate) // Check if the resource file exists cmFileTime fileTime; if (!fileTime.Load(resFile)) { - std::string error; - error = "Could not find the resource file\n "; - error += Quoted(resFile); - error += '\n'; - Log().ErrorFile(GenT::RCC, QrcFile_, error); + Log().ErrorFile(GenT::RCC, QrcFile_, + cmStrCat("Could not find the resource file\n ", + Quoted(resFile), '\n')); return false; } // Check if the resource file is newer than the rcc output file if (RccFileTime_.Older(fileTime)) { if (Log().Verbose()) { - Reason = "Generating "; - Reason += Quoted(RccFileOutput_); - Reason += ", because it is older than "; - Reason += Quoted(resFile); - Reason += ", from "; - Reason += Quoted(QrcFile_); + Reason = cmStrCat("Generating ", Quoted(RccFileOutput_), + ", because it is older than ", Quoted(resFile), + ", from ", Quoted(QrcFile_)); } generate = true; break; @@ -396,10 +356,9 @@ bool cmQtAutoRcc::TestInfoFile() // Test if the rcc output file is older than the info file if (RccFileTime_.Older(InfoFileTime())) { if (Log().Verbose()) { - std::string reason = - cmStrCat("Touching ", Quoted(RccFileOutput_), - " because it is older than ", Quoted(InfoFile())); - Log().Info(GenT::RCC, reason); + Log().Info(GenT::RCC, + cmStrCat("Touching ", Quoted(RccFileOutput_), + " because it is older than ", Quoted(InfoFile()))); } // Touch build file if (!cmSystemTools::Touch(RccFileOutput_, false)) { @@ -431,13 +390,9 @@ bool cmQtAutoRcc::GenerateRcc() // Log reason and command if (Log().Verbose()) { - std::string msg = Reason; - if (!msg.empty() && (msg.back() != '\n')) { - msg += '\n'; - } - msg += QuotedCommand(cmd); - msg += '\n'; - Log().Info(GenT::RCC, msg); + Log().Info(GenT::RCC, + cmStrCat(Reason, cmHasSuffix(Reason, '\n') ? "" : "\n", + QuotedCommand(cmd), '\n')); } std::string rccStdOut; @@ -448,12 +403,11 @@ bool cmQtAutoRcc::GenerateRcc() cmSystemTools::OUTPUT_NONE, cmDuration::zero(), cmProcessOutput::Auto); if (!result || (retVal != 0)) { // rcc process failed - { - std::string err = - cmStrCat("The rcc process failed to compile\n ", Quoted(QrcFile_), - "\ninto\n ", Quoted(RccFileOutput_)); - Log().ErrorCommand(GenT::RCC, err, cmd, rccStdOut + rccStdErr); - } + Log().ErrorCommand(GenT::RCC, + cmStrCat("The rcc process failed to compile\n ", + Quoted(QrcFile_), "\ninto\n ", + Quoted(RccFileOutput_)), + cmd, rccStdOut + rccStdErr); cmSystemTools::RemoveFile(RccFileOutput_); return false; } diff --git a/Source/cmRemoveCommand.cxx b/Source/cmRemoveCommand.cxx index 4ba21fa..457b708 100644 --- a/Source/cmRemoveCommand.cxx +++ b/Source/cmRemoveCommand.cxx @@ -2,14 +2,13 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmRemoveCommand.h" +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmStringAlgorithms.h" -class cmExecutionStatus; - // cmRemoveCommand -bool cmRemoveCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmRemoveCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.empty()) { return true; @@ -17,7 +16,7 @@ bool cmRemoveCommand::InitialPass(std::vector<std::string> const& args, std::string const& variable = args[0]; // VAR is always first // get the old value - const char* cacheValue = this->Makefile->GetDefinition(variable); + const char* cacheValue = status.GetMakefile().GetDefinition(variable); // if there is no old value then return if (!cacheValue) { @@ -51,7 +50,7 @@ bool cmRemoveCommand::InitialPass(std::vector<std::string> const& args, } // add the definition - this->Makefile->AddDefinition(variable, value); + status.GetMakefile().AddDefinition(variable, value); return true; } diff --git a/Source/cmRemoveCommand.h b/Source/cmRemoveCommand.h index 088d8ad..fb72ab5 100644 --- a/Source/cmRemoveCommand.h +++ b/Source/cmRemoveCommand.h @@ -8,34 +8,14 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmRemoveCommand +/** * \brief remove command * * cmRemoveCommand implements the remove CMake command */ -class cmRemoveCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmRemoveCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; +bool cmRemoveCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmScriptGenerator.cxx b/Source/cmScriptGenerator.cxx index 9182b41..1438f07 100644 --- a/Source/cmScriptGenerator.cxx +++ b/Source/cmScriptGenerator.cxx @@ -2,6 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmScriptGenerator.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include <utility> @@ -51,9 +52,8 @@ static void cmScriptGeneratorEncodeConfig(const std::string& config, std::string cmScriptGenerator::CreateConfigTest(const std::string& config) { - std::string result = "\"${"; - result += this->RuntimeConfigVariable; - result += "}\" MATCHES \"^("; + std::string result = + cmStrCat("\"${", this->RuntimeConfigVariable, "}\" MATCHES \"^("); if (!config.empty()) { cmScriptGeneratorEncodeConfig(config, result); } @@ -64,9 +64,8 @@ std::string cmScriptGenerator::CreateConfigTest(const std::string& config) std::string cmScriptGenerator::CreateConfigTest( std::vector<std::string> const& configs) { - std::string result = "\"${"; - result += this->RuntimeConfigVariable; - result += "}\" MATCHES \"^("; + std::string result = + cmStrCat("\"${", this->RuntimeConfigVariable, "}\" MATCHES \"^("); const char* sep = ""; for (std::string const& config : configs) { result += sep; diff --git a/Source/cmSearchPath.cxx b/Source/cmSearchPath.cxx index affff54..d15ce57 100644 --- a/Source/cmSearchPath.cxx +++ b/Source/cmSearchPath.cxx @@ -78,8 +78,7 @@ void cmSearchPath::AddCMakePath(const std::string& variable) // Get a path from a CMake variable. if (const char* value = this->FC->Makefile->GetDefinition(variable)) { - std::vector<std::string> expanded; - cmExpandList(value, expanded); + std::vector<std::string> expanded = cmExpandedList(value); for (std::string const& p : expanded) { this->AddPathInternal( @@ -103,8 +102,7 @@ void cmSearchPath::AddCMakePrefixPath(const std::string& variable) // Get a path from a CMake variable. if (const char* value = this->FC->Makefile->GetDefinition(variable)) { - std::vector<std::string> expanded; - cmExpandList(value, expanded); + std::vector<std::string> expanded = cmExpandedList(value); this->AddPrefixPaths( expanded, this->FC->Makefile->GetCurrentSourceDirectory().c_str()); diff --git a/Source/cmSeparateArgumentsCommand.cxx b/Source/cmSeparateArgumentsCommand.cxx index ab4a0c7..27f45a8 100644 --- a/Source/cmSeparateArgumentsCommand.cxx +++ b/Source/cmSeparateArgumentsCommand.cxx @@ -5,17 +5,16 @@ #include <algorithm> #include <sstream> +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmSystemTools.h" -class cmExecutionStatus; - // cmSeparateArgumentsCommand -bool cmSeparateArgumentsCommand::InitialPass( - std::vector<std::string> const& args, cmExecutionStatus&) +bool cmSeparateArgumentsCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.empty()) { - this->SetError("must be given at least one argument."); + status.SetError("must be given at least one argument."); return false; } @@ -59,17 +58,17 @@ bool cmSeparateArgumentsCommand::InitialPass( } else { std::ostringstream e; e << "given unknown argument " << arg; - this->SetError(e.str()); + status.SetError(e.str()); return false; } } if (mode == ModeOld) { // Original space-replacement version of command. - if (const char* def = this->Makefile->GetDefinition(var)) { + if (const char* def = status.GetMakefile().GetDefinition(var)) { std::string value = def; std::replace(value.begin(), value.end(), ' ', ';'); - this->Makefile->AddDefinition(var, value); + status.GetMakefile().AddDefinition(var, value); } } else { // Parse the command line. @@ -97,7 +96,7 @@ bool cmSeparateArgumentsCommand::InitialPass( value += si; } } - this->Makefile->AddDefinition(var, value); + status.GetMakefile().AddDefinition(var, value); } return true; diff --git a/Source/cmSeparateArgumentsCommand.h b/Source/cmSeparateArgumentsCommand.h index 76e2002..e000c51 100644 --- a/Source/cmSeparateArgumentsCommand.h +++ b/Source/cmSeparateArgumentsCommand.h @@ -8,34 +8,14 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmSeparateArgumentsCommand +/** * \brief separate_arguments command * * cmSeparateArgumentsCommand implements the separate_arguments CMake command */ -class cmSeparateArgumentsCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmSeparateArgumentsCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; +bool cmSeparateArgumentsCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx index 8fcb710..670161d 100644 --- a/Source/cmServerProtocol.cxx +++ b/Source/cmServerProtocol.cxx @@ -2,6 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmServerProtocol.h" +#include "cmAlgorithms.h" #include "cmExternalMakefileProjectGenerator.h" #include "cmFileMonitor.h" #include "cmGlobalGenerator.h" @@ -433,7 +434,7 @@ cmServerResponse cmServerProtocol1::ProcessCache( keys = allKeys; } else { for (auto const& i : keys) { - if (std::find(allKeys.begin(), allKeys.end(), i) == allKeys.end()) { + if (!cmContains(allKeys, i)) { return request.ReportError("Key \"" + i + "\" not found in cache."); } } diff --git a/Source/cmSetCommand.cxx b/Source/cmSetCommand.cxx index 1a12785..8c3a4cb 100644 --- a/Source/cmSetCommand.cxx +++ b/Source/cmSetCommand.cxx @@ -2,6 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmSetCommand.h" +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmRange.h" @@ -10,14 +11,12 @@ #include "cmStringAlgorithms.h" #include "cmSystemTools.h" -class cmExecutionStatus; - // cmSetCommand -bool cmSetCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmSetCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.empty()) { - this->SetError("called with incorrect number of arguments"); + status.SetError("called with incorrect number of arguments"); return false; } @@ -45,7 +44,7 @@ bool cmSetCommand::InitialPass(std::vector<std::string> const& args, std::string m = "Only the first value argument is used when setting " "an environment variable. Argument '" + args[2] + "' and later are unused."; - this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, m); + status.GetMakefile().IssueMessage(MessageType::AUTHOR_WARNING, m); } return true; } @@ -59,13 +58,13 @@ bool cmSetCommand::InitialPass(std::vector<std::string> const& args, // SET (VAR) // Removes the definition of VAR. if (args.size() == 1) { - this->Makefile->RemoveDefinition(variable); + status.GetMakefile().RemoveDefinition(variable); return true; } // SET (VAR PARENT_SCOPE) // Removes the definition of VAR // in the parent scope. if (args.size() == 2 && args.back() == "PARENT_SCOPE") { - this->Makefile->RaiseScope(variable, nullptr); + status.GetMakefile().RaiseScope(variable, nullptr); return true; } @@ -106,7 +105,7 @@ bool cmSetCommand::InitialPass(std::vector<std::string> const& args, value = cmJoin(cmMakeRange(args).advance(1).retreat(ignoreLastArgs), ";"); if (parentScope) { - this->Makefile->RaiseScope(variable, value.c_str()); + status.GetMakefile().RaiseScope(variable, value.c_str()); return true; } @@ -116,7 +115,7 @@ bool cmSetCommand::InitialPass(std::vector<std::string> const& args, if ((args.back() == "CACHE") || (args.size() > 1 && args[args.size() - 2] == "CACHE") || (force && !cache)) { - this->SetError("given invalid arguments for CACHE mode."); + status.SetError("given invalid arguments for CACHE mode."); return false; } @@ -125,7 +124,7 @@ bool cmSetCommand::InitialPass(std::vector<std::string> const& args, if (!cmState::StringToCacheEntryType(args[cacheStart + 1].c_str(), type)) { std::string m = "implicitly converting '" + args[cacheStart + 1] + "' to 'STRING' type."; - this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, m); + status.GetMakefile().IssueMessage(MessageType::AUTHOR_WARNING, m); // Setting this may not be required, since it's // initialized as a string. Keeping this here to // ensure that the type is actually converting to a string. @@ -135,7 +134,7 @@ bool cmSetCommand::InitialPass(std::vector<std::string> const& args, } // see if this is already in the cache - cmState* state = this->Makefile->GetState(); + cmState* state = status.GetMakefile().GetState(); const char* existingValue = state->GetCacheEntryValue(variable); if (existingValue && (state->GetCacheEntryType(variable) != cmStateEnums::UNINITIALIZED)) { @@ -150,11 +149,11 @@ bool cmSetCommand::InitialPass(std::vector<std::string> const& args, // if it is meant to be in the cache then define it in the cache if (cache) { - this->Makefile->AddCacheDefinition(variable, value.c_str(), docstring, - type, force); + status.GetMakefile().AddCacheDefinition(variable, value.c_str(), docstring, + type, force); } else { // add the definition - this->Makefile->AddDefinition(variable, value); + status.GetMakefile().AddDefinition(variable, value); } return true; } diff --git a/Source/cmSetCommand.h b/Source/cmSetCommand.h index 1c5a435..0973d33 100644 --- a/Source/cmSetCommand.h +++ b/Source/cmSetCommand.h @@ -8,34 +8,14 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmSetCommand +/** * \brief Set a CMAKE variable * * cmSetCommand sets a variable to a value with expansion. */ -class cmSetCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmSetCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; +bool cmSetCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmSetDirectoryPropertiesCommand.cxx b/Source/cmSetDirectoryPropertiesCommand.cxx index 8d3961a..35daca6 100644 --- a/Source/cmSetDirectoryPropertiesCommand.cxx +++ b/Source/cmSetDirectoryPropertiesCommand.cxx @@ -2,31 +2,37 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmSetDirectoryPropertiesCommand.h" +#include "cmExecutionStatus.h" #include "cmMakefile.h" -class cmExecutionStatus; +namespace { +bool RunCommand(cmMakefile& mf, std::vector<std::string>::const_iterator ait, + std::vector<std::string>::const_iterator aitend, + std::string& errors); +} // cmSetDirectoryPropertiesCommand -bool cmSetDirectoryPropertiesCommand::InitialPass( - std::vector<std::string> const& args, cmExecutionStatus&) +bool cmSetDirectoryPropertiesCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.empty()) { - this->SetError("called with incorrect number of arguments"); + status.SetError("called with incorrect number of arguments"); return false; } std::string errors; - bool ret = cmSetDirectoryPropertiesCommand::RunCommand( - this->Makefile, args.begin() + 1, args.end(), errors); + bool ret = + RunCommand(status.GetMakefile(), args.begin() + 1, args.end(), errors); if (!ret) { - this->SetError(errors); + status.SetError(errors); } return ret; } -bool cmSetDirectoryPropertiesCommand::RunCommand( - cmMakefile* mf, std::vector<std::string>::const_iterator ait, - std::vector<std::string>::const_iterator aitend, std::string& errors) +namespace { +bool RunCommand(cmMakefile& mf, std::vector<std::string>::const_iterator ait, + std::vector<std::string>::const_iterator aitend, + std::string& errors) { for (; ait != aitend; ait += 2) { if (ait + 1 == aitend) { @@ -43,8 +49,9 @@ bool cmSetDirectoryPropertiesCommand::RunCommand( errors = "Commands and macros cannot be set using SET_CMAKE_PROPERTIES"; return false; } - mf->SetProperty(prop, value.c_str()); + mf.SetProperty(prop, value.c_str()); } return true; } +} diff --git a/Source/cmSetDirectoryPropertiesCommand.h b/Source/cmSetDirectoryPropertiesCommand.h index 5416127..c243dd7 100644 --- a/Source/cmSetDirectoryPropertiesCommand.h +++ b/Source/cmSetDirectoryPropertiesCommand.h @@ -8,35 +8,9 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -class cmMakefile; - -class cmSetDirectoryPropertiesCommand : public cmCommand -{ -public: - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmSetDirectoryPropertiesCommand>(); - } - - /** - * This is called when the command is first encountered in - * the input file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; - /** - * Static entry point for use by other commands - */ - static bool RunCommand(cmMakefile* mf, - std::vector<std::string>::const_iterator ait, - std::vector<std::string>::const_iterator aitend, - std::string& errors); -}; +bool cmSetDirectoryPropertiesCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmSetPropertyCommand.cxx b/Source/cmSetPropertyCommand.cxx index 9192c11..7e3a340 100644 --- a/Source/cmSetPropertyCommand.cxx +++ b/Source/cmSetPropertyCommand.cxx @@ -2,8 +2,10 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmSetPropertyCommand.h" +#include <set> #include <sstream> +#include "cmExecutionStatus.h" #include "cmGlobalGenerator.h" #include "cmInstalledFile.h" #include "cmMakefile.h" @@ -17,20 +19,66 @@ #include "cmTest.h" #include "cmake.h" -class cmExecutionStatus; - -cmSetPropertyCommand::cmSetPropertyCommand() -{ - this->AppendMode = false; - this->AppendAsString = false; - this->Remove = true; +namespace { +bool HandleGlobalMode(cmExecutionStatus& status, + const std::set<std::string>& names, + const std::string& propertyName, + const std::string& propertyValue, bool appendAsString, + bool appendMode, bool remove); +bool HandleDirectoryMode(cmExecutionStatus& status, + const std::set<std::string>& names, + const std::string& propertyName, + const std::string& propertyValue, bool appendAsString, + bool appendMode, bool remove); +bool HandleTargetMode(cmExecutionStatus& status, + const std::set<std::string>& names, + const std::string& propertyName, + const std::string& propertyValue, bool appendAsString, + bool appendMode, bool remove); +bool HandleTarget(cmTarget* target, cmMakefile& makefile, + const std::string& propertyName, + const std::string& propertyValue, bool appendAsString, + bool appendMode, bool remove); +bool HandleSourceMode(cmExecutionStatus& status, + const std::set<std::string>& names, + const std::string& propertyName, + const std::string& propertyValue, bool appendAsString, + bool appendMode, bool remove); +bool HandleSource(cmSourceFile* sf, const std::string& propertyName, + const std::string& propertyValue, bool appendAsString, + bool appendMode, bool remove); +bool HandleTestMode(cmExecutionStatus& status, std::set<std::string>& names, + const std::string& propertyName, + const std::string& propertyValue, bool appendAsString, + bool appendMode, bool remove); +bool HandleTest(cmTest* test, const std::string& propertyName, + const std::string& propertyValue, bool appendAsString, + bool appendMode, bool remove); +bool HandleCacheMode(cmExecutionStatus& status, + const std::set<std::string>& names, + const std::string& propertyName, + const std::string& propertyValue, bool appendAsString, + bool appendMode, bool remove); +bool HandleCacheEntry(std::string const& cacheKey, const cmMakefile& makefile, + const std::string& propertyName, + const std::string& propertyValue, bool appendAsString, + bool appendMode, bool remove); +bool HandleInstallMode(cmExecutionStatus& status, + const std::set<std::string>& names, + const std::string& propertyName, + const std::string& propertyValue, bool appendAsString, + bool appendMode, bool remove); +bool HandleInstall(cmInstalledFile* file, cmMakefile& makefile, + const std::string& propertyName, + const std::string& propertyValue, bool appendAsString, + bool appendMode, bool remove); } -bool cmSetPropertyCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmSetPropertyCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() < 2) { - this->SetError("called with incorrect number of arguments"); + status.SetError("called with incorrect number of arguments"); return false; } @@ -56,10 +104,17 @@ bool cmSetPropertyCommand::InitialPass(std::vector<std::string> const& args, e << "given invalid scope " << scopeName << ". " << "Valid scopes are GLOBAL, DIRECTORY, " "TARGET, SOURCE, TEST, CACHE, INSTALL."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } + bool appendAsString = false; + bool appendMode = false; + bool remove = true; + std::set<std::string> names; + std::string propertyName; + std::string propertyValue; + // Parse the rest of the arguments up to the values. enum Doing { @@ -75,54 +130,61 @@ bool cmSetPropertyCommand::InitialPass(std::vector<std::string> const& args, doing = DoingProperty; } else if (arg == "APPEND") { doing = DoingNone; - this->AppendMode = true; - this->Remove = false; - this->AppendAsString = false; + appendMode = true; + remove = false; + appendAsString = false; } else if (arg == "APPEND_STRING") { doing = DoingNone; - this->AppendMode = true; - this->Remove = false; - this->AppendAsString = true; + appendMode = true; + remove = false; + appendAsString = true; } else if (doing == DoingNames) { - this->Names.insert(arg); + names.insert(arg); } else if (doing == DoingProperty) { - this->PropertyName = arg; + propertyName = arg; doing = DoingValues; } else if (doing == DoingValues) { - this->PropertyValue += sep; + propertyValue += sep; sep = ";"; - this->PropertyValue += arg; - this->Remove = false; + propertyValue += arg; + remove = false; } else { std::ostringstream e; e << "given invalid argument \"" << arg << "\"."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } } // Make sure a property name was found. - if (this->PropertyName.empty()) { - this->SetError("not given a PROPERTY <name> argument."); + if (propertyName.empty()) { + status.SetError("not given a PROPERTY <name> argument."); return false; } // Dispatch property setting. switch (scope) { case cmProperty::GLOBAL: - return this->HandleGlobalMode(); + return HandleGlobalMode(status, names, propertyName, propertyValue, + appendAsString, appendMode, remove); case cmProperty::DIRECTORY: - return this->HandleDirectoryMode(); + return HandleDirectoryMode(status, names, propertyName, propertyValue, + appendAsString, appendMode, remove); case cmProperty::TARGET: - return this->HandleTargetMode(); + return HandleTargetMode(status, names, propertyName, propertyValue, + appendAsString, appendMode, remove); case cmProperty::SOURCE_FILE: - return this->HandleSourceMode(); + return HandleSourceMode(status, names, propertyName, propertyValue, + appendAsString, appendMode, remove); case cmProperty::TEST: - return this->HandleTestMode(); + return HandleTestMode(status, names, propertyName, propertyValue, + appendAsString, appendMode, remove); case cmProperty::CACHE: - return this->HandleCacheMode(); + return HandleCacheMode(status, names, propertyName, propertyValue, + appendAsString, appendMode, remove); case cmProperty::INSTALL: - return this->HandleInstallMode(); + return HandleInstallMode(status, names, propertyName, propertyValue, + appendAsString, appendMode, remove); case cmProperty::VARIABLE: case cmProperty::CACHED_VARIABLE: @@ -131,57 +193,66 @@ bool cmSetPropertyCommand::InitialPass(std::vector<std::string> const& args, return true; } -bool cmSetPropertyCommand::HandleGlobalMode() +namespace { +bool HandleGlobalMode(cmExecutionStatus& status, + const std::set<std::string>& names, + const std::string& propertyName, + const std::string& propertyValue, + const bool appendAsString, const bool appendMode, + const bool remove) { - if (!this->Names.empty()) { - this->SetError("given names for GLOBAL scope."); + if (!names.empty()) { + status.SetError("given names for GLOBAL scope."); return false; } // Set or append the property. - cmake* cm = this->Makefile->GetCMakeInstance(); - std::string const& name = this->PropertyName; - const char* value = this->PropertyValue.c_str(); - if (this->Remove) { + cmake* cm = status.GetMakefile().GetCMakeInstance(); + const char* value = propertyValue.c_str(); + if (remove) { value = nullptr; } - if (this->AppendMode) { - cm->AppendProperty(name, value ? value : "", this->AppendAsString); + if (appendMode) { + cm->AppendProperty(propertyName, value ? value : "", appendAsString); } else { - cm->SetProperty(name, value); + cm->SetProperty(propertyName, value); } return true; } -bool cmSetPropertyCommand::HandleDirectoryMode() +bool HandleDirectoryMode(cmExecutionStatus& status, + const std::set<std::string>& names, + const std::string& propertyName, + const std::string& propertyValue, + const bool appendAsString, const bool appendMode, + const bool remove) { - if (this->Names.size() > 1) { - this->SetError("allows at most one name for DIRECTORY scope."); + if (names.size() > 1) { + status.SetError("allows at most one name for DIRECTORY scope."); return false; } // Default to the current directory. - cmMakefile* mf = this->Makefile; + cmMakefile* mf = &status.GetMakefile(); // Lookup the directory if given. - if (!this->Names.empty()) { + if (!names.empty()) { // Construct the directory name. Interpret relative paths with // respect to the current directory. - std::string dir = *this->Names.begin(); + std::string dir = *names.begin(); if (!cmSystemTools::FileIsFullPath(dir)) { - dir = this->Makefile->GetCurrentSourceDirectory(); - dir += "/"; - dir += *this->Names.begin(); + dir = cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', + *names.begin()); } // The local generators are associated with collapsed paths. dir = cmSystemTools::CollapseFullPath(dir); - mf = this->Makefile->GetGlobalGenerator()->FindMakefile(dir); + mf = status.GetMakefile().GetGlobalGenerator()->FindMakefile(dir); if (!mf) { // Could not find the directory. - this->SetError( + status.SetError( "DIRECTORY scope provided but requested directory was not found. " "This could be because the directory argument was invalid or, " "it is valid but has not been processed yet."); @@ -190,109 +261,128 @@ bool cmSetPropertyCommand::HandleDirectoryMode() } // Set or append the property. - std::string const& name = this->PropertyName; - const char* value = this->PropertyValue.c_str(); - if (this->Remove) { + const char* value = propertyValue.c_str(); + if (remove) { value = nullptr; } - if (this->AppendMode) { - mf->AppendProperty(name, value ? value : "", this->AppendAsString); + if (appendMode) { + mf->AppendProperty(propertyName, value ? value : "", appendAsString); } else { - mf->SetProperty(name, value); + mf->SetProperty(propertyName, value); } return true; } -bool cmSetPropertyCommand::HandleTargetMode() +bool HandleTargetMode(cmExecutionStatus& status, + const std::set<std::string>& names, + const std::string& propertyName, + const std::string& propertyValue, + const bool appendAsString, const bool appendMode, + const bool remove) { - for (std::string const& name : this->Names) { - if (this->Makefile->IsAlias(name)) { - this->SetError("can not be used on an ALIAS target."); + for (std::string const& name : names) { + if (status.GetMakefile().IsAlias(name)) { + status.SetError("can not be used on an ALIAS target."); return false; } - if (cmTarget* target = this->Makefile->FindTargetToUse(name)) { + if (cmTarget* target = status.GetMakefile().FindTargetToUse(name)) { // Handle the current target. - if (!this->HandleTarget(target)) { + if (!HandleTarget(target, status.GetMakefile(), propertyName, + propertyValue, appendAsString, appendMode, remove)) { return false; } } else { std::ostringstream e; e << "could not find TARGET " << name << ". Perhaps it has not yet been created."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } } return true; } -bool cmSetPropertyCommand::HandleTarget(cmTarget* target) +bool HandleTarget(cmTarget* target, cmMakefile& makefile, + const std::string& propertyName, + const std::string& propertyValue, const bool appendAsString, + const bool appendMode, const bool remove) { // Set or append the property. - std::string const& name = this->PropertyName; - const char* value = this->PropertyValue.c_str(); - if (this->Remove) { + const char* value = propertyValue.c_str(); + if (remove) { value = nullptr; } - if (this->AppendMode) { - target->AppendProperty(name, value, this->AppendAsString); + if (appendMode) { + target->AppendProperty(propertyName, value, appendAsString); } else { - target->SetProperty(name, value); + target->SetProperty(propertyName, value); } // Check the resulting value. - target->CheckProperty(name, this->Makefile); + target->CheckProperty(propertyName, &makefile); return true; } -bool cmSetPropertyCommand::HandleSourceMode() +bool HandleSourceMode(cmExecutionStatus& status, + const std::set<std::string>& names, + const std::string& propertyName, + const std::string& propertyValue, + const bool appendAsString, const bool appendMode, + const bool remove) { - for (std::string const& name : this->Names) { + for (std::string const& name : names) { // Get the source file. - if (cmSourceFile* sf = this->Makefile->GetOrCreateSource(name)) { - if (!this->HandleSource(sf)) { + if (cmSourceFile* sf = status.GetMakefile().GetOrCreateSource(name)) { + if (!HandleSource(sf, propertyName, propertyValue, appendAsString, + appendMode, remove)) { return false; } } else { std::ostringstream e; e << "given SOURCE name that could not be found or created: " << name; - this->SetError(e.str()); + status.SetError(e.str()); return false; } } return true; } -bool cmSetPropertyCommand::HandleSource(cmSourceFile* sf) +bool HandleSource(cmSourceFile* sf, const std::string& propertyName, + const std::string& propertyValue, const bool appendAsString, + const bool appendMode, const bool remove) { // Set or append the property. - std::string const& name = this->PropertyName; - const char* value = this->PropertyValue.c_str(); - if (this->Remove) { + const char* value = propertyValue.c_str(); + if (remove) { value = nullptr; } - if (this->AppendMode) { - sf->AppendProperty(name, value, this->AppendAsString); + if (appendMode) { + sf->AppendProperty(propertyName, value, appendAsString); } else { - sf->SetProperty(name, value); + sf->SetProperty(propertyName, value); } return true; } -bool cmSetPropertyCommand::HandleTestMode() +bool HandleTestMode(cmExecutionStatus& status, std::set<std::string>& names, + const std::string& propertyName, + const std::string& propertyValue, + const bool appendAsString, const bool appendMode, + const bool remove) { // Look for tests with all names given. std::set<std::string>::iterator next; - for (std::set<std::string>::iterator ni = this->Names.begin(); - ni != this->Names.end(); ni = next) { + for (std::set<std::string>::iterator ni = names.begin(); ni != names.end(); + ni = next) { next = ni; ++next; - if (cmTest* test = this->Makefile->GetTest(*ni)) { - if (this->HandleTest(test)) { - this->Names.erase(ni); + if (cmTest* test = status.GetMakefile().GetTest(*ni)) { + if (HandleTest(test, propertyName, propertyValue, appendAsString, + appendMode, remove)) { + names.erase(ni); } else { return false; } @@ -300,137 +390,151 @@ bool cmSetPropertyCommand::HandleTestMode() } // Names that are still left were not found. - if (!this->Names.empty()) { + if (!names.empty()) { std::ostringstream e; e << "given TEST names that do not exist:\n"; - for (std::string const& name : this->Names) { + for (std::string const& name : names) { e << " " << name << "\n"; } - this->SetError(e.str()); + status.SetError(e.str()); return false; } return true; } -bool cmSetPropertyCommand::HandleTest(cmTest* test) +bool HandleTest(cmTest* test, const std::string& propertyName, + const std::string& propertyValue, const bool appendAsString, + const bool appendMode, const bool remove) { // Set or append the property. - std::string const& name = this->PropertyName; - const char* value = this->PropertyValue.c_str(); - if (this->Remove) { + const char* value = propertyValue.c_str(); + if (remove) { value = nullptr; } - if (this->AppendMode) { - test->AppendProperty(name, value, this->AppendAsString); + if (appendMode) { + test->AppendProperty(propertyName, value, appendAsString); } else { - test->SetProperty(name, value); + test->SetProperty(propertyName, value); } return true; } -bool cmSetPropertyCommand::HandleCacheMode() +bool HandleCacheMode(cmExecutionStatus& status, + const std::set<std::string>& names, + const std::string& propertyName, + const std::string& propertyValue, + const bool appendAsString, const bool appendMode, + const bool remove) { - if (this->PropertyName == "ADVANCED") { - if (!this->Remove && !cmIsOn(this->PropertyValue) && - !cmIsOff(this->PropertyValue)) { + if (propertyName == "ADVANCED") { + if (!remove && !cmIsOn(propertyValue) && !cmIsOff(propertyValue)) { std::ostringstream e; - e << "given non-boolean value \"" << this->PropertyValue + e << "given non-boolean value \"" << propertyValue << R"(" for CACHE property "ADVANCED". )"; - this->SetError(e.str()); + status.SetError(e.str()); return false; } - } else if (this->PropertyName == "TYPE") { - if (!cmState::IsCacheEntryType(this->PropertyValue)) { + } else if (propertyName == "TYPE") { + if (!cmState::IsCacheEntryType(propertyValue)) { std::ostringstream e; - e << "given invalid CACHE entry TYPE \"" << this->PropertyValue << "\""; - this->SetError(e.str()); + e << "given invalid CACHE entry TYPE \"" << propertyValue << "\""; + status.SetError(e.str()); return false; } - } else if (this->PropertyName != "HELPSTRING" && - this->PropertyName != "STRINGS" && - this->PropertyName != "VALUE") { + } else if (propertyName != "HELPSTRING" && propertyName != "STRINGS" && + propertyName != "VALUE") { std::ostringstream e; - e << "given invalid CACHE property " << this->PropertyName << ". " + e << "given invalid CACHE property " << propertyName << ". " << "Settable CACHE properties are: " << "ADVANCED, HELPSTRING, STRINGS, TYPE, and VALUE."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } - for (std::string const& name : this->Names) { + for (std::string const& name : names) { // Get the source file. - cmMakefile* mf = this->GetMakefile(); - cmake* cm = mf->GetCMakeInstance(); + cmake* cm = status.GetMakefile().GetCMakeInstance(); const char* existingValue = cm->GetState()->GetCacheEntryValue(name); if (existingValue) { - if (!this->HandleCacheEntry(name)) { + if (!HandleCacheEntry(name, status.GetMakefile(), propertyName, + propertyValue, appendAsString, appendMode, + remove)) { return false; } } else { std::ostringstream e; e << "could not find CACHE variable " << name << ". Perhaps it has not yet been created."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } } return true; } -bool cmSetPropertyCommand::HandleCacheEntry(std::string const& cacheKey) +bool HandleCacheEntry(std::string const& cacheKey, const cmMakefile& makefile, + const std::string& propertyName, + const std::string& propertyValue, + const bool appendAsString, const bool appendMode, + const bool remove) { // Set or append the property. - std::string const& name = this->PropertyName; - const char* value = this->PropertyValue.c_str(); - cmState* state = this->Makefile->GetState(); - if (this->Remove) { - state->RemoveCacheEntryProperty(cacheKey, name); + const char* value = propertyValue.c_str(); + cmState* state = makefile.GetState(); + if (remove) { + state->RemoveCacheEntryProperty(cacheKey, propertyName); } - if (this->AppendMode) { - state->AppendCacheEntryProperty(cacheKey, name, value, - this->AppendAsString); + if (appendMode) { + state->AppendCacheEntryProperty(cacheKey, propertyName, value, + appendAsString); } else { - state->SetCacheEntryProperty(cacheKey, name, value); + state->SetCacheEntryProperty(cacheKey, propertyName, value); } return true; } -bool cmSetPropertyCommand::HandleInstallMode() +bool HandleInstallMode(cmExecutionStatus& status, + const std::set<std::string>& names, + const std::string& propertyName, + const std::string& propertyValue, + const bool appendAsString, const bool appendMode, + const bool remove) { - cmake* cm = this->Makefile->GetCMakeInstance(); + cmake* cm = status.GetMakefile().GetCMakeInstance(); - for (std::string const& name : this->Names) { + for (std::string const& name : names) { if (cmInstalledFile* file = - cm->GetOrCreateInstalledFile(this->Makefile, name)) { - if (!this->HandleInstall(file)) { + cm->GetOrCreateInstalledFile(&status.GetMakefile(), name)) { + if (!HandleInstall(file, status.GetMakefile(), propertyName, + propertyValue, appendAsString, appendMode, remove)) { return false; } } else { std::ostringstream e; e << "given INSTALL name that could not be found or created: " << name; - this->SetError(e.str()); + status.SetError(e.str()); return false; } } return true; } -bool cmSetPropertyCommand::HandleInstall(cmInstalledFile* file) +bool HandleInstall(cmInstalledFile* file, cmMakefile& makefile, + const std::string& propertyName, + const std::string& propertyValue, const bool appendAsString, + const bool appendMode, const bool remove) { // Set or append the property. - std::string const& name = this->PropertyName; - - cmMakefile* mf = this->Makefile; - - const char* value = this->PropertyValue.c_str(); - if (this->Remove) { - file->RemoveProperty(name); - } else if (this->AppendMode) { - file->AppendProperty(mf, name, value, this->AppendAsString); + const char* value = propertyValue.c_str(); + if (remove) { + file->RemoveProperty(propertyName); + } else if (appendMode) { + file->AppendProperty(&makefile, propertyName, value, appendAsString); } else { - file->SetProperty(mf, name, value); + file->SetProperty(&makefile, propertyName, value); } return true; } +} diff --git a/Source/cmSetPropertyCommand.h b/Source/cmSetPropertyCommand.h index 4051e48..ec36f84 100644 --- a/Source/cmSetPropertyCommand.h +++ b/Source/cmSetPropertyCommand.h @@ -5,58 +5,12 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include <set> #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -class cmInstalledFile; -class cmSourceFile; -class cmTarget; -class cmTest; - -class cmSetPropertyCommand : public cmCommand -{ -public: - cmSetPropertyCommand(); - - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmSetPropertyCommand>(); - } - - /** - * This is called when the command is first encountered in - * the input file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; - -private: - std::set<std::string> Names; - std::string PropertyName; - std::string PropertyValue; - bool Remove; - bool AppendMode; - bool AppendAsString; - // Implementation of each property type. - bool HandleGlobalMode(); - bool HandleDirectoryMode(); - bool HandleTargetMode(); - bool HandleTarget(cmTarget* target); - bool HandleSourceMode(); - bool HandleSource(cmSourceFile* sf); - bool HandleTestMode(); - bool HandleTest(cmTest* test); - bool HandleCacheMode(); - bool HandleCacheEntry(std::string const&); - bool HandleInstallMode(); - bool HandleInstall(cmInstalledFile* file); -}; +bool cmSetPropertyCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmSetTargetPropertiesCommand.cxx b/Source/cmSetTargetPropertiesCommand.cxx index 1dc7e69..b4360e4 100644 --- a/Source/cmSetTargetPropertiesCommand.cxx +++ b/Source/cmSetTargetPropertiesCommand.cxx @@ -6,6 +6,7 @@ #include "cmAlgorithms.h" #include "cmMakefile.h" +#include "cmStringAlgorithms.h" #include "cmTarget.h" class cmExecutionStatus; @@ -52,8 +53,8 @@ bool cmSetTargetPropertiesCommand::InitialPass( bool ret = cmSetTargetPropertiesCommand::SetOneTarget( args[i], propertyPairs, this->Makefile); if (!ret) { - std::string message = "Can not find target to add properties to: "; - message += args[i]; + std::string message = + cmStrCat("Can not find target to add properties to: ", args[i]); this->SetError(message); return false; } diff --git a/Source/cmSetTestsPropertiesCommand.cxx b/Source/cmSetTestsPropertiesCommand.cxx index cc9587c..ed909c6 100644 --- a/Source/cmSetTestsPropertiesCommand.cxx +++ b/Source/cmSetTestsPropertiesCommand.cxx @@ -6,6 +6,7 @@ #include "cmAlgorithms.h" #include "cmMakefile.h" +#include "cmStringAlgorithms.h" #include "cmTest.h" class cmExecutionStatus; @@ -70,8 +71,7 @@ bool cmSetTestsPropertiesCommand::SetOneTest( } } } else { - errors = "Can not find test to add properties to: "; - errors += tname; + errors = cmStrCat("Can not find test to add properties to: ", tname); return false; } diff --git a/Source/cmSiteNameCommand.cxx b/Source/cmSiteNameCommand.cxx index 61ede29..d47f121 100644 --- a/Source/cmSiteNameCommand.cxx +++ b/Source/cmSiteNameCommand.cxx @@ -4,19 +4,18 @@ #include "cmsys/RegularExpression.hxx" +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" -class cmExecutionStatus; - // cmSiteNameCommand -bool cmSiteNameCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmSiteNameCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() != 1) { - this->SetError("called with incorrect number of arguments"); + status.SetError("called with incorrect number of arguments"); return false; } std::vector<std::string> paths; @@ -27,12 +26,12 @@ bool cmSiteNameCommand::InitialPass(std::vector<std::string> const& args, paths.emplace_back("/sbin"); paths.emplace_back("/usr/local/bin"); - const char* cacheValue = this->Makefile->GetDefinition(args[0]); + const char* cacheValue = status.GetMakefile().GetDefinition(args[0]); if (cacheValue) { return true; } - const char* temp = this->Makefile->GetDefinition("HOSTNAME"); + const char* temp = status.GetMakefile().GetDefinition("HOSTNAME"); std::string hostname_cmd; if (temp) { hostname_cmd = temp; @@ -72,7 +71,7 @@ bool cmSiteNameCommand::InitialPass(std::vector<std::string> const& args, } } #endif - this->Makefile->AddCacheDefinition( + status.GetMakefile().AddCacheDefinition( args[0], siteName.c_str(), "Name of the computer/site where compile is being run", cmStateEnums::STRING); diff --git a/Source/cmSiteNameCommand.h b/Source/cmSiteNameCommand.h index 0190abb..e8fc608 100644 --- a/Source/cmSiteNameCommand.h +++ b/Source/cmSiteNameCommand.h @@ -8,34 +8,14 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmSiteNameCommand +/** * \brief site_name command * * cmSiteNameCommand implements the site_name CMake command */ -class cmSiteNameCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmSiteNameCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; +bool cmSiteNameCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmSourceFile.cxx b/Source/cmSourceFile.cxx index 3f52e64..5d738d5 100644 --- a/Source/cmSourceFile.cxx +++ b/Source/cmSourceFile.cxx @@ -45,11 +45,13 @@ std::string cmSourceFile::GetObjectLibrary() const return this->ObjectLibrary; } -std::string cmSourceFile::GetLanguage() +std::string const& cmSourceFile::GetOrDetermineLanguage() { // If the language was set explicitly by the user then use it. if (const char* lang = this->GetProperty(propLANGUAGE)) { - return lang; + // Assign to member in order to return a reference. + this->Language = lang; + return this->Language; } // Perform computation needed to get the language if necessary. @@ -72,8 +74,8 @@ std::string cmSourceFile::GetLanguage() } } - // Now try to determine the language. - return static_cast<cmSourceFile const*>(this)->GetLanguage(); + // Use the language determined from the file extension. + return this->Language; } std::string cmSourceFile::GetLanguage() const @@ -83,13 +85,8 @@ std::string cmSourceFile::GetLanguage() const return lang; } - // If the language was determined from the source file extension use it. - if (!this->Language.empty()) { - return this->Language; - } - - // The language is not known. - return ""; + // Use the language determined from the file extension. + return this->Language; } cmSourceFileLocation const& cmSourceFile::GetLocation() const @@ -151,9 +148,7 @@ bool cmSourceFile::FindFullPath(std::string* error) for (auto exts : extsLists) { for (std::string const& ext : *exts) { if (!ext.empty()) { - std::string extPath = fullPath; - extPath += '.'; - extPath += ext; + std::string extPath = cmStrCat(fullPath, '.', ext); if (cmSystemTools::FileExists(extPath)) { this->FullPath = extPath; return true; @@ -178,10 +173,8 @@ bool cmSourceFile::FindFullPath(std::string* error) } // Compose error - std::string err; - err += "Cannot find source file:\n "; - err += lPath; - err += "\nTried extensions"; + std::string err = + cmStrCat("Cannot find source file:\n ", lPath, "\nTried extensions"); for (auto exts : extsLists) { for (std::string const& ext : *exts) { err += " ."; @@ -279,6 +272,13 @@ const char* cmSourceFile::GetPropertyForUser(const std::string& prop) this->GetFullPath(); } + // Similarly, LANGUAGE can be determined by the file extension + // if it is requested by the user. + if (prop == propLANGUAGE) { + // The c_str pointer is valid until `this->Language` is modified. + return this->GetOrDetermineLanguage().c_str(); + } + // Perform the normal property lookup. return this->GetProperty(prop); } diff --git a/Source/cmSourceFile.h b/Source/cmSourceFile.h index edad4c7..ccd5b62 100644 --- a/Source/cmSourceFile.h +++ b/Source/cmSourceFile.h @@ -88,7 +88,7 @@ public: /** * Get the language of the compiler to use for this source file. */ - std::string GetLanguage(); + std::string const& GetOrDetermineLanguage(); std::string GetLanguage() const; /** diff --git a/Source/cmSourceFileLocation.cxx b/Source/cmSourceFileLocation.cxx index 6e2e820..0e8d09d 100644 --- a/Source/cmSourceFileLocation.cxx +++ b/Source/cmSourceFileLocation.cxx @@ -110,8 +110,7 @@ void cmSourceFileLocation::UpdateExtension(const std::string& name) // Check the source tree only because a file in the build tree should // be specified by full path at least once. We do not want this // detection to depend on whether the project has already been built. - tryPath = this->Makefile->GetCurrentSourceDirectory(); - tryPath += "/"; + tryPath = cmStrCat(this->Makefile->GetCurrentSourceDirectory(), '/'); } if (!this->Directory.empty()) { tryPath += this->Directory; diff --git a/Source/cmSourceGroup.cxx b/Source/cmSourceGroup.cxx index 7e1e836..418a40f 100644 --- a/Source/cmSourceGroup.cxx +++ b/Source/cmSourceGroup.cxx @@ -2,6 +2,8 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmSourceGroup.h" +#include "cmStringAlgorithms.h" + #include <utility> class cmSourceGroupInternals @@ -17,8 +19,7 @@ cmSourceGroup::cmSourceGroup(std::string name, const char* regex, this->Internal = new cmSourceGroupInternals; this->SetGroupRegex(regex); if (parentName) { - this->FullName = parentName; - this->FullName += "\\"; + this->FullName = cmStrCat(parentName, '\\'); } this->FullName += this->Name; } diff --git a/Source/cmSourceGroupCommand.cxx b/Source/cmSourceGroupCommand.cxx index 880773b..399f1da 100644 --- a/Source/cmSourceGroupCommand.cxx +++ b/Source/cmSourceGroupCommand.cxx @@ -2,11 +2,11 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmSourceGroupCommand.h" -#include <algorithm> #include <set> #include <stddef.h> #include <utility> +#include "cmAlgorithms.h" #include "cmMakefile.h" #include "cmSourceGroup.h" #include "cmStringAlgorithms.h" @@ -30,9 +30,7 @@ std::string getFullFilePath(const std::string& currentPath, std::string fullPath = path; if (!cmSystemTools::FileIsFullPath(path)) { - fullPath = currentPath; - fullPath += "/"; - fullPath += path; + fullPath = cmStrCat(currentPath, '/', path); } return cmSystemTools::CollapseFullPath(fullPath); @@ -140,8 +138,7 @@ cmSourceGroupCommand::getExpectedOptions() const bool cmSourceGroupCommand::isExpectedOption( const std::string& argument, const ExpectedOptions& expectedOptions) { - return std::find(expectedOptions.begin(), expectedOptions.end(), argument) != - expectedOptions.end(); + return cmContains(expectedOptions, argument); } void cmSourceGroupCommand::parseArguments( @@ -237,9 +234,8 @@ bool cmSourceGroupCommand::InitialPass(std::vector<std::string> const& args, for (auto const& filesArg : filesArguments) { std::string src = filesArg; if (!cmSystemTools::FileIsFullPath(src)) { - src = this->Makefile->GetCurrentSourceDirectory(); - src += "/"; - src += filesArg; + src = + cmStrCat(this->Makefile->GetCurrentSourceDirectory(), '/', filesArg); } src = cmSystemTools::CollapseFullPath(src); sg->AddGroupFile(src); diff --git a/Source/cmState.cxx b/Source/cmState.cxx index 07f4dec..902287c 100644 --- a/Source/cmState.cxx +++ b/Source/cmState.cxx @@ -14,11 +14,11 @@ #include "cmCacheManager.h" #include "cmCommand.h" #include "cmDefinitions.h" -#include "cmDisallowedCommand.h" #include "cmExecutionStatus.h" #include "cmGlobVerificationManager.h" #include "cmListFileCache.h" #include "cmMakefile.h" +#include "cmMessageType.h" #include "cmStatePrivate.h" #include "cmStateSnapshot.h" #include "cmStringAlgorithms.h" @@ -432,6 +432,20 @@ void cmState::AddBuiltinCommand(std::string const& name, Command command) this->BuiltinCommands.emplace(name, std::move(command)); } +static bool InvokeBuiltinCommand(cmState::BuiltinCommand command, + std::vector<cmListFileArgument> const& args, + cmExecutionStatus& status) +{ + cmMakefile& mf = status.GetMakefile(); + std::vector<std::string> expandedArguments; + if (!mf.ExpandArguments(args, expandedArguments)) { + // There was an error expanding arguments. It was already + // reported, so we can skip this command without error. + return true; + } + return command(expandedArguments, status); +} + void cmState::AddBuiltinCommand(std::string const& name, BuiltinCommand command) { @@ -439,24 +453,35 @@ void cmState::AddBuiltinCommand(std::string const& name, name, [command](const std::vector<cmListFileArgument>& args, cmExecutionStatus& status) -> bool { - std::vector<std::string> expandedArguments; - if (!status.GetMakefile().ExpandArguments(args, expandedArguments)) { - // There was an error expanding arguments. It was already - // reported, so we can skip this command without error. - return true; - } - return command(expandedArguments, status); + return InvokeBuiltinCommand(command, args, status); }); } void cmState::AddDisallowedCommand(std::string const& name, - std::unique_ptr<cmCommand> command, + BuiltinCommand command, cmPolicies::PolicyID policy, const char* message) { this->AddBuiltinCommand( name, - cm::make_unique<cmDisallowedCommand>(std::move(command), policy, message)); + [command, policy, message](const std::vector<cmListFileArgument>& args, + cmExecutionStatus& status) -> bool { + cmMakefile& mf = status.GetMakefile(); + switch (mf.GetPolicyStatus(policy)) { + case cmPolicies::WARN: + mf.IssueMessage(MessageType::AUTHOR_WARNING, + cmPolicies::GetPolicyWarning(policy)); + break; + case cmPolicies::OLD: + break; + case cmPolicies::REQUIRED_IF_USED: + case cmPolicies::REQUIRED_ALWAYS: + case cmPolicies::NEW: + mf.IssueMessage(MessageType::FATAL_ERROR, message); + return true; + } + return InvokeBuiltinCommand(command, args, status); + }); } void cmState::AddUnexpectedCommand(std::string const& name, const char* error) diff --git a/Source/cmState.h b/Source/cmState.h index 8847f3b..a7ca015 100644 --- a/Source/cmState.h +++ b/Source/cmState.h @@ -157,8 +157,7 @@ public: std::unique_ptr<cmCommand> command); void AddBuiltinCommand(std::string const& name, Command command); void AddBuiltinCommand(std::string const& name, BuiltinCommand command); - void AddDisallowedCommand(std::string const& name, - std::unique_ptr<cmCommand> command, + void AddDisallowedCommand(std::string const& name, BuiltinCommand command, cmPolicies::PolicyID policy, const char* message); void AddUnexpectedCommand(std::string const& name, const char* error); void AddScriptedCommand(std::string const& name, Command command); diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx index 5bff0e5..9a2de9d 100644 --- a/Source/cmStringCommand.cxx +++ b/Source/cmStringCommand.cxx @@ -8,139 +8,70 @@ #include <algorithm> #include <ctype.h> #include <iterator> +#include <memory> #include <sstream> #include <stdio.h> #include <stdlib.h> +#include "cm_static_string_view.hxx" + #include "cmAlgorithms.h" #include "cmCryptoHash.h" +#include "cmExecutionStatus.h" #include "cmGeneratorExpression.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmRange.h" #include "cmStringAlgorithms.h" #include "cmStringReplaceHelper.h" +#include "cmSubcommandTable.h" #include "cmSystemTools.h" #include "cmTimestamp.h" #include "cmUuid.h" -class cmExecutionStatus; +namespace { -bool cmStringCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) -{ - if (args.empty()) { - this->SetError("must be called with at least one argument."); - return false; - } +bool RegexMatch(std::vector<std::string> const& args, + cmExecutionStatus& status); +bool RegexMatchAll(std::vector<std::string> const& args, + cmExecutionStatus& status); +bool RegexReplace(std::vector<std::string> const& args, + cmExecutionStatus& status); - const std::string& subCommand = args[0]; - if (subCommand == "REGEX") { - return this->HandleRegexCommand(args); - } - if (subCommand == "REPLACE") { - return this->HandleReplaceCommand(args); - } - if (subCommand == "MD5" || subCommand == "SHA1" || subCommand == "SHA224" || - subCommand == "SHA256" || subCommand == "SHA384" || - subCommand == "SHA512" || subCommand == "SHA3_224" || - subCommand == "SHA3_256" || subCommand == "SHA3_384" || - subCommand == "SHA3_512") { - return this->HandleHashCommand(args); - } - if (subCommand == "TOLOWER") { - return this->HandleToUpperLowerCommand(args, false); - } - if (subCommand == "TOUPPER") { - return this->HandleToUpperLowerCommand(args, true); - } - if (subCommand == "COMPARE") { - return this->HandleCompareCommand(args); - } - if (subCommand == "ASCII") { - return this->HandleAsciiCommand(args); - } - if (subCommand == "CONFIGURE") { - return this->HandleConfigureCommand(args); - } - if (subCommand == "LENGTH") { - return this->HandleLengthCommand(args); - } - if (subCommand == "APPEND") { - return this->HandleAppendCommand(args); - } - if (subCommand == "PREPEND") { - return this->HandlePrependCommand(args); - } - if (subCommand == "CONCAT") { - return this->HandleConcatCommand(args); - } - if (subCommand == "JOIN") { - return this->HandleJoinCommand(args); - } - if (subCommand == "SUBSTRING") { - return this->HandleSubstringCommand(args); - } - if (subCommand == "STRIP") { - return this->HandleStripCommand(args); - } - if (subCommand == "REPEAT") { - return this->HandleRepeatCommand(args); - } - if (subCommand == "RANDOM") { - return this->HandleRandomCommand(args); - } - if (subCommand == "FIND") { - return this->HandleFindCommand(args); - } - if (subCommand == "TIMESTAMP") { - return this->HandleTimestampCommand(args); - } - if (subCommand == "MAKE_C_IDENTIFIER") { - return this->HandleMakeCIdentifierCommand(args); - } - if (subCommand == "GENEX_STRIP") { - return this->HandleGenexStripCommand(args); - } - if (subCommand == "UUID") { - return this->HandleUuidCommand(args); - } +bool joinImpl(std::vector<std::string> const& args, std::string const& glue, + size_t varIdx, cmMakefile& makefile); - std::string e = "does not recognize sub-command " + subCommand; - this->SetError(e); - return false; -} - -bool cmStringCommand::HandleHashCommand(std::vector<std::string> const& args) +bool HandleHashCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { #if !defined(CMAKE_BOOTSTRAP) if (args.size() != 3) { std::ostringstream e; e << args[0] << " requires an output variable and an input string"; - this->SetError(e.str()); + status.SetError(e.str()); return false; } std::unique_ptr<cmCryptoHash> hash(cmCryptoHash::New(args[0])); if (hash) { std::string out = hash->HashString(args[2]); - this->Makefile->AddDefinition(args[1], out); + status.GetMakefile().AddDefinition(args[1], out); return true; } return false; #else std::ostringstream e; e << args[0] << " not available during bootstrap"; - this->SetError(e.str().c_str()); + status.SetError(e.str().c_str()); return false; #endif } -bool cmStringCommand::HandleToUpperLowerCommand( - std::vector<std::string> const& args, bool toUpper) +bool HandleToUpperLowerCommand(std::vector<std::string> const& args, + bool toUpper, cmExecutionStatus& status) { if (args.size() < 3) { - this->SetError("no output variable specified"); + status.SetError("no output variable specified"); return false; } @@ -154,14 +85,27 @@ bool cmStringCommand::HandleToUpperLowerCommand( } // Store the output in the provided variable. - this->Makefile->AddDefinition(outvar, output); + status.GetMakefile().AddDefinition(outvar, output); return true; } -bool cmStringCommand::HandleAsciiCommand(std::vector<std::string> const& args) +bool HandleToUpperCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) +{ + return HandleToUpperLowerCommand(args, true, status); +} + +bool HandleToLowerCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) +{ + return HandleToUpperLowerCommand(args, false, status); +} + +bool HandleAsciiCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() < 3) { - this->SetError("No output variable specified"); + status.SetError("No output variable specified"); return false; } std::string::size_type cc; @@ -172,27 +116,26 @@ bool cmStringCommand::HandleAsciiCommand(std::vector<std::string> const& args) if (ch > 0 && ch < 256) { output += static_cast<char>(ch); } else { - std::string error = "Character with code "; - error += args[cc]; - error += " does not exist."; - this->SetError(error); + std::string error = + cmStrCat("Character with code ", args[cc], " does not exist."); + status.SetError(error); return false; } } // Store the output in the provided variable. - this->Makefile->AddDefinition(outvar, output); + status.GetMakefile().AddDefinition(outvar, output); return true; } -bool cmStringCommand::HandleConfigureCommand( - std::vector<std::string> const& args) +bool HandleConfigureCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() < 2) { - this->SetError("No input string specified."); + status.SetError("No input string specified."); return false; } if (args.size() < 3) { - this->SetError("No output variable specified."); + status.SetError("No output variable specified."); return false; } @@ -207,73 +150,75 @@ bool cmStringCommand::HandleConfigureCommand( } else { std::ostringstream err; err << "Unrecognized argument \"" << args[i] << "\""; - this->SetError(err.str()); + status.SetError(err.str()); return false; } } // Configure the string. std::string output; - this->Makefile->ConfigureString(args[1], output, atOnly, escapeQuotes); + status.GetMakefile().ConfigureString(args[1], output, atOnly, escapeQuotes); // Store the output in the provided variable. - this->Makefile->AddDefinition(args[2], output); + status.GetMakefile().AddDefinition(args[2], output); return true; } -bool cmStringCommand::HandleRegexCommand(std::vector<std::string> const& args) +bool HandleRegexCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() < 2) { - this->SetError("sub-command REGEX requires a mode to be specified."); + status.SetError("sub-command REGEX requires a mode to be specified."); return false; } std::string const& mode = args[1]; if (mode == "MATCH") { if (args.size() < 5) { - this->SetError("sub-command REGEX, mode MATCH needs " - "at least 5 arguments total to command."); + status.SetError("sub-command REGEX, mode MATCH needs " + "at least 5 arguments total to command."); return false; } - return this->RegexMatch(args); + return RegexMatch(args, status); } if (mode == "MATCHALL") { if (args.size() < 5) { - this->SetError("sub-command REGEX, mode MATCHALL needs " - "at least 5 arguments total to command."); + status.SetError("sub-command REGEX, mode MATCHALL needs " + "at least 5 arguments total to command."); return false; } - return this->RegexMatchAll(args); + return RegexMatchAll(args, status); } if (mode == "REPLACE") { if (args.size() < 6) { - this->SetError("sub-command REGEX, mode REPLACE needs " - "at least 6 arguments total to command."); + status.SetError("sub-command REGEX, mode REPLACE needs " + "at least 6 arguments total to command."); return false; } - return this->RegexReplace(args); + return RegexReplace(args, status); } std::string e = "sub-command REGEX does not recognize mode " + mode; - this->SetError(e); + status.SetError(e); return false; } -bool cmStringCommand::RegexMatch(std::vector<std::string> const& args) +bool RegexMatch(std::vector<std::string> const& args, + cmExecutionStatus& status) { //"STRING(REGEX MATCH <regular_expression> <output variable> // <input> [<input>...])\n"; std::string const& regex = args[2]; std::string const& outvar = args[3]; - this->Makefile->ClearMatches(); + status.GetMakefile().ClearMatches(); // Compile the regular expression. cmsys::RegularExpression re; if (!re.compile(regex.c_str())) { std::string e = "sub-command REGEX, mode MATCH failed to compile regex \"" + regex + "\"."; - this->SetError(e); + status.SetError(e); return false; } @@ -283,38 +228,39 @@ bool cmStringCommand::RegexMatch(std::vector<std::string> const& args) // Scan through the input for all matches. std::string output; if (re.find(input)) { - this->Makefile->StoreMatches(re); + status.GetMakefile().StoreMatches(re); std::string::size_type l = re.start(); std::string::size_type r = re.end(); if (r - l == 0) { std::string e = "sub-command REGEX, mode MATCH regex \"" + regex + "\" matched an empty string."; - this->SetError(e); + status.SetError(e); return false; } output = input.substr(l, r - l); } // Store the output in the provided variable. - this->Makefile->AddDefinition(outvar, output); + status.GetMakefile().AddDefinition(outvar, output); return true; } -bool cmStringCommand::RegexMatchAll(std::vector<std::string> const& args) +bool RegexMatchAll(std::vector<std::string> const& args, + cmExecutionStatus& status) { //"STRING(REGEX MATCHALL <regular_expression> <output variable> <input> // [<input>...])\n"; std::string const& regex = args[2]; std::string const& outvar = args[3]; - this->Makefile->ClearMatches(); + status.GetMakefile().ClearMatches(); // Compile the regular expression. cmsys::RegularExpression re; if (!re.compile(regex.c_str())) { std::string e = "sub-command REGEX, mode MATCHALL failed to compile regex \"" + regex + "\"."; - this->SetError(e); + status.SetError(e); return false; } @@ -325,14 +271,14 @@ bool cmStringCommand::RegexMatchAll(std::vector<std::string> const& args) std::string output; const char* p = input.c_str(); while (re.find(p)) { - this->Makefile->ClearMatches(); - this->Makefile->StoreMatches(re); + status.GetMakefile().ClearMatches(); + status.GetMakefile().StoreMatches(re); std::string::size_type l = re.start(); std::string::size_type r = re.end(); if (r - l == 0) { std::string e = "sub-command REGEX, mode MATCHALL regex \"" + regex + "\" matched an empty string."; - this->SetError(e); + status.SetError(e); return false; } if (!output.empty()) { @@ -343,32 +289,33 @@ bool cmStringCommand::RegexMatchAll(std::vector<std::string> const& args) } // Store the output in the provided variable. - this->Makefile->AddDefinition(outvar, output); + status.GetMakefile().AddDefinition(outvar, output); return true; } -bool cmStringCommand::RegexReplace(std::vector<std::string> const& args) +bool RegexReplace(std::vector<std::string> const& args, + cmExecutionStatus& status) { //"STRING(REGEX REPLACE <regular_expression> <replace_expression> // <output variable> <input> [<input>...])\n" std::string const& regex = args[2]; std::string const& replace = args[3]; std::string const& outvar = args[4]; - cmStringReplaceHelper replaceHelper(regex, replace, this->Makefile); + cmStringReplaceHelper replaceHelper(regex, replace, &status.GetMakefile()); if (!replaceHelper.IsReplaceExpressionValid()) { - this->SetError( + status.SetError( "sub-command REGEX, mode REPLACE: " + replaceHelper.GetError() + "."); return false; } - this->Makefile->ClearMatches(); + status.GetMakefile().ClearMatches(); if (!replaceHelper.IsRegularExpressionValid()) { std::string e = "sub-command REGEX, mode REPLACE failed to compile regex \"" + regex + "\"."; - this->SetError(e); + status.SetError(e); return false; } @@ -378,21 +325,22 @@ bool cmStringCommand::RegexReplace(std::vector<std::string> const& args) std::string output; if (!replaceHelper.Replace(input, output)) { - this->SetError( + status.SetError( "sub-command REGEX, mode REPLACE: " + replaceHelper.GetError() + "."); return false; } // Store the output in the provided variable. - this->Makefile->AddDefinition(outvar, output); + status.GetMakefile().AddDefinition(outvar, output); return true; } -bool cmStringCommand::HandleFindCommand(std::vector<std::string> const& args) +bool HandleFindCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { // check if all required parameters were passed if (args.size() < 4 || args.size() > 5) { - this->SetError("sub-command FIND requires 3 or 4 parameters."); + status.SetError("sub-command FIND requires 3 or 4 parameters."); return false; } @@ -404,7 +352,7 @@ bool cmStringCommand::HandleFindCommand(std::vector<std::string> const& args) // if we have 5 arguments the last one must be REVERSE if (args.size() == 5 && args[4] != "REVERSE") { - this->SetError("sub-command FIND: unknown last parameter"); + status.SetError("sub-command FIND: unknown last parameter"); return false; } @@ -415,9 +363,9 @@ bool cmStringCommand::HandleFindCommand(std::vector<std::string> const& args) // ensure that the user cannot accidentally specify REVERSE as a variable if (outvar == "REVERSE") { - this->SetError("sub-command FIND does not allow one to select REVERSE as " - "the output variable. " - "Maybe you missed the actual output variable?"); + status.SetError("sub-command FIND does not allow one to select REVERSE as " + "the output variable. " + "Maybe you missed the actual output variable?"); return false; } @@ -431,20 +379,20 @@ bool cmStringCommand::HandleFindCommand(std::vector<std::string> const& args) if (std::string::npos != pos) { std::ostringstream s; s << pos; - this->Makefile->AddDefinition(outvar, s.str()); + status.GetMakefile().AddDefinition(outvar, s.str()); return true; } // the character was not found, but this is not really an error - this->Makefile->AddDefinition(outvar, "-1"); + status.GetMakefile().AddDefinition(outvar, "-1"); return true; } -bool cmStringCommand::HandleCompareCommand( - std::vector<std::string> const& args) +bool HandleCompareCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() < 2) { - this->SetError("sub-command COMPARE requires a mode to be specified."); + status.SetError("sub-command COMPARE requires a mode to be specified."); return false; } std::string const& mode = args[1]; @@ -452,10 +400,10 @@ bool cmStringCommand::HandleCompareCommand( (mode == "LESS_EQUAL") || (mode == "GREATER") || (mode == "GREATER_EQUAL")) { if (args.size() < 5) { - std::string e = "sub-command COMPARE, mode "; - e += mode; - e += " needs at least 5 arguments total to command."; - this->SetError(e); + std::string e = + cmStrCat("sub-command COMPARE, mode ", mode, + " needs at least 5 arguments total to command."); + status.SetError(e); return false; } @@ -478,22 +426,22 @@ bool cmStringCommand::HandleCompareCommand( result = !(left == right); } if (result) { - this->Makefile->AddDefinition(outvar, "1"); + status.GetMakefile().AddDefinition(outvar, "1"); } else { - this->Makefile->AddDefinition(outvar, "0"); + status.GetMakefile().AddDefinition(outvar, "0"); } return true; } std::string e = "sub-command COMPARE does not recognize mode " + mode; - this->SetError(e); + status.SetError(e); return false; } -bool cmStringCommand::HandleReplaceCommand( - std::vector<std::string> const& args) +bool HandleReplaceCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() < 5) { - this->SetError("sub-command REPLACE requires at least four arguments."); + status.SetError("sub-command REPLACE requires at least four arguments."); return false; } @@ -506,15 +454,15 @@ bool cmStringCommand::HandleReplaceCommand( cmsys::SystemTools::ReplaceString(input, matchExpression.c_str(), replaceExpression.c_str()); - this->Makefile->AddDefinition(variableName, input); + status.GetMakefile().AddDefinition(variableName, input); return true; } -bool cmStringCommand::HandleSubstringCommand( - std::vector<std::string> const& args) +bool HandleSubstringCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() != 5) { - this->SetError("sub-command SUBSTRING requires four arguments."); + status.SetError("sub-command SUBSTRING requires four arguments."); return false; } @@ -529,24 +477,26 @@ bool cmStringCommand::HandleSubstringCommand( std::ostringstream ostr; ostr << "begin index: " << begin << " is out of range 0 - " << stringLength; - this->SetError(ostr.str()); + status.SetError(ostr.str()); return false; } if (end < -1) { std::ostringstream ostr; ostr << "end index: " << end << " should be -1 or greater"; - this->SetError(ostr.str()); + status.SetError(ostr.str()); return false; } - this->Makefile->AddDefinition(variableName, stringValue.substr(begin, end)); + status.GetMakefile().AddDefinition(variableName, + stringValue.substr(begin, end)); return true; } -bool cmStringCommand::HandleLengthCommand(std::vector<std::string> const& args) +bool HandleLengthCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() != 3) { - this->SetError("sub-command LENGTH requires two arguments."); + status.SetError("sub-command LENGTH requires two arguments."); return false; } @@ -557,14 +507,15 @@ bool cmStringCommand::HandleLengthCommand(std::vector<std::string> const& args) char buffer[1024]; sprintf(buffer, "%d", static_cast<int>(length)); - this->Makefile->AddDefinition(variableName, buffer); + status.GetMakefile().AddDefinition(variableName, buffer); return true; } -bool cmStringCommand::HandleAppendCommand(std::vector<std::string> const& args) +bool HandleAppendCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() < 2) { - this->SetError("sub-command APPEND requires at least one argument."); + status.SetError("sub-command APPEND requires at least one argument."); return false; } @@ -576,20 +527,20 @@ bool cmStringCommand::HandleAppendCommand(std::vector<std::string> const& args) const std::string& variable = args[1]; std::string value; - const char* oldValue = this->Makefile->GetDefinition(variable); + const char* oldValue = status.GetMakefile().GetDefinition(variable); if (oldValue) { value = oldValue; } value += cmJoin(cmMakeRange(args).advance(2), std::string()); - this->Makefile->AddDefinition(variable, value); + status.GetMakefile().AddDefinition(variable, value); return true; } -bool cmStringCommand::HandlePrependCommand( - std::vector<std::string> const& args) +bool HandlePrependCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() < 2) { - this->SetError("sub-command PREPEND requires at least one argument."); + status.SetError("sub-command PREPEND requires at least one argument."); return false; } @@ -601,67 +552,69 @@ bool cmStringCommand::HandlePrependCommand( const std::string& variable = args[1]; std::string value = cmJoin(cmMakeRange(args).advance(2), std::string()); - const char* oldValue = this->Makefile->GetDefinition(variable); + const char* oldValue = status.GetMakefile().GetDefinition(variable); if (oldValue) { value += oldValue; } - this->Makefile->AddDefinition(variable, value); + status.GetMakefile().AddDefinition(variable, value); return true; } -bool cmStringCommand::HandleConcatCommand(std::vector<std::string> const& args) +bool HandleConcatCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() < 2) { - this->SetError("sub-command CONCAT requires at least one argument."); + status.SetError("sub-command CONCAT requires at least one argument."); return false; } - return this->joinImpl(args, std::string(), 1); + return joinImpl(args, std::string(), 1, status.GetMakefile()); } -bool cmStringCommand::HandleJoinCommand(std::vector<std::string> const& args) +bool HandleJoinCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() < 3) { - this->SetError("sub-command JOIN requires at least two arguments."); + status.SetError("sub-command JOIN requires at least two arguments."); return false; } - return this->joinImpl(args, args[1], 2); + return joinImpl(args, args[1], 2, status.GetMakefile()); } -bool cmStringCommand::joinImpl(std::vector<std::string> const& args, - std::string const& glue, const size_t varIdx) +bool joinImpl(std::vector<std::string> const& args, std::string const& glue, + const size_t varIdx, cmMakefile& makefile) { std::string const& variableName = args[varIdx]; // NOTE Items to concat/join placed right after the variable for // both `CONCAT` and `JOIN` sub-commands. std::string value = cmJoin(cmMakeRange(args).advance(varIdx + 1), glue); - this->Makefile->AddDefinition(variableName, value); + makefile.AddDefinition(variableName, value); return true; } -bool cmStringCommand::HandleMakeCIdentifierCommand( - std::vector<std::string> const& args) +bool HandleMakeCIdentifierCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() != 3) { - this->SetError("sub-command MAKE_C_IDENTIFIER requires two arguments."); + status.SetError("sub-command MAKE_C_IDENTIFIER requires two arguments."); return false; } const std::string& input = args[1]; const std::string& variableName = args[2]; - this->Makefile->AddDefinition(variableName, - cmSystemTools::MakeCidentifier(input)); + status.GetMakefile().AddDefinition(variableName, + cmSystemTools::MakeCidentifier(input)); return true; } -bool cmStringCommand::HandleGenexStripCommand( - std::vector<std::string> const& args) +bool HandleGenexStripCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() != 3) { - this->SetError("sub-command GENEX_STRIP requires two arguments."); + status.SetError("sub-command GENEX_STRIP requires two arguments."); return false; } @@ -672,14 +625,15 @@ bool cmStringCommand::HandleGenexStripCommand( const std::string& variableName = args[2]; - this->Makefile->AddDefinition(variableName, result); + status.GetMakefile().AddDefinition(variableName, result); return true; } -bool cmStringCommand::HandleStripCommand(std::vector<std::string> const& args) +bool HandleStripCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() != 3) { - this->SetError("sub-command STRIP requires two arguments."); + status.SetError("sub-command STRIP requires two arguments."); return false; } @@ -711,13 +665,16 @@ bool cmStringCommand::HandleStripCommand(std::vector<std::string> const& args) outLength = endPos - startPos + 1; } - this->Makefile->AddDefinition(variableName, - stringValue.substr(startPos, outLength)); + status.GetMakefile().AddDefinition(variableName, + stringValue.substr(startPos, outLength)); return true; } -bool cmStringCommand::HandleRepeatCommand(std::vector<std::string> const& args) +bool HandleRepeatCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { + cmMakefile& makefile = status.GetMakefile(); + // `string(REPEAT "<str>" <times> OUTPUT_VARIABLE)` enum ArgPos : std::size_t { @@ -729,16 +686,15 @@ bool cmStringCommand::HandleRepeatCommand(std::vector<std::string> const& args) }; if (args.size() != ArgPos::TOTAL_ARGS) { - this->Makefile->IssueMessage( - MessageType::FATAL_ERROR, - "sub-command REPEAT requires three arguments."); + makefile.IssueMessage(MessageType::FATAL_ERROR, + "sub-command REPEAT requires three arguments."); return true; } unsigned long times; if (!cmStrToULong(args[ArgPos::TIMES], ×)) { - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, - "repeat count is not a positive number."); + makefile.IssueMessage(MessageType::FATAL_ERROR, + "repeat count is not a positive number."); return true; } @@ -765,14 +721,15 @@ bool cmStringCommand::HandleRepeatCommand(std::vector<std::string> const& args) break; } - this->Makefile->AddDefinition(variableName, result); + makefile.AddDefinition(variableName, result); return true; } -bool cmStringCommand::HandleRandomCommand(std::vector<std::string> const& args) +bool HandleRandomCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() < 2 || args.size() == 3 || args.size() == 5) { - this->SetError("sub-command RANDOM requires at least one argument."); + status.SetError("sub-command RANDOM requires at least one argument."); return false; } @@ -809,11 +766,11 @@ bool cmStringCommand::HandleRandomCommand(std::vector<std::string> const& args) double sizeofAlphabet = static_cast<double>(alphabet.size()); if (sizeofAlphabet < 1) { - this->SetError("sub-command RANDOM invoked with bad alphabet."); + status.SetError("sub-command RANDOM invoked with bad alphabet."); return false; } if (length < 1) { - this->SetError("sub-command RANDOM invoked with bad length."); + status.SetError("sub-command RANDOM invoked with bad length."); return false; } const std::string& variableName = args.back(); @@ -832,19 +789,19 @@ bool cmStringCommand::HandleRandomCommand(std::vector<std::string> const& args) } result.push_back(0); - this->Makefile->AddDefinition(variableName, result.data()); + status.GetMakefile().AddDefinition(variableName, result.data()); return true; } -bool cmStringCommand::HandleTimestampCommand( - std::vector<std::string> const& args) +bool HandleTimestampCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() < 2) { - this->SetError("sub-command TIMESTAMP requires at least one argument."); + status.SetError("sub-command TIMESTAMP requires at least one argument."); return false; } if (args.size() > 4) { - this->SetError("sub-command TIMESTAMP takes at most three arguments."); + status.SetError("sub-command TIMESTAMP takes at most three arguments."); return false; } @@ -864,25 +821,26 @@ bool cmStringCommand::HandleTimestampCommand( } else { std::string e = " TIMESTAMP sub-command does not recognize option " + args[argsIndex] + "."; - this->SetError(e); + status.SetError(e); return false; } } cmTimestamp timestamp; std::string result = timestamp.CurrentTime(formatString, utcFlag); - this->Makefile->AddDefinition(outputVariable, result); + status.GetMakefile().AddDefinition(outputVariable, result); return true; } -bool cmStringCommand::HandleUuidCommand(std::vector<std::string> const& args) +bool HandleUuidCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { #if !defined(CMAKE_BOOTSTRAP) unsigned int argsIndex = 1; if (args.size() < 2) { - this->SetError("UUID sub-command requires an output variable."); + status.SetError("UUID sub-command requires an output variable."); return false; } @@ -897,21 +855,21 @@ bool cmStringCommand::HandleUuidCommand(std::vector<std::string> const& args) if (args[argsIndex] == "NAMESPACE") { ++argsIndex; if (argsIndex >= args.size()) { - this->SetError("UUID sub-command, NAMESPACE requires a value."); + status.SetError("UUID sub-command, NAMESPACE requires a value."); return false; } uuidNamespaceString = args[argsIndex++]; } else if (args[argsIndex] == "NAME") { ++argsIndex; if (argsIndex >= args.size()) { - this->SetError("UUID sub-command, NAME requires a value."); + status.SetError("UUID sub-command, NAME requires a value."); return false; } uuidName = args[argsIndex++]; } else if (args[argsIndex] == "TYPE") { ++argsIndex; if (argsIndex >= args.size()) { - this->SetError("UUID sub-command, TYPE requires a value."); + status.SetError("UUID sub-command, TYPE requires a value."); return false; } uuidType = args[argsIndex++]; @@ -921,7 +879,7 @@ bool cmStringCommand::HandleUuidCommand(std::vector<std::string> const& args) } else { std::string e = "UUID sub-command does not recognize option " + args[argsIndex] + "."; - this->SetError(e); + status.SetError(e); return false; } } @@ -931,7 +889,7 @@ bool cmStringCommand::HandleUuidCommand(std::vector<std::string> const& args) std::vector<unsigned char> uuidNamespace; if (!uuidGenerator.StringToBinary(uuidNamespaceString, uuidNamespace)) { - this->SetError("UUID sub-command, malformed NAMESPACE UUID."); + status.SetError("UUID sub-command, malformed NAMESPACE UUID."); return false; } @@ -941,12 +899,12 @@ bool cmStringCommand::HandleUuidCommand(std::vector<std::string> const& args) uuid = uuidGenerator.FromSha1(uuidNamespace, uuidName); } else { std::string e = "UUID sub-command, unknown TYPE '" + uuidType + "'."; - this->SetError(e); + status.SetError(e); return false; } if (uuid.empty()) { - this->SetError("UUID sub-command, generation failed."); + status.SetError("UUID sub-command, generation failed."); return false; } @@ -954,12 +912,59 @@ bool cmStringCommand::HandleUuidCommand(std::vector<std::string> const& args) uuid = cmSystemTools::UpperCase(uuid); } - this->Makefile->AddDefinition(outputVariable, uuid); + status.GetMakefile().AddDefinition(outputVariable, uuid); return true; #else std::ostringstream e; e << args[0] << " not available during bootstrap"; - this->SetError(e.str().c_str()); + status.SetError(e.str().c_str()); return false; #endif } + +} // namespace + +bool cmStringCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) +{ + if (args.empty()) { + status.SetError("must be called with at least one argument."); + return false; + } + + static cmSubcommandTable const subcommand{ + { "REGEX"_s, HandleRegexCommand }, + { "REPLACE"_s, HandleReplaceCommand }, + { "MD5"_s, HandleHashCommand }, + { "SHA1"_s, HandleHashCommand }, + { "SHA224"_s, HandleHashCommand }, + { "SHA256"_s, HandleHashCommand }, + { "SHA384"_s, HandleHashCommand }, + { "SHA512"_s, HandleHashCommand }, + { "SHA3_224"_s, HandleHashCommand }, + { "SHA3_256"_s, HandleHashCommand }, + { "SHA3_384"_s, HandleHashCommand }, + { "SHA3_512"_s, HandleHashCommand }, + { "TOLOWER"_s, HandleToLowerCommand }, + { "TOUPPER"_s, HandleToUpperCommand }, + { "COMPARE"_s, HandleCompareCommand }, + { "ASCII"_s, HandleAsciiCommand }, + { "CONFIGURE"_s, HandleConfigureCommand }, + { "LENGTH"_s, HandleLengthCommand }, + { "APPEND"_s, HandleAppendCommand }, + { "PREPEND"_s, HandlePrependCommand }, + { "CONCAT"_s, HandleConcatCommand }, + { "JOIN"_s, HandleJoinCommand }, + { "SUBSTRING"_s, HandleSubstringCommand }, + { "STRIP"_s, HandleStripCommand }, + { "REPEAT"_s, HandleRepeatCommand }, + { "RANDOM"_s, HandleRandomCommand }, + { "FIND"_s, HandleFindCommand }, + { "TIMESTAMP"_s, HandleTimestampCommand }, + { "MAKE_C_IDENTIFIER"_s, HandleMakeCIdentifierCommand }, + { "GENEX_STRIP"_s, HandleGenexStripCommand }, + { "UUID"_s, HandleUuidCommand }, + }; + + return subcommand(args[0], args, status); +} diff --git a/Source/cmStringCommand.h b/Source/cmStringCommand.h index f48ea17..bd71ba2 100644 --- a/Source/cmStringCommand.h +++ b/Source/cmStringCommand.h @@ -5,67 +5,16 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include <cstddef> #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmStringCommand +/** * \brief Common string operations * */ -class cmStringCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmStringCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; - -protected: - bool HandleConfigureCommand(std::vector<std::string> const& args); - bool HandleAsciiCommand(std::vector<std::string> const& args); - bool HandleRegexCommand(std::vector<std::string> const& args); - bool RegexMatch(std::vector<std::string> const& args); - bool RegexMatchAll(std::vector<std::string> const& args); - bool RegexReplace(std::vector<std::string> const& args); - bool HandleHashCommand(std::vector<std::string> const& args); - bool HandleToUpperLowerCommand(std::vector<std::string> const& args, - bool toUpper); - bool HandleCompareCommand(std::vector<std::string> const& args); - bool HandleReplaceCommand(std::vector<std::string> const& args); - bool HandleLengthCommand(std::vector<std::string> const& args); - bool HandleSubstringCommand(std::vector<std::string> const& args); - bool HandleAppendCommand(std::vector<std::string> const& args); - bool HandlePrependCommand(std::vector<std::string> const& args); - bool HandleConcatCommand(std::vector<std::string> const& args); - bool HandleJoinCommand(std::vector<std::string> const& args); - bool HandleStripCommand(std::vector<std::string> const& args); - bool HandleRepeatCommand(std::vector<std::string> const& args); - bool HandleRandomCommand(std::vector<std::string> const& args); - bool HandleFindCommand(std::vector<std::string> const& args); - bool HandleTimestampCommand(std::vector<std::string> const& args); - bool HandleMakeCIdentifierCommand(std::vector<std::string> const& args); - bool HandleGenexStripCommand(std::vector<std::string> const& args); - bool HandleUuidCommand(std::vector<std::string> const& args); - - bool joinImpl(std::vector<std::string> const& args, std::string const& glue, - size_t varIdx); -}; +bool cmStringCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmSubdirCommand.cxx b/Source/cmSubdirCommand.cxx index 9d36228..07f8efe 100644 --- a/Source/cmSubdirCommand.cxx +++ b/Source/cmSubdirCommand.cxx @@ -3,6 +3,7 @@ #include "cmSubdirCommand.h" #include "cmMakefile.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" class cmExecutionStatus; @@ -44,8 +45,8 @@ bool cmSubdirCommand::InitialPass(std::vector<std::string> const& args, cmSystemTools::GetFilenameName(i); this->Makefile->AddSubDirectory(i, binPath, excludeFromAll, false); } else { - std::string error = "Incorrect SUBDIRS command. Directory: "; - error += i + " does not exist."; + std::string error = cmStrCat("Incorrect SUBDIRS command. Directory: ", i, + " does not exist."); this->SetError(error); res = false; } diff --git a/Source/cmSubdirDependsCommand.cxx b/Source/cmSubdirDependsCommand.cxx index 0bb2c0a..496c60d 100644 --- a/Source/cmSubdirDependsCommand.cxx +++ b/Source/cmSubdirDependsCommand.cxx @@ -4,8 +4,8 @@ class cmExecutionStatus; -bool cmSubdirDependsCommand::InitialPass(std::vector<std::string> const&, - cmExecutionStatus&) +bool cmSubdirDependsCommand(std::vector<std::string> const&, + cmExecutionStatus&) { return true; } diff --git a/Source/cmSubdirDependsCommand.h b/Source/cmSubdirDependsCommand.h index 64c28b9..bf99bd1 100644 --- a/Source/cmSubdirDependsCommand.h +++ b/Source/cmSubdirDependsCommand.h @@ -8,21 +8,9 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -class cmSubdirDependsCommand : public cmCommand -{ -public: - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmSubdirDependsCommand>(); - } - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; +bool cmSubdirDependsCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 3461e67..b7287d9 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -147,12 +147,10 @@ void cmSystemTools::ExpandRegistryValues(std::string& source, KeyWOW64 view) std::string key = regEntry.match(1); std::string val; if (ReadRegistryValue(key.c_str(), val, view)) { - std::string reg = "["; - reg += key + "]"; + std::string reg = cmStrCat('[', key, ']'); cmSystemTools::ReplaceString(source, reg.c_str(), val.c_str()); } else { - std::string reg = "["; - reg += key + "]"; + std::string reg = cmStrCat('[', key, ']'); cmSystemTools::ReplaceString(source, reg.c_str(), "/registry"); } } @@ -165,8 +163,7 @@ void cmSystemTools::ExpandRegistryValues(std::string& source, while (regEntry.find(source)) { // the arguments are the second match std::string key = regEntry.match(1); - std::string reg = "["; - reg += key + "]"; + std::string reg = cmStrCat('[', key, ']'); cmSystemTools::ReplaceString(source, reg.c_str(), "/registry"); } } @@ -244,9 +241,8 @@ void cmSystemTools::Message(const std::string& m, const char* title) void cmSystemTools::ReportLastSystemError(const char* msg) { - std::string m = msg; - m += ": System Error: "; - m += Superclass::GetLastSystemError(); + std::string m = + cmStrCat(msg, ": System Error: ", Superclass::GetLastSystemError()); cmSystemTools::Error(m); } @@ -346,10 +342,9 @@ std::vector<std::string> cmSystemTools::HandleResponseFile( if (cmHasLiteralPrefix(arg, "@")) { cmsys::ifstream responseFile(arg.substr(1).c_str(), std::ios::in); if (!responseFile) { - std::string error = "failed to open for reading ("; - error += cmSystemTools::GetLastSystemError(); - error += "):\n "; - error += arg.substr(1); + std::string error = cmStrCat("failed to open for reading (", + cmSystemTools::GetLastSystemError(), + "):\n ", cm::string_view(arg).substr(1)); cmSystemTools::Error(error); } else { std::string line; @@ -702,9 +697,7 @@ bool cmSystemTools::DoesFileExistWithExtensions( std::string hname; for (std::string const& headerExt : headerExts) { - hname = name; - hname += "."; - hname += headerExt; + hname = cmStrCat(name, '.', headerExt); if (cmSystemTools::FileExists(hname)) { return true; } @@ -998,9 +991,7 @@ void cmSystemTools::GlobDirs(const std::string& path, for (unsigned int i = 0; i < d.GetNumberOfFiles(); ++i) { if ((std::string(d.GetFile(i)) != ".") && (std::string(d.GetFile(i)) != "..")) { - std::string fname = startPath; - fname += "/"; - fname += d.GetFile(i); + std::string fname = cmStrCat(startPath, '/', d.GetFile(i)); if (cmSystemTools::FileIsDirectory(fname)) { fname += finishPath; cmSystemTools::GlobDirs(fname, files); @@ -1183,8 +1174,7 @@ std::string cmSystemTools::ForceToRelativePath(std::string const& local_path, bool cmSystemTools::UnsetEnv(const char* value) { # if !defined(HAVE_UNSETENV) - std::string var = value; - var += "="; + std::string var = cmStrCat(value, '='); return cmSystemTools::PutEnv(var.c_str()); # else unsetenv(value); @@ -1270,10 +1260,8 @@ bool cmSystemTools::CreateTar(const std::string& outFileName, std::string cwd = cmSystemTools::GetCurrentWorkingDirectory(); cmsys::ofstream fout(outFileName.c_str(), std::ios::out | std::ios::binary); if (!fout) { - std::string e = "Cannot open output file \""; - e += outFileName; - e += "\": "; - e += cmSystemTools::GetLastSystemError(); + std::string e = cmStrCat("Cannot open output file \"", outFileName, + "\": ", cmSystemTools::GetLastSystemError()); cmSystemTools::Error(e); return false; } @@ -1956,35 +1944,29 @@ void cmSystemTools::FindCMakeResources(const char* argv0) } #endif exe_dir = cmSystemTools::GetActualCaseForPath(exe_dir); - cmSystemToolsCMakeCommand = exe_dir; - cmSystemToolsCMakeCommand += "/cmake"; - cmSystemToolsCMakeCommand += cmSystemTools::GetExecutableExtension(); + cmSystemToolsCMakeCommand = + cmStrCat(exe_dir, "/cmake", cmSystemTools::GetExecutableExtension()); #ifdef CMAKE_BOOTSTRAP // The bootstrap cmake does not provide the other tools, // so use the directory where they are about to be built. exe_dir = CMAKE_BOOTSTRAP_BINARY_DIR "/bin"; #endif - cmSystemToolsCTestCommand = exe_dir; - cmSystemToolsCTestCommand += "/ctest"; - cmSystemToolsCTestCommand += cmSystemTools::GetExecutableExtension(); - cmSystemToolsCPackCommand = exe_dir; - cmSystemToolsCPackCommand += "/cpack"; - cmSystemToolsCPackCommand += cmSystemTools::GetExecutableExtension(); - cmSystemToolsCMakeGUICommand = exe_dir; - cmSystemToolsCMakeGUICommand += "/cmake-gui"; - cmSystemToolsCMakeGUICommand += cmSystemTools::GetExecutableExtension(); + cmSystemToolsCTestCommand = + cmStrCat(exe_dir, "/ctest", cmSystemTools::GetExecutableExtension()); + cmSystemToolsCPackCommand = + cmStrCat(exe_dir, "/cpack", cmSystemTools::GetExecutableExtension()); + cmSystemToolsCMakeGUICommand = + cmStrCat(exe_dir, "/cmake-gui", cmSystemTools::GetExecutableExtension()); if (!cmSystemTools::FileExists(cmSystemToolsCMakeGUICommand)) { cmSystemToolsCMakeGUICommand.clear(); } - cmSystemToolsCMakeCursesCommand = exe_dir; - cmSystemToolsCMakeCursesCommand += "/ccmake"; - cmSystemToolsCMakeCursesCommand += cmSystemTools::GetExecutableExtension(); + cmSystemToolsCMakeCursesCommand = + cmStrCat(exe_dir, "/ccmake", cmSystemTools::GetExecutableExtension()); if (!cmSystemTools::FileExists(cmSystemToolsCMakeCursesCommand)) { cmSystemToolsCMakeCursesCommand.clear(); } - cmSystemToolsCMClDepsCommand = exe_dir; - cmSystemToolsCMClDepsCommand += "/cmcldeps"; - cmSystemToolsCMClDepsCommand += cmSystemTools::GetExecutableExtension(); + cmSystemToolsCMClDepsCommand = + cmStrCat(exe_dir, "/cmcldeps", cmSystemTools::GetExecutableExtension()); if (!cmSystemTools::FileExists(cmSystemToolsCMClDepsCommand)) { cmSystemToolsCMClDepsCommand.clear(); } @@ -2222,8 +2204,9 @@ bool cmSystemTools::ChangeRPath(std::string const& file, return true; } if (emsg) { - *emsg = "No valid ELF RPATH or RUNPATH entry exists in the file; "; - *emsg += elf.GetErrorMessage(); + *emsg = + cmStrCat("No valid ELF RPATH or RUNPATH entry exists in the file; ", + elf.GetErrorMessage()); } return false; } @@ -2289,9 +2272,8 @@ bool cmSystemTools::ChangeRPath(std::string const& file, // least one null terminator. if (rp[rp_count].Size < rp[rp_count].Value.length() + 1) { if (emsg) { - *emsg = "The replacement path is too long for the "; - *emsg += se_name[i]; - *emsg += " entry."; + *emsg = cmStrCat("The replacement path is too long for the ", + se_name[i], " entry."); } return false; } @@ -2327,9 +2309,7 @@ bool cmSystemTools::ChangeRPath(std::string const& file, // Seek to the RPATH position. if (!f.seekp(rp[i].Position)) { if (emsg) { - *emsg = "Error seeking to "; - *emsg += rp[i].Name; - *emsg += " position."; + *emsg = cmStrCat("Error seeking to ", rp[i].Name, " position."); } return false; } @@ -2344,9 +2324,8 @@ bool cmSystemTools::ChangeRPath(std::string const& file, // Make sure it wrote correctly. if (!f) { if (emsg) { - *emsg = "Error writing the new "; - *emsg += rp[i].Name; - *emsg += " string to the file."; + *emsg = cmStrCat("Error writing the new ", rp[i].Name, + " string to the file."); } return false; } @@ -2375,7 +2354,8 @@ bool cmSystemTools::VersionCompare(cmSystemTools::CompareOp op, { const char* endl = lhss; const char* endr = rhss; - unsigned long lhs, rhs; + unsigned long lhs; + unsigned long rhs; while (((*endl >= '0') && (*endl <= '9')) || ((*endr >= '0') && (*endr <= '9'))) { diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 9b002ee..2a09b43 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -88,8 +88,7 @@ const char* cmTargetPropertyComputer::GetSources<cmTarget>( std::ostringstream ss; const char* sep = ""; for (std::string const& entry : entries) { - std::vector<std::string> files; - cmExpandList(entry, files); + std::vector<std::string> files = cmExpandedList(entry); for (std::string const& file : files) { if (cmHasLiteralPrefix(file, "$<TARGET_OBJECTS:") && file.back() == '>') { @@ -191,6 +190,8 @@ public: std::vector<cmListFileBacktrace> CompileFeaturesBacktraces; std::vector<std::string> CompileDefinitionsEntries; std::vector<cmListFileBacktrace> CompileDefinitionsBacktraces; + std::vector<std::string> PrecompileHeadersEntries; + std::vector<cmListFileBacktrace> PrecompileHeadersBacktraces; std::vector<std::string> SourceEntries; std::vector<cmListFileBacktrace> SourceBacktraces; std::vector<std::string> LinkOptionsEntries; @@ -347,8 +348,10 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, initProp("LINK_SEARCH_START_STATIC"); initProp("LINK_SEARCH_END_STATIC"); initProp("FOLDER"); + initProp("Swift_LANGUAGE_VERSION"); initProp("Swift_MODULE_DIRECTORY"); initProp("VS_JUST_MY_CODE_DEBUGGING"); + initProp("DISABLE_PRECOMPILE_HEADERS"); #ifdef __APPLE__ if (this->GetGlobalGenerator()->IsXcode()) { initProp("XCODE_GENERATE_SCHEME"); @@ -392,8 +395,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, strcmp(prop, "MAP_IMPORTED_CONFIG_") != 0) { continue; } - std::string property = prop; - property += configUpper; + std::string property = cmStrCat(prop, configUpper); initProp(property); } @@ -404,8 +406,8 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, // property directly. if (impl->TargetType != cmStateEnums::EXECUTABLE && impl->TargetType != cmStateEnums::INTERFACE_LIBRARY) { - std::string property = cmSystemTools::UpperCase(configName); - property += "_POSTFIX"; + std::string property = + cmStrCat(cmSystemTools::UpperCase(configName), "_POSTFIX"); initProp(property); } } @@ -500,8 +502,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, if (globals) { const std::string genName = mf->GetGlobalGenerator()->GetName(); if (cmHasLiteralPrefix(genName, "Visual Studio")) { - std::vector<std::string> props; - cmExpandList(globals, props); + std::vector<std::string> props = cmExpandedList(globals); const std::string vsGlobal = "VS_GLOBAL_"; for (const std::string& i : props) { // split NAME=VALUE @@ -743,8 +744,7 @@ public: bool operator()(std::string const& entry) { - std::vector<std::string> files; - cmExpandList(entry, files); + std::vector<std::string> files = cmExpandedList(entry); std::vector<cmSourceFileLocation> locations; locations.reserve(files.size()); std::transform(files.begin(), files.end(), std::back_inserter(locations), @@ -778,8 +778,7 @@ cmSourceFile* cmTarget::AddSource(const std::string& src, bool before) void cmTarget::ClearDependencyInformation(cmMakefile& mf) { - std::string depname = this->GetName(); - depname += "_LIB_DEPENDS"; + std::string depname = cmStrCat(this->GetName(), "_LIB_DEPENDS"); mf.RemoveCacheDefinition(depname); } @@ -947,8 +946,7 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf, std::string const& lib, impl->TargetType <= cmStateEnums::MODULE_LIBRARY && (this->GetPolicyStatusCMP0073() == cmPolicies::OLD || this->GetPolicyStatusCMP0073() == cmPolicies::WARN)) { - std::string targetEntry = impl->Name; - targetEntry += "_LIB_DEPENDS"; + std::string targetEntry = cmStrCat(impl->Name, "_LIB_DEPENDS"); std::string dependencies; const char* old_val = mf.GetDefinition(targetEntry); if (old_val) { @@ -1023,6 +1021,16 @@ cmBacktraceRange cmTarget::GetCompileDefinitionsBacktraces() const return cmMakeRange(impl->CompileDefinitionsBacktraces); } +cmStringRange cmTarget::GetPrecompileHeadersEntries() const +{ + return cmMakeRange(impl->PrecompileHeadersEntries); +} + +cmBacktraceRange cmTarget::GetPrecompileHeadersBacktraces() const +{ + return cmMakeRange(impl->PrecompileHeadersBacktraces); +} + cmStringRange cmTarget::GetSourceEntries() const { return cmMakeRange(impl->SourceEntries); @@ -1074,6 +1082,7 @@ void cmTarget::SetProperty(const std::string& prop, const char* value) MAKE_STATIC_PROP(COMPILE_DEFINITIONS); MAKE_STATIC_PROP(COMPILE_FEATURES); MAKE_STATIC_PROP(COMPILE_OPTIONS); + MAKE_STATIC_PROP(PRECOMPILE_HEADERS); MAKE_STATIC_PROP(CUDA_PTX_COMPILATION); MAKE_STATIC_PROP(EXPORT_NAME); MAKE_STATIC_PROP(IMPORTED_GLOBAL); @@ -1087,21 +1096,19 @@ void cmTarget::SetProperty(const std::string& prop, const char* value) MAKE_STATIC_PROP(TYPE); #undef MAKE_STATIC_PROP if (prop == propMANUALLY_ADDED_DEPENDENCIES) { - std::ostringstream e; - e << "MANUALLY_ADDED_DEPENDENCIES property is read-only\n"; - impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + impl->Makefile->IssueMessage( + MessageType::FATAL_ERROR, + "MANUALLY_ADDED_DEPENDENCIES property is read-only\n"); return; } if (prop == propNAME) { - std::ostringstream e; - e << "NAME property is read-only\n"; - impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, + "NAME property is read-only\n"); return; } if (prop == propTYPE) { - std::ostringstream e; - e << "TYPE property is read-only\n"; - impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, + "TYPE property is read-only\n"); return; } if (prop == propEXPORT_NAME && this->IsImported()) { @@ -1174,6 +1181,14 @@ void cmTarget::SetProperty(const std::string& prop, const char* value) cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace(); impl->LinkDirectoriesBacktraces.push_back(lfbt); } + } else if (prop == propPRECOMPILE_HEADERS) { + impl->PrecompileHeadersEntries.clear(); + impl->PrecompileHeadersBacktraces.clear(); + if (value) { + impl->PrecompileHeadersEntries.emplace_back(value); + cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace(); + impl->PrecompileHeadersBacktraces.push_back(lfbt); + } } else if (prop == propLINK_LIBRARIES) { impl->LinkImplementationPropertyEntries.clear(); impl->LinkImplementationPropertyBacktraces.clear(); @@ -1228,9 +1243,8 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value, return; } if (prop == "NAME") { - std::ostringstream e; - e << "NAME property is read-only\n"; - impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, + "NAME property is read-only\n"); return; } if (prop == "EXPORT_NAME" && this->IsImported()) { @@ -1291,6 +1305,12 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value, cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace(); impl->LinkDirectoriesBacktraces.push_back(lfbt); } + } else if (prop == "PRECOMPILE_HEADERS") { + if (value && *value) { + impl->PrecompileHeadersEntries.emplace_back(value); + cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace(); + impl->PrecompileHeadersBacktraces.push_back(lfbt); + } } else if (prop == "LINK_LIBRARIES") { if (value && *value) { cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace(); @@ -1402,6 +1422,13 @@ void cmTarget::InsertLinkDirectory(std::string const& entry, impl->LinkDirectoriesBacktraces.insert(btPosition, bt); } +void cmTarget::InsertPrecompileHeader(std::string const& entry, + cmListFileBacktrace const& bt) +{ + impl->PrecompileHeadersEntries.push_back(entry); + impl->PrecompileHeadersBacktraces.push_back(bt); +} + static void cmTargetCheckLINK_INTERFACE_LIBRARIES(const std::string& prop, const char* value, cmMakefile* context, @@ -1522,6 +1549,7 @@ const char* cmTarget::GetProperty(const std::string& prop) const MAKE_STATIC_PROP(COMPILE_DEFINITIONS); MAKE_STATIC_PROP(LINK_OPTIONS); MAKE_STATIC_PROP(LINK_DIRECTORIES); + MAKE_STATIC_PROP(PRECOMPILE_HEADERS); MAKE_STATIC_PROP(IMPORTED); MAKE_STATIC_PROP(IMPORTED_GLOBAL); MAKE_STATIC_PROP(MANUALLY_ADDED_DEPENDENCIES); @@ -1537,6 +1565,7 @@ const char* cmTarget::GetProperty(const std::string& prop) const propCOMPILE_FEATURES, propCOMPILE_OPTIONS, propCOMPILE_DEFINITIONS, + propPRECOMPILE_HEADERS, propLINK_OPTIONS, propLINK_DIRECTORIES, propIMPORTED, @@ -1625,6 +1654,15 @@ const char* cmTarget::GetProperty(const std::string& prop) const output = cmJoin(impl->Utilities, ";"); return output.c_str(); } + if (prop == propPRECOMPILE_HEADERS) { + if (impl->PrecompileHeadersEntries.empty()) { + return nullptr; + } + + static std::string output; + output = cmJoin(impl->PrecompileHeadersEntries, ";"); + return output.c_str(); + } if (prop == propIMPORTED) { return this->IsImported() ? "TRUE" : "FALSE"; } @@ -1806,8 +1844,7 @@ std::string cmTarget::ImportedGetFullPath( if (loc) { result = loc; } else { - std::string impProp = "IMPORTED_LOCATION"; - impProp += suffix; + std::string impProp = cmStrCat("IMPORTED_LOCATION", suffix); if (const char* config_location = this->GetProperty(impProp)) { result = config_location; } else if (const char* location = @@ -1822,8 +1859,7 @@ std::string cmTarget::ImportedGetFullPath( result = imp; } else if (this->GetType() == cmStateEnums::SHARED_LIBRARY || this->IsExecutableWithExports()) { - std::string impProp = "IMPORTED_IMPLIB"; - impProp += suffix; + std::string impProp = cmStrCat("IMPORTED_IMPLIB", suffix); if (const char* config_implib = this->GetProperty(impProp)) { result = config_implib; } else if (const char* implib = @@ -1836,8 +1872,7 @@ std::string cmTarget::ImportedGetFullPath( } if (result.empty()) { - result = this->GetName(); - result += "-NOTFOUND"; + result = cmStrCat(this->GetName(), "-NOTFOUND"); } return result; } @@ -1891,13 +1926,11 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config, } // Track the configuration-specific property suffix. - suffix = "_"; - suffix += config_upper; + suffix = cmStrCat('_', config_upper); std::vector<std::string> mappedConfigs; { - std::string mapProp = "MAP_IMPORTED_CONFIG_"; - mapProp += config_upper; + std::string mapProp = cmStrCat("MAP_IMPORTED_CONFIG_", config_upper); if (const char* mapValue = this->GetProperty(mapProp)) { cmExpandList(mapValue, mappedConfigs, true); } @@ -1928,19 +1961,16 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config, } } else { std::string mcUpper = cmSystemTools::UpperCase(*mci); - std::string locProp = locPropBase + "_"; - locProp += mcUpper; + std::string locProp = cmStrCat(locPropBase, '_', mcUpper); *loc = this->GetProperty(locProp); if (allowImp) { - std::string impProp = "IMPORTED_IMPLIB_"; - impProp += mcUpper; + std::string impProp = cmStrCat("IMPORTED_IMPLIB_", mcUpper); *imp = this->GetProperty(impProp); } // If it was found, use it for all properties below. if (*loc || *imp) { - suffix = "_"; - suffix += mcUpper; + suffix = cmStrCat('_', mcUpper); } } } @@ -1957,12 +1987,10 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config, // If we have not yet found it then there are no mapped // configurations. Look for an exact-match. if (!*loc && !*imp) { - std::string locProp = locPropBase; - locProp += suffix; + std::string locProp = cmStrCat(locPropBase, suffix); *loc = this->GetProperty(locProp); if (allowImp) { - std::string impProp = "IMPORTED_IMPLIB"; - impProp += suffix; + std::string impProp = cmStrCat("IMPORTED_IMPLIB", suffix); *imp = this->GetProperty(impProp); } } @@ -1991,14 +2019,11 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config, for (std::vector<std::string>::const_iterator aci = availableConfigs.begin(); !*loc && !*imp && aci != availableConfigs.end(); ++aci) { - suffix = "_"; - suffix += cmSystemTools::UpperCase(*aci); - std::string locProp = locPropBase; - locProp += suffix; + suffix = cmStrCat('_', cmSystemTools::UpperCase(*aci)); + std::string locProp = cmStrCat(locPropBase, suffix); *loc = this->GetProperty(locProp); if (allowImp) { - std::string impProp = "IMPORTED_IMPLIB"; - impProp += suffix; + std::string impProp = cmStrCat("IMPORTED_IMPLIB", suffix); *imp = this->GetProperty(impProp); } } diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 2b75879..783c278 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -216,6 +216,8 @@ public: cmListFileBacktrace const& bt, bool before = false); void InsertLinkDirectory(std::string const& entry, cmListFileBacktrace const& bt, bool before = false); + void InsertPrecompileHeader(std::string const& entry, + cmListFileBacktrace const& bt); void AppendBuildInterfaceIncludes(); @@ -237,6 +239,9 @@ public: cmStringRange GetCompileDefinitionsEntries() const; cmBacktraceRange GetCompileDefinitionsBacktraces() const; + cmStringRange GetPrecompileHeadersEntries() const; + cmBacktraceRange GetPrecompileHeadersBacktraces() const; + cmStringRange GetSourceEntries() const; cmBacktraceRange GetSourceBacktraces() const; diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx index 3883b52..4fbec90 100644 --- a/Source/cmTargetLinkLibrariesCommand.cxx +++ b/Source/cmTargetLinkLibrariesCommand.cxx @@ -12,6 +12,7 @@ #include "cmPolicies.h" #include "cmState.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" #include "cmake.h" @@ -237,8 +238,7 @@ bool cmTargetLinkLibrariesCommand::InitialPass( // only there for backwards compatibility when mixing projects built // with old versions of CMake and new) llt = GENERAL_LibraryType; - std::string linkType = args[0]; - linkType += "_LINK_TYPE"; + std::string linkType = cmStrCat(args[0], "_LINK_TYPE"); const char* linkTypeString = this->Makefile->GetDefinition(linkType); if (linkTypeString) { if (strcmp(linkTypeString, "debug") == 0) { @@ -502,8 +502,7 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib, if (llt == DEBUG_LibraryType || llt == GENERAL_LibraryType) { // Put in the DEBUG configuration interfaces. for (std::string const& dc : debugConfigs) { - prop = "LINK_INTERFACE_LIBRARIES_"; - prop += dc; + prop = cmStrCat("LINK_INTERFACE_LIBRARIES_", dc); this->Target->AppendProperty(prop, libRef.c_str()); } } @@ -514,8 +513,7 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib, // Make sure the DEBUG configuration interfaces exist so that the // general one will not be used as a fall-back. for (std::string const& dc : debugConfigs) { - prop = "LINK_INTERFACE_LIBRARIES_"; - prop += dc; + prop = cmStrCat("LINK_INTERFACE_LIBRARIES_", dc); if (!this->Target->GetProperty(prop)) { this->Target->SetProperty(prop, ""); } diff --git a/Source/cmTargetPrecompileHeadersCommand.cxx b/Source/cmTargetPrecompileHeadersCommand.cxx new file mode 100644 index 0000000..30cf1be --- /dev/null +++ b/Source/cmTargetPrecompileHeadersCommand.cxx @@ -0,0 +1,36 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmTargetPrecompileHeadersCommand.h" + +#include "cmMakefile.h" +#include "cmMessageType.h" +#include "cmStringAlgorithms.h" +#include "cmTarget.h" + +bool cmTargetPrecompileHeadersCommand::InitialPass( + std::vector<std::string> const& args, cmExecutionStatus&) +{ + return this->HandleArguments(args, "PRECOMPILE_HEADERS"); +} + +void cmTargetPrecompileHeadersCommand::HandleMissingTarget( + const std::string& name) +{ + const std::string e = + cmStrCat("Cannot specify precompile headers for target \"", name, + "\" which is not built by this project."); + this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e); +} + +std::string cmTargetPrecompileHeadersCommand::Join( + const std::vector<std::string>& content) +{ + return cmJoin(content, ";"); +} + +bool cmTargetPrecompileHeadersCommand::HandleDirectContent( + cmTarget* tgt, const std::vector<std::string>& content, bool, bool) +{ + tgt->AppendProperty("PRECOMPILE_HEADERS", this->Join(content).c_str()); + return true; +} diff --git a/Source/cmTargetPrecompileHeadersCommand.h b/Source/cmTargetPrecompileHeadersCommand.h new file mode 100644 index 0000000..1ddf2af --- /dev/null +++ b/Source/cmTargetPrecompileHeadersCommand.h @@ -0,0 +1,41 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#ifndef cmTargetPrecompileHeadersCommand_h +#define cmTargetPrecompileHeadersCommand_h + +#include "cmConfigure.h" // IWYU pragma: keep + +#include <string> +#include <vector> + +#include "cm_memory.hxx" + +#include "cmCommand.h" + +#include "cmTargetPropCommandBase.h" + +class cmExecutionStatus; +class cmTarget; + +class cmTargetPrecompileHeadersCommand : public cmTargetPropCommandBase +{ +public: + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmTargetPrecompileHeadersCommand>(); + } + + bool InitialPass(std::vector<std::string> const& args, + cmExecutionStatus& status) override; + +private: + void HandleMissingTarget(const std::string& name) override; + + bool HandleDirectContent(cmTarget* tgt, + const std::vector<std::string>& content, + bool prepend, bool system) override; + + std::string Join(const std::vector<std::string>& content) override; +}; + +#endif diff --git a/Source/cmTargetSourcesCommand.cxx b/Source/cmTargetSourcesCommand.cxx index eb5f37c..2251a65 100644 --- a/Source/cmTargetSourcesCommand.cxx +++ b/Source/cmTargetSourcesCommand.cxx @@ -75,9 +75,8 @@ std::vector<std::string> cmTargetSourcesCommand::ConvertToAbsoluteContent( absoluteSrc = src; } else { changedPath = true; - absoluteSrc = this->Makefile->GetCurrentSourceDirectory(); - absoluteSrc += "/"; - absoluteSrc += src; + absoluteSrc = + cmStrCat(this->Makefile->GetCurrentSourceDirectory(), '/', src); } absoluteContent.push_back(absoluteSrc); } diff --git a/Source/cmTestGenerator.cxx b/Source/cmTestGenerator.cxx index 75cb413..333d4d5 100644 --- a/Source/cmTestGenerator.cxx +++ b/Source/cmTestGenerator.cxx @@ -102,8 +102,7 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os, // Prepend with the emulator when cross compiling if required. const char* emulator = target->GetProperty("CROSSCOMPILING_EMULATOR"); if (emulator != nullptr && *emulator) { - std::vector<std::string> emulatorWithArgs; - cmExpandList(emulator, emulatorWithArgs); + std::vector<std::string> emulatorWithArgs = cmExpandedList(emulator); std::string emulatorExe(emulatorWithArgs[0]); cmSystemTools::ConvertToUnixSlashes(emulatorExe); os << cmOutputConverter::EscapeForCMake(emulatorExe) << " "; diff --git a/Source/cmTimestamp.cxx b/Source/cmTimestamp.cxx index 0915986..a9be729 100644 --- a/Source/cmTimestamp.cxx +++ b/Source/cmTimestamp.cxx @@ -6,6 +6,7 @@ #include <sstream> #include <stdlib.h> +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" std::string cmTimestamp::CurrentTime(const std::string& formatString, @@ -131,8 +132,7 @@ std::string cmTimestamp::AddTimestampComponent(char flag, struct tm& timeStruct, const time_t timeT) const { - std::string formatString = "%"; - formatString += flag; + std::string formatString = cmStrCat('%', flag); switch (flag) { case 'a': @@ -168,9 +168,7 @@ std::string cmTimestamp::AddTimestampComponent(char flag, return std::string(); } - std::ostringstream ss; - ss << static_cast<long int>(difftime(timeT, unixEpoch)); - return ss.str(); + return std::to_string(static_cast<long int>(difftime(timeT, unixEpoch))); } default: { return formatString; diff --git a/Source/cmTryRunCommand.cxx b/Source/cmTryRunCommand.cxx index 0847b9b..24d0f0f 100644 --- a/Source/cmTryRunCommand.cxx +++ b/Source/cmTryRunCommand.cxx @@ -170,8 +170,7 @@ void cmTryRunCommand::RunExecutable(const std::string& runArgs, const std::string& emulator = this->Makefile->GetSafeDefinition("CMAKE_CROSSCOMPILING_EMULATOR"); if (!emulator.empty()) { - std::vector<std::string> emulatorWithArgs; - cmExpandList(emulator, emulatorWithArgs); + std::vector<std::string> emulatorWithArgs = cmExpandedList(emulator); finalCommand += cmSystemTools::ConvertToRunCommandPath(emulatorWithArgs[0]); finalCommand += " "; @@ -214,19 +213,17 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs, // copy the executable out of the CMakeFiles/ directory, so it is not // removed at the end of TRY_RUN and the user can run it manually // on the target platform. - std::string copyDest = this->Makefile->GetHomeOutputDirectory(); - copyDest += "/CMakeFiles/"; - copyDest += cmSystemTools::GetFilenameWithoutExtension(this->OutputFile); - copyDest += "-"; - copyDest += this->RunResultVariable; - copyDest += cmSystemTools::GetFilenameExtension(this->OutputFile); + std::string copyDest = + cmStrCat(this->Makefile->GetHomeOutputDirectory(), "/CMakeFiles/", + cmSystemTools::GetFilenameWithoutExtension(this->OutputFile), '-', + this->RunResultVariable, + cmSystemTools::GetFilenameExtension(this->OutputFile)); cmSystemTools::CopyFileAlways(this->OutputFile, copyDest); - std::string resultFileName = this->Makefile->GetHomeOutputDirectory(); - resultFileName += "/TryRunResults.cmake"; + std::string resultFileName = + cmStrCat(this->Makefile->GetHomeOutputDirectory(), "/TryRunResults.cmake"); - std::string detailsString = "For details see "; - detailsString += resultFileName; + std::string detailsString = cmStrCat("For details see ", resultFileName); std::string internalRunOutputName = this->RunResultVariable + "__TRYRUN_OUTPUT"; @@ -235,10 +232,10 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs, if (!this->Makefile->GetDefinition(this->RunResultVariable)) { // if the variables doesn't exist, create it with a helpful error text // and mark it as advanced - std::string comment; - comment += "Run result of TRY_RUN(), indicates whether the executable " - "would have been able to run on its target platform.\n"; - comment += detailsString; + std::string comment = + cmStrCat("Run result of TRY_RUN(), indicates whether the executable " + "would have been able to run on its target platform.\n", + detailsString); this->Makefile->AddCacheDefinition(this->RunResultVariable, "PLEASE_FILL_OUT-FAILED_TO_RUN", comment.c_str(), cmStateEnums::STRING); @@ -258,11 +255,10 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs, if (!this->Makefile->GetDefinition(internalRunOutputName)) { // if the variables doesn't exist, create it with a helpful error text // and mark it as advanced - std::string comment; - comment += + std::string comment = cmStrCat( "Output of TRY_RUN(), contains the text, which the executable " - "would have printed on stdout and stderr on its target platform.\n"; - comment += detailsString; + "would have printed on stdout and stderr on its target platform.\n", + detailsString); this->Makefile->AddCacheDefinition( internalRunOutputName, "PLEASE_FILL_OUT-NOTFOUND", comment.c_str(), @@ -294,15 +290,15 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs, /* clang-format on */ } - std::string comment = "\n"; - comment += this->RunResultVariable; - comment += "\n indicates whether the executable would have been able " + std::string comment = + cmStrCat('\n', this->RunResultVariable, + "\n indicates whether the executable would have been able " "to run on its\n" - " target platform. If so, set "; - comment += this->RunResultVariable; - comment += " to\n" + " target platform. If so, set ", + this->RunResultVariable, + " to\n" " the exit code (in many cases 0 for success), otherwise " - "enter \"FAILED_TO_RUN\".\n"; + "enter \"FAILED_TO_RUN\".\n"); if (out) { comment += internalRunOutputName; comment += @@ -343,10 +339,11 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs, } firstTryRun = false; - std::string errorMessage = "TRY_RUN() invoked in cross-compiling mode, " - "please set the following cache variables " - "appropriately:\n"; - errorMessage += " " + this->RunResultVariable + " (advanced)\n"; + std::string errorMessage = + cmStrCat("TRY_RUN() invoked in cross-compiling mode, " + "please set the following cache variables " + "appropriately:\n ", + this->RunResultVariable, " (advanced)\n"); if (out) { errorMessage += " " + internalRunOutputName + " (advanced)\n"; } diff --git a/Source/cmUnsetCommand.cxx b/Source/cmUnsetCommand.cxx index 3eb293a..3ba95e9 100644 --- a/Source/cmUnsetCommand.cxx +++ b/Source/cmUnsetCommand.cxx @@ -2,18 +2,17 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmUnsetCommand.h" +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" -class cmExecutionStatus; - // cmUnsetCommand -bool cmUnsetCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmUnsetCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.empty() || args.size() > 2) { - this->SetError("called with incorrect number of arguments"); + status.SetError("called with incorrect number of arguments"); return false; } @@ -31,20 +30,20 @@ bool cmUnsetCommand::InitialPass(std::vector<std::string> const& args, } // unset(VAR) if (args.size() == 1) { - this->Makefile->RemoveDefinition(variable); + status.GetMakefile().RemoveDefinition(variable); return true; } // unset(VAR CACHE) if ((args.size() == 2) && (args[1] == "CACHE")) { - this->Makefile->RemoveCacheDefinition(variable); + status.GetMakefile().RemoveCacheDefinition(variable); return true; } // unset(VAR PARENT_SCOPE) if ((args.size() == 2) && (args[1] == "PARENT_SCOPE")) { - this->Makefile->RaiseScope(variable, nullptr); + status.GetMakefile().RaiseScope(variable, nullptr); return true; } // ERROR: second argument isn't CACHE or PARENT_SCOPE - this->SetError("called with an invalid second argument"); + status.SetError("called with an invalid second argument"); return false; } diff --git a/Source/cmUnsetCommand.h b/Source/cmUnsetCommand.h index 9b78d44..be4c166 100644 --- a/Source/cmUnsetCommand.h +++ b/Source/cmUnsetCommand.h @@ -8,34 +8,14 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmUnsetCommand +/** * \brief Unset a CMAKE variable * * cmUnsetCommand unsets or removes a variable. */ -class cmUnsetCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmUnsetCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; +bool cmUnsetCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmUseMangledMesaCommand.cxx b/Source/cmUseMangledMesaCommand.cxx index 4358194..cfc00e8 100644 --- a/Source/cmUseMangledMesaCommand.cxx +++ b/Source/cmUseMangledMesaCommand.cxx @@ -5,29 +5,30 @@ #include "cmsys/FStream.hxx" #include "cmsys/RegularExpression.hxx" +#include "cmExecutionStatus.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" -class cmExecutionStatus; +namespace { +void CopyAndFullPathMesaHeader(const std::string& source, + const std::string& outdir); +} -bool cmUseMangledMesaCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmUseMangledMesaCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { // expected two arguments: // argument one: the full path to gl_mangle.h // argument two : directory for output of edited headers if (args.size() != 2) { - this->SetError("called with incorrect number of arguments"); + status.SetError("called with incorrect number of arguments"); return false; } const std::string& inputDir = args[0]; - std::string glh = inputDir; - glh += "/"; - glh += "gl.h"; + std::string glh = cmStrCat(inputDir, "/gl.h"); if (!cmSystemTools::FileExists(glh)) { - std::string e = "Bad path to Mesa, could not find: "; - e += glh; - e += " "; - this->SetError(e); + std::string e = cmStrCat("Bad path to Mesa, could not find: ", glh, ' '); + status.SetError(e); return false; } const std::string& destDir = args[1]; @@ -39,25 +40,22 @@ bool cmUseMangledMesaCommand::InitialPass(std::vector<std::string> const& args, } cmSystemTools::MakeDirectory(destDir); for (std::string const& f : files) { - std::string path = inputDir; - path += "/"; - path += f; - this->CopyAndFullPathMesaHeader(path, destDir); + std::string path = cmStrCat(inputDir, '/', f); + CopyAndFullPathMesaHeader(path, destDir); } return true; } -void cmUseMangledMesaCommand::CopyAndFullPathMesaHeader( - const std::string& source, const std::string& outdir) +namespace { +void CopyAndFullPathMesaHeader(const std::string& source, + const std::string& outdir) { - std::string dir, file; + std::string dir; + std::string file; cmSystemTools::SplitProgramPath(source, dir, file); - std::string outFile = outdir; - outFile += "/"; - outFile += file; - std::string tempOutputFile = outFile; - tempOutputFile += ".tmp"; + std::string outFile = cmStrCat(outdir, '/', file); + std::string tempOutputFile = cmStrCat(outFile, ".tmp"); cmsys::ofstream fout(tempOutputFile.c_str()); if (!fout) { cmSystemTools::Error("Could not open file for write in copy operation: " + @@ -103,3 +101,4 @@ void cmUseMangledMesaCommand::CopyAndFullPathMesaHeader( cmSystemTools::CopyFileIfDifferent(tempOutputFile, outFile); cmSystemTools::RemoveFile(tempOutputFile); } +} diff --git a/Source/cmUseMangledMesaCommand.h b/Source/cmUseMangledMesaCommand.h index 1c01596..215e4a3 100644 --- a/Source/cmUseMangledMesaCommand.h +++ b/Source/cmUseMangledMesaCommand.h @@ -8,25 +8,9 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -class cmUseMangledMesaCommand : public cmCommand -{ -public: - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmUseMangledMesaCommand>(); - } - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; - -protected: - void CopyAndFullPathMesaHeader(const std::string& source, - const std::string& outdir); -}; +bool cmUseMangledMesaCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmUtilitySourceCommand.cxx b/Source/cmUtilitySourceCommand.cxx index b59a587..25fe4ad 100644 --- a/Source/cmUtilitySourceCommand.cxx +++ b/Source/cmUtilitySourceCommand.cxx @@ -4,19 +4,19 @@ #include <string.h> +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmState.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" -class cmExecutionStatus; - // cmUtilitySourceCommand -bool cmUtilitySourceCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmUtilitySourceCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() < 3) { - this->SetError("called with incorrect number of arguments"); + status.SetError("called with incorrect number of arguments"); return false; } @@ -24,26 +24,26 @@ bool cmUtilitySourceCommand::InitialPass(std::vector<std::string> const& args, // The first argument is the cache entry name. std::string const& cacheEntry = *arg++; - const char* cacheValue = this->Makefile->GetDefinition(cacheEntry); + const char* cacheValue = status.GetMakefile().GetDefinition(cacheEntry); // If it exists already and appears up to date then we are done. If // the string contains "(IntDir)" but that is not the // CMAKE_CFG_INTDIR setting then the value is out of date. std::string const& intDir = - this->Makefile->GetRequiredDefinition("CMAKE_CFG_INTDIR"); + status.GetMakefile().GetRequiredDefinition("CMAKE_CFG_INTDIR"); bool haveCacheValue = false; - if (this->Makefile->IsOn("CMAKE_CROSSCOMPILING")) { + if (status.GetMakefile().IsOn("CMAKE_CROSSCOMPILING")) { haveCacheValue = (cacheValue != nullptr); if (!haveCacheValue) { - std::string msg = "UTILITY_SOURCE is used in cross compiling mode for "; - msg += cacheEntry; - msg += ". If your intention is to run this executable, you need to " - "preload the cache with the full path to a version of that " - "program, which runs on this build machine."; + std::string msg = cmStrCat( + "UTILITY_SOURCE is used in cross compiling mode for ", cacheEntry, + ". If your intention is to run this executable, you need to " + "preload the cache with the full path to a version of that " + "program, which runs on this build machine."); cmSystemTools::Message(msg, "Warning"); } } else { - cmState* state = this->Makefile->GetState(); + cmState* state = status.GetMakefile().GetState(); haveCacheValue = (cacheValue && (strstr(cacheValue, "(IntDir)") == nullptr || (intDir == "$(IntDir)")) && @@ -62,7 +62,7 @@ bool cmUtilitySourceCommand::InitialPass(std::vector<std::string> const& args, // The third argument specifies the relative directory of the source // of the utility. std::string const& relativeSource = *arg++; - std::string utilitySource = this->Makefile->GetCurrentSourceDirectory(); + std::string utilitySource = status.GetMakefile().GetCurrentSourceDirectory(); utilitySource = utilitySource + "/" + relativeSource; // If the directory doesn't exist, the source has not been included. @@ -80,11 +80,12 @@ bool cmUtilitySourceCommand::InitialPass(std::vector<std::string> const& args, // The source exists. const std::string& cmakeCFGout = - this->Makefile->GetRequiredDefinition("CMAKE_CFG_INTDIR"); - std::string utilityDirectory = this->Makefile->GetCurrentBinaryDirectory(); + status.GetMakefile().GetRequiredDefinition("CMAKE_CFG_INTDIR"); + std::string utilityDirectory = + status.GetMakefile().GetCurrentBinaryDirectory(); std::string exePath; - if (this->Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH")) { - exePath = this->Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH"); + if (status.GetMakefile().GetDefinition("EXECUTABLE_OUTPUT_PATH")) { + exePath = status.GetMakefile().GetDefinition("EXECUTABLE_OUTPUT_PATH"); } if (!exePath.empty()) { utilityDirectory = exePath; @@ -94,21 +95,22 @@ bool cmUtilitySourceCommand::InitialPass(std::vector<std::string> const& args, // Construct the cache entry for the executable's location. std::string utilityExecutable = utilityDirectory + "/" + cmakeCFGout + "/" + - utilityName + this->Makefile->GetDefinition("CMAKE_EXECUTABLE_SUFFIX"); + utilityName + + status.GetMakefile().GetDefinition("CMAKE_EXECUTABLE_SUFFIX"); // make sure we remove any /./ in the name cmSystemTools::ReplaceString(utilityExecutable, "/./", "/"); // Enter the value into the cache. - this->Makefile->AddCacheDefinition(cacheEntry, utilityExecutable.c_str(), - "Path to an internal program.", - cmStateEnums::FILEPATH); + status.GetMakefile().AddCacheDefinition( + cacheEntry, utilityExecutable.c_str(), "Path to an internal program.", + cmStateEnums::FILEPATH); // add a value into the cache that maps from the // full path to the name of the project cmSystemTools::ConvertToUnixSlashes(utilityExecutable); - this->Makefile->AddCacheDefinition(utilityExecutable, utilityName.c_str(), - "Executable to project name.", - cmStateEnums::INTERNAL); + status.GetMakefile().AddCacheDefinition( + utilityExecutable, utilityName.c_str(), "Executable to project name.", + cmStateEnums::INTERNAL); return true; } diff --git a/Source/cmUtilitySourceCommand.h b/Source/cmUtilitySourceCommand.h index cef7fed..934d539 100644 --- a/Source/cmUtilitySourceCommand.h +++ b/Source/cmUtilitySourceCommand.h @@ -8,21 +8,9 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -class cmUtilitySourceCommand : public cmCommand -{ -public: - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmUtilitySourceCommand>(); - } - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; +bool cmUtilitySourceCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmVSSetupHelper.cxx b/Source/cmVSSetupHelper.cxx index 20f5e2f..707ceac 100644 --- a/Source/cmVSSetupHelper.cxx +++ b/Source/cmVSSetupHelper.cxx @@ -365,8 +365,8 @@ bool cmVSSetupAPIHelper::EnumerateAndChooseVSInstance() // We are not looking for a specific instance. // If we've been given a hint then use it. if (!envVSCommonToolsDir.empty()) { - std::string currentVSLocation = instanceInfo.GetInstallLocation(); - currentVSLocation += "/Common7/Tools"; + std::string currentVSLocation = + cmStrCat(instanceInfo.GetInstallLocation(), "/Common7/Tools"); if (cmSystemTools::ComparePath(currentVSLocation, envVSCommonToolsDir)) { chosenInstanceInfo = instanceInfo; diff --git a/Source/cmVSSetupHelper.h b/Source/cmVSSetupHelper.h index 1bda54a..ad46c75 100644 --- a/Source/cmVSSetupHelper.h +++ b/Source/cmVSSetupHelper.h @@ -74,26 +74,8 @@ class SmartBSTR { public: SmartBSTR() { str = NULL; } - SmartBSTR(const SmartBSTR& src) - { - if (src.str != NULL) { - str = ::SysAllocStringByteLen((char*)str, ::SysStringByteLen(str)); - } else { - str = ::SysAllocStringByteLen(NULL, 0); - } - } - SmartBSTR& operator=(const SmartBSTR& src) - { - if (str != src.str) { - ::SysFreeString(str); - if (src.str != NULL) { - str = ::SysAllocStringByteLen((char*)str, ::SysStringByteLen(str)); - } else { - str = ::SysAllocStringByteLen(NULL, 0); - } - } - return *this; - } + SmartBSTR(const SmartBSTR& src) = delete; + SmartBSTR& operator=(const SmartBSTR& src) = delete; operator BSTR() const { return str; } BSTR* operator&() throw() { return &str; } ~SmartBSTR() throw() { ::SysFreeString(str); } diff --git a/Source/cmVariableRequiresCommand.cxx b/Source/cmVariableRequiresCommand.cxx index 9878ff1..6b93c63 100644 --- a/Source/cmVariableRequiresCommand.cxx +++ b/Source/cmVariableRequiresCommand.cxx @@ -2,32 +2,32 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmVariableRequiresCommand.h" +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmState.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" -class cmExecutionStatus; - // cmLibraryCommand -bool cmVariableRequiresCommand::InitialPass( - std::vector<std::string> const& args, cmExecutionStatus&) +bool cmVariableRequiresCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() < 3) { - this->SetError("called with incorrect number of arguments"); + status.SetError("called with incorrect number of arguments"); return false; } std::string const& testVariable = args[0]; - if (!this->Makefile->IsOn(testVariable)) { + if (!status.GetMakefile().IsOn(testVariable)) { return true; } std::string const& resultVariable = args[1]; bool requirementsMet = true; std::string notSet; bool hasAdvanced = false; - cmState* state = this->Makefile->GetState(); + cmState* state = status.GetMakefile().GetState(); for (unsigned int i = 2; i < args.size(); ++i) { - if (!this->Makefile->IsOn(args[i])) { + if (!status.GetMakefile().IsOn(args[i])) { requirementsMet = false; notSet += args[i]; notSet += "\n"; @@ -37,21 +37,20 @@ bool cmVariableRequiresCommand::InitialPass( } } } - const char* reqVar = this->Makefile->GetDefinition(resultVariable); + const char* reqVar = status.GetMakefile().GetDefinition(resultVariable); // if reqVar is unset, then set it to requirementsMet // if reqVar is set to true, but requirementsMet is false , then // set reqVar to false. - if (!reqVar || (!requirementsMet && this->Makefile->IsOn(reqVar))) { - this->Makefile->AddDefinitionBool(resultVariable, requirementsMet); + if (!reqVar || (!requirementsMet && status.GetMakefile().IsOn(reqVar))) { + status.GetMakefile().AddDefinitionBool(resultVariable, requirementsMet); } if (!requirementsMet) { - std::string message = "Variable assertion failed:\n"; - message += - testVariable + " Requires that the following unset variables are set:\n"; - message += notSet; - message += "\nPlease set them, or set "; - message += testVariable + " to false, and re-configure.\n"; + std::string message = + cmStrCat("Variable assertion failed:\n", testVariable, + " Requires that the following unset variables are set:\n", + notSet, "\nPlease set them, or set ", testVariable, + " to false, and re-configure.\n"); if (hasAdvanced) { message += "One or more of the required variables is advanced." diff --git a/Source/cmVariableRequiresCommand.h b/Source/cmVariableRequiresCommand.h index 38e7490..fb0520e 100644 --- a/Source/cmVariableRequiresCommand.h +++ b/Source/cmVariableRequiresCommand.h @@ -8,21 +8,9 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -class cmVariableRequiresCommand : public cmCommand -{ -public: - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmVariableRequiresCommand>(); - } - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; +bool cmVariableRequiresCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmVariableWatchCommand.cxx b/Source/cmVariableWatchCommand.cxx index 83a774d..db23efd 100644 --- a/Source/cmVariableWatchCommand.cxx +++ b/Source/cmVariableWatchCommand.cxx @@ -2,6 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmVariableWatchCommand.h" +#include <memory> #include <sstream> #include <utility> @@ -119,11 +120,11 @@ private: std::shared_ptr<Impl const> Action; }; -bool cmVariableWatchCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmVariableWatchCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.empty()) { - this->SetError("must be called with at least one argument."); + status.SetError("must be called with at least one argument."); return false; } std::string const& variable = args[0]; @@ -134,7 +135,7 @@ bool cmVariableWatchCommand::InitialPass(std::vector<std::string> const& args, if (variable == "CMAKE_CURRENT_LIST_FILE") { std::ostringstream ostr; ostr << "cannot be set on the variable: " << variable; - this->SetError(ostr.str()); + status.SetError(ostr.str()); return false; } @@ -143,13 +144,14 @@ bool cmVariableWatchCommand::InitialPass(std::vector<std::string> const& args, data->InCallback = false; data->Command = command; - if (!this->Makefile->GetCMakeInstance()->GetVariableWatch()->AddWatch( + if (!status.GetMakefile().GetCMakeInstance()->GetVariableWatch()->AddWatch( variable, cmVariableWatchCommandVariableAccessed, data, deleteVariableWatchCallbackData)) { deleteVariableWatchCallbackData(data); return false; } - this->Makefile->AddFinalAction(FinalAction(this->Makefile, variable)); + status.GetMakefile().AddFinalAction( + FinalAction(&status.GetMakefile(), variable)); return true; } diff --git a/Source/cmVariableWatchCommand.h b/Source/cmVariableWatchCommand.h index 221269f..3f9f244 100644 --- a/Source/cmVariableWatchCommand.h +++ b/Source/cmVariableWatchCommand.h @@ -8,33 +8,13 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmVariableWatchCommand +/** * \brief Watch when the variable changes and invoke command * */ -class cmVariableWatchCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmVariableWatchCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; +bool cmVariableWatchCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 08378eb..b4f05c7 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -249,6 +249,8 @@ cmVisualStudio10TargetGenerator::cmVisualStudio10TargetGenerator( this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget); this->InSourceBuild = (this->Makefile->GetCurrentSourceDirectory() == this->Makefile->GetCurrentBinaryDirectory()); + + this->LocalGenerator->AddPchDependencies(target, ""); } cmVisualStudio10TargetGenerator::~cmVisualStudio10TargetGenerator() @@ -364,10 +366,9 @@ void cmVisualStudio10TargetGenerator::Generate() return; } } - std::string path = this->LocalGenerator->GetCurrentBinaryDirectory(); - path += "/"; - path += this->Name; - path += ProjectFileExtension; + std::string path = + cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(), '/', + this->Name, ProjectFileExtension); cmGeneratedFileStream BuildFileStream(path); const std::string PathToProjectFile = path; BuildFileStream.SetCopyIfDifferent(true); @@ -628,9 +629,8 @@ void cmVisualStudio10TargetGenerator::Generate() std::string propsTemplate = GetCMakeFilePath("Templates/MSBuild/nasm.props.in"); - std::string propsLocal; - propsLocal += this->DefaultArtifactDir; - propsLocal += "\\nasm.props"; + std::string propsLocal = + cmStrCat(this->DefaultArtifactDir, "\\nasm.props"); ConvertToWindowsSlash(propsLocal); this->Makefile->ConfigureFile(propsTemplate, propsLocal, false, true, true); @@ -853,8 +853,8 @@ void cmVisualStudio10TargetGenerator::WriteImports(Elem& e0) const char* imports = this->GeneratorTarget->Target->GetProperty("VS_PROJECT_IMPORT"); if (imports) { - std::vector<std::string> argsSplit; - cmExpandList(std::string(imports), argsSplit, false); + std::vector<std::string> argsSplit = + cmExpandedList(std::string(imports), false); for (auto& path : argsSplit) { if (!cmsys::SystemTools::FileIsFullPath(path)) { path = this->Makefile->GetCurrentSourceDirectory() + "/" + path; @@ -1117,7 +1117,10 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues(Elem& e0) std::string configType; if (const char* vsConfigurationType = this->GeneratorTarget->GetProperty("VS_CONFIGURATION_TYPE")) { - configType = vsConfigurationType; + cmGeneratorExpression ge; + std::unique_ptr<cmCompiledGeneratorExpression> cge = + ge.Parse(vsConfigurationType); + configType = cge->Evaluate(this->LocalGenerator, c); } else { switch (this->GeneratorTarget->GetType()) { case cmStateEnums::SHARED_LIBRARY: @@ -1272,8 +1275,8 @@ void cmVisualStudio10TargetGenerator::WriteMSToolConfigurationValuesManaged( e1.Element("PlatformToolset", toolset); } - std::string postfixName = cmSystemTools::UpperCase(config); - postfixName += "_POSTFIX"; + std::string postfixName = + cmStrCat(cmSystemTools::UpperCase(config), "_POSTFIX"); std::string assemblyName = this->GeneratorTarget->GetOutputName( config, cmStateEnums::RuntimeBinaryArtifact); if (const char* postfix = this->GeneratorTarget->GetProperty(postfixName)) { @@ -1378,9 +1381,8 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule( // preventing dependent rebuilds. this->ForceOld(sourcePath); } else { - std::string error = "Could not create file: ["; - error += sourcePath; - error += "] "; + std::string error = + cmStrCat("Could not create file: [", sourcePath, "] "); cmSystemTools::Error(error + cmSystemTools::GetLastSystemError()); } } @@ -1549,11 +1551,9 @@ void cmVisualStudio10TargetGenerator::WriteGroups() this->AddMissingSourceGroups(groupsUsed, sourceGroups); // Write out group file - std::string path = this->LocalGenerator->GetCurrentBinaryDirectory(); - path += "/"; - path += this->Name; - path += computeProjectFileExtension(this->GeneratorTarget); - path += ".filters"; + std::string path = cmStrCat( + this->LocalGenerator->GetCurrentBinaryDirectory(), '/', this->Name, + computeProjectFileExtension(this->GeneratorTarget), ".filters"); cmGeneratedFileStream fout(path); fout.SetCopyIfDifferent(true); char magic[] = { char(0xEF), char(0xBB), char(0xBF) }; @@ -2150,6 +2150,9 @@ void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0) if (si.Kind == cmGeneratorTarget::SourceKindObjectSource) { this->OutputSourceSpecificFlags(e2, si.Source); } + if (si.Source->GetPropertyAsBool("SKIP_PRECOMPILE_HEADERS")) { + e2.Element("PrecompiledHeader", "NotUsing"); + } if (!exclude_configs.empty()) { this->WriteExcludeFromBuild(e2, exclude_configs); } @@ -2234,8 +2237,7 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags( for (std::string const& config : this->Configurations) { std::string configUpper = cmSystemTools::UpperCase(config); std::string configDefines = defines; - std::string defPropName = "COMPILE_DEFINITIONS_"; - defPropName += configUpper; + std::string defPropName = cmStrCat("COMPILE_DEFINITIONS_", configUpper); if (const char* ccdefs = sf.GetProperty(defPropName)) { if (!configDefines.empty()) { configDefines += ";"; @@ -2425,17 +2427,14 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions( e1.WritePlatformConfigTag( "IntDir", cond, "$(Platform)\\$(Configuration)\\$(ProjectName)\\"); } else { - std::string intermediateDir = - this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget); - intermediateDir += "/"; - intermediateDir += config; - intermediateDir += "/"; + std::string intermediateDir = cmStrCat( + this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget), '/', + config, '/'); std::string outDir; std::string targetNameFull; if (ttype == cmStateEnums::OBJECT_LIBRARY) { outDir = intermediateDir; - targetNameFull = this->GeneratorTarget->GetName(); - targetNameFull += ".lib"; + targetNameFull = cmStrCat(this->GeneratorTarget->GetName(), ".lib"); } else { outDir = this->GeneratorTarget->GetDirectory(config) + "/"; targetNameFull = this->GeneratorTarget->GetFullName(config); @@ -2603,8 +2602,7 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions( std::string langForClCompile; if (this->ProjectType == csproj) { langForClCompile = "CSharp"; - } else if (std::find(cm::cbegin(clLangs), cm::cend(clLangs), linkLanguage) != - cm::cend(clLangs)) { + } else if (cmContains(clLangs, linkLanguage)) { langForClCompile = linkLanguage; } else { std::set<std::string> languages; @@ -2636,6 +2634,13 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions( this->IPOEnabledConfigurations.insert(configName); } + // Precompile Headers + std::string pchHeader = + this->GeneratorTarget->GetPchHeader(configName, linkLanguage); + if (this->MSTools && vcxproj == this->ProjectType && pchHeader.empty()) { + clOptions.AddFlag("PrecompiledHeader", "NotUsing"); + } + // Get preprocessor definitions for this directory. std::string defineFlags = this->Makefile->GetDefineFlags(); if (this->MSTools) { @@ -2651,7 +2656,6 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions( // replace this setting with "true" below. clOptions.AddFlag("UseFullPaths", "false"); } - clOptions.AddFlag("PrecompiledHeader", "NotUsing"); clOptions.AddFlag("AssemblerListingLocation", "$(IntDir)"); } } @@ -2716,9 +2720,7 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions( } // Add a definition for the configuration name. - std::string configDefine = "CMAKE_INTDIR=\""; - configDefine += configName; - configDefine += "\""; + std::string configDefine = cmStrCat("CMAKE_INTDIR=\"", configName, '"'); clOptions.AddDefine(configDefine); if (const std::string* exportMacro = this->GeneratorTarget->GetExportMacro()) { @@ -3013,9 +3015,7 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaOptions( cudaOptions.AddDefines(targetDefines); // Add a definition for the configuration name. - std::string configDefine = "CMAKE_INTDIR=\""; - configDefine += configName; - configDefine += "\""; + std::string configDefine = cmStrCat("CMAKE_INTDIR=\"", configName, '"'); cudaOptions.AddDefine(configDefine); if (const std::string* exportMacro = this->GeneratorTarget->GetExportMacro()) { @@ -3430,9 +3430,7 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions( linkType = "EXE"; } std::string flags; - std::string linkFlagVarBase = "CMAKE_"; - linkFlagVarBase += linkType; - linkFlagVarBase += "_LINKER_FLAGS"; + std::string linkFlagVarBase = cmStrCat("CMAKE_", linkType, "_LINKER_FLAGS"); flags += " "; flags += this->Makefile->GetRequiredDefinition(linkFlagVarBase); std::string linkFlagVar = linkFlagVarBase + "_" + CONFIG; @@ -3444,8 +3442,7 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions( flags += " "; flags += targetLinkFlags; } - std::string flagsProp = "LINK_FLAGS_"; - flagsProp += CONFIG; + std::string flagsProp = cmStrCat("LINK_FLAGS_", CONFIG); if (const char* flagsConfig = this->GeneratorTarget->GetProperty(flagsProp)) { flags += " "; @@ -3470,8 +3467,7 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions( std::vector<std::string> libVec; std::vector<std::string> vsTargetVec; this->AddLibraries(cli, libVec, vsTargetVec, config); - if (std::find(linkClosure->Languages.begin(), linkClosure->Languages.end(), - "CUDA") != linkClosure->Languages.end() && + if (cmContains(linkClosure->Languages, "CUDA") && this->CudaOptions[config] != nullptr) { switch (this->CudaOptions[config]->GetCudaRuntime()) { case cmVisualStudioGeneratorOptions::CudaRuntimeStatic: @@ -3486,9 +3482,8 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions( break; } } - std::string standardLibsVar = "CMAKE_"; - standardLibsVar += linkLanguage; - standardLibsVar += "_STANDARD_LIBRARIES"; + std::string standardLibsVar = + cmStrCat("CMAKE_", linkLanguage, "_STANDARD_LIBRARIES"); std::string const& libs = this->Makefile->GetSafeDefinition(standardLibsVar); cmSystemTools::ParseWindowsCommandLine(libs.c_str(), libVec); linkOptions.AddFlag("AdditionalDependencies", libVec); @@ -3552,13 +3547,12 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions( linkOptions.AddFlag("GenerateDebugInformation", "false"); - std::string pdb = this->GeneratorTarget->GetPDBDirectory(config); - pdb += "/"; - pdb += targetNames.PDB; - std::string imLib = this->GeneratorTarget->GetDirectory( - config, cmStateEnums::ImportLibraryArtifact); - imLib += "/"; - imLib += targetNames.ImportLibrary; + std::string pdb = cmStrCat(this->GeneratorTarget->GetPDBDirectory(config), + '/', targetNames.PDB); + std::string imLib = + cmStrCat(this->GeneratorTarget->GetDirectory( + config, cmStateEnums::ImportLibraryArtifact), + '/', targetNames.ImportLibrary); linkOptions.AddFlag("ImportLibrary", imLib); linkOptions.AddFlag("ProgramDataBaseFile", pdb); @@ -3758,8 +3752,7 @@ void cmVisualStudio10TargetGenerator::AddTargetsFileAndConfigPair( { for (TargetsFileAndConfigs& i : this->TargetsFileAndConfigsVec) { if (cmSystemTools::ComparePath(targetsFile, i.File)) { - if (std::find(i.Configs.begin(), i.Configs.end(), config) == - i.Configs.end()) { + if (!cmContains(i.Configs, config)) { i.Configs.push_back(config); } return; @@ -3941,10 +3934,8 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences(Elem& e0) if (p) { path = p; } else { - path = lg->GetCurrentBinaryDirectory(); - path += "/"; - path += dt->GetName(); - path += computeProjectFileExtension(dt); + path = cmStrCat(lg->GetCurrentBinaryDirectory(), '/', dt->GetName(), + computeProjectFileExtension(dt)); } ConvertToWindowsSlash(path); Elem e2(e1, "ProjectReference"); @@ -4751,8 +4742,8 @@ std::string cmVisualStudio10TargetGenerator::GetCMakeFilePath( const char* relativeFilePath) const { // Always search in the standard modules location. - std::string path = cmSystemTools::GetCMakeRoot() + "/"; - path += relativeFilePath; + std::string path = + cmStrCat(cmSystemTools::GetCMakeRoot(), '/', relativeFilePath); ConvertToWindowsSlash(path); return path; diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx index 6c28996..3e423e9 100644 --- a/Source/cmVisualStudioGeneratorOptions.cxx +++ b/Source/cmVisualStudioGeneratorOptions.cxx @@ -325,9 +325,9 @@ void cmVisualStudioGeneratorOptions::ParseFinish() // "rtSingleThreadedDLL", "10", /libs:dll // "rtSingleThreadedDebug", "5", /dbglibs /libs:static // "rtSingleThreadedDebugDLL", "11", /dbglibs /libs:dll - std::string rl = "rtMultiThreaded"; - rl += this->FortranRuntimeDebug ? "Debug" : ""; - rl += this->FortranRuntimeDLL ? "DLL" : ""; + std::string rl = + cmStrCat("rtMultiThreaded", this->FortranRuntimeDebug ? "Debug" : "", + this->FortranRuntimeDLL ? "DLL" : ""); this->FlagMap["RuntimeLibrary"] = rl; } diff --git a/Source/cmWorkerPool.cxx b/Source/cmWorkerPool.cxx index 974100b..baf326a 100644 --- a/Source/cmWorkerPool.cxx +++ b/Source/cmWorkerPool.cxx @@ -3,6 +3,7 @@ #include "cmWorkerPool.h" #include "cmRange.h" +#include "cmStringAlgorithms.h" #include "cmUVHandlePtr.h" #include "cmUVSignalHackRAII.h" // IWYU pragma: keep #include "cm_uv.h" @@ -306,13 +307,11 @@ void cmUVReadOnlyProcess::UVExit(uv_process_t* handle, int64_t exitStatus, proc.Result()->TermSignal = termSignal; if (!proc.Result()->error()) { if (termSignal != 0) { - proc.Result()->ErrorMessage = "Process was terminated by signal "; - proc.Result()->ErrorMessage += - std::to_string(proc.Result()->TermSignal); + proc.Result()->ErrorMessage = cmStrCat( + "Process was terminated by signal ", proc.Result()->TermSignal); } else if (exitStatus != 0) { - proc.Result()->ErrorMessage = "Process failed with return value "; - proc.Result()->ErrorMessage += - std::to_string(proc.Result()->ExitStatus); + proc.Result()->ErrorMessage = cmStrCat( + "Process failed with return value ", proc.Result()->ExitStatus); } } @@ -332,9 +331,8 @@ void cmUVReadOnlyProcess::UVPipeOutEnd(ssize_t error) { // Process pipe error if ((error != 0) && !Result()->error()) { - Result()->ErrorMessage = - "Reading from stdout pipe failed with libuv error code "; - Result()->ErrorMessage += std::to_string(error); + Result()->ErrorMessage = cmStrCat( + "Reading from stdout pipe failed with libuv error code ", error); } // Try finish UVTryFinish(); @@ -351,9 +349,8 @@ void cmUVReadOnlyProcess::UVPipeErrEnd(ssize_t error) { // Process pipe error if ((error != 0) && !Result()->error()) { - Result()->ErrorMessage = - "Reading from stderr pipe failed with libuv error code "; - Result()->ErrorMessage += std::to_string(error); + Result()->ErrorMessage = cmStrCat( + "Reading from stderr pipe failed with libuv error code ", error); } // Try finish UVTryFinish(); diff --git a/Source/cmWriteFileCommand.cxx b/Source/cmWriteFileCommand.cxx index 49dbf1a..5009b16 100644 --- a/Source/cmWriteFileCommand.cxx +++ b/Source/cmWriteFileCommand.cxx @@ -4,18 +4,18 @@ #include "cmsys/FStream.hxx" +#include "cmExecutionStatus.h" #include "cmMakefile.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cm_sys_stat.h" -class cmExecutionStatus; - // cmLibraryCommand -bool cmWriteFileCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmWriteFileCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() < 2) { - this->SetError("called with incorrect number of arguments"); + status.SetError("called with incorrect number of arguments"); return false; } std::string message; @@ -33,10 +33,10 @@ bool cmWriteFileCommand::InitialPass(std::vector<std::string> const& args, } } - if (!this->Makefile->CanIWriteThisFile(fileName)) { + if (!status.GetMakefile().CanIWriteThisFile(fileName)) { std::string e = "attempted to write a file: " + fileName + " into a source directory."; - this->SetError(e); + status.SetError(e); cmSystemTools::SetFatalErrorOccured(); return false; } @@ -65,10 +65,10 @@ bool cmWriteFileCommand::InitialPass(std::vector<std::string> const& args, cmsys::ofstream file(fileName.c_str(), overwrite ? std::ios::out : std::ios::app); if (!file) { - std::string error = "Internal CMake error when trying to open file: "; - error += fileName; - error += " for writing."; - this->SetError(error); + std::string error = + cmStrCat("Internal CMake error when trying to open file: ", fileName, + " for writing."); + status.SetError(error); return false; } file << message << std::endl; diff --git a/Source/cmWriteFileCommand.h b/Source/cmWriteFileCommand.h index 3961898..3e0e043 100644 --- a/Source/cmWriteFileCommand.h +++ b/Source/cmWriteFileCommand.h @@ -8,33 +8,13 @@ #include <string> #include <vector> -#include "cm_memory.hxx" - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmWriteFileCommand +/** * \brief Writes a message to a file * */ -class cmWriteFileCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmWriteFileCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; +bool cmWriteFileCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmXCodeObject.h b/Source/cmXCodeObject.h index 51e5d36..0552676 100644 --- a/Source/cmXCodeObject.h +++ b/Source/cmXCodeObject.h @@ -12,6 +12,8 @@ #include <utility> #include <vector> +#include "cmAlgorithms.h" + class cmGeneratorTarget; class cmXCodeObject @@ -80,15 +82,10 @@ public: void SetObject(cmXCodeObject* value) { this->Object = value; } cmXCodeObject* GetObject() { return this->Object; } void AddObject(cmXCodeObject* value) { this->List.push_back(value); } - bool HasObject(cmXCodeObject* o) const - { - return !(std::find(this->List.begin(), this->List.end(), o) == - this->List.end()); - } + bool HasObject(cmXCodeObject* o) const { return cmContains(this->List, o); } void AddUniqueObject(cmXCodeObject* value) { - if (std::find(this->List.begin(), this->List.end(), value) == - this->List.end()) { + if (!cmContains(this->List, value)) { this->List.push_back(value); } } diff --git a/Source/cmXCodeScheme.cxx b/Source/cmXCodeScheme.cxx index a565a9c..a1c64ed 100644 --- a/Source/cmXCodeScheme.cxx +++ b/Source/cmXCodeScheme.cxx @@ -27,14 +27,11 @@ void cmXCodeScheme::WriteXCodeSharedScheme(const std::string& xcProjDir, { // Create shared scheme sub-directory tree // - std::string xcodeSchemeDir = xcProjDir; - xcodeSchemeDir += "/xcshareddata/xcschemes"; + std::string xcodeSchemeDir = cmStrCat(xcProjDir, "/xcshareddata/xcschemes"); cmSystemTools::MakeDirectory(xcodeSchemeDir.c_str()); - std::string xcodeSchemeFile = xcodeSchemeDir; - xcodeSchemeFile += "/"; - xcodeSchemeFile += this->TargetName; - xcodeSchemeFile += ".xcscheme"; + std::string xcodeSchemeFile = + cmStrCat(xcodeSchemeDir, '/', this->TargetName, ".xcscheme"); cmGeneratedFileStream fout(xcodeSchemeFile); fout.SetCopyIfDifferent(true); @@ -217,8 +214,7 @@ void cmXCodeScheme::WriteLaunchAction(cmXMLWriter& xout, if (const char* argList = this->Target->GetTarget()->GetProperty("XCODE_SCHEME_ARGUMENTS")) { - std::vector<std::string> arguments; - cmExpandList(argList, arguments); + std::vector<std::string> arguments = cmExpandedList(argList); if (!arguments.empty()) { xout.StartElement("CommandLineArguments"); @@ -238,8 +234,7 @@ void cmXCodeScheme::WriteLaunchAction(cmXMLWriter& xout, if (const char* envList = this->Target->GetTarget()->GetProperty("XCODE_SCHEME_ENVIRONMENT")) { - std::vector<std::string> envs; - cmExpandList(envList, envs); + std::vector<std::string> envs = cmExpandedList(envList); if (!envs.empty()) { xout.StartElement("EnvironmentVariables"); @@ -393,9 +388,7 @@ std::string cmXCodeScheme::FindConfiguration(const std::string& name) // Try to find the desired configuration by name, // and if it's not found return first from the list // - if (std::find(this->ConfigList.begin(), this->ConfigList.end(), name) == - this->ConfigList.end() && - !this->ConfigList.empty()) { + if (!cmContains(this->ConfigList, name) && !this->ConfigList.empty()) { return this->ConfigList[0]; } diff --git a/Source/cm_optional.hxx b/Source/cm_optional.hxx new file mode 100644 index 0000000..295571d --- /dev/null +++ b/Source/cm_optional.hxx @@ -0,0 +1,343 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#ifndef cm_optional_hxx +#define cm_optional_hxx + +#include "cmConfigure.h" // IWYU pragma: keep + +#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) +# define CMake_HAVE_CXX_OPTIONAL +#endif + +#if defined(CMake_HAVE_CXX_OPTIONAL) +# include <optional> +#else +# include "cm_utility.hxx" +# include <memory> +# include <utility> +#endif + +namespace cm { + +#if defined(CMake_HAVE_CXX_OPTIONAL) + +using std::nullopt_t; +using std::nullopt; +using std::optional; +using std::bad_optional_access; +using std::make_optional; + +#else + +class bad_optional_access : public std::exception +{ + using std::exception::exception; +}; + +struct nullopt_t +{ + explicit constexpr nullopt_t(int) {} +}; + +constexpr nullopt_t nullopt{ 0 }; + +template <typename T> +class optional +{ +public: + using value_type = T; + + optional() noexcept = default; + optional(nullopt_t) noexcept; + optional(const optional& other); + optional(optional&& other) noexcept; + + template <typename... Args> + explicit optional(cm::in_place_t, Args&&... args); + + template < + typename U = T, + typename = typename std::enable_if< + std::is_constructible<T, U&&>::value && + !std::is_same<typename std::decay<U>::type, cm::in_place_t>::value && + !std::is_same<typename std::decay<U>::type, + cm::optional<T>>::value>::type> + optional(U&& v); + + ~optional(); + + optional& operator=(nullopt_t) noexcept; + optional& operator=(const optional& other); + optional& operator=(optional&& other) noexcept; + + template < + typename U = T, + typename = typename std::enable_if< + !std::is_same<typename std::decay<U>::type, cm::optional<T>>::value && + std::is_constructible<T, U>::value && std::is_assignable<T&, U>::value && + (!std::is_scalar<T>::value || + !std::is_same<typename std::decay<U>::type, T>::value)>::type> + optional& operator=(U&& v); + + const T* operator->() const; + T* operator->(); + const T& operator*() const&; + T& operator*() &; + const T&& operator*() const&&; + T&& operator*() &&; + + explicit operator bool() const noexcept; + bool has_value() const noexcept; + + T& value() &; + const T& value() const&; + + T&& value() &&; + const T&& value() const&&; + + template <typename U> + T value_or(U&& default_value) const&; + + template <typename U> + T value_or(U&& default_value) &&; + + void swap(optional& other) noexcept; + void reset() noexcept; + + template <typename... Args> + T& emplace(Args&&... args); + +private: + bool _has_value = false; + std::allocator<T> _allocator; + union _mem_union + { + T value; + + // Explicit constructor and destructor is required to make this work + _mem_union() noexcept {} + ~_mem_union() noexcept {} + } _mem; +}; + +template <typename T> +optional<typename std::decay<T>::type> make_optional(T&& value) +{ + return optional<typename std::decay<T>::type>(std::forward<T>(value)); +} + +template <typename T, class... Args> +optional<T> make_optional(Args&&... args) +{ + return optional<T>(in_place, std::forward<Args>(args)...); +} + +template <typename T> +optional<T>::optional(nullopt_t) noexcept +{ +} + +template <typename T> +optional<T>::optional(const optional& other) +{ + *this = other; +} + +template <typename T> +optional<T>::optional(optional&& other) noexcept +{ + *this = std::move(other); +} + +template <typename T> +template <typename... Args> +optional<T>::optional(cm::in_place_t, Args&&... args) +{ + this->emplace(std::forward<Args>(args)...); +} + +template <typename T> +template <typename U, typename> +optional<T>::optional(U&& v) +{ + this->emplace(std::forward<U>(v)); +} + +template <typename T> +optional<T>::~optional() +{ + this->reset(); +} + +template <typename T> +optional<T>& optional<T>::operator=(nullopt_t) noexcept +{ + this->reset(); + return *this; +} + +template <typename T> +optional<T>& optional<T>::operator=(const optional& other) +{ + if (other.has_value()) { + if (this->has_value()) { + this->value() = *other; + } else { + this->emplace(*other); + } + } else { + this->reset(); + } + return *this; +} + +template <typename T> +optional<T>& optional<T>::operator=(optional&& other) noexcept +{ + if (other.has_value()) { + if (this->has_value()) { + this->value() = std::move(*other); + } else { + this->emplace(std::move(*other)); + } + } else { + this->reset(); + } + return *this; +} + +template <typename T> +template <typename U, typename> +optional<T>& optional<T>::operator=(U&& v) +{ + if (this->has_value()) { + this->value() = v; + } else { + this->emplace(std::forward<U>(v)); + } + return *this; +} + +template <typename T> +const T* optional<T>::operator->() const +{ + return &**this; +} + +template <typename T> +T* optional<T>::operator->() +{ + return &**this; +} + +template <typename T> +const T& optional<T>::operator*() const& +{ + return this->_mem.value; +} + +template <typename T> +T& optional<T>::operator*() & +{ + return this->_mem.value; +} + +template <typename T> +const T&& optional<T>::operator*() const&& +{ + return std::move(**this); +} + +template <typename T> +T&& optional<T>::operator*() && +{ + return std::move(**this); +} + +template <typename T> +bool optional<T>::has_value() const noexcept +{ + return this->_has_value; +} + +template <typename T> +optional<T>::operator bool() const noexcept +{ + return this->has_value(); +} + +template <typename T> +T& optional<T>::value() & +{ + if (!this->has_value()) { + throw cm::bad_optional_access{}; + } + return **this; +} + +template <typename T> +const T& optional<T>::value() const& +{ + if (!this->has_value()) { + throw cm::bad_optional_access{}; + } + return **this; +} + +template <typename T> +template <typename U> +T optional<T>::value_or(U&& default_value) const& +{ + return bool(*this) ? **this : static_cast<T>(std::forward<U>(default_value)); +} + +template <typename T> +template <typename U> +T optional<T>::value_or(U&& default_value) && +{ + return bool(*this) ? std::move(**this) + : static_cast<T>(std::forward<U>(default_value)); +} + +template <typename T> +void optional<T>::swap(optional& other) noexcept +{ + if (this->has_value()) { + if (other.has_value()) { + using std::swap; + swap(**this, *other); + } else { + other.emplace(std::move(**this)); + this->reset(); + } + } else if (other.has_value()) { + this->emplace(std::move(*other)); + other.reset(); + } +} + +template <typename T> +void optional<T>::reset() noexcept +{ + if (this->has_value()) { + this->_has_value = false; + std::allocator_traits<std::allocator<T>>::destroy(this->_allocator, + &**this); + } +} + +template <typename T> +template <typename... Args> +T& optional<T>::emplace(Args&&... args) +{ + this->reset(); + std::allocator_traits<std::allocator<T>>::construct( + this->_allocator, &**this, std::forward<Args>(args)...); + this->_has_value = true; + return this->value(); +} + +#endif +} + +#endif diff --git a/Source/cm_utility.hxx b/Source/cm_utility.hxx new file mode 100644 index 0000000..99d7f8b --- /dev/null +++ b/Source/cm_utility.hxx @@ -0,0 +1,35 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#ifndef cm_utility_hxx +#define cm_utility_hxx + +#include "cmConfigure.h" // IWYU pragma: keep + +#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) +# define CMake_HAVE_CXX_IN_PLACE +#endif + +#if defined(CMake_HAVE_CXX_IN_PLACE) +# include <utility> +#endif + +namespace cm { + +#if defined(CMake_HAVE_CXX_IN_PLACE) + +using std::in_place_t; +using std::in_place; + +#else + +struct in_place_t +{ + explicit in_place_t() = default; +}; + +constexpr in_place_t in_place{}; + +#endif +} + +#endif diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 1625931..1746082 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -140,6 +140,7 @@ cmake::cmake(Role role, cmState::Mode mode) , State(cm::make_unique<cmState>()) , Messenger(cm::make_unique<cmMessenger>()) { + this->TraceFile.close(); this->State->SetMode(mode); this->CurrentSnapshot = this->State->CreateBaseSnapshot(); @@ -295,7 +296,8 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args) return false; } } - std::string var, value; + std::string var; + std::string value; cmStateEnums::CacheEntryType type = cmStateEnums::UNINITIALIZED; if (cmState::ParseCacheEntry(entry, var, value, type)) { // The value is transformed if it is a filepath for example, so @@ -429,6 +431,11 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args) } // Register fake project commands that hint misuse in script mode. GetProjectCommandsInScriptMode(this->GetState()); + // Documented behaviour of CMAKE{,_CURRENT}_{SOURCE,BINARY}_DIR is to be + // set to $PWD for -P mode. + this->SetHomeDirectory(cmSystemTools::GetCurrentWorkingDirectory()); + this->SetHomeOutputDirectory( + cmSystemTools::GetCurrentWorkingDirectory()); this->ReadListFile(args, path); } else if (arg.find("--find-package", 0) == 0) { findPackageMode = true; @@ -458,15 +465,9 @@ void cmake::ReadListFile(const std::vector<std::string>& args, // read in the list file to fill the cache if (!path.empty()) { this->CurrentSnapshot = this->State->Reset(); - std::string homeDir = this->GetHomeDirectory(); - std::string homeOutputDir = this->GetHomeOutputDirectory(); - this->SetHomeDirectory(cmSystemTools::GetCurrentWorkingDirectory()); - this->SetHomeOutputDirectory(cmSystemTools::GetCurrentWorkingDirectory()); cmStateSnapshot snapshot = this->GetCurrentSnapshot(); - snapshot.GetDirectory().SetCurrentBinary( - cmSystemTools::GetCurrentWorkingDirectory()); - snapshot.GetDirectory().SetCurrentSource( - cmSystemTools::GetCurrentWorkingDirectory()); + snapshot.GetDirectory().SetCurrentBinary(this->GetHomeOutputDirectory()); + snapshot.GetDirectory().SetCurrentSource(this->GetHomeDirectory()); snapshot.SetDefaultDefinitions(); cmMakefile mf(gg, snapshot); if (this->GetWorkingMode() != NORMAL_MODE) { @@ -479,8 +480,6 @@ void cmake::ReadListFile(const std::vector<std::string>& args, if (!mf.ReadListFile(path)) { cmSystemTools::Error("Error processing file: " + path); } - this->SetHomeDirectory(homeDir); - this->SetHomeOutputDirectory(homeOutputDir); } // free generic one if generated @@ -529,8 +528,7 @@ bool cmake::FindPackage(const std::vector<std::string>& args) } } else if (mode == "COMPILE") { std::string includes = mf->GetSafeDefinition("PACKAGE_INCLUDE_DIRS"); - std::vector<std::string> includeDirs; - cmExpandList(includes, includeDirs); + std::vector<std::string> includeDirs = cmExpandedList(includes); gg->CreateGenerationObjects(); cmLocalGenerator* lg = gg->LocalGenerators[0]; @@ -546,8 +544,7 @@ bool cmake::FindPackage(const std::vector<std::string>& args) tgt->SetProperty("LINKER_LANGUAGE", language.c_str()); std::string libs = mf->GetSafeDefinition("PACKAGE_LIBRARIES"); - std::vector<std::string> libList; - cmExpandList(libs, libList); + std::vector<std::string> libList = cmExpandedList(libs); for (std::string const& lib : libList) { tgt->AddLinkLibrary(*mf, lib, GENERAL_LibraryType); } @@ -603,10 +600,9 @@ void cmake::LoadEnvironmentPresets() if (hasEnvironmentGenerator) { key = varValue; } else if (!this->GetIsInTryCompile()) { - std::string message = "Warning: Environment variable "; - message += name; - message += " will be ignored, because CMAKE_GENERATOR "; - message += "is not set."; + std::string message = + cmStrCat("Warning: Environment variable ", name, + " will be ignored, because CMAKE_GENERATOR is not set."); cmSystemTools::Message(message, "Warning"); } } @@ -740,6 +736,11 @@ void cmake::SetArgs(const std::vector<std::string>& args) cmSystemTools::ConvertToUnixSlashes(file); this->AddTraceSource(file); this->SetTrace(true); + } else if (arg.find("--trace-redirect=", 0) == 0) { + std::string file = arg.substr(strlen("--trace-redirect=")); + cmSystemTools::ConvertToUnixSlashes(file); + this->SetTraceFile(file); + this->SetTrace(true); } else if (arg.find("--trace", 0) == 0) { std::cout << "Running with trace output on.\n"; this->SetTrace(true); @@ -870,6 +871,20 @@ cmake::LogLevel cmake::StringToLogLevel(const std::string& levelStr) return (it != levels.cend()) ? it->second : LogLevel::LOG_UNDEFINED; } +void cmake::SetTraceFile(const std::string& file) +{ + this->TraceFile.close(); + this->TraceFile.open(file.c_str()); + if (!this->TraceFile) { + std::stringstream ss; + ss << "Error opening trace file " << file << ": " + << cmSystemTools::GetLastSystemError(); + cmSystemTools::Error(ss.str()); + return; + } + std::cout << "Trace will be written to " << file << "\n"; +} + void cmake::SetDirectoriesFromFile(const std::string& arg) { // Check if the argument refers to a CMakeCache.txt or @@ -880,10 +895,8 @@ void cmake::SetDirectoriesFromFile(const std::string& arg) if (cmSystemTools::FileIsDirectory(arg)) { std::string path = cmSystemTools::CollapseFullPath(arg); cmSystemTools::ConvertToUnixSlashes(path); - std::string cacheFile = path; - cacheFile += "/CMakeCache.txt"; - std::string listFile = path; - listFile += "/CMakeLists.txt"; + std::string cacheFile = cmStrCat(path, "/CMakeCache.txt"); + std::string listFile = cmStrCat(path, "/CMakeLists.txt"); if (cmSystemTools::FileExists(cacheFile)) { cachePath = path; } @@ -1138,12 +1151,10 @@ std::string cmake::FindCacheFile(const std::string& binaryDir) { std::string cachePath = binaryDir; cmSystemTools::ConvertToUnixSlashes(cachePath); - std::string cacheFile = cachePath; - cacheFile += "/CMakeCache.txt"; + std::string cacheFile = cmStrCat(cachePath, "/CMakeCache.txt"); if (!cmSystemTools::FileExists(cacheFile)) { // search in parent directories for cache - std::string cmakeFiles = cachePath; - cmakeFiles += "/CMakeFiles"; + std::string cmakeFiles = cmStrCat(cachePath, "/CMakeFiles"); if (cmSystemTools::FileExists(cmakeFiles)) { std::string cachePathFound = cmSystemTools::FileExistsInParentDirectories("CMakeCache.txt", @@ -1198,8 +1209,7 @@ void cmake::SetGlobalGenerator(cmGlobalGenerator* gg) int cmake::DoPreConfigureChecks() { // Make sure the Source directory contains a CMakeLists.txt file. - std::string srcList = this->GetHomeDirectory(); - srcList += "/CMakeLists.txt"; + std::string srcList = cmStrCat(this->GetHomeDirectory(), "/CMakeLists.txt"); if (!cmSystemTools::FileExists(srcList)) { std::ostringstream err; if (cmSystemTools::FileIsDirectory(this->GetHomeDirectory())) { @@ -1221,17 +1231,16 @@ int cmake::DoPreConfigureChecks() // do a sanity check on some values if (this->State->GetInitializedCacheValue("CMAKE_HOME_DIRECTORY")) { std::string cacheStart = - *this->State->GetInitializedCacheValue("CMAKE_HOME_DIRECTORY"); - cacheStart += "/CMakeLists.txt"; - std::string currentStart = this->GetHomeDirectory(); - currentStart += "/CMakeLists.txt"; + cmStrCat(*this->State->GetInitializedCacheValue("CMAKE_HOME_DIRECTORY"), + "/CMakeLists.txt"); + std::string currentStart = + cmStrCat(this->GetHomeDirectory(), "/CMakeLists.txt"); if (!cmSystemTools::SameFile(cacheStart, currentStart)) { - std::string message = "The source \""; - message += currentStart; - message += "\" does not match the source \""; - message += cacheStart; - message += "\" used to generate cache. "; - message += "Re-run cmake with a different source directory."; + std::string message = + cmStrCat("The source \"", currentStart, + "\" does not match the source \"", cacheStart, + "\" used to generate cache. Re-run cmake with a different " + "source directory."); cmSystemTools::Error(message); return -2; } @@ -1250,8 +1259,7 @@ struct SaveCacheEntry int cmake::HandleDeleteCacheVariables(const std::string& var) { - std::vector<std::string> argsSplit; - cmExpandList(std::string(var), argsSplit, true); + std::vector<std::string> argsSplit = cmExpandedList(std::string(var), true); // erase the property to avoid infinite recursion this->State->SetGlobalProperty("__CMAKE_DELETE_CACHE_CHANGE_VARS_", ""); if (this->State->GetIsInTryCompile()) { @@ -1434,12 +1442,11 @@ int cmake::ActualConfigure() this->State->GetInitializedCacheValue("CMAKE_GENERATOR"); if (genName) { if (!this->GlobalGenerator->MatchesGeneratorName(*genName)) { - std::string message = "Error: generator : "; - message += this->GlobalGenerator->GetName(); - message += "\nDoes not match the generator used previously: "; - message += *genName; - message += "\nEither remove the CMakeCache.txt file and CMakeFiles " - "directory or choose a different binary directory."; + std::string message = + cmStrCat("Error: generator : ", this->GlobalGenerator->GetName(), + "\nDoes not match the generator used previously: ", *genName, + "\nEither remove the CMakeCache.txt file and CMakeFiles " + "directory or choose a different binary directory."); cmSystemTools::Error(message); return -2; } @@ -1457,12 +1464,11 @@ int cmake::ActualConfigure() if (const std::string* instance = this->State->GetInitializedCacheValue("CMAKE_GENERATOR_INSTANCE")) { if (this->GeneratorInstanceSet && this->GeneratorInstance != *instance) { - std::string message = "Error: generator instance: "; - message += this->GeneratorInstance; - message += "\nDoes not match the instance used previously: "; - message += *instance; - message += "\nEither remove the CMakeCache.txt file and CMakeFiles " - "directory or choose a different binary directory."; + std::string message = + cmStrCat("Error: generator instance: ", this->GeneratorInstance, + "\nDoes not match the instance used previously: ", *instance, + "\nEither remove the CMakeCache.txt file and CMakeFiles " + "directory or choose a different binary directory."); cmSystemTools::Error(message); return -2; } @@ -1476,12 +1482,11 @@ int cmake::ActualConfigure() this->State->GetInitializedCacheValue("CMAKE_GENERATOR_PLATFORM")) { if (this->GeneratorPlatformSet && this->GeneratorPlatform != *platformName) { - std::string message = "Error: generator platform: "; - message += this->GeneratorPlatform; - message += "\nDoes not match the platform used previously: "; - message += *platformName; - message += "\nEither remove the CMakeCache.txt file and CMakeFiles " - "directory or choose a different binary directory."; + std::string message = cmStrCat( + "Error: generator platform: ", this->GeneratorPlatform, + "\nDoes not match the platform used previously: ", *platformName, + "\nEither remove the CMakeCache.txt file and CMakeFiles " + "directory or choose a different binary directory."); cmSystemTools::Error(message); return -2; } @@ -1494,12 +1499,11 @@ int cmake::ActualConfigure() if (const std::string* tsName = this->State->GetInitializedCacheValue("CMAKE_GENERATOR_TOOLSET")) { if (this->GeneratorToolsetSet && this->GeneratorToolset != *tsName) { - std::string message = "Error: generator toolset: "; - message += this->GeneratorToolset; - message += "\nDoes not match the toolset used previously: "; - message += *tsName; - message += "\nEither remove the CMakeCache.txt file and CMakeFiles " - "directory or choose a different binary directory."; + std::string message = + cmStrCat("Error: generator toolset: ", this->GeneratorToolset, + "\nDoes not match the toolset used previously: ", *tsName, + "\nEither remove the CMakeCache.txt file and CMakeFiles " + "directory or choose a different binary directory."); cmSystemTools::Error(message); return -2; } @@ -1757,8 +1761,8 @@ int cmake::Run(const std::vector<std::string>& args, bool noconfigure) "Build files cannot be regenerated correctly."); return ret; } - std::string message = "Build files have been written to: "; - message += this->GetHomeOutputDirectory(); + std::string message = cmStrCat("Build files have been written to: ", + this->GetHomeOutputDirectory()); this->UpdateProgress(message, -1); return ret; } @@ -1917,8 +1921,8 @@ int cmake::LoadCache() // could we not read the cache if (!this->LoadCache(this->GetHomeOutputDirectory())) { // if it does exist, but isn't readable then warn the user - std::string cacheFile = this->GetHomeOutputDirectory(); - cacheFile += "/CMakeCache.txt"; + std::string cacheFile = + cmStrCat(this->GetHomeOutputDirectory(), "/CMakeCache.txt"); if (cmSystemTools::FileExists(cacheFile)) { cmSystemTools::Error( "There is a CMakeCache.txt file for the current binary tree but " @@ -2072,7 +2076,8 @@ void cmake::UpdateConversionPathTable() ". CMake can not open file."); cmSystemTools::ReportLastSystemError("CMake can not open file."); } else { - std::string a, b; + std::string a; + std::string b; while (!table.eof()) { // two entries per line table >> a; @@ -2095,9 +2100,7 @@ int cmake::CheckBuildSystem() // If no file is provided for the check, we have to rerun. if (this->CheckBuildSystemArgument.empty()) { if (verbose) { - std::ostringstream msg; - msg << "Re-run cmake no build system arguments\n"; - cmSystemTools::Stdout(msg.str()); + cmSystemTools::Stdout("Re-run cmake no build system arguments\n"); } return 1; } @@ -2180,10 +2183,8 @@ int cmake::CheckBuildSystem() if (depends.empty() || outputs.empty()) { // Not enough information was provided to do the test. Just rerun. if (verbose) { - std::ostringstream msg; - msg << "Re-run cmake no CMAKE_MAKEFILE_DEPENDS " - "or CMAKE_MAKEFILE_OUTPUTS :\n"; - cmSystemTools::Stdout(msg.str()); + cmSystemTools::Stdout("Re-run cmake no CMAKE_MAKEFILE_DEPENDS " + "or CMAKE_MAKEFILE_OUTPUTS :\n"); } return 1; } @@ -2199,9 +2200,8 @@ int cmake::CheckBuildSystem() } } else { if (verbose) { - std::ostringstream msg; - msg << "Re-run cmake: build system dependency is missing\n"; - cmSystemTools::Stdout(msg.str()); + cmSystemTools::Stdout( + "Re-run cmake: build system dependency is missing\n"); } return 1; } @@ -2218,9 +2218,8 @@ int cmake::CheckBuildSystem() } } else { if (verbose) { - std::ostringstream msg; - msg << "Re-run cmake: build system output is missing\n"; - cmSystemTools::Stdout(msg.str()); + cmSystemTools::Stdout( + "Re-run cmake: build system output is missing\n"); } return 1; } @@ -2247,9 +2246,7 @@ int cmake::CheckBuildSystem() void cmake::TruncateOutputLog(const char* fname) { - std::string fullPath = this->GetHomeOutputDirectory(); - fullPath += "/"; - fullPath += fname; + std::string fullPath = cmStrCat(this->GetHomeOutputDirectory(), '/', fname); struct stat st; if (::stat(fullPath.c_str(), &st)) { return; @@ -2276,10 +2273,10 @@ void cmake::GenerateGraphViz(const std::string& fileName) const #ifndef CMAKE_BOOTSTRAP cmGraphVizWriter gvWriter(this->GetGlobalGenerator()); - std::string settingsFile = this->GetHomeOutputDirectory(); - settingsFile += "/CMakeGraphVizOptions.cmake"; - std::string fallbackSettingsFile = this->GetHomeDirectory(); - fallbackSettingsFile += "/CMakeGraphVizOptions.cmake"; + std::string settingsFile = + cmStrCat(this->GetHomeOutputDirectory(), "/CMakeGraphVizOptions.cmake"); + std::string fallbackSettingsFile = + cmStrCat(this->GetHomeDirectory(), "/CMakeGraphVizOptions.cmake"); gvWriter.ReadSettings(settingsFile, fallbackSettingsFile); gvWriter.WritePerTargetFiles(fileName); @@ -2376,8 +2373,7 @@ int cmake::GetSystemInformation(std::vector<std::string>& args) // no option assume it is the output file else { if (!cmSystemTools::FileIsFullPath(arg)) { - resultFile = cwd; - resultFile += "/"; + resultFile = cmStrCat(cwd, '/'); } resultFile += arg; writeToStdout = false; @@ -2386,12 +2382,10 @@ int cmake::GetSystemInformation(std::vector<std::string>& args) // we have to find the module directory, so we can copy the files this->AddCMakePaths(); - std::string modulesPath = cmSystemTools::GetCMakeRoot(); - modulesPath += "/Modules"; - std::string inFile = modulesPath; - inFile += "/SystemInformation.cmake"; - std::string outFile = destPath; - outFile += "/CMakeLists.txt"; + std::string modulesPath = + cmStrCat(cmSystemTools::GetCMakeRoot(), "/Modules"); + std::string inFile = cmStrCat(modulesPath, "/SystemInformation.cmake"); + std::string outFile = cmStrCat(destPath, "/CMakeLists.txt"); // Copy file if (!cmsys::SystemTools::CopyFileAlways(inFile, outFile)) { @@ -2402,8 +2396,7 @@ int cmake::GetSystemInformation(std::vector<std::string>& args) // do we write to a file or to stdout? if (resultFile.empty()) { - resultFile = cwd; - resultFile += "/__cmake_systeminformation/results.txt"; + resultFile = cmStrCat(cwd, "/__cmake_systeminformation/results.txt"); } { @@ -2459,8 +2452,7 @@ static bool cmakeCheckStampFile(const std::string& stampName) // conjunction with cmLocalVisualStudio7Generator to avoid // repeatedly re-running CMake when the user rebuilds the entire // solution. - std::string stampDepends = stampName; - stampDepends += ".depend"; + std::string stampDepends = cmStrCat(stampName, ".depend"); #if defined(_WIN32) || defined(__CYGWIN__) cmsys::ifstream fin(stampDepends.c_str(), std::ios::in | std::ios::binary); #else @@ -2670,8 +2662,8 @@ int cmake::Build(int jobs, const std::string& dir, "Build files cannot be regenerated correctly."); return ret; } - std::string message = "Build files have been written to: "; - message += this->GetHomeOutputDirectory(); + std::string message = cmStrCat("Build files have been written to: ", + this->GetHomeOutputDirectory()); this->UpdateProgress(message, -1); // Restore the previously set directories to their original value. @@ -2734,7 +2726,7 @@ void cmake::WatchUnusedCli(const std::string& var) { #ifndef CMAKE_BOOTSTRAP this->VariableWatch->AddWatch(var, cmWarnUnusedCliWarning, this); - if (this->UsedCliVariables.find(var) == this->UsedCliVariables.end()) { + if (!cmContains(this->UsedCliVariables, var)) { this->UsedCliVariables[var] = false; } #endif diff --git a/Source/cmake.h b/Source/cmake.h index 4c73519..081e120 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -13,6 +13,7 @@ #include <unordered_set> #include <vector> +#include "cmGeneratedFileStream.h" #include "cmInstalledFile.h" #include "cmListFileCache.h" #include "cmMessageType.h" @@ -401,6 +402,9 @@ public: { return this->TraceOnlyThisSources; } + cmGeneratedFileStream& GetTraceFile() { return this->TraceFile; } + void SetTraceFile(std::string const& file); + bool GetWarnUninitialized() { return this->WarnUninitialized; } void SetWarnUninitialized(bool b) { this->WarnUninitialized = b; } bool GetWarnUnused() { return this->WarnUnused; } @@ -547,6 +551,7 @@ private: bool DebugOutput = false; bool Trace = false; bool TraceExpand = false; + cmGeneratedFileStream TraceFile; bool WarnUninitialized = false; bool WarnUnused = false; bool WarnUnusedCli = true; diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index 74c0d0f..2b51a2a 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -80,6 +80,8 @@ const char* cmDocumentationOptions[][2] = { { "--trace-expand", "Put cmake in trace mode with variable expansion." }, { "--trace-source=<file>", "Trace only this CMake file/module. Multiple options allowed." }, + { "--trace-redirect=<file>", + "Redirect trace output to a file instead of stderr." }, { "--warn-uninitialized", "Warn about uninitialized values." }, { "--warn-unused-vars", "Warn about unused variables." }, { "--no-warn-unused-cli", "Don't warn about command line options." }, @@ -136,11 +138,9 @@ void cmakemainProgressCallback(const std::string& m, float prog, cmake* cm) cmMakefile* mf = cmakemainGetMakefile(cm); std::string dir; if (mf && cmHasLiteralPrefix(m, "Configuring") && (prog < 0)) { - dir = " "; - dir += mf->GetCurrentSourceDirectory(); + dir = cmStrCat(' ', mf->GetCurrentSourceDirectory()); } else if (mf && cmHasLiteralPrefix(m, "Generating")) { - dir = " "; - dir += mf->GetCurrentBinaryDirectory(); + dir = cmStrCat(' ', mf->GetCurrentBinaryDirectory()); } if ((prog < 0) || (!dir.empty())) { diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index 9b8689f..6cbe546 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -38,10 +38,8 @@ #include "cmsys/FStream.hxx" #include "cmsys/Process.h" #include "cmsys/Terminal.h" -#include <algorithm> #include <array> #include <iostream> -#include <iterator> #include <memory> #include <sstream> #include <stdio.h> @@ -174,8 +172,7 @@ static int HandleIWYU(const std::string& runCmd, { // Construct the iwyu command line by taking what was given // and adding all the arguments we give to the compiler. - std::vector<std::string> iwyu_cmd; - cmExpandList(runCmd, iwyu_cmd, true); + std::vector<std::string> iwyu_cmd = cmExpandedList(runCmd, true); cmAppend(iwyu_cmd, orig_cmd.begin() + 1, orig_cmd.end()); // Run the iwyu command line. Capture its stderr and hide its stdout. // Ignore its return code because the tool always returns non-zero. @@ -264,8 +261,7 @@ static int HandleCppLint(const std::string& runCmd, const std::vector<std::string>&) { // Construct the cpplint command line. - std::vector<std::string> cpplint_cmd; - cmExpandList(runCmd, cpplint_cmd, true); + std::vector<std::string> cpplint_cmd = cmExpandedList(runCmd, true); cpplint_cmd.push_back(sourceFile); // Run the cpplint command line. Capture its output. @@ -293,8 +289,7 @@ static int HandleCppCheck(const std::string& runCmd, const std::vector<std::string>& orig_cmd) { // Construct the cpplint command line. - std::vector<std::string> cppcheck_cmd; - cmExpandList(runCmd, cppcheck_cmd, true); + std::vector<std::string> cppcheck_cmd = cmExpandedList(runCmd, true); // extract all the -D, -U, and -I options from the compile line for (auto const& opt : orig_cmd) { if (opt.size() > 2) { @@ -678,10 +673,17 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args) // If an error occurs, we want to continue removing directories. bool return_value = false; for (auto const& arg : cmMakeRange(args).advance(2)) { - if (cmSystemTools::FileIsDirectory(arg) && - !cmSystemTools::RemoveADirectory(arg)) { - std::cerr << "Error removing directory \"" << arg << "\".\n"; - return_value = true; + if (cmSystemTools::FileIsDirectory(arg)) { + if (cmSystemTools::FileIsSymlink(arg)) { + if (!cmSystemTools::RemoveFile(arg)) { + std::cerr << "Error removing directory symlink \"" << arg + << "\".\n"; + return_value = true; + } + } else if (!cmSystemTools::RemoveADirectory(arg)) { + std::cerr << "Error removing directory \"" << arg << "\".\n"; + return_value = true; + } } } return return_value; @@ -765,8 +767,10 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args) if (args[1] == "time" && args.size() > 2) { std::vector<std::string> command(args.begin() + 2, args.end()); - clock_t clock_start, clock_finish; - time_t time_start, time_finish; + clock_t clock_start; + clock_t clock_finish; + time_t time_start; + time_t time_finish; time(&time_start); clock_start = clock(); @@ -837,8 +841,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args) // Command to start progress for a build if (args[1] == "cmake_progress_start" && args.size() == 4) { // basically remove the directory - std::string dirName = args[2]; - dirName += "/Progress"; + std::string dirName = cmStrCat(args[2], "/Progress"); cmSystemTools::RemoveADirectory(dirName); // is the last argument a filename that exists? @@ -855,8 +858,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args) if (count) { cmSystemTools::MakeDirectory(dirName); // write the count into the directory - std::string fName = dirName; - fName += "/count.txt"; + std::string fName = cmStrCat(dirName, "/count.txt"); FILE* progFile = cmsys::SystemTools::Fopen(fName, "w"); if (progFile) { fprintf(progFile, "%i\n", count); @@ -1074,11 +1076,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args) } } else if (cmHasLiteralPrefix(arg, "--format=")) { format = arg.substr(9); - bool isKnown = - std::find(cm::cbegin(knownFormats), cm::cend(knownFormats), - format) != cm::cend(knownFormats); - - if (!isKnown) { + if (!cmContains(knownFormats, format)) { cmSystemTools::Error("Unknown -E tar --format= argument: " + format); return 1; @@ -1350,14 +1348,12 @@ bool cmcmd::SymlinkInternal(std::string const& file, std::string const& link) static void cmcmdProgressReport(std::string const& dir, std::string const& num) { - std::string dirName = dir; - dirName += "/Progress"; + std::string dirName = cmStrCat(dir, "/Progress"); std::string fName; FILE* progFile; // read the count - fName = dirName; - fName += "/count.txt"; + fName = cmStrCat(dirName, "/count.txt"); progFile = cmsys::SystemTools::Fopen(fName, "r"); int count = 0; if (!progFile) { @@ -1372,8 +1368,7 @@ static void cmcmdProgressReport(std::string const& dir, std::string const& num) for (const char* c = last;; ++c) { if (*c == ',' || *c == '\0') { if (c != last) { - fName = dirName; - fName += "/"; + fName = cmStrCat(dirName, '/'); fName.append(last, c - last); progFile = cmsys::SystemTools::Fopen(fName, "w"); if (progFile) { diff --git a/Source/ctest.cxx b/Source/ctest.cxx index 77a84fd..a69ba15 100644 --- a/Source/ctest.cxx +++ b/Source/ctest.cxx @@ -83,7 +83,9 @@ static const char* cmDocumentationOptions[][2] = { { "-T <action>, --test-action <action>", "Sets the dashboard action to " "perform" }, - { "--track <track>", "Specify the track to submit dashboard to" }, + { "--group <group>", + "Specify what build group on the dashboard you'd like to " + "submit results to." }, { "-S <script>, --script <script>", "Execute a dashboard for a " "configuration" }, diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt index 79e813e..09bcdb9 100644 --- a/Source/kwsys/CMakeLists.txt +++ b/Source/kwsys/CMakeLists.txt @@ -121,8 +121,8 @@ if(KWSYS_CXX_STANDARD) set(CMAKE_CXX_STANDARD "${KWSYS_CXX_STANDARD}") elseif(NOT DEFINED CMAKE_CXX_STANDARD AND NOT DEFINED KWSYS_CXX_STANDARD) if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" - AND "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC" - AND "x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU" + AND CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC" + AND CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "GNU" ) set(CMAKE_CXX_STANDARD 14) else() @@ -1013,7 +1013,7 @@ ADD_DEFINITIONS("-DKWSYS_NAMESPACE=${KWSYS_NAMESPACE}") # Disable deprecation warnings for standard C functions. IF(MSVC OR (WIN32 AND (CMAKE_C_COMPILER_ID STREQUAL "Intel" OR - (CMAKE_C_COMPILER_ID STREQUAL "Clang" AND "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC")))) + (CMAKE_C_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC")))) ADD_DEFINITIONS( -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_SECURE_NO_DEPRECATE @@ -1104,7 +1104,7 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR) SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS} testConsoleBuf.cxx ) - IF("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC" AND + IF(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "19.0.23506") set_property(SOURCE testConsoleBuf.cxx testConsoleBufChild.cxx PROPERTY COMPILE_FLAGS /utf-8) ENDIF() diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx index 36f24c7..8571477 100644 --- a/Source/kwsys/SystemTools.cxx +++ b/Source/kwsys/SystemTools.cxx @@ -2169,24 +2169,24 @@ std::string SystemTools::ConvertToWindowsOutputPath(const std::string& path) return ret; } +/** + * Append the filename from the path source to the directory name dir. + */ +static std::string FileInDir(const std::string& source, const std::string& dir) +{ + std::string new_destination = dir; + SystemTools::ConvertToUnixSlashes(new_destination); + return new_destination + '/' + SystemTools::GetFilenameName(source); +} + bool SystemTools::CopyFileIfDifferent(const std::string& source, const std::string& destination) { // special check for a destination that is a directory // FilesDiffer does not handle file to directory compare if (SystemTools::FileIsDirectory(destination)) { - std::string new_destination = destination; - SystemTools::ConvertToUnixSlashes(new_destination); - new_destination += '/'; - std::string source_name = source; - new_destination += SystemTools::GetFilenameName(source_name); - if (SystemTools::FilesDiffer(source, new_destination)) { - return SystemTools::CopyFileAlways(source, destination); - } else { - // the files are the same so the copy is done return - // true - return true; - } + const std::string new_destination = FileInDir(source, destination); + return SystemTools::CopyFileIfDifferent(source, new_destination); } // source and destination are files so do a copy if they // are different @@ -2612,101 +2612,6 @@ std::string SystemTools::GetLastSystemError() return strerror(e); } -#ifdef _WIN32 - -static bool IsJunction(const std::wstring& source) -{ -# ifdef FSCTL_GET_REPARSE_POINT - const DWORD JUNCTION_ATTRS = - FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT; - DWORD attrs = GetFileAttributesW(source.c_str()); - if (attrs == INVALID_FILE_ATTRIBUTES) { - return false; - } - if ((attrs & JUNCTION_ATTRS) != JUNCTION_ATTRS) { - return false; - } - - // Adjust privileges so that we can succefully open junction points. - HANDLE token; - TOKEN_PRIVILEGES privs; - OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token); - LookupPrivilegeValue(NULL, SE_BACKUP_NAME, &privs.Privileges[0].Luid); - privs.PrivilegeCount = 1; - privs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; - AdjustTokenPrivileges(token, FALSE, &privs, sizeof(TOKEN_PRIVILEGES), NULL, - NULL); - CloseHandle(token); - - HANDLE dir = CreateFileW( - source.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, - FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL); - if (dir == INVALID_HANDLE_VALUE) { - return false; - } - - // Query whether this is a reparse point or not. - BYTE buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; - REPARSE_GUID_DATA_BUFFER* reparse_buffer = (REPARSE_GUID_DATA_BUFFER*)buffer; - DWORD sentinel; - - BOOL success = - DeviceIoControl(dir, FSCTL_GET_REPARSE_POINT, NULL, 0, reparse_buffer, - MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &sentinel, NULL); - - CloseHandle(dir); - - return (success && - (reparse_buffer->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT)); -# else - return false; -# endif -} - -static bool DeleteJunction(const std::wstring& source) -{ -# ifdef FSCTL_DELETE_REPARSE_POINT - // Adjust privileges so that we can succefully open junction points as - // read/write. - HANDLE token; - TOKEN_PRIVILEGES privs; - OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token); - LookupPrivilegeValue(NULL, SE_RESTORE_NAME, &privs.Privileges[0].Luid); - privs.PrivilegeCount = 1; - privs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; - AdjustTokenPrivileges(token, FALSE, &privs, sizeof(TOKEN_PRIVILEGES), NULL, - NULL); - CloseHandle(token); - - HANDLE dir = CreateFileW( - source.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, - FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL); - if (dir == INVALID_HANDLE_VALUE) { - return false; - } - - // Set up the structure so that we can delete the junction. - std::vector<BYTE> buffer(REPARSE_GUID_DATA_BUFFER_HEADER_SIZE, 0); - REPARSE_GUID_DATA_BUFFER* reparse_buffer = - (REPARSE_GUID_DATA_BUFFER*)&buffer[0]; - DWORD sentinel; - - reparse_buffer->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; - - BOOL success = DeviceIoControl( - dir, FSCTL_DELETE_REPARSE_POINT, reparse_buffer, - REPARSE_GUID_DATA_BUFFER_HEADER_SIZE, NULL, 0, &sentinel, NULL); - - CloseHandle(dir); - - return !!success; -# else - return false; -# endif -} - -#endif - bool SystemTools::RemoveFile(const std::string& source) { #ifdef _WIN32 @@ -2728,9 +2633,7 @@ bool SystemTools::RemoveFile(const std::string& source) SetLastError(err); return false; } - if (IsJunction(ws) && DeleteJunction(ws)) { - return true; - } + const DWORD DIRECTORY_SOFT_LINK_ATTRS = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT; DWORD attrs = GetFileAttributesW(ws.c_str()); diff --git a/Source/kwsys/testSystemTools.cxx b/Source/kwsys/testSystemTools.cxx index ffa6a29..88277de 100644 --- a/Source/kwsys/testSystemTools.cxx +++ b/Source/kwsys/testSystemTools.cxx @@ -999,30 +999,45 @@ static bool writeFile(const char* fileName, const char* data) return true; } +static std::string readFile(const char* fileName) +{ + kwsys::ifstream in(fileName, std::ios::binary); + std::stringstream sstr; + sstr << in.rdbuf(); + std::string data = sstr.str(); + if (!in) { + std::cerr << "Failed to read file: " << fileName << std::endl; + return std::string(); + } + return data; +} + +struct +{ + const char* a; + const char* b; + bool differ; +} diff_test_cases[] = { { "one", "one", false }, + { "one", "two", true }, + { "", "", false }, + { "\n", "\r\n", false }, + { "one\n", "one\n", false }, + { "one\r\n", "one\n", false }, + { "one\n", "one", false }, + { "one\ntwo", "one\ntwo", false }, + { "one\ntwo", "one\r\ntwo", false } }; + static bool CheckTextFilesDiffer() { - struct - { - const char* a; - const char* b; - bool differ; - } test_cases[] = { { "one", "one", false }, - { "one", "two", true }, - { "", "", false }, - { "\n", "\r\n", false }, - { "one\n", "one\n", false }, - { "one\r\n", "one\n", false }, - { "one\n", "one", false }, - { "one\ntwo", "one\ntwo", false }, - { "one\ntwo", "one\r\ntwo", false } }; - const int num_test_cases = sizeof(test_cases) / sizeof(test_cases[0]); + const int num_test_cases = + sizeof(diff_test_cases) / sizeof(diff_test_cases[0]); for (int i = 0; i < num_test_cases; ++i) { - if (!writeFile("file_a", test_cases[i].a) || - !writeFile("file_b", test_cases[i].b)) { + if (!writeFile("file_a", diff_test_cases[i].a) || + !writeFile("file_b", diff_test_cases[i].b)) { return false; } if (kwsys::SystemTools::TextFilesDiffer("file_a", "file_b") != - test_cases[i].differ) { + diff_test_cases[i].differ) { std::cerr << "Incorrect TextFilesDiffer result for test case " << i + 1 << "." << std::endl; return false; @@ -1032,6 +1047,36 @@ static bool CheckTextFilesDiffer() return true; } +static bool CheckCopyFileIfDifferent() +{ + bool ret = true; + const int num_test_cases = + sizeof(diff_test_cases) / sizeof(diff_test_cases[0]); + for (int i = 0; i < num_test_cases; ++i) { + if (!writeFile("file_a", diff_test_cases[i].a) || + !writeFile("file_b", diff_test_cases[i].b)) { + return false; + } + const char* cptarget = + i < 4 ? TEST_SYSTEMTOOLS_BINARY_DIR "/file_b" : "file_b"; + if (!kwsys::SystemTools::CopyFileIfDifferent("file_a", cptarget)) { + std::cerr << "CopyFileIfDifferent() returned false for test case " + << i + 1 << "." << std::endl; + ret = false; + continue; + } + std::string bdata = readFile("file_b"); + if (diff_test_cases[i].a != bdata) { + std::cerr << "Incorrect CopyFileIfDifferent file contents in test case " + << i + 1 << "." << std::endl; + ret = false; + continue; + } + } + + return ret; +} + int testSystemTools(int, char* []) { bool res = true; @@ -1077,5 +1122,7 @@ int testSystemTools(int, char* []) res &= CheckTextFilesDiffer(); + res &= CheckCopyFileIfDifferent(); + return res ? 0 : 1; } |